PageSourceSearch

https://hakalab.com/assets/index-ImmABN35.js

js hakalab.com collected 2026-10-02 00:50:05 UTC 2,660,199 bytes, 17,964 lines download raw bytes

vendor: 5,492 bytes, lines 1-9
1var iq=Object.defineProperty;var rq=(t,e,a)=>e in t?iq(t,e,{enumerable:!0,configurable:!0,writable:!0,value:a}):t[e]=a;var di=(t,e,a)=>rq(t,typeof e!="symbol"?e+"":e,a);(function(){const e=document.createElement("link").relList;if(e&&e.supports&&e.supports("modulepreload"))return;for(const i of document.querySelectorAll('link[rel="modulepreload"]'))n(i);new MutationObserver(i=>{for(const r of i)if(r.type==="childList")for(const o of r.addedNodes)o.tagName==="LINK"&&o.rel==="modulepreload"&&n(o)}).observe(document,{childList:!0,subtree:!0});function a(i){const r={};return i.integrity&&(r.integrity=i.integrity),i.referrerPolicy&&(r.referrerPolicy=i.referrerPolicy),i.crossOrigin==="use-credentials"?r.credentials="include":i.crossOrigin==="anonymous"?r.credentials="omit":r.credentials="same-origin",r}function n(i){if(i.ep)return;i.ep=!0;const r=a(i);fetch(i.href,r)}})();function wu(t){return t&&t.__esModule&&Object.prototype.hasOwnProperty.call(t,"default")?t.default:t}var QT={exports:{}},qf={},XT={exports:{}},be={};/**
2 * @license React
3 * react.production.min.js
4 *
5 * Copyright (c) Facebook, Inc. and its affiliates.
6 *
7 * This source code is licensed under the MIT license found in the
8 * LICENSE file in the root directory of this source tree.
9 */var ku=Symbol.for("react.element"),oq=Symbol.for("react.portal"),sq=Symbol.for("react.fragment"),lq=Symbol.for("react.strict_mode"),cq=Symbol.for("react.profiler"),dq=Symbol.for("react.provider"),uq=Symbol.for("react.context"),pq=Symbol.for("react.forward_ref"),mq=Symbol.for("react.suspense"),hq=Symbol.for("react.memo"),fq=Symbol.for("react.lazy"),R2=Symbol.iterator;function gq(t){return t===null||typeof t!="object"?null:(t=R2&&t[R2]||t["@@iterator"],typeof t=="function"?t:null)}var YT={isMounted:function(){return!1},enqueueForceUpdate:function(){},enqueueReplaceState:function(){},enqueueSetState:function(){}},ZT=Object.assign,eN={};function ql(t,e,a){this.props=t,this.context=e,this.refs=eN,this.updater=a||YT}ql.prototype.isReactComponent={};ql.prototype.setState=function(t,e){if(typeof t!="object"&&typeof t!="function"&&t!=null)throw Error("setState(...): takes an object of state variables to update or a function which returns an object of state variables.");this.updater.enqueueSetState(this,t,e,"setState")};ql.prototype.forceUpdate=function(t){this.updater.enqueueForceUpdate(this,t,"forceUpdate")};function tN(){}tN.prototype=ql.prototype;function e1(t,e,a){this.props=t,this.context=e,this.refs=eN,this.updater=a||YT}var t1=e1.prototype=new tN;t1.constructor=e1;ZT(t1,ql.prototype);t1.isPureReactComponent=!0;var L2=Array.isArray,aN=Object.prototype.hasOwnProperty,a1={current:null},nN={key:!0,ref:!0,__self:!0,__source:!0};function iN(t,e,a){var n,i={},r=null,o=null;if(e!=null)for(n in e.ref!==void 0&&(o=e.ref),e.key!==void 0&&(r=""+e.key),e)aN.call(e,n)&&!nN.hasOwnProperty(n)&&(i[n]=e[n]);var l=arguments.length-2;if(l===1)i.children=a;else if(1<l){for(var c=Array(l),d=0;d<l;d++)c[d]=arguments[d+2];i.children=c}if(t&&t.defaultProps)for(n in l=t.defaultProps,l)i[n]===void 0&&(i[n]=l[n]);return{$$typeof:ku,type:t,key:r,ref:o,props:i,_owner:a1.current}}function yq(t,e){return{$$typeof:ku,type:t.type,key:e,ref:t.ref,props:t.props,_owner:t._owner}}function n1(t){return typeof t=="object"&&t!==null&&t.$$typeof===ku}function xq(t){var e={"=":"=0",":":"=2"};return"$"+t.replace(/[=:]/g,function(a){return e[a]})}var O2=/\/+/g;function ky(t,e){return typeof t=="object"&&t!==null&&t.key!=null?xq(""+t.key):e.toString(36)}function dm(t,e,a,n,i){var r=typeof t;(r==="undefined"||r==="boolean")&&(t=null);var o=!1;if(t===null)o=!0;else switch(r){case"string":case"number":o=!0;break;case"object":switch(t.$$typeof){case ku:case oq:o=!0}}if(o)return o=t,i=i(o),t=n===""?"."+ky(o,0):n,L2(i)?(a="",t!=null&&(a=t.replace(O2,"$&/")+"/"),dm(i,e,a,"",function(d){return d})):i!=null&&(n1(i)&&(i=yq(i,a+(!i.key||o&&o.key===i.key?"":(""+i.key).replace(O2,"$&/")+"/")+t)),e.push(i)),1;if(o=0,n=n===""?".":n+":",L2(t))for(var l=0;l<t.length;l++){r=t[l];var c=n+ky(r,l);o+=dm(r,e,a,c,i)}else if(c=gq(t),typeof c=="function")for(t=c.call(t),l=0;!(r=t.next()).done;)r=r.value,c=n+ky(r,l++),o+=dm(r,e,a,c,i);else if(r==="object")throw e=String(t),Error("Objects are not valid as a React child (found: "+(e==="[object Object]"?"object with keys {"+Object.keys(t).join(", ")+"}":e)+"). If you meant to render a collection of children, use an array instead.");return o}function fp(t,e,a){if(t==null)return t;var n=[],i=0;return dm(t,n,"","",function(r){return e.call(a,r,i++)}),n}function vq(t){if(t._status===-1){var e=t._result;e=e(),e.then(function(a){(t._status===0||t._status===-1)&&(t._status=1,t._result=a)},function(a){(t._status===0||t._status===-1)&&(t._status=2,t._result=a)}),t._status===-1&&(t._status=0,t._result=e)}if(t._status===1)return t._result.default;throw t._result}var va={current:null},um={transition:null},bq={ReactCurrentDispatcher:va,ReactCurrentBatchConfig:um,ReactCurrentOwner:a1};function rN(){throw Error("act(...) is not supported in production builds of React.")}be.Children={map:fp,forEach:function(t,e,a){fp(t,function(){e.apply(this,arguments)},a)},count:function(t){var e=0;return fp(t,function(){e++}),e},toArray:function(t){return fp(t,function(e){return e})||[]},only:function(t){if(!n1(t))throw Error("React.Children.only expected to receive a single React element child.");return t}};be.Component=ql;be.Fragment=sq;be.Profiler=cq;be.PureComponent=e1;be.StrictMode=lq;be.Suspense=mq;
vendor: 7,474 bytes, lines 9-25
9be.__SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED=bq;be.act=rN;be.cloneElement=function(t,e,a){if(t==null)throw Error("React.cloneElement(...): The argument must be a React element, but you passed "+t+".");var n=ZT({},t.props),i=t.key,r=t.ref,o=t._owner;if(e!=null){if(e.ref!==void 0&&(r=e.ref,o=a1.current),e.key!==void 0&&(i=""+e.key),t.type&&t.type.defaultProps)var l=t.type.defaultProps;for(c in e)aN.call(e,c)&&!nN.hasOwnProperty(c)&&(n[c]=e[c]===void 0&&l!==void 0?l[c]:e[c])}var c=arguments.length-2;if(c===1)n.children=a;else if(1<c){l=Array(c);for(var d=0;d<c;d++)l[d]=arguments[d+2];n.children=l}return{$$typeof:ku,type:t.type,key:i,ref:r,props:n,_owner:o}};be.createContext=function(t){return t={$$typeof:uq,_currentValue:t,_currentValue2:t,_threadCount:0,Provider:null,Consumer:null,_defaultValue:null,_globalName:null},t.Provider={$$typeof:dq,_context:t},t.Consumer=t};be.createElement=iN;be.createFactory=function(t){var e=iN.bind(null,t);return e.type=t,e};be.createRef=function(){return{current:null}};be.forwardRef=function(t){return{$$typeof:pq,render:t}};be.isValidElement=n1;be.lazy=function(t){return{$$typeof:fq,_payload:{_status:-1,_result:t},_init:vq}};be.memo=function(t,e){return{$$typeof:hq,type:t,compare:e===void 0?null:e}};be.startTransition=function(t){var e=um.transition;um.transition={};try{t()}finally{um.transition=e}};be.unstable_act=rN;be.useCallback=function(t,e){return va.current.useCallback(t,e)};be.useContext=function(t){return va.current.useContext(t)};be.useDebugValue=function(){};be.useDeferredValue=function(t){return va.current.useDeferredValue(t)};be.useEffect=function(t,e){return va.current.useEffect(t,e)};be.useId=function(){return va.current.useId()};be.useImperativeHandle=function(t,e,a){return va.current.useImperativeHandle(t,e,a)};be.useInsertionEffect=function(t,e){return va.current.useInsertionEffect(t,e)};be.useLayoutEffect=function(t,e){return va.current.useLayoutEffect(t,e)};be.useMemo=function(t,e){return va.current.useMemo(t,e)};be.useReducer=function(t,e,a){return va.current.useReducer(t,e,a)};be.useRef=function(t){return va.current.useRef(t)};be.useState=function(t){return va.current.useState(t)};be.useSyncExternalStore=function(t,e,a){return va.current.useSyncExternalStore(t,e,a)};be.useTransition=function(){return va.current.useTransition()};be.version="18.3.1";XT.exports=be;var k=XT.exports;const Re=wu(k);/**
10 * @license React
11 * react-jsx-runtime.production.min.js
12 *
13 * Copyright (c) Facebook, Inc. and its affiliates.
14 *
15 * This source code is licensed under the MIT license found in the
16 * LICENSE file in the root directory of this source tree.
17 */var wq=k,kq=Symbol.for("react.element"),Sq=Symbol.for("react.fragment"),_q=Object.prototype.hasOwnProperty,Aq=wq.__SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED.ReactCurrentOwner,Eq={key:!0,ref:!0,__self:!0,__source:!0};function oN(t,e,a){var n,i={},r=null,o=null;a!==void 0&&(r=""+a),e.key!==void 0&&(r=""+e.key),e.ref!==void 0&&(o=e.ref);for(n in e)_q.call(e,n)&&!Eq.hasOwnProperty(n)&&(i[n]=e[n]);if(t&&t.defaultProps)for(n in e=t.defaultProps,e)i[n]===void 0&&(i[n]=e[n]);return{$$typeof:kq,type:t,key:r,ref:o,props:i,_owner:Aq.current}}qf.Fragment=Sq;qf.jsx=oN;qf.jsxs=oN;QT.exports=qf;var s=QT.exports,xx={},sN={exports:{}},Ga={},lN={exports:{}},cN={};/**
18 * @license React
19 * scheduler.production.min.js
20 *
21 * Copyright (c) Facebook, Inc. and its affiliates.
22 *
23 * This source code is licensed under the MIT license found in the
24 * LICENSE file in the root directory of this source tree.
25 */(function(t){function e(F,Z){var re=F.length;F.push(Z);e:for(;0<re;){var fe=re-1>>>1,ve=F[fe];if(0<i(ve,Z))F[fe]=Z,F[re]=ve,re=fe;else break e}}function a(F){return F.length===0?null:F[0]}function n(F){if(F.length===0)return null;var Z=F[0],re=F.pop();if(re!==Z){F[0]=re;e:for(var fe=0,ve=F.length,Ie=ve>>>1;fe<Ie;){var ne=2*(fe+1)-1,ge=F[ne],Me=ne+1,We=F[Me];if(0>i(ge,re))Me<ve&&0>i(We,ge)?(F[fe]=We,F[Me]=re,fe=Me):(F[fe]=ge,F[ne]=re,fe=ne);else if(Me<ve&&0>i(We,re))F[fe]=We,F[Me]=re,fe=Me;else break e}}return Z}function i(F,Z){var re=F.sortIndex-Z.sortIndex;return re!==0?re:F.id-Z.id}if(typeof performance=="object"&&typeof performance.now=="function"){var r=performance;t.unstable_now=function(){return r.now()}}else{var o=Date,l=o.now();t.unstable_now=function(){return o.now()-l}}var c=[],d=[],u=1,p=null,m=3,h=!1,g=!1,y=!1,x=typeof setTimeout=="function"?setTimeout:null,v=typeof clearTimeout=="function"?clearTimeout:null,w=typeof setImmediate<"u"?setImmediate:null;typeof navigator<"u"&&navigator.scheduling!==void 0&&navigator.scheduling.isInputPending!==void 0&&navigator.scheduling.isInputPending.bind(navigator.scheduling);function S(F){for(var Z=a(d);Z!==null;){if(Z.callback===null)n(d);else if(Z.startTime<=F)n(d),Z.sortIndex=Z.expirationTime,e(c,Z);else break;Z=a(d)}}function T(F){if(y=!1,S(F),!g)if(a(c)!==null)g=!0,ke(P);else{var Z=a(d);Z!==null&&ae(T,Z.startTime-F)}}function P(F,Z){g=!1,y&&(y=!1,v(E),E=-1),h=!0;var re=m;try{for(S(Z),p=a(c);p!==null&&(!(p.expirationTime>Z)||F&&!L());){var fe=p.callback;if(typeof fe=="function"){p.callback=null,m=p.priorityLevel;var ve=fe(p.expirationTime<=Z);Z=t.unstable_now(),typeof ve=="function"?p.callback=ve:p===a(c)&&n(c),S(Z)}else n(c);p=a(c)}if(p!==null)var Ie=!0;else{var ne=a(d);ne!==null&&ae(T,ne.startTime-Z),Ie=!1}return Ie}finally{p=null,m=re,h=!1}}var M=!1,C=null,E=-1,j=5,N=-1;function L(){return!(t.unstable_now()-N<j)}function O(){if(C!==null){var F=t.unstable_now();N=F;var Z=!0;try{Z=C(!0,F)}finally{Z?R():(M=!1,C=null)}}else M=!1}var R;if(typeof w=="function")R=function(){w(O)};else if(typeof MessageChannel<"u"){var G=new MessageChannel,ee=G.port2;G.port1.onmessage=O,R=function(){ee.postMessage(null)}}else R=function(){x(O,0)};function ke(F){C=F,M||(M=!0,R())}function ae(F,Z){E=x(function(){F(t.unstable_now())},Z)}t.unstable_IdlePriority=5,t.unstable_ImmediatePriority=1,t.unstable_LowPriority=4,t.unstable_NormalPriority=3,t.unstable_Profiling=null,t.unstable_UserBlockingPriority=2,t.unstable_cancelCallback=function(F){F.callback=null},t.unstable_continueExecution=function(){g||h||(g=!0,ke(P))},t.unstable_forceFrameRate=function(F){0>F||125<F?console.error("forceFrameRate takes a positive int between 0 and 125, forcing frame rates higher than 125 fps is not supported"):j=0<F?Math.floor(1e3/F):5},t.unstable_getCurrentPriorityLevel=function(){return m},t.unstable_getFirstCallbackNode=function(){return a(c)},t.unstable_next=function(F){switch(m){case 1:case 2:case 3:var Z=3;break;default:Z=m}var re=m;m=Z;try{return F()}finally{m=re}},t.unstable_pauseExecution=function(){},t.unstable_requestPaint=function(){},t.unstable_runWithPriority=function(F,Z){switch(F){case 1:case 2:case 3:case 4:case 5:break;default:F=3}var re=m;m=F;try{return Z()}finally{m=re}},t.unstable_scheduleCallback=function(F,Z,re){var fe=t.unstable_now();switch(typeof re=="object"&&re!==null?(re=re.delay,re=typeof re=="number"&&0<re?fe+re:fe):re=fe,F){case 1:var ve=-1;break;case 2:ve=250;break;case 5:ve=1073741823;break;case 4:ve=1e4;break;default:ve=5e3}return ve=re+ve,F={id:u++,callback:Z,priorityLevel:F,startTime:re,expirationTime:ve,sortIndex:-1},re>fe?(F.sortIndex=re,e(d,F),a(c)===null&&F===a(d)&&(y?(v(E),E=-1):y=!0,ae(T,re-fe))):(F.sortIndex=ve,e(c,F),g||h||(g=!0,ke(P))),F},t.unstable_shouldYield=L,t.unstable_wrapCallback=function(F){var Z=m;return function(){var re=m;m=Z;try{return F.apply(this,arguments)}finally{m=re}}}})(cN);lN.exports=cN;
vendor: 4,228 bytes, lines 25-33
25var Cq=lN.exports;/**
26 * @license React
27 * react-dom.production.min.js
28 *
29 * Copyright (c) Facebook, Inc. and its affiliates.
30 *
31 * This source code is licensed under the MIT license found in the
32 * LICENSE file in the root directory of this source tree.
33 */var jq=k,$a=Cq;function U(t){for(var e="https://reactjs.org/docs/error-decoder.html?invariant="+t,a=1;a<arguments.length;a++)e+="&args[]="+encodeURIComponent(arguments[a]);return"Minified React error #"+t+"; visit "+e+" for the full message or use the non-minified dev environment for full errors and additional helpful warnings."}var dN=new Set,Nd={};function ls(t,e){pl(t,e),pl(t+"Capture",e)}function pl(t,e){for(Nd[t]=e,t=0;t<e.length;t++)dN.add(e[t])}var Ri=!(typeof window>"u"||typeof window.document>"u"||typeof window.document.createElement>"u"),vx=Object.prototype.hasOwnProperty,Tq=/^[:A-Z_a-z\u00C0-\u00D6\u00D8-\u00F6\u00F8-\u02FF\u0370-\u037D\u037F-\u1FFF\u200C-\u200D\u2070-\u218F\u2C00-\u2FEF\u3001-\uD7FF\uF900-\uFDCF\uFDF0-\uFFFD][:A-Z_a-z\u00C0-\u00D6\u00D8-\u00F6\u00F8-\u02FF\u0370-\u037D\u037F-\u1FFF\u200C-\u200D\u2070-\u218F\u2C00-\u2FEF\u3001-\uD7FF\uF900-\uFDCF\uFDF0-\uFFFD\-.0-9\u00B7\u0300-\u036F\u203F-\u2040]*$/,M2={},D2={};function Nq(t){return vx.call(D2,t)?!0:vx.call(M2,t)?!1:Tq.test(t)?D2[t]=!0:(M2[t]=!0,!1)}function Iq(t,e,a,n){if(a!==null&&a.type===0)return!1;switch(typeof e){case"function":case"symbol":return!0;case"boolean":return n?!1:a!==null?!a.acceptsBooleans:(t=t.toLowerCase().slice(0,5),t!=="data-"&&t!=="aria-");default:return!1}}function Pq(t,e,a,n){if(e===null||typeof e>"u"||Iq(t,e,a,n))return!0;if(n)return!1;if(a!==null)switch(a.type){case 3:return!e;case 4:return e===!1;case 5:return isNaN(e);case 6:return isNaN(e)||1>e}return!1}function ba(t,e,a,n,i,r,o){this.acceptsBooleans=e===2||e===3||e===4,this.attributeName=n,this.attributeNamespace=i,this.mustUseProperty=a,this.propertyName=t,this.type=e,this.sanitizeURL=r,this.removeEmptyString=o}var Ut={};"children dangerouslySetInnerHTML defaultValue defaultChecked innerHTML suppressContentEditableWarning suppressHydrationWarning style".split(" ").forEach(function(t){Ut[t]=new ba(t,0,!1,t,null,!1,!1)});[["acceptCharset","accept-charset"],["className","class"],["htmlFor","for"],["httpEquiv","http-equiv"]].forEach(function(t){var e=t[0];Ut[e]=new ba(e,1,!1,t[1],null,!1,!1)});["contentEditable","draggable","spellCheck","value"].forEach(function(t){Ut[t]=new ba(t,2,!1,t.toLowerCase(),null,!1,!1)});["autoReverse","externalResourcesRequired","focusable","preserveAlpha"].forEach(function(t){Ut[t]=new ba(t,2,!1,t,null,!1,!1)});"allowFullScreen async autoFocus autoPlay controls default defer disabled disablePictureInPicture disableRemotePlayback formNoValidate hidden loop noModule noValidate open playsInline readOnly required reversed scoped seamless itemScope".split(" ").forEach(function(t){Ut[t]=new ba(t,3,!1,t.toLowerCase(),null,!1,!1)});["checked","multiple","muted","selected"].forEach(function(t){Ut[t]=new ba(t,3,!0,t,null,!1,!1)});["capture","download"].forEach(function(t){Ut[t]=new ba(t,4,!1,t,null,!1,!1)});["cols","rows","size","span"].forEach(function(t){Ut[t]=new ba(t,6,!1,t,null,!1,!1)});["rowSpan","start"].forEach(function(t){Ut[t]=new ba(t,5,!1,t.toLowerCase(),null,!1,!1)});var i1=/[\-:]([a-z])/g;function r1(t){return t[1].toUpperCase()}"accent-height alignment-baseline arabic-form baseline-shift cap-height clip-path clip-rule color-interpolation color-interpolation-filters color-profile color-rendering dominant-baseline enable-background fill-opacity fill-rule flood-color flood-opacity font-family font-size font-size-adjust font-stretch font-style font-variant font-weight glyph-name glyph-orientation-horizontal glyph-orientation-vertical horiz-adv-x horiz-origin-x image-rendering letter-spacing lighting-color marker-end marker-mid marker-start overline-position overline-thickness paint-order panose-1 pointer-events rendering-intent shape-rendering stop-color stop-opacity strikethrough-position strikethrough-thickness stroke-dasharray stroke-dashoffset stroke-linecap stroke-linejoin stroke-miterlimit stroke-opacity stroke-width text-anchor text-decoration text-rendering underline-position underline-thickness unicode
33-bidi unicode-range units-per-em v-alphabetic v-hanging v-ideographic v-mathematical vector-effect vert-adv-y vert-origin-x vert-origin-y word-spacing writing-mode xmlns:xlink x-height".split(" ").forEach(function(t){var e=t.replace(i1,r1);Ut[e]=new ba(e,1,!1,t,null,!1,!1)});"xlink:actuate xlink:arcrole xlink:role xlink:show xlink:title xlink:type".split(" ").forEach(function(t){var e=t.replace(i1,r1);Ut[e]=new ba(e,1,!1,t,"http://www.w3.org/1999/xlink",!1,!1)});["xml:base","xml:lang","xml:space"].forEach(function(t){var e=t.replace(i1,r1);Ut[e]=new ba(e,1,!1,t,"http://www.w3.org/XML/1998/namespace",!1,!1)});["tabIndex","crossOrigin"].forEach(function(t){Ut[t]=new ba(t,1,!1,t.toLowerCase(),null,!1,!1)});Ut.xlinkHref=new ba("xlinkHref",1,!1,"xlink:href","http://www.w3.org/1999/xlink",!0,!1);["src","href","action","formAction"].forEach(function(t){Ut[t]=new ba(t,1,!1,t.toLowerCase(),null,!0,!0)});function o1(t,e,a,n){var i=Ut.hasOwnProperty(e)?Ut[e]:null;(i!==null?i.type!==0:n||!(2<e.length)||e[0]!=="o"&&e[0]!=="O"||e[1]!=="n"&&e[1]!=="N")&&(Pq(e,a,i,n)&&(a=null),n||i===null?Nq(e)&&(a===null?t.removeAttribute(e):t.setAttribute(e,""+a)):i.mustUseProperty?t[i.propertyName]=a===null?i.type===3?!1:"":a:(e=i.attributeName,n=i.attributeNamespace,a===null?t.removeAttribute(e):(i=i.type,a=i===3||i===4&&a===!0?"":""+a,n?t.setAttributeNS(n,e,a):t.setAttribute(e,a))))}var Ui=jq.__SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED,gp=Symbol.for("react.element"),Rs=Symbol.for("react.portal"),Ls=Symbol.for("react.fragment"),s1=Symbol.for("react.strict_mode"),bx=Symbol.for("react.profiler"),uN=Symbol.for("react.provider"),pN=Symbol.for("react.context"),l1=Symbol.for("react.forward_ref"),wx=Symbol.for("react.suspense"),kx=Symbol.for("react.suspense_list"),c1=Symbol.for("react.memo"),tr=Symbol.for("react.lazy"),mN=Symbol.for("react.offscreen"),q2=Symbol.iterator;function hc(t){return t===null||typeof t!="object"?null:(t=q2&&t[q2]||t["@@iterator"],typeof t=="function"?t:null)}var Ze=Object.assign,Sy;function Lc(t){if(Sy===void 0)try{throw Error()}catch(a){var e=a.stack.trim().match(/\n( *(at )?)/);Sy=e&&e[1]||""}return`
34`+Sy+t}var _y=!1;function Ay(t,e){if(!t||_y)return"";_y=!0;var a=Error.prepareStackTrace;Error.prepareStackTrace=void 0;try{if(e)if(e=function(){throw Error()},Object.defineProperty(e.prototype,"props",{set:function(){throw Error()}}),typeof Reflect=="object"&&Reflect.construct){try{Reflect.construct(e,[])}catch(d){var n=d}Reflect.construct(t,[],e)}else{try{e.call()}catch(d){n=d}t.call(e.prototype)}else{try{throw Error()}catch(d){n=d}t()}}catch(d){if(d&&n&&typeof d.stack=="string"){for(var i=d.stack.split(`
35`),r=n.stack.split(`
36`),o=i.length-1,l=r.length-1;1<=o&&0<=l&&i[o]!==r[l];)l--;for(;1<=o&&0<=l;o--,l--)if(i[o]!==r[l]){if(o!==1||l!==1)do if(o--,l--,0>l||i[o]!==r[l]){var c=`
37`+i[o].replace(" at new "," at ");return t.displayName&&c.includes("<anonymous>")&&(c=c.replace("<anonymous>",t.displayName)),c}while(1<=o&&0<=l);break}}}finally{_y=!1,Error.prepareStackTrace=a}return(t=t?t.displayName||t.name:"")?Lc(t):""}function Rq(t){switch(t.tag){case 5:return Lc(t.type);case 16:return Lc("Lazy");case 13:return Lc("Suspense");case 19:return Lc("SuspenseList");case 0:case 2:case 15:return t=Ay(t.type,!1),t;case 11:return t=Ay(t.type.render,!1),t;case 1:return t=Ay(t.type,!0),t;default:return""}}function Sx(t){if(t==null)return null;if(typeof t=="function")return t.displayName||t.name||null;if(typeof t=="string")return t;switch(t){case Ls:return"Fragment";case Rs:return"Portal";case bx:return"Profiler";case s1:return"StrictMode";case wx:return"Suspense";case kx:return"SuspenseList"}if(typeof t=="object")switch(t.$$typeof){case pN:return(t.displayName||"Context")+".Consumer";case uN:return(t._context.displayName||"Context")+".Provider";case l1:var e=t.render;return t=t.displayName,t||(t=e.displayName||e.name||"",t=t!==""?"ForwardRef("+t+")":"ForwardRef"),t;case c1:return e=t.displayName||null,e!==null?e:Sx(t.type)||"Memo";case tr:e=t._payload,t=t._init;try{return Sx(t(e))}catch{}}return null}function Lq(t){var e=t.type;switch(t.tag){case 24:return"Cache";case 9:return(e.displayName||"Context")+".Consumer";case 10:return(e._context.displayName||"Context")+".Provider";case 18:return"DehydratedFragment";case 11:return t=e.render,t=t.displayName||t.name||"",e.displayName||(t!==""?"ForwardRef("+t+")":"ForwardRef");case 7:return"Fragment";case 5:return e;case 4:return"Portal";case 3:return"Root";case 6:return"Text";case 16:return Sx(e);case 8:return e===s1?"StrictMode":"Mode";case 22:return"Offscreen";case 12:return"Profiler";case 21:return"Scope";case 13:return"Suspense";case 19:return"SuspenseList";case 25:return"TracingMarker";case 1:case 0:case 17:case 2:case 14:case 15:if(typeof e=="function")return e.displayName||e.name||null;if(typeof e=="string")return e}return null}function Dr(t){switch(typeof t){case"boolean":case"number":case"string":case"undefined":return t;case"object":return t;default:return""}}function hN(t){var e=t.type;
vendor: 11,635 bytes, line 37
37return(t=t.nodeName)&&t.toLowerCase()==="input"&&(e==="checkbox"||e==="radio")}function Oq(t){var e=hN(t)?"checked":"value",a=Object.getOwnPropertyDescriptor(t.constructor.prototype,e),n=""+t[e];if(!t.hasOwnProperty(e)&&typeof a<"u"&&typeof a.get=="function"&&typeof a.set=="function"){var i=a.get,r=a.set;return Object.defineProperty(t,e,{configurable:!0,get:function(){return i.call(this)},set:function(o){n=""+o,r.call(this,o)}}),Object.defineProperty(t,e,{enumerable:a.enumerable}),{getValue:function(){return n},setValue:function(o){n=""+o},stopTracking:function(){t._valueTracker=null,delete t[e]}}}}function yp(t){t._valueTracker||(t._valueTracker=Oq(t))}function fN(t){if(!t)return!1;var e=t._valueTracker;if(!e)return!0;var a=e.getValue(),n="";return t&&(n=hN(t)?t.checked?"true":"false":t.value),t=n,t!==a?(e.setValue(t),!0):!1}function Km(t){if(t=t||(typeof document<"u"?document:void 0),typeof t>"u")return null;try{return t.activeElement||t.body}catch{return t.body}}function _x(t,e){var a=e.checked;return Ze({},e,{defaultChecked:void 0,defaultValue:void 0,value:void 0,checked:a??t._wrapperState.initialChecked})}function z2(t,e){var a=e.defaultValue==null?"":e.defaultValue,n=e.checked!=null?e.checked:e.defaultChecked;a=Dr(e.value!=null?e.value:a),t._wrapperState={initialChecked:n,initialValue:a,controlled:e.type==="checkbox"||e.type==="radio"?e.checked!=null:e.value!=null}}function gN(t,e){e=e.checked,e!=null&&o1(t,"checked",e,!1)}function Ax(t,e){gN(t,e);var a=Dr(e.value),n=e.type;if(a!=null)n==="number"?(a===0&&t.value===""||t.value!=a)&&(t.value=""+a):t.value!==""+a&&(t.value=""+a);else if(n==="submit"||n==="reset"){t.removeAttribute("value");return}e.hasOwnProperty("value")?Ex(t,e.type,a):e.hasOwnProperty("defaultValue")&&Ex(t,e.type,Dr(e.defaultValue)),e.checked==null&&e.defaultChecked!=null&&(t.defaultChecked=!!e.defaultChecked)}function V2(t,e,a){if(e.hasOwnProperty("value")||e.hasOwnProperty("defaultValue")){var n=e.type;if(!(n!=="submit"&&n!=="reset"||e.value!==void 0&&e.value!==null))return;e=""+t._wrapperState.initialValue,a||e===t.value||(t.value=e),t.defaultValue=e}a=t.name,a!==""&&(t.name=""),t.defaultChecked=!!t._wrapperState.initialChecked,a!==""&&(t.name=a)}function Ex(t,e,a){(e!=="number"||Km(t.ownerDocument)!==t)&&(a==null?t.defaultValue=""+t._wrapperState.initialValue:t.defaultValue!==""+a&&(t.defaultValue=""+a))}var Oc=Array.isArray;function Xs(t,e,a,n){if(t=t.options,e){e={};for(var i=0;i<a.length;i++)e["$"+a[i]]=!0;for(a=0;a<t.length;a++)i=e.hasOwnProperty("$"+t[a].value),t[a].selected!==i&&(t[a].selected=i),i&&n&&(t[a].defaultSelected=!0)}else{for(a=""+Dr(a),e=null,i=0;i<t.length;i++){if(t[i].value===a){t[i].selected=!0,n&&(t[i].defaultSelected=!0);return}e!==null||t[i].disabled||(e=t[i])}e!==null&&(e.selected=!0)}}function Cx(t,e){if(e.dangerouslySetInnerHTML!=null)throw Error(U(91));return Ze({},e,{value:void 0,defaultValue:void 0,children:""+t._wrapperState.initialValue})}function H2(t,e){var a=e.value;if(a==null){if(a=e.children,e=e.defaultValue,a!=null){if(e!=null)throw Error(U(92));if(Oc(a)){if(1<a.length)throw Error(U(93));a=a[0]}e=a}e==null&&(e=""),a=e}t._wrapperState={initialValue:Dr(a)}}function yN(t,e){var a=Dr(e.value),n=Dr(e.defaultValue);a!=null&&(a=""+a,a!==t.value&&(t.value=a),e.defaultValue==null&&t.defaultValue!==a&&(t.defaultValue=a)),n!=null&&(t.defaultValue=""+n)}function F2(t){var e=t.textContent;e===t._wrapperState.initialValue&&e!==""&&e!==null&&(t.value=e)}function xN(t){switch(t){case"svg":return"http://www.w3.org/2000/svg";case"math":return"http://www.w3.org/1998/Math/MathML";default:return"http://www.w3.org/1999/xhtml"}}function jx(t,e){return t==null||t==="http://www.w3.org/1999/xhtml"?xN(e):t==="http://www.w3.org/2000/svg"&&e==="foreignObject"?"http://www.w3.org/1999/xhtml":t}var xp,vN=function(t){return typeof MSApp<"u"&&MSApp.execUnsafeLocalFunction?function(e,a,n,i){MSApp.execUnsafeLocalFunction(function(){return t(e,a,n,i)})}:t}(function(t,e){if(t.namespaceURI!=="http://www.w3.org/2000/svg"||"innerHTML"in t)t.innerHTML=e;else{for(xp=xp||document.createElement("div"),xp.innerHTML="<svg>"+e.valueOf().toString()+"</svg>",e=xp.firstChild;t.firstChild;)t.removeChild(t.firstChild);for(;e.firstChild;)t.appendChild(e.firstChild)}});function Id(t,e){if(e){var a=t.firstChild;if(a&&a===t.lastChild&&a.nodeType===3){a.nodeValue=e;return}}t.textContent=e}var Jc={animationIterationCount:!0,aspectRatio:!0,borderImageOutset:!0,borderImageSlice:!0,borderImageWidth:!0,boxFlex:!0,boxFlexGroup:!0,boxOrdinalGroup:!0,columnCount:!0,columns:!0,flex:!0,flexGrow:!0,flexPositive:!0,flexShrink:!0,flexNegative:!0,flexOrder:!0,gridArea:!0,gridRow:!0,gridRowEnd:!0,gridRowSpan:!0,gridRowStart:!0,gridColumn:!0,gridColumnEnd:!0,gridColumnSpan:!0,gridColumnStart:!0,fontWeight:!0,lineClamp:!0,lineHeight:!0,opacity:!0,order:!0,orphans:!0,tabSize:!0,widows:!0,zIndex:!0,zoom:!0,fillOpacity:!0,floodOpacity:!0,stopOpacity:!0,strokeDasharray:!0,strokeDashoffset:!0,strokeMiterlimit:!0,strokeOpacity:!0,strokeWidth:!0},Mq=["Webkit","ms","Moz","O"];Object.keys(Jc).forEach(function(t){Mq.forEach(function(e){e=e+t.charAt(0).toUpperCase()+t.substring(1),Jc[e]=Jc[t]})});function bN(t,e,a){return e==null||typeof e=="boolean"||e===""?"":a||typeof e!="number"||e===0||Jc.hasOwnProperty(t)&&Jc[t]?(""+e).trim():e+"px"}function wN(t,e){t=t.style;for(var a in e)if(e.hasOwnProperty(a)){var n=a.indexOf("--")===0,i=bN(a,e[a],n);a==="float"&&(a="cssFloat"),n?t.setProperty(a,i):t[a]=i}}var Dq=Ze({menuitem:!0},{area:!0,base:!0,br:!0,col:!0,embed:!0,hr:!0,img:!0,input:!0,keygen:!0,link:!0,meta:!0,param:!0,source:!0,track:!0,wbr:!0});function Tx(t,e){if(e){if(Dq[t]&&(e.children!=null||e.dangerouslySetInnerHTML!=null))throw Error(U(137,t));if(e.dangerouslySetInnerHTML!=null){if(e.children!=null)throw Error(U(60));if(typeof e.dangerouslySetInnerHTML!="object"||!("__html"in e.dangerouslySetInnerHTML))throw Error(U(61))}if(e.style!=null&&typeof e.style!="object")throw Error(U(62))}}function Nx(t,e){if(t.indexOf("-")===-1)return typeof e.is=="string";switch(t){case"annotation-xml":case"color-profile":case"font-face":case"font-face-src":case"font-face-uri":case"font-face-format":case"font-face-name":case"missing-glyph":return!1;default:return!0}}var Ix=null;function d1(t){return t=t.target||t.srcElement||window,t.correspondingUseElement&&(t=t.correspondingUseElement),t.nodeType===3?t.parentNode:t}var Px=null,Ys=null,Zs=null;function B2(t){if(t=Au(t)){if(typeof Px!="function")throw Error(U(280));var e=t.stateNode;e&&(e=Bf(e),Px(t.stateNode,t.type,e))}}function kN(t){Ys?Zs?Zs.push(t):Zs=[t]:Ys=t}function SN(){if(Ys){var t=Ys,e=Zs;if(Zs=Ys=null,B2(t),e)for(t=0;t<e.length;t++)B2(e[t])}}function _N(t,e){return t(e)}function AN(){}var Ey=!1;function EN(t,e,a){if(Ey)return t(e,a);Ey=!0;try{return _N(t,e,a)}finally{Ey=!1,(Ys!==null||Zs!==null)&&(AN(),SN())}}function Pd(t,e){var a=t.stateNode;if(a===null)return null;var n=Bf(a);if(n===null)return null;a=n[e];e:switch(e){case"onClick":case"onClickCapture":case"onDoubleClick":case"onDoubleClickCapture":case"onMouseDown":case"onMouseDownCapture":case"onMouseMove":case"onMouseMoveCapture":case"onMouseUp":case"onMouseUpCapture":case"onMouseEnter":(n=!n.disabled)||(t=t.type,n=!(t==="button"||t==="input"||t==="select"||t==="textarea")),t=!n;break e;default:t=!1}if(t)return null;if(a&&typeof a!="function")throw Error(U(231,e,typeof a));return a}var Rx=!1;if(Ri)try{var fc={};Object.defineProperty(fc,"passive",{get:function(){Rx=!0}}),window.addEventListener("test",fc,fc),window.removeEventListener("test",fc,fc)}catch{Rx=!1}function qq(t,e,a,n,i,r,o,l,c){var d=Array.prototype.slice.call(arguments,3);try{e.apply(a,d)}catch(u){this.onError(u)}}var Qc=!1,Jm=null,Qm=!1,Lx=null,zq={onError:function(t){Qc=!0,Jm=t}};function Vq(t,e,a,n,i,r,o,l,c){Qc=!1,Jm=null,qq.apply(zq,arguments)}function Hq(t,e,a,n,i,r,o,l,c){if(Vq.apply(this,arguments),Qc){if(Qc){var d=Jm;Qc=!1,Jm=null}else throw Error(U(198));Qm||(Qm=!0,Lx=d)}}function cs(t){var e=t,a=t;if(t.alternate)for(;e.return;)e=e.return;else{t=e;do e=t,e.flags&4098&&(a=e.return),t=e.return;while(t)}return e.tag===3?a:null}function CN(t){if(t.tag===13){var e=t.memoizedState;if(e===null&&(t=t.alternate,t!==null&&(e=t.memoizedState)),e!==null)return e.dehydrated}return null}function U2(t){if(cs(t)!==t)throw Error(U(188))}function Fq(t){var e=t.alternate;if(!e){if(e=cs(t),e===null)throw Error(U(188));return e!==t?null:t}for(var a=t,n=e;;){var i=a.return;if(i===null)break;var r=i.alternate;if(r===null){if(n=i.return,n!==null){a=n;continue}break}if(i.child===r.child){for(r=i.child;r;){if(r===a)return U2(i),t;if(r===n)return U2(i),e;r=r.sibling}throw Error(U(188))}if(a.return!==n.return)a=i,n=r;else{for(var o=!1,l=i.child;l;){if(l===a){o=!0,a=i,n=r;break}if(l===n){o=!0,n=i,a=r;break}l=l.sibling}if(!o){for(l=r.child;l;){if(l===a){o=!0,a=r,n=i;break}if(l===n){o=!0,n=r,a=i;break}l=l.sibling}if(!o)throw Error(U(189))}}if(a.alternate!==n)throw Error(U(190))}if(a.tag!==3)throw Error(U(188));return a.stateNode.current===a?t:e}function jN(t){return t=Fq(t),t!==null?TN(t):null}function TN(t){if(t.tag===5||t.tag===6)return t;for(t=t.child;t!==null;){var e=TN(t);if(e!==null)return e;t=t.sibling}return null}var NN=$a.unstable_scheduleCallback,$2=$a.unstable_cancelCallback,Bq=$a.unstable_shouldYield,Uq=$a.unstable_requestPaint,pt=$a.unstable_now,$q=$a.unstable_getCurrentPriorityLevel,u1=$a.unstable_ImmediatePriority,IN=$a.unstable_UserBlockingPriority,Xm=$a.unstable_NormalPriority,Wq=$a.unstable_LowPriority,PN=$a.unstable_IdlePriority,zf=null,Xn=null;function Gq(t){if(Xn&&typeof Xn.onCommitFiberRoot=="function")try{Xn.onCommitFiberRoot(zf,t,void 0,(t.current.flags&128)===128)}catch{}}var Tn=Math.clz32?Math.clz32:Qq,Kq=Math.log,Jq=Math.LN2;function Qq(t){return t>>>=0,t===0?32:31-(Kq(t)/Jq|0)|0}var vp=64,bp=4194304;function Mc(t){switch(t&-t){case 1:return 1;case 2:return 2;case 4:return 4;case 8:return 8;case 16:return 16;case 32:return 32;case 64:case 128:case 256:case 512:case 1024:case 2048:case 4096:case 8192:case 16384:case 32768:case 65536:case 131072:case 262144:case 524288:case 1048576:case 2097152:return t&4194240;case 4194304:case 8388608:case 16777216:case 33554432:case 67108864:return t&130023424;case 134217728:return 134217728;case 268435456:return 268435456;case 536870912:return 536870912;case 1073741824:return 1073741824;default:return t}}function Ym(t,e){var a=t.pendingLanes;if(a===0)return 0;var n=0,i=t.suspendedLanes,r=t.pingedLanes,o=a&268435455;if(o!==0){var l=o&~i;l!==0?n=Mc(l):(r&=o,r!==0&&(n=Mc(r)))}else o=a&~i,o!==0?n=Mc(o):r!==0&&(n=Mc(r));if(n===0)return 0;if(e!==0&&e!==n&&!(e&i)&&(i=n&-n,r=e&-e,i>=r||i===16&&(r&4194240)!==0))return e;if(n&4&&(n|=a&16),e=t.entangledLanes,e!==0)for(t=t.entanglements,e&=n;0<e;)a=31-Tn(e),i=1<<a,n|=t[a],e&=~i;return n}function Xq(t,e){switch(t){case 1:case 2:case 4:return e+250;case 8:case 16:case 32:case 64:case 128:case 256:case 512:case 1024:case 2048:case 4096:case 8192:case 16384:case 32768:case 65536:case 131072:case 262144:case 524288:case 1048576:case 2097152:return e+5e3;case 4194304:case 8388608:case 16777216:case 33554432:case 67108864:return-1;case 134217728:case 268435456:case 536870912:case 1073741824:return-1;default:return-1}}function Yq(t,e){for(var a=t.suspendedLanes,n=t.pingedLanes,i=t.expirationTimes,r=t.pendingLanes;0<r;){var o=31-Tn(r),l=1<<o,c=i[o];c===-1?(!(l&a)||l&n)&&(i[o]=Xq(l,e)):c<=e&&(t.expiredLanes|=l),r&=~l}}function Ox(t){return t=t.pendingLanes&-1073741825,t!==0?t:t&1073741824?1073741824:0}function RN(){var t=vp;return vp<<=1,!(vp&4194240)&&(vp=64),t}function Cy(t){for(var e=[],a=0;31>a;
vendor: 4,110 bytes, line 37
37a++)e.push(t);return e}function Su(t,e,a){t.pendingLanes|=e,e!==536870912&&(t.suspendedLanes=0,t.pingedLanes=0),t=t.eventTimes,e=31-Tn(e),t[e]=a}function Zq(t,e){var a=t.pendingLanes&~e;t.pendingLanes=e,t.suspendedLanes=0,t.pingedLanes=0,t.expiredLanes&=e,t.mutableReadLanes&=e,t.entangledLanes&=e,e=t.entanglements;var n=t.eventTimes;for(t=t.expirationTimes;0<a;){var i=31-Tn(a),r=1<<i;e[i]=0,n[i]=-1,t[i]=-1,a&=~r}}function p1(t,e){var a=t.entangledLanes|=e;for(t=t.entanglements;a;){var n=31-Tn(a),i=1<<n;i&e|t[n]&e&&(t[n]|=e),a&=~i}}var Le=0;function LN(t){return t&=-t,1<t?4<t?t&268435455?16:536870912:4:1}var ON,m1,MN,DN,qN,Mx=!1,wp=[],wr=null,kr=null,Sr=null,Rd=new Map,Ld=new Map,or=[],e6="mousedown mouseup touchcancel touchend touchstart auxclick dblclick pointercancel pointerdown pointerup dragend dragstart drop compositionend compositionstart keydown keypress keyup input textInput copy cut paste click change contextmenu reset submit".split(" ");function W2(t,e){switch(t){case"focusin":case"focusout":wr=null;break;case"dragenter":case"dragleave":kr=null;break;case"mouseover":case"mouseout":Sr=null;break;case"pointerover":case"pointerout":Rd.delete(e.pointerId);break;case"gotpointercapture":case"lostpointercapture":Ld.delete(e.pointerId)}}function gc(t,e,a,n,i,r){return t===null||t.nativeEvent!==r?(t={blockedOn:e,domEventName:a,eventSystemFlags:n,nativeEvent:r,targetContainers:[i]},e!==null&&(e=Au(e),e!==null&&m1(e)),t):(t.eventSystemFlags|=n,e=t.targetContainers,i!==null&&e.indexOf(i)===-1&&e.push(i),t)}function t6(t,e,a,n,i){switch(e){case"focusin":return wr=gc(wr,t,e,a,n,i),!0;case"dragenter":return kr=gc(kr,t,e,a,n,i),!0;case"mouseover":return Sr=gc(Sr,t,e,a,n,i),!0;case"pointerover":var r=i.pointerId;return Rd.set(r,gc(Rd.get(r)||null,t,e,a,n,i)),!0;case"gotpointercapture":return r=i.pointerId,Ld.set(r,gc(Ld.get(r)||null,t,e,a,n,i)),!0}return!1}function zN(t){var e=xo(t.target);if(e!==null){var a=cs(e);if(a!==null){if(e=a.tag,e===13){if(e=CN(a),e!==null){t.blockedOn=e,qN(t.priority,function(){MN(a)});return}}else if(e===3&&a.stateNode.current.memoizedState.isDehydrated){t.blockedOn=a.tag===3?a.stateNode.containerInfo:null;return}}}t.blockedOn=null}function pm(t){if(t.blockedOn!==null)return!1;for(var e=t.targetContainers;0<e.length;){var a=Dx(t.domEventName,t.eventSystemFlags,e[0],t.nativeEvent);if(a===null){a=t.nativeEvent;var n=new a.constructor(a.type,a);Ix=n,a.target.dispatchEvent(n),Ix=null}else return e=Au(a),e!==null&&m1(e),t.blockedOn=a,!1;e.shift()}return!0}function G2(t,e,a){pm(t)&&a.delete(e)}function a6(){Mx=!1,wr!==null&&pm(wr)&&(wr=null),kr!==null&&pm(kr)&&(kr=null),Sr!==null&&pm(Sr)&&(Sr=null),Rd.forEach(G2),Ld.forEach(G2)}function yc(t,e){t.blockedOn===e&&(t.blockedOn=null,Mx||(Mx=!0,$a.unstable_scheduleCallback($a.unstable_NormalPriority,a6)))}function Od(t){function e(i){return yc(i,t)}if(0<wp.length){yc(wp[0],t);for(var a=1;a<wp.length;a++){var n=wp[a];n.blockedOn===t&&(n.blockedOn=null)}}for(wr!==null&&yc(wr,t),kr!==null&&yc(kr,t),Sr!==null&&yc(Sr,t),Rd.forEach(e),Ld.forEach(e),a=0;a<or.length;a++)n=or[a],n.blockedOn===t&&(n.blockedOn=null);for(;0<or.length&&(a=or[0],a.blockedOn===null);)zN(a),a.blockedOn===null&&or.shift()}var el=Ui.ReactCurrentBatchConfig,Zm=!0;function n6(t,e,a,n){var i=Le,r=el.transition;el.transition=null;try{Le=1,h1(t,e,a,n)}finally{Le=i,el.transition=r}}function i6(t,e,a,n){var i=Le,r=el.transition;el.transition=null;try{Le=4,h1(t,e,a,n)}finally{Le=i,el.transition=r}}function h1(t,e,a,n){if(Zm){var i=Dx(t,e,a,n);if(i===null)Dy(t,e,n,eh,a),W2(t,n);else if(t6(i,t,e,a,n))n.stopPropagation();else if(W2(t,n),e&4&&-1<e6.indexOf(t)){for(;i!==null;){var r=Au(i);if(r!==null&&ON(r),r=Dx(t,e,a,n),r===null&&Dy(t,e,n,eh,a),r===i)break;i=r}i!==null&&n.stopPropagation()}else Dy(t,e,n,null,a)}}var eh=null;function Dx(t,e,a,n){if(eh=null,t=d1(n),t=xo(t),t!==null)if(e=cs(t),e===null)t=null;else if(a=e.tag,a===13){if(t=CN(e),t!==null)return t;t=null}else if(a===3){if(e.stateNode.current.memoizedState.isDehydrated)return e.tag===3?e.stateNode.containerInfo:null;t=null}else e!==t&&(t=null);return eh=t,null}
vendor: 10,401 bytes, line 37
37function VN(t){switch(t){case"cancel":case"click":case"close":case"contextmenu":case"copy":case"cut":case"auxclick":case"dblclick":case"dragend":case"dragstart":case"drop":case"focusin":case"focusout":case"input":case"invalid":case"keydown":case"keypress":case"keyup":case"mousedown":case"mouseup":case"paste":case"pause":case"play":case"pointercancel":case"pointerdown":case"pointerup":case"ratechange":case"reset":case"resize":case"seeked":case"submit":case"touchcancel":case"touchend":case"touchstart":case"volumechange":case"change":case"selectionchange":case"textInput":case"compositionstart":case"compositionend":case"compositionupdate":case"beforeblur":case"afterblur":case"beforeinput":case"blur":case"fullscreenchange":case"focus":case"hashchange":case"popstate":case"select":case"selectstart":return 1;case"drag":case"dragenter":case"dragexit":case"dragleave":case"dragover":case"mousemove":case"mouseout":case"mouseover":case"pointermove":case"pointerout":case"pointerover":case"scroll":case"toggle":case"touchmove":case"wheel":case"mouseenter":case"mouseleave":case"pointerenter":case"pointerleave":return 4;case"message":switch($q()){case u1:return 1;case IN:return 4;case Xm:case Wq:return 16;case PN:return 536870912;default:return 16}default:return 16}}var hr=null,f1=null,mm=null;function HN(){if(mm)return mm;var t,e=f1,a=e.length,n,i="value"in hr?hr.value:hr.textContent,r=i.length;for(t=0;t<a&&e[t]===i[t];t++);var o=a-t;for(n=1;n<=o&&e[a-n]===i[r-n];n++);return mm=i.slice(t,1<n?1-n:void 0)}function hm(t){var e=t.keyCode;return"charCode"in t?(t=t.charCode,t===0&&e===13&&(t=13)):t=e,t===10&&(t=13),32<=t||t===13?t:0}function kp(){return!0}function K2(){return!1}function Ka(t){function e(a,n,i,r,o){this._reactName=a,this._targetInst=i,this.type=n,this.nativeEvent=r,this.target=o,this.currentTarget=null;for(var l in t)t.hasOwnProperty(l)&&(a=t[l],this[l]=a?a(r):r[l]);return this.isDefaultPrevented=(r.defaultPrevented!=null?r.defaultPrevented:r.returnValue===!1)?kp:K2,this.isPropagationStopped=K2,this}return Ze(e.prototype,{preventDefault:function(){this.defaultPrevented=!0;var a=this.nativeEvent;a&&(a.preventDefault?a.preventDefault():typeof a.returnValue!="unknown"&&(a.returnValue=!1),this.isDefaultPrevented=kp)},stopPropagation:function(){var a=this.nativeEvent;a&&(a.stopPropagation?a.stopPropagation():typeof a.cancelBubble!="unknown"&&(a.cancelBubble=!0),this.isPropagationStopped=kp)},persist:function(){},isPersistent:kp}),e}var zl={eventPhase:0,bubbles:0,cancelable:0,timeStamp:function(t){return t.timeStamp||Date.now()},defaultPrevented:0,isTrusted:0},g1=Ka(zl),_u=Ze({},zl,{view:0,detail:0}),r6=Ka(_u),jy,Ty,xc,Vf=Ze({},_u,{screenX:0,screenY:0,clientX:0,clientY:0,pageX:0,pageY:0,ctrlKey:0,shiftKey:0,altKey:0,metaKey:0,getModifierState:y1,button:0,buttons:0,relatedTarget:function(t){return t.relatedTarget===void 0?t.fromElement===t.srcElement?t.toElement:t.fromElement:t.relatedTarget},movementX:function(t){return"movementX"in t?t.movementX:(t!==xc&&(xc&&t.type==="mousemove"?(jy=t.screenX-xc.screenX,Ty=t.screenY-xc.screenY):Ty=jy=0,xc=t),jy)},movementY:function(t){return"movementY"in t?t.movementY:Ty}}),J2=Ka(Vf),o6=Ze({},Vf,{dataTransfer:0}),s6=Ka(o6),l6=Ze({},_u,{relatedTarget:0}),Ny=Ka(l6),c6=Ze({},zl,{animationName:0,elapsedTime:0,pseudoElement:0}),d6=Ka(c6),u6=Ze({},zl,{clipboardData:function(t){return"clipboardData"in t?t.clipboardData:window.clipboardData}}),p6=Ka(u6),m6=Ze({},zl,{data:0}),Q2=Ka(m6),h6={Esc:"Escape",Spacebar:" ",Left:"ArrowLeft",Up:"ArrowUp",Right:"ArrowRight",Down:"ArrowDown",Del:"Delete",Win:"OS",Menu:"ContextMenu",Apps:"ContextMenu",Scroll:"ScrollLock",MozPrintableKey:"Unidentified"},f6={8:"Backspace",9:"Tab",12:"Clear",13:"Enter",16:"Shift",17:"Control",18:"Alt",19:"Pause",20:"CapsLock",27:"Escape",32:" ",33:"PageUp",34:"PageDown",35:"End",36:"Home",37:"ArrowLeft",38:"ArrowUp",39:"ArrowRight",40:"ArrowDown",45:"Insert",46:"Delete",112:"F1",113:"F2",114:"F3",115:"F4",116:"F5",117:"F6",118:"F7",119:"F8",120:"F9",121:"F10",122:"F11",123:"F12",144:"NumLock",145:"ScrollLock",224:"Meta"},g6={Alt:"altKey",Control:"ctrlKey",Meta:"metaKey",Shift:"shiftKey"};function y6(t){var e=this.nativeEvent;return e.getModifierState?e.getModifierState(t):(t=g6[t])?!!e[t]:!1}function y1(){return y6}var x6=Ze({},_u,{key:function(t){if(t.key){var e=h6[t.key]||t.key;if(e!=="Unidentified")return e}return t.type==="keypress"?(t=hm(t),t===13?"Enter":String.fromCharCode(t)):t.type==="keydown"||t.type==="keyup"?f6[t.keyCode]||"Unidentified":""},code:0,location:0,ctrlKey:0,shiftKey:0,altKey:0,metaKey:0,repeat:0,locale:0,getModifierState:y1,charCode:function(t){return t.type==="keypress"?hm(t):0},keyCode:function(t){return t.type==="keydown"||t.type==="keyup"?t.keyCode:0},which:function(t){return t.type==="keypress"?hm(t):t.type==="keydown"||t.type==="keyup"?t.keyCode:0}}),v6=Ka(x6),b6=Ze({},Vf,{pointerId:0,width:0,height:0,pressure:0,tangentialPressure:0,tiltX:0,tiltY:0,twist:0,pointerType:0,isPrimary:0}),X2=Ka(b6),w6=Ze({},_u,{touches:0,targetTouches:0,changedTouches:0,altKey:0,metaKey:0,ctrlKey:0,shiftKey:0,getModifierState:y1}),k6=Ka(w6),S6=Ze({},zl,{propertyName:0,elapsedTime:0,pseudoElement:0}),_6=Ka(S6),A6=Ze({},Vf,{deltaX:function(t){return"deltaX"in t?t.deltaX:"wheelDeltaX"in t?-t.wheelDeltaX:0},deltaY:function(t){return"deltaY"in t?t.deltaY:"wheelDeltaY"in t?-t.wheelDeltaY:"wheelDelta"in t?-t.wheelDelta:0},deltaZ:0,deltaMode:0}),E6=Ka(A6),C6=[9,13,27,32],x1=Ri&&"CompositionEvent"in window,Xc=null;Ri&&"documentMode"in document&&(Xc=document.documentMode);var j6=Ri&&"TextEvent"in window&&!Xc,FN=Ri&&(!x1||Xc&&8<Xc&&11>=Xc),Y2=" ",Z2=!1;function BN(t,e){switch(t){case"keyup":return C6.indexOf(e.keyCode)!==-1;case"keydown":return e.keyCode!==229;case"keypress":case"mousedown":case"focusout":return!0;default:return!1}}function UN(t){return t=t.detail,typeof t=="object"&&"data"in t?t.data:null}var Os=!1;function T6(t,e){switch(t){case"compositionend":return UN(e);case"keypress":return e.which!==32?null:(Z2=!0,Y2);case"textInput":return t=e.data,t===Y2&&Z2?null:t;default:return null}}function N6(t,e){if(Os)return t==="compositionend"||!x1&&BN(t,e)?(t=HN(),mm=f1=hr=null,Os=!1,t):null;switch(t){case"paste":return null;case"keypress":if(!(e.ctrlKey||e.altKey||e.metaKey)||e.ctrlKey&&e.altKey){if(e.char&&1<e.char.length)return e.char;if(e.which)return String.fromCharCode(e.which)}return null;case"compositionend":return FN&&e.locale!=="ko"?null:e.data;default:return null}}var I6={color:!0,date:!0,datetime:!0,"datetime-local":!0,email:!0,month:!0,number:!0,password:!0,range:!0,search:!0,tel:!0,text:!0,time:!0,url:!0,week:!0};function e_(t){var e=t&&t.nodeName&&t.nodeName.toLowerCase();return e==="input"?!!I6[t.type]:e==="textarea"}function $N(t,e,a,n){kN(n),e=th(e,"onChange"),0<e.length&&(a=new g1("onChange","change",null,a,n),t.push({event:a,listeners:e}))}var Yc=null,Md=null;function P6(t){aI(t,0)}function Hf(t){var e=qs(t);if(fN(e))return t}function R6(t,e){if(t==="change")return e}var WN=!1;if(Ri){var Iy;if(Ri){var Py="oninput"in document;if(!Py){var t_=document.createElement("div");t_.setAttribute("oninput","return;"),Py=typeof t_.oninput=="function"}Iy=Py}else Iy=!1;WN=Iy&&(!document.documentMode||9<document.documentMode)}function a_(){Yc&&(Yc.detachEvent("onpropertychange",GN),Md=Yc=null)}function GN(t){if(t.propertyName==="value"&&Hf(Md)){var e=[];$N(e,Md,t,d1(t)),EN(P6,e)}}function L6(t,e,a){t==="focusin"?(a_(),Yc=e,Md=a,Yc.attachEvent("onpropertychange",GN)):t==="focusout"&&a_()}function O6(t){if(t==="selectionchange"||t==="keyup"||t==="keydown")return Hf(Md)}function M6(t,e){if(t==="click")return Hf(e)}function D6(t,e){if(t==="input"||t==="change")return Hf(e)}function q6(t,e){return t===e&&(t!==0||1/t===1/e)||t!==t&&e!==e}var Ln=typeof Object.is=="function"?Object.is:q6;function Dd(t,e){if(Ln(t,e))return!0;if(typeof t!="object"||t===null||typeof e!="object"||e===null)return!1;var a=Object.keys(t),n=Object.keys(e);if(a.length!==n.length)return!1;for(n=0;n<a.length;n++){var i=a[n];if(!vx.call(e,i)||!Ln(t[i],e[i]))return!1}return!0}function n_(t){for(;t&&t.firstChild;)t=t.firstChild;return t}function i_(t,e){var a=n_(t);t=0;for(var n;a;){if(a.nodeType===3){if(n=t+a.textContent.length,t<=e&&n>=e)return{node:a,offset:e-t};t=n}e:{for(;a;){if(a.nextSibling){a=a.nextSibling;break e}a=a.parentNode}a=void 0}a=n_(a)}}function KN(t,e){return t&&e?t===e?!0:t&&t.nodeType===3?!1:e&&e.nodeType===3?KN(t,e.parentNode):"contains"in t?t.contains(e):t.compareDocumentPosition?!!(t.compareDocumentPosition(e)&16):!1:!1}function JN(){for(var t=window,e=Km();e instanceof t.HTMLIFrameElement;){try{var a=typeof e.contentWindow.location.href=="string"}catch{a=!1}if(a)t=e.contentWindow;else break;e=Km(t.document)}return e}function v1(t){var e=t&&t.nodeName&&t.nodeName.toLowerCase();return e&&(e==="input"&&(t.type==="text"||t.type==="search"||t.type==="tel"||t.type==="url"||t.type==="password")||e==="textarea"||t.contentEditable==="true")}function z6(t){var e=JN(),a=t.focusedElem,n=t.selectionRange;if(e!==a&&a&&a.ownerDocument&&KN(a.ownerDocument.documentElement,a)){if(n!==null&&v1(a)){if(e=n.start,t=n.end,t===void 0&&(t=e),"selectionStart"in a)a.selectionStart=e,a.selectionEnd=Math.min(t,a.value.length);else if(t=(e=a.ownerDocument||document)&&e.defaultView||window,t.getSelection){t=t.getSelection();var i=a.textContent.length,r=Math.min(n.start,i);n=n.end===void 0?r:Math.min(n.end,i),!t.extend&&r>n&&(i=n,n=r,r=i),i=i_(a,r);var o=i_(a,n);i&&o&&(t.rangeCount!==1||t.anchorNode!==i.node||t.anchorOffset!==i.offset||t.focusNode!==o.node||t.focusOffset!==o.offset)&&(e=e.createRange(),e.setStart(i.node,i.offset),t.removeAllRanges(),r>n?(t.addRange(e),t.extend(o.node,o.offset)):(e.setEnd(o.node,o.offset),t.addRange(e)))}}for(e=[],t=a;t=t.parentNode;)t.nodeType===1&&e.push({element:t,left:t.scrollLeft,top:t.scrollTop});for(typeof a.focus=="function"&&a.focus(),a=0;a<e.length;a++)t=e[a],t.element.scrollLeft=t.left,t.element.scrollTop=t.top}}var V6=Ri&&"documentMode"in document&&11>=document.documentMode,Ms=null,qx=null,Zc=null,zx=!1;function r_(t,e,a){var n=a.window===a?a.document:a.nodeType===9?a:a.ownerDocument;zx||Ms==null||Ms!==Km(n)||(n=Ms,"selectionStart"in n&&v1(n)?n={start:n.selectionStart,end:n.selectionEnd}:(n=(n.ownerDocument&&n.ownerDocument.defaultView||window).getSelection(),n={anchorNode:n.anchorNode,anchorOffset:n.anchorOffset,focu
vendor: 4,501 bytes, line 37
37sNode:n.focusNode,focusOffset:n.focusOffset}),Zc&&Dd(Zc,n)||(Zc=n,n=th(qx,"onSelect"),0<n.length&&(e=new g1("onSelect","select",null,e,a),t.push({event:e,listeners:n}),e.target=Ms)))}function Sp(t,e){var a={};return a[t.toLowerCase()]=e.toLowerCase(),a["Webkit"+t]="webkit"+e,a["Moz"+t]="moz"+e,a}var Ds={animationend:Sp("Animation","AnimationEnd"),animationiteration:Sp("Animation","AnimationIteration"),animationstart:Sp("Animation","AnimationStart"),transitionend:Sp("Transition","TransitionEnd")},Ry={},QN={};Ri&&(QN=document.createElement("div").style,"AnimationEvent"in window||(delete Ds.animationend.animation,delete Ds.animationiteration.animation,delete Ds.animationstart.animation),"TransitionEvent"in window||delete Ds.transitionend.transition);function Ff(t){if(Ry[t])return Ry[t];if(!Ds[t])return t;var e=Ds[t],a;for(a in e)if(e.hasOwnProperty(a)&&a in QN)return Ry[t]=e[a];return t}var XN=Ff("animationend"),YN=Ff("animationiteration"),ZN=Ff("animationstart"),eI=Ff("transitionend"),tI=new Map,o_="abort auxClick cancel canPlay canPlayThrough click close contextMenu copy cut drag dragEnd dragEnter dragExit dragLeave dragOver dragStart drop durationChange emptied encrypted ended error gotPointerCapture input invalid keyDown keyPress keyUp load loadedData loadedMetadata loadStart lostPointerCapture mouseDown mouseMove mouseOut mouseOver mouseUp paste pause play playing pointerCancel pointerDown pointerMove pointerOut pointerOver pointerUp progress rateChange reset resize seeked seeking stalled submit suspend timeUpdate touchCancel touchEnd touchStart volumeChange scroll toggle touchMove waiting wheel".split(" ");function Wr(t,e){tI.set(t,e),ls(e,[t])}for(var Ly=0;Ly<o_.length;Ly++){var Oy=o_[Ly],H6=Oy.toLowerCase(),F6=Oy[0].toUpperCase()+Oy.slice(1);Wr(H6,"on"+F6)}Wr(XN,"onAnimationEnd");Wr(YN,"onAnimationIteration");Wr(ZN,"onAnimationStart");Wr("dblclick","onDoubleClick");Wr("focusin","onFocus");Wr("focusout","onBlur");Wr(eI,"onTransitionEnd");pl("onMouseEnter",["mouseout","mouseover"]);pl("onMouseLeave",["mouseout","mouseover"]);pl("onPointerEnter",["pointerout","pointerover"]);pl("onPointerLeave",["pointerout","pointerover"]);ls("onChange","change click focusin focusout input keydown keyup selectionchange".split(" "));ls("onSelect","focusout contextmenu dragend focusin keydown keyup mousedown mouseup selectionchange".split(" "));ls("onBeforeInput",["compositionend","keypress","textInput","paste"]);ls("onCompositionEnd","compositionend focusout keydown keypress keyup mousedown".split(" "));ls("onCompositionStart","compositionstart focusout keydown keypress keyup mousedown".split(" "));ls("onCompositionUpdate","compositionupdate focusout keydown keypress keyup mousedown".split(" "));var Dc="abort canplay canplaythrough durationchange emptied encrypted ended error loadeddata loadedmetadata loadstart pause play playing progress ratechange resize seeked seeking stalled suspend timeupdate volumechange waiting".split(" "),B6=new Set("cancel close invalid load scroll toggle".split(" ").concat(Dc));function s_(t,e,a){var n=t.type||"unknown-event";t.currentTarget=a,Hq(n,e,void 0,t),t.currentTarget=null}function aI(t,e){e=(e&4)!==0;for(var a=0;a<t.length;a++){var n=t[a],i=n.event;n=n.listeners;e:{var r=void 0;if(e)for(var o=n.length-1;0<=o;o--){var l=n[o],c=l.instance,d=l.currentTarget;if(l=l.listener,c!==r&&i.isPropagationStopped())break e;s_(i,l,d),r=c}else for(o=0;o<n.length;o++){if(l=n[o],c=l.instance,d=l.currentTarget,l=l.listener,c!==r&&i.isPropagationStopped())break e;s_(i,l,d),r=c}}}if(Qm)throw t=Lx,Qm=!1,Lx=null,t}function Fe(t,e){var a=e[Ux];a===void 0&&(a=e[Ux]=new Set);var n=t+"__bubble";a.has(n)||(nI(e,t,2,!1),a.add(n))}function My(t,e,a){var n=0;e&&(n|=4),nI(a,t,n,e)}var _p="_reactListening"+Math.random().toString(36).slice(2);function qd(t){if(!t[_p]){t[_p]=!0,dN.forEach(function(a){a!=="selectionchange"&&(B6.has(a)||My(a,!1,t),My(a,!0,t))});var e=t.nodeType===9?t:t.ownerDocument;e===null||e[_p]||(e[_p]=!0,My("selectionchange",!1,e))}}function nI(t,e,a,n){switch(VN(e)){case 1:var i=n6;break;case 4:i=i6;break;default:i=h1}a=i.bind(null,e,a,t),i=void 0,!Rx||e!=="touchstart"&&e!=="touchmove"&&e!=="wheel"||(i=!0),n?i!==void 0?t.addEventListener(e,a,{capture:!0,passive:i}):t.addEventListener(e,a,!0):i!==void 0?t.addEventListener(e,a,{passive:i}):t.addEventListener(e,a,!1)}function Dy(t,e,a,n,i){var r=n;if(!(e&1)&&!(e&2)&&n!==null)e:for(;;){if(n===null)return;var o=n.tag;if(o===3||o===4){var l=n.stateNode.containerInfo;
vendor: 5,316 bytes, lines 37-38
37if(l===i||l.nodeType===8&&l.parentNode===i)break;if(o===4)for(o=n.return;o!==null;){var c=o.tag;if((c===3||c===4)&&(c=o.stateNode.containerInfo,c===i||c.nodeType===8&&c.parentNode===i))return;o=o.return}for(;l!==null;){if(o=xo(l),o===null)return;if(c=o.tag,c===5||c===6){n=r=o;continue e}l=l.parentNode}}n=n.return}EN(function(){var d=r,u=d1(a),p=[];e:{var m=tI.get(t);if(m!==void 0){var h=g1,g=t;switch(t){case"keypress":if(hm(a)===0)break e;case"keydown":case"keyup":h=v6;break;case"focusin":g="focus",h=Ny;break;case"focusout":g="blur",h=Ny;break;case"beforeblur":case"afterblur":h=Ny;break;case"click":if(a.button===2)break e;case"auxclick":case"dblclick":case"mousedown":case"mousemove":case"mouseup":case"mouseout":case"mouseover":case"contextmenu":h=J2;break;case"drag":case"dragend":case"dragenter":case"dragexit":case"dragleave":case"dragover":case"dragstart":case"drop":h=s6;break;case"touchcancel":case"touchend":case"touchmove":case"touchstart":h=k6;break;case XN:case YN:case ZN:h=d6;break;case eI:h=_6;break;case"scroll":h=r6;break;case"wheel":h=E6;break;case"copy":case"cut":case"paste":h=p6;break;case"gotpointercapture":case"lostpointercapture":case"pointercancel":case"pointerdown":case"pointermove":case"pointerout":case"pointerover":case"pointerup":h=X2}var y=(e&4)!==0,x=!y&&t==="scroll",v=y?m!==null?m+"Capture":null:m;y=[];for(var w=d,S;w!==null;){S=w;var T=S.stateNode;if(S.tag===5&&T!==null&&(S=T,v!==null&&(T=Pd(w,v),T!=null&&y.push(zd(w,T,S)))),x)break;w=w.return}0<y.length&&(m=new h(m,g,null,a,u),p.push({event:m,listeners:y}))}}if(!(e&7)){e:{if(m=t==="mouseover"||t==="pointerover",h=t==="mouseout"||t==="pointerout",m&&a!==Ix&&(g=a.relatedTarget||a.fromElement)&&(xo(g)||g[Li]))break e;if((h||m)&&(m=u.window===u?u:(m=u.ownerDocument)?m.defaultView||m.parentWindow:window,h?(g=a.relatedTarget||a.toElement,h=d,g=g?xo(g):null,g!==null&&(x=cs(g),g!==x||g.tag!==5&&g.tag!==6)&&(g=null)):(h=null,g=d),h!==g)){if(y=J2,T="onMouseLeave",v="onMouseEnter",w="mouse",(t==="pointerout"||t==="pointerover")&&(y=X2,T="onPointerLeave",v="onPointerEnter",w="pointer"),x=h==null?m:qs(h),S=g==null?m:qs(g),m=new y(T,w+"leave",h,a,u),m.target=x,m.relatedTarget=S,T=null,xo(u)===d&&(y=new y(v,w+"enter",g,a,u),y.target=S,y.relatedTarget=x,T=y),x=T,h&&g)t:{for(y=h,v=g,w=0,S=y;S;S=ws(S))w++;for(S=0,T=v;T;T=ws(T))S++;for(;0<w-S;)y=ws(y),w--;for(;0<S-w;)v=ws(v),S--;for(;w--;){if(y===v||v!==null&&y===v.alternate)break t;y=ws(y),v=ws(v)}y=null}else y=null;h!==null&&l_(p,m,h,y,!1),g!==null&&x!==null&&l_(p,x,g,y,!0)}}e:{if(m=d?qs(d):window,h=m.nodeName&&m.nodeName.toLowerCase(),h==="select"||h==="input"&&m.type==="file")var P=R6;else if(e_(m))if(WN)P=D6;else{P=O6;var M=L6}else(h=m.nodeName)&&h.toLowerCase()==="input"&&(m.type==="checkbox"||m.type==="radio")&&(P=M6);if(P&&(P=P(t,d))){$N(p,P,a,u);break e}M&&M(t,m,d),t==="focusout"&&(M=m._wrapperState)&&M.controlled&&m.type==="number"&&Ex(m,"number",m.value)}switch(M=d?qs(d):window,t){case"focusin":(e_(M)||M.contentEditable==="true")&&(Ms=M,qx=d,Zc=null);break;case"focusout":Zc=qx=Ms=null;break;case"mousedown":zx=!0;break;case"contextmenu":case"mouseup":case"dragend":zx=!1,r_(p,a,u);break;case"selectionchange":if(V6)break;case"keydown":case"keyup":r_(p,a,u)}var C;if(x1)e:{switch(t){case"compositionstart":var E="onCompositionStart";break e;case"compositionend":E="onCompositionEnd";break e;case"compositionupdate":E="onCompositionUpdate";break e}E=void 0}else Os?BN(t,a)&&(E="onCompositionEnd"):t==="keydown"&&a.keyCode===229&&(E="onCompositionStart");E&&(FN&&a.locale!=="ko"&&(Os||E!=="onCompositionStart"?E==="onCompositionEnd"&&Os&&(C=HN()):(hr=u,f1="value"in hr?hr.value:hr.textContent,Os=!0)),M=th(d,E),0<M.length&&(E=new Q2(E,t,null,a,u),p.push({event:E,listeners:M}),C?E.data=C:(C=UN(a),C!==null&&(E.data=C)))),(C=j6?T6(t,a):N6(t,a))&&(d=th(d,"onBeforeInput"),0<d.length&&(u=new Q2("onBeforeInput","beforeinput",null,a,u),p.push({event:u,listeners:d}),u.data=C))}aI(p,e)})}function zd(t,e,a){return{instance:t,listener:e,currentTarget:a}}function th(t,e){for(var a=e+"Capture",n=[];t!==null;){var i=t,r=i.stateNode;i.tag===5&&r!==null&&(i=r,r=Pd(t,a),r!=null&&n.unshift(zd(t,r,i)),r=Pd(t,e),r!=null&&n.push(zd(t,r,i))),t=t.return}return n}function ws(t){if(t===null)return null;do t=t.return;while(t&&t.tag!==5);return t||null}function l_(t,e,a,n,i){for(var r=e._reactName,o=[];a!==null&&a!==n;){var l=a,c=l.alternate,d=l.stateNode;if(c!==null&&c===n)break;l.tag===5&&d!==null&&(l=d,i?(c=Pd(a,r),c!=null&&o.unshift(zd(a,c,l))):i||(c=Pd(a,r),c!=null&&o.push(zd(a,c,l)))),a=a.return}o.length!==0&&t.push({event:e,listeners:o})}var U6=/\r\n?/g,$6=/\u0000|\uFFFD/g;function c_(t){return(typeof t=="string"?t:""+t).replace(U6,`
38`).replace($6,"")}function Ap(t,e,a){if(e=c_(e),c_(t)!==e&&a)throw Error(U(425))}function ah(){}var Vx=null,Hx=null;function Fx(t,e){return t==="textarea"||t==="noscript"||typeof e.children=="string"||typeof e.children=="number"||typeof e.dangerouslySetInnerHTML=="object"&&e.dangerouslySetInnerHTML!==null&&e.dangerouslySetInnerHTML.__html!=null}var Bx=typeof setTimeout=="function"?setTimeout:void 0,W6=typeof clearTimeout=="function"?clearTimeout:void 0,d_=typeof Promise=="function"?Promise:void 0,G6=typeof queueMicrotask=="function"?queueMicrotask:typeof d_<"u"?function(t){return d_.resolve(null).then(t).cat
vendor: 4,633 bytes, line 38
38ch(K6)}:Bx;function K6(t){setTimeout(function(){throw t})}function qy(t,e){var a=e,n=0;do{var i=a.nextSibling;if(t.removeChild(a),i&&i.nodeType===8)if(a=i.data,a==="/$"){if(n===0){t.removeChild(i),Od(e);return}n--}else a!=="$"&&a!=="$?"&&a!=="$!"||n++;a=i}while(a);Od(e)}function _r(t){for(;t!=null;t=t.nextSibling){var e=t.nodeType;if(e===1||e===3)break;if(e===8){if(e=t.data,e==="$"||e==="$!"||e==="$?")break;if(e==="/$")return null}}return t}function u_(t){t=t.previousSibling;for(var e=0;t;){if(t.nodeType===8){var a=t.data;if(a==="$"||a==="$!"||a==="$?"){if(e===0)return t;e--}else a==="/$"&&e++}t=t.previousSibling}return null}var Vl=Math.random().toString(36).slice(2),Wn="__reactFiber$"+Vl,Vd="__reactProps$"+Vl,Li="__reactContainer$"+Vl,Ux="__reactEvents$"+Vl,J6="__reactListeners$"+Vl,Q6="__reactHandles$"+Vl;function xo(t){var e=t[Wn];if(e)return e;for(var a=t.parentNode;a;){if(e=a[Li]||a[Wn]){if(a=e.alternate,e.child!==null||a!==null&&a.child!==null)for(t=u_(t);t!==null;){if(a=t[Wn])return a;t=u_(t)}return e}t=a,a=t.parentNode}return null}function Au(t){return t=t[Wn]||t[Li],!t||t.tag!==5&&t.tag!==6&&t.tag!==13&&t.tag!==3?null:t}function qs(t){if(t.tag===5||t.tag===6)return t.stateNode;throw Error(U(33))}function Bf(t){return t[Vd]||null}var $x=[],zs=-1;function Gr(t){return{current:t}}function $e(t){0>zs||(t.current=$x[zs],$x[zs]=null,zs--)}function Ve(t,e){zs++,$x[zs]=t.current,t.current=e}var qr={},ia=Gr(qr),Ea=Gr(!1),Bo=qr;function ml(t,e){var a=t.type.contextTypes;if(!a)return qr;var n=t.stateNode;if(n&&n.__reactInternalMemoizedUnmaskedChildContext===e)return n.__reactInternalMemoizedMaskedChildContext;var i={},r;for(r in a)i[r]=e[r];return n&&(t=t.stateNode,t.__reactInternalMemoizedUnmaskedChildContext=e,t.__reactInternalMemoizedMaskedChildContext=i),i}function Ca(t){return t=t.childContextTypes,t!=null}function nh(){$e(Ea),$e(ia)}function p_(t,e,a){if(ia.current!==qr)throw Error(U(168));Ve(ia,e),Ve(Ea,a)}function iI(t,e,a){var n=t.stateNode;if(e=e.childContextTypes,typeof n.getChildContext!="function")return a;n=n.getChildContext();for(var i in n)if(!(i in e))throw Error(U(108,Lq(t)||"Unknown",i));return Ze({},a,n)}function ih(t){return t=(t=t.stateNode)&&t.__reactInternalMemoizedMergedChildContext||qr,Bo=ia.current,Ve(ia,t),Ve(Ea,Ea.current),!0}function m_(t,e,a){var n=t.stateNode;if(!n)throw Error(U(169));a?(t=iI(t,e,Bo),n.__reactInternalMemoizedMergedChildContext=t,$e(Ea),$e(ia),Ve(ia,t)):$e(Ea),Ve(Ea,a)}var yi=null,Uf=!1,zy=!1;function rI(t){yi===null?yi=[t]:yi.push(t)}function X6(t){Uf=!0,rI(t)}function Kr(){if(!zy&&yi!==null){zy=!0;var t=0,e=Le;try{var a=yi;for(Le=1;t<a.length;t++){var n=a[t];do n=n(!0);while(n!==null)}yi=null,Uf=!1}catch(i){throw yi!==null&&(yi=yi.slice(t+1)),NN(u1,Kr),i}finally{Le=e,zy=!1}}return null}var Vs=[],Hs=0,rh=null,oh=0,nn=[],rn=0,Uo=null,vi=1,bi="";function po(t,e){Vs[Hs++]=oh,Vs[Hs++]=rh,rh=t,oh=e}function oI(t,e,a){nn[rn++]=vi,nn[rn++]=bi,nn[rn++]=Uo,Uo=t;var n=vi;t=bi;var i=32-Tn(n)-1;n&=~(1<<i),a+=1;var r=32-Tn(e)+i;if(30<r){var o=i-i%5;r=(n&(1<<o)-1).toString(32),n>>=o,i-=o,vi=1<<32-Tn(e)+i|a<<i|n,bi=r+t}else vi=1<<r|a<<i|n,bi=t}function b1(t){t.return!==null&&(po(t,1),oI(t,1,0))}function w1(t){for(;t===rh;)rh=Vs[--Hs],Vs[Hs]=null,oh=Vs[--Hs],Vs[Hs]=null;for(;t===Uo;)Uo=nn[--rn],nn[rn]=null,bi=nn[--rn],nn[rn]=null,vi=nn[--rn],nn[rn]=null}var Fa=null,za=null,Ge=!1,_n=null;function sI(t,e){var a=sn(5,null,null,0);a.elementType="DELETED",a.stateNode=e,a.return=t,e=t.deletions,e===null?(t.deletions=[a],t.flags|=16):e.push(a)}function h_(t,e){switch(t.tag){case 5:var a=t.type;return e=e.nodeType!==1||a.toLowerCase()!==e.nodeName.toLowerCase()?null:e,e!==null?(t.stateNode=e,Fa=t,za=_r(e.firstChild),!0):!1;case 6:return e=t.pendingProps===""||e.nodeType!==3?null:e,e!==null?(t.stateNode=e,Fa=t,za=null,!0):!1;case 13:return e=e.nodeType!==8?null:e,e!==null?(a=Uo!==null?{id:vi,overflow:bi}:null,t.memoizedState={dehydrated:e,treeContext:a,retryLane:1073741824},a=sn(18,null,null,0),a.stateNode=e,a.return=t,t.child=a,Fa=t,za=null,!0):!1;default:return!1}}function Wx(t){return(t.mode&1)!==0&&(t.flags&128)===0}function Gx(t){if(Ge){var e=za;if(e){var a=e;if(!h_(t,e)){if(Wx(t))throw Error(U(418));e=_r(a.nextSibling);var n=Fa;e&&h_(t,e)?sI(n,a):(t.flags=t.flags&-4097|2,Ge=!1,Fa=t)}}else{if(Wx(t))throw Error(U(418));t.flags=t.flags&-4097|2,Ge=!1,Fa=t}}}function f_(t){for(t=t.return;t!==null&&t.tag!==5&&t.tag!==3&&t.tag!==13;)t=t.return;Fa=t}function Ep(t){if(t!==Fa)return!1;if(!Ge)return f_(t),Ge=!0,!1;var e;if((e=t.tag!==3)&&!(e=t.tag!==5)&&(e=t.type,e=e!=="head"&&e!=="body"&&!Fx(t.type,t.memoizedProps)),e&&(e=za)){if
vendor: 10,470 bytes, line 38
38(Wx(t))throw lI(),Error(U(418));for(;e;)sI(t,e),e=_r(e.nextSibling)}if(f_(t),t.tag===13){if(t=t.memoizedState,t=t!==null?t.dehydrated:null,!t)throw Error(U(317));e:{for(t=t.nextSibling,e=0;t;){if(t.nodeType===8){var a=t.data;if(a==="/$"){if(e===0){za=_r(t.nextSibling);break e}e--}else a!=="$"&&a!=="$!"&&a!=="$?"||e++}t=t.nextSibling}za=null}}else za=Fa?_r(t.stateNode.nextSibling):null;return!0}function lI(){for(var t=za;t;)t=_r(t.nextSibling)}function hl(){za=Fa=null,Ge=!1}function k1(t){_n===null?_n=[t]:_n.push(t)}var Y6=Ui.ReactCurrentBatchConfig;function vc(t,e,a){if(t=a.ref,t!==null&&typeof t!="function"&&typeof t!="object"){if(a._owner){if(a=a._owner,a){if(a.tag!==1)throw Error(U(309));var n=a.stateNode}if(!n)throw Error(U(147,t));var i=n,r=""+t;return e!==null&&e.ref!==null&&typeof e.ref=="function"&&e.ref._stringRef===r?e.ref:(e=function(o){var l=i.refs;o===null?delete l[r]:l[r]=o},e._stringRef=r,e)}if(typeof t!="string")throw Error(U(284));if(!a._owner)throw Error(U(290,t))}return t}function Cp(t,e){throw t=Object.prototype.toString.call(e),Error(U(31,t==="[object Object]"?"object with keys {"+Object.keys(e).join(", ")+"}":t))}function g_(t){var e=t._init;return e(t._payload)}function cI(t){function e(v,w){if(t){var S=v.deletions;S===null?(v.deletions=[w],v.flags|=16):S.push(w)}}function a(v,w){if(!t)return null;for(;w!==null;)e(v,w),w=w.sibling;return null}function n(v,w){for(v=new Map;w!==null;)w.key!==null?v.set(w.key,w):v.set(w.index,w),w=w.sibling;return v}function i(v,w){return v=jr(v,w),v.index=0,v.sibling=null,v}function r(v,w,S){return v.index=S,t?(S=v.alternate,S!==null?(S=S.index,S<w?(v.flags|=2,w):S):(v.flags|=2,w)):(v.flags|=1048576,w)}function o(v){return t&&v.alternate===null&&(v.flags|=2),v}function l(v,w,S,T){return w===null||w.tag!==6?(w=Wy(S,v.mode,T),w.return=v,w):(w=i(w,S),w.return=v,w)}function c(v,w,S,T){var P=S.type;return P===Ls?u(v,w,S.props.children,T,S.key):w!==null&&(w.elementType===P||typeof P=="object"&&P!==null&&P.$$typeof===tr&&g_(P)===w.type)?(T=i(w,S.props),T.ref=vc(v,w,S),T.return=v,T):(T=wm(S.type,S.key,S.props,null,v.mode,T),T.ref=vc(v,w,S),T.return=v,T)}function d(v,w,S,T){return w===null||w.tag!==4||w.stateNode.containerInfo!==S.containerInfo||w.stateNode.implementation!==S.implementation?(w=Gy(S,v.mode,T),w.return=v,w):(w=i(w,S.children||[]),w.return=v,w)}function u(v,w,S,T,P){return w===null||w.tag!==7?(w=Po(S,v.mode,T,P),w.return=v,w):(w=i(w,S),w.return=v,w)}function p(v,w,S){if(typeof w=="string"&&w!==""||typeof w=="number")return w=Wy(""+w,v.mode,S),w.return=v,w;if(typeof w=="object"&&w!==null){switch(w.$$typeof){case gp:return S=wm(w.type,w.key,w.props,null,v.mode,S),S.ref=vc(v,null,w),S.return=v,S;case Rs:return w=Gy(w,v.mode,S),w.return=v,w;case tr:var T=w._init;return p(v,T(w._payload),S)}if(Oc(w)||hc(w))return w=Po(w,v.mode,S,null),w.return=v,w;Cp(v,w)}return null}function m(v,w,S,T){var P=w!==null?w.key:null;if(typeof S=="string"&&S!==""||typeof S=="number")return P!==null?null:l(v,w,""+S,T);if(typeof S=="object"&&S!==null){switch(S.$$typeof){case gp:return S.key===P?c(v,w,S,T):null;case Rs:return S.key===P?d(v,w,S,T):null;case tr:return P=S._init,m(v,w,P(S._payload),T)}if(Oc(S)||hc(S))return P!==null?null:u(v,w,S,T,null);Cp(v,S)}return null}function h(v,w,S,T,P){if(typeof T=="string"&&T!==""||typeof T=="number")return v=v.get(S)||null,l(w,v,""+T,P);if(typeof T=="object"&&T!==null){switch(T.$$typeof){case gp:return v=v.get(T.key===null?S:T.key)||null,c(w,v,T,P);case Rs:return v=v.get(T.key===null?S:T.key)||null,d(w,v,T,P);case tr:var M=T._init;return h(v,w,S,M(T._payload),P)}if(Oc(T)||hc(T))return v=v.get(S)||null,u(w,v,T,P,null);Cp(w,T)}return null}function g(v,w,S,T){for(var P=null,M=null,C=w,E=w=0,j=null;C!==null&&E<S.length;E++){C.index>E?(j=C,C=null):j=C.sibling;var N=m(v,C,S[E],T);if(N===null){C===null&&(C=j);break}t&&C&&N.alternate===null&&e(v,C),w=r(N,w,E),M===null?P=N:M.sibling=N,M=N,C=j}if(E===S.length)return a(v,C),Ge&&po(v,E),P;if(C===null){for(;E<S.length;E++)C=p(v,S[E],T),C!==null&&(w=r(C,w,E),M===null?P=C:M.sibling=C,M=C);return Ge&&po(v,E),P}for(C=n(v,C);E<S.length;E++)j=h(C,v,E,S[E],T),j!==null&&(t&&j.alternate!==null&&C.delete(j.key===null?E:j.key),w=r(j,w,E),M===null?P=j:M.sibling=j,M=j);return t&&C.forEach(function(L){return e(v,L)}),Ge&&po(v,E),P}function y(v,w,S,T){var P=hc(S);if(typeof P!="function")throw Error(U(150));if(S=P.call(S),S==null)throw Error(U(151));for(var M=P=null,C=w,E=w=0,j=null,N=S.next();C!==null&&!N.done;E++,N=S.next()){C.index>E?(j=C,C=null):j=C.sibling;var L=m(v,C,N.value,T);if(L===null){C===null&&(C=j);break}t&&C&&L.alternate===null&&e(v,C),w=r(L,w,E),M===null?P=L:M.sibling=L,M=L,C=j}if(N.done)return a(v,C),Ge&&po(v,E),P;if(C===null){for(;!N.done;E++,N=S.next())N=p(v,N.value,T),N!==null&&(w=r(N,w,E),M===null?P=N:M.sibling=N,M=N);return Ge&&po(v,E),P}for(C=n(v,C);!N.done;E++,N=S.next())N=h(C,v,E,N.value,T),N!==null&&(t&&N.alternate!==null&&C.delete(N.key===null?E:N.key),w=r(N,w,E),M===null?P=N:M.sibling=N,M=N);return t&&C.forEach(function(O){return e(v,O)}),Ge&&po(v,E),P}function x(v,w,S,T){if(typeof S=="object"&&S!==null&&S.type===Ls&&S.key===null&&(S=S.props.children),typeof S=="object"&&S!==null){switch(S.$$typeof){case gp:e:{for(var P=S.key,M=w;M!==null;){if(M.key===P){if(P=S.type,P===Ls){if(M.tag===7){a(v,M.sibling),w=i(M,S.props.children),w.return=v,v=w;break e}}else if(M.elementType===P||typeof P=="object"&&P!==null&&P.$$typeof===tr&&g_(P)===M.type){a(v,M.sibling),w=i(M,S.props),w.ref=vc(v,M,S),w.return=v,v=w;break e}a(v,M);break}else e(v,M);M=M.sibling}S.type===Ls?(w=Po(S.props.children,v.mode,T,S.key),w.return=v,v=w):(T=wm(S.type,S.key,S.props,null,v.mode,T),T.ref=vc(v,w,S),T.return=v,v=T)}return o(v);case Rs:e:{for(M=S.key;w!==null;){if(w.key===M)if(w.tag===4&&w.stateNode.containerInfo===S.containerInfo&&w.stateNode.implementation===S.implementation){a(v,w.sibling),w=i(w,S.children||[]),w.return=v,v=w;break e}else{a(v,w);break}else e(v,w);w=w.sibling}w=Gy(S,v.mode,T),w.return=v,v=w}return o(v);case tr:return M=S._init,x(v,w,M(S._payload),T)}if(Oc(S))return g(v,w,S,T);if(hc(S))return y(v,w,S,T);Cp(v,S)}return typeof S=="string"&&S!==""||typeof S=="number"?(S=""+S,w!==null&&w.tag===6?(a(v,w.sibling),w=i(w,S),w.return=v,v=w):(a(v,w),w=Wy(S,v.mode,T),w.return=v,v=w),o(v)):a(v,w)}return x}var fl=cI(!0),dI=cI(!1),sh=Gr(null),lh=null,Fs=null,S1=null;function _1(){S1=Fs=lh=null}function A1(t){var e=sh.current;$e(sh),t._currentValue=e}function Kx(t,e,a){for(;t!==null;){var n=t.alternate;if((t.childLanes&e)!==e?(t.childLanes|=e,n!==null&&(n.childLanes|=e)):n!==null&&(n.childLanes&e)!==e&&(n.childLanes|=e),t===a)break;t=t.return}}function tl(t,e){lh=t,S1=Fs=null,t=t.dependencies,t!==null&&t.firstContext!==null&&(t.lanes&e&&(Aa=!0),t.firstContext=null)}function pn(t){var e=t._currentValue;if(S1!==t)if(t={context:t,memoizedValue:e,next:null},Fs===null){if(lh===null)throw Error(U(308));Fs=t,lh.dependencies={lanes:0,firstContext:t}}else Fs=Fs.next=t;return e}var vo=null;function E1(t){vo===null?vo=[t]:vo.push(t)}function uI(t,e,a,n){var i=e.interleaved;return i===null?(a.next=a,E1(e)):(a.next=i.next,i.next=a),e.interleaved=a,Oi(t,n)}function Oi(t,e){t.lanes|=e;var a=t.alternate;for(a!==null&&(a.lanes|=e),a=t,t=t.return;t!==null;)t.childLanes|=e,a=t.alternate,a!==null&&(a.childLanes|=e),a=t,t=t.return;return a.tag===3?a.stateNode:null}var ar=!1;function C1(t){t.updateQueue={baseState:t.memoizedState,firstBaseUpdate:null,lastBaseUpdate:null,shared:{pending:null,interleaved:null,lanes:0},effects:null}}function pI(t,e){t=t.updateQueue,e.updateQueue===t&&(e.updateQueue={baseState:t.baseState,firstBaseUpdate:t.firstBaseUpdate,lastBaseUpdate:t.lastBaseUpdate,shared:t.shared,effects:t.effects})}function Ei(t,e){return{eventTime:t,lane:e,tag:0,payload:null,callback:null,next:null}}function Ar(t,e,a){var n=t.updateQueue;if(n===null)return null;if(n=n.shared,Ee&2){var i=n.pending;return i===null?e.next=e:(e.next=i.next,i.next=e),n.pending=e,Oi(t,a)}return i=n.interleaved,i===null?(e.next=e,E1(n)):(e.next=i.next,i.next=e),n.interleaved=e,Oi(t,a)}function fm(t,e,a){if(e=e.updateQueue,e!==null&&(e=e.shared,(a&4194240)!==0)){var n=e.lanes;n&=t.pendingLanes,a|=n,e.lanes=a,p1(t,a)}}function y_(t,e){var a=t.updateQueue,n=t.alternate;if(n!==null&&(n=n.updateQueue,a===n)){var i=null,r=null;if(a=a.firstBaseUpdate,a!==null){do{var o={eventTime:a.eventTime,lane:a.lane,tag:a.tag,payload:a.payload,callback:a.callback,next:null};r===null?i=r=o:r=r.next=o,a=a.next}while(a!==null);r===null?i=r=e:r=r.next=e}else i=r=e;a={baseState:n.baseState,firstBaseUpdate:i,lastBaseUpdate:r,shared:n.shared,effects:n.effects},t.updateQueue=a;return}t=a.lastBaseUpdate,t===null?a.firstBaseUpdate=e:t.next=e,a.lastBaseUpdate=e}function ch(t,e,a,n){var i=t.updateQueue;ar=!1;var r=i.firstBaseUpdate,o=i.lastBaseUpdate,l=i.shared.pending;if(l!==null){i.shared.pending=null;var c=l,d=c.next;c.next=null,o===null?r=d:o.next=d,o=c;var u=t.alternate;u!==null&&(u=u.updateQueue,l=u.lastBaseUpdate,l!==o&&(l===null?u.firstBaseUpdate=d:l.next=d,u.lastBaseUpdate=c))}if(r!==null){var p=i.baseState;o=0,u=d=c=null,l=r;do{var m=l.lane,h=l.eventTime;if((n&m)===m){u!==null&&(u=u.next={eventTime:h,lane:0,tag:l.tag,payload:l.payload,callback:l.callback,next:null});e:{var g=t,y=l;switch(m=e,h=a,y.tag){case 1:if(g=y.payload,typeof g=="function"){p=g.call(h,p,m);break e}p=g;break e;case 3:g.flags=g.flags&-65537|128;case 0:if(g=y.payload,m=typeof g=="function"?g.call(h,p,m):g,m==null)break e;p=Ze({},p,m);break e;case 2:ar=!0}}l.callback!==null&&l.lane!==0&&(t.flags|=64,m=i.effects,m===null?i.effects=[l]:m.push(l))}else h={eventTime:h,lane:m,tag:l.tag,payload:l.payload,callback:l.callback,next:null},u===null?(d=u=h,c=p):u=u.next=h,o|=m;if(l=l.next,l===null){if(l=i.shared.pending,l===null)break;m=l,l=m.next,m.next=null,i.lastBaseUpdate=m,i.shared.pending=null}}while(!0);if(u===null&&(c=p),i.baseState=c,i.firstBaseUpdate=d,i.lastBaseUpdate=u,e=i.shared.interleaved,e!==null){i=e;do o|=i.lane,i=i.next;while(i!==e)}else r===null&&(i.shared.lanes=0);Wo|=o,t.lanes=o,t.memoizedState=p}}function x_(t,e,a){if(t=e.effects,e.effects=null,t!==null)for(e=0;e<t.length;e++){var n=t[e],i=n.callback;if(i!==null){if(n.callback=null,n=a,typeof i!="function")throw Error(U(191,i));i.call(n)}}}var Eu={},Yn=Gr(Eu),Hd=Gr(Eu),Fd=Gr(Eu);function bo(t){if(t===Eu)throw Error(U(174));return t}function j1(t,e){switch(Ve(Fd,e),Ve(Hd,t),Ve(Yn,Eu),t=e.nodeType,t){case 9:case 11:e=(e
vendor: 6,847 bytes, line 38
38=e.documentElement)?e.namespaceURI:jx(null,"");break;default:t=t===8?e.parentNode:e,e=t.namespaceURI||null,t=t.tagName,e=jx(e,t)}$e(Yn),Ve(Yn,e)}function gl(){$e(Yn),$e(Hd),$e(Fd)}function mI(t){bo(Fd.current);var e=bo(Yn.current),a=jx(e,t.type);e!==a&&(Ve(Hd,t),Ve(Yn,a))}function T1(t){Hd.current===t&&($e(Yn),$e(Hd))}var Je=Gr(0);function dh(t){for(var e=t;e!==null;){if(e.tag===13){var a=e.memoizedState;if(a!==null&&(a=a.dehydrated,a===null||a.data==="$?"||a.data==="$!"))return e}else if(e.tag===19&&e.memoizedProps.revealOrder!==void 0){if(e.flags&128)return e}else if(e.child!==null){e.child.return=e,e=e.child;continue}if(e===t)break;for(;e.sibling===null;){if(e.return===null||e.return===t)return null;e=e.return}e.sibling.return=e.return,e=e.sibling}return null}var Vy=[];function N1(){for(var t=0;t<Vy.length;t++)Vy[t]._workInProgressVersionPrimary=null;Vy.length=0}var gm=Ui.ReactCurrentDispatcher,Hy=Ui.ReactCurrentBatchConfig,$o=0,Ye=null,wt=null,jt=null,uh=!1,ed=!1,Bd=0,Z6=0;function Qt(){throw Error(U(321))}function I1(t,e){if(e===null)return!1;for(var a=0;a<e.length&&a<t.length;a++)if(!Ln(t[a],e[a]))return!1;return!0}function P1(t,e,a,n,i,r){if($o=r,Ye=e,e.memoizedState=null,e.updateQueue=null,e.lanes=0,gm.current=t===null||t.memoizedState===null?nz:iz,t=a(n,i),ed){r=0;do{if(ed=!1,Bd=0,25<=r)throw Error(U(301));r+=1,jt=wt=null,e.updateQueue=null,gm.current=rz,t=a(n,i)}while(ed)}if(gm.current=ph,e=wt!==null&&wt.next!==null,$o=0,jt=wt=Ye=null,uh=!1,e)throw Error(U(300));return t}function R1(){var t=Bd!==0;return Bd=0,t}function Fn(){var t={memoizedState:null,baseState:null,baseQueue:null,queue:null,next:null};return jt===null?Ye.memoizedState=jt=t:jt=jt.next=t,jt}function mn(){if(wt===null){var t=Ye.alternate;t=t!==null?t.memoizedState:null}else t=wt.next;var e=jt===null?Ye.memoizedState:jt.next;if(e!==null)jt=e,wt=t;else{if(t===null)throw Error(U(310));wt=t,t={memoizedState:wt.memoizedState,baseState:wt.baseState,baseQueue:wt.baseQueue,queue:wt.queue,next:null},jt===null?Ye.memoizedState=jt=t:jt=jt.next=t}return jt}function Ud(t,e){return typeof e=="function"?e(t):e}function Fy(t){var e=mn(),a=e.queue;if(a===null)throw Error(U(311));a.lastRenderedReducer=t;var n=wt,i=n.baseQueue,r=a.pending;if(r!==null){if(i!==null){var o=i.next;i.next=r.next,r.next=o}n.baseQueue=i=r,a.pending=null}if(i!==null){r=i.next,n=n.baseState;var l=o=null,c=null,d=r;do{var u=d.lane;if(($o&u)===u)c!==null&&(c=c.next={lane:0,action:d.action,hasEagerState:d.hasEagerState,eagerState:d.eagerState,next:null}),n=d.hasEagerState?d.eagerState:t(n,d.action);else{var p={lane:u,action:d.action,hasEagerState:d.hasEagerState,eagerState:d.eagerState,next:null};c===null?(l=c=p,o=n):c=c.next=p,Ye.lanes|=u,Wo|=u}d=d.next}while(d!==null&&d!==r);c===null?o=n:c.next=l,Ln(n,e.memoizedState)||(Aa=!0),e.memoizedState=n,e.baseState=o,e.baseQueue=c,a.lastRenderedState=n}if(t=a.interleaved,t!==null){i=t;do r=i.lane,Ye.lanes|=r,Wo|=r,i=i.next;while(i!==t)}else i===null&&(a.lanes=0);return[e.memoizedState,a.dispatch]}function By(t){var e=mn(),a=e.queue;if(a===null)throw Error(U(311));a.lastRenderedReducer=t;var n=a.dispatch,i=a.pending,r=e.memoizedState;if(i!==null){a.pending=null;var o=i=i.next;do r=t(r,o.action),o=o.next;while(o!==i);Ln(r,e.memoizedState)||(Aa=!0),e.memoizedState=r,e.baseQueue===null&&(e.baseState=r),a.lastRenderedState=r}return[r,n]}function hI(){}function fI(t,e){var a=Ye,n=mn(),i=e(),r=!Ln(n.memoizedState,i);if(r&&(n.memoizedState=i,Aa=!0),n=n.queue,L1(xI.bind(null,a,n,t),[t]),n.getSnapshot!==e||r||jt!==null&&jt.memoizedState.tag&1){if(a.flags|=2048,$d(9,yI.bind(null,a,n,i,e),void 0,null),It===null)throw Error(U(349));$o&30||gI(a,e,i)}return i}function gI(t,e,a){t.flags|=16384,t={getSnapshot:e,value:a},e=Ye.updateQueue,e===null?(e={lastEffect:null,stores:null},Ye.updateQueue=e,e.stores=[t]):(a=e.stores,a===null?e.stores=[t]:a.push(t))}function yI(t,e,a,n){e.value=a,e.getSnapshot=n,vI(e)&&bI(t)}function xI(t,e,a){return a(function(){vI(e)&&bI(t)})}function vI(t){var e=t.getSnapshot;t=t.value;try{var a=e();return!Ln(t,a)}catch{return!0}}function bI(t){var e=Oi(t,1);e!==null&&Nn(e,t,1,-1)}function v_(t){var e=Fn();return typeof t=="function"&&(t=t()),e.memoizedState=e.baseState=t,t={pending:null,interleaved:null,lanes:0,dispatch:null,lastRenderedReducer:Ud,lastRenderedState:t},e.queue=t,t=t.dispatch=az.bind(null,Ye,t),[e.memoizedState,t]}function $d(t,e,a,n){return t={tag:t,create:e,destroy:a,deps:n,next:null},e=Ye.updateQueue,e===null?(e={lastEffect:null,stores:null},Ye.updateQueue=e,e.lastEffect=t.next=t):(a=e.lastEffect,a===null?e.lastEffect=t.next=t:(n=a.next,a.next=t,t.next=n,e.lastEffect=t)),t}function wI(){return mn().memoizedState}function ym(t,e,a,n){var i=Fn();Ye.flags|=t,i.memoizedState=$d(1|e,a,void 0,n===void 0?null:n)}function $f(t,e,a,n){var i=mn();n=n===void 0?null:n;var r=void 0;if(wt!==null){var o=wt.memoizedState;if(r=o.destroy,n!==null&&I1(n,o.deps)){i.memoizedState=$d(e,a,r,n);return}}Ye.flags|=t,i.memoizedState=$d(1|e,a,r,n)}function b_(t,e){return ym(8390656,8,t,e)}function L1(t,e){return $f(2048,8,t,e)}function kI(t,e){return $f(4,2,t,e)}function SI(t,e){return $f(4,4,t,e)}function _I(t,e){if(typeof e=="function")return t=t(),e(t),function(){e(null)};if(e!=null)return t=t(),e.current=t,function(){e.current=null}}function AI(t,e,a){return a=a!=null?a.concat([t]):null,$f(4,4,_I.bind(null,e,t),a)}function O1(){}function EI(t,e){var a=mn();e=e===void 0?null:e;var n=a.memoizedState;return n!==null&&e!==null&&I1(e,n[1])?n[0]:(a.memoizedState=[t,e],t)}function CI(t,e){var a=mn();e=e===void 0?null:e;var n=a.memoizedState;return n!==null&&e!==null&&I1(e,n[1])?n[0]:(t=t(),a.memoizedState=[t,e],t)}function jI(t,e,a){return $o&21?(Ln(a,e)||(a=RN(),Ye.lanes|=a,Wo|=a,t.baseState=!0),e):(t.baseState&&(t.baseState=!1,Aa=!0),t.memoizedState=a)}function ez(t,e){var a=Le;Le=a!==0&&4>a?a:4,t(!0);var n=Hy.transition;Hy.transition={};try{t(!1),e()}finally{Le=a,Hy.transition=n}}function TI(){return mn().memoizedState}function tz(t,e,a){var n=Cr(t);if(a={lane:n,action:a,hasEagerState:!1,eagerState:null,next:null},NI(t))II(e,a);else if(a=uI(t,e,a,n),a!==null){var i=fa();Nn(a,t,n,i),PI(a,e,n)}}function az(t,e,a){var n=Cr(t),i={lane:n,action:a,hasEagerState:!1,eagerState:null,next:null};if(NI(t))II(e,i);else{var r=t.alternate;if(t.lanes===0&&(r===null||r.lanes===0)&&(r=e.lastRenderedReducer,r!==null))try{var o=e.lastRenderedState,l=r(o,a);if(i.hasEagerState=!0,i.eagerState=l,Ln(l,o)){var c=e.interleaved;c===null?(i.next=i,E1(e)):(i.next=c.next,c.next=i),e.interleaved=i;return}}catch{}finally{}a=uI(t,e,i,n),a!==null&&(i=fa(),Nn(a,t,n,i),PI(a,e,n))}}function NI(t){var e=t.alternate;return t===Ye||e!==null&&e===Ye}function II(t,e){ed=uh=!0;var a=t.pending;a===null?e.next=e:(e.next=a.next,a.next=e),t.pending=e}function PI(t,e,a){if(a&4194240){var n=e.lanes;
vendor: 8,339 bytes, lines 38-40
38n&=t.pendingLanes,a|=n,e.lanes=a,p1(t,a)}}var ph={readContext:pn,useCallback:Qt,useContext:Qt,useEffect:Qt,useImperativeHandle:Qt,useInsertionEffect:Qt,useLayoutEffect:Qt,useMemo:Qt,useReducer:Qt,useRef:Qt,useState:Qt,useDebugValue:Qt,useDeferredValue:Qt,useTransition:Qt,useMutableSource:Qt,useSyncExternalStore:Qt,useId:Qt,unstable_isNewReconciler:!1},nz={readContext:pn,useCallback:function(t,e){return Fn().memoizedState=[t,e===void 0?null:e],t},useContext:pn,useEffect:b_,useImperativeHandle:function(t,e,a){return a=a!=null?a.concat([t]):null,ym(4194308,4,_I.bind(null,e,t),a)},useLayoutEffect:function(t,e){return ym(4194308,4,t,e)},useInsertionEffect:function(t,e){return ym(4,2,t,e)},useMemo:function(t,e){var a=Fn();return e=e===void 0?null:e,t=t(),a.memoizedState=[t,e],t},useReducer:function(t,e,a){var n=Fn();return e=a!==void 0?a(e):e,n.memoizedState=n.baseState=e,t={pending:null,interleaved:null,lanes:0,dispatch:null,lastRenderedReducer:t,lastRenderedState:e},n.queue=t,t=t.dispatch=tz.bind(null,Ye,t),[n.memoizedState,t]},useRef:function(t){var e=Fn();return t={current:t},e.memoizedState=t},useState:v_,useDebugValue:O1,useDeferredValue:function(t){return Fn().memoizedState=t},useTransition:function(){var t=v_(!1),e=t[0];return t=ez.bind(null,t[1]),Fn().memoizedState=t,[e,t]},useMutableSource:function(){},useSyncExternalStore:function(t,e,a){var n=Ye,i=Fn();if(Ge){if(a===void 0)throw Error(U(407));a=a()}else{if(a=e(),It===null)throw Error(U(349));$o&30||gI(n,e,a)}i.memoizedState=a;var r={value:a,getSnapshot:e};return i.queue=r,b_(xI.bind(null,n,r,t),[t]),n.flags|=2048,$d(9,yI.bind(null,n,r,a,e),void 0,null),a},useId:function(){var t=Fn(),e=It.identifierPrefix;if(Ge){var a=bi,n=vi;a=(n&~(1<<32-Tn(n)-1)).toString(32)+a,e=":"+e+"R"+a,a=Bd++,0<a&&(e+="H"+a.toString(32)),e+=":"}else a=Z6++,e=":"+e+"r"+a.toString(32)+":";return t.memoizedState=e},unstable_isNewReconciler:!1},iz={readContext:pn,useCallback:EI,useContext:pn,useEffect:L1,useImperativeHandle:AI,useInsertionEffect:kI,useLayoutEffect:SI,useMemo:CI,useReducer:Fy,useRef:wI,useState:function(){return Fy(Ud)},useDebugValue:O1,useDeferredValue:function(t){var e=mn();return jI(e,wt.memoizedState,t)},useTransition:function(){var t=Fy(Ud)[0],e=mn().memoizedState;return[t,e]},useMutableSource:hI,useSyncExternalStore:fI,useId:TI,unstable_isNewReconciler:!1},rz={readContext:pn,useCallback:EI,useContext:pn,useEffect:L1,useImperativeHandle:AI,useInsertionEffect:kI,useLayoutEffect:SI,useMemo:CI,useReducer:By,useRef:wI,useState:function(){return By(Ud)},useDebugValue:O1,useDeferredValue:function(t){var e=mn();return wt===null?e.memoizedState=t:jI(e,wt.memoizedState,t)},useTransition:function(){var t=By(Ud)[0],e=mn().memoizedState;return[t,e]},useMutableSource:hI,useSyncExternalStore:fI,useId:TI,unstable_isNewReconciler:!1};function kn(t,e){if(t&&t.defaultProps){e=Ze({},e),t=t.defaultProps;for(var a in t)e[a]===void 0&&(e[a]=t[a]);return e}return e}function Jx(t,e,a,n){e=t.memoizedState,a=a(n,e),a=a==null?e:Ze({},e,a),t.memoizedState=a,t.lanes===0&&(t.updateQueue.baseState=a)}var Wf={isMounted:function(t){return(t=t._reactInternals)?cs(t)===t:!1},enqueueSetState:function(t,e,a){t=t._reactInternals;var n=fa(),i=Cr(t),r=Ei(n,i);r.payload=e,a!=null&&(r.callback=a),e=Ar(t,r,i),e!==null&&(Nn(e,t,i,n),fm(e,t,i))},enqueueReplaceState:function(t,e,a){t=t._reactInternals;var n=fa(),i=Cr(t),r=Ei(n,i);r.tag=1,r.payload=e,a!=null&&(r.callback=a),e=Ar(t,r,i),e!==null&&(Nn(e,t,i,n),fm(e,t,i))},enqueueForceUpdate:function(t,e){t=t._reactInternals;var a=fa(),n=Cr(t),i=Ei(a,n);i.tag=2,e!=null&&(i.callback=e),e=Ar(t,i,n),e!==null&&(Nn(e,t,n,a),fm(e,t,n))}};function w_(t,e,a,n,i,r,o){return t=t.stateNode,typeof t.shouldComponentUpdate=="function"?t.shouldComponentUpdate(n,r,o):e.prototype&&e.prototype.isPureReactComponent?!Dd(a,n)||!Dd(i,r):!0}function RI(t,e,a){var n=!1,i=qr,r=e.contextType;return typeof r=="object"&&r!==null?r=pn(r):(i=Ca(e)?Bo:ia.current,n=e.contextTypes,r=(n=n!=null)?ml(t,i):qr),e=new e(a,r),t.memoizedState=e.state!==null&&e.state!==void 0?e.state:null,e.updater=Wf,t.stateNode=e,e._reactInternals=t,n&&(t=t.stateNode,t.__reactInternalMemoizedUnmaskedChildContext=i,t.__reactInternalMemoizedMaskedChildContext=r),e}function k_(t,e,a,n){t=e.state,typeof e.componentWillReceiveProps=="function"&&e.componentWillReceiveProps(a,n),typeof e.UNSAFE_componentWillReceiveProps=="function"&&e.UNSAFE_componentWillReceiveProps(a,n),e.state!==t&&Wf.enqueueReplaceState(e,e.state,null)}function Qx(t,e,a,n){var i=t.stateNode;i.props=a,i.state=t.memoizedState,i.refs={},C1(t);var r=e.contextType;typeof r=="object"&&r!==null?i.context=pn(r):(r=Ca(e)?Bo:ia.current,i.context=ml(t,r)),i.state=t.memoizedState,r=e.getDerivedStateFromProps,typeof r=="function"&&(Jx(t,e,r,a),i.state=t.memoizedState),typeof e.getDerivedStateFromProps=="function"||typeof i.getSnapshotBeforeUpdate=="function"||typeof i.UNSAFE_componentWillMount!="function"&&typeof i.componentWillMount!="function"||(e=i.state,typeof i.componentWillMount=="function"&&i.componentWillMount(),typeof i.UNSAFE_componentWillMount=="function"&&i.UNSAFE_componentWillMount(),e!==i.state&&Wf.enqueueReplaceState(i,i.state,null),ch(t,a,i,n),i.state=t.memoizedState),typeof i.componentDidMount=="function"&&(t.flags|=4194308)}function yl(t,e){try{var a="",n=e;do a+=Rq(n),n=n.return;while(n);var i=a}catch(r){i=`
39Error generating stack: `+r.message+`
40`+r.stack}return{value:t,source:e,stack:i,digest:null}}function Uy(t,e,a){return{value:t,source:null,stack:a??null,digest:e??null}}function Xx(t,e){try{console.error(e.value)}catch(a){setTimeout(function(){throw a})}}var oz=typeof WeakMap=="function"?WeakMap:Map;function LI(t,e,a){a=Ei(-1,a),a.tag=3,a.payload={element:null};var n=e.value;return a.callback=function(){hh||(hh=!0,sv=n),Xx(t,e)},a}function OI(t,e,a){a=Ei(-1,a),a.tag=3;var n=t.type.getDerivedStateFromError;if(typeof n=="function"){var i=e.value;a.payload=function(){return n(i)},a.callback=function(){Xx(t,e)}}var r=t.stateNode;return r!==null&&typeof r.componentDidCatch=="function"&&(a.callback=function(){Xx(t,e),typeof n!="function"&&(Er===null?Er=new Set([this]):Er.add(this));var o=e.stack;this.componentDidCatch(e.value,{componentStack:o!==null?o:""})}),a}function S_(t,e,a){var n=t.pingCache;if(n===null){n=t.pingCache=new oz;var i=new Set;n.set(e,i)}else i=n.get(e),i===void 0&&(i=new Set,n.set(e,i));i.has(a)||(i.add(a),t=bz.bind(null,t,e,a),e.then(t,t))}function __(t){do{var e;if((e=t.tag===13)&&(e=t.memoizedState,e=e!==null?e.dehydrated!==null:!0),e)return t;t=t.return}while(t!==null);return null}function A_(t,e,a,n,i){return t.mode&1?(t.flags|=65536,t.lanes=i,t):(t===e?t.flags|=65536:(t.flags|=128,a.flags|=131072,a.flags&=-52805,a.tag===1&&(a.alternate===null?a.tag=17:(e=Ei(-1,1),e.tag=2,Ar(a,e,1))),a.lanes|=1),t)}var sz=Ui.ReactCurrentOwner,Aa=!1;function ua(t,e,a,n){e.child=t===null?dI(e,null,a,n):fl(e,t.child,a,n)}function E_(t,e,a,n,i){a=a.render;var r=e.ref;return tl(e,i),n=P1(t,e,a,n,r,i),a=R1(),t!==null&&!Aa?(e.updateQueue=t.updateQueue,e.flags&=-2053,t.lanes&=~i,Mi(t,e,i)):(Ge&&a&&b1(e),e.flags|=1,ua(t,e,n,i),e.child)}function C_(t,e,a,n,i){if(t===null){var r=a.type;return typeof r=="function"&&!B1(r)&&r.defaultProps===void 0&&a.compare===null&&a.defaultProps===void 0?(e.tag=15,e.type=r,MI(t,e,r,n,i)):(t=wm(a.type,null,n,e,e.mode,i),t.ref=e.ref,t.return=e,e.child=t)}if(r=t.child,!(t.lanes&i)){var o=r.memoizedProps;if(a=a.compare,a=a!==null?a:Dd,a(o,n)&&t.ref===e.ref)return Mi(t,e,i)}return e.flags|=1,t=jr(r,n),t.ref=e.ref,t.return=e,e.child=t}function MI(t,e,a,n,i){if(t!==null){var r=t.memoizedProps;if(Dd(r,n)&&t.ref===e.ref)if(Aa=!1,e.pendingProps=n=r,(t.lanes&i)!==0)t.flags&131072&&(Aa=!0);else return e.lanes=t.lanes,Mi(t,e,i)}return Yx(t,e,a,n,i)}function DI(t,e,a){var n=e.pendingProps,i=n.children,r=t!==null?t.memoizedState:null;if(n.mode==="hidden")if(!(e.mode&1))e.memoizedState={baseLanes:0,cachePool:null,transitions:null},Ve(Us,Da),Da|=a;else{if(!(a&1073741824))return t=r!==null?r.baseLanes|a:a,e.lanes=e.childLanes=1073741824,e.memoizedState={baseLanes:t,cachePool:null,transitions:null},e.updateQueue=null,Ve(Us,Da),Da|=t,null;e.memoizedState={baseLanes:0,cachePool:null,transitions:null},n=r!==null?r.baseLanes:a,Ve(Us,Da),Da|=n}else r!==null?(n=r.baseLanes|a,e.memoizedState=null):n=a,Ve(Us,Da),Da|=n;
vendor: 4,972 bytes, line 40
40return ua(t,e,i,a),e.child}function qI(t,e){var a=e.ref;(t===null&&a!==null||t!==null&&t.ref!==a)&&(e.flags|=512,e.flags|=2097152)}function Yx(t,e,a,n,i){var r=Ca(a)?Bo:ia.current;return r=ml(e,r),tl(e,i),a=P1(t,e,a,n,r,i),n=R1(),t!==null&&!Aa?(e.updateQueue=t.updateQueue,e.flags&=-2053,t.lanes&=~i,Mi(t,e,i)):(Ge&&n&&b1(e),e.flags|=1,ua(t,e,a,i),e.child)}function j_(t,e,a,n,i){if(Ca(a)){var r=!0;ih(e)}else r=!1;if(tl(e,i),e.stateNode===null)xm(t,e),RI(e,a,n),Qx(e,a,n,i),n=!0;else if(t===null){var o=e.stateNode,l=e.memoizedProps;o.props=l;var c=o.context,d=a.contextType;typeof d=="object"&&d!==null?d=pn(d):(d=Ca(a)?Bo:ia.current,d=ml(e,d));var u=a.getDerivedStateFromProps,p=typeof u=="function"||typeof o.getSnapshotBeforeUpdate=="function";p||typeof o.UNSAFE_componentWillReceiveProps!="function"&&typeof o.componentWillReceiveProps!="function"||(l!==n||c!==d)&&k_(e,o,n,d),ar=!1;var m=e.memoizedState;o.state=m,ch(e,n,o,i),c=e.memoizedState,l!==n||m!==c||Ea.current||ar?(typeof u=="function"&&(Jx(e,a,u,n),c=e.memoizedState),(l=ar||w_(e,a,l,n,m,c,d))?(p||typeof o.UNSAFE_componentWillMount!="function"&&typeof o.componentWillMount!="function"||(typeof o.componentWillMount=="function"&&o.componentWillMount(),typeof o.UNSAFE_componentWillMount=="function"&&o.UNSAFE_componentWillMount()),typeof o.componentDidMount=="function"&&(e.flags|=4194308)):(typeof o.componentDidMount=="function"&&(e.flags|=4194308),e.memoizedProps=n,e.memoizedState=c),o.props=n,o.state=c,o.context=d,n=l):(typeof o.componentDidMount=="function"&&(e.flags|=4194308),n=!1)}else{o=e.stateNode,pI(t,e),l=e.memoizedProps,d=e.type===e.elementType?l:kn(e.type,l),o.props=d,p=e.pendingProps,m=o.context,c=a.contextType,typeof c=="object"&&c!==null?c=pn(c):(c=Ca(a)?Bo:ia.current,c=ml(e,c));var h=a.getDerivedStateFromProps;(u=typeof h=="function"||typeof o.getSnapshotBeforeUpdate=="function")||typeof o.UNSAFE_componentWillReceiveProps!="function"&&typeof o.componentWillReceiveProps!="function"||(l!==p||m!==c)&&k_(e,o,n,c),ar=!1,m=e.memoizedState,o.state=m,ch(e,n,o,i);var g=e.memoizedState;l!==p||m!==g||Ea.current||ar?(typeof h=="function"&&(Jx(e,a,h,n),g=e.memoizedState),(d=ar||w_(e,a,d,n,m,g,c)||!1)?(u||typeof o.UNSAFE_componentWillUpdate!="function"&&typeof o.componentWillUpdate!="function"||(typeof o.componentWillUpdate=="function"&&o.componentWillUpdate(n,g,c),typeof o.UNSAFE_componentWillUpdate=="function"&&o.UNSAFE_componentWillUpdate(n,g,c)),typeof o.componentDidUpdate=="function"&&(e.flags|=4),typeof o.getSnapshotBeforeUpdate=="function"&&(e.flags|=1024)):(typeof o.componentDidUpdate!="function"||l===t.memoizedProps&&m===t.memoizedState||(e.flags|=4),typeof o.getSnapshotBeforeUpdate!="function"||l===t.memoizedProps&&m===t.memoizedState||(e.flags|=1024),e.memoizedProps=n,e.memoizedState=g),o.props=n,o.state=g,o.context=c,n=d):(typeof o.componentDidUpdate!="function"||l===t.memoizedProps&&m===t.memoizedState||(e.flags|=4),typeof o.getSnapshotBeforeUpdate!="function"||l===t.memoizedProps&&m===t.memoizedState||(e.flags|=1024),n=!1)}return Zx(t,e,a,n,r,i)}function Zx(t,e,a,n,i,r){qI(t,e);var o=(e.flags&128)!==0;if(!n&&!o)return i&&m_(e,a,!1),Mi(t,e,r);n=e.stateNode,sz.current=e;var l=o&&typeof a.getDerivedStateFromError!="function"?null:n.render();return e.flags|=1,t!==null&&o?(e.child=fl(e,t.child,null,r),e.child=fl(e,null,l,r)):ua(t,e,l,r),e.memoizedState=n.state,i&&m_(e,a,!0),e.child}function zI(t){var e=t.stateNode;e.pendingContext?p_(t,e.pendingContext,e.pendingContext!==e.context):e.context&&p_(t,e.context,!1),j1(t,e.containerInfo)}function T_(t,e,a,n,i){return hl(),k1(i),e.flags|=256,ua(t,e,a,n),e.child}var ev={dehydrated:null,treeContext:null,retryLane:0};function tv(t){return{baseLanes:t,cachePool:null,transitions:null}}function VI(t,e,a){var n=e.pendingProps,i=Je.current,r=!1,o=(e.flags&128)!==0,l;if((l=o)||(l=t!==null&&t.memoizedState===null?!1:(i&2)!==0),l?(r=!0,e.flags&=-129):(t===null||t.memoizedState!==null)&&(i|=1),Ve(Je,i&1),t===null)return Gx(e),t=e.memoizedState,t!==null&&(t=t.dehydrated,t!==null)?(e.mode&1?t.data==="$!"?e.lanes=8:e.lanes=1073741824:e.lanes=1,null):(o=n.children,t=n.fallback,r?(n=e.mode,r=e.child,o={mode:"hidden",children:o},!(n&1)&&r!==null?(r.childLanes=0,r.pendingProps=o):r=Jf(o,n,0,null),t=Po(t,n,a,null),r.return=e,t.return=e,r.sibling=t,e.child=r,e.child.memoizedState=tv(a),e.memoizedState=ev,t):M1(e,o));if(i=t.memoizedState,i!==null&&(l=i.dehydrated,l!==null))return lz(t,e,o,n,l,i,a);if(r){r=n.fallback,o=e.mode,i=t.child,l=i.sibling;var c={mode:"hidden",children:n.children};return!(o&1)&&e.child!==i?(n=e.child,n.childLanes=0,n.pendingProps=c,e.deletions=null):(n=jr(i,c),n.subtreeFlags=i.subtreeFlags&14680064),l!==null?r=jr(l,r):(r=Po(r,o,a,null),r.flags|=2),r.return=e,n.return=e,n.sibling=r,e.child=n,n=r,r=e.child,o=t.child.memoizedState,o=o===null?tv(a):{baseLanes:o.baseLanes|a,cachePool:null,transitions:o.transitions},r.memoizedState=o,r.childLanes=t.childLanes&~a,e.memoizedState=ev,n}
vendor: 8,788 bytes, line 40
40return r=t.child,t=r.sibling,n=jr(r,{mode:"visible",children:n.children}),!(e.mode&1)&&(n.lanes=a),n.return=e,n.sibling=null,t!==null&&(a=e.deletions,a===null?(e.deletions=[t],e.flags|=16):a.push(t)),e.child=n,e.memoizedState=null,n}function M1(t,e){return e=Jf({mode:"visible",children:e},t.mode,0,null),e.return=t,t.child=e}function jp(t,e,a,n){return n!==null&&k1(n),fl(e,t.child,null,a),t=M1(e,e.pendingProps.children),t.flags|=2,e.memoizedState=null,t}function lz(t,e,a,n,i,r,o){if(a)return e.flags&256?(e.flags&=-257,n=Uy(Error(U(422))),jp(t,e,o,n)):e.memoizedState!==null?(e.child=t.child,e.flags|=128,null):(r=n.fallback,i=e.mode,n=Jf({mode:"visible",children:n.children},i,0,null),r=Po(r,i,o,null),r.flags|=2,n.return=e,r.return=e,n.sibling=r,e.child=n,e.mode&1&&fl(e,t.child,null,o),e.child.memoizedState=tv(o),e.memoizedState=ev,r);if(!(e.mode&1))return jp(t,e,o,null);if(i.data==="$!"){if(n=i.nextSibling&&i.nextSibling.dataset,n)var l=n.dgst;return n=l,r=Error(U(419)),n=Uy(r,n,void 0),jp(t,e,o,n)}if(l=(o&t.childLanes)!==0,Aa||l){if(n=It,n!==null){switch(o&-o){case 4:i=2;break;case 16:i=8;break;case 64:case 128:case 256:case 512:case 1024:case 2048:case 4096:case 8192:case 16384:case 32768:case 65536:case 131072:case 262144:case 524288:case 1048576:case 2097152:case 4194304:case 8388608:case 16777216:case 33554432:case 67108864:i=32;break;case 536870912:i=268435456;break;default:i=0}i=i&(n.suspendedLanes|o)?0:i,i!==0&&i!==r.retryLane&&(r.retryLane=i,Oi(t,i),Nn(n,t,i,-1))}return F1(),n=Uy(Error(U(421))),jp(t,e,o,n)}return i.data==="$?"?(e.flags|=128,e.child=t.child,e=wz.bind(null,t),i._reactRetry=e,null):(t=r.treeContext,za=_r(i.nextSibling),Fa=e,Ge=!0,_n=null,t!==null&&(nn[rn++]=vi,nn[rn++]=bi,nn[rn++]=Uo,vi=t.id,bi=t.overflow,Uo=e),e=M1(e,n.children),e.flags|=4096,e)}function N_(t,e,a){t.lanes|=e;var n=t.alternate;n!==null&&(n.lanes|=e),Kx(t.return,e,a)}function $y(t,e,a,n,i){var r=t.memoizedState;r===null?t.memoizedState={isBackwards:e,rendering:null,renderingStartTime:0,last:n,tail:a,tailMode:i}:(r.isBackwards=e,r.rendering=null,r.renderingStartTime=0,r.last=n,r.tail=a,r.tailMode=i)}function HI(t,e,a){var n=e.pendingProps,i=n.revealOrder,r=n.tail;if(ua(t,e,n.children,a),n=Je.current,n&2)n=n&1|2,e.flags|=128;else{if(t!==null&&t.flags&128)e:for(t=e.child;t!==null;){if(t.tag===13)t.memoizedState!==null&&N_(t,a,e);else if(t.tag===19)N_(t,a,e);else if(t.child!==null){t.child.return=t,t=t.child;continue}if(t===e)break e;for(;t.sibling===null;){if(t.return===null||t.return===e)break e;t=t.return}t.sibling.return=t.return,t=t.sibling}n&=1}if(Ve(Je,n),!(e.mode&1))e.memoizedState=null;else switch(i){case"forwards":for(a=e.child,i=null;a!==null;)t=a.alternate,t!==null&&dh(t)===null&&(i=a),a=a.sibling;a=i,a===null?(i=e.child,e.child=null):(i=a.sibling,a.sibling=null),$y(e,!1,i,a,r);break;case"backwards":for(a=null,i=e.child,e.child=null;i!==null;){if(t=i.alternate,t!==null&&dh(t)===null){e.child=i;break}t=i.sibling,i.sibling=a,a=i,i=t}$y(e,!0,a,null,r);break;case"together":$y(e,!1,null,null,void 0);break;default:e.memoizedState=null}return e.child}function xm(t,e){!(e.mode&1)&&t!==null&&(t.alternate=null,e.alternate=null,e.flags|=2)}function Mi(t,e,a){if(t!==null&&(e.dependencies=t.dependencies),Wo|=e.lanes,!(a&e.childLanes))return null;if(t!==null&&e.child!==t.child)throw Error(U(153));if(e.child!==null){for(t=e.child,a=jr(t,t.pendingProps),e.child=a,a.return=e;t.sibling!==null;)t=t.sibling,a=a.sibling=jr(t,t.pendingProps),a.return=e;a.sibling=null}return e.child}function cz(t,e,a){switch(e.tag){case 3:zI(e),hl();break;case 5:mI(e);break;case 1:Ca(e.type)&&ih(e);break;case 4:j1(e,e.stateNode.containerInfo);break;case 10:var n=e.type._context,i=e.memoizedProps.value;Ve(sh,n._currentValue),n._currentValue=i;break;case 13:if(n=e.memoizedState,n!==null)return n.dehydrated!==null?(Ve(Je,Je.current&1),e.flags|=128,null):a&e.child.childLanes?VI(t,e,a):(Ve(Je,Je.current&1),t=Mi(t,e,a),t!==null?t.sibling:null);Ve(Je,Je.current&1);break;case 19:if(n=(a&e.childLanes)!==0,t.flags&128){if(n)return HI(t,e,a);e.flags|=128}if(i=e.memoizedState,i!==null&&(i.rendering=null,i.tail=null,i.lastEffect=null),Ve(Je,Je.current),n)break;return null;case 22:case 23:return e.lanes=0,DI(t,e,a)}return Mi(t,e,a)}var FI,av,BI,UI;FI=function(t,e){for(var a=e.child;a!==null;){if(a.tag===5||a.tag===6)t.appendChild(a.stateNode);else if(a.tag!==4&&a.child!==null){a.child.return=a,a=a.child;continue}if(a===e)break;for(;a.sibling===null;){if(a.return===null||a.return===e)return;a=a.return}a.sibling.return=a.return,a=a.sibling}};av=function(){};BI=function(t,e,a,n){var i=t.memoizedProps;if(i!==n){t=e.stateNode,bo(Yn.current);var r=null;switch(a){case"input":i=_x(t,i),n=_x(t,n),r=[];break;case"select":i=Ze({},i,{value:void 0}),n=Ze({},n,{value:void 0}),r=[];break;case"textarea":i=Cx(t,i),n=Cx(t,n),r=[];break;default:typeof i.onClick!="function"&&typeof n.onClick=="function"&&(t.onclick=ah)}Tx(a,n);var o;a=null;for(d in i)if(!n.hasOwnProperty(d)&&i.hasOwnProperty(d)&&i[d]!=null)if(d==="style"){var l=i[d];for(o in l)l.hasOwnProperty(o)&&(a||(a={}),a[o]="")}else d!=="dangerouslySetInnerHTML"&&d!=="children"&&d!=="suppressContentEditableWarning"&&d!=="suppressHydrationWarning"&&d!=="autoFocus"&&(Nd.hasOwnProperty(d)?r||(r=[]):(r=r||[]).push(d,null));for(d in n){var c=n[d];if(l=i!=null?i[d]:void 0,n.hasOwnProperty(d)&&c!==l&&(c!=null||l!=null))if(d==="style")if(l){for(o in l)!l.hasOwnProperty(o)||c&&c.hasOwnProperty(o)||(a||(a={}),a[o]="");for(o in c)c.hasOwnProperty(o)&&l[o]!==c[o]&&(a||(a={}),a[o]=c[o])}else a||(r||(r=[]),r.push(d,a)),a=c;else d==="dangerouslySetInnerHTML"?(c=c?c.__html:void 0,l=l?l.__html:void 0,c!=null&&l!==c&&(r=r||[]).push(d,c)):d==="children"?typeof c!="string"&&typeof c!="number"||(r=r||[]).push(d,""+c):d!=="suppressContentEditableWarning"&&d!=="suppressHydrationWarning"&&(Nd.hasOwnProperty(d)?(c!=null&&d==="onScroll"&&Fe("scroll",t),r||l===c||(r=[])):(r=r||[]).push(d,c))}a&&(r=r||[]).push("style",a);var d=r;(e.updateQueue=d)&&(e.flags|=4)}};UI=function(t,e,a,n){a!==n&&(e.flags|=4)};function bc(t,e){if(!Ge)switch(t.tailMode){case"hidden":e=t.tail;for(var a=null;e!==null;)e.alternate!==null&&(a=e),e=e.sibling;a===null?t.tail=null:a.sibling=null;break;case"collapsed":a=t.tail;for(var n=null;a!==null;)a.alternate!==null&&(n=a),a=a.sibling;n===null?e||t.tail===null?t.tail=null:t.tail.sibling=null:n.sibling=null}}function Xt(t){var e=t.alternate!==null&&t.alternate.child===t.child,a=0,n=0;if(e)for(var i=t.child;i!==null;)a|=i.lanes|i.childLanes,n|=i.subtreeFlags&14680064,n|=i.flags&14680064,i.return=t,i=i.sibling;else for(i=t.child;i!==null;)a|=i.lanes|i.childLanes,n|=i.subtreeFlags,n|=i.flags,i.return=t,i=i.sibling;return t.subtreeFlags|=n,t.childLanes=a,e}function dz(t,e,a){var n=e.pendingProps;switch(w1(e),e.tag){case 2:case 16:case 15:case 0:case 11:case 7:case 8:case 12:case 9:case 14:return Xt(e),null;case 1:return Ca(e.type)&&nh(),Xt(e),null;case 3:return n=e.stateNode,gl(),$e(Ea),$e(ia),N1(),n.pendingContext&&(n.context=n.pendingContext,n.pendingContext=null),(t===null||t.child===null)&&(Ep(e)?e.flags|=4:t===null||t.memoizedState.isDehydrated&&!(e.flags&256)||(e.flags|=1024,_n!==null&&(dv(_n),_n=null))),av(t,e),Xt(e),null;case 5:T1(e);var i=bo(Fd.current);if(a=e.type,t!==null&&e.stateNode!=null)BI(t,e,a,n,i),t.ref!==e.ref&&(e.flags|=512,e.flags|=2097152);else{if(!n){if(e.stateNode===null)throw Error(U(166));return Xt(e),null}if(t=bo(Yn.current),Ep(e)){n=e.stateNode,a=e.type;var r=e.memoizedProps;switch(n[Wn]=e,n[Vd]=r,t=(e.mode&1)!==0,a){case"dialog":Fe("cancel",n),Fe("close",n);break;case"iframe":case"object":case"embed":Fe("load",n);break;case"video":case"audio":for(i=0;i<Dc.length;i++)Fe(Dc[i],n);break;case"source":Fe("error",n);break;case"img":case"image":case"link":Fe("error",n),Fe("load",n);break;case"details":Fe("toggle",n);break;case"input":z2(n,r),Fe("invalid",n);break;case"select":n._wrapperState={wasMultiple:!!r.multiple},Fe("invalid",n);break;case"textarea":H2(n,r),Fe("invalid",n)}Tx(a,r),i=null;for(var o in r)if(r.hasOwnProperty(o)){var l=r[o];o==="children"?typeof l=="string"?n.textContent!==l&&(r.suppressHydrationWarning!==!0&&Ap(n.textContent,l,t),i=["children",l]):typeof l=="number"&&n.textContent!==""+l&&(r.suppressHydrationWarning!==!0&&Ap(n.textContent,l,t),i=["children",""+l]):Nd.hasOwnProperty(o)&&l!=null&&o==="onScroll"&&Fe("scroll",n)}switch(a){case"input":yp(n),V2(n,r,!0);break;case"textarea":yp(n),F2(n);break;case"select":case"option":break;default:typeof r.onClick=="function"&&(n.onclick=ah)}n=i,e.updateQueue=n,n!==null&&(e.flags|=4)}else{o=i.nodeType===9?i:i.ownerDocument,t==="http://www.w3.org/1999/xhtml"&&(t=xN(a)),t==="http://www.w3.org/1999/xhtml"?a==="script"?(t=o.createElement("div"),t.innerHTML="<script><\/script>
40",t=t.removeChild(t.firstChild)):typeof n.is=="string"?t=o.createElement(a,{is:n.is}):(t=o.createElement(a),a==="select"&&(o=t,n.multiple?o.multiple=!0:n.size&&(o.size=n.size))):t=o.createElementNS(t,a),t[Wn]=e,t[Vd]=n,FI(t,e,!1,!1),e.stateNode=t;e:{switch(o=Nx(a,n),a){case"dialog":Fe("cancel",t),Fe("close",t),i=n;break;case"iframe":case"object":case"embed":Fe("load",t),i=n;break;case"video":case"audio":for(i=0;i<Dc.length;i++)Fe(Dc[i],t);i=n;break;case"source":Fe("error",t),i=n;break;case"img":case"image":case"link":Fe("error",t),Fe("load",t),i=n;break;case"details":Fe("toggle",t),i=n;break;case"input":z2(t,n),i=_x(t,n),Fe("invalid",t);break;case"option":i=n;break;case"select":t._wrapperState={wasMultiple:!!n.multiple},i=Ze({},n,{value:void 0}),Fe("invalid",t);break;case"textarea":H2(t,n),i=Cx(t,n),Fe("invalid",t);break;default:i=n}Tx(a,i),l=i;for(r in l)if(l.hasOwnProperty(r)){var c=l[r];r==="style"?wN(t,c):r==="dangerouslySetInnerHTML"?(c=c?c.__html:void 0,c!=null&&vN(t,c)):r==="children"?typeof c=="string"?(a!=="textarea"||c!=="")&&Id(t,c):typeof c=="number"&&Id(t,""+c):r!=="suppressContentEditableWarning"&&r!=="suppressHydrationWarning"&&r!=="autoFocus"&&(Nd.hasOwnProperty(r)?c!=null&&r==="onScroll"&&Fe("scroll",t):c!=null&&o1(t,r,c,o))}switch(a){case"input":yp(t),V2(t,n,!1);break;case"textarea":yp(t),F2(t);break;case"option":n.value!=null&&t.setAttribute("value",""+Dr(n.value));break;case"select":t.multiple=!!n.multiple,r=n.value,r!=null?Xs(t,!!n.multiple,r,!1):n.defaultValue!=null&&Xs(t,!!n.multiple,n.defaultValue,!0);break;default:typeof i.onClick=="function"&&(t.onclick=ah)}switch(a){case"button":case"input":case"select":case"textarea":n=!!n.autoFocus;break e;case"img":n=!0;break e;default:n=!1}}n&&(e.flags|=4)}e.ref!==null&&(e.flags|=512,e.flags|=2097152)}return Xt(e),null;case 6:if(t&&e.stateNode!=null)UI(t,e,t.memoizedProps,n);else{if(typeof n!="string"&&e.stateNode===null)throw Error(U(166));if(a=bo(Fd.current),bo(Yn.current),Ep(e)){if(n=e.stateNode,a=e.memoizedProps,n[Wn]=e,(r=n.nodeValue!==a)&&(t=Fa,t!==null))switch(t.tag){case 3:Ap(n.nodeValue,a,(t.mode&1)!==0);break;case 5:t.memoizedProps.suppressHydrationWarning!==!0&&Ap(n.nodeValue,a,(t.mode&1)!==0)}r&&(e.flags|=4)}else n=(a.nodeType===9?a:a.ownerDocument).createTextNode(n),n[Wn]=e,e.stateNode=n}return Xt(e),null;case 13:if($e(Je),n=e.memoizedState,t===null||t.memoizedState!==null&&t.memoizedState.dehydrated!==null){if(Ge&&za!==null&&e.mode&1&&!(e.flags&128))lI(),hl(),e.flags|=98560,r=!1;else if(r=Ep(e),n!==null&&n.dehydrated!==null){if(t===null){if(!r)throw Error(U(318));if(r=e.memoizedState,r=r!==null?r.dehydrated:null,!r)throw Error(U(317));r[Wn]=e}else hl(),!(e.flags&128)&&(e.memoizedState=null),e.flags|=4;Xt(e),r=!1}else _n!==null&&(dv(_n),_n=null),r=!0;if(!r)return e.flags&65536?e:null}return e.flags&128?(e.lanes=a,e):(n=n!==null,n!==(t!==null&&t.memoizedState!==null)&&n&&(e.child.flags|=8192,e.mode&1&&(t===null||Je.current&1?kt===0&&(kt=3):F1())),e.updateQueue!==null&&(e.flags|=4),Xt(e),null);case 4:return gl(),av(t,e),t===null&&qd(e.stateNode.containerInfo),Xt(e),null;case 10:return A1(e.type._context),Xt(e),null;case 17:return Ca(e.type)&&nh(),Xt(e),null;case 19:if($e(Je),r=e.memoizedState,r===null)return Xt(e),null;if(n=(e.flags&128)!==0,o=r.rendering,o===null)if(n)bc(r,!1);else{if(kt!==0||t!==null&&t.flags&128)for(t=e.child;t!==null;){if(o=dh(t),o!==null){for(e.flags|=128,bc(r,!1),n=o.updateQueue,n!==null&&(e.updateQueue=n,e.flags|=4),e.subtreeFlags=0,n=a,a=e.child;a!==null;)r=a,t=n,r.flags&=14680066,o=r.alternate,o===null?(r.childLanes=0,r.lanes=t,r.child=null,r.subtreeFlags=0,r.memoizedProps=null,r.memoizedState=null,r.updateQueue=null,r.dependencies=null,r.stateNode=null):(r.childLanes=o.childLanes,r.lanes=o.lanes,r.child=o.child,r.subtreeFlags=0,r.deletions=null,r.memoizedProps=o.memoizedProps,r.memoizedState=o.memoizedState,r.updateQueue=o.updateQueue,r.type=o.type,t=o.dependencies,r.dependencies=t===null?null:{lanes:t.lanes,firstContext:t.firstContext}),a=a.sibling;return Ve(Je,Je.current&1|2),e.child}t=t.sibling}r.tail!==null&&pt()>xl&&(e.flags|=128,n=!0,bc(r,!1),e.lanes=4194304)}else{if(!n)if(t=dh(o),t!==null){if(e.flags|=128,n=!0,a=t.updateQueue,a!==null&&(e.updateQueue=a,e.flags|=4),bc(r,!0),r.tail===null&&r.tailMode==="hidden"&&!o.alternate&&!Ge)return Xt(e),null}else 2*pt()-r.renderingStartTime>xl&&a!==1073741824&&(e.flags|=128,n=!0,bc(r,!1),e.lanes=4194304);r.isBackwards?(o.sibling=e.child,e.child=o):(a=r.last,a!==null?a.sibling=o:e.child=o,r.last=o
vendor: 24,891 bytes, line 40
40)}return r.tail!==null?(e=r.tail,r.rendering=e,r.tail=e.sibling,r.renderingStartTime=pt(),e.sibling=null,a=Je.current,Ve(Je,n?a&1|2:a&1),e):(Xt(e),null);case 22:case 23:return H1(),n=e.memoizedState!==null,t!==null&&t.memoizedState!==null!==n&&(e.flags|=8192),n&&e.mode&1?Da&1073741824&&(Xt(e),e.subtreeFlags&6&&(e.flags|=8192)):Xt(e),null;case 24:return null;case 25:return null}throw Error(U(156,e.tag))}function uz(t,e){switch(w1(e),e.tag){case 1:return Ca(e.type)&&nh(),t=e.flags,t&65536?(e.flags=t&-65537|128,e):null;case 3:return gl(),$e(Ea),$e(ia),N1(),t=e.flags,t&65536&&!(t&128)?(e.flags=t&-65537|128,e):null;case 5:return T1(e),null;case 13:if($e(Je),t=e.memoizedState,t!==null&&t.dehydrated!==null){if(e.alternate===null)throw Error(U(340));hl()}return t=e.flags,t&65536?(e.flags=t&-65537|128,e):null;case 19:return $e(Je),null;case 4:return gl(),null;case 10:return A1(e.type._context),null;case 22:case 23:return H1(),null;case 24:return null;default:return null}}var Tp=!1,ta=!1,pz=typeof WeakSet=="function"?WeakSet:Set,Q=null;function Bs(t,e){var a=t.ref;if(a!==null)if(typeof a=="function")try{a(null)}catch(n){ot(t,e,n)}else a.current=null}function nv(t,e,a){try{a()}catch(n){ot(t,e,n)}}var I_=!1;function mz(t,e){if(Vx=Zm,t=JN(),v1(t)){if("selectionStart"in t)var a={start:t.selectionStart,end:t.selectionEnd};else e:{a=(a=t.ownerDocument)&&a.defaultView||window;var n=a.getSelection&&a.getSelection();if(n&&n.rangeCount!==0){a=n.anchorNode;var i=n.anchorOffset,r=n.focusNode;n=n.focusOffset;try{a.nodeType,r.nodeType}catch{a=null;break e}var o=0,l=-1,c=-1,d=0,u=0,p=t,m=null;t:for(;;){for(var h;p!==a||i!==0&&p.nodeType!==3||(l=o+i),p!==r||n!==0&&p.nodeType!==3||(c=o+n),p.nodeType===3&&(o+=p.nodeValue.length),(h=p.firstChild)!==null;)m=p,p=h;for(;;){if(p===t)break t;if(m===a&&++d===i&&(l=o),m===r&&++u===n&&(c=o),(h=p.nextSibling)!==null)break;p=m,m=p.parentNode}p=h}a=l===-1||c===-1?null:{start:l,end:c}}else a=null}a=a||{start:0,end:0}}else a=null;for(Hx={focusedElem:t,selectionRange:a},Zm=!1,Q=e;Q!==null;)if(e=Q,t=e.child,(e.subtreeFlags&1028)!==0&&t!==null)t.return=e,Q=t;else for(;Q!==null;){e=Q;try{var g=e.alternate;if(e.flags&1024)switch(e.tag){case 0:case 11:case 15:break;case 1:if(g!==null){var y=g.memoizedProps,x=g.memoizedState,v=e.stateNode,w=v.getSnapshotBeforeUpdate(e.elementType===e.type?y:kn(e.type,y),x);v.__reactInternalSnapshotBeforeUpdate=w}break;case 3:var S=e.stateNode.containerInfo;S.nodeType===1?S.textContent="":S.nodeType===9&&S.documentElement&&S.removeChild(S.documentElement);break;case 5:case 6:case 4:case 17:break;default:throw Error(U(163))}}catch(T){ot(e,e.return,T)}if(t=e.sibling,t!==null){t.return=e.return,Q=t;break}Q=e.return}return g=I_,I_=!1,g}function td(t,e,a){var n=e.updateQueue;if(n=n!==null?n.lastEffect:null,n!==null){var i=n=n.next;do{if((i.tag&t)===t){var r=i.destroy;i.destroy=void 0,r!==void 0&&nv(e,a,r)}i=i.next}while(i!==n)}}function Gf(t,e){if(e=e.updateQueue,e=e!==null?e.lastEffect:null,e!==null){var a=e=e.next;do{if((a.tag&t)===t){var n=a.create;a.destroy=n()}a=a.next}while(a!==e)}}function iv(t){var e=t.ref;if(e!==null){var a=t.stateNode;switch(t.tag){case 5:t=a;break;default:t=a}typeof e=="function"?e(t):e.current=t}}function $I(t){var e=t.alternate;e!==null&&(t.alternate=null,$I(e)),t.child=null,t.deletions=null,t.sibling=null,t.tag===5&&(e=t.stateNode,e!==null&&(delete e[Wn],delete e[Vd],delete e[Ux],delete e[J6],delete e[Q6])),t.stateNode=null,t.return=null,t.dependencies=null,t.memoizedProps=null,t.memoizedState=null,t.pendingProps=null,t.stateNode=null,t.updateQueue=null}function WI(t){return t.tag===5||t.tag===3||t.tag===4}function P_(t){e:for(;;){for(;t.sibling===null;){if(t.return===null||WI(t.return))return null;t=t.return}for(t.sibling.return=t.return,t=t.sibling;t.tag!==5&&t.tag!==6&&t.tag!==18;){if(t.flags&2||t.child===null||t.tag===4)continue e;t.child.return=t,t=t.child}if(!(t.flags&2))return t.stateNode}}function rv(t,e,a){var n=t.tag;if(n===5||n===6)t=t.stateNode,e?a.nodeType===8?a.parentNode.insertBefore(t,e):a.insertBefore(t,e):(a.nodeType===8?(e=a.parentNode,e.insertBefore(t,a)):(e=a,e.appendChild(t)),a=a._reactRootContainer,a!=null||e.onclick!==null||(e.onclick=ah));else if(n!==4&&(t=t.child,t!==null))for(rv(t,e,a),t=t.sibling;t!==null;)rv(t,e,a),t=t.sibling}function ov(t,e,a){var n=t.tag;if(n===5||n===6)t=t.stateNode,e?a.insertBefore(t,e):a.appendChild(t);else if(n!==4&&(t=t.child,t!==null))for(ov(t,e,a),t=t.sibling;t!==null;)ov(t,e,a),t=t.sibling}var Mt=null,Sn=!1;function Ji(t,e,a){for(a=a.child;a!==null;)GI(t,e,a),a=a.sibling}function GI(t,e,a){if(Xn&&typeof Xn.onCommitFiberUnmount=="function")try{Xn.onCommitFiberUnmount(zf,a)}catch{}switch(a.tag){case 5:ta||Bs(a,e);case 6:var n=Mt,i=Sn;Mt=null,Ji(t,e,a),Mt=n,Sn=i,Mt!==null&&(Sn?(t=Mt,a=a.stateNode,t.nodeType===8?t.parentNode.removeChild(a):t.removeChild(a)):Mt.removeChild(a.stateNode));break;case 18:Mt!==null&&(Sn?(t=Mt,a=a.stateNode,t.nodeType===8?qy(t.parentNode,a):t.nodeType===1&&qy(t,a),Od(t)):qy(Mt,a.stateNode));break;case 4:n=Mt,i=Sn,Mt=a.stateNode.containerInfo,Sn=!0,Ji(t,e,a),Mt=n,Sn=i;break;case 0:case 11:case 14:case 15:if(!ta&&(n=a.updateQueue,n!==null&&(n=n.lastEffect,n!==null))){i=n=n.next;do{var r=i,o=r.destroy;r=r.tag,o!==void 0&&(r&2||r&4)&&nv(a,e,o),i=i.next}while(i!==n)}Ji(t,e,a);break;case 1:if(!ta&&(Bs(a,e),n=a.stateNode,typeof n.componentWillUnmount=="function"))try{n.props=a.memoizedProps,n.state=a.memoizedState,n.componentWillUnmount()}catch(l){ot(a,e,l)}Ji(t,e,a);break;case 21:Ji(t,e,a);break;case 22:a.mode&1?(ta=(n=ta)||a.memoizedState!==null,Ji(t,e,a),ta=n):Ji(t,e,a);break;default:Ji(t,e,a)}}function R_(t){var e=t.updateQueue;if(e!==null){t.updateQueue=null;var a=t.stateNode;a===null&&(a=t.stateNode=new pz),e.forEach(function(n){var i=kz.bind(null,t,n);a.has(n)||(a.add(n),n.then(i,i))})}}function xn(t,e){var a=e.deletions;if(a!==null)for(var n=0;n<a.length;n++){var i=a[n];try{var r=t,o=e,l=o;e:for(;l!==null;){switch(l.tag){case 5:Mt=l.stateNode,Sn=!1;break e;case 3:Mt=l.stateNode.containerInfo,Sn=!0;break e;case 4:Mt=l.stateNode.containerInfo,Sn=!0;break e}l=l.return}if(Mt===null)throw Error(U(160));GI(r,o,i),Mt=null,Sn=!1;var c=i.alternate;c!==null&&(c.return=null),i.return=null}catch(d){ot(i,e,d)}}if(e.subtreeFlags&12854)for(e=e.child;e!==null;)KI(e,t),e=e.sibling}function KI(t,e){var a=t.alternate,n=t.flags;switch(t.tag){case 0:case 11:case 14:case 15:if(xn(e,t),Hn(t),n&4){try{td(3,t,t.return),Gf(3,t)}catch(y){ot(t,t.return,y)}try{td(5,t,t.return)}catch(y){ot(t,t.return,y)}}break;case 1:xn(e,t),Hn(t),n&512&&a!==null&&Bs(a,a.return);break;case 5:if(xn(e,t),Hn(t),n&512&&a!==null&&Bs(a,a.return),t.flags&32){var i=t.stateNode;try{Id(i,"")}catch(y){ot(t,t.return,y)}}if(n&4&&(i=t.stateNode,i!=null)){var r=t.memoizedProps,o=a!==null?a.memoizedProps:r,l=t.type,c=t.updateQueue;if(t.updateQueue=null,c!==null)try{l==="input"&&r.type==="radio"&&r.name!=null&&gN(i,r),Nx(l,o);var d=Nx(l,r);for(o=0;o<c.length;o+=2){var u=c[o],p=c[o+1];u==="style"?wN(i,p):u==="dangerouslySetInnerHTML"?vN(i,p):u==="children"?Id(i,p):o1(i,u,p,d)}switch(l){case"input":Ax(i,r);break;case"textarea":yN(i,r);break;case"select":var m=i._wrapperState.wasMultiple;i._wrapperState.wasMultiple=!!r.multiple;var h=r.value;h!=null?Xs(i,!!r.multiple,h,!1):m!==!!r.multiple&&(r.defaultValue!=null?Xs(i,!!r.multiple,r.defaultValue,!0):Xs(i,!!r.multiple,r.multiple?[]:"",!1))}i[Vd]=r}catch(y){ot(t,t.return,y)}}break;case 6:if(xn(e,t),Hn(t),n&4){if(t.stateNode===null)throw Error(U(162));i=t.stateNode,r=t.memoizedProps;try{i.nodeValue=r}catch(y){ot(t,t.return,y)}}break;case 3:if(xn(e,t),Hn(t),n&4&&a!==null&&a.memoizedState.isDehydrated)try{Od(e.containerInfo)}catch(y){ot(t,t.return,y)}break;case 4:xn(e,t),Hn(t);break;case 13:xn(e,t),Hn(t),i=t.child,i.flags&8192&&(r=i.memoizedState!==null,i.stateNode.isHidden=r,!r||i.alternate!==null&&i.alternate.memoizedState!==null||(z1=pt())),n&4&&R_(t);break;case 22:if(u=a!==null&&a.memoizedState!==null,t.mode&1?(ta=(d=ta)||u,xn(e,t),ta=d):xn(e,t),Hn(t),n&8192){if(d=t.memoizedState!==null,(t.stateNode.isHidden=d)&&!u&&t.mode&1)for(Q=t,u=t.child;u!==null;){for(p=Q=u;Q!==null;){switch(m=Q,h=m.child,m.tag){case 0:case 11:case 14:case 15:td(4,m,m.return);break;case 1:Bs(m,m.return);var g=m.stateNode;if(typeof g.componentWillUnmount=="function"){n=m,a=m.return;try{e=n,g.props=e.memoizedProps,g.state=e.memoizedState,g.componentWillUnmount()}catch(y){ot(n,a,y)}}break;case 5:Bs(m,m.return);break;case 22:if(m.memoizedState!==null){O_(p);continue}}h!==null?(h.return=m,Q=h):O_(p)}u=u.sibling}e:for(u=null,p=t;;){if(p.tag===5){if(u===null){u=p;try{i=p.stateNode,d?(r=i.style,typeof r.setProperty=="function"?r.setProperty("display","none","important"):r.display="none"):(l=p.stateNode,c=p.memoizedProps.style,o=c!=null&&c.hasOwnProperty("display")?c.display:null,l.style.display=bN("display",o))}catch(y){ot(t,t.return,y)}}}else if(p.tag===6){if(u===null)try{p.stateNode.nodeValue=d?"":p.memoizedProps}catch(y){ot(t,t.return,y)}}else if((p.tag!==22&&p.tag!==23||p.memoizedState===null||p===t)&&p.child!==null){p.child.return=p,p=p.child;continue}if(p===t)break e;for(;p.sibling===null;){if(p.return===null||p.return===t)break e;u===p&&(u=null),p=p.return}u===p&&(u=null),p.sibling.return=p.return,p=p.sibling}}break;case 19:xn(e,t),Hn(t),n&4&&R_(t);break;case 21:break;default:xn(e,t),Hn(t)}}function Hn(t){var e=t.flags;if(e&2){try{e:{for(var a=t.return;a!==null;){if(WI(a)){var n=a;break e}a=a.return}throw Error(U(160))}switch(n.tag){case 5:var i=n.stateNode;n.flags&32&&(Id(i,""),n.flags&=-33);var r=P_(t);ov(t,r,i);break;case 3:case 4:var o=n.stateNode.containerInfo,l=P_(t);rv(t,l,o);break;default:throw Error(U(161))}}catch(c){ot(t,t.return,c)}t.flags&=-3}e&4096&&(t.flags&=-4097)}function hz(t,e,a){Q=t,JI(t)}function JI(t,e,a){for(var n=(t.mode&1)!==0;Q!==null;){var i=Q,r=i.child;if(i.tag===22&&n){var o=i.memoizedState!==null||Tp;if(!o){var l=i.alternate,c=l!==null&&l.memoizedState!==null||ta;l=Tp;var d=ta;if(Tp=o,(ta=c)&&!d)for(Q=i;Q!==null;)o=Q,c=o.child,o.tag===22&&o.memoizedState!==null?M_(i):c!==null?(c.return=o,Q=c):M_(i);for(;r!==null;)Q=r,JI(r),r=r.sibling;Q=i,Tp=l,ta=d}L_(t)}else i.subtreeFlags&8772&&r!==null?(r.return=i,Q=r):L_(t)}}function L_(t){for(;Q!==null;){var e=Q;if(e.flags&8772){var a=e.alternate;try{if(e.flags&8772)switch(e.tag){case 0:case 11:case 15:ta||Gf(5,e);break;case 1:var n=e.stateNode;if(e.flags&4&&!ta)if(a===null)n.componentDidMount();else{var i=e.elementType===e.type?a.memoizedProps:kn(e.type,a.memoizedProps);n.componentDidUpdate(i,a.memoizedState,n.__reactInternalSnapshotBeforeUpdate)}var r=e.updateQueue;r!==null&&x_(e,r,n);break;case 3:var o=e.updateQueue;if(o!==null){if(a=null,e.child!==null)switch(e.child.tag){case 5:a=e.child.stateNode;break;case 1:a=e.child.stateNode}x_(e,o,a)}break;case 5:var l=e.stateNode;if(a===null&&e.flags&4){a=l;var c=e.memoizedProps;switch(e.type){case"button":case"input":case"select":case"textarea":c.autoFocus&&a.focus();break;case"img":c.src&&(a.src=c.src)}}break;case 6:break;case 4:break;case 12:break;case 13:if(e.memoizedState===null){var d=e.alternate;if(d!==null){var u=d.memoizedState;if(u!==null){var p=u.dehydrated;p!==null&&Od(p)}}}break;case 19:case 17:case 21:case 22:case 23:case 25:break;default:throw Error(U(163))}ta||e.flags&512&&iv(e)}catch(m){ot(e,e.return,m)}}if(e===t){Q=null;break}if(a=e.sibling,a!==null){a.return=e.return,Q=a;break}Q=e.return}}function O_(t){for(;Q!==null;){var e=Q;if(e===t){Q=null;break}var a=e.sibling;if(a!==null){a.return=e.return,Q=a;break}Q=e.return}}function M_(t){for(;Q!==null;){var e=Q;try{switch(e.tag){case 0:case 11:case 15:var a=e.return;try{Gf(4,e)}catch(c){ot(e,a,c)}break;case 1:var n=e.stateNode;if(typeof n.componentDidMount=="function"){var i=e.return;try{n.componentDidMount()}catch(c){ot(e,i,c)}}var r=e.return;try{iv(e)}catch(c){ot(e,r,c)}break;case 5:var o=e.return;try{iv(e)}catch(c){ot(e,o,c)}}}catch(c){ot(e,e.return,c)}if(e===t){Q=null;break}var l=e.sibling;if(l!==null){l.return=e.return,Q=l;break}Q=e.return}}var fz=Math.ceil,mh=Ui.ReactCurrentDispatcher,D1=Ui.ReactCurrentOwner,cn=Ui.ReactCurrentBatchConfig,Ee=0,It=null,ft=null,Ft=0,Da=0,Us=Gr(0),kt=0,Wd=null,Wo=0,Kf=0,q1=0,ad=null,ka=null,z1=0,xl=1/0,fi=null,hh=!1,sv=null,Er=null,Np=!1,fr=null,fh=0,nd=0,lv=null,vm=-1,bm=0;function fa(){return Ee&6?pt():vm!==-1?vm:vm=pt()}function Cr(t){return t.mode&1?Ee&2&&Ft!==0?Ft&-Ft:Y6.transition!==null?(bm===0&&(bm=RN()),bm):(t=Le,t!==0||(t=window.event,t=t===void 0?16:VN(t.type)),t):1}function Nn(t,e,a,n){if(50<nd)throw nd=0,lv=null,Error(U(185));Su(t,a,n),(!(Ee&2)||t!==It)&&(t===It&&(!(Ee&2)&&(Kf|=a),kt===4&&sr(t,Ft)),ja(t,n),a===1&&Ee===0&&!(e.mode&1)&&(xl=pt()+500,Uf&&Kr()))}function ja(t,e){var a=t.callbackNode;Yq(t,e);var n=Ym(t,t===It?Ft:0);if(n===0)a!==null&&$2(a),t.callbackNode=null,t.callbackPriority=0;else if(e=n&-n,t.callbackPriority!==e){if(a!=null&&$2(a),e===1)t.tag===0?X6(D_.bind(null,t)):rI(D_.bind(null,t)),G6(function(){!(Ee&6)&&Kr()}),a=null;else{switch(LN(n)){case 1:a=u1;break;case 4:a=IN;break;case 16:a=Xm;break;case 536870912:a=PN;break;default:a=Xm}a=nP(a,QI.bind(null,t))}t.callbackPriority=e,t.callbackNode=a}}function QI(t,e){if(vm=-1,bm=0,Ee&6)throw Error(U(327));var a=t.callbackNode;if(al()&&t.callbackNode!==a)return null;var n=Ym(t,t===It?Ft:0);if(n===0)return null;if(n&30||n&t.expiredLanes||e)e=gh(t,n);else{e=n;var i=Ee;Ee|=2;var r=YI();(It!==t||Ft!==e)&&(fi=null,xl=pt()+500,Io(t,e));do try{xz();break}catch(l){XI(t,l)}while(!0);_1(),mh.current=r,Ee=i,ft!==null?e=0:(It=null,Ft=0,e=kt)}if(e!==0){if(e===2&&(i=Ox(t),i!==0&&(n=i,e=cv(t,i))),e===1)throw a=Wd,Io(t,0),sr(t,n),ja(t,pt()),a;if(e===6)sr(t,n);else{if(i=t.current.alternate,!(n&30)&&!gz(i)&&(e=gh(t,n),e===2&&(r=Ox(t),r!==0&&(n=r,e=cv(t,r))),e===1))throw a=Wd,Io(t,0),sr(t,n),ja(t,pt()),a;switch(t.finishedWork=i,t.finishedLanes=n,e){case 0:case 1:throw Error(U(345));case 2:mo(t,ka,fi);break;case 3:if(sr(t,n),(n&130023424)===n&&(e=z1+500-pt(),10<e)){if(Ym(t,0)!==0)break;if(i=t.suspendedLanes,(i&n)!==n){fa(),t.pingedLanes|=t.suspendedLanes&i;break}t.timeoutHandle=Bx(mo.bind(null,t,ka,fi),e);break}mo(t,ka,fi);break;case 4:if(sr(t,n),(n&4194240)===n)break;for(e=t.eventTimes,i=-1;0<n;){var o=31-Tn(n);r=1<<o,o=e[o],o>i&&(i=o),n&=~r}if(n=i,n=pt()-n,n=(120>n?120:480>n?480:1080>n?1080:1920>n?1920:3e3>n?3e3:4320>n?4320:1960*fz(n/1960))-n,10<n){t.timeoutHandle=Bx(mo.bind(null,t,ka,fi),n);break}mo(t,ka,fi);break;case 5:mo(t,ka,fi);break;default:throw Error(U(329))}}}return ja(t,pt()),t.callbackNode===a?QI.bind(null,t):null}function cv(t,e){var a=ad;return t.current.memoizedState.isDehydrated&&(Io(t,e).flags|=256),t=gh(t,e),t!==2&&(e=ka,ka=a,e!==null&&dv(e)),t}function dv(t){ka===null?ka=t:ka.push.apply(ka,t)}function gz(t){for(var e=t;;){if(e.flags&16384){var a=e.updateQueue;if(a!==null&&(a=a.stores,a!==null))for(var n=0;n<a.length;n++){var i=a[n],r=i.getSnapshot;i=i.value;try{if(!Ln(r(),i))return!1}catch{return!1}}}if(a=e.child,e.subtreeFlags&16384&&a!==null)a.return=e,e=a;else{if(e===t)break;for(;e.sibling===null;){if(e.return===null||e.return===t)return!0;e=e.return}e.sibling.return=e.return,e=e.sibling}}return!0}function sr(t,e){for(e&=~q1,e&=~Kf,t.suspendedLanes|=e,t.pingedLanes&=~e,t=t.expirationTimes;0<e;){var a=31-Tn(e),n=1<<a;t[a]=-1,e&=~n}}function D_(t){if(Ee&6)throw Error(U(327));al();var e=Ym(t,0);if(!(e&1))return ja(t,pt()),null;var a=gh(t,e);if(t.tag!==0&&a===2){var n=Ox(t);n!==0&&(e=n,a=cv(t,n))}if(a===1)throw a=Wd,Io(t,0),sr(t,e),ja(t,pt()),a;if(a===6)throw Error(U(345));return t.finishedWork=t.current.alternate,t.finishedLanes=e,mo(t,ka,fi),ja(t,pt()),null}function V1(t,e){var a=Ee;Ee|=1;try{return t(e)}finally{Ee=a,Ee===0&&(xl=pt()+500,Uf&&Kr())}}function Go(t){fr!==null&&fr.tag===0&&!(Ee&6)&&al();var e=Ee;Ee|=1;var a=cn.transition,n=Le;try{if(cn.transition=null,Le=1,t)return t()}finally{Le=n,cn.transition=a,Ee=e,!(Ee&6)&&Kr()}}function H1(){Da=Us.current,$e(Us)}function Io(t,e){t.finishedWork=null,t.finishedLanes=0;var a=t.timeoutHandle;if(a!==-1&&(t.timeoutHandle=-1,W6(a)),ft!==null)for(a=ft.return;a!==null;){var n=a;switch(w1(n),n.tag){case 1:n=n.type.childContextTypes,n!=null&&nh();break;case 3:gl(),$e(Ea),$e(ia),N1();break;case 5:T1(n);break;case 4:gl();break;case 13:$e(Je);break;case 19:$e(Je);break;case 10:A1(n.type._context);break;case 22:case 23:H1()}a=a.return}if(It=t,ft=t=jr(t.current,null),Ft=Da=e,kt=0,Wd=null,q1=Kf=Wo=0,ka=ad=null,vo!==null){for(e=0;e<vo.length;e++)if(a=vo[e],n=a.interleaved,n!==null){a.interleaved=null;var i=n.next,r=a.pending;if(r!==null){var o=r.next;r.next=i,n.next=o}a.pending=n}vo=null}return t}function XI(t,e){do{var a=ft;try{if(_1(),gm.current=ph,uh){for(var n=Ye.memoizedState;n!==null;){var i=n.queue;i!==null&&(i.pending=null),n=n.next}uh=!1}if($o=0,jt=wt=Ye=null,ed=!1,Bd=0,D1.current=null,a===null||a.return===null){kt=1,Wd=e,ft=null;break}e:{var r=t,o=a.return,l=a,c=e;if(e=Ft,l.flags|=32768,c!==null&&typeof c=="object"&&typeof c.then=="function"){var d=c,u=l,p=u.tag;if(!(u.mode&1)&&(p===0||p===11||p===15)){var m=u.alternate;m?(u.updateQueue=m.updateQueue,u.memoizedState=m.memoizedState,u.lanes=m.lanes):(u.updateQueue=null,u.memoizedState=null)}var h=__(o);if(h!==null){h.flags&=-257,A_(h,o,l,r,e),h.mode&1&&S_(r,d,e),e=h,c=d;var g=e.updateQueue;if(g===null){var y=new Set;y.add(c),e.updateQueue=y}else g.add(c);break e}else{if(!(e&1)){S_(r,d,e),F1();break e}c=Error(U(426))}}else if(Ge&&l.mode&1){var x=__(o);if(x!==null){!(x.flags&65536)&&(x.flags|=256),A_(x,o,l,r,e),k1(yl(c,l));break e}}r=c=yl(c,l),kt!==4&&(kt=2),ad===null?ad=[r]:ad.push(r),r=o;do{switch(r.tag){case 3:r.flags|=65536,e&=-e,r.lanes|=e;var v=LI(r,c,e);y_(r,v);break e;case 1:l=c;var w=r.type,S=r.stateNode;if(!(r.flags&128)&&(typeof w.getDerivedStateFromError=="function"||S!==null&&typeof S.componentDidCatch=="function"&&(Er===null||!Er.has(S)))){r.flags|=65536,e&=-e,r.lanes|=e;var T=OI(r,l,e);y_(r,T);break e}}r=r.return}while(r!==null)}eP(a)}catch(P){e=P,ft===a&&a!==null&&(ft=a=a.return);continue}break}while(!0)}function YI(){var t=mh.current;return mh.current=ph,t===null?ph:t}function F1(){(kt===0||kt===3||kt===2)&&(kt=4),It===null||!(Wo&268435455)&&!(Kf&268435455)||sr(It,Ft)}function gh(t,e){var a=Ee;Ee|=2;var n=YI();(It!==t||Ft!==e)&&(fi=null,Io(t,e));do try{yz();break}catch(i){XI(t,i)}while(!0);if(_1(),Ee=a,mh.current=n,ft!==null)throw Error(U(261));return It=null,Ft=0,kt}function yz(){for(;ft!==null;)ZI(ft)}function xz(){for(;ft!==null&&!Bq();)ZI(ft)}function ZI(t){var e=aP(t.alternate,t,Da);t.memoizedProps=t.pendingProps,e===null?eP(t):ft=e,D1.current=null}function eP(t){var e=t;do{var a=e.alternate;if(t=e.return,e.flags&32768){if(a=uz(a,e),a!==null){a.flags&=32767,ft=a;return}if(t!==null)t.flags|=32768,t.subtreeFlags=0,t.deletions=null;else{kt=6,ft=null;return}}else if(a=dz(a,e,Da),a!==null){ft=a;return}if(e=e.sibling,e!==null){ft=e;return}ft=e=t}while(e!==null);kt===0&&(kt=5)}function mo(t,e,a){var n=Le,i=cn.transition;try{cn.transition=null,Le=1,vz(t,e,a,n)}finally{cn.transition=i,Le=n}return null}function vz(t,e,a,n){do al();while(fr!==null);if(Ee&6)throw Error(U(327));a=t.finishedWork;var i=t.finishedLanes;if(a===null)return null;if(t.finishedWork=null,t.finishedLanes=0,a===t.current)throw Error(U(177));t.callbackNode=null,t.callbackPriority=0;var r=a.lanes|a.childLanes;if(Zq(t,r),t===It&&(ft=It=null,Ft=0),!(a.subtreeFlags&2064)&&!(a.flags&2064)||Np||(Np=!0,nP(Xm,function(){return al(),null})),r=(a.flags&15990)!==0,a.subtreeFlags&15990||r){r=cn.transition,cn.transition=null;var o=Le;Le=1;var l=Ee;Ee|=4,D1.current=null,mz(t,a),KI(a,t),z6(Hx),Zm=!!Vx,Hx=Vx=null,t.current=a,hz(a),Uq(),Ee=l,Le=o,cn.transition=r}else t.current=a;if(Np&&(Np=!1,fr=t,fh=i),r=t.pendingLanes,r===0&&(Er=null),Gq(a.stateNode),ja(t,pt()),e!==null)for(n=t.onRecoverableError,a=0;a<e.length;a++)i=e[a],n(i.value,{componentStack:i.stack,digest:i.digest});if(hh)throw hh=!1,t=sv,sv=null,t;return fh&1&&t.tag!==0&&al(),r=t.pendingLanes,r&1?t===lv?nd++:(nd=0,lv=t):nd=0,Kr(),null}function al(){if(fr!==null){var t=LN(fh),e=cn.transition,a=Le;try{if(cn.transition=null,Le=16>t?16:t,fr===null)var n=!1;else{if(t=fr,fr=null,fh=0,Ee&6)throw Error(U(331));var i=Ee;for(Ee|=4,Q=t.current;Q!==null;){var r=Q,o=r.child;if(Q.flags&16){var l=r.deletions;if(l!==null){for(var c=0;c<l.length;c++){var d=l[c];for(Q=d;Q!==null;){var u=Q;switch(u.tag){case 0:case 11:case 15:td(8,u,r)}var p=u.child;if(p!==null)p.return=u,Q=p;else for(;Q!==null;){u=Q;var m=u.sibling,h=u.return;if($I(u),u===d){Q=null;break}if(m!==null){m.return=h,Q=m;break}Q=h}}}var g=r.alternate;if(g!==null){var y=g.child;if(y!==null){g.child=null;do{var x=y.sibling;y.sibling=null,y=x}while(y!==null)}}Q=r}}if(r.subtreeFlags&2064&&o!==null)o.return=r,Q=o;else e:for(;Q!==null;){if(r=Q,r.flags&2048)switch(r.tag){case 0:case 11:case 15:td(9,r,r.return)}var v=r.sibling;if(v!==null){v.return=r.return,Q=v;break e}Q=r.return}}var w=t.current;for(Q=w;Q!==null;){o=Q;var S=o.child;if(o.subtreeFlags&2064&&S!==null)S.return=o,Q=S;else e:for(o=w;Q!==null;){if(l=Q,l.flags&2048)try{switch(l.tag){case 0:case 11:case 15:Gf(9,l)}}catch(P){ot(l,l.return,P)}if(l===o){Q=null;break e}var T=l.sibling;if(T!==null){T.return=l.return,Q=T;break e}Q=l.return}}if(Ee=i,Kr(),Xn&&typeof Xn.onPostCommitFiberRoot=="function")try{Xn.onPostCommitFiberRoot(zf,t)}catch{}n=!0}return n}finally{Le=a,cn.transition=e}}return!1}function q_(t,e,a){e=yl(a,e),e=LI(t,e,1),t=Ar(t,e,1),e=fa(),t!==null&&(Su(t,1,e),ja(t,e))}function ot(t,e,a){if(t.tag===3)q_(t,t,a);else for(;e!==null;){if(e.tag===3){q_(e,t,a);break}else if(e.tag===1){var n=e.stateNode;if(typeof e.type.getDerivedStateFromError=="function"||typeof n.componentDidCatch=="function"&&(Er===null||!Er.has(n))){t=yl(a,t),t=OI(e,t,1),e=Ar(e,t,1),t=fa(),e!==null&&(Su(e,1,t),ja(e,t));break}}e=e.return}}function bz(t,e,a){var n=t.pingCache;n!==null&&n.delete(e),e=fa(),t.pingedLanes|=t.suspendedLanes&a,It===t&&(Ft&a)===a&&(kt===4||kt===3&&(Ft&130023424)===Ft&&500>pt()-z1?Io(t,0):q1|=a),ja(t,e)}function tP(t,e){e===0&&(t.mode&1?(e=bp,bp<<=1,!(bp&130023424)&&(bp=4194304)):e=1);var a=fa();t=Oi(t,e),t!==null&&(Su(t,e,a),ja(t,a))}function wz(t){var e=t.memoizedState,a=0;e!==null&&(a=e.retryLane),tP(t,a)}function kz(t,e){var a=0;switch(t.tag){case 13:var n=t.stateNode,i=t.memoizedState;i!==null&&(a=i.retryLane);break;case 19:n=t.stateNode;break;default:throw Error(U(314))}n!==null&&n.delete(e),tP(t,a)}var aP;aP=function(t,e,a){if(t!==null)if(t.memoizedProps!==e.pendingProps||Ea.current)Aa=!0;else{if(!(t.lanes&a)&&!(e.flags&128))return Aa=!1,cz(t,e,a);Aa=!!(t.flags&131072)}else Aa=!1,Ge&&e.flags&1048576&&oI(e,oh,e.index);switch(e.lanes=0,e.tag){case 2:var n=e.type;xm(t,e),t=e.pendingProps;var i=ml(e,ia.current);tl(e,a),i=P1(null,e,n,t,i,a);var r=R1();return e.flags|=1,typeof i=="object"&&i!==null&&typeof i.render=="function"&&i.$$typeof===void 0?(e.tag=1,e.memoizedState=null,e.updateQueue=null,Ca(n)?(r=!0,ih(e)):r=!1,e.memoizedState=i.state!==null&&i.state!==void 0?i.state:null,C1(e),i.updater=Wf,e.stateNode=i,i._reactInternals=e,Qx(e,n,t,a),e=Zx(null,e,n,!0,r,a)):(e.tag=0,Ge&&r&&b1(e),ua(null,e,i,a),e=e.child),e;case 16:n=e.elementType;e:{switch(xm(t,e),t=e.pendingProps,i=n._init,n=i(n._payload),e.type=n,i=e.tag=_z(n),t=kn(n,t),i){case 0:e=Yx(null,e,n,t,a);break e;case 1:e=j_(null,e,n,t,a);break e;case 11:e=E_(null,e,n,t,a);break e;case 14:e=C_(null,e,n,kn(n.type,t),a);break e}throw Error(U(306,n,""))}return e;case 0:return n=e.type,i=e.pendingProps,i=e.elementType===n?i:kn(n,i),Yx(t,e,n,i,a);case 1:return n=e.type,i=e.pendingProps,i=e.elementType===n?i:kn(n,i),j_(t,e,n,i,a);case 3:e:{if(zI(e),t===null)throw Error(U(387));n=e.pendingProps,r=e.memoizedState,i=r.element,pI(t,e),ch(e,n,null,a);var o=e.memoizedState;if(n=o.element,r.isDehydrated)if(r={element:n,isDehydrated:!1,cache:o.cache,pendingSuspenseBoundaries:o.pendingSuspenseBoundaries,transitions:o.transitions},e.updateQueue.baseState=r,e.memoizedState=r,e.flags&256){i=yl(Error(U(423)),e),e=T_(t,e,n,a,i);break e}else if(n!==i){i=yl(Error(U(424)),e),e=T_(t,e,n,a,i);break e}else for(za=_r(e.stateNode.containerInfo.firstChild),Fa=e,Ge=!0,_n=null,a=dI(e,null,n,a),e.child=a;a;)a.flags=a.flags&-3|4096,a=a.sibling;else{if(hl(),n===i){e=Mi(t,e,a);break e}ua(t,e,n,a)}e=e.child}return e;case 5:return mI(e),t===null&&Gx(e),n=e.type,i=e.pendingProps,r=t!==null?t.memoizedProps:null,o=i.children,Fx(n,i)?o=null:r!==null&&Fx(n,r)&&(e.flags|=32),qI(t,e),ua(t,e,o,a),e.child;case 6:return t===null&&Gx(e),null;case 13:return VI(t,e,a);case 4:return j1(e,e.stateNode.containerInfo),n=e.pendingProps,t===null?e.child=fl(e,null,n,a):ua(t,e,n,a),e.child;case 11:return n=e.type,i=e.pendingProps,i=e.elementType===n?i:kn(n,i),E_(t,e,n,i,a);case 7:return ua(t,e,e.pendingProps,a),e.child;case 8:return ua(t,e,e.pendingProps.children,a),e.child;case 12:return ua(t,e,e.pendingProps.children,a),e.child;
vendor: 4,549 bytes, line 40
40case 10:e:{if(n=e.type._context,i=e.pendingProps,r=e.memoizedProps,o=i.value,Ve(sh,n._currentValue),n._currentValue=o,r!==null)if(Ln(r.value,o)){if(r.children===i.children&&!Ea.current){e=Mi(t,e,a);break e}}else for(r=e.child,r!==null&&(r.return=e);r!==null;){var l=r.dependencies;if(l!==null){o=r.child;for(var c=l.firstContext;c!==null;){if(c.context===n){if(r.tag===1){c=Ei(-1,a&-a),c.tag=2;var d=r.updateQueue;if(d!==null){d=d.shared;var u=d.pending;u===null?c.next=c:(c.next=u.next,u.next=c),d.pending=c}}r.lanes|=a,c=r.alternate,c!==null&&(c.lanes|=a),Kx(r.return,a,e),l.lanes|=a;break}c=c.next}}else if(r.tag===10)o=r.type===e.type?null:r.child;else if(r.tag===18){if(o=r.return,o===null)throw Error(U(341));o.lanes|=a,l=o.alternate,l!==null&&(l.lanes|=a),Kx(o,a,e),o=r.sibling}else o=r.child;if(o!==null)o.return=r;else for(o=r;o!==null;){if(o===e){o=null;break}if(r=o.sibling,r!==null){r.return=o.return,o=r;break}o=o.return}r=o}ua(t,e,i.children,a),e=e.child}return e;case 9:return i=e.type,n=e.pendingProps.children,tl(e,a),i=pn(i),n=n(i),e.flags|=1,ua(t,e,n,a),e.child;case 14:return n=e.type,i=kn(n,e.pendingProps),i=kn(n.type,i),C_(t,e,n,i,a);case 15:return MI(t,e,e.type,e.pendingProps,a);case 17:return n=e.type,i=e.pendingProps,i=e.elementType===n?i:kn(n,i),xm(t,e),e.tag=1,Ca(n)?(t=!0,ih(e)):t=!1,tl(e,a),RI(e,n,i),Qx(e,n,i,a),Zx(null,e,n,!0,t,a);case 19:return HI(t,e,a);case 22:return DI(t,e,a)}throw Error(U(156,e.tag))};function nP(t,e){return NN(t,e)}function Sz(t,e,a,n){this.tag=t,this.key=a,this.sibling=this.child=this.return=this.stateNode=this.type=this.elementType=null,this.index=0,this.ref=null,this.pendingProps=e,this.dependencies=this.memoizedState=this.updateQueue=this.memoizedProps=null,this.mode=n,this.subtreeFlags=this.flags=0,this.deletions=null,this.childLanes=this.lanes=0,this.alternate=null}function sn(t,e,a,n){return new Sz(t,e,a,n)}function B1(t){return t=t.prototype,!(!t||!t.isReactComponent)}function _z(t){if(typeof t=="function")return B1(t)?1:0;if(t!=null){if(t=t.$$typeof,t===l1)return 11;if(t===c1)return 14}return 2}function jr(t,e){var a=t.alternate;return a===null?(a=sn(t.tag,e,t.key,t.mode),a.elementType=t.elementType,a.type=t.type,a.stateNode=t.stateNode,a.alternate=t,t.alternate=a):(a.pendingProps=e,a.type=t.type,a.flags=0,a.subtreeFlags=0,a.deletions=null),a.flags=t.flags&14680064,a.childLanes=t.childLanes,a.lanes=t.lanes,a.child=t.child,a.memoizedProps=t.memoizedProps,a.memoizedState=t.memoizedState,a.updateQueue=t.updateQueue,e=t.dependencies,a.dependencies=e===null?null:{lanes:e.lanes,firstContext:e.firstContext},a.sibling=t.sibling,a.index=t.index,a.ref=t.ref,a}function wm(t,e,a,n,i,r){var o=2;if(n=t,typeof t=="function")B1(t)&&(o=1);else if(typeof t=="string")o=5;else e:switch(t){case Ls:return Po(a.children,i,r,e);case s1:o=8,i|=8;break;case bx:return t=sn(12,a,e,i|2),t.elementType=bx,t.lanes=r,t;case wx:return t=sn(13,a,e,i),t.elementType=wx,t.lanes=r,t;case kx:return t=sn(19,a,e,i),t.elementType=kx,t.lanes=r,t;case mN:return Jf(a,i,r,e);default:if(typeof t=="object"&&t!==null)switch(t.$$typeof){case uN:o=10;break e;case pN:o=9;break e;case l1:o=11;break e;case c1:o=14;break e;case tr:o=16,n=null;break e}throw Error(U(130,t==null?t:typeof t,""))}return e=sn(o,a,e,i),e.elementType=t,e.type=n,e.lanes=r,e}function Po(t,e,a,n){return t=sn(7,t,n,e),t.lanes=a,t}function Jf(t,e,a,n){return t=sn(22,t,n,e),t.elementType=mN,t.lanes=a,t.stateNode={isHidden:!1},t}function Wy(t,e,a){return t=sn(6,t,null,e),t.lanes=a,t}function Gy(t,e,a){return e=sn(4,t.children!==null?t.children:[],t.key,e),e.lanes=a,e.stateNode={containerInfo:t.containerInfo,pendingChildren:null,implementation:t.implementation},e}function Az(t,e,a,n,i){this.tag=e,this.containerInfo=t,this.finishedWork=this.pingCache=this.current=this.pendingChildren=null,this.timeoutHandle=-1,this.callbackNode=this.pendingContext=this.context=null,this.callbackPriority=0,this.eventTimes=Cy(0),this.expirationTimes=Cy(-1),this.entangledLanes=this.finishedLanes=this.mutableReadLanes=this.expiredLanes=this.pingedLanes=this.suspendedLanes=this.pendingLanes=0,this.entanglements=Cy(0),this.identifierPrefix=n,this.onRecoverableError=i,this.mutableSourceEagerHydrationData=null}function U1(t,e,a,n,i,r,o,l,c){return t=new Az(t,e,a,l,c),e===1?(e=1,r===!0&&(e|=8)):e=0,r=sn(3,null,null,e),t.current=r,r.stateNode=t,r.memoizedState={element:n,isDehydrated:a,cache:null,transitions:null,pendingSuspenseBoundaries:null},C1(r),t}function Ez(t,e,a){var n=3<arguments.length&&arguments[3]!==void 0?arguments[3]:null;
vendor: 4,591 bytes, line 40
40return{$$typeof:Rs,key:n==null?null:""+n,children:t,containerInfo:e,implementation:a}}function iP(t){if(!t)return qr;t=t._reactInternals;e:{if(cs(t)!==t||t.tag!==1)throw Error(U(170));var e=t;do{switch(e.tag){case 3:e=e.stateNode.context;break e;case 1:if(Ca(e.type)){e=e.stateNode.__reactInternalMemoizedMergedChildContext;break e}}e=e.return}while(e!==null);throw Error(U(171))}if(t.tag===1){var a=t.type;if(Ca(a))return iI(t,a,e)}return e}function rP(t,e,a,n,i,r,o,l,c){return t=U1(a,n,!0,t,i,r,o,l,c),t.context=iP(null),a=t.current,n=fa(),i=Cr(a),r=Ei(n,i),r.callback=e??null,Ar(a,r,i),t.current.lanes=i,Su(t,i,n),ja(t,n),t}function Qf(t,e,a,n){var i=e.current,r=fa(),o=Cr(i);return a=iP(a),e.context===null?e.context=a:e.pendingContext=a,e=Ei(r,o),e.payload={element:t},n=n===void 0?null:n,n!==null&&(e.callback=n),t=Ar(i,e,o),t!==null&&(Nn(t,i,o,r),fm(t,i,o)),o}function yh(t){if(t=t.current,!t.child)return null;switch(t.child.tag){case 5:return t.child.stateNode;default:return t.child.stateNode}}function z_(t,e){if(t=t.memoizedState,t!==null&&t.dehydrated!==null){var a=t.retryLane;t.retryLane=a!==0&&a<e?a:e}}function $1(t,e){z_(t,e),(t=t.alternate)&&z_(t,e)}function Cz(){return null}var oP=typeof reportError=="function"?reportError:function(t){console.error(t)};function W1(t){this._internalRoot=t}Xf.prototype.render=W1.prototype.render=function(t){var e=this._internalRoot;if(e===null)throw Error(U(409));Qf(t,e,null,null)};Xf.prototype.unmount=W1.prototype.unmount=function(){var t=this._internalRoot;if(t!==null){this._internalRoot=null;var e=t.containerInfo;Go(function(){Qf(null,t,null,null)}),e[Li]=null}};function Xf(t){this._internalRoot=t}Xf.prototype.unstable_scheduleHydration=function(t){if(t){var e=DN();t={blockedOn:null,target:t,priority:e};for(var a=0;a<or.length&&e!==0&&e<or[a].priority;a++);or.splice(a,0,t),a===0&&zN(t)}};function G1(t){return!(!t||t.nodeType!==1&&t.nodeType!==9&&t.nodeType!==11)}function Yf(t){return!(!t||t.nodeType!==1&&t.nodeType!==9&&t.nodeType!==11&&(t.nodeType!==8||t.nodeValue!==" react-mount-point-unstable "))}function V_(){}function jz(t,e,a,n,i){if(i){if(typeof n=="function"){var r=n;n=function(){var d=yh(o);r.call(d)}}var o=rP(e,n,t,0,null,!1,!1,"",V_);return t._reactRootContainer=o,t[Li]=o.current,qd(t.nodeType===8?t.parentNode:t),Go(),o}for(;i=t.lastChild;)t.removeChild(i);if(typeof n=="function"){var l=n;n=function(){var d=yh(c);l.call(d)}}var c=U1(t,0,!1,null,null,!1,!1,"",V_);return t._reactRootContainer=c,t[Li]=c.current,qd(t.nodeType===8?t.parentNode:t),Go(function(){Qf(e,c,a,n)}),c}function Zf(t,e,a,n,i){var r=a._reactRootContainer;if(r){var o=r;if(typeof i=="function"){var l=i;i=function(){var c=yh(o);l.call(c)}}Qf(e,o,t,i)}else o=jz(a,e,t,i,n);return yh(o)}ON=function(t){switch(t.tag){case 3:var e=t.stateNode;if(e.current.memoizedState.isDehydrated){var a=Mc(e.pendingLanes);a!==0&&(p1(e,a|1),ja(e,pt()),!(Ee&6)&&(xl=pt()+500,Kr()))}break;case 13:Go(function(){var n=Oi(t,1);if(n!==null){var i=fa();Nn(n,t,1,i)}}),$1(t,1)}};m1=function(t){if(t.tag===13){var e=Oi(t,134217728);if(e!==null){var a=fa();Nn(e,t,134217728,a)}$1(t,134217728)}};MN=function(t){if(t.tag===13){var e=Cr(t),a=Oi(t,e);if(a!==null){var n=fa();Nn(a,t,e,n)}$1(t,e)}};DN=function(){return Le};qN=function(t,e){var a=Le;try{return Le=t,e()}finally{Le=a}};Px=function(t,e,a){switch(e){case"input":if(Ax(t,a),e=a.name,a.type==="radio"&&e!=null){for(a=t;a.parentNode;)a=a.parentNode;for(a=a.querySelectorAll("input[name="+JSON.stringify(""+e)+'][type="radio"]'),e=0;e<a.length;e++){var n=a[e];if(n!==t&&n.form===t.form){var i=Bf(n);if(!i)throw Error(U(90));fN(n),Ax(n,i)}}}break;case"textarea":yN(t,a);break;case"select":e=a.value,e!=null&&Xs(t,!!a.multiple,e,!1)}};_N=V1;AN=Go;var Tz={usingClientEntryPoint:!1,Events:[Au,qs,Bf,kN,SN,V1]},wc={findFiberByHostInstance:xo,bundleType:0,version:"18.3.1",rendererPackageName:"react-dom"},Nz={bundleType:wc.bundleType,version:wc.version,rendererPackageName:wc.rendererPackageName,rendererConfig:wc.rendererConfig,overrideHookState:null,overrideHookStateDeletePath:null,overrideHookStateRenamePath:null,overrideProps:null,overridePropsDeletePath:null,overridePropsRenamePath:null,setErrorHandler:null,setSuspenseHandler:null,scheduleUpdate:null,currentDispatcherRef:Ui.ReactCurrentDispatcher,findHostInstanceByFiber:function(t){return t=jN(t),t===null?null:t.stateNode},findFiberByHostInstance:wc.findFiberByHostInstance||Cz,findHostInstancesForRefresh:null,scheduleRefresh:null,scheduleRoot:null,setRefreshHandler:null,getCurrentFiber:null,reconcilerVersion:"18.3.1-next-f1338f8080-20240426"};
40if(typeof __REACT_DEVTOOLS_GLOBAL_HOOK__<"u"){var Ip=__REACT_DEVTOOLS_GLOBAL_HOOK__;if(!Ip.isDisabled&&Ip.supportsFiber)try{zf=Ip.inject(Nz),Xn=Ip}catch{}}Ga.__SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED=Tz;Ga.createPortal=function(t,e){var a=2<arguments.length&&arguments[2]!==void 0?arguments[2]:null;if(!G1(e))throw Error(U(200));return Ez(t,e,null,a)};Ga.createRoot=function(t,e){if(!G1(t))throw Error(U(299));var a=!1,n="",i=oP;return e!=null&&(e.unstable_strictMode===!0&&(a=!0),e.identifierPrefix!==void 0&&(n=e.identifierPrefix),e.onRecoverableError!==void 0&&(i=e.onRecoverableError)),e=U1(t,1,!1,null,null,a,!1,n,i),t[Li]=e.current,qd(t.nodeType===8?t.parentNode:t),new W1(e)};Ga.findDOMNode=function(t){if(t==null)return null;if(t.nodeType===1)return t;var e=t._reactInternals;if(e===void 0)throw typeof t.render=="function"?Error(U(188)):(t=Object.keys(t).join(","),Error(U(268,t)));return t=jN(e),t=t===null?null:t.stateNode,t};Ga.flushSync=function(t){return Go(t)};Ga.hydrate=function(t,e,a){if(!Yf(e))throw Error(U(200));return Zf(null,t,e,!0,a)};Ga.hydrateRoot=function(t,e,a){if(!G1(t))throw Error(U(405));var n=a!=null&&a.hydratedSources||null,i=!1,r="",o=oP;if(a!=null&&(a.unstable_strictMode===!0&&(i=!0),a.identifierPrefix!==void 0&&(r=a.identifierPrefix),a.onRecoverableError!==void 0&&(o=a.onRecoverableError)),e=rP(e,null,t,1,a??null,i,!1,r,o),t[Li]=e.current,qd(t),n)for(t=0;t<n.length;t++)a=n[t],i=a._getVersion,i=i(a._source),e.mutableSourceEagerHydrationData==null?e.mutableSourceEagerHydrationData=[a,i]:e.mutableSourceEagerHydrationData.push(a,i);return new Xf(e)};Ga.render=function(t,e,a){if(!Yf(e))throw Error(U(200));return Zf(null,t,e,!1,a)};Ga.unmountComponentAtNode=function(t){if(!Yf(t))throw Error(U(40));return t._reactRootContainer?(Go(function(){Zf(null,null,t,!1,function(){t._reactRootContainer=null,t[Li]=null})}),!0):!1};Ga.unstable_batchedUpdates=V1;Ga.unstable_renderSubtreeIntoContainer=function(t,e,a,n){if(!Yf(a))throw Error(U(200));if(t==null||t._reactInternals===void 0)throw Error(U(38));return Zf(t,e,a,!1,n)};Ga.version="18.3.1-next-f1338f8080-20240426";function sP(){if(!(typeof __REACT_DEVTOOLS_GLOBAL_HOOK__>"u"||typeof __REACT_DEVTOOLS_GLOBAL_HOOK__.checkDCE!="function"))try{__REACT_DEVTOOLS_GLOBAL_HOOK__.checkDCE(sP)}catch(t){console.error(t)}}sP(),sN.exports=Ga;var lP=sN.exports;const Iz=wu(lP);var H_=lP;xx.createRoot=H_.createRoot,xx.hydrateRoot=H_.hydrateRoot;var Pz=typeof Element<"u",Rz=typeof Map=="function",Lz=typeof Set=="function",Oz=typeof ArrayBuffer=="function"&&!!ArrayBuffer.isView;function km(t,e){if(t===e)return!0;if(t&&e&&typeof t=="object"&&typeof e=="object"){if(t.constructor!==e.constructor)return!1;var a,n,i;if(Array.isArray(t)){if(a=t.length,a!=e.length)return!1;for(n=a;n--!==0;)if(!km(t[n],e[n]))return!1;return!0}var r;if(Rz&&t instanceof Map&&e instanceof Map){if(t.size!==e.size)return!1;for(r=t.entries();!(n=r.next()).done;)if(!e.has(n.value[0]))return!1;for(r=t.entries();!(n=r.next()).done;)if(!km(n.value[1],e.get(n.value[0])))return!1;return!0}if(Lz&&t instanceof Set&&e instanceof Set){if(t.size!==e.size)return!1;for(r=t.entries();!(n=r.next()).done;)if(!e.has(n.value[0]))return!1;return!0}if(Oz&&ArrayBuffer.isView(t)&&ArrayBuffer.isView(e)){if(a=t.length,a!=e.length)return!1;for(n=a;n--!==0;)if(t[n]!==e[n])return!1;return!0}if(t.constructor===RegExp)return t.source===e.source&&t.flags===e.flags;if(t.valueOf!==Object.prototype.valueOf&&typeof t.valueOf=="function"&&typeof e.valueOf=="function")return t.valueOf()===e.valueOf();if(t.toString!==Object.prototype.toString&&typeof t.toString=="function"&&typeof e.toString=="function")return t.toString()===e.toString();if(i=Object.keys(t),a=i.length,a!==Object.keys(e).length)return!1;for(n=a;n--!==0;)if(!Object.prototype.hasOwnProperty.call(e,i[n]))return!1;if(Pz&&t instanceof Element)return!1;for(n=a;n--!==0;)if(!((i[n]==="_owner"||i[n]==="__v"||i[n]==="__o")&&t.$$typeof)&&!km(t[i[n]],e[i[n]]))return!1;return!0}return t!==t&&e!==e}var Mz=function(e,a){try{return km(e,a)}catch(n){if((n.message||"").match(/stack|recursion/i))return console.warn("react-fast-compare cannot handle circular refs"),!1;throw n}};const Dz=wu(Mz);var qz=function(t,e,a,n,i,r,o,l){if(!t){var c;if(e===void 0)c=new Error("Minified exception occurred; use the non-minified dev environment for the full error message and additional helpful warnings.");else{var d=[a,n,i,r,o,l],u=0;c=new Error(e.replace(/%s/g,function(){return d[u++]})),c.name="Invariant Violation"}throw c.framesToPop=1,c}},zz=qz;const F_=wu(zz);var Vz=function(e,a,n,i){var r=n?n.call(i,e,a):void 0;if(r!==void 0)return!!r;if(e===a)return!0;
40if(typeof e!="object"||!e||typeof a!="object"||!a)return!1;var o=Object.keys(e),l=Object.keys(a);if(o.length!==l.length)return!1;for(var c=Object.prototype.hasOwnProperty.bind(a),d=0;d<o.length;d++){var u=o[d];if(!c(u))return!1;var p=e[u],m=a[u];if(r=n?n.call(i,p,m,u):void 0,r===!1||r===void 0&&p!==m)return!1}return!0};const Hz=wu(Vz);var cP=(t=>(t.BASE="base",t.BODY="body",t.HEAD="head",t.HTML="html",t.LINK="link",t.META="meta",t.NOSCRIPT="noscript",t.SCRIPT="script",t.STYLE="style",t.TITLE="title",t.FRAGMENT="Symbol(react.fragment)",t))(cP||{}),Ky={link:{rel:["amphtml","canonical","alternate"]},script:{type:["application/ld+json"]},meta:{charset:"",name:["generator","robots","description"],property:["og:type","og:title","og:url","og:image","og:image:alt","og:description","twitter:url","twitter:title","twitter:description","twitter:image","twitter:image:alt","twitter:card","twitter:site"]}},B_=Object.values(cP),eg={accesskey:"accessKey",charset:"charSet",class:"className",contenteditable:"contentEditable",contextmenu:"contextMenu","http-equiv":"httpEquiv",itemprop:"itemProp",tabindex:"tabIndex"},dP=Object.entries(eg).reduce((t,[e,a])=>(t[a]=e,t),{}),En="data-rh",nl={DEFAULT_TITLE:"defaultTitle",DEFER:"defer",ENCODE_SPECIAL_CHARACTERS:"encodeSpecialCharacters",ON_CHANGE_CLIENT_STATE:"onChangeClientState",TITLE_TEMPLATE:"titleTemplate",PRIORITIZE_SEO_TAGS:"prioritizeSeoTags"},il=(t,e)=>{for(let a=t.length-1;a>=0;a-=1){const n=t[a];if(Object.prototype.hasOwnProperty.call(n,e))return n[e]}return null},Fz=t=>{let e=il(t,"title");const a=il(t,nl.TITLE_TEMPLATE);if(Array.isArray(e)&&(e=e.join("")),a&&e)return a.replace(/%s/g,()=>e);const n=il(t,nl.DEFAULT_TITLE);return e||n||void 0},Bz=t=>il(t,nl.ON_CHANGE_CLIENT_STATE)||(()=>{}),Jy=(t,e)=>e.filter(a=>typeof a[t]<"u").map(a=>a[t]).reduce((a,n)=>({...a,...n}),{}),Uz=(t,e)=>e.filter(a=>typeof a.base<"u").map(a=>a.base).reverse().reduce((a,n)=>{if(!a.length){const i=Object.keys(n);for(let r=0;r<i.length;r+=1){const l=i[r].toLowerCase();if(t.indexOf(l)!==-1&&n[l])return a.concat(n)}}return a},[]),$z=t=>console&&typeof console.warn=="function"&&console.warn(t),kc=(t,e,a)=>{const n={};return a.filter(i=>Array.isArray(i[t])?!0:(typeof i[t]<"u"&&$z(`Helmet: ${t} should be of type "Array". Instead found type "${typeof i[t]}"`),!1)).map(i=>i[t]).reverse().reduce((i,r)=>{const o={};r.filter(c=>{let d;const u=Object.keys(c);for(let m=0;m<u.length;m+=1){const h=u[m],g=h.toLowerCase();e.indexOf(g)!==-1&&!(d==="rel"&&c[d].toLowerCase()==="canonical")&&!(g==="rel"&&c[g].toLowerCase()==="stylesheet")&&(d=g),e.indexOf(h)!==-1&&(h==="innerHTML"||h==="cssText"||h==="itemprop")&&(d=h)}if(!d||!c[d])return!1;const p=c[d].toLowerCase();return n[d]||(n[d]={}),o[d]||(o[d]={}),n[d][p]?!1:(o[d][p]=!0,!0)}).reverse().forEach(c=>i.push(c));const l=Object.keys(o);for(let c=0;c<l.length;c+=1){const d=l[c],u={...n[d],...o[d]};n[d]=u}return i},[]).reverse()},Wz=(t,e)=>{if(Array.isArray(t)&&t.length){for(let a=0;a<t.length;a+=1)if(t[a][e])return!0}return!1},Gz=t=>({baseTag:Uz(["href"],t),bodyAttributes:Jy("bodyAttributes",t),defer:il(t,nl.DEFER),encode:il(t,nl.ENCODE_SPECIAL_CHARACTERS),htmlAttributes:Jy("htmlAttributes",t),linkTags:kc("link",["rel","href"],t),metaTags:kc("meta",["name","charset","http-equiv","property","itemprop"],t),noscriptTags:kc("noscript",["innerHTML"],t),onChangeClientState:Bz(t),scriptTags:kc("script",["src","innerHTML"],t),styleTags:kc("style",["cssText"],t),title:Fz(t),titleAttributes:Jy("titleAttributes",t),prioritizeSeoTags:Wz(t,nl.PRIORITIZE_SEO_TAGS)}),uP=t=>Array.isArray(t)?t.join(""):t,Kz=(t,e)=>{const a=Object.keys(t);for(let n=0;n<a.length;n+=1)if(e[a[n]]&&e[a[n]].includes(t[a[n]]))return!0;return!1},Qy=(t,e)=>Array.isArray(t)?t.reduce((a,n)=>(Kz(n,e)?a.priority.push(n):a.default.push(n),a),{priority:[],default:[]}):{default:t,priority:[]},U_=(t,e)=>({...t,[e]:void 0}),Jz=["noscript","script","style"],uv=(t,e=!0)=>e===!1?String(t):String(t).replace(/&/g,"&amp;").replace(/</g,"&lt;").replace(/>/g,"&gt;").replace(/"/g,"&quot;").replace(/'/g,"&#x27;"),pP=t=>Object.keys(t).reduce((e,a)=>{const n=typeof t[a]<"u"?`${a}="${t[a]}"`:`${a}`;return e?`${e} ${n}`:n},""),Qz=(t,e,a,n)=>{const i=pP(a),r=uP(e);return i?`<${t} ${En}="true" ${i}>${uv(r,n)}</${t}>`:`<${t} ${En}="true">${uv(r,n)}</${t}>`},Xz=(t,e,a=!0)=>e.reduce((n,i)=>{const r=i,o=Object.keys(r).filter(d=>!(d==="innerHTML"||d==="cssText")).reduce((d,u)=>{const p=typeof r[u]>"u"?u:`${u}="${uv(r[u],a)}"`;return d?`${d} ${p}`:p},""),l=r.innerHTML||r.cssText||"",c=Jz.indexOf(t)===-1;return`${n}<${t} ${En}="true" ${o}${c?"/>":`>${l}</${t}>`}`},""),mP=(t,e={})=>Object.keys(t).reduce((a,n)=>{const i=eg[n];return a[i||n]=t[n],a},e),Yz=(t,e,a)=>{const n={key:e,[En]:!0},i=mP(a,n);return[Re.createElement("title",i,e)]},Sm=(t,e)=>e.map((a,n)=>{const i={key:n,[En]:!0};
40return Object.keys(a).forEach(r=>{const l=eg[r]||r;if(l==="innerHTML"||l==="cssText"){const c=a.innerHTML||a.cssText;i.dangerouslySetInnerHTML={__html:c}}else i[l]=a[r]}),Re.createElement(t,i)}),tn=(t,e,a=!0)=>{switch(t){case"title":return{toComponent:()=>Yz(t,e.title,e.titleAttributes),toString:()=>Qz(t,e.title,e.titleAttributes,a)};case"bodyAttributes":case"htmlAttributes":return{toComponent:()=>mP(e),toString:()=>pP(e)};default:return{toComponent:()=>Sm(t,e),toString:()=>Xz(t,e,a)}}},Zz=({metaTags:t,linkTags:e,scriptTags:a,encode:n})=>{const i=Qy(t,Ky.meta),r=Qy(e,Ky.link),o=Qy(a,Ky.script);return{priorityMethods:{toComponent:()=>[...Sm("meta",i.priority),...Sm("link",r.priority),...Sm("script",o.priority)],toString:()=>`${tn("meta",i.priority,n)} ${tn("link",r.priority,n)} ${tn("script",o.priority,n)}`},metaTags:i.default,linkTags:r.default,scriptTags:o.default}},eV=t=>{const{baseTag:e,bodyAttributes:a,encode:n=!0,htmlAttributes:i,noscriptTags:r,styleTags:o,title:l="",titleAttributes:c,prioritizeSeoTags:d}=t;let{linkTags:u,metaTags:p,scriptTags:m}=t,h={toComponent:()=>[],toString:()=>""};return d&&({priorityMethods:h,linkTags:u,metaTags:p,scriptTags:m}=Zz(t)),{priority:h,base:tn("base",e,n),bodyAttributes:tn("bodyAttributes",a,n),htmlAttributes:tn("htmlAttributes",i,n),link:tn("link",u,n),meta:tn("meta",p,n),noscript:tn("noscript",r,n),script:tn("script",m,n),style:tn("style",o,n),title:tn("title",{title:l,titleAttributes:c},n)}},pv=eV,Pp=[],K1=!!(typeof window<"u"&&window.document&&window.document.createElement),mv=class{constructor(t,e){di(this,"instances",[]);di(this,"canUseDOM",K1);di(this,"context");di(this,"value",{setHelmet:t=>{this.context.helmet=t},helmetInstances:{get:()=>this.canUseDOM?Pp:this.instances,add:t=>{(this.canUseDOM?Pp:this.instances).push(t)},remove:t=>{const e=(this.canUseDOM?Pp:this.instances).indexOf(t);(this.canUseDOM?Pp:this.instances).splice(e,1)}}});this.context=t,this.canUseDOM=e||!1,e||(t.helmet=pv({baseTag:[],bodyAttributes:{},htmlAttributes:{},linkTags:[],metaTags:[],noscriptTags:[],scriptTags:[],styleTags:[],title:"",titleAttributes:{}}))}},tV=parseInt(Re.version.split(".")[0],10),hv=tV>=19,aV={},hP=Re.createContext(aV),No,fP=(No=class extends k.Component{constructor(a){super(a);di(this,"helmetData");hv?this.helmetData=null:this.helmetData=new mv(this.props.context||{},No.canUseDOM)}render(){return hv?Re.createElement(Re.Fragment,null,this.props.children):Re.createElement(hP.Provider,{value:this.helmetData.value},this.props.children)}},di(No,"canUseDOM",K1),No),ks=(t,e)=>{const a=document.head||document.querySelector("head"),n=a.querySelectorAll(`${t}[${En}]`),i=[].slice.call(n),r=[];let o;return e&&e.length&&e.forEach(l=>{const c=document.createElement(t);for(const d in l)if(Object.prototype.hasOwnProperty.call(l,d))if(d==="innerHTML")c.innerHTML=l.innerHTML;else if(d==="cssText"){const u=l.cssText;c.appendChild(document.createTextNode(u))}else{const u=d,p=typeof l[u]>"u"?"":l[u];c.setAttribute(d,p)}c.setAttribute(En,"true"),i.some((d,u)=>(o=u,c.isEqualNode(d)))?i.splice(o,1):r.push(c)}
40),i.forEach(l=>{var c;return(c=l.parentNode)==null?void 0:c.removeChild(l)}),r.forEach(l=>a.appendChild(l)),{oldTags:i,newTags:r}},fv=(t,e)=>{const a=document.getElementsByTagName(t)[0];if(!a)return;const n=a.getAttribute(En),i=n?n.split(","):[],r=[...i],o=Object.keys(e);for(const l of o){const c=e[l]||"";a.getAttribute(l)!==c&&a.setAttribute(l,c),i.indexOf(l)===-1&&i.push(l);const d=r.indexOf(l);d!==-1&&r.splice(d,1)}for(let l=r.length-1;l>=0;l-=1)a.removeAttribute(r[l]);i.length===r.length?a.removeAttribute(En):a.getAttribute(En)!==o.join(",")&&a.setAttribute(En,o.join(","))},nV=(t,e)=>{typeof t<"u"&&document.title!==t&&(document.title=uP(t)),fv("title",e)},$_=(t,e)=>{const{baseTag:a,bodyAttributes:n,htmlAttributes:i,linkTags:r,metaTags:o,noscriptTags:l,onChangeClientState:c,scriptTags:d,styleTags:u,title:p,titleAttributes:m}=t;fv("body",n),fv("html",i),nV(p,m);const h={baseTag:ks("base",a),linkTags:ks("link",r),metaTags:ks("meta",o),noscriptTags:ks("noscript",l),scriptTags:ks("script",d),styleTags:ks("style",u)},g={},y={};Object.keys(h).forEach(x=>{const{newTags:v,oldTags:w}=h[x];v.length&&(g[x]=v),w.length&&(y[x]=h[x].oldTags)}),e&&e(),c(t,g,y)},Sc=null,iV=t=>{Sc&&cancelAnimationFrame(Sc),t.defer?Sc=requestAnimationFrame(()=>{$_(t,()=>{Sc=null})}):($_(t),Sc=null)},rV=iV,W_=class extends k.Component{constructor(){super(...arguments);di(this,"rendered",!1)}shouldComponentUpdate(e){return!Hz(e,this.props)}componentDidUpdate(){this.emitChange()}componentWillUnmount(){const{helmetInstances:e}=this.props.context;e.remove(this),this.emitChange()}emitChange(){const{helmetInstances:e,setHelmet:a}=this.props.context;let n=null;const i=Gz(e.get().map(r=>{const{context:o,...l}=r.props;return l}));fP.canUseDOM?rV(i):pv&&(n=pv(i)),a(n)}init(){if(this.rendered)return;this.rendered=!0;const{helmetInstances:e}=this.props.context;e.add(this),this.emitChange()}render(){return this.init(),null}},_m=[],G_=t=>{const e={};for(const a of Object.keys(t))e[dP[a]||a]=t[a];return e},lo=t=>{const e={};for(const a of Object.keys(t)){const n=eg[a];e[n||a]=t[a]}return e},K_=(t,e)=>{if(!K1)return;const a=document.getElementsByTagName(t)[0];if(!a)return;const n="data-rh-managed",i=a.getAttribute(n),r=i?i.split(","):[],o=Object.keys(e);for(const l of r)o.includes(l)||a.removeAttribute(l);for(const l of o){const c=e[l];c==null||c===!1?a.removeAttribute(l):c===!0?a.setAttribute(l,""):a.setAttribute(l,String(c))}o.length>0?a.setAttribute(n,o.join(",")):a.removeAttribute(n)},Xy=()=>{const t={},e={};for(const a of _m){const{htmlAttributes:n,bodyAttributes:i}=a.props;n&&Object.assign(t,G_(n)),i&&Object.assign(e,G_(i))}K_("html",t),K_("body",e)},oV=class extends k.Component{componentDidMount(){_m.push(this),Xy()}componentDidUpdate(){Xy()}componentWillUnmount(){const t=_m.indexOf(this);t!==-1&&_m.splice(t,1),Xy()}resolveTitle(){const{title:t,titleTemplate:e,defaultTitle:a}=this.props;return t&&e?e.replace(/%s/g,()=>Array.isArray(t)?t.join(""):t):t||a||void 0}renderTitle(){const t=this.resolveTitle();if(t===void 0)return null;const e=this.props.titleAttributes||{};return Re.createElement("title",lo(e),t)}renderBase(){const{base:t}=this.props;return t?Re.createElement("base",lo(t)):null}renderMeta(){const{meta:t}=this.props;return!t||!Array.isArray(t)?null:t.map((e,a)=>Re.createElement("meta",{key:a,...lo(e)}))}renderLink(){const{link:t}=this.props;return!t||!Array.isArray(t)?null:t.map((e,a)=>Re.createElement("link",{key:a,...lo(e)}))}renderScript(){const{script:t}=this.props;return!t||!Array.isArray(t)?null:t.map((e,a)=>{const{innerHTML:n,...i}=e,r=lo(i);return n&&(r.dangerouslySetInnerHTML={__html:n}),Re.createElement("script",{key:a,...r})})}renderStyle(){const{style:t}=this.props;return!t||!Array.isArray(t)?null:t.map((e,a)=>{const{cssText:n,...i}=e,r=lo(i);return n&&(r.dangerouslySetInnerHTML={__html:n}),Re.createElement("style",{key:a,...r})})}renderNoscript(){const{noscript:t}=this.props;return!t||!Array.isArray(t)?null:t.map((e,a)=>{const{innerHTML:n,...i}=e,r=lo(i);return n&&(r.dangerouslySetInnerHTML={__html:n}),Re.createElement("noscript",{key:a,...r})})}render(){return Re.createElement(Re.Fragment,null,this.renderTitle(),this.renderBase(),this.renderMeta(),this.renderLink(),this.renderScript(),this.renderStyle(),this.renderNoscript())}},yx,gP=(yx=class extends k.Component{shouldComponentUpdate(t){return!Dz(U_(this.props,"helmetData"),U_(t,"helmetData"))}mapNestedChildrenToProps(t,e){if(!e)return null;switch(t.type){case"script":case"noscript":return{innerHTML:e};case"style":return{cssText:e};default:throw new Error(`<${t.type} /> elements are self-closing and can not contain children. Refer to our API for more information.`)}}flattenArrayTypeChildren(t,e,a,n){return{...e,[t.type]:[...e[t.type]||[],{...a,...this.mapNestedChildrenToProps(t,n)}]}}mapObjectTypeChildren(t,e,a,n){switch(t.type){case"title":return{...e,[t.type]:n,titleAttributes:{...a}};case"body":return{...e,bodyAttributes:{...a}};case"html":return{...e,htmlAttributes:{...a}};default:return{...e,[t.type]:{...a}}}}mapArrayTypeChildrenToProps(t,e){let a={...e};return Object.keys(t).forEach(n=>{a={...a,[n]:t[n]}}),a}
40warnOnInvalidChildren(t,e){return F_(B_.some(a=>t.type===a),typeof t.type=="function"?"You may be attempting to nest <Helmet> components within each other, which is not allowed. Refer to our API for more information.":`Only elements types ${B_.join(", ")} are allowed. Helmet does not support rendering <${t.type}> elements. Refer to our API for more information.`),F_(!e||typeof e=="string"||Array.isArray(e)&&!e.some(a=>typeof a!="string"),`Helmet expects a string as a child of <${t.type}>. Did you forget to wrap your children in braces? ( <${t.type}>{\`\`}</${t.type}> ) Refer to our API for more information.`),!0}mapChildrenToProps(t,e){let a={};return Re.Children.forEach(t,n=>{if(!n||!n.props)return;const{children:i,...r}=n.props,o=Object.keys(r).reduce((c,d)=>(c[dP[d]||d]=r[d],c),{});let{type:l}=n;switch(typeof l=="symbol"?l=l.toString():this.warnOnInvalidChildren(n,i),l){case"Symbol(react.fragment)":e=this.mapChildrenToProps(i,e);break;case"link":case"meta":case"noscript":case"script":case"style":a=this.flattenArrayTypeChildren(n,a,o,i);break;default:e=this.mapObjectTypeChildren(n,e,o,i);break}}),this.mapArrayTypeChildrenToProps(a,e)}render(){const{children:t,...e}=this.props;let a={...e},{helmetData:n}=e;if(t&&(a=this.mapChildrenToProps(t,a)),n&&!(n instanceof mv)){const i=n;n=new mv(i.context,!0),delete a.helmetData}return hv?Re.createElement(oV,{...a}):n?Re.createElement(W_,{...a,context:n.value}):Re.createElement(hP.Consumer,null,i=>Re.createElement(W_,{...a,context:i}))}},di(yx,"defaultProps",{defer:!0,encodeSpecialCharacters:!0,prioritizeSeoTags:!1}),yx);/**
41 * react-router v7.12.0
42 *
43 * Copyright (c) Remix Software Inc.
44 *
45 * This source code is licensed under the MIT license found in the
46 * LICENSE.md file in the root directory of this source tree.
47 *
48 * @license MIT
49 */var J_="popstate";function sV(t={}){function e(n,i){let{pathname:r,search:o,hash:l}=n.location;return gv("",{pathname:r,search:o,hash:l},i.state&&i.state.usr||null,i.state&&i.state.key||"default")}function a(n,i){return typeof i=="string"?i:Gd(i)}return cV(e,a,null,t)}function Ke(t,e){if(t===!1||t===null||typeof t>"u")throw new Error(e)}function Wa(t,e){if(!t){typeof console<"u"&&console.warn(e);try{throw new Error(e)}catch{}}}function lV(){return Math.random().toString(36).substring(2,10)}function Q_(t,e){return{usr:t.state,key:t.key,idx:e}}function gv(t,e,a=null,n){return{pathname:typeof t=="string"?t:t.pathname,search:"",hash:"",...typeof e=="string"?Hl(e):e,state:a,key:e&&e.key||n||lV()}}function Gd({pathname:t="/",search:e="",hash:a=""}){return e&&e!=="?"&&(t+=e.charAt(0)==="?"?e:"?"+e),a&&a!=="#"&&(t+=a.charAt(0)==="#"?a:"#"+a),t}function Hl(t){let e={};if(t){let a=t.indexOf("#");a>=0&&(e.hash=t.substring(a),t=t.substring(0,a));let n=t.indexOf("?");n>=0&&(e.search=t.substring(n),t=t.substring(0,n)),t&&(e.pathname=t)}return e}function cV(t,e,a,n={}){let{window:i=document.defaultView,v5Compat:r=!1}=n,o=i.history,l="POP",c=null,d=u();d==null&&(d=0,o.replaceState({...o.state,idx:d},""));function u(){return(o.state||{idx:null}).idx}function p(){l="POP";let x=u(),v=x==null?null:x-d;d=x,c&&c({action:l,location:y.location,delta:v})}function m(x,v){l="PUSH";let w=gv(y.location,x,v);d=u()+1;let S=Q_(w,d),T=y.createHref(w);try{o.pushState(S,"",T)}catch(P){if(P instanceof DOMException&&P.name==="DataCloneError")throw P;i.location.assign(T)}r&&c&&c({action:l,location:y.location,delta:1})}function h(x,v){l="REPLACE";let w=gv(y.location,x,v);d=u();let S=Q_(w,d),T=y.createHref(w);o.replaceState(S,"",T),r&&c&&c({action:l,location:y.location,delta:0})}function g(x){return dV(x)}let y={get action(){return l},get location(){return t(i,o)}
49,listen(x){if(c)throw new Error("A history only accepts one active listener");return i.addEventListener(J_,p),c=x,()=>{i.removeEventListener(J_,p),c=null}},createHref(x){return e(i,x)},createURL:g,encodeLocation(x){let v=g(x);return{pathname:v.pathname,search:v.search,hash:v.hash}},push:m,replace:h,go(x){return o.go(x)}};return y}function dV(t,e=!1){let a="http://localhost";typeof window<"u"&&(a=window.location.origin!=="null"?window.location.origin:window.location.href),Ke(a,"No window.location.(origin|href) available to create URL");let n=typeof t=="string"?t:Gd(t);return n=n.replace(/ $/,"%20"),!e&&n.startsWith("//")&&(n=a+n),new URL(n,a)}function yP(t,e,a="/"){return uV(t,e,a,!1)}function uV(t,e,a,n){let i=typeof e=="string"?Hl(e):e,r=Di(i.pathname||"/",a);if(r==null)return null;let o=xP(t);pV(o);let l=null;for(let c=0;l==null&&c<o.length;++c){let d=SV(r);l=wV(o[c],d,n)}return l}function xP(t,e=[],a=[],n="",i=!1){let r=(o,l,c=i,d)=>{let u={relativePath:d===void 0?o.path||"":d,caseSensitive:o.caseSensitive===!0,childrenIndex:l,route:o};if(u.relativePath.startsWith("/")){if(!u.relativePath.startsWith(n)&&c)return;Ke(u.relativePath.startsWith(n),`Absolute route path "${u.relativePath}" nested under path "${n}" is not valid. An absolute child route path must start with the combined path of all its parent routes.`),u.relativePath=u.relativePath.slice(n.length)}let p=Ci([n,u.relativePath]),m=a.concat(u);o.children&&o.children.length>0&&(Ke(o.index!==!0,`Index routes must not have child routes. Please remove all child routes from route path "${p}".`),xP(o.children,e,m,p,c)),!(o.path==null&&!o.index)&&e.push({path:p,score:vV(p,o.index),routesMeta:m})};return t.forEach((o,l)=>{var c;if(o.path===""||!((c=o.path)!=null&&c.includes("?")))r(o,l);else for(let d of vP(o.path))r(o,l,!0,d)}),e}function vP(t){let e=t.split("/");if(e.length===0)return[];let[a,...n]=e,i=a.endsWith("?"),r=a.replace(/\?$/,"");if(n.length===0)return i?[r,""]:[r];let o=vP(n.join("/")),l=[];return l.push(...o.map(c=>c===""?r:[r,c].join("/"))),i&&l.push(...o),l.map(c=>t.startsWith("/")&&c===""?"/":c)}function pV(t){t.sort((e,a)=>e.score!==a.score?a.score-e.score:bV(e.routesMeta.map(n=>n.childrenIndex),a.routesMeta.map(n=>n.childrenIndex)))}var mV=/^:[\w-]+$/,hV=3,fV=2,gV=1,yV=10,xV=-2,X_=t=>t==="*";function vV(t,e){let a=t.split("/"),n=a.length;return a.some(X_)&&(n+=xV),e&&(n+=fV),a.filter(i=>!X_(i)).reduce((i,r)=>i+(mV.test(r)?hV:r===""?gV:yV),n)}function bV(t,e){return t.length===e.length&&t.slice(0,-1).every((n,i)=>n===e[i])?t[t.length-1]-e[e.length-1]:0}function wV(t,e,a=!1){let{routesMeta:n}=t,i={},r="/",o=[];for(let l=0;l<n.length;++l){let c=n[l],d=l===n.length-1,u=r==="/"?e:e.slice(r.length)||"/",p=xh({path:c.relativePath,caseSensitive:c.caseSensitive,end:d},u),m=c.route;if(!p&&d&&a&&!n[n.length-1].route.index&&(p=xh({path:c.relativePath,caseSensitive:c.caseSensitive,end:!1},u)),!p)return null;
49Object.assign(i,p.params),o.push({params:i,pathname:Ci([r,p.pathname]),pathnameBase:CV(Ci([r,p.pathnameBase])),route:m}),p.pathnameBase!=="/"&&(r=Ci([r,p.pathnameBase]))}return o}function xh(t,e){typeof t=="string"&&(t={path:t,caseSensitive:!1,end:!0});let[a,n]=kV(t.path,t.caseSensitive,t.end),i=e.match(a);if(!i)return null;let r=i[0],o=r.replace(/(.)\/+$/,"$1"),l=i.slice(1);return{params:n.reduce((d,{paramName:u,isOptional:p},m)=>{if(u==="*"){let g=l[m]||"";o=r.slice(0,r.length-g.length).replace(/(.)\/+$/,"$1")}const h=l[m];return p&&!h?d[u]=void 0:d[u]=(h||"").replace(/%2F/g,"/"),d},{}),pathname:r,pathnameBase:o,pattern:t}}function kV(t,e=!1,a=!0){Wa(t==="*"||!t.endsWith("*")||t.endsWith("/*"),`Route path "${t}" will be treated as if it were "${t.replace(/\*$/,"/*")}" because the \`*\` character must always follow a \`/\` in the pattern. To get rid of this warning, please change the route path to "${t.replace(/\*$/,"/*")}".`);let n=[],i="^"+t.replace(/\/*\*?$/,"").replace(/^\/*/,"/").replace(/[\\.*+^${}|()[\]]/g,"\\$&").replace(/\/:([\w-]+)(\?)?/g,(o,l,c)=>(n.push({paramName:l,isOptional:c!=null}),c?"/?([^\\/]+)?":"/([^\\/]+)")).replace(/\/([\w-]+)\?(\/|$)/g,"(/$1)?$2");return t.endsWith("*")?(n.push({paramName:"*"}),i+=t==="*"||t==="/*"?"(.*)$":"(?:\\/(.+)|\\/*)$"):a?i+="\\/*$":t!==""&&t!=="/"&&(i+="(?:(?=\\/|$))"),[new RegExp(i,e?void 0:"i"),n]}function SV(t){try{return t.split("/").map(e=>decodeURIComponent(e).replace(/\//g,"%2F")).join("/")}catch(e){return Wa(!1,`The URL path "${t}" could not be decoded because it is a malformed URL segment. This is probably due to a bad percent encoding (${e}).`),t}}function Di(t,e){if(e==="/")return t;if(!t.toLowerCase().startsWith(e.toLowerCase()))return null;let a=e.endsWith("/")?e.length-1:e.length,n=t.charAt(a);return n&&n!=="/"?null:t.slice(a)||"/"}var bP=/^(?:[a-z][a-z0-9+.-]*:|\/\/)/i,_V=t=>bP.test(t);function AV(t,e="/"){let{pathname:a,search:n="",hash:i=""}=typeof t=="string"?Hl(t):t,r;if(a)if(_V(a))r=a;else{if(a.includes("//")){let o=a;a=a.replace(/\/\/+/g,"/"),Wa(!1,`Pathnames cannot have embedded double slashes - normalizing ${o} -> ${a}`)}a.startsWith("/")?r=Y_(a.substring(1),"/"):r=Y_(a,e)}else r=e;return{pathname:r,search:jV(n),hash:TV(i)}}function Y_(t,e){let a=e.replace(/\/+$/,"").split("/");return t.split("/").forEach(i=>{i===".."?a.length>1&&a.pop():i!=="."&&a.push(i)}),a.length>1?a.join("/"):"/"}function Yy(t,e,a,n){return`Cannot include a '${t}' character in a manually specified \`to.${e}\` field [${JSON.stringify(n)}].  Please separate it out to the \`to.${a}\` field. Alternatively you may provide the full path as a string in <Link to="..."> and the router will parse it for you.`}function EV(t){return t.filter((e,a)=>a===0||e.route.path&&e.route.path.length>0)}function J1(t){let e=EV(t);return e.map((a,n)=>n===e.length-1?a.pathname:a.pathnameBase)}function Q1(t,e,a,n=!1){let i;typeof t=="string"?i=Hl(t):(i={...t},Ke(!i.pathname||!i.pathname.includes("?"),Yy("?","pathname","search",i)),Ke(!i.pathname||!i.pathname.includes("#"),Yy("#","pathname","hash",i)),Ke(!i.search||!i.search.includes("#"),Yy("#","search","hash",i)));let r=t===""||i.pathname==="",o=r?"/":i.pathname,l;if(o==null)l=a;else{let p=e.length-1;if(!n&&o.startsWith("..")){let m=o.split("/");for(;m[0]==="..";)m.shift(),p-=1;i.pathname=m.join("/")}l=p>=0?e[p]:"/"}let c=AV(i,l),d=o&&o!=="/"&&o.endsWith("/"),u=(r||o===".")&&a.endsWith("/");return!c.pathname.endsWith("/")&&(d||u)&&(c.pathname+="/"),c}var Ci=t=>t.join("/").replace(/\/\/+/g,"/"),CV=t=>t.replace(/\/+$/,"").replace(/^\/*/,"/"),jV=t=>!t||t==="?"?"":t.startsWith("?")?t:"?"+t,TV=t=>!t||t==="#"?"":t.startsWith("#")?t:"#"+t,NV=class{constructor(t,e,a,n=!1){this.status=t,this.statusText=e||"",this.internal=n,a instanceof Error?(this.data=a.toString(),this.error=a):this.data=a}};function IV(t){return t!=null&&typeof t.status=="number"&&typeof t.statusText=="string"&&typeof t.internal=="boolean"&&"data"in t}function PV(t){return t.map(e=>e.route.path).filter(Boolean).join("/").replace(/\/\/*/g,"/")||"/"}var wP=typeof window<"u"&&typeof window.document<"u"&&typeof window.document.createElement<"u";function kP(t,e){let a=t;if(typeof a!="string"||!bP.test(a))return{absoluteURL:void 0,isExternal:!1,to:a};let n=a,i=!1;if(wP)try{let r=new URL(window.location.href),o=a.startsWith("//")?new URL(r.protocol+a):new URL(a),l=Di(o.pathname,e);o.origin===r.origin&&l!=null?a=l+o.search+o.hash:i=!0}catch{Wa(!1,`<Link to="${a}">
49 contains an invalid URL which will probably break when clicked - please update to a valid URL path.`)}return{absoluteURL:n,isExternal:i,to:a}}Object.getOwnPropertyNames(Object.prototype).sort().join("\0");var SP=["POST","PUT","PATCH","DELETE"];new Set(SP);var RV=["GET",...SP];new Set(RV);var Fl=k.createContext(null);Fl.displayName="DataRouter";var tg=k.createContext(null);tg.displayName="DataRouterState";var LV=k.createContext(!1),_P=k.createContext({isTransitioning:!1});_P.displayName="ViewTransition";var OV=k.createContext(new Map);OV.displayName="Fetchers";var MV=k.createContext(null);MV.displayName="Await";var Ja=k.createContext(null);Ja.displayName="Navigation";var Cu=k.createContext(null);Cu.displayName="Location";var zn=k.createContext({outlet:null,matches:[],isDataRoute:!1});zn.displayName="Route";var X1=k.createContext(null);X1.displayName="RouteError";var AP="REACT_ROUTER_ERROR",DV="REDIRECT",qV="ROUTE_ERROR_RESPONSE";function zV(t){if(t.startsWith(`${AP}:${DV}:{`))try{let e=JSON.parse(t.slice(28));if(typeof e=="object"&&e&&typeof e.status=="number"&&typeof e.statusText=="string"&&typeof e.location=="string"&&typeof e.reloadDocument=="boolean"&&typeof e.replace=="boolean")return e}catch{}}function VV(t){if(t.startsWith(`${AP}:${qV}:{`))try{let e=JSON.parse(t.slice(40));if(typeof e=="object"&&e&&typeof e.status=="number"&&typeof e.statusText=="string")return new NV(e.status,e.statusText,e.data)}catch{}}function HV(t,{relative:e}={}){Ke(Bl(),"useHref() may be used only in the context of a <Router> component.");let{basename:a,navigator:n}=k.useContext(Ja),{hash:i,pathname:r,search:o}=ju(t,{relative:e}),l=r;return a!=="/"&&(l=r==="/"?a:Ci([a,r])),n.createHref({pathname:l,search:o,hash:i})}function Bl(){return k.useContext(Cu)!=null}function fn(){return Ke(Bl(),"useLocation() may be used only in the context of a <Router> component."),k.useContext(Cu).location}var EP="You should call navigate() in a React.useEffect(), not when your component is first rendered.";function CP(t){k.useContext(Ja).static||k.useLayoutEffect(t)}function Qa(){let{isDataRoute:t}=k.useContext(zn);return t?e8():FV()}function FV(){Ke(Bl(),"useNavigate() may be used only in the context of a <Router> component.");let t=k.useContext(Fl),{basename:e,navigator:a}=k.useContext(Ja),{matches:n}=k.useContext(zn),{pathname:i}=fn(),r=JSON.stringify(J1(n)),o=k.useRef(!1);return CP(()=>{o.current=!0}),k.useCallback((c,d={})=>{if(Wa(o.current,EP),!o.current)return;if(typeof c=="number"){a.go(c);return}let u=Q1(c,JSON.parse(r),i,d.relative==="path");t==null&&e!=="/"&&(u.pathname=u.pathname==="/"?e:Ci([e,u.pathname])),(d.replace?a.replace:a.push)(u,d.state,d)},[e,a,r,i,t])}k.createContext(null);function jP(){let{matches:t}=k.useContext(zn),e=t[t.length-1];return e?e.params:{}}function ju(t,{relative:e}={}){let{matches:a}=k.useContext(zn),{pathname:n}=fn(),i=JSON.stringify(J1(a));return k.useMemo(()=>Q1(t,JSON.parse(i),n,e==="path"),[t,i,n,e])}function BV(t,e){return TP(t,e)}function TP(t,e,a,n,i){var w;Ke(Bl(),"useRoutes() may be used only in the context of a <Router> component.");let{navigator:r}=k.useContext(Ja),{matches:o}=k.useContext(zn),l=o[o.length-1],c=l?l.params:{},d=l?l.pathname:"/",u=l?l.pathnameBase:"/",p=l&&l.route;{let S=p&&p.path||"";IP(d,!p||S.endsWith("*")||S.endsWith("*?"),`You rendered descendant <Routes> (or called \`useRoutes()\`) at "${d}" (under <Route path="${S}">) but the parent route path has no trailing "*". This means if you navigate deeper, the parent won't match anymore and therefore the child routes will never render.
50
51Please change the parent <Route path="${S}"> to <Route path="${S==="/"?"*":`${S}/*`}">.`)}let m=fn(),h;if(e){let S=typeof e=="string"?Hl(e):e;Ke(u==="/"||((w=S.pathname)==null?void 0:w.startsWith(u)),`When overriding the location using \`<Routes location>\` or \`useRoutes(routes, location)\`, the location pathname must begin with the portion of the URL pathname that was matched by all parent routes. The current pathname base is "${u}" but pathname "${S.pathname}" was given in the \`location\` prop.`),h=S}else h=m;let g=h.pathname||"/",y=g;if(u!=="/"){let S=u.replace(/^\//,"").split("/");y="/"+g.replace(/^\//,"").split("/").slice(S.length).join("/")}let x=yP(t,{pathname:y});Wa(p||x!=null,`No routes matched location "${h.pathname}${h.search}${h.hash}" `),Wa(x==null||x[x.length-1].route.element!==void 0||x[x.length-1].route.Component!==void 0||x[x.length-1].route.lazy!==void 0,`Matched leaf route at location "${h.pathname}${h.search}${h.hash}" does not have an element or Component. This means it will render an <Outlet /> with a null value by default resulting in an "empty" page.`);let v=KV(x&&x.map(S=>Object.assign({},S,{params:Object.assign({},c,S.params),pathname:Ci([u,r.encodeLocation?r.encodeLocation(S.pathname.replace(/\?/g,"%3F").replace(/#/g,"%23")).pathname:S.pathname]),pathnameBase:S.pathnameBase==="/"?u:Ci([u,r.encodeLocation?r.encodeLocation(S.pathnameBase.replace(/\?/g,"%3F").replace(/#/g,"%23")).pathname:S.pathnameBase])})),o,a,n,i);return e&&v?k.createElement(Cu.Provider,{value:{location:{pathname:"/",search:"",hash:"",state:null,key:"default",...h},navigationType:"POP"}},v):v}function UV(){let t=ZV(),e=IV(t)?`${t.status} ${t.statusText}`:t instanceof Error?t.message:JSON.stringify(t),a=t instanceof Error?t.stack:null,n="rgba(200,200,200, 0.5)",i={padding:"0.5rem",backgroundColor:n},r={padding:"2px 4px",backgroundColor:n},o=null;return console.error("Error handled by React Router default ErrorBoundary:",t),o=k.createElement(k.Fragment,null,k.createElement("p",null,"💿 Hey developer 👋"),k.createElement("p",null,"You can provide a way better UX than this when your app throws errors by providing your own ",k.createElement("code",{style:r},"ErrorBoundary")," or"," ",k.createElement("code",{style:r},"errorElement")," prop on your route.")),k.createElement(k.Fragment,null,k.createElement("h2",null,"Unexpected Application 
51Error!"),k.createElement("h3",{style:{fontStyle:"italic"}},e),a?k.createElement("pre",{style:i},a):null,o)}var $V=k.createElement(UV,null),NP=class extends k.Component{constructor(t){super(t),this.state={location:t.location,revalidation:t.revalidation,error:t.error}}static getDerivedStateFromError(t){return{error:t}}static getDerivedStateFromProps(t,e){return e.location!==t.location||e.revalidation!=="idle"&&t.revalidation==="idle"?{error:t.error,location:t.location,revalidation:t.revalidation}:{error:t.error!==void 0?t.error:e.error,location:e.location,revalidation:t.revalidation||e.revalidation}}componentDidCatch(t,e){this.props.onError?this.props.onError(t,e):console.error("React Router caught the following error during render",t)}render(){let t=this.state.error;if(this.context&&typeof t=="object"&&t&&"digest"in t&&typeof t.digest=="string"){const a=VV(t.digest);a&&(t=a)}let e=t!==void 0?k.createElement(zn.Provider,{value:this.props.routeContext},k.createElement(X1.Provider,{value:t,children:this.props.component})):this.props.children;return this.context?k.createElement(WV,{error:t},e):e}};NP.contextType=LV;var Zy=new WeakMap;function WV({children:t,error:e}){let{basename:a}=k.useContext(Ja);if(typeof e=="object"&&e&&"digest"in e&&typeof e.digest=="string"){let n=zV(e.digest);if(n){let i=Zy.get(e);if(i)throw i;let r=kP(n.location,a);if(wP&&!Zy.get(e))if(r.isExternal||n.reloadDocument)window.location.href=r.absoluteURL||r.to;else{const o=Promise.resolve().then(()=>window.__reactRouterDataRouter.navigate(r.to,{replace:n.replace}));throw Zy.set(e,o),o}return k.createElement("meta",{httpEquiv:"refresh",content:`0;url=${r.absoluteURL||r.to}`})}}return t}function GV({routeContext:t,match:e,children:a}){let n=k.useContext(Fl);return n&&n.static&&n.staticContext&&(e.route.errorElement||e.route.ErrorBoundary)&&(n.staticContext._deepestRenderedBoundaryId=e.route.id),k.createElement(zn.Provider,{value:t},a)}function KV(t,e=[],a=null,n=null,i=null){if(t==null){if(!a)return null;if(a.errors)t=a.matches;else if(e.length===0&&!a.initialized&&a.matches.length>0)t=a.matches;else return null}let r=t,o=a==null?void 0:a.errors;if(o!=null){let u=r.findIndex(p=>p.route.id&&(o==null?void 0:o[p.route.id])!==void 0);Ke(u>=0,`Could not find a matching route for errors on route IDs: ${Object.keys(o).join(",")}`),r=r.slice(0,Math.min(r.length,u+1))}let l=!1,c=-1;if(a)for(let u=0;u<r.length;u++){let p=r[u];if((p.route.HydrateFallback||p.route.hydrateFallbackElement)&&(c=u),p.route.id){let{loaderData:m,errors:h}=a,g=p.route.loader&&!m.hasOwnProperty(p.route.id)&&(!h||h[p.route.id]===void 0);if(p.route.lazy||g){l=!0,c>=0?r=r.slice(0,c+1):r=[r[0]];break}}}let d=a&&n?(u,p)=>{var m,h;n(u,{location:a.location,params:((h=(m=a.matches)==null?void 0:m[0])==null?void 0:h.params)??{},unstable_pattern:PV(a.matches),errorInfo:p})}:void 0;return r.reduceRight((u,p,m)=>{let h,g=!1,y=null,x=null;a&&(h=o&&p.route.id?o[p.route.id]:void 0,y=p.route.errorElement||$V,l&&(c<0&&m===0?(IP("route-fallback",!1,"No `HydrateFallback` element provided to render during initial hydration"),g=!0,x=null):c===m&&(g=!0,x=p.route.hydrateFallbackElement||null)));let v=e.concat(r.slice(0,m+1)),w=()=>{let S;return h?S=y:g?S=x:p.route.Component?S=k.createElement(p.route.Component,null):p.route.element?S=p.route.element:S=u,k.createElement(GV,{match:p,routeContext:{outlet:u,matches:v,isDataRoute:a!=null},children:S})};return a&&(p.route.ErrorBoundary||p.route.errorElement||m===0)?k.createElement(NP,{location:a.location,revalidation:a.revalidation,component:y,error:h,children:w(),routeContext:{outlet:null,matches:v,isDataRoute:!0},onError:d}):w()},null)}function Y1(t){return`${t} must be used within a data router.  See https://reactrouter.com/en/main/routers/picking-a-router.`}function JV(t){let e=k.useContext(Fl);return Ke(e,Y1(t)),e}function QV(t){let e=k.useContext(tg);return Ke(e,Y1(t)),e}function XV(t){let e=k.useContext(zn);return Ke(e,Y1(t)),e}function Z1(t){let e=XV(t),a=e.matches[e.matches.length-1];return Ke(a.route.id,`${t} can only be used on routes that contain a unique "id"`),a.route.id}function YV(){return Z1("useRouteId")}function ZV(){var n;let t=k.useContext(X1),e=QV("useRouteError"),a=Z1("useRouteError");return t!==void 0?t:(n=e.errors)==null?void 0:n[a]}function e8(){let{router:t}=JV("useNavigate"),e=Z1("useNavigate"),a=k.useRef(!1);return CP(()=>{a.current=!0}),k.useCallback(async(i,r={})=>{Wa(a.current,EP),a.current&&(typeof i=="number"?await t.navigate(i):await t.navigate(i,{fromRouteId:e,...r}))},[t,e])}var Z_={};function IP(t,e,a){!e&&!Z_[t]&&(Z_[t]=!0,Wa(!1,a))}k.memo(t8);function t8({routes:t,future:e,state:a,onError:n}){return TP(t,void 0,a,n,e)}function ew({to:t,replace:e,state:a,relative:n}){Ke(Bl(),"<Navigate> may be used only in the context of a <Router> component.");let{static:i}=k.useContext(Ja);Wa(!i,"<Navigate> must not be used on the initial render in a <StaticRouter>. This is a no-op, but you should modify your code so the <Navigate> is only ever rendered in response to some user interaction or state change.");let{matches:r}=k.useContext(zn),{pathname:o}=fn(),l=Qa(),c=Q1(t,J1(r),o,n==="path"),d=JSON.stringify(c);return k.useEffect(()=>{l(JSON.parse(d),{replace:e,state:a,relative:n})},[l,d,n,e,a]),null}function le(t){Ke(!1,"A <Route> is only ever to be used as the child of <Routes> element, never rendered directly. Please wrap your <Route> in a <Routes>.")}function a8({basename:t="/",children:e=null,location:a,navigationType:n="POP",navigator:i,static:r=!1,unstable_useTransitions:o}){Ke(!Bl(),"You cannot render a <Router> inside another <Router>. You should never have more than one in your app.");let l=t.replace(/^\/*/,"/"),c=k.useMemo(()=>({basename:l,navigator:i,static:r,unstable_useTransitions:o,future:{}}),[l,i,r,o]);
51typeof a=="string"&&(a=Hl(a));let{pathname:d="/",search:u="",hash:p="",state:m=null,key:h="default"}=a,g=k.useMemo(()=>{let y=Di(d,l);return y==null?null:{location:{pathname:y,search:u,hash:p,state:m,key:h},navigationType:n}},[l,d,u,p,m,h,n]);return Wa(g!=null,`<Router basename="${l}"> is not able to match the URL "${d}${u}${p}" because it does not start with the basename, so the <Router> won't render anything.`),g==null?null:k.createElement(Ja.Provider,{value:c},k.createElement(Cu.Provider,{children:e,value:g}))}function n8({children:t,location:e}){return BV(yv(t),e)}function yv(t,e=[]){let a=[];return k.Children.forEach(t,(n,i)=>{if(!k.isValidElement(n))return;let r=[...e,i];if(n.type===k.Fragment){a.push.apply(a,yv(n.props.children,r));return}Ke(n.type===le,`[${typeof n.type=="string"?n.type:n.type.name}] is not a <Route> component. All component children of <Routes> must be a <Route> or <React.Fragment>`),Ke(!n.props.index||!n.props.children,"An index route cannot have child routes.");let o={id:n.props.id||r.join("-"),caseSensitive:n.props.caseSensitive,element:n.props.element,Component:n.props.Component,index:n.props.index,path:n.props.path,middleware:n.props.middleware,loader:n.props.loader,action:n.props.action,hydrateFallbackElement:n.props.hydrateFallbackElement,HydrateFallback:n.props.HydrateFallback,errorElement:n.props.errorElement,ErrorBoundary:n.props.ErrorBoundary,hasErrorBoundary:n.props.hasErrorBoundary===!0||n.props.ErrorBoundary!=null||n.props.errorElement!=null,shouldRevalidate:n.props.shouldRevalidate,handle:n.props.handle,lazy:n.props.lazy};n.props.children&&(o.children=yv(n.props.children,r)),a.push(o)}),a}var Am="get",Em="application/x-www-form-urlencoded";function ag(t){return typeof HTMLElement<"u"&&t instanceof HTMLElement}function i8(t){return ag(t)&&t.tagName.toLowerCase()==="button"}function r8(t){return ag(t)&&t.tagName.toLowerCase()==="form"}function o8(t){return ag(t)&&t.tagName.toLowerCase()==="input"}function s8(t){return!!(t.metaKey||t.altKey||t.ctrlKey||t.shiftKey)}function l8(t,e){return t.button===0&&(!e||e==="_self")&&!s8(t)}function xv(t=""){return new URLSearchParams(typeof t=="string"||Array.isArray(t)||t instanceof URLSearchParams?t:Object.keys(t).reduce((e,a)=>{let n=t[a];return e.concat(Array.isArray(n)?n.map(i=>[a,i]):[[a,n]])},[]))}function c8(t,e){let a=xv(t);return e&&e.forEach((n,i)=>{a.has(i)||e.getAll(i).forEach(r=>{a.append(i,r)})}),a}var Rp=null;function d8(){if(Rp===null)try{new FormData(document.createElement("form"),0),Rp=!1}catch{Rp=!0}return Rp}var u8=new Set(["application/x-www-form-urlencoded","multipart/form-data","text/plain"]);function e0(t){return t!=null&&!u8.has(t)?(Wa(!1,`"${t}" is not a valid \`encType\` for \`<Form>\`/\`<fetcher.Form>\` and will default to "${Em}"`),null):t}function p8(t,e){let a,n,i,r,o;if(r8(t)){let l=t.getAttribute("action");n=l?Di(l,e):null,a=t.getAttribute("method")||Am,i=e0(t.getAttribute("enctype"))||Em,r=new FormData(t)}else if(i8(t)||o8(t)&&(t.type==="submit"||t.type==="image")){let l=t.form;if(l==null)throw new Error('Cannot submit a <button> or <input type="submit"> without a <form>');let c=t.getAttribute("formaction")||l.getAttribute("action");if(n=c?Di(c,e):null,a=t.getAttribute("formmethod")||l.getAttribute("method")||Am,i=e0(t.getAttribute("formenctype"))||e0(l.getAttribute("enctype"))||Em,r=new FormData(l,t),!d8()){let{name:d,type:u,value:p}=t;if(u==="image"){let m=d?`${d}.`:"";r.append(`${m}x`,"0"),r.append(`${m}y`,"0")}else d&&r.append(d,p)}}else{if(ag(t))throw new Error('Cannot submit element that is not <form>, <button>, or <input type="submit|image">');a=Am,n=null,i=Em,o=t}return r&&i==="text/plain"&&(o=r,r=void 0),{action:n,method:a.toLowerCase(),encType:i,formData:r,body:o}}Object.getOwnPropertyNames(Object.prototype).sort().join("\0");function tw(t,e){if(t===!1||t===null||typeof t>"u")throw new Error(e)}function m8(t,e,a,n){let i=typeof t=="string"?new URL(t,typeof window>"u"?"server://singlefetch/":window.location.origin):t;return a?i.pathname.endsWith("/")?i.pathname=`${i.pathname}_.${n}`:i.pathname=`${i.pathname}.${n}`:i.pathname==="/"?i.pathname=`_root.${n}`:e&&Di(i.pathname,e)==="/"?i.pathname=`${e.replace(/\/$/,"")}/_root.${n}`:i.pathname=`${i.pathname.replace(/\/$/,"")}.${n}`,i}async function h8(t,e){if(t.id in e)return e[t.id];try{let a=await import(t.module);return e[t.id]=a,a}catch(a){return console.error(`Error loading route module \`${t.module}\`, reloading page...`),console.error(a),window.__reactRouterContext&&window.__reactRouterContext.
51isSpaMode,window.location.reload(),new Promise(()=>{})}}function f8(t){return t==null?!1:t.href==null?t.rel==="preload"&&typeof t.imageSrcSet=="string"&&typeof t.imageSizes=="string":typeof t.rel=="string"&&typeof t.href=="string"}async function g8(t,e,a){let n=await Promise.all(t.map(async i=>{let r=e.routes[i.route.id];if(r){let o=await h8(r,a);return o.links?o.links():[]}return[]}));return b8(n.flat(1).filter(f8).filter(i=>i.rel==="stylesheet"||i.rel==="preload").map(i=>i.rel==="stylesheet"?{...i,rel:"prefetch",as:"style"}:{...i,rel:"prefetch"}))}function eA(t,e,a,n,i,r){let o=(c,d)=>a[d]?c.route.id!==a[d].route.id:!0,l=(c,d)=>{var u;return a[d].pathname!==c.pathname||((u=a[d].route.path)==null?void 0:u.endsWith("*"))&&a[d].params["*"]!==c.params["*"]};return r==="assets"?e.filter((c,d)=>o(c,d)||l(c,d)):r==="data"?e.filter((c,d)=>{var p;let u=n.routes[c.route.id];if(!u||!u.hasLoader)return!1;if(o(c,d)||l(c,d))return!0;if(c.route.shouldRevalidate){let m=c.route.shouldRevalidate({currentUrl:new URL(i.pathname+i.search+i.hash,window.origin),currentParams:((p=a[0])==null?void 0:p.params)||{},nextUrl:new URL(t,window.origin),nextParams:c.params,defaultShouldRevalidate:!0});if(typeof m=="boolean")return m}return!0}):[]}function y8(t,e,{includeHydrateFallback:a}={}){return x8(t.map(n=>{let i=e.routes[n.route.id];if(!i)return[];let r=[i.module];return i.clientActionModule&&(r=r.concat(i.clientActionModule)),i.clientLoaderModule&&(r=r.concat(i.clientLoaderModule)),a&&i.hydrateFallbackModule&&(r=r.concat(i.hydrateFallbackModule)),i.imports&&(r=r.concat(i.imports)),r}).flat(1))}function x8(t){return[...new Set(t)]}function v8(t){let e={},a=Object.keys(t).sort();for(let n of a)e[n]=t[n];return e}function b8(t,e){let a=new Set;return new Set(e),t.reduce((n,i)=>{let r=JSON.stringify(v8(i));return a.has(r)||(a.add(r),n.push({key:r,link:i})),n},[])}function PP(){let t=k.useContext(Fl);return tw(t,"You must render this element inside a <DataRouterContext.Provider> element"),t}function w8(){let t=k.useContext(tg);return tw(t,"You must render this element inside a <DataRouterStateContext.Provider> element"),t}var aw=k.createContext(void 0);aw.displayName="FrameworkContext";function RP(){let t=k.useContext(aw);return tw(t,"You must render this element inside a <HydratedRouter> element"),t}function k8(t,e){let a=k.useContext(aw),[n,i]=k.useState(!1),[r,o]=k.useState(!1),{onFocus:l,onBlur:c,onMouseEnter:d,onMouseLeave:u,onTouchStart:p}=e,m=k.useRef(null);k.useEffect(()=>{if(t==="render"&&o(!0),t==="viewport"){let y=v=>{v.forEach(w=>{o(w.isIntersecting)})},x=new IntersectionObserver(y,{threshold:.5});return m.current&&x.observe(m.current),()=>{x.disconnect()}}},[t]),k.useEffect(()=>{if(n){let y=setTimeout(()=>{o(!0)},100);return()=>{clearTimeout(y)}}},[n]);let h=()=>{i(!0)},g=()=>{i(!1),o(!1)};return a?t!=="intent"?[r,m,{}]:[r,m,{onFocus:_c(l,h),onBlur:_c(c,g),onMouseEnter:_c(d,h),onMouseLeave:_c(u,g),onTouchStart:_c(p,h)}]:[!1,m,{}]}function _c(t,e){return a=>{t&&t(a),a.defaultPrevented||e(a)}}function S8({page:t,...e}){let{router:a}=PP(),n=k.useMemo(()=>yP(a.routes,t,a.basename),[a.routes,t,a.basename]);return n?k.createElement(A8,{page:t,matches:n,...e}):null}function _8(t){let{manifest:e,routeModules:a}=RP(),[n,i]=k.useState([]);return k.useEffect(()=>{let r=!1;return g8(t,e,a).then(o=>{r||i(o)}),()=>{r=!0}},[t,e,a]),n}function A8({page:t,matches:e,...a}){let n=fn(),{future:i,manifest:r,routeModules:o}=RP(),{basename:l}=PP(),{loaderData:c,matches:d}=w8(),u=k.useMemo(()=>eA(t,e,d,r,n,"data"),[t,e,d,r,n]),p=k.useMemo(()=>eA(t,e,d,r,n,"assets"),[t,e,d,r,n]),m=k.useMemo(()=>{if(t===n.pathname+n.search+n.hash)return[];let y=new Set,x=!1;if(e.forEach(w=>{var T;let S=r.routes[w.route.id];!S||!S.hasLoader||(!u.some(P=>P.route.id===w.route.id)&&w.route.id in c&&((T=o[w.route.id])!=null&&T.shouldRevalidate)||S.hasClientLoader?x=!0:y.add(w.route.id))}),y.size===0)return[];let v=m8(t,l,i.unstable_trailingSlashAwareDataRequests,"data");return x&&y.size>0&&v.searchParams.set("_routes",e.filter(w=>y.has(w.route.id)).map(w=>w.route.id).join(",")),[v.pathname+v.search]},[l,i.unstable_trailingSlashAwareDataRequests,c,n,r,u,e,t,o]),h=k.useMemo(()=>y8(p,r),[p,r]),g=_8(p);return k.createElement(k.Fragment,null,m.map(y=>k.createElement("link",{key:y,rel:"prefetch",as:"fetch",href:y,...a})),h.map(y=>k.createElement("link",{key:y,rel:"modulepreload",href:y,...a})),g.map(({key:y,link:x})=>k.createElement("link",{key:y,nonce:a.nonce,...x})))}function E8(...t){return e=>{t.forEach(a=>{typeof a=="function"?a(e):a!=null&&(a.current=e)})}}var C8=typeof window<"u"&&typeof window.document<"u"&&typeof window.document.createElement<"u";try{C8&&(window.__reactRouterVersion="7.12.0")}catch{}function j8({basename:t,children:e,unstable_useTransitions:a,window:n}){let i=k.useRef();i.current==null&&(i.current=sV({window:n,v5Compat:!0}));let r=i.current,[o,l]=k.useState({action:r.action,location:r.location}),c=k.useCallback(d=>{a===!1?l(d):k.startTransition(()=>l(d))},[a]);return k.useLayoutEffect(()=>r.listen(c),[r,c]),k.createElement(a8,{basename:t,children:e,location:o.location,navigationType:o.action,navigator:r,unstable_useTransitions:a})}var LP=/^(?:[a-z][a-z0-9+.-]*:|\/\/)/i,Te=k.forwardRef(function({onClick:e,discover:a="render",prefetch:n="none",relative:i,reloadDocument:r,replace:o,state:l,target:c,to:d,preventScrollReset:u,viewTransition:p,unstable_defaultShouldRevalidate:m,...h},g){let{basename:y,unstable_useTransitions:x}
51=k.useContext(Ja),v=typeof d=="string"&&LP.test(d),w=kP(d,y);d=w.to;let S=HV(d,{relative:i}),[T,P,M]=k8(n,h),C=P8(d,{replace:o,state:l,target:c,preventScrollReset:u,relative:i,viewTransition:p,unstable_defaultShouldRevalidate:m,unstable_useTransitions:x});function E(N){e&&e(N),N.defaultPrevented||C(N)}let j=k.createElement("a",{...h,...M,href:w.absoluteURL||S,onClick:w.isExternal||r?e:E,ref:E8(g,P),target:c,"data-discover":!v&&a==="render"?"true":void 0});return T&&!v?k.createElement(k.Fragment,null,j,k.createElement(S8,{page:S})):j});Te.displayName="Link";var T8=k.forwardRef(function({"aria-current":e="page",caseSensitive:a=!1,className:n="",end:i=!1,style:r,to:o,viewTransition:l,children:c,...d},u){let p=ju(o,{relative:d.relative}),m=fn(),h=k.useContext(tg),{navigator:g,basename:y}=k.useContext(Ja),x=h!=null&&q8(p)&&l===!0,v=g.encodeLocation?g.encodeLocation(p).pathname:p.pathname,w=m.pathname,S=h&&h.navigation&&h.navigation.location?h.navigation.location.pathname:null;a||(w=w.toLowerCase(),S=S?S.toLowerCase():null,v=v.toLowerCase()),S&&y&&(S=Di(S,y)||S);const T=v!=="/"&&v.endsWith("/")?v.length-1:v.length;let P=w===v||!i&&w.startsWith(v)&&w.charAt(T)==="/",M=S!=null&&(S===v||!i&&S.startsWith(v)&&S.charAt(v.length)==="/"),C={isActive:P,isPending:M,isTransitioning:x},E=P?e:void 0,j;typeof n=="function"?j=n(C):j=[n,P?"active":null,M?"pending":null,x?"transitioning":null].filter(Boolean).join(" ");let N=typeof r=="function"?r(C):r;return k.createElement(Te,{...d,"aria-current":E,className:j,ref:u,style:N,to:o,viewTransition:l},typeof c=="function"?c(C):c)});T8.displayName="NavLink";var N8=k.forwardRef(({discover:t="render",fetcherKey:e,navigate:a,reloadDocument:n,replace:i,state:r,method:o=Am,action:l,onSubmit:c,relative:d,preventScrollReset:u,viewTransition:p,unstable_defaultShouldRevalidate:m,...h},g)=>{let{unstable_useTransitions:y}=k.useContext(Ja),x=M8(),v=D8(l,{relative:d}),w=o.toLowerCase()==="get"?"get":"post",S=typeof l=="string"&&LP.test(l),T=P=>{if(c&&c(P),P.defaultPrevented)return;P.preventDefault();let M=P.nativeEvent.submitter,C=(M==null?void 0:M.getAttribute("formmethod"))||o,E=()=>x(M||P.currentTarget,{fetcherKey:e,method:C,navigate:a,replace:i,state:r,relative:d,preventScrollReset:u,viewTransition:p,unstable_defaultShouldRevalidate:m});y&&a!==!1?k.startTransition(()=>E()):E()};return k.createElement("form",{ref:g,method:w,action:v,onSubmit:n?c:T,...h,"data-discover":!S&&t==="render"?"true":void 0})});N8.displayName="Form";function I8(t){return`${t} must be used within a data router.  See https://reactrouter.com/en/main/routers/picking-a-router.`}function OP(t){let e=k.useContext(Fl);return Ke(e,I8(t)),e}function P8(t,{target:e,replace:a,state:n,preventScrollReset:i,relative:r,viewTransition:o,unstable_defaultShouldRevalidate:l,unstable_useTransitions:c}={}){let d=Qa(),u=fn(),p=ju(t,{relative:r});return k.useCallback(m=>{if(l8(m,e)){m.preventDefault();let h=a!==void 0?a:Gd(u)===Gd(p),g=()=>d(t,{replace:h,state:n,preventScrollReset:i,relative:r,viewTransition:o,unstable_defaultShouldRevalidate:l});c?k.startTransition(()=>g()):g()}},[u,d,p,a,n,e,t,i,r,o,l,c])}function R8(t){Wa(typeof URLSearchParams<"u","You cannot use the `useSearchParams` hook in a browser that does not support the URLSearchParams API. If you need to support Internet Explorer 11, we recommend you load a polyfill such as https://github.com/ungap/url-search-params.");let e=k.useRef(xv(t)),a=k.useRef(!1),n=fn(),i=k.useMemo(()=>c8(n.search,a.current?null:e.current),[n.search]),r=Qa(),o=k.useCallback((l,c)=>{const d=xv(typeof l=="function"?l(new URLSearchParams(i)):l);a.current=!0,r("?"+d,c)},[r,i]);return[i,o]}var L8=0,O8=()=>`__${String(++L8)}__`;function M8(){let{router:t}=OP("useSubmit"),{basename:e}=k.useContext(Ja),a=YV(),n=t.fetch,i=t.navigate;return k.useCallback(async(r,o={})=>{let{action:l,method:c,encType:d,formData:u,body:p}=p8(r,e);if(o.navigate===!1){let m=o.fetcherKey||O8();await n(m,a,o.action||l,{unstable_defaultShouldRevalidate:o.unstable_defaultShouldRevalidate,preventScrollReset:o.preventScrollReset,formData:u,body:p,formMethod:o.method||c,formEncType:o.encType||d,flushSync:o.flushSync})}else await i(o.action||l,{unstable_defaultShouldRevalidate:o.unstable_defaultShouldRevalidate,preventScrollReset:o.preventScrollReset,formData:u,body:p,formMethod:o.method||c,formEncType:o.encType||d,replace:o.replace,state:o.state,fromRouteId:a,flushSync:o.flushSync,viewTransition:o.viewTransition})},[n,i,e,a])}function D8(t,{relative:e}={}){let{basename:a}=k.useContext(Ja),n=k.useContext(zn);Ke(n,"useFormAction must be used inside a RouteContext");let[i]=n.matches.slice(-1),r={...ju(t||".",{relative:e})},o=fn();if(t==null){r.search=o.search;
51let l=new URLSearchParams(r.search),c=l.getAll("index");if(c.some(u=>u==="")){l.delete("index"),c.filter(p=>p).forEach(p=>l.append("index",p));let u=l.toString();r.search=u?`?${u}`:""}}return(!t||t===".")&&i.route.index&&(r.search=r.search?r.search.replace(/^\?/,"?index&"):"?index"),a!=="/"&&(r.pathname=r.pathname==="/"?a:Ci([a,r.pathname])),Gd(r)}function q8(t,{relative:e}={}){let a=k.useContext(_P);Ke(a!=null,"`useViewTransitionState` must be used within `react-router-dom`'s `RouterProvider`.  Did you accidentally import `RouterProvider` from `react-router`?");let{basename:n}=OP("useViewTransitionState"),i=ju(t,{relative:e});if(!a.isTransitioning)return!1;let r=Di(a.currentLocation.pathname,n)||a.currentLocation.pathname,o=Di(a.nextLocation.pathname,n)||a.nextLocation.pathname;return xh(i.pathname,o)!=null||xh(i.pathname,r)!=null}const MP=k.createContext();function z8({children:t}){const[e,a]=k.useState(!1),[n,i]=k.useState("Contáctanos"),r=(l="Contáctanos")=>{i(l),a(!0)},o=()=>{a(!1)};return s.jsx(MP.Provider,{value:{isOpen:e,modalTitle:n,openModal:r,closeModal:o},children:t})}function oa(){const t=k.useContext(MP);if(!t)throw new Error("useContactModal debe ser usado dentro de ContactModalProvider");return t}const de=t=>typeof t=="string",Ac=()=>{let t,e;const a=new Promise((n,i)=>{t=n,e=i});return a.resolve=t,a.reject=e,a},tA=t=>t==null?"":""+t,V8=(t,e,a)=>{t.forEach(n=>{e[n]&&(a[n]=e[n])})},H8=/###/g,aA=t=>t&&t.indexOf("###")>-1?t.replace(H8,"."):t,nA=t=>!t||de(t),id=(t,e,a)=>{const n=de(e)?e.split("."):e;let i=0;for(;i<n.length-1;){if(nA(t))return{};const r=aA(n[i]);!t[r]&&a&&(t[r]=new a),Object.prototype.hasOwnProperty.call(t,r)?t=t[r]:t={},++i}return nA(t)?{}:{obj:t,k:aA(n[i])}},iA=(t,e,a)=>{const{obj:n,k:i}=id(t,e,Object);if(n!==void 0||e.length===1){n[i]=a;return}let r=e[e.length-1],o=e.slice(0,e.length-1),l=id(t,o,Object);for(;l.obj===void 0&&o.length;)r=`${o[o.length-1]}.${r}`,o=o.slice(0,o.length-1),l=id(t,o,Object),l!=null&&l.obj&&typeof l.obj[`${l.k}.${r}`]<"u"&&(l.obj=void 0);l.obj[`${l.k}.${r}`]=a},F8=(t,e,a,n)=>{const{obj:i,k:r}=id(t,e,Object);i[r]=i[r]||[],i[r].push(a)},vh=(t,e)=>{const{obj:a,k:n}=id(t,e);if(a&&Object.prototype.hasOwnProperty.call(a,n))return a[n]},B8=(t,e,a)=>{const n=vh(t,a);return n!==void 0?n:vh(e,a)},DP=(t,e,a)=>{for(const n in e)n!=="__proto__"&&n!=="constructor"&&(n in t?de(t[n])||t[n]instanceof String||de(e[n])||e[n]instanceof String?a&&(t[n]=e[n]):DP(t[n],e[n],a):t[n]=e[n]);return t},Ss=t=>t.replace(/[\-\[\]\/\{\}\(\)\*\+\?\.\\\^\$\|]/g,"\\$&");var U8={"&":"&amp;","<":"&lt;",">":"&gt;",'"':"&quot;","'":"&#39;","/":"&#x2F;"};const $8=t=>de(t)?t.replace(/[&<>"'\/]/g,e=>U8[e]):t;class W8{constructor(e){this.capacity=e,this.regExpMap=new Map,this.regExpQueue=[]}getRegExp(e){const a=this.regExpMap.get(e);if(a!==void 0)return a;const n=new RegExp(e);return this.regExpQueue.length===this.capacity&&this.regExpMap.delete(this.regExpQueue.shift()),this.regExpMap.set(e,n),this.regExpQueue.push(e),n}}const G8=[" ",",","?","!",";"],K8=new W8(20),J8=(t,e,a)=>{e=e||"",a=a||"";const n=G8.filter(o=>e.indexOf(o)<0&&a.indexOf(o)<0);if(n.length===0)return!0;const i=K8.getRegExp(`(${n.map(o=>o==="?"?"\\?":o).join("|")})`);let r=!i.test(t);if(!r){const o=t.indexOf(a);o>0&&!i.test(t.substring(0,o))&&(r=!0)}return r},vv=(t,e,a=".")=>{if(!t)return;if(t[e])return Object.prototype.hasOwnProperty.call(t,e)?t[e]:void 0;const n=e.split(a);let i=t;for(let r=0;r<n.length;){if(!i||typeof i!="object")return;let o,l="";for(let c=r;c<n.length;++c)if(c!==r&&(l+=a),l+=n[c],o=i[l],o!==void 0){if(["string","number","boolean"].indexOf(typeof o)>-1&&c<n.length-1)continue;r+=c-r+1;break}i=o}return i},Kd=t=>t==null?void 0:t.replace("_","-"),Q8={type:"logger",log(t){this.output("log",t)},warn(t){this.output("warn",t)},error(t){this.output("error",t)},output(t,e){var a,n;(n=(a=console==null?void 0:console[t])==null?void 0:a.apply)==null||n.call(a,console,e)}};let X8=class bv{constructor(e,a={}){this.init(e,a)}init(e,a={}){this.prefix=a.prefix||"i18next:",this.logger=e||Q8,this.options=a,this.debug=a.debug}log(...e){return this.forward(e,"log","",!0)}warn(...e){return this.forward(e,"warn","",!0)}error(...e){return this.forward(e,"error","")}deprecate(...e){return this.forward(e,"warn","WARNING DEPRECATED: ",!0)}forward(e,a,n,i){return i&&!this.debug?null:(de(e[0])&&(e[0]=`${n}${this.prefix} ${e[0]}`),this.logger[a](e))}create(e){return new bv(this.logger,{prefix:`${this.prefix}:${e}:`,...this.options})}clone(e){return e=e||this.options,e.prefix=e.prefix||this.prefix,new bv(this.logger,e)}};var Jn=new X8;let ng=class{constructor(){this.observers={}}on(e,a){return e.split(" ").forEach(n=>{this.observers[n]||(this.observers[n]=new Map);const i=this.observers[n].get(a)||0;this.observers[n].set(a,i+1)}),this}
vendor: 1,390 bytes, line 51
51off(e,a){if(this.observers[e]){if(!a){delete this.observers[e];return}this.observers[e].delete(a)}}emit(e,...a){this.observers[e]&&Array.from(this.observers[e].entries()).forEach(([i,r])=>{for(let o=0;o<r;o++)i(...a)}),this.observers["*"]&&Array.from(this.observers["*"].entries()).forEach(([i,r])=>{for(let o=0;o<r;o++)i.apply(i,[e,...a])})}};class rA extends ng{constructor(e,a={ns:["translation"],defaultNS:"translation"}){super(),this.data=e||{},this.options=a,this.options.keySeparator===void 0&&(this.options.keySeparator="."),this.options.ignoreJSONStructure===void 0&&(this.options.ignoreJSONStructure=!0)}addNamespaces(e){this.options.ns.indexOf(e)<0&&this.options.ns.push(e)}removeNamespaces(e){const a=this.options.ns.indexOf(e);a>-1&&this.options.ns.splice(a,1)}getResource(e,a,n,i={}){var d,u;const r=i.keySeparator!==void 0?i.keySeparator:this.options.keySeparator,o=i.ignoreJSONStructure!==void 0?i.ignoreJSONStructure:this.options.ignoreJSONStructure;let l;e.indexOf(".")>-1?l=e.split("."):(l=[e,a],n&&(Array.isArray(n)?l.push(...n):de(n)&&r?l.push(...n.split(r)):l.push(n)));const c=vh(this.data,l);return!c&&!a&&!n&&e.indexOf(".")>-1&&(e=l[0],a=l[1],n=l.slice(2).join(".")),c||!o||!de(n)?c:vv((u=(d=this.data)==null?void 0:d[e])==null?void 0:u[a],n,r)}addResource(e,a,n,i,r={silent:!1}){const o=r.keySeparator!==void 0?r.keySeparator:this.options.keySeparator;let l=[e,a];
vendor: 1,825 bytes, line 51
51n&&(l=l.concat(o?n.split(o):n)),e.indexOf(".")>-1&&(l=e.split("."),i=a,a=l[1]),this.addNamespaces(a),iA(this.data,l,i),r.silent||this.emit("added",e,a,n,i)}addResources(e,a,n,i={silent:!1}){for(const r in n)(de(n[r])||Array.isArray(n[r]))&&this.addResource(e,a,r,n[r],{silent:!0});i.silent||this.emit("added",e,a,n)}addResourceBundle(e,a,n,i,r,o={silent:!1,skipCopy:!1}){let l=[e,a];e.indexOf(".")>-1&&(l=e.split("."),i=n,n=a,a=l[1]),this.addNamespaces(a);let c=vh(this.data,l)||{};o.skipCopy||(n=JSON.parse(JSON.stringify(n))),i?DP(c,n,r):c={...c,...n},iA(this.data,l,c),o.silent||this.emit("added",e,a,n)}removeResourceBundle(e,a){this.hasResourceBundle(e,a)&&delete this.data[e][a],this.removeNamespaces(a),this.emit("removed",e,a)}hasResourceBundle(e,a){return this.getResource(e,a)!==void 0}getResourceBundle(e,a){return a||(a=this.options.defaultNS),this.getResource(e,a)}getDataByLanguage(e){return this.data[e]}hasLanguageSomeTranslations(e){const a=this.getDataByLanguage(e);return!!(a&&Object.keys(a)||[]).find(i=>a[i]&&Object.keys(a[i]).length>0)}toJSON(){return this.data}}var qP={processors:{},addPostProcessor(t){this.processors[t.name]=t},handle(t,e,a,n,i){return t.forEach(r=>{var o;e=((o=this.processors[r])==null?void 0:o.process(e,a,n,i))??e}),e}};const zP=Symbol("i18next/PATH_KEY");function Y8(){const t=[],e=Object.create(null);let a;return e.get=(n,i)=>{var r;return(r=a==null?void 0:a.revoke)==null||r.call(a),i===zP?t:(t.push(i),a=Proxy.revocable(n,e),a.proxy)},Proxy.revocable(Object.create(null),e).proxy}function wv(t,e){const{[zP]:a}=t(Y8());return a.join((e==null?void 0:e.keySeparator)??".")}const oA={},t0=t=>!de(t)&&typeof t!="boolean"&&typeof t!="number";class bh extends ng{constructor(e,a={}){super(),V8(["resourceStore","languageUtils","pluralResolver","interpolator","backendConnector","
51i18nFormat","utils"],e,this),this.options=a,this.options.keySeparator===void 0&&(this.options.keySeparator="."),this.logger=Jn.create("translator")}changeLanguage(e){e&&(this.language=e)}exists(e,a={interpolation:{}}){const n={...a};if(e==null)return!1;const i=this.resolve(e,n);if((i==null?void 0:i.res)===void 0)return!1;const r=t0(i.res);return!(n.returnObjects===!1&&r)}extractFromKey(e,a){let n=a.nsSeparator!==void 0?a.nsSeparator:this.options.nsSeparator;n===void 0&&(n=":");const i=a.keySeparator!==void 0?a.keySeparator:this.options.keySeparator;let r=a.ns||this.options.defaultNS||[];const o=n&&e.indexOf(n)>-1,l=!this.options.userDefinedKeySeparator&&!a.keySeparator&&!this.options.userDefinedNsSeparator&&!a.nsSeparator&&!J8(e,n,i);if(o&&!l){const c=e.match(this.interpolator.nestingRegexp);if(c&&c.length>0)return{key:e,namespaces:de(r)?[r]:r};const d=e.split(n);(n!==i||n===i&&this.options.ns.indexOf(d[0])>-1)&&(r=d.shift()),e=d.join(i)}return{key:e,namespaces:de(r)?[r]:r}}translate(e,a,n){let i=typeof a=="object"?{...a}:a;if(typeof i!="object"&&this.options.overloadTranslationOptionHandler&&(i=this.options.overloadTranslationOptionHandler(arguments)),typeof i=="object"&&(i={...i}),i||(i={}),e==null)return"";typeof e=="function"&&(e=wv(e,{...this.options,...i})),Array.isArray(e)||(e=[String(e)]);const r=i.returnDetails!==void 0?i.returnDetails:this.options.returnDetails,o=i.keySeparator!==void 0?i.keySeparator:this.options.keySeparator,{key:l,namespaces:c}=this.extractFromKey(e[e.length-1],i),d=c[c.length-1];let u=i.nsSeparator!==void 0?i.nsSeparator:this.options.nsSeparator;u===void 0&&(u=":");const p=i.lng||this.language,m=i.appendNamespaceToCIMode||this.options.appendNamespaceToCIMode;if((p==null?void 0:p.toLowerCase())==="cimode")return m?r?{res:`${d}${u}${l}`,usedKey:l,exactUsedKey:l,usedLng:p,usedNS:d,usedParams:this.getUsedParamsDetails(i)}:`${d}${u}${l}`:r?{res:l,usedKey:l,exactUsedKey:l,usedLng:p,usedNS:d,usedParams:this.getUsedParamsDetails(i)}:l;const h=this.resolve(e,i);let g=h==null?void 0:h.res;const y=(h==null?void 0:h.usedKey)||l,x=(h==null?void 0:h.exactUsedKey)||l,v=["[object Number]","[object Function]","[object RegExp]"],w=i.joinArrays!==void 0?i.joinArrays:this.options.joinArrays,S=!this.i18nFormat||this.i18nFormat.handleAsObject,T=i.count!==void 0&&!de(i.count),P=bh.hasDefaultValue(i),M=T?this.pluralResolver.getSuffix(p,i.count,i):"",C=i.ordinal&&T?this.pluralResolver.getSuffix(p,i.count,{ordinal:!1}):"",E=T&&!i.ordinal&&i.count===0,j=E&&i[`defaultValue${this.options.pluralSeparator}zero`]||i[`defaultValue${M}`]||i[`defaultValue${C}`]||i.defaultValue;let N=g;S&&!g&&P&&(N=j);const L=t0(N),O=Object.prototype.toString.apply(N);if(S&&N&&L&&v.indexOf(O)<0&&!(de(w)&&Array.isArray(N))){if(!i.returnObjects&&!this.options.returnObjects){this.options.returnedObjectHandler||this.logger.warn("accessing an object - but returnObjects options is not enabled!");const R=this.options.returnedObjectHandler?this.options.returnedObjectHandler(y,N,{...i,ns:c}):`key '${l} (${this.language})' returned an object instead of string.`;return r?(h.res=R,h.usedParams=this.getUsedParamsDetails(i),h):R}if(o){const R=Array.isArray(N),G=R?[]:{},ee=R?x:y;for(const ke in N)if(Object.prototype.hasOwnProperty.call(N,ke)){const ae=`${ee}${o}${ke}`;P&&!g?G[ke]=this.translate(ae,{...i,defaultValue:t0(j)?j[ke]:void 0,joinArrays:!1,ns:c}):G[ke]=this.translate(ae,{...i,joinArrays:!1,ns:c}),G[ke]===ae&&(G[ke]=N[ke])}g=G}}else if(S&&de(w)&&Array.isArray(g))g=g.join(w),g&&(g=this.extendTranslation(g,e,i,n));else{let R=!1,G=!1;!this.isValidLookup(g)&&P&&(R=!0,g=j),this.isValidLookup(g)||(G=!0,g=l);const ke=(i.missingKeyNoValueFallbackToKey||this.options.missingKeyNoValueFallbackToKey)&&G?void 0:g,ae=P&&j!==g&&this.options.updateMissing;if(G||R||ae){if(this.logger.log(ae?"updateKey":"missingKey",p,d,l,ae?j:g),o){const fe=this.resolve(l,{...i,keySeparator:!1});fe&&fe.res&&this.logger.warn("Seems the loaded translations were in flat JSON format instead of nested. Either set keySeparator: false on init or make sure your translations are published in nested format.")}let F=[];const Z=this.languageUtils.getFallbackCodes(this.options.fallbackLng,i.lng||this.language);if(this.options.saveMissingTo==="fallback"&&Z&&Z[0])for(let fe=0;fe<Z.length;fe++)F.push(Z[fe]);else this.options.saveMissingTo==="all"?F=this.languageUtils.toResolveHierarchy(i.lng||this.language):F.push(i.lng||this.language);const re=(fe,ve,Ie)=>{var ge;const ne=P&&Ie!==g?Ie:ke;this.options.missingKeyHandler?this.options.missingKeyHandler(fe,d,ve,ne,ae,i):(ge=this.backendConnector)!=null&&ge.saveMissing&&this.backendConnector.saveMissing(fe,d,ve,ne,ae,i),this.emit
vendor: 28,450 bytes, line 51
51("missingKey",fe,d,ve,g)};this.options.saveMissing&&(this.options.saveMissingPlurals&&T?F.forEach(fe=>{const ve=this.pluralResolver.getSuffixes(fe,i);E&&i[`defaultValue${this.options.pluralSeparator}zero`]&&ve.indexOf(`${this.options.pluralSeparator}zero`)<0&&ve.push(`${this.options.pluralSeparator}zero`),ve.forEach(Ie=>{re([fe],l+Ie,i[`defaultValue${Ie}`]||j)})}):re(F,l,j))}g=this.extendTranslation(g,e,i,h,n),G&&g===l&&this.options.appendNamespaceToMissingKey&&(g=`${d}${u}${l}`),(G||R)&&this.options.parseMissingKeyHandler&&(g=this.options.parseMissingKeyHandler(this.options.appendNamespaceToMissingKey?`${d}${u}${l}`:l,R?g:void 0,i))}return r?(h.res=g,h.usedParams=this.getUsedParamsDetails(i),h):g}extendTranslation(e,a,n,i,r){var c,d;if((c=this.i18nFormat)!=null&&c.parse)e=this.i18nFormat.parse(e,{...this.options.interpolation.defaultVariables,...n},n.lng||this.language||i.usedLng,i.usedNS,i.usedKey,{resolved:i});else if(!n.skipInterpolation){n.interpolation&&this.interpolator.init({...n,interpolation:{...this.options.interpolation,...n.interpolation}});const u=de(e)&&(((d=n==null?void 0:n.interpolation)==null?void 0:d.skipOnVariables)!==void 0?n.interpolation.skipOnVariables:this.options.interpolation.skipOnVariables);let p;if(u){const h=e.match(this.interpolator.nestingRegexp);p=h&&h.length}let m=n.replace&&!de(n.replace)?n.replace:n;if(this.options.interpolation.defaultVariables&&(m={...this.options.interpolation.defaultVariables,...m}),e=this.interpolator.interpolate(e,m,n.lng||this.language||i.usedLng,n),u){const h=e.match(this.interpolator.nestingRegexp),g=h&&h.length;p<g&&(n.nest=!1)}!n.lng&&i&&i.res&&(n.lng=this.language||i.usedLng),n.nest!==!1&&(e=this.interpolator.nest(e,(...h)=>(r==null?void 0:r[0])===h[0]&&!n.context?(this.logger.warn(`It seems you are nesting recursively key: ${h[0]} in key: ${a[0]}`),null):this.translate(...h,a),n)),n.interpolation&&this.interpolator.reset()}const o=n.postProcess||this.options.postProcess,l=de(o)?[o]:o;return e!=null&&(l!=null&&l.length)&&n.applyPostProcessor!==!1&&(e=qP.handle(l,e,a,this.options&&this.options.postProcessPassResolved?{i18nResolved:{...i,usedParams:this.getUsedParamsDetails(n)},...n}:n,this)),e}resolve(e,a={}){let n,i,r,o,l;return de(e)&&(e=[e]),e.forEach(c=>{if(this.isValidLookup(n))return;const d=this.extractFromKey(c,a),u=d.key;i=u;let p=d.namespaces;this.options.fallbackNS&&(p=p.concat(this.options.fallbackNS));const m=a.count!==void 0&&!de(a.count),h=m&&!a.ordinal&&a.count===0,g=a.context!==void 0&&(de(a.context)||typeof a.context=="number")&&a.context!=="",y=a.lngs?a.lngs:this.languageUtils.toResolveHierarchy(a.lng||this.language,a.fallbackLng);p.forEach(x=>{var v,w;this.isValidLookup(n)||(l=x,!oA[`${y[0]}-${x}`]&&((v=this.utils)!=null&&v.hasLoadedNamespace)&&!((w=this.utils)!=null&&w.hasLoadedNamespace(l))&&(oA[`${y[0]}-${x}`]=!0,this.logger.warn(`key "${i}" for languages "${y.join(", ")}" won't get resolved as namespace "${l}" was not yet loaded`,"This means something IS WRONG in your setup. You access the t function before i18next.init / i18next.loadNamespace / i18next.changeLanguage was done. Wait for the callback or Promise to resolve before accessing it!!!")),y.forEach(S=>{var M;if(this.isValidLookup(n))return;o=S;const T=[u];if((M=this.i18nFormat)!=null&&M.addLookupKeys)this.i18nFormat.addLookupKeys(T,u,S,x,a);else{let C;m&&(C=this.pluralResolver.getSuffix(S,a.count,a));const E=`${this.options.pluralSeparator}zero`,j=`${this.options.pluralSeparator}ordinal${this.options.pluralSeparator}`;if(m&&(a.ordinal&&C.indexOf(j)===0&&T.push(u+C.replace(j,this.options.pluralSeparator)),T.push(u+C),h&&T.push(u+E)),g){const N=`${u}${this.options.contextSeparator||"_"}${a.context}`;T.push(N),m&&(a.ordinal&&C.indexOf(j)===0&&T.push(N+C.replace(j,this.options.pluralSeparator)),T.push(N+C),h&&T.push(N+E))}}let P;for(;P=T.pop();)this.isValidLookup(n)||(r=P,n=this.getResource(S,x,P,a))}))})}),{res:n,usedKey:i,exactUsedKey:r,usedLng:o,usedNS:l}}isValidLookup(e){return e!==void 0&&!(!this.options.returnNull&&e===null)&&!(!this.options.returnEmptyString&&e==="")}getResource(e,a,n,i={}){var r;return(r=this.i18nFormat)!=null&&r.getResource?this.i18nFormat.getResource(e,a,n,i):this.resourceStore.getResource(e,a,n,i)}getUsedParamsDetails(e={}){const a=["defaultValue","ordinal","context","replace","lng","lngs","fallbackLng","ns","keySeparator","nsSeparator","returnObjects","returnDetails","joinArrays","postProcess","interpolation"],n=e.replace&&!de(e.replace);let i=n?e.replace:e;if(n&&typeof e.count<"u"&&(i.count=e.count),this.options.interpolation.defaultVariables&&(i={...this.options.interpolation.defaultVariables,...i}),!n){i={...i};for(const r of a)delete i[r]}return i}static hasDefaultValue(e){const a="defaultValue";for(const n in e)if(Object.prototype.hasOwnProperty.call(e,n)&&a===n.substring(0,a.length)&&e[n]!==void 0)return!0;return!1}}class sA{constructor(e){this.options=e,this.supportedLngs=this.options.supportedLngs||!1,this.logger=Jn.create("languageUtils")}getScriptPartFromCode(e){if(e=Kd(e),!e||e.indexOf("-")<0)return null;const a=e.split("-");return a.length===2||(a.pop(),a[a.length-1].toLowerCase()==="x")?null:this.formatLanguageCode(a.join("-"))}getLanguagePartFromCode(e){if(e=Kd(e),!e||e.indexOf("-")<0)return e;const a=e.split("-");return this.formatLanguageCode(a[0])}formatLanguageCode(e){if(de(e)&&e.indexOf("-")>-1){let a;try{a=Intl.getCanonicalLocales(e)[0]}catch{}return a&&this.options.lowerCaseLng&&(a=a.toLowerCase()),a||(this.options.lowerCaseLng?e.toLowerCase():e)}return this.options.cleanCode||this.options.lowerCaseLng?e.toLowerCase():e}isSupportedCode(e){return(this.options.load==="languageOnly"||this.options.nonExplicitSupportedLngs)&&(e=this.getLanguagePartFromCode(e)),!this.supportedLngs||!this.supportedLngs.length||this.supportedLngs.indexOf(e)>-1}getBestMatchFromCodes(e){if(!e)return null;let a;return e.forEach(n=>{if(a)return;const i=this.formatLanguageCode(n);(!this.options.supportedLngs||this.isSupportedCode(i))&&(a=i)}),!a&&this.options.supportedLngs&&e.forEach(n=>{if(a)return;const i=this.getScriptPartFromCode(n);if(this.isSupportedCode(i))return a=i;const r=this.getLanguagePartFromCode(n);if(this.isSupportedCode(r))return a=r;a=this.options.supportedLngs.find(o=>{if(o===r)return o;if(!(o.indexOf("-")<0&&r.indexOf("-")<0)&&(o.indexOf("-")>0&&r.indexOf("-")<0&&o.substring(0,o.indexOf("-"))===r||o.indexOf(r)===0&&r.length>1))return o})}),a||(a=this.getFallbackCodes(this.options.fallbackLng)[0]),a}getFallbackCodes(e,a){if(!e)return[];if(typeof e=="function"&&(e=e(a)),de(e)&&(e=[e]),Array.isArray(e))return e;if(!a)return e.default||[];let n=e[a];return n||(n=e[this.getScriptPartFromCode(a)]),n||(n=e[this.formatLanguageCode(a)]),n||(n=e[this.getLanguagePartFromCode(a)]),n||(n=e.default),n||[]}toResolveHierarchy(e,a){const n=this.getFallbackCodes((a===!1?[]:a)||this.options.fallbackLng||[],e),i=[],r=o=>{o&&(this.isSupportedCode(o)?i.push(o):this.logger.warn(`rejecting language code not found in supportedLngs: ${o}`))};return de(e)&&(e.indexOf("-")>-1||e.indexOf("_")>-1)?(this.options.load!=="languageOnly"&&r(this.formatLanguageCode(e)),this.options.load!=="languageOnly"&&this.options.load!=="currentOnly"&&r(this.getScriptPartFromCode(e)),this.options.load!=="currentOnly"&&r(this.getLanguagePartFromCode(e))):de(e)&&r(this.formatLanguageCode(e)),n.forEach(o=>{i.indexOf(o)<0&&r(this.formatLanguageCode(o))}),i}}const lA={zero:0,one:1,two:2,few:3,many:4,other:5},cA={select:t=>t===1?"one":"other",resolvedOptions:()=>({pluralCategories:["one","other"]})};class Z8{constructor(e,a={}){this.languageUtils=e,this.options=a,this.logger=Jn.create("pluralResolver"),this.pluralRulesCache={}}clearCache(){this.pluralRulesCache={}}getRule(e,a={}){const n=Kd(e==="dev"?"en":e),i=a.ordinal?"ordinal":"cardinal",r=JSON.stringify({cleanedCode:n,type:i});if(r in this.pluralRulesCache)return this.pluralRulesCache[r];let o;try{o=new Intl.PluralRules(n,{type:i})}catch{if(!Intl)return this.logger.error("No Intl support, please use an Intl polyfill!"),cA;if(!e.match(/-|_/))return cA;const c=this.languageUtils.getLanguagePartFromCode(e);o=this.getRule(c,a)}return this.pluralRulesCache[r]=o,o}needsPlural(e,a={}){let n=this.getRule(e,a);return n||(n=this.getRule("dev",a)),(n==null?void 0:n.resolvedOptions().pluralCategories.length)>1}getPluralFormsOfKey(e,a,n={}){return this.getSuffixes(e,n).map(i=>`${a}${i}`)}getSuffixes(e,a={}){let n=this.getRule(e,a);return n||(n=this.getRule("dev",a)),n?n.resolvedOptions().pluralCategories.sort((i,r)=>lA[i]-lA[r]).map(i=>`${this.options.prepend}${a.ordinal?`ordinal${this.options.prepend}`:""}${i}`):[]}getSuffix(e,a,n={}){const i=this.getRule(e,n);return i?`${this.options.prepend}${n.ordinal?`ordinal${this.options.prepend}`:""}${i.select(a)}`:(this.logger.warn(`no plural rule found for: ${e}`),this.getSuffix("dev",a,n))}}const dA=(t,e,a,n=".",i=!0)=>{let r=B8(t,e,a);return!r&&i&&de(a)&&(r=vv(t,a,n),r===void 0&&(r=vv(e,a,n))),r},a0=t=>t.replace(/\$/g,"$$$$");class uA{constructor(e={}){var a;this.logger=Jn.create("interpolator"),this.options=e,this.format=((a=e==null?void 0:e.interpolation)==null?void 0:a.format)||(n=>n),this.init(e)}init(e={}){e.interpolation||(e.interpolation={escapeValue:!0});const{escape:a,escapeValue:n,useRawValueToEscape:i,prefix:r,prefixEscaped:o,suffix:l,suffixEscaped:c,formatSeparator:d,unescapeSuffix:u,unescapePrefix:p,nestingPrefix:m,nestingPrefixEscaped:h,nestingSuffix:g,nestingSuffixEscaped:y,nestingOptionsSeparator:x,maxReplaces:v,alwaysFormat:w}=e.interpolation;this.escape=a!==void 0?a:$8,this.escapeValue=n!==void 0?n:!0,this.useRawValueToEscape=i!==void 0?i:!1,this.prefix=r?Ss(r):o||"{{",this.suffix=l?Ss(l):c||"}}",this.formatSeparator=d||",",this.unescapePrefix=u?"":p||"-",this.unescapeSuffix=this.unescapePrefix?"":u||"",this.nestingPrefix=m?Ss(m):h||Ss("$t("),this.nestingSuffix=g?Ss(g):y||Ss(")"),this.nestingOptionsSeparator=x||",",this.maxReplaces=v||1e3,this.alwaysFormat=w!==void 0?w:!1,this.resetRegExp()}reset(){this.options&&this.init(this.options)}resetRegExp(){const e=(a,n)=>(a==null?void 0:a.source)===n?(a.lastIndex=0,a):new RegExp(n,"g");this.regexp=e(this.regexp,`${this.prefix}(.+?)${this.suffix}`),this.regexpUnescape=e(this.regexpUnescape,`${this.prefix}${this.unescapePrefix}(.+?)${this.unescapeSuffix}${this.suffix}`),this.nestingRegexp=e(this.nestingRegexp,`${this.nestingPrefix}((?:[^()"']+|"[^"]*"|'[^']*'|\\((?:[^()]|"[^"]*"|'[^']*')*\\))*?)${this.nestingSuffix}`)}interpolate(e,a,n,i){var h;let r,o,l;const c=this.options&&this.options.interpolation&&this.options.interpolation.defaultVariables||{},d=g=>{if(g.indexOf(this.formatSeparator)<0){const w=dA(a,c,g,this.options.keySeparator,this.options.ignoreJSONStructure);return this.alwaysFormat?this.format(w,void 0,n,{...i,...a,interpolationkey:g}):w}const y=g.split(this.formatSeparator),x=y.shift().trim(),v=y.join(this.formatSeparator).trim();return this.format(dA(a,c,x,this.options.keySeparator,this.options.ignoreJSONStructure),v,n,{...i,...a,interpolationkey:x})};this.resetRegExp();const u=(i==null?void 0:i.missingInterpolationHandler)||this.options.missingInterpolationHandler,p=((h=i==null?void 0:i.interpolation)==null?void 0:h.skipOnVariables)!==void 0?i.interpolation.skipOnVariables:this.options.interpolation.skipOnVariables;return[{regex:this.regexpUnescape,safeValue:g=>a0(g)},{regex:this.regexp,safeValue:g=>this.escapeValue?a0(this.escape(g)):a0(g)}].forEach(g=>{for(l=0;r=g.regex.exec(e);){const y=r[1].trim();if(o=d(y),o===void 0)if(typeof u=="function"){const v=u(e,r,i);o=de(v)?v:""}else if(i&&Object.prototype.hasOwnProperty.call(i,y))o="";else if(p){o=r[0];continue}else this.logger.warn(`missed to pass in variable ${y} for interpolating ${e}`),o="";else!de(o)&&!this.useRawValueToEscape&&(o=tA(o));const x=g.safeValue(o);if(e=e.replace(r[0],x),p?(g.regex.lastIndex+=o.length,g.regex.lastIndex-=r[0].length):g.regex.lastIndex=0,l++,l>=this.maxReplaces)break}}),e}nest(e,a,n={}){let i,r,o;const l=(c,d)=>{const u=this.nestingOptionsSeparator;if(c.indexOf(u)<0)return c;const p=c.split(new RegExp(`${u}[ ]*{`));let m=`{${p[1]}`;c=p[0],m=this.interpolate(m,o);const h=m.match(/'/g),g=m.match(/"/g);(((h==null?void 0:h.length)??0)%2===0&&!g||g.length%2!==0)&&(m=m.replace(/'/g,'"'));try{o=JSON.parse(m),d&&(o={...d,...o})}catch(y){return this.logger.warn(`failed parsing options string in nesting for key ${c}`,y),`${c}${u}${m}`}return o.defaultValue&&o.defaultValue.indexOf(this.prefix)>-1&&delete o.defaultValue,c};for(;i=this.nestingRegexp.exec(e);){let c=[];o={...n},o=o.replace&&!de(o.replace)?o.replace:o,o.applyPostProcessor=!1,delete o.defaultValue;const d=/{.*}/.test(i[1])?i[1].lastIndexOf("}")+1:i[1].indexOf(this.formatSeparator);if(d!==-1&&(c=i[1].slice(d).split(this.formatSeparator).map(u=>u.trim()).filter(Boolean),i[1]=i[1].slice(0,d)),r=a(l.call(this,i[1].trim(),o),o),r&&i[0]===e&&!de(r))return r;de(r)||(r=tA(r)),r||(this.logger.warn(`missed to resolve ${i[1]} for nesting ${e}`),r=""),c.length&&(r=c.reduce((u,p)=>this.format(u,p,n.lng,{...n,interpolationkey:i[1].trim()}),r.trim())),e=e.replace(i[0],r),this.regexp.lastIndex=0}return e}}const eH=t=>{let e=t.toLowerCase().trim();const a={};if(t.indexOf("(")>-1){const n=t.split("(");e=n[0].toLowerCase().trim();const i=n[1].substring(0,n[1].length-1);e==="currency"&&i.indexOf(":")<0?a.currency||(a.currency=i.trim()):e==="relativetime"&&i.indexOf(":")<0?a.range||(a.range=i.trim()):i.split(";").forEach(o=>{if(o){const[l,...c]=o.split(":"),d=c.join(":").trim().replace(/^'+|'+$/g,""),u=l.trim();a[u]||(a[u]=d),d==="false"&&(a[u]=!1),d==="true"&&(a[u]=!0),isNaN(d)||(a[u]=parseInt(d,10))}})}return{formatName:e,formatOptions:a}},pA=t=>{const e={};return(a,n,i)=>{let r=i;i&&i.interpolationkey&&i.formatParams&&i.formatParams[i.interpolationkey]&&i[i.interpolationkey]&&(r={...r,[i.interpolationkey]:void 0});const o=n+JSON.stringify(r);let l=e[o];return l||(l=t(Kd(n),i),e[o]=l),l(a)}},tH=t=>(e,a,n)=>t(Kd(a),n)(e);class aH{constructor(e={}){this.logger=Jn.create("formatter"),this.options=e,this.init(e)}init(e,a={interpolation:{}}){this.formatSeparator=a.interpolation.formatSeparator||",";const n=a.cacheInBuiltFormats?pA:tH;this.formats={number:n((i,r)=>{const o=new Intl.NumberFormat(i,{...r});return l=>o.format(l)}),currency:n((i,r)=>{const o=new Intl.NumberFormat(i,{...r,style:"currency"});return l=>o.format(l)}),datetime:n((i,r)=>{const o=new Intl.DateTimeFormat(i,{...r});return l=>o.format(l)}),relativetime:n((i,r)=>{const o=new Intl.RelativeTimeFormat(i,{...r});return l=>o.format(l,r.range||"day")}),list:n((i,r)=>{const o=new Intl.ListFormat(i,{...r});return l=>o.format(l)})}}add(e,a){this.formats[e.toLowerCase().trim()]=a}addCached(e,a){this.formats[e.toLowerCase().trim()]=pA(a)}format(e,a,n,i={}){const r=a.split(this.formatSeparator);if(r.length>1&&r[0].indexOf("(")>1&&r[0].indexOf(")")<0&&r.find(l=>l.indexOf(")")>-1)){const l=r.findIndex(c=>c.indexOf(")")>-1);r[0]=[r[0],...r.splice(1,l)].join(this.formatSeparator)}return r.reduce((l,c)=>{var p;const{formatName:d,formatOptions:u}=eH(c);if(this.formats[d]){let m=l;try{const h=((p=i==null?void 0:i.formatParams)==null?void 0:p[i.interpolationkey])||{},g=h.locale||h.lng||i.locale||i.lng||n;m=this.formats[d](l,g,{...u,...i,...h})}catch(h){this.logger.warn(h)}return m}else this.logger.warn(`there was no format function for ${d}`);return l},e)}}const nH=(t,e)=>{t.pending[e]!==void 0&&(delete t.pending[e],t.pendingCount--)};class iH extends ng{constructor(e,a,n,i={}){var r,o;super(),this.backend=e,this.store=a,this.services=n,this.languageUtils=n.languageUtils,this.options=i,this.logger=Jn.create("backendConnector"),this.waitingReads=[],this.maxParallelReads=i.maxParallelReads||10,this.readingCalls=0,this.maxRetries=i.maxRetries>=0?i.maxRetries:5,this.retryTimeout=i.retryTimeout>=1?i.retryTimeout:350,this.state={},this.queue=[],(o=(r=this.backend)==null?void 0:r.init)==null||o.call(r,n,i.backend,i)}queueLoad(e,a,n,i){const r={},o={},l={},c={};return e.forEach(d=>{let u=!0;a.forEach(p=>{const m=`${d}|${p}`;!n.reload&&this.store.hasResourceBundle(d,p)?this.state[m]=2:this.state[m]<0||(this.state[m]===1?o[m]===void 0&&(o[m]=!0):(this.state[m]=1,u=!1,o[m]===void 0&&(o[m]=!0),r[m]===void 0&&(r[m]=!0),c[p]===void 0&&(c[p]=!0)))}),u||(l[d]=!0)}),(Object.keys(r).length||Object.keys(o).length)&&this.queue.push({pending:o,pendingCount:Object.keys(o).length,loaded:{},errors:[],callback:i}),{toLoad:Object.keys(r),pending:Object.keys(o),toLoadLanguages:Object.keys(l),toLoadNamespaces:Object.keys(c)}}loaded(e,a,n){const i=e.split("|"),r=i[0],o=i[1];a&&this.emit("failedLoading",r,o,a),!a&&n&&this.store.addResourceBundle(r,o,n,void 0,void 0,{skipCopy:!0}),this.state[e]=a?-1:2,a&&n&&(this.state[e]=0);const l={};this.queue.forEach(c=>{F8(c.loaded,[r],o),nH(c,e),a&&c.errors.push(a),c.pendingCount===0&&!c.done&&(Object.keys(c.loaded).forEach(d=>{l[d]||(l[d]={});const u=c.loaded[d];u.length&&u.forEach(p=>{l[d][p]===void 0&&(l[d][p]=!0)})}),c.done=!0,c.errors.length?c.callback(c.errors):c.callback())}),this.emit("loaded",l),this.queue=this.queue.filter(c=>!c.done)}read(e,a,n,i=0,r=this.retryTimeout,o){if(!e.length)return o(null,{});if(this.readingCalls>=this.maxParallelReads){this.waitingReads.push({lng:e,ns:a,fcName:n,tried:i,wait:r,callback:o});return}this.readingCalls++;const l=(d,u)=>{if(this.readingCalls--,this.waitingReads.length>0){const p=this.waitingReads.shift();this.read(p.lng,p.ns,p.fcName,p.tried,p.wait,p.callback)}if(d&&u&&i<this.maxRetries){setTimeout(()=>{this.read.call(this,e,a,n,i+1,r*2,o)},r);return}o(d,u)},c=this.backend[n].bind(this.backend);if(c.length===2){try{const d=c(e,a);d&&typeof d.then=="function"?d.then(u=>l(null,u)).catch(l):l(null,d)}catch(d){l(d)}return}return c(e,a,l)}prepareLoading(e,a,n={},i){if(!this.backend)return this.logger.warn("No backend was added via i18next.use. Will not load resources."),i&&i();de(e)&&(e=this.languageUtils.toResolveHierarchy(e)),de(a)&&(a=[a]);const r=this.queueLoad(e,a,n,i);if(!r.toLoad.length)return r.pending.length||i(),null;r.toLoad.forEach(o=>{this.loadOne(o)})}load(e,a,n){this.prepareLoading(e,a,{},n)}reload(e,a,n){this.prepareLoading(e,a,{reload:!0},n)}loadOne(e,a=""){const n=e.split("|"),i=n[0],r=n[1];this.read(i,r,"read",void 0,void 0,(o,l)=>{o&&this.logger.warn(`${a}loading namespace ${r} for language ${i} failed`,o),!o&&l&&this.logger.log(`${a}loaded namespace ${r} for language ${i}`,l),this.loaded(e,o,l)})}saveMissing(e,a,n,i,r,o={},l=()=>{}){var c,d,u,p,m;if((d=(c=this.services)==null?void 0:c.utils)!=null&&d.hasLoadedNamespace&&!((p=(u=this.services)==null?void 0:u.utils)!=null&&p.hasLoadedNamespace(a))){this.logger.warn(`did not save key "${n}" as the namespace "${a}" was not yet loaded`,"This means something IS WRONG in your setup. You access the t function before i18next.init / i18next.loadNamespace / i18next.changeLanguage was done. Wait for the callback or Promise to resolve before accessing it!!!");return}if(!(n==null||n==="")){if((m=this.backend)!=null&&m.create){const h={...o,isUpdate:r},g=this.backend.create.bind(this.backend);if(g.length<6)try{let y;g.length===5?y=g(e,a,n,i,h):y=g(e,a,n,i),y&&typeof y.then=="function"?y.then(x=>l(null,x)).catch(l):l(null,y)}catch(y){l(y)}else g(e,a,n,i,l,h)}!e||!e[0]||this.store.addResource(e[0],a,n,i)}}}const n0=()=>({debug:!1,initAsync:!0,ns:["translation"],defaultNS:["translation"],fallbackLng:["dev"],fallbackNS:!1,supportedLngs:!1,nonExplicitSupportedLngs:!1,load:"all",preload:!1,simplifyPluralSuffix:!0,keySeparator:".",nsSeparator:":",pluralSeparator:"_",contextSeparator:"_",partialBundledLanguages:!1,saveMissing:!1,updateMissing:!1,saveMissingTo:"fallback",saveMissingPlurals:!0,missingKeyHandler:!1,missingInterpolationHandler:!1,postProcess:!1,postProcessPassResolved:!1,returnNull:!1,returnEmptyString:!0,returnObjects:!1,joinArrays:!1,returnedObjectHandler:!1,parseMissingKeyHandler:!1,appendNamespaceToMissingKey:!1,appendNamespaceToCIMode:!1,overloadTranslationOptionHandler:t=>{let e={};if(typeof t[1]=="object"&&(e=t[1]),de(t[1])&&(e.defaultValue=t[1]),de(t[2])&&(e.tDescription=t[2]),typeof t[2]=="object"||typeof t[3]=="object"){const a=t[3]||t[2];Object.keys(a).forEach(n=>{e[n]=a[n]})}return e},interpolation:{escapeValue:!0,format:t=>t,prefix:"{{",suffix:"}}",formatSeparator:",",unescapePrefix:"-",nestingPrefix:"$t(",nestingSuffix:")",nestingOptionsSeparator:",",maxReplaces:1e3,skipOnVariables:!0},cacheInBuiltFormats:!0}),mA=t=>{var e,a;return de(t.ns)&&(t.ns=[t.ns]),de(t.fallbackLng)&&(t.fallbackLng=[t.fallbackLng]),de(t.fallbackNS)&&(t.fallbackNS=[t.fallbackNS]),((a=(e=t.supportedLngs)==null?void 0:e.indexOf)==null?void 0:a.call(e,"cimode"))<0&&(t.supportedLngs=t.supportedLngs.concat(["cimode"])),typeof t.initImmediate=="boolean"&&(t.initAsync=t.initImmediate),t},Lp=()=>{},rH=t=>{Object.getOwnPropertyNames(Object.getPrototypeOf(t)).forEach(a=>{typeof t[a]=="function"&&(t[a]=t[a].bind(t))})};class rd extends ng{constructor(e={},a){if(super(),this.options=mA(e),this.services={},this.logger=Jn,this.modules={external:[]},rH(this),a&&!this.isInitialized&&!e.isClone){if(!this.options.initAsync)return this.init(e,a),this;setTimeout(()=>{this.init(e,a)},0)}}init(e={},a){this.isInitializing=!0,typeof e=="function"&&(a=e,e={}),e.defaultNS==null&&e.ns&&(de(e.ns)?e.defaultNS=e.ns:e.ns.indexOf("translation")<0&&(e.defaultNS=e.ns[0]));const n=n0();this.options={...n,...this.options,...mA(e)},this.options.interpolation={...n.interpolation,...this.options.interpolation},e.keySeparator!==void 0&&(this.options.userDefinedKeySeparator=e.keySeparator),e.nsSeparator!==void 0&&(this.options.userDefinedNsSeparator=e.nsSeparator),typeof this.options.overloadTranslationOptionHandler!="function"&&(this.options.overloadTranslationOptionHandler=n.overloadTranslationOptionHandler);const i=d=>d?typeof d=="function"?new d:d:null;if(!this.options.isClone){this.modules.logger?Jn.init(i(this.modules.logger),this.options):Jn.init(null,this.options);let d;this.modules.formatter?d=this.modules.formatter:d=aH;const u=new sA(this.options);this.store=new rA(this.options.resources,this.options);const p=this.services;p.logger=Jn,p.resourceStore=this.store,p.languageUtils=u,p.pluralResolver=new Z8(u,{prepend:this.options.pluralSeparator,simplifyPluralSuffix:this.options.simplifyPluralSuffix}),this.options.interpolation.format&&this.options.interpolation.format!==n.interpolation.format&&this.logger.deprecate("init: you are still using the legacy format function, please use the new approach: https://www.i18next.com/translation-function/formatting"),d&&(!this.options.interpolation.format||this.options.interpolation.format===n.interpolation.format)&&(p.formatter=i(d),p.formatter.init&&p.formatter.init(p,this.options),this.options.interpolation.format=p.formatter.format.bind(p.formatter)),p.interpolator=new uA(this.options),p.utils={hasLoadedNamespace:this.hasLoadedNamespace.bind(this)},p.backendConnector=new iH(i(this.modules.backend),p.resourceStore,p,this.options),p.backendConnector.on("*",(h,...g)=>{this.emit(h,...g)}),this.modules.languageDetector&&(p.languageDetector=i(this.modules.languageDetector),p.languageDetector.init&&p.languageDetector.init(p,this.options.detection,this.options)),this.modules.i18nFormat&&(p.i18nFormat=i(this.modules.i18nFormat),p.i18nFormat.init&&p.i18nFormat.init(this)),this.translator=new bh(this.services,this.options),this.translator.on("*",(h,...g)=>{this.emit(h,...g)}),this.modules.external.forEach(h=>{h.init&&h.init(this)})}if(this.format=this.options.interpolation.format,a||(a=Lp),this.options.fallbackLng&&!this.services.languageDetector&&!this.options.lng){const d=this.services.languageUtils.getFallbackCodes(this.options.fallbackLng);d.length>0&&d[0]!=="dev"&&(this.options.lng=d[0])}!this.services.languageDetector&&!this.options.lng&&this.logger.warn("init: no languageDetector is used and no lng is defined"),["getResource","hasResourceBundle","getResourceBundle","getDataByLanguage"].forEach(d=>{this[d]=(...u)=>this.store[d](...u)}),["addResource","addResources","addResourceBundle","removeResourceBundle"].forEach(d=>{this[d]=(...u)=>(this.store[d](...u),this)});const l=Ac(),c=()=>{const d=(u,p)=>{this.isInitializing=!1,this.isInitialized&&!this.initializedStoreOnce&&this.logger.warn("init: i18next is already initialized. You should call init just once!"),this.isInitialized=!0,this.options.isClone||this.logger.log("initialized",this.options),this.emit("initialized",this.options),l.resolve(p),a(u,p)};if(this.languages&&!this.isInitialized)return d(null,this.t.bind(this));this.changeLanguage(this.options.lng,d)};return this.options.resources||!this.options.initAsync?c():setTimeout(c,0),l}loadResources(e,a=Lp){var r,o;let n=a;const i=de(e)?e:this.language;if(typeof e=="function"&&(n=e),!this.options.resources||this.options.partialBundledLanguages){if((i==null?void 0:i.toLowerCase())==="cimode"&&(!this.options.preload||this.options.preload.length===0))return n();const l=[],c=d=>{if(!d||d==="cimode")return;this.services.languageUtils.toResolveHierarchy(d).forEach(p=>{p!=="cimode"&&l.indexOf(p)<0&&l.push(p)})};i?c(i):this.services.languageUtils.getFallbackCodes(this.options.fallbackLng).forEach(u=>c(u)),(o=(r=this.options.preload)==null?void 0:r.forEach)==null||o.call(r,d=>c(d)),this.services.backendConnector.load(l,this.options.ns,d=>{!d&&!this.resolvedLanguage&&this.language&&this.setResolvedLanguage(this.language),n(d)})}else n(null)}reloadResources(e,a,n){const i=Ac();return typeof e=="function"&&(n=e,e=void 0),typeof a=="function"&&(n=a,a=void 0),e||(e=this.languages),a||(a=this.options.ns),n||(n=Lp),this.services.backendConnector.reload(e,a,r=>{i.resolve(),n(r)}),i}use(e){if(!e)throw new Error("You are passing an undefined module! Please check the object you are passing to i18next.use()");if(!e.type)throw new Error("You are passing a wrong module! Please check the object you are passing to i18next.use()");return e.type==="backend"&&(this.modules.backend=e),(e.type==="logger"||e.log&&e.warn&&e.error)&&(this.modules.logger=e),e.type==="languageDetector"&&(this.modules.languageDetector=e),e.type==="i18nFormat"&&(this.modules.i18nFormat=e),e.type==="postProcessor"&&qP.addPostProcessor(e),e.type==="formatter"&&(this.modules.formatter=e),e.type==="3rdParty"&&this.modules.external.push(e),this}setResolvedLanguage(e){if(!(!e||!this.languages)&&!(["cimode","dev"].indexOf(e)>-1)){for(let a=0;a<this.languages.length;a++){const n=this.languages[a];if(!(["cimode","dev"].indexOf(n)>-1)&&this.store.hasLanguageSomeTranslations(n)){this.resolvedLanguage=n;break}}!this.resolvedLanguage&&this.languages.indexOf(e)<0&&this.store.hasLanguageSomeTranslations(e)&&(this.resolvedLanguage=e,this.languages.unshift(e))}}changeLanguage(e,a){this.isLanguageChangingTo=e;const n=Ac();this.emit("languageChanging",e);const i=l=>{this.language=l,this.languages=this.services.languageUtils.toResolveHierarchy(l),this.resolvedLanguage=void 0,this.setResolvedLanguage(l)},r=(l,c)=>{c?this.isLanguageChangingTo===e&&(i(c),this.translator.changeLanguage(c),this.isLanguageChangingTo=void 0,this.emit("languageChanged",c),this.logger.log("languageChanged",c)):this.isLanguageChangingTo=void 0,n.resolve((...d)=>this.t(...d)),a&&a(l,(...d)=>this.t(...d))},o=l=>{var u,p;!e&&!l&&this.services.languageDetector&&(l=[]);const c=de(l)?l:l&&l[0],d=this.store.hasLanguageSomeTranslations(c)?c:this.services.languageUtils.getBestMatchFromCodes(de(l)?[l]:l);d&&(this.language||i(d),this.translator.language||this.translator.changeLanguage(d),(p=(u=this.services.languageDetector)==null?void 0:u.cacheUserLanguage)==null||p.call(u,d)),this.loadResources(d,m=>{r(m,d)})};return!e&&this.services.languageDetector&&!this.services.languageDetector.async?o(this.services.languageDetector.detect()):!e&&this.services.languageDetector&&this.services.languageDetector.async?this.services.languageDetector.detect.length===0?this.services.languageDetector.detect().then(o):this.services.languageDetector.detect(o):o(e),n}getFixedT(e,a,n){const i=(r,o,...l)=>{let c;typeof o!="object"?c=this.options.overloadTranslationOptionHandler([r,o].concat(l)):c={...o},c.lng=c.lng||i.lng,c.lngs=c.lngs||i.lngs,c.ns=c.ns||i.ns,c.keyPrefix!==""&&(c.keyPrefix=c.keyPrefix||n||i.keyPrefix);const d=this.options.keySeparator||".";let u;return c.keyPrefix&&Array.isArray(r)?u=r.map(p=>(typeof p=="function"&&(p=wv(p,{...this.options,...o})),`${c.keyPrefix}${d}
51${p}`)):(typeof r=="function"&&(r=wv(r,{...this.options,...o})),u=c.keyPrefix?`${c.keyPrefix}${d}${r}`:r),this.t(u,c)};return de(e)?i.lng=e:i.lngs=e,i.ns=a,i.keyPrefix=n,i}t(...e){var a;return(a=this.translator)==null?void 0:a.translate(...e)}exists(...e){var a;return(a=this.translator)==null?void 0:a.exists(...e)}setDefaultNamespace(e){this.options.defaultNS=e}hasLoadedNamespace(e,a={}){if(!this.isInitialized)return this.logger.warn("hasLoadedNamespace: i18next was not initialized",this.languages),!1;if(!this.languages||!this.languages.length)return this.logger.warn("hasLoadedNamespace: i18n.languages were undefined or empty",this.languages),!1;const n=a.lng||this.resolvedLanguage||this.languages[0],i=this.options?this.options.fallbackLng:!1,r=this.languages[this.languages.length-1];if(n.toLowerCase()==="cimode")return!0;const o=(l,c)=>{const d=this.services.backendConnector.state[`${l}|${c}`];return d===-1||d===0||d===2};if(a.precheck){const l=a.precheck(this,o);if(l!==void 0)return l}return!!(this.hasResourceBundle(n,e)||!this.services.backendConnector.backend||this.options.resources&&!this.options.partialBundledLanguages||o(n,e)&&(!i||o(r,e)))}loadNamespaces(e,a){const n=Ac();return this.options.ns?(de(e)&&(e=[e]),e.forEach(i=>{this.options.ns.indexOf(i)<0&&this.options.ns.push(i)}),this.loadResources(i=>{n.resolve(),a&&a(i)}),n):(a&&a(),Promise.resolve())}loadLanguages(e,a){const n=Ac();de(e)&&(e=[e]);const i=this.options.preload||[],r=e.filter(o=>i.indexOf(o)<0&&this.services.languageUtils.isSupportedCode(o));return r.length?(this.options.preload=i.concat(r),this.loadResources(o=>{n.resolve(),a&&a(o)}),n):(a&&a(),Promise.resolve())}dir(e){var i,r;if(e||(e=this.resolvedLanguage||(((i=this.languages)==null?void 0:i.length)>0?this.languages[0]:this.language)),!e)return"rtl";try{const o=new Intl.Locale(e);if(o&&o.getTextInfo){const l=o.getTextInfo();if(l&&l.direction)return l.direction}}catch{}const a=["ar","shu","sqr","ssh","xaa","yhd","yud","aao","abh","abv","acm","acq","acw","acx","acy","adf","ads","aeb","aec","afb","ajp","apc","apd","arb","arq","ars","ary","arz","auz","avl","ayh","ayl","ayn","ayp","bbz","pga","he","iw","ps","pbt","pbu","pst","prp","prd","ug","ur","ydd","yds","yih","ji","yi","hbo","men","xmn","fa","jpr","peo","pes","prs","dv","sam","ckb"],n=((r=this.services)==null?void 0:r.languageUtils)||new sA(n0());return e.toLowerCase().indexOf("-latn")>1?"ltr":a.indexOf(n.getLanguagePartFromCode(e))>-1||e.toLowerCase().indexOf("-arab")>1?"rtl":"ltr"}static createInstance(e={},a){const n=new rd(e,a);return n.createInstance=rd.createInstance,n}cloneInstance(e={},a=Lp){const n=e.forkResourceStore;n&&delete e.forkResourceStore;const i={...this.options,...e,isClone:!0},r=new rd(i);if((e.debug!==void 0||e.prefix!==void 0)&&(r.logger=r.logger.clone(e)),["store","services","language"].forEach(l=>{r[l]=this[l]}),r.services={...this.services},r.services.utils={hasLoadedNamespace:r.hasLoadedNamespace.bind(r)},n){const l=Object.keys(this.store.data).reduce((c,d)=>(c[d]={...this.store.data[d]},c[d]=Object.keys(c[d]).reduce((u,p)=>(u[p]={...c[d][p]},u),c[d]),c),{});r.store=new rA(l,i),r.services.resourceStore=r.store}if(e.interpolation){const c={...n0().interpolation,...this.options.interpolation,...e.interpolation},d={...i,interpolation:c};r.services.interpolator=new uA(d)}return r.translator=new bh(r.services,i),r.translator.on("*",(l,...c)=>{r.emit(l,...c)}),r.init(i,a),r.translator.options=i,r.translator.backendConnector.services.utils={hasLoadedNamespace:r.hasLoadedNamespace.bind(r)},r}toJSON(){return{options:this.options,store:this.store,language:this.language,languages:this.languages,resolvedLanguage:this.resolvedLanguage}}}const wa=rd.createInstance();wa.createInstance;wa.dir;wa.init;wa.loadResources;wa.reloadResources;wa.use;wa.changeLanguage;wa.getFixedT;wa.t;wa.exists;wa.setDefaultNamespace;wa.hasLoadedNamespace;wa.loadNamespaces;wa.loadLanguages;const oH=(t,e,a,n)=>{var r,o,l,c;const i=[a,{code:e,...n||{}}];if((o=(r=t==null?void 0:t.services)==null?void 0:r.logger)!=null&&o.forward)return t.services.logger.forward(i,"warn","react-i18next::",!0);Ko(i[0])&&(i[0]=`react-i18next:: ${i[0]}`),(c=(l=t==null?void 0:t.services)==null?void 0:l.logger)!=null&&c.warn?t.services.logger.warn(...i):console!=null&&console.warn&&console.warn(...i)},hA={},VP=(t,e,a,n)=>{Ko(a)&&hA[a]||(Ko(a)&&(hA[a]=new Date),oH(t,e,a,n))},HP=(t,e)=>()=>{if(t.isInitialized)e();else{const a=()=>{setTimeout(()=>{t.off("initialized",a)},0),e()};t.on("initialized",a)}},kv=(t,e,a)=>{t.loadNamespaces(e,HP(t,a))},fA=(t,e,a,n)=>
51{if(Ko(a)&&(a=[a]),t.options.preload&&t.options.preload.indexOf(e)>-1)return kv(t,a,n);a.forEach(i=>{t.options.ns.indexOf(i)<0&&t.options.ns.push(i)}),t.loadLanguages(e,HP(t,n))},sH=(t,e,a={})=>!e.languages||!e.languages.length?(VP(e,"NO_LANGUAGES","i18n.languages were undefined or empty",{languages:e.languages}),!0):e.hasLoadedNamespace(t,{lng:a.lng,precheck:(n,i)=>{if(a.bindI18n&&a.bindI18n.indexOf("languageChanging")>-1&&n.services.backendConnector.backend&&n.isLanguageChangingTo&&!i(n.isLanguageChangingTo,t))return!1}}),Ko=t=>typeof t=="string",lH=t=>typeof t=="object"&&t!==null,cH=/&(?:amp|#38|lt|#60|gt|#62|apos|#39|quot|#34|nbsp|#160|copy|#169|reg|#174|hellip|#8230|#x2F|#47);/g,dH={"&amp;":"&","&#38;":"&","&lt;":"<","&#60;":"<","&gt;":">","&#62;":">","&apos;":"'","&#39;":"'","&quot;":'"',"&#34;":'"',"&nbsp;":" ","&#160;":" ","&copy;":"©","&#169;":"©","&reg;":"®","&#174;":"®","&hellip;":"…","&#8230;":"…","&#x2F;":"/","&#47;":"/"},uH=t=>dH[t],pH=t=>t.replace(cH,uH);let Sv={bindI18n:"languageChanged",bindI18nStore:"",transEmptyNodeValue:"",transSupportBasicHtmlNodes:!0,transWrapTextNodes:"",transKeepBasicHtmlNodesFor:["br","strong","i","p"],useSuspense:!0,unescape:pH,transDefaultProps:void 0};const mH=(t={})=>{Sv={...Sv,...t}},hH=()=>Sv;let FP;const fH=t=>{FP=t},gH=()=>FP,yH={type:"3rdParty",init(t){mH(t.options.react),fH(t)}},xH=k.createContext();class vH{constructor(){this.usedNamespaces={}}addUsedNamespaces(e){e.forEach(a=>{this.usedNamespaces[a]||(this.usedNamespaces[a]=!0)})}getUsedNamespaces(){return Object.keys(this.usedNamespaces)}}var BP={exports:{}},UP={};/**
52 * @license React
53 * use-sync-external-store-shim.production.js
54 *
55 * Copyright (c) Meta Platforms, Inc. and affiliates.
56 *
57 * This source code is licensed under the MIT license found in the
58 * LICENSE file in the root directory of this source tree.
59 */var vl=k;function bH(t,e){return t===e&&(t!==0||1/t===1/e)||t!==t&&e!==e}var wH=typeof Object.is=="function"?Object.is:bH,kH=vl.useState,SH=vl.useEffect,_H=vl.useLayoutEffect,AH=vl.useDebugValue;function EH(t,e){var a=e(),n=kH({inst:{value:a,getSnapshot:e}}),i=n[0].inst,r=n[1];return _H(function(){i.value=a,i.getSnapshot=e,i0(i)&&r({inst:i})},[t,a,e]),SH(function(){return i0(i)&&r({inst:i}),t(function(){i0(i)&&r({inst:i})})},[t]),AH(a),a}function i0(t){var e=t.getSnapshot;t=t.value;try{var a=e();return!wH(t,a)}catch{return!0}}function CH(t,e){return e()}var jH=typeof window>"u"||typeof window.document>"u"||typeof window.document.createElement>"u"?CH:EH;UP.useSyncExternalStore=vl.useSyncExternalStore!==void 0?vl.useSyncExternalStore:jH;BP.exports=UP;var ig=BP.exports;const TH=(t,e)=>Ko(e)?e:lH(e)&&Ko(e.defaultValue)?e.defaultValue:Array.isArray(t)?t[t.length-1]:t,NH={t:TH,ready:!1},IH=()=>()=>{},$=(t,e={})=>{var j,N,L;const{i18n:a}=e,{i18n:n,defaultNS:i}=k.useContext(xH)||{},r=a||n||gH();r&&!r.reportNamespaces&&(r.reportNamespaces=new vH),r||VP(r,"NO_I18NEXT_INSTANCE","useTranslation: You will need to pass in an i18next instance by using initReactI18next");const o=k.useMemo(()=>{var O;return{...hH(),...(O=r==null?void 0:r.options)==null?void 0:O.react,...e}},[r,e]),{useSuspense:l,keyPrefix:c}=o,d=i||((j=r==null?void 0:r.options)==null?void 0:j.defaultNS),u=Ko(d)?[d]:d||["translation"],p=k.useMemo(()=>u,u);(L=(N=r==null?void 0:r.reportNamespaces)==null?void 0:N.addUsedNamespaces)==null||L.call(N,p);const m=k.useRef(0),h=k.useCallback(O=>{if(!r)return IH;const{bindI18n:R,bindI18nStore:G}=o,ee=()=>{m.current+=1,O()};return R&&r.on(R,ee),G&&r.store.on(G,ee),()=>{R&&R.split(" ").forEach(ke=>r.off(ke,ee)),G&&G.split(" ").forEach(ke=>r.store.off(ke,ee))}},[r,o]),g=k.useRef(),y=k.useCallback(()=>{if(!r)return NH;const O=!!(r.isInitialized||r.initializedStoreOnce)&&p.every(F=>sH(F,r,o)),R=e.lng||r.language,G=m.current,ee=g.current;if(ee&&ee.ready===O&&ee.lng===R&&ee.keyPrefix===c&&ee.revision===G)return ee;const ae={t:r.getFixedT(R,o.nsMode==="fallback"?p:p[0],c),ready:O,lng:R,keyPrefix:c,revision:G};return g.current=ae,ae}
59,[r,p,c,o,e.lng]),[x,v]=k.useState(0),{t:w,ready:S}=ig.useSyncExternalStore(h,y,y);k.useEffect(()=>{if(r&&!S&&!l){const O=()=>v(R=>R+1);e.lng?fA(r,e.lng,p,O):kv(r,p,O)}},[r,e.lng,p,S,l,x]);const T=r||{},P=k.useRef(null),M=k.useRef(),C=O=>{const R=Object.getOwnPropertyDescriptors(O);R.__original&&delete R.__original;const G=Object.create(Object.getPrototypeOf(O),R);if(!Object.prototype.hasOwnProperty.call(G,"__original"))try{Object.defineProperty(G,"__original",{value:O,writable:!1,enumerable:!1,configurable:!1})}catch{}return G},E=k.useMemo(()=>{const O=T,R=O==null?void 0:O.language;let G=O;O&&(P.current&&P.current.__original===O?M.current!==R?(G=C(O),P.current=G,M.current=R):G=P.current:(G=C(O),P.current=G,M.current=R));const ee=[w,G,S];return ee.t=w,ee.i18n=G,ee.ready=S,ee},[w,T,S,T.resolvedLanguage,T.language,T.languages]);if(r&&l&&!S)throw new Promise(O=>{const R=()=>O();e.lng?fA(r,e.lng,p,R):kv(r,p,R)});return E};function PH(){const{openModal:t}=oa(),{t:e,i18n:a}=$(),[n,i]=k.useState(!1),[r,o]=k.useState(!1);k.useEffect(()=>{const u=()=>{o(window.scrollY>50)};return window.addEventListener("scroll",u),()=>window.removeEventListener("scroll",u)},[]);const l=u=>{u.preventDefault(),t(e("contactModal.title")),i(!1)},c=()=>{const u=a.language==="es"?"en":"es";a.changeLanguage(u),localStorage.setItem("language",u)},d=()=>{i(!1)};return s.jsx("header",{className:`sticky top-0 z-50 bg-darkGray backdrop-blur-md transition-all duration-300 ${r?"py-2":"py-4"}`,children:s.jsxs("div",{className:"max-w-7xl mx-auto px-4 sm:px-6 lg:px-8",children:[s.jsxs("div",{className:`flex justify-between items-center transition-all duration-300 ${r?"h-12":"h-14"}`,children:[s.jsx(Te,{to:"/",id:"header-logo-link",className:"flex items-center gap-3 hover:opacity-80 transition-opacity",children:s.jsx("img",{id:"image-logo-haka",src:"/imagenes/logo_haka.png",alt:"HakaLab",className:`w-auto transition-all duration-300 ${r?"h-10":"h-16"}`})}),s.jsxs("nav",{className:`hidden md:flex gap-8 items-center transition-all duration-300 ${r?"text-sm":"text-base"}`,children:[s.jsx(Te,{id:"header-servicios-link",to:"/servicios",className:"text-gray-300 hover:text-primary transition-colors",children:e("nav.servicios")}),s.jsx(Te,{id:"header-nosotros-link",to:"/nosotros",className:"text-gray-300 hover:text-primary transition-colors",children:e("nav.nosotros")}),s.jsx(Te,{id:"header-casos-link",to:"/casosdeexito",className:"text-gray-300 hover:text-primary transition-colors",children:e("nav.casosDeExito")}),s.jsx(Te,{id:"header-productos-link",to:"/productos",className:"text-gray-300 hover:text-primary transition-colors",children:e("nav.productos")}),s.jsx("button",{id:"header-contacto-button",onClick:l,className:"text-gray-300 hover:text-primary transition-colors bg-none border-none cursor-pointer",children:e("nav.contacto")}),s.jsx("button",{id:"header-language-toggle",onClick:c,className:`ml-4 px-3 py-1 bg-gradient-to-r from-cyan-400 to-blue-500 hover:from-cyan-500 hover:to-blue-600 text-white font-bold rounded-full transition-all duration-300 hover:shadow-lg hover:shadow-cyan-400/50 ${r?"text-xs":"text-sm"}`,children:a.language==="es"?"EN":"ES"})]}),s.jsx("button",{id:"header-mobile-menu-toggle",onClick:()=>i(!n),className:"md:hidden text-primary text-2xl",children:n?"✕":"☰"})]}),n&&s.jsxs("nav",{className:"md:hidden pb-4 space-y-2 text-center mt-4",children:[s.jsx(Te,{to:"/servicios",onClick:d,className:"block px-4 py-2 text-gray-300 hover:text-primary transition-colors border-b-2 border-b-transparent hover:border-b-primary",children:e("nav.servicios")}),s.jsx(Te,{to:"/nosotros",onClick:d,className:"block px-4 py-2 text-gray-300 hover:text-primary transition-colors border-b-2 border-b-transparent hover:border-b-primary",children:e("nav.nosotros")}),s.jsx(Te,{to:"/casosdeexito",onClick:d,className:"block px-4 py-2 text-gray-300 hover:text-primary transition-colors border-b-2 border-b-transparent hover:border-b-primary",children:e("nav.casosDeExito")}),s.jsx(Te,{to:"/productos",onClick:d,className:"block px-4 py-2 text-gray-300 hover:text-primary transition-colors border-b-2 border-b-transparent hover:border-b-primary",children:e("nav.productos")}),s.jsx(Te,{to:"/blog",onClick:d,className:"block px-4 py-2 text-gray-300 hover:text-primary transition-colors border-b-2 border-b-transparent hover:border-b-primary",children:"Blog"}),s.jsx("button",{onClick:l,className:"w-full text-center px-4 py-2 text-gray-300 hover:text-primary transition-colors bg-none border-none cursor-pointer border-b-2 border-b-transparent hover:border-b-primary",children:e("nav.contacto")}),s.jsx("div",{className:"px-4 py-2 flex justify-center",children:s.jsx("button",{onClick:c,className:"px-3 py-1 bg-gradient-to-r from-cyan-400 to-blue-500 hover:from-cyan-500 hover:to-blue-600 text-white font-bold rounded-full text-sm transition-all duration-300 hover:shadow-lg hover:shadow-cyan-400/50",children:a.language==="es"?"EN":"ES"})})]})]})})}const nw=k.createContext({});function zr(t){const e=k.useRef(null);return e.current===null&&(e.current=t()),e.current}const $P=typeof window<"u",rg=$P?k.useLayoutEffect:k.useEffect,og=k.createContext(null);function iw(t,e){t.indexOf(e)===-1&&t.push(e)}function rw(t,e){const a=t.indexOf(e);a>-1&&t.splice(a,1)}
vendor: 27,829 bytes, line 59
59const On=(t,e,a)=>a>e?e:a<t?t:a;let Jd=()=>{};const qi={},WP=t=>/^-?(?:\d+(?:\.\d+)?|\.\d+)$/u.test(t);function GP(t){return typeof t=="object"&&t!==null}const KP=t=>/^0[^.\s]+$/u.test(t);function ow(t){let e;return()=>(e===void 0&&(e=t()),e)}const Ta=t=>t,RH=(t,e)=>a=>e(t(a)),Tu=(...t)=>t.reduce(RH),bl=(t,e,a)=>{const n=e-t;return n===0?1:(a-t)/n};class sw{constructor(){this.subscriptions=[]}add(e){return iw(this.subscriptions,e),()=>rw(this.subscriptions,e)}notify(e,a,n){const i=this.subscriptions.length;if(i)if(i===1)this.subscriptions[0](e,a,n);else for(let r=0;r<i;r++){const o=this.subscriptions[r];o&&o(e,a,n)}}getSize(){return this.subscriptions.length}clear(){this.subscriptions.length=0}}const ji=t=>t*1e3,ln=t=>t/1e3;function lw(t,e){return e?t*(1e3/e):0}const JP=(t,e,a)=>(((1-3*a+3*e)*t+(3*a-6*e))*t+3*e)*t,LH=1e-7,OH=12;function MH(t,e,a,n,i){let r,o,l=0;do o=e+(a-e)/2,r=JP(o,n,i)-t,r>0?a=o:e=o;while(Math.abs(r)>LH&&++l<OH);return o}function Nu(t,e,a,n){if(t===e&&a===n)return Ta;const i=r=>MH(r,0,1,t,a);return r=>r===0||r===1?r:JP(i(r),e,n)}const QP=t=>e=>e<=.5?t(2*e)/2:(2-t(2*(1-e)))/2,XP=t=>e=>1-t(1-e),YP=Nu(.33,1.53,.69,.99),cw=XP(YP),ZP=QP(cw),e4=t=>(t*=2)<1?.5*cw(t):.5*(2-Math.pow(2,-10*(t-1))),dw=t=>1-Math.sin(Math.acos(t)),t4=XP(dw),a4=QP(dw),DH=Nu(.42,0,1,1),qH=Nu(0,0,.58,1),n4=Nu(.42,0,.58,1),zH=t=>Array.isArray(t)&&typeof t[0]!="number",i4=t=>Array.isArray(t)&&typeof t[0]=="number",VH={linear:Ta,easeIn:DH,easeInOut:n4,easeOut:qH,circIn:dw,circInOut:a4,circOut:t4,backIn:cw,backInOut:ZP,backOut:YP,anticipate:e4},HH=t=>typeof t=="string",gA=t=>{if(i4(t)){Jd(t.length===4);const[e,a,n,i]=t;return Nu(e,a,n,i)}else if(HH(t))return VH[t];return t},Op=["setup","read","resolveKeyframes","preUpdate","update","preRender","render","postRender"];function FH(t,e){let a=new Set,n=new Set,i=!1,r=!1;const o=new WeakSet;let l={delta:0,timestamp:0,isProcessing:!1};function c(u){o.has(u)&&(d.schedule(u),t()),u(l)}const d={schedule:(u,p=!1,m=!1)=>{const g=m&&i?a:n;return p&&o.add(u),g.has(u)||g.add(u),u},cancel:u=>{n.delete(u),o.delete(u)},process:u=>{if(l=u,i){r=!0;return}i=!0,[a,n]=[n,a],a.forEach(c),a.clear(),i=!1,r&&(r=!1,d.process(u))}};return d}const BH=40;function r4(t,e){let a=!1,n=!0;const i={delta:0,timestamp:0,isProcessing:!1},r=()=>a=!0,o=Op.reduce((S,T)=>(S[T]=FH(r),S),{}),{setup:l,read:c,resolveKeyframes:d,preUpdate:u,update:p,preRender:m,render:h,postRender:g}=o,y=()=>{const S=qi.useManualTiming?i.timestamp:performance.now();a=!1,qi.useManualTiming||(i.delta=n?1e3/60:Math.max(Math.min(S-i.timestamp,BH),1)),i.timestamp=S,i.isProcessing=!0,l.process(i),c.process(i),d.process(i),u.process(i),p.process(i),m.process(i),h.process(i),g.process(i),i.isProcessing=!1,a&&e&&(n=!1,t(y))},x=()=>{a=!0,n=!0,i.isProcessing||t(y)};return{schedule:Op.reduce((S,T)=>{const P=o[T];return S[T]=(M,C=!1,E=!1)=>(a||x(),P.schedule(M,C,E)),S},{}),cancel:S=>{for(let T=0;T<Op.length;T++)o[Op[T]].cancel(S)},state:i,steps:o}}const{schedule:Ne,cancel:Mn,state:Et,steps:r0}=r4(typeof requestAnimationFrame<"u"?requestAnimationFrame:Ta,!0);let Cm;function UH(){Cm=void 0}const pa={now:()=>(Cm===void 0&&pa.set(Et.isProcessing||qi.useManualTiming?Et.timestamp:performance.now()),Cm),set:t=>{Cm=t,queueMicrotask(UH)}},o4=t=>e=>typeof e=="string"&&e.startsWith(t),s4=o4("--"),$H=o4("var(--"),uw=t=>$H(t)?WH.test(t.split("/*")[0].trim()):!1,WH=/var\(--(?:[\w-]+\s*|[\w-]+\s*,(?:\s*[^)(\s]|\s*\((?:[^)(]|\([^)(]*\))*\))+\s*)\)$/iu;function yA(t){return typeof t!="string"?!1:t.split("/*")[0].includes("var(--")}const Ul={test:t=>typeof t=="number",parse:parseFloat,transform:t=>t},Qd={...Ul,transform:t=>On(0,1,t)},Mp={...Ul,default:1},od=t=>Math.round(t*1e5)/1e5,pw=/-?(?:\d+(?:\.\d+)?|\.\d+)/gu;function GH(t){return t==null}const KH=/^(?:#[\da-f]{3,8}|(?:rgb|hsl)a?\((?:-?[\d.]+%?[,\s]+){2}-?[\d.]+%?\s*(?:[,/]\s*)?(?:\b\d+(?:\.\d+)?|\.\d+)?%?\))$/iu,mw=(t,e)=>a=>!!(typeof a=="string"&&KH.test(a)&&a.startsWith(t)||e&&!GH(a)&&Object.prototype.hasOwnProperty.call(a,e)),l4=(t,e,a)=>n=>{if(typeof n!="string")return n;const[i,r,o,l]=n.match(pw);return{[t]:parseFloat(i),[e]:parseFloat(r),[a]:parseFloat(o),alpha:l!==void 0?parseFloat(l):1}},JH=t=>On(0,255,t),o0={...Ul,transform:t=>Math.round(JH(t))},wo={test:mw("rgb","red"),parse:l4("red","green","blue"),transform:({red:t,green:e,blue:a,alpha:n=1})=>"rgba("+o0.transform(t)+", "+o0.transform(e)+", "+o0.transform(a)+", "+od(Qd.transform(n))+")"};function QH(t){let e="",a="",n="",i="";return t.length>5?(e=t.substring(1,3),a=t.substring(3,5),n=t.substring(5,7),i=t.substring(7,9)):(e=t.substring(1,2),a=t.substring(2,3),n=t.substring(3,4),i=t.substring(4,5),e+=e,a+=a,n+=n,i+=i),{red:parseInt(e,16),green:parseInt(a,16),blue:parseInt(n,16),alpha:i?parseInt(i,16)/255:1}}const _v={test:mw("#"),parse:QH,transform:wo.transform},Iu=t=>({test:e=>typeof e=="string"&&e.endsWith(t)&&e.split(" ").length===1,parse:parseFloat,transform:e=>`${e}${t}`}),Yi=Iu("deg"),Zn=Iu("%"),J=Iu("px"),XH=Iu("vh"),YH=Iu("vw"),xA={...Zn,parse:t=>Zn.parse(t)/100,transform:t=>Zn.transform(t*100)},$s={test:mw("hsl","hue"),parse:l4("hue","saturation","lightness"),transform:({hue:t,saturation:e,lightness:a,alpha:n=1})=>"hsla("+Math.round(t)+", "+Zn.transform(od(e))+", "+Zn.transform(od(a))+", "+od(Qd.transform(n))+")"},ht={test:t=>wo.test(t)||_v.test(t)||$s.test(t),parse:t=>wo.test(t)?wo.parse(t):$s.test(t)?$s.parse(t):_v.parse(t),transform:t=>typeof t=="string"?t:t.hasOwnProperty("red")?wo.transform(t):$s.transform(t),getAnimatableNone:t=>{const e=ht.parse(t);return e.alpha=0,ht.transform(e)}},ZH=/(?:#[\da-f]{3,8}|(?:rgb|hsl)a?\((?:-?[\d.]+%?[,\s]+){2}-?[\d.]+%?\s*(?:[,/]\s*)?(?:\b\d+(?:\.\d+)?|\.\d+)?%?\))/giu;function eF(t){var e,a;return isNaN(t)&&typeof t=="string"&&(((e=t.match(pw))==null?void 0:e.length)||0)+(((a=t.match(ZH))==null?void 0:a.length)||0)>0}const c4="number",d4="color",tF="var",aF="var(",vA="${}",nF=/var\s*\(\s*--(?:[\w-]+\s*|[\w-]+\s*,(?:\s*[^)(\s]|\s*\((?:[^)(]|\([^)(]*\))*\))+\s*)\)|#[\da-f]{3,8}|(?:rgb|hsl)a?\((?:-?[\d.]+%?[,\s]+){2}-?[\d.]+%?\s*(?:[,/]\s*)?(?:\b\d+(?:\.\d+)?|\.\d+)?%?\)|-?(?:\d+(?:\.\d+)?|\.\d+)/giu;function Xd(t){const e=t.toString(),a=[],n={color:[],number:[],var:[]},i=[];let r=0;const l=e.replace(nF,c=>(ht.test(c)?(n.color.push(r),i.push(d4),a.push(ht.parse(c))):c.startsWith(aF)?(n.var.push(r),i.push(tF),a.push(c)):(n.number.push(r),i.push(c4),a.push(parseFloat(c))),++r,vA)).split(vA);return{values:a,split:l,indexes:n,types:i}}function u4(t){return Xd(t).values}function p4(t){const{split:e,types:a}=Xd(t),n=e.length;return i=>{let r="";for(let o=0;o<n;o++)if(r+=e[o],i[o]!==void 0){const l=a[o];l===c4?r+=od(i[o]):l===d4?r+=ht.transform(i[o]):r+=i[o]}return r}}const iF=t=>typeof t=="number"?0:ht.test(t)?ht.getAnimatableNone(t):t;function rF(t){const e=u4(t);return p4(t)(e.map(iF))}const Vr={test:eF,parse:u4,createTransformer:p4,getAnimatableNone:rF};function s0(t,e,a){return a<0&&(a+=1),a>1&&(a-=1),a<1/6?t+(e-t)*6*a:a<1/2?e:a<2/3?t+(e-t)*(2/3-a)*6:t}function oF({hue:t,saturation:e,lightness:a,alpha:n}){t/=360,e/=100,a/=100;let i=0,r=0,o=0;if(!e)i=r=o=a;else{const l=a<.5?a*(1+e):a+e-a*e,c=2*a-l;i=s0(c,l,t+1/3),r=s0(c,l,t),o=s0(c,l,t-1/3)}return{red:Math.round(i*255),green:Math.round(r*255),blue:Math.round(o*255),alpha:n}}function wh(t,e){return a=>a>0?e:t}const Xe=(t,e,a)=>t+(e-t)*a,l0=(t,e,a)=>{const n=t*t,i=a*(e*e-n)+n;return i<0?0:Math.sqrt(i)},sF=[_v,wo,$s],lF=t=>sF.find(e=>e.test(t));function bA(t){const e=lF(t);if(!e)return!1;let a=e.parse(t);return e===$s&&(a=oF(a)),a}const wA=(t,e)=>{const a=bA(t),n=bA(e);if(!a||!n)return wh(t,e);const i={...a};return r=>(i.red=l0(a.red,n.red,r),i.green=l0(a.green,n.green,r),i.blue=l0(a.blue,n.blue,r),i.alpha=Xe(a.alpha,n.alpha,r),wo.transform(i))},Av=new Set(["none","hidden"]);function cF(t,e){return Av.has(t)?a=>a<=0?t:e:a=>a>=1?e:t}function dF(t,e){return a=>Xe(t,e,a)}function hw(t){return typeof t=="number"?dF:typeof t=="string"?uw(t)?wh:ht.test(t)?wA:mF:Array.isArray(t)?m4:typeof t=="object"?ht.test(t)?wA:uF:wh}function m4(t,e){const a=[...t],n=a.length,i=t.map((r,o)=>hw(r)(r,e[o]));return r=>{for(let o=0;o<n;o++)a[o]=i[o](r);return a}}function uF(t,e){const a={...t,...e},n={};for(const i in a)t[i]!==void 0&&e[i]!==void 0&&(n[i]=hw(t[i])(t[i],e[i]));return i=>{for(const r in n)a[r]=n[r](i);return a}}function pF(t,e){const a=[],n={color:0,var:0,number:0};for(let i=0;i<e.values.length;i++){const r=e.types[i],o=t.indexes[r][n[r]],l=t.values[o]??0;a[i]=l,n[r]++}return a}const mF=(t,e)=>{const a=Vr.createTransformer(e),n=Xd(t),i=Xd(e);return n.indexes.var.length===i.indexes.var.length&&n.indexes.color.length===i.indexes.color.length&&n.indexes.number.length>=i.indexes.number.length?Av.has(t)&&!i.values.length||Av.has(e)&&!n.values.length?cF(t,e):Tu(m4(pF(n,i),i.values),a):wh(t,e)};function h4(t,e,a){return typeof t=="number"&&typeof e=="number"&&typeof a=="number"?Xe(t,e,a):hw(t)(t,e)}const hF=t=>{const e=({timestamp:a})=>t(a);return{start:(a=!0)=>Ne.update(e,a),stop:()=>Mn(e),now:()=>Et.isProcessing?Et.timestamp:pa.now()}},f4=(t,e,a=10)=>{let n="";const i=Math.max(Math.round(e/a),2);for(let r=0;r<i;r++)n+=Math.round(t(r/(i-1))*1e4)/1e4+", ";return`linear(${n.substring(0,n.length-2)})`},kh=2e4;function fw(t){let e=0;const a=50;let n=t.next(e);for(;!n.done&&e<kh;)e+=a,n=t.next(e);return e>=kh?1/0:e}function fF(t,e=100,a){const n=a({...t,keyframes:[0,e]}),i=Math.min(fw(n),kh);return{type:"keyframes",ease:r=>n.next(i*r).value/e,duration:ln(i)}}const gF=5;function g4(t,e,a){const n=Math.max(e-gF,0);return lw(a-t(n),e-n)}const rt={stiffness:100,damping:10,mass:1,velocity:0,duration:800,bounce:.3,visualDuration:.3,restSpeed:{granular:.01,default:2},restDelta:{granular:.005,default:.5},minDuration:.01,maxDuration:10,minDamping:.05,maxDamping:1},c0=.001;function yF({duration:t=rt.duration,bounce:e=rt.bounce,velocity:a=rt.velocity,mass:n=rt.mass}){let i,r,o=1-e;o=On(rt.minDamping,rt.maxDamping,o),t=On(rt.minDuration,rt.maxDuration,ln(t)),o<1?(i=d=>{const u=d*o,p=u*t,m=u-a,h=Ev(d,o),g=Math.exp(-p);return c0-m/h*g},r=d=>{const p=d*o*t,m=p*a+a,h=Math.pow(o,2)*Math.pow(d,2)*t,g=Math.exp(-p),y=Ev(Math.pow(d,2),o);return(-i(d)+c0>0?-1:1)*((m-h)*g)/y}):(i=d=>{const u=Math.exp(-d*t),p=(d-a)*t+1;return-c0+u*p},r=d=>{const u=Math.exp(-d*t),p=(a-d)*(t*t);return u*p});const l=5/t,c=vF(i,r,l);if(t=ji(t),isNaN(c))return{stiffness:rt.stiffness,damping:rt.damping,duration:t};{const d=Math.pow(c,2)*n;return{stiffness:d,damping:o*2*Math.sqrt(n*d),duration:t}}}const xF=12;function vF(t,e,a){let n=a;for(let i=1;i<xF;i++)n=n-t(n)/e(n);return n}function Ev(t,e){return t*Math.sqrt(1-e*e)}const bF=["duration","bounce"],wF=["stiffness","damping","mass"];function kA(t,e){return e.some(a=>t[a]!==void 0)}function kF(t){let e={velocity:rt.velocity,stiffness:rt.stiffness,damping:rt.damping,mass:rt.mass,isResolvedFromDuration:!1,...t};if(!kA(t,wF)&&kA(t,bF))if(t.visualDuration){const a=t.visualDuration,n=2*Math.PI/(a*1.2),i=n*n,r=2*On(.05,1,1-(t.bounce||0))*Math.sqrt(i);e={...e,mass:rt.mass,stiffness:i,damping:r}}else{const a=yF(t);e={...e,...a,mass:rt.mass},e.isResolvedFromDuration=!0}return e}function Sh(t=rt.visualDuration,e=rt.bounce){const a=typeof t!="object"?{visualDuration:t,keyframes:[0,1],bounce:e}:t;let{restSpeed:n,restDelta:i}=a;const r=a.keyframes[0],o=a.keyframes[a.keyframes.length-1],l={done:!1,value:r},{stiffness:c,damping:d,mass:u,duration:p,velocity:m,isResolvedFromDuration:h}=kF({...a,velocity:-ln(a.velocity||0)}),g=m||0,y=d/(2*Math.sqrt(c*u)),x=o-r,v=ln(Math.sqrt(c/u)),w=Math.abs(x)<5;n||(n=w?rt.restSpeed.granular:rt.restSpeed.default),i||(i=w?rt.restDelta.granular:rt.restDelta.default);let S;if(y<1){const P=Ev(v,y);S=M=>{const C=Math.exp(-y*v*M);return o-C*((g+y*v*x)/P*Math.sin(P*M)+x*Math.cos(P*M))}}else if(y===1)S=P=>o-Math.exp(-v*P)*(x+(g+v*x)*P);else{const P=v*Math.sqrt(y*y-1);S=M=>{const C=Math.exp(-y*v*M),E=Math.min(P*M,300);return o-C*((g+y*v*x)*Math.sinh(E)+P*x*Math.cosh(E))/P}}const T={calculatedDuration:h&&p||null,next:P=>{const M=S(P);if(h)l.done=P>=p;else{let C=P===0?g:0;y<1&&(C=P===0?ji(g):g4(S,P,M));const E=Math.abs(C)<=n,j=Math.abs(o-M)<=i;l.done=E&&j}return l.value=l.done?o:M,l},toString:()=>{const P=Math.min(fw(T),kh),M=f4(C=>T.next(P*C).value,P,30);return P+"ms "+M},toTransition:()=>{}};return T}Sh.applyToOptions=t=>{const e=fF(t,100,Sh);return t.ease=e.ease,t.duration=ji(e.duration),t.type="keyframes",t};function Cv({keyframes:t,velocity:e=0,power:a=.8,timeConstant:n=325,bounceDamping:i=10,bounceStiffness:r=500,modifyTarget:o,min:l,max:c,restDelta:d=.5,restSpeed:u}){const p=t[0],m={done:!1,value:p},h=E=>l!==void 0&&E<l||c!==void 0&&E>c,g=E=>l===void 0?c:c===void 0||Math.abs(l-E)<Math.abs(c-E)?l:c;let y=a*e;const x=p+y,v=o===void 0?x:o(x);v!==x&&(y=v-p);const w=E=>-y*Math.exp(-E/n),S=E=>v+w(E),T=E=>{const j=w(E),N=S(E);m.done=Math.abs(j)<=d,m.value=m.done?v:N};let P,M;const C=E=>{h(m.value)&&(P=E,M=Sh({keyframes:[m.value,g(m.value)],velocity:g4(S,E,m.value),damping:i,stiffness:r,restDelta:d,restSpeed:u}))};return C(0),{calculatedDuration:null,next:E=>{let j=!1;return!M&&P===void 0&&(j=!0,T(E),C(E)),P!==void 0&&E>=P?M.next(E-P):(!j&&T(E),m)}}}function SF(t,e,a){const n=[],i=a||qi.mix||h4,r=t.length-1;for(let o=0;o<r;o++){let l=i(t[o],t[o+1]);if(e){const c=Array.isArray(e)?e[o]||Ta:e;l=Tu(c,l)}n.push(l)}return n}function gw(t,e,{clamp:a=!0,ease:n,mixer:i}={}){const r=t.length;if(Jd(r===e.length),r===1)return()=>e[0];if(r===2&&e[0]===e[1])return()=>e[1];const o=t[0]===t[1];t[0]>t[r-1]&&(t=[...t].reverse(),e=[...e].reverse());const l=SF(e,n,i),c=l.length,d=u=>{if(o&&u<t[0])return e[0];let p=0;if(c>1)for(;p<t.length-2&&!(u<t[p+1]);p++);const m=bl(t[p],t[p+1],u);return l[p](m)};return a?u=>d(On(t[0],t[r-1],u)):d}function _F(t,e){const a=t[t.length-1];for(let n=1;n<=e;n++){const i=bl(0,e,n);t.push(Xe(a,1,i))}}function y4(t){const e=[0];return _F(e,t.length-1),e}function AF(t,e){return t.map(a=>a*e)}function EF(t,e){return t.map(()=>e||n4).splice(0,t.length-1)}function sd({duration:t=300,keyframes:e,times:a,ease:n="easeInOut"}){const i=zH(n)?n.map(gA):gA(n),r={done:!1,value:e[0]},o=AF(a&&a.length===e.length?a:y4(e),t),l=gw(o,e,{ease:Array.isArray(i)?i:EF(e,i)});return{calculatedDuration:t,next:c=>(r.value=l(c),r.done=c>=t,r)}}const CF=t=>t!==null;function yw(t,{repeat:e,repeatType:a="loop"},n,i=1){const r=t.filter(CF),l=i<0||e&&a!=="loop"&&e%2===1?0:r.length-1;return!l||n===void 0?r[l]:n}const jF={decay:Cv,inertia:Cv,tween:sd,keyframes:sd,spring:Sh};function x4(t){typeof t.type=="string"&&(t.type=jF[t.type])}class xw{constructor(){this.updateFinished()}get finished(){return this._finished}updateFinished(){this._finished=new Promise(e=>{this.resolve=e})}notifyFinished(){this.resolve()}then(e,a){return this.finished.then(e,a)}}const TF=t=>t/100;class vw extends xw{constructor(e){super(),this.state="idle",this.startTime=null,this.isStopped=!1,this.currentTime=0,this.holdTime=null,this.playbackSpeed=1,this.stop=()=>{var n,i;const{motionValue:a}=this.options;a&&a.updatedAt!==pa.now()&&this.tick(pa.now()),this.isStopped=!0,this.state!=="idle"&&(this.teardown(),(i=(n=this.options).onStop)==null||i.call(n))},this.options=e,this.initAnimation(),this.play(),e.autoplay===!1&&this.pause()}initAnimation(){const{options:e}=this;x4(e);const{type:a=sd,repeat:n=0,repeatDelay:i=0,repeatType:r,velocity:o=0}=e;let{keyframes:l}=e;const c=a||sd;c!==sd&&typeof l[0]!="number"&&(this.mixKeyframes=Tu(TF,h4(l[0],l[1])),l=[0,100]);const d=c({...e,keyframes:l});r==="mirror"&&(this.mirroredGenerator=c({...e,keyframes:[...l].reverse(),velocity:-o})),d.calculatedDuration===null&&(d.calculatedDuration=fw(d));const{calculatedDuration:u}=d;this.calculatedDuration=u,this.resolvedDuration=u+i,this.totalDuration=this.resolvedDuration*(n+1)-i,this.generator=d}updateTime(e){const a=Math.round(e-this.startTime)*this.playbackSpeed;this.holdTime!==null?this.currentTime=this.holdTime:this.currentTime=a}tick(e,a=!1){const{generator:n,totalDuration:i,mixKeyframes:r,mirroredGenerator:o,resolvedDuration:l,calculatedDuration:c}=this;if(this.startTime===null)return n.next(0);const{delay:d=0,keyframes:u,repeat:p,repeatType:m,repeatDelay:h,type:g,onUpdate:y,finalKeyframe:x}=this.options;this.speed>0?this.startTime=Math.min(this.startTime,e):this.speed<0&&(this.startTime=Math.min(e-i/this.speed,this.startTime)),a?this.currentTime=e:this.updateTime(e);const v=this.currentTime-d*(this.playbackSpeed>=0?1:-1),w=this.playbackSpeed>=0?v<0:v>i;this.currentTime=Math.max(v,0),this.state==="finished"&&this.holdTime===null&&(this.currentTime=i);let S=this.currentTime,T=n;if(p){const E=Math.min(this.currentTime,i)/l;let j=Math.floor(E),N=E%1;!N&&E>=1&&(N=1),N===1&&j--,j=Math.min(j,p+1),!!(j%2)&&(m==="reverse"?(N=1-N,h&&(N-=h/l)):m==="mirror"&&(T=o)),S=On(0,1,N)*l}const P=w?{done:!1,value:u[0]}:T.next(S);r&&(P.value=r(P.value));let{done:M}=P;!w&&c!==null&&(M=this.playbackSpeed>=0?this.currentTime>=i:this.currentTime<=0);const C=this.holdTime===null&&(this.state==="finished"||this.state==="running"&&M);return C&&g!==Cv&&(P.value=yw(u,this.options,x,this.speed)),y&&y(P.value),C&&this.finish(),P}then(e,a){return this.finished.then(e,a)}get duration(){return ln(this.calculatedDuration)}get iterationDuration(){const{delay:e=0}=this.options||{};return this.duration+ln(e)}get time(){return ln(this.currentTime)}set time(e){var a;e=ji(e),this.currentTime=e,this.startTime===null||this.holdTime!==null||this.playbackSpeed===0?this.holdTime=e:this.driver&&(this.startTime=this.driver.now()-e/this.playbackSpeed),(a=this.driver)==null||a.start(!1)}get speed(){return this.playbackSpeed}set speed(e){this.updateTime(pa.now());const a=this.playbackSpeed!==e;this.playbackSpeed=e,a&&(this.time=ln(this.currentTime))}play(){var i,r;if(this.isStopped)return;const{driver:e=hF,startTime:a}=this.options;this.driver||(this.driver=e(o=>this.tick(o))),(r=(i=this.options).onPlay)==null||r.call(i);const n=this.driver.now();this.state==="finished"?(this.updateFinished(),this.startTime=n):this.holdTime!==null?this.startTime=n-this.holdTime:this.startTime||(this.startTime=a??n),this.state==="finished"&&this.speed<0&&(this.startTime+=this.calculatedDuration),this.holdTime=null,this.state="running",this.driver.start()}pause(){this.state="paused",this.updateTime(pa.now()),this.holdTime=this.currentTime}complete(){this.state!=="running"&&this.play(),this.state="finished",this.holdTime=null}finish(){var e,a;this.notifyFinished(),this.teardown(),this.state="finished",(a=(e=this.options).onComplete)==null||a.call(e)}cancel(){var e,a;this.holdTime=null,this.startTime=0,this.tick(0),this.teardown(),(a=(e=this.options).onCancel)==null||a.call(e)}teardown(){this.state="idle",this.stopDriver(),this.startTime=this.holdTime=null}stopDriver(){this.driver&&(this.driver.stop(),this.driver=void 0)}sample(e){return this.startTime=0,this.tick(e,!0)}attachTimeline(e){var a;return this.options.allowFlatten&&(this.options.type="keyframes",this.options.ease="linear",this.initAnimation()),(a=this.driver)==null||a.stop(),e.observe(this)}}function NF(t){for(let e=1;e<t.length;e++)t[e]??(t[e]=t[e-1])}const ko=t=>t*180/Math.PI,jv=t=>{const e=ko(Math.atan2(t[1],t[0]));return Tv(e)},IF={x:4,y:5,translateX:4,translateY:5,scaleX:0,scaleY:3,scale:t=>(Math.abs(t[0])+Math.abs(t[3]))/2,rotate:jv,rotateZ:jv,skewX:t=>ko(Math.atan(t[1])),skewY:t=>ko(Math.atan(t[2])),skew:t=>(Math.abs(t[1])+Math.abs(t[2]))/2},Tv=t=>(t=t%360,t<0&&(t+=360),t),SA=jv,_A=t=>Math.sqrt(t[0]*t[0]+t[1]*t[1]),AA=t=>Math.sqrt(t[4]*t[4]+t[5]*t[5]),PF={x:12,y:13,z:14,translateX:12,translateY:13,translateZ:14,scaleX:_A,scaleY:AA,scale:t=>(_A(t)+AA(t))/2,rotateX:t=>Tv(ko(Math.atan2(t[6],t[5]))),rotateY:t=>Tv(ko(Math.atan2(-t[2],t[0]))),rotateZ:SA,rotate:SA,skewX:t=>ko(Math.atan(t[4])),skewY:t=>ko(Math.atan(t[1])),skew:t=>(Math.abs(t[1])+Math.abs(t[4]))/2};function Nv(t){return t.includes("scale")?1:0}function Iv(t,e){if(!t||t==="none")return Nv(e);const a=t.match(/^matrix3d\(([-\d.e\s,]+)\)$/u);let n,i;if(a)n=PF,i=a;else{const l=t.match(/^matrix\(([-\d.e\s,]+)\)$/u);n=IF,i=l}if(!i)return Nv(e);const r=n[e],o=i[1].split(",").map(LF);return typeof r=="function"?r(o):o[r]}const RF=(t,e)=>{const{transform:a="none"}=getComputedStyle(t);return Iv(a,e)};function LF(t){return parseFloat(t.trim())}const $l=["transformPerspective","x","y","z","translateX","translateY","translateZ","scale","scaleX","scaleY","rotate","rotateX","rotateY","rotateZ","skew","skewX","skewY"],Wl=new Set($l),EA=t=>t===Ul||t===J,OF=new Set(["x","y","z"]),MF=$l.filter(t=>!OF.has(t));function DF(t){const e=[];return MF.forEach(a=>{const n=t.getValue(a);n!==void 0&&(e.push([a,n.get()]),n.set(a.startsWith("scale")?1:0))}),e}const gr={width:({x:t},{paddingLeft:e="0",paddingRight:a="0"})=>t.max-t.min-parseFloat(e)-parseFloat(a),height:({y:t},{paddingTop:e="0",paddingBottom:a="0"})=>t.max-t.min-parseFloat(e)-parseFloat(a),top:(t,{top:e})=>parseFloat(e),left:(t,{left:e})=>parseFloat(e),bottom:({y:t},{top:e})=>parseFloat(e)+(t.max-t.min),right:({x:t},{left:e})=>parseFloat(e)+(t.max-t.min),x:(t,{transform:e})=>Iv(e,"x"),y:(t,{transform:e})=>Iv(e,"y")};gr.translateX=gr.x;gr.translateY=gr.y;const Ro=new Set;let Pv=!1,Rv=!1,Lv=!1;function v4(){if(Rv){const t=Array.from(Ro).filter(n=>n.needsMeasurement),e=new Set(t.map(n=>n.element)),a=new Map;e.forEach(n=>{const i=DF(n);i.length&&(a.set(n,i),n.render())}),t.forEach(n=>n.measureInitialState()),e.forEach(n=>{n.render();const i=a.get(n);i&&i.forEach(([r,o])=>{var l;(l=n.getValue(r))==null||l.set(o)})}),t.forEach(n=>n.measureEndState()),t.forEach(n=>{n.suspendedScrollY!==void 0&&window.scrollTo(0,n.suspendedScrollY)})}Rv=!1,Pv=!1,Ro.forEach(t=>t.complete(Lv)),Ro.clear()}function b4(){Ro.forEach(t=>{t.readKeyframes(),t.needsMeasurement&&(Rv=!0)})}function qF(){Lv=!0,b4(),v4(),Lv=!1}class bw{constructor(e,a,n,i,r,o=!1){this.state="pending",this.isAsync=!1,this.needsMeasurement=!1,this.unresolvedKeyframes=[...e],this.onComplete=a,this.name=n,this.motionValue=i,this.element=r,this.isAsync=o}scheduleResolve(){this.state="scheduled",this.isAsync?(Ro.add(this),Pv||(Pv=!0,Ne.read(b4),Ne.resolveKeyframes(v4))):(this.readKeyframes(),this.complete())}readKeyframes(){const{unresolvedKeyframes:e,name:a,element:n,motionValue:i}=this;if(e[0]===null){const r=i==null?void 0:i.get(),o=e[e.length-1];if(r!==void 0)e[0]=r;else if(n&&a){const l=n.readValue(a,o);l!=null&&(e[0]=l)}e[0]===void 0&&(e[0]=o),i&&r===void 0&&i.set(e[0])}NF(e)}setFinalKeyframe(){}measureInitialState(){}renderEndStyles(){}measureEndState(){}complete(e=!1){this.state="complete",this.onComplete(this.unresolvedKeyframes,this.finalKeyframe,e),Ro.delete(this)}cancel(){this.state==="scheduled"&&(Ro.delete(this),this.state="pending")}resume(){this.state==="pending"&&this.scheduleResolve()}}const zF=t=>t.startsWith("--");function VF(t,e,a){zF(e)?t.style.setProperty(e,a):t.style[e]=a}const w4=ow(()=>window.ScrollTimeline!==void 0),HF={};function FF(t,e){const a=ow(t);return()=>HF[e]??a()}const k4=FF(()=>{try{document.createElement("div").animate({opacity:0},{easing:"linear(0, 1)"})}catch{return!1}return!0},"linearEasing"),qc=([t,e,a,n])=>`cubic-bezier(${t}, ${e}, ${a}, ${n})`,CA={linear:"linear",ease:"ease",easeIn:"ease-in",easeOut:"ease-out",easeInOut:"ease-in-out",circIn:qc([0,.65,.55,1]),circOut:qc([.55,0,1,.45]),backIn:qc([.31,.01,.66,-.59]),backOut:qc([.33,1.53,.69,.99])};function S4(t,e){if(t)return typeof t=="function"?k4()?f4(t,e):"ease-out":i4(t)?qc(t):Array.isArray(t)?t.map(a=>S4(a,e)||CA.easeOut):CA[t]}function BF(t,e,a,{delay:n=0,duration:i=300,repeat:r=0,repeatType:o="loop",ease:l="easeOut",times:c}={},d=void 0){const u={[e]:a};c&&(u.offset=c);const p=S4(l,i);Array.isArray(p)&&(u.easing=p);const m={delay:n,duration:i,easing:Array.isArray(p)?"linear":p,fill:"both",iterations:r+1,direction:o==="reverse"?"alternate":"normal"};return d&&(m.pseudoElement=d),t.animate(u,m)}function _4(t){return typeof t=="function"&&"applyToOptions"in t}function UF({type:t,...e}){return _4(t)&&k4()?t.applyToOptions(e):(e.duration??(e.duration=300),e.ease??(e.ease="easeOut"),e)}class $F extends xw{constructor(e){if(super(),this.finishedTime=null,this.isStopped=!1,this.manualStartTime=null,!e)return;const{element:a,name:n,keyframes:i,pseudoElement:r,allowFlatten:o=!1,finalKeyframe:l,onComplete:c}=e;this.isPseudoElement=!!r,this.allowFlatten=o,this.options=e,Jd(typeof e.type!="string");const d=UF(e);this.animation=BF(a,n,i,d,r),d.autoplay===!1&&this.animation.pause(),this.animation.onfinish=()=>{if(this.finishedTime=this.time,!r){const u=yw(i,this.options,l,this.speed);this.updateMotionValue?this.updateMotionValue(u):VF(a,n,u),this.animation.cancel()}c==null||c(),this.notifyFinished()}}play(){this.isStopped||(this.manualStartTime=null,this.animation.play(),this.state==="finished"&&this.updateFinished())}pause(){this.animation.pause()}complete(){var e,a;(a=(e=this.animation).finish)==null||a.call(e)}cancel(){try{this.animation.cancel()}catch{}}stop(){if(this.isStopped)return;this.isStopped=!0;const{state:e}=this;e==="idle"||e==="finished"||(this.updateMotionValue?this.updateMotionValue():this.commitStyles(),this.isPseudoElement||this.cancel())}commitStyles(){var e,a;this.isPseudoElement||(a=(e=this.animation).commitStyles)==null||a.call(e)}get duration(){var a,n;const e=((n=(a=this.animation.effect)==null?void 0:a.getComputedTiming)==null?void 0:n.call(a).duration)||0;return ln(Number(e))}get iterationDuration(){const{delay:e=0}=this.options||{};return this.duration+ln(e)}get time(){return ln(Number(this.animation.currentTime)||0)}set time(e){this.manualStartTime=null,this.finishedTime=null,this.animation.currentTime=ji(e)}get speed(){return this.animation.playbackRate}set speed(e){e<0&&(this.finishedTime=null),this.animation.playbackRate=e}get state(){return this.finishedTime!==null?"finished":this.animation.playState}get startTime(){return this.manualStartTime??Number(this.animation.startTime)}set startTime(e){this.manualStartTime=this.animation.startTime=e}attachTimeline({timeline:e,observe:a}){var n;return this.allowFlatten&&((n=this.animation.effect)==null||n.updateTiming({easing:"linear"})),this.animation.onfinish=null,e&&w4()?(this.animation.timeline=e,Ta):a(this)}}const A4={anticipate:e4,backInOut:ZP,circInOut:a4};function WF(t){return t in A4}function GF(t){typeof t.ease=="string"&&WF(t.ease)&&(t.ease=A4[t.ease])}const d0=10;class KF extends $F{constructor(e){GF(e),x4(e),super(e),e.startTime!==void 0&&(this.startTime=e.startTime),this.options=e}updateMotionValue(e){const{motionValue:a,onUpdate:n,onComplete:i,element:r,...o}=this.options;if(!a)return;if(e!==void 0){a.set(e);return}const l=new vw({...o,autoplay:!1}),c=Math.max(d0,pa.now()-this.startTime),d=On(0,d0,c-d0);a.setWithVelocity(l.sample(Math.max(0,c-d)).value,l.sample(c).value,d),l.stop()}}const jA=(t,e)=>e==="zIndex"?!1:!!(typeof t=="number"||Array.isArray(t)||typeof t=="string"&&(Vr.test(t)||t==="0")&&!t.startsWith("url("));function JF(t){const e=t[0];if(t.length===1)return!0;for(let a=0;a<t.length;a++)if(t[a]!==e)return!0}function QF(t,e,a,n){const i=t[0];if(i===null)return!1;if(e==="display"||e==="visibility")return!0;const r=t[t.length-1],o=jA(i,e),l=jA(r,e);return!o||!l?!1:JF(t)||(a==="spring"||_4(a))&&n}function Ov(t){t.duration=0,t.type="keyframes"}const XF=new Set(["opacity","clipPath","filter","transform"]),YF=ow(()=>Object.hasOwnProperty.call(Element.prototype,"animate"));function ZF(t){var u;const{motionValue:e,name:a,repeatDelay:n,repeatType:i,damping:r,type:o}=t;if(!(((u=e==null?void 0:e.owner)==null?void 0:u.current)instanceof HTMLElement))return!1;const{onUpdate:c,transformTemplate:d}=e.owner.getProps();return YF()&&a&&XF.has(a)&&(a!=="transform"||!d)&&!c&&!n&&i!=="mirror"&&r!==0&&o!=="inertia"}const e7=40;class t7 extends xw{constructor({autoplay:e=!0,delay:a=0,type:n="keyframes",repeat:i=0,repeatDelay:r=0,repeatType:
59o="loop",keyframes:l,name:c,motionValue:d,element:u,...p}){var g;super(),this.stop=()=>{var y,x;this._animation&&(this._animation.stop(),(y=this.stopTimeline)==null||y.call(this)),(x=this.keyframeResolver)==null||x.cancel()},this.createdAt=pa.now();const m={autoplay:e,delay:a,type:n,repeat:i,repeatDelay:r,repeatType:o,name:c,motionValue:d,element:u,...p},h=(u==null?void 0:u.KeyframeResolver)||bw;this.keyframeResolver=new h(l,(y,x,v)=>this.onKeyframesResolved(y,x,m,!v),c,d,u),(g=this.keyframeResolver)==null||g.scheduleResolve()}onKeyframesResolved(e,a,n,i){this.keyframeResolver=void 0;const{name:r,type:o,velocity:l,delay:c,isHandoff:d,onUpdate:u}=n;this.resolvedAt=pa.now(),QF(e,r,o,l)||((qi.instantAnimations||!c)&&(u==null||u(yw(e,n,a))),e[0]=e[e.length-1],Ov(n),n.repeat=0);const m={startTime:i?this.resolvedAt?this.resolvedAt-this.createdAt>e7?this.resolvedAt:this.createdAt:this.createdAt:void 0,finalKeyframe:a,...n,keyframes:e},h=!d&&ZF(m)?new KF({...m,element:m.motionValue.owner.current}):new vw(m);h.finished.then(()=>this.notifyFinished()).catch(Ta),this.pendingTimeline&&(this.stopTimeline=h.attachTimeline(this.pendingTimeline),this.pendingTimeline=void 0),this._animation=h}get finished(){return this._animation?this.animation.finished:this._finished}then(e,a){return this.finished.finally(e).then(()=>{})}get animation(){var e;return this._animation||((e=this.keyframeResolver)==null||e.resume(),qF()),this._animation}get duration(){return this.animation.duration}get iterationDuration(){return this.animation.iterationDuration}get time(){return this.animation.time}set time(e){this.animation.time=e}get speed(){return this.animation.speed}get state(){return this.animation.state}set speed(e){this.animation.speed=e}get startTime(){return this.animation.startTime}attachTimeline(e){return this._animation?this.stopTimeline=this.animation.attachTimeline(e):this.pendingTimeline=e,()=>this.stop()}play(){this.animation.play()}pause(){this.animation.pause()}complete(){this.animation.complete()}cancel(){var e;this._animation&&this.animation.cancel(),(e=this.keyframeResolver)==null||e.cancel()}}const a7=/^var\(--(?:([\w-]+)|([\w-]+), ?([a-zA-Z\d ()%#.,-]+))\)/u;function n7(t){const e=a7.exec(t);if(!e)return[,];const[,a,n,i]=e;return[`--${a??n}`,i]}function E4(t,e,a=1){const[n,i]=n7(t);if(!n)return;const r=window.getComputedStyle(e).getPropertyValue(n);if(r){const o=r.trim();return WP(o)?parseFloat(o):o}return uw(i)?E4(i,e,a+1):i}function ww(t,e){return(t==null?void 0:t[e])??(t==null?void 0:t.default)??t}const i7={type:"spring",stiffness:500,damping:25,restSpeed:10},r7=t=>({type:"spring",stiffness:550,damping:t===0?2*Math.sqrt(550):30,restSpeed:10}),o7={type:"keyframes",duration:.8},s7={type:"keyframes",ease:[.25,.1,.35,1],duration:.3},l7=(t,{keyframes:e})=>e.length>2?o7:Wl.has(t)?t.startsWith("scale")?r7(e[1]):i7:s7;function c7({when:t,delay:e,delayChildren:a,staggerChildren:n,staggerDirection:i,repeat:r,repeatType:o,repeatDelay:l,from:c,elapsed:d,...u}){return!!Object.keys(u).length}const d7=t=>t!==null;function u7(t,{repeat:e,repeatType:a="loop"},n){const i=t.filter(d7),r=e&&a!=="loop"&&e%2===1?0:i.length-1;return i[r]}function C4(t,e,a,n=0,i=1){const r=Array.from(t).sort((d,u)=>d.sortNodePosition(u)).indexOf(e),o=t.size,l=(o-1)*n;return typeof a=="function"?a(r,o):i===1?r*n:l-r*n}const kw=(t,e,a,n={},i,r)=>o=>{const l=ww(n,t)||{},c=l.delay||n.delay||0;let{elapsed:d=0}=n;d=d-ji(c);const u={keyframes:Array.isArray(a)?a:[null,a],ease:"easeOut",velocity:e.getVelocity(),...l,delay:-d,onUpdate:m=>{e.set(m),l.onUpdate&&l.onUpdate(m)},onComplete:()=>{o(),l.onComplete&&l.onComplete()},name:t,motionValue:e,element:r?void 0:i};c7(l)||Object.assign(u,l7(t,u)),u.duration&&(u.duration=ji(u.duration)),u.repeatDelay&&(u.repeatDelay=ji(u.repeatDelay)),u.from!==void 0&&(u.keyframes[0]=u.from);let p=!1;if((u.type===!1||u.duration===0&&!u.repeatDelay)&&(Ov(u),u.delay===0&&(p=!0)),(qi.instantAnimations||qi.skipAnimations)&&(p=!0,Ov(u),u.delay=0),u.allowFlatten=!l.type&&!l.ease,p&&!r&&e.get()!==void 0){const m=u7(u.keyframes,l);if(m!==void 0){Ne.update(()=>{u.onUpdate(m),u.onComplete()});return}}return l.isSync?new vw(u):new t7(u)},j4=new Set(["width","height","top","left","right","bottom",...$l]),TA=30,p7=t=>!isNaN(parseFloat(t)),ld={current:void 0};class m7{constructor(e,a={}){this.canTrackVelocity=null,this.events={},this.updateAndNotify=n=>{var r;const i=pa.now();if(this.updatedAt!==i&&this.setPrevFrameValue(),this.prev=this.current,this.setCurrent(n),this.current!==this.prev&&((r=this.events.change)==null||r.notify(this.current),this.dependents))for(const o of this.dependents)o.dirty()},this.hasAnimated=!1,this.setCurrent(e),this.owner=a.owner}setCurrent(e){this.current=e,this.updatedAt=pa.now(),this.canTrackVelocity===null&&e!==void 0&&(this.canTrackVelocity=p7(this.current))}setPrevFrameValue(e=this.current){this.prevFrameValue=e,this.prevUpdatedAt=this.updatedAt}onChange(e){return this.on("change",e)}on(e,a){this.events[e]||(this.events[e]=new sw);const n=this.events[e].add(a);return e==="change"?()=>{n(),Ne.read(()=>{this.events.change.getSize()||this.stop()})}:n}clearListeners(){for(const e in this.events)this.events[e].clear()}attach(e,a){this.passiveEffect=e,this.stopPassiveEffect=a}set(e){this.passiveEffect?this.passiveEffect(e,this.updateAndNotify):this.updateAndNotify(e)}setWithVelocity(e,a,n){this.set(a),this.prev=void 0,this.prevFrameValue=e,this.prevUpdatedAt=this.updatedAt-n}jump(e,a=!0){this.updateAndNotify(e),this.prev=e,this.prevUpdatedAt=this.prevFrameValue=void 0,a&&this.stop(),this.stopPassiveEffect&&this.stopPassiveEffect()}dirty(){var e;(e=this.events.change)==null||e.notify(this.current)}addDependent(e){this.dependents||(this.dependents=new Set),this.dependents.add(e)}removeDependent(e){this.dependents&&this.dependents.delete(e)}get(){return ld.current&&ld.current.push(this),this.current}getPrevious(){return this.prev}getVelocity(){const e=pa.now();if(!this.canTrackVelocity||this.prevFrameValue===void 0||e-this.updatedAt>TA)return 0;const a=Math.min(this.updatedAt-this.prevUpdatedAt,TA);return lw(parseFloat(this.current)-parseFloat(this.prevFrameValue),a)}start(e){return this.stop(),new Promise(a=>
vendor: 7,426 bytes, line 59
59{this.hasAnimated=!0,this.animation=e(a),this.events.animationStart&&this.events.animationStart.notify()}).then(()=>{this.events.animationComplete&&this.events.animationComplete.notify(),this.clearAnimation()})}stop(){this.animation&&(this.animation.stop(),this.events.animationCancel&&this.events.animationCancel.notify()),this.clearAnimation()}isAnimating(){return!!this.animation}clearAnimation(){delete this.animation}destroy(){var e,a;(e=this.dependents)==null||e.clear(),(a=this.events.destroy)==null||a.notify(),this.clearListeners(),this.stop(),this.stopPassiveEffect&&this.stopPassiveEffect()}}function Cn(t,e){return new m7(t,e)}function NA(t){const e=[{},{}];return t==null||t.values.forEach((a,n)=>{e[0][n]=a.get(),e[1][n]=a.getVelocity()}),e}function Sw(t,e,a,n){if(typeof e=="function"){const[i,r]=NA(n);e=e(a!==void 0?a:t.custom,i,r)}if(typeof e=="string"&&(e=t.variants&&t.variants[e]),typeof e=="function"){const[i,r]=NA(n);e=e(a!==void 0?a:t.custom,i,r)}return e}function rl(t,e,a){const n=t.getProps();return Sw(n,e,a!==void 0?a:n.custom,t)}const Mv=t=>Array.isArray(t);function h7(t,e,a){t.hasValue(e)?t.getValue(e).set(a):t.addValue(e,Cn(a))}function f7(t){return Mv(t)?t[t.length-1]||0:t}function g7(t,e){const a=rl(t,e);let{transitionEnd:n={},transition:i={},...r}=a||{};r={...r,...n};for(const o in r){const l=f7(r[o]);h7(t,o,l)}}const na=t=>!!(t&&t.getVelocity);function y7(t){return!!(na(t)&&t.add)}function Dv(t,e){const a=t.getValue("willChange");if(y7(a))return a.add(e);if(!a&&qi.WillChange){const n=new qi.WillChange("auto");t.addValue("willChange",n),n.add(e)}}function _w(t){return t.replace(/([A-Z])/g,e=>`-${e.toLowerCase()}`)}const x7="framerAppearId",T4="data-"+_w(x7);function N4(t){return t.props[T4]}function v7({protectedKeys:t,needsAnimating:e},a){const n=t.hasOwnProperty(a)&&e[a]!==!0;return e[a]=!1,n}function I4(t,e,{delay:a=0,transitionOverride:n,type:i}={}){let{transition:r=t.getDefaultTransition(),transitionEnd:o,...l}=e;n&&(r=n);const c=[],d=i&&t.animationState&&t.animationState.getState()[i];for(const u in l){const p=t.getValue(u,t.latestValues[u]??null),m=l[u];if(m===void 0||d&&v7(d,u))continue;const h={delay:a,...ww(r||{},u)},g=p.get();if(g!==void 0&&!p.isAnimating&&!Array.isArray(m)&&m===g&&!h.velocity)continue;let y=!1;if(window.MotionHandoffAnimation){const v=N4(t);if(v){const w=window.MotionHandoffAnimation(v,u,Ne);w!==null&&(h.startTime=w,y=!0)}}Dv(t,u),p.start(kw(u,p,m,t.shouldReduceMotion&&j4.has(u)?{type:!1}:h,t,y));const x=p.animation;x&&c.push(x)}return o&&Promise.all(c).then(()=>{Ne.update(()=>{o&&g7(t,o)})}),c}function qv(t,e,a={}){var c;const n=rl(t,e,a.type==="exit"?(c=t.presenceContext)==null?void 0:c.custom:void 0);let{transition:i=t.getDefaultTransition()||{}}=n||{};a.transitionOverride&&(i=a.transitionOverride);const r=n?()=>Promise.all(I4(t,n,a)):()=>Promise.resolve(),o=t.variantChildren&&t.variantChildren.size?(d=0)=>{const{delayChildren:u=0,staggerChildren:p,staggerDirection:m}=i;return b7(t,e,d,u,p,m,a)}:()=>Promise.resolve(),{when:l}=i;if(l){const[d,u]=l==="beforeChildren"?[r,o]:[o,r];return d().then(()=>u())}else return Promise.all([r(),o(a.delay)])}function b7(t,e,a=0,n=0,i=0,r=1,o){const l=[];for(const c of t.variantChildren)c.notify("AnimationStart",e),l.push(qv(c,e,{...o,delay:a+(typeof n=="function"?0:n)+C4(t.variantChildren,c,n,i,r)}).then(()=>c.notify("AnimationComplete",e)));return Promise.all(l)}function w7(t,e,a={}){t.notify("AnimationStart",e);let n;if(Array.isArray(e)){const i=e.map(r=>qv(t,r,a));n=Promise.all(i)}else if(typeof e=="string")n=qv(t,e,a);else{const i=typeof e=="function"?rl(t,e,a.custom):e;n=Promise.all(I4(t,i,a))}return n.then(()=>{t.notify("AnimationComplete",e)})}const k7={test:t=>t==="auto",parse:t=>t},P4=t=>e=>e.test(t),R4=[Ul,J,Zn,Yi,YH,XH,k7],IA=t=>R4.find(P4(t));function S7(t){return typeof t=="number"?t===0:t!==null?t==="none"||t==="0"||KP(t):!0}const _7=new Set(["brightness","contrast","saturate","opacity"]);function A7(t){const[e,a]=t.slice(0,-1).split("(");if(e==="drop-shadow")return t;const[n]=a.match(pw)||[];if(!n)return t;const i=a.replace(n,"");let r=_7.has(e)?1:0;return n!==a&&(r*=100),e+"("+r+i+")"}const E7=/\b([a-z-]*)\(.*?\)/gu,zv={...Vr,getAnimatableNone:t=>{const e=t.match(E7);return e?e.map(A7).join(" "):t}},PA={...Ul,transform:Math.round},C7={rotate:Yi,rotateX:Yi,rotateY:Yi,rotateZ:Yi,scale:Mp,scaleX:Mp,scaleY:Mp,scaleZ:Mp,skew:Yi,skewX:Yi,skewY:Yi,distance:J,translateX:J,translateY:J,translateZ:J,x:J,y:J,z:J,perspective:J,transformPerspective:J,opacity:Qd,originX:xA,originY:xA,originZ:J},Aw={borderWidth:J,borderTopWidth:J,borderRightWidth:J,borderBottomWidth:J,borderLeftWidth:J,borderRadius:J,radius:J,borderTopLeftRadius:J,borderTopRightRadius:J,borderBottomRightRadius:J,borderBottomLeftRadius:J,width:J,maxWidth:J,height:J,maxHeight:J,top:J,right:J,bottom:J,left:J,inset:J,insetBlock:J,insetBlockStart:J,insetBlockEnd:J,insetInline:J,insetInlineStart:J,insetInlineEnd:J,padding:J,paddingTop:J,paddingRight:J,paddingBottom:J,paddingLeft:J,paddingBlock:J,paddingBlockStart:J,paddingBlockEnd:J,paddingInline:J,paddingInlineStart:J,paddingInlineEnd:J,margin:J,marginTop:J,marginRight:J,marginBottom:J,marginLeft:J,marginBlock:J,marginBlockStart:J,marginBlockEnd:J,marginInline:J,marginInlineStart:J,marginInlineEnd:J,backgroundPositionX:J,backgroundPositionY:J,...C7,zIndex:PA,fillOpacity:Qd,strokeOpacity:Qd,numOctaves:PA},j7={...Aw,color:ht,backgroundColor:ht,outlineColor:ht,fill:ht,stroke:ht,borderColor:ht,borderTopColor:ht,borderRightColor:ht,borderBottomColor:ht,borderLeftColor:ht,filter:zv,WebkitFilter:zv},L4=t=>j7[t];function O4(t,e){let a=L4(t);return a!==zv&&(a=Vr),a.getAnimatableNone?a.getAnimatableNone(e):void 0}const T7=new Set(["auto","none","0"]);function N7(t,e,a){let n=0,i;for(;n<t.length&&!i;){const r=t[n];typeof r=="string"&&!T7.has(r)&&Xd(r).values.length&&(i=t[n]),n++}if(i&&a)for(const r of e)t[r]=O4(a,i)}class I7 extends bw{constructor(e,a,n,i,r){super(e,a,n,i,r,!0)}readKeyframes(){const{unresolvedKeyframes:e,element:a,name:n}=this;if(!a||!a.current)return;super.readKeyframes();for(let u=0;u<e.length;u++){let p=e[u];if(typeof p=="string"&&(p=p.trim(),uw(p))){const m=E4(p,a.current);m!==void 0&&(e[u]=m),u===e.length-1&&(this.finalKeyframe=p)}}if(this.resolveNoneKeyframes(),!j4.has(n)||e.length!==2)return;const[i,r]=e,o=IA(i),l=IA(r),c=yA(i),d=yA(r);if(c!==d&&gr[n]){this.needsMeasurement=!0;return}if(o!==l)if(EA(o)&&EA(l))for(let u=0;u<e.length;u++){const p=e[u];typeof p=="string"&&(e[u]=parseFloat(p))}else gr[n]&&(this.needsMeasurement=!0)}resolveNoneKeyframes(){const{unresolvedKeyframes:e,name:a}=this,n=[];for(let i=0;i<e.length;i++)(e[i]===null||S7(e[i]))&&n.push(i);n.length&&N7(e,n,a)}measureInitialState(){const{element:e,unresolvedKeyframes:a,name:n}=this;if(!e||!e.current)return;n==="height"&&(this.suspendedScrollY=window.pageYOffset),this.measuredOrigin=gr[n](e.measureViewportBox(),window.getComputedStyle(e.current)),a[0]=this.measuredOrigin;const i=a[a.length-1];i!==void 0&&e.getValue(n,i).jump(i,!1)}measureEndState(){var l;const{element:e,name:a,unresolvedKeyframes:n}=this;if(!e||!e.current)return;const i=e.getValue(a);i&&i.jump(this.measuredOrigin,!1);const r=n.length-1,o=n[r];n[r]=gr[a](e.measureViewportBox(),window.getComputedStyle(e.current)),o!==null&&this.finalKeyframe===void 0&&(this.finalKeyframe=o),(l=this.removedTransforms)!=null&&l.length&&this.removedTransforms.forEac
vendor: 6,863 bytes, line 59
59h(([c,d])=>{e.getValue(c).set(d)}),this.resolveNoneKeyframes()}}function Ew(t,e,a){if(t instanceof EventTarget)return[t];if(typeof t=="string"){const i=document.querySelectorAll(t);return i?Array.from(i):[]}return Array.from(t)}const M4=(t,e)=>e&&typeof t=="number"?e.transform(t):t;function Cw(t){return GP(t)&&"offsetHeight"in t}const{schedule:jw}=r4(queueMicrotask,!1),wn={x:!1,y:!1};function D4(){return wn.x||wn.y}function P7(t){return t==="x"||t==="y"?wn[t]?null:(wn[t]=!0,()=>{wn[t]=!1}):wn.x||wn.y?null:(wn.x=wn.y=!0,()=>{wn.x=wn.y=!1})}function q4(t,e){const a=Ew(t),n=new AbortController,i={passive:!0,...e,signal:n.signal};return[a,i,()=>n.abort()]}function RA(t){return!(t.pointerType==="touch"||D4())}function R7(t,e,a={}){const[n,i,r]=q4(t,a),o=l=>{if(!RA(l))return;const{target:c}=l,d=e(c,l);if(typeof d!="function"||!c)return;const u=p=>{RA(p)&&(d(p),c.removeEventListener("pointerleave",u))};c.addEventListener("pointerleave",u,i)};return n.forEach(l=>{l.addEventListener("pointerenter",o,i)}),r}const z4=(t,e)=>e?t===e?!0:z4(t,e.parentElement):!1,Tw=t=>t.pointerType==="mouse"?typeof t.button!="number"||t.button<=0:t.isPrimary!==!1,L7=new Set(["BUTTON","INPUT","SELECT","TEXTAREA","A"]);function V4(t){return L7.has(t.tagName)||t.isContentEditable===!0}const jm=new WeakSet;function LA(t){return e=>{e.key==="Enter"&&t(e)}}function u0(t,e){t.dispatchEvent(new PointerEvent("pointer"+e,{isPrimary:!0,bubbles:!0}))}const O7=(t,e)=>{const a=t.currentTarget;if(!a)return;const n=LA(()=>{if(jm.has(a))return;u0(a,"down");const i=LA(()=>{u0(a,"up")}),r=()=>u0(a,"cancel");a.addEventListener("keyup",i,e),a.addEventListener("blur",r,e)});a.addEventListener("keydown",n,e),a.addEventListener("blur",()=>a.removeEventListener("keydown",n),e)};function OA(t){return Tw(t)&&!D4()}function M7(t,e,a={}){const[n,i,r]=q4(t,a),o=l=>{const c=l.currentTarget;if(!OA(l))return;jm.add(c);const d=e(c,l),u=(h,g)=>{window.removeEventListener("pointerup",p),window.removeEventListener("pointercancel",m),jm.has(c)&&jm.delete(c),OA(h)&&typeof d=="function"&&d(h,{success:g})},p=h=>{u(h,c===window||c===document||a.useGlobalTarget||z4(c,h.target))},m=h=>{u(h,!1)};window.addEventListener("pointerup",p,i),window.addEventListener("pointercancel",m,i)};return n.forEach(l=>{(a.useGlobalTarget?window:l).addEventListener("pointerdown",o,i),Cw(l)&&(l.addEventListener("focus",d=>O7(d,i)),!V4(l)&&!l.hasAttribute("tabindex")&&(l.tabIndex=0))}),r}function Nw(t){return GP(t)&&"ownerSVGElement"in t}const Tm=new WeakMap;let Zi;const H4=(t,e,a)=>(n,i)=>i&&i[0]?i[0][t+"Size"]:Nw(n)&&"getBBox"in n?n.getBBox()[e]:n[a],D7=H4("inline","width","offsetWidth"),q7=H4("block","height","offsetHeight");function z7({target:t,borderBoxSize:e}){var a;(a=Tm.get(t))==null||a.forEach(n=>{n(t,{get width(){return D7(t,e)},get height(){return q7(t,e)}})})}function V7(t){t.forEach(z7)}function H7(){typeof ResizeObserver>"u"||(Zi=new ResizeObserver(V7))}function F7(t,e){Zi||H7();const a=Ew(t);return a.forEach(n=>{let i=Tm.get(n);i||(i=new Set,Tm.set(n,i)),i.add(e),Zi==null||Zi.observe(n)}),()=>{a.forEach(n=>{const i=Tm.get(n);i==null||i.delete(e),i!=null&&i.size||Zi==null||Zi.unobserve(n)})}}const Nm=new Set;let Ws;function B7(){Ws=()=>{const t={get width(){return window.innerWidth},get height(){return window.innerHeight}};Nm.forEach(e=>e(t))},window.addEventListener("resize",Ws)}function U7(t){return Nm.add(t),Ws||B7(),()=>{Nm.delete(t),!Nm.size&&typeof Ws=="function"&&(window.removeEventListener("resize",Ws),Ws=void 0)}}function $7(t,e){return typeof t=="function"?U7(t):F7(t,e)}function F4(t,e){let a;const n=()=>{const{currentTime:i}=e,o=(i===null?0:i.value)/100;a!==o&&t(o),a=o};return Ne.preUpdate(n,!0),()=>Mn(n)}function W7(t){return Nw(t)&&t.tagName==="svg"}function G7(...t){const e=!Array.isArray(t[0]),a=e?0:-1,n=t[0+a],i=t[1+a],r=t[2+a],o=t[3+a],l=gw(i,r,o);return e?l(n):l}const K7=[...R4,ht,Vr],J7=t=>K7.find(P4(t)),MA=()=>({translate:0,scale:1,origin:0,originPoint:0}),Gs=()=>({x:MA(),y:MA()}),DA=()=>({min:0,max:0}),bt=()=>({x:DA(),y:DA()}),Vv={current:null},B4={current:!1},Q7=typeof window<"u";function X7(){if(B4.current=!0,!!Q7)if(window.matchMedia){const t=window.matchMedia("(prefers-reduced-motion)"),e=()=>Vv.current=t.matches;t.addEventListener("change",e),e()}else Vv.current=!1}const Y7=new WeakMap;function sg(t){return t!==null&&typeof t=="object"&&typeof t.start=="function"}function Yd(t){return typeof t=="string"||Array.isArray(t)}const Iw=["animate","whileInView","whileFocus","whileHover","whileTap","whileDrag","exit"],Pw=["initial",...Iw];function lg(t){return sg(t.animate)||Pw.some(e=>Yd(t[e]))}function U4(t){return!!(lg(t)||t.variants)}function Z7(t,e,a){for(const n in e){const i=e[n],r=a[n];if(na(i))t.addValue(n,i);else if(na(r))t.addValue(n,Cn(i,{owner:t}));else if(r!==i)if(t.hasValue(n)){const o=t.getValue(n);o.liveStyle===!0?o.jump(i):o.hasAnimated||o.set(i)}else{const o=t.getStaticValue(n);t.addValue(n,Cn(o!==void 0?o:i,{owner:t}))}}for(const n in a)e[n]===void 0&&t.removeValue(n);return e}const qA=["AnimationStart","AnimationComplete","Update","BeforeLayoutMeasure","LayoutMeasure","LayoutAnimationStart","LayoutAnimationComplete"];let _h={};function $4(t){_h=t}function eB(){return _h}class tB{scrapeMotionValuesFromProps(e,a,n){return{}}constructor({parent:e,props:a,presenceContext:n,reducedMotionConfig:i,blockInitialAnimation:r,visualState:o},l={}){this.current=null,this.children=new Set,this.isVariantNode=!1,this.isControllingVariants=!1,this.shouldReduceMotion=null,this.values=new Map,this.KeyframeResolver=bw,this.features={},this.valueSubscriptions=new Map,this.prevMotionValues={},this.events={},this.propEventSubscriptions={},this.notifyUpdate=()=>this.notify("Update",this.latestValues),this.render=()=>{this.current&&(this.triggerBuild(),this.renderInstance(this.current,this.renderState,this.props.style,this.projection))},this.renderScheduledAt=0,this.scheduleRender=()=>{const m=pa.now();this.renderScheduledAt<m&&(this.renderScheduledAt=m,Ne.render(this.render,!1,!0))};const{latestValues:c,renderState:d}=o;this.latestValues=c,this.baseTarget={...c},this.initialValues=a.initial?{...c}:{},this.renderState=d,this.parent=e,this.props=a,this.presenceContext=n,this.depth=e?e.depth+1:0,this.reducedMotionConfig=i,this.options=l,this.blockInitialAnimation=!!r,this.isControllingVariants=lg(a),this.isVariantNode=U4(a),this.isVariantNode&&(this.variantChildren=new Set),this.manuallyAnimateOnMount=!!(e&&e.current);const{willChange:u,...p}=this.scrapeMotionValuesFromProps(a,{},this);for(const m in p){const h=p[m];c[m]!==void 0&&na(h)&&h.set(c[m])}}mount(e){var a;this.current=e,Y7.set(e,this),this.projection&&!this.projection.instance&&this.projection.mount(e),this.parent&&this.isVariantNode&&!this.isControllingVariants&&(this.removeFromVariantTree=this.parent.addVariantChild(this)),this.values.forEac
vendor: 10,081 bytes, line 59
59h((n,i)=>this.bindToMotionValue(i,n)),this.reducedMotionConfig==="never"?this.shouldReduceMotion=!1:this.reducedMotionConfig==="always"?this.shouldReduceMotion=!0:(B4.current||X7(),this.shouldReduceMotion=Vv.current),(a=this.parent)==null||a.addChild(this),this.update(this.props,this.presenceContext)}unmount(){var e;this.projection&&this.projection.unmount(),Mn(this.notifyUpdate),Mn(this.render),this.valueSubscriptions.forEach(a=>a()),this.valueSubscriptions.clear(),this.removeFromVariantTree&&this.removeFromVariantTree(),(e=this.parent)==null||e.removeChild(this);for(const a in this.events)this.events[a].clear();for(const a in this.features){const n=this.features[a];n&&(n.unmount(),n.isMounted=!1)}this.current=null}addChild(e){this.children.add(e),this.enteringChildren??(this.enteringChildren=new Set),this.enteringChildren.add(e)}removeChild(e){this.children.delete(e),this.enteringChildren&&this.enteringChildren.delete(e)}bindToMotionValue(e,a){this.valueSubscriptions.has(e)&&this.valueSubscriptions.get(e)();const n=Wl.has(e);n&&this.onBindTransform&&this.onBindTransform();const i=a.on("change",o=>{this.latestValues[e]=o,this.props.onUpdate&&Ne.preRender(this.notifyUpdate),n&&this.projection&&(this.projection.isTransformDirty=!0),this.scheduleRender()});let r;typeof window<"u"&&window.MotionCheckAppearSync&&(r=window.MotionCheckAppearSync(this,e,a)),this.valueSubscriptions.set(e,()=>{i(),r&&r(),a.owner&&a.stop()})}sortNodePosition(e){return!this.current||!this.sortInstanceNodePosition||this.type!==e.type?0:this.sortInstanceNodePosition(this.current,e.current)}updateFeatures(){let e="animation";for(e in _h){const a=_h[e];if(!a)continue;const{isEnabled:n,Feature:i}=a;if(!this.features[e]&&i&&n(this.props)&&(this.features[e]=new i(this)),this.features[e]){const r=this.features[e];r.isMounted?r.update():(r.mount(),r.isMounted=!0)}}}triggerBuild(){this.build(this.renderState,this.latestValues,this.props)}measureViewportBox(){return this.current?this.measureInstanceViewportBox(this.current,this.props):bt()}getStaticValue(e){return this.latestValues[e]}setStaticValue(e,a){this.latestValues[e]=a}update(e,a){(e.transformTemplate||this.props.transformTemplate)&&this.scheduleRender(),this.prevProps=this.props,this.props=e,this.prevPresenceContext=this.presenceContext,this.presenceContext=a;for(let n=0;n<qA.length;n++){const i=qA[n];this.propEventSubscriptions[i]&&(this.propEventSubscriptions[i](),delete this.propEventSubscriptions[i]);const r="on"+i,o=e[r];o&&(this.propEventSubscriptions[i]=this.on(i,o))}this.prevMotionValues=Z7(this,this.scrapeMotionValuesFromProps(e,this.prevProps||{},this),this.prevMotionValues),this.handleChildMotionValue&&this.handleChildMotionValue()}getProps(){return this.props}getVariant(e){return this.props.variants?this.props.variants[e]:void 0}getDefaultTransition(){return this.props.transition}getTransformPagePoint(){return this.props.transformPagePoint}getClosestVariantNode(){return this.isVariantNode?this:this.parent?this.parent.getClosestVariantNode():void 0}addVariantChild(e){const a=this.getClosestVariantNode();if(a)return a.variantChildren&&a.variantChildren.add(e),()=>a.variantChildren.delete(e)}addValue(e,a){const n=this.values.get(e);a!==n&&(n&&this.removeValue(e),this.bindToMotionValue(e,a),this.values.set(e,a),this.latestValues[e]=a.get())}removeValue(e){this.values.delete(e);const a=this.valueSubscriptions.get(e);a&&(a(),this.valueSubscriptions.delete(e)),delete this.latestValues[e],this.removeValueFromRenderState(e,this.renderState)}hasValue(e){return this.values.has(e)}getValue(e,a){if(this.props.values&&this.props.values[e])return this.props.values[e];let n=this.values.get(e);return n===void 0&&a!==void 0&&(n=Cn(a===null?void 0:a,{owner:this}),this.addValue(e,n)),n}readValue(e,a){let n=this.latestValues[e]!==void 0||!this.current?this.latestValues[e]:this.getBaseTargetFromProps(this.props,e)??this.readValueFromInstance(this.current,e,this.options);return n!=null&&(typeof n=="string"&&(WP(n)||KP(n))?n=parseFloat(n):!J7(n)&&Vr.test(a)&&(n=O4(e,a)),this.setBaseTarget(e,na(n)?n.get():n)),na(n)?n.get():n}setBaseTarget(e,a){this.baseTarget[e]=a}getBaseTarget(e){var r;const{initial:a}=this.props;let n;if(typeof a=="string"||typeof a=="object"){const o=Sw(this.props,a,(r=this.presenceContext)==null?void 0:r.custom);o&&(n=o[e])}if(a&&n!==void 0)return n;const i=this.getBaseTargetFromProps(this.props,e);return i!==void 0&&!na(i)?i:this.initialValues[e]!==void 0&&n===void 0?void 0:this.baseTarget[e]}on(e,a){return this.events[e]||(this.events[e]=new sw),this.events[e].add(a)}notify(e,...a){this.events[e]&&this.events[e].notify(...a)}scheduleRenderMicrotask(){jw.render(this.render)}}class Jr{constructor(e){this.isMounted=!1,this.node=e}update(){}}class W4 extends tB{constructor(){super(...arguments),this.KeyframeResolver=I7}sortInstanceNodePosition(e,a){return e.compareDocumentPosition(a)&2?1:-1}getBaseTargetFromProps(e,a){const n=e.style;return n?n[a]:void 0}removeValueFromRenderState(e,{vars:a,style:n}){delete a[e],delete n[e]}handleChildMotionValue(){this.childSubscription&&(this.childSubscription(),delete this.childSubscription);const{children:e}=this.props;na(e)&&(this.childSubscription=e.on("change",a=>{this.current&&(this.current.textContent=`${a}`)}))}}function G4({top:t,left:e,right:a,bottom:n}){return{x:{min:e,max:a},y:{min:t,max:n}}}function aB({x:t,y:e}){return{top:e.min,right:t.max,bottom:e.max,left:t.min}}function nB(t,e){if(!e)return t;const a=e({x:t.left,y:t.top}),n=e({x:t.right,y:t.bottom});return{top:a.y,left:a.x,bottom:n.y,right:n.x}}function p0(t){return t===void 0||t===1}function Hv({scale:t,scaleX:e,scaleY:a}){return!p0(t)||!p0(e)||!p0(a)}function ho(t){return Hv(t)||K4(t)||t.z||t.rotate||t.rotateX||t.rotateY||t.skewX||t.skewY}function K4(t){return zA(t.x)||zA(t.y)}function zA(t){return t&&t!=="0%"}function Ah(t,e,a){const n=t-a,i=e*n;return a+i}function VA(t,e,a,n,i){return i!==void 0&&(t=Ah(t,i,n)),Ah(t,a,n)+e}function Fv(t,e=0,a=1,n,i){t.min=VA(t.min,e,a,n,i),t.max=VA(t.max,e,a,n,i)}function J4(t,{x:e,y:a}){Fv(t.x,e.translate,e.scale,e.originPoint),Fv(t.y,a.translate,a.scale,a.originPoint)}const HA=.999999999999,FA=1.0000000000001;function iB(t,e,a,n=!1){const i=a.length;if(!i)return;e.x=e.y=1;let r,o;for(let l=0;l<i;l++){r=a[l],o=r.projectionDelta;const{visualElement:c}=r.options;c&&c.props.style&&c.props.style.display==="contents"||(n&&r.options.layoutScroll&&r.scroll&&r!==r.root&&Js(t,{x:-r.scroll.offset.x,y:-r.scroll.offset.y}),o&&(e.x*=o.x.scale,e.y*=o.y.scale,J4(t,o)),n&&ho(r.latestValues)&&Js(t,r.latestValues))}e.x<FA&&e.x>HA&&(e.x=1),e.y<FA&&e.y>HA&&(e.y=1)}function Ks(t,e){t.min=t.min+e,t.max=t.max+e}function BA(t,e,a,n,i=.5){const r=Xe(t.min,t.max,i);Fv(t,e,a,r,n)}function Js(t,e){BA(t.x,e.x,e.scaleX,e.scale,e.originX),BA(t.y,e.y,e.scaleY,e.scale,e.originY)}function Q4(t,e){return G4(nB(t.getBoundingClientRect(),e))}function rB(t,e,a){const n=Q4(t,a),{scroll:i}=e;return i&&(Ks(n.x,i.offset.x),Ks(n.y,i.offset.y)),n}const oB={x:"translateX",y:"translateY",z:"translateZ",transformPerspective:"perspective"},sB=$l.length;function lB(t,e,a){let n="",i=!0;for(let r=0;r<sB;r++){const o=$l[r],l=t[o];if(l===void 0)continue;let c=!0;if(typeof l=="number"?c=l===(o.startsWith("scale")?1:0):c=parseFloat(l)===0,!c||a){const d=M4(l,Aw[o]);if(!c){i=!1;const u=oB[o]||o;n+=`${u}(${d}) `}a&&(e[o]=d)}}return n=n.trim(),a?n=a(e,i?"":n):i&&(n="none"),n}function Rw(t,e,a){const{style:n,vars:i,transformOrigin:r}=t;let o=!1,l=!1;for(const c in e){const d=e[c];if(Wl.has(c)){o=!0;continue}else if(s4(c)){i[c]=d;continue}else{const u=M4(d,Aw[c]);c.startsWith("origin")?(l=!0,r[c]=u):n[c]=u}}if(e.transform||(o||a?n.transform=lB(e,t.transform,a):n.transform&&(n.transform="none")),l){const{originX:c="50%",originY:d="50%",originZ:u=0}=r;n.transformOrigin=`${c} ${d} ${u}`}}function X4(t,{style:e,vars:a},n,i){const r=t.style;let o;for(o in e)r[o]=e[o];i==null||i.applyProjectionStyles(r,n);for(o in a)r.setProperty(o,a[o])}function UA(t,e){return e.max===e.min?0:t/(e.max-e.min)*100}const Ec={correct:(t,e)=>{if(!e.target)return t;if(typeof t=="string")if(J.test(t))t=parseFloat(t);else return t;const a=UA(t,e.target.x),n=UA(t,e.target.y);return`${a}% ${n}%`}},cB={correct:(t,{treeScale:e,projectionDelta:a})=>{const n=t,i=Vr.parse(t);if(i.length>5)return n;const r=Vr.createTransformer(t),o=typeof i[0]!="number"?1:0,l=a.x.scale*e.x,c=a.y.scale*e.y;i[0+o]/=l,i[1+o]/=c;const d=Xe(l,c,.5);return typeof i[2+o]=="number"&&(i[2+o]/=d),typeof i[3+o]=="number"&&(i[3+o]/=d),r(i)}},Bv={borderRadius:{...Ec,applyTo:["borderTopLeftRadius","borderTopRightRadius","borderBottomLeftRadius","borderBottomRightRadius"]},borderTopLeftRadius:Ec,borderTopRightRadius:Ec,borderBottomLeftRadius:Ec,borderBottomRightRadius:Ec,boxShadow:cB};function Y4(t,{layout:e,layoutId:a}){return Wl.has(t)||t.startsWith("origin")||(e||a!==void 0)&&(!!Bv[t]||t==="opacity")}function Lw(t,e,a){var o;const n=t.style,i=e==null?void 0:e.style,r={};if(!n)return r;for(const l in n)(na(n[l])||i&&na(i[l])||Y4(l,t)||((o=a==null?void 0:a.getValue(l))==null?void 0:o.liveStyle)!==void 0)&&(r[l]=n[l]);return r}function dB(t){return window.getComputedStyle(t)}class uB extends W4{constructor(){super(...arguments),this.type="html",this.renderInstance=X4}readValueFromInstance(e,a){var n;if(Wl.has(a))return(n=this.projection)!=null&&n.isProjecting?Nv(a):RF(e,a);{const i=dB(e),r=(s4(a)?i.getPropertyValue(a):i[a])||0;return typeof r=="string"?r.trim():r}}measureInstanceViewportBox(e,{transformPagePoint:a}){return Q4(e,a)}build(e,a,n){Rw(e,a,n.transformTemplate)}scrapeMotionValuesFromProps(e,a,n){return Lw(e,a,n)}}const pB={offset:"stroke-dashoffset",array:"stroke-dasharray"},mB={offset:"strokeDashoffset",array:"strokeDasharray"};function hB(t,e,a=1,n=0,i=!0){t.pathLength=1;const r=i?pB:mB;t[r.offset]=J.transform(-n);const o=J.transform(e),l=J.transform(a);t[r.array]=`${o} ${l}`}const fB=["offsetDistance","offsetPath","offsetRotate","offsetAnchor"];function Z4(t,{attrX:e,attrY:a,attrScale:n,pathLength:i,pathSpacing:r=1,pathOffset:o=0,...l}
vendor: 1,571 bytes, line 59
59,c,d,u){if(Rw(t,l,d),c){t.style.viewBox&&(t.attrs.viewBox=t.style.viewBox);return}t.attrs=t.style,t.style={};const{attrs:p,style:m}=t;p.transform&&(m.transform=p.transform,delete p.transform),(m.transform||p.transformOrigin)&&(m.transformOrigin=p.transformOrigin??"50% 50%",delete p.transformOrigin),m.transform&&(m.transformBox=(u==null?void 0:u.transformBox)??"fill-box",delete p.transformBox);for(const h of fB)p[h]!==void 0&&(m[h]=p[h],delete p[h]);e!==void 0&&(p.x=e),a!==void 0&&(p.y=a),n!==void 0&&(p.scale=n),i!==void 0&&hB(p,i,r,o,!1)}const eR=new Set(["baseFrequency","diffuseConstant","kernelMatrix","kernelUnitLength","keySplines","keyTimes","limitingConeAngle","markerHeight","markerWidth","numOctaves","targetX","targetY","surfaceScale","specularConstant","specularExponent","stdDeviation","tableValues","viewBox","gradientTransform","pathLength","startOffset","textLength","lengthAdjust"]),tR=t=>typeof t=="string"&&t.toLowerCase()==="svg";function gB(t,e,a,n){X4(t,e,void 0,n);for(const i in e.attrs)t.setAttribute(eR.has(i)?i:_w(i),e.attrs[i])}function aR(t,e,a){const n=Lw(t,e,a);for(const i in t)if(na(t[i])||na(e[i])){const r=$l.indexOf(i)!==-1?"attr"+i.charAt(0).toUpperCase()+i.substring(1):i;n[r]=t[i]}return n}class yB extends W4{constructor(){super(...arguments),this.type="svg",this.isSVGTag=!1,this.measureInstanceViewportBox=bt}getBaseTargetFromProps(e,a){return e[a]}readValueFromInstance(e,a){if(Wl.has(a)){const n=L4(a);return n&&n.default||0}return a=eR.has(a)?a:_w(a),e.getAttribute(a)}scrapeMotionValuesFromProps(e,a,n){return aR(e,a,n)}
vendor: 2,932 bytes, line 59
59build(e,a,n){Z4(e,a,this.isSVGTag,n.transformTemplate,n.style)}renderInstance(e,a,n,i){gB(e,a,n,i)}mount(e){this.isSVGTag=tR(e.tagName),super.mount(e)}}const xB=Pw.length;function nR(t){if(!t)return;if(!t.isControllingVariants){const a=t.parent?nR(t.parent)||{}:{};return t.props.initial!==void 0&&(a.initial=t.props.initial),a}const e={};for(let a=0;a<xB;a++){const n=Pw[a],i=t.props[n];(Yd(i)||i===!1)&&(e[n]=i)}return e}function iR(t,e){if(!Array.isArray(e))return!1;const a=e.length;if(a!==t.length)return!1;for(let n=0;n<a;n++)if(e[n]!==t[n])return!1;return!0}const vB=[...Iw].reverse(),bB=Iw.length;function wB(t){return e=>Promise.all(e.map(({animation:a,options:n})=>w7(t,a,n)))}function kB(t){let e=wB(t),a=$A(),n=!0;const i=c=>(d,u)=>{var m;const p=rl(t,u,c==="exit"?(m=t.presenceContext)==null?void 0:m.custom:void 0);if(p){const{transition:h,transitionEnd:g,...y}=p;d={...d,...y,...g}}return d};function r(c){e=c(t)}function o(c){const{props:d}=t,u=nR(t.parent)||{},p=[],m=new Set;let h={},g=1/0;for(let x=0;x<bB;x++){const v=vB[x],w=a[v],S=d[v]!==void 0?d[v]:u[v],T=Yd(S),P=v===c?w.isActive:null;P===!1&&(g=x);let M=S===u[v]&&S!==d[v]&&T;if(M&&n&&t.manuallyAnimateOnMount&&(M=!1),w.protectedKeys={...h},!w.isActive&&P===null||!S&&!w.prevProp||sg(S)||typeof S=="boolean")continue;const C=SB(w.prevProp,S);let E=C||v===c&&w.isActive&&!M&&T||x>g&&T,j=!1;const N=Array.isArray(S)?S:[S];let L=N.reduce(i(v),{});P===!1&&(L={});const{prevResolvedValues:O={}}=w,R={...O,...L},G=ae=>{E=!0,m.has(ae)&&(j=!0,m.delete(ae)),w.needsAnimating[ae]=!0;const F=t.getValue(ae);F&&(F.liveStyle=!1)};for(const ae in R){const F=L[ae],Z=O[ae];if(h.hasOwnProperty(ae))continue;let re=!1;Mv(F)&&Mv(Z)?re=!iR(F,Z):re=F!==Z,re?F!=null?G(ae):m.add(ae):F!==void 0&&m.has(ae)?G(ae):w.protectedKeys[ae]=!0}w.prevProp=S,w.prevResolvedValues=L,w.isActive&&(h={...h,...L}),n&&t.blockInitialAnimation&&(E=!1);const ee=M&&C;E&&(!ee||j)&&p.push(...N.map(ae=>{const F={type:v};if(typeof ae=="string"&&n&&!ee&&t.manuallyAnimateOnMount&&t.parent){const{parent:Z}=t,re=rl(Z,ae);if(Z.enteringChildren&&re){const{delayChildren:fe}=re.transition||{};F.delay=C4(Z.enteringChildren,t,fe)}}return{animation:ae,options:F}}))}if(m.size){const x={};if(typeof d.initial!="boolean"){const v=rl(t,Array.isArray(d.initial)?d.initial[0]:d.initial);v&&v.transition&&(x.transition=v.transition)}m.forEach(v=>{const w=t.getBaseTarget(v),S=t.getValue(v);S&&(S.liveStyle=!0),x[v]=w??null}),p.push({animation:x})}let y=!!p.length;return n&&(d.initial===!1||d.initial===d.animate)&&!t.manuallyAnimateOnMount&&(y=!1),n=!1,y?e(p):Promise.resolve()}function l(c,d){var p;if(a[c].isActive===d)return Promise.resolve();(p=t.variantChildren)==null||p.forEach(m=>{var h;return(h=m.animationState)==null?void 0:h.setActive(c,d)}),a[c].isActive=d;const u=o(c);for(const m in a)a[m].protectedKeys={};return u}return{animateChanges:o,setActive:l,setAnimateFunction:r,getState:()=>a,reset:()=>
vendor: 4,136 bytes, line 59
59{a=$A()}}}function SB(t,e){return typeof e=="string"?e!==t:Array.isArray(e)?!iR(e,t):!1}function co(t=!1){return{isActive:t,protectedKeys:{},needsAnimating:{},prevResolvedValues:{}}}function $A(){return{animate:co(!0),whileInView:co(),whileHover:co(),whileTap:co(),whileDrag:co(),whileFocus:co(),exit:co()}}const rR=1e-4,_B=1-rR,AB=1+rR,oR=.01,EB=0-oR,CB=0+oR;function ma(t){return t.max-t.min}function jB(t,e,a){return Math.abs(t-e)<=a}function WA(t,e,a,n=.5){t.origin=n,t.originPoint=Xe(e.min,e.max,t.origin),t.scale=ma(a)/ma(e),t.translate=Xe(a.min,a.max,t.origin)-t.originPoint,(t.scale>=_B&&t.scale<=AB||isNaN(t.scale))&&(t.scale=1),(t.translate>=EB&&t.translate<=CB||isNaN(t.translate))&&(t.translate=0)}function cd(t,e,a,n){WA(t.x,e.x,a.x,n?n.originX:void 0),WA(t.y,e.y,a.y,n?n.originY:void 0)}function GA(t,e,a){t.min=a.min+e.min,t.max=t.min+ma(e)}function TB(t,e,a){GA(t.x,e.x,a.x),GA(t.y,e.y,a.y)}function KA(t,e,a){t.min=e.min-a.min,t.max=t.min+ma(e)}function Eh(t,e,a){KA(t.x,e.x,a.x),KA(t.y,e.y,a.y)}function JA(t,e,a,n,i){return t-=e,t=Ah(t,1/a,n),i!==void 0&&(t=Ah(t,1/i,n)),t}function NB(t,e=0,a=1,n=.5,i,r=t,o=t){if(Zn.test(e)&&(e=parseFloat(e),e=Xe(o.min,o.max,e/100)-o.min),typeof e!="number")return;let l=Xe(r.min,r.max,n);t===r&&(l-=e),t.min=JA(t.min,e,a,l,i),t.max=JA(t.max,e,a,l,i)}function QA(t,e,[a,n,i],r,o){NB(t,e[a],e[n],e[i],e.scale,r,o)}const IB=["x","scaleX","originX"],PB=["y","scaleY","originY"];function XA(t,e,a,n){QA(t.x,e,IB,a?a.x:void 0,n?n.x:void 0),QA(t.y,e,PB,a?a.y:void 0,n?n.y:void 0)}function YA(t,e){t.min=e.min,t.max=e.max}function vn(t,e){YA(t.x,e.x),YA(t.y,e.y)}function ZA(t,e){t.translate=e.translate,t.scale=e.scale,t.originPoint=e.originPoint,t.origin=e.origin}function eE(t){return t.translate===0&&t.scale===1}function sR(t){return eE(t.x)&&eE(t.y)}function tE(t,e){return t.min===e.min&&t.max===e.max}function RB(t,e){return tE(t.x,e.x)&&tE(t.y,e.y)}function aE(t,e){return Math.round(t.min)===Math.round(e.min)&&Math.round(t.max)===Math.round(e.max)}function lR(t,e){return aE(t.x,e.x)&&aE(t.y,e.y)}function nE(t){return ma(t.x)/ma(t.y)}function iE(t,e){return t.translate===e.translate&&t.scale===e.scale&&t.originPoint===e.originPoint}function Za(t){return[t("x"),t("y")]}function LB(t,e,a){let n="";const i=t.x.translate/e.x,r=t.y.translate/e.y,o=(a==null?void 0:a.z)||0;if((i||r||o)&&(n=`translate3d(${i}px, ${r}px, ${o}px) `),(e.x!==1||e.y!==1)&&(n+=`scale(${1/e.x}, ${1/e.y}) `),a){const{transformPerspective:d,rotate:u,rotateX:p,rotateY:m,skewX:h,skewY:g}=a;d&&(n=`perspective(${d}px) ${n}`),u&&(n+=`rotate(${u}deg) `),p&&(n+=`rotateX(${p}deg) `),m&&(n+=`rotateY(${m}deg) `),h&&(n+=`skewX(${h}deg) `),g&&(n+=`skewY(${g}deg) `)}const l=t.x.scale*e.x,c=t.y.scale*e.y;return(l!==1||c!==1)&&(n+=`scale(${l}, ${c})`),n||"none"}const cR=["TopLeft","TopRight","BottomLeft","BottomRight"],OB=cR.length,rE=t=>typeof t=="string"?parseFloat(t):t,oE=t=>typeof t=="number"||J.test(t);function MB(t,e,a,n,i,r){i?(t.opacity=Xe(0,a.opacity??1,DB(n)),t.opacityExit=Xe(e.opacity??1,0,qB(n))):r&&(t.opacity=Xe(e.opacity??1,a.opacity??1,n));for(let o=0;o<OB;o++){const l=`border${cR[o]}Radius`;let c=sE(e,l),d=sE(a,l);if(c===void 0&&d===void 0)continue;c||(c=0),d||(d=0),c===0||d===0||oE(c)===oE(d)?(t[l]=Math.max(Xe(rE(c),rE(d),n),0),(Zn.test(d)||Zn.test(c))&&(t[l]+="%")):t[l]=d}(e.rotate||a.rotate)&&(t.rotate=Xe(e.rotate||0,a.rotate||0,n))}function sE(t,e){return t[e]!==void 0?t[e]:t.borderRadius}const DB=dR(0,.5,t4),qB=dR(.5,.95,Ta);function dR(t,e,a){return n=>n<t?0:n>e?1:a(bl(t,e,n))}function zB(t,e){const a=pa.now(),n=({timestamp:i})=>{const r=i-a;r>=e&&(Mn(n),t(r-e))};return Ne.setup(n,!0),()=>Mn(n)}function Zd(t,e,a,n={passive:!0}){return t.addEventListener(e,a,n),()=>t.removeEventListener(e,a)}function Im(t){return na(t)?t.get():t}function VB(t,e,a){const n=na(t)?t:Cn(t);return n.start(kw("",n,e,a)),n.animation}const HB=(t,e)=>t.depth-e.depth;class FB{constructor(){this.children=[],this.isDirty=!1}add(e){iw(this.children,e),this.isDirty=!0}remove(e){rw(this.children,e),this.isDirty=!0}forEach(e){this.isDirty&&this.children.sort(HB),this.isDirty=!1,this.children.forEac
vendor: 17,284 bytes, line 59
59h(e)}}class BB{constructor(){this.members=[]}add(e){iw(this.members,e),e.scheduleRender()}remove(e){if(rw(this.members,e),e===this.prevLead&&(this.prevLead=void 0),e===this.lead){const a=this.members[this.members.length-1];a&&this.promote(a)}}relegate(e){const a=this.members.findIndex(i=>e===i);if(a===0)return!1;let n;for(let i=a;i>=0;i--){const r=this.members[i];if(r.isPresent!==!1){n=r;break}}return n?(this.promote(n),!0):!1}promote(e,a){const n=this.lead;if(e!==n&&(this.prevLead=n,this.lead=e,e.show(),n)){n.instance&&n.scheduleRender(),e.scheduleRender(),e.resumeFrom=n,a&&(e.resumeFrom.preserveOpacity=!0),n.snapshot&&(e.snapshot=n.snapshot,e.snapshot.latestValues=n.animationValues||n.latestValues),e.root&&e.root.isUpdating&&(e.isLayoutDirty=!0);const{crossfade:i}=e.options;i===!1&&n.hide()}}exitAnimationComplete(){this.members.forEach(e=>{const{options:a,resumingFrom:n}=e;a.onExitComplete&&a.onExitComplete(),n&&n.options.onExitComplete&&n.options.onExitComplete()})}scheduleRender(){this.members.forEach(e=>{e.instance&&e.scheduleRender(!1)})}removeLeadSnapshot(){this.lead&&this.lead.snapshot&&(this.lead.snapshot=void 0)}}const Pm={hasAnimatedSinceResize:!0,hasEverUpdated:!1},m0=["","X","Y","Z"],UB=1e3;let $B=0;function h0(t,e,a,n){const{latestValues:i}=e;i[t]&&(a[t]=i[t],e.setStaticValue(t,0),n&&(n[t]=0))}function uR(t){if(t.hasCheckedOptimisedAppear=!0,t.root===t)return;const{visualElement:e}=t.options;if(!e)return;const a=N4(e);if(window.MotionHasOptimisedAnimation(a,"transform")){const{layout:i,layoutId:r}=t.options;window.MotionCancelOptimisedAnimation(a,"transform",Ne,!(i||r))}const{parent:n}=t;n&&!n.hasCheckedOptimisedAppear&&uR(n)}function pR({attachResizeListener:t,defaultParent:e,measureScroll:a,checkIsScrollRoot:n,resetTransform:i}){return class{constructor(o={},l=e==null?void 0:e()){this.id=$B++,this.animationId=0,this.animationCommitId=0,this.children=new Set,this.options={},this.isTreeAnimating=!1,this.isAnimationBlocked=!1,this.isLayoutDirty=!1,this.isProjectionDirty=!1,this.isSharedProjectionDirty=!1,this.isTransformDirty=!1,this.updateManuallyBlocked=!1,this.updateBlockedByResize=!1,this.isUpdating=!1,this.isSVG=!1,this.needsReset=!1,this.shouldResetTransform=!1,this.hasCheckedOptimisedAppear=!1,this.treeScale={x:1,y:1},this.eventHandlers=new Map,this.hasTreeAnimated=!1,this.layoutVersion=0,this.updateScheduled=!1,this.scheduleUpdate=()=>this.update(),this.projectionUpdateScheduled=!1,this.checkUpdateFailed=()=>{this.isUpdating&&(this.isUpdating=!1,this.clearAllSnapshots())},this.updateProjection=()=>{this.projectionUpdateScheduled=!1,this.nodes.forEach(KB),this.nodes.forEach(YB),this.nodes.forEach(ZB),this.nodes.forEach(JB)},this.resolvedRelativeTargetAt=0,this.linkedParentVersion=0,this.hasProjected=!1,this.isVisible=!0,this.animationProgress=0,this.sharedNodes=new Map,this.latestValues=o,this.root=l?l.root||l:this,this.path=l?[...l.path,l]:[],this.parent=l,this.depth=l?l.depth+1:0;for(let c=0;c<this.path.length;c++)this.path[c].shouldResetTransform=!0;this.root===this&&(this.nodes=new FB)}addEventListener(o,l){return this.eventHandlers.has(o)||this.eventHandlers.set(o,new sw),this.eventHandlers.get(o).add(l)}notifyListeners(o,...l){const c=this.eventHandlers.get(o);c&&c.notify(...l)}hasListeners(o){return this.eventHandlers.has(o)}mount(o){if(this.instance)return;this.isSVG=Nw(o)&&!W7(o),this.instance=o;const{layoutId:l,layout:c,visualElement:d}=this.options;if(d&&!d.current&&d.mount(o),this.root.nodes.add(this),this.parent&&this.parent.children.add(this),this.root.hasTreeAnimated&&(c||l)&&(this.isLayoutDirty=!0),t){let u,p=0;const m=()=>this.root.updateBlockedByResize=!1;Ne.read(()=>{p=window.innerWidth}),t(o,()=>{const h=window.innerWidth;h!==p&&(p=h,this.root.updateBlockedByResize=!0,u&&u(),u=zB(m,250),Pm.hasAnimatedSinceResize&&(Pm.hasAnimatedSinceResize=!1,this.nodes.forEach(dE)))})}l&&this.root.registerSharedNode(l,this),this.options.animate!==!1&&d&&(l||c)&&this.addEventListener("didUpdate",({delta:u,hasLayoutChanged:p,hasRelativeLayoutChanged:m,layout:h})=>{if(this.isTreeAnimationBlocked()){this.target=void 0,this.relativeTarget=void 0;return}const g=this.options.transition||d.getDefaultTransition()||i9,{onLayoutAnimationStart:y,onLayoutAnimationComplete:x}=d.getProps(),v=!this.targetLayout||!lR(this.targetLayout,h),w=!p&&m;if(this.options.layoutRoot||this.resumeFrom||w||p&&(v||!this.currentAnimation)){this.resumeFrom&&(this.resumingFrom=this.resumeFrom,this.resumingFrom.resumingFrom=void 0);const S={...ww(g,"layout"),onPlay:y,onComplete:x};(d.shouldReduceMotion||this.options.layoutRoot)&&(S.delay=0,S.type=!1),this.startAnimation(S),this.setAnimationOrigin(u,w)}else p||dE(this),this.isLead()&&this.options.onExitComplete&&this.options.onExitComplete();this.targetLayout=h})}unmount(){this.options.layoutId&&this.willUpdate(),this.root.nodes.remove(this);const o=this.getStack();o&&o.remove(this),this.parent&&this.parent.children.delete(this),this.instance=void 0,this.eventHandlers.clear(),Mn(this.updateProjection)}blockUpdate(){this.updateManuallyBlocked=!0}unblockUpdate(){this.updateManuallyBlocked=!1}isUpdateBlocked(){return this.updateManuallyBlocked||this.updateBlockedByResize}isTreeAnimationBlocked(){return this.isAnimationBlocked||this.parent&&this.parent.isTreeAnimationBlocked()||!1}startUpdate(){this.isUpdateBlocked()||(this.isUpdating=!0,this.nodes&&this.nodes.forEach(e9),this.animationId++)}getTransformTemplate(){const{visualElement:o}=this.options;return o&&o.getProps().transformTemplate}willUpdate(o=!0){if(this.root.hasTreeAnimated=!0,this.root.isUpdateBlocked()){this.options.onExitComplete&&this.options.onExitComplete();return}if(window.MotionCancelOptimisedAnimation&&!this.hasCheckedOptimisedAppear&&uR(this),!this.root.isUpdating&&this.root.startUpdate(),this.isLayoutDirty)return;this.isLayoutDirty=!0;for(let u=0;u<this.path.length;u++){const p=this.path[u];p.shouldResetTransform=!0,p.updateScroll("snapshot"),p.options.layoutRoot&&p.willUpdate(!1)}const{layoutId:l,layout:c}=this.options;if(l===void 0&&!c)return;const d=this.getTransformTemplate();this.prevTransformTemplateValue=d?d(this.latestValues,""):void 0,this.updateSnapshot(),o&&this.notifyListeners("willUpdate")}update(){if(this.updateScheduled=!1,this.isUpdateBlocked()){this.unblockUpdate(),this.clearAllSnapshots(),this.nodes.forEach(lE);return}if(this.animationId<=this.animationCommitId){this.nodes.forEach(cE);return}this.animationCommitId=this.animationId,this.isUpdating?(this.isUpdating=!1,this.nodes.forEach(XB),this.nodes.forEach(WB),this.nodes.forEach(GB)):this.nodes.forEach(cE),this.clearAllSnapshots();const l=pa.now();Et.delta=On(0,1e3/60,l-Et.timestamp),Et.timestamp=l,Et.isProcessing=!0,r0.update.process(Et),r0.preRender.process(Et),r0.render.process(Et),Et.isProcessing=!1}didUpdate(){this.updateScheduled||(this.updateScheduled=!0,jw.read(this.scheduleUpdate))}clearAllSnapshots(){this.nodes.forEach(QB),this.sharedNodes.forEach(t9)}scheduleUpdateProjection(){this.projectionUpdateScheduled||(this.projectionUpdateScheduled=!0,Ne.preRender(this.updateProjection,!1,!0))}scheduleCheckAfterUnmount(){Ne.postRender(()=>{this.isLayoutDirty?this.root.didUpdate():this.root.checkUpdateFailed()})}updateSnapshot(){this.snapshot||!this.instance||(this.snapshot=this.measure(),this.snapshot&&!ma(this.snapshot.measuredBox.x)&&!ma(this.snapshot.measuredBox.y)&&(this.snapshot=void 0))}updateLayout(){if(!this.instance||(this.updateScroll(),!(this.options.alwaysMeasureLayout&&this.isLead())&&!this.isLayoutDirty))return;if(this.resumeFrom&&!this.resumeFrom.instance)for(let c=0;c<this.path.length;c++)this.path[c].updateScroll();const o=this.layout;this.layout=this.measure(!1),this.layoutVersion++,this.layoutCorrected=bt(),this.isLayoutDirty=!1,this.projectionDelta=void 0,this.notifyListeners("measure",this.layout.layoutBox);const{visualElement:l}=this.options;l&&l.notify("LayoutMeasure",this.layout.layoutBox,o?o.layoutBox:void 0)}updateScroll(o="measure"){let l=!!(this.options.layoutScroll&&this.instance);if(this.scroll&&this.scroll.animationId===this.root.animationId&&this.scroll.phase===o&&(l=!1),l&&this.instance){const c=n(this.instance);this.scroll={animationId:this.root.animationId,phase:o,isRoot:c,offset:a(this.instance),wasRoot:this.scroll?this.scroll.isRoot:c}}}resetTransform(){if(!i)return;const o=this.isLayoutDirty||this.shouldResetTransform||this.options.alwaysMeasureLayout,l=this.projectionDelta&&!sR(this.projectionDelta),c=this.getTransformTemplate(),d=c?c(this.latestValues,""):void 0,u=d!==this.prevTransformTemplateValue;o&&this.instance&&(l||ho(this.latestValues)||u)&&(i(this.instance,d),this.shouldResetTransform=!1,this.scheduleRender())}measure(o=!0){const l=this.measurePageBox();let c=this.removeElementScroll(l);return o&&(c=this.removeTransform(c)),r9(c),{animationId:this.root.animationId,measuredBox:l,layoutBox:c,latestValues:{},source:this.id}}measurePageBox(){var d;const{visualElement:o}=this.options;if(!o)return bt();const l=o.measureViewportBox();if(!(((d=this.scroll)==null?void 0:d.wasRoot)||this.path.some(o9))){const{scroll:u}=this.root;u&&(Ks(l.x,u.offset.x),Ks(l.y,u.offset.y))}return l}removeElementScroll(o){var c;const l=bt();if(vn(l,o),(c=this.scroll)!=null&&c.wasRoot)return l;for(let d=0;d<this.path.length;d++){const u=this.path[d],{scroll:p,options:m}=u;u!==this.root&&p&&m.layoutScroll&&(p.wasRoot&&vn(l,o),Ks(l.x,p.offset.x),Ks(l.y,p.offset.y))}return l}applyTransform(o,l=!1){const c=bt();vn(c,o);for(let d=0;d<this.path.length;d++){const u=this.path[d];!l&&u.options.layoutScroll&&u.scroll&&u!==u.root&&Js(c,{x:-u.scroll.offset.x,y:-u.scroll.offset.y}),ho(u.latestValues)&&Js(c,u.latestValues)}return ho(this.latestValues)&&Js(c,this.latestValues),c}removeTransform(o){const l=bt();vn(l,o);for(let c=0;c<this.path.length;c++){const d=this.path[c];if(!d.instance||!ho(d.latestValues))continue;Hv(d.latestValues)&&d.updateSnapshot();const u=bt(),p=d.measurePageBox();vn(u,p),XA(l,d.latestValues,d.snapshot?d.snapshot.layoutBox:void 0,u)}return ho(this.latestValues)&&XA(l,this.latestValues),l}setTargetDelta(o){this.targetDelta=o,this.root.scheduleUpdateProjection(),this.isProjectionDirty=!0}setOptions(o){this.options={...this.options,...o,crossfade:o.crossfade!==void 0?o.crossfade:!0}}clearMeasurements(){this.scroll=void 0,this.layout=void 0,this.snapshot=void 0,this.prevTransformTemplateValue=void 0,this.targetDelta=void 0,this.target=void 0,this.isLayoutDirty=!1}forceRelativeParentToResolveTarget(){this.relativeParent&&this.relativeParent.resolvedRelativeTargetAt!==Et.timestamp&&this.relativeParent.resolveTargetDelta(!0)}resolveTargetDelta(o=!1){var h;const l=this.getLead();this.isProjectionDirty||(this.isProjectionDirty=l.isProjectionDirty),this.isTransformDirty||(this.isTransformDirty=l.isTransformDirty),this.isSharedProjectionDirty||(this.isSharedProjectionDirty=l.isSharedProjectionDirty);const c=!!this.resumingFrom||this!==l;if(!(o||c&&this.isSharedProjectionDirty||this.isProjectionDirty||(h=this.parent)!=null&&h.isProjectionDirty||this.attemptToResolveRelativeTarget||this.root.updateBlockedByResize))return;const{layout:u,layoutId:p}=this.options;if(!this.layout||!(u||p))return;this.resolvedRelativeTargetAt=Et.timestamp;const m=this.getClosestProjectingParent();m&&this.linkedParentVersion!==m.layoutVersion&&!m.options.layoutRoot&&this.removeRelativeTarget(),!this.targetDelta&&!this.relativeTarget&&(m&&m.layout?this.createRelativeTarget(m,this.layout.layoutBox,m.layout.layoutBox):this.removeRelativeTarget()),!(!this.relativeTarget&&!this.targetDelta)&&(this.target||(this.target=bt(),this.targetWithTransforms=bt()),this.relativeTarget&&this.relativeTargetOrigin&&this.relativeParent&&this.relativeParent.target?(this.forceRelativeParentToResolveTarget(),TB(this.target,this.relativeTarget,this.relativeParent.target)):this.targetDelta?(this.resumingFrom?this.target=this.applyTransform(this.layout.layoutBox):vn(this.target,this.layout.layoutBox),J4(this.target,this.targetDelta)):vn(this.target,this.layout.layoutBox),this.attemptToResolveRelativeTarget&&(this.attemptToResolveRelativeTarget=!1,m&&!!m.resumingFrom==!!this.resumingFrom&&!m.options.layoutScroll&&m.target&&this.animationProgress!==1?this.createRelativeTarget(m,this.target,m.target):this.relativeParent=this.relativeTarget=void 0))}getClosestProjectingParent(){if(!(!this.parent||Hv(this.parent.latestValues)||K4(this.parent.latestValues)))return this.parent.isProjecting()?this.parent:this.parent.getClosestProjectingParent()}isProjecting(){return!!((this.relativeTarget||this.targetDelta||this.options.layoutRoot)&&this.layout)}createRelativeTarget(o,l,c){this.relativeParent=o,this.linkedParentVersion=o.layoutVersion,this.forceRelativeParentToResolveTarget(),this.relativeTarget=bt(),this.relativeTargetOrigin=bt(),Eh(this.relativeTargetOrigin,l,c),vn(this.relativeTarget,this.relativeTargetOrigin)}removeRelativeTarget(){this.relativeParent=this.relativeTarget=void 0}calcProjection(){var g;const o=this.getLead(),l=!!this.resumingFrom||this!==o;let c=!0;if((this.isProjectionDirty||(g=this.parent)!=null&&g.isProjectionDirty)&&(c=!1),l&&(this.isSharedProjectionDirty||this.isTransformDirty)&&(c=!1),this.resolvedRelativeTargetAt===Et.timestamp&&(c=!1),c)return;const{layout:d,layoutId:u}=this.options;if(this.isTreeAnimating=!!(this.parent&&this.parent.isTreeAnimating||this.currentAnimation||this.pendingAnimation),this.isTreeAnimating||(this.targetDelta=this.relativeTarget=void 0),!this.layout||!(d||u))return;vn(this.layoutCorrected,this.layout.layoutBox);const p=this.treeScale.x,m=this.treeScale.y;iB(this.layoutCorrected,this.treeScale,this.path,l),o.layout&&!o.target&&(this.treeScale.x!==1||this.treeScale.y!==1)&&(o.target=o.layout.layoutBox,o.targetWithTransforms=bt());const{target:h}=o;if(!h){this.prevProjectionDelta&&(this.createProjectionDeltas(),this.scheduleRender());return}!this.projectionDelta||!this.prevProjectionDelta?this.createProjectionDeltas():(ZA(this.prevProjectionDelta.x,this.projectionDelta.x),ZA(this.prevProjectionDelta.y,this.projectionDelta.y)),cd(this.projectionDelta,this.layoutCorrected,h,this.latestValues),(this.treeScale.x!==p||this.treeScale.y!==m||!iE(this.projectionDelta.x,this.prevProjectionDelta.x)||!iE(this.projectionDelta.y,this.prevProjectionDelta.y))&&(this.hasProjected=!0,this.scheduleRender(),this.notifyListeners("projectionUpdate",h))}hide(){this.isVisible=!1}show(){this.isVisible=!0}scheduleRender(o=!0){var l;if((l=this.options.visualElement)==null||l.scheduleRender(),o){const c=this.getStack();c&&c.scheduleRender()}this.resumingFrom&&!this.resumingFrom.instance&&(this.resumingFrom=void 0)}createProjectionDeltas(){this.prevProjectionDelta=Gs(),this.projectionDelta=Gs(),this.projectionDeltaWithTransform=Gs()}setAnimationOrigin(o,l=!1){const c=this.snapshot,d=c?c.latestValues:{},u={...this.latestValues},p=Gs();(!this.relativeParent||!this.relativeParent.options.layoutRoot)&&(this.relativeTarget=this.relativeTargetOrigin=void 0),this.attemptToResolveRelativeTarget=!l;const m=bt(),h=c?c.source:void 0,g=this.layout?this.layout.source:void 0,y=h!==g,x=this.getStack(),v=!x||x.members.length<=1,w=!!(y&&!v&&this.options.crossfade===!0&&!this.path.some(n9));this.animationProgress=0;let S;this.mixTargetDelta=T=>{const P=T/1e3;uE(p.x,o.x,P),uE(p.y,o.y,P),this.setTargetDelta(p),this.relativeTarget&&this.relativeTargetOrigin&&this.layout&&this.relativeParent&&this.relativeParent.layout&&(Eh(m,this.layout.layoutBox,this.relativeParent.layout.layoutBox),a9(this.relativeTarget,this.relativeTargetOrigin,m,P),S&&RB(this.relativeTarget,S)&&(this.isProjectionDirty=!1),S||(S=bt()),vn(S,this.relativeTarget)),y&&(this.animationValues=u,MB(u,d,this.latestValues,P,w,v)),this.root.scheduleUpdateProjection(),this.scheduleRender(),this.animationProgress=P},this.mixTargetDelta(this.options.layoutRoot?1e3:0)}startAnimation(o){var l,c,d;this.notifyListeners("animationStart"),(l=this.currentAnimation)==null||l.stop(),(d=(c=this.resumingFrom)==null?void 0:c.currentAnimation)==null||d.stop(),this.pendingAnimation&&(Mn(this.pendingAnimation),this.pendingAnimation=void 0),this.pendingAnimation=Ne.update(()=>{Pm.hasAnimatedSinceResize=!0,this.motionValue||(this.motionValue=Cn(0)),this.currentAnimation=VB(this.motionValue,[0,1e3],{...o,velocity:0,isSync:!0,onUpdate:u=>{this.mixTargetDelta(u),o.onUpdate&&o.onUpdate(u)},onStop:()=>{},onComplete:()=>{o.onComplete&&o.onComplete(),this.completeAnimation()}}),this.resumingFrom&&(this.resumingFrom.currentAnimation=this.currentAnimation),this.pendingAnimation=void 0})}completeAnimation(){this.resumingFrom&&(this.resumingFrom.currentAnimation=void 0,this.resumingFrom.preserveOpacity=void 0);const o=this.getStack();o&&o.exitAnimationComplete(),this.resumingFrom=this.currentAnimation=this.animationValues=void 0,this.notifyListeners("animationComplete")}finishAnimation(){this.currentAnimation&&(this.mixTargetDelta&&this.mixTargetDelta(UB),this.currentAnimation.stop()),this.completeAnimation()}applyTransformsToTarget(){const o=this.getLead();let{targetWithTransforms:l,target:c,layout:d,latestValues:u}=o;if(!(!l||!c||!d)){if(this!==o&&this.layout&&d&&mR(this.options.animationType,this.layout.layoutBox,d.layoutBox)){c=this.target||bt();const p=ma(this.layout.layoutBox.x);
vendor: 4,672 bytes, line 59
59c.x.min=o.target.x.min,c.x.max=c.x.min+p;const m=ma(this.layout.layoutBox.y);c.y.min=o.target.y.min,c.y.max=c.y.min+m}vn(l,c),Js(l,u),cd(this.projectionDeltaWithTransform,this.layoutCorrected,l,u)}}registerSharedNode(o,l){this.sharedNodes.has(o)||this.sharedNodes.set(o,new BB),this.sharedNodes.get(o).add(l);const d=l.options.initialPromotionConfig;l.promote({transition:d?d.transition:void 0,preserveFollowOpacity:d&&d.shouldPreserveFollowOpacity?d.shouldPreserveFollowOpacity(l):void 0})}isLead(){const o=this.getStack();return o?o.lead===this:!0}getLead(){var l;const{layoutId:o}=this.options;return o?((l=this.getStack())==null?void 0:l.lead)||this:this}getPrevLead(){var l;const{layoutId:o}=this.options;return o?(l=this.getStack())==null?void 0:l.prevLead:void 0}getStack(){const{layoutId:o}=this.options;if(o)return this.root.sharedNodes.get(o)}promote({needsReset:o,transition:l,preserveFollowOpacity:c}={}){const d=this.getStack();d&&d.promote(this,c),o&&(this.projectionDelta=void 0,this.needsReset=!0),l&&this.setOptions({transition:l})}relegate(){const o=this.getStack();return o?o.relegate(this):!1}resetSkewAndRotation(){const{visualElement:o}=this.options;if(!o)return;let l=!1;const{latestValues:c}=o;if((c.z||c.rotate||c.rotateX||c.rotateY||c.rotateZ||c.skewX||c.skewY)&&(l=!0),!l)return;const d={};c.z&&h0("z",o,d,this.animationValues);for(let u=0;u<m0.length;u++)h0(`rotate${m0[u]}`,o,d,this.animationValues),h0(`skew${m0[u]}`,o,d,this.animationValues);o.render();for(const u in d)o.setStaticValue(u,d[u]),this.animationValues&&(this.animationValues[u]=d[u]);o.scheduleRender()}applyProjectionStyles(o,l){if(!this.instance||this.isSVG)return;if(!this.isVisible){o.visibility="hidden";return}const c=this.getTransformTemplate();if(this.needsReset){this.needsReset=!1,o.visibility="",o.opacity="",o.pointerEvents=Im(l==null?void 0:l.pointerEvents)||"",o.transform=c?c(this.latestValues,""):"none";return}const d=this.getLead();if(!this.projectionDelta||!this.layout||!d.target){this.options.layoutId&&(o.opacity=this.latestValues.opacity!==void 0?this.latestValues.opacity:1,o.pointerEvents=Im(l==null?void 0:l.pointerEvents)||""),this.hasProjected&&!ho(this.latestValues)&&(o.transform=c?c({},""):"none",this.hasProjected=!1);return}o.visibility="";const u=d.animationValues||d.latestValues;this.applyTransformsToTarget();let p=LB(this.projectionDeltaWithTransform,this.treeScale,u);c&&(p=c(u,p)),o.transform=p;const{x:m,y:h}=this.projectionDelta;o.transformOrigin=`${m.origin*100}% ${h.origin*100}% 0`,d.animationValues?o.opacity=d===this?u.opacity??this.latestValues.opacity??1:this.preserveOpacity?this.latestValues.opacity:u.opacityExit:o.opacity=d===this?u.opacity!==void 0?u.opacity:"":u.opacityExit!==void 0?u.opacityExit:0;for(const g in Bv){if(u[g]===void 0)continue;const{correct:y,applyTo:x,isCSSVariable:v}=Bv[g],w=p==="none"?u[g]:y(u[g],d);if(x){const S=x.length;for(let T=0;T<S;T++)o[x[T]]=w}else v?this.options.visualElement.renderState.vars[g]=w:o[g]=w}this.options.layoutId&&(o.pointerEvents=d===this?Im(l==null?void 0:l.pointerEvents)||"":"none")}clearSnapshot(){this.resumeFrom=this.snapshot=void 0}resetTree(){this.root.nodes.forEach(o=>{var l;return(l=o.currentAnimation)==null?void 0:l.stop()}),this.root.nodes.forEach(lE),this.root.sharedNodes.clear()}}}function WB(t){t.updateLayout()}function GB(t){var a;const e=((a=t.resumeFrom)==null?void 0:a.snapshot)||t.snapshot;if(t.isLead()&&t.layout&&e&&t.hasListeners("didUpdate")){const{layoutBox:n,measuredBox:i}=t.layout,{animationType:r}=t.options,o=e.source!==t.layout.source;r==="size"?Za(p=>{const m=o?e.measuredBox[p]:e.layoutBox[p],h=ma(m);m.min=n[p].min,m.max=m.min+h}):mR(r,e.layoutBox,n)&&Za(p=>{const m=o?e.measuredBox[p]:e.layoutBox[p],h=ma(n[p]);m.max=m.min+h,t.relativeTarget&&!t.currentAnimation&&(t.isProjectionDirty=!0,t.relativeTarget[p].max=t.relativeTarget[p].min+h)});const l=Gs();cd(l,n,e.layoutBox);const c=Gs();o?cd(c,t.applyTransform(i,!0),e.measuredBox):cd(c,n,e.layoutBox);const d=!sR(l);let u=!1;if(!t.resumeFrom){const p=t.getClosestProjectingParent();if(p&&!p.resumeFrom){const{snapshot:m,layout:h}=p;if(m&&h){const g=bt();Eh(g,e.layoutBox,m.layoutBox);const y=bt();Eh(y,n,h.layoutBox),lR(g,y)||(u=!0),p.options.layoutRoot&&(t.relativeTarget=y,t.relativeTargetOrigin=g,t.relativeParent=p)}}}t.notifyListeners("didUpdate",{layout:n,snapshot:e,delta:c,layoutDelta:l,hasLayoutChanged:d,hasRelativeLayoutChanged:u})}else if(t.isLead()){const{onExitComplete:n}=t.options;n&&n()}t.options.transition=void 0}function KB(t){t.parent&&(t.isProjecting()||(t.isProjectionDirty=t.parent.isProjectionDirty),t.isSharedProjectionDirty||(t.isSharedProjectionDirty=!!(t.
vendor: 30,936 bytes, lines 59-67
59isProjectionDirty||t.parent.isProjectionDirty||t.parent.isSharedProjectionDirty)),t.isTransformDirty||(t.isTransformDirty=t.parent.isTransformDirty))}function JB(t){t.isProjectionDirty=t.isSharedProjectionDirty=t.isTransformDirty=!1}function QB(t){t.clearSnapshot()}function lE(t){t.clearMeasurements()}function cE(t){t.isLayoutDirty=!1}function XB(t){const{visualElement:e}=t.options;e&&e.getProps().onBeforeLayoutMeasure&&e.notify("BeforeLayoutMeasure"),t.resetTransform()}function dE(t){t.finishAnimation(),t.targetDelta=t.relativeTarget=t.target=void 0,t.isProjectionDirty=!0}function YB(t){t.resolveTargetDelta()}function ZB(t){t.calcProjection()}function e9(t){t.resetSkewAndRotation()}function t9(t){t.removeLeadSnapshot()}function uE(t,e,a){t.translate=Xe(e.translate,0,a),t.scale=Xe(e.scale,1,a),t.origin=e.origin,t.originPoint=e.originPoint}function pE(t,e,a,n){t.min=Xe(e.min,a.min,n),t.max=Xe(e.max,a.max,n)}function a9(t,e,a,n){pE(t.x,e.x,a.x,n),pE(t.y,e.y,a.y,n)}function n9(t){return t.animationValues&&t.animationValues.opacityExit!==void 0}const i9={duration:.45,ease:[.4,0,.1,1]},mE=t=>typeof navigator<"u"&&navigator.userAgent&&navigator.userAgent.toLowerCase().includes(t),hE=mE("applewebkit/")&&!mE("chrome/")?Math.round:Ta;function fE(t){t.min=hE(t.min),t.max=hE(t.max)}function r9(t){fE(t.x),fE(t.y)}function mR(t,e,a){return t==="position"||t==="preserve-aspect"&&!jB(nE(e),nE(a),.2)}function o9(t){var e;return t!==t.root&&((e=t.scroll)==null?void 0:e.wasRoot)}const s9=pR({attachResizeListener:(t,e)=>Zd(t,"resize",e),measureScroll:()=>({x:document.documentElement.scrollLeft||document.body.scrollLeft,y:document.documentElement.scrollTop||document.body.scrollTop}),checkIsScrollRoot:()=>!0}),f0={current:void 0},hR=pR({measureScroll:t=>({x:t.scrollLeft,y:t.scrollTop}),defaultParent:()=>{if(!f0.current){const t=new s9({});t.mount(window),t.setOptions({layoutScroll:!0}),f0.current=t}return f0.current},resetTransform:(t,e)=>{t.style.transform=e!==void 0?e:"none"},checkIsScrollRoot:t=>window.getComputedStyle(t).position==="fixed"}),cg=k.createContext({transformPagePoint:t=>t,isStatic:!1,reducedMotion:"never"});function gE(t,e){if(typeof t=="function")return t(e);t!=null&&(t.current=e)}function l9(...t){return e=>{let a=!1;const n=t.map(i=>{const r=gE(i,e);return!a&&typeof r=="function"&&(a=!0),r});if(a)return()=>{for(let i=0;i<n.length;i++){const r=n[i];typeof r=="function"?r():gE(t[i],null)}}}}function c9(...t){return k.useCallback(l9(...t),t)}class d9 extends k.Component{getSnapshotBeforeUpdate(e){const a=this.props.childRef.current;if(a&&e.isPresent&&!this.props.isPresent){const n=a.offsetParent,i=Cw(n)&&n.offsetWidth||0,r=this.props.sizeRef.current;r.height=a.offsetHeight||0,r.width=a.offsetWidth||0,r.top=a.offsetTop,r.left=a.offsetLeft,r.right=i-r.width-r.left}return null}componentDidUpdate(){}render(){return this.props.children}}function u9({children:t,isPresent:e,anchorX:a,root:n}){var u;const i=k.useId(),r=k.useRef(null),o=k.useRef({width:0,height:0,top:0,left:0,right:0}),{nonce:l}=k.useContext(cg),c=((u=t.props)==null?void 0:u.ref)??(t==null?void 0:t.ref),d=c9(r,c);return k.useInsertionEffect(()=>{const{width:p,height:m,top:h,left:g,right:y}=o.current;if(e||!r.current||!p||!m)return;const x=a==="left"?`left: ${g}`:`right: ${y}`;r.current.dataset.motionPopId=i;const v=document.createElement("style");l&&(v.nonce=l);const w=n??document.head;return w.appendChild(v),v.sheet&&v.sheet.insertRule(`
60          [data-motion-pop-id="${i}"] {
61            position: absolute !important;
62            width: ${p}px !important;
63            height: ${m}px !important;
64            ${x}px !important;
65            top: ${h}px !important;
66          }
67        `),()=>{w.contains(v)&&w.removeChild(v)}},[e]),s.jsx(d9,{isPresent:e,childRef:r,sizeRef:o,children:k.cloneElement(t,{ref:d})})}const p9=({children:t,initial:e,isPresent:a,onExitComplete:n,custom:i,presenceAffectsLayout:r,mode:o,anchorX:l,root:c})=>{const d=zr(m9),u=k.useId();let p=!0,m=k.useMemo(()=>(p=!1,{id:u,initial:e,isPresent:a,custom:i,onExitComplete:h=>{d.set(h,!0);for(const g of d.values())if(!g)return;n&&n()},register:h=>(d.set(h,!1),()=>d.delete(h))}),[a,d,n]);return r&&p&&(m={...m}),k.useMemo(()=>{d.forEach((h,g)=>d.set(g,!1))},[a]),k.useEffect(()=>{!a&&!d.size&&n&&n()},[a]),o==="popLayout"&&(t=s.jsx(u9,{isPresent:a,anchorX:l,root:c,children:t})),s.jsx(og.Provider,{value:m,children:t})};function m9(){return new Map}function fR(t=!0){const e=k.useContext(og);if(e===null)return[!0,null];const{isPresent:a,onExitComplete:n,register:i}=e,r=k.useId();k.useEffect(()=>{if(t)return i(r)},[t]);const o=k.useCallback(()=>t&&n&&n(r),[r,n,t]);return!a&&n?[!1,o]:[!0]}const Dp=t=>t.key||"";function yE(t){const e=[];return k.Children.forEach(t,a=>{k.isValidElement(a)&&e.push(a)}),e}const La=({children:t,custom:e,initial:a=!0,onExitComplete:n,presenceAffectsLayout:i=!0,mode:r="sync",propagate:o=!1,anchorX:l="left",root:c})=>{const[d,u]=fR(o),p=k.useMemo(()=>yE(t),[t]),m=o&&!d?[]:p.map(Dp),h=k.useRef(!0),g=k.useRef(p),y=zr(()=>new Map),x=k.useRef(new Set),[v,w]=k.useState(p),[S,T]=k.useState(p);rg(()=>{h.current=!1,g.current=p;for(let C=0;C<S.length;C++){const E=Dp(S[C]);m.includes(E)?(y.delete(E),x.current.delete(E)):y.get(E)!==!0&&y.set(E,!1)}},[S,m.length,m.join("-")]);const P=[];if(p!==v){let C=[...p];for(let E=0;E<S.length;E++){const j=S[E],N=Dp(j);m.includes(N)||(C.splice(E,0,j),P.push(j))}return r==="wait"&&P.length&&(C=P),T(yE(C)),w(p),null}const{forceRender:M}=k.useContext(nw);return s.jsx(s.Fragment,{children:S.map(C=>{const E=Dp(C),j=o&&!d?!1:p===S||m.includes(E),N=()=>{if(x.current.has(E))return;if(x.current.add(E),y.has(E))y.set(E,!0);else return;let L=!0;y.forEach(O=>{O||(L=!1)}),L&&(M==null||M(),T(g.current),o&&(u==null||u()),n&&n())};return s.jsx(p9,{isPresent:j,initial:!h.current||a?void 0:!1,custom:e,presenceAffectsLayout:i,mode:r,root:c,onExitComplete:j?void 0:N,anchorX:l,children:C},E)})})},gR=k.createContext({strict:!1}),xE={animation:["animate","variants","whileHover","whileTap","exit","whileInView","whileFocus","whileDrag"],exit:["exit"],drag:["drag","dragControls"],focus:["whileFocus"],hover:["whileHover","onHoverStart","onHoverEnd"],tap:["whileTap","onTap","onTapStart","onTapCancel"],pan:["onPan","onPanStart","onPanSessionStart","onPanEnd"],inView:["whileInView","onViewportEnter","onViewportLeave"],layout:["layout","layoutId"]};let vE=!1;function h9(){if(vE)return;const t={};for(const e in xE)t[e]={isEnabled:a=>xE[e].some(n=>!!a[n])};$4(t),vE=!0}function yR(){return h9(),eB()}function f9(t){const e=yR();for(const a in t)e[a]={...e[a],...t[a]};$4(e)}const g9=new Set(["animate","exit","variants","initial","style","values","variants","transition","transformTemplate","custom","inherit","onBeforeLayoutMeasure","onAnimationStart","onAnimationComplete","onUpdate","onDragStart","onDrag","onDragEnd","onMeasureDragConstraints","onDirectionLock","onDragTransitionEnd","_dragX","_dragY","onHoverStart","onHoverEnd","onViewportEnter","onViewportLeave","globalTapTarget","ignoreStrict","viewport"]);function Ch(t){return t.startsWith("while")||t.startsWith("drag")&&t!=="draggable"||t.startsWith("layout")||t.startsWith("onTap")||t.startsWith("onPan")||t.startsWith("onLayout")||g9.has(t)}let xR=t=>!Ch(t);function y9(t){typeof t=="function"&&(xR=e=>e.startsWith("on")?!Ch(e):t(e))}try{y9(require("@emotion/is-prop-valid").default)}catch{}function x9(t,e,a){const n={};for(const i in t)i==="values"&&typeof t.values=="object"||(xR(i)||a===!0&&Ch(i)||!e&&!Ch(i)||t.draggable&&i.startsWith("onDrag"))&&(n[i]=t[i]);return n}const dg=k.createContext({});function v9(t,e){if(lg(t)){const{initial:a,animate:n}=t;return{initial:a===!1||Yd(a)?a:void 0,animate:Yd(n)?n:void 0}}return t.inherit!==!1?e:{}}function b9(t){const{initial:e,animate:a}=v9(t,k.useContext(dg));return k.useMemo(()=>({initial:e,animate:a}),[bE(e),bE(a)])}function bE(t){return Array.isArray(t)?t.join(" "):t}const Ow=()=>({style:{},transform:{},transformOrigin:{},vars:{}});function vR(t,e,a){for(const n in e)!na(e[n])&&!Y4(n,a)&&(t[n]=e[n])}function w9({transformTemplate:t},e){return k.useMemo(()=>{const a=Ow();return Rw(a,e,t),Object.assign({},a.vars,a.style)},[e])}function k9(t,e){const a=t.style||{},n={};return vR(n,a,t),Object.assign(n,w9(t,e)),n}function S9(t,e){const a={},n=k9(t,e);return t.drag&&t.dragListener!==!1&&(a.draggable=!1,n.userSelect=n.WebkitUserSelect=n.WebkitTouchCallout="none",n.touchAction=t.drag===!0?"none":`pan-${t.drag==="x"?"y":"x"}`),t.tabIndex===void 0&&(t.onTap||t.onTapStart||t.whileTap)&&(a.tabIndex=0),a.style=n,a}const bR=()=>({...Ow(),attrs:{}});function _9(t,e,a,n){const i=k.useMemo(()=>{const r=bR();return Z4(r,e,tR(n),t.transformTemplate,t.style),{...r.attrs,style:{...r.style}}},[e]);if(t.style){const r={};vR(r,t.style,t),i.style={...r,...i.style}}return i}const A9=["animate","circle","defs","desc","ellipse","g","image","line","filter","marker","mask","metadata","path","pattern","polygon","polyline","rect","stop","switch","symbol","svg","text","tspan","use","view"];function Mw(t){return typeof t!="string"||t.includes("-")?!1:!!(A9.indexOf(t)>-1||/[A-Z]/u.test(t))}function E9(t,e,a,{latestValues:n},i,r=!1,o){const c=(o??Mw(t)?_9:S9)(e,n,i,t),d=x9(e,typeof t=="string",r),u=t!==k.Fragment?{...d,...c,ref:a}:{},{children:p}=e,m=k.useMemo(()=>na(p)?p.get():p,[p]);return k.createElement(t,{...u,children:m})}function C9({scrapeMotionValuesFromProps:t,createRenderState:e},a,n,i){return{latestValues:j9(a,n,i,t),renderState:e()}}function j9(t,e,a,n){const i={},r=n(t,{});for(const m in r)i[m]=Im(r[m]);let{initial:o,animate:l}=t;const c=lg(t),d=U4(t);e&&d&&!c&&t.inherit!==!1&&(o===void 0&&(o=e.initial),l===void 0&&(l=e.animate));let u=a?a.initial===!1:!1;u=u||o===!1;const p=u?l:o;if(p&&typeof p!="boolean"&&!sg(p)){const m=Array.isArray(p)?p:[p];for(let h=0;h<m.length;h++){const g=Sw(t,m[h]);if(g){const{transitionEnd:y,transition:x,...v}=g;for(const w in v){let S=v[w];if(Array.isArray(S)){const T=u?S.length-1:0;S=S[T]}S!==null&&(i[w]=S)}for(const w in y)i[w]=y[w]}}}return i}const wR=t=>(e,a)=>{const n=k.useContext(dg),i=k.useContext(og),r=()=>C9(t,e,n,i);return a?r():zr(r)},T9=wR({scrapeMotionValuesFromProps:Lw,createRenderState:Ow}),N9=wR({scrapeMotionValuesFromProps:aR,createRenderState:bR}),I9=Symbol.for("motionComponentSymbol");function P9(t,e,a){const n=k.useRef(a);k.useInsertionEffect(()=>{n.current=a});const i=k.useRef(null);return k.useCallback(r=>{var l;r&&((l=t.onMount)==null||l.call(t,r)),e&&(r?e.mount(r):e.unmount());const o=n.current;if(typeof o=="function")if(r){const c=o(r);typeof c=="function"&&(i.current=c)}else i.current?(i.current(),i.current=null):o(r);else o&&(o.current=r)},[e])}const kR=k.createContext({});function zc(t){return t&&typeof t=="object"&&Object.prototype.hasOwnProperty.call(t,"current")}function R9(t,e,a,n,i,r){var x,v;const{visualElement:o}=k.useContext(dg),l=k.useContext(gR),c=k.useContext(og),d=k.useContext(cg).reducedMotion,u=k.useRef(null);n=n||l.renderer,!u.current&&n&&(u.current=n(t,{visualState:e,parent:o,props:a,presenceContext:c,blockInitialAnimation:c?c.initial===!1:!1,reducedMotionConfig:d,isSVG:r}));const p=u.current,m=k.useContext(kR);p&&!p.projection&&i&&(p.type==="html"||p.type==="svg")&&L9(u.current,a,i,m);const h=k.useRef(!1);k.useInsertionEffect(()=>{p&&h.current&&p.update(a,c)});const g=a[T4],y=k.useRef(!!g&&!((x=window.MotionHandoffIsComplete)!=null&&x.call(window,g))&&((v=window.MotionHasOptimisedAnimation)==null?void 0:v.call(window,g)));return rg(()=>{p&&(h.current=!0,window.MotionIsMounted=!0,p.updateFeatures(),p.scheduleRenderMicrotask(),y.current&&p.animationState&&p.animationState.animateChanges())}),k.useEffect(()=>{p&&(!y.current&&p.animationState&&p.animationState.animateChanges(),y.current&&(queueMicrotask(()=>{var w;(w=window.MotionHandoffMarkAsComplete)==null||w.call(window,g)}),y.current=!1),p.enteringChildren=void 0)}),p}function L9(t,e,a,n){const{layoutId:i,layout:r,drag:o,dragConstraints:l,layoutScroll:c,layoutRoot:d,layoutCrossfade:u}=e;t.projection=new a(t.latestValues,e["data-framer-portal-id"]?void 0:SR(t.parent)),t.projection.setOptions({layoutId:i,layout:r,alwaysMeasureLayout:!!o||l&&zc(l),visualElement:t,animationType:typeof r=="string"?r:"both",initialPromotionConfig:n,crossfade:u,layoutScroll:c,layoutRoot:d})}function SR(t){if(t)return t.options.allowProjection!==!1?t.projection:SR(t.parent)}function g0(t,{forwardMotionProps:e=!1,type:a}={},n,i){n&&f9(n);const r=a?a==="svg":Mw(t),o=r?N9:T9;function l(d,u){let p;const m={...k.useContext(cg),...d,layoutId:O9(d)},{isStatic:h}=m,g=b9(d),y=o(d,h);if(!h&&$P){M9();const x=D9(m);p=x.MeasureLayout,g.visualElement=R9(t,y,m,i,x.ProjectionNode,r)}return s.jsxs(dg.Provider,{value:g,children:[p&&g.visualElement?s.jsx(p,{visualElement:g.visualElement,...m}):null,E9(t,d,P9(y,g.visualElement,u),y,h,e,r)]})}l.displayName=`motion.${typeof t=="string"?t:`create(${t.displayName??t.name??""})`}`;const c=k.forwardRef(l);return c[I9]=t,c}function O9({layoutId:t}){const e=k.useContext(nw).id;return e&&t!==void 0?e+"-"+t:t}function M9(t,e){k.useContext(gR).strict}function D9(t){const e=yR(),{drag:a,layout:n}=e;if(!a&&!n)return{};const i={...a,...n};return{MeasureLayout:a!=null&&a.isEnabled(t)||n!=null&&n.isEnabled(t)?i.MeasureLayout:void 0,ProjectionNode:i.ProjectionNode}}function q9(t,e){if(typeof Proxy>"u")return g0;const a=new Map,n=(r,o)=>g0(r,o,t,e),i=(r,o)=>n(r,o);return new Proxy(i,{get:(r,o)=>o==="create"?n:(a.has(o)||a.set(o,g0(o,void 0,t,e)),a.get(o))})}const z9=(t,e)=>e.isSVG??Mw(t)?new yB(e):new uB(e,{allowProjection:t!==k.Fragment});class V9 extends Jr{constructor(e){super(e),e.animationState||(e.animationState=kB(e))}updateAnimationControlsSubscription(){const{animate:e}=this.node.getProps();sg(e)&&(this.unmountControls=e.subscribe(this.node))}mount(){this.updateAnimationControlsSubscription()}update(){const{animate:e}=this.node.getProps(),{animate:a}=this.node.prevProps||{};e!==a&&this.updateAnimationControlsSubscription()}unmount(){var e;this.node.animationState.reset(),(e=this.unmountControls)==null||e.call(this)}}let H9=0;class F9 extends Jr{constructor(){super(...arguments),this.id=H9++}update(){if(!this.node.presenceContext)return;const{isPresent:e,onExitComplete:a}=this.node.presenceContext,{isPresent:n}=this.node.prevPresenceContext||{};if(!this.node.animationState||e===n)return;const i=this.node.animationState.setActive("exit",!e);a&&!e&&i.then(()=>{a(this.id)})}mount(){const{register:e,onExitComplete:a}=this.node.presenceContext||{};a&&a(this.id),e&&(this.unmount=e(this.id))}unmount(){}}const B9={animation:{Feature:V9},exit:{Feature:F9}};function Pu(t){return{point:{x:t.pageX,y:t.pageY}}}const U9=t=>e=>Tw(e)&&t(e,Pu(e));function dd(t,e,a,n){return Zd(t,e,U9(a),n)}const _R=({current:t})=>t?t.ownerDocument.defaultView:null,wE=(t,e)=>Math.abs(t-e);function $9(t,e){const a=wE(t.x,e.x),n=wE(t.y,e.y);return Math.sqrt(a**2+n**2)}const kE=new Set(["auto","scroll"]);class AR{constructor(e,a,{transformPagePoint:n,contextWindow:i=window,dragSnapToOrigin:r=!1,distanceThreshold:o=3,element:l}={}){if(this.startEvent=null,this.lastMoveEvent=null,this.lastMoveEventInfo=null,this.handlers={},this.contextWindow=window,this.scrollPositions=new Map,this.removeScrollListeners=null,this.onElementScroll=h=>{this.handleScroll(h.target)},this.onWindowScroll=()=>{this.handleScroll(window)},this.updatePoint=()=>{if(!(this.lastMoveEvent&&this.lastMoveEventInfo))return;const h=x0(this.lastMoveEventInfo,this.history),g=this.startEvent!==null,y=$9(h.offset,{x:0,y:0})>=this.distanceThreshold;if(!g&&!y)return;const{point:x}=h,{timestamp:v}=Et;this.history.push({...x,timestamp:v});const{onStart:w,onMove:S}=this.handlers;g||(w&&w(this.lastMoveEvent,h),this.startEvent=this.lastMoveEvent),S&&S(this.lastMoveEvent,h)},this.handlePointerMove=(h,g)=>{this.lastMoveEvent=h,this.lastMoveEventInfo=y0(g,this.transformPagePoint),Ne.update(this.updatePoint,!0)},this.handlePointerUp=(h,g)=>{this.end();const{onEnd:y,onSessionEnd:x,resumeAnimation:v}=this.handlers;if((this.dragSnapToOrigin||!this.startEvent)&&v&&v(),!(this.lastMoveEvent&&this.lastMoveEventInfo))return;const w=x0(h.type==="pointercancel"?this.lastMoveEventInfo:y0(g,this.transformPagePoint),this.history);this.startEvent&&y&&y(h,w),x&&x(h,w)},!Tw(e))return;this.dragSnapToOrigin=r,this.handlers=a,this.transformPagePoint=n,this.distanceThreshold=o,this.contextWindow=i||window;const c=Pu(e),d=y0(c,this.transformPagePoint),{point:u}=d,{timestamp:p}=Et;this.history=[{...u,timestamp:p}];const{onSessionStart:m}=a;m&&m(e,x0(d,this.history)),this.removeListeners=Tu(dd(this.contextWindow,"pointermove",this.handlePointerMove),dd(this.contextWindow,"pointerup",this.handlePointerUp),dd(this.contextWindow,"pointercancel",this.handlePointerUp)),l&&this.startScrollTracking(l)}startScrollTracking(e){let a=e.parentElement;for(;a;){const n=getComputedStyle(a);(kE.has(n.overflowX)||kE.has(n.overflowY))&&this.scrollPositions.set(a,{x:a.scrollLeft,y:a.scrollTop}),a=a.parentElement}this.scrollPositions.set(window,{x:window.scrollX,y:window.scrollY}),window.addEventListener("scroll",this.onElementScroll,{capture:!0,passive:!0}),window.addEventListener("scroll",this.onWindowScroll,{passive:!0}),this.removeScrollListeners=()=>{window.removeEventListener("scroll",this.onElementScroll,{capture:!0}),window.removeEventListener("scroll",this.onWindowScroll)}}handleScroll(e){const a=this.scrollPositions.get(e);if(!a)return;const n=e===window,i=n?{x:window.scrollX,y:window.scrollY}:{x:e.scrollLeft,y:e.scrollTop},r={x:i.x-a.x,y:i.y-a.y};r.x===0&&r.y===0||(n?this.lastMoveEventInfo&&(this.lastMoveEventInfo.point.x+=r.x,this.lastMoveEventInfo.point.y+=r.y):this.history.length>0&&(this.history[0].x-=r.x,this.history[0].y-=r.y),this.scrollPositions.set(e,i),Ne.update(this.updatePoint,!0))}updateHandlers(e){this.handlers=e}end(){this.removeListeners&&this.removeListeners(),this.removeScrollListeners&&this.removeScrollListeners(),this.scrollPositions.clear(),Mn(this.updatePoint)}}function y0(t,e){return e?{point:e(t.point)}:t}function SE(t,e){return{x:t.x-e.x,y:t.y-e.y}}function x0({point:t},e){return{point:t,delta:SE(t,ER(e)),offset:SE(t,W9(e)),velocity:G9(e,.1)}}function W9(t){return t[0]}function ER(t){return t[t.length-1]}function G9(t,e){if(t.length<2)return{x:0,y:0};let a=t.length-1,n=null;const i=ER(t);for(;a>=0&&(n=t[a],!(i.timestamp-n.timestamp>ji(e)));)a--;if(!n)return{x:0,y:0};const r=ln(i.timestamp-n.timestamp);if(r===0)return{x:0,y:0};const o={x:(i.x-n.x)/r,y:(i.y-n.y)/r};return o.x===1/0&&(o.x=0),o.y===1/0&&(o.y=0),o}function K9(t,{min:e,max:a},n){return e!==void 0&&t<e?t=n?Xe(e,t,n.min):Math.max(t,e):a!==void 0&&t>a&&(t=n?Xe(a,t,n.max):Math.min(t,a)),t}function _E(t,e,a){return{min:e!==void 0?t.min+e:void 0,max:a!==void 0?t.max+a-(t.max-t.min):void 0}}function J9(t,{top:e,left:a,bottom:n,right:i}){return{x:_E(t.x,a,i),y:_E(t.y,e,n)}}function AE(t,e){let a=e.min-t.min,n=e.max-t.max;return e.max-e.min<t.max-t.min&&([a,n]=[n,a]),{min:a,max:n}}function Q9(t,e){return{x:AE(t.x,e.x),y:AE(t.y,e.y)}}function X9(t,e){let a=.5;const n=ma(t),i=ma(e);return i>n?a=bl(e.min,e.max-n,t.min):n>i&&(a=bl(t.min,t.max-i,e.min)),On(0,1,a)}function Y9(t,e){const a={};return e.min!==void 0&&(a.min=e.min-t.min),e.max!==void 0&&(a.max=e.max-t.min),a}const Uv=.35;function Z9(t=Uv){return t===!1?t=0:t===!0&&(t=Uv),{x:EE(t,"left","right"),y:EE(t,"top","bottom")}}function EE(t,e,a){return{min:CE(t,e),max:CE(t,a)}}function CE(t,e){return typeof t=="number"?t:t[e]||0}const eU=new WeakMap;class tU{constructor(e){this.openDragLock=null,this.isDragging=!1,this.currentDirection=null,this.originPoint={x:0,y:0},this.constraints=!1,this.hasMutatedConstraints=!1,this.elastic=bt(),this.latestPointerEvent=null,this.latestPanInfo=null,this.visualElement=e}start(e,{snapToCursor:a=!1,distanceThreshold:n}={}){const{presenceContext:i}=this.visualElement;if(i&&i.isPresent===!1)return;const r=p=>{a?(this.stopAnimation(),this.snapToCursor(Pu(p).point)):this.pauseAnimation()},o=(p,m)=>{this.stopAnimation();const{drag:h,dragPropagation:g,onDragStart:y}=this.getProps();if(h&&!g&&(this.openDragLock&&this.openDragLock(),this.openDragLock=P7(h),!this.openDragLock))return;this.latestPointerEvent=p,this.latestPanInfo=m,this.isDragging=!0,this.currentDirection=null,this.resolveConstraints(),this.visualElement.projection&&(this.visualElement.projection.isAnimationBlocked=!0,this.visualElement.projection.target=void 0),Za(v=>{let w=this.getAxisMotionValue(v).get()||0;if(Zn.test(w)){const{projection:S}=this.visualElement;if(S&&S.layout){const T=S.layout.layoutBox[v];T&&(w=ma(T)*(parseFloat(w)/100))}}this.originPoint[v]=w}),y&&Ne.postRender(()=>y(p,m)),Dv(this.visualElement,"transform");const{animationState:x}=this.visualElement;x&&x.setActive("whileDrag",!0)},l=(p,m)=>{this.latestPointerEvent=p,this.latestPanInfo=m;const{dragPropagation:h,dragDirectionLock:g,onDirectionLock:y,onDrag:x}=this.getProps();if(!h&&!this.openDragLock)return;const{offset:v}=m;if(g&&this.currentDirection===null){this.currentDirection=aU(v),this.currentDirection!==null&&y&&y(this.currentDirection);return}this.updateAxis("x",m.point,v),this.updateAxis("y",m.point,v),this.visualElement.render(),x&&x(p,m)},c=(p,m)=>{this.latestPointerEvent=p,this.latestPanInfo=m,this.stop(p,m),this.latestPointerEvent=null,this.latestPanInfo=null},d=()=>Za(p=>{var m;return this.getAnimationState(p)==="paused"&&((m=this.getAxisMotionValue(p).animation)==null?void 0:m.play())}),{dragSnapToOrigin:u}=this.getProps();this.panSession=new AR(e,{onSessionStart:r,onStart:o,onMove:l,onSessionEnd:c,resumeAnimation:d},{transformPagePoint:this.visualElement.getTransformPagePoint(),dragSnapToOrigin:u,distanceThreshold:n,contextWindow:_R(this.visualElement),element:this.visualElement.current})}stop(e,a){const n=e||this.latestPointerEvent,i=a||this.latestPanInfo,r=this.isDragging;if(this.cancel(),!r||!i||!n)return;const{velocity:o}=i;this.startAnimation(o);const{onDragEnd:l}=this.getProps();l&&Ne.postRender(()=>l(n,i))}cancel(){this.isDragging=!1;const{projection:e,animationState:a}=this.visualElement;e&&(e.isAnimationBlocked=!1),this.panSession&&this.panSession.end(),this.panSession=void 0;const{dragPropagation:n}=this.getProps();!n&&this.openDragLock&&(this.openDragLock(),this.openDragLock=null),a&&a.setActive("whileDrag",!1)}updateAxis(e,a,n){const{drag:i}=this.getProps();if(!n||!qp(e,i,this.currentDirection))return;const r=this.getAxisMotionValue(e);let o=this.originPoint[e]+n[e];this.constraints&&this.constraints[e]&&(o=K9(o,this.constraints[e],this.elastic[e])),r.set(o)}resolveConstraints(){var r;const{dragConstraints:e,dragElastic:a}=this.getProps(),n=this.visualElement.projection&&!this.visualElement.projection.layout?this.visualElement.projection.measure(!1):(r=this.visualElement.projection)==null?void 0:r.layout,i=this.constraints;e&&zc(e)?this.constraints||(this.constraints=this.resolveRefConstraints()):e&&n?this.constraints=J9(n.layoutBox,e):this.constraints=!1,this.elastic=Z9(a),i!==this.constraints&&n&&this.constraints&&!this.hasMutatedConstraints&&Za(o=>{this.constraints!==!1&&this.getAxisMotionValue(o)&&(this.constraints[o]=Y9(n.layoutBox[o],this.constraints[o]))})}resolveRefConstraints(){const{dragConstraints:e,onMeasureDragConstraints:a}=this.getProps();if(!e||!zc(e))return!1;const n=e.current,{projection:i}=this.visualElement;if(!i||!i.layout)return!1;const r=rB(n,i.root,this.visualElement.getTransformPagePoint());let o=Q9(i.layout.layoutBox,r);if(a){const l=a(aB(o));this.hasMutatedConstraints=!!l,l&&(o=G4(l))}return o}startAnimation(e){const{drag:a,dragMomentum:n,dragElastic:i,dragTransition:r,dragSnapToOrigin:o,onDragTransitionEnd:l}=this.getProps(),c=this.constraints||{},d=Za(u=>{if(!qp(u,a,this.currentDirection))return;let p=c&&c[u]||{};o&&(p={min:0,max:0});const m=i?200:1e6,h=i?40:1e7,g={type:"inertia",velocity:n?e[u]:0,bounceStiffness:m,bounceDamping:h,timeConstant:750,restDelta:1,restSpeed:10,...r,...p};return this.startAxisValueAnimation(u,g)});return Promise.all(d).then(l)}startAxisValueAnimation(e,a){const n=this.getAxisMotionValue(e);return Dv(this.visualElement,e),n.start(kw(e,n,0,a,this.visualElement,!1))}stopAnimation(){Za(e=>this.getAxisMotionValue(e).stop())}pauseAnimation(){Za(e=>{var a;return(a=this.getAxisMotionValue(e).animation)==null?void 0:a.pause()})}getAnimationState(e){var a;return(a=this.getAxisMotionValue(e).animation)==null?void 0:a.state}getAxisMotionValue(e){const a=`_drag${e.toUpperCase()}`,n=this.visualElement.getProps(),i=n[a];return i||this.visualElement.getValue(e,(n.initial?n.initial[e]:void 0)||0)}snapToCursor(e){Za(a=>{const{drag:n}=this.getProps();if(!qp(a,n,this.currentDirection))return;const{projection:i}=this.visualElement,r=this.getAxisMotionValue(a);if(i&&i.layout){const{min:o,max:l}=i.layout.layoutBox[a],c=r.get()||0;r.set(e[a]-Xe(o,l,.5)+c)}})}scalePositionWithinConstraints(){if(!this.visualElement.current)return;const{drag:e,dragConstraints:a}=this.getProps(),{projection:n}=this.visualElement;if(!zc(a)||!n||!this.constraints)return;this.stopAnimation();const i={x:0,y:0};Za(o=>{const l=this.getAxisMotionValue(o);if(l&&this.constraints!==!1){const c=l.get();i[o]=X9({min:c,max:c},this.constraints[o])}});const{transformTemplate:r}=this.visualElement.getProps();this.visualElement.current.style.transform=r?r({},""):"none",n.root&&n.root.updateScroll(),n.updateLayout(),this.resolveConstraints(),Za(o=>{if(!qp(o,e,null))return;const l=this.getAxisMotionValue(o),{min:c,max:d}=this.constraints[o];l.set(Xe(c,d,i[o]))})}addListeners(){if(!this.visualElement.current)return;eU.set(this.visualElement,this);const e=this.visualElement.current,a=dd(e,"pointerdown",c=>{const{drag:d,dragListener:u=!0}=this.getProps();d&&u&&!V4(c.target)&&this.start(c)}),n=()=>{const{dragConstraints:c}=this.getProps();zc(c)&&c.current&&(this.constraints=this.resolveRefConstraints())},{projection:i}=this.visualElement,r=i.addEventListener("measure",n);i&&!i.layout&&(i.root&&i.root.updateScroll(),i.updateLayout()),Ne.read(n);const o=Zd(window,"resize",()=>this.scalePositionWithinConstraints()),l=i.addEventListener("didUpdate",({delta:c,hasLayoutChanged:d})=>{this.isDragging&&d&&(Za(u=>{const p=this.getAxisMotionValue(u);p&&(this.originPoint[u]+=c[u].translate,p.set(p.get()+c[u].translate))}),this.visualElement.render())});return()=>{o(),a(),r(),l&&l()}}getProps(){const e=this.visualElement.getProps(),{drag:a=!1,dragDirectionLock:n=!1,dragPropagation:i=!1,dragConstraints:r=!1,dragElastic:o=Uv,dragMomentum:l=!0}=e;return{...e,drag:a,dragDirectionLock:n,dragPropagation:i,dragConstraints:r,dragElastic:o,dragMomentum:l}}}function qp(t,e,a){return(e===!0||e===t)&&(a===null||a===t)}function aU(t,e=10){let a=null;return Math.abs(t.y)>e?a="y":Math.abs(t.x)>e&&(a="x"),a}class nU extends Jr{constructor(e){super(e),this.removeGroupControls=Ta,this.removeListeners=Ta,this.controls=new tU(e)}mount(){const{dragControls:e}=this.node.getProps();e&&(this.removeGroupControls=e.subscribe(this.controls)),this.removeListeners=this.controls.addListeners()||Ta}update(){const{dragControls:e}=this.node.getProps(),{dragControls:a}=this.node.prevProps||{};e!==a&&(this.removeGroupControls(),e&&(this.removeGroupControls=e.subscribe(this.controls)))}unmount(){this.removeGroupControls(),this.removeListeners()}}const jE=t=>(e,a)=>{t&&Ne.postRender(()=>t(e,a))};class iU extends Jr{constructor(){super(...arguments),this.removePointerDownListener=Ta}onPointerDown(e){this.session=new AR(e,this.createPanHandlers(),{transformPagePoint:this.node.getTransformPagePoint(),contextWindow:_R(this.node)})}createPanHandlers(){const{onPanSessionStart:e,onPanStart:a,onPan:n,onPanEnd:i}=this.node.getProps();return{onSessionStart:jE(e),onStart:jE(a),onMove:n,onEnd:(r,o)=>{delete this.session,i&&Ne.postRender(()=>i(r,o))}}}mount(){this.removePointerDownListener=dd(this.node.current,"pointerdown",e=>this.onPointerDown(e))}update(){this.session&&this.session.updateHandlers(this.createPanHandlers())}unmount(){this.removePointerDownListener(),this.session&&this.session.end()}}let v0=!1;class rU extends k.Component{componentDidMount(){const{visualElement:e,layoutGroup:a,switchLayoutGroup:n,layoutId:i}=this.props,{projection:r}=e;r&&(a.group&&a.group.add(r),n&&n.register&&i&&n.register(r),v0&&r.root.didUpdate(),r.addEventListener("animationComplete",()=>{this.safeToRemove()}),r.setOptions({...r.options,onExitComplete:()=>this.safeToRemove()})),Pm.hasEverUpdated=!0}getSnapshotBeforeUpdate(e){const{layoutDependency:a,visualElement:n,drag:i,isPresent:r}=this.props,{projection:o}=n;return o&&(o.isPresent=r,v0=!0,i||e.layoutDependency!==a||a===void 0||e.isPresent!==r?o.willUpdate():this.safeToRemove(),e.isPresent!==r&&(r?o.promote():o.relegate()||Ne.postRender(()=>{const l=o.getStack();(!l||!l.members.length)&&this.safeToRemove()}))),null}componentDidUpdate(){const{projection:e}=this.props.visualElement;e&&(e.root.didUpdate(),jw.postRender(()=>{!e.currentAnimation&&e.isLead()&&this.safeToRemove()}))}componentWillUnmount(){const{visualElement:e,layoutGroup:a,switchLayoutGroup:n}=this.props,{projection:i}=e;v0=!0,i&&(i.scheduleCheckAfterUnmount(),a&&a.group&&a.group.remove(i),n&&n.deregister&&n.deregister(i))}safeToRemove(){const{safeToRemove:e}=this.props;e&&e()}render(){return null}}function CR(t){const[e,a]=fR(),n=k.useContext(nw);return s.jsx(rU,{...t,layoutGroup:n,switchLayoutGroup:k.useContext(kR),isPresent:e,safeToRemove:a})}const oU={pan:{Feature:iU},drag:{Feature:nU,ProjectionNode:hR,MeasureLayout:CR}};function TE(t,e,a){const{props:n}=t;t.animationState&&n.whileHover&&t.animationState.setActive("whileHover",a==="Start");const i="onHover"+a,r=n[i];r&&Ne.postRender(()=>r(e,Pu(e)))}class sU extends Jr{mount(){const{current:e}=this.node;e&&(this.unmount=R7(e,(a,n)=>(TE(this.node,n,"Start"),i=>TE(this.node,i,"End"))))}unmount(){}}class lU extends Jr{constructor(){super(...arguments),this.isActive=!1}onFocus(){let e=!1;try{e=this.node.current.matches(":focus-visible")}catch{e=!0}!e||!this.node.animationState||(this.node.animationState.setActive("whileFocus",!0),this.isActive=!0)}onBlur(){!this.isActive||!this.node.animationState||(this.node.animationState.setActive("whileFocus",!1),this.isActive=!1)}mount(){this.unmount=Tu(Zd(this.node.current,"focus",()=>this.onFocus()),Zd(this.node.current,"blur",()=>this.onBlur()))}unmount(){}}function NE(t,e,a){const{props:n}=t;if(t.current instanceof HTMLButtonElement&&t.current.disabled)return;t.animationState&&n.whileTap&&t.animationState.setActive("whileTap",a==="Start");const i="onTap"+(a==="End"?"":a),r=n[i];r&&Ne.postRender(()=>r(e,Pu(e)))}class cU extends Jr{mount(){const{current:e}=this.node;e&&(this.unmount=M7(e,(a,n)=>(NE(this.node,n,"Start"),(i,{success:r})=>NE(this.node,i,r?"End":"Cancel")),{useGlobalTarget:this.node.props.globalTapTarget}))}unmount(){}}const $v=new WeakMap,b0=new WeakMap,dU=t=>{const e=$v.get(t.target);e&&e(t)}
67,uU=t=>{t.forEach(dU)};function pU({root:t,...e}){const a=t||document;b0.has(a)||b0.set(a,{});const n=b0.get(a),i=JSON.stringify(e);return n[i]||(n[i]=new IntersectionObserver(uU,{root:t,...e})),n[i]}function mU(t,e,a){const n=pU(e);return $v.set(t,a),n.observe(t),()=>{$v.delete(t),n.unobserve(t)}}const hU={some:0,all:1};class fU extends Jr{constructor(){super(...arguments),this.hasEnteredView=!1,this.isInView=!1}startObserver(){this.unmount();const{viewport:e={}}=this.node.getProps(),{root:a,margin:n,amount:i="some",once:r}=e,o={root:a?a.current:void 0,rootMargin:n,threshold:typeof i=="number"?i:hU[i]},l=c=>{const{isIntersecting:d}=c;if(this.isInView===d||(this.isInView=d,r&&!d&&this.hasEnteredView))return;d&&(this.hasEnteredView=!0),this.node.animationState&&this.node.animationState.setActive("whileInView",d);const{onViewportEnter:u,onViewportLeave:p}=this.node.getProps(),m=d?u:p;m&&m(c)};return mU(this.node.current,o,l)}mount(){this.startObserver()}update(){if(typeof IntersectionObserver>"u")return;const{props:e,prevProps:a}=this.node;["amount","margin","root"].some(gU(e,a))&&this.startObserver()}unmount(){}}function gU({viewport:t={}},{viewport:e={}}={}){return a=>t[a]!==e[a]}const yU={inView:{Feature:fU},tap:{Feature:cU},focus:{Feature:lU},hover:{Feature:sU}},xU={layout:{ProjectionNode:hR,MeasureLayout:CR}},vU={...B9,...yU,...oU,...xU},_=q9(vU,z9),bU=50,IE=()=>({current:0,offset:[],progress:0,scrollLength:0,targetOffset:0,targetLength:0,containerLength:0,velocity:0}),wU=()=>({time:0,x:IE(),y:IE()}),kU={x:{length:"Width",position:"Left"},y:{length:"Height",position:"Top"}};function PE(t,e,a,n){const i=a[e],{length:r,position:o}=kU[e],l=i.current,c=a.time;i.current=t[`scroll${o}`],i.scrollLength=t[`scroll${r}`]-t[`client${r}`],i.offset.length=0,i.offset[0]=0,i.offset[1]=i.scrollLength,i.progress=bl(0,i.scrollLength,i.current);const d=n-c;i.velocity=d>bU?0:lw(i.current-l,d)}function SU(t,e,a){PE(t,"x",e,a),PE(t,"y",e,a),e.time=a}function _U(t,e){const a={x:0,y:0};let n=t;for(;n&&n!==e;)if(Cw(n))a.x+=n.offsetLeft,a.y+=n.offsetTop,n=n.offsetParent;else if(n.tagName==="svg"){const i=n.getBoundingClientRect();n=n.parentElement;const r=n.getBoundingClientRect();a.x+=i.left-r.left,a.y+=i.top-r.top}else if(n instanceof SVGGraphicsElement){const{x:i,y:r}=n.getBBox();a.x+=i,a.y+=r;let o=null,l=n.parentNode;for(;!o;)l.tagName==="svg"&&(o=l),l=n.parentNode;n=o}else break;return a}const Wv={start:0,center:.5,end:1};function RE(t,e,a=0){let n=0;if(t in Wv&&(t=Wv[t]),typeof t=="string"){const i=parseFloat(t);t.endsWith("px")?n=i:t.endsWith("%")?t=i/100:t.endsWith("vw")?n=i/100*document.documentElement.clientWidth:t.endsWith("vh")?n=i/100*document.documentElement.clientHeight:t=i}return typeof t=="number"&&(n=e*t),a+n}const AU=[0,0];function EU(t,e,a,n){let i=Array.isArray(t)?t:AU,r=0,o=0;return typeof t=="number"?i=[t,t]:typeof t=="string"&&(t=t.trim(),t.includes(" ")?i=t.split(" "):i=[t,Wv[t]?t:"0"]),r=RE(i[0],a,n),o=RE(i[1],e),r-o}const CU={All:[[0,0],[1,1]]},jU={x:0,y:0};function TU(t){return"getBBox"in t&&t.tagName!=="svg"?t.getBBox():{width:t.clientWidth,height:t.clientHeight}}function NU(t,e,a){const{offset:n=CU.All}=a,{target:i=t,axis:r="y"}=a,o=r==="y"?"height":"width",l=i!==t?_U(i,t):jU,c=i===t?{width:t.scrollWidth,height:t.scrollHeight}:TU(i),d={width:t.clientWidth,height:t.clientHeight};e[r].offset.length=0;let u=!e[r].interpolate;const p=n.length;for(let m=0;m<p;m++){const h=EU(n[m],d[o],c[o],l[r]);!u&&h!==e[r].interpolatorOffsets[m]&&(u=!0),e[r].offset[m]=h}u&&(e[r].interpolate=gw(e[r].offset,y4(n),{clamp:!1}),e[r].interpolatorOffsets=[...e[r].offset]),e[r].progress=On(0,1,e[r].interpolate(e[r].current))}function IU(t,e=t,a){if(a.x.targetOffset=0,a.y.targetOffset=0,e!==t){let n=e;for(;n&&n!==t;)a.x.targetOffset+=n.offsetLeft,a.y.targetOffset+=n.offsetTop,n=n.offsetParent}a.x.targetLength=e===t?e.scrollWidth:e.clientWidth,a.y.targetLength=e===t?e.scrollHeight:e.clientHeight,a.x.containerLength=t.clientWidth,a.y.containerLength=t.clientHeight}function PU(t,e,a,n={}){return{measure:i=>{IU(t,n.target,a),SU(t,a,i),(n.offset||n.target)&&NU(t,a,n)},notify:()=>e(a)}}const Cc=new WeakMap,LE=new WeakMap,w0=new WeakMap,OE=t=>t===document.scrollingElement?window:t;function jR(t,{container:e=document.scrollingElement,...a}={}){if(!e)return Ta;let n=w0.get(e);n||(n=new Set,w0.set(e,n));const i=wU(),r=PU(e,t,i,a);if(n.add(r),!Cc.has(e)){const l=()=>{for(const p of n)p.measure(Et.timestamp);Ne.preUpdate(c)},c=()=>{for(const p of n)p.notify()},d=()=>Ne.read(l);Cc.set(e,d);const u=OE(e);window.addEventListener("resize",d,{passive:!0}),e!==document.documentElement&&LE.set(e,$7(e,d)),u.addEventListener("scroll",d,{passive:!0}),d()}const o=Cc.get(e);return Ne.read(o,!1,!0),()=>{var d;Mn(o);const l=w0.get(e);if(!l||(l.delete(r),l.size))return;const c=Cc.get(e);Cc.delete(e),c&&(OE(e).removeEventListener("scroll",c),(d=LE.get(e))==null||d(),window.removeEventListener("resize",c))}}const ME=new Map;function RU(t){const e={value:0},a=jR(n=>{e.value=n[t.axis].progress*100},t);return{currentTime:e,cancel:a}}function TR({source:t,container:e,...a}){const{axis:n}=a;t&&(e=t);const i=ME.get(e)??new Map;ME.set(e,i);const r=a.target??"self",o=i.get(r)??{},l=n+(a.offset??[]).join(",");return o[l]||(o[l]=!a.target&&w4()?new ScrollTimeline({source:e,axis:n}):RU({container:e,...a})),o[l]}function LU(t,e){const a=TR(e);return t.attachTimeline({timeline:e.target?void 0:a,observe:n=>(n.pause(),F4(i=>{n.time=n.iterationDuration*i},a))})}function OU(t){return t.length===2}function MU(t,e){return OU(t)?jR(a=>{t(a[e.axis].progress,a)},e):F4(t,TR(e))}function DU(t,{axis:e="y",container:a=document.scrollingElement,...n}={}){if(!a)return Ta;const i={axis:e,container:a,...n};return typeof t=="function"?MU(t,i):LU(t,i)}const qU=()=>({scrollX:Cn(0),scrollY:Cn(0),scrollXProgress:Cn(0),scrollYProgress:Cn(0)}),zp=t=>t?!t.current:!1;function zU({container:t,target:e,...a}={}){const n=zr(qU),i=k.useRef(null),r=k.useRef(!1),o=k.useCallback(()=>(i.current=DU((l,{x:c,y:d})=>{n.scrollX.set(c.current),n.scrollXProgress.set(c.progress),n.scrollY.set(d.current),n.scrollYProgress.set(d.progress)},{...a,container:(t==null?void 0:t.current)||void 0,target:(e==null?void 0:e.current)||void 0}),()=>{var l;(l=i.current)==null||l.call(i)}),[t,e,JSON.stringify(a.offset)]);return rg(()=>{if(r.current=!1,zp(t)||zp(e)){r.current=!0;return}else return o()},[o]),k.useEffect(()=>{if(r.current)return Jd(!zp(t)),Jd(!zp(e)),o()},[o]),n}function VU(t){const e=zr(()=>Cn(t)),{isStatic:a}=k.useContext(cg);if(a){const[,n]=k.useState(t);k.useEffect(()=>e.on("change",n),[])}return e}function NR(t,e){const a=VU(e()),n=()=>a.set(e());return n(),rg(()=>{const i=()=>Ne.preRender(n,!1,!0),r=t.map(o=>
67o.on("change",i));return()=>{r.forEach(o=>o()),Mn(n)}}),a}function HU(t){ld.current=[],t();const e=NR(ld.current,t);return ld.current=void 0,e}function IR(t,e,a,n){if(typeof t=="function")return HU(t);if(a!==void 0&&!Array.isArray(a)&&typeof e!="function")return FU(t,e,a,n);const o=typeof e=="function"?e:G7(e,a,n);return Array.isArray(t)?DE(t,o):DE([t],([l])=>o(l))}function DE(t,e){const a=zr(()=>[]);return NR(t,()=>{a.length=0;const n=t.length;for(let i=0;i<n;i++)a[i]=t[i].get();return e(a)})}function FU(t,e,a,n){const i=zr(()=>Object.keys(a)),r=zr(()=>({}));for(const o of i)r[o]=IR(t,e,a[o],n);return r}const BU={some:0,all:1};function UU(t,e,{root:a,margin:n,amount:i="some"}={}){const r=Ew(t),o=new WeakMap,l=d=>{d.forEach(u=>{const p=o.get(u.target);if(u.isIntersecting!==!!p)if(u.isIntersecting){const m=e(u.target,u);typeof m=="function"?o.set(u.target,m):c.unobserve(u.target)}else typeof p=="function"&&(p(u),o.delete(u.target))})},c=new IntersectionObserver(l,{root:a,rootMargin:n,threshold:typeof i=="number"?i:BU[i]});return r.forEach(d=>c.observe(d)),()=>c.disconnect()}function we(t,{root:e,margin:a,amount:n,once:i=!1,initial:r=!1}={}){const[o,l]=k.useState(r);return k.useEffect(()=>{if(!t.current||i&&o)return;const c=()=>(l(!0),i?void 0:()=>l(!1)),d={root:e&&e.current||void 0,margin:a,amount:n};return UU(t.current,c,d)},[e,t,a,i,n]),o}var qE={};/**
68 * @license
69 * Copyright 2017 Google LLC
70 *
71 * Licensed under the Apache License, Version 2.0 (the "License");
72 * you may not use this file except in compliance with the License.
73 * You may obtain a copy of the License at
74 *
75 *   http://www.apache.org/licenses/LICENSE-2.0
76 *
77 * Unless required by applicable law or agreed to in writing, software
78 * distributed under the License is distributed on an "AS IS" BASIS,
79 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
80 * See the License for the specific language governing permissions and
81 * limitations under the License.
82 */const PR=function(t){const e=[];let a=0;for(let n=0;n<t.length;n++){let i=t.charCodeAt(n);i<128?e[a++]=i:i<2048?(e[a++]=i>>6|192,e[a++]=i&63|128):(i&64512)===55296&&n+1<t.length&&(t.charCodeAt(n+1)&64512)===56320?(i=65536+((i&1023)<<10)+(t.charCodeAt(++n)&1023),e[a++]=i>>18|240,e[a++]=i>>12&63|128,e[a++]=i>>6&63|128,e[a++]=i&63|128):(e[a++]=i>>12|224,e[a++]=i>>6&63|128,e[a++]=i&63|128)}return e},$U=function(t){const e=[];let a=0,n=0;for(;a<t.length;){const i=t[a++];if(i<128)e[n++]=String.fromCharCode(i);else if(i>191&&i<224){const r=t[a++];e[n++]=String.fromCharCode((i&31)<<6|r&63)}else if(i>239&&i<365){const r=t[a++],o=t[a++],l=t[a++],c=((i&7)<<18|(r&63)<<12|(o&63)<<6|l&63)-65536;e[n++]=String.fromCharCode(55296+(c>>10)),e[n++]=String.fromCharCode(56320+(c&1023))}else{const r=t[a++],o=t[a++];e[n++]=String.fromCharCode((i&15)<<12|(r&63)<<6|o&63)}}return e.join("")},RR={byteToCharMap_:null,charToByteMap_:null,byteToCharMapWebSafe_:null,charToByteMapWebSafe_:null,ENCODED_VALS_BASE:"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789",get ENCODED_VALS(){return this.ENCODED_VALS_BASE+"+/="},get ENCODED_VALS_WEBSAFE(){return this.ENCODED_VALS_BASE+"-_."},HAS_NATIVE_SUPPORT:typeof atob=="function",encodeByteArray(t,e){if(!Array.isArray(t))throw Error("encodeByteArray takes an array as a parameter");this.init_();const a=e?this.byteToCharMapWebSafe_:this.byteToCharMap_,n=[];for(let i=0;i<t.length;i+=3){const r=t[i],o=i+1<t.length,l=o?t[i+1]:0,c=i+2<t.length,d=c?t[i+2]:0,u=r>>2,p=(r&3)<<4|l>>4;let m=(l&15)<<2|d>>6,h=d&63;c||(h=64,o||(m=64)),n.push(a[u],a[p],a[m],a[h])}return n.join("")},encodeString(t,e){return this.HAS_NATIVE_SUPPORT&&!e?btoa(t):this.encodeByteArray(PR(t),e)},decodeString(t,e){return this.HAS_NATIVE_SUPPORT&&!e?atob(t):$U(this.decodeStringToByteArray(t,e))},decodeStringToByteArray(t,e){this.init_();const a=e?this.charToByteMapWebSafe_:this.charToByteMap_,n=[];for(let i=0;i<t.length;){const r=a[t.charAt(i++)],l=i<t.length?a[t.charAt(i)]:0;++i;const d=i<t.length?a[t.charAt(i)]:64;++i;const p=i<t.length?a[t.charAt(i)]:64;if(++i,r==null||l==null||d==null||p==null)throw new WU;const m=r<<2|l>>4;if(n.push(m),d!==64){const h=l<<4&240|d>>2;if(n.push(h),p!==64){const g=d<<6&192|p;n.push(g)}}}return n},init_(){if(!this.byteToCharMap_){this.byteToCharMap_={},this.charToByteMap_={},this.byteToCharMapWebSafe_={},this.charToByteMapWebSafe_={};for(let t=0;t<this.ENCODED_VALS.length;t++)this.byteToCharMap_[t]=this.ENCODED_VALS.charAt(t),this.charToByteMap_[this.byteToCharMap_[t]]=t,this.byteToCharMapWebSafe_[t]=this.ENCODED_VALS_WEBSAFE.charAt(t),this.charToByteMapWebSafe_[this.byteToCharMapWebSafe_[t]]=t,t>=this.ENCODED_VALS_BASE.length&&(this.charToByteMap_[this.ENCODED_VALS_WEBSAFE.charAt(t)]=t,this.charToByteMapWebSafe_[this.ENCODED_VALS.charAt(t)]=t)}}};
82class WU extends Error{constructor(){super(...arguments),this.name="DecodeBase64StringError"}}const GU=function(t){const e=PR(t);return RR.encodeByteArray(e,!0)},jh=function(t){return GU(t).replace(/\./g,"")},LR=function(t){try{return RR.decodeString(t,!0)}catch(e){console.error("base64Decode failed: ",e)}return null};/**
83 * @license
84 * Copyright 2022 Google LLC
85 *
86 * Licensed under the Apache License, Version 2.0 (the "License");
87 * you may not use this file except in compliance with the License.
88 * You may obtain a copy of the License at
89 *
90 *   http://www.apache.org/licenses/LICENSE-2.0
91 *
92 * Unless required by applicable law or agreed to in writing, software
93 * distributed under the License is distributed on an "AS IS" BASIS,
94 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
95 * See the License for the specific language governing permissions and
96 * limitations under the License.
97 */function KU(){if(typeof self<"u")return self;if(typeof window<"u")return window;if(typeof global<"u")return global;throw new Error("Unable to locate global object.")}/**
98 * @license
99 * Copyright 2022 Google LLC
100 *
101 * Licensed under the Apache License, Version 2.0 (the "License");
102 * you may not use this file except in compliance with the License.
103 * You may obtain a copy of the License at
104 *
105 *   http://www.apache.org/licenses/LICENSE-2.0
106 *
107 * Unless required by applicable law or agreed to in writing, software
108 * distributed under the License is distributed on an "AS IS" BASIS,
109 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
110 * See the License for the specific language governing permissions and
111 * limitations under the License.
112 */const JU=()=>KU().__FIREBASE_DEFAULTS__,QU=()=>{if(typeof process>"u"||typeof qE>"u")return;const t=qE.__FIREBASE_DEFAULTS__;if(t)return JSON.parse(t)},XU=()=>{if(typeof document>"u")return;let t;try{t=document.cookie.match(/__FIREBASE_DEFAULTS__=([^;]+)/)}catch{return}const e=t&&LR(t[1]);return e&&JSON.parse(e)},ug=()=>{try{return JU()||QU()||XU()}catch(t){console.info(`Unable to get __FIREBASE_DEFAULTS__ due to: ${t}`);return}},OR=t=>{var e,a;return(a=(e=ug())===null||e===void 0?void 0:e.emulatorHosts)===null||a===void 0?void 0:a[t]},MR=t=>{const e=OR(t);if(!e)return;const a=e.lastIndexOf(":");if(a<=0||a+1===e.length)throw new Error(`Invalid host ${e} with no separate hostname and port!`);const n=parseInt(e.substring(a+1),10);return e[0]==="["?[e.substring(1,a-1),n]:[e.substring(0,a),n]},DR=()=>{var t;return(t=ug())===null||t===void 0?void 0:t.config},qR=t=>{var e;return(e=ug())===null||e===void 0?void 0:e[`_${t}`]};/**
113 * @license
114 * Copyright 2017 Google LLC
115 *
116 * Licensed under the Apache License, Version 2.0 (the "License");
117 * you may not use this file except in compliance with the License.
118 * You may obtain a copy of the License at
119 *
120 *   http://www.apache.org/licenses/LICENSE-2.0
121 *
122 * Unless required by applicable law or agreed to in writing, software
123 * distributed under the License is distributed on an "AS IS" BASIS,
124 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
125 * See the License for the specific language governing permissions and
126 * limitations under the License.
127 */class YU{constructor(){this.reject=()=>{},this.resolve=()=>{},this.promise=new Promise((e,a)=>{this.resolve=e,this.reject=a})}wrapCallback(e){return(a,n)=>{a?this.reject(a):this.resolve(n),typeof e=="function"&&(this.promise.catch(()=>{}),e.length===1?e(a):e(a,n))}}}/**
128 * @license
129 * Copyright 2021 Google LLC
130 *
131 * Licensed under the Apache License, Version 2.0 (the "License");
132 * you may not use this file except in compliance with the License.
133 * You may obtain a copy of the License at
134 *
135 *   http://www.apache.org/licenses/LICENSE-2.0
136 *
137 * Unless required by applicable law or agreed to in writing, software
138 * distributed under the License is distributed on an "AS IS" BASIS,
139 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
140 * See the License for the specific language governing permissions and
141 * limitations under the License.
142 */function zR(t,e){if(t.uid)throw new Error('The "uid" field is no longer supported by mockUserToken. Please use "sub" instead for Firebase Auth User ID.');const a={alg:"none",type:"JWT"}
142,n=e||"demo-project",i=t.iat||0,r=t.sub||t.user_id;if(!r)throw new Error("mockUserToken must contain 'sub' or 'user_id' field!");const o=Object.assign({iss:`https://securetoken.google.com/${n}`,aud:n,iat:i,exp:i+3600,auth_time:i,sub:r,user_id:r,firebase:{sign_in_provider:"custom",identities:{}}},t);return[jh(JSON.stringify(a)),jh(JSON.stringify(o)),""].join(".")}/**
143 * @license
144 * Copyright 2017 Google LLC
145 *
146 * Licensed under the Apache License, Version 2.0 (the "License");
147 * you may not use this file except in compliance with the License.
148 * You may obtain a copy of the License at
149 *
150 *   http://www.apache.org/licenses/LICENSE-2.0
151 *
152 * Unless required by applicable law or agreed to in writing, software
153 * distributed under the License is distributed on an "AS IS" BASIS,
154 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
155 * See the License for the specific language governing permissions and
156 * limitations under the License.
157 */function ra(){return typeof navigator<"u"&&typeof navigator.userAgent=="string"?navigator.userAgent:""}function ZU(){return typeof window<"u"&&!!(window.cordova||window.phonegap||window.PhoneGap)&&/ios|iphone|ipod|ipad|android|blackberry|iemobile/i.test(ra())}function e$(){var t;const e=(t=ug())===null||t===void 0?void 0:t.forceEnvironment;if(e==="node")return!0;if(e==="browser")return!1;try{return Object.prototype.toString.call(global.process)==="[object process]"}catch{return!1}}function t$(){return typeof navigator<"u"&&navigator.userAgent==="Cloudflare-Workers"}function Dw(){const t=typeof chrome=="object"?chrome.runtime:typeof browser=="object"?browser.runtime:void 0;return typeof t=="object"&&t.id!==void 0}function a$(){return typeof navigator=="object"&&navigator.product==="ReactNative"}function n$(){const t=ra();return t.indexOf("MSIE ")>=0||t.indexOf("Trident/")>=0}function i$(){return!e$()&&!!navigator.userAgent&&navigator.userAgent.includes("Safari")&&!navigator.userAgent.includes("Chrome")}function qw(){try{return typeof indexedDB=="object"}catch{return!1}}function zw(){return new Promise((t,e)=>{try{let a=!0;const n="validate-browser-context-for-indexeddb-analytics-module",i=self.indexedDB.open(n);i.onsuccess=()=>{i.result.close(),a||self.indexedDB.deleteDatabase(n),t(!0)},i.onupgradeneeded=()=>{a=!1},i.onerror=()=>{var r;e(((r=i.error)===null||r===void 0?void 0:r.message)||"")}}catch(a){e(a)}})}function VR(){return!(typeof navigator>"u"||!navigator.cookieEnabled)}/**
158 * @license
159 * Copyright 2017 Google LLC
160 *
161 * Licensed under the Apache License, Version 2.0 (the "License");
162 * you may not use this file except in compliance with the License.
163 * You may obtain a copy of the License at
164 *
165 *   http://www.apache.org/licenses/LICENSE-2.0
166 *
167 * Unless required by applicable law or agreed to in writing, software
168 * distributed under the License is distributed on an "AS IS" BASIS,
169 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
170 * See the License for the specific language governing permissions and
171 * limitations under the License.
172 */const r$="FirebaseError";class gn extends Error{constructor(e,a,n){super(a),this.code=e,this.customData=n,this.name=r$,Object.setPrototypeOf(this,gn.prototype),Error.captureStackTrace&&Error.captureStackTrace(this,ds.prototype.create)}}class ds{constructor(e,a,n){this.service=e,this.serviceName=a,this.errors=n}create(e,...a){const n=a[0]||{},i=`${this.service}/${e}`,r=this.errors[e],o=r?o$(r,n):"Error",l=`${this.serviceName}: ${o} (${i}).`;return new gn(i,l,n)}}function o$(t,e){return t.replace(s$,(a,n)=>{const i=e[n];return i!=null?String(i):`<${n}?>`})}const s$=/\{\$([^}]+)}/g;function l$(t){for(const e in t)if(Object.prototype.hasOwnProperty.call(t,e))return!1;return!0}function eu(t,e){if(t===e)return!0;const a=Object.keys(t),n=Object.keys(e);for(const i of a){if(!n.includes(i))return!1;const r=t[i],o=e[i];if(zE(r)&&zE(o)){if(!eu(r,o))return!1}else if(r!==o)return!1}for(const i of n)if(!a.includes(i))return!1;return!0}function zE(t){return t!==null&&typeof t=="object"}/**
173 * @license
174 * Copyright 2017 Google LLC
175 *
176 * Licensed under the Apache License, Version 2.0 (the "License");
177 * you may not use this file except in compliance with the License.
178 * You may obtain a copy of the License at
179 *
180 *   http://www.apache.org/licenses/LICENSE-2.0
181 *
182 * Unless required by applicable law or agreed to in writing, software
183 * distributed under the License is distributed on an "AS IS" BASIS,
184 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
185 * See the License for the specific language governing permissions and
186 * limitations under the License.
187 */function Ru(t){const e=[];for(const[a,n]of Object.entries(t))Array.isArray(n)?n.forEach(i=>{e.push(encodeURIComponent(a)+"="+encodeURIComponent(i))}):e.push(encodeURIComponent(a)+"="+encodeURIComponent(n));return e.length?"&"+e.join("&"):""}function c$(t,e){const a=new d$(t,e);return a.subscribe.bind(a)}class d${constructor(e,a){this.observers=[],this.unsubscribes=[],this.observerCount=0,this.task=Promise.resolve(),this.finalized=!1,this.onNoObservers=a,this.task.then(()=>{e(this)}).catch(n=>{this.error(n)})}next(e){this.forEachObserver(a=>{a.next(e)})}error(e){this.forEachObserver(a=>{a.error(e)}),this.close(e)}complete(){this.forEachObserver(e=>{e.complete()}),this.close()}subscribe(e,a,n){let i;if(e===void 0&&a===void 0&&n===void 0)throw new Error("Missing Observer.");u$(e,["next","error","complete"])?i=e:i={next:e,error:a,complete:n},i.next===void 0&&(i.next=k0),i.error===void 0&&(i.error=k0),i.complete===void 0&&(i.complete=k0);const r=this.unsubscribeOne.bind(this,this.observers.length);return this.finalized&&this.task.then(()=>{try{this.finalError?i.error(this.finalError):i.complete()}catch{}}),this.observers.push(i),r}unsubscribeOne(e){this.observers===void 0||this.observers[e]===void 0||(delete this.observers[e],this.observerCount-=1,this.observerCount===0&&this.onNoObservers!==void 0&&this.onNoObservers(this))}forEachObserver(e){if(!this.finalized)for(let a=0;a<this.observers.length;a++)this.sendOne(a,e)}sendOne(e,a){this.task.then(()=>{if(this.observers!==void 0&&this.observers[e]!==void 0)try{a(this.observers[e])}catch(n){typeof console<"u"&&console.error&&console.error(n)}})}close(e){this.finalized||(this.finalized=!0,e!==void 0&&(this.finalError=e),this.task.then(()=>{this.observers=void 0,this.onNoObservers=void 0}))}}function u$(t,e){if(typeof t!="object"||t===null)return!1;for(const a of e)if(a in t&&typeof t[a]=="function")return!0;return!1}function k0(){}/**
188 * @license
189 * Copyright 2019 Google LLC
190 *
191 * Licensed under the Apache License, Version 2.0 (the "License");
192 * you may not use this file except in compliance with the License.
193 * You may obtain a copy of the License at
194 *
195 *   http://www.apache.org/licenses/LICENSE-2.0
196 *
197 * Unless required by applicable law or agreed to in writing, software
198 * distributed under the License is distributed on an "AS IS" BASIS,
199 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
200 * See the License for the specific language governing permissions and
201 * limitations under the License.
202 */const p$=1e3,m$=2,h$=4*60*60*1e3,f$=.5;function VE(t,e=p$,a=m$){const n=e*Math.pow(a,t),i=Math.round(f$*n*(Math.random()-.5)*2);return Math.min(h$,n+i)}/**
203 * @license
204 * Copyright 2021 Google LLC
205 *
206 * Licensed under the Apache License, Version 2.0 (the "License");
207 * you may not use this file except in compliance with the License.
208 * You may obtain a copy of the License at
209 *
210 *   http://www.apache.org/licenses/LICENSE-2.0
211 *
212 * Unless required by applicable law or agreed to in writing, software
213 * distributed under the License is distributed on an "AS IS" BASIS,
214 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
215 * See the License for the specific language governing permissions and
216 * limitations under the License.
217 */function et(t){return t&&t._delegate?t._delegate:t}class hn{constructor(e,a,n){this.name=e,this.instanceFactory=a,this.type=n,this.multipleInstances=!1,this.serviceProps={},this.instantiationMode="LAZY",this.onInstanceCreated=null}setInstantiationMode(e){return this.instantiationMode=e,this}setMultipleInstances(e){return this.multipleInstances=e,this}setServiceProps(e){return this.serviceProps=e,this}setInstanceCreatedCallback(e){return this.onInstanceCreated=e,this}}/**
218 * @license
219 * Copyright 2019 Google LLC
220 *
221 * Licensed under the Apache License, Version 2.0 (the "License");
222 * you may not use this file except in compliance with the License.
223 * You may obtain a copy of the License at
224 *
225 *   http://www.apache.org/licenses/LICENSE-2.0
226 *
227 * Unless required by applicable law or agreed to in writing, software
228 * distributed under the License is distributed on an "AS IS" BASIS,
229 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
230 * See the License for the specific language governing permissions and
231 * limitations under the License.
232 */const fo="[DEFAULT]";/**
233 * @license
234 * Copyright 2019 Google LLC
235 *
236 * Licensed under the Apache License, Version 2.0 (the "License");
237 * you may not use this file except in compliance with the License.
238 * You may obtain a copy of the License at
239 *
240 *   http://www.apache.org/licenses/LICENSE-2.0
241 *
242 * Unless required by applicable law or agreed to in writing, software
243 * distributed under the License is distributed on an "AS IS" BASIS,
244 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
245 * See the License for the specific language governing permissions and
246 * limitations under the License.
247 */class g${constructor(e,a){this.name=e,this.container=a,this.component=null,this.instances=new Map,this.instancesDeferred=new Map,this.instancesOptions=new Map,this.onInitCallbacks=new Map}get(e){const a=this.normalizeInstanceIdentifier(e);if(!this.instancesDeferred.has(a)){const n=new YU;if(this.instancesDeferred.set(a,n),this.isInitialized(a)||this.shouldAutoInitialize())try{const i=this.getOrInitializeService({instanceIdentifier:a});i&&n.resolve(i)}catch{}}return this.instancesDeferred.get(a).promise}getImmediate(e){var a;const n=this.normalizeInstanceIdentifier(e==null?void 0:e.identifier),i=(a=e==null?void 0:e.optional)!==null&&a!==void 0?a:!1;if(this.isInitialized(n)||this.shouldAutoInitialize())try{return this.getOrInitializeService({instanceIdentifier:n})}catch(r){if(i)return null;throw r}else{if(i)return null;throw Error(`Service ${this.name} is not available`)}}getComponent(){return this.component}setComponent(e){if(e.name!==this.name)throw Error(`Mismatching Component ${e.name} for Provider ${this.name}.`);if(this.component)throw Error(`Component for ${this.name} has already been provided`);if(this.component=e,!!this.shouldAutoInitialize()){if(x$(e))try{this.getOrInitializeService({instanceIdentifier:fo})}catch{}for(const[a,n]of this.instancesDeferred.entries()){const i=this.normalizeInstanceIdentifier(a);try{const r=this.getOrInitializeService({instanceIdentifier:i});n.resolve(r)}catch{}}}}clearInstance(e=fo){this.instancesDeferred.delete(e),this.instancesOptions.delete(e),this.instances.delete(e)}async delete(){const e=Array.from(this.instances.values());await Promise.all([...e.filter(a=>"INTERNAL"in a).map(a=>a.INTERNAL.delete()),...e.filter(a=>"_delete"in a).map(a=>a._delete())])}isComponentSet(){return this.component!=null}isInitialized(e=fo){return this.instances.has(e)}getOptions(e=fo){return this.instancesOptions.get(e)||{}}initialize(e={}){const{options:a={}}=e,n=this.normalizeInstanceIdentifier(e.instanceIdentifier);if(this.isInitialized(n))throw Error(`${this.name}(${n}) has already been initialized`);if(!this.isComponentSet())throw Error(`Component ${this.name} has not been registered yet`);const i=this.getOrInitializeService({instanceIdentifier:n,options:a});for(const[r,o]of this.instancesDeferred.entries()){const l=this.normalizeInstanceIdentifier(r);n===l&&o.resolve(i)}return i}onInit(e,a){var n;const i=this.normalizeInstanceIdentifier(a),r=(n=this.onInitCallbacks.get(i))!==null&&n!==void 0?n:new Set;r.add(e),this.onInitCallbacks.set(i,r);const o=this.instances.get(i);return o&&e(o,i),()=>{r.delete(e)}}invokeOnInitCallbacks(e,a){const n=this.onInitCallbacks.get(a);if(n)for(const i of n)try{i(e,a)}catch{}}getOrInitializeService({instanceIdentifier:e,options:a={}}){let n=this.instances.get(e);if(!n&&this.component&&(n=this.component.instanceFactory(this.container,{instanceIdentifier:y$(e),options:a}),this.instances.set(e,n),this.instancesOptions.set(e,a),this.invokeOnInitCallbacks(n,e),this.component.onInstanceCreated))try{this.component.onInstanceCreated(this.container,e,n)}catch{}return n||null}normalizeInstanceIdentifier(e=fo){return this.component?this.component.multipleInstances?e:fo:e}shouldAutoInitialize(){return!!this.component&&this.component.instantiationMode!=="EXPLICIT"}}function y$(t){return t===fo?void 0:t}function x$(t){return t.instantiationMode==="EAGER"}/**
248 * @license
249 * Copyright 2019 Google LLC
250 *
251 * Licensed under the Apache License, Version 2.0 (the "License");
252 * you may not use this file except in compliance with the License.
253 * You may obtain a copy of the License at
254 *
255 *   http://www.apache.org/licenses/LICENSE-2.0
256 *
257 * Unless required by applicable law or agreed to in writing, software
258 * distributed under the License is distributed on an "AS IS" BASIS,
259 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
260 * See the License for the specific language governing permissions and
261 * limitations under the License.
262 */class v${constructor(e){this.name=e,this.providers=new Map}addComponent(e){const a=this.getProvider(e.name);if(a.isComponentSet())throw new Error(`Component ${e.name} has already been registered with ${this.name}`);a.setComponent(e)}addOrOverwriteComponent(e){this.getProvider(e.name).isComponentSet()&&this.providers.delete(e.name),this.addComponent(e)}getProvider(e){if(this.providers.has(e))return this.providers.get(e);const a=new g$(e,this);return this.providers.set(e,a),a}getProviders(){return Array.from(this.providers.values())}}/**
263 * @license
264 * Copyright 2017 Google LLC
265 *
266 * Licensed under the Apache License, Version 2.0 (the "License");
267 * you may not use this file except in compliance with the License.
268 * You may obtain a copy of the License at
269 *
270 *   http://www.apache.org/licenses/LICENSE-2.0
271 *
272 * Unless required by applicable law or agreed to in writing, software
273 * distributed under the License is distributed on an "AS IS" BASIS,
274 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
275 * See the License for the specific language governing permissions and
276 * limitations under the License.
277 */var _e;(function(t){t[t.DEBUG=0]="DEBUG",t[t.VERBOSE=1]="VERBOSE",t[t.INFO=2]="INFO",t[t.WARN=3]="WARN",t[t.ERROR=4]="ERROR",t[t.SILENT=5]="SILENT"})(_e||(_e={}));const b$={debug:_e.DEBUG,verbose:_e.VERBOSE,info:_e.INFO,warn:_e.WARN,error:_e.ERROR,silent:_e.SILENT},w$=_e.INFO,k$={[_e.DEBUG]:"log",[_e.VERBOSE]:"log",[_e.INFO]:"info",[_e.WARN]:"warn",[_e.ERROR]:"error"},S$=(t,e,...a)=>{if(e<t.logLevel)return;const n=new Date().toISOString(),i=k$[e];if(i)console[i](`[${n}]  ${t.name}:`,...a);else throw new Error(`Attempted to log a message with an invalid logType (value: ${e})`)};class pg{constructor(e){this.name=e,this._logLevel=w$,this._logHandler=S$,this._userLogHandler=null}get logLevel(){return this._logLevel}set logLevel(e){if(!(e in _e))throw new TypeError(`Invalid value "${e}" assigned to \`logLevel\``);this._logLevel=e}setLogLevel(e){this._logLevel=typeof e=="string"?b$[e]:e}get logHandler(){return this._logHandler}set logHandler(e){if(typeof e!="function")throw new TypeError("Value assigned to `logHandler` must be a function");this._logHandler=e}get userLogHandler(){return this._userLogHandler}set userLogHandler(e){this._userLogHandler=e}debug(...e){this._userLogHandler&&this._userLogHandler(this,_e.DEBUG,...e),this._logHandler(this,_e.DEBUG,...e)}log(...e){this._userLogHandler&&this._userLogHandler(this,_e.VERBOSE,...e),this._logHandler(this,_e.VERBOSE,...e)}info(...e){this._userLogHandler&&this._userLogHandler(this,_e.INFO,...e),this._logHandler(this,_e.INFO,...e)}warn(...e){this._userLogHandler&&this._userLogHandler(this,_e.WARN,...e),this._logHandler(this,_e.WARN,...e)}error(...e){this._userLogHandler&&this._userLogHandler(this,_e.ERROR,...e),this._logHandler(this,_e.ERROR,...e)}}const _$=(t,e)=>e.some(a=>t instanceof a);let HE,FE;function A$(){return HE||(HE=[IDBDatabase,IDBObjectStore,IDBIndex,IDBCursor,IDBTransaction])}function E$(){return FE||(FE=[IDBCursor.prototype.advance,IDBCursor.prototype.continue,IDBCursor.prototype.continuePrimaryKey])}const HR=new WeakMap,Gv=new WeakMap,FR=new WeakMap,S0=new WeakMap,Vw=new WeakMap;function C$(t){const e=new Promise((a,n)=>{const i=()=>{t.removeEventListener("success",r),t.removeEventListener("error",o)},r=()=>{a(Tr(t.result)),i()},o=()=>{n(t.error),i()};t.addEventListener("success",r),t.addEventListener("error",o)});return e.then(a=>{a instanceof IDBCursor&&HR.set(a,t)}).catch(()=>{}),Vw.set(e,t),e}function j$(t){if(Gv.has(t))return;const e=new Promise((a,n)=>{const i=()=>{t.removeEventListener("complete",r),t.removeEventListener("error",o),t.removeEventListener("abort",o)},r=()=>{a(),i()},o=()=>{n(t.error||new DOMException("AbortError","AbortError")),i()};t.addEventListener("complete",r),t.addEventListener("error",o),t.addEventListener("abort",o)});Gv.set(t,e)}let Kv={get(t,e,a){if(t instanceof IDBTransaction){if(e==="done")return Gv.get(t);if(e==="objectStoreNames")return t.objectStoreNames||FR.get(t);if(e==="store")return a.objectStoreNames[1]?void 0:a.objectStore(a.objectStoreNames[0])}return Tr(t[e])},set(t,e,a){return t[e]=a,!0},has(t,e){return t instanceof IDBTransaction&&(e==="done"||e==="store")?!0:e in t}};function T$(t){Kv=t(Kv)}function N$(t){return t===IDBDatabase.prototype.transaction&&!("objectStoreNames"in IDBTransaction.prototype)?function(e,...a){const n=t.call(_0(this),e,...a);return FR.set(n,e.sort?e.sort():[e]),Tr(n)}:E$().includes(t)?function(...e){return t.apply(_0(this),e),Tr(HR.get(this))}:function(...e){return Tr(t.apply(_0(this),e))}}function I$(t){return typeof t=="function"?N$(t):(t instanceof IDBTransaction&&j$(t),_$(t,A$())?new Proxy(t,Kv):t)}function Tr(t){if(t instanceof IDBRequest)return C$(t);if(S0.has(t))return S0.get(t);const e=I$(t);return e!==t&&(S0.set(t,e),Vw.set(e,t)),e}const _0=t=>Vw.get(t);function BR(t,e,{blocked:a,upgrade:n,blocking:i,terminated:r}={}){const o=indexedDB.open(t,e),l=Tr(o);return n&&o.addEventListener("upgradeneeded",c=>{n(Tr(o.result),c.oldVersion,c.newVersion,Tr(o.transaction),c)}),a&&o.addEventListener("blocked",c=>a(c.oldVersion,c.newVersion,c)),l.then(c=>{r&&c.addEventListener("close",()=>r()),i&&c.addEventListener("versionchange",d=>i(d.oldVersion,d.newVersion,d))}).catch(()=>{}),l}const P$=["get","getKey","getAll","getAllKeys","count"],R$=["put","add","delete","clear"],A0=new Map;function BE(t,e){if(!(t instanceof IDBDatabase&&!(e in t)&&typeof e=="string"))return;if(A0.get(e))return A0.get(e);const a=e.replace(/FromIndex$/,""),n=e!==a,i=R$.includes(a);if(!(a in(n?IDBIndex:IDBObjectStore).prototype)||!(i||P$.includes(a)))return;const r=async function(o,...l){const c=this.transaction(o,i?"readwrite":"readonly");let d=c.store;
277return n&&(d=d.index(l.shift())),(await Promise.all([d[a](...l),i&&c.done]))[0]};return A0.set(e,r),r}T$(t=>({...t,get:(e,a,n)=>BE(e,a)||t.get(e,a,n),has:(e,a)=>!!BE(e,a)||t.has(e,a)}));/**
278 * @license
279 * Copyright 2019 Google LLC
280 *
281 * Licensed under the Apache License, Version 2.0 (the "License");
282 * you may not use this file except in compliance with the License.
283 * You may obtain a copy of the License at
284 *
285 *   http://www.apache.org/licenses/LICENSE-2.0
286 *
287 * Unless required by applicable law or agreed to in writing, software
288 * distributed under the License is distributed on an "AS IS" BASIS,
289 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
290 * See the License for the specific language governing permissions and
291 * limitations under the License.
292 */class L${constructor(e){this.container=e}getPlatformInfoString(){return this.container.getProviders().map(a=>{if(O$(a)){const n=a.getImmediate();return`${n.library}/${n.version}`}else return null}).filter(a=>a).join(" ")}}function O$(t){const e=t.getComponent();return(e==null?void 0:e.type)==="VERSION"}const Jv="@firebase/app",UE="0.10.13";/**
293 * @license
294 * Copyright 2019 Google LLC
295 *
296 * Licensed under the Apache License, Version 2.0 (the "License");
297 * you may not use this file except in compliance with the License.
298 * You may obtain a copy of the License at
299 *
300 *   http://www.apache.org/licenses/LICENSE-2.0
301 *
302 * Unless required by applicable law or agreed to in writing, software
303 * distributed under the License is distributed on an "AS IS" BASIS,
304 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
305 * See the License for the specific language governing permissions and
306 * limitations under the License.
307 */const zi=new pg("@firebase/app"),M$="@firebase/app-compat",D$="@firebase/analytics-compat",q$="@firebase/analytics",z$="@firebase/app-check-compat",V$="@firebase/app-check",H$="@firebase/auth",F$="@firebase/auth-compat",B$="@firebase/database",U$="@firebase/data-connect",$$="@firebase/database-compat",W$="@firebase/functions",G$="@firebase/functions-compat",K$="@firebase/installations",J$="@firebase/installations-compat",Q$="@firebase/messaging",X$="@firebase/messaging-compat",Y$="@firebase/performance",Z$="@firebase/performance-compat",eW="@firebase/remote-config",tW="@firebase/remote-config-compat",aW="@firebase/storage",nW="@firebase/storage-compat",iW="@firebase/firestore",rW="@firebase/vertexai-preview",oW="@firebase/firestore-compat",sW="firebase",lW="10.14.1";/**
308 * @license
309 * Copyright 2019 Google LLC
310 *
311 * Licensed under the Apache License, Version 2.0 (the "License");
312 * you may not use this file except in compliance with the License.
313 * You may obtain a copy of the License at
314 *
315 *   http://www.apache.org/licenses/LICENSE-2.0
316 *
317 * Unless required by applicable law or agreed to in writing, software
318 * distributed under the License is distributed on an "AS IS" BASIS,
319 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
320 * See the License for the specific language governing permissions and
321 * limitations under the License.
322 */const Qv="[DEFAULT]",cW={[Jv]:"fire-core",[M$]:"fire-core-compat",[q$]:"fire-analytics",[D$]:"fire-analytics-compat",[V$]:"fire-app-check",[z$]:"fire-app-check-compat",[H$]:"fire-auth",[F$]:"fire-auth-compat",[B$]:"fire-rtdb",[U$]:"fire-data-connect",[$$]:"fire-rtdb-compat",[W$]:"fire-fn",[G$]:"fire-fn-compat",[K$]:"fire-iid",[J$]:"fire-iid-compat",[Q$]:"fire-fcm",[X$]:"fire-fcm-compat",[Y$]:"fire-perf",[Z$]:"fire-perf-compat",[eW]:"fire-rc",[tW]:"fire-rc-compat",[aW]:"fire-gcs",[nW]:"fire-gcs-compat",[iW]:"fire-fst",[oW]:"fire-fst-compat",[rW]:"fire-vertex","fire-js":"fire-js",[sW]:"fire-js-all"};/**
323 * @license
324 * Copyright 2019 Google LLC
325 *
326 * Licensed under the Apache License, Version 2.0 (the "License");
327 * you may not use this file except in compliance with the License.
328 * You may obtain a copy of the License at
329 *
330 *   http://www.apache.org/licenses/LICENSE-2.0
331 *
332 * Unless required by applicable law or agreed to in writing, software
333 * distributed under the License is distributed on an "AS IS" BASIS,
334 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
335 * See the License for the specific language governing permissions and
336 * limitations under the License.
337 */const Th=new Map,dW=new Map,Xv=new Map;function $E(t,e){try{t.container.addComponent(e)}catch(a){zi.debug(`Component ${e.name} failed to register with FirebaseApp ${t.name}`,a)}}function Dn(t){const e=t.name;if(Xv.has(e))return zi.debug(`There were multiple attempts to register component ${e}.`),!1;Xv.set(e,t);for(const a of Th.values())$E(a,t);for(const a of dW.values())$E(a,t);return!0}function Qr(t,e){const a=t.container.getProvider("heartbeat").getImmediate({optional:!0});return a&&a.triggerHeartbeat(),t.container.getProvider(e)}function wi(t){return t.settings!==void 0}/**
338 * @license
339 * Copyright 2019 Google LLC
340 *
341 * Licensed under the Apache License, Version 2.0 (the "License");
342 * you may not use this file except in compliance with the License.
343 * You may obtain a copy of the License at
344 *
345 *   http://www.apache.org/licenses/LICENSE-2.0
346 *
347 * Unless required by applicable law or agreed to in writing, software
348 * distributed under the License is distributed on an "AS IS" BASIS,
349 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
350 * See the License for the specific language governing permissions and
351 * limitations under the License.
352 */const uW={"no-app":"No Firebase App '{$appName}' has been created - call initializeApp() first","bad-app-name":"Illegal App name: '{$appName}'","duplicate-app":"Firebase App named '{$appName}' already exists with different options or config","app-deleted":"Firebase App named '{$appName}' already deleted","server-app-deleted":"Firebase Server App has been deleted","no-options":"Need to provide options, when not being deployed to hosting via source.","invalid-app-argument":"firebase.{$appName}() takes either no argument or a Firebase App instance.","invali
352d-log-argument":"First argument to `onLog` must be null or a function.","idb-open":"Error thrown when opening IndexedDB. Original error: {$originalErrorMessage}.","idb-get":"Error thrown when reading from IndexedDB. Original error: {$originalErrorMessage}.","idb-set":"Error thrown when writing to IndexedDB. Original error: {$originalErrorMessage}.","idb-delete":"Error thrown when deleting from IndexedDB. Original error: {$originalErrorMessage}.","finalization-registry-not-supported":"FirebaseServerApp deleteOnDeref field defined but the JS runtime does not support FinalizationRegistry.","invalid-server-app-environment":"FirebaseServerApp is not for use in browser environments."},Nr=new ds("app","Firebase",uW);/**
353 * @license
354 * Copyright 2019 Google LLC
355 *
356 * Licensed under the Apache License, Version 2.0 (the "License");
357 * you may not use this file except in compliance with the License.
358 * You may obtain a copy of the License at
359 *
360 *   http://www.apache.org/licenses/LICENSE-2.0
361 *
362 * Unless required by applicable law or agreed to in writing, software
363 * distributed under the License is distributed on an "AS IS" BASIS,
364 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
365 * See the License for the specific language governing permissions and
366 * limitations under the License.
367 */class pW{constructor(e,a,n){this._isDeleted=!1,this._options=Object.assign({},e),this._config=Object.assign({},a),this._name=a.name,this._automaticDataCollectionEnabled=a.automaticDataCollectionEnabled,this._container=n,this.container.addComponent(new hn("app",()=>this,"PUBLIC"))}get automaticDataCollectionEnabled(){return this.checkDestroyed(),this._automaticDataCollectionEnabled}set automaticDataCollectionEnabled(e){this.checkDestroyed(),this._automaticDataCollectionEnabled=e}get name(){return this.checkDestroyed(),this._name}get options(){return this.checkDestroyed(),this._options}get config(){return this.checkDestroyed(),this._config}get container(){return this._container}get isDeleted(){return this._isDeleted}set isDeleted(e){this._isDeleted=e}checkDestroyed(){if(this.isDeleted)throw Nr.create("app-deleted",{appName:this._name})}}/**
368 * @license
369 * Copyright 2019 Google LLC
370 *
371 * Licensed under the Apache License, Version 2.0 (the "License");
372 * you may not use this file except in compliance with the License.
373 * You may obtain a copy of the License at
374 *
375 *   http://www.apache.org/licenses/LICENSE-2.0
376 *
377 * Unless required by applicable law or agreed to in writing, software
378 * distributed under the License is distributed on an "AS IS" BASIS,
379 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
380 * See the License for the specific language governing permissions and
381 * limitations under the License.
382 */const us=lW;function UR(t,e={}){let a=t;typeof e!="object"&&(e={name:e});const n=Object.assign({name:Qv,automaticDataCollectionEnabled:!1},e),i=n.name;if(typeof i!="string"||!i)throw Nr.create("bad-app-name",{appName:String(i)});if(a||(a=DR()),!a)throw Nr.create("no-options");const r=Th.get(i);if(r){if(eu(a,r.options)&&eu(n,r.config))return r;throw Nr.create("duplicate-app",{appName:i})}const o=new v$(i);for(const c of Xv.values())o.addComponent(c);const l=new pW(a,n,o);return Th.set(i,l),l}function mg(t=Qv){const e=Th.get(t);if(!e&&t===Qv&&DR())return UR();if(!e)throw Nr.create("no-app",{appName:t});return e}function Na(t,e,a){var n;let i=(n=cW[t])!==null&&n!==void 0?n:t;a&&(i+=`-${a}`);const r=i.match(/\s|\//),o=e.match(/\s|\//);if(r||o){const l=[`Unable to register library "${i}" with version "${e}":`];r&&l.push(`library name "${i}" contains illegal characters (whitespace or "/")`),r&&o&&l.push("and"),o&&l.push(`version name "${e}" contains illegal characters (whitespace or "/")`),zi.warn(l.join(" "));return}Dn(new hn(`${i}-version`,()=>({library:i,version:e}),"VERSION"))}/**
383 * @license
384 * Copyright 2021 Google LLC
385 *
386 * Licensed under the Apache License, Version 2.0 (the "License");
387 * you may not use this file except in compliance with the License.
388 * You may obtain a copy of the License at
389 *
390 *   http://www.apache.org/licenses/LICENSE-2.0
391 *
392 * Unless required by applicable law or agreed to in writing, softw
392are
393 * distributed under the License is distributed on an "AS IS" BASIS,
394 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
395 * See the License for the specific language governing permissions and
396 * limitations under the License.
397 */const mW="firebase-heartbeat-database",hW=1,tu="firebase-heartbeat-store";let E0=null;function $R(){return E0||(E0=BR(mW,hW,{upgrade:(t,e)=>{switch(e){case 0:try{t.createObjectStore(tu)}catch(a){console.warn(a)}}}}).catch(t=>{throw Nr.create("idb-open",{originalErrorMessage:t.message})})),E0}async function fW(t){try{const a=(await $R()).transaction(tu),n=await a.objectStore(tu).get(WR(t));return await a.done,n}catch(e){if(e instanceof gn)zi.warn(e.message);else{const a=Nr.create("idb-get",{originalErrorMessage:e==null?void 0:e.message});zi.warn(a.message)}}}async function WE(t,e){try{const n=(await $R()).transaction(tu,"readwrite");await n.objectStore(tu).put(e,WR(t)),await n.done}catch(a){if(a instanceof gn)zi.warn(a.message);else{const n=Nr.create("idb-set",{originalErrorMessage:a==null?void 0:a.message});zi.warn(n.message)}}}function WR(t){return`${t.name}!${t.options.appId}`}/**
398 * @license
399 * Copyright 2021 Google LLC
400 *
401 * Licensed under the Apache License, Version 2.0 (the "License");
402 * you may not use this file except in compliance with the License.
403 * You may obtain a copy of the License at
404 *
405 *   http://www.apache.org/licenses/LICENSE-2.0
406 *
407 * Unless required by applicable law or agreed to in writing, software
408 * distributed under the License is distributed on an "AS IS" BASIS,
409 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
410 * See the License for the specific language governing permissions and
411 * limitations under the License.
412 */const gW=1024,yW=30*24*60*60*1e3;class xW{constructor(e){this.container=e,this._heartbeatsCache=null;const a=this.container.getProvider("app").getImmediate();this._storage=new bW(a),this._heartbeatsCachePromise=this._storage.read().then(n=>(this._heartbeatsCache=n,n))}async triggerHeartbeat(){var e,a;try{const i=this.container.getProvider("platform-logger").getImmediate().getPlatformInfoString(),r=GE();return((e=this._heartbeatsCache)===null||e===void 0?void 0:e.heartbeats)==null&&(this._heartbeatsCache=await this._heartbeatsCachePromise,((a=this._heartbeatsCache)===null||a===void 0?void 0:a.heartbeats)==null)||this._heartbeatsCache.lastSentHeartbeatDate===r||this._heartbeatsCache.heartbeats.some(o=>o.date===r)?void 0:(this._heartbeatsCache.heartbeats.push({date:r,agent:i}),this._heartbeatsCache.heartbeats=this._heartbeatsCache.heartbeats.filter(o=>{const l=new Date(o.date).valueOf();return Date.now()-l<=yW}),this._storage.overwrite(this._heartbeatsCache))}catch(n){zi.warn(n)}}async getHeartbeatsHeader(){var e;try{if(this._heartbeatsCache===null&&await this._heartbeatsCachePromise,((e=this._heartbeatsCache)===null||e===void 0?void 0:e.heartbeats)==null||this._heartbeatsCache.heartbeats.length===0)return"";const a=GE(),{heartbeatsToSend:n,unsentEntries:i}=vW(this._heartbeatsCache.heartbeats),r=jh(JSON.stringify({version:2,heartbeats:n}));return this._heartbeatsCache.lastSentHeartbeatDate=a,i.length>0?(this._heartbeatsCache.heartbeats=i,await this._storage.overwrite(this._heartbeatsCache)):(this._heartbeatsCache.heartbeats=[],this._storage.overwrite(this._heartbeatsCache)),r}catch(a){return zi.warn(a),""}}}function GE(){return new Date().toISOString().substring(0,10)}function vW(t,e=gW){const a=[];let n=t.slice();for(const i of t){const r=a.find(o=>o.agent===i.agent);if(r){if(r.dates.push(i.date),KE(a)>e){r.dates.pop();break}}else if(a.push({agent:i.agent,dates:[i.date]}),KE(a)>e){a.pop();break}n=n.slice(1)}return{heartbeatsToSend:a,unsentEntries:n}}class bW{constructor(e){this.app=e,this._canUseIndexedDBPromise=this.runIndexedDBEnvironmentCheck()}async runIndexedDBEnvironmentCheck(){return qw()?zw().then(()=>!0).catch(()=>!1):!1}async read(){if(await this._canUseIndexedDBPromise){const a=await fW(this.app);return a!=null&&a.heartbeats?a:{heartbeats:[]}}else return{heartbeats:[]}}async overwrite(e){var a;if(await this._canUseIndexedDBPromise){const i=await this.read();return WE(this.app,{lastSentHeartbeatDate:(a=e.lastSentHeartbeatDate)!==null&&a!==void 0?a:i.lastSentHeartbeatDate,heartbeats:e.heartbeats})}else return}async add(e){var a;if(await this._canUseIndexedDBPromise){const i=await this.read();return WE(this.app,{lastSentHeartbeatDate:(a=e.lastSentHeartbeatDate)!==null&&a!==void 0?a:i.lastSentHeartbeatDate,heartbeats:[...i.heartbeats,...e.heartbeats]})}else return}}function KE(t){return jh(JSON.stringify({version:2,heartbeats:t})).length}/**
413 * @license
414 * Copyright 2019 Google LLC
415 *
416 * Licensed under the Apache License, Version 2.0 (the "License");
417 * you may not use this file except in compliance with the License.
418 * You may obtain a copy of the License at
419 *
420 *   http://www.apache.org/licenses/LICENSE-2.0
421 *
422 * Unless required by applicable law or agreed to in writing, software
423 * distributed under the License is distributed on an "AS IS" BASIS,
424 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
425 * See the License for the specific language governing permissions and
426 * limitations under the License.
427 */function wW(t){Dn(new hn("platform-logger",e=>new L$(e),"PRIVATE")),Dn(new hn("heartbeat",e=>new xW(e),"PRIVATE")),Na(Jv,UE,t),Na(Jv,UE,"esm2017"),Na("fire-js","")}wW("");var JE=typeof globalThis<"u"?globalThis:typeof window<"u"?window:typeof global<"u"?global:typeof self<"u"?self:{};/** @license
428Copyright The Closure Library Authors.
429SPDX-License-Identifier: Apache-2.0
430*/var Lo,GR;(function(){var t;/** @license
431
432 Copyright The Closure Library Authors.
433 SPDX-License-Identifier: Apache-2.0
434*/function e(C,E){function j(){}j.prototype=E.prototype,C.D=E.prototype,C.prototype=new j,C.prototype.constructor=C,C.C=function(N,L,O){for(var R=Array(arguments.length-2),G=2;G<arguments.length;G++)R[G-2]=arguments[G];return E.prototype[L].apply(N,R)}}function a(){this.blockSize=-1}function n(){this.blockSize=-1,this.blockSize=64,this.g=Array(4),this.B=Array(this.blockSize),this.o=this.h=0,this.s()}e(n,a),n.prototype.s=function(){this.g[0]=1732584193,this.g[1]=4023233417,this.g[2]=2562383102,this.g[3]=271733878,this.o=this.h=0};function i(C,E,j){j||(j=0);var N=Array(16);if(typeof E=="string")for(var L=0;16>L;++L)N[L]=E.charCodeAt(j++)|E.charCodeAt(j++)<<8|E.charCodeAt(j++)<<16|E.charCo
vendor: 51,538 bytes, lines 434-453
434deAt(j++)<<24;else for(L=0;16>L;++L)N[L]=E[j++]|E[j++]<<8|E[j++]<<16|E[j++]<<24;E=C.g[0],j=C.g[1],L=C.g[2];var O=C.g[3],R=E+(O^j&(L^O))+N[0]+3614090360&4294967295;E=j+(R<<7&4294967295|R>>>25),R=O+(L^E&(j^L))+N[1]+3905402710&4294967295,O=E+(R<<12&4294967295|R>>>20),R=L+(j^O&(E^j))+N[2]+606105819&4294967295,L=O+(R<<17&4294967295|R>>>15),R=j+(E^L&(O^E))+N[3]+3250441966&4294967295,j=L+(R<<22&4294967295|R>>>10),R=E+(O^j&(L^O))+N[4]+4118548399&4294967295,E=j+(R<<7&4294967295|R>>>25),R=O+(L^E&(j^L))+N[5]+1200080426&4294967295,O=E+(R<<12&4294967295|R>>>20),R=L+(j^O&(E^j))+N[6]+2821735955&4294967295,L=O+(R<<17&4294967295|R>>>15),R=j+(E^L&(O^E))+N[7]+4249261313&4294967295,j=L+(R<<22&4294967295|R>>>10),R=E+(O^j&(L^O))+N[8]+1770035416&4294967295,E=j+(R<<7&4294967295|R>>>25),R=O+(L^E&(j^L))+N[9]+2336552879&4294967295,O=E+(R<<12&4294967295|R>>>20),R=L+(j^O&(E^j))+N[10]+4294925233&4294967295,L=O+(R<<17&4294967295|R>>>15),R=j+(E^L&(O^E))+N[11]+2304563134&4294967295,j=L+(R<<22&4294967295|R>>>10),R=E+(O^j&(L^O))+N[12]+1804603682&4294967295,E=j+(R<<7&4294967295|R>>>25),R=O+(L^E&(j^L))+N[13]+4254626195&4294967295,O=E+(R<<12&4294967295|R>>>20),R=L+(j^O&(E^j))+N[14]+2792965006&4294967295,L=O+(R<<17&4294967295|R>>>15),R=j+(E^L&(O^E))+N[15]+1236535329&4294967295,j=L+(R<<22&4294967295|R>>>10),R=E+(L^O&(j^L))+N[1]+4129170786&4294967295,E=j+(R<<5&4294967295|R>>>27),R=O+(j^L&(E^j))+N[6]+3225465664&4294967295,O=E+(R<<9&4294967295|R>>>23),R=L+(E^j&(O^E))+N[11]+643717713&4294967295,L=O+(R<<14&4294967295|R>>>18),R=j+(O^E&(L^O))+N[0]+3921069994&4294967295,j=L+(R<<20&4294967295|R>>>12),R=E+(L^O&(j^L))+N[5]+3593408605&4294967295,E=j+(R<<5&4294967295|R>>>27),R=O+(j^L&(E^j))+N[10]+38016083&4294967295,O=E+(R<<9&4294967295|R>>>23),R=L+(E^j&(O^E))+N[15]+3634488961&4294967295,L=O+(R<<14&4294967295|R>>>18),R=j+(O^E&(L^O))+N[4]+3889429448&4294967295,j=L+(R<<20&4294967295|R>>>12),R=E+(L^O&(j^L))+N[9]+568446438&4294967295,E=j+(R<<5&4294967295|R>>>27),R=O+(j^L&(E^j))+N[14]+3275163606&4294967295,O=E+(R<<9&4294967295|R>>>23),R=L+(E^j&(O^E))+N[3]+4107603335&4294967295,L=O+(R<<14&4294967295|R>>>18),R=j+(O^E&(L^O))+N[8]+1163531501&4294967295,j=L+(R<<20&4294967295|R>>>12),R=E+(L^O&(j^L))+N[13]+2850285829&4294967295,E=j+(R<<5&4294967295|R>>>27),R=O+(j^L&(E^j))+N[2]+4243563512&4294967295,O=E+(R<<9&4294967295|R>>>23),R=L+(E^j&(O^E))+N[7]+1735328473&4294967295,L=O+(R<<14&4294967295|R>>>18),R=j+(O^E&(L^O))+N[12]+2368359562&4294967295,j=L+(R<<20&4294967295|R>>>12),R=E+(j^L^O)+N[5]+4294588738&4294967295,E=j+(R<<4&4294967295|R>>>28),R=O+(E^j^L)+N[8]+2272392833&4294967295,O=E+(R<<11&4294967295|R>>>21),R=L+(O^E^j)+N[11]+1839030562&4294967295,L=O+(R<<16&4294967295|R>>>16),R=j+(L^O^E)+N[14]+4259657740&4294967295,j=L+(R<<23&4294967295|R>>>9),R=E+(j^L^O)+N[1]+2763975236&4294967295,E=j+(R<<4&4294967295|R>>>28),R=O+(E^j^L)+N[4]+1272893353&4294967295,O=E+(R<<11&4294967295|R>>>21),R=L+(O^E^j)+N[7]+4139469664&4294967295,L=O+(R<<16&4294967295|R>>>16),R=j+(L^O^E)+N[10]+3200236656&4294967295,j=L+(R<<23&4294967295|R>>>9),R=E+(j^L^O)+N[13]+681279174&4294967295,E=j+(R<<4&4294967295|R>>>28),R=O+(E^j^L)+N[0]+3936430074&4294967295,O=E+(R<<11&4294967295|R>>>21),R=L+(O^E^j)+N[3]+3572445317&4294967295,L=O+(R<<16&4294967295|R>>>16),R=j+(L^O^E)+N[6]+76029189&4294967295,j=L+(R<<23&4294967295|R>>>9),R=E+(j^L^O)+N[9]+3654602809&4294967295,E=j+(R<<4&4294967295|R>>>28),R=O+(E^j^L)+N[12]+3873151461&4294967295,O=E+(R<<11&4294967295|R>>>21),R=L+(O^E^j)+N[15]+530742520&4294967295,L=O+(R<<16&4294967295|R>>>16),R=j+(L^O^E)+N[2]+3299628645&4294967295,j=L+(R<<23&4294967295|R>>>9),R=E+(L^(j|~O))+N[0]+4096336452&4294967295,E=j+(R<<6&4294967295|R>>>26),R=O+(j^(E|~L))+N[7]+1126891415&4294967295,O=E+(R<<10&4294967295|R>>>22),R=L+(E^(O|~j))+N[14]+2878612391&4294967295,L=O+(R<<15&4294967295|R>>>17),R=j+(O^(L|~E))+N[5]+4237533241&4294967295,j=L+(R<<21&4294967295|R>>>11),R=E+(L^(j|~O))+N[12]+1700485571&4294967295,E=j+(R<<6&4294967295|R>>>26),R=O+(j^(E|~L))+N[3]+2399980690&4294967295,O=E+(R<<10&4294967295|R>>>22),R=L+(E^(O|~j))+N[10]+4293915773&4294967295,L=O+(R<<15&4294967295|R>>>17),R=j+(O^(L|~E))+N[1]+2240044497&4294967295,j=L+(R<<21&4294967295|R>>>11),R=E+(L^(j|~O))+N[8]+1873313359&4294967295,E=j+(R<<6&4294967295|R>>>26),R=O+(j^(E|~L))+N[15]+4264355552&4294967295,O=E+(R<<10&4294967295|R>>>22),R=L+(E^(O|~j))+N[6]+2734768916&4294967295,L=O+(R<<15&4294967295|R>>>17),R=j+(O^(L|~E))+N[13]+1309151649&4294967295,j=L+(R<<21&4294967295|R>>>11),R=E+(L^(j|~O))+N[4]+4149444226&4294967295,E=j+(R<<6&4294967295|R>>>26),R=O+(j^(E|~L))+N[11]+3174756917&4294967295,O=E+(R<<10&4294967295|R>>>22),R=L+(E^(O|~j))+N[2]+718787259&4294967295,L=O+(R<<15&4294967295|R>>>17),R=j+(O^(L|~E))+N[9]+3951481745&4294967295,C.g[0]=C.g[0]+E&4294967295,C.g[1]=C.g[1]+(L+(R<<21&4294967295|R>>>11))&4294967295,C.g[2]=C.g[2]+L&4294967295,C.g[3]=C.g[3]+O&4294967295}n.prototype.u=function(C,E){E===void 0&&(E=C.length);for(var j=E-this.blockSize,N=this.B,L=this.h,O=0;O<E;){if(L==0)for(;O<=j;)i(this,C,O),O+=this.blockSize;if(typeof C=="string"){for(;O<E;)if(N[L++]=C.charCodeAt(O++),L==this.blockSize){i(this,N),L=0;break}}else for(;O<E;)if(N[L++]=C[O++],L==this.blockSize){i(this,N),L=0;break}}this.h=L,this.o+=E},n.prototype.v=function(){var C=Array((56>this.h?this.blockSize:2*this.blockSize)-this.h);C[0]=128;for(var E=1;E<C.length-8;++E)C[E]=0;var j=8*this.o;for(E=C.length-8;E<C.length;++E)C[E]=j&255,j/=256;for(this.u(C),C=Array(16),E=j=0;4>E;++E)for(var N=0;32>N;N+=8)C[j++]=this.g[E]>>>N&255;return C};function r(C,E){var j=l;return Object.prototype.hasOwnProperty.call(j,C)?j[C]:j[C]=E(C)}function o(C,E){this.h=E;for(var j=[],N=!0,L=C.length-1;0<=L;L--){var O=C[L]|0;N&&O==E||(j[L]=O,N=!1)}this.g=j}var l={};function c(C){return-128<=C&&128>C?r(C,function(E){return new o([E|0],0>E?-1:0)}):new o([C|0],0>C?-1:0)}function d(C){if(isNaN(C)||!isFinite(C))return p;if(0>C)return x(d(-C));for(var E=[],j=1,N=0;C>=j;N++)E[N]=C/j|0,j*=4294967296;return new o(E,0)}function u(C,E){if(C.length==0)throw Error("number format error: empty string");if(E=E||10,2>E||36<E)throw Error("radix out of range: "+E);if(C.charAt(0)=="-")return x(u(C.substring(1),E));if(0<=C.indexOf("-"))throw Error('number format error: interior "-" character');for(var j=d(Math.pow(E,8)),N=p,L=0;L<C.length;L+=8){var O=Math.min(8,C.length-L),R=parseInt(C.substring(L,L+O),E);8>O?(O=d(Math.pow(E,O)),N=N.j(O).add(d(R))):(N=N.j(j),N=N.add(d(R)))}return N}var p=c(0),m=c(1),h=c(16777216);t=o.prototype,t.m=function(){if(y(this))return-x(this).m();for(var C=0,E=1,j=0;j<this.g.length;j++){var N=this.i(j);C+=(0<=N?N:4294967296+N)*E,E*=4294967296}return C},t.toString=function(C){if(C=C||10,2>C||36<C)throw Error("radix out of range: "+C);if(g(this))return"0";if(y(this))return"-"+x(this).toString(C);for(var E=d(Math.pow(C,6)),j=this,N="";;){var L=T(j,E).g;j=v(j,L.j(E));var O=((0<j.g.length?j.g[0]:j.h)>>>0).toString(C);if(j=L,g(j))return O+N;for(;6>O.length;)O="0"+O;N=O+N}},t.i=function(C){return 0>C?0:C<this.g.length?this.g[C]:this.h};function g(C){if(C.h!=0)return!1;for(var E=0;E<C.g.length;E++)if(C.g[E]!=0)return!1;return!0}function y(C){return C.h==-1}t.l=function(C){return C=v(this,C),y(C)?-1:g(C)?0:1};function x(C){for(var E=C.g.length,j=[],N=0;N<E;N++)j[N]=~C.g[N];return new o(j,~C.h).add(m)}t.abs=function(){return y(this)?x(this):this},t.add=function(C){for(var E=Math.max(this.g.length,C.g.length),j=[],N=0,L=0;L<=E;L++){var O=N+(this.i(L)&65535)+(C.i(L)&65535),R=(O>>>16)+(this.i(L)>>>16)+(C.i(L)>>>16);N=R>>>16,O&=65535,R&=65535,j[L]=R<<16|O}return new o(j,j[j.length-1]&-2147483648?-1:0)};function v(C,E){return C.add(x(E))}t.j=function(C){if(g(this)||g(C))return p;if(y(this))return y(C)?x(this).j(x(C)):x(x(this).j(C));if(y(C))return x(this.j(x(C)));if(0>this.l(h)&&0>C.l(h))return d(this.m()*C.m());for(var E=this.g.length+C.g.length,j=[],N=0;N<2*E;N++)j[N]=0;for(N=0;N<this.g.length;N++)for(var L=0;L<C.g.length;L++){var O=this.i(N)>>>16,R=this.i(N)&65535,G=C.i(L)>>>16,ee=C.i(L)&65535;j[2*N+2*L]+=R*ee,w(j,2*N+2*L),j[2*N+2*L+1]+=O*ee,w(j,2*N+2*L+1),j[2*N+2*L+1]+=R*G,w(j,2*N+2*L+1),j[2*N+2*L+2]+=O*G,w(j,2*N+2*L+2)}for(N=0;N<E;N++)j[N]=j[2*N+1]<<16|j[2*N];for(N=E;N<2*E;N++)j[N]=0;return new o(j,0)};function w(C,E){for(;(C[E]&65535)!=C[E];)C[E+1]+=C[E]>>>16,C[E]&=65535,E++}function S(C,E){this.g=C,this.h=E}function T(C,E){if(g(E))throw Error("division by zero");if(g(C))return new S(p,p);if(y(C))return E=T(x(C),E),new S(x(E.g),x(E.h));if(y(E))return E=T(C,x(E)),new S(x(E.g),E.h);if(30<C.g.length){if(y(C)||y(E))throw Error("slowDivide_ only works with positive integers.");for(var j=m,N=E;0>=N.l(C);)j=P(j),N=P(N);var L=M(j,1),O=M(N,1);for(N=M(N,2),j=M(j,2);!g(N);){var R=O.add(N);0>=R.l(C)&&(L=L.add(j),O=R),N=M(N,1),j=M(j,1)}return E=v(C,L.j(E)),new S(L,E)}for(L=p;0<=C.l(E);){for(j=Math.max(1,Math.floor(C.m()/E.m())),N=Math.ceil(Math.log(j)/Math.LN2),N=48>=N?1:Math.pow(2,N-48),O=d(j),R=O.j(E);y(R)||0<R.l(C);)j-=N,O=d(j),R=O.j(E);g(O)&&(O=m),L=L.add(O),C=v(C,R)}return new S(L,C)}t.A=function(C){return T(this,C).h},t.and=function(C){for(var E=Math.max(this.g.length,C.g.length),j=[],N=0;N<E;N++)j[N]=this.i(N)&C.i(N);return new o(j,this.h&C.h)},t.or=function(C){for(var E=Math.max(this.g.length,C.g.length),j=[],N=0;N<E;N++)j[N]=this.i(N)|C.i(N);return new o(j,this.h|C.h)},t.xor=function(C){for(var E=Math.max(this.g.length,C.g.length),j=[],N=0;N<E;N++)j[N]=this.i(N)^C.i(N);return new o(j,this.h^C.h)};function P(C){for(var E=C.g.length+1,j=[],N=0;N<E;N++)j[N]=C.i(N)<<1|C.i(N-1)>>>31;return new o(j,C.h)}function M(C,E){var j=E>>5;E%=32;for(var N=C.g.length-j,L=[],O=0;O<N;O++)L[O]=0<E?C.i(O+j)>>>E|C.i(O+j+1)<<32-E:C.i(O+j);return new o(L,C.h)}n.prototype.digest=n.prototype.v,n.prototype.reset=n.prototype.s,n.prototype.update=n.prototype.u,GR=n,o.prototype.add=o.prototype.add,o.prototype.multiply=o.prototype.j,o.prototype.modulo=o.prototype.A,o.prototype.compare=o.prototype.l,o.prototype.toNumber=o.prototype.m,o.prototype.toString=o.prototype.toString,o.prototype.getBits=o.prototype.i,o.fromNumber=d,o.fromString=u,Lo=o}).apply(typeof JE<"u"?JE:typeof self<"u"?self:typeof window<"u"?window:{});var Vp=typeof globalThis<"u"?globalThis:typeof window<"u"?window:typeof global<"u"?global:typeof self<"u"?self:{};/** @license
435Copyright The Closure Library Authors.
436SPDX-License-Identifier: Apache-2.0
437*/var KR,Vc,JR,Rm,Yv,QR,XR,YR;(function(){var t,e=typeof Object.defineProperties=="function"?Object.defineProperty:function(f,b,A){return f==Array.prototype||f==Object.prototype||(f[b]=A.value),f};function a(f){f=[typeof globalThis=="object"&&globalThis,f,typeof window=="object"&&window,typeof self=="object"&&self,typeof Vp=="object"&&Vp];for(var b=0;b<f.length;++b){var A=f[b];if(A&&A.Math==Math)return A}throw Error("Cannot find global object")}var n=a(this);function i(f,b){if(b)e:{var A=n;f=f.split(".");for(var I=0;I<f.length-1;I++){var D=f[I];if(!(D in A))break e;A=A[D]}f=f[f.length-1],I=A[f],b=b(I),b!=I&&b!=null&&e(A,f,{configurable:!0,writable:!0,value:b})}}function r(f,b){f instanceof String&&(f+="");var A=0,I=!1,D={next:function(){if(!I&&A<f.length){var q=A++;return{value:b(q,f[q]),done:!1}}return I=!0,{done:!0,value:void 0}}};return D[Symbol.iterator]=function(){return D},D}i("Array.prototype.values",function(f){return f||function(){return r(this,function(b,A){return A})}});/** @license
438
439 Copyright The Closure Library Authors.
440 SPDX-License-Identifier: Apache-2.0
441*/var o=o||{},l=this||self;function c(f){var b=typeof f;return b=b!="object"?b:f?Array.isArray(f)?"array":b:"null",b=="array"||b=="object"&&typeof f.length=="number"}function d(f){var b=typeof f;return b=="object"&&f!=null||b=="function"}function u(f,b,A){return f.call.apply(f.bind,arguments)}function p(f,b,A){if(!f)throw Error();if(2<arguments.length){var I=Array.prototype.slice.call(arguments,2);return function(){var D=Array.prototype.slice.call(arguments);return Array.prototype.unshift.apply(D,I),f.apply(b,D)}}return function(){return f.apply(b,arguments)}}function m(f,b,A){return m=Function.prototype.bind&&Function.prototype.bind.toString().indexOf("native code")!=-1?u:p,m.apply(null,arguments)}function h(f,b){var A=Array.prototype.slice.call(arguments,1);return function(){var I=A.slice();return I.push.apply(I,arguments),f.apply(this,I)}}function g(f,b){function A(){}A.prototype=b.prototype,f.aa=b.prototype,f.prototype=new A,f.prototype.constructor=f,f.Qb=function(I,D,q){for(var W=Array(arguments.length-2),De=2;De<arguments.length;De++)W[De-2]=arguments[De];return b.prototype[D].apply(I,W)}}function y(f){const b=f.length;if(0<b){const A=Array(b);for(let I=0;I<b;I++)A[I]=f[I];return A}return[]}function x(f,b){for(let A=1;A<arguments.length;A++){const I=arguments[A];if(c(I)){const D=f.length||0,q=I.length||0;f.length=D+q;for(let W=0;W<q;W++)f[D+W]=I[W]}else f.push(I)}}class v{constructor(b,A){this.i=b,this.j=A,this.h=0,this.g=null}get(){let b;return 0<this.h?(this.h--,b=this.g,this.g=b.next,b.next=null):b=this.i(),b}}function w(f){return/^[\s\xa0]*$/.test(f)}function S(){var f=l.navigator;return f&&(f=f.userAgent)?f:""}function T(f){return T[" "](f),f}T[" "]=function(){};var P=S().indexOf("Gecko")!=-1&&!(S().toLowerCase().indexOf("webkit")!=-1&&S().indexOf("Edge")==-1)&&!(S().indexOf("Trident")!=-1||S().indexOf("MSIE")!=-1)&&S().indexOf("Edge")==-1;function M(f,b,A){for(const I in f)b.call(A,f[I],I,f)}function C(f,b){for(const A in f)b.call(void 0,f[A],A,f)}function E(f){const b={};for(const A in f)b[A]=f[A];return b}const j="constructor hasOwnProperty isPrototypeOf propertyIsEnumerable toLocaleString toString valueOf".split(" ");function N(f,b){let A,I;for(let D=1;D<arguments.length;D++){I=arguments[D];for(A in I)f[A]=I[A];for(let q=0;q<j.length;q++)A=j[q],Object.prototype.hasOwnProperty.call(I,A)&&(f[A]=I[A])}}function L(f){var b=1;f=f.split(":");const A=[];for(;0<b&&f.length;)A.push(f.shift()),b--;return f.length&&A.push(f.join(":")),A}function O(f){l.setTimeout(()=>{throw f},0)}function R(){var f=Z;let b=null;return f.g&&(b=f.g,f.g=f.g.next,f.g||(f.h=null),b.next=null),b}class G{constructor(){this.h=this.g=null}add(b,A){const I=ee.get();I.set(b,A),this.h?this.h.next=I:this.g=I,this.h=I}}var ee=new v(()=>new ke,f=>f.reset());class ke{constructor(){this.next=this.g=this.h=null}set(b,A){this.h=b,this.g=A,this.next=null}reset(){this.next=this.g=this.h=null}}let ae,F=!1,Z=new G,re=()=>{const f=l.Promise.resolve(void 0);ae=()=>{f.then(fe)}};var fe=()=>{for(var f;f=R();){try{f.h.call(f.g)}catch(A){O(A)}var b=ee;b.j(f),100>b.h&&(b.h++,f.next=b.g,b.g=f)}F=!1};function ve(){this.s=this.s,this.C=this.C}ve.prototype.s=!1,ve.prototype.ma=function(){this.s||(this.s=!0,this.N())},ve.prototype.N=function(){if(this.C)for(;this.C.length;)this.C.shift()()};function Ie(f,b){this.type=f,this.g=this.target=b,this.defaultPrevented=!1}Ie.prototype.h=function(){this.defaultPrevented=!0};var ne=function(){if(!l.addEventListener||!Object.defineProperty)return!1;var f=!1,b=Object.defineProperty({},"passive",{get:function(){f=!0}});try{const A=()=>{};l.addEventListener("test",A,b),l.removeEventListener("test",A,b)}catch{}return f}();function ge(f,b){if(Ie.call(this,f?f.type:""),this.relatedTarget=this.g=this.target=null,this.button=this.screenY=this.screenX=this.clientY=this.clientX=0,this.key="",this.metaKey=this.shiftKey=this.altKey=this.ctrlKey=!1,this.state=null,this.pointerId=0,this.pointerType="",this.i=null,f){var A=this.type=f.type,I=f.changedTouches&&f.changedTouches.length?f.changedTouches[0]:null;if(this.target=f.target||f.srcElement,this.g=b,b=f.relatedTarget){if(P){e:{try{T(b.nodeName);var D=!0;break e}catch{}D=!1}D||(b=null)}}else A=="mouseover"?b=f.fromElement:A=="mouseout"&&(b=f.toElement);this.relatedTarget=b,I?(this.clientX=I.clientX!==void 0?I.clientX:I.pageX,this.clientY=I.clientY!==void 0?I.clientY:I.pageY,this.screenX=I.screenX||0,this.screenY=I.screenY||0):(this.clientX=f.clientX!==void 0?f.clientX:f.pageX,this.clientY=f.clientY!==void 0?f.clientY:f.pageY,this.screenX=f.screenX||0,this.screenY=f.screenY||0),this.button=f.button,this.key=f.key||"",this.ctrlKey=f.ctrlKey,this.altKey=f.altKey,this.shiftKey=f.shiftKey,this.metaKey=f.metaKey,this.pointerId=f.pointerId||0,this.pointerType=typeof f.pointerType=="string"?f.pointerType:Me[f.pointerType]||"",this.state=f.state,this.i=f,f.defaultPrevented&&ge.aa.h.call(this)}}g(ge,Ie);var Me={2:"touch",3:"pen",4:"mouse"};ge.prototype.h=function(){ge.aa.h.call(this);var f=this.i;f.preventDefault?f.preventDefault():f.returnValue=!1};var We="closure_listenable_"+(1e6*Math.random()|0),si=0;function Vn(f,b,A,I,D){this.listener=f,this.proxy=null,this.src=b,this.type=A,this.capture=!!I,this.ha=D,this.key=++si,this.da=this.fa=!1}function Xu(f){f.da=!0,f.listener=null,f.proxy=null,f.src=null,f.ha=null}function Yu(f){this.src=f,this.g={},this.h=0}Yu.prototype.add=function(f,b,A,I,D){var q=f.toString();f=this.g[q],f||(f=this.g[q]=[],this.h++);var W=ey(f,b,I,D);return-1<W?(b=f[W],A||(b.fa=!1)):(b=new Vn(b,this.src,q,!!I,D),b.fa=A,f.push(b)),b};function Zg(f,b){var A=b.type;if(A in f.g){var I=f.g[A],D=Array.prototype.indexOf.call(I,b,void 0),q;(q=0<=D)&&Array.prototype.splice.call(I,D,1),q&&(Xu(b),f.g[A].length==0&&(delete f.g[A],f.h--))}}function ey(f,b,A,I){for(var D=0;D<f.length;++D){var q=f[D];if(!q.da&&q.listener==b&&q.capture==!!A&&q.ha==I)return D}return-1}var ty="closure_lm_"+(1e6*Math.random()|0),ay={};function LS(f,b,A,I,D){if(Array.isArray(b)){for(var q=0;q<b.length;q++)LS(f,b[q],A,I,D);return null}return A=DS(A),f&&f[We]?f.K(b,A,d(I)?!!I.capture:!1,D):TD(f,b,A,!1,I,D)}function TD(f,b,A,I,D,q){if(!b)throw Error("Invalid event type");var W=d(D)?!!D.capture:!!D,De=iy(f);if(De||(f[ty]=De=new Yu(f)),A=De.add(b,A,I,W,q),A.proxy)return A;if(I=ND(),A.proxy=I,I.src=f,I.listener=A,f.addEventListener)ne||(D=W),D===void 0&&(D=!1),f.addEventListener(b.toString(),I,D);else if(f.attachEvent)f.attachEvent(MS(b.toString()),I);else if(f.addListener&&f.removeListener)f.addListener(I);else throw Error("addEventListener and attachEvent are unavailable.");return A}function ND(){function f(A){return b.call(f.src,f.listener,A)}const b=ID;return f}function OS(f,b,A,I,D){if(Array.isArray(b))for(var q=0;q<b.length;q++)OS(f,b[q],A,I,D);else I=d(I)?!!I.capture:!!I,A=DS(A),f&&f[We]?(f=f.i,b=String(b).toString(),b in f.g&&(q=f.g[b],A=ey(q,A,I,D),-1<A&&(Xu(q[A]),Array.prototype.splice.call(q,A,1),q.length==0&&(delete f.g[b],f.h--)))):f&&(f=iy(f))&&(b=f.g[b.toString()],f=-1,b&&(f=ey(b,A,I,D)),(A=-1<f?b[f]:null)&&ny(A))}function ny(f){if(typeof f!="number"&&f&&!f.da){var b=f.src;if(b&&b[We])Zg(b.i,f);else{var A=f.type,I=f.proxy;b.removeEventListener?b.removeEventListener(A,I,f.capture):b.detachEvent?b.detachEvent(MS(A),I):b.addListener&&b.removeListener&&b.removeListener(I),(A=iy(b))?(Zg(A,f),A.h==0&&(A.src=null,b[ty]=null)):Xu(f)}}}function MS(f){return f in ay?ay[f]:ay[f]="on"+f}function ID(f,b){if(f.da)f=!0;else{b=new ge(b,this);var A=f.listener,I=f.ha||f.src;f.fa&&ny(f),f=A.call(I,b)}return f}function iy(f){return f=f[ty],f instanceof Yu?f:null}var ry="__closure_events_fn_"+(1e9*Math.random()>>>0);function DS(f){return typeof f=="function"?f:(f[ry]||(f[ry]=function(b){return f.handleEvent(b)}),f[ry])}function Gt(){ve.call(this),this.i=new Yu(this),this.M=this,this.F=null}g(Gt,ve),Gt.prototype[We]=!0,Gt.prototype.removeEventListener=function(f,b,A,I){OS(this,f,b,A,I)};function la(f,b){var A,I=f.F;if(I)for(A=[];I;I=I.F)A.push(I);if(f=f.M,I=b.type||b,typeof b=="string")b=new Ie(b,f);else if(b instanceof Ie)b.target=b.target||f;else{var D=b;b=new Ie(I,f),N(b,D)}if(D=!0,A)for(var q=A.length-1;0<=q;q--){var W=b.g=A[q];D=Zu(W,I,!0,b)&&D}if(W=b.g=f,D=Zu(W,I,!0,b)&&D,D=Zu(W,I,!1,b)&&D,A)for(q=0;q<A.length;q++)W=b.g=A[q],D=Zu(W,I,!1,b)&&D}Gt.prototype.N=function(){if(Gt.aa.N.call(this),this.i){var f=this.i,b;for(b in f.g){for(var A=f.g[b],I=0;I<A.length;I++)Xu(A[I]);delete f.g[b],f.h--}}this.F=null},Gt.prototype.K=function(f,b,A,I){return this.i.add(String(f),b,!1,A,I)},Gt.prototype.L=function(f,b,A,I){return this.i.add(String(f),b,!0,A,I)};function Zu(f,b,A,I){if(b=f.i.g[String(b)],!b)return!0;b=b.concat();for(var D=!0,q=0;q<b.length;++q){var W=b[q];if(W&&!W.da&&W.capture==A){var De=W.listener,Lt=W.ha||W.src;W.fa&&Zg(f.i,W),D=De.call(Lt,I)!==!1&&D}}return D&&!I.defaultPrevented}function qS(f,b,A){if(typeof f=="function")A&&(f=m(f,A));else if(f&&typeof f.handleEvent=="function")f=m(f.handleEvent,f);else throw Error("Invalid listener argument");return 2147483647<Number(b)?-1:l.setTimeout(f,b||0)}function zS(f){f.g=qS(()=>{f.g=null,f.i&&(f.i=!1,zS(f))},f.l);const b=f.h;f.h=null,f.m.apply(null,b)}class PD extends ve{constructor(b,A){super(),this.m=b,this.l=A,this.h=null,this.i=!1,this.g=null}j(b){this.h=arguments,this.g?this.i=!0:zS(this)}N(){super.N(),this.g&&(l.clearTimeout(this.g),this.g=null,this.i=!1,this.h=null)}}function tc(f){ve.call(this),this.h=f,this.g={}}g(tc,ve);var VS=[];function HS(f){M(f.g,function(b,A){this.g.hasOwnProperty(A)&&ny(b)},f),f.g={}}tc.prototype.N=function(){tc.aa.N.call(this),HS(this)},tc.prototype.handleEvent=function(){throw Error("EventHandler.handleEvent not implemented")};var oy=l.JSON.stringify,RD=l.JSON.parse,LD=class{stringify(f){return l.JSON.stringify(f,void 0)}parse(f){return l.JSON.parse(f,void 0)}};function sy(){}sy.prototype.h=null;function FS(f){return f.h||(f.h=f.i())}function BS(){}var ac={OPEN:"a",kb:"b",Ja:"c",wb:"d"};function ly(){Ie.call(this,"d")}g(ly,Ie);function cy(){Ie.call(this,"c")}g(cy,Ie);var io={},US=null;function ep(){return US=US||new Gt}io.La="serverreachability";function $S(f){Ie.call(this,io.La,f)}g($S,Ie);function nc(f){const b=ep();la(b,new $S(b))}io.STAT_EVENT="statevent";function WS(f,b){Ie.call(this,io.STAT_EVENT,f),this.stat=b}g(WS,Ie);function ca(f){const b=ep();la(b,new WS(b,f))}io.Ma="timingevent";function GS(f,b){Ie.call(this,io.Ma,f),this.size=b}g(GS,Ie);function ic(f,b){if(typeof f!="function")throw Error("Fn must not be null and must be a function");return l.setTimeout(function(){f()},b)}function rc(){this.g=!0}rc.prototype.xa=function(){this.g=!1};function OD(f,b,A,I,D,q){f.info(function(){if(f.g)if(q)for(var W="",De=q.split("&"),Lt=0;Lt<De.length;Lt++){var Ce=De[Lt].split("=");if(1<Ce.length){var Kt=Ce[0];Ce=Ce[1];var Jt=Kt.split("_");W=2<=Jt.length&&Jt[1]=="type"?W+(Kt+"="+Ce+"&"):W+(Kt+"=redacted&")}}else W=null;else W=q;return"XMLHTTP REQ ("+I+") [attempt "+D+"]: "+b+`
442`+A+`
443`+W})}function MD(f,b,A,I,D,q,W){f.info(function(){return"XMLHTTP RESP ("+I+") [ attempt "+D+"]: "+b+`
444`+A+`
445`+q+" "+W})}function ys(f,b,A,I){f.info(function(){return"XMLHTTP TEXT ("+b+"): "+qD(f,A)+(I?" "+I:"")})}function DD(f,b){f.info(function(){return"TIMEOUT: "+b})}rc.prototype.info=function(){};function qD(f,b){if(!f.g)return b;if(!b)return null;try{var A=JSON.parse(b);if(A){for(f=0;f<A.length;f++)if(Array.isArray(A[f])){var I=A[f];if(!(2>I.length)){var D=I[1];if(Array.isArray(D)&&!(1>D.length)){var q=D[0];if(q!="noop"&&q!="stop"&&q!="close")for(var W=1;W<D.length;W++)D[W]=""}}}}return oy(A)}catch{return b}}var tp={NO_ERROR:0,gb:1,tb:2,sb:3,nb:4,rb:5,ub:6,Ia:7,TIMEOUT:8,xb:9},KS={lb:"complete",Hb:"success",Ja:"error",Ia:"abort",zb:"ready",Ab:"readystatechange",TIMEOUT:"timeout",vb:"incrementaldata",yb:"progress",ob:"downloadprogress",Pb:"uploadprogress"},dy;function ap(){}g(ap,sy),ap.prototype.g=function(){return new XMLHttpRequest},ap.prototype.i=function(){return{}},dy=new ap;function Wi(f,b,A,I){this.j=f,this.i=b,this.l=A,this.R=I||1,this.U=new tc(this),this.I=45e3,this.H=null,this.o=!1,this.m=this.A=this.v=this.L=this.F=this.S=this.B=null,this.D=[],this.g=null,this.C=0,this.s=this.u=null,this.X=-1,this.J=!1,this.O=0,this.M=null,this.W=this.K=this.T=this.P=!1,this.h=new JS}function JS(){this.i=null,this.g="",this.h=!1}var QS={},uy={};function py(f,b,A){f.L=1,f.v=op(li(b)),f.m=A,f.P=!0,XS(f,null)}function XS(f,b){f.F=Date.now(),np(f),f.A=li(f.v);var A=f.A,I=f.R;Array.isArray(I)||(I=[String(I)]),u2(A.i,"t",I),f.C=0,A=f.j.J,f.h=new JS,f.g=T2(f.j,A?b:null,!f.m),0<f.O&&(f.M=new PD(m(f.Y,f,f.g),f.O)),b=f.U,A=f.g,I=f.ca;var D="readystatechange";Array.isArray(D)||(D&&(VS[0]=D.toString()),D=VS);for(var q=0;q<D.length;q++){var W=LS(A,D[q],I||b.handleEvent,!1,b.h||b);if(!W)break;b.g[W.key]=W}b=f.H?E(f.H):{},f.m?(f.u||(f.u="POST"),b["Content-Type"]="application/x-www-form-urlencoded",f.g.ea(f.A,f.u,f.m,b)):(f.u="GET",f.g.ea(f.A,f.u,null,b)),nc(),OD(f.i,f.u,f.A,f.l,f.R,f.m)}Wi.prototype.ca=function(f){f=f.target;const b=this.M;b&&ci(f)==3?b.j():this.Y(f)},Wi.prototype.Y=function(f){try{if(f==this.g)e:{const Jt=ci(this.g);var b=this.g.Ba();const bs=this.g.Z();if(!(3>Jt)&&(Jt!=3||this.g&&(this.h.h||this.g.oa()||x2(this.g)))){this.J||Jt!=4||b==7||(b==8||0>=bs?nc(3):nc(2)),my(this);var A=this.g.Z();this.X=A;t:if(YS(this)){var I=x2(this.g);f="";var D=I.length,q=ci(this.g)==4;if(!this.h.i){if(typeof TextDecoder>"u"){ro(this),oc(this);var W="";break t}this.h.i=new l.TextDecoder}for(b=0;b<D;b++)this.h.h=!0,f+=this.h.i.decode(I[b],{stream:!(q&&b==D-1)});I.length=0,this.h.g+=f,this.C=0,W=this.h.g}else W=this.g.oa();if(this.o=A==200,MD(this.i,this.u,this.A,this.l,this.R,Jt,A),this.o){if(this.T&&!this.K){t:{if(this.g){var De,Lt=this.g;if((De=Lt.g?Lt.g.getResponseHeader("X-HTTP-Initial-Response"):null)&&!w(De)){var Ce=De;break t}}Ce=null}if(A=Ce)ys(this.i,this.l,A,"Initial handshake response via X-HTTP-Initial-Response"),this.K=!0,hy(this,A);else{this.o=!1,this.s=3,ca(12),ro(this),oc(this);break e}}if(this.P){A=!0;let yn;for(;!this.J&&this.C<W.length;)if(yn=zD(this,W),yn==uy){Jt==4&&(this.s=4,ca(14),A=!1),ys(this.i,this.l,null,"[Incomplete Response]");break}else if(yn==QS){this.s=4,ca(15),ys(this.i,this.l,W,"[Invalid Chunk]"),A=!1;break}else ys(this.i,this.l,yn,null),hy(this,yn);if(YS(this)&&this.C!=0&&(this.h.g=this.h.g.slice(this.C),this.C=0),Jt!=4||W.length!=0||this.h.h||(this.s=1,ca(16),A=!1),this.o=this.o&&A,!A)ys(this.i,this.l,W,"[Invalid Chunked Response]"),ro(this),oc(this);else if(0<W.length&&!this.W){this.W=!0;var Kt=this.j;Kt.g==this&&Kt.ba&&!Kt.M&&(Kt.j.info("Great, no buffering proxy detected. Bytes received: "+W.length),by(Kt),Kt.M=!0,ca(11))}}else ys(this.i,this.l,W,null),hy(this,W);Jt==4&&ro(this),this.o&&!this.J&&(Jt==4?A2(this.j,this):(this.o=!1,np(this)))}else aq(this.g),A==400&&0<W.indexOf("Unknown SID")?(this.s=3,ca(12)):(this.s=0,ca(13)),ro(this),oc(this)}}}catch{}finally{}};function YS(f){return f.g?f.u=="GET"&&f.L!=2&&f.j.Ca:!1}function zD(f,b){var A=f.C,I=b.indexOf(`
446`,A);return I==-1?uy:(A=Number(b.substring(A,I)),isNaN(A)?QS:(I+=1,I+A>b.length?uy:(b=b.slice(I,I+A),f.C=I+A,b)))}Wi.prototype.cancel=function(){this.J=!0,ro(this)};function np(f){f.S=Date.now()+f.I,ZS(f,f.I)}function ZS(f,b){if(f.B!=null)throw Error("WatchDog timer not null");f.B=ic(m(f.ba,f),b)}function my(f){f.B&&(l.clearTimeout(f.B),f.B=null)}Wi.prototype.ba=function(){this.B=null;const f=Date.now();0<=f-this.S?(DD(this.i,this.A),this.L!=2&&(nc(),ca(17)),ro(this),this.s=2,oc(this)):ZS(this,this.S-f)};function oc(f){f.j.G==0||f.J||A2(f.j,f)}function ro(f){my(f);var b=f.M;b&&typeof b.ma=="function"&&b.ma(),f.M=null,HS(f.U),f.g&&(b=f.g,f.g=null,b.abort(),b.ma())}function hy(f,b){try{var A=f.j;if(A.G!=0&&(A.g==f||fy(A.h,f))){if(!f.K&&fy(A.h,f)&&A.G==3){try{var I=A.Da.g.parse(b)}catch{I=null}if(Array.isArray(I)&&I.length==3){var D=I;if(D[0]==0){e:if(!A.u){if(A.g)if(A.g.F+3e3<f.F)pp(A),dp(A);else break e;vy(A),ca(18)}}else A.za=D[1],0<A.za-A.T&&37500>D[2]&&A.F&&A.v==0&&!A.C&&(A.C=ic(m(A.Za,A),6e3));if(1>=a2(A.h)&&A.ca){try{A.ca()}catch{}A.ca=void 0}}else so(A,11)}else if((f.K||A.g==f)&&pp(A),!w(b))for(D=A.Da.g.parse(b),b=0;b<D.length;b++){let Ce=D[b];if(A.T=Ce[0],Ce=Ce[1],A.G==2)if(Ce[0]=="c"){A.K=Ce[1],A.ia=Ce[2];const Kt=Ce[3];Kt!=null&&(A.la=Kt,A.j.info("VER="+A.la));const Jt=Ce[4];Jt!=null&&(A.Aa=Jt,A.j.info("SVER="+A.Aa));const bs=Ce[5];bs!=null&&typeof bs=="number"&&0<bs&&(I=1.5*bs,A.L=I,A.j.info("backChannelRequestTimeoutMs_="+I)),I=A;const yn=f.g;if(yn){const hp=yn.g?yn.g.getResponseHeader("X-Client-Wire-Protocol"):null;if(hp){var q=I.h;q.g||hp.indexOf("spdy")==-1&&hp.indexOf("quic")==-1&&hp.indexOf("h2")==-1||(q.j=q.l,q.g=new Set,q.h&&(gy(q,q.h),q.h=null))}if(I.D){const wy=yn.g?yn.g.getResponseHeader("X-HTTP-Session-Id"):null;wy&&(I.ya=wy,He(I.I,I.D,wy))}}A.G=3,A.l&&A.l.ua(),A.ba&&(A.R=Date.now()-f.F,A.j.info("Handshake RTT: "+A.R+"ms")),I=A;var W=f;if(I.qa=j2(I,I.J?I.ia:null,I.W),W.K){n2(I.h,W);var De=W,Lt=I.L;Lt&&(De.I=Lt),De.B&&(my(De),np(De)),I.g=W}else S2(I);0<A.i.length&&up(A)}else Ce[0]!="stop"&&Ce[0]!="close"||so(A,7);else A.G==3&&(Ce[0]=="stop"||Ce[0]=="close"?Ce[0]=="stop"?so(A,7):xy(A):Ce[0]!="noop"&&A.l&&A.l.ta(Ce),A.v=0)}}nc(4)}catch{}}var VD=class{constructor(f,b){this.g=f,this.map=b}};function e2(f){this.l=f||10,l.PerformanceNavigationTiming?(f=l.performance.getEntriesByType("navigation"),f=0<f.length&&(f[0].nextHopProtocol=="hq"||f[0].nextHopProtocol=="h2")):f=!!(l.chrome&&l.chrome.loadTimes&&l.chrome.loadTimes()&&l.chrome.loadTimes().wasFetchedViaSpdy),this.j=f?this.l:1,this.g=null,1<this.j&&(this.g=new Set),this.h=null,this.i=[]}function t2(f){return f.h?!0:f.g?f.g.size>=f.j:!1}function a2(f){return f.h?1:f.g?f.g.size:0}function fy(f,b){return f.h?f.h==b:f.g?f.g.has(b):!1}function gy(f,b){f.g?f.g.add(b):f.h=b}function n2(f,b){f.h&&f.h==b?f.h=null:f.g&&f.g.has(b)&&f.g.delete(b)}e2.prototype.cancel=function(){if(this.i=i2(this),this.h)this.h.cancel(),this.h=null;else if(this.g&&this.g.size!==0){for(const f of this.g.values())f.cancel();this.g.clear()}};function i2(f){if(f.h!=null)return f.i.concat(f.h.D);if(f.g!=null&&f.g.size!==0){let b=f.i;for(const A of f.g.values())b=b.concat(A.D);return b}return y(f.i)}function HD(f){if(f.V&&typeof f.V=="function")return f.V();if(typeof Map<"u"&&f instanceof Map||typeof Set<"u"&&f instanceof Set)return Array.from(f.values());if(typeof f=="string")return f.split("");if(c(f)){for(var b=[],A=f.length,I=0;I<A;I++)b.push(f[I]);return b}b=[],A=0;for(I in f)b[A++]=f[I];return b}function FD(f){if(f.na&&typeof f.na=="function")return f.na();if(!f.V||typeof f.V!="function"){if(typeof Map<"u"&&f instanceof Map)return Array.from(f.keys());if(!(typeof Set<"u"&&f instanceof Set)){if(c(f)||typeof f=="string"){var b=[];f=f.length;for(var A=0;A<f;A++)b.push(A);return b}b=[],A=0;for(const I in f)b[A++]=I;return b}}}function r2(f,b){if(f.forEach&&typeof f.forEach=="function")f.forEach(b,void 0);else if(c(f)||typeof f=="string")Array.prototype.forEach.call(f,b,void 0);else for(var A=FD(f),I=HD(f),D=I.length,q=0;q<D;q++)b.call(void 0,I[q],A&&A[q],f)}var o2=RegExp("^(?:([^:/?#.]+):)?(?://(?:([^\\\\/?#]*)@)?([^\\\\/?#]*?)(?::([0-9]+))?(?=[\\\\/?#]|$))?([^?#]+)?(?:\\?([^#]*))?(?:#([\\s\\S]*))?$");function BD(f,b){if(f){f=f.split("&");for(var A=0;A<f.length;A++){var I=f[A].indexOf("="),D=null;if(0<=I){var q=f[A].substring(0,I);D=f[A].substring(I+1)}else q=f[A];b(q,D?decodeURIComponent(D.replace(/\+/g," ")):"")}}}function oo(f){if(this.g=this.o=this.j="",this.s=null,this.m=this.l="",this.h=!1,f instanceof oo){this.h=f.h,ip(this,f.j),this.o=f.o,this.g=f.g,rp(this,f.s),this.l=f.l;var b=f.i,A=new cc;A.i=b.i,b.g&&(A.g=new Map(b.g),A.h=b.h),s2(this,A),this.m=f.m}else f&&(b=String(f).match(o2))?(this.h=!1,ip(this,b[1]||"",!0),this.o=sc(b[2]||""),this.g=sc(b[3]||"",!0),rp(this,b[4]),this.l=sc(b[5]||"",!0),s2(this,b[6]||"",!0),this.m=sc(b[7]||"")):(this.h=!1,this.i=new cc(null,this.h))}oo.prototype.toString=function(){var f=[],b=this.j;b&&f.push(lc(b,l2,!0),":");var A=this.g;return(A||b=="file")&&(f.push("//"),(b=this.o)&&f.push(lc(b,l2,!0),"@"),f.push(encodeURIComponent(String(A)).replace(/%25([0-9a-fA-F]{2})/g,"%$1")),A=this.s,A!=null&&f.push(":",String(A))),(A=this.l)&&(this.g&&A.charAt(0)!="/"&&f.push("/"),f.push(lc(A,A.charAt(0)=="/"?WD:$D,!0))),(A=this.i.toString())&&f.push("?",A),(A=this.m)&&f.push("#",lc(A,KD)),f.join("")};function li(f){return new oo(f)}function ip(f,b,A){f.j=A?sc(b,!0):b,f.j&&(f.j=f.j.replace(/:$/,""))}function rp(f,b){if(b){if(b=Number(b),isNaN(b)||0>b)throw Error("Bad port number "+b);f.s=b}else f.s=null}function s2(f,b,A){b instanceof cc?(f.i=b,JD(f.i,f.h)):(A||(b=lc(b,GD)),f.i=new cc(b,f.h))}function He(f,b,A){f.i.set(b,A)}function op(f){return He(f,"zx",Math.floor(2147483648*Math.random()).toString(36)+Math.abs(Math.floor(2147483648*Math.random())^Date.now()).toString(36)),f}function sc(f,b){return f?b?decodeURI(f.replace(/%25/g,"%2525")):decodeURIComponent(f):""}function lc(f,b,A){return typeof f=="string"?(f=encodeURI(f).replace(b,UD),A&&(f=f.replace(/%25([0-9a-fA-F]{2})/g,"%$1")),f):null}function UD(f){return f=f.charCodeAt(0),"%"+(f>>4&15).toString(16)+(f&15).toString(16)}var l2=/[#\/\?@]/g,$D=/[#\?:]/g,WD=/[#\?]/g,GD=/[#\?@]/g,KD=/#/g;function cc(f,b){this.h=this.g=null,this.i=f||null,this.j=!!b}function Gi(f){f.g||(f.g=new Map,f.h=0,f.i&&BD(f.i,function(b,A){f.add(decodeURIComponent(b.replace(/\+/g," ")),A)}))}t=cc.prototype,t.add=function(f,b){Gi(this),this.i=null,f=xs(this,f);var A=this.g.get(f);return A||this.g.set(f,A=[]),A.push(b),this.h+=1,this};function c2(f,b){Gi(f),b=xs(f,b),f.g.has(b)&&(f.i=null,f.h-=f.g.get(b).length,f.g.delete(b))}function d2(f,b){return Gi(f),b=xs(f,b),f.g.has(b)}t.forEach=function(f,b){Gi(this),this.g.forEach(function(A,I){A.forEach(function(D){f.call(b,D,I,this)},this)},this)},t.na=function(){Gi(this);const f=Array.from(this.g.values()),b=Array.from(this.g.keys()),A=[];for(let I=0;I<b.length;I++){const D=f[I];for(let q=0;q<D.length;q++)A.push(b[I])}return A},t.V=function(f){Gi(this);let b=[];if(typeof f=="string")d2(this,f)&&(b=b.concat(this.g.get(xs(this,f))));else{f=Array.from(this.g.values());for(let A=0;A<f.length;A++)b=b.concat(f[A])}return b},t.set=function(f,b){return Gi(this),this.i=null,f=xs(this,f),d2(this,f)&&(this.h-=this.g.get(f).length),this.g.set(f,[b]),this.h+=1,this},t.get=function(f,b){return f?(f=this.V(f),0<f.length?String(f[0]):b):b};function u2(f,b,A){c2(f,b),0<A.length&&(f.i=null,f.g.set(xs(f,b),y(A)),f.h+=A.length)}t.toString=function(){if(this.i)return this.i;if(!this.g)return"";const f=[],b=Array.from(this.g.keys());for(var A=0;A<b.length;A++){var I=b[A];const q=encodeURIComponent(String(I)),W=this.V(I);for(I=0;I<W.length;I++){var D=q;W[I]!==""&&(D+="="+encodeURIComponent(String(W[I]))),f.push(D)}}return this.i=f.join("&")};function xs(f,b){return b=String(b),f.j&&(b=b.toLowerCase()),b}function JD(f,b){b&&!f.j&&(Gi(f),f.i=null,f.g.forEach(function(A,I){var D=I.toLowerCase();I!=D&&(c2(this,I),u2(this,D,A))},f)),f.j=b}function QD(f,b){const A=new rc;if(l.Image){const I=new Image;I.onload=h(Ki,A,"TestLoadImage: loaded",!0,b,I),I.onerror=h(Ki,A,"TestLoadImage: error",!1,b,I),I.onabort=h(Ki,A,"TestLoadImage: abort",!1,b,I),I.ontimeout=h(Ki,A,"TestLoadImage: timeout",!1,b,I),l.setTimeout(function(){I.ontimeout&&I.ontimeout()},1e4),I.src=f}else b(!1)}function XD(f,b){const A=new rc,I=new AbortController,D=setTimeout(()=>{I.abort(),Ki(A,"TestPingServer: timeout",!1,b)},1e4);fetch(f,{signal:I.signal}).then(q=>{clearTimeout(D),q.ok?Ki(A,"TestPingServer: ok",!0,b):Ki(A,"TestPingServer: server error",!1,b)}).catch(()=>{clearTimeout(D),Ki(A,"TestPingServer: error",!1,b)})}function Ki(f,b,A,I,D){try{D&&(D.onload=null,D.onerror=null,D.onabort=null,D.ontimeout=null),I(A)}catch{}}function YD(){this.g=new LD}function ZD(f,b,A){const I=A||"";try{r2(f,function(D,q){let W=D;d(D)&&(W=oy(D)),b.push(I+q+"="+encodeURIComponent(W))})}catch(D){throw b.push(I+"type="+encodeURIComponent("_badmap")),D}}function sp(f){this.l=f.Ub||null,this.j=f.eb||!1}g(sp,sy),sp.prototype.g=function(){return new lp(this.l,this.j)},sp.prototype.i=function(f){return function(){return f}}({});function lp(f,b){Gt.call(this),this.D=f,this.o=b,this.m=void 0,this.status=this.readyState=0,this.responseType=this.responseText=this.response=this.statusText="",this.onreadystatechange=null,this.u=new Headers,this.h=null,this.B="GET",this.A="",this.g=!1,this.v=this.j=this.l=null}g(lp,Gt),t=lp.prototype,t.open=function(f,b){if(this.readyState!=0)throw this.abort(),Error("Error reopening a connection");this.B=f,this.A=b,this.readyState=1,uc(this)},t.send=function(f){if(this.readyState!=1)throw this.abort(),Error("need to call open() first. ");this.g=!0;const b={headers:this.u,method:this.B,credentials:this.m,cache:void 0};f&&(b.body=f),(this.D||l).fetch(new Request(this.A,b)).then(this.Sa.bind(this),this.ga.bind(this))},t.abort=function(){this.response=this.responseText="",this.u=new Headers,this.status=0,this.j&&this.j.cancel("Request was aborted.").catch(()=>{}),1<=this.readyState&&this.g&&this.readyState!=4&&(this.g=!1,dc(this)),this.readyState=0},t.Sa=function(f){if(this.g&&(this.l=f,this.h||(this.status=this.l.status,this.statusText=this.l.statusText,this.h=f.headers,this.readyState=2,uc(this)),this.g&&(this.readyState=3,uc(this),this.g)))if(this.responseType==="arraybuffer")f.arrayBuffer().then(this.Qa.bind(this),this.ga.bind(this));else if(typeof l.ReadableStream<"u"&&"body"in f){if(this.j=f.body.getReader(),this.o){if(this.responseType)throw Error('responseType must be empty for "streamBinaryChunks" mode responses.');this.response=[]}else this.response=this.responseText="",this.v=new TextDecoder;p2(this)}else f.text().then(this.Ra.bind(this),this.ga.bind(this))};function p2(f){f.j.read().then(f.Pa.bind(f)).catch(f.ga.bind(f))}t.Pa=function(f){if(this.g){if(this.o&&f.value)this.response.push(f.value);else if(!this.o){var b=f.value?f.value:new Uint8Array(0);(b=this.v.decode(b,{stream:!f.done}))&&(this.response=this.responseText+=b)}f.done?dc(this):uc(this),this.readyState==3&&p2(this)}},t.Ra=function(f){this.g&&(this.response=this.responseText=f,dc(this))},t.Qa=function(f){this.g&&(this.response=f,dc(this))},t.ga=function(){this.g&&dc(this)};function dc(f){f.readyState=4,f.l=null,f.j=null,f.v=null,uc(f)}t.setRequestHeader=function(f,b){this.u.append(f,b)},t.getResponseHeader=function(f){return this.h&&this.h.get(f.toLowerCase())||""},t.getAllResponseHeaders=function(){if(!this.h)return"";const f=[],b=this.h.entries();for(var A=b.next();!A.done;)A=A.value,f.push(A[0]+": "+A[1]),A=b.next();return f.join(`\r
447`)};function uc(f){f.onreadystatechange&&f.onreadystatechange.call(f)}Object.defineProperty(lp.prototype,"withCredentials",{get:function(){return this.m==="include"},set:function(f){this.m=f?"include":"same-origin"}});function m2(f){let b="";return M(f,function(A,I){b+=I,b+=":",b+=A,b+=`\r
448`}),b}function yy(f,b,A){e:{for(I in A){var I=!1;break e}I=!0}I||(A=m2(A),typeof f=="string"?A!=null&&encodeURIComponent(String(A)):He(f,b,A))}function nt(f){Gt.call(this),this.headers=new Map,this.o=f||null,this.h=!1,this.v=this.g=null,this.D="",this.m=0,this.l="",this.j=this.B=this.u=this.A=!1,this.I=null,this.H="",this.J=!1}g(nt,Gt);var eq=/^https?$/i,tq=["POST","PUT"];t=nt.prototype,t.Ha=function(f){this.J=f},t.ea=function(f,b,A,I){if(this.g)throw Error("[goog.net.XhrIo] Object is active with another request="+this.D+"; newUri="+f);b=b?b.toUpperCase():"GET",this.D=f,this.l="",this.m=0,this.A=!1,this.h=!0,this.g=this.o?this.o.g():dy.g(),this.v=this.o?FS(this.o):FS(dy),this.g.onreadystatechange=m(this.Ea,this);try{this.B=!0,this.g.open(b,String(f),!0),this.B=!1}catch(q){h2(this,q);return}if(f=A||"",A=new Map(this.headers),I)if(Object.getPrototypeOf(I)===Object.prototype)for(var D in I)A.set(D,I[D]);else if(typeof I.keys=="function"&&typeof I.get=="function")for(const q of I.keys())A.set(q,I.get(q));else throw Error("Unknown input type for opt_headers: "+String(I));I=Array.from(A.keys()).find(q=>q.toLowerCase()=="content-type"),D=l.FormData&&f instanceof l.FormData,!(0<=Array.prototype.indexOf.call(tq,b,void 0))||I||D||A.set("Content-Type","application/x-www-form-urlencoded;charset=utf-8");for(const[q,W]of A)this.g.setRequestHeader(q,W);this.H&&(this.g.responseType=this.H),"withCredentials"in this.g&&this.g.withCredentials!==this.J&&(this.g.withCredentials=this.J);try{y2(this),this.u=!0,this.g.send(f),this.u=!1}catch(q){h2(this,q)}};function h2(f,b){f.h=!1,f.g&&(f.j=!0,f.g.abort(),f.j=!1),f.l=b,f.m=5,f2(f),cp(f)}function f2(f){f.A||(f.A=!0,la(f,"complete"),la(f,"error"))}t.abort=function(f){this.g&&this.h&&(this.h=!1,this.j=!0,this.g.abort(),this.j=!1,this.m=f||7,la(this,"complete"),la(this,"abort"),cp(this))},t.N=function(){this.g&&(this.h&&(this.h=!1,this.j=!0,this.g.abort(),this.j=!1),cp(this,!0)),nt.aa.N.call(this)},t.Ea=function(){this.s||(this.B||this.u||this.j?g2(this):this.bb())},t.bb=function(){g2(this)};function g2(f){if(f.h&&typeof o<"u"&&(!f.v[1]||ci(f)!=4||f.Z()!=2)){if(f.u&&ci(f)==4)qS(f.Ea,0,f);else if(la(f,"readystatechange"),ci(f)==4){f.h=!1;try{const W=f.Z();e:switch(W){case 200:case 201:case 202:case 204:case 206:case 304:case 1223:var b=!0;break e;default:b=!1}var A;if(!(A=b)){var I;if(I=W===0){var D=String(f.D).match(o2)[1]||null;!D&&l.self&&l.self.location&&(D=l.self.location.protocol.slice(0,-1)),I=!eq.test(D?D.toLowerCase():"")}A=I}if(A)la(f,"complete"),la(f,"success");else{f.m=6;try{var q=2<ci(f)?f.g.statusText:""}catch{q=""}f.l=q+" ["+f.Z()+"]",f2(f)}}finally{cp(f)}}}}function cp(f,b){if(f.g){y2(f);const A=f.g,I=f.v[0]?()=>{}:null;f.g=null,f.v=null,b||la(f,"ready");try{A.onreadystatechange=I}catch{}}}function y2(f){f.I&&(l.clearTimeout(f.I),f.I=null)}t.isActive=function(){return!!this.g};function ci(f){return f.g?f.g.readyState:0}t.Z=function(){try{return 2<ci(this)?this.g.status:-1}catch{return-1}},t.oa=function(){try{return this.g?this.g.responseText:""}catch{return""}},t.Oa=function(f){if(this.g){var b=this.g.responseText;return f&&b.indexOf(f)==0&&(b=b.substring(f.length)),RD(b)}};function x2(f){try{if(!f.g)return null;if("response"in f.g)return f.g.response;switch(f.H){case"":case"text":return f.g.responseText;case"arraybuffer":if("mozResponseArrayBuffer"in f.g)return f.g.mozResponseArrayBuffer}return null}catch{return null}}function aq(f){const b={};f=(f.g&&2<=ci(f)&&f.g.getAllResponseHeaders()||"").split(`\r
449`);for(let I=0;I<f.length;I++){if(w(f[I]))continue;var A=L(f[I]);const D=A[0];if(A=A[1],typeof A!="string")continue;A=A.trim();const q=b[D]||[];b[D]=q,q.push(A)}C(b,function(I){return I.join(", ")})}t.Ba=function(){return this.m},t.Ka=function(){return typeof this.l=="string"?this.l:String(this.l)};function pc(f,b,A){return A&&A.internalChannelParams&&A.internalChannelParams[f]||b}function v2(f){this.Aa=0,this.i=[],this.j=new rc,this.ia=this.qa=this.I=this.W=this.g=this.ya=this.D=this.H=this.m=this.S=this.o=null,this.Ya=this.U=0,this.Va=pc("failFast",!1,f),this.F=this.C=this.u=this.s=this.l=null,this.X=!0,this.za=this.T=-1,this.Y=this.v=this.B=0,this.Ta=pc("baseRetryDelayMs",5e3,f),this.cb=pc("retryDelaySeedMs",1e4,f),this.Wa=pc("forwardChannelMaxRetries",2,f),this.wa=pc("forwardChannelRequestTimeoutMs",2e4,f),this.pa=f&&f.xmlHttpFactory||void 0,this.Xa=f&&f.Tb||void 0,this.Ca=f&&f.useFetchStreams||!1,this.L=void 0,this.J=f&&f.supportsCrossDomainXhr||!1,this.K="",this.h=new e2(f&&f.concurrentRequestLimit),this.Da=new YD,this.P=f&&f.fastHandshake||!1,this.O=f&&f.encodeInitMessageHeaders||!1,this.P&&this.O&&(this.O=!1),this.Ua=f&&f.Rb||!1,f&&f.xa&&this.j.xa(),f&&f.forceLongPolling&&(this.X=!1),this.ba=!this.P&&this.X&&f&&f.detectBufferingProxy||!1,this.ja=void 0,f&&f.longPollingTimeout&&0<f.longPollingTimeout&&(this.ja=f.longPollingTimeout),this.ca=void 0,this.R=0,this.M=!1,this.ka=this.A=null}t=v2.prototype,t.la=8,t.G=1,t.connect=function(f,b,A,I){ca(0),this.W=f,this.H=b||{},A&&I!==void 0&&(this.H.OSID=A,this.H.OAID=I),this.F=this.X,this.I=j2(this,null,this.W),up(this)};function xy(f){if(b2(f),f.G==3){var b=f.U++,A=li(f.I);if(He(A,"SID",f.K),He(A,"RID",b),He(A,"TYPE","terminate"),mc(f,A),b=new Wi(f,f.j,b),b.L=2,b.v=op(li(A)),A=!1,l.navigator&&l.navigator.sendBeacon)try{A=l.navigator.sendBeacon(b.v.toString(),"")}catch{}!A&&l.Image&&(new Image().src=b.v,A=!0),A||(b.g=T2(b.j,null),b.g.ea(b.v)),b.F=Date.now(),np(b)}C2(f)}function dp(f){f.g&&(by(f),f.g.cancel(),f.g=null)}function b2(f){dp(f),f.u&&(l.clearTimeout(f.u),f.u=null),pp(f),f.h.cancel(),f.s&&(typeof f.s=="number"&&l.clearTimeout(f.s),f.s=null)}function up(f){if(!t2(f.h)&&!f.s){f.s=!0;var b=f.Ga;ae||re(),F||(ae(),F=!0),Z.add(b,f),f.B=0}}function nq(f,b){return a2(f.h)>=f.h.j-(f.s?1:0)?!1:f.s?(f.i=b.D.concat(f.i),!0):f.G==1||f.G==2||f.B>=(f.Va?0:f.Wa)?!1:(f.s=ic(m(f.Ga,f,b),E2(f,f.B)),f.B++,!0)}t.Ga=function(f){if(this.s)if(this.s=null,this.G==1){if(!f){this.U=Math.floor(1e5*Math.random()),f=this.U++;const D=new Wi(this,this.j,f);let q=this.o;if(this.S&&(q?(q=E(q),N(q,this.S)):q=this.S),this.m!==null||this.O||(D.H=q,q=null),this.P)e:{for(var b=0,A=0;A<this.i.length;A++){t:{var I=this.i[A];if("__data__"in I.map&&(I=I.map.__data__,typeof I=="string")){I=I.length;break t}I=void 0}if(I===void 0)break;if(b+=I,4096<b){b=A;break e}if(b===4096||A===this.i.length-1){b=A+1;break e}}b=1e3}else b=1e3;b=k2(this,D,b),A=li(this.I),He(A,"RID",f),He(A,"CVER",22),this.D&&He(A,"X-HTTP-Session-Id",this.D),mc(this,A),q&&(this.O?b="headers="+encodeURIComponent(String(m2(q)))+"&"+b:this.m&&yy(A,this.m,q)),gy(this.h,D),this.Ua&&He(A,"TYPE","init"),this.P?(He(A,"$req",b),He(A,"SID","null"),D.T=!0,py(D,A,null)):py(D,A,b),this.G=2}}else this.G==3&&(f?w2(this,f):this.i.length==0||t2(this.h)||w2(this))};function w2(f,b){var A;b?A=b.l:A=f.U++;const I=li(f.I);He(I,"SID",f.K),He(I,"RID",A),He(I,"AID",f.T),mc(f,I),f.m&&f.o&&yy(I,f.m,f.o),A=new Wi(f,f.j,A,f.B+1),f.m===null&&(A.H=f.o),b&&(f.i=b.D.concat(f.i)),b=k2(f,A,1e3),A.I=Math.round(.5*f.wa)+Math.round(.5*f.wa*Math.random()),gy(f.h,A),py(A,I,b)}function mc(f,b){f.H&&M(f.H,function(A,I){He(b,I,A)}),f.l&&r2({},function(A,I){He(b,I,A)})}function k2(f,b,A){A=Math.min(f.i.length,A);var I=f.l?m(f.l.Na,f.l,f):null;e:{var D=f.i;let q=-1;for(;;){const W=["count="+A];q==-1?0<A?(q=D[0].g,W.push("ofs="+q)):q=0:W.push("ofs="+q);let De=!0;for(let Lt=0;Lt<A;Lt++){let Ce=D[Lt].g;const Kt=D[Lt].map;if(Ce-=q,0>Ce)q=Math.max(0,D[Lt].g-100),De=!1;else try{ZD(Kt,W,"req"+Ce+"_")}catch{I&&I(Kt)}}if(De){I=W.join("&");break e}}}return f=f.i.splice(0,A),b.D=f,I}function S2(f){if(!f.g&&!f.u){f.Y=1;var b=f.Fa;ae||re(),F||(ae(),F=!0),Z.add(b,f),f.v=0}}function vy(f){return f.g||f.u||3<=f.v?!1:(f.Y++,f.u=ic(m(f.Fa,f),E2(f,f.v)),f.v++,!0)}t.Fa=function(){if(this.u=null,_2(this),this.ba&&!(this.M||this.g==null||0>=this.R)){var f=2*this.R;this.j.info("BP detection timer enabled: "+f),this.A=ic(m(this.ab,this),f)}},t.ab=function(){this.A&&(this.A=null,this.j.info("BP detection timeout reached."),this.j.info("Buffering proxy detected and switch to long-polling!"),this.F=!1,this.M=!0,ca(10),dp(this),_2(this))};function by(f){f.A!=null&&(l.clearTimeout(f.A),f.A=null)}function _2(f){f.g=new Wi(f,f.j,"rpc",f.Y),f.m===null&&(f.g.H=f.o),f.g.O=0;var b=li(f.qa);He(b,"RID","rpc"),He(b,"SID",f.K),He(b,"AID",f.T),He(b,"CI",f.F?"0":"1"),!f.F&&f.ja&&He(b,"TO",f.ja),He(b,"TYPE","xmlhttp"),mc(f,b),f.m&&f.o&&yy(b,f.m,f.o),f.L&&(f.g.I=f.L);var A=f.g;f=f.ia,A.L=1,A.v=op(li(b)),A.m=null,A.P=!0,XS(A,f)}t.Za=function(){this.C!=null&&(this.C=null,dp(this),vy(this),ca(19))};function pp(f){f.C!=null&&(l.clearTimeout(f.C),f.C=null)}function A2(f,b){var A=null;if(f.g==b){pp(f),by(f),f.g=null;var I=2}else if(fy(f.h,b))A=b.D,n2(f.h,b),I=1;else return;if(f.G!=0){if(b.o)if(I==1){A=b.m?b.m.length:0,b=Date.now()-b.F;var D=f.B;I=ep(),la(I,new GS(I,A)),up(f)}else S2(f);else if(D=b.s,D==3||D==0&&0<b.X||!(I==1&&nq(f,b)||I==2&&vy(f)))switch(A&&0<A.length&&(b=f.h,b.i=b.i.concat(A)),D){case 1:so(f,5);break;case 4:so(f,10);break;case 3:so(f,6);break;default:so(f,2)}}}function E2(f,b){let A=f.Ta+Math.floor(Math.random()*f.cb);return f.isActive()||(A*=2),A*b}function so(f,b){if(f.j.info("Error code "+b),b==2){var A=m(f.fb,f),I=f.Xa;const D=!I;I=new oo(I||"//www.google.com/images/cleardot.gif"),l.location&&l.location.protocol=="http"||ip(I,"https"),op(I),D?QD(I.toString(),A):XD(I.toString(),A)}else ca(2);f.G=0,f.l&&f.l.sa(b),C2(f),b2(f)}t.fb=function(f){f?(this.j.info("Successfully pinged google.com"),ca(2)):(this.j.info("Failed to ping google.com"),ca(1))};function C2(f){if(f.G=0,f.ka=[],f.l){const b=i2(f.h);(b.length!=0||f.i.length!=0)&&(x(f.ka,b),x(f.ka,f.i),f.h.i.length=0,y(f.i),f.i.length=0),f.l.ra()}}function j2(f,b,A){var I=A instanceof oo?li(A):new oo(A);if(I.g!="")b&&(I.g=b+"."+I.g),rp(I,I.s);else{var D=l.location;I=D.protocol,b=b?b+"."+D.hostname:D.hostname,D=+D.port;var q=new oo(null);I&&ip(q,I),b&&(q.g=b),D&&rp(q,D),A&&(q.l=A),I=q}return A=f.D,b=f.ya,A&&b&&He(I,A,b),He(I,"VER",f.la),mc(f,I),I}function T2(f,b,A){if(b&&!f.J)throw Error("Can't create secondary domain capable XhrIo object.");return b=f.Ca&&!f.pa?new nt(new sp({eb:A})):new nt(f.pa),b.Ha(f.J),b}t.isActive=function(){return!!this.l&&this.l.isActive(this)};function N2(){}t=N2.prototype,t.ua=function(){},t.ta=function(){},t.sa=function(){},t.ra=function(){},t.isActive=function(){return!0},t.Na=function(){};function mp(){}mp.prototype.g=function(f,b){return new Ma(f,b)};function Ma(f,b){Gt.call(this),this.g=new v2(b),this.l=f,this.h=b&&b.messageUrlParams||null,f=b&&b.messageHeaders||null,b&&b.clientProtocolHeaderRequired&&(f?f["X-Client-Protocol"]="webchannel":f={"X-Client-Protocol":"webchannel"}),this.g.o=f,f=b&&b.initMessageHeaders||null,b&&b.messageContentType&&(f?f["X-WebChannel-Content-Type"]=b.messageContentType:f={"X-WebChannel-Content-Type":b.messageContentType}),b&&b.va&&(f?f["X-WebChannel-Client-Profile"]=b.va:f={"X-WebChannel-Client-Profile":b.va}),this.g.S=f,(f=b&&b.Sb)&&!w(f)&&(this.g.m=f),this.v=b&&b.supportsCrossDomainXhr||!1,this.u=b&&b.sendRawJson||!1,(b=b&&b.httpSessionIdParam)&&!w(b)&&(this.g.D=b,f=this.h,f!==null&&b in f&&(f=this.h,b in f&&delete f[b])),this.j=new vs(this)}g(Ma,Gt),Ma.prototype.m=function(){this.g.l=this.j,this.v&&(this.g.J=!0),this.g.connect(this.l,this.h||void 0)},Ma.prototype.close=function(){xy(this.g)},Ma.prototype.o=function(f){var b=this.g;if(typeof f=="string"){var A={};A.__data__=f,f=A}else this.u&&(A={},A.__data__=oy(f),f=A);b.i.push(new VD(b.Ya++,f)),b.G==3&&up(b)},Ma.prototype.N=function(){this.g.l=null,delete this.j,xy(this.g),delete this.g,Ma.aa.N.call(this)};function I2(f){ly.call(this),f.__headers__&&(this.headers=f.__headers__,this.statusCode=f.__status__,delete f.__headers__,delete f.__status__);var b=f.__sm__;if(b){e:{for(const A in b){f=A;break e}f=void 0}(this.i=f)&&(f=this.i,b=b!==null&&f in b?b[f]:void 0),this.data=b}else this.data=f}g(I2,ly);function P2(){cy.call(this),this.status=1}g(P2,cy);function vs(f){this.g=f}g(vs,N2),vs.prototype.ua=function(){la(this.g,"a")},vs.prototype.ta=function(f){la(this.g,new I2(f))},vs.prototype.sa=function(f){la(this.g,new P2)},vs.prototype.ra=function(){la(this.g,"b")},mp.prototype.createWebChannel=mp.prototype.g,Ma.prototype.send=Ma.prototype.o,Ma.prototype.open=Ma.prototype.m,Ma.prototype.close=Ma.prototype.close,YR=function(){return new mp},XR=function(){return ep()},QR=io,Yv={mb:0,pb:1,qb:2,Jb:3,Ob:4,Lb:5,Mb:6,Kb:7,Ib:8,Nb:9,PROXY:10,NOPROXY:11,Gb:12,Cb:13,Db:14,Bb:15,Eb:16,Fb:17,ib:18,hb:19,jb:20},tp.NO_ERROR=0,tp.TIMEOUT=8,tp.HTTP_ERROR=6,Rm=tp,KS.COMPLETE="complete",JR=KS,BS.EventType=ac,ac.OPEN="a",ac.CLOSE="b",ac.ERROR="c",ac.MESSAGE="d",Gt.prototype.listen=Gt.prototype.K,Vc=BS,nt.prototype.listenOnce=nt.prototype.L,nt.prototype.getLastError=nt.prototype.Ka,nt.prototype.getLastErrorCode=nt.prototype.Ba,nt.prototype.getStatus=nt.prototype.Z,nt.prototype.getResponseJson=nt.prototype.Oa,nt.prototype.getResponseText=nt.prototype.oa,nt.prototype.send=nt.prototype.ea,nt.prototype.setWithCredentials=nt.prototype.Ha,KR=nt}).apply(typeof Vp<"u"?Vp:typeof self<"u"?self:typeof window<"u"?window:{});const QE="@firebase/firestore";/**
450 * @license
451 * Copyright 2017 Google LLC
452 *
453 * Licensed under the Apache License, Version 2.0 (the "License");
454 * you may not use this file except in compliance with the License.
455 * You may obtain a copy of the License at
456 *
457 *   http://www.apache.org/licenses/LICENSE-2.0
458 *
459 * Unless required by applicable law or agreed to in writing, software
460 * distributed under the License is distributed on an "AS IS" BASIS,
461 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
462 * See the License for the specific language governing permissions and
463 * limitations under the License.
464 */class ea{constructor(e){this.uid=e}isAuthenticated(){return this.uid!=null}toKey(){return this.isAuthenticated()?"uid:"+this.uid:"anonymous-user"}isEqual(e){return e.uid===this.uid}}ea.UNAUTHENTICATED=new ea(null),ea.GOOGLE_CREDENTIALS=new ea("google-credentials-uid"),ea.FIRST_PARTY=new ea("first-party-uid"),ea.MOCK_USER=new ea("mock-user");/**
465 * @license
466 * Copyright 2017 Google LLC
467 *
468 * Licensed under the Apache License, Version 2.0 (the "License");
469 * you may not use this file except in compliance with the License.
470 * You may obtain a copy of the License at
471 *
472 *   http://www.apache.org/licenses/LICENSE-2.0
473 *
474 * Unless required by applicable law or agreed to in writing, software
475 * distributed under the License is distributed on an "AS IS" BASIS,
476 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
477 * See the License for the specific language governing permissions and
478 * limitations under the License.
479 */let Gl="10.14.0";/**
480 * @license
481 * Copyright 2017 Google LLC
482 *
483 * Licensed under the Apache License, Version 2.0 (the "License");
484 * you may not use this file except in compliance with the License.
485 * You may obtain a copy of the License at
486 *
487 *   http://www.apache.org/licenses/LICENSE-2.0
488 *
489 * Unless required by applicable law or agreed to in writing, software
490 * distributed under the License is distributed on an "AS IS" BASIS,
491 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
492 * See the License for the specific language governing permissions and
493 * limitations under the License.
494 */const Jo=new pg("@firebase/firestore");function jc(){return Jo.logLevel}function Y(t,...e){if(Jo.logLevel<=_e.DEBUG){const a=e.map(Hw);Jo.debug(`Firestore (${Gl}): ${t}`,...a)}}function Vi(t,...e){if(Jo.logLevel<=_e.ERROR){const a=e.map(Hw);Jo.error(`Firestore (${Gl}): ${t}`,...a)}}function wl(t,...e){if(Jo.logLevel<=_e.WARN){const a=e.map(Hw);Jo.warn(`Firestore (${Gl}): ${t}`,...a)}}function Hw(t){if(typeof t=="string")return t;try{/**
495* @license
496* Copyright 2020 Google LLC
497*
498* Licensed under the Apache License, Version 2.0 (the "License");
499* you may not use this file except in compliance with the License.
500* You may obtain a copy of the License at
501*
502*   http://www.apache.org/licenses/LICENSE-2.0
503*
504* Unless required by applicable law or agreed to in writing, software
505* distributed under the License is distributed on an "AS IS" BASIS,
506* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
507* See the License for the specific language governing permissions and
508* limitations under the License.
509*/return function(a){return JSON.stringify(a)}(t)}catch{return t}}/**
510 * @license
511 * Copyright 2017 Google LLC
512 *
513 * Licensed under the Apache License, Version 2.0 (the "License");
514 * you may not use this file except in compliance with the License.
515 * You may obtain a copy of the License at
516 *
517 *   http://www.apache.org/licenses/LICENSE-2.0
518 *
519 * Unless required by applicable law or agreed to in writing, software
520 * distributed under the License is distributed on an "AS IS" BASIS,
521 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
522 * See the License for the specific language governing permissions and
523 * limitations under the License.
524 */function pe(t="Unexpected state"){const e=`FIRESTORE (${Gl}) INTERNAL ASSERTION FAILED: `+t;throw Vi(e),new Error(e)}function Oe(t,e){t||pe()}function he(t,e){return t}/**
525 * @license
526 * Copyright 2017 Google LLC
527 *
528 * Licensed under the Apache License, Version 2.0 (the "License");
529 * you may not use this file except in compliance with the License.
530 * You may obtain a copy of the License at
531 *
532 *   http://www.apache.org/licenses/LICENSE-2.0
533 *
534 * Unless required by applicable law or agreed to in writing, softw
534are
535 * distributed under the License is distributed on an "AS IS" BASIS,
536 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
537 * See the License for the specific language governing permissions and
538 * limitations under the License.
539 */const z={OK:"ok",CANCELLED:"cancelled",UNKNOWN:"unknown",INVALID_ARGUMENT:"invalid-argument",DEADLINE_EXCEEDED:"deadline-exceeded",NOT_FOUND:"not-found",ALREADY_EXISTS:"already-exists",PERMISSION_DENIED:"permission-denied",UNAUTHENTICATED:"unauthenticated",RESOURCE_EXHAUSTED:"resource-exhausted",FAILED_PRECONDITION:"failed-precondition",ABORTED:"aborted",OUT_OF_RANGE:"out-of-range",UNIMPLEMENTED:"unimplemented",INTERNAL:"internal",UNAVAILABLE:"unavailable",DATA_LOSS:"data-loss"};class X extends gn{constructor(e,a){super(e,a),this.code=e,this.message=a,this.toString=()=>`${this.name}: [code=${this.code}]: ${this.message}`}}/**
540 * @license
541 * Copyright 2017 Google LLC
542 *
543 * Licensed under the Apache License, Version 2.0 (the "License");
544 * you may not use this file except in compliance with the License.
545 * You may obtain a copy of the License at
546 *
547 *   http://www.apache.org/licenses/LICENSE-2.0
548 *
549 * Unless required by applicable law or agreed to in writing, software
550 * distributed under the License is distributed on an "AS IS" BASIS,
551 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
552 * See the License for the specific language governing permissions and
553 * limitations under the License.
554 */class Ti{constructor(){this.promise=new Promise((e,a)=>{this.resolve=e,this.reject=a})}}/**
555 * @license
556 * Copyright 2017 Google LLC
557 *
558 * Licensed under the Apache License, Version 2.0 (the "License");
559 * you may not use this file except in compliance with the License.
560 * You may obtain a copy of the License at
561 *
562 *   http://www.apache.org/licenses/LICENSE-2.0
563 *
564 * Unless required by applicable law or agreed to in writing, software
565 * distributed under the License is distributed on an "AS IS" BASIS,
566 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
567 * See the License for the specific language governing permissions and
568 * limitations under the License.
569 */class ZR{constructor(e,a){this.user=a,this.type="OAuth",this.headers=new Map,this.headers.set("Authorization",`Bearer ${e}`)}}class kW{getToken(){return Promise.resolve(null)}invalidateToken(){}start(e,a){e.enqueueRetryable(()=>a(ea.UNAUTHENTICATED))}shutdown(){}}class SW{constructor(e){this.token=e,this.changeListener=null}getToken(){return Promise.resolve(this.token)}invalidateToken(){}start(e,a){this.changeListener=a,e.enqueueRetryable(()=>a(this.token.user))}shutdown(){this.changeListener=null}}class _W{constructor(e){this.t=e,this.currentUser=ea.UNAUTHENTICATED,this.i=0,this.forceRefresh=!1,this.auth=null}start(e,a){Oe(this.o===void 0);let n=this.i;const i=c=>this.i!==n?(n=this.i,a(c)):Promise.resolve();let r=new Ti;this.o=()=>{this.i++,this.currentUser=this.u(),r.resolve(),r=new Ti,e.enqueueRetryable(()=>i(this.currentUser))};const o=()=>{const c=r;e.enqueueRetryable(async()=>{await c.promise,await i(this.currentUser)})},l=c=>{Y("FirebaseAuthCredentialsProvider","Auth detected"),this.auth=c,this.o&&(this.auth.addAuthTokenListener(this.o),o())};this.t.onInit(c=>l(c)),setTimeout(()=>{if(!this.auth){const c=this.t.getImmediate({optional:!0});c?l(c):(Y("FirebaseAuthCredentialsProvider","Auth not yet detected"),r.resolve(),r=new Ti)}},0),o()}getToken(){const e=this.i,a=this.forceRefresh;return this.forceRefresh=!1,this.auth?this.auth.getToken(a).then(n=>this.i!==e?(Y("FirebaseAuthCredentialsProvider","getToken aborted due to token change."),this.getToken()):n?(Oe(typeof n.accessToken=="string"),new ZR(n.accessToken,this.currentUser)):null):Promise.resolve(null)}invalidateToken(){this.forceRefresh=!0}shutdown(){this.auth&&this.o&&this.auth.removeAuthTokenListener(this.o),this.o=void 0}u(){const e=this.auth&&this.auth.getUid();return Oe(e===null||typeof e=="string"),new ea(e)}}class AW{constructor(e,a,n){this.l=e,this.h=a,this.P=n,this.type="FirstParty",this.user=ea.FIRST_PARTY,this.I=new Map}T(){return this.P?this.P():null}get headers(){this.I.set("X-Goog-AuthUser",this.l);const e=this.T();return e&&this.I.set("Authorization",e),this.h&&this.I.set("X-Goog-Iam-Authorization-Token",this.h),this.I}}class EW{constructor(e,a,n){this.l=e,this.h=a,this.P=n}getToken(){return Promise.resolve(new AW(this.l,this.h,this.P))}start(e,a){e.enqueueRetryable(()=>a(ea.FIRST_PARTY))}shutdown(){}invalidateToken(){}}class CW{constructor(e){this.value=e,this.type="AppCheck",this.headers=new Map,e&&e.length>0&&this.headers.set("x-firebase-appcheck",this.value)}}class jW{constructor(e){this.A=e,this.forceRefresh=!1,this.appCheck=null,this.R=null}start(e,a){Oe(this.o===void 0);const n=r=>{r.error!=null&&Y("FirebaseAppCheckTokenProvider",`Error getting App Check token; using placeholder token instead. Error: ${r.error.message}`);const o=r.token!==this.R;return this.R=r.token,Y("FirebaseAppCheckTokenProvider",`Received ${o?"new":"existing"} token.`),o?a(r.token):Promise.resolve()};this.o=r=>{e.enqueueRetryable(()=>n(r))};const i=r=>{Y("FirebaseAppCheckTokenProvider","AppCheck detected"),this.appCheck=r,this.o&&this.appCheck.addTokenListener(this.o)};this.A.onInit(r=>i(r)),setTimeout(()=>{if(!this.appCheck){const r=this.A.getImmediate({optional:!0});r?i(r):Y("FirebaseAppCheckTokenProvider","AppCheck not yet detected")}},0)}getToken(){const e=this.forceRefresh;return this.forceRefresh=!1,this.appCheck?this.appCheck.getToken(e).then(a=>a?(Oe(typeof a.token=="string"),this.R=a.token,new CW(a.token)):null):Promise.resolve(null)}invalidateToken(){this.forceRefresh=!0}shutdown(){this.appCheck&&this.o&&this.appCheck.removeTokenListener(this.o),this.o=void 0}}/**
570 * @license
571 * Copyright 2020 Google LLC
572 *
573 * Licensed under the Apache License, Version 2.0 (the "License");
574 * you may not use this file except in compliance with the License.
575 * You may obtain a copy of the License at
576 *
577 *   http://www.apache.org/licenses/LICENSE-2.0
578 *
579 * Unless required by applicable law or agreed to in writing, software
580 * distributed under the License is distributed on an "AS IS" BASIS,
581 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
582 * See the License for the specific language governing permissions and
583 * limitations under the License.
584 */function TW(t){const e=typeof self<"u"&&(self.crypto||self.msCrypto),a=new Uint8Array(t);if(e&&typeof e.getRandomValues=="function")e.getRandomValues(a);else for(let n=0;n<t;n++)a[n]=Math.floor(256*Math.random());return a}/**
585 * @license
586 * Copyright 2017 Google LLC
587 *
588 * Licensed under the Apache License, Version 2.0 (the "License");
589 * you may not use this file except in compliance with the License.
590 * You may obtain a copy of the License at
591 *
592 *   http://www.apache.org/licenses/LICENSE-2.0
593 *
594 * Unless required by applicable law or agreed to in writing, software
595 * distributed under the License is distributed on an "AS IS" BASIS,
596 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
597 * See the License for the specific language governing permissions and
598 * limitations under the License.
599 */class eL{static newId(){const e="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789",a=Math.floor(256/e.length)*e.length;let n="";for(;n.length<20;){const i=TW(40);for(let r=0;r<i.length;++r)n.length<20&&i[r]<a&&(n+=e.charAt(i[r]%e.length))}return n}}function je(t,e){return t<e?-1:t>e?1:0}function kl(t,e,a){return t.length===e.length&&t.every((n,i)=>a(n,e[i]))}/**
600 * @license
601 * Copyright 2017 Google LLC
602 *
603 * Licensed under the Apache License, Version 2.0 (the "License");
604 * you may not use this file except in compliance with the License.
605 * You may obtain a copy of the License at
606 *
607 *   http://www.apache.org/licenses/LICENSE-2.0
608 *
609 * Unless required by applicable law or agreed to in writing, software
610 * distributed under the License is distributed on an "AS IS" BASIS,
611 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
612 * See the License for the specific language governing permissions and
613 * limitations under the License.
614 */class xt{constructor(e,a){if(this.seconds=e,this.nanoseconds=a,a<0)throw new X(z.INVALID_ARGUMENT,"Timestamp nanoseconds out of range: "+a);if(a>=1e9)throw new X(z.INVALID_ARGUMENT,"Timestamp nanoseconds out of range: "+a);if(e<-62135596800)throw new X(z.INVALID_ARGUMENT,"Timestamp seconds out of range: "+e);if(e>=253402300800)throw new X(z.INVALID_ARGUMENT,"Timestamp seconds out of range: "+e)}static now(){return xt.fromMillis(Date.now())}static fromDate(e){return xt.fromMillis(e.getTime())}static fromMillis(e){const a=Math.floor(e/1e3),n=Math.floor(1e6*(e-1e3*a));return new xt(a,n)}toDate(){return new Date(this.toMillis())}toMillis(){return 1e3*this.seconds+this.nanoseconds/1e6}_compareTo(e){return this.seconds===e.seconds?je(this.nanoseconds,e.nanoseconds):je(this.seconds,e.seconds)}isEqual(e){return e.seconds===this.seconds&&e.nanoseconds===this.nanoseconds}toString(){return"Timestamp(seconds="+this.seconds+", nanoseconds="+this.nanoseconds+")"}toJSON(){return{seconds:this.seconds,nanoseconds:this.nanoseconds}}valueOf(){const e=this.seconds- -62135596800;return String(e).padStart(12,"0")+"."+String(this.nanoseconds).padStart(9,"0")}}/**
615 * @license
616 * Copyright 2017 Google LLC
617 *
618 * Licensed under the Apache License, Version 2.0 (the "License");
619 * you may not use this file except in compliance with the License.
620 * You may obtain a copy of the License at
621 *
622 *   http://www.apache.org/licenses/LICENSE-2.0
623 *
624 * Unless required by applicable law or agreed to in writing, software
625 * distributed under the License is distributed on an "AS IS" BASIS,
626 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
627 * See the License for the specific language governing permissions and
628 * limitations under the License.
629 */class me{constructor(e){this.timestamp=e}static fromTimestamp(e){return new me(e)}static min(){return new me(new xt(0,0))}static max(){return new me(new xt(253402300799,999999999))}compareTo(e){return this.timestamp._compareTo(e.timestamp)}isEqual(e){return this.timestamp.isEqual(e.timestamp)}toMicroseconds(){return 1e6*this.timestamp.seconds+this.timestamp.nanoseconds/1e3}toString(){return"SnapshotVersion("+this.timestamp.toString()+")"}toTimestamp(){return this.timestamp}}/**
630 * @license
631 * Copyright 2017 Google LLC
632 *
633 * Licensed under the Apache License, Version 2.0 (the "License");
634 * you may not use this file except in compliance with the License.
635 * You may obtain a copy of the License at
636 *
637 *   http://www.apache.org/licenses/LICENSE-2.0
638 *
639 * Unless required by applicable law or agreed to in writing, software
640 * distributed under the License is distributed on an "AS IS" BASIS,
641 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
642 * See the License for the specific language governing permissions and
643 * limitations under the License.
644 */class au{constructor(e,a,n){a===void 0?a=0:a>e.length&&pe(),n===void 0?n=e.length-a:n>e.length-a&&pe(),this.segments=e,this.offset=a,this.len=n}get length(){return this.len}isEqual(e){return au.comparator(this,e)===0}child(e){const a=this.segments.slice(this.offset,this.limit());return e instanceof au?e.forEach(n=>{a.push(n)}):a.push(e),this.construct(a)}limit(){return this.offset+this.length}popFirst(e){return e=e===void 0?1:e,this.construct(this.segments,this.offset+e,this.length-e)}popLast(){return this.construct(this.segments,this.offset,this.length-1)}firstSegment(){return this.segments[this.offset]}lastSegment(){return this.get(this.length-1)}get(e){return this.segments[this.offset+e]}isEmpty(){return this.length===0}isPrefixOf(e){if(e.length<this.length)return!1;for(let a=0;a<this.length;a++)if(this.get(a)!==e.get(a))return!1;return!0}isImmediateParentOf(e){if(this.length+1!==e.length)return!1;for(let a=0;a<this.length;a++)if(this.get(a)!==e.get(a))return!1;return!0}forEach(e){for(let a=this.offset,n=this.limit();a<n;a++)e(this.segments[a])}toArray(){return this.segments.slice(this.offset,this.limit())}static comparator(e,a){const n=Math.min(e.length,a.length);for(let i=0;i<n;i++){const r=e.get(i),o=a.get(i);if(r<o)return-1;if(r>o)return 1}return e.length<a.length?-1:e.length>a.length?1:0}}class Ue extends au{construct(e,a,n){return new Ue(e,a,n)}canonicalString(){return this.toArray().join("/")}toString(){return this.canonicalString()}toUriEncodedString(){return this.toArray().map(encodeURIComponent).join("/")}static fromString(...e){const a=[];for(const n of e){if(n.indexOf("//")>=0)throw new X(z.INVALID_ARGUMENT,`Invalid segment (${n}). Paths must not contain // in them.`);a.push(...n.split("/").filter(i=>i.length>0))}return new Ue(a)}static emptyPath(){return new Ue([])}}const NW=/^[_a-zA-Z][_a-zA-Z0-9]*$/;class Ht extends au{construct(e,a,n){return new Ht(e,a,n)}static isValidIdentifier(e){return NW.test(e)}canonicalString(){return this.toArray().map(e=>(e=e.replace(/\\/g,"\\\\").replace(/`/g,"\\`"),Ht.isValidIdentifier(e)||(e="`"+e+"`"),e)).join(".")}toString(){return this.canonicalString()}isKeyField(){return this.length===1&&this.get(0)==="__name__"}static keyField(){return new Ht(["__name__"])}static fromServerFormat(e){const a=[];let n="",i=0;const r=()=>{if(n.length===0)throw new X(z.INVALID_ARGUMENT,`Invalid field path (${e}). Paths must not be empty, begin with '.', end with '.', or contain '..'`);a.push(n),n=""};let o=!1;for(;i<e.length;){const l=e[i];if(l==="\\"){if(i+1===e.length)throw new X(z.INVALID_ARGUMENT,"Path has trailing escape character: "+e);const c=e[i+1];if(c!=="\\"&&c!=="."&&c!=="`")throw new X(z.INVALID_ARGUMENT,"Path has invalid escape sequence: "+e);n+=c,i+=2}else l==="`"?(o=!o,i++):l!=="."||o?(n+=l,i++):(r(),i++)}if(r(),o)throw new X(z.INVALID_ARGUMENT,"Unterminated ` in path: "+e);return new Ht(a)}static emptyPath(){return new Ht([])}}/**
645 * @license
646 * Copyright 2017 Google LLC
647 *
648 * Licensed under the Apache License, Version 2.0 (the "License");
649 * you may not use this file except in compliance with the License.
650 * You may obtain a copy of the License at
651 *
652 *   http://www.apache.org/licenses/LICENSE-2.0
653 *
654 * Unless required by applicable law or agreed to in writing, software
655 * distributed under the License is distributed on an "AS IS" BASIS,
656 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
657 * See the License for the specific language governing permissions and
658 * limitations under the License.
659 */class oe{constructor(e){this.path=e}static fromPath(e){return new oe(Ue.fromString(e))}static fromName(e){return new oe(Ue.fromString(e).popFirst(5))}static empty(){return new oe(Ue.emptyPath())}get collectionGroup(){return this.path.popLast().lastSegment()}hasCollectionId(e){return this.path.length>=2&&this.path.get(this.path.length-2)===e}getCollectionGroup(){return this.path.get(this.path.length-2)}getCollectionPath(){return this.path.popLast()}isEqual(e){return e!==null&&Ue.comparator(this.path,e.path)===0}toString(){return this.path.toString()}static comparator(e,a){return Ue.comparator(e.path,a.path)}static isDocumentKey(e){return e.length%2==0}static fromSegments(e){return new oe(new Ue(e.slice()))}}function IW(t,e){const a=t.toTimestamp().seconds,n=t.toTimestamp().nanoseconds+1,i=me.fromTimestamp(n===1e9?new xt(a+1,0):new xt(a,n));return new Hr(i,oe.empty(),e)}function PW(t){return new Hr(t.readTime,t.key,-1)}class Hr{constructor(e,a,n){this.readTime=e,this.documentKey=a,this.largestBatchId=n}static min(){return new Hr(me.min(),oe.empty(),-1)}static max(){return new Hr(me.max(),oe.empty(),-1)}}function RW(t,e){let a=t.readTime.compareTo(e.readTime);return a!==0?a:(a=oe.comparator(t.documentKey,e.documentKey),a!==0?a:je(t.largestBatchId,e.largestBatchId))}/**
660 * @license
661 * Copyright 2020 Google LLC
662 *
663 * Licensed under the Apache License, Version 2.0 (the "License");
664 * you may not use this file except in compliance with the License.
665 * You may obtain a copy of the License at
666 *
667 *   http://www.apache.org/licenses/LICENSE-2.0
668 *
669 * Unless required by applicable law or agreed to in writing, software
670 * distributed under the License is distributed on an "AS IS" BASIS,
671 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
672 * See the License for the specific language governing permissions and
673 * limitations under the License.
674 */const LW="The current tab is not in the required state to perform this operation. It might be necessary to refresh the browser tab.";class OW{constructor(){this.onCommittedListeners=[]}addOnCommittedListener(e){this.onCommittedListeners.push(e)}raiseOnCommittedEvent(){this.onCommittedListeners.forEach(e=>e())}}/**
675 * @license
676 * Copyright 2017 Google LLC
677 *
678 * Licensed under the Apache License, Version 2.0 (the "License");
679 * you may not use this file except in compliance with the License.
680 * You may obtain a copy of the License at
681 *
682 *   http://www.apache.org/licenses/LICENSE-2.0
683 *
684 * Unless required by applicable law or agreed to in writing, software
685 * distributed under the License is distributed on an "AS IS" BASIS,
686 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
687 * See the License for the specific language governing permissions and
688 * limitations under the License.
689 */async function Lu(t){if(t.code!==z.FAILED_PRECONDITION||t.message!==LW)throw t;Y("LocalStore","Unexpectedly lost primary lease")}/**
690 * @license
691 * Copyright 2017 Google LLC
692 *
693 * Licensed under the Apache License, Version 2.0 (the "License");
694 * you may not use this file except in compliance with the License.
695 * You may obtain a copy of the License at
696 *
697 *   http://www.apache.org/licenses/LICENSE-2.0
698 *
699 * Unless required by applicable law or agreed to in writing, software
700 * distributed under the License is distributed on an "AS IS" BASIS,
701 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
702 * See the License for the specific language governing permissions and
703 * limitations under the License.
704 */class H{constructor(e){this.nextCallback=null,this.catchCallback=null,this.result=void 0,this.error=void 0,this.isDone=!1,this.callbackAttached=!1,e(a=>{this.isDone=!0,this.result=a,this.nextCallback&&this.nextCallback(a)},a=>{this.isDone=!0,this.error=a,this.catchCallback&&this.catchCallback(a)})}catch(e){return this.next(void 0,e)}next(e,a){return this.callbackAttached&&pe(),this.callbackAttached=!0,this.isDone?this.error?this.wrapFailure(a,this.error):this.wrapSuccess(e,this.result):new H((n,i)=>{this.nextCallback=r=>{this.wrapSuccess(e,r).next(n,i)},this.catchCallback=r=>{this.wrapFailure(a,r).next(n,i)}})}toPromise(){return new Promise((e,a)=>{this.next(e,a)})}wrapUserFunction(e){try{const a=e();return a instanceof H?a:H.resolve(a)}catch(a){return H.reject(a)}}wrapSuccess(e,a){return e?this.wrapUserFunction(()=>e(a)):H.resolve(a)}wrapFailure(e,a){return e?this.wrapUserFunction(()=>e(a)):H.reject(a)}static resolve(e){return new H((a,n)=>{a(e)})}static reject(e){return new H((a,n)=>{n(e)})}static waitFor(e){return new H((a,n)=>{let i=0,r=0,o=!1;e.forEach(l=>{++i,l.next(()=>{++r,o&&r===i&&a()},c=>n(c))}),o=!0,r===i&&a()})}static or(e){let a=H.resolve(!1);for(const n of e)a=a.next(i=>i?H.resolve(i):n());return a}static forEach(e,a){const n=[];return e.forEach((i,r)=>{n.push(a.call(this,i,r))}),this.waitFor(n)}static mapArray(e,a){return new H((n,i)=>{const r=e.length,o=new Array(r);let l=0;for(let c=0;c<r;c++){const d=c;a(e[d]).next(u=>{o[d]=u,++l,l===r&&n(o)},u=>i(u))}})}static doWhile(e,a){return new H((n,i)=>{const r=()=>{e()===!0?a().next(()=>{r()},i):n()};r()})}}function MW(t){const e=t.match(/Android ([\d.]+)/i),a=e?e[1].split(".").slice(0,2).join("."):"-1";return Number(a)}function Ou(t){return t.name==="IndexedDbTransactionError"}/**
705 * @license
706 * Copyright 2018 Google LLC
707 *
708 * Licensed under the Apache License, Version 2.0 (the "License");
709 * you may not use this file except in compliance with the License.
710 * You may obtain a copy of the License at
711 *
712 *   http://www.apache.org/licenses/LICENSE-2.0
713 *
714 * Unless required by applicable law or agreed to in writing, softw
714are
715 * distributed under the License is distributed on an "AS IS" BASIS,
716 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
717 * See the License for the specific language governing permissions and
718 * limitations under the License.
719 */class Fw{constructor(e,a){this.previousValue=e,a&&(a.sequenceNumberHandler=n=>this.ie(n),this.se=n=>a.writeSequenceNumber(n))}ie(e){return this.previousValue=Math.max(e,this.previousValue),this.previousValue}next(){const e=++this.previousValue;return this.se&&this.se(e),e}}Fw.oe=-1;function hg(t){return t==null}function Nh(t){return t===0&&1/t==-1/0}function DW(t){return typeof t=="number"&&Number.isInteger(t)&&!Nh(t)&&t<=Number.MAX_SAFE_INTEGER&&t>=Number.MIN_SAFE_INTEGER}/**
720 * @license
721 * Copyright 2017 Google LLC
722 *
723 * Licensed under the Apache License, Version 2.0 (the "License");
724 * you may not use this file except in compliance with the License.
725 * You may obtain a copy of the License at
726 *
727 *   http://www.apache.org/licenses/LICENSE-2.0
728 *
729 * Unless required by applicable law or agreed to in writing, software
730 * distributed under the License is distributed on an "AS IS" BASIS,
731 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
732 * See the License for the specific language governing permissions and
733 * limitations under the License.
734 */function XE(t){let e=0;for(const a in t)Object.prototype.hasOwnProperty.call(t,a)&&e++;return e}function ps(t,e){for(const a in t)Object.prototype.hasOwnProperty.call(t,a)&&e(a,t[a])}function tL(t){for(const e in t)if(Object.prototype.hasOwnProperty.call(t,e))return!1;return!0}/**
735 * @license
736 * Copyright 2017 Google LLC
737 *
738 * Licensed under the Apache License, Version 2.0 (the "License");
739 * you may not use this file except in compliance with the License.
740 * You may obtain a copy of the License at
741 *
742 *   http://www.apache.org/licenses/LICENSE-2.0
743 *
744 * Unless required by applicable law or agreed to in writing, software
745 * distributed under the License is distributed on an "AS IS" BASIS,
746 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
747 * See the License for the specific language governing permissions and
748 * limitations under the License.
749 */class tt{constructor(e,a){this.comparator=e,this.root=a||qt.EMPTY}insert(e,a){return new tt(this.comparator,this.root.insert(e,a,this.comparator).copy(null,null,qt.BLACK,null,null))}remove(e){return new tt(this.comparator,this.root.remove(e,this.comparator).copy(null,null,qt.BLACK,null,null))}get(e){let a=this.root;for(;!a.isEmpty();){const n=this.comparator(e,a.key);if(n===0)return a.value;n<0?a=a.left:n>0&&(a=a.right)}return null}indexOf(e){let a=0,n=this.root;for(;!n.isEmpty();){const i=this.comparator(e,n.key);if(i===0)return a+n.left.size;i<0?n=n.left:(a+=n.left.size+1,n=n.right)}return-1}isEmpty(){return this.root.isEmpty()}get size(){return this.root.size}minKey(){return this.root.minKey()}maxKey(){return this.root.maxKey()}inorderTraversal(e){return this.root.inorderTraversal(e)}forEach(e){this.inorderTraversal((a,n)=>(e(a,n),!1))}toString(){const e=[];return this.inorderTraversal((a,n)=>(e.push(`${a}:${n}`),!1)),`{${e.join(", ")}}`}reverseTraversal(e){return this.root.reverseTraversal(e)}getIterator(){return new Hp(this.root,null,this.comparator,!1)}getIteratorFrom(e){return new Hp(this.root,e,this.comparator,!1)}getReverseIterator(){return new Hp(this.root,null,this.comparator,!0)}getReverseIteratorFrom(e){return new Hp(this.root,e,this.comparator,!0)}}class Hp{constructor(e,a,n,i){this.isReverse=i,this.nodeStack=[];let r=1;for(;!e.isEmpty();)if(r=a?n(e.key,a):1,a&&i&&(r*=-1),r<0)e=this.isReverse?e.left:e.right;else{if(r===0){this.nodeStack.push(e);break}this.nodeStack.push(e),e=this.isReverse?e.right:e.left}}getNext(){let e=this.nodeStack.pop();const a={key:e.key,value:e.value};if(this.isReverse)for(e=e.left;!e.isEmpty();)this.nodeStack.push(e),e=e.right;else for(e=e.right;!e.isEmpty();)this.nodeStack.push(e),e=e.left;return a}hasNext(){return this.nodeStack.length>0}peek(){if(this.nodeStack.length===0)return null;const e=this.nodeStack[this.nodeStack.length-1];return{key:e.key,value:e.value}}}class qt{constructor(e,a,n,i,r){this.key=e,this.value=a,this.color=n??qt.RED,this.left=i??qt.EMPTY,this.right=r??qt.EMPTY,this.size=this.left.size+1+this.right.size}
vendor: 5,036 bytes, lines 749-764
749copy(e,a,n,i,r){return new qt(e??this.key,a??this.value,n??this.color,i??this.left,r??this.right)}isEmpty(){return!1}inorderTraversal(e){return this.left.inorderTraversal(e)||e(this.key,this.value)||this.right.inorderTraversal(e)}reverseTraversal(e){return this.right.reverseTraversal(e)||e(this.key,this.value)||this.left.reverseTraversal(e)}min(){return this.left.isEmpty()?this:this.left.min()}minKey(){return this.min().key}maxKey(){return this.right.isEmpty()?this.key:this.right.maxKey()}insert(e,a,n){let i=this;const r=n(e,i.key);return i=r<0?i.copy(null,null,null,i.left.insert(e,a,n),null):r===0?i.copy(null,a,null,null,null):i.copy(null,null,null,null,i.right.insert(e,a,n)),i.fixUp()}removeMin(){if(this.left.isEmpty())return qt.EMPTY;let e=this;return e.left.isRed()||e.left.left.isRed()||(e=e.moveRedLeft()),e=e.copy(null,null,null,e.left.removeMin(),null),e.fixUp()}remove(e,a){let n,i=this;if(a(e,i.key)<0)i.left.isEmpty()||i.left.isRed()||i.left.left.isRed()||(i=i.moveRedLeft()),i=i.copy(null,null,null,i.left.remove(e,a),null);else{if(i.left.isRed()&&(i=i.rotateRight()),i.right.isEmpty()||i.right.isRed()||i.right.left.isRed()||(i=i.moveRedRight()),a(e,i.key)===0){if(i.right.isEmpty())return qt.EMPTY;n=i.right.min(),i=i.copy(n.key,n.value,null,null,i.right.removeMin())}i=i.copy(null,null,null,null,i.right.remove(e,a))}return i.fixUp()}isRed(){return this.color}fixUp(){let e=this;return e.right.isRed()&&!e.left.isRed()&&(e=e.rotateLeft()),e.left.isRed()&&e.left.left.isRed()&&(e=e.rotateRight()),e.left.isRed()&&e.right.isRed()&&(e=e.colorFlip()),e}moveRedLeft(){let e=this.colorFlip();return e.right.left.isRed()&&(e=e.copy(null,null,null,null,e.right.rotateRight()),e=e.rotateLeft(),e=e.colorFlip()),e}moveRedRight(){let e=this.colorFlip();return e.left.left.isRed()&&(e=e.rotateRight(),e=e.colorFlip()),e}rotateLeft(){const e=this.copy(null,null,qt.RED,null,this.right.left);return this.right.copy(null,null,this.color,e,null)}rotateRight(){const e=this.copy(null,null,qt.RED,this.left.right,null);return this.left.copy(null,null,this.color,null,e)}colorFlip(){const e=this.left.copy(null,null,!this.left.color,null,null),a=this.right.copy(null,null,!this.right.color,null,null);return this.copy(null,null,!this.color,e,a)}checkMaxDepth(){const e=this.check();return Math.pow(2,e)<=this.size+1}check(){if(this.isRed()&&this.left.isRed()||this.right.isRed())throw pe();const e=this.left.check();if(e!==this.right.check())throw pe();return e+(this.isRed()?0:1)}}qt.EMPTY=null,qt.RED=!0,qt.BLACK=!1;qt.EMPTY=new class{constructor(){this.size=0}get key(){throw pe()}get value(){throw pe()}get color(){throw pe()}get left(){throw pe()}get right(){throw pe()}copy(e,a,n,i,r){return this}insert(e,a,n){return new qt(e,a)}remove(e,a){return this}isEmpty(){return!0}inorderTraversal(e){return!1}reverseTraversal(e){return!1}minKey(){return null}maxKey(){return null}isRed(){return!1}checkMaxDepth(){return!0}check(){return 0}};/**
750 * @license
751 * Copyright 2017 Google LLC
752 *
753 * Licensed under the Apache License, Version 2.0 (the "License");
754 * you may not use this file except in compliance with the License.
755 * You may obtain a copy of the License at
756 *
757 *   http://www.apache.org/licenses/LICENSE-2.0
758 *
759 * Unless required by applicable law or agreed to in writing, software
760 * distributed under the License is distributed on an "AS IS" BASIS,
761 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
762 * See the License for the specific language governing permissions and
763 * limitations under the License.
764 */class Bt{constructor(e){this.comparator=e,this.data=new tt(this.comparator)}has(e){return this.data.get(e)!==null}first(){return this.data.minKey()}last(){return this.data.maxKey()}get size(){return this.data.size}indexOf(e){return this.data.indexOf(e)}forEach(e){this.data.inorderTraversal((a,n)=>(e(a),!1))}forEachInRange(e,a){const n=this.data.getIteratorFrom(e[0]);for(;n.hasNext();){const i=n.getNext();if(this.comparator(i.key,e[1])>=0)return;a(i.key)}}forEachWhile(e,a){let n;for(n=a!==void 0?this.data.getIteratorFrom(a):this.data.getIterator();n.hasNext();)if(!e(n.getNext().key))return}firstAfterOrEqual(e){const a=this.data.getIteratorFrom(e);return a.hasNext()?a.getNext().key:null}getIterator(){return new YE(this.data.getIterator())}getIteratorFrom(e){return new YE(this.data.getIteratorFrom(e))}add(e){return this.copy(this.data.remove(e).insert(e,!0))}delete(e){return this.has(e)?this.copy(this.data.remove(e)):this}isEmpty(){return this.data.isEmpty()}unionWith(e){let a=this;return a.size<e.size&&(a=e,e=this),e.forEach(n=>{a=a.add(n)}),a}isEqual(e){if(!(e instanceof Bt)||this.size!==e.size)return!1;const a=this.data.getIterator(),n=e.data.getIterator();for(;a.hasNext();){const i=a.getNext().key,r=n.getNext().key;if(this.comparator(i,r)!==0)return!1}return!0}toArray(){const e=[];return this.forEach(a=>{e.push(a)}),e}toString(){const e=[];return this.forEach(a=>e.push(a)),"SortedSet("+e.toString()+")"}copy(e){const a=new Bt(this.comparator);return a.data=e,a}}
764class YE{constructor(e){this.iter=e}getNext(){return this.iter.getNext().key}hasNext(){return this.iter.hasNext()}}/**
765 * @license
766 * Copyright 2020 Google LLC
767 *
768 * Licensed under the Apache License, Version 2.0 (the "License");
769 * you may not use this file except in compliance with the License.
770 * You may obtain a copy of the License at
771 *
772 *   http://www.apache.org/licenses/LICENSE-2.0
773 *
774 * Unless required by applicable law or agreed to in writing, software
775 * distributed under the License is distributed on an "AS IS" BASIS,
776 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
777 * See the License for the specific language governing permissions and
778 * limitations under the License.
779 */class Va{constructor(e){this.fields=e,e.sort(Ht.comparator)}static empty(){return new Va([])}unionWith(e){let a=new Bt(Ht.comparator);for(const n of this.fields)a=a.add(n);for(const n of e)a=a.add(n);return new Va(a.toArray())}covers(e){for(const a of this.fields)if(a.isPrefixOf(e))return!0;return!1}isEqual(e){return kl(this.fields,e.fields,(a,n)=>a.isEqual(n))}}/**
780 * @license
781 * Copyright 2023 Google LLC
782 *
783 * Licensed under the Apache License, Version 2.0 (the "License");
784 * you may not use this file except in compliance with the License.
785 * You may obtain a copy of the License at
786 *
787 *   http://www.apache.org/licenses/LICENSE-2.0
788 *
789 * Unless required by applicable law or agreed to in writing, software
790 * distributed under the License is distributed on an "AS IS" BASIS,
791 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
792 * See the License for the specific language governing permissions and
793 * limitations under the License.
794 */class aL extends Error{constructor(){super(...arguments),this.name="Base64DecodeError"}}/**
795 * @license
796 * Copyright 2020 Google LLC
797 *
798 * Licensed under the Apache License, Version 2.0 (the "License");
799 * you may not use this file except in compliance with the License.
800 * You may obtain a copy of the License at
801 *
802 *   http://www.apache.org/licenses/LICENSE-2.0
803 *
804 * Unless required by applicable law or agreed to in writing, software
805 * distributed under the License is distributed on an "AS IS" BASIS,
806 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
807 * See the License for the specific language governing permissions and
808 * limitations under the License.
809 */class $t{constructor(e){this.binaryString=e}static fromBase64String(e){const a=function(i){try{return atob(i)}catch(r){throw typeof DOMException<"u"&&r instanceof DOMException?new aL("Invalid base64 string: "+r):r}}(e);return new $t(a)}static fromUint8Array(e){const a=function(i){let r="";for(let o=0;o<i.length;++o)r+=String.fromCharCode(i[o]);return r}(e);return new $t(a)}[Symbol.iterator](){let e=0;return{next:()=>e<this.binaryString.length?{value:this.binaryString.charCodeAt(e++),done:!1}:{value:void 0,done:!0}}}toBase64(){return function(a){return btoa(a)}(this.binaryString)}toUint8Array(){return function(a){const n=new Uint8Array(a.length);for(let i=0;i<a.length;i++)n[i]=a.charCodeAt(i);return n}(this.binaryString)}approximateByteSize(){return 2*this.binaryString.length}compareTo(e){return je(this.binaryString,e.binaryString)}isEqual(e){return this.binaryString===e.binaryString}}$t.EMPTY_BYTE_STRING=new $t("");const qW=new RegExp(/^\d{4}-\d\d-\d\dT\d\d:\d\d:\d\d(?:\.(\d+))?Z$/);function Fr(t){if(Oe(!!t),typeof t=="string"){let e=0;const a=qW.exec(t);if(Oe(!!a),a[1]){let i=a[1];i=(i+"000000000").substr(0,9),e=Number(i)}const n=new Date(t);return{seconds:Math.floor(n.getTime()/1e3),nanos:e}}return{seconds:ut(t.seconds),nanos:ut(t.nanos)}}function ut(t){return typeof t=="number"?t:typeof t=="string"?Number(t):0}function Qo(t){return typeof t=="string"?$t.fromBase64String(t):$t.fromUint8Array(t)}/**
810 * @license
811 * Copyright 2020 Google LLC
812 *
813 * Licensed under the Apache License, Version 2.0 (the "License");
814 * you may not use this file except in compliance with the License.
815 * You may obtain a copy of the License at
816 *
817 *   http://www.apache.org/licenses/LICENSE-2.0
818 *
819 * Unless required by applicable law or agreed to in writing, softw
819are
820 * distributed under the License is distributed on an "AS IS" BASIS,
821 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
822 * See the License for the specific language governing permissions and
823 * limitations under the License.
824 */function Bw(t){var e,a;return((a=(((e=t==null?void 0:t.mapValue)===null||e===void 0?void 0:e.fields)||{}).__type__)===null||a===void 0?void 0:a.stringValue)==="server_timestamp"}function Uw(t){const e=t.mapValue.fields.__previous_value__;return Bw(e)?Uw(e):e}function nu(t){const e=Fr(t.mapValue.fields.__local_write_time__.timestampValue);return new xt(e.seconds,e.nanos)}/**
825 * @license
826 * Copyright 2017 Google LLC
827 *
828 * Licensed under the Apache License, Version 2.0 (the "License");
829 * you may not use this file except in compliance with the License.
830 * You may obtain a copy of the License at
831 *
832 *   http://www.apache.org/licenses/LICENSE-2.0
833 *
834 * Unless required by applicable law or agreed to in writing, software
835 * distributed under the License is distributed on an "AS IS" BASIS,
836 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
837 * See the License for the specific language governing permissions and
838 * limitations under the License.
839 */class zW{constructor(e,a,n,i,r,o,l,c,d){this.databaseId=e,this.appId=a,this.persistenceKey=n,this.host=i,this.ssl=r,this.forceLongPolling=o,this.autoDetectLongPolling=l,this.longPollingOptions=c,this.useFetchStreams=d}}class iu{constructor(e,a){this.projectId=e,this.database=a||"(default)"}static empty(){return new iu("","")}get isDefaultDatabase(){return this.database==="(default)"}isEqual(e){return e instanceof iu&&e.projectId===this.projectId&&e.database===this.database}}/**
840 * @license
841 * Copyright 2020 Google LLC
842 *
843 * Licensed under the Apache License, Version 2.0 (the "License");
844 * you may not use this file except in compliance with the License.
845 * You may obtain a copy of the License at
846 *
847 *   http://www.apache.org/licenses/LICENSE-2.0
848 *
849 * Unless required by applicable law or agreed to in writing, software
850 * distributed under the License is distributed on an "AS IS" BASIS,
851 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
852 * See the License for the specific language governing permissions and
853 * limitations under the License.
854 */const Fp={mapValue:{}};function Xo(t){return"nullValue"in t?0:"booleanValue"in t?1:"integerValue"in t||"doubleValue"in t?2:"timestampValue"in t?3:"stringValue"in t?5:"bytesValue"in t?6:"referenceValue"in t?7:"geoPointValue"in t?8:"arrayValue"in t?9:"mapValue"in t?Bw(t)?4:HW(t)?9007199254740991:VW(t)?10:11:pe()}function ni(t,e){if(t===e)return!0;const a=Xo(t);if(a!==Xo(e))return!1;switch(a){case 0:case 9007199254740991:return!0;case 1:return t.booleanValue===e.booleanValue;case 4:return nu(t).isEqual(nu(e));case 3:return function(i,r){if(typeof i.timestampValue=="string"&&typeof r.timestampValue=="string"&&i.timestampValue.length===r.timestampValue.length)return i.timestampValue===r.timestampValue;const o=Fr(i.timestampValue),l=Fr(r.timestampValue);return o.seconds===l.seconds&&o.nanos===l.nanos}(t,e);case 5:return t.stringValue===e.stringValue;case 6:return function(i,r){return Qo(i.bytesValue).isEqual(Qo(r.bytesValue))}(t,e);case 7:return t.referenceValue===e.referenceValue;case 8:return function(i,r){return ut(i.geoPointValue.latitude)===ut(r.geoPointValue.latitude)&&ut(i.geoPointValue.longitude)===ut(r.geoPointValue.longitude)}(t,e);case 2:return function(i,r){if("integerValue"in i&&"integerValue"in r)return ut(i.integerValue)===ut(r.integerValue);if("doubleValue"in i&&"doubleValue"in r){const o=ut(i.doubleValue),l=ut(r.doubleValue);return o===l?Nh(o)===Nh(l):isNaN(o)&&isNaN(l)}return!1}(t,e);case 9:return kl(t.arrayValue.values||[],e.arrayValue.values||[],ni);case 10:case 11:return function(i,r){const o=i.mapValue.fields||{},l=r.mapValue.fields||{};if(XE(o)!==XE(l))return!1;for(const c in o)if(o.hasOwnProperty(c)&&(l[c]===void 0||!ni(o[c],l[c])))return!1;return!0}(t,e);default:return pe()}}function ru(t,e){return(t.values||[]).find(a=>ni(a,e))!==void 0}function Sl(t,e){if(t===e)return 0;const a=Xo(t),n=Xo(e);if(a!==n)return je(a,n);switch(a){case 0:case 9007199254740991:return 0;case 1:return je(t.booleanValue,e.booleanValue);case 2:return function(r,o){const l=ut(r.integerValue||r.doubleValue),c=ut(o.integerValue||o.doubleValue);return l<c?-1:l>c?1:l===c?0:isNaN(l)?isNaN(c)?0:-1:1}(t,e);
854case 3:return ZE(t.timestampValue,e.timestampValue);case 4:return ZE(nu(t),nu(e));case 5:return je(t.stringValue,e.stringValue);case 6:return function(r,o){const l=Qo(r),c=Qo(o);return l.compareTo(c)}(t.bytesValue,e.bytesValue);case 7:return function(r,o){const l=r.split("/"),c=o.split("/");for(let d=0;d<l.length&&d<c.length;d++){const u=je(l[d],c[d]);if(u!==0)return u}return je(l.length,c.length)}(t.referenceValue,e.referenceValue);case 8:return function(r,o){const l=je(ut(r.latitude),ut(o.latitude));return l!==0?l:je(ut(r.longitude),ut(o.longitude))}(t.geoPointValue,e.geoPointValue);case 9:return eC(t.arrayValue,e.arrayValue);case 10:return function(r,o){var l,c,d,u;const p=r.fields||{},m=o.fields||{},h=(l=p.value)===null||l===void 0?void 0:l.arrayValue,g=(c=m.value)===null||c===void 0?void 0:c.arrayValue,y=je(((d=h==null?void 0:h.values)===null||d===void 0?void 0:d.length)||0,((u=g==null?void 0:g.values)===null||u===void 0?void 0:u.length)||0);return y!==0?y:eC(h,g)}(t.mapValue,e.mapValue);case 11:return function(r,o){if(r===Fp.mapValue&&o===Fp.mapValue)return 0;if(r===Fp.mapValue)return 1;if(o===Fp.mapValue)return-1;const l=r.fields||{},c=Object.keys(l),d=o.fields||{},u=Object.keys(d);c.sort(),u.sort();for(let p=0;p<c.length&&p<u.length;++p){const m=je(c[p],u[p]);if(m!==0)return m;const h=Sl(l[c[p]],d[u[p]]);if(h!==0)return h}return je(c.length,u.length)}(t.mapValue,e.mapValue);default:throw pe()}}function ZE(t,e){if(typeof t=="string"&&typeof e=="string"&&t.length===e.length)return je(t,e);const a=Fr(t),n=Fr(e),i=je(a.seconds,n.seconds);return i!==0?i:je(a.nanos,n.nanos)}function eC(t,e){const a=t.values||[],n=e.values||[];for(let i=0;i<a.length&&i<n.length;++i){const r=Sl(a[i],n[i]);if(r)return r}return je(a.length,n.length)}function _l(t){return Zv(t)}function Zv(t){return"nullValue"in t?"null":"booleanValue"in t?""+t.booleanValue:"integerValue"in t?""+t.integerValue:"doubleValue"in t?""+t.doubleValue:"timestampValue"in t?function(a){const n=Fr(a);return`time(${n.seconds},${n.nanos})`}(t.timestampValue):"stringValue"in t?t.stringValue:"bytesValue"in t?function(a){return Qo(a).toBase64()}(t.bytesValue):"referenceValue"in t?function(a){return oe.fromName(a).toString()}(t.referenceValue):"geoPointValue"in t?function(a){return`geo(${a.latitude},${a.longitude})`}(t.geoPointValue):"arrayValue"in t?function(a){let n="[",i=!0;for(const r of a.values||[])i?i=!1:n+=",",n+=Zv(r);return n+"]"}(t.arrayValue):"mapValue"in t?function(a){const n=Object.keys(a.fields||{}).sort();let i="{",r=!0;for(const o of n)r?r=!1:i+=",",i+=`${o}:${Zv(a.fields[o])}`;return i+"}"}(t.mapValue):pe()}function tC(t,e){return{referenceValue:`projects/${t.projectId}/databases/${t.database}/documents/${e.path.canonicalString()}`}}function eb(t){return!!t&&"integerValue"in t}function $w(t){return!!t&&"arrayValue"in t}function aC(t){return!!t&&"nullValue"in t}function nC(t){return!!t&&"doubleValue"in t&&isNaN(Number(t.doubleValue))}function Lm(t){return!!t&&"mapValue"in t}function VW(t){var e,a;return((a=(((e=t==null?void 0:t.mapValue)===null||e===void 0?void 0:e.fields)||{}).__type__)===null||a===void 0?void 0:a.stringValue)==="__vector__"}function ud(t){if(t.geoPointValue)return{geoPointValue:Object.assign({},t.geoPointValue)};if(t.timestampValue&&typeof t.timestampValue=="object")return{timestampValue:Object.assign({},t.timestampValue)};if(t.mapValue){const e={mapValue:{fields:{}}};return ps(t.mapValue.fields,(a,n)=>e.mapValue.fields[a]=ud(n)),e}if(t.arrayValue){const e={arrayValue:{values:[]}};for(let a=0;a<(t.arrayValue.values||[]).length;++a)e.arrayValue.values[a]=ud(t.arrayValue.values[a]);return e}return Object.assign({},t)}function HW(t){return(((t.mapValue||{}).fields||{}).__type__||{}).stringValue==="__max__"}/**
855 * @license
856 * Copyright 2017 Google LLC
857 *
858 * Licensed under the Apache License, Version 2.0 (the "License");
859 * you may not use this file except in compliance with the License.
860 * You may obtain a copy of the License at
861 *
862 *   http://www.apache.org/licenses/LICENSE-2.0
863 *
864 * Unless required by applicable law or agreed to in writing, softw
864are
865 * distributed under the License is distributed on an "AS IS" BASIS,
866 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
867 * See the License for the specific language governing permissions and
868 * limitations under the License.
869 */class _a{constructor(e){this.value=e}static empty(){return new _a({mapValue:{}})}field(e){if(e.isEmpty())return this.value;{let a=this.value;for(let n=0;n<e.length-1;++n)if(a=(a.mapValue.fields||{})[e.get(n)],!Lm(a))return null;return a=(a.mapValue.fields||{})[e.lastSegment()],a||null}}set(e,a){this.getFieldsMap(e.popLast())[e.lastSegment()]=ud(a)}setAll(e){let a=Ht.emptyPath(),n={},i=[];e.forEach((o,l)=>{if(!a.isImmediateParentOf(l)){const c=this.getFieldsMap(a);this.applyChanges(c,n,i),n={},i=[],a=l.popLast()}o?n[l.lastSegment()]=ud(o):i.push(l.lastSegment())});const r=this.getFieldsMap(a);this.applyChanges(r,n,i)}delete(e){const a=this.field(e.popLast());Lm(a)&&a.mapValue.fields&&delete a.mapValue.fields[e.lastSegment()]}isEqual(e){return ni(this.value,e.value)}getFieldsMap(e){let a=this.value;a.mapValue.fields||(a.mapValue={fields:{}});for(let n=0;n<e.length;++n){let i=a.mapValue.fields[e.get(n)];Lm(i)&&i.mapValue.fields||(i={mapValue:{fields:{}}},a.mapValue.fields[e.get(n)]=i),a=i}return a.mapValue.fields}applyChanges(e,a,n){ps(a,(i,r)=>e[i]=r);for(const i of n)delete e[i]}clone(){return new _a(ud(this.value))}}function nL(t){const e=[];return ps(t.fields,(a,n)=>{const i=new Ht([a]);if(Lm(n)){const r=nL(n.mapValue).fields;
vendor: 4,180 bytes, lines 869-909
869if(r.length===0)e.push(i);else for(const o of r)e.push(i.child(o))}else e.push(i)}),new Va(e)}/**
870 * @license
871 * Copyright 2017 Google LLC
872 *
873 * Licensed under the Apache License, Version 2.0 (the "License");
874 * you may not use this file except in compliance with the License.
875 * You may obtain a copy of the License at
876 *
877 *   http://www.apache.org/licenses/LICENSE-2.0
878 *
879 * Unless required by applicable law or agreed to in writing, software
880 * distributed under the License is distributed on an "AS IS" BASIS,
881 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
882 * See the License for the specific language governing permissions and
883 * limitations under the License.
884 */class aa{constructor(e,a,n,i,r,o,l){this.key=e,this.documentType=a,this.version=n,this.readTime=i,this.createTime=r,this.data=o,this.documentState=l}static newInvalidDocument(e){return new aa(e,0,me.min(),me.min(),me.min(),_a.empty(),0)}static newFoundDocument(e,a,n,i){return new aa(e,1,a,me.min(),n,i,0)}static newNoDocument(e,a){return new aa(e,2,a,me.min(),me.min(),_a.empty(),0)}static newUnknownDocument(e,a){return new aa(e,3,a,me.min(),me.min(),_a.empty(),2)}convertToFoundDocument(e,a){return!this.createTime.isEqual(me.min())||this.documentType!==2&&this.documentType!==0||(this.createTime=e),this.version=e,this.documentType=1,this.data=a,this.documentState=0,this}convertToNoDocument(e){return this.version=e,this.documentType=2,this.data=_a.empty(),this.documentState=0,this}convertToUnknownDocument(e){return this.version=e,this.documentType=3,this.data=_a.empty(),this.documentState=2,this}setHasCommittedMutations(){return this.documentState=2,this}setHasLocalMutations(){return this.documentState=1,this.version=me.min(),this}setReadTime(e){return this.readTime=e,this}get hasLocalMutations(){return this.documentState===1}get hasCommittedMutations(){return this.documentState===2}get hasPendingWrites(){return this.hasLocalMutations||this.hasCommittedMutations}isValidDocument(){return this.documentType!==0}isFoundDocument(){return this.documentType===1}isNoDocument(){return this.documentType===2}isUnknownDocument(){return this.documentType===3}isEqual(e){return e instanceof aa&&this.key.isEqual(e.key)&&this.version.isEqual(e.version)&&this.documentType===e.documentType&&this.documentState===e.documentState&&this.data.isEqual(e.data)}mutableCopy(){return new aa(this.key,this.documentType,this.version,this.readTime,this.createTime,this.data.clone(),this.documentState)}toString(){return`Document(${this.key}, ${this.version}, ${JSON.stringify(this.data.value)}, {createTime: ${this.createTime}}), {documentType: ${this.documentType}}), {documentState: ${this.documentState}})`}}/**
885 * @license
886 * Copyright 2022 Google LLC
887 *
888 * Licensed under the Apache License, Version 2.0 (the "License");
889 * you may not use this file except in compliance with the License.
890 * You may obtain a copy of the License at
891 *
892 *   http://www.apache.org/licenses/LICENSE-2.0
893 *
894 * Unless required by applicable law or agreed to in writing, software
895 * distributed under the License is distributed on an "AS IS" BASIS,
896 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
897 * See the License for the specific language governing permissions and
898 * limitations under the License.
899 */class Ih{constructor(e,a){this.position=e,this.inclusive=a}}function iC(t,e,a){let n=0;for(let i=0;i<t.position.length;i++){const r=e[i],o=t.position[i];if(r.field.isKeyField()?n=oe.comparator(oe.fromName(o.referenceValue),a.key):n=Sl(o,a.data.field(r.field)),r.dir==="desc"&&(n*=-1),n!==0)break}return n}function rC(t,e){if(t===null)return e===null;if(e===null||t.inclusive!==e.inclusive||t.position.length!==e.position.length)return!1;for(let a=0;a<t.position.length;a++)if(!ni(t.position[a],e.position[a]))return!1;return!0}/**
900 * @license
901 * Copyright 2022 Google LLC
902 *
903 * Licensed under the Apache License, Version 2.0 (the "License");
904 * you may not use this file except in compliance with the License.
905 * You may obtain a copy of the License at
906 *
907 *   http://www.apache.org/licenses/LICENSE-2.0
908 *
909 * Unless required by applicable law or agreed to in writing, softw
909are
910 * distributed under the License is distributed on an "AS IS" BASIS,
911 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
912 * See the License for the specific language governing permissions and
913 * limitations under the License.
914 */class Ph{constructor(e,a="asc"){this.field=e,this.dir=a}}function FW(t,e){return t.dir===e.dir&&t.field.isEqual(e.field)}/**
915 * @license
916 * Copyright 2022 Google LLC
917 *
918 * Licensed under the Apache License, Version 2.0 (the "License");
919 * you may not use this file except in compliance with the License.
920 * You may obtain a copy of the License at
921 *
922 *   http://www.apache.org/licenses/LICENSE-2.0
923 *
924 * Unless required by applicable law or agreed to in writing, software
925 * distributed under the License is distributed on an "AS IS" BASIS,
926 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
927 * See the License for the specific language governing permissions and
928 * limitations under the License.
929 */class iL{}class gt extends iL{constructor(e,a,n){super(),this.field=e,this.op=a,this.value=n}static create(e,a,n){return e.isKeyField()?a==="in"||a==="not-in"?this.createKeyFieldInFilter(e,a,n):new UW(e,a,n):a==="array-contains"?new GW(e,n):a==="in"?new KW(e,n):a==="not-in"?new JW(e,n):a==="array-contains-any"?new QW(e,n):new gt(e,a,n)}static createKeyFieldInFilter(e,a,n){return a==="in"?new $W(e,n):new WW(e,n)}matches(e){const a=e.data.field(this.field);return this.op==="!="?a!==null&&this.matchesComparison(Sl(a,this.value)):a!==null&&Xo(this.value)===Xo(a)&&this.matchesComparison(Sl(a,this.value))}matchesComparison(e){switch(this.op){case"<":return e<0;case"<=":return e<=0;case"==":return e===0;case"!=":return e!==0;case">":return e>0;case">=":return e>=0;default:return pe()}}isInequality(){return["<","<=",">",">=","!=","not-in"].indexOf(this.op)>=0}getFlattenedFilters(){return[this]}getFilters(){return[this]}}class qn extends iL{constructor(e,a){super(),this.filters=e,this.op=a,this.ae=null}static create(e,a){return new qn(e,a)}matches(e){return rL(this)?this.filters.find(a=>!a.matches(e))===void 0:this.filters.find(a=>a.matches(e))!==void 0}getFlattenedFilters(){return this.ae!==null||(this.ae=this.filters.reduce((e,a)=>e.concat(a.getFlattenedFilters()),[])),this.ae}getFilters(){return Object.assign([],this.filters)}}function rL(t){return t.op==="and"}function oL(t){return BW(t)&&rL(t)}function BW(t){for(const e of t.filters)if(e instanceof qn)return!1;return!0}function tb(t){if(t instanceof gt)return t.field.canonicalString()+t.op.toString()+_l(t.value);if(oL(t))return t.filters.map(e=>tb(e)).join(",");{const e=t.filters.map(a=>tb(a)).join(",");return`${t.op}(${e})`}}function sL(t,e){return t instanceof gt?function(n,i){return i instanceof gt&&n.op===i.op&&n.field.isEqual(i.field)&&ni(n.value,i.value)}(t,e):t instanceof qn?function(n,i){return i instanceof qn&&n.op===i.op&&n.filters.length===i.filters.length?n.filters.reduce((r,o,l)=>r&&sL(o,i.filters[l]),!0):!1}(t,e):void pe()}function lL(t){return t instanceof gt?function(a){return`${a.field.canonicalString()} ${a.op} ${_l(a.value)}`}(t):t instanceof qn?function(a){return a.op.toString()+" {"+a.getFilters().map(lL).join(" ,")+"}"}(t):"Filter"}class UW extends gt{constructor(e,a,n){super(e,a,n),this.key=oe.fromName(n.referenceValue)}matches(e){const a=oe.comparator(e.key,this.key);return this.matchesComparison(a)}}class $W extends gt{constructor(e,a){super(e,"in",a),this.keys=cL("in",a)}matches(e){return this.keys.some(a=>a.isEqual(e.key))}}class WW extends gt{constructor(e,a){super(e,"not-in",a),this.keys=cL("not-in",a)}matches(e){return!this.keys.some(a=>a.isEqual(e.key))}}function cL(t,e){var a;return(((a=e.arrayValue)===null||a===void 0?void 0:a.values)||[]).map(n=>oe.fromName(n.referenceValue))}class GW extends gt{constructor(e,a){super(e,"array-contains",a)}matches(e){const a=e.data.field(this.field);return $w(a)&&ru(a.arrayValue,this.value)}}class KW extends gt{constructor(e,a){super(e,"in",a)}matches(e){const a=e.data.field(this.field);return a!==null&&ru(this.value.arrayValue,a)}}class JW extends gt{constructor(e,a){super(e,"not-in",a)}matches(e){if(ru(this.value.arrayValue,{nullValue:"NULL_VALUE"}))return!1;const a=e.data.field(this.field);return a!==null&&!ru(this.value.arrayValue,a)}}class QW extends gt{constructor(e,a){super(e,"array-contains-any",a)}matches(e){const a=e.data.field(this.field);return!(!$w(a)||!a.arrayValue.values)&&a.arrayValue.values.some(n=>ru(this.value.arrayValue,n))}}/**
930 * @license
931 * Copyright 2019 Google LLC
932 *
933 * Licensed under the Apache License, Version 2.0 (the "License");
934 * you may not use this file except in compliance with the License.
935 * You may obtain a copy of the License at
936 *
937 *   http://www.apache.org/licenses/LICENSE-2.0
938 *
939 * Unless required by applicable law or agreed to in writing, software
940 * distributed under the License is distributed on an "AS IS" BASIS,
941 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
942 * See the License for the specific language governing permissions and
943 * limitations under the License.
944 */class XW{constructor(e,a=null,n=[],i=[],r=null,o=null,l=null){this.path=e,this.collectionGroup=a,this.orderBy=n,this.filters=i,this.limit=r,this.startAt=o,this.endAt=l,this.ue=null}}function oC(t,e=null,a=[],n=[],i=null,r=null,o=null){return new XW(t,e,a,n,i,r,o)}function Ww(t){const e=he(t);if(e.ue===null){let a=e.path.canonicalString();e.collectionGroup!==null&&(a+="|cg:"+e.collectionGroup),a+="|f:",a+=e.filters.map(n=>tb(n)).join(","),a+="|ob:",a+=e.orderBy.map(n=>function(r){return r.field.canonicalString()+r.dir}(n)).join(","),hg(e.limit)||(a+="|l:",a+=e.limit),e.startAt&&(a+="|lb:",a+=e.startAt.inclusive?"b:":"a:",a+=e.startAt.position.map(n=>_l(n)).join(",")),e.endAt&&(a+="|ub:",a+=e.endAt.inclusive?"a:":"b:",a+=e.endAt.position.map(n=>_l(n)).join(",")),e.ue=a}return e.ue}function Gw(t,e){if(t.limit!==e.limit||t.orderBy.length!==e.orderBy.length)return!1;for(let a=0;a<t.orderBy.length;a++)if(!FW(t.orderBy[a],e.orderBy[a]))return!1;if(t.filters.length!==e.filters.length)return!1;for(let a=0;a<t.filters.length;a++)if(!sL(t.filters[a],e.filters[a]))return!1;return t.collectionGroup===e.collectionGroup&&!!t.path.isEqual(e.path)&&!!rC(t.startAt,e.startAt)&&rC(t.endAt,e.endAt)}function ab(t){return oe.isDocumentKey(t.path)&&t.collectionGroup===null&&t.filters.length===0}/**
945 * @license
946 * Copyright 2017 Google LLC
947 *
948 * Licensed under the Apache License, Version 2.0 (the "License");
949 * you may not use this file except in compliance with the License.
950 * You may obtain a copy of the License at
951 *
952 *   http://www.apache.org/licenses/LICENSE-2.0
953 *
954 * Unless required by applicable law or agreed to in writing, software
955 * distributed under the License is distributed on an "AS IS" BASIS,
956 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
957 * See the License for the specific language governing permissions and
958 * limitations under the License.
959 */class Mu{constructor(e,a=null,n=[],i=[],r=null,o="F",l=null,c=null){this.path=e,this.collectionGroup=a,this.explicitOrderBy=n,this.filters=i,this.limit=r,this.limitType=o,this.startAt=l,this.endAt=c,this.ce=null,this.le=null,this.he=null,this.startAt,this.endAt}}function YW(t,e,a,n,i,r,o,l){return new Mu(t,e,a,n,i,r,o,l)}function Kw(t){return new Mu(t)}function sC(t){return t.filters.length===0&&t.limit===null&&t.startAt==null&&t.endAt==null&&(t.explicitOrderBy.length===0||t.explicitOrderBy.length===1&&t.explicitOrderBy[0].field.isKeyField())}function dL(t){return t.collectionGroup!==null}function pd(t){const e=he(t);if(e.ce===null){e.ce=[];const a=new Set;for(const r of e.explicitOrderBy)e.ce.push(r),a.add(r.field.canonicalString());const n=e.explicitOrderBy.length>0?e.explicitOrderBy[e.explicitOrderBy.length-1].dir:"asc";(function(o){let l=new Bt(Ht.comparator);return o.filters.forEach(c=>{c.getFlattenedFilters().forEach(d=>{d.isInequality()&&(l=l.add(d.field))})}),l})(e).forEach(r=>{a.has(r.canonicalString())||r.isKeyField()||e.ce.push(new Ph(r,n))}),a.has(Ht.keyField().canonicalString())||e.ce.push(new Ph(Ht.keyField(),n))}return e.ce}function ei(t){const e=he(t);return e.le||(e.le=ZW(e,pd(t))),e.le}function ZW(t,e){if(t.limitType==="F")return oC(t.path,t.collectionGroup,e,t.filters,t.limit,t.startAt,t.endAt);{e=e.map(i=>{const r=i.dir==="desc"?"asc":"desc";return new Ph(i.field,r)});const a=t.endAt?new Ih(t.endAt.position,t.endAt.inclusive):null,n=t.startAt?new Ih(t.startAt.position,t.startAt.inclusive):null;return oC(t.path,t.collectionGroup,e,t.filters,t.limit,a,n)}}function nb(t,e){const a=t.filters.concat([e]);return new Mu(t.path,t.collectionGroup,t.explicitOrderBy.slice(),a,t.limit,t.limitType,t.startAt,t.endAt)}function ib(t,e,a){return new Mu(t.path,t.collectionGroup,t.explicitOrderBy.slice(),t.filters.slice(),e,a,t.startAt,t.endAt)}function fg(t,e){return Gw(ei(t),ei(e))&&t.limitType===e.limitType}function uL(t){return`${Ww(ei(t))}|lt:${t.limitType}`}function Cs(t){return`Query(target=${function(a){let n=a.path.canonicalString();return a.collectionGroup!==null&&(n+=" collectionGroup="+a.collectionGroup),a.filters.length>0&&(n+=`, filters: [${a.filters.map(i=>lL(i)).join(", ")}]`),hg(a.limit)||(n+=", limit: "+a.limit),a.orderBy.length>0&&(n+=`, orderBy: [${a.orderBy.map(i=>function(o){return`${o.field.canonicalString()} (${o.dir})`}(i)).join(", ")}]`),a.startAt&&(n+=", startAt: ",n+=a.startAt.inclusive?"b:":"a:",n+=a.startAt.position.map(i=>_l(i)).join(",")),a.endAt&&(n+=", endAt: ",n+=a.endAt.inclusive?"a:":"b:",n+=a.endAt.position.map(i=>_l(i)).join(",")),`Target(${n})`}(ei(t))}; limitType=${t.limitType})`}function gg(t,e){return e.isFoundDocument()&&function(n,i){const r=i.key.path;return n.collectionGroup!==null?i.key.hasCollectionId(n.collectionGroup)&&n.path.isPrefixOf(r):oe.isDocumentKey(n.path)?n.path.isEqual(r):n.path.isImmediateParentOf(r)}(t,e)&&function(n,i){for(const r of pd(n))if(!r.field.isKeyField()&&i.data.field(r.field)===null)return!1;return!0}(t,e)&&function(n,i){for(const r of n.filters)if(!r.matches(i))return!1;return!0}(t,e)&&function(n,i){return!(n.startAt&&!function(o,l,c){const d=iC(o,l,c);return o.inclusive?d<=0:d<0}(n.startAt,pd(n),i)||n.endAt&&!function(o,l,c){const d=iC(o,l,c);return o.inclusive?d>=0:d>0}(n.endAt,pd(n),i))}(t,e)}function eG(t){return t.collectionGroup||(t.path.length%2==1?t.path.lastSegment():t.path.get(t.path.length-2))}function pL(t){return(e,a)=>{let n=!1;for(const i of pd(t)){const r=tG(i,e,a);if(r!==0)return r;n=n||i.field.isKeyField()}return 0}}function tG(t,e,a){const n=t.field.isKeyField()?oe.comparator(e.key,a.key):function(r,o,l){const c=o.data.field(r),d=l.data.field(r);return c!==null&&d!==null?Sl(c,d):pe()}(t.field,e,a);switch(t.dir){case"asc":return n;
959case"desc":return-1*n;default:return pe()}}/**
960 * @license
961 * Copyright 2017 Google LLC
962 *
963 * Licensed under the Apache License, Version 2.0 (the "License");
964 * you may not use this file except in compliance with the License.
965 * You may obtain a copy of the License at
966 *
967 *   http://www.apache.org/licenses/LICENSE-2.0
968 *
969 * Unless required by applicable law or agreed to in writing, software
970 * distributed under the License is distributed on an "AS IS" BASIS,
971 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
972 * See the License for the specific language governing permissions and
973 * limitations under the License.
974 */class Kl{constructor(e,a){this.mapKeyFn=e,this.equalsFn=a,this.inner={},this.innerSize=0}get(e){const a=this.mapKeyFn(e),n=this.inner[a];if(n!==void 0){for(const[i,r]of n)if(this.equalsFn(i,e))return r}}has(e){return this.get(e)!==void 0}set(e,a){const n=this.mapKeyFn(e),i=this.inner[n];if(i===void 0)return this.inner[n]=[[e,a]],void this.innerSize++;for(let r=0;r<i.length;r++)if(this.equalsFn(i[r][0],e))return void(i[r]=[e,a]);i.push([e,a]),this.innerSize++}delete(e){const a=this.mapKeyFn(e),n=this.inner[a];if(n===void 0)return!1;for(let i=0;i<n.length;i++)if(this.equalsFn(n[i][0],e))return n.length===1?delete this.inner[a]:n.splice(i,1),this.innerSize--,!0;return!1}forEach(e){ps(this.inner,(a,n)=>{for(const[i,r]of n)e(i,r)})}isEmpty(){return tL(this.inner)}size(){return this.innerSize}}/**
975 * @license
976 * Copyright 2017 Google LLC
977 *
978 * Licensed under the Apache License, Version 2.0 (the "License");
979 * you may not use this file except in compliance with the License.
980 * You may obtain a copy of the License at
981 *
982 *   http://www.apache.org/licenses/LICENSE-2.0
983 *
984 * Unless required by applicable law or agreed to in writing, software
985 * distributed under the License is distributed on an "AS IS" BASIS,
986 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
987 * See the License for the specific language governing permissions and
988 * limitations under the License.
989 */const aG=new tt(oe.comparator);function Hi(){return aG}const mL=new tt(oe.comparator);function Hc(...t){let e=mL;for(const a of t)e=e.insert(a.key,a);return e}function hL(t){let e=mL;return t.forEach((a,n)=>e=e.insert(a,n.overlayedDocument)),e}function So(){return md()}function fL(){return md()}function md(){return new Kl(t=>t.toString(),(t,e)=>t.isEqual(e))}const nG=new tt(oe.comparator),iG=new Bt(oe.comparator);function Se(...t){let e=iG;for(const a of t)e=e.add(a);return e}const rG=new Bt(je);function oG(){return rG}/**
990 * @license
991 * Copyright 2020 Google LLC
992 *
993 * Licensed under the Apache License, Version 2.0 (the "License");
994 * you may not use this file except in compliance with the License.
995 * You may obtain a copy of the License at
996 *
997 *   http://www.apache.org/licenses/LICENSE-2.0
998 *
999 * Unless required by applicable law or agreed to in writing, software
1000 * distributed under the License is distributed on an "AS IS" BASIS,
1001 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
1002 * See the License for the specific language governing permissions and
1003 * limitations under the License.
1004 */function Jw(t,e){if(t.useProto3Json){if(isNaN(e))return{doubleValue:"NaN"};if(e===1/0)return{doubleValue:"Infinity"};if(e===-1/0)return{doubleValue:"-Infinity"}}return{doubleValue:Nh(e)?"-0":e}}function gL(t){return{integerValue:""+t}}function sG(t,e){return DW(e)?gL(e):Jw(t,e)}/**
1005 * @license
1006 * Copyright 2018 Google LLC
1007 *
1008 * Licensed under the Apache License, Version 2.0 (the "License");
1009 * you may not use this file except in compliance with the License.
1010 * You may obtain a copy of the License at
1011 *
1012 *   http://www.apache.org/licenses/LICENSE-2.0
1013 *
1014 * Unless required by applicable law or agreed to in writing, software
1015 * distributed under the License is distributed on an "AS IS" BASIS,
1016 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
1017 * See the License for the specific language governing permissions and
1018 * limitations under the License.
1019 */class yg{constructor(){this._=void 0}}function lG(t,e,a){return t instanceof Rh?function(i,r){const o={fields:{__type__:{stringValue:"server_timestamp"},__local_write_time__:{timestampValue:{seconds:i.seconds,nanos:i.nanoseconds}}}};return r&&Bw(r)&&(r=Uw(r)),r&&(o.fields.__previous_value__=r),{mapValue:o}}(a,e):t instanceof ou?xL(t,e):t instanceof su?vL(t,e):function(i,r){const o=yL(i,r),l=lC(o)+lC(i.Pe);return eb(o)&&eb(i.Pe)?gL(l):Jw(i.serializer,l)}(t,e)}function cG(t,e,a){return t instanceof ou?xL(t,e):t instanceof su?vL(t,e):a}function yL(t,e){return t instanceof Lh?function(n){return eb(n)||function(r){return!!r&&"doubleValue"in r}(n)}(e)?e:{integerValue:0}:null}class Rh extends yg{}class ou extends yg{constructor(e){super(),this.elements=e}}function xL(t,e){const a=bL(e);for(const n of t.elements)a.some(i=>ni(i,n))||a.push(n);return{arrayValue:{values:a}}}class su extends yg{constructor(e){super(),this.elements=e}}function vL(t,e){let a=bL(e);for(const n of t.elements)a=a.filter(i=>!ni(i,n));return{arrayValue:{values:a}}}
1019class Lh extends yg{constructor(e,a){super(),this.serializer=e,this.Pe=a}}function lC(t){return ut(t.integerValue||t.doubleValue)}function bL(t){return $w(t)&&t.arrayValue.values?t.arrayValue.values.slice():[]}function dG(t,e){return t.field.isEqual(e.field)&&function(n,i){return n instanceof ou&&i instanceof ou||n instanceof su&&i instanceof su?kl(n.elements,i.elements,ni):n instanceof Lh&&i instanceof Lh?ni(n.Pe,i.Pe):n instanceof Rh&&i instanceof Rh}(t.transform,e.transform)}class uG{constructor(e,a){this.version=e,this.transformResults=a}}class In{constructor(e,a){this.updateTime=e,this.exists=a}static none(){return new In}static exists(e){return new In(void 0,e)}static updateTime(e){return new In(e)}get isNone(){return this.updateTime===void 0&&this.exists===void 0}isEqual(e){return this.exists===e.exists&&(this.updateTime?!!e.updateTime&&this.updateTime.isEqual(e.updateTime):!e.updateTime)}}function Om(t,e){return t.updateTime!==void 0?e.isFoundDocument()&&e.version.isEqual(t.updateTime):t.exists===void 0||t.exists===e.isFoundDocument()}class xg{}function wL(t,e){if(!t.hasLocalMutations||e&&e.fields.length===0)return null;if(e===null)return t.isNoDocument()?new Qw(t.key,In.none()):new Du(t.key,t.data,In.none());{const a=t.data,n=_a.empty();let i=new Bt(Ht.comparator);for(let r of e.fields)if(!i.has(r)){let o=a.field(r);o===null&&r.length>1&&(r=r.popLast(),o=a.field(r)),o===null?n.delete(r):n.set(r,o),i=i.add(r)}return new Xr(t.key,n,new Va(i.toArray()),In.none())}}function pG(t,e,a){t instanceof Du?function(i,r,o){const l=i.value.clone(),c=dC(i.fieldTransforms,r,o.transformResults);l.setAll(c),r.convertToFoundDocument(o.version,l).setHasCommittedMutations()}(t,e,a):t instanceof Xr?function(i,r,o){if(!Om(i.precondition,r))return void r.convertToUnknownDocument(o.version);const l=dC(i.fieldTransforms,r,o.transformResults),c=r.data;c.setAll(kL(i)),c.setAll(l),r.convertToFoundDocument(o.version,c).setHasCommittedMutations()}(t,e,a):function(i,r,o){r.convertToNoDocument(o.version).setHasCommittedMutations()}(0,e,a)}function hd(t,e,a,n){return t instanceof Du?function(r,o,l,c){if(!Om(r.precondition,o))return l;const d=r.value.clone(),u=uC(r.fieldTransforms,c,o);return d.setAll(u),o.convertToFoundDocument(o.version,d).setHasLocalMutations(),null}(t,e,a,n):t instanceof Xr?function(r,o,l,c){if(!Om(r.precondition,o))return l;const d=uC(r.fieldTransforms,c,o),u=o.data;return u.setAll(kL(r)),u.setAll(d),o.convertToFoundDocument(o.version,u).setHasLocalMutations(),l===null?null:l.unionWith(r.fieldMask.fields).unionWith(r.fieldTransforms.map(p=>p.field))}(t,e,a,n):function(r,o,l){return Om(r.precondition,o)?(o.convertToNoDocument(o.version).setHasLocalMutations(),null):l}(t,e,a)}function mG(t,e){let a=null;for(const n of t.fieldTransforms){const i=e.data.field(n.field),r=yL(n.transform,i||null);r!=null&&(a===null&&(a=_a.empty()),a.set(n.field,r))}return a||null}function cC(t,e){return t.type===e.type&&!!t.key.isEqual(e.key)&&!!t.precondition.isEqual(e.precondition)&&!!function(n,i){return n===void 0&&i===void 0||!(!n||!i)&&kl(n,i,(r,o)=>dG(r,o))}(t.fieldTransforms,e.fieldTransforms)&&(t.type===0?t.value.isEqual(e.value):t.type!==1||t.data.isEqual(e.data)&&t.fieldMask.isEqual(e.fieldMask))}class Du extends xg{constructor(e,a,n,i=[]){super(),this.key=e,this.value=a,this.prec
1019ondition=n,this.fieldTransforms=i,this.type=0}getFieldMask(){return null}}class Xr extends xg{constructor(e,a,n,i,r=[]){super(),this.key=e,this.data=a,this.fieldMask=n,this.precondition=i,this.fieldTransforms=r,this.type=1}getFieldMask(){return this.fieldMask}}function kL(t){const e=new Map;return t.fieldMask.fields.forEach(a=>{if(!a.isEmpty()){const n=t.data.field(a);e.set(a,n)}}),e}function dC(t,e,a){const n=new Map;Oe(t.length===a.length);for(let i=0;i<a.length;i++){const r=t[i],o=r.transform,l=e.data.field(r.field);n.set(r.field,cG(o,l,a[i]))}return n}function uC(t,e,a){const n=new Map;for(const i of t){const r=i.transform,o=a.data.field(i.field);n.set(i.field,lG(r,o,e))}return n}class Qw extends xg{constructor(e,a){super(),this.key=e,this.precondition=a,this.type=2,this.fieldTransforms=[]}getFieldMask(){return null}}class hG extends xg{constructor(e,a){super(),this.key=e,this.precondition=a,this.type=3,this.fieldTransforms=[]}getFieldMask(){return null}}/**
1020 * @license
1021 * Copyright 2017 Google LLC
1022 *
1023 * Licensed under the Apache License, Version 2.0 (the "License");
1024 * you may not use this file except in compliance with the License.
1025 * You may obtain a copy of the License at
1026 *
1027 *   http://www.apache.org/licenses/LICENSE-2.0
1028 *
1029 * Unless required by applicable law or agreed to in writing, software
1030 * distributed under the License is distributed on an "AS IS" BASIS,
1031 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
1032 * See the License for the specific language governing permissions and
1033 * limitations under the License.
1034 */class fG{constructor(e,a,n,i){this.batchId=e,this.localWriteTime=a,this.baseMutations=n,this.mutations=i}applyToRemoteDocument(e,a){const n=a.mutationResults;for(let i=0;i<this.mutations.length;i++){const r=this.mutations[i];r.key.isEqual(e.key)&&pG(r,e,n[i])}}applyToLocalView(e,a){for(const n of this.baseMutations)n.key.isEqual(e.key)&&(a=hd(n,e,a,this.localWriteTime));for(const n of this.mutations)n.key.isEqual(e.key)&&(a=hd(n,e,a,this.localWriteTime));return a}applyToLocalDocumentSet(e,a){const n=fL();return this.mutations.forEach(i=>{const r=e.get(i.key),o=r.overlayedDocument;let l=this.applyToLocalView(o,r.mutatedFields);l=a.has(i.key)?null:l;const c=wL(o,l);c!==null&&n.set(i.key,c),o.isValidDocument()||o.convertToNoDocument(me.min())}),n}keys(){return this.mutations.reduce((e,a)=>e.add(a.key),Se())}isEqual(e){return this.batchId===e.batchId&&kl(this.mutations,e.mutations,(a,n)=>cC(a,n))&&kl(this.baseMutations,e.baseMutations,(a,n)=>cC(a,n))}}class Xw{constructor(e,a,n,i){this.batch=e,this.commitVersion=a,this.mutationResults=n,this.docVersions=i}static from(e,a,n){Oe(e.mutations.length===n.length);let i=function(){return nG}();const r=e.mutations;for(let o=0;o<r.length;o++)i=i.insert(r[o].key,n[o].version);return new Xw(e,a,n,i)}}/**
1035 * @license
1036 * Copyright 2022 Google LLC
1037 *
1038 * Licensed under the Apache License, Version 2.0 (the "License");
1039 * you may not use this file except in compliance with the License.
1040 * You may obtain a copy of the License at
1041 *
1042 *   http://www.apache.org/licenses/LICENSE-2.0
1043 *
1044 * Unless required by applicable law or agreed to in writing, software
1045 * distributed under the License is distributed on an "AS IS" BASIS,
1046 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
1047 * See the License for the specific language governing permissions and
1048 * limitations under the License.
1049 */class gG{constructor(e,a){this.largestBatchId=e,this.mutation=a}getKey(){return this.mutation.key}isEqual(e){return e!==null&&this.mutation===e.mutation}toString(){return`Overlay{
1050      largestBatchId: ${this.largestBatchId},
1051      mutation: ${this.mutation.toString()}
1052    }`}}/**
1053 * @license
1054 * Copyright 2017 Google LLC
1055 *
1056 * Licensed under the Apache License, Version 2.0 (the "License");
1057 * you may not use this file except in compliance with the License.
1058 * You may obtain a copy of the License at
1059 *
1060 *   http://www.apache.org/licenses/LICENSE-2.0
1061 *
1062 * Unless required by applicable law or agreed to in writing, software
1063 * distributed under the License is distributed on an "AS IS" BASIS,
1064 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
1065 * See the License for the specific language governing permissions and
1066 * limitations under the License.
1067 */class yG{constructor(e,a){this.count=e,this.unchangedNames=a}}/**
1068 * @license
1069 * Copyright 2017 Google LLC
1070 *
1071 * Licensed under the Apache License, Version 2.0 (the "License");
1072 * you may not use this file except in compliance with the License.
1073 * You may obtain a copy of the License at
1074 *
1075 *   http://www.apache.org/licenses/LICENSE-2.0
1076 *
1077 * Unless required by applicable law or agreed to in writing, software
1078 * distributed under the License is distributed on an "AS IS" BASIS,
1079 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
1080 * See the License for the specific language governing permissions and
1081 * limitations under the License.
1082 */var mt,Ae;function xG(t){switch(t){default:return pe();case z.CANCELLED:case z.UNKNOWN:case z.DEADLINE_EXCEEDED:case z.RESOURCE_EXHAUSTED:case z.INTERNAL:case z.UNAVAILABLE:case z.UNAUTHENTICATED:return!1;case z.INVALID_ARGUMENT:case z.NOT_FOUND:case z.ALREADY_EXISTS:case z.PERMISSION_DENIED:case z.FAILED_PRECONDITION:case z.ABORTED:case z.OUT_OF_RANGE:case z.UNIMPLEMENTED:case z.DATA_LOSS:return!0}}function SL(t){if(t===void 0)return Vi("GRPC error has no .code"),z.UNKNOWN;switch(t){case mt.OK:return z.OK;case mt.CANCELLED:return z.CANCELLED;case mt.UNKNOWN:return z.UNKNOWN;case mt.DEADLINE_EXCEEDED:return z.DEADLINE_EXCEEDED;case mt.RESOURCE_EXHAUSTED:return z.RESOURCE_EXHAUSTED;case mt.INTERNAL:return z.INTERNAL;case mt.UNAVAILABLE:return z.UNAVAILABLE;case mt.UNAUTHENTICATED:return z.UNAUTHENTICATED;case mt.INVALID_ARGUMENT:return z.INVALID_ARGUMENT;case mt.NOT_FOUND:return z.NOT_FOUND;case mt.ALREADY_EXISTS:return z.ALREADY_EXISTS;case mt.PERMISSION_DENIED:return z.PERMISSION_DENIED;case mt.FAILED_PRECONDITION:return z.FAILED_PRECONDITION;case mt.ABORTED:return z.ABORTED;case mt.OUT_OF_RANGE:return z.OUT_OF_RANGE;case mt.UNIMPLEMENTED:return z.UNIMPLEMENTED;case mt.DATA_LOSS:return z.DATA_LOSS;default:return pe()}}(Ae=mt||(mt={}))[Ae.OK=0]="OK",Ae[Ae.CANCELLED=1]="CANCELLED",Ae[Ae.UNKNOWN=2]="UNKNOWN",Ae[Ae.INVALID_ARGUMENT=3]="INVALID_ARGUMENT",Ae[Ae.DEADLINE_EXCEEDED=4]="DEADLINE_EXCEEDED",Ae[Ae.NOT_FOUND=5]="NOT_FOUND",Ae[Ae.ALREADY_EXISTS=6]="ALREADY_EXISTS",Ae[Ae.PERMISSION_DENIED=7]="PERMISSION_DENIED",Ae[Ae.UNAUTHENTICATED=16]="UNAUTHENTICATED",Ae[Ae.RESOURCE_EXHAUSTED=8]="RESOURCE_EXHAUSTED",Ae[Ae.FAILED_PRECONDITION=9]="FAILED_PRECONDITION",Ae[Ae.ABORTED=10]="ABORTED",Ae[Ae.OUT_OF_RANGE=11]="OUT_OF_RANGE",Ae[Ae.UNIMPLEMENTED=12]="UNIMPLEMENTED",Ae[Ae.INTERNAL=13]="INTERNAL",Ae[Ae.UNAVAILABLE=14]="UNAVAILABLE",Ae[Ae.DATA_LOSS=15]="DATA_LOSS";/**
1083 * @license
1084 * Copyright 2023 Google LLC
1085 *
1086 * Licensed under the Apache License, Version 2.0 (the "License");
1087 * you may not use this file except in compliance with the License.
1088 * You may obtain a copy of the License at
1089 *
1090 *   http://www.apache.org/licenses/LICENSE-2.0
1091 *
1092 * Unless required by applicable law or agreed to in writing, software
1093 * distributed under the License is distributed on an "AS IS" BASIS,
1094 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
1095 * See the License for the specific language governing permissions and
1096 * limitations under the License.
1097 */function vG(){return new TextEncoder}/**
1098 * @license
1099 * Copyright 2022 Google LLC
1100 *
1101 * Licensed under the Apache License, Version 2.0 (the "License");
1102 * you may not use this file except in compliance with the License.
1103 * You may obtain a copy of the License at
1104 *
1105 *   http://www.apache.org/licenses/LICENSE-2.0
1106 *
1107 * Unless required by applicable law or agreed to in writing, software
1108 * distributed under the License is distributed on an "AS IS" BASIS,
1109 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
1110 * See the License for the specific language governing permissions and
1111 * limitations under the License.
1112 */const bG=new Lo([4294967295,4294967295],0);function pC(t){const e=vG().encode(t),a=new GR;return a.update(e),new Uint8Array(a.digest())}function mC(t){const e=new DataView(t.buffer),a=e.getUint32(0,!0),n=e.getUint32(4,!0),i=e.getUint32(8,!0),r=e.getUint32(12,!0);return[new Lo([a,n],0),new Lo([i,r],0)]}class Yw{constructor(e,a,n){if(this.bitmap=e,this.padding=a,this.hashCount=n,a<0||a>=8)throw new Fc(`Invalid padding: ${a}`);if(n<0)throw new Fc(`Invalid hash count: ${n}`);if(e.length>0&&this.hashCount===0)throw new Fc(`Invalid hash count: ${n}`);if(e.length===0&&a!==0)throw new Fc(`Invalid padding when bitmap length is 0: ${a}`);this.Ie=8*e.length-a,this.Te=Lo.fromNumber(this.Ie)}Ee(e,a,n){let i=e.add(a.multiply(Lo.fromNumber(n)));return i.compare(bG)===1&&(i=new Lo([i.getBits(0),i.getBits(1)],0)),i.modulo(this.Te).toNumber()}de(e){return(this.bitmap[Math.floor(e/8)]&1<<e%8)!=0}mightContain(e){if(this.Ie===0)return!1;const a=pC(e),[n,i]=mC(a);for(let r=0;r<this.hashCount;r++){const o=this.Ee(n,i,r);if(!this.de(o))return!1}return!0}static create(e,a,n){const i=e%8==0?0:8-e%8,r=new Uint8Array(Math.ceil(e/8)),o=new Yw(r,i,a);return n.forEach(l=>o.insert(l)),o}insert(e){if(this.Ie===0)return;const a=pC(e),[n,i]=mC(a);for(let r=0;r<this.hashCount;r++){const o=this.Ee(n,i,r);this.Ae(o)}}Ae(e){const a=Math.floor(e/8),n=e%8;this.bitmap[a]|=1<<n}}
1112class Fc extends Error{constructor(){super(...arguments),this.name="BloomFilterError"}}/**
1113 * @license
1114 * Copyright 2017 Google LLC
1115 *
1116 * Licensed under the Apache License, Version 2.0 (the "License");
1117 * you may not use this file except in compliance with the License.
1118 * You may obtain a copy of the License at
1119 *
1120 *   http://www.apache.org/licenses/LICENSE-2.0
1121 *
1122 * Unless required by applicable law or agreed to in writing, software
1123 * distributed under the License is distributed on an "AS IS" BASIS,
1124 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
1125 * See the License for the specific language governing permissions and
1126 * limitations under the License.
1127 */class vg{constructor(e,a,n,i,r){this.snapshotVersion=e,this.targetChanges=a,this.targetMismatches=n,this.documentUpdates=i,this.resolvedLimboDocuments=r}static createSynthesizedRemoteEventForCurrentChange(e,a,n){const i=new Map;return i.set(e,qu.createSynthesizedTargetChangeForCurrentChange(e,a,n)),new vg(me.min(),i,new tt(je),Hi(),Se())}}class qu{constructor(e,a,n,i,r){this.resumeToken=e,this.current=a,this.addedDocuments=n,this.modifiedDocuments=i,this.removedDocuments=r}static createSynthesizedTargetChangeForCurrentChange(e,a,n){return new qu(n,a,Se(),Se(),Se())}}/**
1128 * @license
1129 * Copyright 2017 Google LLC
1130 *
1131 * Licensed under the Apache License, Version 2.0 (the "License");
1132 * you may not use this file except in compliance with the License.
1133 * You may obtain a copy of the License at
1134 *
1135 *   http://www.apache.org/licenses/LICENSE-2.0
1136 *
1137 * Unless required by applicable law or agreed to in writing, software
1138 * distributed under the License is distributed on an "AS IS" BASIS,
1139 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
1140 * See the License for the specific language governing permissions and
1141 * limitations under the License.
1142 */class Mm{constructor(e,a,n,i){this.Re=e,this.removedTargetIds=a,this.key=n,this.Ve=i}}class _L{constructor(e,a){this.targetId=e,this.me=a}}class AL{constructor(e,a,n=$t.EMPTY_BYTE_STRING,i=null){this.state=e,this.targetIds=a,this.resumeToken=n,this.cause=i}}class hC{constructor(){this.fe=0,this.ge=gC(),this.pe=$t.EMPTY_BYTE_STRING,this.ye=!1,this.we=!0}get current(){return this.ye}get resumeToken(){return this.pe}get Se(){return this.fe!==0}get be(){return this.we}De(e){e.approximateByteSize()>0&&(this.we=!0,this.pe=e)}ve(){let e=Se(),a=Se(),n=Se();return this.ge.forEach((i,r)=>{switch(r){case 0:e=e.add(i);break;case 2:a=a.add(i);break;case 1:n=n.add(i);break;default:pe()}}),new qu(this.pe,this.ye,e,a,n)}Ce(){this.we=!1,this.ge=gC()}Fe(e,a){this.we=!0,this.ge=this.ge.insert(e,a)}Me(e){this.we=!0,this.ge=this.ge.remove(e)}xe(){this.fe+=1}Oe(){this.fe-=1,Oe(this.fe>=0)}Ne(){this.we=!0,this.ye=!0}}class wG{constructor(e){this.Le=e,this.Be=new Map,this.ke=Hi(),this.qe=fC(),this.Qe=new tt(je)}Ke(e){for(const a of e.Re)e.Ve&&e.Ve.isFoundDocument()?this.$e(a,e.Ve):this.Ue(a,e.key,e.Ve);for(const a of e.removedTargetIds)this.Ue(a,e.key,e.Ve)}We(e){this.forEachTarget(e,a=>{const n=this.Ge(a);switch(e.state){case 0:this.ze(a)&&n.De(e.resumeToken);break;case 1:n.Oe(),n.Se||n.Ce(),n.De(e.resumeToken);break;case 2:n.Oe(),n.Se||this.removeTarget(a);break;case 3:this.ze(a)&&(n.Ne(),n.De(e.resumeToken));break;case 4:this.ze(a)&&(this.je(a),n.De(e.resumeToken));break;default:pe()}})}forEachTarget(e,a){e.targetIds.length>0?e.targetIds.forEach(a):this.Be.forEach((n,i)=>{this.ze(i)&&a(i)})}He(e){const a=e.targetId,n=e.me.count,i=this.Je(a);if(i){const r=i.target;if(ab(r))if(n===0){const o=new oe(r.path);this.Ue(a,o,aa.newNoDocument(o,me.min()))}else Oe(n===1);else{const o=this.Ye(a);if(o!==n){const l=this.Ze(e),c=l?this.Xe(l,e,o):1;if(c!==0){this.je(a);const d=c===2?"TargetPurposeExistenceFilterMismatchBloom":"TargetPurposeExistenceFilterMismatch";this.Qe=this.Qe.insert(a,d)}}}}}Ze(e){const a=e.me.unchangedNames;if(!a||!a.bits)return null;const{bits:{bitmap:n="",padding:i=0},hashCount:r=0}=a;let o,l;try{o=Qo(n).toUint8Array()}catch(c){if(c instanceof aL)return wl("Decoding the base64 bloom filter in existence filter failed ("+c.message+"); ignoring the bloom filter and falling back to full re-query."),null;throw c}try{l=new Yw(o,i,r)}catch(c){return wl(c instanceof Fc?"BloomFilter error: ":"Applying bloom filter failed: ",c),null}return l.Ie===0?null:l}Xe(e,a,n){return a.me.count===n-this.nt(e,a.targetId)?0:2}nt(e,a){const n=this.Le.getRemoteKeysForTarget(a);let i=0;
1142return n.forEach(r=>{const o=this.Le.tt(),l=`projects/${o.projectId}/databases/${o.database}/documents/${r.path.canonicalString()}`;e.mightContain(l)||(this.Ue(a,r,null),i++)}),i}rt(e){const a=new Map;this.Be.forEach((r,o)=>{const l=this.Je(o);if(l){if(r.current&&ab(l.target)){const c=new oe(l.target.path);this.ke.get(c)!==null||this.it(o,c)||this.Ue(o,c,aa.newNoDocument(c,e))}r.be&&(a.set(o,r.ve()),r.Ce())}});let n=Se();this.qe.forEach((r,o)=>{let l=!0;o.forEachWhile(c=>{const d=this.Je(c);return!d||d.purpose==="TargetPurposeLimboResolution"||(l=!1,!1)}),l&&(n=n.add(r))}),this.ke.forEach((r,o)=>o.setReadTime(e));const i=new vg(e,a,this.Qe,this.ke,n);return this.ke=Hi(),this.qe=fC(),this.Qe=new tt(je),i}$e(e,a){if(!this.ze(e))return;const n=this.it(e,a.key)?2:0;this.Ge(e).Fe(a.key,n),this.ke=this.ke.insert(a.key,a),this.qe=this.qe.insert(a.key,this.st(a.key).add(e))}Ue(e,a,n){if(!this.ze(e))return;const i=this.Ge(e);this.it(e,a)?i.Fe(a,1):i.Me(a),this.qe=this.qe.insert(a,this.st(a).delete(e)),n&&(this.ke=this.ke.insert(a,n))}removeTarget(e){this.Be.delete(e)}Ye(e){const a=this.Ge(e).ve();return this.Le.getRemoteKeysForTarget(e).size+a.addedDocuments.size-a.removedDocuments.size}xe(e){this.Ge(e).xe()}Ge(e){let a=this.Be.get(e);return a||(a=new hC,this.Be.set(e,a)),a}st(e){let a=this.qe.get(e);return a||(a=new Bt(je),this.qe=this.qe.insert(e,a)),a}ze(e){const a=this.Je(e)!==null;return a||Y("WatchChangeAggregator","Detected inactive target",e),a}Je(e){const a=this.Be.get(e);return a&&a.Se?null:this.Le.ot(e)}je(e){this.Be.set(e,new hC),this.Le.getRemoteKeysForTarget(e).forEach(a=>{this.Ue(e,a,null)})}it(e,a){return this.Le.getRemoteKeysForTarget(e).has(a)}}function fC(){return new tt(oe.comparator)}function gC(){return new tt(oe.comparator)}const kG={asc:"ASCENDING",desc:"DESCENDING"},SG={"<":"LESS_THAN","<=":"LESS_THAN_OR_EQUAL",">":"GREATER_THAN",">=":"GREATER_THAN_OR_EQUAL","==":"EQUAL","!=":"NOT_EQUAL","array-contains":"ARRAY_CONTAINS",in:"IN","not-in":"NOT_IN","array-contains-any":"ARRAY_CONTAINS_ANY"},_G={and:"AND",or:"OR"};class AG{constructor(e,a){this.databaseId=e,this.useProto3Json=a}}function rb(t,e){return t.useProto3Json||hg(e)?e:{value:e}}function Oh(t,e){return t.useProto3Json?`${new Date(1e3*e.seconds).toISOString().replace(/\.\d*/,"").replace("Z","")}.${("000000000"+e.nanoseconds).slice(-9)}Z`:{seconds:""+e.seconds,nanos:e.nanoseconds}}function EL(t,e){return t.useProto3Json?e.toBase64():e.toUint8Array()}function EG(t,e){return Oh(t,e.toTimestamp())}function ti(t){return Oe(!!t),me.fromTimestamp(function(a){const n=Fr(a);return new xt(n.seconds,n.nanos)}(t))}function Zw(t,e){return ob(t,e).canonicalString()}function ob(t,e){const a=function(i){return new Ue(["projects",i.projectId,"databases",i.database])}(t).child("documents");return e===void 0?a:a.child(e)}function CL(t){const e=Ue.fromString(t);return Oe(PL(e)),e}function sb(t,e){return Zw(t.databaseId,e.path)}function C0(t,e){const a=CL(e);if(a.get(1)!==t.databaseId.projectId)throw new X(z.INVALID_ARGUMENT,"Tried to deserialize key from different project: "+a.get(1)+" vs "+t.databaseId.projectId);if(a.get(3)!==t.databaseId.database)throw new X(z.INVALID_ARGUMENT,"Tried to deserialize key from different database: "+a.get(3)+" vs "+t.databaseId.database);return new oe(TL(a))}function jL(t,e){return Zw(t.databaseId,e)}function CG(t){const e=CL(t);return e.length===4?Ue.emptyPath():TL(e)}function lb(t){return new Ue(["projects",t.databaseId.projectId,"databases",t.databaseId.database]).canonicalString()}function TL(t){return Oe(t.length>4&&t.get(4)==="documents"),t.popFirst(5)}function yC(t,e,a){return{name:sb(t,e),fields:a.value.mapValue.fields}}function jG(t,e){let a;if("targetChange"in e){e.targetChange;const n=function(d){return d==="NO_CHANGE"?0:d==="ADD"?1:d==="REMOVE"?2:d==="CURRENT"?3:d==="RESET"?4:pe()}(e.targetChange.targetChangeType||"NO_CHANGE"),i=e.targetChange.targetIds||[],r=function(d,u){return d.useProto3Json?(Oe(u===void 0||typeof u=="string"),$t.fromBase64String(u||"")):(Oe(u===void 0||u instanceof Buffer||u instanceof Uint8Array),$t.fromUint8Array(u||new Uint8Array))}(t,e.targetChange.resumeToken),o=e.targetChange.cause,l=o&&function(d){const u=d.code===void 0?z.UNKNOWN:SL(d.c
1142ode);return new X(u,d.message||"")}(o);a=new AL(n,i,r,l||null)}else if("documentChange"in e){e.documentChange;const n=e.documentChange;n.document,n.document.name,n.document.updateTime;const i=C0(t,n.document.name),r=ti(n.document.updateTime),o=n.document.createTime?ti(n.document.createTime):me.min(),l=new _a({mapValue:{fields:n.document.fields}}),c=aa.newFoundDocument(i,r,o,l),d=n.targetIds||[],u=n.removedTargetIds||[];a=new Mm(d,u,c.key,c)}else if("documentDelete"in e){e.documentDelete;const n=e.documentDelete;n.document;const i=C0(t,n.document),r=n.readTime?ti(n.readTime):me.min(),o=aa.newNoDocument(i,r),l=n.removedTargetIds||[];a=new Mm([],l,o.key,o)}else if("documentRemove"in e){e.documentRemove;const n=e.documentRemove;n.document;const i=C0(t,n.document),r=n.removedTargetIds||[];a=new Mm([],r,i,null)}else{if(!("filter"in e))return pe();{e.filter;const n=e.filter;n.targetId;const{count:i=0,unchangedNames:r}=n,o=new yG(i,r),l=n.targetId;a=new _L(l,o)}}return a}function TG(t,e){let a;if(e instanceof Du)a={update:yC(t,e.key,e.value)};else if(e instanceof Qw)a={delete:sb(t,e.key)};else if(e instanceof Xr)a={update:yC(t,e.key,e.data),updateMask:qG(e.fieldMask)};else{if(!(e instanceof hG))return pe();a={verify:sb(t,e.key)}}return e.fieldTransforms.length>0&&(a.updateTransforms=e.fieldTransforms.map(n=>function(r,o){const l=o.transform;if(l instanceof Rh)return{fieldPath:o.field.canonicalString(),setToServerValue:"REQUEST_TIME"};if(l instanceof ou)return{fieldPath:o.field.canonicalString(),appendMissingElements:{values:l.elements}};if(l instanceof su)return{fieldPath:o.field.canonicalString(),removeAllFromArray:{values:l.elements}};if(l instanceof Lh)return{fieldPath:o.field.canonicalString(),increment:l.Pe};throw pe()}(0,n))),e.precondition.isNone||(a.currentDocument=function(i,r){return r.updateTime!==void 0?{updateTime:EG(i,r.updateTime)}:r.exists!==void 0?{exists:r.exists}:pe()}(t,e.precondition)),a}function NG(t,e){return t&&t.length>0?(Oe(e!==void 0),t.map(a=>function(i,r){let o=i.updateTime?ti(i.updateTime):ti(r);return o.isEqual(me.min())&&(o=ti(r)),new uG(o,i.transformResults||[])}(a,e))):[]}function IG(t,e){return{documents:[jL(t,e.path)]}}function PG(t,e){const a={structuredQuery:{}},n=e.path;let i;e.collectionGroup!==null?(i=n,a.structuredQuery.from=[{collectionId:e.collectionGroup,allDescendants:!0}]):(i=n.popLast(),a.structuredQuery.from=[{collectionId:n.lastSegment()}]),a.parent=jL(t,i);const r=function(d){if(d.length!==0)return IL(qn.create(d,"and"))}(e.filters);r&&(a.structuredQuery.where=r);const o=function(d){if(d.length!==0)return d.map(u=>function(m){return{field:js(m.field),direction:OG(m.dir)}}(u))}(e.orderBy);o&&(a.structuredQuery.orderBy=o);const l=rb(t,e.limit);return l!==null&&(a.structuredQuery.limit=l),e.startAt&&(a.structuredQuery.startAt=function(d){return{before:d.inclusive,values:d.position}}(e.startAt)),e.endAt&&(a.structuredQuery.endAt=function(d){return{before:!d.inclusive,values:d.position}}(e.endAt)),{_t:a,parent:i}}function RG(t){let e=CG(t.parent);const a=t.structuredQuery,n=a.from?a.from.length:0;let i=null;if(n>0){Oe(n===1);const u=a.from[0];u.allDescendants?i=u.collectionId:e=e.child(u.collectionId)}let r=[];a.where&&(r=function(p){const m=NL(p);return m instanceof qn&&oL(m)?m.getFilters():[m]}(a.where));let o=[];a.orderBy&&(o=function(p){return p.map(m=>function(g){return new Ph(Ts(g.field),function(x){switch(x){case"ASCENDING":return"asc";case"DESCENDING":return"desc";default:return}}(g.direction))}(m))}(a.orderBy));let l=null;a.limit&&(l=function(p){let m;return m=typeof p=="object"?p.value:p,hg(m)?null:m}(a.limit));let c=null;a.startAt&&(c=function(p){const m=!!p.before,h=p.values||[];return new Ih(h,m)}(a.startAt));let d=null;return a.endAt&&(d=function(p){const m=!p.before,h=p.values||[];return new Ih(h,m)}(a.endAt)),YW(e,i,o,r,l,"F",c,d)}function LG(t,e){const a=function(i){switch(i){case"TargetPurposeListen":return null;case"TargetPurposeExistenceFilterMismatch":return"existence-filter-mismatch";case"TargetPurposeExistenceFilterMismatchBloom":return"existence-filter-mismatch-bloom";case"TargetPurposeLimboResolution":return"limbo-document";default:return pe()}}(e.purpose);return a==null?null:{"goog-listen-tags":a}}function NL(t){return t.unaryFilter!==void 0?function(a){switch(a.unaryFilter.op){case"IS_NAN":const n=Ts(a.unaryFilter.field);return gt.create(n,"==",{doubleValue:NaN});case"IS_NULL":const i=Ts(a.unaryFilter.field);return gt.create(i,"==",{nullValue:"NULL_VALUE"});
1142case"IS_NOT_NAN":const r=Ts(a.unaryFilter.field);return gt.create(r,"!=",{doubleValue:NaN});case"IS_NOT_NULL":const o=Ts(a.unaryFilter.field);return gt.create(o,"!=",{nullValue:"NULL_VALUE"});default:return pe()}}(t):t.fieldFilter!==void 0?function(a){return gt.create(Ts(a.fieldFilter.field),function(i){switch(i){case"EQUAL":return"==";case"NOT_EQUAL":return"!=";case"GREATER_THAN":return">";case"GREATER_THAN_OR_EQUAL":return">=";case"LESS_THAN":return"<";case"LESS_THAN_OR_EQUAL":return"<=";case"ARRAY_CONTAINS":return"array-contains";case"IN":return"in";case"NOT_IN":return"not-in";case"ARRAY_CONTAINS_ANY":return"array-contains-any";default:return pe()}}(a.fieldFilter.op),a.fieldFilter.value)}(t):t.compositeFilter!==void 0?function(a){return qn.create(a.compositeFilter.filters.map(n=>NL(n)),function(i){switch(i){case"AND":return"and";case"OR":return"or";default:return pe()}}(a.compositeFilter.op))}(t):pe()}function OG(t){return kG[t]}function MG(t){return SG[t]}function DG(t){return _G[t]}function js(t){return{fieldPath:t.canonicalString()}}function Ts(t){return Ht.fromServerFormat(t.fieldPath)}function IL(t){return t instanceof gt?function(a){if(a.op==="=="){if(nC(a.value))return{unaryFilter:{field:js(a.field),op:"IS_NAN"}};if(aC(a.value))return{unaryFilter:{field:js(a.field),op:"IS_NULL"}}}else if(a.op==="!="){if(nC(a.value))return{unaryFilter:{field:js(a.field),op:"IS_NOT_NAN"}};if(aC(a.value))return{unaryFilter:{field:js(a.field),op:"IS_NOT_NULL"}}}return{fieldFilter:{field:js(a.field),op:MG(a.op),value:a.value}}}(t):t instanceof qn?function(a){const n=a.getFilters().map(i=>IL(i));return n.length===1?n[0]:{compositeFilter:{op:DG(a.op),filters:n}}}(t):pe()}function qG(t){const e=[];return t.fields.forEach(a=>e.push(a.canonicalString())),{fieldPaths:e}}function PL(t){return t.length>=4&&t.get(0)==="projects"&&t.get(2)==="databases"}/**
1143 * @license
1144 * Copyright 2017 Google LLC
1145 *
1146 * Licensed under the Apache License, Version 2.0 (the "License");
1147 * you may not use this file except in compliance with the License.
1148 * You may obtain a copy of the License at
1149 *
1150 *   http://www.apache.org/licenses/LICENSE-2.0
1151 *
1152 * Unless required by applicable law or agreed to in writing, software
1153 * distributed under the License is distributed on an "AS IS" BASIS,
1154 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
1155 * See the License for the specific language governing permissions and
1156 * limitations under the License.
1157 */class yr{constructor(e,a,n,i,r=me.min(),o=me.min(),l=$t.EMPTY_BYTE_STRING,c=null){this.target=e,this.targetId=a,this.purpose=n,this.sequenceNumber=i,this.snapshotVersion=r,this.lastLimboFreeSnapshotVersion=o,this.resumeToken=l,this.expectedCount=c}withSequenceNumber(e){return new yr(this.target,this.targetId,this.purpose,e,this.snapshotVersion,this.lastLimboFreeSnapshotVersion,this.resumeToken,this.expectedCount)}withResumeToken(e,a){return new yr(this.target,this.targetId,this.purpose,this.sequenceNumber,a,this.lastLimboFreeSnapshotVersion,e,null)}withExpectedCount(e){return new yr(this.target,this.targetId,this.purpose,this.sequenceNumber,this.snapshotVersion,this.lastLimboFreeSnapshotVersion,this.resumeToken,e)}withLastLimboFreeSnapshotVersion(e){return new yr(this.target,this.targetId,this.purpose,this.sequenceNumber,this.snapshotVersion,e,this.resumeToken,this.expectedCount)}}/**
1158 * @license
1159 * Copyright 2017 Google LLC
1160 *
1161 * Licensed under the Apache License, Version 2.0 (the "License");
1162 * you may not use this file except in compliance with the License.
1163 * You may obtain a copy of the License at
1164 *
1165 *   http://www.apache.org/licenses/LICENSE-2.0
1166 *
1167 * Unless required by applicable law or agreed to in writing, software
1168 * distributed under the License is distributed on an "AS IS" BASIS,
1169 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
1170 * See the License for the specific language governing permissions and
1171 * limitations under the License.
1172 */class zG{constructor(e){this.ct=e}}function VG(t){const e=RG({parent:t.parent,structuredQuery:t.structuredQuery});return t.limitType==="LAST"?ib(e,e.limit,"L"):e}/**
1173 * @license
1174 * Copyright 2019 Google LLC
1175 *
1176 * Licensed under the Apache License, Version 2.0 (the "License");
1177 * you may not use this file except in compliance with the License.
1178 * You may obtain a copy of the License at
1179 *
1180 *   http://www.apache.org/licenses/LICENSE-2.0
1181 *
1182 * Unless required by applicable law or agreed to in writing, software
1183 * distributed under the License is distributed on an "AS IS" BASIS,
1184 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
1185 * See the License for the specific language governing permissions and
1186 * limitations under the License.
1187 */class HG{constructor(){this.un=new FG}addToCollectionParentIndex(e,a){return this.un.add(a),H.resolve()}getCollectionParents(e,a){return H.resolve(this.un.getEntries(a))}addFieldIndex(e,a){return H.resolve()}deleteFieldIndex(e,a){return H.resolve()}deleteAllFieldIndexes(e){return H.resolve()}createTargetIndexes(e,a){return H.resolve()}getDocumentsMatchingTarget(e,a){return H.resolve(null)}getIndexType(e,a){return H.resolve(0)}getFieldIndexes(e,a){return H.resolve([])}getNextCollectionGroupToUpdate(e){return H.resolve(null)}getMinOffset(e,a){return H.resolve(Hr.min())}getMinOffsetFromCollectionGroup(e,a){return H.resolve(Hr.min())}updateCollectionGroup(e,a,n){return H.resolve()}updateIndexEntries(e,a){return H.resolve()}}class FG{constructor(){this.index={}}add(e){const a=e.lastSegment(),n=e.popLast(),i=this.index[a]||new Bt(Ue.comparator),r=!i.has(n);return this.index[a]=i.add(n),r}has(e){const a=e.lastSegment(),n=e.popLast(),i=this.index[a];return i&&i.has(n)}getEntries(e){return(this.index[e]||new Bt(Ue.comparator)).toArray()}}/**
1188 * @license
1189 * Copyright 2017 Google LLC
1190 *
1191 * Licensed under the Apache License, Version 2.0 (the "License");
1192 * you may not use this file except in compliance with the License.
1193 * You may obtain a copy of the License at
1194 *
1195 *   http://www.apache.org/licenses/LICENSE-2.0
1196 *
1197 * Unless required by applicable law or agreed to in writing, software
1198 * distributed under the License is distributed on an "AS IS" BASIS,
1199 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
1200 * See the License for the specific language governing permissions and
1201 * limitations under the License.
1202 */class Al{constructor(e){this.Ln=e}next(){return this.Ln+=2,this.Ln}static Bn(){return new Al(0)}static kn(){return new Al(-1)}}/**
1203 * @license
1204 * Copyright 2017 Google LLC
1205 *
1206 * Licensed under the Apache License, Version 2.0 (the "License");
1207 * you may not use this file except in compliance with the License.
1208 * You may obtain a copy of the License at
1209 *
1210 *   http://www.apache.org/licenses/LICENSE-2.0
1211 *
1212 * Unless required by applicable law or agreed to in writing, software
1213 * distributed under the License is distributed on an "AS IS" BASIS,
1214 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
1215 * See the License for the specific language governing permissions and
1216 * limitations under the License.
1217 */class BG{constructor(){this.changes=new Kl(e=>e.toString(),(e,a)=>e.isEqual(a)),this.changesApplied=!1}addEntry(e){this.assertNotApplied(),this.changes.set(e.key,e)}removeEntry(e,a){this.assertNotApplied(),this.changes.set(e,aa.newInvalidDocument(e).setReadTime(a))}getEntry(e,a){this.assertNotApplied();const n=this.changes.get(a);return n!==void 0?H.resolve(n):this.getFromCache(e,a)}getEntries(e,a){return this.getAllFromCache(e,a)}apply(e){return this.assertNotApplied(),this.changesApplied=!0,this.applyChanges(e)}assertNotApplied(){}}/**
1218 * @license
1219 * Copyright 2017 Google LLC
1220 *
1221 * Licensed under the Apache License, Version 2.0 (the "License");
1222 * you may not use this file except in compliance with the License.
1223 * You may obtain a copy of the License at
1224 *
1225 *   http://www.apache.org/licenses/LICENSE-2.0
1226 *
1227 * Unless required by applicable law or agreed to in writing, software
1228 * distributed under the License is distributed on an "AS IS" BASIS,
1229 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
1230 * See the License for the specific language governing permissions and
1231 * limitations under the License.
1232 *//**
1233 * @license
1234 * Copyright 2022 Google LLC
1235 *
1236 * Licensed under the Apache License, Version 2.0 (the "License");
1237 * you may not use this file except in compliance with the License.
1238 * You may obtain a copy of the License at
1239 *
1240 *   http://www.apache.org/licenses/LICENSE-2.0
1241 *
1242 * Unless required by applicable law or agreed to in writing, software
1243 * distributed under the License is distributed on an "AS IS" BASIS,
1244 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
1245 * See the License for the specific language governing permissions and
1246 * limitations under the License.
1247 */class UG{constructor(e,a){this.overlayedDocument=e,this.mutatedFields=a}}/**
1248 * @license
1249 * Copyright 2017 Google LLC
1250 *
1251 * Licensed under the Apache License, Version 2.0 (the "License");
1252 * you may not use this file except in compliance with the License.
1253 * You may obtain a copy of the License at
1254 *
1255 *   http://www.apache.org/licenses/LICENSE-2.0
1256 *
1257 * Unless required by applicable law or agreed to in writing, software
1258 * distributed under the License is distributed on an "AS IS" BASIS,
1259 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
1260 * See the License for the specific language governing permissions and
1261 * limitations under the License.
1262 */class $G{constructor(e,a,n,i){this.remoteDocumentCache=e,this.mutationQueue=a,this.documentOverlayCache=n,this.indexManager=i}getDocument(e,a){let n=null;return this.documentOverlayCache.getOverlay(e,a).next(i=>(n=i,this.remoteDocumentCache.getEntry(e,a))).next(i=>(n!==null&&hd(n.mutation,i,Va.empty(),xt.now()),i))}getDocuments(e,a){return this.remoteDocumentCache.getEntries(e,a).next(n=>this.getLocalViewOfDocuments(e,n,Se()).next(()=>n))}getLocalViewOfDocuments(e,a,n=Se()){const i=So();return this.populateOverlays(e,i,a).next(()=>this.computeViews(e,a,i,n).next(r=>{let o=Hc();return r.forEach((l,c)=>{o=o.insert(l,c.overlayedDocument)}),o}))}getOverlayedDocuments(e,a){const n=So();return this.populateOverlays(e,n,a).next(()=>this.computeViews(e,a,n,Se()))}populateOverlays(e,a,n){const i=[];return n.forEach(r=>{a.has(r)||i.push(r)}),this.documentOverlayCache.getOverlays(e,i).next(r=>{r.forEach((o,l)=>{a.set(o,l)})})}computeViews(e,a,n,i){let r=Hi();const o=md(),l=function(){return md()}();return a.forEach((c,d)=>{const u=n.get(d.key);i.has(d.key)&&(u===void 0||u.mutation instanceof Xr)?r=r.insert(d.key,d):u!==void 0?(o.set(d.key,u.mutation.getFieldMask()),hd(u.mutation,d,u.mutation.getFieldMask(),xt.now())):o.set(d.key,Va.empty())}),this.recalculateAndSaveOverlays(e,r).next(c=>(c.forEach((d,u)=>o.set(d,u)),a.forEach((d,u)=>{var p;return l.set(d,new UG(u,(p=o.get(d))!==null&&p!==void 0?p:null))}),l))}recalculateAndSaveOverlays(e,a){const n=md();let i=new tt((o,l)=>o-l),r=Se();return this.mutationQueue.getAllMutationBatchesAffectingDocumentKeys(e,a).next(o=>{for(const l of o)l.keys().forEach(c=>{const d=a.get(c);if(d===null)return;let u=n.get(c)||Va.empty();u=l.applyToLocalView(d,u),n.set(c,u);const p=(i.get(l.batchId)||Se()).add(c);i=i.insert(l.batchId,p)})}).next(()=>{const o=[],l=i.getReverseIterator();for(;l.hasNext();){const c=l.getNext(),d=c.key,u=c.value,p=fL();u.forEach(m=>{if(!r.has(m)){const h=wL(a.get(m),n.get(m));h!==null&&p.set(m,h),r=r.add(m)}}),o.push(this.documentOverlayCache.saveOverlays(e,d,p))}return H.waitFor(o)}).next(()=>n)}recalculateAndSaveOverlaysForDocumentKeys(e,a){return this.remoteDocumentCache.getEntries(e,a).next(n=>this.recalculateAndSaveOverlays(e,n))}getDocumentsMatchingQuery(e,a,n,i){return function(o){return oe.isDocumentKey(o.path)&&o.collectionGroup===null&&o.filters.length===0}(a)?this.getDocumentsMatchingDocumentQuery(e,a.path):dL(a)?this.getDocumentsMatchingCollectionGroupQuery(e,a,n,i):this.getDocumentsMatchingCollectionQuery(e,a,n,i)}getNextDocuments(e,a,n,i){return this.remoteDocumentCache.getAllFromCollectionGroup(e,a,n,i).next(r=>{const o=i-r.size>0?this.documentOverlayCache.getOverlaysForCollectionGroup(e,a,n.largestBatchId,i-r.size):H.resolve(So());let l=-1,c=r;return o.next(d=>H.forEach(d,(u,p)=>(l<p.largestBatchId&&(l=p.largestBatchId),r.get(u)?H.resolve():this.remoteDocumentCache.getEntry(e,u).next(m=>{c=c.insert(u,m)}))).next(()=>this.populateOverlays(e,d,r)).next(()=>this.computeViews(e,c,d,Se())).next(u=>({batchId:l,changes:hL(u)})))})}getDocumentsMatchingDocumentQuery(e,a){return this.getDocument(e,new oe(a)).next(n=>{let i=Hc();
vendor: 4,204 bytes, lines 1262-1296
1262return n.isFoundDocument()&&(i=i.insert(n.key,n)),i})}getDocumentsMatchingCollectionGroupQuery(e,a,n,i){const r=a.collectionGroup;let o=Hc();return this.indexManager.getCollectionParents(e,r).next(l=>H.forEach(l,c=>{const d=function(p,m){return new Mu(m,null,p.explicitOrderBy.slice(),p.filters.slice(),p.limit,p.limitType,p.startAt,p.endAt)}(a,c.child(r));return this.getDocumentsMatchingCollectionQuery(e,d,n,i).next(u=>{u.forEach((p,m)=>{o=o.insert(p,m)})})}).next(()=>o))}getDocumentsMatchingCollectionQuery(e,a,n,i){let r;return this.documentOverlayCache.getOverlaysForCollection(e,a.path,n.largestBatchId).next(o=>(r=o,this.remoteDocumentCache.getDocumentsMatchingQuery(e,a,n,r,i))).next(o=>{r.forEach((c,d)=>{const u=d.getKey();o.get(u)===null&&(o=o.insert(u,aa.newInvalidDocument(u)))});let l=Hc();return o.forEach((c,d)=>{const u=r.get(c);u!==void 0&&hd(u.mutation,d,Va.empty(),xt.now()),gg(a,d)&&(l=l.insert(c,d))}),l})}}/**
1263 * @license
1264 * Copyright 2020 Google LLC
1265 *
1266 * Licensed under the Apache License, Version 2.0 (the "License");
1267 * you may not use this file except in compliance with the License.
1268 * You may obtain a copy of the License at
1269 *
1270 *   http://www.apache.org/licenses/LICENSE-2.0
1271 *
1272 * Unless required by applicable law or agreed to in writing, software
1273 * distributed under the License is distributed on an "AS IS" BASIS,
1274 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
1275 * See the License for the specific language governing permissions and
1276 * limitations under the License.
1277 */class WG{constructor(e){this.serializer=e,this.hr=new Map,this.Pr=new Map}getBundleMetadata(e,a){return H.resolve(this.hr.get(a))}saveBundleMetadata(e,a){return this.hr.set(a.id,function(i){return{id:i.id,version:i.version,createTime:ti(i.createTime)}}(a)),H.resolve()}getNamedQuery(e,a){return H.resolve(this.Pr.get(a))}saveNamedQuery(e,a){return this.Pr.set(a.name,function(i){return{name:i.name,query:VG(i.bundledQuery),readTime:ti(i.readTime)}}(a)),H.resolve()}}/**
1278 * @license
1279 * Copyright 2022 Google LLC
1280 *
1281 * Licensed under the Apache License, Version 2.0 (the "License");
1282 * you may not use this file except in compliance with the License.
1283 * You may obtain a copy of the License at
1284 *
1285 *   http://www.apache.org/licenses/LICENSE-2.0
1286 *
1287 * Unless required by applicable law or agreed to in writing, software
1288 * distributed under the License is distributed on an "AS IS" BASIS,
1289 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
1290 * See the License for the specific language governing permissions and
1291 * limitations under the License.
1292 */class GG{constructor(){this.overlays=new tt(oe.comparator),this.Ir=new Map}getOverlay(e,a){return H.resolve(this.overlays.get(a))}getOverlays(e,a){const n=So();return H.forEach(a,i=>this.getOverlay(e,i).next(r=>{r!==null&&n.set(i,r)})).next(()=>n)}saveOverlays(e,a,n){return n.forEach((i,r)=>{this.ht(e,a,r)}),H.resolve()}removeOverlaysForBatchId(e,a,n){const i=this.Ir.get(n);return i!==void 0&&(i.forEach(r=>this.overlays=this.overlays.remove(r)),this.Ir.delete(n)),H.resolve()}getOverlaysForCollection(e,a,n){const i=So(),r=a.length+1,o=new oe(a.child("")),l=this.overlays.getIteratorFrom(o);for(;l.hasNext();){const c=l.getNext().value,d=c.getKey();if(!a.isPrefixOf(d.path))break;d.path.length===r&&c.largestBatchId>n&&i.set(c.getKey(),c)}return H.resolve(i)}getOverlaysForCollectionGroup(e,a,n,i){let r=new tt((d,u)=>d-u);const o=this.overlays.getIterator();for(;o.hasNext();){const d=o.getNext().value;if(d.getKey().getCollectionGroup()===a&&d.largestBatchId>n){let u=r.get(d.largestBatchId);u===null&&(u=So(),r=r.insert(d.largestBatchId,u)),u.set(d.getKey(),d)}}const l=So(),c=r.getIterator();for(;c.hasNext()&&(c.getNext().value.forEach((d,u)=>l.set(d,u)),!(l.size()>=i)););return H.resolve(l)}ht(e,a,n){const i=this.overlays.get(n.key);if(i!==null){const o=this.Ir.get(i.largestBatchId).delete(n.key);this.Ir.set(i.largestBatchId,o)}this.overlays=this.overlays.insert(n.key,new gG(a,n));let r=this.Ir.get(a);r===void 0&&(r=Se(),this.Ir.set(a,r)),this.Ir.set(a,r.add(n.key))}}/**
1293 * @license
1294 * Copyright 2024 Google LLC
1295 *
1296 * Licensed under the Apache License, Version 2.0 (the "License");
1297 * you may not use this file except in compliance with the License.
1298 * You may obtain a copy of the License at
1299 *
1300 *   http://www.apache.org/licenses/LICENSE-2.0
1301 *
1302 * Unless required by applicable law or agreed to in writing, software
1303 * distributed under the License is distributed on an "AS IS" BASIS,
1304 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
1305 * See the License for the specific language governing permissions and
1306 * limitations under the License.
1307 */class KG{constructor(){this.sessionToken=$t.EMPTY_BYTE_STRING}getSessionToken(e){return H.resolve(this.sessionToken)}setSessionToken(e,a){return this.sessionToken=a,H.resolve()}}/**
1308 * @license
1309 * Copyright 2017 Google LLC
1310 *
1311 * Licensed under the Apache License, Version 2.0 (the "License");
1312 * you may not use this file except in compliance with the License.
1313 * You may obtain a copy of the License at
1314 *
1315 *   http://www.apache.org/licenses/LICENSE-2.0
1316 *
1317 * Unless required by applicable law or agreed to in writing, software
1318 * distributed under the License is distributed on an "AS IS" BASIS,
1319 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
1320 * See the License for the specific language governing permissions and
1321 * limitations under the License.
1322 */class ek{constructor(){this.Tr=new Bt(Ct.Er),this.dr=new Bt(Ct.Ar)}isEmpty(){return this.Tr.isEmpty()}addReference(e,a){const n=new Ct(e,a);this.Tr=this.Tr.add(n),this.dr=this.dr.add(n)}Rr(e,a){e.forEach(n=>this.addReference(n,a))}removeReference(e,a){this.Vr(new Ct(e,a))}mr(e,a){e.forEach(n=>this.removeReference(n,a))}gr(e){const a=new oe(new Ue([])),n=new Ct(a,e),i=new Ct(a,e+1),r=[];return this.dr.forEachInRange([n,i],o=>{this.Vr(o),r.push(o.key)}),r}pr(){this.Tr.forEach(e=>this.Vr(e))}Vr(e){this.Tr=this.Tr.delete(e),this.dr=this.dr.delete(e)}yr(e){const a=new oe(new Ue([])),n=new Ct(a,e),i=new Ct(a,e+1);let r=Se();return this.dr.forEachInRange([n,i],o=>{r=r.add(o.key)}),r}containsKey(e){const a=new Ct(e,0),n=this.Tr.firstAfterOrEqual(a);return n!==null&&e.isEqual(n.key)}}class Ct{constructor(e,a){this.key=e,this.wr=a}static Er(e,a){return oe.comparator(e.key,a.key)||je(e.wr,a.wr)}static Ar(e,a){return je(e.wr,a.wr)||oe.comparator(e.key,a.key)}}/**
1323 * @license
1324 * Copyright 2017 Google LLC
1325 *
1326 * Licensed under the Apache License, Version 2.0 (the "License");
1327 * you may not use this file except in compliance with the License.
1328 * You may obtain a copy of the License at
1329 *
1330 *   http://www.apache.org/licenses/LICENSE-2.0
1331 *
1332 * Unless required by applicable law or agreed to in writing, software
1333 * distributed under the License is distributed on an "AS IS" BASIS,
1334 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
1335 * See the License for the specific language governing permissions and
1336 * limitations under the License.
1337 */class JG{constructor(e,a){this.indexManager=e,this.referenceDelegate=a,this.mutationQueue=[],this.Sr=1,this.br=new Bt(Ct.Er)}checkEmpty(e){return H.resolve(this.mutationQueue.length===0)}addMutationBatch(e,a,n,i){const r=this.Sr;this.Sr++,this.mutationQueue.length>0&&this.mutationQueue[this.mutationQueue.length-1];const o=new fG(r,a,n,i);this.mutationQueue.push(o);for(const l of i)this.br=this.br.add(new Ct(l.key,r)),this.indexManager.addToCollectionParentIndex(e,l.key.path.popLast());return H.resolve(o)}lookupMutationBatch(e,a){return H.resolve(this.Dr(a))}getNextMutationBatchAfterBatchId(e,a){const n=a+1,i=this.vr(n),r=i<0?0:i;return H.resolve(this.mutationQueue.length>r?this.mutationQueue[r]:null)}getHighestUnacknowledgedBatchId(){return H.resolve(this.mutationQueue.length===0?-1:this.Sr-1)}getAllMutationBatches(e){return H.resolve(this.mutationQueue.slice())}getAllMutationBatchesAffectingDocumentKey(e,a){const n=new Ct(a,0),i=new Ct(a,Number.POSITIVE_INFINITY),r=[];return this.br.forEachInRange([n,i],o=>{const l=this.Dr(o.wr);r.push(l)}),H.resolve(r)}getAllMutationBatchesAffectingDocumentKeys(e,a){let n=new Bt(je);return a.forEach(i=>{const r=new Ct(i,0),o=new Ct(i,Number.POSITIVE_INFINITY);this.br.forEachInRange([r,o],l=>{n=n.add(l.wr)})}),H.resolve(this.Cr(n))}getAllMutationBatchesAffectingQuery(e,a){const n=a.path,i=n.length+1;let r=n;oe.isDocumentKey(r)||(r=r.child(""));const o=new Ct(new oe(r),0);let l=new Bt(je);return this.br.forEachWhile(c=>{const d=c.key.path;return!!n.isPrefixOf(d)&&(d.length===i&&(l=l.add(c.wr)),!0)},o),H.resolve(this.Cr(l))}Cr(e){const a=[];return e.forEach(n=>{const i=this.Dr(n);i!==null&&a.push(i)}),a}removeMutationBatch(e,a){Oe(this.Fr(a.batchId,"removed")===0),this.mutation
1337Queue.shift();let n=this.br;return H.forEach(a.mutations,i=>{const r=new Ct(i.key,a.batchId);return n=n.delete(r),this.referenceDelegate.markPotentiallyOrphaned(e,i.key)}).next(()=>{this.br=n})}On(e){}containsKey(e,a){const n=new Ct(a,0),i=this.br.firstAfterOrEqual(n);return H.resolve(a.isEqual(i&&i.key))}performConsistencyCheck(e){return this.mutationQueue.length,H.resolve()}Fr(e,a){return this.vr(e)}vr(e){return this.mutationQueue.length===0?0:e-this.mutationQueue[0].batchId}Dr(e){const a=this.vr(e);return a<0||a>=this.mutationQueue.length?null:this.mutationQueue[a]}}/**
1338 * @license
1339 * Copyright 2017 Google LLC
1340 *
1341 * Licensed under the Apache License, Version 2.0 (the "License");
1342 * you may not use this file except in compliance with the License.
1343 * You may obtain a copy of the License at
1344 *
1345 *   http://www.apache.org/licenses/LICENSE-2.0
1346 *
1347 * Unless required by applicable law or agreed to in writing, software
1348 * distributed under the License is distributed on an "AS IS" BASIS,
1349 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
1350 * See the License for the specific language governing permissions and
1351 * limitations under the License.
1352 */class QG{constructor(e){this.Mr=e,this.docs=function(){return new tt(oe.comparator)}(),this.size=0}setIndexManager(e){this.indexManager=e}addEntry(e,a){const n=a.key,i=this.docs.get(n),r=i?i.size:0,o=this.Mr(a);return this.docs=this.docs.insert(n,{document:a.mutableCopy(),size:o}),this.size+=o-r,this.indexManager.addToCollectionParentIndex(e,n.path.popLast())}removeEntry(e){const a=this.docs.get(e);a&&(this.docs=this.docs.remove(e),this.size-=a.size)}getEntry(e,a){const n=this.docs.get(a);return H.resolve(n?n.document.mutableCopy():aa.newInvalidDocument(a))}getEntries(e,a){let n=Hi();return a.forEach(i=>{const r=this.docs.get(i);n=n.insert(i,r?r.document.mutableCopy():aa.newInvalidDocument(i))}),H.resolve(n)}getDocumentsMatchingQuery(e,a,n,i){let r=Hi();const o=a.path,l=new oe(o.child("")),c=this.docs.getIteratorFrom(l);for(;c.hasNext();){const{key:d,value:{document:u}}=c.getNext();if(!o.isPrefixOf(d.path))break;d.path.length>o.length+1||RW(PW(u),n)<=0||(i.has(u.key)||gg(a,u))&&(r=r.insert(u.key,u.mutableCopy()))}return H.resolve(r)}getAllFromCollectionGroup(e,a,n,i){pe()}Or(e,a){return H.forEach(this.docs,n=>a(n))}newChangeBuffer(e){return new XG(this)}getSize(e){return H.resolve(this.size)}}class XG extends BG{constructor(e){super(),this.cr=e}applyChanges(e){const a=[];
vendor: 10,236 bytes, lines 1352-1427
1352return this.changes.forEach((n,i)=>{i.isValidDocument()?a.push(this.cr.addEntry(e,i)):this.cr.removeEntry(n)}),H.waitFor(a)}getFromCache(e,a){return this.cr.getEntry(e,a)}getAllFromCache(e,a){return this.cr.getEntries(e,a)}}/**
1353 * @license
1354 * Copyright 2017 Google LLC
1355 *
1356 * Licensed under the Apache License, Version 2.0 (the "License");
1357 * you may not use this file except in compliance with the License.
1358 * You may obtain a copy of the License at
1359 *
1360 *   http://www.apache.org/licenses/LICENSE-2.0
1361 *
1362 * Unless required by applicable law or agreed to in writing, software
1363 * distributed under the License is distributed on an "AS IS" BASIS,
1364 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
1365 * See the License for the specific language governing permissions and
1366 * limitations under the License.
1367 */class YG{constructor(e){this.persistence=e,this.Nr=new Kl(a=>Ww(a),Gw),this.lastRemoteSnapshotVersion=me.min(),this.highestTargetId=0,this.Lr=0,this.Br=new ek,this.targetCount=0,this.kr=Al.Bn()}forEachTarget(e,a){return this.Nr.forEach((n,i)=>a(i)),H.resolve()}getLastRemoteSnapshotVersion(e){return H.resolve(this.lastRemoteSnapshotVersion)}getHighestSequenceNumber(e){return H.resolve(this.Lr)}allocateTargetId(e){return this.highestTargetId=this.kr.next(),H.resolve(this.highestTargetId)}setTargetsMetadata(e,a,n){return n&&(this.lastRemoteSnapshotVersion=n),a>this.Lr&&(this.Lr=a),H.resolve()}Kn(e){this.Nr.set(e.target,e);const a=e.targetId;a>this.highestTargetId&&(this.kr=new Al(a),this.highestTargetId=a),e.sequenceNumber>this.Lr&&(this.Lr=e.sequenceNumber)}addTargetData(e,a){return this.Kn(a),this.targetCount+=1,H.resolve()}updateTargetData(e,a){return this.Kn(a),H.resolve()}removeTargetData(e,a){return this.Nr.delete(a.target),this.Br.gr(a.targetId),this.targetCount-=1,H.resolve()}removeTargets(e,a,n){let i=0;const r=[];return this.Nr.forEach((o,l)=>{l.sequenceNumber<=a&&n.get(l.targetId)===null&&(this.Nr.delete(o),r.push(this.removeMatchingKeysForTargetId(e,l.targetId)),i++)}),H.waitFor(r).next(()=>i)}getTargetCount(e){return H.resolve(this.targetCount)}getTargetData(e,a){const n=this.Nr.get(a)||null;return H.resolve(n)}addMatchingKeys(e,a,n){return this.Br.Rr(a,n),H.resolve()}removeMatchingKeys(e,a,n){this.Br.mr(a,n);const i=this.persistence.referenceDelegate,r=[];return i&&a.forEach(o=>{r.push(i.markPotentiallyOrphaned(e,o))}),H.waitFor(r)}removeMatchingKeysForTargetId(e,a){return this.Br.gr(a),H.resolve()}getMatchingKeysForTargetId(e,a){const n=this.Br.yr(a);return H.resolve(n)}containsKey(e,a){return H.resolve(this.Br.containsKey(a))}}/**
1368 * @license
1369 * Copyright 2017 Google LLC
1370 *
1371 * Licensed under the Apache License, Version 2.0 (the "License");
1372 * you may not use this file except in compliance with the License.
1373 * You may obtain a copy of the License at
1374 *
1375 *   http://www.apache.org/licenses/LICENSE-2.0
1376 *
1377 * Unless required by applicable law or agreed to in writing, software
1378 * distributed under the License is distributed on an "AS IS" BASIS,
1379 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
1380 * See the License for the specific language governing permissions and
1381 * limitations under the License.
1382 */class ZG{constructor(e,a){this.qr={},this.overlays={},this.Qr=new Fw(0),this.Kr=!1,this.Kr=!0,this.$r=new KG,this.referenceDelegate=e(this),this.Ur=new YG(this),this.indexManager=new HG,this.remoteDocumentCache=function(i){return new QG(i)}(n=>this.referenceDelegate.Wr(n)),this.serializer=new zG(a),this.Gr=new WG(this.serializer)}start(){return Promise.resolve()}shutdown(){return this.Kr=!1,Promise.resolve()}get started(){return this.Kr}setDatabaseDeletedListener(){}setNetworkEnabled(){}getIndexManager(e){return this.indexManager}getDocumentOverlayCache(e){let a=this.overlays[e.toKey()];return a||(a=new GG,this.overlays[e.toKey()]=a),a}getMutationQueue(e,a){let n=this.qr[e.toKey()];return n||(n=new JG(a,this.referenceDelegate),this.qr[e.toKey()]=n),n}getGlobalsCache(){return this.$r}getTargetCache(){return this.Ur}getRemoteDocumentCache(){return this.remoteDocumentCache}getBundleCache(){return this.Gr}runTransaction(e,a,n){Y("MemoryPersistence","Starting transaction:",e);const i=new eK(this.Qr.next());return this.referenceDelegate.zr(),n(i).next(r=>this.referenceDelegate.jr(i).next(()=>r)).toPromise().then(r=>(i.raiseOnCommittedEvent(),r))}Hr(e,a){return H.or(Object.values(this.qr).map(n=>()=>n.containsKey(e,a)))}}class eK extends OW{constructor(e){super(),this.currentSequenceNumber=e}}class tk{constructor(e){this.persistence=e,this.Jr=new ek,this.Yr=null}static Zr(e){return new tk(e)}get Xr(){if(this.Yr)return this.Yr;throw pe()}addReference(e,a,n){return this.Jr.addReference(n,a),this.Xr.delete(n.toString()),H.resolve()}removeReference(e,a,n){return this.Jr.removeReference(n,a),this.Xr.add(n.toString()),H.resolve()}markPotentiallyOrphaned(e,a){return this.Xr.add(a.toString()),H.resolve()}removeTarget(e,a){this.Jr.gr(a.targetId).forEach(i=>this.Xr.add(i.toString()));const n=this.persistence.getTargetCache();return n.getMatchingKeysForTargetId(e,a.targetId).next(i=>{i.forEach(r=>this.Xr.add(r.toString()))}).next(()=>n.removeTargetData(e,a))}zr(){this.Yr=new Set}jr(e){const a=this.persistence.getRemoteDocumentCache().newChangeBuffer();return H.forEach(this.Xr,n=>{const i=oe.fromPath(n);return this.ei(e,i).next(r=>{r||a.removeEntry(i,me.min())})}).next(()=>(this.Yr=null,a.apply(e)))}updateLimboDocument(e,a){return this.ei(e,a).next(n=>{n?this.Xr.delete(a.toString()):this.Xr.add(a.toString())})}Wr(e){return 0}ei(e,a){return H.or([()=>H.resolve(this.Jr.containsKey(a)),()=>this.persistence.getTargetCache().containsKey(e,a),()=>this.persistence.Hr(e,a)])}}/**
1383 * @license
1384 * Copyright 2017 Google LLC
1385 *
1386 * Licensed under the Apache License, Version 2.0 (the "License");
1387 * you may not use this file except in compliance with the License.
1388 * You may obtain a copy of the License at
1389 *
1390 *   http://www.apache.org/licenses/LICENSE-2.0
1391 *
1392 * Unless required by applicable law or agreed to in writing, software
1393 * distributed under the License is distributed on an "AS IS" BASIS,
1394 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
1395 * See the License for the specific language governing permissions and
1396 * limitations under the License.
1397 */class ak{constructor(e,a,n,i){this.targetId=e,this.fromCache=a,this.$i=n,this.Ui=i}static Wi(e,a){let n=Se(),i=Se();for(const r of a.docChanges)switch(r.type){case 0:n=n.add(r.doc.key);break;case 1:i=i.add(r.doc.key)}return new ak(e,a.fromCache,n,i)}}/**
1398 * @license
1399 * Copyright 2023 Google LLC
1400 *
1401 * Licensed under the Apache License, Version 2.0 (the "License");
1402 * you may not use this file except in compliance with the License.
1403 * You may obtain a copy of the License at
1404 *
1405 *   http://www.apache.org/licenses/LICENSE-2.0
1406 *
1407 * Unless required by applicable law or agreed to in writing, software
1408 * distributed under the License is distributed on an "AS IS" BASIS,
1409 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
1410 * See the License for the specific language governing permissions and
1411 * limitations under the License.
1412 */class tK{constructor(){this._documentReadCount=0}get documentReadCount(){return this._documentReadCount}incrementDocumentReadCount(e){this._documentReadCount+=e}}/**
1413 * @license
1414 * Copyright 2019 Google LLC
1415 *
1416 * Licensed under the Apache License, Version 2.0 (the "License");
1417 * you may not use this file except in compliance with the License.
1418 * You may obtain a copy of the License at
1419 *
1420 *   http://www.apache.org/licenses/LICENSE-2.0
1421 *
1422 * Unless required by applicable law or agreed to in writing, software
1423 * distributed under the License is distributed on an "AS IS" BASIS,
1424 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
1425 * See the License for the specific language governing permissions and
1426 * limitations under the License.
1427 */class aK{constructor(){this.Gi=!1,this.zi=!1,this.ji=100,this.Hi=function(){return i$()?8:MW(ra())>0?6:4}()}initialize(e,a){this.Ji=e,this.indexManager=a,this.Gi=!0}getDocumentsMatchingQuery(e,a,n,i){const r={result:null};return this.Yi(e,a).next(o=>{r.result=o}).next(()=>{if(!r.result)return this.Zi(e,a,i,n).next(o=>{r.result=o})}).next(()=>{if(r.result)return;const o=new tK;return this.Xi(e,a,o).next(l=>{if(r.result=l,this.zi)return this.es(e,a,o,l.size)})}).next(()=>r.result)}es(e,a,n,i){return n.documentReadCount<this.ji?(jc()<=_e.DEBUG&&Y("QueryEngine","SDK will not create cache indexes for query:",Cs(a),"since it only creates cache indexes for collection contains","more than or equal to",this.ji,"documents"),H.resolve()):(jc()<=_e.DEBUG&&Y("QueryEngine","Query:",Cs(a),"scans",n.documentReadCount,"local documents and returns",i,"documents as results."),n.documentReadCount>this.Hi*i?(jc()<=_e.DEBUG&&Y("QueryEngine","The SDK decides to create cache indexes for query:",Cs(a),"as using cache indexes may help improve performance."),this.indexManager.createTargetIndexes(e,ei(a))):H.resolve())}Yi(e,a){if(sC(a))return H.resolve(null);let n=ei(a);return this.indexManager.getIndexType(e,n).next(i=>i===0?null:(a.limit!==null&&i===1&&(a=ib(a,null,"F"),n=ei(a)),this.indexManager.getDocumentsMatchingTarget(e,n).next(r=>{const o=Se(...r);return this.Ji.getDocuments(e,o).next(l=>this.indexManager.getMinOffset(e,n).next(c=>{const d=this.ts(a,l);return this.ns(a,d,o,c.readTime)?this.Yi(e,ib(a,null,"F")):this.rs(e,d,a,c)}))})))}Zi(e,a,n,i){return sC(a)||i.isEqual(me.min())?H.resolve(null):this.Ji.getDocuments(e,n).next(r=>{const o=this.ts(a,r);return this.ns(a,o,n,i)?H.resolve(null):(jc()<=_e.DEBUG&&Y("QueryEngine","Re-using previous result from %s to execute query: %s",i.toString(),Cs(a)),this.rs(e,o,a,IW(i,-1)).next(l=>l))})}ts(e,a){let n=new Bt(pL(e));return a.forEach((i,r)=>{gg(e,r)&&(n=n.add(r))}),n}ns(e,a,n,i){if(e.limit===null)return!1;if(n.size!==a.size)return!0;const r=e.limitType==="F"?a.last():a.first();return!!r&&(r.hasPendingWrites||r.version.compareTo(i)>0)}Xi(e,a,n){return jc()<=_e.DEBUG&&Y("QueryEngine","Using full collection scan to execute query:",Cs(a)),this.Ji.getDocumentsMatchingQuery(e,a,Hr.min(),n)}rs(e,a,n,i){return this.Ji.getDocumentsMatchingQuery(e,n,i).next(r=>
1427(a.forEach(o=>{r=r.insert(o.key,o)}),r))}}/**
1428 * @license
1429 * Copyright 2020 Google LLC
1430 *
1431 * Licensed under the Apache License, Version 2.0 (the "License");
1432 * you may not use this file except in compliance with the License.
1433 * You may obtain a copy of the License at
1434 *
1435 *   http://www.apache.org/licenses/LICENSE-2.0
1436 *
1437 * Unless required by applicable law or agreed to in writing, software
1438 * distributed under the License is distributed on an "AS IS" BASIS,
1439 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
1440 * See the License for the specific language governing permissions and
1441 * limitations under the License.
1442 */class nK{constructor(e,a,n,i){this.persistence=e,this.ss=a,this.serializer=i,this.os=new tt(je),this._s=new Kl(r=>Ww(r),Gw),this.us=new Map,this.cs=e.getRemoteDocumentCache(),this.Ur=e.getTargetCache(),this.Gr=e.getBundleCache(),this.ls(n)}ls(e){this.documentOverlayCache=this.persistence.getDocumentOverlayCache(e),this.indexManager=this.persistence.getIndexManager(e),this.mutationQueue=this.persistence.getMutationQueue(e,this.indexManager),this.localDocuments=new $G(this.cs,this.mutationQueue,this.documentOverlayCache,this.indexManager),this.cs.setIndexManager(this.indexManager),this.ss.initialize(this.localDocuments,this.indexManager)}collectGarbage(e){return this.persistence.runTransaction("Collect garbage","readwrite-primary",a=>e.collect(a,this.os))}}function iK(t,e,a,n){return new nK(t,e,a,n)}async function RL(t,e){const a=he(t);return await a.persistence.runTransaction("Handle user change","readonly",n=>{let i;return a.mutationQueue.getAllMutationBatches(n).next(r=>(i=r,a.ls(e),a.mutationQueue.getAllMutationBatches(n))).next(r=>{const o=[],l=[];let c=Se();for(const d of i){o.push(d.batchId);for(const u of d.mutations)c=c.add(u.key)}for(const d of r){l.push(d.batchId);for(const u of d.mutations)c=c.add(u.key)}return a.localDocuments.getDocuments(n,c).next(d=>({hs:d,removedBatchIds:o,addedBatchIds:l}))})})}function rK(t,e){const a=he(t);return a.persistence.runTransaction("Acknowledge batch","readwrite-primary",n=>{const i=e.batch.keys(),r=a.cs.newChangeBuffer({trackRemovals:!0});return function(l,c,d,u){const p=d.batch,m=p.keys();let h=H.resolve();return m.forEach(g=>{h=h.next(()=>u.getEntry(c,g)).next(y=>{const x=d.docVersions.get(g);Oe(x!==null),y.version.compareTo(x)<0&&(p.applyToRemoteDocument(y,d),y.isValidDocument()&&(y.setReadTime(d.commitVersion),u.addEntry(y)))})}),h.next(()=>l.mutationQueue.removeMutationBatch(c,p))}(a,n,e,r).next(()=>r.apply(n)).next(()=>a.mutationQueue.performConsistencyCheck(n)).next(()=>a.documentOverlayCache.removeOverlaysForBatchId(n,i,e.batch.batchId)).next(()=>a.localDocuments.recalculateAndSaveOverlaysForDocumentKeys(n,function(l){let c=Se();for(let d=0;d<l.mutationResults.length;++d)l.mutationResults[d].transformResults.length>0&&(c=c.add(l.batch.mutations[d].key));return c}(e))).next(()=>a.localDocuments.getDocuments(n,i))})}function LL(t){const e=he(t);return e.persistence.runTransaction("Get last remote snapshot version","readonly",a=>e.Ur.getLastRemoteSnapshotVersion(a))}function oK(t,e){const a=he(t),n=e.snapshotVersion;let i=a.os;return a.persistence.runTransaction("Apply remote event","readwrite-primary",r=>{const o=a.cs.newChangeBuffer({trackRemovals:!0});i=a.os;const l=[];
vendor: 4,425 bytes, lines 1442-1446
1442e.targetChanges.forEach((u,p)=>{const m=i.get(p);if(!m)return;l.push(a.Ur.removeMatchingKeys(r,u.removedDocuments,p).next(()=>a.Ur.addMatchingKeys(r,u.addedDocuments,p)));let h=m.withSequenceNumber(r.currentSequenceNumber);e.targetMismatches.get(p)!==null?h=h.withResumeToken($t.EMPTY_BYTE_STRING,me.min()).withLastLimboFreeSnapshotVersion(me.min()):u.resumeToken.approximateByteSize()>0&&(h=h.withResumeToken(u.resumeToken,n)),i=i.insert(p,h),function(y,x,v){return y.resumeToken.approximateByteSize()===0||x.snapshotVersion.toMicroseconds()-y.snapshotVersion.toMicroseconds()>=3e8?!0:v.addedDocuments.size+v.modifiedDocuments.size+v.removedDocuments.size>0}(m,h,u)&&l.push(a.Ur.updateTargetData(r,h))});let c=Hi(),d=Se();if(e.documentUpdates.forEach(u=>{e.resolvedLimboDocuments.has(u)&&l.push(a.persistence.referenceDelegate.updateLimboDocument(r,u))}),l.push(sK(r,o,e.documentUpdates).next(u=>{c=u.Ps,d=u.Is})),!n.isEqual(me.min())){const u=a.Ur.getLastRemoteSnapshotVersion(r).next(p=>a.Ur.setTargetsMetadata(r,r.currentSequenceNumber,n));l.push(u)}return H.waitFor(l).next(()=>o.apply(r)).next(()=>a.localDocuments.getLocalViewOfDocuments(r,c,d)).next(()=>c)}).then(r=>(a.os=i,r))}function sK(t,e,a){let n=Se(),i=Se();return a.forEach(r=>n=n.add(r)),e.getEntries(t,n).next(r=>{let o=Hi();return a.forEach((l,c)=>{const d=r.get(l);c.isFoundDocument()!==d.isFoundDocument()&&(i=i.add(l)),c.isNoDocument()&&c.version.isEqual(me.min())?(e.removeEntry(l,c.readTime),o=o.insert(l,c)):!d.isValidDocument()||c.version.compareTo(d.version)>0||c.version.compareTo(d.version)===0&&d.hasPendingWrites?(e.addEntry(c),o=o.insert(l,c)):Y("LocalStore","Ignoring outdated watch update for ",l,". Current version:",d.version," Watch version:",c.version)}),{Ps:o,Is:i}})}function lK(t,e){const a=he(t);return a.persistence.runTransaction("Get next mutation batch","readonly",n=>(e===void 0&&(e=-1),a.mutationQueue.getNextMutationBatchAfterBatchId(n,e)))}function cK(t,e){const a=he(t);return a.persistence.runTransaction("Allocate target","readwrite",n=>{let i;return a.Ur.getTargetData(n,e).next(r=>r?(i=r,H.resolve(i)):a.Ur.allocateTargetId(n).next(o=>(i=new yr(e,o,"TargetPurposeListen",n.currentSequenceNumber),a.Ur.addTargetData(n,i).next(()=>i))))}).then(n=>{const i=a.os.get(n.targetId);return(i===null||n.snapshotVersion.compareTo(i.snapshotVersion)>0)&&(a.os=a.os.insert(n.targetId,n),a._s.set(e,n.targetId)),n})}async function cb(t,e,a){const n=he(t),i=n.os.get(e),r=a?"readwrite":"readwrite-primary";try{a||await n.persistence.runTransaction("Release target",r,o=>n.persistence.referenceDelegate.removeTarget(o,i))}catch(o){if(!Ou(o))throw o;Y("LocalStore",`Failed to update sequence numbers for target ${e}: ${o}`)}n.os=n.os.remove(e),n._s.delete(i.target)}function xC(t,e,a){const n=he(t);let i=me.min(),r=Se();return n.persistence.runTransaction("Execute query","readwrite",o=>function(c,d,u){const p=he(c),m=p._s.get(u);return m!==void 0?H.resolve(p.os.get(m)):p.Ur.getTargetData(d,u)}(n,o,ei(e)).next(l=>{if(l)return i=l.lastLimboFreeSnapshotVersion,n.Ur.getMatchingKeysForTargetId(o,l.targetId).next(c=>{r=c})}).next(()=>n.ss.getDocumentsMatchingQuery(o,e,a?i:me.min(),a?r:Se())).next(l=>(dK(n,eG(e),l),{documents:l,Ts:r})))}function dK(t,e,a){let n=t.us.get(e)||me.min();a.forEach((i,r)=>{r.readTime.compareTo(n)>0&&(n=r.readTime)}),t.us.set(e,n)}class vC{constructor(){this.activeTargetIds=oG()}fs(e){this.activeTargetIds=this.activeTargetIds.add(e)}gs(e){this.activeTargetIds=this.activeTargetIds.delete(e)}Vs(){const e={activeTargetIds:this.activeTargetIds.toArray(),updateTimeMs:Date.now()};return JSON.stringify(e)}}class uK{constructor(){this.so=new vC,this.oo={},this.onlineStateHandler=null,this.sequenceNumberHandler=null}addPendingMutation(e){}updateMutationState(e,a,n){}addLocalQueryTarget(e,a=!0){return a&&this.so.fs(e),this.oo[e]||"not-current"}updateQueryState(e,a,n){this.oo[e]=a}removeLocalQueryTarget(e){this.so.gs(e)}isLocalQueryTarget(e){return this.so.activeTargetIds.has(e)}clearQueryState(e){delete this.oo[e]}getAllActiveQueryTargets(){return this.so.activeTargetIds}isActiveQueryTarget(e){return this.so.activeTargetIds.has(e)}start(){return this.so=new vC,Promise.resolve()}handleUserChange(e,a,n){}setOnlineState(e){}shutdown(){}writeSequenceNumber(e){}notifyBundleLoaded(e){}}/**
1443 * @license
1444 * Copyright 2019 Google LLC
1445 *
1446 * Licensed under the Apache License, Version 2.0 (the "License");
1447 * you may not use this file except in compliance with the License.
1448 * You may obtain a copy of the License at
1449 *
1450 *   http://www.apache.org/licenses/LICENSE-2.0
1451 *
1452 * Unless required by applicable law or agreed to in writing, software
1453 * distributed under the License is distributed on an "AS IS" BASIS,
1454 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
1455 * See the License for the specific language governing permissions and
1456 * limitations under the License.
1457 */class pK{_o(e){}shutdown(){}}/**
1458 * @license
1459 * Copyright 2019 Google LLC
1460 *
1461 * Licensed under the Apache License, Version 2.0 (the "License");
1462 * you may not use this file except in compliance with the License.
1463 * You may obtain a copy of the License at
1464 *
1465 *   http://www.apache.org/licenses/LICENSE-2.0
1466 *
1467 * Unless required by applicable law or agreed to in writing, software
1468 * distributed under the License is distributed on an "AS IS" BASIS,
1469 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
1470 * See the License for the specific language governing permissions and
1471 * limitations under the License.
1472 */class bC{constructor(){this.ao=()=>this.uo(),this.co=()=>this.lo(),this.ho=[],this.Po()}_o(e){this.ho.push(e)}shutdown(){window.removeEventListener("online",this.ao),window.removeEventListener("offline",this.co)}Po(){window.addEventListener("online",this.ao),window.addEventListener("offline",this.co)}uo(){Y("ConnectivityMonitor","Network connectivity changed: AVAILABLE");for(const e of this.ho)e(0)}lo(){Y("ConnectivityMonitor","Network connectivity changed: UNAVAILABLE");for(const e of this.ho)e(1)}static D(){return typeof window<"u"&&window.addEventListener!==void 0&&window.removeEventListener!==void 0}}/**
1473 * @license
1474 * Copyright 2023 Google LLC
1475 *
1476 * Licensed under the Apache License, Version 2.0 (the "License");
1477 * you may not use this file except in compliance with the License.
1478 * You may obtain a copy of the License at
1479 *
1480 *   http://www.apache.org/licenses/LICENSE-2.0
1481 *
1482 * Unless required by applicable law or agreed to in writing, software
1483 * distributed under the License is distributed on an "AS IS" BASIS,
1484 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
1485 * See the License for the specific language governing permissions and
1486 * limitations under the License.
1487 */let Bp=null;function j0(){return Bp===null?Bp=function(){return 268435456+Math.round(2147483648*Math.random())}():Bp++,"0x"+Bp.toString(16)}/**
1488 * @license
1489 * Copyright 2020 Google LLC
1490 *
1491 * Licensed under the Apache License, Version 2.0 (the "License");
1492 * you may not use this file except in compliance with the License.
1493 * You may obtain a copy of the License at
1494 *
1495 *   http://www.apache.org/licenses/LICENSE-2.0
1496 *
1497 * Unless required by applicable law or agreed to in writing, software
1498 * distributed under the License is distributed on an "AS IS" BASIS,
1499 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
1500 * See the License for the specific language governing permissions and
1501 * limitations under the License.
1502 */const mK={BatchGetDocuments:"batchGet",Commit:"commit",RunQuery:"runQuery",RunAggregationQuery:"runAggregationQuery"};/**
1503 * @license
1504 * Copyright 2017 Google LLC
1505 *
1506 * Licensed under the Apache License, Version 2.0 (the "License");
1507 * you may not use this file except in compliance with the License.
1508 * You may obtain a copy of the License at
1509 *
1510 *   http://www.apache.org/licenses/LICENSE-2.0
1511 *
1512 * Unless required by applicable law or agreed to in writing, software
1513 * distributed under the License is distributed on an "AS IS" BASIS,
1514 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
1515 * See the License for the specific language governing permissions and
1516 * limitations under the License.
1517 */class hK{constructor(e){this.Io=e.Io,this.To=e.To}Eo(e){this.Ao=e}Ro(e){this.Vo=e}mo(e){this.fo=e}onMessage(e){this.po=e}close(){this.To()}send(e){this.Io(e)}yo(){this.Ao()}wo(){this.Vo()}So(e){this.fo(e)}bo(e){this.po(e)}}/**
1518 * @license
1519 * Copyright 2017 Google LLC
1520 *
1521 * Licensed under the Apache License, Version 2.0 (the "License");
1522 * you may not use this file except in compliance with the License.
1523 * You may obtain a copy of the License at
1524 *
1525 *   http://www.apache.org/licenses/LICENSE-2.0
1526 *
1527 * Unless required by applicable law or agreed to in writing, software
1528 * distributed under the License is distributed on an "AS IS" BASIS,
1529 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
1530 * See the License for the specific language governing permissions and
1531 * limitations under the License.
1532 */const Yt="WebChannelConnection";class fK extends class{constructor(a){this.databaseInfo=a,this.databaseId=a.databaseId;const n=a.ssl?"https":"http",i=encodeURIComponent(this.databaseId.projectId),r=encodeURIComponent(this.databaseId.database);this.Do=n+"://"+a.host,this.vo=`projects/${i}/databases/${r}`,this.Co=this.databaseId.database==="(default)"?`project_id=${i}`:`project_id=${i}&database_id=${r}`}get Fo(){return!1}Mo(a,n,i,r,o){const l=j0(),c=this.xo(a,n.toUriEncodedString());Y("RestConnection",`Sending RPC '${a}' ${l}:`,c,i);const d={"google-cloud-resource-prefix":this.vo,"x-goog-request-params":this.Co};return this.Oo(d,r,o),this.No(a,c,d,i).then(u=>(Y("RestConnection",`Received RPC '${a}' ${l}: `,u),u),u=>{throw wl("RestConnection",`RPC '${a}' ${l} failed with error: `,u,"url: ",c,"request:",i),u})}Lo(a,n,i,r,o,l){return this.Mo(a,n,i,r,o)}Oo(a,n,i){a["X-Goog-Api-Client"]=function(){return"gl-js/ fire/"+Gl}(),a["Content-Type"]="text/plain",this.databaseInfo.appId&&(a["X-Firebase-GMPID"]=this.databaseInfo.appId),n&&n.headers.forEach((r,o)=>a[o]=r),i&&i.headers.forEach((r,o)=>a[o]=r)}xo(a,n){const i=mK[a];return`${this.Do}/v1/${n}:${i}`}terminate(){}}{constructor(e){super(e),this.forceLongPolling=e.forceLongPolling,this.autoDetectLongPolling=e.autoDetectLongPolling,this.useFetchStreams=e.useFetchStreams,this.longPollingOptions=e.longPollingOptions}No(e,a,n,i){const r=j0();return new Promise((o,l)=>{const c=new KR;c.setWithCredentials(!0),c.listenOnce(JR.COMPLETE,()=>{try{switch(c.getLastErrorCode()){case Rm.NO_ERROR:const u=c.getResponseJson();Y(Yt,`XHR for RPC '${e}' ${r} received:`,JSON.stringify(u)),o(u);break;case Rm.TIMEOUT:Y(Yt,`RPC '${e}' ${r} timed out`),l(new X(z.DEADLINE_EXCEEDED,"Request time out"));break;case Rm.HTTP_ERROR:const p=c.getStatus();if(Y(Yt,`RPC '${e}' ${r} failed with status:`,p,"response text:",c.getResponseText()),p>0){let m=c.getResponseJson();Array.isArray(m)&&(m=m[0]);const h=m==null?void 0:m.error;if(h&&h.status&&h.message){const g=function(x){const v=x.toLowerCase().replace(/_/g,"-");return Object.values(z).indexOf(v)>=0?v:z.UNKNOWN}(h.status);l(new X(g,h.message))}else l(new X(z.UNKNOWN,"Server responded with status "+c.getStatus()))}else l(new X(z.UNAVAILABLE,"Connection failed."));break;default:pe()}}finally{Y(Yt,`RPC '${e}' ${r} completed.`)}});const d=JSON.stringify(i);Y(Yt,`RPC '${e}' ${r} sending request:`,i),c.send(a,"POST",d,n,15)})}Bo(e,a,n){const i=j0(),r=[this.Do,"/","google.firestore.v1.Firestore","/",e,"/channel"],o=YR(),l=XR(),c={httpSessionIdParam:"gsessionid",initMessageHeaders:{},messageUrlParams:{database:`projects/${this.databaseId.projectId}/databases/${this.databaseId.database}`},sendRawJson:!0,supportsCrossDomainXhr:!0,internalChannelParams:{forwardChannelRequestTimeoutMs:6e5},forceLongPolling:this.forceLongPolling,detectBufferingProxy:this.autoDetectLongPolling},d=this.longPollingOptions.timeoutSeconds;d!==void 0&&(c.longPollingTimeout=Math.round(1e3*d)),this.useFetchStreams&&(c.useFetchStreams=!0),this.Oo(c.initMessageHeaders,a,n),c.encodeInitMessageHeaders=!0;const u=r.join("");Y(Yt,`Creating RPC '${e}' stream ${i}: ${u}`,c);const p=o.createWebChannel(u,c);let m=!1,h=!1;const g=new hK({Io:x=>{h?Y(Yt,`Not sending because RPC '${e}' stream ${i} is closed:`,x):(m||(Y(Yt,`Opening RPC '${e}' stream ${i} transport.`),p.open(),m=!0),Y(Yt,`RPC '${e}' stream ${i} sending:`,x),p.send(x))},To:()=>p.close()}),y=(x,v,w)=>{x.listen(v,S=>{try{w(S)}catch(T){setTimeout(()=>{throw T},0)}})};return y(p,Vc.EventType.OPEN,()=>{h||(Y(Yt,`RPC '${e}' stream ${i} transport opened.`),g.yo())}),y(p,Vc.EventType.CLOSE,()=>{h||(h=!0,Y(Yt,`RPC '${e}' stream ${i} transport closed`),g.So())}
1532),y(p,Vc.EventType.ERROR,x=>{h||(h=!0,wl(Yt,`RPC '${e}' stream ${i} transport errored:`,x),g.So(new X(z.UNAVAILABLE,"The operation could not be completed")))}),y(p,Vc.EventType.MESSAGE,x=>{var v;if(!h){const w=x.data[0];Oe(!!w);const S=w,T=S.error||((v=S[0])===null||v===void 0?void 0:v.error);if(T){Y(Yt,`RPC '${e}' stream ${i} received error:`,T);const P=T.status;let M=function(j){const N=mt[j];if(N!==void 0)return SL(N)}(P),C=T.message;M===void 0&&(M=z.INTERNAL,C="Unknown error status: "+P+" with message "+T.message),h=!0,g.So(new X(M,C)),p.close()}else Y(Yt,`RPC '${e}' stream ${i} received:`,w),g.bo(w)}}),y(l,QR.STAT_EVENT,x=>{x.stat===Yv.PROXY?Y(Yt,`RPC '${e}' stream ${i} detected buffering proxy`):x.stat===Yv.NOPROXY&&Y(Yt,`RPC '${e}' stream ${i} detected no buffering proxy`)}),setTimeout(()=>{g.wo()},0),g}}function T0(){return typeof document<"u"?document:null}/**
1533 * @license
1534 * Copyright 2020 Google LLC
1535 *
1536 * Licensed under the Apache License, Version 2.0 (the "License");
1537 * you may not use this file except in compliance with the License.
1538 * You may obtain a copy of the License at
1539 *
1540 *   http://www.apache.org/licenses/LICENSE-2.0
1541 *
1542 * Unless required by applicable law or agreed to in writing, software
1543 * distributed under the License is distributed on an "AS IS" BASIS,
1544 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
1545 * See the License for the specific language governing permissions and
1546 * limitations under the License.
1547 */function bg(t){return new AG(t,!0)}/**
1548 * @license
1549 * Copyright 2017 Google LLC
1550 *
1551 * Licensed under the Apache License, Version 2.0 (the "License");
1552 * you may not use this file except in compliance with the License.
1553 * You may obtain a copy of the License at
1554 *
1555 *   http://www.apache.org/licenses/LICENSE-2.0
1556 *
1557 * Unless required by applicable law or agreed to in writing, software
1558 * distributed under the License is distributed on an "AS IS" BASIS,
1559 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
1560 * See the License for the specific language governing permissions and
1561 * limitations under the License.
1562 */class OL{constructor(e,a,n=1e3,i=1.5,r=6e4){this.ui=e,this.timerId=a,this.ko=n,this.qo=i,this.Qo=r,this.Ko=0,this.$o=null,this.Uo=Date.now(),this.reset()}reset(){this.Ko=0}Wo(){this.Ko=this.Qo}Go(e){this.cancel();const a=Math.floor(this.Ko+this.zo()),n=Math.max(0,Date.now()-this.Uo),i=Math.max(0,a-n);i>0&&Y("ExponentialBackoff",`Backing off for ${i} ms (base delay: ${this.Ko} ms, delay with jitter: ${a} ms, last attempt: ${n} ms ago)`),this.$o=this.ui.enqueueAfterDelay(this.timerId,i,()=>(this.Uo=Date.now(),e())),this.Ko*=this.qo,this.Ko<this.ko&&(this.Ko=this.ko),this.Ko>this.Qo&&(this.Ko=this.Qo)}jo(){this.$o!==null&&(this.$o.skipDelay(),this.$o=null)}cancel(){this.$o!==null&&(this.$o.cancel(),this.$o=null)}zo(){return(Math.random()-.5)*this.Ko}}/**
1563 * @license
1564 * Copyright 2017 Google LLC
1565 *
1566 * Licensed under the Apache License, Version 2.0 (the "License");
1567 * you may not use this file except in compliance with the License.
1568 * You may obtain a copy of the License at
1569 *
1570 *   http://www.apache.org/licenses/LICENSE-2.0
1571 *
1572 * Unless required by applicable law or agreed to in writing, software
1573 * distributed under the License is distributed on an "AS IS" BASIS,
1574 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
1575 * See the License for the specific language governing permissions and
1576 * limitations under the License.
1577 */class ML{constructor(e,a,n,i,r,o,l,c){this.ui=e,this.Ho=n,this.Jo=i,this.connection=r,this.authCredentialsProvider=o,this.appCheckCredentialsProvider=l,this.listener=c,this.state=0,this.Yo=0,this.Zo=null,this.Xo=null,this.stream=null,this.e_=0,this.t_=new OL(e,a)}n_(){return this.state===1||this.state===5||this.r_()}r_(){return this.state===2||this.state===3}start(){this.e_=0,this.state!==4?this.auth():this.i_()}async stop(){this.n_()&&await this.close(0)}s_(){this.state=0,this.t_.reset()}o_(){this.r_()&&this.Zo===null&&(this.Zo=this.ui.enqueueAfterDelay(this.Ho,6e4,()=>this.__()))}a_(e){this.u_(),this.stream.send(e)}async __(){if(this.r_())return this.close(0)}u_(){this.Zo&&(this.Zo.cancel(),this.Zo=null)}
1577c_(){this.Xo&&(this.Xo.cancel(),this.Xo=null)}async close(e,a){this.u_(),this.c_(),this.t_.cancel(),this.Yo++,e!==4?this.t_.reset():a&&a.code===z.RESOURCE_EXHAUSTED?(Vi(a.toString()),Vi("Using maximum backoff delay to prevent overloading the backend."),this.t_.Wo()):a&&a.code===z.UNAUTHENTICATED&&this.state!==3&&(this.authCredentialsProvider.invalidateToken(),this.appCheckCredentialsProvider.invalidateToken()),this.stream!==null&&(this.l_(),this.stream.close(),this.stream=null),this.state=e,await this.listener.mo(a)}l_(){}auth(){this.state=1;const e=this.h_(this.Yo),a=this.Yo;Promise.all([this.authCredentialsProvider.getToken(),this.appCheckCredentialsProvider.getToken()]).then(([n,i])=>{this.Yo===a&&this.P_(n,i)},n=>{e(()=>{const i=new X(z.UNKNOWN,"Fetching auth token failed: "+n.message);return this.I_(i)})})}P_(e,a){const n=this.h_(this.Yo);this.stream=this.T_(e,a),this.stream.Eo(()=>{n(()=>this.listener.Eo())}),this.stream.Ro(()=>{n(()=>(this.state=2,this.Xo=this.ui.enqueueAfterDelay(this.Jo,1e4,()=>(this.r_()&&(this.state=3),Promise.resolve())),this.listener.Ro()))}),this.stream.mo(i=>{n(()=>this.I_(i))}),this.stream.onMessage(i=>{n(()=>++this.e_==1?this.E_(i):this.onNext(i))})}i_(){this.state=5,this.t_.Go(async()=>{this.state=0,this.start()})}I_(e){return Y("PersistentStream",`close with error: ${e}`),this.stream=null,this.close(4,e)}h_(e){return a=>{this.ui.enqueueAndForget(()=>this.Yo===e?a():(Y("PersistentStream","stream callback skipped by getCloseGuardedDispatcher."),Promise.resolve()))}}}class gK extends ML{constructor(e,a,n,i,r,o){super(e,"listen_stream_connection_backoff","listen_stream_idle","health_check_timeout",a,n,i,o),this.serializer=r}T_(e,a){return this.connection.Bo("Listen",e,a)}E_(e){return this.onNext(e)}onNext(e){this.t_.reset();const a=jG(this.serializer,e),n=function(r){if(!("targetChange"in r))return me.min();const o=r.targetChange;return o.targetIds&&o.targetIds.length?me.min():o.readTime?ti(o.readTime):me.min()}(e);return this.listener.d_(a,n)}A_(e){const a={};a.database=lb(this.serializer),a.addTarget=function(r,o){let l;const c=o.target;if(l=ab(c)?{documents:IG(r,c)}:{query:PG(r,c)._t},l.targetId=o.targetId,o.resumeToken.approximateByteSize()>0){l.resumeToken=EL(r,o.resumeToken);const d=rb(r,o.expectedCount);d!==null&&(l.expectedCount=d)}else if(o.snapshotVersion.compareTo(me.min())>0){l.readTime=Oh(r,o.snapshotVersion.toTimestamp());const d=rb(r,o.expectedCount);d!==null&&(l.expectedCount=d)}return l}(this.serializer,e);const n=LG(this.serializer,e);n&&(a.labels=n),this.a_(a)}R_(e){const a={};a.database=lb(this.serializer),a.removeTarget=e,this.a_(a)}}class yK extends ML{constructor(e,a,n,i,r,o){super(e,"write_stream_connection_backoff","write_stream_idle","health_check_timeout",a,n,i,o),this.serializer=r}get V_(){return this.e_>0}start(){this.lastStreamToken=void 0,super.start()}l_(){this.V_&&this.m_([])}T_(e,a){return this.connection.Bo("Write",e,a)}E_(e){return Oe(!!e.streamToken),this.lastStreamToken=e.streamToken,Oe(!e.writeResults||e.writeResults.length===0),this.listener.f_()}onNext(e){Oe(!!e.streamToken),this.lastStreamToken=e.streamToken,this.t_.reset();const a=NG(e.writeResults,e.commitTime),n=ti(e.commitTime);return this.listener.g_(n,a)}p_(){const e={};e.database=lb(this.serializer),this.a_(e)}m_(e){const a={streamToken:this.lastStreamToken,writes:e.map(n=>TG(this.serializer,n))};this.a_(a)}}/**
1578 * @license
1579 * Copyright 2017 Google LLC
1580 *
1581 * Licensed under the Apache License, Version 2.0 (the "License");
1582 * you may not use this file except in compliance with the License.
1583 * You may obtain a copy of the License at
1584 *
1585 *   http://www.apache.org/licenses/LICENSE-2.0
1586 *
1587 * Unless required by applicable law or agreed to in writing, software
1588 * distributed under the License is distributed on an "AS IS" BASIS,
1589 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
1590 * See the License for the specific language governing permissions and
1591 * limitations under the License.
1592 */class xK extends class{}{constructor(e,a,n,i){super(),this.authCredentials=e,this.appCheckCredentials=a,this.connection=n,this.serializer
1592=i,this.y_=!1}w_(){if(this.y_)throw new X(z.FAILED_PRECONDITION,"The client has already been terminated.")}Mo(e,a,n,i){return this.w_(),Promise.all([this.authCredentials.getToken(),this.appCheckCredentials.getToken()]).then(([r,o])=>this.connection.Mo(e,ob(a,n),i,r,o)).catch(r=>{throw r.name==="FirebaseError"?(r.code===z.UNAUTHENTICATED&&(this.authCredentials.invalidateToken(),this.appCheckCredentials.invalidateToken()),r):new X(z.UNKNOWN,r.toString())})}Lo(e,a,n,i,r){return this.w_(),Promise.all([this.authCredentials.getToken(),this.appCheckCredentials.getToken()]).then(([o,l])=>this.connection.Lo(e,ob(a,n),i,o,l,r)).catch(o=>{throw o.name==="FirebaseError"?(o.code===z.UNAUTHENTICATED&&(this.authCredentials.invalidateToken(),this.appCheckCredentials.invalidateToken()),o):new X(z.UNKNOWN,o.toString())})}terminate(){this.y_=!0,this.connection.terminate()}}class vK{constructor(e,a){this.asyncQueue=e,this.onlineStateHandler=a,this.state="Unknown",this.S_=0,this.b_=null,this.D_=!0}v_(){this.S_===0&&(this.C_("Unknown"),this.b_=this.asyncQueue.enqueueAfterDelay("online_state_timeout",1e4,()=>(this.b_=null,this.F_("Backend didn't respond within 10 seconds."),this.C_("Offline"),Promise.resolve())))}M_(e){this.state==="Online"?this.C_("Unknown"):(this.S_++,this.S_>=1&&(this.x_(),this.F_(`Connection failed 1 times. Most recent error: ${e.toString()}`),this.C_("Offline")))}set(e){this.x_(),this.S_=0,e==="Online"&&(this.D_=!1),this.C_(e)}C_(e){e!==this.state&&(this.state=e,this.onlineStateHandler(e))}F_(e){const a=`Could not reach Cloud Firestore backend. ${e}
1593This typically indicates that your device does not have a healthy Internet connection at the moment. The client will operate in offline mode until it is able to successfully connect to the backend.`;this.D_?(Vi(a),this.D_=!1):Y("OnlineStateTracker",a)}x_(){this.b_!==null&&(this.b_.cancel(),this.b_=null)}}/**
1594 * @license
1595 * Copyright 2017 Google LLC
1596 *
1597 * Licensed under the Apache License, Version 2.0 (the "License");
1598 * you may not use this file except in compliance with the License.
1599 * You may obtain a copy of the License at
1600 *
1601 *   http://www.apache.org/licenses/LICENSE-2.0
1602 *
1603 * Unless required by applicable law or agreed to in writing, software
1604 * distributed under the License is distributed on an "AS IS" BASIS,
1605 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
1606 * See the License for the specific language governing permissions and
1607 * limitations under the License.
1608 */class bK{constructor(e,a,n,i,r){this.localStore=e,this.datastore=a,this.asyncQueue=n,this.remoteSyncer={},this.O_=[],this.N_=new Map,this.L_=new Set,this.B_=[],this.k_=r,this.k_._o(o=>{n.enqueueAndForget(async()=>{ms(this)&&(Y("RemoteStore","Restarting streams for network reachability change."),await async function(c){const d=he(c);d.L_.add(4),await zu(d),d.q_.set("Unknown"),d.L_.delete(4),await wg(d)}(this))})}),this.q_=new vK(n,i)}}async function wg(t){if(ms(t))for(const e of t.B_)await e(!0)}async function zu(t){for(const e of t.B_)await e(!1)}function DL(t,e){const a=he(t);a.N_.has(e.targetId)||(a.N_.set(e.targetId,e),ok(a)?rk(a):Jl(a).r_()&&ik(a,e))}function nk(t,e){const a=he(t),n=Jl(a);a.N_.delete(e),n.r_()&&qL(a,e),a.N_.size===0&&(n.r_()?n.o_():ms(a)&&a.q_.set("Unknown"))}function ik(t,e){if(t.Q_.xe(e.targetId),e.resumeToken.approximateByteSize()>0||e.snapshotVersion.compareTo(me.min())>0){const a=t.remoteSyncer.getRemoteKeysForTarget(e.targetId).size;e=e.withExpectedCount(a)}Jl(t).A_(e)}function qL(t,e){t.Q_.xe(e),Jl(t).R_(e)}function rk(t){t.Q_=new wG({getRemoteKeysForTarget:e=>t.remoteSyncer.getRemoteKeysForTarget(e),ot:e=>t.N_.get(e)||null,tt:()=>t.datastore.serializer.databaseId}),Jl(t).start(),t.q_.v_()}function ok(t){return ms(t)&&!Jl(t).n_()&&t.N_.size>0}function ms(t){return he(t).L_.size===0}function zL(t){t.Q_=void 0}async function wK(t){t.q_.set("Online")}async function kK(t){t.N_.forEach((e,a)=>{ik(t,e)})}async function SK(t,e){zL(t),ok(t)?(t.q_.M_(e),rk(t)):t.q_.set("Unknown")}async function _K(t,e,a){if(t.q_.set("Online"),e instanceof AL&&e.state===2&&e.cause)try{await async function(i,r){const o=r.cause;for(const l of r.targetIds)i.N_.has(l)&&(await i.remoteSyncer.rejectListen(l,o),i.N_.delete(l),i.Q_.removeTarget(l))}(t,e)}catch(n){Y("RemoteStore","Failed to remove targets %s: %s ",e.targetIds.join(","),n),await Mh(t,n)}else if(e instanceof Mm?t.Q_.Ke(e):e instanceof _L?t.Q_.He(e):t.Q_.We(e),!a.isEqual(me.min()))try{const n=await LL(t.localStore);a.compareTo(n)>=0&&await function(r,o){const l=r.Q_.rt(o);
1608return l.targetChanges.forEach((c,d)=>{if(c.resumeToken.approximateByteSize()>0){const u=r.N_.get(d);u&&r.N_.set(d,u.withResumeToken(c.resumeToken,o))}}),l.targetMismatches.forEach((c,d)=>{const u=r.N_.get(c);if(!u)return;r.N_.set(c,u.withResumeToken($t.EMPTY_BYTE_STRING,u.snapshotVersion)),qL(r,c);const p=new yr(u.target,c,d,u.sequenceNumber);ik(r,p)}),r.remoteSyncer.applyRemoteEvent(l)}(t,a)}catch(n){Y("RemoteStore","Failed to raise snapshot:",n),await Mh(t,n)}}async function Mh(t,e,a){if(!Ou(e))throw e;t.L_.add(1),await zu(t),t.q_.set("Offline"),a||(a=()=>LL(t.localStore)),t.asyncQueue.enqueueRetryable(async()=>{Y("RemoteStore","Retrying IndexedDB access"),await a(),t.L_.delete(1),await wg(t)})}function VL(t,e){return e().catch(a=>Mh(t,a,e))}async function kg(t){const e=he(t),a=Br(e);let n=e.O_.length>0?e.O_[e.O_.length-1].batchId:-1;for(;AK(e);)try{const i=await lK(e.localStore,n);if(i===null){e.O_.length===0&&a.o_();break}n=i.batchId,EK(e,i)}catch(i){await Mh(e,i)}HL(e)&&FL(e)}function AK(t){return ms(t)&&t.O_.length<10}function EK(t,e){t.O_.push(e);const a=Br(t);a.r_()&&a.V_&&a.m_(e.mutations)}function HL(t){return ms(t)&&!Br(t).n_()&&t.O_.length>0}function FL(t){Br(t).start()}async function CK(t){Br(t).p_()}async function jK(t){const e=Br(t);for(const a of t.O_)e.m_(a.mutations)}async function TK(t,e,a){const n=t.O_.shift(),i=Xw.from(n,e,a);await VL(t,()=>t.remoteSyncer.applySuccessfulWrite(i)),await kg(t)}async function NK(t,e){e&&Br(t).V_&&await async function(n,i){if(function(o){return xG(o)&&o!==z.ABORTED}(i.code)){const r=n.O_.shift();Br(n).s_(),await VL(n,()=>n.remoteSyncer.rejectFailedWrite(r.batchId,i)),await kg(n)}}(t,e),HL(t)&&FL(t)}async function wC(t,e){const a=he(t);a.asyncQueue.verifyOperationInProgress(),Y("RemoteStore","RemoteStore received new credentials");const n=ms(a);a.L_.add(3),await zu(a),n&&a.q_.set("Unknown"),await a.remoteSyncer.handleCredentialChange(e),a.L_.delete(3),await wg(a)}async function IK(t,e){const a=he(t);e?(a.L_.delete(2),await wg(a)):e||(a.L_.add(2),await zu(a),a.q_.set("Unknown"))}function Jl(t){return t.K_||(t.K_=function(a,n,i){const r=he(a);return r.w_(),new gK(n,r.connection,r.authCredentials,r.appCheckCredentials,r.serializer,i)}(t.datastore,t.asyncQueue,{Eo:wK.bind(null,t),Ro:kK.bind(null,t),mo:SK.bind(null,t),d_:_K.bind(null,t)}),t.B_.push(async e=>{e?(t.K_.s_(),ok(t)?rk(t):t.q_.set("Unknown")):(await t.K_.stop(),zL(t))})),t.K_}function Br(t){return t.U_||(t.U_=function(a,n,i){const r=he(a);return r.w_(),new yK(n,r.connection,r.authCredentials,r.appCheckCredentials,r.serializer,i)}(t.datastore,t.asyncQueue,{Eo:()=>Promise.resolve(),Ro:CK.bind(null,t),mo:NK.bind(null,t),f_:jK.bind(null,t),g_:TK.bind(null,t)}),t.B_.push(async e=>{e?(t.U_.s_(),await kg(t)):(await t.U_.stop(),t.O_.length>0&&(Y("RemoteStore",`Stopping write stream with ${t.O_.length} pending writes`),t.O_=[]))})),t.U_}/**
1609 * @license
1610 * Copyright 2017 Google LLC
1611 *
1612 * Licensed under the Apache License, Version 2.0 (the "License");
1613 * you may not use this file except in compliance with the License.
1614 * You may obtain a copy of the License at
1615 *
1616 *   http://www.apache.org/licenses/LICENSE-2.0
1617 *
1618 * Unless required by applicable law or agreed to in writing, software
1619 * distributed under the License is distributed on an "AS IS" BASIS,
1620 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
1621 * See the License for the specific language governing permissions and
1622 * limitations under the License.
1623 */class sk{constructor(e,a,n,i,r){this.asyncQueue=e,this.timerId=a,this.targetTimeMs=n,this.op=i,this.removalCallback=r,this.deferred=new Ti,this.then=this.deferred.promise.then.bind(this.deferred.promise),this.deferred.promise.catch(o=>{})}get promise(){return this.deferred.promise}static createAndSchedule(e,a,n,i,r){const o=Date.now()+n,l=new sk(e,a,o,i,r);return l.start(n),l}start(e){this.timerHandle=setTimeout(()=>this.handleDelayElapsed(),e)}skipDelay(){return this.handleDelayElapsed()}cancel(e){this.timerHandle!==null&&(this.clearTimeout(),this.deferred.reject(new X(z.CANCELLED,"Operation cancelled"+(e?": "+e:""))))}handleDelayElapsed(){this.asyncQueue.enqueueAndForget(()=>this.timerHandle!==null?(this.clearTimeout(),this.op().then(e=>this.deferred.resolve(e))):Promise.resolve())}clearTimeout(){this.timerHandle!==null&&(this.removalCallback(this),clearTimeout(this.timerHandle),this.timerHandle=null)}}function lk(t,e){if(Vi("AsyncQueue",`${e}: ${t}`),Ou(t))return new X(z.UNAVAILABLE,`${e}: ${t}`);throw t}/**
1624 * @license
1625 * Copyright 2017 Google LLC
1626 *
1627 * Licensed under the Apache License, Version 2.0 (the "License");
1628 * you may not use this file except in compliance with the License.
1629 * You may obtain a copy of the License at
1630 *
1631 *   http://www.apache.org/licenses/LICENSE-2.0
1632 *
1633 * Unless required by applicable law or agreed to in writing, software
1634 * distributed under the License is distributed on an "AS IS" BASIS,
1635 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
1636 * See the License for the specific language governing permissions and
1637 * limitations under the License.
1638 */class ol{constructor(e){this.comparator=e?(a,n)=>e(a,n)||oe.comparator(a.key,n.key):(a,n)=>oe.comparator(a.key,n.key),this.keyedMap=Hc(),this.sortedSet=new tt(this.comparator)}static emptySet(e){return new ol(e.comparator)}has(e){return this.keyedMap.get(e)!=null}get(e){return this.keyedMap.get(e)}first(){return this.sortedSet.minKey()}last(){return this.sortedSet.maxKey()}isEmpty(){return this.sortedSet.isEmpty()}indexOf(e){const a=this.keyedMap.get(e);return a?this.sortedSet.indexOf(a):-1}get size(){return this.sortedSet.size}forEach(e){this.sortedSet.inorderTraversal((a,n)=>(e(a),!1))}add(e){const a=this.delete(e.key);return a.copy(a.keyedMap.insert(e.key,e),a.sortedSet.insert(e,null))}delete(e){const a=this.get(e);return a?this.copy(this.keyedMap.remove(e),this.sortedSet.remove(a)):this}isEqual(e){if(!(e instanceof ol)||this.size!==e.size)return!1;const a=this.sortedSet.getIterator(),n=e.sortedSet.getIterator();for(;a.hasNext();){const i=a.getNext().key,r=n.getNext().key;if(!i.isEqual(r))return!1}return!0}toString(){const e=[];return this.forEach(a=>{e.push(a.toString())}),e.length===0?"DocumentSet ()":`DocumentSet (
1639  `+e.join(`  
1640`)+`
1641)`}copy(e,a){const n=new ol;return n.comparator=this.comparator,n.keyedMap=e,n.sortedSet=a,n}}/**
1642 * @license
1643 * Copyright 2017 Google LLC
1644 *
1645 * Licensed under the Apache License, Version 2.0 (the "License");
1646 * you may not use this file except in compliance with the License.
1647 * You may obtain a copy of the License at
1648 *
1649 *   http://www.apache.org/licenses/LICENSE-2.0
1650 *
1651 * Unless required by applicable law or agreed to in writing, software
1652 * distributed under the License is distributed on an "AS IS" BASIS,
1653 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
1654 * See the License for the specific language governing permissions and
1655 * limitations under the License.
1656 */class kC{constructor(){this.W_=new tt(oe.comparator)}track(e){const a=e.doc.key,n=this.W_.get(a);n?e.type!==0&&n.type===3?this.W_=this.W_.insert(a,e):e.type===3&&n.type!==1?this.W_=this.W_.insert(a,{type:n.type,doc:e.doc}):e.type===2&&n.type===2?this.W_=this.W_.insert(a,{type:2,doc:e.doc}):e.type===2&&n.type===0?this.W_=this.W_.insert(a,{type:0,doc:e.doc}):e.type===1&&n.type===0?this.W_=this.W_.remove(a):e.type===1&&n.type===2?this.W_=this.W_.insert(a,{type:1,doc:n.doc}):e.type===0&&n.type===1?this.W_=this.W_.insert(a,{type:2,doc:e.doc}):pe():this.W_=this.W_.insert(a,e)}G_(){const e=[];return this.W_.inorderTraversal((a,n)=>{e.push(n)}),e}}class El{constructor(e,a,n,i,r,o,l,c,d){this.query=e,this.docs=a,this.oldDocs=n,this.docChanges=i,this.mutatedKeys=r,this.fromCache=o,this.syncStateChanged=l,this.excludesMetadataChanges=c,this.hasCachedResults=d}static fromInitialDocuments(e,a,n,i,r){const o=[];return a.forEach(l=>{o.push({type:0,doc:l})}),new El(e,a,ol.emptySet(a),o,n,i,!0,!1,r)}get hasPendingWrites(){return!this.mutatedKeys.isEmpty()}isEqual(e){if(!(this.fromCache===e.fromCache&&this.hasCachedResults===e.hasCachedResults&&this.syncStateChanged===e.syncStateChanged&&this.mutatedKeys.isEqual(e.mutatedKeys)&&fg(this.query,e.query)&&this.docs.isEqual(e.docs)&&this.oldDocs.isEqual(e.oldDocs)))return!1;const a=this.docChanges,n=e.docChanges;if(a.length!==n.length)return!1;for(let i=0;i<a.length;i++)if(a[i].type!==n[i].type||!a[i].doc.isEqual(n[i].doc))return!1;return!0}}/**
1657 * @license
1658 * Copyright 2017 Google LLC
1659 *
1660 * Licensed under the Apache License, Version 2.0 (the "License");
1661 * you may not use this file except in compliance with the License.
1662 * You may obtain a copy of the License at
1663 *
1664 *   http://www.apache.org/licenses/LICENSE-2.0
1665 *
1666 * Unless required by applicable law or agreed to in writing, softw
1666are
1667 * distributed under the License is distributed on an "AS IS" BASIS,
1668 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
1669 * See the License for the specific language governing permissions and
1670 * limitations under the License.
1671 */class PK{constructor(){this.z_=void 0,this.j_=[]}H_(){return this.j_.some(e=>e.J_())}}class RK{constructor(){this.queries=SC(),this.onlineState="Unknown",this.Y_=new Set}terminate(){(function(a,n){const i=he(a),r=i.queries;i.queries=SC(),r.forEach((o,l)=>{for(const c of l.j_)c.onError(n)})})(this,new X(z.ABORTED,"Firestore shutting down"))}}function SC(){return new Kl(t=>uL(t),fg)}async function BL(t,e){const a=he(t);let n=3;const i=e.query;let r=a.queries.get(i);r?!r.H_()&&e.J_()&&(n=2):(r=new PK,n=e.J_()?0:1);try{switch(n){case 0:r.z_=await a.onListen(i,!0);break;case 1:r.z_=await a.onListen(i,!1);break;case 2:await a.onFirstRemoteStoreListen(i)}}catch(o){const l=lk(o,`Initialization of query '${Cs(e.query)}' failed`);return void e.onError(l)}a.queries.set(i,r),r.j_.push(e),e.Z_(a.onlineState),r.z_&&e.X_(r.z_)&&ck(a)}async function UL(t,e){const a=he(t),n=e.query;let i=3;const r=a.queries.get(n);if(r){const o=r.j_.indexOf(e);o>=0&&(r.j_.splice(o,1),r.j_.length===0?i=e.J_()?0:1:!r.H_()&&e.J_()&&(i=2))}switch(i){case 0:return a.queries.delete(n),a.onUnlisten(n,!0);case 1:return a.queries.delete(n),a.onUnlisten(n,!1);case 2:return a.onLastRemoteStoreUnlisten(n);default:return}}function LK(t,e){const a=he(t);let n=!1;for(const i of e){const r=i.query,o=a.queries.get(r);if(o){for(const l of o.j_)l.X_(i)&&(n=!0);o.z_=i}}n&&ck(a)}function OK(t,e,a){const n=he(t),i=n.queries.get(e);if(i)for(const r of i.j_)r.onError(a);n.queries.delete(e)}function ck(t){t.Y_.forEach(e=>{e.next()})}var db,_C;(_C=db||(db={})).ea="default",_C.Cache="cache";class $L{constructor(e,a,n){this.query=e,this.ta=a,this.na=!1,this.ra=null,this.onlineState="Unknown",this.options=n||{}}X_(e){if(!this.options.includeMetadataChanges){const n=[];for(const i of e.docChanges)i.type!==3&&n.push(i);e=new El(e.query,e.docs,e.oldDocs,n,e.mutatedKeys,e.fromCache,e.syncStateChanged,!0,e.hasCachedResults)}let a=!1;return this.na?this.ia(e)&&(this.ta.next(e),a=!0):this.sa(e,this.onlineState)&&(this.oa(e),a=!0),this.ra=e,a}onError(e){this.ta.error(e)}Z_(e){this.onlineState=e;let a=!1;return this.ra&&!this.na&&this.sa(this.ra,e)&&(this.oa(this.ra),a=!0),a}sa(e,a){if(!e.fromCache||!this.J_())return!0;const n=a!=="Offline";return(!this.options._a||!n)&&(!e.docs.isEmpty()||e.hasCachedResults||a==="Offline")}ia(e){if(e.docChanges.length>0)return!0;const a=this.ra&&this.ra.hasPendingWrites!==e.hasPendingWrites;return!(!e.syncStateChanged&&!a)&&this.options.includeMetadataChanges===!0}oa(e){e=El.fromInitialDocuments(e.query,e.docs,e.mutatedKeys,e.fromCache,e.hasCachedResults),this.na=!0,this.ta.next(e)}J_(){return this.options.source!==db.Cache}}/**
1672 * @license
1673 * Copyright 2017 Google LLC
1674 *
1675 * Licensed under the Apache License, Version 2.0 (the "License");
1676 * you may not use this file except in compliance with the License.
1677 * You may obtain a copy of the License at
1678 *
1679 *   http://www.apache.org/licenses/LICENSE-2.0
1680 *
1681 * Unless required by applicable law or agreed to in writing, software
1682 * distributed under the License is distributed on an "AS IS" BASIS,
1683 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
1684 * See the License for the specific language governing permissions and
1685 * limitations under the License.
1686 */class WL{constructor(e){this.key=e}}class GL{constructor(e){this.key=e}}class MK{constructor(e,a){this.query=e,this.Ta=a,this.Ea=null,this.hasCachedResults=!1,this.current=!1,this.da=Se(),this.mutatedKeys=Se(),this.Aa=pL(e),this.Ra=new ol(this.Aa)}get Va(){return this.Ta}ma(e,a){const n=a?a.fa:new kC,i=a?a.Ra:this.Ra;let r=a?a.mutatedKeys:this.mutatedKeys,o=i,l=!1;const c=this.query.limitType==="F"&&i.size===this.query.limit?i.last():null,d=this.query.limitType==="L"&&i.size===this.query.limit?i.first():null;if(e.inorderTraversal((u,p)=>{const m=i.get(u),h=gg(this.query,p)?p:null,g=!!m&&this.mutatedKeys.has(m.ke
1686y),y=!!h&&(h.hasLocalMutations||this.mutatedKeys.has(h.key)&&h.hasCommittedMutations);let x=!1;m&&h?m.data.isEqual(h.data)?g!==y&&(n.track({type:3,doc:h}),x=!0):this.ga(m,h)||(n.track({type:2,doc:h}),x=!0,(c&&this.Aa(h,c)>0||d&&this.Aa(h,d)<0)&&(l=!0)):!m&&h?(n.track({type:0,doc:h}),x=!0):m&&!h&&(n.track({type:1,doc:m}),x=!0,(c||d)&&(l=!0)),x&&(h?(o=o.add(h),r=y?r.add(u):r.delete(u)):(o=o.delete(u),r=r.delete(u)))}),this.query.limit!==null)for(;o.size>this.query.limit;){const u=this.query.limitType==="F"?o.last():o.first();o=o.delete(u.key),r=r.delete(u.key),n.track({type:1,doc:u})}return{Ra:o,fa:n,ns:l,mutatedKeys:r}}ga(e,a){return e.hasLocalMutations&&a.hasCommittedMutations&&!a.hasLocalMutations}applyChanges(e,a,n,i){const r=this.Ra;this.Ra=e.Ra,this.mutatedKeys=e.mutatedKeys;const o=e.fa.G_();o.sort((u,p)=>function(h,g){const y=x=>{switch(x){case 0:return 1;case 2:case 3:return 2;case 1:return 0;default:return pe()}};return y(h)-y(g)}(u.type,p.type)||this.Aa(u.doc,p.doc)),this.pa(n),i=i!=null&&i;const l=a&&!i?this.ya():[],c=this.da.size===0&&this.current&&!i?1:0,d=c!==this.Ea;return this.Ea=c,o.length!==0||d?{snapshot:new El(this.query,e.Ra,r,o,e.mutatedKeys,c===0,d,!1,!!n&&n.resumeToken.approximateByteSize()>0),wa:l}:{wa:l}}Z_(e){return this.current&&e==="Offline"?(this.current=!1,this.applyChanges({Ra:this.Ra,fa:new kC,mutatedKeys:this.mutatedKeys,ns:!1},!1)):{wa:[]}}Sa(e){return!this.Ta.has(e)&&!!this.Ra.has(e)&&!this.Ra.get(e).hasLocalMutations}pa(e){e&&(e.addedDocuments.forEach(a=>this.Ta=this.Ta.add(a)),e.modifiedDocuments.forEach(a=>{}),e.removedDocuments.forEach(a=>this.Ta=this.Ta.delete(a)),this.current=e.current)}ya(){if(!this.current)return[];const e=this.da;this.da=Se(),this.Ra.forEach(n=>{this.Sa(n.key)&&(this.da=this.da.add(n.key))});const a=[];return e.forEach(n=>{this.da.has(n)||a.push(new GL(n))}),this.da.forEach(n=>{e.has(n)||a.push(new WL(n))}),a}ba(e){this.Ta=e.Ts,this.da=Se();const a=this.ma(e.documents);return this.applyChanges(a,!0)}Da(){return El.fromInitialDocuments(this.query,this.Ra,this.mutatedKeys,this.Ea===0,this.hasCachedResults)}}class DK{constructor(e,a,n){this.query=e,this.targetId=a,this.view=n}}class qK{constructor(e){this.key=e,this.va=!1}}class zK{constructor(e,a,n,i,r,o){this.localStore=e,this.remoteStore=a,this.eventManager=n,this.sharedClientState=i,this.currentUser=r,this.maxConcurrentLimboResolutions=o,this.Ca={},this.Fa=new Kl(l=>uL(l),fg),this.Ma=new Map,this.xa=new Set,this.Oa=new tt(oe.comparator),this.Na=new Map,this.La=new ek,this.Ba={},this.ka=new Map,this.qa=Al.kn(),this.onlineState="Unknown",this.Qa=void 0}get isPrimaryClient(){return this.Qa===!0}}async function VK(t,e,a=!0){const n=ZL(t);let i;const r=n.Fa.get(e);return r?(n.sharedClientState.addLocalQueryTarget(r.targetId),i=r.view.Da()):i=await KL(n,e,a,!0),i}async function HK(t,e){const a=ZL(t);await KL(a,e,!0,!1)}async function KL(t,e,a,n){const i=await cK(t.localStore,ei(e)),r=i.targetId,o=t.sharedClientState.addLocalQueryTarget(r,a);let l;return n&&(l=await FK(t,e,r,o==="current",i.resumeToken)),t.isPrimaryClient&&a&&DL(t.remoteStore,i),l}async function FK(t,e,a,n,i){t.Ka=(p,m,h)=>async function(y,x,v,w){let S=x.view.ma(v);S.ns&&(S=await xC(y.localStore,x.query,!1).then(({documents:C})=>x.view.ma(C,S)));const T=w&&w.targetChanges.get(x.targetId),P=w&&w.targetMismatches.get(x.targetId)!=null,M=x.view.applyChanges(S,y.isPrimaryClient,T,P);return EC(y,x.targetId,M.wa),M.snapshot}(t,p,m,h);const r=await xC(t.localStore,e,!0),o=new MK(e,r.Ts),l=o.ma(r.documents),c=qu.createSynthesizedTargetChangeForCurrentChange(a,n&&t.onlineState!=="Offline",i),d=o.applyChanges(l,t.isPrimaryClient,c);EC(t,a,d.wa);const u=new DK(e,a,o);return t.Fa.set(e,u),t.Ma.has(a)?t.Ma.get(a).push(e):t.Ma.set(a,[e]),d.snapshot}async function BK(t,e,a){const n=he(t),i=n.Fa.get(e),r=n.Ma.get(i.targetId);if(r.length>1)return n.Ma.set(i.targetId,r.filter(o=>!fg(o,e))),void n.Fa.delete(e);n.isPrimaryClient?(n.sharedClientState.removeLocalQueryTarget(i.targetId),n.sharedClientState.isActiveQueryTarget(i.targetId)||await cb(n.localStore,i.targetId,!1).then(()=>
1686{n.sharedClientState.clearQueryState(i.targetId),a&&nk(n.remoteStore,i.targetId),ub(n,i.targetId)}).catch(Lu)):(ub(n,i.targetId),await cb(n.localStore,i.targetId,!0))}async function UK(t,e){const a=he(t),n=a.Fa.get(e),i=a.Ma.get(n.targetId);a.isPrimaryClient&&i.length===1&&(a.sharedClientState.removeLocalQueryTarget(n.targetId),nk(a.remoteStore,n.targetId))}async function $K(t,e,a){const n=YK(t);try{const i=await function(o,l){const c=he(o),d=xt.now(),u=l.reduce((h,g)=>h.add(g.key),Se());let p,m;return c.persistence.runTransaction("Locally write mutations","readwrite",h=>{let g=Hi(),y=Se();return c.cs.getEntries(h,u).next(x=>{g=x,g.forEach((v,w)=>{w.isValidDocument()||(y=y.add(v))})}).next(()=>c.localDocuments.getOverlayedDocuments(h,g)).next(x=>{p=x;const v=[];for(const w of l){const S=mG(w,p.get(w.key).overlayedDocument);S!=null&&v.push(new Xr(w.key,S,nL(S.value.mapValue),In.exists(!0)))}return c.mutationQueue.addMutationBatch(h,d,v,l)}).next(x=>{m=x;const v=x.applyToLocalDocumentSet(p,y);return c.documentOverlayCache.saveOverlays(h,x.batchId,v)})}).then(()=>({batchId:m.batchId,changes:hL(p)}))}(n.localStore,e);n.sharedClientState.addPendingMutation(i.batchId),function(o,l,c){let d=o.Ba[o.currentUser.toKey()];d||(d=new tt(je)),d=d.insert(l,c),o.Ba[o.currentUser.toKey()]=d}(n,i.batchId,a),await Vu(n,i.changes),await kg(n.remoteStore)}catch(i){const r=lk(i,"Failed to persist write");a.reject(r)}}async function JL(t,e){const a=he(t);try{const n=await oK(a.localStore,e);
1686e.targetChanges.forEach((i,r)=>{const o=a.Na.get(r);o&&(Oe(i.addedDocuments.size+i.modifiedDocuments.size+i.removedDocuments.size<=1),i.addedDocuments.size>0?o.va=!0:i.modifiedDocuments.size>0?Oe(o.va):i.removedDocuments.size>0&&(Oe(o.va),o.va=!1))}),await Vu(a,n,e)}catch(n){await Lu(n)}}function AC(t,e,a){const n=he(t);if(n.isPrimaryClient&&a===0||!n.isPrimaryClient&&a===1){const i=[];n.Fa.forEach((r,o)=>{const l=o.view.Z_(e);l.snapshot&&i.push(l.snapshot)}),function(o,l){const c=he(o);c.onlineState=l;let d=!1;c.queries.forEach((u,p)=>{for(const m of p.j_)m.Z_(l)&&(d=!0)}),d&&ck(c)}(n.eventManager,e),i.length&&n.Ca.d_(i),n.onlineState=e,n.isPrimaryClient&&n.sharedClientState.setOnlineState(e)}}async function WK(t,e,a){const n=he(t);n.sharedClientState.updateQueryState(e,"rejected",a);const i=n.Na.get(e),r=i&&i.key;if(r){let o=new tt(oe.comparator);o=o.insert(r,aa.newNoDocument(r,me.min()));const l=Se().add(r),c=new vg(me.min(),new Map,new tt(je),o,l);await JL(n,c),n.Oa=n.Oa.remove(r),n.Na.delete(e),dk(n)}else await cb(n.localStore,e,!1).then(()=>ub(n,e,a)).catch(Lu)}async function GK(t,e){const a=he(t),n=e.batch.batchId;try{const i=await rK(a.localStore,e);XL(a,n,null),QL(a,n),a.sharedClientState.updateMutationState(n,"acknowledged"),await Vu(a,i)}catch(i){await Lu(i)}}async function KK(t,e,a){const n=he(t);try{const i=await function(o,l){const c=he(o);return c.persistence.runTransaction("Reject batch","readwrite-primary",d=>{let u;return c.mutationQueue.lookupMutationBatch(d,l).next(p=>
1686(Oe(p!==null),u=p.keys(),c.mutationQueue.removeMutationBatch(d,p))).next(()=>c.mutationQueue.performConsistencyCheck(d)).next(()=>c.documentOverlayCache.removeOverlaysForBatchId(d,u,l)).next(()=>c.localDocuments.recalculateAndSaveOverlaysForDocumentKeys(d,u)).next(()=>c.localDocuments.getDocuments(d,u))})}(n.localStore,e);XL(n,e,a),QL(n,e),n.sharedClientState.updateMutationState(e,"rejected",a),await Vu(n,i)}catch(i){await Lu(i)}}function QL(t,e){(t.ka.get(e)||[]).forEach(a=>{a.resolve()}),t.ka.delete(e)}function XL(t,e,a){const n=he(t);let i=n.Ba[n.currentUser.toKey()];if(i){const r=i.get(e);r&&(a?r.reject(a):r.resolve(),i=i.remove(e)),n.Ba[n.currentUser.toKey()]=i}}function ub(t,e,a=null){t.sharedClientState.removeLocalQueryTarget(e);for(const n of t.Ma.get(e))t.Fa.delete(n),a&&t.Ca.$a(n,a);t.Ma.delete(e),t.isPrimaryClient&&t.La.gr(e).forEach(n=>{t.La.containsKey(n)||YL(t,n)})}function YL(t,e){t.xa.delete(e.path.canonicalString());const a=t.Oa.get(e);a!==null&&(nk(t.remoteStore,a),t.Oa=t.Oa.remove(e),t.Na.delete(a),dk(t))}function EC(t,e,a){for(const n of a)n instanceof WL?(t.La.addReference(n.key,e),JK(t,n)):n instanceof GL?(Y("SyncEngine","Document no longer in limbo: "+n.key),t.La.removeReference(n.key,e),t.La.containsKey(n.key)||YL(t,n.key)):pe()}function JK(t,e){const a=e.key,n=a.path.canonicalString();t.Oa.get(a)||t.xa.has(n)||(Y("SyncEngine","New document in limbo: "+a),t.xa.add(n),dk(t))}function dk(t){for(;t.xa.size>0&&t.Oa.size<t.maxConcurrentLimboResolutions;){const e=t.xa.values().next().value;t.xa.delete(e);const a=new oe(Ue.fromString(e)),n=t.qa.next();t.Na.set(n,new qK(a)),t.Oa=t.Oa.insert(a,n),DL(t.remoteStore,new yr(ei(Kw(a.path)),n,"TargetPurposeLimboResolution",Fw.oe))}}async function Vu(t,e,a){const n=he(t),i=[],r=[],o=[];n.Fa.isEmpty()||(n.Fa.forEach((l,c)=>{o.push(n.Ka(c,e,a).then(d=>{var u;if((d||a)&&n.isPrimaryClient){const p=d?!d.fromCache:(u=a==null?void 0:a.targetChanges.get(c.targetId))===null||u===void 0?void 0:u.current;n.sharedClientState.updateQueryState(c.targetId,p?"current":"not-current")}if(d){i.push(d);const p=ak.Wi(c.targetId,d);r.push(p)}}))}),await Promise.all(o),n.Ca.d_(i),await async function(c,d){const u=he(c);try{await u.persistence.runTransaction("notifyLocalViewChanges","readwrite",p=>H.forEach(d,m=>H.forEach(m.$i,h=>u.persistence.referenceDelegate.addReference(p,m.targetId,h)).next(()=>H.forEach(m.Ui,h=>u.persistence.referenceDelegate.removeReference(p,m.targetId,h)))))}catch(p){if(!Ou(p))throw p;Y("LocalStore","Failed to update sequence numbers: "+p)}for(const p of d){const m=p.targetId;if(!p.fromCache){const h=u.os.get(m),g=h.snapshotVersion,y=h.withLastLimboFreeSnapshotVersion(g);u.os=u.os.insert(m,y)}}}(n.localStore,r))}async function QK(t,e){const a=he(t);if(!a.currentUser.isEqual(e)){Y("SyncEngine","User change. New user:",e.toKey());const n=await RL(a.localStore,e);a.currentUser=e,function(r,o){r.ka.forEach(l=>{l.forEach(c=>{c.reject(new X(z.CANCELLED,o))})}),r.ka.clear()}(a,"'waitForPendingWrites' promise is rejected due to a user change."),a.sharedClientState.handleUserChange(e,n.removedBatchIds,n.addedBatchIds),await Vu(a,n.hs)}}function XK(t,e){const a=he(t),n=a.Na.get(e);if(n&&n.va)return Se().add(n.key);{let i=Se();const r=a.Ma.get(e);if(!r)return i;for(const o of r){const l=a.Fa.get(o);i=i.unionWith(l.view.Va)}return i}}function ZL(t){const e=he(t);return e.remoteStore.remoteSyncer.applyRemoteEvent=JL.bind(null,e),e.remoteStore.remoteSyncer.getRemoteKeysForTarget=XK.bind(null,e),e.remoteStore.remoteSyncer.rejectListen=WK.bind(null,e),e.Ca.d_=LK.bind(null,e.eventManager),e.Ca.$a=OK.bind(null,e.eventManager),e}function YK(t){const e=he(t);return e.remoteStore.remoteSyncer.applySuccessfulWrite=GK.bind(null,e),e.remoteStore.remoteSyncer.rejectFailedWrite=KK.bind(null,e),e}class Dh{constructor(){this.kind="memory",this.synchronizeTabs=!1}async initialize(e){this.serializer=bg(e.databaseInfo.databaseId),this.sharedClientState=this.Wa(e),this.persistence=this.Ga(e),await this.persistence.start(),this.localStore=this.za(e),this.gcScheduler=this.ja(e,this.localStore),this.indexBackfillerScheduler
1686=this.Ha(e,this.localStore)}ja(e,a){return null}Ha(e,a){return null}za(e){return iK(this.persistence,new aK,e.initialUser,this.serializer)}Ga(e){return new ZG(tk.Zr,this.serializer)}Wa(e){return new uK}async terminate(){var e,a;(e=this.gcScheduler)===null||e===void 0||e.stop(),(a=this.indexBackfillerScheduler)===null||a===void 0||a.stop(),this.sharedClientState.shutdown(),await this.persistence.shutdown()}}Dh.provider={build:()=>new Dh};class pb{async initialize(e,a){this.localStore||(this.localStore=e.localStore,this.sharedClientState=e.sharedClientState,this.datastore=this.createDatastore(a),this.remoteStore=this.createRemoteStore(a),this.eventManager=this.createEventManager(a),this.syncEngine=this.createSyncEngine(a,!e.synchronizeTabs),this.sharedClientState.onlineStateHandler=n=>AC(this.syncEngine,n,1),this.remoteStore.remoteSyncer.handleCredentialChange=QK.bind(null,this.syncEngine),await IK(this.remoteStore,this.syncEngine.isPrimaryClient))}createEventManager(e){return function(){return new RK}()}createDatastore(e){const a=bg(e.databaseInfo.databaseId),n=function(r){return new fK(r)}(e.databaseInfo);return function(r,o,l,c){return new xK(r,o,l,c)}(e.authCredentials,e.appCheckCredentials,n,a)}createRemoteStore(e){return function(n,i,r,o,l){return new bK(n,i,r,o,l)}(this.localStore,this.datastore,e.asyncQueue,a=>AC(this.syncEngine,a,0),function(){return bC.D()?new bC:new pK}())}createSyncEngine(e,a){return function(i,r,o,l,c,d,u){const p=new zK(i,r,o,l,c,d);return u&&(p.Qa=!0),p}(this.localStore,this.remoteStore,this.eventManager,this.sharedClientState,e.initialUser,e.maxConcurrentLimboResolutions,a)}async terminate(){var e,a;await async function(i){const r=he(i);Y("RemoteStore","RemoteStore shutting down."),r.L_.add(5),await zu(r),r.k_.shutdown(),r.q_.set("Unknown")}(this.remoteStore),(e=this.datastore)===null||e===void 0||e.terminate(),(a=this.eventManager)===null||a===void 0||a.terminate()}}pb.provider={build:()=>new pb};/**
1687 * @license
1688 * Copyright 2020 Google LLC
1689 *
1690 * Licensed under the Apache License, Version 2.0 (the "License");
1691 * you may not use this file except in compliance with the License.
1692 * You may obtain a copy of the License at
1693 *
1694 *   http://www.apache.org/licenses/LICENSE-2.0
1695 *
1696 * Unless required by applicable law or agreed to in writing, software
1697 * distributed under the License is distributed on an "AS IS" BASIS,
1698 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
1699 * See the License for the specific language governing permissions and
1700 * limitations under the License.
1701 *//**
1702 * @license
1703 * Copyright 2017 Google LLC
1704 *
1705 * Licensed under the Apache License, Version 2.0 (the "License");
1706 * you may not use this file except in compliance with the License.
1707 * You may obtain a copy of the License at
1708 *
1709 *   http://www.apache.org/licenses/LICENSE-2.0
1710 *
1711 * Unless required by applicable law or agreed to in writing, software
1712 * distributed under the License is distributed on an "AS IS" BASIS,
1713 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
1714 * See the License for the specific language governing permissions and
1715 * limitations under the License.
1716 */class e3{constructor(e){this.observer=e,this.muted=!1}next(e){this.muted||this.observer.next&&this.Ya(this.observer.next,e)}error(e){this.muted||(this.observer.error?this.Ya(this.observer.error,e):Vi("Uncaught Error in snapshot listener:",e.toString()))}Za(){this.muted=!0}Ya(e,a){setTimeout(()=>{this.muted||e(a)},0)}}/**
1717 * @license
1718 * Copyright 2017 Google LLC
1719 *
1720 * Licensed under the Apache License, Version 2.0 (the "License");
1721 * you may not use this file except in compliance with the License.
1722 * You may obtain a copy of the License at
1723 *
1724 *   http://www.apache.org/licenses/LICENSE-2.0
1725 *
1726 * Unless required by applicable law or agreed to in writing, software
1727 * distributed under the License is distributed on an "AS IS" BASIS,
1728 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
1729 * See the License for the specific language governing permissions and
1730 * limitations under the License.
1731 */class ZK{constructor(e,a,n,i,r){this.authCredentials=e,this.appCheckCredentials=a,this.asyncQueue=n,this.databaseInfo=i,this.user=ea.UNAUTHENTICATED,this.clientId=eL.newId(),this.authCredentialListener=()=>Promise.resolve(),this.appCheckCredentialListener=()=>Promise.resolve(),this._uninitializedComponentsProvider=r,this.authCredentials.start(n,async o=>{Y("FirestoreClient","Received user=",o.uid),await this.authCredentialListener(o),this.user=o}),this.appCheckCredentials.start(n,o=>(Y("FirestoreClient","Received new app check token=",o),this.appCheckCredentialListener(o,this.user)))}get configuration(){return{asyncQueue:this.asyncQueue,databaseInfo:this.databaseInfo,clientId:this.clientId,authCredentials:this.authCredentials,appCheckCredentials:this.appCheckCredentials,initialUser:this.user,maxConcurrentLimboResolutions:100}}setCredentialChangeListener(e){this.authCredentialListener=e}setAppCheckTokenChangeListener(e){this.appCheckCredentialListener=e}terminate(){this.asyncQueue.enterRestrictedMode();const e=new Ti;return this.asyncQueue.enqueueAndForgetEvenWhileRestricted(async()=>{try{this._onlineComponents&&await this._onlineComponents.terminate(),this._offlineComponents&&await this._offlineComponents.terminate(),this.authCredentials.shutdown(),this.appCheckCredentials.shutdown(),e.resolve()}catch(a){const n=lk(a,"Failed to shutdown persistence");e.reject(n)}}),e.promise}}async function N0(t,e){t.asyncQueue.verifyOperationInProgress(),Y("FirestoreClient","Initializing OfflineComponentProvider");const a=t.configuration;await e.initialize(a);let n=a.initialUser;t.setCredentialChangeListener(async i=>{n.isEqual(i)||(await RL(e.localStore,i),n=i)}),e.persistence.setDatabaseDeletedListener(()=>t.terminate()),t._offlineComponents=e}async function CC(t,e){t.asyncQueue.verifyOperationInProgress();const a=await eJ(t);Y("FirestoreClient","Initializing OnlineComponentProvider"),await e.initialize(a,t.configuration),t.setCredentialChangeListener(n=>wC(e.remoteStore,n)),t.setAppCheckTokenChangeListener((n,i)=>wC(e.remoteStore,i)),t._onlineComponents=e}async function eJ(t){if(!t._offlineComponents)if(t._uninitializedComponentsProvider){Y("FirestoreClient","Using user provided OfflineComponentProvider");try{await N0(t,t._uninitializedComponentsProvider._offline)}catch(e){const a=e;if(!function(i){return i.name==="FirebaseError"?i.code===z.FAILED_PRECONDITION||i.code===z.UNIMPLEMENT
1731ED:!(typeof DOMException<"u"&&i instanceof DOMException)||i.code===22||i.code===20||i.code===11}(a))throw a;wl("Error using user provided cache. Falling back to memory cache: "+a),await N0(t,new Dh)}}else Y("FirestoreClient","Using default OfflineComponentProvider"),await N0(t,new Dh);return t._offlineComponents}async function t3(t){return t._onlineComponents||(t._uninitializedComponentsProvider?(Y("FirestoreClient","Using user provided OnlineComponentProvider"),await CC(t,t._uninitializedComponentsProvider._online)):(Y("FirestoreClient","Using default OnlineComponentProvider"),await CC(t,new pb))),t._onlineComponents}function tJ(t){return t3(t).then(e=>e.syncEngine)}async function a3(t){const e=await t3(t),a=e.eventManager;return a.onListen=VK.bind(null,e.syncEngine),a.onUnlisten=BK.bind(null,e.syncEngine),a.onFirstRemoteStoreListen=HK.bind(null,e.syncEngine),a.onLastRemoteStoreUnlisten=UK.bind(null,e.syncEngine),a}function aJ(t,e,a={}){const n=new Ti;return t.asyncQueue.enqueueAndForget(async()=>function(r,o,l,c,d){const u=new e3({next:m=>{u.Za(),o.enqueueAndForget(()=>UL(r,p));const h=m.docs.has(l);!h&&m.fromCache?d.reject(new X(z.UNAVAILABLE,"Failed to get document because the client is offline.")):h&&m.fromCache&&c&&c.source==="server"?d.reject(new X(z.UNAVAILABLE,'Failed to get document from server. (However, this document does exist in the local cache. Run again without setting source to "server" to retrieve the cached document.)')):d.resolve(m)},error:m=>d.reject(m)}),p=new $L(Kw(l.path),u,{includeMetadataChanges:!0,_a:!0});return BL(r,p)}(await a3(t),t.asyncQueue,e,a,n)),n.promise}function nJ(t,e,a={}){const n=new Ti;return t.asyncQueue.enqueueAndForget(async()=>function(r,o,l,c,d){const u=new e3({next:m=>{u.Za(),o.enqueueAndForget(()=>UL(r,p)),m.fromCache&&c.source==="server"?d.reject(new X(z.UNAVAILABLE,'Failed to get documents from server. (However, these documents may exist in the local cache. Run again without setting source to "server" to retrieve the cached documents.)')):d.resolve(m)},error:m=>d.reject(m)}),p=new $L(l,u,{includeMetadataChanges:!0,_a:!0});return BL(r,p)}(await a3(t),t.asyncQueue,e,a,n)),n.promise}/**
1732 * @license
1733 * Copyright 2023 Google LLC
1734 *
1735 * Licensed under the Apache License, Version 2.0 (the "License");
1736 * you may not use this file except in compliance with the License.
1737 * You may obtain a copy of the License at
1738 *
1739 *   http://www.apache.org/licenses/LICENSE-2.0
1740 *
1741 * Unless required by applicable law or agreed to in writing, software
1742 * distributed under the License is distributed on an "AS IS" BASIS,
1743 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
1744 * See the License for the specific language governing permissions and
1745 * limitations under the License.
1746 */function n3(t){const e={};return t.timeoutSeconds!==void 0&&(e.timeoutSeconds=t.timeoutSeconds),e}/**
1747 * @license
1748 * Copyright 2020 Google LLC
1749 *
1750 * Licensed under the Apache License, Version 2.0 (the "License");
1751 * you may not use this file except in compliance with the License.
1752 * You may obtain a copy of the License at
1753 *
1754 *   http://www.apache.org/licenses/LICENSE-2.0
1755 *
1756 * Unless required by applicable law or agreed to in writing, software
1757 * distributed under the License is distributed on an "AS IS" BASIS,
1758 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
1759 * See the License for the specific language governing permissions and
1760 * limitations under the License.
1761 */const jC=new Map;/**
1762 * @license
1763 * Copyright 2017 Google LLC
1764 *
1765 * Licensed under the Apache License, Version 2.0 (the "License");
1766 * you may not use this file except in compliance with the License.
1767 * You may obtain a copy of the License at
1768 *
1769 *   http://www.apache.org/licenses/LICENSE-2.0
1770 *
1771 * Unless required by applicable law or agreed to in writing, software
1772 * distributed under the License is distributed on an "AS IS" BASIS,
1773 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
1774 * See the License for the specific language governing permissions and
1775 * limitations under the License.
1776 */function i3(t,e,a){if(!a)throw new X(z.INVALID_ARGUMENT,`Function ${t}() cannot be called with an empty ${e}.`)}function iJ(t,e,a,n){if(e===!0&&n===!0)throw new X(z.INVALID_ARGUMENT,`${t} and ${a} cannot be used together.`)}function TC(t){if(!oe.isDocumentKey(t))throw new X(z.INVALID_ARGUMENT,`Invalid document reference. Document references must have an even number of segments, but ${t} has ${t.length}.`)}function NC(t){if(oe.isDocumentKey(t))throw new X(z.INVALID_ARGUMENT,`Invalid collection reference. Collection references must have an odd number of segments, but ${t} has ${t.length}.`)}function Sg(t){if(t===void 0)return"undefined";if(t===null)return"null";if(typeof t=="string")return t.length>20&&(t=`${t.substring(0,20)}...`),JSON.stringify(t);if(typeof t=="number"||typeof t=="boolean")return""+t;if(typeof t=="object"){if(t instanceof Array)return"an array";{const e=function(n){return n.constructor?n.constructor.name:null}(t);return e?`a custom ${e} object`:"an object"}}return typeof t=="function"?"a function":pe()}function Fi(t,e){if("_delegate"in t&&(t=t._delegate),!(t instanceof e)){if(e.name===t.constructor.name)throw new X(z.INVALID_ARGUMENT,"Type does not match the expected instance. Did you pass a reference from a different Firestore SDK?");{const a=Sg(t);throw new X(z.INVALID_ARGUMENT,`Expected type '${e.name}', but it was: ${a}`)}}return t}/**
1777 * @license
1778 * Copyright 2020 Google LLC
1779 *
1780 * Licensed under the Apache License, Version 2.0 (the "License");
1781 * you may not use this file except in compliance with the License.
1782 * You may obtain a copy of the License at
1783 *
1784 *   http://www.apache.org/licenses/LICENSE-2.0
1785 *
1786 * Unless required by applicable law or agreed to in writing, software
1787 * distributed under the License is distributed on an "AS IS" BASIS,
1788 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
1789 * See the License for the specific language governing permissions and
1790 * limitations under the License.
1791 */class IC{constructor(e){var a,n;if(e.host===void 0){if(e.ssl!==void 0)throw new X(z.INVALID_ARGUMENT,"Can't provide ssl option if host option is not set");this.host="firestore.googleapis.com",this.ssl=!0}else this.host=e.host,this.ssl=(a=e.ssl)===null||a===void 0||a;if(this.credentials=e.credentials,this.ignoreUndefinedProperties=!!e.ignoreUndefinedProperties,this.localCache=e.localCache,e.cacheSizeBytes===void 0)this.cacheSizeBytes=41943040;else{if(e.cacheSizeBytes!==-1&&e.cacheSizeBytes<1048576)throw new X(z.INVALID_ARGUMENT,"cacheSizeBytes must be at least 1048576");this.cacheSizeBytes=e.cacheSizeBytes}iJ("experimentalForceLongPolling",e.experimentalForceLongPolling,"experimentalAutoDetectLongPolling",e.experimentalAutoDetectLongPolling),this.experimentalForceLongPolling=!!e.experimentalForceLongPolling,this.experimentalForceLongPolling?this.experimentalAutoDetectLongPolling=!1:e.experimentalAutoDetectLongPolling===void 0?this.experimentalAutoDetectLongPolling=!0:this.experimentalAutoDetectLongPolling=!!e.experimentalAutoDetectLongPolling,this.experimentalLongPollingOptions=n3((n=e.experimentalLongPollingOptions)!==null&&n!==void 0?n:{}),function(r){if(r.timeoutSeconds!==void 0){if(isNaN(r.timeoutSeconds))throw new X(z.INVALID_ARGUMENT,`invalid long polling timeout: ${r.timeoutSeconds} (must not be NaN)`);if(r.timeoutSeconds<5)throw new X(z.INVALID_ARGUMENT,`invalid long polling timeout: ${r.timeoutSeconds} (minimum allowed value is 5)`);if(r.timeoutSeconds>30)throw new X(z.INVALID_ARGUMENT,`invalid long polling timeout: ${r.timeoutSeconds} (maximum allowed value is 30)`)}}(this.experimentalLongPollingOptions),this.useFetchStreams=!!e.useFetchStreams}isEqual(e){return this.host===e.host&&this.ssl===e.ssl&&this.credentials===e.credentials&&this.cacheSizeBytes===e.cacheSizeBytes&&this.experimentalForceLongPolling===e.experimentalForceLongPolling&&this.experimentalAutoDetectLongPolling===e.experimentalAutoDetectLongPolling&&function(n,i){return n.timeoutSeconds===i.timeoutSeconds}(this.experimentalLongPollingOptions,e.experimentalLongPollingOptions)&&this.ignoreUndefinedProperties===e.ignoreUndefinedProperties&&this.useFetchStreams===e.useFetchStreams}}class _g{constructor(e,a,n,i){this._authCredentials=e,this._appCheckCredentials=a,this._databaseId=n,this._app=i,this.type="firestore-lite",this._persistenceKey="(lite)",this._settings=new IC({}),this._settingsFrozen=!1,this._terminateTask="notTerminated"}get app(){if(!this._app)throw new X(z.FAILED_PRECONDITION,"Firestore was not initialized using the Firebase SDK. 'app' is not available");return this._app}get _initialized(){return this._settingsFrozen}get _terminated(){return this._terminateTask!=="notTerminated"}_setSettings(e){if(this._settingsFrozen)throw new X(z.FAILED_PRECONDITION,"Firestore has already been started and its settings can no longer be changed. You can only modify settings before calling any other methods on a Firestore object.");this._settings=new IC(e),e.credentials!==void 0&&(this._authCredentials=function(n){if(!n)return new kW;switch(n.type){case"firstParty":return new EW(n.sessionIndex||"0",n.iamToken||null,n.authTokenFactory||null);case"provider":return n.client;default:throw new X(z.INVALID_ARGUMENT,"makeAuthCredentialsProvider failed due to invalid credential type")}}(e.credentials))}_getSettings(){return this._settings}_freezeSettings(){return this._settingsFrozen=!0,this._settings}_delete(){return this._terminateTask==="notTerminated"&&(this._terminateTask=this._terminate()),this._terminateTask}async _restart(){this._terminateTask==="notTerminated"?await this._terminate():this._terminateTask="notTerminated"}toJSON(){return{app:this._app,databaseId:this._databaseId,settings:this._settings}}_terminate(){return function(a){const n=jC.get(a);n&&(Y("ComponentProvider","Removing Datastore"),jC.delete(a),n.terminate())}(this),Promise.resolve()}}function rJ(t,e,a,n={}){var i;const r=(t=Fi(t,_g))._getSettings(),o=`${e}:${a}`;if(r.host!=="firestore.googleapis.com"&&r.host!==o&&wl("Host has been set in both settings() and connectFirestoreEmulator(), emulator host will be used."),t._setSettings(Object.assign(Object.assign({},r),{host:o,ssl:!1})),n.mockUserToken){let l,c;if(typeof n.mockUserToken=="string")l=n.mockUserToken,c=ea.MOCK_USER;else{l=zR(n.mockUserToken,(i=t._app)===null||i===void 0?void 0:i.options.projectId);const d=n.mockUserToken.sub||n.mockUserToken.user_id;if(!d)throw new X(z.INVALID_ARGUMENT,"mockUserToken must contain 'sub' or 'user_id' field!");c=new ea(d)}
1791t._authCredentials=new SW(new ZR(l,c))}}/**
1792 * @license
1793 * Copyright 2020 Google LLC
1794 *
1795 * Licensed under the Apache License, Version 2.0 (the "License");
1796 * you may not use this file except in compliance with the License.
1797 * You may obtain a copy of the License at
1798 *
1799 *   http://www.apache.org/licenses/LICENSE-2.0
1800 *
1801 * Unless required by applicable law or agreed to in writing, software
1802 * distributed under the License is distributed on an "AS IS" BASIS,
1803 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
1804 * See the License for the specific language governing permissions and
1805 * limitations under the License.
1806 */class Ql{constructor(e,a,n){this.converter=a,this._query=n,this.type="query",this.firestore=e}withConverter(e){return new Ql(this.firestore,e,this._query)}}class Ia{constructor(e,a,n){this.converter=a,this._key=n,this.type="document",this.firestore=e}get _path(){return this._key.path}get id(){return this._key.path.lastSegment()}get path(){return this._key.path.canonicalString()}get parent(){return new Ir(this.firestore,this.converter,this._key.path.popLast())}withConverter(e){return new Ia(this.firestore,e,this._key)}}class Ir extends Ql{constructor(e,a,n){super(e,a,Kw(n)),this._path=n,this.type="collection"}get id(){return this._query.path.lastSegment()}get path(){return this._query.path.canonicalString()}get parent(){const e=this._path.popLast();return e.isEmpty()?null:new Ia(this.firestore,null,new oe(e))}withConverter(e){return new Ir(this.firestore,e,this._path)}}function ga(t,e,...a){if(t=et(t),i3("collection","path",e),t instanceof _g){const n=Ue.fromString(e,...a);return NC(n),new Ir(t,null,n)}{if(!(t instanceof Ia||t instanceof Ir))throw new X(z.INVALID_ARGUMENT,"Expected first argument to collection() to be a CollectionReference, a DocumentReference or FirebaseFirestore");const n=t._path.child(Ue.fromString(e,...a));return NC(n),new Ir(t.firestore,null,n)}}function lu(t,e,...a){if(t=et(t),arguments.length===1&&(e=eL.newId()),i3("doc","path",e),t instanceof _g){const n=Ue.fromString(e,...a);return TC(n),new Ia(t,null,new oe(n))}{if(!(t instanceof Ia||t instanceof Ir))throw new X(z.INVALID_ARGUMENT,"Expected first argument to collection() to be a CollectionReference, a DocumentReference or FirebaseFirestore");const n=t._path.child(Ue.fromString(e,...a));return TC(n),new Ia(t.firestore,t instanceof Ir?t.converter:null,new oe(n))}}/**
1807 * @license
1808 * Copyright 2020 Google LLC
1809 *
1810 * Licensed under the Apache License, Version 2.0 (the "License");
1811 * you may not use this file except in compliance with the License.
1812 * You may obtain a copy of the License at
1813 *
1814 *   http://www.apache.org/licenses/LICENSE-2.0
1815 *
1816 * Unless required by applicable law or agreed to in writing, software
1817 * distributed under the License is distributed on an "AS IS" BASIS,
1818 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
1819 * See the License for the specific language governing permissions and
1820 * limitations under the License.
1821 */class PC{constructor(e=Promise.resolve()){this.Pu=[],this.Iu=!1,this.Tu=[],this.Eu=null,this.du=!1,this.Au=!1,this.Ru=[],this.t_=new OL(this,"async_queue_retry"),this.Vu=()=>{const n=T0();n&&Y("AsyncQueue","Visibility state changed to "+n.visibilityState),this.t_.jo()},this.mu=e;const a=T0();a&&typeof a.addEventListener=="function"&&a.addEventListener("visibilitychange",this.Vu)}get isShuttingDown(){return this.Iu}enqueueAndForget(e){this.enqueue(e)}enqueueAndForgetEvenWhileRestricted(e){this.fu(),this.gu(e)}enterRestrictedMode(e){if(!this.Iu){this.Iu=!0,this.Au=e||!1;const a=T0();a&&typeof a.removeEventListener=="function"&&a.removeEventListener("visibilitychange",this.Vu)}}enqueue(e){if(this.fu(),this.Iu)return new Promise(()=>{});const a=new Ti;return this.gu(()=>this.Iu&&this.Au?Promise.resolve():(e().then(a.resolve,a.reject),a.promise)).then(()=>a.promise)}enqueueRetryable(e){this.enqueueAndForget(()=>(this.Pu.push(e),this.pu()))}async pu(){if(this.Pu.length!==0){try{await this.Pu[0](),this.Pu.shift(),this.t_.reset()}catch(e){if(!Ou(e))throw e;Y("AsyncQueue","Operation failed with retryable error: "+e)}this.Pu.length>0&&this.t_.Go(()=>this.pu())}}gu(e){const a=this.mu.then(()=>(this.du=!0,e().catch(n=>{this.Eu=n,this.du=!1;const i=function(o){let l=o.message||"";return o.stack&&(l=o.stack.includes(o.message)?o.stack:o.message+`
1822`+o.stack),l}(n);throw Vi("INTERNAL UNHANDLED ERROR: ",i),n}).then(n=>(this.du=!1,n))));return this.mu=a,a}enqueueAfterDelay(e,a,n){this.fu(),this.Ru.indexOf(e)>-1&&(a=0);const i=sk.createAndSchedule(this,e,a,n,r=>this.yu(r));return this.Tu.push(i),i}fu(){this.Eu&&pe()}verifyOperationInProgress(){}async wu(){let e;do e=this.mu,await e;while(e!==this.mu)}Su(e){for(const a of this.Tu)if(a.timerId===e)return!0;return!1}bu(e){return this.wu().then(()=>{this.Tu.sort((a,n)=>a.targetTimeMs-n.targetTimeMs);for(const a of this.Tu)if(a.skipDelay(),e!=="all"&&a.timerId===e)break;return this.wu()})}Du(e){this.Ru.push(e)}yu(e){const a=this.Tu.indexOf(e);this.Tu.splice(a,1)}}class Xl extends _g{constructor(e,a,n,i){super(e,a,n,i),this.type="firestore",this._queue=new PC,this._persistenceKey=(i==null?void 0:i.name)||"[DEFAULT]"}async _terminate(){if(this._firestoreClient){const e=this._firestoreClient.terminate();this._queue=new PC(e),this._firestoreClient=void 0,await e}}}function oJ(t,e){const a=typeof t=="object"?t:mg(),n=typeof t=="string"?t:"(default)",i=Qr(a,"f
1822irestore").getImmediate({identifier:n});if(!i._initialized){const r=MR("firestore");r&&rJ(i,...r)}return i}function uk(t){if(t._terminated)throw new X(z.FAILED_PRECONDITION,"The client has already been terminated.");return t._firestoreClient||sJ(t),t._firestoreClient}function sJ(t){var e,a,n;const i=t._freezeSettings(),r=function(l,c,d,u){return new zW(l,c,d,u.host,u.ssl,u.experimentalForceLongPolling,u.experimentalAutoDetectLongPolling,n3(u.experimentalLongPollingOptions),u.useFetchStreams)}(t._databaseId,((e=t._app)===null||e===void 0?void 0:e.options.appId)||"",t._persistenceKey,i);t._componentsProvider||!((a=i.localCache)===null||a===void 0)&&a._offlineComponentProvider&&(!((n=i.localCache)===null||n===void 0)&&n._onlineComponentProvider)&&(t._componentsProvider={_offline:i.localCache._offlineComponentProvider,_online:i.localCache._onlineComponentProvider}),t._firestoreClient=new ZK(t._authCredentials,t._appCheckCredentials,t._queue,r,t._componentsProvider&&function(l){const c=l==null?void 0:l._online.build();return{_offline:l==null?void 0:l._offline.build(c),_online:c}}(t._componentsProvider))}/**
1823 * @license
1824 * Copyright 2020 Google LLC
1825 *
1826 * Licensed under the Apache License, Version 2.0 (the "License");
1827 * you may not use this file except in compliance with the License.
1828 * You may obtain a copy of the License at
1829 *
1830 *   http://www.apache.org/licenses/LICENSE-2.0
1831 *
1832 * Unless required by applicable law or agreed to in writing, software
1833 * distributed under the License is distributed on an "AS IS" BASIS,
1834 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
1835 * See the License for the specific language governing permissions and
1836 * limitations under the License.
1837 */class Cl{constructor(e){this._byteString=e}static fromBase64String(e){try{return new Cl($t.fromBase64String(e))}catch(a){throw new X(z.INVALID_ARGUMENT,"Failed to construct data from Base64 string: "+a)}}static fromUint8Array(e){return new Cl($t.fromUint8Array(e))}toBase64(){return this._byteString.toBase64()}toUint8Array(){return this._byteString.toUint8Array()}toString(){return"Bytes(base64: "+this.toBase64()+")"}isEqual(e){return this._byteString.isEqual(e._byteString)}}/**
1838 * @license
1839 * Copyright 2020 Google LLC
1840 *
1841 * Licensed under the Apache License, Version 2.0 (the "License");
1842 * you may not use this file except in compliance with the License.
1843 * You may obtain a copy of the License at
1844 *
1845 *   http://www.apache.org/licenses/LICENSE-2.0
1846 *
1847 * Unless required by applicable law or agreed to in writing, software
1848 * distributed under the License is distributed on an "AS IS" BASIS,
1849 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
1850 * See the License for the specific language governing permissions and
1851 * limitations under the License.
1852 */class Ag{constructor(...e){for(let a=0;a<e.length;++a)if(e[a].length===0)throw new X(z.INVALID_ARGUMENT,"Invalid field name at argument $(i + 1). Field names must not be empty.");this._internalPath=new Ht(e)}isEqual(e){return this._internalPath.isEqual(e._internalPath)}}/**
1853 * @license
1854 * Copyright 2020 Google LLC
1855 *
1856 * Licensed under the Apache License, Version 2.0 (the "License");
1857 * you may not use this file except in compliance with the License.
1858 * You may obtain a copy of the License at
1859 *
1860 *   http://www.apache.org/licenses/LICENSE-2.0
1861 *
1862 * Unless required by applicable law or agreed to in writing, software
1863 * distributed under the License is distributed on an "AS IS" BASIS,
1864 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
1865 * See the License for the specific language governing permissions and
1866 * limitations under the License.
1867 */class pk{constructor(e){this._methodName=e}}/**
1868 * @license
1869 * Copyright 2017 Google LLC
1870 *
1871 * Licensed under the Apache License, Version 2.0 (the "License");
1872 * you may not use this file except in compliance with the License.
1873 * You may obtain a copy of the License at
1874 *
1875 *   http://www.apache.org/licenses/LICENSE-2.0
1876 *
1877 * Unless required by applicable law or agreed to in writing, software
1878 * distributed under the License is distributed on an "AS IS" BASIS,
1879 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
1880 * See the License for the specific language governing permissions and
1881 * limitations under the License.
1882 */class mk{constructor(e,a){if(!isFinite(e)||e<-90||e>90)throw new X(z.INVALID_ARGUMENT,"Latitude must be a number between -90 and 90, but was: "+e);if(!isFinite(a)||a<-180||a>180)throw new X(z.INVALID_ARGUMENT,"Longitude must be a number between -180 and 180, but was: "+a);this._lat=e,this._long=a}get latitude(){return this._lat}get longitude(){return this._long}isEqual(e){return this._lat===e._lat&&this._long===e._long}toJSON(){return{latitude:this._lat,longitude:this._long}}_compareTo(e){return je(this._lat,e._lat)||je(this._long,e._long)}}/**
1883 * @license
1884 * Copyright 2024 Google LLC
1885 *
1886 * Licensed under the Apache License, Version 2.0 (the "License");
1887 * you may not use this file except in compliance with the License.
1888 * You may obtain a copy of the License at
1889 *
1890 *   http://www.apache.org/licenses/LICENSE-2.0
1891 *
1892 * Unless required by applicable law or agreed to in writing, software
1893 * distributed under the License is distributed on an "AS IS" BASIS,
1894 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
1895 * See the License for the specific language governing permissions and
1896 * limitations under the License.
1897 */class hk{constructor(e){this._values=(e||[]).map(a=>a)}toArray(){return this._values.map(e=>e)}isEqual(e){return function(n,i){if(n.length!==i.length)return!1;for(let r=0;r<n.length;++r)if(n[r]!==i[r])return!1;return!0}(this._values,e._values)}}/**
1898 * @license
1899 * Copyright 2017 Google LLC
1900 *
1901 * Licensed under the Apache License, Version 2.0 (the "License");
1902 * you may not use this file except in compliance with the License.
1903 * You may obtain a copy of the License at
1904 *
1905 *   http://www.apache.org/licenses/LICENSE-2.0
1906 *
1907 * Unless required by applicable law or agreed to in writing, software
1908 * distributed under the License is distributed on an "AS IS" BASIS,
1909 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
1910 * See the License for the specific language governing permissions and
1911 * limitations under the License.
1912 */const lJ=/^__.*__$/;class cJ{constructor(e,a,n){this.data=e,this.fieldMask=a,this.fieldTransforms=n}toMutation(e,a){return this.fieldMask!==null?new Xr(e,this.data,this.fieldMask,a,this.fieldTransforms):new Du(e,this.data,a,this.fieldTransforms)}}class r3{constructor(e,a,n){this.data=e,this.fieldMask=a,this.fieldTransforms=n}toMutation(e,a){return new Xr(e,this.data,this.fieldMask,a,this.fieldTransforms)}}function o3(t){switch(t){case 0:case 2:case 1:return!0;case 3:case 4:return!1;default:throw pe()}}class fk{constructor(e,a,n,i,r,o){this.settings=e,this.databaseId=a,this.serializer=n,this.ignoreUndefinedProperties=i,r===void 0&&this.vu(),this.fieldTransforms=r||[],this.fieldMask=o||[]}get path(){return this.settings.path}get Cu(){return this.settings.Cu}Fu(e){return new fk(Object.assign(Object.assign({},this.settings),e),this.databaseId,this.serializer,this.ignoreUndefinedProperties,this.fieldTransforms,this.fieldMask)}Mu(e){var a;const n=(a=this.path)===null||a===void 0?void 0:a.child(e),i=this.Fu({path:n,xu:!1});return i.Ou(e),i}Nu(e){var a;const n=(a=this.path)===null||a===void 0?void 0:a.child(e),i=this.Fu({path:n,xu:!1});return i.vu(),i}Lu(e){return this.Fu({path:void 0,xu:!0})}Bu(e){return qh(e,this.settings.methodName,this.settings.ku||!1,this.path,this.settings.qu)}contains(e){return this.fieldMask.find(a=>e.isPrefixOf(a))!==void 0||this.fieldTransforms.find(a=>e.isPrefixOf(a.field))!==void 0}vu(){if(this.path)for(let e=0;e<this.path.length;e++)this.Ou(this.path.get(e))}Ou(e){if(e.length===0)throw this.Bu("Document fields must not be empty");if(o3(this.Cu)&&lJ.test(e))throw this.Bu('Document fields cannot begin and end with "__"')}}class dJ{constructor(e,a,n){this.databaseId=e,this.ignoreUndefinedProperties=a,this.serializer=n||bg(e)}Qu(e,a,n,i=!1){return new fk({Cu:e,methodName:a,qu:n,path:Ht.emptyPath(),xu:!1,ku:i},this.databaseId,this.serializer,this.ignoreUndefinedProperties)}}function gk(t){const e=t._freezeSettings(),a=bg(t._databaseId);return new dJ(t._databaseId,!!e.ignoreUndefinedProperties,a)}function uJ(t,e,a,n,i,r={}){const o=t.Qu(r.merge||r.mergeFields?2:0,e,a,i);yk("Data must be an object, but it was:",o,n);const l=s3(n,o);let c,d;if(r.merge)c=new Va(o.fieldMask),d=o.fieldTransforms;else if(r.mergeFields){const u=[];for(const p of r.mergeFields){const m=mb(e,p,a);if(!o.contains(m))throw new X(z.INVALID_ARGUMENT,`Field '${m}' is specified in your field mask but missing from your input data.`);c3(u,m)||u.push(m)}c=new Va(u),d=o.fieldTransforms.filter(p=>c.covers(p.field))}else c=null,d=o.fieldTransforms;return new cJ(new _a(l),c,d)}class Eg extends pk{_toFieldTransform(e){if(e.Cu!==2)throw e.Cu===1?e.Bu(`${this._methodName}() can only appear at the top level of your update data`):e.Bu(`${this._methodName}() cannot be used with set() unless you pass {merge:true}`);return e.fieldMask.push(e.path),null}isEqual(e){return e instanceof Eg}}function pJ(t,e,a,n){const i=t.Qu(1,e,a);
1912yk("Data must be an object, but it was:",i,n);const r=[],o=_a.empty();ps(n,(c,d)=>{const u=xk(e,c,a);d=et(d);const p=i.Nu(u);if(d instanceof Eg)r.push(u);else{const m=Hu(d,p);m!=null&&(r.push(u),o.set(u,m))}});const l=new Va(r);return new r3(o,l,i.fieldTransforms)}function mJ(t,e,a,n,i,r){const o=t.Qu(1,e,a),l=[mb(e,n,a)],c=[i];if(r.length%2!=0)throw new X(z.INVALID_ARGUMENT,`Function ${e}() needs to be called with an even number of arguments that alternate between field names and values.`);for(let m=0;m<r.length;m+=2)l.push(mb(e,r[m])),c.push(r[m+1]);const d=[],u=_a.empty();for(let m=l.length-1;m>=0;--m)if(!c3(d,l[m])){const h=l[m];let g=c[m];g=et(g);const y=o.Nu(h);if(g instanceof Eg)d.push(h);else{const x=Hu(g,y);x!=null&&(d.push(h),u.set(h,x))}}const p=new Va(d);return new r3(u,p,o.fieldTransforms)}function hJ(t,e,a,n=!1){return Hu(a,t.Qu(n?4:3,e))}function Hu(t,e){if(l3(t=et(t)))return yk("Unsupported field value:",e,t),s3(t,e);if(t instanceof pk)return function(n,i){if(!o3(i.Cu))throw i.Bu(`${n._methodName}() can only be used with update() and set()`);if(!i.path)throw i.Bu(`${n._methodName}() is not currently supported inside arrays`);const r=n._toFieldTransform(i);r&&i.fieldTransforms.push(r)}(t,e),null;if(t===void 0&&e.ignoreUndefinedProperties)return null;if(e.path&&e.fieldMask.push(e.path),t instanceof Array){if(e.settings.xu&&e.Cu!==4)throw e.Bu("Nested arrays are not supported");return function(n,i){const r=[];let o=0;for(const l of n){let c=Hu(l,i.Lu(o));c==null&&(c={nullValue:"NULL_VALUE"}),r.push(c),o++}return{arrayValue:{values:r}}}(t,e)}return function(n,i){if((n=et(n))===null)return{nullValue:"NULL_VALUE"};if(typeof n=="number")return sG(i.serializer,n);if(typeof n=="boolean")return{booleanValue:n};if(typeof n=="string")return{stringValue:n};if(n instanceof Date){const r=xt.fromDate(n);return{timestampValue:Oh(i.serializer,r)}}if(n instanceof xt){const r=new xt(n.seconds,1e3*Math.floor(n.nanoseconds/1e3));return{timestampValue:Oh(i.serializer,r)}}if(n instanceof mk)return{geoPointValue:{latitude:n.latitude,longitude:n.longitude}};if(n instanceof Cl)return{bytesValue:EL(i.serializer,n._byteString)};if(n instanceof Ia){const r=i.databaseId,o=n.firestore._databaseId;if(!o.isEqual(r))throw i.Bu(`Document reference is for database ${o.projectId}/${o.database} but should be for database ${r.projectId}/${r.database}`);return{referenceValue:Zw(n.firestore._databaseId||i.databaseId,n._key.path)}}if(n instanceof hk)return function(o,l){return{mapValue:{fields:{__type__:{stringValue:"__vector__"},value:{arrayValue:{values:o.toArray().map(c=>{if(typeof c!="number")throw l.Bu("VectorValues must only contain numeric values.");return Jw(l.serializer,c)})}}}}}}(n,i);throw i.Bu(`Unsupported field value: ${Sg(n)}`)}(t,e)}function s3(t,e){const a={};return tL(t)?e.path&&e.path.length>0&&e.fieldMask.push(e.path):ps(t,(n,i)=>{const r=Hu(i,e.Mu(n));r!=null&&(a[n]=r)}),{mapValue:{fields:a}}}function l3(t){return!(typeof t!="object"||t===null||t instanceof Array||t instanceof Date||t instanceof xt||t instanceof mk||t instanceof Cl||t instanceof Ia||t instanceof pk||t instanceof hk)}function yk(t,e,a){if(!l3(a)||!function(i){return typeof i=="object"&&i!==null&&(Object.getPrototypeOf(i)===Object.prototype||Object.getPrototypeOf(i)===null)}(a)){const n=Sg(a);throw n==="an object"?e.Bu(t+" a custom object"):e.Bu(t+" "+n)}}function mb(t,e,a){if((e=et(e))instanceof Ag)return e._internalPath;if(typeof e=="string")return xk(t,e);throw qh("Field path arguments must be of type string or ",t,!1,void 0,a)}const fJ=new RegExp("[~\\*/\\[\\]]");function xk(t,e,a){if(e.search(fJ)>=0)throw qh(`Invalid field path (${e}). Paths must not contain '~', '*', '/', '[', or ']'`,t,!1,void 0,a);try{return new Ag(...e.split("."))._internalPath}catch{throw qh(`Invalid field path (${e}). Paths must not be empty, begin with '.', end with '.', or contain '..'`,t,!1,void 0,a)}}function qh(t,e,a,n,i){const r=n&&!n.isEmpty(),o=i!==void 0;let l=`Function ${e}() called with invalid data`;a&&(l+=" (via `toFirestore()`)"),l+=". ";let c="";return(r||o)&&(c+=" (found",r&&(c+=` in field ${n}`),o&&(c+=` in document ${i}`),c+=")"),new X(z.INVALID_ARGUMENT,l+t+c)}function c3(t,e){return t.some(a=>a.isEqual(e))}/**
1913 * @license
1914 * Copyright 2020 Google LLC
1915 *
1916 * Licensed under the Apache License, Version 2.0 (the "License");
1917 * you may not use this file except in compliance with the License.
1918 * You may obtain a copy of the License at
1919 *
1920 *   http://www.apache.org/licenses/LICENSE-2.0
1921 *
1922 * Unless required by applicable law or agreed to in writing, software
1923 * distributed under the License is distributed on an "AS IS" BASIS,
1924 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
1925 * See the License for the specific language governing permissions and
1926 * limitations under the License.
1927 */class d3{constructor(e,a,n,i,r){this._firestore=e,this._userDataWriter=a,this._key=n,this._document=i,this._converter=r}get id(){return this._key.path.lastSegment()}get ref(){return new Ia(this._firestore,this._converter,this._key)}exists(){return this._document!==null}data(){if(this._document){if(this._converter){const e=new gJ(this._firestore,this._userDataWriter,this._key,this._document,null);return this._converter.fromFirestore(e)}return this._userDataWriter.convertValue(this._document.data.value)}}get(e){if(this._document){const a=this._document.data.field(vk("DocumentSnapshot.get",e));if(a!==null)return this._userDataWriter.convertValue(a)}}}class gJ extends d3{data(){return super.data()}}function vk(t,e){return typeof e=="string"?xk(t,e):e instanceof Ag?e._internalPath:e._delegate._internalPath}/**
1928 * @license
1929 * Copyright 2020 Google LLC
1930 *
1931 * Licensed under the Apache License, Version 2.0 (the "License");
1932 * you may not use this file except in compliance with the License.
1933 * You may obtain a copy of the License at
1934 *
1935 *   http://www.apache.org/licenses/LICENSE-2.0
1936 *
1937 * Unless required by applicable law or agreed to in writing, software
1938 * distributed under the License is distributed on an "AS IS" BASIS,
1939 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
1940 * See the License for the specific language governing permissions and
1941 * limitations under the License.
1942 */function yJ(t){if(t.limitType==="L"&&t.explicitOrderBy.length===0)throw new X(z.UNIMPLEMENTED,"limitToLast() queries require specifying at least one orderBy() clause")}class bk{}class xJ extends bk{}function jl(t,e,...a){let n=[];e instanceof bk&&n.push(e),n=n.concat(a),function(r){const o=r.filter(c=>c instanceof wk).length,l=r.filter(c=>c instanceof Cg).length;if(o>1||o>0&&l>0)throw new X(z.INVALID_ARGUMENT,"InvalidQuery. When using composite filters, you cannot use more than one filter at the top level. Consider nesting the multiple filters within an `and(...)` statement. For example: change `query(query, where(...), or(...))` to `query(query, and(where(...), or(...)))`.")}(n);for(const i of n)t=i._apply(t);return t}class Cg extends xJ{constructor(e,a,n){super(),this._field=e,this._op=a,this._value=n,this.type="where"}static _create(e,a,n){return new Cg(e,a,n)}_apply(e){const a=this._parse(e);return u3(e._query,a),new Ql(e.firestore,e.converter,nb(e._query,a))}_parse(e){const a=gk(e.firestore);return function(r,o,l,c,d,u,p){let m;if(d.isKeyField()){if(u==="array-contains"||u==="array-contains-any")throw new X(z.INVALID_ARGUMENT,`Invalid Query. You can't perform '${u}' queries on documentId().`);if(u==="in"||u==="not-in"){LC(p,u);const h=[];for(const g of p)h.push(RC(c,r,g));m={arrayValue:{values:h}}}else m=RC(c,r,p)}else u!=="in"&&u!=="not-in"&&u!=="array-contains-any"||LC(p,u),m=hJ(l,o,p,u==="in"||u==="not-in");return gt.create(d,u,m)}(e._query,"where",a,e.firestore._databaseId,this._field,this._op,this._value)}}function Gn(t,e,a){const n=e,i=vk("where",t);return Cg._create(i,n,a)}class wk extends bk{constructor(e,a){super(),this.type=e,this._queryConstraints=a}static _create(e,a){return new wk(e,a)}_parse(e){const a=this._queryConstraints.map(n=>n._parse(e)).filter(n=>n.getFilters().length>0);return a.length===1?a[0]:qn.create(a,this._getOperator())}_apply(e){const a=this._parse(e);return a.getFilters().length===0?e:(function(i,r){let o=i;const l=r.getFlattenedFilters();for(const c of l)u3(o,c),o=nb(o,c)}(e._query,a),new Ql(e.firestore,e.converter,nb(e._query,a)))}_getQueryConstraints(){return this._queryConstraints}_getOperator(){return this.type==="and"?"and":"or"}}
1942function RC(t,e,a){if(typeof(a=et(a))=="string"){if(a==="")throw new X(z.INVALID_ARGUMENT,"Invalid query. When querying with documentId(), you must provide a valid document ID, but it was an empty string.");if(!dL(e)&&a.indexOf("/")!==-1)throw new X(z.INVALID_ARGUMENT,`Invalid query. When querying a collection by documentId(), you must provide a plain document ID, but '${a}' contains a '/' character.`);const n=e.path.child(Ue.fromString(a));if(!oe.isDocumentKey(n))throw new X(z.INVALID_ARGUMENT,`Invalid query. When querying a collection group by documentId(), the value provided must result in a valid document path, but '${n}' is not because it has an odd number of segments (${n.length}).`);return tC(t,new oe(n))}if(a instanceof Ia)return tC(t,a._key);throw new X(z.INVALID_ARGUMENT,`Invalid query. When querying with documentId(), you must provide a valid string or a DocumentReference, but it was: ${Sg(a)}.`)}function LC(t,e){if(!Array.isArray(t)||t.length===0)throw new X(z.INVALID_ARGUMENT,`Invalid Query. A non-empty array is required for '${e.toString()}' filters.`)}function u3(t,e){const a=function(i,r){for(const o of i)for(const l of o.getFlattenedFilters())if(r.indexOf(l.op)>=0)return l.op;return null}(t.filters,function(i){switch(i){case"!=":return["!=","not-in"];case"array-contains-any":case"in":return["not-in"];case"not-in":return["array-contains-any","in","not-in","!="];default:return[]}}(e.op));if(a!==null)throw a===e.op?new X(z.INVALID_ARGUMENT,`Invalid query. You cannot use more than one '${e.op.toString()}' filter.`):new X(z.INVALID_ARGUMENT,`Invalid query. You cannot use '${e.op.toString()}' filters with '${a.toString()}' filters.`)}class vJ{convertValue(e,a="none"){switch(Xo(e)){case 0:return null;case 1:return e.booleanValue;case 2:return ut(e.integerValue||e.doubleValue);case 3:return this.convertTimestamp(e.timestampValue);case 4:return this.convertServerTimestamp(e,a);case 5:return e.stringValue;case 6:return this.convertBytes(Qo(e.bytesValue));case 7:return this.convertReference(e.referenceValue);case 8:return this.convertGeoPoint(e.geoPointValue);case 9:return this.convertArray(e.arrayValue,a);case 11:return this.convertObject(e.mapValue,a);case 10:return this.convertVectorValue(e.mapValue);default:throw pe()}}convertObject(e,a){return this.convertObjectMap(e.fields,a)}convertObjectMap(e,a="none"){const n={};return ps(e,(i,r)=>{n[i]=this.convertValue(r,a)}),n}convertVectorValue(e){var a,n,i;const r=(i=(n=(a=e.fields)===null||a===void 0?void 0:a.value.arrayValue)===null||n===void 0?void 0:n.values)===null||i===void 0?void 0:i.map(o=>ut(o.doubleValue));return new hk(r)}convertGeoPoint(e){return new mk(ut(e.latitude),ut(e.longitude))}convertArray(e,a){return(e.values||[]).map(n=>this.convertValue(n,a))}convertServerTimestamp(e,a){switch(a){case"previous":const n=Uw(e);return n==null?null:this.convertValue(n,a);case"estimate":return this.convertTimestamp(nu(e));default:return null}}convertTimestamp(e){const a=Fr(e);return new xt(a.seconds,a.nanos)}convertDocumentKey(e,a){const n=Ue.fromString(e);Oe(PL(n));const i=new iu(n.get(1),n.get(3)),r=new oe(n.popFirst(5));return i.isEqual(a)||Vi(`Document ${r} contains a document reference within a different database (${i.projectId}/${i.database}) which is not supported. It will be treated as a reference in the current database (${a.projectId}/${a.database}) instead.`),r}}/**
1943 * @license
1944 * Copyright 2020 Google LLC
1945 *
1946 * Licensed under the Apache License, Version 2.0 (the "License");
1947 * you may not use this file except in compliance with the License.
1948 * You may obtain a copy of the License at
1949 *
1950 *   http://www.apache.org/licenses/LICENSE-2.0
1951 *
1952 * Unless required by applicable law or agreed to in writing, software
1953 * distributed under the License is distributed on an "AS IS" BASIS,
1954 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
1955 * See the License for the specific language governing permissions and
1956 * limitations under the License.
1957 */function bJ(t,e,a){let n;return n=t?t.toFirestore(e):e,n}/**
1958 * @license
1959 * Copyright 2020 Google LLC
1960 *
1961 * Licensed under the Apache License, Version 2.0 (the "License");
1962 * you may not use this file except in compliance with the License.
1963 * You may obtain a copy of the License at
1964 *
1965 *   http://www.apache.org/licenses/LICENSE-2.0
1966 *
1967 * Unless required by applicable law or agreed to in writing, software
1968 * distributed under the License is distributed on an "AS IS" BASIS,
1969 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
1970 * See the License for the specific language governing permissions and
1971 * limitations under the License.
1972 */class Bc{constructor(e,a){this.hasPendingWrites=e,this.fromCache=a}isEqual(e){return this.hasPendingWrites===e.hasPendingWrites&&this.fromCache===e.fromCache}}class p3 extends d3{constructor(e,a,n,i,r,o){super(e,a,n,i,o),this._firestore=e,this._firestoreImpl=e,this.metadata=r}exists(){return super.exists()}data(e={}){if(this._document){if(this._converter){const a=new Dm(this._firestore,this._userDataWriter,this._key,this._document,this.metadata,null);return this._converter.fromFirestore(a,e)}return this._userDataWriter.convertValue(this._document.data.value,e.serverTimestamps)}}get(e,a={}){if(this._document){const n=this._document.data.field(vk("DocumentSnapshot.get",e));if(n!==null)return this._userDataWriter.convertValue(n,a.serverTimestamps)}}}class Dm extends p3{data(e={}){return super.data(e)}}class wJ{constructor(e,a,n,i){this._firestore=e,this._userDataWriter=a,this._snapshot=i,this.metadata=new Bc(i.hasPendingWrites,i.fromCache),this.query=n}get docs(){const e=[];return this.forEach(a=>e.push(a)),e}get size(){return this._snapshot.docs.size}get empty(){return this.size===0}forEach(e,a){this._snapshot.docs.forEach(n=>{e.call(a,new Dm(this._firestore,this._userDataWriter,n.key,n,new Bc(this._snapshot.mutatedKeys.has(n.key),this._snapshot.fromCache),this.query.converter))})}docChanges(e={}){const a=!!e.includeMetadataChanges;if(a&&this._snapshot.excludesMetadataChanges)throw new X(z.INVALID_ARGUMENT,"To include metadata changes with your document changes, you must also pass { includeMetadataChanges:true } to onSnapshot().");return this._cachedChanges&&this._cachedChangesIncludeMetadataChanges===a||(this._cachedChanges=function(i,r){if(i._snapshot.oldDocs.isEmpty()){let o=0;return i._snapshot.docChanges.map(l=>{const c=new Dm(i._firestore,i._userDataWriter,l.doc.key,l.doc,new Bc(i._snapshot.mutatedKeys.has(l.doc.key),i._snapshot.fromCache),i.query.converter);return l.doc,{type:"added",doc:c,oldIndex:-1,newIndex:o++}})}{let o=i._snapshot.oldDocs;return i._snapshot.docChanges.filter(l=>r||l.type!==3).map(l=>{const c=new Dm(i._firestore,i._userDataWriter,l.doc.key,l.doc,new Bc(i._snapshot.mutatedKeys.has(l.doc.key),i._snapshot.fromCache),i.query.converter);let d=-1,u=-1;return l.type!==0&&(d=o.indexOf(l.doc.key),o=o.delete(l.doc.key)),l.type!==1&&(o=o.add(l.doc),u=o.indexOf(l.doc.key)),{type:kJ(l.type),doc:c,oldIndex:d,newIndex:u}})}}(this,a),this._cachedChangesIncludeMetadataChanges=a),this._cachedChanges}}function kJ(t){switch(t){case 0:return"added";case 2:case 3:return"modified";case 1:return"removed";default:return pe()}}/**
1973 * @license
1974 * Copyright 2020 Google LLC
1975 *
1976 * Licensed under the Apache License, Version 2.0 (the "License");
1977 * you may not use this file except in compliance with the License.
1978 * You may obtain a copy of the License at
1979 *
1980 *   http://www.apache.org/licenses/LICENSE-2.0
1981 *
1982 * Unless required by applicable law or agreed to in writing, software
1983 * distributed under the License is distributed on an "AS IS" BASIS,
1984 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
1985 * See the License for the specific language governing permissions and
1986 * limitations under the License.
1987 */function SJ(t){t=Fi(t,Ia);const e=Fi(t.firestore,Xl);return aJ(uk(e),t._key).then(a=>AJ(e,t,a))}class m3 extends vJ{constructor(e){super(),this.firestore=e}convertBytes(e){return new Cl(e)}convertReference(e){const a=this.convertDocumentKey(e,this.firestore._databaseId);return new Ia(this.firestore,null,a)}}function Ni(t){t=Fi(t,Ql);const e=Fi(t.firestore,Xl),a=uk(e),n=new m3(e);return yJ(t._query),nJ(a,t._query).then(i=>new wJ(e,n,t,i))}
1987function h3(t,e,a,...n){t=Fi(t,Ia);const i=Fi(t.firestore,Xl),r=gk(i);let o;return o=typeof(e=et(e))=="string"||e instanceof Ag?mJ(r,"updateDoc",t._key,e,a,n):pJ(r,"updateDoc",t._key,e),kk(i,[o.toMutation(t._key,In.exists(!0))])}function _J(t){return kk(Fi(t.firestore,Xl),[new Qw(t._key,In.none())])}function Tl(t,e){const a=Fi(t.firestore,Xl),n=lu(t),i=bJ(t.converter,e);return kk(a,[uJ(gk(t.firestore),"addDoc",n._key,i,t.converter!==null,{}).toMutation(n._key,In.exists(!1))]).then(()=>n)}function kk(t,e){return function(n,i){const r=new Ti;return n.asyncQueue.enqueueAndForget(async()=>$K(await tJ(n),i,r)),r.promise}(uk(t),e)}function AJ(t,e,a){const n=a.docs.get(e._key),i=new m3(t);return new p3(t,i,e._key,n,new Bc(a.hasPendingWrites,a.fromCache),e.converter)}(function(e,a=!0){(function(i){Gl=i})(us),Dn(new hn("firestore",(n,{instanceIdentifier:i,options:r})=>{const o=n.getProvider("app").getImmediate(),l=new Xl(new _W(n.getProvider("auth-internal")),new jW(n.getProvider("app-check-internal")),function(d,u){if(!Object.prototype.hasOwnProperty.apply(d.options,["projectId"]))throw new X(z.INVALID_ARGUMENT,'"projectId" not provided in firebase.initializeApp.');return new iu(d.options.projectId,u)}(o,i),o);return r=Object.assign({useFetchStreams:a},r),l._setSettings(r),l},"PUBLIC").setMultipleInstances(!0)),Na(QE,"4.7.3",e),Na(QE,"4.7.3","esm2017")})();/**
1988 * @license
1989 * Copyright 2017 Google LLC
1990 *
1991 * Licensed under the Apache License, Version 2.0 (the "License");
1992 * you may not use this file except in compliance with the License.
1993 * You may obtain a copy of the License at
1994 *
1995 *   http://www.apache.org/licenses/LICENSE-2.0
1996 *
1997 * Unless required by applicable law or agreed to in writing, software
1998 * distributed under the License is distributed on an "AS IS" BASIS,
1999 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
2000 * See the License for the specific language governing permissions and
2001 * limitations under the License.
2002 */const f3="firebasestorage.googleapis.com",g3="storageBucket",EJ=2*60*1e3,CJ=10*60*1e3;/**
2003 * @license
2004 * Copyright 2017 Google LLC
2005 *
2006 * Licensed under the Apache License, Version 2.0 (the "License");
2007 * you may not use this file except in compliance with the License.
2008 * You may obtain a copy of the License at
2009 *
2010 *   http://www.apache.org/licenses/LICENSE-2.0
2011 *
2012 * Unless required by applicable law or agreed to in writing, software
2013 * distributed under the License is distributed on an "AS IS" BASIS,
2014 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
2015 * See the License for the specific language governing permissions and
2016 * limitations under the License.
2017 */class dt extends gn{constructor(e,a,n=0){super(I0(e),`Firebase Storage: ${a} (${I0(e)})`),this.status_=n,this.customData={serverResponse:null},this._baseMessage=this.message,Object.setPrototypeOf(this,dt.prototype)}get status(){return this.status_}set status(e){this.status_=e}_codeEquals(e){return I0(e)===this.code}get serverResponse(){return this.customData.serverResponse}set serverResponse(e){this.customData.serverResponse=e,this.customData.serverResponse?this.message=`${this._baseMessage}
2018${this.customData.serverResponse}`:this.message=this._baseMessage}}var lt;(function(t){t.UNKNOWN="unknown",t.OBJECT_NOT_FOUND="object-not-found",t.BUCKET_NOT_FOUND="bucket-not-found",t.PROJECT_NOT_FOUND="project-not-found",t.QUOTA_EXCEEDED="quota-exceeded",t.UNAUTHENTICATED="unauthenticated",t.UNAUTHORIZED="unauthorized",t.UNAUTHORIZED_APP="unauthorized-app",t.RETRY_LIMIT_EXCEEDED="retry-limit-exceeded",t.INVALID_CHECKSUM="invalid-checksum",t.CANCELED="canceled",t.INVALID_EVENT_NAME="invalid-event-name",t.INVALID_URL="invalid-url",t.INVALID_DEFAULT_BUCKET="invalid-default-bucket",t.NO_DEFAULT_BUCKET="no-default-bucket",t.CANNOT_SLICE_BLOB="cannot-slice-blob",t.SERVER_FILE_WRONG_SIZE="server-file-wrong-size",t.NO_DOWNLOAD_URL="no-download-url",t.INVALID_ARGUMENT="invalid-argument",t.INVALID_ARGUMENT_COUNT="invalid-argument-count",t.APP_DELETED="app-deleted",t.INVALID_ROOT_OPERATION="invalid-root-operation",t.INVALID_FORMAT="invalid-format",t.INTERNAL_ERROR="internal-error",t.UNSUPPORTED_ENVIRONMENT="unsupported-environment"})(lt||(lt={}));function I0(t){return"storage/"+t}function Sk(){const t="An unknown error occurred, please check the error payload for server response.";return new dt(lt.UNKNOWN,t)}function jJ(t){return new dt(lt.OBJECT_NOT_FOUND,"Object '"+t+"' does not exist.")}function TJ(t){return new dt(lt.QUOTA_EXCEEDED,"Quota for bucket '"+t+"' exceeded, please view quota on https://firebase.google.com/pricing/.")}function NJ(){const t="User is not authenticated, please authenticate using Firebase Authentication and try again.";return new dt(lt.UNAUTHENTICATED,t)}function IJ(){return new dt(lt.UNAUTHORIZED_APP,"This app does not have permission to access Firebase Storage on this project.")}function PJ(t){return new dt(lt.UNAUTHORIZED,"User does not have permission to access '"+t+"'.")}function RJ(){return new dt(lt.RETRY_LIMIT_EXCEEDED,"Max retry time for operation exceeded, please try again.")}function LJ(){return new dt(lt.CANCELED,"User canceled the upload/download.")}
vendor: 4,432 bytes, lines 2018-2052
2018function OJ(t){return new dt(lt.INVALID_URL,"Invalid URL '"+t+"'.")}function MJ(t){return new dt(lt.INVALID_DEFAULT_BUCKET,"Invalid default bucket '"+t+"'.")}function DJ(){return new dt(lt.NO_DEFAULT_BUCKET,"No default bucket found. Did you set the '"+g3+"' property when initializing the app?")}function qJ(){return new dt(lt.CANNOT_SLICE_BLOB,"Cannot slice blob for upload. Please retry the upload.")}function zJ(){return new dt(lt.NO_DOWNLOAD_URL,"The given file does not have any download URLs.")}function VJ(t){return new dt(lt.UNSUPPORTED_ENVIRONMENT,`${t} is missing. Make sure to install the required polyfills. See https://firebase.google.com/docs/web/environments-js-sdk#polyfills for more information.`)}function hb(t){return new dt(lt.INVALID_ARGUMENT,t)}function y3(){return new dt(lt.APP_DELETED,"The Firebase app was deleted.")}function HJ(t){return new dt(lt.INVALID_ROOT_OPERATION,"The operation '"+t+"' cannot be performed on a root reference, create a non-root reference using child, such as .child('file.png').")}function fd(t,e){return new dt(lt.INVALID_FORMAT,"String does not match format '"+t+"': "+e)}function Tc(t){throw new dt(lt.INTERNAL_ERROR,"Internal error: "+t)}/**
2019 * @license
2020 * Copyright 2017 Google LLC
2021 *
2022 * Licensed under the Apache License, Version 2.0 (the "License");
2023 * you may not use this file except in compliance with the License.
2024 * You may obtain a copy of the License at
2025 *
2026 *   http://www.apache.org/licenses/LICENSE-2.0
2027 *
2028 * Unless required by applicable law or agreed to in writing, software
2029 * distributed under the License is distributed on an "AS IS" BASIS,
2030 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
2031 * See the License for the specific language governing permissions and
2032 * limitations under the License.
2033 */class Ha{constructor(e,a){this.bucket=e,this.path_=a}get path(){return this.path_}get isRoot(){return this.path.length===0}fullServerUrl(){const e=encodeURIComponent;return"/b/"+e(this.bucket)+"/o/"+e(this.path)}bucketOnlyServerUrl(){return"/b/"+encodeURIComponent(this.bucket)+"/o"}static makeFromBucketSpec(e,a){let n;try{n=Ha.makeFromUrl(e,a)}catch{return new Ha(e,"")}if(n.path==="")return n;throw MJ(e)}static makeFromUrl(e,a){let n=null;const i="([A-Za-z0-9.\\-_]+)";function r(T){T.path.charAt(T.path.length-1)==="/"&&(T.path_=T.path_.slice(0,-1))}const o="(/(.*))?$",l=new RegExp("^gs://"+i+o,"i"),c={bucket:1,path:3};function d(T){T.path_=decodeURIComponent(T.path)}const u="v[A-Za-z0-9_]+",p=a.replace(/[.]/g,"\\."),m="(/([^?#]*).*)?$",h=new RegExp(`^https?://${p}/${u}/b/${i}/o${m}`,"i"),g={bucket:1,path:3},y=a===f3?"(?:storage.googleapis.com|storage.cloud.google.com)":a,x="([^?#]*)",v=new RegExp(`^https?://${y}/${i}/${x}`,"i"),S=[{regex:l,indices:c,postModify:r},{regex:h,indices:g,postModify:d},{regex:v,indices:{bucket:1,path:2},postModify:d}];for(let T=0;T<S.length;T++){const P=S[T],M=P.regex.exec(e);if(M){const C=M[P.indices.bucket];let E=M[P.indices.path];E||(E=""),n=new Ha(C,E),P.postModify(n);break}}if(n==null)throw OJ(e);return n}}class FJ{constructor(e){this.promise_=Promise.reject(e)}getPromise(){return this.promise_}cancel(e=!1){}}/**
2034 * @license
2035 * Copyright 2017 Google LLC
2036 *
2037 * Licensed under the Apache License, Version 2.0 (the "License");
2038 * you may not use this file except in compliance with the License.
2039 * You may obtain a copy of the License at
2040 *
2041 *   http://www.apache.org/licenses/LICENSE-2.0
2042 *
2043 * Unless required by applicable law or agreed to in writing, software
2044 * distributed under the License is distributed on an "AS IS" BASIS,
2045 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
2046 * See the License for the specific language governing permissions and
2047 * limitations under the License.
2048 */function BJ(t,e,a){let n=1,i=null,r=null,o=!1,l=0;function c(){return l===2}let d=!1;function u(...x){d||(d=!0,e.apply(null,x))}function p(x){i=setTimeout(()=>{i=null,t(h,c())},x)}function m(){r&&clearTimeout(r)}function h(x,...v){if(d){m();return}if(x){m(),u.call(null,x,...v);return}if(c()||o){m(),u.call(null,x,...v);return}n<64&&(n*=2);let S;l===1?(l=2,S=0):S=(n+Math.random())*1e3,p(S)}let g=!1;function y(x){g||(g=!0,m(),!d&&(i!==null?(x||(l=2),clearTimeout(i),p(0)):x||(l=1)))}return p(0),r=setTimeout(()=>{o=!0,y(!0)},a),y}function UJ(t){t(!1)}/**
2049 * @license
2050 * Copyright 2017 Google LLC
2051 *
2052 * Licensed under the Apache License, Version 2.0 (the "License");
2053 * you may not use this file except in compliance with the License.
2054 * You may obtain a copy of the License at
2055 *
2056 *   http://www.apache.org/licenses/LICENSE-2.0
2057 *
2058 * Unless required by applicable law or agreed to in writing, software
2059 * distributed under the License is distributed on an "AS IS" BASIS,
2060 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
2061 * See the License for the specific language governing permissions and
2062 * limitations under the License.
2063 */function $J(t){return t!==void 0}function WJ(t){return typeof t=="object"&&!Array.isArray(t)}function _k(t){return typeof t=="string"||t instanceof String}function OC(t){return Ak()&&t instanceof Blob}function Ak(){return typeof Blob<"u"}function MC(t,e,a,n){if(n<e)throw hb(`Invalid value for '${t}'. Expected ${e} or greater.`);if(n>a)throw hb(`Invalid value for '${t}'. Expected ${a} or less.`)}/**
2064 * @license
2065 * Copyright 2017 Google LLC
2066 *
2067 * Licensed under the Apache License, Version 2.0 (the "License");
2068 * you may not use this file except in compliance with the License.
2069 * You may obtain a copy of the License at
2070 *
2071 *   http://www.apache.org/licenses/LICENSE-2.0
2072 *
2073 * Unless required by applicable law or agreed to in writing, software
2074 * distributed under the License is distributed on an "AS IS" BASIS,
2075 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
2076 * See the License for the specific language governing permissions and
2077 * limitations under the License.
2078 */function Ek(t,e,a){let n=e;return a==null&&(n=`https://${e}`),`${a}://${n}/v0${t}`}function x3(t){const e=encodeURIComponent;let a="?";for(const n in t)if(t.hasOwnProperty(n)){const i=e(n)+"="+e(t[n]);a=a+i+"&"}return a=a.slice(0,-1),a}var Oo;(function(t){t[t.NO_ERROR=0]="NO_ERROR",t[t.NETWORK_ERROR=1]="NETWORK_ERROR",t[t.ABORT=2]="ABORT"})(Oo||(Oo={}));/**
2079 * @license
2080 * Copyright 2022 Google LLC
2081 *
2082 * Licensed under the Apache License, Version 2.0 (the "License");
2083 * you may not use this file except in compliance with the License.
2084 * You may obtain a copy of the License at
2085 *
2086 *   http://www.apache.org/licenses/LICENSE-2.0
2087 *
2088 * Unless required by applicable law or agreed to in writing, software
2089 * distributed under the License is distributed on an "AS IS" BASIS,
2090 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
2091 * See the License for the specific language governing permissions and
2092 * limitations under the License.
2093 */function GJ(t,e){const a=t>=500&&t<600,i=[408,429].indexOf(t)!==-1,r=e.indexOf(t)!==-1;return a||i||r}/**
2094 * @license
2095 * Copyright 2017 Google LLC
2096 *
2097 * Licensed under the Apache License, Version 2.0 (the "License");
2098 * you may not use this file except in compliance with the License.
2099 * You may obtain a copy of the License at
2100 *
2101 *   http://www.apache.org/licenses/LICENSE-2.0
2102 *
2103 * Unless required by applicable law or agreed to in writing, software
2104 * distributed under the License is distributed on an "AS IS" BASIS,
2105 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
2106 * See the License for the specific language governing permissions and
2107 * limitations under the License.
2108 */class KJ{constructor(e,a,n,i,r,o,l,c,d,u,p,m=!0){this.url_=e,this.method_=a,this.headers_=n,this.body_=i,this.successCodes_=r,this.additionalRetryCodes_=o,this.callback_=l,this.errorCallback_=c,this.timeout_=d,this.progressCallback_=u,this.connectionFactory_=p,this.retry=m,this.pendingConnection_=null,this.backoffId_=null,this.canceled_=!1,this.appDelete_=!1,this.promise_=new Promise((h,g)=>{this.resolve_=h,this.reject_=g,this.start_()})}start_(){const e=(n,i)=>{if(i){n(!1,new Up(!1,null,!0));return}const r=this.connectionFactory_();this.pendingConnection_=r;const o=l=>{const c=l.loaded,d=l.lengthComputable?l.total:-1;this.progressCallback_!==null&&this.progressCallback_(c,d)};this.progressCallback_!==null&&r.addUploadProgressListener(o),r.send(this.url_,this.method_,this.body_,this.headers_).then(()=>{this.progressCallback_!==null&&r.removeUploadProgressListener(o),this.pendingConnection_=null;const l=r.getErrorCode()===Oo.NO_ERROR,c=r.getStatus();if(!l||GJ(c,this.additionalRetryCodes_)&&this.retry){const u=r.getErrorCode()===Oo.ABORT;n(!1,new Up(!1,null,u));return}const d=this.successCodes_.indexOf(c)!==-1;n(!0,new Up(d,r))})},a=(n,i)=>{const r=this.resolve_,o=this.reject_,l=i.connection;if(i.wasSuccessCode)try{const c=this.callback_(l,l.getResponse());$J(c)?r(c):r()}catch(c){o(c)}else if(l!==null){const c=Sk();c.serverResponse=l.getErrorText(),this.errorCallback_?o(this.errorCallback_(l,c)):o(c)}else if(i.canceled){const c=this.appDelete_?y3():LJ();o(c)}else{const c=RJ();o(c)}};this.canceled_?a(!1,new Up(!1,null,!0)):this.backoffId_=BJ(e,a,this.timeout_)}getPromise(){return this.promise_}cancel(e){this.canceled_=!0,this.appDelete_=e||!1,this.backoffId_!==null&&UJ(this.backoffId_),this.pendingConnection_!==null&&this.pendingConnection_.abort()}}class Up{constructor(e,a,n){this.wasSuccessCode=e,this.connection=a,this.canceled=!!n}}function JJ(t,e){e!==null&&e.length>0&&(t.Authorization="Firebase "+e)}function QJ(t,e){t["X-Firebase-Storage-Version"]="webjs/"+(e??"AppManager")}function XJ(t,e){e&&(t["X-Firebase-GMPID"]=e)}function YJ(t,e){e!==null&&(t["X-Firebase-AppCheck"]=e)}
2108function ZJ(t,e,a,n,i,r,o=!0){const l=x3(t.urlParams),c=t.url+l,d=Object.assign({},t.headers);return XJ(d,e),JJ(d,a),QJ(d,r),YJ(d,n),new KJ(c,t.method,d,t.body,t.successCodes,t.additionalRetryCodes,t.handler,t.errorHandler,t.timeout,t.progressCallback,i,o)}/**
2109 * @license
2110 * Copyright 2017 Google LLC
2111 *
2112 * Licensed under the Apache License, Version 2.0 (the "License");
2113 * you may not use this file except in compliance with the License.
2114 * You may obtain a copy of the License at
2115 *
2116 *   http://www.apache.org/licenses/LICENSE-2.0
2117 *
2118 * Unless required by applicable law or agreed to in writing, software
2119 * distributed under the License is distributed on an "AS IS" BASIS,
2120 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
2121 * See the License for the specific language governing permissions and
2122 * limitations under the License.
2123 */function eQ(){return typeof BlobBuilder<"u"?BlobBuilder:typeof WebKitBlobBuilder<"u"?WebKitBlobBuilder:void 0}function tQ(...t){const e=eQ();if(e!==void 0){const a=new e;for(let n=0;n<t.length;n++)a.append(t[n]);return a.getBlob()}else{if(Ak())return new Blob(t);throw new dt(lt.UNSUPPORTED_ENVIRONMENT,"This browser doesn't seem to support creating Blobs")}}function aQ(t,e,a){return t.webkitSlice?t.webkitSlice(e,a):t.mozSlice?t.mozSlice(e,a):t.slice?t.slice(e,a):null}/**
2124 * @license
2125 * Copyright 2021 Google LLC
2126 *
2127 * Licensed under the Apache License, Version 2.0 (the "License");
2128 * you may not use this file except in compliance with the License.
2129 * You may obtain a copy of the License at
2130 *
2131 *   http://www.apache.org/licenses/LICENSE-2.0
2132 *
2133 * Unless required by applicable law or agreed to in writing, software
2134 * distributed under the License is distributed on an "AS IS" BASIS,
2135 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
2136 * See the License for the specific language governing permissions and
2137 * limitations under the License.
2138 */function nQ(t){if(typeof atob>"u")throw VJ("base-64");return atob(t)}/**
2139 * @license
2140 * Copyright 2017 Google LLC
2141 *
2142 * Licensed under the Apache License, Version 2.0 (the "License");
2143 * you may not use this file except in compliance with the License.
2144 * You may obtain a copy of the License at
2145 *
2146 *   http://www.apache.org/licenses/LICENSE-2.0
2147 *
2148 * Unless required by applicable law or agreed to in writing, software
2149 * distributed under the License is distributed on an "AS IS" BASIS,
2150 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
2151 * See the License for the specific language governing permissions and
2152 * limitations under the License.
2153 */const Qn={RAW:"raw",BASE64:"base64",BASE64URL:"base64url",DATA_URL:"data_url"};class P0{constructor(e,a){this.data=e,this.contentType=a||null}}function iQ(t,e){switch(t){case Qn.RAW:return new P0(v3(e));case Qn.BASE64:case Qn.BASE64URL:return new P0(b3(t,e));case Qn.DATA_URL:return new P0(oQ(e),sQ(e))}throw Sk()}function v3(t){const e=[];for(let a=0;a<t.length;a++){let n=t.charCodeAt(a);if(n<=127)e.push(n);else if(n<=2047)e.push(192|n>>6,128|n&63);else if((n&64512)===55296)if(!(a<t.length-1&&(t.charCodeAt(a+1)&64512)===56320))e.push(239,191,189);else{const r=n,o=t.charCodeAt(++a);n=65536|(r&1023)<<10|o&1023,e.push(240|n>>18,128|n>>12&63,128|n>>6&63,128|n&63)}else(n&64512)===56320?e.push(239,191,189):e.push(224|n>>12,128|n>>6&63,128|n&63)}return new Uint8Array(e)}function rQ(t){let e;try{e=decodeURIComponent(t)}catch{throw fd(Qn.DATA_URL,"Malformed data URL.")}return v3(e)}function b3(t,e){switch(t){case Qn.BASE64:{const i=e.indexOf("-")!==-1,r=e.indexOf("_")!==-1;if(i||r)throw fd(t,"Invalid character '"+(i?"-":"_")+"' found: is it base64url encoded?");break}case Qn.BASE64URL:{const i=e.indexOf("+")!==-1,r=e.indexOf("/")!==-1;if(i||r)throw fd(t,"Invalid character '"+(i?"+":"/")+"' found: is it base64 encoded?");e=e.replace(/-/g,"+").replace(/_/g,"/");break}}let a;try{a=nQ(e)}catch(i){throw i.message.includes("polyfill")?i:fd(t,"Invalid character found")}const n=new Uint8Array(a.length);for(let i=0;i<a.length;i++)n[i]=a.charCodeAt(i);return n}class w3{constructor(e){this.base64=!1,this.contentType=null;const a=e.match(/^data:([^,]+)?,/);if(a===null)throw fd(Qn.DATA_URL,"Must be formatted 'data:[<mediatype>][;base64],<data>");const n=a[1]||null;n!=null&&(this.base64=lQ(n,";base64"),this.contentType=this.base64?n.substring(0,n.length-7):n),this.rest=e.substring(e.indexOf(",")+1)}}function oQ(t){const e=new w3(t);return e.base64?b3(Qn.BASE64,e.rest):rQ(e.rest)}function sQ(t){return new w3(t).contentType}function lQ(t,e){return t.length>=e.length?t.substring(t.length-e.length)===e:!1}/**
2154 * @license
2155 * Copyright 2017 Google LLC
2156 *
2157 * Licensed under the Apache License, Version 2.0 (the "License");
2158 * you may not use this file except in compliance with the License.
2159 * You may obtain a copy of the License at
2160 *
2161 *   http://www.apache.org/licenses/LICENSE-2.0
2162 *
2163 * Unless required by applicable law or agreed to in writing, software
2164 * distributed under the License is distributed on an "AS IS" BASIS,
2165 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
2166 * See the License for the specific language governing permissions and
2167 * limitations under the License.
2168 */class lr{constructor(e,a){let n=0,i="";OC(e)?(this.data_=e,n=e.size,i=e.type):e instanceof ArrayBuffer?(a?this.data_=new Uint8Array(e):(this.data_=new Uint8Array(e.byteLength),this.data_.set(new Uint8Array(e))),n=this.data_.length):e instanceof Uint8Array&&(a?this.data_=e:(this.data_=new Uint8Array(e.length),this.data_.set(e)),n=e.length),this.size_=n,this.type_=i}size(){return this.size_}type(){return this.type_}slice(e,a){if(OC(this.data_)){const n=this.data_,i=aQ(n,e,a);return i===null?null:new lr(i)}else{const n=new Uint8Array(this.data_.buffer,e,a-e);return new lr(n,!0)}}static getBlob(...e){if(Ak()){const a=e.map(n=>n instanceof lr?n.data_:n);return new lr(tQ.apply(null,a))}else{const a=e.map(o=>_k(o)?iQ(Qn.RAW,o).data:o.data_);let n=0;a.forEach(o=>{n+=o.byteLength});const i=new Uint8Array(n);let r=0;return a.forEach(o=>{for(let l=0;l<o.length;l++)i[r++]=o[l]}),new lr(i,!0)}}uploadData(){return this.data_}}/**
2169 * @license
2170 * Copyright 2017 Google LLC
2171 *
2172 * Licensed under the Apache License, Version 2.0 (the "License");
2173 * you may not use this file except in compliance with the License.
2174 * You may obtain a copy of the License at
2175 *
2176 *   http://www.apache.org/licenses/LICENSE-2.0
2177 *
2178 * Unless required by applicable law or agreed to in writing, software
2179 * distributed under the License is distributed on an "AS IS" BASIS,
2180 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
2181 * See the License for the specific language governing permissions and
2182 * limitations under the License.
2183 */function k3(t){let e;try{e=JSON.parse(t)}catch{return null}return WJ(e)?e:null}/**
2184 * @license
2185 * Copyright 2017 Google LLC
2186 *
2187 * Licensed under the Apache License, Version 2.0 (the "License");
2188 * you may not use this file except in compliance with the License.
2189 * You may obtain a copy of the License at
2190 *
2191 *   http://www.apache.org/licenses/LICENSE-2.0
2192 *
2193 * Unless required by applicable law or agreed to in writing, software
2194 * distributed under the License is distributed on an "AS IS" BASIS,
2195 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
2196 * See the License for the specific language governing permissions and
2197 * limitations under the License.
2198 */function cQ(t){if(t.length===0)return null;const e=t.lastIndexOf("/");return e===-1?"":t.slice(0,e)}function dQ(t,e){const a=e.split("/").filter(n=>n.length>0).join("/");return t.length===0?a:t+"/"+a}function S3(t){const e=t.lastIndexOf("/",t.length-2);return e===-1?t:t.slice(e+1)}/**
2199 * @license
2200 * Copyright 2017 Google LLC
2201 *
2202 * Licensed under the Apache License, Version 2.0 (the "License");
2203 * you may not use this file except in compliance with the License.
2204 * You may obtain a copy of the License at
2205 *
2206 *   http://www.apache.org/licenses/LICENSE-2.0
2207 *
2208 * Unless required by applicable law or agreed to in writing, software
2209 * distributed under the License is distributed on an "AS IS" BASIS,
2210 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
2211 * See the License for the specific language governing permissions and
2212 * limitations under the License.
2213 */function uQ(t,e){return e}let da=class{constructor(e,a,n,i){this.server=e,this.local=a||e,this.writable=!!n,this.xform=i||uQ}},$p=null;function pQ(t){return!_k(t)||t.length<2?t:S3(t)}function _3(){if($p)return $p;const t=[];t.push(new da("bucket")),t.push(new da("generation")),t.push(new da("metageneration")),t.push(new da("name","fullPath",!0));function e(r,o){return pQ(o)}const a=new da("name");a.xform=e,t.push(a);function n(r,o){return o!==void 0?Number(o):o}const i=new da("size");return i.xform=n,t.push(i),t.push(new da("timeCreated")),t.push(new da("updated")),t.push(new da("md5Hash",null,!0)),t.push(new da("cacheControl",null,!0)),t.push(new da("contentDisposition",null,!0)),t.push(new da("contentEncoding",null,!0)),t.push(new da("contentLanguage",null,!0)),t.push(new da("contentType",null,!0)),t.push(new da("metadata","customMetadata",!0)),$p=t,$p}function mQ(t,e){function a(){const n=t.bucket,i=t.fullPath,r=new Ha(n,i);return e._makeStorageReference(r)}Object.defineProperty(t,"ref",{get:a})}function hQ(t,e,a){const n={};n.type="file";const i=a.length;for(let r=0;r<i;r++){const o=a[r];n[o.local]=o.xform(n,e[o.server])}return mQ(n,t),n}function A3(t,e,a){const n=k3(e);return n===null?null:hQ(t,n,a)}function fQ(t,e,a,n){const i=k3(e);if(i===null||!_k(i.downloadTokens))return null;const r=i.downloadTokens;if(r.length===0)return null;const o=encodeURIComponent;return r.split(",").map(d=>{const u=t.bucket,p=t.fullPath,m="/b/"+o(u)+"/o/"+o(p),h=Ek(m,a,n),g=x3({alt:"media",token:d});return h+g})[0]}function gQ(t,e){const a={},n=e.length;for(let i=0;i<n;i++){const r=e[i];r.writable&&(a[r.server]=t[r.local])}return JSON.stringify(a)}class E3{constructor(e,a,n,i){this.url=e,this.method=a,this.handler=n,this.timeout=i,this.urlParam
vendor: 1,504 bytes, lines 2213-2228
2213s={},this.headers={},this.body=null,this.errorHandler=null,this.progressCallback=null,this.successCodes=[200],this.additionalRetryCodes=[]}}/**
2214 * @license
2215 * Copyright 2017 Google LLC
2216 *
2217 * Licensed under the Apache License, Version 2.0 (the "License");
2218 * you may not use this file except in compliance with the License.
2219 * You may obtain a copy of the License at
2220 *
2221 *   http://www.apache.org/licenses/LICENSE-2.0
2222 *
2223 * Unless required by applicable law or agreed to in writing, software
2224 * distributed under the License is distributed on an "AS IS" BASIS,
2225 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
2226 * See the License for the specific language governing permissions and
2227 * limitations under the License.
2228 */function C3(t){if(!t)throw Sk()}function yQ(t,e){function a(n,i){const r=A3(t,i,e);return C3(r!==null),r}return a}function xQ(t,e){function a(n,i){const r=A3(t,i,e);return C3(r!==null),fQ(r,i,t.host,t._protocol)}return a}function j3(t){function e(a,n){let i;return a.getStatus()===401?a.getErrorText().includes("Firebase App Check token is invalid")?i=IJ():i=NJ():a.getStatus()===402?i=TJ(t.bucket):a.getStatus()===403?i=PJ(t.path):i=n,i.status=a.getStatus(),i.serverResponse=n.serverResponse,i}return e}function vQ(t){const e=j3(t);function a(n,i){let r=e(n,i);return n.getStatus()===404&&(r=jJ(t.path)),r.serverResponse=i.serverResponse,r}return a}function bQ(t,e,a){const n=e.fullServerUrl(),i=Ek(n,t.host,t._protocol),r="GET",o=t.maxOperationRetryTime,l=ne
2228w E3(i,r,xQ(t,a),o);return l.errorHandler=vQ(e),l}function wQ(t,e){return t&&t.contentType||e&&e.type()||"application/octet-stream"}function kQ(t,e,a){const n=Object.assign({},a);return n.fullPath=t.path,n.size=e.size(),n.contentType||(n.contentType=wQ(null,e)),n}function SQ(t,e,a,n,i){const r=e.bucketOnlyServerUrl(),o={"X-Goog-Upload-Protocol":"multipart"};function l(){let S="";for(let T=0;T<2;T++)S=S+Math.random().toString().slice(2);return S}const c=l();o["Content-Type"]="multipart/related; boundary="+c;const d=kQ(e,n,i),u=gQ(d,a),p="--"+c+`\r
2229Content-Type: application/json; charset=utf-8\r
2230\r
2231`+u+`\r
2232--`+c+`\r
2233Content-Type: `+d.contentType+`\r
2234\r
2235`,m=`\r
2236--`+c+"--",h=lr.getBlob(p,n,m);if(h===null)throw qJ();const g={name:d.fullPath},y=Ek(r,t.host,t._protocol),x="POST",v=t.maxUploadRetryTime,w=new E3(y,x,yQ(t,a),v);return w.urlParams=g,w.headers=o,w.body=h.uploadData(),w.errorHandler=j3(e),w}class _Q{constructor(){this.sent_=!1,this.xhr_=new XMLHttpRequest,this.initXhr(),this.errorCode_=Oo.NO_ERROR,this.sendPromise_=new Promise(e=>{this.xhr_.addEventListener("abort",()=>{this.errorCode_=Oo.ABORT,e()}),this.xhr_.addEventListener("error",()=>{this.errorCode_=Oo.NETWORK_ERROR,e()}),this.xhr_.addEventListener("load",()=>{e()})})}send(e,a,n,i){if(this.sent_)throw Tc("cannot .send() more than once");if(this.sent_=!0,this.xhr_.open(a,e,!0),i!==void 0)for(const r in i)i.hasOwnProperty(r)&&this.xhr_.setRequestHeader(r,i[r].toString());return n!==void 0?this.xhr_.send(n):this.xhr_.send(),this.sendPromise_}getErrorCode(){if(!this.sent_)throw Tc("cannot .getErrorCode() before sending");return this.errorCode_}getStatus(){if(!this.sent_)throw Tc("cannot .getStatus() before sending");try{return this.xhr_.status}catch{return-1}}getResponse(){if(!this.sent_)throw Tc("cannot .getResponse() before sending");return this.xhr_.response}getErrorText(){if(!this.sent_)throw Tc("cannot .getErrorText() before sending");return this.xhr_.statusText}abort(){this.xhr_.abort()}getResponseHeader(e){return this.xhr_.getResponseHeader(e)}addUploadProgressListener(e){this.xhr_.upload!=null&&this.xhr_.upload.addEventListener("progress",e)}removeUploadProgressListener(e){this.xhr_.upload!=null&&this.xhr_.upload.removeEventListener("progress",e)}}class AQ extends _Q{initXhr(){this.xhr_.responseType="text"}}function T3(){return new AQ}/**
2237 * @license
2238 * Copyright 2019 Google LLC
2239 *
2240 * Licensed under the Apache License, Version 2.0 (the "License");
2241 * you may not use this file except in compliance with the License.
2242 * You may obtain a copy of the License at
2243 *
2244 *   http://www.apache.org/licenses/LICENSE-2.0
2245 *
2246 * Unless required by applicable law or agreed to in writing, software
2247 * distributed under the License is distributed on an "AS IS" BASIS,
2248 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
2249 * See the License for the specific language governing permissions and
2250 * limitations under the License.
2251 */class Yo{constructor(e,a){this._service=e,a instanceof Ha?this._location=a:this._location=Ha.makeFromUrl(a,e.host)}toString(){return"gs://"+this._location.bucket+"/"+this._location.path}_newRef(e,a){return new Yo(e,a)}get root(){const e=new Ha(this._location.bucket,"");return this._newRef(this._service,e)}get bucket(){return this._location.bucket}get fullPath(){return this._location.path}get name(){return S3(this._location.path)}get storage(){return this._service}get parent(){const e=cQ(this._location.path);if(e===null)return null;const a=new Ha(this._location.bucket,e);return new Yo(this._service,a)}_throwIfRoot(e){if(this._location.path==="")throw HJ(e)}}function EQ(t,e,a){t._throwIfRoot("uploadBytes");const n=SQ(t.storage,t._location,_3(),new lr(e,!0),a);return t.storage.makeRequestWithTokens(n,T3).then(i=>({metadata:i,ref:t}))}function CQ(t){t._throwIfRoot("getDownloadURL");const e=bQ(t.storage,t._location,_3());return t.storage.makeRequestWithTokens(e,T3).then(a=>{if(a===null)throw zJ();return a})}function jQ(t,e){const a=dQ(t._location.path,e),n=new Ha(t._location.bucket,a);return new Yo(t.storage,n)}/**
2252 * @license
2253 * Copyright 2017 Google LLC
2254 *
2255 * Licensed under the Apache License, Version 2.0 (the "License");
2256 * you may not use this file except in compliance with the License.
2257 * You may obtain a copy of the License at
2258 *
2259 *   http://www.apache.org/licenses/LICENSE-2.0
2260 *
2261 * Unless required by applicable law or agreed to in writing, software
2262 * distributed under the License is distributed on an "AS IS" BASIS,
2263 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
2264 * See the License for the specific language governing permissions and
2265 * limitations under the License.
2266 */function TQ(t){return/^[A-Za-z]+:\/\//.test(t)}function NQ(t,e){return new Yo(t,e)}function N3(t,e){if(t instanceof Ck){const a=t;if(a._bucket==null)throw DJ();const n=new Yo(a,a._bucket);return e!=null?N3(n,e):n}else return e!==void 0?jQ(t,e):t}function IQ(t,e){if(e&&TQ(e)){if(t instanceof Ck)return NQ(t,e);throw hb("To use ref(service, url), the first argument must be a Storage instance.")}else return N3(t,e)}function DC(t,e){const a=e==null?void 0:e[g3];return a==null?null:Ha.makeFromBucketSpec(a,t)}function PQ(t,e,a,n={}){t.host=`${e}:${a}`,t._protocol="http";const{mockUserToken:i}=n;i&&(t._overrideAuthToken=typeof i=="string"?i:zR(i,t.app.options.projectId))}class Ck{constructor(e,a,n,i,r){this.app=e,this._authProvider=a,this._appCheckProvider=n,this._url=i,this._firebaseVersion=r,this._bucket=null,this._host=f3,this._protocol="https",this._appId=null,this._deleted=!1,this._maxOperationRetryTime=EJ,this._maxUploadRetryTime=CJ,this._requests=new Set,i!=null?this._bucket=Ha.makeFromBucketSpec(i,this._host):this._bucket=DC(this._host,this.app.options)}get host(){return this._host}set host(e){this._host=e,this._url!=null?this._bucket=Ha.makeFromBucketSpec(this._url,e):this._bucket=DC(e,this.app.options)}get maxUploadRetryTime(){return this._maxUploadRetryTime}set maxUploadRetryTime(e){MC("time",0,Number.POSITIVE_INFINITY,e),this._maxUploadRetryTime=e}get maxOperationRetryTime(){return this._maxOperationRetryTime}set maxOperationRetryTime(e){MC("time",0,Number.POSITIVE_INFINITY,e),this._maxOperationRetryTime=e}async _getAuthToken(){if(this._overrideAuthToken)return this._overrideAuthToken;const e=this._authProvider.getImmediate({optional:!0});if(e){const a=await e.getToken();if(a!==null)return a.accessToken}return null}async _getAppCheckToken(){const e=this._appCheckProvider.getImmediate({optional:!0});return e?(await e.getToken()).token:null}_delete(){return this._deleted||(this._deleted=!0,this._requests.forEach(e=>e.cancel()),this._requests.clear()),Promise.resolve()}_makeStorageReference(e){return new Yo(this,e)}_makeRequest(e,a,n,i,r=!0){if(this._deleted)return new FJ(y3());{const o=ZJ(e,this._appId,n,i,a,this._firebaseVersion,r);return this._requests.add(o),o.getPromise().then(()=>this._requests.delete(o),()=>this._requests.delete(o)),o}}async makeRequestWithTokens(e,a){const[n,i]=await Promise.all([this._getAuthToken(),this._getAppCheckToken()]);return this._makeRequest(e,a,n,i).getPromise()}}const qC="@firebase/storage",zC="0.13.2";/**
2267 * @license
2268 * Copyright 2020 Google LLC
2269 *
2270 * Licensed under the Apache License, Version 2.0 (the "License");
2271 * you may not use this file except in compliance with the License.
2272 * You may obtain a copy of the License at
2273 *
2274 *   http://www.apache.org/licenses/LICENSE-2.0
2275 *
2276 * Unless required by applicable law or agreed to in writing, software
2277 * distributed under the License is distributed on an "AS IS" BASIS,
2278 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
2279 * See the License for the specific language governing permissions and
2280 * limitations under the License.
2281 */const I3="storage";function jk(t,e,a){return t=et(t),EQ(t,e,a)}function Tk(t){return t=et(t),CQ(t)}function Nk(t,e){return t=et(t),IQ(t,e)}function RQ(t=mg(),e){t=et(t);const n=Qr(t,I3).getImmediate({identifier:e}),i=MR("storage");return i&&LQ(n,...i),n}function LQ(t,e,a,n={}){PQ(t,e,a,n)}function OQ(t,{instanceIdentifier:e}){const a=t.getProvider("app").getImmediate(),n=t.getProvider("auth-internal"),i=t.getProvider("app-check-internal");return new Ck(a,n,i,e,us)}function MQ(){Dn(new hn(I3,OQ,"PUBLIC").setMultipleInstances(!0)),Na(qC,zC,""),Na(qC,zC,"esm2017")}MQ();var DQ="firebase",qQ="10.14.1";/**
2282 * @license
2283 * Copyright 2020 Google LLC
2284 *
2285 * Licensed under the Apache License, Version 2.0 (the "License");
2286 * you may not use this file except in compliance with the License.
2287 * You may obtain a copy of the License at
2288 *
2289 *   http://www.apache.org/licenses/LICENSE-2.0
2290 *
2291 * Unless required by applicable law or agreed to in writing, software
2292 * distributed under the License is distributed on an "AS IS" BASIS,
2293 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
2294 * See the License for the specific language governing permissions and
2295 * limitations under the License.
2296 */Na(DQ,qQ,"app");function Ik(t,e){var a={};for(var n in t)Object.prototype.hasOwnProperty.call(t,n)&&e.indexOf(n)<0&&(a[n]=t[n]);if(t!=null&&typeof Object.getOwnPropertySymbols=="function")for(var i=0,n=Object.getOwnPropertySymbols(t);i<n.length;i++)e.indexOf(n[i])<0&&Object.prototype.propertyIsEnumerable.call(t,n[i])&&(a[n[i]]=t[n[i]]);return a}function P3(){return{"dependent-sdk-initialized-before-auth":"Another Firebase SDK was initialized and is trying to use Auth before Auth is initialized. Please be sure to call `initializeAuth` or `getAuth` before starting any other Firebase SDK."}}const zQ=P3,R3=new ds("auth","Firebase",P3());/**
2297 * @license
2298 * Copyright 2020 Google LLC
2299 *
2300 * Licensed under the Apache License, Version 2.0 (the "License");
2301 * you may not use this file except in compliance with the License.
2302 * You may obtain a copy of the License at
2303 *
2304 *   http://www.apache.org/licenses/LICENSE-2.0
2305 *
2306 * Unless required by applicable law or agreed to in writing, software
2307 * distributed under the License is distributed on an "AS IS" BASIS,
2308 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
2309 * See the License for the specific language governing permissions and
2310 * limitations under the License.
2311 */const zh=new pg("@firebase/auth");function VQ(t,...e){zh.logLevel<=_e.WARN&&zh.warn(`Auth (${us}): ${t}`,...e)}function qm(t,...e){zh.logLevel<=_e.ERROR&&zh.error(`Auth (${us}): ${t}`,...e)}/**
2312 * @license
2313 * Copyright 2020 Google LLC
2314 *
2315 * Licensed under the Apache License, Version 2.0 (the "License");
2316 * you may not use this file except in compliance with the License.
2317 * You may obtain a copy of the License at
2318 *
2319 *   http://www.apache.org/licenses/LICENSE-2.0
2320 *
2321 * Unless required by applicable law or agreed to in writing, software
2322 * distributed under the License is distributed on an "AS IS" BASIS,
2323 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
2324 * See the License for the specific language governing permissions and
2325 * limitations under the License.
2326 */function ii(t,...e){throw Rk(t,...e)}function Pn(t,...e){return Rk(t,...e)}function Pk(t,e,a){const n=Object.assign(Object.assign({},zQ()),{[e]:a});return new ds("auth","Firebase",n).create(e,{appName:t.name})}function Mo(t){return Pk(t,"operation-not-supported-in-this-environment","Operations that alter the current user are not supported in conjunction with FirebaseServerApp")}function HQ(t,e,a){const n=a;if(!(e instanceof n))throw n.name!==e.constructor.name&&ii(t,"argument-error"),Pk(t,"argument-error",`Type of ${e.constructor.name} does not match expected instance.Did you pass a reference from a different Auth SDK?`)}function Rk(t,...e){if(typeof t!="string"){const a=e[0],n=[...e.slice(1)];return n[0]&&(n[0].appName=t.name),t._errorFactory.create(a,...n)}return R3.create(t,...e)}function ue(t,e,...a){if(!t)throw Rk(e,...a)}function ki(t){const e="INTERNAL ASSERTION FAILED: "+t;throw qm(e),new Error(e)}function Bi(t,e){t||ki(e)}/**
2327 * @license
2328 * Copyright 2020 Google LLC
2329 *
2330 * Licensed under the Apache License, Version 2.0 (the "License");
2331 * you may not use this file except in compliance with the License.
2332 * You may obtain a copy of the License at
2333 *
2334 *   http://www.apache.org/licenses/LICENSE-2.0
2335 *
2336 * Unless required by applicable law or agreed to in writing, software
2337 * distributed under the License is distributed on an "AS IS" BASIS,
2338 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
2339 * See the License for the specific language governing permissions and
2340 * limitations under the License.
2341 */function fb(){var t;return typeof self<"u"&&((t=self.location)===null||t===void 0?void 0:t.href)||""}function FQ(){return VC()==="http:"||VC()==="https:"}function VC(){var t;return typeof self<"u"&&((t=self.location)===null||t===void 0?void 0:t.protocol)||null}/**
2342 * @license
2343 * Copyright 2020 Google LLC
2344 *
2345 * Licensed under the Apache License, Version 2.0 (the "License");
2346 * you may not use this file except in compliance with the License.
2347 * You may obtain a copy of the License at
2348 *
2349 *   http://www.apache.org/licenses/LICENSE-2.0
2350 *
2351 * Unless required by applicable law or agreed to in writing, software
2352 * distributed under the License is distributed on an "AS IS" BASIS,
2353 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
2354 * See the License for the specific language governing permissions and
2355 * limitations under the License.
2356 */function BQ(){return typeof navigator<"u"&&navigator&&"onLine"in navigator&&typeof navigator.onLine=="boolean"&&(FQ()||Dw()||"connection"in navigator)?navigator.onLine:!0}function UQ(){if(typeof navigator>"u")return null;const t=navigator;return t.languages&&t.languages[0]||t.language||null}/**
2357 * @license
2358 * Copyright 2020 Google LLC
2359 *
2360 * Licensed under the Apache License, Version 2.0 (the "License");
2361 * you may not use this file except in compliance with the License.
2362 * You may obtain a copy of the License at
2363 *
2364 *   http://www.apache.org/licenses/LICENSE-2.0
2365 *
2366 * Unless required by applicable law or agreed to in writing, software
2367 * distributed under the License is distributed on an "AS IS" BASIS,
2368 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
2369 * See the License for the specific language governing permissions and
2370 * limitations under the License.
2371 */class Fu{constructor(e,a){this.shortDelay=e,this.longDelay=a,Bi(a>e,"Short delay should be less than long delay!"),this.isMobile=ZU()||a$()}get(){return BQ()?this.isMobile?this.longDelay:this.shortDelay:Math.min(5e3,this.shortDelay)}}/**
2372 * @license
2373 * Copyright 2020 Google LLC
2374 *
2375 * Licensed under the Apache License, Version 2.0 (the "License");
2376 * you may not use this file except in compliance with the License.
2377 * You may obtain a copy of the License at
2378 *
2379 *   http://www.apache.org/licenses/LICENSE-2.0
2380 *
2381 * Unless required by applicable law or agreed to in writing, software
2382 * distributed under the License is distributed on an "AS IS" BASIS,
2383 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
2384 * See the License for the specific language governing permissions and
2385 * limitations under the License.
2386 */function Lk(t,e){Bi(t.emulator,"Emulator should always be set here");const{url:a}=t.emulator;return e?`${a}${e.startsWith("/")?e.slice(1):e}`:a}/**
2387 * @license
2388 * Copyright 2020 Google LLC
2389 *
2390 * Licensed under the Apache License, Version 2.0 (the "License");
2391 * you may not use this file except in compliance with the License.
2392 * You may obtain a copy of the License at
2393 *
2394 *   http://www.apache.org/licenses/LICENSE-2.0
2395 *
2396 * Unless required by applicable law or agreed to in writing, software
2397 * distributed under the License is distributed on an "AS IS" BASIS,
2398 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
2399 * See the License for the specific language governing permissions and
2400 * limitations under the License.
2401 */class L3{static initialize(e,a,n){this.fetchImpl=e,a&&(this.headersImpl=a),n&&(this.responseImpl=n)}static fetch(){if(this.fetchImpl)return this.fetchImpl;if(typeof self<"u"&&"fetch"in self)return self.fetch;if(typeof globalThis<"u"&&globalThis.fetch)return globalThis.fetch;if(typeof fetch<"u")return fetch;ki("Could not find fetch implementation, make sure you call FetchProvider.initialize() with an appropriate polyfill")}static headers(){if(this.headersImpl)return this.headersImpl;if(typeof self<"u"&&"Headers"in self)return self.Headers;if(typeof globalThis<"u"&&globalThis.Headers)return globalThis.Headers;if(typeof Headers<"u")return Headers;ki("Could not find Headers implementation, make sure you call FetchProvider.initialize() with an appropriate polyfill")}static response(){if(this.responseImpl)return this.responseImpl;if(typeof self<"u"&&"Response"in self)return self.Response;if(typeof globalThis<"u"&&globalThis.Response)return globalThis.Response;if(typeof Response<"u")return Response;ki("Could not find Response implementation, make sure you call FetchProvider.initialize() with an appropriate polyfill")}}/**
2402 * @license
2403 * Copyright 2020 Google LLC
2404 *
2405 * Licensed under the Apache License, Version 2.0 (the "License");
2406 * you may not use this file except in compliance with the License.
2407 * You may obtain a copy of the License at
2408 *
2409 *   http://www.apache.org/licenses/LICENSE-2.0
2410 *
2411 * Unless required by applicable law or agreed to in writing, software
2412 * distributed under the License is distributed on an "AS IS" BASIS,
2413 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
2414 * See the License for the specific language governing permissions and
2415 * limitations under the License.
2416 */const $Q={CREDENTIAL_MISMATCH:"custom-token-mismatch",MISSING_CUSTOM_TOKEN:"internal-error",INVALID_IDENTIFIER:"invalid-email",MISSING_CONTINUE_URI:"internal-error",INVALID_PASSWORD:"wrong-password",MISSING_PASSWORD:"missing-password",INVALID_LOGIN_CREDENTIALS:"invalid-credential",EMAIL_EXISTS:"email-already-in-use",PASSWORD_LOGIN_DISABLED:"operation-not-allowed",INVALID_IDP_RESPONSE:"invalid-credential",INVALID_PENDING_TOKEN:"invalid-credential",FEDERATED_USER_ID_ALREADY_LINKED:"credential-already-in-use",MISSING_REQ_TYPE:"internal-error",EMAIL_NOT_FOUND:"user-not-found",RESET_PASSWORD_EXCEED_LIMIT:"too-many-requests",EXPIRED_OOB_CODE:"expired-action-code",INVALID_OOB_CODE:"invalid-action-code",MISSING_OOB_CODE:"internal-error",CREDENTIAL_TOO_OLD_LOGIN_AGAIN:"requires-recent-login",INVALID_ID_TOKEN:"invalid-user-token",TOKEN_EXPIRED:"user-token-expired",USER_NOT_FOUND:"user-token-expired",TOO_MANY_ATTEMPTS_TRY_LATER:"too-many-requests",PASSWORD_DOES_NOT_MEET_REQUIREMENTS:"password-does-not-meet-requirements",INVALID_CODE:"invalid-verification-code",INVALID_SESSION_INFO:"invalid-verification-id",INVALID_TEMPORARY_PROOF:"invalid-credential",MISSING_SESSION_INFO:"missing-verification-id",SESSION_EXPIRED:"code-expired",MISSING_ANDROID_PACKAGE_NAME:"missing-android-pkg-name",UNAUTHORIZED_DOMAIN:"unauthorized-continue-uri",INVALID_OAUTH_CLIENT_ID:"invalid-oauth-client-id",ADMIN_ONLY_OPERATION:"admin-restricted-operation",INVALID_MFA_PENDING_CREDENTIAL:"invalid-multi-factor-session",MFA_ENROLLMENT_NOT_FOUND:"multi-factor-info-not-found",MISSING_MFA_ENROLLMENT_ID:"missing-multi-factor-info",MISSING_MFA_PENDING_CREDENTIAL:"missing-multi-factor-session",SECOND_FACTOR_EXISTS:"second-factor-already-in-use",SECOND_FACTOR_LIMIT_EXCEEDED:"maximum-second-factor-count-exceeded",BLOCKING_FUNCTION_ERROR_RESPONSE:"internal-error",RECAPTCHA_NOT_ENABLED:"recaptcha-not-enabled",MISSING_RECAPTCHA_TOKEN:"missing-recaptcha-token",INVALID_RECAPTCHA_TOKEN:"invalid-recaptcha-token",INVALID_RECAPTCHA_ACTION:"invalid-recaptcha-action",MISSING_CLIENT_TYPE:"missing-client-type",MISSING_RECAPTCHA_VERSION:"missing-recaptcha-version",INVALID_RECAPTCHA_VERSION:"invalid-recaptcha-version",INVALID_REQ_TYPE:"invalid-req-type"};/**
2417 * @license
2418 * Copyright 2020 Google LLC
2419 *
2420 * Licensed under the Apache License, Version 2.0 (the "License");
2421 * you may not use this file except in compliance with the License.
2422 * You may obtain a copy of the License at
2423 *
2424 *   http://www.apache.org/licenses/LICENSE-2.0
2425 *
2426 * Unless required by applicable law or agreed to in writing, software
2427 * distributed under the License is distributed on an "AS IS" BASIS,
2428 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
2429 * See the License for the specific language governing permissions and
2430 * limitations under the License.
2431 */const WQ=new Fu(3e4,6e4);function Ok(t,e){return t.tenantId&&!e.tenantId?Object.assign(Object.assign({},e),{tenantId:t.tenantId}):e}async function Yl(t,e,a,n,i={}){return O3(t,i,async()=>{let r={},o={};n&&(e==="GET"?o=n:r={body:JSON.stringify(n)});const l=Ru(Object.assign({key:t.config.apiKey},o)).slice(1),c=await t._getAdditionalHeaders();c["Content-Type"]="application/json",t.languageCode&&(c["X-Firebase-Locale"]=t.languageCode);const d=Object.assign({method:e,headers:c},r);return t$()||(d.referrerPolicy="no-referrer"),L3.fetch()(M3(t,t.config.apiHost,a,l),d)})}async function O3(t,e,a){t._canInitEmulator=!1;const n=Object.assign(Object.assign({},$Q),e);try{const i=new KQ(t),r=await Promise.race([a(),i.promise]);i.clearNetworkTimeout();const o=await r.json();if("needConfirmation"in o)throw Wp(t,"account-exists-with-different-credential",o);if(r.ok&&!("errorMessage"in o))return o;{const l=r.ok?o.errorMessage:o.error.message,[c,d]=l.split(" : ");if(c==="FEDERATED_USER_ID_ALREADY_LINKED")throw Wp(t,"credential-already-in-use",o);if(c==="EMAIL_EXISTS")throw Wp(t,"email-already-in-use",o);if(c==="USER_DISABLED")throw Wp(t,"user-disabled",o);const u=n[c]||c.toLowerCase().replace(/[_\s]+/g,"-");if(d)throw Pk(t,u,d);ii(t,u)}}catch(i){if(i instanceof gn)throw i;ii(t,"network-request-failed",{message:String(i)})}}async function GQ(t,e,a,n,i={}){const r=await Yl(t,e,a,n,i);return"mfaPendingCredential"in r&&ii(t,"multi-factor-auth-required",{_serverResponse:r}),r}function M3(t,e,a,n){const i=`${e}${a}?${n}`;return t.config.emulator?Lk(t.config,i):`${t.config.apiScheme}://${i}`}class KQ{constructor(e){this.auth=e,this.timer=null,this.promise=new Promise((a,n)=>{this.timer=setTimeout(()=>n(Pn(this.auth,"network-request-failed")),WQ.get())})}clearNetworkTimeout(){clearTimeout(this.timer)}}function Wp(t,e,a){const n={appName:t.name};a.email&&(n.email=a.email),a.phoneNumber&&(n.phoneNumber=a.phoneNumber);const i=Pn(t,e,n);return i.customData._tokenResponse=a,i}/**
2432 * @license
2433 * Copyright 2020 Google LLC
2434 *
2435 * Licensed under the Apache License, Version 2.0 (the "License");
2436 * you may not use this file except in compliance with the License.
2437 * You may obtain a copy of the License at
2438 *
2439 *   http://www.apache.org/licenses/LICENSE-2.0
2440 *
2441 * Unless required by applicable law or agreed to in writing, software
2442 * distributed under the License is distributed on an "AS IS" BASIS,
2443 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
2444 * See the License for the specific language governing permissions and
2445 * limitations under the License.
2446 */async function JQ(t,e){return Yl(t,"POST","/v1/accounts:delete",e)}async function D3(t,e){return Yl(t,"POST","/v1/accounts:lookup",e)}/**
2447 * @license
2448 * Copyright 2020 Google LLC
2449 *
2450 * Licensed under the Apache License, Version 2.0 (the "License");
2451 * you may not use this file except in compliance with the License.
2452 * You may obtain a copy of the License at
2453 *
2454 *   http://www.apache.org/licenses/LICENSE-2.0
2455 *
2456 * Unless required by applicable law or agreed to in writing, software
2457 * distributed under the License is distributed on an "AS IS" BASIS,
2458 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
2459 * See the License for the specific language governing permissions and
2460 * limitations under the License.
2461 */function gd(t){if(t)try{const e=new Date(Number(t));if(!isNaN(e.getTime()))return e.toUTCString()}catch{}}async function QQ(t,e=!1){const a=et(t),n=await a.getIdToken(e),i=Mk(n);ue(i&&i.exp&&i.auth_time&&i.iat,a.auth,"internal-error");const r=typeof i.firebase=="object"?i.firebase:void 0,o=r==null?void 0:r.sign_in_provider;return{claims:i,token:n,authTime:gd(R0(i.auth_time)),issuedAtTime:gd(R0(i.iat)),expirationTime:gd(R0(i.exp)),signInProvider:o||null,signInSecondFactor:(r==null?void 0:r.sign_in_second_factor)||null}}function R0(t){return Number(t)*1e3}function Mk(t){const[e,a,n]=t.split(".");if(e===void 0||a===void 0||n===void 0)return qm("JWT malformed, contained fewer than 3 sections"),null;try{const i=LR(a);return i?JSON.parse(i):(qm("Failed to decode base64 JWT payload"),null)}catch(i){return qm("Caught error parsing JWT payload as JSON",i==null?void 0:i.toString()),null}}function HC(t){const e=Mk(t);return ue(e,"internal-error"),ue(typeof e.exp<"u","internal-error"),ue(typeof e.iat<"u","internal-error"),Number(e.exp)-Number(e.iat)}/**
2462 * @license
2463 * Copyright 2020 Google LLC
2464 *
2465 * Licensed under the Apache License, Version 2.0 (the "License");
2466 * you may not use this file except in compliance with the License.
2467 * You may obtain a copy of the License at
2468 *
2469 *   http://www.apache.org/licenses/LICENSE-2.0
2470 *
2471 * Unless required by applicable law or agreed to in writing, software
2472 * distributed under the License is distributed on an "AS IS" BASIS,
2473 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
2474 * See the License for the specific language governing permissions and
2475 * limitations under the License.
2476 */async function cu(t,e,a=!1){if(a)return e;try{return await e}catch(n){throw n instanceof gn&&XQ(n)&&t.auth.currentUser===t&&await t.auth.signOut(),n}}function XQ({code:t}){return t==="auth/user-disabled"||t==="auth/user-token-expired"}/**
2477 * @license
2478 * Copyright 2020 Google LLC
2479 *
2480 * Licensed under the Apache License, Version 2.0 (the "License");
2481 * you may not use this file except in compliance with the License.
2482 * You may obtain a copy of the License at
2483 *
2484 *   http://www.apache.org/licenses/LICENSE-2.0
2485 *
2486 * Unless required by applicable law or agreed to in writing, software
2487 * distributed under the License is distributed on an "AS IS" BASIS,
2488 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
2489 * See the License for the specific language governing permissions and
2490 * limitations under the License.
2491 */class YQ{constructor(e){this.user=e,this.isRunning=!1,this.timerId=null,this.errorBackoff=3e4}_start(){this.isRunning||(this.isRunning=!0,this.schedule())}_stop(){this.isRunning&&(this.isRunning=!1,this.timerId!==null&&clearTimeout(this.timerId))}getInterval(e){var a;if(e){const n=this.errorBackoff;return this.errorBackoff=Math.min(this.errorBackoff*2,96e4),n}else{this.errorBackoff=3e4;const i=((a=this.user.stsTokenManager.expirationTime)!==null&&a!==void 0?a:0)-Date.now()-3e5;return Math.max(0,i)}}schedule(e=!1){if(!this.isRunning)return;const a=this.getInterval(e);this.timerId=setTimeout(async()=>{await this.iteration()},a)}async iteration(){try{await this.user.getIdToken(!0)}catch(e){(e==null?void 0:e.code)==="auth/network-request-failed"&&this.schedule(!0);return}this.schedule()}}/**
2492 * @license
2493 * Copyright 2020 Google LLC
2494 *
2495 * Licensed under the Apache License, Version 2.0 (the "License");
2496 * you may not use this file except in compliance with the License.
2497 * You may obtain a copy of the License at
2498 *
2499 *   http://www.apache.org/licenses/LICENSE-2.0
2500 *
2501 * Unless required by applicable law or agreed to in writing, software
2502 * distributed under the License is distributed on an "AS IS" BASIS,
2503 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
2504 * See the License for the specific language governing permissions and
2505 * limitations under the License.
2506 */class gb{constructor(e,a){this.createdAt=e,this.lastLoginAt=a,this._initializeTime()}_initializeTime(){this.lastSignInTime=gd(this.lastLoginAt),this.creationTime=gd(this.createdAt)}_copy(e){this.createdAt=e.createdAt,this.lastLoginAt=e.lastLoginAt,this._initializeTime()}toJSON(){return{createdAt:this.createdAt,lastLoginAt:this.lastLoginAt}}}/**
2507 * @license
2508 * Copyright 2019 Google LLC
2509 *
2510 * Licensed under the Apache License, Version 2.0 (the "License");
2511 * you may not use this file except in compliance with the License.
2512 * You may obtain a copy of the License at
2513 *
2514 *   http://www.apache.org/licenses/LICENSE-2.0
2515 *
2516 * Unless required by applicable law or agreed to in writing, software
2517 * distributed under the License is distributed on an "AS IS" BASIS,
2518 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
2519 * See the License for the specific language governing permissions and
2520 * limitations under the License.
2521 */async function Vh(t){var e;const a=t.auth,n=await t.getIdToken(),i=await cu(t,D3(a,{idToken:n}));ue(i==null?void 0:i.users.length,a,"internal-error");const r=i.users[0];t._notifyReloadListener(r);const o=!((e=r.providerUserInfo)===null||e===void 0)&&e.length?q3(r.providerUserInfo):[],l=eX(t.providerData,o),c=t.isAnonymous,d=!(t.email&&r.passwordHash)&&!(l!=null&&l.length),u=c?d:!1,p={uid:r.localId,displayName:r.displayName||null,photoURL:r.photoUrl||null,email:r.email||null,emailVerified:r.emailVerified||!1,phoneNumber:r.phoneNumber||null,tenantId:r.tenantId||null,providerData:l,metadata:new gb(r.createdAt,r.lastLoginAt),isAnonymous:u};Object.assign(t,p)}async function ZQ(t){const e=et(t);await Vh(e),await e.auth._persistUserIfCurrent(e),e.auth._notifyListenersIfCurrent(e)}function eX(t,e){return[...t.filter(n=>!e.some(i=>i.providerId===n.providerId)),...e]}function q3(t){return t.map(e=>{var{providerId:a}=e,n=Ik(e,["providerId"]);return{providerId:a,uid:n.rawId||"",displayName:n.displayName||null,email:n.email||null,phoneNumber:n.phoneNumber||null,photoURL:n.photoUrl||null}})}/**
2522 * @license
2523 * Copyright 2020 Google LLC
2524 *
2525 * Licensed under the Apache License, Version 2.0 (the "License");
2526 * you may not use this file except in compliance with the License.
2527 * You may obtain a copy of the License at
2528 *
2529 *   http://www.apache.org/licenses/LICENSE-2.0
2530 *
2531 * Unless required by applicable law or agreed to in writing, software
2532 * distributed under the License is distributed on an "AS IS" BASIS,
2533 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
2534 * See the License for the specific language governing permissions and
2535 * limitations under the License.
2536 */async function tX(t,e){const a=await O3(t,{},async()=>{const n=Ru({grant_type:"refresh_token",refresh_token:e}).slice(1),{tokenApiHost:i,apiKey:r}=t.config,o=M3(t,i,"/v1/token",`key=${r}`),l=await t._getAdditionalHeaders();return l["Content-Type"]="application/x-www-form-urlencoded",L3.fetch()(o,{method:"POST",headers:l,body:n})});return{accessToken:a.access_token,expiresIn:a.expires_in,refreshToken:a.refresh_token}}async function aX(t,e){return Yl(t,"POST","/v2/accounts:revokeToken",Ok(t,e))}/**
2537 * @license
2538 * Copyright 2020 Google LLC
2539 *
2540 * Licensed under the Apache License, Version 2.0 (the "License");
2541 * you may not use this file except in compliance with the License.
2542 * You may obtain a copy of the License at
2543 *
2544 *   http://www.apache.org/licenses/LICENSE-2.0
2545 *
2546 * Unless required by applicable law or agreed to in writing, software
2547 * distributed under the License is distributed on an "AS IS" BASIS,
2548 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
2549 * See the License for the specific language governing permissions and
2550 * limitations under the License.
2551 */class sl{constructor(){this.refreshToken=null,this.accessToken=null,this.expirationTime=null}get isExpired(){return!this.expirationTime||Date.now()>this.expirationTime-3e4}updateFromServerResponse(e){ue(e.idToken,"internal-error"),ue(typeof e.idToken<"u","internal-error"),ue(typeof e.refreshToken<"u","internal-error");
2551const a="expiresIn"in e&&typeof e.expiresIn<"u"?Number(e.expiresIn):HC(e.idToken);this.updateTokensAndExpiration(e.idToken,e.refreshToken,a)}updateFromIdToken(e){ue(e.length!==0,"internal-error");const a=HC(e);this.updateTokensAndExpiration(e,null,a)}async getToken(e,a=!1){return!a&&this.accessToken&&!this.isExpired?this.accessToken:(ue(this.refreshToken,e,"user-token-expired"),this.refreshToken?(await this.refresh(e,this.refreshToken),this.accessToken):null)}clearRefreshToken(){this.refreshToken=null}async refresh(e,a){const{accessToken:n,refreshToken:i,expiresIn:r}=await tX(e,a);this.updateTokensAndExpiration(n,i,Number(r))}updateTokensAndExpiration(e,a,n){this.refreshToken=a||null,this.accessToken=e||null,this.expirationTime=Date.now()+n*1e3}static fromJSON(e,a){const{refreshToken:n,accessToken:i,expirationTime:r}=a,o=new sl;return n&&(ue(typeof n=="string","internal-error",{appName:e}),o.refreshToken=n),i&&(ue(typeof i=="string","internal-error",{appName:e}),o.accessToken=i),r&&(ue(typeof r=="number","internal-error",{appName:e}),o.expirationTime=r),o}toJSON(){return{refreshToken:this.refreshToken,accessToken:this.accessToken,expirationTime:this.expirationTime}}_assign(e){this.accessToken=e.accessToken,this.refreshToken=e.refreshToken,this.expirationTime=e.expirationTime}_clone(){return Object.assign(new sl,this.toJSON())}_performRefresh(){return ki("not implemented")}}/**
2552 * @license
2553 * Copyright 2020 Google LLC
2554 *
2555 * Licensed under the Apache License, Version 2.0 (the "License");
2556 * you may not use this file except in compliance with the License.
2557 * You may obtain a copy of the License at
2558 *
2559 *   http://www.apache.org/licenses/LICENSE-2.0
2560 *
2561 * Unless required by applicable law or agreed to in writing, software
2562 * distributed under the License is distributed on an "AS IS" BASIS,
2563 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
2564 * See the License for the specific language governing permissions and
2565 * limitations under the License.
2566 */function Qi(t,e){ue(typeof t=="string"||typeof t>"u","internal-error",{appName:e})}class Si{constructor(e){var{uid:a,auth:n,stsTokenManager:i}=e,r=Ik(e,["uid","auth","stsTokenManager"]);this.providerId="firebase",this.proactiveRefresh=new YQ(this),this.reloadUserInfo=null,this.reloadListener=null,this.uid=a,this.auth=n,this.stsTokenManager=i,this.accessToken=i.accessToken,this.displayName=r.displayName||null,this.email=r.email||null,this.emailVerified=r.emailVerified||!1,this.phoneNumber=r.phoneNumber||null,this.photoURL=r.photoURL||null,this.isAnonymous=r.isAnonymous||!1,this.tenantId=r.tenantId||null,this.providerData=r.providerData?[...r.providerData]:[],this.metadata=new gb(r.createdAt||void 0,r.lastLoginAt||void 0)}async getIdToken(e){const a=await cu(this,this.stsTokenManager.getToken(this.auth,e));return ue(a,this.auth,"internal-error"),this.accessToken!==a&&(this.accessToken=a,await this.auth._persistUserIfCurrent(this),this.auth._notifyListenersIfCurrent(this)),a}getIdTokenResult(e){return QQ(this,e)}reload(){return ZQ(this)}_assign(e){this!==e&&(ue(this.uid===e.uid,this.auth,"internal-error"),this.displayName=e.displayName,this.photoURL=e.photoURL,this.email=e.email,this.emailVerified=e.emailVerified,this.phoneNumber=e.phoneNumber,this.isAnonymous=e.isAnonymous,this.tenantId=e.tenantId,this.providerData=e.providerData.map(a=>Object.assign({},a)),this.metadata._copy(e.metadata),this.stsTokenManager._assign(e.stsTokenManager))}_clone(e){const a=new Si(Object.assign(Object.assign({},this),{auth:e,stsTokenManager:this.stsTokenManager._clone()}));return a.metadata._copy(this.metadata),a}_onReload(e){ue(!this.reloadListener,this.auth,"internal-error"),this.reloadListener=e,this.reloadUserInfo&&(this._notifyReloadListener(this.reloadUserInfo),this.reloadUserInfo=null)}_notifyReloadListener(e){this.reloadListener?this.reloadListener(e):this.reloadUserInfo=e}_startProactiveRefresh(){this.proactiveRefresh._start()}_stopProactiveRefresh(){this.proactiveRefresh._stop()}async _updateTokensIfNecessary(e,a=!1){let n=!1;e.idToken&&e.idToken!==this.stsTokenManager.accessToken&&(this.stsTokenManager.updateFromServerResponse(e),n=!0),a&&await Vh(this),await this.auth._persistUserIfCurrent(this),n&&this.auth._notifyListenersIfCurrent(this)}async delete(){if(wi(this.auth.app))return Promise.reject(Mo(this.auth));const e=await this.getIdToken();return await cu(this,JQ(this.auth,{idToken:e})),this.stsTokenManager.clearRefreshToken(),this.auth.signOut()}toJSON(){return Object.assign(Object.assign({uid:this.uid,email:this.email||void 0,emailVerified:this.emailVerified,displayName:this.displayName||void 0,isA
2566nonymous:this.isAnonymous,photoURL:this.photoURL||void 0,phoneNumber:this.phoneNumber||void 0,tenantId:this.tenantId||void 0,providerData:this.providerData.map(e=>Object.assign({},e)),stsTokenManager:this.stsTokenManager.toJSON(),_redirectEventId:this._redirectEventId},this.metadata.toJSON()),{apiKey:this.auth.config.apiKey,appName:this.auth.name})}get refreshToken(){return this.stsTokenManager.refreshToken||""}static _fromJSON(e,a){var n,i,r,o,l,c,d,u;const p=(n=a.displayName)!==null&&n!==void 0?n:void 0,m=(i=a.email)!==null&&i!==void 0?i:void 0,h=(r=a.phoneNumber)!==null&&r!==void 0?r:void 0,g=(o=a.photoURL)!==null&&o!==void 0?o:void 0,y=(l=a.tenantId)!==null&&l!==void 0?l:void 0,x=(c=a._redirectEventId)!==null&&c!==void 0?c:void 0,v=(d=a.createdAt)!==null&&d!==void 0?d:void 0,w=(u=a.lastLoginAt)!==null&&u!==void 0?u:void 0,{uid:S,emailVerified:T,isAnonymous:P,providerData:M,stsTokenManager:C}=a;ue(S&&C,e,"internal-error");const E=sl.fromJSON(this.name,C);ue(typeof S=="string",e,"internal-error"),Qi(p,e.name),Qi(m,e.name),ue(typeof T=="boolean",e,"internal-error"),ue(typeof P=="boolean",e,"internal-error"),Qi(h,e.name),Qi(g,e.name),Qi(y,e.name),Qi(x,e.name),Qi(v,e.name),Qi(w,e.name);const j=new Si({uid:S,auth:e,email:m,emailVerified:T,displayName:p,isAnonymous:P,photoURL:g,phoneNumber:h,tenantId:y,stsTokenManager:E,createdAt:v,lastLoginAt:w});return M&&Array.isArray(M)&&(j.providerData=M.map(N=>Object.assign({},N))),x&&(j._redirectEventId=x),j}static async _fromIdTokenResponse(e,a,n=!1){const i=new sl;i.updateFromServerResponse(a);const r=new Si({uid:a.localId,auth:e,stsTokenManager:i,isAnonymous:n});return await Vh(r),r}static async _fromGetAccountInfoResponse(e,a,n){const i=a.users[0];ue(i.localId!==void 0,"internal-error");const r=i.providerUserInfo!==void 0?q3(i.providerUserInfo):[],o=!(i.email&&i.passwordHash)&&!(r!=null&&r.length),l=new sl;l.updateFromIdToken(n);const c=new Si({uid:i.localId,auth:e,stsTokenManager:l,isAnonymous:o}),d={uid:i.localId,displayName:i.displayName||null,photoURL:i.photoUrl||null,email:i.email||null,emailVerified:i.emailVerified||!1,phoneNumber:i.phoneNumber||null,tenantId:i.tenantId||null,providerData:r,metadata:new gb(i.createdAt,i.lastLoginAt),isAnonymous:!(i.email&&i.passwordHash)&&!(r!=null&&r.length)};return Object.assign(c,d),c}}/**
2567 * @license
2568 * Copyright 2020 Google LLC
2569 *
2570 * Licensed under the Apache License, Version 2.0 (the "License");
2571 * you may not use this file except in compliance with the License.
2572 * You may obtain a copy of the License at
2573 *
2574 *   http://www.apache.org/licenses/LICENSE-2.0
2575 *
2576 * Unless required by applicable law or agreed to in writing, software
2577 * distributed under the License is distributed on an "AS IS" BASIS,
2578 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
2579 * See the License for the specific language governing permissions and
2580 * limitations under the License.
2581 */const FC=new Map;function _i(t){Bi(t instanceof Function,"Expected a class definition");let e=FC.get(t);return e?(Bi(e instanceof t,"Instance stored in cache mismatched with class"),e):(e=new t,FC.set(t,e),e)}/**
2582 * @license
2583 * Copyright 2019 Google LLC
2584 *
2585 * Licensed under the Apache License, Version 2.0 (the "License");
2586 * you may not use this file except in compliance with the License.
2587 * You may obtain a copy of the License at
2588 *
2589 *   http://www.apache.org/licenses/LICENSE-2.0
2590 *
2591 * Unless required by applicable law or agreed to in writing, software
2592 * distributed under the License is distributed on an "AS IS" BASIS,
2593 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
2594 * See the License for the specific language governing permissions and
2595 * limitations under the License.
2596 */class z3{constructor(){this.type="NONE",this.storage={}}async _isAvailable(){return!0}async _set(e,a){this.storage[e]=a}async _get(e){const a=this.storage[e];return a===void 0?null:a}async _remove(e){delete this.storage[e]}_addListener(e,a){}_removeListener(e,a){}}z3.type="NONE";const BC=z3;/**
2597 * @license
2598 * Copyright 2019 Google LLC
2599 *
2600 * Licensed under the Apache License, Version 2.0 (the "License");
2601 * you may not use this file except in compliance with the License.
2602 * You may obtain a copy of the License at
2603 *
2604 *   http://www.apache.org/licenses/LICENSE-2.0
2605 *
2606 * Unless required by applicable law or agreed to in writing, software
2607 * distributed under the License is distributed on an "AS IS" BASIS,
2608 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
2609 * See the License for the specific language governing permissions and
2610 * limitations under the License.
2611 */function zm(t,e,a){return`firebase:${t}:${e}:${a}`}class ll{constructor(e,a,n){this.persistence=e,this.auth=a,this.userKey=n;const{config:i,name:r}=this.auth;this.fullUserKey=zm(this.userKey,i.apiKey,r),this.fullPersistenceKey=zm("persistence",i.apiKey,r),this.boundEventHandler=a._onStorageEvent.bind(a),this.persistence._addListener(this.fullUserKey,this.boundEventHandler)}setCurrentUser(e){return this.persistence._set(this.fullUserKey,e.toJSON())}async getCurrentUser(){const e=await this.persistence._get(this.fullUserKey);return e?Si._fromJSON(this.auth,e):null}removeCurrentUser(){return this.persistence._remove(this.fullUserKey)}savePersistenceForRedirect(){return this.persistence._set(this.fullPersistenceKey,this.persistence.type)}async setPersistence(e){if(this.persistence===e)return;const a=await this.getCurrentUser();if(await this.removeCurrentUser(),this.persistence=e,a)return this.setCurrentUser(a)}delete(){this.persistence._removeListener(this.fullUserKey,this.boundEventHandler)}static async create(e,a,n="authUser"){if(!a.length)return new ll(_i(BC),e,n);const i=(await Promise.all(a.map(async d=>{if(await d._isAvailable())return d}))).filter(d=>d);let r=i[0]||_i(BC);const o=zm(n,e.config.apiKey,e.name);let l=null;for(const d of a)try{const u=await d._get(o);if(u){const p=Si._fromJSON(e,u);d!==r&&(l=p),r=d;break}}catch{}const c=i.filter(d=>d._shouldAllowMigration);return!r._shouldAllowMigration||!c.length?new ll(r,e,n):(r=c[0],l&&await r._set(o,l.toJSON()),await Promise.all(a.map(async d=>{if(d!==r)try{await d._remove(o)}catch{}})),new ll(r,e,n))}}/**
2612 * @license
2613 * Copyright 2020 Google LLC
2614 *
2615 * Licensed under the Apache License, Version 2.0 (the "License");
2616 * you may not use this file except in compliance with the License.
2617 * You may obtain a copy of the License at
2618 *
2619 *   http://www.apache.org/licenses/LICENSE-2.0
2620 *
2621 * Unless required by applicable law or agreed to in writing, software
2622 * distributed under the License is distributed on an "AS IS" BASIS,
2623 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
2624 * See the License for the specific language governing permissions and
2625 * limitations under the License.
2626 */function UC(t){const e=t.toLowerCase();if(e.includes("opera/")||e.includes("opr/")||e.includes("opios/"))return"Opera";if(B3(e))return"IEMobile";if(e.includes("msie")||e.includes("trident/"))return"IE";if(e.includes("edge/"))return"Edge";if(V3(e))return"Firefox";if(e.includes("silk/"))return"Silk";if($3(e))return"Blackberry";if(W3(e))return"Webos";if(H3(e))return"Safari";if((e.includes("chrome/")||F3(e))&&!e.includes("edge/"))return"Chrome";if(U3(e))return"Android";{const a=/([a-zA-Z\d\.]+)\/[a-zA-Z\d\.]*$/,n=t.match(a);if((n==null?void 0:n.length)===2)return n[1]}return"Other"}function V3(t=ra()){return/firefox\//i.test(t)}function H3(t=ra()){const e=t.toLowerCase();return e.includes("safari/")&&!e.includes("chrome/")&&!e.includes("crios/")&&!e.includes("android")}function F3(t=ra()){return/crios\//i.test(t)}function B3(t=ra()){return/iemobile/i.test(t)}function U3(t=ra()){return/android/i.test(t)}function $3(t=ra()){return/blackberry/i.test(t)}function W3(t=ra()){return/webos/i.test(t)}function Dk(t=ra()){return/iphone|ipad|ipod/i.test(t)||/macintosh/i.test(t)&&/mobile/i.test(t)}function nX(t=ra()){var e;return Dk(t)&&!!(!((e=window.navigator)===null||e===void 0)&&e.standalone)}function iX(){return n$()&&document.documentMode===10}function G3(t=ra()){return Dk(t)||U3(t)||W3(t)||$3(t)||/windows phone/i.test(t)||B3(t)}/**
2627 * @license
2628 * Copyright 2020 Google LLC
2629 *
2630 * Licensed under the Apache License, Version 2.0 (the "License");
2631 * you may not use this file except in compliance with the License.
2632 * You may obtain a copy of the License at
2633 *
2634 *   http://www.apache.org/licenses/LICENSE-2.0
2635 *
2636 * Unless required by applicable law or agreed to in writing, software
2637 * distributed under the License is distributed on an "AS IS" BASIS,
2638 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
2639 * See the License for the specific language governing permissions and
2640 * limitations under the License.
2641 */function K3(t,e=[]){let a;switch(t){case"Browser":a=UC(ra());break;case"Worker":a=`${UC(ra())}-${t}`;break;default:a=t}const n=e.length?e.join(","):"FirebaseCore-web";return`${a}/JsCore/${us}/${n}`}/**
2642 * @license
2643 * Copyright 2022 Google LLC
2644 *
2645 * Licensed under the Apache License, Version 2.0 (the "License");
2646 * you may not use this file except in compliance with the License.
2647 * You may obtain a copy of the License at
2648 *
2649 *   http://www.apache.org/licenses/LICENSE-2.0
2650 *
2651 * Unless required by applicable law or agreed to in writing, software
2652 * distributed under the License is distributed on an "AS IS" BASIS,
2653 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
2654 * See the License for the specific language governing permissions and
2655 * limitations under the License.
2656 */class rX{constructor(e){this.auth=e,this.queue=[]}pushCallback(e,a){const n=r=>new Promise((o,l)=>{try{const c=e(r);o(c)}catch(c){l(c)}});n.onAbort=a,this.queue.push(n);const i=this.queue.length-1;return()=>{this.queue[i]=()=>Promise.resolve()}}async runMiddleware(e){if(this.auth.currentUser===e)return;const a=[];try{for(const n of this.queue)await n(e),n.onAbort&&a.push(n.onAbort)}catch(n){a.reverse();for(const i of a)try{i()}catch{}throw this.auth._errorFactory.create("login-blocked",{originalMessage:n==null?void 0:n.message})}}}/**
2657 * @license
2658 * Copyright 2023 Google LLC
2659 *
2660 * Licensed under the Apache License, Version 2.0 (the "License");
2661 * you may not use this file except in compliance with the License.
2662 * You may obtain a copy of the License at
2663 *
2664 *   http://www.apache.org/licenses/LICENSE-2.0
2665 *
2666 * Unless required by applicable law or agreed to in writing, software
2667 * distributed under the License is distributed on an "AS IS" BASIS,
2668 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
2669 * See the License for the specific language governing permissions and
2670 * limitations under the License.
2671 */async function oX(t,e={}){return Yl(t,"GET","/v2/passwordPolicy",Ok(t,e))}/**
2672 * @license
2673 * Copyright 2023 Google LLC
2674 *
2675 * Licensed under the Apache License, Version 2.0 (the "License");
2676 * you may not use this file except in compliance with the License.
2677 * You may obtain a copy of the License at
2678 *
2679 *   http://www.apache.org/licenses/LICENSE-2.0
2680 *
2681 * Unless required by applicable law or agreed to in writing, software
2682 * distributed under the License is distributed on an "AS IS" BASIS,
2683 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
2684 * See the License for the specific language governing permissions and
2685 * limitations under the License.
2686 */const sX=6;class lX{constructor(e){var a,n,i,r;const o=e.customStrengthOptions;this.customStrengthOptions={},this.customStrengthOptions.minPasswordLength=(a=o.minPasswordLength)!==null&&a!==void 0?a:sX,o.maxPasswordLength&&(this.customStrengthOptions.maxPasswordLength=o.maxPasswordLength),o.containsLowercaseCharacter!==void 0&&(this.customStrengthOptions.containsLowercaseLetter=o.containsLowercaseCharacter),o.containsUppercaseCharacter!==void 0&&(this.customStrengthOptions.containsUppercaseLetter=o.containsUppercaseCharacter),o.containsNumericCharacter!==void 0&&(this.customStrengthOptions.containsNumericCharacter=o.containsNumericCharacter),o.containsNonAlphanumericCharacter!==void 0&&(this.customStrengthOptions.containsNonAlphanumericCharacter=o.containsNonAlphanumericCharacter),this.enforcementState=e.enforcementState,this.enforcementState==="ENFORCEMENT_STATE_UNSPECIFIED"&&(this.enforcementState="OFF"),this.allowedNonAlphanumericCharacters=(i=(n=e.allowedNonAlphanumericCharacters)===null||n===void 0?void 0:n.join(""))!==null&&i!==void 0?i:"",this.forceUpgradeOnSignin=(r=e.forceUpgradeOnSignin)!==null&&r!==void 0?r:!1,this.schemaVersion=e.schemaVersion}validatePassword(e){var a,n,i,r,o,l;const c={isValid:!0,passwordPolicy:this};return this.validatePasswordLengthOptions(e,c),this.validatePasswordCharacterOptions(e,c),c.isValid&&
2686(c.isValid=(a=c.meetsMinPasswordLength)!==null&&a!==void 0?a:!0),c.isValid&&(c.isValid=(n=c.meetsMaxPasswordLength)!==null&&n!==void 0?n:!0),c.isValid&&(c.isValid=(i=c.containsLowercaseLetter)!==null&&i!==void 0?i:!0),c.isValid&&(c.isValid=(r=c.containsUppercaseLetter)!==null&&r!==void 0?r:!0),c.isValid&&(c.isValid=(o=c.containsNumericCharacter)!==null&&o!==void 0?o:!0),c.isValid&&(c.isValid=(l=c.containsNonAlphanumericCharacter)!==null&&l!==void 0?l:!0),c}validatePasswordLengthOptions(e,a){const n=this.customStrengthOptions.minPasswordLength,i=this.customStrengthOptions.maxPasswordLength;n&&(a.meetsMinPasswordLength=e.length>=n),i&&(a.meetsMaxPasswordLength=e.length<=i)}validatePasswordCharacterOptions(e,a){this.updatePasswordCharacterOptionsStatuses(a,!1,!1,!1,!1);let n;for(let i=0;i<e.length;i++)n=e.charAt(i),this.updatePasswordCharacterOptionsStatuses(a,n>="a"&&n<="z",n>="A"&&n<="Z",n>="0"&&n<="9",this.allowedNonAlphanumericCharacters.includes(n))}updatePasswordCharacterOptionsStatuses(e,a,n,i,r){this.customStrengthOptions.containsLowercaseLetter&&(e.containsLowercaseLetter||(e.containsLowercaseLetter=a)),this.customStrengthOptions.containsUppercaseLetter&&(e.containsUppercaseLetter||(e.containsUppercaseLetter=n)),this.customStrengthOptions.containsNumericCharacter&&(e.containsNumericCharacter||(e.containsNumericCharacter=i)),this.customStrengthOptions.containsNonAlphanumericCharacter&&(e.containsNonAlphanumericCharacter||(e.containsNonAlphanumericCharacter=r))}}/**
2687 * @license
2688 * Copyright 2020 Google LLC
2689 *
2690 * Licensed under the Apache License, Version 2.0 (the "License");
2691 * you may not use this file except in compliance with the License.
2692 * You may obtain a copy of the License at
2693 *
2694 *   http://www.apache.org/licenses/LICENSE-2.0
2695 *
2696 * Unless required by applicable law or agreed to in writing, software
2697 * distributed under the License is distributed on an "AS IS" BASIS,
2698 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
2699 * See the License for the specific language governing permissions and
2700 * limitations under the License.
2701 */class cX{constructor(e,a,n,i){this.app=e,this.heartbeatServiceProvider=a,this.appCheckServiceProvider=n,this.config=i,this.currentUser=null,this.emulatorConfig=null,this.operations=Promise.resolve(),this.authStateSubscription=new $C(this),this.idTokenSubscription=new $C(this),this.beforeStateQueue=new rX(this),this.redirectUser=null,this.isProactiveRefreshEnabled=!1,this.EXPECTED_PASSWORD_POLICY_SCHEMA_VERSION=1,this._canInitEmulator=!0,this._isInitialized=!1,this._deleted=!1,this._initializationPromise=null,this._popupRedirectResolver=null,this._errorFactory=R3,this._agentRecaptchaConfig=null,this._tenantRecaptchaConfigs={},this._projectPasswordPolicy=null,this._tenantPasswordPolicies={},this.lastNotifiedUid=void 0,this.languageCode=null,this.tenantId=null,this.settings={appVerificationDisabledForTesting:!1},this.frameworks=[],this.name=e.name,this.clientVersion=i.sdkClientVersion}_initializeWithPersistence(e,a){return a&&(this._popupRedirectResolver=_i(a)),this._initializationPromise=this.queue(async()=>{var n,i;if(!this._deleted&&(this.persistenceManager=await ll.create(this,e),!this._deleted)){if(!((n=this._popupRedirectResolver)===null||n===void 0)&&n._shouldInitProactively)try{await this._popupRedirectResolver._initialize(this)}catch{}await this.initializeCurrentUser(a),this.lastNotifiedUid=((i=this.currentUser)===null||i===void 0?void 0:i.uid)||null,!this._deleted&&(this._isInitialized=!0)}}),this._initializationPromise}async _onStorageEvent(){if(this._deleted)return;const e=await this.assertedPersistence.getCurrentUser();if(!(!this.currentUser&&!e)){if(this.currentUser&&e&&this.currentUser.uid===e.uid){this._currentUser._assign(e),await this.currentUser.getIdToken();return}await this._updateCurrentUser(e,!0)}}async initializeCurrentUserFromIdToken(e){try{const a=await D3(this,{idToken:e}),n=await Si._fromGetAccountInfoResponse(this,a,e);await this.directlySetCurrentUser(n)}catch(a){console.warn("FirebaseServerApp could not login user with provided authIdToken: ",a),await this.directlySetCurrentUser(null)}}async initializeCurrentUser(e){var a;if(wi(this.app)){const o=this.app.settings.authIdToken;return o?new Promise(l=>{setTimeout(()=>this.initializeCurrentUserFromIdToken(o).then(l,l))}):this.directlySetCurrentUser(null)}const n=await this.assertedPersistence.getCurrentUser();let i=n,r=!1;if(e&&this.config.authDomain){await this.getOrInitRedirectPersistenceManager();const o=(a=this.redirectUser)===null||a===void 0?void 0:a._redirectEventId,l=i==null?void 0:i._redirectEventId,c=await this.tryRedirectSignIn(e);(!o||o===l)&&(c!=null&&c.user)&&(i=c.user,r=!0)}if(!i)return this.directlySetCurrentUser(null);
2701if(!i._redirectEventId){if(r)try{await this.beforeStateQueue.runMiddleware(i)}catch(o){i=n,this._popupRedirectResolver._overrideRedirectResult(this,()=>Promise.reject(o))}return i?this.reloadAndSetCurrentUserOrClear(i):this.directlySetCurrentUser(null)}return ue(this._popupRedirectResolver,this,"argument-error"),await this.getOrInitRedirectPersistenceManager(),this.redirectUser&&this.redirectUser._redirectEventId===i._redirectEventId?this.directlySetCurrentUser(i):this.reloadAndSetCurrentUserOrClear(i)}async tryRedirectSignIn(e){let a=null;try{a=await this._popupRedirectResolver._completeRedirectFn(this,e,!0)}catch{await this._setRedirectUser(null)}return a}async reloadAndSetCurrentUserOrClear(e){try{await Vh(e)}catch(a){if((a==null?void 0:a.code)!=="auth/network-request-failed")return this.directlySetCurrentUser(null)}return this.directlySetCurrentUser(e)}useDeviceLanguage(){this.languageCode=UQ()}async _delete(){this._deleted=!0}async updateCurrentUser(e){if(wi(this.app))return Promise.reject(Mo(this));const a=e?et(e):null;return a&&ue(a.auth.config.apiKey===this.config.apiKey,this,"invalid-user-token"),this._updateCurrentUser(a&&a._clone(this))}async _updateCurrentUser(e,a=!1){if(!this._deleted)return e&&ue(this.tenantId===e.tenantId,this,"tenant-id-mismatch"),a||await this.beforeStateQueue.runMiddleware(e),this.queue(async()=>{await this.directlySetCurrentUser(e),this.notifyAuthListeners()})}async signOut(){return wi(this.app)?Promise.reject(Mo(this)):(await this.beforeStateQueue.runMiddleware(null),(this.redirectPersistenceManager||this._popupRedirectResolver)&&await this._setRedirectUser(null),this._updateCurrentUser(null,!0))}setPersistence(e){return wi(this.app)?Promise.reject(Mo(this)):this.queue(async()=>{await this.assertedPersistence.setPersistence(_i(e))})}_getRecaptchaConfig(){return this.tenantId==null?this._agentRecaptchaConfig:this._tenantRecaptchaConfigs[this.tenantId]}async validatePassword(e){this._getPasswordPolicyInternal()||await this._updatePasswordPolicy();const a=this._getPasswordPolicyInternal();return a.schemaVersion!==this.EXPECTED_PASSWORD_POLICY_SCHEMA_VERSION?Promise.reject(this._errorFactory.create("unsupported-password-policy-schema-version",{})):a.validatePassword(e)}_getPasswordPolicyInternal(){return this.tenantId===null?this._projectPasswordPolicy:this._tenantPasswordPolicies[this.tenantId]}async _updatePasswordPolicy(){const e=await oX(this),a=new lX(e);this.tenantId===null?this._projectPasswordPolicy=a:this._tenantPasswordPolicies[this.tenantId]=a}_getPersistence(){return this.assertedPersistence.persistence.type}_updateErrorMap(e){this._errorFactory=new ds("auth","Firebase",e())}onAuthStateChanged(e,a,n){return this.registerStateListener(this.authStateSubscription,e,a,n)}beforeAuthStateChanged(e,a){return this.beforeStateQueue.pushCallback(e,a)}onIdTokenChanged(e,a,n){return this.registerStateListener(this.idTokenSubscription,e,a,n)}authStateReady(){return new Promise((e,a)=>{if(this.currentUser)e();else{const n=this.onAuthStateChanged(()=>{n(),e()},a)}})}async revokeAccessToken(e){if(this.currentUser){const a=await this.currentUser.getIdToken(),n={providerId:"apple.com",tokenType:"ACCESS_TOKEN",token:e,idToken:a};this.tenantId!=null&&(n.tenantId=this.tenantId),await aX(this,n)}}toJSON(){var e;return{apiKey:this.config.apiKey,authDomain:this.config.authDomain,appName:this.name,currentUser:(e=this._currentUser)===null||e===void 0?void 0:e.toJSON()}}async _setRedirectUser(e,a){const n=await this.getOrInitRedirectPersistenceManager(a);return e===null?n.removeCurrentUser():n.setCurrentUser(e)}async getOrInitRedirectPersistenceManager(e){if(!this.redirectPersistenceManager){const a=e&&_i(e)||this._popupRedirectResolver;ue(a,this,"argument-error"),this.redirectPersistenceManager=await ll.create(this,[_i(a._redirectPersistence)],"redirectUser"),this.redirectUser=await this.redirectPersistenceManager.getCurrentUser()}return this.redirectPersistenceManager}async _redirectUserForId(e){var a,n;return this._isInitialized&&await this.queue(async()=>{}),((a=this._currentUser)===null||a===void 0?void 0:a._redirectEventId)===e?this._currentUser:((n=this.redirectUser)===null||n===void 0?void 0:n._redirectEventId)===e?this.redirectUser:null}async _persistUserIfCurrent(e){if(e===this.currentUser)return this.queue(async()=>this.directlySetCurrentUser(e))}_notifyListenersIfCurrent(e){e===this.currentUser&&this.notifyAuthListeners()}_key(){return`${this.config.authDomain}:${this.config.apiKey}:${this.name}`}_startProactiveRefresh(){this.isProactiveRefreshEnabled=!0,this.currentUser&&this._currentUser._startProactiveRefresh()}_stopProactiveRefresh(){this.isProactiveRefreshEnabled=!1,this.currentUser&&this._currentUser._stopProactiveRefresh()}get _currentUser(){return this.currentUser}notifyAuthListeners(){var e,a;if(!this._isInitialized)return;this.idTokenSubscription.next(this.currentUser);const n=(a=(e=this.currentUser)===null||e===void 0?void 0:e.uid)!==null&&a!==void 0?a:null;this.lastNotifiedUid!==n&&(this.lastNotifiedUid=n,this.authStateSubscription.next(this.currentUser))}registerStateListener(e,a,n,i){if(this._deleted)return()=>{};const r=typeof a=="function"?a:a.next.bind(a);let o=!1;const l=this._isInitialized?Promise.resolve():this._initializationPromise;if(ue(l,this,"internal-error"),l.then(()=>{o||r(this.currentUser)}),typeof a=="function"){const c=e.addObserver(a,n,i);return()=>{o=!0,c()}}else{const c=e.addObserver(a);return()=>{o=!0,c()}}}async directlySetCurrentUser(e){this.currentUser&&this.currentUser!==e&&this._currentUser._stopProactiveRefresh(),e&&this.isProactiveRefreshEnabled&&e._startProactiveRefresh(),this.currentUser=e,e?await this.assertedPersistence.setCurrentUser(e):await this.assertedPersistence.removeCurrentUser()}queue(e){return this.operations=this.operations.then(e,e),this.operations}get assertedPersistence(){return ue(this.persistenceManager,this,"internal-error"),this.persistenceManager}_logFramework(e){!e||this.frameworks.includes(e)||(this.frameworks.push(e),this.frameworks.sort(),this.clientVersion=K3(this.config.clientPlatform,this._getFrameworks()))}_getFrameworks(){return this.frameworks}async _getAdditionalHeaders(){var e;const a={"X-Client-Version":this.clientVersion};this.app.options.appId&&(a["X-Firebase-gmpid"]=this.app.options.appId);const n=await((e=this.heartbeatServiceProvider.getImmediate({optional:!0}))===null||e===void 0?void 0:e.getHeartbeatsHeader());n&&(a["X-Firebase-Client"]=n);const i=await this._getAppCheckToken();return i&&(a["X-Firebase-AppCheck"]=i),a}async _getAppCheckToken(){var e;const a=await((e=this.appCheckServiceProvider.getImmediate({optional:!0}))===null||e===void 0?void 0:e.getToken());return a!=null&&a.error&&VQ(`Error while retrieving App Check token: ${a.error}`),a==null?void 0:a.token}}function jg(t){return et(t)}class $C{constructor(e){this.auth=e,this.observer=null,this.addObserver=c$(a=>this.observer=a)}get next(){return ue(this.observer,this.auth,"internal-error"),this.observer.next.bind(this.observer)}}/**
2702 * @license
2703 * Copyright 2020 Google LLC
2704 *
2705 * Licensed under the Apache License, Version 2.0 (the "License");
2706 * you may not use this file except in compliance with the License.
2707 * You may obtain a copy of the License at
2708 *
2709 *   http://www.apache.org/licenses/LICENSE-2.0
2710 *
2711 * Unless required by applicable law or agreed to in writing, software
2712 * distributed under the License is distributed on an "AS IS" BASIS,
2713 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
2714 * See the License for the specific language governing permissions and
2715 * limitations under the License.
2716 */let qk={async loadJS(){throw new Error("Unable to load external scripts")},recaptchaV2Script:"",recaptchaEnterpriseScript:"",gapiScript:""};function dX(t){qk=t}function uX(t){return qk.loadJS(t)}function pX(){return qk.gapiScript}function mX(t){return`__${t}${Math.floor(Math.random()*1e6)}`}/**
2717 * @license
2718 * Copyright 2020 Google LLC
2719 *
2720 * Licensed under the Apache License, Version 2.0 (the "License");
2721 * you may not use this file except in compliance with the License.
2722 * You may obtain a copy of the License at
2723 *
2724 *   http://www.apache.org/licenses/LICENSE-2.0
2725 *
2726 * Unless required by applicable law or agreed to in writing, software
2727 * distributed under the License is distributed on an "AS IS" BASIS,
2728 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
2729 * See the License for the specific language governing permissions and
2730 * limitations under the License.
2731 */function hX(t,e){const a=Qr(t,"auth");if(a.isInitialized()){const i=a.getImmediate(),r=a.getOptions();if(eu(r,e??{}))return i;ii(i,"already-initialized")}return a.initialize({options:e})}function fX(t,e){const a=(e==null?void 0:e.persistence)||[],n=(Array.isArray(a)?a:[a]).map(_i);e!=null&&e.errorMap&&t._updateErrorMap(e.errorMap),t._initializeWithPersistence(n,e==null?void 0:e.popupRedirectResolver)}function gX(t,e,a){const n=jg(t);ue(n._canInitEmulator,n,"emulator-config-failed"),ue(/^https?:\/\//.test(e),n,"invalid-emulator-scheme");const i=!1,r=J3(e),{host:o,port:l}=yX(e),c=l===null?"":`:${l}`;n.config.emulator={url:`${r}//${o}${c}/`},n.settings.appVerificationDisabledForTesting=!0,n.emulatorConfig=Object.freeze({host:o,port:l,protocol:r.replace(":",""),options:Object.freeze({disableWarnings:i})}),xX()}function J3(t){const e=t.indexOf(":");return e<0?"":t.substr(0,e+1)}function yX(t){const e=J3(t),a=/(\/\/)?([^?#/]+)/.exec(t.substr(e.length));if(!a)return{host:"",port:null};const n=a[2].split("@").pop()||"",i=/^(\[[^\]]+\])(:|$)/.exec(n);if(i){const r=i[1];return{host:r,port:WC(n.substr(r.length+1))}}else{const[r,o]=n.split(":");return{host:r,port:WC(o)}}}function WC(t){if(!t)return null;const e=Number(t);return isNaN(e)?null:e}function xX(){function t(){const e=document.createElement("p"),a=e.style;e.innerText="Running in emulator mode. Do not use with production credentials.",a.position="fixed",a.width="100%",a.backgroundColor="#ffffff",a.border=".1em solid #000000",a.color="#b50000",a.bottom="0px",a.left="0px",a.margin="0px",a.zIndex="10000",a.textAlign="center",e.classList.add("firebase-emulator-warning"),document.body.appendChild(e)}typeof console<"u"&&typeof console.info=="function"&&console.info("WARNING: You are using the Auth Emulator, which is intended for local testing only.  Do not use with production credentials."),typeof window<"u"&&typeof document<"u"&&(document.readyState==="loading"?window.addEventListener("DOMContentLoaded",t):t())}/**
2732 * @license
2733 * Copyright 2020 Google LLC
2734 *
2735 * Licensed under the Apache License, Version 2.0 (the "License");
2736 * you may not use this file except in compliance with the License.
2737 * You may obtain a copy of the License at
2738 *
2739 *   http://www.apache.org/licenses/LICENSE-2.0
2740 *
2741 * Unless required by applicable law or agreed to in writing, software
2742 * distributed under the License is distributed on an "AS IS" BASIS,
2743 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
2744 * See the License for the specific language governing permissions and
2745 * limitations under the License.
2746 */class Q3{constructor(e,a){this.providerId=e,this.signInMethod=a}toJSON(){return ki("not implemented")}_getIdTokenResponse(e){return ki("not implemented")}_linkToIdToken(e,a){return ki("not implemented")}_getReauthenticationResolver(e){return ki("not implemented")}}/**
2747 * @license
2748 * Copyright 2020 Google LLC
2749 *
2750 * Licensed under the Apache License, Version 2.0 (the "License");
2751 * you may not use this file except in compliance with the License.
2752 * You may obtain a copy of the License at
2753 *
2754 *   http://www.apache.org/licenses/LICENSE-2.0
2755 *
2756 * Unless required by applicable law or agreed to in writing, software
2757 * distributed under the License is distributed on an "AS IS" BASIS,
2758 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
2759 * See the License for the specific language governing permissions and
2760 * limitations under the License.
2761 */async function cl(t,e){return GQ(t,"POST","/v1/accounts:signInWithIdp",Ok(t,e))}/**
2762 * @license
2763 * Copyright 2020 Google LLC
2764 *
2765 * Licensed under the Apache License, Version 2.0 (the "License");
2766 * you may not use this file except in compliance with the License.
2767 * You may obtain a copy of the License at
2768 *
2769 *   http://www.apache.org/licenses/LICENSE-2.0
2770 *
2771 * Unless required by applicable law or agreed to in writing, software
2772 * distributed under the License is distributed on an "AS IS" BASIS,
2773 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
2774 * See the License for the specific language governing permissions and
2775 * limitations under the License.
2776 */const vX="http://localhost";class Zo extends Q3{constructor(){super(...arguments),this.pendingToken=null}static _fromParams(e){const a=new Zo(e.providerId,e.signInMethod);return e.idToken||e.accessToken?(e.idToken&&(a.idToken=e.idToken),e.accessToken&&(a.accessToken=e.accessToken),e.nonce&&!e.pendingToken&&(a.nonce=e.nonce),e.pendingToken&&(a.pendingToken=e.pendingToken)):e.oauthToken&&e.oauthTokenSecret?(a.accessToken=e.oauthToken,a.secret=e.oauthTokenSecret):ii("argument-error"),a}toJSON(){return{idToken:this.idToken,accessToken:this.accessToken,secret:this.secret,n
2776once:this.nonce,pendingToken:this.pendingToken,providerId:this.providerId,signInMethod:this.signInMethod}}static fromJSON(e){const a=typeof e=="string"?JSON.parse(e):e,{providerId:n,signInMethod:i}=a,r=Ik(a,["providerId","signInMethod"]);if(!n||!i)return null;const o=new Zo(n,i);return o.idToken=r.idToken||void 0,o.accessToken=r.accessToken||void 0,o.secret=r.secret,o.nonce=r.nonce,o.pendingToken=r.pendingToken||null,o}_getIdTokenResponse(e){const a=this.buildRequest();return cl(e,a)}_linkToIdToken(e,a){const n=this.buildRequest();return n.idToken=a,cl(e,n)}_getReauthenticationResolver(e){const a=this.buildRequest();return a.autoCreate=!1,cl(e,a)}buildRequest(){const e={requestUri:vX,returnSecureToken:!0};if(this.pendingToken)e.pendingToken=this.pendingToken;else{const a={};this.idToken&&(a.id_token=this.idToken),this.accessToken&&(a.access_token=this.accessToken),this.secret&&(a.oauth_token_secret=this.secret),a.providerId=this.providerId,this.nonce&&!this.pendingToken&&(a.nonce=this.nonce),e.postBody=Ru(a)}return e}}/**
2777 * @license
2778 * Copyright 2020 Google LLC
2779 *
2780 * Licensed under the Apache License, Version 2.0 (the "License");
2781 * you may not use this file except in compliance with the License.
2782 * You may obtain a copy of the License at
2783 *
2784 *   http://www.apache.org/licenses/LICENSE-2.0
2785 *
2786 * Unless required by applicable law or agreed to in writing, software
2787 * distributed under the License is distributed on an "AS IS" BASIS,
2788 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
2789 * See the License for the specific language governing permissions and
2790 * limitations under the License.
2791 */class zk{constructor(e){this.providerId=e,this.defaultLanguageCode=null,this.customParameters={}}setDefaultLanguage(e){this.defaultLanguageCode=e}setCustomParameters(e){return this.customParameters=e,this}getCustomParameters(){return this.customParameters}}/**
2792 * @license
2793 * Copyright 2019 Google LLC
2794 *
2795 * Licensed under the Apache License, Version 2.0 (the "License");
2796 * you may not use this file except in compliance with the License.
2797 * You may obtain a copy of the License at
2798 *
2799 *   http://www.apache.org/licenses/LICENSE-2.0
2800 *
2801 * Unless required by applicable law or agreed to in writing, software
2802 * distributed under the License is distributed on an "AS IS" BASIS,
2803 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
2804 * See the License for the specific language governing permissions and
2805 * limitations under the License.
2806 */class Bu extends zk{constructor(){super(...arguments),this.scopes=[]}addScope(e){return this.scopes.includes(e)||this.scopes.push(e),this}getScopes(){return[...this.scopes]}}/**
2807 * @license
2808 * Copyright 2020 Google LLC
2809 *
2810 * Licensed under the Apache License, Version 2.0 (the "License");
2811 * you may not use this file except in compliance with the License.
2812 * You may obtain a copy of the License at
2813 *
2814 *   http://www.apache.org/licenses/LICENSE-2.0
2815 *
2816 * Unless required by applicable law or agreed to in writing, software
2817 * distributed under the License is distributed on an "AS IS" BASIS,
2818 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
2819 * See the License for the specific language governing permissions and
2820 * limitations under the License.
2821 */class cr extends Bu{constructor(){super("facebook.com")}static credential(e){return Zo._fromParams({providerId:cr.PROVIDER_ID,signInMethod:cr.FACEBOOK_SIGN_IN_METHOD,accessToken:e})}static credentialFromResult(e){return cr.credentialFromTaggedObject(e)}static credentialFromError(e){return cr.credentialFromTaggedObject(e.customData||{})}static credentialFromTaggedObject({_tokenResponse:e}){if(!e||!("oauthAccessToken"in e)||!e.oauthAccessToken)return null;try{return cr.credential(e.oauthAccessToken)}catch{return null}}}cr.FACEBOOK_SIGN_IN_METHOD="facebook.com";cr.PROVIDER_ID="facebook.com";/**
2822 * @license
2823 * Copyright 2020 Google LLC
2824 *
2825 * Licensed under the Apache License, Version 2.0 (the "License");
2826 * you may not use this file except in compliance with the License.
2827 * You may obtain a copy of the License at
2828 *
2829 *   http://www.apache.org/licenses/LICENSE-2.0
2830 *
2831 * Unless required by applicable law or agreed to in writing, softw
2831are
2832 * distributed under the License is distributed on an "AS IS" BASIS,
2833 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
2834 * See the License for the specific language governing permissions and
2835 * limitations under the License.
2836 */class Kn extends Bu{constructor(){super("google.com"),this.addScope("profile")}static credential(e,a){return Zo._fromParams({providerId:Kn.PROVIDER_ID,signInMethod:Kn.GOOGLE_SIGN_IN_METHOD,idToken:e,accessToken:a})}static credentialFromResult(e){return Kn.credentialFromTaggedObject(e)}static credentialFromError(e){return Kn.credentialFromTaggedObject(e.customData||{})}static credentialFromTaggedObject({_tokenResponse:e}){if(!e)return null;const{oauthIdToken:a,oauthAccessToken:n}=e;if(!a&&!n)return null;try{return Kn.credential(a,n)}catch{return null}}}Kn.GOOGLE_SIGN_IN_METHOD="google.com";Kn.PROVIDER_ID="google.com";/**
2837 * @license
2838 * Copyright 2020 Google LLC
2839 *
2840 * Licensed under the Apache License, Version 2.0 (the "License");
2841 * you may not use this file except in compliance with the License.
2842 * You may obtain a copy of the License at
2843 *
2844 *   http://www.apache.org/licenses/LICENSE-2.0
2845 *
2846 * Unless required by applicable law or agreed to in writing, software
2847 * distributed under the License is distributed on an "AS IS" BASIS,
2848 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
2849 * See the License for the specific language governing permissions and
2850 * limitations under the License.
2851 */class dr extends Bu{constructor(){super("github.com")}static credential(e){return Zo._fromParams({providerId:dr.PROVIDER_ID,signInMethod:dr.GITHUB_SIGN_IN_METHOD,accessToken:e})}static credentialFromResult(e){return dr.credentialFromTaggedObject(e)}static credentialFromError(e){return dr.credentialFromTaggedObject(e.customData||{})}static credentialFromTaggedObject({_tokenResponse:e}){if(!e||!("oauthAccessToken"in e)||!e.oauthAccessToken)return null;try{return dr.credential(e.oauthAccessToken)}catch{return null}}}dr.GITHUB_SIGN_IN_METHOD="github.com";dr.PROVIDER_ID="github.com";/**
2852 * @license
2853 * Copyright 2020 Google LLC
2854 *
2855 * Licensed under the Apache License, Version 2.0 (the "License");
2856 * you may not use this file except in compliance with the License.
2857 * You may obtain a copy of the License at
2858 *
2859 *   http://www.apache.org/licenses/LICENSE-2.0
2860 *
2861 * Unless required by applicable law or agreed to in writing, software
2862 * distributed under the License is distributed on an "AS IS" BASIS,
2863 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
2864 * See the License for the specific language governing permissions and
2865 * limitations under the License.
2866 */class ur extends Bu{constructor(){super("twitter.com")}static credential(e,a){return Zo._fromParams({providerId:ur.PROVIDER_ID,signInMethod:ur.TWITTER_SIGN_IN_METHOD,oauthToken:e,oauthTokenSecret:a})}static credentialFromResult(e){return ur.credentialFromTaggedObject(e)}static credentialFromError(e){return ur.credentialFromTaggedObject(e.customData||{})}static credentialFromTaggedObject({_tokenResponse:e}){if(!e)return null;const{oauthAccessToken:a,oauthTokenSecret:n}=e;if(!a||!n)return null;try{return ur.credential(a,n)}catch{return null}}}ur.TWITTER_SIGN_IN_METHOD="twitter.com";ur.PROVIDER_ID="twitter.com";/**
2867 * @license
2868 * Copyright 2020 Google LLC
2869 *
2870 * Licensed under the Apache License, Version 2.0 (the "License");
2871 * you may not use this file except in compliance with the License.
2872 * You may obtain a copy of the License at
2873 *
2874 *   http://www.apache.org/licenses/LICENSE-2.0
2875 *
2876 * Unless required by applicable law or agreed to in writing, software
2877 * distributed under the License is distributed on an "AS IS" BASIS,
2878 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
2879 * See the License for the specific language governing permissions and
2880 * limitations under the License.
2881 */class Nl{constructor(e){this.user=e.user,this.providerId=e.providerId,this._tokenResponse=e._tokenResponse,this.operationType=e.operationType}static async _fromIdTokenResponse(e,a,n,i=!1){const r=await Si._fromIdTokenResponse(e,n,i),o=GC(n);return new Nl({user:r,providerId:o,_tokenResponse:n,operationType:a})}static async _forOperation(e,a,n){await e._updateTokensIfNecessary(n,!0);const i=GC(n);return new Nl({user:e,providerId:i,_tokenResponse:n,operationType:a})}}function GC(t){return t.providerId?t.providerId:"phoneNumber"in t?"phone":null}/**
2882 * @license
2883 * Copyright 2020 Google LLC
2884 *
2885 * Licensed under the Apache License, Version 2.0 (the "License");
2886 * you may not use this file except in compliance with the License.
2887 * You may obtain a copy of the License at
2888 *
2889 *   http://www.apache.org/licenses/LICENSE-2.0
2890 *
2891 * Unless required by applicable law or agreed to in writing, software
2892 * distributed under the License is distributed on an "AS IS" BASIS,
2893 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
2894 * See the License for the specific language governing permissions and
2895 * limitations under the License.
2896 */class Hh extends gn{constructor(e,a,n,i){var r;super(a.code,a.message),this.operationType=n,this.user=i,Object.setPrototypeOf(this,Hh.prototype),this.customData={appName:e.name,tenantId:(r=e.tenantId)!==null&&r!==void 0?r:void 0,_serverResponse:a.customData._serverResponse,operationType:n}}static _fromErrorAndOperation(e,a,n,i){return new Hh(e,a,n,i)}}function X3(t,e,a,n){return(e==="reauthenticate"?a._getReauthenticationResolver(t):a._getIdTokenResponse(t)).catch(r=>{throw r.code==="auth/multi-factor-auth-required"?Hh._fromErrorAndOperation(t,r,e,n):r})}async function bX(t,e,a=!1){const n=await cu(t,e._linkToIdToken(t.auth,await t.getIdToken()),a);return Nl._forOperation(t,"link",n)}/**
2897 * @license
2898 * Copyright 2019 Google LLC
2899 *
2900 * Licensed under the Apache License, Version 2.0 (the "License");
2901 * you may not use this file except in compliance with the License.
2902 * You may obtain a copy of the License at
2903 *
2904 *   http://www.apache.org/licenses/LICENSE-2.0
2905 *
2906 * Unless required by applicable law or agreed to in writing, software
2907 * distributed under the License is distributed on an "AS IS" BASIS,
2908 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
2909 * See the License for the specific language governing permissions and
2910 * limitations under the License.
2911 */async function wX(t,e,a=!1){const{auth:n}=t;if(wi(n.app))return Promise.reject(Mo(n));const i="reauthenticate";try{const r=await cu(t,X3(n,i,e,t),a);ue(r.idToken,n,"internal-error");const o=Mk(r.idToken);ue(o,n,"internal-error");const{sub:l}=o;return ue(t.uid===l,n,"user-mismatch"),Nl._forOperation(t,i,r)}catch(r){throw(r==null?void 0:r.code)==="auth/user-not-found"&&ii(n,"user-mismatch"),r}}/**
2912 * @license
2913 * Copyright 2020 Google LLC
2914 *
2915 * Licensed under the Apache License, Version 2.0 (the "License");
2916 * you may not use this file except in compliance with the License.
2917 * You may obtain a copy of the License at
2918 *
2919 *   http://www.apache.org/licenses/LICENSE-2.0
2920 *
2921 * Unless required by applicable law or agreed to in writing, software
2922 * distributed under the License is distributed on an "AS IS" BASIS,
2923 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
2924 * See the License for the specific language governing permissions and
2925 * limitations under the License.
2926 */async function kX(t,e,a=!1){if(wi(t.app))return Promise.reject(Mo(t));const n="signIn",i=await X3(t,n,e),r=await Nl._fromIdTokenResponse(t,n,i);return a||await t._updateCurrentUser(r.user),r}function SX(t,e,a,n){return et(t).onIdTokenChanged(e,a,n)}function _X(t,e,a){return et(t).beforeAuthStateChanged(e,a)}function Y3(t,e,a,n){return et(t).onAuthStateChanged(e,a,n)}function yd(t){return et(t).signOut()}const Fh="__sak";/**
2927 * @license
2928 * Copyright 2019 Google LLC
2929 *
2930 * Licensed under the Apache License, Version 2.0 (the "License");
2931 * you may not use this file except in compliance with the License.
2932 * You may obtain a copy of the License at
2933 *
2934 *   http://www.apache.org/licenses/LICENSE-2.0
2935 *
2936 * Unless required by applicable law or agreed to in writing, software
2937 * distributed under the License is distributed on an "AS IS" BASIS,
2938 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
2939 * See the License for the specific language governing permissions and
2940 * limitations under the License.
2941 */class Z3{constructor(e,a){this.storageRetriever=e,this.type=a}_isAvailable(){try{return this.storage?(this.storage.setItem(Fh,"1"),this.storage.removeItem(Fh),Promise.resolve(!0)):Promise.resolve(!1)}catch{return Promise.resolve(!1)}}_set(e,a){return this.storage.setItem(e,JSON.stringify(a)),Promise.resolve()}_get(e){const a=this.storage.getItem(e);return Promise.resolve(a?JSON.parse(a):null)}_remove(e){return this.storage.removeItem(e),Promise.resolve()}get storage(){return this.storageRetriever()}}/**
2942 * @license
2943 * Copyright 2020 Google LLC
2944 *
2945 * Licensed under the Apache License, Version 2.0 (the "License");
2946 * you may not use this file except in compliance with the License.
2947 * You may obtain a copy of the License at
2948 *
2949 *   http://www.apache.org/licenses/LICENSE-2.0
2950 *
2951 * Unless required by applicable law or agreed to in writing, software
2952 * distributed under the License is distributed on an "AS IS" BASIS,
2953 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
2954 * See the License for the specific language governing permissions and
2955 * limitations under the License.
2956 */const AX=1e3,EX=10;class eO extends Z3{constructor(){super(()=>window.localStorage,"LOCAL"),this.boundEventHandler=(e,a)=>this.onStorageEvent(e,a),this.listeners={},this.localCache={},this.pollTimer=null,this.fallbackToPolling=G3(),this._shouldAllowMigration=!0}forAllChangedKeys(e){for(const a of Object.keys(this.listeners)){const n=this.storage.getItem(a),i=this.localCache[a];n!==i&&e(a,i,n)}}onStorageEvent(e,a=!1){if(!e.key){this.forAllChangedKeys((o,l,c)=>{this.notifyListeners(o,c)});return}const n=e.key;a?this.detachListener():this.stopPolling();const i=()=>{const o=this.storage.getItem(n);!a&&this.localCache[n]===o||this.notifyListeners(n,o)},r=this.storage.getItem(n);iX()&&r!==e.newValue&&e.newValue!==e.oldValue?setTimeout(i,EX):i()}notifyListeners(e,a){this.localCache[e]=a;const n=this.listeners[e];if(n)for(const i of Array.from(n))i(a&&JSON.parse(a))}startPolling(){this.stopPolling(),this.pollTimer=setInterval(()=>{this.forAllChangedKeys((e,a,n)=>{this.onStorageEvent(new StorageEvent("storage",{key:e,oldValue:a,newValue:n}),!0)})},AX)}stopPolling(){this.pollTimer&&(clearInterval(this.pollTimer),this.pollTimer=null)}attachListener(){window.addEventListener("storage",this.boundEventHandler)}detachListener(){window.removeEventListener("storage",this.boundEventHandler)}_addListener(e,a){Object.keys(this.listeners).length===0&&(this.fallbackToPolling?this.startPolling():this.attachListener()),this.listeners[e]||(this.listeners[e]=new Set,this.localCache[e]=this.storage.getItem(e)),this.listeners[e].add(a)}_removeListener(e,a){this.listeners[e]&&(this.listeners[e].delete(a),this.listeners[e].size===0&&delete this.listeners[e]),Ob
2956ject.keys(this.listeners).length===0&&(this.detachListener(),this.stopPolling())}async _set(e,a){await super._set(e,a),this.localCache[e]=JSON.stringify(a)}async _get(e){const a=await super._get(e);return this.localCache[e]=JSON.stringify(a),a}async _remove(e){await super._remove(e),delete this.localCache[e]}}eO.type="LOCAL";const CX=eO;/**
2957 * @license
2958 * Copyright 2020 Google LLC
2959 *
2960 * Licensed under the Apache License, Version 2.0 (the "License");
2961 * you may not use this file except in compliance with the License.
2962 * You may obtain a copy of the License at
2963 *
2964 *   http://www.apache.org/licenses/LICENSE-2.0
2965 *
2966 * Unless required by applicable law or agreed to in writing, software
2967 * distributed under the License is distributed on an "AS IS" BASIS,
2968 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
2969 * See the License for the specific language governing permissions and
2970 * limitations under the License.
2971 */class tO extends Z3{constructor(){super(()=>window.sessionStorage,"SESSION")}_addListener(e,a){}_removeListener(e,a){}}tO.type="SESSION";const aO=tO;/**
2972 * @license
2973 * Copyright 2019 Google LLC
2974 *
2975 * Licensed under the Apache License, Version 2.0 (the "License");
2976 * you may not use this file except in compliance with the License.
2977 * You may obtain a copy of the License at
2978 *
2979 *   http://www.apache.org/licenses/LICENSE-2.0
2980 *
2981 * Unless required by applicable law or agreed to in writing, software
2982 * distributed under the License is distributed on an "AS IS" BASIS,
2983 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
2984 * See the License for the specific language governing permissions and
2985 * limitations under the License.
2986 */function jX(t){return Promise.all(t.map(async e=>{try{return{fulfilled:!0,value:await e}}catch(a){return{fulfilled:!1,reason:a}}}))}/**
2987 * @license
2988 * Copyright 2019 Google LLC
2989 *
2990 * Licensed under the Apache License, Version 2.0 (the "License");
2991 * you may not use this file except in compliance with the License.
2992 * You may obtain a copy of the License at
2993 *
2994 *   http://www.apache.org/licenses/LICENSE-2.0
2995 *
2996 * Unless required by applicable law or agreed to in writing, software
2997 * distributed under the License is distributed on an "AS IS" BASIS,
2998 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
2999 * See the License for the specific language governing permissions and
3000 * limitations under the License.
3001 */class Tg{constructor(e){this.eventTarget=e,this.handlersMap={},this.boundEventHandler=this.handleEvent.bind(this)}static _getInstance(e){const a=this.receivers.find(i=>i.isListeningto(e));if(a)return a;const n=new Tg(e);return this.receivers.push(n),n}isListeningto(e){return this.eventTarget===e}async handleEvent(e){const a=e,{eventId:n,eventType:i,data:r}=a.data,o=this.handlersMap[i];if(!(o!=null&&o.size))return;a.ports[0].postMessage({status:"ack",eventId:n,eventType:i});const l=Array.from(o).map(async d=>d(a.origin,r)),c=await jX(l);a.ports[0].postMessage({status:"done",eventId:n,eventType:i,response:c})}_subscribe(e,a){Object.keys(this.handlersMap).length===0&&this.eventTarget.addEventListener("message",this.boundEventHandler),this.handlersMap[e]||(this.handlersMap[e]=new Set),this.handlersMap[e].add(a)}_unsubscribe(e,a){this.handlersMap[e]&&a&&this.handlersMap[e].delete(a),(!a||this.handlersMap[e].size===0)&&delete this.handlersMap[e],Object.keys(this.handlersMap).length===0&&this.eventTarget.removeEventListener("message",this.boundEventHandler)}}Tg.receivers=[];/**
3002 * @license
3003 * Copyright 2020 Google LLC
3004 *
3005 * Licensed under the Apache License, Version 2.0 (the "License");
3006 * you may not use this file except in compliance with the License.
3007 * You may obtain a copy of the License at
3008 *
3009 *   http://www.apache.org/licenses/LICENSE-2.0
3010 *
3011 * Unless required by applicable law or agreed to in writing, software
3012 * distributed under the License is distributed on an "AS IS" BASIS,
3013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
3014 * See the License for the specific language governing permissions and
3015 * limitations under the License.
3016 */function Vk(t="",e=10){let a="";for(let n=0;n<e;n++)a+=Math.floor(Math.random()*10);return t+a}/**
3017 * @license
3018 * Copyright 2019 Google LLC
3019 *
3020 * Licensed under the Apache License, Version 2.0 (the "License");
3021 * you may not use this file except in compliance with the License.
3022 * You may obtain a copy of the License at
3023 *
3024 *   http://www.apache.org/licenses/LICENSE-2.0
3025 *
3026 * Unless required by applicable law or agreed to in writing, software
3027 * distributed under the License is distributed on an "AS IS" BASIS,
3028 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
3029 * See the License for the specific language governing permissions and
3030 * limitations under the License.
3031 */class TX{constructor(e){this.target=e,this.handlers=new Set}removeMessageHandler(e){e.messageChannel&&(e.messageChannel.port1.removeEventListener("message",e.onMessage),e.messageChannel.port1.close()),this.handlers.delete(e)}async _send(e,a,n=50){const i=typeof MessageChannel<"u"?new MessageChannel:null;if(!i)throw new Error("connection_unavailable");let r,o;return new Promise((l,c)=>{const d=Vk("",20);i.port1.start();const u=setTimeout(()=>{c(new Error("unsupported_event"))},n);o={messageChannel:i,onMessage(p){const m=p;if(m.data.eventId===d)switch(m.data.status){case"ack":clearTimeout(u),r=setTimeout(()=>{c(new Error("timeout"))},3e3);break;case"done":clearTimeout(r),l(m.data.response);break;default:clearTimeout(u),clearTimeout(r),c(new Error("invalid_response"));break}}},this.handlers.add(o),i.port1.addEventListener("message",o.onMessage),this.target.postMessage({eventType:e,eventId:d,data:a},[i.port2])}).finally(()=>{o&&this.removeMessageHandler(o)})}}/**
3032 * @license
3033 * Copyright 2020 Google LLC
3034 *
3035 * Licensed under the Apache License, Version 2.0 (the "License");
3036 * you may not use this file except in compliance with the License.
3037 * You may obtain a copy of the License at
3038 *
3039 *   http://www.apache.org/licenses/LICENSE-2.0
3040 *
3041 * Unless required by applicable law or agreed to in writing, software
3042 * distributed under the License is distributed on an "AS IS" BASIS,
3043 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
3044 * See the License for the specific language governing permissions and
3045 * limitations under the License.
3046 */function ai(){return window}function NX(t){ai().location.href=t}/**
3047 * @license
3048 * Copyright 2020 Google LLC.
3049 *
3050 * Licensed under the Apache License, Version 2.0 (the "License");
3051 * you may not use this file except in compliance with the License.
3052 * You may obtain a copy of the License at
3053 *
3054 *   http://www.apache.org/licenses/LICENSE-2.0
3055 *
3056 * Unless required by applicable law or agreed to in writing, software
3057 * distributed under the License is distributed on an "AS IS" BASIS,
3058 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
3059 * See the License for the specific language governing permissions and
3060 * limitations under the License.
3061 */function nO(){return typeof ai().WorkerGlobalScope<"u"&&typeof ai().importScripts=="function"}async function IX(){if(!(navigator!=null&&navigator.serviceWorker))return null;try{return(await navigator.serviceWorker.ready).active}catch{return null}}function PX(){var t;return((t=navigator==null?void 0:navigator.serviceWorker)===null||t===void 0?void 0:t.controller)||null}function RX(){return nO()?self:null}/**
3062 * @license
3063 * Copyright 2019 Google LLC
3064 *
3065 * Licensed under the Apache License, Version 2.0 (the "License");
3066 * you may not use this file except in compliance with the License.
3067 * You may obtain a copy of the License at
3068 *
3069 *   http://www.apache.org/licenses/LICENSE-2.0
3070 *
3071 * Unless required by applicable law or agreed to in writing, software
3072 * distributed under the License is distributed on an "AS IS" BASIS,
3073 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
3074 * See the License for the specific language governing permissions and
3075 * limitations under the License.
3076 */const iO="firebaseLocalStorageDb",LX=1,Bh="firebaseLocalStorage",rO="fbase_key";class Uu{constructor(e){this.request=e}toPromise(){return new Promise((e,a)=>{this.request.addEventListener("success",()=>{e(this.request.result)}),this.request.addEventListener("error",()=>{a(this.request.error)})})}}function Ng(t,e){return t.transaction([Bh],e?"readwrite":"readonly").objectStore(Bh)}function OX(){const t=indexedDB.deleteDatabase(iO);
3076return new Uu(t).toPromise()}function yb(){const t=indexedDB.open(iO,LX);return new Promise((e,a)=>{t.addEventListener("error",()=>{a(t.error)}),t.addEventListener("upgradeneeded",()=>{const n=t.result;try{n.createObjectStore(Bh,{keyPath:rO})}catch(i){a(i)}}),t.addEventListener("success",async()=>{const n=t.result;n.objectStoreNames.contains(Bh)?e(n):(n.close(),await OX(),e(await yb()))})})}async function KC(t,e,a){const n=Ng(t,!0).put({[rO]:e,value:a});return new Uu(n).toPromise()}async function MX(t,e){const a=Ng(t,!1).get(e),n=await new Uu(a).toPromise();return n===void 0?null:n.value}function JC(t,e){const a=Ng(t,!0).delete(e);return new Uu(a).toPromise()}const DX=800,qX=3;class oO{constructor(){this.type="LOCAL",this._shouldAllowMigration=!0,this.listeners={},this.localCache={},this.pollTimer=null,this.pendingWrites=0,this.receiver=null,this.sender=null,this.serviceWorkerReceiverAvailable=!1,this.activeServiceWorker=null,this._workerInitializationPromise=this.initializeServiceWorkerMessaging().then(()=>{},()=>{})}async _openDb(){return this.db?this.db:(this.db=await yb(),this.db)}async _withRetries(e){let a=0;for(;;)try{const n=await this._openDb();return await e(n)}catch(n){if(a++>qX)throw n;this.db&&(this.db.close(),this.db=void 0)}}async initializeServiceWorkerMessaging(){return nO()?this.initializeReceiver():this.initializeSender()}async initializeReceiver(){this.receiver=Tg._getInstance(RX()),this.receiver._subscribe("keyChanged",async(e,a)=>({keyProcessed:(await this._poll()).includes(a.key)})),this.receiver._subscribe("ping",async(e,a)=>["keyChanged"])}async initializeSender(){var e,a;if(this.activeServiceWorker=await IX(),!this.activeServiceWorker)return;this.sender=new TX(this.activeServiceWorker);const n=await this.sender._send("ping",{},800);n&&!((e=n[0])===null||e===void 0)&&e.fulfilled&&!((a=n[0])===null||a===void 0)&&a.value.includes("keyChanged")&&(this.serviceWorkerReceiverAvailable=!0)}async notifyServiceWorker(e){if(!(!this.sender||!this.activeServiceWorker||PX()!==this.activeServiceWorker))try{await this.sender._send("keyChanged",{key:e},this.serviceWorkerReceiverAvailable?800:50)}catch{}}async _isAvailable(){try{if(!indexedDB)return!1;const e=await yb();return await KC(e,Fh,"1"),await JC(e,Fh),!0}catch{}return!1}async _withPendingWrite(e){this.pendingWrites++;try{await e()}finally{this.pendingWrites--}}async _set(e,a){return this._withPendingWrite(async()=>(await this._withRetries(n=>KC(n,e,a)),this.localCache[e]=a,this.notifyServiceWorker(e)))}async _get(e){const a=await this._withRetries(n=>MX(n,e));return this.localCache[e]=a,a}async _remove(e){return this._withPendingWrite(async()=>(await this._withRetries(a=>JC(a,e)),delete this.localCache[e],this.notifyServiceWorker(e)))}async _poll(){const e=await this._withRetries(i=>{const r=Ng(i,!1).getAll();return new Uu(r).toPromise()});if(!e)return[];if(this.pendingWrites!==0)return[];const a=[],n=new Set;if(e.length!==0)for(const{fbase_key:i,value:r}of e)n.add(i),JSON.stringify(this.localCache[i])!==JSON.stringify(r)&&(this.notifyListeners(i,r),a.push(i));for(const i of Object.keys(this.localCache))this.localCache[i]&&!n.has(i)&&(this.notifyListeners(i,null),a.push(i));return a}notifyListeners(e,a){this.localCache[e]=a;const n=this.listeners[e];if(n)for(const i of Array.from(n))i(a)}startPolling(){this.stopPolling(),this.pollTimer=setInterval(async()=>this._poll(),DX)}stopPolling(){this.pollTimer&&(clearInterval(this.pollTimer),this.pollTimer=null)}_addListener(e,a){Object.keys(this.listeners).length===0&&this.startPolling(),this.listeners[e]||(this.listeners[e]=new Set,this._get(e)),this.listeners[e].add(a)}_removeListener(e,a){this.listeners[e]&&(this.listeners[e].delete(a),this.listeners[e].size===0&&delete this.listeners[e]),Ob
vendor: 4,318 bytes, lines 3076-3125
3076ject.keys(this.listeners).length===0&&this.stopPolling()}}oO.type="LOCAL";const zX=oO;new Fu(3e4,6e4);/**
3077 * @license
3078 * Copyright 2021 Google LLC
3079 *
3080 * Licensed under the Apache License, Version 2.0 (the "License");
3081 * you may not use this file except in compliance with the License.
3082 * You may obtain a copy of the License at
3083 *
3084 *   http://www.apache.org/licenses/LICENSE-2.0
3085 *
3086 * Unless required by applicable law or agreed to in writing, software
3087 * distributed under the License is distributed on an "AS IS" BASIS,
3088 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
3089 * See the License for the specific language governing permissions and
3090 * limitations under the License.
3091 */function sO(t,e){return e?_i(e):(ue(t._popupRedirectResolver,t,"argument-error"),t._popupRedirectResolver)}/**
3092 * @license
3093 * Copyright 2019 Google LLC
3094 *
3095 * Licensed under the Apache License, Version 2.0 (the "License");
3096 * you may not use this file except in compliance with the License.
3097 * You may obtain a copy of the License at
3098 *
3099 *   http://www.apache.org/licenses/LICENSE-2.0
3100 *
3101 * Unless required by applicable law or agreed to in writing, software
3102 * distributed under the License is distributed on an "AS IS" BASIS,
3103 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
3104 * See the License for the specific language governing permissions and
3105 * limitations under the License.
3106 */class Hk extends Q3{constructor(e){super("custom","custom"),this.params=e}_getIdTokenResponse(e){return cl(e,this._buildIdpRequest())}_linkToIdToken(e,a){return cl(e,this._buildIdpRequest(a))}_getReauthenticationResolver(e){return cl(e,this._buildIdpRequest())}_buildIdpRequest(e){const a={requestUri:this.params.requestUri,sessionId:this.params.sessionId,postBody:this.params.postBody,tenantId:this.params.tenantId,pendingToken:this.params.pendingToken,returnSecureToken:!0,returnIdpCredential:!0};return e&&(a.idToken=e),a}}function VX(t){return kX(t.auth,new Hk(t),t.bypassAuthState)}function HX(t){const{auth:e,user:a}=t;return ue(a,e,"internal-error"),wX(a,new Hk(t),t.bypassAuthState)}async function FX(t){const{auth:e,user:a}=t;return ue(a,e,"internal-error"),bX(a,new Hk(t),t.bypassAuthState)}/**
3107 * @license
3108 * Copyright 2020 Google LLC
3109 *
3110 * Licensed under the Apache License, Version 2.0 (the "License");
3111 * you may not use this file except in compliance with the License.
3112 * You may obtain a copy of the License at
3113 *
3114 *   http://www.apache.org/licenses/LICENSE-2.0
3115 *
3116 * Unless required by applicable law or agreed to in writing, software
3117 * distributed under the License is distributed on an "AS IS" BASIS,
3118 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
3119 * See the License for the specific language governing permissions and
3120 * limitations under the License.
3121 */class lO{constructor(e,a,n,i,r=!1){this.auth=e,this.resolver=n,this.user=i,this.bypassAuthState=r,this.pendingPromise=null,this.eventManager=null,this.filter=Array.isArray(a)?a:[a]}execute(){return new Promise(async(e,a)=>{this.pendingPromise={resolve:e,reject:a};try{this.eventManager=await this.resolver._initialize(this.auth),await this.onExecution(),this.eventManager.registerConsumer(this)}catch(n){this.reject(n)}})}async onAuthEvent(e){const{urlResponse:a,sessionId:n,postBody:i,tenantId:r,error:o,type:l}=e;if(o){this.reject(o);return}const c={auth:this.auth,requestUri:a,sessionId:n,tenantId:r||void 0,postBody:i||void 0,user:this.user,bypassAuthState:this.bypassAuthState};try{this.resolve(await this.getIdpTask(l)(c))}catch(d){this.reject(d)}}onError(e){this.reject(e)}getIdpTask(e){switch(e){case"signInViaPopup":case"signInViaRedirect":return VX;case"linkViaPopup":case"linkViaRedirect":return FX;case"reauthViaPopup":case"reauthViaRedirect":return HX;default:ii(this.auth,"internal-error")}}resolve(e){Bi(this.pendingPromise,"Pending promise was never set"),this.pendingPromise.resolve(e),this.unregisterAndCleanUp()}reject(e){Bi(this.pendingPromise,"Pending promise was never set"),this.pendingPromise.reject(e),this.unregisterAndCleanUp()}unregisterAndCleanUp(){this.eventManager&&this.eventManager.unregisterConsumer(this),this.pendingPromise=null,this.cleanUp()}}/**
3122 * @license
3123 * Copyright 2020 Google LLC
3124 *
3125 * Licensed under the Apache License, Version 2.0 (the "License");
3126 * you may not use this file except in compliance with the License.
3127 * You may obtain a copy of the License at
3128 *
3129 *   http://www.apache.org/licenses/LICENSE-2.0
3130 *
3131 * Unless required by applicable law or agreed to in writing, software
3132 * distributed under the License is distributed on an "AS IS" BASIS,
3133 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
3134 * See the License for the specific language governing permissions and
3135 * limitations under the License.
3136 */const BX=new Fu(2e3,1e4);async function cO(t,e,a){if(wi(t.app))return Promise.reject(Pn(t,"operation-not-supported-in-this-environment"));const n=jg(t);HQ(t,e,zk);const i=sO(n,a);return new _o(n,"signInViaPopup",e,i).executeNotNull()}class _o extends lO{constructor(e,a,n,i,r){super(e,a,i,r),this.provider=n,this.authWindow=null,this.pollId=null,_o.currentPopupAction&&_o.currentPopupAction.cancel(),_o.currentPopupAction=this}async executeNotNull(){const e=await this.execute();return ue(e,this.auth,"internal-error"),e}async onExecution(){Bi(this.filter.length===1,"Popup operations only handle one event");const e=Vk();this.authWindow=await this.resolver._openPopup(this.auth,this.provider,this.filter[0],e),this.authWindow.associatedEvent=e,this.resolver._originValidation(this.auth).catch(a=>{this.reject(a)}),this.resolver._isIframeWebStorageSupported(this.auth,a=>{a||this.reject(Pn(this.auth,"web-storage-unsupported"))}),this.pollUserCancellation()}get eventId(){var e;return((e=this.authWindow)===null||e===void 0?void 0:e.associatedEvent)||null}cancel(){this.reject(Pn(this.auth,"cancelled-popup-request"))}cleanUp(){this.authWindow&&this.authWindow.close(),this.pollId&&window.clearTimeout(this.pollId),this.authWindow=null,this.pollId=null,_o.currentPopupAction=null}pollUserCancellation(){const e=()=>{var a,n;if(!((n=(a=this.authWindow)===null||a===void 0?void 0:a.window)===null||n===void 0)&&n.closed){this.pollId=window.setTimeout(()=>{this.pollId=null,this.reject(Pn(this.auth,"popup-closed-by-user"))},8e3);return}this.pollId=window.setTimeout(e,BX.get())};e()}}_o.currentPopupAction=null;/**
3137 * @license
3138 * Copyright 2020 Google LLC
3139 *
3140 * Licensed under the Apache License, Version 2.0 (the "License");
3141 * you may not use this file except in compliance with the License.
3142 * You may obtain a copy of the License at
3143 *
3144 *   http://www.apache.org/licenses/LICENSE-2.0
3145 *
3146 * Unless required by applicable law or agreed to in writing, software
3147 * distributed under the License is distributed on an "AS IS" BASIS,
3148 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
3149 * See the License for the specific language governing permissions and
3150 * limitations under the License.
3151 */const UX="pendingRedirect",Vm=new Map;class $X extends lO{constructor(e,a,n=!1){super(e,["signInViaRedirect","linkViaRedirect","reauthViaRedirect","unknown"],a,void 0,n),this.eventId=null}async execute(){let e=Vm.get(this.auth._key());if(!e){try{const n=await WX(this.resolver,this.auth)?await super.execute():null;e=()=>Promise.resolve(n)}catch(a){e=()=>Promise.reject(a)}Vm.set(this.auth._key(),e)}return this.bypassAuthState||Vm.set(this.auth._key(),()=>Promise.resolve(null)),e()}async onAuthEvent(e){if(e.type==="signInViaRedirect")return super.onAuthEvent(e);if(e.type==="unknown"){this.resolve(null);return}if(e.eventId){const a=await this.auth._redirectUserForId(e.eventId);if(a)return this.user=a,super.onAuthEvent(e);this.resolve(null)}}async onExecution(){}cleanUp(){}}async function WX(t,e){const a=JX(e),n=KX(t);if(!await n._isAvailable())return!1;const i=await n._get(a)==="true";return await n._remove(a),i}function GX(t,e){Vm.set(t._key(),e)}function KX(t){return _i(t._redirectPersistence)}function JX(t){return zm(UX,t.config.apiKey,t.name)}async function QX(t,e,a=!1){if(wi(t.app))return Promise.reject(Mo(t));const n=jg(t),i=sO(n,e),o=await new $X(n,i,a).execute();return o&&!a&&(delete o.user._redirectEventId,await n._persistUserIfCurrent(o.user),await n._setRedirectUser(null,e)),o}/**
3152 * @license
3153 * Copyright 2020 Google LLC
3154 *
3155 * Licensed under the Apache License, Version 2.0 (the "License");
3156 * you may not use this file except in compliance with the License.
3157 * You may obtain a copy of the License at
3158 *
3159 *   http://www.apache.org/licenses/LICENSE-2.0
3160 *
3161 * Unless required by applicable law or agreed to in writing, software
3162 * distributed under the License is distributed on an "AS IS" BASIS,
3163 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
3164 * See the License for the specific language governing permissions and
3165 * limitations under the License.
3166 */const XX=10*60*1e3;class YX{constructor(e){this.auth=e,this.cachedEventUids=new Set,this.consumers=new Set,this.queuedRedirectEvent=null,this.hasHandledPotentialRedirect=!1,this.lastProcessedEventTime=Date.now()}registerConsumer(e){this.consumers.add(e),this.queuedRedirectEvent&&this.isEventForConsumer(this.queuedRedirectEvent,e)&&(this.sendToConsumer(this.queuedRedirectEvent,e),this.saveEventToCache(this.queuedRedirectEvent),this.queuedRedirectEvent=null)}unregisterConsumer(e){this.consumers.delete(e)}onEvent(e){if(this.hasEventBeenHandled(e))return!1;let a=!1;return this.consumers.forEach(n=>{this.isEventForConsumer(e,n)&&(a=!0,this.sendToConsumer(e,n),this.saveEventToCache(e))}),this.hasHandledPotentialRedirect||!ZX(e)||(this.hasHandledPotentialRedirect=!0,a||(this.queuedRedirectEvent=e,a=!0)),a}sendToConsumer(e,a){var n;if(e.error&&!dO(e)){const i=((n=e.error.code)===null||n===void 0?void 0:n.split("auth/")[1])||"internal-error";a.onError(Pn(this.auth,i))}else a.onAuthEvent(e)}isEventForConsumer(e,a){const n=a.eventId===null||!!e.eventId&&e.eventId===a.eventId;return a.filter.includes(e.type)&&n}hasEventBeenHandled(e){return Date.now()-this.lastProcessedEventTime>=XX&&this.cachedEventUids.clear(),this.cachedEventUids.has(QC(e))}saveEventToCache(e){this.cachedEventUids.add(QC(e)),this.lastProcessedEventTime=Date.now()}}function QC(t){return[t.type,t.eventId,t.sessionId,t.tenantId].filter(e=>e).join("-")}function dO({type:t,error:e}){return t==="unknown"&&(e==null?void 0:e.code)==="auth/no-auth-event"}function ZX(t){switch(t.type){case"signInViaRedirect":case"linkViaRedirect":case"reauthViaRedirect":return!0;case"unknown":return dO(t);default:return!1}}/**
3167 * @license
3168 * Copyright 2020 Google LLC
3169 *
3170 * Licensed under the Apache License, Version 2.0 (the "License");
3171 * you may not use this file except in compliance with the License.
3172 * You may obtain a copy of the License at
3173 *
3174 *   http://www.apache.org/licenses/LICENSE-2.0
3175 *
3176 * Unless required by applicable law or agreed to in writing, software
3177 * distributed under the License is distributed on an "AS IS" BASIS,
3178 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
3179 * See the License for the specific language governing permissions and
3180 * limitations under the License.
3181 */async function eY(t,e={}){return Yl(t,"GET","/v1/projects",e)}/**
3182 * @license
3183 * Copyright 2020 Google LLC
3184 *
3185 * Licensed under the Apache License, Version 2.0 (the "License");
3186 * you may not use this file except in compliance with the License.
3187 * You may obtain a copy of the License at
3188 *
3189 *   http://www.apache.org/licenses/LICENSE-2.0
3190 *
3191 * Unless required by applicable law or agreed to in writing, software
3192 * distributed under the License is distributed on an "AS IS" BASIS,
3193 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
3194 * See the License for the specific language governing permissions and
3195 * limitations under the License.
3196 */const tY=/^\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}$/,aY=/^https?/;async function nY(t){if(t.config.emulator)return;const{authorizedDomains:e}=await eY(t);for(const a of e)try{if(iY(a))return}catch{}ii(t,"unauthorized-domain")}function iY(t){const e=fb(),{protocol:a,hostname:n}=new URL(e);if(t.startsWith("chrome-extension://")){const o=new URL(t);return o.hostname===""&&n===""?a==="chrome-extension:"&&t.replace("chrome-extension://","")===e.replace("chrome-extension://",""):a==="chrome-extension:"&&o.hostname===n}if(!aY.test(a))return!1;if(tY.test(t))return n===t;const i=t.replace(/\./g,"\\.");return new RegExp("^(.+\\."+i+"|"+i+")$","i").test(n)}/**
3197 * @license
3198 * Copyright 2020 Google LLC.
3199 *
3200 * Licensed under the Apache License, Version 2.0 (the "License");
3201 * you may not use this file except in compliance with the License.
3202 * You may obtain a copy of the License at
3203 *
3204 *   http://www.apache.org/licenses/LICENSE-2.0
3205 *
3206 * Unless required by applicable law or agreed to in writing, software
3207 * distributed under the License is distributed on an "AS IS" BASIS,
3208 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
3209 * See the License for the specific language governing permissions and
3210 * limitations under the License.
3211 */const rY=new Fu(3e4,6e4);function XC(){const t=ai().___jsl;if(t!=null&&t.H){for(const e of Object.keys(t.H))if(t.H[e].r=t.H[e].r||[],t.H[e].L=t.H[e].L||[],t.H[e].r=[...t.H[e].L],t.CP)for(let a=0;a<t.CP.length;a++)t.CP[a]=null}}function oY(t){return new Promise((e,a)=>{var n,i,r;function o(){XC(),gapi.load("gapi.iframes",{callback:()=>{e(gapi.iframes.getContext())},ontimeout:()=>{XC(),a(Pn(t,"network-request-failed"))},timeout:rY.get()})}if(!((i=(n=ai().gapi)===null||n===void 0?void 0:n.iframes)===null||i===void 0)&&i.Iframe)e(gapi.iframes.getContext());else if(!((r=ai().gapi)===null||r===void 0)&&r.load)o();else{const l=mX("iframefcb");return ai()[l]=()=>{gapi.load?o():a(Pn(t,"network-request-failed"))},uX(`${pX()}?onload=${l}`).catch(c=>a(c))}}).catch(e=>{throw Hm=null,e})}let Hm=null;function sY(t){return Hm=Hm||oY(t),Hm}/**
3212 * @license
3213 * Copyright 2020 Google LLC.
3214 *
3215 * Licensed under the Apache License, Version 2.0 (the "License");
3216 * you may not use this file except in compliance with the License.
3217 * You may obtain a copy of the License at
3218 *
3219 *   http://www.apache.org/licenses/LICENSE-2.0
3220 *
3221 * Unless required by applicable law or agreed to in writing, software
3222 * distributed under the License is distributed on an "AS IS" BASIS,
3223 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
3224 * See the License for the specific language governing permissions and
3225 * limitations under the License.
3226 */const lY=new Fu(5e3,15e3),cY="__/auth/iframe",dY="emulator/auth/iframe",uY={style:{position:"absolute",top:"-100px",width:"1px",height:"1px"},"aria-hidden":"true",tabindex:"-1"},pY=new Map([["identitytoolkit.googleapis.com","p"],["staging-identitytoolkit.sandbox.googleapis.com","s"],["test-identitytoolkit.sandbox.googleapis.com","t"]]);function mY(t){const e=t.config;ue(e.authDomain,t,"auth-domain-config-required");const a=e.emulator?Lk(e,dY):`https://${t.config.authDomain}/${cY}`,n={apiKey:e.apiKey,appName:t.name,v:us},i=pY.get(t.config.apiHost);i&&(n.eid=i);const r=t._getFrameworks();return r.length&&(n.fw=r.join(",")),`${a}?${Ru(n).slice(1)}`}async function hY(t){const e=await sY(t),a=ai().gapi;return ue(a,t,"internal-error"),e.open({where:document.body,url:mY(t),messageHandlersFilter:a.iframes.CROSS_ORIGIN_IFRAMES_FILTER,attributes:uY,dontclear:!0},n=>new Promise(async(i,r)=>{await n.restyle({setHideOnLeave:!1});const o=Pn(t,"network-request-failed"),l=ai().setTimeout(()=>{r(o)},lY.get());function c(){ai().clearTimeout(l),i(n)}n.ping(c).then(c,()=>{r(o)})}))}/**
3227 * @license
3228 * Copyright 2020 Google LLC.
3229 *
3230 * Licensed under the Apache License, Version 2.0 (the "License");
3231 * you may not use this file except in compliance with the License.
3232 * You may obtain a copy of the License at
3233 *
3234 *   http://www.apache.org/licenses/LICENSE-2.0
3235 *
3236 * Unless required by applicable law or agreed to in writing, software
3237 * distributed under the License is distributed on an "AS IS" BASIS,
3238 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
3239 * See the License for the specific language governing permissions and
3240 * limitations under the License.
3241 */const fY={location:"yes",resizable:"yes",statusbar:"yes",toolbar:"no"},gY=500,yY=600,xY="_blank",vY="http://localhost";class YC{constructor(e){this.window=e,this.associatedEvent=null}close(){if(this.window)try{this.window.close()}catch{}}}function bY(t,e,a,n=gY,i=yY){const r=Math.max((window.screen.availHeight-i)/2,0).toString(),o=Math.max((window.screen.availWidth-n)/2,0).toString();let l="";const c=Object.assign(Object.assign({},fY),{width:n.toString(),height:i.toString(),top:r,left:o}),d=ra().toLowerCase();a&&(l=F3(d)?xY:a),V3(d)&&(e=e||vY,c.scrollbars="yes");const u=Object.entries(c).reduce((m,[h,g])=>`${m}${h}=${g},`,"");if(nX(d)&&l!=="_self")return wY(e||"",l),new YC(null);const p=window.open(e||"",l,u);ue(p,t,"popup-blocked");try{p.focus()}catch{}return new YC(p)}function wY(t,e){const a=document.createElement("a");a.href=t,a.target=e;const n=document.createEvent("MouseEvent");
3241n.initMouseEvent("click",!0,!0,window,1,0,0,0,0,!1,!1,!1,!1,1,null),a.dispatchEvent(n)}/**
3242 * @license
3243 * Copyright 2021 Google LLC
3244 *
3245 * Licensed under the Apache License, Version 2.0 (the "License");
3246 * you may not use this file except in compliance with the License.
3247 * You may obtain a copy of the License at
3248 *
3249 *   http://www.apache.org/licenses/LICENSE-2.0
3250 *
3251 * Unless required by applicable law or agreed to in writing, software
3252 * distributed under the License is distributed on an "AS IS" BASIS,
3253 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
3254 * See the License for the specific language governing permissions and
3255 * limitations under the License.
3256 */const kY="__/auth/handler",SY="emulator/auth/handler",_Y=encodeURIComponent("fac");async function ZC(t,e,a,n,i,r){ue(t.config.authDomain,t,"auth-domain-config-required"),ue(t.config.apiKey,t,"invalid-api-key");const o={apiKey:t.config.apiKey,appName:t.name,authType:a,redirectUrl:n,v:us,eventId:i};if(e instanceof zk){e.setDefaultLanguage(t.languageCode),o.providerId=e.providerId||"",l$(e.getCustomParameters())||(o.customParameters=JSON.stringify(e.getCustomParameters()));for(const[u,p]of Object.entries({}))o[u]=p}if(e instanceof Bu){const u=e.getScopes().filter(p=>p!=="");u.length>0&&(o.scopes=u.join(","))}t.tenantId&&(o.tid=t.tenantId);const l=o;for(const u of Object.keys(l))l[u]===void 0&&delete l[u];const c=await t._getAppCheckToken(),d=c?`#${_Y}=${encodeURIComponent(c)}`:"";return`${AY(t)}?${Ru(l).slice(1)}${d}`}function AY({config:t}){return t.emulator?Lk(t,SY):`https://${t.authDomain}/${kY}`}/**
3257 * @license
3258 * Copyright 2020 Google LLC
3259 *
3260 * Licensed under the Apache License, Version 2.0 (the "License");
3261 * you may not use this file except in compliance with the License.
3262 * You may obtain a copy of the License at
3263 *
3264 *   http://www.apache.org/licenses/LICENSE-2.0
3265 *
3266 * Unless required by applicable law or agreed to in writing, software
3267 * distributed under the License is distributed on an "AS IS" BASIS,
3268 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
3269 * See the License for the specific language governing permissions and
3270 * limitations under the License.
3271 */const L0="webStorageSupport";class EY{constructor(){this.eventManagers={},this.iframes={},this.originValidationPromises={},this._redirectPersistence=aO,this._completeRedirectFn=QX,this._overrideRedirectResult=GX}async _openPopup(e,a,n,i){var r;Bi((r=this.eventManagers[e._key()])===null||r===void 0?void 0:r.manager,"_initialize() not called before _openPopup()");const o=await ZC(e,a,n,fb(),i);return bY(e,o,Vk())}async _openRedirect(e,a,n,i){await this._originValidation(e);const r=await ZC(e,a,n,fb(),i);return NX(r),new Promise(()=>{})}_initialize(e){const a=e._key();if(this.eventManagers[a]){const{manager:i,promise:r}=this.eventManagers[a];return i?Promise.resolve(i):(Bi(r,"If manager is not set, promise should be"),r)}const n=this.initAndGetManager(e);return this.eventManagers[a]={promise:n},n.catch(()=>{delete this.eventManagers[a]}),n}async initAndGetManager(e){const a=await hY(e),n=new YX(e);return a.register("authEvent",i=>(ue(i==null?void 0:i.authEvent,e,"invalid-auth-event"),{status:n.onEvent(i.authEvent)?"ACK":"ERROR"}),gapi.iframes.CROSS_ORIGIN_IFRAMES_FILTER),this.eventManagers[e._key()]={manager:n},this.iframes[e._key()]=a,n}_isIframeWebStorageSupported(e,a){this.iframes[e._key()].send(L0,{type:L0},i=>{var r;const o=(r=i==null?void 0:i[0])===null||r===void 0?void 0:r[L0];o!==void 0&&a(!!o),ii(e,"internal-error")},gapi.iframes.CROSS_ORIGIN_IFRAMES_FILTER)}_originValidation(e){const a=e._key();return this.originValidationPromises[a]||(this.originValidationPromises[a]=nY(e)),this.originValidationPromises[a]}get _shouldInitProactively(){return G3()||H3()||Dk()}}const CY=EY;var ej="@firebase/auth",tj="1.7.9";/**
3272 * @license
3273 * Copyright 2020 Google LLC
3274 *
3275 * Licensed under the Apache License, Version 2.0 (the "License");
3276 * you may not use this file except in compliance with the License.
3277 * You may obtain a copy of the License at
3278 *
3279 *   http://www.apache.org/licenses/LICENSE-2.0
3280 *
3281 * Unless required by applicable law or agreed to in writing, softw
3281are
3282 * distributed under the License is distributed on an "AS IS" BASIS,
3283 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
3284 * See the License for the specific language governing permissions and
3285 * limitations under the License.
3286 */class jY{constructor(e){this.auth=e,this.internalListeners=new Map}getUid(){var e;return this.assertAuthConfigured(),((e=this.auth.currentUser)===null||e===void 0?void 0:e.uid)||null}async getToken(e){return this.assertAuthConfigured(),await this.auth._initializationPromise,this.auth.currentUser?{accessToken:await this.auth.currentUser.getIdToken(e)}:null}addAuthTokenListener(e){if(this.assertAuthConfigured(),this.internalListeners.has(e))return;const a=this.auth.onIdTokenChanged(n=>{e((n==null?void 0:n.stsTokenManager.accessToken)||null)});this.internalListeners.set(e,a),this.updateProactiveRefresh()}removeAuthTokenListener(e){this.assertAuthConfigured();const a=this.internalListeners.get(e);a&&(this.internalListeners.delete(e),a(),this.updateProactiveRefresh())}assertAuthConfigured(){ue(this.auth._initializationPromise,"dependent-sdk-initialized-before-auth")}updateProactiveRefresh(){this.internalListeners.size>0?this.auth._startProactiveRefresh():this.auth._stopProactiveRefresh()}}/**
3287 * @license
3288 * Copyright 2020 Google LLC
3289 *
3290 * Licensed under the Apache License, Version 2.0 (the "License");
3291 * you may not use this file except in compliance with the License.
3292 * You may obtain a copy of the License at
3293 *
3294 *   http://www.apache.org/licenses/LICENSE-2.0
3295 *
3296 * Unless required by applicable law or agreed to in writing, software
3297 * distributed under the License is distributed on an "AS IS" BASIS,
3298 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
3299 * See the License for the specific language governing permissions and
3300 * limitations under the License.
3301 */function TY(t){switch(t){case"Node":return"node";case"ReactNative":return"rn";case"Worker":return"webworker";case"Cordova":return"cordova";case"WebExtension":return"web-extension";default:return}}function NY(t){Dn(new hn("auth",(e,{options:a})=>{const n=e.getProvider("app").getImmediate(),i=e.getProvider("heartbeat"),r=e.getProvider("app-check-internal"),{apiKey:o,authDomain:l}=n.options;ue(o&&!o.includes(":"),"invalid-api-key",{appName:n.name});const c={apiKey:o,authDomain:l,clientPlatform:t,apiHost:"identitytoolkit.googleapis.com",tokenApiHost:"securetoken.googleapis.com",apiScheme:"https",sdkClientVersion:K3(t)},d=new cX(n,i,r,c);return fX(d,a),d},"PUBLIC").setInstantiationMode("EXPLICIT").setInstanceCreatedCallback((e,a,n)=>{e.getProvider("auth-internal").initialize()})),Dn(new hn("auth-internal",e=>{const a=jg(e.getProvider("auth").getImmediate());return(n=>new jY(n))(a)},"PRIVATE").setInstantiationMode("EXPLICIT")),Na(ej,tj,TY(t)),Na(ej,tj,"esm2017")}/**
3302 * @license
3303 * Copyright 2021 Google LLC
3304 *
3305 * Licensed under the Apache License, Version 2.0 (the "License");
3306 * you may not use this file except in compliance with the License.
3307 * You may obtain a copy of the License at
3308 *
3309 *   http://www.apache.org/licenses/LICENSE-2.0
3310 *
3311 * Unless required by applicable law or agreed to in writing, software
3312 * distributed under the License is distributed on an "AS IS" BASIS,
3313 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
3314 * See the License for the specific language governing permissions and
3315 * limitations under the License.
3316 */const IY=5*60,PY=qR("authIdTokenMaxAge")||IY;let aj=null;const RY=t=>async e=>{const a=e&&await e.getIdTokenResult(),n=a&&(new Date().getTime()-Date.parse(a.issuedAtTime))/1e3;if(n&&n>PY)return;const i=a==null?void 0:a.token;aj!==i&&(aj=i,await fetch(t,{method:i?"POST":"DELETE",headers:i?{Authorization:`Bearer ${i}`}:{}}))};function LY(t=mg()){const e=Qr(t,"auth");if(e.isInitialized())return e.getImmediate();const a=hX(t,{popupRedirectResolver:CY,persistence:[zX,CX,aO]}),n=qR("authTokenSyncURL");if(n&&typeof isSecureContext=="boolean"&&isSecureContext){const r=new URL(n,location.origin);if(location.origin===r.origin){const o=RY(r.toString());_X(a,o,()=>o(a.currentUser)),SX(a,l=>o(l))}}const i=OR("auth");return i&&gX(a,`http://${i}`),a}function OY(){var t,e;return(e=(t=document.getElementsByTagName("head"))===null||t===void 0?void 0:t[0])!==null&&e!==void 0?e:document}dX({loadJS(t){return new Promise((e,a)=>{const n=document.createElement("script");n.setAttribute("src",t),n.onload=e,n.onerror=i=>{const r=Pn("internal-error");r.customData=i,a(r)},n.type="text/javascript",n.charset="UTF-8",OY().appendChild(n)})},gapiScript:"https://apis.google.com/js/api.js",recaptchaV2Script:"https://www.google.com/recaptcha/api.js",recaptchaEnterpriseScript:"https://www.google.com/recaptcha/enterprise.js?render="});NY("Browser");const uO="@firebase/installations",Fk="0.6.9";/**
3317 * @license
3318 * Copyright 2019 Google LLC
3319 *
3320 * Licensed under the Apache License, Version 2.0 (the "License");
3321 * you may not use this file except in compliance with the License.
3322 * You may obtain a copy of the License at
3323 *
3324 *   http://www.apache.org/licenses/LICENSE-2.0
3325 *
3326 * Unless required by applicable law or agreed to in writing, software
3327 * distributed under the License is distributed on an "AS IS" BASIS,
3328 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
3329 * See the License for the specific language governing permissions and
3330 * limitations under the License.
3331 */const pO=1e4,mO=`w:${Fk}`,hO="FIS_v2",MY="https://firebaseinstallations.googleapis.com/v1",DY=60*60*1e3,qY="installations",zY="Installations";/**
3332 * @license
3333 * Copyright 2019 Google LLC
3334 *
3335 * Licensed under the Apache License, Version 2.0 (the "License");
3336 * you may not use this file except in compliance with the License.
3337 * You may obtain a copy of the License at
3338 *
3339 *   http://www.apache.org/licenses/LICENSE-2.0
3340 *
3341 * Unless required by applicable law or agreed to in writing, software
3342 * distributed under the License is distributed on an "AS IS" BASIS,
3343 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
3344 * See the License for the specific language governing permissions and
3345 * limitations under the License.
3346 */const VY={"missing-app-config-values":'Missing App configuration value: "{$valueName}"',"not-registered":"Firebase Installation is not registered.","installation-not-found":"Firebase Installation not found.","request-failed":'{$requestName} request failed with error "{$serverCode} {$serverStatus}: {$serverMessage}"',"app-offline":"Could not process request. Application offline.","delete-pending-registration":"Can't delete installation while there is a pending registration request."},es=new ds(qY,zY,VY);function fO(t){return t instanceof gn&&t.code.includes("request-failed")}/**
3347 * @license
3348 * Copyright 2019 Google LLC
3349 *
3350 * Licensed under the Apache License, Version 2.0 (the "License");
3351 * you may not use this file except in compliance with the License.
3352 * You may obtain a copy of the License at
3353 *
3354 *   http://www.apache.org/licenses/LICENSE-2.0
3355 *
3356 * Unless required by applicable law or agreed to in writing, software
3357 * distributed under the License is distributed on an "AS IS" BASIS,
3358 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
3359 * See the License for the specific language governing permissions and
3360 * limitations under the License.
3361 */function gO({projectId:t}){return`${MY}/projects/${t}/installations`}function yO(t){return{token:t.token,requestStatus:2,expiresIn:FY(t.expiresIn),creationTime:Date.now()}}async function xO(t,e){const n=(await e.json()).error;return es.create("request-failed",{requestName:t,serverCode:n.code,serverMessage:n.message,serverStatus:n.status})}function vO({apiKey:t}){return new Headers({"Content-Type":"application/json",Accept:"application/json","x-goog-api-key":t})}function HY(t,{refreshToken:e}){const a=vO(t);return a.append("Authorization",BY(e)),a}async function bO(t){const e=await t();return e.status>=500&&e.status<600?t():e}function FY(t){return Number(t.replace("s","000"))}function BY(t){return`${hO} ${t}`}/**
3362 * @license
3363 * Copyright 2019 Google LLC
3364 *
3365 * Licensed under the Apache License, Version 2.0 (the "License");
3366 * you may not use this file except in compliance with the License.
3367 * You may obtain a copy of the License at
3368 *
3369 *   http://www.apache.org/licenses/LICENSE-2.0
3370 *
3371 * Unless required by applicable law or agreed to in writing, software
3372 * distributed under the License is distributed on an "AS IS" BASIS,
3373 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
3374 * See the License for the specific language governing permissions and
3375 * limitations under the License.
3376 */async function UY({appConfig:t,heartbeatServiceProvider:e},{fid:a}){const n=gO(t),i=vO(t),r=e.getImmediate({optional:!0});if(r){const d=await r.getHeartbeatsHeader();d&&i.append("x-firebase-client",d)}const o={fid:a,authVersion:hO,appId:t.appId,sdkVersion:mO},l={method:"POST",headers:i,body:JSON.stringify(o)},c=await bO(()=>fetch(n,l));if(c.ok){const d=await c.json();return{fid:d.fid||a,registrationStatus:2,refreshToken:d.refreshToken,authToken:yO(d.authToken)}}else throw await xO("Create Installation",c)}/**
3377 * @license
3378 * Copyright 2019 Google LLC
3379 *
3380 * Licensed under the Apache License, Version 2.0 (the "License");
3381 * you may not use this file except in compliance with the License.
3382 * You may obtain a copy of the License at
3383 *
3384 *   http://www.apache.org/licenses/LICENSE-2.0
3385 *
3386 * Unless required by applicable law or agreed to in writing, software
3387 * distributed under the License is distributed on an "AS IS" BASIS,
3388 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
3389 * See the License for the specific language governing permissions and
3390 * limitations under the License.
3391 */function wO(t){return new Promise(e=>{setTimeout(e,t)})}/**
3392 * @license
3393 * Copyright 2019 Google LLC
3394 *
3395 * Licensed under the Apache License, Version 2.0 (the "License");
3396 * you may not use this file except in compliance with the License.
3397 * You may obtain a copy of the License at
3398 *
3399 *   http://www.apache.org/licenses/LICENSE-2.0
3400 *
3401 * Unless required by applicable law or agreed to in writing, software
3402 * distributed under the License is distributed on an "AS IS" BASIS,
3403 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
3404 * See the License for the specific language governing permissions and
3405 * limitations under the License.
3406 */function $Y(t){return btoa(String.fromCharCode(...t)).replace(/\+/g,"-").replace(/\//g,"_")}/**
3407 * @license
3408 * Copyright 2019 Google LLC
3409 *
3410 * Licensed under the Apache License, Version 2.0 (the "License");
3411 * you may not use this file except in compliance with the License.
3412 * You may obtain a copy of the License at
3413 *
3414 *   http://www.apache.org/licenses/LICENSE-2.0
3415 *
3416 * Unless required by applicable law or agreed to in writing, software
3417 * distributed under the License is distributed on an "AS IS" BASIS,
3418 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
3419 * See the License for the specific language governing permissions and
3420 * limitations under the License.
3421 */const WY=/^[cdef][\w-]{21}$/,xb="";function GY(){try{const t=new Uint8Array(17);(self.crypto||self.msCrypto).getRandomValues(t),t[0]=112+t[0]%16;const a=KY(t);return WY.test(a)?a:xb}catch{return xb}}function KY(t){return $Y(t).substr(0,22)}/**
3422 * @license
3423 * Copyright 2019 Google LLC
3424 *
3425 * Licensed under the Apache License, Version 2.0 (the "License");
3426 * you may not use this file except in compliance with the License.
3427 * You may obtain a copy of the License at
3428 *
3429 *   http://www.apache.org/licenses/LICENSE-2.0
3430 *
3431 * Unless required by applicable law or agreed to in writing, software
3432 * distributed under the License is distributed on an "AS IS" BASIS,
3433 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
3434 * See the License for the specific language governing permissions and
3435 * limitations under the License.
3436 */function Ig(t){return`${t.appName}!${t.appId}`}/**
3437 * @license
3438 * Copyright 2019 Google LLC
3439 *
3440 * Licensed under the Apache License, Version 2.0 (the "License");
3441 * you may not use this file except in compliance with the License.
3442 * You may obtain a copy of the License at
3443 *
3444 *   http://www.apache.org/licenses/LICENSE-2.0
3445 *
3446 * Unless required by applicable law or agreed to in writing, software
3447 * distributed under the License is distributed on an "AS IS" BASIS,
3448 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
3449 * See the License for the specific language governing permissions and
3450 * limitations under the License.
3451 */const kO=new Map;function SO(t,e){const a=Ig(t);_O(a,e),JY(a,e)}function _O(t,e){const a=kO.get(t);if(a)for(const n of a)n(e)}function JY(t,e){const a=QY();a&&a.postMessage({key:t,fid:e}),XY()}let Ao=null;function QY(){return!Ao&&"BroadcastChannel"in self&&(Ao=new BroadcastChannel("[Firebase] FID Change"),Ao.onmessage=t=>{_O(t.data.key,t.data.fid)}),Ao}function XY(){kO.size===0&&Ao&&(Ao.close(),Ao=null)}/**
3452 * @license
3453 * Copyright 2019 Google LLC
3454 *
3455 * Licensed under the Apache License, Version 2.0 (the "License");
3456 * you may not use this file except in compliance with the License.
3457 * You may obtain a copy of the License at
3458 *
3459 *   http://www.apache.org/licenses/LICENSE-2.0
3460 *
3461 * Unless required by applicable law or agreed to in writing, software
3462 * distributed under the License is distributed on an "AS IS" BASIS,
3463 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
3464 * See the License for the specific language governing permissions and
3465 * limitations under the License.
3466 */const YY="firebase-installations-database",ZY=1,ts="firebase-installations-store";let O0=null;function Bk(){return O0||(O0=BR(YY,ZY,{upgrade:(t,e)=>{switch(e){case 0:t.createObjectStore(ts)}}})),O0}async function Uh(t,e){const a=Ig(t),i=(await Bk()).transaction(ts,"readwrite"),r=i.objectStore(ts),o=await r.get(a);return await r.put(e,a),await i.done,(!o||o.fid!==e.fid)&&SO(t,e.fid),e}async function AO(t){const e=Ig(t),n=(await Bk()).transaction(ts,"readwrite");await n.objectStore(ts).delete(e),await n.done}async function Pg(t,e){const a=Ig(t),i=(await Bk()).transaction(ts,"readwrite"),r=i.objectStore(ts),o=await r.get(a),l=e(o);return l===void 0?await r.delete(a):await r.put(l,a),await i.done,l&&(!o||o.fid!==l.fid)&&SO(t,l.fid),l}/**
3467 * @license
3468 * Copyright 2019 Google LLC
3469 *
3470 * Licensed under the Apache License, Version 2.0 (the "License");
3471 * you may not use this file except in compliance with the License.
3472 * You may obtain a copy of the License at
3473 *
3474 *   http://www.apache.org/licenses/LICENSE-2.0
3475 *
3476 * Unless required by applicable law or agreed to in writing, software
3477 * distributed under the License is distributed on an "AS IS" BASIS,
3478 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
3479 * See the License for the specific language governing permissions and
3480 * limitations under the License.
3481 */async function Uk(t){let e;const a=await Pg(t.appConfig,n=>{const i=eZ(n),r=tZ(t,i);return e=r.registrationPromise,r.installationEntry});return a.fid===xb?{installationEntry:await e}:{installationEntry:a,registrationPromise:e}}function eZ(t){const e=t||{fid:GY(),registrationStatus:0};return EO(e)}function tZ(t,e){if(e.registrationStatus===0){if(!navigator.onLine){const i=Promise.reject(es.create("app-offline"));return{installationEntry:e,registrationPromise:i}}const a={fid:e.fid,registrationStatus:1,registrationTime:Date.now()},n=aZ(t,a);return{installationEntry:a,registrationPromise:n}}else return e.registrationStatus===1?{installationEntry:e,registrationPromise:nZ(t)}:{installationEntry:e}}async function aZ(t,e){try{const a=await UY(t,e);return Uh(t.appConfig,a)}catch(a){throw fO(a)&&a.customData.serverCode===409?await AO(t.appConfig):await Uh(t.appConfig,{fid:e.fid,registrationStatus:0}),a}}async function nZ(t){let e=await nj(t.appConfig);for(;e.registrationStatus===1;)await wO(100),e=await nj(t.appConfig);if(e.registrationStatus===0){const{installationEntry:a,registrationPromise:n}=await Uk(t);return n||a}return e}function nj(t){return Pg(t,e=>{if(!e)throw es.create("installation-not-found");return EO(e)})}function EO(t){return iZ(t)?{fid:t.fid,registrationStatus:0}:t}function iZ(t){return t.registrationStatus===1&&t.registrationTime+pO<Date.now()}/**
3482 * @license
3483 * Copyright 2019 Google LLC
3484 *
3485 * Licensed under the Apache License, Version 2.0 (the "License");
3486 * you may not use this file except in compliance with the License.
3487 * You may obtain a copy of the License at
3488 *
3489 *   http://www.apache.org/licenses/LICENSE-2.0
3490 *
3491 * Unless required by applicable law or agreed to in writing, software
3492 * distributed under the License is distributed on an "AS IS" BASIS,
3493 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
3494 * See the License for the specific language governing permissions and
3495 * limitations under the License.
3496 */async function rZ({appConfig:t,heartbeatServiceProvider:e},a){const n=oZ(t,a),i=HY(t,a),r=e.getImmediate({optional:!0});if(r){const d=await r.getHeartbeatsHeader();d&&i.append("x-firebase-client",d)}const o={installation:{sdkVersion:mO,appId:t.appId}},l={method:"POST",headers:i,body:JSON.stringify(o)},c=await bO(()=>fetch(n,l));if(c.ok){const d=await c.json();return yO(d)}else throw await xO("Generate Auth Token",c)}function oZ(t,{fid:e}){return`${gO(t)}/${e}/authTokens:generate`}/**
3497 * @license
3498 * Copyright 2019 Google LLC
3499 *
3500 * Licensed under the Apache License, Version 2.0 (the "License");
3501 * you may not use this file except in compliance with the License.
3502 * You may obtain a copy of the License at
3503 *
3504 *   http://www.apache.org/licenses/LICENSE-2.0
3505 *
3506 * Unless required by applicable law or agreed to in writing, software
3507 * distributed under the License is distributed on an "AS IS" BASIS,
3508 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
3509 * See the License for the specific language governing permissions and
3510 * limitations under the License.
3511 */async function $k(t,e=!1){let a;const n=await Pg(t.appConfig,r=>{if(!CO(r))throw es.create("not-registered");const o=r.authToken;
3511if(!e&&cZ(o))return r;if(o.requestStatus===1)return a=sZ(t,e),r;{if(!navigator.onLine)throw es.create("app-offline");const l=uZ(r);return a=lZ(t,l),l}});return a?await a:n.authToken}async function sZ(t,e){let a=await ij(t.appConfig);for(;a.authToken.requestStatus===1;)await wO(100),a=await ij(t.appConfig);const n=a.authToken;return n.requestStatus===0?$k(t,e):n}function ij(t){return Pg(t,e=>{if(!CO(e))throw es.create("not-registered");const a=e.authToken;return pZ(a)?Object.assign(Object.assign({},e),{authToken:{requestStatus:0}}):e})}async function lZ(t,e){try{const a=await rZ(t,e),n=Object.assign(Object.assign({},e),{authToken:a});return await Uh(t.appConfig,n),a}catch(a){if(fO(a)&&(a.customData.serverCode===401||a.customData.serverCode===404))await AO(t.appConfig);else{const n=Object.assign(Object.assign({},e),{authToken:{requestStatus:0}});await Uh(t.appConfig,n)}throw a}}function CO(t){return t!==void 0&&t.registrationStatus===2}function cZ(t){return t.requestStatus===2&&!dZ(t)}function dZ(t){const e=Date.now();return e<t.creationTime||t.creationTime+t.expiresIn<e+DY}function uZ(t){const e={requestStatus:1,requestTime:Date.now()};return Object.assign(Object.assign({},t),{authToken:e})}function pZ(t){return t.requestStatus===1&&t.requestTime+pO<Date.now()}/**
3512 * @license
3513 * Copyright 2019 Google LLC
3514 *
3515 * Licensed under the Apache License, Version 2.0 (the "License");
3516 * you may not use this file except in compliance with the License.
3517 * You may obtain a copy of the License at
3518 *
3519 *   http://www.apache.org/licenses/LICENSE-2.0
3520 *
3521 * Unless required by applicable law or agreed to in writing, software
3522 * distributed under the License is distributed on an "AS IS" BASIS,
3523 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
3524 * See the License for the specific language governing permissions and
3525 * limitations under the License.
3526 */async function mZ(t){const e=t,{installationEntry:a,registrationPromise:n}=await Uk(e);return n?n.catch(console.error):$k(e).catch(console.error),a.fid}/**
3527 * @license
3528 * Copyright 2019 Google LLC
3529 *
3530 * Licensed under the Apache License, Version 2.0 (the "License");
3531 * you may not use this file except in compliance with the License.
3532 * You may obtain a copy of the License at
3533 *
3534 *   http://www.apache.org/licenses/LICENSE-2.0
3535 *
3536 * Unless required by applicable law or agreed to in writing, software
3537 * distributed under the License is distributed on an "AS IS" BASIS,
3538 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
3539 * See the License for the specific language governing permissions and
3540 * limitations under the License.
3541 */async function hZ(t,e=!1){const a=t;return await fZ(a),(await $k(a,e)).token}async function fZ(t){const{registrationPromise:e}=await Uk(t);e&&await e}/**
3542 * @license
3543 * Copyright 2019 Google LLC
3544 *
3545 * Licensed under the Apache License, Version 2.0 (the "License");
3546 * you may not use this file except in compliance with the License.
3547 * You may obtain a copy of the License at
3548 *
3549 *   http://www.apache.org/licenses/LICENSE-2.0
3550 *
3551 * Unless required by applicable law or agreed to in writing, software
3552 * distributed under the License is distributed on an "AS IS" BASIS,
3553 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
3554 * See the License for the specific language governing permissions and
3555 * limitations under the License.
3556 */function gZ(t){if(!t||!t.options)throw M0("App Configuration");if(!t.name)throw M0("App Name");const e=["projectId","apiKey","appId"];for(const a of e)if(!t.options[a])throw M0(a);return{appName:t.name,projectId:t.options.projectId,apiKey:t.options.apiKey,appId:t.options.appId}}function M0(t){return es.create("missing-app-config-values",{valueName:t})}/**
3557 * @license
3558 * Copyright 2020 Google LLC
3559 *
3560 * Licensed under the Apache License, Version 2.0 (the "License");
3561 * you may not use this file except in compliance with the License.
3562 * You may obtain a copy of the License at
3563 *
3564 *   http://www.apache.org/licenses/LICENSE-2.0
3565 *
3566 * Unless required by applicable law or agreed to in writing, software
3567 * distributed under the License is distributed on an "AS IS" BASIS,
3568 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
3569 * See the License for the specific language governing permissions and
3570 * limitations under the License.
3571 */const jO="installations",yZ="installations-internal",xZ=t=>{const e=t.getProvider("app").getImmediate(),a=gZ(e),n=Qr(e,"heartbeat");return{app:e,appConfig:a,heartbeatServiceProvider:n,_delete:()=>Promise.resolve()}},vZ=t=>{const e=t.getProvider("app").getImmediate(),a=Qr(e,jO).getImmediate();return{getId:()=>mZ(a),getToken:i=>hZ(a,i)}};function bZ(){Dn(new hn(jO,xZ,"PUBLIC")),Dn(new hn(yZ,vZ,"PRIVATE"))}bZ();Na(uO,Fk);Na(uO,Fk,"esm2017");/**
3572 * @license
3573 * Copyright 2019 Google LLC
3574 *
3575 * Licensed under the Apache License, Version 2.0 (the "License");
3576 * you may not use this file except in compliance with the License.
3577 * You may obtain a copy of the License at
3578 *
3579 *   http://www.apache.org/licenses/LICENSE-2.0
3580 *
3581 * Unless required by applicable law or agreed to in writing, software
3582 * distributed under the License is distributed on an "AS IS" BASIS,
3583 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
3584 * See the License for the specific language governing permissions and
3585 * limitations under the License.
3586 */const $h="analytics",wZ="firebase_id",kZ="origin",SZ=60*1e3,_Z="https://firebase.googleapis.com/v1alpha/projects/-/apps/{app-id}/webConfig",Wk="https://www.googletagmanager.com/gtag/js";/**
3587 * @license
3588 * Copyright 2019 Google LLC
3589 *
3590 * Licensed under the Apache License, Version 2.0 (the "License");
3591 * you may not use this file except in compliance with the License.
3592 * You may obtain a copy of the License at
3593 *
3594 *   http://www.apache.org/licenses/LICENSE-2.0
3595 *
3596 * Unless required by applicable law or agreed to in writing, software
3597 * distributed under the License is distributed on an "AS IS" BASIS,
3598 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
3599 * See the License for the specific language governing permissions and
3600 * limitations under the License.
3601 */const Pa=new pg("@firebase/analytics");/**
3602 * @license
3603 * Copyright 2019 Google LLC
3604 *
3605 * Licensed under the Apache License, Version 2.0 (the "License");
3606 * you may not use this file except in compliance with the License.
3607 * You may obtain a copy of the License at
3608 *
3609 *   http://www.apache.org/licenses/LICENSE-2.0
3610 *
3611 * Unless required by applicable law or agreed to in writing, software
3612 * distributed under the License is distributed on an "AS IS" BASIS,
3613 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
3614 * See the License for the specific language governing permissions and
3615 * limitations under the License.
3616 */const AZ={"already-exists":"A Firebase Analytics instance with the appId {$id}  already exists. Only one Firebase Analytics instance can be created for each appId.","already-initialized":"initializeAnalytics() cannot be called again with different options than those it was initially called with. It can be called again with the same options to return the existing instance, or getAnalytics() can be used to get a reference to the already-initialized instance.","already-initialized-settings":"Firebase Analytics has already been initialized.settings() must be called before initializing any Analytics instanceor it will have no effect.","interop-component-reg-failed":"Firebase Analytics Interop Component failed to instantiate: {$reason}","invalid-analytics-context":"Firebase Analytics is not supported in this environment. Wrap initialization of analytics in analytics.isSupported() to prevent initialization in unsupported environments. Details: {$errorInfo}","indexeddb-unavailable":"IndexedDB unavailable or restricted in this environment. Wrap initialization of analytics in analytics.isSupported() to prevent initialization in unsupported environments. Details: {$errorInfo}","fetch-throttle":"The config fetch request timed out while in an exponential backoff state. Unix timestamp in milliseconds when fetch request throttling ends: {$throttleEndTimeMillis}.","config-fetch-failed":"Dynamic config fetch failed: [{$httpStatus}] {$responseMessage}","no-api-key":'The "apiKey" field is empty in the local Firebase config. Firebase Analytics requires this field tocontain a valid API key.',"no-app-id":'The "appId" field is empty in the local Firebase config. Firebase Analytics requires this field tocontain a valid app ID.',"no-client-id":'The "client_id" field is empty.',"invalid-gtag-resource":"Trusted Types detected an invalid gtag resource: {$gtagURL}."},Ba=new ds("analytics","Analytics",AZ);/**
3617 * @license
3618 * Copyright 2019 Google LLC
3619 *
3620 * Licensed under the Apache License, Version 2.0 (the "License");
3621 * you may not use this file except in compliance with the License.
3622 * You may obtain a copy of the License at
3623 *
3624 *   http://www.apache.org/licenses/LICENSE-2.0
3625 *
3626 * Unless required by applicable law or agreed to in writing, softw
3626are
3627 * distributed under the License is distributed on an "AS IS" BASIS,
3628 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
3629 * See the License for the specific language governing permissions and
3630 * limitations under the License.
3631 */function EZ(t){if(!t.startsWith(Wk)){const e=Ba.create("invalid-gtag-resource",{gtagURL:t});return Pa.warn(e.message),""}return t}function TO(t){return Promise.all(t.map(e=>e.catch(a=>a)))}function CZ(t,e){let a;return window.trustedTypes&&(a=window.trustedTypes.createPolicy(t,e)),a}function jZ(t,e){const a=CZ("firebase-js-sdk-policy",{createScriptURL:EZ}),n=document.createElement("script"),i=`${Wk}?l=${t}&id=${e}`;n.src=a?a==null?void 0:a.createScriptURL(i):i,n.async=!0,document.head.appendChild(n)}function TZ(t){let e=[];return Array.isArray(window[t])?e=window[t]:window[t]=e,e}async function NZ(t,e,a,n,i,r){const o=n[i];try{if(o)await e[o];else{const c=(await TO(a)).find(d=>d.measurementId===i);c&&await e[c.appId]}}catch(l){Pa.error(l)}t("config",i,r)}async function IZ(t,e,a,n,i){try{let r=[];if(i&&i.send_to){let o=i.send_to;Array.isArray(o)||(o=[o]);const l=await TO(a);for(const c of o){const d=l.find(p=>p.measurementId===c),u=d&&e[d.appId];if(u)r.push(u);else{r=[];break}}}r.length===0&&(r=Object.values(e)),await Promise.all(r),t("event",n,i||{})}catch(r){Pa.error(r)}}function PZ(t,e,a,n){async function i(r,...o){try{if(r==="event"){const[l,c]=o;await IZ(t,e,a,l,c)}else if(r==="config"){const[l,c]=o;await NZ(t,e,a,n,l,c)}else if(r==="consent"){const[l,c]=o;t("consent",l,c)}else if(r==="get"){const[l,c,d]=o;t("get",l,c,d)}else if(r==="set"){const[l]=o;t("set",l)}else t(r,...o)}catch(l){Pa.error(l)}}return i}function RZ(t,e,a,n,i){let r=function(...o){window[n].push(arguments)};return window[i]&&typeof window[i]=="function"&&(r=window[i]),window[i]=PZ(r,t,e,a),{gtagCore:r,wrappedGtag:window[i]}}function LZ(t){const e=window.document.getElementsByTagName("script");for(const a of Object.values(e))if(a.src&&a.src.includes(Wk)&&a.src.includes(t))return a;return null}/**
3632 * @license
3633 * Copyright 2020 Google LLC
3634 *
3635 * Licensed under the Apache License, Version 2.0 (the "License");
3636 * you may not use this file except in compliance with the License.
3637 * You may obtain a copy of the License at
3638 *
3639 *   http://www.apache.org/licenses/LICENSE-2.0
3640 *
3641 * Unless required by applicable law or agreed to in writing, software
3642 * distributed under the License is distributed on an "AS IS" BASIS,
3643 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
3644 * See the License for the specific language governing permissions and
3645 * limitations under the License.
3646 */const OZ=30,MZ=1e3;class DZ{constructor(e={},a=MZ){this.throttleMetadata=e,this.intervalMillis=a}getThrottleMetadata(e){return this.throttleMetadata[e]}setThrottleMetadata(e,a){this.throttleMetadata[e]=a}deleteThrottleMetadata(e){delete this.throttleMetadata[e]}}const NO=new DZ;function qZ(t){return new Headers({Accept:"application/json","x-goog-api-key":t})}async function zZ(t){var e;const{appId:a,apiKey:n}=t,i={method:"GET",headers:qZ(n)},r=_Z.replace("{app-id}",a),o=await fetch(r,i);if(o.status!==200&&o.status!==304){let l="";try{const c=await o.json();!((e=c.error)===null||e===void 0)&&e.message&&(l=c.error.message)}catch{}throw Ba.create("config-fetch-failed",{httpStatus:o.status,responseMessage:l})}return o.json()}async function VZ(t,e=NO,a){const{appId:n,apiKey:i,measurementId:r}=t.options;if(!n)throw Ba.create("no-app-id");if(!i){if(r)return{measurementId:r,appId:n};throw Ba.create("no-api-key")}const o=e.getThrottleMetadata(n)||{backoffCount:0,throttleEndTimeMillis:Date.now()},l=new BZ;return setTimeout(async()=>{l.abort()},SZ),IO({appId:n,apiKey:i,measurementId:r},o,l,e)}async function IO(t,{throttleEndTimeMillis:e,backoffCount:a},n,i=NO){var r;const{appId:o,measurementId:l}=t;try{await HZ(n,e)}catch(c){if(l)return Pa.warn(`Timed out fetching this Firebase app's measurement ID from the server. Falling back to the measurement ID ${l} provided in the "measurementId" field in the local Firebase config. [${c==null?void 0:c.message}
3646]`),{appId:o,measurementId:l};throw c}try{const c=await zZ(t);return i.deleteThrottleMetadata(o),c}catch(c){const d=c;if(!FZ(d)){if(i.deleteThrottleMetadata(o),l)return Pa.warn(`Failed to fetch this Firebase app's measurement ID from the server. Falling back to the measurement ID ${l} provided in the "measurementId" field in the local Firebase config. [${d==null?void 0:d.message}]`),{appId:o,measurementId:l};throw c}const u=Number((r=d==null?void 0:d.customData)===null||r===void 0?void 0:r.httpStatus)===503?VE(a,i.intervalMillis,OZ):VE(a,i.intervalMillis),p={throttleEndTimeMillis:Date.now()+u,backoffCount:a+1};return i.setThrottleMetadata(o,p),Pa.debug(`Calling attemptFetch again in ${u} millis`),IO(t,p,n,i)}}function HZ(t,e){return new Promise((a,n)=>{const i=Math.max(e-Date.now(),0),r=setTimeout(a,i);t.addEventListener(()=>{clearTimeout(r),n(Ba.create("fetch-throttle",{throttleEndTimeMillis:e}))})})}function FZ(t){if(!(t instanceof gn)||!t.customData)return!1;const e=Number(t.customData.httpStatus);return e===429||e===500||e===503||e===504}class BZ{constructor(){this.listeners=[]}addEventListener(e){this.listeners.push(e)}abort(){this.listeners.forEach(e=>e())}}async function UZ(t,e,a,n,i){if(i&&i.global){t("event",a,n);return}else{const r=await e,o=Object.assign(Object.assign({},n),{send_to:r});t("event",a,o)}}/**
3647 * @license
3648 * Copyright 2020 Google LLC
3649 *
3650 * Licensed under the Apache License, Version 2.0 (the "License");
3651 * you may not use this file except in compliance with the License.
3652 * You may obtain a copy of the License at
3653 *
3654 *   http://www.apache.org/licenses/LICENSE-2.0
3655 *
3656 * Unless required by applicable law or agreed to in writing, software
3657 * distributed under the License is distributed on an "AS IS" BASIS,
3658 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
3659 * See the License for the specific language governing permissions and
3660 * limitations under the License.
3661 */async function $Z(){if(qw())try{await zw()}catch(t){return Pa.warn(Ba.create("indexeddb-unavailable",{errorInfo:t==null?void 0:t.toString()}).message),!1}else return Pa.warn(Ba.create("indexeddb-unavailable",{errorInfo:"IndexedDB is not available in this environment."}).message),!1;return!0}async function WZ(t,e,a,n,i,r,o){var l;const c=VZ(t);c.then(h=>{a[h.measurementId]=h.appId,t.options.measurementId&&h.measurementId!==t.options.measurementId&&Pa.warn(`The measurement ID in the local Firebase config (${t.options.measurementId}) does not match the measurement ID fetched from the server (${h.measurementId}). To ensure analytics events are always sent to the correct Analytics property, update the measurement ID field in the local config or remove it from the local config.`)}).catch(h=>Pa.error(h)),e.push(c);const d=$Z().then(h=>{if(h)return n.getId()}),[u,p]=await Promise.all([c,d]);LZ(r)||jZ(r,u.measurementId),i("js",new Date);const m=(l=o==null?void 0:o.config)!==null&&l!==void 0?l:{};return m[kZ]="firebase",m.update=!0,p!=null&&(m[wZ]=p),i("config",u.measurementId,m),u.measurementId}/**
3662 * @license
3663 * Copyright 2019 Google LLC
3664 *
3665 * Licensed under the Apache License, Version 2.0 (the "License");
3666 * you may not use this file except in compliance with the License.
3667 * You may obtain a copy of the License at
3668 *
3669 *   http://www.apache.org/licenses/LICENSE-2.0
3670 *
3671 * Unless required by applicable law or agreed to in writing, software
3672 * distributed under the License is distributed on an "AS IS" BASIS,
3673 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
3674 * See the License for the specific language governing permissions and
3675 * limitations under the License.
3676 */class GZ{constructor(e){this.app=e}_delete(){return delete xd[this.app.options.appId],Promise.resolve()}}let xd={},rj=[];const oj={};let D0="dataLayer",KZ="gtag",sj,PO,lj=!1;function JZ(){const t=[];if(Dw()&&t.push("This is a browser extension environment."),VR()||t.push("Cookies are not available."),t.length>0){const e=t.map((n,i)=>`(${i+1}) ${n}`).join(" "),a=Ba.create("invalid-analytics-context",{errorInfo:e});Pa.warn(a.message)}}function QZ(t,e,a){JZ();
3676const n=t.options.appId;if(!n)throw Ba.create("no-app-id");if(!t.options.apiKey)if(t.options.measurementId)Pa.warn(`The "apiKey" field is empty in the local Firebase config. This is needed to fetch the latest measurement ID for this Firebase app. Falling back to the measurement ID ${t.options.measurementId} provided in the "measurementId" field in the local Firebase config.`);else throw Ba.create("no-api-key");if(xd[n]!=null)throw Ba.create("already-exists",{id:n});if(!lj){TZ(D0);const{wrappedGtag:r,gtagCore:o}=RZ(xd,rj,oj,D0,KZ);PO=r,sj=o,lj=!0}return xd[n]=WZ(t,rj,oj,e,sj,D0,a),new GZ(t)}function RO(t=mg()){t=et(t);const e=Qr(t,$h);return e.isInitialized()?e.getImmediate():XZ(t)}function XZ(t,e={}){const a=Qr(t,$h);if(a.isInitialized()){const i=a.getImmediate();if(eu(e,a.getOptions()))return i;throw Ba.create("already-initialized")}return a.initialize({options:e})}async function LO(){if(Dw()||!VR()||!qw())return!1;try{return await zw()}catch{return!1}}function OO(t,e,a,n){t=et(t),UZ(PO,xd[t.app.options.appId],e,a,n).catch(i=>Pa.error(i))}const cj="@firebase/analytics",dj="0.10.8";function YZ(){Dn(new hn($h,(e,{options:a})=>{const n=e.getProvider("app").getImmediate(),i=e.getProvider("installations-internal").getImmediate();return QZ(n,i,a)},"PUBLIC")),Dn(new hn("analytics-internal",t,"PRIVATE")),Na(cj,dj),Na(cj,dj,"esm2017");function t(e){try{const a=e.getProvider($h).getImmediate();return{logEvent:(n,i,r)=>OO(a,n,i,r)}}catch(a){throw Ba.create("interop-component-reg-failed",{reason:a})}}}YZ();const ZZ={apiKey:"AIzaSyAnGhhCPPtwkANfLbB5XkPpQtie7v3B2qw",authDomain:"web-haka-2026.firebaseapp.com",projectId:"web-haka-2026",storageBucket:"web-haka-2026.firebasestorage.app",messagingSenderId:"786948522059",appId:"1:786948522059:web:6ffa235f89fa769208cdce",measurementId:"G-H8DW25VVF8"},Rg=UR(ZZ),xi=LY(Rg),St=oJ(Rg),Gk=RQ(Rg);LO().then(t=>t?RO(Rg):null);function eee({isOpen:t,onClose:e}){const{t:a}=$(),n=k.useRef(null),[i,r]=k.useState({nombre:"",email:"",pais:"",telefono:""}),[o,l]=k.useState(null),[c,d]=k.useState(!1),[u,p]=k.useState(null),m=x=>{r({...i,[x.target.name]:x.target.value})},h=x=>{const v=x.target.files[0];if(!v)return;if(!["application/pdf","application/msword","application/vnd.openxmlformats-officedocument.wordprocessingml.document"].includes(v.type)){alert(a("trabajaModal.archivoInvalido"));return}if(v.size>2*1024*1024){alert(a("trabajaModal.archivoGrande"));return}l(v)},g=()=>{r({nombre:"",email:"",pais:"",telefono:""}),l(null),n.current&&(n.current.value="")},y=async x=>{x.preventDefault(),d(!0),p(null);try{let v="";if(o){const w=Date.now(),S=o.name.replace(/[^a-zA-Z0-9._-]/g,"_"),T=Nk(Gk,`cv/${w}_${S}`);await jk(T,o),v=await Tk(T)}await Tl(ga(St,"mail"),{to:["[email protected]"],cc:["[email protected]"],message:{subject:"Trabaja con Nosotros - Nuevo CV recibido",html:`
3677                        <div style="font-family: Arial, sans-serif; max-width: 600px; margin: 0 auto;">
3678                            <h2 style="color: #06b6d4;">Nuevo postulante - Trabaja con Nosotros</h2>
3679                            <div style="background: #f3f4f6; padding: 20px; border-radius: 8px; margin: 20px 0;">
3680                                <p><strong>Nombre:</strong> ${i.nombre}</p>
3681                                <p><strong>Email:</strong> ${i.email}</p>
3682                                <p><strong>País de residencia:</strong> ${i.pais}</p>
3683                                <p><strong>Teléfono:</strong> ${i.telefono}</p>
3684                                ${v?`<p><strong>CV:</strong> <a href="${v}" style="color: #06b6d4;">Descargar CV</a></p>`:"<p><em>No adjuntó CV</em></p>"}
3685                            </div>
3686                            <p style="color: #6b7280; font-size: 12px;">Este mensaje fue enviado desde el formulario "Trabaja con Nosotros" de hakalab.com</p>
3687                        </div>
3688                    `},timestamp:new Date}),p("success"),g(),setTimeout(()=>{e(),p(null)},2e3)}catch(v){console.error("Error al enviar postulación:",v),p("error")}finally{d(!1)}};return t?s.jsx(La,{children:t&&s.jsx(_.div,{initial:{opacity:0}
3688,animate:{opacity:1},exit:{opacity:0},onClick:e,className:"fixed inset-0 bg-black/70 backdrop-blur-sm z-50 flex items-center justify-center p-4",children:s.jsxs(_.div,{initial:{opacity:0,scale:.95,y:20},animate:{opacity:1,scale:1,y:0},exit:{opacity:0,scale:.95,y:20},onClick:x=>x.stopPropagation(),className:"bg-[#1a1d3a] rounded-3xl shadow-2xl max-w-2xl w-full relative overflow-hidden max-h-[90vh] overflow-y-auto",children:[s.jsx("div",{className:"absolute top-0 right-0 w-64 h-64 bg-cyan-500/10 rounded-full blur-3xl"}),s.jsx("div",{className:"absolute bottom-0 left-0 w-64 h-64 bg-blue-500/10 rounded-full blur-3xl"}),s.jsxs("div",{className:"relative p-8 sm:p-10",children:[s.jsx("button",{onClick:e,className:"absolute top-6 right-6 text-gray-400 hover:text-white transition-colors",children:s.jsx("svg",{className:"w-6 h-6",fill:"none",viewBox:"0 0 24 24",stroke:"currentColor",children:s.jsx("path",{strokeLinecap:"round",strokeLinejoin:"round",strokeWidth:2,d:"M6 18L18 6M6 6l12 12"})})}),s.jsx("h2",{className:"text-3xl sm:text-4xl font-bold text-white mb-3",children:a("trabajaModal.title")}),s.jsx("p",{className:"text-gray-300 mb-8",children:a("trabajaModal.subtitle")}),s.jsxs("form",{onSubmit:y,className:"space-y-6",children:[s.jsxs("div",{children:[s.jsxs("label",{htmlFor:"trabaja-nombre",className:"block text-gray-300 mb-2 font-medium",children:[a("trabajaModal.nombre")," ",s.jsx("span",{className:"text-cyan-400",children:"*"})]}),s.jsx("input",{type:"text",id:"trabaja-nombre",name:"nombre",value:i.nombre,onChange:m,required:!0,placeholder:a("trabajaModal.nombrePlaceholder"),className:"w-full bg-[#2a2d4a] text-white px-4 py-3 rounded-xl border-2 border-transparent focus:border-cyan-400 focus:outline-none transition-colors placeholder-gray-500"})]}),s.jsxs("div",{children:[s.jsxs("label",{htmlFor:"trabaja-email",className:"block text-gray-300 mb-2 font-medium",children:[a("trabajaModal.email")," ",s.jsx("span",{className:"text-cyan-400",children:"*"})]}),s.jsxs("div",{className:"relative",children:[s.jsx("div",{className:"absolute inset-y-0 left-0 pl-4 flex items-center pointer-events-none",children:s.jsx("svg",{className:"w-5 h-5 text-gray-500",fill:"none",viewBox:"0 0 24 24",stroke:"currentColor",children:s.jsx("path",{strokeLinecap:"round",strokeLinejoin:"round",strokeWidth:2,d:"M3 8l7.89 5.26a2 2 0 002.22 0L21 8M5 19h14a2 2 0 002-2V7a2 2 0 00-2-2H5a2 2 0 00-2 2v10a2 2 0 002 2z"})})}),s.jsx("input",{type:"email",id:"trabaja-email",name:"email",value:i.email,onChange:m,required:!0,placeholder:a("trabajaModal.emailPlaceholder"),className:"w-full bg-[#2a2d4a] text-white pl-12 pr-4 py-3 rounded-xl border-2 border-transparent focus:border-cyan-400 focus:outline-none transition-colors placeholder-gray-500"})]})]}),s.jsxs("div",{children:[s.jsxs("label",{htmlFor:"trabaja-pais",className:"block text-gray-300 mb-2 font-medium",children:[a("trabajaModal.pais")," ",s.jsx("span",{className:"text-cyan-400",children:"*"})]}),s.jsx("input",{type:"text",id:"trabaja-pais",name:"pais",value:i.pais,onChange:m,required:!0,placeholder:a("trabajaModal.paisPlaceholder"),className:"w-full bg-[#2a2d4a] text-white px-4 py-3 rounded-xl border-2 border-transparent focus:border-cyan-400 focus:outline-none transition-colors placeholder-gray-500"})]}),s.jsxs("div",{children:[s.jsxs("label",{htmlFor:"trabaja-telefono",className:"block text-gray-300 mb-2 font-medium",children:[a("trabajaModal.telefono")," ",s.jsx("span",{className:"text-cyan-400",children:"*"})]}),s.jsx("input",{type:"tel",id:"trabaja-telefono",name:"telefono",value:i.telefono,onChange:m,required:!0,placeholder:a("trabajaModal.telefonoPlaceholder"),className:"w-full bg-[#2a2d4a] text-white px-4 py-3 rounded-xl border-2 border-transparent focus:border-cyan-400 focus:outline-none transition-colors placeholder-gray-500"})]}),s.jsxs("div",{children:[s.jsxs("label",{className:"block text-gray-300 mb-2 font-medium",children:[a("trabajaModal.cv")," ",s.jsx("span",{className:"text-cyan-400",children:"*"})]}),s.jsxs("div",{onClick:()=>{var x;return(x=n.current)==null?void 0:x.click()},className:"w-full bg-[#2a2d4a] text-white px-4 py-4 rounded-xl border-2 border-dashed border-gray-600 hover:border-cyan-400 transition-colors cursor-pointer flex items-center gap-3",children:[s.jsx("svg",{className:"w-6 h-6 text-cyan-400 flex-shrink-0",fill:"none",viewBox:"0 0 24 24",stroke:"currentColor",children:s.jsx("path",{strokeLinecap:"round",strokeLinejoin:"round",strokeWidth:2,d:"M7 16a4 4 0 01-.88-7.903A5 5 0 1115.9 6L16 6a5 5 0 011 9.9M15 13l-3-3m0 0l-3 3m3-3v12"})}),s.jsx("span",{className:o?"text-cyan-400":"text-gray-500",children:o?o.name:a("trabajaModal.cvPlaceholder")})]}),s.jsx("input",{ref:n,type:"file",accept:".pdf,.doc,.docx",onChange:h,className:"hidden",required:!0}),s.jsx("p",{className:"text-gray-500 text-xs mt-1",children:a("trabajaModal.cvFormatos")})]}),u==="success"&&s.jsx(_.div,{initial:{opacity:0,y:-10}
3688,animate:{opacity:1,y:0},className:"bg-green-500/20 border border-green-500 text-green-400 px-4 py-3 rounded-xl",children:a("trabajaModal.exitoEnvio")}),u==="error"&&s.jsx(_.div,{initial:{opacity:0,y:-10},animate:{opacity:1,y:0},className:"bg-red-500/20 border border-red-500 text-red-400 px-4 py-3 rounded-xl",children:a("trabajaModal.errorEnvio")}),s.jsx("button",{type:"submit",disabled:c,className:"w-full bg-gradient-to-r from-cyan-400 to-blue-500 hover:from-cyan-500 hover:to-blue-600 text-white font-bold py-4 px-6 rounded-xl transition-all duration-300 hover:shadow-lg hover:shadow-cyan-400/50 disabled:opacity-50 disabled:cursor-not-allowed border-2 border-cyan-400",children:c?s.jsxs("span",{className:"flex items-center justify-center gap-2",children:[s.jsxs("svg",{className:"animate-spin h-5 w-5",viewBox:"0 0 24 24",children:[s.jsx("circle",{className:"opacity-25",cx:"12",cy:"12",r:"10",stroke:"currentColor",strokeWidth:"4",fill:"none"}),s.jsx("path",{className:"opacity-75",fill:"currentColor",d:"M4 12a8 8 0 018-8V0C5.373 0 0 5.373 0 12h4zm2 5.291A7.962 7.962 0 014 12H0c0 3.042 1.135 5.824 3 7.938l3-2.647z"})]}),a("trabajaModal.enviando")]}):a("trabajaModal.enviar")})]})]})]})})}):null}function tee(){const{t}=$(),[e,a]=k.useState(!1);return s.jsxs("footer",{className:"bg-darkGray border-t border-slate-800 py-8 px-4 pt-10",children:[s.jsxs("div",{className:"max-w-7xl mx-auto mt-10 pt-6",children:[s.jsxs("div",{className:"flex flex-col md:flex-row items-center justify-center gap-9 mb-6 pt-10 pb-7 border-b border-slate-800 mt-10",children:[s.jsx("div",{className:"flex flex-col items-center gap-4",children:s.jsxs("div",{className:"flex flex-wrap justify-center gap-6 text-sm",children:[s.jsx("a",{id:"footer-terminos-link",href:"/productos/terms",className:"text-gray-400 hover:text-primary transition-colors",children:t("footer.terminos")}),s.jsxs("a",{href:"mailto:[email protected]",className:"text-gray-400 hover:text-primary transition-colors",children:["contacto",s.jsx("span",{children:"@"}),"hakalab.com"]}),s.jsx("a",{id:"footer-ereshaka-link",href:"https://voyager.hakalab.com/",className:"text-gray-400 hover:text-primary transition-colors",children:t("footer.ereshaka")}),s.jsx("button",{id:"footer-trabaja-link",onClick:()=>a(!0),className:"text-gray-400 hover:text-primary transition-colors",children:t("footer.trabajaConNosotros")})]})}),s.jsxs("div",{className:"flex gap-4",children:[s.jsx("a",{href:"https://www.linkedin.com/company/hakalab",target:"_blank",className:"text-gray-400 hover:text-primary transition-colors",title:"LinkedIn",children:s.jsx("svg",{className:"w-5 h-5",fill:"currentColor",viewBox:"0 0 24 24",children:s.jsx("path",{d:"M19 0h-14c-2.761 0-5 2.239-5 5v14c0 2.761 2.239 5 5 5h14c2.762 0 5-2.239 5-5v-14c0-2.761-2.238-5-5-5zm-11 19h-3v-11h3v11zm-1.5-12.268c-.966 0-1.75-.79-1.75-1.764s.784-1.764 1.75-1.764 1.75.79 1.75 1.764-.783 1.764-1.75 1.764zm13.5 12.268h-3v-5.604c0-3.368-4-3.113-4 0v5.604h-3v-11h3v1.765c1.396-2.586 7-2.777 7 2.476v6.759z"})})}),s.jsx("a",{href:"https://www.instagram.com/hakalab.latam",target:"_blank",className:"text-gray-400 hover:text-primary transition-colors",title:"Instagram",children:s.jsx("svg",{className:"w-5 h-5",fill:"currentColor",viewBox:"0 0 24 24",children:s.jsx("path",{d:"M12 2.163c3.204 0 3.584.012 4.85.07 3.252.148 4.771 1.691 4.919 4.919.058 1.265.069 1.645.069 4.849 0 3.205-.012 3.584-.069 4.849-.149 3.225-1.664 4.771-4.919 4.919-1.266.058-1.644.07-4.85.07-3.204 0-3.584-.012-4.849-.07-3.26-.149-4.771-1.699-4.919-4.92-.058-1.265-.07-1.644-.07-4.849 0-3.204.013-3.583.07-4.849.149-3.227 1.664-4.771 4.919-4.919 1.266-.057 1.645-.069 4.849-.069zm0-2.163c-3.259 0-3.667.014-4.947.072-4.358.2-6.78 2.618-6.98 6.98-.059 1.281-.073 1.689-.073 4.948 0 3.259.014 3.668.072 4.948.2 4.358 2.618 6.78 6.98 6.98 1.281.058 1.689.072 4.948.072 3.259 0 3.668-.014 4.948-.072 4.354-.2 6.782-2.618 6.979-6.98.059-1.28.073-1.689.073-4.948 0-3.259-.014-3.667-.072-4.947-.196-4.354-2.617-6.78-6.979-6.98-1.281-.059-1.69-.073-4.949-.073zM5.838 12a6.162 6.162 0 1 1 12.324 0 6.162 6.162 0 0 1-12.324 0zM12 16a4 4 0 1 1 0-8 4 4 0 0 1 0 8zm4.965-10.322a1.44 1.44 0 1 1 2.881.001 1.44 1.44 0 0 1-2.881-.001z"})})}),s.jsx("a",{href:"https://x.com/haka_lab",target:"_blank",className:"text-gray-400 hover:text-primary transition-colors",title:"X",children:s.jsx("svg",{className:"w-5 h-5",fill:"currentColor",viewBox:"0 0 24 24",children:s.jsx("path",{d:"M18.244 2.25h3.308l-7.227 8.26 8.502 11.24h-6.514l-5.106-6.694-5.829 6.694h-3.328l7.691-8.793-8.156-10.707h6.657l4.596 6.08 5.279-6.08zM16.369 20.033h1.83L7.622 3.956H5.696l10.673 16.
3688077z"})})}),s.jsx("a",{href:"https://github.com/HakaLab-2025",target:"_blank",className:"text-gray-400 hover:text-primary transition-colors",title:"GitHub",children:s.jsx("svg",{className:"w-5 h-5",fill:"currentColor",viewBox:"0 0 24 24",children:s.jsx("path",{d:"M12 0c-6.626 0-12 5.373-12 12 0 5.302 3.438 9.8 8.207 11.387.599.111.793-.261.793-.577v-2.234c-3.338.726-4.033-1.416-4.033-1.416-.546-1.387-1.333-1.756-1.333-1.756-1.089-.745.083-.729.083-.729 1.205.084 1.839 1.237 1.839 1.237 1.07 1.834 2.807 1.304 3.492.997.107-.775.418-1.305.762-1.604-2.665-.305-5.467-1.334-5.467-5.931 0-1.311.469-2.381 1.236-3.221-.124-.303-.535-1.524.117-3.176 0 0 1.008-.322 3.301 1.23.957-.266 1.983-.399 3.003-.404 1.02.005 2.047.138 3.006.404 2.291-1.552 3.297-1.23 3.297-1.23.653 1.653.242 2.874.118 3.176.77.84 1.235 1.911 1.235 3.221 0 4.609-2.807 5.624-5.479 5.921.43.372.823 1.102.823 2.222v 3.293c0 .319.192.694.801.576 4.765-1.589 8.199-6.086 8.199-11.386 0-6.627-5.373-12-12-12z"})})})]})]}),s.jsxs("div",{className:"flex items-center justify-center gap-3 pb-9",children:[s.jsx("img",{id:"footer-logo",src:"/imagenes/logo_haka.png",alt:"Haka Lab",className:"h-5 w-auto"}),s.jsx("span",{className:"text-sm text-gray-400",children:t("footer.empresa")})]})]}),s.jsx(eee,{isOpen:e,onClose:()=>a(!1)})]})}function aee(){const[t,e]=k.useState(!1),a=()=>{window.scrollY>300?e(!0):e(!1)},n=()=>{window.scrollTo({top:0,behavior:"smooth"})};return k.useEffect(()=>(window.addEventListener("scroll",a),()=>{window.removeEventListener("scroll",a)}),[]),s.jsx(La,{children:t&&s.jsx(_.button,{initial:{opacity:0,scale:.8},animate:{opacity:1,scale:1},exit:{opacity:0,scale:.8},transition:{duration:.3},onClick:n,className:"fixed bottom-8 right-8 z-40 p-2 rounded-full bg-gradient-to-br from-cyan-400 to-blue-500 hover:from-cyan-500 hover:to-blue-600 shadow-2xl shadow-cyan-500/50 transition-all duration-300 hover:shadow-cyan-500/70 transform hover:-translate-y-1","aria-label":"Volver al inicio",children:s.jsx("img",{src:"/imagenes/volverarriba.png",alt:"Volver arriba",className:"w-14 h-14"})})})}function Yr({isOpen:t,onClose:e,title:a="Contáctanos"}){const{t:n}=$(),[i,r]=k.useState({nombre:"",empresa:"",email:"",mensaje:""}),[o,l]=k.useState(!1),[c,d]=k.useState(null),u=m=>{r({...i,[m.target.name]:m.target.value})},p=async m=>{m.preventDefault(),l(!0),d(null);try{const h=await Tl(ga(St,"mail"),{to:["[email protected]"],message:{subject:"Contacto desde la web - HakaLab",html:`
3689                        <div style="font-family: Arial, sans-serif; max-width: 600px; margin: 0 auto;">
3690                            <h2 style="color: #06b6d4;">Nueva solicitud de contacto</h2>
3691                            <div style="background: #f3f4f6; padding: 20px; border-radius: 8px; margin: 20px 0;">
3692                                <p><strong>Nombre:</strong> ${i.nombre}</p>
3693                                <p><strong>Empresa:</strong> ${i.empresa}</p>
3694                                <p><strong>Email:</strong> ${i.email}</p>
3695                                <p><strong>Mensaje:</strong></p>
3696                                <p style="white-space: pre-wrap;">${i.mensaje}</p>
3697                            </div>
3698                            <p style="color: #6b7280; font-size: 12px;">Este mensaje fue enviado desde el formulario de contacto de hakalab.com</p>
3699                        </div>
3700                    `},timestamp:new Date});console.log("Documento guardado en Firestore con ID:",h.id);const g=await fetch("https://us-central1-web-haka-2026.cloudfunctions.net/createJiraIssueFromContact",{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({nombre:i.nombre,email:i.email,empresa:i.empresa,mensaje:i.mensaje})});if(!g.ok)console.warn("Advertencia: No se pudo crear el issue en Jira:",g.status);else{const y=await g.json();console.log("Issue creado en Jira:",y)}d("success"),r({nombre:"",empresa:"",email:"",mensaje:""}),setTimeout(()=>{e(),d(null)},2e3)}catch(h){console.error("Error detallado al enviar:",{message:h.message,code:h.code,fullError:h}),d("error")}finally{l(!1)}};return t?s.jsx(La,{children:t&&s.jsx(s.Fragment,{children:s.jsx(_.div,{id:"contact-modal-overlay",initial:{opacity:0}
3700,animate:{opacity:1},exit:{opacity:0},onClick:e,className:"fixed inset-0 bg-black/70 backdrop-blur-sm z-50 flex items-center justify-center p-4",children:s.jsxs(_.div,{initial:{opacity:0,scale:.95,y:20},animate:{opacity:1,scale:1,y:0},exit:{opacity:0,scale:.95,y:20},onClick:m=>m.stopPropagation(),className:"bg-[#1a1d3a] rounded-3xl shadow-2xl max-w-2xl w-full relative overflow-hidden",children:[s.jsx("div",{className:"absolute top-0 right-0 w-64 h-64 bg-cyan-500/10 rounded-full blur-3xl"}),s.jsx("div",{className:"absolute bottom-0 left-0 w-64 h-64 bg-blue-500/10 rounded-full blur-3xl"}),s.jsxs("div",{className:"relative p-8 sm:p-10",children:[s.jsx("button",{id:"contact-modal-close-button",onClick:e,className:"absolute top-6 right-6 text-gray-400 hover:text-white transition-colors",children:s.jsx("svg",{className:"w-6 h-6",fill:"none",viewBox:"0 0 24 24",stroke:"currentColor",children:s.jsx("path",{strokeLinecap:"round",strokeLinejoin:"round",strokeWidth:2,d:"M6 18L18 6M6 6l12 12"})})}),s.jsx("h2",{className:"text-3xl sm:text-4xl font-bold text-white mb-3",children:a}),s.jsx("p",{className:"text-gray-300 mb-8",children:n("contactModal.subtitle")}),s.jsxs("form",{onSubmit:p,className:"space-y-6",children:[s.jsxs("div",{children:[s.jsxs("label",{htmlFor:"nombre",className:"block text-gray-300 mb-2 font-medium",children:[n("contactModal.nombre")," ",s.jsx("span",{className:"text-cyan-400",children:"*"})]}),s.jsx("input",{type:"text",id:"nombre",name:"nombre",value:i.nombre,onChange:u,required:!0,placeholder:n("contactModal.nombrePlaceholder"),className:"w-full bg-[#2a2d4a] text-white px-4 py-3 rounded-xl border-2 border-transparent focus:border-cyan-400 focus:outline-none transition-colors placeholder-gray-500"})]}),s.jsxs("div",{children:[s.jsxs("label",{htmlFor:"empresa",className:"block text-gray-300 mb-2 font-medium",children:[n("contactModal.empresa")," ",s.jsx("span",{className:"text-cyan-400",children:"*"})]}),s.jsx("input",{type:"text",id:"empresa",name:"empresa",value:i.empresa,onChange:u,required:!0,placeholder:n("contactModal.empresaPlaceholder"),className:"w-full bg-[#2a2d4a] text-white px-4 py-3 rounded-xl border-2 border-transparent focus:border-cyan-400 focus:outline-none transition-colors placeholder-gray-500"})]}),s.jsxs("div",{children:[s.jsxs("label",{htmlFor:"email",className:"block text-gray-300 mb-2 font-medium",children:[n("contactModal.email")," ",s.jsx("span",{className:"text-cyan-400",children:"*"})]}),s.jsxs("div",{className:"relative",children:[s.jsx("div",{className:"absolute inset-y-0 left-0 pl-4 flex items-center pointer-events-none",children:s.jsx("svg",{className:"w-5 h-5 text-gray-500",fill:"none",viewBox:"0 0 24 24",stroke:"currentColor",children:s.jsx("path",{strokeLinecap:"round",strokeLinejoin:"round",strokeWidth:2,d:"M3 8l7.89 5.26a2 2 0 002.22 0L21 8M5 19h14a2 2 0 002-2V7a2 2 0 00-2-2H5a2 2 0 00-2 2v10a2 2 0 002 2z"})})}),s.jsx("input",{type:"email",id:"email",name:"email",value:i.email,onChange:u,required:!0,placeholder:n("contactModal.emailPlaceholder"),className:"w-full bg-[#2a2d4a] text-white pl-12 pr-4 py-3 rounded-xl border-2 border-transparent focus:border-cyan-400 focus:outline-none transition-colors placeholder-gray-500"})]})]}),s.jsxs("div",{children:[s.jsxs("label",{htmlFor:"mensaje",className:"block text-gray-300 mb-2 font-medium",children:[n("contactModal.mensaje")," ",s.jsx("span",{className:"text-cyan-400",children:"*"})]}),s.jsx("textarea",{id:"mensaje",name:"mensaje",value:i.mensaje,onChange:u,required:!0,rows:"4",placeholder:n("contactModal.mensajePlaceholder"),className:"w-full bg-[#2a2d4a] text-white px-4 py-3 rounded-xl border-2 border-transparent focus:border-cyan-400 focus:outline-none transition-colors placeholder-gray-500 resize-none"})]}),c==="success"&&s.jsx(_.div,{initial:{opacity:0,y:-10},animate:{opacity:1,y:0},className:"bg-green-500/20 border border-green-500 text-green-400 px-4 py-3 rounded-xl",children:n("contactModal.exitoEnvio")}),c==="error"&&s.jsx(_.div,{initial:{opacity:0,y:-10},animate:{opacity:1,y:0},className:"bg-red-500/20 border border-red-500 text-red-400 px-4 py-3 rounded-xl",children:n("contactModal.errorEnvio")}),s.jsx("button",{type:"submit",disabled:o,className:"w-full bg-gradient-to-r from-cyan-400 to-blue-500 hover:from-cyan-500 hover:to-blue-600 text-white font-bold py-4 px-6 rounded-xl transition-all duration-300 hover:shadow-lg hover:shadow-cyan-400/50 disabled:opacity-50 disabled:cursor-not-allowed border-2 border-cyan-400",children:o?s.jsxs("span",{className:"flex items-center justify-center gap-2",children:[s.jsxs("svg",{className:"animate-spin h-5 w-5",viewBox:"0 0 24 24",children:[s.jsx("circle",{className:"opacity-25",cx:"12",cy:"12",r:"10",stroke:"currentColor",strokeWidth:"4",fill:"none"}),s.jsx("path",{className:"opacity-75",fill:"currentColor",d:"M4 12a8 8 0 018-8V0C5.373 0 0 5.373 0 12h4zm2 5.291A7.962 7.962 0 014 12H0c0 3.042 1.135 5.824 3 7.938l3-2.647z"})]}),n("contactModal.enviando")]}):n("contactModal.enviar")})]})]})]})})})}):null}const MO=k.createContext(),uj=["[email protected]","[email protected]","[email protected]","[email protected]","[email protected]"];function nee({children:t}){const[e,a]=k.useState(null),[n,i]=k.useState(!0),[r,o]=k.useState(null),[l,c]=k.useState(!1);k.useEffect(()=>Y3(xi,async h=>{try{h?uj.includes(h.email)?(a(h),c(!0)):(await yd(xi),a(null),c(!1)):(a(null),c(!1))}catch(g){console.error("Error verificando usuario:",g),o(g.message),a(null),c(!1)}finally{i(!1)}}),[]);const p={user:e,loading:n,error:r,isAdmin:l,loginWithGoogle:async()=>{try{o(null);const m=new Kn,h=await cO(xi,m);if(!uj.includes(h.user.email))throw await yd(xi),new Error(`El usuario ${h.user.email} no tiene permiso para acceder. Solo usuarios autorizados pueden ingresar.`);return a(h.user),c(!0),i(!1),h.user}catch(m){throw o(m.message),i(!1),m}},logout:async()=>{try{o(null),await yd(xi),a(null),c(!1)}catch(m){throw o(m.message),m}}};return s.jsx(MO.Provider,{value:p,children:t})}function hs(){const t=k.useContext(MO);if(!t)throw new Error("useAuth debe ser usado dentro de AuthProvider");return t}function Gp({children:t}){const{user:e,loading:a,isAdmin:n}=hs();return a?s.jsx("div",{className:"min-h-screen flex items-center justify-center bg-dark",children:s.jsx(_.div,{animate:{rotate:360},transition:{duration:2,repeat:1/0,ease:"linear"},className:"w-12 h-12 border-4 border-primary border-t-transparent roun
3700ded-full"})}):!e||!n?s.jsx(ew,{to:"/admin-blog",replace:!0}):t}function q0({children:t}){return window.location.hostname.includes("web-haka-2026.web.app")||window.location.hostname==="localhost"||window.location.hostname==="127.0.0.1"?t:s.jsx(ew,{to:"/404",replace:!0})}function ie({variant:t=1}){const e="#0a0e27ff",a={1:"M0,0L0,40L48,45.3C96,51,192,61,288,66.7C384,72,480,72,576,66.7C672,61,768,51,864,56C960,61,1056,83,1152,88C1248,93,1344,83,1392,77.3L1440,72L1440,0L1392,0C1344,0,1248,0,1152,0C1056,0,960,0,864,0C768,0,672,0,576,0C480,0,384,0,288,0C192,0,96,0,48,0L0,0Z",2:"M0,0L0,40L48,34.7C96,29,192,19,288,24C384,29,480,51,576,56C672,61,768,51,864,45.3C960,40,1056,40,1152,34.7C1248,29,1344,19,1392,13.3L1440,8L1440,0L1392,0C1344,0,1248,0,1152,0C1056,0,960,0,864,0C768,0,672,0,576,0C480,0,384,0,288,0C192,0,96,0,48,0L0,0Z",3:"M0,0L0,40L48,45.3C96,51,192,61,288,56C384,51,480,29,576,24C672,19,768,29,864,40C960,51,1056,61,1152,61.3C1248,61,1344,51,1392,45.3L1440,40L1440,0L1392,0C1344,0,1248,0,1152,0C1056,0,960,0,864,0C768,0,672,0,576,0C480,0,384,0,288,0C192,0,96,0,48,0L0,0Z"},n=`waveGrad-${t}`;return s.jsx("div",{className:"absolute bottom-0 left-0 w-full overflow-visible pointer-events-none",style:{height:"clamp(60px, 15vw, 120px)",transform:"translateY(100%)",zIndex:10},children:s.jsxs("svg",{className:"w-full h-full overflow-visible",viewBox:"0 0 1440 100",preserveAspectRatio:"xMidYMid slice",xmlns:"http://www.w3.org/2000/svg",style:{filter:"drop-shadow(0px 18px 10px rgba(0, 0, 0, 0.8))"},children:[s.jsx("defs",{children:s.jsxs("linearGradient",{id:n,x1:"0%",y1:"0%",x2:"0%",y2:"100%",children:[s.jsx("stop",{offset:"0%",stopColor:e,stopOpacity:"1"}),s.jsx("stop",{offset:"20%",stopColor:e,stopOpacity:"1"}),s.jsx("stop",{offset:"100%",stopColor:e,stopOpacity:"1"})]})}),s.jsx("path",{fill:`url(#${n})`,d:a[t]})]})})}function iee(){const{t}=$(),e=t("roibox",{returnObjects:!0});return s.jsxs("div",{className:`animate-float-slow absolute -bottom-4 -right-4 md:-right-10 z-20 
3701                    flex items-center gap-3 bg-[#0a1628]/80 backdrop-blur-md 
3702                    border border-white/10 p-4 rounded-2xl shadow-2xl min-w-[200px]`,children:[s.jsx("div",{className:"bg-[#0095ff] p-2 rounded-xl shadow-[0_0_15px_rgba(0,149,255,0.6)] flex items-center justify-center",children:s.jsx("svg",{className:"w-6 h-6 text-white",fill:"currentColor",viewBox:"0 0 24 24",children:s.jsx("path",{d:"M13 10V3L4 14h7v7l9-11h-7z"})})}),s.jsxs("div",{className:"flex flex-col text-left",children:[s.jsx("span",{className:"text-[10px] font-bold text-[#0095ff] tracking-widest uppercase leading-tight",children:e.title}),s.jsxs("div",{className:"flex items-center gap-1",children:[s.jsx("span",{className:"text-xl md:text-2xl font-bold text-white",children:"+70%"}),s.jsx("span",{className:"text-sm md:text-base font-medium text-white/90",children:e.title2})]})]})]})}const Lg=({text:t})=>s.jsxs("div",{className:"w-fit inline-flex items-center gap-2 px-4 py-1 rounded-full border border-cyan-500/40 bg-cyan-950/20 backdrop-blur-md",children:[s.jsx("span",{className:"h-2 w-2 rounded-full bg-cyan-400 shadow-[0_0_8px_rgba(34,211,238,0.8)]"}),s.jsx("span",{className:"text-[10px] md:text-xs font-bold tracking-[0.15em] text-cyan-400 uppercase whitespace-nowrap",children:t})]}),ree="https://calendar.app.google/dkJfuj7MNARbfT5HA";function oee(){const{t}=$(),e=t("home.hero",{returnObjects:!0}),a=t("badges",{returnObjects:!0}),{isOpen:n,modalTitle:i,openModal:r,closeModal:o}=oa(),l=Qa(),c=()=>{window.open(ree,"_blank","width=1000,height=700,noopener")};return s.jsxs("section",{id:"home",className:"relative bg-dark",itemScope:!0,itemType:"https://schema.org/WebPageElement",children:[s.jsxs("div",{className:"relative py-12 sm:py-16 md:py-5 flex items-center justify-center overflow-hidden min-h-[500px] sm:min-h-[600px]",children:[s.jsx("div",{className:"absolute inset-0 bg-gradient-to-br from-dark via-dark to-dark"}),s.jsx("div",{className:"hero-glow"}),s.jsx("div",{className:"relative z-10 mt-6 sm:mt-8 md:mt-10 max-w-7xl mx-auto px-4 sm:px-6 md:px-8 w-full",children:s.jsxs("div",{className:"grid grid-cols-1 lg:grid-cols-2 gap-8 sm:gap-12 md:gap-16 items-center",children:[s.jsxs("div",{className:"flex flex-col justify-center text-left lg:text-left",children:[s.jsx(Lg,{text:a.lideres}),s.jsx("h1",{id:"hero-title",className:"text-5xl md:text-7xl font-extrabold tracking-tight text-white",itemProp:"headline",children:e.title}),s.jsx("h1",{id:"hero-title-2",class:"text-5xl md:text-7xl font-extrabold border-primary text-primary italic mt-4",children:s.jsx("span",{span:"",children:e.title2})}),s.jsx("p",{id:"hero-subtitle",className:"text-xl text-white font-normal max-w-lg leading-relaxed mt-10",itemProp:"description",children:e.subt
3702itle}),s.jsxs("div",{className:"flex flex-col sm:flex-row justify-center lg:justify-start gap-4 w-full sm:w-auto mt-7",children:[s.jsx("button",{id:"hero-schedule-call-button",onClick:c,className:"bg-primary border-2 border-primary text-dark px-6 sm:px-8 md:px-10 py-3 sm:py-3 rounded-2xl text-base sm:text-lg font-semibold hover:bg-dark hover:text-primary transition-all duration-300","aria-label":"Agendar una cita",children:e.scheduleCall}),s.jsx("button",{id:"hero-casos-exito-button",onClick:()=>{l("/casosdeexito")},className:"border-2 border-primary/50 text-primary px-6 sm:px-8 md:px-10 py-3 sm:py-2 rounded-2xl text-base sm:text-lg font-semibold hover:bg-primary hover:text-dark transition-all duration-300",children:e.cta})]})]}),s.jsxs("div",{className:"flex justify-center items-center mt-0 lg:mt-0 relative",children:[s.jsx(iee,{}),s.jsx("img",{id:"hero-hero-image",src:"/imagenes/home/personajeshaka_hero1.webp",alt:t("common.altHeroImage"),className:"w-full max-w-xs sm:max-w-md lg:max-w-lg h-auto drop-shadow-2xl",loading:"eager",fetchpriority:"high",decoding:"async",width:"512",height:"512",itemProp:"image"})]})]})})]}),s.jsx(ie,{variant:1}),s.jsx(Yr,{isOpen:n,onClose:o,title:i})]})}function see({className:t="w-12 h-12"}){return s.jsxs("svg",{className:t,viewBox:"0 0 24 24",fill:"none",xmlns:"http://www.w3.org/2000/svg",children:[s.jsx("path",{d:"M12 2L3 7V17L12 22L21 17V7L12 2Z",stroke:"currentColor",strokeWidth:"1.5",strokeLinecap:"round",strokeLinejoin:"round"}),s.jsx("path",{d:"M12 22V12",stroke:"currentColor",strokeWidth:"1.5",strokeLinecap:"round",strokeLinejoin:"round"}),s.jsx("path",{d:"M21 7L12 12L3 7",stroke:"currentColor",strokeWidth:"1.5",strokeLinecap:"round",strokeLinejoin:"round"}),s.jsx("circle",{cx:"12",cy:"9",r:"2",stroke:"currentColor",strokeWidth:"1.5"}),s.jsx("path",{d:"M8 14L12 16L16 14",stroke:"currentColor",strokeWidth:"1.5",strokeLinecap:"round",strokeLinejoin:"round"})]})}function lee({className:t="w-12 h-12"}){return s.jsx("svg",{className:t,viewBox:"0 0 24 24",fill:"none",xmlns:"http://www.w3.org/2000/svg",children:s.jsx("path",{d:"M13 2L3 14H12L11 22L21 10H12L13 2Z",stroke:"currentColor",strokeWidth:"1.5",strokeLinecap:"round",strokeLinejoin:"round"})})}function cee({className:t="w-12 h-12"}){return s.jsxs("svg",{className:t,viewBox:"0 0 24 24",fill:"none",xmlns:"http://www.w3.org/2000/svg",children:[s.jsx("rect",{x:"3",y:"3",width:"7",height:"7",rx:"1",stroke:"currentColor",strokeWidth:"1.5"}),s.jsx("rect",{x:"3",y:"14",width:"7",height:"7",rx:"1",stroke:"currentColor",strokeWidth:"1.5"}),s.jsx("rect",{x:"14",y:"3",width:"7",height:"7",rx:"1",stroke:"currentColor",strokeWidth:"1.5"}),s.jsx("rect",{x:"14",y:"14",width:"7",height:"7",rx:"1",stroke:"currentColor",strokeWidth:"1.5"}),s.jsx("path",{d:"M6.5 6.5V8.5",stroke:"currentColor",strokeWidth:"1.5",strokeLinecap:"round"}),s.jsx("path",{d:"M6.5 17.5V19.5",stroke:"currentColor",strokeWidth:"1.5",strokeLinecap:"round"}),s.jsx("path",{d:"M17.5 6.5V8.5",stroke:"currentColor",strokeWidth:"1.5",strokeLinecap:"round"}),s.jsx("path",{d:"M17.5 17.5V19.5",stroke:"currentColor",strokeWidth:"1.5",strokeLinecap:"round"})]})}function dee({className:t="w-12 h-12"}){return s.jsxs("svg",{className:t,viewBox:"0 0 24 24",fill:"none",xmlns:"http://www.w3.org/2000/svg",children:[s.jsx("circle",{cx:"5",cy:"12",r:"2",stroke:"currentColor",strokeWidth:"1.5"}),s.jsx("circle",{cx:"12",cy:"12",r:"2",stroke:"currentColor",strokeWidth:"1.5"}),s.jsx("circle",{cx:"19",cy:"12",r:"2",stroke:"currentColor",strokeWidth:"1.5"}),s.jsx("path",{d:"M7 12H10",stroke:"currentColor",strokeWidth:"1.5",strokeLinecap:"round"}),s.jsx("path",{d:"M14 12H17",stroke:"currentColor",strokeWidth:"1.5",strokeLinecap:"round"}),s.jsx("path",{d:"M5 10V6C5 4.89543 5.89543 4 7 4H17C18.1046 4 19 4.89543 19 6V10",stroke:"currentColor",strokeWidth:"1.5",strokeLinecap:"round"}),s.jsx("path",{d:"M5 14V18C5 19.1046 5.89543 20 7 20H17C18.1046 20 19 19.1046 19 18V14",stroke:"currentColor",strokeWidth:"1.5",strokeLinecap:"round"})]})}function uee(){const{t}=$(),e=t("home.services",{returnObjects:!0}),a={0:see,1:lee,2:cee,3:dee},n={0:"/imagenes/salesforce.png",1:"/imagenes/sap.png"};return s.jsxs("section",{id:"services",className:"relative bg-gradient-to-b from-slate-800/30 via-dark to-dark",children:[s.jsx("div",{className:"py-12 sm:py-16 md:py-20 px-4 sm:px-6 mt-9",children:s.jsxs("div",{className:"max-w-7xl mx-auto text-center",children:[s.jsxs(_.h2,{initial:{opacity:0,y:-20},whileInView:{opacity:1,y:0},viewport:{once:!0},transition:{duration:.6},className:"mt-10 text-3xl md:text-4xl font-extrabold text-white leading-tight uppercase tracking-tight",children:[t("nav.servicios"),s.jsx("div",{className:"h-2 w-20 bg-cyan-400 mt-2 mx-auto"})]}),s.jsx(_.p,{initial:{opacity:0,y:-20},whileInView:{opacity:1,y:0},viewport:{once:!0},transition:{duration:.6,delay:.2},className:"mt-5 text-center text-base sm:text-lg md:text-xl leading-relaxed text-white mb-8 sm:mb-10 md:mb-12 font-light max-w-5xl mx-auto px-4",children:t("servicios.servicesDescription")}),s.jsx("div",{className:"grid grid-cols-1 sm:grid-cols-2 lg:grid-cols-4 gap-6 pt-5",children:e.map((i,r)=>{const o=a[r],l=n[r];return s.jsx(_.div,{initial:{opacity:0,y:50},whileInView:{opacity:1,y:0},viewport:{once:!0},transition:{duration:.5,delay:r*.1},className:"group relative",children:s.jsx(Te,{to:"/servicios",children:s.jsxs("div",{className:"relative h-full p-6 sm:p-8 rounded-2xl bg-slate-900/50 backdrop-blur-sm border border-primary/20 hover:border-primary/50 transition-all duration-300 hover:shadow-xl hover:shadow-
3702primary/20 hover:-translate-y-2",children:[s.jsx("div",{className:"mb-6 text-primary",children:o&&s.jsx(o,{className:"w-12 h-12 sm:w-14 sm:h-14"})}),s.jsx("h3",{className:"text-xl sm:text-2xl font-bold mb-4 text-white group-hover:text-primary transition-colors",children:i.title}),s.jsx("p",{className:"text-gray-300 text-sm sm:text-base leading-relaxed mb-6",children:i.description}),l&&s.jsx("div",{className:"w-1/2 sm:w-2/5 lg:w-3/4 max-w-[100px] overflow-hidden rounded-xl border-white/10 shadow-lg",children:s.jsx("img",{src:l,alt:i.title,className:"w-full h-auto object-cover grayscale group-hover:grayscale-0 transition-all duration-500"})}),s.jsx("div",{className:"absolute inset-0 rounded-2xl bg-gradient-to-br from-primary/5 to-transparent opacity-0 group-hover:opacity-100 transition-opacity pointer-events-none"})]})})},r)})})]})}),s.jsx(ie,{color:"#0a0e27",variant:2})]})}function pee(){const{t}=$(),e=t("home.methodology",{returnObjects:!0}),[a,n]=k.useState(0);return k.useEffect(()=>{const i=setInterval(()=>{n(r=>(r+1)%e.steps.length)},3e3);return()=>clearInterval(i)},[e.steps.length]),s.jsxs("section",{className:"relative bg-gradient-to-b from-slate-800/30 via-dark to-dark",children:[s.jsx("div",{className:"py-20 px-4 mt-9",children:s.jsxs("div",{className:"max-w-6xl mx-auto text-center",children:[s.jsxs(_.h1,{id:"methodology-title",initial:{opacity:0,y:-20},whileInView:{opacity:1,y:0},viewport:{once:!0},transition:{duration:.6},className:"mt-10 text-3xl md:text-4xl font-extrabold text-white leading-tight uppercase tracking-tight",children:[e.title,s.jsx("div",{className:"h-2 w-20 bg-cyan-400 mt-2 mx-auto"})]}),s.jsx(_.p,{initial:{opacity:0}
3702,whileInView:{opacity:1},viewport:{once:!0},transition:{duration:.6,delay:.2},className:"text-center text-gray-300 text-lg mb-3 text-xl pt-10",children:e.subtitle}),s.jsx(_.p,{initial:{opacity:0},whileInView:{opacity:1},viewport:{once:!0},transition:{duration:.6,delay:.3},className:"text-center text-gray-400 mb-16 max-w-3xl mx-auto",children:e.description}),s.jsxs("div",{className:"relative",children:[s.jsx("div",{className:"absolute top-8 left-0 right-0 h-1 bg-gray-700",children:s.jsx(_.div,{className:"h-full bg-primary",initial:{width:"0%"},animate:{width:`${a/(e.steps.length-1)*100}%`},transition:{duration:.8,ease:"easeInOut"}})}),s.jsx(_.div,{className:"absolute top-4 w-8 h-8 bg-primary rounded-full shadow-lg shadow-primary/50 z-20",animate:{left:`${a/(e.steps.length-1)*100}%`,x:"-50%"},transition:{duration:.8,ease:"easeInOut"},children:s.jsx("div",{className:"absolute inset-0 rounded-full bg-primary animate-ping opacity-75"})}),s.jsx("div",{className:"relative grid grid-cols-2 md:grid-cols-4 gap-3 sm:gap-4 pt-20",children:e.steps.map((i,r)=>s.jsxs(_.div,{id:`methodology-step-${r+1}`,initial:{opacity:0,y:20},whileInView:{opacity:1,y:0},viewport:{once:!0},transition:{duration:.5,delay:r*.1},className:"flex flex-col items-center text-center",children:[s.jsxs(_.div,{animate:{rotate:a>=r?360:0,scale:a===r?1.2:1},transition:{duration:.6},className:"mb-3 sm:mb-4 relative",children:[s.jsx("div",{className:`absolute inset-0 rounded-full blur-lg transition-opacity duration-500 ${a>=r?"opacity-100":"opacity-0"}`,style:{background:"radial-gradient(circle, #06b6d4 0%, transparent 10%)",width:"100%",height:"100%"}}),s.jsx("svg",{className:`w-8 sm:w-10 md:w-12 h-8 sm:h-10 md:h-12 transition-all duration-500 relative z-10 ${a>=r?"text-cyan-400 drop-shadow-lg":"text-gray-600"}`,style:{filter:a>=r?"drop-shadow(0 0 8px #06b6d4) drop-shadow(0 0 16px rgba(6, 182, 212, 0.5))":"none",textShadow:a>=r?"0 0 10px #06b6d4":"none"},fill:"currentColor",viewBox:"0 0 20 20",children:s.jsx("path",{d:"M9.049 2.927c.3-.921 1.603-.921 1.902 0l1.07 3.292a1 1 0 00.95.69h3.462c.969 0 1.371 1.24.588 1.81l-2.8 2.034a1 1 0 00-.364 1.118l1.07 3.292c.3.921-.755 1.688-1.54 1.118l-2.8-2.034a1 1 0 00-1.175 0l-2.8 2.034c-.784.57-1.838-.197-1.539-1.118l1.07-3.292a1 1 0 00-.364-1.118L2.98 8.72c-.783-.57-.38-1.81.588-1.81h3.461a1 1 0 00.951-.69l1.07-3.292z"})})]}),s.jsxs(_.div,{animate:{opacity:a>=r?1:.5,scale:a===r?1.05:1},transition:{duration:.3},className:`p-3 sm:p-4 rounded-lg border transition-all ${a>=r?"border-primary/30 bg-primary/5":"border-gray-700 bg-gray-800/30"}`,children:[s.jsx("h3",{className:`font-bold mb-1 sm:mb-2 text-xs sm:text-sm lg:text-base ${a>=r?"text-primary":"text-gray-400"}`,children:i.title}),s.jsx("p",{className:"text-[10px] sm:text-xs lg:text-sm text-gray-400",children:i.description})]})]},`step-${r}`))})]}),s.jsx(_.p,{initial:{opacity:0}
3702,whileInView:{opacity:1},viewport:{once:!0},transition:{duration:.6,delay:.5},className:"text-center text-gray-300 mt-16 max-w-3xl mx-auto text-lg",children:e.bottomText})]})}),s.jsx(ie,{color:"#0a0e27",variant:3})]})}function mee(){var o,l,c,d,u,p,m,h,g,y,x,v,w,S,T,P;const{t}=$(),e=t("home.errorCost",{returnObjects:!0}),a=t("bugCostCycle",{returnObjects:!0}),n=[{icon:"⚠️",title:((o=e.risks)==null?void 0:o[0])||"Integraciones que fallan sin dejar rastro"},{icon:"⚠️",title:((l=e.risks)==null?void 0:l[1])||"Actualizaciones de Salesforce que rompen flujos críticos"},{icon:"⚠️",title:((c=e.risks)==null?void 0:c[2])||"Tiempos de certificación manual insostenibles"}],i=[{label:((u=(d=a.stages)==null?void 0:d[0])==null?void 0:u.label)||"Requirements",cost:"1x",color:"from-purple-600 to-purple-700"},{label:((m=(p=a.stages)==null?void 0:p[1])==null?void 0:m.label)||"Design/Architecture",cost:"3x",color:"from-purple-500 to-purple-600"},{label:((g=(h=a.stages)==null?void 0:h[2])==null?void 0:g.label)||"Coding",cost:"7x",color:"from-purple-500 to-purple-600"},{label:((x=(y=a.stages)==null?void 0:y[3])==null?void 0:x.label)||"Testing",cost:"15x",color:"from-orange-400 to-red-500"},{label:((w=(v=a.stages)==null?void 0:v[4])==null?void 0:w.label)||"Deployment/Maintenance",cost:"30x...100x",color:"from-red-500 to-orange-400"}],r=250;return s.jsxs("section",{className:"relative bg-dark pt-10 sm:pt-20 pb-10 px-4 mt-5 sm:mt-10",children:[s.jsx("div",{className:"max-w-6xl mx-auto mt-5 sm:mt-10",children:s.jsxs("div",{className:"grid grid-cols-1 lg:grid-cols-2 gap-8 sm:gap-12 lg:gap-20",children:[s.jsxs(_.div,{initial:{opacity:0,x:-30},whileInView:{opacity:1,x:0},viewport:{once:!0},transition:{duration:.6},className:"order-2 lg:order-1",children:[s.jsxs("h2",{id:"error-cost-title",className:"text-2xl sm:text-3xl lg:text-4xl font-bold mb-4 sm:mb-6 leading-tight pt-6",children:[s.jsx("span",{className:"text-white",children:((S=e.title)==null?void 0:S.before)||'"El costo de un error tras despliegue es '}),s.jsx("span",{className:"text-red-500",children:((T=e.title)==null?void 0:T.highlight)||"10 veces mayor"}),s.jsx("span",{className:"text-white",children:((P=e.title)==null?void 0:P.after)||' al de prevenirlo."'})]}),s.jsx("p",{className:"text-gray-300 mb-6 sm:mb-8 leading-relaxed text-sm sm:text-base",children:e.description||"Cada actualización de Salesforce sin certificar es un riesgo inaceptable para tu operación. Los errores silenciosos en integraciones y flujos destruyen la confianza del usuario y el ROI de tu inversión."}),s.jsx("div",{className:"space-y-2 sm:space-y-3",children:n.map((M,C)=>s.jsxs(_.div,{id:`error-cost-risk-${C+1}`,initial:{opacity:0,x:-20},whileInView:{opacity:1,x:0},viewport:{once:!0},transition:{duration:.5,delay:C*.1},className:"flex items-start gap-2 sm:gap-3 p-2 sm:p-4 rounded-lg border border-red-500/30 bg-red-500/5 hover:bg-red-500/10 transition-colors",children:[s.jsx("div",{className:"text-red-500 text-lg sm:text-xl flex-shrink-0 mt-0.5",children:s.jsx("svg",{className:"w-4 h-4 sm:w-5 sm:h-5",fill:"currentColor",viewBox:"0 0 20 20",children:s.jsx("path",{fillRule:"evenodd",d:"M8.257 3.099c.765-1.36 2.722-1.36 3.486 0l5.58 9.92c.75 1.334-.213 2.98-1.742 2.98H4.42c-1.53 0-2.493-1.646-1.743-2.98l5.58-9.92zM11 13a1 1 0 11-2 0 1 1 0 012 0zm-1-8a1 1 0 00-1 1v3a1 1 0 002 0V6a1 1 0 00-1-1z",clipRule:"evenodd"})})}),s.jsx("span",{className:"text-white font-medium text-xs sm:text-sm",children:M.title})]},C))})]}),s.jsxs(_.div,{initial:{opacity:0,x:30},whileInView:{opacity:1,x:0},viewport:{once:!0},transition:{duration:.6},className:"p-4 sm:p-8 rounded-lg from-primary/5 to-primary/10 order-1 lg:order-2",children:[s.jsx("h2",{className:"text-base sm:text-lg lg:text-lg mb-6 sm:mb-8 leading-tight pb-10 mt-5",children:a.subtitle}),s.jsxs("div",{id:"error-cost-chart",className:"grid grid-cols-5 gap-0.5 sm:gap-1 pt-5",children:[s.jsx("div",{className:"flex items-end justify-center gap-1 sm:gap-2 h-40 sm:h-50 mb-2 relative col-span-5",children:i.map((M,C)=>s.jsx(_.div,{initial:{height:0,opacity:0},whileInView:{height:`${(C+1)/i.length*r}px`,opacity:1},viewport:{once:!0},transition:{duration:.1,delay:C*.1},className:`flex-1 rounded-t-lg bg-gradient-to-t ${M.color} shadow-lg relative group cursor-pointer transition-all duration-300 hover:shadow-2xl hover:scale-115 hover:brightness-115`,whileHover:{y:-12},children:s.jsx("div",{className:"absolute top-1 left-1/2 transform -translate-x-1/2 text-white font-bold text-xs sm:text-md",children:M.cost})},C))}),i.map((M,C)=>s.jsx(_.div,{initial:{opacity:0,y:10},whileInView:{opacity:1,y:0},viewport:{once:!0},transition:{duration:.5,delay:C*.1},className:"text-center",children:s.jsx("p",{className:"text-gray-100 text-xs font-medium break-words",children:M.label})},`label-${C}`))]}),s.jsx("div",{className:"flex justify-center mb-4 sm:mb-6 mt-3 sm:mt-5",children:s.jsxs("div",{className:"w-full flex items-center gap-2",children:[s.jsx("div",{className:"flex-1 h-1 bg-gray-200"}),s.jsx("span",{className:"text-gray-200 text-xs whitespace-nowrap",children:a.ciclos})]})}),s.jsx("p",{className:"text-xs sm:text-sm text-gray-100 text-left",children:a.message})]})]})}),s.jsx(ie,{variant:1})]})}function hee(){const{t}=$(),e=t("home.testimonials",{returnObjects:!0}),[a,n]=k.useState(0);k.useEffect(()=>{const o=setInterval(()=>{n(l=>l===e.items.length-1?0:l+1)},5e3);return()=>clearInterval(o)},[e.items.length]);const i=()=>{n(o=>o===0?e.items.length-1:o-1)},r=()=>{n(o=>o===e.items.length-1?0:o+1)};return s.jsxs("section",{className:"relative bg-gradient-to-b from-slate-800/30 via-dark to-dark",children:[s.jsx("div",{className:"py-20 px-4",children:s.jsxs("div",{className:"max-w-6xl mx-auto text-center",children:[s.jsx(_.h2,{id:"testimonials-title",initial:{opacity:0,y:-20},whileInView:{opacity:1,y:0},viewport:{once:!0},transition:{duration:.6},className:"text-center text-2xl uppercase tracking-wider text-primary mb-3 whitespace-pre-line",children:e.title}),s.jsxs(_.h2,{initial:{opacity:0,y:-20},whileInView:{opacity:1,y:0},viewport:{once:!0},transition:{duration:1.2,delay:.1},className:"mt-5 text-3xl md:text-4xl font-extrabold text-white leading-tight uppercase tracking-tight",children:[e.subtitle,s.jsx("div",{className:"h-2 w-20 bg-cyan-400 mt-2 mx-auto"})]}),s.jsxs("div",{className:"relative mt-10 text-left",children:[s.jsxs(_.div,{id:"testimonials-card",initial:{opacity:0,x:100}
3702,animate:{opacity:1,x:0},exit:{opacity:0,x:-100},transition:{duration:.5},className:"relative bg-gradient-to-br from-slate-800/50 to-slate-900/30 backdrop-blur-sm border border-primary/30 rounded-2xl p-8 lg:p-12 shadow-2xl",children:[s.jsx("div",{className:"absolute top-6 left-6 text-primary/20 text-6xl font-serif",children:'"'}),s.jsxs("div",{className:"relative z-10 pt-8",children:[s.jsx("p",{className:"text-gray-200 text-lg lg:text-xl leading-relaxed mb-8 italic whitespace-pre-line",children:e.items[a].text}),s.jsxs("div",{className:"flex items-center gap-4",children:[s.jsx("img",{id:"testimonials-author-image",src:`/imagenes/testimonios/${e.items[a].author.split(" ")[0]}.jpeg`,alt:e.items[a].author,className:"w-12 h-12 rounded-full object-cover border-2 border-primary/40"}),s.jsxs("div",{children:[s.jsx("p",{className:"text-white font-semibold",children:e.items[a].author}),s.jsx("p",{className:"text-gray-400 text-sm",children:e.items[a].position}),s.jsx("p",{className:"text-primary text-sm",children:e.items[a].company})]})]})]}),s.jsx("div",{className:"absolute bottom-6 right-6 text-primary/10 text-6xl font-serif rotate-180",children:'"'})]},a),s.jsxs("div",{className:"flex justify-center items-center gap-4 mt-8",children:[s.jsx("button",{id:"testimonials-prev-button",onClick:i,className:"w-12 h-12 rounded-full border-2 border-primary/40 text-primary hover:bg-primary hover:text-dark transition-all duration-300 flex items-center justify-center","aria-label":"Anterior",children:s.jsx("svg",{className:"w-6 h-6",fill:"none",stroke:"currentColor",viewBox:"0 0 24 24",children:s.jsx("path",{strokeLinecap:"round",strokeLinejoin:"round",strokeWidth:2,d:"M15 19l-7-7 7-7"})})}),s.jsx("div",{className:"flex gap-2",children:e.items.map((o,l)=>s.jsx("button",{id:`testimonials-indicator-${l+1}`,onClick:()=>n(l),className:`h-2 rounded-full transition-all duration-300 ${l===a?"w-8 bg-primary":"w-2 bg-gray-600 hover:bg-gray-500"}`,"aria-label":`Ir al testimonio ${l+1}`},l))}),s.jsx("button",{id:"testimonials-next-button",onClick:r,className:"w-12 h-12 rounded-full border-2 border-primary/40 text-primary hover:bg-primary hover:text-dark transition-all duration-300 flex items-center justify-center","aria-label":"Siguiente",children:s.jsx("svg",{className:"w-6 h-6",fill:"none",stroke:"currentColor",viewBox:"0 0 24 24",children:s.jsx("path",{strokeLinecap:"round",strokeLinejoin:"round",strokeWidth:2,d:"M9 5l7 7-7 7"})})})]})]})]})}),s.jsx(ie,{color:"#0a0e27",variant:1})]})}function fee(){const{t}=$(),e=t("home.clients.title"),a=t("home.clients.description"),n={logos:[{id:1,name:"",image:"/imagenes/home/logo_abastible.png",alt:"Abastible"},{id:2,name:"",image:"/imagenes/home/logo_walmart.png",alt:"Walmart"},{id:3,name:"",image:"/imagenes/home/logo_cencosud.png",alt:"Cencosud"},{id:4,name:"Consorcio",image:"/imagenes/home/logo_falabella.png",alt:"Falabella"},{id:5,name:"",image:"/imagenes/home/logo_casaideas.png",alt:"Casa Ideas"},{id:6,name:"",image:"/imagenes/home/logo_wom.png",alt:"Wom"},{id:7,name:"",image:"/imagenes/home/log_bupa.png",alt:"Bupa"},{id:8,name:"",image:"/imagenes/home/logo_ikea.png",alt:"Ikea"},{id:9,name:"",image:"/imagenes/home/logo_colmena.png",alt:"Colmena"},{id:10,name:"",image:"/imagenes/home/logo_consorcio.png",alt:"Colmena"},{id:11,name:"",image:"/imagenes/home/logo_continuum.png",alt:"Continuum"},{id:12,name:"",image:"/imagenes/home/logo_melt.png",alt:"Melt"},{id:13,name:"",image:"/imagenes/home/logo_parque.png",alt:"Parque Arauco"},{id:14,name:"",image:"/imagenes/home/logo_scotiabank.png",alt:"Scotiabank"},{id:15,name:"",image:"/imagenes/home/logo_security.png",alt:"Security"},{id:16,name:"",image:"/imagenes/home/logo_spartan.png",alt:"Spartan"},{id:17,name:"",image:"/imagenes/home/logo_vida_security.png",alt:"Vida Security"}]},[i,r]=k.useState(0),o=4;k.useEffect(()=>{const c=setInterval(()=>{r(d=>{const u=d+o;return u>=n.logos.length?0:u})},3e3);return()=>clearInterval(c)},[n.logos.length]);const l=n.logos.slice(i,i+o);return s.jsxs("section",{className:"relative bg-gradient-to-b from-slate-800/30 via-dark to-dark overflow-hidden",children:[s.jsx("div",{className:"py-20 px-4 mt-9",children:s.jsxs("div",{className:"max-w-7xl mx-auto text-center mt-10",children:[s.jsxs(_.h1,{id:"clients-title",initial:{opacity:0,y:-20},whileInView:{opacity:1,y:0},viewport:{once:!0},transition:{duration:.6},className:"mt-5 text-3xl md:text-4xl font-extrabold text-white leading-tight uppercase tracking-tight",children:[e,s.jsx("div",{className:"h-2 w-20 bg-cyan-400 mt-2 mx-auto"})]}),s.jsxs("div",{id:"clients-carousel",className:"relative mt-10 pt-10",children:[s.jsx(La,{mode:"wait",children:s.jsx(_.div,{initial:{opacity:0}
3702,animate:{opacity:1},exit:{opacity:0},transition:{duration:.8,ease:"easeInOut"},className:"grid grid-cols-2 md:grid-cols-4 gap-8 lg:gap-12",children:l.map((c,d)=>s.jsx(_.div,{id:`clients-logo-${c.id}`,initial:{opacity:0,y:20,scale:.96},animate:{opacity:1,y:0,scale:1},transition:{type:"spring",stiffness:120,damping:22,delay:d*.1},whileHover:{scale:1.03},className:"flex items-center justify-center p-6 rounded-xl bg-slate-800/30 border border-primary/10 hover:border-primary/30 group",children:s.jsx("div",{className:"relative w-full h-20 flex items-center justify-center",children:s.jsx("img",{src:c.image,alt:c.alt,loading:"lazy",decoding:"async",width:"250",height:"150",className:"max-w-full max-h-full object-contain transition-all duration-300 opacity-90 group-hover:opacity-100 group-hover:scale-150"})})},c.id))},i)}),s.jsx("div",{className:"flex justify-center gap-2 mt-8",children:Array.from({length:Math.ceil(n.logos.length/o)}).map((c,d)=>s.jsx("button",{onClick:()=>r(d*o),className:`h-2 rounded-full transition-all duration-300 ${Math.floor(i/o)===d?"w-8 bg-primary":"w-2 bg-gray-600 hover:bg-gray-500"}`,"aria-label":`Ir al grupo ${d+1}`},d))})]}),s.jsx(_.p,{initial:{opacity:0}
3702,whileInView:{opacity:1},viewport:{once:!0},transition:{duration:.6,delay:.8},className:"text-center text-gray-200 mt-12 max-w-2xl mx-auto",children:a})]})}),s.jsx(ie,{color:"#0a0e27",variant:2})]})}const gee="https://calendar.app.google/dkJfuj7MNARbfT5HA";function yee(){const{t}=$(),e=t("partners",{returnObjects:!0}),a=t("badges",{returnObjects:!0}),n=()=>{window.open(gee,"_blank","width=1000,height=700")},i={logos:[{id:1,name:"XRAY Partner",image:"/imagenes/XrayPartner.webp",alt:"XRAY Partner - Haka Lab"}]};return s.jsxs("section",{className:"relative bg-gradient-to-b from-slate-800/30 via-dark to-darkpx-4",children:[s.jsxs("div",{className:"relative z-10 max-w-7xl mx-auto px-4 sm:px-6 md:px-8 pt-16 pb-16",children:[s.jsxs(_.h2,{initial:{opacity:0,y:20},whileInView:{opacity:1,y:0},viewport:{once:!0},transition:{duration:.6},className:"text-3xl md:text-4xl font-extrabold text-white text-center mb-2 uppercase tracking-tight",children:[s.jsx("span",{className:"text-primary",children:"ALIANZAS"})," ESTRATÉGICAS"]}),s.jsx("div",{className:"h-2 w-20 bg-cyan-400 mx-auto mb-10"}),s.jsxs("div",{className:"flex flex-wrap justify-center items-center gap-10 md:gap-16 mb-8",children:[s.jsx(_.img,{initial:{opacity:0,y:20},whileInView:{opacity:1,y:0},viewport:{once:!0},transition:{duration:.6,delay:.1},src:"/imagenes/logo chiletec.png",alt:"ChileTec",className:"h-20 md:h-28 object-contain"}),s.jsx(_.img,{initial:{opacity:0,y:20},whileInView:{opacity:1,y:0},viewport:{once:!0},transition:{duration:.6,delay:.2},src:"/imagenes/logo_ccs_2025.png",alt:"CCS 2025",className:"h-20 md:h-28 object-contain"})]}),s.jsx(_.p,{initial:{opacity:0,y:10},whileInView:{opacity:1,y:0},viewport:{once:!0},transition:{duration:.6,delay:.3},className:"text-center text-gray-300 text-lg max-w-3xl mx-auto leading-relaxed",children:"Formamos parte de las instituciones más relevantes del ecosistema empresarial y tecnológico de Chile, garantizando innovación y confianza en cada proyecto de QA"})]}),s.jsxs("div",{className:"relative py-12 sm:py-16 md:py-5 flex items-center justify-center overflow-hidden min-h-[400px] sm:min-h-[400px]",children:[s.jsx("div",{className:"absolute inset-0 bg-gradient-to-br from-dark via-dark to-dark"}),s.jsx("div",{className:"relative z-10 mt-6 sm:mt-8 md:mt-1 max-w-7xl mx-auto px-4 sm:px-6 md:px-8 w-full",children:s.jsxs("div",{className:"grid grid-cols-1 lg:grid-cols-2 gap-8 sm:gap-12 md:gap-16 items-center",children:[s.jsxs("div",{className:"flex flex-col justify-center text-center lg:text-left",children:[s.jsx(Lg,{text:a.partners}),s.jsx("h1",{id:"partners-title",className:"text-3xl md:text-4xl font-extrabold text-white leading-tight uppercase tracking-tight mt-4",itemProp:"headline",children:e.titulo}),s.jsx("h1",{id:"partners-title-2",class:"text-3xl md:text-6xl font-extrabold text-primary leading-tight uppercase tracking-tight",children:e.titulo2}),s.jsxs("h1",{id:"partners-title-3",class:"text-2xl md:text-2xl font-extrabold text-white leading-tight uppercase tracking-tight",children:[e.titulo3,s.jsx("div",{className:"h-2 w-20 bg-cyan-400 mt-2 mx-auto md:mx-0"})]}),s.jsx("p",{id:"partners-subtitle",className:"text-xl text-white font-normal max-w-lg leading-relaxed mt-10",itemProp:"description",children:e.subt
3702itulo}),s.jsx("div",{className:"flex flex-col sm:flex-row justify-center lg:justify-start gap-4 w-full sm:w-auto mt-10"})]}),s.jsx("div",{className:"flex justify-center items-center mt-0 lg:mt-0",children:s.jsx("div",{className:"flex flex-col md:flex-row items-right justify-center gap-8 sm:gap-10 md:gap-16 lg:gap-20",children:i.logos.map((r,o)=>s.jsx(_.div,{id:`partners-logo-${r.id}`,initial:{opacity:0,y:30},whileInView:{opacity:1,y:0},viewport:{once:!0},transition:{duration:.6,delay:o*.2},className:"w-full max-w-xs md:max-w-none md:w-auto flex items-center justify-center",children:s.jsx("div",{className:"relative w-full md:w-72 lg:w-80 h-48 sm:h-80 md:h-96 flex items-center justify-center p-6 transition-all duration-300 hover:scale-145 group",children:s.jsx("img",{src:r.image,alt:r.alt,loading:"lazy",decoding:"async",width:"324",height:"176",className:"max-w-full max-h-full object-contain filter brightness-90 group-hover:brightness-110 transition-all duration-300"})})},r.id))})})]})})]}),s.jsx("div",{className:"flex justify-center pb-16",children:s.jsx("button",{id:"partners-schedule-button",onClick:n,className:"bg-primary border-2 border-primary text-dark px-6 sm:px-8 md:px-10 py-3 sm:py-3 rounded-2xl text-base sm:text-lg font-semibold hover:bg-dark hover:text-primary transition-all duration-300","aria-label":"Agendar una cita",children:e.conversemos})}),s.jsx(ie,{color:"#0a0e27",variant:2})]})}const pj="https://hakalab.com";function Xa({title:t,description:e,path:a="/",image:n,type:i="website"}){const r=t?`${t} | HakaLab`:"HakaLab - Testing con IA, Automatización QA y Certificación Salesforce en Chile",o=`${pj}${a}`,l=n||`${pj}/imagenes/og-image.png`;return s.jsxs(gP,{children:[s.jsx("title",{children:r}),s.jsx("meta",{name:"description",content:e}),s.jsx("link",{rel:"canonical",href:o}),s.jsx("link",{rel:"alternate",hreflang:"es",href:o}),s.jsx("link",{rel:"alternate",hreflang:"x-default",href:o}),s.jsx("meta",{property:"og:type",content:i}),s.jsx("meta",{property:"og:url",content:o}),s.jsx("meta",{property:"og:title",content:r}),s.jsx("meta",{property:"og:description",content:e}),s.jsx("meta",{property:"og:image",content:l}),s.jsx("meta",{property:"og:locale",content:"es_CL"}),s.jsx("meta",{property:"og:site_name",content:"HakaLab"}),s.jsx("meta",{name:"twitter:card",content:"summary_large_image"}),s.jsx("meta",{name:"twitter:url",content:o}),s.jsx("meta",{name:"twitter:title",content:r}),s.jsx("meta",{name:"twitter:description",content:e}),s.jsx("meta",{name:"twitter:image",content:l}),s.jsx("meta",{name:"twitter:creator",content:"@hakalab"})]})}function xee(){return s.jsxs("div",{className:"bg-dark",children:[s.jsx(Xa,{title:"Testing con IA, Automatización QA y Certificación Salesforce en Chile",description:"HakaLab es líder en Chile en testing automatizado con inteligencia artificial. Acelera tu ciclo de pruebas hasta un 70% con herramientas de IA para QA.",path:"/"}),s.jsx(oee,{}),s.jsx(mee,{}),s.jsx(uee,{}),s.jsx(pee,{}),s.jsx(hee,{}),s.jsx(fee,{}),s.jsx(yee,{})]})}function vee(){const{isOpen:t,modalTitle:e,openModal:a,closeModal:n}=oa(),{t:i}=$();return s.jsxs(s.Fragment,{children:[s.jsxs("section",{className:"relative bg-dark pt-12",children:[s.jsx("div",{className:"hero-glow-head"}),s.jsxs("div",{className:"max-w-7xl mx-auto px-4 py-12 sm:py-16 md:py-20 text-center",children:[s.jsx("h1",{id:"servicios-hero-title",className:"text-5xl md:text-7xl font-extrabold tracking-tight text-white",itemProp:"headline",children:i("servicios.titulo")}),s.jsx("div",{className:"h-2 w-32 bg-cyan-400 mt-2 mx-auto"}),s.jsx("p",{className:"mt-5 text-center text-md sm:text-base lg:text-lg text-gray-200 mb-8 sm:mb-10 md:mb-12 leading-relaxed font-light max-w-4xl mx-auto",children:i("servicios.descripcion")}),s.jsx("div",{className:"flex justify-center",children:s.jsx("button",{id:"servicios-contacto-button",onClick:()=>a(i("contactModal.title")),className:"border-2 border-primary text-primary px-6 sm:px-8 md:px-8 py-2 sm:py-3 rounded-2xl text-base sm:text-lg font-semibold hover:bg-primary hover:text-dark transition-all","aria-label":i("servicios.contactanos"),children:i("servicios.contactanos")})})]}),s.jsx(ie,{variant:1})]}),s.jsx(Yr,{isOpen:t,onClose:n,title:e})]})}function bee(){const{t}=$(),e=t("servicios.performance",{returnObjects:!0});return s.jsx("section",{id:"home",className:"relative bg-gradient-to-b from-slate-800/30 via-dark to-dark overflow-x-hidden",itemScope:!0,itemType:"https://schema.org/WebPageElement",children:s.jsx("div",{className:"relative py-16 sm:py-16 md:py-20 flex items-center justify-center overflow-hidden",children:s.jsx("div",{className:"relative z-10 mt-6 sm:mt-8 md:mt-10 max-w-7xl mx-auto px-4 sm:px-6 md:px-8 w-full",children:s.jsxs("div",{className:"grid grid-cols-1 lg:grid-cols-2 gap-8 sm:gap-12 md:gap-16 items-center",children:[s.jsx("div",{className:"flex justify-center items-center mt-8 lg:mt-0 lg:text-left",children:s.jsx("img",{src:"/imagenes/performance.png",alt:"Equipo HakaLab - Soluciones tecnológicas innovadoras",className:"w-1/2 sm:w-full max-w-[200px] sm:max-w-md lg:max-w-lg h-auto drop-shadow-2xl object-contain",loading:"eager",fetchpriority:"high",decoding:"async",width:"512",height:"512",itemProp:"image"})}),s.jsxs("div",{className:"flex flex-col justify-center text-center lg:text-left",children:[s.jsx("h2",{id:"servicios-performance-title",className:"mt-5 text-3xl md:text-4xl font-extrabold text-white leading-tight uppercase tracking-tight",itemProp:"headline",children:e.title}),s.jsx("div",{className:"h-2 w-24 md:w-32 bg-cyan-400 mt-4 mx-auto lg:ml-0 lg:mr-0"}),s.jsx("p",{className:"text-md sm:text-base lg:text-lg text-gray-100 mb-6 sm:mb-8 leading-relaxed font-light mt-5",itemProp:"description",children:e.subt
3702itle}),s.jsx("div",{className:"mb-8 sm:mb-10 space-y-4",children:e.features.map((a,n)=>s.jsxs(_.div,{initial:{opacity:0,x:-20},whileInView:{opacity:1,x:0},viewport:{once:!0},transition:{duration:.5,delay:n*.1},className:"flex items-start gap-3",children:[s.jsx("svg",{className:"w-6 h-6 text-primary flex-shrink-0 mt-0.5",fill:"none",stroke:"currentColor",viewBox:"0 0 24 24",children:s.jsx("path",{strokeLinecap:"round",strokeLinejoin:"round",strokeWidth:2,d:"M5 13l4 4L19 7"})}),s.jsx("span",{className:"text-sm sm:text-base text-gray-200 leading-relaxed text-left",children:a})]},n))})]})]})})})})}const Wh=360/7,Gh=-90,mj=[{label:"Planificación",color:"#1e3a8a"},{label:"Diseño",color:"#1e40af"},{label:"Desarrollo",color:"#0369a1"},{label:"Testing",color:"#0891b2"},{label:"Despliegue",color:"#0e7490"},{label:"Revisión",color:"#155e75"},{label:"Lanzamiento",color:"#164e63"}].map((t,e)=>({...t,startAngle:Gh+Wh*e,endAngle:Gh+Wh*(e+1)})),_s=[{id:0,label:"Análisis de requerimientos",color:"#059669",inactiveColor:"#1e3a8a"},{id:1,label:"Diseño pruebas",color:"#0d9488",inactiveColor:"#1e40af"},{id:2,label:"Construcción",color:"#06b6d4",inactiveColor:"#2563eb"},{id:3,label:"Ejecución",color:"#0284c7",inactiveColor:"#3b82f6"},{id:4,label:"CI/CD",color:"#7c3aed",inactiveColor:"#1d4ed8"},{id:5,label:"Resultados",color:"#db2777",inactiveColor:"#0369a1"},{id:6,label:"Métricas Productivas",color:"#f59e0b",inactiveColor:"#0284c7"}].map((t,e)=>({...t,startAngle:Gh+Wh*e,endAngle:Gh+Wh*(e+1)}));function Pr(t){return t*Math.PI/180}function z0(t,e,a,n,i,r,o,l,c,d=!1,u=null){const p=Pr(r),m=Pr(o),g=i+(c&&d?8:0),y=n-(c&&d?2:0);t.save(),t.beginPath(),t.arc(e,a,g,p,m),t.arc(e,a,y,m,p,!0),t.closePath(),c&&d?t.fillStyle="#06b6d4":c&&!d?(t.fillStyle=l,t.globalAlpha=1):d&&u?(t.fillStyle=u,t.globalAlpha=.5):d?t.fillStyle=l:(t.fillStyle=l,t.globalAlpha=.3),t.fill(),t.restore()}function wee(t,e,a,n,i,r,o){const c=i+8,d=n-2,u=Pr(r),p=Pr(o),m=(d+c)/2,g=(c-d)*.9/m,y=Pr(o),x=y+g,v=Math.cos(x)*m+e,w=Math.sin(x)*m+a,S=Math.cos(y)*(c-1)+e,T=Math.sin(y)*(c-1)+a,P=Math.cos(y)*(d+1)+e,M=Math.sin(y)*(d+1)+a;t.save(),t.beginPath(),t.arc(e,a,c,u,p),t.lineTo(S,T),t.lineTo(v,w),t.lineTo(P,M),t.arc(e,a,d,p,u,!0),t.closePath(),t.strokeStyle="#22d3ee",t.lineWidth=2,t.shadowColor="#22d3ee",t.shadowBlur=20,t.stroke(),t.restore()}function kee(t,e,a,n,i,r,o,l,c){const d=Pr((r+o)/2),u=(n+i)/2,p=Math.cos(d)*u+e,m=Math.sin(d)*u+a;t.save(),t.translate(p,m),t.fillStyle="white",t.font=`${c}px sans-serif`,t.textAlign="center",t.textBaseline="middle",t.fillText(l,0,0),t.restore()}function hj(t,e,a,n,i,r,o,l,c=!1,d=null){const p=i+8,m=n-2,h=(m+p)/2,y=(p-m)*.9/h,x=Pr(r),v=x+y,w=Math.cos(v)*h+e,S=Math.sin(v)*h+a,T=Math.cos(x)*(p-1)+e,P=Math.sin(x)*(p-1)+a,M=Math.cos(x)*(m+1)+e,C=Math.sin(x)*(m+1)+a;t.save(),t.beginPath(),t.moveTo(w,S),t.lineTo(T,P),t.lineTo(M,C),t.closePath(),t.fillStyle="#06b6d4",t.fill(),t.restore()}function See(t,e,a,n,i,r,o){const l=Pr(i),c=n+35,d=Math.cos(l)*c+e,u=Math.sin(l)*c+a;t.save(),t.font=`${o?"bold ":""}14px sans-serif`,t.textAlign="center",t.textBaseline="middle";const h=t.measureText(r).width+14*2,g=28;o?(t.fillStyle="#0f172a",t.strokeStyle="#06b6d4",t.lineWidth=2):(t.fillStyle="rgba(15,23,42,0.6)",t.strokeStyle="rgba(148,163,184,0.3)",t.lineWidth=1);const y=g/2;t.beginPath(),t.moveTo(d-h/2+y,u-g/2),t.lineTo(d+h/2-y,u-g/2),t.arc(d+h/2-y,u,y,-Math.PI/2,Math.PI/2),t.lineTo(d-h/2+y,u+g/2),t.arc(d-h/2+y,u,y,Math.PI/2,-Math.PI/2),t.closePath(),t.fill(),t.stroke(),t.fillStyle=o?"#06b6d4":"#cbd5e1",t.fillText(r,d,u),t.restore()}function Og({showIntro:t=!0,light:e=!1}={}){const{t:a}=$(),n=a("servicios.agileCycle",{returnObjects:!0}),i=k.useRef(null),[r,o]=k.useState(0),[l,c]=k.useState(!0),d=n.devStages||[],u=n.qaStages||[],p=n.centerText||{line1:"",line2:""};k.useEffect(()=>{if(!l)return;const y=setInterval(()=>o(x=>(x+1)%_s.length),4e3);return()=>clearInterval(y)},[l]);const m=y=>{c(!1),o(y),setTimeout(()=>c(!0),8e3)},h=k.useCallback(()=>{const y=i.current;if(!y)return;const x=y.getContext("2d"),v=y.width,w=y.height,S=v/2,T=w/2,P=v*.34,M=v*.245,C=v*.225,E=v*.15;
3702x.clearRect(0,0,v,w),_s.forEach(N=>{z0(x,S,T,M,P,N.startAngle,N.endAngle,N.color,N.id===r,!0,N.inactiveColor)});const j=_s[r];hj(x,S,T,M,P,j.endAngle,j.color,!0,!0,j.inactiveColor),z0(x,S,T,M,P,j.startAngle,j.endAngle,j.color,!0,!0,j.inactiveColor),hj(x,S,T,M,P,j.endAngle,j.color,!0,!0,j.inactiveColor),wee(x,S,T,M,P,j.startAngle,j.endAngle),x.save(),x.beginPath(),x.arc(S,T,M-1,0,Math.PI*2),x.fillStyle="transparent",x.fill(),x.restore(),mj.forEach((N,L)=>{const O=L===r;z0(x,S,T,E,C,N.startAngle,N.endAngle,N.color,O,!1)}),mj.forEach((N,L)=>{const O=d[L]||N.label;kee(x,S,T,E,C,N.startAngle,N.endAngle,O,v*.018)}),x.save(),x.beginPath(),x.arc(S,T,E-1,0,Math.PI*2),x.fillStyle="transparent",x.fill(),x.restore(),x.save(),x.fillStyle="#94a3b8",x.font=`${v*.022}px sans-serif`,x.textAlign="center",x.textBaseline="middle",x.fillText(p.line1,S,T-v*.03),x.fillText(p.line2,S,T+v*.01),x.restore(),_s.forEach((N,L)=>{var G;const O=(N.startAngle+N.endAngle)/2,R=((G=u[L])==null?void 0:G.label)||N.label;See(x,S,T,P,O,R,N.id===r)})},[r,d,u,p]);k.useEffect(()=>{h()},[h]);const g=y=>{const x=i.current;if(!x)return;const v=x.getBoundingClientRect(),w=x.width/v.width,S=x.height/v.height,T=(y.clientX-v.left)*w,P=(y.clientY-v.top)*S,M=x.width/2,C=x.height/2,E=x.width,j=E*.34,N=E*.245,L=T-M,O=P-C,R=Math.sqrt(L*L+O*O);if(R<N||R>j)return;let G=Math.atan2(O,L)*180/Math.PI;G<0&&(G+=360),_s.forEach(ee=>{let ke=(ee.startAngle%360+360)%360,ae=(ee.endAngle%360+360)%360;(ke<ae?G>=ke&&G<=ae:G>=ke||G<=ae)&&m(ee.id)})};return s.jsxs("div",{className:"relative w-full max-w-7xl mx-auto py-8",children:[t&&s.jsx("div",{className:"text-center mb-8 max-w-4xl mx-auto",children:s.jsx("p",{className:"text-gray-100 text-lg leading-relaxed",children:n.introText})}),s.jsxs("div",{className:"grid grid-cols-1 lg:grid-cols-5 gap-8 items-center",children:[s.jsxs("div",{className:"lg:col-span-3 relative w-full aspect-square mx-auto",children:[s.jsx("p",{className:"text-gray-300 text-sm text-center leading-relaxed -mb-20",children:"Ciclo de vida de calidad del software"}),s.jsx("canvas",{ref:i,width:900,height:900,className:"w-full h-full cursor-pointer",onClick:g})]}),s.jsx("div",{className:"lg:col-span-2 flex flex-col justify-center h-full",children:s.jsxs("div",{className:"space-y-5",children:[s.jsx(La,{mode:"wait",children:s.jsxs(_.div,{initial:{opacity:0,x:30},animate:{opacity:1,x:0},exit:{opacity:0,x:-30},transition:{duration:.3},className:"bg-white/5 backdrop-blur rounded-2xl p-7 border border-cyan-400/40 shadow-xl",children:[s.jsxs("div",{className:"flex items-center gap-4 mb-4",children:[s.jsx("div",{className:"bg-gradient-to-br from-cyan-400 to-blue-600 text-white font-bold text-lg w-11 h-11 rounded-full flex items-center justify-center flex-shrink-0",children:String(r+1).padStart(2,"0")}),s.jsx("h3",{className:"text-lg font-bold text-white leading-tight",children:u[r].fullName})]}),s.jsx("p",{className:"text-gray-300 text-sm leading-relaxed mb-6",children:u[r].description}),(r===0||r===1)&&s.jsx("div",{className:"flex justify-center pt-4 border-t border-white/10",children:s.jsx("img",{src:"/imagenes/productos/hakaboost_logo.png",alt:"Hakaboost",className:"h-8 opacity-70"})}),r===2&&s.jsxs("div",{className:"flex flex-col items-center gap-4 pt-4 border-t border-white/10",children:[s.jsx("img",{src:"/imagenes/productos/logo Automation Engine.png",alt:"Haka Automation Engine",className:"h-10 sm:h-12 opacity-80"}),s.jsx("img",{src:"/imagenes/productos/hakabuddy_logo2.png",alt:"Hakabuddy",className:"h-8 sm:h-10 opacity-70"}),s.jsx("img",{src:"/imagenes/productos/hakapath_logo.png",alt:"Hakapath",className:"h-8 sm:h-10 opacity-70"}),s.jsx("img",{src:"/imagenes/productos/haka_mobile_recorder_logo.png",alt:"Haka Mobile Recorder",className:"h-16 sm:h-20 opacity-80"})]}),r===3&&s.jsxs("div",{className:"flex flex-col items-center gap-4 pt-4 border-t border-white/10",children:[s.jsx("img",{src:"/imagenes/productos/logo Automation Engine.png",alt:"Haka Automation Engine",className:"h-10 sm:h-12 opacity-80"}),s.jsx("img",{src:"/imagenes/productos/hakabuddy_logo2.png",alt:"Hakabuddy",className:"h-8 sm:h-10 opacity-70"}),s.jsx("img",{src:"/imagenes/productos/haka_mobile_recorder_logo.png",alt:"Haka Mobile Recorder",className:"h-16 sm:h-20 opacity-80"})]}
3702),r===4&&s.jsxs("div",{className:"flex flex-col items-center gap-4 pt-4 border-t border-white/10",children:[s.jsx("img",{src:"/imagenes/productos/logo Automation Engine.png",alt:"Haka Automation Engine",className:"h-10 sm:h-12 opacity-80"}),s.jsx("img",{src:"/imagenes/productos/hakabuddy_logo2.png",alt:"Hakabuddy",className:"h-8 sm:h-10 opacity-70"})]}),r===5&&s.jsxs("div",{className:"flex flex-col items-center gap-4 pt-4 border-t border-white/10",children:[s.jsx("img",{src:"/imagenes/productos/logo Automation Engine.png",alt:"Haka Automation Engine",className:"h-10 sm:h-12 opacity-80"}),s.jsx("img",{src:"/imagenes/productos/hakabuddy_logo2.png",alt:"Hakabuddy",className:"h-8 sm:h-10 opacity-70"}),s.jsx("img",{src:"/imagenes/productos/cassini_logo.png",alt:"Cassini",className:"h-14 sm:h-16 opacity-70"}),s.jsx("img",{src:"/imagenes/productos/haka_mobile_recorder_logo.png",alt:"Haka Mobile Recorder",className:"h-16 sm:h-20 opacity-80"})]})]},r)}),s.jsx("div",{className:"flex gap-2 items-center",children:_s.map(y=>s.jsx("button",{onClick:()=>m(y.id),className:`h-2 rounded-full transition-all duration-300 ${r===y.id?"bg-cyan-400 w-8":"bg-gray-600 hover:bg-gray-400 w-3"}`},y.id))})]})})]})]})}function _ee(){const{t}=$(),e=t("servicios.continuos",{returnObjects:!0}),a=t("servicios.services",{returnObjects:!0}),n=k.useRef(null),{scrollYProgress:i}=zU({target:n,offset:["start end","end start"]}),r=IR(i,[.2,.8],["0%","100%"]);return s.jsxs("section",{ref:n,className:"relative bg-gradient-to-b from-slate-800/30 via-dark to-dark overflow-x-clip",children:[s.jsx("div",{className:"relative py-16 sm:py-20 md:py-24 mt-10",children:s.jsxs("div",{className:"relative z-10 max-w-7xl mx-auto px-4 sm:px-6 md:px-8 w-full text-center",children:[s.jsx("h1",{id:"servicios-continuos-title",className:"mt-1 text-3xl md:text-4xl font-extrabold text-white leading-tight uppercase tracking-tight",children:e.title}),s.jsx("div",{className:"h-2 w-32 bg-cyan-400 mt-2 mx-auto"}),s.jsx("p",{className:"mt-6 text-center text-md sm:text-base lg:text-xl text-gray-200 mb-2 sm:mb-2 leading-relaxed font-light",children:e.subt
3702itle}),s.jsx("div",{className:"mb-16 sm:mb-20",children:s.jsx(Og,{})}),s.jsxs("div",{className:"grid grid-cols-1 lg:grid-cols-12 gap-8 lg:gap-12 text-left",children:[s.jsx("div",{className:"lg:col-span-7 space-y-8",children:a.map((o,l)=>s.jsxs(_.div,{id:`servicios-continuos-card-${l+1}`,initial:{opacity:0,x:-50},whileInView:{opacity:1,x:0},viewport:{once:!0,margin:"-100px"},transition:{duration:.6,delay:l*.2},className:"p-6 sm:p-8 rounded-lg bg-primary/10 border border-primary/20 hover:border-primary/50 transition-all hover:shadow-lg hover:shadow-primary/25",children:[s.jsx("h3",{className:"text-xl sm:text-2xl mb-3 text-primary leading-snug",children:o.title}),s.jsx("p",{className:"text-gray-200 text-sm sm:text-base mb-6 leading-relaxed",children:o.description}),l===0?s.jsxs("a",{href:"/salesforce-testing",className:"inline-flex items-center gap-2 px-6 py-3 bg-cyan-400 hover:bg-cyan-500 text-dark font-semibold rounded-lg transition-all duration-300 hover:shadow-lg hover:shadow-cyan-400/50",children:["Conocer más del servicio",s.jsx("svg",{className:"w-5 h-5",fill:"none",stroke:"currentColor",viewBox:"0 0 24 24",children:s.jsx("path",{strokeLinecap:"round",strokeLinejoin:"round",strokeWidth:2,d:"M17 8l4 4m0 0l-4 4m4-4H3"})})]}):o.features&&s.jsx("div",{className:"space-y-3",children:o.features.map((c,d)=>s.jsxs(_.div,{initial:{opacity:0,x:-20},whileInView:{opacity:1,x:0},viewport:{once:!0},transition:{duration:.5,delay:d*.1},className:"flex items-start gap-3",children:[s.jsx("svg",{className:"w-5 h-5 text-primary flex-shrink-0 mt-0.5",fill:"none",stroke:"currentColor",viewBox:"0 0 24 24",children:s.jsx("path",{strokeLinecap:"round",strokeLinejoin:"round",strokeWidth:2,d:"M5 13l4 4L19 7"})}),s.jsx("span",{className:"text-sm text-gray-200 leading-relaxed",children:c})]},d))})]},o.id))}),s.jsx("div",{className:"hidden lg:block lg:col-span-5 relative",children:s.jsxs("div",{className:"sticky top-24 h-fit",children:[s.jsx("div",{className:"absolute left-8 top-0 w-1 h-full bg-primary/20 rounded-full"}),s.jsx(_.div,{className:"absolute left-8 top-0 w-1 bg-primary rounded-full origin-top",style:{height:r}}),s.jsx("div",{className:"space-y-32 pl-20",children:a.map((o,l)=>s.jsxs(_.div,{initial:{opacity:0,x:20},whileInView:{opacity:1,x:0},viewport:{once:!0,margin:"-150px"},transition:{duration:.6,delay:.3},className:"relative",children:[s.jsx(_.div,{initial:{scale:0},whileInView:{scale:1},viewport:{once:!0,margin:"-150px"},transition:{duration:.4,delay:.2},className:"absolute -left-[52px] top-2 w-6 h-6 rounded-full bg-primary border-4 border-dark shadow-lg shadow-primary/50"}),s.jsxs("div",{className:"bg-gradient-to-br from-primary/20 to-primary/5 border border-primary/30 rounded-lg p-6 backdrop-blur-sm",children:[s.jsxs("div",{className:"flex items-start gap-3 mb-3",children:[s.jsx("svg",{className:"w-6 h-6 text-primary flex-shrink-0 mt-1",fill:"none",stroke:"currentColor",viewBox:"0 0 24 24",children:s.jsx("path",{strokeLinecap:"round",strokeLinejoin:"round",strokeWidth:2,d:"M13 10V3L4 14h7v7l9-11h-7z"})}),s.jsx("h4",{className:"text-lg font-semibold text-primary",children:"Beneficio Clave"})]}),s.jsx("p",{className:"text-gray-200 text-sm leading-relaxed",children:o.benefit})]})]},o.id))})]})})]})]})}),s.jsx(ie,{color:"#0a0d29f5",variant:2})]})}function Aee(){const{t}=$(),e=t("servicios.data",{returnObjects:!0});return s.jsxs("section",{id:"home",className:"relative bg-gradient-to-b from-slate-800/30 via-dark to-dark overflow-x-clip",itemScope:!0,itemType:"https://schema.org/WebPageElement",children:[s.jsx("div",{className:"relative py-16 sm:py-16 md:py-20 flex items-center justify-center overflow-hidden",children:s.jsx("div",{className:"relative z-10 mt-6 sm:mt-8 md:mt-10 max-w-7xl mx-auto px-4 sm:px-6 md:px-8 w-full",children:s.jsxs("div",{className:"grid grid-cols-1 lg:grid-cols-2 gap-8 sm:gap-12 md:gap-16 items-center",children:[s.jsx("div",{className:"flex justify-center items-center mt-8 lg:mt-0 lg:text-left",children:s.jsx("img",{src:"/imagenes/datatesting.png",alt:"Equipo HakaLab - Soluciones tecnológicas innovadoras",className:"w-1/2 sm:w-full max-w-[200px] sm:max-w-md lg:max-w-lg h-auto drop-shadow-2xl object-contain",loading:"eager",fetchpriority:"high",decoding:"async",width:"512",height:"512",itemProp:"image"})}),s.jsxs("div",{className:"flex flex-col justify-center text-center lg:text-left",children:[s.jsx("h2",{id:"servicios-data-title",className:"mt-1 text-3xl md:text-4xl font-extrabold text-white leading-tight uppercase tracking-tight",itemProp:"headline",children:e.title}),s.jsx("div",{className:"h-2 w-24 md:w-32 bg-cyan-400 mt-4 mx-auto lg:ml-0 lg:mr-0"}),s.jsx("p",{className:"text-sm sm:text-base lg:text-lg text-gray-200 mb-6 sm:mb-8 leading-relaxed font-light mt-5",itemProp:"description",children:e.subt
3702itle}),s.jsx("div",{className:"mb-8 sm:mb-10 space-y-4",children:e.features.map((a,n)=>s.jsxs(_.div,{initial:{opacity:0,x:-20},whileInView:{opacity:1,x:0},viewport:{once:!0},transition:{duration:.5,delay:n*.1},className:"flex items-start gap-3",children:[s.jsx("svg",{className:"w-6 h-6 text-primary flex-shrink-0 mt-0.5",fill:"none",stroke:"currentColor",viewBox:"0 0 24 24",children:s.jsx("path",{strokeLinecap:"round",strokeLinejoin:"round",strokeWidth:2,d:"M5 13l4 4L19 7"})}),s.jsx("span",{className:"text-sm sm:text-base text-gray-200 leading-relaxed text-left",children:a})]},n))})]})]})})}),s.jsx(ie,{color:"#0a0e27",variant:2})]})}function Eee(){const{t}=$(),[e,a]=k.useState(null),n=t("faqServicios",{returnObjects:!0}),i=n.items||[],r=l=>{a(e===l?null:l)},o={"@context":"https://schema.org","@type":"FAQPage",mainEntity:i.map(l=>{var c;return{"@type":"Question",name:l.question,acceptedAnswer:{"@type":"Answer",text:`${l.answer} ${(c=l.details)==null?void 0:c.join(" ")}`}}})};return s.jsxs("section",{className:"bg-dark py-20 sm:py-24 md:py-28 px-4",children:[s.jsx(gP,{children:s.jsx("script",{type:"application/ld+json",children:JSON.stringify(o)})}),s.jsxs("div",{className:"max-w-4xl mx-auto",children:[s.jsxs(_.div,{initial:{opacity:0,y:20},whileInView:{opacity:1,y:0},viewport:{once:!0},transition:{duration:.6},className:"text-center mb-16",children:[s.jsx("h2",{className:"text-3xl sm:text-4xl font-bold text-white mb-5",children:n.titulo}),s.jsx("p",{className:"text-gray-400 text-lg max-w-2xl mx-auto leading-relaxed",children:n.subtitulo})]}),s.jsx("div",{className:"space-y-4",children:i.map((l,c)=>s.jsxs(_.div,{initial:{opacity:0,y:10},whileInView:{opacity:1,y:0},viewport:{once:!0},transition:{duration:.4,delay:c*.05},className:"bg-slate-800/50 border border-slate-700 rounded-xl overflow-hidden hover:border-slate-600 transition-colors",children:[s.jsxs("button",{onClick:()=>r(c),className:"w-full flex items-center justify-between p-6 text-left hover:bg-slate-700/20 transition-colors","aria-expanded":e===c,children:[s.jsx("span",{className:"text-white font-semibold text-base sm:text-lg pr-4 leading-snug",children:l.question}),s.jsx(_.span,{animate:{rotate:e===c?180:0},transition:{duration:.3},className:"text-primary flex-shrink-0",children:s.jsx("svg",{className:"w-5 h-5",fill:"none",viewBox:"0 0 24 24",stroke:"currentColor",children:s.jsx("path",{strokeLinecap:"round",strokeLinejoin:"round",strokeWidth:2,d:"M19 9l-7 7-7-7"})})})]}),s.jsx(La,{children:e===c&&s.jsx(_.div,{initial:{height:0,opacity:0},animate:{height:"auto",opacity:1},exit:{height:0,opacity:0},transition:{duration:.3},className:"overflow-hidden",children:s.jsxs("div",{className:"px-6 pb-6 pt-2 space-y-4 border-t border-slate-700/50",children:[s.jsx("p",{className:"text-gray-200 text-base leading-relaxed font-medium",children:l.answer}),l.details&&l.details.length>0&&s.jsx("ul",{className:"space-y-3 pl-1",children:l.details.map((d,u)=>s.jsxs("li",{className:"flex items-start gap-3",children:[s.jsx("span",{className:"text-primary mt-1.5 flex-shrink-0",children:s.jsx("svg",{className:"w-4 h-4",fill:"currentColor",viewBox:"0 0 20 20",children:s.jsx("path",{fillRule:"evenodd",d:"M16.707 5.293a1 1 0 010 1.414l-8 8a1 1 0 01-1.414 0l-4-4a1 1 0 011.414-1.414L8 12.586l7.293-7.293a1 1 0 011.414 0z",clipRule:"evenodd"})})}),s.jsx("span",{className:"text-gray-300 text-sm leading-relaxed",children:d})]},u))}),l.highlight&&s.jsx("div",{className:"pt-2",children:s.jsxs("span",{className:"inline-flex items-center gap-2 px-4 py-2 bg-primary/10 border border-primary/30 rounded-full text-primary text-sm font-semibold",children:[s.jsx("svg",{className:"w-4 h-4",fill:"currentColor",viewBox:"0 0 20 20",children:s.jsx("path",{fillRule:"evenodd",d:"M11.3 1.046A1 1 0 0112 2v5h4a1 1 0 01.82 1.573l-7 10A1 1 0 018 18v-5H4a1 1 0 01-.82-1.573l7-10a1 1 0 011.12-.38z",clipRule:"evenodd"})}),l.highlight]})})]})})})]},c))})]})]})}function Cee(){return s.jsxs("div",{className:"bg-dark",children:[s.jsx(Xa,{title:"Servicios de Testing Automatizado y QA en Chile",description:"Empresa líder en Quality Assurance (QA) en Chile. Testing automatizado, performance testing, certificación Salesforce y SAP, consultoría QA. Más de 10 años de experiencia con empresas Fortune 500.",path:"/servicios"}),s.jsx(vee,{}),s.jsx(_ee,{}),s.jsx(bee,{}),s.jsx(Aee,{}),s.jsx(Eee,{})]})}function jee(){const{t}=$(),e=t("nosotros.hero",{returnObjects:!0}),{isOpen:a,modalTitle:n,openModal:i,closeModal:r}=oa();return s.jsxs(s.Fragment,{children:[s.jsxs("section",{id:"home",className:"relative bg-dark",
3702itemScope:!0,itemType:"https://schema.org/WebPageElement",children:[s.jsxs("div",{className:"relative py-12 sm:py-16 md:py-5 flex items-center justify-center overflow-hidden min-h-[400px] sm:min-h-[400px]",children:[s.jsx("div",{className:"absolute inset-0 bg-gradient-to-br from-dark via-dark to-dark"}),s.jsx("div",{className:"hero-glow-head"}),s.jsx("div",{className:"relative z-10 mt-6 sm:mt-8 md:mt-10 max-w-7xl mx-auto px-4 sm:px-6 md:px-8 w-full",children:s.jsxs("div",{className:"grid grid-cols-1 lg:grid-cols-2 gap-8 sm:gap-12 md:gap-16 items-center",children:[s.jsxs("div",{className:"flex flex-col justify-center text-center lg:text-left",children:[s.jsx("h1",{className:"text-5xl md:text-7xl font-extrabold tracking-tight text-white",itemProp:"headline",children:e.title}),s.jsx("div",{className:"h-2 w-24 md:w-32 bg-cyan-400 mt-4 mx-auto lg:ml-0 lg:mr-0"}),s.jsx("p",{className:"mt-10 text-sm sm:text-base lg:text-lg text-gray-200 mb-8 sm:mb-10 md:mb-12 leading-relaxed font-light",itemProp:"description",children:e.subtitle}),s.jsx("div",{className:"flex justify-center lg:justify-start",children:s.jsx("button",{onClick:()=>i(t("contactModal.title")),className:"border-2 border-primary text-primary px-6 sm:px-8 md:px-8 py-2 sm:py-3 rounded-2xl text-base sm:text-lg font-semibold hover:bg-primary hover:text-dark transition-all","aria-label":t("nav.contacto"),children:e.cta})})]}),s.jsx("div",{className:"flex justify-center items-center mt-2 lg:mt-0",children:s.jsx("img",{src:"/imagenes/animado.gif",alt:t("common.altEquipoHakalab"),className:"w-1/2 sm:w-full max-w-[300px] sm:max-w-md lg:max-w-lg h-auto drop-shadow-2xl object-contain",loading:"eager",fetchpriority:"high",decoding:"async",width:"512",height:"512",itemProp:"image"})})]})})]}),s.jsxs("div",{className:"max-w-7xl mx-auto px-4 py-12 sm:py-10 md:py-10",children:[s.jsx("p",{className:"text-center text-md sm:text-base lg:text-xl text-gray-200 mb-5 sm:mb-5 md:mb-5 leading-relaxed font-light max-w-6xl mx-auto",children:t("nosotros.identidad.intro")}),s.jsx("p",{className:"text-center text-md sm:text-base lg:text-xl text-gray-200 mb-5 sm:mb-5 md:mb-5 leading-relaxed font-light max-w-6xl mx-auto",children:t("nosotros.koru.descripcion")}),s.jsx("p",{className:"text-center text-md sm:text-base lg:text-xl text-gray-200 mb-5 sm:mb-5 md:mb-5 leading-relaxed font-light max-w-6xl mx-auto",children:t("nosotros.kai.descripcion")}),s.jsx("p",{className:"text-center text-md sm:text-base lg:text-xl text-gray-200 mb-5 sm:mb-5 md:mb-5 leading-relaxed font-light max-w-6xl mx-auto",children:t("nosotros.haka.conclusion")})]}),s.jsx(ie,{color:"#0a0e27",variant:1})]}),s.jsx(Yr,{isOpen:a,onClose:r,title:n})]})}function Tee(){const{t}=$(),e={image:"/imagenes/nosotros_caracteristicas.png",left:[{id:"esencia",title:t("nosotros.caracteristicas.esencia.title"),description:t("nosotros.caracteristicas.esencia.description"),icon:"/imagenes/nosotros_esencia.png"},{id:"vision",title:t("nosotros.caracteristicas.vision.title"),description:t("nosotros.caracteristicas.vision.description"),icon:"/imagenes/nosotros_vision.png"}],right:[{id:"mision",title:t("nosotros.caracteristicas.mision.title"),description:t("nosotros.caracteristicas.mision.description"),icon:"/imagenes/nosotros_mision.png"},{id:"compromiso",title:t("nosotros.caracteristicas.compromiso.title"),description:t("nosotros.caracteristicas.compromiso.description"),icon:"/imagenes/nosotros_compromiso.png"}]};return s.jsxs("section",{className:"relative bg-gradient-to-b from-slate-800/30 via-dark to-dark py-16 sm:py-20 md:py-24",children:[s.jsx("div",{className:"max-w-7xl mx-auto px-4 sm:px-6 md:px-8 mt-9",children:s.jsxs("div",{className:"grid grid-cols-1 lg:grid-cols-12 gap-8 lg:gap-10 items-center",children:[s.jsx("div",{className:"lg:col-span-4 space-y-8 sm:space-y-12 mt-5",children:e.left.map((a,n)=>s.jsxs(_.div,{initial:{opacity:0,x:-50},whileInView:{opacity:1,x:0},viewport:{once:!0},transition:{duration:.6,delay:n*.2},className:"text-left lg:text-right",children:[s.jsx("div",{className:"flex lg:justify-end mb-4",children:s.jsx("img",{src:a.icon,alt:a.title,className:"w-12 h-12 sm:w-16 sm:h-16",loading:"lazy"})}),s.jsx("h3",{className:"text-xl sm:text-2xl font-semibold text-primary mb-3",children:a.title}),s.jsx("p",{className:"text-sm sm:text-base text-gray-200 leading-relaxed",children:a.description})]},a.id))}),s.jsx("div",{className:"lg:col-span-4 flex justify-center items-center my-6 lg:my-0 w-full",children:s.jsx(_.div,{className:"flex justify-center w-full",initial:{opacity:0,scale:.8},whileInView:{opacity:1,scale:1},viewport:{once:!0},transition:{duration:.8,delay:.3},children:s.jsx("img",{src:e.image,alt:"Personajes HakaLab",className:"w-2/3 sm:max-w-lg lg:max-w-lg h-auto drop-shadow-2xl object-contain mx-auto",loading:"lazy"})})}),s.jsx("div",{className:"lg:col-span-4 space-y-6 sm:space-y-10 lg:mt-5 sm:mt-0",children:e.right.map((a,n)=>s.jsxs(_.div,{initial:{opacity:0,x:50},whileInView:{opacity:1,x:0},viewport:{once:!0},transition:{duration:.6,delay:n*.2},className:"text-left",children:[s.jsx("div",{className:"flex justify-start mb-4",children:s.jsx("img",{src:a.icon,alt:a.title,className:"w-12 h-12 sm:w-16 sm:h-16",loading:"lazy"})}),s.jsx("h3",{className:"text-xl sm:text-2xl font-semibold text-primary mb-3",children:a.title}),s.jsx("p",{className:"text-sm sm:text-base text-gray-200 leading-relaxed",children:a.description})]},a.id))})]})}),s.jsx(ie,{variant:1})]})}function Nee(t="haka_lab",e=10){const[a,n]=k.useState([]),[i,r]=k.useState(!0),[o,l]=k.useState(null);return k.useEffect(()=>{(async()=>{try{r(!0);const d=await fetch(`https://us-central1-web-haka-2026.cloudfunctions.net/getTweetsHttp?username=${t}&maxResults=${e}`);if(!d.ok)throw new Error(`Error HTTP: ${d.status}`);const u=await d.json();if(!u.success)throw new Error(u.error||"Error desconocido");n(u.tweets||[]),l(null)}catch(d){console.error("Error al obtener tweets:",d),l(d.message),n([])}finally{r(!1)}})()},[t,e]),{tweets:a,loading:i,error:o}}function Iee(){const{t}=$(),{tweets:e,loading:a}=Nee("haka_lab",9),[n,i]=k.useState(9),r=[{id:1,title:"Haka RTC captura y organiza tráfico de API REST",description:"Con Haka RTC captura y organiza tráfico de API REST desde el navegador y Postman o CSV para obtener pruebas de integración y regresión.",image:"/imagenes/personajes_home.png",date:"2024-01-14",link:"https://twitter.com/haka_lab"},{id:2,title:"Cada hora caída en un cyber puede costar hasta 25%",description:"En fechas críticas, una caída impacta significativamente en ventas y reputación.",image:"/imagenes/performance.png",date:"2024-01-09",link:"https://twitter.com/haka_lab"},{id:3,title:"Certificación más rápida, mismo nivel de calida
3702d",description:"Optimiza tus procesos de testing con nuestras soluciones.",image:"/imagenes/personajes_home.png",date:"2024-01-04",link:"https://twitter.com/haka_lab"}],o=()=>{i(d=>d+3)},l=e.length>0?e.slice(0,n):r.slice(0,n),c=n<(e.length>0?e.length:r.length);return s.jsxs("section",{className:"relative bg-gradient-to-b from-slate-800/30 via-dark to-dark py-16 sm:py-20 md:py-24",children:[s.jsxs("div",{className:"max-w-7xl mx-auto px-4 sm:px-6 md:px-8",children:[s.jsxs(_.div,{initial:{opacity:0,y:-20},whileInView:{opacity:1,y:0},viewport:{once:!0},transition:{duration:.6},className:"text-center mb-12 sm:mb-16 mt-8 sm:mt-12 md:mt-16",children:[s.jsx("h2",{className:"mt-1 text-3xl md:text-4xl font-extrabold text-white leading-tight uppercase tracking-tight",children:t("nosotros.redes.titulo")}),s.jsx("div",{className:"h-2 w-32 bg-cyan-400 mt-2 mx-auto"}),s.jsx("p",{className:"text-base sm:text-lg text-gray-200 font-light mb-8 mt-8",children:t("nosotros.redes.subtitulo")}),s.jsxs("div",{className:"flex justify-center gap-6",children:[s.jsx(_.a,{href:"https://www.youtube.com/@HakaLab_latam",target:"_blank",rel:"noopener noreferrer",whileHover:{scale:1.1},className:"w-12 h-12 bg-slate-800 rounded-full flex items-center justify-center hover:bg-red-600 transition-all duration-300 shadow-lg group",children:s.jsx("svg",{className:"w-6 h-6 text-white group-hover:text-white",fill:"currentColor",viewBox:"0 0 24 24",children:s.jsx("path",{d:"M23.498 6.186a2.96 2.96 0 00-2.083-2.09C19.505 3.5 12 3.5 12 3.5s-7.505 0-9.415.596a2.96 2.96 0 00-2.083 2.09C0 8.1 0 12 0 12s0 3.9.502 5.814a2.96 2.96 0 002.083 2.09C4.495 20.5 12 20.5 12 20.5s7.505 0 9.415-.596a2.96 2.96 0 002.083-2.09C24 15.9 24 12 24 12s0-3.9-.502-5.814zM9.75 15.5v-7l6.5 3.5-6.5 3.5z"})})}),s.jsx(_.a,{href:"https://www.linkedin.com/company/33261585",target:"_blank",rel:"noopener noreferrer",whileHover:{scale:1.1},className:"w-12 h-12 bg-slate-800 rounded-full flex items-center justify-center hover:bg-blue-600 transition-all duration-300 shadow-lg group",children:s.jsx("svg",{className:"w-6 h-6 text-white",viewBox:"0 0 24 24",fill:"currentColor",children:s.jsx("path",{d:"M4.98 3.5C4.98 4.88 3.87 6 2.5 6S0 4.88 0 3.5 1.12 1 2.5 1 4.98 2.12 4.98 3.5zM.5 8h4v16h-4V8zm7 0h3.75v2.16h.05c.52-.99 1.8-2.03 3.7-2.03 3.96 0 4.68 2.6 4.68 5.97V24h-4v-7.5c0-1.79-.03-4.1-2.5-4.1-2.5 0-2.88 1.95-2.88 3.97V24h-4V8z"})})}),s.jsx(_.a,{href:"https://x.com/haka_lab",target:"_blank",rel:"noopener noreferrer",whileHover:{scale:1.1},className:"w-12 h-12 bg-slate-800 rounded-full flex items-center justify-center hover:bg-black transition-all duration-300 shadow-lg",children:s.jsx("svg",{className:"w-5 h-5 text-white",fill:"currentColor",viewBox:"0 0 24 24",children:s.jsx("path",{d:"M18.244 2.25h3.308l-7.227 8.26 8.502 11.24H16.17l-5.214-6.817L4.99 21.75H1.68l7.73-8.835L1.254 2.25H8.08l4.713 6.231zm-1.161 17.52h1.833L7.084 4.126H5.117z"})})}),s.jsxs(_.a,{href:"https://www.instagram.com/hakalab.latam",target:"_blank",rel:"noopener noreferrer",whileHover:{scale:1.1},className:"w-12 h-12 bg-slate-800 rounded-full flex items-center justify-center hover:shadow-lg transition-all duration-300 relative overflow-hidden group",children:[s.jsx("div",{className:"absolute inset-0 bg-gradient-to-tr from-[#feda75] via-[#d62976] to-[#4f5bd5] opacity-0 group-hover:opacity-100 transition-opacity duration-300"}),s.jsxs("svg",{className:"w-6 h-6 text-white relative z-10",viewBox:"0 0 24 24",fill:"none",stroke:"currentColor",strokeWidth:"2",strokeLinecap:"round",strokeLinejoin:"round",children:[s.jsx("rect",{x:"2",y:"2",width:"20",height:"20",rx:"5",ry:"5"}),s.jsx("path",{d:"M16 11.37A4 4 0 1112.63 8 4 4 0 0116 11.37z"}),s.jsx("line",{x1:"17.5",y1:"6.5",x2:"17.51",y2:"6.5"})]})]})]})]}),s.jsx("div",{className:"grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-6 lg:gap-8",children:a?s.jsx("div",{className:"col-span-full text-center py-12",children:s.jsx("p",{className:"text-gray-300",children:t("common.cargandoTweets")})}):e.length>0?l.map((d,u)=>s.jsxs(_.a,{href:d.url,target:"_blank",rel:"noopener noreferrer",initial:{opacity:0,y:30},whileInView:{opacity:1,y:0},viewport:{once:!0},transition:{duration:.5,delay:u*.1},className:"group bg-slate-800/30 rounded-lg overflow-hidden border border-primary/20 hover:border-primary/50 transition-all hover:shadow-lg hover:shadow-
3702primary/20 p-6 flex flex-col",children:[s.jsx("div",{className:"flex-1",children:s.jsx("h3",{className:"text-lg sm:text-xl font-semibold text-primary mb-3 group-hover:text-cyan-300 transition-colors line-clamp-3",children:d.text})}),s.jsxs("div",{className:"flex items-center justify-between text-xs text-gray-400 mt-4 pt-4 border-t border-primary/10",children:[s.jsxs("div",{className:"flex gap-4",children:[s.jsxs("span",{children:["❤️ ",d.likes]}),s.jsxs("span",{children:["🔄 ",d.retweets]}),s.jsxs("span",{children:["💬 ",d.replies]})]}),s.jsx("span",{className:"text-primary group-hover:underline",children:t("common.verEnX")})]}),s.jsx("div",{className:"text-xs text-gray-500 mt-3",children:new Date(d.created_at).toLocaleDateString("es-ES",{year:"numeric",month:"long",day:"numeric"})})]},d.id)):l.map((d,u)=>s.jsxs(_.a,{href:d.link,target:"_blank",rel:"noopener noreferrer",initial:{opacity:0,y:30},whileInView:{opacity:1,y:0},viewport:{once:!0},transition:{duration:.5,delay:u*.1},className:"group bg-slate-800/30 rounded-lg overflow-hidden border border-primary/20 hover:border-primary/50 transition-all hover:shadow-lg hover:shadow-primary/20",children:[s.jsxs("div",{className:"relative h-48 bg-slate-700/50 overflow-hidden",children:[s.jsx("img",{src:d.image,alt:d.title,className:"w-full h-full object-cover group-hover:scale-110 transition-transform duration-300",loading:"lazy"}),s.jsx("div",{className:"absolute top-4 right-4 w-10 h-10 bg-black/70 rounded-full flex items-center justify-center",children:s.jsx("svg",{className:"w-5 h-5 text-white",fill:"currentColor",viewBox:"0 0 24 24",children:s.jsx("path",{d:"M18.244 2.25h3.308l-7.227 8.26 8.502 11.24H16.17l-5.214-6.817L4.99 21.75H1.68l7.73-8.835L1.254 2.25H8.08l4.713 6.231zm-1.161 17.52h1.833L7.084 4.126H5.117z"})})})]}),s.jsxs("div",{className:"p-6",children:[s.jsx("h3",{className:"text-lg sm:text-xl font-semibold text-primary mb-2 group-hover:text-cyan-300 transition-colors",children:d.title}),s.jsx("p",{className:"text-sm text-gray-300 mb-4 line-clamp-3",children:d.description}),s.jsxs("div",{className:"flex items-center justify-between text-xs text-gray-400",children:[s.jsx("span",{children:new Date(d.date).toLocaleDateString("es-ES",{year:"numeric",month:"long",day:"numeric"})}),s.jsx("span",{className:"text-primary group-hover:underline",children:t("common.verEnX")})]})]})]},d.id))}),s.jsx(_.div,{initial:{opacity:0}
3702,whileInView:{opacity:1},viewport:{once:!0},transition:{duration:.6,delay:.4},className:"flex flex-col sm:flex-row gap-4 justify-center mt-12",children:c&&s.jsx("button",{onClick:o,className:"border-2 border-primary/50 text-primary px-8 py-3 rounded text-base sm:text-lg font-semibold hover:bg-primary/10 transition-all duration-300",children:t("nosotros.redes.verMasNoticias")})})]}),s.jsx(ie,{color:"#0a0e27",variant:2})]})}function Pee(){return s.jsxs("div",{className:"bg-dark",children:[s.jsx(Xa,{title:"Nosotros - Expertos en QA y Testing",description:"Conoce al equipo de HakaLab. Mas de 10 años de experiencia en testing automatizado y calidad de software en Chile.",path:"/nosotros"}),s.jsx(jee,{}),s.jsx(Tee,{}),s.jsx(Iee,{})]})}function Ree(){const{t}=$(),e=t("casosExito.hero",{returnObjects:!0}),{isOpen:a,modalTitle:n,openModal:i,closeModal:r}=oa();return s.jsxs(s.Fragment,{children:[s.jsxs("section",{id:"home",className:"relative bg-dark",itemScope:!0,itemType:"https://schema.org/WebPageElement",children:[s.jsxs("div",{className:"relative py-12 sm:py-16 md:py-5 flex items-center justify-center overflow-hidden min-h-[400px] sm:min-h-[400px]",children:[s.jsx("div",{className:"absolute inset-0 bg-gradient-to-br from-dark via-dark to-dark"}),s.jsx("div",{className:"hero-glow-head"}),s.jsx("div",{className:"relative z-10 mt-6 sm:mt-1 md:mt-10 max-w-7xl mx-auto px-4 sm:px-6 md:px-8 w-full",children:s.jsxs("div",{className:"grid grid-cols-1 lg:grid-cols-2 gap-8 sm:gap-12 md:gap-16 items-center",children:[s.jsxs("div",{className:"flex flex-col justify-center text-center lg:text-right order-1 lg:order-2",children:[s.jsx("h1",{id:"casos-hero-title",className:"text-4xl md:text-5xl font-extrabold tracking-tight text-white",itemProp:"headline",children:e.title}),s.jsx("div",{className:"h-2 w-24 md:w-32 bg-cyan-400 mt-4 mx-auto lg:ml-auto lg:mr-0"}),s.jsx("p",{id:"casos-hero-subtitle",className:"mt-6 text-md sm:text-base lg:text-lg text-gray-100 mb-8 leading-relaxed font-light",itemProp:"description",children:e.subt
3702itle}),s.jsx("div",{className:"flex justify-center lg:justify-end",children:s.jsx("button",{id:"casos-hero-button",onClick:()=>i(t("contactModal.title")),className:"border-2 border-primary text-primary px-6 py-2 sm:py-3 rounded-2xl text-base font-semibold hover:bg-primary hover:text-dark transition-all",children:e.btn})})]}),s.jsx("div",{className:"flex justify-center items-center order-2 lg:order-1",children:s.jsx("img",{src:"/imagenes/casos_exito.png",alt:"Casos de Éxito HakaLab",id:"casos-hero-image",className:"w-full max-w-[250px] sm:max-w-md lg:max-w-lg h-auto drop-shadow-2xl",loading:"eager",width:"512",height:"512"})})]})})]}),s.jsx(ie,{color:"#0a0e27",variant:1})]}),s.jsx(Yr,{isOpen:a,onClose:r,title:n})]})}function Lee({className:t="w-5 h-5"}){return s.jsx("svg",{xmlns:"http://www.w3.org/2000/svg",fill:"none",viewBox:"0 0 24 24",className:t,children:s.jsx("path",{stroke:"currentColor",strokeLinecap:"round",strokeLinejoin:"round",strokeWidth:"2",d:"M21 21H4.6c-.56 0-.84 0-1.054-.109a1 1 0 0 1-.437-.437C3 20.2401 3 19.9601 3 19.4V3m18 4-5.4343 5.4343c-.198.198-.297.297-.4112.3341a.5.5 0 0 1-.309 0c-.1142-.0371-.2132-.1361-.4112-.3341l-1.8686-1.8686c-.198-.198-.297-.297-.4112-.3341a.5.5 0 0 0-.309 0c-.1142.0371-.2132.1361-.4112.3341L7 15m14-8h-4m4 0v4"})})}function Oee({className:t="w-5 h-5"}){return s.jsx("svg",{xmlns:"http://www.w3.org/2000/svg",fill:"none",viewBox:"0 0 24 24",className:t,children:s.jsx("path",{stroke:"currentColor",strokeLinecap:"round",strokeLinejoin:"round",strokeWidth:"2",d:"M11 4.5h7.3c1.1201 0 1.6802 0 2.108.218.3763.1917.6823.4977.874.874.218.4278.218.9879.218 2.108V9c0 .9319 0 1.3978-.1522 1.7654-.203.49-.5924.8794-1.0824 1.0824C19.8978 12 19.4319 12 18.5 12M13 19.5H5.7c-1.1201 0-1.6802 0-2.108-.218a2 2 0 0 1-.874-.874C2.5 17.9802 2.5 17.4201 2.5 16.3V15c0-.9319 0-1.3978.1522-1.7654.203-.49.5924-.8794 1.0824-1.0824C4.1022 12 4.5681 12 5.5 12m4.8 2.5h3.4c.28 0 .42 0 .527-.0545a.5.5 0 0 0 .2185-.2185c.0545-.107.0545-.247.0545-.527v-3.4c0-.28 0-.42-.0545-.527a.5.5 0 0 0-.2185-.2185C14.12 9.5 13.98 9.5 13.7 9.5h-3.4c-.28 0-.42 0-.527.0545a.5.5 0 0 0-.2185.2185C9.5 9.88 9.5 10.02 9.5 10.3v3.4c0 .28 0 .42.0545.527a.5.5 0 0 0 .2185.2185c.107.0545.247.0545.527.0545m7.5 7.5h3.4c.28 0 .42 0 .527-.0545a.5.5 0 0 0 .2185-.2185C22 21.62 22 21.48 22 21.2v-3.4c0-.28 0-.42-.0545-.527a.5.5 0 0 0-.2185-.2185C21.62 17 21.48 17 21.2 17h-3.4c-.28 0-.42 0-.527.0545a.5.5 0 0 0-.2185.2185C17 17.38 17 17.52 17 17.8v3.4c0 .28 0 .42.0545.527a.5.5 0 0 0 .2185.2185C17.38 22 17.52 22 17.8 22M2.8 7h3.4c.28 0 .42 0 .527-.0545a.5.5 0 0 0 .2185-.2185C7 6.62 7 6.48 7 6.2V2.8c0-.28 0-.42-.0545-.527a.5.5 0 0 0-.2185-.2185C6.62 2 6.48 2 6.2 2H2.8c-.28 0-.42 0-.527.0545a.5.5 0 0 0-.2185.2185C2 2.38 2 2.52 2 2.8v3.4c0 .28 0 .42.0545.527a.5.5 0 0 0 .2185.2185C2.38 7 2.52 7 2.8 7"})})}function Mee({className:t="w-5 h-5"}){return s.jsx("svg",{xmlns:"http://www.w3.org/2000/svg",fill:"none",viewBox:"0 0 24 24",className:t,children:s.jsx("path",{stroke:"currentColor",strokeLinecap:"round",strokeLinejoin:"round",strokeWidth:"2",d:"M22 9H2m12 8.5 2.5-2.5-2.5-2.5m-4 0L7.5 15l2.5 2.5M2 7.8v8.4c0 1.6802 0 2.5202.327 3.162a3 3 0 0 0 1.311 1.311C4.2798 21 5.1198 21 6.8 21h10.4c1.6802 0 2.5202 0 3.162-.327a3 3 0 0 0 1.311-1.311C22 18.7202 22 17.8802 22 16.2V7.8c0-1.6802 0-2.5202-.327-3.162a3 3 0 0 0-1.311-1.311C19.7202 3 18.8802 3 17.2 3H6.8c-1.6802 0-2.5202 0-3.162.327a3 3 0 0 0-1.311 1.311C2 5.2798 2 6.1198 2 7.8"})})}function Dee({className:t="w-8 h-8"}){return s.jsx("svg",{xmlns:"http://www.w3.org/2000/svg",fill:"none",viewBox:"0 0 24 24",className:t,children:s.jsx("path",{stroke:"currentColor",strokeLinecap:"round",strokeLinejoin:"round",strokeWidth:"2",d:"M12 12L7.5 7.5M12 12l4.5-4.5M12 12l-4.5 4.5M12 12l4.5 4.5M6 3h12M6 21h12M8.4 3v2.4c0 .5601 0 .8402.109 1.054a1 1 0 0 0 .437.437C9.1598 7 9.4399 7 10 7h4c.5601 0 .8402 0 1.054-.109a1 1 0 0 0 .437-.437C15.6 6.2402 15.6 5.9601 15.6 5.4V3M8.4 21v-2.4c0-.5601 0-.8402.109-1.054a1 1 0 0 1 .437-.437C9.1598 17 9.4399 17 10 17h4c.5601 0 .8402 0 1.054.109a1 1 0 0 1 .437.437c.109.2138.109.4939.109 1.054V21"})})}function qee({className:t="w-8 h-8"}){return s.jsx("svg",{xmlns:"http://www.w3.org/2000/svg",fill:"none",viewBox:"0 0 24 24",className:t,children:s.jsx("path",{stroke:"currentColor",strokeLinecap:"round",strokeLinejoin:"round",strokeWidth:"2",d:"M22 12h-4m-6-6V2m0 20v-4m-6-6H2m20 0c0 5.5228-4.4772 10-10 10S2 17.5228 2 12 6.4772 2 12 2s10 4.4772 10 10m-4 0c0 3.3137-2.6863 6-6 6s-6-2.6863-6-6 2.6863-6 6-6 6 2.6863 6 6m-4 0a2 2 0 1 1-4 0 2 2 
37020 0 1 4 0"})})}function zee({className:t="w-8 h-8"}){return s.jsx("svg",{xmlns:"http://www.w3.org/2000/svg",fill:"none",viewBox:"0 0 24 24",className:t,children:s.jsx("path",{stroke:"currentColor",strokeLinecap:"round",strokeLinejoin:"round",strokeWidth:"2",d:"m14.7279 10.1213 7.0711 7.0711c.3905.3905.5858.5858.5858.8284 0 .2427-.1953.4379-.5858.8284l-1.4142 1.4142c-.3905.3905-.5857.5858-.8284.5858s-.4379-.1953-.8284-.5858l-7.0711-7.0711m3.5355-3.5355A5.0001 5.0001 0 0 0 12 4c-.5523 0-1 .4477-1 1v.3431c0 .3183 0 .4774-.0586.6131a1 1 0 0 1-.2652.3652c-.1357.0586-.2948.0586-.6131.0586H9.5c-.2761 0-.4142 0-.5176.0384a1 1 0 0 0-.6963.6963C8.25 7.1858 8.25 7.3239 8.25 7.6v.65c0 .3183 0 .4774-.0586.6131a1 1 0 0 1-.3652.2652c-.1357.0586-.2948.0586-.6131.0586H7c-.5523 0-1 .4477-1 1a5.0001 5.0001 0 0 0 5.6569 4.9497m3.5355-3.5355-3.5355 3.5355"})})}function Vee({className:t="w-8 h-8"}){return s.jsx("svg",{xmlns:"http://www.w3.org/2000/svg",fill:"none",viewBox:"0 0 24 24",className:t,children:s.jsx("path",{stroke:"currentColor",strokeLinecap:"round",strokeLinejoin:"round",strokeWidth:"2",d:"M12 15v3.5m0-3.5a6.9998 6.9998 0 0 1-4.2426-1.4571L6.5 12.5v-2l-3.2929-3.2929C2.7803 6.7803 2.5732 6.5732 2.4619 6.3271A1.5 1.5 0 0 1 2.25 5.5v-.3c0-.4714 0-.7071.0732-.8536a.5.5 0 0 1 .2732-.2732C2.7929 4 3.0286 4 3.5 4h.8c.2357 0 .4714 0 .6857.0381.1929.0343.3771.0933.5514.1762.1935.092.3664.2197.7122.4751L9.5 7.5h2l1.5429-1.2574A6.9998 6.9998 0 0 1 15 4.5V2m-3 13a6.9998 6.9998 0 0 0 4.2426-1.4571L17.5 12.5v-2l3.2929-3.2929c.4268-.4268.6402-.6402.7515-.8863A1.5 1.5 0 0 0 21.75 5.5v-.3c0-.4714 0-.7071-.0732-.8536a.5.5 0 0 0-.2732-.2732C21.2571 4 21.0214 4 20.5 4h-.8c-.2357 0-.4714 0-.6857.0381a2 2 0 0 0-.5514.1762c-.1935.092-.3664.2197-.7122.4751L14.5 7.5h-2l-1.5429-1.2574A6.9998 6.9998 0 0 0 9 4.5V2m3 13c0 1.8638 0 2.7956-.1522 3.5307-.203.9802-.7476 1.8744-1.5449 2.5375C9.5577 22 8.6935 22 6.9651 22c-.5523 0-.8284 0-1.0214-.0815a1.4 1.4 0 0 1-.8622-.8622C5 20.9463 5 20.6702 5 20.1179v-1.6358c0-.3183 0-.4774.0586-.6131a1 1 0 0 1 .2652-.3652c.1357-.0586.2948-.0586.6131-.0586h.8262c.3183 0 .4774 0 .6131.0586a1 1 0 0 1 .3652.2652c.0586.1357.0586.2948.0586.6131v1.6358c0 .5523 0 .8284.0815 1.0214a1.4 1.4 0 0 0 .8622.8622C8.8821 22 9.1582 22 9.7105 22h.3244c1.7284 0 2.5926 0 3.3378-.3932.7973-.4631 1.3418-1.3573 1.5449-2.5375C15.0676 18.3304 15.0676 17.3986 15.0676 15.5m0 0c0-1.8638 0-2.7956.1522-3.5307.203-.9802.7476-1.8744 1.5449-2.5375C17.5099 9 18.3741 9 20.1025 9c.5523 0 .8284 0 1.0214.0815a1.4 1.4 0 0 1 .8622.8622C22 10.1537 22 10.4298 22 10.9821v1.6358c0 .3183 0 .4774-.0586.6131a1 1 0 0 1-.2652.3652c-.1357.0586-.2948.0586-.6131.0586h-.8262c-.3183 0-.4774 0-.6131-.0586a1 1 0 0 1-.3652-.2652c-.0586-.1357-.0586-.2948-.0586-.6131v-1.6358c0-.5523 0-.8284-.0815-1.0214a1.4 1.4 0 0 0-.8622-.8622C18.1179 9 17.8418 9 17.2895 9h-.3244c-1.7284 0-2.5926 0-3.3378.3932-.7973.4631-1.3418 1.3573-1.5449 2.5375C12.0324 12.6696 12.0324 13.6014 12.0324 15.5M15 9a3 3 0 1 1-6 0 3 3 0 0 1 6 0"})})}function Hee({className:t="w-8 h-8"}){return s.jsx("svg",{xmlns:"http://www.w3.org/2000/svg",fill:"none",viewBox:"0 0 24 24",className:t,children:s.jsx("path",{stroke:"currentColor",strokeLinecap:"round",strokeLinejoin:"round",strokeWidth:"2",d:"M12 16v2m0 0v2m0-2h-2m2 0h2M6.8 20h10.4c1.6802 0 2.5202 0 3.162-.327a3 3 0 0 0 1.311-1.311C22 17.7202 22 16.8802 22 15.2V8.8c0-1.6802 0-2.5202-.327-3.162a3 3 0 0 0-1.311-1.311C19.7202 4 18.8802 4 17.2 4H6.8c-1.6802 0-2.5202 0-3.162.327a3 3 0 0 0-1.311 1.311C2 6.2798 2 7.1198 2 8.8v6.4c0 1.6802 0 2.5202.327 3.162a3 3 0 0 0 1.311 1.311C4.2798 20 5.1198 20 6.8 20"})})}function Fee({className:t="w-8 h-8"}){return s.jsx("svg",{xmlns:"http://www.w3.org/2000/svg",fill:"none",viewBox:"0 0 24 24",className:t,children:s.jsx("path",{stroke:"currentColor",strokeLinecap:"round",strokeLinejoin:"round",strokeWidth:"2",d:"M6 20V10m6 10V4m6 16v-7"})})}function Bee({className:t="w-8 h-8"}){return s.jsx("svg",{xmlns:"http://www.w3.org/2000/svg",fill:"none",viewBox:"0 0 24 24",className:t,children:s.jsx("path",{stroke:"currentColor",strokeLinecap:"round",strokeLinejoin:"round",strokeWidth:"2",d:"m9 12 2 2 4-4m7-1.3418V7.2c0-.6402 0-.9603-.0545-1.2162a2 2 0 0 0-.2185-.5274c-.1357-.2118-.3339-.3801-.7303-.7166l-4.8-4.08c-.3753-.3189-.5629-.4783-.7763-.5384a1 1 0 0 0-.5408 0c-.2134.0601-.401.2195-.7763.5384l-4.8 4.08c-.39
370264.3365-.5946.5048-.7303.7166a2 2 0 0 0-.2185.5274C2 6.2397 2 6.5598 2 7.2v1.4582c0 4.5714 2.5 8.7714 7.5 11.2714 5-2.5 7.5-6.7 7.5-11.2714"})})}function Uee({className:t="w-8 h-8"}){return s.jsx("svg",{xmlns:"http://www.w3.org/2000/svg",fill:"none",viewBox:"0 0 24 24",className:t,children:s.jsx("path",{stroke:"currentColor",strokeLinecap:"round",strokeLinejoin:"round",strokeWidth:"2",d:"M7 22V11M2 13v6c0 .9319 0 1.3978.1522 1.7654.203.49.5924.8794 1.0824 1.0824C3.6022 22 4.0681 22 5 22h1.3431c.2357 0 .4714 0 .6857-.0381a2 2 0 0 0 .5514-.1762c.1935-.092.3664-.2197.7122-.4751L11 19m0 0 .5858-.5858c.3905-.3905.5858-.5858.7071-.8284.1214-.2427.1214-.5142.1214-1.0572V13c0-.4714 0-.7071.0732-.8536a.5.5 0 0 1 .2185-.2185C12.7929 11.85 13.0286 11.85 13.5 11.85h4.8c1.1201 0 1.6802 0 2.108-.218a2 2 0 0 0 .874-.874c.218-.4278.218-.9879.218-2.108V8.5c0-.4714 0-.7071-.0732-.8536a.5.5 0 0 0-.2185-.2185C21.0571 7.35 20.8214 7.35 20.35 7.35h-4.8c-.4714 0-.7071 0-.8536-.0732a.5.5 0 0 1-.2185-.2185C14.4 6.9071 14.4 6.6714 14.4 6.2V3.7c0-.5601 0-.8402-.109-1.054a1 1 0 0 0-.437-.437C13.6402 2.1 13.3601 2.1 12.8 2.1h-.3c-.2357 0-.4714 0-.6857.0381a2 2 0 0 0-.5514.1762c-.1935.092-.3664.2197-.7122.4751L7 6.5"})})}function $ee({className:t="w-8 h-8"}){return s.jsx("svg",{xmlns:"http://www.w3.org/2000/svg",fill:"none",viewBox:"0 0 24 24",className:t,children:s.jsx("path",{stroke:"currentColor",strokeLinecap:"round",strokeLinejoin:"round",strokeWidth:"2",d:"M6 6h.01M6 18h.01M6 12h.01M22 8.2v-.4c0-1.6802 0-2.5202-.327-3.162a3 3 0 0 0-1.311-1.311C19.7202 3 18.8802 3 17.2 3H6.8c-1.6802 0-2.5202 0-3.162.327a3 3 0 0 0-1.311 1.311C2 5.2798 2 6.1198 2 7.8v.4c0 1.6802 0 2.5202.327 3.162a3 3 0 0 0 1.311 1.311C4.2798 13 5.1198 13 6.8 13h10.4c1.6802 0 2.5202 0 3.162-.327a3 3 0 0 0 1.311-1.311C22 10.7202 22 9.8802 22 8.2m0 7.6v.4c0 1.6802 0 2.5202-.327 3.162a3 3 0 0 1-1.311 1.311C19.7202 21 18.8802 21 17.2 21H6.8c-1.6802 0-2.5202 0-3.162-.327a3 3 0 0 1-1.311-1.311C2 18.7202 2 17.8802 2 16.2v-.4c0-1.6802 0-2.5202.327-3.162a3 3 0 0 1 1.311-1.311C4.2798 11 5.1198 11 6.8 11h10.4c1.6802 0 2.5202 0 3.162.327a3 3 0 0 1 1.311 1.311C22 13.2798 22 14.1198 22 15.8"})})}function Wee({className:t="w-8 h-8"}){return s.jsx("svg",{xmlns:"http://www.w3.org/2000/svg",fill:"none",viewBox:"0 0 24 24",className:t,children:s.jsx("path",{stroke:"currentColor",strokeLinecap:"round",strokeLinejoin:"round",strokeWidth:"2",d:"M21 7.35294V16.6471C21 17.1686 21 17.4294 20.9447 17.6543C20.7672 18.3841 20.2128 18.9385 19.483 19.116C19.2581 19.1713 18.9973 19.1713 18.4758 19.1713C17.9543 19.1713 17.6935 19.1713 17.4686 19.116C16.7388 18.9385 16.
37021844 18.3841 16.0069 17.6543C15.9516 17.4294 15.9516 17.1686 15.9516 16.6471V7.35294C15.9516 6.83143 15.9516 6.57068 16.0069 6.34575C16.1844 5.61595 16.7388 5.06154 17.4686 4.88403C17.6935 4.82874 17.9543 4.82874 18.4758 4.82874C18.9973 4.82874 19.2581 4.82874 19.483 4.88403C20.2128 5.06154 20.7672 5.61595 20.9447 6.34575C21 6.57068 21 6.83143 21 7.35294ZM15.9516 7.35294V16.6471C15.9516 17.1686 15.9516 17.4294 15.8963 17.6543C15.7188 18.3841 15.1644 18.9385 14.4346 19.116C14.2097 19.1713 13.9489 19.1713 13.4274 19.1713H6.8C5.11984 19.1713 3.73433 17.7858 3.73433 16.1056V7.89437C3.73433 6.21421 5.11984 4.82874 6.8 4.82874H13.4274C13.9489 4.82874 14.2097 4.82874 14.4346 4.88403C15.1644 5.06154 15.7188 5.61595 15.8963 6.34575C15.9516 6.57068 15.9516 6.83143 15.9516 7.35294ZM9.86667 19.1713V20.2374C9.86667 21.2119 9.08114 22 8.10667 22C7.13219 22 6.34667 21.2119 6.34667 20.2374V19.1713H9.86667Z"})})}function Gee({className:t="w-8 h-8"}){return s.jsxs("svg",{xmlns:"http://www.w3.org/2000/svg",fill:"none",viewBox:"0 0 24 24",className:t,children:[s.jsx("path",{stroke:"currentColor",strokeLinecap:"round",strokeLinejoin:"round",strokeWidth:"2",d:"M9.3951 19.3711L9.97955 20.6856C10.1533 21.0768 10.4368 21.4093 10.7958 21.6426C11.1547 21.8759 11.5737 22.0001 12.0018 22C12.4299 22.0001 12.8488 21.8759 13.2078 21.6426C13.5667 21.4093 13.8503 21.0768 14.024 20.6856L14.6084 19.3711C14.8165 18.9047 15.1664 18.5159 15.6084 18.26C16.0532 18.0034 16.5678 17.8941 17.0784 17.9478L18.5084 18.1C18.9341 18.145 19.3637 18.0656 19.7451 17.8713C20.1265 17.6771 20.4434 17.3763 20.6573 17.0056C20.8715 16.635 20.9735 16.2103 20.9511 15.7829C20.9286 15.3555 20.7825 14.9438 20.5307 14.5978L19.684 13.4344C19.3825 13.0171 19.2214 12.5148 19.224 12C19.2239 11.4866 19.3865 10.9864 19.6884 10.5711L20.5351 9.40778C20.787 9.06175 20.933 8.65007 20.9555 8.22267C20.978 7.79528 20.8759 7.37054 20.6618 7C20.4479 6.62923 20.131 6.32849 19.7496 6.13423C19.3681 5.93997 18.9386 5.86053 18.5129 5.90556L17.0829 6.05778C16.5722 6.11141 16.0577 6.00212 15.6129 5.74556C15.17 5.48825 14.82 5.09736 14.6129 4.62889L14.024 3.31444C13.8503 2.92317 13.5667 2.59072 13.2078 2.3574C12.8488 2.12408 12.4299 1.99993 12.0018 2C11.5737 1.99993 11.1547 2.12408 10.7958 2.3574C10.4368 2.59072 10.1533 2.92317 9.97955 3.31444L9.3951 4.62889C9.18803 5.09736 8.83798 5.48825 8.3951 5.74556C7.95032 6.00212 7.43577 6.11141 6.9251 6.05778L5.49066 5.90556C5.06499 5.86053 4.6354 5.93997 4.25397 6.13423C3.87255 6.32849 3.55567 6.62923 3.34177 7C3.12759 7.37054 3.02555 7.79528 3.04804 8.22267C3.07052 8.65007 3.21656 9.06175 3.46844 9.40778L4.3151 10.5711C4.61704 10.9864 4.77964 11.4866 4.7795
37025 12C4.77964 12.5134 4.61704 13.0137 4.3151 13.4289L3.46844 14.5922C3.21656 14.9382 3.07052 15.3499 3.04804 15.7773C3.02555 16.2047 3.12759 16.6295 3.34177 17C3.55589 17.3706 3.8728 17.6712 4.25417 17.8654C4.63554 18.0596 5.06502 18.1392 5.49066 18.0944L6.92066 17.9422C7.43133 17.8886 7.94587 17.9979 8.39066 18.2544C8.83519 18.511 9.18687 18.902 9.3951 19.3711Z"}),s.jsx("path",{stroke:"currentColor",strokeLinecap:"round",strokeLinejoin:"round",strokeWidth:"2",d:"M15 12C15 13.6569 13.6569 15 12 15C10.3431 15 9 13.6569 9 12C9 10.3431 10.3431 9 12 9C13.6569 9 15 10.3431 15 12Z"})]})}function Kee({className:t="w-8 h-8"}){return s.jsx("svg",{xmlns:"http://www.w3.org/2000/svg",fill:"none",viewBox:"0 0 24 24",className:t,children:s.jsx("path",{stroke:"currentColor",strokeLinecap:"round",strokeLinejoin:"round",strokeWidth:"2",d:"M22 11.0857V12.0057C21.9988 14.1621 21.3005 16.2604 20.0093 17.9875C18.7182 19.7147 16.9033 20.9782 14.8354 21.5896C12.7674 22.201 10.5573 22.1276 8.53447 21.3803C6.51168 20.633 4.78465 19.2518 3.61096 17.4428C2.43727 15.6338 1.87979 13.4938 2.02168 11.342C2.16356 9.19029 2.99721 7.14205 4.39828 5.5028C5.79935 3.86354 7.69279 2.72111 9.79619 2.24587C11.8996 1.77063 14.1003 1.98806 16.07 2.86572M22 4L12 14.01L9 11.01"})})}function Jee(){const{t}=$(),e={tabs:[{id:"performance",iconComponent:"line-chart",label:"Performance",cases:[{company:"Walmart",image:"/imagenes/casos_walmart.png"},{company:"Melt Pizzas",image:"/imagenes/casos_melt.png"}]},{id:"continuous",iconComponent:"dataflow",label:"Continuous Testing",cases:[{company:"Consorcio",image:"/imagenes/casos_consorcio.png"},{company:"Casa Ideas",image:"/imagenes/casos_casaideas.png"},{company:"Sodimac Homecenter",image:"/imagenes/casos_sodimac.png"},{company:"Scotiabank",image:"/imagenes/casos_scotiabank.png"}]},{id:"data",iconComponent:"code-browser",label:"Data Testing",cases:[{company:"Parque Arauco",image:"/imagenes/casos_parquearauco.png"}]}]},[a,n]=k.useState(0),i=e.tabs[a],r=Array.isArray(i.cases)?i.cases:[i],o={Walmart:"walmart","Melt Pizzas":"melt",Consorcio:"consorcio","Casa Ideas":"casaideas","Sodimac Homecenter":"sodimac",Scotiabank:"scotiabank","Parque Arauco":"parquearauco"},l=u=>{const p=o[u];return p?t(`casosExito.cases.${p}`,{returnObjects:!0}):null},c={"line-chart":Lee,dataflow:Oee,"code-browser":Mee,hourglass:Dee,target:qee,wrench:zee,rocket:Vee,monitor:Hee,chart:Fee,"check-shield":Bee,"thumbs-up":Uee,server:$ee,megaphone:Wee,gear:Gee,"circle-check":Kee},d=u=>{if(u.iconComponent&&c[u.iconComponent]){const p=c[u.iconComponent];return s.jsx(p,{className:"w-5 h-5 sm:w-6 sm:h-6"})}return u.iconImage?s.jsx("img",{src:u.iconImage,alt:u.label,className:"w-5 h-5 sm:w-6 sm:h-6 object-contain"}):s.jsx("span",{className:"text-lg sm:text-xl",children:u.icon})};return s.jsxs("section",{className:"relative bg-gradient-to-b from-slate-800/30 via-dark to-dark py-16 sm:py-20 md:py-24",children:[s.jsxs("div",{className:"max-w-7xl mx-auto px-4 sm:px-6 md:px-8",children:[s.jsx("div",{className:"flex flex-wrap justify-center gap-3 sm:gap-4 mb-12 sm:mb-16 mt-9",children:e.tabs.map((u,p)=>s.jsxs(_.button,{id:`casos-interactivos-tab-${u.id}`,onClick:()=>n(p),whileHover:{scale:1.05},whileTap:{scale:.95},className:`
3703                                flex items-center gap-2 px-4 sm:px-6 py-2 sm:py-3 rounded-lg text-sm sm:text-base font-semibold
3704                                transition-all duration-300 border-2
3705                                ${a===p?"bg-primary text-dark border-primary shadow-lg shadow-primary/50":"bg-slate-800/50 text-gray-300 border-primary/30 hover:border-primary/60 hover:text-primary"}
3706                            `,children:[d(u),s.jsx("span",{children:u.label})]},u.id))}),s.jsx(La,{mode:"wait",children:s.jsx(_.div,{initial:{opacity:0,y:20},animate:{opacity:1,y:0},exit:{opacity:0,y:-20},transition:{duration:.5},className:"space-y-16 sm:space-y-20",children:r.map((u,p)=>{const h=l(u.company)||u;return s.jsxs("div",{className:"grid grid-cols-1 lg:grid-cols-2 gap-8 lg:gap-12 items-center",children:[s.jsxs("div",{className:`space-y-6 ${p%2===1?"lg:order-2":"lg:order-1"}`,children:[s.jsxs("div",{children:[s.jsx(_.h3,{initial:{opacity:0,x:-20}
3706,animate:{opacity:1,x:0},transition:{delay:.2},className:"text-2xl sm:text-3xl font-bold text-primary mb-2",children:h.company}),s.jsx(_.p,{initial:{opacity:0,x:-20},animate:{opacity:1,x:0},transition:{delay:.3},className:"text-xl sm:text-2xl text-gray-200",children:h.title})]}),h.problem&&s.jsxs(_.div,{initial:{opacity:0,x:-20},animate:{opacity:1,x:0},transition:{delay:.4},className:"bg-slate-800/30 p-4 sm:p-6 rounded-lg border border-red-500/30",children:[s.jsx("p",{className:"text-sm font-semibold text-red-400 mb-2",children:t("casosExito.desafioLabel")}),s.jsx("p",{className:"text-sm sm:text-base text-gray-200 leading-relaxed",children:h.problem})]}),h.solution&&s.jsxs(_.div,{initial:{opacity:0,x:-20},animate:{opacity:1,x:0},transition:{delay:.5},className:"bg-slate-800/30 p-4 sm:p-6 rounded-lg border border-primary/30",children:[s.jsx("p",{className:"text-sm font-semibold text-primary mb-2",children:t("casosExito.solucionLabel")}),s.jsx("p",{className:"text-sm sm:text-base text-gray-200 leading-relaxed",children:h.solution})]}),h.results&&s.jsx(_.div,{initial:{opacity:0,x:-20},animate:{opacity:1,x:0},transition:{delay:.6},className:"space-y-4",children:h.results.map((g,y)=>s.jsxs(_.div,{initial:{opacity:0,x:-20},animate:{opacity:1,x:0},transition:{delay:.7+y*.1},className:"flex items-start gap-4",children:[g.iconComponent&&c[g.iconComponent]&&s.jsx("div",{className:"flex-shrink-0 text-primary",children:(()=>{const x=c[g.iconComponent];return s.jsx(x,{className:"w-8 h-8 sm:w-10 sm:h-10"})})()}),g.iconImage&&!g.iconComponent&&s.jsx("div",{className:"flex-shrink-0",children:s.jsx("img",{src:g.iconImage,alt:"",className:"w-8 h-8 sm:w-10 sm:h-10 object-contain"})}),g.icon&&!g.iconImage&&!g.iconComponent&&s.jsx("div",{className:"flex-shrink-0 text-3xl",children:g.icon}),g.metric&&!g.icon&&!g.iconImage&&!g.iconComponent&&s.jsx("div",{className:"flex-shrink-0",children:s.jsx("div",{className:"text-3xl sm:text-4xl font-bold text-primary",children:g.metric})}),s.jsx("div",{className:"flex-1",children:s.jsx("p",{className:"text-sm sm:text-base text-gray-200",children:g.description})})]},y))}),h.testimonial&&s.jsxs(_.div,{initial:{opacity:0,x:-20},animate:{opacity:1,x:0},transition:{delay:.9},className:"bg-slate-800/30 p-4 sm:p-6 rounded-lg border border-primary/30",children:[s.jsx("p",{className:"text-sm font-semibold text-primary mb-2",children:t("casosExito.testimonioLabel")}),s.jsx("p",{className:"text-sm sm:text-base text-gray-200 italic mb-4",children:h.testimonial.text}),s.jsxs("div",{className:"text-sm text-gray-300",children:[s.jsx("p",{className:"font-semibold",children:h.testimonial.author}),s.jsx("p",{children:h.testimonial.position}),s.jsx("p",{className:"text-primary",children:h.testimonial.company})]})]}),h.qa&&!h.testimonial&&s.jsxs(_.div,{initial:{opacity:0,x:-20},animate:{opacity:1,x:0},transition:{delay:.9},className:"bg-primary/10 p-4 sm:p-6 rounded-lg border border-primary/50",children:[s.jsx("p",{className:"text-sm sm:text-base font-semibold text-primary",children:t("casosExito.qaLabel")}),s.jsx("p",{className:"text-sm sm:text-base text-gray-200 mt-2",children:h.qa})]})]}),s.jsx(_.div,{initial:{opacity:0,scale:.9},animate:{opacity:1,scale:1},transition:{delay:.3,duration:.6},className:`flex justify-center items-center w-full ${p%2===1?"lg:order-1":"lg:order-2"}`,children:s.jsx("div",{className:"relative w-full max-w-lg flex justify-center",children:s.jsx("img",{src:u.image,alt:`Caso de éxito ${u.company}`,className:"w-1/2 sm:w-full max-w-[200px] sm:max-w-md lg:max-w-lg h-auto drop-shadow-2xl object-contain",loading:"lazy"})})})]},p)})},a)})]}),s.jsx(ie,{color:"#0a0e27",variant:2})]})}function Qee(){const{isOpen:t,modalTitle:e,openModal:a,closeModal:n}=oa(),{t:i}=$();return s.jsxs(s.Fragment,{children:[s.jsx("section",{className:"relative bg-dark py-19 sm:py-20 mt-10",children:s.jsx("div",{className:"max-w-6xl mx-auto px-4 sm:px-6 md:px-8",children:s.jsxs("div",{className:"flex flex-col lg:flex-row items-center justify-between gap-8 sm:pt-10 pt-5",children:[s.jsxs("div",{className:"flex-1 text-center lg:text-left mt-10",children:[s.jsx(_.h2,{id:"casos-cta-diagnostico-title",initial:{opacity:0,y:20},whileInView:{opacity:1,y:0},viewport:{once:!0},transition:{duration:.6},className:"text-4xl md:text-5xl font-extrabold tracking-tight text-white",children:i("casosExito.cta.titulo")}),s.jsx(_.p,{id:"casos-cta-diagnostico-description",initial:{opacity:0,y:20},whileInView:{opacity:1,y:0},viewport:{once:!0},transition:{duration:.6,delay:.2},className:"text-base sm:text-lg text-gray-300 max-w-xl mt-6",children:i("casosExito.cta.descripcion")})]}),s.jsx(_.div,{initial:{opacity:0,y:20},whileInView:{opacity:1,y:0},viewport:{once:!0},transition:{duration:.6,delay:.4},className:"flex-shrink-0",children:s.jsx("button",{id:"casos-cta-diagnostico-button",onClick:()=>a(i("casosExito.cta.boton")),className:"inline-block px-8 py-3 bg-transparent border-2 border-primary text-primary rounded-2xl font-semibold hover:bg-primary hover:text-dark transition-all duration-300 transform hover:scale-105 whitespace-nowrap",children:i("casosExito.cta.boton")})})]})})}),s.jsx(Yr,{isOpen:t,onClose:n,title:e})]})}function Kk({className:t="w-8 h-8"}){return s.jsx("svg",{xmlns:"http://www.w3.org/2000/svg",fill:"none",viewBox:"0 0 24 24",className:t,children:s.jsx("path",{stroke:"currentColor",strokeLinecap:"round",strokeLinejoin:"round",strokeWidth:"2",d:"M12 15V17M12 17V19.5M12 17H9.5M12 17H14.5M6 3H18C18 3 18 5.5 18 7C18 9.5 15.5 12 12 12C8.5 12 6 9.5 6 7C6 5.5 6 3 6 3ZM6 3H4C3.5 3 3 3.5 3 4V6C3 7.5 4 9 5.5 9H6M18 3H20C20.5 3 21 3.5 21 4V6C21 7.5 20 9 18.5 9H18M8.5 19.5H15.5C16.0523 19.5 16.5 19.9477 16.5 20.5C16.5 21.0523 16.0523 21.5 15.5 21.5H8.5C7.94772 21.5 7.5 21.0523 7.5 20.5C7.5 19.9477 7.94772 19.5 8.5 19.5Z"})})}function Xee(){const[t,e]=k.useState(""),[a,n]=k.useState(!1),[i,r]=k.useState(""),{t:o}=$(),l=async c=>{c.preventDefault(),n(!0),r("");try{const d=document.createElement("a");d.href="/descargas/Casos-de-exitos-Haka-lab.pdf",d.download="Casos-de-exitos-Haka-lab.pdf",document.body.appendChild(d),d.click(),document.body.removeChild(d),r(o("ctaNewsletter.mensaje")),e(""),setTimeout(()=>{r("")},5e3)}catch(d){console.error("Error:",d),r("Hubo un error. Por favor intenta de nuevo.")}finally{n(!1)}};return s.jsxs("section",{className:"relative bg-dark py-16 sm:py-20 xs:mt-7",children:[s.jsx("div",{className:"max-w-4xl mx-auto px-4 sm:px-6 md:px-8",children:s.jsxs(_.div,{initial:{opacity:0,y:20},whileInView:{opacity:1,y:0},viewport:{once:!0},transition:{duration:.6},className:"relative bg-slate-900/50 backdrop-blur-sm border border-primary/30 rounded-2xl p-8 sm:p-12 shadow-2xl",style:{boxShadow:"0 0 40px rgba(0, 255, 255, 0.1)"},children:[s.jsx("div",{className:"absolute top-0 left-0 w-32 h-32 bg-primary/5 rounded-full blur-3xl -z-10"}),s.jsx("div",{className:"absolute bottom-0 right-0 w-32 h-32 bg-primary/5 rounded-full blur-3xl -z-10"}),s.jsx(_.div,{className:"absolute -top-6 -right-6 text-primary",animate:{rotate:360,scale:[1,1.1,1]},transition:{rotate:{duration:8,repeat:1/0,ease:"linear"},scale:{duration:2,repeat:1/0,ease:"easeInOut"}},children:s.jsx("div",{className:"bg-slate-800 rounded-full p-4 border-2 border-primary shadow-lg shadow-primary/50",children:s.jsx(Kk,{className:"w-8 h-8 sm:w-10 sm:h-10"})})}),s.jsx(_.h2,{initial:{opacity:0,y:20},whileInView:{opacity:1,y:0},viewport:{once:!0},transition:{duration:.6,delay:.1},className:"text-3xl sm:text-4xl md:text-3xl font-bold text-primary mb-8 text-center",children:o("ctaNewsletter.titulo")}),s.jsxs(_.form,{initial:{opacity:0,y:20},whileInView:{opacity:1,y:0},viewport:{once:!0},transition:{duration:.6,delay:.2},onSubmit:l,className:"flex flex-col sm:flex-row gap-4 justify-center items-center",children:[s.jsx("input",{id:"input-email",type:"email",value:t,onChange:c=>e(c.target.value),placeholder:o("ctaNewsletter.placeholder"),required:!0,disabled:a,className:"w-full sm:flex-1 px-6 py-3 bg-slate-800/80 border border-gray-700 rounded-lg text-gray-200 placeholder-gray-500 focus:outline-none focus:border-primary focus:ring-2 focus:ring-primary/20 transition-all disabled:opacity-50"}),s.jsx("button",{id:"btn-input-email",type:"submit",disabled:a,className:"w-full sm:w-auto px-4 sm:px-8 py-3 bg-transparent border-2 border-primary text-primary rounded-2xl font-semibold hover:bg-primary hover:text-dark transition-all duration-300 transform hover:scale-105 shadow-lg hover:shadow-
3706primary/50 text-sm sm:text-base leading-tight disabled:opacity-50 disabled:cursor-not-allowed",children:a?"Descargando...":o("ctaNewsletter.boton")})]}),i&&s.jsx(_.p,{initial:{opacity:0,y:10},animate:{opacity:1,y:0},className:"text-center text-primary text-sm mt-4",children:i})]})}),s.jsx(ie,{color:"#0a0e27",variant:1})]})}function Yee(){return s.jsxs("div",{className:"bg-dark",children:[s.jsx(Xa,{title:"Casos de Exito - Resultados Comprobados",description:"Walmart, Sodimac, Scotiabank y mas. Conoce como HakaLab ha ayudado a empresas Fortune 500 a mejorar su calidad de software.",path:"/casosdeexito"}),s.jsx(Ree,{}),s.jsx(Jee,{}),s.jsx(Qee,{}),s.jsx(Xee,{})]})}function Zee(){const{t}=$(),e=t("productos.hero",{returnObjects:!0});return s.jsxs("section",{id:"home",className:"relative bg-dark",itemScope:!0,itemType:"https://schema.org/WebPageElement",children:[s.jsx("div",{className:"relative py-12 sm:py-16 md:py-5 flex items-center justify-center overflow-hidden min-h-[400px] sm:min-h-[500px]",children:s.jsx("div",{className:"relative z-10 mt-6 sm:mt-8 md:mt-10 max-w-7xl mx-auto px-4 sm:px-6 md:px-8 w-full",children:s.jsxs("div",{className:"grid grid-cols-1 lg:grid-cols-2 gap-8 sm:gap-12 md:gap-16 items-center",children:[s.jsxs("div",{className:"flex flex-col justify-center text-center lg:text-left",children:[s.jsx("h1",{id:"productos-hero-title",className:"text-5xl md:text-5xl font-extrabold tracking-tight text-white",itemProp:"headline",children:e.title}),s.jsx("h1",{className:"text-5xl md:text-5xl font-extrabold tracking-tight  text-primary italic",itemProp:"headline",children:e.title2}),s.jsx("div",{className:"h-2 w-24 md:w-32 bg-cyan-400 mt-4 mx-auto lg:ml-0 lg:mr-0"}),s.jsx("p",{className:"mt-7 text-md sm:text-base lg:text-lg text-white mb-8 sm:mb-10 md:mb-12 leading-relaxed font-light",itemProp:"description",children:e.subt
3706itle})]}),s.jsx("div",{className:"flex justify-center items-center mt-8 lg:mt-0",children:s.jsx("video",{id:"productos-hero-video",src:"/video/video_productos.webm",className:"w-full max-w-xs sm:max-w-md lg:max-w-lg h-auto drop-shadow-2xl rounded-lg",autoPlay:!0,loop:!0,muted:!0,playsInline:!0,itemProp:"video",children:t("common.videoNoSoportado")})})]})})}),s.jsx(ie,{color:"#0a0e27",variant:1})]})}function ete(){const t=k.useRef(null),e=we(t,{once:!0,margin:"-100px"}),{t:a}=$();return s.jsx("section",{ref:t,className:"relative bg-dark py-16 sm:py-20 md:py-24 overflow-x-clip",children:s.jsxs("div",{className:"max-w-7xl mx-auto px-4 sm:px-6 md:px-8 text-center",children:[s.jsx(_.h2,{initial:{opacity:0,y:20},animate:e?{opacity:1,y:0}:{},transition:{duration:.6},className:"text-4xl md:text-5xl font-extrabold tracking-tight text-white pt-6",children:a("cicloTesting.titulo")}),s.jsx("div",{className:"h-2 w-24 md:w-32 bg-cyan-400 mt-4 mx-auto"}),s.jsx("p",{className:"pt-8 text-center text-md sm:text-base lg:text-lg text-gray-200 mb-4 leading-relaxed max-w-4xl mx-auto",children:a("cicloTesting.descripcion")}),s.jsx(Og,{showIntro:!1})]})})}function tte(){const{t}=$(),e=t("productos.hero",{returnObjects:!0});return s.jsx("section",{className:"relative bg-dark pt-20",children:s.jsxs("div",{className:"max-w-6xl mx-auto px-4 py-12 sm:py-16 md:py-20 text-center",children:[s.jsx("h2",{id:"productos-resumen-title",className:"text-4xl md:text-5xl font-extrabold tracking-tight text-white",itemProp:"headline",children:t("productos.titulo2")}),s.jsx("h2",{className:"text-4xl md:text-5xl font-extrabold tracking-tight text-primary",itemProp:"headline",children:e.title2})]})})}function ate(){const t=k.useRef(null),e=we(t,{once:!0,margin:"-100px"}),a=Qa(),{t:n}=$(),i=[{id:0,nombre:"HakaEngine",nombreCompleto:"Haka Automation Engine",imagen:"/imagenes/productos/card Automation Engine.png",descripcion:"Framework para pruebas Web, Mobile, Api e IA con mas de 1.800 steps preconstruidos e impulsado por IA",color:"from-emerald-600 to-cyan-500",borderColor:"border-emerald-400",ruta:"/haka-engine",aiPowered:!0},{id:1,nombre:"HakaAIStudio",nombreCompleto:"Haka AI Studio",imagen:"/imagenes/productos/Haka-AI-Studio.webp",descripcion:n("productos.hakaaistudio.descripcion"),color:"from-violet-600 to-blue-500",borderColor:"border-violet-400",ruta:"/haka-ai-studio",aiPowered:!0},{id:2,nombre:"Hakabuddy",nombreCompleto:"Haka Buddy",imagen:"/imagenes/productos/hakabuddy.webp",descripcion:n("productos.hakabuddy.descripcion"),color:"from-blue-600 to-blue-500",borderColor:"border-blue-500",ruta:"/hakabuddy",aiPowered:!0},{id:3,nombre:"Hakaboost",nombreCompleto:"Haka Boost",imagen:"/imagenes/productos/hakaboost_new.png",descripcion:n("productos.hakaboost.descripcion"),color:"from-blue-500 to-cyan-400",borderColor:"border-cyan-400",ruta:"/hakaboost",aiPowered:!0},{id:4,nombre:"Hakapath",nombreCompleto:"Haka Path",imagen:"/imagenes/productos/hakapath.webp",descripcion:n("productos.hakapath.descripcion"),color:"from-blue-500 to-cyan-400",borderColor:"border-cyan-400",ruta:"/hakapath",aiPowered:!0},{id:5,nombre:"Hakartc",nombreCompleto:"HakaRTC",imagen:"/imagenes/productos/hakartc.webp",descripcion:n("productos.hakartc.descripcion"),color:"from-blue-500 to-cyan-400",borderColor:"border-cyan-400",ruta:"/hakartc",aiPowered:!0},{id:6,nombre:"Hakatools",nombreCompleto:"Haka Tools",imagen:"/imagenes/productos/hakatools.webp",descripcion:n("productos.hakatools.descripcion"),color:"from-blue-600 to-blue-500",borderColor:"border-blue-500",ruta:"https://hakatools.hakalab.com/hakatools",external:!0,aiPowered:!1}];return s.jsxs("section",{ref:t,className:"relative bg-[#0a0e27] py-10 sm:py-10 md:py-1 mb-2",children:[s.jsx("div",{className:"max-w-7xl mx-auto px-4 sm:px-6 md:px-8",children:s.jsx("div",{className:"grid grid-cols-1 sm:grid-cols-2 lg:grid-cols-4 gap-6 md:gap-8 pb-10",children:i.map((r,o)=>s.jsx(_.div,{initial:{opacity:0,y:30},animate:e?{opacity:1,y:0}:{},transition:{duration:.5,delay:o*.1},className:"group cursor-pointer relative",onClick:()=>r.external?window.open(r.ruta,"_blank"):a(r.ruta),children:s.jsxs("div",{id:`productos-card-${r.nombre.toLowerCase()}`,className:`
3707                                relative bg-gradient-to-br ${r.color} 
3708                                rounded-3xl overflow-hidden
3709                                border-4 ${r.borderColor}
3710                                transition-all duration-300
3711                                hover:scale-105 hover:shadow-2xl hover:shadow-cyan-500/20
3712                                h-full flex flex-col
3713                            `,children:[s.jsx("div",{className:"relative h-56 sm:h-56 bg-gradient-to-b from-transparent to-black/20",children:s.jsx("img",{id:`productos-image-${r.nombre.toLowerCase()}`,src:r.imagen,alt:r.nombreCompleto,className:"w-full h-full object-cover drop-shadow-2xl"})}),s.jsxs("div",{className:"bg-[#0a0e27] p-6 flex flex-col flex-1",children:[s.jsx("p",{className:"text-gray-300 text-sm sm:text-base mb-6 leading-relaxed",children:r.descripcion}),s.jsx("div",{className:"flex-1"}),s.jsx("button",{id:`productos-button-${r.nombre.toLowerCase()}`,className:`
3714                                        w-full bg-cyan-400 hover:bg-cyan-500 
3715                                        text-[#0a0e27] font-bold 
3716                                        py-3 px-6 rounded-2xl
3717                                        transition-all duration-300
3718                                        hover:shadow-lg hover:shadow-cyan-400/50
3719                                        transform hover:-translate-y-1
3720                                    `,children:n("relatedProducts.saberMas")})]})]})},r.id))})}),s.jsx(ie,{variant:1})]})}function nte(){return s.jsxs("div",{className:"bg-dark",children:[s.jsx(Xa,{title:"Productos - Herramientas de IA para Testing",description:"HakaBoost, HakaBuddy, HakaPath, HakaLens y mas. Herramientas de inteligencia artificial para acelerar tu QA hasta un 70%.",path:"/productos"}),s.jsx(Zee,{}),s.jsx(tte,{}),s.jsx(ate,{}),s.jsx(ete,{})]})}function ite(){const t=k.useRef(null),e=we(t,{once:!0,margin:"-100px"}),{isOpen:a,modalTitle:n,closeModal:i}=oa(),{t:r}=$();return s.jsxs(s.Fragment,{children:[s.jsxs("section",{ref:t,className:"relative bg-dark pt-20 pb-16 text-center",children:[s.jsx("div",{className:"hero-glow"}),s.jsxs("div",{className:"max-w-1xl mx-auto px-4 sm:px-6 md:px-8",children:[s.jsx(_.div,{initial:{opacity:0,y:-30},animate:e?{opacity:1,y:0}:{},transition:{duration:.6},className:"flex justify-center mb-12",children:s.jsx("img",{src:"/imagenes/productos/hakaboostgif.gif",alt:"Hakaboost Interface",className:"w-full max-w-3xl h-auto drop-shadow-2xl"})}),s.jsxs(_.div,{initial:{opacity:0,y:30},animate:e?{opacity:1,y:0}:{},transition:{duration:.6,delay:.2},className:"max-w-3xl mx-auto w-full flex flex-col items-center justify-center",children:[s.jsx(_.img,{initial:{opacity:0,scale:.8},animate:e?{opacity:1,scale:1}:{},transition:{duration:.6,delay:.3},src:"/imagenes/productos/hakaboost_logo.png",alt:"Hakaboost Logo",className:"sm:w-full max-w-[300px] sm:max-w-md lg:max-w-lg h-auto drop-shadow-2xl object-contain"}),s.jsx(_.p,{initial:{opacity:0,y:20},animate:e?{opacity:1,y:0}:{},transition:{duration:.6,delay:.4},className:"text-2xl w-full mt-3",children:r("hakaboost.hero.descripcion")}),s.jsx(_.h1,{initial:{opacity:0,y:20},animate:e?{opacity:1,y:0}:{},transition:{duration:.6,delay:.5},className:"text-4xl font-bold text-white mt-3",children:r("hakaboost.hero.gratis")})]})]}
3720),s.jsx(ie,{color:"#0a0e27",variant:1})]}),s.jsx(Yr,{isOpen:a,onClose:i,title:n})]})}function rte(){const t=k.useRef(null),e=we(t,{once:!0,margin:"-100px"}),{t:a}=$();return s.jsx(s.Fragment,{children:s.jsx("section",{ref:t,className:" bg-gradient-to-b from-slate-950 to-blue-900 pt-11 pb-11 text-center mt-10",children:s.jsxs("div",{className:"max-w-1xl mx-auto px-4 sm:px-6 md:px-8 mt-10",children:[s.jsxs(_.div,{initial:{opacity:0,y:30},animate:e?{opacity:1,y:0}:{},transition:{duration:.6,delay:.2},className:"max-w-4xl mx-auto",children:[s.jsx(_.h2,{initial:{opacity:0,y:20},animate:e?{opacity:1,y:0}:{},transition:{duration:.6,delay:.5},className:"text-3xl font-bold text-white",children:a("hakaboost.presentacion.titulo")}),s.jsx("a",{href:"https://chromewebstore.google.com/detail/hakaboost-ai-for-quality/gcpcibcgheckokkooihbkgjpdbnolfcg",target:"_blank",rel:"noopener noreferrer",className:`
3721                                        inline-block w-48 bg-cyan-400 hover:bg-cyan-500 
3722                                        text-[#0a0e27] font-bold text-center
3723                                        py-3 rounded-full
3724                                        transition-all duration-300
3725                                        hover:shadow-lg hover:shadow-cyan-400/50
3726                                        transform hover:-translate-y-1
3727                                        mt-5
3728                                    `,children:a("hakaboost.descargar")})]}),s.jsx(_.div,{initial:{opacity:0,y:-30},animate:e?{opacity:1,y:0}:{},transition:{duration:.6},className:"flex justify-center mb-12 mt-10",children:s.jsx("img",{src:"/imagenes/productos/hakaboost_presentacion.gif",alt:"Hakaboost Interface",className:"w-full max-w-3xl h-auto drop-shadow-2xl"})})]})})})}function ote(){const{t}=$();return s.jsx(s.Fragment,{children:s.jsxs("section",{className:"relative bg-dark pt-5",children:[s.jsxs("div",{className:"max-w-7xl mx-auto px-4 py-12 sm:py-16 md:py-10",children:[s.jsx("h2",{className:"text-center text-3xl sm:text-3xl lg:text-4xl mb-4 sm:mb-6 md:mb-7 text-primary leading-tight sm:leading-snug",itemProp:"headline",children:t("hakaboost.potencia.titulo")}),s.jsx("p",{className:"text-center text-sm sm:text-base lg:text-lg text-gray-200 mb-8 sm:mb-10 md:mb-12 leading-relaxed font-light max-w-4xl mx-auto",children:t("hakaboost.potencia.descripcion")}),s.jsx("div",{className:"flex justify-center",children:s.jsx("a",{href:"https://chromewebstore.google.com/detail/hakaboost-ai-for-quality/gcpcibcgheckokkooihbkgjpdbnolfcg",target:"_blank",rel:"noopener noreferrer",className:`
3729                            inline-block w-48 bg-cyan-400 hover:bg-cyan-500 
3730                            text-[#0a0e27] font-bold text-center
3731                            py-3 rounded-full
3732                            transition-all duration-300
3733                            hover:shadow-lg hover:shadow-cyan-400/50
3734                            transform hover:-translate-y-1
3735                            mt-1
3736                        `,children:t("hakaboost.descargar")})})]}),s.jsx(ie,{color:"#0a0d29f5",variant:1})]})})}function ste(){const t=k.useRef(null),e=we(t,{once:!0,margin:"-100px"}),{t:a}=$(),n=a("hakaboost.queHace.features",{returnObjects:!0}),i=a("hakaboost.caracteristicas.items",{returnObjects:!0}),r=a("hakaboost.beneficios.items",{returnObjects:!0});return s.jsxs("section",{ref:t,className:"relative bg-dark pt-16 sm:pt-20 md:pt-24 pb-0",children:[s.jsxs("div",{className:"max-w-7xl mx-auto px-4 sm:px-6 md:px-8 mt-10",children:[s.jsxs("div",{className:"mb-20",children:[s.jsx(_.h2,{initial:{opacity:0,y:20},animate:e?{opacity:1,y:0}:{},transition:{duration:.6},className:"text-4xl font-bold text-white mb-8",children:a("hakaboost.queHace.titulo")}),s.jsxs("div",{className:"grid grid-cols-1 lg:grid-cols-2 gap-12 items-center",children:[s.jsxs(_.div,{initial:{opacity:0,x:-30},animate:e?{opacity:1,x:0}:{},transition:{duration:.6,delay:.2},children:[s.jsx("p",{className:"text-gray-200 mb-6 leading-relaxed",children:a("hakaboost.queHace.descripcion1")}),s.jsx("p",{className:"text-gray-200 mb-8 leading-relaxed",children:a("hakaboost.queHace.descripcion2")}),s.jsx("div",{className:"space-y-4",children:n.map((o,l)=>s.jsxs(_.div,{initial:{opacity:0,x:-20},animate:e?{opacity:1,x:0}:{},transition:{duration:.5,delay:.3+l*.1},className:"flex gap-3",children:[s.jsx("div",{className:"text-cyan-400 flex-shrink-0 mt-1",children:"✓"}),s.jsx("p",{className:"text-gray-200 text-md",children:o})]},l))})]}),s.jsx(_.div,{initial:{opacity:0,x:30},animate:e?{opacity:1,x:0}:{},transition:{duration:.6,delay:.2},className:"flex justify-center",children:s.jsx("img",{src:"/imagenes/productos/hakaboosk_quehace.gif",alt:a("hakaboost.queHace.titulo"),className:"w-full max-w-md h-auto"})})]})]}),s.jsx("div",{className:"mb-20",children:s.jsxs("div",{className:"grid grid-cols-1 lg:grid-cols-2 gap-12 items-start",children:[s.jsx(_.div,{initial:{opacity:0,x:-30},animate:e?{opacity:1,x:0}:{},transition:{duration:.6,delay:.5},className:"flex justify-center order-2 lg:order-1",children:s.jsx("img",{src:"/imagenes/productos/hakaboost_caracteristica.png",alt:a("hakaboost.caracteristicas.titulo"),className:"sm:w-full max-w-[200px] sm:max-w-md lg:max-w-lg h-auto drop-shadow-2xl object-contain"})}),s.jsxs(_.div,{initial:{opacity:0,x:30},animate:e?{opacity:1,x:0}:{},transition:{duration:.6,delay:.5},className:"space-y-4 order-1 lg:order-2",children:[s.jsx(_.h2,{initial:{opacity:0,y:20},animate:e?{opacity:1,y:0}:{},transition:{duration:.6,delay:.4},className:"text-4xl font-bold text-white mb-12 text-left",children:a("hakaboost.caracteristicas.titulo")}),i.map((o,l)=>s.jsxs(_.div,{initial:{opacity:0,x:20},animate:e?{opacity:1,x:0}:{},transition:{duration:.5,delay:.6+l*.1},className:"flex gap-3",children:[s.jsx("div",{className:"text-cyan-400 flex-shrink-0 mt-1",children:"✓"}),s.jsx("p",{className:"text-gray-300 text-md leading-relaxed",children:o})]},l))]})]})}),s.jsxs("div",{className:"mb-20",children:[s.jsx(_.h2,{initial:{opacity:0,y:20},animate:e?{opacity:1,y:0}:{},transition:{duration:.6},className:"text-4xl font-bold text-white mb-8",children:a("hakaboost.beneficios.titulo")}),s.jsxs("div",{className:"grid grid-cols-1 lg:grid-cols-2 gap-12 items-center",children:[s.jsxs(_.div,{initial:{opacity:0,x:-30},animate:e?{opacity:1,x:0}:{},transition:{duration:.6,delay:.2},children:[s.jsx("p",{className:"text-gray-200 mb-6 leading-relaxed",children:a("hakaboost.beneficios.descripcion")}),s.jsx("div",{className:"space-y-4",children:r.map((o,l)=>s.jsxs(_.div,{initial:{opacity:0,x:-20},animate:e?{opacity:1,x:0}:{},transition:{duration:.5,delay:.3+l*.1},className:"flex gap-3",children:[s.jsx("div",{className:"text-cyan-400 flex-shrink-0 mt-1",children:"✓"}),s.jsx("p",{className:"text-gray-200 text-md",children:o})]},l))})]}),s.jsx(_.div,{initial:{opacity:0,x:30},animate:e?{opacity:1,x:0}:{},transition:{duration:.6,delay:.2},className:"flex justify-center",children:s.jsx("img",{src:"/imagenes/productos/hakaboost_beneficios.png",alt:a("hakaboost.beneficios.titulo"),className:"w-full max-w-md h-auto"})})]})]})]}),s.jsx(ie,{variant:1})]})}function lte(){const t=k.useRef(null),e=we(t,{once:!0,margin:"-100px"}),[a,n]=k.useState(0),{t:i}=$(),r=i("faq.items",{returnObjects:!0});return s.jsxs("section",{ref:t,className:"relative bg-dark py-10 sm:py-20 md:py-20",children:[s.jsx("div",{className:"hero-glow"}),s.jsxs("div",{className:"max-w-4xl mx-auto px-4 sm:px-6 md:px-8",children:[s.jsxs(_.div,{initial:{opacity:0,y:20},animate:e?{opacity:1,y:0}:{},transition:{duration:.6},className:"text-center mb-16",children:[s.jsx("h2",{className:"text-4xl font-bold text-white mb-4",children:i("faq.titulo")}),s.jsx("p",{className:"text-gray-300 text-lg",children:i("faq.subtitulo")})]}),s.jsx("div",{className:"space-y-4",children:r.map((o,l)=>s.jsxs(_.div,{initial:{opacity:0,y:10},animate:e?{opacity:1,y:0}:{},transition:{duration:.5,delay:l*.05},className:"border border-primary/20 rounded-lg overflow-hidden hover:border-primary/50 transition-colors",children:[s.jsxs("button",{onClick:()=>n(a===l?-1:l),className:"w-full px-6 py-4 flex items-center justify-between bg-slate-800/30 hover:bg-slate-800/50 transition-colors",children:[s.jsx("h3",{className:"text-lg font-semibold text-white text-left",children:o.question}),s.jsx(_.div,{animate:{rotate:a===l?180:0},transition:{duration:.3},className:"flex-shrink-0 ml-4",children:s.jsx("svg",{className:"w-6 h-6 text-primary",fill:"none",viewBox:"0 0 24 24",stroke:"currentColor",children:s.jsx("path",{strokeLinecap:"round",strokeLinejoin:"round",strokeWidth:2,d:"M19 14l-7 7m0 0l-7-7m7 7V3"})})})]}),s.jsx(_.div,{initial:{height:0,opacity:0}
3736,animate:{height:a===l?"auto":0,opacity:a===l?1:0},transition:{duration:.3},className:"overflow-hidden",children:s.jsx("div",{className:"px-6 py-4 bg-slate-900/50 border-t border-primary/10",children:s.jsx("p",{className:"text-gray-300 leading-relaxed",children:o.answer})})})]},l))})]}),s.jsx(ie,{color:"#0a0e27",variant:1})]})}function Zr({title:t,productIds:e=[2,3,4,5],showWaveDivider:a=!0}){const n=k.useRef(null),i=we(n,{once:!0,margin:"-100px"}),r=Qa(),{t:o}=$(),l=t||o("relatedProducts.title"),c={1:{id:1,nombre:"Hakaboost",nombreCompleto:"Haka Boost",imagen:"/imagenes/productos/hakaboost_new.png",descripcion:o("productos.hakaboost.descripcion"),color:"from-blue-500 to-cyan-400",borderColor:"border-cyan-400",ruta:"/hakaboost"},2:{id:2,nombre:"Hakabuddy",nombreCompleto:"Haka Buddy",imagen:"/imagenes/productos/hakabuddy.webp",descripcion:o("productos.hakabuddy.descripcion"),color:"from-blue-600 to-blue-500",borderColor:"border-blue-500",ruta:"/hakabuddy"},3:{id:3,nombre:"Hakapath",nombreCompleto:"Haka Path",imagen:"/imagenes/productos/hakapath.webp",descripcion:o("productos.hakapath.descripcion"),color:"from-blue-500 to-cyan-400",borderColor:"border-cyan-400",ruta:"/hakapath"}
3736,4:{id:4,nombre:"Hakatools",nombreCompleto:"Haka Tools",imagen:"/imagenes/productos/hakatools.webp",descripcion:o("productos.hakatools.descripcion"),color:"from-blue-600 to-blue-500",borderColor:"border-blue-500",ruta:"https://hakatools.hakalab.com/hakatools",external:!0},5:{id:5,nombre:"Hakartc",nombreCompleto:"HakaRTC",imagen:"/imagenes/productos/hakartc.webp",descripcion:o("productos.hakartc.descripcion"),color:"from-blue-500 to-cyan-400",borderColor:"border-cyan-400",ruta:"/hakartc"},6:{id:6,nombre:"HakaEngine",nombreCompleto:"Haka Automation Engine",imagen:"/imagenes/productos/card Automation Engine.png",descripcion:"",color:"from-emerald-600 to-cyan-500",borderColor:"border-emerald-400",ruta:"/haka-engine"}},d=e.map(u=>c[u]).filter(Boolean);return s.jsxs("section",{ref:n,className:"relative bg-[#0a0e27] py-16 sm:py-20 md:py-24",children:[s.jsxs("div",{className:"max-w-7xl mx-auto px-4 sm:px-6 md:px-8 mt-10",children:[s.jsx(_.div,{initial:{opacity:0,y:-20},animate:i?{opacity:1,y:0}:{},transition:{duration:.6},className:"text-center mb-12 sm:mb-16",children:s.jsx("h2",{className:"text-3xl sm:text-4xl font-bold text-primary",children:l})}),s.jsx("div",{className:"grid grid-cols-1 sm:grid-cols-2 lg:grid-cols-4 gap-6 md:gap-8",children:d.map((u,p)=>s.jsx(_.div,{initial:{opacity:0,y:30},animate:i?{opacity:1,y:0}:{},transition:{duration:.5,delay:p*.1},className:"group cursor-pointer",onClick:()=>{u.external?window.open(u.ruta,"_blank"):r(u.ruta)},children:s.jsxs("div",{className:`
3737                                relative bg-gradient-to-br ${u.color} 
3738                                rounded-3xl overflow-hidden
3739                                border-4 ${u.borderColor}
3740                                transition-all duration-300
3741                                hover:scale-105 hover:shadow-2xl hover:shadow-cyan-500/20
3742                                flex flex-col
3743                            `,children:[s.jsx("div",{className:"relative aspect-[4/3] bg-gradient-to-b from-transparent to-black/20",children:s.jsx("img",{src:u.imagen,alt:u.nombreCompleto,className:"w-full h-full object-cover drop-shadow-2xl"})}),s.jsxs("div",{className:"bg-[#0a0e27] p-6 flex flex-col flex-grow",children:[s.jsxs("h3",{className:"text-2xl sm:text-3xl font-bold mb-3",children:[s.jsx("span",{className:"text-cyan-400",children:"Haka"}),s.jsx("span",{className:"text-white",children:u.nombre.replace("Haka","")})]}),s.jsx("p",{className:"text-gray-300 text-sm sm:text-base mb-6 leading-relaxed flex-grow",children:u.descripcion}),s.jsx("button",{className:`
3744                                        w-full bg-cyan-400 hover:bg-cyan-500 
3745                                        text-[#0a0e27] font-bold 
3746                                        py-3 px-6 rounded-2xl
3747                                        transition-all duration-300
3748                                        hover:shadow-lg hover:shadow-cyan-400/50
3749                                        transform hover:-translate-y-1
3750                                    `,children:o("relatedProducts.saberMas")})]})]})},u.id))})]}),a&&s.jsx(ie,{color:"#0a0e27",variant:1})]})}function cte(){return s.jsxs("div",{className:"bg-dark",children:[s.jsx(Xa,{title:"HakaBoost - Copiloto de Calidad con IA para Jira y Azure DevOps",description:"Extension de Chrome que acelera la creacion de tests hasta un 70% con IA. Genera escenarios Gherkin, mejora descripciones y crea tests automaticamente.",path:"/hakaboost"}),s.jsx(ite,{}),s.jsx(rte,{}),s.jsx(ote,{}),s.jsx(ste,{}),s.jsx(lte,{}),s.jsx(Zr,{productIds:[2,3,4,5,6]})]})}function dte(){const t=k.useRef(null),e=we(t,{once:!0,margin:"-100px"}),{t:a}=$();return s.jsxs("section",{ref:t,className:"relative bg-dark pt-1 pb-2 text-center",children:[s.jsx("div",{className:"hero-glow"}),s.jsxs("div",{className:"max-w-1xl mx-auto px-4 sm:px-6 md:px-8",children:[s.jsx(_.div,{initial:{opacity:0,y:-30},animate:e?{opacity:1,y:0}:{},transition:{duration:.6},className:"flex justify-center mb-12",children:s.jsx("img",{src:"/imagenes/productos/HakaBuddy v3.gif",alt:"HakaBuddy Interface",className:"w-full max-w-3xl h-auto drop-shadow-2xl"})}),s.jsxs(_.div,{initial:{opacity:0,y:30},animate:e?{opacity:1,y:0}:{},transition:{duration:.6,delay:.2},className:"max-w-3xl mx-auto w-full flex flex-col items-center justify-center",children:[s.jsx(_.img,{initial:{opacity:0,scale:.8},animate:e?{opacity:1,scale:1}:{},transition:{duration:.6,delay:.3},src:"/imagenes/productos/hakabuddy_logo.png",alt:"Hakaboost Logo",className:"sm:w-full max-w-[300px] sm:max-w-md lg:max-w-lg h-auto drop-shadow-2xl object-contain"}),s.jsx(_.p,{initial:{opacity:0,y:20},animate:e?{opacity:1,y:0}:{},transition:{duration:.6,delay:.4},className:"text-2xl w-full",children:a("hakabuddy.hero.descripcion")}),s.jsx(_.h1,{initial:{opacity:0,y:20},animate:e?{opacity:1,y:0}:{},transition:{duration:.6,delay:.5},className:"text-4xl font-bold text-white mb-8 mt-3",children:a("hakabuddy.hero.gratis")})]})]}
3750),s.jsx(ie,{color:"#0a0e27",variant:1})]})}function ute(){const t=k.useRef(null),e=we(t,{once:!0,margin:"-100px"}),{t:a}=$();return s.jsx(s.Fragment,{children:s.jsx("section",{ref:t,className:"relative bg-gradient-to-b from-slate-950 to-blue-900 pt-11 pb-11 text-center mt-10",children:s.jsxs("div",{className:"max-w-1xl mx-auto px-4 sm:px-6 md:px-8 mt-10",children:[s.jsx(_.div,{initial:{opacity:0,y:30},animate:e?{opacity:1,y:0}:{},transition:{duration:.6,delay:.2},className:"max-w-4xl mx-auto",children:s.jsx(_.h2,{initial:{opacity:0,y:20},animate:e?{opacity:1,y:0}:{},transition:{duration:.6,delay:.5},className:"text-3xl font-bold text-white",children:a("hakabuddy.presentacion.titulo")})}),s.jsx(_.div,{initial:{opacity:0,y:-30},animate:e?{opacity:1,y:0}:{},transition:{duration:.6},className:"flex justify-center mb-12 mt-10",children:s.jsx("img",{src:"/imagenes/productos/hakabuddygif2.gif",alt:"Hakaboost Interface",className:"w-full max-w-3xl h-auto drop-shadow-2xl"})})]})})})}function pte(){const t=k.useRef(null),e=we(t,{once:!0,margin:"-100px"}),{t:a}=$(),n=a("hakabuddy_queHace.features",{returnObjects:!0}),i=a("hakabuddy_queHace.caracteristicasItems",{returnObjects:!0}),r=a("hakabuddy_queHace.beneficiosItems",{returnObjects:!0});return s.jsxs("section",{ref:t,className:"relative bg-dark pt-16 sm:pt-20 md:pt-10 pb-0",children:[s.jsx("div",{className:"hero-glow"}),s.jsxs("div",{className:"max-w-7xl mx-auto px-4 sm:px-6 md:px-8 mt-10",children:[s.jsxs("div",{className:"mb-20",children:[s.jsx(_.h2,{initial:{opacity:0,y:20},animate:e?{opacity:1,y:0}:{},transition:{duration:.6},className:"text-4xl font-bold text-white",children:a("hakabuddy_queHace.titulo")}),s.jsxs("div",{className:"grid grid-cols-1 lg:grid-cols-2 gap-12 items-center",children:[s.jsxs(_.div,{initial:{opacity:0,x:-30},animate:e?{opacity:1,x:0}:{},transition:{duration:.6,delay:.2},children:[s.jsx("p",{className:"text-gray-200 mb-6 leading-relaxed",children:a("hakabuddy_queHace.descripcion")}),s.jsx("div",{className:"space-y-4",children:n.map((o,l)=>s.jsxs(_.div,{initial:{opacity:0,x:-20},animate:e?{opacity:1,x:0}:{},transition:{duration:.5,delay:.3+l*.1},className:"flex gap-3",children:[s.jsx("div",{className:"text-cyan-400 flex-shrink-0 mt-1",children:"✓"}),s.jsx("p",{className:"text-gray-200 text-md",children:o})]},l))})]}),s.jsx(_.div,{initial:{opacity:0,x:30},animate:e?{opacity:1,x:0}:{},transition:{duration:.6,delay:.2},className:"flex justify-center",children:s.jsx("img",{src:"/imagenes/productos/quehacehakabuddy.png",alt:"¿Qué hace Hakaboost?",className:"w-full max-w-md h-auto"})})]})]}),s.jsx("div",{className:"mb-20",children:s.jsxs("div",{className:"grid grid-cols-1 lg:grid-cols-2 gap-12 items-start",children:[s.jsx(_.div,{initial:{opacity:0,x:-30},animate:e?{opacity:1,x:0}:{},transition:{duration:.6,delay:.5},className:"flex justify-center order-2 lg:order-1",children:s.jsx("img",{src:"/imagenes/productos/hakabuddy_quehace.gif",alt:"Características",className:"w-full max-w-md h-auto"})}),s.jsxs(_.div,{initial:{opacity:0,x:30},animate:e?{opacity:1,x:0}:{},transition:{duration:.6,delay:.5},className:"space-y-4 order-1 lg:order-2",children:[s.jsx(_.h2,{initial:{opacity:0,y:20},animate:e?{opacity:1,y:0}:{},transition:{duration:.6,delay:.4},className:"text-4xl font-bold text-white mb-12 text-left",children:a("hakabuddy_queHace.caracteristicas")}),i.map((o,l)=>s.jsxs(_.div,{initial:{opacity:0,x:20},animate:e?{opacity:1,x:0}:{},transition:{duration:.5,delay:.6+l*.1},className:"flex gap-3",children:[s.jsx("div",{className:"text-cyan-400 flex-shrink-0 mt-1",children:"✓"}),s.jsx("p",{className:"text-gray-300 text-md leading-relaxed",children:o})]},l))]})]})}),s.jsxs("div",{className:"mb-20",children:[s.jsx(_.h2,{initial:{opacity:0,y:20},animate:e?{opacity:1,y:0}:{},transition:{duration:.6},className:"text-4xl font-bold text-white mb-8",children:a("hakabuddy_queHace.beneficios")}),s.jsxs("div",{className:"grid grid-cols-1 lg:grid-cols-2 gap-12 items-center",children:[s.jsxs(_.div,{initial:{opacity:0,x:-30},animate:e?{opacity:1,x:0}:{},transition:{duration:.6,delay:.2},children:[s.jsx("p",{className:"text-gray-200 mb-6 leading-relaxed",children:a("hakabuddy_queHace.beneficiosDescripcion")}),s.jsx("div",{className:"space-y-4",children:r.map((o,l)=>s.jsxs(_.div,{initial:{opacity:0,x:-20},animate:e?{opacity:1,x:0}:{},transition:{duration:.5,delay:.3+l*.1},className:"flex gap-3",children:[s.jsx("div",{className:"text-cyan-400 flex-shrink-0 mt-1",children:"✓"}),s.jsx("p",{className:"text-gray-200 text-md",children:o})]},l))})]}),s.jsx(_.div,{initial:{opacity:0,x:30},animate:e?{opacity:1,x:0}:{},transition:{duration:.6,delay:.2},className:"flex justify-center",children:s.jsx("img",{src:"/imagenes/productos/hakabuddy2.png",alt:"¿Qué hace Hakaboost?",className:"w-full max-w-md h-auto"})})]})]})]}),s.jsx(ie,{variant:1})]})}function mte({isOpen:t,onClose:e}){const{t:a}=$();return s.jsx(La,{children:t&&s.jsx(s.Fragment,{children:s.jsx(_.div,{initial:{opacity:0}
3750,animate:{opacity:1},exit:{opacity:0},onClick:e,className:"fixed inset-0 bg-black/70 backdrop-blur-sm z-50 flex items-center justify-center p-4",children:s.jsxs(_.div,{initial:{opacity:0,scale:.95,y:20},animate:{opacity:1,scale:1,y:0},exit:{opacity:0,scale:.95,y:20},onClick:n=>n.stopPropagation(),className:"bg-[#1a1d3a] rounded-3xl shadow-2xl max-w-md w-full relative overflow-hidden",children:[s.jsx("div",{className:"absolute top-0 right-0 w-64 h-64 bg-cyan-500/10 rounded-full blur-3xl"}),s.jsx("div",{className:"absolute bottom-0 left-0 w-64 h-64 bg-green-500/10 rounded-full blur-3xl"}),s.jsxs("div",{className:"relative p-8 sm:p-10 text-center",children:[s.jsx(_.div,{initial:{scale:0},animate:{scale:1},transition:{delay:.2,type:"spring",stiffness:200},className:"mb-6 flex justify-center",children:s.jsx("div",{className:"w-16 h-16 bg-gradient-to-br from-green-400 to-green-500 rounded-full flex items-center justify-center",children:s.jsx("svg",{className:"w-8 h-8 text-white",fill:"none",viewBox:"0 0 24 24",stroke:"currentColor",children:s.jsx("path",{strokeLinecap:"round",strokeLinejoin:"round",strokeWidth:3,d:"M5 13l4 4L19 7"})})})}),s.jsx(_.h2,{initial:{opacity:0,y:10},animate:{opacity:1,y:0},transition:{delay:.3},className:"text-2xl sm:text-3xl font-bold text-white mb-4",children:a("descargaExitoModal.titulo")}),s.jsx(_.p,{initial:{opacity:0,y:10},animate:{opacity:1,y:0},transition:{delay:.4},className:"text-gray-300 mb-6 leading-relaxed",children:a("descargaExitoModal.mensaje")}),s.jsx(_.p,{initial:{opacity:0,y:10},animate:{opacity:1,y:0},transition:{delay:.5},className:"text-sm text-gray-400 mb-8",children:a("descargaExitoModal.submensaje")}),s.jsx(_.div,{initial:{opacity:0}
3750,animate:{opacity:1},transition:{delay:.6},className:"flex justify-center gap-2 mb-8",children:[0,1,2].map(n=>s.jsx(_.div,{animate:{y:[0,-8,0]},transition:{duration:.6,delay:n*.1,repeat:1/0},className:"w-2 h-2 bg-cyan-400 rounded-full"},n))}),s.jsx(_.button,{initial:{opacity:0},animate:{opacity:1},transition:{delay:.7},onClick:e,className:"w-full bg-gradient-to-r from-cyan-400 to-blue-500 hover:from-cyan-500 hover:to-blue-600 text-white font-bold py-3 px-6 rounded-xl transition-all duration-300 hover:shadow-lg hover:shadow-cyan-400/50 border-2 border-cyan-400",children:a("descargaExitoModal.boton")})]})]})})})})}function hte(){const t=k.useRef(null),e=we(t,{once:!0,margin:"-100px"}),{t:a}=$(),[n,i]=k.useState({nombre:"",email:"",cargo:"",empresa:"",sistemaOperativo:"",aceptaTerminos:!1}),[r,o]=k.useState(!1),[l,c]=k.useState(null),[d,u]=k.useState(!1),p=h=>{const{name:g,value:y,type:x,checked:v}=h.target;console.log(`Campo: ${g}, Tipo: ${x}, Valor: ${v||y}`),i({...n,[g]:x==="checkbox"?v:y}),g==="aceptaTerminos"&&v&&c(null)},m=async h=>{if(h.preventDefault(),!n.aceptaTerminos){c("error");return}o(!0),c(null);try{await Tl(ga(St,"mail"),{to:["[email protected]"],message:{subject:"Nueva descarga de HakaBuddy",html:`
3751                        <div style="font-family: Arial, sans-serif; max-width: 600px; margin: 0 auto;">
3752                            <h2 style="color: #06b6d4;">Nueva descarga de HakaBuddy</h2>
3753                            <div style="background: #f3f4f6; padding: 20px; border-radius: 8px; margin: 20px 0;">
3754                                <p><strong>Nombre:</strong> ${n.nombre}</p>
3755                                <p><strong>Email:</strong> ${n.email}</p>
3756                                <p><strong>Cargo:</strong> ${n.cargo}</p>
3757                                <p><strong>Empresa:</strong> ${n.empresa}</p>
3758                                <p><strong>Sistema Operativo:</strong> ${n.sistemaOperativo}</p>
3759                            </div>
3760                            <p style="color: #6b7280; font-size: 12px;">Registro desde el formulario de descarga de hakalab.com</p>
3761                        </div>
3762                    `},timestamp:new Date}),u(!0),setTimeout(async()=>{const g={windows:"/descargas/version3.2.0.2/Hakabuddy-3.2.0.2-Windows.zip",mac:"/descargas/version3.2.0.2/Hakabuddy-3.2.0.2-OSX.zip",linux:"/descargas/version3.2.0.2/Hakabuddy-3.2.0.2-Linux.zip"},y=g[n.sistemaOperativo]||g.windows;try{const x=await fetch(y);if(!x.ok)throw new Error(`HTTP error! status: ${x.status}`);const v=await x.blob(),w=document.createElement("a");w.href=URL.createObjectURL(v),w.download=y.split("/").pop(),document.body.appendChild(w),w.click(),document.body.removeChild(w),URL.revokeObjectURL(w.href)}catch(x){console.error("Error descargando archivo:",x)}},1e3),c("success"),i({nombre:"",email:"",cargo:"",empresa:"",sistemaOperativo:"",aceptaTerminos:!1}),setTimeout(()=>{c(null)},3e3)}catch(g){console.error("Error al enviar:",g),c("error")}finally{o(!1)}};return s.jsxs("section",{ref:t,className:"relative bg-dark py-16 sm:py-20 md:py-24",children:[s.jsx("div",{className:"max-w-7xl mx-auto px-4 sm:px-6 md:px-8",children:s.jsxs("div",{className:"relative rounded-3xl overflow-hidden",children:[s.jsx("div",{className:"absolute top-0 right-0 w-96 h-96 bg-cyan-500/10 rounded-full blur-3xl -z-10"}),s.jsx("div",{className:"absolute bottom-0 left-0 w-96 h-96 bg-blue-500/10 rounded-full blur-3xl -z-10"}),s.jsx("div",{className:"absolute inset-0 bg-gradient-to-br from-slate-800/40 to-slate-900/40 backdrop-blur-xl border border-white/10 rounded-3xl shadow-2xl shadow-cyan-500/20"}),s.jsx("div",{className:"relative p-8 sm:p-12 md:p-16",children:s.jsxs("div",{className:"grid grid-cols-1 lg:grid-cols-2 gap-12 items-center",children:[s.jsxs(_.div,{initial:{opacity:0,x:-30},animate:e?{opacity:1,x:0}:{},transition:{duration:.6},className:"max-w-3xl mx-auto w-full flex flex-col items-center justify-center",children:[s.jsx("h2",{className:"text-4xl sm:text-5xl font-bold text-white mb-6",children:a("hakabuddy.title")}),s.jsx("p",{className:"text-lg text-gray-300 leading-relaxed",children:a("hakabuddy.subtitle")}),s.jsx("img",{src:"/imagenes/productos/hakaboost_caracteristica.png",alt:"¿Qué hace Hakaboost?",className:"sm:w-full max-w-[150px] sm:max-w-md lg:max-w-lg h-auto drop-shadow-2xl object-contain"})]}),s.jsx(_.div,{initial:{opacity:0,x:30},animate:e?{opacity:1,x:0}:{},transition:{duration:.6,delay:.2},className:"bg-gradient-to-br from-slate-700/30 to-slate-800/30 rounded-2xl p-8 border border-cyan-400/20 backdrop-blur-md shadow-2xl shadow-cyan-500/10",children:s.jsxs("form",{onSubmit:m,className:"space-y-5",children:[s.jsxs("div",{children:[s.jsxs("label",{htmlFor:"nombre",className:"block text-gray-300 mb-2 font-medium text-sm",children:[a("hakabuddy.nombre")," ",s.jsx("span",{className:"text-cyan-400",children:"*"})]}),s.jsx("input",{type:"text",id:"nombre",name:"nombre",value:n.nombre,onChange:p,required:!0,placeholder:a("hakabuddy.nombrePlaceholder"),className:"w-full bg-slate-700/50 text-white px-4 py-2.5 rounded-lg border border-cyan-400/20 focus:border-cyan-400 focus:outline-none transition-all placeholder-gray-500 text-sm backdrop-blur-sm hover:border-cyan-400/40"})]}),s.jsxs("div",{children:[s.jsxs("label",{htmlFor:"email",className:"block text-gray-300 mb-2 font-medium text-sm",children:[a("contactModal.email")," ",s.jsx("span",{className:"text-cyan-400",children:"*"})]}),s.jsx("input",{type:"email",id:"email",name:"email",value:n.email,onChange:p,required:!0,placeholder:"[email protected]",className:"w-full bg-slate-700/50 text-white px-4 py-2.5 rounded-lg border border-cyan-400/20 focus:border-cyan-400 focus:outline-none transition-all placeholder-gray-500 text-sm backdrop-blur-sm hover:border-cyan-400/40"})]}),s.jsxs("div",{children:[s.jsxs("label",{htmlFor:"cargo",className:"block text-gray-300 mb-2 font-medium text-sm",children:[a("hakabuddy.cargo")," ",s.jsx("span",{className:"text-cyan-400",children:"*"})]}),s.jsx("input",{type:"text",id:"cargo",name:"cargo",value:n.cargo,onChange:p,required:!0,placeholder:a("hakabuddy.cargoPlaceholder"),className:"w-full bg-slate-700/50 text-white px-4 py-2.5 rounded-lg border border-cyan-400/20 focus:border-cyan-400 focus:outline-none transition-all placeholder-gray-500 text-sm backdrop-blur-sm hover:border-cyan-400/40"})]}),s.jsxs("div",{children:[s.jsxs("label",{htmlFor:"empresa",className:"block text-gray-300 mb-2 font-medium text-sm",children:[a("contactModal.empresa")," ",s.jsx("span",{className:"text-cyan-400",children:"*"})]}),s.jsx("input",{type:"text",id:"empresa",name:"empresa",value:n.empresa,onChange:p,required:!0,placeholder:a("hakabuddy.empresaPlaceholder"),className:"w-full bg-slate-700/50 text-white px-4 py-2.5 rounded-lg border border-cyan-400/20 focus:border-cyan-400 focus:outline-none transition-all placeholder-gray-500 text-sm backdrop-blur-sm hover:border-cyan-400/40"})]}),s.jsxs("div",{children:[s.jsxs("label",{htmlFor:"sistemaOperativo",className:"block text-gray-300 mb-2 font-medium text-sm",children:[a("hakabuddy.sistemaOperativo")," ",s.jsx("span",{className:"text-cyan-400",children:"*"})]}),s.jsxs("select",{id:"sistemaOperativo",name:"sistemaOperativo",value:n.sistemaOperativo,onChange:p,required:!0,className:"w-full bg-slate-700/50 text-white px-4 py-2.5 rounded-lg border border-cyan-400/20 focus:border-cyan-400 focus:outline-none transition-all text-sm backdrop-blur-sm hover:border-cyan-400/40",children:[s.jsx("option",{value:"",children:a("hakabuddy.sistemaOperativoPlaceholder")}),s.jsx("option",{value:"windows",children:"Windows"}),s.jsx("option",{value:"mac",children:"macOS"}),s.jsx("option",{value:"linux",children:"Linux"})]})]}),s.jsxs("div",{className:"flex items-start gap-3 pt-2",children:[s.jsx("input",{type:"checkbox",id:"aceptaTerminos",name:"aceptaTerminos",checked:n.aceptaTerminos,onChange:p,className:"mt-1 w-4 h-4 accent-cyan-400 cursor-pointer"}),s.jsxs("label",{htmlFor:"aceptaTerminos",className:"text-gray-300 text-sm cursor-pointer",children:[a("hakabuddy.aceptaTerminos")," ",s.jsx("span",{className:"text-cyan-400",children:"*"})]})]}),l==="success"&&s.jsx(_.div,{initial:{opacity:0,y:-10}
3762,animate:{opacity:1,y:0},className:"bg-green-500/20 border border-green-500 text-green-400 px-4 py-3 rounded-lg text-sm backdrop-blur-sm",children:a("hakabuddy.exitoDescarga")}),l==="error"&&s.jsx(_.div,{initial:{opacity:0,y:-10},animate:{opacity:1,y:0},className:"bg-red-500/20 border border-red-500 text-red-400 px-4 py-3 rounded-lg text-sm backdrop-blur-sm",children:a("hakabuddy.errorDescarga")}),s.jsx("button",{type:"submit",disabled:r,className:"w-full bg-gradient-to-r from-cyan-400 to-blue-500 hover:from-cyan-500 hover:to-blue-600 text-white font-bold py-3 px-6 rounded-lg transition-all duration-300 hover:shadow-lg hover:shadow-cyan-400/50 disabled:opacity-50 disabled:cursor-not-allowed border-2 border-cyan-400 mt-6 transform hover:-translate-y-0.5",children:r?s.jsxs("span",{className:"flex items-center justify-center gap-2",children:[s.jsxs("svg",{className:"animate-spin h-5 w-5",viewBox:"0 0 24 24",children:[s.jsx("circle",{className:"opacity-25",cx:"12",cy:"12",r:"10",stroke:"currentColor",strokeWidth:"4",fill:"none"}),s.jsx("path",{className:"opacity-75",fill:"currentColor",d:"M4 12a8 8 0 018-8V0C5.373 0 0 5.373 0 12h4zm2 5.291A7.962 7.962 0 014 12H0c0 3.042 1.135 5.824 3 7.938l3-2.647z"})]}),a("hakabuddy.descargando")]}):a("hakabuddy.descargar")})]})})]})})]})}),s.jsx(ie,{color:"#0a0e27",variant:1}),s.jsx(mte,{isOpen:d,onClose:()=>u(!1)})]})}function fte(){const t=k.useRef(null),e=we(t,{once:!0,margin:"-100px"}),[a,n]=k.useState(0),{t:i}=$(),r=i("hakabuddy_faq.items",{returnObjects:!0});return s.jsxs("section",{ref:t,className:"relative bg-dark py-10 sm:py-20 md:py-20  mt-10",children:[s.jsx("div",{className:"hero-glow"}),s.jsxs("div",{className:"max-w-4xl mx-auto px-4 sm:px-6 md:px-8  mt-10",children:[s.jsxs(_.div,{initial:{opacity:0,y:20},animate:e?{opacity:1,y:0}:{},transition:{duration:.6},className:"text-center mb-16",children:[s.jsx("h2",{className:"text-4xl font-bold text-white mb-4",children:i("hakabuddy_faq.titulo")}),s.jsx("p",{className:"text-gray-300 text-lg",children:i("hakabuddy_faq.subtitulo")})]}),s.jsx("div",{className:"space-y-4",children:r.map((o,l)=>s.jsxs(_.div,{initial:{opacity:0,y:10},animate:e?{opacity:1,y:0}:{},transition:{duration:.5,delay:l*.05},className:"border border-primary/20 rounded-lg overflow-hidden hover:border-primary/50 transition-colors",children:[s.jsxs("button",{onClick:()=>n(a===l?-1:l),className:"w-full px-6 py-4 flex items-center justify-between bg-slate-800/30 hover:bg-slate-800/50 transition-colors",children:[s.jsx("h3",{className:"text-lg font-semibold text-white text-left",children:o.question}),s.jsx(_.div,{animate:{rotate:a===l?180:0},transition:{duration:.3},className:"flex-shrink-0 ml-4",children:s.jsx("svg",{className:"w-6 h-6 text-primary",fill:"none",viewBox:"0 0 24 24",stroke:"currentColor",children:s.jsx("path",{strokeLinecap:"round",strokeLinejoin:"round",strokeWidth:2,d:"M19 14l-7 7m0 0l-7-7m7 7V3"})})})]}),s.jsx(_.div,{initial:{height:0,opacity:0},animate:{height:a===l?"auto":0,opacity:a===l?1:0},transition:{duration:.3},className:"overflow-hidden",children:s.jsx("div",{className:"px-6 py-4 bg-slate-900/50 border-t border-primary/10",children:s.jsx("p",{className:"text-gray-300 leading-relaxed",children:o.answer})})})]},l))})]}),s.jsx(ie,{color:"#0a0e27",variant:1})]})}function gte(){return s.jsxs("div",{className:"bg-dark",children:[s.jsx(Xa,{title:"HakaBuddy - Reportes de Testing con IA",description:"Herramienta de escritorio para generacion de reportes de testing con IA. Crea reportes manuales de forma inteligente en Windows y Mac.",path:"/hakabuddy"}),s.jsx(dte,{}),s.jsx(ute,{}),s.jsx(pte,{}),s.jsx(hte,{}),s.jsx(fte,{}),s.jsx(Zr,{title:"También te podría interesar",productIds:[1,3,4,5,6]})]})}function yte(){const{t}=$(),e=k.useRef(null),a=we(e,{once:!0,margin:"-100px"});return s.jsx(s.Fragment,{children:s.jsxs("section",{ref:e,className:"relative bg-dark pt-1 pb-2 text-center",children:[s.jsx("div",{className:"hero-glow"}),s.jsxs("div",{className:"max-w-1xl mx-auto px-4 sm:px-6 md:px-8",children:[s.jsx(_.div,{initial:{opacity:0,y:-30},animate:a?{opacity:1,y:0}:{},transition:{duration:.6},className:"flex justify-center mb-12",children:s.jsx("img",{src:"/imagenes/productos/hakapathgif.gif",alt:"Hakaboost Interface",className:"w-full max-w-3xl h-auto drop-shadow-2xl"})}),s.jsxs(_.div,{initial:{opacity:0,y:30},animate:a?{opacity:1,y:0}:{},transition:{duration:.6,delay:.2},className:"max-w-3xl mx-auto w-full flex flex-col items-center justify-center",children:[s.jsx(_.img,{initial:{opacity:0,scale:.8},animate:a?{opacity:1,scale:1}:{},transition:{duration:.6,delay:.3},src:"/imagenes/productos/hakapath_logo.png",alt:"Hakaboost Logo",className:"sm:w-full max-w-[300px] sm:max-w-md lg:max-w-lg h-auto drop-shadow-2xl object-contain"}),s.jsx(_.p,{initial:{opacity:0,y:20},animate:a?{opacity:1,y:0}:{},transition:{duration:.6,delay:.4},className:"text-2xl w-full mt-2",children:t("hakapath.titulo1")}),s.jsx(_.h1,{initial:{opacity:0,y:20},animate:a?{opacity:1,y:0}:{},transition:{duration:.6,delay:.5},className:"text-4xl font-bold text-white mb-8 mt-3",children:t("hakapath.gratis1")})]})]}
3762),s.jsx(ie,{color:"#0a0e27",variant:1})]})})}function xte(){const t=k.useRef(null),e=we(t,{once:!0,margin:"-100px"}),{t:a}=$();return s.jsx(s.Fragment,{children:s.jsx("section",{ref:t,className:"relative bg-gradient-to-b from-slate-950 to-blue-900 pt-11 pb-11 text-center mt-10",children:s.jsxs("div",{className:"max-w-1xl mx-auto px-4 sm:px-6 md:px-8 mt-10",children:[s.jsxs(_.div,{initial:{opacity:0,y:30},animate:e?{opacity:1,y:0}:{},transition:{duration:.6,delay:.2},className:"max-w-4xl mx-auto mt-5",children:[s.jsx(_.h3,{initial:{opacity:0,y:20},animate:e?{opacity:1,y:0}:{},transition:{duration:.6,delay:.5},className:"text-2xl font-bold text-white mt-5",children:a("hakapath.ayuda")}),s.jsx("a",{href:"https://chromewebstore.google.com/detail/hakapath/jooljogmncojjfjoomhaamdbgjolnpkp",target:"_blank",rel:"noopener noreferrer",className:`
3763                                w-48 bg-cyan-400 hover:bg-cyan-500 
3764                                text-[#0a0e27] font-bold 
3765                                py-3 rounded-full
3766                                transition-all duration-300
3767                                hover:shadow-lg hover:shadow-cyan-400/50
3768                                transform hover:-translate-y-1
3769                                mt-10 inline-block text-center
3770                            `,children:a("hakapath.descargar")})]}),s.jsx(_.div,{initial:{opacity:0,y:-30},animate:e?{opacity:1,y:0}:{},transition:{duration:.6},className:"flex justify-center mb-12 mt-10",children:s.jsx("img",{src:"/imagenes/productos/hakapathgif2.gif",alt:"Hakaboost Interface",className:"w-full max-w-3xl h-auto drop-shadow-2xl"})})]})})})}function vte(){const{t}=$();return s.jsx(s.Fragment,{children:s.jsxs("section",{className:"relative bg-dark pt-5",children:[s.jsxs("div",{className:"max-w-7xl mx-auto px-4 py-12 sm:py-16 md:py-10",children:[s.jsx("h2",{className:"text-center text-3xl sm:text-3xl lg:text-4xl mb-4 sm:mb-6 md:mb-7 text-primary leading-tight sm:leading-snug",itemProp:"headline",children:t("potencia_hakapath.titulo")}),s.jsx("p",{className:"text-center text-sm sm:text-base lg:text-lg text-gray-200 mb-8 sm:mb-10 md:mb-12 leading-relaxed font-light max-w-4xl mx-auto",children:t("potencia_hakapath.descripcion1")}),s.jsx("p",{className:"text-center text-sm sm:text-base lg:text-lg text-gray-200 mb-8 sm:mb-10 md:mb-12 leading-relaxed font-light max-w-4xl mx-auto",children:t("potencia_hakapath.descripcion2")}),s.jsx("div",{className:"flex justify-center",children:s.jsx("a",{href:"https://chromewebstore.google.com/detail/hakapath/jooljogmncojjfjoomhaamdbgjolnpkp",target:"_blank",rel:"noopener noreferrer",className:`
3771                                w-48 bg-cyan-400 hover:bg-cyan-500 
3772                                text-[#0a0e27] font-bold 
3773                                py-3 rounded-full
3774                                transition-all duration-300
3775                                hover:shadow-lg hover:shadow-cyan-400/50
3776                                transform hover:-translate-y-1
3777                                mt-1 inline-block text-center
3778                            `,children:t("hakapath.descargar")})})]}),s.jsx(ie,{color:"#0a0d29f5",variant:1})]})})}function bte(){const t=k.useRef(null),e=we(t,{once:!0,margin:"-100px"}),{t:a}=$(),n=a("hakapath_queHace.features",{returnObjects:!0}),i=a("hakapath_queHace.caracteristicasItems",{returnObjects:!0});return s.jsxs("section",{ref:t,className:"relative bg-dark pt-16 sm:pt-20 md:pt-24 pb-0",children:[s.jsxs("div",{className:"max-w-7xl mx-auto px-4 sm:px-6 md:px-8 mt-10",children:[s.jsxs("div",{className:"mb-20",children:[s.jsx(_.h2,{initial:{opacity:0,y:20},animate:e?{opacity:1,y:0}:{},transition:{duration:.6},className:"text-4xl font-bold text-white mb-8",children:a("hakapath_queHace.titulo")}),s.jsxs("div",{className:"grid grid-cols-1 lg:grid-cols-2 gap-12 items-center",children:[s.jsxs(_.div,{initial:{opacity:0,x:-30},animate:e?{opacity:1,x:0}:{},transition:{duration:.6,delay:.2},children:[s.jsx("p",{className:"text-gray-200 mb-6 leading-relaxed",children:a("hakapath_queHace.descripcion1")}),s.jsx("p",{className:"text-gray-200 mb-8 leading-relaxed",children:a("hakapath_queHace.descripcion2")}),s.jsx("div",{className:"space-y-4",children:n.map((r,o)=>s.jsxs(_.div,{initial:{opacity:0,x:-20},animate:e?{opacity:1,x:0}:{},transition:{duration:.5,delay:.3+o*.1},className:"flex gap-3",children:[s.jsx("div",{className:"text-cyan-400 flex-shrink-0 mt-1",children:"✓"}),s.jsx("p",{className:"text-gray-200 text-md",children:r})]},o))})]}),s.jsx(_.div,{initial:{opacity:0,x:30},animate:e?{opacity:1,x:0}:{},transition:{duration:.6,delay:.2},className:"flex justify-center",children:s.jsx("img",{src:"/imagenes/productos/hakapath_quehace.png",alt:"¿Qué hace Hakaboost?",className:"w-full max-w-md h-auto"})})]})]}),s.jsx("div",{className:"mb-20",children:s.jsxs("div",{className:"grid grid-cols-1 lg:grid-cols-2 gap-12 items-start",children:[s.jsx(_.div,{initial:{opacity:0,x:-30},animate:e?{opacity:1,x:0}:{},transition:{duration:.6,delay:.5},className:"flex justify-center order-2 lg:order-1",children:s.jsx("img",{src:"/imagenes/productos/hakapath_caracteristica.png",alt:"Características",className:"w-full max-w-md h-auto"})}),s.jsxs(_.div,{initial:{opacity:0,x:30},animate:e?{opacity:1,x:0}:{},transition:{duration:.6,delay:.5},className:"space-y-4 order-1 lg:order-2",children:[s.jsx(_.h2,{initial:{opacity:0,y:20},animate:e?{opacity:1,y:0}:{},transition:{duration:.6,delay:.4},className:"text-4xl font-bold text-white mb-12 text-left",children:a("hakapath_queHace.caracteristicas")}),i.map((r,o)=>s.jsxs(_.div,{initial:{opacity:0,x:20},animate:e?{opacity:1,x:0}:{},transition:{duration:.5,delay:.6+o*.1},className:"flex gap-3",children:[s.jsx("div",{className:"text-cyan-400 flex-shrink-0 mt-1",children:"✓"}),s.jsx("p",{className:"text-gray-300 text-md leading-relaxed",children:r})]},o))]})]})})]}),s.jsx(ie,{variant:1})]})}function wte(){const t=k.useRef(null),e=we(t,{once:!0,margin:"-100px"}),[a,n]=k.useState(0),{t:i}=$(),r=i("hakapath_faq.items",{returnObjects:!0});return s.jsxs("section",{ref:t,className:"relative bg-dark py-10 sm:py-20 md:py-20",children:[s.jsx("div",{className:"hero-glow"}),s.jsxs("div",{className:"max-w-4xl mx-auto px-4 sm:px-6 md:px-8",children:[s.jsxs(_.div,{initial:{opacity:0,y:20},animate:e?{opacity:1,y:0}:{},transition:{duration:.6},className:"text-center mb-16",children:[s.jsx("h2",{className:"text-4xl font-bold text-white mb-4",children:i("hakapath_faq.titulo")}),s.jsx("p",{className:"text-gray-300 text-lg",children:i("hakapath_faq.subtitulo")})]}),s.jsx("div",{className:"space-y-4",children:r.map((o,l)=>s.jsxs(_.div,{initial:{opacity:0,y:10},animate:e?{opacity:1,y:0}:{},transition:{duration:.5,delay:l*.05},className:"border border-primary/20 rounded-lg overflow-hidden hover:border-primary/50 transition-colors",children:[s.jsxs("button",{onClick:()=>n(a===l?-1:l),className:"w-full px-6 py-4 flex items-center justify-between bg-slate-800/30 hover:bg-slate-800/50 transition-colors",children:[s.jsx("h3",{className:"text-lg font-semibold text-white text-left",children:o.question}),s.jsx(_.div,{animate:{rotate:a===l?180:0},transition:{duration:.3},className:"flex-shrink-0 ml-4",children:s.jsx("svg",{className:"w-6 h-6 text-primary",fill:"none",viewBox:"0 0 24 24",stroke:"currentColor",children:s.jsx("path",{strokeLinecap:"round",strokeLinejoin:"round",strokeWidth:2,d:"M19 14l-7 7m0 0l-7-7m7 7V3"})})})]}),s.jsx(_.div,{initial:{height:0,opacity:0}
3778,animate:{height:a===l?"auto":0,opacity:a===l?1:0},transition:{duration:.3},className:"overflow-hidden",children:s.jsx("div",{className:"px-6 py-4 bg-slate-900/50 border-t border-primary/10",children:s.jsx("p",{className:"text-gray-300 leading-relaxed",children:o.answer})})})]},l))})]}),s.jsx(ie,{color:"#0a0e27",variant:1})]})}function kte(){return s.jsxs("div",{className:"bg-dark",children:[s.jsx(Xa,{title:"HakaPath - Planificacion y Ejecucion de Testing con IA",description:"Plataforma de ejecucion automatizada de pruebas con planificacion inteligente de testing impulsada por inteligencia artificial.",path:"/hakapath"}),s.jsx(yte,{}),s.jsx(xte,{}),s.jsx(vte,{}),s.jsx(bte,{}),s.jsx(wte,{}),s.jsx(Zr,{productIds:[1,2,4,5,6]})]})}function Ste(){const t=k.useRef(null),e=we(t,{once:!0,margin:"-100px"}),{t:a}=$();return s.jsxs("section",{ref:t,className:"relative bg-dark pt-1 pb-2 text-center",children:[s.jsx("div",{className:"hero-glow"}),s.jsxs("div",{className:"max-w-1xl mx-auto px-4 sm:px-6 md:px-8",children:[s.jsx(_.div,{initial:{opacity:0,y:-30},animate:e?{opacity:1,y:0}:{},transition:{duration:.6},className:"flex justify-center mb-12",children:s.jsx("img",{src:"/imagenes/productos/hakartcgif.gif",alt:"Hakaboost Interface",className:"w-full max-w-3xl h-auto drop-shadow-2xl"})}),s.jsxs(_.div,{initial:{opacity:0,y:30},animate:e?{opacity:1,y:0}:{},transition:{duration:.6,delay:.2},className:"max-w-3xl mx-auto w-full flex flex-col items-center justify-center",children:[s.jsx(_.img,{initial:{opacity:0,scale:.8},animate:e?{opacity:1,scale:1}:{},transition:{duration:.6,delay:.3},src:"/imagenes/productos/hakartc_logo.png",alt:"Hakaboost Logo",className:"sm:w-full max-w-[300px] sm:max-w-md lg:max-w-lg h-auto drop-shadow-2xl object-contain"}),s.jsx(_.p,{initial:{opacity:0,y:20},animate:e?{opacity:1,y:0}:{},transition:{duration:.6,delay:.4},className:"text-2xl w-full mt-3",children:a("hakartc.hero.descripcion")}),s.jsx(_.h1,{initial:{opacity:0,y:20},animate:e?{opacity:1,y:0}:{},transition:{duration:.6,delay:.5},className:"text-4xl font-bold text-white mb-8 mt-3",children:a("hakartc.hero.gratis")})]})]}),s.jsx(ie,{variant:1})]})}function _te(){const t=k.useRef(null),e=we(t,{once:!0,margin:"-100px"}),{t:a}=$();return s.jsx(s.Fragment,{children:s.jsx("section",{ref:t,className:"relative bg-gradient-to-b from-slate-950 to-blue-900 pt-11 pb-11 text-center mt-10",children:s.jsxs("div",{className:"max-w-1xl mx-auto px-4 sm:px-6 md:px-8 mt-10",children:[s.jsxs(_.div,{initial:{opacity:0,y:30},animate:e?{opacity:1,y:0}:{},transition:{duration:.6,delay:.2},className:"max-w-4xl mx-auto mt-5",children:[s.jsx(_.h3,{initial:{opacity:0,y:20},animate:e?{opacity:1,y:0}:{},transition:{duration:.6,delay:.5},className:"text-2xl font-bold text-white mt-5",children:a("hakartc.presentacion.titulo")}),s.jsx("a",{href:"https://chromewebstore.google.com/detail/haka-rtc/jnmppgpcnckmiifheplcgcmapicdomkn",target:"_blank",rel:"noopener noreferrer",className:`
3779                                w-48 bg-cyan-400 hover:bg-cyan-500 
3780                                text-[#0a0e27] font-bold 
3781                                py-3 rounded-full
3782                                transition-all duration-300
3783                                hover:shadow-lg hover:shadow-cyan-400/50
3784                                transform hover:-translate-y-1
3785                                mt-10 inline-block text-center
3786                            `,children:a("hakartc.descargar")})]}),s.jsx(_.div,{initial:{opacity:0,y:-30},animate:e?{opacity:1,y:0}:{},transition:{duration:.6},className:"flex justify-center mb-12 mt-10",children:s.jsx("img",{src:"/imagenes/productos/hakartcgif2.gif",alt:"Hakartc Interface",className:"w-full max-w-3xl h-auto drop-shadow-2xl"})})]})})})}function Ate(){const{t}=$();return s.jsx(s.Fragment,{children:s.jsxs("section",{className:"relative bg-dark pt-5",children:[s.jsxs("div",{className:"max-w-7xl mx-auto px-4 py-12 sm:py-16 md:py-10",children:[s.jsx("h2",{className:"text-center text-3xl sm:text-3xl lg:text-4xl mb-4 sm:mb-6 md:mb-7 text-primary leading-tight sm:leading-snug",itemProp:"headline",children:t("potencia_hakartc.titulo")}),s.jsx("p",{className:"text-center text-md sm:text-base lg:text-lg text-gray-200 mb-8 sm:mb-10 md:mb-12 leading-relaxed font-light max-w-4xl mx-auto",children:t("potencia_hakartc.descripcion1")}),s.jsx("p",{className:"text-center text-md sm:text-base lg:text-lg text-gray-200 mb-8 sm:mb-10 md:mb-12 leading-relaxed font-light max-w-4xl mx-auto",children:t("potencia_hakartc.descripcion2")}),s.jsx("div",{className:"flex justify-center",children:s.jsx("a",{href:"https://chromewebstore.google.com/detail/haka-rtc/jnmppgpcnckmiifheplcgcmapicdomkn",target:"_blank",rel:"noopener noreferrer",className:`
3787                                w-48 bg-cyan-400 hover:bg-cyan-500 
3788                                text-[#0a0e27] font-bold 
3789                                py-3 rounded-full
3790                                transition-all duration-300
3791                                hover:shadow-lg hover:shadow-cyan-400/50
3792                                transform hover:-translate-y-1
3793                                mt-1 inline-block text-center
3794                            `,children:t("hakartc.descargar")})})]}
3794),s.jsx(ie,{color:"#0a0d29f5",variant:1})]})})}function Ete(){const t=k.useRef(null),e=we(t,{once:!0,margin:"-100px"}),{t:a}=$(),n=a("hakartc_queHace.features",{returnObjects:!0}),i=a("hakartc_queHace.caracteristicasItems",{returnObjects:!0});return s.jsxs("section",{ref:t,className:"relative bg-dark pt-16 sm:pt-20 md:pt-24 pb-0",children:[s.jsxs("div",{className:"max-w-7xl mx-auto px-4 sm:px-6 md:px-8 mt-10",children:[s.jsxs("div",{className:"mb-20",children:[s.jsx(_.h2,{initial:{opacity:0,y:20},animate:e?{opacity:1,y:0}:{},transition:{duration:.6},className:"text-4xl font-bold text-white mb-8",children:a("hakartc_queHace.titulo")}),s.jsxs("div",{className:"grid grid-cols-1 lg:grid-cols-2 gap-12 items-center",children:[s.jsx(_.div,{initial:{opacity:0,x:-30},animate:e?{opacity:1,x:0}:{},transition:{duration:.6,delay:.2},children:s.jsx("div",{className:"space-y-4",children:n.map((r,o)=>s.jsxs(_.div,{initial:{opacity:0,x:-20},animate:e?{opacity:1,x:0}:{},transition:{duration:.5,delay:.3+o*.1},className:"flex gap-3",children:[s.jsx("div",{className:"text-cyan-400 flex-shrink-0 mt-1",children:"✓"}),s.jsx("p",{className:"text-gray-200 text-md",children:r})]},o))})}),s.jsx(_.div,{initial:{opacity:0,x:30},animate:e?{opacity:1,x:0}:{},transition:{duration:.6,delay:.2},className:"flex justify-center",children:s.jsx("img",{src:"/imagenes/productos/hakartc_quehace.png",alt:"¿Qué hace Hakaboost?",className:"w-full max-w-md h-auto"})})]})]}),s.jsx("div",{className:"mb-20",children:s.jsxs("div",{className:"grid grid-cols-1 lg:grid-cols-2 gap-12 items-start",children:[s.jsx(_.div,{initial:{opacity:0,x:-30},animate:e?{opacity:1,x:0}:{},transition:{duration:.6,delay:.5},className:"flex justify-center order-2 lg:order-1",children:s.jsx("img",{src:"/imagenes/productos/hakartc_caracteristicas.png",alt:"Características",className:"w-full max-w-md h-auto"})}),s.jsxs(_.div,{initial:{opacity:0,x:30},animate:e?{opacity:1,x:0}:{},transition:{duration:.6,delay:.5},className:"space-y-4 order-1 lg:order-2",children:[s.jsx(_.h2,{initial:{opacity:0,y:20},animate:e?{opacity:1,y:0}:{},transition:{duration:.6,delay:.4},className:"text-4xl font-bold text-white mb-12 text-left",children:a("hakartc_queHace.caracteristicas")}),i.map((r,o)=>s.jsxs(_.div,{initial:{opacity:0,x:20},animate:e?{opacity:1,x:0}:{},transition:{duration:.5,delay:.6+o*.1},className:"flex gap-3",children:[s.jsx("div",{className:"text-cyan-400 flex-shrink-0 mt-1",children:"✓"}),s.jsx("p",{className:"text-gray-300 text-md leading-relaxed",children:r})]},o))]})]})})]}),s.jsx(ie,{variant:1})]})}function Cte(){return s.jsxs("div",{className:"bg-dark",children:[s.jsx(Xa,{title:"HakaRTC - Diseno de Casos de Prueba con IA",description:"Herramienta de diseno de casos de prueba asistida por inteligencia artificial para equipos de QA.",path:"/hakartc"}),s.jsx(Ste,{}),s.jsx(_te,{}),s.jsx(Ate,{}),s.jsx(Ete,{}),s.jsx(Zr,{productIds:[1,2,3,4,6]})]})}function jte(){const{t}=$(),e=k.useRef(null),a=we(e,{once:!0,margin:"-100px"});return s.jsx(s.Fragment,{children:s.jsxs("section",{ref:e,className:"relative bg-dark pt-1 pb-2 text-center",children:[s.jsx("div",{className:"hero-glow -mt-24"}),s.jsx("div",{className:"max-w-1xl mx-auto px-4 sm:px-6 md:px-8 mt-24 mb-14",children:s.jsxs(_.div,{initial:{opacity:0,y:30},animate:a?{opacity:1,y:0}:{},transition:{duration:.6,delay:.2},className:"max-w-3xl mx-auto w-full flex flex-col items-center justify-center",children:[s.jsx(_.img,{initial:{opacity:0,scale:.8},animate:a?{opacity:1,scale:1}:{},transition:{duration:.6,delay:.3},src:"/imagenes/productos/Haka Insight_logo.png",alt:"Haka Insight Logo",className:"sm:w-full max-w-[300px] sm:max-w-md lg:max-w-lg h-auto drop-shadow-2xl object-contain"}),s.jsx(_.p,{initial:{opacity:0,y:20},animate:a?{opacity:1,y:0}:{},transition:{duration:.6,delay:.4},className:"text-2xl w-full mt-2 text-gray-300",children:"Analiza tu código y crea explicaciones simples con diagramas interactivos automáticamente"}),s.jsxs(_.h1,{initial:{opacity:0,y:20},animate:a?{opacity:1,y:0}:{},transition:{duration:.6,delay:.5},className:"text-4xl font-bold text-white mb-8 mt-3",children:["Extensión gratuita para ",s.jsx("span",{className:"text-cyan-400",children:"VS Code"})]})]})}
3794),s.jsx(ie,{color:"#0a0e27",variant:1})]})})}function Tte(){const t=k.useRef(null),e=we(t,{once:!0,margin:"-100px"}),[a,n]=k.useState(!1);return s.jsxs(s.Fragment,{children:[s.jsx("section",{ref:t,className:"relative bg-gradient-to-b from-slate-950 to-blue-900 pt-11 pb-11 mt-10",children:s.jsx("div",{className:"max-w-7xl mx-auto px-4 sm:px-6 md:px-8 mt-24 md:pt-12 md:pb-14",children:s.jsxs("div",{className:"grid grid-cols-1 lg:grid-cols-2 gap-12 items-center",children:[s.jsxs(_.div,{initial:{opacity:0,x:-30},animate:e?{opacity:1,x:0}:{},transition:{duration:.6,delay:.2},children:[s.jsx(_.h2,{initial:{opacity:0,y:20},animate:e?{opacity:1,y:0}:{},transition:{duration:.6,delay:.3},className:"text-3xl font-bold text-white mb-6",children:"¿Qué es Haka Insight?"}),s.jsx(_.p,{initial:{opacity:0,y:20},animate:e?{opacity:1,y:0}:{},transition:{duration:.6,delay:.4},className:"text-lg text-gray-300 mb-8 leading-relaxed",children:"Una extensión de Visual Studio Code impulsada por inteligencia artificial que transforma la forma en que los desarrolladores comprenden y analizan código. Utilizando Google Gemini AI, convierte automáticamente tu código en diagramas interactivos mientras identifica vulnerabilidades de seguridad y evalúa la calidad del código, todo sin salir de tu IDE."}),s.jsx(_.h3,{initial:{opacity:0,y:20},animate:e?{opacity:1,y:0}:{},transition:{duration:.6,delay:.5},className:"text-xl font-bold text-white mb-6",children:"Instala Haka Insight desde VS Code Marketplace"}),s.jsx("a",{href:"https://marketplace.visualstudio.com/items?itemName=hakalab.haka-insight",target:"_blank",rel:"noopener noreferrer",className:`
3795                                    inline-block w-64 bg-cyan-400 hover:bg-cyan-500 
3796                                    text-[#0a0e27] font-bold 
3797                                    py-3 px-8 rounded-full text-center
3798                                    transition-all duration-300
3799                                    hover:shadow-lg hover:shadow-cyan-400/50
3800                                    transform hover:-translate-y-1
3801                                `,children:"Descargar Extensión"})]}),s.jsx(_.div,{initial:{opacity:0,x:30},animate:e?{opacity:1,x:0}:{},transition:{duration:.6,delay:.4},className:"flex justify-center",children:s.jsxs("div",{className:"relative group cursor-pointer",onClick:()=>n(!0),children:[s.jsx("img",{src:"/video/haka-insight.gif",alt:"Haka Insight Demo",className:"w-full max-w-2xl h-auto drop-shadow-2xl rounded-lg transition-all duration-300 group-hover:scale-105"}),s.jsx("div",{className:"absolute inset-0 bg-black/40 opacity-0 group-hover:opacity-100 transition-opacity duration-300 rounded-lg flex items-center justify-center",children:s.jsx("svg",{className:"w-16 h-16 text-white",fill:"none",stroke:"currentColor",viewBox:"0 0 24 24",children:s.jsx("path",{strokeLinecap:"round",strokeLinejoin:"round",strokeWidth:2,d:"M4 8V4m0 0h4M4 4l5 5m11-1V4m0 0h-4m4 0l-5 5M4 16v4m0 0h4m-4 0l5-5m11 5l-5-5m5 5v-4m0 4h-4"})})})]})})]})})}),s.jsx(La,{children:a&&s.jsxs(_.div,{initial:{opacity:0}
3801,animate:{opacity:1},exit:{opacity:0},className:"fixed inset-0 z-50 flex items-center justify-center p-4 bg-black/90",onClick:()=>n(!1),children:[s.jsx("button",{onClick:()=>n(!1),className:"absolute top-4 right-4 text-white hover:text-cyan-400 transition-colors duration-300 z-10",children:s.jsx("svg",{className:"w-10 h-10",fill:"none",stroke:"currentColor",viewBox:"0 0 24 24",children:s.jsx("path",{strokeLinecap:"round",strokeLinejoin:"round",strokeWidth:2,d:"M6 18L18 6M6 6l12 12"})})}),s.jsx(_.div,{initial:{scale:.8,opacity:0},animate:{scale:1,opacity:1},exit:{scale:.8,opacity:0},transition:{duration:.3},className:"relative max-w-6xl w-full",onClick:i=>i.stopPropagation(),children:s.jsx("img",{src:"/video/haka-insight.gif",alt:"Haka Insight Demo",className:"w-full h-auto rounded-lg shadow-2xl"})})]})})]})}function Nte(){const t=k.useRef(null),e=we(t,{once:!0,margin:"-100px"}),[a,n]=k.useState(0),i=[{icon:s.jsx("svg",{className:"w-10 h-10",fill:"none",viewBox:"0 0 24 24",stroke:"currentColor",children:s.jsx("path",{strokeLinecap:"round",strokeLinejoin:"round",strokeWidth:2,d:"M9 19v-6a2 2 0 00-2-2H5a2 2 0 00-2 2v6a2 2 0 002 2h2a2 2 0 002-2zm0 0V9a2 2 0 012-2h2a2 2 0 012 2v10m-6 0a2 2 0 002 2h2a2 2 0 002-2m0 0V5a2 2 0 012-2h2a2 2 0 012 2v14a2 2 0 01-2 2h-2a2 2 0 01-2-2z"})}),title:"Diagramas Interactivos",description:"Genera automáticamente diagramas visuales de tu código mostrando archivos, clases, funciones y sus relaciones. Navega directamente al código haciendo clic en nodos."},{icon:s.jsx("svg",{className:"w-10 h-10",fill:"none",viewBox:"0 0 24 24",stroke:"currentColor",children:s.jsx("path",{strokeLinecap:"round",strokeLinejoin:"round",strokeWidth:2,d:"M12 15v2m-6 4h12a2 2 0 002-2v-6a2 2 0 00-2-2H6a2 2 0 00-2 2v6a2 2 0 002 2zm10-10V7a4 4 0 00-8 0v4h8z"})}),title:"Análisis de Seguridad con IA",description:"Detecta vulnerabilidades de seguridad y las categoriza por severidad (Critical, High, Medium, Low) con scoring de riesgo automático."},{icon:s.jsx("svg",{className:"w-10 h-10",fill:"none",viewBox:"0 0 24 24",stroke:"currentColor",children:s.jsx("path",{strokeLinecap:"round",strokeLinejoin:"round",strokeWidth:2,d:"M9 19v-6a2 2 0 00-2-2H5a2 2 0 00-2 2v6a2 2 0 002 2h2a2 2 0 002-2zm0 0V9a2 2 0 012-2h2a2 2 0 012 2v10m-6 0a2 2 0 002 2h2a2 2 0 002-2m0 0V5a2 2 0 012-2h2a2 2 0 012 2v14a2 2 0 01-2 2h-2a2 2 0 01-2-2z"})}),title:"Métricas de Calidad",description:"Proporciona un score de calidad 0-100 con problemas categorizados (Bugs, Improvements, Performance, Best Practices) y recomendaciones accionables."},{icon:s.jsx("svg",{className:"w-10 h-10",fill:"none",viewBox:"0 0 24 24",stroke:"currentColor",children:s.jsx("path",{strokeLinecap:"round",strokeLinejoin:"round",strokeWidth:2,d:"M5 8h14M5 8a2 2 0 110-4h14a2 2 0 110 4M5 8v10a2 2 0 002 2h10a2 2 0 002-2V8m-9 4h4"})}),title:"Caché Inteligente",description:"Guarda automáticamente todos los análisis localmente para acceso instantáneo sin llamadas a la API. Ahorra ~70% en costos de API."},{icon:s.jsx("svg",{className:"w-10 h-10",fill:"none",viewBox:"0 0 24 24",stroke:"currentColor",children:s.jsx("path",{strokeLinecap:"round",strokeLinejoin:"round",strokeWidth:2,d:"M3.055 11H5a2 2 0 012 2v1a2 2 0 002 2 2 2 0 012 2v2.945M8 3.935V5.5A2.5 2.5 0 0010.5 8h.5a2 2 0 012 2 2 2 0 104 0 2 2 0 012-2h1.064M15 20.488V18a2 2 0 012-2h3.064M21 12a9 9 0 11-18 0 9 9 0 0118 0z"})}),title:"Soporte Multi-Lenguaje",description:"Analiza código en JavaScript, TypeScript, Python, Java, C#, PHP, Ruby, Go y más. Interfaz bilingüe (Inglés/Español)."},{icon:s.jsx("svg",{className:"w-10 h-10",fill:"none",viewBox:"0 0 24 24",stroke:"currentColor",children:s.jsx("path",{strokeLinecap:"round",strokeLinejoin:"round",strokeWidth:2,d:"M9 12h6m-6 4h6m2 5H7a2 2 0 01-2-2V5a2 2 0 012-2h5.586a1 1 0 01.707.293l5.414 5.414a1 1 0 01.293.707V19a2 2 0 01-2 2z"})}),title:"Reportes Profesionales",description:"Crea reportes HTML profesionales de seguridad y calidad para compartir con tu equipo. Incluye resumen ejecutivo, hallazgos detallados y gráficos."}];return k.useEffect(()=>{const r=setInterval(()=>{n(o=>(o+1)%i.length)},3e3);return()=>clearInterval(r)},[i.length]),s.jsx("section",{ref:t,className:"relative bg-dark py-20",children:s.jsxs("div",{className:"max-w-7xl mx-auto px-4 sm:px-6 md:px-8",children:[s.jsxs(_.div,{initial:{opacity:0,y:20},animate:e?{opacity:1,y:0}:{},transition:{duration:.6},className:"text-center mb-16",children:[s.jsx("h2",{className:"text-4xl font-bold text-white mb-4",children:"Características Principales"}),s.jsx("p",{className:"text-xl text-gray-400",children:"Todo lo que necesitas para entender y mejorar tu código"})]}),s.jsxs("div",{className:"relative mb-20",children:[s.jsx("div",{className:"absolute top-8 left-0 right-0 h-1 bg-gray-700",children:s.jsx(_.div,{className:"h-full bg-cyan-400",initial:{width:"0%"},animate:{width:`${a/(i.length-1)*100}%`},transition:{duration:.8,ease:"easeInOut"}})}),s.jsx(_.div,{className:"absolute top-4 w-8 h-8 bg-cyan-400 rounded-full shadow-lg shadow-cyan-400/50 z-20",animate:{left:`${a/(i.length-1)*100}%`,x:"-50%"},transition:{duration:.8,ease:"easeInOut"},children:s.jsx("div",{className:"absolute inset-0 rounded-full bg-cyan-400 animate-ping opacity-75"})}),s.jsx("div",{className:"relative grid grid-cols-2 md:grid-cols-3 lg:grid-cols-6 gap-4 pt-20",children:i.map((r,o)=>s.jsxs(_.div,{initial:{opacity:0,y:20},animate:e?{opacity:1,y:0}:{},transition:{duration:.5,delay:o*.1},className:"flex flex-col items-center text-center",children:[s.jsxs(_.div,{animate:{scale:a===o?1.2:1},transition:{duration:.6},className:"mb-4 relative",children:[s.jsx("div",{className:`absolute inset-0 rounded-full blur-lg transition-opacity duration-500 ${a>=o?"opacity-100":"opacity-0"}`,style:{background:"radial-gradient(circle, #06b6d4 0%, transparent 70%)",width:"100%",height:"100%"}}),s.jsx("div",{className:`transition-all duration-500 relative z-10 ${a>=o?"text-cyan-400":"text-gray-600"}`,style:{filter:a>=o?"drop-shadow(0 0 8px #06b6d4) drop-shadow(0 0 16px rgba(6, 182, 212, 0.5))":"none"},children:r.icon})]}
3801),s.jsxs(_.div,{animate:{opacity:a>=o?1:.5,scale:a===o?1.05:1},transition:{duration:.3},className:`p-4 rounded-lg border transition-all ${a>=o?"border-cyan-400/30 bg-cyan-400/5":"border-gray-700 bg-gray-800/30"}`,children:[s.jsx("h3",{className:`font-bold mb-2 text-sm lg:text-base ${a>=o?"text-cyan-400":"text-gray-400"}`,children:r.title}),s.jsx("p",{className:"text-xs lg:text-sm text-gray-200",children:r.description})]})]},o))})]}),s.jsxs(_.div,{initial:{opacity:0,y:30},animate:e?{opacity:1,y:0}:{},transition:{duration:.6,delay:.8},className:"mt-16 bg-gradient-to-r from-cyan-500/10 to-blue-500/10 p-8 rounded-2xl border border-cyan-400/30 relative",children:[s.jsxs(_.div,{initial:{scale:0,rotate:-180},animate:e?{scale:1,rotate:0}:{},transition:{duration:.8,delay:1},className:"absolute -top-6 -right-6 w-16 h-16 bg-gradient-to-br from-cyan-400 to-blue-500 rounded-full flex items-center justify-center shadow-lg shadow-cyan-400/50 text-dark z-10",children:[s.jsx(Kk,{className:"w-8 h-8"}),s.jsx("div",{className:"absolute inset-0 rounded-full bg-cyan-400 animate-ping opacity-30"})]}),s.jsx("h3",{className:"text-2xl font-bold text-white mb-6 text-center",children:"¿Por qué elegir Haka Insight?"}),s.jsxs("div",{className:"grid grid-cols-1 md:grid-cols-2 lg:grid-cols-4 gap-6",children:[s.jsxs("div",{className:"text-center",children:[s.jsx("div",{className:"text-3xl font-bold text-cyan-400 mb-2",children:"60-80%"}),s.jsx("div",{className:"text-gray-300",children:"Reducción en tiempo de comprensión de código"})]}),s.jsxs("div",{className:"text-center",children:[s.jsx("div",{className:"text-3xl font-bold text-cyan-400 mb-2",children:"~70%"}),s.jsx("div",{className:"text-gray-300",children:"Ahorro en costos de API con caché"})]}),s.jsxs("div",{className:"text-center",children:[s.jsx("div",{className:"text-3xl font-bold text-cyan-400 mb-2",children:"2 min"}),s.jsx("div",{className:"text-gray-300",children:"Setup completo y listo para usar"})]}),s.jsxs("div",{className:"text-center",children:[s.jsx("div",{className:"text-3xl font-bold text-cyan-400 mb-2",children:"Gratis"}),s.jsx("div",{className:"text-gray-300",children:"Con tu propia API key de Gemini"})]})]})]})]})})}function Ite(){const t=k.useRef(null),e=we(t,{once:!0,margin:"-100px"}),[a,n]=k.useState(0),i=[{title:"Onboarding de Desarrolladores",problem:"Nuevo desarrollador necesita entender codebase complejo",solution:"Analiza archivos clave, genera diagramas, comprende arquitectura en minutos",icon:s.jsx("svg",{className:"w-16 h-16",fill:"none",viewBox:"0 0 24 24",stroke:"currentColor",children:s.jsx("path",{strokeLinecap:"round",strokeLinejoin:"round",strokeWidth:2,d:"M16 7a4 4 0 11-8 0 4 4 0 018 0zM12 14a7 7 0 00-7 7h14a7 7 0 00-7-7z"})})},{title:"Code Review",problem:"Revisar PRs manualmente toma mucho tiempo",solution:"Análisis automático de seguridad y calidad antes de merge",icon:s.jsx("svg",{className:"w-16 h-16",fill:"none",viewBox:"0 0 24 24",stroke:"currentColor",children:s.jsx("path",{strokeLinecap:"round",strokeLinejoin:"round",strokeWidth:2,d:"M21 21l-6-6m2-5a7 7 0 11-14 0 7 7 0 0114 0z"})})},{title:"Auditoría de Seguridad",problem:"Identificar vulnerabilidades en aplicación legacy",solution:"Escaneo completo con categorización por severidad y reportes",icon:s.jsx("svg",{className:"w-16 h-16",fill:"none",viewBox:"0 0 24 24",stroke:"currentColor",children:s.jsx("path",{strokeLinecap:"round",strokeLinejoin:"round",strokeWidth:2,d:"M9 12l2 2 4-4m5.618-4.016A11.955 11.955 0 0112 2.944a11.955 11.955 0 01-8.618 3.04A12.02 12.02 0 003 9c0 5.591 3.824 10.29 9 11.622 5.176-1.332 9-6.03 9-11.622 0-1.042-.133-2.052-.382-3.016z"})})},{title:"Refactoring",problem:"Necesitas mejorar calidad sin romper funcionalidad",solution:"Identifica áreas problemáticas con métricas objetivas",icon:s.jsxs("svg",{className:"w-16 h-16",fill:"none",viewBox:"0 0 24 24",stroke:"currentColor",children:[s.jsx("path",{strokeLinecap:"round",strokeLinejoin:"round",strokeWidth:2,d:"M10.325 4.317c.426-1.756 2.924-1.756 3.35 0a1.724 1.724 0 002.573 1.066c1.543-.94 3.31.826 2.37 2.37a1.724 1.724 0 001.065 2.572c1.756.426 1.756 2.924 0 3.35a1.724 1.724 0 00-1.066 2.573c.94 1.543-.826 3.31-2.37 2.37a1.724 1.724 0 00-2.572 1.065c-.426 1.756-2.924 1.756-3.35 0a1.724 1.724 0 00-2.573-1.066c-1.543.94-3.31-.826-2.37-2.37a1.724 1.724 0 00-1.065-2.572c-1.756-.426-1.756-2.924 0-3.35a1.724 1.724 0 001.066-2.573c-.94-1.543.826-3.31 2.37-2.37.996.608 2.296.07 2.572-1.065z"}),s.jsx("path",{strokeLinecap:"round",strokeLinejoin:"round",strokeWidth:2,d:"M15 12a3 3 0 11-6 0 3 3 0 016 0z"})]})},{title:"Documentación",problem:"Documentación de arquitectura desactualizada",solution:"Diagramas automáticos siempre actualizados con el código",icon:s.jsx("svg",{className:"w-16 h-16",fill:"none",viewBox:"0 0 24 24",stroke:"currentColor",children:s.jsx("path",{strokeLinecap:"round",strokeLinejoin:"round",strokeWidth:2,d:"M12 6.253v13m0-13C10.832 5.477 9.246 5 7.5 5S4.168 5.477 3 6.253v13C4.168 18.477 5.754 18 7.5 18s3.332.477 4.5 1.253m0-13C13.168 5.477 14.754 5 16.5 5c1.747 0 3.332.477 4.5 1.253v13C19.832 18.477 18.247 18 16.5 18c-1.746 0-3.332.477-4.5 1.253"})})},{title:"Due Diligence Técnico",problem:"Evaluar calidad de código antes de adquisición",solution:"Análisis completo con reportes profesionales para decisión",icon:s.jsx("svg",{className:"w-16 h-16",fill:"none",viewBox:"0 0 24 24",stroke:"currentColor",children:s.jsx("path",{strokeLinecap:"round",strokeLinejoin:"round",strokeWidth:2,d:"M21 13.255A23.931 23.931 0 0112 15c-3.183 0-6.22-.62-9-1.745M16 6V4a2 2 0 00-2-2h-4a2 2 0 00-2 2v2m4 6h.01M5 20h14a2 2 0 002-2V8a2 2 0 00-2-2H5a2 2 0 00-2 2v10a2 2 0 002 2z"})})}];return k.useEffect(()=>{const r=setInterval(()=>{n(o=>(o+1)%i.length)},5e3);return()=>clearInterval(r)},[i.length]),s.jsxs("section",{ref:t,className:"relative bg-[#0a0e27] py-20",children:[s.jsxs("div",{className:"max-w-7xl mx-auto px-4 sm:px-6 md:px-8",children:[s.jsxs(_.div,{initial:{opacity:0,y:20},animate:e?{opacity:1,y:0}:{},transition:{duration:.6},className:"text-center mb-16",children:[s.jsx("h2",{className:"text-4xl font-bold text-white mb-4",children:"Casos de Uso Reales"}),s.jsx("p",{className:"text-xl text-gray-400",children:"Cómo Haka Insight resuelve problemas del día a día"})]}),s.jsxs("div",{className:"relative max-w-5xl mx-auto mb-16",children:[s.jsx(La,{mode:"wait",children:s.jsx(_.div,{initial:{opacity:0,x:100}
3801,animate:{opacity:1,x:0},exit:{opacity:0,x:-100},transition:{duration:.5},className:"bg-gradient-to-br from-slate-800/80 to-slate-900/80 p-10 rounded-2xl border-2 border-cyan-400/30 backdrop-blur-sm",children:s.jsxs("div",{className:"flex flex-col md:flex-row items-center gap-8",children:[s.jsx("div",{className:"flex-shrink-0",children:s.jsx("div",{className:"w-32 h-32 bg-gradient-to-br from-cyan-400/20 to-blue-500/20 rounded-2xl flex items-center justify-center border border-cyan-400/30 text-cyan-400",children:i[a].icon})}),s.jsxs("div",{className:"flex-1 text-center md:text-left",children:[s.jsx("h3",{className:"text-3xl font-bold text-white mb-4",children:i[a].title}),s.jsxs("div",{className:"space-y-4",children:[s.jsxs("div",{className:"bg-red-500/10 border border-red-400/30 rounded-lg p-4",children:[s.jsx("span",{className:"text-red-400 font-semibold text-lg",children:"Problema: "}),s.jsx("span",{className:"text-gray-300 text-lg",children:i[a].problem})]}),s.jsxs("div",{className:"bg-green-500/10 border border-green-400/30 rounded-lg p-4",children:[s.jsx("span",{className:"text-green-400 font-semibold text-lg",children:"Solución: "}),s.jsx("span",{className:"text-gray-300 text-lg",children:i[a].solution})]})]})]})]})},a)}),s.jsxs("div",{className:"flex items-center justify-center gap-4 mt-8",children:[s.jsx("button",{onClick:()=>n(r=>(r-1+i.length)%i.length),className:"w-10 h-10 rounded-full bg-slate-800 border border-cyan-400/30 hover:bg-cyan-400/20 transition-colors flex items-center justify-center text-cyan-400",children:s.jsx("svg",{className:"w-6 h-6",fill:"none",viewBox:"0 0 24 24",stroke:"currentColor",children:s.jsx("path",{strokeLinecap:"round",strokeLinejoin:"round",strokeWidth:2,d:"M15 19l-7-7 7-7"})})}),s.jsx("div",{className:"flex gap-2",children:i.map((r,o)=>s.jsx("button",{onClick:()=>n(o),className:`transition-all duration-300 rounded-full ${o===a?"w-8 h-3 bg-cyan-400":"w-3 h-3 bg-gray-600 hover:bg-gray-500"}`},o))}),s.jsx("button",{onClick:()=>n(r=>(r+1)%i.length),className:"w-10 h-10 rounded-full bg-slate-800 border border-cyan-400/30 hover:bg-cyan-400/20 transition-colors flex items-center justify-center text-cyan-400",children:s.jsx("svg",{className:"w-6 h-6",fill:"none",viewBox:"0 0 24 24",stroke:"currentColor",children:s.jsx("path",{strokeLinecap:"round",strokeLinejoin:"round",strokeWidth:2,d:"M9 5l7 7-7 7"})})})]}),s.jsx("div",{className:"grid grid-cols-2 md:grid-cols-3 lg:grid-cols-6 gap-4 mt-8",children:i.map((r,o)=>s.jsxs(_.button,{onClick:()=>n(o),whileHover:{scale:1.05},className:`p-4 rounded-xl border transition-all ${o===a?"bg-cyan-400/20 border-cyan-400":"bg-slate-800/50 border-slate-700 hover:border-cyan-400/50"}`,children:[s.jsx("div",{className:`text-3xl mb-2 ${o===a?"text-cyan-400":"text-gray-500"}`,children:r.icon}),s.jsx("p",{className:`text-xs font-semibold ${o===a?"text-white":"text-gray-400"}`,children:r.title})]},o))})]})]}),s.jsx(ie,{color:"#0a0e27",variant:3})]})}function Pte(){const t=k.useRef(null),e=we(t,{once:!0,margin:"-100px"}),[a,n]=k.useState(null),i=[{question:"¿Haka Insight es realmente gratis?",answer:"Sí, la extensión es completamente gratuita. Solo necesitas tu propia API key de Google Gemini, que también tiene un tier gratuito generoso. No hay costos ocultos ni suscripciones."},{question:"¿Qué lenguajes de programación soporta?",answer:"Haka Insight soporta múltiples lenguajes incluyendo JavaScript, TypeScript, Python, Java, C#, PHP, Ruby, Go y más. La IA de Gemini puede analizar prácticamente cualquier lenguaje de programación moderno."},{question:"¿Mis datos están seguros?",answer:"Absolutamente. Tu API key se almacena de forma segura usando VS Code Secret Storage. El código se envía directamente a la API de Google Gemini sin pasar por nuestros servidores. Además, el sistema de caché guarda los análisis localmente en tu máquina."},{question:"¿Cómo funciona el sistema de caché?",answer:"Cada vez que analizas un archivo, los resultados se guardan automáticamente en tu máquina. La próxima vez que abras ese análisis, se carga instantáneamente desde el caché sin hacer llamadas a la API, ahorrando tiempo y costos."},{question:"¿Puedo compartir los análisis con mi equipo?",answer:"Sí, puedes generar reportes HTML profesionales que incluyen todos los hallazgos, diagramas y métricas. Estos reportes son fáciles de compartir por email o sistemas de gestión de proyectos."},{question:"¿Qué tan preciso es el análisis de seguridad?",answer:"Haka Insight utiliza Google Gemini AI, uno de los modelos de IA más avanzados. El análisis identifica vulnerabilidades comunes y las categoriza por severi
3801dad. Sin embargo, recomendamos usarlo como complemento a otras herramientas de seguridad y revisiones manuales."},{question:"¿Funciona con proyectos grandes?",answer:"Sí, aunque actualmente analiza archivos individuales. El sistema de caché y los diagramas interactivos con zoom facilitan trabajar con bases de código grandes. Próximamente agregaremos análisis de múltiples archivos simultáneos."},{question:"¿Necesito conocimientos técnicos avanzados?",answer:"No, Haka Insight está diseñado para ser intuitivo. Si sabes usar VS Code, puedes usar Haka Insight. La interfaz es clara y los resultados se presentan de forma fácil de entender."},{question:"¿Puedo personalizar los análisis?",answer:"Actualmente puedes elegir entre dos modelos de IA (Gemini Flash para rapidez o Gemini Pro para análisis detallado) y cambiar el idioma de la interfaz. Estamos trabajando en reglas de análisis personalizables para futuras versiones."}];return s.jsx("section",{ref:t,className:"relative bg-dark py-20",children:s.jsxs("div",{className:"max-w-4xl mx-auto px-4 sm:px-6 md:px-8",children:[s.jsxs(_.div,{initial:{opacity:0,y:20},animate:e?{opacity:1,y:0}:{},transition:{duration:.6},className:"text-center mb-12",children:[s.jsx("h2",{className:"text-4xl font-bold text-white mb-4",children:"Preguntas Frecuentes"}),s.jsx("p",{className:"text-xl text-gray-400",children:"Todo lo que necesitas saber sobre Haka Insight"})]}),s.jsx("div",{className:"space-y-4",children:i.map((r,o)=>s.jsxs(_.div,{initial:{opacity:0,y:20},animate:e?{opacity:1,y:0}:{},transition:{duration:.6,delay:o*.05},className:"bg-slate-800/50 rounded-xl border border-slate-700 overflow-hidden",children:[s.jsxs("button",{onClick:()=>n(a===o?null:o),className:"w-full px-6 py-4 text-left flex justify-between items-center hover:bg-slate-700/30 transition-colors",children:[s.jsx("span",{className:"text-lg font-semibold text-white pr-4",children:r.question}),s.jsx("svg",{className:`w-6 h-6 text-cyan-400 flex-shrink-0 transition-transform ${a===o?"transform rotate-180":""}`,fill:"none",stroke:"currentColor",viewBox:"0 0 24 24",children:s.jsx("path",{strokeLinecap:"round",strokeLinejoin:"round",strokeWidth:2,d:"M19 9l-7 7-7-7"})})]}),a===o&&s.jsx(_.div,{initial:{height:0,opacity:0},animate:{height:"auto",opacity:1},exit:{height:0,opacity:0},transition:{duration:.3},className:"px-6 pb-4",children:s.jsx("p",{className:"text-gray-300 leading-relaxed",children:r.answer})})]},o))})]})})}function Rte(){return s.jsxs("div",{className:"bg-dark",children:[s.jsx(Xa,{title:"Haka Insight - Analisis de Codigo con IA",description:"Analisis inteligente de codigo fuente con IA para identificar riesgos y oportunidades de testing en tu proyecto.",path:"/haka-insight"}),s.jsx(jte,{}),s.jsx(Tte,{}),s.jsx(Nte,{}),s.jsx(Ite,{}),s.jsx(Pte,{}),s.jsx(Zr,{productIds:[1,2,3,4,5]})]})}function Lte(){const t=k.useRef(null),e=we(t,{once:!0,margin:"-100px"}),[a,n]=k.useState(0),i=[{label:"Web",path:"M21 12a9 9 0 01-9 9m9-9a9 9 0 00-9-9m9 9H3m9 9a9 9 0 01-9-9m9 9c1.657 0 3-4.03 3-9s-1.343-9-3-9m0 18c-1.657 0-3-4.03-3-9s1.343-9 3-9m-9 9a9 9 0 019-9"},{label:"Mobile",path:"M12 18h.01M8 21h8a2 2 0 002-2V5a2 2 0 00-2-2H8a2 2 0 00-2 2v14a2 2 0 002 2z"},{label:"API",path:"M8 9l3 3-3 3m5 0h3M5 20h14a2 2 0 002-2V6a2 2 0 00-2-2H5a2 2 0 00-2 2v12a2 2 0 002 2z"},{label:"BBDD",path:"M4 7v10c0 2.21 3.582 4 8 4s8-1.79 8-4V7M4 7c0 2.21 3.582 4 8 4s8-1.79 8-4M4 7c0-2.21 3.582-4 8-4s8 1.79 8 4m0 5c0 2.21-3.582 4-8 4s-8-1.79-8-4"},{label:"Desktop",path:"M9.75 17L9 20l-1 1h8l-1-1-.75-3M3 13h18M5 17h14a2 2 0 002-2V5a2 2 0 00-2-2H5a2 2 0 00-2 2v10a2 2 0 002 2z"},{label:"IA",path:"M9.663 17h4.673M12 3v1m6.364 1.636l-.707.707M21 12h-1M4 12H3m3.343-5.657l-.707-.707m2.828 9.9a5 5 0 117.072 0l-.548.547A3.374 3.374 0 0014 18.469V19a2 2 0 11-4 0v-.531c0-.895-.356-1.754-.988-2.386l-.548-.547z"}];return k.useEffect(()=>{const r=setInterval(()=>{n(o=>(o+1)%i.length)},1500);return()=>clearInterval(r)},[i.length]),s.jsx(s.Fragment,{children:s.jsxs("section",{ref:t,className:"relative bg-dark pt-1 pb-2 text-center",children:[s.jsx("div",{className:"hero-glow -mt-24"}),s.jsx("div",{className:"max-w-1xl mx-auto px-4 sm:px-6 md:px-8 mt-24 mb-14",children:s.jsxs(_.div,{initial:{opacity:0,y:30},animate:e?{opacity:1,y:0}:{},transition:{duration:.6,delay:.2},className:"max-w-3xl mx-auto w-full flex flex-col items-center justify-center",children:[s.jsx(_.img,{initial:{opacity:0,scale:.8},animate:e?{opacity:1,scale:1}:{},transition:{duration:.6,delay:.3},src:"/imagenes/productos/haka automation ide.png",alt:"Haka Playwright Engine Logo",className:"sm:w-full max-w-[390px] sm:max-w-lg lg:max-w-xl h-auto drop-shadow-2xl object-contain"}),s.jsx(_.p,{initial:{opacity:0,y:20},animate:e?{opacity:1,y:0}:{},transition:{duration:.6,delay:.4},className:"text-2xl w-full mt-2 mb-2 text-gray-300",children:"Acelera la construcción de pruebas automatizadas hasta en un 80%"}),s.jsxs(_.h1,{initial:{opacity:0,y:20},animate:e?{opacity:1,y:0}:{},transition:{duration:.6,delay:.5},className:"text-4xl font-bold text-white mb-5 mt-16 ",children:["Framework BDD con ",s.jsx("span",{className:"text-cyan-400",children:"1800+"})," Steps Múlticapa"]}),s.jsx(_.div,{initial:{opacity:0,y:20},animate:e?{opacity:1,y:0}:{},transition:{duration:.6,delay:.7},className:"mt-0 flex flex-wrap items-center justify-center gap-3",children:i.map((r,o)=>s.jsxs("div",{className:"flex items-center gap-3",children:[s.jsxs("div",{className:"flex flex-col items-center gap-1",children:[s.jsx("div",{className:`
3802                                            w-12 h-12 rounded-lg bg-slate-800/80 flex items-center justify-center
3803                                            transition-all duration-500 ease-in-out
3804                                            ${a===o?"border-2 border-cyan-400 shadow-[0_0_15px_rgba(34,211,238,0.6)] text-cyan-300 scale-110":"border border-cyan-400/30 text-cyan-400/60"}
3805                                        `,children:s.jsx("svg",{className:"w-6 h-6",fill:"none",viewBox:"0 0 24 24",stroke:"currentColor",children:s.jsx("path",{strokeLinecap:"round",strokeLinejoin:"round",strokeWidth:2,d:r.path})})}),s.jsx("span",{className:`text-[10px] transition-all duration-500 ${a===o?"text-cyan-300":"text-gray-400"}`,children:r.label})]}),o<i.length-1&&s.jsx("span",{className:"text-cyan-400/40 font-bold text-lg",children:"+"})]},o))})]})}
3805),s.jsx(ie,{color:"#0a0e27",variant:1})]})})}function Ote(){const t=k.useRef(null),e=we(t,{once:!0,margin:"-100px"}),[a,n]=k.useState(!1),[i,r]=k.useState(!1),[o,l]=k.useState(0),c=[{title:"Construcción de Feature",desc:"Escenarios BDD en Gherkin con +1.800 steps predefinidos. Soporta Scenario Outline con tablas de datos, Background compartido, tags para filtrar ejecución y variables dinámicas.",detail:"Asistido por Haka AI Studio (complemento VS Code con IA), el catálogo visual de Haka UI, grabación de flujos con Haka Conector, o documentación oficial. Sin escribir código Python."},{title:"Runner",desc:"Ejecuta los escenarios seleccionados por tags, en modo serial o paralelo. Selección inteligente de features según la matriz de pruebas.",detail:"Compatible con ejecución local y en pipelines de CI/CD (GitHub Actions, Azure Pipelines, GitLab CI). Soporta reintentos automáticos de escenarios fallidos y modo headless."},{title:"Ejecución en tiempo real",desc:"Chromium, Firefox, WebKit y Chrome real. Interacción realista: clicks, formularios, drag & drop, iframes, modales, scroll, teclado, uploads y descargas.",detail:"Self-healing con IA: si un localizador se rompe, el framework lo corrige automáticamente. Evidencia automática: screenshot por paso, grabación de video y data snapshots."},{title:"Reportes y Dashboards",desc:"Reportes HTML portables con screenshots embebidos, request/response de API, evaluaciones de IA y métricas de performance. Se generan automáticamente.",detail:"Integración push & play con Jira (comentarios + adjuntos), Xray Cloud (Test Executions), Azure DevOps, Cassini (dashboard centralizado) y Haka Lens."}];k.useEffect(()=>{const u=setInterval(()=>{l(p=>(p+1)%c.length)},3e3);return()=>clearInterval(u)},[c.length]);const d=[{icon:s.jsx("svg",{className:"w-8 h-8",fill:"none",viewBox:"0 0 24 24",stroke:"currentColor",children:s.jsx("path",{strokeLinecap:"round",strokeLinejoin:"round",strokeWidth:2,d:"M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2m-6 9l2 2 4-4"})}),title:"1.800+ Steps Listos",description:"Pasos predefinidos para aplicaciones web, API, mobile, desktop, base de datos, performance, geolocalización, Gen AI y más."},{icon:s.jsx("svg",{className:"w-8 h-8",fill:"none",viewBox:"0 0 24 24",stroke:"currentColor",children:s.jsx("path",{strokeLinecap:"round",strokeLinejoin:"round",strokeWidth:2,d:"M9.663 17h4.673M12 3v1m6.364 1.636l-.707.707M21 12h-1M4 12H3m3.343-5.657l-.707-.707m2.828 9.9a5 5 0 117.072 0l-.548.547A3.374 3.374 0 0014 18.469V19a2 2 0 11-4 0v-.531c0-.895-.356-1.754-.988-2.386l-.548-.547z"})}),title:"Agentes de IA especializados",description:"Nuestro IDE integra agentes de IA especializados en construcción, ejecución y análisis de pruebas, que asisten en cada etapa del ciclo de calidad."},{icon:s.jsx("svg",{className:"w-8 h-8",fill:"none",viewBox:"0 0 24 24",stroke:"currentColor",children:s.jsx("path",{strokeLinecap:"round",strokeLinejoin:"round",strokeWidth:2,d:"M12 15v2m-6 4h12a2 2 0 002-2v-6a2 2 0 00-2-2H6a2 2 0 00-2 2v6a2 2 0 002 2zm10-10V7a4 4 0 00-8 0v4h8z"})}),title:"Integración CI/CD",description:"Integra tus pruebas en pipelines de CI/CD para validación continua y automatizada, garantizando el gobierno de datos y la trazabilidad en cada ejecución."},{icon:s.jsx("svg",{className:"w-8 h-8",fill:"none",viewBox:"0 0 24 24",stroke:"currentColor",children:s.jsx("path",{strokeLinecap:"round",strokeLinejoin:"round",strokeWidth:2,d:"M13 10V3L4 14h7v7l9-11h-7z"})}),title:"Integración Plug & Play",description:"Integración push and play con Jira, Azure, Xray y dashboards personalizados. Conecta tu gestión de pruebas en minutos."}];return s.jsxs(s.Fragment,{children:[s.jsxs("section",{ref:t,className:"relative bg-dark pt-24 pb-20 mt-10",children:[s.jsxs("div",{className:"max-w-7xl mx-auto px-4 sm:px-6 md:px-8",children:[s.jsxs(_.div,{initial:{opacity:0,y:20},animate:e?{opacity:1,y:0}:{},transition:{duration:.6},className:"text-center mb-16",children:[s.jsx("h2",{className:"text-3xl md:text-4xl font-extrabold text-white leading-tight uppercase tracking-tight",children:"Características Principales"}),s.jsx("div",{className:"h-2 w-32 bg-cyan-400 mt-2 mb-6 mx-auto"}),s.jsx("p",{className:"text-xl text-gray-400",children:"Haka Automation + IDE provee todo lo necesario para la automatización de pruebas en todas las capas del desarrollo de forma sencilla y segura, utilizando Inteligencia Artificial de forma estratég
3805ica desde la construcción hasta la ejecución, resultados y observabilidad."})]}),s.jsxs("div",{className:"grid grid-cols-1 lg:grid-cols-2 gap-12 items-start",children:[s.jsxs(_.div,{initial:{opacity:0,x:-30},animate:e?{opacity:1,x:0}:{},transition:{duration:.6,delay:.2},className:"relative rounded-2xl overflow-hidden border border-cyan-400/20 shadow-xl shadow-cyan-500/10",children:[!a&&s.jsxs("div",{className:"absolute inset-0 flex flex-col items-center justify-center bg-gray-900/90 z-10",children:[s.jsx("div",{className:"w-12 h-12 border-4 border-cyan-400/30 border-t-cyan-400 rounded-full animate-spin mb-4"}),s.jsx("p",{className:"text-gray-400 text-sm",children:"Cargando demo..."})]}),s.jsx("video",{autoPlay:!0,muted:!0,loop:!0,playsInline:!0,preload:"auto",className:`w-full h-auto transition-opacity duration-500 ${a?"opacity-100":"opacity-0"}`,onCanPlayThrough:()=>n(!0),onLoadedData:()=>n(!0),onError:()=>n(!0),children:s.jsx("source",{src:"/video/haka-engine-demo.mp4",type:"video/mp4"})})]}),s.jsx(_.div,{initial:{opacity:0,x:30},animate:e?{opacity:1,x:0}:{},transition:{duration:.6,delay:.4},className:"grid grid-cols-1 sm:grid-cols-2 gap-4",children:d.map((u,p)=>s.jsxs(_.div,{initial:{opacity:0,y:15},animate:e?{opacity:1,y:0}:{},transition:{duration:.4,delay:.5+p*.15},className:"flex gap-4 p-5 rounded-xl border border-gray-700/50 bg-gray-800/30 hover:border-cyan-400/40 hover:bg-cyan-400/5 transition-all duration-300",children:[s.jsx("div",{className:"flex-shrink-0 text-cyan-400 mt-1",children:u.icon}),s.jsxs("div",{children:[s.jsx("h3",{className:"font-bold text-white text-lg mb-1",children:u.title}),s.jsx("p",{className:"text-gray-400 text-sm leading-relaxed",children:u.description})]})]},p))})]}),s.jsxs("div",{className:"grid grid-cols-1 lg:grid-cols-2 gap-12 items-start mt-24",children:[s.jsx(_.div,{initial:{opacity:0,x:-30},animate:e?{opacity:1,x:0}:{},transition:{duration:.6,delay:.3},className:"grid grid-cols-1 sm:grid-cols-2 gap-4",children:[{icon:s.jsx("svg",{className:"w-8 h-8",fill:"none",viewBox:"0 0 24 24",stroke:"currentColor",children:s.jsx("path",{strokeLinecap:"round",strokeLinejoin:"round",strokeWidth:2,d:"M9.663 17h4.673M12 3v1m6.364 1.636l-.707.707M21 12h-1M4 12H3m3.343-5.657l-.707-.707m2.828 9.9a5 5 0 117.072 0l-.548.547A3.374 3.374 0 0014 18.469V19a2 2 0 11-4 0v-.531c0-.895-.356-1.754-.988-2.386l-.548-.547z"})}),title:"Grabación de flujos",description:"Captura un flujo funcional directamente desde el navegador y genera la prueba automáticamente, sin escribir código."},{icon:s.jsx("svg",{className:"w-8 h-8",fill:"none",viewBox:"0 0 24 24",stroke:"currentColor",children:s.jsx("path",{strokeLinecap:"round",strokeLinejoin:"round",strokeWidth:2,d:"M15 10l4.553-2.276A1 1 0 0121 8.618v6.764a1 1 0 01-1.447.894L15 14M5 18h8a2 2 0 002-2V8a2 2 0 00-2-2H5a2 2 0 00-2 2v8a2 2 0 002 2z"})}),title:"Sesiones 2FA/MFA",description:"Sesiones almacenadas para sistemas con doble factor de autenticación: login manual una vez, ejecución automática siempre."},{icon:s.jsx("svg",{className:"w-8 h-8",fill:"none",viewBox:"0 0 24 24",stroke:"currentColor",children:s.jsx("path",{strokeLinecap:"round",strokeLinejoin:"round",strokeWidth:2,d:"M9.75 17L9 20l-1 1h8l-1-1-.75-3M3 13h18M5 17h14a2 2 0 002-2V5a2 2 0 00-2-2H5a2 2 0 00-2 2v10a2 2 0 002 2z"})}),title:"Evidencia automática",description:"Screenshot por paso, grabación de video y data snapshots generados automáticamente en cada corrida, sin configuración adicional."},{icon:s.jsx("svg",{className:"w-8 h-8",fill:"none",viewBox:"0 0 24 24",stroke:"currentColor",children:s.jsx("path",{strokeLinecap:"round",strokeLinejoin:"round",strokeWidth:2,d:"M4 5a1 1 0 011-1h14a1 1 0 011 1v2a1 1 0 01-1 1H5a1 1 0 01-1-1V5zm0 8a1 1 0 011-1h6a1 1 0 011 1v6a1 1 0 01-1 1H5a1 1 0 01-1-1v-6zm12 0a1 1 0 011-1h2a1 1 0 011 1v6a1 1 0 01-1 1h-2a1 1 0 01-1-1v-6z"})}),title:"Validación de Gen AI",description:"Steps dedicados para probar servicios de IA generativa: evalúa respuestas de modelos y valida la calidad de las salidas dentro de tus escenarios."}].map((u,p)=>s.jsxs(_.div,{initial:{opacity:0,y:15},animate:e?{opacity:1,y:0}:{},transition:{duration:.4,delay:.5+p*.15},className:"flex gap-4 p-5 rounded-xl border border-gray-700/50 bg-gray-800/30 hover:border-cyan-400/40 hover:bg-cyan-400/5 transition-all duration-300",children:[s.jsx("div",{className:"flex-shrink-0 w-12 h-12 rounded-lg bg-cyan-400/10 border border-cyan-400/30 flex items-center justify-center text-cyan-400",children:u.icon}),s.jsxs("div",{children:[s.jsx("h3",{className:"font-bold text-white text-lg mb-1",children:u.title}),s.jsx("p",{className:"text-gray-400 text-sm leading-relaxed",children:u.description})]})]},p))}),s.jsxs(_.div,{initial:{opacity:0,x:30},animate:e?{opacity:1,x:0}:{},transition:{duration:.6,delay:.4},className:"relative rounded-2xl overflow-hidden border border-cyan-400/20 shadow-xl shadow-cyan-500/10 sticky top-8",children:[!i&&s.jsxs("div",{className:"absolute inset-0 flex flex-col items-center justify-center bg-gray-900/90 z-10",children:[s.jsx("div",{className:"w-12 h-12 border-4 border-cyan-400/30 border-t-cyan-400 rounded-full animate-spin mb
3805-4"}),s.jsx("p",{className:"text-gray-400 text-sm",children:"Cargando demo..."})]}),s.jsx("video",{autoPlay:!0,muted:!0,loop:!0,playsInline:!0,preload:"auto",className:`w-full h-auto transition-opacity duration-500 ${i?"opacity-100":"opacity-0"}`,onCanPlayThrough:()=>r(!0),onLoadedData:()=>r(!0),onError:()=>r(!0),children:s.jsx("source",{src:"/video/haka-engine-tools-v2.mp4",type:"video/mp4"})})]})]})]}),s.jsx(ie,{color:"#0a0e27",variant:1})]}),s.jsxs("section",{className:"relative bg-dark pt-32 pb-20",children:[s.jsx("div",{className:"max-w-7xl mx-auto px-4 sm:px-6 md:px-8",children:s.jsxs(_.div,{initial:{opacity:0,y:30},animate:e?{opacity:1,y:0}:{},transition:{duration:.6,delay:.8},children:[s.jsx("h3",{className:"text-3xl md:text-4xl font-extrabold text-white leading-tight uppercase tracking-tight",children:"Flujo de acción"}),s.jsx("div",{className:"h-2 w-32 bg-cyan-400 mt-2 mb-12"}),s.jsx("div",{className:"space-y-6",children:c.map((u,p)=>s.jsxs("div",{className:`
3806                                    grid grid-cols-1 lg:grid-cols-[1fr_auto_1fr] gap-4 items-center
3807                                    transition-all duration-700 ease-in-out
3808                                    ${o===p?"scale-[1.02]":"scale-100 opacity-70"}
3809                                `,style:{marginLeft:`${p*40}px`},children:[s.jsxs("div",{className:`
3810                                    p-5 rounded-xl border-l-4 transition-all duration-700
3811                                    ${o===p?"border-cyan-400 bg-cyan-400/10 shadow-lg shadow-cyan-400/20":"border-cyan-400/30 bg-slate-800/50"}
3812                                `,children:[s.jsx("h4",{className:`font-bold text-lg mb-2 transition-colors duration-500 ${o===p?"text-cyan-300":"text-cyan-400/70"}`,children:u.title}),s.jsx("p",{className:`text-sm transition-colors duration-500 ${o===p?"text-gray-200":"text-gray-400"}`,children:u.desc})]}),s.jsxs("div",{className:"hidden lg:flex items-center gap-1 px-2",children:[s.jsx("div",{className:`w-8 border-t-2 border-dashed transition-colors duration-500 ${o===p?"border-cyan-400":"border-cyan-400/30"}`}),s.jsx("div",{className:`w-2 h-2 rounded-full transition-all duration-500 ${o===p?"bg-cyan-400 shadow-[0_0_8px_rgba(34,211,238,0.8)]":"bg-cyan-400/40"}`}),s.jsx("div",{className:`w-2 h-2 rounded-full transition-all duration-500 ${o===p?"bg-cyan-400/80":"bg-cyan-400/20"}`}),s.jsx("div",{className:`w-8 border-t-2 border-dashed transition-colors duration-500 ${o===p?"border-cyan-400":"border-cyan-400/30"}`})]}),s.jsx("div",{className:`
3813                                    p-4 rounded-xl border border-dashed transition-all duration-700
3814                                    ${o===p?"border-cyan-400/60 bg-cyan-400/5 shadow-md shadow-cyan-400/10":"border-gray-500/30 bg-gray-800/20"}
3815                                `,children:s.jsx("p",{className:`text-sm transition-colors duration-500 ${o===p?"text-gray-300":"text-gray-500"}`,children:u.detail})})]},p))})]})}),s.jsx(ie,{color:"#0a0e27",variant:2})]})]})}function Mte(){const t=k.useRef(null),e=we(t,{once:!0,margin:"-100px"}),[a,n]=k.useState(null),i=[{question:"¿Necesito saber programar para usar el framework?",answer:"El framework resuelve +95% de los casos sin necesidad de escribir código, y los asistentes de IA pueden aumentar aún más ese porcentaje. Sin embargo, se considera necesario tener nociones de Python y Playwright para construir pasos personalizados cuando el flujo requiera una casuística o paso demasiado especializado o particular."},{question:"¿Qué tipos de pruebas puedo automatizar?",answer:"Pruebas web (cualquier navegador), API REST, mobile (Android/iOS con Appium), desktop (PyAutoGUI), base de datos, y combinaciones de todas ellas en un mismo escenario."},{question:"¿Cómo maneja los selectores que se rompen?",answer:"El JSON POM soporta fallbacks: si el selector principal falla, el framework prueba automáticamente los alternativos. Con IA activa, puede encontrar selectores nuevos sin intervención."},{question:"¿Funciona con sistemas que tienen MFA/2FA?",answer:"Sí. Las sesiones guardadas permiten hacer login manualmente una vez (incluyendo MFA) y reutilizar el estado del navegador en todas las ejecuciones posteriores."},{question:"¿Se integra con Jira y herramientas de gestión?",answer:"Sí. Se integra con Xray Cloud para reportar resultados, con Cassini para gestión de ejecuciones, y con Haka Lens para crear bugs automáticamente cuando un test falla."},{question:"¿Puedo ejecutar tests en paralelo?",answer:"Sí. Configurando PARALLEL_WORKERS en el .env, el framework ejecuta múltiples features simultáneamente, cada uno con su propio navegador."},{question:"¿Es compatible con CI/CD?",answer:"Totalmente. Funciona en GitHub Actions, GitLab CI, Jenkins y cualquier pipeline. Solo necesita Python y el pip install. Genera reportes HTML y screenshots automáticos en fallos."}];return s.jsx("section",{ref:t,className:"relative bg-dark py-20",children:s.jsxs("div",{className:"max-w-4xl mx-auto px-4 sm:px-6 md:px-8",children:[s.jsxs(_.div,{initial:{opacity:0,y:20},animate:e?{opacity:1,y:0}:{},transition:{duration:.6},className:"text-center mb-12",children:[s.jsx("h2",{className:"text-4xl font-bold text-white mb-4",children:"Preguntas Frecuentes"}),s.jsx("p",{className:"text-xl text-gray-400",children:"Lo que más nos preguntan sobre el framework"})]}),s.jsx("div",{className:"space-y-4",children:i.map((r,o)=>s.jsxs(_.div,{initial:{opacity:0,y:20},animate:e?{opacity:1,y:0}:{},transition:{duration:.5,delay:o*.05},className:"bg-slate-800/50 border border-slate-700 rounded-xl overflow-hidden",children:[s.jsxs("button",{onClick:()=>
3815n(a===o?null:o),className:"w-full px-6 py-5 flex items-center justify-between text-left hover:bg-slate-700/30 transition-colors",children:[s.jsx("span",{className:"font-semibold text-white text-lg pr-4",children:r.question}),s.jsx("svg",{className:`w-5 h-5 text-emerald-400 flex-shrink-0 transition-transform ${a===o?"rotate-180":""}`,fill:"none",viewBox:"0 0 24 24",stroke:"currentColor",children:s.jsx("path",{strokeLinecap:"round",strokeLinejoin:"round",strokeWidth:2,d:"M19 9l-7 7-7-7"})})]}),a===o&&s.jsx(_.div,{initial:{height:0,opacity:0},animate:{height:"auto",opacity:1},transition:{duration:.3},className:"px-6 pb-5",children:s.jsx("p",{className:"text-gray-300 leading-relaxed",children:r.answer})})]},o))})]})})}function Dte(){const{isOpen:t,modalTitle:e,openModal:a,closeModal:n}=oa();return s.jsxs("div",{className:"bg-dark",children:[s.jsx(Xa,{title:"Haka Playwright Engine - Framework de Testing Automatizado",description:"Framework de testing automatizado basado en Playwright con soporte BDD, ejecucion en paralelo, reportes integrados y compatibilidad mobile.",path:"/haka-engine"}),s.jsx(Lte,{}),s.jsx(Ote,{}),s.jsx("section",{className:"relative bg-dark py-20 mt-16",children:s.jsx("div",{className:"max-w-7xl mx-auto px-4 sm:px-6 md:px-8",children:s.jsxs("div",{className:"grid grid-cols-1 lg:grid-cols-2 gap-12 items-center",children:[s.jsxs(_.div,{initial:{opacity:0,x:-30},whileInView:{opacity:1,x:0},viewport:{once:!0},transition:{duration:.6},children:[s.jsx("svg",{className:"w-10 h-10 text-cyan-400/40 mb-4",fill:"currentColor",viewBox:"0 0 24 24",children:s.jsx("path",{d:"M14.017 21v-7.391c0-5.704 3.731-9.57 8.983-10.609l.995 2.151c-2.432.917-3.995 3.638-3.995 5.849h4v10h-9.983zm-14.017 0v-7.391c0-5.704 3.748-9.57 9-10.609l.996 2.151c-2.433.917-3.996 3.638-3.996 5.849h3.983v10h-9.983z"})}),s.jsx("blockquote",{className:"text-xl md:text-2xl text-gray-200 font-light leading-relaxed italic mb-6",children:'"Con la generación de código con IA, se le está pidiendo a los equipos que validen un orden de magnitud más de código manteniendo la misma capacidad de QA. El resultado es un cuello de botella en las pruebas: los lanzamientos se frenan, las funciones de IA se acumulan en preproducción y los equipos de ingeniería reciben la presión por limitaciones que ellos no crearon. La respuesta no es ralentizar la innovación, sino hacer evolucionar la ingeniería de calidad al mismo ritmo que la generación de código."'}),s.jsx("a",{href:"https://kms-technology.com/blog/the-testing-bottleneck-how-ai-coding-broke-qa-and-how-to-fix-it/",target:"_blank",rel:"noopener noreferrer",className:"text-cyan-400 text-sm hover:underline",children:"KMS Technology — The Testing Bottleneck"})]}),s.jsx(_.div,{initial:{opacity:0,x:30},whileInView:{opacity:1,x:0},viewport:{once:!0},transition:{duration:.6,delay:.2},className:"relative",children:s.jsxs("div",{className:"relative bg-gradient-to-br from-[#1a1d3a] to-[#0a0e27] rounded-2xl border border-gray-700/50 shadow-2xl overflow-hidden",children:[s.jsxs("div",{className:"bg-[#2a2d4a] px-4 py-3 flex items-center gap-2 border-b border-gray-700/50",children:[s.jsxs("div",{className:"flex gap-2",children:[s.jsx("div",{className:"w-3 h-3 rounded-full bg-red-500"}),s.jsx("div",{className:"w-3 h-3 rounded-full bg-yellow-500"}),s.jsx("div",{className:"w-3 h-3 rounded-full bg-green-500"})]}),s.jsx("span",{className:"text-gray-400 text-sm ml-4",children:"Haka Automation Engine"})]}),s.jsxs("div",{className:"p-8 sm:p-10 text-center",children:[s.jsxs("h2",{className:"text-lg md:text-xl font-normal text-white mb-4",children:["En ",s.jsxs("span",{className:"font-bold",children:[s.jsx("span",{className:"text-cyan-400",children:"Haka"})," Lab"]})," tenemos la tecnología, la metodología y las personas que pueden ayudar a tus equipos de desarrollo a alcanzar sus objetivos con calidad"]}),s.jsx("button",{onClick:()=>a("Solicitar demo de Haka Automation Engine"),className:"mt-6 inline-block px-8 py-3 bg-transparent border-2 border-cyan-400 text-cyan-400 rounded-2xl font-semibold hover:bg-cyan-400 hover:text-[#0a0e27] transition-all duration-300 transform hover:scale-105",children:"Solicitar una demo"})]})]})})]})})}),s.jsx(Mte,{}),s.jsx(Zr,{productIds:[0,1,3,5]}),s.jsx(Yr,{isOpen:t,onClose:n,title:e})]})}function qte(){const t=k.useRef(null),e=we(t,{once:!0,margin:"-100px"}),{t:a}=$();return s.jsxs("section",{ref:t,className:"relative bg-dark pt-20 pb-16 text-center",children:[s.jsx("div",{className:"hero-glow"}),s.jsxs("div",{className:"max-w-1xl mx-auto px-4 sm:px-6 md:px-8",children:[s.jsx(_.div,{initial:{opacity:0,y:-30},animate:e?{opacity:1,y:0}:{},transition:{duration:.6},className:"flex justify-center mb-12",children:s.jsx("img",{src:"/imagenes/productos/hakaistudio_hero.png",alt:"Haka AI Studio Interface",className:"w-full max-w-3xl h-auto drop-shadow-2xl"})}),s.jsxs(_.div,{initial:{opacity:0,y:30},animate:e?{opacity:1,y:0}:{},transition:{duration:.6,delay:.2},className:"max-w-3xl mx-auto w-full flex flex-col items-center justify-center",children:[s.jsx(_.img,{initial:{opacity:0,scale:.8},animate:e?{opacity:1,scale:1}:{},transition:{duration:.6,delay:.3},src:"/imagenes/productos/hakaistudio_logo.png",alt:"Haka AI Studio Logo",className:"sm:w-full max-w-[300px] sm:max-w-md lg:max-w-lg h-auto drop-shadow-2xl object-contain"}),s.jsx(_.p,{initial:{opacity:0,y:20},animate:e?{opacity:1,y:0}:{},transition:{duration:.6,delay:.4},className:"text-xl w-full mt-3 text-gray-300",children:a("hakaistudio.hero.descripcion")}),s.jsx(_.h1,{initial:{opacity:0,y:20},animate:e?{opacity:1,y:0}:{},transition:{duration:.6,delay:.5},className:"text-4xl font-bold text-white mt-3",children:a("hakaistudio.hero.exclusivo")}),s.jsxs(_.div,{initial:{opacity:0,y:20},animate:e?{opacity:1,y:0}:{},transition:{duration:.6,delay:.6},className:"mt-6 flex flex-wrap justify-center gap-2",children:[["VS Code","Kiro","Antigravity","Cursor","Windsurf"].map(n=>s.jsx("span",{className:"px-3 py-1 bg-cyan-400/10 border border-cyan-400/40 text-cyan-300 text-sm font-medium rounded-full",children:n},n)),s.jsx("span",{className:"px-3 py-1 bg-violet-400/10 border border-violet-400/40 text-violet-300 text-sm font-medium rounded-full",children:"+ cualquier editor VSX"})]}),s.jsxs(_.a,{href:"https://open-vsx.org/extension/HakaLabChile/haka-ai-studio",target:"_blank",rel:"noopener noreferrer",initial:{opacity:0,y:20},animate:e?{opacity:1,y:0}:{},transition:{duration:.6,delay:.7},className:"mt-6 inline-flex items-center gap-3 bg-cyan-400 hover:bg-cyan-300 text-[#0a0e27] font-bold px-8 py-3 rounded-full transition-all duration-300 hover:shadow-lg hover:shadow-cyan-400/50 transform hover:-translate-y-1",children:[s.jsx("svg",{className:"w-5 h-5",fill:"none",viewBox:"0 0 24 24",stroke:"currentColor",children:s.jsx("path",{strokeLinecap:"round",strokeLinejoin:"round",strokeWidth:2,d:"M4 16v1a3 3 0 003 3h10a3 3 0 003-3v-1m-4-4l-4 4m0 0l-4-4m4 4V4"})}),"Descargar en Open VSX"]}),s.jsx(_.p,{initial:{opacity:0}
3815,animate:e?{opacity:1}:{},transition:{duration:.6,delay:.8},className:"mt-3 text-sm text-gray-500",children:"O búscalo directamente en el marketplace de tu editor favorito"})]})]}),s.jsx(ie,{color:"#0a0e27",variant:1})]})}function zte(){const t=k.useRef(null),e=we(t,{once:!0,margin:"-100px"}),{t:a}=$(),[n,i]=k.useState(0),r=[{icon:s.jsxs("svg",{className:"w-12 h-12",fill:"none",viewBox:"0 0 24 24",stroke:"currentColor",children:[s.jsx("path",{strokeLinecap:"round",strokeLinejoin:"round",strokeWidth:1.5,d:"M10.325 4.317c.426-1.756 2.924-1.756 3.35 0a1.724 1.724 0 002.573 1.066c1.543-.94 3.31.826 2.37 2.37a1.724 1.724 0 001.065 2.572c1.756.426 1.756 2.924 0 3.35a1.724 1.724 0 00-1.066 2.573c.94 1.543-.826 3.31-2.37 2.37a1.724 1.724 0 00-2.572 1.065c-.426 1.756-2.924 1.756-3.35 0a1.724 1.724 0 00-2.573-1.066c-1.543.94-3.31-.826-2.37-2.37a1.724 1.724 0 00-1.065-2.572c-1.756-.426-1.756-2.924 0-3.35a1.724 1.724 0 001.066-2.573c-.94-1.543.826-3.31 2.37-2.37.996.608 2.296.07 2.572-1.065z"}),s.jsx("path",{strokeLinecap:"round",strokeLinejoin:"round",strokeWidth:1.5,d:"M15 12a3 3 0 11-6 0 3 3 0 016 0z"})]}),title:a("hakaistudio.presentacion.etapas.automatizacion.titulo"),description:a("hakaistudio.presentacion.etapas.automatizacion.descripcion")},{icon:s.jsx("svg",{className:"w-12 h-12",fill:"none",viewBox:"0 0 24 24",stroke:"currentColor",children:s.jsx("path",{strokeLinecap:"round",strokeLinejoin:"round",strokeWidth:1.5,d:"M12 15v2m-6 4h12a2 2 0 002-2v-6a2 2 0 00-2-2H6a2 2 0 00-2 2v6a2 2 0 002 2zm10-10V7a4 4 0 00-8 0v4h8z"})}),title:a("hakaistudio.presentacion.etapas.seguridad.titulo"),description:a("hakaistudio.presentacion.etapas.seguridad.descripcion")},{icon:s.jsx("svg",{className:"w-12 h-12",fill:"none",viewBox:"0 0 24 24",stroke:"currentColor",children:s.jsx("path",{strokeLinecap:"round",strokeLinejoin:"round",strokeWidth:1.5,d:"M9.663 17h4.673M12 3v1m6.364 1.636l-.707.707M21 12h-1M4 12H3m3.343-5.657l-.707-.707m2.828 9.9a5 5 0 117.072 0l-.548.547A3.374 3.374 0 0014 18.469V19a2 2 0 11-4 0v-.531c0-.895-.356-1.754-.988-2.386l-.548-.547z"})}),title:a("hakaistudio.presentacion.etapas.ia.titulo"),description:a("hakaistudio.presentacion.etapas.ia.descripcion")},{icon:s.jsx("svg",{className:"w-12 h-12",fill:"none",viewBox:"0 0 24 24",stroke:"currentColor",children:s.jsx("path",{strokeLinecap:"round",strokeLinejoin:"round",strokeWidth:1.5,d:"M17 20h5v-2a3 3 0 00-5.356-1.857M17 20H7m10 0v-2c0-.656-.126-1.283-.356-1.857M7 20H2v-2a3 3 0 015.356-1.857M7 20v-2c0-.656.126-1.283.356-1.857m0 0a5.002 5.002 0 019.288 0M15 7a3 3 0 11-6 0 3 3 0 016 0zm6 3a2 2 0 11-4 0 2 2 0 014 0zM7 10a2 2 0 11-4 0 2 2 0 014 0z"})}),title:a("hakaistudio.presentacion.etapas.talento.titulo"),description:a("hakaistudio.presentacion.etapas.talento.descripcion")},{icon:s.jsx("svg",{className:"w-12 h-12",fill:"none",viewBox:"0 0 24 24",stroke:"currentColor",children:s.jsx("path",{strokeLinecap:"round",strokeLinejoin:"round",strokeWidth:1.5,d:"M13 7h8m0 0v8m0-8l-8 8-4-4-6 6"})}),title:a("hakaistudio.presentacion.etapas.impacto.titulo"),description:a("hakaistudio.presentacion.etapas.impacto.descripcion")}];return k.useEffect(()=>{const o=setInterval(()=>{i(l=>(l+1)%r.length)},3e3);return()=>clearInterval(o)},[r.length]),s.jsx("section",{ref:t,className:"relative bg-gradient-to-b from-slate-950 to-blue-900 pt-16 sm:pt-40 pb-20 text-center overflow-hidden",children:s.jsxs("div",{className:"max-w-6xl mx-auto px-4 sm:px-6 md:px-8",children:[s.jsx(_.h2,{initial:{opacity:0,y:20},animate:e?{opacity:1,y:0}:{},transition:{duration:.6,delay:.3},className:"text-4xl md:text-5xl font-bold text-white mb-6",children:a("hakaistudio.presentacion.titulo")}),s.jsx(_.p,{initial:{opacity:0,y:20},animate:e?{opacity:1,y:0}:{},transition:{duration:.6,delay:.4},className:"text-xl text-gray-300 mb-8 max-w-4xl mx-auto",children:a("hakaistudio.presentacion.subtitulo")}),s.jsxs(_.div,{initial:{opacity:0,y:10},animate:e?{opacity:1,y:0}:{},transition:{duration:.6,delay:.5},className:"inline-flex items-center gap-3 bg-gradient-to-r from-violet-500/20 to-cyan-500/20 border border-violet-400/30 rounded-full px-6 py-3 mb-16",children:[s.jsx("svg",{className:"w-5 h-5 text-violet-400",fill:"none",viewBox:"0 0 24 24",stroke:"currentColor",children:s.jsx("path",{strokeLinecap:"round",strokeLinejoin:"round",strokeWidth:2,d:"M10 20l4-16m4 4l4 4-4 4M6 16l-4-4 4-4"})}),s.jsxs("span",{className:"text-sm text-gray-300",children:["Extensión ",s.jsx("span",{className:"text-violet-300 font-semibold",children:"VSX"})," compatible con"," ",s.jsx("span",{className:"text-cyan-300 font-semibold",children:"VS Code · Kiro · Antigravity · Cursor · Windsurf"})]})]}),s.jsxs("div",{className:"relative mt-16",children:[s.jsx("div",{className:"absolute top-8 left-0 right-0 h-1 bg-gray-700",children:s.jsx(_.div,{className:"h-full bg-gradient-to-r from-blue-500 to-purple-500",initial:{width:"0%"},animate:{width:`${n/(r.length-1)*100}%`},transition:{duration:.8,ease:"easeInOut"}})}),s.jsx(_.div,{className:"absolute top-4 w-8 h-8 bg-gradient-to-r from-blue-500 to-purple-500 rounded-full shadow-lg shadow-blue-500/50 z-20",animate:{left:`${n/(r.length-1)*100}%`,x:"-50%"},transition:{duration:.8,ease:"easeInOut"},children:s.jsx("div",{className:"absolute inset-0 rounded-full bg-blue-500 animate-ping opacity-75"})}),s.jsx("div",{className:"relative grid grid-cols-2 md:grid-cols-5 ga
3815p-4 pt-20",children:r.map((o,l)=>s.jsxs(_.div,{initial:{opacity:0,y:20},animate:e?{opacity:1,y:0}:{},transition:{duration:.5,delay:.5+l*.1},className:"flex flex-col items-center text-center",children:[s.jsx(_.div,{animate:{scale:n===l?1.2:n>=l?1.05:1,rotate:n>=l?360:0},transition:{duration:.6},className:"mb-4 relative",children:s.jsx("div",{className:`transition-all duration-500 relative z-10 ${n>=l?"text-blue-400":"text-gray-600"}`,style:{filter:n>=l?"drop-shadow(0 0 8px rgba(59, 130, 246, 0.8)) drop-shadow(0 0 16px rgba(59, 130, 246, 0.4))":"none"},children:o.icon})}),s.jsxs(_.div,{animate:{opacity:n>=l?1:.5,scale:n===l?1.05:1},transition:{duration:.3},className:`p-4 rounded-lg border transition-all ${n>=l?"border-blue-500/30 bg-blue-500/10":"border-gray-700 bg-gray-800/30"}`,children:[s.jsx("h3",{className:`font-bold mb-2 text-sm lg:text-base ${n>=l?"text-blue-400":"text-gray-500"}`,children:o.title}),s.jsx("p",{className:"text-xs lg:text-sm text-gray-300",children:o.description})]})]},l))})]})]})})}function Vte(){const t=k.useRef(null),e=we(t,{once:!0,margin:"-100px"}),{t:a}=$(),n=a("hakaistudio.queHace.beneficios",{returnObjects:!0});return s.jsx("section",{ref:t,className:"relative bg-slate-950 py-20 overflow-hidden",children:s.jsxs("div",{className:"max-w-7xl mx-auto px-4 sm:px-6 md:px-8",children:[s.jsxs(_.div,{initial:{opacity:0,y:20},animate:e?{opacity:1,y:0}:{},transition:{duration:.6},className:"text-center mb-16",children:[s.jsx("h2",{className:"text-4xl font-bold text-white mb-4",children:a("hakaistudio.queHace.titulo")}),s.jsx("p",{className:"text-xl text-gray-400",children:a("hakaistudio.queHace.subtitulo")})]}),s.jsxs("div",{className:"grid grid-cols-1 lg:grid-cols-2 gap-12 items-center",children:[s.jsxs(_.div,{initial:{opacity:0,x:-50},animate:e?{opacity:1,x:0}:{},transition:{duration:.8},className:"flex flex-col items-center lg:items-start text-center lg:text-left",children:[s.jsx(_.div,{initial:{scale:.5,opacity:0},animate:e?{scale:1,opacity:1}:{},transition:{duration:1,delay:.3},className:"relative",children:s.jsx(_.h3,{animate:{textShadow:["0 0 20px rgba(6, 182, 212, 0.5)","0 0 40px rgba(6, 182, 212, 0.8)","0 0 20px rgba(6, 182, 212, 0.5)"]},transition:{duration:2,repeat:1/0,ease:"easeInOut"},className:"text-8xl md:text-9xl font-black text-cyan-400 relative z-10",style:{textShadow:"0 0 30px rgba(6, 182, 212, 0.6)"},children:"70~80%"})}),s.jsx(_.p,{initial:{opacity:0,y:20},animate:e?{opacity:1,y:0}:{},transition:{duration:.6,delay:.5},className:"text-xl md:text-2xl text-gray-300 mt-6 max-w-md",children:a("hakaistudio.queHace.reduccion")})]}),s.jsx(_.div,{initial:{opacity:0,x:50},animate:e?{opacity:1,x:0}:{},transition:{duration:.8,delay:.2},className:"space-y-6",children:n.map((i,r)=>s.jsxs(_.div,{initial:{opacity:0,x:20},animate:e?{opacity:1,x:0}:{},transition:{duration:.5,delay:.4+r*.1},className:"flex items-start gap-4 group",children:[s.jsx(_.div,{whileHover:{scale:1.2,rotate:360},transition:{duration:.5},className:"flex-shrink-0 mt-1",children:s.jsx("svg",{className:"w-7 h-7 text-cyan-400",fill:"none",viewBox:"0 0 24 24",stroke:"currentColor",style:{filter:"drop-shadow(0 0 6px rgba(6, 182, 212, 0.6))"},children:s.jsx("path",{strokeLinecap:"round",strokeLinejoin:"round",strokeWidth:2.5,d:"M5 13l4 4L19 7"})})}),s.jsx("p",{className:"text-lg text-gray-300 group-hover:text-white transition-colors duration-300",children:i})]},r))})]})]})})}function Hte({variant:t=1}){const e="#1e3a8a",a="#0a0e27",n={1:"M0,0L0,40L48,45.3C96,51,192,61,288,66.7C384,72,480,72,576,66.7C672,61,768,51,864,56C960,61,1056,83,1152,88C1248,93,1344,83,1392,77.3L1440,72L1440,0L1392,0C1344,0,1248,0,1152,0C1056,0,960,0,864,0C768,0,672,0,576,0C480,0,384,0,288,0C192,0,96,0,48,0L0,0Z",2:"M0,0L0,40L48,34.7C96,29,192,19,288,24C384,29,480,51,576,56C672,61,768,51,864,45.3C960,40,1056,40,1152,34.7C1248,29,1344,19,1392,13.3L1440,8L1440,0L1392,0C1344,0,1248,0,1152,0C1056,0,960,0,864,0C768,0,672,0,576,0C480,0,384,0,288,0C192,0,96,0,48,0L0,0Z",3:"M0,0L0,40L48,45.3C96,51,192,61,288,56C384,51,480,29,576,24C672,19,768,29,864,40C960,51,1056,61,1152,61.3C1248,61,1344,51,1392,45.3L1440,40L1440,0L1392,0C1344,0,1248,0,1152,0C1056,0,960,0,864,0C768,0,672,0,576,0C480,0,384,0,288,0C192,0,96,0,48,0L0,0Z"},i=`waveGradBlue-${t}`;return s.jsx("div",{className:"absolute bottom-0 left-0 w-full overflow-visible pointer-events-none",style:{height:"clamp(60px, 15vw, 120px)",transform:"translateY(100%)",zIndex:10},children:s.jsxs("svg",{className:"w-full h-full overflow-visible",viewBox:"0 0 1440 100",preserveAspectRatio:"xMidYMid slice",xmlns:"http://www.w3.org/2000/svg",style:{filter:"drop-shadow(0px 18px 10px rgba(0, 0, 0, 0.8))"},children:[s.jsx("defs",{children:s.jsxs("linearGradient",{id:i,x1:"0%",y1:"0%",x2:"0%",y2:"100%",children:[s.jsx("stop",{offset:"0%",stopColor:e,stopOpacity:"1"}),s.jsx("stop",{offset:"50%",stopColor:e,stopOpacity:"1"}),s.jsx("stop",{offset:"100%",stopColor:a,stopOpacity:"1"})]})}),s.jsx("path",{fill:`url(#${i})`,d:n[t]})]})})}function Fte(){const t=k.useRef(null),e=we(t,{once:!0,margin:"-100px"}),{t:a}=$(),n=[{aspecto:a("hakaistudio.comparativa.tabla.tiempo.aspecto"),sinHaka:a("hakaistudio.comparativa.tabla.tiempo.sin"),conHaka:a("hakaistudio.comparativa.tabla.tiempo.con")},{aspecto:a("hakaistudio.comparativa.tabla.seguridad.aspecto"),sinHaka:a("hakaistudio.comparativa.tabla.seguridad.sin"),conHaka:a("hakaistudio.comparativa.tabla.seguridad.con")},{aspecto:a("hakaistudio.comparativa.tabla.selectores.aspecto"),sinHaka:a("hakaistudio.comparativa.tabla.selectores.sin"),conHaka:a("hakaistudio.comparativa.tabla.selectores.con")},{aspecto:a("hakaistudio.comparativa.tabla.reutilizacion.aspecto"),sinHaka:a("hakaistudio.comparativa.tabla.reutilizacion.sin"),conHaka:a("hakaistudio.comparativa.tabla.reutilizacion.con")},{aspecto:a("hakaistudio.comparativa.tabla.formato.aspecto"),sinHaka:a("hakaistudio.comparativa.tabla.formato.sin"),conHaka:a("hakaistudio.comparativa.tabla.formato.con")},{aspecto:a("hakaistudio.comparativa.tabla.mantenimiento.aspecto"),sinHaka:a("hakaistudio.comparativa.tabla.mantenimiento.sin"),conHaka:a("hakaistudio.comparativa.tabla.mantenimiento.con")}];return s.jsxs("section",{ref:t,className:"relative bg-gradient-to-b from-slate-950 to-blue-900 py-20",children:[s.jsxs("div",{className:"max-w-7xl mx-auto px-4 sm:px-6 md:px-8",children:[s.jsxs(_.div,{initial:{opacity:0,y:20},animate:e?{opacity:1,y:0}:{},transition:{duration:.6},className:"text-center mb-12",children:[s.jsx("h2",{className:"text-4xl font-bold text-white mb-4",children:a("hakaistudio.comparativa.titulo")}),s.jsx("p",{className:"text-xl text-gray-400",children:a("hakaistudio.comparativa.subtitulo")})]}),s.jsx(_.div,{initial:{opacity:0,y:30},animate:e?{opacity:1,y:0}:{},transition:{duration:.6,delay:.2},className:"overflow-hidden rounded-2xl border border-slate-700/50 bg-slate-900/50 backdrop-blur-sm",children:s.jsx("div",{className:"overflow-x-auto",children:s.jsxs("table",{className:"w-full",children:[s.jsx("thead",{children:s.jsxs("tr",{className:"bg-gradient-to-r from-slate-800 to-slate-900",children:[s.jsx("th",{className:"px-6 py-4 text-left text-sm font-bold text-white uppercase tracking-wider border-b border-slate-700/50",children:a("hakaistudio.comparativa.aspecto")}),s.jsx("th",{className:"px-6 py-4 text-left text-sm font-bold text-red-400 uppercase tracking-wider border-b border-slate-700/50",children:s.jsxs("div",{className:"flex items-center gap-2",children:[s.jsx("svg",{className:"w-5 h-5",fill:"none",viewBox:"0 0 24 24",stroke:"currentColor",children:s.jsx("path",{strokeLinecap:"round",strokeLinejoin:"round",strokeWidth:2,d:"M6 18L18 6M6 6l12 12"})}),a("hakaistudio.comparativa.sinHaka")]})}),s.jsx("th",{className:"px-6 py-4 text-left text-sm font-bold text-green-400 uppercase tracking-wider border-b border-slate-700/50",children:s.jsxs("div",{className:"flex items-center gap-2",children:[s.jsx("svg",{className:"w-5 h-5",fill:"none",viewBox:"0 0 24 24",stroke:"currentColor",children:s.jsx("path",{strokeLinecap:"round",strokeLinejoin:"round",strokeWidth:2,d:"M5 13l4 4L19 7"})}),a("hakaistudio.comparativa.conHaka")]})})]})}),s.jsx("tbody",{children:n.map((i,r)=>s.jsxs(_.tr,{initial:{opacity:0,x:-20},animate:e?{opacity:1,x:0}:{},transition:{duration:.4,delay:.3+r*.05},className:"border-b border-slate-700/30 hover:bg-slate-800/30 transition-colors duration-200",children:[s.jsx("td",{className:"px-6 py-4 text-white font-semibold",children:i.aspecto}),s.jsx("td",{className:"px-6 py-4 text-gray-300",children:i.sinHaka}),s.jsx("td",{className:"px-6 py-4 text-gray-300 bg-green-900/5",children:i.conHaka})]},r))})]})})}),s.jsxs(_.div,{initial:{opacity:0,y:20},animate:e?{opacity:1,y:0}:{},transition:{duration:.6,delay:.8},className:"mt-12 relative overflow-hidden rounded-xl",children:[s.jsx("div",{className:"absolute inset-0 opacity-20",style:{background:"radial-gradient(circle at center, #06b6d4 0%, transparent 70%)"}}),s.jsx("div",{className:"relative bg-gradient-to-r from-cyan-500/20 via-blue-500/20 to-purple-500/20 border border-cyan-500/50 rounded-xl p-6 text-center backdrop-blur-sm",children:s.jsxs(_.div,{animate:{scale:[1,1.02,1]},transition:{duration:2,repeat:1/0,ease:"easeInOut"},children:[s.jsx("p",{className:"text-2xl font-bold text-white mb-2",children:a("hakaistudio.comparativa.destacado.titulo")}),s.jsx("p",{className:"text-lg text-cyan-400 font-semibold",children:a("hakaistudio.comparativa.destacado.descripcion")})]})})]})]}),s.jsx(Hte,{variant:1})]})}function Bte(){const t=k.useRef(null),e=we(t,{once:!0,margin:"-100px"}),{t:a}=$(),[n,i]=k.useState(0);k.useEffect(()=>{if(!e)return;const o=setInterval(()=>{i(l=>(l+1)%5)},2e3);return()=>clearInterval(o)},[e]);const r=[{titulo:a("hakaistudio.casosUso.frontEnd.titulo"),descripcion:a("hakaistudio.casosUso.frontEnd.descripcion"),icon:s.jsx("svg",{className:"w-16 h-16",fill:"none",viewBox:"0 0 24 24",stroke:"currentColor",children:s.jsx("path",{strokeLinecap:"round",strokeLinejoin:"round",strokeWidth:1.5,d:"M9.75 17L9 20l-1 1h8l-1-1-.75-3M3 13h18M5 17h14a2 2 0 002-2V5a2 2 0 00-2-2H5a2 2 0 00-2 2v10a2 2 0 002 2z"})})},{titulo:a("hakaistudio.casosUso.backend.titulo"),descripcion:a("hakaistudio.casosUso.backend.descripcion"),icon:s.jsx("svg",{className:"w-16 h-16",fill:"none",viewBox:"0 0 24 24",stroke:"currentColor",children:s.jsx("path",{strokeLinecap:"round",strokeLinejoin:"round",strokeWidth:1.5,d:"M5 12h14M5 12a2 2 0 01-2-2V6a2 2 0 012-2h14a2 2 0 012 2v4a2 2 0 01-2 2M5 12a2 2 0 00-2 2v4a2 2 0 002 2h14a2 2 0 002-2v-4a2 2 0 00-2-2m-2-4h.01M17 16h.01"})})},{titulo:a("hakaistudio.casosUso.regresion.titulo"),descripcion:a("hakaistudio.casosUso.regresion.descripcion"),icon:s.jsx("svg",{className:"w-16 h-16",fill:"none",viewBox:"0 0 24 24",stroke:"currentColor",children:s.jsx("path",{strokeLinecap:"round",strokeLinejoin:"round",strokeWidth:1.5,d:"M4 4v5h.582m15.356 2A8.001 8.001 0 004.582 9m0 0H9m11 11v-5h-.581m0 0a8.003 8.003 0 01-15.357-2m15.357 2H15"})})},{titulo:a("hakaistudio.casosUso.ayudante.titulo"),descripcion:a("hakaistudio.casosUso.ayudante.descripcion"),icon:s.jsx("svg",{className:"w-16 h-16",fill:"none",viewBox:"0 0 24 24",stroke:"currentColor",children:s.jsx("path",{strokeLinecap:"round",strokeLinejoin:"round",strokeWidth:1.5,d:"M8 12h.01M12 12h.01M16 12h.01M21 12c0 4.418-4.03 8-9 8a9.863 9.863 0 01-4.25
38155-.949L3 20l1.395-3.72C3.512 15.042 3 13.574 3 12c0-4.418 4.03-8 9-8s9 3.582 9 8z"})})}];return s.jsx("section",{ref:t,className:"relative bg-[#0a0e27] pt-20 pb-20 overflow-hidden",children:s.jsxs("div",{className:"max-w-7xl mx-auto px-4 sm:px-6 md:px-8",children:[s.jsxs(_.div,{initial:{opacity:0,y:20},animate:e?{opacity:1,y:0}:{},transition:{duration:.6},className:"text-center mb-16 mt-16",children:[s.jsx("h2",{className:"text-4xl font-bold text-white mb-4",children:a("hakaistudio.casosUso.titulo").toUpperCase()}),s.jsx("div",{className:"w-24 h-1 bg-cyan-400 mx-auto mb-6"}),s.jsx("p",{className:"text-lg text-gray-300 max-w-3xl mx-auto",children:a("hakaistudio.casosUso.subtitulo")})]}),s.jsx("div",{className:"grid grid-cols-1 sm:grid-cols-2 lg:grid-cols-4 gap-6 max-w-5xl mx-auto",children:r.map((o,l)=>s.jsx(_.div,{initial:{opacity:0,y:30},animate:e?{opacity:1,y:0}:{},transition:{duration:.5,delay:l*.1},className:"group relative",children:s.jsxs("div",{className:`relative h-full bg-[#0f1629] border-2 rounded-lg p-6 transition-all duration-500 ${n===l?"border-cyan-400 shadow-lg shadow-cyan-500/50 scale-105":"border-cyan-500/30 hover:border-cyan-400 hover:shadow-lg hover:shadow-cyan-500/20"}`,children:[n===l&&s.jsx(_.div,{initial:{opacity:0}
3815,animate:{opacity:[0,.3,0]},transition:{duration:1.5,repeat:1/0},className:"absolute inset-0 bg-gradient-to-br from-cyan-400/20 via-transparent to-transparent rounded-lg"}),s.jsx("div",{className:`mb-6 transition-all duration-500 ${n===l?"text-cyan-300 scale-110":"text-cyan-400"}`,children:o.icon}),s.jsx("h3",{className:"text-xl font-bold text-white mb-4 relative z-10",children:o.titulo}),s.jsx("p",{className:"text-gray-300 leading-relaxed text-sm relative z-10",children:o.descripcion})]})},l))}),s.jsx(_.div,{initial:{opacity:0,y:30},animate:e?{opacity:1,y:0}:{},transition:{duration:.5,delay:.4},className:"mt-6 group relative",children:s.jsxs("div",{className:`relative bg-[#0f1629] border-2 rounded-lg p-6 transition-all duration-500 ${n===4?"border-cyan-400 shadow-lg shadow-cyan-500/50 scale-[1.02]":"border-cyan-500/30 hover:border-cyan-400 hover:shadow-lg hover:shadow-cyan-500/20"}`,children:[n===4&&s.jsx(_.div,{initial:{opacity:0},animate:{opacity:[0,.3,0]},transition:{duration:1.5,repeat:1/0},className:"absolute inset-0 bg-gradient-to-br from-cyan-400/20 via-transparent to-transparent rounded-lg"}),s.jsxs("div",{className:"flex items-start gap-6",children:[s.jsx("div",{className:`flex-shrink-0 transition-all duration-500 ${n===4?"text-cyan-300 scale-110":"text-cyan-400"}`,children:s.jsx("svg",{className:"w-16 h-16",fill:"none",viewBox:"0 0 24 24",stroke:"currentColor",children:s.jsx("path",{strokeLinecap:"round",strokeLinejoin:"round",strokeWidth:1.5,d:"M9 12l2 2 4-4m5.618-4.016A11.955 11.955 0 0112 2.944a11.955 11.955 0 01-8.618 3.04A12.02 12.02 0 003 9c0 5.591 3.824 10.29 9 11.622 5.176-1.332 9-6.03 9-11.622 0-1.042-.133-2.052-.382-3.016z"})})}),s.jsxs("div",{className:"flex-1 relative z-10",children:[s.jsx("h3",{className:"text-xl font-bold text-white mb-4",children:a("hakaistudio.casosUso.talento.titulo")}),s.jsx("p",{className:"text-gray-300 leading-relaxed",children:a("hakaistudio.casosUso.talento.descripcion")})]})]})]})})]})})}function Ute(){const t=k.useRef(null),e=we(t,{once:!0,margin:"-100px"}),{t:a}=$(),[n,i]=k.useState(null),r=a("hakaistudio.faq.items",{returnObjects:!0}),o=l=>{i(n===l?null:l)};return s.jsx("section",{ref:t,className:"relative bg-slate-950 py-20",children:s.jsxs("div",{className:"max-w-4xl mx-auto px-4 sm:px-6 md:px-8",children:[s.jsxs(_.div,{initial:{opacity:0,y:20},animate:e?{opacity:1,y:0}:{},transition:{duration:.6},className:"text-center mb-12",children:[s.jsx("h2",{className:"text-4xl font-bold text-white mb-4",children:a("hakaistudio.faq.titulo")}),s.jsx("p",{className:"text-xl text-gray-400",children:a("hakaistudio.faq.subtitulo")})]}),s.jsx("div",{className:"space-y-4",children:r.map((l,c)=>s.jsxs(_.div,{initial:{opacity:0,y:20},animate:e?{opacity:1,y:0}:{},transition:{duration:.4,delay:c*.1},className:"bg-slate-800/50 backdrop-blur-sm rounded-xl border border-slate-700 overflow-hidden",children:[s.jsxs("button",{onClick:()=>o(c),className:"w-full p-6 text-left flex justify-between items-center hover:bg-slate-800/70 transition-colors",children:[s.jsx("span",{className:"text-lg font-semibold text-white pr-8",children:l.question}),s.jsx("span",{className:"text-2xl text-blue-400 flex-shrink-0",children:n===c?"−":"+"})]}),s.jsx(_.div,{initial:!1,animate:{height:n===c?"auto":0,opacity:n===c?1:0},transition:{duration:.3},className:"overflow-hidden",children:s.jsx("div",{className:"p-6 pt-0 text-gray-300 leading-relaxed",children:l.answer})})]},c))})]})})}function $te(){return s.jsxs("div",{className:"bg-dark",children:[s.jsx(Xa,{title:"Haka AI Studio - Automatizacion de Testing con IA en VS Code",description:"Extension de VS Code para automatizacion de pruebas end-to-end con inteligencia artificial y soporte BDD completo.",path:"/haka-ai-studio"}),s.jsx(qte,{}),s.jsx(zte,{}),s.jsx(Vte,{}),s.jsx(Fte,{}),s.jsx(Bte,{}),s.jsx(Ute,{}),s.jsx(Zr,{title:"También te podría interesar",productIds:[1,2,3,4,5]})]})}function Wte(){const t=k.useRef(null),e=we(t,{once:!0,margin:"-100px"});return s.jsxs("section",{ref:t,className:"relative bg-dark pt-20 pb-16 text-center",children:[s.jsx("div",{className:"hero-glow"}),s.jsxs("div",{className:"max-w-5xl mx-auto px-4 sm:px-6 md:px-8",children:[s.jsxs(_.div,{initial:{opacity:0,y:-30},animate:e?{opacity:1,y:0}:{},transition:{duration:.6},className:"flex flex-col items-center mb-8",children:[s.jsxs("h1",{className:"text-5xl md:text-6xl font-black text-white mb-2",children:["Haka ",s.jsx("span",{className:"text-cyan-400",children:"Lens"})]}),s.jsx("span",{className:"text-sm text-gray-500 font-mono",children:"v9.0"})]}),s.jsx(_.p,{initial:{opacity:0,y:20},animate:e?{opacity:1,y:0}:{},transition:{duration:.6,delay:.2},className:"text-xl md:text-2xl text-gray-300 mb-6 max-w-3xl mx-auto",children:"Plataforma de gestión de QA nativa para Jira Cloud. Centraliza pruebas, planes, ejecuciones y cobertura sin salir de tu flujo de trabajo."}),s.jsx(_.h2,{initial:{opacity:0,y:20},animate:e?{opacity:1,y:0}:{},transition:{duration:.6,delay:.3},className:"text-3xl font-bold text-white mb-8",children:"QA integrado donde tus equipos ya trabajan"}),s.jsx(_.div,{initial:{opacity:0,y:20},animate:e?{opacity:1,y:0}:{},transition:{duration:.6,delay:.4},className:"flex flex-wrap justify-center gap-2 mb-8",children:["Jira Cloud","Atlassian Forge","Bilingue (EN/ES)","CI/CD API"].map(a=>s.jsx("span",{className:"px-3 py-1 bg-cyan-400/10 border border-cyan-400/40 text-cyan-300 text-sm font-medium rounded-full",children:a},a))}),s.jsxs(_.div,{initial:{opacity:0,y:20},animate:e?{opacity:1,y:0}:{},transition:{duration:.6,delay:.5},className:"flex flex-wrap justify-center gap-4 mb-6",children:[s.jsxs("a",{href:"https://marketplace.atlassian.com",target:"_blank",rel:"noopener noreferrer",className:"inline-flex items-center gap-3 bg-cyan-400 hover:bg-cyan-300 text-[#0a0e27] font-bold px-8 py-3 rounded-full transition-all duration-300 hover:shadow-lg hover:shadow-cyan-400/50 transform hover:-translate-y-1",children:[s.jsx("svg",{className:"w-5 h-5",fill:"none",viewBox:"0 0 24 24",stroke:"currentColor",children:s.jsx("path",{strokeLinecap:"round",strokeLinejoin:"round",strokeWidth:2,d:"M4 16v1a3 3 0 003 3h10a3 3 0 003-3v-1m-4-4l-4 4m0 0l-4-4m4 4V4"})}),"Instalar desde Atlassian Marketplace"]}),s.jsxs("a",{href:"/hakalens/docs",className:"inline-flex items-center gap-3 bg-transparent border-2 border-cyan-400/60 text-cyan-300 hover:bg-cyan-400/10 font-bold px-8 py-3 rounded-full transition-all duration-300 hover:shadow-lg hover:shadow-cyan-400/20 transform hover:-translate-y-1",children:[s.jsx("svg",{className:"w-5 h-5",fill:"none",viewBox:"0 0 24 24",stroke:"currentColor",children:s.jsx("path",{strokeLinecap:"round",strokeLinejoin:"round",strokeWidth:2,d:"M12 6.253v13m0-13C10.832 5.477 9.246 5 7.5 5S4.168 5.477 3 6.253v13C4.168 18.477 5.754 18 7.5 18s3.332.477 4.5 1.253m0-13C13.168 5.477 14.754 5 16.5 5c1.747 0 3.332.477 4.5 1.253v13C19.832 18.477 18.247 18 16.5 18c-1.746 0-3.332.477-4.5 1.253"})}),"Documentacion"]})]}),s.jsxs(_.div,{initial:{opacity:0}
3815,animate:e?{opacity:1}:{},transition:{duration:.6,delay:.6},className:"flex flex-wrap justify-center gap-6 text-sm text-gray-500",children:[s.jsx("a",{href:"/hakalens/docs",className:"hover:text-cyan-400 transition-colors",children:"API de Automatizacion"}),s.jsx("a",{href:"/hakalens/docs",className:"hover:text-cyan-400 transition-colors",children:"Plugins CI/CD"}),s.jsx("a",{href:"/hakalens/docs",className:"hover:text-cyan-400 transition-colors",children:"Soporte"})]})]}),s.jsx(ie,{color:"#0a0e27",variant:1})]})}function Gte(){const t=k.useRef(null),e=we(t,{once:!0,margin:"-100px"});return s.jsx("section",{ref:t,className:"relative bg-gradient-to-b from-slate-950 to-blue-900 pt-16 sm:pt-24 pb-20 overflow-hidden",children:s.jsxs("div",{className:"max-w-6xl mx-auto px-4 sm:px-6 md:px-8",children:[s.jsx(_.h2,{initial:{opacity:0,y:20},animate:e?{opacity:1,y:0}:{},transition:{duration:.6},className:"text-4xl md:text-5xl font-bold text-white mb-6 text-center",children:"Que es Haka Lens?"}),s.jsx(_.p,{initial:{opacity:0,y:20},animate:e?{opacity:1,y:0}:{},transition:{duration:.6,delay:.2},className:"text-xl text-gray-300 mb-12 max-w-4xl mx-auto text-center",children:"Haka Lens es una aplicacion de QA creada por Haka Lab que vive dentro de Jira (Atlassian Forge), disenada para centralizar la gestion, ejecucion y documentacion de pruebas de softw
3815are sin salir de tus proyectos. Convierte historias y tareas en casos de prueba, planes y ejecuciones nativos de Jira, con trazabilidad de cobertura de extremo a extremo."}),s.jsx(_.div,{initial:{opacity:0,y:30},animate:e?{opacity:1,y:0}:{},transition:{duration:.6,delay:.3},className:"grid grid-cols-2 md:grid-cols-3 lg:grid-cols-5 gap-4 mb-12",children:[{name:"Pruebas",icon:"🧪",desc:"Casos de prueba manuales y automatizados"},{name:"Planes",icon:"📋",desc:"Agrupa pruebas en planes ejecutables"},{name:"Ejecuciones",icon:"▶️",desc:"Registra resultados por caso"},{name:"Cobertura",icon:"📊",desc:"Trazabilidad sobre historias"},{name:"Bugs QA",icon:"🐛",desc:"Bugs con metadatos enriquecidos"}].map((a,n)=>s.jsxs(_.div,{initial:{opacity:0,y:20},animate:e?{opacity:1,y:0}:{},transition:{duration:.5,delay:.4+n*.1},className:"p-4 rounded-lg border border-cyan-500/30 bg-cyan-500/5 text-center hover:bg-cyan-500/10 transition-all",children:[s.jsx("div",{className:"text-3xl mb-2",children:a.icon}),s.jsx("h3",{className:"text-cyan-400 font-bold text-sm mb-1",children:a.name}),s.jsx("p",{className:"text-xs text-gray-400",children:a.desc})]},a.name))}),s.jsxs(_.p,{initial:{opacity:0,y:20},animate:e?{opacity:1,y:0}:{},transition:{duration:.6,delay:.6},className:"text-lg text-gray-300 max-w-4xl mx-auto text-center",children:["Ofrece gestion de Casos de Prueba, Planes y Ejecuciones, cobertura sobre historias, sugerencia y analisis de pruebas con ",s.jsx("span",{className:"text-cyan-400 font-semibold",children:"IA"})," (proveedores externos o Rovo de Atlassian), reportes automaticos en ",s.jsx("span",{className:"text-cyan-400 font-semibold",children:"DOCX y HTML"}
3815),", dashboards con metricas de calidad e integracion con ",s.jsx("span",{className:"text-cyan-400 font-semibold",children:"CI/CD"})," (GitHub, GitLab, Bitbucket, Jenkins, Azure) via API de automatizacion."]}),s.jsxs(_.div,{initial:{opacity:0,y:20},animate:e?{opacity:1,y:0}:{},transition:{duration:.6,delay:.7},className:"mt-10 text-center",children:[s.jsx("h3",{className:"text-lg font-bold text-white mb-4",children:"Apoya en"}),s.jsx("div",{className:"flex flex-wrap justify-center gap-2",children:["Gestion de Pruebas","Ejecucion","Cobertura","Reportes","IA","CI/CD","Dashboards","Jira"].map(a=>s.jsx("span",{className:"px-4 py-2 bg-slate-800 border border-cyan-400/30 text-cyan-300 text-sm font-medium rounded-full",children:a},a))})]})]})})}const Kte=[{categoria:"Gestion",titulo:"Casos de Prueba en Jira",descripcion:"Crea y documenta casos de prueba nativos con pasos manuales o escenarios Gherkin, precondiciones, ambiente, categoria, enfoque y tiempo estimado."},{categoria:"Gestion",titulo:"Planes y Ejecuciones",descripcion:"Agrupa pruebas en Planes, lanza Ejecuciones y registra resultados por caso (exitoso, fallido, por ejecutar), con soporte de iteraciones parametrizadas."},{categoria:"Cobertura",titulo:"Trazabilidad sobre Historias",descripcion:"Vincula pruebas, planes y ejecuciones a historias para ver la cobertura y resultados directamente en el issue."},{categoria:"Inteligencia Artificial",titulo:"Sugerencia y Analisis con IA",descripcion:"Genera casos de prueba y analiza issues (riesgos, ambiguedades, mejoras) con Gemini, OpenAI, Anthropic o Rovo de Atlassian."},{categoria:"Observabilidad",titulo:"Reportes Automaticos",descripcion:"Genera reportes profesionales en DOCX y HTML con plantillas personalizables, evidencias y datos de ejecucion."},{categoria:"Observabilidad",titulo:"Dashboards de QA",descripcion:"12 gadgets con metricas de calida
3815d: cobertura, resultados, distribucion por tipo, factibilidad, tiempos y documentacion."},{categoria:"Integracion",titulo:"CI/CD y API de Automatizacion",descripcion:"Actualiza resultados desde tus pipelines (GitHub, GitLab, Bitbucket, Jenkins, Azure) via API REST con emparejamiento por tag."},{categoria:"Gestion",titulo:"Importacion desde CSV",descripcion:"Importa pruebas masivamente a un plan desde CSV con mapeo de columnas, deteccion de duplicados y creacion por lotes."}],Jte={Gestion:"border-blue-500/30 bg-blue-500/5",Cobertura:"border-green-500/30 bg-green-500/5","Inteligencia Artificial":"border-purple-500/30 bg-purple-500/5",Observabilidad:"border-amber-500/30 bg-amber-500/5",Integracion:"border-cyan-500/30 bg-cyan-500/5"},Qte={Gestion:"text-blue-400",Cobertura:"text-green-400","Inteligencia Artificial":"text-purple-400",Observabilidad:"text-amber-400",Integracion:"text-cyan-400"};function Xte(){const t=k.useRef(null),e=we(t,{once:!0,margin:"-100px"});return s.jsx("section",{ref:t,className:"relative bg-slate-950 py-20 overflow-hidden",children:s.jsxs("div",{className:"max-w-7xl mx-auto px-4 sm:px-6 md:px-8",children:[s.jsxs(_.div,{initial:{opacity:0,y:20},animate:e?{opacity:1,y:0}:{},transition:{duration:.6},className:"text-center mb-16",children:[s.jsx("h2",{className:"text-4xl font-bold text-white mb-4",children:"Funcionalidades"}),s.jsx("p",{className:"text-xl text-gray-400",children:"Todo lo que necesitas para gestionar QA dentro de Jira"})]}),s.jsx("div",{className:"grid grid-cols-1 md:grid-cols-2 lg:grid-cols-4 gap-6",children:Kte.map((a,n)=>s.jsxs(_.div,{initial:{opacity:0,y:20},animate:e?{opacity:1,y:0}:{},transition:{duration:.5,delay:.2+n*.08},className:`p-6 rounded-xl border ${Jte[a.categoria]} hover:scale-105 transition-transform duration-300`,children:[s.jsx("span",{className:`text-xs font-semibold uppercase tracking-wider ${Qte[a.categoria]}`,children:a.categoria}),s.jsx("h3",{className:"text-lg font-bold text-white mt-2 mb-3",children:a.titulo}),s.jsx("p",{className:"text-sm text-gray-400 leading-relaxed",children:a.descripcion})]},n))})]})})}const Yte=[{pregunta:"Haka Lens reemplaza a Xray o Zephyr?",respuesta:"Si. Haka Lens cubre la gestion completa de pruebas (casos, planes, ejecuciones, cobertura, bugs QA) directamente en Jira Cloud, sin necesidad de herramientas externas. Ademas incluye IA, reportes automaticos y API de CI/CD."},{pregunta:"Necesito instalar algo en mi computador?",respuesta:"No. Haka Lens es una app Atlassian Forge que corre 100% en la nube de Jira. Se instala desde el Marketplace y se usa directamente en Jira. Solo necesitas un sitio Jira Cloud."},{pregunta:"Como funciona la integracion con CI/CD?",respuesta:"Haka Lens expone una API REST (Web Trigger) que tus pipelines pueden llamar para actualizar resultados de tests. Soporta GitHub Actions, GitLab CI, Bitbucket Pipelines, Jenkins y Azure DevOps. Tambien incluye plugins descargables para Playwright y Selenium."},{pregunta:"Que proveedores de IA soporta?",respuesta:"Soporta Google Gemini, OpenAI (GPT-4), Anthropic (Claude) como proveedores externos, y Rovo (modelo de Atlassian) como fallback integrado sin configuracion adicional."},{pregunta:"Puedo importar mis pruebas desde un archivo?",respuesta:"Si. Desde cualquier Plan de Pruebas puedes importar hasta 50 tests desde un archivo CSV con mapeo de columnas automatico, deteccion de duplicados y creacion por lotes."},{pregunta:"En que idiomas esta disponible?",respuesta:"Haka Lens es bilingue: ingles (por defecto) y espanol. El idioma se configura por proyecto desde la seccion Diversos. Aplica a toda la interfaz, reportes DOCX y mensajes del backend."},{pregunta:"Cuantos gadgets de dashboard incluye?",respuesta:"12 gadgets de metricas de QA: tests creados, planes activos, distribucion por tipo, resultados de ejecucion, cobertura, tests por ambiente/categoria/enfoque, factibilidad de automatizacion, tiempos y documentacion."},{pregunta:"Como se cobra?",respuesta:"Haka Lens se cobra por usuario con acceso (user-based billing). Solo pagan los usuarios que operan la herramienta (equipo QA). Los demas pueden ver dashboards y reportes sin licencia."}];function Zte(){const t=k.useRef(null),e=we(t,{once:!0,margin:"-100px"}),[a,n]=k.useState(null),i=r=>{n(a===r?null:r)};return s.jsx("section",{ref:t,className:"relative bg-slate-950 py-20 overflow-hidden",children:s.jsxs("div",{className:"max-w-4xl mx-auto px-4 sm:px-6 md:px-8",children:[s.jsxs(_.div,{initial:{opacity:0,y:20},animate:e?{opacity:1,y:0}:{},transition:{duration:.6},className:"text-center mb-12",children:[s.jsx("h2",{className:"text-4xl font-bold text-white mb-4",children:"Preguntas Frecuentes"}),s.jsx("p",{className:"text-lg text-gray-400",children:"Todo lo que necesitas saber sobre Haka Lens"})]}),s.jsx("div",{className:"space-y-3",children:Yte.map((r,o)=>s.jsxs(_.div,{initial:{opacity:0,y:10},animate:e?{opacity:1,y:0}:{},transition:{duration:.4,delay:.1+o*.05},className:"border border-gray-700 rounded-lg overflow-hidden",children:[s.jsxs("button",{onClick:()=>i(o),className:"w-full flex items-center justify-between p-5 text-left bg-slate-900 hover:bg-slate-800 transition-colors",children:[s.jsx("span",{className:"font-semibold text-white pr-4",children:r.pregunta}),s.jsx("svg",{className:`w-5 h-5 text-cyan-400 flex-shrink-0 transition-transform duration-300 ${a===o?"rotate-180":""}`,fill:"none",viewBox:"0 0 24 24",stroke:"currentColor",children:s.jsx("path",{strokeLinecap:"round",strokeLinejoin:"round",strokeWidth:2,d:"M19 9l-7 7-7-7"})})]}),a===o&&s.jsx("div",{className:"p-5 bg-slate-900/50 border-t border-gray-700",children:s.jsx("p",{className:"text-gray-300 leading-relaxed",children:r.respuesta})})]},o))})]})})}function eae(){return s.jsxs("div",{className:"bg-dark",children:[s.jsx(Xa,{title:"HakaLens - Gestion de Testing en Jira",description:"Aplicacion Jira para gestion de repositorios de pruebas, planes de ejecucion, cobertura y analitica de testing integrada.",path:"/hakalens"}),s.jsx(Wte,{}),s.jsx(Gte,{}),s.jsx(Xte,{}),s.jsx(Zte,{}),s.jsx(Zr,{title:"Tambien te podria interesar",productIds:[1,2,3,5,7]})]})}const Mg=t=>{k.useEffect(()=>{if(t.title&&(document.title=t.title),t.description){const e=document.querySelector('meta[name="description"]');e&&e.setAttribute("content",t.description)}if(t.keywords){const e=document.querySelector('meta[name="keywords"]');
3815e&&e.setAttribute("content",t.keywords)}if(t.canonical){let e=document.querySelector('link[rel="canonical"]');e||(e=document.createElement("link"),e.rel="canonical",document.head.appendChild(e)),e.href=t.canonical}if(t.ogTitle){const e=document.querySelector('meta[property="og:title"]');e&&e.setAttribute("content",t.ogTitle)}if(t.ogDescription){const e=document.querySelector('meta[property="og:description"]');e&&e.setAttribute("content",t.ogDescription)}if(t.ogImage){const e=document.querySelector('meta[property="og:image"]');e&&e.setAttribute("content",t.ogImage)}if(t.ogUrl){const e=document.querySelector('meta[property="og:url"]');e&&e.setAttribute("content",t.ogUrl)}if(t.twitterTitle){const e=document.querySelector('meta[name="twitter:title"]');e&&e.setAttribute("content",t.twitterTitle)}if(t.twitterDescription){const e=document.querySelector('meta[name="twitter:description"]');e&&e.setAttribute("content",t.twitterDescription)}if(t.twitterImage){const e=document.querySelector('meta[name="twitter:image"]');e&&e.setAttribute("content",t.twitterImage)}if(t.schema){let e=document.querySelector('script[type="application/ld+json"]');e||(e=document.createElement("script"),e.type="application/ld+json",document.head.appendChild(e)),e.textContent=JSON.stringify(t.schema)}},[t])}
3815,tae=[{id:"technology",name:{es:"Tecnología",en:"Technology"}},{id:"finance",name:{es:"Finanzas",en:"Finance"}},{id:"retail",name:{es:"Retail/E-commerce",en:"Retail/E-commerce"}},{id:"health",name:{es:"Salud",en:"Healthcare"}},{id:"education",name:{es:"Educación",en:"Education"}},{id:"manufacturing",name:{es:"Manufactura",en:"Manufacturing"}},{id:"telecommunications",name:{es:"Telecomunicaciones",en:"Telecommunications"}},{id:"government",name:{es:"Gobierno",en:"Government"}},{id:"energy",name:{es:"Energía",en:"Energy"}},{id:"logistics",name:{es:"Transporte/Logística",en:"Transport/Logistics"}},{id:"entertainment",name:{es:"Entretenimiento/Media",en:"Entertainment/Media"}},{id:"insurance",name:{es:"Seguros",en:"Insurance"}},{id:"real_estate",name:{es:"Inmobiliaria",en:"Real Estate"}},{id:"agriculture",name:{es:"Agricultura",en:"Agriculture"}},{id:"hospitality",name:{es:"Turismo/Hospitalidad",en:"Tourism/Hospitality"}},{id:"other",name:{es:"Otro",en:"Other"}}],aae=[{id:"web_app",name:{es:"Web y App",en:"Web and App"}},{id:"ecommerce",name:{es:"E-commerce",en:"E-commerce"}},{id:"salesforce",name:{es:"Salesforce",en:"Salesforce"}},{id:"sap",name:{es:"SAP",en:"SAP"}},{id:"erp",name:{es:"ERP Personalizado",en:"Custom ERP"}},{id:"crm",name:{es:"CRM",en:"CRM"}},{id:"mobile",name:{es:"Aplicaciones Móviles Nativas",en:"Native Mobile Applications"}},{id:"api",name:{es:"APIs/Microservicios",en:"APIs/Microservices"}},{id:"data_analytics",name:{es:"Data Analytics/BI",en:"Data Analytics/BI"}},{id:"iot",name:{es:"IoT",en:"IoT"}},{id:"blockchain",name:{es:"Blockchain",en:"Blockchain"}},{id:"other",name:{es:"Otro",en:"Other"}}],nae=t=>t?/^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(t):!1,Kp=t=>t!=null&&t.toString().trim()!=="",iae=t=>{const e={};return Kp(t.email)?nae(t.email)||(e.email={es:"El email no es válido",en:"Email is not valid"}):e.email={es:"El email es requerido",en:"Email is required"}
3815,Kp(t.company)||(e.company={es:"La empresa es requerida",en:"Company is required"}),Kp(t.industry)||(e.industry={es:"La industria es requerida",en:"Industry is required"}),Kp(t.developmentType)||(e.developmentType={es:"El tipo de desarrollo es requerido",en:"Development type is required"}),e},rae=(t,e)=>t.every(a=>{const n=e[a.id];return n!=null&&n>=1&&n<=5});function oae({onSubmit:t}){const{t:e,i18n:a}=$(),n=a.language,[i,r]=k.useState({email:"",company:"",industry:"",developmentType:""}),[o,l]=k.useState({}),[c,d]=k.useState({}),u=g=>{const{name:y,value:x}=g.target;r(v=>({...v,[y]:x})),o[y]&&l(v=>{const w={...v};return delete w[y],w})},p=g=>{d(y=>({...y,[g]:!0}))},m=g=>{g.preventDefault();const y=iae(i);if(Object.keys(y).length>0){l(y),d({email:!0,company:!0,industry:!0,developmentType:!0});return}t(i)},h=()=>i.email&&i.company&&i.industry&&i.developmentType&&Object.keys(o).length===0;return s.jsxs(_.div,{initial:{opacity:0,y:20},animate:{opacity:1,y:0},transition:{duration:.5},className:"max-w-2xl mx-auto",children:[s.jsx(_.div,{className:"absolute top-0 right-0 w-96 h-96 bg-cyan-500/20 rounded-full blur-3xl",animate:{scale:[1,1.2,1],opacity:[.2,.3,.2]},transition:{duration:4,repeat:1/0,ease:"easeInOut"}}),s.jsx(_.div,{className:"absolute bottom-0 left-0 w-96 h-96 bg-blue-500/20 rounded-full blur-3xl",animate:{scale:[1.2,1,1.2],opacity:[.3,.2,.3]},transition:{duration:4,repeat:1/0,ease:"easeInOut",delay:2}}),s.jsx(_.div,{className:"absolute top-1/2 left-1/2 w-64 h-64 bg-purple-500/10 rounded-full blur-3xl",animate:{x:[-100,100,-100],y:[-50,50,-50]},transition:{duration:8,repeat:1/0,ease:"easeInOut"}}),s.jsxs("div",{className:"relative bg-gradient-to-br from-[#1a1d3a]/90 via-[#1a1d3a]/95 to-[#0a0e27]/90 backdrop-blur-xl rounded-3xl p-8 sm:p-10 border-2 border-cyan-400/30 shadow-2xl shadow-cyan-500/20",children:[s.jsxs("div",{className:"text-center mb-8",children:[s.jsx(_.div,{initial:{scale:0,rotate:-180},animate:{scale:1,rotate:0},transition:{duration:.6,ease:"backOut"},className:"inline-block mb-6",children:s.jsxs("div",{className:"relative",children:[s.jsx("div",{className:"absolute inset-0 bg-gradient-to-r from-cyan-400 to-blue-500 rounded-2xl blur-xl opacity-50"}),s.jsx("div",{className:"relative bg-gradient-to-br from-cyan-400 to-blue-500 p-4 rounded-2xl",children:s.jsx("svg",{className:"w-12 h-12 text-white",fill:"none",viewBox:"0 0 24 24",stroke:"currentColor",children:s.jsx("path",{strokeLinecap:"round",strokeLinejoin:"round",strokeWidth:2,d:"M9 12l2 2 4-4m6 2a9 9 0 11-18 0 9 9 0 0118 0z"})})})]})}),s.jsx(_.h1,{initial:{opacity:0,y:20},animate:{opacity:1,y:0},transition:{delay:.2,duration:.5},className:"text-3xl sm:text-4xl font-bold mb-4",children:s.jsx("span",{className:"bg-gradient-to-r from-cyan-400 via-blue-400 to-purple-400 bg-clip-text text-transparent",children:e("quickAnalysis.welcome.title")})}),s.jsx(_.p,{initial:{opacity:0,y:20},animate:{opacity:1,y:0},transition:{delay:.3,duration:.5},className:"text-gray-300 text-lg max-w-xl mx-auto leading-relaxed",children:e("quickAnalysis.welcome.subtitle")}),s.jsx(_.div,{initial:{width:0},animate:{width:"100%"},transition:{delay:.5,duration:.8},className:"h-1 bg-gradient-to-r from-transparent via-cyan-400 to-transparent mx-auto mt-6 rounded-full",style:{maxWidth:"200px"}})]}),s.jsxs(_.form,{onSubmit:m,className:"space-y-6",initial:{opacity:0}
3815,animate:{opacity:1},transition:{delay:.6,duration:.5},children:[s.jsxs(_.div,{initial:{opacity:0,x:-20},animate:{opacity:1,x:0},transition:{delay:.7,duration:.5},children:[s.jsxs("label",{htmlFor:"email",className:"block text-gray-300 mb-2 font-medium flex items-center gap-2",children:[s.jsx("svg",{className:"w-5 h-5 text-cyan-400",fill:"none",viewBox:"0 0 24 24",stroke:"currentColor",children:s.jsx("path",{strokeLinecap:"round",strokeLinejoin:"round",strokeWidth:2,d:"M3 8l7.89 5.26a2 2 0 002.22 0L21 8M5 19h14a2 2 0 002-2V7a2 2 0 00-2-2H5a2 2 0 00-2 2v10a2 2 0 002 2z"})}),e("quickAnalysis.welcome.email")," ",s.jsx("span",{className:"text-cyan-400",children:"*"})]}),s.jsxs("div",{className:"relative group",children:[s.jsx("input",{type:"email",id:"email",name:"email",value:i.email,onChange:u,onBlur:()=>p("email"),placeholder:e("quickAnalysis.welcome.emailPlaceholder"),className:`
3816                  w-full bg-[#2a2d4a] text-white px-4 py-3 rounded-xl 
3817                  border-2 transition-all duration-300 placeholder-gray-500
3818                  ${c.email&&o.email?"border-red-500 focus:border-red-500":"border-transparent focus:border-cyan-400 group-hover:border-cyan-400/30"}
3819                  focus:outline-none focus:shadow-lg focus:shadow-cyan-400/20
3820                `}),s.jsx("div",{className:"absolute inset-0 rounded-xl bg-gradient-to-r from-cyan-400/0 to-blue-500/0 group-hover:from-cyan-400/5 group-hover:to-blue-500/5 pointer-events-none transition-all duration-300"})]}),c.email&&o.email&&s.jsxs(_.p,{initial:{opacity:0,y:-10},animate:{opacity:1,y:0},className:"text-red-400 text-sm mt-2 flex items-center gap-1",children:[s.jsx("svg",{className:"w-4 h-4",fill:"currentColor",viewBox:"0 0 20 20",children:s.jsx("path",{fillRule:"evenodd",d:"M18 10a8 8 0 11-16 0 8 8 0 0116 0zm-7 4a1 1 0 11-2 0 1 1 0 012 0zm-1-9a1 1 0 00-1 1v4a1 1 0 102 0V6a1 1 0 00-1-1z",clipRule:"evenodd"})}),o.email[n]||o.email.es]})]}),s.jsxs(_.div,{initial:{opacity:0,x:-20},animate:{opacity:1,x:0},transition:{delay:.8,duration:.5},children:[s.jsxs("label",{htmlFor:"company",className:"block text-gray-300 mb-2 font-medium flex items-center gap-2",children:[s.jsx("svg",{className:"w-5 h-5 text-cyan-400",fill:"none",viewBox:"0 0 24 24",stroke:"currentColor",children:s.jsx("path",{strokeLinecap:"round",strokeLinejoin:"round",strokeWidth:2,d:"M19 21V5a2 2 0 00-2-2H7a2 2 0 00-2 2v16m14 0h2m-2 0h-5m-9 0H3m2 0h5M9 7h1m-1 4h1m4-4h1m-1 4h1m-5 10v-5a1 1 0 011-1h2a1 1 0 011 1v5m-4 0h4"})}),e("quickAnalysis.welcome.company")," ",s.jsx("span",{className:"text-cyan-400",children:"*"})]}),s.jsxs("div",{className:"relative group",children:[s.jsx("input",{type:"text",id:"company",name:"company",value:i.company,onChange:u,onBlur:()=>p("company"),placeholder:e("quickAnalysis.welcome.companyPlaceholder"),className:`
3821                  w-full bg-[#2a2d4a] text-white px-4 py-3 rounded-xl 
3822                  border-2 transition-all duration-300 placeholder-gray-500
3823                  ${c.company&&o.company?"border-red-500 focus:border-red-500":"border-transparent focus:border-cyan-400 group-hover:border-cyan-400/30"}
3824                  focus:outline-none focus:shadow-lg focus:shadow-cyan-400/20
3825                `}),s.jsx("div",{className:"absolute inset-0 rounded-xl bg-gradient-to-r from-cyan-400/0 to-blue-500/0 group-hover:from-cyan-400/5 group-hover:to-blue-500/5 pointer-events-none transition-all duration-300"})]}),c.company&&o.company&&s.jsxs(_.p,{initial:{opacity:0,y:-10},animate:{opacity:1,y:0},className:"text-red-400 text-sm mt-2 flex items-center gap-1",children:[s.jsx("svg",{className:"w-4 h-4",fill:"currentColor",viewBox:"0 0 20 20",children:s.jsx("path",{fillRule:"evenodd",d:"M18 10a8 8 0 11-16 0 8 8 0 0116 0zm-7 4a1 1 0 11-2 0 1 1 0 012 0zm-1-9a1 1 0 00-1 1v4a1 1 0 102 0V6a1 1 0 00-1-1z",clipRule:"evenodd"})}),o.company[n]||o.company.es]})]}),s.jsxs(_.div,{initial:{opacity:0,x:-20},animate:{opacity:1,x:0},transition:{delay:.9,duration:.5},children:[s.jsxs("label",{htmlFor:"industry",className:"block text-gray-300 mb-2 font-medium flex items-center gap-2",children:[s.jsx("svg",{className:"w-5 h-5 text-cyan-400",fill:"none",viewBox:"0 0 24 24",stroke:"currentColor",children:s.jsx("path",{strokeLinecap:"round",strokeLinejoin:"round",strokeWidth:2,d:"M21 13.255A23.931 23.931 0 0112 15c-3.183 0-6.22-.62-9-1.745M16 6V4a2 2 0 00-2-2h-4a2 2 0 00-2 2v2m4 6h.01M5 20h14a2 2 0 002-2V8a2 2 0 00-2-2H5a2 2 0 00-2 2v10a2 2 0 002 2z"})}),e("quickAnalysis.welcome.industry")," ",s.jsx("span",{className:"text-cyan-400",children:"*"})]}),s.jsxs("div",{className:"relative group",children:[s.jsxs("select",{id:"industry",name:"industry",value:i.industry,onChange:u,onBlur:()=>p("industry"),className:`
3826                  w-full bg-[#2a2d4a] text-white px-4 py-3 rounded-xl 
3827                  border-2 transition-all duration-300
3828                  ${c.industry&&o.industry?"border-red-500 focus:border-red-500":"border-transparent focus:border-cyan-400 group-hover:border-cyan-400/30"}
3829                  focus:outline-none cursor-pointer focus:shadow-lg focus:shadow-cyan-400/20
3830                `,children:[s.jsx("option",{value:"",className:"bg-[#2a2d4a]",children:e("quickAnalysis.welcome.industryPlaceholder")}),tae.map(g=>s.jsx("option",{value:g.id,className:"bg-[#2a2d4a]",children:g.name[n]||g.name.es},g.id))]}),s.jsx("div",{className:"absolute inset-0 rounded-xl bg-gradient-to-r from-cyan-400/0 to-blue-500/0 group-hover:from-cyan-400/5 group-hover:to-blue-500/5 pointer-events-none transition-all duration-300"})]}),c.industry&&o.industry&&s.jsxs(_.p,{initial:{opacity:0,y:-10}
3830,animate:{opacity:1,y:0},className:"text-red-400 text-sm mt-2 flex items-center gap-1",children:[s.jsx("svg",{className:"w-4 h-4",fill:"currentColor",viewBox:"0 0 20 20",children:s.jsx("path",{fillRule:"evenodd",d:"M18 10a8 8 0 11-16 0 8 8 0 0116 0zm-7 4a1 1 0 11-2 0 1 1 0 012 0zm-1-9a1 1 0 00-1 1v4a1 1 0 102 0V6a1 1 0 00-1-1z",clipRule:"evenodd"})}),o.industry[n]||o.industry.es]})]}),s.jsxs(_.div,{initial:{opacity:0,x:-20},animate:{opacity:1,x:0},transition:{delay:1,duration:.5},children:[s.jsxs("label",{htmlFor:"developmentType",className:"block text-gray-300 mb-2 font-medium flex items-center gap-2",children:[s.jsx("svg",{className:"w-5 h-5 text-cyan-400",fill:"none",viewBox:"0 0 24 24",stroke:"currentColor",children:s.jsx("path",{strokeLinecap:"round",strokeLinejoin:"round",strokeWidth:2,d:"M10 20l4-16m4 4l4 4-4 4M6 16l-4-4 4-4"})}),e("quickAnalysis.welcome.developmentType")," ",s.jsx("span",{className:"text-cyan-400",children:"*"})]}),s.jsxs("div",{className:"relative group",children:[s.jsxs("select",{id:"developmentType",name:"developmentType",value:i.developmentType,onChange:u,onBlur:()=>p("developmentType"),className:`
3831                  w-full bg-[#2a2d4a] text-white px-4 py-3 rounded-xl 
3832                  border-2 transition-all duration-300
3833                  ${c.developmentType&&o.developmentType?"border-red-500 focus:border-red-500":"border-transparent focus:border-cyan-400 group-hover:border-cyan-400/30"}
3834                  focus:outline-none cursor-pointer focus:shadow-lg focus:shadow-cyan-400/20
3835                `,children:[s.jsx("option",{value:"",className:"bg-[#2a2d4a]",children:e("quickAnalysis.welcome.developmentTypePlaceholder")}),aae.map(g=>s.jsx("option",{value:g.id,className:"bg-[#2a2d4a]",children:g.name[n]||g.name.es},g.id))]}),s.jsx("div",{className:"absolute inset-0 rounded-xl bg-gradient-to-r from-cyan-400/0 to-blue-500/0 group-hover:from-cyan-400/5 group-hover:to-blue-500/5 pointer-events-none transition-all duration-300"})]}),c.developmentType&&o.developmentType&&s.jsxs(_.p,{initial:{opacity:0,y:-10},animate:{opacity:1,y:0},className:"text-red-400 text-sm mt-2 flex items-center gap-1",children:[s.jsx("svg",{className:"w-4 h-4",fill:"currentColor",viewBox:"0 0 20 20",children:s.jsx("path",{fillRule:"evenodd",d:"M18 10a8 8 0 11-16 0 8 8 0 0116 0zm-7 4a1 1 0 11-2 0 1 1 0 012 0zm-1-9a1 1 0 00-1 1v4a1 1 0 102 0V6a1 1 0 00-1-1z",clipRule:"evenodd"})}),o.developmentType[n]||o.developmentType.es]})]}),s.jsxs(_.div,{initial:{opacity:0,y:20},animate:{opacity:1,y:0},transition:{delay:1.1,duration:.5},className:"relative",children:[h()&&s.jsx(_.div,{className:"absolute inset-0 bg-gradient-to-r from-cyan-400 to-blue-500 rounded-xl blur-xl opacity-50",animate:{opacity:[.3,.6,.3]},transition:{duration:2,repeat:1/0,ease:"easeInOut"}}),s.jsxs(_.button,{type:"submit",disabled:!h(),whileHover:h()?{scale:1.03,y:-2}:{},whileTap:h()?{scale:.97}:{},className:`
3836                relative w-full py-4 px-6 rounded-xl font-bold text-lg
3837                transition-all duration-300 border-2 overflow-hidden
3838                ${h()?"bg-gradient-to-r from-cyan-400 via-blue-500 to-purple-500 hover:from-cyan-500 hover:via-blue-600 hover:to-purple-600 text-white border-cyan-400 shadow-2xl shadow-cyan-400/50":"bg-gray-600 text-gray-400 border-gray-600 cursor-not-allowed opacity-50"}
3839              `,children:[h()&&s.jsx(_.div,{className:"absolute inset-0 bg-gradient-to-r from-transparent via-white/30 to-transparent",animate:{x:["-100%","200%"]},transition:{duration:2,repeat:1/0,ease:"easeInOut",repeatDelay:1}}),s.jsxs("span",{className:"relative flex items-center justify-center gap-2",children:[s.jsx("svg",{className:"w-6 h-6",fill:"none",viewBox:"0 0 24 24",stroke:"currentColor",children:s.jsx("path",{strokeLinecap:"round",strokeLinejoin:"round",strokeWidth:2,d:"M13 7l5 5m0 0l-5 5m5-5H6"})}),e("quickAnalysis.welcome.startButton")]})]})]})]})]})]})}const sae=[{id:"q1",group:1,text:{es:"¿Aplican mediciones y gestiones sobre los issues productivos para determinar mejoras continuas en el ciclo de desarrollo?",en:"Do you apply measurements and management on production issues to determine continuous improvements in the development cycle?"},category:"process",weight:1},{id:"q2",group:1,text:{es:"¿Hay un representante del equipo de calida
3839d en el levantamiento de requerimientos y/o planificación?",en:"Is there a quality team representative in requirements gathering and/or planning?"},category:"integration",weight:1},{id:"q3",group:1,text:{es:"¿Existen DOR (Definition of Ready) y DOD (Definition of Done) claros para las tareas a realizar?",en:"Are there clear DOR (Definition of Ready) and DOD (Definition of Done) for tasks to be performed?"},category:"process",weight:1},{id:"q4",group:2,text:{es:"¿El software es testeado en ambientes similares a producción?",en:"Is the software tested in environments similar to production?"},category:"environment",weight:1},{id:"q5",group:2,text:{es:"¿Los desarrolladores aplican pruebas unitarias?",en:"Do developers apply unit tests?"},category:"testing",weight:1},{id:"q6",group:2,text:{es:"¿Se aplican pruebas humo para validar los criterios de aceptación antes de pasar a etapa de pruebas?",en:"Are smoke tests applied to validate acceptance criteria before moving to the testing stage?"},category:"testing",weight:1},{id:"q7",group:3,text:{es:"¿El equipo de calidad realiza pruebas automatizadas?",en:"Does the quality team perform automated tests?"},category:"automation",weight:1},{id:"q8",group:3,text:{es:"¿Se obtienen métricas relevantes para la mejora continua en base a los bugs identificados?",en:"Are relevant metrics obtained for continuous improvement based on identified bugs?"},category:"metrics",weight:1},{id:"q9",group:3,text:{es:"¿La información del proceso de calidad está disponible fácilmente para todo el equipo?",en:"Is quality process information easily available to the entire team?"},category:"transparency",weight:1},{id:"q10",group:4,text:{es:"¿Se realizan pruebas regresivas periódicamente?",en:"Are regression tests performed periodically?"},category:"testing",weight:1}],lae=t=>{const e={};return t.forEach(a=>{e[a.group]||(e[a.group]=[]),e[a.group].push(a)}),Object.values(e)},Jp={industry:{finance:[{id:"q_fin_1",group:4,text:{es:"¿Se realizan pruebas de seguridad y cumplimiento normativo (PCI-DSS, SOX, etc.) de forma regular?",en:"Are security and regulatory compliance tests (PCI-DSS, SOX, etc.) performed regularly?"},category:"security",weight:1}],retail:[{id:"q_retail_1",group:4,text:{es:"¿Se realizan pruebas de carga y performance durante eventos de alto tráfico (Black Friday, Cyber Monday)?",en:"Are load and performance tests conducted during high-traffic events (Black Friday, Cyber Monday)?"},category:"performance",weight:1}],health:[{id:"q_health_1",group:4,text:{es:"¿Se valida el cumplimiento de normativas de privacidad de datos médicos (HIPAA, GDPR)?",en:"Is compliance with medical data privacy regulations (HIPAA, GDPR) validated?"},category:"compliance",weight:1}],manufacturing:[{id:"q_manuf_1",group:4,text:{es:"¿Se realizan pruebas de integración con dispositivos IoT y sistemas embebidos?",en:"Are integration tests performed with IoT devices and embedded systems?"},category:"integration",weight:1}],government:[{id:"q_gov_1",group:4,text:{es:"¿Se realizan auditorías de seguridad y cumplimiento de estándares gubernamentales?",en:"Are security audits and compliance with government standards performed?"},category:"compliance",weight:1}],technology:[{id:"q_tech_1",group:4,text:{es:"¿Se realizan pruebas de escalabilidad y multi-tenancy?",en:"Are scalability and multi-tenancy tests performed?"},category:"scalability",weight:1}],insurance:[{id:"q_ins_1",group:4,text:{es:"¿Se validan los cálculos actuariales y procesos de suscripción en las pruebas?",en:"Are actuarial calculations and underwriting processes validated in testing?"},category:"business_logic",weight:1}]},developmentType:{ecommerce:[{id:"q_ecom_1",group:4,text:{es:"¿Se validan los flujos de pago y checkout en diferentes métodos de pago?",en:"Are payment and checkout flows validated across different payment methods?"},category:"payment",weight:1}],salesforce:[{id:"q_sf_1",group:4,text:{es:"¿Se realizan pruebas de integración con sistemas legacy y migraciones de datos?",en:"Are integration tests with legacy systems and data migrations performed?"}
3839,category:"integration",weight:1}],sap:[{id:"q_sap_1",group:4,text:{es:"¿Se realizan pruebas de integración con sistemas legacy y migraciones de datos?",en:"Are integration tests with legacy systems and data migrations performed?"},category:"integration",weight:1}],erp:[{id:"q_erp_1",group:4,text:{es:"¿Se validan los procesos de negocio end-to-end en las pruebas?",en:"Are end-to-end business processes validated in testing?"},category:"business_logic",weight:1}],api:[{id:"q_api_1",group:4,text:{es:"¿Se realizan pruebas de contrato y validación de APIs?",en:"Are contract tests and API validation performed?"},category:"api",weight:1}],mobile:[{id:"q_mobile_1",group:4,text:{es:"¿Se realizan pruebas en múltiples dispositivos y versiones de OS?",en:"Are tests performed on multiple devices and OS versions?"},category:"compatibility",weight:1}],data_analytics:[{id:"q_data_1",group:4,text:{es:"¿Se valida la calidad y precisión de los datos en los reportes?",en:"Is data quality and accuracy validated in reports?"},category:"data_quality",weight:1}],iot:[{id:"q_iot_1",group:4,text:{es:"¿Se realizan pruebas de conectividad y resiliencia de dispositivos IoT?",en:"Are connectivity and resilience tests performed on IoT devices?"},category:"iot",weight:1}]}},cae=t=>{const[e,a]=k.useState(0),[n,i]=k.useState({}),[r,o]=k.useState([]);k.useEffect(()=>{l()},[t]);const l=()=>{let w=[...sae];if(t!=null&&t.industry&&Jp.industry[t.industry]){const T=Jp.industry[t.industry];w=[...w,...T]}if(t!=null&&t.developmentType&&Jp.developmentType[t.developmentType]){const T=Jp.developmentType[t.developmentType];w=[...w,...T]}const S=lae(w);o(S)},c=(w,S)=>{i(T=>({...T,[w]:S}))},d=k.useMemo(()=>{if(r.length===0)return!1;const w=r[e];return rae(w,n)},[r,e,n]),u=()=>{e<r.length-1&&a(w=>w+1)},p=()=>{e>0&&a(w=>w-1)},m=k.useMemo(()=>e===r.length-1,[e,r]),h=k.useMemo(()=>e===0,[e]),g=k.useMemo(()=>r[e]||[],[r,e]),y=k.useMemo(()=>r.flat().length,[r]),x=k.useMemo(()=>Object.keys(n).length,[n]),v=()=>{a(0),i({})};return{currentGroupIndex:e,answers:n,questionGroups:r,currentQuestions:g,totalQuestions:y,answeredQuestions:x,totalGroups:r.length,isLastGroup:m,isFirstGroup:h,canContinue:d,handleAnswer:c,handleNext:u,handlePrevious:p,resetQuiz:v}};function dae({current:t,total:e}){const{t:a}=$(),n=e>0?Math.round(t/e*100):0;return s.jsxs("div",{className:"w-full mb-8",children:[s.jsxs("div",{className:"flex justify-between items-center mb-3",children:[s.jsx("span",{className:"text-gray-300 text-sm font-medium",children:a("quickAnalysis.quiz.progress")}),s.jsxs("span",{className:"text-cyan-400 text-sm font-bold",children:[n,"%"]})]}),s.jsx("div",{className:"w-full h-3 bg-[#2a2d4a] rounded-full overflow-hidden",children:s.jsx(_.div,{initial:{width:0},animate:{width:`${n}%`},transition:{duration:.5,ease:"easeOut"},className:"h-full bg-gradient-to-r from-cyan-400 to-blue-500 rounded-full relative",children:s.jsx("div",{className:"absolute inset-0 bg-white/20 animate-pulse"})})}),s.jsx("div",{className:"flex justify-between items-center mt-2",children:s.jsxs("span",{className:"text-gray-400 text-xs",children:[t," ",a("quickAnalysis.quiz.of")," ",e]})})]})}function uae({value:t,onChange:e}){const{t:a}=$(),n=[{value:1,label:a("quickAnalysis.rating.never")},{value:2,label:a("quickAnalysis.rating.rarely")},{value:3,label:a("quickAnalysis.rating.sometimes")},{value:4,label:a("quickAnalysis.rating.frequently")},{value:5,label:a("quickAnalysis.rating.always")}];return s.jsx("div",{className:"flex flex-col sm:flex-row gap-3 sm:gap-4 justify-center items-stretch sm:items-center mt-6",children:n.map(i=>s.jsxs(_.button,{type:"button",onClick:()=>e(i.value),whileHover:{scale:1.1},whileTap:{scale:.95},className:`
3840            flex flex-col items-center justify-center gap-2 p-4 rounded-xl
3841            transition-all duration-300 min-w-[80px] sm:min-w-[100px]
3842            ${t===i.value?"bg-gradient-to-br from-cyan-400 to-blue-500 text-white shadow-lg shadow-cyan-400/50 border-2 border-cyan-300":"bg-[#2a2d4a] text-gray-300 hover:bg-[#3a3d5a] border-2 border-transparent hover:border-cyan-400/30"}
3843          `,children:[s.jsx("div",{className:`
3844            w-10 h-10 sm:w-12 sm:h-12 rounded-full flex items-center justify-center text-xl sm:text-2xl font-bold
3845            ${t===i.value?"bg-white/20":"bg-white/5"}
3846          `,children:i.value}),s.jsx("span",{className:"text-xs sm:text-sm font-medium text-center",children:i.label})]},i.value))})}function pae({id:t,text:e,value:a,onChange:n,index:i=0}){const{i18n:r}=$(),o=r.language;return s.jsxs(_.div,{initial:{opacity:0,y:20}
3846,animate:{opacity:1,y:0},transition:{duration:.4,delay:i*.1},className:"bg-[#1a1d3a]/50 backdrop-blur-sm rounded-2xl p-6 sm:p-8 border border-cyan-400/20 hover:border-cyan-400/40 transition-all duration-300",children:[s.jsx("h3",{className:"text-lg sm:text-xl text-white font-medium mb-4 leading-relaxed",children:e[o]||e.es}),s.jsx(uae,{value:a,onChange:n})]})}function mae({questions:t,answers:e,onAnswer:a}){return s.jsx(_.div,{initial:{opacity:0,x:50},animate:{opacity:1,x:0},exit:{opacity:0,x:-50},transition:{duration:.3},className:"space-y-6",children:t.map((n,i)=>s.jsx(pae,{id:n.id,text:n.text,value:e[n.id]||null,onChange:r=>a(n.id,r),index:i},n.id))})}function hae({userData:t,onComplete:e}){const{t:a}=$(),{currentGroupIndex:n,answers:i,currentQuestions:r,totalQuestions:o,answeredQuestions:l,totalGroups:c,isLastGroup:d,isFirstGroup:u,canContinue:p,handleAnswer:m,handleNext:h,handlePrevious:g}=cae(t),y=()=>{d?e(i):h()};return s.jsxs(_.div,{initial:{opacity:0},animate:{opacity:1},transition:{duration:.5},className:"max-w-4xl mx-auto",children:[s.jsx("div",{className:"absolute top-0 right-0 w-96 h-96 bg-cyan-500/10 rounded-full blur-3xl"}),s.jsx("div",{className:"absolute bottom-0 left-0 w-96 h-96 bg-blue-500/10 rounded-full blur-3xl"}),s.jsxs("div",{className:"relative",children:[s.jsx(dae,{current:l,total:o}),s.jsx(La,{mode:"wait",children:s.jsx(mae,{questions:r,answers:i,onAnswer:m},n)}),s.jsxs("div",{className:"flex flex-col sm:flex-row gap-4 mt-8",children:[!u&&s.jsx(_.button,{type:"button",onClick:g,whileHover:{scale:1.02},whileTap:{scale:.98},className:`
3847                flex-1 py-4 px-6 rounded-xl font-bold text-lg
3848                bg-[#2a2d4a] text-gray-300 border-2 border-cyan-400/30
3849                hover:bg-[#3a3d5a] hover:border-cyan-400/50
3850                transition-all duration-300
3851              `,children:a("quickAnalysis.quiz.previousButton")}),s.jsx(_.button,{type:"button",onClick:y,disabled:!p,whileHover:p?{scale:1.02}:{},whileTap:p?{scale:.98}:{},className:`
3852              flex-1 py-4 px-6 rounded-xl font-bold text-lg
3853              transition-all duration-300 border-2
3854              ${p?"bg-gradient-to-r from-cyan-400 to-blue-500 hover:from-cyan-500 hover:to-blue-600 text-white border-cyan-400 hover:shadow-lg hover:shadow-cyan-400/50":"bg-gray-600 text-gray-400 border-gray-600 cursor-not-allowed opacity-50"}
3855            `,children:a(d?"quickAnalysis.quiz.seeResultsButton":"quickAnalysis.quiz.continueButton")})]}),!p&&s.jsx(_.p,{initial:{opacity:0,y:-10},animate:{opacity:1,y:0},className:"text-center text-amber-400 text-sm mt-4",children:a("quickAnalysis.quiz.allQuestionsRequired")}),s.jsx("div",{className:"text-center mt-6",children:s.jsxs("span",{className:"text-gray-400 text-sm",children:[a("quickAnalysis.quiz.question")," ",n+1," ",a("quickAnalysis.quiz.of")," ",c]})})]})]})}
3855const V0={reactive:{id:"reactive",range:[0,20],name:{es:"Calidad Reactiva",en:"Reactive Quality"},label:{es:"Nivel Crítico",en:"Critical Level"},color:"#EF4444",bgColor:"bg-red-500",textColor:"text-red-500",borderColor:"border-red-500",diagnosis:{es:"El equipo apaga incendios. QA es un cuello de botella al final del proceso y hay poca visibilidad de lo que pasa en producción.",en:"The team is firefighting. QA is a bottleneck at the end of the process with little visibility into production."},icon:"🚨"},transition:{id:"transition",range:[21,40],name:{es:"Calidad en Transición",en:"Quality in Transition"},label:{es:"Nivel Medio",en:"Medium Level"},color:"#F59E0B",bgColor:"bg-amber-500",textColor:"text-amber-500",borderColor:"border-amber-500",diagnosis:{es:"Existen esfuerzos (quizás algunas pruebas unitarias o ambientes de QA), pero falta consistencia y métricas para mejorar.",en:"Efforts exist (perhaps some unit tests or QA environments), but consistency and metrics for improvement are lacking."},icon:"⚠️"}
3855,advanced:{id:"advanced",range:[41,60],name:{es:"Calidad Avanzada",en:"Advanced Quality"},label:{es:"Nivel Pro",en:"Pro Level"},color:"#10B981",bgColor:"bg-green-500",textColor:"text-green-500",borderColor:"border-green-500",diagnosis:{es:"El equipo tiene cultura de calidad. QA está integrado y hay métricas.",en:"The team has a quality culture. QA is integrated and there are metrics."},icon:"✅"}},fae=t=>t<=20?V0.reactive:t<=40?V0.transition:V0.advanced,gae={silos:{id:"silos",name:{es:"Alerta de Silos",en:"Silos Alert"},condition:t=>(t.q2||0)<3&&(t.q9||0)<3,message:{es:"Tu equipo de QA está aislado; esto genera retrabajo y costos altos de corrección.",en:"Your QA team is isolated; this generates rework and high correction costs."},icon:"🚨",color:"#EF4444",severity:"high"},production_risk:{id:"production_risk",name:{es:"Alerta de Riesgo en Producción",en:"Production Risk Alert"},condition:t=>(t.q1||0)<3&&(t.q8||0)<3,message:{es:"Estás volando a ciegas; no estás aprendiendo de tus errores en producción.",en:"You are flying blind; you are not learning from your production errors."},icon:"⚠️",color:"#F59E0B",severity:"high"},technical_debt:{id:"technical_debt",name:{es:"Alerta de Deuda Técnica",en:"Technical Debt Alert"},condition:t=>(t.q5||0)<3&&(t.q7||0)<3&&(t.q10||0)<3,message:{es:"Tu regresión manual se volverá insostenible pronto. La automatización es tu siguiente paso.",en:"Your manual regression will become unsustainable soon. Automation is your next step."},icon:"🔧",color:"#F59E0B",severity:"medium"},environment_issues:{id:"environment_issues",name:{es:"Alerta de Ambientes",en:"Environment Alert"},condition:t=>(t.q4||0)<3,message:{es:"Tus ambientes de prueba no reflejan producción, lo que aumenta el riesgo de bugs en producción.",en:"Your test environments do not reflect production, increasing the risk of production bugs."},icon:"🌐",color:"#F59E0B",severity:"medium"}},yae=t=>{const e=[];return Object.values(gae).forEach(a=>{a.condition(t)&&e.push(a)}),e},Qp={qa_assessment:{id:"qa_assessment",name:{es:"QA Assessment & Strategy",en:"QA Assessment & Strategy"},description:{es:"Definimos procesos desde cero, establecemos DOR/DOD y movemos QA hacia la izquierda (Shift Left).",en:"We define processes from scratch, establish DOR/DOD and shift QA left."},link:"/servicios#continuous-testing",icon:"📋",levels:["reactive"],categories:["foundation"],redFlags:["silos","production_risk"]},test_automation:{id:"test_automation",name:{es:"Test Automation",en:"Test Automation"},description:{es:"Automatizamos pruebas humo y regresiones para liberar tiempo y mejorar la confianza.",en:"We automate smoke and regression tests to free up time and improve confidence."},link:"/servicios#continuous-testing",icon:"🤖",levels:["transition","advanced"],categories:["automation"],redFlags:["technical_debt"]},continuous_testing:{id:"continuous_testing",name:{es:"Continuous Testing",en:"Continuous Testing"},description:{es:"Integramos pruebas en tu pipeline CI/CD para detectar problemas temprano.",en:"We integrate tests into your CI/CD pipeline to detect problems early."},link:"/servicios#continuous-testing",icon:"🔄",levels:["reactive","transition","advanced"],categories:["integration"],redFlags:["silos","technical_debt"]},performance_testing:{id:"performance_testing",name:{es:"Performance Testing",en:"Performance Testing"},description:{es:"Optimizamos la carga del sistema y aseguramos que tu aplicación escale.",en:"We optimize system load and ensure your application scales."},link:"/servicios#performance",icon:"⚡",levels:["transition","advanced"],categories:["optimization","advanced"],redFlags:["production_risk"]},data_testing:{id:"data_testing",name:{es:"Data Testing",en:"Data Testing"},description:{es:"Validamos la calidad y precisión de tus datos en pipelines y reportes.",en:"We validate the quality and accuracy of your data in pipelines and reports."},link:"/servicios#data",icon:"📊",levels:["advanced"],categories:["advanced"],redFlags:[]},resource_optimization:{id:"resource_optimization",name:{es:"Optimización de Recursos",en:"Resource Optimization"},description:{es:"Optimizamos tus procesos de QA existentes para maximizar eficiencia y reducir costos.",en:"We optimize your existing QA processes to maximize efficiency and reduce costs."},link:"/servicios#continuous-testing",icon:"💎",levels:["advanced"],categories:["optimization"],redFlags:[]}},xae=(t,e,a)=>{let n=[];
3855Object.values(Qp).forEach(l=>{l.levels.includes(t)&&n.push(l)});const i=e.map(l=>l.id);Object.values(Qp).forEach(l=>{l.redFlags.some(d=>i.includes(d))&&!n.find(d=>d.id===l.id)&&n.push(l)}),a>50&&(n=n.filter(l=>l.categories.includes("optimization")||l.categories.includes("advanced")),n.length<2&&(n.push(Qp.resource_optimization),n.push(Qp.data_testing)));const r=[],o=new Set;return n.forEach(l=>{o.has(l.id)||(o.add(l.id),r.push(l))}),r},vae=(t,e)=>t>50?{es:"¡Excelente trabajo! Tu equipo tiene un nivel de calidad sólido. Podemos ayudarte a optimizar aún más tus recursos y procesos para alcanzar la excelencia operacional.",en:"Excellent work! Your team has a solid quality level. We can help you further optimize your resources and processes to achieve operational excellence."}:e==="transition"?{es:"Estás en el camino correcto. Con las mejoras adecuadas, puedes llevar tu calidad al siguiente nivel y reducir significativamente los costos de corrección.",en:"You are on the right track. With the right improvements, you can take your quality to the next level and significantly reduce correction costs."}:{es:"Hay oportunidades importantes de mejora. Implementar las prácticas correctas ahora te ahorrará tiempo y dinero en el futuro.",en:"There are significant opportunities for improvement. Implementing the right practices now will save you time and money in the future."},bae=t=>Object.values(t).reduce((e,a)=>e+(a||0),0),wae=t=>fae(t),kae=t=>yae(t),Sae=(t,e,a)=>xae(t,e,a),DO=t=>{const e=bae(t),a=wae(e),n=kae(t),i=Sae(a.id,n,e),r=vae(e,a.id);return{totalScore:e,maxScore:60,maturityLevel:a,redFlags:n,recommendedServices:i,personalizedMessage:r,answersCount:Object.keys(t).length}},_ae=t=>{const e=k.useMemo(()=>!t||Object.keys(t).length===0?null:DO(t),[t]),a=(e==null?void 0:e.totalScore)||0,n=(e==null?void 0:e.maxScore)||60,i=(e==null?void 0:e.maturityLevel)||null,r=(e==null?void 0:e.redFlags)||[],o=(e==null?void 0:e.recommendedServices)||[],l=(e==null?void 0:e.personalizedMessage)||null,c=n>0?Math.round(a/n*100):0,d=k.useMemo(()=>r.length>0,[r]),u=k.useMemo(()=>i?i.color:"#6B7280",[i]),p=k.useMemo(()=>a>50,[a]),m=k.useMemo(()=>a<20,[a]),h=k.useMemo(()=>a>=20&&a<=40,[a]);return{results:e,totalScore:a,maxScore:n,scorePercentage:c,maturityLevel:i,redFlags:r,recommendedServices:o,personalizedMessage:l,hasCriticalFlags:d,levelColor:u,isHighScore:p,isLowScore:m,isMediumScore:h,isReady:e!==null}};function Aae({score:t,maxScore:e=60}){const{t:a}=$(),[n,i]=k.useState(0),r=Math.round(t/e*100);k.useEffect(()=>{let l=0;const d=t/(1500/16),u=setInterval(()=>{l+=d,l>=t?(i(t),clearInterval(u)):i(Math.floor(l))},16);return()=>clearInterval(u)},[t]);const o=()=>r>=70?"from-green-400 to-emerald-500":r>=40?"from-amber-400 to-orange-500":"from-red-400 to-rose-500";return s.jsxs(_.div,{initial:{scale:0,opacity:0},animate:{scale:1,opacity:1},transition:{duration:.6,ease:"backOut"},className:"relative",children:[s.jsxs("div",{className:"relative w-64 h-64 mx-auto",children:[s.jsx("div",{className:"absolute inset-0 rounded-full bg-gradient-to-br from-cyan-400/20 to-blue-500/20 blur-xl"}),s.jsx("div",{className:"relative w-full h-full rounded-full bg-[#1a1d3a] border-8 border-[#2a2d4a] flex flex-col items-center justify-center",children:s.jsxs(_.div,{initial:{scale:0},animate:{scale:1},transition:{delay:.3,duration:.5,ease:"backOut"},className:"text-center",children:[s.jsx("div",{className:`text-6xl font-bold bg-gradient-to-r ${o()} bg-clip-text text-transparent`,children:n}),s.jsxs("div",{className:"text-gray-400 text-sm mt-1",children:[a("quickAnalysis.results.outOf")," ",e]}),s.jsx("div",{className:"text-gray-300 text-xs mt-2",children:a("quickAnalysis.results.points")})]})}),s.jsxs("svg",{className:"absolute inset-0 w-full h-full -rotate-90",children:[s.jsx("circle",{cx:"50%",cy:"50%",r:"45%",fill:"none",stroke:"#2a2d4a",strokeWidth:"8"}),s.jsx(_.circle,{cx:"50%",cy:"50%",r:"45%",fill:"none",stroke:"url(#scoreGradient)",strokeWidth:"8",strokeLinecap:"round",strokeDasharray:`${2*Math.PI*120}`,initial:{strokeDashoffset:2*Math.PI*120},animate:{strokeDashoffset:2*Math.PI*120*(1-r/100)},transition:{duration:1.5,ease:"easeOut"}}),s.jsx("defs",{children:s.jsxs("linearGradient",{id:"scoreGradient",x1:"0%",y1:"0%",x2:"100%",y2:"100%",children:[s.jsx("stop",{offset:"0%",stopColor:"#06b6d4"}),s.jsx("stop",{offset:"100%",stopColor:"#3b82f6"})]})})]})]}),s.jsxs(_.div,{initial:{opacity:0,y:20}
3855,animate:{opacity:1,y:0},transition:{delay:.8,duration:.5},className:"text-center mt-6",children:[s.jsxs("span",{className:"text-2xl font-bold text-cyan-400",children:[r,"%"]}),s.jsx("span",{className:"text-gray-400 text-sm ml-2",children:a("quickAnalysis.results.yourScore")})]})]})}function Eae({level:t,score:e}){const{t:a,i18n:n}=$(),i=n.language;if(!t)return null;const r=()=>{switch(t.id){case"reactive":return"🚨";case"transition":return"⚡";case"advanced":return"🏆";default:return"📊"}};return s.jsxs(_.div,{initial:{opacity:0,y:20},animate:{opacity:1,y:0},transition:{duration:.5,delay:.2},className:"text-center",children:[s.jsx(_.div,{initial:{scale:0},animate:{scale:1},transition:{delay:.4,duration:.5,ease:"backOut"},className:"inline-block",children:s.jsxs("div",{className:"relative px-8 py-4 rounded-2xl border-2",style:{borderColor:t.color,background:`linear-gradient(135deg, ${t.color}20, ${t.color}10)`},children:[s.jsx("div",{className:"text-5xl mb-2",children:r()}),s.jsx("h3",{className:"text-2xl font-bold mb-1",style:{color:t.color},children:t.name[i]||t.name.es}),s.jsx("div",{className:"inline-block px-4 py-1 rounded-full text-sm font-semibold",style:{backgroundColor:`${t.color}30`,color:t.color},children:t.label[i]||t.label.es}),s.jsx("div",{className:"absolute inset-0 rounded-2xl opacity-20 blur-xl",style:{backgroundColor:t.color}})]})}),s.jsx(_.p,{initial:{opacity:0}
3855,animate:{opacity:1},transition:{delay:.6,duration:.5},className:"text-gray-300 text-lg mt-6 max-w-2xl mx-auto leading-relaxed",children:t.diagnosis[i]||t.diagnosis.es})]})}function Cae({redFlags:t}){const{t:e,i18n:a}=$();return a.language,!t||t.length===0?s.jsxs(_.div,{initial:{opacity:0,y:20},animate:{opacity:1,y:0},transition:{duration:.5},className:"bg-green-500/10 border border-green-500/30 rounded-2xl p-6 text-center",children:[s.jsx("div",{className:"text-4xl mb-3",children:"✅"}),s.jsx("p",{className:"text-green-400 font-medium",children:e("quickAnalysis.results.noRedFlags")})]}):s.jsx("div",{className:"space-y-4",children:t.map((n,i)=>s.jsx(_.div,{initial:{opacity:0,x:-20},animate:{opacity:1,x:0},transition:{duration:.5,delay:i*.1},className:"bg-red-500/10 border border-red-500/30 rounded-2xl p-6 hover:border-red-500/50 transition-all duration-300",children:s.jsxs("div",{className:"flex items-start gap-4",children:[s.jsx("div",{className:"text-3xl flex-shrink-0",children:n.icon}),s.jsxs("div",{className:"flex-1",children:[s.jsx("h4",{className:"text-red-400 font-bold text-lg mb-2",children:e(`quickAnalysis.redFlags.${n.id}.title`)}),s.jsx("p",{className:"text-gray-300 leading-relaxed",children:e(`quickAnalysis.redFlags.${n.id}.message`)})]})]})},n.id))})}function jae({maturityLevel:t,redFlags:e,personalizedMessage:a}){const{t:n,i18n:i}=$(),r=i.language;return s.jsxs(_.div,{initial:{opacity:0,y:20},animate:{opacity:1,y:0},transition:{duration:.5,delay:.3},className:"space-y-8",children:[s.jsxs("div",{className:"text-center",children:[s.jsx("h2",{className:"text-3xl font-bold text-white mb-2",children:n("quickAnalysis.results.analysis")}),s.jsx("div",{className:"w-24 h-1 bg-gradient-to-r from-cyan-400 to-blue-500 mx-auto rounded-full"})]}),a&&s.jsx(_.div,{initial:{opacity:0,scale:.95},animate:{opacity:1,scale:1},transition:{delay:.4,duration:.5},className:"bg-gradient-to-br from-cyan-500/10 to-blue-500/10 border border-cyan-400/30 rounded-2xl p-6",children:s.jsx("p",{className:"text-gray-200 text-lg leading-relaxed text-center",children:typeof a=="string"?a:a[r]||a.es})}),s.jsxs("div",{children:[s.jsx("h3",{className:"text-xl font-bold text-white mb-4",children:n("quickAnalysis.results.redFlags")}),s.jsx(Cae,{redFlags:e})]})]})}function Tae({service:t,index:e=0}){const{t:a,i18n:n}=$();return n.language,s.jsx(_.div,{initial:{opacity:0,y:20},animate:{opacity:1,y:0},transition:{duration:.5,delay:e*.1},whileHover:{scale:1.02,y:-5},className:"h-full",children:s.jsxs(Te,{to:t.link,className:"block h-full bg-[#1a1d3a]/50 backdrop-blur-sm rounded-2xl p-6 border border-cyan-400/20 hover:border-cyan-400/50 transition-all duration-300 group",children:[s.jsx("div",{className:"text-4xl mb-4 group-hover:scale-110 transition-transform duration-300",children:t.icon}),s.jsx("h4",{className:"text-xl font-bold text-white mb-3 group-hover:text-cyan-400 transition-colors duration-300",children:a(`quickAnalysis.services.${t.id}.name`)}),s.jsx("p",{className:"text-gray-300 leading-relaxed mb-4",children:a(`quickAnalysis.services.${t.id}.description`)}),s.jsxs("div",{className:"flex items-center text-cyan-400 font-medium group-hover:text-cyan-300 transition-colors duration-300",children:[s.jsx("span",{children:a("quickAnalysis.results.learnMore")}),s.jsx("svg",{className:"w-5 h-5 ml-2 group-hover:translate-x-1 transition-transform duration-300",fill:"none",viewBox:"0 0 24 24",stroke:"currentColor",children:s.jsx("path",{strokeLinecap:"round",strokeLinejoin:"round",strokeWidth:2,d:"M9 5l7 7-7 7"})})]}),s.jsx("div",{className:"absolute inset-0 rounded-2xl bg-gradient-to-br from-cyan-400/0 to-blue-500/0 group-hover:from-cyan-400/5 group-hover:to-blue-500/5 transition-all duration-300 pointer-events-none"})]})})}function Nae({services:t,score:e}){const{t:a}=$();return!t||t.length===0?null:s.jsxs(_.div,{initial:{opacity:0,y:20},animate:{opacity:1,y:0},transition:{duration:.5,delay:.4},className:"space-y-8",children:[s.jsxs("div",{className:"text-center",children:[s.jsx("h2",{className:"text-3xl font-bold text-white mb-2",children:a("quickAnalysis.results.recommendations")}),s.jsx("p",{className:"text-gray-300 text-lg",children:a("quickAnalysis.results.recommendationsSubtitle")}),s.jsx("div",{className:"w-24 h-1 bg-gradient-to-r from-cyan-400 to-blue-500 mx-auto rounded-full mt-4"})]}),e>50&&s.jsx(_.div,{initial:{opacity:0,scale:.95}
3855,animate:{opacity:1,scale:1},transition:{delay:.5,duration:.5},className:"bg-gradient-to-br from-green-500/10 to-emerald-500/10 border border-green-400/30 rounded-2xl p-6",children:s.jsxs("div",{className:"flex items-center gap-3 justify-center",children:[s.jsx("span",{className:"text-3xl",children:"🎉"}),s.jsx("p",{className:"text-green-400 font-medium text-lg",children:a("quickAnalysis.results.highScoreMessage")})]})}),s.jsx("div",{className:"grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-6",children:t.map((n,i)=>s.jsx(Tae,{service:n,index:i},n.id))})]})}function Iae({userEmail:t,results:e}){const{t:a}=$(),{openModal:n}=oa(),i=()=>{n(a("contactModal.title"))};return s.jsx(_.div,{initial:{opacity:0,y:20},animate:{opacity:1,y:0},transition:{duration:.5,delay:.5},className:"text-center",children:s.jsxs("div",{className:"bg-gradient-to-br from-cyan-500/10 to-blue-500/10 border border-cyan-400/30 rounded-3xl p-8 sm:p-12",children:[s.jsx("div",{className:"absolute inset-0 bg-gradient-to-br from-cyan-400/5 to-blue-500/5 rounded-3xl"}),s.jsxs("div",{className:"relative",children:[s.jsx(_.div,{initial:{scale:0},animate:{scale:1},transition:{delay:.6,duration:.5,ease:"backOut"},className:"text-6xl mb-6",children:"💬"}),s.jsx("h3",{className:"text-2xl sm:text-3xl font-bold text-white mb-4",children:"¿Listo para mejorar tu calidad?"}),s.jsx("p",{className:"text-gray-300 text-lg mb-8 max-w-2xl mx-auto",children:"Nuestro equipo de expertos está listo para ayudarte a implementar las mejoras que necesitas."}),s.jsxs(_.button,{onClick:i,whileHover:{scale:1.05},whileTap:{scale:.95},className:`
3856              inline-flex items-center gap-3 px-8 py-4 rounded-xl
3857              bg-gradient-to-r from-cyan-400 to-blue-500 
3858              hover:from-cyan-500 hover:to-blue-600
3859              text-white font-bold text-lg
3860              border-2 border-cyan-400
3861              hover:shadow-lg hover:shadow-cyan-400/50
3862              transition-all duration-300
3863            `,children:[s.jsx("svg",{className:"w-6 h-6",fill:"none",viewBox:"0 0 24 24",stroke:"currentColor",children:s.jsx("path",{strokeLinecap:"round",strokeLinejoin:"round",strokeWidth:2,d:"M3 8l7.89 5.26a2 2 0 002.22 0L21 8M5 19h14a2 2 0 002-2V7a2 2 0 00-2-2H5a2 2 0 00-2 2v10a2 2 0 002 2z"})}),a("quickAnalysis.results.contactButton")]}),s.jsx("p",{className:"text-gray-400 text-sm mt-6",children:"Te responderemos en menos de 24 horas"})]})]})})}function Pae({answers:t,userData:e}){const{t:a}=$(),{totalScore:n,maxScore:i,maturityLevel:r,redFlags:o,recommendedServices:l,personalizedMessage:c,isReady:d}=_ae(t);return d?s.jsxs(_.div,{initial:{opacity:0}
3863,animate:{opacity:1},transition:{duration:.5},className:"max-w-6xl mx-auto space-y-16 pb-16",children:[s.jsx("div",{className:"absolute top-0 right-0 w-96 h-96 bg-cyan-500/10 rounded-full blur-3xl"}),s.jsx("div",{className:"absolute bottom-0 left-0 w-96 h-96 bg-blue-500/10 rounded-full blur-3xl"}),s.jsxs("div",{className:"relative",children:[s.jsxs(_.div,{initial:{opacity:0,y:-20},animate:{opacity:1,y:0},transition:{duration:.5},className:"text-center mb-12",children:[s.jsx("h1",{className:"text-4xl sm:text-5xl font-bold text-white mb-4",children:a("quickAnalysis.results.title")}),s.jsx("div",{className:"w-32 h-1 bg-gradient-to-r from-cyan-400 to-blue-500 mx-auto rounded-full"})]}),s.jsx("div",{className:"mb-16",children:s.jsx(Aae,{score:n,maxScore:i})}),s.jsx("div",{className:"mb-16",children:s.jsx(Eae,{level:r,score:n})}),s.jsx("div",{className:"mb-16",children:s.jsx(jae,{maturityLevel:r,redFlags:o,personalizedMessage:c})}),s.jsx("div",{className:"mb-16",children:s.jsx(Nae,{services:l,score:n})}),s.jsx("div",{children:s.jsx(Iae,{userEmail:e==null?void 0:e.email,results:{totalScore:n,maturityLevel:r,redFlags:o}})})]})]}):s.jsx("div",{className:"flex items-center justify-center min-h-screen",children:s.jsxs("div",{className:"text-center",children:[s.jsx("div",{className:"animate-spin rounded-full h-16 w-16 border-t-2 border-b-2 border-cyan-400 mx-auto mb-4"}),s.jsx("p",{className:"text-gray-300",children:a("quickAnalysis.results.savingResults")})]})})}function Rae(){const{t,i18n:e}=$(),[a,n]=k.useState("welcome"),[i,r]=k.useState(null),[o,l]=k.useState({}),[c,d]=k.useState(null),[u,p]=k.useState(!1);Mg({title:t("quickAnalysis.welcome.title"),description:t("quickAnalysis.welcome.subtitle"),keywords:"quality assessment, software testing, QA maturity, test automation, calidad de software",ogImage:"/imagenes/og-quick-analysis.png"});const m=y=>{r(y),n("quiz")},h=async y=>{l(y);const x=DO(y);d(x),n("results"),g(y,x)},g=async(y,x)=>{p(!0);try{const v={email:i.email,company:i.company,industry:i.industry,developmentType:i.developmentType,answers:y,totalScore:x.totalScore,maxScore:x.maxScore,maturityLevel:x.maturityLevel.id,maturityLevelName:x.maturityLevel.name[e.language]||x.maturityLevel.name.es,redFlags:x.redFlags.map(S=>S.id),timestamp:xt.now(),language:e.language,userAgent:navigator.userAgent,completed:!0,jiraIssueCreated:!1,jiraIssueKey:null},w=await Tl(ga(St,"quality_assessments"),v);console.log("Evaluación guardada en Firestore con ID:",w.id);try{const S=await fetch("https://us-central1-web-haka-2026.cloudfunctions.net/createJiraIssueFromAssessment",{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({assessmentId:w.id,...v})});if(S.ok){const T=await S.json();console.log("Issue creado en Jira:",T)}else console.warn("No se pudo crear el issue en Jira:",S.status)}catch(S){console.warn("Error al crear issue en Jira:",S)}}catch(v){console.error("Error al guardar evaluación:",v)}finally{p(!1)}};return s.jsxs("div",{className:"min-h-screen bg-dark pt-24 pb-16 px-4 sm:px-6 lg:px-8 relative overflow-hidden",children:[s.jsxs(La,{mode:"wait",children:[a==="welcome"&&s.jsx(_.div,{initial:{opacity:0}
3863,animate:{opacity:1},exit:{opacity:0},transition:{duration:.3},children:s.jsx(oae,{onSubmit:m})},"welcome"),a==="quiz"&&s.jsx(_.div,{initial:{opacity:0},animate:{opacity:1},exit:{opacity:0},transition:{duration:.3},children:s.jsx(hae,{userData:i,onComplete:h})},"quiz"),a==="results"&&s.jsx(_.div,{initial:{opacity:0},animate:{opacity:1},exit:{opacity:0},transition:{duration:.3},children:s.jsx(Pae,{answers:o,userData:i})},"results")]}),u&&s.jsx(_.div,{initial:{opacity:0,y:50},animate:{opacity:1,y:0},exit:{opacity:0,y:50},className:"fixed bottom-8 right-8 bg-cyan-500/20 border border-cyan-400/50 rounded-xl px-6 py-3 backdrop-blur-sm",children:s.jsxs("div",{className:"flex items-center gap-3",children:[s.jsx("div",{className:"animate-spin rounded-full h-5 w-5 border-t-2 border-b-2 border-cyan-400"}),s.jsx("span",{className:"text-cyan-400 font-medium",children:t("quickAnalysis.results.savingResults")})]})})]})}const Lae="https://calendar.app.google/dkJfuj7MNARbfT5HA";function Oae(){const{t}=$(),{openModal:e}=oa(),a=()=>{window.open(Lae,"_blank","width=1000,height=700,noopener")};return s.jsxs("section",{className:"relative min-h-[600px] flex items-center justify-center bg-dark pt-20",children:[s.jsxs("div",{className:"container mx-auto px-4 py-12 text-center relative",children:[s.jsx(_.div,{initial:{opacity:0,y:-20},animate:{opacity:1,y:0},transition:{duration:.6},className:"inline-block mb-8",children:s.jsx("div",{className:"bg-cyan-500/10 border border-cyan-400/30 rounded-full px-6 py-2 backdrop-blur-sm",children:s.jsx("span",{className:"text-cyan-400 font-semibold text-sm tracking-wider uppercase",children:"Expertos en Calidad de Salesforce"})})}),s.jsxs(_.h1,{initial:{opacity:0,y:20},animate:{opacity:1,y:0},transition:{duration:.6,delay:.2},className:"text-4xl sm:text-4xl md:text-5xl lg:text-6xl font-bold mb-6 leading-tight",children:[s.jsx("span",{className:"text-white",children:"Somos especialistas en aseguramiento de calida
3863d"}),s.jsx("br",{}),s.jsx("span",{className:"text-primary",children:"de Salesforce"})]}),s.jsx(_.p,{initial:{opacity:0,y:20},animate:{opacity:1,y:0},transition:{duration:.6,delay:.4},className:"text-gray-300 text-lg md:text-xl max-w-3xl mx-auto mb-12 leading-relaxed",children:"Con nuestra metodología especializada en Salesforce aceleramos los tiempos de certificación de tus desarrollos"}),s.jsxs(_.div,{initial:{opacity:0,y:20},animate:{opacity:1,y:0},transition:{duration:.6,delay:.6},className:"flex flex-col sm:flex-row gap-4 justify-center items-center",children:[s.jsx("button",{id:"hero-salesforce-schedule-button",onClick:a,className:"bg-primary border-2 border-primary text-dark px-6 sm:px-8 md:px-10 py-3 sm:py-3 rounded-2xl text-base sm:text-lg font-semibold hover:bg-dark hover:text-primary transition-all duration-300","aria-label":"Agendar una cita",children:"Agendemos una Reunión"}),s.jsx(Te,{to:"/casosdeexito",children:s.jsx("button",{id:"hero-salesforce-cases-button",className:"border-2 border-primary/50 text-primary px-6 sm:px-8 md:px-10 py-3 sm:py-3 rounded-2xl text-base sm:text-lg font-semibold hover:bg-primary hover:text-dark transition-all duration-300",children:"Ver Casos de Éxito"})})]}),s.jsx(_.div,{initial:{opacity:0,scale:.8},animate:{opacity:1,scale:1},transition:{duration:.8,delay:.8},className:"animate-float-slow absolute bottom-8 right-4 md:right-10 lg:right-20 z-20",children:s.jsx("img",{src:"/imagenes/salesforce.png",alt:"Salesforce",className:"w-20 h-20 md:w-38 md:h-28 lg:w-38 lg:h-38 object-contain drop-shadow-[0_0_20px_rgba(6,182,212,0.5)]"})})]}),s.jsx(ie,{variant:1})]})}function Mae(){const{t}=$(),[e,a]=k.useState(0);k.useEffect(()=>{const i=setInterval(()=>{a(r=>(r+1)%3)},2e3);return()=>clearInterval(i)},[]);const n=[{id:1,icon:s.jsx("svg",{className:"w-12 h-12 text-primary flex-shrink-0",fill:"none",viewBox:"0 0 24 24",stroke:"currentColor",children:s.jsx("path",{strokeLinecap:"round",strokeLinejoin:"round",strokeWidth:2,d:"M13 10V3L4 14h7v7l9-11h-7z"})}),title:"Velocidad de Entrega",description:"70% de reducción del tiempo de las certificaciones de calidad.",color:"from-yellow-400 to-orange-500"},{id:2,icon:s.jsx("svg",{className:"w-12 h-12 text-primary flex-shrink-0",fill:"none",viewBox:"0 0 24 24",stroke:"currentColor",children:s.jsx("path",{strokeLinecap:"round",strokeLinejoin:"round",strokeWidth:2,d:"M9 12l2 2 4-4m6 2a9 9 0 11-18 0 9 9 0 0118 0z"})}),title:"QA Especializado",description:"Servicio de QA Automation especializado en desarrollo de proyectos Salesforce",color:"from-cyan-400 to-blue-500"},{id:3,icon:s.jsx("svg",{className:"w-12 h-12 text-primary flex-shrink-0",fill:"none",viewBox:"0 0 24 24",stroke:"currentColor",children:s.jsx("path",{strokeLinecap:"round",strokeLinejoin:"round",strokeWidth:2,d:"M12 8v4l3 3m6-3a9 9 0 11-18 0 9 9 0 0118 0z"})}),title:"Time To Market",description:"Disminución del Time To Market gracias a nuestra metodología de calidad continua.",color:"from-green-400 to-emerald-500"}];return s.jsxs("section",{className:"relative py-20 bg-dark mt-20",children:[s.jsx("div",{className:"container mx-auto px-4",children:s.jsx("div",{className:"grid grid-cols-1 md:grid-cols-3 gap-8 lg:gap-12",children:n.map((i,r)=>s.jsx(_.div,{initial:{opacity:0,y:30},whileInView:{opacity:1,y:0},viewport:{once:!0},transition:{duration:.6,delay:r*.2},className:"group",children:s.jsxs("div",{className:`relative h-full bg-[#1a1d3a]/50 backdrop-blur-sm rounded-2xl p-8 border transition-all duration-500 ${e===r?"border-cyan-400/50 shadow-xl shadow-cyan-400/10":"border-gray-700/50"}`,children:[s.jsx("div",{className:"mb-6",children:i.icon}),s.jsx("h3",{className:`text-2xl font-bold mb-4 transition-colors duration-500 ${e===r?"text-cyan-400":"text-white"}`,children:i.title}),s.jsx("p",{className:"text-gray-400 leading-relaxed",children:i.description}),s.jsx("div",{className:`absolute inset-0 rounded-2xl bg-gradient-to-br ${i.color} transition-opacity duration-500 pointer-events-none ${e===r?"opacity-5":"opacity-0"}`})]})},i.id))})}),s.jsx(ie,{variant:2})]})}const Dae="https://calendar.app.google/dkJfuj7MNARbfT5HA";function qae(){const{t}=$(),{openModal:e}=oa(),a=()=>{window.open(Dae,"_blank","width=1000,height=700,noopener")},n=["Evaluación de madurez digital","Implementación de mejoras para la calidad del producto","Testing continuo y regresiones","Métricas de valor para la mejora continua"];return s.jsxs("section",{className:"relative py-20 bg-dark",children:[s.jsx("div",{className:"container mx-auto px-4 mt-10",children:s.jsxs("div",{className:"grid grid-cols-1 lg:grid-cols-2 gap-12 items-center",children:[s.jsxs(_.div,{initial:{opacity:0,x:-30},whileInView:{opacity:1,x:0},viewport:{once:!0},transition:{duration:.6},children:[s.jsxs("div",{className:"inline-flex items-center gap-2 bg-cyan-500/10 border border-cyan-400/30 rounded-full px-4 py-2 mb-6",children:[s.jsx("svg",{className:"w-4 h-4 text-cyan-400",fill:"none",viewBox:"0 0 24 24",stroke:"currentColor",children:s.jsx("path",{strokeLinecap:"round",strokeLinejoin:"round",strokeWidth:2,d:"M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2m-6 9l2 2 4-4"})}),s.jsx("span",{className:"text-cyan-400 font-semibold text-sm tracking-wider up
3863percase",children:"Calidad y Reducción de Riesgos"})]}),s.jsxs("h2",{className:"text-4xl md:text-5xl font-bold mb-7 leading-tight",children:[s.jsx("span",{className:"text-white",children:"Acelera tu Time to Market"}),s.jsx("br",{}),s.jsx("span",{className:"text-primary",children:"con"}),s.jsx("br",{}),s.jsx("span",{className:"text-primary",children:"Testing Automatizado"})]}),s.jsx("p",{className:"text-gray-400 text-lg leading-relaxed mb-8",children:"Una implementación con pruebas deficientes es un riesgo latente. Nuestro servicio especializado detecta problemas antes de que afecten a tu negocio y asegura que cada flujo funcione correctamente."}),s.jsx("div",{className:"space-y-4 mb-8",children:n.map((i,r)=>s.jsxs(_.div,{initial:{opacity:0,x:-20},whileInView:{opacity:1,x:0},viewport:{once:!0},transition:{duration:.4,delay:r*.1},className:"flex items-center gap-3",children:[s.jsx("svg",{className:"w-6 h-6 text-primary flex-shrink-0",fill:"none",stroke:"currentColor",viewBox:"0 0 24 24",children:s.jsx("path",{strokeLinecap:"round",strokeLinejoin:"round",strokeWidth:2,d:"M5 13l4 4L19 7"})}),s.jsx("span",{className:"text-gray-300 text-lg",children:i})]},r))}),s.jsx("button",{id:"hero-salesforce-schedule-button",onClick:a,className:"bg-primary border-2 border-primary text-dark px-6 sm:px-8 md:px-10 py-3 sm:py-3 rounded-2xl text-base sm:text-lg font-semibold hover:bg-dark hover:text-primary transition-all duration-300","aria-label":"Agendar una cita",children:"Hablemos Sobre Calidad"})]}),s.jsxs(_.div,{initial:{opacity:0,x:30},whileInView:{opacity:1,x:0},viewport:{once:!0},transition:{duration:.6,delay:.2},className:"relative",children:[s.jsxs("div",{className:"relative bg-gradient-to-br from-[#1a1d3a] to-[#0a0e27] rounded-2xl border border-gray-700/50 shadow-2xl overflow-hidden",children:[s.jsxs("div",{className:"bg-[#2a2d4a] px-4 py-3 flex items-center gap-2 border-b border-gray-700/50",children:[s.jsxs("div",{className:"flex gap-2",children:[s.jsx("div",{className:"w-3 h-3 rounded-full bg-red-500"}),s.jsx("div",{className:"w-3 h-3 rounded-full bg-yellow-500"}),s.jsx("div",{className:"w-3 h-3 rounded-full bg-green-500"})]}),s.jsx("span",{className:"text-gray-400 text-sm ml-4",children:"Haka_Analysis_Report"})]}),s.jsxs("div",{className:"p-8 space-y-6",children:[s.jsxs("div",{className:"mb-6",children:[s.jsx("h3",{className:"text-white font-bold text-lg mb-1",children:"Haka Lab - Testing Report"}),s.jsx("p",{className:"text-gray-500 text-xs",children:"Salesforce Quality Analysis"})]}),s.jsxs("div",{className:"grid grid-cols-2 gap-4",children:[s.jsxs(_.div,{initial:{opacity:0,scale:.8},whileInView:{opacity:1,scale:1},viewport:{once:!0},transition:{duration:.5,delay:.4},className:"bg-[#2a2d4a]/50 rounded-lg p-4 border border-cyan-400/20",children:[s.jsxs("div",{className:"flex items-center gap-2 mb-2",children:[s.jsx("svg",{className:"w-4 h-4 text-cyan-400",fill:"none",viewBox:"0 0 24 24",stroke:"currentColor",children:s.jsx("path",{strokeLinecap:"round",strokeLinejoin:"round",strokeWidth:2,d:"M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2m-6 9l2 2 4-4"})}),s.jsx("span",{className:"text-gray-400 text-xs uppercase",children:"Tests"})]}),s.jsx(_.div,{initial:{opacity:0}
3863,whileInView:{opacity:1},viewport:{once:!0},transition:{duration:.5,delay:.6},className:"text-3xl font-bold text-cyan-400",children:"1,247"}),s.jsx("div",{className:"text-xs text-gray-500 mt-1",children:"Ejecutados"})]}),s.jsxs(_.div,{initial:{opacity:0,scale:.8},whileInView:{opacity:1,scale:1},viewport:{once:!0},transition:{duration:.5,delay:.5},className:"bg-[#2a2d4a]/50 rounded-lg p-4 border border-red-400/20",children:[s.jsxs("div",{className:"flex items-center gap-2 mb-2",children:[s.jsx("svg",{className:"w-4 h-4 text-red-400",fill:"none",viewBox:"0 0 24 24",stroke:"currentColor",children:s.jsx("path",{strokeLinecap:"round",strokeLinejoin:"round",strokeWidth:2,d:"M12 9v2m0 4h.01m-6.938 4h13.856c1.54 0 2.502-1.667 1.732-3L13.732 4c-.77-1.333-2.694-1.333-3.464 0L3.34 16c-.77 1.333.192 3 1.732 3z"})}),s.jsx("span",{className:"text-gray-400 text-xs uppercase",children:"Bugs"})]}),s.jsx(_.div,{initial:{opacity:0},whileInView:{opacity:1},viewport:{once:!0},transition:{duration:.5,delay:.7},className:"text-3xl font-bold text-red-400",children:"23"}),s.jsx("div",{className:"text-xs text-gray-500 mt-1",children:"Detectados"})]})]}),s.jsxs(_.div,{initial:{opacity:0,y:20},whileInView:{opacity:1,y:0},viewport:{once:!0},transition:{duration:.5,delay:.6},className:"bg-[#2a2d4a]/50 rounded-lg p-4 border border-green-400/20",children:[s.jsxs("div",{className:"flex items-center justify-between mb-3",children:[s.jsxs("div",{className:"flex items-center gap-2",children:[s.jsx("svg",{className:"w-4 h-4 text-green-400",fill:"none",viewBox:"0 0 24 24",stroke:"currentColor",children:s.jsx("path",{strokeLinecap:"round",strokeLinejoin:"round",strokeWidth:2,d:"M9 12l2 2 4-4m6 2a9 9 0 11-18 0 9 9 0 0118 0z"})}),s.jsx("span",{className:"text-gray-400 text-xs uppercase",children:"Cobertura"})]}),s.jsx(_.span,{initial:{scale:0},whileInView:{scale:1},viewport:{once:!0},transition:{duration:.5,delay:.8,type:"spring"},className:"text-2xl font-bold text-green-400",children:"92%"})]}),s.jsx("div",{className:"w-full bg-gray-700 rounded-full h-2",children:s.jsx(_.div,{initial:{width:0},whileInView:{width:"92%"},viewport:{once:!0},transition:{duration:1,delay:.9},className:"bg-gradient-to-r from-green-400 to-emerald-500 h-2 rounded-full"})})]}),s.jsxs(_.div,{initial:{opacity:0,y:20},whileInView:{opacity:1,y:0},viewport:{once:!0},transition:{duration:.5,delay:.7},className:"bg-[#2a2d4a]/50 rounded-lg p-4 border border-purple-400/20",children:[s.jsxs("div",{className:"flex items-center gap-2 mb-4",children:[s.jsx("svg",{className:"w-4 h-4 text-purple-400",fill:"none",viewBox:"0 0 24 24",stroke:"currentColor",children:s.jsx("path",{strokeLinecap:"round",strokeLinejoin:"round",strokeWidth:2,d:"M12 9v2m0 4h.01m-6.938 4h13.856c1.54 0 2.502-1.667 1.732-3L13.732 4c-.77-1.333-2.694-1.333-3.464 0L3.34 16c-.77 1.333.192 3 1.732 3z"})}),s.jsx("span",{className:"text-gray-400 text-xs uppercase",children:"Bugs por Criticidad"})]}),s.jsxs("div",{className:"flex items-end justify-between gap-3 h-24 mb-2",children:[s.jsx("div",{className:"flex-1 flex flex-col items-center justify-end h-full",children:s.jsx(_.div,{initial:{scaleY:0},whileInView:{scaleY:1},viewport:{once:!0},transition:{duration:.8,delay:.9},style:{originY:1},className:"w-full h-[50%] bg-gradient-to-t from-red-500 to-red-400 rounded-t-md"})}),s.jsx("div",{className:"flex-1 flex flex-col items-center justify-end h-full",children:s.jsx(_.div,{initial:{scaleY:0},whileInView:{scaleY:1},viewport:{once:!0},transition:{duration:.8,delay:1},style:{originY:1},className:"w-full h-[40%] bg-gradient-to-t from-yellow-500 to-yellow-400 rounded-t-md"})}),s.jsx("div",{className:"flex-1 flex flex-col items-center justify-end h-full",children:s.jsx(_.div,{initial:{scaleY:0},whileInView:{scaleY:1},viewport:{once:!0},transition:{duration:.8,delay:1.1},style:{originY:1},className:"w-full h-[80%] bg-gradient-to-t from-green-500 to-green-400 rounded-t-md"})})]}),s.jsxs("div",{className:"flex items-center justify-between gap-3",children:[s.jsx("span",{className:"flex-1 text-center text-[10px] text-red-400 font-semibold",children:"Alta"}),s.jsx("span",{className:"flex-1 text-center text-[10px] text-yellow-400 font-semibold",children:"Media"}),s.jsx("span",{className:"flex-1 text-center text-[10px] text-green-400 font-semibold",children:"Baja"})]})]}),s.jsxs(_.div,{initial:{opacity:0}
3863,whileInView:{opacity:1},viewport:{once:!0},transition:{duration:.5,delay:1.2},className:"flex items-center justify-center gap-2 pt-2",children:[s.jsx("div",{className:"w-2 h-2 rounded-full bg-green-400 animate-pulse"}),s.jsx("span",{className:"text-xs text-gray-400",children:"All Systems Operational"})]})]}),s.jsx("div",{className:"absolute inset-0 bg-gradient-to-tr from-cyan-500/5 to-purple-500/5 pointer-events-none"})]}),s.jsx(_.div,{animate:{y:[0,-10,0]},transition:{duration:3,repeat:1/0,ease:"easeInOut"},className:"absolute -top-4 -right-4 w-24 h-24 bg-gradient-to-br from-cyan-400 to-blue-500 rounded-full blur-2xl opacity-30"}),s.jsx(_.div,{animate:{y:[0,10,0]},transition:{duration:4,repeat:1/0,ease:"easeInOut",delay:1},className:"absolute -bottom-4 -left-4 w-32 h-32 bg-gradient-to-br from-purple-400 to-pink-500 rounded-full blur-2xl opacity-30"})]})]})}),s.jsx(ie,{variant:1})]})}function zae(){const{t}=$(),e=[{id:1,icon:s.jsx("svg",{className:"w-10 h-10 text-primary flex-shrink-0",fill:"none",viewBox:"0 0 24 24",stroke:"currentColor",children:s.jsx("path",{strokeLinecap:"round",strokeLinejoin:"round",strokeWidth:2,d:"M13 7h8m0 0v8m0-8l-8 8-4-4-6 6"})}),title:"Maximización del ROI",description:"Transformamos tu inversión de QA en ganancias tangibles al reducir el time to market, minimizar errores productivos y mejorar la experiencia del usuario final.",color:"from-cyan-400 to-blue-500"},{id:2,icon:s.jsx("svg",{className:"w-10 h-10 text-primary flex-shrink-0",fill:"none",viewBox:"0 0 24 24",stroke:"currentColor",children:s.jsx("path",{strokeLinecap:"round",strokeLinejoin:"round",strokeWidth:2,d:"M9 12l2 2 4-4m5.618-4.016A11.955 11.955 0 0112 2.944a11.955 11.955 0 01-8.618 3.04A12.02 12.02 0 003 9c0 5.591 3.824 10.29 9 11.622 5.176-1.332 9-6.03 9-11.622 0-1.042-.133-2.052-.382-3.016z"})}),title:"Eficiencia en Costos Operativos",description:"Eliminamos los altos costos asociados a la manualidad de los procesos de certificación. Menos horas hombre dedicadas a tareas repetitivas se traducen en un menor costo de delivery para tu empresa.",color:"from-purple-400 to-pink-500"},{id:3,icon:s.jsx("svg",{className:"w-10 h-10 text-primary flex-shrink-0",fill:"none",viewBox:"0 0 24 24",stroke:"currentColor",children:s.jsx("path",{strokeLinecap:"round",strokeLinejoin:"round",strokeWidth:2,d:"M13 10V3L4 14h7v7l9-11h-7z"})}),title:"Reducción de Time-to-Market",description:"Optimizamos tus ciclos de entrega con una reducción del 70% en el tiempo de certificaciones regresivas. Aceleramos el despliegue de nuevos releases para que tu negocio nunca se detenga.",color:"from-pink-400 to-red-500"},{id:4,icon:s.jsx("svg",{className:"w-10 h-10 text-primary flex-shrink-0",fill:"none",viewBox:"0 0 24 24",stroke:"currentColor",children:s.jsx("path",{strokeLinecap:"round",strokeLinejoin:"round",strokeWidth:2,d:"M3.055 11H5a2 2 0 012 2v1a2 2 0 002 2 2 2 0 012 2v2.945M8 3.935V5.5A2.5 2.5 0 0010.5 8h.5a2 2 0 012 2 2 2 0 104 0 2 2 0 012-2h1.064M15 20.488V18a2 2 0 012-2h3.064M21 12a9 9 0 11-18 0 9 9 0 0118 0z"})}),title:"Testing E2E e Integraciones",description:"Garantizamos la integridad de tus flujos de principio a fin, validando integraciones críticas con sistemas legados. Aseguramos que Salesforce se comunique perfectamente con todo tu ecosistema digital.",color:"from-blue-400 to-indigo-500"},{id:5,icon:s.jsx("svg",{className:"w-10 h-10 text-primary flex-shrink-0",fill:"none",viewBox:"0 0 24 24",stroke:"currentColor",children:s.jsx("path",{strokeLinecap:"round",strokeLinejoin:"round",strokeWidth:2,d:"M9 19v-6a2 2 0 00-2-2H5a2 2 0 00-2 2v6a2 2 0 002 2h2a2 2 0 002-2zm0 0V9a2 2 0 012-2h2a2 2 0 012 2v10m-6 0a2 2 0 002 2h2a2 2 0 002-2m0 0V5a2 2 0 012-2h2a2 2 0 012 2v14a2 2 0 01-2 2h-2a2 2 0 01-2-2z"})}),title:"Automatización de Alta Cobertura",description:"Ampliamos radicalmente tu capacidad de prueba; hemos logrado pasar de 674 a más de 5,600 casos automatizados. Cubrimos múltiples combinatorias y escenarios con componentes altamente reutilizables.",color:"from-cyan-400 to-teal-500"},{id:6,icon:s.jsx("svg",{className:"w-10 h-10 text-primary flex-shrink-0",fill:"none",viewBox:"0 0 24 24",stroke:"currentColor",children:s.jsx("path",{strokeLinecap:"round",strokeLinejoin:"round",strokeWidth:2,d:"M4 4v5h.582m15.356 2A8.001 8.001 0 004.582 9m0 0H9m11 11v-5h-.581m0 0a8.003 8.003 0 01-15.357-2m15.357 2H15"})}),title:"Mejora Continua",description:"No solo entregamos; iteramos. Utilizamos las métricas de QA para implementar mejoras continuas en los equipos de desarrollo.",color:"from-green-400 to-emerald-500"}];return s.jsxs("section",{className:"relative py-20 bg-dark",children:[s.jsxs("div",{className:"container mx-auto px-4 mt-10 pt-10",children:[s.jsxs(_.div,{initial:{opacity:0,y:20},whileInView:{opacity:1,y:0},viewport:{once:!0},transition:{duration:.6},className:"text-center mb-16",children:[s.jsx("p",{className:"text-cyan-400 font-semibold text-lg tracking-wider up
3863percase mb-4",children:"¿Por qué nosotros?"}),s.jsx("h2",{className:"text-4xl md:text-5xl font-bold text-white mb-4",children:"Beneficios Clave"}),s.jsx("p",{className:"text-gray-400 text-lg max-w-3xl mx-auto",children:"Hemos diseñado e implementado exitosamente en multiples clientes nuestro servicio especializado en testing eficiente de Salesforce."})]}),s.jsx("div",{className:"grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-6",children:e.map((a,n)=>s.jsx(_.div,{initial:{opacity:0,y:30},whileInView:{opacity:1,y:0},viewport:{once:!0},transition:{duration:.5,delay:n*.1},className:"group",children:s.jsxs("div",{className:"relative h-full bg-[#1a1d3a]/30 backdrop-blur-sm rounded-2xl p-6 border border-gray-700/50 hover:border-cyan-400/50 transition-all duration-300 hover:shadow-xl hover:shadow-cyan-400/10",children:[s.jsx("div",{className:"mb-4",children:a.icon}),s.jsx("h3",{className:"text-xl font-bold text-cyan-400 mb-3 group-hover:text-cyan-400 transition-colors duration-300",children:a.title}),s.jsx("p",{className:"text-gray-200 leading-relaxed text-md",children:a.description}),s.jsx("div",{className:`absolute inset-0 rounded-2xl bg-gradient-to-br ${a.color} opacity-0 group-hover:opacity-5 transition-opacity duration-300 pointer-events-none`})]})},a.id))}),s.jsx(_.div,{initial:{opacity:0,scale:.8},whileInView:{opacity:1,scale:1},viewport:{once:!0},transition:{duration:.8,delay:.3},className:"flex justify-center my-16",children:s.jsx("div",{className:"animate-float-slow",children:s.jsx("img",{src:"/imagenes/salesforce.png",alt:"Salesforce",className:"w-24 h-24 md:w-32 md:h-32 lg:w-40 lg:h-40 object-contain drop-shadow-[0_0_25px_rgba(6,182,212,0.6)]"})})}),s.jsx(Vae,{}),s.jsx(Hae,{})]}),s.jsx(ie,{variant:2})]})}function Vae(){const[t,e]=k.useState(0),a=[{title:"Análisis",description:"Integramos la visión de calidad desde la etapa de planificación"},{title:"Diseño",description:"Creamos una estrategia de testing adaptada al negocio"},{title:"Implementación",description:"Desarrollamos y ejecutamos las pruebas automatizadas"},{title:"Optimización",description:"Mejoramos continuamente basados en métricas"}];return k.useEffect(()=>{const n=setInterval(()=>{e(i=>(i+1)%a.length)},3e3);return()=>clearInterval(n)},[a.length]),s.jsxs("div",{className:"mt-20 pt-0",children:[s.jsx(_.div,{initial:{opacity:0,y:20},whileInView:{opacity:1,y:0},viewport:{once:!0},transition:{duration:.6},className:"text-center mb-16",children:s.jsx("p",{className:"text-gray-100 text-lg mt-6 max-w-4xl mx-auto",children:"Un enfoque estructurado y probado para garantizar la calidad de tu implementación Salesforce desde las etapas iniciales del ciclo de vida de desarrollo"})}),s.jsxs("div",{className:"relative max-w-5xl mx-auto",children:[s.jsx("div",{className:"absolute top-8 left-0 right-0 h-1 bg-gray-700",children:s.jsx(_.div,{className:"h-full bg-primary",initial:{width:"0%"},animate:{width:`${t/(a.length-1)*100}%`},transition:{duration:.8,ease:"easeInOut"}})}),s.jsx(_.div,{className:"absolute top-4 w-8 h-8 bg-primary rounded-full shadow-lg shadow-primary/50 z-20",animate:{left:`${t/(a.length-1)*100}%`,x:"-50%"},transition:{duration:.8,ease:"easeInOut"},children:s.jsx("div",{className:"absolute inset-0 rounded-full bg-primary animate-ping opacity-75"})}),s.jsx("div",{className:"relative grid grid-cols-2 md:grid-cols-4 gap-3 sm:gap-4 pt-20",children:a.map((n,i)=>s.jsxs(_.div,{initial:{opacity:0,y:20},whileInView:{opacity:1,y:0},viewport:{once:!0},transition:{duration:.5,delay:i*.1},className:"flex flex-col items-center text-center",children:[s.jsxs(_.div,{animate:{rotate:t>=i?360:0,scale:t===i?1.2:1},transition:{duration:.6},className:"mb-3 sm:mb-4 relative",children:[s.jsx("div",{className:`absolute inset-0 rounded-full blur-lg transition-opacity duration-500 ${t>=i?"opacity-100":"opacity-0"}`,style:{background:"radial-gradient(circle, #06b6d4 0%, transparent 10%)",width:"100%",height:"100%"}}),s.jsx("svg",{className:`w-8 sm:w-10 md:w-12 h-8 sm:h-10 md:h-12 transition-all duration-500 relative z-10 ${t>=i?"text-cyan-400 drop-shadow-lg":"text-gray-600"}`,style:{filter:t>=i?"drop-shadow(0 0 8px #06b6d4) drop-shadow(0 0 16px rgba(6, 182, 212, 0.5))":"none",textShadow:t>=i?"0 0 10px #06b6d4":"none"},fill:"currentColor",viewBox:"0 0 20 20",children:s.jsx("path",{d:"M9.049 2.927c.3-.921 1.603-.921 1.902 0l1.07 3.292a1 1 0 00.95.69h3.462c.969 0 1.371 1.24.588 1.81l-2.8 2.034a1 1 0 00-.364 1.118l1.07 3.292c.3.921-.755 1.688-1.54 1.118l-2.8-2.034a1 1 0 00-1.175 0l-2.8 2.034c-.784.57-1.838-.197-1.539-1.118l1.07-3.292a1 1 0 00-.364-1.118L2.98 8.72c-.783-.57-.38-1.81.588-1.81h3.461a1 1 0 00.951-.69l1.07-3.292z"})})]}
3863),s.jsxs(_.div,{animate:{opacity:t>=i?1:.5,scale:t===i?1.05:1},transition:{duration:.3},className:`p-3 sm:p-4 rounded-lg border transition-all ${t>=i?"border-primary/30 bg-primary/5":"border-gray-700 bg-gray-800/30"}`,children:[s.jsx("h3",{className:`font-bold mb-1 sm:mb-2 text-xs sm:text-sm lg:text-base ${t>=i?"text-primary":"text-gray-400"}`,children:n.title}),s.jsx("p",{className:"text-[10px] sm:text-xs lg:text-sm text-gray-100",children:n.description})]})]},`step-${i}`))})]})]})}function Hae(){const t={logos:[{id:1,image:"/imagenes/home/logo_abastible.png",alt:"Abastible"},{id:4,image:"/imagenes/home/logo_falabella.png",alt:"Falabella"},{id:5,image:"/imagenes/home/logo_casaideas.png",alt:"Casa Ideas"},{id:7,image:"/imagenes/home/log_bupa.png",alt:"Bupa"},{id:9,image:"/imagenes/home/logo_colmena.png",alt:"Colmena"},{id:10,image:"/imagenes/home/logo_consorcio.png",alt:"Consorcio"},{id:11,image:"/imagenes/home/logo_continuum.png",alt:"Continuum"},{id:14,image:"/imagenes/home/logo_scotiabank.png",alt:"Scotiabank"},{id:15,image:"/imagenes/home/logo_security.png",alt:"Security"},{id:17,image:"/imagenes/home/logo_vida_security.png",alt:"Vida Security"},{id:18,image:"/imagenes/home/logo_sodimac.png",alt:"Sodimac"}]},[e,a]=k.useState(0),n=4;k.useEffect(()=>{const r=setInterval(()=>{a(o=>{const l=o+n;return l>=t.logos.length?0:l})},3e3);return()=>clearInterval(r)},[t.logos.length]);const i=t.logos.slice(e,e+n);return s.jsxs("div",{className:"mt-20 pt-10",children:[s.jsxs(_.div,{initial:{opacity:0,y:20},whileInView:{opacity:1,y:0},viewport:{once:!0},transition:{duration:.8},className:"text-center mb-12",children:[s.jsx("h3",{className:"text-3xl md:text-3xl font-bold text-white mb-2",children:"Clientes que Confían su Calidad Salesforce en Nosotros"}),s.jsx("div",{className:"h-2 w-20 bg-cyan-400 mt-4 mx-auto"})]}),s.jsxs("div",{className:"relative",children:[s.jsx(La,{mode:"wait",children:s.jsx(_.div,{initial:{opacity:0}
3863,animate:{opacity:1},exit:{opacity:0},transition:{duration:1.2,ease:"easeInOut"},className:"grid grid-cols-2 md:grid-cols-4 gap-8 lg:gap-12",children:i.map((r,o)=>s.jsx(_.div,{initial:{opacity:0,y:20,scale:.96},animate:{opacity:1,y:0,scale:1},transition:{type:"spring",stiffness:120,damping:22,delay:o*.1},whileHover:{scale:1.03},className:"flex items-center justify-center p-6 rounded-xl bg-slate-800/30 border border-primary/10 hover:border-primary/30 group",children:s.jsx("div",{className:"relative w-full h-20 flex items-center justify-center",children:s.jsx("img",{src:r.image,alt:r.alt,loading:"lazy",decoding:"async",width:"250",height:"150",className:"max-w-full max-h-full object-contain transition-all duration-300 opacity-90 group-hover:opacity-100 group-hover:scale-110"})})},r.id))},e)}),s.jsx("div",{className:"flex justify-center gap-2 mt-8",children:Array.from({length:Math.ceil(t.logos.length/n)}).map((r,o)=>s.jsx("button",{onClick:()=>a(o*n),className:`h-2 rounded-full transition-all duration-300 ${Math.floor(e/n)===o?"w-8 bg-primary":"w-2 bg-gray-600 hover:bg-gray-500"}`,"aria-label":`Ir al grupo ${o+1}`},o))})]})]})}const Fae="https://calendar.app.google/dkJfuj7MNARbfT5HA";function Bae(){const{t}=$(),{openModal:e}=oa(),a=()=>{window.open(Fae,"_blank","width=1000,height=700,noopener")};return s.jsxs("section",{className:"relative py-32 bg-dark",children:[s.jsxs("div",{className:"container mx-auto px-4 text-center pt-5",children:[s.jsxs(_.h2,{initial:{opacity:0,y:20},whileInView:{opacity:1,y:0},viewport:{once:!0},transition:{duration:.6},className:"text-4xl md:text-5xl lg:text-6xl font-bold mb-6 leading-tight",children:[s.jsx("span",{className:"text-white",children:"¿Listo para escalar tu"}),s.jsx("br",{}),s.jsx("span",{className:"text-primary",children:"Estrategia de Calidad?"})]}),s.jsx(_.p,{initial:{opacity:0,y:20},whileInView:{opacity:1,y:0},viewport:{once:!0},transition:{duration:.6,delay:.2},className:"text-gray-300 text-lg md:text-xl max-w-3xl mx-auto mb-12 leading-relaxed",children:"Agenda una reunión y permitenos mostrate como llevar tu estrategia de calidad en Salesforce al siguiente nivel."}),s.jsx("button",{id:"hero-salesforce-schedule-button",onClick:a,className:"bg-primary border-2 border-primary text-dark px-6 sm:px-8 md:px-10 py-3 sm:py-3 rounded-2xl text-base sm:text-lg font-semibold hover:bg-dark hover:text-primary transition-all duration-300","aria-label":"Agendar una cita",children:"Hablemos Sobre Calidad"}),s.jsx(_.div,{animate:{y:[0,-20,0],opacity:[.3,.6,.3]},transition:{duration:4,repeat:1/0,ease:"easeInOut"},className:"absolute top-1/4 left-1/4 w-2 h-2 bg-cyan-400 rounded-full blur-sm"}),s.jsx(_.div,{animate:{y:[0,-30,0],opacity:[.3,.6,.3]},transition:{duration:5,repeat:1/0,ease:"easeInOut",delay:1},className:"absolute top-1/3 right-1/3 w-3 h-3 bg-purple-400 rounded-full blur-sm"}),s.jsx(_.div,{animate:{y:[0,-25,0],opacity:[.3,.6,.3]},transition:{duration:4.5,repeat:1/0,ease:"easeInOut",delay:2},className:"absolute bottom-1/4 right-1/4 w-2 h-2 bg-blue-400 rounded-full blur-sm"})]}),s.jsx(ie,{variant:1})]})}function Uae(){const{t}=$();return Mg({title:"Salesforce Testing - HakaLab",description:"Servicios especializados de testing para Salesforce. Transformamos tu CRM en un motor de crecimiento.",keywords:"salesforce, testing, qa, automation, crm, salesforce partners, salesforce experts"}),s.jsxs("div",{className:"min-h-screen bg-dark",children:[s.jsx(Oae,{}),s.jsx(Mae,{}),s.jsx(qae,{}),s.jsx(zae,{}),s.jsx(Bae,{})]})}function $ae(){const{t}=$(),e=t("hakaAutomationEngine.hero",{returnObjects:!0}),{openModal:a}=oa();return s.jsxs("section",{className:"relative bg-dark",children:[s.jsxs("div",{className:"relative py-12 sm:py-16 md:py-20 flex items-center justify-center overflow-hidden min-h-[500px] sm:min-h-[600px]",children:[s.jsx("div",{className:"absolute inset-0 bg-gradient-to-br from-dark via-dark to-dark"}),s.jsx("div",{className:"hero-glow"}),s.jsx("div",{className:"relative z-10 max-w-7xl mx-auto px-4 sm:px-6 md:px-8 w-full",children:s.jsxs("div",{className:"text-center",children:[s.jsx(Lg,{text:e.badge}),s.jsx("h1",{className:"text-5xl md:text-7xl font-extrabold tracking-tight text-white mt-6",children:e.title}),s.jsx("h2",{className:"text-4xl md:text-5xl font-extrabold text-primary italic mt-4",children:e.titleHighlight}),s.jsx("p",{className:"text-xl text-gray-300 font-normal max-w-3xl mx-auto leading-relaxed mt-10",children:e.subt
3863itle}),s.jsx("div",{className:"flex flex-col sm:flex-row justify-center gap-4 mt-14",children:s.jsx("button",{onClick:()=>a(e.ctaContact),className:"bg-primary border-2 border-primary text-dark px-10 py-3 rounded-2xl text-lg font-semibold hover:bg-dark hover:text-primary transition-all duration-300",children:e.ctaContact})})]})})]}),s.jsx(ie,{variant:1})]})}function Wae(){const{t}=$(),e=t("hakaAutomationEngine.diagram",{returnObjects:!0}),[a,n]=k.useState(0);k.useEffect(()=>{const r=setInterval(()=>{n(o=>(o+1)%5)},2e3);return()=>clearInterval(r)},[]);const i=[{id:1,title:e.layer1.title,description:e.layer1.description,icons:["/imagenes/framework/Selenium_Logo.png","/imagenes/framework/playwright.png","/imagenes/framework/cucumber.png"],color:"from-orange-500/20 to-orange-500/5"},{id:2,title:e.layer2.title,description:e.layer2.description,icons:["/imagenes/framework/front.png","/imagenes/framework/apirest.png","/imagenes/framework/bbdd.png"],color:"from-green-500/20 to-green-500/5"},{id:3,title:e.layer3.title,description:e.layer3.description,icons:["/imagenes/framework/jira-3.svg","/imagenes/framework/Logo-Xray.png","/imagenes/framework/Grafana_icon.svg.png"],color:"from-purple-500/20 to-purple-500/5"},{id:4,title:e.layer4.title,description:e.layer4.description,icons:["/imagenes/framework/html.png","/imagenes/framework/video.png"],color:"from-blue-500/20 to-blue-500/5"},{id:5,title:e.layer5.title,description:e.layer5.description,icons:["/imagenes/framework/Jenkins_logo.svg.png","/imagenes/framework/github.png","/imagenes/framework/docker.png"],color:"from-primary/20 to-primary/5"}];return s.jsxs("section",{className:"relative bg-dark py-20 pt-14 mt-24",children:[s.jsxs("div",{className:"max-w-7xl mx-auto px-4 sm:px-6 md:px-8",children:[s.jsxs("div",{className:"text-center mb-16",children:[s.jsx("h2",{className:"text-4xl md:text-5xl font-bold text-white mb-4",children:e.title}),s.jsx("p",{className:"text-xl text-gray-400 max-w-3xl mx-auto",children:e.subt
3863itle})]}),s.jsxs("div",{className:"relative max-w-5xl mx-auto",children:[s.jsxs("div",{className:"absolute left-8 top-0 bottom-0 w-1 hidden md:block",children:[s.jsx("div",{className:"absolute inset-0 bg-gray-800/30"}),s.jsx(_.div,{initial:{height:0},whileInView:{height:"100%"},transition:{duration:i.length*.3,ease:"linear"},viewport:{once:!0},className:"absolute top-0 left-0 w-full bg-gradient-to-b from-primary via-primary to-primary"})]}),i.map((r,o)=>s.jsxs(_.div,{initial:{opacity:0,x:-50},whileInView:{opacity:1,x:0},transition:{duration:.5,delay:o*.3},viewport:{once:!0},className:"relative mb-8 md:ml-16",children:[s.jsx(_.div,{initial:{width:1},whileInView:{width:"2.4rem"},transition:{duration:.4,delay:o*.3+.2},viewport:{once:!0},className:`absolute top-16 h-0.5 ${o===a?"bg-gradient-to-r from-cyan-400 to-cyan-400/50 shadow-lg shadow-cyan-400/50":"bg-gradient-to-r from-primary to-transparent"} hidden md:block transition-all duration-500`,style:{left:"-2rem"}}),s.jsx("div",{className:`bg-gradient-to-r ${r.color} border ${o===a?"border-cyan-400 shadow-lg shadow-cyan-400/50":"border-gray-800"} rounded-2xl p-6 md:p-8 backdrop-blur-sm transition-all duration-500`,children:s.jsxs("div",{className:"flex flex-col md:flex-row items-center gap-6",children:[s.jsx("div",{className:`flex-shrink-0 w-16 h-16 rounded-full ${o===a?"bg-cyan-400 text-dark shadow-lg shadow-cyan-400/50":"bg-gray-800 text-primary"} flex items-center justify-center text-2xl font-bold transition-all duration-500`,children:r.id}),s.jsxs("div",{className:"flex-grow text-center md:text-left",children:[s.jsx("h3",{className:"text-2xl font-bold text-white mb-2",children:r.title}),s.jsx("p",{className:"text-gray-200",children:r.description})]}),s.jsx("div",{className:"flex gap-4 flex-shrink-0",children:r.icons.map((l,c)=>s.jsx(_.div,{initial:{scale:0,rotate:-180},whileInView:{scale:1,rotate:0},transition:{duration:.5,delay:o*.3+.4+c*.1},viewport:{once:!0},whileHover:{scale:1.1,rotate:5},className:"w-14 h-14 bg-dark/50 rounded-lg p-2 flex items-center justify-center",children:s.jsx("img",{src:l,alt:"",className:"w-full h-full object-contain"})},c))})]})})]},r.id))]}),s.jsxs(_.div,{initial:{opacity:0,scale:.9},whileInView:{opacity:1,scale:1},transition:{duration:.5},viewport:{once:!0},className:"mt-24 bg-gradient-to-r from-primary/10 to-transparent border border-primary/30 rounded-2xl p-8 relative",children:[s.jsxs(_.div,{initial:{scale:0,rotate:-180},whileInView:{scale:1,rotate:0},transition:{duration:.6,delay:.3},viewport:{once:!0},className:"absolute -top-6 -right-6 w-12 h-12 bg-gradient-to-br from-cyan-400 to-blue-500 rounded-full flex items-center justify-center shadow-lg shadow-cyan-400/50",children:[s.jsx("svg",{className:"w-6 h-6",viewBox:"0 0 24 24",fill:"none",xmlns:"http://www.w3.org/2000/svg",children:s.jsx("path",{d:"M13 2L3 14H12L11 22L21 10H12L13 2Z",fill:"#0a0a0a",stroke:"#0a0a0a",strokeWidth:"1",strokeLinecap:"round",strokeLinejoin:"round"})}),s.jsx("div",{className:"absolute inset-0 rounded-full bg-cyan-400 animate-ping opacity-30"})]}),s.jsxs("div",{className:"flex flex-wrap justify-center items-start gap-6 md:gap-8 mb-6",children:[s.jsx(_.img,{initial:{opacity:0,y:20},whileInView:{opacity:1,y:0},transition:{duration:.5,delay:.2},viewport:{once:!0},src:"/imagenes/productos/hakaboost_logo.png",alt:"Hakaboost",className:"h-9 object-contain object-top"}),s.jsx(_.img,{initial:{opacity:0,y:20},whileInView:{opacity:1,y:0},transition:{duration:.5,delay:.3},viewport:{once:!0},src:"/imagenes/productos/hakabuddy_logo2.png",alt:"Hakabuddy",className:"h-10 object-contain object-top"}),s.jsx(_.img,{initial:{opacity:0,y:20},whileInView:{opacity:1,y:0},transition:{duration:.5,delay:.4},viewport:{once:!0},src:"/imagenes/productos/hakapath_logo.png",alt:"Hakapath",className:"h-10 object-contain object-top"}),s.jsx(_.img,{initial:{opacity:0,y:20},whileInView:{opacity:1,y:0},transition:{duration:.5,delay:.5},viewport:{once:!0},src:"/imagenes/productos/hakartc_logo.png",alt:"Hakartc",className:"h-10 object-contain object-top"})]}),s.jsx("p",{className:"text-xl text-white text-center",children:e.note})]})]}),s.jsx(ie,{variant:2})]})}function Gae(){const{t}=$(),e=t("hakaAutomationEngine.aiTesting",{returnObjects:!0}),a=[{icon:s.jsxs("svg",{className:"w-12 h-12",viewBox:"0 0 24 24",fill:"none",xmlns:"http://www.w3.org/2000/svg",children:[s.jsx("circle",{cx:"12",cy:"8",r:"3",fill:"#22d3ee",opacity:"0.2"}),s.jsx("circle",{cx:"12",cy:"8",r:"3",stroke:"#22d3ee",strokeWidth:"2"}),s.jsx("path",{d:"M6 21C6 17.134 8.686 14 12 14C15.314 14 18 17.134 18 21",stroke:"#22d3ee",strokeWidth:"2",strokeLinecap:"round"}),s.jsx("path",{d:"M9 8L10 9L12 7",stroke:"#0a0a0a",strokeWidth:"1.5",strokeLinecap:"round",strokeLinejoin:"round"}),s.jsx("circle",{cx:"18",cy:"6",r:"2",fill:"#22d3ee"}),s.jsx("circle",{cx:"6",cy:"6",r:"2",fill:"#22d3ee"})]}
3863),title:e.features.genAI.title,description:e.features.genAI.description},{icon:s.jsxs("svg",{className:"w-12 h-12",viewBox:"0 0 24 24",fill:"none",xmlns:"http://www.w3.org/2000/svg",children:[s.jsx("path",{d:"M12 2L15.09 8.26L22 9.27L17 14.14L18.18 21.02L12 17.77L5.82 21.02L7 14.14L2 9.27L8.91 8.26L12 2Z",fill:"#22d3ee",opacity:"0.2"}),s.jsx("path",{d:"M12 2L15.09 8.26L22 9.27L17 14.14L18.18 21.02L12 17.77L5.82 21.02L7 14.14L2 9.27L8.91 8.26L12 2Z",stroke:"#22d3ee",strokeWidth:"2",strokeLinejoin:"round"}),s.jsx("circle",{cx:"12",cy:"12",r:"3",fill:"#22d3ee"})]}),title:e.features.semantic.title,description:e.features.semantic.description},{icon:s.jsxs("svg",{className:"w-12 h-12",viewBox:"0 0 24 24",fill:"none",xmlns:"http://www.w3.org/2000/svg",children:[s.jsx("rect",{x:"4",y:"4",width:"6",height:"6",rx:"1",fill:"#22d3ee",opacity:"0.2"}),s.jsx("rect",{x:"4",y:"4",width:"6",height:"6",rx:"1",stroke:"#22d3ee",strokeWidth:"2"}),s.jsx("rect",{x:"14",y:"4",width:"6",height:"6",rx:"1",fill:"#22d3ee",opacity:"0.2"}),s.jsx("rect",{x:"14",y:"4",width:"6",height:"6",rx:"1",stroke:"#22d3ee",strokeWidth:"2"}),s.jsx("rect",{x:"4",y:"14",width:"6",height:"6",rx:"1",fill:"#22d3ee",opacity:"0.2"}),s.jsx("rect",{x:"4",y:"14",width:"6",height:"6",rx:"1",stroke:"#22d3ee",strokeWidth:"2"}),s.jsx("rect",{x:"14",y:"14",width:"6",height:"6",rx:"1",fill:"#22d3ee"}),s.jsx("path",{d:"M16 17L17 18L19 16",stroke:"#0a0a0a",strokeWidth:"1.5",strokeLinecap:"round",strokeLinejoin:"round"})]}),title:e.features.rag.title,description:e.features.rag.description},{icon:s.jsxs("svg",{className:"w-12 h-12",viewBox:"0 0 24 24",fill:"none",xmlns:"http://www.w3.org/2000/svg",children:[s.jsx("rect",{x:"3",y:"3",width:"18",height:"18",rx:"2",fill:"#22d3ee",opacity:"0.2"}),s.jsx("rect",{x:"3",y:"3",width:"18",height:"18",rx:"2",stroke:"#22d3ee",strokeWidth:"2"}),s.jsx("path",{d:"M8 12L11 15L16 9",stroke:"#22d3ee",strokeWidth:"2.5",strokeLinecap:"round",strokeLinejoin:"round"})]}),title:e.features.validation.title,description:e.features.validation.description}];return s.jsxs("section",{className:"relative bg-dark py-12 mt-16",children:[s.jsxs("div",{className:"max-w-7xl mx-auto px-4 sm:px-6 md:px-8",children:[s.jsxs("div",{className:"grid lg:grid-cols-2 gap-12 items-center",children:[s.jsxs(_.div,{initial:{opacity:0,x:-50},whileInView:{opacity:1,x:0},transition:{duration:.6},viewport:{once:!0},children:[s.jsx("div",{className:"inline-block bg-primary/20 text-primary px-4 py-2 rounded-full text-sm font-semibold mb-6",children:e.badge}),s.jsx("h2",{className:"text-4xl md:text-5xl font-bold text-white mb-6",children:e.title}),s.jsx("p",{className:"text-xl text-gray-300 mb-8 leading-relaxed",children:e.subt
3863itle}),s.jsx("div",{className:"space-y-4",children:a.map((n,i)=>s.jsxs(_.div,{initial:{opacity:0,x:-30},whileInView:{opacity:1,x:0},transition:{duration:.5,delay:i*.1},viewport:{once:!0},className:"flex items-start gap-4 bg-gradient-to-r from-gray-800/50 to-transparent border border-gray-800 rounded-xl p-4 hover:border-primary/50 transition-all duration-300",children:[s.jsx("div",{className:"flex-shrink-0",children:n.icon}),s.jsxs("div",{children:[s.jsx("h3",{className:"text-lg font-bold text-white mb-1",children:n.title}),s.jsx("p",{className:"text-gray-400 text-sm",children:n.description})]})]},i))})]}),s.jsx(_.div,{initial:{opacity:0,x:50},whileInView:{opacity:1,x:0},transition:{duration:.6},viewport:{once:!0},className:"relative mt-16",children:s.jsxs("div",{className:"relative bg-gradient-to-br from-primary/10 to-purple-500/10 border-2 border-primary/30 rounded-3xl p-8 backdrop-blur-sm mt-20",children:[s.jsx("div",{className:"absolute top-0 right-0 w-64 h-64 bg-primary/20 rounded-full blur-3xl"}),s.jsx("div",{className:"absolute bottom-0 left-0 w-64 h-64 bg-purple-500/20 rounded-full blur-3xl"}),s.jsxs("div",{className:"relative space-y-6",children:[s.jsxs(_.div,{initial:{scale:0},whileInView:{scale:1},transition:{duration:.5,delay:.2},viewport:{once:!0},className:"bg-gradient-to-r from-blue-500/20 to-blue-500/5 border border-blue-500/30 rounded-xl p-4 text-center",children:[s.jsx("p",{className:"text-blue-400 font-semibold mb-2",children:e.diagram.input.title}),s.jsx("p",{className:"text-gray-400 text-sm",children:e.diagram.input.description})]}),s.jsx(_.div,{initial:{opacity:0}
3863,whileInView:{opacity:1},transition:{duration:.3,delay:.4},viewport:{once:!0},className:"flex justify-center",children:s.jsx("div",{className:"text-primary text-3xl",children:"↓"})}),s.jsxs(_.div,{initial:{scale:0},whileInView:{scale:1},transition:{duration:.5,delay:.5},viewport:{once:!0},className:"bg-gradient-to-r from-purple-500/20 to-purple-500/5 border border-purple-500/30 rounded-xl p-4 text-center",children:[s.jsxs("div",{className:"flex items-center justify-center gap-2 mb-2",children:[s.jsxs("svg",{className:"w-6 h-6",viewBox:"0 0 24 24",fill:"none",xmlns:"http://www.w3.org/2000/svg",children:[s.jsx("circle",{cx:"12",cy:"8",r:"3",fill:"#a855f7",opacity:"0.3"}),s.jsx("circle",{cx:"12",cy:"8",r:"3",stroke:"#a855f7",strokeWidth:"2"}),s.jsx("path",{d:"M6 21C6 17.134 8.686 14 12 14C15.314 14 18 17.134 18 21",stroke:"#a855f7",strokeWidth:"2",strokeLinecap:"round"}),s.jsx("circle",{cx:"18",cy:"6",r:"2",fill:"#a855f7"}),s.jsx("circle",{cx:"6",cy:"6",r:"2",fill:"#a855f7"})]}),s.jsx("p",{className:"text-purple-400 font-semibold",children:e.diagram.genAI.title})]}),s.jsx("p",{className:"text-gray-400 text-sm",children:e.diagram.genAI.description})]}),s.jsx(_.div,{initial:{opacity:0}
3863,whileInView:{opacity:1},transition:{duration:.3,delay:.7},viewport:{once:!0},className:"flex justify-center",children:s.jsx("div",{className:"text-primary text-3xl",children:"↓"})}),s.jsxs(_.div,{initial:{scale:0},whileInView:{scale:1},transition:{duration:.5,delay:.8},viewport:{once:!0},className:"bg-gradient-to-r from-green-500/20 to-green-500/5 border border-green-500/30 rounded-xl p-4 text-center",children:[s.jsx("p",{className:"text-green-400 font-semibold mb-2",children:e.diagram.output.title}),s.jsx("p",{className:"text-gray-400 text-sm",children:e.diagram.output.description})]}),s.jsx(_.div,{initial:{opacity:0},whileInView:{opacity:1},transition:{duration:.3,delay:1},viewport:{once:!0},className:"flex justify-center",children:s.jsx("div",{className:"text-primary text-3xl",children:"↓"})}),s.jsxs(_.div,{initial:{scale:0},whileInView:{scale:1},transition:{duration:.5,delay:1.1},viewport:{once:!0},className:"bg-gradient-to-r from-primary/30 to-primary/10 border-2 border-primary rounded-xl p-4 text-center",children:[s.jsxs("div",{className:"flex items-center justify-center gap-2 mb-2",children:[s.jsxs("svg",{className:"w-6 h-6",viewBox:"0 0 24 24",fill:"none",xmlns:"http://www.w3.org/2000/svg",children:[s.jsx("rect",{x:"3",y:"3",width:"18",height:"18",rx:"2",fill:"#22d3ee",opacity:"0.3"}),s.jsx("rect",{x:"3",y:"3",width:"18",height:"18",rx:"2",stroke:"#22d3ee",strokeWidth:"2"}),s.jsx("path",{d:"M8 12L11 15L16 9",stroke:"#22d3ee",strokeWidth:"2.5",strokeLinecap:"round",strokeLinejoin:"round"})]}),s.jsx("p",{className:"text-primary font-bold",children:e.diagram.testing.title})]}),s.jsx("p",{className:"text-gray-300 text-sm font-semibold",children:e.diagram.testing.description})]})]}),s.jsx(_.div,{initial:{rotate:-10,scale:0},whileInView:{rotate:0,scale:1},transition:{duration:.5,delay:1.3},viewport:{once:!0},className:"absolute -top-4 -right-4 bg-primary text-dark px-4 py-2 rounded-full font-bold text-sm shadow-lg",children:e.innovationBadge})]})})]}),s.jsx(_.div,{initial:{opacity:0,y:30},whileInView:{opacity:1,y:0},transition:{duration:.6,delay:.4},viewport:{once:!0},className:"mt-16 text-center",children:s.jsxs("div",{className:"inline-block bg-gradient-to-r from-primary/20 to-purple-500/20 border border-primary/30 rounded-2xl px-12 py-8",children:[s.jsx("p",{className:"text-gray-400 mb-2",children:e.stat.label}),s.jsx("p",{className:"text-4xl md:text-5xl font-bold text-primary mb-2",children:e.stat.value}),s.jsx("p",{className:"text-gray-300",children:e.stat.description})]})})]}),s.jsx(ie,{variant:1})]})}function Kae(){const{t}=$(),e=t("hakaAutomationEngine.comparison",{returnObjects:!0});return s.jsxs("section",{className:"relative bg-dark py-20 mt-16",children:[s.jsxs("div",{className:"max-w-7xl mx-auto px-4 sm:px-6 md:px-8",children:[s.jsxs("div",{className:"text-center mb-16",children:[s.jsx("h2",{className:"text-4xl md:text-5xl font-bold text-white mb-4",children:e.title}),s.jsx("p",{className:"text-xl text-gray-400 max-w-3xl mx-auto",children:e.subt
3863itle})]}),s.jsxs("div",{className:"grid md:grid-cols-2 gap-8 max-w-5xl mx-auto",children:[s.jsxs(_.div,{initial:{opacity:0,x:-50},whileInView:{opacity:1,x:0},transition:{duration:.6},viewport:{once:!0},className:"bg-gradient-to-br from-gray-800/50 to-gray-900/50 border border-gray-700 rounded-2xl p-8",children:[s.jsxs("div",{className:"text-center mb-6",children:[s.jsx("div",{className:"inline-block bg-red-500/20 text-red-400 px-4 py-2 rounded-full text-sm font-semibold mb-4",children:e.traditional.badge}),s.jsx("h3",{className:"text-2xl font-bold text-white mb-2",children:e.traditional.title}),s.jsx("p",{className:"text-gray-400",children:e.traditional.description})]}),s.jsx("div",{className:"relative h-16 bg-gray-900 rounded-xl overflow-hidden mb-4",children:s.jsx(_.div,{initial:{width:0},whileInView:{width:"100%"},transition:{duration:1.5,delay:.3},viewport:{once:!0},className:"h-full bg-gradient-to-r from-red-600 to-red-400 flex items-center justify-center",children:s.jsx("span",{className:"text-white font-bold text-xl",children:"100%"})})}),s.jsxs("div",{className:"space-y-3",children:[s.jsxs("div",{className:"flex items-center gap-2 text-gray-400",children:[s.jsx("span",{className:"text-red-400",children:"✗"}),s.jsx("span",{children:e.traditional.point1})]}),s.jsxs("div",{className:"flex items-center gap-2 text-gray-400",children:[s.jsx("span",{className:"text-red-400",children:"✗"}),s.jsx("span",{children:e.traditional.point2})]}),s.jsxs("div",{className:"flex items-center gap-2 text-gray-400",children:[s.jsx("span",{className:"text-red-400",children:"✗"}),s.jsx("span",{children:e.traditional.point3})]})]})]}),s.jsxs(_.div,{initial:{opacity:0,x:50},whileInView:{opacity:1,x:0},transition:{duration:.6},viewport:{once:!0},className:"bg-gradient-to-br from-primary/20 to-primary/5 border-2 border-primary rounded-2xl p-8 relative",children:[s.jsxs(_.div,{initial:{scale:0,rotate:-180},whileInView:{scale:1,rotate:0},transition:{duration:.6,delay:.4},viewport:{once:!0},className:"absolute -top-5 -right-5 w-14 h-14 bg-gradient-to-br from-cyan-400 to-blue-500 rounded-full flex items-center justify-center shadow-lg shadow-cyan-400/50 text-dark z-10",children:[s.jsx(Kk,{className:"w-7 h-7"}),s.jsx("div",{className:"absolute inset-0 rounded-full bg-cyan-400 animate-ping opacity-30"})]}),s.jsx("div",{className:"absolute top-0 right-0 w-32 h-32 bg-primary/20 rounded-full blur-3xl -z-10"}),s.jsxs("div",{className:"relative text-center mb-6",children:[s.jsx("div",{className:"inline-block bg-primary/20 text-primary px-4 py-2 rounded-full text-sm font-semibold mb-4",children:e.hakalab.badge}),s.jsx("h3",{className:"text-2xl font-bold text-white mb-2",children:e.hakalab.title}),s.jsx("p",{className:"text-gray-300",children:e.hakalab.description})]}),s.jsxs("div",{className:"relative h-16 bg-gray-900 rounded-xl overflow-hidden mb-4",children:[s.jsx(_.div,{initial:{width:0},whileInView:{width:"60%"},transition:{duration:1.5,delay:.3},viewport:{once:!0},className:"h-full bg-gradient-to-r from-primary to-green-400 flex items-center justify-center",children:s.jsx("span",{className:"text-dark font-bold text-xl",children:"60%"})}),s.jsx("div",{className:"absolute right-4 top-1/2 transform -translate-y-1/2 text-primary font-bold text-lg",children:"40% Ahorro"})]}),s.jsxs("div",{className:"space-y-3",children:[s.jsxs("div",{className:"flex items-center gap-2 text-gray-300",children:[s.jsx("span",{className:"text-primary",children:"✓"}),s.jsx("span",{children:e.hakalab.point1})]}),s.jsxs("div",{className:"flex items-center gap-2 text-gray-300",children:[s.jsx("span",{className:"text-primary",children:"✓"}),s.jsx("span",{children:e.hakalab.point2})]}),s.jsxs("div",{className:"flex items-center gap-2 text-gray-300",children:[s.jsx("span",{className:"text-primary",children:"✓"}),s.jsx("span",{children:e.hakalab.point3})]})]})]})]})]}),s.jsx(ie,{variant:1})]})}const Jae="https://calendar.app.google/dkJfuj7MNARbfT5HA";function Qae(){const{t}=$(),e=t("hakaAutomationEngine.cta",{returnObjects:!0}),{openModal:a}=oa(),[n,i]=k.useState(!1),[r,o]=k.useState(!1),l=()=>{window.open(Jae,"_blank","width=1000,height=700,noopener")},c=()=>{i(!0),o(!1)},d=()=>{o(!0),i(!0)};return s.jsxs("section",{className:"relative bg-dark py-20 mt-20",children:[s.jsxs("div",{className:"max-w-7xl mx-auto px-4 sm:px-6 md:px-8",children:[s.jsxs("div",{className:"mb-16",children:[s.jsxs(_.div,{initial:{opacity:0,y:30},whileInView:{opacity:1,y:0},transition:{duration:.6},viewport:{once:!0},className:"text-center mb-8",children:[s.jsx("h2",{className:"text-4xl md:text-5xl font-bold text-white mb-4",children:e.demoTitle}),s.jsx("p",{className:"text-xl text-gray-400 max-w-3xl mx-auto",children:e.demoSubtitle})]}),s.jsx(_.div,{initial:{opacity:0,scale:.95},whileInView:{opacity:1,scale:1},transition:{duration:.6,delay:.2},viewport:{once:!0},className:"relative max-w-5xl mx-auto",children:s.jsxs("div",{className:" relative bg-gradient-to-br from-primary/10 to-purple-500/10 border-2 border-primary/30 rounded-2xl p-4 backdrop-blur-sm",children:[s.jsxs("div",{className:"relative aspect-video rounded-xl overflow-hidden bg-gray-900",children:[!n&&!r&&s.jsxs("div",{className:"absolute inset-0 flex flex-col items-center justify-center bg-gray-900 z-10",children:[s.jsxs("div",{className:"relative",children:[s.jsx("div",{className:"w-16 h-16 border-4 border-primary/30 border-t-primary rounded-full animate-spin"}),s.jsx("div",{className:"absolute inset-0 flex items-center justify-center",children:s.jsx("svg",{className:"w-6 h-6 text-primary",fill:"currentColor",viewBox:"0 0 20 20",children:s.jsx("path",{d:"M2 6a2 2 0 012-2h6a2 2 0 012 2v8a2 2 0 01-2 2H4a2 2 0 01-2-2V6zM14.553 7.106A1 1 0 0014 8v4a1 1 0 00.553.894l2 1A1 1 0 0018 13V7a1 1 0 00-1.447-.894l-2 1z"})})})]}),s.jsx("p",{className:"text-primary font-semibold mt-6 text-lg",children:e.videoLoading||"Cargando video..."}),s.jsx("p",{className:"text-gray-400 text-sm mt-2",children:e.videoLoadingSubtitle||"Por favor espera unos segundos"})]}),r&&s.jsxs("div",{className:"absolute inset-0 flex flex-col items-center justify-center bg-gray-900 z-10",children:[s.jsx("svg",{className:"w-16 h-16 text-red-400 mb-4",fill:"none",viewBox:"0 0 24 24",stroke:"currentColor",children:s.jsx("path",{strokeLinecap:"round",strokeLinejoin:"round",strokeWidth:2,d:"M12 9v2m0 4h.01m-6.938 4h13.856c1.54 0 2.502-1.667 1.732-3L13.732 4c-.77-1.333-2.694-1.333-3.464 0L3.34 16c-.77 1.333.192 3 1.732 3z"})}),s.jsx("p",{className:"text-red-400 font-semibold text-lg mb-2",children:"Error al cargar el video"}),s.jsx("p",{className:"text-gray-400 text-sm mb-4",children:"El video es muy grande o hay un problema de conexión"}),s.jsx("a",{href:"/video/demo.mp4",target:"_blank",rel:"noopener noreferrer",className:"bg-primary text-dark px-6 py-2 rounded-lg font-semibold hover:bg-primary/80 transition-colors",children:"Abrir video en nueva pestaña"})]}),s.jsxs("video",{className:`w-full h-full object-cover transition-opacity duration-500 ${n&&!r?"opacity-100":"opacity-0"}`,controls:!0,onLoadedData:c,onError:d,preload:"auto",children:[s.jsx("source",{src:"/video/demo.mp4",type:"video/mp4"}),"Tu navegador no soporta el elemento de video."]})]}),s.jsxs("div",{className:"absolute top-8 left-8 bg-red-500 text-white px-3 py-1 rounded-full text-xs font-bold flex items-center gap-2",children:[s.jsx("span",{className:"w-2 h-2 bg-white rounded-full animate-pulse"}),"DEMO"]})]})})]}),s.jsxs(_.div,{initial:{opacity:0,y:30},whileInView:{opacity:1,y:0},transition:{duration:.6},viewport:{once:!0},className:"relative bg-gradient-to-br from-primary/20 to-primary/5 border-2 border-primary rounded-3xl p-12 overflow-hidden max-w-5xl mx-auto",children:[s.jsx("div",{className:"absolute top-0 right-0 w-64 h-64 bg-primary/10 rounded-full blur-3xl"}),s.jsx("div",{className:"absolute bottom-0 left-0 w-64 h-64 bg-primary/10 rounded-full blur-3xl"}),s.jsxs("div",{className:"relative text-center",children:[s.jsx(_.div,{initial:{scale:0},whileInView:{scale:1},transition:{duration:.5,delay:.2},viewport:{once:!0},className:"inline-block bg-primary/20 text-primary px-6 py-2 rounded-full text-sm font-semibold mb-6",children:e.badge}),s.jsx("h2",{className:"text-4xl md:text-5xl font-bold text-white mb-6",children:e.title}),s.jsx("p",{className:"text-xl text-gray-300 max-w-2xl mx-auto mb-10",children:e.description}),s.jsxs("div",{className:"flex flex-col sm:flex-row justify-center gap-4",children:[s.jsx(_.button,{whileHover:{scale:1.05},whileTap:{scale:.95},onClick:l,className:"bg-primary border-2 border-primary text-dark px-10 py-4 rounded-2xl text-lg font-semibold hover:bg-dark hover:text-primary transition-all duration-300",children:e.scheduleDemo}),s.jsx(_.button,{whileHover:{scale:1.05},whileTap:{scale:.95},onClick:()=>a(e.contact),className:"border-2 border-primary/50 text-primary px-10 py-4 rounded-2xl text-lg font-semibold hover:bg-primary hover:text-dark transition-all duration-300",children:e.contact})]})]})]})]}),s.jsx(ie,{variant:1})]})}function Xae(){return s.jsxs("div",{className:"bg-dark",children:[s.jsx($ae,{}),s.jsx(Wae,{}),s.jsx(Gae,{}),s.jsx(Kae,{}),s.jsx(Qae,{})]})}function Yae(){const{t}=$(),e=t("frameworkHakalab.hero",{returnObjects:!0}),{openModal:a}=oa();return s.jsxs("section",{className:"relative bg-dark",children:[s.jsxs("div",{className:"relative py-12 sm:py-16 md:py-20 flex items-center justify-center overflow-hidden min-h-[400px] sm:min-h-[500px]",children:[s.jsx("div",{className:"absolute inset-0 bg-gradient-to-br from-dark via-dark to-dark"}),s.jsx("div",{className:"absolute top-0 left-1/2 transform -translate-x-1/2 w-[800px] h-[400px] bg-primary/20 rounded-full blur-[120px] opacity-30"}),s.jsx("div",{className:"relative z-10 max-w-7xl mx-auto px-4 sm:px-6 md:px-8 w-full",children:s.jsxs("div",{className:"text-center",children:[s.jsx(Lg,{text:e.badge}),s.jsxs("h1",{className:"text-5xl md:text-7xl font-extrabold tracking-tight text-white mt-6",children:[s.jsx("span",{className:"text-primary",children:"Haka"}),"Lab Framework"]}),s.jsx("h2",{className:"text-3xl md:text-4xl font-bold text-primary mt-6",children:e.titleHighlight}),s.jsx("p",{className:"text-xl text-gray-300 font-normal max-w-3xl mx-auto leading-relaxed mt-8",children:e.subt
3863itle}),s.jsx("div",{className:"flex flex-col sm:flex-row justify-center gap-4 mt-10",children:s.jsx("button",{onClick:()=>a(e.ctaContact),className:"bg-primary border-2 border-primary text-dark px-10 py-3 rounded-2xl text-lg font-semibold hover:bg-dark hover:text-primary transition-all duration-300",children:e.ctaContact})})]})})]}),s.jsx(ie,{variant:1})]})}function Zae(){const{t}=$(),e=t("frameworkHakalab.pillars",{returnObjects:!0}),a=[{icon:s.jsxs("svg",{className:"w-8 h-8",viewBox:"0 0 24 24",fill:"none",xmlns:"http://www.w3.org/2000/svg",children:[s.jsx("circle",{cx:"12",cy:"8",r:"4",fill:"#22d3ee",opacity:"0.2"}),s.jsx("circle",{cx:"12",cy:"8",r:"4",stroke:"#22d3ee",strokeWidth:"2"}),s.jsx("path",{d:"M5 21C5 16.582 8.134 13 12 13C15.866 13 19 16.582 19 21",stroke:"#22d3ee",strokeWidth:"2",strokeLinecap:"round"})]}),title:e.people.title,description:e.people.description},{icon:s.jsxs("svg",{className:"w-8 h-8",viewBox:"0 0 24 24",fill:"none",xmlns:"http://www.w3.org/2000/svg",children:[s.jsx("rect",{x:"3",y:"3",width:"18",height:"18",rx:"2",fill:"#22d3ee",opacity:"0.2"}),s.jsx("rect",{x:"3",y:"3",width:"18",height:"18",rx:"2",stroke:"#22d3ee",strokeWidth:"2"}),s.jsx("path",{d:"M8 12L11 15L16 9",stroke:"#22d3ee",strokeWidth:"2.5",strokeLinecap:"round",strokeLinejoin:"round"}),s.jsx("circle",{cx:"18",cy:"6",r:"2",fill:"#22d3ee"})]}),title:e.methodology.title,description:e.methodology.description},{icon:s.jsxs("svg",{className:"w-8 h-8",viewBox:"0 0 24 24",fill:"none",xmlns:"http://www.w3.org/2000/svg",children:[s.jsx("rect",{x:"4",y:"4",width:"7",height:"7",rx:"1",fill:"#22d3ee",opacity:"0.2"}),s.jsx("rect",{x:"4",y:"4",width:"7",height:"7",rx:"1",stroke:"#22d3ee",strokeWidth:"2"}),s.jsx("rect",{x:"13",y:"4",width:"7",height:"7",rx:"1",fill:"#22d3ee",opacity:"0.2"}),s.jsx("rect",{x:"13",y:"4",width:"7",height:"7",rx:"1",stroke:"#22d3ee",strokeWidth:"2"}),s.jsx("rect",{x:"4",y:"13",width:"7",height:"7",rx:"1",fill:"#22d3ee",opacity:"0.2"}),s.jsx("rect",{x:"4",y:"13",width:"7",height:"7",rx:"1",stroke:"#22d3ee",strokeWidth:"2"}),s.jsx("rect",{x:"13",y:"13",width:"7",height:"7",rx:"1",fill:"#22d3ee"}),s.jsx("path",{d:"M15 16.5L16 17.5L18 15.5",stroke:"#0a0a0a",strokeWidth:"1.5",strokeLinecap:"round",strokeLinejoin:"round"})]}),title:e.technology.title,description:e.technology.description}];return s.jsxs("section",{className:"relative bg-dark py-20",children:[s.jsx("div",{className:"relative text-center mb-12 mt-20",children:s.jsxs("p",{className:"text-xl text-gray-300 max-w-3xl mx-auto",children:["Nuestra solución se centra en tres pilares fundamentales que trabajan en",s.jsx("br",{}),s.jsx("span",{className:"text-primary",children:"sinergia, aprendizaje y mejora continua"})]})}),s.jsx("div",{className:"max-w-7xl mx-auto px-4 sm:px-6 md:px-8 overflow-hidden",children:s.jsxs(_.div,{initial:{opacity:0,y:30},whileInView:{opacity:1,y:0},transition:{duration:.6},viewport:{once:!0},className:"bg-gradient-to-br from-primary/10 to-purple-500/10 border-2 border-primary/30 rounded-3xl p-8 md:p-12 pt-16 backdrop-blur-sm relative overflow-visible shadow-2xl shadow-primary/20",children:[s.jsx(_.div,{animate:{opacity:[.3,.6,.3],scale:[1,1.02,1]},transition:{duration:3,repeat:1/0,ease:"easeInOut"},className:"absolute inset-0 rounded-3xl border-2 border-primary/50 blur-sm"}),s.jsx("div",{className:"absolute top-0 right-0 w-64 h-64 bg-primary/10 rounded-full blur-3xl"}),s.jsx("div",{className:"absolute bottom-0 left-0 w-64 h-64 bg-purple-500/10 rounded-full blur-3xl"}),s.jsx("div",{className:"relative grid grid-cols-1 md:grid-cols-3 gap-8",children:a.map((n,i)=>s.jsxs("div",{className:"relative",children:[s.jsxs(_.div,{initial:{opacity:0,y:30},whileInView:{opacity:1,y:0},whileHover:{scale:1.05,y:-5},transition:{duration:.3},viewport:{once:!0},className:"relative bg-gradient-to-br from-gray-800/50 to-gray-900/50 border border-gray-700 rounded-2xl p-6 pt-14 hover:border-primary hover:shadow-2xl hover:shadow-primary/50 transition-all duration-300 h-full flex flex-col group",children:[s.jsx("div",{className:"absolute inset-0 rounded-2xl bg-primary/5 opacity-0 group-hover:opacity-100 transition-opacity duration-300"}),s.jsx("div",{className:"absolute -top-8 left-1/2 transform -translate-x-1/2 bg-gradient-to-br from-gray-800 to-gray-900 border-2 border-primary rounded-xl p-3 shadow-lg shadow-primary/30 group-hover:shadow-
3863primary/60 group-hover:scale-110 transition-all duration-300",children:n.icon}),s.jsx("h3",{className:"relative text-lg font-bold text-white text-center mb-4 z-10",children:n.title}),s.jsx("p",{className:"relative text-gray-300 text-center leading-relaxed flex-grow z-10",children:n.description})]}),i<a.length-1&&s.jsx(_.div,{initial:{opacity:0,scale:0},whileInView:{opacity:1,scale:1},transition:{duration:.5,delay:i*.2+.4},viewport:{once:!0},className:"hidden md:block absolute -right-10 top-1/2 transform -translate-y-1/2 z-10",children:s.jsx(_.div,{animate:{scale:[1,1.2,1],opacity:[.7,1,.7]},transition:{duration:2,repeat:1/0,ease:"easeInOut"},className:"w-12 h-12 rounded-full bg-primary/20 border-2 border-primary flex items-center justify-center shadow-lg shadow-primary/50",children:s.jsx("svg",{className:"w-6 h-6 text-primary",fill:"none",stroke:"currentColor",viewBox:"0 0 24 24",children:s.jsx("path",{strokeLinecap:"round",strokeLinejoin:"round",strokeWidth:3,d:"M12 4v16m8-8H4"})})})})]},i))})]})}),s.jsx(ie,{variant:2})]})}function ene(){const{t}=$(),e=t("frameworkHakalab.methodology",{returnObjects:!0});return s.jsxs("section",{className:"relative bg-dark py-20 mt-10",children:[s.jsxs("div",{className:"max-w-7xl mx-auto px-4 sm:px-6 md:px-8",children:[s.jsx(_.div,{initial:{opacity:0,y:30},whileInView:{opacity:1,y:0},transition:{duration:.6},viewport:{once:!0},className:"text-center mb-16",children:s.jsxs("h2",{className:"text-4xl md:text-5xl font-bold text-white -mb-10",children:[s.jsx("span",{className:"text-primary",children:"Framework"})," Metodológico"]})}),s.jsx(Og,{}),s.jsx(_.div,{initial:{opacity:0,y:30},whileInView:{opacity:1,y:0},transition:{duration:.6,delay:.3},viewport:{once:!0},className:"max-w-4xl mx-auto mt-16",children:s.jsxs("div",{className:"bg-gradient-to-br from-primary/10 to-purple-500/10 border-l-4 border-primary rounded-r-2xl p-8 backdrop-blur-sm relative -mt-10",children:[s.jsx("svg",{className:"absolute top-4 left-4 w-8 h-8 text-primary/30",fill:"currentColor",viewBox:"0 0 24 24",children:s.jsx("path",{d:"M6 17h3l2-4V7H5v6h3zm8 0h3l2-4V7h-6v6h3z"})}),s.jsxs("div",{className:"flex items-start gap-6 mt-4",children:[s.jsx("div",{className:"flex-shrink-0",children:s.jsx("div",{className:"w-16 h-16 rounded-full bg-gradient-to-br from-primary to-blue-500 flex items-center justify-center text-white text-2xl font-bold shadow-lg shadow-primary/30",children:"MC"})}),s.jsxs("div",{className:"flex-grow",children:[s.jsxs("p",{className:"text-lg text-gray-200 italic leading-relaxed mb-4",children:['"',e.quote,'"']}),s.jsxs("div",{className:"flex items-center gap-2",children:[s.jsx("div",{className:"h-px w-12 bg-primary"}),s.jsx("p",{className:"text-primary font-semibold",children:e.author}),s.jsx("p",{className:"text-gray-400 text-sm",children:e.authorRole})]})]})]})]})})]}),s.jsx(ie,{variant:1})]})}function tne(){const{t}=$(),e=t("frameworkHakalab.technology",{returnObjects:!0}),a=[{src:"/imagenes/framework/Selenium_Logo.png",name:"Selenium",desc:e.tools.selenium},{src:"/imagenes/framework/playwright.png",name:"Playwright",desc:e.tools.playwright},{src:"/imagenes/framework/cucumber.png",name:"Cucumber",desc:e.tools.cucumber},{src:"/imagenes/framework/python.png",name:"Python",desc:e.tools.python},{src:"/imagenes/framework/Jenkins_logo.svg.png",name:"Jenkins",desc:e.tools.jenkins},{src:"/imagenes/framework/docker.png",name:"Docker",desc:e.tools.docker},{src:"/imagenes/framework/github.png",name:"GitHub",desc:e.tools.github},{src:"/imagenes/framework/jira-3.svg",name:"Jira",desc:e.tools.jira},{src:"/imagenes/framework/Logo-Xray.png",name:"Xray",desc:e.tools.xray},{src:"/imagenes/framework/Grafana_icon.svg.png",name:"Grafana",desc:e.tools.grafana},{src:"/imagenes/framework/html.png",name:"HTML Reports",desc:e.tools.html},{src:"/imagenes/framework/apirest.png",name:"API REST",desc:e.tools.apirest},{src:"/imagenes/framework/bbdd.png",name:"Database",desc:e.tools.bbdd},{src:"/imagenes/framework/front.png",name:"Frontend",desc:e.tools.front},{src:"/imagenes/framework/chrome.png",name:"Chrome",desc:e.tools.chrome},{src:"/imagenes/framework/appium.png",name:"Appium",desc:e.tools.appium}],n=[{src:"/imagenes/productos/hakaboost_logo.png",alt:"Hakaboost"},{src:"/imagenes/productos/hakabuddy_logo2.png",alt:"Hakabuddy"},{src:"/imagenes/productos/hakapath_logo.png",alt:"Hakapath"},{src:"/imagenes/productos/hakartc_logo.png",alt:"Hakartc"}];return s.jsxs("section",{className:"relative bg-dark py-20",children:[s.jsxs("div",{className:"max-w-7xl mx-auto px-4 sm:px-6 md:px-8",children:[s.jsxs(_.div,{initial:{opacity:0,y:30},whileInView:{opacity:1,y:0},transition:{duration:.6},viewport:{once:!0},className:"text-center mb-16",children:[s.jsxs("h2",{className:"text-4xl md:text-5xl font-bold text-white mb-4 mt-10",children:[s.jsx("span",{className:"text-primary",children:"Framework"})," Tecnológico"]}),s.jsx("p",{className:"text-xl text-gray-300 max-w-3xl mx-auto",children:e.subt
3863itle})]}),s.jsxs("div",{className:"grid lg:grid-cols-2 gap-12 items-center",children:[s.jsxs(_.div,{initial:{opacity:0,x:-50},whileInView:{opacity:1,x:0},transition:{duration:.6},viewport:{once:!0},className:"relative",children:[s.jsx("div",{className:"absolute -top-4 -left-4 z-10",children:s.jsxs("div",{className:"bg-gradient-to-r from-primary to-blue-500 text-dark px-4 py-2 rounded-full font-bold text-sm shadow-lg shadow-primary/50 flex items-center gap-2",children:[s.jsx("svg",{className:"w-4 h-4",fill:"currentColor",viewBox:"0 0 24 24",children:s.jsx("path",{d:"M12 2L15.09 8.26L22 9.27L17 14.14L18.18 21.02L12 17.77L5.82 21.02L7 14.14L2 9.27L8.91 8.26L12 2Z"})}),e.aiPowered]})}),s.jsxs("div",{className:"bg-gradient-to-br from-gray-800/50 to-gray-900/50 border-2 border-gray-700 rounded-2xl p-8 hover:border-primary/50 transition-all duration-300",children:[s.jsx("h3",{className:"text-2xl font-bold text-white mb-6 text-center",children:e.techTitle}),s.jsx("div",{className:"grid grid-cols-6 gap-3",children:a.map((i,r)=>s.jsxs(_.div,{initial:{opacity:0,scale:0},whileInView:{opacity:1,scale:1},transition:{duration:.3,delay:r*.05},viewport:{once:!0},whileHover:{scale:1.1,rotate:5},className:"bg-dark/50 rounded-lg p-2 flex items-center justify-center aspect-square border border-gray-700 hover:border-primary/50 transition-all duration-300 relative group cursor-pointer",title:i.desc,children:[s.jsx("img",{src:i.src,alt:i.name,className:"w-full h-full object-contain"}),s.jsxs("div",{className:"absolute bottom-full left-1/2 transform -translate-x-1/2 mb-2 px-3 py-2 bg-gray-900 text-white text-xs rounded-lg opacity-0 group-hover:opacity-100 transition-opacity duration-300 pointer-events-none whitespace-nowrap z-20 shadow-lg border border-primary/30",children:[s.jsx("div",{className:"font-bold mb-1",children:i.name}),s.jsx("div",{className:"text-gray-300",children:i.desc}),s.jsx("div",{className:"absolute top-full left-1/2 transform -translate-x-1/2 -mt-1",children:s.jsx("div",{className:"border-4 border-transparent border-t-gray-900"})})]})]},r))})]})]}),s.jsxs(_.div,{initial:{opacity:0,x:50},whileInView:{opacity:1,x:0},transition:{duration:.6},viewport:{once:!0},className:"space-y-8",children:[s.jsxs("div",{className:"bg-gradient-to-br from-primary/10 to-purple-500/10 border-l-4 border-primary rounded-r-2xl p-6",children:[s.jsx("h4",{className:"text-lg font-bold text-white mb-2",children:e.differentiator.title}),s.jsx("p",{className:"text-md text-gray-300 leading-relaxed",children:e.differentiator.description})]}),s.jsxs("div",{className:"bg-gradient-to-br from-gray-800/50 to-gray-900/50 border border-gray-700 rounded-2xl p-6",children:[s.jsxs("div",{className:"flex items-center gap-3 mb-4",children:[s.jsx("div",{className:"w-10 h-10 rounded-full bg-primary/20 flex items-center justify-center",children:s.jsx("svg",{className:"w-6 h-6 text-primary",fill:"none",stroke:"currentColor",viewBox:"0 0 24 24",children:s.jsx("path",{strokeLinecap:"round",strokeLinejoin:"round",strokeWidth:2,d:"M13 10V3L4 14h7v7l9-11h-7z"})})}),s.jsx("h4",{className:"text-xl font-bold text-white",children:e.powerups.title})]}),s.jsx("p",{className:"text-gray-300 mb-6",children:e.powerups.description}),s.jsx("div",{className:"grid grid-cols-2 gap-4 mb-6",children:n.map((i,r)=>s.jsx(_.div,{initial:{opacity:0,y:20},whileInView:{opacity:1,y:0},transition:{duration:.4,delay:r*.1},viewport:{once:!0},className:"bg-dark/50 rounded-xl p-4 flex items-center justify-center border border-gray-700 hover:border-primary/50 transition-all duration-300",children:s.jsx("img",{src:i.src,alt:i.alt,className:"h-8 object-contain"})},r))}),s.jsx(Te,{to:"/haka-automation-engine",className:"block w-full bg-primary hover:bg-primary/80 text-dark font-bold py-3 px-6 rounded-xl text-center transition-all duration-300 hover:shadow-lg hover:shadow-primary/50 transform hover:-translate-y-1",children:e.cta})]})]})]})]}),s.jsx(ie,{variant:2})]})}function ane(){return s.jsxs("div",{className:"bg-dark",children:[s.jsx(Yae,{}),s.jsx(Zae,{}),s.jsx(ene,{}),s.jsx(tne,{})]})}const nne=[{id:"inicio",title:"Inicio",group:"Empezar",icon:"",topics:[{id:"estructura-proyecto",title:"Estructura del Proyecto",content:`## Estructura de Carpetas Estándar
3864
3865Un proyecto que usa Haka Framework sigue una estructura específica donde Behave maneja las features y el framework provee los steps, helpers y configuración. El framework se instala como paquete.
3866
3867### Proyecto Mínimo
3868
3869\`\`\`
3870mi_proyecto/
3871├── .env                        # Configuración (navegador, URLs, timeouts)
3872├── behave.ini                  # Configuración de Behave
3873├── features/
3874│   ├── environment.py          # Ciclo de vida (template del framework)
3875│   ├── login.feature           # Feature de login
3876│   ├── compras.feature         # Feature de compras
3877│   └── steps/
3878│       └── custom_steps.py     # Pasos personalizados del proyecto
3879├── json_poms/
3880│   ├── LOGIN.json              # Localizadores de la página de login
3881│   ├── DASHBOARD.json          # Localizadores del dashboard
3882│   └── COMPRAS.json            # Localizadores del módulo compras
3883├── screenshots/                # Screenshots automáticos (generado)
3884├── html-reports/               # Reportes HTML (generado)
3885└── requirements.txt            # Dependencias (haka-playwright-engine)
3886\`\`\`
3887
3888### Proyecto Completo con API y Datos
3889
3890\`\`\`
3891mi_proyecto/
3892├── .env
3893├── behave.ini
3894├── features/
3895│   ├── environment.py
3896│   ├── web/
3897│   │   ├── login.feature
3898│   │   └── checkout.feature
3899│   ├── api/
3900│   │   ├── usuarios_api.feature
3901│   │   └── pagos_api.feature
3902│   └── steps/
3903│       ├── custom_web_steps.py
3904│       └── custom_api_steps.py
3905├── json_poms/
3906│   ├── LOGIN.json
3907│   └── CHECKOUT.json
3908├── payloads/                   # JSON bodies para peticiones API
3909├── schemas/                    # JSON Schema para validar respuestas
3910├── expected/                   # Respuestas esperadas para comparar
3911├── screenshots/
3912├── html-reports/
3913└── requirements.txt
3914\`\`\`
3915
3916## Consideraciones
3917
3918- \`features/environment.py\` es OBLIGATORIO — configura el framework.
3919- El archivo \`.env\` es OBLIGATORIO — contiene toda la configuración.
3920- \`json_poms/\` es la ubicación por defecto pero es configurable con \`JSON_POMS_PATH\`.
3921- Puedes organizar los \`.feature\` en subcarpetas; Behave los busca recursivamente.
3922
3923## Ejecutar las Pruebas
3924
3925\`\`\`bash
3926# Ejecutar todo
3927behave
3928
3929# Ejecutar un feature específico
3930behave features/login.feature
3931
3932# Ejecutar por tag
3933behave --tags=@smoke
3934behave --tags="@smoke and @login"
3935
3936# Un escenario específico por nombre
3937behave --name="Validar login con credenciales válidas"
3938
3939# Ejecución paralela (CLI del framework)
3940haka-run --workers=4 --features=features/
3941\`\`\`
3942
3943## Tags Especiales del Framework
3944
3945- \`@no_browser\`: No se levanta Playwright, ideal para pruebas de API pura.
3946- \`@soft_assertions\`: Los fallos en assertions no detienen el escenario.
3947- \`@PROJ-XXX\`: Integración con Jira (si está configurada).
3948- \`@TEST-XXX\`: Integración con Xray (si está configurada).`},{id:"requisitos-previos",title:"Requisitos Previos",content:`## Requisitos del Sistema
3949
3950Para utilizar Haka Framework necesitas tener instalado:
3951
3952| Requisito | Versión Mínima | Notas |
3953|---|---|---|
3954| Python | 3.10+ | Disponible en el PATH del sistema |
3955| pip | (incluido con Python) | Gestor de paquetes |
3956| Node.js | 18+ | Necesario para Appium (pruebas mobile) |
3957| Git | Cualquiera | Para clonar el repositorio |
3958
3959> **Nota para macOS:** Los comandos \`python\` deben ejecutarse como \`python3\`.
3960
3961## Dependencias Opcionales
3962
3963Según el tipo de pruebas que necesites, puedes instalar dependencias adicionales:
3964
3965| Tipo de Prueba | Paquetes Adicionales |
3966|---|---|
3967| Validación semántica con IA | \`sentence-transformers torch transformers keybert scikit-learn\` |
3968| Evaluación con Gemini (GenAI) | \`google-generativeai\` |
3969| Pruebas mobile con Appium | \`Appium-Python-Client\` (incluido por defecto) |
3970| OCR | \`pytesseract easyocr Pillow opencv-python\` (incluidos por defecto) |
3971| Pruebas desktop | \`pyautogui pillow pyperclip pytesseract\` (incluido por defecto) |
3972| MySQL | \`mysql-connector-python\` |
3973| PostgreSQL | \`psycopg2-binary\` |`},{id:"instalacion",title:"Instalación desde repositorio",content:`## 1. Clonar el Repositorio
3974
3975\`\`\`bash
3976git clone https://github.com/HakaLab-2025/Engine-Playwright-Base.git
3977cd Engine-Playwright-Base
3978\`\`\`
3979
3980## 2. Crear Entorno Virtual (recomendado)
3981
3982\`\`\`bash
3983python -m venv venv
3984
3985# Windows
3986venv\\Scripts\\activate
3987
3988# macOS / Linux
3989source venv/bin/activate
3990\`\`\`
3991
3992## 3. Instalar Dependencias Base
3993
3994\`\`\`bash
3995pip install -r requirements.txt
3996\`\`\`
3997
3998Esto instala \`haka-playwright-engine\` junto con todas las dependencias necesarias para pruebas web, API y utilidades generales.
3999
4000## 4. Instalar Navegadores de Playwright
4001
4002\`\`\`bash
4003playwright install
4004\`\`\`
4005
4006Descarga los binarios de Chromium, Firefox y WebKit necesarios para ejecutar pruebas web.
4007
4008## 5. Configurar el Archivo .env
4009
4010\`\`\`bash
4011# Windows
4012copy ejemplo.env .env
4013
4014# macOS / Linux
4015cp ejemplo.env .env
4016\`\`\`
4017
4018Edita el archivo \`.env\` con la configuración de tu proyecto.
4019
4020## 6. Dependencias Opcionales
4021
4022\`\`\`bash
4023# Validación semántica con IA
4024pip install sentence-transformers torch transformers keybert scikit-learn
4025
4026# Evaluación con Gemini (GenAI)
4027pip install google-generativeai
4028
4029# Pruebas mobile con Appium
4030pip install Appium-Python-Client
4031
4032# OCR
4033pip install pytesseract easyocr Pillow opencv-python
4034
4035# Pruebas desktop
4036pip install pyautogui pillow pyperclip pytesseract
4037\`\`\`
4038
4039> La mayoría de estas dependencias ya están incluidas en el \`requirements.txt\` por defecto. Adicionalmente, para OCR se requiere instalar el binario de Tesseract.`},{id:"haka-init",title:"Instalación con haka-init",content:`## Crear un Proyecto Nuevo con haka-init
4040
4041\`haka-init\` genera la estructura completa de un proyecto de pruebas en segundos. Es la forma recomendada de empezar: crea los archivos de configuración, los features de ejemplo, los runners y la documentación, todo listo para ejecutar.
4042
4043## Pasos previos
4044
4045Antes de ejecutar \`haka-init\`, necesitás tener el framework instalado:
4046
4047### 1. Crear una carpeta para el proyecto
4048
4049\`\`\`bash
4050mkdir mi-proyecto-qa
4051cd mi-proyecto-qa
4052\`\`\`
4053
4054### 2. Crear un entorno virtual
4055
4056\`\`\`bash
4057python -m venv venv
4058
4059# Windows
4060venv\\Scripts\\activate
4061
4062# macOS / Linux
4063source venv/bin/activate
4064\`\`\`
4065
4066> En macOS usá \`python3\` en lugar de \`python\`.
4067
4068### 3. Instalar el framework
4069
4070\`\`\`bash
4071pip install haka-playwright-engine
4072\`\`\`
4073
4074Esto instala el framework y habilita los comandos \`haka-init\`, \`haka-run\`, \`haka-agent\`, \`haka-login\` y \`haka-ui\`.
4075
4076### 4. Ejecutar haka-init
4077
4078\`\`\`bash
4079haka-init
4080\`\`\`
4081
4082Esto genera la estructura base en el directorio actual (15 archivos).
4083
4084### 5. Instalar las dependencias del proyecto
4085
4086\`\`\`bash
4087pip install -r requirements.txt
4088\`\`\`
4089
4090El \`requirements.txt\` generado incluye todas las dependencias. Algunas están comentadas según el tipo de prueba: descomentá las que necesites (semántica, OCR, mobile).
4091
4092### 6. Instalar los navegadores de Playwright
4093
4094\`\`\`bash
4095playwright install
4096\`\`\`
4097
4098### 7. Configurar el .env
4099
4100Editá el archivo \`.env\` con la configuración de tu proyecto: \`BASE_URL\`, credenciales de IA, integraciones, etc.
4101
4102---
4103
4104## Uso básico
4105
4106\`\`\`bash
4107# Genera la estructura en el directorio actual
4108haka-init
4109
4110# Genera en un subdirectorio nuevo
4111haka-init mi-suite
4112\`\`\`
4113
4114Si el directorio ya tiene archivos, \`haka-init\` los conserva sin tocar. Para reemplazarlos con los de la plantilla:
4115
4116\`\`\`bash
4117haka-init --force
4118\`\`\`
4119
4120---
4121
4122## Módulos opcionales
4123
4124Los flags agregan archivos de configuración y ejemplos específicos. Se pueden combinar y se pueden ejecutar después sobre un proyecto existente para agregar lo que falta:
4125
4126\`\`\`bash
4127# Solo web (default)
4128haka-init
4129
4130# Web + integración Jira
4131haka-init --jira
4132
4133# Web + Jira + Xray
4134haka-init --jira --xray
4135
4136# Web + ejemplos de pruebas API
4137haka-init --api
4138
4139# Web + pruebas mobile (incluye APK de demo)
4140haka-init --mobile
4141
4142# Todo junto
4143haka-init --jira --xray --api --mobile
4144\`\`\`
4145
4146> \`--xray\` implica \`--jira\` automáticamente: no tiene sentido sin él.
4147
4148---
4149
4150## Qué genera cada flag
4151
4152### Base (siempre)
4153
4154| Archivo | Descripción |
4155|---------|-------------|
4156| \`.env\` | Configuración completa del framework (292 variables) |
4157| \`behave.ini\` | Configuración de Behave |
4158| \`requirements.txt\` | Dependencias Python con opcionales comentados |
4159| \`.gitignore\` | Ignora reportes, videos, sesiones y virtualenvs |
4160| \`Runner.py\` | Ejecución serial con selección de features |
4161| \`Runner_parallel.py\` | Ejecución paralela (usa PARALLEL_WORKERS del .env) |
4162| \`report_config.json\` | Título, logos y colores del reporte HTML |
4163| \`json_poms/DEMO.json\` | POM de ejemplo con selectores reales (role=, XPath, id) |
4164| \`features/demo_formulario.feature\` | Scenario Outline ejecutable contra hakatools |
4165| \`features/environment.py\` | Carga del framework (no necesita modificación) |
4166| \`features/steps/custom_steps.py\` | Tus pasos personalizados |
4167| \`README.md\` | Documentación completa del proyecto |
4168| \`documentacion/README.md\` | Guía para documentación funcional |
4169
4170### --jira
4171
4172| Archivo | Descripción |
4173|---------|-------------|
4174| \`jira_config.json\` | Configuración de la integración con Jira: adjuntos, comentarios, creación de bugs, campos personalizados |
4175
4176### --xray
4177
4178| Archivo | Descripción |
4179|---------|-------------|
4180| \`xray_config.json\` | Configuración completa de Xray Cloud: matching por tags, evidencias, ciclo de vida de tests, manejo de errores |
4181
4182### --mobile
4183
4184| Archivo | Descripción |
4185|---------|-------------|
4186| \`apps/appDemo.apk\` | APK de la Sauce Labs Demo App para pruebas |
4187| \`json_poms/DEMOMOBILE.json\` | POM mobile con selectores Appium (xpath, content-desc) |
4188| \`features/demo_mobile.feature\` | Scenario Outline de flujo de carrito mobile |
4189
4190### --api
4191
4192| Archivo | Descripción |
4193|---------|-------------|
4194| \`features/demo_api.feature\` | 4 escenarios de pruebas API REST contra jsonplaceholder |
4195
4196---
4197
4198## Estructura resultante (base + todos los módulos)
4199
4200\`\`\`
4201mi-proyecto-qa/
4202|-- .env
4203|-- .gitignore
4204|-- behave.ini
4205|-- requirements.txt
4206|-- Runner.py
4207|-- Runner_parallel.py
4208|-- report_config.json
4209|-- jira_config.json          (--jira)
4210|-- xray_config.json          (--xray)
4211|-- README.md
4212|-- features/
4213|   |-- environment.py
4214|   |-- demo_formulario.feature
4215|   |-- demo_api.feature      (--api)
4216|   |-- demo_mobile.feature   (--mobile)
4217|   +-- steps/
4218|       |-- __init__.py
4219|       +-- custom_steps.py
4220|-- json_poms/
4221|   |-- DEMO.json
4222|   +-- DEMOMOBILE.json       (--mobile)
4223|-- apps/
4224|   +-- appDemo.apk           (--mobile)
4225|-- documentacion/
4226|   +-- README.md
4227+-- test_files/
4228    +-- .gitkeep
4229\`\`\`
4230
4231---
4232
4233## Archivos existentes
4234
4235\`haka-init\` nunca sobreescribe un archivo que ya existe. Si corrés el comando en un proyecto que ya tiene un \`.env\` propio, lo conserva:
4236
4237\`\`\`
4238🛡️  Conservados, ya existían (3):
4239   = .env
4240   = features/steps/custom_steps.py
4241   = Runner.py
4242   Usá --force si querés reemplazarlos por la plantilla.
4243\`\`\`
4244
4245Eso permite agregar módulos después sin riesgo:
4246
4247\`\`\`bash
4248# El proyecto ya existe, solo quiero agregar la config de Xray
4249haka-init --xray
4250\`\`\`
4251
4252---
4253
4254## Ejemplo completo desde cero
4255
4256\`\`\`bash
4257# 1. Crear carpeta y entorno
4258mkdir mi-suite && cd mi-suite
4259python -m venv venv
4260source venv/bin/activate    # Linux/Mac
4261# venv\\Scripts\\activate    # Windows
4262
4263# 2. Instalar el framework
4264pip install haka-playwright-engine
4265
4266# 3. Generar el proyecto con API y Jira
4267haka-init --api --jira
4268
4269# 4. Instalar dependencias del proyecto
4270pip install -r requirements.txt
4271
4272# 5. Instalar navegadores
4273playwright install
4274
4275# 6. Ejecutar la demo
4276python Runner.py
4277\`\`\`
4278
4279El feature de demo corre contra \`hakatools.hakalab.com\` sin necesidad de configurar nada más.`},{id:"configuracion-env",title:"Configuración (.env)",content:'## Descripción General\n\nEl framework usa un archivo `.env` en la raíz del proyecto para toda la configuración. Se carga automáticamente con `python-dotenv` con `override=True`, lo que significa que las variables del `.env` tienen prioridad sobre las del sistema.\n\n> **Importante:** No subas el `.env` con credenciales reales a Git. Usa variables de entorno del sistema o secretos de CI/CD para datos sensibles.\n\n---\n\n## Navegador y Pruebas Web\n\n| Variable | Tipo | Default | Descripción |\n|---|---|---|---|\n| `BROWSER` | string | `chromium` | Navegador: `chromium`, `firefox`, `webkit`, `chrome` |\n| `HEADLESS` | bool | `false` | Ejecutar sin interfaz gráfica |\n| `TIMEOUT` | int (ms) | `30000` | Timeout global para operaciones de Playwright |\n| `ASSERTION_TIMEOUT` | int (ms) | `30000` | Timeout específico para assertions/verificaciones |\n| `VIEWPORT_WIDTH` | int | `1920` | Ancho del viewport en píxeles |\n| `VIEWPORT_HEIGHT` | int | `1080` | Alto del viewport en píxeles |\n| `DEVICE_SCALE_FACTOR` | float | `1` | Factor de escala del dispositivo (2 para retina) |\n| `SLOW_MO` | int (ms) | `0` | Milisegundos de pausa entre cada acción |\n| `BASE_URL` | string | `""` | URL base de la aplicación bajo prueba |\n| `IGNORE_HTTPS_ERRORS` | bool | `false` | Ignorar errores de certificados SSL |\n| `BROWSER_USER_AGENT` | string | `""` | User agent personalizado |\n| `NAVIGATION_TIMEOUT` | int (ms) | `10000` | Timeout para navegación |\n| `WAIT_UNTIL` | string | `load` | Evento de espera: `load`, `domcontentloaded`, `networkidle` |\n| `DISABLE_NETWORKIDLE_WAIT` | bool | `true` | Desactivar espera de networkidle |\n\n**Configuración avanzada del navegador:**\n\n| Variable | Tipo | Default | Descripción |\n|---|---|---|---|\n| `BROWSER_ARGS` | string | `""` | Argumentos adicionales separados por coma |\n| `BROWSER_CONFIG_PRESET` | string | `""` | Preset: `performance`, `mobile`, `cicd`, `security_disabled` |\n| `BROWSER_CONFIG_FILE` | string | `""` | Ruta a archivo JSON con argumentos |\n| `BROWSER_MEMORY_LIMIT` | int (MB) | `4096` | Límite de memoria para el navegador |\n| `BROWSER_PROXY` | string | `""` | URL del proxy (ej: `http://proxy:8080`) |\n| `BROWSER_DOWNLOADS_DIR` | string | `downloads` | Directorio para archivos descargados |\n\n**Chrome/Chromium:**\n\n| Variable | Tipo | Default | Descripción |\n|---|---|---|---|\n| `CHROME_DISABLE_SECURITY` | bool | `false` | Desactivar seguridad web |\n| `CHROME_ENABLE_LOGGING` | bool | `false` | Activar logging del navegador |\n| `CHROME_LOG_LEVEL` | string | `INFO` | Nivel de log del navegador |\n| `CHROME_DISABLE_EXTENSIONS` | bool | `true` | Desactivar extensiones |\n| `CHROME_DISABLE_PLUGINS` | bool | `true` | Desactivar plugins |\n| `CHROME_DISABLE_IMAGES` | bool | `false` | No cargar imágenes (acelera pruebas) |\n| `CHROME_DISABLE_JAVASCRIPT` | bool | `false` | Desactivar JavaScript |\n\n**Firefox:**\n\n| Variable | Tipo | Default | Descripción |\n|---|---|---|---|\n| `FIREFOX_PROFILE_PATH` | string | `""` | Ruta a perfil personalizado |\n| `FIREFOX_DISABLE_ADDONS` | bool | `true` | Desactivar addons |\n| `FIREFOX_PRIVATE_MODE` | bool | `false` | Abrir en modo privado |\n\n---\n\n## Screenshots y Video\n\n**Screenshots:**\n\n| Variable | Tipo | Default | Descripción |\n|---|---|---|---|\n| `SCREENSHOTS_DIR` | str
4279ing | `reports/screenshots` | Directorio de screenshots |\n| `SCREENSHOT_FULL_PAGE` | bool | `false` | Capturar página completa o solo viewport |\n| `AUTO_SCREENSHOT_ON_FAILURE` | bool | `true` | Screenshot automático al fallar |\n| `HTML_REPORT_CAPTURE_ALL_STEPS` | bool | `true` | Capturar screenshot en cada step |\n| `CAPTURE_FRAMEWORK_STEPS` | bool | `false` | Capturar steps internos del framework |\n\n**Video:**\n\n| Variable | Tipo | Default | Descripción |\n|---|---|---|---|\n| `RECORD_VIDEO` | bool | `false` | Activar grabación de video |\n| `VIDEO_DIR` | string | `reports/videos` | Directorio de videos |\n| `VIDEO_SIZE` | string | `1280x720` | Resolución del video |\n| `VIDEO_MODE` | string | `retain-on-failure` | Cuándo guardar: `on`, `off`, `retain-on-failure` |\n| `VIDEO_INTRO_ENABLED` | bool | `true` | Habilitar intro en el video |\n| `CLEANUP_OLD_VIDEOS` | bool | `true` | Limpiar videos antiguos |\n| `VIDEO_MAX_AGE_HOURS` | int | `48` | Edad máxima de videos en horas |\n\n---\n\n## Reportes\n\n| Variable | Tipo | Default | Descripción |\n|---|---|---|---|\n| `USE_HTML_REPORT` | bool | `true` | Generar reporte HTML |\n| `HTML_REPORTS_DIR` | string | `reports/html-reports` | Directorio para reportes HTML |\n| `CLEANUP_OLD_FILES` | bool | `true` | Limpieza automática de archivos |\n| `CLEANUP_MODE` | string | `all` | Modo de limpieza: `all` o `old` |\n| `CLEANUP_MAX_AGE_HOURS` | int | `24` | Edad máxima en horas para modo `old` |\n\n**Reportes de IA:**\n\n| Variable | Tipo | Default | Descripción |\n|---|---|---|---|\n| `GENERATE_AI_REPORT` | bool | `true` | Generar reporte de validaciones de IA |\n| `AI_REPORT_PATH` | string | `reports/html-reports/ai-reports` | Directorio para reportes de IA |\n| `AI_REPORT_ANALYSIS` | bool | `true` | Usar Gemini para análisis automático |\n\n---\n\n## API Testing\n\n| Variable | Tipo | Default | Descripción |\n|---|---|---|---|\n| `API_BASE_URL` | string | `""` | URL base para testing de APIs |\n| `API_TIMEOUT` | int (s) | `30` | Timeout para requests HTTP |\n| `API_KEY` | string | `""` | API Key para autenticación |\n| `BEARER_TOKEN` | string | `""` | Bearer token para autenticación |\n\n---\n\n## Base de Datos\n\n| Variable | Tipo | Default | Descripción |\n|---|---|---|---|\n| `DB_TYPE` | string | `sqlite` | Tipo: `sqlite`, `mysql`, `postgresql` |\n| `DB_SQLITE_PATH` | string | `test_data/test.db` | Ruta al archivo SQLite |\n| `DB_SQLITE_TIMEOUT` | int (s) | `30` | Timeout de conexión SQLite |\n| `DB_CONNECTION_TIMEOUT` | int (s) | `30` | Timeout de conexión general |\n| `DB_QUERY_TIMEOUT` | int (s) | `60` | Timeout de queries |\n| `DB_AUTO_COMMIT` | bool | `true` | Auto-commit en escritura |\n| `DB_DEBUG_QUERIES` | bool | `false` | Mostrar queries en el log |\n\n**MySQL:**\n\n| Variable | Tipo | Default | Descripción |\n|---|---|---|---|\n| `DB_MYSQL_HOST` | string | `localhost` | Host |\n| `DB_MYSQL_PORT` | int | `3306` | Puerto |\n| `DB_MYSQL_DATABASE` | string | `test_db` | Base de datos |\n| `DB_MYSQL_USERNAME` | string | `test_user` | Usuario |\n| `DB_MYSQL_PASSWORD` | str
4279ing | `test_password` | Contraseña |\n| `DB_MYSQL_CHARSET` | string | `utf8mb4` | Charset |\n\n**PostgreSQL:**\n\n| Variable | Tipo | Default | Descripción |\n|---|---|---|---|\n| `DB_POSTGRES_HOST` | string | `localhost` | Host |\n| `DB_POSTGRES_PORT` | int | `5432` | Puerto |\n| `DB_POSTGRES_DATABASE` | string | `test_db` | Base de datos |\n| `DB_POSTGRES_USERNAME` | string | `test_user` | Usuario |\n| `DB_POSTGRES_PASSWORD` | string | `test_password` | Contraseña |\n| `DB_POSTGRES_SCHEMA` | string | `public` | Schema |\n\n---\n\n## Gemini AI (Juez GenAI)\n\n| Variable | Tipo | Default | Descripción |\n|---|---|---|---|\n| `GEMINI_API_KEY` | string | — | API Key de Google Gemini |\n| `GEMINI_JUDGE_MODEL` | string | `gemini-3.1-flash-lite-preview` | Modelo de Gemini |\n| `GEMINI_DEFAULT_THRESHOLD` | float | `0.8` | Umbral por defecto (0.0-1.0) |\n| `GEMINI_CACHE_TTL_HOURS` | int | `1` | TTL del caché en horas |\n| `GEMINI_JUDGE_PROMPT_FILE` | string | `""` | Ruta a prompt personalizado |\n\n**Valores recomendados para el umbral:**\n- `0.90 - 1.00`: Excelencia (muy estricto)\n- `0.80 - 0.89`: Bueno (recomendado para producción)\n- `0.70 - 0.79`: Aceptable (más permisivo)\n- `0.60 - 0.69`: Básico (desarrollo/testing)\n\n**Vectorización (Supabase):**\n\n| Variable | Tipo | Default | Descripción |\n|---|---|---|---|\n| `SUPABASE_URL` | string | `""` | URL de Supabase |\n| `SUPABASE_KEY` | string | `""` | Key de Supabase |\n\n---\n\n## Validación Semántica\n\n| Variable | Tipo | Default | Descripción |\n|---|---|---|---|\n| `SEMANTIC_MODEL` | string | `paraphrase-multilingual-MiniLM-L12-v2` | Modelo de Sentence Transformers |\n| `SEMANTIC_THRESHOLD` | float | `0.75` | Umbral de similitud (0.0-1.0) |\n| `HIDE_TRANSFORMERS_WARNINGS` | bool | `true` | Ocultar warnings de transformers |\n| `HIDE_HF_WARNINGS` | bool | `true` | Ocultar warnings de HuggingFace |\n| `HIDE_BEHAVE_WARNINGS` | bool | `true` | Ocultar warnings de Behave |\n\n**Modelos disponibles:**\n- `paraphrase-multilingual-MiniLM-L12-v2` — Multilingüe, balanceado (~420MB) — **Recomendado**\n- `paraphrase-multilingual-mpnet-base-v2` — Multilingüe, más preciso (~1GB)\n- `all-MiniLM-L6-v2` — Solo inglés, rápido (~80MB)\n\n---\n\n## OCR / Tesseract\n\n| Variable | Tipo | Default | Descripción |\n|---|---|---|---|\n| `OCR_ENGINE` | string | `auto` | Motor OCR: `auto`, `tesseract`, `easyocr` |\n| `OCR_LANGUAGES` | string | `en,es` | Idiomas para OCR |\n| `OCR_MIN_CONFIDENCE` | float | `70.0` | Confianza mínima para resultados |\n| `OCR_PREPROCESSING` | string | `default` | Preprocesamiento: `default`, `denoise`, `enhance`, `morphology` |\n| `TESSERACT_PATH` | string | `""` | Ruta al ejecutable de Tesseract |\n| `OCR_SAVE_PROCESSED_IMAGES` | bool | `false` | Guardar imágenes procesadas |\n| `OCR_DEBUG_MODE` | bool | `false` | Modo debug de OCR |\n\n---\n\n## Integraciones (Jira, Xray, Azure DevOps)\n\n**Jira:**\n\n| Variable | Tipo | Default | Descripción |\n|---|---|---|---|\n| `JIRA_ENABLED` | bool | `false` | Activar integración con Jira |\n| `JIRA_URL` | string | `""` | URL de la instancia Jira |\n| `JIRA_EMAIL` | string | `""` | Email de la cuenta Jira |\n| `JIRA_TOKEN` | string | `""` | API token de Jira |\n| `JIRA_PROJECT` | string | `""` | Clave del proyecto (ej: `PROJ`) |\n| `JIRA_COMMENT_MESSAGE` | string | `Reporte prueba de QA` | Mensaje para comentarios |\n\n**Xray:**\n\n| Variable | Tipo | Default | Descripción |\n|---|---|---|---|\n| `XRAY_ENABLED` | bool | `false` | Activar integración con Xray |\n| `XRAY_AUTHORIZATION_TOKEN` | string | `""` | Bearer token de Xray Cloud |\n| `XRAY_BASE_URL` | string | `https://xray.cloud.getxray.app` | URL base de Xray |\n\n**Azure DevOps:**\n\n| Variable | Tipo | Default | Descripción |\n|---|---|---|---|\n| `AZURE_DEVOPS_ENABLED` | bool | `false` | Activar integración |\n| `AZURE_DEVOPS_ORG` | string | `""` | Nombre de la organización |\n| `AZURE_DEVOPS_PROJECT` | string | `""` | Nombre del proyecto |\n| `AZURE_DEVOPS_PAT` | string | `""` | Personal Access Token |\n\n---\n\n## Paralelización\n\n| Variable | Tipo | Default | Descripción |\n|---|---|---|---|\n| `PARALLEL_WORKERS` | int | `1` | Número de workers paralelos |\n| `MAX_BROWSER_INSTANCES` | int | `1` | Máximo instancias de navegador |\n| `BROWSER_POOL_SIZE` | int | `5` | Tamaño del pool de navegadores |\n| `WORKER_TIMEOUT` | int (s) | `300` | Timeout por worker |\n| `SHARD_INDEX` | int | — | Índice del shard actual (CI/CD) |\n| `TOTAL_SHARDS` | int | — | Total de shards (CI/CD) |\n\n---\n\n## Modo Stealth\n\n| Variable | Tipo | Default | Descripción |\n|---|---|---|---|\n| `STEALTH_MODE` | bool | `false` | Activar modo anti-detección |\n\nOculta propiedades que delatan automatización. Út
4279il para evitar detección de bots. Requiere `playwright-stealth` (incluido en `requirements.txt`).\n\n---\n\n## Logging y Debug\n\n| Variable | Tipo | Default | Descripción |\n|---|---|---|---|\n| `LOG_LEVEL` | string | `INFO` | Nivel: `DEBUG`, `INFO`, `WARNING`, `ERROR` |\n| `HAKALAB_DEBUG` | bool | `true` | Mensajes de debug del framework |\n| `HAKALAB_SHOW_STEPS` | bool | `false` | Mostrar lista de steps cargados al iniciar |\n\n---\n\n## Datos de Prueba\n\n| Variable | Tipo | Default | Descripción |\n|---|---|---|---|\n| `TEST_EMAIL` | string | `""` | Email de prueba (`context.test_data[\'email\']`) |\n| `TEST_PASSWORD` | string | `""` | Contraseña de prueba |\n| `TEST_USER_NAME` | string | `""` | Nombre de usuario de prueba |\n\n---\n\n## Reintentos\n\n| Variable | Tipo | Default | Descripción |\n|---|---|---|---|\n| `RETRY_FAILED_STEPS` | int | `0` | Reintentos para steps fallidos |\n| `RETRY_FAILED_SCENARIOS` | bool | `false` | Reintentos automáticos de escenarios |\n| `MAX_SCENARIO_RETRIES` | int | `1` | Máximo reintentos por escenario |\n\n---\n\n## Notas Generales\n\n- No pongas comillas alrededor de los valores en el `.env`.\n- Las variables son CASE SENSITIVE.\n- Nunca commitees el `.env` con credenciales reales.\n- Las variables del `.env` tienen prioridad sobre las del sistema (`override=True`).'},{id:"environment-py",title:"Configurar environment.py",content:`## Environment.py Simple (Recomendado)
4280
4281El archivo \`features/environment.py\` es el punto de entrada del ciclo de vida de Behave. Inicializa el framework, maneja screenshots, reportes y limpieza de recursos.
4282
4283\`\`\`python
4284from hakalab_framework import setup_framework_context, setup_scenario_context
4285from hakalab_framework.core.screenshot_manager import take_screenshot_on_failure
4286from hakalab_framework.core.environment_config import auto_after_scenario, auto_after_all
4287from hakalab_framework.core.soft_assertion_hooks import (
4288    before_scenario_soft_assertions,
4289    after_step_soft_assertions,
4290    after_scenario_soft_assertions
4291)
4292from hakalab_framework.steps import *
4293
4294
4295def before_all(context):
4296    from hakalab_framework.core.screenshot_manager import cleanup_directories
4297    cleanup_directories()
4298    setup_framework_context(context)
4299
4300def before_scenario(context, scenario):
4301    if 'no_browser' in [tag.lower() for tag in getattr(scenario, 'tags', [])]:
4302        context.browser_disabled = True
4303    setup_scenario_context(context, scenario)
4304    before_scenario_soft_assertions(context, scenario)
4305
4306def after_step(context, step):
4307    after_step_soft_assertions(context, step)
4308
4309def after_scenario(context, scenario):
4310    try:
4311        after_scenario_soft_assertions(context, scenario)
4312    except AssertionError:
4313        pass
4314    take_screenshot_on_failure(context, scenario)
4315    auto_after_scenario(context, scenario)
4316
4317def after_all(context):
4318    if hasattr(context, 'framework_config') and context.framework_config:
4319        context.framework_config.cleanup()
4320    auto_after_all(context)
4321\`\`\`
4322
4323## Consideraciones
4324
4325- \`from hakalab_framework.steps import *\` es OBLIGATORIO — importa todos los steps.
4326- \`setup_framework_context(context)\` inicializa Playwright, variables, localizadores e integraciones.
4327- \`setup_scenario_context(context, scenario)\` crea o reutiliza la página del navegador.`},{id:"ejecucion",title:"Ejecución de Pruebas",content:`## Ejecución Directa con Behave
4328
4329\`\`\`bash
4330# Ejecutar todos los features
4331python -m behave
4332
4333# Ejecutar un feature específico
4334python -m behave features/demo.feature
4335
4336# Ejecutar con un tag específico
4337python -m behave --tags=@mi_tag
4338
4339# Ejecutar excluyendo tags
4340python -m behave --tags="not @wip"
4341
4342# Sin captura de output (ver prints en consola)
4343python -m behave --no-capture --no-skipped
4344\`\`\`
4345
4346## Ejecución con Runner.py
4347
4348El proyecto incluye un \`Runner.py\` que permite ejecutar pruebas con tags:
4349
4350\`\`\`bash
4351python Runner.py
4352\`\`\`
4353
4354> Por defecto el \`Runner.py\` ejecuta con el tag configurado internamente. Modifica la variable \`tags\` en el archivo según tus necesidades.
4355
4356## Configuración de Behave (behave.ini)
4357
4358\`\`\`ini
4359[behave]
4360paths = features
4361show_timings = true
4362show_skipped = false
4363logging_level = INFO
4364\`\`\`
4365
4366## Ejecución por Tags
4367
4368\`\`\`bash
4369# Combinar tags
4370behave --tags="@smoke and @login"
4371
4372# Un escenario específico por nombre
4373behave --name="Validar login con credenciales válidas"
4374
4375# Ejecución paralela (CLI del framework)
4376haka-run --workers=4 --features=features/
4377\`\`\``},{id:"tags-especiales",title:"Tags Especiales",content:`## Tags del Framework
4378
4379Los tags de Behave controlan el comportamiento del framework durante la ejecución:
4380
4381| Tag | Descripción |
4382|---|---|
4383| \`@no_browser\` | Desactiva la inicialización del navegador. Esencial para pruebas de API, BD, semántica o desktop. |
4384| \`@desktop\` | Indica que el escenario es una prueba de escritorio. Usar junto con \`@no_browser\`. |
4385| \`@mobile\` | Configura viewport móvil automáticamente (375x667). |
4386| \`@soft_assertions\` | Activa soft assertions para el escenario. Los fallos no detienen la ejecución. |
4387| \`@retry\` | Marca el escenario para reintento automático si falla (requiere \`RETRY_FAILED_SCENARIOS=true\`). |
4388| \`@JIRA-123\` | Vincula el escenario a una issue de Jira. El reporte se adjunta automáticamente. |
4389| \`@TEST-XXX\` | Integración con Xray (si está configurada). |
4390| \`@security\` | Activa la auditoría de seguridad pasiva (también \`@seguridad\` / \`@pentest\`). Funciona a nivel de escenario o feature. |
4391| \`@wip\` | Work in progress. Behave lo salta por defecto. |
4392| \`@skip\` | Salta el escenario. |
4393
4394## Auditoría de seguridad (\`@security\`)
4395
4396El tag \`@security\` audita el tráfico de red de la prueba y genera un reporte en \`reports/security/\` (JSON determinista + HTML). Revisa cabeceras de seguridad, cookies, CORS, mixed content y exposición de tecnología. No hace fallar el escenario salvo que uses los steps de aserción de seguridad.
4397
4398### Análisis con IA (opcional)
4399
4400El reporte HTML incluye un **análisis complementario con IA** solo si hay un proveedor de IA configurado en el \`.env\`. Usa las mismas variables que el resto del framework:
4401
4402\`\`\`env
4403AI_PROVIDER=gemini          # gemini | openai | anthropic | ollama
4404AI_MODEL=gemini-2.5-flash   # opcional (hay default por proveedor)
4405
4406# Credencial según el proveedor elegido:
4407GEMINI_API_KEY=...
4408OPENAI_API_KEY=...
4409ANTHROPIC_API_KEY=...
4410OLLAMA_BASE_URL=http://localhost:11434   # para Ollama local
4411\`\`\`
4412
4413Sin proveedor configurado, la auditoría igual genera el reporte determinista (JSON + HTML) y solo omite la sección "Análisis con IA". No existe una variable específica de seguridad para la IA.
4414
4415También puedes cambiar la carpeta de salida con \`SECURITY_REPORTS_DIR\` o desactivar la auditoría por completo con \`SECURITY_AUDIT_ENABLED=false\`.
4416
4417## Ejemplo de Uso
4418
4419\`\`\`gherkin
4420@no_browser @JIRA-456
4421Feature: Pruebas de API
4422
4423  @soft_assertions @retry
4424  Scenario: Validar endpoint de usuarios
4425    Given configuro la API base en "\${ENV.API_BASE_URL}"
4426    When realizo GET a "/usuarios"
4427    Then la respuesta deberia tener codigo "200"
4428\`\`\`
4429
4430\`\`\`gherkin
4431@desktop @no_browser
4432Feature: Pruebas de escritorio
4433
4434  Scenario: Verificar calculadora
4435    Given lanzo y espero "2" segundos la aplicacion "calc.exe"
4436    When hago click en la imagen "calculadora/boton_1"
4437\`\`\``}]},{id:"localizadores",title:"Localizadores",group:"Fundamentos",icon:"",topics:[{id:"json-poms",title:"JSON POMs",content:`## Qué es un JSON POM
4438
4439Los JSON POMs (Page Object Models en formato JSON) almacenan los selectores de elementos por página o módulo. Se leen desde la carpeta \`json_poms/\` y se exponen con \`$.ARCHIVO.elemento\`.
4440
4441### Ejemplo: json_poms/LOGIN.json
4442
4443\`\`\`json
4444{
4445  "input_usuario": "#username",
4446  "input_password": "#password",
4447  "btn_login": "button[type='submit']",
4448  "mensaje_error": ".alert-error",
4449  "link_recuperar": "a[href='/forgot-password']"
4450}
4451\`\`\`
4452
4453### Uso en el feature
4454
4455\`\`\`gherkin
4456When relleno el campo "usuario" con "admin" con identificador "$.LOGIN.input_usuario"
4457And relleno el campo "clave" con "1234" con identificador "$.LOGIN.input_password"
4458And hago click en el elemento "boton login" con identificador "$.LOGIN.btn_login"
4459\`\`\`
4460
4461## Tipos de Selectores Soportados
4462
4463\`\`\`json
4464{
4465  "por_id":         "#mi-elemento",
4466  "por_clase":      ".mi-clase",
4467  "por_css":        "button.primary[type='submit']",
4468  "por_xpath":      "//button[contains(text(),'Guardar')]",
4469  "por_atributo":   "[data-testid='submit-btn']",
4470  "por_name":       "[name='fieldName:REGION']"
4471}
4472\`\`\`
4473
4474## Formato por Tipo/Valor (Inferencia Automática)
4475
4476\`\`\`json
4477{
4478  "titulo": {"type": "text", "value": "Bienvenido"},
4479  "campo_email": {"type": "placeholder", "value": "Ingrese su email"},
4480  "contenedor": {"type": "id", "value": "main-container"},
4481  "boton": {"type": "class", "value": "btn-primary"},
4482  "custom": {"type": "data-testid", "value": "login-form"}
4483}
4484\`\`\`
4485
4486## Formato por Role (Accesibilidad)
4487
4488\`\`\`json
4489{
4490  "campo_nombre": {"role": "textbox", "type": "name", "value": "Ingresa tu nombre"},
4491  "boton_login": {"role": "button", "type": "exact", "value": "Login"}
4492}
4493\`\`\`
4494
4495## Formato con Fallbacks Automáticos
4496
4497\`\`\`json
4498{
4499  "btn_guardar": {
4500    "selector": "button.primary",
4501    "fallbacks": ["button[type='submit']", "//button[text()='Guardar']"]
4502  }
4503}
4504\`\`\`
4505
4506Si el selector principal no encuentra el elemento, el framework prueba cada fallback en orden.
4507
4508## Placeholders Dinámicos
4509
4510\`\`\`json
4511{
4512  "resultado_por_texto": "//*[contains(text(), '<valor>')]",
4513  "checkbox_por_indice": "(//input[@type='checkbox'])[<valor_int>]"
4514}
4515\`\`\`
4516
4517\`\`\`gherkin
4518When hago click en el elemento "resultado" con identificador "$.SEARCH.resultado_por_texto=Hola Mundo"
4519\`\`\``},{id:"localizadores-dinamicos",title:"Localizadores Dinámicos",content:`## Placeholders en Selectores
4520
4521Cuando el selector incluye un valor variable se usan placeholders que se reemplazan en tiempo de ejecución.
4522
4523\`\`\`json
4524{
4525  "fila_por_nombre": "//tr[td[contains(text(), '<valor>')]]",
4526  "opcion_select":   "option[value='<valor>']"
4527}
4528\`\`\`
4529
4530\`\`\`gherkin
4531When hago click en el elemento "fila Juan" con identificador "$.TABLA.fila_por_nombre=Juan Pérez"
4532\`\`\`
4533
4534## Índices para N-ésimo Elemento
4535
4536Cuando un selector retorna múltiples elementos, selecciona uno con \`[n]\` (índice desde 0).
4537
4538\`\`\`gherkin
4539When hago click en el elemento "primer resultado" con identificador "$.LISTA.item_lista[0]"
4540And hago click en el elemento "tercer resultado" con identificador "$.LISTA.item_lista[2]"
4541\`\`\`
4542
4543## Selectores Inline (sin JSON POM)
4544
4545Si el identificador NO comienza con \`$.\`, se trata como selector directo.
4546
4547\`\`\`gherkin
4548When hago click en el elemento "boton" con identificador "button.primary"
4549And relleno el campo "nombre" con "Ana" con identificador "#campo-nombre"
4550And hago click en el elemento "link" con identificador "//a[contains(text(),'Ver más')]"
4551\`\`\``},{id:"helpers-context",title:"Helpers de Contexto",content:'## Helpers para Custom Steps\n\nEl framework provee funciones helper en `context` para simplificar el uso de localizadores en pasos personalizados.\n\n```python\n@step(\'hago login rápido con "{user}" y "{password}"\')\ndef step_quick_login(context, user, password):\n    context.fill("$.LOGIN.input_usuario", user)\n    context.fill("$.LOGIN.input_password", password)\n    context.click("$.LOGIN.btn_login")\n    context.wait_for("$.DASHBOARD.panel_principal")\n```\n\n## Helpers Disponibles\n\n- `context.find()` — Retorna un Locator de Playwright\n- `context.find_all()` — Retorna lista de Locators\n- `context.click()` — Click en elemento\n- `context.fill()` — Rellenar campo (resuelve variables)\n- `context.get_text()` — Obtener text_content()\n- `context.is_visible()` — Verificar visibilidad\n- `context.wait_for()` — Esperar elemento visible\n- `context.hover()` — Hover sobre elemento\n- `context.select()` — Seleccionar opción\n- `context.check()` / `context.uncheck()` — Checkbox\n\n### Helpers Avanzados\n\n- `context.wait_and_click()`\n- `context.scroll_and_click()`\n- `context.retry_action()`\n- `context.conditional_action()`'}]},{id:"variables",title:"Variables",group:"Fundamentos",icon:"",topics:[{id:"variables-basico",title:"Crear y Usar Variables",content:`## Crear Variable con Valor Fijo
4552
4553\`\`\`gherkin
4554When creo la variable "nombre_usuario" con valor "Juan Pérez"
4555And relleno el campo "nombre" con "\${nombre_usuario}" con identificador "$.FORM.input_nombre"
4556\`\`\`
4557
4558## Variables Aleatorias
4559
4560\`\`\`gherkin
4561When genero una variable "codigo_otp" con número aleatorio entre 100000 y 999999
4562When genero una variable "usuario_temp" con texto aleatorio de 8 caracteres
4563\`\`\`
4564
4565## Variables de Fecha
4566
4567\`\`\`gherkin
4568When genero una variable "fecha_hoy" con fecha actual usando formato "%d/%m/%Y"
4569When genero una variable "fecha_vencimiento" con fecha actual en formato "%d/%m/%Y" sumando 5 días hábiles
4570\`\`\`
4571
4572## Variables de Entorno (.env)
4573
4574\`\`\`gherkin
4575Given voy a la url "\${ENV.BASE_URL}/login"
4576When relleno el campo "usuario" con "\${ENV.TEST_USER}" con identificador "$.LOGIN.input_user"
4577\`\`\`
4578
4579## Extraer Texto de un Elemento
4580
4581\`\`\`gherkin
4582When guardo el texto del elemento "$.RESULT.codigo" en la variable "codigo_generado"
4583Then verifico que la variable "codigo_generado" contiene "TXN-"
4584\`\`\`
4585
4586## Concatenar Variables
4587
4588\`\`\`gherkin
4589When creo la variable "cuenta_clp" con valor "CL123456789"
4590And concateno "AC S " y "\${cuenta_clp}" y lo guardo en la variable "busqueda_clp"
4591Then verifico que la variable "busqueda_clp" contiene "AC S CL123456789"
4592\`\`\``},{id:"variables-sintaxis",title:"Sintaxis de Variables",content:'## Regla de Oro\n\n**Variables existentes se referencian con `${nombre_variable}`**\n\nCuando quieres usar el **valor** de una variable que ya existe, debes usar: `${nombre_variable}`\n\n## Tabla Rápida de Referencia\n\n| Necesito... | Sintaxis | Ejemplo |\n|---|---|---|\n| Usar el VALOR de una variable | `${nombre}` | `relleno el campo "email" con "${email_usuario}"` |\n| Pasar el NOMBRE como parámetro | `nombre` (sin `${}`) | `verifico que la variable "email_usuario" contiene "@"` |\n| Crear una variable nueva | `"nombre"` (sin `${}`) | `creo la variable "resultado" con valor "42"` |\n| Guardar resultado en variable | `"nombre"` (sin `${}`) | `guardo el texto en la variable "titulo"` |\n| Concatenar variable + texto | `"texto" y "${variable}"` | `concateno "AC S " y "${cuenta}"` |\n\n## Ejemplo Completo\n\n```gherkin\nScenario: Encadenamiento de Variables\n  Given creo la variable "prefijo" con valor "USR"\n  And creo la variable "dominio" con valor "@miapp.com"\n  When concateno "${prefijo}" y "_admin" y lo guardo en la variable "username"\n  And concateno "${username}" y "${dominio}" y lo guardo en la variable "email"\n  And relleno el campo "email" con "${email}" con identificador "$.FORM.input_email"\n  Then verifico que la variable "email" contiene "@miapp.com"\n```\n\n**Variables resultantes:**\n- `prefijo` = "USR"\n- `username` = "USR_admin"\n- `email` = "[email protected]"'}]},{id:"pruebas-web",title:"Pruebas Web",group:"Tipos de Prueba",icon:"",topics:[{id:"steps-navegacion",title:"Inventario: Navegación",content:`## Navegación
4593
4594step: voy a la url "{url}"
4595descripcion: Navega a una URL específica y espera a que la página cargue completamente. Soporta variables y reintentos automáticos.
4596
4597step: voy hacia atrás
4598descripcion: Navega hacia atrás en el historial del navegador y espera a que la página cargue.
4599
4600step: voy hacia adelante
4601descripcion: Navega hacia adelante en el historial del navegador y espera a que la página cargue.
4602
4603step: recargo la página
4604descripcion: Recarga la página actual y espera a que cargue completamente.
4605
4606step: espero a que cargue la página
4607descripcion: Espera a que la página termine de cargar según la estrategia de espera configurada.
4608
4609step: abro una nueva pestaña
4610descripcion: Abre una nueva pestaña en el navegador con los timeouts configurados.
4611
4612step: cierro la pestaña actual
4613descripcion: Cierra la pestaña actualmente activa del navegador.
4614
4615step: cambio a la pestaña {tab_index:d}
4616descripcion: Cambia a una pestaña específica por su índice numérico.
4617
4618step: maximizo la ventana
4619descripcion: Maximiza la ventana del navegador estableciendo el viewport a 1920x1080.
4620
4621step: establezco el tamaño de ventana a {width:d}x{height:d}
4622descripcion: Establece el tamaño de la ventana del navegador a dimensiones específicas en píxeles.`},{id:"steps-interaccion",title:"Inventario: Interacción",content:`## Interacción con Elementos
4623
4624step: hago click en el elemento "{element_name}" con identificador "{identifier}"
4625descripcion: Hace click en un elemento web. Espera a que sea visible antes de hacer click y añade una pausa de estabilización.
4626
4627step: hago click en el select "{element_name}" con identificador "{identifier}"
4628descripcion: Hace click en un elemento select/combobox para abrirlo.
4629
4630step: hago doble click en el elemento "{element_name}" con identificador "{identifier}"
4631descripcion: Hace doble click en un elemento web específico.
4632
4633step: hago click derecho en el elemento "{element_name}" con identificador "{identifier}"
4634descripcion: Hace click derecho (menú contextual) en un elemento web.
4635
4636step: paso el mouse sobre el elemento "{element_name}" con identificador "{identifier}"
4637descripcion: Pasa el mouse sobre un elemento (hover) para activar efectos o menús desplegables.
4638
4639step: relleno el campo "{field_name}" con "{text}" con identificador "{identifier}"
4640descripcion: Rellena un campo de texto con el valor especificado. Soporta resolución de variables.
4641
4642step: relleno el campo de fecha "{field_name}" con "{date_text}" con identificador "{identifier}"
4643descripcion: Rellena un campo de fecha (input type="date") y dispara eventos de Angular. Acepta formatos DD-MM-YYYY y YYYY-MM-DD.
4644
4645step: limpio el campo "{field_name}" con identificador "{identifier}"
4646descripcion: Limpia completamente el contenido de un campo de texto.
4647
4648step: escribo "{text}" en el campo "{field_name}" con identificador "{identifier}"
4649descripcion: Escribe texto en un campo sin limpiar el contenido previo (append).
4650
4651step: selecciono la opción "{option}" del dropdown "{dropdown_name}" con identificador "{identifier}"
4652descripcion: Selecciona una opción de un dropdown/select por su texto visible.
4653
4654step: marco el checkbox "{checkbox_name}" con identificador "{identifier}"
4655descripcion: Marca un checkbox que está desmarcado.
4656
4657step: desmarco el checkbox "{checkbox_name}" con identificador "{identifier}"
4658descripcion: Desmarca un checkbox que está marcado.
4659
4660step: subo el archivo "{file_path}" al campo "{field_name}" con identificador "{identifier}"
4661descripcion: Sube un archivo al campo de tipo file especificado.
4662
4663step: remuevo el atributo "{attribute_name}" del elemento "{element_name}" con identificador "{identifier}"
4664descripcion: Remueve un atributo HTML de un elemento usando JavaScript (ej: readonly, disabled).
4665
4666step: establezco el atributo "{attribute_name}" a "{attribute_value}" en el elemento "{element_name}" con identificador "{identifier}"
4667descripcion: Establece o modifica un atributo HTML de un elemento usando JavaScript.
4668
4669step: verifico que el elemento "{element_name}" con identificador "{identifier}" tiene el atributo "{attribute_name}"
4670descripcion: Verifica que un elemento tiene un atributo HTML específico presente.
4671
4672step: verifico que el elemento "{element_name}" con identificador "{identifier}" no tiene el atributo "{attribute_name}"
4673descripcion: Verifica que un elemento NO tiene un atributo HTML específico.
4674
4675step: obtengo el atributo "{attribute_name}" del elemento "{element_name}" con identificador "{identifier}" y lo guardo en la variable "{variable_name}"
4676descripcion: Obtiene el valor de un atributo HTML de un elemento y lo guarda en una variable del framework.
4677
4678step: selecciono la fecha "{date_text}" en el input de fecha "{identifier}"
4679descripcion: Selecciona una fecha en un input nativo de tipo date, disparando eventos de Angular para validación.
4680
4681step: abro el calendario y relleno el campo de fecha "{field_name}" con "{date_text}" con identificador "{identifier}"
4682descripcion: Abre el calendario nativo del navegador y rellena el campo de fecha, disparando todos los eventos necesarios.
4683
4684step: abro el calendario html desde el icono derecho con localizador "{identifier}"
4685descripcion: Abre un calendario HTML haciendo click en el icono del borde derecho del campo de fecha.
4686
4687step: presiono desde el teclado "{key}"
4688descripcion: Presiona una tecla específica del teclado con mapeo de teclas especiales (Enter, Escape, flechas, etc.).`},{id:"steps-esperas",title:"Inventario: Esperas",content:`## Esperas
4689
4690step: espero a que el elemento "{element_name}" sea visible con identificador "{identifier}"
4691descripcion: Espera a que un elemento sea visible en la página antes de continuar.
4692
4693step: espero a que el elemento "{element_name}" esté oculto con identificador "{identifier}"
4694descripcion: Espera a que un elemento esté oculto o desaparezca de la vista.
4695
4696step: espero a que el elemento "{element_name}" esté habilitado con identificador "{identifier}"
4697descripcion: Espera a que un elemento esté habilitado (no disabled) para interactuar con él.
4698
4699step: espero a que el elemento "{element_name}" contenga el texto "{text}" con identificador "{identifier}"
4700descripcion: Espera a que un elemento contenga un texto específico en su contenido.
4701
4702step: espero a que la url de la página contenga "{url_part}"
4703descripcion: Espera a que la URL actual del navegador contenga una parte específica de texto.
4704
4705step: espero a que el título de la página sea "{title}"
4706descripcion: Espera a que el título de la página sea exactamente el texto especificado.
4707
4708step: espero a que la red esté inactiva
4709descripcion: Espera a que no haya peticiones de red activas (networkidle).
4710
4711step: espero a que el contenido del DOM esté cargado
4712descripcion: Espera a que el evento DOMContentLoaded se haya disparado.
4713
4714step: espero a que el elemento "{element_name}" sea clickeable con identificador "{identifier}"
4715descripcion: Espera a que un elemento sea visible, esté adjunto al DOM y no esté deshabilitado.
4716
4717step: espero a que el select "{element_name}" tenga opciones con identificador "{identifier}"
4718descripcion: Espera a que un select tenga opciones cargadas (al menos 2, asumiendo que la primera es placeholder).
4719
4720step: espero a que el select "{element_name}" tenga al menos {count:d} opciones con identificador "{identifier}"
4721descripcion: Espera a que un select tenga al menos N opciones cargadas.
4722
4723step: espero a que la tabla "{element_name}" tenga filas con identificador "{identifier}"
4724descripcion: Espera a que una tabla tenga al menos una fila de datos cargada en el tbody.
4725
4726step: espero a que la tabla "{element_name}" tenga al menos {count:d} filas con identificador "{identifier}"
4727descripcion: Espera a que una tabla tenga al menos N filas de datos.
4728
4729step: espero a que la lista "{element_name}" tenga elementos con identificador "{identifier}"
4730descripcion: Espera a que una lista (ul/ol) tenga al menos un elemento li cargado.
4731
4732step: espero a que el elemento "{element_name}" tenga elementos hijos con identificador "{identifier}"
4733descripcion: Espera a que un elemento tenga al menos un elemento hijo cargado.
4734
4735step: espero a que el elemento "{element_name}" tenga el atributo "{attribute}" en identificador "{identifier}"
4736descripcion: Espera a que un elemento tenga un atributo HTML específico presente.
4737
4738step: espero a que el elemento "{element_name}" tenga el atributo "{attribute}" con valor "{value}" con identificador "{identifier}"
4739descripcion: Espera a que un atributo de un elemento tenga un valor específico.
4740
4741step: espero a que el campo "{element_name}" tenga valor con identificador "{identifier}"
4742descripcion: Espera a que un campo de entrada tenga algún valor (no esté vacío).
4743
4744step: espero a que el campo "{element_name}" tenga el valor "{value}" con identificador "{identifier}"
4745descripcion: Espera a que un campo de entrada tenga un valor específico.
4746
4747step: espero a que el elemento "{element_name}" tenga la clase "{css_class}" con identificador "{identifier}"
4748descripcion: Espera a que un elemento tenga una clase CSS específica en su classList.
4749
4750step: espero a que el elemento "{element_name}" no tenga la clase "{css_class}" con identificador "{identifier}"
4751descripcion: Espera a que un elemento NO tenga una clase CSS específica. Útil para esperar fin de loading.
4752
4753step: espero a que haya al menos {count:d} elementos que coinciden con "{element_name}" con identificador "{identifier}"
4754descripcion: Espera a que haya al menos N elementos que coincidan con el selector dado.
4755
4756step: espero a que haya exactamente {count:d} elementos que coinciden con "{element_name}" con identificador "{identifier}"
4757descripcion: Espera a que haya exactamente N elementos que coincidan con el selector.
4758
4759step: espero a que el elemento "{element_name}" no esté vacío con identificador "{identifier}"
4760descripcion: Espera a que un elemento tenga contenido de texto (textContent no vacío).
4761
4762step: espero a que el elemento "{element_name}" deje de cambiar con identificador "{identifier}"
4763descripcion: Espera a que el contenido de un elemento se estabilice (no cambie durante 500ms). Útil para contadores y loaders.
4764
4765step: espero a que el spinner de carga desaparezca con identificador "{identifier}"
4766descripcion: Espera a que un spinner/loader desaparezca de la vista.
4767
4768step: espero a que el elemento "{element_name}" sea removido del DOM con identificador "{identifier}"
4769descripcion: Espera a que un elemento sea completamente removido del DOM.
4770
4771step: espero {seconds:d} segundos
4772descripcion: Espera un número específico de segundos. Usar solo cuando sea estrictamente necesario.
4773
4774step: espero {milliseconds:d} milisegundos
4775descripcion: Espera un número específico de milisegundos.`}
4775,{id:"steps-esperas-avanzadas",title:"Inventario: Esperas Avanzadas y Tiempos",content:`## Esperas Avanzadas y Tiempos
4776
4777Esperas condicionales por selector, pausas, esperas aleatorias/progresivas y cronómetros. Prefiere estas esperas inteligentes por sobre \`espero N segundos\` fijo.
4778
4779### Pausas y esperas por tiempo
4780
4781step: pauso {seconds:d} segundos
4782descripcion: Pausa un número específico de segundos (alternativa a espero).
4783
4784step: pauso {milliseconds:d} milisegundos
4785descripcion: Pausa un número específico de milisegundos (alternativa a espero).
4786
4787step: espero aleatoriamente entre {min_seconds:d} y {max_seconds:d} segundos
4788descripcion: Espera un tiempo aleatorio entre dos valores (útil para simular comportamiento humano).
4789
4790step: espero progresivamente: {wait_pattern}
4791descripcion: Espera con un patrón progresivo de tiempos (ej: "1,2,3,5" segundos).
4792
4793step: establezco el timeout global en {timeout:d} segundos
4794descripcion: Establece el timeout global para las operaciones de espera.
4795
4796### Esperas condicionales por selector
4797
4798step: espero hasta que el elemento "{selector}" sea visible
4799descripcion: Espera hasta que un elemento sea visible.
4800
4801step: espero hasta que el elemento "{selector}" desaparezca
4802descripcion: Espera hasta que un elemento desaparezca del DOM o deje de ser visible.
4803
4804step: espero hasta que el elemento "{selector}" esté habilitado
4805descripcion: Espera hasta que un elemento esté habilitado (no disabled).
4806
4807step: espero hasta que el elemento "{selector}" contenga el texto "{expected_text}"
4808descripcion: Espera hasta que un elemento contenga un texto específico.
4809
4810step: espero hasta que el elemento "{selector}" tenga el atributo "{attribute}" con valor "{expected_value}"
4811descripcion: Espera hasta que un elemento tenga un atributo con un valor específico.
4812
4813step: espero hasta que el elemento "{selector}" no esté en estado de carga
4814descripcion: Espera hasta que un elemento salga de un estado de carga (spinner/busy).
4815
4816step: espero con timeout de {timeout:d} segundos hasta que "{selector}" sea visible
4817descripcion: Espera a que un elemento sea visible con un timeout personalizado.
4818
4819step: espero hasta que haya {count:d} elementos "{selector}"
4820descripcion: Espera hasta que haya un número específico de elementos (con número literal).
4821
4822step: espero hasta que haya en total {count_text} elementos "{selector}"
4823descripcion: Espera hasta que haya un número específico de elementos (soporta variables).
4824
4825### Esperas de página, red y URL
4826
4827step: espero hasta que la página termine de cargar
4828descripcion: Espera hasta que la página termine de cargar completamente.
4829
4830step: espero hasta que no haya requests de red pendientes
4831descripcion: Espera hasta que no haya actividad de red pendiente.
4832
4833step: espero hasta que la URL contenga "{url_part}"
4834descripcion: Espera hasta que la URL contenga una parte específica.
4835
4836### Cronómetros
4837
4838step: marco el tiempo de inicio como "{timer_name}"
4839descripcion: Inicia un cronómetro con un nombre específico.
4840
4841step: verifico que el cronómetro "{timer_name}" no exceda {max_seconds:d} segundos
4842descripcion: Verifica que un cronómetro no exceda un tiempo máximo.
4843
4844step: muestro el tiempo transcurrido del cronómetro "{timer_name}"
4845descripcion: Muestra el tiempo transcurrido de un cronómetro.`},{id:"steps-scroll",title:"Inventario: Scroll",content:`## Scroll
4846
4847step: hago scroll al elemento "{element_name}" con identificador "{identifier}"
4848descripcion: Hace scroll hasta que un elemento específico sea visible en el viewport.
4849
4850step: hago scroll al inicio de la página
4851descripcion: Hace scroll hasta el inicio (top) de la página.
4852
4853step: hago scroll al final de la página
4854descripcion: Hace scroll hasta el final (bottom) de la página.
4855
4856step: hago scroll hacia abajo {pixels:d} píxeles
4857descripcion: Hace scroll hacia abajo un número específico de píxeles.
4858
4859step: hago scroll hacia arriba {pixels:d} píxeles
4860descripcion: Hace scroll hacia arriba un número específico de píxeles.
4861
4862step: hago scroll hacia la izquierda {pixels:d} píxeles
4863descripcion: Hace scroll horizontal hacia la izquierda un número específico de píxeles.
4864
4865step: hago scroll hacia la derecha {pixels:d} píxeles
4866descripcion: Hace scroll horizontal hacia la derecha un número específico de píxeles.
4867
4868step: hago scroll del elemento "{element_name}" hacia abajo {pixels:d} píxeles con identificador "{identifier}"
4869descripcion: Hace scroll hacia abajo dentro de un elemento con overflow (contenedor scrollable).
4870
4871step: hago scroll del elemento "{element_name}" hacia arriba {pixels:d} píxeles con identificador "{identifier}"
4872descripcion: Hace scroll hacia arriba dentro de un elemento con overflow (contenedor scrollable).`},{id:"steps-ventanas-frames",title:"Inventario: Ventanas y Frames",content:`## Ventanas y Frames
4873
4874step: cambio a la nueva ventana
4875descripcion: Cambia el contexto a la ventana/pestaña más reciente que se haya abierto. Espera hasta 30 segundos.
4876
4877step: cierro la ventana actual
4878descripcion: Cierra la ventana actual y cambia a la primera ventana disponible.
4879
4880step: cambio a la ventana con título "{title}"
4881descripcion: Cambia a una ventana específica buscando por título (búsqueda parcial, case-insensitive). Espera hasta 30 segundos.
4882
4883step: cambio a la ventana con url que contiene "{url_part}"
4884descripcion: Cambia a una ventana cuya URL contenga el texto especificado. Espera hasta 30 segundos si no existe aún.
4885
4886step: acepto la alerta simple
4887descripcion: Acepta (OK) una alerta de JavaScript esperando a que aparezca.
4888
4889step: rechazo la alerta
4890descripcion: Rechaza (Cancel) una alerta de JavaScript esperando a que aparezca.
4891
4892step: acepto la alerta con texto "{text}"
4893descripcion: Acepta una alerta de tipo prompt enviando un texto específico.
4894
4895step: obtengo el texto de la alerta y lo guardo en la variable "{variable_name}"
4896descripcion: Captura el mensaje de una alerta, lo guarda en una variable y acepta el diálogo.
4897
4898step: cambio al frame "{frame_name}" con identificador "{identifier}"
4899descripcion: Cambia el contexto de ejecución a un frame/iframe específico.
4900
4901step: cambio al contenido principal
4902descripcion: Vuelve al contenido principal de la página, saliendo de cualquier iframe.
4903
4904step: salgo del frame
4905descripcion: Alias para volver al contenido principal, saliendo del iframe actual.
4906
4907step: tomo una captura de pantalla y la guardo como "{filename}"
4908descripcion: Toma una captura de pantalla de la página completa y la guarda con el nombre especificado.
4909
4910step: tomo una captura del elemento "{element_name}" y la guardo como "{filename}" con identificador "{identifier}"
4911descripcion: Toma una captura de pantalla de un elemento específico.
4912
4913step: el mensaje de la alerta debería ser "{expected_text}"
4914descripcion: Verifica que el mensaje de una alerta sea exactamente igual al texto esperado.
4915
4916step: el mensaje de la alerta debería contener "{expected_text}"
4917descripcion: Verifica que el mensaje de una alerta contenga un texto parcial.
4918
4919step: guardo el mensaje de la alerta en la variable "{variable_name}"
4920descripcion: Guarda el mensaje de una alerta en una variable y acepta el diálogo.
4921
4922step: extraigo el texto del diálogo lo guardo en la variable "{variable_name}" y cierro el diálogo
4923descripcion: Captura el texto de un diálogo usando listener, lo guarda en variable y cierra el diálogo. Desactiva listeners anteriores.`},{id:"steps-iframes",title:"Inventario: iFrames",content:`## iFrames
4924
4925step: cambio al iframe "{iframe_name}" con identificador "{identifier}"
4926descripcion: Cambia el contexto al iframe especificado usando su identificador. Guarda referencia en el stack de frames.
4927
4928step: cambio al iframe por nombre "{name}"
4929descripcion: Cambia al iframe buscando por su atributo name.
4930
4931step: cambio al iframe por src que contiene "{src_part}"
4932descripcion: Cambia al iframe buscando por parte de su URL src.
4933
4934step: cambio al iframe por índice "{index}"
4935descripcion: Cambia al iframe por su posición/índice en la página (basado en 0).
4936
4937step: regreso al frame padre
4938descripcion: Regresa al frame padre en la jerarquía de iframes.
4939
4940step: hago click en el elemento "{element_name}" dentro del iframe con identificador "{identifier}"
4941descripcion: Hace click en un elemento dentro del iframe actualmente activo.
4942
4943step: relleno el campo "{field_name}" con "{text}" dentro del iframe con identificador "{identifier}"
4944descripcion: Rellena un campo de texto dentro del iframe actualmente activo.
4945
4946step: debería ver texto "{text}" dentro del iframe
4947descripcion: Verifica que un texto sea visible dentro del iframe actual.
4948
4949step: debería ver el elemento "{element_name}" dentro del iframe con identificador "{identifier}"
4950descripcion: Verifica que un elemento sea visible dentro del iframe actual.
4951
4952step: espero a que cargue el iframe "{iframe_name}" con identificador "{identifier}"
4953descripcion: Espera a que un iframe sea visible y termine de cargar.
4954
4955step: ejecuto javascript "{script}" dentro del iframe
4956descripcion: Ejecuta código JavaScript dentro del contexto del iframe actual.
4957
4958step: obtengo el número de iframes y lo guardo en la variable "{variable_name}"
4959descripcion: Cuenta el número total de iframes en la página y guarda el resultado en una variable.
4960
4961step: verifico que existe el iframe "{iframe_name}" con identificador "{identifier}"
4962descripcion: Verifica que un iframe existe y es visible en la página.
4963
4964step: verifico que el iframe "{iframe_name}" tiene src "{expected_src}" con identificador "{identifier}"
4965descripcion: Verifica que un iframe tiene una URL src específica.`},{id:"steps-teclado-mouse",title:"Inventario: Teclado y Mouse",content:`## Teclado y Mouse
4966
4967step: pulso la tecla "{key}"
4968descripcion: Presiona una tecla específica del teclado.
4969
4970step: presiono la combinación de teclas "{keys}"
4971descripcion: Presiona una combinación de teclas (ej: Ctrl+C, Alt+Tab) manteniendo los modificadores.
4972
4973step: escribo el texto "{text}" con retraso de "{delay}" ms entre caracteres
4974descripcion: Escribe texto carácter por carácter con un retraso específico entre cada uno.
4975
4976step: mantengo presionada la tecla "{key}" por "{duration}" segundos
4977descripcion: Mantiene presionada una tecla por un tiempo específico y luego la suelta.
4978
4979step: hago click en las coordenadas x="{x}" y="{y}"
4980descripcion: Hace click en coordenadas específicas de la página.
4981
4982step: hago doble click en las coordenadas x="{x}" y="{y}"
4983descripcion: Hace doble click en coordenadas específicas de la página.
4984
4985step: hago click derecho en las coordenadas x="{x}" y="{y}"
4986descripcion: Hace click derecho en coordenadas específicas de la página.
4987
4988step: muevo el mouse a las coordenadas x="{x}" y="{y}"
4989descripcion: Mueve el cursor del mouse a coordenadas específicas sin hacer click.
4990
4991step: hago scroll con la rueda del mouse "{direction}" por "{steps}" pasos
4992descripcion: Hace scroll usando la rueda del mouse en dirección up o down por N pasos.
4993
4994step: realizo gesto de mouse desde x="{start_x}" y="{start_y}" hasta x="{end_x}" y="{end_y}"
4995descripcion: Realiza un gesto de arrastre con el mouse desde un punto hasta otro (mousedown, move, mouseup).
4996
4997step: simulo el atajo de teclado "{shortcut}" en el elemento "{element_name}" con identificador "{identifier}"
4998descripcion: Simula un atajo de teclado en un elemento específico, enfocándolo primero.
4999
5000step: selecciono todo el texto con Ctrl+A
5001descripcion: Selecciona todo el texto de la página o del elemento enfocado.
5002
5003step: copio el texto seleccionado con Ctrl+C
5004descripcion: Copia el texto actualmente seleccionado al portapapeles.
5005
5006step: pego el texto con Ctrl+V
5007descripcion: Pega el contenido del portapapeles en el elemento enfocado.
5008
5009step: corto el texto con Ctrl+X
5010descripcion: Corta el texto seleccionado (lo copia y elimina).
5011
5012step: deshago la acción con Ctrl+Z
5013descripcion: Deshace la última acción realizada.
5014
5015step: rehago la acción con Ctrl+Y
5016descripcion: Rehace la última acción deshecha.
5017
5018step: navego con la tecla Tab "{times}" veces
5019descripcion: Navega entre elementos usando la tecla Tab un número específico de veces.
5020
5021step: navego con Shift+Tab "{times}" veces
5022descripcion: Navega hacia atrás entre elementos usando Shift+Tab.
5023
5024step: pulso la tecla Enter
5025descripcion: Presiona la tecla Enter.
5026
5027step: presiono la tecla Escape
5028descripcion: Presiona la tecla Escape.
5029
5030step: presiono la tecla Espacio
5031descripcion: Presiona la tecla Espacio.
5032
5033step: presiono la tecla de flecha "{direction}"
5034descripcion: Presiona una tecla de flecha específica (up, down, left, right o arriba, abajo, izquierda, derecha).
5035
5036step: escribo el texto "{text}" y presiono Enter
5037descripcion: Escribe texto y presiona Enter inmediatamente después.
5038
5039step: limpio el campo actual con Ctrl+A y Delete
5040descripcion: Limpia el campo actualmente enfocado seleccionando todo y borrando.
5041
5042step: simulo escritura humana con el texto "{text}" y retrasos aleatorios
5043descripcion: Simula escritura humana con retrasos aleatorios entre 50-200ms entre caracteres.
5044
5045step: incremento el campo numérico "{field_name}" "{times}" veces con identificador "{identifier}"
5046descripcion: Incrementa el valor de un campo numérico presionando ArrowUp N veces.
5047
5048step: decremento el campo numérico "{field_name}" "{times}" veces con identificador "{identifier}"
5049descripcion: Decrementa el valor de un campo numérico presionando ArrowDown N veces.`},{id:"steps-drag-drop",title:"Inventario: Drag and Drop",content:`## Drag and Drop
5050
5051step: arrastro el elemento "{source_element}" al elemento "{target_element}" con identificadores "{source_id}" y "{target_id}"
5052descripcion: Arrastra un elemento y lo suelta en otro usando movimiento de mouse manual con pausas.
5053
5054step: arrastro el elemento "{element_name}" por desplazamiento x="{x}" y="{y}" con identificador "{identifier}"
5055descripcion: Arrastra un elemento por un desplazamiento relativo en píxeles desde su posición actual.
5056
5057step: arrastro el elemento "{element_name}" a las coordenadas x="{x}" y="{y}" con identificador "{identifier}"
5058descripcion: Arrastra un elemento a coordenadas absolutas específicas en la página.
5059
5060step: empiezo a arrastrar el elemento "{element_name}" con identificador "{identifier}"
5061descripcion: Inicia el arrastre de un elemento (mousedown) para operaciones de drag complejas en múltiples pasos.
5062
5063step: muevo el elemento arrastrado a las coordenadas x="{x}" y="{y}"
5064descripcion: Mueve un elemento que está siendo arrastrado a nuevas coordenadas.
5065
5066step: suelto el elemento arrastrado
5067descripcion: Suelta el elemento que está siendo arrastrado (mouseup).
5068
5069step: paso el mouse sobre el elemento antes de arrastrar "{element_name}" con identificador "{identifier}"
5070descripcion: Pasa el mouse sobre un elemento antes de arrastrarlo. Útil para elementos que requieren hover previo.
5071
5072step: arrastro lentamente el elemento "{element_name}" al elemento "{target_element}" con identificadores "{source_id}" y "{target_id}"
5073descripcion: Drag and drop con movimiento lento en 20 pasos intermedios. Útil para elementos sensibles al movimiento.
5074
5075step: verifico que el drag and drop fue exitoso comprobando la posición del elemento "{element_name}" con identificador "{identifier}"
5076descripcion: Verifica que un drag and drop fue exitoso comprobando que el elemento tiene una posición válida.
5077
5078step: verifico que el elemento "{element_name}" está en la posición x="{x}" y="{y}" con identificador "{identifier}"
5079descripcion: Verifica que un elemento está en una posición específica con tolerancia de 10 píxeles.
5080
5081step: arrastro y suelto el archivo "{file_path}" al elemento "{element_name}" con identificador "{identifier}"
5082descripcion: Arrastra y suelta un archivo en un elemento para uploads (usa set_input_files).
5083
5084step: arrastro el elemento "{source_element}" al elemento "{target_element}" usando API nativa con identificadores "{source_id}" y "{target_id}"
5085descripcion: Arrastra un elemento usando la API nativa drag_to de Playwright con fallback a método manual.
5086
5087step: realizo drag and drop avanzado desde "{source_element}" hasta "{target_element}" con identificadores "{source_id}" y "{target_id}"
5088descripcion: Drag and drop avanzado con múltiples métodos de fallback (API nativa, manual, HTML5).
5089
5090step: simulo drag and drop con HTML5 desde "{source_element}" hasta "{target_element}" con identificadores "{source_id}" y "{target_id}"
5091descripcion: Simula drag and drop HTML5 usando JavaScript con soporte para CSS, XPath e identificadores del framework.`},{id:"steps-formularios",title:"Inventario: Formularios",content:`## Formularios
5092
5093step: envío el formulario "{form_name}" con identificador "{identifier}"
5094descripcion: Envía un formulario ejecutando form.submit() vía JavaScript.
5095
5096step: reseteo el formulario "{form_name}" con identificador "{identifier}"
5097descripcion: Resetea un formulario a sus valores por defecto usando form.reset().
5098
5099step: relleno el formulario con datos de la variable "{data_variable}" para formulario "{form_name}" con identificador "{identifier}"
5100descripcion: Rellena un formulario completo con datos de una variable JSON, detectando automáticamente el tipo de cada campo.
5101
5102step: obtengo los datos del formulario y los guardo en la variable "{variable_name}" para formulario "{form_name}" con identificador "{identifier}"
5103descripcion: Extrae todos los datos de un formulario usando FormData y los guarda como JSON en una variable.
5104
5105step: valido el formulario "{form_name}" con identificador "{identifier}"
5106descripcion: Valida un formulario usando la validación HTML5 nativa (checkValidity).
5107
5108step: verifico los campos requeridos en el formulario "{form_name}" con identificador "{identifier}"
5109descripcion: Verifica que todos los campos marcados como required estén completados.
5110
5111step: establezco el campo "{field_name}" como solo lectura en formulario "{form_name}" con identificador de formulario "{form_id}" y identificador de campo "{field_id}"
5112descripcion: Establece un campo como solo lectura (readOnly = true).
5113
5114step: habilito el campo "{field_name}" en formulario "{form_name}" con identificador de formulario "{form_id}" y identificador de campo "{field_id}"
5115descripcion: Habilita un campo de formulario removiendo disabled y readOnly.
5116
5117step: deshabilito el campo "{field_name}" en formulario "{form_name}" con identificador de formulario "{form_id}" y identificador de campo "{field_id}"
5118descripcion: Deshabilita un campo de formulario (disabled = true).
5119
5120step: auto-relleno el formulario "{form_name}" con datos de prueba usando identificador "{identifier}"
5121descripcion: Auto-rellena un formulario con datos de prueba comunes (email, nombre, teléfono, dirección, etc.).
5122
5123step: limpio todos los campos del formulario "{form_name}" con identificador "{identifier}"
5124descripcion: Limpia todos los campos de un formulario (inputs, selects, textareas, checkboxes, radios).`},{id:"steps-navegador",title:"Inventario: Control del Navegador",content:`## Control del Navegador
5125
5126step: establezco la cookie "{name}" con valor "{value}"
5127descripcion: Establece una cookie específica en el contexto del navegador.
5128
5129step: obtengo la cookie "{name}" y la guardo en la variable "{variable_name}"
5130descripcion: Obtiene el valor de una cookie y lo guarda en una variable.
5131
5132step: elimino la cookie "{name}"
5133descripcion: Elimina una cookie específica del navegador.
5134
5135step: limpio todas las cookies
5136descripcion: Elimina todas las cookies del contexto del navegador.
5137
5138step: establezco el item de localStorage "{key}" con valor "{value}"
5139descripcion: Establece un item en el localStorage del navegador.
5140
5141step: obtengo el item de localStorage "{key}" y lo guardo en la variable "{variable_name}"
5142descripcion: Obtiene un item del localStorage y lo guarda en una variable.
5143
5144step: elimino el item de localStorage "{key}"
5145descripcion: Elimina un item específico del localStorage.
5146
5147step: limpio el localStorage
5148descripcion: Limpia completamente el localStorage del navegador.
5149
5150step: establezco el item de sessionStorage "{key}" con valor "{value}"
5151descripcion: Establece un item en el sessionStorage del navegador.
5152
5153step: obtengo el item de sessionStorage "{key}" y lo guardo en la variable "{variable_name}"
5154descripcion: Obtiene un item del sessionStorage y lo guarda en una variable.
5155
5156step: limpio el sessionStorage
5157descripcion: Limpia completamente el sessionStorage del navegador.
5158
5159step: ejecuto JavaScript "{script}" y guardo el resultado en la variable "{variable_name}"
5160descripcion: Ejecuta JavaScript personalizado en la página y guarda el resultado en una variable.
5161
5162step: ejecuto el siguiente JavaScript y guardo el resultado en la variable "{variable_name}"
5163descripcion: Ejecuta JavaScript multilínea (desde context.text) y guarda el resultado. Envuelve automáticamente en función si contiene return.
5164
5165step: establezco el viewport del navegador a "{width}x{height}"
5166descripcion: Establece el tamaño del viewport del navegador a dimensiones específicas.
5167
5168step: habilito JavaScript
5169descripcion: Paso informativo que indica que JavaScript está habilitado (por defecto en Playwright).
5170
5171step: deshabilito JavaScript
5172descripcion: Paso informativo sobre deshabilitar JavaScript (requiere reiniciar contexto).
5173
5174step: establezco el user agent a "{user_agent}"
5175descripcion: Establece un user agent personalizado para las peticiones HTTP.
5176
5177step: obtengo el user agent actual y lo guardo en la variable "{variable_name}"
5178descripcion: Obtiene el user agent actual del navegador y lo guarda en una variable.
5179
5180step: simulo la condición de red "{condition}"
5181descripcion: Simula condiciones de red como slow_3g, fast_3g u offline.
5182
5183step: limpio la caché del navegador
5184descripcion: Limpia la caché del navegador usando la API de caches.
5185
5186step: bloqueo el tipo de recurso "{resource_type}"
5187descripcion: Bloquea un tipo específico de recurso (images, scripts, stylesheets, etc.) interceptando las peticiones.
5188
5189step: desbloqueo todos los recursos
5190descripcion: Desbloquea todos los recursos previamente bloqueados.
5191
5192step: desactivo el navegador para esta prueba
5193descripcion: Desactiva el navegador para pruebas que no lo necesitan (API, validación semántica). Evita screenshots innecesarios.
5194
5195step: no necesito navegador para esta prueba
5196descripcion: Alias para desactivar el navegador en pruebas que no requieren UI.
5197
5198step: reactivo el navegador
5199descripcion: Reactiva el navegador después de haberlo desactivado.
5200
5201step: necesito el navegador ahora
5202descripcion: Alias para reactivar el navegador cuando se necesita nuevamente.`},{id:"steps-modales",title:"Inventario: Modales",content:`## Modales
5203
5204step: espero a que aparezca el modal "{modal_name}" con identificador "{identifier}"
5205descripcion: Espera hasta 10 segundos a que un modal sea visible en la página.
5206
5207step: espero a que desaparezca el modal "{modal_name}" con identificador "{identifier}"
5208descripcion: Espera hasta 10 segundos a que un modal desaparezca de la vista.
5209
5210step: cierro el modal "{modal_name}" haciendo click en el botón cerrar con identificador "{identifier}"
5211descripcion: Cierra un modal haciendo click en su botón de cerrar.
5212
5213step: cierro el modal presionando la tecla Escape
5214descripcion: Cierra un modal presionando la tecla Escape.
5215
5216step: cierro el modal haciendo click fuera
5217descripcion: Cierra un modal haciendo click fuera del contenido (en la esquina superior izquierda).
5218
5219step: verifico que el modal "{modal_name}" es visible con identificador "{identifier}"
5220descripcion: Verifica que un modal es actualmente visible en la página.
5221
5222step: verifico que el modal "{modal_name}" no es visible con identificador "{identifier}"
5223descripcion: Verifica que un modal no es visible en la página.
5224
5225step: verifico que el modal "{modal_name}" tiene el título "{expected_title}" con identificador "{identifier}"
5226descripcion: Verifica que un modal tiene un título específico buscando en selectores comunes de título.
5227
5228step: hago click en el botón "{button_text}" del modal "{modal_name}" con identificador de modal "{modal_id}"
5229descripcion: Hace click en un botón específico dentro de un modal buscando por texto.
5230
5231step: relleno el campo "{field_name}" con "{text}" en el modal "{modal_name}" con identificadores modal="{modal_id}" campo="{field_id}"
5232descripcion: Rellena un campo de texto dentro de un modal específico.
5233
5234step: verifico que el modal "{modal_name}" contiene el texto "{text}" con identificador "{identifier}"
5235descripcion: Verifica que un modal contiene un texto específico visible.
5236
5237step: manejo la alerta del navegador con acción "{action}"
5238descripcion: Step deprecado. Usar 'acepto la alerta' o 'rechazo la alerta' en su lugar.
5239
5240step: manejo la confirmación del navegador con acción "{action}"
5241descripcion: Step deprecado. Usar 'acepto la alerta' o 'rechazo la alerta' en su lugar.
5242
5243step: manejo el prompt del navegador con texto "{text}" y acción "{action}"
5244descripcion: Step deprecado. Usar 'obtengo el texto de la alerta' en su lugar.
5245
5246step: espero a que aparezca cualquier modal
5247descripcion: Espera a que aparezca cualquier modal en la página buscando selectores comunes (.modal, .dialog, [role="dialog"], etc.).
5248
5249step: verifico que no hay modales visibles
5250descripcion: Verifica que no hay ningún modal visible en la página.
5251
5252step: tomo captura del modal "{modal_name}" con identificador "{identifier}"
5253descripcion: Toma una captura de pantalla específica del modal y la guarda con timestamp.
5254
5255step: desactivo el manejo automático de diálogos
5256descripcion: Desactiva el manejo automático de diálogos/alertas removiendo todos los listeners.
5257
5258step: evito que se cierren automáticamente los diálogos
5259descripcion: Configura un listener que captura el mensaje del diálogo y lo acepta automáticamente. Debe ejecutarse ANTES de la acción que dispara el diálogo.
5260
5261step: obtengo el mensaje del diálogo guardado
5262descripcion: Obtiene el mensaje del diálogo que fue capturado por el listener previo.
5263
5264step: el mensaje del diálogo capturado debería contener "{expected_text}"
5265descripcion: Verifica que el mensaje capturado del diálogo contiene un texto parcial.
5266
5267step: el mensaje del diálogo capturado debería ser "{expected_text}"
5268descripcion: Verifica que el mensaje capturado del diálogo es exactamente igual al texto esperado.
5269
5270step: guardo el mensaje del diálogo capturado en la variable "{variable_name}"
5271descripcion: Guarda el mensaje capturado del diálogo en una variable del framework.`},{id:"steps-combobox",title:"Inventario: Combobox",content:`## Combobox
5272
5273step: selecciono la opción "{option}
5273" del combobox "{element_name}" con identificador "{identifier}"
5274descripcion: Selecciona una opción de un combobox simulando interacción humana completa con todos los eventos (focus, click, change, blur, Angular events).
5275
5276step: selecciono la opción "{option}" del select "{element_name}" con identificador "{identifier}"
5277descripcion: Selecciona una opción de un elemento select HTML nativo con eventos completos para compatibilidad con Angular y otros frameworks SPA.
5278
5279step: selecciono la opción por valor "{value}" del combobox "{element_name}" con identificador "{identifier}"
5280descripcion: Selecciona una opción de un combobox/select por su atributo value.
5281
5282step: selecciono la opción por índice "{index}" del combobox "{element_name}" con identificador "{identifier}"
5283descripcion: Selecciona una opción de un combobox/select por su posición numérica.
5284
5285step: abro el dropdown "{element_name}" con identificador "{identifier}"
5286descripcion: Abre un dropdown personalizado haciendo click y esperando que aparezcan las opciones.
5287
5288step: selecciono la opción "{option}" del dropdown abierto
5289descripcion: Selecciona una opción de un dropdown que ya está abierto, buscando por diferentes selectores.
5290
5291step: escribo y selecciono "{text}" en el combobox buscable "{element_name}" con identificador "{identifier}"
5292descripcion: Escribe en un combobox buscable/autocomplete y selecciona la opción que coincida.
5293
5294step: limpio la selección del combobox "{element_name}" con identificador "{identifier}"
5295descripcion: Limpia la selección actual de un combobox usando múltiples métodos de fallback.
5296
5297step: verifico que el combobox "{element_name}" tiene seleccionada la opción "{option}" con identificador "{identifier}"
5298descripcion: Verifica que un combobox tiene una opción específica actualmente seleccionada.
5299
5300step: verifico que el combobox "{element_name}" contiene las opciones "{options}" con identificador "{identifier}"
5301descripcion: Verifica que un combobox contiene todas las opciones especificadas (separadas por coma).
5302
5303step: selecciono múltiples opciones "{options}" del multiselect "{element_name}" con identificador "{identifier}"
5304descripcion: Selecciona múltiples opciones de un select múltiple (opciones separadas por coma).
5305
5306step: navego las opciones del combobox con flechas y selecciono la opción "{option}" de "{element_name}" con identificador "{identifier}"
5307descripcion: Navega por las opciones de un combobox usando teclas de flecha hasta encontrar y seleccionar la opción deseada.
5308
5309step: verifico que el combobox "{element_name}" tiene la opción "{option}" con identificador "{identifier}"
5310descripcion: Verifica que una opción específica existe en el DOM del combobox sin abrirlo. Soporta variables en el identificador.
5311
5312## Validaciones de Combobox
5313
5314step: verifico que el combobox "{element_name}" contiene exactamente "{expected_options}" opciones con identificador "{identifier}"
5315descripcion: Verifica que un combobox contiene exactamente las opciones especificadas (separadas por coma), sin más ni menos.
5316
5317step: verifico que el combobox "{element_name}" tiene "{expected_count}" opciones con identificador "{identifier}"
5318descripcion: Verifica que un combobox tiene un número específico de opciones no vacías.
5319
5320step: verifico que la primera opción del combobox "{element_name}" es "{expected_option}" con identificador "{identifier}"
5321descripcion: Verifica que la primera opción de un combobox es un texto específico.
5322
5323step: verifico que la última opción del combobox "{element_name}" es "{expected_option}" con identificador "{identifier}"
5324descripcion: Verifica que la última opción de un combobox es un texto específico.
5325
5326step: verifico que las opciones del combobox "{element_name}" están ordenadas alfabéticamente con identificador "{identifier}"
5327descripcion: Verifica que las opciones de un combobox están en orden alfabético.
5328
5329step: verifico que el combobox "{element_name}" no tiene opciones duplicadas con identificador "{identifier}"
5330descripcion: Verifica que un combobox no tiene opciones repetidas.
5331
5332step: verifico que el combobox "{element_name}" contiene la opción "{expected_option}" con identificador "{identifier}"
5333descripcion: Verifica que un combobox contiene una opción específica entre sus opciones dis
5333ponibles.
5334
5335step: verifico que el combobox "{element_name}" no contiene la opción "{unexpected_option}" con identificador "{identifier}"
5336descripcion: Verifica que un combobox NO contiene una opción específica.
5337
5338step: verifico que la selección por defecto del combobox "{element_name}" es "{expected_selection}" con identificador "{identifier}"
5339descripcion: Verifica que la selección por defecto (opción marcada como selected) es un texto específico.
5340
5341step: verifico que el combobox "{element_name}" permite selección múltiple con identificador "{identifier}"
5342descripcion: Verifica que un combobox tiene el atributo multiple habilitado.
5343
5344step: verifico que el combobox "{element_name}" no permite selección múltiple con identificador "{identifier}"
5345descripcion: Verifica que un combobox NO tiene el atributo multiple.
5346
5347step: verifico que el combobox "{element_name}" es campo requerido con identificador "{identifier}"
5348descripcion: Verifica que un combobox tiene el atributo required.
5349
5350step: verifico que el placeholder del combobox "{element_name}" es "{expected_placeholder}" con identificador "{identifier}"
5351descripcion: Verifica que un combobox tiene un placeholder específico (atributo o primera opción vacía).
5352
5353step: verifico que las opciones del combobox "{element_name}" contienen los valores "{expected_values}" con identificador "{identifier}"
5354descripcion: Verifica que las opciones de un combobox tienen atributos value específicos (separados por coma).
5355
5356step: verifico que el combobox "{element_name}" se puede filtrar escribiendo "{filter_text}" con identificador "{identifier}"
5357descripcion: Verifica que un combobox se puede filtrar escribiendo texto y que reduce el número de opciones visibles.`},{id:"steps-inputs-avanzados",title:"Inventario: Inputs Avanzados",content:`## Inputs Avanzados
5358
5359step: escribo gradualmente "{text}" en "{selector}" con {delay:d}ms entre caracteres
5360descripcion: Escribe texto gradualmente, carácter por carácter, con un delay específico en milisegundos.
5361
5362step: escribo naturalmente "{text}" en "{selector}"
5363descripcion: Escribe texto simulando escritura humana con delays aleatorios entre 50-200ms.
5364
5365step: limpio completamente el campo "{selector}"
5366descripcion: Limpia completamente un campo usando múltiples métodos (clear, Ctrl+A+Delete, Backspace).
5367
5368step: selecciono todo el texto en "{selector}" y lo borro
5369descripcion: Selecciona todo el texto de un campo y lo borra con Delete.
5370
5371step: borro {num_chars:d} caracteres del final en "{selector}"
5372descripcion: Borra un número específico de caracteres del final de un campo usando Backspace.
5373
5374step: reemplazo el texto en "{selector}" con "{new_text}"
5375descripcion: Reemplaza completamente el texto de un campo seleccionando todo y escribiendo el nuevo texto.
5376
5377step: agrego "{additional_text}" al final del texto en "{selector}"
5378descripcion: Agrega texto al final del contenido existente de un campo sin borrar lo anterior.
5379
5380step: inserto "{text}" al inicio del campo "{selector}"
5381descripcion: Inserta texto al inicio del contenido existente de un campo.
5382
5383step: tecleo "{key}" en el campo "{selector}"
5384descripcion: Presiona una tecla específica en un elemento después de enfocarlo.
5385
5386step: tecleo combinación "{key_combination}" en el campo "{selector}"
5387descripcion: Presiona una combinación de teclas en un elemento específico.
5388
5389step: enfoco el campo "{selector}"
5390descripcion: Enfoca un campo específico usando focus().
5391
5392step: desenfocar el campo actual
5393descripcion: Quita el foco del campo actual presionando Tab.
5394
5395step: copio el contenido del campo "{selector}" al portapapeles
5396descripcion: Selecciona todo el contenido de un campo y lo copia al portapapeles con Ctrl+C.
5397
5398step: pego el contenido del portapapeles en "{selector}"
5399descripcion: Pega el contenido del portapapeles en un campo con Ctrl+V.
5400
5401step: escribo avanzado "{text}" y presiono Enter en "{selector}"
5402descripcion: Escribe texto en un campo usando fill() y presiona Enter inmediatamente.
5403
5404step: selecciono el texto desde la posición {start:d} hasta {end:d} en "{selector}"
5405descripcion: Selecciona un rango específico de texto en un campo usando setSelectionRange.
5406
5407step: escribo con velocidad "{speed_type}" el texto "{text}" en "{selector}"
5408descripcion: Escribe texto con velocidades predefinidas (muy_lenta, lenta, normal, ra
5408pida, muy_rapida).
5409
5410step: simulo errores de escritura con texto "{text}" en "{selector}"
5411descripcion: Simula errores de escritura humanos con 15% de probabilidad de error, corrección automática y delays variables.
5412
5413step: verifico que puedo escribir en el campo "{selector}"
5414descripcion: Verifica que un campo está habilitado y es editable (acepta entrada de texto).
5415
5416step: limpio el campo "{selector}" usando {method}
5417descripcion: Limpia un campo usando un método específico (clear, select_all, backspace, delete).
5418
5419step: escribo texto multilínea en "{selector}"
5420descripcion: Escribe texto multilínea desde context.text (bloque de texto del feature) en un campo.`},{id:"steps-responsive",title:"Inventario: Responsive",content:`## Responsive
5421
5422step: establezco el viewport a tamaño móvil "{width}x{height}"
5423descripcion: Establece el viewport a un tamaño móvil específico en píxeles.
5424
5425step: establezco el viewport a tamaño tablet "{width}x{height}"
5426descripcion: Establece el viewport a un tamaño tablet específico en píxeles.
5427
5428step: establezco el viewport a tamaño desktop "{width}x{height}"
5429descripcion: Establece el viewport a un tamaño desktop específico en píxeles.
5430
5431step: verifico que el elemento "{element_name}" es visible en móvil con identificador "{identifier}"
5432descripcion: Verifica que un elemento es visible en viewport móvil (375x667 - iPhone SE).
5433
5434step: verifico que el elemento "{element_name}" está oculto en móvil con identificador "{identifier}"
5435descripcion: Verifica que un elemento está oculto en viewport móvil (375x667).
5436
5437step: verifico que el elemento "{element_name}" se adapta a cambios de viewport con identificador "{identifier}"
5438descripcion: Verifica que un elemento cambia de tamaño o posición entre diferentes viewports (móvil, tablet, desktop).
5439
5440step: verifico que el menú de navegación se colapsa en móvil
5441descripcion: Verifica que el menú de navegación se colapsa en dispositivos móviles buscando elementos hamburger/toggle.
5442
5443step: verifico que el texto es legible en tamaño móvil
5444descripcion: Verifica que los textos tienen un tamaño de fuente mínimo de 14px en viewport móvil.
5445
5446step: verifico que los botones son amigables al tacto en móvil
5447descripcion: Verifica que los elementos clickeables tienen un tamaño mínimo de 44px para dispositivos táctiles.
5448
5449step: verifico que no hay scroll horizontal
5450descripcion: Verifica que el ancho de la página no excede el ancho del viewport (sin scroll horizontal).
5451
5452step: verifico que las imágenes se escalan apropiadamente en móvil
5453descripcion: Verifica que las imágenes no son más anchas que el viewport en dispositivos móviles.
5454
5455step: verifico que el elemento "{element_name}" se apila verticalmente en móvil con identificador "{identifier}"
5456descripcion: Verifica que elementos que están en fila en desktop se apilan verticalmente en móvil.
5457
5458step: verifico el comportamiento del breakpoint en "{width}" píxeles
5459descripcion: Verifica que hay cambios de layout al cruzar un breakpoint específico.
5460
5461step: verifico que el elemento "{element_name}" tiene tamaño de fuente responsive con identificador "{identifier}"
5462descripcion: Verifica que un elemento tiene tamaño de fuente que se adapta entre viewport móvil y desktop.`},{id:"steps-tablas",title:"Inventario: Tablas",content:`## Tablas
5463
5464step: verifico que la tabla "{table_name}" tiene "{expected_rows}" filas con identificador "{identifier}"
5465descripcion: Verifica que una tabla tiene un número específico de filas en el tbody. Soporta variables con \${variable_name}.
5466
5467step: verifico que la tabla "{table_name}" tiene "{expected_columns}" columnas con identificador "{identifier}"
5468descripcion: Verifica que una tabla tiene un número específico de columnas en el header.
5469
5470step: hago click en la celda de la fila "{row}" columna "{column}" de la tabla "{table_name}" con identificador "{identifier}"
5471descripcion: Hace click en una celda específica de la tabla por índice de fila y columna (basados en 1).
5472
5473step: verifico que la celda de la fila "{row}" columna "{column}" contiene "{expected_text}" en la tabla "{table_name}" con identificador "{identifier}"
5474descripcion: Verifica que una celda específica contiene un texto esperado.
5475
5476step: ordeno la tabla "{table_name}" por la columna "{column_name}" con identificador "{identifier}"
5477descripcion: Ordena una tabla haciendo click en el header de una columna específica.
5478
5479step: filtro la tabla "{table_name}" por la columna "{column_name}" con valor "{filter_value}" con identificador "{identifier}"
5480descripcion: Filtra una tabla escribiendo un valor en el campo de filtro de una columna.
5481
5482step: selecciono la fila "{row_number}" en la tabla "{table_name}" con identificador "{identifier}"
5483descripcion: Selecciona una fila de la tabla haciendo click en su checkbox, radio o la fila completa.
5484
5485step: verifico que la fila "{row_number}" de la tabla "{table_name}
5485" está seleccionada con identificador "{identifier}"
5486descripcion: Verifica que una fila específica está seleccionada (checkbox checked, clase selected/active).
5487
5488step: obtengo el valor de la celda fila "{row}" columna "{column}" y lo guardo en la variable "{variable_name}" de la tabla "{table_name}" con identificador "{identifier}"
5489descripcion: Obtiene el texto de una celda específica y lo guarda en una variable.
5490
5491step: verifico que la fila "{row_number}" de la tabla "{table_name}" tiene los siguientes datos con identificador "{identifier}"
5492descripcion: Verifica que una fila completa tiene los datos esperados usando una tabla Gherkin con columna "datos".
5493
5494step: verifico que el header de la tabla "{table_name}" tiene las siguientes columnas con identificador "{identifier}"
5495descripcion: Verifica que el header de la tabla tiene los nombres de columnas esperados usando una tabla Gherkin con columna "columnas".
5496
5497step: verifico que la fila "{row_number}" de la tabla "{table_name}" tiene datos con formato con identificador "{identifier}"
5498descripcion: Verifica que una fila tiene datos que coinciden con formatos específicos (numero, string, fecha, email, url, button, a, vacio, no_vacio, cualquiera). Soporta múltiples formatos con separador /.
5499
5500step: guardo en la variable "{variable_name}" el valor de la columna "{column}" de la fila "{row}" en la tabla con identificador "{identifier}"
5501descripcion: Guarda el valor de una celda en una variable. Soporta XPath y CSS para el identificador.
5502
5503step: edito la celda de la fila "{row}" columna "{column}" con valor "{new_value}" en la tabla "{table_name}" con identificador "{identifier}"
5504descripcion: Edita el valor de una celda haciendo doble click y escribiendo en el campo de edición.
5505
5506step: exporto los datos de la tabla "{table_name}" y los guardo en la variable "{variable_name}" con identificador "{identifier}"
5507descripcion: Exporta todos los datos de la tabla como lista de diccionarios (headers como keys) y los guarda en una variable.`},{id:"steps-elementos-web",title:"Inventario: Elementos Web",content:`## Elementos Web
5508
5509step: establezco el atributo "{attribute}" con valor "{value}" en el elemento "{element_name}" con identificador "{identifier}"
5510descripcion: Establece un atributo específico en un elemento usando JavaScript setAttribute.
5511
5512step: elimino el atributo "{attribute}" del elemento "{element_name}" con identificador "{identifier}"
5513descripcion: Elimina un atributo específico de un elemento usando JavaScript removeAttribute.
5514
5515step: establezco el estilo CSS "{property}" con valor "{value}" en el elemento "{element_name}" con identificador "{identifier}"
5516descripcion: Establece una propiedad CSS inline en un elemento.
5517
5518step: disparo el evento "{event}" en el elemento "{element_name}" con identificador "{identifier}"
5519descripcion: Dispara un evento específico (input, change, blur, etc.) en un elemento con bubbling.
5520
5521step: enfoco el elemento "{element_name}" con identificador "{identifier}"
5522descripcion: Enfoca un elemento específico usando focus().
5523
5524step: desenfocar el elemento "{element_name}" con identificador "{identifier}"
5525descripcion: Desenfoca un elemento específico usando blur().
5526
5527step: selecciono el texto del elemento "{element_name}" con identificador "{identifier}"
5528descripcion: Selecciona todo el texto dentro de un elemento usando selectText().
5529
5530step: limpio la selección en la página
5531descripcion: Limpia cualquier selección de texto activa en la página.
5532
5533step: simulo mouse enter en el elemento "{element_name}" con identificador "{identifier}"
5534descripcion: Simula el evento mouseenter en un elemento usando hover().
5535
5536step: simulo mouse leave en el elemento "{element_name}" con identificador "{identifier}"
5537descripcion: Simula el evento mouseleave moviendo el mouse fuera del elemento.
5538
5539step: obtengo las dimensiones del elemento y las guardo en variables ancho="{width_var}" alto="{height_var}" para elemento "{element_name}" con identificador "{identifier}"
5540descripcion: Obtiene el ancho y alto de un elemento y los guarda en variables separadas.
5541
5542step: obtengo la posición del elemento y la guardo en variables x="{x_var}" y="{y_var}" para elemento "{element_name}" con identificador "{identifier}"
5543descripcion: Obtiene las coordenadas x,y de un elemento y las guarda en variables separadas.
5544
5545step: clono el elemento "{source_element}" y lo añado a "{target_element}" con identificadores "{source_id}" y "{target_id}"
5546descripcion: Clona un elemento del DOM y lo añade como hijo de otro elemento.
5547
5548step: elimino el elemento "{element_name}" con identificador "{identifier}"
5549descripcion: Elimina un elemento completamente del DOM usando JavaScript remove().`},{id:"steps-validaciones",title:"Inventario: Validaciones",content:`## Aserciones de Elementos
5550
5551step: debería ver el texto "{text}"
5552descripcion: Verifica que un texto exacto sea visible en la página actual. Soporta resolución de variables.
5553
5554step: debería ver el texto que contiene "{text}"
5555descripcion: Verifica que un texto parcial sea visible en la página. Usa búsqueda XPath con contains.
5556
5557step: debería ver en la página el texto {text_with_variable}
5558descripcion: Verifica que un texto sea visible en la página, soportando variables sin comillas (ej: \${variable}).
5559
5560step: no debería ver el texto "{text}"
5561descripcion: Verifica que un texto específico no sea visible en la página actual.
5562
5563step: el título de la página debería ser "{title}"
5564descripcion: Verifica que el título de la página sea exactamente igual al texto proporcionado.
5565
5566step: el título de la página debería contener "{text}"
5567descripcion: Verifica que el título de la página contenga un texto parcial específico.
5568
5569step: el elemento "{element_name}" debería existir con identificador "{identifier}" y valor "{value}"
5570descripcion: Verifica que un elemento existe en el DOM usando un localizador dinámico con placeholder reemplazado por el valor.
5571
5572step: el elemento "{element_name}" debería existir en identificador "{identifier}"
5573descripcion: Verifica que un elemento existe en el DOM sin importar si es visible. Soporta localizadores dinámicos.
5574
5575step: el elemento "{element_name}" no debería existir con identificador "{identifier}" y valor "{value}"
5576descripcion: Verifica que un elemento NO existe en el DOM usando un localizador dinámico con valor.
5577
5578step: el elemento "{element_name}" no debería existir en identificador "{identifier}"
5579descripcion: Verifica que un elemento NO existe en el DOM. Soporta localizadores con placeholders.
5580
5581step: debería ver el elemento "{element_name}" con identificador "{identifier}"
5582descripcion: Verifica que un elemento sea visible en la página. Soporta variables en el identificador con \${variable}.
5583
5584step: no debería ver el elemento "{element_name}" con identificador "{identifier}"
5585descripcion: Verifica que un elemento no sea visible en la página. Soporta variables en el identificador.
5586
5587step: el elemento "{element_name}" debería contener el texto "{text}" con identificador "{identifier}"
5588descripcion: Verifica que un elemento contenga un texto específico (búsqueda parcial dentro del elemento).
5589
5590step: el elemento "{element_name}" debería tener el texto exacto "{text}" con identificador "{identifier}"
5591descripcion: Verifica que un elemento tenga exactamente el texto proporcionado, sin contenido adicional.
5592
5593step: el campo "{field_name}" debería tener el valor "{value}" con identificador "{identifier}"
5594descripcion: Verifica que un campo de formulario tenga un valor específico.
5595
5596step: el campo "{field_name}" no debería tener el valor "{value}" con identificador "{identifier}"
5597descripcion: Verifica que un campo de formulario NO tenga un valor específico.
5598
5599step: el campo "{field_name}" debería estar vacío con identificador "{identifier}"
5600descripcion: Verifica que un campo de formulario esté vacío, sin ningún valor ingresado.
5601
5602step: el campo "{field_name}" no debería estar vacío con identificador "{identifier}"
5603descripcion: Verifica que un campo de formulario tenga algún valor (no esté vacío).
5604
5605step: el elemento "{element_name}" debería estar habilitado con identificador "{identifier}"
5606descripcion: Verifica que un elemento esté habilitado para interacción del usuario.
5607
5608step: el elemento "{element_name}" debería estar deshabilitado con identificador "{identifier}"
5609descripcion: Verifica que un elemento esté deshabilitado y no permita interacción.
5610
5611step: el checkbox "{checkbox_name}" debería estar marcado con identificador "{identifier}"
5612descripcion: Verifica que un checkbox esté en estado marcado/checked.
5613
5614step: el checkbox "{checkbox_name}" no debería estar marcado con identificador "{identifier}"
5615descripcion: Verifica que un checkbox no esté marcado.
5616
5617step: la url actual debería ser "{url}"
5618descripcion: Verifica que la URL actual del navegador sea exactamente la proporcionada.
5619
5620step: la url actual debería contener "{url_part}"
5621descripcion: Verifica que la URL actual del navegador contenga una parte específica del texto.
5622
5623step: debería haberse abierto una nueva ventana con url que contiene "{url_part}"
5624descripcion: Verifica que se abrió una nueva ventana o pestaña cuya URL contiene el texto especificado.
5625
5626step: debería haberse abierto una nueva ventana con título que contiene "{title}"
5627descripcion: Verifica que se abrió una nueva ventana o pestaña cuyo título contiene el texto especificado.
5628
5629step: debería haber {count:d} ventanas abiertas
5630descripcion: Verifica que hay un número específico de ventanas/pestañas abiertas en el navegador.
5631
5632step: el elemento "{element_name}" debería tener la clase "{css_class}" con identificador "{identifier}"
5633descripcion: Verifica que un elemento tenga una clase CSS específica en su atributo class.
5634
5635step: el elemento "{element_name}" no debería tener la clase "{css_class}" con identificador "{identifier}"
5636descripcion: Verifica que un elemento NO tenga una clase CSS específica.
5637
5638step: el elemento "{element_name}" debería tener el atributo "{attribute}" en identificador "{identifier}"
5639descripcion: Verifica que un elemento tenga un atributo HTML específico, sin importar su valor.
5640
5641step: el elemento "{element_name}" no debería tener el atributo "{attribute}" con identificador "{identifier}"
5642descripcion: Verifica que un elemento NO tenga un atributo HTML específico.
5643
5644step: el elemento "{element_name}" debería tener el atributo "{attribute}" con valor "{value}" con identificador "{identifier}"
5645descripcion: Verifica que un atributo HTML de un elemento tenga un valor exacto específico.
5646
5647step: el elemento "{element_name}" debería tener el atributo "{attribute}" que contiene "{value}" con identificador "{identifier}"
5648descripcion: Verifica que un atributo HTML de un elemento contenga un valor parcial específico.
5649
5650step: el elemento "{element_name}" debería ser de solo lectura con identificador "{identifier}"
5651descripcion: Verifica que un elemento tenga el atributo readonly (solo lectura).
5652
5653step: el elemento "{element_name}" no debería ser de solo lectura con identificador "{identifier}"
5654descripcion: Verifica que un elemento NO sea de solo lectura.
5655
5656step: el elemento "{element_name}" debería ser requerido con identificador "{identifier}"
5657descripcion: Verifica que un elemento tenga el atributo required (campo obligatorio).
5658
5659step: el elemento "{element_name}" no debería ser requerido con identificador "{identifier}"
5660descripcion: Verifica que un elemento NO sea requerido.
5661
5662step: el elemento "{element_name}" debería estar oculto con identificador "{identifier}"
5663descripcion: Verifica que un elemento esté oculto (hidden o display:none).
5664
5665step: el elemento "{element_name}" debería estar adjunto al DOM con identificador "{identifier}"
5666descripcion: Verifica que un elemento esté adjunto/presente en el DOM del documento.
5667
5668step: el elemento "{element_name}" debería ser editable con identificador "{identifier}"
5669descripcion: Verifica que un elemento sea editable por el usuario.
5670
5671step: el input "{element_name}" debería tener valor mínimo "{min_value}" con identificador "{identifier}"
5672descripcion: Verifica que un input numérico tenga un atributo min con el valor especificado.
5673
5674step: el input "{element_name}" debería tener valor máximo "{max_value}" con identificador "{identifier}"
5675descripcion: Verifica que un input numérico tenga un atributo max con el valor especificado.
5676
5677step: el input "{element_name}" debería tener longitud máxima "{maxlength}" con identificador "{identifier}"
5678descripcion: Verifica que un input tenga un atributo maxlength con el valor especificado.
5679
5680step: el input "{element_name}" debería tener patrón "{pattern}" con identificador "{identifier}"
5681descripcion: Verifica que un input tenga un atributo pattern de validación específico.
5682
5683step: el input "{element_name}" debería tener placeholder "{placeholder}" con identificador "{identifier}"
5684descripcion: Verifica que un input tenga un texto placeholder específico.
5685
5686step: el input "{element_name}" debería tener tipo "{input_type}" con identificador "{identifier}"
5687descripcion: Verifica que un input tenga un tipo específico (text, email, number, etc.).
5688
5689step: debería haber exactamente {count:d} elementos que coinciden con "{element_name}" con identificador "{identifier}"
5690descripcion: Verifica que haya un número exacto de elementos que coincidan con el selector.
5691
5692step: debería haber al menos {count:d} elementos que coinciden con "{element_name}" con identificador "{identifier}"
5693descripcion: Verifica que haya al menos un número mínimo de elementos que coincidan con el selector.
5694
5695step: debería haber como máximo {count:d} elementos que coinciden con "{element_name}" con identificador "{identifier}"
5696descripcion: Verifica que haya como máximo un número de elementos que coincidan con el selector.
5697
5698step: el elemento "{element_name}" debería tener aria-label "{aria_label}" con identificador "{identifier}"
5699descripcion: Verifica que un elemento tenga un atributo aria-label con el valor especificado.
5700
5701step: el elemento "{element_name}" debería tener rol "{role}" con identificador "{identifier}"
5702descripcion: Verifica que un elemento tenga un rol ARIA específico (button, dialog, etc.).
5703
5704step: el elemento "{element_name}" debería tener aria-expanded "{state}" con identificador "{identifier}"
5705descripcion: Verifica que un elemento tenga aria-expanded con un estado específico (true/false).
5706
5707step: el elemento "{element_name}" debería tener atributo data "{data_attr}" con valor "{value}" con identificador "{identifier}"
5708descripcion: Verifica que un elemento tenga un data-attribute específico con un valor determinado.
5709
5710step: el enlace "{element_name}" debería tener href "{href}" con identificador "{identifier}"
5711descripcion: Verifica que un enlace tenga un atributo href con la URL exacta especificada.
5712
5713step: el enlace "{element_name}" debería tener href que contiene "{href_part}" con identificador "{identifier}"
5714descripcion: Verifica que un enlace tenga un href que contenga una parte específica de la URL.
5715
5716step: la imagen "{element_name}" debería tener src "{src}" con identificador "{identifier}"
5717descripcion: Verifica que una imagen tenga un atributo src con la ruta exacta especificada.
5718
5719step: la imagen "{element_name}" debería tener alt "{alt}" con identificador "{identifier}"
5720descripcion: Verifica que una imagen tenga un texto alternativo (alt) específico.
5721
5722step: el elemento "{element_name}" debería tener título "{title}" con identificador "{identifier}"
5723descripcion: Verifica que un elemento tenga un atributo title con el texto especificado.
5724
5725step: el elemento "{element_name}" debería tener nombre "{name}" con identificador "{identifier}"
5726descripcion: Verifica que un elemento tenga un atributo name con el valor especificado.
5727
5728step: el elemento "{element_name}" debería tener id "{element_id}" con identificador "{identifier}"
5729descripcion: Verifica que un elemento tenga un atributo id con el valor especificado.
5730
5731step: el select "{element_name}
5731" debería tener la opción seleccionada "{option_text}" con identificador "{identifier}"
5732descripcion: Verifica que un select tenga una opción específica actualmente seleccionada.
5733
5734step: el select "{element_name}" debería tener {count:d} opciones con identificador "{identifier}"
5735descripcion: Verifica que un select tenga un número específico de opciones disponibles.
5736
5737step: lanzo un error con el mensaje "{mensaje}"
5738descripcion: Fuerza un fallo inmediato del escenario con un mensaje personalizado. Útil para marcar caminos que no deberían alcanzarse.
5739
5740## Validaciones de Página
5741
5742step: deberia ver el elemento "{element_name}" con identificador "{identifier}"
5743descripcion: Verifica que un elemento es visible en la página (sin tilde en "debería").
5744
5745step: no deberia ver el elemento "{element_name}" con identificador "{identifier}"
5746descripcion: Verifica que un elemento NO es visible en la página (sin tilde en "debería").
5747
5748step: deberia ver que el elemento "{element_name}" existe con identificador "{identifier}"
5749descripcion: Verifica que un elemento existe en el DOM, aunque puede estar oculto visualmente.
5750
5751step: no deberia ver que el elemento "{element_name}" existe con identificador "{identifier}"
5752descripcion: Verifica que un elemento NO existe en el DOM de la página.
5753
5754step: verifico que el elemento "{element_name}" tiene la clase CSS "{css_class}" con identificador "{identifier}"
5755descripcion: Verifica que un elemento tiene una clase CSS específica en su lista de clases.
5756
5757step: verifico que el elemento "{element_name}" no tiene la clase CSS "{css_class}" con identificador "{identifier}"
5758descripcion: Verifica que un elemento NO tiene una clase CSS específica.
5759
5760step: verifico que el elemento "{element_name}" tiene el atributo "{attribute}" con valor "{expected_value}" con identificador "{identifier}"
5761descripcion: Verifica que un elemento tiene un atributo HTML con un valor exacto específico.
5762
5763step: verifico que el atributo "{attribute}" del elemento "{element_name}" coincide con el patrón "{pattern}" con identificador "{identifier}"
5764descripcion: Verifica que un atributo de un elemento coincide con un patrón de expresión regular.
5765
5766step: verifico que el texto del elemento "{element_name}" coincide con el patrón "{pattern}" con identificador "{identifier}"
5767descripcion: Verifica que el texto de un elemento coincide con un patrón regex específico.
5768
5769step: verifico que el texto del elemento "{element_name}" tiene formato de email válido con identificador "{identifier}"
5770descripcion: Verifica que el texto de un elemento tiene formato de correo electrónico válido.
5771
5772step: verifico que el texto del elemento "{element_name}" tiene formato de teléfono válido con identificador "{identifier}"
5773descripcion: Verifica que el texto de un elemento tiene formato de número telefónico válido.
5774
5775step: verifico que el texto del elemento "{element_name}" tiene formato de fecha válido "{date_format}" con identificador "{identifier}"
5776descripcion: Verifica que el texto de un elemento tiene un formato de fecha válido según el patrón proporcionado (ej: %Y-%m-%d).
5777
5778step: verifico que el texto del elemento "{element_name}" es numérico con identificador "{identifier}"
5779descripcion: Verifica que el texto de un elemento es un valor numérico válido.
5780
5781step: verifico que la longitud del texto del elemento "{element_name}" es "{expected_length}" con identificador "{identifier}"
5782descripcion: Verifica que el texto de un elemento tiene una longitud exacta en caracteres.
5783
5784step: verifico que la longitud del texto del elemento "{element_name}" está entre "{min_length}" y "{max_length}" con identificador "{identifier}"
5785descripcion: Verifica que la longitud del texto de un elemento está dentro de un rango específico.
5786
5787step: verifico que el elemento "{element_name}" está dentro del viewport con identificador "{identifier}"
5788descripcion: Verifica que un elemento está visible dentro del área visible del navegador (viewport).
5789
5790step: verifico que el elemento "{element_name}" tiene el foco con identificador "{identifier}"
5791descripcion: Verifica que un elemento tiene actualmente el foco del te
5791clado.
5792
5793step: verifico que el color de fondo del elemento "{element_name}" es "{expected_color}" con identificador "{identifier}"
5794descripcion: Verifica que un elemento tiene un color de fondo específico (soporta hex y rgb).
5795
5796step: verifico que el color del texto del elemento "{element_name}" es "{expected_color}" con identificador "{identifier}"
5797descripcion: Verifica que un elemento tiene un color de texto específico.
5798
5799step: verifico que el tamaño de fuente del elemento "{element_name}" es "{expected_size}" con identificador "{identifier}"
5800descripcion: Verifica que un elemento tiene un tamaño de fuente específico (ej: 16px).
5801
5802step: verifico que el ancho del elemento "{element_name}" es "{expected_width}" píxeles con identificador "{identifier}"
5803descripcion: Verifica que un elemento tiene un ancho específico en píxeles.
5804
5805step: verifico que la altura del elemento "{element_name}" es "{expected_height}" píxeles con identificador "{identifier}"
5806descripcion: Verifica que un elemento tiene una altura específica en píxeles.
5807
5808step: verifico que el elemento "{element_name}" está posicionado en x="{expected_x}" y="{expected_y}" con identificador "{identifier}"
5809descripcion: Verifica que un elemento está en una posición específica en la página (con tolerancia de 5px).
5810
5811step: verifico que la propiedad CSS "{property}" del elemento "{element_name}" es "{expected_value}" con identificador "{identifier}"
5812descripcion: Verifica que una propiedad CSS computada de un elemento tiene un valor exacto.
5813
5814step: verifico que la propiedad CSS "{property}" del elemento "{element_name}" contiene "{expected_value}" con identificador "{identifier}"
5815descripcion: Verifica que una propiedad CSS computada de un elemento contiene un valor parcial.
5816
5817step: verifico que la propiedad CSS "{property}" del elemento "{element_name}" no existe con identificador "{identifier}"
5818descripcion: Verifica que un elemento NO tiene una propiedad CSS específica en su estilo inline.
5819
5820step: guardo en la variable "{variable_name}" el valor de la propiedad CSS "{property}" del elemento "{element_name}" con identificador "{identifier}"
5821descripcion: Obtiene el valor de una propiedad CSS computada y lo guarda en una variable para uso posterior.
5822
5823step: verifico que la propiedad CSS "{property}" del elemento "{element_name}" coincide con el patrón "{pattern}" con identificador "{identifier}"
5824descripcion: Verifica que una propiedad CSS de un elemento coincide con un patrón de expresión regular.
5825
5826step: verifico que el elemento "{element_name}" tiene la propiedad CSS "{property}" con identificador "{identifier}"
5827descripcion: Verifica que un elemento tiene una propiedad CSS específica definida (sin importar el valor).
5828
5829step: verifico que el elemento "{element_name}" no tiene la propiedad CSS "{property}" con identificador "{identifier}"
5830descripcion: Verifica que un elemento NO tiene una propiedad CSS específica en su estilo.`},{id:"steps-extraccion-datos",title:"Inventario: Extracción de Datos y Variables",content:`## Extracción de Datos
5831
5832step: guardo el texto del elemento "{selector}" en la variable "{variable_name}"
5833descripcion: Obtiene el texto visible de un elemento (usando identificador JSON POM o selector CSS/XPath) y lo almacena en una variable. El selector puede ser $.ARCHIVO.elemento o un selector directo.
5834
5835step: guardo el atributo "{attribute}" del elemento "{selector}" en la variable "{variable_name}"
5836descripcion: Obtiene el valor de un atributo HTML de un elemento y lo almacena en una variable.
5837
5838step: obtengo el título de la página y lo guardo en la variable "{variable_name}"
5839descripcion: Obtiene el título de la página actual y lo almacena en una variable.
5840
5841step: cuento los elementos con identificador "{identifier}" y guardo el conteo en la variable "{variable_name}"
5842descripcion: Cuenta la cantidad de elementos que coinciden con un localizador y guarda el número en una variable.
5843
5844step: verifico si el elemento "{element_name}" es visible y guardo el resultado en la variable "{variable_name}" con identificador "{identifier}"
5845descripcion: Verifica si un elemento es visible y guarda el resultado booleano (true/false) en una variable.
5846
5847step: verifico si el elemento "{element_name}" está habilitado y guardo el resultado en la variable "{variable_name}" con identificador "{identifier}"
5848descripcion: Verifica si un elemento está habilitado y guarda el resultado booleano en una variable.
5849
5850step: verifico si el checkbox "{checkbox_name}" está marcado y guardo el resultado en la variable "{variable_name}" con identificador "{identifier}"
5851descripcion: Verifica si un checkbox está marcado y guarda el resultado booleano en una variable.
5852
5853## Variables
5854
5855step: creo la variable "{variable_name}" con valor "{value}"
5856descripcion: Crea o actualiza una variable con un valor específico. Resuelve variables existentes en el valor.
5857
5858step: establezco "{variable_name}" = "{value}"
5859descripcion: Establece el valor de una variable usando sintaxis abreviada de asignación.
5860
5861step: establezco la variable "{variable_name}" con el valor "{value}"
5862descripcion: Establece el valor de una variable con sintaxis descriptiva completa.
5863
5864step: genero una variable "{variable_name}" con texto aleatorio de {length:d} caracteres
5865descripcion: Genera una variable con texto aleatorio alfanumérico de la longitud especificada.
5866
5867step: genero una cadena aleatoria de longitud {length:d} y la guardo en la variable "{variable_name}"
5868descripcion: Genera una cadena aleatoria de longitud específica y la almacena en una variable.
5869
5870step: genero una variable "{variable_name}" con número aleatorio entre {min_val:d} y {max_val:d}
5871descripcion: Genera un número aleatorio dentro de un rango y lo guarda en una variable.
5872
5873step: genero un número aleatorio entre {min_val:d} y {max_val:d} y lo guardo en la variable "{variable_name}"
5874descripcion: Genera un número aleatorio entre dos valores y lo almacena en una variable.
5875
5876step: genero una variable "{variable_name}" con timestamp actual
5877descripcion: Genera una variable con el timestamp actual en formato YYYYMMDD_HHMMSS.
5878
5879step: obtengo el timestamp actual y lo guardo en la variable "{variable_name}"
5880descripcion: Obtiene el timestamp actual y lo almacena en una variable.
5881
5882step: genero una variable "{variable_name}" con fecha actual usando formato "{date_format}"
5883descripcion: Genera una variable con la fecha actual formateada según el patrón proporcionado (ej: %Y-%m-%d, %d/%m/%Y).
5884
5885step: obtengo la fecha actual y la guardo en la variable "{variable_name}"
5886descripcion: Obtiene la fecha actual en formato por defecto (%Y-%m-%d) y la guarda en una variable.
5887
5888step: concateno "{var1}" y "{var2}" y lo guardo en la variable "{result_var}"
5889descripcion: Concatena dos valores (textos, literales o variables con sintaxis \${nombre}) y guarda el resultado en una nueva variable.
5890
5891step: incremento la variable numérica "{variable_name}" en {increment:d}
5892descripcion: Incrementa el valor numérico de una variable en la cantidad especificada.
5893
5894step: muestro el valor de la variable "{variable_name}"
5895descripcion: Muestra en consola el valor actual de una variable para depuración.
5896
5897step: muestro en consola el valor de la variable "{variable_name}"
5898descripcion: Imprime en la consola el valor de una variable específica.
5899
5900step: imprimo la variable "{variable_name}"
5901descripcion: Imprime el valor de una variable en la salida estándar.
5902
5903step: verifico que la variable "{variable_name}" contiene "{expected_value}"
5904descripcion: Verifica que el valor de una variable contiene un texto específico (búsqueda parcial).
5905
5906step: verifico que la variable "{variable_name}" es igual a "{expected_value}"
5907descripcion: Verifica que el valor de una variable es exactamente igual al valor esperado. Soporta comparación entre variables.
5908
5909step: muestro todas las variables actuales
5910descripcion: Muestra en consola un listado de todas las variables definidas con sus valores actuales.
5911
5912step: limpio todas las variables globales
5913descripcion: Elimina todas las variables globales definidas durante la ejecución.
5914
5915step: limpio todas las variables del escenario
5916descripcion: Limpia todas las variables del escenario actual, dejando el estado limpio.
5917
5918step: copio la variable "{source_var}" a "{target_var}"
5919descripcion: Copia el valor de una variable existente a una nueva variable.
5920
5921step: genero una variable "{variable_name}" con fecha actual en formato "{date_format}" sumando {days:d} días hábiles
5922descripcion: Genera una fecha futura sumando días hábiles (lunes a viernes) a la fecha actual y la guarda en una variable.
5923
5924step: genero una fecha con {days:d} días hábiles y la guardo en la variable "{variable_name}" en formato "{date_format}"
5925descripcion: Calcula una fecha futura con días hábiles y la almacena en una variable con el formato especificado.`},{id:"steps-performance",title:"Inventario: Performance",content:`## Performance
5926
5927step: verifico que la página carga en menos de "{max_seconds}" segundos
5928descripcion: Verifica que la página completa su carga (networkidle) dentro del tiempo máximo especificado.
5929
5930step: verifico que el elemento "{element_name}" aparece en menos de "{max_seconds}" segundos con identificador "{identifier}"
5931descripcion: Verifica que un elemento se vuelve visible dentro del tiempo máximo especificado.
5932
5933step: verifico que el tiempo de respuesta del click en elemento "{element_name}" es menor a "{max_seconds}" segundos con identificador "{identifier}"
5934descripcion: Mide el tiempo de respuesta después de hacer click en un elemento y verifica que sea menor al máximo.
5935
5936step: mido y guardo el tiempo de carga de página en la variable "{variable_name}"
5937descripcion: Mide el tiempo de carga de la página hasta networkidle y lo guarda en una variable en segundos.
5938
5939step: verifico que las peticiones de red se completan en menos de "{max_seconds}" segundos
5940descripcion: Verifica que todas las peticiones de red pendientes se completan dentro del tiempo especificado.
5941
5942step: verifico que el tiempo de respuesta del envío de formulario es menor a "{max_seconds}" segundos
5943descripcion: Verifica que el envío de un formulario y su respuesta se completan dentro del tiempo máximo.
5944
5945step: verifico que los resultados de búsqueda aparecen en menos de "{max_seconds}" segundos
5946descripcion: Verifica que los resultados de búsqueda se muestran dentro del tiempo máximo especificado.
5947
5948step: verifico que la imagen "{image_name}" carga en menos de "{max_seconds}" segundos con identificador "{identifier}"
5949descripcion: Verifica que una imagen se carga completamente dentro del tiempo máximo especificado.
5950
5951step: verifico que la animación se completa en menos de "{max_seconds}" segundos en elemento "{element_name}" con identificador "{identifier}"
5952descripcion: Verifica que una animación CSS/JS se completa dentro del tiempo máximo en un elemento específico.
5953
5954step: verifico que el modal "{modal_name}" se abre en menos de "{max_seconds}" segundos con identificador "{identifier}"
5955descripcion: Verifica que un modal se vuelve visible dentro del tiempo máximo especificado.
5956
5957step: verifico que el dropdown "{dropdown_name}" se expande en menos de "{max_seconds}" segundos con identificador "{identifier}"
5958descripcion: Verifica que un dropdown se expande y muestra sus opciones dentro del tiempo máximo.
5959
5960step: verifico que el rendimiento del scroll de página es suave
5961descripcion: Verifica que el scroll completo de la página (arriba y abajo) se ejecuta en menos de 1 segundo.
5962
5963step: verifico que el uso de memoria es aceptable después de "{actions_count}" acciones
5964descripcion: Verifica que el uso de memoria del navegador no supera el 80% después de realizar múltiples acciones.`}
5964,{id:"steps-performance-frontend",title:"Inventario: Performance Frontend",content:`## Performance Frontend (Web Vitals)
5965
5966Métricas de rendimiento del front end medidas en el navegador real (Navigation Timing API + PerformanceObserver). Las verificaciones de tiempo usan **milisegundos**.
5967
5968### Medición y reportes
5969
5970step: mido las metricas de carga de la pagina y las guardo en la variable "{variable_name}"
5971descripcion: Obtiene métricas de carga con Navigation Timing API y guarda un JSON con: dns, tcp, ttfb, download, dom_interactive, dom_complete, total.
5972
5973step: genero un reporte de performance de la pagina y lo guardo en la variable "{variable_name}"
5974descripcion: Genera un reporte completo de performance con todas las métricas disponibles: timing, vitals, recursos, DOM y errores.
5975
5976step: mido los recursos de la pagina por tipo y los guardo en la variable "{variable_name}"
5977descripcion: Cuenta y pesa los recursos agrupados por tipo (script, css, img, font, etc.).
5978
5979### Core Web Vitals
5980
5981step: verifico que el First Contentful Paint es menor a "{max_ms}" milisegundos
5982descripcion: Verifica el First Contentful Paint (FCP): cuándo se renderiza el primer contenido visible. Referencia Google: Bueno < 1800ms, Aceptable < 3000ms.
5983
5984step: verifico que el Largest Contentful Paint es menor a "{max_ms}" milisegundos
5985descripcion: Verifica el Largest Contentful Paint (LCP): cuándo termina de renderizar el elemento más grande del viewport. Referencia Google: Bueno < 2500ms, Necesita mejora < 4000ms.
5986
5987step: verifico que el Cumulative Layout Shift es menor a "{max_cls}"
5988descripcion: Verifica el Cumulative Layout Shift (CLS): estabilidad visual (cuánto se mueven los elementos al cargar). Referencia Google: Bueno < 0.1, Necesita mejora < 0.25.
5989
5990step: verifico que el TTFB es menor a "{max_ms}" milisegundos
5991descripcion: Verifica el Time To First Byte (TTFB): cuánto tarda el servidor en enviar el primer byte. Referencia: Bueno < 800ms, Aceptable < 1800ms.
5992
5993### DOM e interactividad
5994
5995step: verifico que el DOM esta interactivo en menos de "{max_ms}" milisegundos
5996descripcion: Verifica que el DOM alcanza el estado interactivo dentro del umbral. Referencia: Bueno < 3000ms, Aceptable < 5000ms.
5997
5998step: verifico que la pagina es interactiva en menos de "{max_seconds}" segundos
5999descripcion: Verifica que la página es interactiva (DOMContentLoaded + sin JS bloqueante) dentro del umbral en segundos.
6000
6001step: verifico que el DOM tiene menos de "{max_nodes}" nodos
6002descripcion: Verifica que el DOM no es excesivamente grande. Referencia: Bueno < 1500 nodos, Aceptable < 3000, Problemático > 5000.
6003
6004step: verifico que la profundidad maxima del DOM es menor a "{max_depth}" niveles
6005descripcion: Verifica que el DOM no tiene anidamiento excesivo. Referencia: Bueno < 15 niveles, Aceptable < 25, Problemático > 32.
6006
6007### Red, peso y errores
6008
6009step: verifico que la pagina carga menos de "{max_requests}" peticiones de red
6010descripcion: Verifica que la página no genera demasiadas peticiones HTTP durante su carga.
6011
6012step: verifico que el peso total de la pagina es menor a "{max_kb}" KB
6013descripcion: Verifica que el peso total de los recursos cargados no excede el límite en KB.
6014
6015step: verifico que no hay errores de JavaScript en la consola
6016descripcion: Verifica que no hubo errores JavaScript durante la carga de la página.`},{id:"steps-accesibilidad",title:"Inventario: Accesibilidad",content:`## Accesibilidad
6017
6018step: verifico que el elemento "{element_name}" tiene etiqueta ARIA "{expected_label}" con identificador "{identifier}"
6019descripcion: Verifica que un elemento tiene un atributo aria-label con el valor exacto especificado.
6020
6021step: verifico que el elemento "{element_name}" tiene rol ARIA "{expected_role}" con identificador "{identifier}"
6022descripcion: Verifica que un elemento tiene un atributo role ARIA con el valor especificado.
6023
6024step: verifico que el elemento "{element_name}" es accesible por teclado con identificador "{identifier}"
6025descripcion: Verifica que un elemento puede recibir foco y tiene tabindex no negativo para navegación por teclado.
6026
6027step: verifico que el elemento "{element_name}" tiene texto alt "{expected_alt}" con identificador "{identifier}"
6028descripcion: Verifica que una imagen tiene un texto alternativo (alt) con el valor exacto especificado.
6029
6030step: verifico que el elemento "{element_name}" tiene jerarquía de encabezados correcta con identificador "{identifier}"
6031descripcion: Verifica que los encabezados de la página siguen una jerarquía correcta sin saltar niveles.
6032
6033step: verifico que el formulario tiene etiquetas apropiadas para todos los campos
6034descripcion: Verifica que todos los campos de formulario tienen etiquetas asociadas (label, aria-label o aria-labelledby).
6035
6036step: verifico que el elemento "{element_name}
6036" tiene contraste de color suficiente con identificador "{identifier}"
6037descripcion: Verifica que un elemento cumple con el ratio de contraste mínimo WCAG AA de 4.5:1.
6038
6039step: verifico que la página tiene estructura de documento apropiada
6040descripcion: Verifica que la página tiene título, un solo h1, y elementos de navegación y contenido principal.
6041
6042step: verifico que el elemento "{element_name}" es anunciado por lector de pantalla con identificador "{identifier}"
6043descripcion: Verifica que un elemento será anunciado por lectores de pantalla (no tiene aria-hidden=true y tiene contenido accesible).
6044
6045step: verifico que los elementos interactivos tienen indicadores de foco
6046descripcion: Verifica que botones, enlaces e inputs tienen indicadores visuales de foco (outline, box-shadow).
6047
6048step: verifico que el elemento "{element_name}" tiene texto de enlace descriptivo con identificador "{identifier}"
6049descripcion: Verifica que un enlace tiene texto descriptivo y no genérico como "click aquí" o "más".
6050
6051step: verifico que las imágenes tienen texto alternativo apropiado
6052descripcion: Verifica que todas las imágenes de la página tienen atributo alt y que no es solo el nombre del archivo.`},{id:"steps-tooltips",title:"Inventario: Tooltips y Puntero",content:`## Tooltips y Puntero
6053
6054Pasos para validar tooltips y controlar el puntero del mouse. Resuelven el tooltip en cascada sin que el QA necesite saber qué librería usa la aplicación:
6055
6056- \`aria-describedby\` del elemento
6057- \`role="tooltip"\` (estándar ARIA)
6058- Selectores de 11 librerías: Bootstrap, Material UI, Tippy, Ant Design, Vuetify, PrimeNG, Radix, jQuery UI
6059- Atributo \`title\` (tooltip nativo del navegador)
6060
6061> Los tooltips nativos (atributo \`title\`) los dibuja el navegador y no existen en el DOM. Solo es observable el atributo.
6062
6063## Validar el texto del tooltip
6064
6065step: el tooltip del elemento "{element_name}" debería contener el texto "{expected_text}" con identificador "{identifier}"
6066descripcion: Pasa el mouse sobre un elemento y valida que su tooltip contenga el texto indicado. Resuelve en cascada.
6067
6068step: el tooltip del elemento "{element_name}" debería ser "{expected_text}" con identificador "{identifier}"
6069descripcion: Igual que el anterior pero exige coincidencia exacta del texto completo.
6070
6071step: el tooltip visible debería contener el texto "{expected_text}"
6072descripcion: Valida el tooltip que ya está visible, sin volver a hacer hover. Para cuando lo dispara otra acción como el foco.
6073
6074## Controlar el puntero
6075
6076step: paso el mouse sobre el elemento "{element_name}" y espero el tooltip con identificador "{identifier}"
6077descripcion: Pasa el mouse sobre un elemento y espera a que aparezca su tooltip, dejándolo abierto para validarlo en pasos siguientes.
6078
6079step: mantengo el mouse sobre el elemento "{element_name}" por "{seconds}" segundos con identificador "{identifier}"
6080descripcion: Mantiene el puntero sobre un elemento durante un tiempo. Para tooltips con delay largo o menús que requieren permanencia.
6081
6082step: quito el mouse del elemento
6083descripcion: Aleja el puntero para que se cierren los tooltips y menús por hover. Mueve el mouse a una esquina.
6084
6085## Validar ausencia del tooltip
6086
6087step: no debería verse ningún tooltip
6088descripcion: Valida que no haya ningún tooltip visible, recorriendo todas las estrategias de la cascada.
6089
6090step: el elemento "{element_name}" no debería mostrar tooltip con identificador "{identifier}"
6091descripcion: Valida que un elemento NO muestre tooltip al pasarle el mouse.
6092
6093## Accesibilidad del tooltip
6094
6095step: pongo el foco en el elemento "{element_name}" y espero el tooltip con identificador "{identifier}"
6096descripcion: Enfoca un elemento con el teclado y espera su tooltip. Un tooltip accesible debe aparecer también al tabular.
6097
6098step: el elemento "{element_name}" debería describirse con el texto "{expected_text}" con identificador "{identifier}"
6099descripcion: Valida la descripción accesible (aria-describedby) sin hacer hover. Es lo que lee un screen reader.
6100
6101## Capturar texto del tooltip
6102
6103step: obtengo el texto del tooltip del elemento "{element_name}" y lo guardo en la variable "{variable_name}" con identificador "{identifier}"
6104descripcion: Guarda el texto del tooltip en una variable del framework para reutilizarlo en pasos siguientes.`},{id:"steps-geolocalizacion",title:"Inventario: Geolocalización",content:`## Geolocalización
6105
6106Documento generado a partir del código fuente real del framework.
6107Cada paso fue verificado directamente en el archivo \`geolocation_steps.py\`.
6108
6109**Requisitos:** Ninguno adicional (usa Playwright nativo).
6110
6111**Configuración .env:**
6112\`\`\`
6113GEOLOCATION_ENABLED=true
6114GEOLOCATION_LATITUDE=-33.4489
6115GEOLOCATION_LONGITUDE=-70.6693
6116GEOLOCATION_ACCURACY=100
6117\`\`\`
6118
6119**Nota importante:** Cuando \`GEOLOCATION_ENABLED=true\`, el framework otorga automáticamente el permiso de geolocalización al crear el contexto del navegador. Esto resuelve el problema de páginas que usan \`navigator.geolocation.getCurrentPosition()\` sin mostrar un popup de permiso explícito.
6120
6121---
6122
6123## Configurar Geolocalización
6124
6125step: configuro la geolocalización en latitud "{lat}" y longitud "{lon}"
6126descripcion: Configura la geolocalización del navegador con las coordenadas indicadas. Otorga permisos automáticamente.
6127
6128step: configuro la geolocalización en latitud "{lat}" longitud "{lon}" con precisión "{acc}"
6129descripcion: Configura la geolocalización con una precisión personalizada en metros.
6130
6131step: configuro la geolocalización para "{ciudad}"
6132descripcion: Configura la geolocalización usando una ciudad predefinida. Ciudades disponibles: Santiago, Buenos Aires, Lima, Bogotá, México, Madrid, New York, London, Paris, Berlin, Tokyo, Sydney, São Paulo, Valparaíso, Concepción.
6133
6134---
6135
6136## Permisos
6137
6138step: otorgo permisos de geolocalización al navegador
6139descripcion: Otorga permisos de geolocalización al contexto del navegador sin cambiar las coordenadas.
6140
6141step: otorgo permisos de geolocalización para la url "{url}"
6142descripcion: Otorga permisos de geolocalización para un origen/URL específico.
6143
6144---
6145
6146## Desactivar
6147
6148step: desactivo la geolocalización del navegador
6149descripcion: Limpia la geolocalización y los permisos del navegador, volviendo al comportamiento por defecto (sin ubicación simulada).
6150
6151---
6152
6153## Verificación
6154
6155step: verifico que la geolocalización del navegador es latitud "{lat}" y longitud "{lon}"
6156descripcion: Ejecuta navigator.geolocation.getCurrentPosition() en la página y verifica que las coordenadas coincidan (tolerancia de ~111 metros).
6157
6158step: verifico que la geolocalización del navegador es "{ciudad}"
6159descripcion: Verifica que la geolocalización actual corresponde a las coordenadas de una ciudad predefinida.
6160
6161---
6162
6163## Ejemplos de Uso
6164
6165### Configurar desde .env (se aplica al crear el contexto)
6166
6167\`\`\`
6168# .env
6169GEOLOCATION_ENABLED=true
6170GEOLOCATION_LATITUDE=-33.4489
6171GEOLOCATION_LONGITUDE=-70.6693
6172\`\`\`
6173
6174### Cambiar dinámicamente durante un test
6175
6176\`\`\`gherkin
6177Feature: Geolocalización
6178
6179  Scenario: Verificar comportamiento con ubicación en Santiago
6180    When configuro la geolocalización para "santiago"
6181    And voy a la url "https://example.com/stores"
6182    Then verifico que la geolocalización del navegador es "santiago"
6183
6184  Scenario: Cambiar ubicación durante el flujo
6185    When configuro la geolocalización en latitud "-33.4489" y longitud "-70.6693"
6186    And voy a la url "https://maps.google.com"
6187    Then debería ver el elemento "Indicador de ubicación" con identificador "#location-indicator"
6188    When configuro la geolocalización para "buenos aires"
6189    And recargo la página
6190    Then verifico que la geolocalización del navegador es latitud "-34.6037" y longitud "-58.3816"
6191
6192  Scenario: Permisos para un origen específico
6193    When otorgo permisos de geolocalización para la url "https://example.com"
6194    And configuro la geolocalización en latitud "40.7128" longitud "-74.0060" con precisión "50"
6195    And voy a la url "https://example.com/location"
6196    Then verifico que la geolocalización del navegador es latitud "40.7128" y longitud "-74.0060"
6197\`\`\`
6198
6199### Ciudades predefinidas
6200
6201| Ciudad | Latitud | Longitud |
6202|--------|---------|----------|
6203| Santiago | -33.4489 | -70.6693 |
6204| Buenos Aires | -34.6037 | -58.3816 |
6205| Lima | -12.0464 | -77.0428 |
6206| Bogotá | 4.7110 | -74.0721 |
6207| México | 19.4326 | -99.1332 |
6208| Madrid | 40.4168 | -3.7038 |
6209| New York | 40.7128 | -74.0060 |
6210| London | 51.5074 | -0.1278 |
6211| Paris | 48.8566 | 2.3522 |
6212| Berlin | 52.5200 | 13.4050 |
6213| Tokyo | 35.6762 | 139.6503 |
6214| Sydney | -33.8688 | 151.2093 |
6215| São Paulo | -23.5505 | -46.6333 |
6216| Valparaíso | -33.0472 | -71.6127 |
6217| Concepción | -36.8270 | -73.0503 |`},{id:"steps-condicionales",title:"Inventario: Condicionales",content:`## Pasos Condicionales
6218
6219Ejecutan acciones basadas en el estado actual de la página. Si la condición **no se cumple**, el step pasa sin error (no falla el escenario).
6220
6221**Timeout por defecto:** 3 segundos para verificación de condiciones.
6222
6223---
6224
6225## Condicionales por Visibilidad → Click
6226
6227step: si el elemento "{element_name}" es visible hago click con identificador "{identifier}"
6228descripcion: Hace click en un elemento SOLO si es visible. Si no es visible, pasa sin error.
6229
6230step: si el elemento "{element_name}" es visible con identificador "{check_id}" hago click en "{target}" con identificador "{target_id}"
6231descripcion: Si un elemento es visible, hace click en OTRO elemento diferente.
6232
6233step: si el elemento "{element_name}" no es visible con identificador "{check_id}" hago click en "{target}" con identificador "{target_id}"
6234descripcion: Si un elemento NO es visible, hace click en otro elemento.
6235
6236---
6237
6238## Condicionales por Existencia → Click
6239
6240step: si existe el elemento "{element_name}" hago click con identificador "{identifier}"
6241descripcion: Hace click en un elemento SOLO si existe en el DOM. Si no existe, pasa sin error.
6242
6243step: si existe el elemento "{element_name}" con identificador "{check_id}" hago click en "{target}" con identificador "{target_id}"
6244descripcion: Si un elemento existe en el DOM, hace click en OTRO elemento.
6245
6246step: si no existe el elemento "{element_name}" con identificador "{check_id}" hago click en "{target}" con identificador "{target_id}"
6247descripcion: Si un elemento NO existe en el DOM, hace click en otro elemento.
6248
6249---
6250
6251## Condicionales por Visibilidad → Rellenar
6252
6253step: si el elemento "{element_name}" es visible relleno con "{text}" con identificador "{identifier}"
6254descripcion: Rellena un campo SOLO si es visible. Si no es visible, pasa sin error.
6255
6256step: si el elemento "{element_name}" es visible con identificador "{check_id}" relleno "{target}" con "{text}" con identificador "{target_id}"
6257descripcion: Si un elemento es visible, rellena OTRO campo con el texto indicado.
6258
6259---
6260
6261## Condicionales por Texto → Click
6262
6263step: si el elemento "{element_name}" contiene "{text}" con identificador "{check_id}" hago click en "{target}" con identificador "{target_id}"
6264descripcion: Si un elemento contiene un texto parcial (case-insensitive), hace click en otro.
6265
6266step: si el elemento "{element_name}" no contiene "{text}" con identificador "{check_id}" hago click en "{target}" con identificador "{target_id}"
6267descripcion: Si un elemento NO contiene un texto, hace click en otro.
6268
6269---
6270
6271## Condicionales por URL → Acciones
6272
6273step: si la url contiene "{url_part}" hago click en "{element_name}" con identificador "{identifier}"
6274descripcion: Si la URL actual contiene un texto, hace click en un elemento.
6275
6276step: si la url no contiene "{url_part}" hago click en "{element_name}" con identificador "{identifier}"
6277descripcion: Si la URL actual NO contiene un texto, hace click en un elemento.
6278
6279step: si la url contiene "{url_part}" navego a "{url}"
6280descripcion: Si la URL actual contiene un texto, navega a otra URL.
6281
6282step: si la url no contiene "{url_part}" navego a "{url}"
6283descripcion: Si la URL actual NO contiene un texto, navega a otra URL.
6284
6285---
6286
6287## Condicionales por Visibilidad → Navegar
6288
6289step: si el elemento "{element_name}" es visible con identificador "{identifier}" navego a "{url}"
6290descripcion: Si un elemento es visible, navega a una URL.
6291
6292step: si el elemento "{element_name}" no es visible con identificador "{identifier}" navego a "{url}"
6293descripcion: Si un elemento NO es visible, navega a una URL.
6294
6295---
6296
6297## Condicionales con Timeout Personalizado
6298
6299step: si el elemento "{element_name}" aparece en "{seconds}" segundos hago click con identificador "{identifier}"
6300descripcion: Espera N segundos a que aparezca un elemento. Si aparece, hace click. Si no, pasa sin error.
6301
6302step: si el elemento "{element_name}" aparece en "{seconds}" segundos con identificador "{check_id}" hago click en "{target}" con identificador "{target_id}"
6303descripcion: Espera N segundos a que aparezca un elemento. Si aparece, hace click en otro.
6304
6305step: si el elemento "{element_name}" no aparece en "{seconds}" segundos con identificador "{identifier}" hago click en "{target}" con identificador "{target_id}"
6306descripcion: Espera N segundos. Si el elemento NO aparece, hace click en otro.
6307
6308---
6309
6310## Condicionales por Variable → Acciones
6311
6312step: si la variable "{var_name}" es "{expected_value}" hago click en "{element_name}" con identificador "{identifier}"
6313descripcion: Si una variable tiene un valor exacto, hace click en un elemento.
6314
6315step: si la variable "{var_name}" no es "{expected_value}" hago click en "{element_name}" con identificador "{identifier}"
6316descripcion: Si una variable NO tiene un valor específico, hace click en un elemento.
6317
6318step: si la variable "{var_name}" contiene "{expected_text}" hago click en "{element_name}" con identificador "{identifier}"
6319descripcion: Si una variable contiene un texto parcial (case-insensitive), hace click en un elemento.
6320
6321step: si la variable "{var_name}" es "{expected_value}" navego a "{url}"
6322descripcion: Si una variable tiene un valor específico, navega a una URL.
6323
6324step: si la variable "{var_name}" es "{expected_value}" relleno "{element_name}" con "{text}" con identificador "{identifier}"
6325descripcion: Si una variable tiene un valor específico, rellena un campo.
6326
6327---
6328
6329## Condicionales por Estado del Elemento
6330
6331step: si el elemento "{element_name}" está habilitado hago click con identificador "{identifier}"
6332descripcion: Hace click en un elemento SOLO si está habilitado (no disabled).
6333
6334step: si el checkbox "{element_name}" no está marcado con identificador "{check_id}" lo marco
6335descripcion: Si un checkbox NO está marcado, lo marca. Si ya está marcado, pasa sin error.
6336
6337---
6338
6339## Evaluar y Guardar Resultado
6340
6341step: evalúo si el elemento "{element_name}" es visible con identificador "{identifier}" y guardo en "{variable_name}"
6342descripcion: Evalúa si un elemento es visible y guarda "true" o "false" en una variable.
6343
6344step: evalúo si existe el elemento "{element_name}" con identificador "{identifier}" y guardo en "{variable_name}"
6345descripcion: Evalúa si un elemento existe en el DOM y guarda "true" o "false" en una variable.
6346
6347step: evalúo si el elemento "{element_name}" contiene "{text}" con identificador "{identifier}" y guardo en "{variable_name}"
6348descripcion: Evalúa si un elemento contiene un texto y guarda "true" o "false" en una variable.
6349
6350---
6351
6352## Esperas con Timeout Personalizado
6353
6354step: espero a que el elemento "{element_name}" sea visible en máximo "{seconds}" segundos con identificador "{identifier}"
6355descripcion: Espera a que un elemento sea visible con un timeout personalizado en segundos.
6356
6357step: espero a que el elemento "{element_name}" desaparezca en máximo "{seconds}" segundos con identificador "{identifier}"
6358descripcion: Espera a que un elemento desaparezca con un timeout personalizado en segundos.
6359
6360step: espero a que el elemento "{element_name}" esté oculto en máximo "{seconds}" segundos con identificador "{identifier}"
6361descripcion: Espera a que un elemento esté oculto con un timeout personalizado en segundos.
6362
6363---
6364
6365## Ejemplos de Uso
6366
6367### Cerrar popup si aparece
6368
6369\`\`\`gherkin
6370When si el elemento "cookie banner" es visible hago click con identificador "$.COOKIES.btn_aceptar"
6371\`\`\`
6372
6373### Flujo alternativo según estado
6374
6375\`\`\`gherkin
6376When si el elemento "error" es visible con identificador "$.LOGIN.msg_error" hago click en "reintentar" con identificador "$.LOGIN.btn_retry"
6377When si el elemento "error" no es visible con identificador "$.LOGIN.msg_error" hago click en "continuar" con identificador "$.LOGIN.btn_next"
6378\`\`\`
6379
6380### Esperar popup con timeout
6381
6382\`\`\`gherkin
6383When si el elemento "alerta" aparece en "5" segundos hago click con identificador "$.PAGE.btn_cerrar_alerta"
6384\`\`\`
6385
6386### Condicional por URL
6387
6388\`\`\`gherkin
6389When si la url contiene "login" navego a "\${ENV.BASE_URL}/dashboard"
6390\`\`\`
6391
6392### Condicional por variable
6393
6394\`\`\`gherkin
6395When evalúo si el elemento "descuento" es visible con identificador "$.CART.badge" y guardo en "hay_descuento"
6396And si la variable "hay_descuento" es "true" hago click en "aplicar" con identificador "$.CART.btn_aplicar"
6397\`\`\`
6398
6399### Marcar checkbox solo si no está marcado
6400
6401\`\`\`gherkin
6402When si el checkbox "términos" no está marcado con identificador "$.FORM.chk_terminos" lo marco
6403\`\`\`
6404
6405---
6406
6407## Notas Importantes
6408
6409- **No fallan:** Si la condición no se cumple, el step pasa exitosamente sin ejecutar la acción.
6410- **Timeout corto (3s):** Por defecto se espera 3 segundos para verificar la condición.
6411- **Timeout personalizado:** Los steps con \`aparece en "{seconds}" segundos\` permiten definir cuánto esperar.
6412- **Variables:** Todos los textos y URLs se resuelven con \`\${variable}\` antes de usarse.
6413- **Case-insensitive:** Las comparaciones de texto (\`contiene\`) no distinguen mayúsculas/minúsculas.`},{id:"steps-playwright-moderno",title:"Inventario: Capacidades Modernas (Playwright 2026)",content:`## Capacidades Modernas de Playwright (2026)
6414
6415Pasos que aprovechan APIs recientes de Playwright para IA/agentes, accesibilidad
6416y control fino de interacciones. Las capacidades base requieren **Playwright
64171.61+**; el click sin desplazamiento requiere **Playwright 1.62+** (el paso
6418detecta la versión y avisa si es menor, sin romper el framework).
6419
6420### ARIA snapshot (IA / agentes / validación estructural)
6421
6422step: capturo el aria snapshot de la página en la variable "{variable_name}"
6423descripcion: Captura el árbol de accesibilidad (ARIA snapshot) de la página en una variable. Útil para depurar, aserciones estructurales o alimentar un agente/LLM.
6424
6425step: capturo el aria snapshot con coordenadas de la página en la variable "{variable_name}"
6426descripcion: Igual que el anterior pero anexa coordenadas [box=x,y,w,h] a cada nodo, para que agentes visuales/LLMs ubiquen espacialmente los elementos.
6427
6428step: capturo el aria snapshot del elemento "{element_name}" en la variable "{variable_name}" con identificador "{identifier}"
6429descripcion: Captura el ARIA snapshot acotado a un elemento (subárbol) en una variable.
6430
6431step: la estructura de la página debería coincidir con el aria snapshot
6432descripcion: Valida la estructura de la página completa contra un ARIA snapshot esperado (formato YAML de Playwright) provisto como bloque de texto (docstring) debajo del paso.
6433
6434### Espera por función JavaScript
6435
6436step: espero hasta que se cumpla la función JavaScript "{expression}"
6437descripcion: Detiene la ejecución hasta que una función/expresión JavaScript evaluada en el navegador devuelva un valor verdadero.
6438
6439### CSS en pseudo-elementos (::before / ::after)
6440
6441step: verifico que el pseudo-elemento "{pseudo}" del elemento "{element_name}" tiene el CSS "{prop}" igual a "{value}" con identificador "{identifier}"
6442descripcion: Verifica una propiedad CSS aplicada en un pseudo-elemento (::before o ::after). El pseudo debe ser "before" o "after".
6443
6444### Drop nativo HTML5
6445
6446step: suelto el archivo "{file_path}" en el elemento "{element_name}" con identificador "{identifier}"
6447descripcion: Suelta (drag & drop nativo HTML5) un archivo sobre un elemento, simulando dragenter/dragover/drop que esperan las zonas de carga modernas.
6448
6449step: suelto el texto "{text}" en el elemento "{element_name}" con identificador "{identifier}"
6450descripcion: Suelta (drag & drop nativo HTML5) texto plano sobre un elemento.
6451
6452### Accesibilidad y control de scroll
6453
6454step: hago click en el elemento con rol "{role}" y descripción "{description}"
6455descripcion: Hace click en un elemento localizado por su rol ARIA y su descripción accesible (get_by_role con filtro description).
6456
6457step: hago click en el elemento "{element_name}" sin desplazamiento con identificador "{identifier}"
6458descripcion: Hace click en un elemento SIN el auto-scroll por defecto de Playwright (scroll="none"). Útil con headers/footers sticky o listas virtualizadas. Requiere Playwright 1.62+.
6459
6460## Ejemplo
6461
6462\`\`\`gherkin
6463@PlaywrightModerno
6464Scenario: Estructura accesible + espera por estado de la app
6465  Given voy a la url "\${ENV.BASE_URL}/dashboard"
6466  When capturo el aria snapshot con coordenadas de la página en la variable "mapa_espacial"
6467  And espero hasta que se cumpla la función JavaScript "() => window.appReady === true"
6468  Then la estructura de la página debería coincidir con el aria snapshot
6469    """
6470    - heading "Panel de control" [level=1]
6471    - button "Ingresar"
6472    """
6473\`\`\``}]},{id:"pruebas-api",title:"Pruebas API",group:"Tipos de Prueba",icon:"",topics:[{id:"api-configuracion",title:"Configuración API",content:`## Configurar una Sesión API
6474
6475Antes de enviar peticiones, puedes configurar headers persistentes, autenticación y URL base que se aplican a todas las peticiones del escenario.
6476
6477\`\`\`gherkin
6478Given configuro la API base en "\${ENV.API_BASE_URL}"
6479And configuro el header "Accept" con valor "application/json"
6480And configuro el header "Content-Type" con valor "application/json"
6481And configuro el token Bearer "\${ENV.API_TOKEN}"
6482\`\`\`
6483
6484## Tipos de Autenticación
6485
6486\`\`\`gherkin
6487# Bearer Token
6488Given configuro el token Bearer "mi_token_secreto"
6489
6490# Basic Auth
6491Given configuro autenticacion basica usuario "admin" contrasena "password123"
6492
6493# API Key en header personalizado
6494Given configuro API key en el header "X-API-Key" con valor "\${ENV.API_KEY}"
6495\`\`\`
6496
6497## Consideraciones
6498
6499- Los headers configurados persisten durante todo el escenario.
6500- \`limpio los headers de sesion API\` resetea todos los headers.
6501- Para pruebas sin navegador, usa el tag \`@no_browser\` en el Feature.
6502- Las variables \`\${ENV.X}\` se resuelven desde el \`.env\`.`},{id:"api-peticiones",title:"Peticiones HTTP",content:`## Peticiones GET
6503
6504\`\`\`gherkin
6505When realizo GET a "https://api.miapp.com/users/1"
6506Then la respuesta deberia tener codigo "200"
6507And el campo "name" de la respuesta deberia ser "Juan"
6508\`\`\`
6509
6510## GET con Query Parameters
6511
6512\`\`\`gherkin
6513When realizo GET con parametros '{"page":"1","limit":"10"}' a "\${ENV.API_BASE_URL}/users"
6514Then la respuesta deberia tener codigo "200"
6515\`\`\`
6516
6517## POST Inline
6518
6519\`\`\`gherkin
6520When realizo POST a "\${ENV.API_BASE_URL}/users" con body '{"name": "Ana", "email": "[email protected]"}'
6521Then la respuesta deberia tener codigo "201"
6522And el campo "id" de la respuesta no deberia estar vacio
6523\`\`\`
6524
6525## POST con DocString (JSON multilínea)
6526
6527\`\`\`gherkin
6528When envio JSON body a "\${ENV.API_BASE_URL}/users" via POST
6529  """
6530  {
6531    "name": "Ana García",
6532    "email": "[email protected]",
6533    "role": "admin",
6534    "permissions": ["read", "write", "delete"]
6535  }
6536  """
6537Then la respuesta deberia tener codigo "201"
6538\`\`\`
6539
6540## POST desde archivo externo
6541
6542\`\`\`gherkin
6543When cargo y envio POST a "\${ENV.API_BASE_URL}/users" con body del archivo "payloads/crear_usuario.json"
6544Then la respuesta deberia tener codigo "201"
6545\`\`\`
6546
6547## PUT, PATCH, DELETE
6548
6549\`\`\`gherkin
6550When realizo PUT a "\${ENV.API_BASE_URL}/users/1" con body '{"name": "Ana Actualizada"}'
6551When realizo PATCH a "\${ENV.API_BASE_URL}/users/1" con body '{"status": "active"}'
6552When realizo DELETE a "\${ENV.API_BASE_URL}/users/1"
6553\`\`\`
6554
6555## Ejecutar cURL
6556
6557\`\`\`gherkin
6558When ejecuto la peticion curl y guardo respuesta en "resultado"
6559  """
6560  curl -X POST https://api.ejemplo.com/auth/login \\
6561    -H "Content-Type: application/json" \\
6562    -d '{"email": "[email protected]", "password": "123456"}'
6563  """
6564\`\`\``},{id:"api-validaciones",title:"Validaciones API",content:`## Validar Código de Estado
6565
6566\`\`\`gherkin
6567Then la respuesta deberia tener codigo "200"
6568Then verifico que el estado de respuesta API está en el rango "200" a "299"
6569\`\`\`
6570
6571## Validar Campos JSON
6572
6573\`\`\`gherkin
6574Then el campo "data.user.name" de la respuesta deberia ser "Juan"
6575Then el campo "data.user.email" de la respuesta deberia contener "@empresa"
6576Then el campo "data.token" de la respuesta no deberia estar vacio
6577Then el campo "data.deletedAt" de la respuesta deberia ser nulo
6578\`\`\`
6579
6580## Validar Arrays
6581
6582\`\`\`gherkin
6583Then la respuesta deberia ser un array JSON
6584Then el array "data.items" de la respuesta deberia tener "5" elementos
6585Then el arreglo "$.data.users" deberia tener al menos "1" elementos
6586\`\`\`
6587
6588## Validar con JSONPath
6589
6590\`\`\`gherkin
6591Then existe el campo "$.data.user.id" en la respuesta
6592Then el campo "$.data.user.id" en la respuesta es de tipo "integer"
6593Then verifico que el campo "$.data.price" en la respuesta vale "99.99"
6594Then el campo "$.data.email" en la respuesta coincide con el patron "^[\\w.]+@[\\w]+\\.[a-z]{2,}$"
6595\`\`\`
6596
6597## Validar contra Schema JSON
6598
6599\`\`\`gherkin
6600Then verifico que el JSON de respuesta API coincide con el esquema del archivo "schemas/usuario_schema.json"
6601\`\`\`
6602
6603## Validar contra Respuesta Esperada
6604
6605\`\`\`gherkin
6606Then verifico que el JSON de respuesta API coincide exactamente con el archivo "expected/usuario_esperado.json"
6607Then verifico que el JSON de respuesta API coincide con el archivo "expected/lista.json" ignorando orden
6608Then verifico que el JSON de respuesta API coincide con el archivo "expected/user.json" ignorando campos "id,createdAt,updatedAt"
6609\`\`\`
6610
6611## Validar Performance
6612
6613\`\`\`gherkin
6614Then verifico que el tiempo de respuesta de la API es menor a "3" segundos
6615Then el tiempo de respuesta deberia ser menor a "500" milisegundos
6616\`\`\``},{id:"api-custom-steps",title:"Custom Steps API",content:`## Crear Custom Steps de API
6617
6618Puedes crear pasos personalizados que combinan múltiples operaciones API.
6619
6620\`\`\`python
6621from behave import step
6622
6623@step('obtengo el token de autenticación para "{user}" con clave "{password}"')
6624def step_get_auth_token(context, user, password):
6625    context.api_session.set_header("Content-Type", "application/json")
6626    response = context.api_session.post(
6627        f"{context.env.get('API_BASE_URL')}/auth/login",
6628        json={"email": user, "password": password}
6629    )
6630    assert response.status_code == 200, f"Login falló: {response.status_code}"
6631    token = response.json()["data"]["token"]
6632    context.variable_manager.set_variable("auth_token", token)
6633    context.api_session.set_header("Authorization", f"Bearer {token}")
6634\`\`\`
6635
6636## Ejemplo: CRUD completo
6637
6638\`\`\`python
6639@step('creo un usuario con datos de prueba y guardo su ID')
6640def step_create_test_user(context):
6641    import random, string
6642    random_suffix = ''.join(random.choices(string.ascii_lowercase, k=5))
6643    payload = {
6644        "name": f"Test User {random_suffix}",
6645        "email": f"test_{random_suffix}@qa.com",
6646        "role": "tester"
6647    }
6648    response = context.api_session.post(
6649        f"{context.env.get('API_BASE_URL')}/users",
6650        json=payload
6651    )
6652    assert response.status_code == 201
6653    user_id = response.json()["data"]["id"]
6654    context.variable_manager.set_variable("created_user_id", str(user_id))
6655\`\`\`
6656
6657## Consideraciones
6658
6659- Los custom steps API tienen acceso a \`context.api_session\` para realizar peticiones.
6660- Usa \`context.variable_manager.set_variable()\` para guardar datos entre steps.
6661- \`context.env.get('KEY')\` accede a las variables del \`.env\`.
6662- Puedes combinar steps web y API en un mismo escenario (flujo E2E).`},{id:"steps-api-config",title:"Inventario: Configuración",content:`## Inventario: Configuración de API
6663
6664step: configuro la API base en "{base_url}"
6665descripcion: Establece la URL base para todas las peticiones API del escenario. Las peticiones posteriores usarán esta URL como prefijo.
6666
6667step: configuro el header "{name}" con valor "{value}"
6668descripcion: Agrega o actualiza un header persistente que se enviará en todas las peticiones API del escenario. Útil para Content-Type, Accept, etc.
6669
6670step: configuro el token Bearer "{token}"
6671descripcion: Configura autenticación Bearer Token para todas las peticiones del escenario. Agrega automáticamente el header Authorization con el prefijo "Bearer".
6672
6673step: configuro autenticacion basica usuario "{username}" contrasena "{password}"
6674descripcion: Configura autenticación Basic Auth codificando usuario y contraseña en Base64. Se aplica a todas las peticiones del escenario.
6675
6676step: configuro API key en el header "{header_name}" con valor "{api_key}"
6677descripcion: Configura autenticación mediante API Key en un header personalizado. Permite especificar el nombre del header donde se enviará la clave.
6678
6679step: configuro headers de API
6680descripcion: Configura múltiples headers de una vez usando un DocString JSON en el feature. Permite definir varios headers en un solo paso sin repetir el paso por cada uno.
6681
6682step: limpio los headers de sesion API
6683descripcion: Elimina todos los headers configurados para la sesión actual. Útil para resetear la configuración entre escenarios o cuando se necesita cambiar de contexto de autenticación.
6684
6685step: establezco la URL base de API a "{base_url}"
6686descripcion: Establece una URL base para las peticiones API. Las peticiones a endpoints relativos se 
6686concatenarán con esta URL base.
6687
6688step: establezco el header de API "{header_name}" a "{header_value}"
6689descripcion: Establece un header individual para las próximas peticiones API. El valor puede contener variables del framework que se resolverán al momento de enviar.
6690
6691step: establezco el timeout de API a "{timeout}" segundos
6692descripcion: Establece el tiempo máximo de espera para las peticiones API en segundos. Si una petición excede este tiempo, se lanzará un error de timeout.
6693
6694step: limpio todos los datos de sesión API
6695descripcion: Limpia completamente la sesión API incluyendo headers, URL base, timeout y última respuesta. Resetea todo el estado de la sesión API.`},{id:"steps-api-peticiones",title:"Inventario: Peticiones",content:`## Inventario: Peticiones GET
6696
6697step: realizo GET a "{url}"
6698descripcion: Envía una petición GET usando los headers de sesión configurados previamente. La URL puede ser absoluta o relativa a la URL base configurada.
6699
6700step: realizo GET con parametros "{params}" a "{url}"
6701descripcion: Envía una petición GET con query parameters. Los parámetros se pasan como JSON (ej: {"page":"1","limit":"10"}) y se agregan a la URL automáticamente.
6702
6703step: envío petición GET a "{url}" y guardo la respuesta en la variable "{variable_name}"
6704descripcion: Envía una petición GET y guarda la respuesta completa (status, headers, body, json) en una variable del framework para uso posterior.
6705
6706step: envío petición GET al endpoint "{endpoint}" y guardo la respuesta en la variable "{variable_name}"
6707descripcion: Envía una petición GET concatenando la URL base configurada con el endpoint relativo. Guarda la respuesta en una variable.
6708
6709step: envío petición GET autenticada a "{url}" con token "{token}" y guardo la respuesta en la variable "{variable_name}"
6710descripcion: Envía una petición GET con autenticación Bearer Token. El token se incluye en el header Authorization y la respuesta se guarda en una variable.
6711
6712## Inventario: Peticiones POST/PUT/PATCH/DELETE
6713
6714step: realizo POST a "{url}" con body "{body}"
6715descripcion: Envía una petición POST con body inline. Si el body es JSON válido se envía como application/json, de lo contrario como texto plano.
6716
6717step: realizo PUT a "{url}" con body "{body}"
6718descripcion: Envía una petición PUT con body inline. Detecta automáticamente si el body es JSON para establecer el Content-Type adecuado.
6719
6720step: realizo PATCH a "{url}" con body "{body}"
6721descripcion: Envía una petición PATCH con body inline. Útil para actualizaciones parciales de recursos REST.
6722
6723step: realizo DELETE a "{url}"
6724descripcion: Envía una petición DELETE usando los headers de sesión configurados. No requiere body.
6725
6726step: envío petición POST a "{url}" con cuerpo "{body}" y guardo la respuesta en la variable "{variable_name}"
6727descripcion: Envía una petición POST con cuerpo y guarda la respuesta completa en una variable. Detecta automáticamente si el body es JSON.
6728
6729step: envío petición PUT a "{url}" con cuerpo "{body}" y guardo la respuesta en la variable "{variable_name}"
6730descripcion: Envía una petición PUT con cuerpo y guarda la respuesta completa en una variable del framework.
6731
6732step: envío petición PATCH a "{url}" con cuerpo "{body}" y guardo la respuesta en la variable "{variable_name}"
6733descripcion: Envía una petición PATCH con cuerpo y guarda la respuesta completa en una variable del framework.
6734
6735step: envío petición DELETE a "{url}" y guardo la respuesta en la variable "{variable_name}"
6736descripcion: Envía una petición DELETE y guarda la respuesta completa en una variable del framework.
6737
6738step: envío petición HEAD a "{url}" y guardo la respuesta en la variable "{variable_name}"
6739descripcion: Envía una petición HEAD (solo obtiene headers, sin body) y guarda la respuesta en una variable.
6740
6741step: envío petición OPTIONS a "{url}" y guardo la respuesta en la variable "{variable_name}"
6742descripcion: Envía una petición OPTIONS para consultar los métodos HTTP permitidos y configuración CORS del endpoint.
6743
6744step: envío petición multipart form a "{url}" con campos "{fields}" y guardo la respuesta en la variable "{variable_name}"
6745descripcion: Envía una petición multipart/form-data con campos especificados como JSON. Útil para enviar formularios con múltiples campos.
6746
6747step: subo archivo "{file_path}" al endpoint API "{url}" con nombre de campo "{field_name}" y guardo la respuesta en la variable "{variable_name}"
6748descripcion: Sube un archivo a un endpoint API usando multipart/form-data. Permite especificar el nombre del campo del formulario para el archivo.
6749
6750step: subo archivo "{file_path}" a "{url}" en campo "{field_name}"
6751descripcion: Versión simplificada para subir un archivo via POST multipart/form-data. Usa los headers de sesión configurados (excepto Content-Type).
6752
6753step: envio form data "{form_data}" a "{url}"
6754descripcion: Envía un POST con application/x-www-form-urlencoded. Los datos se pasan como JSON que se convierte a form-data.
6755
6756## Inventario: Peticiones con DocString
6757
6758step: envio JSON body a "{url}" via POST
6759descripcion: Envía un POST con body JSON escrito como DocString multilínea en el feature.
6760
6761step: envio JSON body a "{url}" via PUT
6762descripcion: Envía un PUT con body JSON como DocString multilínea.
6763
6764step: envio JSON body a "{url}" via PATCH
6765descripcion: Envía un PATCH con body JSON como DocString multilínea.
6766
6767step: envio POST a "{url}" y guardo respuesta en "{variable_name}"
6768descripcion: Envía un POST con body como DocString y guarda la respuesta completa en una variable.
6769
6770step: envio PUT a "{url}" y guardo respuesta en "{variable_name}"
6771descripcion: Envía un PUT con body como DocString y guarda la respuesta en una variable del framework.
6772
6773step: envio PATCH a "{url}" y guardo respuesta en "{variable_name}"
6774descripcion: Envía un PATCH con body como DocString y guarda la respuesta en una variable del framework.
6775
6776step: envio DELETE a "{url}" y guardo respuesta en "{variable_name}"
6777descripcion: Envía un DELETE y guarda la respuesta en una variable. Opcionalmente acepta body como DocString.
6778
6779## Inventario: Peticiones desde archivo
6780
6781step: cargo y envio POST a "{url}" con body del archivo "{file_path}"
6782descripcion: Carga el body desde un archivo JSON externo y envía un POST. Útil para payloads grandes.
6783
6784step: cargo y envio PUT a "{url}" con body del archivo "{file_path}"
6785descripcion: Carga el body desde un archivo JSON externo y envía un PUT. Las variables del framework dentro del archivo se resuelven automáticamente.
6786
6787step: cargo y envio PATCH a "{url}" con body del archivo "{file_path}"
6788descripcion: Carga el body desde un archivo JSON externo y envía un PATCH. Soporta resolución de variables dentro del contenido del archivo.
6789
6790step: envio POST desde archivo "{file_path}" a "{url}" y guardo respuesta en "{variable_name}"
6791descripcion: Carga el body desde un archivo, envía POST y guarda la respuesta en una variable.
6792
6793step: envio PUT desde archivo "{file_path}" a "{url}" y guardo respuesta en "{variable_name}"
6794descripcion: Carga el body desde un archivo, envía PUT y guarda la respuesta en una variable del framework.
6795
6796step: envio PATCH desde archivo "{file_path}" a "{url}" y guardo respuesta en "{variable_name}"
6797descripcion: Carga el body desde un archivo, envía PATCH y guarda la respuesta en una variable del framework.
6798
6799step: cargo el cuerpo de petición API del archivo "{file_path}" y envío POST a "{url}" guardando respuesta en variable "{variable_name}"
6800descripcion: Carga el cuerpo de petición desde un archivo (JSON o texto plano) y envía POST. Detecta automáticamente el formato del contenido.
6801
6802step: cargo JSON del archivo "{file_path}" y envío POST a "{url}" guardando respuesta en variable "{variable_name}"
6803descripcion: Carga un archivo JSON y envía POST al endpoint especificado. Guarda la respuesta completa incluyendo status, headers y body en una variable.
6804
6805step: envío peticiones API en lote desde archivo "{requests_file}" y guardo resultados en variable "{variable_name}"
6806descripcion: Envía múltiples peticiones API definidas en un archivo JSON de configuración. Los resultados se guardan como array.
6807
6808## Inventario: Peticiones cURL
6809
6810step: ejecuto la peticion curl y guardo respuesta en "{variable_name}"
6811descripcion: Ejecuta una petición parseando un comando cURL desde DocString. Soporta -X (método), -H (headers), -d (body), URLs y continuación de línea con barra invertida.
6812
6813step: ejecuto la peticion curl del archivo "{file_path}" y guardo respuesta en "{variable_name}"
6814descripcion: Lee un comando cURL desde un archivo de texto y lo ejecuta. Útil para reutilizar comandos cURL exportados desde Postman o el navegador.
6815
6816## Inventario: Interceptación de llamadas API del navegador
6817
6818step: inicio la escucha de llamadas a API
6819descripcion: Activa listeners en el navegador para capturar todas las llamadas API (requests y responses) en background.
6820
6821step: detengo la escucha de llamadas a API
6822descripcion: Desactiva los listeners de captura de llamadas API del navegador.
6823
6824step: detengo la interceptación de llamadas a API
6825descripcion: Detiene la interceptación de rutas del navegador (unroute). Libera el control sobre las peticiones del navegador.
6826
6827step: verifico que se realizó una llamada a la API en "{api_url}"
6828descripcion: Verifica que se capturó una llamada a una URL específica (búsqueda parcial).
6829
6830step: verifico que se realizó una llamada a la API "{api_url}" usando método "{method}"
6831descripcion: Verifica que se realizó una llamada a una API con un método HTTP específico.
6832
6833step: verifico que la llamada a API contiene el parámetro "{parameter}" con valor "{value}"
6834descripcion: Verifica que la última llamada interceptada contiene un parámetro específico con el valor esperado en el body JSON.
6835
6836step: verifico que la llamada a API contiene el header "{header_name}" con valor "{header_value}"
6837descripcion: Verifica que la última llamada interceptada contiene un header específico con el valor esperado.
6838
6839step: verifico que el número de llamadas a la API "{api_url}" es "{expected_count}"
6840descripcion: Verifica que se realizó un número exacto de llamadas a una URL específica.
6841
6842step: verifico que NO se realizó una llamada a la API "{api_url}"
6843descripcion: Verifica que NO se capturó ninguna llamada a una URL específica.
6844
6845step: guardo los datos de la llamada a API en la variable "{variable_name}"
6846descripcion: Guarda los datos completos de la última llamada interceptada (URL, método, headers, body) en una variable del framework.
6847
6848step: limpio las llamadas a API interceptadas
6849descripcion: Limpia el registro de llamadas interceptadas.`},{id:"steps-api-validaciones",title:"Inventario: Validaciones",content:`## Inventario: Validaciones de código de estado
6850
6851step: la respuesta deberia tener codigo "{expected_status}"
6852descripcion: Verifica que el código de estado HTTP de la última respuesta coincide exactamente con el valor esperado.
6853
6854step: verifico que el código de estado de la respuesta API es "{expected_status}"
6855descripcion: Verifica el código de estado de la última respuesta API. Muestra el código actual vs esperado en caso de fallo.
6856
6857step: verifico que el estado de respuesta API está en el rango "{min_status}" a "{max_status}"
6858descripcion: Verifica que el código de estado está dentro de un rango numérico (ej: 200-299 para éxito).
6859
6860step: verifico que la respuesta API sigue las convenciones REST para el método "{http_method}"
6861descripcion: Verifica que el código de estado sigue las convenciones REST según el método HTTP (GET→200, POST→201, PUT/DELETE→200/204).
6862
6863## Inventario: Validaciones de headers
6864
6865step: verifico que el header de respuesta API "{header_name}" es igual a "{expected_value}"
6866descripcion: Verifica que un header de respuesta tiene exactamente el valor esperado.
6867
6868step: verifico que el header de respuesta API "{header_name}" contiene "{expected_text}"
6869descripcion: Verifica que un header de respuesta contiene un texto parcial.
6870
6871step: verifico que el tipo de contenido de respuesta API es "{expected_content_type}"
6872descripcion: Verifica que el Content-Type de la respuesta contiene el tipo esperado.
6873
6874step: verifico que los headers de rate limit están presentes en la respuesta API
6875descripcion: Verifica la presencia de headers de rate limiting (X-RateLimit-Limit, X-RateLimit-Remaining, etc.).
6876
6877step: verifico que la respuesta API tiene headers de seguridad
6878descripcion: Verifica la presencia de headers de seguridad importantes (X-Content-Type-Options, X-Frame-Options, HSTS, CSP, etc.).
6879
6880## Inventario: Validaciones de body y contenido
6881
6882step: verifico que la respuesta API es JSON válido
6883descripcion: Verifica que el cuerpo de la respuesta puede parsearse como JSON válido.
6884
6885step: verifico que la respuesta API contiene "{key}" con valor "{expected_value}"
6886descripcion: Verifica que la respuesta JSON contiene una clave con un valor específico. Soporta notación de punto para claves anidadas.
6887
6888step: verifico que el cuerpo de respuesta API contiene el texto "{expected_text}"
6889descripcion: Verifica que el body de la respuesta (como texto plano) contiene un texto específico.
6890
6891step: verifico que el array JSON de respuesta API tiene "{expected_length}" elementos
6892descripcion: Verifica que la respuesta es un array JSON con exactamente la cantidad de elementos indicada.
6893
6894step: verifico que el elemento "{index}" del array JSON tiene "{key}" con valor "{expected_value}"
6895descripcion: Verifica que un elemento específico de un array JSON (por índice) tiene un campo con el valor esperado.
6896
6897step: la respuesta deberia ser un array JSON
6898descripcion: Verifica que la respuesta completa es un array JSON (lista). Informa la cantidad de elementos.
6899
6900step: la respuesta deberia ser un objeto JSON
6901descripcion: Verifica que la respuesta completa es un objeto JSON (diccionario). Informa la cantidad de campos.
6902
6903step: el body de la respuesta deberia estar vacio
6904descripcion: Verifica que el cuerpo de la respuesta está vacío. Útil para validar respuestas 204 No Content.
6905
6906step: verifico que la respuesta API tiene paginación con total "{expected_total}" y página "{expected_page}"
6907descripcion: Verifica información de paginación buscando campos comunes (total, totalCount, page, currentPage) en la respuesta JSON.
6908
6909## Inventario: Validaciones de campos (notación de punto)
6910
6911step: el campo "{field_path}" de la respuesta deberia ser "{expected_value}"
6912descripcion: Verifica que un campo del JSON tiene el valor exacto esperado. Soporta notación de punto para campos anidados.
6913
6914step: el campo "{field_path}" de la respuesta deberia contener "{expected_value}"
6915descripcion: Verifica que un campo del JSON contiene un valor parcial (búsqueda de substring).
6916
6917step: el campo "{field_path}
6917" de la respuesta no deberia estar vacio
6918descripcion: Verifica que un campo no está vacío (no es None, string vacío ni lista vacía).
6919
6920step: el campo "{field_path}" de la respuesta deberia ser nulo
6921descripcion: Verifica que un campo es null/None en la respuesta JSON.
6922
6923step: el campo "{field_path}" deberia existir en la respuesta
6924descripcion: Verifica que un campo existe en el JSON de respuesta, sin importar su valor.
6925
6926step: el array "{field_path}" de la respuesta deberia tener "{count}" elementos
6927descripcion: Verifica que un array dentro de la respuesta tiene exactamente N elementos.
6928
6929step: el array "{field_path}" de la respuesta deberia tener al menos "{count}" elementos
6930descripcion: Verifica que un array dentro de la respuesta tiene al menos N elementos.
6931
6932## Inventario: Validaciones JSONPath
6933
6934step: existe el campo "{jsonpath}" en la respuesta
6935descripcion: Verifica que un campo existe en la respuesta usando notación JSONPath (ej: "$.data.user.id").
6936
6937step: no existe el campo "{jsonpath}" en la respuesta
6938descripcion: Verifica que un campo NO existe en la respuesta usando notación JSONPath.
6939
6940step: el campo "{jsonpath}" en la respuesta es de tipo "{expected_type}"
6941descripcion: Verifica el tipo de un campo usando JSONPath. Tipos soportados: string, number, integer, boolean, array, object, null.
6942
6943step: verifico que el campo "{jsonpath}" en la respuesta vale "{expected_value}"
6944descripcion: Verifica que un campo JSONPath tiene el valor exacto esperado.
6945
6946step: verifico que el campo "{jsonpath}" en la respuesta contiene "{expected_value}"
6947descripcion: Verifica que un campo JSONPath contiene un valor parcial.
6948
6949step: el campo "{jsonpath}" en la respuesta es nulo
6950descripcion: Verifica que un campo JSONPath es null/None.
6951
6952step: el campo "{jsonpath}" en la respuesta no es nulo
6953descripcion: Verifica que un campo JSONPath no es null.
6954
6955step: el campo "{jsonpath}" en la respuesta esta vacio
6956descripcion: Verifica que un campo JSONPath está vacío (None, string vacío, lista vacía o diccionario vacío).
6957
6958step: el campo "{jsonpath}" en la respuesta no esta vacio
6959descripcion: Verifica que un campo JSONPath no está vacío.
6960
6961step: el campo "{jsonpath}" en la respuesta es mayor que "{expected_value}"
6962descripcion: Verifica que un campo numérico JSONPath es estrictamente mayor que el valor esperado.
6963
6964step: el campo "{jsonpath}" en la respuesta es menor que "{expected_value}"
6965descripcion: Verifica que un campo numérico JSONPath es estrictamente menor que el valor esperado.
6966
6967step: el campo "{jsonpath}" en la respuesta esta entre "{min_value}" y "{max_value}"
6968descripcion: Verifica que un campo numérico JSONPath está dentro del rango [min, max] inclusive.
6969
6970step: el campo "{jsonpath}" en la respuesta coincide con el patron "{pattern}"
6971descripcion: Verifica que un campo JSONPath coincide con una expresión regular.
6972
6973## Inventario: Validaciones de arrays JSONPath
6974
6975step: el arreglo "{jsonpath}" deberia tener "{count}" elementos
6976descripcion: Verifica que un array JSONPath tiene exactamente N elementos.
6977
6978step: el arreglo "{jsonpath}" deberia tener al menos "{count}" elementos
6979descripcion: Verifica que un array JSONPath tiene al menos N elementos.
6980
6981step: en el arreglo "{jsonpath}" en la posicion "{index}" encuentro "{field_path}" con valor "{expected_value}"
6982descripcion: Verifica el valor de un campo en un elemento específico de un array JSONPath.
6983
6984step: en el arreglo "{jsonpath}" en la posicion "{index}" encuentro el campo "{field_path}"
6985descripcion: Verifica que un campo existe en un elemento específico de un array JSONPath.
6986
6987step: el arreglo "{jsonpath}" deberia contener un elemento con "{field_path}" igual a "{expected_value}"
6988descripcion: Busca en todo el array si al menos un elemento tiene un campo con el valor esperado.
6989
6990step: todos los elementos del arreglo "{jsonpath}" deberian tener el campo "{field_path}"
6991descripcion: Verifica que todos los elementos de un array JSONPath tienen un campo específico.
6992
6993step: guardo el campo JSONPath "{jsonpath}" de la respuesta en la variable "{variable_name}"
6994descripcion: Extrae un valor usando JSONPath y lo guarda en una variable del framework.
6995
6996## Inventario: Validaciones avanzadas de JSON
6997
6998step: verifico que el JSON de respuesta API coincide con el esquema del archivo "{schema_file}"
6999descripcion: Valida la respuesta JSON contra un JSON Schema (Draft 7) cargado desde archivo.
7000
7001step: verifico que el JSON de respuesta API coincide exactamente con el archivo "{expected_file}"
7002descripcion: Compara la respuesta JSON byte a byte con el contenido de un archivo.
7003
7004step: verifico que el JSON de respuesta API coincide con el archivo "{expected_file}" ignorando orden
7005descripcion: Compara la respuesta JSON con un archivo ignorando el orden de los elementos en arrays.
7006
7007step: verifico que el JSON de respuesta API coincide con el archivo "{expected_file}" ignorando campos "{ignored_fields}"
7008descripcion: Compara la respuesta JSON con un archivo excluyendo campos específicos (separados por coma).
7009
7010step: verifico que el JSON de respuesta API tiene el campo "{field_path}" con tipo "{expected_type}"
7011descripcion: Verifica que un campo específico tiene el tipo de dato esperado.
7012
7013step: verifico que el campo "{field_path}" del JSON de respuesta API coincide con el patrón "{pattern}"
7014descripcion: Verifica que un campo de la respuesta coincide con una expresión regular.
7015
7016step: verifico que el campo "{field_path}" del JSON de respuesta API está en el rango {min_value} a {max_value}
7017descripcion: Verifica que un campo numérico está dentro de un rango específico [min, max].
7018
7019step: verifico que el array "{array_path}" del JSON de respuesta API contiene un elemento con "{field}" igual a "{value}"
7020descripcion: Busca en un array JSON si existe al menos un elemento cuyo campo especificado tiene el valor indicado.
7021
7022step: verifico que todos los elementos del array "{array_path}" del JSON de respuesta API tienen el campo "{field}"
7023descripcion: Verifica que cada elemento del array tiene un campo específico.
7024
7025step: verifico que el JSON de respuesta API no tiene valores nulos
7026descripcion: Recorre recursivamente toda la respuesta JSON buscando valores null.
7027
7028step: verifico que el esquema JSON de respuesta API coincide con el archivo "{schema_file}"
7029descripcion: Validación básica de esquema JSON verificando tipos y propiedades.
7030
7031step: verifico que la respuesta API coincide con la respuesta esperada del ar
7031chivo "{expected_file}"
7032descripcion: Compara la respuesta JSON completa con un archivo de respuesta esperada.
7033
7034## Inventario: Extracción y almacenamiento de datos
7035
7036step: extraigo el valor de la respuesta API "{key}" y lo guardo en la variable "{variable_name}"
7037descripcion: Extrae un valor de la respuesta JSON usando notación de punto y lo guarda en una variable.
7038
7039step: guardo el campo "{field_path}" de la respuesta en la variable "{variable_name}"
7040descripcion: Extrae un campo del JSON de respuesta y lo guarda en una variable.
7041
7042step: guardo el body completo de la respuesta en la variable "{variable_name}"
7043descripcion: Guarda el body completo de la respuesta como string en una variable.
7044
7045step: guardo el status code de la respuesta en la variable "{variable_name}"
7046descripcion: Guarda el código de estado HTTP de la última respuesta en una variable.
7047
7048step: guardo el header "{header_name}" de la respuesta en la variable "{variable_name}"
7049descripcion: Guarda el valor de un header específico de la respuesta en una variable.
7050
7051step: guardo el JSON de respuesta API en el archivo "{file_path}"
7052descripcion: Guarda la respuesta JSON formateada (con indentación) en un archivo.
7053
7054step: guardo el cuerpo de respuesta API en el archivo "{file_path}"
7055descripcion: Guarda el body de la respuesta (como texto) en un archivo.
7056
7057step: obtengo el valor de la respuesta API capturada "{api_url}" en la ruta "{json_path}" y lo guardo en la variable "{variable_name}"
7058descripcion: Extrae un valor de una respuesta API capturada en background por el listener.
7059
7060## Inventario: Rendimiento y carga
7061
7062step: verifico que el tiempo de respuesta de la API es menor a "{max_seconds}" segundos
7063descripcion: Verifica que el tiempo de respuesta de la última petición API no excede el límite en segundos.
7064
7065step: el tiempo de respuesta deberia ser menor a "{max_ms}" milisegundos
7066descripcion: Verifica que el tiempo de respuesta es menor al límite especificado en milisegundos.
7067
7068step: envío peticiones API concurrentes "{count}" veces a "{url}" y verifico que todas tengan éxito
7069descripcion: Envía múltiples peticiones GET concurrentes usando threads para testing de carga.
7070
7071step: mido el rendimiento de API para "{iterations}" peticiones a "{url}" y guardo métricas en variable "{variable_name}"
7072descripcion: Ejecuta N peticiones secuenciales midiendo tiempos. Calcula métricas (min, max, promedio, mediana, tasa de error).
7073
7074## Inventario: CORS y seguridad
7075
7076step: verifico que el endpoint API "{endpoint}" soporta CORS
7077descripcion: Envía una petición OPTIONS al endpoint y verifica la presencia de headers CORS.
7078
7079## Inventario: Datos de prueba
7080
7081step: creo datos de prueba API con plantilla "{template}" y valores "{values}" guardando en variable "{variable_name}"
7082descripcion: Crea datos de prueba reemplazando placeholders {{key}} en una plantilla JSON con valores proporcionados.`}]},{id:"pruebas-mobile",title:"Pruebas Mobile",group:"Tipos de Prueba",icon:"",topics:[{id:"mobile-setup",title:"Guía de Setup Mobile (Appium)",content:`## Requisitos
7083
7084- Servidor Appium corriendo (\`appium --port 4723\`)
7085- Dispositivo/emulador conectado y visible con \`adb devices\`
7086- App instalada o ruta al APK/IPA disponible
7087
7088## Configuración .env
7089
7090\`\`\`env
7091APPIUM_SERVER_URL=http://localhost:4723
7092APPIUM_PLATFORM_NAME=Android
7093APPIUM_DEVICE_NAME=emulator-5554
7094APPIUM_APP_PACKAGE=com.miapp.android
7095APPIUM_APP_ACTIVITY=.MainActivity
7096APPIUM_AUTOMATION_NAME=UiAutomator2
7097APPIUM_APP_PATH=./app/mi-app.apk
7098APPIUM_TIMEOUT=30000
7099APPIUM_RESET_STRATEGY=noReset
7100\`\`\`
7101
7102## Estrategias de Reset
7103
7104- \`noReset\`: No resetea la app entre tests (mantiene estado).
7105- \`fullReset\`: Desinstala y reinstala la app (estado limpio).
7106- \`fastReset\`: Limpia los datos de la app sin reinstalar.
7107
7108## Ejemplo de Feature
7109
7110\`\`\`gherkin
7111@mobile
7112Feature: Testing de la app mobile
7113
7114  Scenario: Login en la app
7115    Given uso el modo mobile
7116    When escribo texto "[email protected]" en el campo móvil "id:email_input"
7117    And escribo texto "password123" en el campo móvil "id:password_input"
7118    And hago tap simple en el elemento móvil "id:login_button"
7119    Then verifico que el elemento móvil "id:home_screen" es visible
7120\`\`\`
7121
7122## Consideraciones
7123
7124- \`uso el modo mobile\` verifica si la app está instalada y aplica la estrategia de reset configurada.
7125- La sesión se cierra automáticamente al finalizar el escenario.
7126- Puedes combinar pruebas mobile y web en un mismo feature usando \`activo el modo web en el contexto\`.`},{id:"mobile-configuracion",title:"Configuración Mobile",content:`## Tipos de Localizadores Mobile
7127
7128\`\`\`
7129id:mi_elemento          → resource-id (Android) / accessibilityIdentifier (iOS)
7130xpath://android.widget.Button[@text='OK']  → XPath
7131accessibility_id:submit → accessibility id
7132class:android.widget.EditText  → class name
7133\`\`\`
7134
7135## Variables de Entorno Mobile
7136
7137| Variable | Descripción | Ejemplo |
7138|----------|-------------|---------|
7139| APPIUM_SERVER_URL | URL del servidor Appium | http://localhost:4723 |
7140| APPIUM_PLATFORM_NAME | Plataforma | Android / iOS |
7141| APPIUM_DEVICE_NAME | Nombre del dispositivo | emulator-5554 |
7142| APPIUM_APP_PACKAGE | Package de la app (Android) | com.miapp.android |
7143| APPIUM_APP_ACTIVITY | Activity principal (Android) | .MainActivity |
7144| APPIUM_AUTOMATION_NAME | Motor de automatización | UiAutomator2 / XCUITest |
7145| APPIUM_APP_PATH | Ruta al APK/IPA | ./app/mi-app.apk |
7146| APPIUM_TIMEOUT | Timeout por defecto (ms) | 30000 |
7147| APPIUM_RESET_STRATEGY | Estrategia de reset | noReset / fullReset / fastReset |
7148
7149## Consideraciones
7150
7151- Los localizadores \`id:\` buscan por resource-id en Android y accessibilityIdentifier en iOS.
7152- XPath funciona pero es más lento; preferir id o accessibility_id.
7153- El timeout por defecto se usa en todas las esperas implícitas de elementos.`},{id:"mobile-interacciones",title:"Interacciones Mobile",content:`## Taps Básicos
7154
7155\`\`\`gherkin
7156When hago tap simple en el elemento móvil "id:btn_continuar"
7157And hago doble tap en el elemento móvil "id:item_favorito"
7158And hago tap largo simple en el elemento móvil "id:item_lista"
7159And hago tap largo en el elemento móvil "id:item_lista" por "2000" milisegundos
7160\`\`\`
7161
7162## Taps por Texto y Coordenadas
7163
7164\`\`\`gherkin
7165When hago tap en el texto móvil "Aceptar"
7166And hago tap en las coordenadas móvil "200" y "500"
7167And hago tap en el accessibility id "submit_button"
7168\`\`\`
7169
7170## Entrada de Texto
7171
7172\`\`\`gherkin
7173When escribo texto "Juan Pérez" en el campo móvil "id:name_input"
7174And limpio el campo móvil "id:email_input"
7175And agrego texto " Apellido" al campo móvil "id:name_input"
7176And escribo "password" en el campo móvil "id:pass" ocultando teclado
7177\`\`\`
7178
7179## Scroll y Swipe
7180
7181\`\`\`gherkin
7182When hago scroll hacia abajo en el dispositivo
7183And hago scroll hasta el elemento móvil "id:footer"
7184And hago swipe del elemento móvil "id:card" hacia la izquierda
7185And hago swipe desde "100" "500" hasta "100" "200" en el dispositivo
7186\`\`\`
7187
7188## Verificaciones
7189
7190\`\`\`gherkin
7191Then verifico que el elemento móvil "id:welcome" es visible
7192And verifico que el texto del elemento móvil "id:title" es "Bienvenido"
7193And verifico que el elemento móvil "id:btn_submit" está habilitado
7194\`\`\``},{id:"mobile-custom-steps",title:"Custom Steps Mobile",content:`## Crear Custom Steps Mobile
7195
7196\`\`\`python
7197from behave import step
7198
7199@step('hago login mobile con "{user}" y "{password}"')
7200def step_mobile_login(context, user, password):
7201    driver = context.appium_driver
7202    # Limpiar y escribir email
7203    context.mobile_fill("id:email_input", user)
7204    # Limpiar y escribir password
7205    context.mobile_fill("id:password_input", password)
7206    # Tap en botón login
7207    context.mobile_tap("id:login_button")
7208    # Esperar pantalla principal
7209    context.mobile_wait_visible("id:home_screen", timeout=10)
7210\`\`\`
7211
7212## Ejemplo: Navegación con Scroll
7213
7214\`\`\`python
7215@step('busco y selecciono el producto "{product_name}" en la lista')
7216def step_find_product(context, product_name):
7217    max_scrolls = 10
7218    for i in range(max_scrolls):
7219        try:
7220            element = context.mobile_find(f"xpath://*[contains(@text, '{product_name}')]")
7221            if element.is_displayed():
7222                element.click()
7223                return
7224        except:
7225            context.mobile_scroll_down()
7226    raise AssertionError(f"Producto '{product_name}' no encontrado después de {max_scrolls} scrolls")
7227\`\`\`
7228
7229## Helpers Disponibles
7230
7231- \`context.mobile_tap(locator)\` — Tap en elemento
7232- \`context.mobile_fill(locator, text)\` — Escribir en campo (limpia primero)
7233- \`context.mobile_find(locator)\` — Buscar elemento
7234- \`context.mobile_find_all(locator)\` — Buscar todos los elementos
7235- \`context.mobile_wait_visible(locator, timeout)\` — Esperar elemento visible
7236- \`context.mobile_scroll_down()\` — Scroll hacia abajo
7237- \`context.mobile_scroll_up()\` — Scroll hacia arriba
7238- \`context.mobile_swipe(x1, y1, x2, y2)\` — Swipe entre coordenadas
7239- \`context.appium_driver\` — Acceso directo al driver de Appium`},{id:"mobile-inventario-sesion",title:"Inventario: Sesión",content:`## Conexión y Sesión
7240
7241step: uso el modo mobile
7242descripcion: Inicia el modo mobile leyendo la configuración del .env (APPIUM_*), conecta al dispositivo, verifica si la app está instalada y aplica la estrategia de reset configurada.
7243
7244step: desconecto del dispositivo móvil
7245descripcion: Cierra la sesión Appium activa con el dispositivo.
7246
7247step: reinicio la aplicación móvil
7248descripcion: Reinicia la aplicación sin cerrar la sesión Appium.
7249
7250step: lanzo la aplicación móvil
7251descripcion: Lanza la aplicación configurada en las capacidades de Appium.
7252
7253step: cierro la aplicación móvil
7254descripcion: Cierra la aplicación sin cerrar la sesión Appium.
7255
7256step: instalo la aplicación desde la ruta "{app_path}"
7257descripcion: Instala una aplicación en el dispositivo desde la ruta especificada.
7258
7259step: desinstalo la aplicación móvil
7260descripcion: Desinstala la aplicación actual del dispositivo.
7261
7262step: activo la aplicación móvil en primer plano
7263descripcion: Trae la aplicación actual al primer plano del dispositivo.
7264
7265step: termino la aplicación móvil en segundo plano
7266descripcion: Termina la aplicación actual enviándola a segundo plano.
7267
7268step: abro la aplicación móvil con paquete "{app_id}"
7269descripcion: Abre (activa o lanza) una app por su package en Android (ej: com.android.calculator2) o bundleId en iOS (ej: com.apple.Preferences). La app pasa a ser la "actual" para los pasos siguientes.
7270
7271step: abro la aplicación móvil con bundle "{app_id}"
7272descripcion: Alias del paso anterior; abre una app por su identificador (bundleId de iOS o package de Android).
7273
7274step: abro la aplicación "{name}" desde el dispositivo
7275descripcion: Android — abre una app tocando su ícono en el launcher por su nombre visible (ej: "Calculadora", "Ajustes"). Depende del launcher del dispositivo; para máxima fiabilidad usa la apertura por package/bundle id.
7276
7277step: lanzo la actividad "{activity}" del paquete "{package}"
7278descripcion: Android — lanza una actividad específica de un paquete (ej: actividad ".Settings" del paquete "com.android.settings").
7279
7280step: termino la aplicación móvil con paquete "{app_id}"
7281descripcion: Termina en segundo plano una app específica indicada por su package/bundle id.
7282
7283step: verifico que la aplicación con paquete "{app_id}" está instalada
7284descripcion: Verifica que una app esté instalada en el dispositivo, identificada por su package/bundle id.
7285
7286## Navegación del Dispositivo
7287
7288step: presiono atrás en el dispositivo
7289descripcion: Presiona el botón Atrás del dispositivo.
7290
7291step: presiono el botón home del dispositivo
7292descripcion: Presiona el botón Home del dispositivo.
7293
7294step: abro el panel de notificaciones del dispositivo
7295descripcion: Abre el panel de notificaciones del dispositivo (Android).
7296
7297step: cambio la orientación del dispositivo a "{orientation}"
7298descripcion: Cambia la orientación del dispositivo al valor indicado (PORTRAIT o LANDSCAPE).
7299
7300step: cambio la orientación del dispositivo a horizontal
7301descripcion: Cambia la orientación del dispositivo a modo horizontal (LANDSCAPE).
7302
7303step: cambio la orientación del dispositivo a vertical
7304descripcion: Cambia la orientación del dispositivo a modo vertical (PORTRAIT).
7305
7306step: presiono el botón atrás del dispositivo repetidamente "{n}" veces
7307descripcion: Presiona el botón Atrás del dispositivo N veces consecutivas con una pausa entre cada pulsación.
7308
7309step: activo el modo web en el contexto
7310descripcion: Vuelve al modo web en el framework para pruebas mixtas mobile/web.
7311
7312step: abro la url "{url}" en el navegador del dispositivo
7313descripcion: Abre una URL específica en el navegador del dispositivo móvil.
7314
7315## Contextos y Modo Mixto
7316
7317step: cambio al contexto webview del dispositivo
7318descripcion: Cambia al primer contexto WebView disponible para interactuar con contenido web dentro de la app.
7319
7320step: cambio al contexto webview número "{index}" del dispositivo
7321descripcion: Cambia a un contexto WebView específico por su índice cuando hay múltiples WebViews.
7322
7323step: cambio al contexto nativo del dispositivo
7324descripcion: Cambia al contexto nativo (NATIVE_APP) para interactuar con elementos nativos de la app.
7325
7326step: verifico que el contexto actual del dispositivo es "{expected}"
7327descripcion: Verifica que el contexto actual del dispositivo coincida con el valor esperado.
7328
7329step: verifico que hay contextos webview disponibles en el dispositivo
7330descripcion: Verifica que haya al menos un contexto WebView disponible en la aplicación.
7331
7332step: verifico que el contexto actual del dispositivo es nativo
7333descripcion: Verifica que el contexto actual sea NATIVE_APP (modo nativo).
7334
7335## Alertas y Diálogos
7336
7337step: acepto la alerta nativa del dispositivo
7338descripcion: Acepta (presiona OK/Aceptar) una alerta nativa del dispositivo.
7339
7340step: rechazo la alerta del dispositivo
7341descripcion: Rechaza o descarta una alerta nativa del dispositivo.
7342
7343step: obtengo el texto de la alerta del dispositivo y lo guardo en la variable "{var}"
7344descripcion: Obtiene el texto de una alerta nativa y lo almacena en una variable.
7345
7346step: escribo el texto "{text}" en la alerta del dispositivo
7347descripcion: Escribe texto en el campo de entrada de una alerta nativa.
7348
7349step: escribo "{text}" en la alerta del dispositivo y la acepto
7350descripcion: Escribe texto en una alerta nativa y luego la acepta automáticamente.
7351
7352step: verifico que el texto de la alerta del dispositivo es "{expected}"
7353descripcion: Verifica que el texto de la alerta sea exactamente igual al valor esperado.
7354
7355step: verifico que el texto de la alerta del dispositivo contiene "{expected}"
7356descripcion: Verifica que el texto de la alerta contenga el substring esperado.
7357
7358step: acepto la alerta del dispositivo solo si existe
7359descripcion: Acepta una alerta si existe en pantalla, sin fallar si no hay ninguna alerta presente.
7360
7361## Esperas
7362
7363step: espero "{seconds}" segundos en el dispositivo
7364descripcion: Pausa la ejecución durante el número de segundos indicado.
7365
7366step: espero que el elemento móvil "{locator}" sea visible
7367descripcion: Espera hasta que un elemento sea visible en pantalla usando el timeout por defecto.
7368
7369step: espero a que el elemento móvil "{locator}" sea visible en máximo "{seconds}" segundos
7370descripcion: Espera hasta que un elemento sea visible con un timeout específico en segundos.
7371
7372step: espero que el elemento móvil "{locator}" desaparezca
7373descripcion: Espera hasta que un elemento desaparezca de la pantalla.
7374
7375step: espero a que el elemento móvil "{locator}" desaparezca en máximo "{seconds}" segundos
7376descripcion: Espera hasta que un elemento desaparezca con un timeout específico en segundos.
7377
7378step: espero que el texto móvil "{text}" sea visible
7379descripcion: Espera hasta que un texto específico sea visible en la pantalla del dispositivo.
7380
7381step: espero a que el texto móvil "{text}" sea visible en máximo "{seconds}" segundos
7382descripcion: Espera hasta que un texto sea visible con un timeout específico en segundos.
7383
7384step: espero que el elemento móvil "{locator}" exista
7385descripcion: Espera hasta que un elemento exista en el DOM de la aplicación.
7386
7387step: espero a que el elemento móvil "{locator}" exista en máximo "{seconds}" segundos
7388descripcion: Espera hasta que un elemento exista en el DOM con un timeout específico en segundos.
7389
7390step: espero a que la pantalla del dispositivo esté estable durante "{seconds}" segundos
7391descripcion: Espera a que la pantalla no cambie durante N segundos, útil para verificar que animaciones o cargas hayan terminado.
7392
7393## Screenshots y Reportes
7394
7395step: tomo screenshot del dispositivo
7396descripcion: Toma un screenshot del dispositivo y lo agrega automáticamente al reporte HTML.
7397
7398step: tomo un screenshot nombrado "{name}" del dispositivo
7399descripcion: Toma un screenshot con un nombre descriptivo específico y lo agrega al reporte.
7400
7401step: tomo un screenshot del elemento móvil "{locator}"
7402descripcion: Toma un screenshot de un elemento específico de la pantalla.
7403
7404step: tomo un screenshot nombrado "{name}" del elemento móvil "{locator}"
7405descripcion: Toma un screenshot de un elemento específico con un nombre descriptivo.
7406
7407step: tomo un screenshot del dispositivo guardándolo en la variable "{var}"
7408descripcion: Toma un screenshot y guarda la ruta del archivo en una variable para uso posterior.
7409
7410step: tomo un screenshot del dispositivo por fallo del paso anterior
7411descripcion: Toma un screenshot solo si el escenario tiene errores, útil para diagnóstico de fallos.
7412
7413## Ejecución de Scripts y Comandos
7414
7415step: ejecuto el script "{script}" solo en el dispositivo
7416descripcion: Ejecuta un script JavaScript en el contexto WebView del dispositivo.
7417
7418step: ejecuto el script "{script}" en el dispositivo guardando resultado en la variable "{var}"
7419descripcion: Ejecuta un script JavaScript y guarda el resultado en una variable del framework.
7420
7421step: ejecuto el comando mobile "{command}" solo en el dispositivo
7422descripcion: Ejecuta un comando mobile específico de Appium en el dispositivo.
7423
7424step: ejecuto el comando mobile "{command}" con argumentos en el dispositivo
7425descripcion: Ejecuta un comando mobile de Appium con argumentos definidos en una tabla Gherkin (columnas key/value).
7426
7427step: ejecuto el comando mobile "{command}" en el dispositivo guardando resultado en la variable "{var}"
7428descripcion: Ejecuta un comando mobile de Appium y guarda el resultado en una variable.`},{id:"mobile-inventario-taps",title:"Inventario: Taps",content:`## Taps y Clicks
7429
7430step: hago tap simple en el elemento móvil "{locator}"
7431descripcion: Realiza un tap simple en el elemento identificado por el locator.
7432
7433step: hago doble tap en el elemento móvil "{locator}"
7434descripcion: Realiza un doble tap en el elemento identificado por el locator.
7435
7436step: hago tap largo simple en el elemento móvil "{locator}"
7437descripcion: Realiza un long press con duración por defecto (1 segundo) en el elemento.
7438
7439step: hago tap largo en el elemento móvil "{locator}" por "{ms}" milisegundos
7440descripcion: Realiza un long press con una duración específica en milisegundos sobre el elemento.
7441
7442step: hago tap en las coordenadas móvil "{x}" y "{y}"
7443descripcion: Realiza un tap en coordenadas absolutas de pantalla (x, y).
7444
7445step: hago tap en el texto móvil "{text}"
7446descripcion: Realiza un tap en el primer elemento que contiene el texto exacto indicado.
7447
7448step: hago tap en el accessibility id "{acc_id}"
7449descripcion: Realiza un tap usando el accessibility ID del elemento.
7450
7451step: hago tap en el elemento móvil "{locator}" con timeout de "{seconds}" segundos
7452descripcion: Realiza un tap en un elemento con un timeout personalizado de espera.
7453
7454step: hago tap en el primer elemento de la lista "{locator}"
7455descripcion: Realiza un tap en el primer elemento de una lista de coincidencias del locator.
7456
7457step: hago tap en el último elemento de la lista "{locator}"
7458descripcion: Realiza un tap en el último elemento de una lista de coincidencias del locator.
7459
7460step: hago tap en el elemento número "{index}" de la lista "{locator}"
7461descripcion: Realiza un tap en un elemento específico por su índice (base 0) dentro de una lista.
7462
7463step: hago tap en el elemento móvil "{locator}" tras hacer scroll
7464descripcion: Hace scroll hasta encontrar el elemento y luego realiza un tap sobre él.
7465
7466step: hago tap múltiple "{times}" veces en el elemento móvil "{locator}"
7467descripcion: Realiza múltiples taps consecutivos en un elemento la cantidad de veces indicada.
7468
7469step: hago tap en el elemento móvil "{locator}" esperando "{seconds}" segundos
7470descripcion: Realiza un tap en un elemento y luego espera el tiempo indicado en segundos.
7471
7472step: hago tap en el elemento móvil "{locator}" solo si existe
7473descripcion: Realiza un tap en un elemento solo si existe en pantalla, sin fallar si no está presente.`},{id:"mobile-inventario-texto",title:"Inventario: Texto y Teclado",content:`## Entrada de Texto y Teclado
7474
7475step: escribo texto "{text}" en el campo móvil "{locator}"
7476descripcion: Escribe texto en un campo, limpiando primero el contenido existente.
7477
7478step: escribo "{text}" en el campo móvil "{locator}" manteniendo contenido
7479descripcion: Escribe texto en un campo sin limpiar el contenido previo.
7480
7481step: limpio el campo móvil "{locator}"
7482descripcion: Limpia todo el contenido de un campo de texto.
7483
7484step: agrego texto "{text}" al campo móvil "{locator}"
7485descripcion: Agrega texto al final del campo sin borrar el contenido existente.
7486
7487step: limpio y escribo "{text}" en el campo móvil "{locator}"
7488descripcion: Limpia explícitamente el campo y luego escribe el texto indicado.
7489
7490step: escribo "{text}" en el campo móvil "{locator}" ocultando teclado
7491descripcion: Escribe texto en un campo y luego oculta el teclado virtual automáticamente.
7492
7493step: escribo "{text}" en el campo móvil "{locator}" presionando enter
7494descripcion: Escribe texto en un campo y presiona la tecla Enter al finalizar.
7495
7496step: escribo "{text}" en el campo móvil "{locator}" presionando buscar
7497descripcion: Escribe texto en un campo y presiona la tecla Search al finalizar.
7498
7499step: escribo "{text}" en el campo móvil "{locator}" letra por letra
7500descripcion: Escribe texto carácter por carácter, útil para campos con autocompletado que requieren entrada gradual.
7501
7502step: oculto el teclado del dispositivo
7503descripcion: Oculta el teclado virtual del dispositivo.
7504
7505step: presiono la tecla con código "{key_code}" en el dispositivo
7506descripcion: Presiona una tecla específica usando su código Android KeyEvent.
7507
7508step: presiono la tecla Enter en el dispositivo
7509descripcion: Presiona la tecla Enter en el dispositivo.
7510
7511step: presiono la tecla Back en el dispositivo
7512descripcion: Presiona la tecla Back del dispositivo (código 4).
7513
7514step: presiono la tecla Tab en el dispositivo
7515descripcion: Presiona la tecla Tab en el dispositivo.`},{id:"mobile-inventario-scroll",title:"Inventario: Scroll y Swipe",content:`## Scroll y Swipe
7516
7517step: hago scroll hacia abajo en el dispositivo
7518descripcion: Realiza un scroll hacia abajo una vez en la pantalla del dispositivo.
7519
7520step: hago scroll abajo en el dispositivo "{n}" veces
7521descripcion: Realiza scroll hacia abajo N veces consecutivas.
7522
7523step: hago scroll hacia arriba en el dispositivo
7524descripcion: Realiza un scroll hacia arriba una vez en la pantalla del dispositivo.
7525
7526step: hago scroll arriba en el dispositivo "{n}" veces
7527descripcion: Realiza scroll hacia arriba N veces consecutivas.
7528
7529step: hago scroll hacia la izquierda en el dispositivo
7530descripcion: Realiza un scroll hacia la izquierda una vez en la pantalla del dispositivo.
7531
7532step: hago scroll izquierda en el dispositivo "{n}" veces
7533descripcion: Realiza scroll hacia la izquierda N veces consecutivas.
7534
7535step: hago scroll hacia la derecha en el dispositivo
7536descripcion: Realiza un scroll hacia la derecha una vez en la pantalla del dispositivo.
7537
7538step: hago scroll derecha en el dispositivo "{n}" veces
7539descripcion: Realiza scroll hacia la derecha N veces consecutivas.
7540
7541step: hago scroll hasta el elemento móvil "{locator}"
7542descripcion: Realiza scroll hasta que el elemento indicado sea visible en pantalla.
7543
7544step: hago scroll hasta encontrar el elemento móvil "{locator}" limitando a "{max_sw}" intentos
7545descripcion: Realiza scroll hasta encontrar el elemento con un límite máximo de intentos de swipe.
7546
7547step: hago scroll hasta encontrar el texto móvil "{text}"
7548descripcion: Realiza scroll hasta que el texto indicado sea visible en pantalla.
7549
7550step: hago swipe del elemento móvil "{locator}" hacia la izquierda
7551descripcion: Realiza un swipe hacia la izquierda sobre un elemento específico (útil para eliminar o revelar acciones).
7552
7553step: hago swipe del elemento móvil "{locator}" hacia la derecha
7554descripcion: Realiza un swipe hacia la derecha sobre un elemento específico.
7555
7556step: hago swipe desde "{x1}" "{y1}" hasta "{x2}" "{y2}" en el dispositivo
7557descripcion: Realiza un swipe entre dos coordenadas absolutas de pantalla.
7558
7559step: hago swipe desde "{x1}" "{y1}" hasta "{x2}" "{y2}" con duración "{ms}" ms
7560descripcion: Realiza un swipe entre dos coordenadas con una duración específica en milisegundos.
7561
7562step: hago pinch en el elemento móvil "{locator}"
7563descripcion: Realiza un gesto de pinch (zoom out) sobre un elemento.
7564
7565step: hago zoom en el elemento móvil "{locator}"
7566descripcion: Realiza un gesto de zoom (zoom in) sobre un elemento.
7567
7568step: hago scroll hasta el final de la pantalla del dispositivo
7569descripcion: Realiza scroll hasta el final de la pantalla con un máximo de 20 swipes.`},{id:"mobile-inventario-verificaciones",title:"Inventario: Verificaciones",content:`## Verificación de Elementos
7570
7571step: verifico que el elemento móvil "{locator}" es visible
7572descripcion: Verifica que un elemento sea visible en la pantalla del dispositivo.
7573
7574step: verifico que el elemento móvil "{locator}" no es visible
7575descripcion: Verifica que un elemento NO sea visible en la pantalla del dispositivo.
7576
7577step: verifico que el elemento móvil "{locator}" existe
7578descripcion: Verifica que un elemento exista en el DOM de la aplicación.
7579
7580step: verifico que el elemento móvil "{locator}" no existe
7581descripcion: Verifica que un elemento NO exista en el DOM de la aplicación.
7582
7583step: verifico que el elemento móvil "{locator}" está habilitado
7584descripcion: Verifica que un elemento esté habilitado para interacción.
7585
7586step: verifico que el elemento móvil "{locator}" está deshabilitado
7587descripcion: Verifica que un elemento esté deshabilitado y no permita interacción.
7588
7589step: verifico que el elemento móvil "{locator}" está seleccionado
7590descripcion: Verifica que un elemento esté seleccionado (checkbox, radio button).
7591
7592step: verifico que el elemento móvil "{locator}" no está seleccionado
7593descripcion: Verifica que un elemento NO esté seleccionado.
7594
7595step: verifico que el texto del elemento móvil "{locator}" es "{expected}"
7596descripcion: Verifica que el texto de un elemento sea exactamente igual al valor esperado.
7597
7598step: verifico que el texto del elemento móvil "{locator}" contiene "{expected}"
7599descripcion: Verifica que el texto de un elemento contenga el substring esperado.
7600
7601step: verifico que el texto del elemento móvil "{locator}" no contiene "{unexpected}"
7602descripcion: Verifica que el texto de un elemento NO contenga el substring indicado.
7603
7604step: verifico que el texto del elemento móvil "{locator}" no está vacío
7605descripcion: Verifica que el texto de un elemento no esté vacío ni contenga solo espacios.
7606
7607step: verifico que el atributo "{attr}" del elemento móvil "{locator}" es "{expected}"
7608descripcion: Verifica que el valor de un atributo del elemento sea exactamente el esperado.
7609
7610step: verifico que el atributo "{attr}" del elemento móvil "{locator}" contiene "{expected}"
7611descripcion: Verifica que el valor de un atributo del elemento contenga el substring esperado.
7612
7613step: verifico que hay "{count}" elementos móviles "{locator}"
7614descripcion: Verifica que la cantidad exacta de elementos coincida con el número esperado.
7615
7616step: verifico que hay al menos "{count}" elementos móviles "{locator}"
7617descripcion: Verifica que haya al menos N elementos que coincidan con el locator.
7618
7619step: verifico que la orientación del dispositivo es "{orientation}"
7620descripcion: Verifica que la orientación actual del dispositivo sea la esperada (PORTRAIT o LANDSCAPE).
7621
7622## Obtención de Datos y Variables
7623
7624step: obtengo el texto del elemento móvil "{locator}" y lo guardo en la variable "{var}"
7625descripcion: Obtiene el texto de un elemento y lo almacena en una variable del framework para uso posterior.
7626
7627step: obtengo el atributo "{attr}" del elemento móvil "{locator}" y lo guardo en la variable "{var}"
7628descripcion: Obtiene el valor de un atributo de un elemento y lo almacena en una variable.
7629
7630step: obtengo la cantidad de elementos móviles "{locator}" y la guardo en la variable "{var}"
7631descripcion: Cuenta los elementos que coinciden con el locator y guarda el resultado en una variable.
7632
7633step: obtengo la orientación del dispositivo y la guardo en la variable "{var}"
7634descripcion: Obtiene la orientación actual del dispositivo y la almacena en una variable.
7635
7636step: obtengo el tamaño de la pantalla del dispositivo y lo guardo en las variables "{w_var}" y "{h_var}"
7637descripcion: Obtiene el ancho y alto de la pantalla del dispositivo y los guarda en dos variables separadas.
7638
7639step: obtengo la información del dispositivo y la guardo en la variable "{var}"
7640descripcion: Obtiene información completa del dispositivo y la guarda como JSON en una variable.
7641
7642step: obtengo el contexto actual del dispositivo y lo guardo en la variable "{var}"
7643descripcion: Obtiene el contexto actual (NATIVE_APP o WEBVIEW) y lo almacena en una variable.
7644
7645step: obtengo los contextos disponibles del dispositivo y los guardo en la variable "{var}"
7646descripcion: Obtiene la lista de todos los contextos disponibles y la guarda como JSON en una variable.
7647
7648step: obtengo el código fuente de la pantalla del dispositivo y lo guardo en la variable "{var}"
7649descripcion: Obtiene el XML/HTML de la pantalla actual y lo almacena en una variable.
7650
7651step: imprimo la información del dispositivo
7652descripcion: Imprime en el log la información completa del dispositivo conectado.
7653
7654step: imprimo los contextos disponibles del dispositivo
7655descripcion: Imprime en el log la lista de contextos disponibles (NATIVE_APP, WEBVIEW, etc.).
7656
7657step: imprimo el código fuente de la pantalla del dispositivo
7658descripcion: Imprime en el log el XML/HTML de la pantalla actual del dispositivo (primeros 2000 caracteres).`}]},{id:"pruebas-desktop",title:"Pruebas Desktop",group:"Tipos de Prueba",icon:"",topics:[{id:"desktop-setup",title:"Guía de Setup Desktop (PyAutoGUI)",content:`## Requisitos
7659
7660- Python con PyAutoGUI instalado (\`pip install pyautogui\`)
7661- Tesseract OCR instalado (para funciones de lectura de texto)
7662- Imágenes de referencia en carpeta configurada
7663- Pantalla con resolución conocida (las coordenadas son absolutas)
7664
7665## Configuración .env
7666
7667\`\`\`env
7668DESKTOP_IMAGES_PATH=./desktop_images
7669DESKTOP_CONFIDENCE=0.8
7670DESKTOP_TIMEOUT=10
7671DESKTOP_PAUSE=0.5
7672\`\`\`
7673
7674## Ejemplo de Feature
7675
7676\`\`\`gherkin
7677@desktop
7678Feature: Automatización de aplicación de escritorio
7679
7680  Scenario: Abrir calculadora y sumar
7681    Given uso el modo desktop
7682    When abro la aplicacion "calc.exe"
7683    And hago click en la imagen "boton_5"
7684    And hago click en la imagen "boton_suma"
7685    And hago click en la imagen "boton_3"
7686    And hago click en la imagen "boton_igual"
7687    Then deberia ver la imagen "resultado_8" en pantalla
7688\`\`\`
7689
7690## Consideraciones
7691
7692- PyAutoGUI trabaja con coordenadas absolutas de pantalla.
7693- La búsqueda por imagen requiere imágenes de referencia (screenshots recortados).
7694- El nivel de confianza por defecto (0.8) puede ajustarse según la necesidad.
7695- \`uso el modo desktop\` activa el modo escritorio y las capturas del reporte usarán PyAutoGUI.
7696- Puedes combinar pruebas desktop y web usando \`uso el modo web\` para volver al navegador.`},{id:"desktop-automatizacion",title:"Automatización Desktop",content:`## Clicks por Coordenadas
7697
7698\`\`\`gherkin
7699When hago click en las coordenadas "500" "300"
7700And hago doble click en las coordenadas "500" "300"
7701And hago click derecho en las coordenadas "500" "300"
7702And muevo el mouse a las coordenadas "200" "400"
7703\`\`\`
7704
7705## Clicks por Imagen
7706
7707\`\`\`gherkin
7708When hago click en la imagen "boton_aceptar"
7709And hago doble click en la imagen "icono_archivo"
7710And hago click con confianza "0.9" en la imagen "boton_submit"
7711And hago click con desplazamiento "10" "5" en la imagen "campo_texto"
7712\`\`\`
7713
7714## Teclado y Texto
7715
7716\`\`\`gherkin
7717When escribo el texto "Hola mundo"
7718And pego el texto "Texto con ñ y tildes" usando el portapapeles
7719And presiono en escritorio la tecla "enter"
7720And presiono en escritorio las teclas "ctrl" y "s"
7721And presiono en escritorio las teclas "ctrl" mas "shift" mas "s"
7722\`\`\`
7723
7724## Drag and Drop
7725
7726\`\`\`gherkin
7727When arrastro desde las coordenadas "100" "200" hasta las coordenadas "400" "500"
7728And arrastro la imagen "archivo_origen" hacia la imagen "carpeta_destino"
7729And arrastro la imagen "icono" hacia las coordenadas "600" "400"
7730\`\`\`
7731
7732## Modo Mixto Web + Desktop
7733
7734\`\`\`gherkin
7735Given uso el modo web
7736When voy a la url "https://app.ejemplo.com/descargar"
7737And hago click en el elemento "btn_descargar" con identificador "$.DESCARGAS.btn_download"
7738Then uso el modo desktop
7739And espero a que aparezca la imagen "dialogo_guardar"
7740And hago click en la imagen "boton_guardar"
7741Then uso el modo web
7742And debería ver el texto "Descarga completada"
7743\`\`\``},{id:"desktop-custom-steps",title:"Custom Steps Desktop",content:`## Crear Custom Steps Desktop
7744
7745\`\`\`python
7746from behave import step
7747import pyautogui
7748import time
7749
7750@step('abro el archivo "{filename}" en Notepad')
7751def step_open_in_notepad(context, filename):
7752    import subprocess
7753    subprocess.Popen(['notepad.exe', filename])
7754    time.sleep(2)
7755    # Verificar que se abrió
7756    context.desktop_manager.wait_for_image("notepad_title", timeout=5)
7757
7758@step('guardo el documento activo con nombre "{name}"')
7759def step_save_as(context, name):
7760    pyautogui.hotkey('ctrl', 'shift', 's')
7761    time.sleep(1)
7762    pyautogui.typewrite(name, interval=0.05)
7763    pyautogui.press('enter')
7764    time.sleep(1)
7765\`\`\`
7766
7767## Helpers Disponibles
7768
7769- \`context.desktop_manager.click_image(name)\` — Click en imagen
7770- \`context.desktop_manager.find_image(name)\` — Buscar imagen
7771- \`context.desktop_manager.wait_for_image(name, timeout)\` — Esperar imagen
7772- \`context.desktop_manager.type_text(text)\` — Escribir texto
7773- \`context.desktop_manager.paste_text(text)\` — Pegar texto con portapapeles
7774- \`context.desktop_manager.take_screenshot(name)\` — Captura de pantalla
7775- \`context.desktop_manager.read_screen_text()\` — OCR de pantalla completa
7776- \`pyautogui\` — Acceso directo a PyAutoGUI para operaciones avanzadas`},{id:"desktop-inventario-apps",title:"Inventario: Aplicaciones",content:`## Gestión de Aplicaciones
7777
7778step: abro la aplicacion "{app_path}"
7779descripcion: Lanza una aplicación de escritorio y espera 2 segundos antes de continuar con el siguiente paso.
7780
7781step: lanzo y espero "{seconds}" segundos la aplicacion "{app_path}"
7782descripcion: Lanza una aplicación de escritorio y espera el tiempo indicado en segundos antes de continuar.
7783
7784step: lanzo con argumentos "{args}" la aplicacion "{app_path}"
7785descripcion: Lanza una aplicación de escritorio pasándole argumentos de línea de comandos separados por espacios.
7786
7787step: cierro la aplicacion "{process_name}"
7788descripcion: Cierra una aplicación en ejecución buscándola por su nombre de proceso.
7789
7790step: traigo la ventana "{window_title}" al frente
7791descripcion: Trae una ventana al frente del escritorio buscándola por su título.
7792
7793## Modo Mixto (Web + Escritorio)
7794
7795step: uso el modo desktop
7796descripcion: Activa el modo escritorio guardando el estado del navegador. Las capturas del reporte usarán PyAutoGUI.
7797
7798step: uso el modo web
7799descripcion: Vuelve al modo web restaurando la página del navegador. Las capturas del reporte vuelven a usar Playwright.
7800
7801step: uso el modo api
7802descripcion: Activa el modo API donde el reporte mostrará request/response en lugar de screenshots.
7803
7804step: cambio a la aplicacion de escritorio "{app_path}" desde la prueba web
7805descripcion: Lanza una aplicación de escritorio y activa modo desktop sin cerrar el navegador web activo.
7806
7807step: vuelvo al navegador web despues de la interaccion con escritorio
7808descripcion: Vuelve al modo web y trae la ventana del navegador al frente del escritorio.
7809
7810step: capturo el escritorio y vuelvo al navegador con nombre "{name}"
7811descripcion: Toma una captura del escritorio con nombre personalizado y devuelve el foco al navegador web.
7812
7813## Esperas
7814
7815step: espero "{seconds}" segundos en escritorio
7816descripcion: Pausa la ejecución la cantidad de segundos indicada antes de continuar.
7817
7818step: espero a que aparezca la imagen "{image_name}"
7819descripcion: Espera hasta que una imagen aparezca en pantalla usando el timeout por defecto.
7820
7821step: espero con timeout "{timeout}" segundos a que aparezca la imagen "{image_name}"
7822descripcion: Espera hasta que una imagen aparezca en pantalla con un timeout personalizado en segundos.
7823
7824step: espero a que desaparezca la imagen "{image_name}"
7825descripcion: Espera hasta que una imagen deje de estar visible en pantalla usando el timeout por defecto.
7826
7827step: espero con timeout "{timeout}" segundos a que desaparezca la imagen "{image_name}"
7828descripcion: Espera hasta que una imagen desaparezca de pantalla con un timeout personalizado en segundos.
7829
7830## Configuración y Utilidades
7831
7832step: guardo la posicion del mouse en la variable "{variable_name}"
7833descripcion: Obtiene las coordenadas actuales del cursor del mouse y las guarda en una variable.
7834
7835step: guardo el tamano de pantalla en la variable "{variable_name}"
7836descripcion: Obtiene la resolución actual de la pantalla (ancho, alto) y la guarda en una variable.
7837
7838step: establezco la pausa entre acciones en "{seconds}" segundos
7839descripcion: Configura el tiempo de espera automático entre cada acción de PyAutoGUI.
7840
7841step: establezco la confianza de busqueda de imagenes en "{confidence}"
7842descripcion: Configura el nivel de confianza global para la búsqueda de imágenes en pantalla (0.0 a 1.0).
7843
7844step: establezco el timeout de busqueda de imagenes en "{seconds}" segundos
7845descripcion: Configura el tiempo máximo de espera global para encontrar imágenes en pantalla.`},{id:"desktop-inventario-clicks",title:"Inventario: Clicks",content:`## Clicks por Coordenadas
7846
7847step: hago click en las coordenadas "{x}" "{y}"
7848descripcion: Realiza un click izquierdo en las coordenadas absolutas de pantalla indicadas.
7849
7850step: hago doble click en las coordenadas "{x}" "{y}"
7851descripcion: Realiza un doble click en las coordenadas absolutas de pantalla indicadas.
7852
7853step: hago click derecho en las coordenadas "{x}" "{y}"
7854descripcion: Realiza un click derecho en las coordenadas absolutas de pantalla indicadas.
7855
7856step: muevo el mouse a las coordenadas "{x}" "{y}"
7857descripcion: Mueve el cursor del mouse a las coordenadas indicadas sin realizar ningún click.
7858
7859step: escribo en las coordenadas "{x}" "{y}" el texto "{text}"
7860descripcion: Hace click en las coordenadas indicadas, limpia el campo y escribe el texto especificado.
7861
7862step: arrastro desde las coordenadas "{x1}" "{y1}" hasta las coordenadas "{x2}" "{y2}"
7863descripcion: Arrastra el mouse desde unas coordenadas de origen hasta unas coordenadas de destino (drag and drop).
7864
7865## Clicks por Imagen
7866
7867step: hago click en la imagen "{image_name}"
7868descripcion: Busca un elemento en pantalla por imagen de referencia y realiza un click izquierdo sobre él.
7869
7870step: hago doble click en la imagen "{image_name}"
7871descripcion: Busca un elemento en pantalla por imagen de referencia y realiza un doble click sobre él.
7872
7873step: hago click derecho en la imagen "{image_name}"
7874descripcion: Busca un elemento en pantalla por imagen de referencia y realiza un click derecho sobre él.
7875
7876step: paso el mouse sobre la imagen "{image_name}"
7877descripcion: Mueve el cursor sobre un elemento encontrado por imagen sin hacer click (hover).
7878
7879step: hago click con confianza "{confidence}" en la imagen "{image_name}"
7880descripcion: Hace click en un elemento por imagen usando un nivel de confianza personalizado (valor entre 0.0 y 1.0).
7881
7882step: hago click con desplazamiento "{offset_x}" "{offset_y}" en la imagen "{image_name}"
7883descripcion: Hace click en un elemento por imagen aplicando un desplazamiento en píxeles desde el centro de la imagen encontrada.
7884
7885step: escribo en la imagen "{image_name}" el texto "{text}"
7886descripcion: Hace click en un campo encontrado por imagen, limpia su contenido y escribe el texto indicado.
7887
7888step: agrego en la imagen "{image_name}" el texto "{text}"
7889descripcion: Hace click en un campo encontrado por imagen y agrega texto sin borrar el contenido existente.
7890
7891step: arrastro la imagen "{source_image}" hacia la imagen "{target_image}"
7892descripcion: Arrastra un elemento encontrado por imagen origen hacia otro elemento encontrado por imagen destino.
7893
7894step: arrastro la imagen "{source_image}" hacia las coordenadas "{x}" "{y}"
7895descripcion: Arrastra un elemento encontrado por imagen hacia unas coordenadas específicas de pantalla.
7896
7897## Scroll
7898
7899step: hago scroll hacia arriba "{clicks}" veces
7900descripcion: Realiza scroll hacia arriba en la posición actual del mouse la cantidad de clicks indicada.
7901
7902step: hago scroll hacia abajo "{clicks}" veces
7903descripcion: Realiza scroll hacia abajo en la posición actual del mouse la cantidad de clicks indicada.
7904
7905step: hago scroll arriba "{clicks}" veces en la posicion "{x}" "{y}"
7906descripcion: Realiza scroll hacia arriba en unas coordenadas específicas de pantalla.
7907
7908step: hago scroll abajo "{clicks}" veces en la posicion "{x}" "{y}"
7909descripcion: Realiza scroll hacia abajo en unas coordenadas específicas de pantalla.
7910
7911step: hago scroll arriba "{clicks}" veces sobre la imagen "{image_name}"
7912descripcion: Realiza scroll hacia arriba sobre un elemento encontrado por imagen.
7913
7914step: hago scroll abajo "{clicks}" veces sobre la imagen "{image_name}"
7915descripcion: Realiza scroll hacia abajo sobre un elemento encontrado por imagen.`},{id:"desktop-inventario-teclado",title:"Inventario: Teclado",content:`## Teclado y Texto
7916
7917step: escribo el texto "{text}"
7918descripcion: Escribe texto carácter a carácter en el elemento que tiene el foco actualmente.
7919
7920step: pego el texto "{text}" usando el portapapeles
7921descripcion: Escribe texto usando el portapapeles del sistema, soportando tildes, eñes y caracteres especiales.
7922
7923step: limpio el campo y escribo "{text}"
7924descripcion: Selecciona todo el contenido del campo activo, lo borra y escribe el texto nuevo.
7925
7926step: presiono en escritorio la tecla "{key}"
7927descripcion: Presiona una tecla especial en el escritorio (enter, tab, escape, f5, delete, etc.).
7928
7929step: presiono en escritorio las teclas "{key1}" y "{key2}"
7930descripcion: Presiona una combinación de dos teclas simultáneamente (ctrl+c, alt+f4, etc.).
7931
7932step: presiono en escritorio las teclas "{key1}" mas "{key2}" mas "{key3}"
7933descripcion: Presiona una combinación de tres teclas simultáneamente (ctrl+shift+s, etc.).
7934
7935step: mantengo presionada en escritorio la tecla "{key}"
7936descripcion: Mantiene una tecla presionada sin soltarla, útil para combinaciones con arrastre.
7937
7938step: suelto en escritorio la tecla "{key}"
7939descripcion: Suelta una tecla que fue previamente mantenida presionada.
7940
7941step: presiono Enter en escritorio
7942descripcion: Presiona la tecla Enter en el escritorio como atajo rápido.
7943
7944step: presiono Tab en escritorio
7945descripcion: Presiona la tecla Tab en el escritorio como atajo rápido.
7946
7947step: presiono Escape en escritorio
7948descripcion: Presiona la tecla Escape en el escritorio como atajo rápido.
7949
7950step: presiono el atajo de escritorio copiar
7951descripcion: Ejecuta el atajo de teclado Ctrl+C para copiar el contenido seleccionado.
7952
7953step: presiono el atajo de escritorio pegar
7954descripcion: Ejecuta el atajo de teclado Ctrl+V para pegar el contenido del portapapeles.
7955
7956step: presiono el atajo de escritorio seleccionar todo
7957descripcion: Ejecuta el atajo de teclado Ctrl+A para seleccionar todo el contenido.
7958
7959step: presiono el atajo de escritorio guardar
7960descripcion: Ejecuta el atajo de teclado Ctrl+S para guardar el documento activo.
7961
7962step: presiono el atajo de escritorio deshacer
7963descripcion: Ejecuta el atajo de teclado Ctrl+Z para deshacer la última acción.
7964
7965## Portapapeles
7966
7967step: copio el texto "{text}" al portapapeles
7968descripcion: Copia un texto específico al portapapeles del sistema operativo.
7969
7970step: obtengo el contenido del portapapeles y lo guardo en la variable "{variable_name}"
7971descripcion: Lee el contenido actual del portapapeles del sistema y lo guarda en una variable.
7972
7973step: copio el texto seleccionado y lo guardo en la variable "{variable_name}"
7974descripcion: Ejecuta Ctrl+C sobre el texto seleccionado y guarda el resultado en una variable.
7975
7976step: deberia ver que el portapapeles contiene "{expected_text}"
7977descripcion: Verifica que el contenido actual del portapapeles contenga el texto esperado (comparación sin distinción de mayúsculas).`},{id:"desktop-inventario-verificaciones",title:"Inventario: Verificaciones",content:`## Verificaciones Visuales
7978
7979step: deberia ver la imagen "{image_name}" en pantalla
7980descripcion: Verifica que una imagen de referencia esté visible en la pantalla actual. Falla si no la encuentra.
7981
7982step: no deberia ver la imagen "{image_name}" en pantalla
7983descripcion: Verifica que una imagen de referencia NO esté visible en la pantalla actual. Falla si la encuentra.
7984
7985step: verifico con confianza "{confidence}" que la imagen "{image_name}" es visible
7986descripcion: Verifica que una imagen esté visible usando un nivel de confianza personalizado (0.0 a 1.0).
7987
7988step: guardo la ubicacion de la imagen "{image_name}" en la variable "{variable_name}"
7989descripcion: Busca una imagen en pantalla y guarda sus coordenadas (x, y) en una variable para uso posterior.
7990
7991step: cuento las ocurrencias de la imagen "{image_name}" y las guardo en la variable "{variable_name}"
7992descripcion: Busca todas las apariciones de una imagen en pantalla y guarda la cantidad encontrada en una variable.
7993
7994step: verifico que el tamano de pantalla es "{width}" por "{height}"
7995descripcion: Verifica que la resolución de pantalla coincida con el ancho y alto esperados en píxeles.
7996
7997## Capturas de Pantalla
7998
7999step: tomo una captura del escritorio
8000descripcion: Toma una captura de pantalla completa del escritorio y la registra en el reporte HTML.
8001
8002step: capturo el escritorio con nombre "{name}"
8003descripcion: Toma una captura de pantalla completa con un nombre personalizado y la registra en el reporte HTML.
8004
8005step: tomo una captura antes de la accion "{action_name}"
8006descripcion: Toma una captura de pantalla antes de ejecutar una acción, útil para documentar el estado previo.
8007
8008step: tomo una captura despues de la accion "{action_name}"
8009descripcion: Toma una captura de pantalla después de ejecutar una acción, útil para documentar el resultado.
8010
8011step: tomo una captura de la region "{x}" "{y}" "{width}" "{height}" con nombre "{name}"
8012descripcion: Toma una captura de una región específica de la pantalla definida por coordenadas y dimensiones en píxeles.
8013
8014## OCR en Escritorio
8015
8016step: capturo el escritorio y extraigo texto en la variable "{variable_name}"
8017descripcion: Toma captura de pantalla completa, aplica OCR y guarda todo el texto detectado en una variable.
8018
8019step: deberia ver el texto "{expected_text}" en el escritorio usando OCR
8020descripcion: Toma captura del escritorio y verifica que el texto esperado esté presente usando reconocimiento óptico.
8021
8022step: no deberia ver el texto "{unexpected_text}" en el escritorio usando OCR
8023descripcion: Toma captura del escritorio y verifica que el texto NO esté presente usando reconocimiento óptico.
8024
8025step: capturo la region "{x}" "{y}" "{width}" "{height}" y extraigo texto en la variable "{variable_name}"
8026descripcion: Toma captura de una región específica de pantalla y aplica OCR para extraer el texto en una variable.
8027
8028## Lectura y Extracción de Texto
8029
8030step: leo el texto de la pantalla y lo guardo en la variable "{variable_name}"
8031descripcion: Toma screenshot de toda la pantalla, aplica OCR y guarda el texto completo en una variable.
8032
8033step: leo el texto de la pantalla con confianza minima "{confidence}" y lo guardo en la variable "{variable_name}"
8034descripcion: Aplica OCR a la pantalla completa filtrando texto con confianza menor al umbral indicado.
8035
8036step: leo el texto de la region "{x}" "{y}" "{width}" "{height}" y lo guardo en la variable "{variable_name}"
8037descripcion: Toma screenshot de una región específica en píxeles, aplica OCR y guarda el texto en una variable.
8038
8039step: copio y leo el texto seleccionado y lo guardo en la variable "{variable_name}"
8040descripcion: Copia el texto actualmente seleccionado en pantalla (Ctrl+C) y lo guarda en una variable.
8041
8042step: leo el campo imagen "{image_name}" y guardo el texto en la variable "{variable_name}"
8043descripcion: Hace click en un campo por imagen, selecciona todo su contenido, lo copia y guarda el texto en una variable.
8044
8045step: leo el campo en las coordenadas "{x}" "{y}" y guardo el texto en la variable "{variable_name}"
8046descripcion: Hace click en coordenadas, selecciona todo el contenido del campo, lo copia y guarda el texto en una variable.
8047
8048step: selecciono todo y leo el texto del campo activo y lo guardo en la variable "{variable_name}"
8049descripcion: En el campo con foco actual, selecciona todo (Ctrl+A), copia (Ctrl+C) y guarda el texto en una variable.
8050
8051## Verificaciones de Texto Leído
8052
8053step: el texto leido en la variable "{variable_name}" deberia contener "{expected_text}"
8054descripcion: Verifica que el texto guardado en una variable contenga el texto esperado (sin distinción de mayúsculas).
8055
8056step: el texto leido en la variable "{variable_name}" deberia ser exactamente "{expected_text}"
8057descripcion: Verifica que el texto guardado en una variable sea exactamente igual al texto esperado.`}]},{id:"pruebas-bd",title:"Pruebas Base de Datos",group:"Tipos de Prueba",icon:"",topics:[{id:"bd-conexion",title:"Conexión y Consultas",content:`## Conexión a Base de Datos
8058
8059El framework soporta conexiones a SQLite y bases de datos configuradas por entorno (.env).
8060
8061### Configuración .env
8062
8063\`\`\`env
8064# PostgreSQL
8065DB_TYPE=postgresql
8066DB_POSTGRES_HOST=localhost
8067DB_POSTGRES_PORT=5432
8068DB_POSTGRES_DATABASE=mi_base_datos
8069DB_POSTGRES_USERNAME=usuario
8070DB_POSTGRES_PASSWORD=mi_password
8071DB_POSTGRES_SCHEMA=public
8072
8073# MySQL (alternativa)
8074# DB_TYPE=mysql
8075# DB_MYSQL_HOST=localhost
8076# DB_MYSQL_PORT=3306
8077# DB_MYSQL_DATABASE=mi_base_datos
8078# DB_MYSQL_USERNAME=usuario
8079# DB_MYSQL_PASSWORD=mi_password
8080# DB_MYSQL_CHARSET=utf8mb4
8081
8082# SQLite (alternativa)
8083# DB_TYPE=sqlite
8084# DB_SQLITE_PATH=test_data/test.db
8085\`\`\`
8086
8087### Ejemplo: Consulta y Validación
8088
8089\`\`\`gherkin
8090@no_browser
8091Feature: Validar datos en base de datos
8092
8093  Scenario: Verificar usuario creado
8094    Given me conecto a la base de datos usando configuración del entorno
8095    When ejecuto la consulta SQL "SELECT * FROM usuarios WHERE email = '[email protected]'" y guardo el resultado en la variable "resultado"
8096    Then verifico que el resultado de la consulta SQL tiene "1" filas
8097    And verifico que el resultado SQL contiene una fila con "email" igual a "[email protected]"
8098    And cierro la conexión a la base de datos
8099\`\`\`
8100
8101### Ejemplo: SQLite directo
8102
8103\`\`\`gherkin
8104  Scenario: Consultar SQLite local
8105    Given me conecto a la base de datos SQLite "./test_data/app.db"
8106    When ejecuto la consulta SQL "SELECT count(*) as total FROM productos" y guardo el resultado en la variable "conteo"
8107    Then obtengo el valor del resultado SQL de la columna "total" fila "0" y lo guardo en la variable "total_productos"
8108    And verifico que la variable "total_productos" es igual a "15"
8109\`\`\`
8110
8111### Ejemplo: Inserción y Backup
8112
8113\`\`\`gherkin
8114  Scenario: Insertar datos y hacer backup
8115    Given me conecto a la base de datos "mi_db"
8116    When inserto datos de prueba en la tabla "usuarios" con valores '{"nombre": "Ana", "email": "[email protected]", "rol": "admin"}'
8117    And ejecuto la actualización SQL "UPDATE usuarios SET activo = 1 WHERE email = '[email protected]'"
8118    Then hago backup de la base de datos al archivo "./backups/pre_test.sql"
8119    And cierro la conexión a la base de datos
8120\`\`\`
8121
8122## Consideraciones
8123
8124- Usa el tag \`@no_browser\` para pruebas de BD que no necesitan navegador.
8125- Los resultados de consultas se guardan como JSON en variables.
8126- \`obtengo el valor del resultado SQL\` permite extraer celdas específicas por columna y fila.
8127- Siempre cierra la conexión al finalizar con \`cierro la conexión a la base de datos\`.`}
8127,{id:"bd-inventario",title:"Inventario: Pasos BD",content:`## Conexión
8128
8129step: me conecto a la base de datos "{db_name}"
8130descripcion: Conecta a una base de datos usando la configuración del archivo .env o un nombre/ruta específico. Soporta SQLite (por extensión .db/.sqlite) y conexiones configuradas por entorno.
8131
8132step: me conecto a la base de datos SQLite "{db_path}"
8133descripcion: Conecta directamente a una base de datos SQLite especificando la ruta del archivo.
8134
8135step: me conecto a la base de datos usando configuración del entorno
8136descripcion: Conecta a la base de datos utilizando las variables de configuración definidas en el archivo .env (DB_TYPE, DB_HOST, etc.).
8137
8138step: cierro la conexión a la base de datos
8139descripcion: Cierra la conexión activa a la base de datos. Si no hay conexión abierta, muestra una advertencia sin generar error.
8140
8141## Creación y Estructura
8142
8143step: creo base de datos de prueba con datos de ejemplo
8144descripcion: Crea una base de datos de prueba con tablas y datos de ejemplo precargados para facilitar las pruebas.
8145
8146step: creo la tabla "{table_name}" con columnas "{columns_definition}"
8147descripcion: Crea una tabla nueva con la definición de columnas especificada. Usa CREATE TABLE IF NOT EXISTS para evitar errores si ya existe.
8148
8149step: elimino la tabla "{table_name}"
8150descripcion: Elimina una tabla de la base de datos usando DROP TABLE IF EXISTS.
8151
8152## Consultas SELECT
8153
8154step: ejecuto la consulta SQL "{query}" y guardo el resultado en la variable "{variable_name}"
8155descripcion: Ejecuta una consulta SQL de lectura (SELECT) y guarda el resultado como JSON en una variable. También almacena el resultado en context.last_db_results para validaciones posteriores.
8156
8157step: obtengo el valor del resultado SQL de la columna "{column}" fila "{row_index}" y lo guardo en la variable "{variable_name}"
8158descripcion: Extrae un valor específico del último resultado SQL indicando columna e índice de fila, y lo guarda en una variable para uso posterior.
8159
8160## Operaciones de Escritura
8161
8162step: ejecuto la actualización SQL "{query}"
8163descripcion: Ejecuta una consulta SQL de modificación (INSERT, UPDATE, DELETE) e informa la cantidad de filas afectadas.
8164
8165step: inserto datos de prueba en la tabla "{table_name}" con valores "{values}"
8166descripcion: Inserta datos en una tabla a partir de valores en formato JSON. Soporta inserción de una fila o múltiples filas simultáneamente.
8167
8168## Verificaciones
8169
8170step: verifico que el resultado de la consulta SQL tiene "{expected_count}" filas
8171descripcion: Valida que el último resultado SQL obtenido contenga exactamente la cantidad de filas esperada. Falla si el conteo no coincide.
8172
8173step: verifico que el resultado SQL contiene una fila con "{column}" igual a "{expected_value}"
8174descripcion: Verifica que en el último resultado SQL exista al menos una fila donde la columna indicada tenga el valor esperado.
8175
8176## Backup
8177
8178step: hago backup de la base de datos al archivo "{backup_file}"
8179descripcion: Realiza un respaldo de la base de datos actual guardándolo en el archivo especificado.`},{id:"bd-email",title:"Inventario: Pasos Email",content:`## Email (SMTP/IMAP)
8180
8181Steps para enviar y leer emails. Permiten verificar flujos que dependen de correos: confirmaciones de registro, códigos de verificación (MFA por email), notificaciones, etc.
8182
8183> Estos pasos usan el tag \`@no_browser\` porque no requieren navegador.
8184
8185## Envío de Email (SMTP)
8186
8187step: establezco las credenciales de email remitente="{sender}" contraseña="{password}"
8188descripcion: Establece las credenciales para envío de email.
8189
8190step: envío email a "{recipient}" con asunto "{subject}" y cuerpo "{body}" usando SMTP "{smtp_server}" puerto "{port}"
8191descripcion: Envía un email usando SMTP con las credenciales previamente configuradas.
8192
8193## Lectura de Email (IMAP)
8194
8195step: me conecto al servidor IMAP "{imap_server}" puerto "{port}" con usuario "{username}" contraseña "{password}"
8196descripcion: Conecta a un servidor IMAP para leer emails.
8197
8198step: selecciono la carpeta de email "{folder}"
8199descripcion: Selecciona una carpeta de email (INBOX, SENT, etc.).
8200
8201step: busco emails con asunto que contiene "{subject_text}" y guardo el conteo en la variable "{variable_name}"
8202descripcion: Busca emails por asunto y guarda el conteo en una variable.
8203
8204step: obtengo el contenido del email más reciente y lo guardo en la variable "{variable_name}"
8205descripcion: Obtiene el contenido del email más reciente de la carpeta seleccionad
8205a.
8206
8207step: verifico que se recibió un email con asunto "{subject}" dentro de "{timeout}" segundos
8208descripcion: Espera y verifica que se recibió un email con un asunto específico dentro del tiempo límite.
8209
8210step: extraigo el código de verificación del cuerpo del email y lo guardo en la variable "{variable_name}"
8211descripcion: Extrae un código de verificación (numérico o alfanumérico) del último email recibido.
8212
8213step: elimino emails con asunto que contiene "{subject_text}"
8214descripcion: Elimina emails que contienen un texto específico en el asunto. Útil para limpiar la bandeja después de las pruebas.
8215
8216step: cierro la conexión de email
8217descripcion: Cierra la conexión IMAP activa.
8218
8219## Ejemplo Completo
8220
8221\`\`\`gherkin
8222@no_browser
8223Feature: Verificación de email de registro
8224
8225  Scenario: El usuario recibe código de verificación por email
8226    Given establezco las credenciales de email remitente="[email protected]" contraseña="app_password_123"
8227    And me conecto al servidor IMAP "imap.gmail.com" puerto "993" con usuario "[email protected]" contraseña "app_password_123"
8228    And selecciono la carpeta de email "INBOX"
8229    And elimino emails con asunto que contiene "Código de verificación"
8230    When envío email a "[email protected]" con asunto "Bienvenido" y cuerpo "Tu cuenta fue creada" usando SMTP "smtp.gmail.com" puerto "587"
8231    Then verifico que se recibió un email con asunto "Código de verificación" dentro de "30" segundos
8232    And extraigo el código de verificación del cuerpo del email y lo guardo en la variable "codigo_mfa"
8233    And cierro la conexión de email
8234\`\`\`
8235
8236> Para Gmail, usa una contraseña de aplicación (App Password) en vez de tu contraseña normal.`}]},{id:"pruebas-genai",title:"Pruebas GenAI",group:"Tipos de Prueba",icon:"",topics:[{id:"genai-evaluacion",title:"Evaluación con Gemini",content:`## Evaluación de IA con Gemini como Juez
8237
8238El framework permite evaluar respuestas de sistemas de IA usando Gemini como juez imparcial en 7 dimensiones: precisión, cumplimiento, tono, coherencia, context relevance, faithfulness y answer relevance.
8239
8240### Configuración .env
8241
8242\`\`\`env
8243GEMINI_API_KEY=tu_api_key
8244GEMINI_DEFAULT_THRESHOLD=0.80
8245GEMINI_JUDGE_MODEL=gemini-3.1-flash-lite
8246\`\`\`
8247
8248### Flujo Básico
8249
8250\`\`\`gherkin
8251@no_browser
8252Feature: Evaluar chatbot de soporte
8253
8254  Scenario: Validar respuesta sobre políticas de devolución
8255    Given el contexto de reglas de negocio "soporte" está cargado desde el archivo "contextos/politicas_devolucion.txt"
8256    When interactúo con la IA con el prompt "¿Cuál es la política de devolución?"
8257    Then el Juez Gemini debe validar la respuesta con un umbral mínimo de 0.85
8258\`\`\`
8259
8260### Validación Directa (un solo paso)
8261
8262\`\`\`gherkin
8263  Scenario: Validar par pregunta-respuesta
8264    Given el contexto de reglas de negocio "FAQ" está cargado desde el archivo "contextos/faq.txt"
8265    Then valido con Gemini que según el contexto para la pregunta "¿Horario de atención?" la respuesta "Lunes a viernes de 9 a 18 hrs" es válida con umbral 0.80
8266\`\`\`
8267
8268### Criterios Personalizados
8269
8270\`\`\`gherkin
8271  Scenario: Validar con criterios específicos
8272    Given el contexto de reglas de negocio "legal" está cargado desde el archivo "contextos/terminos.txt"
8273    When establezco la respuesta del SUT como "El plazo es de 30 días hábiles según la ley."
8274    Then el Juez Gemini debe validar la respuesta con criterios personalizados "precisión legal,citas normativas,lenguaje formal" y umbral 0.90
8275\`\`\`
8276
8277### Consideraciones
8278
8279- El Juez evalúa en 7 dimensiones por defecto, devolviendo un score promedio.
8280- Context Caching se usa automáticamente para contextos mayores a 32k tokens.
8281- Puedes guardar evaluaciones con \`guardo la evaluación del Juez en el archivo\`.
8282- El tag \`@no_browser\` es recomendado para pruebas puramente de GenAI.`},{id:"genai-semantica",title:"Validación Semántica",content:`## Validación Semántica con Embeddings
8283
8284Usa modelos de Sentence Transformers para comparar textos por significado (no por texto exacto).
8285
8286### Configuración
8287
8288\`\`\`gherkin
8289Given configuro el modelo semántico como "paraphrase-multilingual-MiniLM-L12-v2"
8290And establezco el umbral de similitud semántica en 0.80
8291\`\`\`
8292
8293### Comparación de Textos
8294
8295\`\`\`gherkin
8296Then el texto "El auto es rojo" debe ser semánticamente similar a "El vehículo tiene color rojo"
8297And el texto de la variable "respuesta_chatbot" debe ser semánticamente similar a "Nuestro horario es de 9 a 18"
8298\`\`\`
8299
8300### Análisis de Sentimiento
8301
8302\`\`\`gherkin
8303Then el sentimiento del texto "¡Excelente servicio, muy satisfecho!" debe ser "positivo"
8304And el sentimiento de la variable "feedback_cliente" debe ser "negativo"
8305\`\`\`
8306
8307### Clasificación de Texto
8308
8309\`\`\`gherkin
8310Then el texto "Quiero devolver mi producto" debe pertenecer a la categoría "devolución" de "consulta,reclamo,devolución,soporte"
8311\`\`\`
8312
8313### NLP Avanzado
8314
8315\`\`\`gherkin
8316When extraigo las entidades del texto "Juan visitó París el 15 de marzo" y las guardo en "entidades"
8317And genero un resumen del texto "..." y lo guardo en "resumen"
8318And analizo la toxicidad del texto "mensaje del usuario" y guardo el resultado en "es_toxico"
8319Then verifico que el texto "mensaje del usuario" no es tóxico
8320\`\`\`
8321
8322### Supabase Vector (RAG)
8323
8324\`\`\`gherkin
8325Given me conecto a Supabase usando variables de entorno
8326When busco en la tabla "knowledge_base" el contexto más similar a "política de reembolso" y lo guardo en "contexto"
8327Then el Juez Gemini debe validar la respuesta con un umbral mínimo de 0.85
8328\`\`\``}
8328,{id:"genai-inventario",title:"Inventario: Pasos GenAI",content:`## Evaluación con Gemini
8329
8330step: el contexto de reglas de negocio "{context_name}" está cargado desde el archivo "{file_path}"
8331descripcion: Carga el contexto de reglas de negocio desde un archivo. Si supera 32k tokens usa Context Caching de Gemini, si es menor lo almacena como system_instruction.
8332
8333step: cambio al contexto de reglas de negocio "{context_name}"
8334descripcion: Cambia al contexto de reglas de negocio especificado cuando hay múltiples contextos cargados.
8335
8336step: limpio todos los cachés de contexto
8337descripcion: Elimina todos los cachés de contexto creados en Gemini para liberar recursos.
8338
8339step: interactúo con la IA con el prompt "{user_query}"
8340descripcion: Envía un prompt al Sistema Bajo Prueba (SUT) y guarda la respuesta para evaluación posterior.
8341
8342step: envío el prompt "{user_query}" a la IA
8343descripcion: Alias para interactuar con el SUT enviando un prompt y guardando la respuesta.
8344
8345step: establezco la respuesta del SUT como "{response_text}"
8346descripcion: Establece manualmente la respuesta del Sistema Bajo Prueba, útil para simular respuestas en testing.
8347
8348step: la respuesta del SUT es "{response_text}"
8349descripcion: Alias para establecer manualmente la respuesta del SUT.
8350
8351step: cargo la respuesta del SUT desde el archivo "{file_path}"
8352descripcion: Carga la respuesta del Sistema Bajo Prueba desde un archivo de texto.
8353
8354step: Gemini genera la respuesta para el prompt "{user_query}"
8355descripcion: Genera una respuesta usando Gemini basándose en el contexto de negocio cargado. Útil para crear golden answers o comparar con tu IA.
8356
8357step: genero la respuesta con Gemini para el prompt "{user_query}"
8358descripcion: Alias para generar una respuesta con Gemini usando el contexto de negocio activo.
8359
8360step: el Juez Gemini debe validar la respuesta con un umbral mínimo de {threshold}
8361descripcion: Evalúa la respuesta del SUT usando Gemini como Juez en 7 dimensiones (precisión, cumplimiento, tono, coherencia, context relevance, faithfulness, answer relevance).
8362
8363step: el Juez Gemini valida la respuesta con umbral {threshold}
8364descripcion: Alias para la validación del Juez Gemini con umbral especificado.
8365
8366step: el Juez Gemini debe validar la respuesta
8367descripcion: Evalúa la respuesta del SUT usando Gemini como Juez con el umbral configurado en .env o el valor por defecto (0.80
8367).
8368
8369step: el Juez Gemini debe validar la respuesta con criterios personalizados "{criteria}" y umbral {threshold}
8370descripcion: Evalúa la respuesta del SUT con criterios personalizados separados por comas y un umbral específico.
8371
8372step: valido con Gemini que según el contexto para la pregunta "{pregunta}" la respuesta "{respuesta}" es válida con umbral {threshold}
8373descripcion: Valida un par pregunta-respuesta directamente en un solo paso, combinando establecer pregunta, respuesta y validar.
8374
8375step: el Juez Gemini valida que para la pregunta "{pregunta}" la respuesta "{respuesta}" es correcta con umbral {threshold}
8376descripcion: Alias para validar un par pregunta-respuesta en un solo paso con el Juez Gemini.
8377
8378step: guardo la evaluación del Juez en el archivo "{file_path}"
8379descripcion: Guarda la última evaluación del Juez Gemini en un archivo JSON para análisis posterior.
8380
8381step: el score de la última evaluación debe ser mayor o igual a {min_score}
8382descripcion: Verifica que el score de la última evaluación del Juez cumple con un mínimo requerido.
8383
8384## Steps Avanzados de GenAI
8385
8386step: valido que la respuesta del SUT está en idioma "{language}"
8387descripcion: Valida que la respuesta del Sistema Bajo Prueba está escrita en el idioma especificado usando Gemini para la detección.
8388
8389step: verifico que la respuesta está en "{language}"
8390descripcion: Alias para validar el idioma de la respuesta del SUT.
8391
8392step: valido que la respuesta del SUT es un JSON válido
8393descripcion: Verifica que la respuesta del SUT sea un JSON válido y lo parsea para uso posterior.
8394
8395step: verifico que la respuesta es JSON válido
8396descripcion: Alias para validar que la respuesta del SUT es JSON válido.
8397
8398step: valido que el JSON de respuesta tiene la estructura "{schema_file}"
8399descripcion: Valida que el JSON de respuesta cumple con un esquema JSON específico cargado desde un archivo.
8400
8401step: verifico que el JSON cumple con el esquema "{schema_file}"
8402descripcion: Alias para validar la estructura JSON contra un esquema.
8403
8404step: valido que la intención de la respuesta es "{expected_intent}"
8405descripcion: Detecta y valida que la intención de la respuesta del SUT coincide con la esperada (informativa, persuasiva, etc.).
8406
8407step: verifico que la intención detectada es "{expected_intent}"
8408descripcion: Alias para validar la intencionalidad de la respuesta.
8409
8410step: valido que la respuesta rechaza el prompt adversarial
8411descripcion: Verifica que la IA rechaza correctamente un intento de manipulación o jailbreaking sin proporcionar información sensible.
8412
8413step: verifico que la IA rechaza el intento de jailbreaking
8414descripcion: Alias para validar el rechazo de prompts adversariales.
8415
8416step: valido que la respuesta no contiene alucinaciones según el contexto
8417descripcion: Detecta si la respuesta contiene información inventada (alucinaciones) que no está en el contexto de negocio.
8418
8419step: verifico que no hay hallucinations en la respuesta
8420descripcion: Alias para la detección de alucinaciones en la respuesta del SUT.
8421
8422step: valido que la respuesta no contiene sesgos de "{bias_type}"
8423descripcion: Detecta si la respuesta contiene sesgos específicos (género, edad, raza, etc.) como estereotipos o generalizaciones injustas.
8424
8425step: verifico que no hay sesgo de "{bias_type}" en la respuesta
8426descripcion: Alias para la detección de sesgos en la respuesta.
8427
8428step: valido que la respuesta no contiene lenguaje tóxico
8429descripcion: Detecta si la respuesta contiene lenguaje tóxico, ofensivo o inapropiado para un contexto profesional.
8430
8431step: verifico que la respuesta es profesional y respetuosa
8432descripcion: Alias para validar que la respuesta no contiene toxicidad.
8433
8434step: valido que las respuestas "{var1}" y "{var2}" son consistentes
8435descripcion: Valida que dos respuestas almacenadas en variables son consistentes entre sí, sin contradicciones ni inconsistencias lógicas.
8436
8437step: verifico consistencia entre "{var1}" y "{var2}"
8438descripcion: Alias para validar la consistencia entre dos respuestas.
8439
8440step: valido que la respuesta cita fuentes correctamente
8441descripcion: Verifica que la respuesta cita fuentes de forma específica y verificable, evaluando la calidad de la citación.
8442
8443step: verifico que hay citación de fuentes en la respuesta
8444descripcion: Alias para validar la citación de fuentes en la respuesta.
8445
8446## Validación Semántica
8447
8448step: configuro el modelo semántico como "{model_name}"
8449descripcion: Configura el modelo de Sentence Transformers a utilizar para las validaciones semánticas.
8450
8451step: establezco el umbral de similitud semántica en {threshold}
8452descripcion: Establece el umbral de similitud (0.0 a 1.0) para las validaciones semánticas.
8453
8454step: uso la configuración semántica por defecto
8455descripcion: Configura modelo y umbral por defecto leyendo desde variables de entorno SEMANTIC_MODEL y SEMANTIC_THRESHOLD.
8456
8457step: el texto "{actual_text}" debe ser semánticamente similar a "{expected_text}"
8458descripcion: Verifica que dos textos sean semánticamente similares según el umbral configurado, usando embeddings y similitud de coseno.
8459
8460step: el texto de la variable "{var_name}" debe ser semánticamente similar a "{expected_text}"
8461descripcion: Verifica que el texto almacenado en una variable sea semánticamente similar al texto esperado.
8462
8463step: calculo la similitud semántica entre "{text1}" y "{text2}" y la guardo en "{var_name}"
8464descripcion: Calcula la similitud semántica entre dos textos y almacena el resultado numérico en una variable.
8465
8466step: el texto del elemento "{element_name}" con identificador "{locator}" debe ser semánticamente similar a "{expected_text}"
8467descripcion: Verifica que el texto de un elemento web sea semánticamente similar al texto esperado.
8468
8469## Semántica Avanzada
8470
8471step: el sentimiento del texto "{text}" debe ser "{expected_sentiment}"
8472descripcion: Analiza el sentimiento de un texto y verifica que coincida con el esperado (positivo, negativo o neutral).
8473
8474step: el sentimiento de la variable "{var_name}" debe ser "{expected_sentiment}"
8475descripcion: Analiza el sentimiento del texto almacenado en una variable y verifica que sea el esperado.
8476
8477step: clasifico el texto "{text}" en las categorías "{categories}" y guardo el resultado en "{var_name}"
8478descripcion: Clasifica un texto en una de las categorías proporcionadas (separadas por comas) usando similitud semántica.
8479
8480step: el texto "{text}" debe pertenecer a la categoría "{expected_category}" de "{categories}"
8481descripcion: Verifica que un texto pertenezca a una categoría específica dentro de un conjunto de categorías posibles.
8482
8483step: detecto el idioma del texto "{text}" y lo guardo en "{var_name}"
8484descripcion: Detecta el idioma de un texto usando similitud semántica con textos de referencia y guarda el resultado.
8485
8486step: el idioma del texto "{text}" debe ser "{expected_language}"
8487descripcion: Verifica que un texto esté escrito en el idioma esperado.
8488
8489step: busco el texto más similar a "{query}" en la lista "{text_list}" y lo guardo en "{var_name}"
8490descripcion: Busca el texto más similar a una consulta dentro de una lista de textos separados por comas.
8491
8492step: comparo el texto "{text}" con múltiples referencias "{references}" y muestro las similitudes
8493descripcion: Compara un texto con múltiples referencias y muestra todas las similitudes calculadas.
8494
8495## NLP Avanzado
8496
8497step: extraigo las entidades del texto "{text}" y las guardo en "{var_name}"
8498descripcion: Extrae entidades nombradas (personas, lugares, organizaciones, fechas) de un texto usando un modelo NER multilingüe.
8499
8500step: verifico que el texto "{text}" contiene una entidad de tipo "{entity_type}"
8501descripcion: Verifica que un texto contenga al menos una entidad del tipo especificado (PER, LOC, ORG, DATE).
8502
8503step: genero un resumen del texto "{text}" y lo guardo en "{var_name}"
8504descripcion: Genera un resumen automático de un texto largo usando el modelo BART.
8505
8506step: genero un resumen de la variable "{var_name}" con máximo {max_words} palabras y lo guardo en "{output_var}"
8507descripcion: Genera un resumen con longitud controlada del texto almacenado en una variable.
8508
8509step: traduzco el texto "{text}" de "{source_lang}" a "{target_lang}" y lo guardo en "{var_name}"
8510descripcion: Traduce un texto entre idiomas soportados (es, en, fr, de, pt) usando modelos Helsinki-NLP.
8511
8512step: genero una respuesta para "{prompt}" y la guardo en "{var_name}"
8513descripcion: Genera texto automáticamente basado en un prompt usando GPT-2.
8514
8515step: analizo la toxicidad del texto "{text}" y guardo el resultado en "{var_name}"
8516descripcion: Analiza si un texto contiene contenido tóxico u ofensivo usando toxic-bert y guarda true/false.
8517
8518step: verifico que el texto "{text}" no es tóxico
8519descripcion: Verifica que un texto NO contenga contenido tóxico.
8520
8521step: extraigo las palabras clave del texto "{text}" y las guardo en "{var_name}"
8522descripcion: Extrae las 5 palabras clave más importantes de un texto usando KeyBERT.
8523
8524step: agrupo los textos "{text_list}" en {num_clusters} clusters y guardo los resultados en "{var_name}"
8525descripcion: Agrupa textos similares en clusters usando K-Means sobre embeddings semánticos.
8526
8527step: respondo la pregunta "{question}" basándome en el contexto "{context_text}" y guardo la respuesta en "{var_name}"
8528descripcion: Responde una pregunta basándose en un contexto proporcionado usando Question Answering con RoBERTa.
8529
8530## Supabase Vector / RAG
8531
8532step: me conecto a Supabase con URL "{supabase_url}" y key "{supabase_key}"
8533descripcion: Establece conexión a Supabase usando URL y API key proporcionados directamente o desde variables.
8534
8535step: me conecto a Supabase usando variables de entorno
8536descripcion: Conecta a Supabase usando las variables de entorno SUPABASE_URL y SUPABASE_KEY definidas en .env.
8537
8538step: busco en la tabla "{table_name}" el contexto más similar a "{query}" y lo guardo en "{variable_name}"
8539descripcion: Busca contexto similar usando búsqueda vectorial con embeddings de Gemini en Supabase.
8540
8541step: busco en la tabla "{table_name}" los {count} contextos más similares a "{query}" y los guardo en "{variable_name}"
8542descripcion: Busca múltiples contextos similares usando búsqueda vectorial.
8543
8544step: cargo el contexto de Supabase tabla "{table_name}" para la query "{query}" en el contexto de Gemini "{context_name}"
8545descripcion: Busca contexto en Supabase y lo carga directamente en Gemini como contexto de negocio nombrado.
8546
8547step: consulto la tabla "{table_name}" en Supabase y guardo el resultado en "{variable_name}"
8548descripcion: Consulta todos los registros de una tabla de Supabase y guarda el resultado en una variable.
8549
8550step: consulto la tabla "{table_name}" filtrando por "{column}" igual a "{value}" y guardo en "{variable_name}"
8551descripcion: Consulta una tabla de Supabase aplicando un filtro de igualdad en una columna específica.`}]},{id:"patrones-avanzados",title:"Patrones Avanzados",group:"Técnicas Avanzadas",icon:"",topics:[{id:"scenario-outline",title:"Scenario Outline",content:`## Probar con Múltiples Datos
8552
8553\`Scenario Outline\` ejecuta el mismo escenario con múltiples combinaciones de datos. Cada fila de la tabla \`Examples\` genera una ejecución independiente.
8554
8555\`\`\`gherkin
8556Esquema del Escenario: Verificar que cada rol accede a su pantalla
8557  Dado voy a la url "\${ENV.BASE_URL}/login"
8558  Cuando relleno el campo "usuario" con "<email>" con identificador "$.LOGIN.input_user"
8559  Y relleno el campo "clave" con "<password>" con identificador "$.LOGIN.input_pass"
8560  Y hago click en el elemento "ingresar" con identificador "$.LOGIN.btn_login"
8561  Entonces la url actual debería contener "<url_esperada>"
8562
8563  Ejemplos:
8564    | email              | password   | url_esperada |
8565    | [email protected]     | admin123   | /dashboard   |
8566    | [email protected]      | user123    | /home        |
8567    | [email protected]    | viewer123  | /reports     |
8568\`\`\`
8569
8570## Background (Antecedentes)
8571
8572Pasos que se ejecutan antes de CADA escenario del feature.
8573
8574\`\`\`gherkin
8575Antecedentes:
8576  Dado voy a la url "\${ENV.BASE_URL}/login"
8577  Y relleno el campo "usuario" con "\${ENV.TEST_USER}" con identificador "$.LOGIN.input_user"
8578  Y relleno el campo "clave" con "\${ENV.TEST_PASS}" con identificador "$.LOGIN.input_pass"
8579  Y hago click en el elemento "ingresar" con identificador "$.LOGIN.btn_login"
8580
8581Escenario: Crear un producto nuevo
8582  Cuando hago click en el elemento "nuevo" con identificador "$.PRODUCTS.btn_new"
8583\`\`\``},{id:"pasos-personalizados",title:"Pasos Personalizados",content:`## Crear un Paso Personalizado
8584
8585\`\`\`python
8586# features/steps/custom_steps.py
8587from behave import step
8588
8589@step('hago login con usuario "{user}" y clave "{password}"')
8590def step_login(context, user, password):
8591    user = context.variable_manager.resolve_variables(user)
8592    password = context.variable_manager.resolve_variables(password)
8593    context.fill("$.LOGIN.input_usuario", user)
8594    context.fill("$.LOGIN.input_password", password)
8595    context.click("$.LOGIN.btn_login")
8596    context.page.wait_for_load_state("domcontentloaded")
8597\`\`\`
8598
8599## Agrupar Pasos del Framework
8600
8601\`\`\`python
8602@step('completo el flujo de login para el ambiente "{env}"')
8603def step_full_login_flow(context, env):
8604    base_urls = {"dev": "http://localhost:3000", "staging": "https://staging.miapp.com"}
8605    url = base_urls.get(env, "http://localhost:3000")
8606    user = context.variable_manager.resolve_variables("\${ENV.TEST_USER}")
8607    password = context.variable_manager.resolve_variables("\${ENV.TEST_PASS}")
8608    context.execute_steps(f'''
8609        When voy a la url "{url}/login"
8610        And relleno el campo "usuario" con "{user}" con identificador "$.LOGIN.input_usuario"
8611        And relleno el campo "clave" con "{password}" con identificador "$.LOGIN.input_clave"
8612        And hago click en el elemento "login" con identificador "$.LOGIN.btn_login"
8613    ''')
8614\`\`\`
8615
8616## Paso con Tabla Gherkin
8617
8618\`\`\`python
8619@step('completo el formulario con los siguientes datos')
8620def step_fill_form(context):
8621    for row in context.table:
8622        campo = row['campo']
8623        valor = context.variable_manager.resolve_variables(row['valor'])
8624        context.fill(f"$.REGISTRO.input_{campo}", valor)
8625\`\`\`
8626
8627\`\`\`gherkin
8628When completo el formulario con los siguientes datos
8629  | campo    | valor          |
8630  | nombre   | Ana García     |
8631  | email    | [email protected]   |
8632  | telefono | +56912345678   |
8633\`\`\``},{id:"soft-assertions",title:"Soft Assertions",content:`## Qué son las Soft Assertions
8634
8635Por defecto, cuando una verificación falla, Behave detiene el escenario. Con Soft Assertions, las verificaciones fallidas se capturan pero la ejecución continúa.
8636
8637## Activar Soft Assertions
8638
8639\`\`\`gherkin
8640@soft_assertions
8641Scenario: Validar todos los campos del formulario
8642  Given voy a la url "\${ENV.BASE_URL}/perfil"
8643  Then el campo "nombre" debería tener el valor "Ana" con identificador "$.PERFIL.nombre"
8644  And el campo "email" debería tener el valor "[email protected]" con identificador "$.PERFIL.email"
8645  And el campo "rol" debería tener el valor "Administrador" con identificador "$.PERFIL.rol"
8646\`\`\`
8647
8648## Comportamiento
8649
8650- Se activa con el tag \`@soft_assertions\` en el escenario.
8651- Solo captura \`AssertionError\` (pasos de verificación).
8652- Errores de otro tipo (TimeoutError, ElementNotFound) siguen deteniendo la ejecución.
8653- El reporte HTML muestra el estado real de cada step.
8654- Al final del escenario se imprime un resumen con todos los errores.`},{id:"reintentos",title:"Reintentos Automáticos",content:`## Configuración
8655
8656\`\`\`env
8657RETRY_FAILED_SCENARIOS=true
8658MAX_SCENARIO_RETRIES=2
8659\`\`\`
8660
8661## Cómo Funciona
8662
86631. Behave ejecuta todos los escenarios normalmente
86642. Cuando un escenario falla, se registra internamente
86653. Después de terminar todos los escenarios, se reintentan los fallidos
86664. Cada reintento crea una página limpia (navega a \`about:blank\`)
86675. Si pasa en el reintento, se reporta como passed
8668
8669## Recomendaciones
8670
8671- Usar para manejar flakiness, no para ocultar bugs reales
8672- Máximo 2-3 reintentos
8673- Si un escenario necesita reintentos consistentemente, investigar la causa raíz
8674- En CI/CD, habilitar reintentos reduce falsos negativos`},{id:"variables-dinamicas-localizadores",title:"Variables en Identificadores",content:`## Variables Dinámicas en Identificadores
8675
8676Puedes usar variables del framework dentro de los identificadores para construir selectores dinámicamente.
8677
8678\`\`\`gherkin
8679When guardo el texto del elemento "$.RESULT.codigo" en la variable "id_registro"
8680And hago click en el elemento "editar" con identificador "$.TABLE.btn_editar=\${id_registro}"
8681\`\`\`
8682
8683Donde \`TABLE.json\` tiene:
8684\`\`\`json
8685{
8686  "btn_editar": "[data-id='<valor>']"
8687}
8688\`\`\`
8689
8690## Texto Dinámico en XPath
8691
8692\`\`\`gherkin
8693When creo la variable "nombre_producto" con valor "Laptop Pro 15"
8694And debería ver el elemento "producto" con identificador "$.CATALOG.item_por_nombre=\${nombre_producto}"
8695\`\`\`
8696
8697\`\`\`json
8698{
8699  "item_por_nombre": "//div[@class='product-card'][contains(., '<valor>')]"
8700}
8701\`\`\`
8702
8703- La sintaxis \`$.ARCHIVO.elemento=\${variable}\` resuelve la variable antes de buscar el elemento.
8704- Si la variable no existe, el placeholder queda sin reemplazar.`},{id:"context-avanzado",title:"Context en Custom Steps",content:`## Recursos Disponibles en Context
8705
8706\`\`\`python
8707@step('ejecuto mi paso complejo')
8708def step_complex(context):
8709    # Navegador Playwright
8710    context.page                    # La página actual
8711    context.browser                 # El browser (multi-tab)
8712
8713    # Localizadores
8714    context.element_locator         # ElementLocator para JSON POMs
8715    context.find("$.MOD.elemento")  # Shortcut: retorna Locator
8716    context.click("$.MOD.btn")      # Shortcut: click
8717    context.fill("$.MOD.input", "texto")  # Shortcut: fill
8718    context.get_text("$.MOD.label") # Shortcut: text_content()
8719
8720    # Variables
8721    context.variable_manager.get_variable("mi_var")
8722    context.variable_manager.set_variable("nueva_var", "valor")
8723    context.variable_manager.resolve_variables("Hola \${nombre}")
8724
8725    # Logger
8726    context.logger.info("Mensaje de info")
8727
8728    # Framework config
8729    timeout = context.framework_config.config['timeout']
8730    browser_name = context.framework_config.config['browser']
8731\`\`\`
8732
8733## Paso que Usa Playwright Directamente
8734
8735\`\`\`python
8736@step('capturo el valor del campo oculto "{field_id}"')
8737def step_capture_hidden_field(context, field_id):
8738    value = context.page.evaluate(f"document.getElementById('{field_id}').value")
8739    context.variable_manager.set_variable(f"hidden_{field_id}", str(value))
8740    print(f"✓ Campo oculto '{field_id}' = '{value}'")
8741\`\`\`
8742
8743- \`context.page\` puede ser None si el navegador fue desactivado (\`@no_browser\`).
8744- Siempre chequea \`if hasattr(context, 'page') and context.page:\` antes de usarlo.`},{id:"pasos-alias-condicionales",title:"Alias y Pasos Condicionales",content:`## Múltiples Alias para un Paso
8745
8746Un mismo paso puede tener múltiples formas de invocarlo:
8747
8748\`\`\`python
8749@step('ingreso al sistema como "{role}"')
8750@step('que ingreso al sistema como "{role}"')
8751@step('me logueo como "{role}"')
8752def step_login_as_role(context, role):
8753    credentials = {
8754        "admin": ("[email protected]", "admin123"),
8755        "usuario": ("[email protected]", "user123"),
8756    }
8757    email, password = credentials.get(role, ("[email protected]", "guest"))
8758    context.fill("$.LOGIN.input_email", email)
8759    context.fill("$.LOGIN.input_pass", password)
8760    context.click("$.LOGIN.btn_ingresar")
8761\`\`\`
8762
8763## Paso Condicional
8764
8765\`\`\`python
8766@step('cierro el modal de bienvenida si aparece')
8767def step_close_welcome_modal(context):
8768    try:
8769        btn_cerrar = context.page.locator("$.MODAL.btn_cerrar")
8770        if btn_cerrar.is_visible(timeout=3000):
8771            btn_cerrar.click()
8772            print("✓ Modal de bienvenida cerrado")
8773        else:
8774            print("ℹ️ Modal no apareció, continuando")
8775    except Exception:
8776        print("ℹ️ Modal no encontrado, continuando")
8777\`\`\`
8778
8779## Retry con Lógica Personalizada
8780
8781\`\`\`python
8782@step('espero a que el proceso termine con timeout de "{seconds}" segundos')
8783def step_wait_for_process(context, seconds):
8784    import time
8785    max_time = int(seconds)
8786    start = time.time()
8787    while time.time() - start < max_time:
8788        status = context.get_text("$.PROCESS.status_label")
8789        if status in ("Completado", "Error"):
8790            break
8791        context.page.wait_for_timeout(1000)
8792    else:
8793        raise AssertionError(f"El proceso no terminó en {seconds} segundos")
8794    assert status == "Completado", f"Terminó con estado: {status}"
8795\`\`\`
8796
8797- Usa \`context.conditional_action("selector", action_fn, else_fn)\` para condicionales simples.
8798- Usa \`context.retry_action(lambda: ..., max_retries=3, delay=1000)\` para reintentos automáticos.`},{id:"docstrings-tablas",title:"DocStrings y Tablas",content:`## Paso con DocString (Texto Multilínea)
8799
8800\`\`\`python
8801@step('envío la configuración al endpoint "{endpoint}"')
8802def step_send_config(context, endpoint):
8803    import requests, json
8804    payload = json.loads(context.text)
8805    response = requests.post(endpoint, json=payload, timeout=30)
8806    context.variable_manager.set_variable("last_status", str(response.status_code))
8807\`\`\`
8808
8809\`\`\`gherkin
8810When envío la configuración al endpoint "https://api.miapp.com/config"
8811  """
8812  {
8813    "modo": "produccion",
8814    "timeout": 5000,
8815    "retries": 3
8816  }
8817  """
8818\`\`\`
8819
8820## Paso con Tabla Gherkin (DataTable)
8821
8822\`\`\`python
8823@step('verifico los datos del usuario en la tabla')
8824def step_verify_user_data(context):
8825    for row in context.table:
8826        columna = row['columna']
8827        esperado = row['valor esperado']
8828        actual = context.page.locator(f"td[data-col='{columna}']").text_content()
8829        assert esperado in actual, f"'{columna}': esperado '{esperado}', actual '{actual}'"
8830\`\`\`
8831
8832\`\`\`gherkin
8833Then verifico los datos del usuario en la tabla
8834  | columna | valor esperado |
8835  | nombre  | Ana García     |
8836  | email   | [email protected]   |
8837  | estado  | Activo         |
8838\`\`\`
8839
8840- \`context.text\` es el DocString (sin las triples comillas).
8841- \`context.table\` es iterable con acceso por nombre de columna.`},{id:"tablas-html",title:"Manejo de Tablas HTML",content:`## Esperar y Verificar Tabla
8842
8843\`\`\`gherkin
8844When hago click en el elemento "buscar" con identificador "$.SEARCH.btn"
8845And espero a que la tabla "resultados" tenga filas con identificador "$.RESULT.tabla"
8846And espero a que la tabla "resultados" tenga al menos 5 filas con identificador "$.RESULT.tabla"
8847Then debería haber exactamente 10 elementos que coinciden con "fila" con identificador "$.RESULT.tabla tbody tr"
8848\`\`\`
8849
8850## Paso Personalizado para Iterar Tabla
8851
8852\`\`\`python
8853@step('verifico que ninguna fila tiene estado "Pendiente"')
8854def step_verify_no_pending(context):
8855    rows = context.find_all("$.TABLA.filas_estado")
8856    for i, row in enumerate(rows):
8857        status = row.text_content().strip()
8858        assert status != "Pendiente", f"Fila {i} tiene estado 'Pendiente'"
8859    print(f"✓ Ninguna de las {len(rows)} filas tiene estado 'Pendiente'")
8860\`\`\`
8861
8862- Para tablas con paginación, navega página por página.
8863- Combina con \`guardo el texto del elemento "$.TABLA.fila[0]" en la variable "primera_fila"\` para extraer valores.`},{id:"ciclo-vida",title:"Ciclo de Vida",content:`## Orden de Ejecución
8864
8865\`\`\`
8866before_all          ← Una vez al inicio de toda la ejecución
8867  before_feature    ← Una vez por cada archivo .feature
8868    before_scenario ← Una vez por cada escenario
8869      [Antecedentes]
8870      before_step   ← Antes de cada step
8871      after_step    ← Después de cada step
8872    after_scenario  ← Después de cada escenario
8873  after_feature     ← Al terminar el feature
8874after_all           ← Una vez al final de toda la ejecución
8875\`\`\`
8876
8877## Qué Hace el Framework en Cada Hook
8878
8879**before_all:**
8880- Carga el .env
8881- Inicia Playwright
8882- Crea ElementLocator y VariableManager
8883- Inicializa integraciones (Jira, Cassini)
8884
8885**before_scenario:**
8886- Crea o reutiliza la página del navegador
8887- Limpia variables de escenario anterior
8888- Inicializa soft assertions si aplica
8889
8890**after_step:**
8891- Captura screenshot si está configurado
8892- Procesa soft assertions
8893
8894**after_scenario:**
8895- Captura screenshot si el escenario falló
8896- Procesa reintentos si aplica
8897- Reporta resultado a Cassini/Jira
8898
8899**after_all:**
8900- Genera reporte HTML
8901- Cierra Playwright
8902- Finaliza integraciones`},{id:"variables-alcance-global",title:"Variables Globales",content:`## Alcance de Variables
8903
8904Por defecto las variables son de **escenario** (se limpian al terminar). Para compartir entre escenarios del mismo feature, usa variables globales.
8905
8906\`\`\`python
8907@step('guardo globalmente la variable "{name}" con valor "{value}"')
8908def step_set_global_var(context, name, value):
8909    context.variable_manager.set_variable(name, value, scope='global')
8910\`\`\`
8911
8912\`\`\`gherkin
8913# Escenario 1
8914When guardo globalmente la variable "token_sesion" con valor "abc123"
8915
8916# Escenario 2 (mismo feature)
8917Then verifico que la variable "token_sesion" contiene "abc"
8918\`\`\`
8919
8920## Variables en Custom Steps
8921
8922\`\`\`python
8923@step('creo un ticket con asunto "{subject}" y obtengo su número')
8924def step_create_ticket(context, subject):
8925    import requests
8926    response = requests.post(
8927        f"{context.variable_manager.get_variable('API_URL')}/tickets",
8928        json={"subject": subject}, timeout=30
8929    )
8930    assert response.status_code == 201
8931    ticket_number = response.json()["number"]
8932    context.variable_manager.set_variable("numero_ticket", str(ticket_number))
8933    print(f"✓ Ticket creado: #{ticket_number}")
8934\`\`\`
8935
8936\`\`\`gherkin
8937When creo un ticket con asunto "Error en formulario" y obtengo su número
8938Then verifico que la variable "numero_ticket" contiene "TKT-"
8939\`\`\`
8940
8941## Consideraciones
8942
8943- \`get_variable(name)\` busca en: variables de escenario → globales → entorno (.env).
8944- Si la variable no existe, lanza \`KeyError\`. Maneja la excepción si es opcional.
8945- \`resolve_variables(text)\` resuelve interpolaciones \`\${var}\` en un string completo.
8946- Las variables globales persisten durante toda la ejecución.
8947- Evita depender de variables globales para pruebas paralelas (condiciones de carrera).`},{id:"paralelizacion",title:"Ejecución Paralela",content:`## Configuración de Paralelismo
8948
8949El framework soporta ejecución paralela por features, usando múltiples instancias de Playwright simultáneamente.
8950
8951### Configuración en .env
8952
8953\`\`\`env
8954PARALLEL_WORKERS=4    # Número de workers paralelos (1 = serial)
8955\`\`\`
8956
8957### Ejecución desde CLI
8958
8959\`\`\`bash
8960# Ejecución serial (por defecto)
8961haka-run
8962
8963# Ejecución paralela con 4 workers
8964haka-run --parallel --workers 4
8965
8966# Ejecución paralela por tag
8967haka-run --parallel --workers 4 --tags @regression
8968\`\`\`
8969
8970### Ejecución desde Python
8971
8972\`\`\`python
8973from hakalab_framework.runner import run_tests
8974import sys
8975
8976# Serial
8977sys.exit(run_tests(tags='@smoke'))
8978
8979# Paralelo: usa PARALLEL_WORKERS del .env automáticamente
8980sys.exit(run_tests(tags='@regression'))
8981\`\`\`
8982
8983## Cómo Funciona
8984
89851. El framework detecta \`PARALLEL_WORKERS\` del \`.env\`
89862. Si es > 1 y hay más de un feature, ejecuta en paralelo
89873. Cada feature se ejecuta en un subprocess independiente
89884. Cada worker tiene su propia instancia de Playwright
89895. Al finalizar, se unifican los reportes HTML
8990
8991## Consideraciones
8992
8993- La paralelización es a nivel de **feature** (no de escenario)
8994- Cada worker tiene su propia sesión de navegador
8995- Variables globales no se comparten entre workers
8996- Los reportes se consolidan al final automáticamente
8997- Compatible con integraciones (Cassini crea una sola ejecución compartida)`},{id:"cicd",title:"CI/CD",content:`## Configuración para CI/CD
8998
8999### Variables de Entorno para Pipelines
9000
9001\`\`\`env
9002HEADLESS=true              # Sin ventana visible
9003BROWSER=chromium           # Más liviano que chrome
9004AUTO_SCREENSHOT_ON_FAILURE=true
9005RETRY_FAILED_SCENARIOS=true
9006MAX_SCENARIO_RETRIES=2
9007\`\`\`
9008
9009### CLI Optimizado para Docker
9010
9011\`\`\`bash
9012haka-run --headless --docker --tags @smoke
9013\`\`\`
9014
9015El flag \`--docker\` fuerza headless, activa screenshots en fallos y ajusta el logging.
9016
9017## Sharding en CI/CD (GitHub Actions)
9018
9019Para distribuir tests entre múltiples jobs paralelos, usa sharding por variables de entorno:
9020
9021\`\`\`env
9022SHARD_INDEX=1       # Índice del shard actual (1-based)
9023TOTAL_SHARDS=4      # Total de shards
9024\`\`\`
9025
9026### GitHub Actions con Sharding
9027
9028\`\`\`yaml
9029jobs:
9030  test:
9031    runs-on: ubuntu-latest
9032    strategy:
9033      matrix:
9034        shard: [1, 2, 3, 4]
9035    env:
9036      SHARD_INDEX: \${{ matrix.shard }}
9037      TOTAL_SHARDS: 4
9038    steps:
9039      - uses: actions/checkout@v4
9040      - uses: actions/setup-python@v5
9041        with:
9042          python-version: '3.11'
9043      - name: Instalar dependencias
9044        run: |
9045          pip install haka-playwright-engine
9046          playwright install chromium
9047      - name: Ejecutar tests (shard \${{ matrix.shard }})
9048        run: haka-run --headless
9049      - name: Upload reporte
9050        uses: actions/upload-artifact@v4
9051        with:
9052          name: report-shard-\${{ matrix.shard }}
9053          path: html-reports/
9054\`\`\`
9055
9056### Consolidar Reportes
9057
9058\`\`\`yaml
9059  consolidate-reports:
9060    runs-on: ubuntu-latest
9061    needs: test
9062    if: always()
9063    steps:
9064      - uses: actions/checkout@v4
9065      - uses: actions/download-artifact@v4
9066        with:
9067          path: artifacts/
9068      - name: Generar reporte unificado
9069        run: |
9070          pip install haka-playwright-engine
9071          python -m hakalab_framework.merge_reports \\
9072            --artifacts-dir ./artifacts \\
9073            --output-dir ./consolidated-reports
9074      - name: Upload reporte consolidado
9075        uses: actions/upload-artifact@v4
9076        with:
9077          name: consolidated-reports
9078          path: consolidated-reports/
9079\`\`\`
9080
9081## Azure DevOps
9082
9083\`\`\`yaml
9084stages:
9085- stage: Test
9086  jobs:
9087  - job: RunTests
9088    pool:
9089      vmImage: 'ubuntu-latest'
9090    strategy:
9091      parallel: 4
9092    steps:
9093    - task: UsePythonVersion@0
9094      inputs:
9095        versionSpec: '3.11'
9096    - script: |
9097        pip install haka-playwright-engine
9098        playwright install chromium
9099        export SHARD_INDEX=$(System.JobPositionInPhase)
9100        export TOTAL_SHARDS=4
9101        haka-run --headless
9102      displayName: 'Run tests'
9103\`\`\`
9104
9105## behave.ini para CI/CD
9106
9107\`\`\`ini
9108[behave]
9109paths = features
9110format = progress
9111stdout_capture = true
9112stderr_capture = true
9113log_capture = true
9114junit = true
9115junit_directory = reports/junit
9116\`\`\`
9117
9118## Comandos CLI Útiles
9119
9120\`\`\`bash
9121# Ver información de sharding
9122haka-run --shard-info
9123
9124# Validar configuración del proyecto
9125haka-validate
9126
9127# Generar reporte HTML simple
9128haka-report --simple
9129
9130# Limpiar reportes anteriores
9131haka-report --clean
9132\`\`\``}]},{id:"pasos-personalizados",title:"Pasos Personalizados",group:"Técnicas Avanzadas",icon:"",topics:[{id:"custom-steps-intro",title:"Introducción",content:`## Creación de Pasos Personalizados
9133
9134El framework incluye +1,800 pasos listos para usar, pero cada proyecto tiene necesidades específicas. Los pasos personalizados permiten encapsular lógica de negocio propia sin modificar el framework.
9135
9136## Dónde se crean
9137
9138Los pasos personalizados van en \`features/steps/custom_steps.py\` (o cualquier archivo \`.py\` dentro de \`features/steps/\`). Behave los descubre automáticamente.
9139
9140\`\`\`
9141mi-proyecto/
9142+-- features/
9143    +-- steps/
9144        |-- __init__.py           # Importa los pasos del framework
9145        |-- custom_steps.py       # Tus pasos personalizados
9146        +-- steps_checkout.py     # Puedes crear más archivos
9147\`\`\`
9148
9149## Estructura básica de un paso
9150
9151\`\`\`python
9152from behave import given, when, then, step
9153
9154@when('hago login con el usuario "{usuario}" y clave "{clave}"')
9155def step_login(context, usuario, clave):
9156    """Paso compuesto que encapsula el flujo de login."""
9157    context.page.goto(f"{context.base_url}/login")
9158    context.page.fill("#email", usuario)
9159    context.page.fill("#password", clave)
9160    context.page.click("button[type='submit']")
9161    context.page.wait_for_url("**/dashboard**")
9162\`\`\`
9163
9164Uso en el feature:
9165
9166\`\`\`gherkin
9167When hago login con el usuario "[email protected]" y clave "Secret123"
9168\`\`\`
9169
9170## Decoradores disponibles
9171
9172| Decorador | Keyword en Gherkin |
9173|-----------|-------------------|
9174| \`@given\` | Given / Dado / Dado que |
9175| \`@when\` | When / Cuando |
9176| \`@then\` | Then / Entonces |
9177| \`@step\` | Cualquier keyword (comodín) |
9178
9179## Acceso al contexto
9180
9181El objeto \`context\` da acceso a todo lo que el framework provee:
9182
9183| Atributo | Qué es |
9184|----------|--------|
9185| \`context.page\` | Página de Playwright (navegador) |
9186| \`context.browser\` | Instancia del navegador |
9187| \`context.element_locator\` | Resolvedor de POMs (\`$.ARCHIVO.elemento\`) |
9188| \`context.api_session\` | Sesión HTTP para pruebas API |
9189| \`context.appium_driver\` | Driver de Appium (mobile) |
9190| \`context.desktop_manager\` | Manager de PyAutoGUI (desktop) |
9191| \`context.variables\` | Diccionario de variables del escenario |
9192
9193> El atributo disponible depende del tipo de prueba. \`context.page\` no existe en pruebas \`@no_browser\`.`},{id:"custom-steps-web",title:"Pasos Web",content:`## Pasos Personalizados para Web
9194
9195Los pasos web usan \`context.page\` (la página de Playwright) y \`context.element_locator\` (el resolvedor de POMs).
9196
9197## Ejemplo: Paso compuesto con POM
9198
9199\`\`\`python
9200from behave import when, then
9201
9202@when('completo el formulario de contacto con nombre "{nombre}" y email "{email}"')
9203def step_completar_contacto(context, nombre, email):
9204    """Encapsula un flujo de varios pasos en uno solo."""
9205    locator = context.element_locator
9206    page = context.page
9207
9208    # Resolver selectores desde el POM
9209    campo_nombre = locator.get_element(page, "$.CONTACTO.input_nombre")
9210    campo_email = locator.get_element(page, "$.CONTACTO.input_email")
9211    btn_enviar = locator.get_element(page, "$.CONTACTO.btn_enviar")
9212
9213    campo_nombre.fill(nombre)
9214    campo_email.fill(email)
9215    btn_enviar.click()
9216\`\`\`
9217
9218## Ejemplo: Validación personalizada
9219
9220\`\`\`python
9221from behave import then
9222import re
9223
9224@then('el RUT "{rut}" debería ser válido')
9225def step_validar_rut(context, rut):
9226    """Valida formato y dígito verificador de un RUT chileno."""
9227    rut_limpio = rut.replace(".", "").replace("-", "")
9228    cuerpo, dv = rut_limpio[:-1], rut_limpio[-1].upper()
9229
9230    suma = 0
9231    multiplo = 2
9232    for digito in reversed(cuerpo):
9233        suma += int(digito) * multiplo
9234        multiplo = multiplo + 1 if multiplo < 7 else 2
9235
9236    resto = suma % 11
9237    dv_esperado = {0: "0", 1: "K"}.get(resto, str(11 - resto))
9238
9239    assert dv == dv_esperado, (
9240        f"RUT {rut} inválido: dígito verificador esperado {dv_esperado}, "
9241        f"obtenido {dv}"
9242    )
9243\`\`\`
9244
9245## Ejemplo: Esperar condición de negocio
9246
9247\`\`\`python
9248from behave import when
9249from playwright.sync_api import expect
9250
9251@when('espero a que el pedido "{pedido_id}" aparezca en la tabla')
9252def step_esperar_pedido(context, pedido_id):
9253    """Espera a que un pedido específico aparezca en la tabla de resultados."""
9254    fila = context.page.locator(f"tr:has-text('{pedido_id}')")
9255    expect(fila).to_be_visible(timeout=15000)
9256\`\`\`
9257
9258## Ejemplo: Paso con screenshot condicional
9259
9260\`\`\`python
9261from behave import then
9262import os
9263
9264@then('capturo evidencia si el monto supera "{monto}" en "$.{pom}.{elemento}"')
9265def step_captura_condicional(context, monto, pom, elemento):
9266    """Toma screenshot solo si el monto en pantalla supera el umbral."""
9267    el = context.element_locator.get_element(
9268        context.page, f"$.{pom}.{elemento}"
9269    )
9270    texto = el.inner_text()
9271    valor = float(texto.replace("$", "").replace(".", "").replace(",", "."))
9272
9273    if valor > float(monto):
9274        path = f"reports/screenshots/monto_alto_{valor}.png"
9275        context.page.screenshot(path=path)
9276        print(f"  [evidencia] Monto {valor} > {monto}, screenshot en {path}")
9277\`\`\`
9278
9279## Usar variables del framework
9280
9281\`\`\`python
9282from behave import when
9283
9284@when('genero un correo único para el usuario "{nombre}"')
9285def step_generar_correo(context, nombre):
9286    """Genera un correo único y lo guarda como variable del escenario."""
9287    import time
9288    correo = f"{nombre.lower()}_{int(time.time())}@test.hakalab.com"
9289    context.variables[nombre + "_email"] = correo
9290    print(f"  Variable creada: {nombre}_email = {correo}")
9291\`\`\`
9292
9293Uso en el feature:
9294
9295\`\`\`gherkin
9296When genero un correo único para el usuario "admin"
9297And relleno el campo "email" con "\${admin_email}" con identificador "$.REGISTRO.input_email"
9298\`\`\``},{id:"custom-steps-api",title:"Pasos API",content:`## Pasos Personalizados para API
9299
9300Los pasos API usan \`context.api_session\` (sesión de \`requests\`) y se marcan con \`@no_browser\` en el feature para no abrir navegador.
9301
9302## Ejemplo: Autenticación con token
9303
9304\`\`\`python
9305from behave import given
9306import requests
9307import os
9308
9309@given('me autentico en la API con las credenciales del ambiente')
9310def step_auth_api(context):
9311    """Obtiene un token OAuth2 y lo configura en la sesión."""
9312    token_url = os.getenv("API_TOKEN_URL")
9313    client_id = os.getenv("API_CLIENT_ID")
9314    client_secret = os.getenv("API_CLIENT_SECRET")
9315
9316    response = requests.post(token_url, data={
9317        "grant_type": "client_credentials",
9318        "client_id": client_id,
9319        "client_secret": client_secret,
9320    })
9321    assert response.status_code == 200, f"Auth falló: {response.text}"
9322
9323    token = response.json()["access_token"]
9324    context.api_session.headers.update({
9325        "Authorization": f"Bearer {token}"
9326    })
9327    print(f"  Token obtenido: {token[:20]}...")
9328\`\`\`
9329
9330## Ejemplo: Validar esquema de respuesta
9331
9332\`\`\`python
9333from behave import then
9334import jsonschema
9335import json
9336
9337@then('la respuesta cumple el esquema definido en "{archivo_schema}"')
9338def step_validar_schema(context, archivo_schema):
9339    """Valida la respuesta API contra un JSON Schema."""
9340    with open(archivo_schema, 'r') as f:
9341        schema = json.load(f)
9342
9343    response_json = context.last_api_response.json()
9344
9345    try:
9346        jsonschema.validate(response_json, schema)
9347    except jsonschema.ValidationError as e:
9348        assert False, f"La respuesta no cumple el esquema: {e.message}"
9349\`\`\`
9350
9351## Ejemplo: CRUD completo reutilizable
9352
9353\`\`\`python
9354from behave import when, then
9355import json
9356
9357@when('creo un recurso en "{endpoint}" con los datos')
9358def step_crear_recurso(context, endpoint):
9359    """Crea un recurso usando el body del DocString del step."""
9360    body = json.loads(context.text)
9361    base_url = context.api_session.headers.get("X-Base-URL", "")
9362
9363    response = context.api_session.post(f"{base_url}{endpoint}", json=body)
9364    context.last_api_response = response
9365
9366    # Guardar el ID para pasos posteriores
9367    if response.status_code in (200, 201):
9368        data = response.json()
9369        context.variables["ultimo_recurso_id"] = str(data.get("id", ""))
9370
9371
9372@then('elimino el recurso creado en "{endpoint}"')
9373def step_eliminar_recurso(context, endpoint):
9374    """Elimina el recurso creado en el paso anterior."""
9375    recurso_id = context.variables.get("ultimo_recurso_id")
9376    assert recurso_id, "No hay recurso creado para eliminar"
9377
9378    base_url = context.api_session.headers.get("X-Base-URL", "")
9379    response = context.api_session.delete(f"{base_url}{endpoint}/{recurso_id}")
9380    context.last_api_response = response
9381\`\`\`
9382
9383Uso en el feature:
9384
9385\`\`\`gherkin
9386@no_browser
9387Feature: CRUD de usuarios
9388
9389  Scenario: Crear y eliminar un usuario
9390    Given me autentico en la API con las credenciales del ambiente
9391    When creo un recurso en "/api/users" con los datos
9392      """
9393      {"name": "QA Test", "email": "[email protected]", "role": "tester"}
9394      """
9395    Then la respuesta debería tener código "201"
9396    And elimino el recurso creado en "/api/users"
9397    And la respuesta debería tener código "204"
9398\`\`\``},{id:"custom-steps-mobile",title:"Pasos Mobile",content:`## Pasos Personalizados para Mobile
9399
9400Los pasos mobile usan \`context.appium_driver\` (el driver de Appium) y se combinan con los tags \`@no_browser\` y \`@mobile\` o \`@solo_mobile\`.
9401
9402## Ejemplo: Scroll hasta encontrar un elemento
9403
9404\`\`\`python
9405from behave import when
9406
9407@when('hago scroll hasta encontrar el texto "{texto}" en la app')
9408def step_scroll_hasta_texto(context, texto):
9409    """Hace scroll vertical hasta que el texto sea visible."""
9410    driver = context.appium_driver
9411    max_intentos = 10
9412
9413    for i in range(max_intentos):
9414        try:
9415            elemento = driver.find_element("xpath",
9416                f"//*[contains(@text, '{texto}')]")
9417            if elemento.is_displayed():
9418                return
9419        except Exception:
9420            pass
9421
9422        # Scroll hacia abajo
9423        size = driver.get_window_size()
9424        start_y = int(size['height'] * 0.8)
9425        end_y = int(size['height'] * 0.2)
9426        start_x = int(size['width'] * 0.5)
9427        driver.swipe(start_x, start_y, start_x, end_y, 800)
9428
9429    assert False, f"No se encontró el texto '{texto}' después de {max_intentos} scrolls"
9430\`\`\`
9431
9432## Ejemplo: Esperar que cargue la app
9433
9434\`\`\`python
9435from behave import given
9436from appium.webdriver.common.appiumby import AppiumBy
9437from selenium.webdriver.support.ui import WebDriverWait
9438from selenium.webdriver.support import expected_conditions as EC
9439
9440@given('espero a que la app esté lista con el elemento "{locator}"')
9441def step_esperar_app(context, locator):
9442    """Espera hasta que un elemento clave de la app sea visible."""
9443    driver = context.appium_driver
9444    wait = WebDriverWait(driver, 30)
9445
9446    # Resolver el locator desde el POM mobile
9447    pom_data = context.element_locator.get_locator(locator)
9448    by_type = pom_data.get("by", "xpath")
9449    value = pom_data.get("value")
9450
9451    by_map = {
9452        "xpath": AppiumBy.XPATH,
9453        "id": AppiumBy.ID,
9454        "accessibility_id": AppiumBy.ACCESSIBILITY_ID,
9455        "class_name": AppiumBy.CLASS_NAME,
9456    }
9457
9458    wait.until(EC.visibility_of_element_located(
9459        (by_map.get(by_type, AppiumBy.XPATH), value)
9460    ))
9461\`\`\`
9462
9463## Ejemplo: Capturar screenshot mobile con nombre descriptivo
9464
9465\`\`\`python
9466from behave import then
9467import os
9468from datetime import datetime
9469
9470@then('capturo la pantalla mobile como "{nombre}"')
9471def step_screenshot_mobile(context, nombre):
9472    """Toma screenshot del dispositivo con nombre descriptivo."""
9473    driver = context.appium_driver
9474    timestamp = datetime.now().strftime("%H%M%S")
9475    filename = f"reports/screenshots/mobile_{nombre}_{timestamp}.png"
9476
9477    os.makedirs(os.path.dirname(filename), exist_ok=True)
9478    driver.save_screenshot(filename)
9479    print(f"  Screenshot mobile guardado: {filename}")
9480\`\`\`
9481
9482## Ejemplo: Verificar notificación del sistema
9483
9484\`\`\`python
9485from behave import then
9486
9487@then('debería aparecer una notificación con texto "{texto}"')
9488def step_verificar_notificacion(context, texto):
9489    """Abre la barra de notificaciones y busca el texto."""
9490    driver = context.appium_driver
9491
9492    # Abrir panel de notificaciones
9493    driver.open_notifications()
9494    import time
9495    time.sleep(2)
9496
9497    # Buscar el texto en las notificaciones
9498    try:
9499        notif = driver.find_element("xpath",
9500            f"//*[contains(@text, '{texto}')]")
9501        assert notif.is_displayed(), f"Notificación '{texto}' no visible"
9502    finally:
9503        # Cerrar el panel
9504        driver.press_keycode(4)  # Back
9505\`\`\`
9506
9507## Estructura del POM mobile
9508
9509Los selectores mobile van en \`json_poms/\` con formato especial:
9510
9511\`\`\`json
9512{
9513  "btn_login": {
9514    "by": "accessibility_id",
9515    "value": "login-button"
9516  },
9517  "campo_email": {
9518    "by": "xpath",
9519    "value": "//android.widget.EditText[@content-desc='Email input']"
9520  }
9521}
9522\`\`\`
9523
9524Tipos de localizador soportados:
9525
9526| Tipo (\`by\`) | Descripción | Ejemplo |
9527|-------------|-------------|---------|
9528| \`xpath\` | XPath del árbol de vistas | \`//android.widget.Button[@text='OK']\` |
9529| \`id\` | Resource ID de Android | \`com.app:id/btn_login\` |
9530| \`accessibility_id\` | content-description | \`login-button\` |
9531| \`class_name\` | Clase del widget | \`android.widget.EditText\` |
9532| \`uiautomator\` | Selector UIAutomator2 | \`new UiSelector().text("Login")\` |`},{id:"custom-steps-tips",title:"Buenas Prácticas",content:`## Buenas Prácticas para Pasos Personalizados
9533
9534## Nombrar los pasos de forma legible
9535
9536Los pasos son la interfaz entre el QA funcional y la automatización. Un buen n
9536ombre se lee como lenguaje natural:
9537
9538\`\`\`python
9539# Bien: se entiende sin ver el código
9540@when('agrego el producto "{sku}" al carrito con cantidad "{cantidad}"')
9541
9542# Mal: demasiado técnico, no aporta al feature
9543@when('ejecuto POST /cart/add con sku={sku}&qty={qty}')
9544\`\`\`
9545
9546## Un paso, una responsabilidad
9547
9548\`\`\`python
9549# Bien: hace una cosa
9550@when('selecciono la sucursal "{sucursal}"')
9551def step_seleccionar_sucursal(context, sucursal):
9552    context.page.select_option("#branch", label=sucursal)
9553
9554# Mal: hace demasiado, difícil de debuggear
9555@when('configuro todo el formulario de envío')
9556def step_todo_envio(context):
9557    context.page.fill("#nombre", "Juan")
9558    context.page.fill("#dir", "Av. Principal 123")
9559    context.page.select_option("#branch", label="Central")
9560    context.page.click("#btn_siguiente")
9561\`\`\`
9562
9563## Usar asserts descriptivos
9564
9565\`\`\`python
9566# Bien: el mensaje dice qué falló y qué se esperaba
9567assert precio_total == precio_esperado, (
9568    f"El precio total es {precio_total} pero se esperaba "
9569    f"{precio_esperado} ({cantidad} x {precio_unitario})"
9570)
9571
9572# Mal: no dice nada útil
9573assert precio_total == precio_esperado
9574\`\`\`
9575
9576## Reutilizar a través de funciones helper
9577
9578Si la lógica se repite entre pasos, extraela a una función:
9579
9580\`\`\`python
9581# helpers.py
9582def obtener_precio(texto):
9583    """Extrae un número de un texto con formato monetario."""
9584    import re
9585    numeros = re.findall(r'[\\d.,]+', texto.replace(".", "").replace(",", "."))
9586    return float(numeros[0]) if numeros else 0.0
9587
9588
9589# custom_steps.py
9590from helpers import obtener_precio
9591
9592@then('el precio mostrado debería ser "{esperado}"')
9593def step_verificar_precio(context, esperado):
9594    texto = context.page.locator(".precio-total").inner_text()
9595    actual = obtener_precio(texto)
9596    assert actual == float(esperado), f"Precio: {actual} != {esperado}"
9597\`\`\`
9598
9599## Organizar por dominio
9600
9601\`\`\`
9602features/steps/
9603|-- __init__.py              # from hakalab_framework.steps import *
9604|-- custom_steps.py          # Pasos generales del proyecto
9605|-- steps_login.py           # Pasos de autenticación
9606|-- steps_checkout.py        # Pasos del carrito y pago
9607|-- steps_admin.py           # Pasos del panel de administración
9608+-- helpers.py               # Funciones utilitarias (no son steps)
9609\`\`\`
9610
9611## No duplicar pasos del framework
9612
9613Antes de crear un paso, verificá si ya existe:
9614
9615\`\`\`bash
9616# Buscar pasos disponibles
9617haka-steps --search "click"
9618haka-steps --search "API"
9619haka-steps --search "mobile"
9620
9621# O ver el catálogo completo
9622haka-ui
9623# Ir a Features > Scenario Builder > buscar
9624\`\`\``}]},{id:"xray-cloud",title:"Xray Cloud",group:"Integraciones y Reportes",icon:"",topics:[{id:"xray-descripcion-general",title:"Descripción General",content:`## Integración Xray Cloud
9625
9626La integración con Xray Cloud permite reportar automáticamente los resultados de ejecución de pruebas Behave directamente a Xray Cloud (Jira). Cuando ejecutas tus tests con Haka Framework, los resultados se envían a Xray para crear o actualizar Test Executions, vinculando cada escenario con su Test Issue correspondiente.
9627
9628## Requisitos Previos
9629
96301. **Proyecto Xray Cloud** configurado en Jira Cloud
96312. **API Keys** de Xray Cloud (Client ID y Client Secret) o un Bearer Token válido
96323. **Tests creados en Xray** con keys asignadas (ej: \`PROJ-123\`)
96334. **Haka Framework** instalado y configurado`},{id:"xray-inicio-rapido",title:"Inicio Rápido",content:`## Inicio Rápido
9634
9635### 1. Crear el archivo de configuración
9636
9637Crea \`xray_config.json\` en la raíz de tu proyecto:
9638
9639\`\`\`json
9640{
9641  "enabled": true,
9642  "auth": {
9643    "method": "client_credentials"
9644  },
9645  "matching": {
9646    "strategy": "tag",
9647    "tag_pattern": "[A-Z]+-\\\\d+"
9648  }
9649}
9650\`\`\`
9651
9652### 2. Configurar variables de entorno
9653
9654\`\`\`bash
9655# Autenticación
9656set XRAY_CLIENT_ID=tu_client_id
9657set XRAY_CLIENT_SECRET=tu_client_secret
9658
9659# Habilitar integración
9660set XRAY_ENABLED=true
9661\`\`\`
9662
9663### 3. Etiquetar escenarios con test keys
9664
9665\`\`\`gherkin
9666@PROJ-101
9667Scenario: Login exitoso con credenciales válidas
9668  Given el usuario está en la página de login
9669  When ingresa credenciales válidas
9670  Then accede al dashboard
9671\`\`\`
9672
9673### 4. Ejecutar tests
9674
9675\`\`\`bash
9676behave
9677\`\`\`
9678
9679Los resultados se envían automáticamente a Xray Cloud al finalizar la ejecución.`},{id:"xray-configuracion",title:"Configuración (xray_config.json)",content:`## Archivo xray_config.json
9680
9681El archivo \`xray_config.json\` es el mecanismo principal de configuración. Se busca en:
9682
96831. **Raíz del proyecto** (directorio de trabajo)
96842. **Ruta personalizada** definida en la variable \`XRAY_CONFIG_PATH\`
9685
9686### Estructura completa
9687
9688\`\`\`json
9689{
9690  "enabled": true,
9691  "auth": {
9692    "method": "client_credentials",
9693    "retry_attempts": 3
9694  },
9695  "execution": {
9696    "create": true,
9697    "existing_execution_key": null,
9698    "summary_template": "Automated Execution - {feature_name} - {date} {time}",
9699    "description_template": "Automated execution from Haka Framework for feature: {feature_name}",
9700    "test_plan_key": null,
9701    "environments": [],
9702    "fix_version": null,
9703    "labels": [],
9704    "custom_fields": {},
9705    "group_by": "feature",
9706    "group_tag": null
9707  },
9708  "matching": {
9709    "strategy": "tag",
9710    "tag_pattern": "[A-Z]+-\\\\d+",
9711    "tag_prefix": null,
9712    "multiple_keys": false,
9713    "unmatched_behavior": "warn",
9714    "validate_issue_type": true,
9715    "custom_field_id": null
9716  },
9717  "results": {
9718    "include_steps": false,
9719    "include_step_data_tables": false,
9720    "include_duration": true,
9721    "comment_template": null,
9722    "defects": {
9723      "enabled": false,
9724      "tag_pattern": "BUG-[A-Z]+-\\\\d+"
9725    }
9726  },
9727  "statuses": {
9728    "mapping": {
9729      "passed": "PASS",
9730      "failed": "FAIL",
9731      "skipped": "ABORTED",
9732      "undefined": "TODO",
9733      "pending": "TODO"
9734    }
9735  },
9736  "evidence": {
9737    "screenshots": {
9738      "enabled": false,
9739      "on_failure_only": true
9740    },
9741    "html_report": {
9742      "enabled": false
9743    },
9744    "video": {
9745      "enabled": false
9746    },
9747    "custom_attachments": [],
9748    "max_file_size_mb": 10
9749  },
9750  "import": {
9751    "format": "xray_json",
9752    "batch_size": null,
9753    "retry_attempts": 3
9754  },
9755  "lifecycle": {
9756    "auto_create_tests": false,
9757    "update_test_definition": false,
9758    "link_to_story": true,
9759    "link_to_execution": true,
9760    "link_type": "Tests"
9761  },
9762  "error_handling": {
9763    "fail_on_upload_error": false,
9764    "save_failed_payload": true,
9765    "payload_output_dir": "xray-payloads",
9766    "timeout_seconds": 30
9767  },
9768  "debug": {
9769    "dry_run": false,
9770    "log_level": "INFO",
9771    "log_payloads": false,
9772    "output_dir": "xray-debug"
9773  }
9774}
9775\`\`\`
9776
9777> **Nota**: Todos los campos son opcionales excepto \`enabled\`. Los valores por defecto se aplican automáticamente.
9778
9779## Variables de Entorno
9780
9781Las variables de entorno se utilizan para credenciales y overrides:
9782
9783| Variable | Descripción | Requerida |
9784|----------|-------------|-----------|
9785| \`XRAY_ENABLED\` | Habilita/deshabilita la integración (\`true\`/\`false\`) | Sí |
9786| \`XRAY_CLIENT_ID\` | Client ID de Xray Cloud API | Sí (si \`method=client_credentials\`) |
9787| \`XRAY_CLIENT_SECRET\` | Client Secret de Xray Cloud API | Sí (si \`method=client_credentials\`) |
9788| \`XRAY_AUTHORIZATION_TOKEN\` | Bearer token directo | Sí (si \`method=bearer_token\`) |
9789| \`XRAY_CONFIG_PATH\` | Ruta al archivo de configuración | No |
9790| \`XRAY_TEST_PLAN\` | Override del Test Plan key | No |
9791
9792> **Seguridad**: Las credenciales SOLO se pueden configurar via variables de entorno. Si se detectan campos con valores similares a credenciales en el JSON, se emite una advertencia.
9793
9794## Modo Legacy (Deprecado)
9795
9796Si tienes \`XRAY_ENABLED=true\` pero **no** existe un archivo \`xray_config.json\`, el sistema opera en modo legacy utilizando únicamente variables de entorno. Este modo es limitado y está deprecado.
9797
9798Variables legacy soportadas:
9799- \`XRAY_ENABLED\`
9800- \`XRAY_AUTHORIZATION_TOKEN\`
9801- \`XRAY_BASE_URL\`
9802- \`XRAY_TEST_PLAN\`
9803
9804Se recomienda migrar a \`xray_config.json\`.`},{id:"xray-autenticacion",title:"Autenticación",content:`## Client Credentials (Recomendado)
9805
9806Utiliza las API Keys de Xray Cloud para obtener un token automáticamente:
9807
9808\`\`\`json
9809{
9810  "auth": {
9811    "method": "client_credentials",
9812    "retry_attempts": 3
9813  }
9814}
9815\`\`\`
9816
9817Variables requeridas:
9818\`\`\`bash
9819set XRAY_CLIENT_ID=abc123def456
9820set XRAY_CLIENT_SECRET=xyz789secret
9821\`\`\`
9822
9823El sistema:
98241. Envía POST a \`/api/v2/authenticate\` con las credenciales
98252. Obtiene un bearer token
98263. Refresca el token automáticamente si está próximo a expirar
98274. Reintenta con backoff exponencial si falla
9828
9829## Bearer Token
9830
9831Si ya tienes un token válido (ej: generado externamente):
9832
9833\`\`\`json
9834{
9835  "auth": {
9836    "method": "bearer_token"
9837  }
9838}
9839\`\`\`
9840
9841Variable requerida:
9842\`\`\`bash
9843set XRAY_AUTHORIZATION_TOKEN=eyJhbGciOiJIUzI1NiIs...
9844\`\`\`
9845
9846## Comportamiento ante fallos de autenticación
9847
9848- Si la autenticación falla después de todos los reintentos, el plugin se deshabilita automáticamente para esa ejecución
9849- Las pruebas **nunca** se interrumpen por fallos de autenticación`},{id:"xray-matching",title:"Matching de Escenarios",content:`## Matching de Escenarios
9850
9851El matching vincula cada escenario Behave con uno o más Test Issues de Xray.
9852
9853### Estrategia: Tag (por defecto)
9854
9855Extrae test keys de los tags del escenario usando una expresión regular:
9856
9857\`\`\`json
9858{
9859  "matching": {
9860    "strategy": "tag",
9861    "tag_pattern": "[A-Z]+-\\\\d+"
9862  }
9863}
9864\`\`\`
9865
9866\`\`\`gherkin
9867@PROJ-101
9868Scenario: Login exitoso
9869  ...
9870
9871@PROJ-102 @PROJ-103
9872Scenario: Múltiples tests asociados
9873  ...
9874\`\`\`
9875
9876#### Filtrado por prefijo
9877
9878Para proyectos con múltiples tags, puedes filtrar por prefijo:
9879
9880\`\`\`json
9881{
9882  "matching": {
9883    "strategy": "tag",
9884    "tag_prefix": "XRAY-",
9885    "tag_pattern": "[A-Z]+-\\\\d+"
9886  }
9887}
9888\`\`\`
9889
9890\`\`\`gherkin
9891@XRAY-PROJ-101 @smoke @regression
9892Scenario: Solo XRAY-PROJ-101 será matcheado
9893  ...
9894\`\`\`
9895
9896### Estrategia: Nombre del Escenario
9897
9898Compara el nombre del escenario contra los summaries de Test Issues en Xray:
9899
9900\`\`\`json
9901{
9902  "matching": {
9903    "strategy": "scenario_name"
9904  }
9905}
9906\`\`\`
9907
9908### Estrategia: Custom Field
9909
9910Compara contra un campo personalizado de Jira:
9911
9912\`\`\`json
9913{
9914  "matching": {
9915    "strategy": "custom_field",
9916    "custom_field_id": "customfield_10042"
9917  }
9918}
9919\`\`\`
9920
9921### Estrategia: Hybrid
9922
9923Intenta tag primero; si no encuentra match, usa scenario_name como fallback:
9924
9925\`\`\`json
9926{
9927  "matching": {
9928    "strategy": "hybrid"
9929  }
9930}
9931\`\`\`
9932
9933### Múltiples Keys
9934
9935Cuando un escenario está asociado a varios tests:
9936
9937\`\`\`json
9938{
9939  "matching": {
9940    "multiple_keys": true
9941  }
9942}
9943\`\`\`
9944
9945### Comportamiento para Escenarios No Matcheados
9946
9947| Valor | Comportamiento |
9948|-------|---------------|
9949| \`"skip"\` | Ignora silenciosamente el escenario |
9950| \`"warn"\` | Loguea una advertencia (por defecto) |
9951| \`"create"\` | Crea automáticamente un Test Issue en Xray |`},{id:"xray-agrupacion",title:"Agrupación y Vinculación de Ejecuciones",content:`## Agrupación de Ejecuciones
9952
9953Controla cómo se agrupan los resultados en Test Executions:
9954
9955### Por Feature (por defecto)
9956
9957Crea un Test Execution por cada archivo \`.feature\`:
9958
9959\`\`\`json
9960{
9961  "execution": {
9962    "group_by": "feature"
9963  }
9964}
9965\`\`\`
9966
9967### Por Run
9968
9969Crea un único Test Execution para toda la ejecución:
9970
9971\`\`\`json
9972{
9973  "execution": {
9974    "group_by": "run"
9975  }
9976}
9977\`\`\`
9978
9979### Por Tag
9980
9981Agrupa escenarios por un tag específico:
9982
9983\`\`\`json
9984{
9985  "execution": {
9986    "group_by": "tag",
9987    "group_tag": "sprint-42"
9988  }
9989}
9990\`\`\`
9991
9992### Templates de Summary/Description
9993
9994Los templates soportan placeholders:
9995
9996| Placeholder | Valor |
9997|-------------|-------|
9998| \`{date}\` | Fecha de ejecución (YYYY-MM-DD) |
9999| \`{time}\` | Hora de ejecución (HH:MM:SS) |
10000| \`{feature_name}\` | Nombre del feature |
10001| \`{environment}\` | Entorno de ejecución |
10002| \`{project}\` | Clave del proyecto |
10003
10004Ejemplo:
10005\`\`\`json
10006{
10007  "execution": {
10008    "summary_template": "QA Automation - {feature_name} - {environment} - {date}",
10009    "description_template": "Resultados automáticos del sprint para {feature_name}"
10010  }
10011}
10012\`\`\`
10013
10014---
10015
10016## Vinculación con Test Executions Existentes
10017
10018El framework tiene dos modos de operación respecto a Test Executions:
10019
10020### Modo 1: Crear ejecuciones nuevas (\`create: true\` — por defecto)
10021
10022Cuando \`create\` está activo, el plugin **crea un nuevo Test Execution**. No busca tags de ejecución en los features.
10023
10024\`\`\`json
10025{
10026  "execution": {
10027    "create": true
10028  }
10029}
10030\`\`\`
10031
10032### Modo 2: Actualizar ejecuciones existentes (\`create: false\`)
10033
10034Cuando \`create\` es \`false\`, el plugin **NO crea ejecuciones nuevas**. Busca en los tags del Feature cuál(es) corresponden a Test Executions existentes en Xray para actualizar sus estados.
10035
10036\`\`\`json
10037{
10038  "execution": {
10039    "create": false,
10040    "detect_from_tags": true,
10041    "execution_tag_prefix": null
10042  }
10043}
10044\`\`\`
10045
10046**¿Cómo identifica cuál tag es un Test Execution?**
10047
10048Un feature puede tener tags mezclados:
10049
10050\`\`\`gherkin
10051@PROJ-500 @smoke @regression @PROJ-101
10052Feature: Login
10053
10054  @PROJ-101
10055  Scenario: Login exitoso
10056    ...
10057
10058  @PROJ-102
10059  Scenario: Login con error
10060    ...
10061\`\`\`
10062
10063Aquí \`@PROJ-500\` es un Test Execution, \`@PROJ-101\`/\`@PROJ-102\` son Tests, y \`@smoke\`/\`@regression\` son tags genéricos.
10064
10065**Estrategias de detección:**
10066
10067| Configuración | Comportamiento |
10068|---|---|
10069| \`detect_from_tags: true\` + \`execution_tag_prefix: null\` | Extrae tags que matchean \`[A-Z]+-\\\\d+\`, consulta la API de Jira para verificar el issuetype, usa los que son "Test Execution" |
10070| \`detect_from_tags: true\` + \`execution_tag_prefix: "EXEC-"\` | Busca tags con el prefijo (ej: \`@EXEC-PROJ-500\`). No necesita llamada API |
10071| \`detect_from_tags: false\` + \`existing_execution_key: "PROJ-500"\` | Usa la key fija. Aplica a todos los features |
10072
10073**Ejemplo con validación vía API (recomendado):**
10074
10075\`\`\`json
10076{
10077  "execution": {
10078    "create": false,
10079    "detect_from_tags": true
10080  }
10081}
10082\`\`\`
10083
10084\`\`\`gherkin
10085@PROJ-500 @smoke
10086Feature: Login
10087
10088  @PROJ-101
10089  Scenario: Login exitoso
10090    ...
10091\`\`\`
10092
10093El plugin: extrae \`PROJ-500\` del feature → consulta API → confirma que es Test Execution → importa resultados ahí.
10094
10095**Ejemplo con prefijo (sin llamadas API extra):**
10096
10097\`\`\`json
10098{
10099  "execution": {
10100    "create": false,
10101    "detect_from_tags": true,
10102    "execution_tag_prefix": "EXEC-"
10103  }
10104}
10105\`\`\`
10106
10107\`\`\`gherkin
10108@EXEC-PROJ-500 @smoke
10109Feature: Login
10110
10111  @PROJ-101
10112  Scenario: Login exitoso
10113    ...
10114\`\`\`
10115
10116**Múltiples ejecuciones por feature:**
10117
10118Si un feature tiene varios tags de ejecución, los resultados se reportan a cada una:
10119
10120\`\`\`gherkin
10121@PROJ-500 @PROJ-600
10122Feature: Login (reporta a ambas ejecuciones)
10123  ...
10124\`\`\``},{id:"xray-resultados-estados",title:"Resultados y Estados",content:`## Mapeo de Estados
10125
10126El mapeo entre estados de Behave y estados de Xray:
10127
10128\`\`\`json
10129{
10130  "statuses": {
10131    "mapping": {
10132      "passed": "PASS",
10133      "failed": "FAIL",
10134      "skipped": "ABORTED",
10135      "undefined": "TODO",
10136      "pending": "TODO"
10137    }
10138  }
10139}
10140\`\`\`
10141
10142Puedes personalizar el mapeo según los estados configurados en tu Xray.
10143
10144## Incluir Pasos Individuales
10145
10146Para reportar cada paso Given/When/Then por separado:
10147
10148\`\`\`json
10149{
10150  "results": {
10151    "include_steps": true,
10152    "include_step_data_tables": true
10153  }
10154}
10155\`\`\`
10156
10157## Template de Comentarios
10158
10159Agrega comentarios a cada Test Run con información contextual:
10160
10161\`\`\`json
10162{
10163  "results": {
10164    "comment_template": "Feature: {feature_name}\\nEscenario: {scenario_name}\\nStatus: {status}\\nDuración: {duration}s\\n\\n{error}"
10165  }
10166}
10167\`\`\`
10168
10169## Vinculación de Defectos
10170
10171Extrae automáticamente defect keys de los tags:
10172
10173\`\`\`json
10174{
10175  "results": {
10176    "defects": {
10177      "enabled": true,
10178      "tag_pattern": "BUG-[A-Z]+-\\\\d+"
10179    }
10180  }
10181}
10182\`\`\`
10183
10184\`\`\`gherkin
10185@PROJ-101 @BUG-PROJ-555
10186Scenario: Test con defecto conocido
10187  ...
10188\`\`\``},{id:"xray-evidencias",title:"Evidencias",content:`## Screenshots
10189
10190Adjunta screenshots a los Test Runs:
10191
10192\`\`\`json
10193{
10194  "evidence": {
10195    "screenshots": {
10196      "enabled": true,
10197      "on_failure_only": true
10198    }
10199  }
10200}
10201\`\`\`
10202
10203- \`on_failure_only: true\` — Solo adjunta screenshots de escenarios fallidos
10204- \`on_failure_only: false\` — Adjunta screenshots de todos los escenarios
10205
10206## Video
10207
10208Adjunta grabaciones de video:
10209
10210\`\`\`json
10211{
10212  "evidence": {
10213    "video": {
10214      "enabled": true
10215    }
10216  }
10217}
10218\`\`\`
10219
10220## Reporte HTML
10221
10222Adjunta el reporte HTML al Test Execution:
10223
10224\`\`\`json
10225{
10226  "evidence": {
10227    "html_report": {
10228      "enabled": true
10229    }
10230  }
10231}
10232\`\`\`
10233
10234## Attachments Personalizados
10235
10236Adjunta archivos adicionales usando patrones glob:
10237
10238\`\`\`json
10239{
10240  "evidence": {
10241    "custom_attachments": [
10242      "logs/*.log",
10243      "reports/*.pdf"
10244    ]
10245  }
10246}
10247\`\`\`
10248
10249## Límite de Tamaño
10250
10251\`\`\`json
10252{
10253  "evidence": {
10254    "max_file_size_mb": 10
10255  }
10256}
10257\`\`\`
10258
10259Archivos que excedan el límite son descartados con una advertencia en el log.`},{id:"xray-importacion",title:"Formatos de Importación",content:`## Xray JSON (por defecto)
10260
10261El formato nativo de Xray Cloud:
10262
10263\`\`\`json
10264{
10265  "import": {
10266    "format": "xray_json"
10267  }
10268}
10269\`\`\`
10270
10271## Multipart
10272
10273Para enviar evidencias como archivos adjuntos en la misma solicitud:
10274
10275\`\`\`json
10276{
10277  "import": {
10278    "format": "multipart"
10279  }
10280}
10281\`\`\`
10282
10283## Cucumber JSON
10284
10285Para importar usando el formato estándar de Cucumber:
10286
10287\`\`\`json
10288{
10289  "import": {
10290    "format": "cucumber_json"
10291  }
10292}
10293\`\`\`
10294
10295## Batching
10296
10297Para payloads grandes, divide en lotes:
10298
10299\`\`\`json
10300{
10301  "import": {
10302    "batch_size": 50,
10303    "retry_attempts": 3
10304  }
10305}
10306\`\`\``}
10306,{id:"xray-errores-debug",title:"Manejo de Errores y Debug",content:`## Principio Fundamental
10307
10308**Las pruebas nunca se interrumpen por fallos de la integración Xray.** Los errores de API, timeouts o problemas de red se manejan internamente sin afectar la ejecución de tests.
10309
10310## Opciones de Error Handling
10311
10312\`\`\`json
10313{
10314  "error_handling": {
10315    "fail_on_upload_error": false,
10316    "save_failed_payload": true,
10317    "payload_output_dir": "xray-payloads",
10318    "timeout_seconds": 30
10319  }
10320}
10321\`\`\`
10322
10323| Opción | Descripción |
10324|--------|-------------|
10325| \`fail_on_upload_error\` | Si \`true\`, lanza excepción al final si hubo fallos de upload |
10326| \`save_failed_payload\` | Guarda payloads fallidos en disco para reenvío manual |
10327| \`payload_output_dir\` | Directorio donde se guardan los payloads fallidos |
10328| \`timeout_seconds\` | Timeout para solicitudes HTTP |
10329
10330## Reintentos Automáticos
10331
10332Los siguientes códigos HTTP activan reintentos automáticos:
10333- \`429\` — Rate Limited (respeta header \`Retry-After\`)
10334- \`500\` — Internal Server Error
10335- \`502\` — Bad Gateway
10336- \`503\` — Service Unavailable
10337
10338## Dry Run
10339
10340Genera el payload sin enviar solicitudes HTTP. Ideal para validar la configuración:
10341
10342\`\`\`json
10343{
10344  "debug": {
10345    "dry_run": true,
10346    "output_dir": "xray-debug"
10347  }
10348}
10349\`\`\`
10350
10351El payload se guarda en el directorio \`xray-debug/\` para inspección.
10352
10353## Log Detallado
10354
10355\`\`\`json
10356{
10357  "debug": {
10358    "log_level": "DEBUG",
10359    "log_payloads": true
10360  }
10361}
10362\`\`\`
10363
10364Niveles disponibles: \`DEBUG\`, \`INFO\`, \`WARNING\`, \`ERROR\``},{id:"xray-ciclo-vida",title:"Ciclo de Vida",content:`## Auto-creación de Tests
10365
10366Crea automáticamente Test Issues para escenarios sin match:
10367
10368\`\`\`json
10369{
10370  "lifecycle": {
10371    "auto_create_tests": true
10372  }
10373}
10374\`\`\`
10375
10376## Vinculación con Stories
10377
10378Vincula Test Executions y Tests con Story issues encontradas en tags del feature:
10379
10380\`\`\`json
10381{
10382  "lifecycle": {
10383    "link_to_story": true,
10384    "link_to_execution": true,
10385    "link_type": "Tests"
10386  }
10387}
10388\`\`\`
10389
10390## Actualización de Definición de Test
10391
10392Actualiza los pasos del Test en Xray cuando el escenario cambia:
10393
10394\`\`\`json
10395{
10396  "lifecycle": {
10397    "update_test_definition": true
10398  }
10399}
10400\`\`\``},{id:"xray-ejemplos",title:"Ejemplos Completos",content:`## Ejemplo 1: Configuración Mínima
10401
10402\`\`\`json
10403{
10404  "enabled": true,
10405  "auth": {
10406    "method": "client_credentials"
10407  }
10408}
10409\`\`\`
10410
10411Con variables:
10412\`\`\`bash
10413set XRAY_ENABLED=true
10414set XRAY_CLIENT_ID=mi_client_id
10415set XRAY_CLIENT_SECRET=mi_client_secret
10416\`\`\`
10417
10418## Ejemplo 2: CI/CD con Evidencias Completas
10419
10420\`\`\`json
10421{
10422  "enabled": true,
10423  "auth": {
10424    "method": "client_credentials",
10425    "retry_attempts": 5
10426  },
10427  "execution": {
10428    "group_by": "run",
10429    "summary_template": "CI Build #{build_number} - {date}",
10430    "test_plan_key": "PROJ-1000",
10431    "environments": ["staging"],
10432    "labels": ["automated", "ci"]
10433  },
10434  "matching": {
10435    "strategy": "tag",
10436    "tag_prefix": "TEST-",
10437    "multiple_keys": true,
10438    "unmatched_behavior": "skip"
10439  },
10440  "results": {
10441    "include_steps": true,
10442    "include_duration": true,
10443    "defects": {
10444      "enabled": true
10445    }
10446  },
10447  "evidence": {
10448    "screenshots": {
10449      "enabled": true,
10450      "on_failure_only": true
10451    },
10452    "video": {
10453      "enabled": true
10454    },
10455    "html_report": {
10456      "enabled": true
10457    }
10458  },
10459  "import": {
10460    "format": "xray_json",
10461    "batch_size": 100,
10462    "retry_attempts": 5
10463  },
10464  "error_handling": {
10465    "fail_on_upload_error": true,
10466    "save_failed_payload": true,
10467    "timeout_seconds": 60
10468  }
10469}
10470\`\`\`
10471
10472## Ejemplo 3: Desarrollo Local con Dry Run
10473
10474\`\`\`json
10475{
10476  "enabled": true,
10477  "auth": {
10478    "method": "bearer_token"
10479  },
10480  "matching": {
10481    "strategy": "hybrid",
10482    "unmatched_behavior": "warn"
10483  },
10484  "debug": {
10485    "dry_run": true,
10486    "log_level": "DEBUG",
10487    "log_payloads": true,
10488    "output_dir": "xray-debug"
10489  }
10490}
10491\`\`\`
10492
10493## Ejemplo 4: Scenario Outline con Iteraciones
10494
10495\`\`\`gherkin
10496@PROJ-200
10497Scenario Outline: Validación de login con múltiples datos
10498  Given el usuario ingresa "<usuario>" y "<password>"
10499  When hace clic en login
10500  Then ve el mensaje "<resultado>"
10501
10502  Examples:
10503    | usuario | password | resultado  |
10504    | admin   | 1234     | Bienvenido |
10505    | guest   | wrong    | Error      |
10506\`\`\`
10507
10508Cada fila del Examples genera una iteración separada en el Test Run de Xray.`},{id:"xray-troubleshooting",title:"Solución de Problemas",content:`## El plugin no se activa
10509
105101. Verifica que \`XRAY_ENABLED=true\` está configurado
105112. Verifica que el archivo \`xray_config.json\` existe en la raíz del proyecto
105123. Revisa los logs buscando mensajes del módulo \`hakalab_framework.plugins.xray_cloud_plugin\`
10513
10514## Error de autenticación
10515
105161. Verifica que las variables \`XRAY_CLIENT_ID\` y \`XRAY_CLIENT_SECRET\` están correctas
105172. Las API Keys se generan desde Xray Cloud > Settings > API Keys
105183. Usa \`"debug": {"log_level": "DEBUG"}\` para ver detalles de la autenticación
10519
10520## Escenarios no se matchean
10521
105221. Verifica que los tags siguen el patrón configurado en \`tag_pattern\`
105232. Si usas \`tag_prefix\`, asegúrate de que el tag incluya el prefijo
105243. Usa \`"unmatched_behavior": "warn"\` para ver qué escenarios no matchean
105254. Verifica con \`"debug": {"log_level": "DEBUG"}\` qué está detectando el matcher
10526
10527## Payloads no se envían
10528
105291. Revisa la carpeta \`xray-payloads/\` si \`save_failed_payload\` está habilitado
105302. Usa \`"debug": {"dry_run": true}\` para generar el payload sin enviarlo
105313. Verifica conectividad con la API de Xray Cloud
105324. Revisa los logs para errores HTTP (429, 500, 502, 503)
10533
10534## Conflicto con JiraXrayPlugin
10535
10536Los plugins \`JiraXrayPlugin\` y \`XrayCloudPlugin\` pueden coexistir:
10537- \`JiraXrayPlugin\` se activa con \`JIRA_ENABLED=true\`
10538- \`XrayCloudPlugin\` se activa con \`XRAY_ENABLED=true\`
10539
10540Si quieres usar solo Xray Cloud:
10541\`\`\`bash
10542set XRAY_ENABLED=true
10543set JIRA_ENABLED=false
10544\`\`\`
10545
10546## Resumen de Ejecución
10547
10548Al finalizar cada ejecución, el plugin imprime un resumen:
10549
10550\`\`\`
10551============================================================
10552  Xray Cloud Integration - Run Summary
10553============================================================
10554  Total scenarios:        25
10555  Matched scenarios:      22
10556  Unmatched scenarios:    3
10557------------------------------------------------------------
10558  Uploaded successfully:  1
10559  Upload failures:        0
10560------------------------------------------------------------
10561  Executions created:
10562    - PROJ-5001
10563============================================================
10564\`\`\`
10565
10566Este resumen indica:
10567- Cuántos escenarios se procesaron
10568- Cuántos se vincularon correctamente con test keys
10569- Cuántos uploads fueron exitosos/fallidos
10570- Las keys de los Test Executions creados`},{id:"xray-migracion-legacy",title:"Migración desde Modo Legacy",content:`## Migración desde Modo Legacy
10571
10572Si actualmente usas solo variables de entorno (modo legacy), sigue estos pasos:
10573
10574### Paso 1: Crear xray_config.json
10575
10576\`\`\`json
10577{
10578  "enabled": true,
10579  "auth": {
10580    "method": "bearer_token"
10581  },
10582  "execution": {
10583    "test_plan_key": "TU_TEST_PLAN_KEY"
10584  }
10585}
10586\`\`\`
10587
10588### Paso 2: Mantener variables de entorno de credenciales
10589
10590\`\`\`bash
10591set XRAY_ENABLED=true
10592set XRAY_AUTHORIZATION_TOKEN=tu_token_actual
10593\`\`\`
10594
10595### Paso 3: Verificar con dry_run
10596
10597Agrega temporalmente:
10598\`\`\`json
10599{
10600  "debug": {
10601    "dry_run": true,
10602    "log_level": "DEBUG"
10603  }
10604}
10605\`\`\`
10606
10607### Paso 4: Activar
10608
10609Elimina \`dry_run\` y ejecuta normalmente. El sistema detectará \`xray_config.json\` y usará la configuración nueva.
10610
10611### Paso 5: (Opcional) Migrar a Client Credentials
10612
10613Para mejor seguridad y renovación automática de tokens:
10614
10615\`\`\`json
10616{
10617  "auth": {
10618    "method": "client_credentials"
10619  }
10620}
10621\`\`\`
10622
10623\`\`\`bash
10624set XRAY_CLIENT_ID=nuevo_client_id
10625set XRAY_CLIENT_SECRET=nuevo_client_secret
10626\`\`\``}]},{id:"haka-lens",title:"Haka Lens",group:"Herramientas Haka",icon:"",topics:[{id:"hakalens-descripcion",title:"Descripción General",content:`## Integración con Haka Lens (Cassini)
10627
10628Haka Lens es la plataforma de visibilidad y métricas de calidad de Haka Lab. La integración permite reportar automáticamente los resultados de las ejecuciones de pruebas a Haka Lens en tiempo real.
10629
10630### ¿Qué hace?
10631
10632- Crea una ejecución en Haka Lens al iniciar una suite de pruebas
10633- Reporta el resultado de cada escenario (passed/failed) en tiempo real
10634- Registra tiempos de ejecución por escenario
10635- Permite visualizar tendencias y métricas en el dashboard de Haka Lens
10636- Se integra automáticamente a través del environment.py del framework
10637
10638### ¿Cómo funciona?
10639
106401. Al iniciar \`behave\`, el framework detecta \`CASSINI_ENABLED=true\` en el .env
106412. Se crea una ejecución en Haka Lens con el título de la suite
106423. Por cada escenario ejecutado, se reporta su estado y duración
106434. Al finalizar, la ejecución se cierra automáticamente
106445. Los resultados son visibles inmediatamente en el dashboard`},{id:"hakalens-configuracion",title:"Configuración",content:`## Configuración de Haka Lens
10645
10646### Variables de Entorno (.env)
10647
10648\`\`\`env
10649# Habilitar/deshabilitar la integración
10650CASSINI_ENABLED=true
10651
10652# URL de la API de Haka Lens
10653CASSINI_API_URL=https://us-central1-cassini-eae7e.cloudfunctions.net/api/v1
10654
10655# API Key (obtenida desde el dashboard de Haka Lens)
10656CASSINI_API_KEY=tu_api_key_aqui
10657
10658# ID del equipo (obtenido desde el dashboard)
10659CASSINI_TEAM_ID=tu_team_id_aqui
10660
10661# Título personalizado para la suite (opcional)
10662CASSINI_SUITE_TITLE=Mi Suite de Regresión
10663
10664# Entorno de ejecución (opcional)
10665CASSINI_ENVIRONMENT=staging
10666
10667# Total de pasos fijo (opcional, se calcula automáticamente si no se especifica)
10668# CASSINI_TOTAL_STEPS=10
10669\`\`\`
10670
10671### Variables Requeridas
10672
10673| Variable | Descripción |
10674|----------|-------------|
10675| CASSINI_ENABLED | Debe ser \`true\` para activar la integración |
10676| CASSINI_API_URL | URL base de la API |
10677| CASSINI_API_KEY | API Key de autenticación (Bearer token) |
10678| CASSINI_TEAM_ID | Identificador del equipo en Haka Lens |
10679
10680### Variables Opcionales
10681
10682| Variable | Descripción |
10683|----------|-------------|
10684| CASSINI_SUITE_TITLE | Nombre de la suite (si no se especifica, se auto-genera) |
10685| CASSINI_ENVIRONMENT | Nombre del ambiente (staging, production, etc.) |
10686| CASSINI_TOTAL_STEPS | Número total de escenarios (se calcula automáticamente) |`},{id:"hakalens-uso",title:"Uso y Flujo",content:`## Uso de Haka Lens
10687
10688### Activación Automática
10689
10690Una vez configurado en el .env, no necesitas hacer nada más. El framework se encarga automáticamente de:
10691
106921. Detectar que Cassini está habilitado
106932. Crear la ejecución al inicio
106943. Reportar cada escenario
106954. Cerrar la ejecución al finalizar
10696
10697### Flujo de Reporte
10698
10699\`\`\`
10700before_all:
10701  → Inicializa CassiniIntegration
10702  → Crea ejecución (POST /executions)
10703  → Obtiene executionId
10704
10705after_scenario:
10706  → Reporta paso (POST /executions/{id}/steps)
10707  → Status: 'passed' o 'failed'
10708  → Incluye tiempo de ejecución en ms
10709
10710after_all:
10711  → La ejecución se cierra automáticamente
10712  → Dashboard se actualiza en tiempo real
10713\`\`\`
10714
10715### Ejecución Paralela
10716
10717Cuando ejecutas en paralelo con múltiples workers:
10718- Se crea UNA sola ejecución compartida
10719- Todos los workers reportan a la misma ejecución
10720- El total de steps se calcula automáticamente entre todos los workers
10721
10722### Comportamiento ante Errores
10723
10724- Si Cassini no está disponible (red caída), los tests continúan normalmente
10725- Los errores de conexión se loguean pero no interrumpen la ejecución
10726- Si la API Key es inválida, se muestra un mensaje y se desactiva para el resto de la ejecución
10727
10728### Ejemplo de Feature
10729
10730\`\`\`gherkin
10731# No necesitas ningún tag especial ni step adicional
10732# Solo tener CASSINI_ENABLED=true en el .env
10733
10734Feature: Login de usuarios
10735
10736  Scenario: Login exitoso
10737    Given voy a la url "\${ENV.BASE_URL}/login"
10738    When relleno el campo "email" con "[email protected]" con identificador "$.LOGIN.email"
10739    Then debería ver el elemento "dashboard" con identificador "$.DASHBOARD.panel"
10740    # → Se reporta automáticamente a Haka Lens como PASSED
10741
10742  Scenario: Login fallido
10743    Given voy a la url "\${ENV.BASE_URL}/login"
10744    When relleno el campo "email" con "invalido" con identificador "$.LOGIN.email"
10745    Then debería ver el texto "Credenciales incorrectas"
10746    # → Se reporta automáticamente a Haka Lens como PASSED o FAILED según resultado
10747\`\`\``},{id:"hakalens-dashboard",title:"Dashboard y Métricas",content:`## Dashboard de Haka Lens
10748
10749### ¿Qué ves en el Dashboard?
10750
10751- **Ejecuciones en tiempo real**: progreso de la suite actual
10752- **Historial de ejecuciones**: tendencia de passed/failed a lo largo del tiempo
10753- **Métricas por equipo**: resultados agregados por CASSINI_TEAM_ID
10754- **Duración**: tiempos promedio por escenario y por suite
10755- **Ambientes**: filtrar por CASSINI_ENVIRONMENT (staging, production, etc.)
10756
10757### Cómo Obtener las Credenciales
10758
107591. Accede al dashboard de Haka Lens
107602. Ve a Configuración → API Keys
107613. Genera una nueva API Key
107624. Copia el Team ID de tu equipo
107635. Configura ambos en el .env
10764
10765### Troubleshooting
10766
10767| Problema | Solución |
10768|----------|----------|
10769| "Cassini no configurado" | Verificar que CASSINI_API_URL, CASSINI_API_KEY y CASSINI_TEAM_ID están definidos |
10770| "No se pudo conectar" | Verificar conectividad a *.cloudfunctions.net puerto 443 |
10771| "Error al crear ejecución" | Verificar que la API Key sea válida y no haya expirado |
10772| Los resultados no aparecen | Verificar CASSINI_ENABLED=true (minúsculas) |
10773| Errores en paralelo | La ejecución compartida se maneja automáticamente, no requiere configuración |`}]},{id:"sesiones-guardadas",title:"Sesiones Guardadas",group:"Fundamentos",icon:"",topics:[{id:"sesiones-concepto",title:"Concepto",content:`## Qué es una Sesión Guardada
10774
10775Una sesión guardada es una captura completa del estado del navegador (cookie
10775s, localStorage, sessionStorage) después de un login exitoso. Permite reutilizar ese estado en ejecuciones automáticas futuras sin repetir el flujo de autenticación, incluyendo MFA/2FA.
10776
10777## Problema que Resuelve
10778
10779Sistemas como Salesforce, SAP, Azure AD, Google Workspace y otros exigen autenticación multi-factor (MFA) que no se puede automatizar de forma confiable. Con sesiones guardadas:
10780
10781- Haces login UNA sola vez (manualmente, con MFA incluido)
10782- Guardas el estado del navegador en un archivo JSON
10783- Tus tests restauran ese estado y acceden al sistema ya logueados
10784
10785## Cómo Funciona Internamente
10786
107871. El framework abre un navegador visible
107882. Tú haces login manualmente (incluyendo código MFA, biometría, SSO, etc.)
107893. Al terminar, el framework captura el storageState de Playwright: cookies (httpOnly, secure, sameSite), localStorage de cada origen, sessionStorage, IndexedDB y Service Workers registrados
107904. Se guarda todo en \`logins/nombre.json\` (encriptado si hay clave)
107915. En la ejecución automática, se inyectan cookies, localStorage, IndexedDB y sessionStorage, y se navega a la URL capturada
107926. El servidor reconoce la sesión como válida y no pide login
10793
10794## Tipos de Sesión
10795
10796| Tipo | Uso | Archivo |
10797|------|-----|---------|
10798| **Estándar** | Salesforce, SAP, Azure AD, Google, etc. | \`logins/nombre.json\` |
10799| **Persistente** | WhatsApp Web, Signal, Telegram | \`logins/.persistent_nombre/\` (directorio) |
10800
10801Las sesiones persistentes guardan el perfil completo del navegador (user_data_dir) y se usan para apps con claves criptográficas no exportables.
10802
10803## Compatibilidad
10804
10805Funciona con cualquier sistema que use cookies para sesión: Salesforce, SAP, Azure AD, Google Workspace, Jira, Confluence, ServiceNow, OAuth2, SSO, etc.
10806
10807## Expiración Típica
10808
10809| Sistema | Duración típica |
10810|---------|-----------------|
10811| Salesforce | 2-12 horas |
10812| SAP | 1-8 horas |
10813| Azure AD | 1-24 horas |
10814| Google Workspace | 1-14 días |`},{id:"sesiones-implementacion",title:"Implementación Paso a Paso",content:`## Implementación Completa (desde cero)
10815
10816Guía para configurar sesiones guardadas en un proyecto nuevo o existente.
10817
10818## Requisitos
10819
10820- Haka Playwright Engine instalado
10821- Playwright browsers instalados (\`playwright install\`)
10822- Acceso al sistema donde se hará login
10823- Terminal interactiva para la captura (no funciona en CI headless)
10824
10825## Paso 1: Generar la clave de encriptación
10826
10827La clave protege las cookies y tokens sensibles que se guardan en disco. Solo necesitas hacerlo **una vez por proyecto**.
10828
10829\`\`\`bash
10830haka-login --gen-key
10831\`\`\`
10832
10833Esto crea el archivo \`.haka_session_key\` en la raíz del proyecto con una clave Fernet aleatoria.
10834
10835**Alternativa para CI/CD:** En vez de archivo, usa la variable de entorno:
10836\`\`\`bash
10837export HAKA_SESSION_KEY="tu-clave-aqui"
10838\`\`\`
10839
10840## Paso 2: Agregar a .gitignore
10841
10842\`\`\`bash
10843echo '.haka_session_key' >> .gitignore
10844echo 'logins/' >> .gitignore
10845\`\`\`
10846
10847Esto evita subir credenciales sensibles al repositorio.
10848
10849## Paso 3: Capturar una sesión
10850
10851\`\`\`bash
10852haka-login --save admin_salesforce --url https://login.salesforce.com
10853\`\`\`
10854
10855**Lo que ocurre:**
108561. Se abre un navegador visible en la URL indicada
108572. Haces login completo (usuario, password, código MFA, lo que sea)
108583. Una vez dentro del sistema, vuelves a la terminal y presionas ENTER
108594. El framework captura cookies + localStorage y los guarda **cifrados** en \`logins/admin_salesforce.json\`
10860
10861**Opciones adicionales:**
10862\`\`\`bash
10863# Usar Firefox en vez de Chromium
10864haka-login --save mi_sesion --url https://mi-app.com --browser firefox
10865
10866# Dar más tiempo para MFA complejos
10867haka-login --save mi_sesion --url https://mi-app.com --timeout 10
10868\`\`\`
10869
10870## Paso 4: Usar en tus tests
10871
10872\`\`\`gherkin
10873Feature: Pruebas en Salesforce
10874
10875  Scenario: Crear nueva cuenta
10876    Given inicio sesion guardada con el usuario "admin_salesforce"
10877    When voy a la url "https://miorg.lightning.force.com/lightning/o/Account/new"
10878    And relleno el campo "Nombre" con "Cliente Test" con identificador "$.ACCOUNT.nombre"
10879    Then deberia ver el texto "se creo correctamente"
10880\`\`\`
10881
10882El step \`inicio sesion guardada\` desencripta el archivo en memoria, inyecta las cookies y navega a la URL donde se capturó. Todo transparente.
10883
10884**Variante: navegar a una URL diferente a la capturada**
10885\`\`\`gherkin
10886Given cargo sesion guardada "admin_sf" y navego a "https://miorg.lightning.force.com/lightning/o/Account/list"
10887\`\`\`
10888
10889## Paso 5: Verificar y listar
10890
10891\`\`\`bash
10892# Ver todas las sesiones (cifrada / sin cifrar)
10893haka-login --list
10894
10895# Ver detalle de una sesión
10896haka-login --info admin_salesforce
10897\`\`\`
10898
10899## Paso 6: Renovar cuando expire
10900
10901Cuando una sesión expira (el test redirige a login), simplemente recaptura:
10902
10903\`\`\`bash
10904haka-login --save admin_salesforce --url https://login.salesforce.com
10905\`\`\`
10906
10907Se sobrescribe y re-encripta automáticamente.
10908
10909## Estructura Final del Proyecto
10910
10911\`\`\`
10912mi-proyecto/
10913├── .env                       # Configuración del framework
10914├── .gitignore                 # Incluye: logins/ y .haka_session_key
10915├── .haka_session_key          # Clave de encriptación (NO commitear)
10916├── logins/                    # Sesiones cifradas (NO commitear)
10917│   ├── admin_salesforce.json
10918│   └── viewer_sap.json
10919├── features/
10920│   ├── environment.py
10921│   └── salesforce.feature
10922├── json_poms/
10923└── requirements.txt
10924\`\`\`
10925
10926## Resumen Rápido
10927
10928| Paso | Comando | Frecuencia |
10929|------|---------|------------|
10930| Generar clave | \`haka-login --gen-key\` | Una vez por proyecto |
10931| Capturar sesión | \`haka-login --save X --url Y\` | Una vez por sesión (o cuando expire) |
10932| Usar en test | \`Given inicio sesion guardada con el usuario "X"\` | Cada ejecución |
10933| Verificar | \`haka-login --list\` | Cuando quieras |`},{id:"sesiones-cli",title:"Comandos CLI",content:`## Capturar Sesión
10934
10935\`\`\`bash
10936# Sintaxis básica
10937haka-login --save <nombre> --url <url_de_login>
10938
10939# Ejemplos reales
10940haka-login --save admin_salesforce --url https://login.salesforce.com
10941haka-login --save sap_qa --url https://sap.miempresa.com/sap/bc/gui/sap/its/webgui
10942haka-login --save azure_user --url https://login.microsoftonline.com
10943
10944# Con opciones adicionales
10945haka-login --save admin_sf --url https://login.salesforce.com --browser firefox --timeout 10
10946\`\`\`
10947
10948## Opciones Disponibles
10949
10950| Opción | Default | Descripción |
10951|--------|---------|-------------|
10952| --save | (requerido) | Nombre para la sesión |
10953| --url | (requerido) | URL de la página de login |
10954| --browser | chromium | Navegador: chromium, firefox, webkit |
10955| --timeout | 5 | Minutos máximos para completar el login |
10956| --persistent | false | Usar sesión persistente (perfil completo, para WhatsApp/Signal) |
10957
10958## Capturar Sesión Persistente
10959
10960Para aplicaciones como WhatsApp Web, Signal o Telegram que usan claves criptográficas internas:
10961
10962\`\`\`bash
10963haka-login --save whatsapp --url https://web.whatsapp.com --persistent
10964haka-login --save signal --url https://signal.link --persistent
10965\`\`\`
10966
10967Esto guarda el perfil completo del navegador en \`logins/.persistent_nombre/\` en vez de un archivo JSON.
10968
10969## Listar Sesiones
10970
10971\`\`\`bash
10972haka-login --list
10973\`\`\`
10974
10975Salida:
10976\`\`\`
10977📋 Sesiones guardadas (3):
10978
10979  • admin_salesforce
10980    URL: https://miorg.lightning.force.com/lightning/page/home
10981    Capturada: 2026-07-10T14:30:22
10982    Cookies: 28
10983
10984  • sap_qa
10985    URL: https://sap.miempresa.com/sap/bc/gui/sap/its/webgui
10986    Capturada: 2026-07-09T09:15:00
10987    Cookies: 12
10988\`\`\`
10989
10990## Ver Información Detallada
10991
10992\`\`\`bash
10993haka-login --info admin_salesforce
10994\`\`\`
10995
10996## Eliminar Sesión
10997
10998\`\`\`bash
10999haka-login --delete sesion_vieja
11000\`\`\`
11001
11002## Renovar Sesión Expirada
11003
11004\`\`\`bash
11005# Simplemente recapturar con el mismo nombre (sobrescribe)
11006haka-login --save admin_salesforce --url https://login.salesforce.com
11007\`\`\``},{id:"sesiones-steps-bdd",title:"Steps BDD Disponibles",content:`## Uso en Features
11008
11009### Login básico (navega a la URL capturada)
11010
11011\`\`\`gherkin
11012Feature: Pruebas en Salesforce
11013
11014  Scenario: Crear nueva cuenta
11015    Given inicio sesion guardada con el usuario "admin_salesforce"
11016    When voy a la url "https://miorg.lightning.force.com/lightning/o/Account/new"
11017    And relleno el campo "Nombre" con "Cliente Test" con identificador "$.ACCOUNT.nombre"
11018    Then debería ver el elemento "Toast" con identificador "$.ACCOUNT.toast_exito"
11019\`\`\`
11020
11021### Login con URL específica (ir directo a una página interna)
11022
11023\`\`\`gherkin
11024Feature: Reportes SAP
11025
11026  Scenario: Descargar reporte mensual
11027    Given cargo sesion guardada "sap_qa" y navego a "https://sap.miempresa.com/reportes/mensuales"
11028    When hago click en el elemento "Generar" con identificador "$.REPORTES.btn_generar"
11029    Then espero a que el elemento "Descarga" sea visible con identificador "$.REPORTES.link_descarga"
11030\`\`\`
11031
11032### Con variables de entorno
11033
11034\`\`\`gherkin
11035Feature: Multi-ambiente
11036
11037  Scenario: Verificar dashboard
11038    Given inicio sesion guardada con el usuario "\${ENV.SESSION_NAME}"
11039    When voy a la url "\${ENV.BASE_URL}/dashboard"
11040    Then debería ver el elemento "Titulo" con identificador "$.DASHBOARD.titulo"
11041\`\`\`
11042
11043### Verificar que la sesión existe antes de usarla
11044
11045\`\`\`gherkin
11046Feature: Validación previa
11047
11048  Scenario: Sesión debe existir
11049    Then verifico que la sesion guardada "admin_salesforce" existe
11050    Given inicio sesion guardada con el usuario "admin_salesforce"
11051\`\`\`
11052
11053### Uso recomendado en Background
11054
11055\`\`\`gherkin
11056Feature: Mi feature
11057
11058  Background:
11059    Given inicio sesion guardada con el usuario "mi_usuario"
11060
11061  Scenario: Test 1
11062    When ...
11063
11064  Scenario: Test 2
11065    When ...
11066\`\`\`
11067
11068Usar en Background asegura que cada escenario restaura la sesión limpia.`},{id:"sesiones-inventario",title:"Inventario de Pasos",content:`## Inventario Completo de Steps de Sesiones Guardadas
11069
11070step: inicio sesion guardada con el usuario "{session_name}"
11071descripcion: Restaura una sesión de login previamente capturada. Detecta automáticamente si la sesión es estándar (cookies + localStorage + IndexedDB) o persistente (perfil completo). Para sesiones estándar: carga cookies, localStorage, IndexedDB y sessionStorage, luego navega a la URL capturada. Para sesiones persistentes: cierra el navegador actual y reabre uno con el perfil guardado.
11072
11073step: cargo sesion guardada "{session_name}" y navego a "{url}"
11074descripcion: Restaura una sesión guardada pero navega a una URL diferente a la capturada. Soporta tanto sesiones estándar como persistentes. Útil para ir directamente a una página interna del sistema sin pasar por el home.
11075
11076step: verifico que la sesion guardada "{session_name}" existe
11077descripcion: Verifica que una sesión guardada existe en la carpeta logins/ antes de intentar restaurarla. Falla con un mensaje claro si no existe, indicando cómo crearla.
11078
11079step: elimino la sesion guardada "{session_name}"
11080descripcion: Elimina el archivo JSON de una sesión guardada de la carpeta logins/. Útil para limpieza de sesiones expiradas o como paso de teardown.
11081
11082## Notas Técnicas
11083
11084**Variables soportadas:**
11085Todos los pasos resuelven variables del framework en el nombre de sesión:
11086\`\`\`gherkin
11087Given inicio sesion guardada con el usuario "\${ENV.SESSION_NAME}"
11088\`\`\`
11089
11090**Qué se restaura (Sesión Estándar):**
11091- Cookies de todos los dominios (incluyendo httpOnly y secure)
11092- localStorage de cada origen visitado durante la captura
11093- sessionStorage de cada pestaña/origen
11094- IndexedDB (bases de datos completas con todos los stores)
11095- Navegación automática a la URL donde se estaba al momento de la captura
11096
11097**Qué se restaura (Sesión Persistente):**
11098- TODO el estado del navegador (perfil completo user_data_dir)
11099- Service Workers, Cache API, WebCrypto keys
11100- IndexedDB con claves criptográficas no exportables
11101- Estado completo de la app (como si nunca hubieras cerrado el navegador)
11102
11103**Qué NO se restaura (Estándar):**
11104- Claves criptográficas no exportables (usar sesión persistente)
11105- Estado de JavaScript en memoria (variables globales, websockets)
11106- Sesiones de WebSocket activas
11107
11108**Detección automática:**
11109El step \`inicio sesion guardada\` detecta automáticamente el tipo de sesión:
11110- Si existe \`logins/.persistent_nombre/\` → sesión persistente
11111- Si existe \`logins/nombre.json\` → sesión estándar`},{id:"sesiones-encriptacion",title:"Encriptación",content:`## Encriptación de Sesiones
11112
11113Las sesiones guardadas contienen cookies reales con tokens de autenticación. El framework soporta encriptación automática usando Fernet (AES-128-CBC + HMAC-SHA256).
11114
11115## Cómo Funciona
11116
11117- Los archivos \`.json\` en \`logins/\` se guardan encriptados (base64 de Fernet)
11118- Al leer, se detecta automáticamente si el archivo está cifrado o plano (backward compatible)
11119- El archivo cifrado tiene un header \`HAKA_ENC:\` seguido del ciphertext
11120- La clave se deriva de una passphrase usando SHA-256
11121
11122## Configuración de la Clave
11123
11124La clave se obtiene en este orden de prioridad:
11125
111261. **Variable de entorno** \`HAKA_SESSION_KEY\`
111272. **Archivo** \`.haka_session_key\` en la raíz del proyecto
111283. **Generación automática** al capturar la primera sesión
11129
11130### Opción 1: Variable de entorno
11131
11132\`\`\`bash
11133export HAKA_SESSION_KEY=mi_clave_secreta_segura
11134\`\`\`
11135
11136### Opción 2: Archivo de clave
11137
11138\`\`\`bash
11139# Se genera automáticamente la primera vez, o créalo manualmente:
11140echo "mi_clave_secreta" > .haka_session_key
11141chmod 600 .haka_session_key
11142\`\`\`
11143
11144## Habilitar/Deshabilitar Encriptación
11145
11146\`\`\`env
11147# Habilitar (por defecto si hay clave disponible)
11148HAKA_SESSION_ENCRYPT=true
11149
11150# Deshabilitar explícitamente
11151HAKA_SESSION_ENCRYPT=false
11152\`\`\`
11153
11154## Seguridad
11155
11156- Agrega \`.haka_session_key\` al \`.gitignore\`
11157- Agrega \`logins/\` al \`.gitignore\`
11158- En CI/CD, pasa la clave como secreto: \`HAKA_SESSION_KEY\` en environment variables
11159- Los permisos del archivo de clave se restringen automáticamente a \`600\` (solo owner)
11160
11161## Formato del Archivo Encriptado
11162
11163\`\`\`
11164HAKA_ENC:gAAAAABl... (ciphertext en base64)
11165\`\`\`
11166
11167Al leer, el framework detecta el header \`HAKA_ENC:\` y desencripta automáticamente. Si el archivo no tiene el header, se lee como JSON plano (compatibilidad hacia atrás).
11168
11169## Troubleshooting
11170
11171| Problema | Solución |
11172|----------|----------|
11173| "No se encontró clave de encriptación" | Configura HAKA_SESSION_KEY o crea .haka_session_key |
11174| "No se pudo desencriptar la sesión" | La clave es incorrecta o el archivo está corrompido. Recaptura la sesión. |
11175| Sesiones antiguas sin encriptar | Funcionan normalmente (detección automática). Recaptúralas para encriptarlas. |`},{id:"sesiones-persistentes",title:"Sesiones Persistentes",content:`## Sesiones Persistentes (WhatsApp, Signal, Telegram)
11176
11177Las sesiones persistentes son un modo especial para aplicaciones que **no funcionan** con el enfoque clásico de cookies + localStorage. Esto incluye:
11178
11179- **WhatsApp Web** (Signal Protocol + IndexedDB con claves no exportables)
11180- **Signal Web**
11181- **Telegram Web** (MTProto keys)
11182- Cualquier app con WebCrypto keys no exportables o Service Workers con estado criptográfico
11183
11184## Diferencia con Sesiones Estándar
11185
11186| Aspecto | Sesión Estándar | Sesión Persistente |
11187|---------|----------------|-------------------|
11188| Qué guarda | Cookies + localStorage + IndexedDB (exportados) | Perfil COMPLETO del navegador (user_data_dir) |
11189| Cómo restaura | Inyecta datos en un contexto nuevo | Reabre el navegador con el perfil guardado |
11190| Archivo resultante | \`logins/nombre.json\` (cifrable) | \`logins/.persistent_nombre/\` (directorio) |
11191| Compatibilidad | Cualquier sitio con cookies | Apps con claves criptográficas internas |
11192| Tamaño | ~10-100 KB | ~50-500 MB |
11193
11194## Captura
11195
11196\`\`\`bash
11197haka-login --save whatsapp --url https://web.whatsapp.com --persistent
11198\`\`\`
11199
11200**Lo que ocurre:**
112011. Se abre un navegador con un perfil dedicado (user_data_dir)
112022. Escaneas el QR o completas el login
112033. Esperas a que la app cargue completamente
112044. Presionas ENTER
112055. El perfil completo queda guardado en \`logins/.persistent_whatsapp/\`
11206
11207## Uso en Tests
11208
11209Los steps son los mismos. El framework detecta automáticamente si la sesión es persistente:
11210
11211\`\`\`gherkin
11212Feature: Notificaciones WhatsApp
11213
11214  Scenario: Enviar mensaje
11215    Given inicio sesion guardada con el usuario "whatsapp"
11216    When hago click en el elemento "Buscar" con identificador "$.WA.search"
11217    And relleno el campo "Buscar" con "Equipo QA" con identificador "$.WA.search_input"
11218\`\`\`
11219
11220O con URL de navegación:
11221
11222\`\`\`gherkin
11223Given cargo sesion guardada "whatsapp" y navego a "https://web.whatsapp.com"
11224\`\`\`
11225
11226## Cómo Funciona Internamente
11227
112281. El framework detecta que la sesión tiene un directorio \`.persistent_*\`
112292. Cierra el navegador actual del framework
112303. Abre un nuevo navegador con \`launch_persistent_context(user_data_dir=...)\`
112314. El navegador reconoce la sesión válida y no pide re-escaneo de QR
112325. Todo el estado (Service Workers, IndexedDB, Cache API, WebCrypto keys) se mantiene
11233
11234## Renovación
11235
11236Para WhatsApp: la sesión dura ~14 días. Si expira, simplemente recaptura:
11237
11238\`\`\`bash
11239haka-login --save whatsapp --url https://web.whatsapp.com --persistent
11240\`\`\`
11241
11242## Consideraciones
11243
11244- Las sesiones persistentes NO se encriptan (son directorios, no archivos JSON)
11245- Son más pesadas en disco (~50-500 MB)
11246- No se pueden compartir fácilmente entre máquinas
11247- Solo funcionan con el mismo tipo de navegador con que se capturaron
11248- Agregar \`logins/.persistent_*/\` al \`.gitignore\``},{id:"sesiones-captura-avanzada",title:"Captura Avanzada",content:`## Datos que se Capturan Automáticamente
11249
11250A partir de la v1.5, la captura de sesiones incluye mucho más que cookies:
11251
11252| Dato | Descripción | Cuándo es útil |
11253|------|-------------|----------------|
11254| **Cookies** | Todas (httpOnly, secure, sameSite) | Siempre — es la base de toda sesión |
11255| **localStorage** | Por cada origen visitado | Apps que guardan tokens JWT, preferencias |
11256| **sessionStorage** | Por cada pestaña/origen | SAP, apps bancarias (tokens CSRF, session IDs) |
11257| **IndexedDB** | Bases de datos completas | Firebase, Auth0, Salesforce Lightning, SAP Fiori |
11258| **Service Workers** | Registros detectados | Apps PWA con auth en Service Workers |
11259
11260## IndexedDB
11261
11262Muchas aplicaciones modernas almacenan tokens y estado crítico en IndexedDB:
11263
11264- **Firebase**: \`firebaseLocalStorageDb\` con tokens de autenticación
11265- **Auth0**: Tokens de refresh y access
11266- **Salesforce Lightning**: Cache de componentes y estado de sesión
11267- **SAP Fiori**: Estado de la UI y tokens
11268
11269El framework captura todas las bases de datos IndexedDB accesibles y las restaura automáticamente al inicio de la sesión.
11270
11271## sessionStorage
11272
11273A diferencia de localStorage, el sessionStorage se pierde al cerrar la pestaña. Sin embargo, durante la captura se preserva:
11274
11275- Tokens CSRF de aplicaciones bancarias
11276- IDs de sesión de SAP
11277- Estado de navegación de SPAs
11278
11279**Nota**: La restauración de sessionStorage requiere que la app no invalide estos valores al detectar una nueva pestaña.
11280
11281## Formato del Archivo de Sesión
11282
11283\`\`\`json
11284{
11285  "_metadata": {
11286    "session_name": "admin_salesforce",
11287    "login_url": "https://login.salesforce.com",
11288    "captured_url": "https://miorg.lightning.force.com/home",
11289    "captured_at": "2026-07-10T14:30:22",
11290    "browser": "chromium",
11291    "framework_version": "1.5.0",
11292    "encrypted": true,
11293    "captured_data": ["sessionStorage", "indexedDB", "serviceWorkers"]
11294  },
11295  "storageState": { "cookies": [...], "origins": [...] },
11296  "sessionStorage": [{ "origin": "...", "sessionStorage": [...] }],
11297  "indexedDB": [{ "origin": "...", "name": "...", "stores": {...} }],
11298  "serviceWorkers": [{ "scope": "...", "active": true }]
11299}
11300\`\`\`
11301
11302El campo \`captured_data\` indica qué datos adicionales se incluyeron en la captura (varía según la app).
11303
11304## Restauración Inteligente
11305
11306Al restaurar, el framework:
11307
113081. Inyecta cookies en el browser context
113092. Navega a cada origen para restaurar localStorage
113103. Navega a cada origen de IndexedDB y recrea las bases/stores
113114. Navega a cada origen de sessionStorage y restaura items
113125. Finalmente navega a la URL objetivo
11313
11314Todo esto es transparente: el step \`inicio sesion guardada\` hace todo automáticamente.
11315
11316## Troubleshooting
11317
11318| Problema | Causa | Solución |
11319|----------|-------|----------|
11320| La app pide login de nuevo | Cookies expiradas | Recapturar la sesión |
11321| IndexedDB no se restaura | La app cambió el schema | Recapturar la sesión |
11322| sessionStorage se ignora | La app invalida en nueva pestaña | Usar sesión persistente |
11323| "Service Workers detectados" | Info — no es un error | Los SW se re-registran solos |`}]},{id:"haka-agent",title:"🧪 Haka Agent (Experimental)",group:"Herramientas Haka",icon:"🤖",topics:[{id:"agent-concepto",title:"Concepto",content:`## Haka Agent — Discovery Automatizado
11324
11325>
11325 ⚠️ **EXPERIMENTAL**: Esta funcionalidad está en fase experimental. Su API, comportamiento y artefactos generados pueden cambiar entre versiones sin previo aviso. Úsala para explorar y documentar, pero revisa siempre los resultados antes de incorporarlos a tu suite.
11326
11327Haka Agent (\`haka-agent\`) es un agente que recorre una aplicación web, entiende qué hace, y genera automáticamente tres cosas:
11328
113291. **Documentación funcional** — Un reporte markdown con reglas de negocio, validaciones y comportamientos observados
113302. **Localizadores verificados (JSON POM)** — Con fallbacks y puntaje de estabilidad
113313. **Escenarios BDD ejecutables** — En el formato estándar del framework, listos para correr con \`behave\`
11332
11333## Principio Fundamental
11334
11335A diferencia de un generador de tests basado en IA convencional, el agente **ejecuta primero y escribe el test después**. Cada acción se ejecuta en un navegador real, su efecto se observa comparando el estado antes y después, y solo entonces se sintetiza el escenario. Un escenario marcado como \`@verificado\` tiene la garantía de que sus pasos funcionaron y sus aserciones corresponden a algo que efectivamente ocurrió.
11336
11337## IA Opcional
11338
11339La IA es una capa opcional. Sin ella el agente sigue verificando selectores, construyendo la matriz de casos de formularios y observando efectos. Con IA activa se añade: análisis funcional, detección de reglas de negocio, planificación de flujos y nombres descriptivos de escenarios.
11340
11341## Ejemplo Rápido
11342
11343\`\`\`bash
11344cd /ruta/a/tu/proyecto-de-pruebas
11345haka-agent exhaustive --url https://miapp.com/formulario --dry-run
11346\`\`\`
11347
11348Esto analiza el formulario, genera selectores verificados, construye la matriz de casos, y produce un feature y un reporte — sin enviar ningún formulario.`},{id:"agent-instalacion",title:"Requisitos e Instalación",content:`## Requisitos
11349
11350> ⚠️ **EXPERIMENTAL**: Haka Agent requiere la última versión del framework.
11351
11352El agente necesita:
11353- Haka Playwright Engine instalado
11354- Playwright browsers instalados
11355- Opcionalmente: un proveedor de IA para análisis funcional
11356
11357\`\`\`bash
11358pip install haka-playwright-engine
11359playwright install chromium
11360\`\`\`
11361
11362## Configuración de IA (opcional)
11363
11364El agente reutiliza la misma configuración de IA del framework. Configura en tu \`.env\`:
11365
11366\`\`\`env
11367# Gemini (recomendado por costo y velocidad)
11368AI_PROVIDER=gemini
11369GEMINI_API_KEY=tu_api_key
11370AI_MODEL=gemini-2.5-flash
11371\`\`\`
11372
11373Otros proveedores soportados: OpenAI, Anthropic, Ollama local.
11374
11375## Sin IA
11376
11377Sin proveedor configurado el agente funciona en modo determinista: selectores verificados, matriz de casos y observación de efectos. Lo que se pierde es el análisis funcional, reglas de negocio y nombres descriptivos.
11378
11379## Importante
11380
11381- Ejecutar desde el directorio del proyecto (donde está el \`.env\`)
11382- Chromium es el navegador recomendado
11383- Un discovery completo puede consumir 20-100 llamadas al modelo de IA`},{id:"agent-modos",title:"Modos de Operación",content:`## Los Cuatro Modos
11384
11385> ⚠️ **EXPERIMENTAL**: Los modos y sus opciones pueden cambiar.
11386
11387### exhaustive — Agotar una vista
11388
11389\`\`\`bash
11390haka-agent exhaustive --url https://miapp.com/crear-pedido --dry-run
11391\`\`\`
11392
11393Prueba cada elemento interactivo y construye la matriz completa de casos de formularios: obligatorios faltantes, formatos inválidos, valores frontera, solo espacios, caracteres especiales y longitud máxima. Ideal para "quiero conocer todas las casuísticas de esta pantalla".
11394
11395### explore — Mapear la aplicación
11396
11397\`\`\`bash
11398haka-agent explore --url https://miapp.com --autonomous --budget 60 --max-states 25
11399\`\`\`
11400
11401Recorrido libre con frontera de exploración y backtracking. Prioriza contenido funcional sobre menús de navegación. Genera documentación general y el \`graph.json\` para regression.
11402
11403### flow — Completar un objetivo concreto
11404
11405\`\`\`bash
11406haka-agent flow --url https://miapp.com --goal "crear un pedido nuevo con dos productos"
11407\`\`\`
11408
11409La IA planifica los pasos, el executor confirma que cada uno funcionó. Si un paso falla, replanifica. **Requiere proveedor de IA**.
11410
11411### regression — Detectar cambios
11412
11413\`\`\`bash
11414# Generar línea base
11415haka-agent explore --url https://miapp.com --autonomous --session baseline_v1
11416
11417# Comparar después de un release
11418haka-agent regression --url https://miapp.com --baseline discovery/graph.json
11419\`\`\`
11420
11421Compara el estado actual contra un grafo de referencia. Reporta vistas nuevas, vistas que ya no responden, y elementos que cambiaron.
11422
11423## Recomendación
11424
11425- Empezar siempre con \`exhaustive\` sobre una pantalla conocida
11426- \`explore\` con \`--read-only\` para mapear sin riesgo
11427- \`flow\` es el único modo que no funciona sin IA
11428- \`regression\` necesita un \`graph.json\` previo`},{id:"agent-opciones-cli",title:"Opciones CLI",content:`## Opciones Comunes
11429
11430> ⚠️ **EXPERIMENTAL**: Las opciones pueden cambiar entre versiones.
11431
11432| Opción | Valor | Descripción |
11433|---|---|---|
11434| \`--url\` | URL | Punto de partida (obligatoria salvo \`--cdp-url\`) |
11435| \`--cdp-url\` | \`http://localhost:9222\` | Adoptar un Chrome ya abierto |
11436| \`--browser\` | chromium/chrome/firefox/webkit | Navegador a usar |
11437| \`--budget\` | entero (default: 60) | Máximo de acciones a ejecutar |
11438| \`--max-states\` | entero (default: 25) | Máximo de vistas distintas |
11439| \`--output\` | ruta (default: .) | Directorio de salida |
11440| \`--session\` | nombre | Nombre del POM y feature |
11441| \`--login-session\` | nombre | Sesión guardada con haka-login |
11442| \`--locale\` | es-CL | Locale de los datos generados |
11443| \`--instructions\` | texto | Contexto de negocio para el agente |
11444| \`--autonomous\` | flag | Sin preguntar al QA |
11445| \`--dry-run\` | flag | Rellenar pero no enviar formularios |
11446| \`--read-only\` | flag | Solo navegar y leer |
11447| \`--headless\` | flag | Sin ventana visible |
11448
11449## Opciones Específicas
11450
11451\`\`\`bash
11452# flow: requiere objetivo
11453haka-agent flow --url URL --goal "descripción del objetivo"
11454
11455# regression: ruta de línea base
11456haka-agent regression --url URL --baseline discovery/graph.json
11457\`\`\`
11458
11459## Notas
11460
11461- \`--budget\` cuenta acciones (clicks, fills, selects), no páginas
11462- Un formulario de 6 campos consume ~7 acciones
11463- Sin \`--session\` el nombre se genera con timestamp
11464- \`--cdp-url\` ignora \`--browser\` y \`--headless\`
11465- \`--instructions\` y \`--goal\` requieren IA configurada
11466
11467## Ejemplos
11468
11469Todos los ejemplos se ejecutan **desde la raíz de tu proyecto de pruebas**, donde está el \`.env\`. Ahí es donde el agente escribe \`features/generated/\`, \`json_poms/\` y \`discovery/\`.
11470
11471## 1. Primera vez: conocer una pantalla
11472
11473Si nunca usaste el agente, empezá por acá. Una sola pantalla, sin enviar nada:
11474
11475\`\`\`bash
11476haka-agent exhaustive --url https://miapp.com/contacto --dry-run
11477\`\`\`
11478
11479Qué pasa: abre una ventana de Chromium, verifica un selector para cada elemento de la pantalla, construye la matriz de casos del formulario (obligatorios faltantes, formatos inválidos, límites de longitud) y rellena los campos **sin apretar Enviar**.
11480
11481Qué obtenés:
11482
11483\`\`\`
11484json_poms/06082026_2132.json          # localizadores verificados
11485features/generated/06082026_2132.feature
11486discovery/06082026_2132.md            # análisis funcional
11487discovery/screenshots/
11488\`\`\`
11489
11490> 💡 \`exhaustive\` fuerza \`--max-states\` a un máximo de **3** aunque pidas más. Es a propósito: el modo existe para agotar *una* vista, no para navegar.
11491
11492## 2. Mapear una aplicación completa sin tocar nada
11493
11494\`\`\`bash
11495haka-agent explore --url https://miapp.com --read-only --autonomous --budget 40
11496\`\`\`
11497
11498\`--read-only\` limita al agente a navegar y leer: no rellena ni envía. Es la forma segura de largarlo contra un ambiente que no conocés, o contra algo parecido a producción.
11499
11500\`--autonomous\` evita que te pregunte antes de cada acción de riesgo. Combinado con \`--read-only\` no hay riesgo que confirmar, así que van bien juntos.
11501
11502## 3. Explorar en serio, creando datos
11503
11504\`\`\`bash
11505haka-agent explore --url https://qa.miapp.com --autonomous \\
11506  --budget 80 --max-states 30 --session mapeo_qa_v1
11507\`\`\`
11508
11509Sin \`--dry-run\` ni \`--read-only\`, el agente **sí** envía formularios y crea registros. Usalo en QA, nunca en producción.
11510
11511\`--session mapeo_qa_v1\` fija el nombre: el POM queda en \`json_poms/MAPEO_QA_V1.json\` y el feature en \`features/generated/mapeo_qa_v1.feature\`. Volver a correr con la misma sesión **acumula** en esos archivos en vez de sobrescribirlos.
11512
11513## 4. Aplicación con login
11514
11515### Opción A — Guardar la sesión una vez (recomendado)
11516
11517Sirve incluso con MFA/2FA, porque el login lo hacés vos a mano una sola vez:
11518
11519\`\`\`bash
11520# 1. Login manual. Se abre el navegador y tenés 5 minutos para entrar.
11521haka-login --save qa_admin --url https://miapp.com/login
11522
11523# 2. Verificar que quedó guardada
11524haka-login --list
11525
11526# 3. El agente arranca ya autenticado
11527haka-agent explore --url https://miapp.com/dashboard \\
11528  --login-session qa_admin --autonomous --budget 60
11529\`\`\`
11530
11531La sesión queda en \`logins/qa_admin.json\` (cookies + localStorage). Opciones útiles:
11532
11533\`\`\`bash
11534haka-login --save wpp --url https://web.whatsapp.com --persistent
11535haka-login --save admin --url https://miapp.com --timeout 10
11536haka-login --info qa_admin
11537haka-login --encrypt qa_admin
11538haka-login --delete qa_admin
11539\`\`\`
11540
11541> \`--persistent\` usa un perfil de Chrome completo en vez de solo cookies. Necesario para apps que atan la sesión al dispositivo, como WhatsApp o Signal.
11542
11543### Opción B — Adoptar un Chrome que ya tenés abierto
11544
11545\`\`\`bash
11546# 1. Abrir Chrome con el puerto de depuración
11547google-chrome --remote-debugging-port=9222 --user-data-dir=/tmp/chrome-haka
11548
11549# 2. Navegar a mano hasta donde quieras: login, filtros, pasos previos...
11550
11551# 3. Enganchar el agente a esa pestaña, sin --url
11552haka-agent exhaustive --cdp-url http://localhost:9222 --dry-run
11553\`\`\`
11554
11555Cuando pasás \`--cdp-url\` **sin** \`--url\`, el agente arranca desde donde esté la pestaña. Es la vía más práctica para llegar a una pantalla enterrada detrás de varios pasos: llegás vos a mano y desde ahí toma el control.
11556
11557Si además pasás \`--url\`, navega a esa dirección dentro del navegador adoptado.
11558
11559## 5. Un objetivo concreto
11560
11561\`\`\`bash
11562haka-agent flow --url https://miapp.com \\
11563  --goal "crear un pedido nuevo con dos productos y confirmarlo"
11564\`\`\`
11565
11566La IA planifica los pasos eligiendo entre elementos ya verificados, y el executor confirma que cada uno tuvo efecto. Si un paso falla, replanifica con lo que aprendió.
11567
11568Es el **único modo que no funciona sin IA**: sin un proveedor configurado no hay quién planifique.
11569
11570Un objetivo bien escrito hace toda la diferencia. Comparalo:
11571
11572\`\`\`bash
11573# Vago: el agente no sabe cuándo terminó
11574--goal "probar el checkout"
11575
11576# Concreto: hay un criterio de éxito observable
11577--goal "agregar el producto SKU-1234 al carro, aplicar el cupón QA10 y \\
11578        llegar a la pantalla de confirmación de pago"
11579\`\`\`
11580
11581## 6. Línea base y regresión
11582
11583\`\`\`bash
11584# Antes del release: fotografiar la aplicación
11585haka-agent explore --url https://miapp.com --autonomous \\
11586  --budget 80 --session baseline_v1
11587
11588# Guardar el grafo con un nombre estable
11589cp discovery/graph.json discovery/baseline_v1.json
11590
11591# Después del release: comparar
11592haka-agent regression --url https://miapp.com \\
11593  --baseline discovery/baseline_v1.json
11594\`\`\`
11595
11596El reporte te dice qué vistas aparecieron, cuáles dejaron de responder y qué elementos cambiaron de comportamiento.
11597
11598Sin \`--baseline\` busca en \`discovery/graph.json\`, que es donde \`explore\` deja el último grafo. Sirve para una comparación rápida contra la corrida anterior, pero para regresión de verdad conviene copiarlo a un nombre fijo: si no, la próxima exploración lo pisa.
11599
11600## 7. Darle contexto de negocio
11601
11602El agente no sabe qué significa tu dominio hasta que se lo contás:
11603
11604\`\`\`bash
11605haka-agent exhaustive --url https://miapp.com/alta-cliente \\
11606  --dry-run \\
11607  --instructions "El RUT debe ser chileno y válido con dígito verificador. \\
11608El campo Convenio solo acepta clientes de tipo Empresa. \\
11609No uses correos con dominio @test.com, el sistema los rechaza."
11610\`\`\`
11611
11612Eso cambia los datos que genera y las validaciones que espera. Requiere IA configurada; sin ella se ignora.
11613
11614## 8. Datos en otro locale
11615
11616\`\`\`bash
11617haka-agent exhaustive --url https://app.com.br/cadastro --locale pt-BR --dry-run
11618haka-agent exhaustive --url https://app.com/signup --locale en-US --dry-run
11619\`\`\`
11620
11621\`--locale\` afecta dos cosas: el locale del navegador y el formato de los datos generados (nombres, teléfonos, direcciones, fechas). El default es \`es-CL\`.
11622
11623## 9. En CI, sin ventana
11624
11625\`\`\`bash
11626haka-agent explore --url https://qa.miapp.com \\
11627  --headless --autonomous --read-only \\
11628  --budget 50 --session ci_nightly --output ./artefactos
11629\`\`\`
11630
11631\`--headless\` va casi siempre acompañado de \`--autonomous\`: sin ventana no hay nadie para responder una confirmación.
11632
11633\`--output ./artefactos\` mueve todo lo generado a ese directorio, cómodo para publicarlo como artefacto del pipeline.
11634
11635## 10. Otro navegador
11636
11637\`\`\`bash
11638haka-agent exhaustive --url https://miapp.com --browser chrome --dry-run
11639haka-agent exhaustive --url https://miapp.com --browser firefox --dry-run
11640haka-agent exhaustive --url https://miapp.com --browser webkit --dry-run
11641\`\`\`
11642
11643\`chromium\` (default) es el recomendado y el más probado. \`chrome\` usa el Chrome instalado en el sistema en vez del que trae Playwright. Con \`--cdp-url\` esta opción se ignora.
11644
11645---
11646
11647## Cómo dimensionar \`--budget\`
11648
11649\`--budget\` cuenta **acciones**, no páginas. Sirve de referencia:
11650
11651| Situación | Acciones aproximadas |
11652|---|---|
11653| Formulario de 6 campos + enviar | ~7 |
11654| Matriz de casos de ese formulario | ~25-40 |
11655| Recorrer un menú de 8 secciones | ~8 |
11656| Tabla con filtros y paginación | ~15 |
11657
11658Con \`--budget\` muy bajo el agente corta a mitad de camino y el feature queda incompleto. Muy alto y una corrida puede tardar bastante y consumir muchas llamadas al modelo. Para arrancar, 40-60 es un rango razonable.
11659
11660## Combinaciones que conviene conocer
11661
11662| Combinación | Qué pasa |
11663|---|---|
11664| \`--dry-run\` + \`--read-only\` | Gana el más restrictivo: solo lectura |
11665| \`--cdp-url\` + \`--browser\` | \`--browser\` se ignora, ya hay un navegador |
11666| \`--cdp-url\` + \`--headless\` | \`--headless\` se ignora por el mismo motivo |
11667| \`--cdp-url\` + \`--login-session\` | Gana \`--cdp-url\`: ya hay una sesión viva |
11668| \`--cdp-url\` sin \`--url\` | Arranca desde la pestaña actual |
11669| \`exhaustive\` + \`--max-states 25\` | Se recorta a 3 |
11670| \`flow\` sin IA | Falla: es el único modo que la exige |
11671| \`--headless\` sin \`--autonomous\` | Puede quedar esperando una confirmación que no ves |
11672
11673## Chuleta
11674
11675\`\`\`bash
11676# Conocer una pantalla, sin enviar nada
11677haka-agent exhaustive --url URL --dry-run
11678
11679# Mapear una app sin tocar nada
11680haka-agent explore --url URL --read-only --autonomous
11681
11682# Explorar creando datos, en QA
11683haka-agent explore --url URL --autonomous --budget 80 --session mi_mapeo
11684
11685# Detrás de login
11686haka-login --save usr --url URL/login
11687haka-agent explore --url URL --login-session usr --autonomous
11688
11689# Desde una pantalla a la que llegaste a mano
11690haka-agent exhaustive --cdp-url http://localhost:9222 --dry-run
11691
11692# Un objetivo concreto (requiere IA)
11693haka-agent flow --url URL --goal "objetivo con criterio de éxito claro"
11694
11695# Regresión contra una línea base
11696haka-agent regression --url URL --baseline discovery/baseline_v1.json
11697
11698# Ver la versión instalada
11699haka-agent --version
11700\`\`\``},{id:"agent-seguridad",title:"Modos de Seguridad",content:`## Niveles de Riesgo
11701
11702> ⚠️ **EXPERIMENTAL**
11703
11704El agente clasifica cada acción por nivel de riesgo antes de ejecutarla:
11705
11706| Nivel | Significado |
11707|---|---|
11708| \`safe\` | Sin efectos persistentes (navegar, leer) |
11709| \`caution\` | Crea o modifica datos (enviar formulario) |
11710| \`destructive\` | Borra datos o acciones irreversibles |
11711
11712## Los Tres Modos de Seguridad
11713
11714\`\`\`bash
11715# read_only: solo navegación y lectura
11716haka-agent explore --url https://miapp.com --read-only
11717
11718# dry_run: rellena formularios pero NO los envía
11719haka-agent exhaustive --url https://miapp.com/form --dry-run
11720
11721# normal (default): permite crear y modificar
11722haka-agent exhaustive --url https://miapp.com/form
11723\`\`\`
11724
11725## Recomendaciones
11726
11727- Acciones \`destructive\` se bloquean incluso en modo normal
11728- Usar \`--read-only\` la primera vez que apuntas a un ambiente desconocido
11729- **Nunca apuntar a producción sin \`--read-only\`**
11730- En \`--dry-run\` los escenarios quedan \`@derivado\` porque no se enviaron`},{id:"agent-artefactos",title:"Artefactos Generados",content:`## Estructura de Salida
11731
11732> ⚠️ **EXPERIMENTAL**: El formato de los artefactos puede cambiar.
11733
11734\`\`\`
11735tu-proyecto/
11736├── json_poms/
11737│   └── MI_MODULO.json              Localizadores verificados con fallbacks
11738├── features/generated/
11739│   └── mi_modulo.feature           Escenarios BDD
11740└── discovery/
11741    ├── discovery_mi_modulo.md      Documentación funcional
11742    ├── graph.json                  Grafo de estados (para regression)
11743    └── screenshots/
11744        └── login_page_dfa9342c.png Captura por vista
11745\`\`\`
11746
11747## JSON POM Generado
11748
11749\`\`\`json
11750{
11751  "input_username": {
11752    "selector": "#username",
11753    "fallbacks": [
11754      "//label[normalize-space(text())='Username']/following::input[1]",
11755      "input[name=\\"username\\"]"
11756    ]
11757  },
11758  "btn_login": {
11759    "selector": "//button[contains(normalize-space(.),'Login')]",
11760    "fallbacks": ["button.radius"]
11761  }
11762}
11763\`\`\`
11764
11765Los selectores se usan como: \`$.MI_MODULO.input_username\`
11766
11767## Tags de Escenarios
11768
11769| Tag | Significado |
11770|---|---|
11771| \`@verificado\` | Ejecutado en navegador real, pasos funcionaron |
11772| \`@derivado\` | Inferido del HTML pero no ejecutado |
11773| \`@happy_path\` | Flujo exitoso con datos válidos |
11774| \`@required_missing\` | Campo obligatorio vacío |
11775| \`@format_invalid\` | Formato incorrecto |
11776| \`@boundary_*\` | Valores en los límites |
11777
11778## Ejecutar los Escenarios
11779
11780\`\`\`bash
11781# Solo lo verificado (confiable)
11782behave features/generated/ --tags=@verificado
11783
11784# Solo caminos felices
11785behave features/generated/ --tags=@happy_path
11786
11787# Excluir los derivados sin revisar
11788behave features/generated/ --tags=~@derivado
11789\`\`\`
11790
11791## Acumulación por Sesión
11792
11793Si corres con el mismo \`--session\` varias veces, los selectores nuevos se agregan sin borrar los existentes.`},{id:"agent-formularios",title:"Matriz de Casos",content:'## Matriz de Casos de Formularios\n\n> ⚠️ **EXPERIMENTAL**\n\nCuando el agente encuentra un formulario, extrae las restricciones del HTML (`required`, `type`, `pattern`, `minlength`, `maxlength`, `min`, `max`) y deriva una matriz de casos de forma **determinista** (no depende de la IA):\n\n| Categoría | Qué prueba |\n|---|---|\n| `happy_path` | Todos los campos válidos |\n| `required_missing` | Falta un campo obligatorio (uno por campo) |\n| `format_invalid` | Formato incorrecto según type o pattern |\n| `boundary_min` | Valor en el límite inferior |\n| `boundary_below` | Justo por debajo del límite |\n| `boundary_max` | Valor en el límite superior |\n| `boundary_above` | Justo por encima del límite |\n| `max_length_exact` | Exactamente el máximo permitido |\n| `whitespace_only` | Solo espacios en campo obligatorio |\n| `special_chars` | Apóstrofos, ampersands, ángulos |\n\n## Ejemplo de Escenario Generado\n\n```gherkin\n@formulario @happy_path @positivo @verificado\nScenario: Completar login con datos válidos\n  Given voy a la url "https://miapp.com/login"\n  When relleno el campo "Username" con "Valentina" con identificador "$.MI_MODULO.input_username"\n  And relleno el campo "Password" con "ClaveSegura2026!" con identificador "$.MI_MODULO.input_password"\n  And hago click en el elemento "Login" con identificador "$.MI_MODULO.btn_login"\n  And espero 2 segundos\n  Then debería ver el texto "Your username is invali
11793d!"\n```\n\nEl `Then` no fue inventado: es el mensaje que la aplicación **realmente mostró** al ejecutar el caso.\n\n## Con y Sin IA\n\n- **Con IA**: genera datos plausibles según locale y contexto de negocio\n- **Sin IA**: datos derivados del nombre y tipo del campo (email → email válido, rut → RUT formateado)'},{id:"agent-cdp",title:"Pantallas Profundas (CDP)",content:`## Partir desde una Pantalla Profunda
11794
11795> ⚠️ **EXPERIMENTAL**
11796
11797Cuando la pantalla que quieres analizar está detrás de un login y varios pasos previos (wizard, carrito, formulario dependiente), puedes navegar manualmente y pasarle el control al agente:
11798
11799\`\`\`bash
11800# 1. Abrir Chrome con puerto de depuración
11801google-chrome --remote-debugging-port=9222 --user-data-dir=/tmp/chrome-haka
11802
11803# 2. En ese Chrome: login + navegar hasta la pantalla objetivo
11804
11805# 3. Sin cerrar el navegador, lanzar el agente
11806haka-agent exhaustive --cdp-url http://localhost:9222 --dry-run
11807\`\`\`
11808
11809El agente adopta la pestaña actual y arranca desde ahí, reutilizando tu sesión y estado.
11810
11811## Cuándo Usar Cada Opción
11812
11813| Situación | Opción |
11814|---|---|
11815| Solo hay que pasar el login | \`--login-session\` |
11816| Login + pasos previos (wizard, carrito) | \`--cdp-url\` |
11817| App con claves criptográficas | \`--login-session\` con sesión persistente |
11818
11819## Consideraciones
11820
11821- Solo funciona con navegadores Chromium (Chrome, Edge)
11822- Usar un \`--user-data-dir\` separado
11823- El agente **no cierra tu navegador** al terminar
11824- El agente **sí navega en tu ventana** — duplica la pestaña si necesitas preservar el estado`},{id:"agent-flujo-trabajo",title:"Flujo de Trabajo",content:`## Flujo Recomendado
11825
11826> ⚠️ **EXPERIMENTAL**: Los artefactos generados son un punto de partida, no un reemplazo del criterio del QA.
11827
11828### De Cero a Suite
11829
11830\`\`\`bash
11831# 1. Mapear la aplicación sin tocar nada
11832haka-agent explore --url https://miapp.com --read-only --autonomous \\
11833  --session mapa_general --budget 60
11834
11835# 2. Leer el discovery para entender qué hay
11836#    discovery/discovery_mapa_general.md
11837
11838# 3. Profundizar en las pantallas críticas
11839haka-agent exhaustive --url https://miapp.com/crear-pedido \\
11840  --session pedidos --dry-run
11841
11842# 4. Ejecutar de verdad en ambiente seguro para obtener @verificado
11843haka-agent exhaustive --url https://miapp.com/crear-pedido --session pedidos
11844
11845# 5. Validar un flujo completo
11846haka-agent flow --url https://miapp.com \\
11847  --goal "crear un pedido y confirmarlo" --session flujo_pedido
11848\`\`\`
11849
11850### Uso Continuo (Regresión)
11851
11852\`\`\`bash
11853# Después de cada release
11854haka-agent regression --url https://miapp.com --baseline discovery/graph.json
11855\`\`\`
11856
11857### Organización por Módulo
11858
11859\`\`\`bash
11860haka-agent exhaustive --url https://miapp.com/clientes --session clientes
11861haka-agent exhaustive --url https://miapp.com/pedidos  --session pedidos
11862haka-agent exhaustive --url https://miapp.com/facturas --session facturas
11863\`\`\`
11864
11865Cada \`--session\` genera un POM y feature separado. Correr con el mismo nombre acumula selectores.
11866
11867## Limitaciones Conocidas
11868
11869- No reemplaza el criterio del QA
11870- Solo detecta lo observable desde el frontend
11871- Aplicaciones con captcha bloquean la exploración
11872- Canvas y WebGL no son inspeccionables
11873- \`flow\` requiere IA configurada
11874- Nunca apuntar a producción sin \`--read-only\``},{id:"agent-referencia",title:"Referencia Rápida",content:`## Cheat Sheet
11875
11876> ⚠️ **EXPERIMENTAL**
11877
11878\`\`\`bash
11879# Explorar sin tocar nada
11880haka-agent explore --url URL --read-only --autonomous
11881
11882# Agotar una pantalla sin enviar formularios
11883haka-agent exhaustive --url URL --dry-run
11884
11885# Agotar una pantalla ejecutando de verdad
11886haka-agent exhaustive --url URL
11887
11888# Completar un objetivo dirigido
11889haka-agent flow --url URL --goal "descripción del objetivo"
11890
11891# Detectar cambios contra línea base
11892haka-agent regression --url URL --baseline discovery/graph.json
11893
11894# Con autenticación
11895haka-agent explore --url URL --login-session NOMBRE
11896
11897# Adoptar Chrome abierto (pantallas profundas)
11898haka-agent exhaustive --cdp-url http://localhost:9222 --dry-run
11899
11900# Pipeline: sin ventana, sin preguntas, solo lectura
11901haka-agent explore --url URL --headless --autonomous --read-only
11902
11903# Ayuda
11904haka-agent --help
11905haka-agent <modo> --help
11906\`\`\`
11907
11908## Troubleshooting
11909
11910| Síntoma | Solución |
11911|---|---|
11912| "IA: no configurada" | Ejecutar desde el directorio del proyecto donde está el \`.env\` |
11913| POM con pocos selectores | Subir \`--budget\` o apuntar a la vista específica |
11914| Todos los escenarios \`@derivado\` | Quitar \`--dry-run\` y correr en ambiente seguro |
11915| No pasa del login | Usar \`--login-session\` o \`--cdp-url\` |
11916| Se queda en la misma vista | Subir \`--max-states\` |
11917| "No se pudo conectar a 9222" | Levantar Chrome con \`--user-data-dir\` separado |`}]},{id:"browser-context",title:"Browser Context",group:"Fundamentos",icon:"",topics:[{id:"browser-context-personalizacion",title:"Personalización del Browser Context",content:`## Personalización del Browser Context
11918
11919El framework permite personalizar completamente el navegador que se abre para las pruebas mediante \`context.browser_context_options\` en tu archivo \`environment.py\`. Esto te da acceso a **todas las opciones de Playwright** sin necesidad de modificar el framework.
11920
11921---
11922
11923## Uso Básico
11924
11925En tu \`features/environment.py\`:
11926
11927\`\`\`python
11928from hakalab_framework.core.environment_config import setup_framework_context, setup_sce
11928nario_context
11929
11930def before_all(context):
11931    setup_framework_context(context)
11932    
11933    # Personalizar el browser context
11934    context.browser_context_options = {
11935        'locale': 'es-CL',
11936        'timezone_id': 'America/Santiago',
11937        'color_scheme': 'dark',
11938    }
11939
11940def before_scenario(context, scenario):
11941    setup_scenario_context(context, scenario)
11942\`\`\`
11943
11944Las opciones se aplican **automáticamente** al crear la primera página del navegador.
11945
11946---
11947
11948## Prioridad de Configuración
11949
119501. **\`.env\`** → Configuración base (viewport, timeout, headless, etc.)
119512. **\`context.browser_context_options\`** → Sobrescribe o complementa el .env
119523. **Steps dinámicos** → Pueden cambiar valores en runtime (ej: geolocalización)
11953
11954El merge es **inteligente**:
11955- \`permissions\`: se **concatenan** (framework + usuario). Si el .env pone \`['geolocation']\` y tú pones \`['notifications']\`, el resultado es \`['geolocation', 'notifications']\`.
11956- \`extra_http_headers\`: se **mergean** (dict update, tus headers se agregan a los del framework).
11957- Todo lo demás: **tu valor gana** sobre el del .env.`},{id:"browser-context-opciones",title:"Opciones Disponibles",content:`## Opciones Disponibles
11958
11959Todas las opciones de \`browser.new_context()\` de Playwright están disponibles:
11960
11961### Localización y Zona Horaria
11962
11963\`\`\`python
11964context.browser_context_options = {
11965    'locale': 'es-CL',                    # Idioma del navegador
11966    'timezone_id': 'America/Santiago',     # Zona horaria simulada
11967}
11968\`\`\`
11969
11970Útil para probar que las fechas, formatos numéricos y textos se muestran correctamente según la región.
11971
11972### Geolocalización
11973
11974\`\`\`python
11975context.browser_context_options = {
11976    'geolocation': {
11977        'latitude': -33.4489,
11978        'longitude': -70.6693,
11979        'accuracy': 50,                    # Precisión en metros (opcional)
11980    },
11981    'permissions': ['geolocation'],        # OBLIGATORIO para que funcione
11982}
11983\`\`\`
11984
11985**Nota:** También puedes configurar esto via \`.env\` con \`GEOLOCATION_ENABLED=true\`.
11986
11987### Apariencia
11988
11989\`\`\`python
11990context.browser_context_options = {
11991    'color_scheme': 'dark',               # 'dark', 'light', 'no-preference'
11992    'forced_colors': 'active',            # 'active', 'none' (alto contraste)
11993    'reduced_motion': 'reduce',           # 'reduce', 'no-preference'
11994}
11995\`\`\`
11996
11997Ideal para probar dark mode, accesibilidad y preferencias de movimiento reducido.
11998
11999### Permisos del Navegador
12000
12001\`\`\`python
12002context.browser_context_options = {
12003    'permissions': [
12004        'geolocation',
12005        'notifications',
12006        'clipboard-read',
12007        'clipboard-write',
12008        'camera',
12009        'microphone',
12010    ],
12011}
12012\`\`\`
12013
12014Los permisos se otorgan automáticamente sin popup. Esto resuelve el problema de pruebas bloqueadas por popups de permisos.
12015
12016### Headers HTTP Personalizados
12017
12018\`\`\`python
12019context.browser_context_options = {
12020    'extra_http_headers': {
12021        'X-Custom-Token': 'abc123',
12022        'Accept-Language': 'es-CL,es;q=0.9',
12023        'X-Test-Environment': 'staging',
12024    },
12025}
12026\`\`\`
12027
12028Se envían con **cada request** del navegador. Útil para APIs que requieren headers de autenticación custom.
12029
12030### Autenticación HTTP (Basic Auth)
12031
12032\`\`\`python
12033context.browser_context_options = {
12034    'http_credentials': {
12035        'username': 'admin',
12036        'password': 'secret',
12037    },
12038}
12039\`\`\`
12040
12041Para páginas protegidas con autenticación HTTP básica (el popup de login del browser).
12042
12043### Proxy
12044
12045\`\`\`python
12046context.browser_context_options = {
12047    'proxy': {
12048        'server': 'http://proxy.company.com:8080',
12049        'bypass': '*.internal.com',           # Dominios que no pasan por proxy
12050        'username': 'proxy_user',             # Opcional
12051        'password': 'proxy_pass',             # Opcional
12052    },
12053}
12054\`\`\`
12055
12056### Red y Conectividad
12057
12058\`\`\`python
12059context.browser_context_options = {
12060    'offline': True,                          # Simular sin conexión
12061    'ignore_https_errors': True,              # Ignorar errores SSL
12062}
12063\`\`\`
12064
12065### Dispositivo Móvil
12066
12067\`\`\`python
12068context.browser_context_options = {
12069    'is_mobile': True,
12070    'has_touch': True,
12071    'viewport': {'width': 390, 'height': 844},  # iPhone 14
12072    'device_scale_factor': 3,
12073    'user_agent': 'Mozilla/5.0 (iPhone; CPU iPhone OS 16_0...',
12074}
12075\`\`\`
12076
12077### Seguridad y JavaScript
12078
12079\`\`\`python
12080context.browser_context_options = {
12081    'bypass_csp': True,                       # Ignorar Content-Security-Policy
12082    'java_script_enabled': False,             # Desactivar JavaScript
12083}
12084\`\`\`
12085
12086### Descargas
12087
12088\`\`\`python
12089context.browser_context_options = {
12090    'accept_downloads': True,                 # Permitir descargas automáticas
12091}
12092\`\`\`
12093
12094### Estado de Almacenamiento (Storage State)
12095
12096\`\`\`python
12097context.browser_context_options = {
12098    'storage_state': 'state.json',           # Restaurar cookies/localStorage
12099}
12100\`\`\`
12101
12102Útil para saltar el login reutilizando una sesión previa (ver Sesiones Guardadas).`},{id:"browser-context-ejemplos",title:"Ejemplos Completos",content:`## Ejemplos Completos
12103
12104### E-commerce con ubicación en Santiago + dark mode
12105
12106\`\`\`python
12107def before_all(context):
12108    setup_framework_context(context)
12109    context.browser_context_options = {
12110        'locale': 'es-CL',
12111        'timezone_id': 'America/Santiago',
12112        'geolocation': {'latitude': -33.4489, 'longitude': -70.6693},
12113        'permissions': ['geolocation'],
12114        'color_scheme': 'dark',
12115    }
12116\`\`\`
12117
12118### API interna con proxy + headers custom
12119
12120\`\`\`python
12121def before_all(context):
12122    setup_framework_context(context)
12123    context.browser_context_options = {
12124        'proxy': {'server': 'http://proxy:3128'},
12125        'extra_http_headers': {
12126            'X-API-Key': os.getenv('API_KEY'),
12127            'X-Environment': 'qa',
12128        },
12129        'ignore_https_errors': True,
12130    }
12131\`\`\`
12132
12133### Mobile responsive testing
12134
12135\`\`\`python
12136def before_all(context):
12137    setup_framework_context(context)
12138    context.browser_context_options = {
12139        'is_mobile': True,
12140        'has_touch': True,
12141        'viewport': {'width': 375, 'height': 812},
12142        'device_scale_factor': 3,
12143        'user_agent': 'Mozilla/5.0 (iPhone; CPU iPhone OS 17_0 like Mac OS X)...',
12144    }
12145\`\`\`
12146
12147### Testing offline y sin JavaScript
12148
12149\`\`\`python
12150def before_all(context):
12151    setup_framework_context(context)
12152    context.browser_context_options = {
12153        'offline': True,
12154        'java_script_enabled': False,
12155    }
12156\`\`\`
12157
12158---
12159
12160## Combinación con Steps Dinámicos
12161
12162Las opciones de \`browser_context_options\` se aplican al **crear** el contexto. Si necesitas cambiar valores **durante** la ejecución (ej: cambiar geolocalización entre scenarios), usa los steps dinámicos:
12163
12164\`\`\`gherkin
12165Scenario: Verificar tienda cercana en Santiago
12166  When configuro la geolocalización para "santiago"
12167  And voy a la url "https://tienda.cl/sucursales"
12168  Then debería ver el texto "Providencia"
12169
12170Scenario: Verificar tienda cercana en Valparaíso
12171  When configuro la geolocalización para "valparaiso"
12172  And voy a la url "https://tienda.cl/sucursales"
12173  Then debería ver el texto "Viña del Mar"
12174\`\`\`
12175
12176---
12177
12178## Notas Importantes
12179
12180- **\`browser_context_options\` se lee UNA VEZ** al crear el primer contexto del escenario. Si lo cambias después de \`before_all\`, no tendrá efecto en contextos ya creados.
12181- **No conflicta con el \`.env\`**: El .env sigue siendo la fuente principal para viewport, timeout, headless, browser type, etc. Las \`browser_context_options\` complementan esos valores.
12182- **Reutilización de páginas**: Si el framework reutiliza una página entre scenarios (comportamiento por defecto), las opciones del context ya están aplicadas. Solo si se necesita un **nuevo** contexto se vuelven a aplicar.
12183- **No es necesario importar nada extra**: Solo define el diccionario en \`context\` y el framework lo usa automáticamente.`},{id:"browser-context-geolocation-env",title:"Geolocalización via .env",content:`## Configuración de Geolocalización via .env
12184
12185La forma más simple de habilitar geolocalización es mediante variables de entorno en el archivo \`.env\`:
12186
12187\`\`\`env
12188# Habilitar geolocalización automática
12189GEOLOCATION_ENABLED=true
12190
12191# Coordenadas (obligatorias si GEOLOCATION_ENABLED=true)
12192GEOLOCATION_LATITUDE=-33.4489
12193GEOLOCATION_LONGITUDE=-70.6693
12194
12195# Precisión en metros (opcional, default: 100)
12196GEOLOCATION_ACCURACY=100
12197\`\`\`
12198
12199### Comportamiento
12200
12201Cuando \`GEOLOCATION_ENABLED=true\`:
122021. El framework otorga automáticamente el permiso \`geolocation\` al crear el contexto del navegador
122032. Configura las coordenadas especificadas como ubicación simulada
122043. Las páginas que llamen \`navigator.geolocation.getCurrentPosition()\` recibirán las coordenadas configuradas sin mostrar popup de permiso
12205
12206### Prioridad con browser_context_options
12207
12208Si además defines geolocalización en \`browser_context_options\`, el merge inteligente se aplica:
12209
12210\`\`\`python
12211# .env tiene: GEOLOCATION_ENABLED=true, lat=-33.4489, lon=-70.6693
12212
12213def before_all(context):
12214    setup_framework_context(context)
12215    context.browser_context_options = {
12216        'geolocation': {'latitude': -34.6037, 'longitude': -58.3816},  # Buenos Aires
12217        'permissions': ['notifications'],  # Se concatena con ['geolocation'] del .env
12218    }
12219# Resultado: geolocation=Buenos Aires, permissions=['geolocation', 'notifications']
12220\`\`\`
12221
12222### Combinación con Steps Dinámicos
12223
12224Puedes configurar la geolocalización base via .env y cambiarla durante la ejecución:
12225
12226\`\`\`gherkin
12227# El .env configura Santiago como ubicación inicial
12228# Durante el test, cambias dinámicamente:
12229
12230Scenario: Verificar cambio de ubicación
12231  Given voy a la url "https://mi-app.com/tiendas"
12232  # Usa la ubicación del .env (Santiago)
12233  Then debería ver el texto "Tienda Santiago Centro"
12234  
12235  When configuro la geolocalización para "valparaiso"
12236  And recargo la página
12237  # Ahora usa Valparaíso
12238  Then debería ver el texto "Tienda Viña del Mar"
12239\`\`\`
12240
12241### Ejemplo completo de environment.py con geolocalización
12242
12243\`\`\`python
12244from hakalab_framework.core.environment_config import setup_framework_context, setup_scenario_context
12245
12246def before_all(context):
12247    setup_framework_context(context)
12248    
12249    # Complementar la geolocalización del .env con opciones adicionales
12250    context.browser_context_options = {
12251        'locale': 'es-CL',
12252        'timezone_id': 'America/Santiago',
12253        'permissions': ['notifications'],  # Se suma al 'geolocation' del .env
12254    }
12255
12256def before_scenario(context, scenario):
12257    setup_scenario_context(context, scenario)
12258\`\`\``}]}
12258,{id:"problemas-comunes",title:"Problemas Comunes",group:"Empezar",icon:"",topics:[{id:"problemas-linux",title:"Problemas en Linux",content:`## Problemas en Linux
12259
12260### Error: dependencias del sistema no instaladas
12261
12262\`\`\`
12263playwright._impl._errors.Error: Host system is missing dependencies to run browsers.
12264\`\`\`
12265
12266**Solución:**
12267\`\`\`bash
12268sudo playwright install-deps
12269# O instalar manualmente las dependencias de Chromium:
12270sudo apt-get install -y libgbm1 libasound2 libatk1.0-0 libcups2 libdbus-1-3 libdrm2 libxkbcommon0 libxcomposite1 libxdamage1 libxrandr2 libpango-1.0-0 libcairo2
12271\`\`\`
12272
12273### Error: "No usable sandbox" en Docker/CI
12274
12275\`\`\`
12276Failed to launch chromium because of sandbox limitations
12277\`\`\`
12278
12279**Solución:** Agregar al .env:
12280\`\`\`env
12281CHROMIUM_SANDBOX=false
12282\`\`\`
12283
12284O ejecutar con la variable de entorno:
12285\`\`\`bash
12286PLAYWRIGHT_CHROMIUM_SANDBOX=0 behave
12287\`\`\`
12288
12289### Error: display not found (entornos sin GUI)
12290
12291\`\`\`
12292Error: Failed to launch browser: DISPLAY environment variable is not set
12293\`\`\`
12294
12295**Solución:** Usar modo headless obligatoriamente:
12296\`\`\`env
12297HEADLESS=true
12298\`\`\`
12299
12300O instalar Xvfb para un display virtual:
12301\`\`\`bash
12302sudo apt-get install -y xvfb
12303xvfb-run behave
12304\`\`\`
12305
12306### Error: permisos en la carpeta de screenshots
12307
12308\`\`\`bash
12309chmod -R 777 screenshots/ html-reports/
12310\`\`\`
12311
12312### Playwright no encuentra los browsers tras instalación con pip
12313
12314\`\`\`bash
12315# Verificar que playwright está en el PATH correcto
12316which playwright
12317# Reinstalar browsers
12318python -m playwright install chromium
12319\`\`\`
12320
12321### Error con pyautogui (Desktop) en Linux sin display
12322
12323\`\`\`
12324Xlib.error.DisplayNameError: Bad display name ""
12325\`\`\`
12326
12327**Solución:** PyAutoGUI requiere un display X11. En servidores headless no funciona. Usa Xvfb o ejecuta desktop tests solo en máquinas con GUI.
12328
12329### Firewall corporativo bloquea la validación de licencia
12330
12331**Verificar conectividad:**
12332\`\`\`bash
12333curl -I https://us-central1-haka-licencias-productivos.cloudfunctions.net/validarLicencia
12334# Debe retornar: HTTP 405 Method Not Allowed
12335\`\`\`
12336
12337**Si está bloqueado, pedir a IT que habilite:**
12338\`\`\`
12339Dominio: *.cloudfunctions.net
12340Protocolo: HTTPS
12341Puerto: 443
12342Dirección: Salida (Outbound)
12343\`\`\``},{id:"problemas-macos",title:"Problemas en macOS",content:`## Problemas en macOS
12344
12345### Error: "webkit" no se puede verificar (Gatekeeper)
12346
12347\`\`\`
12348"Playwright.app" can't be opened because Apple cannot check it for malicious software
12349\`\`\`
12350
12351**Solución:**
12352\`\`\`bash
12353# Remover la cuarentena del browser de Playwright
12354xattr -cr ~/Library/Caches/ms-playwright
12355# O usar chromium que no tiene este problema
12356\`\`\`
12357
12358En .env, preferir chromium:
12359\`\`\`env
12360BROWSER=chromium
12361\`\`\`
12362
12363### Error: "Operation not permitted" al tomar screenshots (Desktop)
12364
12365macOS requiere permisos de accesibilidad para PyAutoGUI:
12366
123671. Ir a **System Preferences → Security & Privacy → Privacy → Accessibility**
123682. Agregar la app de Terminal (o iTerm2) a la lista
123693. Si usas un IDE, agregar el IDE también
12370
12371### Error: Tesseract OCR no encontrado
12372
12373\`\`\`bash
12374# Instalar con Homebrew
12375brew install tesseract
12376brew install tesseract-lang  # Para idiomas adicionales
12377
12378# Verificar instalación
12379tesseract --version
12380\`\`\`
12381
12382### Error con certificados SSL en macOS
12383
12384\`\`\`
12385ssl.SSLCertVerificationError: certificate verify failed
12386\`\`\`
12387
12388**Solución:**
12389\`\`\`bash
12390# Instalar certificados de Python
12391/Applications/Python\\ 3.11/Install\\ Certificates.command
12392# O con pip:
12393pip install certifi
12394\`\`\`
12395
12396### Playwright se cierra inesperadamente en macOS Sonoma+
12397
12398\`\`\`bash
12399# Actualizar Playwright a la última versión
12400pip install --upgrade playwright
12401playwright install
12402\`\`\`
12403
12404### Appium + Android emulator en macOS con Apple Silicon (M1/M2/M3)
12405
12406\`\`\`bash
12407# Usar el emulador ARM64 (no x86)
12408# En Android Studio: crear AVD con imagen "arm64-v8a"
12409# Verificar:
12410adb devices
12411\`\`\`
12412
12413### Firewall corporativo bloquea la validación de licencia
12414
12415**Verificar conectividad:**
12416\`\`\`bash
12417curl -I https://us-central1-haka-licencias-productivos.cloudfunctions.net/validarLicencia
12418\`\`\`
12419
12420Si hay proxy corporativo:
12421\`\`\`bash
12422export HTTPS_PROXY=http://proxy.empresa.com:8080
12423\`\`\``},{id:"problemas-windows",title:"Problemas en Windows",content:`## Problemas en Windows
12424
12425### Error: "execution policy" al ejecutar scripts
12426
12427\`\`\`
12428running scripts is disabled on this system
12429\`\`\`
12430
12431**Solución (PowerShell como administrador):**
12432\`\`\`powershell
12433Set-ExecutionPolicy -ExecutionPolicy RemoteSigned -Scope CurrentUser
12434\`\`\`
12435
12436### Error: ruta demasiado larga (path > 260 caracteres)
12437
12438\`\`\`
12439FileNotFoundError: [WinError 3] The system cannot find the path specified
12440\`\`\`
12441
12442**Solución:**
124431. Mover el proyecto a una ruta más corta (ej: \`C:\\tests\\mi_proyecto\`)
124442. O habilitar rutas largas en Windows:
12445\`\`\`powershell
12446# PowerShell como administrador
12447New-ItemProperty -Path "HKLM:\\SYSTEM\\CurrentControlSet\\Control\\FileSystem" -Name "LongPathsEnabled" -Value 1 -PropertyType DWORD -Force
12448\`\`\`
12449
12450### Error: permisos al instalar Playwright browsers
12451
12452\`\`\`
12453PermissionError: [WinError 5] Access is denied
12454\`\`\`
12455
12456**Solución:**
12457\`\`\`bash
12458# Ejecutar como administrador o especificar directorio:
12459set PLAYWRIGHT_BROWSERS_PATH=C:\\playwright-browsers
12460playwright install chromium
12461\`\`\`
12462
12463### Error: pip no reconocido
12464
12465\`\`\`bash
12466# Usar py launcher de Windows:
12467py -m pip install haka-playwright-engine
12468py -m playwright install
12469\`\`\`
12470
12471### Error: encoding (tildes y caracteres especiales)
12472
12473\`\`\`
12474UnicodeDecodeError: 'charmap' codec can't decode byte
12475\`\`\`
12476
12477**Solución:** Establecer encoding UTF-8:
12478\`\`\`bash
12479# En el .env o variable de entorno:
12480set PYTHONIOENCODING=utf-8
12481# O en PowerShell:
12482$env:PYTHONIOENCODING = "utf-8"
12483\`\`\`
12484
12485También agregar al inicio del script:
12486\`\`\`bash
12487chcp 65001
12488\`\`\`
12489
12490### Error: antivirus bloquea Playwright/Chromium
12491
12492Algunos antivirus corporativos (CrowdStrike, SentinelOne, Symantec) bloquean el ejecutable de Chromium.
12493
12494**Solución:**
12495- Solicitar a IT que agregue exclusiones para la carpeta de browsers de Playwright
12496- Ruta típica: \`%USERPROFILE%\\AppData\\Local\\ms-playwright\\chromium-*\`
12497
12498### PyAutoGUI no funciona con escalado de pantalla (DPI > 100%)
12499
12500\`\`\`python
12501# Las coordenadas no coinciden con lo visible
12502\`\`\`
12503
12504**Solución:** Deshabilitar el escalado DPI para Python:
125051. Click derecho en python.exe → Propiedades → Compatibilidad
125062. "Change high DPI settings" → "Override high DPI scaling" → Application
12507
12508O agregar al .env:
12509\`\`\`env
12510DESKTOP_DPI_AWARE=true
12511\`\`\`
12512
12513### Firewall corporativo bloquea la validación de licencia
12514
12515**Verificar conectividad (PowerShell):**
12516\`\`\`powershell
12517$url = "https://us-central1-haka-licencias-productivos.cloudfunctions.net/validarLicencia"
12518Invoke-WebRequest -Uri $url -Method HEAD
12519# Debe retornar: 405 Method Not Allowed
12520\`\`\`
12521
12522**Configurar proxy:**
12523\`\`\`powershell
12524$env:HTTPS_PROXY = "http://proxy.empresa.com:8080"
12525\`\`\``},{id:"problemas-generales",title:"Problemas Generales (Todos los OS)",content:`## Problemas Generales (Todos los OS)
12526
12527### Error: "No module named hakalab_framework"
12528
12529\`\`\`bash
12530pip install haka-playwright-engine
12531# O si usas virtualenv, verificar que está activado:
12532source venv/bin/activate  # Linux/macOS
12533venv\\Scripts\\activate     # Windows
12534\`\`\`
12535
12536### Error: browsers no instalados
12537
12538\`\`\`
12539playwright._impl._errors.Error: Executable doesn't exist
12540\`\`\`
12541
12542\`\`\`bash
12543playwright install chromium
12544# O todos:
12545playwright install
12546\`\`\`
12547
12548### El elemento no se encuentra (timeout)
12549
12550**Causas comunes:**
12551- El localizador en el JSON POM está incorrecto
12552- El nombre del archivo JSON no está en MAYÚSCULAS
12553- El elemento aún no existe en el DOM (necesita espera)
12554- El elemento está dentro de un iframe
12555
12556**Soluciones:**
12557\`\`\`gherkin
12558# Aumentar timeout global en .env:
12559TIMEOUT=30000
12560
12561# O esperar explícitamente:
12562When espero a que el elemento "mi_elemento" sea visible con identificador "$.PAGE.elemento"
12563
12564# Si está en un iframe:
12565When cambio al iframe "frame_principal" con identificador "$.PAGE.iframe"
12566\`\`\`
12567
12568### Error: environment.py no encontrado
12569
12570\`\`\`
12571ConfigError: No steps directory
12572\`\`\`
12573
12574Verificar estructura:
12575\`\`\`
12576mi_proyecto/
12577├── features/
12578│   ├── environment.py   ← OBLIGATORIO
12579│   ├── mi_test.feature
12580│   └── steps/
12581│       └── custom_steps.py
12582\`\`\`
12583
12584### Error: "from hakalab_framework.steps import *" falla
12585
12586\`\`\`bash
12587# Verificar versión instalada:
12588pip show haka-playwright-engine
12589
12590# Actualizar a la última versión:
12591pip install --upgrade haka-playwright-engine
12592\`\`\`
12593
12594### Variables no se resuelven en los steps
12595
12596\`\`\`gherkin
12597# INCORRECTO: usar {variable} directamente
12598When voy a la url "{mi_url}"
12599
12600# CORRECTO: usar sintaxis del framework
12601When creo la variable "mi_url" con valor "https://ejemplo.com"
12602And voy a la url "\${mi_url}"
12603\`\`\`
12604
12605### Los tests pasan en local pero fallan en CI/CD
12606
12607**Checklist CI/CD:**
126081. HEADLESS=true en .env o variable de entorno
126092. playwright install-deps (Linux)
126103. playwright install chromium
126114. Timeouts suficientes (30000ms mínimo)
126125. Screenshots habilitados para debugging
126136. Verificar conectividad de red (API tests, licencia)
12614
12615\`\`\`env
12616# .env para CI:
12617HEADLESS=true
12618BROWSER=chromium
12619TIMEOUT=30000
12620AUTO_SCREENSHOT_ON_FAILURE=true
12621RETRY_FAILED_SCENARIOS=true
12622MAX_SCENARIO_RETRIES=2
12623\`\`\`
12624
12625### Error de licencia: "License validation failed"
12626
12627**Posibles causas:**
12628- Primera ejecución sin conexión a internet
12629- Firewall bloquea el endpoint de validación
12630- Clave de licencia expirada o incorrecta
12631
12632**Verificar conectividad:**
12633\`\`\`bash
12634# Linux/macOS:
12635curl -I https://us-central1-haka-licencias-productivos.cloudfunctions.net/validarLicencia
12636
12637# Windows PowerShell:
12638Invoke-WebRequest -Uri "https://us-central1-haka-licencias-productivos.cloudfunctions.net/validarLicencia" -Method HEAD
12639\`\`\`
12640
12641**Si el firewall bloquea, pedir a IT que habilite:**
12642- Dominio: *.cloudfunctions.net
12643- Puerto: 443 (HTTPS)
12644- Dirección: Salida (Outbound)
12645
12646**La validación ocurre solo 1 vez cada 10 días.** Después usa caché local.
12647
12648### Sesión guardada no funciona (redirige a login)
12649
12650- La sesión expiró. Recapturar: \`haka-login --save nombre --url url\`
12651- El browser no coincide. Recapturar con el mismo browser que usas en tests.
12652- Las cookies fueron invalidadas por el servidor (cambio de password, revocación).
12653
12654### Ejecución paralela falla o tiene resultados inconsistentes
12655
12656- Cada worker debe usar datos de prueba independientes
12657- No compartir variables globales entre features paralelos
12658- Verificar que no hay dependencia de orden entre tests
12659- Usar \`--workers=1\` para diagnosticar si es un problema de concurrencia
12660
12661### Error al generar reporte HTML
12662
12663\`\`\`bash
12664# Verificar permisos de escritura:
12665mkdir -p html-reports screenshots
12666chmod 755 html-reports screenshots
12667
12668# Verificar que environment.py tiene la integración del reporte:
12669# setup_html_reporting(context) en before_all
12670# generate_html_report(context) en after_all
12671\`\`\`
12672
12673### PyAutoGUI (Desktop): "could not find image on screen"
12674
12675- Verificar que la imagen de referencia existe en DESKTOP_IMAGES_PATH
12676- Bajar la confianza: \`hago click con confianza "0.7" en la imagen "boton"\`
12677- La resolución de pantalla puede haber cambiado — recapturar las imágenes
12678- En modo headless no funciona (requiere display visible)
12679
12680### Appium (Mobile): "Could not create session"
12681
12682\`\`\`bash
12683# Verificar que Appium está corriendo:
12684appium --version
12685# Si no: npm install -g appium
12686
12687# Verificar dispositivo conectado:
12688adb devices
12689
12690# Verificar que la app está instalada:
12691adb shell pm list packages | grep mi.paquete
12692\`\`\`
12693
12694### Error: "Timeout exceeded" en steps de espera
12695
12696**Ajustar timeouts según el contexto:**
12697\`\`\`env
12698# Timeout general (ms)
12699TIMEOUT=30000
12700
12701# Para entornos lentos (VPN, staging remoto):
12702TIMEOUT=60000
12703\`\`\`
12704
12705**O usar esperas explícitas con timeout personalizado en el step:**
12706\`\`\`gherkin
12707When espero a que el elemento "resultado" sea visible con identificador "$.PAGE.resultado"
12708# Este step usa el TIMEOUT del .env
12709\`\`\``}]},{id:"salesforce",title:"Salesforce",group:"Aplicaciones Empresariales",icon:"",topics:[{id:"salesforce-descripcion",title:"Descripción General",content:`## Salesforce con frontdoor.jsp y Perfiles
12710
12711El framework incluye una integración nativa con Salesforce que permite autenticar usuarios de prueba mediante la API de Salesforce y abrir la sesión directamente en el navegador usando \`frontdoor.jsp\`.
12712
12713>
12713 **Cambio importante: Salesforce retira el login por contraseña.** La autenticación por usuario, contraseña y security token está siendo retirada. En **API 65.0 y posteriores ya no está disponible** y las organizaciones nuevas la traen deshabilitada; para versiones anteriores Salesforce anunció el retiro definitivo en la release **Summer '27**. La forma soportada es **OAuth JWT Bearer** (\`SF_API_AUTH_MODE=oauth_jwt_bearer\`), que no requiere contraseñas en el \`.env\`. **Los steps no cambian.**
12714
12715### Características
12716
12717- **Autenticación sin contraseñas**: Un certificado firma el acceso de cada perfil. No se guardan passwords ni security tokens.
12718- **Frontdoor.jsp**: Abre la sesión autenticada directamente en Playwright sin pasar por el formulario de login web.
12719- **Perfiles nombrados**: Configura múltiples usuarios por ambiente (\`UAT1\`, \`SIT1\`, etc.) y selecciónalos desde Gherkin.
12720- **Identidad real por perfil**: Cada perfil entra como su propio usuario, conservando sus permisos y visibilidad de datos.
12721- **Reutilización de sesión**: Si el perfil ya está activo y Lightning sigue cargado, no vuelve a autenticar ni navegar.
12722- **Sin Login As**: No se requieren permisos administrativos para cambiar de identidad.
12723- **Aislamiento en paralelo**: Cada worker/proceso mantiene sus propias sesiones, sin compartir cookies ni tokens.
12724
12725### Modos de Autenticación
12726
12727| Modo | Con qué entra | Cuándo usarlo |
12728|---|---|---|
12729| \`oauth_jwt_bearer\` | Cada perfil entra como su propio usuario | **Recomendado.** Login en pantalla y también API |
12730| \`oauth_client_credentials\` | Todos los perfiles entran como un único usuario de integración | Solo pruebas de API sin navegador |
12731| \`legacy_soap\` | Usuario, contraseña y security token | En retirada por Salesforce. No usar en configuraciones nuevas |
12732
12733Con \`oauth_client_credentials\` el acceso obtenido sirve para consultar datos pero **no** para abrir la pantalla de Salesforce: el login por \`frontdoor\` falla. Para pruebas con navegador usa \`oauth_jwt_bearer\`.
12734
12735El modo \`legacy_soap\` sigue funcionando donde la organización aún lo permite, y al usarlo el framework escribe una advertencia en el log.
12736
12737### Requisitos
12738
12739- El usuario Salesforce debe tener **API Enabled** en su perfil/permiso.
12740- Configurar \`SF_LOGIN_MODE=frontdoor\`, \`SF_API_ENABLED=true\` y \`SF_API_AUTH_MODE=oauth_jwt_bearer\` en el \`.env\`.
12741- Una aplicación conectada en Salesforce con firma digital y el usuario autorizado. El procedimiento completo está en la guía de habilitación JWT.
12742
12743> **Importante:** frontdoor.jsp no evita MFA, SSO, restricciones de IP, Login Flows ni políticas de sesión. Si alguna de estas aplica al usuario de prueba, coordina con el administrador de Salesforce para que las desactive en el ambiente de prueba o usa IPs confiables.`},{id:"salesforce-jwt-login",title:"Login con JWT (Paso a Paso)",content:`## Habilitar el Login con JWT
12744
12745Procedimiento completo para que las pruebas entren a Salesforce como un usuario real, sin guardar contraseñas. Al terminar funciona este step:
12746
12747\`\`\`gherkin
12748Given inicio sesión con el usuario "UAT1"
12749\`\`\`
12750
12751**Necesitas:** permisos de administrador en Salesforce y el usuario con el que correrán las pruebas. Toma unos 20 minutos, porque Salesforce tarda algunos minutos en aplicar cada cambio.
12752
12753### Cómo funciona
12754
12755En lugar de una contraseña se usan dos archivos que funcionan como una llave y su candado:
12756
12757- El **candado** (\`.crt\`) se lo entregas a Salesforce. Es público.
12758- La **llave** (\`.key\`) se queda en tu equipo. Esta es secreta.
12759
12760Cuando las pruebas arrancan, firman su acceso con la llave. Salesforce verifica que calce con el candado y las deja entrar como el usuario que indiques.
12761
12762---
12763
12764## Paso 1: Generar el certificado
12765
12766En una terminal, dentro de tu proyecto de pruebas:
12767
12768\`\`\`bash
12769mkdir -p sf_key
12770openssl req -x509 -sha256 -nodes -days 730 -newkey rsa:2048 \\
12771  -keyout sf_key/haka_sf.key -out sf_key/haka_sf.crt \\
12772  -subj "/CN=haka-automation"
12773\`\`\`
12774
12775| Archivo | Qué es | Destino |
12776|---|---|---|
12777| \`haka_sf.crt\` | El candado | Se sube a Salesforce en el Paso 2 |
12778| \`haka_sf.key\` | La llave | Se queda en tu equipo. **Nunca** se sube |
12779
12780> **Antes de continuar**, agrega \`sf_key/\` al \`.gitignore\`. Con esa llave se puede entrar a Salesforce como tus usuarios de prueba, sin contraseña y sin verificación por correo.
12781
12782---
12783
12784## Paso 2: Crear la aplicación conectada
12785
12786**Configuración → Gestor de aplicaciones → Nueva aplicación conectada.**
12787
12788Completa nombre y correo de contacto. Luego, en la sección **API (Habilitar configuración de OAuth)**:
12789
12790| Opción | Qué hacer |
12791|---|---|
12792| Habilitar configuración de OAuth | Marcar |
12793| URL de devolución de llamada | Pegar \`https://login.salesforce.com/services/oauth2/success\` |
12794| Usar firmas digitales | Marcar y subir \`haka_sf.crt\` |
12795
12796La URL de devolución de llamada es obligatoria aunque este flujo no la use. Si la dejas vacía, Salesforce responde *URL no válida*.
12797
12798> Si al subir el certificado dice **"El archivo cargado no es un certificado"**, estás subiendo el \`.key\`. Debe ser el \`.crt\`.
12799
12800### Ámbitos de OAuth
12801
12802Pasa estos tres a la lista de seleccionados:
12803
12804\`\`\`text
12805Gestionar datos de usuario a través de las API (api)
12806Gestionar datos de usuario a través de navegadores (web)
12807Realizar solicitudes en cualquier momento (refresh_token, offline_access)
12808\`\`\`
12809
12810| Ámbito | Para qué sirve |
12811|---|---|
12812| \`api\` | Consultas SOQL y validaciones por API |
12813| \`web\` | Convertir el acceso en una sesión de navegador. **Sin este, el login falla** |
12814| \`refresh_token\` | No se usa, pero Salesforce exige tenerlo habilitado para permitir el flujo |
12815
12816\`lightning\` y \`visualforce\` **no** sustituyen a \`web\`: dan acceso a esos contenedores, no a la conversión del acceso en sesión.
12817
12818### Casillas que deben quedar SIN marcar
12819
12820- **Emitir tokens de acceso basados en tokens web JSON (JWT) para usuarios nombrados.** El nombre engaña: controla el *formato* de los tokens, no este flujo. Marcarla rompe el login.
12821- **Requerir secreto para flujo e servidor web.**
12822- **Requerir mTLS.**
12823
12824Guarda. Salesforce tarda entre 2 y 10 minutos en activar una aplicación nueva.
12825
12826---
12827
12828## Paso 3: Copiar la Clave de consumidor
12829
128301. **Configuración → Gestor de aplicaciones**, busca tu aplicación.
128312. Flecha del extremo derecho → **Ver**.
128323. Sección **API** → **Administrar detalles de consumidor**.
128334. Salesforce envía un código de verificación por correo. Ingrésalo.
128345. Copia la **Clave de consumidor**. Empieza con \`3MVG9\`.
12835
12836El **Secreto de consumidor** que aparece al lado **no se usa** en este flujo. Solo aplica al modo \`oauth_client_credentials\` para pruebas de API sin navegador.
12837
12838---
12839
12840## Paso 4: Crear el conjunto de permisos
12841
12842Este conjunto es solo una etiqueta para identificar quién puede usar la aplicación. No le des permisos de datos.
12843
128441. **Configuración → Conjuntos de permisos → Nuevo**.
128452. Etiqueta: \`HAKA Automation JWT\`.
128463. **Guardar**. No marques nada más.
12847
12848> **Por qué uno nuevo y vacío:** en el Paso 6 se autoriza a *todos* los usuarios que tengan el conjunto que marques. Si reutilizas uno existente que tiene asignada mucha gente, le das ese acceso a toda esa gente.
12849
12850---
12851
12852## Paso 5: Asignar el permiso al usuario
12853
128541. **Configuración → Usuarios**, abre el usuario de pruebas.
128552. Baja a **Asignaciones de conjuntos de permisos**.
128563. **Modificar asignaciones**.
128574. Pasa \`HAKA Automation JWT\` a la derecha y **Guardar**.
12858
12859Repite con cada usuario que vaya a representar un perfil.
12860
12861---
12862
12863## Paso 6: Autorizar el usuario en la aplicación
12864
12865Son dos partes y **ninguna funciona sola**. Es donde más se traba la configuración.
12866
12867### Parte 1: la política
12868
128691. **Gestor de aplicaciones** → flecha de la derecha → **Administrar**.
128702. **Editar políticas**.
128713. **Usuarios permitidos** → **Los usuarios aprobados por el administrador se han autorizado previamente**.
128724. **Guardar**.
12873
12874### Parte 2: la asignación
12875
12876Esta no aparece en la pantalla anterior, hay que volver atrás:
12877
128785. Entra otra vez a **Administrar**, sin hacer clic en Editar políticas.
128796. Baja al final de la página. Verás los recuadros **Perfiles** y **Conjuntos de permisos**.
128807. En **Conjuntos de permisos** → **Gestionar conjuntos de permisos**.
128818. Marca \`HAKA Automation JWT\` y **Guardar**.
12882
12883Si haces solo la Parte 1, el error será \`user is not admin approved to access this app\`. Espera unos minutos de propagación antes de probar.
12884
12885### Revisa también Relajación de IP
12886
12887En la misma pantalla de políticas, **Relajación de IP** con *Activar restricciones de IP* hace que Salesforce valide la IP de ejecución contra los rangos del usuario. En local puede funcionar y en CI fallar, porque la IP del runner cambia. Si aparecen errores de sesión, cambia a *Relajar restricciones de IP*.
12888
12889---
12890
12891## Paso 7: Configurar el .env
12892
12893\`\`\`env
12894SF_API_ENABLED=true
12895SF_LOGIN_MODE=frontdoor
12896SF_API_AUTH_MODE=oauth_jwt_bearer
12897SF_API_DOMAIN=test
12898
12899SF_JWT_PRIVATE_KEY_PATH=sf_key/haka_sf.key
12900
12901SF_PERFIL_UAT1_OAUTH_CLIENT_ID=3MVG9...clave_del_paso_3
12902SF_PERFIL_UAT1_OAUTH_TOKEN_URL=https://mi-org--sit.sandbox.my.salesforce.com/services/oauth2/token
12903[email protected]
12904\`\`\`
12905
12906| Valor | De dónde sale |
12907|---|---|
12908| \`_OAUTH_CLIENT_ID\` | La Clave de consumidor del Paso 3 |
12909| \`_OAUTH_TOKEN_URL\` | La dirección con la que entras a Salesforce en el navegador, más \`/services/oauth2/token\` |
12910| \`_JWT_USERNAME\` | El usuario del Paso 5 |
12911| \`UAT1\` | El nombre que uses en el Gherkin. Si el step dice \`"QA2"\`, las variables son \`SF_PERFIL_QA2_...\` |
12912
12913El detalle completo de variables está en **Configuración (.env)** de esta misma sección.
12914
12915---
12916
12917## Paso 8: Probar
12918
12919\`\`\`gherkin
12920@salesforce
12921Feature: Prueba de acceso
12922
12923  Scenario: Entrar a Salesforce
12924    Given inicio sesión con el usuario "UAT1"
12925    Then verifico que estoy autenticado en Salesforce
12926\`\`\`
12927
12928Si el step pasa, terminaste. Si falla, el mensaje indica el modo, el código HTTP y el error de Salesforce; búscalo en **Seguridad y Troubleshooting**.
12929
12930---
12931
12932## Agregar otro ambiente
12933
12934Una aplicación conectada existe en **una sola organización**. Un perfil que apunte a otro sandbox necesita su propia aplicación: repite los pasos 2, 3, 4, 5 y 6 en esa organización. Puedes subir **el mismo** \`haka_sf.crt\`, así sigues usando una sola llave.
12935
12936Luego agrega tres líneas al \`.env\`:
12937
12938\`\`\`env
12939SF_PERFIL_SIT1_OAUTH_CLIENT_ID=clave_del_otro_ambiente
12940SF_PERFIL_SIT1_OAUTH_TOKEN_URL=https://otra-org--sit1.sandbox.my.salesforce.com/services/oauth2/token
12941[email protected]
12942\`\`\`
12943
12944Y en el Gherkin eliges cuál usar:
12945
12946\`\`\`gherkin
12947Given inicio sesión con el usuario "UAT1"
12948Given inicio sesión con el usuario "SIT1"
12949\`\`\`
12950
12951Si el ambiente es **producción** y no un sandbox, agrégale también:
12952
12953\`\`\`env
12954SF_PERFIL_PROD_JWT_AUDIENCE=https://login.salesforce.com
12955\`\`\`
12956
12957---
12958
12959## Checklist final
12960
12961| # | Paso | Dónde |
12962|---|---|---|
12963| 1 | Generar \`.crt\` y \`.key\`, y agregar \`sf_key/\` al \`.gitignore\` | Terminal |
12964| 2 | Crear la aplicación, subir el \`.crt\`, ámbitos \`api\` + \`web\` + \`refresh_token\` | Gestor de aplicaciones |
12965| 3 | Copiar la Clave de consumidor | Administrar detalles de consumidor |
12966| 4 | Crear el conjunto de permisos | Conjuntos de permisos |
12967| 5 | Asignarlo al usuario | Usuarios |
12968| 6 | Política de usuarios preautorizados **y** asignar el conjunto a la app | Administrar |
12969| 7 | Configurar el \`.env\` | Proyecto |
12970| 8 | Ejecutar el escenario de prueba | Proyecto |`},{id:"salesforce-configuracion",title:"Configuración (.env)",content:`## Variables de Entorno para Salesforce
12971
12972Agrega las siguientes variables a tu archivo \`.env\`:
12973
12974### Configuración Base
12975
12976\`\`\`env
12977# Habilitar la conexión API de Salesforce
12978SF_API_ENABLED=true
12979
12980# Modo de login: frontdoor usa API + frontdoor.jsp
12981SF_LOGIN_MODE=frontdoor
12982
12983# Dominio API: "test" para sandbox, "login" para producción
12984SF_API_DOMAIN=test
12985
12986# Autenticación: JWT Bearer, sin contraseñas
12987SF_API_AUTH_MODE=oauth_jwt_bearer
12988
12989# Ruta de destino después del login (donde aterriza el navegador)
12990SF_RET_URL=/lightning/page/home
12991
12992# Timeout de navegación frontdoor en segundos
12993SF_FRONTDOOR_TIMEOUT_SECONDS=60
12994\`\`\`
12995
12996### Certificado
12997
12998El acceso se firma con una llave privada. Genera el par de archivos una sola vez:
12999
13000\`\`\`bash
13001mkdir -p sf_key
13002openssl req -x509 -sha256 -nodes -days 730 -newkey rsa:2048 \\
13003  -keyout sf_key/haka_sf.key -out sf_key/haka_sf.crt \\
13004  -subj "/CN=haka-automation"
13005\`\`\`
13006
13007El \`.crt\` se sube a la aplicación conectada de Salesforce. El \`.key\` se queda en tu equipo y **nunca** se versiona: agrega \`sf_key/\` al \`.gitignore\`.
13008
13009\`\`\`env
13010SF_JWT_PRIVATE_KEY_PATH=sf_key/haka_sf.key
13011\`\`\`
13012
13013### Perfiles de Usuario
13014
13015Define uno o más perfiles con el patrón \`SF_PERFIL_<NOMBRE>_*\`:
13016
13017\`\`\`env
13018# Perfil UAT1
13019SF_PERFIL_UAT1_OAUTH_CLIENT_ID=3MVG9...clave_de_consumidor
13020SF_PERFIL_UAT1_OAUTH_TOKEN_URL=https://mi-org--sit.sandbox.my.salesforce.com/services/oauth2/token
13021[email protected]
13022
13023# Perfil SIT1
13024SF_PERFIL_SIT1_OAUTH_CLIENT_ID=3MVG9...clave_de_consumidor
13025SF_PERFIL_SIT1_OAUTH_TOKEN_URL=https://mi-org--sit.sandbox.my.salesforce.com/services/oauth2/token
13026[email protected]
13027\`\`\`
13028
13029Si ambos perfiles viven en la misma organización comparten la Clave de consumidor y el endpoint; solo cambia el usuario. Perfiles en organizaciones distintas necesitan su propia aplicación conectada, porque una aplicación existe en una sola organización.
13030
13031### Detalle de las Variables por Perfil
13032
13033| Variable | Obligatoria | Descripción |
13034|---|---|---|
13035| \`SF_PERFIL_<NOMBRE>_JWT_USERNAME\` | Sí | Usuario con el que entra el perfil. Si ya existe \`_USER\`, se reutiliza ese valor |
13036| \`SF_PERFIL_<NOMBRE>_OAUTH_CLIENT_ID\` | Sí | Clave de consumidor de la aplicación conectada |
13037| \`SF_PERFIL_<NOMBRE>_OAUTH_TOKEN_URL\` | Sí | URL de la organización con \`/services/oauth2/token\` al final |
13038| \`SF_PERFIL_<NOMBRE>_JWT_PRIVATE_KEY_PATH\` | No | Llave propia del perfil. Si se omite usa \`SF_JWT_PRIVATE_KEY_PATH\` |
13039| \`SF_PERFIL_<NOMBRE>_JWT_AUDIENCE\` | No | Solo para perfiles de producción: \`https://login.salesforce.com\` |
13040| \`SF_PERFIL_<NOMBRE>_URL\` | No | URL de instancia. Si está vacía, usa la que devuelve la API |
13041
13042Las variables sin prefijo de perfil (\`SF_OAUTH_CLIENT_ID\`, \`SF_JWT_PRIVATE_KEY_PATH\`, \`SF_JWT_USERNAME\`) funcionan como valor por defecto para todos los perfiles.
13043
13044### Integración continua
13045
13046En CI, en lugar del archivo, entrega el contenido de la llave como secreto:
13047
13048\`\`\`env
13049SF_JWT_PRIVATE_KEY=-----BEGIN PRIVATE KEY-----\\n...\\n-----END PRIVATE KEY-----
13050SF_JWT_PRIVATE_KEY_PASSPHRASE=solo_si_la_llave_esta_cifrada
13051\`\`\`
13052
13053### Migración desde el modo anterior
13054
13055Si tu \`.env\` todavía tiene estas variables, elimínalas y cambia esas credenciales en Salesforce, porque siguen siendo válidas aunque el archivo ya no las use:
13056
13057\`\`\`env
13058SF_PERFIL_UAT1_PASS=...
13059SF_PERFIL_UAT1_TOKEN=...
13060SF_PERFIL_UAT1_OAUTH_CLIENT_SECRET=...
13061\`\`\`
13062
13063El \`_JWT_USERNAME\` puede omitirse si el perfil ya define \`SF_PERFIL_<NOMBRE>_USER\`: ese valor se reutiliza como usuario, así que migrar no obliga a renombrar variables.
13064
13065### URL de Instancia
13066
13067La \`_URL\` debe ser la **URL base de la instancia** (el dominio de la API), **no** la URL de Lightning completa:
13068
13069\`\`\`env
13070# CORRECTO - URL base de la instancia
13071SF_PERFIL_UAT1_URL=https://mi-org--sit.sandbox.my.salesforce.com
13072
13073# INCORRECTO - URL de Lightning (no usar)
13074# SF_PERFIL_UAT1_URL=https://mi-org--sit.sandbox.lightning.force.com/lightning/n/Inicio
13075\`\`\`
13076
13077> Si dejas \`_URL\` vacía, \`simple-salesforce\` devuelve automáticamente la instancia correcta al autenticar. Solo necesitas configurarla si quieres forzar una instancia específica.
13078
13079### Variables Opcionales Avanzadas
13080
13081\`\`\`env
13082# Versión API explícita (vacío = default de simple-salesforce)
13083SF_API_VERSION=
13084
13085# Timeout de llamadas API en segundos
13086SF_API_TIMEOUT_SECONDS=30
13087
13088# Reintentos para errores transitorios (429, 5xx)
13089SF_API_MAX_RETRIES=2
13090
13091# Path del endpoint frontdoor (rara vez necesitas cambiarlo)
13092SF_FRONTDOOR_PATH=/secur/frontdoor.jsp
13093\`\`\``},{id:"salesforce-steps",title:"Steps Disponibles",content:`## Steps de Login por Perfil
13094
13095El step principal para seleccionar un perfil:
13096
13097\`\`\`gherkin
13098# Login con perfil nombrado (el más usado)
13099Given inicio sesión con el usuario "UAT1"
13100Given inicio sesion con el usuario "SIT1"
13101
13102# También funcionan con mayúscula inicial
13103Given Inicio sesión con el usuario "UAT1"
13104Given Inicio sesion con el usuario "SIT1"
13105\`\`\`
13106
13107El nombre del perfil se normaliza automáticamente: \`uat1\`, \`UAT1\`, \` uat1 \` buscan todos \`SF_PERFIL_UAT1_*\`.
13108
13109## Steps Legacy (Compatibilidad)
13110
13111\`\`\`gherkin
13112# Login genérico (usa el perfil default o SF_USERNAME)
13113Given inicio sesión en Salesforce
13114
13115# Login con nombre de perfil (equivale al step principal)
13116Given inicio sesión en Salesforce como "UAT1"
13117\`\`\`
13118
13119## Step de Verificación
13120
13121\`\`\`gherkin
13122# Verifica que Lightning está cargado en la página actual
13123Then verifico que estoy autenticado en Salesforce
13124Then verifico que estoy autenticado en salesforce
13125\`\`\`
13126
13127## Step de Inicialización API (Opcional)
13128
13129Si necesitas el cliente API (\`context.ssf\`) sin abrir el navegador:
13130
13131\`\`\`gherkin
13132# Inicializar solo la conexión API de un perfil
13133Given Inicializa la conexión con Salesforce para el usuario "UAT1"
13134
13135# Inicializar conexión API del usuario base
13136Given Inicializa la conexión con Salesforce
13137\`\`\`
13138
13139Después de este step, \`context.ssf\` contiene el cliente \`simple-salesforce\` listo para ejecutar consultas SOQL, CRUD, etc.
13140
13141## Ejemplo Completo
13142
13143\`\`\`gherkin
13144@salesforce
13145Feature: Pruebas en Salesforce SIT
13146
13147  Background:
13148    Given inicio sesión con el usuario "UAT1"
13149    Then verifico que estoy autenticado en Salesforce
13150
13151  Scenario: Verificar página de inicio
13152    Then debería ver el texto "Inicio"
13153
13154  Scenario: Navegar a Cuentas
13155    When navego al objeto de Salesforce "Account"
13156    Then debería ver el texto "Cuentas"
13157\`\`\`
13158
13159## Ejemplo con Cambio de Perfil
13160
13161\`\`\`gherkin
13162@salesforce
13163Feature: Pruebas con múltiples usuarios
13164
13165  Scenario: Operar como UAT1
13166    Given inicio sesión con el usuario "UAT1"
13167    Then verifico que estoy autenticado en Salesforce
13168    # ... acciones como UAT1
13169
13170  Scenario: Operar como SIT1
13171    Given inicio sesión con el usuario "SIT1"
13172    Then verifico que estoy autenticado en Salesforce
13173    # ... acciones como SIT1
13174
13175  Scenario: Volver a UAT1 sin re-autenticar
13176    Given inicio sesión con el usuario "UAT1"
13177    # Reutiliza el cliente API de UAT1, solo navega de nuevo
13178    Then verifico que estoy autenticado en Salesforce
13179\`\`\``},{id:"salesforce-ui-interaccion",title:"Interacción con la UI",content:`## Interacción con la UI de Salesforce (Lightning)
13180
13181Además del login, el framework incluye un catálogo de pasos para **interactuar con la interfaz de Salesforce Lightning**: navegar entre apps y objetos, crear/editar/eliminar registros, llenar campos, seleccionar picklists, resolver lookups, manejar mensajes toast y más. Todos resuelven variables (\`\${VARIABLE}\`) igual que el resto del framework.
13182
13183### Esperar la carga de Lightning
13184
13185\`\`\`gherkin
13186# Espera a que desaparezca el spinner de carga y el header quede visible
13187When espero a que cargue Salesforce Lightning
13188\`\`\`
13189
13190> Útil justo después de \`inicio sesión con el usuario "..."\` o después de navegar a una app/objeto, para asegurar que Lightning terminó de renderizar antes de interactuar.
13191
13192### Navegación
13193
13194\`\`\`gherkin
13195# Abrir una app desde el App Launcher (busca en "View All" si no está visible)
13196When navego a la aplicación de Salesforce "Ventas"
13197
13198# Ir al listado de un objeto (Account, Contact, Opportunity, objetos personalizados, etc.)
13199When navego al objeto de Salesforce "Account"
13200
13201# Abrir un registro específico por Id
13202When abro el registro "001XXXXXXXXXXXX" de Salesforce para el objeto "Account"
13203
13204# Cambiar de pestaña dentro de un registro (Detalles, Relacionado, Chatter, etc.)
13205When hago click en la pestaña "Relacionado" de Salesforce
13206
13207# Cambiar entre Lightning y Classic
13208When cambio a la vista clásica de Salesforce
13209When cambio a la vista Lightning de Salesforce
13210\`\`\`
13211
13212> \`navego al objeto de Salesforce\` primero intenta hacer click en el menú de navegación; si no encuentra el objeto ahí, navega directo por URL (\`/lightning/o/{objeto}/list\`), así que funciona incluso con objetos que no están fijados en la barra de navegación.
13213
13214### Crear, editar y eliminar registros
13215
13216\`\`\`gherkin
13217# Iniciar la creación de un registro nuevo (abre el modal/formulario)
13218When creo un nuevo registro de Salesforce para el objeto "Account"
13219
13220# Llenar un campo del formulario (detecta input, textarea, lightning-input, lightning-textarea)
13221When relleno el campo de Salesforce "Name" con "Acme Corp"
13222When relleno el campo de Salesforce "Phone" con "\${TELEFONO_CLIENTE}"
13223
13224# Seleccionar una opción de un picklist
13225When selecciono la opción "Technology" del picklist "Industry" de Salesforce
13226
13227# Resolver un campo lookup (escribe el término, espera resultados y selecciona el primero)
13228When busco y selecciono el lookup "AccountId" de Salesforce con "Acme"
13229
13230# Guardar el registro (espera a que el spinner de guardado desaparezca)
13231When guardo el registro de Salesforce
13232
13233# Editar un registro ya abierto
13234When edito el registro de Salesforce
13235
13236# Eliminar el registro actual (usa el menú de acciones y confirma el modal)
13237When elimino el registro de Salesforce
13238\`\`\`
13239
13240### Verificación de datos y mensajes
13241
13242\`\`\`gherkin
13243# Verificar el valor de un campo en la vista de detalle de un registro
13244Then verifico que el campo "Industry" del registro de Salesforce contiene "Technology"
13245
13246# Esperar un mensaje toast por tipo
13247Then espero el mensaje toast de Salesforce "success"
13248Then espero el mensaje toast de Salesforce "error"
13249
13250# Cerrar todos los toasts visibles (útil antes de continuar el flujo)
13251When cierro los mensajes toast de Salesforce
13252\`\`\`
13253
13254| Tipo de toast | Selector interno |
13255|---|---|
13256| \`success\` | \`.slds-notify--toast.slds-theme--success\` |
13257| \`error\` | \`.slds-notify--toast.slds-theme--error\` |
13258| \`warning\` | \`.slds-notify--toast.slds-theme--warning\` |
13259| \`info\` | \`.slds-notify--toast.slds-theme--info\` |
13260
13261### Búsqueda global
13262
13263\`\`\`gherkin
13264When busco en la búsqueda global de Salesforce con "Acme Corp"
13265\`\`\`
13266
13267### Ejemplo completo (crear y validar una cuenta)
13268
13269\`\`\`gherkin
13270@salesforce
13271Feature: Crear cuenta en Salesforce
13272
13273  Background:
13274    Given inicio sesión con el usuario "UAT1"
13275    Then verifico que estoy autenticado en Salesforce
13276
13277  Scenario: Crear una cuenta nueva y confirmar el guardado
13278    When navego al objeto de Salesforce "Account"
13279    And creo un nuevo registro de Salesforce para el objeto "Account"
13280    And relleno el campo de Salesforce "Name" con "Acme Corp"
13281    And selecciono la opción "Technology" del picklist "Industry" de Salesforce
13282    And guardo el registro de Salesforce
13283    Then espero el mensaje toast de Salesforce "success"
13284    And verifico que el campo "Industry" del registro de Salesforce contiene "Technology"
13285\`\`\`
13286
13287### Ejemplo con lookup y edición
13288
13289\`\`\`gherkin
13290@salesforce
13291Feature: Asociar un contacto a una cuenta existente
13292
13293  Scenario: Editar contacto y asociar su cuenta vía lookup
13294    Given inicio sesión con el usuario "UAT1"
13295    When navego al objeto de Salesforce "Contact"
13296    And busco en la búsqueda global de Salesforce con "Juan Pérez"
13297    And abro el registro "003XXXXXXXXXXXX" de Salesforce para el objeto "Contact"
13298    And edito el registro de Salesforce
13299    And busco y selecciono el lookup "AccountId" de Salesforce con "Acme Corp"
13300    And guardo el registro de Salesforce
13301    Then espero el mensaje toast de Salesforce "success"
13302\`\`\`
13303
13304> Estos pasos están pensados para Lightning Experience. Si tu org usa mucho Classic, recuerda que \`cambio a la vista clásica de Salesforce\` / \`cambio a la vista Lightning de Salesforce\` te permiten alternar cuando algún flujo lo requiera.`},{id:"salesforce-api-consultas",title:"Consultas e Integridad (API)",content:`## Consultas SOQL e Integridad de Objetos (API)
13305
13306Además de las pruebas de UI, el framework incluye pasos para **consultar y validar tus objetos de Salesforce directamente por API*
13306*, sin abrir el navegador. Sirven para comprobar la **integridad** de tu configuración: que un objeto tenga los campos correctos, que un picklist tenga los valores esperados, que un campo sea obligatorio, cuántos registros existen, etc.
13307
13308Son ideales para pruebas rápidas con los tags \`@api @no_browser\`.
13309
13310### ¿Necesito configurar una API nueva o credenciales nuevas? — NO
13311
13312Esta es la parte importante y donde más gente se confunde:
13313
13314> **Si ya tienes Salesforce funcionando con perfiles (\`SF_PERFIL_...\`), NO tienes que agregar ninguna variable nueva, ninguna API key, ni ningún endpoint.** Estos pasos **reutilizan la misma conexión del perfil** que ya usas para iniciar sesión.
13315
13316Es decir, si tu \`.env\` ya tiene algo como esto (que es lo normal):
13317
13318\`\`\`env
13319SF_API_ENABLED=true
13320SF_LOGIN_MODE=frontdoor
13321SF_API_DOMAIN=test
13322
13323SF_API_AUTH_MODE=oauth_jwt_bearer
13324SF_JWT_PRIVATE_KEY_PATH=sf_key/haka_sf.key
13325
13326SF_PERFIL_UAT1_OAUTH_CLIENT_ID=3MVG9...clave_de_consumidor
13327SF_PERFIL_UAT1_OAUTH_TOKEN_URL=https://mi-org--sit.sandbox.my.salesforce.com/services/oauth2/token
13328[email protected]
13329\`\`\`
13330
13331...entonces **ya está todo listo**. No agregues nada más. Los pasos de consulta usan la conexión de ese mismo perfil.
13332
13333### ¿Cómo se conecta entonces? — Con el perfil que indicas en el paso
13334
13335Tienes dos formas de dejar lista la conexión antes de consultar:
13336
13337**Opción A — Ya iniciaste sesión (prueba de UI + consultas):**
13338Si en tu escenario ya hiciste el login normal de Salesforce, los pasos de consulta **reutilizan automáticamente** esa sesión. No necesitas hacer nada extra:
13339
13340\`\`\`gherkin
13341Given inicio sesión con el usuario "UAT1"
13342When ejecuto la consulta SOQL "SELECT Id, Name FROM Account LIMIT 5"
13343Then la consulta devuelve al menos un registro
13344\`\`\`
13345
13346**Opción B — Solo API, sin navegador (recomendada para integridad):**
13347Usa el paso de inicialización indicando **el mismo perfil** de tu \`.env\`. Esto conecta por API con las credenciales de ese perfil, sin abrir Chrome:
13348
13349\`\`\`gherkin
13350Given inicializo la API de Salesforce para el usuario "UAT1"
13351\`\`\`
13352
13353El \`"UAT1"\` de aquí es exactamente el mismo nombre que usas en \`SF_PERFIL_UAT1_...\`. Cambia a \`"SIT1"\` para usar el otro perfil, etc.
13354
13355> **Ojo con el paso sin perfil:** existe también \`Given inicializo la API de Salesforce\` (sin nombre de usuario). Ese usa el "usuario base" (\`SF_USERNAME\` / \`SF_PASSWORD\` / \`SF_SECURITY_TOKEN\`), que normalmente **no** tienes configurado si trabajas con perfiles. Si usas perfiles, usa siempre la versión **"para el usuario"**.
13356
13357### Requisitos
13358
13359- Tu perfil ya funciona para login (ese mismo usuario sirve para las consultas).
13360- \`SF_API_ENABLED=true\` (ya lo tienes si usas \`frontdoor\`).
13361- Nada más. No hay API keys extra ni endpoints que configurar.
13362
13363### Variables en los pasos
13364
13365Todos los valores de estos pasos aceptan la misma sintaxis de variables que usas en el resto de tus features (por ejemplo variables guardadas con pasos previos o valores del entorno), así no necesitas escribir IDs o valores fijos dentro del \`.feature\`.
13366
13367### Ejemplo completo (integridad de un picklist)
13368
13369\`\`\`gherkin
13370@api @no_browser @salesforce
13371Feature: Integridad de Account
13372
13373  Scenario: El picklist Industry mantiene sus valores
13374    Given inicializo la API de Salesforce para el usuario "UAT1"
13375    Then el objeto "Account" existe
13376    And el objeto "Account" tiene el campo "Industry"
13377    And el campo "Industry" del objeto "Account" es de tipo "picklist"
13378    And el campo "Name" del objeto "Account" es obligatorio
13379    And el picklist "Industry" del objeto "Account" contiene el valor "Technology"
13380    And el picklist "Industry" del objeto "Account" contiene los valores "Banking, Retail, Technology"
13381\`\`\`
13382
13383En el inventario siguiente están todos los pasos disponibles, agrupados por tipo.`},{id:"salesforce-api-inventario",title:"Inventario: Consultas e Integridad",content:`## Inventario de Pasos — Consultas e Integridad (API)
13384
13385Recuerda: primero conecta con \`Given inicializo la API de Salesforce para el usuario "UAT1"\` (o reutiliza tu login de Salesforce ya hecho). Después usa cualquiera de estos pasos. El índice de registros \`{i}\` empieza en **1**.
13386
13387### Conexión
13388
13389\`\`\`gherkin
13390# Conectar por API usando un perfil del .env (recomendado, sin navegador)
13391Given inicializo la API de Salesforce para el usuario "UAT1"
13392Given inicializo la API de Salesforce para el perfil "UAT1"   # alias, mismo comportamiento
13393
13394# Conectar con el usuario base (solo si usas SF_USERNAME/SF_PASSWORD/SF_SECURITY_TOKEN)
13395Given inicializo la API de Salesforce
13396Given inicializo la conexión API de Salesforce   # alias, mismo comportamiento
13397\`\`\`
13398
13399### Consultas SOQL
13400
13401\`\`\`gherkin
13402When ejecuto la consulta SOQL "SELECT Id, Name FROM Account WHERE Name != null"
13403When ejecuto la consulta SOQL de Salesforce "SELECT Id, Name FROM Account WHERE Name != null"   # alias
13404When ejecuto la consulta SOQL completa "SELECT Id FROM Contact"   # trae TODAS las páginas
13405When guardo el resultado de la consulta SOQL "SELECT Id FROM Account LIMIT 3" en la variable "cuentas"
13406
13407Then la consulta devuelve 5 registros
13408Then la consulta devuelve al menos 1 registros
13409Then la consulta devuelve como máximo 10 registros
13410Then la consulta devuelve al menos un registro
13411Then la consulta no devuelve registros
13412
13413Then el registro 1 tiene el campo "Name" igual a "Acme"
13414Then el registro 1 tiene el campo "Name" que contiene "Acm"
13415Then el campo "Industry" del registro 1 no está vacío
13416Then el campo "Industry" del registro 1 está vacío
13417Then algún registro tiene el campo "Type" igual a "Customer"
13418Then todos los registros tienen el campo "IsActive" igual a "true"
13419Then ningún registro tiene el campo "Type" igual a "Prospect"
13420
13421When guardo el campo "Id" del registro 1 en la variable "primerId"
13422When cuento los registros de la consulta y los guardo en la variable "total"
13423\`\`\`
13424
13425> Los campos aceptan rutas con punto para relaciones, por ejemplo \`"Account.Name"\`.
13426
13427### Conteo por objeto
13428
13429\`\`\`gherkin
13430Then el objeto "Account" tiene 100 registros
13431Then el objeto "Account" tiene al menos 1 registros
13432Then el objeto "Account" tiene 3 registros donde "Industry = 'Technology'"
13433Then el objeto "Account" tiene registros donde "Name != null"
13434Then existe al menos un registro de "Contact" donde "Email != null"
13435Then el objeto "Lead" no tiene registros donde "Status = 'Junk'"
13436
13437When cuento los registros de "Account" donde "Industry = 'Banking'" y los guardo en la variable "bancos"
13438When cuento los registros de "Contact" y los guardo en la variable "totalContactos"
13439\`\`\`
13440
13441### Registro por Id
13442
13443\`\`\`gherkin
13444When obtengo el registro "001XXXXXXXXXXXX" del objeto "Account"
13445Then el último registro obtenido tiene el campo "Name" igual a "Acme"
13446When guardo el campo "OwnerId" del último registro obtenido en la variable "dueno"
13447\`\`\`
13448
13449### Integridad de objetos
13450
13451\`\`\`gherkin
13452Then el objeto "Account" existe
13453Then existe el objeto "Account" en Salesforce   # alias, mismo comportamiento
13454Then el objeto "ObjetoInventado__c" no existe
13455Then el objeto "Account" tiene el campo "Industry"
13456Then el objeto "Account" no tiene el campo "CampoQueNoDebeExistir__c"
13457Then el objeto "Account" tiene los campos "Name, Industry, Phone"
13458Then el objeto "Account" tiene al menos 10 campos
13459Then el objeto "Account" tiene 45 campos
13460Then el objeto "MiObjeto__c" es personalizado
13461Then el objeto "Account" permite crear registros
13462When describo el objeto "Account"
13463\`\`\`
13464
13465### Integridad de campos
13466
13467\`\`\`gherkin
13468Then el campo "Industry" del objeto "Account" es de tipo "picklist"
13469Then el campo "Name" del objeto "Account" es obligatorio
13470Then el campo "Website" del objeto "Account" es opcional
13471Then el campo "Email" del objeto "Contact" es único
13472Then el campo "Name" del objeto "Account" es actualizable
13473Then el campo "CreatedDate" del objeto "Account" es de solo lectura
13474Then el campo "Name" del objeto "Account" tiene longitud 255
13475Then el campo "Name" del objeto "Account" tiene longitud máxima 255
13476Then la etiqueta del campo "Industry" del objeto "Account" es "Sector"
13477Then el campo "AccountId" del objeto "Contact" referencia al objeto "Account"
13478\`\`\`
13479
13480> Tipos comunes de Salesforce: \`string\`, \`textarea\`, \`picklist\`, \`multipicklist\`, \`reference\`, \`boolean\`, \`double\`, \`currency\`, \`date\`, \`datetime\`, \`email\`, \`phone\`, \`id\`.
13481
13482### Integridad de picklists
13483
13484\`\`\`gherkin
13485Then el picklist "Industry" del objeto "Account" contiene el valor "Technology"
13486Then el picklist "Industry" del objeto "Account" no contiene el valor "Obsoleto"
13487Then el picklist "Industry" del objeto "Account" contiene los valores "Banking, Retail, Technology"
13488Then el picklist "Industry" del objeto "Account" contiene exactamente los valores "Banking, Retail, Technology"
13489Then el picklist "Industry" del objeto "Account" tiene 35 valores
13490Then el picklist "Industry" del objeto "Account" tiene 30 valores activos
13491Then el valor por defecto del picklist "Estado__c" del objeto "MiObjeto__c" es "Nuevo"
13492Then el valor "Technology" del picklist "Industry" del objeto "Account" está activo
13493Then el valor "Obsoleto" del picklist "Industry" del objeto "Account" está inactivo
13494When guardo los valores del picklist "Industry" del objeto "Account" en la variable "sectores"
13495\`\`\`
13496
13497- **contiene los valores**: verifica que estén TODOS los indicados (pueden existir otros más).
13498- **contiene exactamente los valores**: el conjunto de valores **activos** debe ser idéntico al indicado (ni más ni menos).
13499
13500### Tipos de registro
13501
13502\`\`\`gherkin
13503Then el objeto "Opportunity" tiene el tipo de registro "Ventas"
13504Then el objeto "Opportunity" tiene 2 tipos de registro
13505\`\`\`
13506
13507### REST genérico (avanzado)
13508
13509\`\`\`gherkin
13510When ejecuto una petición REST de Salesforce a "limits"
13511Then la respuesta REST de Salesforce tiene el campo "DailyApiRequests.Max" igual a "15000"
13512\`\`\`
13513
13514Todos estos pasos quedan registrados en el reporte HTML con la consulta y su resultado, para que puedas revisarlos de
13514spués.`},{id:"salesforce-reutilizacion",title:"Reutilización y Paralelismo",content:`## Reutilización de Sesión
13515
13516El framework es inteligente con la reutilización:
13517
13518### Mismo Perfil, Misma Sesión
13519
13520Si llamas \`inicio sesión con el usuario "UAT1"\` dos veces seguidas:
135211. La primera vez: autentica por API + abre frontdoor.jsp + espera Lightning.
135222. La segunda vez: verifica que Lightning sigue cargado → **no hace nada** (no navega, no re-autentica).
13523
13524### Cambio de Perfil
13525
13526Si cambias de \`UAT1\` a \`SIT1\`:
135271. Obtiene o crea el cliente API de \`SIT1\`.
135282. Abre frontdoor.jsp con la sesión de \`SIT1\`.
135293. Ambos clientes quedan en cache.
13530
13531### Regreso a un Perfil Anterior
13532
13533Si vuelves a \`UAT1\` después de usar \`SIT1\`:
135341. Reutiliza el cliente API de \`UAT1\` (ya estaba conectado).
135352. Solo navega para restaurar la sesión de \`UAT1\` en el navegador.
13536
13537### Retención Entre Features
13538
13539La sesión se conserva entre features del mismo proceso. Si el \`Background\` de cada feature llama al mismo perfil, solo el primer feature navega; los siguientes reutilizan.
13540
13541## Ejecución Paralela
13542
13543### Aislamiento por Proceso
13544
13545Cada worker paralelo ejecuta un subprocess independiente con:
13546- Su propio browser Playwright.
13547- Su propio BrowserContext y cookies.
13548- Su propio cache de clientes API.
13549- Sus propias sesiones Salesforce.
13550
13551**No se comparte nada entre workers.**
13552
13553### Limitación con Mismo Usuario
13554
13555Si dos workers usan el mismo usuario Salesforce y ambos **modifican datos**, Salesforce puede producir conflictos (locks, errores de concurrencia). Recomendaciones:
13556
13557| Situación | Recomendación |
13558|---|---|
13559| Features de solo lectura | Pueden compartir usuario sin problemas |
13560| Features que modifican datos | Usar un usuario distinto por worker |
13561| Features mixtos | Separar por tags y asignar usuarios |
13562
13563### Configuración para Múltiples Workers
13564
13565\`\`\`env
13566# Worker 1 usa UAT1
13567[email protected]
13568
13569# Worker 2 usa UAT2
13570[email protected]
13571\`\`\`
13572
13573Ambos comparten la aplicación conectada y el certificado; solo cambia el usuario.
13574
13575\`\`\`gherkin
13576# Feature asignado a worker 1
13577@worker1
13578Feature: Operaciones en cuentas
13579  Given inicio sesión con el usuario "UAT1"
13580
13581# Feature asignado a worker 2
13582@worker2
13583Feature: Operaciones en contactos
13584  Given inicio sesión con el usuario "UAT2"
13585\`\`\``},{id:"salesforce-seguridad",title:"Seguridad y Troubleshooting",content:'## Seguridad\n### La Llave Privada\n- **Nunca versionar el `.key`.** Agrega `sf_key/` a `.gitignore`. Con ese archivo se puede entrar a Salesforce como los usuarios autorizados, sin contraseña y sin verificación por correo.\n- En CI, entrégala como secreto en `SF_JWT_PRIVATE_KEY` en lugar de subir el archivo.\n- El conjunto de permisos asignado a la aplicación conectada es el control real de quién puede autenticarse. Revísalo periódicamente y no reutilices uno que tenga asignada mucha gente.\n### Credenciales\n- **Nunca versionar el `.env`** en Git. Agrega `.env` a `.gitignore`.\n- En CI/CD, usa secretos del pipeline (GitHub Secrets, GitLab CI Variables, etc.).\n- El framework enmascara automáticamente passwords, tokens y `sid` en logs, errores y reportes.\n### Qué se Enmascara\n- `SF_PASSWORD`, `SF_SECURITY_TOKEN`\n- `SF_PERFIL_*_PASS`, `SF_PERFIL_*_TOKEN`\n- Llave privada, client secret y access tokens en mensajes de error\n- Parámetro `sid` en URLs de frontdoor\n- Cualquier valor que coincida con patterns de password/token en textos de error\n### Permisos del Usuario\nLas pruebas ven exactamente lo que ve el usuario del perfil. Si le faltan permisos sobre un objeto, las consultas SOQL **no dan error**: devuelven cero resultados, y el fallo parece un problema de datos cuando en realidad es de permisos.\n## Troubleshooting\nLos errores de autenticación informan el modo activo, el código HTTP y el mensaje de Salesforce. Por ejemplo: `modo=oauth_jwt_bearer; HTTP 400; error=invalid_app_access`.\n### Error: "user is not admin approved to access this app"\nFalta autorizar al usuario en la aplicación conectada. Son dos partes y ninguna funciona sola:\n1. **Administrar → Editar políticas → Usuarios permitidos** → *Los usuarios a
13585probados por el administrador se han autorizado previamente*.\n2. Volver a **Administrar** sin editar, bajar al recuadro **Conjuntos de permisos** y asignar ahí el conjunto que tiene el usuario.\nDespués de guardar, espera unos minutos de propagación.\n### Error: "invalid assertion" o "audience is invalid"\nLa llave privada no corresponde al certificado subido, o el `aud` es incorrecto. El `aud` es `https://test.salesforce.com` para sandbox y `https://login.salesforce.com` para producción, y **no** es la URL de tu organización: esa va en `_OAUTH_TOKEN_URL`.\n### Error: "invalid_client"\nLa Clave de consumidor está mal copiada, o la aplicación conectada todavía no se activó. Salesforce tarda entre 2 y 10 minutos en activar una aplicación nueva.\n### Error: "request not supported on this domain"\nLa dirección de `_OAUTH_TOKEN_URL` no corresponde. Usa la misma con la que entras a Salesforce por el navegador, agregando `/services/oauth2/token`.\n### Error: "Salesforce rechazó la sesión y mostró su pantalla de login"\nEl acceso se obtuvo pero no abrió la pantalla. Revisa:\n1. Que la aplicación conectada tenga el ámbito `web` (*Gestionar datos de usuario a través de navegadores*).\n2. Que el usuario no tenga el permiso **Solo API**, porque ese tipo de usuario no puede abrir sesión de navegador.\n3. Que no lo bloqueen MFA, SSO o restricciones de IP. En la aplicación, **Relajación de IP** suele necesitar *Relajar restricciones de IP* para CI, donde la IP cambia.\n4. Que `SF_API_AUTH_MODE` no sea `oauth_client_credentials`: ese modo no abre sesión de navegador.\n### Error: "Salesforce no alcanzó Lightning en la fase frontdoor"\n**Causas comunes:**\n1. **URL incorrecta en `_URL`**: Debe ser la URL base (`my.salesforce.com`), no la URL de Lightning (`lightning.force.com`).\n   ```env\n   # BIEN\n   SF_PERFIL_UAT1_URL=https://mi-org--sit.sandbox.my.salesforce.com\n   # MAL\n   SF_PERFIL_UAT1_URL=https://mi-org--sit.sandbox.lightning.force.com/lightning/n/Inicio\n   ```\n2. **Usuario sin API Enabled**: Revisa el perfil del usuario en Salesforce → System Permissions → API Enabled.\n3. **MFA/SSO activo**: frontdoor.jsp no puede saltarse MFA. Coordina con el admin para desactivarlo en el ambiente de prueba.\n4. **Timeout muy bajo**: Aumenta `SF_FRONTDOOR_TIMEOUT_SECONDS` si la org es lenta.\n### Error: "Faltan credenciales JWT del perfil \'X\'"\nEl nombre del perfil no coincide con las variables del `.env`. Verifica:\n- El nombre en el step se normaliza a mayúsculas: `"uat1"` busca `SF_PERFIL_UAT1_*`.\n- Espacios y guiones se convierten en `_`: `"uat 1"` busca `SF_PERFIL_UAT_1_*`.\n- Debe existir el usuario, la Clave de consumidor y la llave privada, ya sea por perfil o como valor global.\n### Error: "SF_LOGIN_MODE=frontdoor requiere SF_API_ENABLED=true"\nAgrega `SF_API_ENABLED=true` en tu `.env`.\n### Error: "simple-salesforce no está instalada"\nReinstala el framework:\n```bash\npip install --upgrade haka-playwright-engine\n```\n### Advertencia en el log: "Salesforce está retirando el login SOAP"\nTu `.env` está usando `SF_API_AUTH_MODE=legacy_soap`, con usuario, contraseña y security token. Ese método ya no está disponible en API 65.0 y posteriores. Migra a `oauth_jwt_bearer`.\n### ¿Dónde obtengo la Clave de consumidor?\nEn Salesforce: **Configuración → Gestor de aplicaciones**, flecha de la derecha de tu aplicación → **Ver** → sección **API** → **Administrar detalles de consumidor**. Salesforce envía un código de verificación por correo antes de mostrarla.\n> **Nota:** El **Secreto de consumidor** que aparece junto a la Clave no se usa con JWT Bearer. Solo aplica al modo `oauth_client_credentials` para pruebas de API sin navegador.'}]},{id:"sap",title:"SAP (UI5 / Fiori)",group:"Aplicaciones Empresariales",icon:"",topics:[{id:"sap-descripcion",title:"Descripción General",content:'## Automatización de SAP Web (SAPUI5 / Fiori)\n\nSAP Web (SAPUI5, OpenUI5, Fiori Launchpad, Fiori Elements) **no usa elementos HTML nativos**. Un "checkbox" no es un `<input type="checkbox">`, un "select" no es un `<select>` y una "tabla" no son `<table>` estándar. Todo se renderiza como `div`/`span`/`ul`/`li` con clases propias (`sapM*`, `sapUi*`, `sapF*`) y atributos ARIA.\n\nEsto rompe los pasos genéricos de cualquier framework. Por eso Haka incluye un catálogo dedicado de **101 pasos SAP** (202 patrones contando el al
13585ias con `que` inicial) que conocen estos patrones: controles UI5, roles ARIA, tablas responsive vs grid y los *busy indicators* de OData.\n\n### Regla de oro\n\nTodos los pasos SAP llevan la palabra **`SAP`** o **`Fiori`** en su nombre. Si un paso no la lleva, es un paso genérico del framework (que también puedes usar cuando aplique: navegación, ventanas, evidencias, aserciones de texto).\n\n### Qué cubre el catálogo SAP\n\n| Categoría | Pasos |\n|---|---|\n| Base (click por texto, combobox, tabla, botón) | 7 |\n| Estados de carga y espera (OData) | 4 |\n| Inputs y campos de texto | 10 |\n| CheckBox / RadioButton / Switch | 9 |\n| Mensajes (Toast / MessageBox / MessageStrip / MessagePopover) | 8 |\n| Tablas (responsive + grid) | 13 |\n| Select / MultiComboBox / Value Help (F4) | 6 |\n| Diálogos y popovers | 6 |\n| Navegación Fiori Launchpad | 9 |\n| Botones y acciones (avanzado) | 8 |\n| DatePicker / DateRange | 5 |\n| Tabs / IconTabBar / Wizard | 4 |\n| ObjectPage (Fiori Elements) | 4 |\n| Utilidades / Avanzado | 5 |\n| Elementos genéricos SAP por POM | 3 |\n| **Total** | **101** |\n\n> Todos los pasos SAP tienen nombres únicos, sin ambigüedad de Behave ni conflictos de prefijo con el resto del catálogo. Cada paso admite el prefijo opcional `que` (ej: `que hago click en el elemento SAP ...`) para encadenar en `And`/`Y`.'},{id:"sap-espera-carga",title:"Espera Inteligente (OData)",content:`## Espera inteligente: lo primero que debes saber
13586
13587SAP carga datos de forma asíncrona vía **OData**. Entre una acción y la siguiente suele aparecer un *busy indicator* que bloquea la UI. Si interactúas antes de que desaparezca, el paso falla de forma intermitente (flaky).
13588
13589Casi todos los pasos SAP ya esperan internamente a que SAP esté listo, pero cuando necesites una espera explícita entre acciones:
13590
13591\`\`\`gherkin
13592When hago click en el elemento SAP "boton GO" con identificador "$.APP.btn_go"
13593And espero a que SAP termine de cargar
13594Then verifico que la tabla SAP "resultados" con identificador "$.APP.tabla" tiene 15 filas
13595\`\`\`
13596
13597### Consideraciones
13598
13599- \`espero a que SAP termine de cargar\` espera a que desaparezcan **todos** los busy indicators globales.
13600- \`espero a que la tabla SAP "X" cargue datos\` es más específico: espera a que la tabla salga de busy y renderice filas.
13601- Evita \`espero N segundos\` (hardcoded). Usa las esperas SAP inteligentes.`},{id:"sap-inicio-rapido",title:"Inicio Rápido (Ejemplos)",content:`## Ejemplos reales de flujos SAP
13602
13603### Flujo S/4HANA — Manage Supplier Line + Monitor Grant
13604
13605\`\`\`gherkin
13606@sap
13607Scenario: Flujo S/4HANA - Manage Supplier Line + Monitor Grant
13608  Given voy a la url "\${ENV.URL_BASE}"
13609  And escribo "[email protected]" en el input SAP "Usuario" con identificador "$.DEMO_SAP.login_username"
13610  And hago click en el elemento SAP "boton login" con identificador "$.DEMO_SAP.btn_login"
13611  And escribo "\${ENV.PASS_SAP}" en el input SAP "Pass" con identificador "$.DEMO_SAP.login_password"
13612  * evidencia "Login completo"
13613  And hago click en el elemento SAP "boton login" con identificador "$.DEMO_SAP.btn_login"
13614  And hago click en el elemento SAP "Accounts Payable" con identificador "$.DEMO_SAP.seccion_accounts"
13615  When intento cambiar a la ventana con url que contiene "my300180.s4hana.ondemand.com" esperando hasta 60 segundos
13616  And espero a que SAP termine de cargar
13617  And si existe el elemento SAP "Cerrar Tour" con identificador "$.DEMO_SAP.leave_tour" hago click
13618  And hago click en el elemento SAP "Menú Home" con identificador "$.DEMO_SAP.Menu_Home"
13619  And hago click en el elemento SAP "Manage Supplier Line" con identificador "$.DEMO_SAP.Opcion_MSLI"
13620  When selecciono "All Items" del combobox SAP "Status" con identificador "$.DEMO_SAP.msli_status"
13621  And hago click en el elemento SAP "boton GO" con identificador "$.DEMO_SAP.msli_go"
13622  And hago click en el elemento SAP "Primer elemento del listado" con identificador "$.DEMO_SAP.primer_registro"
13623  * evidencia "Manage Supplier"
13624  Then verifico que el elemento SAP "Panel Billing Details" con identificador "$.DEMO_SAP.panel_grant_billig" está visible
13625  And debería ver el texto "33,73K"
13626\`\`\`
13627
13628### Fiori Launchpad — abrir app, filtrar tabla y validar
13629
13630\`\`\`gherkin
13631@sap
13632Scenario: Fiori Launchpad - abrir app, filtrar tabla y validar
13633  Given voy a la url "\${ENV.FIORI_URL}"
13634  And verifico que estoy en el launchpad de Fiori
13635  When abro el tile de Fiori "Manage Purchase Orders"
13636  And espero a que SAP termine de cargar
13637  And selecciono "All Items" del combobox SAP "Status" con identificador "$.PO.status"
13638  And hago click en el elemento SAP "Go" con identificador "$.PO.btn_go"
13639  And espero a que la tabla SAP "resultados" cargue datos
13640  Then verifico que la tabla SAP "resultados" con identificador "$.PO.tabla" contiene el texto "ACME Corp"
13641  And verifico que la tabla SAP "resultados" con identificador "$.PO.tabla" tiene 15 filas
13642\`\`\`
13643
13644### Formulario SAP — inputs, selects, checkbox y validación
13645
13646\`\`\`gherkin
13647@sap
13648Scenario: Formulario SAP - inputs, selects, checkbox y validación
13649  Given voy a la url "\${ENV.FIORI_URL}"
13650  When abro del grupo de Fiori "Compras" el tile "Create Supplier Invoice"
13651  And escribo "ACME Corp" en el input SAP "Proveedor" con identificador "$.INV.proveedor"
13652  And selecciono "CLP" del select SAP "Moneda" con identificador "$.INV.moneda"
13653  And selecciono la fecha "15/03/2025" en el DatePicker SAP "Fecha" con identificador "$.INV.fecha"
13654  And marco el checkbox SAP "Pago inmediato" con identificador "$.INV.pago_inmediato"
13655  And presiono el botón de acción "Save" del footer SAP
13656  Then verifico el mensaje toast SAP "Factura creada correctamente"
13657\`\`\`
13658
13659> Los pasos SAP se combinan con los genéricos del framework: \`voy a la url\`, \`intento cambiar a la ventana ...\`, \`* evidencia\` y \`debería ver el texto\` siguen siendo genéricos.`},{id:"sap-inv-base",title:"Inventario: Base, Cargas y Espera",content:`## SAP UI5 / Fiori (base)
13660
13661step: hago click en el texto "{text}"
13662descripcion: Hace click en cualquier elemento que contenga el texto visible especificado.
13663
13664step: selecciono "{option}" del combobox SAP "{element_name}" con identificador "{identifier}"
13665descripcion: Selecciona una opción de un combobox SAP UI5.
13666
13667step: selecciono "{option}" del combobox SAP que muestra "{current_value}"
13668descripcion: Selecciona una opción de un combobox SAP identificándolo por su valor actual visible.
13669
13670step: abro el combobox SAP "{element_name}" con identificador "{identifier}"
13671descripcion: Abre un combobox SAP sin seleccionar opción (para inspección o validación).
13672
13673step: escribo "{text}" en el campo SAP "{element_name}" con identificador "{identifier}" y selecciono "{option}"
13674descripcion: Escribe en un campo SAP (search/input) y selecciona una opción del autocomplete.
13675
13676step: selecciono la fila con texto "{text}" en la tabla SAP "{table_name}" con identificador "{identifier}"
13677descripcion: Selecciona una fila de una tabla SAP UI5 buscando por texto visible en cualquier celda.
13678
13679step: presiono el botón SAP "{button_text}"
13680descripcion: Presiona un botón SAP UI5 por su texto visible.
13681
13682## Estados de carga y espera
13683
13684step: espero a que SAP termine de cargar
13685descripcion: Espera a que desaparezcan todos los busy indicators globales de SAP.
13686
13687step: espero a que desaparezca el busy indicator SAP
13688descripcion: Espera a que desaparezca el busy indicator local de SAP.
13689
13690step: espero a que la tabla SAP "{table_name}" cargue datos
13691descripcion: Espera a que una tabla SAP salga de estado busy y tenga filas.
13692
13693step: espero a que el diálogo SAP "{title}" aparezca
13694descripcion: Espera a que un diálogo SAP con el título dado se haga visible.`},{id:"sap-inv-inputs",title:"Inventario: Inputs y Campos de Texto",content:`## Inputs y campos de texto
13695
13696step: escribo "{text}" en el input SAP "{element_name}" con identificador "{identifier}"
13697descripcion: Escribe texto en un input UI5 identificado por POM o selector directo.
13698
13699step: escribo "{text}" en el input SAP con label "{label}"
13700descripcion: Escribe texto en un input UI5 localizado por su label asociad
13700o.
13701
13702step: limpio el input SAP "{element_name}" con identificador "{identifier}"
13703descripcion: Vacía un input UI5.
13704
13705step: verifico que el input SAP "{element_name}" con identificador "{identifier}" contiene "{value}"
13706descripcion: Verifica el valor actual de un input UI5.
13707
13708step: verifico que el input SAP "{element_name}" con identificador "{identifier}" está vacío
13709descripcion: Verifica que un input UI5 esté vacío.
13710
13711step: escribo "{text}" en el textarea SAP "{element_name}" con identificador "{identifier}"
13712descripcion: Escribe texto en un TextArea UI5.
13713
13714step: escribo "{text}" en el campo de búsqueda SAP
13715descripcion: Escribe en un SearchField UI5 (search box con lupa) y presiona Enter.
13716
13717step: verifico que el input SAP "{element_name}" con identificador "{identifier}" tiene estado "{state}"
13718descripcion: Verifica el valueState de un input UI5 (Error/Warning/Success/Information/None).
13719
13720step: verifico el mensaje de validación "{text}" del input SAP "{element_name}"
13721descripcion: Verifica el valueStateText (mensaje bajo el campo) de un input SAP.
13722
13723step: escribo letra por letra "{text}" en el input SAP "{element_name}" con identificador "{identifier}"
13724descripcion: Escribe texto carácter por carácter en un input SAP (dispara autocomplete/suggestions).`},{id:"sap-inv-controles",title:"Inventario: CheckBox, Radio y Switch",content:`## CheckBox / RadioButton / Switch
13725
13726step: marco el checkbox SAP "{element_name}" con identificador "{identifier}"
13727descripcion: Marca un CheckBox UI5 (si no está ya marcado).
13728
13729step: desmarco el checkbox SAP "{element_name}" con identificador "{identifier}"
13730descripcion: Desmarca un CheckBox UI5 (si está marcado).
13731
13732step: verifico que el checkbox SAP "{element_name}" con identificador "{identifier}" está marcado
13733descripcion: Verifica que un CheckBox UI5 esté marcado.
13734
13735step: verifico que el checkbox SAP "{element_name}" con identificador "{identifier}" está desmarcado
13736descripcion: Verifica que un CheckBox UI5 esté desmarcado.
13737
13738step: selecciono el radio button SAP "{label}"
13739descripcion: Selecciona un RadioButton UI5 por su label visible.
13740
13741step: verifico que el radio button SAP "{label}" está seleccionado
13742descripcion: Verifica que un RadioButton UI5 esté seleccionado.
13743
13744step: activo el switch SAP "{element_name}" con identificador "{identifier}"
13745descripcion: Enciende un Switch UI5 (si está apagado).
13746
13747step: desactivo el switch SAP "{element_name}" con identificador "{identifier}"
13748descripcion: Apaga un Switch UI5 (si está encendido).
13749
13750step: verifico que el switch SAP "{element_name}" con identificador "{identifier}" está activado
13751descripcion: Verifica que un Switch UI5 esté encendido.`},{id:"sap-inv-mensajes",title:"Inventario: Mensajes",content:`## Mensajes (Toast / MessageBox / MessageStrip / MessagePopover)
13752
13753step: verifico el mensaje toast SAP "{text}"
13754descripcion: Verifica que aparezca un MessageToast SAP con el texto dado.
13755
13756step: espero el mensaje toast SAP
13757descripcion: Espera a que aparezca cualquier MessageToast SAP.
13758
13759step: verifico el MessageBox SAP de tipo "{msg_type}"
13760descripcion: Verifica que aparezca un MessageBox SAP del tipo dado (Error/Warning/Success/Information/Confirm).
13761
13762step: confirmo el MessageBox SAP
13763descripcion: Presiona OK/Yes/Aceptar en un MessageBox SAP.
13764
13765step: cancelo el MessageBox SAP
13766descripcion: Presiona Cancel/No/Cancelar en un MessageBox SAP.
13767
13768step: verifico el MessageStrip SAP "{text}"
13769descripcion: Verifica un MessageStrip SAP (barra de mensaje inline) con el texto dado.
13770
13771step: abro el MessagePopover SAP
13772descripcion: Abre el MessagePopover SAP (indicador de mensajes de validación).
13773
13774step: verifico que hay {count:d} mensajes de error SAP
13775descripcion: Verifica la cantidad de mensajes de error en el MessagePopover SAP.`},{id:"sap-inv-tablas",title:"Inventario: Tablas",content:`## Tablas (sap.m.Table responsive + sap.ui.table grid)
13776
13777Todos los pasos de tabla prueban automáticamente ambos tipos de tabla SAP. Las columnas se localizan por su nombre de header (parcial, case-insensitive).
13778
13779step: verifico que la tabla SAP "{table_name}" con identificador "{identifier}" tiene {count:d} filas
13780descripcion: Verifica la cantidad de filas de una tabla SAP.
13781
13782step: verifico que la tabla SAP "{table_name}" con identificador "{identifier}" contiene el texto "{text}"
13783descripcion: Verifica que una tabla SAP contenga el texto en alguna celda.
13784
13785step: verifico que la tabla SAP "{table_name}" con identificador "{identifier}" no contiene el texto "{text}"
13786descripcion: Verifica que una tabla SAP NO contenga el texto en ninguna celda.
13787
13788step: hago click en la celda de columna "{col}" de la fila con texto "{row_text}" en la tabla SAP "{table_name}" con identificador "{identifier}"
13789descripcion: Hace click en una celda específica (columna + fila) de una tabla SAP.
13790
13791step: obtengo el valor de la columna "{col}" de la fila con texto "{row_text}" de la tabla SAP "{table_name}" con identificador "{identifier}" en la variable "{var}"
13792descripcion: Extrae el valor de una celda (columna+fila) de una tabla SAP a una variable.
13793
13794step: marco el checkbox de la fila con texto "{row_text}" en la tabla SAP "{table_name}" con identificador "{identifier}"
13795descripcion: Marca el checkbox de selección de una fila en una tabla SAP multiselect.
13796
13797step: selecciono todas las filas de la tabla SAP "{table_name}" con identificador "{identifier}"
13798descripcion: Marca el checkbox de selección de todas las filas (header select-all).
13799
13800step: presiono la acción "{action}" de la fila con texto "{row_text}" en la tabla SAP "{table_name}" con identificador "{identifier}"
13801descripcion: Presiona un botón de acción inline dentro de una fila de tabla SAP.
13802
13803step: ordeno la tabla SAP "{table_name}" con identificador "{identifier}" por la columna "{col}"
13804descripcion: Ordena una tabla SAP haciendo click en el header de la columna.
13805
13806step: expando la fila con texto "{row_text}" de la tabla SAP "{table_name}" con identificador "{identifier}"
13807descripcion: Expande una fila expandible en una TreeTable SAP.
13808
13809step: verifico que la fila con texto "{row_text}" de la tabla SAP "{table_name}" con identificador "{identifier}" tiene la columna "{col}" con valor "{value}"
13810descripcion: Verifica el valor de una celda (columna+fila) de una tabla SAP.
13811
13812step: voy a la página {page_num:d} de la tabla SAP "{table_name}" con identificador "{identifier}"
13813descripcion: Navega a una página específica en la paginación de una tabla SAP.
13814
13815step: verifico que la tabla SAP "{table_name}" con identificador "{identifier}" está vacía
13816descripcion: Verifica que una tabla SAP esté vacía (estado No data).`},{id:"sap-inv-select",title:"Inventario: Select, MultiComboBox y Value Help",content:`## Select / MultiComboBox / Value Help (F4)
13817
13818step: selecciono "{option}" del select SAP "{element_name}" con identificador "{identifier}"
13819descripcion: Selecciona una opción de un sap.m.Select UI5 (distinto del ComboBox editable).
13820
13821step: agrego "{option}" al MultiComboBox SAP "{element_name}" con identificador "{identifier}"
13822descripcion: Agrega una opción (token) a un MultiComboBox SAP.
13823
13824step: elimino el token "{value}" del MultiComboBox SAP "{element_name}" con identificador "{identifier}"
13825descripcion: Elimina un token seleccionado de un MultiComboBox/MultiInput SAP.
13826
13827step: verifico que el combobox SAP "{element_name}" con identificador "{identifier}" muestra "{value}"
13828descripcion: Verifica el valor mostrado por un combobox/select SAP.
13829
13830step: abro el value help del campo SAP "{element_name}" con identificador "{identifier}"
13831descripcion: Abre el Value Help (F4) de un campo SAP.
13832
13833step: selecciono "{value}" del value help SAP
13834descripcion: Selecciona un valor del diálogo de Value Help (F4) SAP.`},{id:"sap-inv-dialogos",title:"Inventario: Diálogos y Popovers",content:`## Diálogos y popovers
13835
13836step: verifico que el diálogo SAP "{title}" está visible
13837descripcion: Verifica que un diálogo SAP con el título dado esté visible.
13838
13839step: cierro el diálogo SAP
13840descripcion: Cierra el diálogo SAP activo (botón X, Cancel o Close).
13841
13842step: presiono "{button}" en el diálogo SAP
13843descripcion: Presiona un botón del footer de un diálogo SAP por su texto.
13844
13845step: verifico que el popover SAP está visible
13846descripcion: Verifica que un Popover SAP esté visible.
13847
13848step: cierro el popover SAP
13849descripcion: Cierra un Popover SAP presionando Escape.
13850
13851step: verifico el contenido "{text}" del diálogo SAP
13852descripcion: Verifica que el diálogo SAP activo contenga el texto dado.`},{id:"sap-inv-fiori",title:"Inventario: Fiori Launchpad",content:`## Navegación Fiori Launchpad
13853
13854Estos pasos operan sobre el **shell** de Fiori (home, tiles, buscador, menú de usuario), no sobre la app embebida.
13855
13856step: abro el tile de Fiori "{tile}"
13857descripcion: Hace click en un tile del Fiori Launchpad por su título.
13858
13859step: abro del grupo de Fiori "{group}" el tile "{tile}"
13860descripcion: Hace click en un tile dentro de un grupo específico del launchpad. Nota el orden: primero el grupo, luego el tile.
13861
13862step: busco "{text}" en la búsqueda de Fiori
13863descripcion: Usa el buscador global del shell de Fiori.
13864
13865step: vuelvo al inicio de Fiori
13866descripcion: Hace click en el botón Home del shell de Fiori.
13867
13868step: abro el menú de usuario de Fiori
13869descripcion: Despliega el menú de acciones de usuario del shell de Fiori.
13870
13871step: cierro sesión en Fiori
13872descripcion: Cierra sesión desde el menú de usuario de Fiori (confirma el logout automáticamente).
13873
13874step: abro el panel de notificaciones de Fiori
13875descripcion: Abre el popover de notificaciones del shell de Fiori.
13876
13877step: navego atrás en Fiori
13878descripcion: Presiona el botón back del shell de Fiori (no del navegador).
13879
13880step: verifico que estoy en el launchpad de Fiori
13881descripcion: Verifica que el shell home del Fiori Launchpad esté visible.`},{id:"sap-inv-botones",title:"Inventario: Botones y Acciones",content:`## Botones y acciones (avanzado)
13882
13883step: presiono el botón SAP con icono "{icon}"
13884descripcion: Presiona un botón SAP identificado por su icono (nombre sap-icon:// o sufijo).
13885
13886step: presiono el botón SAP con tooltip "{tooltip}"
13887descripcion: Presiona un botón SAP por su atributo title/tooltip.
13888
13889step: presiono dentro del contenedor SAP "{container}" el botón "{button_text}"
13890descripcion: Presiona un botón SAP por texto, acotado a un contenedor/diálogo específico (evita ambigüedad si hay varios botones iguales).
13891
13892step: presiono el botón de acción "{button_text}" del footer SAP
13893descripcion: Presiona un botón del footer bar SAP (Save, Cancel, etc.).
13894
13895step: abro el menú de acciones SAP "{button_text}"
13896descripcion: Abre un MenuButton SAP que despliega opciones.
13897
13898step: selecciono "{option}" del menú de acciones SAP
13899descripcion: Selecciona una opción de un menú SAP desplegado.
13900
13901step: presiono el botón de segmento SAP "{text}"
13902descripcion: Presiona un botón de un SegmentedButton SAP (toggle de vistas tipo Lista/Tarjetas).
13903
13904step: presiono el botón de overflow de la toolbar SAP
13905descripcion: Presiona el botón de overflow ('...') de una OverflowToolbar SAP.`},{id:"sap-inv-fechas",title:"Inventario: Fechas (DatePicker)",content:`## DatePicker / DateTimePicker / DateRange
13906
13907step: selecciono la fecha "{date}" en el DatePicker SAP "{element_name}" con identificador "{identifier}"
13908descripcion: Escribe una fecha en un DatePicker SAP.
13909
13910step: abro el calendario del DatePicker SAP "{element_name}" con identificador "{identifier}"
13911descripcion: Abre el popup de calendario de un DatePicker SAP.
13912
13913step: selecciono el día {day:d} del calendario SAP
13914descripcion: Hace click en un día visible del calendario SAP abierto.
13915
13916step: selecciono el rango "{from_date}" a "{to_date}" en el DateRange SAP "{element_name}" con identificador "{identifier}"
13917descripcion: Escribe un rango de fechas en un DateRangeSelection SAP.
13918
13919step: verifico que el DatePicker SAP "{element_name}" con identificador "{identifier}" tiene la fecha "{date}"
13920descripcion: Verifica la fecha actual de un DatePicker SAP.`},{id:"sap-inv-tabs-objectpage",title:"Inventario: Tabs, Wizard y ObjectPage",content:`## Tabs / IconTabBar / Wizard
13921
13922step: selecciono la pestaña SAP "{tab}"
13923descripcion: Selecciona una pestaña de un IconTabBar/TabContainer SAP.
13924
13925step: verifico que la pestaña SAP "{tab}" está activa
13926descripcion: Verifica que una pestaña SAP esté seleccionada/activa.
13927
13928step: avanzo al siguiente paso del wizard SAP
13929descripcion: Avanza al siguiente paso de un Wizard SAP.
13930
13931step: verifico que el paso "{step_name}" del wizard SAP está activo
13932descripcion: Verifica que un paso específico del wizard SAP esté activo.
13933
13934## ObjectPage / Detalle (Fiori Elements)
13935
13936step: navego a la sección "{section}" del ObjectPage SAP
13937descripcion: Navega a una sección del ObjectPage SAP vía el anchor bar.
13938
13939step: verifico el header del ObjectPage SAP "{title}"
13940descripcion: Verifica el título del header de un ObjectPage SAP.
13941
13942step: entro en modo edición del ObjectPage SAP
13943descripcion: Presiona el botón Edit de un ObjectPage SAP.
13944
13945step: verifico el ObjectStatus SAP "{text}" con estado "{state}"
13946descripcion: Verifica un ObjectStatus SAP con su texto y estado (Success/Error/Warning/None).`},{id:"sap-inv-utilidades",title:"Inventario: Utilidades y Genéricos",content:`## Utilidades / Avanzado
13947
13948step: hago scroll hasta el elemento SAP con texto "{text}"
13949descripcion: Hace scroll hasta un elemento SAP por su texto (útil con virtualización).
13950
13951step: verifico que existe el control SAP con id "{control_id}"
13952descripcion: Verifica que exista un control SAP por su id estable de UI5.
13953
13954step: capturo el valor del control SAP "{element_name}" con identificador "{identifier}" en la variable "{var}"
13955descripcion: Captura el valor de un control SAP (input o texto) en una variable.
13956
13957step: verifico que el control SAP "{element_name}" con identificador "{identifier}" está habilitado
13958descripcion: Verifica que un control SAP esté habilitado.
13959
13960step: verifico que el control SAP "{element_name}" con identificador "{identifier}" está deshabilitado
13961descripcion: Verifica que un control SAP esté deshabilitado.
13962
13963## Elementos genéricos SAP por POM (click, visibilidad, condicional)
13964
13965Cuando el flujo es 100% SAP y quieres el wait de OData integrado en cada acción, usa estos pasos por identificador POM en vez de los genéricos del framework.
13966
13967step: hago click en el elemento SAP "{element_name}" con identificador "{identifier}"
13968descripcion: Hace click en un control SAP por POM/selector, esperando a que SAP esté listo antes y después.
13969
13970step: verifico que el elemento SAP "{element_name}" con identificador "{identifier}" está visible
13971descripcion: Verifica que un control SAP identificado por POM/selector esté visible.
13972
13973step: si existe el elemento SAP "{element_name}" con identificador "{identifier}" hago click
13974descripcion: Hace click en un control SAP solo si existe y es visible (no falla si no está). Útil para tours, cookies y avisos intermitentes.`},{id:"sap-buenas-practicas",title:"Buenas Prácticas",content:'## Buenas prácticas para SAP\n\n1. **Localizadores por id de UI5**: cuando el POM capture el id estable de UI5 (`__component0---view--controlId`), úsalo — es el selector más confiable. Los pasos SAP lo aceptan vía POM.\n2. **Espera antes de aserciones**: intercala `espero a que SAP termine de cargar` después de acciones que disparan OData.\n3. **Iframes de Fiori**: el Launchpad clásico embebe apps en iframes. Los pasos de app respetan el iframe activo; los pasos del shell (`... de Fiori`) operan sobre el shell. Usa `cambio al iframe ...` si tu app está embebida.\n4. **Condicionales para tours/avisos**: usa `si existe el elemento SAP ... hago click` para diálogos intermitentes (tours de bienvenida, cookies).\n5. **Combina con pasos genéricos**: navegación (`voy a la url`), ventanas (`intento cambiar a la ventana ...`), evidencias (`* evidencia`) y aserciones de texto (`debería ver el texto`) siguen siendo genéricos — úsalos junto a los pasos SAP.\n\n### Distinción clave: pasos SAP vs genéricos\n\n| Situación | Usa |\n|---|---|\n| Click en control UI5 con wait de OData | `hago click en el elemento SAP "X" con identificador "Y"` |\n| Click en elemento HTML normal | `hago click en el elemento "X" con identificador "Y"` (genérico) |\n| Escribir en input UI5 | `escribo "X" en el input SAP "Y" con identificador "Z"` |\n| Navegar a una URL | `voy a la url "..."` (genérico) |\n| Cambiar de ventana/pestaña | `intento cambiar a la ventana ...` (genérico) |\n\n### Referencia completa\n\nEl catálogo SAP se genera desde las definiciones reales del framework (`sap_steps.py`). 
13974Cada paso admite el prefijo opcional `que` para encadenar en `And`/`Y`.'}]},{id:"haka-ui",title:"Haka UI",group:"Herramientas Haka",icon:"",topics:[{id:"hakaui-descripcion",title:"Descripción General",content:`## Haka UI — Interfaz Gráfica Local
13975
13976Haka UI es una interfaz web local integrada al framework que permite gestionar visualmente tu proyecto de pruebas. Incluye 7 módulos: Dashboard, Features, Page Objects, Runner, Reportes, Configuración e Integraciones.
13977
13978### Características Principales
13979
13980- **Sin instalación adicional**: viene empaquetada con el framework
13981- **Comando único**: se lanza con \`haka-ui\` desde cualquier proyecto (alias: \`hakalab-ui\`)
13982- **Dark theme**: interfaz oscura profesional con acentos cyan
13983- **Sidebar colapsable**: reduce a iconos para maximizar espacio de trabajo
13984- **Logo personalizable**: coloca tu logo en \`public/logo.png\`
13985- **SPA routing**: navega directamente por URL (ej: \`localhost:8787/features\`)
13986- **API documentada**: Swagger disponible en \`/api/docs\`
13987
13988### Arquitectura
13989
13990- **Backend**: FastAPI (Python) — lee/escribe archivos del proyecto
13991- **Frontend**: Vite + React — interfaz SPA empaquetada en \`dist/\`
13992- **Puerto**: 8787 por defecto
13993- **Sin base de datos**: todo se lee/escribe directamente en los archivos del proyecto`},{id:"hakaui-instalacion",title:"Instalación y Uso",content:"## Requisitos\n\n- Haka Playwright Engine instalado (`pip install haka-playwright-engine`)\n- `fastapi` y `uvicorn` (incluidos automáticamente con el framework desde v1.4.28)\n\n## Lanzamiento\n\n```bash\n# Desde el directorio de tu proyecto (con venv activado si aplica)\nhaka-ui\n```\n\n> El comando `hakalab-ui` sigue funcionando como alias por compatibilidad, pero `haka-ui` es el nombre recomendado (homologado con `haka-init`, `haka-run`, `haka-agent`, etc.).\n\nEl servidor se levanta en `http://localhost:8787` y abre el navegador automáticamente.\n\n## Opciones de Línea de Comandos\n\n| Opción | Descripción | Default |\n|--------|-------------|---------|\n| `--port` | Puerto del servidor | 8787 |\n| `--path` o `-p` | Ruta al directorio del proyecto | Directorio actual |\n| `--no-browser` | No abrir el navegador automáticamente | false |\n\n```bash\n# Ejemplos\nhaka-ui --port 9000\nhaka-ui --path /ruta/a/mi/proyecto\nhaka-ui --no-browser\n```"},{id:"hakaui-dashboard",title:"Módulo: Dashboard",content:`## Dashboard
13994
13995Vista general del proyecto con métricas de la última ejecución.
13996
13997### Contenido
13998
13999- **Cards de resumen**: cantidad de Features, Scenarios y JSON POMs del proyecto
14000- **Última ejecución**: fecha, duración, navegador usado
14001- **Gráficos donut**: porcentaje de éxito para Scenarios y Steps
14002- **Barras de progreso**: distribución passed/failed/skipped
14003
14004### Fuente de Datos
14005
14006Los gráficos se generan desde el último archivo JSON en \`reports/html-reports/\`. Si no hay reportes, solo se muestran las cards de conteo.`},{id:"hakaui-features",title:"Módulo: Features",content:`## Features
14007
14008Gestión completa de archivos \`.feature\` con vista visual por escenarios.
14009
14010### Vista General
14011
14012- Features agrupados por **carpeta** del filesystem
14013- Carpetas colapsables con conteo de features
14014- **Filtro** por nombre de feature o tag
14015- Crear carpetas, mover features entre carpetas
14016- **Tag de grupo**: seleccionar múltiples features y aplicar un tag a nivel Feature
14017
14018### Vista por Escenarios
14019
14020Al seleccionar un feature, se parsea y muestra cada escenario como una **card individual** con:
14021
14022- Tags del scenario (badges)
14023- Tipo: Scenario o Scenario Outline
14024- Pasos con syntax highlighting (Given/When/Then en colores)
14025- Tabla de Examples (para Outlines)
14026- Botón **"Editar con Builder"** por escenario
14027- Botón **"Editar todo (código)"** para edición libre del feature completo
14028
14029### Crear Feature
14030
14031- Nombre + Tags + Carpeta destino (si hay carpetas)
14032- Se crea el archivo en el filesystem del proyecto
14033
14034### Scenario Builder
14035
14036Modal split-panel (60% editor / 40% catálogo):
14037
14038**Panel izquierdo (editor):**
14039- Título y tags del scenario
14040- Toggle tipo: Scenario / Scenario Outline
14041- Lista de pasos con controles (✎ editar, ↑↓ mover, ✕ eliminar)
14042- Tabla de Examples: crear tabla, agregar/eliminar columnas y filas, editar headers y celdas
14043
14044**Panel derecho (catálogo):**
14045- **Buscador** que filtra en tiempo real todo el catálogo
14046- +700 pasos organizados por categoría (Web, API REST, Base de Datos, Gen AI, Performance, Sesiones)
14047- Badge **"usado en tus features"** para pasos ya utilizados en el proyecto
14048- Al agregar un paso con parámetros, se abre un formulario inline
14049
14050**Selector de localizadores (POM):**
14051- Para parámetros de tipo \`identifier\`, aparece un botón **"POM"**
14052- Abre un modal dedicado con:
14053  - Buscador de localizadores
14054  - Lista de JSON POMs expandibles con sus localizadores
14055  - Botón **"+ Nuevo"** para crear un localizador inline (seleccionar POM, nombre, selector)
14056  - Click en un localizador para usarlo: se inserta como \`$.NOMBRE.localizador\``},{id:"hakaui-poms",title:"Módulo: Page Objects",content:`## Page Objects (JSON POMs)
14057
14058Visualización y edición de los archivos de localizadores.
14059
14060### Vista de Lista
14061
14062- Cards compactas por cada archivo JSON POM
14063- Nombre del archivo + cantidad de localizadores
14064- Click para abrir el editor
14065
14066### Editor
14067
14068- Lista de localizadores (nombre → selector)
14069- Editor JSON para edición directa
14070- Crear nuevos POMs
14071- Los cambios se guardan directamente en el filesystem`},{id:"hakaui-runner",title:"Módulo: Ejecutar",content:`## Runner (Ejecutar)
14072
14073Ejecución visual de pruebas con selección de tags.
14074
14075### Selección de Tags
14076
14077- Tags agrupados por nivel: **Feature** (cyan) y **Scenario** (naranja)
14078- **Buscador** que filtra por nombre de tag, nombre de scenario O nombre de feature
14079- Checkbox para seleccionar múltiples tags
14080- Hover muestra qué scenarios ejecutará cada tag
14081- Contador total de scenarios a ejecutar
14082
14083### Configuración de Ejecución
14084
14085- Selector de **navegador**: Chrome, Firefox, WebKit
14086- **Headless**: checkbox para ejecutar sin ventana
14087- Botón **Ejecutar**
14088
14089### Flujo de Ejecución (Modal)
14090
14091- Botón "Flujo de Ejecución" muestra un modal con el orden exacto en que behave ejecutará
14092- Expande Scenario Outlines en sus iteraciones reales
14093- Lazy rendering para soportar 5000+ escenarios
14094
14095### Salida en Tiempo Real
14096
14097- Cards por escenario con estado (✓ passed / ✕ failed)
14098- Pasos individuales con estado
14099- Mensaje de error para pasos fallidos
14100- Detección automática de **virtualenv** del proyecto (\`venv/\`, \`.venv/\`, \`env/\`)
14101- Usa \`venv/bin/python -m behave\` para ejecutar con las dependencias correctas`},{id:"hakaui-reportes",title:"Módulo: Reportes",content:`## Reportes
14102
14103Visor de reportes HTML y JSON de ejecuciones pasadas.
14104
14105### Lista de Reportes
14106
14107- Reportes agrupados por **ejecución** (timestamp)
14108- Badges de tipo: JSON / HTML
14109- Tamaño del archivo
14110- Ordenados por fecha descendente
14111
14112### Vista Resumen (JSON)
14113
14114- Info de ejecución: duración, navegador, ambiente, hora inicio
14115- **3 cards** con porcentaje de éxito: Features, Scenarios, Steps
14116- Detalle expandible: Feature → Scenario → Step
14117- Iconos de estado (✓ ✕ ⊘)
14118- Botón 📷 en pasos con screenshot — abre modal con la imagen
14119- Mensaje de error para pasos fallidos
14120
14121### Vista HTML
14122
14123- Iframe con el reporte HTML completo renderizado
14124- Altura 70vh, ancho completo`},{id:"hakaui-config",title:"Módulo: Configuración",content:`## Configuración
14125
14126Editor visual del archivo \`.env\` del proyecto.
14127
14128### Secciones
14129
14130Las ~120 variables se organizan en secciones colapsables:
14131- Navegador y Pruebas Web
14132- Rutas y Directorios
14133- Funcionalidades (screenshots, video, cleanup)
14134- Gemini AI
14135- Validación Semántica
14136- Jira / Xray
14137- Cassini (Haka Lens)
14138- Salesforce
14139- Variables de Prueba
14140- Integración con Test Managers
14141
14142### Características
14143
14144- **Booleans** se muestran como combobox (select true/false)
14145- **Strings** se muestran como campos editables
14146- **Tooltip con ?** en cada variable explicando su función
14147- Botón **Guardar** actualiza directamente el \`.env\` del proyecto
14148- Indicadores visuales: "Sin guardar" (naranja), "Guardado" (verde)`},{id:"hakaui-integraciones",title:"Módulo: Integraciones",content:`## Integraciones
14149
14150Editores visuales para configuraciones de integraciones externas. Organizado en pestañas.
14151
14152### Jira
14153
14154- Campos booleanos: adjuntar HTML, video, screenshots, comentar resultado, crear issue on failure, vincular bug con tags
14155- Campos de texto: tipo de issue, tipo de vínculo
14156- Mapeo de tags con campos personalizados por tipo de issue
14157
14158### Cassini (Haka Lens)
14159
14160- Variables \`CASSINI_*\` del \`.env\` con detección automática de tipo (bool/string)
14161- Tooltips explicativos por variable
14162
14163### CI/CD
14164
14165- Lista de workflows de GitHub Actions encontrados en \`.github/workflows/\` (solo lectura)
14166
14167### Reportes (report_config.json)
14168
14169- **Información del Reporte**: título, ingeniero, producto, empresa, versión, ambiente
14170- **Logos**: preview de imagen + upload (conversión a base64 client-side) + campos alt y width. Permite cargar PNG/JPG/SVG/WebP hasta 500KB.
14171- **Estilos**: color pickers nativos + input hex para cada color del reporte HTML (primario, secundario, accent, éxito, warning)`},{id:"hakaui-api",title:"API Backend",content:"## Endpoints de la API\n\nEl backend expone endpoints RESTful bajo `/api/`. Documentación Swagger disponible en `http://localhost:8787/api/docs`.\n\n| Prefijo | Descripción |\n|---------|-------------|\n| `/api/dashboard/summary` | Resumen del proyecto + última ejecución |\n| `/api/config/` | Lectura y escritura del .env |\n| `/api/poms/` | CRUD de JSON POMs |\n| `/api/features/` | Listado, lectura, creación, edición, tags, carpetas, used-steps |\n| `/api/runner/tags` | Tags disponibles con scenarios asociados |\n| `/api/runner/start` | Iniciar ejecución de behave |\n| `/api/runner/status/{id}` | Estado y output de ejecución en curso |\n| `/api/reports/` | Listado y lectura de reportes (JSON, HTML, screenshots) |\n| `/api/integrations/` | Lectura y escritura de configs de integraciones |\n| `/api/steps-catalog/` | Catálogo de pasos parseado desde documentación |\n\n### Notas Técnicas\n\n- El frontend se empaqueta pre-buildeado en `dist/`. No requiere Node.js en producción.\n- El catálogo de pasos se parsea en runtime desde `hakalab_framework/documentacion/INVENTARIO_PASOS_*.md`, siempre sincronizado con la versión instalada.\n- La ejecución usa el virtualenv detectado en el proyecto para ejecutar behave.\n- Las imágenes de logos se convierten a base64 client-side sin upload de archivos al servidor."}]},{id:"haka-cli",title:"CLI (Comandos)",group:"Empezar",icon:"",topics:[{id:"cli-resumen",title:"Resumen de Comandos",content:"## Los 12 comandos del framework\n\nAl instalar `haka-playwright-engine` se registran 12 comandos en tu entorno:\n\n| Comando | Para que sirve |\n|---|---|\n| `haka-init` | Crear la estructura de un proyecto nuevo |\n| `haka-run` | Ejecutar las pruebas |\n| `haka-report` | Regenerar o servir el reporte HTML |\n| `haka-steps` | Buscar en el catalogo de +1800 steps |\n| `haka-validate` | Validar estructura del proyecto y .env |\n| `haka-login` | Guardar sesiones de login (bypass 2FA/MFA) |\n| `haka-deps` | Instalar dependencias opcionales (OCR, etc.) |\n| `haka-agent` | Explorar una app con IA y generar POMs/features |\n| `haka-connector` | Servidor para grabar desde la extension de Chrome |\n| `haka-vault` | Boveda cifrada de datos de prueba (credenciales, tokens) |\n| `haka-ui` | Interfaz grafica local del proyecto |\n| `haka-mcp` | Servidor MCP para asistentes de IA |"},{id:"cli-haka-init",title:"haka-init",content:`## haka-init
14172
14173Crea la estructura de un proyecto de pruebas nuevo (o completa una existente).
14174
14175\`\`\`bash
14176haka-init                    # solo web, en el directorio actual
14177haka-init mi-suite           # en un subdirectorio nuevo
14178haka-init --jira             # web + configuracion de Jira
14179haka-init --jira --xray      # web + Jira + Xray
14180haka-init --mobile           # web + ejemplos de Mobile (Appium)
14181haka-init --api              # web + ejemplos de API REST
14182\`\`\`
14183
14184### Opciones
14185
14186| Opcion | Descripcion |
14187|---|---|
14188| \`project_name\` | Subdirectorio destino. Por defecto el directorio actual |
14189| \`--template\` | Plantilla: basic (default) o advanced |
14190| \`--force\` | Sobrescribe archivos existentes |
14191| \`--jira\` | Agrega configuracion de Jira |
14192| \`--xray\` | Agrega configuracion de Xray (implica --jira) |
14193| \`--mobile\` | Agrega ejemplos y estructura para Mobile (Appium) |
14194| \`--api\` | Agrega ejemplos de pruebas API REST |
14195
14196Los modulos (--jira, --xray, --mobile, --api) se pueden correr despues sobre un proyecto ya existente para agregar lo que falta, sin tocar lo que ya esta.`},{id:"cli-haka-run",title:"haka-run",content:`## haka-run
14197
14198Ejecuta las pruebas del proyecto con Behave.
14199
14200\`\`\`bash
14201haka-run                              # todo features/
14202haka-run --tags @smoke                # solo un tag
14203haka-run --feature login              # un feature puntual
14204haka-run --parallel --workers 8       # en paralelo
14205haka-run --browser firefox --headless
14206\`\`\`
14207
14208### Opciones
14209
14210| Opcion | Descripcion |
14211|---|---|
14212| \`--tags\` | Tag para filtrar |
14213| \`--feature\` | Nombre de un archivo .feature puntual |
14214| \`--parallel\` | Ejecuta con multiples workers |
14215| \`--workers\` | Cantidad de workers en paralelo (default: 4) |
14216| \`--list-features\` | Lista los .feature disponibles y termina |
14217| \`--browser\` | Sobrescribe BROWSER del .env |
14218| \`--headless\` | Fuerza modo headless |
14219| \`--docker\` | Preset para CI/Docker |
14220
14221### Reintentos
14222
14223Si \`RETRY_FAILED_SCENARIOS=true\` en el .env, reintenta automaticamente los escenarios fallidos hasta \`MAX_SCENARIO_RETRIES\` veces (default 1).`},{id:"cli-haka-steps",title:"haka-steps",content:`## haka-steps
14224
14225Explora el catalogo completo de steps del framework (mas de 1800 pasos disponibles).
14226
14227\`\`\`bash
14228haka-steps                              # resumen por categoria
14229haka-steps --search "doble click"       # busqueda exacta (substring)
14230haka-steps --search "click" --category Web
14231haka-steps --suggest "clic doble"       # busqueda flexible, tolera errores
14232haka-steps --category Salesforce        # todos los steps de una categoria
14233haka-steps --generate-docs              # genera steps_documentation.md
14234\`\`\`
14235
14236### Opciones
14237
14238| Opcion | Descripcion |
14239|---|---|
14240| \`--search\` | Busca por substring en el texto o la descripcion del step |
14241| \`--category\` | Filtra por categoria (Web, Validaciones, API REST, Mobile, Desktop, Base de Datos, Salesforce, Gen AI, Performance, Geolocalizacion, Condicionales, Sesiones) |
14242| \`--suggest\` | Sugiere steps por similitud (fuzzy match), tolera errores de tipeo |
14243| \`--generate-docs\` | Genera steps_documentation.md con el catalogo completo |
14244| \`--list-categories\` | Fuerza el resumen por categoria |
14245
14246Sin flags, muestra cuantos steps hay por categoria. Si --search no encuentra nada, sugiere probar con --suggest.`},{id:"cli-haka-validate",title:"haka-validate",content:`## haka-validate
14247
14248Valida la estructura del proyecto (features/, json_poms/, behave.ini) y las variables del .env contra el esquema del framework.
14249
14250\`\`\`bash
14251haka-validate                         # valida el proyecto actual
14252haka-validate --env-file .env.staging # valida un .env especifico
14253haka-validate --full                  # documentacion completa de TODAS las variables
14254haka-validate --generate-env          # genera .env.example con todas las variables
14255\`\`\`
14256
14257### Opciones
14258
14259| Opcion | Descripcion |
14260|---|---|
14261| \`--env-file\` | Archivo .env especifico a validar |
14262| \`--full\` | Muestra la documentacion completa de cada variable |
14263| \`--generate-env\` | Genera .env.example con todas las variables |`},{id:"cli-haka-login",title:"haka-login",content:'## haka-login\n\nGestiona sesiones de login guardadas, para saltarse 2FA/MFA en las ejecuciones automatizadas.\n\n```bash\nhaka-login --save admin_prod --url https://login.salesforce.com\nhaka-login --save whatsapp --url https://web.whatsapp.com --persistent\nhaka-login --list\nhaka-login --info admin_prod\nhaka-login --delete admin_prod\nhaka-login --gen-key\nhaka-login --encrypt admin_prod\n```\n\n### Opciones\n\n| Opcion | Descripcion |\n|---|---|\n| `--save` | Nombre para guardar la sesion (requiere --url) |\n| `--url` | URL de login |\n| `--browser` | Navegador: chromium (default), firefox, webkit |\n| `--timeout` | Minutos para completar el login manual (default: 5) |\n| `--persistent` | Guarda el perfil completo del navegador (WhatsApp, Signal, Telegram) |\n| `--list` | Lista las sesiones guardadas |\n| `--info` | Muestra el detalle de una sesion |\n| `--delete` | Elimina una sesion guardada |\n| `--gen-key` | Genera la clave de encriptacion de sesiones |\n| `--encrypt` / `--encrypt-all` | Encripta sesiones |\n| `--decrypt` | Desencripta una sesion |\n\nUna vez guardada, se usa en los .feature con: `Given inicio sesion guardada con el usuario "admin_prod"`'},{id:"cli-haka-deps",title:"haka-deps",content:`## haka-deps
14264
14265Gestiona dependencias opcionales del framework (OCR, extraccion avanzada de datos, performance).
14266
14267\`\`\`bash
14268haka-deps --status          # ver que esta instalado
14269haka-deps --check ocr       # verificar dependencias de un grupo
14270haka-deps --install ocr     # instalar un grupo
14271haka-deps --install all     # instalar todos los grupos opcionales
14272\`\`\`
14273
14274### Opciones
14275
14276| Opcion | Descripcion |
14277|---|---|
14278| \`--status\` | Muestra el estado de todas las dependencias opcionales |
14279| \`--check\` | Verifica que falta de un grupo especifico |
14280| \`--install\` | Instala un grupo (ocr, advanced_data, performance, o all) |`},{id:"cli-haka-report",title:"haka-report",content:`## haka-report
14281
14282Regenera o sirve el reporte de la ultima ejecucion.
14283
14284> El reporte HTML principal se genera automaticamente al terminar cada ejecucion de haka-run, con screenshots embebidos y branding personalizable. Este comando es complementario para regenerar o servir un reporte existente.
14285
14286\`\`\`bash
14287haka-report                    # genera el reporte y abre el navegador
14288haka-report --no-browser       # genera sin abrir el navegador
14289haka-report --simple           # genera un reporte HTML simple
14290haka-report --serve --port 9000 # sirve el reporte ya generado
14291haka-report --clean            # limpia reportes anteriores
14292\`\`\`
14293
14294### Opciones
14295
14296| Opcion | Descripcion |
14297|---|---|
14298| \`--serve\` | Sirve el reporte con un servidor integrado |
14299| \`--port\` | Puerto del servidor (default: 8080) |
14300| \`--simple\` | Genera un reporte HTML simple |
14301| \`--clean\` | Limpia reportes y resultados anteriores |
14302| \`--no-browser\` | No abre el navegador automaticamente |`},{id:"cli-haka-vault",title:"haka-vault",content:`## haka-vault
14303
14304Boveda cifrada de datos de prueba. Almacena credenciales, tokens, RUTs y cualquier dato sensible de forma segura en el repositorio.
14305
14306El archivo \`.haka_vault\` se cifra con AES-256 y va al repo sin riesgo. Sin la clave, es ilegible. La clave vive en \`.haka_session_key\` (fuera del repo) o en la variable de entorno \`HAKA_SESSION_KEY\` (para CI/CD).
14307
14308\`\`\`bash
14309# Inicializar el vault en el proyecto
14310haka-vault init
14311
14312# Agregar un dato (formato: seccion.clave valor)
14313haka-vault set login_admin.usuario [email protected]
14314haka-vault set login_admin.password MiClave123
14315
14316# Obtener un dato
14317haka-vault get login_admin.usuario
14318
14319# Ver secciones y sus claves
14320haka-vault list
14321
14322# Exportar el vault descifrado (solo debug)
14323haka-vault export
14324
14325# Eliminar un dato o seccion
14326haka-vault delete login_admin.password
14327haka-vault delete-section login_admin
14328\`\`\`
14329
14330### Uso en features
14331
14332\`\`\`gherkin
14333Scenario: Login con datos del vault
14334  Given cargo credenciales del vault "login_admin"
14335  And voy a la url "\${url}"
14336  When relleno el campo "Email" con "\${usuario}" con identificador "$.LOGIN.input_email"
14337  And relleno el campo "Password" con "\${password}" con identificador "$.LOGIN.input_password"
14338  Then debería ver el elemento "Dashboard" con identificador "$.DASHBOARD.contenedor"
14339\`\`\`
14340
14341Tambien puedes cargar un campo especifico:
14342
14343\`\`\`gherkin
14344Given cargo el campo "usuario" del vault "login_admin" en la variable "mi_user"
14345\`\`\`
14346
14347### CI/CD
14348
14349En pipelines, la clave se pasa como un unico secret:
14350
14351\`\`\`yaml
14352# GitHub Actions
14353env:
14354  HAKA_SESSION_KEY: \${{ secrets.HAKA_SESSION_KEY }}
14355
14356# GitLab CI
14357variables:
14358  HAKA_SESSION_KEY: $HAKA_VAULT_KEY
14359\`\`\`
14360
14361### Opciones
14362
14363| Opcion | Descripcion |
14364|---|---|
14365| \`init\` | Inicializa el vault (genera clave + archivo cifrado) |
14366| \`set <seccion.clave> <valor>\` | Agrega o actualiza un dato |
14367| \`get <seccion.clave>\` | Obtiene un dato (muestra en terminal) |
14368| \`list\` | Lista todas las secciones y sus claves |
14369| \`delete <seccion.clave>\` | Elimina una clave |
14370| \`delete-section <seccion>\` | Elimina una seccion completa |
14371| \`export\` | Muestra el vault descifrado en JSON (solo debug) |
14372
14373### Seguridad
14374
14375- Cifrado AES-256-GCM en reposo
14376- La clave nunca va al repositorio (\`.haka_session_key\` esta en \`.gitignore\`)
14377- Cumple principios de la Ley 21.719: minimizacion, cifrado, accountability
14378- Compatible con \`:::ocultar\` para triple proteccion (repo + reporte + screenshot)`}]},{id:"haka-mcp",title:"Haka MCP",group:"Herramientas Haka",icon:"",topics:[{id:"mcp-descripcion",title:"Descripcion General",content:`## Haka MCP - El proyecto dentro de tu asistente de IA
14379
14380Haka MCP es un servidor Model Context Protocol (MCP) que expone un proyecto Haka Playwright Engine (features, catalogo de steps, POMs, reportes) a cualquier asistente de IA compatible: Kiro, Claude Desktop, Cursor, Windsurf, etc.
14381
14382En vez de describir manualmente que steps existen, copiar y pegar el contenido de un reporte, o salir del chat a correr \`haka-steps --search\`, el asistente puede invocar estas herramientas directamente durante la conversacion.
14383
14384### Requisitos
14385
14386- Haka Playwright Engine instalado (Python 3.10 o superior)
14387- El servidor MCP se instala automaticamente con el framework
14388
14389\`\`\`bash
14390pip install haka-playwright-engine
14391python -m playwright install chromium
14392\`\`\``},{id:"mcp-configuracion",title:"Configuracion",content:`## Configuracion del servidor MCP
14393
14394Registra el servidor en el mcp.json de tu asistente:
14395
14396\`\`\`json
14397{
14398  "mcpServers": {
14399    "haka-engine": {
14400      "command": "/ruta/a/tu-proyecto/venv/bin/haka-mcp",
14401      "cwd": "/ruta/a/tu-proyecto"
14402    }
14403  }
14404}
14405\`\`\`
14406
14407>
14407 Usa la ruta absoluta al binario haka-mcp dentro del venv del proyecto. "command": "haka-mcp" sin ruta puede fallar porque el cliente MCP no hereda el PATH de tu terminal.
14408
14409### Verificacion manual
14410
14411\`\`\`bash
14412cd /ruta/a/tu-proyecto
14413haka-mcp
14414# Queda esperando en stdio. Ctrl+C para cerrar.
14415\`\`\``},{id:"mcp-tools-lectura",title:"Tools de Lectura",content:`## Tools de lectura del proyecto
14416
14417### Catalogo de steps
14418
14419**search_steps(query, category, limit)**
14420
14421Busca en el catalogo de +1800 steps por texto en el patron o la descripcion. Devuelve el patron, descripcion, parametros y keyword sugerido (Given/When/Then).
14422
14423**list_step_categories()**
14424
14425Lista las categorias disponibles (Web, API REST, Salesforce, Gen AI, Mobile, etc.).
14426
14427### Features
14428
14429**list_features()**
14430
14431Lista los archivos .feature del proyecto con su nombre, tags y cantidad de escenarios.
14432
14433**get_feature(path)**
14434
14435Lee un .feature puntual con contenido crudo y estructura parseada (tags, escenarios, steps, Examples).
14436
14437### Page Objects (POMs)
14438
14439**list_poms()**
14440
14441Lista los JSON POM del proyecto con sus localizadores.
14442
14443**get_pom(filename)**
14444
14445Lee un JSON POM puntual por nombre de archivo.
14446
14447### Reportes
14448
14449**list_reports()**
14450
14451Lista los archivos de reporte (JSON y HTML) disponibles, mas recientes primero.
14452
14453**get_last_report()**
14454
14455Devuelve el resumen del ultimo reporte: info de ejecucion, pass/fail/skipped, y detalle por feature, escenario y step con mensajes de error.
14456
14457### Validacion
14458
14459**validate_project()**
14460
14461Valida la estructura del proyecto (carpetas features/, json_poms/, behave.ini) y las variables del .env.
14462
14463### Ejecucion
14464
14465**run_tests(tags)**
14466
14467Ejecuta las pruebas con Behave, opcionalmente filtradas por tag (ej: "@smoke"). Requiere licencia configurada en el .env.`},{id:"mcp-browser-experimental",title:"Navegacion (Experimental)",content:`## Navegacion con estado - EXPERIMENTAL
14468
14469Un segundo grupo de tools que comparten un navegador vivo entre llamadas: abrir, navegar, ver la pagina, actuar sobre un elemento y cerrar.
14470
14471> Estas tools son experimentales. Los escenarios que se lleguen a escribir quedan marcados con @borrador y requieren revision humana antes de integrarse a la suite.
14472
14473### Tools de navegacion
14474
14475| Tool | Descripcion |
14476|---|---|
14477| \`browser_open(headless)\` | Abre el navegador y empieza la sesion |
14478| \`browser_navigate(url)\` | Navega a una URL |
14479| \`browser_snapshot(limit)\` | Captura los elementos interactivos con selectores verificados |
14480| \`browser_click(key)\` | Hace click en un elemento y observa el efecto |
14481| \`browser_fill(key, value)\` | Rellena un campo |
14482| \`browser_select_option(key, value, label)\` | Selecciona una opcion de un select |
14483| \`browser_check(key, checked)\` | Marca o desmarca un checkbox |
14484| \`browser_save_selectors(keys)\` | Persiste los selectores verificados al JSON POM |
14485| \`browser_draft_scenario(intent)\` | Escribe las acciones como escenario .feature @borrador |
14486| \`browser_close()\` | Cierra la sesion |
14487
14488### Ejemplo de flujo
14489
14490\`\`\`
14491browser_open(headless=True)
14492browser_navigate("https://miapp.test/contacto")
14493browser_snapshot()
14494browser_fill("input_nombre", "Ana")
14495browser_snapshot()
14496browser_fill("input_email", "[email protected]")
14497browser_snapshot()
14498browser_click("btn_enviar")
14499browser_save_selectors()
14500browser_draft_scenario("Enviar el formulario de contacto")
14501browser_close()
14502\`\`\`
14503
14504El .feature queda en features/generated/ con tag @borrador, y los selectores en json_poms/.`}]},{id:"privacidad-oculto",title:"Privacidad (:::oculto)",group:"Fundamentos",icon:"",topics:[{id:"priv-concepto",title:"Concepto",content:`## Privacidad en Screenshots y Reportes
14505
14506Los screenshots y el texto de los pasos en reportes HTML pueden contener datos personales visibles: RUTs, correos, tarjetas. Si el reporte se comparte, esos datos quedan expuestos.
14507
14508**Solucion:** Agregar \`:::oculto\` al final de cualquier localizador en el JSON POM. El framework aplica doble redactado:
14509
14510- **En screenshots**: pinta un rectangulo negro sobre el elemento antes de guardar el PNG.
14511- **En el texto del reporte**: reemplaza el valor por \`***\` en la linea del paso.
14512
14513**El dato nunca llega al disco ni al reporte.** El test sigue funcionando normalmente.`},{id:"priv-uso",title:"Uso",content:`## Como usar :::oculto
14514
14515En tu JSON POM, agrega \`:::oculto\` o \`:::ocultar\` al selector del campo sensible:
14516
14517\`\`\`json
14518{
14519  "input_rut": "#rut-field:::oculto",
14520  "input_correo": "role=textbox[name='Correo']:::oculto",
14521  "input_tarjeta": "[data-testid='card-number']:::oculto",
14522  "btn_enviar": "#submit"
14523}
14524\`\`\`
14525
14526No hay variables de entorno que configurar ni codigo que tocar. Se aceptan ambas variantes.
14527
14528### Que pasa internamente
14529
145301. \`element_locator\` detecta \`:::oculto\` al final del selector
145312. Recorta el sufijo para Playwright (\`#rut-field\`)
145323. Registra el selector en la lista de elementos a redactar
145334. Al tomar screenshot: obtiene \`bounding_box()\` de cada selector registrado
145345. Dibuja rectangulos negros con Pillow sobre esas areas
145356. El PNG guardado en disco ya NO contiene el dato visible
145367. En el reporte: \`relleno el campo "RUT" con "19595225-6"\` se muestra como \`relleno el campo "RUT" con "***"\`
14537
14538### Requisitos
14539
14540- Pillow (incluido en extras \`[ocr]\` y \`[full]\`). Si no esta instalado, avisa una vez y guarda sin redactar.
14541- Funciona con CSS, XPath, role y text; con fallbacks; con screenshots de fallo, por step y manuales.`},{id:"priv-combinaciones",title:"Combinacion con Vault",content:`## Triple Proteccion
14542
14543Combinando \`:::oculto\` con el Haka Vault y Scenario Outline:
14544
14545| Capa | Protege | Mecanismo |
14546|------|---------|-----------|
14547| Haka Vault | El repositorio | Datos cifrados con AES-256, nunca en texto plano |
14548| \`:::oculto\` | El reporte HTML | Rectangulo negro sobre screenshots + texto \`***\` en pasos |
14549| Scenario Outline | El .feature | Datos en la tabla, no en los steps, facil de ofuscar |
14550
14551### Ejemplo completo
14552
14553\`\`\`gherkin
14554Feature: Login seguro
14555
14556  Scenario: Ingresar con credenciales del vault
14557    Given cargo credenciales del vault "login_prod"
14558    And voy a la url "\${url}"
14559    When relleno el campo "RUT" con "\${rut}" con identificador "$.LOGIN.input_rut"
14560    And relleno el campo "Password" con "\${password}" con identificador "$.LOGIN.input_pass"
14561    And hago click en el elemento "Ingresar" con identificador "$.LOGIN.btn_login"
14562    Then debería ver el elemento "Dashboard" con identificador "$.DASHBOARD.contenedor"
14563\`\`\`
14564
14565Con el POM:
14566\`\`\`json
14567{
14568  "input_rut": "#rut:::oculto",
14569  "input_pass": "#password:::oculto",
14570  "btn_login": "#btn-login"
14571}
14572\`\`\`
14573
14574Resultado: el RUT y password no aparecen ni en el repo (vault), ni en el screenshot (:::oculto), ni en el reporte (texto enmascarado).`}]},{id:"haka-connector",title:"Haka Connector",group:"Herramientas Haka",icon:"",topics:[{id:"connector-concepto",title:"Concepto",content:`## Haka Connector — Grabar desde el Navegador
14575
14576Extension de Chrome MV3 + servidor local que graba la interaccion del QA en **su propio navegador con su sesion activa** y genera el \`.feature\` + POM automaticamente.
14577
14578A diferencia de Haka Agent (que explora solo), el Connector graba lo que hace la persona. No necesitas repetir el login ni abrir un navegador limpio — se graba a mitad de un flujo largo.
14579
14580### Arquitectura
14581
14582- **Extension Chrome**: captura clicks, inputs, selects, checks. Verifica unicidad de selectores en el DOM real.
14583- **Servidor Python** (\`haka-connector\`): traduce acciones a steps Gherkin, genera POM con \`ElementIndex\`, acumula escenarios con \`ArtifactGenerator\`.
14584- **Compatibilidad**: se negocia por numero de protocolo entre extension y servidor.`},{id:"connector-instalacion",title:"Instalacion y Uso",content:`## Instalacion
14585
14586\`\`\`bash
14587pip install 'haka-playwright-engine[connector]'
14588\`\`\`
14589
14590Esto instala FastAPI + uvicorn para el servidor. La extension de Chrome se descarga por separado.
14591
14592## Uso
14593
14594\`\`\`bash
14595# 1. Iniciar el servidor
14596haka-connector
14597
14598# 2. Abrir Chrome y activar la extension (panel lateral derecho)
14599# 3. Navegar normalmente e interactuar con la app
14600# 4. La extension captura cada accion con selector verificado
14601# 5. Al terminar, el servidor genera el .feature + POM
14602\`\`\`
14603
14604### Que genera
14605
14606- \`features/generated/grabacion_TIMESTAMP.feature\` — Escenario Gherkin con steps reales
14607- \`json_poms/PAGINA.json\` — Selectores verificados contra el DOM
14608
14609### Soporte de iframes
14610
14611El content script corre en todos los frames. El traductor inserta \`cambio al iframe por src que contiene\` y \`regreso al frame padre\` donde hagan falta.
14612
14613### Verificacion
14614
14615Los features generados se ejecutan con \`haka-run\`: 0 undefined (porque los steps existen en el catalogo) y 0 failed (porque los selectores son reales).`}]},{id:"web-moderna",title:"Web Moderna (SPA)",group:"Tipos de Prueba",icon:"",topics:[{id:"wm-descripcion",title:"Descripcion",content:`## Steps para Componentes Web Modernos
14616
1461759 steps para elementos que las apps SPA (React, Angular, Vue, Material UI, Ant Design, Vuetify) usan masivamente y que NO son HTML nativo.
14618
14619Modulo: \`modern_web_steps.py\`
14620
14621Todos los steps respetan el iframe activo y usan la cascada de fallbacks del POM.`},{id:"wm-dropdowns",title:"Dropdowns y Autocomplete",content:'## Dropdowns personalizados\n\nPara dropdowns de Material UI, React Select, PrimeNG, etc. que NO son `<select>`:\n\n| Step | Descripcion |\n|---|---|\n| `las opciones del dropdown "{nombre}" deberian ser "{opciones}" con identificador "{id}"` | Verifica opciones exactas (separadas por coma) |\n| `las opciones del dropdown "{nombre}" deberian contener "{opciones}" con identificador "{id}"` | Verifica que contenga al menos las indicadas |\n| `las sugerencias del autocompletable "{nombre}" deberian contener "{esperadas}" con identificador "{id}"` | Verifica sugerencias visibles |\n\n```gherkin\nWhen relleno el campo "Ciudad" con "San" con identificador "$.FORM.ciudad"\nThen las sugerencias del autocompletable "Ciudad" deberian contener "Santiago,San Fernando" con identificador "$.FORM.ciudad"\n```'},{id:"wm-componentes",title:"Componentes UI",content:'## Multi-select, Chips, Sliders, Tabs, Acordeones\n\n| Step | Descripcion |\n|---|---|\n| `agrego la opcion "{opcion}" al multiselect "{nombre}" con identificador "{id}
14621"` | Selecciona opcion en multi-select |\n| `remuevo la opcion "{opcion}" del multiselect "{nombre}" con identificador "{id}"` | Quita chip/tag |\n| `las opciones seleccionadas del multiselect "{nombre}" deberian ser "{esperadas}"` | Verifica chips |\n| `muevo el slider "{nombre}" al valor "{valor}" con identificador "{id}"` | Ajusta slider |\n| `el valor del slider "{nombre}" deberia ser "{valor}"` | Verifica slider |\n| `selecciono la pestana "{nombre}" con identificador "{id}"` | Activa tab |\n| `la pestana activa deberia ser "{nombre}"` | Verifica tab activo |\n| `expando el acordeon "{nombre}" con identificador "{id}"` | Abre acordeon (idempotente) |\n| `el acordeon "{nombre}" deberia estar expandido` | Verifica estado |\n| `activo el toggle "{nombre}" con identificador "{id}"` | Enciende toggle switch |\n| `desactivo el toggle "{nombre}" con identificador "{id}"` | Apaga toggle switch |'},{id:"wm-notificaciones",title:"Notificaciones y Progreso",content:'## Toasts, Badges, Barras de Progreso\n\n| Step | Descripcion |\n|---|---|\n| `deberia aparecer un toast con el mensaje "{texto}"` | Verifica toast/notification |\n| `el toast deberia desaparecer en {N}
14621 segundos` | Espera desaparicion |\n| `no deberia haber toasts visibles` | Verifica ausencia |\n| `el badge "{nombre}" deberia mostrar "{valor}"` | Verifica contador de badge |\n| `espero a que la barra de progreso llegue al 100%` | Espera progress bar |\n\n## Datepicker, Color Picker, Rich Text\n\n| Step | Descripcion |\n|---|---|\n| `selecciono la fecha "{dd-mm-yyyy}" en el datepicker "{nombre}" con identificador "{id}"` | Para datepickers no nativos |\n| `selecciono el color "{#hex}" en el color picker "{nombre}"` | Seleccion de color |\n| `escribo "{texto}" en el editor de texto enriquecido "{nombre}" con identificador "{id}"` | Quill, TinyMCE, CKEditor, ProseMirror |\n| `el contenido del editor "{nombre}" deberia contener "{texto}"` | Verifica contenido |\n\n## Otros\n\n| Step | Descripcion |\n|---|---|\n| `la cantidad de elementos visibles "{nombre}" deberia ser {N}` | Conteo exacto |\n| `deberia haber al menos {N} elementos visibles "{nombre}"` | Conteo minimo |\n| `copio al portapapeles el contenido del elemento "{nombre}"` | Clipboard |\n| `el portapapeles deberia contener "{texto}"` | Verifica clipboard |\n| `hago scroll infinito hasta que haya {N} elementos "{nombre}"` | Infinite scroll |\n| `los elementos "{nombre}" deberian estar en el orden "{a,b,c}"` | Verifica secuencia |\n| `el breadcrumb deberia mostrar la ruta "{Home > Seccion > Pagina}"` | Verifica breadcrumbs |\n| `el campo "{nombre}" deberia mostrar el error "{mensaje}"` | Validacion inline |'}]},{id:"api-avanzada",title:"API Avanzada",group:"Tipos de Prueba",icon:"",topics:[{id:"api-adv-descripcion",title:"Descripción",content:"## Steps Avanzados de API\n\n27 steps (54 patrones contando el al
14621ias con `que` inicial) inspirados en Karate/Judo Framework. Cubren GraphQL, retry/polling, OAuth2, match parcial, JSON Schema, WebSocket, SOAP/XML, idempotencia, paginación, latencia (p95), cookies y comparación de versiones.\n\nMódulo: `api_advanced_steps.py`"},{id:"api-adv-graphql",title:"GraphQL",content:'## GraphQL\n\n| Step | Descripción |\n|---|---|\n| `envío query GraphQL a "{url}" con query "{query}" y guardo la respuesta en la variable "{variable}"` | Ejecuta una query GraphQL |\n| `envío mutation GraphQL a "{url}" con mutation "{mutation}" y guardo la respuesta en la variable "{variable}"` | Ejecuta una mutation GraphQL |\n| `configuro variables GraphQL "{variables_json}"` | Establece variables para la próxima query/mutation |\n| `la respuesta GraphQL no debería tener errores` | Verifica que el campo `errors` esté vacío |\n| `el campo GraphQL "{path}" debería ser "{expected}"` | Valida un campo de la respuesta |\n\n```gherkin\nGiven configuro variables GraphQL \'{"userId": 1}\'\nWhen envío query GraphQL a "/graphql" con query "query($userId: Int!) { user(id: $userId) { name } }" y guardo la respuesta en la variable "user"\nThen la respuesta GraphQL no debería tener errores\nAnd el campo GraphQL "data.user.name" debería ser "Felipe"\n```'},{id:"api-adv-retry",title:"Retry, OAuth2, Encadenamiento",content:`## Retry Until (polling asíncrono)
14622
14623| Step | Descripción |
14624|---|---|
14625| \`reintento GET a "{url}" hasta que el campo "{field}" sea "{expected}" con máximo {max_retries} intentos cada {interval} segundos\` | Polling de estado por GET |
14626| \`reintento POST a "{url}" con body "{body}" hasta que el status sea {expected_status} con máximo {max_retries} intentos cada {interval} segundos\` | Polling con POST |
14627
14628## OAuth2 (client_credentials)
14629
14630| Step | Descripción |
14631|---|---|
14632| \`obtengo token OAuth2 de "{token_url}" con client_id "{client_id}" y client_secret "{client_secret}"\` | Obtiene el token y configura el Bearer automáticamente |
14633
14634## Encadenamiento de llamadas
14635
14636| Step | Descripción |
14637|---|---|
14638| \`extraigo el campo "{field}" de la última respuesta API y lo uso como "{param}" en la siguiente petición\` | Reutiliza un valor de la respuesta anterior en la siguiente request |
14639
14640\`\`\`gherkin
14641When envío petición POST a "/orders" con cuerpo '{"product":"laptop"}' y guardo la respuesta en la variable "orden"
14642And extraigo el campo "id" de la última respuesta API y lo uso como "order_id" en la siguiente petición
14643Then reintento GET a "/orders/\${order_id}" hasta que el campo "status" sea "shipped" con máximo 10 intentos cada 5 segundos
14644\`\`\``},{id:"api-adv-validaciones",title:"Match, Schema, WebSocket",content:'## Match parcial y Schema\n\n| Step | Descripción |\n|---|---|\n| `la respuesta API debería contener parcialmente "{expected_json}"` | Match parcial estilo Karate (contains) |\n| `todos los elementos del array API "{path}" deberían contener "{expected_json}"` | Match aplicado a cada elemento del array |\n| `la respuesta API debería cumplir el esquema "{schema_json}"` | Validación con JSON Schema inline |\n| `verifico idempotencia ejecutando {method} a "{url}" {times} veces y comparando respuestas` | Test de idempotencia (GET/DELETE/etc.) |\n\n## WebSocket\n\n| Step | Descripción |\n|---|---|\n| `abro conexión WebSocket a "{url}" y guardo la referencia como "{ws_name}"` | Abre y nombra la conexión |\n| `envío mensaje "{message}" por WebSocket "{ws_name}"` | Envía un mensaje |\n| `recibo mensaje del WebSocket "{ws_name}" y lo guardo en la variable "{variable}"` | Recibe y guarda el mensaje |\n| `cierro la conexión WebSocket "{ws_name}"` | Cierra la conexión |\n\n## SOAP / XML, paginación, latencia y multipart\n\n| Step | Descripción |\n|---|---|\n| `recorro todas las páginas de "{url}" con parámetro "{page_param}" y acumulo resultados en "{variable}"` | Paginación automática |\n| `envío petición SOAP a "{url}" con body XML del archivo "{file_path}" y guardo la respuesta en la variable "{variable}"` | Petición SOAP desde archivo XML |\n| `la respuesta XML debería contener el tag "{tag}" con valor "{expected}"` | Validación de XML |\n| `mido latencia de {count} peticiones GET a "{url}" y verifico que el p95 sea menor a {max_ms} ms` | Latencia p95 |\n| `envío petición multipart a "{url}" con archivo "{file_path}" campo "{field}" y datos adicionales "{extra_fields}" y guardo en "{variable}"` | Multipart con archivo + campos |\n\n## Cookies, comparación y versiones\n\n| Step | Descripción |\n|---|---|\n| `guardo las cookies de la respuesta API en la sesión` | Persiste cookies en la sesión API |\n| `verifico que la cookie "{cookie_name}
14644" existe en la sesión API` | Verifica una cookie de sesión |\n| `limpio las cookies de la sesión API` | Limpia las cookies de la sesión |\n| `comparo la respuesta API actual con la guardada en la variable "{variable}" ignorando los campos "{ignored_fields}"` | Comparación ignorando campos volátiles |\n| `verifico que el endpoint "{endpoint}" responde igual en versiones "{versions}"` | Compara la respuesta entre versiones de API |'}]},{id:"verificacion-archivos",title:"Verificacion de Archivos",group:"Tipos de Prueba",icon:"",topics:[{id:"va-descripcion",title:"Descripcion",content:`## Steps para Verificacion y Comparacion de Archivos
14645
1464632 steps para validar archivos descargados o generados por la app bajo test: exportaciones CSV, reportes PDF, descargas Excel, archivos XML, imagenes y verificacion de integridad por hash.
14647
14648Modulo: \`file_verification_steps.py\`
14649
14650Util para certificar que las exportaciones de una app generan archivos correctos (estructura, contenido, integridad).`},{id:"va-comparacion",title:"Comparacion de Archivos",content:`## Comparacion
14651
14652| Step | Descripcion |
14653|---|---|
14654| \`el archivo "{a}" deberia ser identico al archivo "{b}"\` | Byte a byte |
14655| \`el CSV "{a}" deberia coincidir con "{b}" ignorando las columnas "{cols}"\` | Ignora columnas dinamicas |
14656| \`el JSON "{a}" deberia coincidir con "{b}" ignorando los campos "{campos}"\` | Ignora campos dinamicos |
14657| \`el CSV "{a}" deberia tener la misma estructura que "{b}"\` | Solo verifica columnas |
14658
14659## PDF
14660
14661| Step | Descripcion |
14662|---|---|
14663| \`el PDF "{path}" deberia contener el texto "{texto}"\` | Busca en todas las paginas |
14664| \`el PDF "{path}
14664" no deberia contener el texto "{texto}"\` | Ausencia |
14665| \`el PDF "{path}" deberia tener {N} paginas\` | Conteo de paginas |
14666
14667## Excel
14668
14669| Step | Descripcion |
14670|---|---|
14671| \`en el archivo Excel "{path}" hoja "{hoja}" celda "{celda}" deberia contener "{valor}"\` | Valor de celda |
14672| \`el archivo Excel "{path}" hoja "{hoja}" deberia tener al menos {N} filas de datos\` | Minimo filas |
14673| \`la suma de la columna "{col}" del Excel "{path}" hoja "{hoja}" deberia ser "{total}"\` | Suma de columna |`},{id:"va-csv-xml-hash",title:"CSV, XML, Hash y Limpieza",content:`## CSV avanzado
14674
14675| Step | Descripcion |
14676|---|---|
14677| \`en el archivo CSV "{path}" la columna "{col}" deberia estar ordenada de forma "{orden}"\` | asc o desc |
14678| \`en el archivo CSV "{path}" no deberia haber filas duplicadas en la columna "{col}"\` | Unicidad |
14679| \`el archivo CSV "{path}" deberia tener exactamente las columnas "{a,b,c}"\` | Estructura |
14680| \`el promedio de la columna "{col}" en el archivo CSV "{path}" deberia ser mayor a "{N}"\` | Estadistica |
14681| \`el archivo CSV "{path}" deberia tener {N} filas de datos\` | Conteo |
14682
14683## XML
14684
14685| Step | Descripcion |
14686|---|---|
14687| \`en el archivo XML "{path}" el nodo "{xpath}" deberia contener "{valor}"\` | Valor de nodo |
14688| \`en el archivo XML "{path}" deberia haber {N} nodos "{xpath}"\` | Conteo de nodos |
14689
14690## Existencia, tamano y hash
14691
14692| Step | Descripcion |
14693|---|---|
14694| \`deberia existir el archivo "{path}"\` | Existe |
14695| \`no deberia existir el archivo "{path}"\` | No existe |
14696| \`el archivo "{path}" deberia pesar menos de {N} MB\` | Tamano maximo |
14697| \`el hash MD5 del archivo "{path}" deberia ser "{hash}"\` | Integridad MD5 |
14698| \`el hash SHA256 del archivo "{path}" deberia ser "{hash}"\` | Integridad SHA256 |
14699| \`guardo el hash SHA256 del archivo "{path}" en la variable "{var}"\` | Para comparar despues |
14700
14701## Limpieza
14702
14703| Step | Descripcion |
14704|---|---|
14705| \`elimino el archivo "{path}" si existe\` | Cleanup |
14706| \`limpio el directorio "{path}"\` | Borra contenido del directorio |`}]},{id:"screenshots-reportes",title:"Screenshots y Reportes",group:"Integraciones y Reportes",icon:"",topics:[{id:"configuracion-screenshots",title:"Configuracion de Screenshots",content:`## Captura de Screenshots
14707
14708El framework captura screenshots automaticamente durante la ejecucion de pruebas para generar evidencia visual en el reporte HTML.
14709
14710### Configuracion basica (.env)
14711
14712\`\`\`
14713# Capturar screenshot en CADA paso (genera mucha evidencia, util para debug)
14714HTML_REPORT_CAPTURE_ALL_STEPS=true
14715
14716# Solo capturar en pasos fallidos (default, menos peso)
14717HTML_REPORT_CAPTURE_ALL_STEPS=false
14718
14719# Screenshots de pagina completa o solo viewport
14720SCREENSHOT_FULL_PAGE=true
14721
14722# Directorio donde se guardan los screenshots
14723SCREENSHOTS_DIR=screenshots
14724\`\`\`
14725
14726### Comportamiento por defecto
14727
14728| Situacion | Comportamiento |
14729|---|---|
14730| Pasos fallidos | Siempre se captura screenshot automaticamente |
14731| Pasos exitosos | Solo se captura si \`HTML_REPORT_CAPTURE_ALL_STEPS=true\` |
14732| Modo API | No se capturan screenshots (se muestra request/response) |
14733| Modo Desktop | Se controla con \`DESKTOP_CAPTURE_ALL_STEPS=true\` (default: true) |
14734| Modo Mobile | Se controla con \`MOBILE_CAPTURE_ALL_STEPS=true\` (default: true) |`},{id:"screenshot-group",title:"Screenshot Group",content:`## Screenshot Group — Control de capturas en pasos compuestos
14735
14736Cuando creas un paso personalizado que agrupa varios sub-pasos con \`context.execute_steps(...)\`, por defecto el framework captura un screenshot por cada sub-paso (si la captura esta habilitada). Esto genera evidencia redundante.
14737
14738\`screenshot_group\` es un context manager que permite controlar que screenshots se conservan dentro de un paso compuesto.
14739
14740### Import
14741
14742\`\`\`python
14743from hakalab_framework import screenshot_group
14744\`\`\`
14745
14746### Politicas disponibles
14747
14748| Policy | Comportamiento |
14749|---|---|
14750| \`'all'\` | Captura todos los screenshots de cada sub-paso (por defecto) |
14751| \`'last'\` | Solo conserva el ultimo screenshot del grupo (estado final) |
14752| \`'first'\` | Solo conserva el primer screenshot del grupo (estado inicial) |
14753| \`'none'\` | No captura ningun screenshot en los sub-pasos |
14754
14755### Ejemplo: Solo el ultimo screenshot (policy='last')
14756
14757El caso mas comun. Te interesa ver como quedo la pantalla despues de completar todo el flujo.
14758
14759\`\`\`python
14760from behave import step
14761from hakalab_framework import screenshot_group
14762
14763@step('completo el formulario de login con "{usuario}" y "{clave}"')
14764def step_login(context, usuario, clave):
14765    with screenshot_group(context, policy='last'):
14766        context.execute_steps(f'''
14767            When relleno el campo "usuario" con "{usuario}" con identificador "$.LOGIN.input_user"
14768            And relleno el campo "password" con "{clave}" con identificador "$.LOGIN.input_pass"
14769            And hago click en el elemento "Login" con identificador "$.LOGIN.btn_login"
14770        ''')
14771\`\`\`
14772
14773Resultado en el reporte: se muestra 1 solo screenshot (el de despues del click en Login), no 3.
14774
14775### Ejemplo: Solo el primer screenshot (policy='first')
14776
14777Util cuando quieres capturar el estado inicial antes de que el flujo modifique la pantalla.
14778
14779\`\`\`python
14780@step('verifico y limpio el carrito de compras')
14781def step_limpiar_carrito(context):
14782    with screenshot_group(context, policy='first'):
14783        context.execute_steps('''
14784            When hago click en el elemento "Carrito" con identificador "$.HEADER.btn_carrito"
14785            And hago click en el elemento "Vaciar" con identificador "$.CARRITO.btn_vaciar"
14786            And hago click en el elemento "Confirmar" con identificador "$.MODAL.btn_confirmar"
14787        ''')
14788\`\`\`
14789
14790Resultado en el reporte: se muestra 1 screenshot (despues de abrir el carrito, antes de vaciarlo).
14791
14792### Ejemplo: Sin screenshots (policy='none')
14793
14794Para pasos auxiliares que no aportan evidencia visual (setup de datos, limpieza, navegacion intermedia).
14795
14796\`\`\`python
14797@step('preparo los datos de prueba del usuario "{email}"')
14798def step_preparar_datos(context, email):
14799    with screenshot_group(context, policy='none'):
14800        context.execute_steps(f'''
14801            Given voy a la url "https://admin.test/users"
14802            When relleno el campo "buscar" con "{email}" con identificador "$.ADMIN.input_search"
14803            And hago click en el elemento "Buscar" con identificador "$.ADMIN.btn_search"
14804            And hago click en el elemento "Reset" con identificador "$.ADMIN.btn_reset"
14805        ''')
14806\`\`\`
14807
14808Resultado en el reporte: no se captura ningun screenshot de estos sub-pasos.
14809
14810### Ejemplo: Todos los screenshots (policy='all')
14811
14812Es el comportamiento por defecto. No necesitas usar \`screenshot_group\` para esto, pero puedes ser explicito.
14813
14814\`\`\`python
14815@step('realizo el flujo critico de pago')
14816def step_pago(context):
14817    with screenshot_group(context, policy='all'):
14818        context.execute_steps('''
14819            When selecciono la opcion "Tarjeta" del campo "metodo_pago" con identificador "$.PAGO.select_metodo"
14820            And relleno el campo "numero" con "4111111111111111" con identificador "$.PAGO.input_numero"
14821            And hago click en el elemento "Pagar" con identificador "$.PAGO.btn_pagar"
14822        ''')
14823\`\`\`
14824
14825Resultado en el reporte: se captura un screenshot por cada sub-paso (3 en total).
14826
14827### Anidamiento
14828
14829\`screenshot_group\` soporta anidamiento. Si un paso compuesto llama a otro paso compuesto que tambien usa \`screenshot_group\`, cada uno respeta su propia policy de forma independiente.
14830
14831### Retrocompatibilidad
14832
14833Si no usas \`screenshot_group\`, el comportamiento es identico al anterior. Los proyectos existentes no necesitan cambios.`},{id:"reportes-html",title:"Reportes HTML",content:`## Reportes HTML
14834
14835### Campos personalizados en el header
14836
14837El reporte HTML muestra una barra con informacion del proyecto (Ingeniero, Fecha, Producto, Empresa, Version, Ambiente). Puedes agregar campos adicionales configurandolos en el \`report_config.json\`:
14838
14839\`\`\`json
14840{
14841  "report_info": {
14842    "title": "Reporte de Pruebas",
14843    "engineer": "Felipe Farias",
14844    "execution_date": "auto",
14845    "product": "Mi App",
14846    "company": "Haka Lab",
14847    "version": "2.1.0",
14848    "environment": "QA"
14849  },
14850  "custom_fields": [
14851    {
14852      "enabled": true,
14853      "label": "Sprint",
14854      "value": "Sprint 24",
14855      "icon": "sprint-icon"
14856    },
14857    {
14858      "enabled": true,
14859      "label": "Rama",
14860      "value": "feature/login-refactor",
14861      "icon": "branch-icon"
14862    },
14863    {
14864      "enabled": true,
14865      "label": "Pipeline",
14866      "value": "CI #1482",
14867      "icon": "pipeline-icon"
14868    },
14869    {
14870      "enabled": false,
14871      "label": "Ticket",
14872      "value": "JIRA-1234",
14873      "icon": "ticket-icon"
14874    }
14875  ]
14876}
14877\`\`\`
14878
14879Los campos con \`"enabled": true\` se muestran en la barra del header junto a los campos fijos. Los que tienen \`"enabled": false\` se ignoran. Si el JSON no tiene la seccion \`custom_fields\`, el reporte se genera igual que antes.
14880
14881### Buscador y filtro de escenarios
14882
14883El reporte HTML incluye una barra de busqueda arriba de la lista de features que permite:
14884
14885- Buscar por texto: filtra escenarios cuyo nombre o tags contengan lo que escribes.
14886- Filtrar por estado: muestra solo los escenarios Passed, Failed o Skipped.
14887
14888El filtro funciona en tiempo real (mientras escribes) y es completamente client-side (no requiere servidor ni conexion). Los features que quedan sin escenarios visibles se ocultan automaticamente.
14889
14890### Atajos de teclado del reporte
14891
14892| Atajo | Accion |
14893|---|---|
14894| \`Ctrl+E\` | Expandir/contraer todos los features |
14895| \`ESC\` | Cerrar el modal de screenshot ampliado |
14896
14897### Configuracion de colores
14898
14899Los colores del reporte se configuran en la seccion \`styling\` del \`report_config.json\`:
14900
14901\`\`\`json
14902{
14903  "styling": {
14904    "primary_color": "#2c3e50",
14905    "secondary_color": "#3498db",
14906    "accent_color": "#e74c3c",
14907    "success_color": "#27ae60",
14908    "warning_color": "#f39c12"
14909  }
14910}
14911\`\`\`
14912
14913### Logos
14914
14915El reporte soporta dos logos (esquina superior izquierda y derecha):
14916
14917\`\`\`json
14918{
14919  "logos": {
14920    "primary_logo": {
14921      "enabled": true,
14922      "path": "auto",
14923      "alt": "Haka Lab",
14924      "width": "150px"
14925    },
14926    "secondary_logo": {
14927      "enabled": true,
14928      "path": "data:image/png;base64,...",
14929      "alt": "Mi Empresa",
14930      "width": "150px"
14931    }
14932  }
14933}
14934\`\`\`
14935
14936- \`"path": "auto"\` usa el logo de Haka Lab embebido.
14937- Para logos personalizados, usa una ruta de archivo o un data URI en base64.`}]}],fj=["Empezar","Fundamentos","Tipos de Prueba","Aplicaciones Empresariales","Técnicas Avanzadas","Herramientas Haka","Integraciones y Reportes"],ine="Otros";function rne(){const[t,e]=k.useState(null),[a,n]=k.useState(null),[i,r]=k.useState(""),[o,l]=k.useState(!1),c=k.useMemo(()=>{const h=new Set;
14937return nne.filter(g=>h.has(g.id)?!1:(h.add(g.id),!0))},[]);k.useEffect(()=>{document.title="Docs - Haka Playwright Engine | Haka Lab",c.length>0&&(e(c[0].id),c[0].topics.length>0&&n(c[0].topics[0].id))},[c]);const d=k.useMemo(()=>{if(!i.trim())return c;const h=i.toLowerCase();return c.map(g=>({...g,topics:g.topics.filter(y=>y.title.toLowerCase().includes(h)||y.content.toLowerCase().includes(h))})).filter(g=>g.topics.length>0)},[i,c]),u=k.useMemo(()=>{const h=new Map;for(const x of d){const v=x.group||ine,w=h.get(v)||[];w.push(x),h.set(v,w)}const g=fj.filter(x=>h.has(x)),y=[...h.keys()].filter(x=>!fj.includes(x));return[...g,...y].map(x=>({name:x,sections:h.get(x)}))},[d]),p=k.useMemo(()=>{for(const h of c){const g=h.topics.find(y=>y.id===a);if(g)return g}return null},[a,c]),m=(h,g)=>{e(h),n(g),l(!1)};return s.jsxs("div",{className:"bg-dark min-h-screen",children:[s.jsxs("div",{className:"lg:hidden sticky top-0 z-30 bg-dark/95 backdrop-blur border-b border-gray-800 px-4 py-3 flex items-center gap-3",children:[s.jsx("button",{onClick:()=>l(!o),className:"text-gray-300 hover:text-primary",children:s.jsx("svg",{className:"w-6 h-6",fill:"none",stroke:"currentColor",viewBox:"0 0 24 24",children:s.jsx("path",{strokeLinecap:"round",strokeLinejoin:"round",strokeWidth:2,d:"M4 6h16M4 12h16M4 18h16"})})}),s.jsx("h1",{className:"text-white font-semibold text-sm truncate",children:"Haka Playwright Engine - Docs"})]}),s.jsxs("div",{className:"flex",children:[o&&s.jsx("div",{className:"lg:hidden fixed inset-0 z-40 bg-black/60",onClick:()=>l(!1)}),s.jsxs("aside",{className:`
14938          fixed lg:sticky top-0 left-0 z-50 lg:z-10
14939          w-80 h-screen overflow-y-auto
14940          bg-darkGray border-r border-gray-800
14941          transition-transform duration-300
14942          ${o?"translate-x-0":"-translate-x-full lg:translate-x-0"}
14943        `,children:[s.jsxs("div",{className:"p-5 border-b border-gray-800",children:[s.jsxs(Te,{to:"/docs",className:"text-xs text-gray-400 hover:text-primary transition-colors flex items-center gap-1 mb-3",children:[s.jsx("svg",{className:"w-3 h-3",fill:"none",stroke:"currentColor",viewBox:"0 0 24 24",children:s.jsx("path",{strokeLinecap:"round",strokeLinejoin:"round",strokeWidth:2,d:"M15 19l-7-7 7-7"})}),"Volver a Docs"]}),s.jsx("h2",{className:"text-white font-bold text-lg mb-1",children:"Haka Playwright Engine"}),s.jsx("p",{className:"text-gray-400 text-xs",children:"Documentación del Framework"})]}),s.jsx("div",{className:"p-4",children:s.jsxs("div",{className:"relative",children:[s.jsx("svg",{className:"absolute left-3 top-1/2 -translate-y-1/2 w-4 h-4 text-gray-500",fill:"none",stroke:"currentColor",viewBox:"0 0 24 24",children:s.jsx("path",{strokeLinecap:"round",strokeLinejoin:"round",strokeWidth:2,d:"M21 21l-6-6m2-5a7 7 0 11-14 0 7 7 0 0114 0z"})}),s.jsx("input",{type:"text",placeholder:"Buscar en docs...",value:i,onChange:h=>r(h.target.value),className:"w-full pl-10 pr-4 py-2 bg-dark border border-gray-700 rounded-lg text-sm text-white placeholder-gray-500 focus:outline-none focus:border-primary"})]})}),s.jsx("nav",{className:"px-3 pb-6",children:u.map(h=>s.jsxs("div",{className:"mb-4",children:[s.jsx("p",{className:"px-3 pt-3 pb-1.5 text-[11px] font-bold uppercase tracking-wider text-gray-500",children:h.name}),h.sections.map(g=>{const y=i.trim()?!0:t===g.id;return s.jsxs("div",{className:"mb-1",children:[s.jsxs("button",{onClick:()=>e(t===g.id?null:g.id),className:"w-full flex items-center justify-between px-3 py-2 text-sm font-semibold text-gray-300 hover:text-white rounded-md hover:bg-dark/50 transition-colors",children:[s.jsxs("span",{className:"flex items-center gap-2",children:[s.jsx("span",{children:g.icon}),s.jsx("span",{children:g.title})]}),s.jsx("svg",{className:`w-4 h-4 transition-transform ${y?"rotate-90":""}`,fill:"none",stroke:"currentColor",viewBox:"0 0 24 24",children:s.jsx("path",{strokeLinecap:"round",strokeLinejoin:"round",strokeWidth:2,d:"M9 5l7 7-7 7"})})]}),y&&s.jsx("div",{className:"ml-4 mt-1 space-y-0.5",children:g.topics.map(x=>s.jsx("button",{onClick:()=>m(g.id,x.id),className:`w-full text-left px-3 py-1.5 text-sm rounded-md transition-colors ${a===x.id?"text-primary bg-primary/10 border-l-2 border-primary":"text-gray-400 hover:text-gray-200 hover:bg-dark/30"}`,children:x.title},x.id))})]},g.id)})]},h.name))})]}),s.jsx("main",{className:"flex-1 min-w-0 px-4 sm:px-8 lg:px-12 py-8 lg:py-12 max-w-4xl",children:p?s.jsxs("article",{children:[s.jsx("h1",{className:"text-3xl md:text-4xl font-bold text-white mb-6",children:p.title}),s.jsx("div",{className:"prose prose-invert prose-lg max-w-none docs-content",children:s.jsx(one,{content:p.content})})]}):s.jsx("div",{className:"text-center py-20",children:s.jsx("p",{className:"text-gray-400 text-lg",children:"Selecciona un tema del menú lateral"})})})]})]})}function one({content:t}){return sne(t).map((a,n)=>s.jsx(lne,{block:a},n))}function sne(t){var i;const e=[],a=t.split(`
14944`);let n=0;for(;n<a.length;){const r=a[n];if(r.startsWith("```")){const o=r.slice(3).trim(),l=[];for(n++;n<a.length&&!a[n].startsWith("```");)l.push(a[n]),n++;e.push({type:"code",lang:o,code:l.join(`
14945`)}),n++;continue}if(r.startsWith("## ")){e.push({type:"h2",text:r.slice(3)}),n++;continue}if(r.startsWith("### ")){e.push({type:"h3",text:r.slice(4)}),n++;continue}if(r.includes("|")&&n+1<a.length&&((i=a[n+1])!=null&&i.includes("---"))){const o=[];for(;n<a.length&&a[n].includes("|");)o.push(a[n]),n++;e.push({type:"table",rows:o});continue}if(r.startsWith("- ")||r.startsWith("* ")){const o=[];for(;n<a.length&&(a[n].startsWith("- ")||a[n].startsWith("* "));)o.push(a[n].slice(2)),n++;e.push({type:"list",items:o});continue}if(r.startsWith("> ")||r===">"){const o=[];for(;n<a.length&&(a[n].startsWith("> ")||a[n]===">");)o.push(a[n].replace(/^>\s?/,"")),n++;e.push({type:"quote",text:o.join(" ").trim()});continue}if(r.startsWith("step: ")){e.push({type:"step",text:r.slice(6)}),n++;continue}if(r.startsWith("descripcion: ")){e.push({type:"description",text:r.slice(13)}),n++;continue}if(r.startsWith("**")&&r.endsWith("**")){e.push({type:"bold",text:r.slice(2,-2)}),n++;continue}if(r.trim()===""||r.trim()==="---"){n++;continue}e.push({type:"paragraph",text:r}),n++}return e}function lne({block:t}){switch(t.type){case"h2":return s.jsx("h2",{className:"text-2xl font-bold text-white mt-8 mb-4",children:t.text});case"h3":return s.jsx("h3",{className:"text-xl font-semibold text-gray-200 mt-6 mb-3",children:t.text});case"bold":return s.jsx("p",{className:"font-semibold text-primary mt-4 mb-2",children:t.text});case"paragraph":return s.jsx("p",{className:"text-gray-300 mb-3 leading-relaxed",children:s.jsx(Fm,{text:t.text})});case"step":return s.jsx("div",{className:"bg-primary/5 border-l-4 border-primary px-4 py-2 my-3 rounded-r-lg",children:s.jsx("code",{className:"text-primary text-sm font-mono",children:t.text})});
14945case"description":return s.jsx("p",{className:"text-gray-400 text-sm mb-4 ml-4",children:t.text});case"quote":return s.jsx("blockquote",{className:"border-l-4 border-primary/60 bg-primary/5 px-4 py-3 my-4 rounded-r-lg text-gray-300 leading-relaxed",children:s.jsx(Fm,{text:t.text})});case"code":return s.jsxs("div",{className:"my-4 rounded-lg overflow-hidden border border-gray-700",children:[t.lang&&s.jsx("div",{className:"bg-gray-800 px-4 py-1.5 text-xs text-gray-400 border-b border-gray-700",children:t.lang}),s.jsx("pre",{className:"bg-[#0d1117] p-4 overflow-x-auto",children:s.jsx("code",{className:"text-sm text-gray-300 font-mono whitespace-pre",children:t.code})})]});case"list":return s.jsx("ul",{className:"list-disc list-inside space-y-1 text-gray-300 mb-4 ml-2",children:t.items.map((e,a)=>s.jsx("li",{children:s.jsx(Fm,{text:e})},a))});case"table":return s.jsx(cne,{rows:t.rows});default:return null}}function cne({rows:t}){if(t.length<2)return null;const e=i=>i.split("|").filter(r=>r.trim()!=="").map(r=>r.trim()),a=e(t[0]),n=t.slice(2).map(e);return s.jsx("div",{className:"overflow-x-auto my-4 rounded-lg border border-gray-700",children:s.jsxs("table",{className:"w-full text-sm",children:[s.jsx("thead",{className:"bg-gray-800",children:s.jsx("tr",{children:a.map((i,r)=>s.jsx("th",{className:"px-4 py-2 text-left text-gray-300 font-semibold",children:i},r))})}),s.jsx("tbody",{className:"divide-y divide-gray-800",children:n.map((i,r)=>s.jsx("tr",{className:"hover:bg-dark/50",children:i.map((o,l)=>s.jsx("td",{className:"px-4 py-2 text-gray-400",children:s.jsx(Fm,{text:o})},l))},r))})]})})}function Fm({text:t}){return t.split(/(`[^`]+`|\*\*[^*]+\*\*)/g).map((a,n)=>a.startsWith("`")&&a.endsWith("`")?s.jsx("code",{className:"bg-gray-800 px-1.5 py-0.5 rounded text-primary text-sm font-mono",children:a.slice(1,-1)},n):a.startsWith("**")&&a.endsWith("**")?s.jsx("strong",{className:"text-white font-semibold",children:a.slice(2,-2)},n):s.jsx("span",{children:a},n))}const qO=k.createContext(),H0="hakalab.com",dne="https://us-central1-haka-licencias-productos.cloudfunctions.net/validarLicencia",F0=["Engine Playwright","Haka AI Studio","HakaBoost","Hakabuddy","HakaPath"];function At({children:t}){const[e,a]=k.useState(null),[n,i]=k.useState(!0);k.useEffect(()=>{const c=localStorage.getItem("docs_user");if(c)try{a(JSON.parse(c))}catch{}const d=Y3(xi,u=>{var p;if(u&&((p=u.email)!=null&&p.endsWith(`@${H0}`))){const m={email:u.email,name:u.displayName,photo:u.photoURL,method:"google",productos:F0};a(m),localStorage.setItem("docs_user",JSON.stringify(m))}i(!1)});return i(!1),()=>d()},[]);const r=async()=>{const c=new Kn;c.setCustomParameters({hd:H0});const d=await cO(xi,c),u=d.user.email;if(!(u!=null&&u.endsWith(`@${H0}`)))throw await yd(xi),new Error("Solo se permiten cuentas @hakalab.com");const p={email:u,name:d.user.displayName,photo:d.user.photoURL,method:"google",productos:F0};return a(p),localStorage.setItem("docs_user",JSON.stringify(p)),p},o=async(c,d)=>{const u=await fetch(dne,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({key:d,mail:c,producto:"todos",id_app:"na"})});if(!u.ok)throw new Error("Error de conexión con el servidor");const p=await u.json();if(p.estado!=="habilitado")throw new Error(p.mensaje||"Licencia no válida");const h=(Array.isArray(p.producto)?p.producto:[p.producto]).filter(y=>F0.includes(y));if(h.length===0)throw new Error("Tu licencia no incluye acceso a documentación disponible");const g={email:c,name:p.nombre||c,empresa:p.empresa,method:"license",productos:h};return a(g),localStorage.setItem("docs_user",JSON.stringify(g)),g},l=async()=>{try{await yd(xi)}catch{}a(null),localStorage.removeItem("docs_user")};return s.jsx(qO.Provider,{value:{user:e,loading:n,loginWithGoogle:r,loginWithLicense:o,logout:l},children:t})}const Zl=()=>k.useContext(qO),go={id:"haka-automation-engine",titulo:"Curso Haka Automation Engine",descripcion:"Seis sesiones en orden, desde qué es el framework hasta ejecutar pruebas en dispositivos móviles.",sesiones:[{numero:1,id:"que-es-haka-automation-engine",titulo:"¿
14945Qué es el Haka Automation Engine?",nivel:"Introducción",duracion:"18:51",youtubeId:"lMQLdlcsebU",descripcion:"Qué resuelve el framework, cómo se compone y en qué se diferencia de automatizar con Playwright a mano.",temas:["Visión general","Arquitectura","Casos de uso"],docsLink:"/docs/haka-playwright-engine/docs"},{numero:2,id:"ambientacion-del-proyecto",titulo:"Ambientación del proyecto",nivel:"Básico",duracion:"18:45",youtubeId:"hre6R5sxTJo",descripcion:"Instalación, estructura de carpetas y configuración inicial del archivo .env para dejar el proyecto listo.",temas:["Instalación","Estructura","Configuración .env"],docsLink:"/docs/haka-playwright-engine/docs"},{numero:3,id:"primera-prueba-web",titulo:"Primera Prueba Web",nivel:"Básico",duracion:"28:29",youtubeId:"kjeDr5sxtRk",descripcion:"Escribir un escenario en Gherkin, mapear localizadores en un Page Object y ejecutar la prueba en el navegador.",temas:["Gherkin","Localizadores","Ejecución"],docsLink:"/docs/haka-playwright-engine/docs"},{numero:4,id:"pruebas-api-rest",titulo:"Pruebas de API Rest",nivel:"Intermedio",duracion:"24:44",youtubeId:"1h9J7OmNRDE",descripcion:"Peticiones HTTP, validación de respuestas y encadenamiento de datos entre pasos sin abrir el navegador.",temas:["Peticiones HTTP","Validaciones","Variables"],docsLink:"/docs/haka-playwright-engine/docs"},{numero:5,id:"ambientacion-mobile",titulo:"Ambientación Mobile",nivel:"Intermedio",duracion:"21:15",youtubeId:"6u8f75G9nnI",descripcion:"Preparar el entorno de pruebas móviles: Appium, dependencias y configuración del dispositivo o emulador.",temas:["Appium","Dependencias","Emulador"],docsLink:"/docs/haka-playwright-engine/docs"}
14945,{numero:6,id:"ejecucion-en-mobile",titulo:"Ejecución en Mobile",nivel:"Intermedio",duracion:"30:59",youtubeId:"vSM4jtFhUlM",descripcion:"Escribir y correr un escenario móvil, con taps, scroll y verificaciones sobre la aplicación instalada.",temas:["Taps y scroll","Verificaciones","Reportes"],docsLink:"/docs/haka-playwright-engine/docs"}]};function une(t){if(!t)return 0;const e=String(t).split(":").map(Number);return e.some(Number.isNaN)?0:e.reduce((a,n)=>a*60+n,0)}function gj(t){const e=Math.round(t/60),a=Math.floor(e/60),n=e%60;return a===0?`${n}min`:n===0?`${a}h`:`${a}h ${n}min`}function pne(t=[],e=go){let a=0,n=0;for(const i of e.sesiones){const r=une(i.duracion);a+=r,t.includes(i.id)||(n+=r)}return{total:a,restante:n}}const zO="haka-video-progress";function mne(t){try{const e=window.localStorage.getItem(`${zO}:${t}`),a=e?JSON.parse(e):[];return Array.isArray(a)?a.filter(n=>typeof n=="string"):[]}catch{return[]}}function yj(t,e){try{window.localStorage.setItem(`${zO}:${t}`,JSON.stringify(e))}catch{}}function hne({completadas:t,total:e}){const n=2*Math.PI*34,i=e>0?t/e:0;return s.jsxs("div",{className:"relative w-24 h-24 shrink-0",children:[s.jsxs("svg",{className:"w-24 h-24 -rotate-90",viewBox:"0 0 80 80","aria-hidden":"true",children:[s.jsx("circle",{cx:"40",cy:"40",r:34,fill:"none",stroke:"currentColor",strokeWidth:"5",className:"text-gray-800"}),s.jsx("circle",{cx:"40",cy:"40",r:34,fill:"none",stroke:"currentColor",strokeWidth:"5",strokeLinecap:"round",className:"text-primary transition-[stroke-dashoffset] duration-700 ease-out",strokeDasharray:n,strokeDashoffset:n*(1-i)})]}),s.jsxs("div",{className:"absolute inset-0 flex flex-col items-center justify-center",children:[s.jsx("span",{className:"text-white font-bold text-xl leading-none",children:t}),s.jsxs("span",{className:"text-gray-500 text-[11px] mt-0.5",children:["de ",e]})]})]})}function fne({sesion:t,siguiente:e,onCerrar:a,onCompletar:n,onIrSiguiente:i}){return k.useEffect(()=>{const r=l=>{l.key==="Escape"&&a()};window.addEventListener("keydown",r);const o=document.body.style.overflow;return document.body.style.overflow="hidden",()=>{window.removeEventListener("keydown",r),document.body.style.overflow=o}},[a]),s.jsx("div",{className:"fixed inset-0 z-[60] flex items-center justify-center p-4 sm:p-6 bg-black/80 backdrop-blur-sm",role:"dialog","aria-modal":"true","aria-label":`Sesión ${t.numero}: ${t.titulo}`,onClick:a,children:s.jsxs(_.div,{initial:{opacity:0,scale:.97},animate:{opacity:1,scale:1},transition:{duration:.2},className:"w-full max-w-5xl bg-darkGray border border-gray-800 rounded-2xl overflow-hidden shadow-2xl",onClick:r=>r.stopPropagation(),children:[s.jsxs("div",{className:"flex items-start justify-between gap-4 px-5 py-4 border-b border-gray-800",children:[s.jsxs("div",{className:"min-w-0",children:[s.jsxs("p",{className:"text-primary text-xs font-semibold tracking-wide",children:["SESIÓN ",t.numero]}),s.jsx("h2",{className:"text-white font-semibold text-base sm:text-lg truncate",children:t.titulo})]}),s.jsx("button",{onClick:a,"aria-label":"Cerrar reproductor",className:"text-gray-400 hover:text-white transition-colors p-1 shrink-0",children:s.jsx("svg",{className:"w-6 h-6",fill:"none",stroke:"currentColor",viewBox:"0 0 24 24",children:s.jsx("path",{strokeLinecap:"round",strokeLinejoin:"round",strokeWidth:2,d:"M6 18L18 6M6 6l12 12"})})})]}),s.jsx("div",{className:"aspect-video bg-black",children:s.jsx("iframe",{className:"w-full h-full",src:`https://www.youtube-nocookie.com/embed/${t.youtubeId}?autoplay=1&rel=0&modestbranding=1`,title:`Sesión ${t.numero}: ${t.titulo}`,allow:"accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture",allowFullScreen:!0})}),s.jsxs("div",{className:"px-5 py-4 flex flex-col sm:flex-row sm:items-center gap-3 sm:justify-between",children:[s.jsxs("button",{onClick:()=>n(t.id),className:"inline-flex items-center justify-center gap-2 px-4 py-2 rounded-lg border border-primary/40 text-primary text-sm font-medium hover:bg-primary/10 transition-colors",children:[s.jsx("svg",{className:"w-4 h-4",fill:"none",stroke:"currentColor",viewBox:"0 0 24 24",children:s.jsx("path",{strokeLinecap:"round",strokeLinejoin:"round",strokeWidth:2,d:"M5 13l4 4L19 7"})}),"Marcar como completada"]}),e&&s.jsxs("button",{onClick:()=>i(e),className:"inline-flex items-center justify-center gap-2 px-4 py-2 rounded-lg bg-primary/90 hover:bg-primary text-dark text-sm font-semibold transition-colors",children:["Siguiente: ",e.titulo,s.jsx("svg",{className:"w-4 h-4",fill:"none",stroke:"currentColor",viewBox:"0 0 24 24",children:s.jsx("path",{strokeLinecap:"round",strokeLinejoin:"round",strokeWidth:2,d:"M9 5l7 7-7 7"})})]})]})]})})}function gne(){const{user:t,logout:e}=Zl(),[a,n]=R8(),[i,r]=k.useState([]),[o,l]=k.useState(null),c=go.sesiones,d=k.useMemo(()=>c.filter(v=>v.youtubeId),[c]);k.useEffect(()=>{document.title="Video Tutoriales - Haka Automation Engine | Haka Lab",r(mne(go.id))},[]),k.useEffect(()=>{const v=a.get("v");if(!v){l(null);return}const w=c.find(S=>S.id===v&&S.youtubeId);l(w||null)},[a,c]);const u=k.useCallback(v=>{v.youtubeId&&n({v:v.id},{replace:!1})},[n]),p=k.useCallback(()=>{n({},{replace:!0})},[n]),m=k.useCallback(v=>{r(w=>{const S=w.includes(v)?w.filter(T=>T!==v):[...w,v];return yj(go.id,S),S})},[]),h=k.useCallback(v=>{r(w=>{if(w.includes(v))return w;const S=[...w,v];return yj(go.id,S),S})},[]),g=k.useCallback(v=>{const w=d.findIndex(S=>S.id===v.id);return w>=0&&d[w+1]||null},[d]),y=i.filter(v=>c.some(w=>w.id===v)).length,x=k.useMemo(()=>pne(i),[i]);return s.jsxs("div",{className:"min-h-screen bg-dark",children:[s.jsx("header",{className:"border-b border-gray-800 bg-darkGray/50 backdrop-blur sticky top-0 z-20",children:s.jsxs("div",{className:"max-w-7xl mx-auto px-4 sm:px-6 lg:px-8 py-4 flex items-center justify-between",children:[s.jsxs("div",{className:"flex items-center gap-3 min-w-0",children:[s.jsx(Te,{to:"/docs/haka-playwright-engine",className:"text-gray-400 hover:text-white transition-colors text-sm shrink-0",children:"← Volver"}),s.jsx("span",{className:"text-gray-600",children:"|"}),s.jsx("span",{className:"text-white font-semibold text-base sm:text-lg truncate",children:"Video Tutoriales"})]}),s.jsxs("div",{className:"flex items-center gap-4 shrink-0",children:[s.jsx("span",{className:"text-gray-400 text-sm hidden sm:block",children:t==null?void 0:t.email}),s.jsx("button",{onClick:e,className:"text-sm text-gray-400 hover:text-red-400 transition-colors",children:"Cerrar sesión"})]})]})}),s.jsxs("main",{className:"max-w-4xl mx-auto px-4 sm:px-6 lg:px-8 py-10 sm:py-14",children:[s.jsxs(_.div,{initial:{opacity:0,y:10}
14945,animate:{opacity:1,y:0},transition:{duration:.4},className:"flex flex-col sm:flex-row sm:items-center gap-6 mb-12",children:[s.jsxs("div",{className:"flex-1",children:[s.jsx("p",{className:"text-primary text-xs font-semibold tracking-wider mb-2",children:"RUTA DE APRENDIZAJE"}),s.jsx("h1",{className:"text-3xl sm:text-4xl font-bold text-white mb-3",children:go.titulo}),s.jsx("p",{className:"text-gray-400 leading-relaxed mb-4",children:go.descripcion}),s.jsxs("div",{className:"flex items-center gap-3 text-sm flex-wrap",children:[s.jsxs("span",{className:"text-gray-500",children:[c.length," sesiones · ",gj(x.total)," en total"]}),x.restante>0&&x.restante<x.total&&s.jsxs(s.Fragment,{children:[s.jsx("span",{className:"text-gray-700","aria-hidden":"true",children:"•"}),s.jsxs("span",{className:"text-primary font-medium",children:[gj(x.restante)," restantes"]})]}),x.restante===0&&s.jsxs(s.Fragment,{children:[s.jsx("span",{className:"text-gray-700","aria-hidden":"true",children:"•"}),s.jsx("span",{className:"text-primary font-medium",children:"Curso completado"})]})]})]}),s.jsx(hne,{completadas:y,total:c.length})]}),s.jsx("ol",{className:"relative",children:c.map((v,w)=>{const S=i.includes(v.id),T=!!v.youtubeId,P=w===c.length-1;return s.jsxs(_.li,{initial:{opacity:0,y:12},animate:{opacity:1,y:0},transition:{duration:.35,delay:Math.min(w*.06,.4)},className:"relative pl-14 sm:pl-16 pb-6 last:pb-0",children:[!P&&s.jsx("span",{"aria-hidden":"true",className:`absolute left-[19px] sm:left-[23px] top-12 bottom-0 w-0.5 rounded-full transition-colors duration-500 ${S?"bg-primary/50":"bg-gray-800"}`}),s.jsx("span",{"aria-hidden":"true",className:`absolute left-0 top-1 w-10 h-10 sm:w-12 sm:h-12 rounded-full border-2 flex items-center justify-center font-bold text-sm transition-all duration-300 ${S?"bg-primary/15 border-primary text-primary shadow-[0_0_18px_-4px_rgba(0,212,255,0.6)]":T?"bg-darkGray border-gray-700 text-gray-300":"bg-darkGray border-gray-800 text-gray-600"}`,children:S?s.jsx("svg",{className:"w-5 h-5",fill:"none",stroke:"currentColor",viewBox:"0 0 24 24",children:s.jsx("path",{strokeLinecap:"round",strokeLinejoin:"round",strokeWidth:3,d:"M5 13l4 4L19 7"})}):v.numero}),s.jsx("div",{className:`group rounded-xl border bg-darkGray transition-all duration-300 overflow-hidden ${T?"border-gray-800 hover:border-primary/50 hover:bg-darkGray/80":"border-gray-800/70 opacity-70"}`,children:s.jsxs("div",{className:"flex flex-col sm:flex-row",children:[s.jsxs("div",{className:"sm:w-56 shrink-0 relative",children:[s.jsx("div",{className:"aspect-video bg-dark/60 overflow-hidden",children:T?s.jsx("img",{src:`https://i.ytimg.com/vi/${v.youtubeId}/hqdefault.jpg`,alt:"",loading:"lazy",className:"w-full h-full object-cover transition-transform duration-500 group-hover:scale-105"}):s.jsx("div",{className:"w-full h-full flex items-center justify-center",children:s.jsx("span",{className:"text-gray-600 text-xs font-medium",children:"Próximamente"})})}),T&&s.jsx("button",{onClick:()=>u(v),"aria-label":`Reproducir sesión ${v.numero}: ${v.titulo}`,className:"absolute inset-0 flex items-center justify-center bg-dark/40 opacity-0 group-hover:opacity-100 focus:opacity-100 transition-opacity outline-none",children:s.jsx("span",{className:"w-12 h-12 rounded-full bg-primary text-dark flex items-center justify-center shadow-lg",children:s.jsx("svg",{className:"w-5 h-5 ml-0.5",fill:"currentColor",viewBox:"0 0 24 24",children:s.jsx("path",{d:"M8 5v14l11-7z"})})})}),v.duracion&&s.jsx("span",{className:"absolute bottom-2 right-2 px-1.5 py-0.5 rounded bg-black/80 text-white text-[11px] font-medium tabular-nums",children:v.duracion})]}),s.jsxs("div",{className:"flex-1 p-4 sm:p-5 min-w-0",children:[s.jsxs("div",{className:"flex items-start justify-between gap-3 mb-1.5",children:[s.jsxs("div",{className:"min-w-0",children:[s.jsxs("div",{className:"flex items-center gap-2 mb-1 flex-wrap",children:[s.jsxs("span",{className:"text-[11px] font-semibold text-gray-500 tracking-wide",children:["SESIÓN ",v.numero]}),s.jsx("span",{className:"px-2 py-0.5 rounded-full bg-dark border border-gray-700 text-[10px] font-medium text-gray-400",children:v.nivel})]}),s.jsx("h3",{className:"text-white font-semibold text-base sm:text-lg leading-snug",children:v.titulo})]}),s.jsx("button",{onClick:()=>
14945m(v.id),"aria-pressed":S,"aria-label":S?`Marcar sesión ${v.numero} como no completada`:`Marcar sesión ${v.numero} como completada`,title:S?"Completada":"Marcar como completada",className:`shrink-0 w-7 h-7 rounded-full border flex items-center justify-center transition-colors ${S?"border-primary bg-primary/15 text-primary":"border-gray-700 text-transparent hover:border-gray-500 hover:text-gray-500"}`,children:s.jsx("svg",{className:"w-4 h-4",fill:"none",stroke:"currentColor",viewBox:"0 0 24 24",children:s.jsx("path",{strokeLinecap:"round",strokeLinejoin:"round",strokeWidth:3,d:"M5 13l4 4L19 7"})})})]}),s.jsx("p",{className:"text-gray-400 text-sm leading-relaxed mb-3",children:v.descripcion}),s.jsx("div",{className:"flex items-center gap-2 flex-wrap",children:v.temas.map(M=>s.jsx("span",{className:"px-2 py-0.5 rounded-md bg-dark/70 border border-gray-800 text-[11px] text-gray-400",children:M},M))}),s.jsxs("div",{className:"mt-4 flex items-center gap-4",children:[T?s.jsxs("button",{onClick:()=>u(v),className:"inline-flex items-center gap-1.5 text-primary text-sm font-medium hover:gap-2.5 transition-all",children:[s.jsx("svg",{className:"w-4 h-4",fill:"currentColor",viewBox:"0 0 24 24",children:s.jsx("path",{d:"M8 5v14l11-7z"})}),"Ver sesión"]}):s.jsx("span",{className:"text-gray-600 text-sm",children:"Disponible pronto"}),v.docsLink&&s.jsx(Te,{to:v.docsLink,className:"text-gray-500 hover:text-gray-300 text-sm transition-colors",children:"Leer la documentación"})]})]})]})})]},v.id)})}),d.length===0&&s.jsx("p",{className:"mt-10 text-center text-gray-500 text-sm",children:"Las sesiones se publicarán próximamente."})]}),o&&s.jsx(fne,{sesion:o,siguiente:g(o),onCerrar:p,onCompletar:h,onIrSiguiente:v=>{h(o.id),n({v:v.id},{replace:!0})}})]})}const yne=[{id:"inicio",title:"Inicio",icon:"",topics:[{id:"que-es",title:"¿Qué es Haka AI Studio?",content:`## ¿Qué es Haka AI Studio?
14946
14947Haka AI Studio es una extensión de Visual Studio Code que usa inteligencia artificial para generar pruebas automatizadas. Graba las interacciones del usuario en un navegador y genera automáticamente casos de prueba en formato Gherkin/BDD con implementaciones listas para ejecutar.
14948
14949En términos simples: abres tu aplicación web, interactúas con ella (clicks, formularios, navegación), y la extensión genera los tests por ti.
14950
14951**Compatible con Haka-Playwright-Engine v1.4.1**
14952
14953## ¿Para quién es?
14954
14955| Perfil | Beneficio principal |
14956|--------|-------------------|
14957| QA Manual que quiere automatizar | Genera tests sin escribir código. Graba y la IA escribe por ti. |
14958| QA Automation | Acelera la creación de tests. La IA genera el esqueleto, tú lo refinas. |
14959| Desarrollador | Crea tests de regresión rápidamente mientras desarrolla features. |
14960| Tech Lead / QA Lead | Estandariza el formato de tests (Gherkin + Page Objects) en el equipo. |
14961| Equipos sin experiencia en automation | Punto de entrada accesible. La curva de aprendizaje baja drásticamente. |`},{id:"funcionalidades",title:"Funcionalidades Principales",content:`## Funcionalidades Principales
14962
14963| Funcionalidad | Descripción |
14964|---------------|-------------|
14965| **Koru** | Graba interacciones en el navegador y genera pruebas Gherkin con IA |
14966| **Kai** | Chat asistente de IA especializado en automatización de pruebas |
14967| **@aistudio** | Asistente inteligente inline en archivos .feature (búsqueda + IA) |
14968| **Gherkin/Cucumber** | Syntax highlighting, icono, colores personalizables |
14969| **Rest** | Genera features de pruebas REST desde OpenAPI, Postman o cURL |
14970| **Mock Server** | Servidor HTTP local para simular APIs |
14971| **Autocompletado** | IntelliSense de steps del framework en archivos .feature |
14972| **Sesiones Guardadas** | Autologin con sesiones capturadas (MFA/2FA, Firebase, SAP, Salesforce) |
14973| **Multi-IA** | Soporta Google Gemini, OpenAI y Anthropic Claude |
14974| **Dual Engine** | Funciona con Playwright y Selenium |
14975| **i18n** | Interfaz completa en español e inglés |
14976| **Modo Invitado** | Uso sin licencia con conocimiento genérico de IA |`},{id:"instalacion",title:"Instalación",content:`## Instalación
14977
14978### Requisitos Previos
14979
14980- Visual Studio Code versión 1.85.0 o superior
14981- Node.js versión 20.x o superior
14982- Python versión 3.8 o superior (para ejecutar tests)
14983- Navegador: Chrome, Firefox, Edge o Safari
14984
14985### Pasos de Instalación
14986
149871. Abre VS Code
149882. Ve a Extensiones (Ctrl+Shift+X en Windows/Linux, Cmd+Shift+X en Mac)
149893. Busca "Haka AI Studio" o instala desde .vsix
149904. Haz clic en "Instalar"
149915. Recarga VS Code (Ctrl+Shift+P → "Developer: Reload Window")
14992
14993### Instalación desde .vsix
14994
14995\`\`\`bash
14996code --install-extension haka-ai-studio-1.5.9.vsix
14997\`\`\`
14998
14999### Verificación
15000
15001Después de instalar, deberías ver:
15002- Icono de Haka AI Studio en la barra lateral izquierda
15003- Panel "Haka AI Studio" en la vista lateral
15004- Comandos disponibles en la paleta de comandos (Ctrl+Shift+P → "Haka:")
15005- Archivos .feature con syntax highlighting automático`},{id:"inicio-rapido",title:"Inicio Rápido",content:`## Inicio Rápido
15006
150071. **Instalar** la extensión desde el Marketplace o archivo .vsix
150082. **Abrir** el panel de Haka AI Studio desde la barra de actividad
150093. **Aceptar** los Términos de Uso y Política de Privacidad
150104. **Iniciar sesión** con Google o tu licencia Hakalab
150115. **Configurar** tu proveedor de IA (Gemini recomendado) en la pestaña Config
150126. **Grabar** un test con Koru o preguntarle a Kai
15013
15014### Tipos de Cuenta
15015
15016| Tipo | Acceso |
15017|------|--------|
15018| **Haka Lab** (Google OAuth) | Acceso completo, steps vectorizados |
15019| **Clave de Licencia** | Acceso completo, validación por dispositivo |
15020| **Invitado** | Koru + Kai con IA genérica (sin vectores, sin REST) |`},{id:"flujo-trabajo",title:"Flujo de Trabajo",content:`## Flujo de Trabajo Típico
15021
15022\`\`\`
150231. Abrir VS Code en tu proyecto de tests
150242. Click en Haka AI Studio (barra lateral)
150253. Configurar IA si es la primera vez
150264. (Opcional) Seleccionar perfil de sesión guardada
150275. Click "Grabar" → interactuar con la app → "Detener"
150286. Click "Generar con IA"
150297. Revisar resultado → Guardar archivos
15030\`\`\`
15031
15032### Para escribir features manualmente
15033
15034\`\`\`
150351. Crear/abrir un archivo .feature
150362. Disfrutar del syntax highlighting automático
150373. Usar @aistudio para buscar steps existentes
150384. Usar @aistudio? para que la IA sugiera steps nuevos
150395. Personalizar colores en Config > Cucumber / Gherkin
15040\`\`\`
15041
15042## Comparación con Alternativas
15043
15044| Característica | Haka AI Studio | Playwright Codegen | Selenium IDE |
15045|---------------|----------------|-------------------|--------------|
15046| Genera Gherkin | Si | No | No |
15047| Syntax Highlighting Gherkin | Si (integrado) | No | No |
15048| @aistudio (búsqueda + IA inline) | Si | No | No |
15049| Page Objects | Si (JSON) | No | No |
15050| IA integrada | Si (multi-proveedor) | No | No |
15051| Reutiliza steps existentes | Si (vectorial) | No | No |
15052| Chat asistente | Si (Kai) | No | No |
15053| Sesiones guardadas (MFA) | Si (con IndexedDB) | No | No |
15054| Mock Server | Si (integrado) | No | No |
15055| Autocompletado .feature | Si (IntelliSense + @aistudio) | No | No |
15056| Pruebas REST desde spec | Si (OpenAPI/cURL) | No | No |
15057| Colores Gherkin personalizables | Si (en tiempo real) | No | No |`}]},{id:"configuracion",title:"Configuración",icon:"",topics:[{id:"config-ia",title:"Configurar Proveedor de IA",content:`## Configurar Proveedor de IA
15058
15059Haka AI Studio soporta múltiples proveedores de IA. Gemini es el recomendado por su integración con el sistema de búsqueda vectorial.
15060
15061### Obtener API Key de Gemini
15062
150631. Ve a https://aistudio.google.com/apikey
150642. Haz clic en "Get API Key" o "Create API Key"
150653. Copia tu API Key
15066
15067### Configurar en Haka AI Studio
15068
150691. Abre Haka AI Studio (barra lateral de VS Code)
150702. Ve a la pestaña "Config"
150713. Pega tu API Key
150724. Selecciona el modelo
150735. Los cambios se aplican en tiempo real (sin reiniciar VS Code)
15074
15075### Proveedores Soportados
15076
15077| Proveedor | Modelo Recomendado | Costo aprox. por test |
15078|-----------|-------------------|----------------|
15079| **Gemini** (Google) | gemini-2.5-flash-lite | ~$0.003 |
15080| **OpenAI** | gpt-4o | ~$0.01 |
15081| **Claude** (Anthropic) | claude-3-5-sonnet | ~$0.008 |
15082
15083### Costos Estimados Mensuales
15084
15085| Uso mensual | Costo aproximado |
15086|-------------|-----------------|
15087| 50 tests/mes | ~$0.15-$0.50 USD |
15088| 200 tests/mes | ~$0.60-$2.00 USD |
15089| 500 tests + chat | ~$1.50-$5.00 USD |
15090
15091### Consumo de IA
15092
15093- **No consume al grabar** — la grabación es local
15094- **Consume al generar** — cuando presionas "Generar con IA"
15095- **Consume al chatear** — cada mensaje a Kai usa tokens
15096- **Consume al vectorizar** — al generar embeddings de tus custom steps
15097- **Consume @aistudio?** — al pedir sugerencias con IA generativa`},{id:"config-licencia",title:"Licencia y Autenticación",content:`## Licencia y Autenticación
15098
15099### Métodos de Login
15100
15101- **Google OAuth** — cuenta corporativa @hakalab.com o autorizada
15102- **Email + Clave de licencia** — licencia manual por dispositivo
15103- **Modo invitado** — sin licencia, acceso limitado
15104
15105### Un dispositivo a la vez
15106
15107La licencia se bloquea por dispositivo. Si necesitas usar la extensión en otro equipo, cierra sesión en el actual. El bloqueo se libera automáticamente.
15108
15109### Modo Invitado
15110
15111Permite usar funcionalidades básicas sin licencia:
15112- Koru (grabación + generación con IA genérica)
15113- Chat con Kai (sin vectores del framework)
15114- No tiene acceso a engines vectorizados ni pruebas REST
15115
15116### Validación de Licencia
15117
15118- Primera ejecución: valida inmediatamente
15119- Próximos 10 días: usa caché local (sin llamadas)
15120- Cada 10 días: revalida (1 sola llamada)
15121
15122### Si hay Firewall Corporativo
15123
15124Solicitar a IT que habilite:
15125- Dominio: *.cloudfunctions.net (puerto 443)
15126- Dominio: generativelanguage.googleapis.com (para Gemini)
15127- Dirección: Salida (Outbound)`},{id:"config-panel",title:"Panel de Configuración",content:`## Panel de Configuración
15128
15129La pestaña Config organiza todas las opciones en secciones colapsables (plegables) que comienzan minimizadas por defecto.
15130
15131| Sección | Contenido |
15132|---------|-----------|
15133| **Gemini AI** | API Key, selección de modelo |
15134| **Instrucción adicional** | Prompt personalizado que se añade a todas las generaciones |
15135| **Estado** | Indicador de configuración actual |
15136| **Vectorización de Steps** | Escanear y vectorizar steps custom del proyecto |
15137| **Cucumber / Gherkin** | Colores de sintaxis, formato, vista previa en vivo |
15138| **Idioma** | Español / English |
15139
15140### Secciones Colapsables
15141
15142- Todas las secciones tienen chevron (▼/▶) para expandir/colapsar
15143- Comienzan colapsadas por defecto para una vista limpia
15144- Animación suave de apertura/cierre
15145- El panel hace scroll correctamente cuando varias están abiertas`}]},{id:"koru",title:"Koru (Grabación)",icon:"",topics:[{id:"koru-como-grabar",title:"Cómo Grabar",content:`## Grabación con Koru
15146
15147Koru es el módulo de grabación inteligente de Haka AI Studio. Captura las interacciones en el navegador en tiempo real.
15148
15149### Cómo Grabar
15150
151511. Abre el panel de Haka AI Studio (clic en el icono en la barra lateral)
151522. Ingresa la URL de tu aplicación
151533. (Opcional) Selecciona un perfil de sesión guardada para autologin
151544. Haz clic en "Iniciar Grabación"
151555. Se abrirá un navegador controlado (Chromium)
151566. Navega e interactúa con tu aplicación como lo haría un usuario real
151577. Haz clic en "Detener Grabación" cuando termines
15158
15159### Lo que Captura
15160
15161- Clicks en elementos
15162- Escritura en campos de texto
15163- Navegación entre páginas
15164- Selección de opciones en dropdowns
15165- Checks y radios
15166- Scrolls
15167
15168### Dos Modos de Grabación
15169
15170| Modo | Selectores | Uso recomendado |
15171|------|-----------|-----------------|
15172| **Playwright** | Roles, labels, data-testid | Apps modernas con buen markup |
15173| **Selenium** | XPath optimizados con validación de unicidad | Apps legacy o con selectores complejos |`},{id:"koru-generacion",title:"Generación con IA",content:`## Generación de Tests con IA
15174
15175### Paso 1: Revisar Grabación
15176
15177Después de detener la grabación, verás:
15178- Lista de acciones capturadas
15179- Selectores detectados
15180- Opción de editar antes de generar
15181
15182### Paso 2: Generar con IA
15183
151841. Haz clic en "Generar con IA" (botón con icono de chispa)
151852. Espera a que el proveedor procese (típicamente 5-30 segundos)
151863. Verás el test generado en formato Gherkin
15187
15188### Paso 3: Revisar Resultado
15189
15190El test generado incluye:
15191- **Feature**: Descripción del flujo
15192- **Scenario**: Caso de prueba específico
15193- **Steps**: Pasos en formato Gherkin (Given, When, Then)
15194- **Page Objects**: Localizadores en JSON
15195- **Implementación**: Código Python listo para ejecutar
15196
15197### Ejemplo de Test Generado
15198
15199\`\`\`gherkin
15200Feature: Login de usuario
15201
15202  Scenario: Login exitoso con credenciales válidas
15203    Given voy a la url "https://app.ejemplo.com/login"
15204    When relleno el campo "Email" con "[email protected]" con identificador "$.LOGIN.input_email"
15205    And relleno el campo "Password" con "123456" con identificador "$.LOGIN.input_password"
15206    And hago click en el elemento "Botón Ingresar" con identificador "$.LOGIN.btn_submit"
15207    Then debería ver el elemento "Dashboard" con identificador "$.DASHBOARD.titulo"
15208\`\`\`
15209
15210\`\`\`json
15211// LOGIN.json (Page Object generado)
15212{
15213  "input_email": "#email",
15214  "input_password": "#password",
15215  "btn_submit": "button[type='submit']"
15216}
15217\`\`\``},{id:"koru-busqueda-vectorial",title:"Búsqueda Vectorial",content:`## Búsqueda Vectorial (
15217Reutilización)
15218
15219El sistema vectoriza los steps existentes del framework Hakalab y los compara semánticamente con las acciones grabadas.
15220
15221### ¿Qué logra?
15222
15223- Si ya existe un step que hace lo que grabaste → lo reutiliza
15224- Si no existe → genera uno nuevo
15225- Evita duplicación de código
15226- Sugiere mejores prácticas del framework
15227
15228### Vectores Disponibles
15229
15230| Tipo | Cantidad |
15231|------|----------|
15232| API | 130 |
15233| Base de Datos | 14 |
15234| Desktop | 87 |
15235| GenAI | 52 |
15236| Guías | 143 |
15237| Mobile | 129 |
15238| Validaciones | 151 |
15239| Web | 481 |
15240| **Total** | **1187** |
15241
15242### Vectorizar Steps Personalizados
15243
15244En la pestaña Config > Vectorización de Steps, puedes escanear y vectorizar los steps de tu propio proyecto para que la IA los reutilice al generar tests.`},{id:"koru-consejos",title:"Consejos de Grabación",content:`## Consejos para Mejores Grabaciones
15245
15246### Buenas Prácticas
15247
15248- Usa datos ficticios en ambientes de prueba
15249- Graba flujos completos (inicio a fin)
15250- Espera a que los elementos carguen antes de interactuar
15251- Valida resultados visibles en la página
15252- Graba un flujo por escenario (no mezcles múltiples flujos)
15253
15254### Evitar
15255
15256- No grabes en producción con datos reales
15257- No cambies de ventana durante la grabación
15258- No hagas acciones muy rápidas (la grabación podría perder eventos)
15259- No grabes datos sensibles (contraseñas reales, números de tarjeta)
15260
15261### Grabación de Login
15262
15263\`\`\`
152641. Iniciar grabación
152652. Navegar a https://ejemplo.com/login
152663. Escribir usuario en el campo "Usuario"
152674. Escribir contraseña en el campo "Contraseña"
152685. Hacer clic en "Iniciar Sesión"
152696. Esperar a que cargue el dashboard
152707. Detener grabación
15271\`\`\``}]},{id:"aistudio",title:"@aistudio",icon:"",topics:[{id:"aistudio-descripcion",title:"¿Qué es @aistudio?",content:`## @aistudio — Asistente Inteligente en .feature
15272
15273El sistema \`@aistudio\` es un asistente inteligente que funciona directamente dentro de los archivos \`.feature\`. Escribe el trigger y obtén sugerencias de steps al instante.
15274
15275### Uso
15276
15277\`\`\`gherkin
15278# Buscar steps en todo el proyecto + búsqueda semántica
15279@aistudio click
15280
15281# Pedir a la IA que sugiera steps (con descripción de qué hace cada uno)
15282@aistudio? como valido que un modal se cierra
15283\`\`\`
15284
15285### Niveles de Inteligencia
15286
15287| Trigger | Nivel | Fuente | Velocidad |
15288|---------|-------|--------|-----------|
15289| \`@aistudio <texto>\` | Búsqueda local | Todos los .feature del proyecto (recursivo) | Instantáneo |
15290| \`@aistudio <texto>\` | Búsqueda semántica | 1187 vectores del framework Hakalab | Instantáneo |
15291| \`@aistudio? <texto>\` | IA generativa | Gemini AI con contexto del proyecto | 1-3 segundos |
15292
15293### Comportamiento
15294
15295- Al seleccionar una sugerencia, todo el \`@aistudio...\` se reemplaza con el step elegido
15296- Las sugerencias locales muestran el archivo fuente de cada step
15297- Las sugerencias semánticas muestran el % de similitud y la categoría
15298- Las sugerencias de IA incluyen una explicación de qué hace cada paso
15299- Un spinner en la barra de estado indica cuando la IA está procesando`},{id:"aistudio-niveles",title:"Niveles de Inteligencia",content:`## Niveles de Inteligencia de @aistudio
15300
15301### Nivel 1 — Búsqueda Local en el Proyecto
15302
15303- Escanea recursivamente TODOS los \`.feature\` del workspace
15304- Excluye automáticamente \`node_modules\`, \`.git\`, \`dist\`, etc.
15305- Filtra por coincidencia fuzzy de múltiples términos
15306- Muestra el archivo fuente de cada step encontrado
15307
15308### Nivel 2 — Búsqueda Semántica (Embeddings)
15309
15310- Usa los 1187 vectores pre-entrenados del framework Hakalab
15311- Encuentra steps semánticamente similares aunque no coincidan textualmente
15312- Muestra el % de similitud y la categoría (api, web, mobile, validaciones, etc.)
15313- Se activa automáticamente cuando el query tiene 3+ caracteres
15314
15315### Nivel 3 — Generación con IA (Gemini)
15316
15317- Se activa con \`@aistudio?\` (con signo de interrogación)
15318- Envía a Gemini el contexto del proyecto (steps existentes, steps del archivo actual)
15319- Genera 3-5 sugerencias de steps compatibles con el proyecto
15320- Cada sugerencia incluye una descripción de qué hace el paso concretamente
15321- Muestra un spinner en la barra de estado mientras procesa
15322
15323### Comportamiento al Seleccionar
15324
15325- Todo el texto \`@aistudio...\` o \`@aistudio?...\` se reemplaza con el step elegido
15326- El step incluye su keyword (Given/When/Then/And/But)
15327- La indentación se mantiene`},{id:"aistudio-ejemplos",title:"Ejemplos de Uso",content:`## Ejemplos de @aistudio
15328
15329### Buscar steps existentes
15330
15331\`\`\`gherkin
15332# Buscar todos los steps que tienen "login"
15333@aistudio login
15334
15335# Buscar steps de validación
15336@aistudio verificar elemento visible
15337
15338# Buscar steps de API
15339@aistudio request POST
15340\`\`\`
15341
15342### Pedir sugerencias a la IA
15343
15344\`\`\`gherkin
15345# Pedir a la IA pasos para un flujo específico
15346@aistudio? como hago logout y verifico que redirige al login
15347
15348# Pedir steps de API
15349@aistudio? validar respuesta JSON con status 201
15350
15351# Pedir steps de formulario
15352@aistudio? como verifico que un formulario se envió correctamente
15353\`\`\`
15354
15355### Requisitos
15356
15357- **Búsqueda local (nivel 1):** funciona sin API key
15358- **Búsqueda semántica (nivel 2):** requiere Gemini configurado
15359- **Generación IA (nivel 3):** requiere Gemini configurado`}]},{id:"gherkin",title:"Gherkin / Cucumber",icon:"",topics:[{id:"gherkin-syntax",title:"Syntax Highlighting",content:`## Soporte Gherkin / Cucumber
15360
15361Haka AI Studio convierte a VS Code en un editor completo para archivos Gherkin.
15362
15363### Reconocimiento de Lenguaje
15364
15365- Los archivos \`.feature\` se identifican automáticamente como lenguaje "Gherkin"
15366- Aliases: "Gherkin", "Feature", "Cucumber"
15367- Icono de Cucumber en las tabs del editor
15368
15369### Syntax Highlighting (Gramática TextMate)
15370
15371| Elemento | Color por defecto |
15372|----------|-------------------|
15373| Feature/Scenario/Background/Rule/Examples | Rosa (#FF79C6) |
15374| Given/When/Then/And/But | Verde (#50FA7B) |
15375| Tags (@smoke, @api) | Amarillo (#F1FA8C) |
15376| Comentarios (# ...) | Gris (#6272A4) |
15377| Strings ("valor") | Blanco (#F8F8F2) |
15378| Variables (<param>) | Rojo (#FF5555) |
15379| Tablas (|) | Cyan (#00D4FF) |
15380| Doc Strings (triple comillas) | Blanco |
15381
15382### Configuración de Lenguaje
15383
15384- Comentarios de línea con \`#\`
15385- Auto-cierre de \`"\`, \`'\`, \`<>\`
15386- Folding por bloques Feature/Scenario/Background`},{id:"gherkin-idiomas",title:"Idiomas Soportados",content:`## Idiomas Soportados en la Gramática
15387
15388La gramática Gherkin reconoce keywords en 5 idiomas:
15389
15390| Idioma | Feature | Scenario | Given | When | Then | And | But |
15391|--------|---------|----------|-------|------|------|-----|-----|
15392| Inglés | Feature | Scenario | Given | When | Then | And | But |
15393| Español | Característica | Escenario | Dado/Dada | Cuando | Entonces | Y | Pero |
15394| Francés | Fonctionnalité | Scénario | Étant donné | Quand | Alors | Et | Mais |
15395| Portugués | Funcionalidade | Cenário | Dado | Quando | Então | E | Mas |
15396| Alemán | Funktionalität | Szenario | Angenommen | Wenn | Dann | Und | Aber |
15397
15398Todos los keywords se reconocen y colorean correctamente independientemente del idioma utilizado.`},{id:"gherkin-colores",title:"Configuración de Colores",content:`## Configuración de Colores Gherkin
15399
15400Personaliza los colores directamente desde el panel de configuración de Haka AI Studio.
15401
15402### Cómo Configurar
15403
154041. Abre el panel → pestaña **Config**
154052. Expande la sección **Cucumber / Gherkin**
154063. Ajusta los colores con los color pickers
154074. Los cambios se aplican **en tiempo real** al editor
154085. La vista previa muestra cómo se verá
15409
15410### Opciones Disponibles
15411
15412- **Colores de palabras clave**: 7 color pickers para cada tipo de elemento
15413- **Formato**: Negrita para keywords, cursiva para tags y comentarios
15414- **Vista previa en vivo**: Muestra el resultado de los colores en tiempo real
15415- **Actualización instantánea**: Los colores se aplican al editor al cambiar, sin necesidad de guardar
15416- **Botón Restablecer**: Vuelve a los colores por defecto (esquema Dracula adaptado)
15417
15418Los colores se guardan en \`editor.tokenColorCustomizations\` de VS Code y persisten entre sesiones.
15419
15420### Icono Cucumber
15421
15422Los archivos \`.feature\` muestran un icono de Cucumber/Gherkin en:
15423- Las tabs del editor (siempre visible)
15424- El explorador de archivos (activando el tema "Haka Gherkin File Icons" en File > Preferences > File Icon Theme)`}]},{id:"kai",title:"Kai (Chat IA)",icon:"",topics:[{id:"kai-descripcion",title:"¿Qué es Kai?",content:`## Chat con Kai (Asistente IA)
15425
15426Kai es tu asistente de IA especializado en testing, integrado directamente en VS Code.
15427
15428### ¿Qué puedes hacer con Kai?
15429
15430- Preguntar cómo automatizar algo específico
15431- Pedir que refine un test generado
15432- Consultar sobre el framework Hakalab
15433- Pedir explicaciones del código generado
15434- Obtener sugerencias de mejoras
15435
15436### Kai conoce
15437
15438- Todos los steps del framework Hakalab (Web, API, Mobile, Desktop, GenAI)
15439- Las reglas de buenas prácticas de Gherkin
15440- Los patrones de Page Object (JSON POMs)
15441- La estructura de proyectos del framework
15442- Configuración del .env y environment.py
15443
15444### UI del Chat
15445
15446- Fuente optimizada (12.5px) para mejor legibilidad
15447- Code blocks con fuente monospace (11px)
15448- Textarea con font-size cómodo para escritura`},{id:"kai-ejemplos",title:"Ejemplos de Uso",content:`## Ejemplos de Preguntas a Kai
15449
15450### Sobre Testing
15451
15452- "¿Cómo escribo un test para un modal?"
15453- "¿Cuál es la mejor forma de validar un formulario?"
15454- "¿Cómo manejo elementos dinámicos?"
15455
15456### Sobre el Framework
15457
15458- "¿Qué steps hay disponibles para tablas?"
15459- "¿Cómo configuro las sesiones guardadas?"
15460- "¿Cómo uso variables en los identificadores?"
15461
15462### Sobre Código Generado
15463
15464- "Explícame este test que se generó"
15465- "¿Cómo puedo mejorar este escenario?"
15466- "¿Por qué usa ese selector y no otro?"
15467
15468### Sobre Buenas Prácticas
15469
15470- "¿Cómo organizo mis features por módulo?"
15471- "¿Cuándo usar Scenario Outline vs múltiples Scenarios?"
15472- "¿Cómo hago para no repetir el login en cada test?"
15473
15474### Consumo
15475
15476Cada mensaje a Kai usa tokens del proveedor de IA configurado. Las respuestas típicas consumen entre 500-2000 tokens de salida.`}]},{id:"rest",title:"REST y Mock Server",icon:"",topics:[{id:"rest-generador",title:"Generador REST",content:`## Generador de Pruebas REST
15477
15478Genera features Gherkin para pruebas de API REST desde especificaciones.
15479
15480### Métodos de Entrada
15481
15482- **Archivo OpenAPI/Swagger** — carga el archivo JSON/YAML de tu API
15483- **Colección Postman** — importa colecciones exportadas
15484- **cURL** — pega comandos cURL directamente
15485
15486### Lo que Genera
15487
15488- Escenarios completos con Background
15489- Casos exitosos y de error
15490- Validaciones de status code y JSON response
15491- Headers y autenticación configurados
15492
15493### Ejemplo Generado
15494
15495\`\`\`gherkin
15496@no_browser
15497Feature: API de Usuarios
15498
15499  Scenario: Obtener lista de usuarios
15500    Given configuro la API base en "https://api.ejemplo.com/v1"
15501    And configuro el token Bearer "\${ENV.API_TOKEN}"
15502    When realizo GET a "/users?page=1&limit=10"
15503    Then la respuesta deberia tener codigo "200"
15504    And la respuesta deberia ser un array JSON
15505    And el array "" de la respuesta deberia tener al menos "1" elementos
15506\`\`\``},{id:"rest-mock-server",title:"Mock Server",content:`## Mock Server Local
15507
15508Servidor HTTP integrado para simular APIs dummy antes de que estén disponibles en el ambiente real.
15509
15510### Características
15511
15512- Soporta endpoints GET, POST, PUT, DELETE y PATCH
15513- Status codes personalizados
15514- Response body en JSON configurables
15515- Headers custom por endpoint
15516- Simulación de latencia (delay en ms) para probar timeouts
15517- CORS automático para consumir desde cualquier frontend
15518- Path matching con parámetros dinámicos (\`:id\`, \`{id}\`)
15519- Log en vivo de todos los requests recibidos
15520
15521### Configuración
15522
15523- Guardar/cargar configuración desde \`mock-server.json\` del proyecto
15524- Agregar endpoints desde la UI del panel
15525- Iniciar/detener el servidor con un click
15526
15527### Uso Típico
15528
15529\`\`\`
155301. Abrir pestaña "Rest" en el panel
155312. Ir a la sección "Mock Server"
155323. Agregar endpoints con sus respuestas
155334. Iniciar el servidor (se asigna un puerto local)
155345. Consumir desde tu frontend o tests
155356. Ver el log de requests en tiempo real
15536\`\`\``}]},{id:"sesiones",title:"Sesiones Guardadas",icon:"",topics:[{id:"sesiones-descripcion",title:"¿Qué son las Sesiones?",content:`## Sesiones Guardadas (Autologin)
15537
15538Permite reutilizar sesiones de login previamente capturadas para evitar flujos de MFA/2FA en cada ejecución.
15539
15540### ¿Para qué sirve?
15541
15542Si tu aplicación tiene:
15543- Login con MFA/2FA (código SMS, authenticator)
15544- SSO corporativo (SAML, OAuth)
15545- Firebase Auth / Auth0
15546- SAP Fiori / Salesforce Lightning
15547
15548No necesitas hacer login manualmente en cada test. Capturas la sesión una vez y la reutilizas.
15549
15550### Cómo Funciona
15551
155521. Captura una sesión con \`haka-login --save nombre --url https://tu-app.com\`
155532. Haces login manualmente (incluyendo MFA/2FA)
155543. El framework guarda el estado completo
155554. En AI Studio, seleccionas el perfil de sesión antes de grabar
155565. El navegador se abre ya autenticado
15557
15558### Datos Capturados
15559
15560- Cookies de todos los dominios (httpOnly, secure, sameSite)
15561- localStorage y sessionStorage por origen
15562- IndexedDB completa (todas las bases y stores)
15563- Detección de Service Workers
15564
15565### Compatibilidad
15566
15567| Plataforma | Soporte |
15568|-----------|---------|
15569| Firebase Auth | Si (IndexedDB + localStorage) |
15570| Auth0 | Si (cookies + localStorage) |
15571| Salesforce Lightning | Si (IndexedDB completa) |
15572| SAP Fiori | Si (cookies + IndexedDB) |
15573| SSO Corporativo | Si (cookies de sesión) |
15574| MFA/2FA | Si (sesión post-autenticación) |
15575
15576### Seguridad
15577
15578- Cifrado con Fernet (AES-128-CBC + HMAC-SHA256)
15579- Usa variable de entorno \`HAKA_SESSION_KEY\` como clave
15580- Los perfiles se almacenan cifrados localmente`}
15580]},{id:"autocompletado",title:"Autocompletado",icon:"",topics:[{id:"autocompletado-clasico",title:"Autocompletado Clásico",content:`## Autocompletado de Steps
15581
15582Al editar archivos \`.feature\`, la extensión ofrece dos sistemas de autocompletado:
15583
15584### 1. Autocompletado Clásico (tras keyword)
15585
15586- Se activa al escribir \`Given \`, \`When \`, \`Then \`, \`And \` o \`But \`
15587- Escanea \`<proyecto>/docs/ejemplos/*.feature\`
15588- Muestra steps disponibles del framework con su keyword y archivo fuente
15589- Cache de 30 segundos para rendimiento óptimo
15590
15591### 2. @aistudio (búsqueda inteligente)
15592
15593- Se activa al escribir \`@aistudio\` en cualquier parte del archivo
15594- Busca en TODO el proyecto + embeddings + IA
15595- Ver sección @aistudio para más detalles
15596
15597### Diferencias
15598
15599| Característica | Clásico | @aistudio |
15600|---------------|---------|-----------|
15601| Trigger | Tras keyword Gherkin | \`@aistudio\` en cualquier lugar |
15602| Alcance | Solo docs/ejemplos/ | Todo el proyecto + vectores + IA |
15603| Velocidad | Instantáneo | Instantáneo (local) / 1-3s (IA) |
15604| Requiere API Key | No | Solo nivel 2 y 3 |`}]},{id:"seguridad",title:"Seguridad y Privacidad",icon:"",topics:[{id:"seguridad-datos",title:"Manejo de Datos",content:`## Seguridad y Privacidad
15605
15606### Principios
15607
15608- Sin telemetría, sin rastreo, sin envío de datos a Haka Lab
15609- Comunicación con IA exclusivamente por HTTPS
15610- API Keys en almacenamiento cifrado de VS Code (SecretStorage)
15611- Validación de licencia por dispositivo
15612- Sesiones de login cifradas con Fernet
15613
15614### ¿Qué datos se envían al proveedor de IA?
15615
15616- Las acciones grabadas (selectores, textos ingresados, URLs)
15617- El contexto de steps del framework para reutilización
15618- Las preguntas que haces a Kai
15619- Queries de @aistudio? (nivel 3)
15620
15621### ¿Qué datos NO se envían?
15622
15623- Contraseñas reales (se recomienda usar datos ficticios)
15624- Cookies o tokens de sesión
15625- Código fuente de tu aplicación bajo prueba
15626- Información del sistema operativo
15627
15628### Almacenamiento Local
15629
15630- La API Key se guarda en el almacenamiento seguro de VS Code
15631- Las grabaciones se almacenan temporalmente en memoria
15632- Los tests generados se guardan solo cuando tú los guardas explícitamente
15633- Los colores Gherkin se persisten en settings de VS Code
15634
15635### Recomendaciones
15636
15637- Usa ambientes de prueba (staging, QA) para grabar, nunca producción
15638- Usa datos ficticios en formularios durante la grabación
15639- Revisa el test generado antes de guardarlo
15640- No compartas tu API Key con otros usuarios`}]},{id:"uso-avanzado",title:"Uso Avanzado",icon:"",topics:[{id:"avanzado-vectorizacion",title:"Vectorización Custom",content:`## Vectorizar Steps Personalizados
15641
15642Si tu proyecto tiene custom steps, puedes vectorizarlos para que la IA los reutilice al generar tests.
15643
15644### Desde la UI
15645
156461. Panel de Haka AI Studio → pestaña Config
156472. Expandir sección "Vectorización de Steps"
156483. Click en "Escanear y Vectorizar"
15649
15650### ¿Qué hace?
15651
156521. Escanea los archivos de steps en tu proyecto
156532. Extrae las definiciones de cada step
156543. Genera embeddings semánticos de cada paso
156554. Los almacena en la base vectorial local
15656
15657### Resultado
15658
15659La próxima vez que grabes y generes, si una acción coincide con un custom step tuyo, la IA lo usará en vez de crear uno nuevo.`},{id:"avanzado-comandos",title:"Comandos Disponibles",content:`## Comandos de VS Code
15660
15661Todos los comandos están disponibles desde la paleta (Ctrl+Shift+P):
15662
15663| Comando | Descripción |
15664|---------|-------------|
15665| Haka: Start Recording | Iniciar grabación de interacciones |
15666| Haka: Stop Recording | Detener grabación |
15667| Haka: Generate Test | Generar test con IA a partir de la grabación |
15668| Haka: Configure AI Provider | Configurar proveedor y API Key |
15669| Haka: Switch AI Provider | Cambiar de proveedor rápidamente |
15670| Haka: Vectorize Custom Steps | Vectorizar steps personalizados del proyecto |
15671| Haka: Open Chat (Kai) | Abrir el chat con el asistente Kai |
15672| Haka: Show License Info | Ver información de licencia actual |
15673| Haka: Logout | Cerrar sesión de licencia |`},{id:"avanzado-tecnologias",title:"Stack Tecnológico",content:`## Tecnologías
15674
15675| Componente | Tecnología |
15676|-----------|------------|
15677| Plataforma | VS Code Extension API |
15678| Lenguaje | TypeScript |
15679| Build | Webpack |
15680| Grabación | Playwright CDP |
15681| IA | Google Gemini / OpenAI / Anthropic Claude |
15682| Vectorización | Embeddings locales (dim=768) |
15683| Syntax Highlighting | TextMate Grammar (JSON) |
15684| UI | HTML + CSS custom (Webview) |
15685| Auth | Google OAuth + API REST Hakalab |
15686| Mock Server | Node.js http module |
15687| Cifrado | Fernet (AES-128-CBC + HMAC-SHA256) |`}]},{id:"faq",title:"FAQ",icon:"",topics:[{id:"preguntas-frecuentes",title:"Preguntas Frecuentes",content:`## Preguntas Frecuentes
15688
15689### ¿Necesito saber programar para usarlo?
15690
15691No para grabar y generar. Sí para ajustar y ejecutar los tests generados.
15692
15693### ¿Funciona con cualquier aplicación web?
15694
15695Sí, cualquier aplicación accesible desde un navegador.
15696
15697### ¿Los tests generados se pueden ejecutar directamente?
15698
15699Sí, si estás usando el Hakalab Framework. Los .feature generados son compatibles con Behave + Playwright o Behave + Selenium.
15700
15701### ¿Necesito mi propia API key?
15702
15703Sí. Se configura en la pestaña Config. Cada usuario usa su propia key del proveedor que elija (Gemini, OpenAI o Claude).
15704
15705### ¿Consume créditos de IA al grabar?
15706
15707No. Solo consume al presionar "Generar con IA", al chatear con Kai, o al usar @aistudio? (nivel 3).
15708
15709### ¿Se pueden vectorizar mis propios steps?
15710
15711Sí. En Config > Vectorización de Steps, escanea y vectoriza los steps de tu proyecto.
15712
15713### ¿Cómo uso @aistudio?
15714
15715En cualquier archivo \`.feature\`, escribe \`@aistudio\` seguido de lo que buscas. Para pedir a la IA, usa \`@aistudio?\` seguido de tu pregunta.
15716
15717### ¿@aistudio busca solo en docs/ejemplos?
15718
15719No. \`@aistudio\` busca en TODO el proyecto recursivamente. El autocompletado clásico (tras keyword) sí busca solo en \`docs/ejemplos/\`.
15720
15721### ¿Los colores de Gherkin se aplican automáticamente?
15722
15723Sí. Al instalar la extensión, los archivos \`.feature\` obtienen highlighting automáticamente. Para personalizar colores, ve a Config > Cucumber / Gherkin.
15724
15725### ¿Puedo usar @aistudio sin API key?
15726
15727La búsqueda local (nivel 1) funciona sin API key. Los niveles 2 (semántico) y 3 (IA) requieren tener Gemini configurado.
15728
15729### ¿Qué frameworks de test soporta?
15730
15731Genera tests compatibles con Haka Playwright Engine (Behave + Playwright) y Haka Selenium Engine (Behave + Selenium).
15732
15733### ¿Funciona sin internet?
15734
15735La grabación funciona sin internet. La generación con IA, el chat y @aistudio (niveles 2 y 3) requieren conexión.
15736
15737### ¿Puedo usar la extensión en más de un equipo?
15738
15739La licencia permite un dispositivo a la vez. Si cambias de equipo, cierra sesión en el anterior.`},{id:"troubleshooting",title:"Solución de Problemas",content:`## Solución de Problemas
15740
15741### La extensión no aparece en VS Code
15742
15743- Verificar versión de VS Code >= 1.85.0
15744- Reinstalar: \`code --install-extension haka-ai-studio-1.5.9.vsix\`
15745- Recargar ventana: Ctrl+Shift+P → "Developer: Reload Window"
15746
15747### Error al configurar API Key
15748
15749- Verificar que la API Key es válida y no ha expirado
15750- Verificar conexión a internet
15751- Probar con otro proveedor para descartar problemas de red
15752
15753### La grabación no captura acciones
15754
15755- Verificar que el navegador de grabación está abierto
15756- No cambiar de ventana durante la grabación
15757- Esperar a que los elementos carguen antes de interactuar
15758- Reiniciar la grabación si se pierden eventos
15759
15760### Error al generar con IA
15761
15762- Verificar que hay una grabación activa (no vacía)
15763- Verificar que la API Key del proveedor es válida
15764- Si el error es de timeout, la grabación puede ser muy larga — dividir en partes
15765- Cambiar a otro proveedor si uno falla consistentemente
15766
15767### Error de licencia
15768
15769- Verificar email y clave de licencia
15770- Verificar conexión a internet (necesaria para validar)
15771- Si hay firewall, verificar acceso a *.cloudfunctions.net puerto 443
15772- Si cambió de equipo, cerrar sesión en el anterior
15773
15774### El test generado no funciona
15775
15776- Verificar que los selectores son válidos (puede haber cambiado la app)
15777- Verificar que el framework Hakalab está instalado y configurado
15778- Verificar que el .env tiene las variables necesarias (BASE_URL, etc.)
15779
15780### @aistudio no muestra sugerencias
15781
15782- Verificar que estás en un archivo .feature
15783- Verificar que escribiste \`@aistudio \` (con espacio) seguido de tu búsqueda
15784- Para nivel 2 y 3, verificar que Gemini está configurado con API key válida
15785
15786### Los colores de Gherkin no se ven
15787
15788- Verificar que el archivo tiene extensión .feature
15789- Recargar VS Code (Ctrl+Shift+P → "Developer: Reload Window")
15790- Verificar que no hay otra extensión Gherkin en conflicto`},{id:"changelog",title:"Changelog",content:`## Changelog
15791
15792### v1.5.9 (16 julio 2026)
15793
15794**Nuevas Características:**
15795- **@aistudio**: Asistente inteligente en archivos .feature con búsqueda local, semántica y generación con IA
15796- **Soporte Gherkin/Cucumber**: Syntax highlighting completo, icono Cucumber, soporte multiidioma
15797- **Panel de Configuración Cucumber/Gherkin**: Colores personalizables, formato, vista previa en vivo
15798- **Secciones colapsables en Config**: Todas las secciones plegables con animación suave
15799
15800**Correcciones:**
15801- Login con Google: solucionada condición de carrera en OAuth
15802- Webview JavaScript: corregido ReferenceError en inicialización
15803- UI Config Panel: corregido overflow en secciones expandidas
15804
15805### v1.4.9 (15 julio 2026)
15806
15807**Nuevas Características:**
15808- **Mock Server Local**: Servidor HTTP integrado para simular APIs
15809- **Autocompletado de Steps**: IntelliSense nativo para archivos .feature
15810- **Sesiones con IndexedDB**: Captura completa incluyendo IndexedDB y sessionStorage
15811
15812**Correcciones:**
15813- Configuración de IA en tiempo real (sin reiniciar)
15814- Checkbox de términos de uso corregido
15815- Autologin de sesiones estabilizado
15816
15817### v1.4.0 (15 mayo 2026)
15818
15819- Sesiones Guardadas (perfiles cifrados con Fernet)
15820- Generador de Pruebas REST (OpenAPI/Swagger, Postman, cURL)
15821- Modo Selenium (XPath inteligente + servidor de eventos HTTP)
15822
15823### v1.0.20 (18 mayo 2025)
15824
15825- Multi-Proveedor de IA (Gemini, OpenAI, Claude)
15826- Arquitectura con BaseProvider + Factory pattern
15827- Suite de pruebas completa (75+ casos, 82% cobertura)
15828
15829### v1.0.19 (10 mayo 2025)
15830
15831- Grabación mejorada
15832- Generación con Gemini AI
15833- Chat Kai
15834- Búsqueda vectorial
15835
15836### v1.0.18 (15 abril 2025)
15837
15838- Versión inicial de Haka AI Studio`}]}];function xne(){const[t,e]=k.useState(null),[a,n]=k.useState(null),[i,r]=k.useState(""),[o,l]=k.useState(!1),c=k.useMemo(()=>{const m=new Set;return yne.filter(h=>m.has(h.id)?!1:(m.add(h.id),!0))},[]);k.useEffect(()=>{document.title="Docs - Haka AI Studio | Haka Lab",c.length>0&&(e(c[0].id),c[0].topics.length>0&&n(c[0].topics[0].id))},[c]);const d=k.useMemo(()=>{if(!i.trim())return c;const m=i.toLowerCase();return c.map(h=>({...h,topics:h.topics.filter(g=>g.title.toLowerCase().includes(m)||g.content.toLowerCase().includes(m))})).filter(h=>h.topics.length>0)},[i,c]),u=k.useMemo(()=>{for(const m of c){const h=m.topics.find(g=>g.id===a);if(h)return h}return null},[a,c]),p=(m,h)=>{e(m),n(h),l(!1)};return s.jsxs("div",{className:"bg-dark min-h-screen",children:[s.jsxs("div",{className:"lg:hidden sticky top-0 z-30 bg-dark/95 backdrop-blur border-b border-gray-800 px-4 py-3 flex items-center gap-3",children:[s.jsx("button",{onClick:()=>l(!o),className:"text-gray-300 hover:text-primary",children:s.jsx("svg",{className:"w-6 h-6",fill:"none",stroke:"currentColor",viewBox:"0 0 24 24",children:s.jsx("path",{strokeLinecap:"round",strokeLinejoin:"round",strokeWidth:2,d:"M4 6h16M4 12h16M4 18h16"})})}),s.jsx("h1",{className:"text-white font-semibold text-sm truncate",children:"Haka AI Studio - Docs"})]}),s.jsxs("div",{className:"flex",children:[o&&s.jsx("div",{className:"lg:hidden fixed inset-0 z-40 bg-black/60",onClick:()=>l(!1)}),s.jsxs("aside",{className:`
15839          fixed lg:sticky top-0 left-0 z-50 lg:z-10
15840          w-80 h-screen overflow-y-auto
15841          bg-darkGray border-r border-gray-800
15842          transition-transform duration-300
15843          ${o?"translate-x-0":"-translate-x-full lg:translate-x-0"}
15844        `,children:[s.jsxs("div",{className:"p-5 border-b border-gray-800",children:[s.jsxs(Te,{to:"/docs",className:"text-xs text-gray-400 hover:text-primary transition-colors flex items-center gap-1 mb-3",children:[s.jsx("svg",{className:"w-3 h-3",fill:"none",stroke:"currentColor",viewBox:"0 0 24 24",children:s.jsx("path",{strokeLinecap:"round",strokeLinejoin:"round",strokeWidth:2,d:"M15 19l-7-7 7-7"})}),"Volver a Docs"]}),s.jsx("h2",{className:"text-white font-bold text-lg mb-1",children:"Haka AI Studio"}),s.jsx("p",{className:"text-gray-400 text-xs",children:"Manual de Usuario v1.5.9"})]}),s.jsx("div",{className:"p-4",children:s.jsxs("div",{className:"relative",children:[s.jsx("svg",{className:"absolute left-3 top-1/2 -translate-y-1/2 w-4 h-4 text-gray-500",fill:"none",stroke:"currentColor",viewBox:"0 0 24 24",children:s.jsx("path",{strokeLinecap:"round",strokeLinejoin:"round",strokeWidth:2,d:"M21 21l-6-6m2-5a7 7 0 11-14 0 7 7 0 0114 0z"})}),s.jsx("input",{type:"text",placeholder:"Buscar en docs...",value:i,onChange:m=>r(m.target.value),className:"w-full pl-10 pr-4 py-2 bg-dark border border-gray-700 rounded-lg text-sm text-white placeholder-gray-500 focus:outline-none focus:border-primary"})]})}),s.jsx("nav",{className:"px-3 pb-6",children:d.map(m=>{const h=i.trim()?!0:t===m.id;return s.jsxs("div",{className:"mb-2",children:[s.jsxs("button",{onClick:()=>e(t===m.id?null:m.id),className:"w-full flex items-center justify-between px-3 py-2 text-sm font-semibold text-gray-300 hover:text-white rounded-md hover:bg-dark/50 transition-colors",children:[s.jsxs("span",{className:"flex items-center gap-2",children:[s.jsx("span",{children:m.icon}),s.jsx("span",{children:m.title})]}),s.jsx("svg",{className:`w-4 h-4 transition-transform ${h?"rotate-90":""}`,fill:"none",stroke:"currentColor",viewBox:"0 0 24 24",children:s.jsx("path",{strokeLinecap:"round",strokeLinejoin:"round",strokeWidth:2,d:"M9 5l7 7-7 7"})})]}),h&&s.jsx("div",{className:"ml-4 mt-1 space-y-0.5",children:m.topics.map(g=>s.jsx("button",{onClick:()=>p(m.id,g.id),className:`w-full text-left px-3 py-1.5 text-sm rounded-md transition-colors ${a===g.id?"text-primary bg-primary/10 border-l-2 border-primary":"text-gray-400 hover:text-gray-200 hover:bg-dark/30"}`,children:g.title},g.id))})]},m.id)})})]}),s.jsx("main",{className:"flex-1 min-w-0 px-4 sm:px-8 lg:px-12 py-8 lg:py-12 max-w-4xl",children:u?s.jsxs("article",{children:[s.jsx("h1",{className:"text-3xl md:text-4xl font-bold text-white mb-6",children:u.title}),s.jsx("div",{className:"prose prose-invert prose-lg max-w-none docs-content",children:s.jsx(vne,{content:u.content})})]}):s.jsx("div",{className:"text-center py-20",children:s.jsx("p",{className:"text-gray-400 text-lg",children:"Selecciona un tema del menú lateral"})})})]})]})}function vne({content:t}){return bne(t).map((a,n)=>s.jsx(wne,{block:a},n))}function bne(t){var i;const e=[],a=t.split(`
15845`);let n=0;for(;n<a.length;){const r=a[n];if(r.startsWith("```")){const o=r.slice(3).trim(),l=[];for(n++;n<a.length&&!a[n].startsWith("```");)l.push(a[n]),n++;e.push({type:"code",lang:o,code:l.join(`
15846`)}),n++;continue}if(r.startsWith("## ")){e.push({type:"h2",text:r.slice(3)}),n++;continue}if(r.startsWith("### ")){e.push({type:"h3",text:r.slice(4)}),n++;continue}if(r.includes("|")&&n+1<a.length&&((i=a[n+1])!=null&&i.includes("---"))){const o=[];for(;n<a.length&&a[n].includes("|");)o.push(a[n]),n++;e.push({type:"table",rows:o});continue}if(r.startsWith("- ")||r.startsWith("* ")){const o=[];for(;n<a.length&&(a[n].startsWith("- ")||a[n].startsWith("* "));)o.push(a[n].slice(2)),n++;e.push({type:"list",items:o});continue}if(r.startsWith("step: ")){e.push({type:"step",text:r.slice(6)}),n++;continue}if(r.startsWith("descripcion: ")){e.push({type:"description",text:r.slice(13)}),n++;continue}if(r.startsWith("**")&&r.endsWith("**")){e.push({type:"bold",text:r.slice(2,-2)}),n++;continue}if(r.trim()===""||r.trim()==="---"){n++;continue}e.push({type:"paragraph",text:r}),n++}return e}function wne({block:t}){switch(t.type){case"h2":return s.jsx("h2",{className:"text-2xl font-bold text-white mt-8 mb-4",children:t.text});case"h3":return s.jsx("h3",{className:"text-xl font-semibold text-gray-200 mt-6 mb-3",children:t.text});case"bold":return s.jsx("p",{className:"font-semibold text-primary mt-4 mb-2",children:t.text});case"paragraph":return s.jsx("p",{className:"text-gray-300 mb-3 leading-relaxed",children:s.jsx(vb,{text:t.text})});case"step":return s.jsx("div",{className:"bg-primary/5 border-l-4 border-primary px-4 py-2 my-3 rounded-r-lg",children:s.jsx("code",{className:"text-primary text-sm font-mono",children:t.text})});
15846case"description":return s.jsx("p",{className:"text-gray-400 text-sm mb-4 ml-4",children:t.text});case"code":return s.jsxs("div",{className:"my-4 rounded-lg overflow-hidden border border-gray-700",children:[t.lang&&s.jsx("div",{className:"bg-gray-800 px-4 py-1.5 text-xs text-gray-400 border-b border-gray-700",children:t.lang}),s.jsx("pre",{className:"bg-[#0d1117] p-4 overflow-x-auto",children:s.jsx("code",{className:"text-sm text-gray-300 font-mono whitespace-pre",children:t.code})})]});case"list":return s.jsx("ul",{className:"list-disc list-inside space-y-1 text-gray-300 mb-4 ml-2",children:t.items.map((e,a)=>s.jsx("li",{children:s.jsx(vb,{text:e})},a))});case"table":return s.jsx(kne,{rows:t.rows});default:return null}}function kne({rows:t}){if(t.length<2)return null;const e=i=>i.split("|").filter(r=>r.trim()!=="").map(r=>r.trim()),a=e(t[0]),n=t.slice(2).map(e);return s.jsx("div",{className:"overflow-x-auto my-4 rounded-lg border border-gray-700",children:s.jsxs("table",{className:"w-full text-sm",children:[s.jsx("thead",{className:"bg-gray-800",children:s.jsx("tr",{children:a.map((i,r)=>s.jsx("th",{className:"px-4 py-2 text-left text-gray-300 font-semibold",children:i},r))})}),s.jsx("tbody",{className:"divide-y divide-gray-800",children:n.map((i,r)=>s.jsx("tr",{className:"hover:bg-dark/50",children:i.map((o,l)=>s.jsx("td",{className:"px-4 py-2 text-gray-400",children:s.jsx(vb,{text:o})},l))},r))})]})})}function vb({text:t}){return t.split(/(`[^`]+`|\*\*[^*]+\*\*)/g).map((a,n)=>a.startsWith("`")&&a.endsWith("`")?s.jsx("code",{className:"bg-gray-800 px-1.5 py-0.5 rounded text-primary text-sm font-mono",children:a.slice(1,-1)},n):a.startsWith("**")&&a.endsWith("**")?s.jsx("strong",{className:"text-white font-semibold",children:a.slice(2,-2)},n):s.jsx("span",{children:a},n))}const Sne=[{id:"inicio",title:"Inicio",icon:"",topics:[{id:"que-es",title:"¿Qué es HakaBoost?",content:`## ¿Qué es HakaBoost?
15847
15848HakaBoost es una extensión de Chrome (Manifest V3) que potencia los flujos de trabajo de QA y testing usando IA. Funciona directamente sobre Jira Cloud y Azure DevOps desde un side panel integrado.
15849
15850## ¿Para quién es?
15851
15852| Perfil | Beneficio principal |
15853|--------|-------------------|
15854| QA Manual | Genera tests Gherkin automáticamente desde requerimientos |
15855| QA Automation | Acelera la creación de escenarios con criterios de aceptación |
15856| Product Owner | Mejora la calidad de las historias de usuario con IA |
15857| Tech Lead | Estandariza el formato de requerimientos y tests en el equipo |
15858
15859## Plataformas Soportadas
15860
15861| Plataforma | Leer descripción | Mejorar con IA | Crear Tests | Vincular | Comentar |
15862|---|---|---|---|---|---|
15863| Jira Cloud | DOM + API | Si | Test/Task | Si | Si |
15864| Azure DevOps | DOM + API | Si | Test Case | Si | Si |
15865| Xray Cloud | — | — | Cucumber | Si | — |`},{id:"instalacion",title:"Instalación",content:`## Instalación
15866
15867### Requisitos
15868
15869- Google Chrome 120+ (Manifest V3)
15870- Una cuenta en Jira Cloud o Azure DevOps
15871- Al menos un proveedor de IA configurado
15872
15873### Pasos
15874
158751. Descarga el archivo de la extensión o clona el repositorio
158762. Abre \`chrome://extensions\` → activa **Modo desarrollador**
158773. Click en **Cargar descomprimida** → selecciona la carpeta del proyecto
158784. HakaBoost aparecerá en la barra de extensiones
15879
15880### Verificación
15881
15882- Verás el ícono de HakaBoost en la barra de extensiones de Chrome
15883- Atajo de teclado: \`Ctrl+Shift+Y\` (Windows/Linux) / \`Cmd+Shift+Y\` (macOS)
15884- Al abrir un work item en Jira o Azure DevOps, el side panel se activa`},{id:"uso-basico",title:"Uso Básico",content:`## Uso Básico
15885
15886### Flujo Principal
15887
158881. Navega a un work item en Jira o Azure DevOps
158892. Abre HakaBoost con el ícono o \`Ctrl+Shift+Y\`
158903. La extensión detecta automáticamente la plataforma
158914. **Leer descripción** → carga el contenido actual del work item
158925. **Mejorar Desc.** → genera versión mejorada con IA (criterios de aceptación + Gherkin)
158936. **Actualizar Jira/Azure** → reemplaza la descripción en la plataforma
158947. **Sugerir Tests** → parsea escenarios y permite crearlos como issues
15895
15896### Detección Automática
15897
15898HakaBoost detecta automáticamente si estás en Jira Cloud o Azure DevOps y adapta su comportamiento:
15899- Los botones se ajustan a la plataforma activa
15900- Los tipos de issue/work item se configuran por plataforma
15901- Los vínculos se crean según la convención de cada sistema`}]},{id:"configuracion",title:"Configuración",icon:"",topics:[{id:"config-ia",title:"Proveedores de IA",content:`## Configuración de IA
15902
15903Desde el side panel → pestaña **Configuraciones** → sección IA.
15904
15905### Chrome Built-in AI (Gemini Nano)
15906
15907- 100% local, sin costo, sin enviar datos a la nube
15908- No requiere API Key
15909- Requiere Chrome 120+ con soporte de Chrome AI habilitado
15910- Limitación: inputs largos se truncan a 4000 caracteres
15911
15912### Google Gemini (Cloud)
15913
15914- Modelos disponibles: gemini-2.5-flash, gemini-2.0-flash
15915- Requiere API Key de Google AI Studio
15916- Obtener en: https://aistudio.google.com/apikey
15917- Bajo costo, rápido
15918
15919### OpenAI (Cloud)
15920
15921- Modelos disponibles: gpt-4o-mini, gpt-4o, gpt-4-turbo
15922- Requiere API Key de OpenAI
15923- Obtener en: https://platform.openai.com/api-keys
15924
15925### Prompt Personalizable
15926
15927Puedes personalizar el prompt que se envía a la IA para ajustar el estilo de las mejoras de descripción según tus necesidades de equipo.`},{id:"config-jira",title:"Jira Cloud",content:`## Configuración de Jira Cloud
15928
15929Desde el side panel → pestaña **Configuraciones** → sección Jira.
15930
15931### Campos Requeridos
15932
15933| Campo | Descripción | Ejemplo |
15934|-------|-------------|---------|
15935| URL base | URL de tu instancia Jira | https://tu-sitio.atlassian.net |
15936| Email | Email de tu cuenta Atlassian | [email protected] |
15937| API Token | Token de API de Atlassian | Crear en id.atlassian.com |
15938
15939### Cómo Obtener el API Token
15940
159411. Ve a https://id.atlassian.com/manage-profile/security/api-tokens
159422. Click en "Create API token"
159433. Asigna un nombre descriptivo (ej: "HakaBoost")
159444. Copia el token generado
159455. Pégalo en la configuración de HakaBoost
15946
15947### Opciones Personalizables
15948
15949- **Tipo de issue para tests**: Test (Xray) o Task (estándar)
15950- **Tipo de vínculo**: "Tests", "Relates to", u otro personalizado
15951- **Proyecto por defecto**: se detecta automáticamente del work item actual`},{id:"config-azure",title:"Azure DevOps",content:`## Configuración de Azure DevOps
15952
15953Desde el side panel → pestaña **Configuraciones** → sección Azure DevOps.
15954
15955### Campos Requeridos
15956
15957| Campo | Descripción | Ejemplo |
15958|-------|-------------|---------|
15959| Organización | Nombre de la organización | mi-empresa |
15960| Proyecto | Nombre del proyecto | QA-Automation |
15961| PAT | Personal Access Token | Token con permisos de Work Items |
15962
15963### Cómo Obtener el PAT
15964
159651. En Azure DevOps, click en tu avatar → "Personal Access Tokens"
159662. Click en "New Token"
159673. Nombre: "HakaBoost"
159684. Scopes: Work Items (Read & Write)
159695. Click "Create"
159706. Copia el token generado
15971
15972### Opciones Personalizables
15973
15974- **Tipo de Work Item**: Test Case (predeterminado)
15975- **Tipo de vínculo**: "Tested By" (predeterminado)`},{id:"config-xray",title:"Xray Cloud",content:`## Configuración de Xray Cloud (Opcional)
15976
15977Para funcionalidades avanzadas de testing con Xray en Jira.
15978
15979### Campos Requeridos
15980
15981| Campo | Descripción |
15982|-------|-------------|
15983| Client ID | ID de cliente de Xray Cloud API |
15984| Client Secret | Secret de Xray Cloud API |
15985
15986### Cómo Obtener Credenciales
15987
159881. En Jira, ve a Xray → Settings → API Keys
159892. Genera un nuevo par Client ID / Client Secret
159903. Configura ambos en HakaBoost
15991
15992### Funcionalidades con Xray
15993
15994- Crear tests de tipo Cucumber (en vez de Generic)
15995- Export directo como archivo .feature
15996- Steps de Gherkin estructurados en el Test Issue de Xray`},{id:"config-ofuscacion",title:"Ofuscación de Datos",content:`## Ofuscación de Datos Sensibles
15997
15998HakaBoost ofusca automáticamente información sensible antes de enviarla a la IA cloud.
15999
16000### Datos que se Ofuscan
16001
16002- URLs completas
16003- Emails
16004- Direcciones IP
16005- Números de teléfono
16006- RUT (Chile)
16007- UUIDs
16008
16009### Configuración
16010
16011- Toggle para activar/desactivar la ofuscación
16012- Diccionario personalizado: define palabras → reemplazos específicos
16013
16014### Cómo Funciona
16015
160161. Antes de enviar a la IA, se detectan patrones sensibles
160172. Se reemplazan por placeholders genéricos
160183. La IA genera la respuesta con los placeholders
160194. Se des-ofusca automáticamente al mostrar el resultado
16020
16021### Nota
16022
16023La ofuscación no aplica a Chrome Built-in AI (Gemini Nano) ya que procesa todo localmente sin enviar datos a la nube.`}]},{id:"copiloto",title:"Copiloto de Descripción",icon:"",topics:[{id:"copiloto-mejorar",title:"Mejorar Descripción",content:`## Copiloto de Descripción
16024
16025### ¿Qué Hace?
16026
16027Lee la descripción actual de un work item (historia de usuario, bug, task) y genera una versión mejorada que incluye:
16028
16029- Descripción estructurada y clara
16030- Criterios de aceptación explícitos
16031- Escenarios Gherkin (Given/When/Then)
16032- Precondiciones identificadas
16033- Datos de ejemplo cuando aplica
16034
16035### Flujo
16036
160371. **Leer Descripción**: Extrae el texto del work item actual (DOM o API REST)
160382. **Mejorar Desc.**: Envía a la IA con el prompt configurado
160393. **Vista previa**: Muestra el resultado mejorado para revisión
160404. **Actualizar**: Reemplaza la descripción en Jira o Azure DevOps vía API
16041
16042### Ejemplo
16043
16044**Antes (descripción original):**
16045\`\`\`
16046Como usuario quiero poder recuperar mi contraseña
16047\`\`\`
16048
16049**Después (mejorada por IA):**
16050\`\`\`
16051## Descripción
16052Como usuario registrado, quiero poder recuperar mi contraseña olvidada
16053para poder acceder nuevamente a mi cuenta sin contactar a soporte.
16054
16055## Criterios de Aceptación
16056- El usuario puede solicitar recuperación desde la pantalla de login
16057- Se envía un email con link de recuperación válido por 24 horas
16058- El link permite establecer una nueva contraseña
16059- La nueva contraseña debe cumplir las políticas de seguridad
16060
16061## Escenarios
16062
16063Scenario: Solicitar recuperación con email válido
16064  Given estoy en la pantalla de login
16065  When hago click en "Olvidé mi contraseña"
16066  And ingreso mi email registrado "[email protected]"
16067  And hago click en "Enviar"
16068  Then debería ver el mensaje "Te enviamos un email de recuperación"
16069  And debería recibir un email con el link de recuperación
16070\`\`\``},{id:"copiloto-crear-tests",title:"Crear Tests",content:`## Creación de Tests
16071
16072### ¿Qué Hace?
16073
16074Parsea los escenarios Gherkin de la descripción mejorada y crea issues/work items de tipo Test en la plataforma, vinculándolos automáticamente al work item principal.
16075
16076### Flujo
16077
160781. **Sugerir Tests**: Parsea los escenarios Gherkin de la descripción
160792. **Seleccionar**: Elige cuáles escenarios crear como tests
160803. **Crear**: Crea los issues en la plataforma con los steps Gherkin
160814. **Vincular**: Vincula automáticamente cada test al work item original
16082
16083### En Jira Cloud
16084
16085- Crea issues de tipo Test (si usas Xray) o Task
16086- Vincula con el tipo de link configurado (ej: "Tests", "Relates to")
16087- Si usa Xray: crea como Cucumber Test con steps estructurados
16088
16089### En Azure DevOps
16090
16091- Crea Work Items de tipo Test Case
16092- Vincula con "Tested By" al work item principal
16093- Los steps se agregan como Test Steps del Test Case
16094
16095### Exportación
16096
16097- Export como archivo \`.feature\` (Cucumber)
16098- Export como Excel con los escenarios tabulados`}]},{id:"funciones-pro",title:"Funciones Pro",icon:"",topics:[{id:"pro-analisis",title:"Análisis de IA",content:`## Análisis de IA (Pro)
16099
16100Genera un reporte de calidad del work item con recomendaciones, riesgos y precondiciones.
16101
16102### ¿Qué Incluye?
16103
16104- **Recomendaciones**: Mejoras sugeridas para el requerimiento
16105- **Riesgos identificados**: Posibles problemas de implementación o testing
16106- **Precondiciones**: Condiciones necesarias antes de ejecutar los tests
16107- **Puntos de atención**: Áreas que requieren validación extra
16108
16109### Opciones
16110
16111- **Publicar como comentario**: Agrega el análisis como comentario en el work item
16112- **Exportar a PDF**: Descarga el reporte como documento PDF
16113
16114### Presentación
16115
16116El análisis se presenta en formato de cards verticales con categorización visual por tipo (recomendación, riesgo, precondición).`},{id:"pro-datos-prueba",title:"Datos de Prueba",content:`## Datos de Prueba (Pro)
16117
16118Sugiere datos concretos para cada escenario: valores válidos, inválidos, límite y edge cases.
16119
16120### ¿Qué Genera?
16121
16122Para cada escenario Gherkin detectado, sugiere:
16123
16124- **Datos válidos**: valores correctos que deben funcionar
16125- **Datos inválidos**: valores que deben ser rechazados
16126- **Datos límite**: valores en los extremos permitidos
16127- **Edge cases**: situaciones atípicas o combinaciones especiales
16128
16129### Presentación Visual
16130
16131- Cards por escenario con badges de clasificación
16132- Colores por tipo: verde (válido), rojo (inválido), amarillo (límite), naranja (edge)
16133
16134### Scenario Outline
16135
16136Los datos sugeridos se pueden transformar automáticamente en:
16137- **Scenario Outline** con tabla de Examples
16138- Formato listo para copiar al .feature
16139
16140### Ejemplo
16141
16142\`\`\`gherkin
16143Scenario Outline: Validar campo email
16144  When ingreso "<email>" en el campo de email
16145  Then debería ver "<resultado>"
16146
16147  Examples:
16148    | email | resultado | tipo |
16149    | [email protected] | Éxito | válido |
16150    | [email protected] | Éxito | límite |
16151    | | Error: campo requerido | inválido |
16152    | usuario@@empresa.com | Error: formato inválido | inválido |
16153    | [email protected] | Éxito | edge case |
16154\`\`\``},{id:"pro-cobertura",title:"Análisis de Cobertura",content:`## Análisis de Cobertura (Pro)
16155
16156Compara los escenarios generados contra la descripción original para 
16156identificar brechas de cobertura.
16157
16158### ¿Qué Hace?
16159
161601. Toma la descripción original del work item
161612. Toma los escenarios Gherkin generados
161623. Compara usando IA para detectar gaps
161634. Sugiere escenarios faltantes
16164
16165### Resultado
16166
16167- **Cobertura actual**: Porcentaje estimado de cobertura de los requisitos
16168- **Gaps identificados**: Requisitos o criterios sin escenarios asociados
16169- **Sugerencias**: Títulos concretos de escenarios adicionales necesarios
16170
16171### Ejemplo de Gap
16172
16173\`\`\`
16174Gap detectado: "El criterio de expiración del link en 24 horas
16175no tiene escenario de validación"
16176
16177Sugerencia: "Scenario: Verificar que link de recuperación expira después de 24 horas"
16178\`\`\``}]},{id:"planes",title:"Planes y Cuenta",icon:"",topics:[{id:"planes-free-pro",title:"Free vs Pro",content:`## Planes
16179
16180### Plan Free
16181
16182- Registro sin contraseña (nombre, email, empresa)
16183- Acceso al Copiloto de Descripción (mejorar + crear tests)
16184- Proveedores de IA: Chrome Built-in AI, Gemini, OpenAI
16185- Sin límite de uso del copiloto base
16186
16187### Plan Pro
16188
16189- Login con email/contraseña o Google
16190- Todo lo de Free +
16191- Análisis de IA (reporte de calidad)
16192- Datos de Prueba (sugerencias con clasificación)
16193- Análisis de Cobertura (detección de gaps)
16194- Exportación a PDF
16195- Publicación como comentario
16196
16197### Clientes de Haka Lab
16198
16199Los clientes de Haka Lab tienen acceso gratuito al plan Pro iniciando sesión con su cuenta de Google corporativa (dominio configurado).`},{id:"planes-autenticacion",title:"Autenticación",content:`## Autenticación
16200
16201### Registro Free
16202
162031. Click en "Registrarse" en el panel de HakaBoost
162042. Ingresa: nombre, email, empresa
162053. No requiere contraseña
162064. Acceso inmediato al copiloto base
16207
16208### Login Pro
16209
162101. Click en "Iniciar Sesión"
162112. Opciones:
16212   - Email + Contraseña
16213   - Google (para dominios configurados)
162143. Verificación server-side del plan
16215
16216### Recuperación de Contraseña
16217
162181. Click en "Olvidé mi contraseña"
162192. Ingresa tu email
162203. Recibirás un link para restablecer
16221
16222### Sesión Concurrente
16223
16224- Solo un dispositivo activo por cuenta
16225- Si se detecta sesión en otro dispositivo, se notifica al usuario
16226- Puedes cerrar la sesión remota y continuar en el dispositivo actual`}]},{id:"privacidad",title:"Privacidad",icon:"",topics:[{id:"privacidad-datos",title:"Manejo de Datos",content:`## Privacidad y Seguridad
16227
16228### Almacenamiento
16229
16230- Todos los datos de configuración se guardan localmente en \`chrome.storage.sync\`
16231- Los tokens y API keys nunca se envían a servidores propios de Haka Lab
16232- La autenticación usa Firebase Auth (REST API directa, sin SDK)
16233
16234### IA Cloud (OpenAI / Gemini)
16235
16236Cuando usas proveedores cloud:
16237- Las descripciones se envían a los proveedores según sus términos de servicio
16238- La ofuscación automática protege datos sensibles antes del envío
16239- Puedes usar Chrome Built-in AI (Gemini Nano) para procesamiento 100% local
16240
16241### Chrome Built-in AI
16242
16243- Procesamiento completamente local en tu dispositivo
16244- Ningún dato sale de tu computador
16245- No requiere internet para funcionar (después de la descarga inicial del modelo)
16246
16247### Firebase
16248
16249- Solo se usa para autenticación (login/registro)
16250- Se almacenan: email, nombre, empresa, plan
16251- No se almacenan descripciones, tests ni contenido de work items`}]}];function _ne(){const[t,e]=k.useState(null),[a,n]=k.useState(null),[i,r]=k.useState(""),[o,l]=k.useState(!1),c=k.useMemo(()=>{const m=new Set;return Sne.filter(h=>m.has(h.id)?!1:(m.add(h.id),!0))},[]);k.useEffect(()=>{document.title="Docs - HakaBoost | Haka Lab",c.length>0&&(e(c[0].id),c[0].topics.length>0&&n(c[0].topics[0].id))},[c]);const d=k.useMemo(()=>{if(!i.trim())return c;const m=i.toLowerCase();return c.map(h=>({...h,topics:h.topics.filter(g=>g.title.toLowerCase().includes(m)||g.content.toLowerCase().includes(m))})).filter(h=>h.topics.length>0)},[i,c]),u=k.useMemo(()=>{for(const m of c){const h=m.topics.find(g=>g.id===a);if(h)return h}return null},[a,c]),p=(m,h)=>{e(m),n(h),l(!1)};return s.jsxs("div",{className:"bg-dark min-h-screen",children:[s.jsxs("div",{className:"lg:hidden sticky top-0 z-30 bg-dark/95 backdrop-blur border-b border-gray-800 px-4 py-3 flex items-center gap-3",children:[s.jsx("button",{onClick:()=>l(!o),className:"text-gray-300 hover:text-primary",children:s.jsx("svg",{className:"w-6 h-6",fill:"none",stroke:"currentColor",viewBox:"0 0 24 24",children:s.jsx("path",{strokeLinecap:"round",strokeLinejoin:"round",strokeWidth:2,d:"M4 6h16M4 12h16M4 18h16"})})}),s.jsx("h1",{className:"text-white font-semibold text-sm truncate",children:"HakaBoost - Docs"})]}),s.jsxs("div",{className:"flex",children:[o&&s.jsx("div",{className:"lg:hidden fixed inset-0 z-40 bg-black/60",onClick:()=>l(!1)}),s.jsxs("aside",{className:`
16252          fixed lg:sticky top-0 left-0 z-50 lg:z-10
16253          w-80 h-screen overflow-y-auto
16254          bg-darkGray border-r border-gray-800
16255          transition-transform duration-300
16256          ${o?"translate-x-0":"-translate-x-full lg:translate-x-0"}
16257        `,children:[s.jsxs("div",{className:"p-5 border-b border-gray-800",children:[s.jsxs(Te,{to:"/docs",className:"text-xs text-gray-400 hover:text-primary transition-colors flex items-center gap-1 mb-3",children:[s.jsx("svg",{className:"w-3 h-3",fill:"none",stroke:"currentColor",viewBox:"0 0 24 24",children:s.jsx("path",{strokeLinecap:"round",strokeLinejoin:"round",strokeWidth:2,d:"M15 19l-7-7 7-7"})}),"Volver a Docs"]}),s.jsx("h2",{className:"text-white font-bold text-lg mb-1",children:"HakaBoost"}),s.jsx("p",{className:"text-gray-400 text-xs",children:"Copiloto de Calidad v3.0"})]}),s.jsx("div",{className:"p-4",children:s.jsxs("div",{className:"relative",children:[s.jsx("svg",{className:"absolute left-3 top-1/2 -translate-y-1/2 w-4 h-4 text-gray-500",fill:"none",stroke:"currentColor",viewBox:"0 0 24 24",children:s.jsx("path",{strokeLinecap:"round",strokeLinejoin:"round",strokeWidth:2,d:"M21 21l-6-6m2-5a7 7 0 11-14 0 7 7 0 0114 0z"})}),s.jsx("input",{type:"text",placeholder:"Buscar en docs...",value:i,onChange:m=>r(m.target.value),className:"w-full pl-10 pr-4 py-2 bg-dark border border-gray-700 rounded-lg text-sm text-white placeholder-gray-500 focus:outline-none focus:border-primary"})]})}),s.jsx("nav",{className:"px-3 pb-6",children:d.map(m=>{const h=i.trim()?!0:t===m.id;return s.jsxs("div",{className:"mb-2",children:[s.jsxs("button",{onClick:()=>e(t===m.id?null:m.id),className:"w-full flex items-center justify-between px-3 py-2 text-sm font-semibold text-gray-300 hover:text-white rounded-md hover:bg-dark/50 transition-colors",children:[s.jsxs("span",{className:"flex items-center gap-2",children:[s.jsx("span",{children:m.icon}),s.jsx("span",{children:m.title})]}),s.jsx("svg",{className:`w-4 h-4 transition-transform ${h?"rotate-90":""}`,fill:"none",stroke:"currentColor",viewBox:"0 0 24 24",children:s.jsx("path",{strokeLinecap:"round",strokeLinejoin:"round",strokeWidth:2,d:"M9 5l7 7-7 7"})})]}),h&&s.jsx("div",{className:"ml-4 mt-1 space-y-0.5",children:m.topics.map(g=>s.jsx("button",{onClick:()=>p(m.id,g.id),className:`w-full text-left px-3 py-1.5 text-sm rounded-md transition-colors ${a===g.id?"text-primary bg-primary/10 border-l-2 border-primary":"text-gray-400 hover:text-gray-200 hover:bg-dark/30"}`,children:g.title},g.id))})]},m.id)})})]}),s.jsx("main",{className:"flex-1 min-w-0 px-4 sm:px-8 lg:px-12 py-8 lg:py-12 max-w-4xl",children:u?s.jsxs("article",{children:[s.jsx("h1",{className:"text-3xl md:text-4xl font-bold text-white mb-6",children:u.title}),s.jsx("div",{className:"prose prose-invert prose-lg max-w-none docs-content",children:s.jsx(Ane,{content:u.content})})]}):s.jsx("div",{className:"text-center py-20",children:s.jsx("p",{className:"text-gray-400 text-lg",children:"Selecciona un tema del menú lateral"})})})]})]})}function Ane({content:t}){return Ene(t).map((a,n)=>s.jsx(Cne,{block:a},n))}function Ene(t){var i;const e=[],a=t.split(`
16258`);let n=0;for(;n<a.length;){const r=a[n];if(r.startsWith("```")){const o=r.slice(3).trim(),l=[];for(n++;n<a.length&&!a[n].startsWith("```");)l.push(a[n]),n++;e.push({type:"code",lang:o,code:l.join(`
16259`)}),n++;continue}if(r.startsWith("## ")){e.push({type:"h2",text:r.slice(3)}),n++;continue}if(r.startsWith("### ")){e.push({type:"h3",text:r.slice(4)}),n++;continue}if(r.includes("|")&&n+1<a.length&&((i=a[n+1])!=null&&i.includes("---"))){const o=[];for(;n<a.length&&a[n].includes("|");)o.push(a[n]),n++;e.push({type:"table",rows:o});continue}if(r.startsWith("- ")||r.startsWith("* ")){const o=[];for(;n<a.length&&(a[n].startsWith("- ")||a[n].startsWith("* "));)o.push(a[n].slice(2)),n++;e.push({type:"list",items:o});continue}if(r.startsWith("step: ")){e.push({type:"step",text:r.slice(6)}),n++;continue}if(r.startsWith("descripcion: ")){e.push({type:"description",text:r.slice(13)}),n++;continue}if(r.startsWith("**")&&r.endsWith("**")){e.push({type:"bold",text:r.slice(2,-2)}),n++;continue}if(r.trim()===""||r.trim()==="---"){n++;continue}e.push({type:"paragraph",text:r}),n++}return e}function Cne({block:t}){switch(t.type){case"h2":return s.jsx("h2",{className:"text-2xl font-bold text-white mt-8 mb-4",children:t.text});case"h3":return s.jsx("h3",{className:"text-xl font-semibold text-gray-200 mt-6 mb-3",children:t.text});case"bold":return s.jsx("p",{className:"font-semibold text-primary mt-4 mb-2",children:t.text});case"paragraph":return s.jsx("p",{className:"text-gray-300 mb-3 leading-relaxed",children:s.jsx(bb,{text:t.text})});case"step":return s.jsx("div",{className:"bg-primary/5 border-l-4 border-primary px-4 py-2 my-3 rounded-r-lg",children:s.jsx("code",{className:"text-primary text-sm font-mono",children:t.text})});
16259case"description":return s.jsx("p",{className:"text-gray-400 text-sm mb-4 ml-4",children:t.text});case"code":return s.jsxs("div",{className:"my-4 rounded-lg overflow-hidden border border-gray-700",children:[t.lang&&s.jsx("div",{className:"bg-gray-800 px-4 py-1.5 text-xs text-gray-400 border-b border-gray-700",children:t.lang}),s.jsx("pre",{className:"bg-[#0d1117] p-4 overflow-x-auto",children:s.jsx("code",{className:"text-sm text-gray-300 font-mono whitespace-pre",children:t.code})})]});case"list":return s.jsx("ul",{className:"list-disc list-inside space-y-1 text-gray-300 mb-4 ml-2",children:t.items.map((e,a)=>s.jsx("li",{children:s.jsx(bb,{text:e})},a))});case"table":return s.jsx(jne,{rows:t.rows});default:return null}}function jne({rows:t}){if(t.length<2)return null;const e=i=>i.split("|").filter(r=>r.trim()!=="").map(r=>r.trim()),a=e(t[0]),n=t.slice(2).map(e);return s.jsx("div",{className:"overflow-x-auto my-4 rounded-lg border border-gray-700",children:s.jsxs("table",{className:"w-full text-sm",children:[s.jsx("thead",{className:"bg-gray-800",children:s.jsx("tr",{children:a.map((i,r)=>s.jsx("th",{className:"px-4 py-2 text-left text-gray-300 font-semibold",children:i},r))})}),s.jsx("tbody",{className:"divide-y divide-gray-800",children:n.map((i,r)=>s.jsx("tr",{className:"hover:bg-dark/50",children:i.map((o,l)=>s.jsx("td",{className:"px-4 py-2 text-gray-400",children:s.jsx(bb,{text:o})},l))},r))})]})})}function bb({text:t}){return t.split(/(`[^`]+`|\*\*[^*]+\*\*)/g).map((a,n)=>a.startsWith("`")&&a.endsWith("`")?s.jsx("code",{className:"bg-gray-800 px-1.5 py-0.5 rounded text-primary text-sm font-mono",children:a.slice(1,-1)},n):a.startsWith("**")&&a.endsWith("**")?s.jsx("strong",{className:"text-white font-semibold",children:a.slice(2,-2)},n):s.jsx("span",{children:a},n))}const Tne=[{id:"inicio",title:"Inicio",icon:"",topics:[{id:"que-es",title:"¿Qué es HakaBuddy?",content:`## ¿Qué es HakaBuddy?
16260
16261HakaBuddy es una herramienta de escritorio para equipos de QA que centraliza la gestión, ejecución y documentación de pruebas de softw
16261are — tanto manuales como automatizadas con Playwright.
16262
16263Permite registrar pruebas paso a paso con evidencia visual, grabar y ejecutar scripts de automatización, generar reportes profesionales en PDF y HTML, y publicar suites de regresión en GitHub, GitLab o Bitbucket para ejecutarlas en CI/CD.
16264
16265## ¿Para quién es?
16266
16267| Perfil | Beneficio principal |
16268|--------|-------------------|
16269| QA Manual | Registro de pruebas con evidencia visual y reportes PDF profesionales |
16270| QA Automation | Grabación y ejecución de scripts Playwright sin escribir código |
16271| QA Lead | Gestión de suites de regresión y trazabilidad completa |
16272| Equipos ágiles | Integración con Jira, Xray, CI/CD y reportes exportables |
16273
16274## Plataformas
16275
16276- Windows (.exe)
16277- macOS (.app / .dmg) — Intel y Apple Silicon
16278- Linux (ejecutable)
16279
16280## Tecnologías
16281
16282- Python 3.12+ con PyQt6 (interfaz gráfica)
16283- Playwright (automatización de navegador)
16284- SQLite (base de datos local)
16285- Multi-proveedor IA (Gemini, OpenAI, Claude, Ollama)`},{id:"instalacion",title:"Instalación",content:`## Instalación
16286
16287### Windows
16288
162891. Descarga \`Hakabuddy.exe\`
162902. Ejecuta el instalador
162913. La aplicación se instala y crea un acceso directo
16292
16293### macOS
16294
162951. Descarga \`Hakabuddy.dmg\`
162962. Abre el DMG y arrastra Hakabuddy a Aplicaciones
162973. La primera vez, macOS puede pedir permisos de:
16298   - Captura de pantalla (para evidencias)
16299   - Accesibilidad (para grabación)
16300
16301**Nota:** Compilar en el mismo tipo de arquitectura donde se va a usar (Intel → Intel, Apple Silicon → Apple Silicon).
16302
16303### Linux (Manjaro/Arch)
16304
16305\`\`\`bash
16306sudo pacman -S python python-pip qt6-base qt6-svg
16307./Hakabuddy
16308\`\`\`
16309
16310Si usas Wayland y hay problemas gráficos: \`export QT_QPA_PLATFORM=xcb\`
16311
16312### Datos del Usuario
16313
16314Los datos se guardan automáticamente en:
16315- **Windows**: \`C:\\Users\\{usuario}\\AppData\\Local\\Hakabuddy\\data\\\`
16316- **macOS**: \`~/Library/Application Support/Hakabuddy/data/\`
16317- **Linux**: \`~/.local/share/Hakabuddy/data/\`
16318
16319Incluye: base de datos SQLite, configuración, scripts grabados, capturas y reportes. Los datos persisten entre actualizaciones del ejecutable.`},{id:"login",title:"Login y Sesión",content:`## Login y Sesión
16320
16321### Opciones de Acceso
16322
16323| Método | Descripción |
16324|--------|-------------|
16325| Google OAuth2 | Login con cuenta de Google (recomendado para equipos) |
16326| Email/Contraseña | Login con Firebase Auth |
16327| Modo Invitado | Pruebas manuales sin cuenta (funcionalidad limitada) |
16328
16329### Sesión Persistente
16330
16331- La sesión se mantiene entre ejecuciones de la aplicación
16332- No necesitas hacer login cada vez que abres HakaBuddy
16333- El refresh token se almacena localmente de forma segura
16334- Si pierdes la sesión, simplemente vuelve a hacer login
16335
16336### Modo Invitado
16337
16338Permite usar las funcionalidades básicas de pruebas manuales sin necesidad de crear cuenta. No tiene acceso a:
16339- Integraciones (Jira, Git)
16340- Funcionalidades Pro
16341- Historial persistente`}]},{id:"configuracion",title:"Configuracion",icon:"",topics:[{id:"config-productos",title:"Productos y Ambientes",content:`## Productos y Ambientes
16342
16343### Productos
16344
16345Configura los productos que tu equipo testea. Cada prueba se asocia a un producto para organizar el historial.
16346
16347- Agregar/editar/eliminar productos
16348- Nombre del producto visible en reportes
16349- Filtrar historial por producto
16350
16351### Ambientes
16352
16353Define los ambientes disponibles para tus pruebas:
16354- Desarrollo
16355- QA
16356- Staging
16357- Producción
16358- Custom (cualquier nombre)
16359
16360### Células / Equipos
16361
16362Organiza las pruebas por células o equipos de trabajo. Útil para equipos grandes con múltiples QAs.`},{id:"config-ia",title:"Inteligencia Artificial",content:`## Configuración de IA
16363
16364### Proveedores Soportados
16365
16366| Proveedor | Tipo | Modelos |
16367|-----------|------|---------|
16368| Google Gemini | Cloud | gemini-2.0-flash, gemini-pro |
16369| OpenAI | Cloud | gpt-4o, gpt-4o-mini |
16370| Claude (Anthropic) | Cloud | claude-3-7-sonnet |
16371| Ollama | Local | llama3, mistral, codestral, cualquier modelo local |
16372
16373### Configurar Proveedor Cloud
16374
163751. Ir a Configuraciones → IA
163762. Seleccionar proveedor
163773. Ingresar API Key
163784. Seleccionar modelo
16379
16380### Configurar Ollama (Local)
16381
163821. Instalar Ollama (\`https://ollama.ai\`)
163832. Descargar modelo: \`ollama pull llama3\`
163843. En HakaBuddy: seleccionar "Ollama" como proveedor
163854. URL del servidor: \`http://localhost:11434\` (por defecto)
163865. Seleccionar modelo disponible
16387
16388**Ventaja de Ollama:** 100% local, sin costo de API, sin enviar datos a la nube, funciona sin internet.`},{id:"config-jira",title:"Jira y Xray",content:`## Configuración de Jira
16389
16390### Campos Requeridos
16391
16392| Campo | Ejemplo |
16393|-------|---------|
16394| URL base | https://tu-sitio.atlassian.net |
16395| Email | [email protected] |
16396| API Token | Token de Atlassian |
16397
16398### Cómo Obtener el API Token
16399
164001. Ve a https://id.atlassian.com/manage-profile/security/api-tokens
164012. "Create API token" → Nombre: "HakaBuddy"
164023. Copia el token y pégalo en HakaBuddy
16403
16404### Configuración de Xray (opcional)
16405
16406| Campo | Descripción |
16407|-------|-------------|
16408| Client ID | ID de Xray Cloud API |
16409| Client Secret | Secret de Xray Cloud API |
16410
16411Obtener en: Jira → Xray → Settings → API Keys`},{id:"config-reportes",title:"Reportes",content:`## Configuración de Reportes
16412
16413### PDF
16414
16415- **Logo**: Imagen PNG/JPG del equipo o empresa (aparece en portada)
16416- **Plantilla de portada**: Personalizable
16417- **Datos de pie de página**: Nombre de empresa, contacto
16418- **Formato de fecha**: Configurable
16419
16420### HTML
16421
16422- Logo embebido en base64
16423- Título del reporte personalizable
16424- Tema oscuro por defecto
16425
16426### Plantillas
16427
16428HakaBuddy incluye plantillas PDF profesionales por defecto. La portada, contraportada y formato de pasos se pueden personalizar.`},{id:"config-git",title:"Git / CI-CD",content:`## Configuración Git
16429
16430### Plataformas Soportadas
16431
16432| Plataforma | Token requerido |
16433|------------|----------------|
16434| GitHub | Personal Access Token (PAT) |
16435| GitLab | Personal Access Token |
16436| Bitbucket | App Password |
16437
16438### Configurar
16439
164401. Ir a Configuraciones → Git/CI-CD
164412. Seleccionar plataforma
164423. Ingresar token de acceso
164434. Seleccionar repositorio destino
164445. Configurar rama (por defecto: main)`}]},{id:"pruebas-manuales",title:"Pruebas Manuales",icon:"",topics:[{id:"manual-flujo",title:"Flujo Completo",content:`## Flujo de Pruebas Manuales
16445
16446### Paso 1: Iniciar Prueba
16447
164481. Selecciona producto y ambiente
164492. Ingresa el título del caso de prueba
164503. (Opcional) Asocia una issue de Jira
164514. Click en "Iniciar Prueba"
16452
16453### Paso 2: Registrar Pasos
16454
16455Para cada paso de la prueba:
164561. Ingresa el título/descripción de la acción
164572. Ejecuta la acción en la aplicación bajo prueba
164583. Captura evidencia (screenshot)
164594. Marca el estado: Exitoso o Fallido
164605. (Opcional) Agrega observaciones
16461
16462### Paso 3: Finalizar
16463
164641. Click en "Finalizar Prueba"
164652. Selecciona formato de reporte (PDF, HTML, o ambos)
164663. El reporte se genera automáticamente con toda la evidencia
164674. (Opcional) Exportar a Xray JSON
16468
16469### Funcionalidades Durante la Ejecución
16470
16471- Editar pasos previos sin perder el progreso
16472- Agregar observaciones a cualquier paso
16473- Adjuntar archivos adicionales (JSON, PDF)
16474- Activar/desactivar grabación de video
16475- Usar IA para generar descripciones de pasos`},{id:"manual-capturas",title:"Tipos de Captura",content:`## Tipos de Captura de Evidencia
16476
16477### Pantalla Completa
16478
16479Captura todo el contenido visible del monitor principal. Ideal para mostrar el contexto completo de la acción.
16480
16481### Área Seleccionada
16482
16483Permite recortar una región específica de la pantalla:
164841. Click en "Capturar Área"
164852. Arrastra para seleccionar la zona
164863. Solo se guarda la región seleccionada
16487
16488Ideal para: campos específicos, mensajes de error, tooltips.
16489
16490### Con Temporizador
16491
16492Captura después de un delay configurable:
16493- 3 segundos
16494- 5 segundos
16495- 10 segundos
16496
16497Útil para: menús desplegables, tooltips que desaparecen, animaciones.
16498
16499### Editor de Imagen
16500
16501Después de capturar, puedes editar la imagen:
16502- Resaltar áreas (rectángulos de color)
16503- Agregar flechas indicativas
16504- Añadir texto/anotaciones
16505- Difuminar información sensible`},{id:"manual-video",title:"Grabación de Video",content:`## Grabación de Video
16506
16507### Activar Grabación
16508
165091. Al iniciar una prueba, activa el toggle de "Grabar Video"
165102. Se captura todo lo que ocurre en pantalla durante la prueba
165113. Al finalizar, el video se adjunta al reporte
16512
16513### Configuración
16514
16515- Formato: MP4
16516- FPS configurable
16517- Se almacena junto con las evidencias del test
16518
16519### Casos de Uso
16520
16521- Pruebas exploratorias donde necesitas mostrar el flujo completo
16522- Bugs difíciles de reproducir (el video muestra exactamente qué pasó)
16523- Demostraciones para stakeholders o desarrolladores
16524- Evidencia de timing (animaciones, transiciones, cargas)`},{id:"manual-anexos",title:"Anexos y Adjuntos",content:`## Anexos y Adjuntos
16525
16526### Tipos de Anexos Soportados
16527
16528- **JSON**: Respuestas de API, configuraciones, payloads
16529- **PDF**: Documentos de referencia, especificaciones
16530- **Archivos de texto**: Logs, outputs de consola
16531
16532### Cómo Adjuntar
16533
165341. Durante la ejecución de la prueba, click en "Adjuntar"
165352. Selecciona el archivo desde tu sistema
165363. El anexo se incluye en el reporte final con portada separada
16537
16538### En el Reporte PDF
16539
16540Los anexos aparecen en una sección dedicada con:
16541- Portada de anexos separada
16542- Cada archivo con su nombre y tipo
16543- Contenido embebido o referenciado`}]},{id:"pruebas-automatizadas",title:"Pruebas Automatizadas",icon:"",topics:[{id:"auto-grabar",title:"Grabar Scripts",content:`## Grabación de Scripts Playwright
16544
16545### Cómo Grabar
16546
165471. Ve a la pestaña "Playwright" en HakaBuddy
165482. Click en "Nueva Grabación"
165493. Configura las opciones del navegador
165504. Ingresa la URL inicial
165515. Se abre el navegador — interactúa normalmente
165526. Al cerrar el navegador, el script se guarda automáticamente
16553
16554### Opciones del Navegador
16555
16556| Opción | Descripción | Ejemplo |
16557|--------|-------------|---------|
16558| Navegador | Motor del browser | Chromium, Chrome, Edge |
16559| Viewport | Resolución de pantalla | 1920x1080 |
16560| User-Agent | Agente personalizado | Mozilla/5.0... |
16561| Headers | Headers HTTP custom | Authorization, X-Custom |
16562| Locale | Idioma del navegador | es-CL, en-US |
16563| Timezone | Zona horaria | America/Santiago |
16564| Slow Motion | Delay entre acciones | 100ms |
16565
16566### Con Sesión Autenticada
16567
16568Si necesitas grabar en un sitio con login/2FA:
165691. Primero captura una sesión (ver sección Sesiones Autenticadas)
165702. Al grabar, selecciona la sesión guardada
165713. El navegador se abre ya autenticado
165724. Graba las acciones post-login
16573
16574### Resultado
16575
16576La grabación genera un script Python compatible con Playwright que se almacena en la base de datos local de HakaBuddy. Puedes editarlo, ejecutarlo o incluirlo en una suite.`},{id:"auto-ejecutar",title:"Ejecutar Scripts",content:`## Ejecución de Scripts
16577
16578### Script Individual
16579
165801. Selecciona un script grabado de la lista
165812. Click en "Ejecutar"
165823. El navegador se abre y ejecuta las acciones grabadas
165834. Cada paso se captura con screenshot automático
165845. Al finalizar se muestra el resultado (passed/failed)
16585
16586### Lo que Ocurre Durante la Ejecución
16587
16588- Se captura screenshot en cada paso
16589- Se registra el tiempo de cada acción
16590- Se detecta automáticamente si el paso fue exitoso o falló
16591- Si falla, se captura el error y el estado de la pantalla
16592- Al finalizar se genera un reporte con toda la evidencia
16593
16594### Modos de Ejecución
16595
16596| Modo | Descripción | Uso |
16597|------|-------------|-----|
16598| Visible (headed) | Ves el navegador ejecutar | Debugging, demos |
16599| Invisible (headless) | Sin interfaz gráfica | CI/CD, ejecución masiva |
16600
16601### Con Sesión Autenticada
16602
16603Selecciona una sesión guardada al ejecutar para que el navegador inicie ya logueado en el sistema bajo prueba.`},{id:"auto-outline",title:"Scenario Outline (Datos)",content:`## Scenario Outline — Ejecución con Múlt
16603iples Datos
16604
16605### ¿Qué es?
16606
16607Permite ejecutar un mismo script con diferentes conjuntos de datos automáticamente. HakaBuddy detecta los valores parametrizables del script y te permite definir una tabla de datos.
16608
16609### Cómo Funciona
16610
166111. Selecciona un script grabado
166122. HakaBuddy analiza el script y detecta valores que pueden ser variables (textos ingresados, URLs, etc.)
166133. Defines una tabla de datos con diferentes combinaciones
166144. El script se ejecuta N veces, una por cada fila de datos
166155. Se genera un reporte consolidado
16616
16617### Ejemplo
16618
16619Si tu script graba un login:
16620\`\`\`
16621Paso 1: Ir a https://app.com/login
16622Paso 2: Escribir "[email protected]" en campo email
16623Paso 3: Escribir "password123" en campo password
16624Paso 4: Click en "Ingresar"
16625\`\`\`
16626
16627Puedes parametrizar:
16628| email | password | resultado_esperado |
16629|-------|----------|-------------------|
16630| [email protected] | password123 | Dashboard |
16631| [email protected] | user456 | Home |
16632| [email protected] | wrong | Error de login |
16633
16634El script se ejecuta 3 veces con diferentes datos.`},{id:"auto-editar",title:"Editar Scripts",content:`## Edición de Scripts
16635
16636### Editor Integrado
16637
16638HakaBuddy permite editar los scripts grabados directamente desde la aplicación:
16639
16640- Ver y modificar cada paso del script
16641- Cambiar selectores si la app cambió
16642- Agregar o quitar pasos
16643- Modificar textos y valores
16644- Reordenar pasos
16645
16646### Análisis de Script con IA
16647
16648La IA puede analizar tu script y sugerir:
16649- Mejores selectores (más robustos)
16650- Pasos de validación faltantes
16651- Optimizaciones de flujo
16652- Esperas implícitas recomendadas`}]},{id:"suites",title:"Suites de Regresion",icon:"",topics:[{id:"suites-crear",title:"Crear Suites",content:`## Crear una Suite de Regresión
16653
16654### ¿Qué es una Suite?
16655
16656Una suite agrupa múltiples scripts de automatización para ejecutarlos en secuencia como una prueba de regresión completa.
16657
16658### Crear una Suite
16659
166601. Ve a la sección de Suites
166612. Click en "Nueva Suite"
166623. Asigna un nombre descriptivo
166634. Agrega scripts arrastrándolos o seleccionándolos de la lista
166645. Configura el orden de ejecución (drag & drop)
16665
16666### Organización
16667
16668- Cada suite tiene un nombre y descripción
16669- Los scripts se ejecutan en el orden configurado
16670- Puedes agregar/quitar scripts en cualquier momento
16671- Un script puede estar en múltiples suites`},{id:"suites-ejecutar",title:"Ejecutar Suites",content:`## Ejecución de Suites
16672
16673### Flujo
16674
166751. Selecciona la suite a ejecutar
166762. Click en "Ejecutar Suite"
166773. Los scripts se ejecutan en orden secuencial
166784. Progreso en tiempo real (barra de progreso por script)
166795. Al finalizar: reporte consolidado
16680
16681### Durante la Ejecución
16682
16683- Barra de progreso general (scripts completados / total)
16684- Estado de cada script (en espera, ejecutando, passed, failed)
16685- Tiempo transcurrido
16686- Opción de cancelar la ejecución
16687
16688### Resultado
16689
16690Al finalizar la suite se genera:
16691- Reporte HTML consolidado con todos los scripts
16692- Resumen: scripts passed / failed / total
16693- Duración total y por script
16694- Evidencias de cada paso de cada script
16695
16696### Historial
16697
16698Cada ejecución de suite se registra con:
16699- Fecha y hora
16700- Duración total
16701- Scripts passed / failed
16702- Reporte descargable`}]},{id:"cicd",title:"Integracion CI/CD",icon:"",topics:[{id:"cicd-push",title:"Push a Repositorio",content:`## Push de Suites a CI/CD
16703
16704### Plataformas Soportadas
16705
16706| Plataforma | Workflow generado |
16707|------------|-----------------|
16708| GitHub | GitHub Actions (.github/workflows/) |
16709| GitLab | GitLab CI (.gitlab-ci.yml) |
16710| Bitbucket | Bitbucket Pipelines (bitbucket-pipelines.yml) |
16711
16712### Flujo
16713
167141. Configura las credenciales Git (token de acceso)
167152. Selecciona la suite a publicar
167163. Click en "Push a CI/CD"
167174. HakaBuddy genera automáticamente:
16718   - Los scripts de la suite como archivos .py
16719   - El workflow de CI/CD según la plataforma
16720   - El runner que ejecuta los scripts en headless
16721   - El requirements.txt con las dependencias
16722   - Configuración de artefactos (reportes como descargables)
167235. Push al repositorio seleccionado
16724
16725### Lo que se Genera
16726
16727\`\`\`
16728repo/
16729├── .github/workflows/regression.yml  # (o .gitlab-ci.yml)
16730├── scripts/
16731│   ├── script_login.py
16732│   ├── script_checkout.py
16733│   └── script_search.py
16734├── runner.py                          # Ejecutor de la suite
16735├── requirements.txt                   # playwright, etc.
16736└── README.md                          # Instrucciones
16737\`\`\``},{id:"cicd-workflow",title:"Workflow Generado",content:`## Workflow Generado
16738
16739### GitHub Actions (ejemplo)
16740
16741\`\`\`yaml
16742name: Regression Suite
16743on:
16744  workflow_dispatch:
16745  schedule:
16746    - cron: '0 8 * * 1-5'  # Lunes a viernes 8am
16747
16748jobs:
16749  test:
16750    runs-on: ubuntu-latest
16751    steps:
16752      - uses: actions/checkout@v4
16753      - uses: actions/setup-python@v5
16754        with:
16755          python-version: '3.11'
16756      - name: Install dependencies
16757        run: |
16758          pip install -r requirements.txt
16759          playwright install chromium
16760          playwright install-deps
16761      - name: Run regression
16762        run: python runner.py
16763      - name: Upload report
16764        if: always()
16765        uses: actions/upload-artifact@v4
16766        with:
16767          name: regression-report
16768          path: reports/
16769\`\`\`
16770
16771### Características del Workflow
16772
16773- Instalación automática de Python + Playwright
16774- Ejecución en modo headless
16775- Reporte HTML como artefacto descargable
16776- Configurable: schedule, trigger manual, o en cada push
16777- Notificación del resultado (passed/failed)`},{id:"cicd-runner",title:"Runner Template",content:`## Runner de CI/CD
16778
16779El runner es un script Python que HakaBuddy genera automáticamente. Ejecuta todos los scripts de la suite en orden y genera el reporte.
16780
16781### Qué Hace
16782
167831. Lee la configuración de la suite
167842. Ejecuta cada script en orden secuencial
167853. Captura screenshots en cada paso
167864. Detecta passed/failed por script
167875. Genera reporte HTML consolidado
167886. Retorna exit code 0 (todo passed) o 1 (alguno failed)
16789
16790### Personalización
16791
16792El runner se puede editar para:
16793- Cambiar el orden de ejecución
16794- Agregar setup/teardown global
16795- Configurar variables de entorno
16796- Ajustar timeouts
16797- Agregar notificaciones (Slack, email, etc.)`}]},{id:"reportes",title:"Reportes",icon:"",topics:[{id:"reportes-pdf",title:"Reporte PDF",content:`## Reporte PDF Profesional
16798
16799### Estructura del PDF
16800
168011. **Portada**: Logo, título del test, fecha, tester, producto, ambiente
168022. **Contenido**: Cada paso con título, estado (color verde/rojo), evidencia screenshot y observaciones
168033. **Portada de Anexos**: Separador visual si hay archivos adjuntos
168044. **Anexos**: Contenido de archivos JSON, PDFs adjuntados
168055. **Contraportada**: Logo y datos de la empresa/equipo
16806
16807### Personalización
16808
16809- Logo del equipo/empresa configurable
16810- Plantilla de portada personalizable
16811- Colores según estado (verde = exitoso, rojo = fallido)
16812- Formato de fecha y metadata configurables
16813- Fuente profesional (Calibri) incluida
16814
16815### Generación
16816
16817Al finalizar cualquier prueba (manual o automatizada):
168181. Click en "Generar PDF"
168192. Se genera automáticamente con toda la evidencia
168203. Se guarda en la carpeta de reportes del test
168214. Se puede abrir, compartir o enviar por email`},{id:"reportes-html",title:"Reporte HTML",content:`## Reporte HTML
16822
16823### Características
16824
16825- **Autocontenido**: Un solo archivo .html con todo embebido
16826- **Tema oscuro**: Diseño profesional con tema dark
16827- **Logos en base64**: No requiere carpeta de imágenes externa
16828- **Pasos expandibles**: Click para expandir/colapsar cada paso
16829- **Evidencias embebidas**: Screenshots en base64 (no requiere archivos externos)
16830- **Portable**: Se puede enviar por email o compartir sin dependencias
16831
16832### Ideal Para
16833
16834- Compartir resultados por email (un solo archivo adjunto)
16835- Publicar como artefacto en CI/CD
16836- Archivar con todas las evidencias autocontenidas
16837- Visualizar en cualquier navegador sin configuración`},{id:"reportes-xray",title:"Exportación Xray",content:`## Exportación Xray JSON
16838
16839### ¿Qué es?
16840
16841Exporta los resultados de prueba en formato JSON compatible con Jira Xray para importarlos directamente como Test Executions.
16842
16843### Estructura del JSON
16844
16845- Test Key (issue asociada en Jira)
16846- Status (PASS/FAIL)
16847- Steps con detalle y evidencia
16848- Metadata (fecha, tester, ambiente, duración)
16849- Evidencias adjuntas (screenshots)
16850
16851### Flujo
16852
168531. Al configurar la prueba, asocia una issue de Jira
168542. Ejecuta la prueba normalmente
168553. Al finalizar, click en "Exportar Xray"
168564. Se genera el JSON listo para importar en Xray
168575. Opcionalmente, se sube automáticamente vía API de Xray`},{id:"reportes-playwright",title:"Reporte de Scripts",content:`## Reporte de Scripts Automatizados
16858
16859### Reporte Individual
16860
16861Cada ejecución de script genera:
16862- Estado: passed/failed
16863- Duración total
16864- Detalle paso a paso con screenshots
16865- Error (si falló) con stack trace
16866
16867### Reporte de Suite
16868
16869La ejecución de una suite genera un reporte consolidado:
16870- Resumen ejecutivo (passed/failed/total)
16871- Duración total
16872- Detalle de cada script con sus pasos
16873- Evidencias de cada paso
16874- Estadísticas de la regresión`}]},{id:"jira-xray",title:"Integracion Jira y Xray",icon:"",topics:[{id:"jira-conexion",title:"Conectar con Jira",content:`## Integración con Jira Cloud
16875
16876### Funcionalidades
16877
16878- Conectar a tu proyecto de Jira Cloud
16879- Listar issues del proyecto (historias, bugs, tasks)
16880- Asociar pruebas a issues específicas
16881- Ver detalles de la issue desde HakaBuddy
16882- Filtrar issues por sprint, estado o asignado
16883
16884### Cómo Conectar
16885
168861. Ve a Configuraciones → Jira
168872. Ingresa URL, email y API Token
168883. Click en "Probar Conexión"
168894. Si es exitoso, verás los proyectos disponibles
16890
16891### Asociar Prueba a Issue
16892
168931. Al iniciar una prueba, click en "Vincular con Jira"
168942. Selecciona la issue de la lista o busca por key
168953. La prueba queda asociada y aparecerá en el reporte
16896
16897### Beneficios
16898
16899- Trazabilidad completa: prueba → issue → requerimiento
16900- El reporte PDF/HTML incluye la key de Jira
16901- Exportar resultados directamente a Xray`},{id:"jira-xray-export",title:"Exportar a Xray",content:`## Exportación a Xray
16902
16903### Formatos de Exportación
16904
16905| Formato | Uso |
16906|---------|-----|
16907| Xray JSON | Importar como Test Execution en Xray |
16908| Test Plan vinculado | Asociar resultados a un Test Plan existente |
16909
16910### Flujo de Exportación
16911
169121. Ejecuta tu prueba (manual o automatizada)
169132. La prueba está vinculada a una issue de Jira
169143. Al finalizar: click en "Exportar a Xray"
169154. Se genera el JSON de Test Execution
169165. Se puede subir manualmente o vía API
16917
16918### Exportación Automática (API)
16919
16920Si tienes configurado Client ID y Client Secret de Xray:
169211. La exportación se hace automáticamente al finalizar la prueba
169222. Se crea un Test Execution en Xray
169233. Los screenshots se adjuntan como evidencias
169244. El resultado (PASS/FAIL) se marca en cada step`}]},{id:"ia",title:"Inteligencia Artificial",icon:"",topics:[{id:"ia-descripcion",title:"¿Qué puede hacer la IA?",content:`## Inteligencia Artificial en HakaBuddy
16925
16926### Funcionalidades de IA
16927
16928| Función | Descripción |
16929|---------|-------------|
16930| Generar descripción de pasos | La IA sugiere títulos descriptivos para los pasos durante pruebas manuales |
16931| Análisis de fallos | Cuando un paso falla, la IA analiza el screenshot y sugiere posibles causas |
16932| Optimización de scripts | Sugiere mejoras en selectores y estructura de scripts |
16933| Análisis de script | Revisa un script completo y sugiere validaciones faltantes |
16934| Generación de datos | Sugiere datos de prueba para campos detectados |
16935
16936### Cuándo se Usa
16937
16938- Durante pruebas manuales: al registrar cada paso
16939- Después de una ejecución fallida: análisis del error
16940- Al revisar scripts: sugerencias de mejora
16941- En la creación de Scenario Outlines: datos para la tabla`},{id:"ia-proveedores",title:"Proveedores y Modelos",content:`## Proveedores de IA
16942
16943### Google Gemini (Recomendado)
16944
16945- Rápido y económico
16946- Modelos: gemini-2.0-flash (recomendado), gemini-pro
16947- Ideal para uso diario
16948
16949### OpenAI
16950
16951- Alta precisión en análisis complejos
16952- Modelos: gpt-4o, gpt-4o-mini
16953- Mayor costo por consulta
16954
16955### Claude (Anthropic)
16956
16957- Excelente razonamiento
16958- Modelos: claude-3-7-sonnet
16959- Bueno para análisis detallados
16960
16961### Ollama (Local)
16962
16963- 100% local, sin enviar datos a la nube
16964- Sin costo de API
16965- Modelos: llama3, mistral, codestral, y cualquier modelo descargado
16966- Funciona sin internet
16967- Requiere Ollama instalado localmente
16968
16969### Cambiar Proveedor
16970
16971Se puede cambiar de proveedor en cualquier momento desde Configuraciones → IA. No se pierde historial ni configuración.`}]},{id:"sesiones",title:"Sesiones Autenticadas",icon:"",topics:[{id:"sesiones-concepto",title:"Concepto",content:`## Sesiones Autenticadas
16972
16973### ¿Qué son?
16974
16975Las sesiones autenticadas permiten grabar y ejecutar scripts de Playwright en sitios que requieren login con 2FA/MFA (como Salesforce, SAP, Azure AD) sin tener que autenticarte cada vez.
16976
16977### ¿Cómo funcionan?
16978
169791. Capturas una sesión: se abre un navegador donde haces login manualmente (incluyendo 2FA)
169802. Al cerrar el navegador, HakaBuddy guarda las cookies y localStorage
169813. Cuando grabas o ejecutas un script, seleccionas la sesión guardada
169824. El navegador se abre ya autenticado, sin pasar por el login
16983
16984### Compatibilidad
16985
16986Funciona con cualquier sitio que use cookies para sesión:
16987- Salesforce
16988- SAP
16989- Azure AD / Microsoft 365
16990- Google Workspace
16991- Jira / Confluence
16992- ServiceNow
16993- Cualquier aplicación web con login`},{id:"sesiones-capturar",title:"Capturar y Gestionar",content:`## Capturar una Sesión
16994
16995### Desde la UI
16996
169971. Ve a Pruebas Automatizadas → "Sesiones"
169982. Click en "Nueva Sesión"
169993. Ingresa un nombre (ej: "admin_salesforce") y la URL de login
170004. Se abre un navegador: haz login completo (incluyendo 2FA)
170015. Cuando estés dentro del sistema, cierra el navegador
170026. La sesión se guarda automáticamente
17003
17004### Gestionar Sesiones
17005
17006Desde el diálogo de Sesiones puedes:
17007- **Listar** todas las sesiones guardadas (nombre, URL, fecha)
17008- **Renovar** una sesión expirada (re-capturar con el mismo nombre)
17009- **Eliminar** sesiones que ya no necesitas
17010- **Ver info** de una sesión (cookies, origen, fecha)
17011
17012### Usar al Grabar
17013
17014Al iniciar una nueva grabación:
170151. En las opciones de grabación, selecciona "Usar sesión autenticada"
170162. Elige la sesión de la lista
170173. El navegador se abre ya logueado en la URL capturada
17018
17019### Usar al Ejecutar
17020
17021Al ejecutar un script:
170221. Si el script fue grabado con sesión, la usa automáticamente
170232. También puedes seleccionar manualmente una sesión diferente
17024
17025### Expiración
17026
17027Las sesiones expiran según la configuración del servidor (típicamente 2-24 horas). Cuando expira, simplemente recaptura con el mismo nombre.`}]},{id:"debug",title:"Modo Debug con HakaPath",icon:"",topics:[{id:"debug-concepto",title:"¿Qué es el Modo Debug?",content:`## Modo Debug
17028
17029### ¿Qué es?
17030
17031El Modo Debug permite ejecutar scripts de Playwright paso a paso, deteniendo la ejecución en cada acción para inspeccionar el estado de la página, modificar pasos que fallen y generar selectores alternativos con HakaPath.
17032
17033### ¿Cuándo usarlo?
17034
17035- Un script que antes funcionaba ahora falla (la app cambió)
17036- Quieres entender qué hace exactamente cada paso del script
17037- Necesitas actualizar un selector que ya no funciona
17038- Quieres agregar validaciones en puntos específicos
17039
17040### Flujo
17041
170421. Selecciona un script y click en "Debug"
170432. Se abre el navegador y un panel lateral con los pasos
170443. Cada paso se muestra con su estado (pendiente, ejecutando, passed, failed)
170454. Click en "Siguiente" para avanzar paso a paso
170465. Si un paso falla, puedes editar el selector y reintentar
170476. Al finalizar, guardas las modificaciones al script`},{id:"debug-panel",title:"Panel de Debug",content:`## Panel de Debug
17048
17049### Interfaz
17050
17051El panel de debug muestra:
17052- Lista de todos los pasos del script (izquierda)
17053- Estado visual de cada paso: pendiente (gris), ejecutando (amarillo), passed (verde), failed (rojo)
17054- Botones de control: Ejecutar paso, Siguiente, Reintentar, Detener
17055- Detalle del paso actual (selector, acción, valor)
17056- Editor inline para modificar pasos
17057
17058### Cuando un Paso Falla
17059
17060Si un paso falla durante el debug:
170611. Se marca en rojo con el mensaje de error
170622. Puedes inspeccionar la página actual
170633. Opciones:
17064   - **Editar selector**: Modificar el localizador directamente
17065   - **Generar alternativas**: La IA sugiere selectores alternativos
17066   - **HakaPath**: Abre HakaPath para generar un selector robusto visualmente
17067   - **Reintentar**: Ejecutar el paso nuevamente con el selector modificado
17068   - **Saltar**: Continuar con el siguiente paso
17069
17070### Guardar Modificaciones
17071
17072Al finalizar el debug, si modificaste algún paso:
170731. HakaBuddy muestra un resumen de los cambios
170742. Puedes guardar las modificaciones al script original
170753. O guardar como nuevo script (mantener ambas versiones)`},{id:"debug-hakapath",title:"Integración con HakaPath",content:`## HakaPath en el Debug
17076
17077### ¿Qué es HakaPath?
17078
17079HakaPath es la extensión de Chrome para generar selectores robustos (XPath, CSS, data-testid). Cuando estás en modo Debug de HakaBuddy, puedes invocar HakaPath para generar un selector alternativo visualmente.
17080
17081### Flujo Integrado
17082
170831. Durante el debug, un paso falla porque el selector no encuentra el elemento
170842. Click en "Usar HakaPath" en el panel de debug
170853. Se activa la selección visual en el navegador
170864. Haces click en el elemento correcto
170875. HakaPath genera el selector (XPath, CSS, o data-testid)
170886. El selector se copia automáticamente al paso del script
170897. Reintenta el paso con el nuevo selector
17090
17091### Beneficio
17092
17093Combina la potencia del debug paso a paso con la generación visual de selectores, permitiendo actualizar scripts rápidamente cuando la aplicación cambia.`}]},{id:"historico",title:"Historico",icon:"",topics:[{id:"historico-pruebas",title:"Historial de Pruebas",content:`## Historial de Pruebas
17094
17095### Qué se Registra
17096
17097Cada prueba ejecutada (manual o automatizada) se almacena con:
17098- Fecha y hora de ejecución
17099- Producto y ambiente
17100- Tester (nombre del usuario)
17101- Tipo de prueba (manual/automatizada)
17102- Resultado (exitoso/fallido)
17103- Número de pasos y evidencias
17104- Reportes generados (PDF, HTML)
17105- Issue de Jira asociada (si aplica)
17106
17107### Filtros Disponibles
17108
17109- Por rango de fecha
17110- Por producto
17111- Por ambiente
17112- Por tester
17113- Por resultado (exitoso/fallido)
17114- Por tipo (manual/automatizada)
17115
17116### Acciones
17117
17118- Ver detalle completo de la prueba
17119- Descargar reportes (PDF/HTML)
17120- Re-ejecutar (para pruebas automatizadas)
17121- Duplicar (crear nueva prueba basada en una anterior)
17122- Eliminar registros antiguos`},{id:"historico-suites",title:"Historial de Suites",content:`## Historial de Ejecuciones de Suites
17123
17124### Qué se Registra
17125
17126Cada ejecución de suite se almacena con:
17127- Nombre de la suite ejecutada
17128- Fecha y hora
17129- Duración total
17130- Número de scripts: total, passed, failed
17131- Reporte HTML generado
17132- Enlace al reporte consolidado
17133
17134### Visualización
17135
17136- Lista cronológica de ejecuciones
17137- Indicador visual de resultado (verde = all passed, rojo = alguno failed)
17138- Acceso directo al reporte HTML de cada ejecución
17139- Comparación entre ejecuciones (tendencia de fallos)`}]},{id:"faq",title:"FAQ",icon:"",topics:[{id:"faq-general",title:"Preguntas Frecuentes",content:`## Preguntas Frecuentes
17140
17141### ¿Necesito saber programar para usar HakaBuddy?
17142
17143No para pruebas manuales ni para grabar scripts (la grabación es visual). Para editar scripts o crear custom steps sí necesitas conocimientos básicos de Python.
17144
17145### ¿Los datos se guardan en la nube?
17146
17147No. Todos los datos se guardan localmente en tu computador (SQLite). Nada se envía a servidores de Haka Lab.
17148
17149### ¿Puedo usar HakaBuddy sin internet?
17150
17151Sí, excepto para:
17152- Login inicial (necesita validar licencia)
17153- IA cloud (Gemini/OpenAI/Claude) — usa Ollama para IA local sin internet
17154- Integración con Jira/Xray
17155- Push a Git
17156
17157### ¿Funciona en macOS con Apple Silicon (M1/M2/M3)?
17158
17159Sí. El build de macOS soporta tanto Intel como Apple Silicon. Usa el build correspondiente a tu arquitectura.
17160
17161### ¿Puedo compartir pruebas entre compañeros?
17162
17163La base de datos es local por usuario. Para compartir:
17164- Exporta reportes (PDF/HTML) y comparte por email
17165- Usa la integración CI/CD para publicar suites
17166- Exporta a Xray para trazabilidad en Jira
17167
17168### ¿Qué pasa si actualizo la app?
17169
17170Los datos persisten entre actualizaciones. La base de datos se migra automáticamente si hay cambios de esquema.
17171
17172### ¿Puedo grabar pruebas en aplicaciones con 2FA/MFA?
17173
17174Sí, usando Sesiones Autenticadas. Capturas una sesión una vez (con login manual incluyendo MFA) y después grabas/ejecutas sin necesidad de re-autenticarte.
17175
17176### ¿Los scripts grabados funcionan en CI/CD?
17177
17178Sí. Al hacer Push a CI/CD, los scripts se adaptan automáticamente para ejecución headless. El workflow generado instala Playwright y ejecuta los scripts.
17179
17180### ¿Puedo editar los screenshots capturados?
17181
17182Sí. HakaBuddy incluye un editor de imágenes integrado con herramientas para resaltar áreas, agregar flechas, texto y difuminar información sensible.
17183
17184### ¿Cómo actualizo un script cuando la app cambia?
17185
17186Usa el Modo Debug: ejecuta paso a paso, identifica qué falló, y usa HakaPath para generar el selector correcto. Los cambios se guardan directamente al script.`}]}];function Nne(){const[t,e]=k.useState(null),[a,n]=k.useState(null),[i,r]=k.useState(""),[o,l]=k.useState(!1),c=k.useMemo(()=>{const m=new Set;return Tne.filter(h=>m.has(h.id)?!1:(m.add(h.id),!0))},[]);k.useEffect(()=>{document.title="Docs - HakaBuddy | Haka Lab",c.length>0&&(e(c[0].id),c[0].topics.length>0&&n(c[0].topics[0].id))},[c]);const d=k.useMemo(()=>{if(!i.trim())return c;const m=i.toLowerCase();return c.map(h=>({...h,topics:h.topics.filter(g=>g.title.toLowerCase().includes(m)||g.content.toLowerCase().includes(m))})).filter(h=>h.topics.length>0)},[i,c]),u=k.useMemo(()=>{for(const m of c){const h=m.topics.find(g=>g.id===a);if(h)return h}return null},[a,c]),p=(m,h)=>{e(m),n(h),l(!1)};return s.jsxs("div",{className:"bg-dark min-h-screen",children:[s.jsxs("div",{className:"lg:hidden sticky top-0 z-30 bg-dark/95 backdrop-blur border-b border-gray-800 px-4 py-3 flex items-center gap-3",children:[s.jsx("button",{onClick:()=>l(!o),className:"text-gray-300 hover:text-primary",children:s.jsx("svg",{className:"w-6 h-6",fill:"none",stroke:"currentColor",viewBox:"0 0 24 24",children:s.jsx("path",{strokeLinecap:"round",strokeLinejoin:"round",strokeWidth:2,d:"M4 6h16M4 12h16M4 18h16"})})}),s.jsx("h1",{className:"text-white font-semibold text-sm truncate",children:"HakaBuddy - Docs"})]}),s.jsxs("div",{className:"flex",children:[o&&s.jsx("div",{className:"lg:hidden fixed inset-0 z-40 bg-black/60",onClick:()=>l(!1)}),s.jsxs("aside",{className:`
17187          fixed lg:sticky top-0 left-0 z-50 lg:z-10
17188          w-80 h-screen overflow-y-auto
17189          bg-darkGray border-r border-gray-800
17190          transition-transform duration-300
17191          ${o?"translate-x-0":"-translate-x-full lg:translate-x-0"}
17192        `,children:[s.jsxs("div",{className:"p-5 border-b border-gray-800",children:[s.jsxs(Te,{to:"/docs",className:"text-xs text-gray-400 hover:text-primary transition-colors flex items-center gap-1 mb-3",children:[s.jsx("svg",{className:"w-3 h-3",fill:"none",stroke:"currentColor",viewBox:"0 0 24 24",children:s.jsx("path",{strokeLinecap:"round",strokeLinejoin:"round",strokeWidth:2,d:"M15 19l-7-7 7-7"})}),"Volver a Docs"]}),s.jsx("h2",{className:"text-white font-bold text-lg mb-1",children:"HakaBuddy"}),s.jsx("p",{className:"text-gray-400 text-xs",children:"Aplicación de Escritorio para QA"})]}),s.jsx("div",{className:"p-4",children:s.jsxs("div",{className:"relative",children:[s.jsx("svg",{className:"absolute left-3 top-1/2 -translate-y-1/2 w-4 h-4 text-gray-500",fill:"none",stroke:"currentColor",viewBox:"0 0 24 24",children:s.jsx("path",{strokeLinecap:"round",strokeLinejoin:"round",strokeWidth:2,d:"M21 21l-6-6m2-5a7 7 0 11-14 0 7 7 0 0114 0z"})}),s.jsx("input",{type:"text",placeholder:"Buscar en docs...",value:i,onChange:m=>r(m.target.value),className:"w-full pl-10 pr-4 py-2 bg-dark border border-gray-700 rounded-lg text-sm text-white placeholder-gray-500 focus:outline-none focus:border-primary"})]})}),s.jsx("nav",{className:"px-3 pb-6",children:d.map(m=>{const h=i.trim()?!0:t===m.id;return s.jsxs("div",{className:"mb-2",children:[s.jsxs("button",{onClick:()=>e(t===m.id?null:m.id),className:"w-full flex items-center justify-between px-3 py-2 text-sm font-semibold text-gray-300 hover:text-white rounded-md hover:bg-dark/50 transition-colors",children:[s.jsxs("span",{className:"flex items-center gap-2",children:[s.jsx("span",{children:m.icon}),s.jsx("span",{children:m.title})]}),s.jsx("svg",{className:`w-4 h-4 transition-transform ${h?"rotate-90":""}`,fill:"none",stroke:"currentColor",viewBox:"0 0 24 24",children:s.jsx("path",{strokeLinecap:"round",strokeLinejoin:"round",strokeWidth:2,d:"M9 5l7 7-7 7"})})]}),h&&s.jsx("div",{className:"ml-4 mt-1 space-y-0.5",children:m.topics.map(g=>s.jsx("button",{onClick:()=>p(m.id,g.id),className:`w-full text-left px-3 py-1.5 text-sm rounded-md transition-colors ${a===g.id?"text-primary bg-primary/10 border-l-2 border-primary":"text-gray-400 hover:text-gray-200 hover:bg-dark/30"}`,children:g.title},g.id))})]},m.id)})})]}),s.jsx("main",{className:"flex-1 min-w-0 px-4 sm:px-8 lg:px-12 py-8 lg:py-12 max-w-4xl",children:u?s.jsxs("article",{children:[s.jsx("h1",{className:"text-3xl md:text-4xl font-bold text-white mb-6",children:u.title}),s.jsx("div",{className:"prose prose-invert prose-lg max-w-none docs-content",children:s.jsx(Ine,{content:u.content})})]}):s.jsx("div",{className:"text-center py-20",children:s.jsx("p",{className:"text-gray-400 text-lg",children:"Selecciona un tema del menú lateral"})})})]})]})}function Ine({content:t}){return Pne(t).map((a,n)=>s.jsx(Rne,{block:a},n))}function Pne(t){var i;const e=[],a=t.split(`
17193`);let n=0;for(;n<a.length;){const r=a[n];if(r.startsWith("```")){const o=r.slice(3).trim(),l=[];for(n++;n<a.length&&!a[n].startsWith("```");)l.push(a[n]),n++;e.push({type:"code",lang:o,code:l.join(`
17194`)}),n++;continue}if(r.startsWith("## ")){e.push({type:"h2",text:r.slice(3)}),n++;continue}if(r.startsWith("### ")){e.push({type:"h3",text:r.slice(4)}),n++;continue}if(r.includes("|")&&n+1<a.length&&((i=a[n+1])!=null&&i.includes("---"))){const o=[];for(;n<a.length&&a[n].includes("|");)o.push(a[n]),n++;e.push({type:"table",rows:o});continue}if(r.startsWith("- ")||r.startsWith("* ")){const o=[];for(;n<a.length&&(a[n].startsWith("- ")||a[n].startsWith("* "));)o.push(a[n].slice(2)),n++;e.push({type:"list",items:o});continue}if(r.startsWith("step: ")){e.push({type:"step",text:r.slice(6)}),n++;continue}if(r.startsWith("descripcion: ")){e.push({type:"description",text:r.slice(13)}),n++;continue}if(r.startsWith("**")&&r.endsWith("**")){e.push({type:"bold",text:r.slice(2,-2)}),n++;continue}if(r.trim()===""||r.trim()==="---"){n++;continue}e.push({type:"paragraph",text:r}),n++}return e}function Rne({block:t}){switch(t.type){case"h2":return s.jsx("h2",{className:"text-2xl font-bold text-white mt-8 mb-4",children:t.text});case"h3":return s.jsx("h3",{className:"text-xl font-semibold text-gray-200 mt-6 mb-3",children:t.text});case"bold":return s.jsx("p",{className:"font-semibold text-primary mt-4 mb-2",children:t.text});case"paragraph":return s.jsx("p",{className:"text-gray-300 mb-3 leading-relaxed",children:s.jsx(wb,{text:t.text})});case"step":return s.jsx("div",{className:"bg-primary/5 border-l-4 border-primary px-4 py-2 my-3 rounded-r-lg",children:s.jsx("code",{className:"text-primary text-sm font-mono",children:t.text})});
17194case"description":return s.jsx("p",{className:"text-gray-400 text-sm mb-4 ml-4",children:t.text});case"code":return s.jsxs("div",{className:"my-4 rounded-lg overflow-hidden border border-gray-700",children:[t.lang&&s.jsx("div",{className:"bg-gray-800 px-4 py-1.5 text-xs text-gray-400 border-b border-gray-700",children:t.lang}),s.jsx("pre",{className:"bg-[#0d1117] p-4 overflow-x-auto",children:s.jsx("code",{className:"text-sm text-gray-300 font-mono whitespace-pre",children:t.code})})]});case"list":return s.jsx("ul",{className:"list-disc list-inside space-y-1 text-gray-300 mb-4 ml-2",children:t.items.map((e,a)=>s.jsx("li",{children:s.jsx(wb,{text:e})},a))});case"table":return s.jsx(Lne,{rows:t.rows});default:return null}}function Lne({rows:t}){if(t.length<2)return null;const e=i=>i.split("|").filter(r=>r.trim()!=="").map(r=>r.trim()),a=e(t[0]),n=t.slice(2).map(e);return s.jsx("div",{className:"overflow-x-auto my-4 rounded-lg border border-gray-700",children:s.jsxs("table",{className:"w-full text-sm",children:[s.jsx("thead",{className:"bg-gray-800",children:s.jsx("tr",{children:a.map((i,r)=>s.jsx("th",{className:"px-4 py-2 text-left text-gray-300 font-semibold",children:i},r))})}),s.jsx("tbody",{className:"divide-y divide-gray-800",children:n.map((i,r)=>s.jsx("tr",{className:"hover:bg-dark/50",children:i.map((o,l)=>s.jsx("td",{className:"px-4 py-2 text-gray-400",children:s.jsx(wb,{text:o})},l))},r))})]})})}function wb({text:t}){return t.split(/(`[^`]+`|\*\*[^*]+\*\*)/g).map((a,n)=>a.startsWith("`")&&a.endsWith("`")?s.jsx("code",{className:"bg-gray-800 px-1.5 py-0.5 rounded text-primary text-sm font-mono",children:a.slice(1,-1)},n):a.startsWith("**")&&a.endsWith("**")?s.jsx("strong",{className:"text-white font-semibold",children:a.slice(2,-2)},n):s.jsx("span",{children:a},n))}const One=[{id:"inicio",title:"Inicio",icon:"",topics:[{id:"que-es",title:"¿Qué es HakaPath?",content:`## ¿Qué es HakaPath?
17195
17196HakaPath es una extensión de Chrome/Edge (Manifest V3) que captura elementos web mediante el menú contextual y genera múltiples localizadores XPath y CSS listos para usarse en suites de automatización.
17197
17198### Flujo Básico
17199
172001. Haz clic derecho sobre un elemento en cualquier página
172012. Selecciona "Obtener HakaPath"
172023. Se abre el popup con localizadores generados automáticamente
172034. Copia el que necesites o conviértelo al formato de tu framework
17204
17205### Características Principales
17206
17207- **6 slots de localizadores**: 3 XPath + 3 CSS (incluyendo generación con IA)
17208- **Conteo de coincidencias**: badges que muestran cuántas veces aparece el selector en el DOM
17209- **Conversión a WebElement**: botón que transforma al formato de tu framework
17210- **Exportación POM**: genera Page Object Model en 4 lenguajes × 4 frameworks
17211- **Indicador de robustez** (Pro): puntúa cada localizador de 0 a 100
17212- **Detección de volatilidad**: advierte cuando un selector usa atributos dinámicos
17213- **5 pestañas**: Localizadores, Relativos, Semánticos, POM/Exportar, Configuración
17214
17215### Frameworks Soportados
17216
17217| Framework | Lenguajes |
17218|-----------|-----------|
17219| Selenium | Python, Java, JavaScript, C# |
17220| Playwright | Python, Java, JavaScript, C# |
17221| Cypress | JavaScript |
17222| Appium | Python, Java, JavaScript, C# |`},{id:"instalacion",title:"Instalación",content:`## Instalación
17223
17224### Desde Chrome Web Store
17225
17226Busca "HakaPath" en la Chrome Web Store e instala directamente. Compatible con Chrome 88+ y Edge 88+.
17227
17228### Modo Desarrollador
17229
172301. Descarga o clona el repositorio
172312. Abre \`chrome://extensions/\` y activa Developer mode
172323. Usa "Load unpacked" apuntando a la carpeta del proyecto
172334. Fija HakaPath a la barra del navegador (pin)
17234
17235### Primer Uso
17236
172371. Al abrir por primera vez, aparece selección de idioma (Español/English) — obligatorio
172382. Selecciona tipo de cuenta:
17239   - **Free**: Registro con nombre, email y empresa (sin contraseña)
17240   - **Pro**: Login con email/contraseña, Google o Microsoft
172413. Los clientes de Haka Lab tienen acceso Pro sin costo con su cuenta corporativa
17242
17243### Requisitos
17244
17245- Chrome 88+ o Edge 88+ (Chromium con Manifest V3)
17246- Chrome 127+ para Chrome Built-in AI (Gemini Nano local, opcional)
17247- Conexión a internet para login y proveedores de IA externos`},{id:"free-vs-pro",title:"Free vs Pro",content:`## Free vs Pro
17248
17249| Capacidad | Free | Pro |
17250|-----------|------|-----|
17251| Localizadores XPath | 1 slot local | 3 slots (2 locales + 1 IA) |
17252| Localizadores CSS | 1 slot local | 3 slots (2 locales + 1 IA) |
17253| Localizadores Semánticos | 1 de cada tipo | 2 de cada tipo |
17254| Localizadores Relativos | Above y Near | Los 5 (Above, Below, Near, Left, Right) |
17255| Proveedores de IA | Solo Chrome Built-in AI | Chrome AI + OpenAI + Claude + Gemini |
17256| Frameworks | Selenium, Playwright | Selenium, Playwright, Cypress, Appium |
17257| Indicador de robustez | No | Si, con puntaje y detalles |
17258| Exportación POM | Si | Si |
17259| Histórico | Si | Si |
17260| Tema oscuro/claro | Si | Si |`}]},{id:"localizadores",title:"Localizadores XPath y CSS",icon:"",topics:[{id:"loc-captura",title:"Capturar un Elemento",content:`## Capturar un Elemento
17261
17262### Pasos
17263
172641. Navega a cualquier página web
172652. Haz **click derecho** sobre el elemento que quieres localizar
172663. Selecciona **"Obtener HakaPath"** del menú contextual
172674. Se abre automáticamente la ventana de HakaPath con los localizadores
17268
17269### Lo que se Captura
17270
17271Al hacer click derecho, HakaPath recolecta:
17272- Tag, id, class, name, title, role, alt, href, type
17273- Texto visible (textContent)
17274- Atributos data-* (data-testid, data-qa, data-cy, etc.)
17275- Atributos aria-* (aria-label, aria-describedby)
17276- Placeholder, value, src
17277- outerHTML del elemento (contexto real)
17278- Información de hermanos (siblings): tag, id, class, texto
17279- Posición entre hermanos (siblingIndex)
17280- Información del padre (tag, id, name, title, class)
17281
17282### Evaluación Automática
17283
17284Cada localizador generado se evalúa contra el DOM real:
17285- **Badge verde [1]**: Exactamente 1 coincidencia (ideal, localizador único)
17286- **Badge rojo [4]**: Múltiples coincidencias (ambiguo, no recomendado)
17287- **Badge azul [0]**: Sin coincidencias (sugerido para mejora)`},{id:"loc-xpath",title:"Estrategias XPath",content:`## Estrategias de Generación XPath
17288
17289HakaPath usa 13+ estrategias para generar XPaths, priorizando las que dan exactamente 1 match:
17290
172911. **ID absoluto**: \`//*[@id="..."]\`
172922. **Atributos únicos**: data-testid, data-qa, name, aria-label
172933. **Atributos extra**: placeholder, type, href, src, value
172944. **Combinación de atributos**: múltiples atributos con AND
172955. **Parent + child con atributos**: contexto del padre
172966. **Parent + child con texto**: padre + texto del elemento
172977. **Clase específica**: primera clase CSS del elemento
172988. **Posición con parent**: \`(parent//tag)[N]\`
172999. **Following/preceding-sibling**: relación con hermanos
1730010. **Texto exacto**: \`//*[text()='...']\`
1730111. **Contains text**: \`//*[contains(text(),'...')]\`
1730212. **Jerarquía con índices**: ruta completa con posiciones
1730313. **Ancestor + descendant**: patrones avanzados
1730414. **Combinaciones OR**: múltiples condiciones opcionales
17305
17306### Priorización
17307
17308Se priorizan en orden:
173091. Selectores con 1 sola coincidencia
173102. Selectores cortos y semánticos (data-testid, id, name)
173113. Selectores que no usan clases CSS (pueden ser dinámicas)
173124. Selectores que no dependen de posición`},{id:"loc-css",title:"Estrategias CSS",content:'## Estrategias de Generación CSS\n\n### Estrategias (en orden de prioridad)\n\n1. **ID**: `#element-id`\n2. **Atributos de testing**: `[data-testid="value"]`\n3. **Clase única**: `tag.class-name`\n4. **Atributos**: `tag[attr="value"]`\n5. **Combinadores**: `parent > child`, `ancestor descendant`\n6. **Pseudo-clases**: `:nth-child()`, `:first-child`\n7. **Atributos múltiples**: `tag[attr1="v1"][attr2="v2"]`\n8. **Selectores compuestos**: especificidad creciente\n\n### Validación de Compatibilidad\n\nHakaPath valida cada CSS generado contra el motor de Chrome actual:\n- Usa `CSS.supports(\'selector(...)\')` para verificar soporte\n- Prueba con `document.querySelector(sel)` para detectar errores de sintaxis\n- Muestra la versión de Chrome donde es compatible'},{id:"loc-acciones",title:"Acciones sobre Localizadores",content:`## Acciones Disponibles
17313
17314### Copiar (botón azul)
17315
17316- Copia el localizador al portapapeles
17317- Muestra notificación "Selector Copiado!"
17318- Automáticamente agrega la línea al POM (pestaña POM/Exportar)
17319
17320### Convertir a WebElement (botón </>)
17321
17322Transforma el localizador al formato ejecutable del framework configurado:
17323
17324\`\`\`
17325Selenium (Python):    driver.find_element(By.XPATH, "//...")
17326Selenium (Java):      driver.findElement(By.xpath("//..."))
17327Playwright (Python):  page.locator("...")
17328Playwright (Java/JS): page.locator("...")
17329Cypress:              cy.get("...") / cy.xpath("...")
17330Appium (Python):      driver.find_element(AppiumBy.XPATH, "...")
17331\`\`\`
17332
17333Click de nuevo: revierte al localizador crudo (toggle).
17334
17335### Badge de Coincidencias
17336
17337Muestra cuántas veces aparece el localizador en el DOM actual:
17338- **[1]** Verde: único (ideal)
17339- **[N]** Rojo: múltiples (ambiguo)
17340- **[0]** Azul: ninguna (sugerido para mejora)`}]},{id:"relativos",title:"Localizadores Relativos",icon:"",topics:[{id:"rel-descripcion",title:"Cómo Funcionan",content:`## Localizadores Relativos
17341
17342Los localizadores relativos encuentran elementos según su posición visual respecto a otro elemento. Soportado por Selenium 4+ y Playwright.
17343
17344### Tipos Disponibles
17345
17346| Tipo | Descripción | Disponibilidad |
17347|------|-------------|----------------|
17348| Above | Elemento posicionado debajo de una referencia | Free + Pro |
17349| Below | Elemento posicionado arriba de una referencia | Pro |
17350| Near | Elemento cercano a una referencia | Free + Pro |
17351| To Left Of | Elemento a la izquierda de una referencia | Pro |
17352| To Right Of | Elemento a la derecha de una referencia | Pro |
17353
17354### Formato según Framework
17355
17356\`\`\`
17357Selenium 4 (Java):   RelativeLocator.with(By.tagName("a")).below(By.id("ref"))
17358Selenium 4 (Python): locate_with(By.TAG_NAME, "a").below(By.ID, "ref")
17359Selenium 4 (C#):     RelativeBy.WithLocator(By.TagName("a")).Below(By.Id("ref"))
17360Playwright:          page.locator("a:below(#ref)")
17361\`\`\`
17362
17363### Generación
17364
17365HakaPath analiza los hermanos (siblings) del elemento capturado para determinar referencias posicionales válidas. Si no hay hermanos identificables cercanos, se muestra "No se encontró referencia de hermano".`}]},{id:"semanticos",title:"Localizadores Semánticos",icon:"",topics:[{id:"sem-descripcion",title:"By Role, Text, TestId",content:`## Localizadores Semánticos
17366
17367Los localizadores semánticos usan atributos accesibles (rol, texto, label) para encontrar elementos. Recomendado por Playwright y Testing Library.
17368
17369### By Role
17370
17371Detecta el rol del elemento (explícito vía atributo "role" o implícito por el tag HTML):
17372
17373\`\`\`
17374getByRole('link', { name: 'Servicios' })
17375getByRole('button', { name: 'Enviar' })
17376getByRole('textbox', { name: 'Email' })
17377\`\`\`
17378
17379Mapa de roles implícitos: button→button, a→link, input→textbox, select→combobox, h1-h6→heading, nav→navigation.
17380
17381El nombre accesible se obtiene de: aria-label > texto visible > title > alt > placeholder.
17382
17383### By Text / Label / Placeholder
17384
17385\`\`\`
17386getByText('Servicios')              // Texto visible
17387getByLabel('Email')                 // aria-label o label asociad
17387o
17388getByPlaceholder('Ingresa tu email') // Placeholder del input
17389getByAltText('Logo empresa')        // Alt de imagen
17390getByTitle('Cerrar modal')          // Atributo title
17391\`\`\`
17392
17393### By TestId
17394
17395Busca atributos de testing: data-testid, data-test-id, data-test, data-qa, data-cy, data-pw.
17396
17397\`\`\`
17398getByTestId('header-servicios-link')
17399getByTestId('submit-button')
17400\`\`\`
17401
17402Fallback: usa el ID si parece estable (no autogenerado).
17403
17404### Formato según Framework
17405
17406\`\`\`
17407Playwright (Python/Java/JS): page.getByRole('button', { name: 'Login' })
17408Playwright (C#):             Page.GetByRole('button', { name: 'Login' })
17409Cypress:                     cy.findByRole('button', { name: 'Login' })
17410Selenium/Appium:             Comentario indicando usar Playwright/Cypress
17411\`\`\``}]},{id:"pom",title:"POM / Exportar",icon:"",topics:[{id:"pom-generacion",title:"Generación Automática",content:`## Generación de Page Object Model
17412
17413### Funcionamiento
17414
17415Cada vez que copias un localizador (botón copiar en cualquier pestaña), se agrega automáticamente una línea al POM con el formato correcto.
17416
17417### Ejemplo con Selenium + Python
17418
17419\`\`\`python
17420from selenium.webdriver.common.by import By
17421
17422  servicios_link = (By.XPATH, "//*[@id='header-servicios']")
17423  login_button = (By.CSS_SELECTOR, "#login-btn")
17424\`\`\`
17425
17426### Ejemplo con Playwright + Java
17427
17428\`\`\`java
17429import com.microsoft.playwright.*;
17430
17431  public Locator servicios = page.locator("//*[@id='header']");
17432  public Locator login = page.locator("#login-btn");
17433\`\`\`
17434
17435### 16 Combinaciones Soportadas
17436
17437| Framework | Python | Java | JavaScript | C# |
17438|-----------|--------|------|------------|-----|
17439| Selenium | Si | Si | Si | Si |
17440| Playwright | Si | Si | Si | Si |
17441| Cypress | — | — | Si | — |
17442| Appium | Si | Si | Si | Si |
17443
17444### Nombrado Automático
17445
17446Los nombres de variables se generan automáticamente basándose en:
17447- Tag del elemento + atributos relevantes
17448- Texto del localizador (IDs, clases semánticas)
17449- Formato camelCase o snake_case según el lenguaje`},{id:"pom-exportar",title:"Exportar y Descargar",content:`## Exportar POM
17450
17451### Descargar Archivo
17452
17453- Click en botón de descarga (ícono nube con flecha)
17454- Se descarga con la extensión correcta: .py, .java, .js, .cs
17455- Incluye header con firma HakaPath
17456- Incluye imports necesarios del framework
17457
17458### Textarea Editable
17459
17460- Puedes editar manualmente el contenido del POM
17461- Los cambios se persisten en chrome.storage.local
17462- Se mantiene entre sesiones hasta que se limpie
17463
17464### Limpiar POM
17465
17466- Click en botón limpiar (ícono varita)
17467- Pregunta confirmación antes de borrar
17468- Reinicia el textarea para empezar de nuevo`}]},{id:"ia",title:"Inteligencia Artificial",icon:"",topics:[{id:"ia-proveedores",title:"Proveedores y Modelos",content:`## Inteligencia Artificial
17469
17470HakaPath genera localizadores inteligentes en los slots 3 (XPath) y 6 (CSS) usando IA.
17471
17472### Proveedores
17473
17474| Proveedor | Modelos | Disponibilidad |
17475|-----------|---------|----------------|
17476| Chrome Built-in AI | Gemini Nano (local) | Free + Pro |
17477| OpenAI | GPT-4o Mini, GPT-4o, GPT-4.1 Nano/Mini/Full | Solo Pro |
17478| Claude (Anthropic) | Sonnet 4, Haiku 3.5, Opus 4 | Solo Pro |
17479| Google Gemini | 3.1 Flash Lite, 2.0 Flash, 2.5 Flash, 2.5 Pro | Solo Pro |
17480
17481### Chrome Built-in AI (Gemini Nano)
17482
17483- Ejecuta 100% localmente en el dispositivo
17484- No requiere API key ni conexión a internet
17485- Requiere Chrome 127+ con flags de IA habilitados
17486- Disponible en versión Free
17487- Limitación: inputs largos se truncan a ~4000 caracteres
17488
17489### Flujo de Generación
17490
174911. Usuario captura elemento (click derecho)
174922. Slots 1, 2, 4, 5 se generan instantáneamente (locales)
174933. Slots 3 y 6 muestran "Creando con IA, espera..."
174944. Se envía al proveedor: info del elemento, padre, hermanos, outerHTML
174955. La IA genera un XPath (slot 3) y un CSS (slot 6) optimizados
174966. Se evalúan coincidencias y se muestra badge "AI"
174977. Tiempo típico: 1-5 segundos
17498
17499### Si la IA Falla
17500
17501- Se usa un tercer localizador local como fallback
17502- No se muestra etiqueta "AI"
17503- La funcionalidad principal no se ve afectada`}]},{id:"robustez",title:"Indicador de Robustez",icon:"",topics:[{id:"robustez-algoritmo",title:"Algoritmo y Puntuación",content:`## Indicador de Robustez (Solo Pro)
17504
17505### Puntuación: 0-100
17506
17507Cada localizador recibe un puntaje visual:
17508- **Verde (70-100)**: Robusto — usa atributos estables
17509- **Amarillo (40-69)**: Moderado — tiene algunos riesgos
17510- **Rojo (0-39)**: Frágil — depende de elementos volátiles
17511
17512### Penalizaciones (restan puntos)
17513
17514- Clases CSS dinámicas (patrones: ng-, react-, css-, hash, sc-)
17515- Índices posicionales ([1], [position()=])
17516- IDs autogenerados (GUIDs, hashes, :r0:)
17517- Rutas absolutas (/html/body/...)
17518- Profundidad excesiva (>5 niveles)
17519- Atributos volátiles detectados por el observador DOM
17520
17521### Bonificaciones (suman puntos)
17522
17523- data-testid, data-qa, data-test (+15)
17524- aria-label, aria-describedby (+10)
17525- Atributo name (+10)
17526- Atributo role (+8)
17527- IDs estables (cortos, semánticos) (+12)
17528- Rutas cortas (<3 niveles) (+8)
17529- Coincidencia por texto (+5)
17530
17531### Tooltip Detallado
17532
17533Al pasar el mouse sobre el indicador:
17534\`\`\`
17535Puntuación de robustez: 85/100
17536Penalizaciones: clase dinámica detectada (-5)
17537Bonificaciones: usa data-testid (+15), ruta corta (+8)
17538\`\`\``},{id:"robustez-volatilidad",title:"Detección de Volatilidad",content:`## Detección de Volatilidad
17539
17540### MutationObserver
17541
17542Al capturar un elemento, HakaPath activa un observador DOM por 10 segundos:
17543- Observa hasta 3 niveles de ancestros
17544- Detecta cambios en atributos (attributeOldValue: true)
17545- Se desconecta automáticamente al finalizar
17546
17547### ¿Qué Detecta?
17548
17549- Atributos que cambian durante la observación (mutaciones reales)
17550- Clases con hashes (css-abc123, sc-dkzDqf)
17551- IDs con timestamps o UUIDs
17552- Atributos data-* que cambian en cada render
17553- Clases de estado (active, selected, hover, focus)
17554
17555### Cuando se Detecta Volatilidad
17556
17557Aparece un ícono de advertencia (triángulo amarillo) con:
17558- Tooltip: "Atributo volátil detectado: class cambió durante observación"
17559- Panel inferior con localizadores alternativos que evitan los atributos volátiles
17560
17561### Auto-Heal (Fingerprinting)
17562
17563Cada elemento capturado genera una huella digital con:
17564- Tag, atributos, texto, posición entre hermanos, ancestros
17565- Si un localizador falla en el futuro, se buscan candidatos por similitud ponderada`}]},{id:"configuracion",title:"Configuración",icon:"",topics:[{id:"config-opciones",title:"Opciones",content:`## Configuración
17566
17567### Opciones Disponibles
17568
17569| Opción | Valores | Nota |
17570|--------|---------|------|
17571| Framework | Selenium, Playwright, Cypress*, Appium* | *Solo Pro |
17572| Lenguaje WebElement | Python, Java, JavaScript, C# | Afecta conversión y POM |
17573| Idioma | Español / English | Requiere reiniciar |
17574| Máx. Histórico | 1-30 | Límite de entradas guardadas |
17575| Proveedor IA | Deshabilitado, Chrome AI, OpenAI*, Claude*, Gemini* | *Solo Pro |
17576| Modelo | Según proveedor | Seleccionable |
17577| API Key | Campo password | Solo proveedores externos |
17578| Tema | Oscuro / Claro | Toggle inmediato |
17579
17580### Importante
17581
17582- El lenguaje no se puede cambiar si hay contenido en el POM (debe limpiar primero)
17583- El cambio de framework afecta: formato de conversión, generación POM, formato de relativos
17584- Toda la configuración se guarda en chrome.storage.local`}]},{id:"faq",title:"FAQ",icon:"",topics:[{id:"faq-general",title:"Preguntas Frecuentes",content:`## Preguntas Frecuentes
17585
17586### ¿Funciona en cualquier página web?
17587
17588Sí. HakaPath se inyecta como content script en todas las URLs y funciona en cualquier página web.
17589
17590### ¿Necesito internet para generar localizadores?
17591
17592No. Los localizadores locales (slots 1, 2, 4, 5) se generan sin internet. Solo la IA externa requiere conexión (excepto Chrome Built-in AI que es local).
17593
17594### ¿Por qué mi localizador tiene badge rojo?
17595
17596Badge rojo significa que el selector coincide con múltiples elementos en el DOM (no es único). Usa uno con badge verde [1] para asegurar unicidad.
17597
17598### ¿Qué hago si el badge es azul [0]?
17599
17600Badge azul significa que no se encontró ninguna coincidencia. Esto puede ocurrir si:
17601- El elemento es dinámico y ya no está en el DOM
17602- La IA sugirió un selector mejorado que requiere un atributo que se debería agregar (data-testid)
17603
17604### ¿Por qué algunos slots dicen "Disponible en versión Pro"?
17605
17606En la versión Free, solo tienes 1 slot XPath y 1 slot CSS local. Los slots adicionales y la IA avanzada requieren cuenta Pro.
17607
17608### ¿Puedo usar HakaPath con Selenium y Playwright al mismo tiempo?
17609
17610Puedes cambiar de framework en cualquier momento desde la configuración. El POM se genera según el framework activo. Si cambias de framework, debes limpiar el POM actual.
17611
17612### ¿Los localizadores se guardan entre sesiones?
17613
17614El POM se guarda persistentemente en chrome.storage.local hasta que lo limpies. El historial también se mantiene entre sesiones.
17615
17616### ¿Cómo integro HakaPath con HakaBuddy?
17617
17618En HakaBuddy, durante el Modo Debug, puedes invocar HakaPath directamente para generar selectores alternativos cuando un paso del script falla. El selector generado se copia automáticamente al paso del script.
17619
17620### ¿Chrome Built-in AI (Gemini Nano) funciona en mi Chrome?
17621
17622Requiere Chrome 127+ con los flags de IA habilitados. Si no está disponible, HakaPath te mostrará un modal informativo con instrucciones para habilitarlo.`}]}];function Mne(){const[t,e]=k.useState(null),[a,n]=k.useState(null),[i,r]=k.useState(""),[o,l]=k.useState(!1),c=k.useMemo(()=>{const m=new Set;return One.filter(h=>m.has(h.id)?!1:(m.add(h.id),!0))},[]);k.useEffect(()=>{document.title="Docs - HakaPath | Haka Lab",c.length>0&&(e(c[0].id),c[0].topics.length>0&&n(c[0].topics[0].id))},[c]);const d=k.useMemo(()=>
17622{if(!i.trim())return c;const m=i.toLowerCase();return c.map(h=>({...h,topics:h.topics.filter(g=>g.title.toLowerCase().includes(m)||g.content.toLowerCase().includes(m))})).filter(h=>h.topics.length>0)},[i,c]),u=k.useMemo(()=>{for(const m of c){const h=m.topics.find(g=>g.id===a);if(h)return h}return null},[a,c]),p=(m,h)=>{e(m),n(h),l(!1)};return s.jsxs("div",{className:"bg-dark min-h-screen",children:[s.jsxs("div",{className:"lg:hidden sticky top-0 z-30 bg-dark/95 backdrop-blur border-b border-gray-800 px-4 py-3 flex items-center gap-3",children:[s.jsx("button",{onClick:()=>l(!o),className:"text-gray-300 hover:text-primary",children:s.jsx("svg",{className:"w-6 h-6",fill:"none",stroke:"currentColor",viewBox:"0 0 24 24",children:s.jsx("path",{strokeLinecap:"round",strokeLinejoin:"round",strokeWidth:2,d:"M4 6h16M4 12h16M4 18h16"})})}),s.jsx("h1",{className:"text-white font-semibold text-sm truncate",children:"HakaPath - Docs"})]}),s.jsxs("div",{className:"flex",children:[o&&s.jsx("div",{className:"lg:hidden fixed inset-0 z-40 bg-black/60",onClick:()=>l(!1)}),s.jsxs("aside",{className:`
17623          fixed lg:sticky top-0 left-0 z-50 lg:z-10
17624          w-80 h-screen overflow-y-auto
17625          bg-darkGray border-r border-gray-800
17626          transition-transform duration-300
17627          ${o?"translate-x-0":"-translate-x-full lg:translate-x-0"}
17628        `,children:[s.jsxs("div",{className:"p-5 border-b border-gray-800",children:[s.jsxs(Te,{to:"/docs",className:"text-xs text-gray-400 hover:text-primary transition-colors flex items-center gap-1 mb-3",children:[s.jsx("svg",{className:"w-3 h-3",fill:"none",stroke:"currentColor",viewBox:"0 0 24 24",children:s.jsx("path",{strokeLinecap:"round",strokeLinejoin:"round",strokeWidth:2,d:"M15 19l-7-7 7-7"})}),"Volver a Docs"]}),s.jsx("h2",{className:"text-white font-bold text-lg mb-1",children:"HakaPath"}),s.jsx("p",{className:"text-gray-400 text-xs",children:"Extensión Chrome v3.1"})]}),s.jsx("div",{className:"p-4",children:s.jsxs("div",{className:"relative",children:[s.jsx("svg",{className:"absolute left-3 top-1/2 -translate-y-1/2 w-4 h-4 text-gray-500",fill:"none",stroke:"currentColor",viewBox:"0 0 24 24",children:s.jsx("path",{strokeLinecap:"round",strokeLinejoin:"round",strokeWidth:2,d:"M21 21l-6-6m2-5a7 7 0 11-14 0 7 7 0 0114 0z"})}),s.jsx("input",{type:"text",placeholder:"Buscar en docs...",value:i,onChange:m=>r(m.target.value),className:"w-full pl-10 pr-4 py-2 bg-dark border border-gray-700 rounded-lg text-sm text-white placeholder-gray-500 focus:outline-none focus:border-primary"})]})}),s.jsx("nav",{className:"px-3 pb-6",children:d.map(m=>{const h=i.trim()?!0:t===m.id;return s.jsxs("div",{className:"mb-2",children:[s.jsxs("button",{onClick:()=>e(t===m.id?null:m.id),className:"w-full flex items-center justify-between px-3 py-2 text-sm font-semibold text-gray-300 hover:text-white rounded-md hover:bg-dark/50 transition-colors",children:[s.jsxs("span",{className:"flex items-center gap-2",children:[s.jsx("span",{children:m.icon}),s.jsx("span",{children:m.title})]}),s.jsx("svg",{className:`w-4 h-4 transition-transform ${h?"rotate-90":""}`,fill:"none",stroke:"currentColor",viewBox:"0 0 24 24",children:s.jsx("path",{strokeLinecap:"round",strokeLinejoin:"round",strokeWidth:2,d:"M9 5l7 7-7 7"})})]}),h&&s.jsx("div",{className:"ml-4 mt-1 space-y-0.5",children:m.topics.map(g=>s.jsx("button",{onClick:()=>p(m.id,g.id),className:`w-full text-left px-3 py-1.5 text-sm rounded-md transition-colors ${a===g.id?"text-primary bg-primary/10 border-l-2 border-primary":"text-gray-400 hover:text-gray-200 hover:bg-dark/30"}`,children:g.title},g.id))})]},m.id)})})]}),s.jsx("main",{className:"flex-1 min-w-0 px-4 sm:px-8 lg:px-12 py-8 lg:py-12 max-w-4xl",children:u?s.jsxs("article",{children:[s.jsx("h1",{className:"text-3xl md:text-4xl font-bold text-white mb-6",children:u.title}),s.jsx("div",{className:"prose prose-invert prose-lg max-w-none docs-content",children:s.jsx(Dne,{content:u.content})})]}):s.jsx("div",{className:"text-center py-20",children:s.jsx("p",{className:"text-gray-400 text-lg",children:"Selecciona un tema del menú lateral"})})})]})]})}function Dne({content:t}){return qne(t).map((a,n)=>s.jsx(zne,{block:a},n))}function qne(t){var i;const e=[],a=t.split(`
17629`);let n=0;for(;n<a.length;){const r=a[n];if(r.startsWith("```")){const o=r.slice(3).trim(),l=[];for(n++;n<a.length&&!a[n].startsWith("```");)l.push(a[n]),n++;e.push({type:"code",lang:o,code:l.join(`
17630`)}),n++;continue}if(r.startsWith("## ")){e.push({type:"h2",text:r.slice(3)}),n++;continue}if(r.startsWith("### ")){e.push({type:"h3",text:r.slice(4)}),n++;continue}if(r.includes("|")&&n+1<a.length&&((i=a[n+1])!=null&&i.includes("---"))){const o=[];for(;n<a.length&&a[n].includes("|");)o.push(a[n]),n++;e.push({type:"table",rows:o});continue}if(r.startsWith("- ")||r.startsWith("* ")){const o=[];for(;n<a.length&&(a[n].startsWith("- ")||a[n].startsWith("* "));)o.push(a[n].slice(2)),n++;e.push({type:"list",items:o});continue}if(r.startsWith("step: ")){e.push({type:"step",text:r.slice(6)}),n++;continue}if(r.startsWith("descripcion: ")){e.push({type:"description",text:r.slice(13)}),n++;continue}if(r.startsWith("**")&&r.endsWith("**")){e.push({type:"bold",text:r.slice(2,-2)}),n++;continue}if(r.trim()===""||r.trim()==="---"){n++;continue}e.push({type:"paragraph",text:r}),n++}return e}function zne({block:t}){switch(t.type){case"h2":return s.jsx("h2",{className:"text-2xl font-bold text-white mt-8 mb-4",children:t.text});case"h3":return s.jsx("h3",{className:"text-xl font-semibold text-gray-200 mt-6 mb-3",children:t.text});case"bold":return s.jsx("p",{className:"font-semibold text-primary mt-4 mb-2",children:t.text});case"paragraph":return s.jsx("p",{className:"text-gray-300 mb-3 leading-relaxed",children:s.jsx(kb,{text:t.text})});case"step":return s.jsx("div",{className:"bg-primary/5 border-l-4 border-primary px-4 py-2 my-3 rounded-r-lg",children:s.jsx("code",{className:"text-primary text-sm font-mono",children:t.text})});
17630case"description":return s.jsx("p",{className:"text-gray-400 text-sm mb-4 ml-4",children:t.text});case"code":return s.jsxs("div",{className:"my-4 rounded-lg overflow-hidden border border-gray-700",children:[t.lang&&s.jsx("div",{className:"bg-gray-800 px-4 py-1.5 text-xs text-gray-400 border-b border-gray-700",children:t.lang}),s.jsx("pre",{className:"bg-[#0d1117] p-4 overflow-x-auto",children:s.jsx("code",{className:"text-sm text-gray-300 font-mono whitespace-pre",children:t.code})})]});case"list":return s.jsx("ul",{className:"list-disc list-inside space-y-1 text-gray-300 mb-4 ml-2",children:t.items.map((e,a)=>s.jsx("li",{children:s.jsx(kb,{text:e})},a))});case"table":return s.jsx(Vne,{rows:t.rows});default:return null}}function Vne({rows:t}){if(t.length<2)return null;const e=i=>i.split("|").filter(r=>r.trim()!=="").map(r=>r.trim()),a=e(t[0]),n=t.slice(2).map(e);return s.jsx("div",{className:"overflow-x-auto my-4 rounded-lg border border-gray-700",children:s.jsxs("table",{className:"w-full text-sm",children:[s.jsx("thead",{className:"bg-gray-800",children:s.jsx("tr",{children:a.map((i,r)=>s.jsx("th",{className:"px-4 py-2 text-left text-gray-300 font-semibold",children:i},r))})}),s.jsx("tbody",{className:"divide-y divide-gray-800",children:n.map((i,r)=>s.jsx("tr",{className:"hover:bg-dark/50",children:i.map((o,l)=>s.jsx("td",{className:"px-4 py-2 text-gray-400",children:s.jsx(kb,{text:o})},l))},r))})]})})}function kb({text:t}){return t.split(/(`[^`]+`|\*\*[^*]+\*\*)/g).map((a,n)=>a.startsWith("`")&&a.endsWith("`")?s.jsx("code",{className:"bg-gray-800 px-1.5 py-0.5 rounded text-primary text-sm font-mono",children:a.slice(1,-1)},n):a.startsWith("**")&&a.endsWith("**")?s.jsx("strong",{className:"text-white font-semibold",children:a.slice(2,-2)},n):s.jsx("span",{children:a},n))}function Hne(){const[t,e]=k.useState("google"),[a,n]=k.useState(""),[i,r]=k.useState(""),[o,l]=k.useState(!1),[c,d]=k.useState(""),{loginWithGoogle:u,loginWithLicense:p,user:m}=Zl(),h=Qa();k.useEffect(()=>{m&&h("/docs")},[m,h]);const g=async()=>{d(""),l(!0);try{await u(),h("/docs")}catch(x){d(x.message)}finally{l(!1)}},y=async x=>{if(x.preventDefault(),d(""),!a.trim()||!i.trim()){d("Ingresa tu email y clave de licencia");return}l(!0);try{await p(a.trim(),i.trim()),h("/docs")}catch(v){d(v.message)}finally{l(!1)}};return s.jsx("div",{className:"min-h-screen bg-gradient-to-br from-dark via-slate-900 to-dark flex flex-col items-center justify-center px-4",children:s.jsxs(_.div,{initial:{opacity:0,y:20},animate:{opacity:1,y:0},transition:{duration:.5},className:"w-full max-w-md flex flex-col items-center",children:[s.jsxs(_.div,{animate:{boxShadow:["0 0 20px rgba(0,200,255,0.1), 0 0 40px rgba(0,200,255,0.05)","0 0 40px rgba(0,200,255,0.3), 0 0 80px rgba(0,200,255,0.1)","0 0 20px rgba(0,200,255,0.1), 0 0 40px rgba(0,200,255,0.05)"]},transition:{duration:3,repeat:1/0,ease:"easeInOut"},className:"relative w-full bg-slate-800/50 backdrop-blur-sm border border-cyan-400/40 rounded-2xl p-8",children:[s.jsx(_.div,{animate:{rotate:360},transition:{duration:8,repeat:1/0,ease:"linear"},className:"absolute -top-5 -right-5 w-12 h-12 bg-slate-800 border border-cyan-400/40 rounded-full flex items-center justify-center shadow-[0_0_15px_rgba(0,200,255,0.2)]",children:s.jsx("svg",{className:"w-6 h-6 text-cyan-400",fill:"none",stroke:"currentColor",viewBox:"0 0 24 24",strokeWidth:1.5,children:s.jsx("path",{strokeLinecap:"round",strokeLinejoin:"round",d:"M12 6.042A8.967 8.967 0 0 0 6 3.75c-1.052 0-2.062.18-3 .512v14.25A8.987 8.987 0 0 1 6 18c2.305 0 4.408.867 6 2.292m0-14.25a8.966 8.966 0 0 1 6-2.292c1.052 0 2.062.18 3 .512v14.25A8.987 8.987 0 0 0 18 18a8.967 8.967 0 0 0-6 2.292m0-14.25v14.25"})})}),s.jsx("h1",{className:"text-2xl font-bold text-white mb-1",children:"Documentación de productos HakaLab"}),s.jsx("p",{className:"text-gray-400 text-sm mb-6",children:"Accede con tu cuenta o licencia"}),s.jsxs("div",{className:"flex mb-6 bg-dark rounded-lg p-1",children:[s.jsx("button",{onClick:()=>{e("google"),d("")},className:`flex-1 py-2 text-sm font-medium rounded-md transition-colors ${t==="google"?"bg-primary/20 text-primary":"text-gray-400 hover:text-gray-200"}`,children:"Google"}),s.jsx("button",{onClick:()=>{e("license"),d("")},className:`flex-1 py-2 text-sm font-medium rounded-md transition-colors ${t==="license"?"bg-primary/20 text-primary":"text-gray-400 hover:text-gray-200"}`,children:"Licencia"})]}),c&&s.jsx(_.div,{initial:{opacity:0}
17630,animate:{opacity:1},className:"mb-4 p-3 bg-red-500/10 border border-red-500/30 rounded-lg text-red-400 text-sm",children:c}),t==="google"?s.jsxs(s.Fragment,{children:[s.jsx("button",{onClick:g,disabled:o,className:"w-full flex items-center justify-center gap-3 bg-white text-gray-800 font-medium py-3 px-4 rounded-xl hover:bg-gray-100 transition-all disabled:opacity-50 disabled:cursor-not-allowed shadow-lg",children:o?s.jsx("div",{className:"animate-spin rounded-full h-5 w-5 border-t-2 border-b-2 border-gray-800"}):s.jsxs(s.Fragment,{children:[s.jsxs("svg",{className:"w-5 h-5",viewBox:"0 0 24 24",children:[s.jsx("path",{fill:"#4285F4",d:"M22.56 12.25c0-.78-.07-1.53-.2-2.25H12v4.26h5.92c-.26 1.37-1.04 2.53-2.21 3.31v2.77h3.57c2.08-1.92 3.28-4.74 3.28-8.09z"}),s.jsx("path",{fill:"#34A853",d:"M12 23c2.97 0 5.46-.98 7.28-2.66l-3.57-2.77c-.98.66-2.23 1.06-3.71 1.06-2.86 0-5.29-1.93-6.16-4.53H2.18v2.84C3.99 20.53 7.7 23 12 23z"}),s.jsx("path",{fill:"#FBBC05",d:"M5.84 14.09c-.22-.66-.35-1.36-.35-2.09s.13-1.43.35-2.09V7.07H2.18C1.43 8.55 1 10.22 1 12s.43 3.45 1.18 4.93l2.85-2.22.81-.62z"}),s.jsx("path",{fill:"#EA4335",d:"M12 5.38c1.62 0 3.06.56 4.21 1.64l3.15-3.15C17.45 2.09 14.97 1 12 1 7.7 1 3.99 3.47 2.18 7.07l3.66 2.84c.87-2.6 3.3-4.53 6.16-4.53z"})]}),s.jsx("span",{children:"Continuar con Google"})]})}),s.jsxs("p",{className:"mt-3 text-center text-xs text-gray-500",children:["Solo cuentas ",s.jsx("span",{className:"text-primary",children:"@hakalab.com"})]})]}):s.jsxs("form",{onSubmit:y,className:"space-y-4",children:[s.jsxs("div",{children:[s.jsx("label",{className:"block text-sm text-gray-400 mb-1",children:"Email"}),s.jsx("input",{type:"email",value:a,onChange:x=>n(x.target.value),placeholder:"[email protected]",className:"w-full px-4 py-3 bg-dark border border-gray-700 rounded-lg text-white placeholder-gray-500 focus:outline-none focus:border-primary"})]}),s.jsxs("div",{children:[s.jsx("label",{className:"block text-sm text-gray-400 mb-1",children:"Clave de Licencia"}),s.jsx("input",{type:"password",value:i,onChange:x=>r(x.target.value),placeholder:"Tu clave de licencia",className:"w-full px-4 py-3 bg-dark border border-gray-700 rounded-lg text-white placeholder-gray-500 focus:outline-none focus:border-primary"})]}),s.jsx("button",{type:"submit",disabled:o,className:"w-full py-3 bg-primary text-dark font-semibold rounded-xl hover:bg-primary/90 transition-all disabled:opacity-50 disabled:cursor-not-allowed",children:o?"Validando...":"Ingresar"})]})]}),s.jsx("p",{className:"text-center text-gray-500 text-xs mt-6",children:"© 2026 HakaLab. Todos los derechos reservados."})]})})}const xj=[{productKey:"Engine Playwright",to:"/docs/haka-playwright-engine",logo:"/imagenes/docs-logos/Automation Engine.png",alt:"Haka Automation Engine",logoHeight:"h-8",description:"Framework de automatización de pruebas funcionales. Soporta Web, Mobile, Desktop, API y GenAI."},{productKey:"Haka AI Studio",to:"/docs/haka-ai-studio",logo:"/imagenes/docs-logos/AI Studio.png",alt:"Haka AI Studio",logoHeight:"h-8",description:"Extensión de VS Code con IA para grabar y generar pruebas automatizadas. Soporta Playwright y Selenium."},{productKey:"HakaBoost",to:"/docs/hakaboost",logo:"/imagenes/docs-logos/HakaBoost.png",alt:"HakaBoost",logoHeight:"h-6",description:"Copiloto de calida
17630d con IA para Jira y Azure DevOps. Genera tests Gherkin y mejora requerimientos."},{productKey:"Hakabuddy",to:"/docs/hakabuddy",logo:"/imagenes/docs-logos/HakaBuddy.png",alt:"HakaBuddy",logoHeight:"h-8",description:"Aplicación de escritorio para QA. Pruebas manuales y automatizadas con reportes profesionales."},{productKey:"HakaPath",to:"/docs/hakapath",logo:"/imagenes/docs-logos/HakaPath.png",alt:"HakaPath",logoHeight:"h-8",description:"Extensión Chrome para generar selectores robustos (XPath, CSS, data-testid) con un solo click."}];function Fne(){const{user:t,logout:e}=Zl();k.useEffect(()=>{document.title="Documentación | Haka Lab"},[]);const a=(t==null?void 0:t.productos)??[],i=(t==null?void 0:t.method)==="google"?xj:xj.filter(r=>a.includes(r.productKey));return s.jsxs("div",{className:"min-h-screen bg-dark",children:[s.jsx("header",{className:"border-b border-gray-800 bg-darkGray/50 backdrop-blur sticky top-0 z-20",children:s.jsxs("div",{className:"max-w-7xl mx-auto px-4 sm:px-6 lg:px-8 py-4 flex items-center justify-between",children:[s.jsx("span",{className:"text-white font-semibold text-lg",children:"Documentación de productos HakaLab"}),s.jsxs("div",{className:"flex items-center gap-4",children:[s.jsx("span",{className:"text-gray-400 text-sm hidden sm:block",children:t==null?void 0:t.email}),s.jsx("button",{onClick:e,className:"text-sm text-gray-400 hover:text-red-400 transition-colors",children:"Cerrar sesión"})]})]})}),s.jsx("main",{className:"max-w-7xl mx-auto px-4 sm:px-6 lg:px-8 py-12",children:s.jsxs(_.div,{initial:{opacity:0,y:10},animate:{opacity:1,y:0},transition:{duration:.4},children:[s.jsxs("h1",{className:"text-3xl md:text-4xl font-bold text-white mb-2",children:["Bienvenido",t!=null&&t.name?`, ${t.name.split(" ")[0]}`:""]}),s.jsx("p",{className:"text-gray-400 mb-10",children:"Accede a la documentación de los productos Haka"}),i.length===0?s.jsxs("div",{className:"bg-darkGray border border-gray-800 rounded-xl p-8 text-center",children:[s.jsx("p",{className:"text-gray-400",children:"Tu licencia no incluye acceso a documentación de ningún producto actualmente disponible."}),s.jsx("p",{className:"text-gray-500 text-sm mt-2",children:"Contacta a tu administrador o a soporte de HakaLab para ampliar tu acceso."})]}):s.jsx("div",{className:"grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-6",children:i.map(r=>s.jsx(Te,{to:r.to,className:"group",children:s.jsxs("div",{className:"bg-darkGray border border-gray-800 rounded-xl p-6 hover:border-primary/50 hover:bg-darkGray/80 transition-all duration-300 h-full",children:[s.jsx("img",{src:r.logo,alt:r.alt,className:`${r.logoHeight} mb-4`}),s.jsx("p",{className:"text-gray-400 text-sm leading-relaxed",children:r.description}),s.jsxs("div",{className:"mt-4 flex items-center gap-2 text-primary text-sm font-medium opacity-0 group-hover:opacity-100 transition-opacity",children:[s.jsx("span",{children:"Ver documentación"}),s.jsx("svg",{className:"w-4 h-4",fill:"none",stroke:"currentColor",viewBox:"0 0 24 24",children:s.jsx("path",{strokeLinecap:"round",strokeLinejoin:"round",strokeWidth:2,d:"M9 5l7 7-7 7"})})]})]})},r.productKey))})]})})]})}function Ot({children:t}){const{user:e,loading:a}=Zl();return a?s.jsx("div",{className:"min-h-screen flex items-center justify-center bg-dark",children:s.jsx("div",{className:"w-10 h-10 border-4 border-primary border-t-transparent rounded-full animate-spin"})}):e?t:s.jsx(ew,{to:"/docs/login",replace:!0})}function Bne(){const[t,e]=k.useState(!1);return t?s.jsx("div",{className:"w-24 h-24 rounded-2xl bg-primary/10 border border-primary/20 flex items-center justify-center group-hover:bg-primary/15 transition-colors",children:s.jsxs("svg",{className:"w-11 h-11 text-primary",fill:"currentColor",viewBox:"0 0 24 24","aria-hidden":"true",children:[s.jsx("path",{d:"M10 8.64v6.72L15.27 12 10 8.64z"}),s.jsx("path",{fillRule:"evenodd",d:"M12 3c-3.09 0-5.4.2-6.88.4a2.71 2.71 0 0 0-2.3 2.2A18.7 18.7 0 0 0 2.5 12c0 2.3.2 4.2.32 5.4a2.71 2.71 0 0 0 2.3 2.2c1.48.2 3.79.4 6.88.4s5.4-.2 6.88-.4a2.71 2.71 0 0 0 2.3-2.2c.12-1.2.32-3.1.32-5.4 0-2.3-.2-4.2-.32-5.4a2.71 2.71 0 0 0-2.3-2.2C17.4 3.2 15.09 3 12 3Zm0 1.8c2.98 0 5.18.19 6.63.38.44.06.78.4.83.83.11 1.13.29 2.93.29 4.99 0 2.06-.18 3.86-.29 4.99a.92.92 0 0 1-.83.83c-1.45.19-3.65.38-6.63.38s-5.18-.19-6.63-.38a.92.92 0 0 1-.83-.83A47.6 47.6 0 0 1 4.25 12c0-2.06.18-3.86.29-4.99a.92.92 0 0 1 .83-.83C6.82 4.99 9.02 4.8 12 4.8Z",clipRule:"evenodd"})]})}
17630):s.jsx("img",{src:"/imagenes/docs-logos/videos.png",alt:"Video tutoriales",className:"w-24 h-24 object-contain",onError:()=>e(!0)})}function $u({productName:t,logo:e,logoHeight:a="h-8",docsPath:n,faqPath:i,videosPath:r}){const{user:o,logout:l}=Zl();return s.jsxs("div",{className:"min-h-screen bg-dark",children:[s.jsx("header",{className:"border-b border-gray-800 bg-darkGray/50 backdrop-blur sticky top-0 z-20",children:s.jsxs("div",{className:"max-w-7xl mx-auto px-4 sm:px-6 lg:px-8 py-4 flex items-center justify-between",children:[s.jsxs("div",{className:"flex items-center gap-3",children:[s.jsx(Te,{to:"/docs",className:"text-gray-400 hover:text-white transition-colors text-sm",children:"← Productos"}),s.jsx("span",{className:"text-gray-600",children:"|"}),s.jsx("span",{className:"text-white font-semibold text-lg",children:t})]}),s.jsxs("div",{className:"flex items-center gap-4",children:[s.jsx("span",{className:"text-gray-400 text-sm hidden sm:block",children:o==null?void 0:o.email}),s.jsx("button",{onClick:l,className:"text-sm text-gray-400 hover:text-red-400 transition-colors",children:"Cerrar sesión"})]})]})}),s.jsx("main",{className:"max-w-4xl mx-auto px-4 sm:px-6 lg:px-8 py-16",children:s.jsxs(_.div,{initial:{opacity:0,y:10},animate:{opacity:1,y:0},transition:{duration:.4},className:"text-center",children:[e&&s.jsx("img",{src:e,alt:t,className:`${a} mx-auto mb-6`}),s.jsx("p",{className:"text-gray-400 mb-12",children:"¿Qué necesitas?"}),s.jsxs("div",{className:`grid grid-cols-1 gap-6 mx-auto ${r?"md:grid-cols-3 max-w-4xl":"md:grid-cols-2 max-w-2xl"}`,children:[s.jsx(Te,{to:n,className:"group",children:s.jsxs("div",{className:"bg-darkGray border border-gray-800 rounded-xl p-8 hover:border-primary/50 hover:bg-darkGray/80 transition-all duration-300 h-full text-center",children:[s.jsx("div",{className:"flex items-center justify-center mx-auto mb-4",children:s.jsx("img",{src:"/imagenes/docs-logos/documentacion.png",alt:"Documentación",className:"w-24 h-24 object-contain"})}),s.jsx("h2",{className:"text-white font-semibold text-lg mb-2",children:"Documentación"}),s.jsx("p",{className:"text-gray-400 text-sm leading-relaxed",children:"Guías de uso, configuración, referencia técnica y ejemplos."}),s.jsxs("div",{className:"mt-5 flex items-center justify-center gap-2 text-primary text-sm font-medium opacity-0 group-hover:opacity-100 transition-opacity",children:[s.jsx("span",{children:"Ir a la documentación"}),s.jsx("svg",{className:"w-4 h-4",fill:"none",stroke:"currentColor",viewBox:"0 0 24 24",children:s.jsx("path",{strokeLinecap:"round",strokeLinejoin:"round",strokeWidth:2,d:"M9 5l7 7-7 7"})})]})]})}),s.jsx(Te,{to:i,className:"group",children:s.jsxs("div",{className:"bg-darkGray border border-gray-800 rounded-xl p-8 hover:border-primary/50 hover:bg-darkGray/80 transition-all duration-300 h-full text-center",children:[s.jsx("div",{className:"flex items-center justify-center mx-auto mb-4",children:s.jsx("img",{src:"/imagenes/docs-logos/preguntas.png",alt:"Preguntas frecuentes",className:"w-24 h-24 object-contain"})}),s.jsx("h2",{className:"text-white font-semibold text-lg mb-2",children:"Preguntas frecuentes y soporte"}),s.jsx("p",{className:"text-gray-400 text-sm leading-relaxed",children:"Respuestas a preguntas comunes y formulario para crear un ticket de soporte."}),s.jsxs("div",{className:"mt-5 flex items-center justify-center gap-2 text-primary text-sm font-medium opacity-0 group-hover:opacity-100 transition-opacity",children:[s.jsx("span",{children:"Ver preguntas y soporte"}),s.jsx("svg",{className:"w-4 h-4",fill:"none",stroke:"currentColor",viewBox:"0 0 24 24",children:s.jsx("path",{strokeLinecap:"round",strokeLinejoin:"round",strokeWidth:2,d:"M9 5l7 7-7 7"})})]})]})}),r&&s.jsx(Te,{to:r,className:"group",children:s.jsxs("div",{className:"bg-darkGray border border-gray-800 rounded-xl p-8 hover:border-primary/50 hover:bg-darkGray/80 transition-all duration-300 h-full text-center",children:[s.jsx("div",{className:"flex items-center justify-center mx-auto mb-4",children:s.jsx(Bne,{})}),s.jsx("h2",{className:"text-white font-semibold text-lg mb-2",children:"Video tutoriales"}),s.jsx("p",{className:"text-gray-400 text-sm leading-relaxed",children:"Curso en video paso a paso, desde la instalación hasta pruebas móviles."}),s.jsxs("div",{className:"mt-5 flex items-center justify-center gap-2 text-primary text-sm font-medium opacity-0 group-hover:opacity-100 transition-opacity",children:[s.jsx("span",{children:"Ver el curso"}),s.jsx("svg",{className:"w-4 h-4",fill:"none",stroke:"currentColor",viewBox:"0 0 24 24",children:s.jsx("path",{strokeLinecap:"round",strokeLinejoin:"round",strokeWidth:2,d:"M9 5l7 7-7 7"})})]})]})})]})]})})]})}function Une(){return s.jsx($u,{productName:"Haka Automation Engine",logo:"/imagenes/docs-logos/Automation Engine.png",logoHeight:"h-11",docsPath:"/docs/haka-playwright-engine/docs",faqPath:"/docs/haka-playwright-engine/faq",videosPath:"/docs/haka-playwright-engine/videos"})}function $ne(){return s.jsx($u,{productName:"Haka AI Studio",logo:"/imagenes/docs-logos/AI Studio.png",logoHeight:"h-8",docsPath:"/docs/haka-ai-studio/docs",faqPath:"/docs/haka-ai-studio/faq"})}function Wne(){return s.jsx($u,{productName:"HakaBoost",logo:"/imagenes/docs-logos/HakaBoost.png",logoHeight:"h-6",docsPath:"/docs/hakaboost/docs",faqPath:"/docs/hakaboost/faq"})}function Gne(){return s.jsx($u,{productName:"HakaBuddy",logo:"/imagenes/docs-logos/HakaBuddy.png",logoHeight:"h-8",docsPath:"/docs/hakabuddy/docs",faqPath:"/docs/hakabuddy/faq"})}function Kne(){return s.jsx($u,{productName:"HakaPath",logo:"/imagenes/docs-logos/HakaPath.png",logoHeight:"h-8",docsPath:"/docs/hakapath/d
17630ocs",faqPath:"/docs/hakapath/faq"})}function vj({faq:t,index:e,isOpen:a,onToggle:n}){return s.jsxs("div",{className:"border border-gray-800 rounded-lg overflow-hidden",children:[s.jsxs("button",{onClick:n,className:"w-full text-left px-5 py-4 flex items-center justify-between bg-darkGray hover:bg-darkGray/80 transition-colors",children:[s.jsx("span",{className:"text-white text-sm font-medium pr-4",children:t.question}),s.jsx("svg",{className:`w-5 h-5 text-gray-400 flex-shrink-0 transition-transform duration-200 ${a?"rotate-180":""}`,fill:"none",stroke:"currentColor",viewBox:"0 0 24 24",children:s.jsx("path",{strokeLinecap:"round",strokeLinejoin:"round",strokeWidth:2,d:"M19 9l-7 7-7-7"})})]}),s.jsx(La,{children:a&&s.jsx(_.div,{initial:{height:0,opacity:0},animate:{height:"auto",opacity:1},exit:{height:0,opacity:0},transition:{duration:.2},className:"overflow-hidden",children:s.jsx("div",{className:"px-5 py-4 text-gray-400 text-sm leading-relaxed border-t border-gray-800 bg-dark/50",children:t.answer})})})]})}function Wu({productName:t,productKey:e,logo:a,logoHeight:n="h-8",hubPath:i,faqs:r=[]}){const{user:o,logout:l}=Zl(),[c,d]=k.useState(null),[u,p]=k.useState(""),m=k.useMemo(()=>{if(!u.trim())return r;const v=u.toLowerCase();return r.filter(w=>w.question.toLowerCase().includes(v)||w.answer.toLowerCase().includes(v))},[r,u]),h=Math.ceil(m.length/2),g=m.slice(0,h),y=m.slice(h),x=v=>{d(c===v?null:v)};return s.jsxs("div",{className:"min-h-screen bg-dark",children:[s.jsx("header",{className:"border-b border-gray-800 bg-darkGray/50 backdrop-blur sticky top-0 z-20",children:s.jsxs("div",{className:"max-w-7xl mx-auto px-4 sm:px-6 lg:px-8 py-4 flex items-center justify-between",children:[s.jsx("div",{className:"flex items-center gap-3",children:s.jsxs(Te,{to:i,className:"text-gray-400 hover:text-white transition-colors text-sm",children:["← ",t]})}),s.jsxs("div",{className:"flex items-center gap-4",children:[s.jsx("span",{className:"text-gray-400 text-sm hidden sm:block",children:o==null?void 0:o.email}),s.jsx("button",{onClick:l,className:"text-sm text-gray-400 hover:text-red-400 transition-colors",children:"Cerrar sesión"})]})]})}),s.jsx("main",{className:"max-w-6xl mx-auto px-4 sm:px-6 lg:px-8 py-12",children:s.jsxs(_.div,{initial:{opacity:0,y:10},animate:{opacity:1,y:0},transition:{duration:.4},children:[s.jsxs("div",{className:"flex items-center gap-3 mb-8",children:[a&&s.jsx("img",{src:a,alt:t,className:n}),s.jsx("h1",{className:"text-2xl md:text-3xl font-bold text-white",children:"Preguntas frecuentes y soporte"})]}),r.length>0&&s.jsxs("section",{className:"mb-12",children:[s.jsxs("div",{className:"mb-6",children:[s.jsxs("div",{className:"relative max-w-md",children:[s.jsx("svg",{className:"absolute left-3 top-1/2 -translate-y-1/2 w-4 h-4 text-gray-500",fill:"none",stroke:"currentColor",viewBox:"0 0 24 24",children:s.jsx("path",{strokeLinecap:"round",strokeLinejoin:"round",strokeWidth:2,d:"M21 21l-6-6m2-5a7 7 0 11-14 0 7 7 0 0114 0z"})}),s.jsx("input",{type:"text",value:u,onChange:v=>{p(v.target.value),d(null)},placeholder:"Buscar en preguntas frecuentes…",className:"w-full bg-darkGray border border-gray-700 rounded-lg pl-10 pr-4 py-2.5 text-white text-sm placeholder-gray-500 focus:outline-none focus:border-primary/50 transition-colors"}),u&&s.jsx("button",{onClick:()=>p(""),className:"absolute right-3 top-1/2 -translate-y-1/2 text-gray-500 hover:text-gray-300",children:s.jsx("svg",{className:"w-4 h-4",fill:"none",stroke:"currentColor",viewBox:"0 0 24 24",children:s.jsx("path",{strokeLinecap:"round",strokeLinejoin:"round",strokeWidth:2,d:"M6 18L18 6M6 6l12 12"})})})]}),u&&s.jsxs("p",{className:"text-gray-500 text-xs mt-2",children:[m.length," resultado",m.length!==1?"s":"",' para "',u,'"']})]}),m.length===0?s.jsxs("div",{className:"text-center py-8",children:[s.jsx("p",{className:"text-gray-400 text-sm",children:"No se encontraron preguntas que coincidan con tu búsqueda."}),s.jsx("button",{onClick:()=>p(""),className:"text-primary text-sm mt-2 hover:underline",children:"Limpiar búsqueda"})]}):s.jsxs("div",{className:"grid grid-cols-1 lg:grid-cols-2 gap-4",children:[s.jsx("div",{className:"space-y-2",children:g.map(v=>{const w=r.indexOf(v);return s.jsx(vj,{faq:v,index:w,isOpen:c===w,onToggle:()=>x(w)},w)})}),s.jsx("div",{className:"space-y-2",children:y.map(v=>{const w=r.indexOf(v);return s.jsx(vj,{faq:v,index:w,isOpen:c===w,onToggle:()=>x(w)},w)})})]})]})]})})]})}const Jne=[{question:"¿Cómo instalo Haka Playwright Engine?",answer:'Hay dos formas: (1) Con haka-init: crea una carpeta, activa un entorno virtual, ejecuta "pip install haka-playwright-engine" y luego "haka-init" para generar toda la estructura. Después "pip install -r requirements.txt" y "playwright install". (2) Desde el repositorio: clona https://github.com/HakaLab-2025/Engine-Playwright-Base, 
17630crea un venv y ejecuta "pip install -r requirements.txt" seguido de "playwright install".'},{question:"¿Qué versión de Python necesito?",answer:"Python 3.11 o superior. Recomendamos 3.11 por compatibilidad y rendimiento."},{question:"¿Qué navegadores soporta?",answer:"Chromium, Firefox y WebKit (Safari) a través de Playwright. También soporta pruebas mobile con Appium y desktop con PyAutoGUI/OCR."},{question:"¿Funciona en Windows, macOS y Linux?",answer:'Sí. El framework funciona en cualquier sistema operativo donde Python y Playwright estén soportados. En Linux CI, usa "playwright install --with-deps chromium" para instalar dependencias del sistema.'},{question:"¿Necesito instalar Playwright por separado?",answer:'Playwright se instala como dependencia de pip, pero debes ejecutar "playwright install" una vez para descargar los binarios de los navegadores. En CI/CD usa "playwright install --with-deps chromium".'},{question:"¿Cuáles son las opciones de instalación?",answer:"pip install haka-playwright-engine (básica), haka-playwright-engine[ai] (con IA/self-healing), haka-playwright-engine[ocr] (con OCR para desktop), haka-playwright-engine[salesforce] (con frontdoor.jsp) o haka-playwright-engine[all] (todo incluido)."},{question:"¿Cómo creo un proyecto nuevo?",answer:'Ejecuta "haka-init" en terminal. Crea automáticamente la estructura de carpetas (features/, steps/, json_poms/, .env, environment.py, behave.ini) con plantillas listas para usar.'},{question:"¿Qué es el archivo .env y qué contiene?",answer:"Es el archivo de configuración principal. Define navegador (BROWSER), modo headless (HEADLESS), timeouts (TIMEOUT), URLs (BASE_URL), credenciales (TEST_EMAIL/TEST_PASSWORD), screenshots, reportes, IA, integraciones, y más de 60 variables configurables."},{question:"¿Puedo tener diferentes .env por ambiente (QA, staging, prod)?",answer:'Sí. Crea archivos como qa.env, staging.env, prod.env y ejecútalos con: haka-run --env staging.env. También puedes usar "haka-validate --env-file staging.env" para validar cada uno.'},{question:"¿Qué es behave.ini?",answer:"Archivo de configuración de Behave (el motor BDD). Define paths de features, formato de salida, tags por defecto, etc. El framework lo genera automáticamente con haka-init."},{question:"¿Qué es environment.py?",answer:"Archivo de hooks de Behave. Define qué pasa antes/después de cada escenario, feature o toda la ejecución. El framework proporciona hooks pre-configurados para screenshots, reportes HTML, manejo de browser, etc."},{question:"¿Qué son los JSON POMs?",answer:"Son archivos JSON que almacenan los selectores/localizadores de los elementos de cada página. En vez de hardcodear selectores en los steps, los referencias como $.PAGINA.elemento. Esto centraliza el mantenimiento: si un selector cambia, se actualiza en un solo lugar."},{question:"¿Cómo se estructura un JSON POM?",answer:'Cada archivo se llama en MAYUSCULAS (ej: LOGIN.json) y contiene pares clave-valor: {"campo_email": "input#email", "boton_submit": "button[type=submit]"}. Los selectores pueden ser CSS, XPath, text, placeholder, role o data-testid.'},{question:"¿Cómo referencio un elemento del POM en un step?",answer:'Usa la sintaxis $.PAGINA.elemento. Ejemplo: When hago click en el elemento "$.LOGIN.boton_submit". El framework resuelve el selector del JSON automáticamente.'},{question:"¿Puedo usar selectores directos sin POM?",answer:'Sí. Puedes usar selectores inline: When hago click en el elemento "button#submit". Útil para pruebas rápidas, pero para mantenibilidad se recomienda POM.'},{question:"¿Los POMs soportan selectores dinámicos?",answer:`Sí. Usa placeholders con {valor}: {"fila_tabla": "//tr[contains(.,'{valor}')]"}. En el step: When hago click en el elemento "$.TABLA.fila_tabla" con valor "Producto A". El {valor} se reemplaza dinámicamente.`},{question:"¿Cómo ejecuto las pruebas?",answer:'Tienes varias opciones: "behave" (todas), "behave features/login.feature" (un archivo), "behave -t @smoke" (por tag), o "haka-run --parallel 4" (paralelo con 4 workers).'},{question:"¿Cómo ejecuto pruebas en paralelo?",answer:'Usa "haka-run --parallel N" donde N es la cantidad de workers. Cada worker ejecuta features independientes con su propio browser. Para CI/CD también puedes usar sharding entre jobs.'},{question:"¿Cómo filtro qué pruebas ejecutar?",answer:'Usa tags de Behave: @smoke, @regression, @api, etc. Ejecuta con "behave -t @smoke" o "behave -t @smoke,@login" (OR) o "behave -t @smoke -t @web" (AND). También puedes excluir: "behave -t ~@slow".'},{question:"¿Puedo ejecutar en modo headless?",answer:"Sí. Configura HEADLESS=true en tu .env. Es obligatorio en CI/CD (no hay pantalla). Para desarrollo local usa HEADLESS=false para ver el navegador."},{question:"¿Qué es SLOW_MO y para qué sirve?",answer:"SLOW_MO=500 agrega 500ms de pausa entre cada acción de Playwright. Útil para debugging visual: ves exactamente qué hace el framework paso a paso. No uses en CI/CD."},{question:"¿Cómo depuro un test que falla?",answer:"Usa PWDEBUG=1 behave para abrir Playwright Inspector (pausas interactivas). También puedes usar SLOW_MO=500, HEADLESS=false y SCREENSHOT_ON_FAILURE=true para investigar visualmente."},{question:"¿Cuántos steps tiene el framework?",answer:"Más de 500 steps únicos con 1100+ variantes. Cubren: web (clicks, formularios, navegación, validaciones), API REST, mobile, desktop, base de datos, email, archivos, GenAI, accesibilidad, performance y más."},{question:"¿Los steps están en español o inglés?",answer:'Ambos. Cada step tiene alias en español e inglés, y puedes mezclarlos en el mismo feature. Ejemplo: "Given voy a la url" y "Given I go to the url" son equivalentes.'},{question:"¿Cómo veo la lista completa de steps?",answer:'Ejecuta "haka-steps" en terminal. Muestra todos los steps disponibles organizados por categoría con su sintaxis exacta y parámetros.'},{question:"¿Puedo crear steps personalizados?",answer:"Sí. Crea archivos .py en tu carpeta steps/ con decoradores @given/@when/@then de Behave. Puedes usar el contexto del framework (context.page, context.browser) y componer steps existentes con execute_steps()."},{question:"¿Qué es un Scenario Outline y cómo lo uso?",answer:"Es un escenario parametrizado con tabla Examples. El mismo escenario se ejecuta N veces con diferentes datos. Usa <variable> en los steps y define los valores en la tabla Examples debajo."}
17630,{question:"¿Qué es Background?",answer:"Pasos comunes que se ejecutan ANTES de cada Scenario en un Feature. Típicamente contiene la navegación inicial y login. Evita repetir los mismos Given en cada escenario."},{question:"¿Cómo uso variables del .env en los steps?",answer:'Usa la sintaxis ${ENV.NOMBRE}. Ejemplo: Given voy a la url "${ENV.BASE_URL}". El framework reemplaza el valor antes de ejecutar el step.'},{question:"¿Puedo generar datos aleatorios?",answer:"Sí. El framework genera: texto aleatorio (${RANDOM_TEXT}), números (${RANDOM_NUMBER}), emails (${RANDOM_EMAIL}), RUT (${RANDOM_RUT}), fechas (${TODAY}, ${TOMORROW}, ${BUSINESS_DAY+5}), timestamps y más."},{question:"¿Cómo extraigo un valor de la página a una variable?",answer:'Usa: Then guardo el texto del elemento "$.PAGINA.precio" en la variable "precio_actual". Después referénciala con ${precio_actual} en steps posteriores.'},{question:"¿Las variables se comparten entre escenarios?",answer:"Por defecto cada escenario es independiente. Para compartir variables entre escenarios del mismo feature, usa variables de contexto global o extracciones en Background."},{question:"¿Cómo hago click en un elemento?",answer:'When hago click en el elemento "$.PAGINA.boton" (con POM) o When hago click en el elemento "button#submit" (selector directo). Soporta click simple, doble click, click derecho y click con offset.'},{question:"¿Cómo lleno un campo de texto?",answer:'When relleno el campo "$.LOGIN.email" con "[email protected]". También: When limpio y relleno el campo (borra antes), When escribo lentamente (simula humano con delays).'},{question:"¿Cómo manejo dropdowns/selects?",answer:'When selecciono la opción "Chile" en el select "$.FORM.pais". Soporta selección por texto visible, por valor y por índice.'},{question:"¿Cómo subo archivos?",answer:'When adjunto el archivo "datos.pdf" en el campo "$.FORM.upload". El archivo debe estar en la carpeta del proyecto o usa ruta absoluta.'},{question:"¿Cómo manejo iframes?",answer:'When cambio al iframe "$.PAGINA.iframe_pago". Después interactúas normalmente con los elementos dentro. Para volver: When vuelvo al contexto principal.'},{question:"¿Cómo manejo múltiples pestañas/ventanas?",answer:'El framework detecta nuevas pestañas automáticamente. Usa: When cambio a la pestaña "2" (por índice) o When cambio a la pestaña que contiene "checkout" (por URL/título).'},{question:"¿Cómo hago drag & drop?",answer:'When arrastro el elemento "$.BOARD.tarea" al elemento "$.BOARD.columna_done". El sistema tiene múltiples fallbacks para máxima compatibilidad con diferentes frameworks frontend.'},{question:"¿Cómo manejo alertas/diálogos del navegador?",answer:'When acepto la alerta / When rechazo la alerta / Then verifico que la alerta contiene "¿Estás seguro?". El framework intercepta alerts, confirms y prompts automáticamente.'},{question:"¿Cómo verifico que un texto es visible en la página?",answer:'Then verifico que el elemento "$.PAGINA.titulo" contiene el texto "Bienvenido". También: Then el texto "Bienvenido" es visible en la página (sin selector específico).'},{question:"¿Qué son las Soft Assertions?",answer:"Validaciones que NO detienen el test al fallar. Se acumulan y se reportan al final. Actívalas con el tag @soft_assertions en el Scenario. Útil para verificar múltiples campos en un formulario."},{question:"¿Puedo validar atributos CSS o HTML?",answer:'Sí. Then verifico que el atributo "class" del elemento "$.FORM.campo" contiene "error". También valida estilos computados, visibilidad, habilitado/deshabilitado, checked, etc.'},{question:"¿Puedo hacer pruebas de API sin navegador?",answer:"Sí. Usa el tag @no_browser en el Scenario. Los steps de API (GET, POST, PUT, DELETE, PATCH) funcionan sin abrir navegador. Valida status codes, body, headers y tiempos de respuesta."},{question:"¿Cómo hago una petición POST con body JSON?",answer:'When envío una petición POST a "/api/users" con body: (seguido de un DocString JSON). También puedes cargar el body desde archivo: When envío una petición POST a "/api/users" con el archivo "payload.json".'},{question:"¿Puedo validar un JSON Schema en la respuesta?",answer:'Sí. Then la respuesta cumple con el JSON Schema del archivo "schemas/user.json". Valida tipos, campos requeridos, formatos y estructura completa.'},{question:"¿Puedo interceptar peticiones de red del navegador?",answer:"Sí. El framework permite capturar requests/responses que hace el frontend (XHR/fetch) y validar su contenido, headers o status. Útil para verificar que el frontend envía los datos correctos al backend."},{question:"¿Puedo hacer pruebas mobile con este framework?",answer:"Sí. Soporta Android e iOS mediante Appium. Los steps mobile cubren: taps, swipes, scroll, pinch/zoom, rotación, te
17630clado, navegación del dispositivo (back/home), y verificaciones de elementos nativos."},{question:"¿Qué necesito para pruebas mobile?",answer:"Appium Server instalado, el driver correspondiente (UiAutomator2 para Android, XCUITest para iOS), y un dispositivo/emulador. Configura APPIUM_URL, PLATFORM_NAME, DEVICE_NAME y APP_PATH en .env."},{question:"¿Los JSON POMs funcionan diferente en mobile?",answer:`Sí. En mobile los POMs usan formato {"by": "xpath", "value": "//XCUIElementTypeButton[@name='Login']"} en vez del selector directo. Esto permite especificar la estrategia de localización (xpath, id, accessibility_id, class_name).`},{question:"¿Puedo automatizar aplicaciones de escritorio?",answer:"Sí. El framework soporta testing desktop con PyAutoGUI (clicks por coordenadas o por imagen), OCR (lectura de texto en pantalla) y modo mixto web+desktop (combina navegador con app nativa)."},{question:"¿Cómo funciona el click por imagen en desktop?",answer:"Capturas un screenshot del botón/elemento como referencia (imagen PNG). El step busca esa imagen en la pantalla y hace click en su centro. Útil para apps sin accesibilidad expuesta."},{question:"¿Puedo conectarme a una base de datos durante los tests?",answer:"Sí. Soporta SQLite, PostgreSQL y MySQL. Puedes ejecutar SELECT para validar datos, INSERT/UPDATE/DELETE para preparar escenarios, y guardar resultados en variables para usar en steps posteriores."}
17630,{question:"¿Puedo combinar pruebas web con validaciones de BD?",answer:"Sí. Un mismo Scenario puede: crear un registro vía web, luego verificar con un SELECT que se guardó correctamente en la base de datos."},{question:"¿Qué proveedores de IA soporta?",answer:"Gemini (Google), OpenAI (GPT), Anthropic (Claude), Ollama (local/offline) y Azure OpenAI. Se auto-detecta por API keys presentes o se configura con AI_PROVIDER en .env."},{question:"¿Qué es el Self-Healing?",answer:"Cuando un selector falla (elemento no encontrado), la IA analiza el HTML de la página y sugiere selectores alternativos automáticamente. Configura SELF_HEALING_ENABLED=true en .env. Funciona con cualquier proveedor de IA."},{question:"¿Puedo hacer testing de sistemas de IA Generativa?",answer:"Sí. Hay 20+ steps especializados para validar respuestas de IA: detección de alucinaciones, validación semántica, testing adversarial (jailbreaking), análisis de bias/toxicidad, validación de idioma, y Gemini como juez evaluador."},{question:"¿Qué es el AI Analysis Report?",answer:"Tras una ejecución, la IA analiza los resultados y genera un reporte con: causa raíz probable de cada fallo, sugerencias de corrección, tendencias de estabilidad y recomendaciones. Se configura con AI_ANALYSIS_REPORT=true."},{question:"¿Ollama funciona sin internet?",answer:"Sí. Ollama corre un modelo de IA localmente en tu máquina. Configura AI_PROVIDER=ollama y AI_MODEL=llama3.1. No requiere API key ni conexión, ideal para entornos on-premises o con restricciones de red."},{question:"¿Cómo evito repetir el login con MFA/2FA en cada test?",answer:'Usa sesiones guardadas: "haka-login --save nombre_sesion --url https://app.com/login". Esto abre un browser, te logueas manualmente (incluyendo MFA), y el estado se guarda. En los tests: Given inicio sesion guardada con el usuario "nombre_sesion".'},{question:"¿Las sesiones guardadas expiran?",answer:'Sí. Depende del servidor: típicamente 24-48 horas. Cuando expiran, recaptúralas con "haka-login --save nombre --url URL". Puedes verificar el estado con "haka-login --info nombre".'},{question:"¿Con qué sistemas funcionan las sesiones guardadas?",answer:"Con cualquier sistema que use cookies de sesión: Salesforce, SAP, Azure AD, Google Workspace, AWS Console, Okta, Auth0, y cualquier aplicación web con autenticación basada en cookies."},{question:"¿Qué reportes genera el framework?",answer:"Reporte HTML personalizado con screenshots embebidos (generado automáticamente), compatible con Allure, y opcionalmente un AI Analysis Report que usa IA para analizar resultados. Los screenshots se toman en cada fallo y opcionalmente en cada paso."},{question:"¿Cómo activo el reporte HTML?",answer:"Agrega el hook en tu environment.py (se incluye con haka-init). El reporte se genera automáticamente en html-reports/ al finalizar la ejecución."},{question:"¿Puedo tomar screenshots en cada paso, no solo al fallar?",answer:"Sí. Configura SCREENSHOT_ON_EACH_STEP=true en .env. Útil para evidencia visual completa de la ejecución."},{question:"¿Es compatible con GitHub Actions / GitLab CI?",answer:"Sí. Incluye configuraciones de ejemplo para GitHub Actions, GitLab CI, Bitbucket Pipelines y Azure DevOps. La clave es: instalar dependencias, configurar variables como secrets, ejecutar con HEADLESS=true, y subir reportes como artifacts."},{question:"¿Cómo integro con Jira / Xray?",answer:"Configura las variables XRAY_CLIENT_ID/SECRET en .env. El framework reporta resultados automáticamente a Xray Cloud tras cada ejecución. Cada tag del Scenario se mapea a un test case en Jira. No requiere código adicional."},{question:"¿Cómo integro con Haka Lens?",answer:"Configura HAKA_LENS_URL y HAKA_LENS_AUTH en .env. Los resultados se reportan automáticamente al finalizar. El tag del Scenario debe coincidir con la clave del test en Haka Lens."},{question:"¿Puedo reintentar escenarios que fallan?",answer:"Sí. Configura RETRY_FAILED_SCENARIOS=true y MAX_SCENARIO_RETRIES=2 en .env. Los escenarios fallidos se reintentan automáticamente al final con un browser limpio. Útil para flakiness por timing."},{question:"¿Puedo ejecutar un step solo si un elemento está visible?",answer:'Sí. Usa pasos condicionales: When si el elemento "$.PAGINA.cookie_banner" es visible, hago click en "$.PAGINA.aceptar_cookies". Si no es visible, el step se omite sin fallar.'},{question:"¿Cómo manejo popups/banners intermitentes?",answer:'Con pasos condicionales. El framework tiene steps tipo "si existe/es visible, entonces...". Ejemplo: When si el elemento "$.APP.popup_promo" existe, hago click en "$.APP.cerrar_popup".'},{question:"¿Puedo emular un dispositivo móvil en el browser?",answer:"Sí. Configura VIEWPORT_WIDTH/VIEWPORT_HEIGHT en .env o usa browser_context con user_agent mobile. Playwright tiene presets de dispositivos (iPhone, Pixel, etc.)."},{question:"¿Puedo configurar geolocalización, idioma o zona horaria?",answer:"Sí. En .env o en browser_context: GEO_LATITUDE, GEO_LONGITUDE, LOCALE (ej: es-CL), TIMEZONE (ej: America/Santiago). Útil para probar funcionalidades depen
17630dientes de ubicación."},{question:"¿Puedo usar proxy o modo offline?",answer:"Sí. Configura PROXY_SERVER en .env para proxy. El framework también soporta modo offline (simular pérdida de conexión) y throttling de red."},{question:"¿Qué es Stealth Mode?",answer:"STEALTH_MODE=true hace que el navegador automatizado pase desapercibido ante detecciones anti-bot. Modifica fingerprints, headers y propiedades de navigator para simular un usuario real."},{question:"¿Tiene soporte especial para Salesforce?",answer:"Sí. Con pip install haka-playwright-engine[salesforce] obtienes login vía frontdoor.jsp (bypasea MFA automáticamente vía API), soporte multi-sandbox/multi-usuario, y sesión reutilizable entre escenarios."},{question:"¿Por qué un test pasa local pero falla en CI?",answer:"Causas comunes: 1) HEADLESS no configurado, 2) resolución diferente (configura VIEWPORT), 3) timing más lento (aumenta TIMEOUT), 4) variables de entorno no inyectadas como secrets, 5) dependencias del sistema no instaladas (usa --with-deps)."},{question:"¿Qué hago si un elemento no se encuentra (TimeoutError)?",answer:"Verifica: 1) El selector es correcto (usa DevTools), 2) El timeout es suficiente (aumenta TIMEOUT), 3) El elemento no está en un iframe (usa step de cambio), 4) Necesita scroll previo, 5) Está detrás de una animación/loader."},{question:'¿Qué es "Step undefined" y cómo lo resuelvo?',answer:'Significa que el step que escribiste no coincide con ningún paso del framework. Verifica la sintaxis exacta con "haka-steps". Los steps son sensibles a espacios, comillas y parámetros.'},{question:"¿Cómo valido que mi .env está correcto?",answer:'Ejecuta "haka-validate" en terminal. Detecta: variables mal escritas (typos por Levenshtein), valores inválidos, dependencias cruzadas (ej: self-healing requiere API key de IA), y genera un reporte de la configuración.'},{question:"¿Puedo ver un video de la ejecución?",answer:"Sí. Configura VIDEO_RECORDING=true en .env. Playwright graba un video de cada escenario que se guarda en la carpeta de reportes. Útil para debugging de tests inestables."},{question:"¿El framework genera un .env de ejemplo?",answer:'Sí. Ejecuta "haka-validate --generate-env" para generar un archivo .env.example con todas las variables documentadas y sus valores por defecto.'}],Qne=[{question:"¿Cómo instalo Haka AI Studio?",answer:'Descarga el archivo .vsix y ejecuta en terminal: code --install-extension haka-ai-studio-1.6.3.vsix. También puedes instalarlo desde VS Code: Extensiones → menú ⋯ → "Install from VSIX…" y seleccionar el archivo.'},{question:"¿Qué versión de VS Code necesito?",answer:"Se requiere VS Code 1.85.0 o superior. Recomendamos mantener VS Code actualizado para evitar incompatibilidades."},{question:"¿Necesito instalar algo más además de la extensión?",answer:'Para grabar con Playwright necesitas Node.js 18+ y ejecutar "npx playwright install" una vez para descargar los navegadores. Para Selenium necesitas el driver del navegador correspondiente (chromedriver, geckodriver).'},{question:"¿Funciona en Windows, macOS y Linux?",answer:"Sí. La extensión funciona en cualquier sistema operativo donde VS Code esté soportado."},{question:"¿Es compatible con VS Code remoto (SSH, WSL, Containers)?",answer:"La extensión funciona en VS Code local. En entornos remotos puede haber limitaciones con el grabador (que necesita un navegador visible), pero la edición de .feature, @aistudio, Kai y las funcionalidades de editor funcionan normalmente."},{question:"¿Cómo inicio sesión?",answer:"Al abrir el panel por primera vez, acepta los Términos de Uso y luego inicia sesión con tu cuenta de Google o con tu clave de licencia HakaLab. Los usuarios @hakalab.com tienen acceso completo con Google."},{question:"¿La licencia es por usuario o por dispositivo?",answer:"Es por dispositivo. Cada licencia se vincula al primer equipo donde se activa. Si cambias de computador, debes cerrar sesión en el anterior o contactar a soporte para liberar la licencia."},{question:'¿Qué hago si me aparece "Licencia ya en uso en otro dispositivo"?',answer:"Asegúrate de cerrar sesión en tu equipo anterior. Si no tienes acceso a ese equipo, contacta a soporte en [email protected] para que liberen tu licencia."},{question:"¿Qué proveedor de IA debo usar?",answer:"Recomendamos Gemini (Google) por su relación costo/beneficio: es ~25 veces más barato que OpenAI y genera resultados de calida
17630d comparable para pruebas automatizadas. El modelo recomendado es gemini-2.0-flash."},{question:"¿Cuánto cuesta usar la IA?",answer:"Con Gemini 2.0 Flash, cada generación de test cuesta aproximadamente $0.003 USD. Para un uso normal de ~100 generaciones al mes, el costo es alrededor de $0.20 USD/mes. OpenAI es más caro (~$0.01/test) y Claude intermedio (~$0.008/test)."},{question:"¿Dónde obtengo mi API Key de Gemini?",answer:"Ve a https://aistudio.google.com/apikey y crea una clave gratuita. Google ofrece un nivel gratuito generoso. Luego pega la clave en Config → Gemini AI → API Key."},{question:"¿Puedo usar OpenAI o Claude en vez de Gemini?",answer:"Sí. La arquitectura soporta los tres proveedores. Configura tu API Key del proveedor preferido en la pestaña Config. Sin embargo, Gemini es el recomendado por costo y es el más probado."},{question:"¿Mis datos o código se envían a la nube?",answer:"Solo se envía la grabación del navegador (acciones realizadas) al proveedor de IA para generar el test. No se almacena código en servidores de HakaLab. La comunicación es directa entre tu VS Code y el proveedor de IA por HTTPS."},{question:"¿Dónde se almacena mi API Key?",answer:"En el almacenamiento cifrado de VS Code (context.secrets). Nunca se guarda en texto plano ni se envía a HakaLab."},{question:"¿Qué es Koru y cómo funciona?",answer:"Koru es el grabador de interacciones. Abre un navegador, graba todo lo que haces (clics, escritura, navegación) y luego usa IA para convertir esas acciones en un test Gherkin completo con Feature, Steps y Page Objects."},{question:"¿Qué navegadores puedo usar para grabar?",answer:"Con Playwright: Chromium, Chrome, Edge, Firefox y WebKit (Safari). Con Selenium: Chrome y Firefox. La resolución del navegador es configurable."},{question:"¿Cuál es la diferencia entre grabar con Playwright y Selenium?",answer:"Playwright usa el modo codegen nativo (más estable, captura selectores robustos). Selenium captura XPaths. Elige según el framework que uses para ejecutar las pruebas: si usas haka-playwright-engine, graba con Playwright."},{question:"¿Puedo grabar en un sitio que requiere login con MFA/2FA?",answer:'Sí. Koru soporta "sesiones guardadas": puedes guardar el estado de autenticación (cookies, localStorage, sessionStorage) cifrado con Fernet. Al grabar, selecciona el perfil de sesión y el navegador se abre ya autenticado sin repetir el login.'},{question:"¿Cómo guardo una sesión para no repetir el login?",answer:'En Koru, después de loguearte manualmente una vez, usa la opción "Guardar sesión". La próxima vez que grabes, selecciona esa sesión antes de iniciar y el navegador se abrirá ya logueado.'},{question:"El grabador no se abre o muestra error al iniciar",answer:'Verifica que Playwright esté instalado: ejecuta "npx playwright install" en terminal. Si usas Selenium, verifica que el driver del navegador esté en tu PATH. También revisa que no haya otra instancia del grabador abierta.'},{question:"¿Puedo agregar validaciones (Then) después de grabar?",answer:"Sí. Después de detener la grabación, hay una etapa para agregar validaciones antes de generar con IA. Puedes verificar textos visibles, estados de elementos, URLs, etc."},{question:"¿Qué genera la IA después de grabar?",answer:"Genera un archivo .feature completo con escenarios Gherkin, los archivos de steps (implementaciones Python) y Page Objects con los selectores de los elementos utilizados. Todo listo para ejecutar."},{question:"¿Qué es @aistudio y cómo lo uso?",answer:'Es un asistente inteligente que funciona dentro de archivos .feature. Escribe @aistudio seguido de lo que buscas para encontrar steps existentes. Agrega "?" para pedirle a la IA que genere algo nuevo.'},{question:"¿Cuál es la diferencia entre @aistudio y @aistudio?",answer:'Sin "?" busca en tus archivos locales y en los 1187 vectores del framework (instantáneo). Con "?" consulta a la IA generativa para crear steps o escenarios nuevos (tarda 1-5 segundos).'},{question:"¿@aistudio funciona sin conexión a internet?",answer:'La búsqueda local (sin "?") funciona offline porque escanea tus archivos .feature. La generación con IA (con "?") necesita conexión para consultar al proveedor.'},{question:"¿Puedo generar un Feature completo con @aistudio?",answer:'Sí. Escribe algo como "@aistudio? genera todos los escenarios para un CRUD de usuarios" y la IA genera un Feature completo con Backgroun
17630d, Scenario Outline y Examples.'},{question:"@aistudio no muestra sugerencias",answer:'Verifica que estás en un archivo .feature y que el workspace contiene archivos .feature escaneados. Si usas "?" verifica que tu API Key esté configurada en Config. Revisa la barra de estado de VS Code por mensajes de error.'},{question:"¿Qué es Kai?",answer:"Kai es un chat con IA especializado en automatización de pruebas. Tiene conocimiento vectorizado del framework haka-playwright-engine y puede ayudarte con consultas sobre steps, mejores prácticas, debugging de tests y explicación de código generado."},{question:"¿Kai conoce mi proyecto o solo el framework?",answer:"Kai conoce los 1187 vectores del framework haka-playwright-engine y además puede consultar los archivos .feature de tu proyecto actual para dar respuestas contextualizadas."},{question:"¿Puedo preguntarle a Kai cómo resolver un error de ejecución?",answer:"Sí. Pega el error o describe el problema y Kai te sugerirá soluciones basándose en el framework y mejores prácticas de automatización."},{question:"¿Los archivos .feature se colorean automáticamente?",answer:"Sí. Al instalar la extensión, todos los archivos .feature reciben syntax highlighting automático con colores para keywords, steps, tags, variables, tablas y comentarios. Soporta Gherkin en español, inglés, francés, portugués y alemán."},{question:"¿Puedo personalizar los colores del Gherkin?",answer:"Sí. En Config → Cucumber / Gherkin hay 7 color pickers que se aplican en tiempo real al editor. También puedes activar negrita en keywords y cursiva en tags/comentarios."},{question:"¿Cómo formateo un archivo .feature?",answer:'Clic derecho → "Haka: Formatear Documento (.feature)" o usa Ctrl+Shift+I. Alinea tablas, corrige indentación (Feature→0, Scenario→2, Steps→4) y elimina espacios sobrantes.'},{question:'¿Qué hace "Convertir en Scenario Outline"?',answer:"Toma un Scenario normal, extrae los valores entre comillas, los reemplaza por variables (<param>) y genera una tabla Examples. No parametriza identificadores de Page Object ($.PAGINA.elemento)."},{question:"¿Go to Definition funciona con steps del framework?",answer:"Go to Definition (Ctrl+Click o F12) navega a la implementación si está en tus carpetas /steps/*.py. Si el step pertenece al framework, muestra un mensaje indicando que es interno de haka-playwright-engine."},{question:"¿Qué muestra el Hover sobre un step?",answer:"Muestra en cuántos archivos y escenarios se usa ese mismo step en tu proyecto, con la ruta y número de línea de cada ocurrencia. Útil para entender el impacto de modificar un step."},{question:"¿Qué es la pestaña Rest?",answer:"Permite generar archivos .feature de pruebas REST (API) a partir de archivos OpenAPI/Swagger, colecciones Postman o comandos cURL. Genera escenarios de prueba para cada endpoint."},{question:"¿Qué es el Mock Server?",answer:"Es un servidor HTTP local configurable que simula APIs. Puedes definir endpoints con respuestas JSON personalizadas, status codes, delays y CORS. Útil para probar tu frontend sin depender del backend real."},{question:"¿En qué puerto corre el Mock Server?",answer:"El puerto es configurable. Por defecto usa un puerto libre disponible. Puedes cambiarlo en la configuración del mock."},{question:"¿En qué formato genera el código?",answer:"Genera archivos .feature (Gherkin), archivos de steps en Python (compatibles con Behave) y Page Objects en formato JSON. Todo listo para ejecutar con haka-playwright-engine o adaptable a otros frameworks."},{question:"¿El código generado sobrescribe mis archivos?",answer:"No. La exportación tiene lógica de merge inteligente: detecta imports y steps existentes y solo agrega lo nuevo. No duplica imports ni definiciones de steps que ya existan."},{question:"¿Puedo personalizar el prompt que usa la IA para generar?",answer:'Sí. En Config → "Instrucción adicional" puedes escribir un prompt personalizado que se agrega al contexto de la IA. Útil para indicar convenciones de tu equipo o reglas específicas.'},{question:"¿El código generado es compatible con mi framework?",answer:"Está optimizado para haka-playwright-engine (Playwright + Behave), pero el formato Gherkin es universal. Para Selenium, el grabador genera código compatible con el motor Selenium del framework."},{question:"¿Qué es la vectorización?",answer:"Es un proceso que escanea los steps de tu proyecto y los convierte en representaciones numéricas (embeddings) para que @aistudio pueda buscar steps similares semánticamente, no solo por texto exacto."},{question:"¿Necesito vectorizar cada vez que agrego steps nuevos?",answer:'Sí. Si agregas steps propios (no del framework), ejecuta la vectorización desde Config → Vectorización → "Escanear y vectorizar steps custom" para que @aistudio los encuentre.'},{question:"¿Los 1187 vectores del framework vienen pre-incluidos?",answer:"Sí. Cubren Web (481), Validaciones (151), Guías (143), API (130), Mobile (129), Desktop (87), GenAI (52) y Base de Datos (14). Se buscan automáticamente sin necesidad de vectorizar nada."},{question:"La extensión no aparece en la barra de actividad",answer:"Reinicia VS Code después de instalar. Si persiste, verifica que el .vsix se instaló correctamente en Extensiones → Installed. Si aparece deshabilitada, habilítala manualmente."},{question:"La IA genera código con errores o steps que no existen",answer:'Esto puede pasar con prompts muy vagos. Sé más específico en tus instrucciones. También puedes agregar contexto en Config → "Instru
17630cción adicional" indicando los steps disponibles o el formato preferido.'},{question:"El grabador se cierra inesperadamente",answer:'Puede deberse a falta de memoria, un navegador corrupto o un conflicto de puertos. Reinstala los navegadores con "npx playwright install" y verifica que ningún otro proceso use el puerto del grabador.'},{question:"No puedo conectarme al proveedor de IA (error de red)",answer:"Verifica tu conexión a internet. Si estás detrás de un proxy corporativo, configura las variables de entorno HTTP_PROXY/HTTPS_PROXY. También confirma que tu API Key sea válida y no haya expirado."},{question:"Los colores de Gherkin no se aplican",answer:'Asegúrate de que el archivo tenga extensión .feature. Si usas un tema de VS Code que sobreescribe los colores, ve a Config → Cucumber/Gherkin y ajusta los colores manualmente. El botón "Restablecer" vuelve a los valores por defecto.'},{question:"¿Cómo actualizo la extensión?",answer:"Descarga el nuevo .vsix y ejecuta code --install-extension haka-ai-studio-X.Y.Z.vsix. La nueva versión reemplaza la anterior automáticamente. Tu configuración y API Keys se conservan."},{question:"¿Haka AI Studio es compatible con otras extensiones de Gherkin/Cucumber?",answer:"Puede haber conflictos de syntax highlighting si tienes otra extensión de Gherkin instalada. Recomendamos desactivar las demás extensiones de Cucumber/Gherkin para evitar que se sobreescriban los colores o el completado."},{question:"¿La extensión recopila datos o telemetría?",answer:"No. Haka AI Studio no envía telemetría, no rastrea tu uso y no almacena datos en servidores de HakaLab. La única comunicación externa es con tu proveedor de IA configurado."},{question:"¿Las sesiones guardadas son seguras?",answer:"Sí. Se cifran con Fernet (AES-128-CBC) y se almacenan localmente. La clave de cifrado está en el almacenamiento seguro de VS Code. Nadie sin acceso a tu equipo puede leer las sesiones."}],Xne=[{question:"¿Qué es HakaBoost?",answer:"Es una extensión de Chrome que actúa como copiloto de calida
17630d para equipos QA. Se integra como panel lateral en Jira Cloud y Azure DevOps, y usa IA para mejorar descripciones de tareas, generar escenarios de prueba en Gherkin, crear tests automáticamente y analizar cobertura."},{question:"¿Necesito saber programar para usarlo?",answer:"No. HakaBoost está diseñado para QA Analysts, Product Owners y cualquier persona que escriba o revise historias de usuario. La IA genera los escenarios de prueba automáticamente en formato Gherkin (lenguaje natural estructurado)."},{question:"¿En qué plataformas funciona?",answer:"Jira Cloud (*.atlassian.net) y Azure DevOps (dev.azure.com). Detecta automáticamente en cuál estás navegando y adapta su interfaz. No funciona en Jira Server/Data Center."},{question:"¿Cómo instalo HakaBoost?",answer:'Desde la Chrome Web Store, busca "HakaBoost" e instala. Aparecerá en tu barra de extensiones. También puedes cargarlo manualmente desde chrome://extensions en modo desarrollador.'},{question:"¿Qué navegador necesito?",answer:"Google Chrome 120 o superior (Manifest V3). También funciona en navegadores basados en Chromium (Edge, Brave) si soportan el Chrome Web Store."},{question:"¿Cómo abro el panel de HakaBoost?",answer:"Navega a un issue/work item en Jira o Azure DevOps, luego haz clic en el ícono de HakaBoost o usa el atajo Ctrl+Shift+Y (Windows) / Cmd+Shift+Y (Mac). Se abrirá como panel lateral."},{question:"¿Cuál es la diferencia entre Free y Pro?",answer:"Free: mejorar descripción + sugerir tests (funciones base). Pro: todo lo anterior + Análisis de calidad (recomendaciones, riesgos), Datos de prueba (válidos/inválidos/límite), Análisis de cobertura (gaps), ofuscación personalizable, exportación a PDF y publicación como comentario."},{question:"¿Cómo me registro en el plan Free?",answer:'Al abrir HakaBoost por primera vez, selecciona "Free" e ingresa nombre, email y empresa. No requiere contraseña. Es inmediato.'},{question:"¿Cómo accedo al plan Pro?",answer:"Tres opciones: 1) Con clave de licencia (email + key), 2) Con Google (dominios autorizados), 3) Con Microsoft (dominios autorizados). Los clientes de Haka Lab tienen acceso Pro gratuito con su cuenta Google corporativa."},{question:"¿La licencia Pro es por usuario o por dispositivo?",answer:"Por dispositivo. Cada licencia se vincula al equipo donde la activas. Si inicias sesión en otro equipo, la sesión anterior se cierra automáticamente (detecta sesión concurrente)."},{question:'¿Qué pasa si me dice "sesión en otro dispositivo"?',answer:"Significa que la misma licencia se usó en otro equipo. Solo puede estar activa en uno a la vez. Si tú no la usaste en otro lugar, contacta a soporte ([email protected]) para verificar."},{question:"¿Qué motores de IA soporta?",answer:"Tres opciones: 1) Chrome Built-in AI (Gemini Nano) — 100% local, sin costo, sin enviar datos a internet. 2) Google Gemini (cloud) — modelos como gemini-2.5-flash. 3) OpenAI (cloud) — modelos como gpt-4o-mini."},{question:"¿Qué es Chrome Built-in AI?",answer:"Es el modelo Gemini Nano que corre directamente en tu computador dentro de Chrome, sin enviar datos a ningún servidor. Es gratuito, privado y no requiere API key. La primera vez descarga ~5GB del modelo."},{question:"¿Cuál IA me recomiendan?",answer:"Si la privacidad es prioridad: Chrome Built-in AI (100% local). Si necesitas la mejor calidad de resultados: Gemini Cloud (gemini-2.5-flash es rápido y económico). OpenAI es una alternativa si ya tienes cuenta."},{question:"¿Dónde obtengo mi API Key de Gemini u OpenAI?",answer:"Gemini: https://aistudio.google.com/apikey (gratis con límites generosos). OpenAI: https://platform.openai.com/api-keys (requiere cuenta con créditos). Pega la key en Configuraciones → IA."},{question:"¿Cuánto cuesta usar la IA en la nube?",answer:"Gemini 2.5 Flash: ~$0.001-0.003 USD por consulta. OpenAI gpt-4o-mini: ~$0.005-0.01 por consulta. Chrome Built-in AI: completamente gratis (se ejecuta local)."},{question:"¿Puedo personalizar el prompt que usa la IA?",answer:"Sí. En Configuraciones → IA hay un campo para modificar el prompt. La IA viene con un prompt optimizado de QA Analyst senior en BDD, pero puedes adaptarlo a las convenciones de tu equipo. Hay un botón para restaurar el original."},{question:"¿Cómo mejoro una descripción con IA?",answer:'Abre el issue en Jira/Azure, abre HakaBoost, haz clic en "Leer descripción" para cargarla, luego "Mejorar Desc.". La IA genera una versión mejorada con criterios de aceptación y escenarios Gherkin (según el modo que elijas).'},{question:"¿Puedo actualizar la descripción directamente en Jira/Azure?",answer:'Sí. Después de mejorar, el botón "Actualizar Jira" o "Actualizar Azure" reemplaza la descripción del issue con la versión mejorada. Funciona via API REST directa.'},{question:"¿Qué modos de mejora hay?",answer:"7 modos: 1) Solo mejorar descripción, 2) Mejorar + criterios de aceptación, 3) Mejorar + criterios + Gherkin, 4) Mejorar + criterios + lenguaje natural, 5) Sugerir tests en Gherkin, 6) Sugerir tests en lenguaje natural, 7) Crear tests existentes (lee los que ya están escritos)."},{question:"¿Cómo creo tests desde los escenarios generados?",answer:'Después de generar escenarios, haz clic en "Sugerir Tests". HakaBoost parsea cada Scenario/Scenario Outline y te permite crear cada uno como un issue Test en Jira (o Test Case en Azure DevOps), vinculándolo automáticamente a la tarea principal.'},{question:"¿Los tests creados se vinculan al issue original?",answer:'Sí. Cada test creado se vincula automáticamente al work item principal con el tipo de link configurado (por defecto "Test" en Jira o "Tested By" en Azure DevOps).'},{question:"¿HakaBoost funciona con Xray Cloud?",answer:'Sí. Si configuras las credenciales de Xray (Client ID + Client Secret), los tests creados en Jira se configuran como tipo "Cucumber" en Xray y se les sube el Gherkin automáticamente. También puedes exportar archivos .feature.'},{question:"¿Cómo configuro Xray Cloud?",answer:"En Configuraciones → Xray, ingresa tu Client ID y Client Secret (se generan en Xray Cloud → Settings → API Keys). HakaBoost los usa para autenticar y subir los escenarios Gherkin a los tests."},{question:"¿Qué es el Análisis de Calidad (Pro)?",answer:"Genera un reporte con: recomendaciones de mejora, riesgos identificados, precondiciones sugeridas y evaluación de la calidad del requerimiento. Se puede exportar a PDF o publicar como comentario en el issue."},{question:"¿Qué son los Datos de Prueba (Pro)?",answer:"Sugiere datos concretos para cada escenario: valores válidos, inválidos, de límite y edge cases. Los presenta visualmente con cards y badges de clasificación. Puede transformar Scenarios en Scenario Outlines con tablas Ex
17630amples."},{question:"¿Qué es el Análisis de Cobertura (Pro)?",answer:"Compara los escenarios generados contra la descripción original del issue e identifica brechas: funcionalidades mencionadas que no tienen test. Sugiere escenarios faltantes con títulos concretos para completar la cobertura."},{question:"¿Qué formatos de exportación soporta?",answer:"Archivos .feature (Cucumber/Gherkin), Excel/CSV (datos de prueba tabulares) y PDF (reportes de análisis). La exportación .feature es compatible directamente con frameworks BDD como Behave, Cucumber o haka-playwright-engine."},{question:"¿Puedo publicar el análisis como comentario en el issue?",answer:'Sí. Las tabs de Análisis, Datos de Prueba y Cobertura tienen un botón "Publicar como comentario" que agrega el resultado directamente como comentario en el issue de Jira o Azure DevOps.'},{question:"¿Mis datos se envían a algún servidor de HakaLab?",answer:"No. HakaBoost no envía datos a servidores propios. Los tokens y credenciales se almacenan localmente en tu navegador (chrome.storage). Solo se comunica con: tu Jira/Azure (vía API), tu proveedor de IA configurado, y Firebase para autenticación."},{question:"¿Qué es la ofuscación de datos?",answer:"Antes de enviar la descripción a la IA en la nube, HakaBoost reemplaza automáticamente datos sensibles (emails, URLs, IPs, teléfonos, RUT, UUIDs) por placeholders como [EMAIL_1], [URL_1]. La respuesta de la IA se des-ofusca para restaurar los valores originales."},{question:"¿Puedo agregar palabras personalizadas a la ofuscación?",answer:"Sí. En Configuraciones → Ofuscación puedes agregar un diccionario de palabras (ej: nombre de tu empresa, clientes, proyectos internos) que se reemplazarán antes de enviar a la IA."},{question:"¿Chrome Built-in AI envía datos a internet?",answer:"No. Gemini Nano se ejecuta 100% en tu computador. Ningún dato sale de tu máquina. Es la opción más privada."},{question:"¿Dónde se guardan mis credenciales de Jira/Azure/IA?",answer:"En chrome.storage (almacenamiento local/sincronizado del navegador). Nunca se envían a servidores de HakaLab. Se eliminan al cerrar sesión o desinstalar la extensión."},{question:"¿Cómo configuro Jira Cloud?",answer:"En Configuraciones → Jira: ingresa tu URL base (ej: https://tu-sitio.atlassian.net), email y API Token. El API Token se genera en https://id.atlassian.com/manage-profile/security/api-tokens."},{question:"¿Cómo configuro Azure DevOps?",answer:"En Configuraciones → Azure DevOps: ingresa tu Organización, Proyecto y un Personal Access Token (PAT) con permisos de Work Items. El PAT se genera en Azure DevOps → User Settings → Personal Access Tokens."},{question:"¿Puedo cambiar el tipo de issue que crea?",answer:"Sí. En Configuraciones puedes elegir el tipo de issue a crear (Test, Task, Bug, etc.) y el tipo de vínculo (Test, Relates, Blocks). Si el tipo seleccionado no existe en tu proyecto, usa un fallback automático."},{question:"¿Puedo cambiar el idioma de la interfaz?",answer:"Sí. HakaBoost soporta español e inglés. Elige el idioma al registrarte o cámbialo en Configuraciones. Afecta toda la interfaz y los mensajes."},{question:"HakaBoost no se abre / no aparece el panel lateral",answer:"Verifica que estés en una URL de Jira Cloud (*.atlassian.net) o Azure DevOps (dev.azure.com). El panel solo se habilita en páginas soportadas. Si estás en la URL correcta, recarga la página y vuelve a intentar con Ctrl+Shift+Y."},{question:'"Error de conexión" al probar la configuración de Jira',answer:'Verifica: 1) La URL base no tiene "/" al final, 2) El email es el de tu cuenta Atlassian, 3) El API Token es válido y no ha expirado (genera uno nuevo si dudas), 4) Tu usuario tiene permisos en el proyecto.'},{question:'"Error de conexión" en Azure DevOps',answer:'Verifica: 1) La organización y proyecto están bien escritos (case-sensitive), 2) El PAT tiene permisos "Work Items: Read & Write", 3) El PAT no ha expirado.'},{question:"La IA no genera respuesta o tarda mucho",answer:"Chrome Built-in AI: puede tardar hasta 120s en la primera consulta (descarga del modelo). Si falla, verifica que tu equipo soporta Chrome AI (chrome://flags → Prompt API). Gemini/OpenAI: verifica que la API Key sea válida y tengas saldo/cuota."},{question:"No puedo leer la descripción del issue",answer:"HakaBoost usa múltiples estrategias para leer la descripción (DOM + API). Si falla: 1) Recarga la página del issue, 2) Espera a que cargue completamente, 3) Verifica que tus credenciales tengan permiso de lectura en ese proyecto."},{question:"Los tests no se crean en Jira / da error al crear",answer:'Causas: 1) Tu usuario no tiene permiso para crear issues en ese proyecto, 2) El tipo de issue "Test" no existe (configura otro tipo en Settings), 3) El proyecto tiene campos obligatorios no soportados. Revisa el mensaje de error específico.'},{question:"¿Se puede usar con Jira Server o Data Center?",answer:"No. HakaBoost solo funciona con Jira Cloud (*.atlassian.net). Las APIs de Jira Server son diferentes 
17630y no están soportadas actualmente."},{question:"¿Hay atajo de teclado?",answer:"Sí. Ctrl+Shift+Y (Windows/Linux) o Cmd+Shift+Y (Mac) abre/cierra el panel lateral de HakaBoost."},{question:"¿Puedo usar HakaBoost sin conexión a internet?",answer:"Parcialmente. Con Chrome Built-in AI (si ya descargaste el modelo) puedes generar mejoras offline. Pero para leer/escribir en Jira/Azure y para IA en la nube necesitas conexión."},{question:"¿Cómo actualizo HakaBoost?",answer:"Si lo instalaste desde la Chrome Web Store, se actualiza automáticamente. Si lo cargaste manualmente, descarga la nueva versión y vuelve a cargarla desde chrome://extensions."}],Yne=[{question:"¿Qué es HakaBuddy?",answer:"Es una aplicación de escritorio para equipos QA que centraliza la gestión, ejecución y documentación de pruebas de software. Permite hacer pruebas manuales con evidencia visual, automatizar con Playwright, generar reportes profesionales en PDF/HTML, y publicar suites en CI/CD."},{question:"¿Necesito saber programar para usarlo?",answer:"No para pruebas manuales (capturas, video, pasos con evidencia, reportes). Para automatización con Playwright se requiere conocimiento básico del navegador, pero el grabador genera el código automáticamente sin escribir una línea."},{question:"¿En qué se diferencia de otras herramientas de testing?",answer:"Es desktop (tus datos quedan locales, no en la nube), incluye automatización Playwright integrada (graba y ejecuta sin herramientas externas), genera reportes listos para entregar, y conecta directamente con Jira/Xray y CI/CD. Todo en un solo ejecutable."},{question:"¿En qué sistemas operativos funciona?",answer:"Windows 10+, macOS 12+ (Intel y Apple Silicon) y Linux (Ubuntu 20.04+, Fedora, Arch). Se distribuye como ejecutable nativo para cada plataforma (.exe, .app, AppImage)."},{question:"¿Necesito instalar algo más?",answer:"No para el uso básico. El ejecutable incluye todo. Para automatización con Playwright, la primera vez se descargan los navegadores automáticamente (~200MB). Para grabación de video necesitas ffmpeg instalado (solo macOS/Linux)."},{question:"¿Necesito conexión a internet?",answer:"No para las funciones principales (pruebas manuales, capturas, reportes, ejecución de scripts). La conexión es necesaria para: validar la licencia, conectar con Jira/Xray, usar IA (Gemini/OpenAI/Claude), y push a CI/CD."},{question:"¿Dónde se guardan mis datos?",answer:"Todo se guarda localmente en tu equipo: Windows: C:\\Users\\{tu_usuario}\\AppData\\Local\\Hakabuddy\\data\\, macOS: ~/Library/Application Support/Hakabuddy/data/, Linux: ~/.local/share/Hakabuddy/data/. Incluye la base de datos SQLite, capturas, scripts, reportes y configuración."},{question:"¿Los datos persisten al actualizar?",answer:"Sí. La carpeta de datos es independiente del ejecutable. Al instalar una nueva versión, tus pruebas, scripts, suites y configuración se mantienen intactos."},{question:"¿Puedo mover mis datos a otro equipo?",answer:"Sí. Copia la carpeta data/ completa al mismo path en el nuevo equipo. Contiene la base de datos SQLite y todos los archivos asociados (capturas, scripts, reportes)."},{question:"¿Cómo inicio sesión?",answer:"Tres opciones: 1) Con Google (solo cuentas @hakalab.com — acceso completo), 2) Con clave de licencia (email + key), 3) Modo invitado (solo pruebas manuales, sin CI/CD ni Jira ni IA)."},{question:"¿La licencia es por usuario o por dispositivo?",answer:"Por dispositivo. Al activar tu licencia se vincula al equipo. Si cambias de computador, debes cerrar sesión en el anterior (libera el dispositivo) o contactar soporte para liberar la licencia remotamente."},{question:'¿Qué hago si me dice "Licencia ya en uso en otro dispositivo"?',answer:"Cierra sesión en el equipo anterior (Menú → Cerrar sesión). Si no tienes acceso a ese equipo, contacta a [email protected] para que liberen tu licencia."},{question:"¿Qué puedo hacer en Modo Invitado?",answer:"Pruebas manuales completas: registrar pasos, capturar pantalla, grabar video, generar reportes PDF/HTML. No disponible: Playwright, CI/CD, Jira/Xray, IA."},{question:"¿Cómo creo una prueba manual?",answer:'En la pantalla principal haz clic en "Nueva prueba". Ingresa título, selecciona producto/ambiente, y comienza a agregar pasos. Cada paso tiene: acción, estado (Exitoso/Fallido) y puedes adjuntar evidencia (captura, archivo, JSON).'},{question:"¿Cómo capturo la pantalla durante una prueba?",answer:"Tres modos: 1) Captura completa (toda la pantalla), 2) Área seleccionad
17630a (dibujas un rectángulo), 3) Con temporizador (cuenta regresiva de 3-5 segundos). La captura se adjunta automáticamente al paso actual."},{question:"¿Puedo grabar video de la ejecución?",answer:"Sí. Activa la grabación de video antes de ejecutar. Se graba toda la sesión y el video se adjunta al reporte. Soporta múltiples monitores en Windows y captura por ventana."},{question:"¿Puedo adjuntar archivos a un paso?",answer:"Sí. Puedes adjuntar PDFs, archivos JSON, capturas adicionales y cualquier archivo como evidencia de un paso. Se incluyen en el reporte y se guardan con la prueba."},{question:"¿Puedo editar pasos después de crearlos?",answer:"Sí. Puedes editar el título, estado y evidencia de cualquier paso durante o después de la ejecución. También puedes reordenar y eliminar pasos."},{question:"¿Cómo registro un paso como fallido?",answer:'Al crear o editar un paso, selecciona el estado "Fallido". La captura del momento del fallo se adjunta como evidencia. El paso se marca en rojo en el reporte.'},{question:"¿Cómo grabo un script de Playwright?",answer:'En la pestaña Playwright, ingresa la URL inicial y haz clic en "Grabar". Se abre un navegador donde interactúas normalmente. Al cerrar, el código del script se captura y se guarda listo para ejecutar.'},{question:"¿Qué navegadores puedo usar para grabar?",answer:"Chromium (predeterminado), Google Chrome y Microsoft Edge. Puedes configurar la resolución (viewport), locale, timezone, user-agent y estado de autenticación previo."},{question:"¿Puedo ejecutar un script individual?",answer:'Sí. Selecciona un script y haz clic en "Ejecutar". Se abre el navegador, ejecuta los pasos y captura screenshots de cada acción. Al finalizar muestra el resultado (exitoso/fallido) con el detalle.'},{question:"¿Qué es una suite de regresión?",answer:"Es un grupo ordenado de scripts que se ejecutan en secuencia. Puedes agregar, quitar y reordenar scripts. Al ejecutar una suite, cada script corre uno tras otro y se genera un reporte consolidado con el resultado de toda la suite."},{question:"¿Puedo ejecutar suites de regresión completas?",answer:'Sí. Selecciona la suite y "Ejecutar suite". Muestra progreso en tiempo real (script actual, exitosos, fallidos). Al finalizar genera un reporte HTML con screenshots por paso y un resumen.'},{question:"¿Puedo inyectar autenticación en los scripts?",answer:"Sí. Si tienes un archivo de estado de sesión (storage state de Playwright), puedes configurarlo en la suite. Cada script se ejecuta ya autenticado sin repetir el login."},{question:"¿Puedo ejecutar con datos (data-driven)?",answer:"Sí. Los scripts soportan ejecución parametrizada (outline): defines un dataset y el script se ejecuta N veces con diferentes datos. Cada iteración se registra individualmente."},{question:"¿Puedo publicar mis suites en un repositorio Git?",answer:"Sí. En la pestaña Git, configura tu repositorio (GitHub, GitLab o Bitbucket) y token. Con un clic publicas toda la suite: scripts, runner y workflow de CI/CD se suben al repositorio."},{question:"¿Qué workflows de CI/CD genera?",answer:"Genera automáticamente: GitHub Actions (.github/workflows/), GitLab CI (.gitlab-ci.yml) o Bitbucket Pipelines (bitbucket-pipelines.yml). El workflow instala dependencias, ejecuta la suite en headless y sube el reporte HTML como artefacto."},{question:"¿Qué es el runner que se publica?",answer:"Es un script Python que ejecuta todos los scripts de la suite en modo headless, captura screenshots y genera un reporte HTML autocontenido. Es lo que corre en el pipeline de CI/CD."},{question:"¿Necesito configurar algo en GitHub/GitLab/Bitbucket?",answer:"Solo necesitas un token con permisos de escritura en el repositorio. HakaBuddy se encarga de crear la estructura de archivos, el workflow y hacer el commit/push."},{question:"¿Qué tipos de reporte genera?",answer:"PDF (profesional con portada, contenido, evidencias, anexos y contraportada), HTML (autocontenido, modo oscuro, con logos y evidencias embebidas en base64), y Xray JSON (para importar resultados a Jira Xray)."},{question:"¿Puedo personalizar el reporte PDF?",answer:"Sí. Puedes configurar logos, colores de la portada, nombre de la empresa, QA responsable, y usar plantillas (portada + contraportada custom). Los pasos incluyen capturas, estados y detalle."},{question:"¿El reporte HTML es compartible?",answer:"Sí. Es un archivo .html único autocontenido (imágenes embebidas en base64, sin dependencias externas). Puedes enviarlo por email, subirlo a Confluence, o adjuntarlo en Jira."},{question:"¿Puedo generar reportes de suites de Playwright?",answer:"Sí. Al ejecutar una suite se genera automáticamente un reporte HTML con el resultado de cada script, screenshots por paso, y un resumen visual de la ejecución."},{question:"¿Cómo conecto HakaBuddy con Jira?",answer:"En Configuraciones → Jira, ingresa: URL de Jira (ej: https://tu-sitio.atlassian.net), email y API Token. Puedes validar la conexión antes de guardar."},{question:"¿Qué puedo hacer con la integración Jira?",answer:"Conectarte a tableros, ver sprints e issues, seleccionar un issue para asociarlo a tu prueba, adjuntar reportes como attachment y agregar comentarios con el resultado de la ejecución."},{question:"¿Cómo exporto resultados a Xray?",answer:"Configura las credenciales de Xray Cloud (Client ID + Client Secret) en Configuraciones → Xray. Después, al finalizar una prueba puedes exportar el resultado con pasos, estados y evidencias directamente a Xray."},{question:"¿Los resultados de Xray incluyen screenshots?",answer:"Sí. Cada paso del test execution incluye la evidencia en base64 (capturas de pantalla) y el estado individual de cada paso."},{question:"¿Qué proveedores de IA soporta?",answer:"Google Gemini (recomendado, económico), OpenAI (GPT-4o, GPT-4), Anthropic Claude y Ollama (local, sin internet). Se configura el proveedor y API key en Configuraciones → IA."},{question:"¿Qué puede hacer la IA en HakaBuddy?",answer:"Genera descripciones de pasos a partir de capturas, analiza fallos y sugiere causas raíz, optimiza scripts de Playwright (mejora selectores, agrega esperas), y genera análisis de resultados de ejecución en reportes HTML."},{question:"¿Puedo usar Ollama (IA local) sin internet?",answer:"Sí. Configura Ollama como proveedor e indica el modelo (ej: llama3.1). La IA corre en tu máquina sin enviar datos a internet. Ideal para ambientes con restricciones de red."},{question:"¿La IA ve mis datos sensibles?",answer:"Solo si usas IA en la nube (Gemini/OpenAI/Claude). 
17630Con Ollama todo es local. Para los proveedores cloud, se envía solo el contexto necesario (descripción del paso o script) directamente al proveedor, sin pasar por servidores de HakaLab."},{question:"¿Qué son Productos, Células y Ambientes?",answer:'Son entidades organizativas. Producto: la aplicación bajo prueba (ej: "Portal Web"). Célula: el equipo (ej: "Squad Checkout"). Ambiente: dónde pruebas (ej: "QA", "Staging", "Producción"). Se configuran una vez y se seleccionan al crear pruebas.'},{question:"¿Puedo ver el historial de pruebas?",answer:'Sí. La pestaña "Histórico" muestra todas las pruebas ejecutadas con filtros por fecha, producto y estado. Puedes abrir cualquier prueba anterior y ver sus pasos, evidencias y reportes.'},{question:"¿Puedo ver el historial de ejecuciones de suites?",answer:"Sí. Cada suite tiene un registro de ejecuciones con fecha, duración, cantidad de scripts y resultado global. Puedes ver el detalle de cada ejecución pasada."},{question:"El grabador de Playwright no se abre",answer:"Verifica que los navegadores de Playwright estén instalados. Si es la primera vez, HakaBuddy los descarga automáticamente (~200MB). Asegúrate de tener espacio en disco y conexión a internet para la descarga inicial."},{question:"La captura de pantalla sale negra o vacía",answer:"En Linux con Wayland puede ocurrir. Intenta ejecutar con XWayland o configura la variable de entorno XDG_SESSION_TYPE=x11. En macOS, otorga permiso de grabación de pantalla en Preferencias del Sistema → Privacidad."},{question:"La grabación de video no funciona",answer:"En macOS/Linux necesitas ffmpeg instalado (brew install ffmpeg o apt install ffmpeg). En Windows funciona sin dependencias adicionales. Verifica que no haya otro software usando la cámara/pantalla."},{question:"Error de licencia al iniciar",answer:'Si ves "Licencia no válida": verifica que el email y la clave son correctos. Si ves "En uso en otro dispositivo": cierra sesión en el otro equipo primero. Si no tienes acceso, contacta soporte.'},{question:"El push a Git falla",answer:"Verifica: 1) El token tiene permisos de escritura (repo scope en GitHub, Developer role en GitLab), 2) El repositorio existe y tienes acceso, 3) La rama no tiene protecciones que bloqueen push directo."},{question:"No puedo conectar con Jira",answer:'Verifica: 1) La URL base es correcta (sin "/" al final), 2) El email es el de tu cuenta Atlassian, 3) El API Token es válido y vigente (genera uno nuevo en https://id.atlassian.com/manage-profile/security/api-tokens).'},{question:"¿Puedo usar HakaBuddy detrás de un proxy corporativo?",answer:"Sí. Configura las variables de entorno HTTP_PROXY/HTTPS_PROXY del sistema antes de abrir HakaBuddy. La aplicación las respeta para todas las conexiones de red."},{question:"¿Cómo actualizo HakaBuddy?",answer:"Descarga el nuevo ejecutable y reemplaza el anterior. Tus datos se conservan (están en una carpeta aparte). No necesitas de
17630sinstalar la versión anterior."},{question:"¿Puedo tener varias versiones instaladas?",answer:"Sí. Como es un ejecutable portable, puedes tener varias versiones en carpetas diferentes. Todas comparten la misma carpeta de datos, así que tus pruebas son accesibles desde cualquier versión."}],Zne=[{question:"¿Qué es HakaPath?",answer:"Es una extensión de Chrome/Edge que genera localizadores XPath y CSS con inteligencia artificial para automatización de pruebas. Con un clic derecho sobre cualquier elemento web, genera múltiples selectores listos para usar en Selenium, Playwright, Cypress o Appium."},{question:"¿A quién está dirigido?",answer:"A QA Automation Engineers, SDETs y cualquier persona que necesite obtener selectores robustos para tests automatizados. No requiere experiencia avanzada en XPath/CSS porque la extensión genera los selectores automáticamente."},{question:"¿Con qué frameworks de testing es compatible?",answer:"Selenium (Python, Java, JavaScript, C#), Playwright (Python, Java, JavaScript, C#), Cypress (JavaScript) y Appium (Python, Java). La exportación genera código específico para cada combinación framework + lenguaje."},{question:"¿Cómo instalo HakaPath?",answer:'Desde la Chrome Web Store, busca "HakaPath" e instálalo. También funciona en Edge (basado en Chromium). Para modo desarrollador: chrome://extensions → Developer mode → Load unpacked → selecciona la carpeta del proyecto.'},{question:"¿Qué navegador necesito?",answer:"Chrome 88+ o Edge 88+ (cualquier navegador Chromium con soporte Manifest V3). Para Chrome Built-in AI necesitas Chrome 127+ con los flags de IA habilitados."},{question:"¿Necesito instalar algo más?",answer:"No. La extensión funciona de forma autónoma. Solo necesitas una API key si quieres usar IA cloud (OpenAI, Claude o Gemini). Chrome Built-in AI (versión Free) funciona sin API key."},{question:"¿Cuál es la diferencia entre Free y Pro?",answer:"Free: 1 slot XPath + 1 slot CSS (locales) + Chrome Built-in AI + Selenium y Playwright + exportación POM + historial + tema oscuro. Pro: 3 slots XPath + 3 slots CSS (incluye IA cloud) + 4 frameworks + indicador de robustez + detección de volatilidad + todos los proveedores de IA."},{question:"¿Cómo me registro?",answer:"Al abrir HakaPath por primera vez: 1) Elige idioma (Español/English), 2) Selecciona Free (registro con nombre, email, empresa) o Pro (login con credenciales, Google o Microsoft). Los clientes Haka Lab tienen Pro gratis con su cuenta corporativa."},{question:"¿Los clientes de Haka Lab pagan por Pro?",answer:"No. Los clientes de Haka Lab tienen acceso Pro sin costo usando su cuenta Google o Microsoft corporativa para iniciar sesión."},{question:"¿Cómo capturo un elemento?",answer:'Clic derecho sobre cualquier elemento de la página → "Obtener HakaPath". Se abre el panel con los localizadores generados automáticamente en la pestaña Localizadores.'},{question:'¿Qué son los "slots" de localizadores?',answer:"Cada captura genera múltiples opciones: Slots 1-2 (XPath local), Slot 3 (XPath con IA), Slots 4-5 (CSS local), Slot 6 (CSS con IA). Puedes elegir el que mejor se adapte a tu caso. En Free solo tienes 1 XPath + 1 CSS."},{question:"¿Qué significa el badge con número que aparece junto a cada localizador?",answer:'Es el conteo de coincidencias: cuántos elementos del DOM actual coinciden con ese selector. Lo ideal es "1" (selector único). Si muestra "0" el selector está roto; si muestra ">1" podría seleccionar el elemento equivocado.'},{question:"¿Cómo copio un localizador?",answer:'Haz clic en el localizador o en el botón de copiar. Se copia al portapapeles listo para pegar en tu código. El botón </> lo convierte a formato WebElement del framework configurado (ej: driver.find_element(By.XPATH, "...")).'},{question:"¿Qué es la conversión a WebElement?",answer:`El botón </> transforma el selector puro en una línea de código completa para tu framework. Ejemplo: "//button[@id='login']" → driver.find_element(By.XPATH, "//button[@id='login']") en Selenium Python.`},{question:"¿Qué estrategias de XPath genera?",answer:"Más de 13: por ID, atributos únicos (data-testid, aria-label, name), combinación de atributos, padre+hijo, texto (exacto y contains), siblings, posición, clase específica, jerarquía con índices, ancestor+descendant, y combinaciones con OR."},{question:"¿Qué estrategias de CSS genera?",answer:'ID (#id), clase (tag.class), atributos (tag[attr="value"]), combinadores (parent > child), pseudo-clases (:nth-child), atributos múltiples, y selectores compuestos con especificidad creciente.'},{question:"¿Qué son los Localizadores Relativos?",answer:"Ubican un elemento por su posición respecto a otro: Above (arriba de), Below (debajo de), Near (cerca de), ToLeftOf (a la izquierda de), ToRightOf (a la derecha de). Útiles cuando el elemento no tiene atributos únicos pero está junto a uno que sí."},{question:"¿Qué son los Localizadores Semánticos?",answer:"Usan la semántica del HTML: By Role (getByRole), By Text (getByText), By Label (getByLabel), By Placeholder (getByPlaceholder), By TestId (getByTestId), By Alt/Title. Son los más robustos y recomendados por Playwright y Testing Library."},{question:"¿Los semánticos funcionan en todos los frameworks?",answer:"Nativamente en Playwright y Cypress (con Testing Library). Para Selenium/Appium se genera un comentario indicando el equivalente, ya que no tienen API nativa de localizadores semánticos."},{question:"¿Cómo funciona la generación con IA?",answer:"Al capturar un elemento, los slots de IA (3 y 6) envían la información del elemento (tag, atributos, texto, padre, hermanos, outerHTML truncado) al proveedor configurado. La IA genera selectores optimizados que se validan contra el DOM real."},{question:"¿Qué proveedores de IA soporta?",answer:"Chrome Built-in AI (Gemini Nano, local, gratis, sin API key), OpenAI (GPT-4o Mini/4o/4.1), Claude (Sonnet 4/Haiku/Opus 4), Google Gemini (2.0 Flash/2.5 Flash
17630/2.5 Pro/3.1 Flash Lite). Free solo tiene Chrome Built-in AI."},{question:"¿Chrome Built-in AI funciona sin internet?",answer:"Sí. Gemini Nano se ejecuta localmente en tu computador, sin enviar datos a ningún servidor. Requiere Chrome 127+ con flags de IA habilitados y una descarga inicial del modelo (~5GB)."},{question:"¿Qué datos se envían a la IA?",answer:"Solo metadatos del elemento: tag, id, clases, texto, atributos y contexto de hermanos/padre. Nunca se envía la página completa. Con Chrome Built-in AI no sale nada de tu equipo."},{question:"¿Qué pasa si la IA no está disponible?",answer:"Los slots 3 y 6 se muestran como no disponibles, pero los slots locales (1, 2, 4, 5) funcionan normalmente sin IA. La extensión es completamente funcional sin conexión a IA."},{question:"¿Qué es el indicador de robustez?",answer:"Un puntaje de 0 a 100 que evalúa qué tan confiable es cada localizador. Verde (70-100): robusto, usa atributos estables. Amarillo (40-69): moderado, tiene riesgos. Rojo (0-39): frágil, depende de elementos que pueden cambiar."},{question:"¿Qué penaliza la robustez?",answer:"Clases CSS dinámicas (react-, css-, hashes), índices posicionales ([1], [position()=]), IDs autogenerados (GUIDs, :r0:), rutas absolutas (/html/body/...), profundidad excesiva (>5 niveles), y atributos volátiles detectados."},{question:"¿Qué bonifica la robustez?",answer:"data-testid, data-qa, aria-label, aria-describedby, atributo name, atributo role, IDs estables (cortos, semánticos), rutas cortas (<3 niveles), y coincidencia por texto."},{question:"¿Qué es la detección de volatilidad?",answer:"Un observador DOM (MutationObserver) que analiza el elemento durante 10 segundos después de capturarlo. Si detecta que atributos cambian (clases dinámicas, IDs que mutan), te avisa con una alerta y sugiere localizadores alternativos que evitan esos atributos."},{question:"¿Qué es el generador POM?",answer:"Genera automáticamente un archivo Page Object Model con los localizadores que has capturado. Soporta Python (.py), Java (.java), JavaScript (.js) y C# (.cs) con imports y estructura correcta para cada lenguaje."},{question:"¿Cómo exporto los localizadores?",answer:"En la pestaña POM/Exportar, selecciona el framework y lenguaje. Puedes copiar el código generado o descargarlo como archivo. El histórico también se puede exportar completo."},{question:"¿Puedo exportar el historial completo?",answer:"Sí. El historial guarda hasta 30 localizadores capturados y se puede exportar en formato POM (código) o como lista plana. Configura el máximo en Configuración → Máx. histórico."},{question:"¿Qué es el Auto-Heal?",answer:'Cada elemento capturado genera un "fingerprint" (huella digital: tag, atributos, texto, posición, ancestros). Si un localizador falla en el futuro, se buscan elementos similares por la huella y se sugieren candidatos de reemplazo usando similitud ponderada.'},{question:"¿Cómo funciona la similitud para auto-heal?",answer:"Se compara el fingerprint original con todos los elementos actuales usando pesos: Tag (15%), Atributos (30%), Texto (25%), Posición (10%), Ancestros (20%). Los candidatos con mayor similitud se sugieren como reemplazo."},{question:"¿Qué puedo configurar?",answer:"Framework (Selenium/Playwright/Cypress/Appium), lenguaje (Python/Java/JS/C#), idioma (Español/English), máximo de historial (1-30), proveedor de IA (Deshabilitado/Chrome AI/OpenAI/Claude/Gemini), y tema (Oscuro/Claro)."},{question:"¿Puedo cambiar el tema a claro?",answer:"Sí. En Configuración hay un toggle para cambiar entre tema oscuro (predeterminado, paleta azul marino) y tema claro. Se guarda en tus preferencias."},{question:"¿Dónde se guardan mis API keys?",answer:"En chrome.storage.local (almacenamiento local del navegador, cifrado por Chrome). Nunca se envían a servidores de HakaLab ni a terceros; solo se usan para comunicarse con el proveedor de IA que configuraste."},{question:'No aparece "Obtener HakaPath" en el menú contextual',answer:"Verifica que la extensión esté activa en chrome://extensions. En algunas páginas protegidas (chrome://, about:, archivos locales) las extensiones no tienen acceso. Recarga la página e intenta de nuevo."},{question:'El slot de IA muestra "No disponible"',answer:"Si usas Chrome Built-in AI: verifica Chrome 127+ y que los flags de IA estén habilitados (chrome://flags → Prompt API for Gemini Nano). Si usas IA cloud: verifica que la API key sea válida en Configuración."},{question:'Un localizador muestra "0" coincidencias',answer:"El selector no encuentra el elemento en el DOM actual. Puede que: 1) El elemento esté dentro de un iframe (HakaPath opera en el contexto principal), 2) El elemento se cargó dinámicamente después de la captura, 3) El DOM cambió (navegaste a otra página)."},{question:"¿Funciona dentro de iframes?",answer:"HakaPath captura el elemento en el contexto principal de la página. Para elementos dentro de iframes, primero 
17630necesitas navegar al iframe (click derecho dentro del iframe). El conteo de coincidencias se evalúa en el frame activo."},{question:"¿Funciona con Shadow DOM?",answer:"Parcialmente. Los elementos dentro de Shadow DOM abierto son accesibles, pero los selectores generados pueden necesitar ajuste manual para incluir el host del shadow root. En Shadow DOM cerrado la captura no es posible."},{question:"¿Funciona en SPAs (React, Angular, Vue)?",answer:"Sí. Los selectores se generan y validan contra el DOM actual. La detección de volatilidad es especialmente útil aquí porque detecta clases CSS dinámicas que estos frameworks generan (css-hash, ng-*, _ngcontent-*)."},{question:"¿Cómo sé qué localizador elegir entre los slots?",answer:'Usa el indicador de robustez (Pro) como guía: elige el verde. En Free, prefiere los que tengan badge "1" (exactamente una coincidencia) y que usen atributos semánticos (data-testid, aria-label, name) sobre clases o posiciones.'},{question:"¿Puedo usar HakaPath sin conexión?",answer:"Para los localizadores locales (slots 1,2,4,5) no necesitas conexión. Chrome Built-in AI tampoco requiere internet (después de la descarga inicial del modelo). Solo la verificación de cuenta y los proveedores cloud necesitan conexión."}];function eie(){return s.jsx(Wu,{productName:"Haka Automation Engine",productKey:"Engine Playwright",logo:"/imagenes/docs-logos/Automation Engine.png",logoHeight:"h-8",hubPath:"/docs/haka-playwright-engine",faqs:Jne})}function tie(){return s.jsx(Wu,{productName:"Haka AI Studio",productKey:"Haka AI Studio",logo:"/imagenes/docs-logos/AI Studio.png",logoHeight:"h-8",hubPath:"/docs/haka-ai-studio",faqs:Qne})}function aie(){return s.jsx(Wu,{productName:"HakaBoost",productKey:"HakaBoost",logo:"/imagenes/docs-logos/HakaBoost.png",logoHeight:"h-6",hubPath:"/docs/hakaboost",faqs:Xne})}function nie(){return s.jsx(Wu,{productName:"HakaBuddy",productKey:"Hakabuddy",logo:"/imagenes/docs-logos/HakaBuddy.png",logoHeight:"h-8",hubPath:"/docs/hakabuddy",faqs:Yne})}function iie(){return s.jsx(Wu,{productName:"HakaPath",productKey:"HakaPath",logo:"/imagenes/docs-logos/HakaPath.png",logoHeight:"h-8",hubPath:"/docs/hakapath",faqs:Zne})}const bj=["Planificación","Diseño","Desarrollo","Testing","Deploy","Review","Launch"],bn=[{id:0,label:"Análisis",fullName:"Análisis, precondiciones y riesgos",description:"Análisis detallado de requerimientos, identificación de riesgos y establecimiento de precondiciones para garantizar la calidad desde el inicio.",color:"#1e3a8a",logo:"/imagenes/productos/hakaboost_logo.png"},{id:1,label:"Diseño pruebas",fullName:"Diseño de pruebas",description:"Diseño detallado del plan de pruebas con estrategias, casos de prueba y criterios de aceptación.",color:"#1e40af",logo:"/imagenes/productos/hakaboost_logo.png"},{id:2,label:"Construcción",fullName:"Construcción de pruebas",description:"Construcción y desarrollo de pruebas automatizadas y manuales según el plan definido.",color:"#2563eb",logos:["/imagenes/productos/hakartc_logo.png","/imagenes/productos/hakabuddy_logo.png","/imagenes/productos/hakapath_logo.png"]},{id:3,label:"Ejecución",fullName:"Ejecución de pruebas",description:"Ejecución de pruebas en diferentes ambientes y escenarios para validar la calidad del software.",color:"#3b82f6",logo:"/imagenes/productos/hakabuddy_logo.png"},{id:4,label:"CI/CD",fullName:"Testing en CI/CD",description:"Integración de pruebas en el pipeline de CI/CD para validación continua y automatizada.",color:"#1d4ed8"}
17630,{id:5,label:"Resultados",fullName:"Resultados de calidad",description:"Análisis de resultados, generación de reportes y toma de decisiones basada en métricas de calidad.",color:"#0369a1"},{id:6,label:"Métricas",fullName:"Métricas productivas",description:"Medición y análisis de indicadores clave de productividad y eficiencia del proceso de testing para mejora continua.",color:"#0284c7"}],rie=[0,260,500,640,980,1130,1480];function oie(){const[t,e]=k.useState(0),[a,n]=k.useState(!0);k.useEffect(()=>{if(!a)return;const r=setInterval(()=>e(o=>(o+1)%bn.length),4e3);return()=>clearInterval(r)},[a]);const i=r=>{n(!1),e(r),setTimeout(()=>n(!0),8e3)};return s.jsxs("div",{className:"relative w-full max-w-7xl mx-auto py-16",children:[s.jsxs("div",{className:"mb-12 text-center",children:[s.jsx("h2",{className:"text-3xl font-bold text-white mb-3",children:"Ruta de Calidad Continua"}),s.jsx("p",{className:"text-gray-400",children:"Seguimiento paso a paso del proceso de QA"})]}),s.jsx("div",{className:"relative",children:s.jsxs("svg",{className:"w-full h-auto",viewBox:"0 0 1400 550",preserveAspectRatio:"xMidYMid meet",children:[s.jsx("path",{d:"M 80 280 Q 150 280 200 230 Q 250 180 300 180 Q 350 180 400 230 Q 450 280 500 330 Q 550 380 650 380 Q 750 380 800 330 Q 850 280 900 230 Q 950 180 1050 180 Q 1150 180 1200 230 Q 1250 280 1320 280",fill:"none",stroke:"rgba(148,163,184,0.2)",strokeWidth:"40",strokeLinecap:"round"}),s.jsx(_.path,{d:"M 80 280 Q 150 280 200 230 Q 250 180 300 180 Q 350 180 400 230 Q 450 280 500 330 Q 550 380 650 380 Q 750 380 800 330 Q 850 280 900 230 Q 950 180 1050 180 Q 1150 180 1200 230 Q 1250 280 1320 280",fill:"none",stroke:"url(#pathGradient)",strokeWidth:"40",strokeLinecap:"round",strokeDasharray:"1780",strokeDashoffset:1780-rie[t],style:{transition:"stroke-dashoffset 1s ease-in-out"}}),s.jsx("defs",{children:s.jsxs("linearGradient",{id:"pathGradient",x1:"0%",y1:"0%",x2:"100%",y2:"0%",children:[s.jsx("stop",{offset:"0%",stopColor:"#06b6d4",stopOpacity:"0.8"}),s.jsx("stop",{offset:"100%",stopColor:"#3b82f6",stopOpacity:"0.8"})]})}),s.jsx("text",{x:"700",y:"30",textAnchor:"middle",fill:"#94a3b8",fontSize:"18",fontWeight:"600",className:"pointer-events-none",children:"Ciclo de desarrollo de Testing"}),bn.map((r,o)=>{const c=[{x:80,y:280},{x:300,y:180},{x:500,y:330},{x:650,y:380},{x:900,y:230},{x:1050,y:180},{x:1320,y:280}][o],d=o===t;return s.jsx("line",{x1:c.x,y1:c.y-28,x2:c.x,y2:80+20,stroke:d?"#06b6d4":"rgba(148,163,184,0.3)",strokeWidth:d?2:1,strokeDasharray:d?"0":"4 4",className:"transition-all duration-300"},`line-qa-${o}`)}),bn.map((r,o)=>{const c=[{x:80,y:280},{x:300,y:180},{x:500,y:330},{x:650,y:380},{x:900,y:230},{x:1050,y:180},{x:1320,y:280}][o],d=o===t;return s.jsx("g",{children:s.jsx("foreignObject",{x:c.x-75,y:80-20,width:"150",height:"40",children:s.jsx("div",{className:"flex justify-center",children:s.jsx("div",{className:`px-5 py-2 rounded-full text-sm font-medium transition-all duration-300 whitespace-nowrap ${d?"bg-cyan-500/20 border-2 border-cyan-400 text-cyan-300":"bg-slate-800/60 border border-slate-600 text-slate-300"}`,children:r.label})})})},`qa-${o}`)}),bj.map((r,o)=>{const c=[{x:80,y:280},{x:300,y:180},{x:500,y:330},{x:650,y:380},{x:900,y:230},{x:1050,y:180},{x:1320,y:280}][o],d=o===t;return s.jsx("g",{children:s.jsx("foreignObject",{x:c.x-55,y:480-20,width:"110",height:"40",children:s.jsx("div",{className:"flex justify-center",children:s.jsx("div",{className:`px-3 py-1.5 rounded-full text-xs font-medium transition-all duration-300 whitespace-nowrap ${d?"bg-blue-500/30 border border-blue-400 text-blue-200":"bg-slate-800/40 border border-slate-700 text-slate-400"}`,children:r})})})},`dev-${o}`)}),bj.map((r,o)=>{const c=[{x:80,y:280},{x:300,y:180},{x:500,y:330},{x:650,y:380},{x:900,y:230},{x:1050,y:180},{x:1320,y:280}][o],d=o===t;return s.jsx("line",{x1:c.x,y1:c.y+28,x2:c.x,y2:480-20,stroke:d?"#3b82f6":"rgba(148,163,184,0.3)",strokeWidth:d?2:1,strokeDasharray:d?"0":"4 4",className:"transition-all duration-300"},`line-dev-${o}`)}),s.jsx("text",{x:"700",y:"520",textAnchor:"middle",fill:"#94a3b8",fontSize:"18",fontWeight:"600",className:"pointer-events-none",children:"Ciclo de Desarrollo"}),bn.map((r,o)=>{const c=[{x:80,y:280},{x:300,y:180},{x:500,y:330},{x:650,y:380},{x:900,y:230},{x:1050,y:180},{x:1320,y:280}][o],d=o===t,u=o<t;return s.jsxs("g",{children:[d&&s.jsxs("circle",{cx:c.x,cy:c.y,r:"35",fill:"none",stroke:"#06b6d4",strokeWidth:"3",opacity:"0.6",children:[s.jsx("animate",{attributeName:"r",from:"35",to:"45",dur:"1.5s",repeatCount:"indef
17630inite"}),s.jsx("animate",{attributeName:"opacity",from:"0.6",to:"0",dur:"1.5s",repeatCount:"indefinite"})]}),s.jsx("circle",{cx:c.x,cy:c.y,r:"28",fill:d?"#06b6d4":u?r.color:"#1e293b",stroke:d?"#22d3ee":u?"#3b82f6":"#334155",strokeWidth:d?3:2,className:"cursor-pointer transition-all duration-300",onClick:()=>i(o),style:{filter:d?"drop-shadow(0 0 12px #06b6d4)":"none"}}),s.jsx("text",{x:c.x,y:c.y+5,textAnchor:"middle",fill:"white",fontSize:"16",fontWeight:"bold",className:"pointer-events-none",children:String(o+1).padStart(2,"0")})]},r.id)})]})}),s.jsx(_.div,{initial:{opacity:0,y:20},animate:{opacity:1,y:0},transition:{duration:.4},className:"mt-12 bg-white/5 backdrop-blur rounded-2xl p-8 border border-cyan-400/40",children:s.jsxs("div",{className:"flex items-start gap-6",children:[s.jsx("div",{className:"bg-gradient-to-br from-cyan-400 to-blue-600 text-white font-bold text-xl w-14 h-14 rounded-full flex items-center justify-center flex-shrink-0",children:String(t+1).padStart(2,"0")}),s.jsxs("div",{className:"flex-1",children:[s.jsx("h3",{className:"text-2xl font-bold text-white mb-3",children:bn[t].fullName}),s.jsx("p",{className:"text-gray-300 leading-relaxed",children:bn[t].description}),bn[t].logo&&s.jsx("div",{className:"flex justify-center mt-6 pt-6 border-t border-white/10",children:s.jsx("img",{src:bn[t].logo,alt:"Product logo",className:"h-8 opacity-70"})}),bn[t].logos&&s.jsx("div",{className:"flex justify-center items-center gap-6 mt-6 pt-6 border-t border-white/10",children:bn[t].logos.map((r,o)=>s.jsx("img",{src:r,alt:"Product logo",className:"h-7 opacity-70"},o))})]})]})},t),s.jsx("div",{className:"flex justify-center gap-2 mt-8",children:bn.map(r=>s.jsx("button",{onClick:()=>i(r.id),className:`h-2 rounded-full transition-all duration-300 ${t===r.id?"bg-cyan-400 w-8":"bg-gray-600 hover:bg-gray-400 w-3"}`},r.id))})]})}function sie(){return s.jsx("div",{className:"min-h-screen bg-[#0a0e27] py-20",children:s.jsxs("div",{className:"max-w-7xl mx-auto px-4 sm:px-6 md:px-8",children:[s.jsxs(_.div,{initial:{opacity:0,y:20},animate:{opacity:1,y:0},transition:{duration:.6},className:"text-center mb-12",children:[s.jsx("h1",{className:"text-4xl sm:text-5xl font-bold text-primary mb-4",children:"Calidad en Todo El Ciclo de Desarrollo"}),s.jsx("p",{className:"text-gray-300 text-lg",children:"Ciclo de Desarrollo y Quality Assurance"})]}),s.jsx(Og,{}),s.jsx("div",{className:"my-20 border-t border-white/10"}),s.jsx(oie,{})]})})}function lie(){const{t}=$();return k.useEffect(()=>{document.title="Términos y Condiciones | Haka Lab"},[]),s.jsx("div",{className:"bg-dark min-h-screen",children:s.jsxs("div",{className:"max-w-4xl mx-auto px-4 py-16 sm:px-6 lg:px-8",children:[s.jsxs("div",{className:"text-center mb-12",children:[s.jsx("h1",{className:"text-4xl md:text-5xl font-bold text-white mb-4",children:t("terminos.titulo")}),s.jsxs("p",{className:"text-gray-400 text-lg",children:[t("terminos.ultimaActualizacion"),": 15 julio 2025"]})]}),s.jsxs("div",{className:"prose prose-invert prose-lg max-w-none",children:[s.jsx("div",{className:"mb-12 text-gray-300 leading-relaxed",children:s.jsx("p",{children:'Estos Términos y Condiciones de Uso (en adelante, los "Términos") regulan la relación entre Haka Lab SpA, empresa legalmente constituida con domicilio en Guardia Vieja #181, Providencia, Santiago, Chile (en adelante, "Haka Lab", "nosotros" o "nuestro(s)"), y el Usuario (en adelante, "usted" o "tu"), en relación con el uso de los productos y servicios digitales de Haka Lab.'})}),s.jsxs("section",{className:"mb-10",children:[s.jsxs("h2",{className:"text-2xl font-bold text-white mb-4",children:["1. ",t("terminos.definiciones.titulo")]}),s.jsxs("div",{className:"space-y-4 text-gray-300",children:[s.jsxs("div",{children:[s.jsx("p",{className:"font-semibold text-primary mb-2",children:'"Servicios":'}),s.jsx("p",{children:"se refiere a todos los productos, plataformas, aplicaciones, sitios web y herramientas desarrollados y ofrecidos por Haka Lab, incluyendo pero no limitados a HakaPath, HakaBuddy, HakaTools, así como cualquier producto futuro."})]}),s.jsxs("div",{children:[s.jsx("p",{className:"font-semibold text-primary mb-2",children:'"Usuario" o "usted":'}),s.jsx("p",{children:"cualquier persona natural o jurídica que acceda, utilice o interactúe con los Servicios."}),s.jsx("p",{className:"mt-2 italic",children:"Si accede en representación de una entidad (por ejemplo, su empleador), declara contar con la facultad legal para vincular a dicha entidad con estos Términos."})]})]})]}),s.jsxs("section",{className:"mb-10",children:[s.jsxs("h2",{className:"text-2xl font-bold text-white mb-4",children:["2. ",t("terminos.aceptacion.titulo")]}),s.jsx("p",{className:"text-gray-300",children:"Al utilizar nuestros Servicios, usted acepta expresamente estos Términos. Si no está de acuerdo con ellos, debe abstenerse de utilizar nuestros productos."})]}),s.jsxs("section",{className:"mb-10",children:[s.jsxs("h2",{className:"text-2xl font-bold text-white mb-4",children:["3. ",t("terminos.licencia.titulo")]}),s.jsx("p",{className:"text-gray-300",children:"Haka Lab otorga al Usuario una licencia limitada, no exclusiva, intransferible y revocable para utilizar los Servicios con fines personales o empresariales legítimos, conforme a la ley y a estos Términos."})]}),s.jsxs("section",{className:"mb-10",children:[s.jsxs("h2",{className:"text-2xl font-bold text-white mb-4",children:["4. ",t("terminos.restricciones.titulo")]}),s.jsx("p",{className:"text-gray-300 mb-3",children:"El Usuario se compromete a no:"}),s.jsxs("ul",{className:"list-disc list-inside space-y-2 text-gray-300 ml-4",children:[s.jsx("li",{children:"Copiar, modificar, descompilar o aplicar ingeniería inversa a los Servicios."}),s.jsx("li",{children:"Vender, sublicenciar o distribuir nuestros productos sin autorización escrita de Haka Lab."}),s.jsx("li",{children:"Usar los Servicios para fines ilícitos o contrarios a la moral y buenas costumbres."}),s.jsx("li",{children:"Infringir derechos de propiedad intelectual de Haka Lab o de terceros."})]})]}),s.jsxs("section",{className:"mb-10",children:[s.jsxs("h2",{className:"text-2xl font-bold text-white mb-4",children:["5. ",t("terminos.actualizaciones.titulo")]}),s.jsx("p",{className:"text-gray-300",children:"Haka Lab podrá actualizar, mejorar o discontinuar cualquier parte de los Servicios sin previo aviso. Algunas actualizaciones pueden ser obligatorias para seguir utilizando los productos."})]}),s.jsxs("section",{className:"mb-10",children:[s.jsxs("h2",{className:"text-2xl font-bold text-white mb-4",children:["6. ",t("terminos.privacidad.titulo")]}),s.jsxs("p",{className:"text-gray-300",children:["El uso de los Servicios está sujeto a nuestra Política de Privacidad. Al utilizar nuestros productos, usted consiente el tratamiento de sus datos personales conforme a dicha política. Puede consultarla en el siguiente enlace: ",s.jsx("a",{href:"/politica-privacidad",className:"text-primary hover:underline font-semibold",children:"Política de Privacidad"}),"."]})]}),s.jsxs("section",{className:"mb-10",children:[s.jsxs("h2",{className:"text-2xl font-bold text-white mb-4",children:["7. ",t("terminos.limitacion.titulo")]}),s.jsx("p",{className:"text-gray-300",children:"En la medida máxima permitida por la ley, Haka Lab no será responsable por daños directos, indirectos, incidentales o consecuentes derivados del uso de nuestros Servicios. El uso se realiza bajo su propio riesgo."})]}),s.jsxs("section",{className:"mb-10",children:[s.jsxs("h2",{className:"text-2xl font-bold text-white mb-4",children:["8. ",t("terminos.terminacion.titulo")]}),s.jsx("p",{className:"text-gray-300",children:"Podremos suspender o cancelar el acceso a los Servicios si usted incumple estos Términos. En tal caso, usted deberá dejar de utilizarlos inmediatamente."})]}),s.jsxs("section",{className:"mb-10",children:[s.jsxs("h2",{className:"text-2xl font-bold text-white mb-4",children:["9. ",t("terminos.legislacion.titulo")]}),s.jsx("p",{className:"text-gray-300",children:"Estos Términos se rigen por las leyes de la República de Chile. Toda controversia será sometida a los tribunales ordinarios de justicia de Santiago, Chile."})]}),s.jsxs("section",{className:"mb-16",children:[s.jsxs("h2",{className:"text-2xl font-bold text-white mb-4",children:["10. ",t("terminos.modificaciones.titulo")]}),s.jsx("p",{className:"text-gray-300",children:"Nos reservamos el derecho de modificar estos Términos en cualquier momento. Los cambios serán publicados en nuestro sitio web y entrarán en vigor desde su publicación. Se podrá notificar a los usuarios por medios razonables (como avisos en la app o vía email)."})]}),s.jsx("div",{className:"border-t border-gray-700 pt-12 mt-12",children:s.jsxs("div",{className:"bg-slate-800/60 border border-cyan-400/30 rounded-xl p-8 text-center",children:[s.jsx("h2",{className:"text-2xl md:text-3xl font-bold text-white mb-4",children:"Política de Privacidad"}),s.jsx("p",{className:"text-gray-300 mb-6 max-w-2xl mx-auto",children:"Para conocer en detalle cómo recopilamos, utilizamos, almacenamos y protegemos sus datos personales, consulte nuestra Política de Privacidad completa."}),s.jsx("a",{href:"/politica-privacidad",className:"inline-block bg-gradient-to-r from-cyan-500 to-blue-500 text-white font-semibold px-8 py-3 rounded-lg hover:from-cyan-400 hover:to-blue-400 transition-all shadow-lg hover:shadow-cyan-500/25",children:"Ver Política de Privacidad"})]})})]})]})})}function cie(){return k.useEffect(()=>{document.title="Política de Privacidad | Haka Lab"},[]),s.jsx("div",{className:"bg-dark min-h-screen",children:s.jsxs("div",{className:"max-w-4xl mx-auto px-4 py-16 sm:px-6 lg:px-8",children:[s.jsxs("div",{className:"text-center mb-12",children:[s.jsx("h1",{className:"text-4xl md:text-5xl font-bold text-white mb-4",children:"Política de Privacidad"}),s.jsx("p",{className:"text-gray-400 text-lg",children:"Última actualización: 13 de mayo de 2026 — Versión 1.0"})]}),s.jsxs("div",{className:"prose prose-invert prose-lg max-w-none",children:[s.jsxs("section",{className:"mb-10",children:[s.jsx("h2",{className:"text-2xl font-bold text-white mb-4",children:"1. Identificación del Responsable"}),s.jsxs("div",{className:"space-y-2 text-gray-300",children:[s.jsxs("p",{children:[s.jsx("span",{className:"font-semibold text-primary",children:"Responsable del tratamiento:"})," Hakalab SpA"]}),s.jsxs("p",{children:[s.jsx("span",{className:"font-semibold text-primary",children:"Correo de contacto:"})," ",s.jsx("a",{href:"mailto:[email protected]",className:"text-primary hover:underline",children:"[email protected]"})]}),s.jsxs("p",{children:[s.jsx("span",{className:"font-semibold text-primary",children:"Sitio web:"})," ",s.jsx("a",{href:"https://hakalab.com",className:"text-primary hover:underline",children:"https://hakalab.com"})]}),s.jsxs("p",{children:[s.jsx("span",{className:"font-semibold text-primary",children:"Productos:"}
vendor: 5,543 bytes, line 17630
17630)," HakaBoost, HakaBuddy, HakaPath, HakaRTC, Haka Insight, Haka AI Studio, Haka Engine Connector y demás productos desarrollados por Haka Lab"]})]})]}),s.jsxs("section",{className:"mb-10",children:[s.jsx("h2",{className:"text-2xl font-bold text-white mb-4",children:"2. Alcance"}),s.jsx("p",{className:"text-gray-300 mb-4",children:"Esta política de privacidad describe cómo Haka Lab recopila, utiliza, almacena y protege los datos personales de sus usuarios. Aplica a todas las personas que instalen y utilicen cualquiera de los productos de Haka Lab (HakaBoost, HakaBuddy, HakaPath, HakaRTC, Haka Insight, Haka AI Studio, Haka Engine Connector, entre otros), independientemente de su plan (Free o Pro)."}),s.jsx("p",{className:"text-gray-300 mb-3",children:"Esta política se rige por la legislación chilena vigente, en particular:"}),s.jsxs("ul",{className:"list-disc list-inside space-y-2 text-gray-300 ml-4",children:[s.jsx("li",{children:"Ley N° 21.719 sobre Protección de Datos Personales"}),s.jsx("li",{children:"Ley N° 21.663 — Ley Marco de Ciberseguridad"}),s.jsx("li",{children:"Constitución Política de la República de Chile, Art. 19 N° 4"})]})]}),s.jsxs("section",{className:"mb-10",children:[s.jsx("h2",{className:"text-2xl font-bold text-white mb-4",children:"3. Datos que recopilamos"}),s.jsx("h3",{className:"text-xl font-semibold text-white mb-3",children:"3.1 Datos proporcionados directamente por el usuario"}),s.jsx("div",{className:"overflow-x-auto mb-6",children:s.jsxs("table",{className:"w-full text-sm text-gray-300 border border-gray-700 rounded-lg",children:[s.jsx("thead",{className:"bg-slate-700/50",children:s.jsxs("tr",{children:[s.jsx("th",{className:"px-4 py-3 text-left text-primary font-semibold",children:"Dato"}),s.jsx("th",{className:"px-4 py-3 text-left text-primary font-semibold",children:"Finalidad"}),s.jsx("th",{className:"px-4 py-3 text-left text-primary font-semibold",children:"Plan"})]})}),s.jsxs("tbody",{className:"divide-y divide-gray-700",children:[s.jsxs("tr",{children:[s.jsx("td",{className:"px-4 py-2",children:"Nombre"}),s.jsx("td",{className:"px-4 py-2",children:"Identificación del usuario"}),s.jsx("td",{className:"px-4 py-2",children:"Free y Pro"})]}),s.jsxs("tr",{children:[s.jsx("td",{className:"px-4 py-2",children:"Correo electrónico"}),s.jsx("td",{className:"px-4 py-2",children:"Identificación, comunicación y validación de licencia"}),s.jsx("td",{className:"px-4 py-2",children:"Free y Pro"})]}),s.jsxs("tr",{children:[s.jsx("td",{className:"px-4 py-2",children:"Empresa"}),s.jsx("td",{className:"px-4 py-2",children:"Conocer el contexto organizacional del usuario"}),s.jsx("td",{className:"px-4 py-2",children:"Free"})]}),s.jsxs("tr",{children:[s.jsx("td",{className:"px-4 py-2",children:"Clave de licencia"}),s.jsx("td",{className:"px-4 py-2",children:"Validación del acceso Pro"}),s.jsx("td",{className:"px-4 py-2",children:"Pro"})]})]})]})}),s.jsx("h3",{className:"text-xl font-semibold text-white mb-3",children:"3.2 Datos generados automáticamente"}),s.jsx("div",{className:"overflow-x-auto mb-6",children:s.jsxs("table",{className:"w-full text-sm text-gray-300 border border-gray-700 rounded-lg",children:[s.jsx("thead",{className:"bg-slate-700/50",children:s.jsxs("tr",{children:[s.jsx("th",{className:"px-4 py-3 text-left text-primary font-semibold",children:"Dato"}),s.jsx("th",{className:"px-4 py-3 text-left text-primary font-semibold",children:"Finalidad"}),s.jsx("th",{className:"px-4 py-3 text-left text-primary font-semibold",children:"Almacenamiento"})]})}),s.jsxs("tbody",{className:"divide-y divide-gray-700",children:[s.jsxs("tr",{children:[s.jsx("td",{className:"px-4 py-2",children:"ID de instalación (UUID)"}),s.jsx("td",{className:"px-4 py-2",children:"Identificar el dispositivo para detección de sesiones concurrentes"}),s.jsx("td",{className:"px-4 py-2",children:"Local en el navegador"})]}),s.jsxs("tr",{children:[s.jsx("td",{className:"px-4 py-2",children:"Fecha del último chequeo de licencia"}),s.jsx("td",{className:"px-4 py-2",children:"Control de validación diaria"}),s.jsx("td",{className:"px-4 py-2",children:"Local en el navegador"})]}),s.jsxs("tr",{children:[s.jsx("td",{className:"px-4 py-2",children:"Preferencias de configuración (idioma, tema, modelo de IA)"}),s.jsx("td",{className:"px-4 py-2",children:"Personalización de la experiencia"}),s.jsx("td",{className:"px-4 py-2",children:"Local en el navegador"})]})]})]})}),s.jsx("h3",{className:"text-xl font-semibold text-white mb-3",children:"3.3 Datos que NO recopilamos"}),s.jsxs("ul",{className:"list-disc list-inside space-y-2 text-gray-300 ml-4 mb-6",children:[s.jsx("li",{children:"No recopilamos contraseñas de Jira, Azure DevOps ni de servicios de IA"}),s.jsx("li",{children:"No recopilamos el contenido de las tareas o work items del usuario"}),s.jsx("li",{children:"No recopilamos historial de navegación"}),s.jsx("li",{children:"No recopilamos datos biométricos"}),s.jsx("li",{children:"No utilizamos cookies ni tecnologías de rastreo"})]}),s.jsx("h3",{className:"text-xl font-semibold text-white mb-3",children:"3.4 Credenciales de terceros"}),s.jsx("p",{className:"text-gray-300 mb-3",children:"El usuario puede configurar voluntariamente credenciales de servicios externos (Jira, Azure DevOps, OpenAI, Google Gemini, Claude, Xray). Estas credenciales:"}),s.jsxs("ul",{className:"list-disc list-inside space-y-2 text-gray-300 ml-4",children:[s.jsx("li",{children:"Se almacenan exclusivamente en el navegador del usuario (chrome.storage)"}
17630),s.jsx("li",{children:"Nunca se envían a servidores de Hakalab"}),s.jsx("li",{children:"Se utilizan únicamente para conectar con los servicios que el usuario configuró"}),s.jsx("li",{children:"Se eliminan completamente al cerrar sesión"})]}),s.jsx("h3",{className:"text-xl font-semibold text-white mb-3 mt-6",children:"3.5 Actividad del usuario en Haka Engine Connector"}),s.jsxs("p",{className:"text-gray-300 mb-3",children:["Haka Engine Connector captura la actividad del usuario (clics, entradas de texto, selecciones y navegaciones) ",s.jsx("span",{className:"font-semibold",children:"exclusivamente mientras la grabación está activa"})," (activada manualmente por el usuario). Esta información:"]}),s.jsxs("ul",{className:"list-disc list-inside space-y-2 text-gray-300 ml-4 mb-4",children:[s.jsx("li",{children:"Se envía únicamente al servidor local del usuario (127.0.0.1/localhost), que corre en su propia máquina"}),s.jsx("li",{children:s.jsx("span",{className:"font-semibold",children:"Nunca se transmite a servidores externos ni a la nube"})}),s.jsx("li",{children:"Se procesa localmente para generar archivos de prueba automatizada (features y localizadores)"}),s.jsx("li",{children:"No se almacena de forma persistente — se descarta al finalizar la generación"}),s.jsx("li",{children:"No se captura ninguna actividad fuera del modo de grabación"})]}),s.jsx("p",{className:"text-gray-300",children:"Adicionalmente, Haka Engine Connector almacena preferencias del usuario (último proyecto y nombre de sesión) en chrome.storage.local, que se eliminan al desinstalar la extensión."})]}),s.jsxs("section",{className:"mb-10",children:[s.jsx("h2",{className:"text-2xl font-bold text-white mb-4",children:"4. Bases de licitud del tratamiento"}),s.jsx("p",{className:"text-gray-300 mb-4",children:"De acuerdo con la Ley N° 21.719, el tratamiento de datos personales en los productos de Haka Lab se fundamenta en las siguientes bases:"}),s.jsx("div",{className:"overflow-x-auto",children:s.jsxs("table",{className:"w-full text-sm text-gray-300 border border-gray-700 rounded-lg",children:[s.jsx("thead",{className:"bg-slate-700/50",children:s.jsxs("tr",{children:[s.jsx("th",{className:"px-4 py-3 text-left text-primary font-semibold",children:"Tratamiento"}),s.jsx("th",{className:"px-4 py-3 text-left text-primary font-semibold",children:"Base de licitud"})]})}),s.jsxs("tbody",{className:"divide-y divide-gray-700",children:[s.jsxs("tr",{children:[s.jsx("td",{className:"px-4 py-2",children:"Registro de cuenta (nombre, email, empresa)"}),s.jsx("td",{className:"px-4 py-2",children:"Consentimiento del titular"})]}),s.jsxs("tr",{children:[s.jsx("td",{className:"px-4 py-2",children:"Validación de licencia (email, clave, id_app)"}),s.jsx("td",{className:"px-4 py-2",children:"Ejecución del contrato de servicio"})]}),s.jsxs("tr",{children:[s.jsx("td",{className:"px-4 py-2",children:"Almacenamiento de preferencias"}),s.jsx("td",{className:"px-4 py-2",children:"Interés legítimo del responsable"})]}),s.jsxs("tr",{children:[s.jsx("td",{className:"px-4 py-2",children:"Detección de sesiones concurrentes"}),s.jsx("td",{className:"px-4 py-2",children:"Ejecución del contrato de servicio"})]}),s.jsxs("tr",{children:[s.jsx("td",{className:"px-4 py-2",children:"Envío de descripciones a servicios de IA"}),s.jsx("td",{className:"px-4 py-2",children:"Consentimiento del titular"})]})]})]})})]}),s.jsxs("section",{className:"mb-10",children:[s.jsx("h2",{className:"text-2xl font-bold text-white mb-4",children:"5. Finalidades del tratamiento"}),s.jsx("p",{className:"text-gray-300 mb-3",children:"Los datos personales se tratan exclusivamente para las siguientes finalidades:"}),s.jsxs("ol",{className:"list-decimal list-inside space-y-2 text-gray-300 ml-4 mb-4",children:[s.jsxs("li",{children:[s.jsx("span",{className:"font-semibold",children:"Prestación del servicio:"})," Permitir el funcionamiento de los productos de Haka Lab y sus funcionalidades"]}),s.jsxs("li",{children:[s.jsx("span",{className:"font-semibold",children:"Gestión de licencias:"})," Validar el acceso al plan Pro y detectar uso no autorizado"]}),s.jsxs("li",{children:[s.jsx("span",{className:"font-semibold",children:"Mejora del producto:"})," Conocer el perfil general de nuestros usuarios (sin análisis individual)"]}),s.jsxs("li",{children:[s.jsx("span",{className:"font-semibold",children:"Comunicación:"})," Contactar al usuario únicamente para asuntos relacionados con su cuenta o el servicio"]}),s.jsxs("li",{children:[s.jsx("span",{className:"font-semibold",children:"Seguridad:"})," Detectar y prevenir accesos no autorizados"]})]}),s.jsx("p",{className:"text-gray-300 mb-3",children:"Los datos personales NO se utilizan para:"}),s.jsxs("ul",{className:"list-disc list-inside space-y-2 text-gray-300 ml-4",children:[s.jsx("li",{children:"Publicidad personalizada"}),s.jsx("li",{children:"Venta a terceros"}),s.jsx("li",{children:"Elaboración de perfiles de comportamiento"}),s.jsx("li",{children:"Decisiones automatizadas que afecten al usuario"})]})]}),s.jsxs("section",{className:"mb-10",children:[s.jsx("h2",{className:"text-2xl font-bold text-white mb-4",children:"6. Transferencia internacional de datos"}),s.jsx("h3",{className:"text-xl font-semibold text-white mb-3",children:"6.1 Servicios de inteligencia artificial"}),s.jsx("p",{className:"text-gray-300 mb-3",children:"Cuando el usuario utiliza servicios de IA en la nube (OpenAI, Google Gemini o Claude), las de
17630scripciones de las tareas se envían a servidores ubicados fuera de Chile (principalmente Estados Unidos) para su procesamiento. Esta transferencia:"}),s.jsxs("ul",{className:"list-disc list-inside space-y-2 text-gray-300 ml-4 mb-4",children:[s.jsx("li",{children:"Solo ocurre cuando el usuario ejecuta activamente una acción de IA"}),s.jsx("li",{children:"El usuario puede evitarla usando Chrome Built-in AI (procesamiento 100% local)"}),s.jsx("li",{children:"Se aplica ofuscación automática de datos sensibles (URLs, emails, IPs, teléfonos, identificadores) antes del envío"}),s.jsx("li",{children:"Los proveedores de IA procesan los datos según sus propias políticas de privacidad:"})]}),s.jsxs("ul",{className:"list-disc list-inside space-y-2 text-gray-300 ml-8 mb-4",children:[s.jsxs("li",{children:["OpenAI: ",s.jsx("a",{href:"https://openai.com/privacy",target:"_blank",rel:"noopener noreferrer",className:"text-primary hover:underline",children:"https://openai.com/privacy"})]}),s.jsxs("li",{children:["Google (Gemini): ",s.jsx("a",{href:"https://policies.google.com/privacy",target:"_blank",rel:"noopener noreferrer",className:"text-primary hover:underline",children:"https://policies.google.com/privacy"})]}),s.jsxs("li",{children:["Anthropic (Claude): ",s.jsx("a",{href:"https://www.anthropic.com/privacy",target:"_blank",rel:"noopener noreferrer",className:"text-primary hover:underline",children:"https://www.anthropic.com/privacy"})]})]}),s.jsx("h3",{className:"text-xl font-semibold text-white mb-3",children:"6.2 Firebase (Google Cloud)"}),s.jsx("p",{className:"text-gray-300 mb-3",children:"Los datos de registro (email, nombre, empresa) se almacenan en Firebase/Firestore (Google Cloud Platform), con servidores que pueden estar ubicados fuera de Chile. Google cumple con estándares internacionales de protección de datos y cuenta con certificaciones ISO 27001, SOC 2 y SOC 3."}),s.jsxs("p",{className:"text-gray-300 mb-4",children:["Política de privacidad de Firebase: ",s.jsx("a",{href:"https://firebase.google.com/support/privacy",target:"_blank",rel:"noopener noreferrer",className:"text-primary hover:underline",children:"https://firebase.google.com/support/privacy"})]}),s.jsx("h3",{className:"text-xl font-semibold text-white mb-3",children:"6.3 Validación de licencia"}),s.jsx("p",{className:"text-gray-300",children:"La validación de licencia se realiza contra un servicio alojado en Google Cloud Functions (us-central1). Se envía únicamente: email, clave de licencia, nombre del producto e ID de instalación."})]}),s.jsxs("section",{className:"mb-10",children:[s.jsx("h2",{className:"text-2xl font-bold text-white mb-4",children:"7. Almacenamiento y seguridad"}),s.jsx("h3",{className:"text-xl font-semibold text-white mb-3",children:"7.1 Almacenamiento local"}),s.jsx("p",{className:"text-gray-300 mb-3",children:"En productos que operan como extensiones de navegador, la mayoría de los datos se almacenan exclusivamente en el navegador del usuario:"}),s.jsxs("ul",{className:"list-disc list-inside space-y-2 text-gray-300 ml-4 mb-4",children:[s.jsxs("li",{children:[s.jsx("span",{className:"font-semibold",children:"Almacenamiento local:"})," Datos sensibles de sesión (tokens, credenciales) — no se sincronizan"]}),s.jsxs("li",{children:[s.jsx("span",{className:"font-semibold",children:"Almacenamiento sincronizado:"})," Preferencias de configuración (idioma, tema, modelo de IA)"]})]}),s.jsx("h3",{className:"text-xl font-semibold text-white mb-3",children:"7.2 Almacenamiento en la nube"}),s.jsx("div",{className:"overflow-x-auto mb-6",children:s.jsxs("table",{className:"w-full text-sm text-gray-300 border border-gray-700 rounded-lg",children:[s.jsx("thead",{className:"bg-slate-700/50",children:s.jsxs("tr",{children:[s.jsx("th",{className:"px-4 py-3 text-left text-primary font-semibold",children:"Dato"}),s.jsx("th",{className:"px-4 py-3 text-left text-primary font-semibold",children:"Servicio"}),s.jsx("th",{className:"px-4 py-3 text-left text-primary font-semibold",children:"Ubicación"})]})}),s.jsxs("tbody",{className:"divide-y divide-gray-700",children:[s.jsxs("tr",{children:[s.jsx("td",{className:"px-4 py-2",children:"Email, nombre, empresa (usuarios Free)"}),s.jsx("td",{className:"px-4 py-2",children:"Firebase Firestore"}),s.jsx("td",{className:"px-4 py-2",children:"Google Cloud"})]}),s.jsxs("tr",{children:[s.jsx("td",{className:"px-4 py-2",children:"Email, plan, session_id (usuarios Pro Google/Microsoft)"}),s.jsx("td",{className:"px-4 py-2",children:"Firebase Firestore"}),s.jsx("td",{className:"px-4 py-2",children:"Google Cloud"})]})]})]})}),s.jsx("h3",{className:"text-xl font-semibold text-white mb-3",children:"7.3 Medidas de seguridad técnicas"}),s.jsxs("ul",{className:"list-disc list-inside space-y-2 text-gray-300 ml-4 mb-4",children:[s.jsx("li",{children:"Comunicaciones cifradas mediante HTTPS/TLS en todas las conexiones"}),s.jsx("li",{children:"Tokens y credenciales enmascarados en la interfaz de usuario"}),s.jsx("li",{children:"Ofuscación automática de datos sensibles antes del envío a servicios de IA"}),s.jsx("li",{children:"Validación de sesión con detección de uso multi-dispositivo"}),s.jsx("li",{children:"Código fuente sin ofuscación ni código remoto (Manifest V3)"}),s.jsx("li",{children:"Permisos mínimos necesarios declarados en el manifiesto de la extensión"}),s.jsx("li",{children:"Sin uso de eval(), código dinámico ni dependencias externas en tiempo de ejecución"})]}),s.jsx("h3",{className:"text-xl font-semibold text-white mb-3",children:"7.4 Plazos de conservación"}),s.jsx("div",{className:"overflow-x-auto",children:s.jsxs("table",{className:"w-full text-sm text-gray-300 border border-gray-700 rounded-lg",children:[s.jsx("thead",{className:"bg-slate-700/50",children:s.jsxs("tr",{children:[s.jsx("th",{className:"px-4 py-3 text-left text-primary font-semibold",children:"Dato"}),s.jsx("th",{className:"px-4 py-3 text-left text-primary font-semibold",children:"Plazo de conservación"})]})}),s.jsxs("tbody",{className:"divide-y divide-gray-700",children:[s.jsxs("tr",{children:[s.jsx("td",{className:"px-4 py-2",children:"Datos de registro (Firestore)"}),s.jsx("td",{className:"px-4 py-2",children:"Mientras la cuenta esté activa. Se eliminan a solicitud del titular"})]}),s.jsxs("tr",{children:[s.jsx("td",{className:"px-4 py-2",children:"Datos de sesión local"}),s.jsx("td",{className:"px-4 py-2",children:"Hasta que el usuario cierre sesión o desinstale el producto"})]}),s.jsxs("tr",{children:[s.jsx("td",{className:"px-4 py-2",children:"Credenciales de terceros"}),s.jsx("td",{className:"px-4 py-2",children:"Hasta que el usuario las elimine o cierre sesión"})]}),s.jsxs("tr",{children:[s.jsx("td",{className:"px-4 py-2",children:"Descripciones enviadas a IA"}),s.jsx("td",{className:"px-4 py-2",children:"No se almacenan. Se procesan en tiempo real y se descartan"})]})]})]})})]}),s.jsxs("section",{className:"mb-10",children:[s.jsx("h2",{className:"text-2xl font-bold text-white mb-4",children:"8. Derechos del titular"}),s.jsx("p",{className:"text-gray-300 mb-4",children:"De acuerdo con la Ley N° 21.719, todo usuario tiene derecho a:"}),s.jsx("div",{className:"overflow-x-auto mb-4",children:s.jsxs("table",{className:"w-full text-sm text-gray-300 border border-gray-700 rounded-lg",children:[s.jsx("thead",{className:"bg-slate-700/50",children:s.jsxs("tr",{children:[s.jsx("th",{className:"px-4 py-3 text-left text-primary font-semibold",children:"Derecho"}),s.jsx("th",{className:"px-4 py-3 text-left text-primary font-semibold",children:"Descripción"}),s.jsx("th",{className:"px-4 py-3 text-left text-primary font-semibold",children:"Cómo ejercerlo"})]})}),s.jsxs("tbody",{className:"divide-y divide-gray-700",children:[s.jsxs("tr",{children:[s.jsx("td",{className:"px-4 py-2 font-semibold",children:"Acceso"}),s.jsx("td",{className:"px-4 py-2",children:"Conocer qué datos personales tenemos sobre usted"}),s.jsx("td",{className:"px-4 py-2",children:"Enviar solicitud a [email protected]"})]}),s.jsxs("tr",{children:[s.jsx("td",{className:"px-4 py-2 font-semibold",children:"Rectificación"}),s.jsx("td",{className:"px-4 py-2",children:"Corregir datos inexactos o incompletos"}),s.jsx("td",{className:"px-4 py-2",children:"Enviar solicitud a [email protected]"})]}),s.jsxs("tr",{children:[s.jsx("td",{className:"px-4 py-2 font-semibold",children:"Supresión"}),s.jsx("td",{className:"px-4 py-2",children:"Solicitar la eliminación de sus datos"}),s.jsx("td",{className:"px-4 py-2",children:"Cerrar sesión + enviar solicitud a [email protected]"})]}),s.jsxs("tr",{children:[s.jsx("td",{className:"px-4 py-2 font-semibold",children:"Oposición"}),s.jsx("td",{className:"px-4 py-2",children:"Oponerse al tratamiento de sus datos"}),s.jsx("td",{className:"px-4 py-2",children:"Enviar solicitud a [email protected]"})]}),s.jsxs("tr",{children:[s.jsx("td",{className:"px-4 py-2 font-semibold",children:"Portabilidad"}),s.jsx("td",{className:"px-4 py-2",children:"Recibir sus datos en formato estructurado"}),s.jsx("td",{className:"px-4 py-2",children:"Enviar solicitud a [email protected]"})]}),s.jsxs("tr",{children:[s.jsx("td",{className:"px-4 py-2 font-semibold",children:"Limitación"}),s.jsx("td",{className:"px-4 py-2",children:"Restringir el tratamiento en ciertos casos"}),s.jsx("td",{className:"px-4 py-2",children:"Enviar solicitud a [email protected]"})]})]})]})}),s.jsxs("p",{className:"text-gray-300 mb-3",children:[s.jsx("span",{className:"font-semibold",children:"Plazo de respuesta:"})," Responderemos a su solicitud dentro de 15 días hábiles desde su recepción."]}),s.jsxs("p",{className:"text-gray-300 mb-3",children:[s.jsx("span",{className:"font-semibold",children:"Eliminación inmediata de datos locales:"}),' El usuario puede eliminar todos sus datos locales en cualquier momento cerrando sesión desde el producto (botón "Cerrar Sesión"). Esto elimina tokens, credenciales, preferencias y datos de sesión del navegador.']}),s.jsxs("p",{className:"text-gray-300",children:[s.jsx("span",{className:"font-semibold",children:"Reclamación ante la autoridad:"})," Si considera que sus derechos no han sido debidamente atendidos, puede presentar una reclamación ante la Agencia de Protección de Datos Personales de Chile."]})]}),s.jsxs("section",{className:"mb-10",children:[s.jsx("h2",{className:"text-2xl font-bold text-white mb-4",children:"9. Consentimiento"}),s.jsx("p",{className:"text-gray-300 mb-4",children:"Al registrarse en cualquiera de los productos de Haka Lab, el usuario otorga su consentimiento libre, específico, informado e inequívoco para el tratamiento de sus datos personales conforme a esta política."}),s.jsx("p",{className:"text-gray-300 mb-3",children:"El usuario puede retirar su 
17630consentimiento en cualquier momento:"}),s.jsxs("ul",{className:"list-disc list-inside space-y-2 text-gray-300 ml-4 mb-4",children:[s.jsx("li",{children:"Cerrando sesión en el producto (elimina datos locales)"}),s.jsx("li",{children:"Solicitando la eliminación de sus datos en Firestore a [email protected]"}),s.jsx("li",{children:"Desinstalando el producto"})]}),s.jsx("p",{className:"text-gray-300",children:"El retiro del consentimiento no afecta la licitud del tratamiento realizado con anterioridad."})]}),s.jsxs("section",{className:"mb-10",children:[s.jsx("h2",{className:"text-2xl font-bold text-white mb-4",children:"10. Uso de inteligencia artificial"}),s.jsx("p",{className:"text-gray-300 mb-3",children:"Los productos de Haka Lab utilizan servicios de inteligencia artificial para mejorar descripciones de tareas, generar escenarios de prueba y optimizar flujos de trabajo. Es importante que el usuario comprenda:"}),s.jsxs("ol",{className:"list-decimal list-inside space-y-2 text-gray-300 ml-4",children:[s.jsxs("li",{children:[s.jsx("span",{className:"font-semibold",children:"Las descripciones se envían a proveedores de IA externos"})," (OpenAI, Google, Anthropic) cuando se usa IA en la nube"]}),s.jsxs("li",{children:[s.jsx("span",{className:"font-semibold",children:"La ofuscación automática"})," reemplaza datos sensibles (emails, URLs, IPs, teléfonos, identificadores) por placeholders antes del envío"]}),s.jsxs("li",{children:[s.jsx("span",{className:"font-semibold",children:"El usuario puede agregar palabras personalizadas"})," al diccionario de ofuscación para proteger información específica de su organización"]}),s.jsxs("li",{children:[s.jsx("span",{className:"font-semibold",children:"Chrome Built-in AI"})," procesa todo localmente sin enviar datos a ningún servidor externo"]}),s.jsxs("li",{children:[s.jsx("span",{className:"font-semibold",children:"Los proveedores de IA"})," pueden procesar los datos según sus propias políticas. Hakalab no tiene control sobre el tratamiento que estos proveedores realicen"]}),s.jsxs("li",{children:[s.jsx("span",{className:"font-semibold",children:"No se almacenan las descripciones"})," enviadas a la IA. Se procesan en tiempo real y el resultado se muestra al usuario sin persistencia"]})]})]}),s.jsxs("section",{className:"mb-10",children:[s.jsx("h2",{className:"text-2xl font-bold text-white mb-4",children:"11. Menores de edad"}),s.jsx("p",{className:"text-gray-300",children:"Los productos de Haka Lab son herramientas profesionales de calidad de software. No están dirigidos a menores de 18 años y no recopilamos intencionalmente datos de menores. Si detectamos que un menor ha proporcionado datos personales, procederemos a eliminarlos."})]}),s.jsxs("section",{className:"mb-10",children:[s.jsx("h2",{className:"text-2xl font-bold text-white mb-4",children:"12. Modificaciones a esta política"}),s.jsx("p",{className:"text-gray-300",children:"Nos reservamos el derecho de actualizar esta política de privacidad para reflejar cambios en nuestras prácticas o en la legislación aplicable. Las modificaciones se publicarán en esta página con la fecha de actualización. Si los cambios son sustanciales, notificaremos a los usuarios a través de nuestros productos o por correo electrónico."})]}),s.jsxs("section",{className:"mb-10",children:[s.jsx("h2",{className:"text-2xl font-bold text-white mb-4",children:"13. Contacto"}),s.jsx("p",{className:"text-gray-300 mb-3",children:"Para cualquier consulta, solicitud o reclamo relacionado con el tratamiento de sus datos personales:"}),s.jsxs("div",{className:"space-y-2 text-gray-300 ml-4",children:[s.jsxs("p",{children:["📧 ",s.jsx("a",{href:"mailto:[email protected]",className:"text-primary hover:underline",children:"[email protected]"})]}),s.jsx("p",{children:"🏢 Hakalab SpA"}),s.jsx("p",{children:"🌎 Chile"})]})]}),s.jsxs("section",{className:"mb-10",children:[s.jsx("h2",{className:"text-2xl font-bold text-white mb-4",children:"14. Legislación aplicable y jurisdicción"}),s.jsx("p",{className:"text-gray-300",children:"Esta política se rige por la legislación de la República de Chile. Cualquier controversia será sometida a los tribunales ordinarios de justicia de Santiago de Chile, sin perjuicio del derecho del titular a reclamar ante la Agencia de Protección de Datos Personales."})]}),s.jsx("div",{className:"border-t border-gray-700 pt-8 mt-12 text-center",children:s.jsx("p",{className:"text-gray-400 italic",children:"Documento vigente desde el 13 de mayo de 2026."})})]})]})})}function die(){const[t,e]=k.useState(!1),[a,n]=k.useState(""),{loginWithGoogle:i}=hs(),r=Qa(),o=async()=>{n(""),e(!0);try{await i(),r("/admin-blog/dashboard")}catch(l){n(l.message)}finally{e(!1)}};return s.jsx("div",{className:"min-h-screen bg-gradient-to-br from-dark via-slate-900 to-dark flex items-center justify-center px-4",children:s.jsxs(_.div,{initial:{opacity:0,y:20}
17630,animate:{opacity:1,y:0},transition:{duration:.6},className:"w-full max-w-md",children:[s.jsxs("div",{className:"text-center mb-8",children:[s.jsx("img",{src:"/imagenes/logo_haka.png",alt:"HakaLab",className:"h-16 mx-auto mb-4"}),s.jsx("p",{className:"text-gray-400",children:"Panel de Administración - Blog"})]}),s.jsxs("div",{className:"bg-slate-800/50 backdrop-blur-sm border border-slate-700 rounded-2xl p-8 shadow-2xl",children:[s.jsx("h2",{className:"text-2xl font-bold text-white mb-2",children:"Iniciar Sesión"}),s.jsx("p",{className:"text-gray-400 text-sm mb-6",children:"Panel de Administración - Blog"}),a&&s.jsx(_.div,{initial:{opacity:0,y:-10},animate:{opacity:1,y:0},className:"mb-6 p-4 bg-red-500/10 border border-red-500/50 rounded-lg",children:s.jsx("p",{className:"text-red-400 text-sm",children:a})}),s.jsx("button",{onClick:o,disabled:t,className:"w-full px-4 py-3 bg-white text-gray-900 font-semibold rounded-lg hover:bg-gray-100 transition-all disabled:opacity-50 disabled:cursor-not-allowed flex items-center justify-center gap-3",children:t?s.jsxs(s.Fragment,{children:[s.jsx(_.div,{animate:{rotate:360},transition:{duration:1,repeat:1/0,ease:"linear"},className:"w-4 h-4 border-2 border-gray-900 border-t-transparent rounded-full"}),"Iniciando sesión..."]}):s.jsxs(s.Fragment,{children:[s.jsxs("svg",{className:"w-5 h-5",viewBox:"0 0 24 24",children:[s.jsx("path",{fill:"currentColor",d:"M22.56 12.25c0-.78-.07-1.53-.2-2.25H12v4.26h5.92c-.26 1.37-1.04 2.53-2.21 3.31v2.77h3.57c2.08-1.92 3.28-4.74 3.28-8.09z"}),s.jsx("path",{fill:"currentColor",d:"M12 23c2.97 0 5.46-.98 7.28-2.66l-3.57-2.77c-.98.66-2.23 1.06-3.71 1.06-2.86 0-5.29-1.93-6.16-4.53H2.18v2.84C3.99 20.53 7.7 23 12 23z"}),s.jsx("path",{fill:"currentColor",d:"M5.84 14.09c-.22-.66-.35-1.36-.35-2.09s.13-1.43.35-2.09V7.07H2.18C1.43 8.55 1 10.22 1 12s.43 3.45 1.18 4.93l2.85-2.22.81-.62z"}),s.jsx("path",{fill:"currentColor",d:"M12 5.38c1.62 0 3.06.56 4.21 1.64l3.15-3.15C17.45 2.09 14.97 1 12 1 7.7 1 3.99 3.47 2.18 7.07l3.66 2.84c.87-2.6 3.3-4.53 6.16-4.53z"})]}),"Iniciar con Google"]})}),s.jsx("div",{className:"mt-6 p-4 bg-blue-500/10 border border-blue-500/30 rounded-lg",children:s.jsxs("p",{className:"text-xs text-blue-300",children:[s.jsx("strong",{children:"Nota:"})," Solo usuarios autorizados pueden acceder al panel de administración."]})})]}),s.jsx("p",{className:"text-center text-gray-500 text-sm mt-8",children:"© 2026 HakaLab. Todos los derechos reservados."})]})})}function Do({children:t}){const[e,a]=k.useState(!0),{user:n,logout:i}=hs(),r=Qa(),o=fn(),l=async()=>{try{await i(),r("/admin-blog")}catch(u){console.error("Error al cerrar sesión:",u)}},c=[{label:"Crear Blog",path:"/admin-blog/create",icon:"✏️"},{label:"Editar Blogs",path:"/admin-blog/edit",icon:"📝"}],d=u=>o.pathname===u;return s.jsxs("div",{className:"min-h-screen bg-dark flex",children:[s.jsxs(_.div,{initial:{x:-300},animate:{x:0},transition:{duration:.3},className:`${e?"w-64":"w-20"} bg-slate-800 border-r border-slate-700 transition-all duration-300 flex flex-col`,children:[s.jsx("div",{className:"p-4 border-b border-slate-700",children:s.jsxs("div",{className:"flex items-center justify-between",children:[e&&s.jsx("div",{className:"flex items-center gap-2",children:s.jsx("img",{src:"../imagenes/logo_haka.png",alt:"HakaLab",className:"h-8"})}),s.jsx("button",{onClick:()=>a(!e),className:"p-2 hover:bg-slate-700 rounded-lg transition",children:e?"◀":"▶"})]})}),s.jsx("nav",{className:"flex-1 p-4 space-y-2",children:c.map(u=>s.jsxs("button",{onClick:()=>r(u.path),className:`w-full flex items-center gap-3 px-4 py-3 rounded-lg transition ${d(u.path)?"bg-primary/20 text-primary border border-primary/50":"text-gray-400 hover:bg-slate-700/50"}`,children:[s.jsx("span",{className:"text-xl",children:u.icon}),e&&s.jsx("span",{className:"text-sm font-medium",children:u.label})]},u.path))}),s.jsxs("div",{className:"p-4 border-t border-slate-700 space-y-3",children:[e&&s.jsxs("div",{className:"text-xs",children:[s.jsx("p",{className:"text-gray-500",children:"Conectado como:"}),s.jsx("p",{className:"text-white font-medium truncate",children:n==null?void 0:n.email})]}),s.jsx("button",{onClick:l,className:"w-full px-4 py-2 bg-red-500/10 text-red-400 hover:bg-red-500/20 rounded-lg transition text-sm font-medium",children:e?"Cerrar Sesión":"🚪"})]})]}),s.jsxs("div",{className:"flex-1 flex flex-col",children:[s.jsxs("div",{className:"bg-slate-800/50 border-b border-slate-700 px-6 py-4 flex items-center justify-between",children:[s.jsx("h1",{className:"text-2xl font-bold text-white",children:"Panel de Administración"}),s.jsxs("div",{className:"flex items-center gap-4",children:[s.jsx("span",{className:"text-gray-400 text-sm",children:n==null?void 0:n.email}
17630),s.jsx("img",{src:`https://ui-avatars.com/api/?name=${n==null?void 0:n.email}&background=06b6d4&color=fff`,alt:"Avatar",className:"w-10 h-10 rounded-full"})]})]}),s.jsx("div",{className:"flex-1 overflow-auto p-6",children:t})]})]})}function uie(){const{user:t}=hs(),[e,a]=k.useState({published:0,drafts:0,tags:0}),[n,i]=k.useState(!0);return k.useEffect(()=>{(async()=>{try{i(!0);const o=jl(ga(St,"blogs"),Gn("published","==",!0)),c=(await Ni(o)).size,d=jl(ga(St,"blogs"),Gn("published","==",!1)),p=(await Ni(d)).size,h=(await Ni(ga(St,"tags"))).size;a({published:c,drafts:p,tags:h})}catch(o){console.error("Error al cargar estadísticas:",o)}finally{i(!1)}})()},[]),s.jsx(Do,{children:s.jsxs(_.div,{initial:{opacity:0,y:20},animate:{opacity:1,y:0},transition:{duration:.6},className:"space-y-6",children:[s.jsxs("div",{children:[s.jsx("h2",{className:"text-3xl font-bold text-white mb-2",children:"Bienvenido al Panel de Blog"}),s.jsx("p",{className:"text-gray-400",children:"Gestiona tus artículos de blog desde aquí"})]}),s.jsxs("div",{className:"grid grid-cols-1 md:grid-cols-3 gap-6",children:[s.jsx(_.div,{whileHover:{y:-5},className:"bg-slate-800/50 border border-slate-700 rounded-lg p-6",children:s.jsxs("div",{className:"flex items-center justify-between",children:[s.jsxs("div",{children:[s.jsx("p",{className:"text-gray-400 text-sm",children:"Blogs Publicados"}),n?s.jsx("div",{className:"mt-2",children:s.jsx(_.div,{animate:{rotate:360},transition:{duration:1,repeat:1/0,ease:"linear"},className:"w-8 h-8 border-4 border-primary border-t-transparent rounded-full"})}):s.jsx("p",{className:"text-3xl font-bold text-white mt-2",children:e.published})]}),s.jsx("span",{className:"text-4xl",children:"📝"})]})}),s.jsx(_.div,{whileHover:{y:-5},className:"bg-slate-800/50 border border-slate-700 rounded-lg p-6",children:s.jsxs("div",{className:"flex items-center justify-between",children:[s.jsxs("div",{children:[s.jsx("p",{className:"text-gray-400 text-sm",children:"Borradores"}),n?s.jsx("div",{className:"mt-2",children:s.jsx(_.div,{animate:{rotate:360},transition:{duration:1,repeat:1/0,ease:"linear"},className:"w-8 h-8 border-4 border-primary border-t-transparent rounded-full"})}):s.jsx("p",{className:"text-3xl font-bold text-white mt-2",children:e.drafts})]}),s.jsx("span",{className:"text-4xl",children:"📋"})]})}),s.jsx(_.div,{whileHover:{y:-5},className:"bg-slate-800/50 border border-slate-700 rounded-lg p-6",children:s.jsxs("div",{className:"flex items-center justify-between",children:[s.jsxs("div",{children:[s.jsx("p",{className:"text-gray-400 text-sm",children:"Etiquetas"}),n?s.jsx("div",{className:"mt-2",children:s.jsx(_.div,{animate:{rotate:360},transition:{duration:1,repeat:1/0,ease:"linear"},className:"w-8 h-8 border-4 border-primary border-t-transparent rounded-full"})}):s.jsx("p",{className:"text-3xl font-bold text-white mt-2",children:e.tags})]}),s.jsx("span",{className:"text-4xl",children:"🏷️"})]})})]}),s.jsxs("div",{className:"bg-slate-800/50 border border-slate-700 rounded-lg p-6",children:[s.jsx("h3",{className:"text-xl font-bold text-white mb-4",children:"Acciones Rápidas"}),s.jsxs("div",{className:"grid grid-cols-1 md:grid-cols-2 gap-4",children:[s.jsx(_.button,{whileHover:{scale:1.02},whileTap:{scale:.98},onClick:()=>window.location.href="/admin-blog/create",className:"px-6 py-3 bg-gradient-to-r from-cyan-500 to-blue-600 text-white rounded-lg font-semibold hover:shadow-lg hover:shadow-cyan-500/50 transition",children:"✏️ Crear Nuevo Blog"}),s.jsx(_.button,{whileHover:{scale:1.02},whileTap:{scale:.98},onClick:()=>window.location.href="/admin-blog/edit",className:"px-6 py-3 bg-slate-700 text-white rounded-lg font-semibold hover:bg-slate-600 transition",children:"📝 Ver Mis Blogs"})]})]}),s.jsxs("div",{className:"bg-blue-500/10 border border-blue-500/30 rounded-lg p-6",children:[s.jsx("h3",{className:"text-lg font-bold text-blue-300 mb-2",children:"💡 Próximas Características"}),s.jsxs("ul",{className:"text-blue-200 text-sm space-y-2",children:[s.jsx("li",{children:"✅ Editor de blogs con rich text"}),s.jsx("li",{children:"✅ Gestión de etiquetas"}),s.jsx("li",{children:"✅ Subida de imágenes"}),s.jsx("li",{children:"✅ Publicación automática"}),s.jsx("li",{children:"✅ Estadísticas de blogs"})]})]})]})})}function Dt(t){this.content=t}Dt.prototype={constructor:Dt,find:function(t){for(var e=0;e<this.content.length;e+=2)if(this.content[e]===t)return e;return-1},get:function(t){var e=this.find(t);return e==-1?void 0:this.content[e+1]},update:function(t,e,a){var n=a&&a!=t?this.remove(a):this,i=n.find(t),r=n.content.slice();return i==-1?r.push(a||t,e):(r[i+1]=e,a&&(r[i]=a)),new Dt(r)},remove:function(t){var e=this.find(t);if(e==-1)return this;var a=this.content.slice();return a.splice(e,2),new Dt(a)},addToStart:function(t,e){return new Dt([t,e].concat(this.remove(t).content))},addToEnd:function(t,e){var a=this.remove(t).content.slice();return a.push(t,e),new Dt(a)},addBefore:function(t,e,a){var n=this.remove(e),i=n.content.slice(),r=n.find(t);return i.splice(r==-1?i.length:r,0,e,a),new Dt(i)}
vendor: 26,975 bytes, lines 17630-17631
17630,forEach:function(t){for(var e=0;e<this.content.length;e+=2)t(this.content[e],this.content[e+1])},prepend:function(t){return t=Dt.from(t),t.size?new Dt(t.content.concat(this.subtract(t).content)):this},append:function(t){return t=Dt.from(t),t.size?new Dt(this.subtract(t).content.concat(t.content)):this},subtract:function(t){var e=this;t=Dt.from(t);for(var a=0;a<t.content.length;a+=2)e=e.remove(t.content[a]);return e},toObject:function(){var t={};return this.forEach(function(e,a){t[e]=a}),t},get size(){return this.content.length>>1}};Dt.from=function(t){if(t instanceof Dt)return t;var e=[];if(t)for(var a in t)e.push(a,t[a]);return new Dt(e)};function VO(t,e,a){for(let n=0;;n++){if(n==t.childCount||n==e.childCount)return t.childCount==e.childCount?null:a;let i=t.child(n),r=e.child(n);if(i==r){a+=i.nodeSize;continue}if(!i.sameMarkup(r))return a;if(i.isText&&i.text!=r.text){for(let o=0;i.text[o]==r.text[o];o++)a++;return a}if(i.content.size||r.content.size){let o=VO(i.content,r.content,a+1);if(o!=null)return o}a+=i.nodeSize}}function HO(t,e,a,n){for(let i=t.childCount,r=e.childCount;;){if(i==0||r==0)return i==r?null:{a,b:n};let o=t.child(--i),l=e.child(--r),c=o.nodeSize;if(o==l){a-=c,n-=c;continue}if(!o.sameMarkup(l))return{a,b:n};if(o.isText&&o.text!=l.text){let d=0,u=Math.min(o.text.length,l.text.length);for(;d<u&&o.text[o.text.length-d-1]==l.text[l.text.length-d-1];)d++,a--,n--;return{a,b:n}}if(o.content.size||l.content.size){let d=HO(o.content,l.content,a-1,n-1);if(d)return d}a-=c,n-=c}}class V{constructor(e,a){if(this.content=e,this.size=a||0,a==null)for(let n=0;n<e.length;n++)this.size+=e[n].nodeSize}nodesBetween(e,a,n,i=0,r){for(let o=0,l=0;l<a;o++){let c=this.content[o],d=l+c.nodeSize;if(d>e&&n(c,i+l,r||null,o)!==!1&&c.content.size){let u=l+1;c.nodesBetween(Math.max(0,e-u),Math.min(c.content.size,a-u),n,i+u)}l=d}}descendants(e){this.nodesBetween(0,this.size,e)}textBetween(e,a,n,i){let r="",o=!0;return this.nodesBetween(e,a,(l,c)=>{let d=l.isText?l.text.slice(Math.max(e,c)-c,a-c):l.isLeaf?i?typeof i=="function"?i(l):i:l.type.spec.leafText?l.type.spec.leafText(l):"":"";l.isBlock&&(l.isLeaf&&d||l.isTextblock)&&n&&(o?o=!1:r+=n),r+=d},0),r}append(e){if(!e.size)return this;if(!this.size)return e;let a=this.lastChild,n=e.firstChild,i=this.content.slice(),r=0;for(a.isText&&a.sameMarkup(n)&&(i[i.length-1]=a.withText(a.text+n.text),r=1);r<e.content.length;r++)i.push(e.content[r]);return new V(i,this.size+e.size)}cut(e,a=this.size){if(e==0&&a==this.size)return this;let n=[],i=0;if(a>e)for(let r=0,o=0;o<a;r++){let l=this.content[r],c=o+l.nodeSize;c>e&&((o<e||c>a)&&(l.isText?l=l.cut(Math.max(0,e-o),Math.min(l.text.length,a-o)):l=l.cut(Math.max(0,e-o-1),Math.min(l.content.size,a-o-1))),n.push(l),i+=l.nodeSize),o=c}return new V(n,i)}cutByIndex(e,a){return e==a?V.empty:e==0&&a==this.content.length?this:new V(this.content.slice(e,a))}replaceChild(e,a){let n=this.content[e];if(n==a)return this;let i=this.content.slice(),r=this.size+a.nodeSize-n.nodeSize;return i[e]=a,new V(i,r)}addToStart(e){return new V([e].concat(this.content),this.size+e.nodeSize)}addToEnd(e){return new V(this.content.concat(e),this.size+e.nodeSize)}eq(e){if(this.content.length!=e.content.length)return!1;for(let a=0;a<this.content.length;a++)if(!this.content[a].eq(e.content[a]))return!1;return!0}get firstChild(){return this.content.length?this.content[0]:null}get lastChild(){return this.content.length?this.content[this.content.length-1]:null}get childCount(){return this.content.length}child(e){let a=this.content[e];if(!a)throw new RangeError("Index "+e+" out of range for "+this);return a}maybeChild(e){return this.content[e]||null}forEach(e){for(let a=0,n=0;a<this.content.length;a++){let i=this.content[a];e(i,n,a),n+=i.nodeSize}}findDiffStart(e,a=0){return VO(this,e,a)}findDiffEnd(e,a=this.size,n=e.size){return HO(this,e,a,n)}findIndex(e){if(e==0)return Xp(0,e);if(e==this.size)return Xp(this.content.length,e);if(e>this.size||e<0)throw new RangeError(`Position ${e} outside of fragment (${this})`);for(let a=0,n=0;;a++){let i=this.child(a),r=n+i.nodeSize;if(r>=e)return r==e?Xp(a+1,r):Xp(a,n);n=r}}toString(){return"<"+this.toStringInner()+">"}toStringInner(){return this.content.join(", ")}toJSON(){return this.content.length?this.content.map(e=>e.toJSON()):null}static fromJSON(e,a){if(!a)return V.empty;if(!Array.isArray(a))throw new RangeError("Invalid input for Fragment.fromJSON");return new V(a.map(e.nodeFromJSON))}static fromArray(e){if(!e.length)return V.empty;let a,n=0;for(let i=0;i<e.length;i++){let r=e[i];n+=r.nodeSize,i&&r.isText&&e[i-1].sameMarkup(r)?(a||(a=e.slice(0,i)),a[a.length-1]=r.withText(a[a.length-1].text+r.text)):a&&a.push(r)}return new V(a||e,n)}static from(e){if(!e)return V.empty;if(e instanceof V)return e;if(Array.isArray(e))return this.fromArray(e);if(e.attrs)return new V([e],e.nodeSize);throw new RangeError("Can not convert "+e+" to a Fragment"+(e.nodesBetween?" (looks like multiple versions of prosemirror-model were loaded)":""))}}V.empty=new V([],0);const B0={index:0,offset:0};function Xp(t,e){return B0.index=t,B0.offset=e,B0}function Kh(t,e){if(t===e)return!0;if(!(t&&typeof t=="object")||!(e&&typeof e=="object"))return!1;let a=Array.isArray(t);if(Array.isArray(e)!=a)return!1;if(a){if(t.length!=e.length)return!1;for(let n=0;n<t.length;n++)if(!Kh(t[n],e[n]))return!1}else{for(let n in t)if(!(n in e)||!Kh(t[n],e[n]))return!1;for(let n in e)if(!(n in t))return!1}return!0}let qe=class Sb{constructor(e,a){this.type=e,this.attrs=a}addToSet(e){let a,n=!1;for(let i=0;i<e.length;i++){let r=e[i];if(this.eq(r))return e;if(this.type.excludes(r.type))a||(a=e.slice(0,i));else{if(r.type.excludes(this.type))return e;!n&&r.type.rank>this.type.rank&&(a||(a=e.slice(0,i)),a.push(this),n=!0),a&&a.push(r)}}return a||(a=e.slice()),n||a.push(this),a}removeFromSet(e){for(let a=0;a<e.length;a++)if(this.eq(e[a]))return e.slice(0,a).concat(e.slice(a+1));return e}isInSet(e){for(let a=0;a<e.length;a++)if(this.eq(e[a]))return!0;return!1}eq(e){return this==e||this.type==e.type&&Kh(this.attrs,e.attrs)}toJSON(){let e={type:this.type.name};for(let a in this.attrs){e.attrs=this.attrs;break}return e}static fromJSON(e,a){if(!a)throw new RangeError("Invalid input for Mark.fromJSON");let n=e.marks[a.type];if(!n)throw new RangeError(`There is no mark type ${a.type} in this schema`);let i=n.create(a.attrs);return n.checkAttrs(i.attrs),i}static sameSet(e,a){if(e==a)return!0;if(e.length!=a.length)return!1;for(let n=0;n<e.length;n++)if(!e[n].eq(a[n]))return!1;return!0}static setFrom(e){if(!e||Array.isArray(e)&&e.length==0)return Sb.none;if(e instanceof Sb)return[e];let a=e.slice();return a.sort((n,i)=>n.type.rank-i.type.rank),a}};qe.none=[];class Jh extends Error{}class K{constructor(e,a,n){this.content=e,this.openStart=a,this.openEnd=n}get size(){return this.content.size-this.openStart-this.openEnd}insertAt(e,a){let n=BO(this.content,e+this.openStart,a);return n&&new K(n,this.openStart,this.openEnd)}removeBetween(e,a){return new K(FO(this.content,e+this.openStart,a+this.openStart),this.openStart,this.openEnd)}eq(e){return this.content.eq(e.content)&&this.openStart==e.openStart&&this.openEnd==e.openEnd}toString(){return this.content+"("+this.openStart+","+this.openEnd+")"}toJSON(){if(!this.content.size)return null;let e={content:this.content.toJSON()};return this.openStart>0&&(e.openStart=this.openStart),this.openEnd>0&&(e.openEnd=this.openEnd),e}static fromJSON(e,a){if(!a)return K.empty;let n=a.openStart||0,i=a.openEnd||0;if(typeof n!="number"||typeof i!="number")throw new RangeError("Invalid input for Slice.fromJSON");return new K(V.fromJSON(e,a.content),n,i)}static maxOpen(e,a=!0){let n=0,i=0;for(let r=e.firstChild;r&&!r.isLeaf&&(a||!r.type.spec.isolating);r=r.firstChild)n++;for(let r=e.lastChild;r&&!r.isLeaf&&(a||!r.type.spec.isolating);r=r.lastChild)i++;return new K(e,n,i)}}K.empty=new K(V.empty,0,0);function FO(t,e,a){let{index:n,offset:i}=t.findIndex(e),r=t.maybeChild(n),{index:o,offset:l}=t.findIndex(a);if(i==e||r.isText){if(l!=a&&!t.child(o).isText)throw new RangeError("Removing non-flat range");return t.cut(0,e).append(t.cut(a))}if(n!=o)throw new RangeError("Removing non-flat range");return t.replaceChild(n,r.copy(FO(r.content,e-i-1,a-i-1)))}function BO(t,e,a,n){let{index:i,offset:r}=t.findIndex(e),o=t.maybeChild(i);if(r==e||o.isText)return n&&!n.canReplace(i,i,a)?null:t.cut(0,e).append(a).append(t.cut(e));let l=BO(o.content,e-r-1,a,o);return l&&t.replaceChild(i,o.copy(l))}function pie(t,e,a){if(a.openStart>t.depth)throw new Jh("Inserted content deeper than insertion position");if(t.depth-a.openStart!=e.depth-a.openEnd)throw new Jh("Inconsistent open depths");return UO(t,e,a,0)}function UO(t,e,a,n){let i=t.index(n),r=t.node(n);if(i==e.index(n)&&n<t.depth-a.openStart){let o=UO(t,e,a,n+1);return r.copy(r.content.replaceChild(i,o))}else if(a.content.size)if(!a.openStart&&!a.openEnd&&t.depth==n&&e.depth==n){let o=t.parent,l=o.content;return zo(o,l.cut(0,t.parentOffset).append(a.content).append(l.cut(e.parentOffset)))}else{let{start:o,end:l}=mie(a,t);return zo(r,WO(t,o,l,e,n))}else return zo(r,Qh(t,e,n))}function $O(t,e){if(!e.type.compatibleContent(t.type))throw new Jh("Cannot join "+e.type.name+" onto "+t.type.name)}function _b(t,e,a){let n=t.node(a);return $O(n,e.node(a)),n}function qo(t,e){let a=e.length-1;a>=0&&t.isText&&t.sameMarkup(e[a])?e[a]=t.withText(e[a].text+t.text):e.push(t)}function vd(t,e,a,n){let i=(e||t).node(a),r=0,o=e?e.index(a):i.childCount;t&&(r=t.index(a),t.depth>a?r++:t.textOffset&&(qo(t.nodeAfter,n),r++));for(let l=r;l<o;l++)qo(i.child(l),n);e&&e.depth==a&&e.textOffset&&qo(e.nodeBefore,n)}function zo(t,e){return t.type.checkContent(e),t.copy(e)}function WO(t,e,a,n,i){let r=t.depth>i&&_b(t,e,i+1),o=n.depth>i&&_b(a,n,i+1),l=[];return vd(null,t,i,l),r&&o&&e.index(i)==a.index(i)?($O(r,o),qo(zo(r,WO(t,e,a,n,i+1)),l)):(r&&qo(zo(r,Qh(t,e,i+1)),l),vd(e,a,i,l),o&&qo(zo(o,Qh(a,n,i+1)),l)),vd(n,null,i,l),new V(l)}function Qh(t,e,a){let n=[];if(vd(null,t,a,n),t.depth>a){let i=_b(t,e,a+1);qo(zo(i,Qh(t,e,a+1)),n)}return vd(e,null,a,n),new V(n)}function mie(t,e){let a=e.depth-t.openStart,i=e.node(a).copy(t.content);for(let r=a-1;r>=0;r--)i=e.node(r).copy(V.from(i));return{start:i.resolveNoCache(t.openStart+a),end:i.resolveNoCache(i.content.size-t.openEnd-a)}}class du{constructor(e,a,n){this.pos=e,this.path=a,this.parentOffset=n,this.depth=a.length/3-1}resolveDepth(e){return e==null?this.depth:e<0?this.depth+e:e}get parent(){return this.node(this.depth)}get doc(){return this.node(0)}node(e){return this.path[this.resolveDepth(e)*3]}index(e){return this.path[this.resolveDepth(e)*3+1]}indexAfter(e){return e=this.resolveDepth(e),this.index(e)+(e==this.depth&&!this.textOffset?0:1)}start(e){return e=this.resolveDepth(e),e==0?0:this.path[e*3-1]+1}end(e){return e=this.resolveDepth(e),this.start(e)+this.node(e).content.size}before(e){if(e=this.resolveDepth(e),!e)throw new RangeError("There is no position before the top-level node");return e==this.depth+1?this.pos:this.path[e*3-1]}after(e){if(e=this.resolveDepth(e),!e)throw new RangeError("There is no position after the top-level node");return e==this.depth+1?this.pos:this.path[e*3-1]+this.path[e*3].nodeSize}get textOffset(){return this.pos-this.path[this.path.length-1]}get nodeAfter(){let e=this.parent,a=this.index(this.depth);if(a==e.childCount)return null;let n=this.pos-this.path[this.path.length-1],i=e.child(a);return n?e.child(a).cut(n):i}get nodeBefore(){let e=this.index(this.depth),a=this.pos-this.path[this.path.length-1];return a?this.parent.child(e).cut(0,a):e==0?null:this.parent.child(e-1)}posAtIndex(e,a){a=this.resolveDepth(a);let n=this.path[a*3],i=a==0?0:this.path[a*3-1]+1;for(let r=0;r<e;r++)i+=n.child(r).nodeSize;return i}marks(){let e=this.parent,a=this.index();if(e.content.size==0)return qe.none;if(this.textOffset)return e.child(a).marks;let n=e.maybeChild(a-1),i=e.maybeChild(a);if(!n){let l=n;n=i,i=l}let r=n.marks;for(var o=0;o<r.length;o++)r[o].type.spec.inclusive===!1&&(!i||!r[o].isInSet(i.marks))&&(r=r[o--].removeFromSet(r));return r}marksAcross(e){let a=this.parent.maybeChild(this.index());if(!a||!a.isInline)return null;let n=a.marks,i=e.parent.maybeChild(e.index());for(var r=0;r<n.length;r++)n[r].type.spec.inclusive===!1&&(!i||!n[r].isInSet(i.marks))&&(n=n[r--].removeFromSet(n));return n}sharedDepth(e){for(let a=this.depth;a>0;a--)if(this.start(a)<=e&&this.end(a)>=e)return a;return 0}blockRange(e=this,a){if(e.pos<this.pos)return e.blockRange(this);for(let n=this.depth-(this.parent.inlineContent||this.pos==e.pos?1:0);n>=0;n--)if(e.pos<=this.end(n)&&(!a||a(this.node(n))))return new Xh(this,e,n);return null}sameParent(e){return this.pos-this.parentOffset==e.pos-e.parentOffset}max(e){return e.pos>this.pos?e:this}min(e){return e.pos<this.pos?e:this}toString(){let e="";for(let a=1;a<=this.depth;a++)e+=(e?"/":"")+this.node(a).type.name+"_"+this.index(a-1);return e+":"+this.parentOffset}static resolve(e,a){if(!(a>=0&&a<=e.content.size))throw new RangeError("Position "+a+" out of range");let n=[],i=0,r=a;for(let o=e;;){let{index:l,offset:c}=o.content.findIndex(r),d=r-c;if(n.push(o,l,i+c),!d||(o=o.child(l),o.isText))break;r=d-1,i+=c+1}return new du(a,n,r)}static resolveCached(e,a){let n=wj.get(e);if(n)for(let r=0;r<n.elts.length;r++){let o=n.elts[r];if(o.pos==a)return o}else wj.set(e,n=new hie);let i=n.elts[n.i]=du.resolve(e,a);return n.i=(n.i+1)%fie,i}}class hie{constructor(){this.elts=[],this.i=0}}const fie=12,wj=new WeakMap;class Xh{constructor(e,a,n){this.$from=e,this.$to=a,this.depth=n}get start(){return this.$from.before(this.depth+1)}get end(){return this.$to.after(this.depth+1)}get parent(){return this.$from.node(this.depth)}get startIndex(){return this.$from.index(this.depth)}get endIndex(){return this.$to.indexAfter(this.depth)}}const gie=Object.create(null);class Rn{constructor(e,a,n,i=qe.none){this.type=e,this.attrs=a,this.marks=i,this.content=n||V.empty}get children(){return this.content.content}get nodeSize(){return this.isLeaf?1:2+this.content.size}get childCount(){return this.content.childCount}child(e){return this.content.child(e)}maybeChild(e){return this.content.maybeChild(e)}forEach(e){this.content.forEach(e)}nodesBetween(e,a,n,i=0){this.content.nodesBetween(e,a,n,i,this)}descendants(e){this.nodesBetween(0,this.content.size,e)}get textContent(){return this.isLeaf&&this.type.spec.leafText?this.type.spec.leafText(this):this.textBetween(0,this.content.size,"")}textBetween(e,a,n,i){return this.content.textBetween(e,a,n,i)}get firstChild(){return this.content.firstChild}get lastChild(){return this.content.lastChild}eq(e){return this==e||this.sameMarkup(e)&&this.content.eq(e.content)}sameMarkup(e){return this.hasMarkup(e.type,e.attrs,e.marks)}hasMarkup(e,a,n){return this.type==e&&Kh(this.attrs,a||e.defaultAttrs||gie)&&qe.sameSet(this.marks,n||qe.none)}copy(e=null){return e==this.content?this:new Rn(this.type,this.attrs,e,this.marks)}mark(e){return e==this.marks?this:new Rn(this.type,this.attrs,this.content,e)}cut(e,a=this.content.size){return e==0&&a==this.content.size?this:this.copy(this.content.cut(e,a))}slice(e,a=this.content.size,n=!1){if(e==a)return K.empty;let i=this.resolve(e),r=this.resolve(a),o=n?0:i.sharedDepth(a),l=i.start(o),d=i.node(o).content.cut(i.pos-l,r.pos-l);return new K(d,i.depth-o,r.depth-o)}replace(e,a,n){return pie(this.resolve(e),this.resolve(a),n)}nodeAt(e){for(let a=this;;){let{index:n,offset:i}=a.content.findIndex(e);if(a=a.maybeChild(n),!a)return null;if(i==e||a.isText)return a;e-=i+1}}childAfter(e){let{index:a,offset:n}=this.content.findIndex(e);return{node:this.content.maybeChild(a),index:a,offset:n}}childBefore(e){if(e==0)return{node:null,index:0,offset:0};let{index:a,offset:n}=this.content.findIndex(e);if(n<e)return{node:this.content.child(a),index:a,offset:n};let i=this.content.child(a-1);return{node:i,index:a-1,offset:n-i.nodeSize}}resolve(e){return du.resolveCached(this,e)}resolveNoCache(e){return du.resolve(this,e)}rangeHasMark(e,a,n){let i=!1;return a>e&&this.nodesBetween(e,a,r=>(n.isInSet(r.marks)&&(i=!0),!i)),i}get isBlock(){return this.type.isBlock}get isTextblock(){return this.type.isTextblock}get inlineContent(){return this.type.inlineContent}get isInline(){return this.type.isInline}get isText(){return this.type.isText}get isLeaf(){return this.type.isLeaf}get isAtom(){return this.type.isAtom}toString(){if(this.type.spec.toDebugString)return this.type.spec.toDebugString(this);let e=this.type.name;return this.content.size&&(e+="("+this.content.toStringInner()+")"),GO(this.marks,e)}contentMatchAt(e){let a=this.type.contentMatch.matchFragment(this.content,0,e);if(!a)throw new Error("Called contentMatchAt on a node with invalid content");return a}canReplace(e,a,n=V.empty,i=0,r=n.childCount){let o=this.contentMatchAt(e).matchFragment(n,i,r),l=o&&o.matchFragment(this.content,a);if(!l||!l.validEnd)return!1;for(let c=i;c<r;c++)if(!this.type.allowsMarks(n.child(c).marks))return!1;return!0}canReplaceWith(e,a,n,i){if(i&&!this.type.allowsMarks(i))return!1;let r=this.contentMatchAt(e).matchType(n),o=r&&r.matchFragment(this.content,a);return o?o.validEnd:!1}canAppend(e){return e.content.size?this.canReplace(this.childCount,this.childCount,e.content):this.type.compatibleContent(e.type)}check(){this.type.checkContent(this.content),this.type.checkAttrs(this.attrs);let e=qe.none;for(let a=0;a<this.marks.length;a++){let n=this.marks[a];n.type.checkAttrs(n.attrs),e=n.addToSet(e)}if(!qe.sameSet(e,this.marks))throw new RangeError(`Invalid collection of marks for node ${this.type.name}: ${this.marks.map(a=>a.type.name)}`);this.content.forEach(a=>a.check())}toJSON(){let e={type:this.type.name};for(let a in this.attrs){e.attrs=this.attrs;break}return this.content.size&&(e.content=this.content.toJSON()),this.marks.length&&(e.marks=this.marks.map(a=>a.toJSON())),e}static fromJSON(e,a){if(!a)throw new RangeError("Invalid input for Node.fromJSON");let n;if(a.marks){if(!Array.isArray(a.marks))throw new RangeError("Invalid mark data for Node.fromJSON");n=a.marks.map(e.markFromJSON)}if(a.type=="text"){if(typeof a.text!="string")throw new RangeError("Invalid text node in JSON");return e.text(a.text,n)}let i=V.fromJSON(e,a.content),r=e.nodeType(a.type).create(a.attrs,i,n);return r.type.checkAttrs(r.attrs),r}}Rn.prototype.text=void 0;class Yh extends Rn{constructor(e,a,n,i){if(super(e,a,null,i),!n)throw new RangeError("Empty text nodes are not allowed");this.text=n}toString(){return this.type.spec.toDebugString?this.type.spec.toDebugString(this):GO(this.marks,JSON.stringify(this.text))}get textContent(){return this.text}textBetween(e,a){return this.text.slice(e,a)}get nodeSize(){return this.text.length}mark(e){return e==this.marks?this:new Yh(this.type,this.attrs,this.text,e)}withText(e){return e==this.text?this:new Yh(this.type,this.attrs,e,this.marks)}cut(e=0,a=this.text.length){return e==0&&a==this.text.length?this:this.withText(this.text.slice(e,a))}eq(e){return this.sameMarkup(e)&&this.text==e.text}toJSON(){let e=super.toJSON();return e.text=this.text,e}}function GO(t,e){for(let a=t.length-1;a>=0;a--)e=t[a].type.name+"("+e+")";return e}class as{constructor(e){this.validEnd=e,this.next=[],this.wrapCache=[]}static parse(e,a){let n=new yie(e,a);if(n.next==null)return as.empty;let i=KO(n);n.next&&n.err("Unexpected trailing text");let r=_ie(Sie(i));return Aie(r,n),r}matchType(e){for(let a=0;a<this.next.length;a++)if(this.next[a].type==e)return this.next[a].next;return null}matchFragment(e,a=0,n=e.childCount){let i=this;for(let r=a;i&&r<n;r++)i=i.matchType(e.child(r).type);return i}get inlineContent(){return this.next.length!=0&&this.next[0].type.isInline}get defaultType(){for(let e=0;e<this.next.length;e++){let{type:a}=this.next[e];if(!(a.isText||a.hasRequiredAttrs()))return a}return null}compatible(e){for(let a=0;a<this.next.length;a++)for(let n=0;n<e.next.length;n++)if(this.next[a].type==e.next[n].type)return!0;return!1}fillBefore(e,a=!1,n=0){let i=[this];function r(o,l){let c=o.matchFragment(e,n);if(c&&(!a||c.validEnd))return V.from(l.map(d=>d.createAndFill()));for(let d=0;d<o.next.length;d++){let{type:u,next:p}=o.next[d];if(!(u.isText||u.hasRequiredAttrs())&&i.indexOf(p)==-1){i.push(p);let m=r(p,l.concat(u));if(m)return m}}return null}return r(this,[])}findWrapping(e){for(let n=0;n<this.wrapCache.length;n+=2)if(this.wrapCache[n]==e)return this.wrapCache[n+1];let a=this.computeWrapping(e);return this.wrapCache.push(e,a),a}computeWrapping(e){let a=Object.create(null),n=[{match:this,type:null,via:null}];for(;n.length;){let i=n.shift(),r=i.match;if(r.matchType(e)){let o=[];for(let l=i;l.type;l=l.via)o.push(l.type);return o.reverse()}for(let o=0;o<r.next.length;o++){let{type:l,next:c}=r.next[o];!l.isLeaf&&!l.hasRequiredAttrs()&&!(l.name in a)&&(!i.type||c.validEnd)&&(n.push({match:l.contentMatch,type:l,via:i}),a[l.name]=!0)}}return null}get edgeCount(){return this.next.length}edge(e){if(e>=this.next.length)throw new RangeError(`There's no ${e}th edge in this content match`);return this.next[e]}toString(){let e=[];function a(n){e.push(n);for(let i=0;i<n.next.length;i++)e.indexOf(n.next[i].next)==-1&&a(n.next[i].next)}return a(this),e.map((n,i)=>{let r=i+(n.validEnd?"*":" ")+" ";for(let o=0;o<n.next.length;o++)r+=(o?", ":"")+n.next[o].type.name+"->"+e.indexOf(n.next[o].next);return r}).join(`
17631`)}}as.empty=new as(!0);class yie{constructor(e,a){this.string=e,this.nodeTypes=a,this.inline=null,this.pos=0,this.tokens=e.split(/\s*(?=\b|\W|$)/),this.tokens[this.tokens.length-1]==""&&this.tokens.pop(),this.tokens[0]==""&&this.tokens.shift()}get next(){return this.tokens[this.pos]}eat(e){return this.next==e&&(this.pos++||!0)}err(e){throw new SyntaxError(e+" (in content expression '"+this.string+"')")}}function KO(t){let e=[];do e.push(xie(t));while(t.eat("|"));return e.length==1?e[0]:{type:"choice",exprs:e}}function xie(t){let e=[];do e.push(vie(t));while(t.next&&t.next!=")"&&t.next!="|");return e.length==1?e[0]:{type:"seq",exprs:e}}function vie(t){let e=kie(t);for(;;)if(t.eat("+"))e={type:"plus",expr:e};else if(t.eat("*"))e={type:"star",expr:e};else if(t.eat("?"))e={type:"opt",expr:e};else if(t.eat("{"))e=bie(t,e);else break;return e}function kj(t){/\D/.test(t.next)&&t.err("Expected number, got '"+t.next+"'");let e=Number(t.next);return t.pos++,e}function bie(t,e){let a=kj(t),n=a;return t.eat(",")&&(t.next!="}"?n=kj(t):n=-1),t.eat("}")||t.err("Unclosed braced range"),{type:"range",min:a,max:n,expr:e}}function wie(t,e){let a=t.nodeTypes,n=a[e];if(n)return[n];let i=[];for(let r in a){let o=a[r];o.isInGroup(e)&&i.push(o)}return i.length==0&&t.err("No node type or group '"+e+"' found"),i}function kie(t){if(t.eat("(")){let e=KO(t);return t.eat(")")||t.err("Missing closing paren"),e}else if(/\W/.test(t.next))t.err("Unexpected token '"+t.next+"'");else{let e=wie(t,t.next).map(a=>(t.inline==null?t.inline=a.isInline:t.inline!=a.isInline&&t.err("Mixing inline and block content"),{type:"name",value:a}));return t.pos++,e.length==1?e[0]:{type:"choice",exprs:e}}}function Sie(t){let e=[[]];return i(r(t,0),a()),e;function a(){return e.push([])-1}function n(o,l,c){let d={term:c,to:l};return e[o].push(d),d}function i(o,l){o.forEach(c=>c.to=l)}function r(o,l){if(o.type=="choice")return o.exprs.reduce((c,d)=>c.concat(r(d,l)),[]);if(o.type=="seq")for(let c=0;;c++){let d=r(o.exprs[c],l);if(c==o.exprs.length-1)return d;i(d,l=a())}else if(o.type=="star"){let c=a();return n(l,c),i(r(o.expr,c),c),[n(c)]}else if(o.type=="plus"){let c=a();return i(r(o.expr,l),c),i(r(o.expr,c),c),[n(c)]}else{if(o.type=="opt")return[n(l)].concat(r(o.expr,l));if(o.type=="range"){let c=l;for(let d=0;d<o.min;d++){let u=a();i(r(o.expr,c),u),c=u}if(o.max==-1)i(r(o.expr,c),c);else for(let d=o.min;d<o.max;d++){let u=a();n(c,u),i(r(o.expr,c),u),c=u}return[n(c)]}else{if(o.type=="name")return[n(l,void 0,o.value)];throw new Error("Unknown expr type")}}}}function JO(t,e){return e-t}function Sj(t,e){let a=[];return n(e),a.sort(JO);function n(i){let r=t[i];if(r.length==1&&!r[0].term)return n(r[0].to);a.push(i);for(let o=0;o<r.length;o++){let{term:l,to:c}=r[o];!l&&a.indexOf(c)==-1&&n(c)}}}function _ie(t){let e=Object.create(null);return a(Sj(t,0));function a(n){let i=[];n.forEach(o=>{t[o].forEach(({term:l,to:c})=>{if(!l)return;let d;for(let u=0;u<i.length;u++)i[u][0]==l&&(d=i[u][1]);Sj(t,c).forEach(u=>{d||i.push([l,d=[]]),d.indexOf(u)==-1&&d.push(u)})})});let r=e[n.join(",")]=new as(n.indexOf(t.length-1)>-1);for(let o=0;o<i.length;o++){let l=i[o][1].sort(JO);r.next.push({type:i[o][0],next:e[l.join(",")]||a(l)})}return r}}function Aie(t,e){for(let a=0,n=[t];a<n.length;a++){let i=n[a],r=!i.validEnd,o=[];for(let l=0;l<i.next.length;l++){let{type:c,next:d}=i.next[l];o.push(c.name),r&&!(c.isText||c.hasRequiredAttrs())&&(r=!1),n.indexOf(d)==-1&&n.push(d)}r&&e.err("Only non-generatable nodes ("+o.join(", ")+") in a required position (see https://prosemirror.net/docs/guide/#generatable)")}}function QO(t){let e=Object.create(null);for(let a in t){let n=t[a];if(!n.hasDefault)return null;e[a]=n.default}return e}function XO(t,e){let a=Object.create(null);for(let n in t){let i=e&&e[n];if(i===void 0){let r=t[n];if(r.hasDefault)i=r.default;else throw new RangeError("No value supplied for attribute "+n)}a[n]=i}return a}function YO(t,e,a,n){for(let i in e)if(!(i in t))throw new RangeError(`Unsupported attribute ${i} for ${a} of type ${i}`);for(let i in t){let r=t[i];r.validate&&r.validate(e[i])}}function ZO(t,e){let a=Object.create(null);if(e)for(let n in e)a[n]=new Cie(t,n,e[n]);return a}let _j=class eM{constructor(e,a,n){this.name=e,this.schema=a,this.spec=n,this.markSet=null,this.groups=n.group?n.group.split(" "):[],this.attrs=ZO(e,n.attrs),this.defaultAttrs=QO(this.attrs),this.contentMatch=null,this.inlineContent=null,this.isBlock=!(n.inline||e=="text"),this.isText=e=="text"}get isInline(){return!this.isBlock}get isTextblock(){return this.isBlock&&this.inlineContent}get isLeaf(){return this.contentMatch==as.empty}get isAtom(){return this.isLeaf||!!this.spec.atom}isInGroup(e){return this.groups.indexOf(e)>-1}get whitespace(){return this.spec.whitespace||(this.spec.code?"pre":"normal")}hasRequiredAttrs(){for(let e in this.attrs)if(this.attrs[e].isRequired)return!0;return!1}compatibleContent(e){return this==e||this.contentMatch.compatible(e.contentMatch)}computeAttrs(e){return!e&&this.defaultAttrs?this.defaultAttrs:XO(this.attrs,e)}create(e=null,a,n){if(this.isText)throw new Error("NodeType.create can't construct text nodes");return new Rn(this,this.computeAttrs(e),V.from(a),qe.setFrom(n))}createChecked(e=null,a,n){return a=V.from(a),this.checkContent(a),new Rn(this,this.computeAttrs(e),a,qe.setFrom(n))}createAndFill(e=null,a,n){if(e=this.computeAttrs(e),a=V.from(a),a.size){let o=this.contentMatch.fillBefore(a);if(!o)return null;a=o.append(a)}let i=this.contentMatch.matchFragment(a),r=i&&i.fillBefore(V.empty,!0);return r?new Rn(this,e,a.append(r),qe.setFrom(n)):null}validContent(e){let a=this.contentMatch.matchFragment(e);
vendor: 9,575 bytes, lines 17631-17632
17631if(!a||!a.validEnd)return!1;for(let n=0;n<e.childCount;n++)if(!this.allowsMarks(e.child(n).marks))return!1;return!0}checkContent(e){if(!this.validContent(e))throw new RangeError(`Invalid content for node ${this.name}: ${e.toString().slice(0,50)}`)}checkAttrs(e){YO(this.attrs,e,"node",this.name)}allowsMarkType(e){return this.markSet==null||this.markSet.indexOf(e)>-1}allowsMarks(e){if(this.markSet==null)return!0;for(let a=0;a<e.length;a++)if(!this.allowsMarkType(e[a].type))return!1;return!0}allowedMarks(e){if(this.markSet==null)return e;let a;for(let n=0;n<e.length;n++)this.allowsMarkType(e[n].type)?a&&a.push(e[n]):a||(a=e.slice(0,n));return a?a.length?a:qe.none:e}static compile(e,a){let n=Object.create(null);e.forEach((r,o)=>n[r]=new eM(r,a,o));let i=a.spec.topNode||"doc";if(!n[i])throw new RangeError("Schema is missing its top node type ('"+i+"')");if(!n.text)throw new RangeError("Every schema needs a 'text' type");for(let r in n.text.attrs)throw new RangeError("The text node type should not have attributes");return n}};function Eie(t,e,a){let n=a.split("|");return i=>{let r=i===null?"null":typeof i;if(n.indexOf(r)<0)throw new RangeError(`Expected value of type ${n} for attribute ${e} on type ${t}, got ${r}`)}}class Cie{constructor(e,a,n){this.hasDefault=Object.prototype.hasOwnProperty.call(n,"default"),this.default=n.default,this.validate=typeof n.validate=="string"?Eie(e,a,n.validate):n.validate}get isRequired(){return!this.hasDefault}}class Dg{constructor(e,a,n,i){this.name=e,this.rank=a,this.schema=n,this.spec=i,this.attrs=ZO(e,i.attrs),this.excluded=null;let r=QO(this.attrs);this.instance=r?new qe(this,r):null}create(e=null){return!e&&this.instance?this.instance:new qe(this,XO(this.attrs,e))}static compile(e,a){let n=Object.create(null),i=0;return e.forEach((r,o)=>n[r]=new Dg(r,i++,a,o)),n}removeFromSet(e){for(var a=0;a<e.length;a++)e[a].type==this&&(e=e.slice(0,a).concat(e.slice(a+1)),a--);return e}isInSet(e){for(let a=0;a<e.length;a++)if(e[a].type==this)return e[a]}checkAttrs(e){YO(this.attrs,e,"mark",this.name)}excludes(e){return this.excluded.indexOf(e)>-1}}class tM{constructor(e){this.linebreakReplacement=null,this.cached=Object.create(null);let a=this.spec={};for(let i in e)a[i]=e[i];a.nodes=Dt.from(e.nodes),a.marks=Dt.from(e.marks||{}),this.nodes=_j.compile(this.spec.nodes,this),this.marks=Dg.compile(this.spec.marks,this);let n=Object.create(null);for(let i in this.nodes){if(i in this.marks)throw new RangeError(i+" can not be both a node and a mark");let r=this.nodes[i],o=r.spec.content||"",l=r.spec.marks;if(r.contentMatch=n[o]||(n[o]=as.parse(o,this.nodes)),r.inlineContent=r.contentMatch.inlineContent,r.spec.linebreakReplacement){if(this.linebreakReplacement)throw new RangeError("Multiple linebreak nodes defined");if(!r.isInline||!r.isLeaf)throw new RangeError("Linebreak replacement nodes must be inline leaf nodes");this.linebreakReplacement=r}r.markSet=l=="_"?null:l?Aj(this,l.split(" ")):l==""||!r.inlineContent?[]:null}for(let i in this.marks){let r=this.marks[i],o=r.spec.excludes;r.excluded=o==null?[r]:o==""?[]:Aj(this,o.split(" "))}this.nodeFromJSON=i=>Rn.fromJSON(this,i),this.markFromJSON=i=>qe.fromJSON(this,i),this.topNodeType=this.nodes[this.spec.topNode||"doc"],this.cached.wrappings=Object.create(null)}node(e,a=null,n,i){if(typeof e=="string")e=this.nodeType(e);else if(e instanceof _j){if(e.schema!=this)throw new RangeError("Node type from different schema used ("+e.name+")")}else throw new RangeError("Invalid node type: "+e);return e.createChecked(a,n,i)}text(e,a){let n=this.nodes.text;return new Yh(n,n.defaultAttrs,e,qe.setFrom(a))}mark(e,a){return typeof e=="string"&&(e=this.marks[e]),e.create(a)}nodeType(e){let a=this.nodes[e];if(!a)throw new RangeError("Unknown node type: "+e);return a}}function Aj(t,e){let a=[];for(let n=0;n<e.length;n++){let i=e[n],r=t.marks[i],o=r;if(r)a.push(r);else for(let l in t.marks){let c=t.marks[l];(i=="_"||c.spec.group&&c.spec.group.split(" ").indexOf(i)>-1)&&a.push(o=c)}if(!o)throw new SyntaxError("Unknown mark type: '"+e[n]+"'")}return a}function jie(t){return t.tag!=null}function Tie(t){return t.style!=null}class Rr{constructor(e,a){this.schema=e,this.rules=a,this.tags=[],this.styles=[];let n=this.matchedStyles=[];a.forEach(i=>{if(jie(i))this.tags.push(i);else if(Tie(i)){let r=/[^=]*/.exec(i.style)[0];n.indexOf(r)<0&&n.push(r),this.styles.push(i)}}),this.normalizeLists=!this.tags.some(i=>{if(!/^(ul|ol)\b/.test(i.tag)||!i.node)return!1;let r=e.nodes[i.node];return r.contentMatch.matchType(r)})}parse(e,a={}){let n=new Cj(this,a,!1);return n.addAll(e,qe.none,a.from,a.to),n.finish()}parseSlice(e,a={}){let n=new Cj(this,a,!0);return n.addAll(e,qe.none,a.from,a.to),K.maxOpen(n.finish())}matchTag(e,a,n){for(let i=n?this.tags.indexOf(n)+1:0;i<this.tags.length;i++){let r=this.tags[i];if(Pie(e,r.tag)&&(r.namespace===void 0||e.namespaceURI==r.namespace)&&(!r.context||a.matchesContext(r.context))){if(r.getAttrs){let o=r.getAttrs(e);if(o===!1)continue;r.attrs=o||void 0}return r}}}matchStyle(e,a,n,i){for(let r=i?this.styles.indexOf(i)+1:0;r<this.styles.length;r++){let o=this.styles[r],l=o.style;if(!(l.indexOf(e)!=0||o.context&&!n.matchesContext(o.context)||l.length>e.length&&(l.charCodeAt(e.length)!=61||l.slice(e.length+1)!=a))){if(o.getAttrs){let c=o.getAttrs(a);if(c===!1)continue;o.attrs=c||void 0}return o}}}static schemaRules(e){let a=[];function n(i){let r=i.priority==null?50:i.priority,o=0;for(;o<a.length;o++){let l=a[o];if((l.priority==null?50:l.priority)<r)break}a.splice(o,0,i)}for(let i in e.marks){let r=e.marks[i].spec.parseDOM;r&&r.forEach(o=>{n(o=jj(o)),o.mark||o.ignore||o.clearMark||(o.mark=i)})}for(let i in e.nodes){let r=e.nodes[i].spec.parseDOM;r&&r.forEach(o=>{n(o=jj(o)),o.node||o.ignore||o.mark||(o.node=i)})}return a}static fromSchema(e){return e.cached.domParser||(e.cached.domParser=new Rr(e,Rr.schemaRules(e)))}}const aM={address:!0,article:!0,aside:!0,blockquote:!0,canvas:!0,dd:!0,div:!0,dl:!0,fieldset:!0,figcaption:!0,figure:!0,footer:!0,form:!0,h1:!0,h2:!0,h3:!0,h4:!0,h5:!0,h6:!0,header:!0,hgroup:!0,hr:!0,li:!0,noscript:!0,ol:!0,output:!0,p:!0,pre:!0,section:!0,table:!0,tfoot:!0,ul:!0},Nie={head:!0,noscript:!0,object:!0,script:!0,style:!0,title:!0},nM={ol:!0,ul:!0},uu=1,Ab=2,bd=4;function Ej(t,e,a){return e!=null?(e?uu:0)|(e==="full"?Ab:0):t&&t.whitespace=="pre"?uu|Ab:a&~bd}class Yp{constructor(e,a,n,i,r,o){this.type=e,this.attrs=a,this.marks=n,this.solid=i,this.options=o,this.content=[],this.activeMarks=qe.none,this.match=r||(o&bd?null:e.contentMatch)}findWrapping(e){if(!this.match){if(!this.type)return[];let a=this.type.contentMatch.fillBefore(V.from(e));if(a)this.match=this.type.contentMatch.matchFragment(a);else{let n=this.type.contentMatch,i;return(i=n.findWrapping(e.type))?(this.match=n,i):null}}return this.match.findWrapping(e.type)}finish(e){if(!(this.options&uu)){let n=this.content[this.content.length-1],i;if(n&&n.isText&&(i=/[ \t\r\n\u000c]+$/.exec(n.text))){let r=n;n.text.length==i[0].length?this.content.pop():this.content[this.content.length-1]=r.withText(r.text.slice(0,r.text.length-i[0].length))}}let a=V.from(this.content);return!e&&this.match&&(a=a.append(this.match.fillBefore(V.empty,!0))),this.type?this.type.create(this.attrs,a,this.marks):a}inlineContext(e){return this.type?this.type.inlineContent:this.content.length?this.content[0].isInline:e.parentNode&&!aM.hasOwnProperty(e.parentNode.nodeName.toLowerCase())}}class Cj{constructor(e,a,n){this.parser=e,this.options=a,this.isOpen=n,this.open=0,this.localPreserveWS=!1;let i=a.topNode,r,o=Ej(null,a.preserveWhitespace,0)|(n?bd:0);i?r=new Yp(i.type,i.attrs,qe.none,!0,a.topMatch||i.type.contentMatch,o):n?r=new Yp(null,null,qe.none,!0,null,o):r=new Yp(e.schema.topNodeType,null,qe.none,!0,null,o),this.nodes=[r],this.find=a.findPositions,this.needsBlock=!1}get top(){return this.nodes[this.open]}addDOM(e,a){e.nodeType==3?this.addTextNode(e,a):e.nodeType==1&&this.addElement(e,a)}addTextNode(e,a){let n=e.nodeValue,i=this.top,r=i.options&Ab?"full":this.localPreserveWS||(i.options&uu)>0,{schema:o}=this.parser;if(r==="full"||i.inlineContext(e)||/[^ \t\r\n\u000c]/.test(n)){if(r)if(r==="full")n=n.replace(/\r\n?/g,`
17632`);else if(o.linebreakReplacement&&/[\r\n]/.test(n)&&this.top.findWrapping(o.linebreakReplacement.create())){let l=n.split(/\r?\n|\r/);for(let c=0;c<l.length;c++)c&&this.insertNode(o.linebreakReplacement.create(),a,!0),l[c]&&this.insertNode(o.text(l[c]),a,!/\S/.test(l[c]));n=""}else n=n.replace(/\r?\n|\r/g," ");else if(n=n.replace(/[ \t\r\n\u000c]+/g," "),/^[ \t\r\n\u000c]/.test(n)&&this.open==this.nodes.length-1){let l=i.content[i.content.length-1],c=e.previousSibling;(!l||c&&c.nodeName=="BR"||l.isText&&/[ \t\r\n\u000c]$/.test(l.text))&&(n=n.slice(1))}n&&this.insertNode(o.text(n),a,!/\S/.test(n)),this.findInText(e)}else this.findInside(e)}addElement(e,a,n){let i=this.localPreserveWS,r=this.top;(e.tagName=="PRE"||/pre/.test(e.style&&e.style.whiteSpace))&&(this.localPreserveWS=!0);let o=e.nodeName.toLowerCase(),l;nM.hasOwnProperty(o)&&this.parser.normalizeLists&&Iie(e);let c=this.options.ruleFromNode&&this.options.ruleFromNode(e)||(l=this.parser.matchTag(e,this,n));e:if(c?c.ignore:Nie.hasOwnProperty(o))this.findInside(e),this.ignoreFallback(e,a);else if(!c||c.skip||c.closeParent){c&&c.closeParent?this.open=Math.max(0,this.open-1):c&&c.skip.nodeType&&(e=c.skip);let d,u=this.needsBlock;if(aM.hasOwnProperty(o))r.content.length&&r.content[0].isInline&&this.open&&(this.open--,r=this.top),d=!0,r.type||(this.needsBlock=!0);else if(!e.firstChild){this.leafFallback(e,a);break e}
vendor: 4,920 bytes, lines 17632-17633
17632let p=c&&c.skip?a:this.readStyles(e,a);p&&this.addAll(e,p),d&&this.sync(r),this.needsBlock=u}else{let d=this.readStyles(e,a);d&&this.addElementByRule(e,c,d,c.consuming===!1?l:void 0)}this.localPreserveWS=i}leafFallback(e,a){e.nodeName=="BR"&&this.top.type&&this.top.type.inlineContent&&this.addTextNode(e.ownerDocument.createTextNode(`
17633`),a)}ignoreFallback(e,a){e.nodeName=="BR"&&(!this.top.type||!this.top.type.inlineContent)&&this.findPlace(this.parser.schema.text("-"),a,!0)}readStyles(e,a){let n=e.style;if(n&&n.length)for(let i=0;i<this.parser.matchedStyles.length;i++){let r=this.parser.matchedStyles[i],o=n.getPropertyValue(r);if(o)for(let l=void 0;;){let c=this.parser.matchStyle(r,o,this,l);if(!c)break;if(c.ignore)return null;if(c.clearMark?a=a.filter(d=>!c.clearMark(d)):a=a.concat(this.parser.schema.marks[c.mark].create(c.attrs)),c.consuming===!1)l=c;else break}}return a}addElementByRule(e,a,n,i){let r,o;if(a.node)if(o=this.parser.schema.nodes[a.node],o.isLeaf)this.insertNode(o.create(a.attrs),n,e.nodeName=="BR")||this.leafFallback(e,n);else{let c=this.enter(o,a.attrs||null,n,a.preserveWhitespace);c&&(r=!0,n=c)}else{let c=this.parser.schema.marks[a.mark];n=n.concat(c.create(a.attrs))}let l=this.top;if(o&&o.isLeaf)this.findInside(e);else if(i)this.addElement(e,n,i);else if(a.getContent)this.findInside(e),a.getContent(e,this.parser.schema).forEach(c=>this.insertNode(c,n,!1));else{let c=e;typeof a.contentElement=="string"?c=e.querySelector(a.contentElement):typeof a.contentElement=="function"?c=a.contentElement(e):a.contentElement&&(c=a.contentElement),this.findAround(e,c,!0),this.addAll(c,n),this.findAround(e,c,!1)}r&&this.sync(l)&&this.open--}addAll(e,a,n,i){let r=n||0;for(let o=n?e.childNodes[n]:e.firstChild,l=i==null?null:e.childNodes[i];o!=l;o=o.nextSibling,++r)this.findAtPoint(e,r),this.addDOM(o,a);this.findAtPoint(e,r)}findPlace(e,a,n){let i,r;for(let o=this.open,l=0;o>=0;o--){let c=this.nodes[o],d=c.findWrapping(e);if(d&&(!i||i.length>d.length+l)&&(i=d,r=c,!d.length))break;if(c.solid){if(n)break;l+=2}}if(!i)return null;this.sync(r);for(let o=0;o<i.length;o++)a=this.enterInner(i[o],null,a,!1);return a}insertNode(e,a,n){if(e.isInline&&this.needsBlock&&!this.top.type){let r=this.textblockFromContext();r&&(a=this.enterInner(r,null,a))}let i=this.findPlace(e,a,n);if(i){this.closeExtra();let r=this.top;r.match&&(r.match=r.match.matchType(e.type));let o=qe.none;for(let l of i.concat(e.marks))(r.type?r.type.allowsMarkType(l.type):Tj(l.type,e.type))&&(o=l.addToSet(o));return r.content.push(e.mark(o)),!0}return!1}enter(e,a,n,i){let r=this.findPlace(e.create(a),n,!1);return r&&(r=this.enterInner(e,a,n,!0,i)),r}enterInner(e,a,n,i=!1,r){this.closeExtra();let o=this.top;o.match=o.match&&o.match.matchType(e);let l=Ej(e,r,o.options);o.options&bd&&o.content.length==0&&(l|=bd);let c=qe.none;return n=n.filter(d=>(o.type?o.type.allowsMarkType(d.type):Tj(d.type,e))?(c=d.addToSet(c),!1):!0),this.nodes.push(new Yp(e,a,c,i,null,l)),this.open++,n}closeExtra(e=!1){let a=this.nodes.length-1;if(a>this.open){for(;a>this.open;a--)this.nodes[a-1].content.push(this.nodes[a].finish(e));this.nodes.length=this.open+1}}finish(){return this.open=0,this.closeExtra(this.isOpen),this.nodes[0].finish(!!(this.isOpen||this.options.topOpen))}sync(e){for(let a=this.open;a>=0;a--){if(this.nodes[a]==e)return this.open=a,!0;this.localPreserveWS&&(this.nodes[a].options|=uu)}return!1}get currentPos(){this.closeExtra();let e=0;for(let a=this.open;a>=0;a--){let n=this.nodes[a].content;for(let i=n.length-1;i>=0;i--)e+=n[i].nodeSize;a&&e++}return e}findAtPoint(e,a){if(this.find)for(let n=0;n<this.find.length;n++)this.find[n].node==e&&this.find[n].offset==a&&(this.find[n].pos=this.currentPos)}findInside(e){if(this.find)for(let a=0;a<this.find.length;a++)this.find[a].pos==null&&e.nodeType==1&&e.contains(this.find[a].node)&&(this.find[a].pos=this.currentPos)}findAround(e,a,n){if(e!=a&&this.find)for(let i=0;i<this.find.length;i++)this.find[i].pos==null&&e.nodeType==1&&e.contains(this.find[i].node)&&a.compareDocumentPosition(this.find[i].node)&(n?2:4)&&(this.find[i].pos=this.currentPos)}findInText(e){if(this.find)for(let a=0;a<this.find.length;a++)this.find[a].node==e&&(this.find[a].pos=this.currentPos-(e.nodeValue.length-this.find[a].offset))}matchesContext(e){if(e.indexOf("|")>-1)return e.split(/\s*\|\s*/).some(this.matchesContext,this);let a=e.split("/"),n=this.options.context,i=!this.isOpen&&(!n||n.parent.type==this.nodes[0].type),r=-(n?n.depth+1:0)+(i?0:1),o=(l,c)=>{for(;l>=0;l--){let d=a[l];if(d==""){if(l==a.length-1||l==0)continue;for(;c>=r;c--)if(o(l-1,c))return!0;return!1}else{let u=c>0||c==0&&i?this.nodes[c].type:n&&c>=r?n.node(c-r).type:null;if(!u||u.name!=d&&!u.isInGroup(d))return!1;c--}}return!0};return o(a.length-1,this.open)}textblockFromContext(){let e=this.options.context;if(e)for(let a=e.depth;a>=0;a--){let n=e.node(a).contentMatchAt(e.indexAfter(a)).defaultType;
vendor: 8,890 bytes, line 17633
17633if(n&&n.isTextblock&&n.defaultAttrs)return n}for(let a in this.parser.schema.nodes){let n=this.parser.schema.nodes[a];if(n.isTextblock&&n.defaultAttrs)return n}}}function Iie(t){for(let e=t.firstChild,a=null;e;e=e.nextSibling){let n=e.nodeType==1?e.nodeName.toLowerCase():null;n&&nM.hasOwnProperty(n)&&a?(a.appendChild(e),e=a):n=="li"?a=e:n&&(a=null)}}function Pie(t,e){return(t.matches||t.msMatchesSelector||t.webkitMatchesSelector||t.mozMatchesSelector).call(t,e)}function jj(t){let e={};for(let a in t)e[a]=t[a];return e}function Tj(t,e){let a=e.schema.nodes;for(let n in a){let i=a[n];if(!i.allowsMarkType(t))continue;let r=[],o=l=>{r.push(l);for(let c=0;c<l.edgeCount;c++){let{type:d,next:u}=l.edge(c);if(d==e||r.indexOf(u)<0&&o(u))return!0}};if(o(i.contentMatch))return!0}}class fs{constructor(e,a){this.nodes=e,this.marks=a}serializeFragment(e,a={},n){n||(n=U0(a).createDocumentFragment());let i=n,r=[];return e.forEach(o=>{if(r.length||o.marks.length){let l=0,c=0;for(;l<r.length&&c<o.marks.length;){let d=o.marks[c];if(!this.marks[d.type.name]){c++;continue}if(!d.eq(r[l][0])||d.type.spec.spanning===!1)break;l++,c++}for(;l<r.length;)i=r.pop()[1];for(;c<o.marks.length;){let d=o.marks[c++],u=this.serializeMark(d,o.isInline,a);u&&(r.push([d,i]),i.appendChild(u.dom),i=u.contentDOM||u.dom)}}i.appendChild(this.serializeNodeInner(o,a))}),n}serializeNodeInner(e,a){let{dom:n,contentDOM:i}=Bm(U0(a),this.nodes[e.type.name](e),null,e.attrs);if(i){if(e.isLeaf)throw new RangeError("Content hole not allowed in a leaf node spec");this.serializeFragment(e.content,a,i)}return n}serializeNode(e,a={}){let n=this.serializeNodeInner(e,a);for(let i=e.marks.length-1;i>=0;i--){let r=this.serializeMark(e.marks[i],e.isInline,a);r&&((r.contentDOM||r.dom).appendChild(n),n=r.dom)}return n}serializeMark(e,a,n={}){let i=this.marks[e.type.name];return i&&Bm(U0(n),i(e,a),null,e.attrs)}static renderSpec(e,a,n=null,i){return Bm(e,a,n,i)}static fromSchema(e){return e.cached.domSerializer||(e.cached.domSerializer=new fs(this.nodesFromSchema(e),this.marksFromSchema(e)))}static nodesFromSchema(e){let a=Nj(e.nodes);return a.text||(a.text=n=>n.text),a}static marksFromSchema(e){return Nj(e.marks)}}function Nj(t){let e={};for(let a in t){let n=t[a].spec.toDOM;n&&(e[a]=n)}return e}function U0(t){return t.document||window.document}const Ij=new WeakMap;function Rie(t){let e=Ij.get(t);return e===void 0&&Ij.set(t,e=Lie(t)),e}function Lie(t){let e=null;function a(n){if(n&&typeof n=="object")if(Array.isArray(n))if(typeof n[0]=="string")e||(e=[]),e.push(n);else for(let i=0;i<n.length;i++)a(n[i]);else for(let i in n)a(n[i])}return a(t),e}function Bm(t,e,a,n){if(typeof e=="string")return{dom:t.createTextNode(e)};if(e.nodeType!=null)return{dom:e};if(e.dom&&e.dom.nodeType!=null)return e;let i=e[0],r;if(typeof i!="string")throw new RangeError("Invalid array passed to renderSpec");if(n&&(r=Rie(n))&&r.indexOf(e)>-1)throw new RangeError("Using an array from an attribute object as a DOM spec. This may be an attempted cross site scripting attack.");let o=i.indexOf(" ");o>0&&(a=i.slice(0,o),i=i.slice(o+1));let l,c=a?t.createElementNS(a,i):t.createElement(i),d=e[1],u=1;if(d&&typeof d=="object"&&d.nodeType==null&&!Array.isArray(d)){u=2;for(let p in d)if(d[p]!=null){let m=p.indexOf(" ");m>0?c.setAttributeNS(p.slice(0,m),p.slice(m+1),d[p]):p=="style"&&c.style?c.style.cssText=d[p]:c.setAttribute(p,d[p])}}for(let p=u;p<e.length;p++){let m=e[p];if(m===0){if(p<e.length-1||p>u)throw new RangeError("Content hole must be the only child of its parent node");return{dom:c,contentDOM:c}}else{let{dom:h,contentDOM:g}=Bm(t,m,a,n);if(c.appendChild(h),g){if(l)throw new RangeError("Multiple content holes");l=g}}}return{dom:c,contentDOM:l}}const iM=65535,rM=Math.pow(2,16);function Oie(t,e){return t+e*rM}function Pj(t){return t&iM}function Mie(t){return(t-(t&iM))/rM}const oM=1,sM=2,Um=4,lM=8;class Eb{constructor(e,a,n){this.pos=e,this.delInfo=a,this.recover=n}get deleted(){return(this.delInfo&lM)>0}get deletedBefore(){return(this.delInfo&(oM|Um))>0}get deletedAfter(){return(this.delInfo&(sM|Um))>0}get deletedAcross(){return(this.delInfo&Um)>0}}class qa{constructor(e,a=!1){if(this.ranges=e,this.inverted=a,!e.length&&qa.empty)return qa.empty}recover(e){let a=0,n=Pj(e);if(!this.inverted)for(let i=0;i<n;i++)a+=this.ranges[i*3+2]-this.ranges[i*3+1];return this.ranges[n*3]+a+Mie(e)}mapResult(e,a=1){return this._map(e,a,!1)}map(e,a=1){return this._map(e,a,!0)}_map(e,a,n){let i=0,r=this.inverted?2:1,o=this.inverted?1:2;for(let l=0;l<this.ranges.length;l+=3){let c=this.ranges[l]-(this.inverted?i:0);if(c>e)break;let d=this.ranges[l+r],u=this.ranges[l+o],p=c+d;if(e<=p){let m=d?e==c?-1:e==p?1:a:a,h=c+i+(m<0?0:u);if(n)return h;let g=e==(a<0?c:p)?null:Oie(l/3,e-c),y=e==c?sM:e==p?oM:Um;return(a<0?e!=c:e!=p)&&(y|=lM),new Eb(h,y,g)}i+=u-d}return n?e+i:new Eb(e+i,0,null)}touches(e,a){let n=0,i=Pj(a),r=this.inverted?2:1,o=this.inverted?1:2;for(let l=0;l<this.ranges.length;l+=3){let c=this.ranges[l]-(this.inverted?n:0);if(c>e)break;let d=this.ranges[l+r],u=c+d;if(e<=u&&l==i*3)return!0;n+=this.ranges[l+o]-d}return!1}forEach(e){let a=this.inverted?2:1,n=this.inverted?1:2;for(let i=0,r=0;i<this.ranges.length;i+=3){let o=this.ranges[i],l=o-(this.inverted?r:0),c=o+(this.inverted?0:r),d=this.ranges[i+a],u=this.ranges[i+n];e(l,l+d,c,c+u),r+=u-d}}invert(){return new qa(this.ranges,!this.inverted)}toString(){return(this.inverted?"-":"")+JSON.stringify(this.ranges)}static offset(e){return e==0?qa.empty:new qa(e<0?[0,-e,0]:[0,0,e])}}qa.empty=new qa([]);class pu{constructor(e,a,n=0,i=e?e.length:0){this.mirror=a,this.from=n,this.to=i,this._maps=e||[],this.ownData=!(e||a)}get maps(){return this._maps}slice(e=0,a=this.maps.length){return new pu(this._maps,this.mirror,e,a)}appendMap(e,a){this.ownData||(this._maps=this._maps.slice(),this.mirror=this.mirror&&this.mirror.slice(),this.ownData=!0),this.to=this._maps.push(e),a!=null&&this.setMirror(this._maps.length-1,a)}appendMapping(e){for(let a=0,n=this._maps.length;a<e._maps.length;a++){let i=e.getMirror(a);this.appendMap(e._maps[a],i!=null&&i<a?n+i:void 0)}}getMirror(e){if(this.mirror){for(let a=0;a<this.mirror.length;a++)if(this.mirror[a]==e)return this.mirror[a+(a%2?-1:1)]}}setMirror(e,a){this.mirror||(this.mirror=[]),this.mirror.push(e,a)}appendMappingInverted(e){for(let a=e.maps.length-1,n=this._maps.length+e._maps.length;a>=0;a--){let i=e.getMirror(a);this.appendMap(e._maps[a].invert(),i!=null&&i>a?n-i-1:void 0)}}invert(){let e=new pu;return e.appendMappingInverted(this),e}map(e,a=1){if(this.mirror)return this._map(e,a,!0);for(let n=this.from;n<this.to;n++)e=this._maps[n].map(e,a);return e}mapResult(e,a=1){return this._map(e,a,!1)}_map(e,a,n){let i=0;for(let r=this.from;r<this.to;r++){let o=this._maps[r],l=o.mapResult(e,a);if(l.recover!=null){let c=this.getMirror(r);if(c!=null&&c>r&&c<this.to){r=c,e=this._maps[c].recover(l.recover);continue}}i|=l.delInfo,e=l.pos}return n?e:new Eb(e,i,null)}}const $0=Object.create(null);class sa{getMap(){return qa.empty}merge(e){return null}static fromJSON(e,a){if(!a||!a.stepType)throw new RangeError("Invalid input for Step.fromJSON");let n=$0[a.stepType];if(!n)throw new RangeError(`No step type ${a.stepType} defined`);return n.fromJSON(e,a)}static jsonID(e,a){if(e in $0)throw new RangeError("Duplicate use of step JSON ID "+e);return $0[e]=a,a.prototype.jsonID=e,a}}class yt{constructor(e,a){this.doc=e,this.failed=a}static ok(e){return new yt(e,null)}static fail(e){return new yt(null,e)}static fromReplace(e,a,n,i){try{return yt.ok(e.replace(a,n,i))}catch(r){if(r instanceof Jh)return yt.fail(r.message);throw r}}}function Jk(t,e,a){let n=[];for(let i=0;i<t.childCount;i++){let r=t.child(i);r.content.size&&(r=r.copy(Jk(r.content,e,r))),r.isInline&&(r=e(r,a,i)),n.push(r)}return V.fromArray(n)}class xr extends sa{constructor(e,a,n){super(),this.from=e,this.to=a,this.mark=n}apply(e){let a=e.slice(this.from,this.to),n=e.resolve(this.from),i=n.node(n.sharedDepth(this.to)),r=new K(Jk(a.content,(o,l)=>!o.isAtom||!l.type.allowsMarkType(this.mark.type)?o:o.mark(this.mark.addToSet(o.marks)),i),a.openStart,a.openEnd);return yt.fromReplace(e,this.from,this.to,r)}invert(){return new jn(this.from,this.to,this.mark)}map(e){let a=e.mapResult(this.from,1),n=e.mapResult(this.to,-1);return a.deleted&&n.deleted||a.pos>=n.pos?null:new xr(a.pos,n.pos,this.mark)}merge(e){return e instanceof xr&&e.mark.eq(this.mark)&&this.from<=e.to&&this.to>=e.from?new xr(Math.min(this.from,e.from),Math.max(this.to,e.to),this.mark):null}toJSON(){return{stepType:"addMark",mark:this.mark.toJSON(),from:this.from,to:this.to}}static fromJSON(e,a){if(typeof a.from!="number"||typeof a.to!="number")throw new RangeError("Invalid input for AddMarkStep.fromJSON");return new xr(a.from,a.to,e.markFromJSON(a.mark))}}sa.jsonID("addMark",xr);class jn extends sa{constructor(e,a,n){super(),this.from=e,this.to=a,this.mark=n}
vendor: 6,481 bytes, line 17633
17633apply(e){let a=e.slice(this.from,this.to),n=new K(Jk(a.content,i=>i.mark(this.mark.removeFromSet(i.marks)),e),a.openStart,a.openEnd);return yt.fromReplace(e,this.from,this.to,n)}invert(){return new xr(this.from,this.to,this.mark)}map(e){let a=e.mapResult(this.from,1),n=e.mapResult(this.to,-1);return a.deleted&&n.deleted||a.pos>=n.pos?null:new jn(a.pos,n.pos,this.mark)}merge(e){return e instanceof jn&&e.mark.eq(this.mark)&&this.from<=e.to&&this.to>=e.from?new jn(Math.min(this.from,e.from),Math.max(this.to,e.to),this.mark):null}toJSON(){return{stepType:"removeMark",mark:this.mark.toJSON(),from:this.from,to:this.to}}static fromJSON(e,a){if(typeof a.from!="number"||typeof a.to!="number")throw new RangeError("Invalid input for RemoveMarkStep.fromJSON");return new jn(a.from,a.to,e.markFromJSON(a.mark))}}sa.jsonID("removeMark",jn);class vr extends sa{constructor(e,a){super(),this.pos=e,this.mark=a}apply(e){let a=e.nodeAt(this.pos);if(!a)return yt.fail("No node at mark step's position");let n=a.type.create(a.attrs,null,this.mark.addToSet(a.marks));return yt.fromReplace(e,this.pos,this.pos+1,new K(V.from(n),0,a.isLeaf?0:1))}invert(e){let a=e.nodeAt(this.pos);if(a){let n=this.mark.addToSet(a.marks);if(n.length==a.marks.length){for(let i=0;i<a.marks.length;i++)if(!a.marks[i].isInSet(n))return new vr(this.pos,a.marks[i]);return new vr(this.pos,this.mark)}}return new ns(this.pos,this.mark)}map(e){let a=e.mapResult(this.pos,1);return a.deletedAfter?null:new vr(a.pos,this.mark)}toJSON(){return{stepType:"addNodeMark",pos:this.pos,mark:this.mark.toJSON()}}static fromJSON(e,a){if(typeof a.pos!="number")throw new RangeError("Invalid input for AddNodeMarkStep.fromJSON");return new vr(a.pos,e.markFromJSON(a.mark))}}sa.jsonID("addNodeMark",vr);class ns extends sa{constructor(e,a){super(),this.pos=e,this.mark=a}apply(e){let a=e.nodeAt(this.pos);if(!a)return yt.fail("No node at mark step's position");let n=a.type.create(a.attrs,null,this.mark.removeFromSet(a.marks));return yt.fromReplace(e,this.pos,this.pos+1,new K(V.from(n),0,a.isLeaf?0:1))}invert(e){let a=e.nodeAt(this.pos);return!a||!this.mark.isInSet(a.marks)?this:new vr(this.pos,this.mark)}map(e){let a=e.mapResult(this.pos,1);return a.deletedAfter?null:new ns(a.pos,this.mark)}toJSON(){return{stepType:"removeNodeMark",pos:this.pos,mark:this.mark.toJSON()}}static fromJSON(e,a){if(typeof a.pos!="number")throw new RangeError("Invalid input for RemoveNodeMarkStep.fromJSON");return new ns(a.pos,e.markFromJSON(a.mark))}}sa.jsonID("removeNodeMark",ns);class Tt extends sa{constructor(e,a,n,i=!1){super(),this.from=e,this.to=a,this.slice=n,this.structure=i}apply(e){return this.structure&&Cb(e,this.from,this.to)?yt.fail("Structure replace would overwrite content"):yt.fromReplace(e,this.from,this.to,this.slice)}getMap(){return new qa([this.from,this.to-this.from,this.slice.size])}invert(e){return new Tt(this.from,this.from+this.slice.size,e.slice(this.from,this.to))}map(e){let a=e.mapResult(this.from,1),n=e.mapResult(this.to,-1);return a.deletedAcross&&n.deletedAcross?null:new Tt(a.pos,Math.max(a.pos,n.pos),this.slice,this.structure)}merge(e){if(!(e instanceof Tt)||e.structure||this.structure)return null;if(this.from+this.slice.size==e.from&&!this.slice.openEnd&&!e.slice.openStart){let a=this.slice.size+e.slice.size==0?K.empty:new K(this.slice.content.append(e.slice.content),this.slice.openStart,e.slice.openEnd);return new Tt(this.from,this.to+(e.to-e.from),a,this.structure)}else if(e.to==this.from&&!this.slice.openStart&&!e.slice.openEnd){let a=this.slice.size+e.slice.size==0?K.empty:new K(e.slice.content.append(this.slice.content),e.slice.openStart,this.slice.openEnd);return new Tt(e.from,this.to,a,this.structure)}else return null}toJSON(){let e={stepType:"replace",from:this.from,to:this.to};return this.slice.size&&(e.slice=this.slice.toJSON()),this.structure&&(e.structure=!0),e}static fromJSON(e,a){if(typeof a.from!="number"||typeof a.to!="number")throw new RangeError("Invalid input for ReplaceStep.fromJSON");return new Tt(a.from,a.to,K.fromJSON(e,a.slice),!!a.structure)}}sa.jsonID("replace",Tt);class Pt extends sa{constructor(e,a,n,i,r,o,l=!1){super(),this.from=e,this.to=a,this.gapFrom=n,this.gapTo=i,this.slice=r,this.insert=o,this.structure=l}apply(e){if(this.structure&&(Cb(e,this.from,this.gapFrom)||Cb(e,this.gapTo,this.to)))return yt.fail("Structure gap-replace would overwrite content");let a=e.slice(this.gapFrom,this.gapTo);if(a.openStart||a.openEnd)return yt.fail("Gap is not a flat range");let n=this.slice.insertAt(this.insert,a.content);return n?yt.fromReplace(e,this.from,this.to,n):yt.fail("Content does not fit in gap")}getMap(){return new qa([this.from,this.gapFrom-this.from,this.insert,this.gapTo,this.to-this.gapTo,this.slice.size-this.insert])}invert(e){let a=this.gapTo-this.gapFrom;return new Pt(this.from,this.from+this.slice.size+a,this.from+this.insert,this.from+this.insert+a,e.slice(this.from,this.to).removeBetween(this.gapFrom-this.from,this.gapTo-this.from),this.gapFrom-this.from,this.structure)}map(e){let a=e.mapResult(this.from,1),n=e.mapResult(this.to,-1),i=this.from==this.gapFrom?a.pos:e.map(this.gapFrom,-1),r=this.to==this.gapTo?n.pos:e.map(this.gapTo,1);return a.deletedAcross&&n.deletedAcross||i<a.pos||r>n.pos?null:new Pt(a.pos,n.pos,i,r,this.slice,this.insert,this.structure)}toJSON(){let e={stepType:"replaceAround",from:this.from,to:this.to,gapFrom:this.gapFrom,gapTo:this.gapTo,insert:this.insert};return this.slice.size&&(e.slice=this.slice.toJSON()),this.structure&&(e.structure=!0),e}static fromJSON(e,a){if(typeof a.from!="number"||typeof a.to!="number"||typeof a.gapFrom!="number"||typeof a.gapTo!="number"||typeof a.insert!="number")throw new RangeError("Invalid input for ReplaceAroundStep.fromJSON");return new Pt(a.from,a.to,a.gapFrom,a.gapTo,K.fromJSON(e,a.slice),a.insert,!!a.structure)}}sa.jsonID("replaceAround",Pt);function Cb(t,e,a){let n=t.resolve(e),i=a-e,r=n.depth;for(;i>0&&r>0&&n.indexAfter(r)==n.node(r).childCount;)r--,i--;if(i>0){let o=n.node(r).maybeChild(n.indexAfter(r));for(;i>0;){if(!o||o.isLeaf)return!0;o=o.firstChild,i--}}return!1}function Die(t,e,a,n){let i=[],r=[],o,l;t.doc.nodesBetween(e,a,(c,d,u)=>{if(!c.isInline)return;let p=c.marks;if(!n.isInSet(p)&&u.type.allowsMarkType(n.type)){let m=Math.max(d,e),h=Math.min(d+c.nodeSize,a),g=n.addToSet(p);for(let y=0;y<p.length;y++)p[y].isInSet(g)||(o&&o.to==m&&o.mark.eq(p[y])?o.to=h:i.push(o=new jn(m,h,p[y])));l&&l.to==m?l.to=h:r.push(l=new xr(m,h,n))}}
vendor: 4,283 bytes, lines 17633-17634
17633),i.forEach(c=>t.step(c)),r.forEach(c=>t.step(c))}function qie(t,e,a,n){let i=[],r=0;t.doc.nodesBetween(e,a,(o,l)=>{if(!o.isInline)return;r++;let c=null;if(n instanceof Dg){let d=o.marks,u;for(;u=n.isInSet(d);)(c||(c=[])).push(u),d=u.removeFromSet(d)}else n?n.isInSet(o.marks)&&(c=[n]):c=o.marks;if(c&&c.length){let d=Math.min(l+o.nodeSize,a);for(let u=0;u<c.length;u++){let p=c[u],m;for(let h=0;h<i.length;h++){let g=i[h];g.step==r-1&&p.eq(i[h].style)&&(m=g)}m?(m.to=d,m.step=r):i.push({style:p,from:Math.max(l,e),to:d,step:r})}}}),i.forEach(o=>t.step(new jn(o.from,o.to,o.style)))}function Qk(t,e,a,n=a.contentMatch,i=!0){let r=t.doc.nodeAt(e),o=[],l=e+1;for(let c=0;c<r.childCount;c++){let d=r.child(c),u=l+d.nodeSize,p=n.matchType(d.type);if(!p)o.push(new Tt(l,u,K.empty));else{n=p;for(let m=0;m<d.marks.length;m++)a.allowsMarkType(d.marks[m].type)||t.step(new jn(l,u,d.marks[m]));if(i&&d.isText&&a.whitespace!="pre"){let m,h=/\r?\n|\r/g,g;for(;m=h.exec(d.text);)g||(g=new K(V.from(a.schema.text(" ",a.allowedMarks(d.marks))),0,0)),o.push(new Tt(l+m.index,l+m.index+m[0].length,g))}}l=u}if(!n.validEnd){let c=n.fillBefore(V.empty,!0);t.replace(l,l,new K(c,0,0))}for(let c=o.length-1;c>=0;c--)t.step(o[c])}function zie(t,e,a){return(e==0||t.canReplace(e,t.childCount))&&(a==t.childCount||t.canReplace(0,a))}function ec(t){let a=t.parent.content.cutByIndex(t.startIndex,t.endIndex);for(let n=t.depth,i=0,r=0;;--n){let o=t.$from.node(n),l=t.$from.index(n)+i,c=t.$to.indexAfter(n)-r;if(n<t.depth&&o.canReplace(l,c,a))return n;if(n==0||o.type.spec.isolating||!zie(o,l,c))break;l&&(i=1),c<o.childCount&&(r=1)}return null}function Vie(t,e,a){let{$from:n,$to:i,depth:r}=e,o=n.before(r+1),l=i.after(r+1),c=o,d=l,u=V.empty,p=0;for(let g=r,y=!1;g>a;g--)y||n.index(g)>0?(y=!0,u=V.from(n.node(g).copy(u)),p++):c--;let m=V.empty,h=0;for(let g=r,y=!1;g>a;g--)y||i.after(g+1)<i.end(g)?(y=!0,m=V.from(i.node(g).copy(m)),h++):d++;t.step(new Pt(c,d,o,l,new K(u.append(m),p,h),u.size-p,!0))}function Xk(t,e,a=null,n=t){let i=Hie(t,e),r=i&&Fie(n,e);return r?i.map(Rj).concat({type:e,attrs:a}).concat(r.map(Rj)):null}function Rj(t){return{type:t,attrs:null}}function Hie(t,e){let{parent:a,startIndex:n,endIndex:i}=t,r=a.contentMatchAt(n).findWrapping(e);if(!r)return null;let o=r.length?r[0]:e;return a.canReplaceWith(n,i,o)?r:null}function Fie(t,e){let{parent:a,startIndex:n,endIndex:i}=t,r=a.child(n),o=e.contentMatch.findWrapping(r.type);if(!o)return null;let c=(o.length?o[o.length-1]:e).contentMatch;for(let d=n;c&&d<i;d++)c=c.matchType(a.child(d).type);return!c||!c.validEnd?null:o}function Bie(t,e,a){let n=V.empty;for(let o=a.length-1;o>=0;o--){if(n.size){let l=a[o].type.contentMatch.matchFragment(n);if(!l||!l.validEnd)throw new RangeError("Wrapper type given to Transform.wrap does not form valid content of its parent wrapper")}n=V.from(a[o].type.create(a[o].attrs,n))}let i=e.start,r=e.end;t.step(new Pt(i,r,i,r,new K(n,0,0),a.length,!0))}function Uie(t,e,a,n,i){if(!n.isTextblock)throw new RangeError("Type given to setBlockType should be a textblock");let r=t.steps.length;t.doc.nodesBetween(e,a,(o,l)=>{let c=typeof i=="function"?i(o):i;if(o.isTextblock&&!o.hasMarkup(n,c)&&$ie(t.doc,t.mapping.slice(r).map(l),n)){let d=null;if(n.schema.linebreakReplacement){let h=n.whitespace=="pre",g=!!n.contentMatch.matchType(n.schema.linebreakReplacement);h&&!g?d=!1:!h&&g&&(d=!0)}d===!1&&dM(t,o,l,r),Qk(t,t.mapping.slice(r).map(l,1),n,void 0,d===null);let u=t.mapping.slice(r),p=u.map(l,1),m=u.map(l+o.nodeSize,1);return t.step(new Pt(p,m,p+1,m-1,new K(V.from(n.create(c,null,o.marks)),0,0),1,!0)),d===!0&&cM(t,o,l,r),!1}})}function cM(t,e,a,n){e.forEach((i,r)=>{if(i.isText){let o,l=/\r?\n|\r/g;for(;o=l.exec(i.text);){let c=t.mapping.slice(n).map(a+1+r+o.index);t.replaceWith(c,c+1,e.type.schema.linebreakReplacement.create())}}})}function dM(t,e,a,n){e.forEach((i,r)=>{if(i.type==i.type.schema.linebreakReplacement){let o=t.mapping.slice(n).map(a+1+r);t.replaceWith(o,o+1,e.type.schema.text(`
17634`))}})}function $ie(t,e,a){let n=t.resolve(e),i=n.index();return n.parent.canReplaceWith(i,i+1,a)}function Wie(t,e,a,n,i){let r=t.doc.nodeAt(e);if(!r)throw new RangeError("No node at given position");a||(a=r.type);let o=a.create(n,null,i||r.marks);if(r.isLeaf)return t.replaceWith(e,e+r.nodeSize,o);
vendor: 11,670 bytes, line 17634
17634if(!a.validContent(r.content))throw new RangeError("Invalid content for node type "+a.name);t.step(new Pt(e,e+r.nodeSize,e+1,e+r.nodeSize-1,new K(V.from(o),0,0),1,!0))}function Ii(t,e,a=1,n){let i=t.resolve(e),r=i.depth-a,o=n&&n[n.length-1]||i.parent;if(r<0||i.parent.type.spec.isolating||!i.parent.canReplace(i.index(),i.parent.childCount)||!o.type.validContent(i.parent.content.cutByIndex(i.index(),i.parent.childCount)))return!1;for(let d=i.depth-1,u=a-2;d>r;d--,u--){let p=i.node(d),m=i.index(d);if(p.type.spec.isolating)return!1;let h=p.content.cutByIndex(m,p.childCount),g=n&&n[u+1];g&&(h=h.replaceChild(0,g.type.create(g.attrs)));let y=n&&n[u]||p;if(!p.canReplace(m+1,p.childCount)||!y.type.validContent(h))return!1}let l=i.indexAfter(r),c=n&&n[0];return i.node(r).canReplaceWith(l,l,c?c.type:i.node(r+1).type)}function Gie(t,e,a=1,n){let i=t.doc.resolve(e),r=V.empty,o=V.empty;for(let l=i.depth,c=i.depth-a,d=a-1;l>c;l--,d--){r=V.from(i.node(l).copy(r));let u=n&&n[d];o=V.from(u?u.type.create(u.attrs,o):i.node(l).copy(o))}t.step(new Tt(e,e,new K(r.append(o),a,a),!0))}function eo(t,e){let a=t.resolve(e),n=a.index();return uM(a.nodeBefore,a.nodeAfter)&&a.parent.canReplace(n,n+1)}function Kie(t,e){e.content.size||t.type.compatibleContent(e.type);let a=t.contentMatchAt(t.childCount),{linebreakReplacement:n}=t.type.schema;for(let i=0;i<e.childCount;i++){let r=e.child(i),o=r.type==n?t.type.schema.nodes.text:r.type;if(a=a.matchType(o),!a||!t.type.allowsMarks(r.marks))return!1}return a.validEnd}function uM(t,e){return!!(t&&e&&!t.isLeaf&&Kie(t,e))}function qg(t,e,a=-1){let n=t.resolve(e);for(let i=n.depth;;i--){let r,o,l=n.index(i);if(i==n.depth?(r=n.nodeBefore,o=n.nodeAfter):a>0?(r=n.node(i+1),l++,o=n.node(i).maybeChild(l)):(r=n.node(i).maybeChild(l-1),o=n.node(i+1)),r&&!r.isTextblock&&uM(r,o)&&n.node(i).canReplace(l,l+1))return e;if(i==0)break;e=a<0?n.before(i):n.after(i)}}function Jie(t,e,a){let n=null,{linebreakReplacement:i}=t.doc.type.schema,r=t.doc.resolve(e-a),o=r.node().type;if(i&&o.inlineContent){let u=o.whitespace=="pre",p=!!o.contentMatch.matchType(i);u&&!p?n=!1:!u&&p&&(n=!0)}let l=t.steps.length;if(n===!1){let u=t.doc.resolve(e+a);dM(t,u.node(),u.before(),l)}o.inlineContent&&Qk(t,e+a-1,o,r.node().contentMatchAt(r.index()),n==null);let c=t.mapping.slice(l),d=c.map(e-a);if(t.step(new Tt(d,c.map(e+a,-1),K.empty,!0)),n===!0){let u=t.doc.resolve(d);cM(t,u.node(),u.before(),t.steps.length)}return t}function Qie(t,e,a){let n=t.resolve(e);if(n.parent.canReplaceWith(n.index(),n.index(),a))return e;if(n.parentOffset==0)for(let i=n.depth-1;i>=0;i--){let r=n.index(i);if(n.node(i).canReplaceWith(r,r,a))return n.before(i+1);if(r>0)return null}if(n.parentOffset==n.parent.content.size)for(let i=n.depth-1;i>=0;i--){let r=n.indexAfter(i);if(n.node(i).canReplaceWith(r,r,a))return n.after(i+1);if(r<n.node(i).childCount)return null}return null}function pM(t,e,a){let n=t.resolve(e);if(!a.content.size)return e;let i=a.content;for(let r=0;r<a.openStart;r++)i=i.firstChild.content;for(let r=1;r<=(a.openStart==0&&a.size?2:1);r++)for(let o=n.depth;o>=0;o--){let l=o==n.depth?0:n.pos<=(n.start(o+1)+n.end(o+1))/2?-1:1,c=n.index(o)+(l>0?1:0),d=n.node(o),u=!1;if(r==1)u=d.canReplace(c,c,i);else{let p=d.contentMatchAt(c).findWrapping(i.firstChild.type);u=p&&d.canReplaceWith(c,c,p[0])}if(u)return l==0?n.pos:l<0?n.before(o+1):n.after(o+1)}return null}function zg(t,e,a=e,n=K.empty){if(e==a&&!n.size)return null;let i=t.resolve(e),r=t.resolve(a);return mM(i,r,n)?new Tt(e,a,n):new Xie(i,r,n).fit()}function mM(t,e,a){return!a.openStart&&!a.openEnd&&t.start()==e.start()&&t.parent.canReplace(t.index(),e.index(),a.content)}class Xie{constructor(e,a,n){this.$from=e,this.$to=a,this.unplaced=n,this.frontier=[],this.placed=V.empty;for(let i=0;i<=e.depth;i++){let r=e.node(i);this.frontier.push({type:r.type,match:r.contentMatchAt(e.indexAfter(i))})}for(let i=e.depth;i>0;i--)this.placed=V.from(e.node(i).copy(this.placed))}get depth(){return this.frontier.length-1}fit(){for(;this.unplaced.size;){let d=this.findFittable();d?this.placeNodes(d):this.openMore()||this.dropNode()}let e=this.mustMoveInline(),a=this.placed.size-this.depth-this.$from.depth,n=this.$from,i=this.close(e<0?this.$to:n.doc.resolve(e));if(!i)return null;let r=this.placed,o=n.depth,l=i.depth;for(;o&&l&&r.childCount==1;)r=r.firstChild.content,o--,l--;let c=new K(r,o,l);return e>-1?new Pt(n.pos,e,this.$to.pos,this.$to.end(),c,a):c.size||n.pos!=this.$to.pos?new Tt(n.pos,i.pos,c):null}findFittable(){let e=this.unplaced.openStart;for(let a=this.unplaced.content,n=0,i=this.unplaced.openEnd;n<e;n++){let r=a.firstChild;if(a.childCount>1&&(i=0),r.type.spec.isolating&&i<=n){e=n;break}a=r.content}for(let a=1;a<=2;a++)for(let n=a==1?e:this.unplaced.openStart;n>=0;n--){let i,r=null;n?(r=W0(this.unplaced.content,n-1).firstChild,i=r.content):i=this.unplaced.content;let o=i.firstChild;for(let l=this.depth;l>=0;l--){let{type:c,match:d}=this.frontier[l],u,p=null;if(a==1&&(o?d.matchType(o.type)||(p=d.fillBefore(V.from(o),!1)):r&&c.compatibleContent(r.type)))return{sliceDepth:n,frontierDepth:l,parent:r,inject:p};if(a==2&&o&&(u=d.findWrapping(o.type)))return{sliceDepth:n,frontierDepth:l,parent:r,wrap:u};if(r&&d.matchType(r.type))break}}}openMore(){let{content:e,openStart:a,openEnd:n}=this.unplaced,i=W0(e,a);return!i.childCount||i.firstChild.isLeaf?!1:(this.unplaced=new K(e,a+1,Math.max(n,i.size+a>=e.size-n?a+1:0)),!0)}dropNode(){let{content:e,openStart:a,openEnd:n}=this.unplaced,i=W0(e,a);if(i.childCount<=1&&a>0){let r=e.size-a<=a+i.size;this.unplaced=new K(Uc(e,a-1,1),a-1,r?a-1:n)}else this.unplaced=new K(Uc(e,a,1),a,n)}placeNodes({sliceDepth:e,frontierDepth:a,parent:n,inject:i,wrap:r}){for(;this.depth>a;)this.closeFrontierNode();if(r)for(let y=0;y<r.length;y++)this.openFrontierNode(r[y]);let o=this.unplaced,l=n?n.content:o.content,c=o.openStart-e,d=0,u=[],{match:p,type:m}=this.frontier[a];if(i){for(let y=0;y<i.childCount;y++)u.push(i.child(y));p=p.matchFragment(i)}let h=l.size+e-(o.content.size-o.openEnd);for(;d<l.childCount;){let y=l.child(d),x=p.matchType(y.type);if(!x)break;d++,(d>1||c==0||y.content.size)&&(p=x,u.push(hM(y.mark(m.allowedMarks(y.marks)),d==1?c:0,d==l.childCount?h:-1)))}let g=d==l.childCount;g||(h=-1),this.placed=$c(this.placed,a,V.from(u)),this.frontier[a].match=p,g&&h<0&&n&&n.type==this.frontier[this.depth].type&&this.frontier.length>1&&this.closeFrontierNode();for(let y=0,x=l;y<h;y++){let v=x.lastChild;this.frontier.push({type:v.type,match:v.contentMatchAt(v.childCount)}),x=v.content}this.unplaced=g?e==0?K.empty:new K(Uc(o.content,e-1,1),e-1,h<0?o.openEnd:e-1):new K(Uc(o.content,e,d),o.openStart,o.openEnd)}mustMoveInline(){if(!this.$to.parent.isTextblock)return-1;let e=this.frontier[this.depth],a;if(!e.type.isTextblock||!G0(this.$to,this.$to.depth,e.type,e.match,!1)||this.$to.depth==this.depth&&(a=this.findCloseLevel(this.$to))&&a.depth==this.depth)return-1;let{depth:n}=this.$to,i=this.$to.after(n);for(;n>1&&i==this.$to.end(--n);)++i;return i}findCloseLevel(e){e:for(let a=Math.min(this.depth,e.depth);a>=0;a--){let{match:n,type:i}=this.frontier[a],r=a<e.depth&&e.end(a+1)==e.pos+(e.depth-(a+1)),o=G0(e,a,i,n,r);if(o){for(let l=a-1;l>=0;l--){let{match:c,type:d}=this.frontier[l],u=G0(e,l,d,c,!0);if(!u||u.childCount)continue e}return{depth:a,fit:o,move:r?e.doc.resolve(e.after(a+1)):e}}}}close(e){let a=this.findCloseLevel(e);if(!a)return null;for(;this.depth>a.depth;)this.closeFrontierNode();a.fit.childCount&&(this.placed=$c(this.placed,a.depth,a.fit)),e=a.move;for(let n=a.depth+1;n<=e.depth;n++){let i=e.node(n),r=i.type.contentMatch.fillBefore(i.content,!0,e.index(n));this.openFrontierNode(i.type,i.attrs,r)}return e}openFrontierNode(e,a=null,n){let i=this.frontier[this.depth];i.match=i.match.matchType(e),this.placed=$c(this.placed,this.depth,V.from(e.create(a,n))),this.frontier.push({type:e,match:e.contentMatch})}closeFrontierNode(){let a=this.frontier.pop().match.fillBefore(V.empty,!0);a.childCount&&(this.placed=$c(this.placed,this.frontier.length,a))}}function Uc(t,e,a){return e==0?t.cutByIndex(a,t.childCount):t.replaceChild(0,t.firstChild.copy(Uc(t.firstChild.content,e-1,a)))}function $c(t,e,a){return e==0?t.append(a):t.replaceChild(t.childCount-1,t.lastChild.copy($c(t.lastChild.content,e-1,a)))}function W0(t,e){for(let a=0;a<e;a++)t=t.firstChild.content;return t}function hM(t,e,a){if(e<=0)return t;let n=t.content;return e>1&&(n=n.replaceChild(0,hM(n.firstChild,e-1,n.childCount==1?a-1:0))),e>0&&(n=t.type.contentMatch.fillBefore(n).append(n),a<=0&&(n=n.append(t.type.contentMatch.matchFragment(n).fillBefore(V.empty,!0)))),t.copy(n)}function G0(t,e,a,n,i){let r=t.node(e),o=i?t.indexAfter(e):t.index(e);if(o==r.childCount&&!a.compatibleContent(r.type))return null;let l=n.fillBefore(r.content,!0,o);return l&&!Yie(a,r.content,o)?l:null}function Yie(t,e,a){for(let n=a;n<e.childCount;n++)if(!t.allowsMarks(e.child(n).marks))return!0;return!1}function Zie(t){return t.spec.defining||t.spec.definingForContent}function ere(t,e,a,n){if(!n.size)return t.deleteRange(e,a);let i=t.doc.resolve(e),r=t.doc.resolve(a);if(mM(i,r,n))return t.step(new Tt(e,a,n));let o=gM(i,r);o[o.length-1]==0&&o.pop();let l=-(i.depth+1);o.unshift(l);for(let m=i.depth,h=i.pos-1;m>0;m--,h--){let g=i.node(m).type.spec;if(g.defining||g.definingAsContext||g.isolating)break;o.indexOf(m)>-1?l=m:i.before(m)==h&&o.splice(1,0,-m)}let c=o.indexOf(l),d=[],u=n.openStart;for(let m=n.content,h=0;;h++){let g=m.firstChild;if(d.push(g),h==n.openStart)break;m=g.content}for(let m=u-1;m>=0;m--){let h=d[m],g=Zie(h.type);if(g&&!h.sameMarkup(i.node(Math.abs(l)-1)))u=m;else if(g||!h.type.isTextblock)break}for(let m=n.openStart;m>=0;m--){let h=(m+u+1)%(n.openStart+1),g=d[h];if(g)for(let y=0;y<o.length;y++){let x=o[(y+c)%o.length],v=!0;x<0&&(v=!1,x=-x);let w=i.node(x-1),S=i.index(x-1);if(w.canReplaceWith(S,S,g.type,g.marks))return t.replace(i.before(x),v?r.after(x):a,new K(fM(n.content,0,n.openStart,h),h,n.openEnd))}}let p=t.steps.length;for(let m=o.length-1;m>=0&&(t.replace(e,a,n),!(t.steps.length>p));m--){let h=o[m];h<0||(e=i.before(h),a=r.after(h))}}function fM(t,e,a,n,i){if(e<a){let r=t.firstChild;t=t.replaceChild(0,r.copy(fM(r.content,e+1,a,n,r)))}if(e>n){let r=i.contentMatchAt(0),o=r.fillBefore(t).append(t);t=o.append(r.matchFragment(o).fillBefore(V.empty,!0))}return t}function tre(t,e,a,n){if(!n.isInline&&e==a&&t.doc.resolve(e).parent.content.size){let i=Qie(t.doc,e,n.type);i!=null&&(e=a=i)}t.replaceRange(e,a,new K(V.from(n),0,0))}function are(t,e,a){let n=t.doc.resolve(e),i=t.doc.resolve(a),r=gM(n,i);for(let o=0;o<r.length;o++){let l=r[o],c=o==r.length-1;if(c&&l==0||n.node(l).type.contentMatch.validEnd)return t.delete(n.start(l),i.end(l));if(l>0&&(c||n.node(l-1).canReplace(n.index(l-1),i.indexAfter(l-1))))return t.delete(n.before(l),i.after(l))}for(let o=1;o<=n.depth&&o<=i.depth;o++)if(e-n.start(o)==n.depth-o&&a>n.end(o)&&i.end(o)-a!=i.depth-o&&n.start(o-1)==i.start(o-1)&&n.node(o-1).canReplace(n.index(o-1),i.index(o-1)))return t.delete(n.before(o),a);t.delete(e,a)}function gM(t,e){let a=[],n=Math.min(t.depth,e.depth);for(let i=n;i>=0;i--){let r=t.start(i);if(r<t.pos-(t.depth-i)||e.end(i)>e.pos+(e.depth-i)||t.node(i).type.spec.isolating||e.node(i).type.spec.isolating)break;(r==e.start(i)||i==t.depth&&i==e.depth&&t.parent.inlineContent&&e.parent.inlineContent&&i&&e.start(i-1)==r-1)&&a.push(i)}return a}class dl extends sa{constructor(e,a,n){super(),this.pos=e,this.attr=a,this.value=n}apply(e){let a=e.nodeAt(this.pos);if(!a)return yt.fail("No node at attribute step's position");let n=Object.create(null);for(let r in a.attrs)n[r]=a.attrs[r];n[this.attr]=this.value;let i=a.type.create(n,null,a.marks);
vendor: 5,172 bytes, line 17634
17634return yt.fromReplace(e,this.pos,this.pos+1,new K(V.from(i),0,a.isLeaf?0:1))}getMap(){return qa.empty}invert(e){return new dl(this.pos,this.attr,e.nodeAt(this.pos).attrs[this.attr])}map(e){let a=e.mapResult(this.pos,1);return a.deletedAfter?null:new dl(a.pos,this.attr,this.value)}toJSON(){return{stepType:"attr",pos:this.pos,attr:this.attr,value:this.value}}static fromJSON(e,a){if(typeof a.pos!="number"||typeof a.attr!="string")throw new RangeError("Invalid input for AttrStep.fromJSON");return new dl(a.pos,a.attr,a.value)}}sa.jsonID("attr",dl);class mu extends sa{constructor(e,a){super(),this.attr=e,this.value=a}apply(e){let a=Object.create(null);for(let i in e.attrs)a[i]=e.attrs[i];a[this.attr]=this.value;let n=e.type.create(a,e.content,e.marks);return yt.ok(n)}getMap(){return qa.empty}invert(e){return new mu(this.attr,e.attrs[this.attr])}map(e){return this}toJSON(){return{stepType:"docAttr",attr:this.attr,value:this.value}}static fromJSON(e,a){if(typeof a.attr!="string")throw new RangeError("Invalid input for DocAttrStep.fromJSON");return new mu(a.attr,a.value)}}sa.jsonID("docAttr",mu);let Il=class extends Error{};Il=function t(e){let a=Error.call(this,e);return a.__proto__=t.prototype,a};Il.prototype=Object.create(Error.prototype);Il.prototype.constructor=Il;Il.prototype.name="TransformError";class yM{constructor(e){this.doc=e,this.steps=[],this.docs=[],this.mapping=new pu}get before(){return this.docs.length?this.docs[0]:this.doc}step(e){let a=this.maybeStep(e);if(a.failed)throw new Il(a.failed);return this}maybeStep(e){let a=e.apply(this.doc);return a.failed||this.addStep(e,a.doc),a}get docChanged(){return this.steps.length>0}addStep(e,a){this.docs.push(this.doc),this.steps.push(e),this.mapping.appendMap(e.getMap()),this.doc=a}replace(e,a=e,n=K.empty){let i=zg(this.doc,e,a,n);return i&&this.step(i),this}replaceWith(e,a,n){return this.replace(e,a,new K(V.from(n),0,0))}delete(e,a){return this.replace(e,a,K.empty)}insert(e,a){return this.replaceWith(e,e,a)}replaceRange(e,a,n){return ere(this,e,a,n),this}replaceRangeWith(e,a,n){return tre(this,e,a,n),this}deleteRange(e,a){return are(this,e,a),this}lift(e,a){return Vie(this,e,a),this}join(e,a=1){return Jie(this,e,a),this}wrap(e,a){return Bie(this,e,a),this}setBlockType(e,a=e,n,i=null){return Uie(this,e,a,n,i),this}setNodeMarkup(e,a,n=null,i){return Wie(this,e,a,n,i),this}setNodeAttribute(e,a,n){return this.step(new dl(e,a,n)),this}setDocAttribute(e,a){return this.step(new mu(e,a)),this}addNodeMark(e,a){return this.step(new vr(e,a)),this}removeNodeMark(e,a){let n=this.doc.nodeAt(e);if(!n)throw new RangeError("No node at position "+e);if(a instanceof qe)a.isInSet(n.marks)&&this.step(new ns(e,a));else{let i=n.marks,r,o=[];for(;r=a.isInSet(i);)o.push(new ns(e,r)),i=r.removeFromSet(i);for(let l=o.length-1;l>=0;l--)this.step(o[l])}return this}split(e,a=1,n){return Gie(this,e,a,n),this}addMark(e,a,n){return Die(this,e,a,n),this}removeMark(e,a,n){return qie(this,e,a,n),this}clearIncompatible(e,a,n){return Qk(this,e,a,n),this}}const K0=Object.create(null);class xe{constructor(e,a,n){this.$anchor=e,this.$head=a,this.ranges=n||[new nre(e.min(a),e.max(a))]}get anchor(){return this.$anchor.pos}get head(){return this.$head.pos}get from(){return this.$from.pos}get to(){return this.$to.pos}get $from(){return this.ranges[0].$from}get $to(){return this.ranges[0].$to}get empty(){let e=this.ranges;for(let a=0;a<e.length;a++)if(e[a].$from.pos!=e[a].$to.pos)return!1;return!0}content(){return this.$from.doc.slice(this.from,this.to,!0)}replace(e,a=K.empty){let n=a.content.lastChild,i=null;for(let l=0;l<a.openEnd;l++)i=n,n=n.lastChild;let r=e.steps.length,o=this.ranges;for(let l=0;l<o.length;l++){let{$from:c,$to:d}=o[l],u=e.mapping.slice(r);e.replaceRange(u.map(c.pos),u.map(d.pos),l?K.empty:a),l==0&&Mj(e,r,(n?n.isInline:i&&i.isTextblock)?-1:1)}}replaceWith(e,a){let n=e.steps.length,i=this.ranges;for(let r=0;r<i.length;r++){let{$from:o,$to:l}=i[r],c=e.mapping.slice(n),d=c.map(o.pos),u=c.map(l.pos);r?e.deleteRange(d,u):(e.replaceRangeWith(d,u,a),Mj(e,n,a.isInline?-1:1))}}static findFrom(e,a,n=!1){let i=e.parent.inlineContent?new ce(e):Ns(e.node(0),e.parent,e.pos,e.index(),a,n);if(i)return i;for(let r=e.depth-1;r>=0;r--){let o=a<0?Ns(e.node(0),e.node(r),e.before(r+1),e.index(r),a,n):Ns(e.node(0),e.node(r),e.after(r+1),e.index(r)+1,a,n);if(o)return o}return null}static near(e,a=1){return this.findFrom(e,a)||this.findFrom(e,-a)||new Ua(e.node(0))}static atStart(e){return Ns(e,e,0,0,1)||new Ua(e)}static atEnd(e){return Ns(e,e,e.content.size,e.childCount,-1)||new Ua(e)}static fromJSON(e,a){if(!a||!a.type)throw new RangeError("Invalid input for Selection.fromJSON");let n=K0[a.type];if(!n)throw new RangeError(`No selection type ${a.type} defined`);return n.fromJSON(e,a)}static jsonID(e,a){if(e in K0)throw new RangeError("Duplicate use of selection JSON ID "+e);return K0[e]=a,a.prototype.jsonID=e,a}getBookmark(){return ce.between(this.$anchor,this.$head).getBookmark()}}xe.prototype.visible=!0;class nre{constructor(e,a){this.$from=e,this.$to=a}}let Lj=!1;function Oj(t){!Lj&&!t.parent.inlineContent&&(Lj=!0,console.warn("TextSelection endpoint not pointing into a 
17634node with inline content ("+t.parent.type.name+")"))}class ce extends xe{constructor(e,a=e){Oj(e),Oj(a),super(e,a)}get $cursor(){return this.$anchor.pos==this.$head.pos?this.$head:null}map(e,a){let n=e.resolve(a.map(this.head));if(!n.parent.inlineContent)return xe.near(n);let i=e.resolve(a.map(this.anchor));return new ce(i.parent.inlineContent?i:n,n)}replace(e,a=K.empty){if(super.replace(e,a),a==K.empty){let n=this.$from.marksAcross(this.$to);n&&e.ensureMarks(n)}}eq(e){return e instanceof ce&&e.anchor==this.anchor&&e.head==this.head}getBookmark(){return new Vg(this.anchor,this.head)}toJSON(){return{type:"text",anchor:this.anchor,head:this.head}}static fromJSON(e,a){if(typeof a.anchor!="number"||typeof a.head!="number")throw new RangeError("Invalid input for TextSelection.fromJSON");return new ce(e.resolve(a.anchor),e.resolve(a.head))}static create(e,a,n=a){let i=e.resolve(a);return new this(i,n==a?i:e.resolve(n))}static between(e,a,n){let i=e.pos-a.pos;if((!n||i)&&(n=i>=0?1:-1),!a.parent.inlineContent){let r=xe.findFrom(a,n,!0)||xe.findFrom(a,-n,!0);if(r)a=r.$head;else return xe.near(a,n)}return e.parent.inlineContent||(i==0?e=a:(e=(xe.findFrom(e,-n,!0)||xe.findFrom(e,n,!0)).$anchor,e.pos<a.pos!=i<0&&(e=a))),new ce(e,a)}}xe.jsonID("text",ce);class Vg{constructor(e,a){this.anchor=e,this.head=a}map(e){return new Vg(e.map(this.anchor),e.map(this.head))}resolve(e){return ce.between(e.resolve(this.anchor),e.resolve(this.head))}}class se extends xe{constructor(e){let a=e.nodeAfter,n=e.node(0).resolve(e.pos+a.nodeSize);super(e,n),this.node=a}map(e,a){let{deleted:n,pos:i}=a.mapResult(this.anchor),r=e.resolve(i);return n?xe.near(r):new se(r)}content(){return new K(V.from(this.node),0,0)}eq(e){return e instanceof se&&e.anchor==this.anchor}toJSON(){return{type:"node",anchor:this.anchor}}getBookmark(){return new Yk(this.anchor)}static fromJSON(e,a){if(typeof a.anchor!="number")throw new RangeError("Invalid input for NodeSelection.fromJSON");return new se(e.resolve(a.anchor))}static create(e,a){return new se(e.resolve(a))}static isSelectable(e){return!e.isText&&e.type.spec.selectable!==!1}}se.prototype.visible=!1;xe.jsonID("node",se);class Yk{constructor(e){this.anchor=e}map(e){let{deleted:a,pos:n}=e.mapResult(this.anchor);return a?new Vg(n,n):new Yk(n)}resolve(e){let a=e.resolve(this.anchor),n=a.nodeAfter;return n&&se.isSelectable(n)?new se(a):xe.near(a)}}class Ua extends xe{constructor(e){super(e.resolve(0),e.resolve(e.content.size))}replace(e,a=K.empty){if(a==K.empty){e.delete(0,e.doc.content.size);let n=xe.atStart(e.doc);n.eq(e.selection)||e.setSelection(n)}else super.replace(e,a)}toJSON(){return{type:"all"}}static fromJSON(e){return new Ua(e)}map(e){return new Ua(e)}eq(e){return e instanceof Ua}getBookmark(){return ire}}xe.jsonID("all",Ua);const ire={map(){return this},resolve(t){return new Ua(t)}};function Ns(t,e,a,n,i,r=!1){if(e.inlineContent)return ce.create(t,a);for(let o=n-(i>0?0:1);i>0?o<e.childCount:o>=0;o+=i){let l=e.child(o);if(l.isAtom){if(!r&&se.isSelectable(l))return se.create(t,a-(i<0?l.nodeSize:0))}else{let c=Ns(t,l,a+i,i<0?l.childCount:0,i,r);if(c)return c}a+=l.nodeSize*i}return null}function Mj(t,e,a){let n=t.steps.length-1;if(n<e)return;let i=t.steps[n];if(!(i instanceof Tt||i instanceof Pt))return;let r=t.mapping.maps[n],o;r.forEach((l,c,d,u)=>{o==null&&(o=u)}),t.setSelection(xe.near(t.doc.resolve(o),a))}const Dj=1,Zp=2,qj=4;class rre extends yM{constructor(e){super(e.doc),this.curSelectionFor=0,this.updated=0,this.meta=Object.create(null),this.time=Date.now(),this.curSelection=e.selection,this.storedMarks=e.storedMarks}get selection(){return this.curSelectionFor<this.steps.length&&(this.curSelection=this.curSelection.map(this.doc,this.mapping.slice(this.curSelectionFor)),this.curSelectionFor=this.steps.length),this.curSelection}setSelection(e){if(e.$from.doc!=this.doc)throw new RangeError("Selection passed to setSelection must point at the current document");return this.curSelection=e,this.curSelectionFor=this.steps.length,this.updated=(this.updated|Dj)&~Zp,this.storedMarks=null,this}get selectionSet(){return(this.updated&Dj)>0}setStoredMarks(e){return this.storedMarks=e,this.updated|=Zp,this}ensureMarks(e){return qe.sameSet(this.storedMarks||this.selection.$from.marks(),e)||this.setStoredMarks(e),this}addStoredMark(e){return this.ensureMarks(e.addToSet(this.storedMarks||this.selection.$head.marks()))}removeStoredMark(e){return this.ensureMarks(e.removeFromSet(this.storedMarks||this.selection.$head.marks()))}get storedMarksSet(){return(this.updated&Zp)>0}addStep(e,a){super.addStep(e,a),this.updated=this.updated&~Zp,this.storedMarks=null}setTime(e){return this.time=e,this}replaceSelection(e){return this.selection.replace(this,e),this}replaceSelectionWith(e,a=!0){let n=this.selection;return a&&(e=e.mark(this.storedMarks||(n.empty?n.$from.marks():n.$from.marksAcross(n.$to)||qe.none))),n.replaceWith(this,e),this}deleteSelection(){return this.selection.replace(this),this}insertText(e,a,n){let i=this.doc.type.schema;if(a==null)return e?this.replaceSelectionWith(i.text(e),!0):this.deleteSelection();{if(n==null&&(n=a),!e)return this.deleteRange(a,n);let r=this.storedMarks;if(!r){let o=this.doc.resolve(a);r=n==a?o.marks():o.marksAcross(this.doc.resolve(n))}return this.replaceRangeWith(a,n,i.text(e,r)),!this.selection.empty&&this.selection.to==a+e.length&&this.setSelection(xe.near(this.selection.$to)),this}}setMeta(e,a){return this.meta[typeof e=="string"?e:e.key]=a,this}getMeta(e){return this.meta[typeof e=="string"?e:e.key]}get isGeneric(){for(let e in this.meta)return!1;return!0}scrollIntoView(){return this.updated|=qj,this}get scrolledIntoView(){return(this.updated&qj)>0}}function zj(t,e){return!e||!t?t:t.bind(e)}class Wc{constructor(e,a,n){this.name=e,this.init=zj(a.init,n),this.apply=zj(a.apply,n)}}const ore=[new Wc("doc",{init(t){return t.doc||t.schema.topNodeType.createAndFill()},apply(t){return t.doc}}),new Wc("selection",{init(t,e){return t.selection||xe.atStart(e.doc)},apply(t){return t.selection}}),new Wc("storedMarks",{init(t){return t.storedMarks||null},apply(t,e,a,n){return n.selection.$cursor?t.storedMarks:null}}),new Wc("scrollToSelection",{init(){return 0},apply(t,e){return t.scrolledIntoView?e+1:e}})];class J0{constructor(e,a){this.schema=e,this.plugins=[],this.pluginsByKey=Object.create(null),this.fields=ore.slice(),a&&a.forEach(n=>{if(this.pluginsByKey[n.key])throw new RangeError("Adding different instances of a keyed plugin ("+n.key+")");this.plugins.push(n),this.pluginsByKey[n.key]=n,n.spec.state&&this.fields.push(new Wc(n.key,n.spec.state,n))})}}class Qs{constructor(e){this.config=e}get schema(){return this.config.schema}get plugins(){return this.config.plugins}
vendor: 4,627 bytes, line 17634
17634apply(e){return this.applyTransaction(e).state}filterTransaction(e,a=-1){for(let n=0;n<this.config.plugins.length;n++)if(n!=a){let i=this.config.plugins[n];if(i.spec.filterTransaction&&!i.spec.filterTransaction.call(i,e,this))return!1}return!0}applyTransaction(e){if(!this.filterTransaction(e))return{state:this,transactions:[]};let a=[e],n=this.applyInner(e),i=null;for(;;){let r=!1;for(let o=0;o<this.config.plugins.length;o++){let l=this.config.plugins[o];if(l.spec.appendTransaction){let c=i?i[o].n:0,d=i?i[o].state:this,u=c<a.length&&l.spec.appendTransaction.call(l,c?a.slice(c):a,d,n);if(u&&n.filterTransaction(u,o)){if(u.setMeta("appendedTransaction",e),!i){i=[];for(let p=0;p<this.config.plugins.length;p++)i.push(p<o?{state:n,n:a.length}:{state:this,n:0})}a.push(u),n=n.applyInner(u),r=!0}i&&(i[o]={state:n,n:a.length})}}if(!r)return{state:n,transactions:a}}}applyInner(e){if(!e.before.eq(this.doc))throw new RangeError("Applying a mismatched transaction");let a=new Qs(this.config),n=this.config.fields;for(let i=0;i<n.length;i++){let r=n[i];a[r.name]=r.apply(e,this[r.name],this,a)}return a}get tr(){return new rre(this)}static create(e){let a=new J0(e.doc?e.doc.type.schema:e.schema,e.plugins),n=new Qs(a);for(let i=0;i<a.fields.length;i++)n[a.fields[i].name]=a.fields[i].init(e,n);return n}reconfigure(e){let a=new J0(this.schema,e.plugins),n=a.fields,i=new Qs(a);for(let r=0;r<n.length;r++){let o=n[r].name;i[o]=this.hasOwnProperty(o)?this[o]:n[r].init(e,i)}return i}toJSON(e){let a={doc:this.doc.toJSON(),selection:this.selection.toJSON()};if(this.storedMarks&&(a.storedMarks=this.storedMarks.map(n=>n.toJSON())),e&&typeof e=="object")for(let n in e){if(n=="doc"||n=="selection")throw new RangeError("The JSON fields `doc` and `selection` are reserved");let i=e[n],r=i.spec.state;r&&r.toJSON&&(a[n]=r.toJSON.call(i,this[i.key]))}return a}static fromJSON(e,a,n){if(!a)throw new RangeError("Invalid input for EditorState.fromJSON");if(!e.schema)throw new RangeError("Required config field 'schema' missing");let i=new J0(e.schema,e.plugins),r=new Qs(i);return i.fields.forEach(o=>{if(o.name=="doc")r.doc=Rn.fromJSON(e.schema,a.doc);else if(o.name=="selection")r.selection=xe.fromJSON(r.doc,a.selection);else if(o.name=="storedMarks")a.storedMarks&&(r.storedMarks=a.storedMarks.map(e.schema.markFromJSON));else{if(n)for(let l in n){let c=n[l],d=c.spec.state;if(c.key==o.name&&d&&d.fromJSON&&Object.prototype.hasOwnProperty.call(a,l)){r[o.name]=d.fromJSON.call(c,e,a[l],r);return}}r[o.name]=o.init(e,r)}}),r}}function xM(t,e,a){for(let n in t){let i=t[n];i instanceof Function?i=i.bind(e):n=="handleDOMEvents"&&(i=xM(i,e,{})),a[n]=i}return a}class at{constructor(e){this.spec=e,this.props={},e.props&&xM(e.props,this,this.props),this.key=e.key?e.key.key:vM("plugin")}getState(e){return e[this.key]}}const Q0=Object.create(null);function vM(t){return t in Q0?t+"$"+ ++Q0[t]:(Q0[t]=0,t+"$")}class _t{constructor(e="key"){this.key=vM(e)}get(e){return e.config.pluginsByKey[this.key]}getState(e){return e[this.key]}}const Zk=(t,e)=>t.selection.empty?!1:(e&&e(t.tr.deleteSelection().scrollIntoView()),!0);function bM(t,e){let{$cursor:a}=t.selection;return!a||(e?!e.endOfTextblock("backward",t):a.parentOffset>0)?null:a}const wM=(t,e,a)=>{let n=bM(t,a);if(!n)return!1;let i=eS(n);if(!i){let o=n.blockRange(),l=o&&ec(o);return l==null?!1:(e&&e(t.tr.lift(o,l).scrollIntoView()),!0)}let r=i.nodeBefore;if(NM(t,i,e,-1))return!0;if(n.parent.content.size==0&&(Pl(r,"end")||se.isSelectable(r)))for(let o=n.depth;;o--){let l=zg(t.doc,n.before(o),n.after(o),K.empty);if(l&&l.slice.size<l.to-l.from){if(e){let c=t.tr.step(l);c.setSelection(Pl(r,"end")?xe.findFrom(c.doc.resolve(c.mapping.map(i.pos,-1)),-1):se.create(c.doc,i.pos-r.nodeSize)),e(c.scrollIntoView())}return!0}if(o==1||n.node(o-1).childCount>1)break}return r.isAtom&&i.depth==n.depth-1?(e&&e(t.tr.delete(i.pos-r.nodeSize,i.pos).scrollIntoView()),!0):!1},sre=(t,e,a)=>{let n=bM(t,a);if(!n)return!1;let i=eS(n);return i?kM(t,i,e):!1},lre=(t,e,a)=>{let n=_M(t,a);if(!n)return!1;let i=tS(n);return i?kM(t,i,e):!1};function kM(t,e,a){let n=e.nodeBefore,i=n,r=e.pos-1;for(;!i.isTextblock;r--){if(i.type.spec.isolating)return!1;let u=i.lastChild;if(!u)return!1;i=u}let o=e.nodeAfter,l=o,c=e.pos+1;for(;!l.isTextblock;c++){if(l.type.spec.isolating)return!1;let u=l.firstChild;if(!u)return!1;l=u}let d=zg(t.doc,r,c,K.empty);if(!d||d.from!=r||d instanceof Tt&&d.slice.size>=c-r)return!1;if(a){let u=t.tr.step(d);u.setSelection(ce.create(u.doc,r)),a(u.scrollIntoView())}return!0}function Pl(t,e,a=!1){for(let n=t;n;n=e=="start"?n.firstChild:n.lastChild){if(n.isTextblock)return!0;
vendor: 6,074 bytes, lines 17634-17635
17634if(a&&n.childCount!=1)return!1}return!1}const SM=(t,e,a)=>{let{$head:n,empty:i}=t.selection,r=n;if(!i)return!1;if(n.parent.isTextblock){if(a?!a.endOfTextblock("backward",t):n.parentOffset>0)return!1;r=eS(n)}let o=r&&r.nodeBefore;return!o||!se.isSelectable(o)?!1:(e&&e(t.tr.setSelection(se.create(t.doc,r.pos-o.nodeSize)).scrollIntoView()),!0)};function eS(t){if(!t.parent.type.spec.isolating)for(let e=t.depth-1;e>=0;e--){if(t.index(e)>0)return t.doc.resolve(t.before(e+1));if(t.node(e).type.spec.isolating)break}return null}function _M(t,e){let{$cursor:a}=t.selection;return!a||(e?!e.endOfTextblock("forward",t):a.parentOffset<a.parent.content.size)?null:a}const AM=(t,e,a)=>{let n=_M(t,a);if(!n)return!1;let i=tS(n);if(!i)return!1;let r=i.nodeAfter;if(NM(t,i,e,1))return!0;if(n.parent.content.size==0&&(Pl(r,"start")||se.isSelectable(r))){let o=zg(t.doc,n.before(),n.after(),K.empty);if(o&&o.slice.size<o.to-o.from){if(e){let l=t.tr.step(o);l.setSelection(Pl(r,"start")?xe.findFrom(l.doc.resolve(l.mapping.map(i.pos)),1):se.create(l.doc,l.mapping.map(i.pos))),e(l.scrollIntoView())}return!0}}return r.isAtom&&i.depth==n.depth-1?(e&&e(t.tr.delete(i.pos,i.pos+r.nodeSize).scrollIntoView()),!0):!1},EM=(t,e,a)=>{let{$head:n,empty:i}=t.selection,r=n;if(!i)return!1;if(n.parent.isTextblock){if(a?!a.endOfTextblock("forward",t):n.parentOffset<n.parent.content.size)return!1;r=tS(n)}let o=r&&r.nodeAfter;return!o||!se.isSelectable(o)?!1:(e&&e(t.tr.setSelection(se.create(t.doc,r.pos)).scrollIntoView()),!0)};function tS(t){if(!t.parent.type.spec.isolating)for(let e=t.depth-1;e>=0;e--){let a=t.node(e);if(t.index(e)+1<a.childCount)return t.doc.resolve(t.after(e+1));if(a.type.spec.isolating)break}return null}const cre=(t,e)=>{let a=t.selection,n=a instanceof se,i;if(n){if(a.node.isTextblock||!eo(t.doc,a.from))return!1;i=a.from}else if(i=qg(t.doc,a.from,-1),i==null)return!1;if(e){let r=t.tr.join(i);n&&r.setSelection(se.create(r.doc,i-t.doc.resolve(i).nodeBefore.nodeSize)),e(r.scrollIntoView())}return!0},dre=(t,e)=>{let a=t.selection,n;if(a instanceof se){if(a.node.isTextblock||!eo(t.doc,a.to))return!1;n=a.to}else if(n=qg(t.doc,a.to,1),n==null)return!1;return e&&e(t.tr.join(n).scrollIntoView()),!0},ure=(t,e)=>{let{$from:a,$to:n}=t.selection,i=a.blockRange(n),r=i&&ec(i);return r==null?!1:(e&&e(t.tr.lift(i,r).scrollIntoView()),!0)},CM=(t,e)=>{let{$head:a,$anchor:n}=t.selection;return!a.parent.type.spec.code||!a.sameParent(n)?!1:(e&&e(t.tr.insertText(`
17635`).scrollIntoView()),!0)};function aS(t){for(let e=0;e<t.edgeCount;e++){let{type:a}=t.edge(e);if(a.isTextblock&&!a.hasRequiredAttrs())return a}return null}const pre=(t,e)=>{let{$head:a,$anchor:n}=t.selection;if(!a.parent.type.spec.code||!a.sameParent(n))return!1;let i=a.node(-1),r=a.indexAfter(-1),o=aS(i.contentMatchAt(r));if(!o||!i.canReplaceWith(r,r,o))return!1;if(e){let l=a.after(),c=t.tr.replaceWith(l,l,o.createAndFill());c.setSelection(xe.near(c.doc.resolve(l),1)),e(c.scrollIntoView())}return!0},jM=(t,e)=>{let a=t.selection,{$from:n,$to:i}=a;if(a instanceof Ua||n.parent.inlineContent||i.parent.inlineContent)return!1;let r=aS(i.parent.contentMatchAt(i.indexAfter()));if(!r||!r.isTextblock)return!1;if(e){let o=(!n.parentOffset&&i.index()<i.parent.childCount?n:i).pos,l=t.tr.insert(o,r.createAndFill());l.setSelection(ce.create(l.doc,o+1)),e(l.scrollIntoView())}return!0},TM=(t,e)=>{let{$cursor:a}=t.selection;if(!a||a.parent.content.size)return!1;if(a.depth>1&&a.after()!=a.end(-1)){let r=a.before();if(Ii(t.doc,r))return e&&e(t.tr.split(r).scrollIntoView()),!0}let n=a.blockRange(),i=n&&ec(n);return i==null?!1:(e&&e(t.tr.lift(n,i).scrollIntoView()),!0)};function mre(t){return(e,a)=>{let{$from:n,$to:i}=e.selection;if(e.selection instanceof se&&e.selection.node.isBlock)return!n.parentOffset||!Ii(e.doc,n.pos)?!1:(a&&a(e.tr.split(n.pos).scrollIntoView()),!0);if(!n.depth)return!1;let r=[],o,l,c=!1,d=!1;for(let h=n.depth;;h--)if(n.node(h).isBlock){c=n.end(h)==n.pos+(n.depth-h),d=n.start(h)==n.pos-(n.depth-h),l=aS(n.node(h-1).contentMatchAt(n.indexAfter(h-1))),r.unshift(c&&l?{type:l}:null),o=h;break}else{if(h==1)return!1;r.unshift(null)}let u=e.tr;(e.selection instanceof ce||e.selection instanceof Ua)&&u.deleteSelection();let p=u.mapping.map(n.pos),m=Ii(u.doc,p,r.length,r);if(m||(r[0]=l?{type:l}:null,m=Ii(u.doc,p,r.length,r)),!m)return!1;if(u.split(p,r.length,r),!c&&d&&n.node(o).type!=l){let h=u.mapping.map(n.before(o)),g=u.doc.resolve(h);l&&n.node(o-1).canReplaceWith(g.index(),g.index()+1,l)&&u.setNodeMarkup(u.mapping.map(n.before(o)),l)}return a&&a(u.scrollIntoView()),!0}}const hre=mre(),fre=(t,e)=>{let{$from:a,to:n}=t.selection,i,r=a.sharedDepth(n);return r==0?!1:(i=a.before(r),e&&e(t.tr.setSelection(se.create(t.doc,i))),!0)};function gre(t,e,a){let n=e.nodeBefore,i=e.nodeAfter,r=e.index();return!n||!i||!n.type.compatibleContent(i.type)?!1:!n.content.size&&e.parent.canReplace(r-1,r)?(a&&a(t.tr.delete(e.pos-n.nodeSize,e.pos).scrollIntoView()),!0):!e.parent.canReplace(r,r+1)||!(i.isTextblock||eo(t.doc,e.pos))?!1:(a&&a(t.tr.join(e.pos).scrollIntoView()),!0)}function NM(t,e,a,n){let i=e.nodeBefore,r=e.nodeAfter,o,l,c=i.type.spec.isolating||r.type.spec.isolating;if(!c&&gre(t,e,a))return!0;let d=!c&&e.parent.canReplace(e.index(),e.index()+1);if(d&&(o=(l=i.contentMatchAt(i.childCount)).findWrapping(r.type))&&l.matchType(o[0]||r.type).validEnd){if(a){let h=e.pos+r.nodeSize,g=V.empty;for(let v=o.length-1;v>=0;v--)g=V.from(o[v].create(null,g));g=V.from(i.copy(g));let y=t.tr.step(new Pt(e.pos-1,h,e.pos,h,new K(g,1,0),o.length,!0)),x=y.doc.resolve(h+2*o.length);x.nodeAfter&&x.nodeAfter.type==i.type&&eo(y.doc,x.pos)&&y.join(x.pos),a(y.scrollIntoView())}return!0}let u=r.type.spec.isolating||n>0&&c?null:xe.findFrom(e,1),p=u&&u.$from.blockRange(u.$to),m=p&&ec(p);if(m!=null&&m>=e.depth)return a&&a(t.tr.lift(p,m).scrollIntoView()),!0;if(d&&Pl(r,"start",!0)&&Pl(i,"end")){let h=i,g=[];for(;g.push(h),!h.isTextblock;)h=h.lastChild;let y=r,x=1;for(;!y.isTextblock;y=y.firstChild)x++;if(h.canReplace(h.childCount,h.childCount,y.content)){if(a){let v=V.empty;for(let S=g.length-1;S>=0;
vendor: 4,510 bytes, line 17635
17635S--)v=V.from(g[S].copy(v));let w=t.tr.step(new Pt(e.pos-g.length,e.pos+r.nodeSize,e.pos+x,e.pos+r.nodeSize-x,new K(v,g.length,0),0,!0));a(w.scrollIntoView())}return!0}}return!1}function IM(t){return function(e,a){let n=e.selection,i=t<0?n.$from:n.$to,r=i.depth;for(;i.node(r).isInline;){if(!r)return!1;r--}return i.node(r).isTextblock?(a&&a(e.tr.setSelection(ce.create(e.doc,t<0?i.start(r):i.end(r)))),!0):!1}}const yre=IM(-1),xre=IM(1);function vre(t,e=null){return function(a,n){let{$from:i,$to:r}=a.selection,o=i.blockRange(r),l=o&&Xk(o,t,e);return l?(n&&n(a.tr.wrap(o,l).scrollIntoView()),!0):!1}}function Vj(t,e=null){return function(a,n){let i=!1;for(let r=0;r<a.selection.ranges.length&&!i;r++){let{$from:{pos:o},$to:{pos:l}}=a.selection.ranges[r];a.doc.nodesBetween(o,l,(c,d)=>{if(i)return!1;if(!(!c.isTextblock||c.hasMarkup(t,e)))if(c.type==t)i=!0;else{let u=a.doc.resolve(d),p=u.index();i=u.parent.canReplaceWith(p,p+1,t)}})}if(!i)return!1;if(n){let r=a.tr;for(let o=0;o<a.selection.ranges.length;o++){let{$from:{pos:l},$to:{pos:c}}=a.selection.ranges[o];r.setBlockType(l,c,t,e)}n(r.scrollIntoView())}return!0}}function nS(...t){return function(e,a,n){for(let i=0;i<t.length;i++)if(t[i](e,a,n))return!0;return!1}}nS(Zk,wM,SM);nS(Zk,AM,EM);nS(CM,jM,TM,hre);typeof navigator<"u"?/Mac|iP(hone|[oa]d)/.test(navigator.platform):typeof os<"u"&&os.platform&&os.platform()=="darwin";function bre(t,e=null){return function(a,n){let{$from:i,$to:r}=a.selection,o=i.blockRange(r);if(!o)return!1;let l=n?a.tr:null;return wre(l,o,t,e)?(n&&n(l.scrollIntoView()),!0):!1}}function wre(t,e,a,n=null){let i=!1,r=e,o=e.$from.doc;if(e.depth>=2&&e.$from.node(e.depth-1).type.compatibleContent(a)&&e.startIndex==0){if(e.$from.index(e.depth-1)==0)return!1;let c=o.resolve(e.start-2);r=new Xh(c,c,e.depth),e.endIndex<e.parent.childCount&&(e=new Xh(e.$from,o.resolve(e.$to.end(e.depth)),e.depth)),i=!0}let l=Xk(r,a,n,e);return l?(t&&kre(t,e,l,i,a),!0):!1}function kre(t,e,a,n,i){let r=V.empty;for(let u=a.length-1;u>=0;u--)r=V.from(a[u].type.create(a[u].attrs,r));t.step(new Pt(e.start-(n?2:0),e.end,e.start,e.end,new K(r,0,0),a.length,!0));let o=0;for(let u=0;u<a.length;u++)a[u].type==i&&(o=u+1);let l=a.length-o,c=e.start+a.length-(n?2:0),d=e.parent;for(let u=e.startIndex,p=e.endIndex,m=!0;u<p;u++,m=!1)!m&&Ii(t.doc,c,l)&&(t.split(c,l),c+=2*l),c+=d.child(u).nodeSize;return t}function Sre(t){return function(e,a){let{$from:n,$to:i}=e.selection,r=n.blockRange(i,o=>o.childCount>0&&o.firstChild.type==t);return r?a?n.node(r.depth-1).type==t?_re(e,a,t,r):Are(e,a,r):!0:!1}}function _re(t,e,a,n){let i=t.tr,r=n.end,o=n.$to.end(n.depth);r<o&&(i.step(new Pt(r-1,o,r,o,new K(V.from(a.create(null,n.parent.copy())),1,0),1,!0)),n=new Xh(i.doc.resolve(n.$from.pos),i.doc.resolve(o),n.depth));const l=ec(n);if(l==null)return!1;i.lift(n,l);let c=i.doc.resolve(i.mapping.map(r,-1)-1);return eo(i.doc,c.pos)&&c.nodeBefore.type==c.nodeAfter.type&&i.join(c.pos),e(i.scrollIntoView()),!0}function Are(t,e,a){let n=t.tr,i=a.parent;for(let h=a.end,g=a.endIndex-1,y=a.startIndex;g>y;g--)h-=i.child(g).nodeSize,n.delete(h-1,h+1);let r=n.doc.resolve(a.start),o=r.nodeAfter;if(n.mapping.map(a.end)!=a.start+r.nodeAfter.nodeSize)return!1;let l=a.startIndex==0,c=a.endIndex==i.childCount,d=r.node(-1),u=r.index(-1);if(!d.canReplace(u+(l?0:1),u+1,o.content.append(c?V.empty:V.from(i))))return!1;let p=r.pos,m=p+o.nodeSize;return n.step(new Pt(p-(l?1:0),m+(c?1:0),p+1,m-1,new K((l?V.empty:V.from(i.copy(V.empty))).append(c?V.empty:V.from(i.copy(V.empty))),l?0:1,c?0:1),l?0:1)),e(n.scrollIntoView()),!0}function Ere(t){return function(e,a){let{$from:n,$to:i}=e.selection,r=n.blockRange(i,d=>d.childCount>0&&d.firstChild.type==t);if(!r)return!1;let o=r.startIndex;if(o==0)return!1;let l=r.parent,c=l.child(o-1);if(c.type!=t)return!1;if(a){let d=c.lastChild&&c.lastChild.type==l.type,u=V.from(d?t.create():null),p=new K(V.from(t.create(null,V.from(l.type.create(null,u)))),d?3:1,0),m=r.start,h=r.end;a(e.tr.step(new Pt(m-(d?3:1),h,m,h,p,1,!0)).scrollIntoView())}return!0}}const zt=function(t){for(var e=0;;e++)if(t=t.previousSibling,!t)return e},Rl=function(t){let e=t.assignedSlot||t.parentNode;return e&&e.nodeType==11?e.host:e};let jb=null;const gi=function(t,e,a){let n=jb||(jb=document.createRange());return n.setEnd(t,a??t.nodeValue.length),n.setStart(t,e||0),n},Cre=function(){jb=null},is=function(t,e,a,n){return a&&(Hj(t,e,a,n,-1)||Hj(t,e,a,n,1))},jre=/^(img|br|input|textarea|hr)$/i;function Hj(t,e,a,n,i){for(var r;;){if(t==a&&e==n)return!0;
vendor: 4,508 bytes, line 17635
17635if(e==(i<0?0:on(t))){let o=t.parentNode;if(!o||o.nodeType!=1||Gu(t)||jre.test(t.nodeName)||t.contentEditable=="false")return!1;e=zt(t)+(i<0?0:1),t=o}else if(t.nodeType==1){let o=t.childNodes[e+(i<0?-1:0)];if(o.nodeType==1&&o.contentEditable=="false")if(!((r=o.pmViewDesc)===null||r===void 0)&&r.ignoreForSelection)e+=i;else return!1;else t=o,e=i<0?on(t):0}else return!1}}function on(t){return t.nodeType==3?t.nodeValue.length:t.childNodes.length}function Tre(t,e){for(;;){if(t.nodeType==3&&e)return t;if(t.nodeType==1&&e>0){if(t.contentEditable=="false")return null;t=t.childNodes[e-1],e=on(t)}else if(t.parentNode&&!Gu(t))e=zt(t),t=t.parentNode;else return null}}function Nre(t,e){for(;;){if(t.nodeType==3&&e<t.nodeValue.length)return t;if(t.nodeType==1&&e<t.childNodes.length){if(t.contentEditable=="false")return null;t=t.childNodes[e],e=0}else if(t.parentNode&&!Gu(t))e=zt(t)+1,t=t.parentNode;else return null}}function Ire(t,e,a){for(let n=e==0,i=e==on(t);n||i;){if(t==a)return!0;let r=zt(t);if(t=t.parentNode,!t)return!1;n=n&&r==0,i=i&&r==on(t)}}function Gu(t){let e;for(let a=t;a&&!(e=a.pmViewDesc);a=a.parentNode);return e&&e.node&&e.node.isBlock&&(e.dom==t||e.contentDOM==t)}const Hg=function(t){return t.focusNode&&is(t.focusNode,t.focusOffset,t.anchorNode,t.anchorOffset)};function yo(t,e){let a=document.createEvent("Event");return a.initEvent("keydown",!0,!0),a.keyCode=t,a.key=a.code=e,a}function Pre(t){let e=t.activeElement;for(;e&&e.shadowRoot;)e=e.shadowRoot.activeElement;return e}function Rre(t,e,a){if(t.caretPositionFromPoint)try{let n=t.caretPositionFromPoint(e,a);if(n)return{node:n.offsetNode,offset:Math.min(on(n.offsetNode),n.offset)}}catch{}if(t.caretRangeFromPoint){let n=t.caretRangeFromPoint(e,a);if(n)return{node:n.startContainer,offset:Math.min(on(n.startContainer),n.startOffset)}}}const ri=typeof navigator<"u"?navigator:null,Fj=typeof document<"u"?document:null,to=ri&&ri.userAgent||"",Tb=/Edge\/(\d+)/.exec(to),PM=/MSIE \d/.exec(to),Nb=/Trident\/(?:[7-9]|\d{2,})\..*rv:(\d+)/.exec(to),Ra=!!(PM||Nb||Tb),Lr=PM?document.documentMode:Nb?+Nb[1]:Tb?+Tb[1]:0,dn=!Ra&&/gecko\/(\d+)/i.test(to);dn&&+(/Firefox\/(\d+)/.exec(to)||[0,0])[1];const Ib=!Ra&&/Chrome\/(\d+)/.exec(to),Nt=!!Ib,RM=Ib?+Ib[1]:0,Wt=!Ra&&!!ri&&/Apple Computer/.test(ri.vendor),Ll=Wt&&(/Mobile\/\w+/.test(to)||!!ri&&ri.maxTouchPoints>2),an=Ll||(ri?/Mac/.test(ri.platform):!1),LM=ri?/Win/.test(ri.platform):!1,Ai=/Android \d/.test(to),Ku=!!Fj&&"webkitFontSmoothing"in Fj.documentElement.style,Lre=Ku?+(/\bAppleWebKit\/(\d+)/.exec(navigator.userAgent)||[0,0])[1]:0;function Ore(t){let e=t.defaultView&&t.defaultView.visualViewport;return e?{left:0,right:e.width,top:0,bottom:e.height}:{left:0,right:t.documentElement.clientWidth,top:0,bottom:t.documentElement.clientHeight}}function ui(t,e){return typeof t=="number"?t:t[e]}function Mre(t){let e=t.getBoundingClientRect(),a=e.width/t.offsetWidth||1,n=e.height/t.offsetHeight||1;return{left:e.left,right:e.left+t.clientWidth*a,top:e.top,bottom:e.top+t.clientHeight*n}}function Bj(t,e,a){let n=t.someProp("scrollThreshold")||0,i=t.someProp("scrollMargin")||5,r=t.dom.ownerDocument;for(let o=a||t.dom;o;){if(o.nodeType!=1){o=Rl(o);continue}let l=o,c=l==r.body,d=c?Ore(r):Mre(l),u=0,p=0;if(e.top<d.top+ui(n,"top")?p=-(d.top-e.top+ui(i,"top")):e.bottom>d.bottom-ui(n,"bottom")&&(p=e.bottom-e.top>d.bottom-d.top?e.top+ui(i,"top")-d.top:e.bottom-d.bottom+ui(i,"bottom")),e.left<d.left+ui(n,"left")?u=-(d.left-e.left+ui(i,"left")):e.right>d.right-ui(n,"right")&&(u=e.right-d.right+ui(i,"right")),u||p)if(c)r.defaultView.scrollBy(u,p);else{let h=l.scrollLeft,g=l.scrollTop;p&&(l.scrollTop+=p),u&&(l.scrollLeft+=u);let y=l.scrollLeft-h,x=l.scrollTop-g;e={left:e.left-y,top:e.top-x,right:e.right-y,bottom:e.bottom-x}}let m=c?"fixed":getComputedStyle(o).position;if(/^(fixed|sticky)$/.test(m))break;o=m=="absolute"?o.offsetParent:Rl(o)}}function Dre(t){let e=t.dom.getBoundingClientRect(),a=Math.max(0,e.top),n,i;for(let r=(e.left+e.right)/2,o=a+1;o<Math.min(innerHeight,e.bottom);o+=5){let l=t.root.elementFromPoint(r,o);if(!l||l==t.dom||!t.dom.contains(l))continue;let c=l.getBoundingClientRect();if(c.top>=a-20){n=l,i=c.top;break}}return{refDOM:n,refTop:i,stack:OM(t.dom)}}function OM(t){let e=[],a=t.ownerDocument;for(let n=t;n&&(e.push({dom:n,top:n.scrollTop,left:n.scrollLeft}),t!=a);n=Rl(n));return e}function qre({refDOM:t,refTop:e,stack:a}){let n=t?t.getBoundingClientRect().top:0;MM(a,n==0?0:n-e)}function MM(t,e){for(let a=0;a<t.length;a++){let{dom:n,top:i,left:r}
vendor: 13,873 bytes, lines 17635-17636
17635=t[a];n.scrollTop!=i+e&&(n.scrollTop=i+e),n.scrollLeft!=r&&(n.scrollLeft=r)}}let As=null;function zre(t){if(t.setActive)return t.setActive();if(As)return t.focus(As);let e=OM(t);t.focus(As==null?{get preventScroll(){return As={preventScroll:!0},!0}}:void 0),As||(As=!1,MM(e,0))}function DM(t,e){let a,n=2e8,i,r=0,o=e.top,l=e.top,c,d;for(let u=t.firstChild,p=0;u;u=u.nextSibling,p++){let m;if(u.nodeType==1)m=u.getClientRects();else if(u.nodeType==3)m=gi(u).getClientRects();else continue;for(let h=0;h<m.length;h++){let g=m[h];if(g.top<=o&&g.bottom>=l){o=Math.max(g.bottom,o),l=Math.min(g.top,l);let y=g.left>e.left?g.left-e.left:g.right<e.left?e.left-g.right:0;if(y<n){a=u,n=y,i=y&&a.nodeType==3?{left:g.right<e.left?g.right:g.left,top:e.top}:e,u.nodeType==1&&y&&(r=p+(e.left>=(g.left+g.right)/2?1:0));continue}}else g.top>e.top&&!c&&g.left<=e.left&&g.right>=e.left&&(c=u,d={left:Math.max(g.left,Math.min(g.right,e.left)),top:g.top});!a&&(e.left>=g.right&&e.top>=g.top||e.left>=g.left&&e.top>=g.bottom)&&(r=p+1)}}return!a&&c&&(a=c,i=d,n=0),a&&a.nodeType==3?Vre(a,i):!a||n&&a.nodeType==1?{node:t,offset:r}:DM(a,i)}function Vre(t,e){let a=t.nodeValue.length,n=document.createRange(),i;for(let r=0;r<a;r++){n.setEnd(t,r+1),n.setStart(t,r);let o=er(n,1);if(o.top!=o.bottom&&iS(e,o)){i={node:t,offset:r+(e.left>=(o.left+o.right)/2?1:0)};break}}return n.detach(),i||{node:t,offset:0}}function iS(t,e){return t.left>=e.left-1&&t.left<=e.right+1&&t.top>=e.top-1&&t.top<=e.bottom+1}function Hre(t,e){let a=t.parentNode;return a&&/^li$/i.test(a.nodeName)&&e.left<t.getBoundingClientRect().left?a:t}function Fre(t,e,a){let{node:n,offset:i}=DM(e,a),r=-1;if(n.nodeType==1&&!n.firstChild){let o=n.getBoundingClientRect();r=o.left!=o.right&&a.left>(o.left+o.right)/2?1:-1}return t.docView.posFromDOM(n,i,r)}function Bre(t,e,a,n){let i=-1;for(let r=e,o=!1;r!=t.dom;){let l=t.docView.nearestDesc(r,!0),c;if(!l)return null;if(l.dom.nodeType==1&&(l.node.isBlock&&l.parent||!l.contentDOM)&&((c=l.dom.getBoundingClientRect()).width||c.height)&&(l.node.isBlock&&l.parent&&!/^T(R|BODY|HEAD|FOOT)$/.test(l.dom.nodeName)&&(!o&&c.left>n.left||c.top>n.top?i=l.posBefore:(!o&&c.right<n.left||c.bottom<n.top)&&(i=l.posAfter),o=!0),!l.contentDOM&&i<0&&!l.node.isText))return(l.node.isBlock?n.top<(c.top+c.bottom)/2:n.left<(c.left+c.right)/2)?l.posBefore:l.posAfter;r=l.dom.parentNode}return i>-1?i:t.docView.posFromDOM(e,a,-1)}function qM(t,e,a){let n=t.childNodes.length;if(n&&a.top<a.bottom)for(let i=Math.max(0,Math.min(n-1,Math.floor(n*(e.top-a.top)/(a.bottom-a.top))-2)),r=i;;){let o=t.childNodes[r];if(o.nodeType==1){let l=o.getClientRects();for(let c=0;c<l.length;c++){let d=l[c];if(iS(e,d))return qM(o,e,d)}}if((r=(r+1)%n)==i)break}return t}function Ure(t,e){let a=t.dom.ownerDocument,n,i=0,r=Rre(a,e.left,e.top);r&&({node:n,offset:i}=r);let o=(t.root.elementFromPoint?t.root:a).elementFromPoint(e.left,e.top),l;if(!o||!t.dom.contains(o.nodeType!=1?o.parentNode:o)){let d=t.dom.getBoundingClientRect();if(!iS(e,d)||(o=qM(t.dom,e,d),!o))return null}if(Wt)for(let d=o;n&&d;d=Rl(d))d.draggable&&(n=void 0);if(o=Hre(o,e),n){if(dn&&n.nodeType==1&&(i=Math.min(i,n.childNodes.length),i<n.childNodes.length)){let u=n.childNodes[i],p;u.nodeName=="IMG"&&(p=u.getBoundingClientRect()).right<=e.left&&p.bottom>e.top&&i++}let d;Ku&&i&&n.nodeType==1&&(d=n.childNodes[i-1]).nodeType==1&&d.contentEditable=="false"&&d.getBoundingClientRect().top>=e.top&&i--,n==t.dom&&i==n.childNodes.length-1&&n.lastChild.nodeType==1&&e.top>n.lastChild.getBoundingClientRect().bottom?l=t.state.doc.content.size:(i==0||n.nodeType!=1||n.childNodes[i-1].nodeName!="BR")&&(l=Bre(t,n,i,e))}l==null&&(l=Fre(t,o,e));let c=t.docView.nearestDesc(o,!0);return{pos:l,inside:c?c.posAtStart-c.border:-1}}function Uj(t){return t.top<t.bottom||t.left<t.right}function er(t,e){let a=t.getClientRects();if(a.length){let n=a[e<0?0:a.length-1];if(Uj(n))return n}return Array.prototype.find.call(a,Uj)||t.getBoundingClientRect()}const $re=/[\u0590-\u05f4\u0600-\u06ff\u0700-\u08ac]/;function zM(t,e,a){let{node:n,offset:i,atom:r}=t.docView.domFromPos(e,a<0?-1:1),o=Ku||dn;if(n.nodeType==3)if(o&&($re.test(n.nodeValue)||(a<0?!i:i==n.nodeValue.length))){let c=er(gi(n,i,i),a);if(dn&&i&&/\s/.test(n.nodeValue[i-1])&&i<n.nodeValue.length){let d=er(gi(n,i-1,i-1),-1);if(d.top==c.top){let u=er(gi(n,i,i+1),-1);if(u.top!=c.top)return Nc(u,u.left<d.left)}}return c}else{let c=i,d=i,u=a<0?1:-1;return a<0&&!i?(d++,u=-1):a>=0&&i==n.nodeValue.length?(c--,u=1):a<0?c--:d++,Nc(er(gi(n,c,d),u),u<0)}if(!t.state.doc.resolve(e-(r||0)).parent.inlineContent){if(r==null&&i&&(a<0||i==on(n))){let c=n.childNodes[i-1];if(c.nodeType==1)return X0(c.getBoundingClientRect(),!1)}if(r==null&&i<on(n)){let c=n.childNodes[i];if(c.nodeType==1)return X0(c.getBoundingClientRect(),!0)}return X0(n.getBoundingClientRect(),a>=0)}if(r==null&&i&&(a<0||i==on(n))){let c=n.childNodes[i-1],d=c.nodeType==3?gi(c,on(c)-(o?0:1)):c.nodeType==1&&(c.nodeName!="BR"||!c.nextSibling)?c:null;if(d)return Nc(er(d,1),!1)}if(r==null&&i<on(n)){let c=n.childNodes[i];for(;c.pmViewDesc&&c.pmViewDesc.ignoreForCoords;)c=c.nextSibling;let d=c?c.nodeType==3?gi(c,0,o?0:1):c.nodeType==1?c:null:null;if(d)return Nc(er(d,-1),!0)}return Nc(er(n.nodeType==3?gi(n):n,-a),a>=0)}function Nc(t,e){if(t.width==0)return t;let a=e?t.left:t.right;return{top:t.top,bottom:t.bottom,left:a,right:a}}function X0(t,e){if(t.height==0)return t;let a=e?t.top:t.bottom;return{top:a,bottom:a,left:t.left,right:t.right}}function VM(t,e,a){let n=t.state,i=t.root.activeElement;n!=e&&t.updateState(e),i!=t.dom&&t.focus();try{return a()}finally{n!=e&&t.updateState(n),i!=t.dom&&i&&i.focus()}}function Wre(t,e,a){let n=e.selection,i=a=="up"?n.$from:n.$to;return VM(t,e,()=>{let{node:r}=t.docView.domFromPos(i.pos,a=="up"?-1:1);for(;;){let l=t.docView.nearestDesc(r,!0);if(!l)break;if(l.node.isBlock){r=l.contentDOM||l.dom;break}r=l.dom.parentNode}let o=zM(t,i.pos,1);for(let l=r.firstChild;l;l=l.nextSibling){let c;if(l.nodeType==1)c=l.getClientRects();else if(l.nodeType==3)c=gi(l,0,l.nodeValue.length).getClientRects();else continue;for(let d=0;d<c.length;d++){let u=c[d];if(u.bottom>u.top+1&&(a=="up"?o.top-u.top>(u.bottom-o.top)*2:u.bottom-o.bottom>(o.bottom-u.top)*2))return!1}}return!0})}const Gre=/[\u0590-\u08ac]/;function Kre(t,e,a){let{$head:n}=e.selection;if(!n.parent.isTextblock)return!1;let i=n.parentOffset,r=!i,o=i==n.parent.content.size,l=t.domSelection();return l?!Gre.test(n.parent.textContent)||!l.modify?a=="left"||a=="backward"?r:o:VM(t,e,()=>{let{focusNode:c,focusOffset:d,anchorNode:u,anchorOffset:p}=t.domSelectionRange(),m=l.caretBidiLevel;l.modify("move",a,"character");let h=n.depth?t.docView.domAfterPos(n.before()):t.dom,{focusNode:g,focusOffset:y}=t.domSelectionRange(),x=g&&!h.contains(g.nodeType==1?g:g.parentNode)||c==g&&d==y;try{l.collapse(u,p),c&&(c!=u||d!=p)&&l.extend&&l.extend(c,d)}catch{}return m!=null&&(l.caretBidiLevel=m),x}):n.pos==n.start()||n.pos==n.end()}let $j=null,Wj=null,Gj=!1;function Jre(t,e,a){return $j==e&&Wj==a?Gj:($j=e,Wj=a,Gj=a=="up"||a=="down"?Wre(t,e,a):Kre(t,e,a))}const un=0,Kj=1,Eo=2,oi=3;class Ju{constructor(e,a,n,i){this.parent=e,this.children=a,this.dom=n,this.contentDOM=i,this.dirty=un,n.pmViewDesc=this}matchesWidget(e){return!1}matchesMark(e){return!1}matchesNode(e,a,n){return!1}matchesHack(e){return!1}parseRule(){return null}stopEvent(e){return!1}get size(){let e=0;for(let a=0;a<this.children.length;a++)e+=this.children[a].size;return e}get border(){return 0}destroy(){this.parent=void 0,this.dom.pmViewDesc==this&&(this.dom.pmViewDesc=void 0);for(let e=0;e<this.children.length;e++)this.children[e].destroy()}posBeforeChild(e){for(let a=0,n=this.posAtStart;;a++){let i=this.children[a];if(i==e)return n;n+=i.size}}get posBefore(){return this.parent.posBeforeChild(this)}get posAtStart(){return this.parent?this.parent.posBeforeChild(this)+this.border:0}get posAfter(){return this.posBefore+this.size}get posAtEnd(){return this.posAtStart+this.size-2*this.border}localPosFromDOM(e,a,n){if(this.contentDOM&&this.contentDOM.contains(e.nodeType==1?e:e.parentNode))if(n<0){let r,o;if(e==this.contentDOM)r=e.childNodes[a-1];else{for(;e.parentNode!=this.contentDOM;)e=e.parentNode;r=e.previousSibling}for(;r&&!((o=r.pmViewDesc)&&o.parent==this);)r=r.previousSibling;return r?this.posBeforeChild(o)+o.size:this.posAtStart}else{let r,o;if(e==this.contentDOM)r=e.childNodes[a];else{for(;e.parentNode!=this.contentDOM;)e=e.parentNode;r=e.nextSibling}for(;r&&!((o=r.pmViewDesc)&&o.parent==this);)r=r.nextSibling;return r?this.posBeforeChild(o):this.posAtEnd}let i;if(e==this.dom&&this.contentDOM)i=a>zt(this.contentDOM);else if(this.contentDOM&&this.contentDOM!=this.dom&&this.dom.contains(this.contentDOM))i=e.compareDocumentPosition(this.contentDOM)&2;else if(this.dom.firstChild){if(a==0)for(let r=e;;r=r.parentNode){if(r==this.dom){i=!1;break}if(r.previousSibling)break}if(i==null&&a==e.childNodes.length)for(let r=e;;r=r.parentNode){if(r==this.dom){i=!0;break}if(r.nextSibling)break}}return i??n>0?this.posAtEnd:this.posAtStart}nearestDesc(e,a=!1){for(let n=!0,i=e;i;i=i.parentNode){let r=this.getDesc(i),o;if(r&&(!a||r.node))if(n&&(o=r.nodeDOM)&&!(o.nodeType==1?o.contains(e.nodeType==1?e:e.parentNode):o==e))n=!1;else return r}}getDesc(e){let a=e.pmViewDesc;for(let n=a;n;n=n.parent)if(n==this)return a}posFromDOM(e,a,n){for(let i=e;i;i=i.parentNode){let r=this.getDesc(i);if(r)return r.localPosFromDOM(e,a,n)}return-1}descAt(e){for(let a=0,n=0;a<this.children.length;a++){let i=this.children[a],r=n+i.size;if(n==e&&r!=n){for(;!i.border&&i.children.length;)for(let o=0;o<i.children.length;o++){let l=i.children[o];if(l.size){i=l;break}}return i}if(e<r)return i.descAt(e-n-i.border);n=r}}domFromPos(e,a){if(!this.contentDOM)return{node:this.dom,offset:0,atom:e+1};let n=0,i=0;for(let r=0;n<this.children.length;n++){let o=this.children[n],l=r+o.size;if(l>e||o instanceof FM){i=e-r;break}r=l}if(i)return this.children[n].domFromPos(i-this.children[n].border,a);for(let r;n&&!(r=this.children[n-1]).size&&r instanceof HM&&r.side>=0;n--);if(a<=0){let r,o=!0;for(;r=n?this.children[n-1]:null,!(!r||r.dom.parentNode==this.contentDOM);n--,o=!1);return r&&a&&o&&!r.border&&!r.domAtom?r.domFromPos(r.size,a):{node:this.contentDOM,offset:r?zt(r.dom)+1:0}}else{let r,o=!0;for(;r=n<this.children.length?this.children[n]:null,!(!r||r.dom.parentNode==this.contentDOM);n++,o=!1);return r&&o&&!r.border&&!r.domAtom?r.domFromPos(0,a):{node:this.contentDOM,offset:r?zt(r.dom):this.contentDOM.childNodes.length}}}parseRange(e,a,n=0){if(this.children.length==0)return{node:this.contentDOM,from:e,to:a,fromOffset:0,toOffset:this.contentDOM.childNodes.length};let i=-1,r=-1;for(let o=n,l=0;;l++){let c=this.children[l],d=o+c.size;if(i==-1&&e<=d){let u=o+c.border;if(e>=u&&a<=d-c.border&&c.node&&c.contentDOM&&this.contentDOM.contains(c.contentDOM))return c.parseRange(e,a,u);e=o;for(let p=l;p>0;p--){let m=this.children[p-1];if(m.size&&m.dom.parentNode==this.contentDOM&&!m.emptyChildAt(1)){i=zt(m.dom)+1;break}e-=m.size}i==-1&&(i=0)}if(i>-1&&(d>a||l==this.children.length-1)){a=d;for(let u=l+1;u<this.children.length;u++){let p=this.children[u];if(p.size&&p.dom.parentNode==this.contentDOM&&!p.emptyChildAt(-1)){r=zt(p.dom);break}a+=p.size}r==-1&&(r=this.contentDOM.childNodes.length);break}o=d}return{node:this.contentDOM,from:e,to:a,fromOffset:i,toOffset:r}}emptyChildAt(e){if(this.border||!this.contentDOM||!this.children.length)return!1;let a=this.children[e<0?0:this.children.length-1];return a.size==0||a.emptyChildAt(e)}domAfterPos(e){let{node:a,offset:n}=this.domFromPos(e,0);if(a.nodeType!=1||n==a.childNodes.length)throw new RangeError("No node after pos "+e);return a.childNodes[n]}setSelection(e,a,n,i=!1){let r=Math.min(e,a),o=Math.max(e,a);for(let h=0,g=0;h<this.children.length;h++){let y=this.children[h],x=g+y.size;if(r>g&&o<x)return y.setSelection(e-g-y.border,a-g-y.border,n,i);g=x}let l=this.domFromPos(e,e?-1:1),c=a==e?l:this.domFromPos(a,a?-1:1),d=n.root.getSelection(),u=n.domSelectionRange(),p=!1;if((dn||Wt)&&e==a){let{node:h,offset:g}=l;if(h.nodeType==3){if(p=!!(g&&h.nodeValue[g-1]==`
17636`),p&&g==h.nodeValue.length)for(let y=h,x;y;y=y.parentNode){if(x=y.nextSibling){x.nodeName=="BR"&&(l=c={node:x.parentNode,offset:zt(x)+1});break}let v=y.pmViewDesc;if(v&&v.node&&v.node.isBlock)break}}else{let y=h.childNodes[g-1];p=y&&(y.nodeName=="BR"||y.contentEditable=="false")}}if(dn&&u.focusNode&&u.focusNode!=c.node&&u.focusNode.nodeType==1){let h=u.focusNode.childNodes[u.focusOffset];h&&h.contentEditable=="false"&&(i=!0)}if(!(i||p&&Wt)&&is(l.node,l.offset,u.anchorNode,u.anchorOffset)&&is(c.node,c.offset,u.focusNode,u.focusOffset))return;let m=!1;if((d.extend||e==a)&&!(p&&dn)){d.collapse(l.node,l.offset);try{e!=a&&d.extend(c.node,c.offset),m=!0}catch{}}if(!m){if(e>a){let g=l;l=c,c=g}let h=document.createRange();h.setEnd(c.node,c.offset),h.setStart(l.node,l.offset),d.removeAllRanges(),d.addRange(h)}}ignoreMutation(e){return!this.contentDOM&&e.type!="selection"}get contentLost(){return this.contentDOM&&this.contentDOM!=this.dom&&!this.dom.contains(this.contentDOM)}markDirty(e,a){for(let n=0,i=0;i<this.children.length;i++){let r=this.children[i],o=n+r.size;if(n==o?e<=o&&a>=n:e<o&&a>n){let l=n+r.border,c=o-r.border;if(e>=l&&a<=c){this.dirty=e==n||a==o?Eo:Kj,e==l&&a==c&&(r.contentLost||r.dom.parentNode!=this.contentDOM)?r.dirty=oi:r.markDirty(e-l,a-l);return}else r.dirty=r.dom==r.contentDOM&&r.dom.parentNode==this.contentDOM&&!r.children.length?Eo:oi}n=o}this.dirty=Eo}markParentsDirty(){let e=1;for(let a=this.parent;a;a=a.parent,e++){let n=e==1?Eo:Kj;a.dirty<n&&(a.dirty=n)}}get domAtom(){return!1}get ignoreForCoords(){return!1}get ignoreForSelection(){return!1}isText(e){return!1}}class HM extends Ju{constructor(e,a,n,i){let r,o=a.type.toDOM;if(typeof o=="function"&&(o=o(n,()=>{if(!r)return i;if(r.parent)return r.parent.posBeforeChild(r)}
vendor: 4,625 bytes, line 17636
17636)),!a.type.spec.raw){if(o.nodeType!=1){let l=document.createElement("span");l.appendChild(o),o=l}o.contentEditable="false",o.classList.add("ProseMirror-widget")}super(e,[],o,null),this.widget=a,this.widget=a,r=this}matchesWidget(e){return this.dirty==un&&e.type.eq(this.widget.type)}parseRule(){return{ignore:!0}}stopEvent(e){let a=this.widget.spec.stopEvent;return a?a(e):!1}ignoreMutation(e){return e.type!="selection"||this.widget.spec.ignoreSelection}destroy(){this.widget.type.destroy(this.dom),super.destroy()}get domAtom(){return!0}get ignoreForSelection(){return!!this.widget.type.spec.relaxedSide}get side(){return this.widget.type.side}}class Qre extends Ju{constructor(e,a,n,i){super(e,[],a,null),this.textDOM=n,this.text=i}get size(){return this.text.length}localPosFromDOM(e,a){return e!=this.textDOM?this.posAtStart+(a?this.size:0):this.posAtStart+a}domFromPos(e){return{node:this.textDOM,offset:e}}ignoreMutation(e){return e.type==="characterData"&&e.target.nodeValue==e.oldValue}}class rs extends Ju{constructor(e,a,n,i,r){super(e,[],n,i),this.mark=a,this.spec=r}static create(e,a,n,i){let r=i.nodeViews[a.type.name],o=r&&r(a,i,n);return(!o||!o.dom)&&(o=fs.renderSpec(document,a.type.spec.toDOM(a,n),null,a.attrs)),new rs(e,a,o.dom,o.contentDOM||o.dom,o)}parseRule(){return this.dirty&oi||this.mark.type.spec.reparseInView?null:{mark:this.mark.type.name,attrs:this.mark.attrs,contentElement:this.contentDOM}}matchesMark(e){return this.dirty!=oi&&this.mark.eq(e)}markDirty(e,a){if(super.markDirty(e,a),this.dirty!=un){let n=this.parent;for(;!n.node;)n=n.parent;n.dirty<this.dirty&&(n.dirty=this.dirty),this.dirty=un}}slice(e,a,n){let i=rs.create(this.parent,this.mark,!0,n),r=this.children,o=this.size;a<o&&(r=Rb(r,a,o,n)),e>0&&(r=Rb(r,0,e,n));for(let l=0;l<r.length;l++)r[l].parent=i;return i.children=r,i}ignoreMutation(e){return this.spec.ignoreMutation?this.spec.ignoreMutation(e):super.ignoreMutation(e)}destroy(){this.spec.destroy&&this.spec.destroy(),super.destroy()}}class Or extends Ju{constructor(e,a,n,i,r,o,l,c,d){super(e,[],r,o),this.node=a,this.outerDeco=n,this.innerDeco=i,this.nodeDOM=l}static create(e,a,n,i,r,o){let l=r.nodeViews[a.type.name],c,d=l&&l(a,r,()=>{if(!c)return o;if(c.parent)return c.parent.posBeforeChild(c)},n,i),u=d&&d.dom,p=d&&d.contentDOM;if(a.isText){if(!u)u=document.createTextNode(a.text);else if(u.nodeType!=3)throw new RangeError("Text must be rendered as a DOM text node")}else u||({dom:u,contentDOM:p}=fs.renderSpec(document,a.type.spec.toDOM(a),null,a.attrs));!p&&!a.isText&&u.nodeName!="BR"&&(u.hasAttribute("contenteditable")||(u.contentEditable="false"),a.type.spec.draggable&&(u.draggable=!0));let m=u;return u=$M(u,n,a),d?c=new Xre(e,a,n,i,u,p||null,m,d,r,o+1):a.isText?new Fg(e,a,n,i,u,m,r):new Or(e,a,n,i,u,p||null,m,r,o+1)}parseRule(){if(this.node.type.spec.reparseInView)return null;let e={node:this.node.type.name,attrs:this.node.attrs};if(this.node.type.whitespace=="pre"&&(e.preserveWhitespace="full"),!this.contentDOM)e.getContent=()=>this.node.content;else if(!this.contentLost)e.contentElement=this.contentDOM;else{for(let a=this.children.length-1;a>=0;a--){let n=this.children[a];if(this.dom.contains(n.dom.parentNode)){e.contentElement=n.dom.parentNode;break}}e.contentElement||(e.getContent=()=>V.empty)}return e}matchesNode(e,a,n){return this.dirty==un&&e.eq(this.node)&&Zh(a,this.outerDeco)&&n.eq(this.innerDeco)}get size(){return this.node.nodeSize}get border(){return this.node.isLeaf?0:1}updateChildren(e,a){let n=this.node.inlineContent,i=a,r=e.composing?this.localCompositionInfo(e,a):null,o=r&&r.pos>-1?r:null,l=r&&r.pos<0,c=new Zre(this,o&&o.node,e);aoe(this.node,this.innerDeco,(d,u,p)=>{d.spec.marks?c.syncToMarks(d.spec.marks,n,e,u):d.type.side>=0&&!p&&c.syncToMarks(u==this.node.childCount?qe.none:this.node.child(u).marks,n,e,u),c.placeWidget(d,e,i)},(d,u,p,m)=>{c.syncToMarks(d.marks,n,e,m);let h;c.findNodeMatch(d,u,p,m)||l&&e.state.selection.from>i&&e.state.selection.to<i+d.nodeSize&&(h=c.findIndexWithChild(r.node))>-1&&c.updateNodeAt(d,u,p,h,e)||c.updateNextNode(d,u,p,e,m,i)||c.addNode(d,u,p,e,i),i+=d.nodeSize}),c.syncToMarks([],n,e,0),this.node.isTextblock&&c.addTextblockHacks(),c.destroyRest(),(c.changed||this.dirty==Eo)&&(o&&this.protectLocalComposition(e,o),BM(this.contentDOM,this.children,e),Ll&&noe(this.dom))}localCompositionInfo(e,a){let{from:n,to:i}=e.state.selection;if(!(e.state.selection instanceof ce)||n<a||i>a+this.node.content.size)return null;let r=e.input.compositionNode;if(!r||!this.dom.contains(r.parentNode))return null;if(this.node.inlineContent){let o=r.nodeValue,l=ioe(this.node.content,o,n-a,i-a);
vendor: 5,034 bytes, line 17636
17636return l<0?null:{node:r,pos:l,text:o}}else return{node:r,pos:-1,text:""}}protectLocalComposition(e,{node:a,pos:n,text:i}){if(this.getDesc(a))return;let r=a;for(;r.parentNode!=this.contentDOM;r=r.parentNode){for(;r.previousSibling;)r.parentNode.removeChild(r.previousSibling);for(;r.nextSibling;)r.parentNode.removeChild(r.nextSibling);r.pmViewDesc&&(r.pmViewDesc=void 0)}let o=new Qre(this,r,a,i);e.input.compositionNodes.push(o),this.children=Rb(this.children,n,n+i.length,e,o)}update(e,a,n,i){return this.dirty==oi||!e.sameMarkup(this.node)?!1:(this.updateInner(e,a,n,i),!0)}updateInner(e,a,n,i){this.updateOuterDeco(a),this.node=e,this.innerDeco=n,this.contentDOM&&this.updateChildren(i,this.posAtStart),this.dirty=un}updateOuterDeco(e){if(Zh(e,this.outerDeco))return;let a=this.nodeDOM.nodeType!=1,n=this.dom;this.dom=UM(this.dom,this.nodeDOM,Pb(this.outerDeco,this.node,a),Pb(e,this.node,a)),this.dom!=n&&(n.pmViewDesc=void 0,this.dom.pmViewDesc=this),this.outerDeco=e}selectNode(){this.nodeDOM.nodeType==1&&(this.nodeDOM.classList.add("ProseMirror-selectednode"),(this.contentDOM||!this.node.type.spec.draggable)&&(this.nodeDOM.draggable=!0))}deselectNode(){this.nodeDOM.nodeType==1&&(this.nodeDOM.classList.remove("ProseMirror-selectednode"),(this.contentDOM||!this.node.type.spec.draggable)&&this.nodeDOM.removeAttribute("draggable"))}get domAtom(){return this.node.isAtom}}function Jj(t,e,a,n,i){$M(n,e,t);let r=new Or(void 0,t,e,a,n,n,n,i,0);return r.contentDOM&&r.updateChildren(i,0),r}class Fg extends Or{constructor(e,a,n,i,r,o,l){super(e,a,n,i,r,null,o,l,0)}parseRule(){let e=this.nodeDOM.parentNode;for(;e&&e!=this.dom&&!e.pmIsDeco;)e=e.parentNode;return{skip:e||!0}}update(e,a,n,i){return this.dirty==oi||this.dirty!=un&&!this.inParent()||!e.sameMarkup(this.node)?!1:(this.updateOuterDeco(a),(this.dirty!=un||e.text!=this.node.text)&&e.text!=this.nodeDOM.nodeValue&&(this.nodeDOM.nodeValue=e.text,i.trackWrites==this.nodeDOM&&(i.trackWrites=null)),this.node=e,this.dirty=un,!0)}inParent(){let e=this.parent.contentDOM;for(let a=this.nodeDOM;a;a=a.parentNode)if(a==e)return!0;return!1}domFromPos(e){return{node:this.nodeDOM,offset:e}}localPosFromDOM(e,a,n){return e==this.nodeDOM?this.posAtStart+Math.min(a,this.node.text.length):super.localPosFromDOM(e,a,n)}ignoreMutation(e){return e.type!="characterData"&&e.type!="selection"}slice(e,a,n){let i=this.node.cut(e,a),r=document.createTextNode(i.text);return new Fg(this.parent,i,this.outerDeco,this.innerDeco,r,r,n)}markDirty(e,a){super.markDirty(e,a),this.dom!=this.nodeDOM&&(e==0||a==this.nodeDOM.nodeValue.length)&&(this.dirty=oi)}get domAtom(){return!1}isText(e){return this.node.text==e}}class FM extends Ju{parseRule(){return{ignore:!0}}matchesHack(e){return this.dirty==un&&this.dom.nodeName==e}get domAtom(){return!0}get ignoreForCoords(){return this.dom.nodeName=="IMG"}}class Xre extends Or{constructor(e,a,n,i,r,o,l,c,d,u){super(e,a,n,i,r,o,l,d,u),this.spec=c}update(e,a,n,i){if(this.dirty==oi)return!1;if(this.spec.update&&(this.node.type==e.type||this.spec.multiType)){let r=this.spec.update(e,a,n);return r&&this.updateInner(e,a,n,i),r}else return!this.contentDOM&&!e.isLeaf?!1:super.update(e,a,n,i)}selectNode(){this.spec.selectNode?this.spec.selectNode():super.selectNode()}deselectNode(){this.spec.deselectNode?this.spec.deselectNode():super.deselectNode()}setSelection(e,a,n,i){this.spec.setSelection?this.spec.setSelection(e,a,n.root):super.setSelection(e,a,n,i)}destroy(){this.spec.destroy&&this.spec.destroy(),super.destroy()}stopEvent(e){return this.spec.stopEvent?this.spec.stopEvent(e):!1}ignoreMutation(e){return this.spec.ignoreMutation?this.spec.ignoreMutation(e):super.ignoreMutation(e)}}function BM(t,e,a){let n=t.firstChild,i=!1;for(let r=0;r<e.length;r++){let o=e[r],l=o.dom;if(l.parentNode==t){for(;l!=n;)n=Qj(n),i=!0;n=n.nextSibling}else i=!0,t.insertBefore(l,n);if(o instanceof rs){let c=n?n.previousSibling:t.lastChild;BM(o.contentDOM,o.children,a),n=c?c.nextSibling:t.firstChild}}for(;n;)n=Qj(n),i=!0;i&&a.trackWrites==t&&(a.trackWrites=null)}const wd=function(t){t&&(this.nodeName=t)};wd.prototype=Object.create(null);const Co=[new wd];function Pb(t,e,a){if(t.length==0)return Co;let n=a?Co[0]:new wd,i=[n];for(let r=0;r<t.length;r++){let o=t[r].type.attrs;if(o){o.nodeName&&i.push(n=new wd(o.nodeName));for(let l in o){let c=o[l];c!=null&&(a&&i.length==1&&i.push(n=new wd(e.isInline?"span":"div")),l=="class"?n.class=(n.class?n.class+" ":"")+c:l=="style"?n.style=(n.style?n.style+";":"")+c:l!="nodeName"&&(n[l]=c))}}}return i}function UM(t,e,a,n){if(a==Co&&n==Co)return e;let i=e;for(let r=0;r<n.length;r++){let o=n[r],l=a[r];if(r){let c;l&&l.nodeName==o.nodeName&&i!=t&&(c=i.parentNode)&&c.nodeName.toLowerCase()==o.nodeName||(c=document.createElement(o.nodeName),c.pmIsDeco=!0,c.appendChild(i),l=Co[0]),i=c}Yre(i,l||Co[0],o)}return i}function Yre(t,e,a){for(let n in e)n!="class"&&n!="style"&&n!="nodeName"&&!(n in a)&&t.removeAttribute(n);for(let n in a)n!="class"&&n!="style"&&n!="nodeName"&&a[n]!=e[n]&&t.setAttribute(n,a[n]);
vendor: 6,195 bytes, line 17636
17636if(e.class!=a.class){let n=e.class?e.class.split(" ").filter(Boolean):[],i=a.class?a.class.split(" ").filter(Boolean):[];for(let r=0;r<n.length;r++)i.indexOf(n[r])==-1&&t.classList.remove(n[r]);for(let r=0;r<i.length;r++)n.indexOf(i[r])==-1&&t.classList.add(i[r]);t.classList.length==0&&t.removeAttribute("class")}if(e.style!=a.style){if(e.style){let n=/\s*([\w\-\xa1-\uffff]+)\s*:(?:"(?:\\.|[^"])*"|'(?:\\.|[^'])*'|\(.*?\)|[^;])*/g,i;for(;i=n.exec(e.style);)t.style.removeProperty(i[1])}a.style&&(t.style.cssText+=a.style)}}function $M(t,e,a){return UM(t,t,Co,Pb(e,a,t.nodeType!=1))}function Zh(t,e){if(t.length!=e.length)return!1;for(let a=0;a<t.length;a++)if(!t[a].type.eq(e[a].type))return!1;return!0}function Qj(t){let e=t.nextSibling;return t.parentNode.removeChild(t),e}class Zre{constructor(e,a,n){this.lock=a,this.view=n,this.index=0,this.stack=[],this.changed=!1,this.top=e,this.preMatch=eoe(e.node.content,e)}destroyBetween(e,a){if(e!=a){for(let n=e;n<a;n++)this.top.children[n].destroy();this.top.children.splice(e,a-e),this.changed=!0}}destroyRest(){this.destroyBetween(this.index,this.top.children.length)}syncToMarks(e,a,n,i){let r=0,o=this.stack.length>>1,l=Math.min(o,e.length);for(;r<l&&(r==o-1?this.top:this.stack[r+1<<1]).matchesMark(e[r])&&e[r].type.spec.spanning!==!1;)r++;for(;r<o;)this.destroyRest(),this.top.dirty=un,this.index=this.stack.pop(),this.top=this.stack.pop(),o--;for(;o<e.length;){this.stack.push(this.top,this.index+1);let c=-1,d=this.top.children.length;i<this.preMatch.index&&(d=Math.min(this.index+3,d));for(let u=this.index;u<d;u++){let p=this.top.children[u];if(p.matchesMark(e[o])&&!this.isLocked(p.dom)){c=u;break}}if(c>-1)c>this.index&&(this.changed=!0,this.destroyBetween(this.index,c)),this.top=this.top.children[this.index];else{let u=rs.create(this.top,e[o],a,n);this.top.children.splice(this.index,0,u),this.top=u,this.changed=!0}this.index=0,o++}}findNodeMatch(e,a,n,i){let r=-1,o;if(i>=this.preMatch.index&&(o=this.preMatch.matches[i-this.preMatch.index]).parent==this.top&&o.matchesNode(e,a,n))r=this.top.children.indexOf(o,this.index);else for(let l=this.index,c=Math.min(this.top.children.length,l+5);l<c;l++){let d=this.top.children[l];if(d.matchesNode(e,a,n)&&!this.preMatch.matched.has(d)){r=l;break}}return r<0?!1:(this.destroyBetween(this.index,r),this.index++,!0)}updateNodeAt(e,a,n,i,r){let o=this.top.children[i];return o.dirty==oi&&o.dom==o.contentDOM&&(o.dirty=Eo),o.update(e,a,n,r)?(this.destroyBetween(this.index,i),this.index++,!0):!1}findIndexWithChild(e){for(;;){let a=e.parentNode;if(!a)return-1;if(a==this.top.contentDOM){let n=e.pmViewDesc;if(n){for(let i=this.index;i<this.top.children.length;i++)if(this.top.children[i]==n)return i}return-1}e=a}}updateNextNode(e,a,n,i,r,o){for(let l=this.index;l<this.top.children.length;l++){let c=this.top.children[l];if(c instanceof Or){let d=this.preMatch.matched.get(c);if(d!=null&&d!=r)return!1;let u=c.dom,p,m=this.isLocked(u)&&!(e.isText&&c.node&&c.node.isText&&c.nodeDOM.nodeValue==e.text&&c.dirty!=oi&&Zh(a,c.outerDeco));if(!m&&c.update(e,a,n,i))return this.destroyBetween(this.index,l),c.dom!=u&&(this.changed=!0),this.index++,!0;if(!m&&(p=this.recreateWrapper(c,e,a,n,i,o)))return this.destroyBetween(this.index,l),this.top.children[this.index]=p,p.contentDOM&&(p.dirty=Eo,p.updateChildren(i,o+1),p.dirty=un),this.changed=!0,this.index++,!0;break}}return!1}recreateWrapper(e,a,n,i,r,o){if(e.dirty||a.isAtom||!e.children.length||!e.node.content.eq(a.content)||!Zh(n,e.outerDeco)||!i.eq(e.innerDeco))return null;let l=Or.create(this.top,a,n,i,r,o);if(l.contentDOM){l.children=e.children,e.children=[];for(let c of l.children)c.parent=l}return e.destroy(),l}addNode(e,a,n,i,r){let o=Or.create(this.top,e,a,n,i,r);o.contentDOM&&o.updateChildren(i,r+1),this.top.children.splice(this.index++,0,o),this.changed=!0}placeWidget(e,a,n){let i=this.index<this.top.children.length?this.top.children[this.index]:null;if(i&&i.matchesWidget(e)&&(e==i.widget||!i.widget.type.toDOM.parentNode))this.index++;else{let r=new HM(this.top,e,a,n);this.top.children.splice(this.index++,0,r),this.changed=!0}}addTextblockHacks(){let e=this.top.children[this.index-1],a=this.top;for(;e instanceof rs;)a=e,e=a.children[a.children.length-1];(!e||!(e instanceof Fg)||/\n$/.test(e.node.text)||this.view.requiresGeckoHackNode&&/\s$/.test(e.node.text))&&((Wt||Nt)&&e&&e.dom.contentEditable=="false"&&this.addHackNode("IMG",a),this.addHackNode("BR",this.top))}addHackNode(e,a){if(a==this.top&&this.index<a.children.length&&a.children[this.index].matchesHack(e))this.index++;else{let n=document.createElement(e);e=="IMG"&&(n.className="ProseMirror-separator",n.alt=""),e=="BR"&&(n.className="ProseMirror-trailingBreak");let i=new FM(this.top,[],n,null);a!=this.top?a.children.push(i):a.children.splice(this.index++,0,i),this.changed=!0}}isLocked(e){return this.lock&&(e==this.lock||e.nodeType==1&&e.contains(this.lock.parentNode))}}function eoe(t,e){let a=e,n=a.children.length,i=t.childCount,r=new Map,o=[];e:for(;i>0;){let l;for(;;)if(n){let d=a.children[n-1];if(d instanceof rs)a=d,n=d.children.length;else{l=d,n--;break}}else{if(a==e)break e;n=a.parent.children.indexOf(a),a=a.parent}let c=l.node;if(c){if(c!=t.child(i-1))break;--i,r.set(l,i),o.push(l)}}return{index:i,matched:r,matches:o.reverse()}}function toe(t,e){return t.type.side-e.type.side}function aoe(t,e,a,n){let i=e.locals(t),r=0;if(i.length==0){for(let d=0;d<t.childCount;d++){let u=t.child(d);n(u,i,e.forChild(r,u),d),r+=u.nodeSize}return}let o=0,l=[],c=null;for(let d=0;;){let u,p;for(;o<i.length&&i[o].to==r;){let x=i[o++];x.widget&&(u?(p||(p=[u])).push(x):u=x)}if(u)if(p){p.sort(toe);for(let x=0;x<p.length;x++)a(p[x],d,!!c)}else a(u,d,!!c);let m,h;if(c)h=-1,m=c,c=null;else if(d<t.childCount)h=d,m=t.child(d++);else break;for(let x=0;x<l.length;x++)l[x].to<=r&&l.splice(x--,1);for(;o<i.length&&i[o].from<=r&&i[o].to>r;)l.push(i[o++]);let g=r+m.nodeSize;if(m.isText){let x=g;o<i.length&&i[o].from<x&&(x=i[o].from);for(let v=0;v<l.length;v++)l[v].to<x&&(x=l[v].to);x<g&&(c=m.cut(x-r),m=m.cut(0,x-r),g=x,h=-1)}else for(;o<i.length&&i[o].to<g;)o++;let y=m.isInline&&!m.isLeaf?l.filter(x=>!x.inline):l.slice();n(m,y,e.forChild(r,m),h),r=g}}
vendor: 7,315 bytes, line 17636
17636function noe(t){if(t.nodeName=="UL"||t.nodeName=="OL"){let e=t.style.cssText;t.style.cssText=e+"; list-style: square !important",window.getComputedStyle(t).listStyle,t.style.cssText=e}}function ioe(t,e,a,n){for(let i=0,r=0;i<t.childCount&&r<=n;){let o=t.child(i++),l=r;if(r+=o.nodeSize,!o.isText)continue;let c=o.text;for(;i<t.childCount;){let d=t.child(i++);if(r+=d.nodeSize,!d.isText)break;c+=d.text}if(r>=a){if(r>=n&&c.slice(n-e.length-l,n-l)==e)return n-e.length;let d=l<n?c.lastIndexOf(e,n-l-1):-1;if(d>=0&&d+e.length+l>=a)return l+d;if(a==n&&c.length>=n+e.length-l&&c.slice(n-l,n-l+e.length)==e)return n}}return-1}function Rb(t,e,a,n,i){let r=[];for(let o=0,l=0;o<t.length;o++){let c=t[o],d=l,u=l+=c.size;d>=a||u<=e?r.push(c):(d<e&&r.push(c.slice(0,e-d,n)),i&&(r.push(i),i=void 0),u>a&&r.push(c.slice(a-d,c.size,n)))}return r}function rS(t,e=null){let a=t.domSelectionRange(),n=t.state.doc;if(!a.focusNode)return null;let i=t.docView.nearestDesc(a.focusNode),r=i&&i.size==0,o=t.docView.posFromDOM(a.focusNode,a.focusOffset,1);if(o<0)return null;let l=n.resolve(o),c,d;if(Hg(a)){for(c=o;i&&!i.node;)i=i.parent;let p=i.node;if(i&&p.isAtom&&se.isSelectable(p)&&i.parent&&!(p.isInline&&Ire(a.focusNode,a.focusOffset,i.dom))){let m=i.posBefore;d=new se(o==m?l:n.resolve(m))}}else{if(a instanceof t.dom.ownerDocument.defaultView.Selection&&a.rangeCount>1){let p=o,m=o;for(let h=0;h<a.rangeCount;h++){let g=a.getRangeAt(h);p=Math.min(p,t.docView.posFromDOM(g.startContainer,g.startOffset,1)),m=Math.max(m,t.docView.posFromDOM(g.endContainer,g.endOffset,-1))}if(p<0)return null;[c,o]=m==t.state.selection.anchor?[m,p]:[p,m],l=n.resolve(o)}else c=t.docView.posFromDOM(a.anchorNode,a.anchorOffset,1);if(c<0)return null}let u=n.resolve(c);if(!d){let p=e=="pointer"||t.state.selection.head<l.pos&&!r?1:-1;d=oS(t,u,l,p)}return d}function WM(t){return t.editable?t.hasFocus():KM(t)&&document.activeElement&&document.activeElement.contains(t.dom)}function Pi(t,e=!1){let a=t.state.selection;if(GM(t,a),!!WM(t)){if(!e&&t.input.mouseDown&&t.input.mouseDown.allowDefault&&Nt){let n=t.domSelectionRange(),i=t.domObserver.currentSelection;if(n.anchorNode&&i.anchorNode&&is(n.anchorNode,n.anchorOffset,i.anchorNode,i.anchorOffset)){t.input.mouseDown.delayedSelectionSync=!0,t.domObserver.setCurSelection();return}}if(t.domObserver.disconnectSelection(),t.cursorWrapper)ooe(t);else{let{anchor:n,head:i}=a,r,o;Xj&&!(a instanceof ce)&&(a.$from.parent.inlineContent||(r=Yj(t,a.from)),!a.empty&&!a.$from.parent.inlineContent&&(o=Yj(t,a.to))),t.docView.setSelection(n,i,t,e),Xj&&(r&&Zj(r),o&&Zj(o)),a.visible?t.dom.classList.remove("ProseMirror-hideselection"):(t.dom.classList.add("ProseMirror-hideselection"),"onselectionchange"in document&&roe(t))}t.domObserver.setCurSelection(),t.domObserver.connectSelection()}}const Xj=Wt||Nt&&RM<63;function Yj(t,e){let{node:a,offset:n}=t.docView.domFromPos(e,0),i=n<a.childNodes.length?a.childNodes[n]:null,r=n?a.childNodes[n-1]:null;if(Wt&&i&&i.contentEditable=="false")return Y0(i);if((!i||i.contentEditable=="false")&&(!r||r.contentEditable=="false")){if(i)return Y0(i);if(r)return Y0(r)}}function Y0(t){return t.contentEditable="true",Wt&&t.draggable&&(t.draggable=!1,t.wasDraggable=!0),t}function Zj(t){t.contentEditable="false",t.wasDraggable&&(t.draggable=!0,t.wasDraggable=null)}function roe(t){let e=t.dom.ownerDocument;e.removeEventListener("selectionchange",t.input.hideSelectionGuard);let a=t.domSelectionRange(),n=a.anchorNode,i=a.anchorOffset;e.addEventListener("selectionchange",t.input.hideSelectionGuard=()=>{(a.anchorNode!=n||a.anchorOffset!=i)&&(e.removeEventListener("selectionchange",t.input.hideSelectionGuard),setTimeout(()=>{(!WM(t)||t.state.selection.visible)&&t.dom.classList.remove("ProseMirror-hideselection")},20))})}function ooe(t){let e=t.domSelection();if(!e)return;let a=t.cursorWrapper.dom,n=a.nodeName=="IMG";n?e.collapse(a.parentNode,zt(a)+1):e.collapse(a,0),!n&&!t.state.selection.visible&&Ra&&Lr<=11&&(a.disabled=!0,a.disabled=!1)}function GM(t,e){if(e instanceof se){let a=t.docView.descAt(e.from);a!=t.lastSelectedViewDesc&&(eT(t),a&&a.selectNode(),t.lastSelectedViewDesc=a)}else eT(t)}function eT(t){t.lastSelectedViewDesc&&(t.lastSelectedViewDesc.parent&&t.lastSelectedViewDesc.deselectNode(),t.lastSelectedViewDesc=void 0)}function oS(t,e,a,n){return t.someProp("createSelectionBetween",i=>i(t,e,a))||ce.between(e,a,n)}function tT(t){return t.editable&&!t.hasFocus()?!1:KM(t)}function KM(t){let e=t.domSelectionRange();if(!e.anchorNode)return!1;try{return t.dom.contains(e.anchorNode.nodeType==3?e.anchorNode.parentNode:e.anchorNode)&&(t.editable||t.dom.contains(e.focusNode.nodeType==3?e.focusNode.parentNode:e.focusNode))}catch{return!1}}function soe(t){let e=t.docView.domFromPos(t.state.selection.anchor,0),a=t.domSelectionRange();return is(e.node,e.offset,a.anchorNode,a.anchorOffset)}function Lb(t,e){let{$anchor:a,$head:n}=t.selection,i=e>0?a.max(n):a.min(n),r=i.parent.inlineContent?i.depth?t.doc.resolve(e>0?i.after():i.before()):null:i;return r&&xe.findFrom(r,e)}function nr(t,e){return t.dispatch(t.state.tr.setSelection(e).scrollIntoView()),!0}function aT(t,e,a){let n=t.state.selection;if(n instanceof ce)if(a.indexOf("s")>-1){let{$head:i}=n,r=i.textOffset?null:e<0?i.nodeBefore:i.nodeAfter;if(!r||r.isText||!r.isLeaf)return!1;let o=t.state.doc.resolve(i.pos+r.nodeSize*(e<0?-1:1));return nr(t,new ce(n.$anchor,o))}else if(n.empty){if(t.endOfTextblock(e>0?"forward":"backward")){let i=Lb(t.state,e);return i&&i instanceof se?nr(t,i):!1}else if(!(an&&a.indexOf("m")>-1)){let i=n.$head,r=i.textOffset?null:e<0?i.nodeBefore:i.nodeAfter,o;if(!r||r.isText)return!1;let l=e<0?i.pos-r.nodeSize:i.pos;return r.isAtom||(o=t.docView.descAt(l))&&!o.contentDOM?se.isSelectable(r)?nr(t,new se(e<0?t.state.doc.resolve(i.pos-r.nodeSize):i)):Ku?nr(t,new ce(t.state.doc.resolve(e<0?l:l+r.nodeSize))):!1:!1}}else return!1;else{if(n instanceof se&&n.node.isInline)return nr(t,new ce(e>0?n.$to:n.$from));{let i=Lb(t.state,e);return i?nr(t,i):!1}}}function ef(t){return t.nodeType==3?t.nodeValue.length:t.childNodes.length}function kd(t,e){let a=t.pmViewDesc;return a&&a.size==0&&(e<0||t.nextSibling||t.nodeName!="BR")}function Es(t,e){return e<0?loe(t):coe(t)}function loe(t){let e=t.domSelectionRange(),a=e.focusNode,n=e.focusOffset;if(!a)return;let i,r,o=!1;for(dn&&a.nodeType==1&&n<ef(a)&&kd(a.childNodes[n],-1)&&(o=!0);;)if(n>0){if(a.nodeType!=1)break;{let l=a.childNodes[n-1];if(kd(l,-1))i=a,r=--n;else if(l.nodeType==3)a=l,n=a.nodeValue.length;else break}}else{if(JM(a))break;{let l=a.previousSibling;for(;l&&kd(l,-1);)i=a.parentNode,r=zt(l),l=l.previousSibling;if(l)a=l,n=ef(a);else{if(a=a.parentNode,a==t.dom)break;n=0}}}o?Ob(t,a,n):i&&Ob(t,i,r)}function coe(t){let e=t.domSelectionRange(),a=e.focusNode,n=e.focusOffset;if(!a)return;let i=ef(a),r,o;for(;;)if(n<i){if(a.nodeType!=1)break;let l=a.childNodes[n];if(kd(l,1))r=a,o=++n;else break}else{if(JM(a))break;{let l=a.nextSibling;for(;l&&kd(l,1);)r=l.parentNode,o=zt(l)+1,l=l.nextSibling;if(l)a=l,n=0,i=ef(a);else{if(a=a.parentNode,a==t.dom)break;n=i=0}}}r&&Ob(t,r,o)}function JM(t){let e=t.pmViewDesc;return e&&e.node&&e.node.isBlock}function doe(t,e){for(;t&&e==t.childNodes.length&&!Gu(t);)e=zt(t)+1,t=t.parentNode;for(;t&&e<t.childNodes.length;){let a=t.childNodes[e];if(a.nodeType==3)return a;
vendor: 4,229 bytes, lines 17636-17639
17636if(a.nodeType==1&&a.contentEditable=="false")break;t=a,e=0}}function uoe(t,e){for(;t&&!e&&!Gu(t);)e=zt(t),t=t.parentNode;for(;t&&e;){let a=t.childNodes[e-1];if(a.nodeType==3)return a;if(a.nodeType==1&&a.contentEditable=="false")break;t=a,e=t.childNodes.length}}function Ob(t,e,a){if(e.nodeType!=3){let r,o;(o=doe(e,a))?(e=o,a=0):(r=uoe(e,a))&&(e=r,a=r.nodeValue.length)}let n=t.domSelection();if(!n)return;if(Hg(n)){let r=document.createRange();r.setEnd(e,a),r.setStart(e,a),n.removeAllRanges(),n.addRange(r)}else n.extend&&n.extend(e,a);t.domObserver.setCurSelection();let{state:i}=t;setTimeout(()=>{t.state==i&&Pi(t)},50)}function nT(t,e){let a=t.state.doc.resolve(e);if(!(Nt||LM)&&a.parent.inlineContent){let i=t.coordsAtPos(e);if(e>a.start()){let r=t.coordsAtPos(e-1),o=(r.top+r.bottom)/2;if(o>i.top&&o<i.bottom&&Math.abs(r.left-i.left)>1)return r.left<i.left?"ltr":"rtl"}if(e<a.end()){let r=t.coordsAtPos(e+1),o=(r.top+r.bottom)/2;if(o>i.top&&o<i.bottom&&Math.abs(r.left-i.left)>1)return r.left>i.left?"ltr":"rtl"}}return getComputedStyle(t.dom).direction=="rtl"?"rtl":"ltr"}function iT(t,e,a){let n=t.state.selection;if(n instanceof ce&&!n.empty||a.indexOf("s")>-1||an&&a.indexOf("m")>-1)return!1;let{$from:i,$to:r}=n;if(!i.parent.inlineContent||t.endOfTextblock(e<0?"up":"down")){let o=Lb(t.state,e);if(o&&o instanceof se)return nr(t,o)}if(!i.parent.inlineContent){let o=e<0?i:r,l=n instanceof Ua?xe.near(o,e):xe.findFrom(o,e);return l?nr(t,l):!1}return!1}function rT(t,e){if(!(t.state.selection instanceof ce))return!0;let{$head:a,$anchor:n,empty:i}=t.state.selection;if(!a.sameParent(n))return!0;if(!i)return!1;if(t.endOfTextblock(e>0?"forward":"backward"))return!0;let r=!a.textOffset&&(e<0?a.nodeBefore:a.nodeAfter);if(r&&!r.isText){let o=t.state.tr;return e<0?o.delete(a.pos-r.nodeSize,a.pos):o.delete(a.pos,a.pos+r.nodeSize),t.dispatch(o),!0}return!1}function oT(t,e,a){t.domObserver.stop(),e.contentEditable=a,t.domObserver.start()}function poe(t){if(!Wt||t.state.selection.$head.parentOffset>0)return!1;let{focusNode:e,focusOffset:a}=t.domSelectionRange();if(e&&e.nodeType==1&&a==0&&e.firstChild&&e.firstChild.contentEditable=="false"){let n=e.firstChild;oT(t,n,"true"),setTimeout(()=>oT(t,n,"false"),20)}return!1}function moe(t){let e="";return t.ctrlKey&&(e+="c"),t.metaKey&&(e+="m"),t.altKey&&(e+="a"),t.shiftKey&&(e+="s"),e}function hoe(t,e){let a=e.keyCode,n=moe(e);if(a==8||an&&a==72&&n=="c")return rT(t,-1)||Es(t,-1);if(a==46&&!e.shiftKey||an&&a==68&&n=="c")return rT(t,1)||Es(t,1);if(a==13||a==27)return!0;if(a==37||an&&a==66&&n=="c"){let i=a==37?nT(t,t.state.selection.from)=="ltr"?-1:1:-1;return aT(t,i,n)||Es(t,i)}else if(a==39||an&&a==70&&n=="c"){let i=a==39?nT(t,t.state.selection.from)=="ltr"?1:-1:1;return aT(t,i,n)||Es(t,i)}else{if(a==38||an&&a==80&&n=="c")return iT(t,-1,n)||Es(t,-1);if(a==40||an&&a==78&&n=="c")return poe(t)||iT(t,1,n)||Es(t,1);if(n==(an?"m":"c")&&(a==66||a==73||a==89||a==90))return!0}return!1}function sS(t,e){t.someProp("transformCopied",h=>{e=h(e,t)});let a=[],{content:n,openStart:i,openEnd:r}=e;for(;i>1&&r>1&&n.childCount==1&&n.firstChild.childCount==1;){i--,r--;let h=n.firstChild;a.push(h.type.name,h.attrs!=h.type.defaultAttrs?h.attrs:null),n=h.content}let o=t.someProp("clipboardSerializer")||fs.fromSchema(t.state.schema),l=t5(),c=l.createElement("div");c.appendChild(o.serializeFragment(n,{document:l}));let d=c.firstChild,u,p=0;for(;d&&d.nodeType==1&&(u=e5[d.nodeName.toLowerCase()]);){for(let h=u.length-1;h>=0;h--){let g=l.createElement(u[h]);for(;c.firstChild;)g.appendChild(c.firstChild);c.appendChild(g),p++}d=c.firstChild}d&&d.nodeType==1&&d.setAttribute("data-pm-slice",`${i} ${r}${p?` -${p}`:""} ${JSON.stringify(a)}`);let m=t.someProp("clipboardTextSerializer",h=>h(e,t))||e.content.textBetween(0,e.content.size,`
17637
17638`);return{dom:c,text:m,slice:e}}function QM(t,e,a,n,i){let r=i.parent.type.spec.code,o,l;if(!a&&!e)return null;let c=!!e&&(n||r||!a);if(c){if(t.someProp("transformPastedText",m=>{e=m(e,r||n,t)}),r)return l=new K(V.from(t.state.schema.text(e.replace(/\r\n?/g,`
17639`))),0,0),t.someProp("transformPasted",m=>{l=m(l,t,!0)}),l;let p=t.someProp("clipboardTextParser",m=>m(e,i,n,t));if(p)l=p;else{let m=i.marks(),{schema:h}=t.state,g=fs.fromSchema(h);
vendor: 8,907 bytes, line 17639
17639o=document.createElement("div"),e.split(/(?:\r\n?|\n)+/).forEach(y=>{let x=o.appendChild(document.createElement("p"));y&&x.appendChild(g.serializeNode(h.text(y,m)))})}}else t.someProp("transformPastedHTML",p=>{a=p(a,t)}),o=xoe(a),Ku&&voe(o);let d=o&&o.querySelector("[data-pm-slice]"),u=d&&/^(\d+) (\d+)(?: -(\d+))? (.*)/.exec(d.getAttribute("data-pm-slice")||"");if(u&&u[3])for(let p=+u[3];p>0;p--){let m=o.firstChild;for(;m&&m.nodeType!=1;)m=m.nextSibling;if(!m)break;o=m}if(l||(l=(t.someProp("clipboardParser")||t.someProp("domParser")||Rr.fromSchema(t.state.schema)).parseSlice(o,{preserveWhitespace:!!(c||u),context:i,ruleFromNode(m){return m.nodeName=="BR"&&!m.nextSibling&&m.parentNode&&!foe.test(m.parentNode.nodeName)?{ignore:!0}:null}})),u)l=boe(sT(l,+u[1],+u[2]),u[4]);else if(l=K.maxOpen(goe(l.content,i),!0),l.openStart||l.openEnd){let p=0,m=0;for(let h=l.content.firstChild;p<l.openStart&&!h.type.spec.isolating;p++,h=h.firstChild);for(let h=l.content.lastChild;m<l.openEnd&&!h.type.spec.isolating;m++,h=h.lastChild);l=sT(l,p,m)}return t.someProp("transformPasted",p=>{l=p(l,t,c)}),l}const foe=/^(a|abbr|acronym|b|cite|code|del|em|i|ins|kbd|label|output|q|ruby|s|samp|span|strong|sub|sup|time|u|tt|var)$/i;function goe(t,e){if(t.childCount<2)return t;for(let a=e.depth;a>=0;a--){let i=e.node(a).contentMatchAt(e.index(a)),r,o=[];if(t.forEach(l=>{if(!o)return;let c=i.findWrapping(l.type),d;if(!c)return o=null;if(d=o.length&&r.length&&YM(c,r,l,o[o.length-1],0))o[o.length-1]=d;else{o.length&&(o[o.length-1]=ZM(o[o.length-1],r.length));let u=XM(l,c);o.push(u),i=i.matchType(u.type),r=c}}),o)return V.from(o)}return t}function XM(t,e,a=0){for(let n=e.length-1;n>=a;n--)t=e[n].create(null,V.from(t));return t}function YM(t,e,a,n,i){if(i<t.length&&i<e.length&&t[i]==e[i]){let r=YM(t,e,a,n.lastChild,i+1);if(r)return n.copy(n.content.replaceChild(n.childCount-1,r));if(n.contentMatchAt(n.childCount).matchType(i==t.length-1?a.type:t[i+1]))return n.copy(n.content.append(V.from(XM(a,t,i+1))))}}function ZM(t,e){if(e==0)return t;let a=t.content.replaceChild(t.childCount-1,ZM(t.lastChild,e-1)),n=t.contentMatchAt(t.childCount).fillBefore(V.empty,!0);return t.copy(a.append(n))}function Mb(t,e,a,n,i,r){let o=e<0?t.firstChild:t.lastChild,l=o.content;return t.childCount>1&&(r=0),i<n-1&&(l=Mb(l,e,a,n,i+1,r)),i>=a&&(l=e<0?o.contentMatchAt(0).fillBefore(l,r<=i).append(l):l.append(o.contentMatchAt(o.childCount).fillBefore(V.empty,!0))),t.replaceChild(e<0?0:t.childCount-1,o.copy(l))}function sT(t,e,a){return e<t.openStart&&(t=new K(Mb(t.content,-1,e,t.openStart,0,t.openEnd),e,t.openEnd)),a<t.openEnd&&(t=new K(Mb(t.content,1,a,t.openEnd,0,0),t.openStart,a)),t}const e5={thead:["table"],tbody:["table"],tfoot:["table"],caption:["table"],colgroup:["table"],col:["table","colgroup"],tr:["table","tbody"],td:["table","tbody","tr"],th:["table","tbody","tr"]};let lT=null;function t5(){return lT||(lT=document.implementation.createHTMLDocument("title"))}let Z0=null;function yoe(t){let e=window.trustedTypes;return e?(Z0||(Z0=e.defaultPolicy||e.createPolicy("ProseMirrorClipboard",{createHTML:a=>a})),Z0.createHTML(t)):t}function xoe(t){let e=/^(\s*<meta [^>]*>)*/.exec(t);e&&(t=t.slice(e[0].length));let a=t5().createElement("div"),n=/<([a-z][^>\s]+)/i.exec(t),i;if((i=n&&e5[n[1].toLowerCase()])&&(t=i.map(r=>"<"+r+">").join("")+t+i.map(r=>"</"+r+">").reverse().join("")),a.innerHTML=yoe(t),i)for(let r=0;r<i.length;r++)a=a.querySelector(i[r])||a;return a}function voe(t){let e=t.querySelectorAll(Nt?"span:not([class]):not([style])":"span.Apple-converted-space");for(let a=0;a<e.length;a++){let n=e[a];n.childNodes.length==1&&n.textContent==" "&&n.parentNode&&n.parentNode.replaceChild(t.ownerDocument.createTextNode(" "),n)}}function boe(t,e){if(!t.size)return t;let a=t.content.firstChild.type.schema,n;try{n=JSON.parse(e)}catch{return t}let{content:i,openStart:r,openEnd:o}=t;for(let l=n.length-2;l>=0;l-=2){let c=a.nodes[n[l]];if(!c||c.hasRequiredAttrs())break;i=V.from(c.create(n[l+1],i)),r++,o++}return new K(i,r,o)}const ya={},xa={},woe={touchstart:!0,touchmove:!0};class koe{constructor(){this.shiftKey=!1,this.mouseDown=null,this.lastKeyCode=null,this.lastKeyCodeTime=0,this.lastClick={time:0,x:0,y:0,type:"",button:0},this.lastSelectionOrigin=null,this.lastSelectionTime=0,this.lastIOSEnter=0,this.lastIOSEnterFallbackTimeout=-1,this.lastFocus=0,this.lastTouch=0,this.lastChromeDelete=0,this.composing=!1,this.compositionNode=null,this.composingTimeout=-1,this.compositionNodes=[],this.compositionEndedAt=-2e8,this.compositionID=1,this.badSafariComposition=!1,this.compositionPendingChanges=0,this.domChangeCount=0,this.eventHandlers=Object.create(null),this.hideSelectionGuard=null}}function Soe(t){for(let e in ya){let a=ya[e];t.dom.addEventListener(e,t.input.eventHandlers[e]=n=>{Aoe(t,n)&&!lS(t,n)&&(t.editable||!(n.type in xa))&&a(t,n)},woe[e]?{passive:!0}:void 0)}Wt&&t.dom.addEventListener("input",()=>null),Db(t)}function br(t,e){t.input.lastSelectionOrigin=e,t.input.lastSelectionTime=Date.now()}function _oe(t){t.domObserver.stop();for(let e in t.input.eventHandlers)t.dom.removeEventListener(e,t.input.eventHandlers[e]);clearTimeout(t.input.composingTimeout),clearTimeout(t.input.lastIOSEnterFallbackTimeout)}function Db(t){t.someProp("handleDOMEvents",e=>{for(let a in e)t.input.eventHandlers[a]||t.dom.addEventListener(a,t.input.eventHandlers[a]=n=>lS(t,n))})}function lS(t,e){return t.someProp("handleDOMEvents",a=>{let n=a[e.type];return n?n(t,e)||e.defaultPrevented:!1})}function Aoe(t,e){if(!e.bubbles)return!0;if(e.defaultPrevented)return!1;for(let a=e.target;a!=t.dom;a=a.parentNode)if(!a||a.nodeType==11||a.pmViewDesc&&a.pmViewDesc.stopEvent(e))return!1;return!0}function Eoe(t,e){!lS(t,e)&&ya[e.type]&&(t.editable||!(e.type in xa))&&ya[e.type](t,e)}xa.keydown=(t,e)=>{let a=e;if(t.input.shiftKey=a.keyCode==16||a.shiftKey,!n5(t,a)&&(t.input.lastKeyCode=a.keyCode,t.input.lastKeyCodeTime=Date.now(),!(Ai&&Nt&&a.keyCode==13)))if(a.keyCode!=229&&t.domObserver.forceFlush(),Ll&&a.keyCode==13&&!a.ctrlKey&&!a.altKey&&!a.metaKey){let n=Date.now();t.input.lastIOSEnter=n,t.input.lastIOSEnterFallbackTimeout=setTimeout(()=>{t.input.lastIOSEnter==n&&(t.someProp("handleKeyDown",i=>i(t,yo(13,"Enter"))),t.input.lastIOSEnter=0)},200)}else t.someProp("handleKeyDown",n=>n(t,a))||hoe(t,a)?a.preventDefault():br(t,"key")};xa.keyup=(t,e)=>{e.keyCode==16&&(t.input.shiftKey=!1)};xa.keypress=(t,e)=>{let a=e;if(n5(t,a)||!a.charCode||a.ctrlKey&&!a.altKey||an&&a.metaKey)return;if(t.someProp("handleKeyPress",i=>i(t,a))){a.preventDefault();return}let n=t.state.selection;if(!(n instanceof ce)||!n.$from.sameParent(n.$to)){let i=String.fromCharCode(a.charCode),r=()=>t.state.tr.insertText(i).scrollIntoView();!/[\r\n]/.test(i)&&!t.someProp("handleTextInput",o=>o(t,n.$from.pos,n.$to.pos,i,r))&&t.dispatch(r()),a.preventDefault()}};function Bg(t){return{left:t.clientX,top:t.clientY}}function Coe(t,e){let a=e.x-t.clientX,n=e.y-t.clientY;return a*a+n*n<100}function cS(t,e,a,n,i){if(n==-1)return!1;let r=t.state.doc.resolve(n);for(let o=r.depth+1;o>0;o--)if(t.someProp(e,l=>o>r.depth?l(t,a,r.nodeAfter,r.before(o),i,!0):l(t,a,r.node(o),r.before(o),i,!1)))return!0;return!1}function ul(t,e,a){if(t.focused||t.focus(),t.state.selection.eq(e))return;let n=t.state.tr.setSelection(e);n.setMeta("pointer",!0),t.dispatch(n)}function joe(t,e){if(e==-1)return!1;let a=t.state.doc.resolve(e),n=a.nodeAfter;return n&&n.isAtom&&se.isSelectable(n)?(ul(t,new se(a)),!0):!1}function Toe(t,e){if(e==-1)return!1;let a=t.state.selection,n,i;a instanceof se&&(n=a.node);let r=t.state.doc.resolve(e);for(let o=r.depth+1;o>0;o--){let l=o>r.depth?r.nodeAfter:r.node(o);if(se.isSelectable(l)){n&&a.$from.depth>0&&o>=a.$from.depth&&r.before(a.$from.depth+1)==a.$from.pos?i=r.before(a.$from.depth):i=r.before(o);break}}return i!=null?(ul(t,se.create(t.state.doc,i)),!0):!1}function Noe(t,e,a,n,i){return cS(t,"handleClickOn",e,a,n)||t.someProp("handleClick",r=>r(t,e,n))||(i?Toe(t,a):joe(t,a))}function Ioe(t,e,a,n){return cS(t,"handleDoubleClickOn",e,a,n)||t.someProp("handleDoubleClick",i=>i(t,e,n))}function Poe(t,e,a,n){return cS(t,"handleTripleClickOn",e,a,n)||t.someProp("handleTripleClick",i=>i(t,e,n))||Roe(t,a,n)}function Roe(t,e,a){if(a.button!=0)return!1;let n=t.state.doc;if(e==-1)return n.inlineContent?(ul(t,ce.create(n,0,n.content.size)),!0):!1;let i=n.resolve(e);for(let r=i.depth+1;r>0;r--){let o=r>i.depth?i.nodeAfter:i.node(r),l=i.before(r);if(o.inlineContent)ul(t,ce.create(n,l+1,l+1+o.content.size));else if(se.isSelectable(o))ul(t,se.create(n,l));else continue;return!0}}function dS(t){return tf(t)}const a5=an?"metaKey":"ctrlKey";ya.mousedown=(t,e)=>{let a=e;t.input.shiftKey=a.shiftKey;let n=dS(t),i=Date.now(),r="singleClick";i-t.input.lastClick.time<500&&Coe(a,t.input.lastClick)&&!a[a5]&&t.input.lastClick.button==a.button&&(t.input.lastClick.type=="singleClick"?r="doubleClick":t.input.last
vendor: 18,917 bytes, line 17639
17639Click.type=="doubleClick"&&(r="tripleClick")),t.input.lastClick={time:i,x:a.clientX,y:a.clientY,type:r,button:a.button};let o=t.posAtCoords(Bg(a));o&&(r=="singleClick"?(t.input.mouseDown&&t.input.mouseDown.done(),t.input.mouseDown=new Loe(t,o,a,!!n)):(r=="doubleClick"?Ioe:Poe)(t,o.pos,o.inside,a)?a.preventDefault():br(t,"pointer"))};class Loe{constructor(e,a,n,i){this.view=e,this.pos=a,this.event=n,this.flushed=i,this.delayedSelectionSync=!1,this.mightDrag=null,this.startDoc=e.state.doc,this.selectNode=!!n[a5],this.allowDefault=n.shiftKey;let r,o;if(a.inside>-1)r=e.state.doc.nodeAt(a.inside),o=a.inside;else{let u=e.state.doc.resolve(a.pos);r=u.parent,o=u.depth?u.before():0}const l=i?null:n.target,c=l?e.docView.nearestDesc(l,!0):null;this.target=c&&c.nodeDOM.nodeType==1?c.nodeDOM:null;let{selection:d}=e.state;(n.button==0&&r.type.spec.draggable&&r.type.spec.selectable!==!1||d instanceof se&&d.from<=o&&d.to>o)&&(this.mightDrag={node:r,pos:o,addAttr:!!(this.target&&!this.target.draggable),setUneditable:!!(this.target&&dn&&!this.target.hasAttribute("contentEditable"))}),this.target&&this.mightDrag&&(this.mightDrag.addAttr||this.mightDrag.setUneditable)&&(this.view.domObserver.stop(),this.mightDrag.addAttr&&(this.target.draggable=!0),this.mightDrag.setUneditable&&setTimeout(()=>{this.view.input.mouseDown==this&&this.target.setAttribute("contentEditable","false")},20),this.view.domObserver.start()),e.root.addEventListener("mouseup",this.up=this.up.bind(this)),e.root.addEventListener("mousemove",this.move=this.move.bind(this)),br(e,"pointer")}done(){this.view.root.removeEventListener("mouseup",this.up),this.view.root.removeEventListener("mousemove",this.move),this.mightDrag&&this.target&&(this.view.domObserver.stop(),this.mightDrag.addAttr&&this.target.removeAttribute("draggable"),this.mightDrag.setUneditable&&this.target.removeAttribute("contentEditable"),this.view.domObserver.start()),this.delayedSelectionSync&&setTimeout(()=>Pi(this.view)),this.view.input.mouseDown=null}up(e){if(this.done(),!this.view.dom.contains(e.target))return;let a=this.pos;this.view.state.doc!=this.startDoc&&(a=this.view.posAtCoords(Bg(e))),this.updateAllowDefault(e),this.allowDefault||!a?br(this.view,"pointer"):Noe(this.view,a.pos,a.inside,e,this.selectNode)?e.preventDefault():e.button==0&&(this.flushed||Wt&&this.mightDrag&&!this.mightDrag.node.isAtom||Nt&&!this.view.state.selection.visible&&Math.min(Math.abs(a.pos-this.view.state.selection.from),Math.abs(a.pos-this.view.state.selection.to))<=2)?(ul(this.view,xe.near(this.view.state.doc.resolve(a.pos))),e.preventDefault()):br(this.view,"pointer")}move(e){this.updateAllowDefault(e),br(this.view,"pointer"),e.buttons==0&&this.done()}updateAllowDefault(e){!this.allowDefault&&(Math.abs(this.event.x-e.clientX)>4||Math.abs(this.event.y-e.clientY)>4)&&(this.allowDefault=!0)}}ya.touchstart=t=>{t.input.lastTouch=Date.now(),dS(t),br(t,"pointer")};ya.touchmove=t=>{t.input.lastTouch=Date.now(),br(t,"pointer")};ya.contextmenu=t=>dS(t);function n5(t,e){return t.composing?!0:Wt&&Math.abs(e.timeStamp-t.input.compositionEndedAt)<500?(t.input.compositionEndedAt=-2e8,!0):!1}const Ooe=Ai?5e3:-1;xa.compositionstart=xa.compositionupdate=t=>{if(!t.composing){t.domObserver.flush();let{state:e}=t,a=e.selection.$to;if(e.selection instanceof ce&&(e.storedMarks||!a.textOffset&&a.parentOffset&&a.nodeBefore.marks.some(n=>n.type.spec.inclusive===!1)||Nt&&LM&&Moe(t)))t.markCursor=t.state.storedMarks||a.marks(),tf(t,!0),t.markCursor=null;else if(tf(t,!e.selection.empty),dn&&e.selection.empty&&a.parentOffset&&!a.textOffset&&a.nodeBefore.marks.length){let n=t.domSelectionRange();for(let i=n.focusNode,r=n.focusOffset;i&&i.nodeType==1&&r!=0;){let o=r<0?i.lastChild:i.childNodes[r-1];if(!o)break;if(o.nodeType==3){let l=t.domSelection();l&&l.collapse(o,o.nodeValue.length);break}else i=o,r=-1}}t.input.composing=!0}i5(t,Ooe)};function Moe(t){let{focusNode:e,focusOffset:a}=t.domSelectionRange();if(!e||e.nodeType!=1||a>=e.childNodes.length)return!1;let n=e.childNodes[a];return n.nodeType==1&&n.contentEditable=="false"}xa.compositionend=(t,e)=>{t.composing&&(t.input.composing=!1,t.input.compositionEndedAt=e.timeStamp,t.input.compositionPendingChanges=t.domObserver.pendingRecords().length?t.input.compositionID:0,t.input.compositionNode=null,t.input.badSafariComposition?t.domObserver.forceFlush():t.input.compositionPendingChanges&&Promise.resolve().then(()=>t.domObserver.flush()),t.input.compositionID++,i5(t,20))};function i5(t,e){clearTimeout(t.input.composingTimeout),e>-1&&(t.input.composingTimeout=setTimeout(()=>tf(t),e))}function r5(t){for(t.composing&&(t.input.composing=!1,t.input.compositionEndedAt=qoe());t.input.compositionNodes.length>0;)t.input.compositionNodes.pop().markParentsDirty()}function Doe(t){let e=t.domSelectionRange();if(!e.focusNode)return null;let a=Tre(e.focusNode,e.focusOffset),n=Nre(e.focusNode,e.focusOffset);if(a&&n&&a!=n){let i=n.pmViewDesc,r=t.domObserver.lastChangedTextNode;if(a==r||n==r)return r;if(!i||!i.isText(n.nodeValue))return n;if(t.input.compositionNode==n){let o=a.pmViewDesc;if(!(!o||!o.isText(a.nodeValue)))return n}}return a||n}function qoe(){let t=document.createEvent("Event");return t.initEvent("event",!0,!0),t.timeStamp}function tf(t,e=!1){if(!(Ai&&t.domObserver.flushingSoon>=0)){if(t.domObserver.forceFlush(),r5(t),e||t.docView&&t.docView.dirty){let a=rS(t),n=t.state.selection;return a&&!a.eq(n)?t.dispatch(t.state.tr.setSelection(a)):(t.markCursor||e)&&!n.$from.node(n.$from.sharedDepth(n.to)).inlineContent?t.dispatch(t.state.tr.deleteSelection()):t.updateState(t.state),!0}return!1}}function zoe(t,e){if(!t.dom.parentNode)return;let a=t.dom.parentNode.appendChild(document.createElement("div"));a.appendChild(e),a.style.cssText="position: fixed; left: -10000px; top: 10px";let n=getSelection(),i=document.createRange();i.selectNodeContents(e),t.dom.blur(),n.removeAllRanges(),n.addRange(i),setTimeout(()=>{a.parentNode&&a.parentNode.removeChild(a),t.focus()},50)}const hu=Ra&&Lr<15||Ll&&Lre<604;ya.copy=xa.cut=(t,e)=>{let a=e,n=t.state.selection,i=a.type=="cut";if(n.empty)return;let r=hu?null:a.clipboardData,o=n.content(),{dom:l,text:c}=sS(t,o);r?(a.preventDefault(),r.clearData(),r.setData("text/html",l.innerHTML),r.setData("text/plain",c)):zoe(t,l),i&&t.dispatch(t.state.tr.deleteSelection().scrollIntoView().setMeta("uiEvent","cut"))};function Voe(t){return t.openStart==0&&t.openEnd==0&&t.content.childCount==1?t.content.firstChild:null}function Hoe(t,e){if(!t.dom.parentNode)return;let a=t.input.shiftKey||t.state.selection.$from.parent.type.spec.code,n=t.dom.parentNode.appendChild(document.createElement(a?"textarea":"div"));a||(n.contentEditable="true"),n.style.cssText="position: fixed; left: -10000px; top: 10px",n.focus();let i=t.input.shiftKey&&t.input.lastKeyCode!=45;setTimeout(()=>{t.focus(),n.parentNode&&n.parentNode.removeChild(n),a?fu(t,n.value,null,i,e):fu(t,n.textContent,n.innerHTML,i,e)},50)}function fu(t,e,a,n,i){let r=QM(t,e,a,n,t.state.selection.$from);if(t.someProp("handlePaste",c=>c(t,i,r||K.empty)))return!0;if(!r)return!1;let o=Voe(r),l=o?t.state.tr.replaceSelectionWith(o,n):t.state.tr.replaceSelection(r);return t.dispatch(l.scrollIntoView().setMeta("paste",!0).setMeta("uiEvent","paste")),!0}function o5(t){let e=t.getData("text/plain")||t.getData("Text");if(e)return e;let a=t.getData("text/uri-list");return a?a.replace(/\r?\n/g," "):""}xa.paste=(t,e)=>{let a=e;if(t.composing&&!Ai)return;let n=hu?null:a.clipboardData,i=t.input.shiftKey&&t.input.lastKeyCode!=45;n&&fu(t,o5(n),n.getData("text/html"),i,a)?a.preventDefault():Hoe(t,a)};class s5{constructor(e,a,n){this.slice=e,this.move=a,this.node=n}}const Foe=an?"altKey":"ctrlKey";function l5(t,e){let a=t.someProp("dragCopies",n=>!n(e));return a??!e[Foe]}ya.dragstart=(t,e)=>{let a=e,n=t.input.mouseDown;if(n&&n.done(),!a.dataTransfer)return;let i=t.state.selection,r=i.empty?null:t.posAtCoords(Bg(a)),o;if(!(r&&r.pos>=i.from&&r.pos<=(i instanceof se?i.to-1:i.to))){if(n&&n.mightDrag)o=se.create(t.state.doc,n.mightDrag.pos);else if(a.target&&a.target.nodeType==1){let p=t.docView.nearestDesc(a.target,!0);p&&p.node.type.spec.draggable&&p!=t.docView&&(o=se.create(t.state.doc,p.posBefore))}}let l=(o||t.state.selection).content(),{dom:c,text:d,slice:u}=sS(t,l);(!a.dataTransfer.files.length||!Nt||RM>120)&&a.dataTransfer.clearData(),a.dataTransfer.setData(hu?"Text":"text/html",c.innerHTML),a.dataTransfer.effectAllowed="copyMove",hu||a.dataTransfer.setData("text/plain",d),t.dragging=new s5(u,l5(t,a),o)};ya.dragend=t=>{let e=t.dragging;window.setTimeout(()=>{t.dragging==e&&(t.dragging=null)},50)};xa.dragover=xa.dragenter=(t,e)=>e.preventDefault();xa.drop=(t,e)=>{try{Boe(t,e,t.dragging)}finally{t.dragging=null}};function Boe(t,e,a){if(!e.dataTransfer)return;let n=t.posAtCoords(Bg(e));if(!n)return;let i=t.state.doc.resolve(n.pos),r=a&&a.slice;r?t.someProp("transformPasted",h=>{r=h(r,t,!1)}):r=QM(t,o5(e.dataTransfer),hu?null:e.dataTransfer.getData("text/html"),!1,i);let o=!!(a&&l5(t,e));if(t.someProp("handleDrop",h=>h(t,e,r||K.empty,o))){e.preventDefault();return}if(!r)return;e.preventDefault();let l=r?pM(t.state.doc,i.pos,r):i.pos;l==null&&(l=i.pos);let c=t.state.tr;if(o){let{node:h}=a;h?h.replace(c):c.deleteSelection()}let d=c.mapping.map(l),u=r.openStart==0&&r.openEnd==0&&r.content.childCount==1,p=c.doc;if(u?c.replaceRangeWith(d,d,r.content.firstChild):c.replaceRange(d,d,r),c.doc.eq(p))return;let m=c.doc.resolve(d);if(u&&se.isSelectable(r.content.firstChild)&&m.nodeAfter&&m.nodeAfter.sameMarkup(r.content.firstChild))c.setSelection(new se(m));else{let h=c.mapping.map(l);c.mapping.maps[c.mapping.maps.length-1].forEach((g,y,x,v)=>h=v),c.setSelection(oS(t,m,c.doc.resolve(h)))}t.focus(),t.dispatch(c.setMeta("uiEvent","drop"))}ya.focus=t=>{t.input.lastFocus=Date.now(),t.focused||(t.domObserver.stop(),t.dom.classList.add("ProseMirror-focused"),t.domObserver.start(),t.focused=!0,setTimeout(()=>{t.docView&&t.hasFocus()&&!t.domObserver.currentSelection.eq(t.domSelectionRange())&&Pi(t)},20))};ya.blur=(t,e)=>{let a=e;t.focused&&(t.domObserver.stop(),t.dom.classList.remove("ProseMirror-focused"),t.domObserver.start(),a.relatedTarget&&t.dom.contains(a.relatedTarget)&&t.domObserver.currentSelection.clear(),t.focused=!1)};ya.beforeinput=(t,e)=>{if(Nt&&Ai&&e.inputType=="deleteContentBackward"){t.domObserver.flushSoon();let{domChangeCount:n}=t.input;setTimeout(()=>{if(t.input.domChangeCount!=n||(t.dom.blur(),t.focus(),t.someProp("handleKeyDown",r=>r(t,yo(8,"Backspace")))))return;let{$cursor:i}=t.state.selection;i&&i.pos>0&&t.dispatch(t.state.tr.delete(i.pos-1,i.pos).scrollIntoView())},50)}};for(let t in xa)ya[t]=xa[t];function gu(t,e){if(t==e)return!0;for(let a in t)if(t[a]!==e[a])return!1;for(let a in e)if(!(a in t))return!1;return!0}class af{constructor(e,a){this.toDOM=e,this.spec=a||Vo,this.side=this.spec.side||0}map(e,a,n,i){let{pos:r,deleted:o}=e.mapResult(a.from+i,this.side<0?-1:1);return o?null:new ha(r-n,r-n,this)}valid(){return!0}eq(e){return this==e||e instanceof af&&(this.spec.key&&this.spec.key==e.spec.key||this.toDOM==e.toDOM&&gu(this.spec,e.spec))}destroy(e){this.spec.destroy&&this.spec.destroy(e)}}class Mr{constructor(e,a){this.attrs=e,this.spec=a||Vo}map(e,a,n,i){let r=e.map(a.from+i,this.spec.inclusiveStart?-1:1)-n,o=e.map(a.to+i,this.spec.inclusiveEnd?1:-1)-n;return r>=o?null:new ha(r,o,this)}valid(e,a){return a.from<a.to}eq(e){return this==e||e instanceof Mr&&gu(this.attrs,e.attrs)&&gu(this.spec,e.spec)}static is(e){return e.type instanceof Mr}destroy(){}}class uS{constructor(e,a){this.attrs=e,this.spec=a||Vo}map(e,a,n,i){let r=e.mapResult(a.from+i,1);if(r.deleted)return null;let o=e.mapResult(a.to+i,-1);return o.deleted||o.pos<=r.pos?null:new ha(r.pos-n,o.pos-n,this)}valid(e,a){let{index:n,offset:i}=e.content.findIndex(a.from),r;return i==a.from&&!(r=e.child(n)).isText&&i+r.nodeSize==a.to}eq(e){return this==e||e instanceof uS&&gu(this.attrs,e.attrs)&&gu(this.spec,e.spec)}destroy(){}}class ha{constructor(e,a,n){this.from=e,this.to=a,this.type=n}copy(e,a){return new ha(e,a,this.type)}eq(e,a=0){return this.type.eq(e.type)&&this.from+a==e.from&&this.to+a==e.to}map(e,a,n){return this.type.map(e,this,a,n)}static widget(e,a,n){return new ha(e,e,new af(a,n))}static inline(e,a,n,i){return new ha(e,a,new Mr(n,i))}static node(e,a,n,i){return new ha(e,a,new uS(n,i))}get spec(){return this.type.spec}get inline(){return this.type instanceof Mr}get widget(){return this.type instanceof af}}const Is=[],Vo={};class Qe{constructor(e,a){this.local=e.length?e:Is,this.children=a.length?a:Is}static create(e,a){return a.length?nf(a,e,0,Vo):Zt}find(e,a,n){let i=[];return this.findInner(e??0,a??1e9,i,0,n),i}findInner(e,a,n,i,r){for(let o=0;o<this.local.length;o++){let l=this.local[o];l.from<=a&&l.to>=e&&(!r||r(l.spec))&&n.push(l.copy(l.from+i,l.to+i))}for(let o=0;o<this.children.length;o+=3)if(this.children[o]<a&&this.children[o+1]>e){let l=this.children[o]+1;this.children[o+2].findInner(e-l,a-l,n,i+l,r)}}map(e,a,n){return this==Zt||e.maps.length==0?this:this.mapInner(e,a,0,0,n||Vo)}mapInner(e,a,n,i,r){let o;for(let l=0;l<this.local.length;l++){let c=this.local[l].map(e,n,i);c&&c.type.valid(a,c)?(o||(o=[])).push(c):r.onRemove&&r.onRemove(this.local[l].spec)}return this.children.length?Uoe(this.children,o||[],e,a,n,i,r):o?new Qe(o.sort(Ho),Is):Zt}add(e,a){return a.length?this==Zt?Qe.create(e,a):this.addInner(e,a,0):this}addInner(e,a,n){let i,r=0;e.forEach((l,c)=>{let d=c+n,u;if(u=d5(a,l,d)){for(i||(i=this.children.slice());r<i.length&&i[r]<c;)r+=3;i[r]==c?i[r+2]=i[r+2].addInner(l,u,d+1):i.splice(r,0,c,c+l.nodeSize,nf(u,l,d+1,Vo)),r+=3}});let o=c5(r?u5(a):a,-n);for(let l=0;l<o.length;l++)o[l].type.valid(e,o[l])||o.splice(l--,1);return new Qe(o.length?this.local.concat(o).sort(Ho):this.local,i||this.children)}remove(e){return e.length==0||this==Zt?this:this.removeInner(e,0)}removeInner(e,a){let n=this.children,i=this.local;for(let r=0;r<n.length;r+=3){let o,l=n[r]+a,c=n[r+1]+a;for(let u=0,p;u<e.length;u++)(p=e[u])&&p.from>l&&p.to<c&&(e[u]=null,(o||(o=[])).push(p));if(!o)continue;n==this.children&&(n=this.children.slice());let d=n[r+2].removeInner(o,l+1);d!=Zt?n[r+2]=d:(n.splice(r,3),r-=3)}if(i.length){for(let r=0,o;r<e.length;r++)if(o=e[r])for(let l=0;l<i.length;l++)i[l].eq(o,a)&&(i==this.local&&(i=this.local.slice()),i.splice(l--,1))}return n==this.children&&i==this.local?this:i.length||n.length?new Qe(i,n):Zt}forChild(e,a){if(this==Zt)return this;if(a.isLeaf)return Qe.empty;let n,i;for(let l=0;l<this.children.length;l+=3)if(this.children[l]>=e){this.children[l]==e&&(n=this.children[l+2]);break}let r=e+1,o=r+a.content.size;for(let l=0;l<this.local.length;l++){let c=this.local[l];if(c.from<o&&c.to>r&&c.type instanceof Mr){let d=Math.max(r,c.from)-r,u=Math.min(o,c.to)-r;d<u&&(i||(i=[])).push(c.copy(d,u))}}if(i){let l=new Qe(i.sort(Ho),Is);return n?new pr([l,n]):l}return n||Zt}eq(e){if(this==e)return!0;if(!(e instanceof Qe)||this.local.length!=e.local.length||this.children.length!=e.children.length)return!1;for(let a=0;a<this.local.length;a++)if(!this.local[a].eq(e.local[a]))return!1;for(let a=0;a<this.children.length;a+=3)if(this.children[a]!=e.children[a]||this.children[a+1]!=e.children[a+1]||!this.children[a+2].eq(e.children[a+2]))return!1;return!0}locals(e){return pS(this.localsInner(e))}localsInner(e){if(this==Zt)return Is;if(e.inlineContent||!this.local.some(Mr.is))return this.local;let a=[];for(let n=0;n<this.local.length;n++)this.local[n].type instanceof Mr||a.push(this.local[n]);return a}forEachSet(e){e(this)}}Qe.empty=new Qe([],[]);Qe.removeOverlap=pS;const Zt=Qe.empty;class pr{constructor(e){this.members=e}map(e,a){const n=this.members.map(i=>i.map(e,a,Vo));return pr.from(n)}forChild(e,a){if(a.isLeaf)return Qe.empty;let n=[];for(let i=0;i<this.members.length;i++){let r=this.members[i].forChild(e,a);r!=Zt&&(r instanceof pr?n=n.concat(r.members):n.push(r))}return pr.from(n)}eq(e){if(!(e instanceof pr)||e.members.length!=this.members.length)return!1;for(let a=0;a<this.members.length;a++)if(!this.members[a].eq(e.members[a]))return!1;return!0}locals(e){let a,n=!0;for(let i=0;i<this.members.length;i++){let r=this.members[i].localsInner(e);if(r.length)if(!a)a=r;else{n&&(a=a.slice(),n=!1);for(let o=0;o<r.length;o++)a.push(r[o])}}return a?pS(n?a:a.sort(Ho)):Is}static from(e){switch(e.length){case 0:return Zt;case 1:return e[0];default:return new pr(e.every(a=>a instanceof Qe)?e:e.reduce((a,n)=>a.concat(n instanceof Qe?n:n.members),[]))}}forEachSet(e){for(let a=0;a<this.members.length;a++)this.members[a].forEachSet(e)}}function Uoe(t,e,a,n,i,r,o){let l=t.slice();for(let d=0,u=r;d<a.maps.length;d++){let p=0;a.maps[d].forEach((m,h,g,y)=>{let x=y-g-(h-m);for(let v=0;v<l.length;v+=3){let w=l[v+1];if(w<0||m>w+u-p)continue;let S=l[v]+u-p;h>=S?l[v+1]=m<=S?-2:-1:m>=u&&x&&(l[v]+=x,l[v+1]+=x)}p+=x}),u=a.maps[d].map(u,-1)}let c=!1;for(let d=0;d<l.length;d+=3)if(l[d+1]<0){if(l[d+1]==-2){c=!0,l[d+1]=-1;continue}let u=a.map(t[d]+r),p=u-i;if(p<0||p>=n.content.size){c=!0;continue}let m=a.map(t[d+1]+r,-1),h=m-i,{index:g,offset:y}=n.content.findIndex(p),x=n.maybeChild(g);if(x&&y==p&&y+x.nodeSize==h){let v=l[d+2].mapInner(a,x,u+1,t[d]+r+1,o);v!=Zt?(l[d]=p,l[d+1]=h,l[d+2]=v):(l[d+1]=-2,c=!0)}else c=!0}if(c){let d=$oe(l,t,e,a,i,r,o),u=nf(d,n,0,o);e=u.local;for(let p=0;p<l.length;p+=3)l[p+1]<0&&(l.splice(p,3),p-=3);for(let p=0,m=0;p<u.children.length;p+=3){let h=u.children[p];for(;m<l.length&&l[m]<h;)m+=3;l.splice(m,0,u.children[p],u.children[p+1],u.children[p+2])}}return new Qe(e.sort(Ho),l)}function c5(t,e){if(!e||!t.length)return t;let a=[];for(let n=0;n<t.length;n++){let i=t[n];a.push(new ha(i.from+e,i.to+e,i.type))}return a}function $oe(t,e,a,n,i,r,o){function l(c,d){for(let u=0;u<c.local.length;u++){let p=c.local[u].map(n,i,d);p?a.push(p):o.onRemove&&o.onRemove(c.local[u].spec)}for(let u=0;u<c.children.length;u+=3)l(c.children[u+2],c.children[u]+d+1)}for(let c=0;c<t.length;c+=3)t[c+1]==-1&&l(t[c+2],e[c]+r+1);return a}function d5(t,e,a){if(e.isLeaf)return null;let n=a+e.nodeSize,i=null;for(let r=0,o;r<t.length;r++)(o=t[r])&&o.from>a&&o.to<n&&((i||(i=[])).push(o),t[r]=null);return i}function u5(t){let e=[];for(let a=0;a<t.length;a++)t[a]!=null&&e.push(t[a]);return e}function nf(t,e,a,n){let i=[],r=!1;e.forEach((l,c)=>{let d=d5(t,l,c+a);if(d){r=!0;let u=nf(d,l,a+c+1,n);u!=Zt&&i.push(c,c+l.nodeSize,u)}});let o=c5(r?u5(t):t,-a).sort(Ho);for(let l=0;l<o.length;l++)o[l].type.valid(e,o[l])||(n.onRemove&&n.onRemove(o[l].spec),o.splice(l--,1));return o.length||i.length?new Qe(o,i):Zt}function Ho(t,e){return t.from-e.from||t.to-e.to}function pS(t){let e=t;for(let a=0;a<e.length-1;a++){let n=e[a];if(n.from!=n.to)for(let i=a+1;i<e.length;i++){let r=e[i];if(r.from==n.from){r.to!=n.to&&(e==t&&(e=t.slice()),e[i]=r.copy(r.from,n.to),cT(e,i+1,r.copy(n.to,r.to)));continue}else{r.from<n.to&&(e==t&&(e=t.slice()),e[a]=n.copy(n.from,r.from),cT(e,i,n.copy(r.from,n.to))
vendor: 8,710 bytes, line 17639
17639);break}}}return e}function cT(t,e,a){for(;e<t.length&&Ho(a,t[e])>0;)e++;t.splice(e,0,a)}function ex(t){let e=[];return t.someProp("decorations",a=>{let n=a(t.state);n&&n!=Zt&&e.push(n)}),t.cursorWrapper&&e.push(Qe.create(t.state.doc,[t.cursorWrapper.deco])),pr.from(e)}const Woe={childList:!0,characterData:!0,characterDataOldValue:!0,attributes:!0,attributeOldValue:!0,subtree:!0},Goe=Ra&&Lr<=11;class Koe{constructor(){this.anchorNode=null,this.anchorOffset=0,this.focusNode=null,this.focusOffset=0}set(e){this.anchorNode=e.anchorNode,this.anchorOffset=e.anchorOffset,this.focusNode=e.focusNode,this.focusOffset=e.focusOffset}clear(){this.anchorNode=this.focusNode=null}eq(e){return e.anchorNode==this.anchorNode&&e.anchorOffset==this.anchorOffset&&e.focusNode==this.focusNode&&e.focusOffset==this.focusOffset}}class Joe{constructor(e,a){this.view=e,this.handleDOMChange=a,this.queue=[],this.flushingSoon=-1,this.observer=null,this.currentSelection=new Koe,this.onCharData=null,this.suppressingSelectionUpdates=!1,this.lastChangedTextNode=null,this.observer=window.MutationObserver&&new window.MutationObserver(n=>{for(let i=0;i<n.length;i++)this.queue.push(n[i]);Ra&&Lr<=11&&n.some(i=>i.type=="childList"&&i.removedNodes.length||i.type=="characterData"&&i.oldValue.length>i.target.nodeValue.length)?this.flushSoon():Wt&&e.composing&&n.some(i=>i.type=="childList"&&i.target.nodeName=="TR")?(e.input.badSafariComposition=!0,this.flushSoon()):this.flush()}),Goe&&(this.onCharData=n=>{this.queue.push({target:n.target,type:"characterData",oldValue:n.prevValue}),this.flushSoon()}),this.onSelectionChange=this.onSelectionChange.bind(this)}flushSoon(){this.flushingSoon<0&&(this.flushingSoon=window.setTimeout(()=>{this.flushingSoon=-1,this.flush()},20))}forceFlush(){this.flushingSoon>-1&&(window.clearTimeout(this.flushingSoon),this.flushingSoon=-1,this.flush())}start(){this.observer&&(this.observer.takeRecords(),this.observer.observe(this.view.dom,Woe)),this.onCharData&&this.view.dom.addEventListener("DOMCharacterDataModified",this.onCharData),this.connectSelection()}stop(){if(this.observer){let e=this.observer.takeRecords();if(e.length){for(let a=0;a<e.length;a++)this.queue.push(e[a]);window.setTimeout(()=>this.flush(),20)}this.observer.disconnect()}this.onCharData&&this.view.dom.removeEventListener("DOMCharacterDataModified",this.onCharData),this.disconnectSelection()}connectSelection(){this.view.dom.ownerDocument.addEventListener("selectionchange",this.onSelectionChange)}disconnectSelection(){this.view.dom.ownerDocument.removeEventListener("selectionchange",this.onSelectionChange)}suppressSelectionUpdates(){this.suppressingSelectionUpdates=!0,setTimeout(()=>this.suppressingSelectionUpdates=!1,50)}onSelectionChange(){if(tT(this.view)){if(this.suppressingSelectionUpdates)return Pi(this.view);if(Ra&&Lr<=11&&!this.view.state.selection.empty){let e=this.view.domSelectionRange();if(e.focusNode&&is(e.focusNode,e.focusOffset,e.anchorNode,e.anchorOffset))return this.flushSoon()}this.flush()}}setCurSelection(){this.currentSelection.set(this.view.domSelectionRange())}ignoreSelectionChange(e){if(!e.focusNode)return!0;let a=new Set,n;for(let r=e.focusNode;r;r=Rl(r))a.add(r);for(let r=e.anchorNode;r;r=Rl(r))if(a.has(r)){n=r;break}let i=n&&this.view.docView.nearestDesc(n);if(i&&i.ignoreMutation({type:"selection",target:n.nodeType==3?n.parentNode:n}))return this.setCurSelection(),!0}pendingRecords(){if(this.observer)for(let e of this.observer.takeRecords())this.queue.push(e);return this.queue}flush(){let{view:e}=this;if(!e.docView||this.flushingSoon>-1)return;let a=this.pendingRecords();a.length&&(this.queue=[]);let n=e.domSelectionRange(),i=!this.suppressingSelectionUpdates&&!this.currentSelection.eq(n)&&tT(e)&&!this.ignoreSelectionChange(n),r=-1,o=-1,l=!1,c=[];if(e.editable)for(let u=0;u<a.length;u++){let p=this.registerMutation(a[u],c);p&&(r=r<0?p.from:Math.min(p.from,r),o=o<0?p.to:Math.max(p.to,o),p.typeOver&&(l=!0))}if(dn&&c.length){let u=c.filter(p=>p.nodeName=="BR");if(u.length==2){let[p,m]=u;p.parentNode&&p.parentNode.parentNode==m.parentNode?m.remove():p.remove()}else{let{focusNode:p}=this.currentSelection;for(let m of u){let h=m.parentNode;h&&h.nodeName=="LI"&&(!p||Yoe(e,p)!=h)&&m.remove()}}}else if((Nt||Wt)&&c.some(u=>u.nodeName=="BR")&&(e.input.lastKeyCode==8||e.input.lastKeyCode==46)){for(let u of c)if(u.nodeName=="BR"&&u.parentNode){let p=u.nextSibling;p&&p.nodeType==1&&p.contentEditable=="false"&&u.parentNode.removeChild(u)}}let d=null;r<0&&i&&e.input.lastFocus>Date.now()-200&&Math.max(e.input.lastTouch,e.input.lastClick.time)<Date.now()-300&&Hg(n)&&(d=rS(e))&&d.eq(xe.near(e.state.doc.resolve(0),1))?(e.input.lastFocus=0,Pi(e),this.currentSelection.set(n),e.scrollToSelection()):(r>-1||i)&&(r>-1&&(e.docView.markDirty(r,o),Qoe(e)),e.input.badSafariComposition&&(e.input.badSafariComposition=!1,Zoe(e,c)),this.handleDOMChange(r,o,l,c),e.docView&&e.docView.dirty?e.updateState(e.state):this.currentSelection.eq(n)||Pi(e),this.currentSelection.set(n))}registerMutation(e,a){if(a.indexOf(e.target)>-1)return null;let n=this.view.docView.nearestDesc(e.target);if(e.type=="attributes"&&(n==this.view.docView||e.attributeName=="contenteditable"||e.attributeName=="style"&&!e.oldValue&&!e.target.getAttribute("style"))||!n||n.ignoreMutation(e))return null;if(e.type=="childList"){for(let u=0;u<e.addedNodes.length;u++){let p=e.addedNodes[u];a.push(p),p.nodeType==3&&(this.lastChangedTextNode=p)}if(n.contentDOM&&n.contentDOM!=n.dom&&!n.contentDOM.contains(e.target))return{from:n.posBefore,to:n.posAfter};let i=e.previousSibling,r=e.nextSibling;if(Ra&&Lr<=11&&e.addedNodes.length)for(let u=0;u<e.addedNodes.length;u++){let{previousSibling:p,nextSibling:m}=e.addedNodes[u];(!p||Array.prototype.indexOf.call(e.addedNodes,p)<0)&&(i=p),(!m||Array.prototype.indexOf.call(e.addedNodes,m)<0)&&(r=m)}let o=i&&i.parentNode==e.target?zt(i)+1:0,l=n.localPosFromDOM(e.target,o,-1),c=r&&r.parentNode==e.target?zt(r):e.target.childNodes.length,d=n.localPosFromDOM(e.target,c,1);return{from:l,to:d}}else return e.type=="attributes"?{from:n.posAtStart-n.border,to:n.posAtEnd+n.border}:(this.lastChangedTextNode=e.target,{from:n.posAtStart,to:n.posAtEnd,typeOver:e.target.nodeValue==e.oldValue})}}let dT=new WeakMap,uT=!1;function Qoe(t){if(!dT.has(t)&&(dT.set(t,null),["normal","nowrap","pre-line"].indexOf(getComputedStyle(t.dom).whiteSpace)!==-1)){if(t.requiresGeckoHackNode=dn,uT)return;console.warn("ProseMirror expects the CSS white-space property to be set, preferably to 'pre-wrap'. It is recommended to load style/prosemirror.css from the prosemirror-view package."),uT=!0}}function pT(t,e){let a=e.startContainer,n=e.startOffset,i=e.endContainer,r=e.endOffset,o=t.domAtPos(t.state.selection.anchor);return is(o.node,o.offset,i,r)&&([a,n,i,r]=[i,r,a,n]),{anchorNode:a,anchorOffset:n,focusNode:i,focusOffset:r}}function Xoe(t,e){if(e.getComposedRanges){let i=e.getComposedRanges(t.root)[0];if(i)return pT(t,i)}let a;function n(i){i.preventDefault(),i.stopImmediatePropagation(),a=i.getTargetRanges()[0]}return t.dom.addEventListener("beforeinput",n,!0),document.execCommand("indent"),t.dom.removeEventListener("beforeinput",n,!0),a?pT(t,a):null}function Yoe(t,e){for(let a=e.parentNode;a&&a!=t.dom;a=a.parentNode){let n=t.docView.nearestDesc(a,!0);if(n&&n.node.isBlock)return a}return null}function Zoe(t,e){var a;let{focusNode:n,focusOffset:i}=t.domSelectionRange();for(let r of e)if(((a=r.parentNode)===null||a===void 0?void 0:a.nodeName)=="TR"){let o=r.nextSibling;for(;o&&o.nodeName!="TD"&&o.nodeName!="TH";)o=o.nextSibling;if(o){let l=o;for(;;){let c=l.firstChild;if(!c||c.nodeType!=1||c.contentEditable=="false"||/^(BR|IMG)$/.test(c.nodeName))break;l=c}l.insertBefore(r,l.firstChild),n==r&&t.domSelection().collapse(r,i)}else r.parentNode.removeChild(r)}}function ese(t,e,a){let{node:n,fromOffset:i,toOffset:r,from:o,to:l}=t.docView.parseRange(e,a),c=t.domSelectionRange(),d,u=c.anchorNode;if(u&&t.dom.contains(u.nodeType==1?u:u.parentNode)&&(d=[{node:u,offset:c.anchorOffset}],Hg(c)||d.push({node:c.focusNode,offset:c.focusOffset})),Nt&&t.input.lastKeyCode===8)for(let x=r;x>i;x--){let v=n.childNodes[x-1],w=v.pmViewDesc;if(v.nodeName=="BR"&&!w){r=x;break}if(!w||w.size)break}let p=t.state.doc,m=t.someProp("domParser")||Rr.fromSchema(t.state.schema),h=p.resolve(o),g=null,y=m.parse(n,{topNode:h.parent,topMatch:h.parent.contentMatchAt(h.index()),topOpen:!0,from:i,to:r,preserveWhitespace:h.parent.type.whitespace=="pre"?"full":!0,findPositions:d,ruleFromNode:tse,context:h});if(d&&d[0].pos!=null){let x=d[0].pos,v=d[1]&&d[1].pos;v==null&&(v=x),g={anchor:x+o,head:v+o}}return{doc:y,sel:g,from:o,to:l}}function tse(t){let e=t.pmViewDesc;if(e)return e.parseRule();
vendor: 3,578 bytes, line 17639
17639if(t.nodeName=="BR"&&t.parentNode){if(Wt&&/^(ul|ol)$/i.test(t.parentNode.nodeName)){let a=document.createElement("div");return a.appendChild(document.createElement("li")),{skip:a}}else if(t.parentNode.lastChild==t||Wt&&/^(tr|table)$/i.test(t.parentNode.nodeName))return{ignore:!0}}else if(t.nodeName=="IMG"&&t.getAttribute("mark-placeholder"))return{ignore:!0};return null}const ase=/^(a|abbr|acronym|b|bd[io]|big|br|button|cite|code|data(list)?|del|dfn|em|i|img|ins|kbd|label|map|mark|meter|output|q|ruby|s|samp|small|span|strong|su[bp]|time|u|tt|var)$/i;function nse(t,e,a,n,i){let r=t.input.compositionPendingChanges||(t.composing?t.input.compositionID:0);if(t.input.compositionPendingChanges=0,e<0){let C=t.input.lastSelectionTime>Date.now()-50?t.input.lastSelectionOrigin:null,E=rS(t,C);if(E&&!t.state.selection.eq(E)){if(Nt&&Ai&&t.input.lastKeyCode===13&&Date.now()-100<t.input.lastKeyCodeTime&&t.someProp("handleKeyDown",N=>N(t,yo(13,"Enter"))))return;let j=t.state.tr.setSelection(E);C=="pointer"?j.setMeta("pointer",!0):C=="key"&&j.scrollIntoView(),r&&j.setMeta("composition",r),t.dispatch(j)}return}let o=t.state.doc.resolve(e),l=o.sharedDepth(a);e=o.before(l+1),a=t.state.doc.resolve(a).after(l+1);let c=t.state.selection,d=ese(t,e,a),u=t.state.doc,p=u.slice(d.from,d.to),m,h;t.input.lastKeyCode===8&&Date.now()-100<t.input.lastKeyCodeTime?(m=t.state.selection.to,h="end"):(m=t.state.selection.from,h="start"),t.input.lastKeyCode=null;let g=ose(p.content,d.doc.content,d.from,m,h);if(g&&t.input.domChangeCount++,(Ll&&t.input.lastIOSEnter>Date.now()-225||Ai)&&i.some(C=>C.nodeType==1&&!ase.test(C.nodeName))&&(!g||g.endA>=g.endB)&&t.someProp("handleKeyDown",C=>C(t,yo(13,"Enter")))){t.input.lastIOSEnter=0;return}if(!g)if(n&&c instanceof ce&&!c.empty&&c.$head.sameParent(c.$anchor)&&!t.composing&&!(d.sel&&d.sel.anchor!=d.sel.head))g={start:c.from,endA:c.to,endB:c.to};else{if(d.sel){let C=mT(t,t.state.doc,d.sel);if(C&&!C.eq(t.state.selection)){let E=t.state.tr.setSelection(C);r&&E.setMeta("composition",r),t.dispatch(E)}}return}t.state.selection.from<t.state.selection.to&&g.start==g.endB&&t.state.selection instanceof ce&&(g.start>t.state.selection.from&&g.start<=t.state.selection.from+2&&t.state.selection.from>=d.from?g.start=t.state.selection.from:g.endA<t.state.selection.to&&g.endA>=t.state.selection.to-2&&t.state.selection.to<=d.to&&(g.endB+=t.state.selection.to-g.endA,g.endA=t.state.selection.to)),Ra&&Lr<=11&&g.endB==g.start+1&&g.endA==g.start&&g.start>d.from&&d.doc.textBetween(g.start-d.from-1,g.start-d.from+1)=="  "&&(g.start--,g.endA--,g.endB--);let y=d.doc.resolveNoCache(g.start-d.from),x=d.doc.resolveNoCache(g.endB-d.from),v=u.resolve(g.start),w=y.sameParent(x)&&y.parent.inlineContent&&v.end()>=g.endA;if((Ll&&t.input.lastIOSEnter>Date.now()-225&&(!w||i.some(C=>C.nodeName=="DIV"||C.nodeName=="P"))||!w&&y.pos<d.doc.content.size&&(!y.sameParent(x)||!y.parent.inlineContent)&&y.pos<x.pos&&!/\S/.test(d.doc.textBetween(y.pos,x.pos,"","")))&&t.someProp("handleKeyDown",C=>C(t,yo(13,"Enter")))){t.input.lastIOSEnter=0;return}if(t.state.selection.anchor>g.start&&rse(u,g.start,g.endA,y,x)&&t.someProp("handleKeyDown",C=>C(t,yo(8,"Backspace")))){Ai&&Nt&&t.domObserver.suppressSelectionUpdates();return}Nt&&g.endB==g.start&&(t.input.lastChromeDelete=Date.now()),Ai&&!w&&y.start()!=x.start()&&x.parentOffset==0&&y.depth==x.depth&&d.sel&&d.sel.anchor==d.sel.head&&d.sel.head==g.endA&&(g.endB-=2,x=d.doc.resolveNoCache(g.endB-d.from),setTimeout(()=>{t.someProp("handleKeyDown",function(C){return C(t,yo(13,"Enter"))})},20));let S=g.start,T=g.endA,P=C=>
vendor: 12,478 bytes, line 17639
17639{let E=C||t.state.tr.replace(S,T,d.doc.slice(g.start-d.from,g.endB-d.from));if(d.sel){let j=mT(t,E.doc,d.sel);j&&!(Nt&&t.composing&&j.empty&&(g.start!=g.endB||t.input.lastChromeDelete<Date.now()-100)&&(j.head==S||j.head==E.mapping.map(T)-1)||Ra&&j.empty&&j.head==S)&&E.setSelection(j)}return r&&E.setMeta("composition",r),E.scrollIntoView()},M;if(w)if(y.pos==x.pos){Ra&&Lr<=11&&y.parentOffset==0&&(t.domObserver.suppressSelectionUpdates(),setTimeout(()=>Pi(t),20));let C=P(t.state.tr.delete(S,T)),E=u.resolve(g.start).marksAcross(u.resolve(g.endA));E&&C.ensureMarks(E),t.dispatch(C)}else if(g.endA==g.endB&&(M=ise(y.parent.content.cut(y.parentOffset,x.parentOffset),v.parent.content.cut(v.parentOffset,g.endA-v.start())))){let C=P(t.state.tr);M.type=="add"?C.addMark(S,T,M.mark):C.removeMark(S,T,M.mark),t.dispatch(C)}else if(y.parent.child(y.index()).isText&&y.index()==x.index()-(x.textOffset?0:1)){let C=y.parent.textBetween(y.parentOffset,x.parentOffset),E=()=>P(t.state.tr.insertText(C,S,T));t.someProp("handleTextInput",j=>j(t,S,T,C,E))||t.dispatch(E())}else t.dispatch(P());else t.dispatch(P())}function mT(t,e,a){return Math.max(a.anchor,a.head)>e.content.size?null:oS(t,e.resolve(a.anchor),e.resolve(a.head))}function ise(t,e){let a=t.firstChild.marks,n=e.firstChild.marks,i=a,r=n,o,l,c;for(let u=0;u<n.length;u++)i=n[u].removeFromSet(i);for(let u=0;u<a.length;u++)r=a[u].removeFromSet(r);if(i.length==1&&r.length==0)l=i[0],o="add",c=u=>u.mark(l.addToSet(u.marks));else if(i.length==0&&r.length==1)l=r[0],o="remove",c=u=>u.mark(l.removeFromSet(u.marks));else return null;let d=[];for(let u=0;u<e.childCount;u++)d.push(c(e.child(u)));if(V.from(d).eq(t))return{mark:l,type:o}}function rse(t,e,a,n,i){if(a-e<=i.pos-n.pos||tx(n,!0,!1)<i.pos)return!1;let r=t.resolve(e);if(!n.parent.isTextblock){let l=r.nodeAfter;return l!=null&&a==e+l.nodeSize}if(r.parentOffset<r.parent.content.size||!r.parent.isTextblock)return!1;let o=t.resolve(tx(r,!0,!0));return!o.parent.isTextblock||o.pos>a||tx(o,!0,!1)<a?!1:n.parent.content.cut(n.parentOffset).eq(o.parent.content)}function tx(t,e,a){let n=t.depth,i=e?t.end():t.pos;for(;n>0&&(e||t.indexAfter(n)==t.node(n).childCount);)n--,i++,e=!1;if(a){let r=t.node(n).maybeChild(t.indexAfter(n));for(;r&&!r.isLeaf;)r=r.firstChild,i++}return i}function ose(t,e,a,n,i){let r=t.findDiffStart(e,a);if(r==null)return null;let{a:o,b:l}=t.findDiffEnd(e,a+t.size,a+e.size);if(i=="end"){let c=Math.max(0,r-Math.min(o,l));n-=o+c-r}if(o<r&&t.size<e.size){let c=n<=r&&n>=o?r-n:0;r-=c,r&&r<e.size&&hT(e.textBetween(r-1,r+1))&&(r+=c?1:-1),l=r+(l-o),o=r}else if(l<r){let c=n<=r&&n>=l?r-n:0;r-=c,r&&r<t.size&&hT(t.textBetween(r-1,r+1))&&(r+=c?1:-1),o=r+(o-l),l=r}return{start:r,endA:o,endB:l}}function hT(t){if(t.length!=2)return!1;let e=t.charCodeAt(0),a=t.charCodeAt(1);return e>=56320&&e<=57343&&a>=55296&&a<=56319}class p5{constructor(e,a){this._root=null,this.focused=!1,this.trackWrites=null,this.mounted=!1,this.markCursor=null,this.cursorWrapper=null,this.lastSelectedViewDesc=void 0,this.input=new koe,this.prevDirectPlugins=[],this.pluginViews=[],this.requiresGeckoHackNode=!1,this.dragging=null,this._props=a,this.state=a.state,this.directPlugins=a.plugins||[],this.directPlugins.forEach(vT),this.dispatch=this.dispatch.bind(this),this.dom=e&&e.mount||document.createElement("div"),e&&(e.appendChild?e.appendChild(this.dom):typeof e=="function"?e(this.dom):e.mount&&(this.mounted=!0)),this.editable=yT(this),gT(this),this.nodeViews=xT(this),this.docView=Jj(this.state.doc,fT(this),ex(this),this.dom,this),this.domObserver=new Joe(this,(n,i,r,o)=>nse(this,n,i,r,o)),this.domObserver.start(),Soe(this),this.updatePluginViews()}get composing(){return this.input.composing}get props(){if(this._props.state!=this.state){let e=this._props;this._props={};for(let a in e)this._props[a]=e[a];this._props.state=this.state}return this._props}update(e){e.handleDOMEvents!=this._props.handleDOMEvents&&Db(this);let a=this._props;this._props=e,e.plugins&&(e.plugins.forEach(vT),this.directPlugins=e.plugins),this.updateStateInner(e.state,a)}setProps(e){let a={};for(let n in this._props)a[n]=this._props[n];a.state=this.state;for(let n in e)a[n]=e[n];this.update(a)}updateState(e){this.updateStateInner(e,this._props)}updateStateInner(e,a){var n;let i=this.state,r=!1,o=!1;e.storedMarks&&this.composing&&(r5(this),o=!0),this.state=e;let l=i.plugins!=e.plugins||this._props.plugins!=a.plugins;if(l||this._props.plugins!=a.plugins||this._props.nodeViews!=a.nodeViews){let h=xT(this);lse(h,this.nodeViews)&&(this.nodeViews=h,r=!0)}(l||a.handleDOMEvents!=this._props.handleDOMEvents)&&Db(this),this.editable=yT(this),gT(this);let c=ex(this),d=fT(this),u=i.plugins!=e.plugins&&!i.doc.eq(e.doc)?"reset":e.scrollToSelection>i.scrollToSelection?"to selection":"preserve",p=r||!this.docView.matchesNode(e.doc,d,c);(p||!e.selection.eq(i.selection))&&(o=!0);let m=u=="preserve"&&o&&this.dom.style.overflowAnchor==null&&Dre(this);if(o){this.domObserver.stop();let h=p&&(Ra||Nt)&&!this.composing&&!i.selection.empty&&!e.selection.empty&&sse(i.selection,e.selection);if(p){let g=Nt?this.trackWrites=this.domSelectionRange().focusNode:null;this.composing&&(this.input.compositionNode=Doe(this)),(r||!this.docView.update(e.doc,d,c,this))&&(this.docView.updateOuterDeco(d),this.docView.destroy(),this.docView=Jj(e.doc,d,c,this.dom,this)),g&&(!this.trackWrites||!this.dom.contains(this.trackWrites))&&(h=!0)}h||!(this.input.mouseDown&&this.domObserver.currentSelection.eq(this.domSelectionRange())&&soe(this))?Pi(this,h):(GM(this,e.selection),this.domObserver.setCurSelection()),this.domObserver.start()}this.updatePluginViews(i),!((n=this.dragging)===null||n===void 0)&&n.node&&!i.doc.eq(e.doc)&&this.updateDraggedNode(this.dragging,i),u=="reset"?this.dom.scrollTop=0:u=="to selection"?this.scrollToSelection():m&&qre(m)}scrollToSelection(){let e=this.domSelectionRange().focusNode;if(!(!e||!this.dom.contains(e.nodeType==1?e:e.parentNode))){if(!this.someProp("handleScrollToSelection",a=>a(this)))if(this.state.selection instanceof se){let a=this.docView.domAfterPos(this.state.selection.from);a.nodeType==1&&Bj(this,a.getBoundingClientRect(),e)}else Bj(this,this.coordsAtPos(this.state.selection.head,1),e)}}destroyPluginViews(){let e;for(;e=this.pluginViews.pop();)e.destroy&&e.destroy()}updatePluginViews(e){if(!e||e.plugins!=this.state.plugins||this.directPlugins!=this.prevDirectPlugins){this.prevDirectPlugins=this.directPlugins,this.destroyPluginViews();for(let a=0;a<this.directPlugins.length;a++){let n=this.directPlugins[a];n.spec.view&&this.pluginViews.push(n.spec.view(this))}for(let a=0;a<this.state.plugins.length;a++){let n=this.state.plugins[a];n.spec.view&&this.pluginViews.push(n.spec.view(this))}}else for(let a=0;a<this.pluginViews.length;a++){let n=this.pluginViews[a];n.update&&n.update(this,e)}}updateDraggedNode(e,a){let n=e.node,i=-1;if(this.state.doc.nodeAt(n.from)==n.node)i=n.from;else{let r=n.from+(this.state.doc.content.size-a.doc.content.size);(r>0&&this.state.doc.nodeAt(r))==n.node&&(i=r)}this.dragging=new s5(e.slice,e.move,i<0?void 0:se.create(this.state.doc,i))}someProp(e,a){let n=this._props&&this._props[e],i;if(n!=null&&(i=a?a(n):n))return i;for(let o=0;o<this.directPlugins.length;o++){let l=this.directPlugins[o].props[e];if(l!=null&&(i=a?a(l):l))return i}let r=this.state.plugins;if(r)for(let o=0;o<r.length;o++){let l=r[o].props[e];if(l!=null&&(i=a?a(l):l))return i}}hasFocus(){if(Ra){let e=this.root.activeElement;if(e==this.dom)return!0;if(!e||!this.dom.contains(e))return!1;for(;e&&this.dom!=e&&this.dom.contains(e);){if(e.contentEditable=="false")return!1;e=e.parentElement}return!0}return this.root.activeElement==this.dom}focus(){this.domObserver.stop(),this.editable&&zre(this.dom),Pi(this),this.domObserver.start()}get root(){let e=this._root;if(e==null){for(let a=this.dom.parentNode;a;a=a.parentNode)if(a.nodeType==9||a.nodeType==11&&a.host)return a.getSelection||(Object.getPrototypeOf(a).getSelection=()=>a.ownerDocument.getSelection()),this._root=a}return e||document}updateRoot(){this._root=null}posAtCoords(e){return Ure(this,e)}coordsAtPos(e,a=1){return zM(this,e,a)}domAtPos(e,a=0){return this.docView.domFromPos(e,a)}nodeDOM(e){let a=this.docView.descAt(e);return a?a.nodeDOM:null}posAtDOM(e,a,n=-1){let i=this.docView.posFromDOM(e,a,n);if(i==null)throw new RangeError("DOM position not inside the editor");return i}endOfTextblock(e,a){return Jre(this,a||this.state,e)}pasteHTML(e,a){return fu(this,"",e,!1,a||new ClipboardEvent("paste"))}pasteText(e,a){return fu(this,e,null,!0,a||new ClipboardEvent("paste"))}serializeForClipboard(e){return sS(this,e)}destroy(){this.docView&&(_oe(this),this.destroyPluginViews(),this.mounted?(this.docView.update(this.state.doc,[],ex(this),this),this.dom.textContent=""):this.dom.parentNode&&this.dom.parentNode.removeChild(this.dom),this.docView.destroy(),this.docView=null,Cre())}get isDestroyed(){return this.docView==null}dispatchEvent(e){return Eoe(this,e)}domSelectionRange(){let e=this.domSelection();return e?Wt&&this.root.nodeType===11&&Pre(this.dom.ownerDocument)==this.dom&&Xoe(this,e)||e:{focusNode:null,focusOffset:0,anchorNode:null,anchorOffset:0}}domSelection(){return this.root.getSelection()}}p5.prototype.dispatch=function(t){let e=this._props.dispatchTransaction;e?e.call(this,t):this.updateState(this.state.apply(t))};function fT(t){let e=Object.create(null);return e.class="ProseMirror",e.contenteditable=String(t.editable),t.someProp("attributes",a=>{if(typeof a=="function"&&(a=a(t.state)),a)for(let n in a)n=="class"?e.class+=" "+a[n]:n=="style"?e.style=(e.style?e.style+";":"")+a[n]:!e[n]&&n!="contenteditable"&&n!="nodeName"&&(e[n]=String(a[n]))}),e.translate||(e.translate="no"),[ha.node(0,t.state.doc.content.size,e)]}function gT(t){if(t.markCursor){let e=document.createElement("img");e.className="ProseMirror-separator",e.setAttribute("mark-placeholder","true"),e.setAttribute("alt",""),t.cursorWrapper={dom:e,deco:ha.widget(t.state.selection.from,e,{raw:!0,marks:t.markCursor})}}else t.cursorWrapper=null}function yT(t){return!t.someProp("editable",e=>e(t.state)===!1)}function sse(t,e){let a=Math.min(t.$anchor.sharedDepth(t.head),e.$anchor.sharedDepth(e.head));return t.$anchor.start(a)!=e.$anchor.start(a)}function xT(t){let e=Object.create(null);function a(n){for(let i in n)Object.prototype.hasOwnProperty.call(e,i)||(e[i]=n[i])}return t.someProp("nodeViews",a),t.someProp("markViews",a),e}function lse(t,e){let a=0,n=0;for(let i in t){if(t[i]!=e[i])return!0;a++}for(let i in e)n++;return a!=n}function vT(t){if(t.spec.state||t.spec.filterTransaction||t.spec.appendTransaction)throw new RangeError("Plugins passed directly to the view must not have a state component")}var Ur={8:"Backspace",9:"Tab",10:"Enter",12:"NumLock",13:"Enter",16:"Shift",17:"Control",18:"Alt",20:"CapsLock",27:"Escape",32:" ",33:"PageUp",34:"PageDown",35:"End",36:"Home",37:"ArrowLeft",38:"ArrowUp",39:"ArrowRight",40:"ArrowDown",44:"PrintScreen",45:"Insert",46:"Delete",59:";",61:"=",91:"Meta",92:"Meta",106:"*",107:"+",108:",",109:"-",110:".",111:"/",144:"NumLock",145:"ScrollLock",160:"Shift",161:"Shift",162:"Control",163:"Control",164:"Alt",165:"Alt",173:"-",186:";",187:"=",188:",",189:"-",190:".",191:"/",192:"`",219:"[",220:"\\",221:"]",222:"'"},rf={48:")",49:"!",50:"@",51:"#",52:"$",53:"%",54:"^",55:"&",56:"*",57:"(",59:":",61:"+",173:"_",186:":",187:"+",188:"<",189:"_",190:">",191:"?",192:"~",219:"{",220:"|",221:"}",222:'"'},cse=typeof navigator<"u"&&/Mac/.test(navigator.platform),dse=typeof navigator<"u"&&/MSIE \d|Trident\/(?:[7-9]|\d{2,})\..*rv:(\d+)/.exec(navigator.userAgent);for(var Vt=0;Vt<10;Vt++)Ur[48+Vt]=Ur[96+Vt]=String(Vt);for(var Vt=1;Vt<=24;Vt++)Ur[Vt+111]="F"+Vt;for(var Vt=65;Vt<=90;Vt++)Ur[Vt]=String.fromCharCode(Vt+32),rf[Vt]=String.fromCharCode(Vt);for(var ax in Ur)rf.hasOwnProperty(ax)||(rf[ax]=Ur[ax]);function use(t){var e=cse&&t.metaKey&&t.shiftKey&&!t.ctrlKey&&!t.altKey||dse&&t.shiftKey&&t.key&&t.key.length==1||t.key=="Unidentified",a=!e&&t.key||(t.shiftKey?rf:Ur)[t.keyCode]||t.key||"Unidentified";return a=="Esc"&&(a="Escape"),a=="Del"&&(a="Delete"),a=="Left"&&(a="ArrowLeft"),a=="Up"&&(a="ArrowUp"),a=="Right"&&(a="ArrowRight"),a=="Down"&&(a="ArrowDown"),a}const pse=typeof navigator<"u"&&/Mac|iP(hone|[oa]d)/.test(navigator.platform),mse=typeof navigator<"u"&&/Win/.test(navigator.platform);function hse(t){let e=t.split(/-(?!$)/),a=e[e.length-1];a=="Space"&&(a=" ");let n,i,r,o;for(let l=0;l<e.length-1;l++){let c=e[l];
vendor: 18,325 bytes, line 17639
17639if(/^(cmd|meta|m)$/i.test(c))o=!0;else if(/^a(lt)?$/i.test(c))n=!0;else if(/^(c|ctrl|control)$/i.test(c))i=!0;else if(/^s(hift)?$/i.test(c))r=!0;else if(/^mod$/i.test(c))pse?o=!0:i=!0;else throw new Error("Unrecognized modifier name: "+c)}return n&&(a="Alt-"+a),i&&(a="Ctrl-"+a),o&&(a="Meta-"+a),r&&(a="Shift-"+a),a}function fse(t){let e=Object.create(null);for(let a in t)e[hse(a)]=t[a];return e}function nx(t,e,a=!0){return e.altKey&&(t="Alt-"+t),e.ctrlKey&&(t="Ctrl-"+t),e.metaKey&&(t="Meta-"+t),a&&e.shiftKey&&(t="Shift-"+t),t}function gse(t){return new at({props:{handleKeyDown:m5(t)}})}function m5(t){let e=fse(t);return function(a,n){let i=use(n),r,o=e[nx(i,n)];if(o&&o(a.state,a.dispatch,a))return!0;if(i.length==1&&i!=" "){if(n.shiftKey){let l=e[nx(i,n,!1)];if(l&&l(a.state,a.dispatch,a))return!0}if((n.altKey||n.metaKey||n.ctrlKey)&&!(mse&&n.ctrlKey&&n.altKey)&&(r=Ur[n.keyCode])&&r!=i){let l=e[nx(r,n)];if(l&&l(a.state,a.dispatch,a))return!0}}return!1}}var yse=Object.defineProperty,mS=(t,e)=>{for(var a in e)yse(t,a,{get:e[a],enumerable:!0})};function Ug(t){const{state:e,transaction:a}=t;let{selection:n}=a,{doc:i}=a,{storedMarks:r}=a;return{...e,apply:e.apply.bind(e),applyTransaction:e.applyTransaction.bind(e),plugins:e.plugins,schema:e.schema,reconfigure:e.reconfigure.bind(e),toJSON:e.toJSON.bind(e),get storedMarks(){return r},get selection(){return n},get doc(){return i},get tr(){return n=a.selection,i=a.doc,r=a.storedMarks,a}}}var $g=class{constructor(t){this.editor=t.editor,this.rawCommands=this.editor.extensionManager.commands,this.customState=t.state}get hasCustomState(){return!!this.customState}get state(){return this.customState||this.editor.state}get commands(){const{rawCommands:t,editor:e,state:a}=this,{view:n}=e,{tr:i}=a,r=this.buildProps(i);return Object.fromEntries(Object.entries(t).map(([o,l])=>[o,(...d)=>{const u=l(...d)(r);return!i.getMeta("preventDispatch")&&!this.hasCustomState&&n.dispatch(i),u}]))}get chain(){return()=>this.createChain()}get can(){return()=>this.createCan()}createChain(t,e=!0){const{rawCommands:a,editor:n,state:i}=this,{view:r}=n,o=[],l=!!t,c=t||i.tr,d=()=>(!l&&e&&!c.getMeta("preventDispatch")&&!this.hasCustomState&&r.dispatch(c),o.every(p=>p===!0)),u={...Object.fromEntries(Object.entries(a).map(([p,m])=>[p,(...g)=>{const y=this.buildProps(c,e),x=m(...g)(y);return o.push(x),u}])),run:d};return u}createCan(t){const{rawCommands:e,state:a}=this,n=!1,i=t||a.tr,r=this.buildProps(i,n);return{...Object.fromEntries(Object.entries(e).map(([l,c])=>[l,(...d)=>c(...d)({...r,dispatch:void 0})])),chain:()=>this.createChain(i,n)}}buildProps(t,e=!0){const{rawCommands:a,editor:n,state:i}=this,{view:r}=n,o={tr:t,editor:n,view:r,state:Ug({state:i,transaction:t}),dispatch:e?()=>{}:void 0,chain:()=>this.createChain(t,e),can:()=>this.createCan(t),get commands(){return Object.fromEntries(Object.entries(a).map(([l,c])=>[l,(...d)=>c(...d)(o)]))}};return o}},h5={};mS(h5,{blur:()=>xse,clearContent:()=>vse,clearNodes:()=>bse,command:()=>wse,createParagraphNear:()=>kse,cut:()=>Sse,deleteCurrentNode:()=>_se,deleteNode:()=>Ase,deleteRange:()=>Ese,deleteSelection:()=>Cse,enter:()=>jse,exitCode:()=>Tse,extendMarkRange:()=>Nse,first:()=>Ise,focus:()=>Rse,forEach:()=>Lse,insertContent:()=>Ose,insertContentAt:()=>qse,joinBackward:()=>Hse,joinDown:()=>Vse,joinForward:()=>Fse,joinItemBackward:()=>Bse,joinItemForward:()=>Use,joinTextblockBackward:()=>$se,joinTextblockForward:()=>Wse,joinUp:()=>zse,keyboardShortcut:()=>Kse,lift:()=>Jse,liftEmptyBlock:()=>Qse,liftListItem:()=>Xse,newlineInCode:()=>Yse,resetAttributes:()=>Zse,scrollIntoView:()=>ele,selectAll:()=>tle,selectNodeBackward:()=>ale,selectNodeForward:()=>nle,selectParentNode:()=>ile,selectTextblockEnd:()=>rle,selectTextblockStart:()=>ole,setContent:()=>sle,setMark:()=>jle,setMeta:()=>Tle,setNode:()=>Nle,setNodeSelection:()=>Ile,setTextDirection:()=>Ple,setTextSelection:()=>Rle,sinkListItem:()=>Lle,splitBlock:()=>Ole,splitListItem:()=>Mle,toggleList:()=>qle,toggleMark:()=>zle,toggleNode:()=>Vle,toggleWrap:()=>Hle,undoInputRule:()=>Fle,unsetAllMarks:()=>Ble,unsetMark:()=>Ule,unsetTextDirection:()=>$le,updateAttributes:()=>Wle,wrapIn:()=>Gle,wrapInList:()=>Kle});var xse=()=>({editor:t,view:e})=>(requestAnimationFrame(()=>{var a;t.isDestroyed||(e.dom.blur(),(a=window==null?void 0:window.getSelection())==null||a.removeAllRanges())}),!0),vse=(t=!0)=>({commands:e})=>e.setContent("",{emitUpdate:t}),bse=()=>({state:t,tr:e,dispatch:a})=>{const{selection:n}=e,{ranges:i}=n;return a&&i.forEach(({$from:r,$to:o})=>{t.doc.nodesBetween(r.pos,o.pos,(l,c)=>{if(l.type.isText)return;const{doc:d,mapping:u}=e,p=d.resolve(u.map(c)),m=d.resolve(u.map(c+l.nodeSize)),h=p.blockRange(m);if(!h)return;const g=ec(h);if(l.type.isTextblock){const{defaultType:y}=p.parent.contentMatchAt(p.index());e.setNodeMarkup(h.start,y)}(g||g===0)&&e.lift(h,g)})}),!0},wse=t=>e=>t(e),kse=()=>({state:t,dispatch:e})=>jM(t,e),Sse=(t,e)=>({editor:a,tr:n})=>{const{state:i}=a,r=i.doc.slice(t.from,t.to);n.deleteRange(t.from,t.to);const o=n.mapping.map(e);return n.insert(o,r.content),n.setSelection(new ce(n.doc.resolve(Math.max(o-1,0)))),!0},_se=()=>({tr:t,dispatch:e})=>{const{selection:a}=t,n=a.$anchor.node();if(n.content.size>0)return!1;const i=t.selection.$anchor;for(let r=i.depth;r>0;r-=1)if(i.node(r).type===n.type){if(e){const l=i.before(r),c=i.after(r);t.delete(l,c).scrollIntoView()}return!0}return!1};function vt(t,e){if(typeof t=="string"){if(!e.nodes[t])throw Error(`There is no node type named '${t}'. Maybe you forgot to add the extension?`);return e.nodes[t]}return t}var Ase=t=>({tr:e,state:a,dispatch:n})=>{const i=vt(t,a.schema),r=e.selection.$anchor;for(let o=r.depth;o>0;o-=1)if(r.node(o).type===i){if(n){const c=r.before(o),d=r.after(o);e.delete(c,d).scrollIntoView()}return!0}return!1},Ese=t=>({tr:e,dispatch:a})=>{const{from:n,to:i}=t;return a&&e.delete(n,i),!0},Cse=()=>({state:t,dispatch:e})=>Zk(t,e),jse=()=>({commands:t})=>t.keyboardShortcut("Enter"),Tse=()=>({state:t,dispatch:e})=>pre(t,e);function hS(t){return Object.prototype.toString.call(t)==="[object RegExp]"}function of(t,e,a={strict:!0}){const n=Object.keys(e);return n.length?n.every(i=>a.strict?e[i]===t[i]:hS(e[i])?e[i].test(t[i]):e[i]===t[i]):!0}function f5(t,e,a={}){return t.find(n=>n.type===e&&of(Object.fromEntries(Object.keys(a).map(i=>[i,n.attrs[i]])),a))}function bT(t,e,a={}){return!!f5(t,e,a)}function fS(t,e,a){if(!t||!e)return;let n=t.parent.childAfter(t.parentOffset);if((!n.node||!n.node.marks.some(d=>d.type===e))&&(n=t.parent.childBefore(t.parentOffset)),!n.node||!n.node.marks.some(d=>d.type===e))return;if(!a){const d=n.node.marks.find(u=>u.type===e);d&&(a=d.attrs)}if(!f5([...n.node.marks],e,a))return;let r=n.index,o=t.start()+n.offset,l=r+1,c=o+n.node.nodeSize;for(;r>0&&bT([...t.parent.child(r-1).marks],e,a);)r-=1,o-=t.parent.child(r).nodeSize;for(;l<t.parent.childCount&&bT([...t.parent.child(l).marks],e,a);)c+=t.parent.child(l).nodeSize,l+=1;return{from:o,to:c}}function $i(t,e){if(typeof t=="string"){if(!e.marks[t])throw Error(`There is no mark type named '${t}'. Maybe you forgot to add the extension?`);return e.marks[t]}return t}var Nse=(t,e)=>({tr:a,state:n,dispatch:i})=>{const r=$i(t,n.schema),{doc:o,selection:l}=a,{$from:c,from:d,to:u}=l;if(i){const p=fS(c,r,e);if(p&&p.from<=d&&p.to>=u){const m=ce.create(o,p.from,p.to);a.setSelection(m)}}return!0},Ise=t=>e=>{const a=typeof t=="function"?t(e):t;for(let n=0;n<a.length;n+=1)if(a[n](e))return!0;return!1};function g5(t){return t instanceof ce}function jo(t=0,e=0,a=0){return Math.min(Math.max(t,e),a)}function y5(t,e=null){if(!e)return null;const a=xe.atStart(t),n=xe.atEnd(t);if(e==="start"||e===!0)return a;if(e==="end")return n;const i=a.from,r=n.to;return e==="all"?ce.create(t,jo(0,i,r),jo(t.content.size,i,r)):ce.create(t,jo(e,i,r),jo(e,i,r))}function wT(){return navigator.platform==="Android"||/android/i.test(navigator.userAgent)}function sf(){return["iPad Simulator","iPhone Simulator","iPod Simulator","iPad","iPhone","iPod"].includes(navigator.platform)||navigator.userAgent.includes("Mac")&&"ontouchend"in document}function Pse(){return typeof navigator<"u"?/^((?!chrome|android).)*safari/i.test(navigator.userAgent):!1}var Rse=(t=null,e={})=>({editor:a,view:n,tr:i,dispatch:r})=>{e={scrollIntoView:!0,...e};const o=()=>{(sf()||wT())&&n.dom.focus(),Pse()&&!sf()&&!wT()&&n.dom.focus({preventScroll:!0}),requestAnimationFrame(()=>{a.isDestroyed||(n.focus(),e!=null&&e.scrollIntoView&&a.commands.scrollIntoView())})};try{if(n.hasFocus()&&t===null||t===!1)return!0}catch{return!1}if(r&&t===null&&!g5(a.state.selection))return o(),!0;const l=y5(i.doc,t)||a.state.selection,c=a.state.selection.eq(l);return r&&(c||i.setSelection(l),c&&i.storedMarks&&i.setStoredMarks(i.storedMarks),o()),!0},Lse=(t,e)=>a=>t.every((n,i)=>e(n,{...a,index:i})),Ose=(t,e)=>({tr:a,commands:n})=>n.insertContentAt({from:a.selection.from,to:a.selection.to},t,e),x5=t=>{const e=t.childNodes;for(let a=e.length-1;a>=0;a-=1){const n=e[a];n.nodeType===3&&n.nodeValue&&/^(\n\s\s|\n)$/.test(n.nodeValue)?t.removeChild(n):n.nodeType===1&&x5(n)}return t};function em(t){if(typeof window>"u")throw new Error("[tiptap error]: there is no window object available, so this function cannot be used");const e=`<body>${t}</body>`,a=new window.DOMParser().parseFromString(e,"text/html").body;return x5(a)}function yu(t,e,a){if(t instanceof Rn||t instanceof V)return t;a={slice:!0,parseOptions:{},...a};const n=typeof t=="object"&&t!==null,i=typeof t=="string";if(n)try{if(Array.isArray(t)&&t.length>0)return V.fromArray(t.map(l=>e.nodeFromJSON(l)));const o=e.nodeFromJSON(t);return a.errorOnInvalidContent&&o.check(),o}catch(r){if(a.errorOnInvalidContent)throw new Error("[tiptap error]: Invalid JSON content",{cause:r});return console.warn("[tiptap warn]: Invalid content.","Passed value:",t,"Error:",r),yu("",e,a)}if(i){if(a.errorOnInvalidContent){let o=!1,l="";const c=new tM({topNode:e.spec.topNode,marks:e.spec.marks,nodes:e.spec.nodes.append({__tiptap__private__unknown__catch__all__node:{content:"inline*",group:"block",parseDOM:[{tag:"*",getAttrs:d=>(o=!0,l=typeof d=="string"?d:d.outerHTML,null)}]}})});if(a.slice?Rr.fromSchema(c).parseSlice(em(t),a.parseOptions):Rr.fromSchema(c).parse(em(t),a.parseOptions),a.errorOnInvalidContent&&o)throw new Error("[tiptap error]: Invalid HTML content",{cause:new Error(`Invalid element found: ${l}`)})}const r=Rr.fromSchema(e);return a.slice?r.parseSlice(em(t),a.parseOptions).content:r.parse(em(t),a.parseOptions)}return yu("",e,a)}function Mse(t,e,a){const n=t.steps.length-1;if(n<e)return;const i=t.steps[n];if(!(i instanceof Tt||i instanceof Pt))return;const r=t.mapping.maps[n];let o=0;r.forEach((l,c,d,u)=>{o===0&&(o=u)}),t.setSelection(xe.near(t.doc.resolve(o),a))}var Dse=t=>!("type"in t),qse=(t,e,a)=>({tr:n,dispatch:i,editor:r})=>{var o;if(i){a={parseOptions:r.options.parseOptions,updateSelection:!0,applyInputRules:!1,applyPasteRules:!1,...a};let l;const c=x=>{r.emit("contentError",{editor:r,error:x,disableCollaboration:()=>{"collaboration"in r.storage&&typeof r.storage.collaboration=="object"&&r.storage.collaboration&&(r.storage.collaboration.isDisabled=!0)}})},d={preserveWhitespace:"full",...a.parseOptions};if(!a.errorOnInvalidContent&&!r.options.enableContentCheck&&r.options.emitContentError)try{yu(e,r.schema,{parseOptions:d,errorOnInvalidContent:!0})}catch(x){c(x)}try{l=yu(e,r.schema,{parseOptions:d,errorOnInvalidContent:(o=a.errorOnInvalidContent)!=null?o:r.options.enableContentCheck})}catch(x){return c(x),!1}let{from:u,to:p}=typeof t=="number"?{from:t,to:t}:{from:t.from,to:t.to},m=!0,h=!0;if((Dse(l)?l:[l]).forEach(x=>{x.check(),m=m?x.isText&&x.marks.length===0:!1,h=h?x.isBlock:!1}),u===p&&h){const{parent:x}=n.doc.resolve(u);x.isTextblock&&!x.type.spec.code&&!x.childCount&&(u-=1,p+=1)}let y;if(m){if(Array.isArray(e))y=e.map(x=>x.text||"").join("");else if(e instanceof V){let x="";e.forEach(v=>{v.text&&(x+=v.text)}),y=x}else typeof e=="object"&&e&&e.text?y=e.text:y=e;n.insertText(y,u,p)}else{y=l;const x=n.doc.resolve(u),v=x.node(),w=x.parentOffset===0,S=v.isText||v.isTextblock,T=v.content.size>0;w&&S&&T&&h&&(u=Math.max(0,u-1)),n.replaceWith(u,p,y)}a.updateSelection&&Mse(n,n.steps.length-1,-1),a.applyInputRules&&n.setMeta("applyInputRules",{from:u,text:y}),a.applyPasteRules&&n.setMeta("applyPasteRules",{from:u,text:y})}return!0},zse=()=>({state:t,dispatch:e})=>cre(t,e),Vse=()=>({state:t,dispatch:e})=>dre(t,e),Hse=()=>({state:t,dispatch:e})=>wM(t,e),Fse=()=>({state:t,dispatch:e})=>AM(t,e),Bse=()=>({state:t,dispatch:e,tr:a})=>{try{const n=qg(t.doc,t.selection.$from.pos,-1);return n==null?!1:(a.join(n,2),e&&e(a),!0)}catch{return!1}},Use=()=>({state:t,dispatch:e,tr:a})=>{try{const n=qg(t.doc,t.selection.$from.pos,1);return n==null?!1:(a.join(n,2),e&&e(a),!0)}catch{return!1}},$se=()=>({state:t,dispatch:e})=>sre(t,e),Wse=()=>({state:t,dispatch:e})=>lre(t,e);function v5(){return typeof navigator<"u"?/Mac/.test(navigator.platform):!1}function Gse(t){const e=t.split(/-(?!$)/);let a=e[e.length-1];a==="Space"&&(a=" ");let n,i,r,o;for(let l=0;l<e.length-1;l+=1){const c=e[l];if(/^(cmd|meta|m)$/i.test(c))o=!0;else if(/^a(lt)?$/i.test(c))n=!0;else if(/^(c|ctrl|control)$/i.test(c))i=!0;else if(/^s(hift)?$/i.test(c))r=!0;else if(/^mod$/i.test(c))sf()||v5()?o=!0:i=!0;else throw new Error(`Unrecognized modifier name: ${c}`)}return n&&(a=`Alt-${a}`),i&&(a=`Ctrl-${a}`),o&&(a=`Meta-${a}`),r&&(a=`Shift-${a}`),a}var Kse=t=>({editor:e,view:a,tr:n,dispatch:i})=>{const r=Gse(t).split(/-(?!$)/),o=r.find(d=>!["Alt","Ctrl","Meta","Shift"].includes(d)),l=new KeyboardEvent("keydown",{key:o==="Space"?" ":o,altKey:r.includes("Alt"),ctrlKey:r.includes("Ctrl"),metaKey:r.includes("Meta"),shiftKey:r.includes("Shift"),bubbles:!0,cancelable:!0}),c=e.captureTransaction(()=>{a.someProp("handleKeyDown",d=>d(a,l))});return c==null||c.steps.forEach(d=>{const u=d.map(n.mapping);u&&i&&n.maybeStep(u)}),!0};function $r(t,e,a={}){const{from:n,to:i,empty:r}=t.selection,o=e?vt(e,t.schema):null,l=[];t.doc.nodesBetween(n,i,(p,m)=>{if(p.isText)return;const h=Math.max(n,m),g=Math.min(i,m+p.nodeSize);l.push({node:p,from:h,to:g})});const c=i-n,d=l.filter(p=>o?o.name===p.node.type.name:!0).filter(p=>of(p.node.attrs,a,{strict:!1}));return r?!!d.length:d.reduce((p,m)=>p+m.to-m.from,0)>=c}var Jse=(t,e={})=>({state:a,dispatch:n})=>{const i=vt(t,a.schema);return $r(a,i,e)?ure(a,n):!1},Qse=()=>({state:t,dispatch:e})=>TM(t,e),Xse=t=>({state:e,dispatch:a})=>{const n=vt(t,e.schema);return Sre(n)(e,a)},Yse=()=>({state:t,dispatch:e})=>CM(t,e);function Wg(t,e){return e.nodes[t]?"node":e.marks[t]?"mark":null}function kT(t,e){const a=typeof e=="string"?[e]:e;return Object.keys(t).reduce((n,i)=>(a.includes(i)||(n[i]=t[i]),n),{})}var Zse=(t,e)=>({tr:a,state:n,dispatch:i})=>{let r=null,o=null;const l=Wg(typeof t=="string"?t:t.name,n.schema);if(!l)return!1;l==="node"&&(r=vt(t,n.schema)),l==="mark"&&(o=$i(t,n.schema));let c=!1;return a.selection.ranges.forEach(d=>{n.doc.nodesBetween(d.$from.pos,d.$to.pos,(u,p)=>{r&&r===u.type&&(c=!0,i&&a.setNodeMarkup(p,void 0,kT(u.attrs,e))),o&&u.marks.length&&u.marks.forEach(m=>{o===m.type&&(c=!0,i&&a.addMark(p,p+u.nodeSize,o.create(kT(m.attrs,e))))})})}),c},ele=()=>({tr:t,dispatch:e})=>(e&&t.scrollIntoView(),!0),tle=()=>({tr:t,dispatch:e})=>{if(e){const a=new Ua(t.doc);t.setSelection(a)}return!0},ale=()=>({state:t,dispatch:e})=>SM(t,e),nle=()=>({state:t,dispatch:e})=>EM(t,e),ile=()=>({state:t,dispatch:e})=>fre(t,e),rle=()=>({state:t,dispatch:e})=>xre(t,e),ole=()=>({state:t,dispatch:e})=>yre(t,e);function qb(t,e,a={},n={}){return yu(t,e,{slice:!1,parseOptions:a,errorOnInvalidContent:n.errorOnInvalidContent})}var sle=(t,{errorOnInvalidContent:e,emitUpdate:a=!0,parseOptions:n={}}={})=>({editor:i,tr:r,dispatch:o,commands:l})=>{const{doc:c}=r;if(n.preserveWhitespace!=="full"){const d=qb(t,i.schema,n,{errorOnInvalidContent:e??i.options.enableContentCheck});return o&&r.replaceWith(0,c.content.size,d).setMeta("preventUpdate",!a),!0}return o&&r.setMeta("preventUpdate",!a),l.insertContentAt({from:0,to:c.content.size},t,{parseOptions:n,errorOnInvalidContent:e??i.options.enableContentCheck})};function b5(t,e){const a=$i(e,t.schema),{from:n,to:i,empty:r}=t.selection,o=[];r?(t.storedMarks&&o.push(...t.storedMarks),o.push(...t.selection.$head.marks())):t.doc.nodesBetween(n,i,c=>{o.push(...c.marks)});const l=o.find(c=>c.type.name===a.name);return l?{...l.attrs}:{}}function w5(t,e){const a=new yM(t);return e.forEach(n=>{n.steps.forEach(i=>{a.step(i)})}),a}function lle(t){for(let e=0;e<t.edgeCount;e+=1){const{type:a}=t.edge(e);if(a.isTextblock&&!a.hasRequiredAttrs())return a}return null}function cle(t,e,a){const n=[];return t.nodesBetween(e.from,e.to,(i,r)=>{a(i)&&n.push({node:i,pos:r})}),n}function dle(t,e){for(let a=t.depth;a>0;a-=1){const n=t.node(a);if(e(n))return{pos:a>0?t.before(a):0,start:t.start(a),depth:a,node:n}}}function Gg(t){return e=>dle(e.$from,t)}function te(t,e,a){return t.config[e]===void 0&&t.parent?te(t.parent,e,a):typeof t.config[e]=="function"?t.config[e].bind({...a,parent:t.parent?te(t.parent,e,a):null}):t.config[e]}function gS(t){return t.map(e=>{const a={name:e.name,options:e.options,storage:e.storage},n=te(e,"addExtensions",a);return n?[e,...gS(n())]:e}).flat(10)}function yS(t,e){const a=fs.fromSchema(e).serializeFragment(t),i=document.implementation.createHTMLDocument().createElement("div");return i.appendChild(a),i.innerHTML}function k5(t){return typeof t=="function"}function Pe(t,e=void 0,...a){return k5(t)?e?t.bind(e)(...a):t(...a):t}function ule(t={}){return Object.keys(t).length===0&&t.constructor===Object}function Ol(t){const e=t.filter(i=>i.type==="extension"),a=t.filter(i=>i.type==="node"),n=t.filter(i=>i.type==="mark");return{baseExtensions:e,nodeExtensions:a,markExtensions:n}}function S5(t){const e=[],{nodeExtensions:a,markExtensions:n}=Ol(t),i=[...a,...n],r={default:null,validate:void 0,rendered:!0,renderHTML:null,parseHTML:null,keepOnSplit:!0,isRequired:!1},o=a.filter(d=>d.name!=="text").map(d=>d.name),l=n.map(d=>d.name),c=[...o,...l];return t.forEach(d=>{const u={name:d.name,options:d.options,storage:d.storage,extensions:i},p=te(d,"addGlobalAttributes",u);if(!p)return;p().forEach(h=>{let g;Array.isArray(h.types)?g=h.types:h.types==="*"?g=c:h.types==="nodes"?g=o:h.types==="marks"?g=l:g=[],g.forEach(y=>
17639{Object.entries(h.attributes).forEach(([x,v])=>{e.push({type:y,name:x,attribute:{...r,...v}})})})})}),i.forEach(d=>{const u={name:d.name,options:d.options,storage:d.storage},p=te(d,"addAttributes",u);if(!p)return;const m=p();Object.entries(m).forEach(([h,g])=>{const y={...r,...g};typeof(y==null?void 0:y.default)=="function"&&(y.default=y.default()),y!=null&&y.isRequired&&(y==null?void 0:y.default)===void 0&&delete y.default,e.push({type:d.name,name:h,attribute:y})})}),e}function ple(t){const e=[];let a="",n=!1,i=!1,r=0;const o=t.length;for(let l=0;l<o;l+=1){const c=t[l];if(c==="'"&&!i){n=!n,a+=c;continue}if(c==='"'&&!n){i=!i,a+=c;continue}if(!n&&!i){if(c==="("){r+=1,a+=c;continue}if(c===")"&&r>0){r-=1,a+=c;continue}if(c===";"&&r===0){e.push(a),a="";continue}}a+=c}return a&&e.push(a),e}function ST(t){const e=[],a=ple(t||""),n=a.length;for(let i=0;i<n;i+=1){const r=a[i],o=r.indexOf(":");if(o===-1)continue;const l=r.slice(0,o).trim(),c=r.slice(o+1).trim();l&&c&&e.push([l,c])}return e}function ct(...t){return t.filter(e=>!!e).reduce((e,a)=>{const n={...e};return Object.entries(a).forEach(([i,r])=>{if(!n[i]){n[i]=r;return}if(i==="class"){const l=r?String(r).split(" "):[],c=n[i]?n[i].split(" "):[],d=l.filter(u=>!c.includes(u));n[i]=[...c,...d].join(" ")}else if(i==="style"){const l=new Map([...ST(n[i]),...ST(r)]);n[i]=Array.from(l.entries()).map(([c,d])=>`${c}: ${d}`).join("; ")}else n[i]=r}),n},{})}function xu(t,e){return e.filter(a=>a.type===t.type.name).filter(a=>a.attribute.rendered).map(a=>a.attribute.renderHTML?a.attribute.renderHTML(t.attrs)||{}:{[a.name]:t.attrs[a.name]}).reduce((a,n)=>ct(a,n),{})}function mle(t){return typeof t!="string"?t:t.match(/^[+-]?(?:\d*\.)?\d+$/)?Number(t):t==="true"?!0:t==="false"?!1:t}function _T(t,e){return"style"in t?t:{...t,getAttrs:a=>{const n=t.getAttrs?t.getAttrs(a):t.attrs;if(n===!1)return!1;const i=e.reduce((r,o)=>{const l=o.attribute.parseHTML?o.attribute.parseHTML(a):mle(a.getAttribute(o.name));return l==null?r:{...r,[o.name]:l}},{});return{...n,...i}}}}function AT(t){return Object.fromEntries(Object.entries(t).filter(([e,a])=>e==="attrs"&&ule(a)?!1:a!=null))}function ET(t){var e,a;const n={};return!((e=t==null?void 0:t.attribute)!=null&&e.isRequired)&&"default"in((t==null?void 0:t.attribute)||{})&&(n.default=t.attribute.default),((a=t==null?void 0:t.attribute)==null?void 0:a.validate)!==void 0&&(n.validate=t.attribute.validate),[t.name,n]}function hle(t,e){var a;const n=S5(t),{nodeExtensions:i,markExtensions:r}=Ol(t),o=(a=i.find(d=>te(d,"topNode")))==null?void 0:a.name,l=Object.fromEntries(i.map(d=>{const u=n.filter(v=>v.type===d.name),p={name:d.name,options:d.options,storage:d.storage,editor:e},m=t.reduce((v,w)=>{const S=te(w,"extendNodeSchema",p);return{...v,...S?S(d):{}}},{}),h=AT({...m,content:Pe(te(d,"content",p)),marks:Pe(te(d,"marks",p)),group:Pe(te(d,"group",p)),inline:Pe(te(d,"inline",p)),atom:Pe(te(d,"atom",p)),selectable:Pe(te(d,"selectable",p)),draggable:Pe(te(d,"draggable",p)),code:Pe(te(d,"code",p)),whitespace:Pe(te(d,"whitespace",p)),linebreakReplacement:Pe(te(d,"linebreakReplacement",p)),defining:Pe(te(d,"defining",p)),isolating:Pe(te(d,"isolating",p)),attrs:Object.fromEntries(u.map(ET))}),g=Pe(te(d,"parseHTML",p));g&&(h.parseDOM=g.map(v=>_T(v,u)));const y=te(d,"renderHTML",p);y&&(h.toDOM=v=>y({node:v,HTMLAttributes:xu(v,u)}));const x=te(d,"renderText",p);return x&&(h.toText=x),[d.name,h]})),c=Object.fromEntries(r.map(d=>{const u=n.filter(x=>x.type===d.name),p={name:d.name,options:d.options,storage:d.storage,editor:e},m=t.reduce((x,v)=>{const w=te(v,"extendMarkSchema",p);return{...x,...w?w(d):{}}},{}),h=AT({...m,inclusive:Pe(te(d,"inclusive",p)),excludes:Pe(te(d,"excludes",p)),group:Pe(te(d,"group",p)),spanning:Pe(te(d,"spanning",p)),code:Pe(te(d,"code",p)),attrs:Object.fromEntries(u.map(ET))}),g=Pe(te(d,"parseHTML",p));g&&(h.parseDOM=g.map(x=>_T(x,u)));const y=te(d,"renderHTML",p);return y&&(h.toDOM=x=>y({mark:x,HTMLAttributes:xu(x,u)})),[d.name,h]}));return new tM({topNode:o,nodes:l,marks:c})}function fle(t){const e=t.filter((a,n)=>t.indexOf(a)!==n);return Array.from(new Set(e))}function Sd(t){return t.sort((a,n)=>{const i=te(a,"priority")||100,r=te(n,"priority")||100;return i>r?-1:i<r?1:0})}function _5(t){const e=Sd(gS(t)),a=fle(e.map(n=>n.name));return a.length&&console.warn(`[tiptap warn]: Duplicate extension names found: [${a.map(n=>`'${n}'`).join(", ")}]. This can lead to issues.`),e}function A5(t,e,a){const{from:n,to:i}=e,{blockSeparator:r=`
17640
17641`,textSerializers:o={}}=a||{};let l="";return t.nodesBetween(n,i,(c,d,u,p)=>{var m;c.isBlock&&d>n&&(l+=r);const h=o==null?void 0:o[c.type.name];if(h)return u&&(l+=h({node:c,pos:d,parent:u,index:p,range:e})),!1;c.isText&&(l+=(m=c==null?void 0:c.text)==null?void 0:m.slice(Math.max(n,d)-d,i-d))}),l}function gle(t,e){const a={from:0,to:t.content.size};return A5(t,a,e)}function E5(t){return Object.fromEntries(Object.entries(t.nodes).filter(([,e])=>e.spec.toText).map(([e,a])=>[e,a.spec.toText]))}function yle(t,e){const a=vt(e,t.schema),{from:n,to:i}=t.selection,r=[];t.doc.nodesBetween(n,i,l=>{r.push(l)});const o=r.reverse().find(l=>l.type.name===a.name);return o?{...o.attrs}:{}}function C5(t,e){const a=Wg(typeof e=="string"?e:e.name,t.schema);return a==="node"?yle(t,e):a==="mark"?b5(t,e):{}}function xle(t,e=JSON.stringify){const a={};return t.filter(n=>{const i=e(n);return Object.prototype.hasOwnProperty.call(a,i)?!1:a[i]=!0})}function vle(t){const e=xle(t);return e.length===1?e:e.filter((a,n)=>!e.filter((r,o)=>o!==n).some(r=>a.oldRange.from>=r.oldRange.from&&a.oldRange.to<=r.oldRange.to&&a.newRange.from>=r.newRange.from&&a.newRange.to<=r.newRange.to))}function j5(t){const{mapping:e,steps:a}=t,n=[];return e.maps.forEach((i,r)=>{const o=[];if(i.ranges.length)i.forEach((l,c)=>{o.push({from:l,to:c})});else{const{from:l,to:c}=a[r];if(l===void 0||c===void 0)return;o.push({from:l,to:c})}o.forEach(({from:l,to:c})=>{const d=e.slice(r).map(l,-1),u=e.slice(r).map(c),p=e.invert().map(d,-1),m=e.invert().map(u);n.push({oldRange:{from:p,to:m},newRange:{from:d,to:u}})})}),vle(n)}function xS(t,e,a){const n=[];return t===e?a.resolve(t).marks().forEach(i=>{const r=a.resolve(t),o=fS(r,i.type);o&&n.push({mark:i,...o})}):a.nodesBetween(t,e,(i,r)=>{!i||(i==null?void 0:i.nodeSize)===void 0||n.push(...i.marks.map(o=>({from:r,to:r+i.nodeSize,mark:o})))}),n}var ble=(t,e,a,n=20)=>{const i=t.doc.resolve(a);let r=n,o=null;for(;r>0&&o===null;){const l=i.node(r);(l==null?void 0:l.type.name)===e?o=l:r-=1}return[o,r]};function Ic(t,e){return e.nodes[t]||e.marks[t]||null}function $m(t,e,a){return Object.fromEntries(Object.entries(a).filter(([n])=>{const i=t.find(r=>r.type===e&&r.name===n);return i?i.attribute.keepOnSplit:!1}))}var wle=(t,e=500)=>{let a="";const n=t.parentOffset;return t.parent.nodesBetween(Math.max(0,n-e),n,(i,r,o,l)=>{var c,d;const u=((d=(c=i.type.spec).toText)==null?void 0:d.call(c,{node:i,pos:r,parent:o,index:l}))||i.textContent||"%leaf%";a+=i.isAtom&&!i.isText?u:u.slice(0,Math.max(0,n-r))}),a};function zb(t,e,a={}){const{empty:n,ranges:i}=t.selection,r=e?$i(e,t.schema):null;if(n)return!!(t.storedMarks||t.selection.$from.marks()).filter(p=>r?r.name===p.type.name:!0).find(p=>of(p.attrs,a,{strict:!1}));let o=0;const l=[];if(i.forEach(({$from:p,$to:m})=>{const h=p.pos,g=m.pos;t.doc.nodesBetween(h,g,(y,x)=>{if(r&&y.inlineContent&&!y.type.allowsMarkType(r))return!1;if(!y.isText&&!y.marks.length)return;const v=Math.max(h,x),w=Math.min(g,x+y.nodeSize),S=w-v;o+=S,l.push(...y.marks.map(T=>({mark:T,from:v,to:w})))})}),o===0)return!1;const c=l.filter(p=>r?r.name===p.mark.type.name:!0).filter(p=>of(p.mark.attrs,a,{strict:!1})).reduce((p,m)=>p+m.to-m.from,0),d=l.filter(p=>r?p.mark.type!==r&&p.mark.type.excludes(r):!0).reduce((p,m)=>p+m.to-m.from,0);return(c>0?c+d:c)>=o}function kle(t,e,a={}){if(!e)return $r(t,null,a)||zb(t,null,a);const n=Wg(e,t.schema);return n==="node"?$r(t,e,a):n==="mark"?zb(t,e,a):!1}var Sle=(t,e)=>{const{$from:a,$to:n,$anchor:i}=t.selection;if(e){const r=Gg(l=>l.type.name===e)(t.selection);if(!r)return!1;const o=t.doc.resolve(r.pos+1);return i.pos+1===o.end()}return!(n.parentOffset<n.parent.nodeSize-2||a.pos!==n.pos)},_le=t=>{const{$from:e,$to:a}=t.selection;return!(e.parentOffset>0||e.pos!==a.pos)};function CT(t,e){return Array.isArray(e)?e.some(a=>(typeof a=="string"?a:a.name)===t.name):e}function ix(t,e){const{nodeExtensions:a}=Ol(e),n=a.find(o=>o.name===t);if(!n)return!1;const i={name:n.name,options:n.options,storage:n.storage},r=Pe(te(n,"group",i));return typeof r!="string"?!1:r.split(" ").includes("list")}function Kg(t,{checkChildren:e=!0,ignoreWhitespace:a=!1}={}){var n;if(a){if(t.type.name==="hardBreak")return!0;
vendor: 43,382 bytes, lines 17641-17714
17641if(t.isText)return!/\S/.test((n=t.text)!=null?n:"")}if(t.isText)return!t.text;if(t.isAtom||t.isLeaf)return!1;if(t.content.childCount===0)return!0;if(e){let i=!0;return t.content.forEach(r=>{i!==!1&&(Kg(r,{ignoreWhitespace:a,checkChildren:e})||(i=!1))}),i}return!1}function T5(t){return t instanceof se}var N5=class I5{constructor(e){this.position=e}static fromJSON(e){return new I5(e.position)}toJSON(){return{position:this.position}}};function Ale(t,e){const a=e.mapping.mapResult(t.position);return{position:new N5(a.pos),mapResult:a}}function Ele(t){return new N5(t)}function Cle(t,e,a){var n;const{selection:i}=e;let r=null;if(g5(i)&&(r=i.$cursor),r){const l=(n=t.storedMarks)!=null?n:r.marks();return r.parent.type.allowsMarkType(a)&&(!!a.isInSet(l)||!l.some(d=>d.type.excludes(a)))}const{ranges:o}=i;return o.some(({$from:l,$to:c})=>{let d=l.depth===0?t.doc.inlineContent&&t.doc.type.allowsMarkType(a):!1;return t.doc.nodesBetween(l.pos,c.pos,(u,p,m)=>{if(d)return!1;if(u.isInline){const h=!m||m.type.allowsMarkType(a),g=!!a.isInSet(u.marks)||!u.marks.some(y=>y.type.excludes(a));d=h&&g}return!d}),d})}var jle=(t,e={})=>({tr:a,state:n,dispatch:i})=>{const{selection:r}=a,{empty:o,ranges:l}=r,c=$i(t,n.schema);if(i)if(o){const d=b5(n,c);a.addStoredMark(c.create({...d,...e}))}else l.forEach(d=>{const u=d.$from.pos,p=d.$to.pos;n.doc.nodesBetween(u,p,(m,h)=>{const g=Math.max(h,u),y=Math.min(h+m.nodeSize,p);m.marks.find(v=>v.type===c)?m.marks.forEach(v=>{c===v.type&&a.addMark(g,y,c.create({...v.attrs,...e}))}):a.addMark(g,y,c.create(e))})});return Cle(n,a,c)},Tle=(t,e)=>({tr:a})=>(a.setMeta(t,e),!0),Nle=(t,e={})=>({state:a,dispatch:n,chain:i})=>{const r=vt(t,a.schema);let o;return a.selection.$anchor.sameParent(a.selection.$head)&&(o=a.selection.$anchor.parent.attrs),r.isTextblock?i().command(({commands:l})=>Vj(r,{...o,...e})(a)?!0:l.clearNodes()).command(({state:l})=>Vj(r,{...o,...e})(l,n)).run():(console.warn('[tiptap warn]: Currently "setNode()" only supports text block nodes.'),!1)},Ile=t=>({tr:e,dispatch:a})=>{if(a){const{doc:n}=e,i=jo(t,0,n.content.size),r=se.create(n,i);e.setSelection(r)}return!0},Ple=(t,e)=>({tr:a,state:n,dispatch:i})=>{const{selection:r}=n;let o,l;return typeof e=="number"?(o=e,l=e):e&&"from"in e&&"to"in e?(o=e.from,l=e.to):(o=r.from,l=r.to),i&&a.doc.nodesBetween(o,l,(c,d)=>{c.isText||a.setNodeMarkup(d,void 0,{...c.attrs,dir:t})}),!0},Rle=t=>({tr:e,dispatch:a})=>{if(a){const{doc:n}=e,{from:i,to:r}=typeof t=="number"?{from:t,to:t}:t,o=ce.atStart(n).from,l=ce.atEnd(n).to,c=jo(i,o,l),d=jo(r,o,l),u=ce.create(n,c,d);e.setSelection(u)}return!0},Lle=t=>({state:e,dispatch:a})=>{const n=vt(t,e.schema);return Ere(n)(e,a)};function jT(t,e){const a=t.storedMarks||t.selection.$to.parentOffset&&t.selection.$from.marks();if(a){const n=a.filter(i=>e==null?void 0:e.includes(i.type.name));t.tr.ensureMarks(n)}}var Ole=({keepMarks:t=!0}={})=>({tr:e,state:a,dispatch:n,editor:i})=>{const{selection:r,doc:o}=e,{$from:l,$to:c}=r,d=i.extensionManager.attributes,u=$m(d,l.node().type.name,l.node().attrs);if(r instanceof se&&r.node.isBlock)return!l.parentOffset||!Ii(o,l.pos)?!1:(n&&(t&&jT(a,i.extensionManager.splittableMarks),e.split(l.pos).scrollIntoView()),!0);if(!l.parent.isBlock)return!1;const p=c.parentOffset===c.parent.content.size,m=l.depth===0?void 0:lle(l.node(-1).contentMatchAt(l.indexAfter(-1)));let h=p&&m?[{type:m,attrs:u}]:void 0,g=Ii(e.doc,e.mapping.map(l.pos),1,h);if(!h&&!g&&Ii(e.doc,e.mapping.map(l.pos),1,m?[{type:m}]:void 0)&&(g=!0,h=m?[{type:m,attrs:u}]:void 0),n){if(g&&(r instanceof ce&&e.deleteSelection(),e.split(e.mapping.map(l.pos),1,h),m&&!p&&!l.parentOffset&&l.parent.type!==m)){const y=e.mapping.map(l.before()),x=e.doc.resolve(y);l.node(-1).canReplaceWith(x.index(),x.index()+1,m)&&e.setNodeMarkup(e.mapping.map(l.before()),m)}t&&jT(a,i.extensionManager.splittableMarks),e.scrollIntoView()}return g},Mle=(t,e={})=>({tr:a,state:n,dispatch:i,editor:r})=>{var o;const l=vt(t,n.schema),{$from:c,$to:d}=n.selection,u=n.selection.node;if(u&&u.isBlock||c.depth<2||!c.sameParent(d))return!1;const p=c.node(-1);if(p.type!==l)return!1;const m=r.extensionManager.attributes;if(c.parent.content.size===0&&c.node(-1).childCount===c.indexAfter(-1)){if(c.depth===2||c.node(-3).type!==l||c.index(-2)!==c.node(-2).childCount-1)return!1;if(i){let v=V.empty;const w=c.index(-1)?1:c.index(-2)?2:3;for(let E=c.depth-w;E>=c.depth-3;E-=1)v=V.from(c.node(E).copy(v));const S=c.indexAfter(-1)<c.node(-2).childCount?1:c.indexAfter(-2)<c.node(-3).childCount?2:3,T={...$m(m,c.node().type.name,c.node().attrs),...e},P=((o=l.contentMatch.defaultType)==null?void 0:o.createAndFill(T))||void 0;v=v.append(V.from(l.createAndFill(null,P)||void 0));const M=c.before(c.depth-(w-1));a.replace(M,c.after(-S),new K(v,4-w,0));let C=-1;a.doc.nodesBetween(M,a.doc.content.size,(E,j)=>{if(C>-1)return!1;E.isTextblock&&E.content.size===0&&(C=j+1)}),C>-1&&a.setSelection(ce.near(a.doc.resolve(C))),a.scrollIntoView()}return!0}const h=d.pos===c.end()?p.contentMatchAt(0).defaultType:null,g={...$m(m,p.type.name,p.attrs),...e},y={...$m(m,c.node().type.name,c.node().attrs),...e};a.delete(c.pos,d.pos);const x=h?[{type:l,attrs:g},{type:h,attrs:y}]:[{type:l,attrs:g}];if(!Ii(a.doc,c.pos,2))return!1;if(i){const{selection:v,storedMarks:w}=n,{splittableMarks:S}=r.extensionManager,T=w||v.$to.parentOffset&&v.$from.marks();if(a.split(c.pos,2,x).scrollIntoView(),!T||!i)return!0;const P=T.filter(M=>S.includes(M.type.name));a.ensureMarks(P)}return!0},rx=(t,e)=>{const a=Gg(o=>o.type===e)(t.selection);if(!a)return!0;const n=t.doc.resolve(Math.max(0,a.pos-1)).before(a.depth);if(n===void 0)return!0;const i=t.doc.nodeAt(n);return a.node.type===(i==null?void 0:i.type)&&eo(t.doc,a.pos)&&t.join(a.pos),!0},ox=(t,e)=>{const a=Gg(o=>o.type===e)(t.selection);if(!a)return!0;const n=t.doc.resolve(a.start).after(a.depth);if(n===void 0)return!0;const i=t.doc.nodeAt(n);return a.node.type===(i==null?void 0:i.type)&&eo(t.doc,n)&&t.join(n),!0};function Dle(t){const e=t.doc,a=e.firstChild;if(!a)return null;const n=e.resolve(1),i=e.resolve(a.nodeSize-1);return ce.between(n,i)}var qle=(t,e,a,n={})=>({editor:i,tr:r,state:o,dispatch:l,chain:c,commands:d,can:u})=>{const{extensions:p,splittableMarks:m}=i.extensionManager,h=vt(t,o.schema),g=vt(e,o.schema),{selection:y,storedMarks:x}=o,{$from:v,$to:w}=y,S=v.blockRange(w),T=x||y.$to.parentOffset&&y.$from.marks();if(!S)return!1;const P=Gg(R=>ix(R.type.name,p))(y),M=y.from===0&&y.to===o.doc.content.size,C=o.doc.content.content,E=C.length===1?C[0]:null,j=M&&E&&ix(E.type.name,p)?{node:E,pos:0}:null,N=P??j,L=!!P&&S.depth>=1&&S.depth-P.depth<=1,O=!!j;if((L||O)&&N){if(N.node.type===h)return M&&O?c().command(({tr:R,dispatch:G})=>{const ee=Dle(R);return ee?(R.setSelection(ee),G&&G(R),!0):!1}).liftListItem(g).run():d.liftListItem(g);if(ix(N.node.type.name,p)&&h.validContent(N.node.content))return c().command(()=>(r.setNodeMarkup(N.pos,h),!0)).command(()=>rx(r,h)).command(()=>ox(r,h)).run()}return!a||!T||!l?c().command(()=>u().wrapInList(h,n)?!0:d.clearNodes()).wrapInList(h,n).command(()=>rx(r,h)).command(()=>ox(r,h)).run():c().command(()=>{const R=u().wrapInList(h,n),G=T.filter(ee=>m.includes(ee.type.name));return r.ensureMarks(G),R?!0:d.clearNodes()}).wrapInList(h,n).command(()=>rx(r,h)).command(()=>ox(r,h)).run()},zle=(t,e={},a={})=>({state:n,commands:i})=>{const{extendEmptyMarkRange:r=!1}=a,o=$i(t,n.schema);return zb(n,o,e)?i.unsetMark(o,{extendEmptyMarkRange:r}):i.setMark(o,e)},Vle=(t,e,a={})=>({state:n,commands:i})=>{const r=vt(t,n.schema),o=vt(e,n.schema),l=$r(n,r,a);let c;return n.selection.$anchor.sameParent(n.selection.$head)&&(c=n.selection.$anchor.parent.attrs),l?i.setNode(o,c):i.setNode(r,{...c,...a})},Hle=(t,e={})=>({state:a,commands:n})=>{const i=vt(t,a.schema);return $r(a,i,e)?n.lift(i):n.wrapIn(i,e)},Fle=()=>({state:t,dispatch:e})=>{const a=t.plugins;for(let n=0;n<a.length;n+=1){const i=a[n];let r;if(i.spec.isInputRules&&(r=i.getState(t))){if(e){const o=t.tr,l=r.transform;for(let c=l.steps.length-1;c>=0;c-=1)o.step(l.steps[c].invert(l.docs[c]));if(r.text){const c=o.doc.resolve(r.from).marks();o.replaceWith(r.from,r.to,t.schema.text(r.text,c))}else o.delete(r.from,r.to)}return!0}}return!1},Ble=()=>({tr:t,dispatch:e})=>{const{selection:a}=t,{empty:n,ranges:i}=a;return n||e&&i.forEach(r=>{t.removeMark(r.$from.pos,r.$to.pos)}),!0},Ule=(t,e={})=>({tr:a,state:n,dispatch:i})=>{var r;const{extendEmptyMarkRange:o=!1}=e,{selection:l}=a,c=$i(t,n.schema),{$from:d,empty:u,ranges:p}=l;if(!i)return!0;if(u&&o){let{from:m,to:h}=l;const g=(r=d.marks().find(x=>x.type===c))==null?void 0:r.attrs,y=fS(d,c,g);y&&(m=y.from,h=y.to),a.removeMark(m,h,c)}else p.forEach(m=>{a.removeMark(m.$from.pos,m.$to.pos,c)});return a.removeStoredMark(c),!0},$le=t=>({tr:e,state:a,dispatch:n})=>{const{selection:i}=a;let r,o;return typeof t=="number"?(r=t,o=t):t&&"from"in t&&"to"in t?(r=t.from,o=t.to):(r=i.from,o=i.to),n&&e.doc.nodesBetween(r,o,(l,c)=>{if(l.isText)return;const d={...l.attrs};delete d.dir,e.setNodeMarkup(c,void 0,d)}),!0},Wle=(t,e={})=>({tr:a,state:n,dispatch:i})=>{let r=null,o=null;const l=Wg(typeof t=="string"?t:t.name,n.schema);if(!l)return!1;l==="node"&&(r=vt(t,n.schema)),l==="mark"&&(o=$i(t,n.schema));let c=!1;return a.selection.ranges.forEach(d=>{const u=d.$from.pos,p=d.$to.pos;let m,h,g,y;a.selection.empty?n.doc.nodesBetween(u,p,(x,v)=>{r&&r===x.type&&(c=!0,g=Math.max(v,u),y=Math.min(v+x.nodeSize,p),m=v,h=x)}):n.doc.nodesBetween(u,p,(x,v)=>{v<u&&r&&r===x.type&&(c=!0,g=Math.max(v,u),y=Math.min(v+x.nodeSize,p),m=v,h=x),v>=u&&v<=p&&(r&&r===x.type&&(c=!0,i&&a.setNodeMarkup(v,void 0,{...x.attrs,...e})),o&&x.marks.length&&x.marks.forEach(w=>{if(o===w.type&&(c=!0,i)){const S=Math.max(v,u),T=Math.min(v+x.nodeSize,p);a.addMark(S,T,o.create({...w.attrs,...e}))}}))}),h&&(m!==void 0&&i&&a.setNodeMarkup(m,void 0,{...h.attrs,...e}),o&&h.marks.length&&h.marks.forEach(x=>{o===x.type&&i&&a.addMark(g,y,o.create({...x.attrs,...e}))}))}),c},Gle=(t,e={})=>({state:a,dispatch:n})=>{const i=vt(t,a.schema);return vre(i,e)(a,n)},Kle=(t,e={})=>({state:a,dispatch:n})=>{const i=vt(t,a.schema);return bre(i,e)(a,n)},Jle=class{constructor(){this.callbacks={}}on(t,e){return this.callbacks[t]||(this.callbacks[t]=[]),this.callbacks[t].push(e),this}emit(t,...e){const a=this.callbacks[t];return a&&a.forEach(n=>n.apply(this,e)),this}off(t,e){const a=this.callbacks[t];return a&&(e?this.callbacks[t]=a.filter(n=>n!==e):delete this.callbacks[t]),this}once(t,e){const a=(...n)=>{this.off(t,a),e.apply(this,n)};return this.on(t,a)}removeAllListeners(){this.callbacks={}}},Jg=class{constructor(t){var e;this.find=t.find,this.handler=t.handler,this.undoable=(e=t.undoable)!=null?e:!0}},Qle=(t,e)=>{if(hS(e))return e.exec(t);const a=e(t);if(!a)return null;const n=[a.text];return n.index=a.index,n.input=t,n.data=a.data,a.replaceWith&&(a.text.includes(a.replaceWith)||console.warn('[tiptap warn]: "inputRuleMatch.replaceWith" must be part of "inputRuleMatch.text".'),n.push(a.replaceWith)),n};function tm(t){var e;const{editor:a,from:n,to:i,text:r,rules:o,plugin:l}=t,{view:c}=a;if(c.composing)return!1;const d=c.state.doc.resolve(n);if(d.parent.type.spec.code||(e=d.nodeBefore||d.nodeAfter)!=null&&e.marks.find(m=>m.type.spec.code))return!1;let u=!1;const p=wle(d)+r;return o.forEach(m=>{if(u)return;const h=Qle(p,m.find);if(!h)return;const g=c.state.tr,y=Ug({state:c.state,transaction:g}),x={from:n-(h[0].length-r.length),to:i},{commands:v,chain:w,can:S}=new $g({editor:a,state:y});m.handler({state:y,range:x,match:h,commands:v,chain:w,can:S})===null||!g.steps.length||(m.undoable&&g.setMeta(l,{transform:g,from:n,to:i,text:r}),c.dispatch(g),u=!0)}),u}function Xle(t){const{editor:e,rules:a}=t,n=new at({state:{init(){return null},apply(i,r,o){const l=i.getMeta(n);if(l)return l;const c=i.getMeta("applyInputRules");return!!c&&setTimeout(()=>{let{text:u}=c;typeof u=="string"?u=u:u=yS(V.from(u),o.schema);const{from:p}=c,m=p+u.length;tm({editor:e,from:p,to:m,text:u,rules:a,plugin:n})}),i.selectionSet||i.docChanged?null:r}},props:{handleTextInput(i,r,o,l){return tm({editor:e,from:r,to:o,text:l,rules:a,plugin:n})},handleDOMEvents:{compositionend:i=>(setTimeout(()=>{const{$cursor:r}=i.state.selection;r&&tm({editor:e,from:r.pos,to:r.pos,text:"",rules:a,plugin:n})}),!1)},handleKeyDown(i,r){if(r.key!=="Enter")return!1;const{$cursor:o}=i.state.selection;return o?tm({editor:e,from:o.pos,to:o.pos,text:`
17642`,rules:a,plugin:n}):!1}},isInputRules:!0});return n}function Yle(t){return Object.prototype.toString.call(t).slice(8,-1)}function am(t){return Yle(t)!=="Object"?!1:t.constructor===Object&&Object.getPrototypeOf(t)===Object.prototype}function P5(t,e){const a={...t};return am(t)&&am(e)&&Object.keys(e).forEach(n=>{am(e[n])&&am(t[n])?a[n]=P5(t[n],e[n]):a[n]=e[n]}),a}var vS=class{constructor(t={}){this.type="extendable",this.parent=null,this.child=null,this.name="",this.config={name:this.name},this.config={...this.config,...t},this.name=this.config.name}get options(){return{...Pe(te(this,"addOptions",{name:this.name}))||{}}}get storage(){return{...Pe(te(this,"addStorage",{name:this.name,options:this.options}))||{}}}configure(t={}){const e=this.extend({...this.config,addOptions:()=>P5(this.options,t)});return e.name=this.name,e.parent=this.parent,e}extend(t={}){const e=new this.constructor({...this.config,...t});return e.parent=this,this.child=e,e.name="name"in t?t.name:e.parent.name,e}},ao=class R5 extends vS{constructor(){super(...arguments),this.type="mark"}static create(e={}){const a=typeof e=="function"?e():e;return new R5(a)}static handleExit({editor:e,mark:a}){const{tr:n}=e.state,i=e.state.selection.$from;if(i.pos===i.end()){const o=i.marks();if(!!!o.find(d=>(d==null?void 0:d.type.name)===a.name))return!1;const c=o.find(d=>(d==null?void 0:d.type.name)===a.name);return c&&n.removeStoredMark(c),n.insertText(" ",i.pos),e.view.dispatch(n),!0}return!1}configure(e){return super.configure(e)}extend(e){const a=typeof e=="function"?e():e;return super.extend(a)}};function Zle(t){return typeof t=="number"}var ece=class{constructor(t){this.find=t.find,this.handler=t.handler}},tce=(t,e,a)=>{if(hS(e))return[...t.matchAll(e)];const n=e(t,a);return n?n.map(i=>{const r=[i.text];return r.index=i.index,r.input=t,r.data=i.data,i.replaceWith&&(i.text.includes(i.replaceWith)||console.warn('[tiptap warn]: "pasteRuleMatch.replaceWith" must be part of "pasteRuleMatch.text".'),r.push(i.replaceWith)),r}):[]};function ace(t){const{editor:e,state:a,from:n,to:i,rule:r,pasteEvent:o,dropEvent:l}=t,{commands:c,chain:d,can:u}=new $g({editor:e,state:a}),p=[];return a.doc.nodesBetween(n,i,(h,g)=>{var y,x,v,w,S;if((x=(y=h.type)==null?void 0:y.spec)!=null&&x.code||!(h.isText||h.isTextblock||h.isInline))return;const T=(S=(w=(v=h.content)==null?void 0:v.size)!=null?w:h.nodeSize)!=null?S:0,P=Math.max(n,g),M=Math.min(i,g+T);if(P>=M)return;const C=h.isText?h.text||"":h.textBetween(P-g,M-g,void 0,"");tce(C,r.find,o).forEach(j=>{if(j.index===void 0)return;const N=P+j.index+1,L=N+j[0].length,O={from:a.tr.mapping.map(N),to:a.tr.mapping.map(L)},R=r.handler({state:a,range:O,match:j,commands:c,chain:d,can:u,pasteEvent:o,dropEvent:l});p.push(R)})}),p.every(h=>h!==null)}var nm=null,nce=t=>{var e;const a=new ClipboardEvent("paste",{clipboardData:new DataTransfer});return(e=a.clipboardData)==null||e.setData("text/html",t),a};function ice(t){const{editor:e,rules:a}=t;let n=null,i=!1,r=!1,o=typeof ClipboardEvent<"u"?new ClipboardEvent("paste"):null,l;try{l=typeof DragEvent<"u"?new DragEvent("drop"):null}catch{l=null}const c=({state:u,from:p,to:m,rule:h,pasteEvt:g})=>{const y=u.tr,x=Ug({state:u,transaction:y});if(!(!ace({editor:e,state:x,from:Math.max(p-1,0),to:m.b-1,rule:h,pasteEvent:g,dropEvent:l})||!y.steps.length)){try{l=typeof DragEvent<"u"?new DragEvent("drop"):null}catch{l=null}return o=typeof ClipboardEvent<"u"?new ClipboardEvent("paste"):null,y}};return a.map(u=>new at({view(p){const m=g=>{var y;n=(y=p.dom.parentElement)!=null&&y.contains(g.target)?p.dom.parentElement:null,n&&(nm=e)},h=()=>{nm&&(nm=null)};return window.addEventListener("dragstart",m),window.addEventListener("dragend",h),{destroy(){window.removeEventListener("dragstart",m),window.removeEventListener("dragend",h)}}},props:{handleDOMEvents:{drop:(p,m)=>{if(r=n===p.dom.parentElement,l=m,!r){const h=nm;h!=null&&h.isEditable&&setTimeout(()=>{const g=h.state.selection;g&&h.commands.deleteRange({from:g.from,to:g.to})},10)}return!1},paste:(p,m)=>{var h;const g=(h=m.clipboardData)==null?void 0:h.getData("text/html");return o=m,i=!!(g!=null&&g.includes("data-pm-slice")),!1}}},appendTransaction:(p,m,h)=>{const g=p[0],y=g.getMeta("uiEvent")==="paste"&&!i,x=g.getMeta("uiEvent")==="drop"&&!r,v=g.getMeta("applyPasteRules"),w=!!v;if(!y&&!x&&!w)return;if(w){let{text:P}=v;typeof P=="string"?P=P:P=yS(V.from(P),h.schema);const{from:M}=v,C=M+P.length,E=nce(P);return c({rule:u,state:h,from:M,to:{b:C},pasteEvt:E})}const S=m.doc.content.findDiffStart(h.doc.content),T=m.doc.content.findDiffEnd(h.doc.content);if(!(!Zle(S)||!T||S===T.b))return c({rule:u,state:h,from:S,to:T,pasteEvt:o})}}))}var Qg=class{constructor(t,e){this.splittableMarks=[],this.editor=e,this.baseExtensions=t,this.extensions=_5(t),this.schema=hle(this.extensions,e),this.setupExtensions()}get commands(){return this.extensions.reduce((t,e)=>{const a={name:e.name,options:e.options,storage:this.editor.extensionStorage[e.name],editor:this.editor,type:Ic(e.name,this.schema)},n=te(e,"addCommands",a);return n?{...t,...n()}:t},{})}get plugins(){const{editor:t}=this;return Sd([...this.extensions].reverse()).flatMap(n=>{const i={name:n.name,options:n.options,storage:this.editor.extensionStorage[n.name],editor:t,type:Ic(n.name,this.schema)},r=[],o=te(n,"addKeyboardShortcuts",i);let l={};if(n.type==="mark"&&te(n,"exitable",i)&&(l.ArrowRight=()=>ao.handleExit({editor:t,mark:n})),o){const m=Object.fromEntries(Object.entries(o()).map(([h,g])=>[h,()=>g({editor:t})]));l={...l,...m}}const c=gse(l);r.push(c);const d=te(n,"addInputRules",i);if(CT(n,t.options.enableInputRules)&&d){const m=d();if(m&&m.length){const h=Xle({editor:t,rules:m}),g=Array.isArray(h)?h:[h];r.push(...g)}}const u=te(n,"addPasteRules",i);if(CT(n,t.options.enablePasteRules)&&u){const m=u();if(m&&m.length){const h=ice({editor:t,rules:m});r.push(...h)}}const p=te(n,"addProseMirrorPlugins",i);if(p){const m=p();r.push(...m)}return r})}get attributes(){return S5(this.extensions)}get nodeViews(){const{editor:t}=this,{nodeExtensions:e}=Ol(this.extensions);return Object.fromEntries(e.filter(a=>!!te(a,"addNodeView")).map(a=>{const n=this.attributes.filter(c=>c.type===a.name),i={name:a.name,options:a.options,storage:this.editor.extensionStorage[a.name],editor:t,type:vt(a.name,this.schema)},r=te(a,"addNodeView",i);if(!r)return[];const o=r();if(!o)return[];const l=(c,d,u,p,m)=>{const h=xu(c,n);return o({node:c,view:d,getPos:u,decorations:p,innerDecorations:m,editor:t,extension:a,HTMLAttributes:h})};return[a.name,l]}))}dispatchTransaction(t){const{editor:e}=this;return Sd([...this.extensions].reverse()).reduceRight((n,i)=>{const r={name:i.name,options:i.options,storage:this.editor.extensionStorage[i.name],editor:e,type:Ic(i.name,this.schema)},o=te(i,"dispatchTransaction",r);return o?l=>{o.call(r,{transaction:l,next:n})}:n},t)}transformPastedHTML(t){const{editor:e}=this;return Sd([...this.extensions]).reduce((n,i)=>{const r={name:i.name,options:i.options,storage:this.editor.extensionStorage[i.name],editor:e,type:Ic(i.name,this.schema)},o=te(i,"transformPastedHTML",r);return o?(l,c)=>{const d=n(l,c);return o.call(r,d)}:n},t||(n=>n))}get markViews(){const{editor:t}=this,{markExtensions:e}=Ol(this.extensions);return Object.fromEntries(e.filter(a=>!!te(a,"addMarkView")).map(a=>{const n=this.attributes.filter(l=>l.type===a.name),i={name:a.name,options:a.options,storage:this.editor.extensionStorage[a.name],editor:t,type:$i(a.name,this.schema)},r=te(a,"addMarkView",i);if(!r)return[];const o=(l,c,d)=>{const u=xu(l,n);return r()({mark:l,view:c,inline:d,editor:t,extension:a,HTMLAttributes:u,updateAttributes:p=>{vce(l,t,p)}})};return[a.name,o]}))}setupExtensions(){const t=this.extensions;this.editor.extensionStorage=Object.fromEntries(t.map(e=>[e.name,e.storage])),t.forEach(e=>{var a;const n={name:e.name,options:e.options,storage:this.editor.extensionStorage[e.name],editor:this.editor,type:Ic(e.name,this.schema)};e.type==="mark"&&((a=Pe(te(e,"keepOnSplit",n)))==null||a)&&this.splittableMarks.push(e.name);const i=te(e,"onBeforeCreate",n),r=te(e,"onCreate",n),o=te(e,"onUpdate",n),l=te(e,"onSelectionUpdate",n),c=te(e,"onTransaction",n),d=te(e,"onFocus",n),u=te(e,"onBlur",n),p=te(e,"onDestroy",n);i&&this.editor.on("beforeCreate",i),r&&this.editor.on("create",r),o&&this.editor.on("update",o),l&&this.editor.on("selectionUpdate",l),c&&this.editor.on("transaction",c),d&&this.editor.on("focus",d),u&&this.editor.on("blur",u),p&&this.editor.on("destroy",p)})}};Qg.resolve=_5;Qg.sort=Sd;Qg.flatten=gS;var rce={};mS(rce,{ClipboardTextSerializer:()=>O5,Commands:()=>M5,Delete:()=>D5,Drop:()=>q5,Editable:()=>z5,FocusEvents:()=>H5,Keymap:()=>F5,Paste:()=>B5,Tabindex:()=>U5,TextDirection:()=>$5,focusEventsPluginKey:()=>V5});var ze=class L5 extends vS{constructor(){super(...arguments),this.type="extension"}static create(e={}){const a=typeof e=="function"?e():e;return new L5(a)}configure(e){return super.configure(e)}extend(e){const a=typeof e=="function"?e():e;return super.extend(a)}},O5=ze.create({name:"clipboardTextSerializer",addOptions(){return{blockSeparator:void 0}},addProseMirrorPlugins(){return[new at({key:new _t("clipboardTextSerializer"),props:{clipboardTextSerializer:()=>{const{editor:t}=this,{state:e,schema:a}=t,{doc:n,selection:i}=e,{ranges:r}=i,o=Math.min(...r.map(u=>u.$from.pos)),l=Math.max(...r.map(u=>u.$to.pos)),c=E5(a);return A5(n,{from:o,to:l},{...this.options.blockSeparator!==void 0?{blockSeparator:this.options.blockSeparator}:{},textSerializers:c})}}})]}}),M5=ze.create({name:"commands",addCommands(){return{...h5}}}),D5=ze.create({name:"delete",onUpdate({transaction:t,appendedTransactions:e}){var a,n,i;const r=()=>{var o,l,c,d;if((d=(c=(l=(o=this.editor.options.coreExtensionOptions)==null?void 0:o.delete)==null?void 0:l.filterTransaction)==null?void 0:c.call(l,t))!=null?d:t.getMeta("y-sync$"))return;const u=w5(t.before,[t,...e]);j5(u).forEach(h=>{u.mapping.mapResult(h.oldRange.from).deletedAfter&&u.mapping.mapResult(h.oldRange.to).deletedBefore&&u.before.nodesBetween(h.oldRange.from,h.oldRange.to,(g,y)=>{const x=y+g.nodeSize-2,v=h.oldRange.from<=y&&x<=h.oldRange.to;this.editor.emit("delete",{type:"node",node:g,from:y,to:x,newFrom:u.mapping.map(y),newTo:u.mapping.map(x),deletedRange:h.oldRange,newRange:h.newRange,partial:!v,editor:this.editor,transaction:t,combinedTransform:u})})});const m=u.mapping;u.steps.forEach((h,g)=>{var y,x;if(h instanceof jn){const v=m.slice(g).map(h.from,-1),w=m.slice(g).map(h.to),S=m.invert().map(v,-1),T=m.invert().map(w),P=v>0?(y=u.doc.nodeAt(v-1))==null?void 0:y.marks.some(C=>C.eq(h.mark)):!1,M=(x=u.doc.nodeAt(w))==null?void 0:x.marks.some(C=>C.eq(h.mark));this.editor.emit("delete",{type:"mark",mark:h.mark,from:h.from,to:h.to,deletedRange:{from:S,to:T},newRange:{from:v,to:w},partial:!!(M||P),editor:this.editor,transaction:t,combinedTransform:u})}})};(i=(n=(a=this.editor.options.coreExtensionOptions)==null?void 0:a.delete)==null?void 0:n.async)==null||i?setTimeout(r,0):r()}}),q5=ze.create({name:"drop",addProseMirrorPlugins(){return[new at({key:new _t("tiptapDrop"),props:{handleDrop:(t,e,a,n)=>{this.editor.emit("drop",{editor:this.editor,event:e,slice:a,moved:n})}}})]}}),z5=ze.create({name:"editable",addProseMirrorPlugins(){return[new at({key:new _t("editable"),props:{editable:()=>this.editor.options.editable}})]}}),V5=new _t("focusEvents"),H5=ze.create({name:"focusEvents",addProseMirrorPlugins(){const{editor:t}=this;return[new at({key:V5,props:{handleDOMEvents:{focus:(e,a)=>{t.isFocused=!0;const n=t.state.tr.setMeta("focus",{event:a}).setMeta("addToHistory",!1);return e.dispatch(n),!1},blur:(e,a)=>{t.isFocused=!1;const n=t.state.tr.setMeta("blur",{event:a}).setMeta("addToHistory",!1);return e.dispatch(n),!1}}}})]}}),F5=ze.create({name:"keymap",addKeyboardShortcuts(){const t=()=>this.editor.commands.first(({commands:o})=>[()=>o.undoInputRule(),()=>o.command(({tr:l})=>{const{selection:c,doc:d}=l,{empty:u,$anchor:p}=c,{pos:m,parent:h}=p,g=p.parent.isTextblock&&m>0?l.doc.resolve(m-1):p,y=g.parent.type.spec.isolating,x=p.pos-p.parentOffset,v=y&&g.parent.childCount===1?x===p.pos:xe.atStart(d).from===m;return!u||!h.type.isTextblock||h.textContent.length||!v||v&&p.parent.type.name==="paragraph"?!1:o.clearNodes()}),()=>o.deleteSelection(),()=>o.joinBackward(),()=>o.selectNodeBackward()]),e=()=>this.editor.commands.first(({commands:o})=>[()=>o.deleteSelection(),()=>o.deleteCurrentNode(),()=>o.joinForward(),()=>o.selectNodeForward()]),n={Enter:()=>this.editor.commands.first(({commands:o})=>[()=>o.newlineInCode(),()=>o.createParagraphNear(),()=>o.liftEmptyBlock(),()=>o.splitBlock()]),"Mod-Enter":()=>this.editor.commands.exitCode(),Backspace:t,"Mod-Backspace":t,"Shift-Backspace":t,Delete:e,"Mod-Delete":e,"Mod-a":()=>this.editor.commands.selectAll()},i={...n},r={...n,"Ctrl-h":t,"Alt-Backspace":t,"Ctrl-d":e,"Ctrl-Alt-Backspace":e,"Alt-Delete":e,"Alt-d":e,"Ctrl-a":()=>this.editor.commands.selectTextblockStart(),"Ctrl-e":()=>this.editor.commands.selectTextblockEnd()};return sf()||v5()?r:i},addProseMirrorPlugins(){return[new at({key:new _t("clearDocument"),appendTransaction:(t,e,a)=>{if(t.some(y=>y.getMeta("composition")))return;const n=t.some(y=>y.docChanged)&&!e.doc.eq(a.doc),i=t.some(y=>y.getMeta("preventClearDocument"));if(!n||i)return;const{empty:r,from:o,to:l}=e.selection,c=xe.atStart(e.doc).from,d=xe.atEnd(e.doc).to;if(r||!(o===c&&l===d)||!Kg(a.doc))return;const m=a.tr,h=Ug({state:a,transaction:m}),{commands:g}=new $g({editor:this.editor,state:h});if(g.clearNodes(),!!m.steps.length)return m}})]}}),B5=ze.create({name:"paste",addProseMirrorPlugins(){return[new at({key:new _t("tiptapPaste"),props:{handlePaste:(t,e,a)=>{this.editor.emit("paste",{editor:this.editor,event:e,slice:a})}}})]}}),U5=ze.create({name:"tabindex",addProseMirrorPlugins(){return[new at({key:new _t("tabindex"),props:{attributes:()=>this.editor.isEditable?{tabindex:"0"}:{}}})]}}),$5=ze.create({name:"textDirection",addOptions(){return{direction:void 0}},addGlobalAttributes(){if(!this.options.direction)return[];const{nodeExtensions:t}=Ol(this.extensions);return[{types:t.filter(e=>e.name!=="text").map(e=>e.name),attributes:{dir:{default:this.options.direction,parseHTML:e=>{const a=e.getAttribute("dir");return a&&(a==="ltr"||a==="rtl"||a==="auto")?a:this.options.direction},renderHTML:e=>e.dir?{dir:e.dir}:{}}}}]},addProseMirrorPlugins(){return[new at({key:new _t("textDirection"),props:{attributes:()=>{const t=this.options.direction;return t?{dir:t}:{}}}})]}}),oce=class Gc{constructor(e,a,n=!1,i=null){this.currentNode=null,this.actualDepth=null,this.isBlock=n,this.resolvedPos=e,this.editor=a,this.currentNode=i}get name(){return this.node.type.name}get node(){return this.currentNode||this.resolvedPos.node()}get element(){return this.editor.view.domAtPos(this.pos).node}get depth(){var e;return(e=this.actualDepth)!=null?e:this.resolvedPos.depth}get pos(){return this.resolvedPos.pos}get content(){return this.node.content}set content(e){let a=this.from,n=this.to;if(this.isBlock){if(this.content.size===0){console.error(`You can’t set content on a block node. Tried to set content on ${this.name} at ${this.pos}`);return}a=this.from+1,n=this.to-1}this.editor.commands.insertContentAt({from:a,to:n},e)}get attributes(){return this.node.attrs}get textContent(){return this.node.textContent}get size(){return this.node.nodeSize}get from(){return this.isBlock?this.pos:this.resolvedPos.start(this.resolvedPos.depth)}get range(){return{from:this.from,to:this.to}}get to(){return this.isBlock?this.pos+this.size:this.resolvedPos.end(this.resolvedPos.depth)+(this.node.isText?0:1)}get parent(){if(this.depth===0)return null;const e=this.resolvedPos.start(this.resolvedPos.depth-1),a=this.resolvedPos.doc.resolve(e);return new Gc(a,this.editor)}get before(){let e=this.resolvedPos.doc.resolve(this.from-(this.isBlock?1:2));return e.depth!==this.depth&&(e=this.resolvedPos.doc.resolve(this.from-3)),new Gc(e,this.editor)}get after(){let e=this.resolvedPos.doc.resolve(this.to+(this.isBlock?2:1));return e.depth!==this.depth&&(e=this.resolvedPos.doc.resolve(this.to+3)),new Gc(e,this.editor)}get children(){const e=[];return this.node.content.forEach((a,n)=>{const i=a.isBlock&&!a.isTextblock,r=a.isAtom&&!a.isText,o=a.isInline,l=this.pos+n+(r?0:1);if(l<0||l>this.resolvedPos.doc.nodeSize-2)return;const c=this.resolvedPos.doc.resolve(l);if(!i&&!o&&c.depth<=this.depth)return;const d=new Gc(c,this.editor,i,i||o?a:null);i&&(d.actualDepth=this.depth+1),e.push(d)}),e}get firstChild(){return this.children[0]||null}get lastChild(){const e=this.children;return e[e.length-1]||null}closest(e,a={}){let n=null,i=this.parent;for(;i&&!n;){if(i.node.type.name===e)if(Object.keys(a).length>0){const r=i.node.attrs,o=Object.keys(a);for(let l=0;l<o.length;l+=1){const c=o[l];if(r[c]!==a[c])break}}else n=i;i=i.parent}return n}querySelector(e,a={}){return this.querySelectorAll(e,a,!0)[0]||null}querySelectorAll(e,a={},n=!1){let i=[];if(!this.children||this.children.length===0)return i;const r=Object.keys(a);return this.children.forEach(o=>{n&&i.length>0||(o.node.type.name===e&&r.every(c=>a[c]===o.node.attrs[c])&&i.push(o),!(n&&i.length>0)&&(i=i.concat(o.querySelectorAll(e,a,n))))}),i}setAttribute(e){const{tr:a}=this.editor.state;a.setNodeMarkup(this.from,void 0,{...this.node.attrs,...e}),this.editor.view.dispatch(a)}},sce=`.ProseMirror {
17643  position: relative;
17644}
17645
17646.ProseMirror {
17647  word-wrap: break-word;
17648  white-space: pre-wrap;
17649  white-space: break-spaces;
17650  -webkit-font-variant-ligatures: none;
17651  font-variant-ligatures: none;
17652  font-feature-settings: "liga" 0; /* the above doesn't seem to work in Edge */
17653}
17654
17655.ProseMirror [contenteditable="false"] {
17656  white-space: normal;
17657}
17658
17659.ProseMirror [contenteditable="false"] [contenteditable="true"] {
17660  white-space: pre-wrap;
17661}
17662
17663.ProseMirror pre {
17664  white-space: pre-wrap;
17665}
17666
17667img.ProseMirror-separator {
17668  display: inline !important;
17669  border: none !important;
17670  margin: 0 !important;
17671  width: 0 !important;
17672  height: 0 !important;
17673}
17674
17675.ProseMirror-gapcursor {
17676  display: none;
17677  pointer-events: none;
17678  position: absolute;
17679  margin: 0;
17680}
17681
17682.ProseMirror-gapcursor:after {
17683  content: "";
17684  display: block;
17685  position: absolute;
17686  top: -2px;
17687  width: 20px;
17688  border-top: 1px solid black;
17689  animation: ProseMirror-cursor-blink 1.1s steps(2, start) infinite;
17690}
17691
17692@keyframes ProseMirror-cursor-blink {
17693  to {
17694    visibility: hidden;
17695  }
17696}
17697
17698.ProseMirror-hideselection *::selection {
17699  background: transparent;
17700}
17701
17702.ProseMirror-hideselection *::-moz-selection {
17703  background: transparent;
17704}
17705
17706.ProseMirror-hideselection * {
17707  caret-color: transparent;
17708}
17709
17710.ProseMirror-focused .ProseMirror-gapcursor {
17711  display: block;
17712}`;function lce(t,e,a){const n=document.querySelector("style[data-tiptap-style]");if(n!==null)return n;const i=document.createElement("style");return e&&i.setAttribute("nonce",e),i.setAttribute("data-tiptap-style",""),i.innerHTML=t,document.getElementsByTagName("head")[0].appendChild(i),i}var cce=class extends Jle{constructor(t={}){super(),this.css=null,this.className="tiptap",this.editorView=null,this.isFocused=!1,this.isInitialized=!1,this.extensionStorage={},this.instanceId=Math.random().toString(36).slice(2,9),this.options={element:typeof document<"u"?document.createElement("div"):null,content:"",injectCSS:!0,injectNonce:void 0,extensions:[],autofocus:!1,editable:!0,textDirection:void 0,editorProps:{},parseOptions:{},coreExtensionOptions:{},enableInputRules:!0,enablePasteRules:!0,enableCoreExtensions:!0,enableContentCheck:!1,emitContentError:!1,onBeforeCreate:()=>null,onCreate:()=>null,onMount:()=>null,onUnmount:()=>null,onUpdate:()=>null,onSelectionUpdate:()=>null,onTransaction:()=>null,onFocus:()=>null,onBlur:()=>null,onDestroy:()=>null,onContentError:({error:n})=>{throw n},onPaste:()=>null,onDrop:()=>null,onDelete:()=>null,enableExtensionDispatchTransaction:!0},this.isCapturingTransaction=!1,this.capturedTransaction=null,this.utils={getUpdatedPosition:Ale,createMappablePosition:Ele},this.setOptions(t),this.createExtensionManager(),this.createCommandManager(),this.createSchema(),this.on("beforeCreate",this.options.onBeforeCreate),this.emit("beforeCreate",{editor:this}),this.on("mount",this.options.onMount),this.on("unmount",this.options.onUnmount),this.on("contentError",this.options.onContentError),this.on("create",this.options.onCreate),this.on("update",this.options.onUpdate),this.on("selectionUpdate",this.options.onSelectionUpdate),this.on("transaction",this.options.onTransaction),this.on("focus",this.options.onFocus),this.on("blur",this.options.onBlur),this.on("destroy",this.options.onDestroy),this.on("drop",({event:n,slice:i,moved:r})=>this.options.onDrop(n,i,r)),this.on("paste",({event:n,slice:i})=>this.options.onPaste(n,i)),this.on("delete",this.options.onDelete);const e=this.createDoc(),a=y5(e,this.options.autofocus);this.editorState=Qs.create({doc:e,schema:this.schema,selection:a||void 0}),this.options.element&&this.mount(this.options.element)}mount(t){if(typeof document>"u")throw new Error("[tiptap error]: The editor cannot be mounted because there is no 'document' defined in this environment.");this.createView(t),this.emit("mount",{editor:this}),this.css&&!document.head.contains(this.css)&&document.head.appendChild(this.css),window.setTimeout(()=>{this.isDestroyed||(this.options.autofocus!==!1&&this.options.autofocus!==null&&this.commands.focus(this.options.autofocus),this.emit("create",{editor:this}),this.isInitialized=!0)},0)}unmount(){if(this.editorView){const t=this.editorView.dom;t!=null&&t.editor&&delete t.editor,this.editorView.destroy()}if(this.editorView=null,this.isInitialized=!1,this.css&&!document.querySelectorAll(`.${this.className}`).length)try{typeof this.css.remove=="function"?this.css.remove():this.css.parentNode&&this.css.parentNode.removeChild(this.css)}catch(t){console.warn("Failed to remove CSS element:",t)}this.css=null,this.emit("unmount",{editor:this})}get storage(){return this.extensionStorage}get commands(){return this.commandManager.commands}chain(){return this.commandManager.chain()}can(){return this.commandManager.can()}injectCSS(){this.options.injectCSS&&typeof document<"u"&&(this.css=lce(sce,this.options.injectNonce))}setOptions(t={}){this.options={...this.options,...t},!(!this.editorView||!this.state||this.isDestroyed)&&(this.options.editorProps&&this.view.setProps(this.options.editorProps),this.view.updateState(this.state))}setEditable(t,e=!0){this.setOptions({editable:t}),e&&this.emit("update",{editor:this,transaction:this.state.tr,appendedTransactions:[]})}get isEditable(){return this.options.editable&&this.view&&this.view.editable}get view(){return this.editorView?this.editorView:new Proxy({state:this.editorState,updateState:t=>{this.editorState=t},dispatch:t=>{this.dispatchTransaction(t)},composing:!1,dragging:null,editable:!0,isDestroyed:!1},{get:(t,e)=>{if(this.editorView)return this.editorView[e];if(e==="state")return this.editorState;if(e in t)return Reflect.get(t,e);throw new Error(`[tiptap error]: The editor view is not available. Cannot access view['${e}']. The editor may not be mounted yet.`)}})}get state(){return this.editorView&&(this.editorState=this.view.state),this.editorState}registerPlugin(t,e){const a=k5(e)?e(t,[...this.state.plugins]):[...this.state.plugins,t],n=this.state.reconfigure({plugins:a});return this.view.updateState(n),n}unregisterPlugin(t){if(this.isDestroyed)return;const e=this.state.plugins;let a=e;if([].concat(t).forEach(i=>{const r=typeof i=="string"?`${i}$`:i.key;a=a.filter(o=>!o.key.startsWith(r))}),e.length===a.length)return;const n=this.state.reconfigure({plugins:a});return this.view.updateState(n),n}createExtensionManager(){var t,e;const n=[...this.options.enableCoreExtensions?[z5,O5.configure({blockSeparator:(e=(t=this.options.coreExtensionOptions)==null?void 0:t.clipboardTextSerializer)==null?void 0:e.blockSeparator}),M5,H5,F5,U5,q5,B5,D5,$5.configure({direction:this.options.textDirection})].filter(i=>typeof this.options.enableCoreExtensions=="object"?this.options.enableCoreExtensions[i.name]!==!1:!0):[],...this.options.extensions].filter(i=>["extension","node","mark"].includes(i==null?void 0:i.type));this.extensionManager=new Qg(n,this)}createCommandManager(){this.commandManager=new $g({editor:this})}createSchema(){this.schema=this.extensionManager.schema}createDoc(){let t;try{t=qb(this.options.content,this.schema,this.options.parseOptions,{errorOnInvalidContent:this.options.enableContentCheck})}catch(e){if(!(e instanceof Error)||!["[tiptap error]: Invalid JSON content","[tiptap error]: Invalid HTML content"].includes(e.message))throw e;this.emit("contentError",{editor:this,error:e,disableCollaboration:()=>{"collaboration"in this.storage&&typeof this.storage.collaboration=="object"&&this.storage.collaboration&&(this.storage.collaboration.isDisabled=!0),this.options.extensions=this.options.extensions.filter(a=>a.name!=="collaboration"),this.createExtensionManager()}}),t=qb(this.options.content,this.schema,this.options.parseOptions,{errorOnInvalidContent:!1})}return t}createView(t){const{editorProps:e,enableExtensionDispatchTransaction:a}=this.options,n=e.dispatchTransaction||this.dispatchTransaction.bind(this),i=a?this.extensionManager.dispatchTransaction(n):n,r=e.transformPastedHTML,o=this.extensionManager.transformPastedHTML(r);this.editorView=new p5(t,{...e,attributes:{role:"textbox",...e==null?void 0:e.attributes},dispatchTransaction:i,transformPastedHTML:o,state:this.editorState,markViews:this.extensionManager.markViews,nodeViews:this.extensionManager.nodeViews});const l=this.state.reconfigure({plugins:this.extensionManager.plugins});this.view.updateState(l),this.prependClass(),this.injectCSS();const c=this.view.dom;c.editor=this}createNodeViews(){this.view.isDestroyed||this.view.setProps({markViews:this.extensionManager.markViews,nodeViews:this.extensionManager.nodeViews})}prependClass(){this.view.dom.className=`${this.className} ${this.view.dom.className}`}captureTransaction(t){this.isCapturingTransaction=!0,t(),this.isCapturingTransaction=!1;const e=this.capturedTransaction;return this.capturedTransaction=null,e}dispatchTransaction(t){if(this.view.isDestroyed)return;if(this.isCapturingTransaction){if(!this.capturedTransaction){this.capturedTransaction=t;return}t.steps.forEach(d=>{var u;return(u=this.capturedTransaction)==null?void 0:u.step(d)});return}const{state:e,transactions:a}=this.state.applyTransaction(t),n=!this.state.selection.eq(e.selection),i=a.includes(t),r=this.state;if(this.emit("beforeTransaction",{editor:this,transaction:t,nextState:e}),!i)return;this.view.updateState(e),this.emit("transaction",{editor:this,transaction:t,appendedTransactions:a.slice(1)}),n&&this.emit("selectionUpdate",{editor:this,transaction:t});const o=a.findLast(d=>d.getMeta("focus")||d.getMeta("blur")),l=o==null?void 0:o.getMeta("focus"),c=o==null?void 0:o.getMeta("blur");l&&this.emit("focus",{editor:this,event:l.event,transaction:o}),c&&this.emit("blur",{editor:this,event:c.event,transaction:o}),!(t.getMeta("preventUpdate")||!a.some(d=>d.docChanged)||r.doc.eq(e.doc))&&this.emit("update",{editor:this,transaction:t,appendedTransactions:a.slice(1)})}getAttributes(t){return C5(this.state,t)}isActive(t,e){const a=typeof t=="string"?t:null,n=typeof t=="string"?e:t;return kle(this.state,a,n)}getJSON(){return this.state.doc.toJSON()}getHTML(){return yS(this.state.doc.content,this.schema)}getText(t){const{blockSeparator:e=`
17713
17714`,textSerializers:a={}}=t||{};return gle(this.state.doc,{blockSeparator:e,textSerializers:{...E5(this.schema),...a}})}get isEmpty(){return Kg(this.state.doc)}destroy(){this.emit("destroy"),this.unmount(),this.removeAllListeners()}get isDestroyed(){var t,e;return(e=(t=this.editorView)==null?void 0:t.isDestroyed)!=null?e:!0}$node(t,e){var a;return((a=this.$doc)==null?void 0:a.querySelector(t,e))||null}$nodes(t,e){var a;return((a=this.$doc)==null?void 0:a.querySelectorAll(t,e))||null}$pos(t){const e=this.state.doc.resolve(t);return new oce(e,this)}get $doc(){return this.$pos(0)}};function Ml(t){return new Jg({find:t.find,handler:({state:e,range:a,match:n})=>{const i=Pe(t.getAttributes,void 0,n);if(i===!1||i===null)return null;const{tr:r}=e,o=n[n.length-1],l=n[0];if(o){const c=l.search(/\S/),d=a.from+l.indexOf(o),u=d+o.length;if(xS(a.from,a.to,e.doc).filter(h=>h.mark.type.excluded.find(y=>y===t.type&&y!==h.mark.type)).filter(h=>h.to>d).length)return null;u<a.to&&r.delete(u,a.to),d>a.from&&r.delete(a.from+c,d);const m=a.from+c+o.length;r.addMark(a.from+c,m,t.type.create(i||{})),r.removeStoredMark(t.type)}},undoable:t.undoable})}function W5(t){return new Jg({find:t.find,handler:({state:e,range:a,match:n})=>{const i=Pe(t.getAttributes,void 0,n)||{},{tr:r}=e,o=a.from;let l=a.to;const c=t.type.create(i);if(n[1]){const d=n[0].lastIndexOf(n[1]);let u=o+d;u>l?u=l:l=u+n[1].length;const p=n[0][n[0].length-1];r.insertText(p,o+n[0].length-1),r.replaceWith(u,l,c)}else if(n[0]){const d=t.type.isInline?o:o-1;r.insert(d,t.type.create(i)).delete(r.mapping.map(o),r.mapping.map(l))}r.scrollIntoView()},undoable:t.undoable})}function Vb(t){return new Jg({find:t.find,handler:({state:e,range:a,match:n})=>{const i=e.doc.resolve(a.from),r=Pe(t.getAttributes,void 0,n)||{};if(!i.node(-1).canReplaceWith(i.index(-1),i.indexAfter(-1),t.type))return null;e.tr.delete(a.from,a.to).setBlockType(a.from,a.from,t.type,r)},undoable:t.undoable})}function Dl(t){return new Jg({find:t.find,handler:({state:e,range:a,match:n,chain:i})=>{const r=Pe(t.getAttributes,void 0,n)||{},o=e.tr.delete(a.from,a.to),c=o.doc.resolve(a.from).blockRange(),d=c&&Xk(c,t.type,r);if(!d)return null;if(o.wrap(c,d),t.keepMarks&&t.editor){const{selection:p,storedMarks:m}=e,{splittableMarks:h}=t.editor.extensionManager,g=m||p.$to.parentOffset&&p.$from.marks();if(g){const y=g.filter(x=>h.includes(x.type.name));o.ensureMarks(y)}}if(t.keepAttributes){const p=t.type.name==="bulletList"||t.type.name==="orderedList"?"listItem":"taskList";i().updateAttributes(p,r).run()}const u=o.doc.resolve(a.from-1).nodeBefore;u&&u.type===t.type&&eo(o.doc,a.from-1)&&(!t.joinPredicate||t.joinPredicate(n,u))&&o.join(a.from-1)},undoable:t.undoable})}var dce=t=>"touches"in t,uce=class{constructor(t){this.directions=["bottom-left","bottom-right","top-left","top-right"],this.minSize={height:8,width:8},this.preserveAspectRatio=!1,this.classNames={container:"",wrapper:"",handle:"",resizing:""},this.initialWidth=0,this.initialHeight=0,this.aspectRatio=1,this.isResizing=!1,this.activeHandle=null,this.startX=0,this.startY=0,this.startWidth=0,this.startHeight=0,this.isShiftKeyPressed=!1,this.lastEditableState=void 0,this.handleMap=new Map,this.handleMouseMove=l=>{if(!this.isResizing||!this.activeHandle)return;const c=l.clientX-this.startX,d=l.clientY-this.startY;this.handleResize(c,d)},this.handleTouchMove=l=>{if(!this.isResizing||!this.activeHandle)return;const c=l.touches[0];if(!c)return;const d=c.clientX-this.startX,u=c.clientY-this.startY;this.handleResize(d,u)},this.handleMouseUp=()=>
17714{if(!this.isResizing)return;const l=this.element.offsetWidth,c=this.element.offsetHeight;this.onCommit(l,c),this.isResizing=!1,this.activeHandle=null,this.container.dataset.resizeState="false",this.classNames.resizing&&this.container.classList.remove(this.classNames.resizing),document.removeEventListener("mousemove",this.handleMouseMove),document.removeEventListener("mouseup",this.handleMouseUp),document.removeEventListener("keydown",this.handleKeyDown),document.removeEventListener("keyup",this.handleKeyUp)},this.handleKeyDown=l=>{l.key==="Shift"&&(this.isShiftKeyPressed=!0)},this.handleKeyUp=l=>{l.key==="Shift"&&(this.isShiftKeyPressed=!1)};var e,a,n,i,r,o;this.node=t.node,this.editor=t.editor,this.element=t.element,this.contentElement=t.contentElement,this.getPos=t.getPos,this.onResize=t.onResize,this.onCommit=t.onCommit,this.onUpdate=t.onUpdate,(e=t.options)!=null&&e.min&&(this.minSize={...this.minSize,...t.options.min}),(a=t.options)!=null&&a.max&&(this.maxSize=t.options.max),(n=t==null?void 0:t.options)!=null&&n.directions&&(this.directions=t.options.directions),(i=t.options)!=null&&i.preserveAspectRatio&&(this.preserveAspectRatio=t.options.preserveAspectRatio),(r=t.options)!=null&&r.className&&(this.classNames={container:t.options.className.container||"",wrapper:t.options.className.wrapper||"",handle:t.options.className.handle||"",resizing:t.options.className.resizing||""}),(o=t.options)!=null&&o.createCustomHandle&&(this.createCustomHandle=t.options.createCustomHandle),this.wrapper=this.createWrapper(),this.container=this.createContainer(),this.applyInitialSize(),this.attachHandles(),this.editor.on("update",this.handleEditorUpdate.bind(this))}get dom(){return this.container}get contentDOM(){var t;return(t=this.contentElement)!=null?t:null}handleEditorUpdate(){const t=this.editor.isEditable;t!==this.lastEditableState&&(this.lastEditableState=t,t?t&&this.handleMap.size===0&&this.attachHandles():this.removeHandles())}update(t,e,a){return t.type!==this.node.type?!1:(this.node=t,this.onUpdate?this.onUpdate(t,e,a):!0)}destroy(){this.isResizing&&(this.container.dataset.resizeState="false",this.classNames.resizing&&this.container.classList.remove(this.classNames.resizing),document.removeEventListener("mousemove",this.handleMouseMove),document.removeEventListener("mouseup",this.handleMouseUp),document.removeEventListener("keydown",this.handleKeyDown),document.removeEventListener("keyup",this.handleKeyUp),this.isResizing=!1,this.activeHandle=null),this.editor.off("update",this.handleEditorUpdate.bind(this)),this.container.remove()}createContainer(){const t=document.createElement("div");return t.dataset.resizeContainer="",t.dataset.node=this.node.type.name,t.style.display=this.node.type.isInline?"inline-flex":"flex",this.classNames.container&&(t.className=this.classNames.container),t.appendChild(this.wrapper),t}createWrapper(){const t=document.createElement("div");return t.style.position="relative",t.style.display="block",t.dataset.resizeWrapper="",this.classNames.wrapper&&(t.className=this.classNames.wrapper),t.appendChild(this.element),t}createHandle(t){const e=document.createElement("div");return e.dataset.resizeHandle=t,e.style.position="absolute",this.classNames.handle&&(e.className=this.classNames.handle),e}positionHandle(t,e){const a=e.includes("top"),n=e.includes("bottom"),i=e.includes("left"),r=e.includes("right");a&&(t.style.top="0"),n&&(t.style.bottom="0"),i&&(t.style.left="0"),r&&(t.style.right="0"),(e==="top"||e==="bottom")&&(t.style.left="0",t.style.right="0"),(e==="left"||e==="right")&&(t.style.top="0",t.style.bottom="0")}attachHandles(){this.directions.forEach(t=>{let e;this.createCustomHandle?e=this.createCustomHandle(t):e=this.createHandle(t),e instanceof HTMLElement||(console.warn(`[ResizableNodeView] createCustomHandle("${t}") did not return an HTMLElement. Falling back to default handle.`),e=this.createHandle(t)),this.createCustomHandle||this.positionHandle(e,t),e.addEventListener("mousedown",a=>this.handleResizeStart(a,t)),e.addEventListener("touchstart",a=>this.handleResizeStart(a,t)),this.handleMap.set(t,e),this.wrapper.appendChild(e)})}
17714removeHandles(){this.handleMap.forEach(t=>t.remove()),this.handleMap.clear()}applyInitialSize(){const t=this.node.attrs.width,e=this.node.attrs.height;t?(this.element.style.width=`${t}px`,this.initialWidth=t):this.initialWidth=this.element.offsetWidth,e?(this.element.style.height=`${e}px`,this.initialHeight=e):this.initialHeight=this.element.offsetHeight,this.initialWidth>0&&this.initialHeight>0&&(this.aspectRatio=this.initialWidth/this.initialHeight)}handleResizeStart(t,e){t.preventDefault(),t.stopPropagation(),this.isResizing=!0,this.activeHandle=e,dce(t)?(this.startX=t.touches[0].clientX,this.startY=t.touches[0].clientY):(this.startX=t.clientX,this.startY=t.clientY),this.startWidth=this.element.offsetWidth,this.startHeight=this.element.offsetHeight,this.startWidth>0&&this.startHeight>0&&(this.aspectRatio=this.startWidth/this.startHeight),this.getPos(),this.container.dataset.resizeState="true",this.classNames.resizing&&this.container.classList.add(this.classNames.resizing),document.addEventListener("mousemove",this.handleMouseMove),document.addEventListener("touchmove",this.handleTouchMove),document.addEventListener("mouseup",this.handleMouseUp),document.addEventListener("keydown",this.handleKeyDown),document.addEventListener("keyup",this.handleKeyUp)}handleResize(t,e){if(!this.activeHandle)return;const a=this.preserveAspectRatio||this.isShiftKeyPressed,{width:n,height:i}=this.calculateNewDimensions(this.activeHandle,t,e),r=this.applyConstraints(n,i,a);this.element.style.width=`${r.width}px`,this.element.style.height=`${r.height}px`,this.onResize&&this.onResize(r.width,r.height)}calculateNewDimensions(t,e,a){let n=this.startWidth,i=this.startHeight;const r=t.includes("right"),o=t.includes("left"),l=t.includes("bottom"),c=t.includes("top");return r?n=this.startWidth+e:o&&(n=this.startWidth-e),l?i=this.startHeight+a:c&&(i=this.startHeight-a),(t==="right"||t==="left")&&(n=this.startWidth+(r?e:-e)),(t==="top"||t==="bottom")&&(i=this.startHeight+(l?a:-a)),this.preserveAspectRatio||this.isShiftKeyPressed?this.applyAspectRatio(n,i,t):{width:n,height:i}}applyConstraints(t,e,a){var n,i,r,o;if(!a){let d=Math.max(this.minSize.width,t),u=Math.max(this.minSize.height,e);return(n=this.maxSize)!=null&&n.width&&(d=Math.min(this.maxSize.width,d)),(i=this.maxSize)!=null&&i.height&&(u=Math.min(this.maxSize.height,u)),{width:d,height:u}}let l=t,c=e;return l<this.minSize.width&&(l=this.minSize.width,c=l/this.aspectRatio),c<this.minSize.height&&(c=this.minSize.height,l=c*this.aspectRatio),(r=this.maxSize)!=null&&r.width&&l>this.maxSize.width&&(l=this.maxSize.width,c=l/this.aspectRatio),(o=this.maxSize)!=null&&o.height&&c>this.maxSize.height&&(c=this.maxSize.height,l=c*this.aspectRatio),{width:l,height:c}}applyAspectRatio(t,e,a){const n=a==="left"||a==="right",i=a==="top"||a==="bottom";return n?{width:t,height:t/this.aspectRatio}:i?{width:e*this.aspectRatio,height:e}:{width:t,height:t/this.aspectRatio}}};function pce(t,e){const{selection:a}=t,{$from:n}=a;if(a instanceof se){const r=n.index();return n.parent.canReplaceWith(r,r+1,e)}let i=n.depth;for(;i>=0;){const r=n.index(i);if(n.node(i).contentMatchAt(r).matchType(e))return!0;i-=1}return!1}var mce={};mS(mce,{createAtomBlockMarkdownSpec:()=>hce,createBlockMarkdownSpec:()=>fce,createInlineMarkdownSpec:()=>xce,parseAttributes:()=>bS,parseIndentedBlocks:()=>Hb,renderNestedMarkdownContent:()=>kS,serializeAttributes:()=>wS});function bS(t){if(!(t!=null&&t.trim()))return{};const e={},a=[],n=t.replace(/["']([^"']*)["']/g,d=>(a.push(d),`__QUOTED_${a.length-1}__`)),i=n.match(/(?:^|\s)\.([a-zA-Z][\w-]*)/g);if(i){const d=i.map(u=>u.trim().slice(1));e.class=d.join(" ")}const r=n.match(/(?:^|\s)#([a-zA-Z][\w-]*)/);r&&(e.id=r[1]);const o=/([a-zA-Z][\w-]*)\s*=\s*(__QUOTED_\d+__)/g;Array.from(n.matchAll(o)).forEach(([,d,u])=>{var p;const m=parseInt(((p=u.match(/__QUOTED_(\d+)__/))==null?void 0:p[1])||"0",10),h=a[m];h&&(e[d]=h.slice(1,-1))});const c=n.replace(/(?:^|\s)\.([a-zA-Z][\w-]*)/g,"").replace(/(?:^|\s)#([a-zA-Z][\w-]*)/g,"").replace(/([a-zA-Z][\w-]*)\s*=\s*__QUOTED_\d+__/g,"").trim();
vendor: 5,016 bytes, lines 17714-17724
17714return c&&c.split(/\s+/).filter(Boolean).forEach(u=>{u.match(/^[a-zA-Z][\w-]*$/)&&(e[u]=!0)}),e}function wS(t){if(!t||Object.keys(t).length===0)return"";const e=[];return t.class&&String(t.class).split(/\s+/).filter(Boolean).forEach(n=>e.push(`.${n}`)),t.id&&e.push(`#${t.id}`),Object.entries(t).forEach(([a,n])=>{a==="class"||a==="id"||(n===!0?e.push(a):n!==!1&&n!=null&&e.push(`${a}="${String(n)}"`))}),e.join(" ")}function hce(t){const{nodeName:e,name:a,parseAttributes:n=bS,serializeAttributes:i=wS,defaultAttributes:r={},requiredAttributes:o=[],allowedAttributes:l}=t,c=a||e,d=u=>{if(!l)return u;const p={};return l.forEach(m=>{m in u&&(p[m]=u[m])}),p};return{parseMarkdown:(u,p)=>{const m={...r,...u.attributes};return p.createNode(e,m,[])},markdownTokenizer:{name:e,level:"block",start(u){var p;const m=new RegExp(`^:::${c}(?:\\s|$)`,"m"),h=(p=u.match(m))==null?void 0:p.index;return h!==void 0?h:-1},tokenize(u,p,m){const h=new RegExp(`^:::${c}(?:\\s+\\{([^}]*)\\})?\\s*:::(?:\\n|$)`),g=u.match(h);if(!g)return;const y=g[1]||"",x=n(y);if(!o.find(w=>!(w in x)))return{type:e,raw:g[0],attributes:x}}},renderMarkdown:u=>{const p=d(u.attrs||{}),m=i(p),h=m?` {${m}}`:"";return`:::${c}${h} :::`}}}function fce(t){const{nodeName:e,name:a,getContent:n,parseAttributes:i=bS,serializeAttributes:r=wS,defaultAttributes:o={},content:l="block",allowedAttributes:c}=t,d=a||e,u=p=>{if(!c)return p;const m={};return c.forEach(h=>{h in p&&(m[h]=p[h])}),m};return{parseMarkdown:(p,m)=>{let h;if(n){const y=n(p);h=typeof y=="string"?[{type:"text",text:y}]:y}else l==="block"?h=m.parseChildren(p.tokens||[]):h=m.parseInline(p.tokens||[]);const g={...o,...p.attributes};return m.createNode(e,g,h)},markdownTokenizer:{name:e,level:"block",start(p){var m;const h=new RegExp(`^:::${d}`,"m"),g=(m=p.match(h))==null?void 0:m.index;return g!==void 0?g:-1},tokenize(p,m,h){var g;const y=new RegExp(`^:::${d}(?:\\s+\\{([^}]*)\\})?\\s*\\n`),x=p.match(y);if(!x)return;const[v,w=""]=x,S=i(w);let T=1;const P=v.length;let M="";const C=/^:::([\w-]*)(\s.*)?/gm,E=p.slice(P);for(C.lastIndex=0;;){const j=C.exec(E);if(j===null)break;const N=j.index,L=j[1];if(!((g=j[2])!=null&&g.endsWith(":::"))){if(L)T+=1;else if(T-=1,T===0){const O=E.slice(0,N);M=O.trim();const R=p.slice(0,P+N+j[0].length);let G=[];if(M)if(l==="block")for(G=h.blockTokens(O),G.forEach(ee=>{ee.text&&(!ee.tokens||ee.tokens.length===0)&&(ee.tokens=h.inlineTokens(ee.text))});G.length>0;){const ee=G[G.length-1];if(ee.type==="paragraph"&&(!ee.text||ee.text.trim()===""))G.pop();else break}else G=h.inlineTokens(M);return{type:e,raw:R,attributes:S,content:M,tokens:G}}}}}},renderMarkdown:(p,m)=>{const h=u(p.attrs||{}),g=r(h),y=g?` {${g}}`:"",x=m.renderChildren(p.content||[],`
17715
17716`);return`:::${d}${y}
17717
17718${x}
17719
17720:::`}}}function gce(t){if(!t.trim())return{};const e={},a=/(\w+)=(?:"([^"]*)"|'([^']*)')/g;let n=a.exec(t);for(;n!==null;){const[,i,r,o]=n;e[i]=r||o,n=a.exec(t)}return e}function yce(t){return Object.entries(t).filter(([,e])=>e!=null).map(([e,a])=>`${e}="${a}"`).join(" ")}function xce(t){const{nodeName:e,name:a,getContent:n,parseAttributes:i=gce,serializeAttributes:r=yce,defaultAttributes:o={},selfClosing:l=!1,allowedAttributes:c}=t,d=a||e,u=m=>{if(!c)return m;const h={};return c.forEach(g=>{const y=typeof g=="string"?g:g.name,x=typeof g=="string"?void 0:g.skipIfDefault;if(y in m){const v=m[y];if(x!==void 0&&v===x)return;h[y]=v}}),h},p=d.replace(/[.*+?^${}()|[\]\\]/g,"\\$&");return{parseMarkdown:(m,h)=>{const g={...o,...m.attributes};if(l)return h.createNode(e,g);const y=n?n(m):m.content||"";return y?h.createNode(e,g,[h.createTextNode(y)]):h.createNode(e,g,[])},markdownTokenizer:{name:e,level:"inline",start(m){const h=l?new RegExp(`\\[${p}\\s*[^\\]]*\\]`):new RegExp(`\\[${p}\\s*[^\\]]*\\][\\s\\S]*?\\[\\/${p}\\]`),g=m.match(h),y=g==null?void 0:g.index;return y!==void 0?y:-1},tokenize(m,h,g){const y=l?new RegExp(`^\\[${p}\\s*([^\\]]*)\\]`):new RegExp(`^\\[${p}\\s*([^\\]]*)\\]([\\s\\S]*?)\\[\\/${p}\\]`),x=m.match(y);if(!x)return;let v="",w="";if(l){const[,T]=x;w=T}else{const[,T,P]=x;w=T,v=P||""}const S=i(w.trim());return{type:e,raw:x[0],content:v.trim(),attributes:S}}},renderMarkdown:m=>{let h="";n?h=n(m):m.content&&m.content.length>0&&(h=m.content.filter(v=>v.type==="text").map(v=>v.text).join(""));const g=u(m.attrs||{}),y=r(g),x=y?` ${y}`:"";return l?`[${d}${x}]`:`[${d}${x}]${h}[/${d}]`}}}function Hb(t,e,a){var n,i,r,o;const l=t.split(`
17721`),c=[];let d="",u=0;const p=e.baseIndentSize||2;for(;u<l.length;){const m=l[u],h=m.match(e.itemPattern);if(!h){if(c.length>0)break;if(m.trim()===""){u+=1,d=`${d}${m}
17722`;continue}else return}const g=e.extractItemData(h),{indentLevel:y,mainContent:x}=g;d=`${d}${m}
17723`;const v=[x];for(u+=1;u<l.length;){const P=l[u];if(P.trim()===""){const C=l.slice(u+1).findIndex(N=>N.trim()!=="");if(C===-1)break;if((((i=(n=l[u+1+C].match(/^(\s*)/))==null?void 0:n[1])==null?void 0:i.length)||0)>y){v.push(P),d=`${d}${P}
17724`,u+=1;continue}else break}if((((o=(r=P.match(/^(\s*)/))==null?void 0:r[1])==null?void 0:o.length)||0)>
17724y)v.push(P),d=`${d}${P}
17725`,u+=1;else break}let w;const S=v.slice(1);if(S.length>0){const P=S.map(M=>M.slice(y+p)).join(`
17726`);P.trim()&&(e.customNestedParser?w=e.customNestedParser(P):w=a.blockTokens(P))}const T=e.createToken(g,w);c.push(T)}if(c.length!==0)return{items:c,raw:d}}function kS(t,e,a,n){if(!t||!Array.isArray(t.content))return"";const i=typeof a=="function"?a(n):a,[r,...o]=t.content,l=e.renderChildren([r]);let c=`${i}${l}`;return o&&o.length>0&&o.forEach((d,u)=>{var p,m;const h=(m=(p=e.renderChild)==null?void 0:p.call(e,d,u+1))!=null?m:e.renderChildren([d]);if(h!=null){const g=h.split(`
17727`).map(y=>y?e.indent(y):e.indent("")).join(`
17728`);c+=d.type==="paragraph"?`
17729
17730${g}`:`
17731${g}`}}),c}function vce(t,e,a={}){const{state:n}=e,{doc:i,tr:r}=n,o=t;i.descendants((l,c)=>{const d=r.mapping.map(c),u=r.mapping.map(c)+l.nodeSize;let p=null;if(l.marks.forEach(h=>{if(h!==o)return!1;p=h}),!p)return;let m=!1;if(Object.keys(a).forEach(h=>{a[h]!==p.attrs[h]&&(m=!0)}),m){const h=t.type.create({...t.attrs,...a});r.removeMark(d,u,t.type),r.addMark(d,u,h)}}),r.docChanged&&e.view.dispatch(r)}var Oa=class G5 extends vS{constructor(){super(...arguments),this.type="node"}static create(e={}){const a=typeof e=="function"?e():e;return new G5(a)}configure(e){return super.configure(e)}extend(e){const a=typeof e=="function"?e():e;return super.extend(a)}};function ss(t){return new ece({find:t.find,handler:({state:e,range:a,match:n,pasteEvent:i})=>{const r=Pe(t.getAttributes,void 0,n,i);if(r===!1||r===null)return null;const{tr:o}=e,l=n[n.length-1],c=n[0];let d=a.to;if(l){const u=c.search(/\S/),p=a.from+c.indexOf(l),m=p+l.length;if(xS(a.from,a.to,e.doc).filter(y=>y.mark.type.excluded.find(v=>v===t.type&&v!==y.mark.type)).filter(y=>y.to>p).length)return null;m<a.to&&o.delete(m,a.to),p>a.from&&o.delete(a.from+u,p),d=a.from+u+l.length,o.addMark(a.from+u,d,t.type.create(r||{})),n.index!==void 0&&n.input!==void 0&&n.index+n[0].length>=n.input.length||o.removeStoredMark(t.type)}}})}const{getOwnPropertyNames:bce,getOwnPropertySymbols:wce}=Object,{hasOwnProperty:kce}=Object.prototype;function sx(t,e){return function(n,i,r){return t(n,i,r)&&e(n,i,r)}}function im(t){return function(a,n,i){if(!a||!n||typeof a!="object"||typeof n!="object")return t(a,n,i);const{cache:r}=i,o=r.get(a),l=r.get(n);if(o&&l)return o===n&&l===a;r.set(a,n),r.set(n,a);const c=t(a,n,i);return r.delete(a),r.delete(n),c}}function Sce(t){return t!=null?t[Symbol.toStringTag]:void 0}function TT(t){return bce(t).concat(wce(t))}const _ce=Object.hasOwn||((t,e)=>kce.call(t,e));function gs(t,e){return t===e||!t&&!e&&t!==t&&e!==e}const Ace="__v",Ece="__o",Cce="_owner",{getOwnPropertyDescriptor:NT,keys:IT}=Object;function jce(t,e){return t.byteLength===e.byteLength&&lf(new Uint8Array(t),new Uint8Array(e))}function Tce(t,e,a){let n=t.length;if(e.length!==n)return!1;for(;n-- >0;)if(!a.equals(t[n],e[n],n,n,t,e,a))return!1;return!0}function Nce(t,e){return t.byteLength===e.byteLength&&lf(new Uint8Array(t.buffer,t.byteOffset,t.byteLength),new Uint8Array(e.buffer,e.byteOffset,e.byteLength))}function Ice(t,e){return gs(t.getTime(),e.getTime())}function Pce(t,e){return t.name===e.name&&t.message===e.message&&t.cause===e.cause&&t.stack===e.stack}function Rce(t,e){return t===e}function PT(t,e,a){const n=t.size;if(n!==e.size)return!1;if(!n)return!0;const i=new Array(n),r=t.entries();let o,l,c=0;for(;(o=r.next())&&!o.done;){const d=e.entries();let u=!1,p=0;for(;(l=d.next())&&!l.done;){if(i[p]){p++;continue}const m=o.value,h=l.value;if(a.equals(m[0],h[0],c,p,t,e,a)&&a.equals(m[1],h[1],m[0],h[0],t,e,a)){u=i[p]=!0;break}p++}if(!u)return!1;c++}return!0}const Lce=gs;function Oce(t,e,a){const n=IT(t);let i=n.length;if(IT(e).length!==i)return!1;for(;i-- >0;)if(!K5(t,e,a,n[i]))return!1;return!0}function Pc(t,e,a){const n=TT(t);let i=n.length;if(TT(e).length!==i)return!1;let r,o,l;for(;i-- >0;)if(r=n[i],!K5(t,e,a,r)||(o=NT(t,r),l=NT(e,r),(o||l)&&(!o||!l||o.configurable!==l.configurable||o.enumerable!==l.enumerable||o.writable!==l.writable)))return!1;return!0}function Mce(t,e){return gs(t.valueOf(),e.valueOf())}function Dce(t,e){return t.source===e.source&&t.flags===e.flags}function RT(t,e,a){const n=t.size;if(n!==e.size)return!1;if(!n)return!0;const i=new Array(n),r=t.values();let o,l;for(;(o=r.next())&&!o.done;){const c=e.values();let d=!1,u=0;for(;(l=c.next())&&!l.done;){if(!i[u]&&a.equals(o.value,l.value,o.value,l.value,t,e,a)){d=i[u]=!0;break}u++}if(!d)return!1}return!0}function lf(t,e){let a=t.byteLength;if(e.byteLength!==a||t.byteOffset!==e.byteOffset)return!1;for(;a-- >0;)if(t[a]!==e[a])return!1;return!0}function qce(t,e){return t.hostname===e.hostname&&t.pathname===e.pathname&&t.protocol===e.protocol&&t.port===e.port&&t.hash===e.hash&&t.username===e.username&&t.password===e.password}function K5(t,e,a,n){return(n===Cce||n===Ece||n===Ace)&&(t.$$typeof||e.$$typeof)?!0:_ce(e,n)&&a.equals(t[n],e[n],n,n,t,e,a)}const zce="[object ArrayBuffer]",Vce="[object Arguments]",Hce="[object Boolean]",Fce="[object DataView]",Bce="[object Date]",Uce="[object Error]",$ce="[object Map]",Wce="[object Number]",Gce="[object Object]",Kce="[object RegExp]",Jce="[object Set]",Qce="[object String]",Xce={"[object Int8Array]":!0,"[object Uint8Array]":!0,"[object Uint8ClampedArray]":!0,"[object Int16Array]":!0,"[object Uint16Array]":!0,"[object Int32Array]":!0,"[object Uint32Array]":!0,"[object Float16Array]":!0,"[object Float32Array]":!0,"[object Float64Array
17731]":!0,"[object BigInt64Array]":!0,"[object BigUint64Array]":!0},Yce="[object URL]",Zce=Object.prototype.toString;function ede({areArrayBuffersEqual:t,areArraysEqual:e,areDataViewsEqual:a,areDatesEqual:n,areErrorsEqual:i,areFunctionsEqual:r,areMapsEqual:o,areNumbersEqual:l,areObjectsEqual:c,arePrimitiveWrappersEqual:d,areRegExpsEqual:u,areSetsEqual:p,areTypedArraysEqual:m,areUrlsEqual:h,unknownTagComparators:g}){return function(x,v,w){if(x===v)return!0;if(x==null||v==null)return!1;const S=typeof x;if(S!==typeof v)return!1;if(S!=="object")return S==="number"?l(x,v,w):S==="function"?r(x,v,w):!1;const T=x.constructor;if(T!==v.constructor)return!1;if(T===Object)return c(x,v,w);if(Array.isArray(x))return e(x,v,w);if(T===Date)return n(x,v,w);if(T===RegExp)return u(x,v,w);if(T===Map)return o(x,v,w);if(T===Set)return p(x,v,w);const P=Zce.call(x);if(P===Bce)return n(x,v,w);if(P===Kce)return u(x,v,w);if(P===$ce)return o(x,v,w);if(P===Jce)return p(x,v,w);if(P===Gce)return typeof x.then!="function"&&typeof v.then!="function"&&c(x,v,w);if(P===Yce)return h(x,v,w);if(P===Uce)return i(x,v,w);if(P===Vce)return c(x,v,w);if(Xce[P])return m(x,v,w);if(P===zce)return t(x,v,w);if(P===Fce)return a(x,v,w);if(P===Hce||P===Wce||P===Qce)return d(x,v,w);if(g){let M=g[P];if(!M){const C=Sce(x);C&&(M=g[C])}if(M)return M(x,v,w)}return!1}}function tde({circular:t,createCustomConfig:e,strict:a}){let n={areArrayBuffersEqual:jce,areArraysEqual:a?Pc:Tce,areDataViewsEqual:Nce,areDatesEqual:Ice,areErrorsEqual:Pce,areFunctionsEqual:Rce,areMapsEqual:a?sx(PT,Pc):PT,areNumbersEqual:Lce,areObjectsEqual:a?Pc:Oce,arePrimitiveWrappersEqual:Mce,areRegExpsEqual:Dce,areSetsEqual:a?sx(RT,Pc):RT,areTypedArraysEqual:a?sx(lf,Pc):lf,areUrlsEqual:qce,unknownTagComparators:void 0};if(e&&(n=Object.assign({},n,e(n))),t){const i=im(n.areArraysEqual),r=im(n.areMapsEqual),o=im(n.areObjectsEqual),l=im(n.areSetsEqual);n=Object.assign({},n,{areArraysEqual:i,areMapsEqual:r,areObjectsEqual:o,areSetsEqual:l})}return n}function ade(t){return function(e,a,n,i,r,o,l){return t(e,a,l)}}function nde({circular:t,comparator:e,createState:a,equals:n,strict:i}){if(a)return function(l,c){const{cache:d=t?new WeakMap:void 0,meta:u}=a();return e(l,c,{cache:d,equals:n,meta:u,strict:i})};if(t)return function(l,c){return e(l,c,{cache:new WeakMap,equals:n,meta:void 0,strict:i})};const r={cache:void 0,equals:n,meta:void 0,strict:i};return function(l,c){return e(l,c,r)}}const ide=no();no({strict:!0});no({circular:!0});no({circular:!0,strict:!0});no({createInternalComparator:()=>gs});no({strict:!0,createInternalComparator:()=>gs});no({circular:!0,createInternalComparator:()=>gs});no({circular:!0,createInternalComparator:()=>gs,strict:!0});function no(t={}){const{circular:e=!1,createInternalComparator:a,createState:n,strict:i=!1}=t,r=tde(t),o=ede(r),l=a?a(o):ade(o);return nde({circular:e,comparator:o,createState:n,equals:l,strict:i})}var J5={exports:{}},Q5={};/**
17732 * @license React
17733 * use-sync-external-store-shim/with-selector.production.js
17734 *
17735 * Copyright (c) Meta Platforms, Inc. and affiliates.
17736 *
17737 * This source code is licensed under the MIT license found in the
17738 * LICENSE file in the root directory of this source tree.
17739 */var Xg=k,rde=ig;function ode(t,e){return t===e&&(t!==0||1/t===1/e)||t!==t&&e!==e}var sde=typeof Object.is=="function"?Object.is:ode,lde=rde.useSyncExternalStore,cde=Xg.useRef,dde=Xg.useEffect,ude=Xg.useMemo,pde=Xg.useDebugValue;Q5.useSyncExternalStoreWithSelector=function(t,e,a,n,i){var r=cde(null);if(r.current===null){var o={hasValue:!1,value:null};r.current=o}else o=r.current;r=ude(function(){function c(h){if(!d){if(d=!0,u=h,h=n(h),i!==void 0&&o.hasValue){var g=o.value;if(i(g,h))return p=g}return p=h}if(g=p,sde(u,h))return g;var y=n(h);return i!==void 0&&i(g,y)?(u=h,g):(u=h,p=y)}var d=!1,u,p,m=a===void 0?null:a;return[function(){return c(e())},m===null?void 0:function(){return c(m())}]},[e,a,n,i]);var l=lde(t,r[0],r[1]);return dde(function(){o.hasValue=!0,o.value=l},[l]),pde(l),l};J5.exports=Q5;var mde=J5.exports,hde=(...t)=>e=>{t.forEach(a=>{typeof a=="function"?a(e):a&&(a.current=e)})},fde=({contentComponent:t})=>{const e=ig.useSyncExternalStore(t.subscribe,t.getSnapshot,t.getServerSnapshot);return s.jsx(s.Fragment,{children:Object.values(e)})};function gde(){const t=new Set;let e={};return{subscribe(a){return t.add(a),()=>{t.delete(a)}},getSnapshot(){return e},getServerSnapshot(){return e},setRenderer(a,n){e={...e,[a]:Iz.createPortal(n.reactElement,n.element,a)},t.forEach(i=>
17739i())},removeRenderer(a){const n={...e};delete n[a],e=n,t.forEach(i=>i())}}}var yde=class extends Re.Component{constructor(t){var e;super(t),this.editorContentRef=Re.createRef(),this.initialized=!1,this.state={hasContentComponentInitialized:!!((e=t.editor)!=null&&e.contentComponent)}}componentDidMount(){this.init()}componentDidUpdate(){this.init()}init(){var t;const e=this.props.editor;if(e&&!e.isDestroyed&&((t=e.view.dom)!=null&&t.parentNode)){if(e.contentComponent)return;const a=this.editorContentRef.current;a.append(...e.view.dom.parentNode.childNodes),e.setOptions({element:a}),e.contentComponent=gde(),this.state.hasContentComponentInitialized||(this.unsubscribeToContentComponent=e.contentComponent.subscribe(()=>{this.setState(n=>n.hasContentComponentInitialized?n:{hasContentComponentInitialized:!0}),this.unsubscribeToContentComponent&&this.unsubscribeToContentComponent()})),e.createNodeViews(),this.initialized=!0}}componentWillUnmount(){var t;const e=this.props.editor;if(e){this.initialized=!1,e.isDestroyed||e.view.setProps({nodeViews:{}}),this.unsubscribeToContentComponent&&this.unsubscribeToContentComponent(),e.contentComponent=null;try{if(!((t=e.view.dom)!=null&&t.parentNode))return;const a=document.createElement("div");a.append(...e.view.dom.parentNode.childNodes),e.setOptions({element:a})}catch{}}}render(){const{editor:t,innerRef:e,...a}=this.props;return s.jsxs(s.Fragment,{children:[s.jsx("div",{ref:hde(e,this.editorContentRef),...a}),(t==null?void 0:t.contentComponent)&&s.jsx(fde,{contentComponent:t.contentComponent})]})}},xde=k.forwardRef((t,e)=>{const a=Re.useMemo(()=>Math.floor(Math.random()*4294967295).toString(),[t.editor]);return Re.createElement(yde,{key:a,innerRef:e,...t})}),vde=Re.memo(xde),bde=typeof window<"u"?k.useLayoutEffect:k.useEffect,wde=class{constructor(t){this.transactionNumber=0,this.lastTransactionNumber=0,this.subscribers=new Set,this.editor=t,this.lastSnapshot={editor:t,transactionNumber:0},this.getSnapshot=this.getSnapshot.bind(this),this.getServerSnapshot=this.getServerSnapshot.bind(this),this.watch=this.watch.bind(this),this.subscribe=this.subscribe.bind(this)}getSnapshot(){return this.transactionNumber===this.lastTransactionNumber?this.lastSnapshot:(this.lastTransactionNumber=this.transactionNumber,this.lastSnapshot={editor:this.editor,transactionNumber:this.transactionNumber},this.lastSnapshot)}getServerSnapshot(){return{editor:null,transactionNumber:0}}subscribe(t){return this.subscribers.add(t),()=>{this.subscribers.delete(t)}}watch(t){if(this.editor=t,this.editor){const e=()=>{this.transactionNumber+=1,this.subscribers.forEach(n=>n())},a=this.editor;return a.on("transaction",e),()=>{a.off("transaction",e)}}}};function kde(t){var e;const[a]=k.useState(()=>new wde(t.editor)),n=mde.useSyncExternalStoreWithSelector(a.subscribe,a.getSnapshot,a.getServerSnapshot,t.selector,(e=t.equalityFn)!=null?e:ide);return bde(()=>a.watch(t.editor),[t.editor,a]),k.useDebugValue(n),n}var Sde=!1,Fb=typeof window>"u",_de=Fb||!!(typeof window<"u"&&window.next),Ade=class X5{constructor(e){this.editor=null,this.subscriptions=new Set,this.isComponentMounted=!1,this.previousDeps=null,this.instanceId="",this.options=e,this.subscriptions=new Set,this.setEditor(this.getInitialEditor()),this.scheduleDestroy(),this.getEditor=this.getEditor.bind(this),this.getServerSnapshot=this.getServerSnapshot.bind(this),this.subscribe=this.subscribe.bind(this),this.refreshEditorInstance=this.refreshEditorInstance.bind(this),this.scheduleDestroy=this.scheduleDestroy.bind(this),this.onRender=this.onRender.bind(this),this.createEditor=this.createEditor.bind(this)}setEditor(e){this.editor=e,this.instanceId=Math.random().toString(36).slice(2,9),this.subscriptions.forEach(a=>a())}getInitialEditor(){return this.options.current.immediatelyRender===void 0?Fb||_de?null:this.createEditor():(this.options.current.immediatelyRender,this.options.current.immediatelyRender?this.createEditor():null)}createEditor(){const e={...this.options.current,onBeforeCreate:(...n)=>{var i,r;return(r=(i=this.options.current).onBeforeCreate)==null?void 0:r.call(i,...n)},onBlur:(...n)=>{var i,r;return(r=(i=this.options.current).onBlur)==null?void 0:r.call(i,...n)},onCreate:(...n)=>{var i,r;return(r=(i=this.options.current).onCreate)==null?void 0:r.call(i,...n)},onDestroy:(...n)=>{var i,r;return(r=(i=this.options.current).onDestroy)==null?void 0:r.call(i,...n)},onFocus:(...n)=>{var i,r;return(r=(i=this.options.current).onFocus)==null?void 0:r.call(i,...n)},onSelectionUpdate:(...n)=>{var i,r;return(r=(i=this.options.current).onSelectionUpdate)==null?void 0:r.call(i,...n)},onTransaction:(...n)=>{var i,r;return(r=(i=this.options.current).onTransaction)==null?void 0:r.call(i,...n)},onUpdate:(...n)=>{var i,r;return(r=(i=this.options.current).onUpdate)==null?void 0:r.call(i,...n)},onContentError:(...n)=>{var i,r;return(r=(i=this.options.current).onContentError)==null?void 0:r.call(i,...n)},onDrop:(...n)=>{var i,r;return(r=(i=this.options.current).onDrop)==null?void 0:r.call(i,...n)},onPaste:(...n)=>{var i,r;return(r=(i=this.options.current).onPaste)==null?void 0:r.call(i,...n)},onDelete:(...n)=>{var i,r;return(r=(i=this.options.current).onDelete)==null?void 0:r.call(i,...n)}};return new cce(e)}getEditor(){return this.editor}getServerSnapshot(){return null}subscribe(e){return this.subscriptions.add(e),()=>{this.subscriptions.delete(e)}}static compareOptions(e,a){return Object.keys(e).every(n=>["onCreate","onBeforeCreate","onDestroy","onUpdate","onTransaction","onFocus","onBlur","onSelectionUpdate","onContentError","onDrop","onPaste"].includes(n)?!0:n==="extensions"&&e.extensions&&a.extensions?e.extensions.length!==a.extensions.length?!1:e.extensions.every((i,r)=>{var o;return i===((o=a.extensions)==null?void 0:o[r])}):e[n]===a[n])}onRender(e){return()=>(this.isComponentMounted=!0,clearTimeout(this.scheduledDestructionTimeout),this.editor&&!this.editor.isDestroyed&&e.length===0?X5.compareOptions(this.options.current,this.editor.options)||this.editor.setOptions({...this.options.current,editable:this.editor.isEditable}
17739):this.refreshEditorInstance(e),()=>{this.isComponentMounted=!1,this.scheduleDestroy()})}refreshEditorInstance(e){if(this.editor&&!this.editor.isDestroyed){if(this.previousDeps===null){this.previousDeps=e;return}if(this.previousDeps.length===e.length&&this.previousDeps.every((n,i)=>n===e[i]))return}this.editor&&!this.editor.isDestroyed&&this.editor.destroy(),this.setEditor(this.createEditor()),this.previousDeps=e}scheduleDestroy(){const e=this.instanceId,a=this.editor;this.scheduledDestructionTimeout=setTimeout(()=>{if(this.isComponentMounted&&this.instanceId===e){a&&a.setOptions(this.options.current);return}a&&!a.isDestroyed&&(a.destroy(),this.instanceId===e&&this.setEditor(null))},1)}};function Ede(t={},e=[]){const a=k.useRef(t);a.current=t;const[n]=k.useState(()=>new Ade(a)),i=ig.useSyncExternalStore(n.subscribe,n.getEditor,n.getServerSnapshot);return k.useDebugValue(i),k.useEffect(n.onRender(e)),kde({editor:i,selector:({transactionNumber:r})=>t.shouldRerenderOnTransaction===!1||t.shouldRerenderOnTransaction===void 0?null:t.immediatelyRender&&r===0?0:r+1}),i}var Cde=k.createContext({editor:null});Cde.Consumer;var jde=k.createContext({onDragStart:()=>{},nodeViewContentChildren:void 0,nodeViewContentRef:()=>{}}),Tde=()=>k.useContext(jde);Re.forwardRef((t,e)=>{const{onDragStart:a}=Tde(),n=t.as||"div";return s.jsx(n,{...t,ref:e,"data-node-view-wrapper":"",onDragStart:a,style:{whiteSpace:"normal",...t.style}})});Re.createContext({markViewContentRef:()=>{}});var cf=(t,e)=>{if(t==="slot")return 0;if(t instanceof Function)return t(e);const{children:a,...n}=e??{};if(t==="svg")throw new Error("SVG elements are not supported in the JSX syntax, use the array syntax instead");return[t,n,a]},Nde=/^\s*>\s$/,Ide=Oa.create({name:"blockquote",addOptions(){return{HTMLAttributes:{}}},content:"block+",group:"block",defining:!0,parseHTML(){return[{tag:"blockquote"}]},renderHTML({HTMLAttributes:t}){return cf("blockquote",{...ct(this.options.HTMLAttributes,t),children:cf("slot",{})})},parseMarkdown:(t,e)=>e.createNode("blockquote",void 0,e.parseChildren(t.tokens||[])),renderMarkdown:(t,e)=>{if(!t.content)return"";const a=">",n=[];return t.content.forEach(i=>{const l=e.renderChildren([i]).split(`
17740`).map(c=>c.trim()===""?a:`${a} ${c}`);n.push(l.join(`
17741`))}),n.join(`
17742${a}
17743`)},addCommands(){return{setBlockquote:()=>({commands:t})=>t.wrapIn(this.name),toggleBlockquote:()=>({commands:t})=>t.toggleWrap(this.name),unsetBlockquote:()=>({commands:t})=>t.lift(this.name)}},addKeyboardShortcuts(){return{"Mod-Shift-b":()=>this.editor.commands.toggleBlockquote()}},addInputRules(){return[Dl({find:Nde,type:this.type})]}}),Pde=/(?:^|\s)(\*\*(?!\s+\*\*)((?:[^*]+))\*\*(?!\s+\*\*))$/,Rde=/(?:^|\s)(\*\*(?!\s+\*\*)((?:[^*]+))\*\*(?!\s+\*\*))/g,Lde=/(?:^|\s)(__(?!\s+__)((?:[^_]+))__(?!\s+__))$/,Ode=/(?:^|\s)(__(?!\s+__)((?:[^_]+))__(?!\s+__))/g,Mde=ao.create({name:"bold",addOptions(){return{HTMLAttributes:{}}},parseHTML(){return[{tag:"strong"},{tag:"b",getAttrs:t=>t.style.fontWeight!=="normal"&&null},{style:"font-weight=400",clearMark:t=>t.type.name===this.name},{style:"font-weight",getAttrs:t=>/^(bold(er)?|[5-9]\d{2,})$/.test(t)&&null}]},renderHTML({HTMLAttributes:t}){return cf("strong",{...ct(this.options.HTMLAttributes,t),children:cf("slot",{})})},markdownTokenName:"strong",parseMarkdown:(t,e)=>e.applyMark("bold",e.parseInline(t.tokens||[])),renderMarkdown:(t,e)=>`**${e.renderChildren(t)}**`,addCommands(){return{setBold:()=>({commands:t})=>t.setMark(this.name),toggleBold:()=>({commands:t})=>t.toggleMark(this.name),unsetBold:()=>({commands:t})=>t.unsetMark(this.name)}},addKeyboardShortcuts(){return{"Mod-b":()=>this.editor.commands.toggleBold(),"Mod-B":()=>this.editor.commands.toggleBold()}},addInputRules(){return[Ml({find:Pde,type:this.type}),Ml({find:Lde,type:this.type})]},addPasteRules(){return[ss({find:Rde,type:this.type}),ss({find:Ode,type:this.type})]}}),Dde=/(^|[^`])`([^`]+)`(?!`)$/,qde=/(^|[^`])`([^`]+)`(?!`)/g,zde=ao.create({name:"code",addOptions(){return{HTMLAttributes:{}}},excludes:"_",code:!0,exitable:!0,parseHTML(){return[{tag:"code"}]},renderHTML({HTMLAttributes:t}){return["code",ct(this.options.HTMLAttributes,t),0]},markdownTokenName:"codespan",parseMarkdown:(t,e)=>
vendor: 7,314 bytes, lines 17743-17764
17743e.applyMark("code",[{type:"text",text:t.text||""}]),renderMarkdown:(t,e)=>t.content?`\`${e.renderChildren(t.content)}\``:"",addCommands(){return{setCode:()=>({commands:t})=>t.setMark(this.name),toggleCode:()=>({commands:t})=>t.toggleMark(this.name),unsetCode:()=>({commands:t})=>t.unsetMark(this.name)}},addKeyboardShortcuts(){return{"Mod-e":()=>this.editor.commands.toggleCode()}},addInputRules(){return[Ml({find:Dde,type:this.type})]},addPasteRules(){return[ss({find:qde,type:this.type})]}}),lx=4,Vde=/^```([a-z]+)?[\s\n]$/,Hde=/^~~~([a-z]+)?[\s\n]$/,Fde=Oa.create({name:"codeBlock",addOptions(){return{languageClassPrefix:"language-",exitOnTripleEnter:!0,exitOnArrowDown:!0,defaultLanguage:null,enableTabIndentation:!1,tabSize:lx,HTMLAttributes:{}}},content:"text*",marks:"",group:"block",code:!0,defining:!0,addAttributes(){return{language:{default:this.options.defaultLanguage,parseHTML:t=>{var e;const{languageClassPrefix:a}=this.options;if(!a)return null;const r=[...((e=t.firstElementChild)==null?void 0:e.classList)||[]].filter(o=>o.startsWith(a)).map(o=>o.replace(a,""))[0];return r||null},rendered:!1}}},parseHTML(){return[{tag:"pre",preserveWhitespace:"full"}]},renderHTML({node:t,HTMLAttributes:e}){return["pre",ct(this.options.HTMLAttributes,e),["code",{class:t.attrs.language?this.options.languageClassPrefix+t.attrs.language:null},0]]},markdownTokenName:"code",parseMarkdown:(t,e)=>{var a;return((a=t.raw)==null?void 0:a.startsWith("```"))===!1&&t.codeBlockStyle!=="indented"?[]:e.createNode("codeBlock",{language:t.lang||null},t.text?[e.createTextNode(t.text)]:[])},renderMarkdown:(t,e)=>{var a;let n="";const i=((a=t.attrs)==null?void 0:a.language)||"";return t.content?n=[`\`\`\`${i}`,e.renderChildren(t.content),"```"].join(`
17744`):n=`\`\`\`${i}
17745
17746\`\`\``,n},addCommands(){return{setCodeBlock:t=>({commands:e})=>e.setNode(this.name,t),toggleCodeBlock:t=>({commands:e})=>e.toggleNode(this.name,"paragraph",t)}},addKeyboardShortcuts(){return{"Mod-Alt-c":()=>this.editor.commands.toggleCodeBlock(),Backspace:()=>{const{empty:t,$anchor:e}=this.editor.state.selection,a=e.pos===1;return!t||e.parent.type.name!==this.name?!1:a||!e.parent.textContent.length?this.editor.commands.clearNodes():!1},Tab:({editor:t})=>{var e;if(!this.options.enableTabIndentation)return!1;const a=(e=this.options.tabSize)!=null?e:lx,{state:n}=t,{selection:i}=n,{$from:r,empty:o}=i;if(r.parent.type!==this.type)return!1;const l=" ".repeat(a);return o?t.commands.insertContent(l):t.commands.command(({tr:c})=>{const{from:d,to:u}=i,h=n.doc.textBetween(d,u,`
17747`,`
17748`).split(`
17749`).map(g=>l+g).join(`
17750`);return c.replaceWith(d,u,n.schema.text(h)),!0})},"Shift-Tab":({editor:t})=>{var e;if(!this.options.enableTabIndentation)return!1;const a=(e=this.options.tabSize)!=null?e:lx,{state:n}=t,{selection:i}=n,{$from:r,empty:o}=i;return r.parent.type!==this.type?!1:o?t.commands.command(({tr:l})=>{var c;const{pos:d}=r,u=r.start(),p=r.end(),h=n.doc.textBetween(u,p,`
17751`,`
17752`).split(`
17753`);let g=0,y=0;const x=d-u;for(let M=0;M<h.length;M+=1){if(y+h[M].length>=x){g=M;break}y+=h[M].length+1}const w=((c=h[g].match(/^ */))==null?void 0:c[0])||"",S=Math.min(w.length,a);if(S===0)return!0;let T=u;for(let M=0;M<g;M+=1)T+=h[M].length+1;return l.delete(T,T+S),d-T<=S&&l.setSelection(ce.create(l.doc,T)),!0}):t.commands.command(({tr:l})=>{const{from:c,to:d}=i,m=n.doc.textBetween(c,d,`
17754`,`
17755`).split(`
17756`).map(h=>{var g;const y=((g=h.match(/^ */))==null?void 0:g[0])||"",x=Math.min(y.length,a);return h.slice(x)}).join(`
17757`);return l.replaceWith(c,d,n.schema.text(m)),!0})},Enter:({editor:t})=>{if(!this.options.exitOnTripleEnter)return!1;const{state:e}=t,{selection:a}=e,{$from:n,empty:i}=a;if(!i||n.parent.type!==this.type)return!1;const r=n.parentOffset===n.parent.nodeSize-2,o=n.parent.textContent.endsWith(`
17758
17759`);return!r||!o?!1:t.chain().command(({tr:l})=>(l.delete(n.pos-2,n.pos),!0)).exitCode().run()},ArrowDown:({editor:t})=>{if(!this.options.exitOnArrowDown)return!1;const{state:e}=t,{selection:a,doc:n}=e,{$from:i,empty:r}=a;if(!r||i.parent.type!==this.type||!(i.parentOffset===i.parent.nodeSize-2))return!1;const l=i.after();return l===void 0?!1:n.nodeAt(l)?t.commands.command(({tr:d})=>(d.setSelection(xe.near(n.resolve(l))),!0)):t.commands.exitCode()}}},addInputRules(){return[Vb({find:Vde,type:this.type,getAttributes:t=>({language:t[1]})}),Vb({find:Hde,type:this.type,getAttributes:t=>({language:t[1]})})]},addProseMirrorPlugins(){return[new at({key:new _t("codeBlockVSCodeHandler"),props:{handlePaste:(t,e)=>{if(!e.clipboardData||this.editor.isActive(this.type.name))return!1;const a=e.clipboardData.getData("text/plain"),n=e.clipboardData.getData("vscode-editor-data"),i=n?JSON.parse(n):void 0,r=i==null?void 0:i.mode;if(!a||!r)return!1;const{tr:o,schema:l}=t.state,c=l.text(a.replace(/\r\n?/g,`
17760`));return o.replaceSelectionWith(this.type.create({language:r},c)),o.selection.$from.parent.type!==this.type&&o.setSelection(ce.near(o.doc.resolve(Math.max(0,o.selection.from-2)))),o.setMeta("paste",!0),t.dispatch(o),!0}}})]}}),Bde=Oa.create({name:"doc",topNode:!0,content:"block+",renderMarkdown:(t,e)=>t.content?e.renderChildren(t.content,`
17761
17762`):""}),Ude=Oa.create({name:"hardBreak",markdownTokenName:"br",addOptions(){return{keepMarks:!0,HTMLAttributes:{}}},inline:!0,group:"inline",selectable:!1,linebreakReplacement:!0,parseHTML(){return[{tag:"br"}]},renderHTML({HTMLAttributes:t}){return["br",ct(this.options.HTMLAttributes,t)]},renderText(){return`
17763`},renderMarkdown:()=>`  
17764`,parseMarkdown:()=>({type:"hardBreak"}),addCommands(){return{setHardBreak:()=>({commands:t,chain:e,state:a,editor:n})=>t.first([()=>t.exitCode(),()=>t.command(()=>{const{selection:i,storedMarks:r}=a;if(i.$from.parent.type.spec.isolating)return!1;const{keepMarks:o}=this.options,{splittableMarks:l}=n.extensionManager,c=r||i.$to.parentOffset&&i.$from.marks();return e().insertContent({type:this.name}).command(({tr:d,dispatch:u})=>{if(u&&c&&o){const p=c.filter(m=>l.includes(m.type.name));d.ensureMarks(p)}return!0}).run()})])}},addKeyboardShortcuts(){return{"Mod-Enter":()=>this.editor.commands.setHardBreak(),"Shift-Enter":()=>this.editor.commands.setHardBreak()}}}),$de=Oa.create({name:"heading",addOptions(){return{levels:[1,2,3,4,5,6],HTMLAttributes:{}}},content:"inline*",group:"block",defining:!0,addAttributes(){return{level:{default:1,rendered:!1}}},parseHTML(){return this.options.levels.map(t=>({tag:`h${t}`,attrs:{level:t}}))},renderHTML({node:t,HTMLAttributes:e}){return[`h${this.options.levels.includes(t.attrs.level)?t.attrs.level:this.options.levels[0]}`,ct(this.options.HTMLAttributes,e),0]},parseMarkdown:(t,e)=>e.createNode("heading",{level:t.depth||1},e.parseInline(t.tokens||[])),renderMarkdown:(t,e)=>{var a;const n=(a=t.attrs)!=null&&a.level?parseInt(t.attrs.level,10):1,i="#".repeat(n);return t.content?`${i} ${e.renderChildren(t.content)}`:""},addCommands(){return{setHeading:t=>({commands:e})=>this.options.levels.includes(t.level)?e.setNode(this.name,t):!1,toggleHeading:t=>({commands:e})=>this.options.levels.includes(t.level)?e.toggleNode(this.name,"paragraph",t):!1}},addKeyboardShortcuts(){return this.options.levels.reduce((t,e)=>({...t,[`Mod-Alt-${e}`]:()=>this.editor.commands.toggleHeading({level:e})}),{})},addInputRules(){return this.options.levels.map(t=>Vb({find:new RegExp(`^(#{${Math.min(...this.options.levels)},${t}}
17764)\\s$`),type:this.type,getAttributes:{level:t}}))}}),Wde=Oa.create({name:"horizontalRule",addOptions(){return{HTMLAttributes:{},nextNodeType:"paragraph"}},group:"block",parseHTML(){return[{tag:"hr"}]},renderHTML({HTMLAttributes:t}){return["hr",ct(this.options.HTMLAttributes,t)]},markdownTokenName:"hr",parseMarkdown:(t,e)=>e.createNode("horizontalRule"),renderMarkdown:()=>"---",addCommands(){return{setHorizontalRule:()=>({chain:t,state:e})=>{if(!pce(e,e.schema.nodes[this.name]))return!1;const{selection:a}=e,{$to:n}=a,i=t();return T5(a)?i.insertContentAt(n.pos,{type:this.name}):i.insertContent({type:this.name}),i.command(({state:r,tr:o,dispatch:l})=>{if(l){const{$to:c}=o.selection,d=c.end();if(c.nodeAfter)c.nodeAfter.isTextblock?o.setSelection(ce.create(o.doc,c.pos+1)):c.nodeAfter.isBlock?o.setSelection(se.create(o.doc,c.pos)):o.setSelection(ce.create(o.doc,c.pos));else{const u=r.schema.nodes[this.options.nextNodeType]||c.parent.type.contentMatch.defaultType,p=u==null?void 0:u.create();p&&(o.insert(d,p),o.setSelection(ce.create(o.doc,d+1)))}o.scrollIntoView()}return!0}).run()}}},addInputRules(){return[W5({find:/^(?:---|—-|___\s|\*\*\*\s)$/,type:this.t
vendor: 4,463 bytes, line 17764
17764ype})]}}),Gde=/(?:^|\s)(\*(?!\s+\*)((?:[^*]+))\*(?!\s+\*))$/,Kde=/(?:^|\s)(\*(?!\s+\*)((?:[^*]+))\*(?!\s+\*))/g,Jde=/(?:^|\s)(_(?!\s+_)((?:[^_]+))_(?!\s+_))$/,Qde=/(?:^|\s)(_(?!\s+_)((?:[^_]+))_(?!\s+_))/g,Xde=ao.create({name:"italic",addOptions(){return{HTMLAttributes:{}}},parseHTML(){return[{tag:"em"},{tag:"i",getAttrs:t=>t.style.fontStyle!=="normal"&&null},{style:"font-style=normal",clearMark:t=>t.type.name===this.name},{style:"font-style=italic"}]},renderHTML({HTMLAttributes:t}){return["em",ct(this.options.HTMLAttributes,t),0]},addCommands(){return{setItalic:()=>({commands:t})=>t.setMark(this.name),toggleItalic:()=>({commands:t})=>t.toggleMark(this.name),unsetItalic:()=>({commands:t})=>t.unsetMark(this.name)}},markdownTokenName:"em",parseMarkdown:(t,e)=>e.applyMark("italic",e.parseInline(t.tokens||[])),renderMarkdown:(t,e)=>`*${e.renderChildren(t)}*`,addKeyboardShortcuts(){return{"Mod-i":()=>this.editor.commands.toggleItalic(),"Mod-I":()=>this.editor.commands.toggleItalic()}},addInputRules(){return[Ml({find:Gde,type:this.type}),Ml({find:Jde,type:this.type})]},addPasteRules(){return[ss({find:Kde,type:this.type}),ss({find:Qde,type:this.type})]}});const Yde="aaa1rp3bb0ott3vie4c1le2ogado5udhabi7c0ademy5centure6ountant0s9o1tor4d0s1ult4e0g1ro2tna4f0l1rica5g0akhan5ency5i0g1rbus3force5tel5kdn3l0ibaba4pay4lfinanz6state5y2sace3tom5m0azon4ericanexpress7family11x2fam3ica3sterdam8nalytics7droid5quan4z2o0l2partments8p0le4q0uarelle8r0ab1mco4chi3my2pa2t0e3s0da2ia2sociates9t0hleta5torney7u0ction5di0ble3o3spost5thor3o0s4w0s2x0a2z0ure5ba0by2idu3namex4d1k2r0celona5laycard4s5efoot5gains6seball5ketball8uhaus5yern5b0c1t1va3cg1n2d1e0ats2uty4er2rlin4st0buy5t2f1g1h0arti5i0ble3d1ke2ng0o3o1z2j1lack0friday9ockbuster8g1omberg7ue3m0s1w2n0pparibas9o0ats3ehringer8fa2m1nd2o0k0ing5sch2tik2on4t1utique6x2r0adesco6idgestone9oadway5ker3ther5ussels7s1t1uild0ers6siness6y1zz3v1w1y1z0h3ca0b1fe2l0l1vinklein9m0era3p2non3petown5ital0one8r0avan4ds2e0er0s4s2sa1e1h1ino4t0ering5holic7ba1n1re3c1d1enter4o1rn3f0a1d2g1h0anel2nel4rity4se2t2eap3intai5ristmas6ome4urch5i0priani6rcle4sco3tadel4i0c2y3k1l0aims4eaning6ick2nic1que6othing5ud3ub0med6m1n1o0ach3des3ffee4llege4ogne5m0mbank4unity6pany2re3uter5sec4ndos3struction8ulting7tact3ractors9oking4l1p2rsica5untry4pon0s4rses6pa2r0edit0card4union9icket5own3s1uise0s6u0isinella9v1w1x1y0mru3ou3z2dad1nce3ta1e1ing3sun4y2clk3ds2e0al0er2s3gree4livery5l1oitte5ta3mocrat6ntal2ist5si0gn4v2hl2iamonds6et2gital5rect0ory7scount3ver5h2y2j1k1m1np2o0cs1tor4g1mains5t1wnload7rive4tv2ubai3nlop4pont4rban5vag2r2z2earth3t2c0o2deka3u0cation8e1g1mail3erck5nergy4gineer0ing9terprises10pson4quipment8r0icsson6ni3s0q1tate5t1u0rovision8s2vents5xchange6pert3osed4ress5traspace10fage2il1rwinds6th3mily4n0s2rm0ers5shion4t3edex3edback6rrari3ero6i0delity5o2lm2nal1nce1ial7re0stone6mdale6sh0ing5t0ness6j1k1lickr3ghts4r2orist4wers5y2m1o0o0d1tball6rd1ex2sale4um3undation8x2r0ee1senius7l1ogans4ntier7tr2ujitsu5n0d2rniture7tbol5yi3ga0l0lery3o1up4me0s3p1rden4y2b0iz3d0n2e0a1nt0ing5orge5f1g0ee3h1i0ft0s3ves2ing5l0ass3e1obal2o4m0ail3bh2o1x2n1odaddy5ld0point6f2o0dyear5g0le4p1t1v2p1q1r0ainger5phics5tis4een3ipe3ocery4up4s1t1u0cci3ge2ide2tars5ru3w1y2hair2mburg5ngout5us3bo2dfc0bank7ealth0care8lp1sinki6re1mes5iphop4samitsu7tachi5v2k0t2m1n1ockey4ldings5iday5medepot5goods5s0ense7nda3rse3spital5t0ing5t0els3mail5use3w2r1sbc3t1u0ghes5yatt3undai7ibm2cbc2e1u2d1e0ee3fm2kano4l1m0amat4db2mo0bilien9n0c1dustries8finiti5o2g1k1stitute6urance4e4t0ernational10uit4vestments10o1piranga7q1r0ish4s0maili5t0anbul7t0au2v3jaguar4va3cb2e0ep2tzt3welry6io2ll2m0p2nj2o0bs1urg4t1y2p0morgan6rs3uegos4niper7kaufen5ddi3e0rryhotels6properties14fh2g1h1i0a1ds2m1ndle4tchen5wi3m1n1oeln3matsu5sher5p0mg2n2r0d1ed3uokgroup8w1y0oto4z2la0caixa5mborghini8er3nd0rover6xess5salle5t0ino3robe5w0yer5b1c1ds2ease3clerc5frak4gal2o2xus4gbt3i0dl2fe0insurance9style7ghting6ke2lly3mited4o2ncoln4k2ve1ing5k1lc1p2oan0s3cker3us3l1ndon4tte1o3ve3pl0financial11r1s1t0d0a3u0ndbeck6xe1ury5v1y2ma0drid4if1son4keup4n0agement7go3p1rket0ing3s4riott5shalls7ttel5ba2c0kinsey7d1e0d0ia3et2lbourne7me1orial6n0u2rckmsd7g1h1iami3crosoft7l1ni1t2t0subishi9k1l0b1s2m0a2n1o0bi0le4da2e1i1m1nash3ey2ster5rmon3tgage6scow4to0rcycles9v0ie4p1q1r1s0d2t0n1r2u0seum3ic4v1w1x1y1z2na0b1goya4me2vy3ba2c1e0c1t0bank4flix4work5ustar5w0s2xt0direct7us4f0l2g0o2hk2i0co2ke1on3nja3ssan1y5l1o0kia3rton4w0ruz3tv4p1r0a1w2tt2u1yc2z2obi1server7ffice5kinawa6layan0group9lo3m0ega4ne1g1l0ine5oo2pen3racle3nge4g0anic5igins6saka4tsuka4t2vh3pa0ge2nasonic7ris2s1tners4s1y3y2
17764ccw3e0t2f0izer5g1h0armacy6d1ilips5one2to0graphy6s4ysio5ics1tet2ures6d1n0g1k2oneer5zza4k1l0ace2y0station9umbing5s3m1n0c2ohl2ker3litie5rn2st3r0axi3ess3ime3o0d0uctions8f1gressive8mo2perties3y5tection8u0dential9s1t1ub2w0c2y2qa1pon3uebec3st5racing4dio4e0ad1lestate6tor2y4cipes5d0stone5umbrella9hab3ise0n3t2liance6n0t0als5pair3ort3ublican8st0aurant8view0s5xroth6ich0ardli6oh3l1o1p2o0cks3deo3gers4om3s0vp3u0gby3hr2n2w0e2yukyu6sa0arland6fe0ty4kura4le1on3msclub4ung5ndvik0coromant12ofi4p1rl2s1ve2xo3b0i1s2c0b1haeffler7midt4olarships8ol3ule3warz5ience5ot3d1e0arch3t2cure1ity6ek2lect4ner3rvices6ven3w1x0y3fr2g1h0angrila6rp3ell3ia1ksha5oes2p0ping5uji3w3i0lk2na1gles5te3j1k0i0n2y0pe4l0ing4m0art3ile4n0cf3o0ccer3ial4ftbank4ware6hu2lar2utions7ng1y2y2pa0ce3ort2t3r0l2s1t0ada2ples4r1tebank4farm7c0group6ockholm6rage3e3ream4udio2y3yle4u0cks3pplies3y2ort5rf1gery5zuki5v1watch4iss4x1y0dney4stems6z2tab1ipei4lk2obao4rget4tamotors6r2too4x0i3c0i2d0k2eam2ch0nology8l1masek5nnis4va3f1g1h0d1eater2re6iaa2ckets5enda4ps2res2ol4j0maxx4x2k0maxx5l1m0all4n1o0day3kyo3ols3p1ray3shiba5tal3urs3wn2yota3s3r0ade1ing4ining5vel0ers0insurance16ust3v2t1ube2i1nes3shu4v0s2w1z2ua1bank3s2g1k1nicom3versity8o2ol2ps2s1y1z2va0cations7na1guard7c1e0gas3ntures6risign5mögensberater2ung14sicherung10t2g1i0ajes4deo3g1king4llas4n1p1rgin4sa1ion4va1o3laanderen9n1odka3lvo3te1ing3o2yage5u2wales2mart4ter4ng0gou5tch0es6eather0channel12bcam3er2site5d0ding5ibo2r3f1hoswho6ien2ki2lliamhill9n0dows4e1ners6me2olterskluwer11odside6rk0s2ld3w2s1tc1f3xbox3erox4ihuan4n2xx2yz3yachts4hoo3maxun5ndex5e1odobashi7ga2kohama6u0tube6t1un3za0ppos4ra3ero3ip2m1one3uerich6w2",Zde="ελ1υ2бг1ел3дети4ею2католик6ом3мÐ
17764ºÐ´2он1сква6онлайн5рг3рус2ф2сайт3рб3укр3қаз3Õ°Õ¡Õµ3ישראל5קום3ابوظبي5رامكو5لاردن4بحرين5جزائر5سعودية6عليان5مغرب5مارات5یران5بارت2زار4يتك3ھارت5تونس4سودان3رية5شبكة4عراق2ب2مان4فلسطين6قطر3كاثوليك6وم3مصر2ليسيا5وريتانيا7قع4همراه5پاکستان7ڀارت4कॉम3नेट3भारत0म्3ोत5संगठन5বাংলা5ভারত2ৰত4ਭਾਰਤ4ભારત4ଭାରତ4இந்தியா6லங்கை6சிங்கப்பூர்11భారత్5ಭಾರತ4ഭാരതം5ලංකා4คอม3ไทย3ລາວ3გე2みんな3アマゾン4クラウド4グーグル4コム2ストア3セール3ファッション6ポイント4世界2中信1国1國1文网3亚马逊3企业2佛山2信息2健康2八卦2公司1益2台湾1灣2商城1店1标2嘉里0大酒店5在线2大拿2天主教3娱乐2家電2广东2微博2慈善2我爱你3手机2招聘2政务1府2新加坡2闻2时尚2書籍2机构2淡马锡3游戏2澳門2点看2移动2组织机构4网址1店1站1络2联通2谷歌2购物2通販2集团2電訊盈科4飞利浦3食品2餐厅2香格里拉3港2닷넷1ì»´2삼성2한국2",Bb="numeric",Ub="ascii",$b="alpha",_d="asciinumeric",Kc="alphanumeric",Wb="domain",Y5="emoji",eue="scheme",tue="slashscheme",cx="whitespace";function aue(t,e){return t in e||(e[t]=[]),e[t]}function To(t,e,a){e[Bb]&&(e[_d]=!0,e[Kc]=!0),e[Ub]&&(e[_d]=!0,e[$b]=!0),e[_d]&&(e[Kc]=!0),e[$b]&&(e[Kc]=!0),e[Kc]&&(e[Wb]=!0),e[Y5]&&(e[Wb]=!0);for(const n in e){const i=aue(n,a);i.indexOf(t)<0&&i.push(t)}}function nue(t,e){const a={};for(const n in e)e[n].indexOf(t)>=0&&(a[n]=!0);return a}function Sa(t=null){this.j={},this.jr=[],this.jd=null,this.t=t}Sa.groups={};Sa.prototype={accepts(){return!!this.t},go(t){const e=this,a=e.j[t];if(a)return a;for(let n=0;n<e.jr.length;n++){const i=e.jr[n][0],r=e.jr[n][1];if(r&&i.test(t))return r}return e.jd},has(t,e=!1){return e?t in this.j:!!this.go(t)},ta(t,e,a,n){for(let i=0;i<t.length;i++)this.tt(t[i],e,a,n)},tr(t,e,a,n){n=n||Sa.groups;let i;return e&&e.j?i=e:(i=new Sa(e),a&&n&&To(e,a,n)),this.jr.push([t,i]),i},ts(t,e,a,n){let i=this;const r=t.length;if(!r)return i;for(let o=0;o<r-1;o++)i=i.tt(t[o]);return i.tt(t[r-1],e,a,n)},tt(t,e,a,n){n=n||Sa.groups;const i=this;if(e&&e.j)return i.j[t]=e,e;const r=e;let o,l=i.go(t);if(l?(o=new Sa,Object.assign(o.j,l.j),o.jr.push.apply(o.jr,l.jr),o.jd=l.jd,o.t=l.t):o=new Sa,r){if(n)if(o.t&&typeof o.t=="string"){const c=Object.assign(nue(o.t,n),a);To(r,c,n)}else a&&To(r,a,n);o.t=r}return i.j[t]=o,o}};const ye=(t,e,a,n,i)=>t.ta(e,a,n,i),it=(t,e,a,n,i)=>t.tr(e,a,n,i),LT=(t,e,a,n,i)=>t.ts(e,a,n,i),B=(t,e,a,n,i)=>t.tt(e,a,n,i),hi="WORD",Gb="UWORD",Z5="ASCIINUMERICAL",eD="ALPHANUMERICAL",vu="LOCALHOST",Kb="TLD",Jb="UTLD",Wm="SCHEME",Ps="SLASH_SCHEME",SS="NUM",Qb="WS",_S="NL",Ad="OPENBRACE",Ed="CLOSEBRACE",df="OPENBRACKET",uf="CLOSEBRACKET",pf="OPENPAREN",mf="CLOSEPAREN",hf="OPENANGLEBRACKET",ff="CLOSEANGLEBRACKET",gf="FULLWIDTHLEFTPAREN",yf="FULLWIDTHRIGHTPAREN",xf="LEFTCORNERBRACKET",vf="RIGHTCORNERBRACKET",bf="LEFTWHITECORNERBRACKET",wf="RIGHTWHITECORNERBRACKET",kf="FULLWIDTHLESSTHAN",Sf="FULLWIDTHGREATERTHAN",_f="AMPERSAND",Af="APOSTROPHE",Ef="ASTERISK",ir="AT",Cf="BACKSLASH",jf="BACKTICK",Tf="CARET",mr="COLON",AS="COMMA",Nf="DOLLAR",Bn="DOT",If="EQUALS",ES="EXCLAMATION",en="HYPHEN",Cd="PERCENT",Pf="PIPE",Rf="PLUS",Lf="POUND",jd="QUERY",CS="QUOTE",tD="FULLWIDTHMIDDLEDOT",jS="SEMI",Un="SLASH",Td="TILDE",Of="UNDERSCORE",aD="EMOJI",Mf="SYM";var nD=Object.freeze({__proto__:null,ALPHANUMERICAL:eD,AMPERSAND:_f,APOSTROPHE:Af,ASCIINUMERICAL:Z5,ASTERISK:Ef,AT:ir,BACKSLASH:Cf,BACKTICK:jf,CARET:Tf,CLOSEANGLEBRACKET:ff,CLOSEBRACE:Ed,CLOSEBRACKET:uf,CLOSEPAREN:mf,COLON:mr,COMMA:AS,DOLLAR:Nf,DOT:Bn,EMOJI:aD,EQUALS:If,EXCLAMATION:ES,FULLWIDTHGREATERTHAN:Sf,FULLWIDTHLEFTPAREN:gf,FULLWIDTHLESSTHAN:kf,FULLWIDTHMIDDLEDOT:tD,FULLWIDTHRIGHTPAREN:yf,HYPHEN:en,LEFTCORNERBRACKET:xf,LEFTWHITECORNERBRACKET:bf,LOCALHOST:vu,NL:_S,NUM:SS,OPENANGLEBRACKET:hf,OPENBRACE:Ad,OPENBRACKET:df,OPENPAREN:pf,PERCENT:Cd,PIPE:Pf,PLUS:Rf,POUND:Lf,QUERY:jd,QUOTE:CS,RIGHTCORNERBRACKET:vf,RIGHTWHITECORNERBRACKET:wf,SC
vendor: 31,414 bytes, lines 17764-17779
17764HEME:Wm,SEMI:jS,SLASH:Un,SLASH_SCHEME:Ps,SYM:Mf,TILDE:Td,TLD:Kb,UNDERSCORE:Of,UTLD:Jb,UWORD:Gb,WORD:hi,WS:Qb});const pi=/[a-z]/,Rc=new RegExp("\\p{L}","u"),dx=new RegExp("\\p{Emoji}","u"),mi=/\d/,ux=/\s/,OT="\r",px=`
17765`,iue="️",rue="‍",mx="";let rm=null,om=null;function oue(t=[]){const e={};Sa.groups=e;const a=new Sa;rm==null&&(rm=MT(Yde)),om==null&&(om=MT(Zde)),B(a,"'",Af),B(a,"{",Ad),B(a,"}",Ed),B(a,"[",df),B(a,"]",uf),B(a,"(",pf),B(a,")",mf),B(a,"<",hf),B(a,">",ff),B(a,"(",gf),B(a,")",yf),B(a,"「",xf),B(a,"」",vf),B(a,"『",bf),B(a,"』",wf),B(a,"<",kf),B(a,">",Sf),B(a,"&",_f),B(a,"*",Ef),B(a,"@",ir),B(a,"`",jf),B(a,"^",Tf),B(a,":",mr),B(a,",",AS),B(a,"$",Nf),B(a,".",Bn),B(a,"=",If),B(a,"!",ES),B(a,"-",en),B(a,"%",Cd),B(a,"|",Pf),B(a,"+",Rf),B(a,"#",Lf),B(a,"?",jd),B(a,'"',CS),B(a,"/",Un),B(a,";",jS),B(a,"~",Td),B(a,"_",Of),B(a,"\\",Cf),B(a,"・",tD);const n=it(a,mi,SS,{[Bb]:!0});it(n,mi,n);const i=it(n,pi,Z5,{[_d]:!0}),r=it(n,Rc,eD,{[Kc]:!0}),o=it(a,pi,hi,{[Ub]:!0});it(o,mi,i),it(o,pi,o),it(i,mi,i),it(i,pi,i);const l=it(a,Rc,Gb,{[$b]:!0});it(l,pi),it(l,mi,r),it(l,Rc,l),it(r,mi,r),it(r,pi),it(r,Rc,r);const c=B(a,px,_S,{[cx]:!0}),d=B(a,OT,Qb,{[cx]:!0}),u=it(a,ux,Qb,{[cx]:!0});B(a,mx,u),B(d,px,c),B(d,mx,u),it(d,ux,u),B(u,OT),B(u,px),it(u,ux,u),B(u,mx,u);const p=it(a,dx,aD,{[Y5]:!0});B(p,"#"),it(p,dx,p),B(p,iue,p);const m=B(p,rue);B(m,"#"),it(m,dx,p);const h=[[pi,o],[mi,i]],g=[[pi,null],[Rc,l],[mi,r]];for(let y=0;y<rm.length;y++)Xi(a,rm[y],Kb,hi,h);for(let y=0;y<om.length;y++)Xi(a,om[y],Jb,Gb,g);To(Kb,{tld:!0,ascii:!0},e),To(Jb,{utld:!0,alpha:!0},e),Xi(a,"file",Wm,hi,h),Xi(a,"mailto",Wm,hi,h),Xi(a,"http",Ps,hi,h),Xi(a,"https",Ps,hi,h),Xi(a,"ftp",Ps,hi,h),Xi(a,"ftps",Ps,hi,h),To(Wm,{scheme:!0,ascii:!0},e),To(Ps,{slashscheme:!0,ascii:!0},e),t=t.sort((y,x)=>y[0]>x[0]?1:-1);for(let y=0;y<t.length;y++){const x=t[y][0],w=t[y][1]?{[eue]:!0}:{[tue]:!0};x.indexOf("-")>=0?w[Wb]=!0:pi.test(x)?mi.test(x)?w[_d]=!0:w[Ub]=!0:w[Bb]=!0,LT(a,x,x,w)}return LT(a,"localhost",vu,{ascii:!0}),a.jd=new Sa(Mf),{start:a,tokens:Object.assign({groups:e},nD)}}function iD(t,e){const a=sue(e.replace(/[A-Z]/g,l=>l.toLowerCase())),n=a.length,i=[];let r=0,o=0;for(;o<n;){let l=t,c=null,d=0,u=null,p=-1,m=-1;for(;o<n&&(c=l.go(a[o]));)l=c,l.accepts()?(p=0,m=0,u=l):p>=0&&(p+=a[o].length,m++),d+=a[o].length,r+=a[o].length,o++;r-=p,o-=m,d-=p,i.push({t:u.t,v:e.slice(r-d,r),s:r-d,e:r})}return i}function sue(t){const e=[],a=t.length;let n=0;for(;n<a;){let i=t.charCodeAt(n),r,o=i<55296||i>56319||n+1===a||(r=t.charCodeAt(n+1))<56320||r>57343?t[n]:t.slice(n,n+2);e.push(o),n+=o.length}return e}function Xi(t,e,a,n,i){let r;const o=e.length;for(let l=0;l<o-1;l++){const c=e[l];t.j[c]?r=t.j[c]:(r=new Sa(n),r.jr=i.slice(),t.j[c]=r),t=r}return r=new Sa(a),r.jr=i.slice(),t.j[e[o-1]]=r,r}function MT(t){const e=[],a=[];let n=0,i="0123456789";for(;n<t.length;){let r=0;for(;i.indexOf(t[n+r])>=0;)r++;if(r>0){e.push(a.join(""));for(let o=parseInt(t.substring(n,n+r),10);o>0;o--)a.pop();n+=r}else a.push(t[n]),n++}return e}const bu={defaultProtocol:"http",events:null,format:DT,formatHref:DT,nl2br:!1,tagName:"a",target:null,rel:null,validate:!0,truncate:1/0,className:null,attributes:null,ignoreTags:[],render:null};function TS(t,e=null){let a=Object.assign({},bu);t&&(a=Object.assign(a,t instanceof TS?t.o:t));const n=a.ignoreTags,i=[];for(let r=0;r<n.length;r++)i.push(n[r].toUpperCase());this.o=a,e&&(this.defaultRender=e),this.ignoreTags=i}TS.prototype={o:bu,ignoreTags:[],defaultRender(t){return t},check(t){return this.get("validate",t.toString(),t)},get(t,e,a){const n=e!=null;let i=this.o[t];return i&&(typeof i=="object"?(i=a.t in i?i[a.t]:bu[t],typeof i=="function"&&n&&(i=i(e,a))):typeof i=="function"&&n&&(i=i(e,a.t,a)),i)},getObj(t,e,a){let n=this.o[t];return typeof n=="function"&&e!=null&&(n=n(e,a.t,a)),n},render(t){const e=t.render(this);return(this.get("render",null,t)||this.defaultRender)(e,t.t,t)}};function DT(t){return t}function rD(t,e){this.t="token",this.v=t,this.tk=e}rD.prototype={isLink:!1,toString(){return this.v},toHref(t){return this.toString()},toFormattedString(t){const e=this.toString(),a=t.get("truncate",e,this),n=t.get("format",e,this);return a&&n.length>a?n.substring(0,a)+"…":n},toFormattedHref(t){return t.get("formatHref",this.toHref(t.get("defaultProtocol")),this)},startIndex(){return this.tk[0].s},endIndex(){return this.tk[this.tk.length-1].e},toObject(t=bu.defaultProtocol){return{type:this.t,value:this.toString(),isLink:this.isLink,href:this.toHref(t),start:this.startIndex(),end:this.endIndex()}},toFormattedObject(t){return{type:this.t,value:this.toFormattedString(t),isLink:this.isLink,href:this.toFormattedHref(t),start:this.startIndex(),end:this.endIndex()}},validate(t){return t.get("validate",this.toString(),this)},render(t){const e=this,a=this.toHref(t.get("defaultProtocol")),n=t.get("formatHref",a,this),i=t.get("tagName",a,e),r=this.toFormattedString(t),o={},l=t.get("className",a,e),c=t.get("target",a,e),d=t.get("rel",a,e),u=t.getObj("attributes",a,e),p=t.getObj("events",a,e);return o.href=n,l&&(o.class=l),c&&(o.target=c),d&&(o.rel=d),u&&Object.assign(o,u),{tagName:i,attributes:o,content:r,eventListeners:p}}};function Yg(t,e){class a extends rD{constructor(i,r){super(i,r),this.t=t}}for(const n in e)a.prototype[n]=e[n];return a.t=t,a}const qT=Yg("email",{isLink:!0,toHref(){return"mailto:"+this.toString()}}),zT=Yg("text"),lue=Yg("nl"),sm=Yg("url",{isLink:!0,toHref(t=bu.defaultProtocol){return this.hasProtocol()?this.v:`${t}://${this.v}`},hasProtocol(){const t=this.tk;return t.length>=2&&t[0].t!==vu&&t[1].t===mr}}),Ya=t=>new Sa(t);function cue({groups:t}){const e=t.domain.concat([_f,Ef,ir,Cf,jf,Tf,Nf,If,en,SS,Cd,Pf,Rf,Lf,Un,Mf,Td,Of]),a=[Af,mr,AS,Bn,ES,Cd,jd,CS,jS,hf,ff,Ad,Ed,uf,df,pf,mf,gf,yf,xf,vf,bf,wf,kf,Sf],n=[_f,Af,Ef,Cf,jf,Tf,Nf,If,en,Ad,Ed,Cd,Pf,Rf,Lf,jd,Un,Mf,Td,Of],i=Ya(),r=B(i,Td);ye(r,n,r),ye(r,t.domain,r);const o=Ya(),l=Ya(),c=Ya();ye(i,t.domain,o),ye(i,t.scheme,l),ye(i,t.slashscheme,c),ye(o,n,r),ye(o,t.domain,o);const d=B(o,ir);B(r,ir,d),B(l,ir,d),B(c,ir,d);const u=B(r,Bn);ye(u,n,r),ye(u,t.domain,r);const p=Ya();ye(d,t.domain,p),ye(p,t.domain,p);const m=B(p,Bn);ye(m,t.domain,p);const h=Ya(qT);ye(m,t.tld,h),ye(m,t.utld,h),B(d,vu,h);const g=B(p,en);B(g,en,g),ye(g,t.domain,p),ye(h,t.domain,p),B(h,Bn,m),B(h,en,g);const y=B(h,mr);ye(y,t.numeric,qT);const x=B(o,en),v=B(o,Bn);B(x,en,x),ye(x,t.domain,o),ye(v,n,r),ye(v,t.domain,o);const w=Ya(sm);ye(v,t.tld,w),ye(v,t.utld,w),ye(w,t.domain,o),ye(w,n,r),B(w,Bn,v),B(w,en,x),B(w,ir,d);const S=B(w,mr),T=Ya(sm);ye(S,t.numeric,T);const P=Ya(sm),M=Ya();ye(P,e,P),ye(P,a,M),ye(M,e,P),ye(M,a,M),B(w,Un,P),B(T,Un,P);const C=B(l,mr),E=B(c,mr),j=B(E,Un),N=B(j,Un);ye(l,t.domain,o),B(l,Bn,v),B(l,en,x),ye(c,t.domain,o),B(c,Bn,v),B(c,en,x),ye(C,t.domain,P),B(C,Un,P),B(C,jd,P),ye(N,t.domain,P),ye(N,e,P),B(N,Un,P);const L=[[Ad,Ed],[df,uf],[pf,mf],[hf,ff],[gf,yf],[xf,vf],[bf,wf],[kf,Sf]];for(let O=0;O<L.length;O++){const[R,G]=L[O],ee=B(P,R);B(M,R,ee),B(ee,G,P);const ke=Ya(sm);ye(ee,e,ke);const ae=Ya();ye(ee,a),ye(ke,e,ke),ye(ke,a,ae),ye(ae,e,ke),ye(ae,a,ae),B(ke,G,P),B(ae,G,P)}return B(i,vu,w),B(i,_S,lue),{start:i,tokens:nD}}function due(t,e,a){let n=a.length,i=0,r=[],o=[];for(;i<n;){let l=t,c=null,d=null,u=0,p=null,m=-1;for(;i<n&&!(c=l.go(a[i].t));)o.push(a[i++]);for(;i<n&&(d=c||l.go(a[i].t));)c=null,l=d,l.accepts()?(m=0,p=l):m>=0&&m++,i++,u++;if(m<0)i-=u,i<n&&(o.push(a[i]),i++);else{o.length>0&&(r.push(hx(zT,e,o)),o=[]),i-=m,u-=m;const h=p.t,g=a.slice(i-u,i);r.push(hx(h,e,g))}}return o.length>0&&r.push(hx(zT,e,o)),r}function hx(t,e,a){const n=a[0].s,i=a[a.length-1].e,r=e.slice(n,i);return new t(r,a)}const uue=typeof console<"u"&&console&&console.warn||(()=>{}),pue="until manual call of linkify.init(). Register all schemes and plugins before invoking linkify the first time.",Be={scanner:null,parser:null,tokenQueue:[],pluginQueue:[],customSchemes:[],initialized:!1};function mue(){return Sa.groups={},Be.scanner=null,Be.parser=null,Be.tokenQueue=[],Be.pluginQueue=[],Be.customSchemes=[],Be.initialized=!1,Be}function VT(t,e=!1){if(Be.initialized&&uue(`linkifyjs: already initialized - will not register custom scheme "${t}" ${pue}`),!/^[0-9a-z]+(-[0-9a-z]+)*$/.test(t))throw new Error(`linkifyjs: incorrect scheme format.
177661. Must only contain digits, lowercase ASCII letters or "-"
177672. Cannot start or end with "-"
177683. "-" cannot repeat`);Be.customSchemes.push([t,e])}function hue(){Be.scanner=oue(Be.customSchemes);for(let t=0;t<Be.tokenQueue.length;t++)Be.tokenQueue[t][1]({scanner:Be.scanner});Be.parser=cue(Be.scanner.tokens);for(let t=0;t<Be.pluginQueue.length;t++)Be.pluginQueue[t][1]({scanner:Be.scanner,parser:Be.parser});return Be.initialized=!0,Be}function NS(t){return Be.initialized||hue(),due(Be.parser.start,t,iD(Be.scanner.start,t))}NS.scan=iD;function oD(t,e=null,a=null){if(e&&typeof e=="object"){if(a)throw Error(`linkifyjs: Invalid link type ${e}; must be a string`);a=e,e=null}const n=new TS(a),i=NS(t),r=[];for(let o=0;o<i.length;o++){const l=i[o];l.isLink&&(!e||l.t===e)&&n.check(l)&&r.push(l.toFormattedObject(n))}return r}var IS="[\0-   ᠎ -\u2029  ]",fue=new RegExp(IS),gue=new RegExp(`${IS}$`),yue=new RegExp(IS,"g");function xue(t){return t.length===1?t[0].isLink:t.length===3&&t[1].isLink?["()","[]"].includes(t[0].value+t[2].value):!1}function vue(t){return new at({key:new _t("autolink"),appendTransaction:(e,a,n)=>{const i=e.some(d=>d.docChanged)&&!a.doc.eq(n.doc),r=e.some(d=>d.getMeta("preventAutolink"));if(!i||r)return;const{tr:o}=n,l=w5(a.doc,[...e]);if(j5(l).forEach(({newRange:d})=>{const u=cle(n.doc,d,h=>h.isTextblock);let p,m;if(u.length>1)p=u[0],m=n.doc.textBetween(p.pos,p.pos+p.node.nodeSize,void 0," ");else if(u.length){const h=n.doc.textBetween(d.from,d.to," "," ");if(!gue.test(h))return;p=u[0],m=n.doc.textBetween(p.pos,d.to,void 0," ")}if(p&&m){const h=m.split(fue).filter(Boolean);if(h.length<=0)return!1;const g=h[h.length-1],y=p.pos+m.lastIndexOf(g);if(!g)return!1;const x=NS(g).map(v=>v.toObject(t.defaultProtocol));if(!xue(x))return!1;x.filter(v=>v.isLink).map(v=>({...v,from:y+v.start+1,to:y+v.end+1})).filter(v=>n.schema.marks.code?!n.doc.rangeHasMark(v.from,v.to,n.schema.marks.code):!0).filter(v=>t.validate(v.value)).filter(v=>t.shouldAutoLink(v.value)).forEach(v=>{xS(v.from,v.to,n.doc).some(w=>w.mark.type===t.type)||o.addMark(v.from,v.to,t.type.create({href:v.href}))})}}),!!o.steps.length)return o}})}function bue(t){return new at({key:new _t("handleClickLink"),props:{handleClick:(e,a,n)=>{var i,r;if(n.button!==0||!e.editable)return!1;let o=null;if(n.target instanceof HTMLAnchorElement)o=n.target;else{const c=n.target;if(!c)return!1;const d=t.editor.view.dom;o=c.closest("a"),o&&!d.contains(o)&&(o=null)}if(!o)return!1;let l=!1;if(t.enableClickSelection&&(l=t.editor.commands.extendMarkRange(t.type.name)),t.openOnClick){const c=C5(e.state,t.type.name),d=(i=o.href)!=null?i:c.href,u=(r=o.target)!=null?r:c.target;d&&(window.open(d,u),l=!0)}return l}}})}function wue(t){return new at({key:new _t("handlePasteLink"),props:{handlePaste:(e,a,n)=>{const{shouldAutoLink:i}=t,{state:r}=e,{selection:o}=r,{empty:l}=o;if(l)return!1;let c="";n.content.forEach(u=>{c+=u.textContent});const d=oD(c,{defaultProtocol:t.defaultProtocol}).find(u=>u.isLink&&u.value===c);return!c||!d||i!==void 0&&!i(d.value)?!1:t.editor.commands.setMark(t.type,{href:d.href})}}})}function uo(t,e){const a=["http","https","ftp","ftps","mailto","tel","callto","sms","cid","xmpp"];return e&&e.forEach(n=>{const i=typeof n=="string"?n:n.scheme;i&&a.push(i)}),!t||t.replace(yue,"").match(new RegExp(`^(?:(?:${a.join("|")}):|[^a-z]|[a-z0-9+.-]+(?:[^a-z+.-:]|$))`,"i"))}var kue=ao.create({name:"link",priority:1e3,keepOnSplit:!1,exitable:!0,onCreate(){this.options.validate&&!this.options.shouldAutoLink&&(this.options.shouldAutoLink=this.options.validate,console.warn("The `validate` option is deprecated. Rename to the `shouldAutoLink` option instead.")),this.options.protocols.forEach(t=>{if(typeof t=="string"){VT(t);return}VT(t.scheme,t.optionalSlashes)})},onDestroy(){mue()},inclusive(){return this.options.autolink},addOptions(){return{openOnClick:!0,enableClickSelection:!1,linkOnPaste:!0,autolink:!0,protocols:[],defaultProtocol:"http",HTMLAttributes:{target:"_blank",rel:"noopener noreferrer nofollow",class:null},isAllowedUri:(t,e)=>!!uo(t,e.protocols),validate:t=>!!t,shouldAutoLink:t=>{const e=/^[a-z][a-z0-9+.-]*:\/\//i.test(t),a=/^[a-z][a-z0-9+.-]*:/i.test(t);if(e||a&&!t.includes("@"))return!0;const i=(t.includes("@")?t.split("@").pop():t).split(/[/?#:]/)[0];return!(/^\d{1,3}(\.\d{1,3}){3}$/.test(i)||!/\./.test(i))}}},addAttributes(){return{href:{default:null,parseHTML(t){return t.getAttribute("href")}},target:{default:this.options.HTMLAttributes.target},rel:{default:this.options.HTMLAttributes.rel},class:{default:this.options.HTMLAttributes.class}}},parseHTML(){return[{tag:"a[href]",getAttrs:t=>{const e=t.getAttribute("href");return!e||!this.options.isAllowedUri(e,{defaultValidate:a=>!!uo(a,this.options.protocols),protocols:this.options.protocols,defaultProtocol:this.options.defaultProtocol})?!1:null}}]},renderHTML({HTMLAttributes:t}){return this.options.isAllowedUri(t.href,{defaultValidate:e=>!!uo(e,this.options.protocols),protocols:this.options.protocols,defaultProtocol:this.options.defaultProtocol})?["a",ct(this.options.HTMLAttributes,t),0]:["a",ct(this.options.HTMLAttributes,{...t,href:""}),0]},markdownTokenName:"link",parseMarkdown:(t,e)=>e.applyMark("link",e.parseInline(t.tokens||[]),{href:t.href,title:t.title||null}),renderMarkdown:(t,e)=>{var a;const n=((a=t.attrs)==null?void 0:a.href)||"";return`[${e.renderChildren(t)}](${n})`},addCommands(){return{setLink:t=>({chain:e})=>{const{href:a}=t;return this.options.isAllowedUri(a,{defaultValidate:n=>!!uo(n,this.options.protocols),protocols:this.options.protocols,defaultProtocol:this.options.defaultProtocol})?e().setMark(this.name,t).setMeta("preventAutolink",!0).run():!1},toggleLink:t=>({chain:e})=>{const{href:a}=t||{};return a&&!this.options.isAllowedUri(a,{defaultValidate:n=>!!uo(n,this.options.protocols),protocols:this.options.protocols,defaultProtocol:this.options.defaultProtocol})?!1:e().toggleMark(this.name,t,{extendEmptyMarkRange:!0}).setMeta("preventAutolink",!0).run()},unsetLink:()=>({chain:t})=>t().unsetMark(this.name,{extendEmptyMarkRange:!0}).setMeta("preventAutolink",!0).run()}},addPasteRules(){return[ss({find:t=>{const e=[];if(t){const{protocols:a,defaultProtocol:n}=this.options,i=oD(t).filter(r=>r.isLink&&this.options.isAllowedUri(r.value,{defaultValidate:o=>!!uo(o,a),protocols:a,defaultProtocol:n}));i.length&&i.forEach(r=>{this.options.shouldAutoLink(r.value)&&e.push({text:r.value,data:{href:r.href},index:r.start})})}return e},type:this.type,getAttributes:t=>{var e;return{href:(e=t.data)==null?void 0:e.href}}})]},addProseMirrorPlugins(){const t=[],{protocols:e,defaultProtocol:a}=this.options;return this.options.autolink&&t.push(vue({type:this.type,defaultProtocol:this.options.defaultProtocol,validate:n=>this.options.isAllowedUri(n,{defaultValidate:i=>!!uo(i,e),protocols:e,defaultProtocol:a}),shouldAutoLink:this.options.shouldAutoLink})),t.push(bue({type:this.type,editor:this.editor,openOnClick:this.options.openOnClick==="whenNotEditable"?!0:this.options.openOnClick,enableClickSelection:this.options.enableClickSelection})),this.options.linkOnPaste&&t.push(wue({editor:this.editor,defaultProtocol:this.options.defaultProtocol,type:this.type,shouldAutoLink:this.options.shouldAutoLink})),t}}),Sue=Object.defineProperty,_ue=(t,e)=>{for(var a in e)Sue(t,a,{get:e[a],enumerable:!0})},Aue="listItem",HT="textStyle",FT=/^\s*([-+*])\s$/,sD=Oa.create({name:"bulletList",addOptions(){return{itemTypeName:"listItem",HTMLAttributes:{},keepMarks:!1,keepAttributes:!1}},group:"block list",content(){return`${this.options.itemTypeName}+`},parseHTML(){return[{tag:"ul"}]},renderHTML({HTMLAttributes:t}){return["ul",ct(this.options.HTMLAttributes,t),0]},markdownTokenName:"list",parseMarkdown:(t,e)=>t.type!=="list"||t.ordered?[]:{type:"bulletList",content:t.items?e.parseChildren(t.items):[]},renderMarkdown:(t,e)=>t.content?e.renderChildren(t.content,`
17769`):"",markdownOptions:{indentsContent:!0},addCommands(){return{toggleBulletList:()=>({commands:t,chain:e})=>this.options.keepAttributes?e().toggleList(this.name,this.options.itemTypeName,this.options.keepMarks).updateAttributes(Aue,this.editor.getAttributes(HT)).run():t.toggleList(this.name,this.options.itemTypeName,this.options.keepMarks)}},addKeyboardShortcuts(){return{"Mod-Shift-8":()=>this.editor.commands.toggleBulletList()}},addInputRules(){let t=Dl({find:FT,type:this.type});return(this.options.keepMarks||this.options.keepAttributes)&&(t=Dl({find:FT,type:this.type,keepMarks:this.options.keepMarks,keepAttributes:this.options.keepAttributes,getAttributes:()=>this.editor.getAttributes(HT),editor:this.editor})),[t]}}),lD=Oa.create({name:"listItem",addOptions(){return{HTMLAttributes:{},bulletListTypeName:"bulletList",orderedListTypeName:"orderedList"}},content:"paragraph block*",defining:!0,parseHTML(){return[{tag:"li"}]},renderHTML({HTMLAttributes:t}){return["li",ct(this.options.HTMLAttributes,t),0]},markdownTokenName:"list_item",parseMarkdown:(t,e)=>{if(t.type!=="list_item")return[];let a=[];if(t.tokens&&t.tokens.length>0)if(t.tokens.some(i=>i.type==="paragraph"))a=e.parseChildren(t.tokens);else{const i=t.tokens[0];if(i&&i.type==="text"&&i.tokens&&i.tokens.length>0){if(a=[{type:"paragraph",content:e.parseInline(i.tokens)}],t.tokens.length>1){const o=t.tokens.slice(1),l=e.parseChildren(o);a.push(...l)}}else a=e.parseChildren(t.tokens)}return a.length===0&&(a=[{type:"paragraph",content:[]}]),{type:"listItem",content:a}},renderMarkdown:(t,e,a)=>kS(t,e,n=>n.parentType==="bulletList"?"- ":n.parentType==="orderedList"?`${n.index+1}. `:"- ",a),addKeyboardShortcuts(){return{Enter:()=>this.editor.commands.splitListItem(this.name),Tab:()=>this.editor.commands.sinkListItem(this.name),"Shift-Tab":()=>this.editor.commands.liftListItem(this.name)}}}),Eue={};_ue(Eue,{findListItemPos:()=>Qu,getNextListDepth:()=>PS,handleBackspace:()=>Xb,handleDelete:()=>Yb,hasListBefore:()=>cD,hasListItemAfter:()=>Cue,hasListItemBefore:()=>dD,listItemHasSubList:()=>uD,nextListIsDeeper:()=>pD,nextListIsHigher:()=>mD});var Qu=(t,e)=>{const{$from:a}=e.selection,n=vt(t,e.schema);let i=null,r=a.depth,o=a.pos,l=null;for(;r>0&&l===null;)i=a.node(r),i.type===n?l=r:(r-=1,o-=1);return l===null?null:{$pos:e.doc.resolve(o),depth:l}},PS=(t,e)=>{const a=Qu(t,e);if(!a)return!1;const[,n]=ble(e,t,a.$pos.pos+4);return n},cD=(t,e,a)=>{const{$anchor:n}=t.selection,i=Math.max(0,n.pos-2),r=t.doc.resolve(i).node();return!(!r||!a.includes(r.type.name))},dD=(t,e)=>{var a;const{$anchor:n}=e.selection,i=e.doc.resolve(n.pos-2);return!(i.index()===0||((a=i.nodeBefore)==null?void 0:a.type.name)!==t)},uD=(t,e,a)=>{if(!a)return!1;const n=vt(t,e.schema);let i=!1;return a.descendants(r=>{r.type===n&&(i=!0)}),i},Xb=(t,e,a)=>{if(t.commands.undoInputRule())return!0;if(t.state.selection.from!==t.state.selection.to)return!1;if(!$r(t.state,e)&&cD(t.state,e,a)){const{$anchor:l}=t.state.selection,c=t.state.doc.resolve(l.before()-1),d=[];c.node().descendants((m,h)=>{m.type.name===e&&d.push({node:m,pos:h})});const u=d.at(-1);if(!u)return!1;const p=t.state.doc.resolve(c.start()+u.pos+1);return t.chain().cut({from:l.start()-1,to:l.end()+1},p.end()).joinForward().run()}if(!$r(t.state,e)||!_le(t.state))return!1;const n=Qu(e,t.state);if(!n)return!1;const r=t.state.doc.resolve(n.$pos.pos-2).node(n.depth),o=uD(e,t.state,r);return dD(e,t.state)&&!o?t.commands.joinItemBackward():t.chain().liftListItem(e).run()},pD=(t,e)=>{const a=PS(t,e),n=Qu(t,e);return!n||!a?!1:a>n.depth},mD=(t,e)=>{const a=PS(t,e),n=Qu(t,e);return!n||!a?!1:a<n.depth},Yb=(t,e)=>{if(!$r(t.state,e)||!Sle(t.state,e))return!1;const{selection:a}=t.state,{$from:n,$to:i}=a;return!a.empty&&n.sameParent(i)?!1:pD(e,t.state)?t.chain().focus(t.state.selection.from+4).lift(e).joinBackward().run():mD(e,t.state)?t.chain().joinForward().joinBackward().run():t.commands.joinItemForward()},Cue=(t,e)=>{var a;const{$anchor:n}=e.selection,i=e.doc.resolve(n.pos-n.parentOffset-2);return!(i.index()===i.parent.childCount-1||((a=i.nodeAfter)==null?void 0:a.type.name)!==t)},hD=ze.create({name:"listKeymap",addOptions(){return{listTypes:[{itemName:"listItem",wrapperNames:["bulletList","orderedList"]},{itemName:"taskItem",wrapperNames:["taskList"]}]}},addKeyboardShortcuts(){return{Delete:({editor:t})=>{let e=!1;return this.options.listTypes.forEach(({itemName:a})=>{t.state.schema.nodes[a]!==void 0&&Yb(t,a)&&(e=!0)}),e},"Mod-Delete":({editor:t})=>{let e=!1;return this.options.listTypes.forEach(({itemName:a})=>{t.state.schema.nodes[a]!==void 0&&Yb(t,a)&&(e=!0)}),e},Backspace:({editor:t})=>{let e=!1;return this.options.listTypes.forEach(({itemName:a,wrapperNames:n})=>{t.state.schema.nodes[a]!==void 0&&Xb(t,a,n)&&(e=!0)}),e},"Mod-Backspace":({editor:t})=>{let e=!1;return this.options.listTypes.forEach(({itemName:a,wrapperNames:n})=>{t.state.schema.nodes[a]!==void 0&&Xb(t,a,n)&&(e=!0)}),e}}}}),BT=/^(\s*)(\d+)\.\s+(.*)$/,jue=/^\s/;function Tue(t){const e=[];let a=0,n=0;for(;a<t.length;){const i=t[a],r=i.match(BT);if(!r)break;const[,o,l,c]=r,d=o.length;let u=c,p=a+1;const m=[i];for(;p<t.length;){const h=t[p];if(h.match(BT))break;if(h.trim()==="")m.push(h),u+=`
17770`,p+=1;else if(h.match(jue))m.push(h),u+=`
17771${h.slice(d+2)}`,p+=1;else break}e.push({indent:d,number:parseInt(l,10),content:u.trim(),raw:m.join(`
17772`)}),n=p,a=p}return[e,n]}function fD(t,e,a){var n;const i=[];let r=0;for(;r<t.length;){const o=t[r];if(o.indent===e){const l=o.content.split(`
17773`),c=((n=l[0])==null?void 0:n.trim())||"",d=[];c&&d.push({type:"paragraph",raw:c,tokens:a.inlineTokens(c)});const u=l.slice(1).join(`
17774`).trim();if(u){const h=a.blockTokens(u);d.push(...h)}let p=r+1;const m=[];for(;p<t.length&&t[p].indent>e;)m.push(t[p]),p+=1;if(m.length>0){const h=Math.min(...m.map(y=>y.indent)),g=fD(m,h,a);d.push({type:"list",ordered:!0,start:m[0].number,items:g,raw:m.map(y=>y.raw).join(`
17775`)})}i.push({type:"list_item",raw:o.raw,tokens:d}),r=p}else r+=1}return i}function Nue(t,e){return t.map(a=>{if(a.type!=="list_item")return e.parseChildren([a])[0];const n=[];return a.tokens&&a.tokens.length>0&&a.tokens.forEach(i=>{if(i.type==="paragraph"||i.type==="list"||i.type==="blockquote"||i.type==="code")n.push(...e.parseChildren([i]));else if(i.type==="text"&&i.tokens){const r=e.parseChildren([i]);n.push({type:"paragraph",content:r})}else{const r=e.parseChildren([i]);r.length>0&&n.push(...r)}}),{type:"listItem",content:n}})}var Iue="listItem",UT="textStyle",$T=/^(\d+)\.\s$/,gD=Oa.create({name:"orderedList",addOptions(){return{itemTypeName:"listItem",HTMLAttributes:{},keepMarks:!1,keepAttributes:!1}},group:"block list",content(){return`${this.options.itemTypeName}+`},addAttributes(){return{start:{default:1,parseHTML:t=>t.hasAttribute("start")?parseInt(t.getAttribute("start")||"",10):1},type:{default:null,parseHTML:t=>t.getAttribute("type")}}},parseHTML(){return[{tag:"ol"}]},renderHTML({HTMLAttributes:t}){const{start:e,...a}=t;return e===1?["ol",ct(this.options.HTMLAttributes,a),0]:["ol",ct(this.options.HTMLAttributes,t),0]},markdownTokenName:"list",parseMarkdown:(t,e)=>{if(t.type!=="list"||!t.ordered)return[];const a=t.start||1,n=t.items?Nue(t.items,e):[];return a!==1?{type:"orderedList",attrs:{start:a},content:n}:{type:"orderedList",content:n}},renderMarkdown:(t,e)=>t.content?e.renderChildren(t.content,`
17776`):"",markdownTokenizer:{name:"orderedList",level:"block",start:t=>{const e=t.match(/^(\s*)(\d+)\.\s+/),a=e==null?void 0:e.index;return a!==void 0?a:-1},tokenize:(t,e,a)=>{var n;const i=t.split(`
17777`),[r,o]=Tue(i);if(r.length===0)return;const l=fD(r,0,a);return l.length===0?void 0:{type:"list",ordered:!0,start:((n=r[0])==null?void 0:n.number)||1,items:l,raw:i.slice(0,o).join(`
17778`)}}},markdownOptions:{indentsContent:!0},addCommands(){return{toggleOrderedList:()=>({commands:t,chain:e})=>this.options.keepAttributes?e().toggleList(this.name,this.options.itemTypeName,this.options.keepMarks).updateAttributes(Iue,this.editor.getAttributes(UT)).run():t.toggleList(this.name,this.options.itemTypeName,this.options.keepMarks)}},addKeyboardShortcuts(){return{"Mod-Shift-7":()=>this.editor.commands.toggleOrderedList()}},addInputRules(){let t=Dl({find:$T,type:this.type,getAttributes:e=>({start:+e[1]}),joinPredicate:(e,a)=>a.childCount+a.attrs.start===+e[1]});return(this.options.keepMarks||this.options.keepAttributes)&&(t=Dl({find:$T,type:this.type,keepMarks:this.options.keepMarks,keepAttributes:this.options.keepAttributes,getAttributes:e=>({start:+e[1],...this.editor.getAttributes(UT)}),joinPredicate:(e,a)=>a.childCount+a.attrs.start===+e[1],editor:this.editor})),[t]}}),Pue=/^\s*(\[([( |x])?\])\s$/,Rue=Oa.create({name:"taskItem",addOptions(){return{nested:!1,HTMLAttributes:{},taskListTypeName:"taskList",a11y:void 0}},content(){return this.options.nested?"paragraph block*":"paragraph+"},defining:!0,addAttributes(){return{checked:{default:!1,keepOnSplit:!1,parseHTML:t=>{const e=t.getAttribute("data-checked");return e===""||e==="true"},renderHTML:t=>({"data-checked":t.checked})}}},parseHTML(){return[{tag:`li[data-type="${this.name}"]`,priority:51}]},renderHTML({node:t,HTMLAttributes:e}){return["li",ct(this.options.HTMLAttributes,e,{"data-type":this.name}),["label",["input",{type:"checkbox",checked:t.attrs.checked?"checked":null}],["span"]],["div",0]]},parseMarkdown:(t,e)=>{const a=[];if(t.tokens&&t.tokens.length>0?a.push(e.createNode("paragraph",{},e.parseInline(t.tokens))):t.text?a.push(e.createNode("paragraph",{},[e.createNode("text",{text:t.text})])):a.push(e.createNode("paragraph",{},[])),t.nestedTokens&&t.nestedTokens.length>0){const n=e.parseChildren(t.nestedTokens);a.push(...n)}return e.createNode("taskItem",{checked:t.checked||!1},a)},renderMarkdown:(t,e)=>{var a;const i=`- [${(a=t.attrs)!=null&&a.checked?"x":" "}] `;return kS(t,e,i)},addKeyboardShortcuts(){const t={Enter:()=>this.editor.commands.splitListItem(this.name),"Shift-Tab":()=>this.editor.commands.liftListItem(this.name)};return this.options.nested?{...t,Tab:()=>this.editor.commands.sinkListItem(this.name)}:t},addNodeView(){return({node:t,HTMLAttributes:e,getPos:a,editor:n})=>{const i=document.createElement("li"),r=document.createElement("label"),o=document.createElement("span"),l=document.createElement("input"),c=document.createElement("div"),d=p=>{var m,h;l.ariaLabel=((h=(m=this.options.a11y)==null?void 0:m.checkboxLabel)==null?void 0:h.call(m,p,l.checked))||`Task item checkbox for ${p.textContent||"empty task item"}`};d(t),r.contentEditable="false",l.type="checkbox",l.addEventListener("mousedown",p=>p.preventDefault()),l.addEventListener("change",p=>{if(!n.isEditable&&!this.options.onReadOnlyChecked){l.checked=!l.checked;return}const{checked:m}=p.target;n.isEditable&&typeof a=="function"&&n.chain().focus(void 0,{scrollIntoView:!1}).command(({tr:h})=>{const g=a();if(typeof g!="number")return!1;const y=h.doc.nodeAt(g);return h.setNodeMarkup(g,void 0,{...y==null?void 0:y.attrs,checked:m}),!0}).run(),!n.isEditable&&this.options.onReadOnlyChecked&&(this.options.onReadOnlyChecked(t,m)||(l.checked=!l.checked))}),Object.entries(this.options.HTMLAttributes).forEach(([p,m])=>{i.setAttribute(p,m)}),i.dataset.checked=t.attrs.checked,l.checked=t.attrs.checked,r.append(l,o),i.append(r,c),Object.entries(e).forEach(([p,m])=>{i.setAttribute(p,m)});let u=new Set(Object.keys(e));return{dom:i,contentDOM:c,update:p=>{if(p.type!==this.type)return!1;i.dataset.checked=p.attrs.checked,l.checked=p.attrs.checked,d(p);const m=n.extensionManager.attributes,h=xu(p,m),g=new Set(Object.keys(h)),y=this.options.HTMLAttributes;return u.forEach(x=>{g.has(x)||(x in y?i.setAttribute(x,y[x]):i.removeAttribute(x))}),Object.entries(h).forEach(([x,v])=>{v==null?x in y?i.setAttribute(x,y[x]):i.removeAttribute(x):i.setAttribute(x,v)}),u=g,!0}}}},addInputRules(){return[Dl({find:Pue,type:this.type,getAttributes:t=>({checked:t[t.length-1]==="x"})})]}}),Lue=Oa.create({name:"taskList",addOptions(){return{itemTypeName:"taskItem",HTMLAttributes:{}}},group:"block list",content(){return`${this.options.itemTypeName}+`},parseHTML(){return[{tag:`ul[data-type="${this.name}"]`,priority:51}]},renderHTML({HTMLAttributes:t}){return["ul",ct(this.options.HTMLAttributes,t,{"data-type":this.name}),0]},parseMarkdown:(t,e)=>e.createNode("taskList",{},e.parseChildren(t.items||[])),renderMarkdown:(t,e)=>t.content?e.renderChildren(t.content,`
17779`):"",markdownTokenizer:{name:"taskList",level:"block",start(t){var e;const a=(e=t.match(/^\s*[-+*]\s+\[([ xX])\]\s+/))==null?void 0:e.index;return a!==void 0?a:-1},tokenize(t,e,a){const n=r=>{const o=Hb(r,{itemPattern:/^(\s*)([-+*])\s+\[([ xX])\]\s+(.*)$/,extractItemData:l=>({indentLevel:l[1].length,mainContent:l[4],checked:l[3].toLowerCase()==="x"}),createToken:(l,c)=>({type:"taskItem",raw:"",mainContent:l.mainContent,indentLevel:l.indentLevel,checked:l.checked,text:l.mainContent,tokens:a.inlineTokens(l.mainContent),nestedTokens:c}),customNestedParser:n},a);return o?[{type:"taskList",raw:o.raw,items:o.items}]:a.blockTokens(r)},i=Hb(t,{itemPattern:/^(\s*)([-+*])\s+\[([ xX])\]\s+(.*)$/,extractItemData:r=>({indentLevel:r[1].length,mainContent:r[4],checked:r[3].toLowerCase()==="x"}),createToken:(r,o)=>({type:"taskItem",raw:"",mainContent:r.mainContent,indentLevel:r.indentLevel,checked:r.checked,text:r.mainContent,tokens:a.inlineTokens(r.mainContent),nestedTokens:o}),customNestedParser:n},a);if(i)return{type:"taskList",raw:i.raw,items:i.items}}},markdownOptions:{indentsContent:!0},addCommands(){return{toggleTaskList:()=>({commands:t})=>t.toggleList(this.name,this.options.itemTypeName)}},addKeyboardShortcuts(){return{"Mod-Shift-9":()=>this.editor.commands.toggleTaskList()}}});ze.create({name:"listKit",addExtensions(){const t=[];return this.options.bulletList!==!1&&t.push(sD.configure(this.options.bulletList)),this.options.listItem!==!1&&t.push(lD.configure(this.options.listItem)),this.options.listKeymap!==!1&&t.push(hD.configure(this.options.listKeymap)),this.options.orderedList!==!1&&t.push(gD.configure(this.options.orderedList)),this.options.taskItem!==!1&&t.push(Rue.configure(this.options.taskItem)),this.options.taskList!==!1&&t.push(Lue.configure(this.options.taskList)),t}});var Oue=Oa.create({name:"paragraph",priority:1e3,addOptions(){return{HTMLAttributes:{}}},group:"block",content:"inline*",parseHTML(){return[{tag:"p"}]},renderHTML({HTMLAttributes:t}){return["p",ct(this.options.HTMLAttributes,t),0]},parseMarkdown:(t,e)=>{const a=t.tokens||[];return a.length===1&&a[0].type==="image"?e.parseChildren([a[0]]):e.createNode("paragraph",void 0,e.parseInline(a))},renderMarkdown:(t,e)=>!t||!Array.isArray(t.content)?"":e.renderChildren(t.content),addCommands(){return{setParagraph:()=>({commands:t})=>t.setNode(this.name)}},addKeyboardShortcuts(){return{"Mod-Alt-0":()=>this.editor.commands.setParagraph()}}}),Mue=/(?:^|\s)(~~(?!\s+~~)((?:[^~]+))~~(?!\s+~~))$/,Due=/(?:^|\s)(~~(?!\s+~~)((?:[^~]+))~~(?!\s+~~))/g,que=ao.create({name:"strike",addOptions(){return{HTMLAttributes:{}}},parseHTML(){return[{tag:"s"},{tag:"del"},{tag:"strike"},{style:"text-decoration",consuming:!1,getAttrs:t=>t.includes("line-through")?{}:!1}]},renderHTML({HTMLAttributes:t}){return["s",ct(this.options.HTMLAttributes,t),0]},markdownTokenName:"del",parseMarkdown:(t,e)=>
vendor: 5,396 bytes, line 17779
17779e.applyMark("strike",e.parseInline(t.tokens||[])),renderMarkdown:(t,e)=>`~~${e.renderChildren(t)}~~`,addCommands(){return{setStrike:()=>({commands:t})=>t.setMark(this.name),toggleStrike:()=>({commands:t})=>t.toggleMark(this.name),unsetStrike:()=>({commands:t})=>t.unsetMark(this.name)}},addKeyboardShortcuts(){return{"Mod-Shift-s":()=>this.editor.commands.toggleStrike()}},addInputRules(){return[Ml({find:Mue,type:this.type})]},addPasteRules(){return[ss({find:Due,type:this.type})]}}),zue=Oa.create({name:"text",group:"inline",parseMarkdown:t=>({type:"text",text:t.text||""}),renderMarkdown:t=>t.text||""}),Vue=ao.create({name:"underline",addOptions(){return{HTMLAttributes:{}}},parseHTML(){return[{tag:"u"},{style:"text-decoration",consuming:!1,getAttrs:t=>t.includes("underline")?{}:!1}]},renderHTML({HTMLAttributes:t}){return["u",ct(this.options.HTMLAttributes,t),0]},parseMarkdown(t,e){return e.applyMark(this.name||"underline",e.parseInline(t.tokens||[]))},renderMarkdown(t,e){return`++${e.renderChildren(t)}++`},markdownTokenizer:{name:"underline",level:"inline",start(t){return t.indexOf("++")},tokenize(t,e,a){const i=/^(\+\+)([\s\S]+?)(\+\+)/.exec(t);if(!i)return;const r=i[2].trim();return{type:"underline",raw:i[0],text:r,tokens:a.inlineTokens(r)}}},addCommands(){return{setUnderline:()=>({commands:t})=>t.setMark(this.name),toggleUnderline:()=>({commands:t})=>t.toggleMark(this.name),unsetUnderline:()=>({commands:t})=>t.unsetMark(this.name)}},addKeyboardShortcuts(){return{"Mod-u":()=>this.editor.commands.toggleUnderline(),"Mod-U":()=>this.editor.commands.toggleUnderline()}}});function Hue(t={}){return new at({view(e){return new Fue(e,t)}})}class Fue{constructor(e,a){var n;this.editorView=e,this.cursorPos=null,this.element=null,this.timeout=-1,this.width=(n=a.width)!==null&&n!==void 0?n:1,this.color=a.color===!1?void 0:a.color||"black",this.class=a.class,this.handlers=["dragover","dragend","drop","dragleave"].map(i=>{let r=o=>{this[i](o)};return e.dom.addEventListener(i,r),{name:i,handler:r}})}destroy(){this.handlers.forEach(({name:e,handler:a})=>this.editorView.dom.removeEventListener(e,a))}update(e,a){this.cursorPos!=null&&a.doc!=e.state.doc&&(this.cursorPos>e.state.doc.content.size?this.setCursor(null):this.updateOverlay())}setCursor(e){e!=this.cursorPos&&(this.cursorPos=e,e==null?(this.element.parentNode.removeChild(this.element),this.element=null):this.updateOverlay())}updateOverlay(){let e=this.editorView.state.doc.resolve(this.cursorPos),a=!e.parent.inlineContent,n,i=this.editorView.dom,r=i.getBoundingClientRect(),o=r.width/i.offsetWidth,l=r.height/i.offsetHeight;if(a){let p=e.nodeBefore,m=e.nodeAfter;if(p||m){let h=this.editorView.nodeDOM(this.cursorPos-(p?p.nodeSize:0));if(h){let g=h.getBoundingClientRect(),y=p?g.bottom:g.top;p&&m&&(y=(y+this.editorView.nodeDOM(this.cursorPos).getBoundingClientRect().top)/2);let x=this.width/2*l;n={left:g.left,right:g.right,top:y-x,bottom:y+x}}}}if(!n){let p=this.editorView.coordsAtPos(this.cursorPos),m=this.width/2*o;n={left:p.left-m,right:p.left+m,top:p.top,bottom:p.bottom}}let c=this.editorView.dom.offsetParent;this.element||(this.element=c.appendChild(document.createElement("div")),this.class&&(this.element.className=this.class),this.element.style.cssText="position: absolute; z-index: 50; pointer-events: none;",this.color&&(this.element.style.backgroundColor=this.color)),this.element.classList.toggle("prosemirror-dropcursor-block",a),this.element.classList.toggle("prosemirror-dropcursor-inline",!a);let d,u;if(!c||c==document.body&&getComputedStyle(c).position=="static")d=-pageXOffset,u=-pageYOffset;else{let p=c.getBoundingClientRect(),m=p.width/c.offsetWidth,h=p.height/c.offsetHeight;d=p.left-c.scrollLeft*m,u=p.top-c.scrollTop*h}this.element.style.left=(n.left-d)/o+"px",this.element.style.top=(n.top-u)/l+"px",this.element.style.width=(n.right-n.left)/o+"px",this.element.style.height=(n.bottom-n.top)/l+"px"}scheduleRemoval(e){clearTimeout(this.timeout),this.timeout=setTimeout(()=>this.setCursor(null),e)}dragover(e){if(!this.editorView.editable)return;let a=this.editorView.posAtCoords({left:e.clientX,top:e.clientY}),n=a&&a.inside>=0&&this.editorView.state.doc.nodeAt(a.inside),i=n&&n.type.spec.disableDropCursor,r=typeof i=="function"?i(this.editorView,a,e):i;if(a&&!r){let o=a.pos;if(this.editorView.dragging&&this.editorView.dragging.slice){let l=pM(this.editorView.state.doc,o,this.editorView.dragging.slice);l!=null&&(o=l)}this.setCursor(o),this.scheduleRemoval(5e3)}}dragend(){this.scheduleRemoval(20)}drop(){this.scheduleRemoval(20)}dragleave(e){this.editorView.dom.contains(e.relatedTarget)||this.setCursor(null)}}class st extends xe{constructor(e){super(e,e)}map(e,a){let n=e.resolve(a.map(this.head));return st.valid(n)?new st(n):xe.near(n)}content(){return K.empty}eq(e){return e instanceof st&&e.head==this.head}toJSON(){return{type:"gapcursor",pos:this.head}}static fromJSON(e,a){if(typeof a.pos!="number")throw new RangeError("Invalid input for GapCursor.fromJSON");return new st(e.resolve(a.pos))}getBookmark(){return new RS(this.anchor)}static valid(e){let a=e.parent;if(a.isTextblock||!Bue(e)||!Uue(e))return!1;let n=a.type.spec.allowGapCursor;if(n!=null)return n;let i=a.contentMatchAt(e.index()).defaultType;return i&&i.isTextblock}static findGapCursorFrom(e,a,n=!1){e:for(;;){if(!n&&st.valid(e))return e;let i=e.pos,r=null;for(let o=e.depth;;o--){let l=e.node(o);if(a>
vendor: 5,640 bytes, line 17779
177790?e.indexAfter(o)<l.childCount:e.index(o)>0){r=l.child(a>0?e.indexAfter(o):e.index(o)-1);break}else if(o==0)return null;i+=a;let c=e.doc.resolve(i);if(st.valid(c))return c}for(;;){let o=a>0?r.firstChild:r.lastChild;if(!o){if(r.isAtom&&!r.isText&&!se.isSelectable(r)){e=e.doc.resolve(i+r.nodeSize*a),n=!1;continue e}break}r=o,i+=a;let l=e.doc.resolve(i);if(st.valid(l))return l}return null}}}st.prototype.visible=!1;st.findFrom=st.findGapCursorFrom;xe.jsonID("gapcursor",st);class RS{constructor(e){this.pos=e}map(e){return new RS(e.map(this.pos))}resolve(e){let a=e.resolve(this.pos);return st.valid(a)?new st(a):xe.near(a)}}function yD(t){return t.isAtom||t.spec.isolating||t.spec.createGapCursor}function Bue(t){for(let e=t.depth;e>=0;e--){let a=t.index(e),n=t.node(e);if(a==0){if(n.type.spec.isolating)return!0;continue}for(let i=n.child(a-1);;i=i.lastChild){if(i.childCount==0&&!i.inlineContent||yD(i.type))return!0;if(i.inlineContent)return!1}}return!0}function Uue(t){for(let e=t.depth;e>=0;e--){let a=t.indexAfter(e),n=t.node(e);if(a==n.childCount){if(n.type.spec.isolating)return!0;continue}for(let i=n.child(a);;i=i.firstChild){if(i.childCount==0&&!i.inlineContent||yD(i.type))return!0;if(i.inlineContent)return!1}}return!0}function $ue(){return new at({props:{decorations:Jue,createSelectionBetween(t,e,a){return e.pos==a.pos&&st.valid(a)?new st(a):null},handleClick:Gue,handleKeyDown:Wue,handleDOMEvents:{beforeinput:Kue}}})}const Wue=m5({ArrowLeft:lm("horiz",-1),ArrowRight:lm("horiz",1),ArrowUp:lm("vert",-1),ArrowDown:lm("vert",1)});function lm(t,e){const a=t=="vert"?e>0?"down":"up":e>0?"right":"left";return function(n,i,r){let o=n.selection,l=e>0?o.$to:o.$from,c=o.empty;if(o instanceof ce){if(!r.endOfTextblock(a)||l.depth==0)return!1;c=!1,l=n.doc.resolve(e>0?l.after():l.before())}let d=st.findGapCursorFrom(l,e,c);return d?(i&&i(n.tr.setSelection(new st(d))),!0):!1}}function Gue(t,e,a){if(!t||!t.editable)return!1;let n=t.state.doc.resolve(e);if(!st.valid(n))return!1;let i=t.posAtCoords({left:a.clientX,top:a.clientY});return i&&i.inside>-1&&se.isSelectable(t.state.doc.nodeAt(i.inside))?!1:(t.dispatch(t.state.tr.setSelection(new st(n))),!0)}function Kue(t,e){if(e.inputType!="insertCompositionText"||!(t.state.selection instanceof st))return!1;let{$from:a}=t.state.selection,n=a.parent.contentMatchAt(a.index()).findWrapping(t.state.schema.nodes.text);if(!n)return!1;let i=V.empty;for(let o=n.length-1;o>=0;o--)i=V.from(n[o].createAndFill(null,i));let r=t.state.tr.replace(a.pos,a.pos,new K(i,0,0));return r.setSelection(ce.near(r.doc.resolve(a.pos+1))),t.dispatch(r),!1}function Jue(t){if(!(t.selection instanceof st))return null;let e=document.createElement("div");return e.className="ProseMirror-gapcursor",Qe.create(t.doc,[ha.widget(t.selection.head,e,{key:"gapcursor"})])}var Df=200,Rt=function(){};Rt.prototype.append=function(e){return e.length?(e=Rt.from(e),!this.length&&e||e.length<Df&&this.leafAppend(e)||this.length<Df&&e.leafPrepend(this)||this.appendInner(e)):this};Rt.prototype.prepend=function(e){return e.length?Rt.from(e).append(this):this};Rt.prototype.appendInner=function(e){return new Que(this,e)};Rt.prototype.slice=function(e,a){return e===void 0&&(e=0),a===void 0&&(a=this.length),e>=a?Rt.empty:this.sliceInner(Math.max(0,e),Math.min(this.length,a))};Rt.prototype.get=function(e){if(!(e<0||e>=this.length))return this.getInner(e)};Rt.prototype.forEach=function(e,a,n){a===void 0&&(a=0),n===void 0&&(n=this.length),a<=n?this.forEachInner(e,a,n,0):this.forEachInvertedInner(e,a,n,0)};Rt.prototype.map=function(e,a,n){a===void 0&&(a=0),n===void 0&&(n=this.length);var i=[];return this.forEach(function(r,o){return i.push(e(r,o))},a,n),i};Rt.from=function(e){return e instanceof Rt?e:e&&e.length?new xD(e):Rt.empty};var xD=function(t){function e(n){t.call(this),this.values=n}t&&(e.__proto__=t),e.prototype=Object.create(t&&t.prototype),e.prototype.constructor=e;var a={length:{configurable:!0},depth:{configurable:!0}};return e.prototype.flatten=function(){return this.values},e.prototype.sliceInner=function(i,r){return i==0&&r==this.length?this:new e(this.values.slice(i,r))},e.prototype.getInner=function(i){return this.values[i]},e.prototype.forEachInner=function(i,r,o,l){for(var c=r;c<o;c++)if(i(this.values[c],l+c)===!1)return!1},e.prototype.forEachInvertedInner=function(i,r,o,l){for(var c=r-1;c>=o;c--)if(i(this.values[c],l+c)===!1)return!1},e.prototype.leafAppend=function(i){if(this.length+i.length<=Df)return new e(this.values.concat(i.flatten()))},e.prototype.leafPrepend=function(i){if(this.length+i.length<=Df)return new e(i.flatten().concat(this.values))},a.length.get=function(){return this.values.length},a.depth.get=function(){return 0},Object.defineProperties(e.prototype,a),e}(Rt);Rt.empty=new xD([]);var Que=function(t){function e(a,n){t.call(this),this.left=a,this.right=n,this.length=a.length+n.length,this.depth=Math.max(a.depth,n.depth)+1}return t&&(e.__proto__=t),e.prototype=Object.create(t&&t.prototype),e.prototype.constructor=e,e.prototype.flatten=function(){return this.left.flatten().concat(this.right.flatten())},e.prototype.getInner=function(n){return n<this.left.length?this.left.get(n):this.right.get(n-this.left.length)},e.prototype.forEachInner=function(n,i,r,o){var l=this.left.length;if(i<l&&this.left.forEachInner(n,i,Math.min(r,l),o)===!1||r>l&&this.right.forEachInner(n,Math.max(i-l,0),Math.min(this.length,r)-l,o+l)===!1)return!1},e.prototype.forEachInvertedInner=function(n,i,r,o){var l=this.left.length;if(i>l&&this.right.forEachInvertedInner(n,i-l,Math.max(r,l)-l,o+l)===!1||r<l&&this.left.forEachInvertedInner(n,Math.min(i,l),r,o)===!1)return!1}
vendor: 4,834 bytes, line 17779
17779,e.prototype.sliceInner=function(n,i){if(n==0&&i==this.length)return this;var r=this.left.length;return i<=r?this.left.slice(n,i):n>=r?this.right.slice(n-r,i-r):this.left.slice(n,r).append(this.right.slice(0,i-r))},e.prototype.leafAppend=function(n){var i=this.right.leafAppend(n);if(i)return new e(this.left,i)},e.prototype.leafPrepend=function(n){var i=this.left.leafPrepend(n);if(i)return new e(i,this.right)},e.prototype.appendInner=function(n){return this.left.depth>=Math.max(this.right.depth,n.depth)+1?new e(this.left,new e(this.right,n)):new e(this,n)},e}(Rt);const Xue=500;class An{constructor(e,a){this.items=e,this.eventCount=a}popEvent(e,a){if(this.eventCount==0)return null;let n=this.items.length;for(;;n--)if(this.items.get(n-1).selection){--n;break}let i,r;a&&(i=this.remapping(n,this.items.length),r=i.maps.length);let o=e.tr,l,c,d=[],u=[];return this.items.forEach((p,m)=>{if(!p.step){i||(i=this.remapping(n,m+1),r=i.maps.length),r--,u.push(p);return}if(i){u.push(new $n(p.map));let h=p.step.map(i.slice(r)),g;h&&o.maybeStep(h).doc&&(g=o.mapping.maps[o.mapping.maps.length-1],d.push(new $n(g,void 0,void 0,d.length+u.length))),r--,g&&i.appendMap(g,r)}else o.maybeStep(p.step);if(p.selection)return l=i?p.selection.map(i.slice(r)):p.selection,c=new An(this.items.slice(0,n).append(u.reverse().concat(d)),this.eventCount-1),!1},this.items.length,0),{remaining:c,transform:o,selection:l}}addTransform(e,a,n,i){let r=[],o=this.eventCount,l=this.items,c=!i&&l.length?l.get(l.length-1):null;for(let u=0;u<e.steps.length;u++){let p=e.steps[u].invert(e.docs[u]),m=new $n(e.mapping.maps[u],p,a),h;(h=c&&c.merge(m))&&(m=h,u?r.pop():l=l.slice(0,l.length-1)),r.push(m),a&&(o++,a=void 0),i||(c=m)}let d=o-n.depth;return d>Zue&&(l=Yue(l,d),o-=d),new An(l.append(r),o)}remapping(e,a){let n=new pu;return this.items.forEach((i,r)=>{let o=i.mirrorOffset!=null&&r-i.mirrorOffset>=e?n.maps.length-i.mirrorOffset:void 0;n.appendMap(i.map,o)},e,a),n}addMaps(e){return this.eventCount==0?this:new An(this.items.append(e.map(a=>new $n(a))),this.eventCount)}rebased(e,a){if(!this.eventCount)return this;let n=[],i=Math.max(0,this.items.length-a),r=e.mapping,o=e.steps.length,l=this.eventCount;this.items.forEach(m=>{m.selection&&l--},i);let c=a;this.items.forEach(m=>{let h=r.getMirror(--c);if(h==null)return;o=Math.min(o,h);let g=r.maps[h];if(m.step){let y=e.steps[h].invert(e.docs[h]),x=m.selection&&m.selection.map(r.slice(c+1,h));x&&l++,n.push(new $n(g,y,x))}else n.push(new $n(g))},i);let d=[];for(let m=a;m<o;m++)d.push(new $n(r.maps[m]));let u=this.items.slice(0,i).append(d).append(n),p=new An(u,l);return p.emptyItemCount()>Xue&&(p=p.compress(this.items.length-n.length)),p}emptyItemCount(){let e=0;return this.items.forEach(a=>{a.step||e++}),e}compress(e=this.items.length){let a=this.remapping(0,e),n=a.maps.length,i=[],r=0;return this.items.forEach((o,l)=>{if(l>=e)i.push(o),o.selection&&r++;else if(o.step){let c=o.step.map(a.slice(n)),d=c&&c.getMap();if(n--,d&&a.appendMap(d,n),c){let u=o.selection&&o.selection.map(a.slice(n));u&&r++;let p=new $n(d.invert(),c,u),m,h=i.length-1;(m=i.length&&i[h].merge(p))?i[h]=m:i.push(p)}}else o.map&&n--},this.items.length,0),new An(Rt.from(i.reverse()),r)}}An.empty=new An(Rt.empty,0);function Yue(t,e){let a;return t.forEach((n,i)=>{if(n.selection&&e--==0)return a=i,!1}),t.slice(a)}class $n{constructor(e,a,n,i){this.map=e,this.step=a,this.selection=n,this.mirrorOffset=i}merge(e){if(this.step&&e.step&&!e.selection){let a=e.step.merge(this.step);if(a)return new $n(a.getMap().invert(),a,this.selection)}}}class rr{constructor(e,a,n,i,r){this.done=e,this.undone=a,this.prevRanges=n,this.prevTime=i,this.prevComposition=r}}const Zue=20;function epe(t,e,a,n){let i=a.getMeta(Fo),r;if(i)return i.historyState;a.getMeta(npe)&&(t=new rr(t.done,t.undone,null,0,-1));let o=a.getMeta("appendedTransaction");if(a.steps.length==0)return t;if(o&&o.getMeta(Fo))return o.getMeta(Fo).redo?new rr(t.done.addTransform(a,void 0,n,Gm(e)),t.undone,WT(a.mapping.maps),t.prevTime,t.prevComposition):new rr(t.done,t.undone.addTransform(a,void 0,n,Gm(e)),null,t.prevTime,t.prevComposition);if(a.getMeta("addToHistory")!==!1&&!(o&&o.getMeta("addToHistory")===!1)){let l=a.getMeta("composition"),c=t.prevTime==0||!o&&t.prevComposition!=l&&(t.prevTime<(a.time||0)-n.newGroupDelay||!tpe(a,t.prevRanges)),d=o?fx(t.prevRanges,a.mapping):WT(a.mapping.maps);return new rr(t.done.addTransform(a,c?e.selection.getBookmark():void 0,n,Gm(e)),An.empty,d,a.time,l??t.prevComposition)}else return(r=a.getMeta("rebased"))?new rr(t.done.rebased(a,r),t.undone.rebased(a,r),fx(t.prevRanges,a.mapping),t.prevTime,t.prevComposition):new rr(t.done.addMaps(a.mapping.maps),t.undone.addMaps(a.mapping.maps),fx(t.prevRanges,a.mapping),t.prevTime,t.prevComposition)}function tpe(t,e){if(!e)return!1;if(!t.docChanged)return!0;let a=!1;
vendor: 9,331 bytes, line 17779
17779return t.mapping.maps[0].forEach((n,i)=>{for(let r=0;r<e.length;r+=2)n<=e[r+1]&&i>=e[r]&&(a=!0)}),a}function WT(t){let e=[];for(let a=t.length-1;a>=0&&e.length==0;a--)t[a].forEach((n,i,r,o)=>e.push(r,o));return e}function fx(t,e){if(!t)return null;let a=[];for(let n=0;n<t.length;n+=2){let i=e.map(t[n],1),r=e.map(t[n+1],-1);i<=r&&a.push(i,r)}return a}function ape(t,e,a){let n=Gm(e),i=Fo.get(e).spec.config,r=(a?t.undone:t.done).popEvent(e,n);if(!r)return null;let o=r.selection.resolve(r.transform.doc),l=(a?t.done:t.undone).addTransform(r.transform,e.selection.getBookmark(),i,n),c=new rr(a?l:r.remaining,a?r.remaining:l,null,0,-1);return r.transform.setSelection(o).setMeta(Fo,{redo:a,historyState:c})}let gx=!1,GT=null;function Gm(t){let e=t.plugins;if(GT!=e){gx=!1,GT=e;for(let a=0;a<e.length;a++)if(e[a].spec.historyPreserveItems){gx=!0;break}}return gx}const Fo=new _t("history"),npe=new _t("closeHistory");function ipe(t={}){return t={depth:t.depth||100,newGroupDelay:t.newGroupDelay||500},new at({key:Fo,state:{init(){return new rr(An.empty,An.empty,null,0,-1)},apply(e,a,n){return epe(a,n,e,t)}},config:t,props:{handleDOMEvents:{beforeinput(e,a){let n=a.inputType,i=n=="historyUndo"?bD:n=="historyRedo"?wD:null;return!i||!e.editable?!1:(a.preventDefault(),i(e.state,e.dispatch))}}}})}function vD(t,e){return(a,n)=>{let i=Fo.getState(a);if(!i||(t?i.undone:i.done).eventCount==0)return!1;if(n){let r=ape(i,a,t);r&&n(e?r.scrollIntoView():r)}return!0}}const bD=vD(!1,!0),wD=vD(!0,!0);ze.create({name:"characterCount",addOptions(){return{limit:null,mode:"textSize",textCounter:t=>t.length,wordCounter:t=>t.split(" ").filter(e=>e!=="").length}},addStorage(){return{characters:()=>0,words:()=>0}},onBeforeCreate(){this.storage.characters=t=>{const e=(t==null?void 0:t.node)||this.editor.state.doc;if(((t==null?void 0:t.mode)||this.options.mode)==="textSize"){const n=e.textBetween(0,e.content.size,void 0," ");return this.options.textCounter(n)}return e.nodeSize},this.storage.words=t=>{const e=(t==null?void 0:t.node)||this.editor.state.doc,a=e.textBetween(0,e.content.size," "," ");return this.options.wordCounter(a)}},addProseMirrorPlugins(){let t=!1;return[new at({key:new _t("characterCount"),appendTransaction:(e,a,n)=>{if(t)return;const i=this.options.limit;if(i==null||i===0){t=!0;return}const r=this.storage.characters({node:n.doc});if(r>i){const o=r-i,l=0,c=o;console.warn(`[CharacterCount] Initial content exceeded limit of ${i} characters. Content was automatically trimmed.`);const d=n.tr.deleteRange(l,c);return t=!0,d}t=!0},filterTransaction:(e,a)=>{const n=this.options.limit;if(!e.docChanged||n===0||n===null||n===void 0)return!0;const i=this.storage.characters({node:a.doc}),r=this.storage.characters({node:e.doc});if(r<=n||i>n&&r>n&&r<=i)return!0;if(i>n&&r>n&&r>i||!e.getMeta("paste"))return!1;const l=e.selection.$head.pos,c=r-n,d=l-c,u=l;return e.deleteRange(d,u),!(this.storage.characters({node:e.doc})>n)}})]}});var rpe=ze.create({name:"dropCursor",addOptions(){return{color:"currentColor",width:1,class:void 0}},addProseMirrorPlugins(){return[Hue(this.options)]}});ze.create({name:"focus",addOptions(){return{className:"has-focus",mode:"all"}},addProseMirrorPlugins(){return[new at({key:new _t("focus"),props:{decorations:({doc:t,selection:e})=>{const{isEditable:a,isFocused:n}=this.editor,{anchor:i}=e,r=[];if(!a||!n)return Qe.create(t,[]);let o=0;this.options.mode==="deepest"&&t.descendants((c,d)=>{if(c.isText)return;if(!(i>=d&&i<=d+c.nodeSize-1))return!1;o+=1});let l=0;return t.descendants((c,d)=>{if(c.isText||!(i>=d&&i<=d+c.nodeSize-1))return!1;if(l+=1,this.options.mode==="deepest"&&o-l>0||this.options.mode==="shallowest"&&l>1)return this.options.mode==="deepest";r.push(ha.node(d,d+c.nodeSize,{class:this.options.className}))}),Qe.create(t,r)}}})]}});var ope=ze.create({name:"gapCursor",addProseMirrorPlugins(){return[$ue()]},extendNodeSchema(t){var e;const a={name:t.name,options:t.options,storage:t.storage};return{allowGapCursor:(e=Pe(te(t,"allowGapCursor",a)))!=null?e:null}}});ze.create({name:"placeholder",addOptions(){return{emptyEditorClass:"is-editor-empty",emptyNodeClass:"is-empty",placeholder:"Write something …",showOnlyWhenEditable:!0,showOnlyCurrent:!0,includeChildren:!1}},addProseMirrorPlugins(){return[new at({key:new _t("placeholder"),props:{decorations:({doc:t,selection:e})=>{const a=this.editor.isEditable||!this.options.showOnlyWhenEditable,{anchor:n}=e,i=[];if(!a)return null;const r=this.editor.isEmpty;return t.descendants((o,l)=>{const c=n>=l&&n<=l+o.nodeSize,d=!o.isLeaf&&Kg(o);if((c||!this.options.showOnlyCurrent)&&d){const u=[this.options.emptyNodeClass];r&&u.push(this.options.emptyEditorClass);const p=ha.node(l,l+o.nodeSize,{class:u.join(" "),"data-placeholder":typeof this.options.placeholder=="function"?this.options.placeholder({editor:this.editor,node:o,pos:l,hasAnchor:c}):this.options.placeholder});i.push(p)}return this.options.includeChildren}),Qe.create(t,i)}}})]}});ze.create({name:"selection",addOptions(){return{className:"selection"}},addProseMirrorPlugins(){const{editor:t,options:e}=this;return[new at({key:new _t("selection"),props:{decorations(a){return a.selection.empty||t.isFocused||!t.isEditable||T5(a.selection)||t.view.dragging?null:Qe.create(a.doc,[ha.inline(a.selection.from,a.selection.to,{class:e.className})])}}})]}});function KT({types:t,node:e}){return e&&Array.isArray(t)&&t.includes(e.type)||(e==null?void 0:e.type)===t}var spe=ze.create({name:"trailingNode",addOptions(){return{node:void 0,notAfter:[]}},addProseMirrorPlugins(){var t;const e=new _t(this.name),a=this.options.node||((t=this.editor.schema.topNodeType.contentMatch.defaultType)==null?void 0:t.name)||"paragraph",n=Object.entries(this.editor.schema.nodes).map(([,i])=>i).filter(i=>(this.options.notAfter||[]).concat(a).includes(i.name));return[new at({key:e,appendTransaction:(i,r,o)=>{const{doc:l,tr:c,schema:d}=o,u=e.getState(o),p=l.content.size,m=d.nodes[a];if(u)return c.insert(p,m.create())},state:{init:(i,r)=>{const o=r.tr.doc.lastChild;return!KT({node:o,types:n})},apply:(i,r)=>{if(!i.docChanged||i.getMeta("__uniqueIDTransaction"))return r;const o=i.doc.lastChild;return!KT({node:o,types:n})}}})]}}),lpe=ze.create({name:"undoRedo",addOptions(){return{depth:100,newGroupDelay:500}},addCommands(){return{undo:()=>({state:t,dispatch:e})=>bD(t,e),redo:()=>({state:t,dispatch:e})=>wD(t,e)}},addProseMirrorPlugins(){return[ipe(this.options)]},addKeyboardShortcuts(){return{"Mod-z":()=>this.editor.commands.undo(),"Shift-Mod-z":()=>this.editor.commands.redo(),"Mod-y":()=>this.editor.commands.redo(),"Mod-я":()=>this.editor.commands.undo(),"Shift-Mod-я":()=>this.editor.commands.redo()}}}),cpe=ze.create({name:"starterKit",addExtensions(){var t,e,a,n;const i=[];return this.options.bold!==!1&&i.push(Mde.configure(this.options.bold)),this.options.blockquote!==!1&&i.push(Ide.configure(this.options.blockquote)),this.options.bulletList!==!1&&i.push(sD.configure(this.options.bulletList)),this.options.code!==!1&&i.push(zde.configure(this.options.code)),this.options.codeBlock!==!1&&i.push(Fde.configure(this.options.codeBlock)),this.options.document!==!1&&i.push(Bde.configure(this.options.document)),this.options.dropcursor!==!1&&i.push(rpe.configure(this.options.dropcursor)),this.options.gapcursor!==!1&&i.push(ope.configure(this.options.gapcursor)),this.options.hardBreak!==!1&&i.push(Ude.configure(this.options.hardBreak)),this.options.heading!==!1&&i.push($de.configure(this.options.heading)),this.options.undoRedo!==!1&&i.push(lpe.configure(this.options.undoRedo)),this.options.horizontalRule!==!1&&i.push(Wde.configure(this.options.horizontalRule)),this.options.italic!==!1&&i.push(Xde.configure(this.options.italic)),this.options.listItem!==!1&&i.push(lD.configure(this.options.listItem)),this.options.listKeymap!==!1&&i.push(hD.configure((t=this.options)==null?void 0:t.listKeymap)),this.options.link!==!1&&i.push(kue.configure((e=this.options)==null?void 0:e.link)),this.options.orderedList!==!1&&i.push(gD.configure(this.options.orderedList)),this.options.paragraph!==!1&&i.push(Oue.configure(this.options.paragraph)),this.options.strike!==!1&&i.push(que.configure(this.options.strike)),this.options.text!==!1&&i.push(zue.configure(this.options.text)),this.options.underline!==!1&&i.push(Vue.configure((a=this.options)==null?void 0:a.underline)),this.options.trailingNode!==!1&&i.push(spe.configure((n=this.options)==null?void 0:n.trailingNode)),i}}),dpe=cpe,upe=/(?:^|\s)(!\[(.+|:?)]\((\S+)(?:(?:\s+)["'](\S+)["'])?\))$/,ppe=Oa.create({name:"image",addOptions(){return{inline:!1,allowBase64:!1,HTMLAttributes:{},resize:!1}},inline(){return this.options.inline},group(){return this.options.inline?"inline":"block"},draggable:!0,addAttributes(){return{src:{default:null},alt:{default:null},title:{default:null},width:{default:null},height:{default:null}}},parseHTML(){return[{tag:this.options.allowBase64?"img[src]":'img[src]:not([src^="data:"])'}]},renderHTML({HTMLAttributes:t}){return["img",ct(this.options.HTMLAttributes,t)]},parseMarkdown:(t,e)=>e.createNode("image",{src:t.href,title:t.title,alt:t.text}),renderMarkdown:t=>{var e,a,n,i,r,o;const l=(a=(e=t.attrs)==null?void 0:e.src)!=null?a:"",c=(i=(n=t.attrs)==null?void 0:n.alt)!=null?i:"",d=(o=(r=t.attrs)==null?void 0:r.title)!=null?o:"";return d?`![${c}](${l} "${d}")`:`![${c}](${l})`}
17779,addNodeView(){if(!this.options.resize||!this.options.resize.enabled||typeof document>"u")return null;const{directions:t,minWidth:e,minHeight:a,alwaysPreserveAspectRatio:n}=this.options.resize;return({node:i,getPos:r,HTMLAttributes:o,editor:l})=>{const c=document.createElement("img");Object.entries(o).forEach(([p,m])=>{if(m!=null)switch(p){case"width":case"height":break;default:c.setAttribute(p,m);break}}),c.src=o.src;const d=new uce({element:c,editor:l,node:i,getPos:r,onResize:(p,m)=>{c.style.width=`${p}px`,c.style.height=`${m}px`},onCommit:(p,m)=>{const h=r();h!==void 0&&this.editor.chain().setNodeSelection(h).updateAttributes(this.name,{width:p,height:m}).run()},onUpdate:(p,m,h)=>p.type===i.type,options:{directions:t,min:{width:e,height:a},preserveAspectRatio:n===!0}}),u=d.dom;return u.style.visibility="hidden",u.style.pointerEvents="none",c.onload=()=>{u.style.visibility="",u.style.pointerEvents=""},d}},addCommands(){return{setImage:t=>({commands:e})=>e.insertContent({type:this.name,attrs:t})}},addInputRules(){return[W5({find:upe,type:this.type,getAttributes:t=>{const[,,e,a,n]=t;return{src:a,alt:e,title:n}}})]}}),mpe=ppe,hpe=20,kD=(t,e=0)=>{const a=[];return!t.children.length||e>hpe||Array.from(t.children).forEach(n=>{n.tagName==="SPAN"?a.push(n):n.children.length&&a.push(...kD(n,e+1))}),a},fpe=t=>{if(!t.children.length)return;const e=kD(t);e&&e.forEach(a=>{var n,i;const r=a.getAttribute("style"),o=(i=(n=a.parentElement)==null?void 0:n.closest("span"))==null?void 0:i.getAttribute("style");a.setAttribute("style",`${o};${r}`)})},SD=ao.create({name:"textStyle",priority:101,addOptions(){return{HTMLAttributes:{},mergeNestedSpanStyles:!0}},parseHTML(){return[{tag:"span",consuming:!1,getAttrs:t=>t.hasAttribute("style")?(this.options.mergeNestedSpanStyles&&fpe(t),{}):!1}]},renderHTML({HTMLAttributes:t}){return["span",ct(this.options.HTMLAttributes,t),0]},addCommands(){return{toggleTextStyle:t=>({commands:e})=>e.toggleMark(this.name,t),removeEmptyTextStyle:()=>({tr:t})=>{const{selection:e}=t;return t.doc.nodesBetween(e.from,e.to,(a,n)=>{if(a.isTextblock)return!0;a.marks.filter(i=>i.type===this.type).some(i=>Object.values(i.attrs).some(r=>!!r))||t.removeMark(n,n+a.nodeSize,this.type)}),!0}}}}),gpe=ze.create({name:"backgroundColor",addOptions(){return{types:["textStyle"]}},addGlobalAttributes(){return[{types:this.options.types,attributes:{backgroundColor:{default:null,parseHTML:t=>{var e;const a=t.getAttribute("style");if(a){const n=a.split(";").map(i=>i.trim()).filter(Boolean);for(let i=n.length-1;i>=0;i-=1){const r=n[i].split(":");if(r.length>=2){const o=r[0].trim().toLowerCase(),l=r.slice(1).join(":").trim();if(o==="background-color")return l.replace(/['"]+/g,"")}}}return(e=t.style.backgroundColor)==null?void 0:e.replace(/['"]+/g,"")},renderHTML:t=>t.backgroundColor?{style:`background-color: ${t.backgroundColor}`}:{}}}}]},addCommands(){return{setBackgroundColor:t=>({chain:e})=>e().setMark("textStyle",{backgroundColor:t}).run(),unsetBackgroundColor:()=>({chain:t})=>t().setMark("textStyle",{backgroundColor:null}).removeEmptyTextStyle().run()}}}),_D=ze.create({name:"color",addOptions(){return{types:["textStyle"]}},addGlobalAttributes(){return[{types:this.options.types,attributes:{color:{default:null,parseHTML:t=>{var e;const a=t.getAttribute("style");if(a){const n=a.split(";").map(i=>i.trim()).filter(Boolean);for(let i=n.length-1;i>=0;i-=1){const r=n[i].split(":");if(r.length>=2){const o=r[0].trim().toLowerCase(),l=r.slice(1).join(":").trim();if(o==="color")return l.replace(/['"]+/g,"")}}}return(e=t.style.color)==null?void 0:e.replace(/['"]+/g,"")},renderHTML:t=>t.color?{style:`color: ${t.color}`}:{}}}}]},addCommands(){return{setColor:t=>({chain:e})=>e().setMark("textStyle",{color:t}).run(),unsetColor:()=>({chain:t})=>t().setMark("textStyle",{color:null}).removeEmptyTextStyle().run()}}}),AD=ze.create({name:"fontFamily",addOptions(){return{types:["textStyle"]}},addGlobalAttributes(){return[{types:this.options.types,attributes:{fontFamily:{default:null,parseHTML:t=>t.style.fontFamily,renderHTML:t=>t.fontFamily?{style:`font-family: ${t.fontFamily}`}:{}}}}]},addCommands(){return{setFontFamily:t=>({chain:e})=>e().setMark("textStyle",{fontFamily:t}).run(),unsetFontFamily:()=>({chain:t})=>t().setMark("textStyle",{fontFamily:null}).removeEmptyTextStyle().run()}}}),ype=ze.create({name:"fontSize",addOptions(){return{types:["textStyle"]}},addGlobalAttributes(){return[{types:this.options.types,attributes:{fontSize:{default:null,parseHTML:t=>t.style.fontSize,renderHTML:t=>t.fontSize?{style:`font-size: ${t.fontSize}`}:{}}}}]},addCommands(){return{setFontSize:t=>({chain:e})=>e().setMark("textStyle",{fontSize:t}).run(),unsetFontSize:()=>({chain:t})=>t().setMark("textStyle",{fontSize:null}).removeEmptyTextStyle().run()}}}),xpe=ze.create({name:"lineHeight",addOptions(){return{types:["textStyle"]}},addGlobalAttributes(){return[{types:this.options.types,attributes:{lineHeight:{default:null,parseHTML:t=>t.style.lineHeight,renderHTML:t=>t.lineHeight?{style:`line-height: ${t.lineHeight}`}:{}}}}]},addCommands(){return{setLineHeight:t=>({chain:e})=>e().setMark("textStyle",{lineHeight:t}).run(),unsetLineHeight:()=>({chain:t})=>t().setMark("textStyle",{lineHeight:null}).removeEmptyTextStyle().run()}}});ze.create({name:"textStyleKit",addExtensions(){const t=[];return this.options.backgroundColor!==!1&&t.push(gpe.configure(this.options.backgroundColor)),this.options.color!==!1&&t.push(_D.configure(this.options.color)),this.options.fontFamily!==!1&&t.push(AD.configure(this.options.fontFamily)),this.options.fontSize!==!1&&t.push(ype.configure(this.options.fontSize)),this.options.lineHeight!==!1&&t.push(xpe.configure(this.options.lineHeight)),this.options.textStyle!==!1&&t.push(SD.configure(this.options.textStyle)),t}});var vpe=AD;const bpe=1024*1024,wpe=[{label:"12px",value:"12px"},{label:"14px",value:"14px"},{label:"16px",value:"16px"},{label:"18px",value:"18px"},{label:"20px",value:"20px"},{label:"24px",value:"24px"},{label:"28px",value:"28px"},{label:"32px",value:"32px"}],kpe=[{label:"Sans Serif",value:"system-ui, -apple-system, sans-serif"},{label:"Serif",value:"Georgia, serif"},{label:"Monospace",value:"Courier New, monospace"},{label:"Arial",value:"Arial, sans-serif"}],Spe=[{label:"1.0",value:"1"},{label:"1.2",value:"1.2"},{label:"1.5",value:"1.5"},{label:"1.8",value:"1.8"},{label:"2.0",value:"2"}];function _pe({value:t,onChange:e,onImageSizeError:a}){const[n,i]=k.useState(!1),[r,o]=k.useState(""),[l,c]=k.useState(!1),d=Ede({extensions:[dpe,mpe.configure({allowBase64:!0}),SD,_D,vpe],content:t,onUpdate:({editor:p})=>{e(p.getHTML())}}),u=async()=>{const p=document.createElement("input");p.setAttribute("type","file"),p.setAttribute("accept","image/*"),p.click(),p.onchange=async()=>{const m=p.files[0];if(m){if(m.size>bpe){const h=(m.size/1024/1024).toFixed(2);o(`La imagen es demasiado grande (${h} MB). Máximo permitido: 1 MB`),c(!0),a&&a(`La imagen es demasiado grande (${h} MB). Máximo permitido: 1 MB`);return}try{i(!0);const h=Nk(Gk,`blog-images/${Date.now()}-${m.name}`);await jk(h,m);
17779const g=await Tk(h);d&&d.chain().focus().setImage({src:g}).run()}catch(h){console.error("Error al subir imagen:",h),alert("Error al subir la imagen")}finally{i(!1)}}}};return d?s.jsxs("div",{className:"relative",children:[s.jsxs("div",{className:"fixed right-6 top-32 z-50 w-16 bg-slate-800/95 backdrop-blur-md rounded-lg border border-slate-600 shadow-2xl p-2 space-y-2 max-h-[calc(100vh-200px)] overflow-y-auto",children:[s.jsxs("div",{className:"space-y-1",children:[s.jsx("button",{onClick:()=>d.chain().focus().toggleBold().run(),disabled:!d.can().chain().focus().toggleBold().run(),className:`w-full p-2 rounded text-sm font-bold ${d.isActive("bold")?"bg-primary text-white":"bg-slate-700 text-gray-200 hover:bg-slate-600"}`,title:"Negrita",children:"B"}),s.jsx("button",{onClick:()=>d.chain().focus().toggleItalic().run(),disabled:!d.can().chain().focus().toggleItalic().run(),className:`w-full p-2 rounded text-sm italic ${d.isActive("italic")?"bg-primary text-white":"bg-slate-700 text-gray-200 hover:bg-slate-600"}`,title:"Cursiva",children:"I"}),s.jsx("button",{onClick:()=>d.chain().focus().toggleStrike().run(),disabled:!d.can().chain().focus().toggleStrike().run(),className:`w-full p-2 rounded text-sm line-through ${d.isActive("strike")?"bg-primary text-white":"bg-slate-700 text-gray-200 hover:bg-slate-600"}`,title:"Tachado",children:"S"})]}),s.jsx("div",{className:"border-t border-slate-600 my-2"}),s.jsxs("div",{className:"space-y-1",children:[s.jsx("button",{onClick:()=>d.chain().focus().toggleHeading({level:2}).run(),className:`w-full p-2 rounded text-xs font-bold ${d.isActive("heading",{level:2})?"bg-primary text-white":"bg-slate-700 text-gray-200 hover:bg-slate-600"}`,title:"Título H2",children:"H2"}),s.jsx("button",{onClick:()=>d.chain().focus().toggleHeading({level:3}).run(),className:`w-full p-2 rounded text-xs font-bold ${d.isActive("heading",{level:3})?"bg-primary text-white":"bg-slate-700 text-gray-200 hover:bg-slate-600"}`,title:"Título H3",children:"H3"})]}),s.jsx("div",{className:"border-t border-slate-600 my-2"}),s.jsxs("div",{className:"space-y-1",children:[s.jsx("button",{onClick:()=>d.chain().focus().toggleBulletList().run(),className:`w-full p-2 rounded text-sm ${d.isActive("bulletList")?"bg-primary text-white":"bg-slate-700 text-gray-200 hover:bg-slate-600"}`,title:"Lista con viñetas",children:"•"}),s.jsx("button",{onClick:()=>d.chain().focus().toggleOrderedList().run(),className:`w-full p-2 rounded text-sm ${d.isActive("orderedList")?"bg-primary text-white":"bg-slate-700 text-gray-200 hover:bg-slate-600"}`,title:"Lista numerada",children:"1."})]}),s.jsx("div",{className:"border-t border-slate-600 my-2"}),s.jsxs("div",{className:"space-y-1",children:[s.jsx("button",{onClick:()=>d.chain().focus().toggleBlockquote().run(),className:`w-full p-2 rounded text-sm ${d.isActive("blockquote")?"bg-primary text-white":"bg-slate-700 text-gray-200 hover:bg-slate-600"}`,title:"Cita",children:'"'}),s.jsx("button",{onClick:()=>d.chain().focus().toggleCodeBlock().run(),className:`w-full p-2 rounded text-xs font-mono ${d.isActive("codeBlock")?"bg-primary text-white":"bg-slate-700 text-gray-200 hover:bg-slate-600"}`,title:"Bloque de código",children:"<>"}),s.jsx("button",{onClick:u,disabled:n,className:"w-full p-2 bg-slate-700 text-gray-200 rounded hover:bg-slate-600 text-sm disabled:opacity-50",title:"Insertar imagen",children:n?"⏳":"🖼️"})]}),s.jsx("div",{className:"border-t border-slate-600 my-2"}),s.jsxs("div",{className:"space-y-1",children:[s.jsx("label",{htmlFor:"text-color-picker-float",className:"w-full p-2 bg-slate-700 text-gray-200 rounded hover:bg-slate-600 text-xl cursor-pointer flex items-center justify-center",title:"Seleccionar color de texto",children:"🎨"}),s.jsx("input",{id:"text-color-picker-float",type:"color",onChange:p=>{d.chain().focus().setColor(p.target.value).run()},value:d.getAttributes("textStyle").color||"#e5e7eb",className:"w-full h-8 rounded cursor-pointer border border-slate-500",title:"Elegir color personalizado"}),s.jsx("button",{onClick:()=>d.chain().focus().unsetColor().run(),className:"w-full p-2 bg-slate-700 text-gray-200 rounded hover:bg-slate-600 text-sm",title:"Quitar color",children:"✕"})]}),s.jsx("div",{className:"border-t border-slate-600 my-2"}),s.jsx("button",{onClick:()=>d.chain().focus().clearNodes().run(),className:"w-full p-2 bg-red-500/20 text-red-400 rounded hover:bg-red-500/30 text-xs",title:"Limpiar formato",children:"🗑️"})]}),s.jsx("div",{className:"space-y-2 p-2 bg-slate-700 rounded-t-lg border border-slate-600 mb-0",children:s.jsxs("div",{className:"flex flex-wrap gap-2",children:[s.jsxs("select",{onChange:p=>{p.target.value&&d.chain().focus().setMark("textStyle",{fontSize:p.target.value}).run()},className:"px-2 py-1 rounded text-sm bg-slate-600 text-gray-200 hover:bg-slate-500 border border-slate-500",children:[s.jsx("option",{value:"",children:"Tamaño"}),wpe.map(p=>s.jsx("option",{value:p.value,children:p.label},p.value))]}),s.jsxs("select",{onChange:p=>{p.target.value&&d.chain().focus().setFontFamily(p.target.value).run()},className:"px-2 py-1 rounded text-sm bg-slate-600 text-gray-200 hover:bg-slate-500 border border-slate-500",children:[s.jsx("option",{value:"",children:"Fuente"}),kpe.map(p=>s.jsx("option",{value:p.value,children:p.label},p.value))]}),s.jsxs("select",{onChange:p=>{p.target.value&&d.chain().focus().setMark("textStyle",{lineHeight:p.target.value}).run()},className:"px-2 py-1 rounded text-sm bg-slate-600 text-gray-200 hover:bg-slate-500 border border-slate-500",children:[s.jsx("option",{value:"",children:"Espaciado"}),Spe.map(p=>s.jsxs("option",{value:p.value,children:["Línea ",p.label]},p.value))]})]})}),s.jsxs("div",{className:"relative mt-0 pr-20",children:[s.jsx(vde,{editor:d,className:"bg-slate-800 border border-slate-600 rounded-b-lg p-4 focus:outline-none focus:border-primary focus:ring-1 focus:ring-primary",style:{minHeight:"400px"}}),n&&s.jsx(_.div,{initial:{opacity:0}
17779,animate:{opacity:1},className:"absolute inset-0 bg-black/50 rounded-b-lg flex items-center justify-center z-50",children:s.jsxs("div",{className:"text-white text-center",children:[s.jsx(_.div,{animate:{rotate:360},transition:{duration:2,repeat:1/0,ease:"linear"},className:"w-8 h-8 border-4 border-white border-t-transparent rounded-full mx-auto mb-2"}),s.jsx("p",{children:"Subiendo imagen..."})]})})]}),l&&s.jsx(_.div,{initial:{opacity:0},animate:{opacity:1},className:"fixed inset-0 bg-black/50 flex items-center justify-center z-50",children:s.jsxs(_.div,{initial:{scale:.9,opacity:0},animate:{scale:1,opacity:1},className:"bg-slate-800 border border-red-500/50 rounded-lg p-6 max-w-sm mx-4",children:[s.jsx("h3",{className:"text-lg font-bold text-red-400 mb-2",children:"⚠️ Imagen demasiado grande"}),s.jsx("p",{className:"text-gray-300 mb-6",children:r}),s.jsx("button",{onClick:()=>c(!1),className:"w-full px-4 py-2 bg-primary text-white rounded-lg hover:bg-cyan-600 transition font-medium",children:"Entendido"})]})}),s.jsx("style",{children:`
17780        .ProseMirror {
17781          outline: none;
17782          color: #e5e7eb;
17783          line-height: 1.8;
17784        }
17785        
17786        .ProseMirror p {
17787          margin: 1.25rem 0;
17788          color: #e5e7eb;
17789          line-height: 1.8;
17790        }
17791        
17792        .ProseMirror h2 {
17793          font-size: 1.5rem;
17794          font-weight: bold;
17795          margin: 1.5rem 0 1rem 0;
17796          color: #e5e7eb;
17797          line-height: 1.6;
17798        }
17799        
17800        .ProseMirror h3 {
17801          font-size: 1.25rem;
17802          font-weight: bold;
17803          margin: 1.25rem 0 0.75rem 0;
17804          color: #e5e7eb;
17805          line-height: 1.6;
17806        }
17807        
17808        .ProseMirror ul,
17809        .ProseMirror ol {
17810          margin: 1rem 0;
17811          padding-left: 2rem;
17812          color: #e5e7eb;
17813          line-height: 1.8;
17814        }
17815        
17816        .ProseMirror li {
17817          margin: 0.5rem 0;
17818          line-height: 1.8;
17819        }
17820        
17821        .ProseMirror blockquote {
17822          border-left: 4px solid #06b6d4;
17823          padding-left: 1rem;
17824          margin: 1.25rem 0;
17825          color: #9ca3af;
17826          font-style: italic;
17827          line-height: 1.8;
17828        }
17829        
17830        .ProseMirror code {
17831          background-color: #1f2937;
17832          padding: 0.2rem 0.4rem;
17833          border-radius: 0.25rem;
17834          font-family: monospace;
17835          color: #fbbf24;
17836        }
17837        
17838        .ProseMirror pre {
17839          background-color: #111827;
17840          color: #e5e7eb;
17841          padding: 1rem;
17842          border-radius: 0.5rem;
17843          overflow-x: auto;
17844          margin: 1.25rem 0;
17845          border: 1px solid #374151;
17846          line-height: 1.6;
17847        }
17848        
17849        .ProseMirror pre code {
17850          background-color: transparent;
17851          padding: 0;
17852          color: inherit;
17853        }
17854        
17855        .ProseMirror img {
17856          max-width: 100%;
17857          height: auto;
17858          margin: 1.5rem 0;
17859          border-radius: 0.5rem;
17860        }
17861      `})]}):s.jsx("div",{children:"Cargando editor..."})}const Ape=1024*1024;function ED({initialData:t=null,initialBlog:e=null,isEditing:a=!1,onSave:n=null}){const{user:i}=hs(),r=e||t,[o,l]=k.useState({title:(r==null?void 0:r.title)||"",excerpt:(r==null?void 0:r.excerpt)||"",content:(r==null?void 0:r.content)||"",headerImage:(r==null?void 0:r.headerImage)||null,tags:(r==null?void 0:r.tags)||[],published:(r==null?void 0:r.published)||!1,language:(r==null?void 0:r.language)||"es"}),[c,d]=k.useState((r==null?void 0:r.slug)||""),[u,p]=k.useState(null),[m,h]=k.useState((r==null?void 0:r.headerImage)||null),[g,y]=k.useState([]),[x,v]=k.useState(""),[w,S]=k.useState(!1),[T,P]=k.useState(""),[M,C]=k.useState(""),[E,j]=k.useState(""),[N,L]=k.useState(!1),[O,R]=k.useState(!1),[G,ee]=k.useState("");k.useEffect(()=>{(async()=>{try{const ge=ga(St,"tags"),We=(await Ni(ge)).docs.map(si=>({id:si.id,...si.data()}));y(We)}catch(ge){console.error("Error cargando etiquetas:",ge)}})()},[]);const ke=ne=>{const{name:ge,value:Me}=ne.target;l(We=>({...We,[ge]:Me}))},ae=ne=>ne.toLowerCase().trim().replace(/[^\w\s-]/g,"").replace(/\s+/g,"-").replace(/-+/g,"-"),F=ne=>{const ge=ne.target.files[0];if(ge){if(ge.size>Ape){j(`La imagen es demasiado grande (${(ge.size/1024/1024).toFixed(2)} MB). Máximo permitido: 1 MB`),L(!0);return}p(ge);const Me=new FileReader;Me.onloadend=()=>{h(Me.result)}
17861,Me.readAsDataURL(ge)}},Z=()=>{p(null),h(null),l(ne=>({...ne,headerImage:null}))},re=async()=>{if(x.trim())try{const ne=ae(x);if(g.find(Vn=>Vn.slug===ne)){P("Esta etiqueta ya existe");return}const Me=ga(St,"tags"),si={id:(await Tl(Me,{name:x,slug:ne,description:"",color:"#06b6d4"})).id,name:x,slug:ne,description:"",color:"#06b6d4"};y(Vn=>[...Vn,si]),l(Vn=>({...Vn,tags:[...Vn.tags,x]})),v(""),P("")}catch(ne){P("Error al crear la etiqueta"),console.error(ne)}},fe=(ne,ge)=>{l(Me=>({...Me,tags:Me.tags.includes(ge)?Me.tags.filter(We=>We!==ge):[...Me.tags,ge]}))},ve=()=>o.title.trim()?o.excerpt.trim()?o.content.trim()?!m&&!t?(P("La imagen de encabezado es requerida"),!1):o.tags.length===0?(P("Debes seleccionar al menos una etiqueta"),!1):!0:(P("El contenido es requerido"),!1):(P("El resumen es requerido"),!1):(P("El título es requerido"),!1),Ie=async()=>{if(ve())try{S(!0),P(""),C("");let ne=o.headerImage;if(u)try{const We=Nk(Gk,`blog-headers/${Date.now()}-${u.name}`),si=await jk(We,u);ne=await Tk(si.ref)}catch(We){console.error("Error al subir imagen:",We),P("Error al subir la imagen. Intenta de nuevo."),S(!1);return}const ge=c.trim()?ae(c):ae(o.title),Me={title:o.title,slug:ge,excerpt:o.excerpt,content:o.content,headerImage:ne,tags:o.tags,author:i.email,published:o.published,language:o.language,views:(r==null?void 0:r.views)||0,featured:(r==null?void 0:r.featured)||!1,updatedAt:new Date};if(r&&r.id){const We=lu(St,"blogs",r.id);await h3(We,Me),C("Blog actualizado exitosamente")}else{Me.createdAt=new Date;const We=ga(St,"blogs"),si=await Tl(We,Me),Vn=`/blog/${ge}`;ee(Vn),R(!0),l({title:"",excerpt:"",content:"",headerImage:null,tags:[],published:!1,language:"es"}),p(null),h(null)}n&&n(),setTimeout(()=>C(""),3e3)}catch(ne){P("Error al guardar el blog: "+ne.message),console.error(ne)}finally{S(!1)}};return s.jsxs(_.div,{initial:{opacity:0,y:20},animate:{opacity:1,y:0},transition:{duration:.6},className:"space-y-6",children:[T&&s.jsx(_.div,{initial:{opacity:0,y:-10},animate:{opacity:1,y:0},className:"p-4 bg-red-500/10 border border-red-500/50 rounded-lg text-red-400",children:T}),M&&s.jsx(_.div,{initial:{opacity:0,y:-10},animate:{opacity:1,y:0},className:"p-4 bg-green-500/10 border border-green-500/50 rounded-lg text-green-400",children:M}),N&&s.jsx(_.div,{initial:{opacity:0}
17861,animate:{opacity:1},className:"fixed inset-0 bg-black/50 flex items-center justify-center z-50",children:s.jsxs(_.div,{initial:{scale:.9,opacity:0},animate:{scale:1,opacity:1},className:"bg-slate-800 border border-red-500/50 rounded-lg p-6 max-w-sm mx-4",children:[s.jsx("h3",{className:"text-lg font-bold text-red-400 mb-2",children:"⚠️ Imagen demasiado grande"}),s.jsx("p",{className:"text-gray-300 mb-6",children:E}),s.jsx("button",{onClick:()=>L(!1),className:"w-full px-4 py-2 bg-primary text-white rounded-lg hover:bg-cyan-600 transition font-medium",children:"Entendido"})]})}),s.jsxs("div",{className:"bg-slate-800/50 border border-slate-700 rounded-lg p-6",children:[s.jsx("h3",{className:"text-lg font-bold text-white mb-4",children:"Imagen de Encabezado"}),m?s.jsxs("div",{className:"relative",children:[s.jsx("img",{src:m,alt:"Preview",className:"w-full h-64 object-cover rounded-lg"}),s.jsx("button",{onClick:Z,className:"absolute top-2 right-2 px-3 py-1 bg-red-500 text-white rounded-lg hover:bg-red-600 transition",children:"Remover"})]}):s.jsxs("label",{className:"block border-2 border-dashed border-slate-600 rounded-lg p-8 text-center cursor-pointer hover:border-primary transition",children:[s.jsx("input",{type:"file",accept:"image/*",onChange:F,className:"hidden"}),s.jsxs("div",{className:"text-gray-400",children:[s.jsx("p",{className:"text-lg mb-2",children:"📸 Arrastra una imagen aquí o haz clic"}),s.jsx("p",{className:"text-sm",children:"PNG, JPG, GIF (máx. 5MB)"})]})]})]}),s.jsxs("div",{className:"bg-slate-800/50 border border-slate-700 rounded-lg p-6",children:[s.jsx("label",{className:"block text-sm font-medium text-gray-300 mb-2",children:"Título del Blog"}),s.jsx("input",{type:"text",name:"title",value:o.title,onChange:ke,placeholder:"Escribe el título de tu blog",className:"w-full px-4 py-3 bg-slate-700/50 border border-slate-600 rounded-lg text-white placeholder-gray-500 focus:outline-none focus:border-primary focus:ring-1 focus:ring-primary transition"}),s.jsxs("div",{className:"mt-2 flex items-center gap-2",children:[s.jsx("span",{className:"text-xs text-gray-500",children:"Slug:"}),s.jsx("input",{type:"text",value:c||ae(o.title)||"",onChange:ne=>d(ne.target.value.toLowerCase().replace(/[^a-z0-9\s-]/g,"").replace(/\s+/g,"-")),placeholder:ae(o.title)||"tu-titulo-aqui",className:"flex-1 px-2 py-1 text-xs bg-slate-700/30 border border-slate-600/50 rounded text-cyan-400 placeholder-gray-600 focus:outline-none focus:border-primary transition"}),c&&s.jsx("button",{type:"button",onClick:()=>d(""),className:"text-xs text-gray-500 hover:text-gray-300 transition",title:"Usar slug automático del título",children:"✕ Reset"})]})]}),s.jsxs("div",{className:"bg-slate-800/50 border border-slate-700 rounded-lg p-6",children:[s.jsx("label",{className:"block text-sm font-medium text-gray-300 mb-2",children:"Resumen (Excerpt)"}),s.jsx("textarea",{name:"excerpt",value:o.excerpt,onChange:ke,placeholder:"Escribe un resumen corto de tu blog",rows:"3",className:"w-full px-4 py-3 bg-slate-700/50 border border-slate-600 rounded-lg text-white placeholder-gray-500 focus:outline-none focus:border-primary focus:ring-1 focus:ring-primary transition resize-none"}),s.jsxs("p",{className:"text-xs text-gray-500 mt-2",children:[o.excerpt.length,"/160 caracteres"]})]}),s.jsxs("div",{className:"bg-slate-800/50 border border-slate-700 rounded-lg p-6",children:[s.jsx("label",{className:"block text-sm font-medium text-gray-300 mb-4",children:"Contenido del Blog"}),s.jsx(_pe,{value:o.content,onChange:ne=>l(ge=>({...ge,content:ne}))})]}),s.jsxs("div",{className:"bg-slate-800/50 border border-slate-700 rounded-lg p-6",children:[s.jsx("h3",{className:"text-lg font-bold text-white mb-4",children:"Etiquetas"}),s.jsxs("div",{className:"mb-6",children:[s.jsx("p",{className:"text-sm text-gray-400 mb-3",children:"Selecciona etiquetas:"}),s.jsx("div",{className:"flex flex-wrap gap-2",children:g.map(ne=>s.jsx("button",{onClick:()=>fe(ne.id,ne.name),className:`px-4 py-2 rounded-full text-sm font-medium transition ${o.tags.includes(ne.name)?"bg-primary text-white":"bg-slate-700 text-gray-300 hover:bg-slate-600"}`,children:ne.name},ne.id))})]}),s.jsxs("div",{className:"flex gap-2",children:[s.jsx("input",{type:"text",value:x,onChange:ne=>v(ne.target.value),placeholder:"Nombre de nueva etiqueta",className:"flex-1 px-4 py-2 bg-slate-700/50 border border-slate-600 rounded-lg text-white placeholder-gray-500 focus:outline-none focus:border-primary transition",onKeyPress:ne=>ne.key==="Enter"&&re()}),s.jsx("button",{onClick:re,className:"px-4 py-2 bg-primary text-white rounded-lg hover:bg-cyan-600 transition font-medium",children:"+ Agregar"})]})]}),s.jsxs("div",{className:"bg-slate-800/50 border border-slate-700 rounded-lg p-6",children:[s.jsx("label",{className:"block text-sm font-medium text-gray-300 mb-3",children:"Idioma del Blog"}),s.jsxs("div",{className:"flex gap-4",children:[s.jsxs("label",{className:"flex items-center gap-2 cursor-pointer",children:[s.jsx("input",{type:"radio",name:"language",value:"es",checked:o.language==="es",onChange:ne=>l(ge=>({...ge,language:ne.target.value})),className:"w-4 h-4"}),s.jsx("span",{className:"text-gray-300",children:"🇪🇸 Español"})]}),s.jsxs("label",{className:"flex items-center gap-2 cursor-pointer",children:[s.jsx("input",{type:"radio",name:"language",value:"en",checked:o.language==="en",onChange:ne=>l(ge=>({...ge,language:ne.target.value})),className:"w-4 h-4"}),s.jsx("span",{className:"text-gray-300",children:"🇬🇧 English"})]})]}),s.jsxs("p",{className:"text-xs text-gray-500 mt-2",children:["Este blog será visible solo cuando el sitio esté en ",o.language==="es"?"español":"inglés"]})]}),s.jsxs("div",{className:"bg-slate-800/50 border border-slate-700 rounded-lg p-6",children:[s.jsxs("label",{className:"flex items-center gap-3 cursor-pointer",children:[s.jsx("input",{type:"checkbox",checked:o.published,onChange:ne=>l(ge=>({...ge,published:ne.target.checked})),className:"w-5 h-5 rounded"}),s.jsx("span",{className:"text-white font-medium",children:"Publicar blog inmediatamente"})]}),s.jsx("p",{className:"text-xs text-gray-500 mt-2",children:o.published?"✅ Este blog será visible públicamente":"⏳ Este blog será guardado como borrador"})]}),s.jsx("div",{className:"flex gap-4",children:s.jsx("button",{onClick:Ie,disabled:w,className:"flex-1 px-6 py-3 bg-gradient-to-r from-cyan-500 to-blue-600 text-white rounded-lg font-semibold hover:shadow-lg hover:shadow-cyan-500/50 transition disabled:opacity-50 disabled:cursor-not-allowed flex items-center justify-center gap-2",children:w?s.jsxs(s.Fragment,{children:[s.jsx(_.div,{animate:{rotate:360},transition:{duration:1,repeat:1/0,ease:"linear"},className:"w-4 h-4 border-2 border-white border-t-transparent roun
17861ded-full"}),"Guardando..."]}):s.jsx(s.Fragment,{children:"💾 Guardar Blog"})})}),O&&s.jsx(_.div,{initial:{opacity:0},animate:{opacity:1},className:"fixed inset-0 bg-black/50 flex items-center justify-center z-50",onClick:()=>R(!1),children:s.jsxs(_.div,{initial:{scale:.9,opacity:0},animate:{scale:1,opacity:1},className:"bg-slate-800 border border-green-500/50 rounded-lg p-8 max-w-md mx-4 relative",onClick:ne=>ne.stopPropagation(),children:[s.jsx("button",{onClick:()=>R(!1),className:"absolute top-4 right-4 text-gray-400 hover:text-white transition-colors text-2xl leading-none","aria-label":"Cerrar",children:"×"}),s.jsxs("div",{className:"text-center",children:[s.jsx(_.div,{initial:{scale:0},animate:{scale:1},transition:{delay:.2,type:"spring"},className:"text-5xl mb-4",children:"✅"}),s.jsx("h3",{className:"text-2xl font-bold text-green-400 mb-2",children:"¡Blog creado exitosamente!"}),s.jsx("p",{className:"text-gray-300 mb-6",children:"Tu artículo ha sido publicado y está disponible en:"}),s.jsxs("div",{className:"bg-slate-700/50 border border-slate-600 rounded-lg p-4 mb-6",children:[s.jsx("p",{className:"text-sm text-gray-400 mb-2",children:"URL del blog:"}),s.jsx("p",{className:"text-primary font-mono text-sm break-all",children:G})]}),s.jsxs("div",{className:"flex gap-3",children:[s.jsx("button",{onClick:()=>{R(!1)},className:"flex-1 px-4 py-2 bg-slate-700 text-gray-300 rounded-lg hover:bg-slate-600 transition font-medium",children:"Crear otro"}),s.jsx("a",{href:G,target:"_blank",rel:"noopener noreferrer",className:"flex-1 px-4 py-2 bg-primary text-white rounded-lg hover:bg-cyan-600 transition font-medium text-center",children:"Ver blog"})]})]})]})})]})}function Epe(){return s.jsx(Do,{children:s.jsxs("div",{className:"space-y-6",children:[s.jsxs("div",{children:[s.jsx("h2",{className:"text-3xl font-bold text-white mb-2",children:"Crear Blog"}),s.jsx("p",{className:"text-gray-400",children:"Escribe un nuevo artículo para tu blog"})]}),s.jsx(ED,{isEditing:!1})]})})}function Cpe(){const[t,e]=k.useState([]),[a,n]=k.useState(!0),[i,r]=k.useState(""),[o,l]=k.useState(""),[c,d]=k.useState("all"),u=Qa(),{user:p}=hs();k.useEffect(()=>{(async()=>{try{n(!0);const x=ga(St,"blogs"),v=jl(x,Gn("author","==",p.email)),S=(await Ni(v)).docs.map(T=>({id:T.id,...T.data()}));e(S.sort((T,P)=>{var M,C;return((M=P.createdAt)==null?void 0:M.toDate())-((C=T.createdAt)==null?void 0:C.toDate())}))}catch(x){r("Error al cargar blogs: "+x.message),console.error(x)}finally{n(!1)}})()},[p.email]);const m=t.filter(y=>{const x=y.title.toLowerCase().includes(o.toLowerCase()),v=c==="all"||c==="published"&&y.published||c==="draft"&&!y.published;return x&&v}),h=async y=>{if(window.confirm("¿Estás seguro de que deseas eliminar este blog?"))try{await _J(lu(St,"blogs",y)),e(t.filter(x=>x.id!==y))}catch(x){r("Error al eliminar blog: "+x.message)}},g=async(y,x)=>{try{const v=lu(St,"blogs",y);await h3(v,{published:!x}),e(t.map(w=>w.id===y?{...w,published:!x}:w))}catch(v){r("Error al actualizar blog: "+v.message)}};return a?s.jsx(Do,{children:s.jsx("div",{className:"flex items-center justify-center h-96",children:s.jsx(_.div,{animate:{rotate:360},transition:{duration:2,repeat:1/0,ease:"linear"},className:"w-12 h-12 border-4 border-primary border-t-transparent rounded-full"})})}):s.jsx(Do,{children:s.jsxs("div",{className:"space-y-6",children:[s.jsxs("div",{children:[s.jsx("h2",{className:"text-3xl font-bold text-white mb-2",children:"Editar Blogs"}),s.jsx("p",{className:"text-gray-400",children:"Gestiona tus artículos de blog publicados y borradores"})]}),i&&s.jsx(_.div,{initial:{opacity:0,y:-10},animate:{opacity:1,y:0},className:"p-4 bg-red-500/10 border border-red-500/50 rounded-lg text-red-400",children:i}),s.jsx("div",{className:"bg-slate-800/50 border border-slate-700 rounded-lg p-6 space-y-4",children:s.jsxs("div",{className:"grid grid-cols-1 md:grid-cols-2 gap-4",children:[s.jsx("input",{type:"text",placeholder:"Buscar blogs...",value:o,onChange:y=>l(y.target.value),className:"px-4 py-2 bg-slate-700/50 border border-slate-600 rounded-lg text-white placeholder-gray-500 focus:outline-none focus:border-primary transition"}),s.jsxs("select",{value:c,onChange:y=>
17861d(y.target.value),className:"px-4 py-2 bg-slate-700/50 border border-slate-600 rounded-lg text-white focus:outline-none focus:border-primary transition",children:[s.jsx("option",{value:"all",children:"Todos los blogs"}),s.jsx("option",{value:"published",children:"Publicados"}),s.jsx("option",{value:"draft",children:"Borradores"})]})]})}),m.length===0?s.jsxs("div",{className:"bg-slate-800/50 border border-slate-700 rounded-lg p-12 text-center",children:[s.jsx("p",{className:"text-gray-400 text-lg mb-4",children:"No hay blogs para mostrar"}),s.jsx("button",{onClick:()=>u("/admin-blog/create"),className:"px-6 py-2 bg-primary text-white rounded-lg hover:bg-cyan-600 transition font-medium",children:"Crear tu primer blog"})]}):s.jsx("div",{className:"space-y-4",children:m.map((y,x)=>{var v,w;return s.jsx(_.div,{initial:{opacity:0,y:20},animate:{opacity:1,y:0},transition:{delay:x*.1},className:"bg-slate-800/50 border border-slate-700 rounded-lg p-6 hover:border-slate-600 transition",children:s.jsxs("div",{className:"flex gap-6",children:[y.headerImage&&s.jsx("img",{src:y.headerImage,alt:y.title,className:"w-24 h-24 object-cover rounded-lg flex-shrink-0"}),s.jsxs("div",{className:"flex-1 min-w-0",children:[s.jsxs("div",{className:"flex items-start justify-between gap-4 mb-2",children:[s.jsx("h3",{className:"text-lg font-bold text-white truncate",children:y.title}),s.jsx("span",{className:`px-3 py-1 rounded-full text-xs font-medium whitespace-nowrap ${y.published?"bg-green-500/20 text-green-400":"bg-yellow-500/20 text-yellow-400"}`,children:y.published?"✅ Publicado":"⏳ Borrador"})]}),s.jsx("p",{className:"text-gray-400 text-sm mb-3 line-clamp-2",children:y.excerpt}),s.jsxs("div",{className:"flex flex-wrap gap-2 mb-4",children:[y.tags.slice(0,3).map(S=>s.jsxs("span",{className:"px-2 py-1 bg-slate-700 text-gray-300 text-xs rounded",children:["#",S]},S)),y.tags.length>3&&s.jsxs("span",{className:"px-2 py-1 text-gray-500 text-xs",children:["+",y.tags.length-3," más"]})]}),s.jsxs("p",{className:"text-xs text-gray-500 mb-4",children:["Creado: ",(w=(v=y.createdAt)==null?void 0:v.toDate)==null?void 0:w.call(v).toLocaleDateString("es-ES")," • Vistas: ",y.views||0]}),s.jsxs("div",{className:"flex gap-2 flex-wrap",children:[s.jsx("button",{onClick:()=>u(`/admin-blog/edit/${y.id}`),className:"px-4 py-2 bg-blue-500/20 text-blue-400 hover:bg-blue-500/30 rounded-lg text-sm font-medium transition",children:"✏️ Editar"}),s.jsx("button",{onClick:()=>g(y.id,y.published),className:`px-4 py-2 rounded-lg text-sm font-medium transition ${y.published?"bg-yellow-500/20 text-yellow-400 hover:bg-yellow-500/30":"bg-green-500/20 text-green-400 hover:bg-green-500/30"}`,children:y.published?"🔒 Despublicar":"🔓 Publicar"}),s.jsx("a",{href:`/blog/${y.slug}`,target:"_blank",rel:"noopener noreferrer",className:"px-4 py-2 bg-slate-700 text-gray-300 hover:bg-slate-600 rounded-lg text-sm font-medium transition",children:"👁️ Ver"}),s.jsx("button",{onClick:()=>h(y.id),className:"px-4 py-2 bg-red-500/20 text-red-400 hover:bg-red-500/30 rounded-lg text-sm font-medium transition",children:"🗑️ Eliminar"})]})]})]})},y.id)})}),s.jsxs("div",{className:"grid grid-cols-1 md:grid-cols-3 gap-4",children:[s.jsxs("div",{className:"bg-slate-800/50 border border-slate-700 rounded-lg p-4 text-center",children:[s.jsx("p",{className:"text-gray-400 text-sm",children:"Total de Blogs"}),s.jsx("p",{className:"text-2xl font-bold text-white mt-2",children:t.length})]}),s.jsxs("div",{className:"bg-slate-800/50 border border-slate-700 rounded-lg p-4 text-center",children:[s.jsx("p",{className:"text-gray-400 text-sm",children:"Publicados"}),s.jsx("p",{className:"text-2xl font-bold text-green-400 mt-2",children:t.filter(y=>y.published).length})]}),s.jsxs("div",{className:"bg-slate-800/50 border border-slate-700 rounded-lg p-4 text-center",children:[s.jsx("p",{className:"text-gray-400 text-sm",children:"Borradores"}),s.jsx("p",{className:"text-2xl font-bold text-yellow-400 mt-2",children:t.filter(y=>!y.published).length})]})]})]})})}function jpe(){const{id:t}=jP(),e=Qa(),{user:a}=hs(),[n,i]=k.useState(null),[r,o]=k.useState(!0),[l,c]=k.useState("");return k.useEffect(()=>{(async()=>{try{o(!0);const u=lu(St,"blogs",t),p=await SJ(u);if(!p.exists()){c("Blog no encontrado");return}const m={id:p.id,...p.data()};if(m.author!==a.email){c("No tienes permiso para editar este blog");return}i(m)}catch(u){console.error("Error al cargar blog:",u),c("Error al cargar el blog")}finally{o(!1)}})()}
17861,[t,a.email]),r?s.jsx(Do,{children:s.jsx("div",{className:"flex items-center justify-center h-96",children:s.jsx(_.div,{animate:{rotate:360},transition:{duration:2,repeat:1/0,ease:"linear"},className:"w-12 h-12 border-4 border-primary border-t-transparent rounded-full"})})}):l?s.jsx(Do,{children:s.jsxs("div",{className:"text-center py-12",children:[s.jsx("p",{className:"text-red-400 text-lg mb-4",children:l}),s.jsx("button",{onClick:()=>e("/admin-blog/edit"),className:"px-6 py-2 bg-primary text-white rounded-lg hover:bg-cyan-600 transition",children:"Volver a blogs"})]})}):s.jsx(Do,{children:s.jsxs("div",{className:"space-y-6",children:[s.jsxs("div",{children:[s.jsx("h2",{className:"text-3xl font-bold text-white mb-2",children:"Editar Blog"}),s.jsx("p",{className:"text-gray-400",children:"Actualiza tu artículo de blog"})]}),n&&s.jsx(ED,{initialBlog:n,isEditing:!0})]})})}function CD({blog:t,index:e}){var r,o,l;const{t:a}=$(),n=a("blog",{returnObjects:!0}),i=t.excerpt||((r=t.content)==null?void 0:r.replace(/<[^>]*>/g,"").substring(0,150))+"...";return s.jsxs(_.div,{initial:{opacity:0,y:20},animate:{opacity:1,y:0},transition:{delay:e*.1},className:"bg-slate-800/50 border border-slate-700 rounded-lg overflow-hidden hover:border-primary/50 transition group",children:[t.headerImage&&s.jsx("div",{className:"relative h-48 overflow-hidden",children:s.jsx("img",{src:t.headerImage,alt:t.title,className:"w-full h-full object-cover group-hover:scale-105 transition duration-300"})}),s.jsxs("div",{className:"p-6",children:[s.jsxs("div",{className:"flex items-center justify-between mb-3",children:[s.jsx("span",{className:"text-xs text-primary font-medium",children:(l=(o=t.createdAt)==null?void 0:o.toDate)==null?void 0:l.call(o).toLocaleDateString("es-ES")}),s.jsxs("span",{className:"text-xs text-gray-400",children:[t.views||0," ",n.vistas]})]}),s.jsx("h3",{className:"text-xl font-bold text-white mb-3 line-clamp-2 group-hover:text-primary transition",children:t.title}),s.jsx("p",{className:"text-gray-400 text-sm mb-4 line-clamp-3",children:i}),s.jsx("div",{className:"mb-4",children:s.jsxs("p",{className:"text-xs text-gray-400",children:[s.jsxs("span",{className:"text-gray-500",children:[n.por,": "]}),s.jsx("span",{className:"text-primary font-medium",children:t.author})]})}),s.jsxs(Te,{to:`/blog/${t.slug}`,className:"inline-block px-4 py-2 bg-primary/20 text-primary hover:bg-primary hover:text-white rounded-lg text-sm font-medium transition",children:[n.leerMas," →"]})]})]})}function Tpe({tags:t,selectedTags:e,onTagChange:a}){const{t:n}=$(),i=n("blog",{returnObjects:!0}),r=o=>{e.includes(o)?a(e.filter(l=>l!==o)):a([...e,o])};return s.jsxs(_.div,{initial:{opacity:0,x:-20},animate:{opacity:1,x:0},className:"bg-slate-800/50 border border-slate-700 rounded-lg p-6 h-fit sticky top-24",children:[s.jsx("h3",{className:"text-lg font-bold text-white mb-4",children:i.filtrarPorEtiqueta}),t.length===0?s.jsx("p",{className:"text-gray-400 text-sm",children:"No hay etiquetas disponibles"}):s.jsx("div",{className:"space-y-2",children:t.map(o=>s.jsxs("label",{className:"flex items-center gap-3 cursor-pointer group",children:[s.jsx("input",{type:"checkbox",checked:e.includes(o),onChange:()=>r(o),className:"w-4 h-4 rounded border-slate-600 bg-slate-700 text-primary cursor-pointer"}),s.jsxs("span",{className:"text-gray-300 group-hover:text-primary transition text-sm",children:["#",o]}),s.jsxs("span",{className:"text-gray-500 text-xs ml-auto",children:["(",t.filter(l=>l===o).length,")"]})]},o))}),e.length>0&&s.jsx("button",{onClick:()=>a([]),className:"mt-4 w-full px-4 py-2 bg-slate-700 hover:bg-slate-600 text-gray-300 rounded-lg text-sm font-medium transition",children:i.limpiarFiltros})]})}let cm=null;const jD=async()=>{if(cm)return cm;try{const t=ga(St,"tags");return cm=(await Ni(t)).docs.map(a=>({id:a.id,...a.data()})),cm}catch(t){return console.error("Error cargando etiquetas:",t),[]}},Npe=async(t,e=null)=>{if(!t||t.length<20||!/^[a-f0-9]{20,}$/.test(t))return t;const n=(e||await jD()).find(i=>i.id===t);return(n==null?void 0:n.name)||t},Zb=async(t=[])=>{if(!t||t.length===0)return[];const e=await jD();return Promise.all(t.map(a=>Npe(a,e)))};function Ipe(){const{i18n:t}=$(),{t:e}=$(),a=e("blog",{returnObjects:!0}),n=t.language||"es";Mg({title:"Blog - Haka Lab",description:"Artículos sobre testing, calida
17861d de software y automatización de pruebas",keywords:"blog, testing, calidad, automatización, software"});const[i,r]=k.useState([]),[o,l]=k.useState(!0),[c,d]=k.useState(""),[u,p]=k.useState([]),[m,h]=k.useState([]);k.useEffect(()=>{(async()=>{try{l(!0);const x=ga(St,"blogs"),v=jl(x,Gn("published","==",!0),Gn("language","==",n));let S=(await Ni(v)).docs.map(P=>({id:P.id,...P.data()}));S=await Promise.all(S.map(async P=>({...P,tags:await Zb(P.tags)}))),S.sort((P,M)=>{var C,E;return((C=M.createdAt)==null?void 0:C.toDate())-((E=P.createdAt)==null?void 0:E.toDate())}),r(S);const T=new Set;S.forEach(P=>{var M;(M=P.tags)==null||M.forEach(C=>T.add(C))}),h(Array.from(T).sort())}catch(x){console.error("Error al cargar blogs:",x)}finally{l(!1)}})()},[n]);const g=i.filter(y=>{var w;const x=y.title.toLowerCase().includes(c.toLowerCase())||((w=y.excerpt)==null?void 0:w.toLowerCase().includes(c.toLowerCase())),v=u.length===0||u.some(S=>{var T;return(T=y.tags)==null?void 0:T.includes(S)});return x&&v});return s.jsx("div",{children:s.jsxs("main",{children:[s.jsx("section",{className:"bg-gradient-to-b from-slate-900 to-dark py-8 md:py-12",children:s.jsx("div",{className:"max-w-7xl mx-auto px-4 sm:px-6 lg:px-8",children:s.jsxs(_.div,{initial:{opacity:0,y:20},animate:{opacity:1,y:0},className:"text-center",children:[s.jsx("h1",{className:"text-4xl md:text-5xl font-bold text-white mb-4",children:a.titleFront}),s.jsx("p",{className:"text-xl text-gray-400 max-w-2xl mx-auto",children:a.descripcion})]})})}),s.jsx("section",{className:"py-8 md:py-12",children:s.jsx("div",{className:"max-w-7xl mx-auto px-4 sm:px-6 lg:px-8",children:s.jsxs("div",{className:"grid grid-cols-1 lg:grid-cols-4 gap-8",children:[s.jsx("div",{className:"lg:col-span-1",children:s.jsx(Tpe,{tags:m,selectedTags:u,onTagChange:p})}),s.jsxs("div",{className:"lg:col-span-3",children:[s.jsx(_.div,{initial:{opacity:0,y:20},animate:{opacity:1,y:0},className:"mb-8",children:s.jsx("input",{type:"text",placeholder:a.buscar,value:c,onChange:y=>d(y.target.value),className:"w-full px-6 py-3 bg-slate-800/50 border border-slate-700 rounded-lg text-white placeholder-gray-500 focus:outline-none focus:border-primary transition"})}),o?s.jsx("div",{className:"flex items-center justify-center h-96",children:s.jsx(_.div,{animate:{rotate:360},transition:{duration:2,repeat:1/0,ease:"linear"},className:"w-12 h-12 border-4 border-primary border-t-transparent rounded-full"})}):g.length===0?s.jsx(_.div,{initial:{opacity:0}
17861,animate:{opacity:1},className:"bg-slate-800/50 border border-slate-700 rounded-lg p-12 text-center",children:s.jsx("p",{className:"text-gray-400 text-lg",children:i.length===0?"No hay artículos publicados aún":"No se encontraron artículos con los filtros seleccionados"})}):s.jsx("div",{className:"grid grid-cols-1 md:grid-cols-2 gap-6",children:g.map((y,x)=>s.jsx(CD,{blog:y,index:x},y.id))}),g.length>0&&s.jsxs(_.p,{initial:{opacity:0},animate:{opacity:1},className:"text-center text-gray-400 text-sm mt-8",children:[a.mostrando," ",g.length," ",a.de," ",i.length," ",a.articulos]})]})]})})})]})})}function Ppe(){var m,h,g,y;const{slug:t}=jP(),e=Qa(),{i18n:a}=$(),n=a.language||"es",[i,r]=k.useState(null),[o,l]=k.useState([]),[c,d]=k.useState(!0),[u,p]=k.useState("");return k.useEffect(()=>{(async()=>{try{d(!0);const v=ga(St,"blogs"),w=jl(v,Gn("slug","==",t),Gn("published","==",!0),Gn("language","==",n)),S=await Ni(w);if(S.empty){p("Blog no encontrado");return}let T={id:S.docs[0].id,...S.docs[0].data()};T.tags=await Zb(T.tags),r(T);const P=ga(St,"blogs"),M=jl(P,Gn("published","==",!0),Gn("language","==",n));let E=(await Ni(M)).docs.map(N=>({id:N.id,...N.data()}));E=await Promise.all(E.map(async N=>({...N,tags:await Zb(N.tags)})));const j=E.filter(N=>{var L;return N.id!==T.id&&((L=N.tags)==null?void 0:L.some(O=>{var R;return(R=T.tags)==null?void 0:R.includes(O)}))}).slice(0,3);l(j)}catch(v){console.error("Error al cargar blog:",v),p("Error al cargar el blog")}finally{d(!1)}})()},[t,n]),Mg({title:(i==null?void 0:i.title)||"Blog - Haka Lab",description:(i==null?void 0:i.excerpt)||"Artículo del blog de Haka Lab",keywords:((m=i==null?void 0:i.tags)==null?void 0:m.join(", "))||"blog, testing"}),c?s.jsx("div",{className:"flex items-center justify-center min-h-screen",children:s.jsx(_.div,{animate:{rotate:360},transition:{duration:2,repeat:1/0,ease:"linear"},className:"w-12 h-12 border-4 border-primary border-t-transparent rounded-full"})}):u||!i?s.jsx("div",{className:"flex items-center justify-center min-h-screen",children:s.jsxs("div",{className:"text-center",children:[s.jsx("p",{className:"text-gray-400 text-lg mb-4",children:u}),s.jsx("button",{onClick:()=>e("/blog"),className:"px-6 py-2 bg-primary text-white rounded-lg hover:bg-cyan-600 transition",children:"Volver al blog"})]})}):s.jsxs("div",{children:[i.headerImage&&s.jsx(_.div,{initial:{opacity:0}
17861,animate:{opacity:1},className:"flex justify-center py-8",children:s.jsx("img",{src:i.headerImage,alt:i.title,className:"max-w-4xl w-full h-64 object-cover rounded-lg"})}),s.jsx("section",{className:"py-16 md:py-24",children:s.jsxs("div",{className:"max-w-5xl mx-auto px-4 sm:px-6 lg:px-8",children:[s.jsxs(_.div,{initial:{opacity:0,y:20},animate:{opacity:1,y:0},className:"mb-8",children:[s.jsxs("div",{className:"flex items-center justify-between mb-4",children:[s.jsx("span",{className:"text-sm text-primary font-medium",children:(g=(h=i.createdAt)==null?void 0:h.toDate)==null?void 0:g.call(h).toLocaleDateString("es-ES")}),s.jsxs("span",{className:"text-sm text-gray-400",children:[i.views||0," vistas"]})]}),s.jsx("h1",{className:"text-4xl md:text-5xl font-bold text-white mb-4",children:i.title}),s.jsx("div",{className:"flex flex-wrap gap-2",children:(y=i.tags)==null?void 0:y.map(x=>s.jsxs("span",{className:"px-3 py-1 bg-primary/20 text-primary rounded-full text-sm",children:["#",x]},x))})]}),s.jsx(_.div,{initial:{opacity:0,y:20},animate:{opacity:1,y:0},transition:{delay:.1},className:"blog-content max-w-none mb-16",dangerouslySetInnerHTML:{__html:i.content},style:{fontSize:"inherit",lineHeight:"inherit",fontFamily:"inherit"}}),s.jsx("style",{children:`
17862            .blog-content {
17863              color: #e5e7eb;
17864              line-height: 1.8;
17865            }
17866            
17867            .blog-content p {
17868              margin: 1.25rem 0;
17869              color: #e5e7eb;
17870              line-height: inherit;
17871            }
17872            
17873            .blog-content h2 {
17874              font-size: 1.5rem;
17875              font-weight: bold;
17876              margin: 1.5rem 0 1rem 0;
17877              color: #e5e7eb;
17878              line-height: 1.6;
17879            }
17880            
17881            .blog-content h3 {
17882              font-size: 1.25rem;
17883              font-weight: bold;
17884              margin: 1.25rem 0 0.75rem 0;
17885              color: #e5e7eb;
17886              line-height: 1.6;
17887            }
17888            
17889            .blog-content ul,
17890            .blog-content ol {
17891              margin: 1rem 0;
17892              padding-left: 2rem;
17893              color: #e5e7eb;
17894              line-height: inherit;
17895            }
17896            
17897            .blog-content li {
17898              margin: 0.5rem 0;
17899              line-height: inherit;
17900            }
17901            
17902            .blog-content blockquote {
17903              border-left: 4px solid #06b6d4;
17904              padding-left: 1rem;
17905              margin: 1.25rem 0;
17906              color: #9ca3af;
17907              font-style: italic;
17908              line-height: inherit;
17909            }
17910            
17911            .blog-content code {
17912              background-color: #1f2937;
17913              padding: 0.2rem 0.4rem;
17914              border-radius: 0.25rem;
17915              font-family: monospace;
17916              color: #fbbf24;
17917            }
17918            
17919            .blog-content pre {
17920              background-color: #111827;
17921              color: #e5e7eb;
17922              padding: 1rem;
17923              border-radius: 0.5rem;
17924              overflow-x: auto;
17925              margin: 1.25rem 0;
17926              border: 1px solid #374151;
17927              line-height: 1.6;
17928            }
17929            
17930            .blog-content pre code {
17931              background-color: transparent;
17932              padding: 0;
17933              color: inherit;
17934            }
17935            
17936            .blog-content img {
17937              max-width: 100%;
17938              height: auto;
17939              margin: 1.5rem 0;
17940              border-radius: 0.5rem;
17941            }
17942            
17943            .blog-content span[style*="font-size"],
17944            .blog-content span[style*="line-height"],
17945            .blog-content span[style*="font-family"] {
17946              all: revert;
17947            }
17948          `}),s.jsx(_.div,{initial:{opacity:0}
17948,animate:{opacity:1},transition:{delay:.2},className:"border-t border-slate-700 pt-8 mb-16",children:s.jsxs("p",{className:"text-gray-400",children:[s.jsx("span",{className:"font-medium text-white",children:"Autor:"})," ",i.author||"Haka Lab"]})}),o.length>0&&s.jsxs(_.div,{initial:{opacity:0,y:20},animate:{opacity:1,y:0},transition:{delay:.3},children:[s.jsx("h2",{className:"text-2xl font-bold text-white mb-8",children:"Artículos relacionados"}),s.jsx("div",{className:"grid grid-cols-1 md:grid-cols-3 gap-6",children:o.map((x,v)=>s.jsx(CD,{blog:x,index:v},x.id))})]}),s.jsx(_.div,{initial:{opacity:0},animate:{opacity:1},transition:{delay:.4},className:"mt-16 text-center",children:s.jsx("button",{onClick:()=>e("/blog"),className:"px-6 py-3 bg-primary/20 text-primary hover:bg-primary hover:text-white rounded-lg font-medium transition",children:"← Volver al blog"})})]})})]})}function JT(){const{t}=$(),e=Qa();return k.useEffect(()=>{document.title="404 - Página no encontrada | Haka Lab";const a=document.querySelector('meta[name="description"]');a&&a.setAttribute("content","La página que buscas no existe. Vuelve a Haka Lab para explorar nuestros servicios de testing y automatización.");const n=document.querySelector('meta[name="robots"]');if(n)n.setAttribute("content","noindex, nofollow");else{const i=document.createElement("meta");i.name="robots",i.content="noindex, nofollow",document.head.appendChild(i)}},[]),s.jsxs("div",{className:"min-h-screen bg-dark flex flex-col items-center justify-center relative overflow-hidden",children:[s.jsx("div",{className:"absolute inset-0 bg-gradient-to-br from-dark via-dark to-dark"}),s.jsx("div",{className:"hero-glow"}),s.jsxs("div",{className:"relative z-10 text-center px-4",children:[s.jsx("h1",{className:"text-9xl font-bold text-primary opacity-20 select-none",children:"404"}),s.jsx("div",{className:"absolute inset-0 flex items-center justify-center"}),s.jsx("p",{className:"text-xl text-gray-400 mt-8 max-w-lg mx-auto mb-6",children:"Lo sentimos, la página que buscas no existe o ha sido movida. Puede que la URL esté mal escrita o que el contenido ya no esté disponible."}),s.jsx("p",{className:"text-lg text-gray-500 max-w-md mx-auto mb-10",children:"Explora nuestros servicios de testing automatizado, performance y soluciones de calidad de software."}),s.jsxs("div",{className:"flex flex-col sm:flex-row gap-4 justify-center",children:[s.jsx("button",{onClick:()=>e("/"),className:"bg-primary border-2 border-primary text-dark px-8 py-3 rounded-2xl text-lg font-semibold hover:bg-dark hover:text-primary transition-all duration-300",children:"Volver al Inicio"}),s.jsx("button",{onClick:()=>e("/servicios"),className:"border-2 border-primary/50 text-primary px-8 py-3 rounded-2xl text-lg font-semibold hover:bg-primary hover:text-dark transition-all duration-300",children:"Ver Servicios"})]}),s.jsxs("div",{className:"mt-12 text-sm text-gray-500",children:[s.jsx("p",{className:"mb-4",children:"También puedes visitar:"}),s.jsxs("div",{className:"flex flex-wrap justify-center gap-4",children:[s.jsx("button",{onClick:()=>e("/productos"),className:"hover:text-primary transition-colors",children:"Productos"}),s.jsx("span",{children:"•"}),s.jsx("button",{onClick:()=>e("/nosotros"),className:"hover:text-primary transition-colors",children:"Nosotros"}),s.jsx("span",{children:"•"}),s.jsx("button",{onClick:()=>e("/casosdeexito"),className:"hover:text-primary transition-colors",children:"Casos de Éxito"}),s.jsx("span",{children:"•"}),s.jsx("button",{onClick:()=>e("/blog"),className:"hover:text-primary transition-colors",children:"Blog"})]})]})]}),s.jsx("div",{className:"absolute bottom-0 w-full",children:s.jsx(ie,{variant:1})})]})}function Rpe(){const{pathname:t}=fn();k.useEffect(()=>{window.scrollTo({top:0,left:0,behavior:"auto"})},[t])}function Lpe(){const t=fn();k.useEffect(()=>{LO().then(e=>{if(e){const a=RO();OO(a,"page_view",{page_path:t.pathname,page_title:document.title,page_location:window.location.href})}})},[t.pathname])}function Ope(){return Rpe(),Lpe(),null}function Mpe(){const{isOpen:t,modalTitle:e,closeModal:a}=oa();return s.jsx(Yr,{isOpen:t,onClose:a,title:e})}function Dpe(){return s.jsx(nee,{children:s.jsx(z8,{children:s.jsxs(j8,{children:[s.jsx(Ope,{}),s.jsxs("div",{className:"min-h-screen bg-dark flex flex-col",children:[s.jsx(PH,{}),s.jsx("main",{className:"flex-grow",style:{overflowX:"clip"},children:s.jsxs(n8,{children:[s.jsx(le,{path:"/",element:s.jsx(xee,{})}),s.jsx(le,{path:"/servicios",element:s.jsx(Cee,{})}),s.jsx(le,{path:"/nosotros",element:s.jsx(Pee,{})}),s.jsx(le,{path:"/casosdeexito",element:s.jsx(Yee,{})}),s.jsx(le,{path:"/productos",element:s.jsx(nte,{})}),s.jsx(le,{path:"/hakaboost",element:s.jsx(cte,{})}),s.jsx(le,{path:"/hakabuddy",element:s.jsx(gte,{})}),s.jsx(le,{path:"/hakapath",element:s.jsx(kte,{})}),s.jsx(le,{path:"/hakartc",element:s.jsx(Cte,{})}),s.jsx(le,{path:"/haka-insight",element:s.jsx(Rte,{})}),s.jsx(le,{path:"/haka-engine",element:s.jsx(Dte,{})}),s.jsx(le,{path:"/haka-ai-studio",element:s.jsx($te,{})}),s.jsx(le,{path:"/hakalens",element:s.jsx(eae,{})}),s.jsx(le,{path:"/haka-automation-engine",element:s.jsx(Xae,{})}),s.jsx(le,{path:"/salesforce-testing",element:s.jsx(Uae,{})}),s.jsx(le,{path:"/productos/terms",element:s.jsx(lie,{})}),s.jsx(le,{path:"/politica-privacidad",element:s.jsx(cie,{})}),s.jsx(le,{path:"/docs/haka-playwright-engine",element:s.jsx(At,{children:s.jsx(Ot,{children:s.jsx(Une,{})})})}),s.jsx(le,{path:"/docs/haka-playwright-engine/docs",element:s.jsx(At,{children:s.jsx(Ot,{children:s.jsx(rne,{})})})}),s.jsx(le,{path:"/docs/haka-playwright-engine/faq",element:s.jsx(At,{children:s.jsx(Ot,{children:s.jsx(eie,{})})})}),s.jsx(le,{path:"/docs/haka-playwright-engine/videos",element:s.jsx(At,{children:s.jsx(Ot,{children:s.jsx(gne,{})})})}),s.jsx(le,{path:"/docs/haka-ai-studio",element:s.jsx(At,{children:s.jsx(Ot,{children:s.jsx($ne,{})})})}),s.jsx(le,{path:"/docs/haka-ai-studio/docs",element:s.jsx(At,{children:s.jsx(Ot,{children:s.jsx(xne,{})})})}),s.jsx(le,{path:"/docs/haka-ai-studio/faq",element:s.jsx(At,{children:s.jsx(Ot,{children:s.jsx(tie,{})})})}),s.jsx(le,{path:"/docs/hakaboost",element:s.jsx(At,{children:s.jsx(Ot,{children:s.jsx(Wne,{})})})}),s.jsx(le,{path:"/docs/hakaboost/docs",element:s.jsx(At,{children:s.jsx(Ot,{children:s.jsx(_ne,{})})})}),s.jsx(le,{path:"/docs/hakaboost/faq",element:s.jsx(At,{children:s.jsx(Ot,{children:s.jsx(aie,{})})})}),s.jsx(le,{path:"/docs/hakabuddy",element:s.jsx(At,{children:s.jsx(Ot,{children:s.jsx(Gne,{})})})}),s.jsx(le,{path:"/docs/hakabuddy/docs",element:s.jsx(At,{children:s.jsx(Ot,{children:s.jsx(Nne,{})})})}),s.jsx(le,{path:"/docs/hakabuddy/faq",element:s.jsx(At,{children:s.jsx(Ot,{children:s.jsx(nie,{})})})}),s.jsx(le,{path:"/docs/hakapath",element:s.jsx(At,{children:s.jsx(Ot,{children:s.jsx(Kne,{})})})}
17948),s.jsx(le,{path:"/docs/hakapath/docs",element:s.jsx(At,{children:s.jsx(Ot,{children:s.jsx(Mne,{})})})}),s.jsx(le,{path:"/docs/hakapath/faq",element:s.jsx(At,{children:s.jsx(Ot,{children:s.jsx(iie,{})})})}),s.jsx(le,{path:"/docs/login",element:s.jsx(At,{children:s.jsx(Hne,{})})}),s.jsx(le,{path:"/docs",element:s.jsx(At,{children:s.jsx(Ot,{children:s.jsx(Fne,{})})})}),s.jsx(le,{path:"/framework-hakalab",element:s.jsx(q0,{children:s.jsx(ane,{})})}),s.jsx(le,{path:"/haka-quick-analysis",element:s.jsx(q0,{children:s.jsx(Rae,{})})}),s.jsx(le,{path:"/intest",element:s.jsx(q0,{children:s.jsx(sie,{})})}),s.jsx(le,{path:"/blog",element:s.jsx(Ipe,{})}),s.jsx(le,{path:"/blog/:slug",element:s.jsx(Ppe,{})}),s.jsx(le,{path:"/admin-blog",element:s.jsx(die,{})}),s.jsx(le,{path:"/admin-blog/dashboard",element:s.jsx(Gp,{children:s.jsx(uie,{})})}),s.jsx(le,{path:"/admin-blog/create",element:s.jsx(Gp,{children:s.jsx(Epe,{})})}),s.jsx(le,{path:"/admin-blog/edit",element:s.jsx(Gp,{children:s.jsx(Cpe,{})})}),s.jsx(le,{path:"/admin-blog/edit/:id",element:s.jsx(Gp,{children:s.jsx(jpe,{})})}),s.jsx(le,{path:"/404",element:s.jsx(JT,{})}),s.jsx(le,{path:"*",element:s.jsx(JT,{})})]})}),s.jsx(tee,{}),s.jsx(aee,{}),s.jsx(Mpe,{})]})]})})})}const qpe={tagline:"Soluciones de Testing"},zpe={inicio:"Inicio",servicios:"Servicios",nosotros:"Nosotros",casosDeExito:"Casos de éxito",productos:"Productos",contacto:"Contacto"},Vpe={title:"Contáctanos",subtitle:"Si estás pensando en dar un salto tecnológico, en Haka Lab podemos ayudarte.",nombre:"Nombre",empresa:"Empresa",email:"Correo electrónico",mensaje:"¿En qué podemos ayudarte?",enviar:"Enviar solicitud",nombrePlaceholder:"Ingresa tu nombre",empresaPlaceholder:"Ingresa tu empresa",emailPlaceholder:"Ingresa tu correo",mensajePlaceholder:"Ingresa tu solicitud o comentario",enviando:"Enviando...",exitoEnvio:"✓ ¡Mensaje enviado con éxito! Te contactaremos pronto.",errorEnvio:"✗ Error al enviar. Por favor intenta nuevamente."},Hpe={title:"Trabaja con Nosotros",subtitle:"En Haka Lab estamos en la búsqueda de especialistas en calidad de software y automatización, dejanos tu CV!",nombre:"Nombre",nombrePlaceholder:"Ingresa tu nombre",email:"Correo electrónico",emailPlaceholder:"Ingresa tu correo",pais:"País de residencia",paisPlaceholder:"Ingresa tu país de residencia",telefono:"Teléfono",telefonoPlaceholder:"Ingresa tu teléfono",cv:"Adjuntar CV",cvPlaceholder:"Haz clic para seleccionar tu CV (.pdf, .doc, .docx)",cvFormatos:"Formatos aceptados: PDF, DOC, DOCX. Máximo 2MB.",enviar:"Enviar postulación",enviando:"Enviando...",exitoEnvio:"✓ ¡Postulación enviada con éxito! Te contactaremos pronto.",errorEnvio:"✗ Error al enviar. Por favor intenta nuevamente.",archivoInvalido:"Solo se permiten archivos PDF, DOC o DOCX.",archivoGrande:"El archivo no debe superar los 2MB."},Fpe={title:"También te podría interesar",saberMas:"Saber más",impulsadoPorIA:"Impulsado por IA"},Bpe={title:"Descarga Hakaboost Ahora",subtitle:"Para descargar Hakaboost ingresa tus datos",cargo:"Cargo",sistemaOperativo:"Sistema Operativo",aceptaTerminos:"Acepto los términos y condiciones",descargar:"Descargar",descargando:"Descargando...",debesAceptar:"Debes aceptar los términos y condiciones.",exitoDescarga:"✓ ¡Descarga iniciada! Revisa tu email.",errorDescarga:"✗ Debes aceptar los términos y condiciones.",nombrePlaceholder:"Tu nombre",cargoPlaceholder:"Tu cargo",empresaPlaceholder:"Tu empresa",sistemaOperativoPlaceholder:"Selecciona tu SO",hero:{descripcion:"El copiloto de calida
17948d para Jira y Azure DevOps. Acelera tus flujos de testing y QA hasta un 70% con IA.",gratis:"Totalmente Gratis"},presentacion:{titulo:"Acelera tus flujos de testing y QA hasta en un 70% con IA"},queHace:{titulo:"¿Qué hace?",descripcion1:"HakaBoost es una extensión para Chrome que se integra como un panel lateral en Jira y Azure DevOps, revolucionando la forma en que los equipos de calidad trabajan. Con solo unos clics, mejora descripciones de tareas, genera escenarios de prueba, crea tests automáticamente y analiza la calidad de tus requerimientos.",descripcion2:"Una de sus características más potentes es su capacidad para usar múltiples motores de IA, incluyendo la IA local de Chrome. Obtén sugerencias inteligentes para criterios de aceptación y casos de prueba en formato Gherkin, y crea issues en Jira o work items en Azure DevOps de forma automática.",features:["Mejora descripciones transformándolas en historias de usuario completas con criterios de aceptación y escenarios Gherkin","Crea tests automáticamente: parsea escenarios Gherkin y crea issues en Jira o work items en Azure DevOps vinculados a la tarea principal","Integración con Xray: soporte para crear tests de tipo Cucumber y exportar archivos .feature","Análisis Inteligente (Pro): genera reportes de calidad, sugiere datos de prueba y analiza la cobertura de los tests","Exportación Múltiple (Pro): exporta análisis a PDF y publica como comentarios en Jira/Azure"]},caracteristicas:{titulo:"Características",items:["Complemento Web: se integra de forma nativa en Jira Cloud y Azure DevOps","IA Múltiple: soporte para Chrome Built-in AI (Gemini Nano, 100% local), Google Gemini y OpenAI","Autenticación Segura: sistema de cuentas Free y Pro con inicio de sesión social (Google) y email/contraseña","Modo Oscuro/Claro: interfaz moderna y personalizable","Ofuscación de Datos: protege tu información sensible (URLs, emails, IPs) antes de enviarla a las IAs en la nube","Soporte Bilingüe: disponible en Español e Inglés","Pestañas Pro con Análisis Avanzado: análisis de calidad, sugerencia de datos de prueba y análisis de cobertura"]},beneficios:{titulo:"Beneficios",descripcion:"HakaBoost transforma tu flujo de trabajo de QA con beneficios tangibles desde el primer día.",items:["Aceleración del Ciclo de QA: reduce el tiempo de diseño y creación de pruebas hasta en un 70%","Calidad Mejorada: genera criterios de aceptación claros y una cobertura de pruebas más completa desde el inicio","Flexibilidad de IA: elige entre la privacidad total de la IA local o la potencia de los modelos en la nube","Flujo de Trabajo Integrado: todas las herramientas que necesitas, directamente en Jira y Azure DevOps, sin cambiar de contexto","Consistencia y Estandarización: fomenta el uso de BDD y Gherkin en todo el equipo","Funciones Pro: desbloquea análisis avanzados para llevar tu estrategia de calidad al siguiente nivel","Acceso Pro Gratuito para Clientes: todos los clientes de Haka Lab tienen acceso sin costo a HakaBoost Pro"]},potencia:{titulo:"HakaBoost potencia la calidad de tus tareas",descripcion:"HakaBoost es una extensión para navegadores basados en Chromium (Chrome, Edge) que, gracias a múltiples motores de IA (incluyendo IA local de Chrome), permite mejorar descripciones de tareas en Jira y Azure DevOps, generar escenarios de prueba en Gherkin, crear tests automáticamente y analizar la calidad de tus requerimientos. Todo sin salir de tu herramienta de gestión."}},Upe={title:"Prueba HakaBuddy Ahora",subtitle:"Ingresa tus datos para descargar la versión gratuita",nombre:"Nombre",cargo:"Cargo",sistemaOperativo:"Sistema Operativo",aceptaTerminos:"Acepto los términos y condiciones",descargar:"Descargar Gratis",descargando:"Descargando...",debesAceptar:"Debes aceptar los términos y condiciones.",exitoDescarga:"✓ ¡Descarga iniciada! Revisa tu email.",errorDescarga:"✗ Debes aceptar los términos y condiciones.",nombrePlaceholder:"Tu nombre",cargoPlaceholder:"Tu cargo",empresaPlaceholder:"Tu empresa",sistemaOperativoPlaceholder:"Selecciona tu SO",hero:{descripcion:"La herramienta de QA que combina pruebas manuales y automatizadas en un solo lugar.",gratis:"Prueba gratis — Plan Pro disponible"},presentacion:{titulo:"Reduce el tiempo de testing hasta en un 80% con automatización inteligente."}},$pe={titulo:"¡Registro Exitoso!",mensaje:"La descarga iniciará automáticamente, por favor espera.",submensaje:"La descarga puede demorar hasta un minuto dependiendo de tu conexión a internet. Puede que necesites aceptarla en tu navegador.",boton:"Entendido"},Wpe={cargandoTweets:"Cargando tweets...",verEnX:"Ver en X →",videoNoSoportado:"Tu navegador no soporta el elemento de video.",altEquipoHakalab:"HakaLab - Expertos en QA Salesforce y SAP",altHeroImage:"HakaLab - Expertos en QA Salesforce y SAP"},Gpe={empresa:"© 2026 Haka Lab. Todos los derechos reservados.",enlaces:"Enlaces",siguenos:"Síguenos",privacidad:"Privacidad",terminos:"Términos",contacto:"Contacto",twitter:"Twitter",linkedin:"LinkedIn",github:"GitHub",ereshaka:"¿Eres Haka?",trabajaConNosotros:"Trabaja con Nosotros",codigoConducta:"Código de Conducta",politicaSeguridadSalud:"Política de Seguridad y Salud"},Kpe={tweets:"Cargando tweets..."},Jpe={descargar:"Descargar",ayuda:"Te ayudará en la automatización de pruebas y las hará hasta un 70% más veloces y con menos fallas.",titulo1:"Descubre nuestro complemento desarrollado para generar XPaths",gratis1:"Totalmente Gratis"},Qpe={descargar:"Descargar",hero:{descripcion:"Captura, organiza y exp
17948orta REST sin salir del navegador",gratis:"Totalmente Gratis"},presentacion:{titulo:"Hasta 95% más veloz capturando tráfico de red, Exporta tus flujos a Postman y CSV en un clic."}},Xpe={titulo:"¡Conoce todos nuestros casos de éxito!",placeholder:"Tu email",boton:"Descargar casos de éxito",mensaje:"El archivo se descargará automáticamente"},Ype={titulo:"Preguntas Frecuentes",subtitulo:"Resuelve tus dudas sobre HakaBoost",items:[{question:"¿Qué es HakaBoost y para qué sirve?",answer:"HakaBoost es un copiloto de testing que te ayuda a mejorar las descripciones de tus historias de usuario en Jira y crear casos de prueba automáticamente usando inteligencia artificial."},{question:"¿Necesito pagar por usar HakaBoost?",answer:"No, HakaBoost es completamente gratis. Puedes usarlo sin costo alguno en tu instancia de Jira."},{question:"¿Qué IA debo elegir: OpenAI, Gemini o Chrome?",answer:"Puedes elegir según tus preferencias. OpenAI y Gemini son opciones en la nube, mientras que Chrome te ofrece una IA 100% local basada en Gemini para mayor privacidad."},{question:"¿Funciona sin conexión a internet?",answer:"Sí, si utilizas la opción de IA local (Chrome built-in), HakaBoost funciona completamente sin conexión a internet."},{question:"¿Necesito configurar algo antes de usar HakaBoost?",answer:"Solo necesitas instalar la extensión en tu navegador y seleccionar qué IA deseas utilizar. El resto es automático."},{question:"¿Cómo obtengo mi token de Jira?",answer:"Puedes generar un token de Jira desde tu perfil en Jira Cloud. Ve a Configuración > Seguridad > Crear y gestionar tokens de API."},{question:"¿HakaBoost guarda mis datos en algún servidor?",answer:"No, tus datos permanecen en tu instancia de Jira. Si usas IA local, todo se procesa localmente sin enviar información a servidores externos."},{question:"¿Puedo usar HakaBoost en cualquier proyecto de Jira?",answer:"Sí, HakaBoost funciona con cualquier proyecto de Jira Cloud. Solo necesitas tener acceso a ese proyecto."},{question:"¿Qué hace exactamente el botón 'Mejorar Descripción'?",answer:"El botón 'Mejorar Descripción' utiliza IA para analizar tu historia de usuario actual y sugerir mejoras basadas en buenas prácticas de calida
17948d y testing."}]},Zpe={titulo:"¿Qué hace?",descripcion:"HakaBuddy es una aplicación de escritorio para Windows y macOS que permite gestionar pruebas manuales con evidencia visual, automatizar pruebas con Playwright, ejecutar en CI/CD, y generar reportes profesionales enriquecidos con inteligencia artificial.",features:["Crea pruebas manuales con capturas de pantalla, JSON, video y anotaciones como evidencia.","Graba pruebas automatizadas directamente en el navegador sin escribir código.","Ejecuta scripts paso a paso con un debugger visual que permite editar y reintentar en tiempo real.","Genera reportes PDF, HTML y DOCX con layout personalizable y enriquecimiento con IA.","Sube pruebas a GitHub, GitLab o Bitbucket y ejecútalas automáticamente en CI/CD.","Integra con Jira y Xray para trazabilidad completa de tus pruebas."],caracteristicas:"Características",caracteristicasItems:["Pruebas manuales: capturas de pantalla completa o área, editor de anotaciones, video, adjuntos JSON/PDF.","Pruebas automatizadas con Playwright: grabación, ejecución, debug paso a paso, selectores alternativos.","Pruebas data-driven (Outline): ejecuta el mismo script con múltiples conjuntos de datos.","Suites de regresión: agrupa scripts y ejecútalos en secuencia.","Reportes PDF, HTML y DOCX con maquetador visual drag & drop y enriquecimiento con IA.","Integración con Jira, Xray, GitHub, GitLab y Bitbucket.","Ejecución en CI/CD con generación automática de workflows.","Gestión de sesiones autenticadas con cifrado AES-256.","Optimización de scripts con IA (Gemini): elimina redundancias y mejora legibilidad."],beneficios:"Beneficios",beneficiosDescripcion:"Acelera tu proceso de QA de principio a fin.",beneficiosItems:["Reduce el tiempo de creación de reportes manuales entre un 50% y 70%.","Automatiza pruebas sin escribir código — solo graba y reproduce.","Debugger visual para corregir scripts sin salir de la herramienta.","Un solo push sube tus pruebas a CI/CD con workflow listo para ejecutar.","Reportes profesionales con IA que describen cada paso en lenguaje natural.","Conexión directa con Jira para subir evidencia y crear tests automáticamente.","Funciona offline — toda la información se almacena localmente.","Disponible para Windows y macOS."]},eme={titulo:"Preguntas Frecuentes",subtitulo:"Resuelve tus dudas sobre HakaBuddy",items:[{question:"¿Qué es HakaBuddy y para qué sirve?",answer:"HakaBuddy es una aplicación de escritorio para gestión de pruebas de softw
17948are (QA). Permite ejecutar pruebas manuales con captura de evidencia, automatizar pruebas con Playwright, ejecutar en pipelines CI/CD, y generar reportes profesionales en PDF, HTML y DOCX. Está disponible para Windows y macOS."},{question:"¿Cómo creo una prueba manual?",answer:"Completa el formulario con los datos del test (célula, producto, ambiente, URL, título, objetivo), presiona 'Iniciar Test' y registra cada paso con su título, estado y captura de pantalla. Al finalizar, genera el reporte en el formato que prefieras."},{question:"¿Cómo grabo una prueba automatizada?",answer:"Selecciona 'Automatizada', configura la URL y presiona 'Grabar'. Se abrirá un navegador donde realizas las acciones normalmente. Al cerrar el navegador, el script se genera automáticamente. Luego puedes ejecutarlo, debuggearlo paso a paso, o subirlo a CI/CD."},{question:"¿Qué es el Debug paso a paso?",answer:"Es un modo que abre el navegador y ejecuta tu script acción por acción. En cada paso puedes ver qué elemento se está interactuando (resaltado en amarillo), editar el selector si falla, generar selectores alternativos (XPath, CSS, ID), y reintentar inmediatamente. Los cambios se guardan al script al finalizar."},{question:"¿Qué es HakaPath y cómo se integra?",answer:"HakaPath es una extensión de Chrome que genera localizadores robustos (XPath, CSS, semánticos, relativos). En el modo Debug de HakaBuddy, HakaPath se carga automáticamente en el navegador en versión Pro, listo para usar sin login."},{question:"¿Qué son las pruebas data-driven (Outline)?",answer:"Permiten ejecutar el mismo script con diferentes conjuntos de datos. Por ejemplo, un formulario de registro con 5 usuarios distintos. Defines las variables y los data sets, y HakaBuddy ejecuta una iteración por cada conjunto, reportando resultados individuales."},{question:"¿Puedo personalizar los reportes PDF?",answer:"Sí. Puedes configurar logos (izquierdo y derecho), banner, color de cabecera, portada y contraportada. Además, el maquetador visual te permite posicionar cada elemento del reporte arrastrándolo en un canvas A4."},{question:"¿Cómo funciona la integración con CI/CD?",answer:"Seleccionas las suites que quieres publicar, presionas 'Publicar' y HakaBuddy sube los scripts al repositorio junto con un workflow configurado (GitHub Actions, GitLab CI o Bitbucket Pipelines). Las pruebas se ejecutan automáticamente en cada push."},{question:"¿Qué opciones tengo para exportar resultados?",answer:"Reporte PDF completo, reporte HTML autocontenido, reporte DOCX (Word), JSON compatible con Xray, imágenes en ZIP, y subida directa a Jira como adjunto."},{question:"¿Puedo conectar con Jira Cloud?",answer:"Sí. Configuras URL, token y email de Jira. Esto te permite obtener historias de usuario del tablero, vincular tests a tickets, subir reportes como adjuntos y crear tests automáticamente."},{question:"¿Puedo conectar con Xray?",answer:"Sí. Configuras Client ID y Client Secret de Xray Cloud. Esto permite exportar resultados de ejecución directamente a Xray con mapeo de estados PASS/FAIL por paso."},{question:"¿HakaBuddy almacena los reportes?",answer:"Sí. Tiene un historial con filtros por fecha y producto donde puedes volver a generar cualquier reporte, descargar capturas, ver videos y acceder a todos los resultados anteriores."},{question:"¿Tiene límite de pruebas o reportes?",answer:"No. Tanto en la versión gratuita como en Pro, no hay límite en la cantidad de pruebas o reportes que puedes crear."},{question:"¿Qué pasa con las sesiones autenticadas?",answer:"HakaBuddy puede capturar y reutilizar sesiones de login (cookies y localStorage). Esto permite grabar y ejecutar pruebas en sitios con autenticación (como Salesforce) sin repetir el login o 2FA cada vez. Las sesiones se cifran con AES-256 antes de subir a repositorios."},{question:"¿La versión gratuita tiene fecha de expiración?",answer:"No. La versión gratuita es permanente y permite crear pruebas manuales sin límite. Las funcionalidades de automatización, integraciones y reportes avanzados requieren el plan Pro."}]}
17948,tme={titulo:"¿Qué hace?",descripcion1:"HakaBoost es un complemento de HakaLab especializado en Jira que permite acelerar la calidad de las descripciones de una tarea y crear fácilmente los test.",descripcion2:"HakaBoost lee automáticamente la issue en pantalla, mejora la descripción con IA (Cloud o Local), detecta y crea escenarios en Gherkin y crea Tests en Jira/Xray vinculados a la historia principal. Todo sin salir de Jira.",features:["Permite descargar el historial de Xpaths generados en hasta 5 diferentes tipos de archivos.","Crea hasta 4 localizadores Xpath de forma automática. Utilizando un algoritmo de creación preciso.","Conserva un historial de hasta 30 Xpaths generados para su posterior consulta o reutilización.","Permite convertir los Xpath a código de selenium en hasta 4 lenguajes de programación.","Por cada Xpath generado identifica automáticamente el número de elementos coincidentes en el DOM."],caracteristicas:"Características",caracteristicasItems:["Complemento Web. Se integra fácil y nativamente en Google Chrome y Microsoft Edge.","Descargable directamente desde Chrome Store.","Construcción de Xpath utilizando la metodología Haka Lab para creación de localizadores efectivos.","Idiomas: Español e Inglés.","Revisión automática del DOM de html para la identificación de coincidencias."]},ame={titulo:"¿Qué hace?",features:["Permite exportar las solicitudes capturadas a una colección de Postman.","Permite exportar un resumen de las solicitudes a un archivo CSV.","Conserva un historial de las solicitudes capturadas para su posterior consulta o reutilización.","Permite filtrar las solicitudes por URL."],caracteristicas:"Características",caracteristicasItems:["Captura de tráfico de red hasta un 95% más veloz.","Múltiples opciones de exportación, permite seleccionar entre Postman y CSV.","Organización de solicitudes por pasos con un solo click.","Historial de solicitudes, permite realizar grupos de solicitudes por página y exportar el documento."]},nme={titulo:"Haka RTC",descripcion1:"Diseñada para navegadores basados en Chromium, Haka RTC revoluciona la forma de capturar tráfico REST para tus proyectos de QA. Con pocos clics, registra las solicitudes desde DevTools, las organiza por pasos y permite exportar a Postman o CSV para documentar y reutilizar escenarios con rapidez.",descripcion2:"Además, incorpora filtros dinámicos y lista de exclusión para aislar servicios propios y omitir terceros no autorizados, junto con historial y conteo de repeticiones que aportan precisión y aceleran pruebas (incluidas las de estrés). Gratis y lista para usar en Chrome/Edge."},ime={titulo:"Haka Path es una valiosa extensión",descripcion1:"Diseñado específicamente para navegadores web que revoluciona la forma en que generas XPaths para tus proyectos de automatización de pruebas. Con solo dos clics, esta herramienta te permite crear XPaths de manera eficiente y efectiva, acelerando significativamente tu flujo de trabajo.",descripcion2:"Una de las características destacadas de Haka Path es generar múltiples opciones de XPaths y mostrar cuántos elementos coinciden en tiempo real, brindando mayor precisión, flexibilidad y ahorro de tiempo en la creación de localizadores para tus pruebas automatizadas."},rme={hero:{descripcion:"Extensión para editores basados en VSX (Visual Studio Code, Kiro, Antigravity y más) que revoluciona la automatización de pruebas con Inteligencia Artificial",exclusivo:"Exclusivo de Haka Lab",cta:"Solicitar Acceso",compatibilidad:"Compatible con VS Code · Kiro · Antigravity · Cursor · Windsurf y cualquier editor basado en VSX"},presentacion:{titulo:"Automatización de pruebas con IA, directo en tu editor",subtitulo:"Haka AI Studio se instala como extensión en tu editor favorito basado en VSX. Sin cambiar de herramienta, aplica Inteligencia Artificial de manera estratég
17948ica para reducir los tiempos de creación de pruebas y optimizar los procesos",etapas:{automatizacion:{titulo:"Automatización",descripcion:"Genera scripts robustos de forma automatizada."},seguridad:{titulo:"Seguridad",descripcion:"La información enviada a la IA es mínima y ofuscada para alinearnos con las leyes de seguridad y gobernanza de datos."},ia:{titulo:"IA",descripcion:"La IA se encarga de los procesos más costosos de desarrollar pruebas automatizadas."},talento:{titulo:"Talento Humano",descripcion:"Nuestros Ingenieros supervisan lo creado por la IA, ajustan y aseguran la seguridad y funcionamiento."},impacto:{titulo:"Impacto Real",descripcion:"Entre un 70 y 80% de reducción de tiempos en la creación de tests automatizados."}}},potencia:{titulo:"Características Principales",subtitulo:"Potenciado por Gemini AI para llevar tu automatización al siguiente nivel",grabacion:{titulo:"Grabación Inteligente",descripcion:"Captura tus interacciones en tiempo real con dos modos: Playwright (selectores semánticos modernos) y Selenium (XPath optimizados con validación de unicidad)."},generacion:{titulo:"Generación con IA",descripcion:"Gemini AI analiza tus grabaciones y genera casos de prueba en Gherkin, implementaciones Python completas, Page Objects optimizados y steps personalizados."},busqueda:{titulo:"Búsqueda Vectorial Inteligente",descripcion:"Sistema de embeddings que detecta pasos reutilizables, evita duplicación de código, sugiere mejores prácticas y aprende de tus patrones de testing."},chat:{titulo:"Chat Interactivo con Kai",descripcion:"Asistente de IA integrado que responde preguntas sobre testing, ayuda a refinar casos de prueba, sugiere mejoras y explica el código generado."},analisis:{titulo:"Análisis de Reutilización",descripcion:"Detecta automáticamente secuencias de pasos repetitivas, oportunidades de refactorización, patrones comunes y código duplicado."},velocidad:{titulo:"Velocidad Extrema",descripcion:"Reduce el tiempo de creación de tests en un 70%. Lo que tomaba 2-4 horas ahora toma 15-30 minutos."}},queHace:{titulo:"Beneficios Clave",subtitulo:"Impacto real en tu proceso de automatización",reduccion:"De reducción de tiempo en creación de tests automatizados",beneficios:["Genera código de alta calidad","Reutiliza steps preexistentes","Vectorización progresiva para conocimiento en tiempo real","Utiliza un estándar de alta calidad","Libera al QA Engineer para otras tareas de calidad","Acelera la puesta en marcha del proyecto","Reduce el onboarding técnico",'Gracias a su chat de IA integrado "KAI" soluciona inconvenientes de scripting de forma rápida']},comparativa:{titulo:"Automatización Tradicional vs Haka AI Studio",subtitulo:"Descubre la diferencia que hace la IA en tu flujo de trabajo",aspecto:"Aspecto",sinHaka:"Sin Haka AI Studio",conHaka:"Con Haka AI Studio",tabla:{tiempo:{aspecto:"Tiempo de creación",sin:"1 hora por test",con:"12-18 minutos"},seguridad:{aspecto:"Seguridad",sin:"No hay control sobre lo que se envía a la IA",con:"Ofuscación automática y personalizable de URLs, mails, dominios"},selectores:{aspecto:"Selectores",sin:"Manualmente escritos, propensos a errores",con:"Generados y validados automáticamente"},reutilizacion:{aspecto:"Reutilización de código",sin:"Manual, requiere búsqueda y análisis",con:"Automática con búsqueda vectorial"},formato:{aspecto:"Formato de tests",sin:"Código Python directo",con:"Gherkin legible + implementación"},mantenimiento:{aspecto:"Mantenimiento",sin:"Alto - selectores frágiles",con:"Bajo - selectores optimizados"}},destacado:{titulo:"Lo que antes tomaba 1 hora, ahora toma 12-18 minutos",descripcion:"Entre 70% y 80% de reducción en tiempo de creación de tests"}},casosUso:{titulo:"Mentalidad Lean Aplicada a los Procesos de Calidad",subtitulo:"Haka AI Studio se une a las Power Ups de Haka Lab para optimizar procesos y maximizar el ROI",frontEnd:{titulo:"Testing de Front End",descripcion:"Permite construir pruebas para cualquier tipo de aplicación web, no requiere especificaciones sobre cómo ha sido construida."},backend:{titulo:"Testing Backend",descripcion:"Gracias a que está optimizado para trabajar con los Haka Engines de Automatización, es posible integrar fácilmente pruebas o pasos de backend a las pruebas creadas."},regresion:{titulo:"Pruebas de Regresión",descripcion:"Disponibiliza pruebas de regresión en suites completas de forma acelerada."},ayudante:{titulo:"Ayudante de QA",descripcion:"El chat interno KAI permite, en segundos, a los ingenieros de calida
17948d diagnosticar problemas en sus pruebas, realizar correcciones y mejorar su robustez."},talento:{titulo:"IA al Servicio del Talento",descripcion:"Haka AI Studio usa la IA de forma estratégica, en lugar de pedirle que construya todo, nos servimos de su capa generativa para la orquestación inteligente, lo que mantiene la seguridad al máximo."}},faq:{titulo:"Preguntas Frecuentes",subtitulo:"Resuelve tus dudas sobre Haka AI Studio",items:[{question:"¿Qué es Haka AI Studio?",answer:"Haka AI Studio es una extensión exclusiva de Visual Studio Code que combina la potencia de la inteligencia artificial con las mejores prácticas de automatización de pruebas. Graba tus interacciones en el navegador y genera automáticamente casos de prueba completos en formato Gherkin/BDD con implementaciones listas para ejecutar."},{question:"¿Qué frameworks soporta?",answer:"Haka AI Studio soporta Playwright y Selenium, los dos frameworks más populares de automatización web. Puedes grabar con un framework y generar código para el otro."},{question:"¿Necesito conocimientos de programación de pruebas?",answer:"Si. Aunque Haka AI Studio automatiza la creación de scripts (y reduce el esfuerzo significativamente), el conocimiento de los profesionales de calidad es vital."},{question:"¿Cómo funciona la búsqueda vectorial?",answer:"El sistema de búsqueda vectorial analiza tu framework existente y detecta automáticamente pasos reutilizables. Esto evita duplicación de código y asegura que sigas los patrones establecidos en tu proyecto."},{question:"¿Puedo personalizar el código generado?",answer:"Sí, completamente. Puedes usar el chat de Kai para refinar los tests, agregar validaciones adicionales o ajustar cualquier aspecto del código generado."},{question:"¿Haka AI Studio está disponible públicamente?",answer:"Sí, Haka AI Studio ahora tiene una versión free con menores prestaciones y sin acceso a la vectorización. La versión pro exclusiva de clientes Haka Lab contiene todas las caracteristicas avanzadas."},{question:"¿Qué necesito para usar Haka AI Studio?",answer:"Necesitas Visual Studio Code 1.85.0 o superior, Kiro, Antigravity u otros IDES basados en VSX, Node.js 20.x o superior, una API Key de Gemini, Claude o OpenAI y Python 3.8+ para ejecutar los tests."},{question:"¿Cuánto tiempo ahorro realmente?",answer:"En promedio, nuestras métricas reportan una reducción entre el 70% ~ 80% en el tiempo de creación de tests. Lo que antes tomaba 2-4 horas ahora toma 15-30 minutos."}]}},ome={titulo:"Preguntas Frecuentes",subtitulo:"Resuelve tus dudas sobre HakaPath",items:[{question:"¿Qué debo hacer después de instalar HakaPath?",answer:"Tras instalar el complemento es necesario fijar el complemento al navegador desde el menú de complementos en Google Chrome, luego debes reiniciar el navegador. No se requieren acciones adicionales a estos dos pasos."},{question:"¿Cómo generar un xpath?",answer:'Para generar un xpath simplemente identifica al elemento web del que desees obtener el xpath, haz click derecho sobre él y selecciona "Obtener Hakapath".'},{question:"¿Qué estrategia de localización utiliza HakaPath?",answer:"HakaPath utiliza una estrategia de localización basada en buenas prácticas de xpath. De manera automática HakaPath construye el xpath según los principales componentes disponibles en el elemento web clickeado: id, name, class, etc."},{question:"¿Hasta cuántos xpath se pueden generar?",answer:"HakaPath permite generar xpath de forma ilimitada. Cada vez que generas un xpath se entregan hasta 4 opciones posibles de localización (en la versión registrada del complemento)."},{question:"¿En qué se diferencian los resultados del xpath generado?",answer:"HakaPath genera hasta 4 xpaths de forma automática (en la versión registrada) cuya diferencia está en la especialización de la estrategia de localización, de esta forma se ofrecen diferentes estrategias como: Localización general mediante comodín (*), Localización específica mediante tag del componente web, Localización específica de segundo orden, añadiendo el parent del elemento seleccionado, Localización específica de tercer orden, intentando acceder al elemento web parent desde un child."}
17948,{question:"¿A qué lenguajes se pueden convertir automáticamente los xpaths generados?",answer:"HakaPath permite convertir los xpaths generados en código de Selenium para obtener un webElement, se ofrecen hasta 4 lenguajes disponibles en las opciones de configuración: Python (por defecto), Java, Javascript y C#."},{question:'HakaPath no entrega xpaths, queda en "esperando…" ¿Qué debo hacer?',answer:'Si estás utilizando Google Chrome en vista de dispositivos mobile (escalado de tamaño) verifica que no esté activa la opción "Barra de herramientas de dispositivo", ya que esta opción sobrepone una capa sobre la web para mostrar las herramientas de dispositivos móviles lo cual interfiere con HakaPath.'},{question:"¿En qué situaciones HakaPath puede no entregar un resultado correcto?",answer:"Si bien en la gran mayoría de los casos HakaPath entregará localizadores exactos pueden darse casos donde sea difícil hacerlo, esto puede originarse en la forma en que esté diseñado el sitio web o aplicación, en particular en aquellos donde se sobreponen capas de componentes una sobre la otra."},{question:"¿Cómo se identifican las coincidencias del XPath?",answer:"Hakapath busca automáticamente en el DOM del HTML coincidencias para cada xpath generado tal cual se hace cuando manualmente ingresas un xpath en el inspector del navegador. En ocasiones puede darse el caso que no se encuentren coincidencias, esto implica que el xpath no coincide con ningún elemento del DOM. Lo mostramos igual en el listado de Xpaths generado en caso de ser útil para utilizarlo de base para generar un localizador mucho más especializado."},{question:"¿Para qué sirve la identificación y conteos de elementos coincidentes con el xpath?",answer:"Esto te permitirá conocer con exactitud cuál es el xpath más certero, además conocer el número de coincidencias te permitirá identificar el tipo de estrategia para utilizar con tu xpath al momento de crear un web element particular o una lista de ellos desde selenium."}]},sme={hero:{title:"Somos Especialistas en",title2:"Calidad de Software",subtitle:"Expertos en QA automatizado y testing que transforman la calidad en ventaja competitiva para tu negocio.",cta:"Casos de éxito",scheduleCall:"Hablemos de calidad"},services:[{title:"QA Salesforce y Continuous Testing",description:"Nuestra metodología y experiencia en testing nos permite asegurar la calidad de tus desarrollos en Salesforce en múltiples capas, acelerando el Time To Market y ahorrando costos en aseguramiento continuo de calidad a través de regresiones automatizadas."},{title:"QA SAP y Testing Funcional",description:"Desde la etapa de planificación hasta la implementación final del producto ayudamos a nuestros partners a construir con calidad, disminuyendo errores, mejorando la confianza y resiliencia del producto, ahorrando costos y promoviendo el aseguramiento continuo mediante pruebas automatizadas."},{title:"Continuous Performance",description:"A través de diferentes estrategias escalables preparamos tu ecosistema para enfrentar exitosamente eventos de alta demanda, entregando información valiosa sobre el uso real de infraestructura y capacidades permitimos ahorrar costos en infraestructura cloud garantizando el retorno de inversión."},{title:"Continuous Data Testing",description:"Trabajamos sobre los desafíos específicos de la infraestructura de datos, análisis y evaluación de la integridad, seguridad y eficiencia de los sistemas de datos."}],methodology:{title:"Metodología",subtitle:"Nuestro ADN: Calidad + Innovación + Entrega de Valor.",description:"Una metodología ágil, escalable y centrada en resultados medibles.",bottomText:"Aseguramos la calidad de software mediante diferentes enfoques de testing, para garantizar la estabilidad, confianza y operatividad de tus productos",steps:[{title:"Detección de riesgos",description:"Identificamos puntos críticos"},{title:"Priorización",description:"Enfocamos esfuerzos estratég
17948icamente"},{title:"Ejecución ágil y automatizada",description:"Implementamos con velocidad"},{title:"Feedback continuo y escalabilidad",description:"Mejoramos constantemente"}]},errorCost:{title:{before:'"El costo de un error tras despliegue es ',highlight:"10 veces mayor",after:' al de prevenirlo."'},description:"Ignorar el testing en etapas tempranas impacta directamente en el ROI de tu inversión, degrada la experiencia del usuario y rompe la confianza en tu marca.",risks:["Errores críticos que se descubren en producción.","Pérdida de presupuesto en correcciones reactivas.","Erosión de la reputación y fidelidad del usuario."],impactTitle:"Impacto en el Negocio",impacts:[{label:"Pérdida de Productividad",percentage:"+55%"},{label:"Deuda Técnica Acumulada",percentage:"+75%"}],disclaimer:"*Datos basados en auditorías de salud de ecosistemas Salesforce pre-Haka Lab."},testimonials:{title:"Testimonios",subtitle:"¿Qué dicen nuestros clientes?",items:[{text:`Destaco de forma especial: 
17949
17950El gran compromiso de la empresa en apoyar a la organización en los desafíos que han enfrentado. Un alto nivel técnico y profesional en sus equipos entregando soluciones de muy buena calidad. Una increíble vocación de servicios que se ve reflejada en la calidad de los servicios que prestan. Realmente ponen al cliente al centro.`,author:"Jesus Rodriguez",position:"CTO",company:"Sodimac"},{text:"Gracias a Haka Lab, hemos podido establecer un proceso de certificación robusto y automatizado en nuestra plataforma CRM Salesforce, lo que ha mejorado el tiempo de comercialización de nuestros desarrollos",author:"Francisco Rodriguez",position:"Subgerente CRM",company:"Consorcio"},{text:"Se destaca la adaptación a los equipos y el apoyo constante y su compromiso frente a los desafíos planteados. Por lo tanto puedo recomendar perfectamente cualquier servicio que Haka Lab pueda prestar en el ámbito de automatización de pruebas.",author:"Humberto Proschle",position:"Gerente Tecnología",company:"Casa Ideas"}]},clients:{title:"Nuestros clientes",description:"Trabajamos con empresas líderes en sus industrias, ayudándolas a alcanzar sus objetivos tecnológicos con soluciones innovadoras y de calidad."},partners:{title:"Nuestros partners"}},lme={hero:{title:"¿Quiénes Somos?",subtitle:"En Haka Lab, impulsamos la calidad tecnológica. Con más de 7 años de experiencia, colaboramos con empresas de diversos sectores — retail, banca, salud y servicios — para garantizar soluciones tecnológicas que se alinean con sus objetivos y cultura organizacional.",cta:"Contáctanos"},identidad:{intro:"Creemos que la calidad nace del compromiso humano, no solo del código. Por eso nuestra identidad también se refleja en Koru y Kai, dos personajes que simbolizan lo que nos impulsa:"},koru:{descripcion:"Koru representa la innovación y la automatización, siempre buscando nuevas formas de crear valor."},kai:{descripcion:"Kai encarna la colaboración y la confianza, la fuerza que asegura que cada entrega esté acompañada de excelencia."},haka:{conclusion:"Juntos, hacen el haka: un baile que transmite unidad, energía y propósito compartido. Así es como trabajamos cada día en Haka Lab: con pasión, en comunidad y siempre enfocados en generar Entrega Continua de Valor."},caracteristicas:{esencia:{title:"Nuestra Esencia",description:"Nos dedicamos a mejorar continuamente nuestros procesos y servicios, asegurando que cada proyecto supere las expectativas en calidad y eficiencia."},vision:{title:"Visión",description:"Aspiramos a impactar positivamente en nuestros partners y clientes, fomentando una cultura de innovación y mejora continua."},mision:{title:"Misión",description:"Nos enfocamos en ofrecer soluciones tecnológicas que aporten valor sostenible, respaldadas por un servicio de excelencia y una cultura organizacional sólida."},compromiso:{title:"Compromiso",description:"Nos comprometemos a impulsar el crecimiento y éxito de nuestros clientes mediante soluciones tecnológicas innovadoras y de alta calidad."}},redes:{titulo:"Síguenos en Nuestras Redes Sociales",subtitulo:"Mantente actualizado con nuestras últimas noticias y actualizaciones",verMasNoticias:"Ver más noticias"}},cme={titulo:"Nuestros Servicios",descripcion:"Ofrecemos soluciones integrales de testing y calidad diseña
17950das para garantizar la excelencia de tus productos tecnológicos. Desde testing funcional hasta análisis de datos, cubrimos todas las etapas de tu ciclo de desarrollo.",contactanos:"Contáctanos",servicesDescription:"Nuestros servicios están diseñados para garantizar la calidad, automatización y escalabilidad de tus soluciones tecnológicas.",agileCycle:{introText:"Integramos la visión de calidad en todas las etapas del ciclo de vida de desarrollo del software eficientando el proceso y reduciendo costos.",centerText:{line1:"Ciclo de Vida de",line2:"Desarrollo de Software"},devStages:["Planificación","Diseño","Desarrollo","Testing","Deploy","Review","Launch"],qaStages:[{label:"Análisis",fullName:"Análisis, precondiciones y riesgos",description:"Análisis detallado de requerimientos, identificación de riesgos y establecimiento de precondiciones para garantizar la calidad desde el inicio."},{label:"Diseño pruebas",fullName:"Diseño de pruebas",description:"Diseño detallado del plan de pruebas con estrategias, casos de prueba y criterios de aceptación."},{label:"Construcción",fullName:"Construcción de pruebas",description:"Construcción y desarrollo de pruebas automatizadas y manuales según el plan definido."},{label:"Ejecución",fullName:"Ejecución de pruebas",description:"Ejecución de pruebas en diferentes ambientes y escenarios para validar la calidad del software."},{label:"Verificación regresiva (CI/CD)",fullName:"Testing en CI/CD",description:"Integración de pruebas en el pipeline de CI/CD para validación continua y automatizada."},{label:"Evaluación",fullName:"Evaluación de resultados",description:"Análisis de resultados, generación de reportes y toma de decisiones basada en métricas de calida
17950d."},{label:"Medición",fullName:"Medición de indicadores en producción",description:"Medición y análisis de indicadores clave de productividad y eficiencia del proceso de testing para mejora continua."}]},performance:{title:"Continuous Performance",subtitle:"Nuestro marco de trabajo amplía el enfoque tradicional de pruebas de performance integrando Observabilidad y monitoreo continuo para garantizar una preparación de infraestructura y ecosistemas frente a cualquier desafío.",cta:"Solicitar una demo gratis",features:["Estrategias de pruebas que se adaptan a los requerimientos de tu negocio.","Mejora continua mediante la ejecución constante de pruebas.","Foco en la experiencia del cliente y objetivos de negocio.","Reportería personalizada y custom.","Proceso integrado activamente."]},continuos:{title:"Continuous Testing",subtitle:"Funcional - Salesforce - SAP"},services:[{title:"Testing Salesforce",description:"Aseguramos la calidad del producto gracias a nuestro framework de pruebas especialmente desarrollado y robustecido para Salesforce, optimizando los tiempos de certificación mediante la creación de estrategias de ejecución en paralelo, escenarios de múltiples combinatorias, identificación de objetos personalizada, regresión e integración continua para minimizar el impacto en la operación del negocio.",benefit:"Acelera el time-to-market de tus proyectos Salesforce en un 40% con testing especializado.",features:["Disminución hasta en un 70% el tiempo de certificación.","Propio Framework de Automatización.","Reportería y evidencia custom.","Ejecuciones multi browser."]},{title:"Testing Funcional",description:"Implementamos los más altos estándares de calidad en el ciclo completo de desarrollo de software. Desde la etapa de planificación hasta la implementación final del producto, brindando apoyo técnico y metodológico a los equipos en el cumplimiento de sus desafíos, teniendo como eje central la automatización de pruebas bajo una mirada integrativa de todo el proceso.",benefit:"Reduce costos operativos hasta un 60% mediante automatización inteligente y detección temprana de errores.",features:["Certificación en paralelo para reducir hasta un 80% el delivery.","Automatización altamente reutilizable.","Estrategias de calida
17950d continua."]},{title:"Testing SAP",description:"Integramos sistemas legados como BD, OMS, APIs, IMS y distintas plataformas de ecommerce a través de nuestro framework de automatización de pruebas. Hemos incorporado además tecnologías como visión por computadora, control de periféricos, y todo lo necesario para garantizar las validaciones eficaces que reducen riesgos, costos y que maximizan el beneficio.",benefit:"Minimiza riesgos en implementaciones SAP críticas, protegiendo inversiones millonarias.",features:["Automatización por fases y entrega de valor al corto plazo.","Disminución en tiempo de certificación.","Reportería personalizada."]}],data:{title:"Data Testing",subtitle:"Trabajamos sobre los desafíos específicos de la infraestructura de datos, profundizamos en el análisis y evaluación de la integridad, seguridad y eficiencia de sistemas de datos. Además, identificamos fallos tempranamente y áreas de mejora, asegurando la robustez y fiabilidad de bases de datos y almacenamiento de información, optimizando la gestión de información y garantizando su seguridad.",cta:"Solicitar una demo gratis",features:["Reducción de hasta un 90% de tiempo relacionado a los procesos de data testing.","Testing, análisis y evaluación.","Ejecuciones regresivas constantes.","Verificación de consistencia de datos constante."]}},dme={titulo2:"Conoce nuestras herramientas de testing",hero:{title:"Soluciones estratégicas para tu",title2:" calidad de software",subtitle:"Simplifica tus procesos de calida
17950d con nuestras herramientas impulsadas por Inteligencia Artificial estratégica.",cta:"Solicitar una demo gratis"},titulo:"Impulsa tu trabajo en QA y desarrollo con nuestras herramientas Haka",descripcion:"Simplifica tus tareas diarias, reduce tiempos y automatiza con inteligencia.",hakaboost:{descripcion:"Acelera la creación de test en Jira hasta en un 97% con IA"},hakabuddy:{descripcion:"Crea reportes de pruebas manuales en minutos, no en horas"},hakapath:{descripcion:"Genera XPaths automáticamente con precisión y velocidad"},hakatools:{descripcion:"Suite completa de herramientas para automatización de pruebas"},hakartc:{descripcion:"Captura y exporta tráfico REST para tus pruebas de API"},hakainsight:{descripcion:"Analiza tu código y crea explicaciones simples con diagramas interactivos automáticamente"},hakaengine:{descripcion:"Framework BDD de automatización de pruebas con Playwright, self-healing con IA y 1800+ steps listos para usar"},hakaaistudio:{descripcion:"Acelera la automatización con nuestro Engine impulsado por IA"},hakaistudio:{descripcion:"Extensión VS Code con IA que transforma grabaciones en tests automatizados completos"}},ume={titulo:"Ciclo de Testing",descripcion:"Nuestros productos impactan directamente en las diferentes etapas del ciclo de pruebas, permitiéndonos acelerar los procesos y optimizar el aseguramiento de la calidad.",productoLabel:"Product:",entendido:"Excelente",pasos:[`Planning
17951y análisis`,`Diseño de
17952pruebas`,`Ejecución de
17953pruebas`,`Reporte de
17954hallazgos`,`Análisis y
17955visibilidad`,`Mejora 
17956continua`],descriptions:["Definimos objetivos claros de calidad, identificamos riesgos y establecemos criterios de aceptación. Analizamos requisitos funcionales y no funcionales para garantizar que cada aspecto del software cumpla con los estándares de calidad desde el inicio.","Creamos escenarios de prueba exhaustivos que cubren flujos principales, casos límite y situaciones excepcionales. Diseñamos estrategias de testing que aseguran la cobertura completa del código y la validación de todos los requisitos de negocio.","Implementamos scripts de automatización robustos y mantenibles. Configuramos entornos de prueba que replican producción y establecemos pipelines de CI/CD para integrar el testing en cada etapa del desarrollo, detectando defectos tempranamente.","Ejecutamos pruebas funcionales, de regresión, performance y seguridad de forma automatizada. Validamos que cada funcionalidad opere correctamente bajo diferentes condiciones y cargas, asegurando la estabilidad y confiabilidad del sistema.","Analizamos métricas de calida
17956d, identificamos patrones de defectos y generamos reportes detallados. Proporcionamos visibilidad completa del estado de calidad del software, facilitando la toma de decisiones informadas sobre el release.","Refinamos procesos de testing basándonos en lecciones aprendidas. Optimizamos la cobertura de pruebas, reducimos tiempos de ejecución y mejoramos la detección temprana de defectos. Implementamos feedback loops para elevar continuamente los estándares de calidad."],productDescriptions:{hakaboost:"Planning y análisis, Diseño de pruebas",hakabuddy:"Diseño de pruebas, Ejecución, Reportes, Análisis y visibilidad",hakapath:"Ejecución de pruebas",hakartc:"Diseño de pruebas",hakainsight:"Analiza y comprende tu código fuente fácilmente",hakaengine:"Automatización de pruebas funcionales sin código",hakaaistudio:"Automatización de pruebas con Inteligencia Artificial"}},pme={hero:{title:"¿Tus sistemas fallan justo cuando más los necesitas?",subtitle:"En Haka Lab solucionamos esos dolores con tecnología, velocidad y calidad real. Conoce cómo empresas como la tuya convirtieron sus desafíos en historias de éxito - con resultados en horas ahorradas, bugs eliminados y clientes felices.",btn:"Solicita una evaluación gratuita"},desafioLabel:"Desafío:",solucionLabel:"Solución:",testimonioLabel:"Testimonio",qaLabel:"QA",cta:{titulo:"¿Quieres lograr estos resultados?",descripcion:"Agenda tu diagnóstico gratuito y descubre cómo adaptamos nuestros frameworks a tu entorno.",boton:"Solicita una evaluación gratuita"},cases:{walmart:{company:"Walmart",title:"100% Uptime durante Cyber Day",problem:"La operación omnicanal requería garantizar estabilidad en todos los sistemas durante eventos críticos de alta tráfico (como lanzamientos y campañas promocionales), evitando errores y caídas en producción.",solution:"Implementamos una estrategia de automatización E2E con foco en performance, integrando los diferentes servicios de los flujos ecommerce mediante diferentes estrategias de calida
17956d que permitieron garantizar el éxito de las estrategias comerciales en eventos de alta demanda e impacto para la compañía.",results:[{metric:"100%",description:"Aseguramos un 100% de cumplimiento del time to market, sin retrasos en releases clave."},{metric:"65%",description:"Disminuimos en un 65% las incidencias críticas relacionadas al rendimiento del sistema."},{metric:"99.98%",description:"Habilitamos alertas preventivas en tiempo real, elevando la disponibilidad del ecosistema digital a un 99.98%"}],qa:"Transformamos el QA en un eje estratégico para anticiparnos a los riesgos y mejorar la experiencia del cliente."},melt:{company:"Melt Pizzas",title:"Monitoreo Sintético",problem:"Melt Pizzas buscaba asegurar que su infraestructura soportara el crecimiento acelerado de sus canales digitales, especialmente en contextos de alta demanda.",solution:"Realizamos monitoreo sintético y pruebas de performance para validar si la infraestructura actual soportaba el crecimiento esperado. Se emitieron recomendaciones estratégicas a partir del análisis de carga y experiencia de usuario.",results:[{description:"Establecimos una base de monitoreo permanente que permite escalar sin sacrificar calidad ni disponibilidad."},{description:"Reportería personalizada para presentar los datos obtenidos de las pruebas, con gráficos para representar kpis relevantes a gerencia."},{description:"Validación proactiva de la capacidad de respuesta de la infraestructura."}]},consorcio:{company:"Consorcio",title:"CRM Salesforce",problem:"Proceso manual de certificación lento y sin trazabilidad.",solution:"Automatización al 100% de pruebas funcionales de Salesforce con ejecución desde CI/CD.",results:[{description:"Reducimos un 70% los tiempos de paso a producción."},{description:"Mejoramos la visibilidad del proceso y eliminamos deuda técnica en semanas."}],testimonial:{text:"Gracias a Haka Lab, hemos podido establecer un proceso de certificación robusto y automatizado en nuestra plataforma CRM Salesforce, lo que ha mejorado el Time to Market de nuestros desarrollos",author:"Francisco Rodríguez",position:"Subgerente CRM Salesforce",company:"Implementation Leader"}},casaideas:{company:"Casa Ideas",title:"Automatización Flujo de Ecommerce e integraciones SAP y Magento",problem:"Flujo E2E complejo de certificar el cual tenía múltiples errores en producción.",solution:"Automatizamos SAP Logon v760 en conjunto del E2E de la compra en el ecommerce para luego validar que los datos que se generaban cuadraran y llegaran correctamente a SAP, Magento, Omnix y Dbnet.",results:[{description:"Automatización de pruebas integrales con SAP y legados."},{description:"Ejecución de pruebas en máquinas virtuales automatizadas."}],testimonial:{text:"Para el lanzamiento de nuestra nueva plataforma e-commerce decidimos contratar los servicios de Haka Lab ya que demostraron un alto grado de conocimiento técnico en el proceso de automatización de pruebas. El proyecto logró sus objetivos y se destaca de forma especial: - Innovación y manejo de la tecnología - Uso de Metodologías - Soporte y acompañamiento en el proceso de diseño y elaboración de pruebas - Adaptación constante al cambio - Apoyo técnico y compromiso. En forma adicional, se destaca la adaptación a los equipos y el apoyo constante y su compromiso frente a los desafíos planteados. Por lo tanto puede recomendar perfectamente cualquier servicio que Haka Lab pueda prestar en el ámbito de la automatización de pruebas.",author:"Equipo Casa Ideas",position:""}},sodimac:{company:"Sodimac Homecenter",title:"Backoffice cierre y cuadratura",problem:"Dificultad en el proceso y altos tiempos para el cierre y cuadratura de los POS de ventas.",solution:"Automatizamos un proceso crítico que antes tomaba 8 horas y lo redujimos a solo 70 minutos, superando barreras tecnológicas complejas con componentes legados (UXPOS, SAP, Control-M) y visión computarizada.",results:[{description:"Reducción de tiempo del proceso manual del Back office de Cierre y Cuadratura de 8 horas a 70 minutos automatizado."},{description:"Automatización de componentes UXPOS, SAP y Control-M"}],testimonial:{text:"Destacó de forma especial el gran compromiso de la empresa en apoyar a la organización en los desafíos que han afrontado. Un alto 
17956nivel técnico y profesional en sus equipos entregando soluciones de muy buena calidad. Una increíble vocación de servicios que se ve reflejada en la calidad de los servicios que prestan. Realmente ponen al cliente al centro.",author:"Jesús Rodríguez",position:"CTO Sodimac",company:""}},scotiabank:{company:"Scotiabank",title:"Digital Factory",problem:"",solution:"Fuimos pioneros en implementar una estrategia de Continuous Testing y Delivery en la Fábrica Digital de una de las principales entidades bancarias de Chile. Incorporamos prácticas como ATDD y BDD para alinear al negocio con el desarrollo y asegurar la calidad desde el primer sprint. Nos hicimos cargo de la certificación completa de la fábrica, integrando calidad en todas las capas.",results:[{description:"Certificación total de los productos digitales en paralelo al desarrollo."},{description:"Implementación exitosa de ATDD y BDD como base de madurez QA."},{description:"Reducción en los ciclos de entrega gracias al Continuous Delivery."},{description:"Establecimos un modelo de calida
17956d continuo que hoy sigue vigente."}]},parquearauco:{company:"Parque Arauco",title:"Migración SAP Hana a AWS",problem:"Parque Arauco enfrentaba el desafío de asegurar la calidad en una migración compleja hacia AWS, involucrando múltiples capas de datos, servicios cloud y componentes críticos del negocio.",solution:"Desplegamos nuestro framework de automatización especializado para certificación de datos, aplicando tecnologías como Spark, Glue, Hyde, C3, Lambda y Python. Implementamos pruebas regresivas con enfoque en trazabilidad e integridad end-to-end, integrándolos activamente a los equipos del cliente con entregas iterativas y feedback continuo.",results:[{description:"Disminución de tiempos de certificación gracias a las regresivas constantes identificando errores de manera temprana."},{description:"Propio Framework de Automatización para certificaciones de datos con tecnologías como Spark, Hyde, Glue, C3, Lambda, Python."}]}}},mme={titulo:"Blog",titleFront:"Blog de HakaLab",descripcion:"Artículos sobre testing, calida
17956d de software y automatización de pruebas",leerMas:"Leer más",verEnBlog:"Ver en blog",articulosRelacionados:"Artículos relacionados",volverAlBlog:"Volver al blog",buscar:"Buscar artículos...",filtrarPorEtiqueta:"Filtrar por etiqueta",limpiarFiltros:"Limpiar filtros",noHayArticulos:"No hay artículos publicados aún",noEncontrados:"No se encontraron artículos con los filtros seleccionados",mostrando:"Mostrando",de:"de",articulos:"artículos",vistas:"vistas",autor:"Autor",creado:"Creado",etiquetas:"Etiquetas",por:"Por"},hme={title:"Agendar Cita",name:"Nombre",email:"Email",company:"Empresa",date:"Fecha",time:"Hora",message:"Mensaje (opcional)",schedule:"Agendar",scheduling:"Agendando...",cancel:"Cancelar",success:"¡Cita agendada exitosamente!",successMessage:"Te enviaremos un email de confirmación",errorRequired:"Por favor completa todos los campos requeridos",noCalendarUrl:"El calendario no está configurado",close:"Cerrar",calendlyMessage:"Haz clic en el botón para abrir el calendario y agendar tu cita",openCalendar:"Abrir Calendario"},fme={title:"El Costo de los Bugs en el Ciclo de Desarrollo",subtitle:"Costo de encontrar un bug en el ciclo de desarrollo de software",message:"Al integrarnos a tu equipo, aceleramos la detección de bugs a etapas tempranas.",conclusion:"Eso Ahorra Dinero",ciclos:"Ciclo Desarrollo",stages:[{label:"Planificación"},{label:"Diseño"},{label:"Coding"},{label:"Testing"},{label:"Producción"}]},gme={titulo:"Partner Oficial de",titulo2:"XRAY",titulo3:"by Sembi",subtitulo:"Somos implementadores oficiales de XRAY en Jira Cloud y especialistas en su uso profesional para el acompañamiento de la calidad de software en nuestros clientes.",conversemos:"Hablemos de calidad"},yme={partners:"Partners Estratégicos",lideres:"Líderes en Salesforce Quality"},xme={title:"Impacto en ROI",title2:"Eficiencia"},vme={welcome:{title:"Autoevaluación de calidad Haka Lab",subtitle:"Responde las siguientes preguntas para medir el nivel de calidad que aplicas hoy en día sobre tus desarrollos de software",email:"Correo electrónico",emailPlaceholder:"[email protected]",company:"Empresa",companyPlaceholder:"Nombre de tu empresa",industry:"Industria",industryPlaceholder:"Selecciona tu industria",developmentType:"Tipo de desarrollo",developmentTypePlaceholder:"Selecciona el tipo de desarrollo",startButton:"Iniciar Evaluación",requiredField:"Este campo es requerido",invalidEmail:"El email no es válido"},quiz:{progress:"Progreso",question:"Pregunta",of:"de",continueButton:"Continuar",previousButton:"Anterior",seeResultsButton:"Conocer Resultados",allQuestionsRequired:"Por favor responde todas las preguntas antes de continuar"},rating:{never:"Nunca",rarely:"Raramente",sometimes:"A veces",frequently:"Frecuentemente",always:"Siempre"},results:{title:"Tus Resultados",yourScore:"Tu Puntaje",outOf:"de",points:"puntos",maturityLevel:"Nivel de Madurez",analysis:"Análisis Personalizado",redFlags:"Banderas Rojas Identificadas",noRedFlags:"¡Excelente! No se identificaron banderas rojas críticas.",recommendations:"¿Cómo podemos ayudarte?",recommendationsSubtitle:"Servicios recomendados según tu evaluación",contactButton:"Contactar con HakaLab",learnMore:"Conocer más",highScoreMessage:"¡Felicitaciones! Tu equipo tiene una cultura de calidad establecida. Podemos ayudarte a optimizar aún más tus procesos.",savingResults:"Guardando resultados...",resultsSaved:"Resultados guardados exitosamente"},maturityLevels:{reactive:{name:"Calidad Reactiva",label:"Nivel Crítico",diagnosis:"El equipo apaga incendios. QA es un cuello de botella al final del proceso y hay poca visibilidad de lo que pasa en producción."},transition:{name:"Calidad en Transición",label:"Nivel Medio",diagnosis:"Existen esfuerzos (quizás algunas pruebas unitarias o ambientes de QA), pero falta consistencia y métricas para mejorar."},advanced:{name:"Calidad Avanzada",label:"Nivel Pro",diagnosis:"El equipo tiene cultura de calidad. QA está integrado y hay métricas."}},redFlags:{silos:{title:"Alerta de Silos",message:"Tu equipo de QA está aislado; esto genera retrabajo y costos altos de corrección."},production_risk:{title:"Alerta de Riesgo en Producción",message:"Estás volando a ciegas; no estás aprendiendo de tus errores en producción."},technical_debt:{title:"Alerta de Deuda Técnica",message:"Tu regresión manual se volverá insostenible pronto. La automatización es tu siguiente paso."}},services:{qa_assessment:{name:"QA Assessment & Strategy",description:"Definimos procesos desde cero, establecemos DOR/DOD y movemos QA hacia la izquierda (Shift Left)."},test_automation:{name:"Test Automation",description:"Automatizamos pruebas humo y regresiones para liberar tiempo y mejorar la confianza."},continuous_testing:{name:"Continuous Testing",description:"Integramos pruebas en tu pipeline CI/CD para detectar problemas temprano."},performance_testing:{name:"Performance Testing",description:"Optimizamos la carga del sistema y aseguramos que tu aplicación escale."},data_testing:{name:"Data Testing",description:"Validamos la calidad y precisión de tus datos en pipelines y reportes."},resource_optimization:{name:"Optimización de Recursos",description:"Optimizamos tus procesos de QA existentes para maximizar eficiencia y reducir costos."}},errors:{loadingQuestions:"Error al cargar las preguntas",savingResults:"Error al guardar los resultados",generic:"Ocurrió un error. Por favor intenta nuevamente."}},bme={hero:{badge:"Motor de Automatización",title:"Haka Automation Engine",titleHighlight:"Inteligencia aplicada a la calidad",subtitle:"Nuestro motor de automatización especializado integra las mejores tecnologías de testing para construir pruebas automatizadas hasta 40% más rápido, reduciendo costos y garantizando calidad continua.",ctaContact:"Solicitar Demo"},diagram:{title:"Arquitectura del Motor",subtitle:"Basados en nuestra experiencia creamos una solución completa en capas que optimiza cada etapa del proceso de testing",layer1:{title:"Base Tecnológica",description:"Selenium, Playwright y Behave (Gherkin) para pruebas modernas y estables con ejecución paralela"}
17956,layer2:{title:"Impulsado por Experiencia e IA",description:"Permite construir pruebas para front-end, API REST, BBDD y Gen AI a gran velocidad"},layer3:{title:"Integraciones Nativas",description:"Conexión directa con Jira, Xray, Zephyr y Grafana para resultados en tiempo real"},layer4:{title:"Reportes Automáticos",description:"Reportes HTML/Video construidos de forma automática junto con las pruebas para facilitar el seguimiento, revisión de indicadores y trazabilidad completa"},layer5:{title:"CI/CD Ready",description:"Preparado para pipelines de integración y despliegue continuo"},note:"Nuestros productos impulsan al motor para eficientar el proceso, máximar la calidad y reducir costos de construcción y ejecución de pruebas"},aiTesting:{badge:"Innovación en Testing",title:"Motor Impulsado por IA",subtitle:"Nuestro motor está impulsado y preparado para testear aplicaciones que usan IA Generativa, mediante análisis semánticos avanzados y estrategias RAG (Retrieval-Augmented Generation).",innovationBadge:"Innovación",features:{genAI:{title:"Testing de IA Generativa",description:"Validación especializada para aplicaciones que utilizan GEN AI para generar interacciones o respuestas a sus usuarios"},semantic:{title:"Análisis Semántico",description:"Evaluación inteligente del significado y contexto de las respuestas generadas por IA ahorrando costos asociados a validadores externos"},rag:{title:"Estrategias RAG",description:"Testing a sistemas que combinan recuperación de información con generación de contenido con diferentes estrategias de validación y análisis cuantitativo de resultados"},validation:{title:"Validación de Calidad",description:"Verificación de precisión, coherencia y relevancia en respuestas de IA en alineación a las espectativas técnologicas y de negocio del cliente"}},stat:{label:"Preparados para el futuro",value:"Gen AI Testing",description:"Testing especializado para la nueva era de aplicaciones inteligentes"},diagram:{input:{title:"Input de Usuario",description:"Consulta o prompt"},genAI:{title:"IA Generativa",description:"Procesamiento + RAG"},output:{title:"Respuesta Generada",description:"Contenido de IA"},testing:{title:"Haka Automation Engine",description:"Validación Semántica"}}},comparison:{title:"Comparativa de Eficiencia",subtitle:"Descubre cómo Haka Automation Engine acelera tu proceso de testing, optimiza recursos, máximiza la eficiencia y ahorra costos.",traditional:{badge:"Método Tradicional",title:"Sin Motor Especializado",description:"Construcción manual de cada componente de prueba, curva de implementación alta, sin estandar técnologico claro ni métodologia garantizada.",point1:"Desarrollo desde cero",point2:"Mayor tiempo de implementación",point3:"Costos elevados de recursos"},hakalab:{badge:"Con Hakalab",title:"Haka Automation Engine",description:"Componentes y productos Haka Lab, optimizados e impulsados para la construcción, ejecución y documentación.",point1:"Automatización lista para implementar",point2:"Productos propios que apoyan el proceso de calidad",point3:"Reducción de costos significativa"},savings:"Menos tiempo de desarrollo"},benefits:{title:"Beneficios Clave",subtitle:"Por qué Haka Automation Engine marca la diferencia",speed:{title:"Velocidad Optimizada",description:"Reduce hasta 40% el tiempo de construcción de pruebas con componentes preconstruidos"},coverage:{title:"Cobertura Maximizada",description:"Pruebas en todas las capas: front-end, API REST, bases de datos y Gen AI"},continuous:{title:"Calidad Continua",description:"Integración con CI/CD para regresiones automáticas y feedback inmediato"},reports:{title:"Reportes Robustos",description:"Documentación automática con evidencias, métricas y trazabilidad completa"},integrations:{title:"Integraciones Nativas",description:"Conexión directa con Jira, Xray, Zephyr y Grafana sin configuración compleja"},cost:{title:"Ahorro de Costos",description:"Optimización de recursos y reducción de tiempo se traduce en ahorro real"}},technologies:{title:"Tecnologías Integradas",subtitle:"Un ecosistema completo de herramientas líderes en la industria",products:{title:"Productos Hakalab Incluidos",description:"Todos nuestros productos están diseña
17956dos para trabajar con el motor y acelerar tu testing"}},cta:{badge:"Comienza Ahora",demoTitle:"Demo de Ejecución Automatizada",demoSubtitle:"Observa cómo Haka Automation Engine ejecuta pruebas automatizadas fácilmente",videoLoading:"Cargando video...",videoLoadingSubtitle:"Por favor espera unos segundos",title:"¿Listo para acelerar tu testing?",description:"Agenda una demo personalizada y descubre cómo Haka Automation Engine puede transformar tu proceso de QA",scheduleDemo:"Agendar Demo",contact:"Contactar",stat1:"Menos tiempo",stat2:"Pasos preconstruidos",stat3:"Automatizable"}},wme={hero:{badge:"Framework Integral",title:"Framework HakaLab",titleHighlight:"Personas + Metodología + Tecnologías",subtitle:"Trabajando en conjunto para asegurar la calidad de tus productos",ctaContact:"Solicitar Demo"},pillars:{title:"Framework HakaLab",subtitle:"Nuestra solución se centra en tres pilares fundamentales que trabajan en sinergia, aprendizaje y mejora continua",people:{title:"Personas",description:"Nuestros profesionales llevan la cultura de calidad Haka a nuestroos clientes, con expertis métodologica y técnica en base a una pensamiento Lean.."},methodology:{title:"Framework Metodológico",description:"Implementamos prácticas de calida
17956d en todo el ciclo de desarrollo de software mediante las mejores prácticas de la industria."},technology:{title:"Framework Tecnológico",description:"Utilizamos una solución tecnológica propia construida sobre las herramientas de testing y automatización más robustas en la actualidad, impulsado por IA y nuestra experiencia."}},methodology:{title:"Framework Metodológico",subtitle:"Implementamos prácticas de calidad en todo el ciclo de desarrollo mediante metodologías ágiles y mejora continua",quote:"Integramos el framework metodológico Haka Lab según las necesidades y capacidades del cliente en un modelo evolutivo de mejora continua, valor y retorno de inversión constante.",author:"Matías Carrasco",authorRole:"CEO Haka Lab"},technology:{subtitle:"Tecnologías robustas potenciadas por la experiencia de nuestra experiencia",techTitle:"Stack Tecnológico",aiPowered:"Impulsado por IA",differentiator:{title:"¿Qué nos diferencia?",description:"Sustentados en el framework metodologico nuestros especialistas dominan las técnologiaspara acelerar procesos, reducir costos y maximizar la calidad. Potenciamos cada proyecto con nuestros Power Ups Haka."},powerups:{title:"Power-Ups Haka",description:"Nuestros productos propios que multiplican la eficiencia del framework tecnológico:"},cta:"Conocer Haka Automation Engine",tools:{selenium:"Automatización de navegadores web",playwright:"Testing moderno de aplicaciones web",cucumber:"Framework BDD con Gherkin",python:"Lenguaje para scripts de testing",jenkins:"Automatización CI/CD",docker:"Contenedores para ambientes consistentes",github:"Control de versiones y colaboración",jira:"Gestión de proyectos y seguimiento",xray:"Gestión de casos de prueba en Jira",grafana:"Visualización de métricas y dashboards",html:"Reportes HTML automatizados",apirest:"Testing de APIs REST",bbdd:"Testing de bases de datos",front:"Testing de interfaces frontend",chrome:"Navegador para testing automatizado",appium:"Automatización de apps móviles"}}},kme={titulo:"Términos y Condiciones de Uso",ultimaActualizacion:"Última actualización",definiciones:{titulo:"Definiciones"},aceptacion:{titulo:"Aceptación de los Términos"},licencia:{titulo:"Licencia de Uso"},restricciones:{titulo:"Restricciones de Uso"},actualizaciones:{titulo:"Actualizaciones y Cambios en los Servicios"},privacidad:{titulo:"Privacidad y Protección de Datos"},limitacion:{titulo:"Limitación de Responsabilidad"},terminacion:{titulo:"Terminación"},legislacion:{titulo:"Legislación Aplicable"},modificaciones:{titulo:"Modificaciones a los Términos"},politicaPrivacidad:{titulo:"Política de Privacidad de Haka Lab",informacion:{titulo:"Información que Recopilamos"},finalidades:{titulo:"Finalidades del Tratamiento"},baseLegal:{titulo:"Base Legal y Consentimiento"},transferencia:{titulo:"Transferencia y Compartición de Datos"},seguridad:{titulo:"Seguridad de la Información"},derechos:{titulo:"Sus Derechos"},cambios:{titulo:"Cambios a esta Política"},contacto:{titulo:"Contacto"}}},Sme={titulo:"Preguntas Frecuentes sobre QA y Testing",subtitulo:"Resuelve tus dudas sobre servicios de Quality Assurance, testing automatizado y cómo podemos ayudar a tu empresa.",items:[{question:"¿Qué es QA y por qué es importante para mi empresa?",answer:"QA (Quality Assurance) es el proceso que garantiza que tu software funcione correctamente antes de que llegue a tus clientes.",details:["Sin QA, los errores en producción generan pérdidas económicas directas y dañan la reputación de tu marca.","Invertir en calidad desde el inicio reduce costos operativos y acelera los tiempos de entrega.","En HakaLab llevamos más de 10 años ayudando a empresas en Chile a convertir la calidad en una ventaja competitiva."],highlight:"más de 10 años"},{question:"¿Qué servicios de QA ofrece HakaLab?",answer:"Ofrecemos un modelo integral de aseguramiento de calida
17956d que cubre todo el ciclo de vida del software:",details:["Automatización de pruebas para acelerar releases y reducir tiempos de entrega.","Pruebas de rendimiento para garantizar disponibilidad en momentos críticos de alta demanda.","Certificación de calidad para implementaciones Salesforce y SAP.","Consultoría estratégica para optimizar procesos de testing y madurar equipos.","Validación de datos para asegurar la integridad de tu información."],highlight:"ciclo de vida del software"},{question:"¿En qué se diferencia HakaLab de otras empresas de QA en Chile?",answer:"Tres pilares nos diferencian:",details:["Capacidad adaptativa: nos integramos al ecosistema del cliente sin imponer tecnologías, adaptando procesos a su contexto de negocio.","Más de 7 productos propios impulsados por IA que aceleran los procesos de calidad y generan eficiencias únicas en el mercado.","Metodología probada por más de 10 años + talento humano altamente especializado = resultados medibles que impactan directamente en el ROI."],highlight:"70% de aceleración en ciclos de entrega"},{question:"¿Cómo puede la automatización de pruebas reducir costos?",answer:"Un error detectado en producción cuesta hasta 10 veces más que prevenirlo en etapas tempranas.",details:["Reduce hasta un 80% el tiempo de validación en cada entrega.","Libera a tu equipo para tareas de mayor valor estratégico.","Acelera el time-to-market de nuevas funcionalidades.","Garantiza calidad continua sin esfuerzo manual repetitivo."],highlight:"80% el tiempo de validación"},{question:"¿Qué capacidad tecnológica tiene HakaLab?",answer:"Contamos con un ecosistema tecnológico amplio y flexible que se adapta a cada cliente:",details:["Herramientas líderes del mercado para automatización, rendimiento e integración continua.","Más de 7 productos propios con IA: motores de automatización, copiloto de calida
17956d, reportes inteligentes y análisis de código.","Nos integramos con los ecosistemas existentes del cliente para potenciar la capacidad del equipo sin fricciones."],highlight:"más de 7 productos propios"},{question:"¿Trabajan con empresas de cualquier tamaño?",answer:"Sí. Nuestro modelo se adapta al tamaño y madurez de cada organización:",details:["Startups en etapas tempranas que necesitan construir una estrategia de calidad desde cero.","Empresas medianas en crecimiento que buscan escalar y profesionalizar sus procesos de testing.","Corporaciones Fortune 500 que requieren optimizar y automatizar operaciones de QA a gran escala."],highlight:"Fortune 500"},{question:"¿Cuánto tiempo toma ver resultados con HakaLab?",answer:"Resultados iniciales son visibles desde las primeras 2-4 semanas:",details:["Nuestro motor de automatización propio implementa soluciones hasta un 40% más rápido que enfoques tradicionales.","Desde el primer sprint se generan entregas de valor incremental.","Nuestro motor está preparado para testear aplicaciones con Inteligencia Artificial, posicionándonos como partners de largo plazo."],highlight:"40% más rápido"}]},_me={header:qpe,nav:zpe,contactModal:Vpe,trabajaModal:Hpe,relatedProducts:Fpe,hakaboost:Bpe,hakabuddy:Upe,descargaExitoModal:$pe,common:Wpe,footer:Gpe,cargando:Kpe,hakapath:Jpe,hakartc:Qpe,ctaNewsletter:Xpe,faq:Ype,hakabuddy_queHace:Zpe,hakabuddy_faq:eme,hakapath_queHace:tme,hakartc_queHace:ame,potencia_hakartc:nme,potencia_hakapath:ime,hakaistudio:rme,hakapath_faq:ome,home:sme,nosotros:lme,servicios:cme,productos:dme,cicloTesting:ume,casosExito:pme,blog:mme,scheduleModal:hme,bugCostCycle:fme,partners:gme,badges:yme,roibox:xme,quickAnalysis:vme,hakaAutomationEngine:bme,frameworkHakalab:wme,terminos:kme,faqServicios:Sme},Ame={tagline:"Testing Solutions"},Eme={inicio:"Home",servicios:"Services",nosotros:"About Us",casosDeExito:"Success Cases",productos:"Products",contacto:"Contact"},Cme={title:"Contact Us",subtitle:"If you're thinking about making a technological leap, Haka Lab can help you.",nombre:"Name",empresa:"Company",email:"Email",mensaje:"How can we help you?",enviar:"Send Request",nombrePlaceholder:"Enter your name",empresaPlaceholder:"Enter your company",emailPlaceholder:"Enter your email",mensajePlaceholder:"Enter your request or comment",enviando:"Sending...",exitoEnvio:"✓ Message sent successfully! We will contact you soon.",errorEnvio:"✗ Error sending. Please try again."},jme={title:"Work With Us",subtitle:"At Haka Lab we are looking for software quality and automation specialists, send us your CV!",nombre:"Name",nombrePlaceholder:"Enter your name",email:"Email",emailPlaceholder:"Enter your email",pais:"Country of residence",paisPlaceholder:"Enter your country of residence",telefono:"Phone",telefonoPlaceholder:"Enter your phone number",cv:"Attach CV",cvPlaceholder:"Click to select your CV (.pdf, .doc, .docx)",cvFormatos:"Accepted formats: PDF, DOC, DOCX. Max 2MB.",enviar:"Submit application",enviando:"Sending...",exitoEnvio:"✓ Application sent successfully! We will contact you soon.",errorEnvio:"✗ Error sending. Please try again.",archivoInvalido:"Only PDF, DOC or DOCX files are allowed.",archivoGrande:"File must not exceed 2MB."},Tme={title:"You might also be interested in",saberMas:"Learn More",impulsadoPorIA:"AI Powered"},Nme={title:"Download Hakaboost Now",subtitle:"To download Hakaboost enter your details",cargo:"Position",sistemaOperativo:"Operating System",aceptaTerminos:"I accept the terms and conditions",descargar:"Download",descargando:"Downloading...",debesAceptar:"You must accept the terms and conditions.",exitoDescarga:"✓ Download started! Check your email.",errorDescarga:"✗ You must accept the terms and conditions.",nombrePlaceholder:"Your name",cargoPlaceholder:"Your position",empresaPlaceholder:"Your company",sistemaOperativoPlaceholder:"Select your OS",hero:{descripcion:"The quality copilot for Jira and Azure DevOps. Speed up your testing and QA workflows by up to 70% with AI.",gratis:"Completely Free"},presentacion:{titulo:"Speed up your testing and QA workflows by up to 70% with AI"},queHace:{titulo:"What does it do?",descripcion1:"HakaBoost is a Chrome extension that integrates as a side panel in Jira and Azure DevOps, revolutionizing how quality team
17956s work. With just a few clicks, it improves task descriptions, generates test scenarios, creates tests automatically, and analyzes the quality of your requirements.",descripcion2:"One of its most powerful features is its ability to use multiple AI engines, including Chrome's local AI. Get intelligent suggestions for acceptance criteria and test cases in Gherkin format, and create issues in Jira or work items in Azure DevOps automatically.",features:["Improves descriptions by transforming them into complete user stories with acceptance criteria and Gherkin scenarios","Creates tests automatically: parses Gherkin scenarios and creates issues in Jira or work items in Azure DevOps linked to the main task","Xray Integration: support for creating Cucumber-type tests and exporting .feature files","Intelligent Analysis (Pro): generates quality reports, suggests test data, and analyzes test coverage","Multiple Export (Pro): export analysis to PDF and post as comments in Jira/Azure"]},caracteristicas:{titulo:"Features",items:["Web Plugin: integrates natively into Jira Cloud and Azure DevOps","Multiple AI: support for Chrome Built-in AI (Gemini Nano, 100% local), Google Gemini, and OpenAI","Secure Authentication: Free and Pro account system with social login (Google) and email/password","Dark/Light Mode: modern and customizable interface","Data Obfuscation: protects your sensitive information (URLs, emails, IPs) before sending it to cloud AIs","Bilingual Support: available in Spanish and English","Pro Tabs with Advanced Analysis: quality analysis, test data suggestion, and coverage analysis"]},beneficios:{titulo:"Benefits",descripcion:"HakaBoost transforms your QA workflow with tangible benefits from day one.",items:["Accelerated QA Cycle: reduces test design and creation time by up to 70%","Improved Quality: generates clear acceptance criteria and more comprehensive test coverage from the start","AI Flexibility: choose between the total privacy of local AI or the power of cloud models","Integrated Workflow: all the tools you need, directly in Jira and Azure DevOps, without context switching","Consistency and Standardization: encourages the use of BDD and Gherkin across the team","Pro Features: unlock advanced analysis to take your quality strategy to the next level","Free Pro Access for Clients: all Haka Lab clients get free access to HakaBoost Pro"]},potencia:{titulo:"HakaBoost empowers the quality of your tasks",descripcion:"HakaBoost is an extension for Chromium-based browsers (Chrome, Edge) that, thanks to multiple AI engines (including Chrome's local AI), allows you to improve task descriptions in Jira and Azure DevOps, generate test scenarios in Gherkin, create tests automatically, and analyze the quality of your requirements. All without leaving your management tool."}},Ime={title:"Download Hakabuddy Now",subtitle:"To download Hakabuddy enter your details",cargo:"Position",sistemaOperativo:"Operating System",aceptaTerminos:"I accept the terms and conditions",descargar:"Download",descargando:"Downloading...",debesAceptar:"You must accept the terms and conditions.",exitoDescarga:"✓ Download started! Check your email.",errorDescarga:"✗ You must accept the terms and conditions.",nombrePlaceholder:"Your name",cargoPlaceholder:"Your position",empresaPlaceholder:"Your company",sistemaOperativoPlaceholder:"Select your OS",hero:{descripcion:"Facilitates the creation of manual reports.",gratis:"Completely Free"},presentacion:{titulo:"Reducing creation time by up to 70%."}},Pme={titulo:"Registration Successful!",mensaje:"The download will start automatically, please wait.",submensaje:"The download may take up to a minute depending on your internet connection. You may need to accept it in your browser.",boton:"Got it"},Rme={cargandoTweets:"Loading tweets...",verEnX:"View on X →",videoNoSoportado:"Your browser does not support the video element.",altEquipoHakalab:"HakaLab - Salesforce and SAP QA Experts",altHeroImage:"HakaLab - Salesforce and SAP QA Experts"},Lme={empresa:"© 2026 Haka Lab. All rights reserved.",enlaces:"Links",siguenos:"Follow Us",privacidad:"Privacy",terminos:"Terms",contacto:"Contact",twitter:"Twitter",linkedin:"LinkedIn",github:"GitHub",ereshaka:"Are you Haka?",trabajaConNosotros:"Work With Us",codigoConducta:"Code of Conduct",politicaSeguridadSalud:"Health & Safety Policy"},Ome={tweets:"Loading tweets..."},Mme={descargar:"Download",ayuda:"It will help you automate tests and make them up to 70% faster and with fewer errors.",titulo1:"Discover our plugin developed to generate XPaths",gratis1:"Completely Free"},Dme={descargar:"Download",hero:{descripcion:"Capture, organize and export REST without leaving the browser",gratis:"Completely Free"},presentacion:{titulo:"Up to 95% faster capturing network traffic, Export your flows to Postman and CSV in one click."}}
17956,qme={titulo:"Know all our success cases!",placeholder:"Your email",boton:"Download success stories",mensaje:"The file will be downloaded automatically."},zme={titulo:"Frequently Asked Questions",subtitulo:"Resolve your doubts about HakaBoost",items:[{question:"What is HakaBoost and what is it for?",answer:"HakaBoost is a testing copilot that helps you improve the descriptions of your user stories in Jira and create test cases automatically using artificial intelligence."},{question:"Do I need to pay to use HakaBoost?",answer:"No, HakaBoost is completely free. You can use it at no cost in your Jira instance."},{question:"Which AI should I choose: OpenAI, Gemini or Chrome?",answer:"You can choose based on your preferences. OpenAI and Gemini are cloud options, while Chrome offers you 100% local AI based on Gemini for greater privacy."},{question:"Does it work without internet connection?",answer:"Yes, if you use the local AI option (Chrome built-in), HakaBoost works completely without internet connection."},{question:"Do I need to configure anything before using HakaBoost?",answer:"You only need to install the extension in your browser and select which AI you want to use. The rest is automatic."},{question:"How do I get my Jira token?",answer:"You can generate a Jira token from your profile in Jira Cloud. Go to Settings > Security > Create and manage API tokens."},{question:"Does HakaBoost save my data on any server?",answer:"No, your data remains in your Jira instance. If you use local AI, everything is processed locally without sending information to external servers."},{question:"Can I use HakaBoost in any Jira project?",answer:"Yes, HakaBoost works with any Jira Cloud project. You just need to have access to that project."},{question:"What exactly does the 'Improve Description' button do?",answer:"The 'Improve Description' button uses AI to analyze your current user story and suggest improvements based on quality and testing best practices."}]},Vme={titulo:"What does it do?",descripcion:"Haka Buddy is a desktop application available for Windows and MAC OS that facilitates the creation of manual reports, reducing creation time by between 50% and 70%",features:["With Haka Buddy you can create test reports in an easy and simple way.","Add what you need and insert screenshots, json documents and more.","It's practical! You'll have a complete report in PDF format automatically when you finish a test."],caracteristicas:"Features",caracteristicasItems:["You can generate as many steps as you need.","Assign a status to each step.","Take full screen screenshots of your tests or custom screen.","Add or upload attachments at any step of the test.","You can include texts as a test step (Designed for APIs testing and DB).","When you generate the report you can choose between: PDF Report. Images in ZIP. JSON XRAY. All at the same time if you need it!"],beneficios:"Benefits",beneficiosDescripcion:"Speed up test creation in Jira by up to 97%",beneficiosItems:["Register your teams.","Register different environments.","You can load your last test data.","Regenerate any test report created before.","Download the images captured in a test.","You can download a JSON to create the test steps in Jira automatically.","Customize your reports: Upload custom covers and give identity to your reports.","Connection with JIRA. You can get user stories, upload reports automatically and more!"]},Hme={titulo:"Frequently Asked Questions",subtitulo:"Resolve your doubts about Hakabuddy",items:[{question:"What is HakaBuddy and what is it for?",answer:"Haka Buddy is a desktop application designed to facilitate the creation of manual tests. It allows you to record step by step, status, test data, screenshots and other relevant details. When the test is finished, the application generates a complete report in PDF format."},{question:"How to create a test in Hakabuddy?",answer:"Creating a new test in Hakabuddy is simple, in the following video we will create a test following the basic options, from the initial information, step by step and export of the final file."},{question:"Can I customize the report covers?",answer:"Yes. You can customize all the covers of the PDF report, additionally in version 2.0, you can customize 100% of the HTML report"},{question:"What options do I have to export results?",answer:"The application offers you a variety of test results, including; the complete PDF report, the images you captured during the test (independently), a .JSON that can be used to import the results to XRAY manually, the ability to automatically record the results in JIRA (requires having an active connection to a JIRA board), and if you have an active connection to Jira and Xray, Hakabuddy allows you to create the manual test automatically in your board."},{question:"Can I connect with JIRA CLOUD?",answer:"Yes, with Hakabuddy you can connect to Jira, this will allow you to get the user stories from the configured jira board, upload reports and attach comments to the selected issues."},{question:"What type of evidence can I attach in a test report?",answer:"You can attach full screen screenshots, cropped and edited screenshots, jsons and attachments."},{question:"Does Hakabuddy store the reports?",answer:"Yes, Hakabuddy has its own history in which you can review all generated reports, images and additional files."},{question:"Is there a limit to the total number of reports I can create?",answer:"No, Hakabuddy has no limit on the number of reports you can create."},{question:"What additional functions does the 'Open own browser' option enable in Hakabuddy?",answer:"The own browser (based on playwright) allows you to record video of the test performed and capture full screen vertically."}]},Fme={titulo:"What does it do?",descripcion1:"HakaBoost is a HakaLab add-on specialized in Jira that allows you to accelerate the quality of task descriptions and easily create tests.",descripcion2:"Haka
17956Boost automatically reads the issue on screen, improves the description with AI (Cloud or Local), detects and creates Gherkin scenarios and creates Tests in Jira/Xray linked to the main story. All without leaving Jira.",features:["Allows you to download the history of generated Xpaths in up to 5 different file types.","Creates up to 4 Xpath locators automatically. Using a precise creation algorithm.","Keeps a history of up to 30 generated Xpaths for later consultation or reuse.","Allows you to convert Xpath to selenium code in up to 4 programming languages.","For each generated Xpath it automatically identifies the number of matching elements in the DOM."],caracteristicas:"Features",caracteristicasItems:["Web add-on. Integrates easily and natively in Google Chrome and Microsoft Edge.","Downloadable directly from Chrome Store.","Xpath construction using the Haka Lab methodology for creating effective locators.","Languages; Spanish and English.","Automatic review of html DOM for identifying matches."]},Bme={titulo:"What does it do?",features:["Allows you to export captured requests to a Postman collection.","Allows you to export a summary of requests to a CSV file.","Keeps a history of captured requests for later consultation or reuse.","Allows you to filter requests by URL."],caracteristicas:"Features",caracteristicasItems:["Network traffic capture up to 95% faster.","Multiple export options, allows you to choose between Postman and CSV.","Organization of requests by steps with a single click.","Request history, allows you to make groups of requests by page and export the document."]},Ume={titulo:"Haka RTC",descripcion1:"Designed for Chromium-based browsers, Haka RTC revolutionizes the way you capture REST traffic for your QA projects. With a few clicks, record requests from DevTools, organize them by steps and export to Postman or CSV to document and reuse scenarios quickly.",descripcion2:"Additionally, it incorporates dynamic filters and exclusion list to isolate own services and omit unauthorized third parties, along with history and repetition count that provide precision and accelerate tests (including stress tests). Free and ready to use in Chrome/Edge."},$me={titulo:"Haka Path is a valuable extension",descripcion1:"Specifically designed for web browsers that revolutionizes the way you generate XPaths for your test automation projects. With just two clicks, this tool allows you to create XPaths efficiently and effectively, significantly accelerating your workflow.",descripcion2:"One of the standout features of Haka Path is generating multiple XPath options and showing how many elements match in real time, providing greater precision, flexibility and time savings in creating locators for your automated tests."},Wme={hero:{descripcion:"The Revolution in Test Automation with Artificial Intelligence",exclusivo:"Exclusive to Haka Lab",cta:"Request Access"},presentacion:{titulo:"We transform how software testing is automated",subtitulo:"We apply Artificial Intelligence strategically to reduce test creation times and optimize processes",etapas:{automatizacion:{titulo:"Automation",descripcion:"Generates robust scripts automatically."},seguridad:{titulo:"Security",descripcion:"Information sent to AI is minimal and obfuscated to align with security and data governance laws."},ia:{titulo:"AI",descripcion:"AI handles the most costly processes of developing automated tests."},talento:{titulo:"Human Talent",descripcion:"Our Engineers supervise what AI creates, adjust and ensure security and functionality."},impacto:{titulo:"Real Impact",descripcion:"Between 70 and 80% reduction in automated test creation times."}}},potencia:{titulo:"Key Features",subtitulo:"Powered by Gemini AI to take your automation to the next level",grabacion:{titulo:"Smart Recording",descripcion:"Capture your interactions in real-time with two modes: Playwright (modern semantic selectors) and Selenium (optimized XPath with uniqueness validation)."},generacion:{titulo:"AI Generation",descripcion:"Gemini AI analyzes your recordings and generates Gherkin test cases, complete Python implementations, optimized Page Objects, and custom steps."},busqueda:{titulo:"Intelligent Vector Search",descripcion:"Embedding system that detects reusable steps, avoids code duplication, suggests best practices, and learns from your testing patterns."}
17956,chat:{titulo:"Interactive Chat with Kai",descripcion:"Integrated AI assistant that answers testing questions, helps refine test cases, suggests improvements, and explains generated code."},analisis:{titulo:"Reusability Analysis",descripcion:"Automatically detects repetitive step sequences, refactoring opportunities, common patterns, and duplicate code."},velocidad:{titulo:"Extreme Speed",descripcion:"Reduces test creation time by 70%. What took 2-4 hours now takes 15-30 minutes."}},queHace:{titulo:"Key Benefits",subtitulo:"Real impact on your automation process",reduccion:"Reduction in automated test creation time",beneficios:["Generates high-quality code","Reuses pre-existing steps","Progressive vectorization for real-time knowledge","Uses a high-quality standard","Frees QA Engineer for other quality tasks","Accelerates project launch","Reduces technical onboarding",'Thanks to its integrated AI chat "KAI" it solves scripting issues quickly']},comparativa:{titulo:"Traditional Automation vs Haka AI Studio",subtitulo:"Discover the difference AI makes in your workflow",aspecto:"Aspect",sinHaka:"Without Haka AI Studio",conHaka:"With Haka AI Studio",tabla:{tiempo:{aspecto:"Creation time",sin:"1 hour per test",con:"12-18 minutes"},seguridad:{aspecto:"Security",sin:"No control over what is sent to AI",con:"Automatic and customizable obfuscation of URLs, emails, domains"},selectores:{aspecto:"Selectors",sin:"Manually written, error-prone",con:"Automatically generated and validated"},reutilizacion:{aspecto:"Code reusability",sin:"Manual, requires search and analysis",con:"Automatic with vector search"},formato:{aspecto:"Test format",sin:"Direct Python code",con:"Readable Gherkin + implementation"},mantenimiento:{aspecto:"Maintenance",sin:"High - fragile selectors",con:"Low - optimized selectors"}},destacado:{titulo:"What used to take 1 hour, now takes 12-18 minutes",descripcion:"Between 70% and 80% reduction in test creation time"}},casosUso:{titulo:"Lean Mindset Applied to Processes",subtitulo:"Haka AI Studio joins Haka Lab's Power Ups to optimize processes and maximize ROI",frontEnd:{titulo:"Front End Testing",descripcion:"Allows building tests for any type of web application, no specifications required on how it was built."},backend:{titulo:"Backend Testing",descripcion:"Thanks to being optimized to work with Haka Automation Engines, it's possible to easily integrate backend tests or steps into created tests."},regresion:{titulo:"Regression Testing",descripcion:"Makes regression tests available in complete suites in an accelerated manner."},ayudante:{titulo:"QA Assistant",descripcion:"The internal KAI chat allows quality engineers to diagnose problems in their tests, make corrections and improve their robustness in seconds."},talento:{titulo:"AI at the Service of Talent",descripcion:"Haka AI Studio uses AI strategically, instead of asking it to build everything, we use its generative layer for intelligent orchestration, which keeps security at maximum."}},faq:{titulo:"Frequently Asked Questions",subtitulo:"Resolve your doubts about Haka AI Studio",items:[{question:"What is Haka AI Studio?",answer:"Haka AI Studio is an exclusive Visual Studio Code extension that combines the power of artificial intelligence with test automation best practices. Record your browser interactions and automatically generate complete test cases in Gherkin/BDD format with ready-to-run implementations."},{question:"What frameworks does it support?",answer:"Haka AI Studio supports Playwright and Selenium, the two most popular web automation frameworks. You can record with one framework and generate code for the other."},{question:"Do I need advanced programming knowledge?",answer:"No. Haka AI Studio is designed so that anyone with basic knowledge can create quality automated tests. AI guides the entire process and generates code following best practices."},{question:"How does vector search work?",answer:"The vector search system analyzes your existing framework and automatically detects reusable steps. This avoids code duplication and ensures you follow established patterns in your project."},{question:"Can I customize the generated code?",answer:"Yes, completely. You can use Kai's chat to refine tests, add additional validations, or adjust any aspect of the generated code."},{question:"Is Haka AI Studio publicly available?",answer:"No, Haka AI Studio is an exclusive Haka Lab tool for our QA services. Contact your project leader to get access."},{question:"What do I need to use Haka AI Studio?",answer:"You need Visual Studio Code 1.85.0 or higher, Node.js 20.x or higher, a Gemini API Key (provided by Haka Lab), and Python 3.8+ to run the tests."},{question:"How much time do I really save?",answer:"On average, our clients report a 70% reduction in test creation time. What used to take 2-4 hours now takes 15-30 minutes."}]}},Gme={titulo:"Frequently Asked Questions",subtitulo:"Resolve your doubts about HakaPath",items:[{question:"What should I do after installing HakaPath?",answer:"After installing the add-on, you need to pin the add-on to your browser from the add-ons menu in Google Chrome, then restart your browser. No additional actions are required beyond these two steps."},{question:"How to generate an xpath?",answer:'To generate an xpath, simply identify the web element you want to get the xpath from, right-click on it and select "Get Hakapath"'},{question:"What localization strategy does HakaPath use?",answer:"HakaPath uses a localization strategy based on xpath best practices. HakaPath automatically constructs the xpath according to the main components available in the clicked web element; id, name, class, etc."},{question:"How many xpaths can be generated?",answer:"HakaPath allows you to generate xpath unlimited. Each time you generate an xpath, up to 4 possible localization options are delivered (in the registered version of the add-on)."},{question:"What are the differences in the generated xpath results?",answer:"HakaPath generates up to 4 xpaths automatically (in the registered version) whose difference lies in the specialization of the localization strategy, thus offering different strategies such as: General localization using wildcard (*), Specific localization using web component tag, Second-order specific localization, adding the parent of the selected element, Third-order specific localization, trying to access the parent web element from a child."},{question:"What languages can generated xpaths be automatically converted to?",answer:"HakaPath allows you to convert generated xpaths to Selenium code to get a webElement, up to 4 languages are available in the configuration options; Python (default), Java, Javascript and C#."},{question:'HakaPath does not deliver xpaths, it stays in "waiting..." What should I do?',answer:'If you are using Google Chrome in mobile device view (size scaling) verify that the "Device toolbar" option is not active, as this option overlays a layer on the web to display mobile device tools which interferes with HakaPath.'},{question:"In what situations can HakaPath fail to deliver a correct result?",answer:"While in the vast majority of cases HakaPath will deliver exact locators, there may be cases where it is difficult to do so, this can originate from the way the website or application is designed, particularly in those where layers of components overlap one another."},{question:"How are XPath matches identified?",answer:"Hakapath automatically searches the HTML DOM for matches for each generated xpath just as it does when you manually enter an xpath in the browser inspector. Occasionally it may happen that no matches are found, this means that the xpath does not match any element in the DOM. We show it anyway in the list of generated Xpaths in case it is useful to use it as a basis to generate a much more specialized locator."},{question:"What is the purpose of identifying and counting elements that match the xpath?",answer:"This will allow you to know with certainty which is the most accurate xpath, plus knowing the number of matches will allow you to identify the type of strategy to use with your xpath when creating a particular web element or a list of them from selenium."}]},Kme={hero:{title:"We are specialists in",title2:"Software Quality",subtitle:"Experts in automated QA and testing who transform quality into a competitive advantage for your business.",cta:"Success stories",scheduleCall:"Let's talk about quality"},services:[{title:"Salesforce QA and Continuous Testing",description:"Our methodology and experience in testing allows us to ensure the quality of your Salesforce developments in multiple layers, accelerating time to market and saving costs in continuous quality assurance through automated regressions."},{title:"SAP QA and Functional Testing",description:"From the planning stage to final product implementation, we help our partners build with quality, reducing errors, improving product reliability and resilience, saving costs, and promoting continuous assurance through automated testing."},{title:"Continuous Performance",description:"Through different scalable strategies we prepare your ecosystem to successfully face high-demand events, delivering valuable information on the actual use of infrastru
17956cture and capabilities, allowing you to save costs in cloud infrastructure while guaranteeing a return on investment."},{title:"Continuous Data Testing",description:"We work on the specific challenges of data infrastructure, analysis and evaluation of the integrity, security and efficiency of data systems."}],methodology:{title:"Methodology",subtitle:"Our DNA: Quality + Innovation + Value Delivery.",description:"An agile, scalable methodology focused on measurable results.",bottomText:"We ensure software quality through different testing approaches, to guarantee the stability, reliability and operability of your products",steps:[{title:"Risk Detection",description:"We identify critical points"},{title:"Prioritization",description:"We focus efforts strategically"},{title:"Agile and automated execution",description:"We implement with speed"},{title:"Continuous feedback and scalability",description:"We improve constantly"}]},errorCost:{title:{before:'"The cost of an error after deployment is ',highlight:"10 times higher",after:' than preventing it."'},description:"Ignoring testing in early stages directly impacts the ROI of your investment, degrades the user experience, and breaks trust in your brand.",risks:["Critical errors discovered in production.","Loss of budget on reactive corrections.","Erosion of reputation and user loyalty."],impactTitle:"Business Impact",impacts:[{label:"Loss of Productivity",percentage:"+55%"},{label:"Accumulated Technical Debt",percentage:"+75%"}],disclaimer:"*Data based on health audits of Salesforce ecosystems pre-Haka Lab."},testimonials:{title:"Testimonials",subtitle:"What do our clients say?",items:[{text:`I especially highlight: 
17957
17958The company's great commitment to supporting the organization in the challenges they have faced. A high level of technical and professional expertise in their teams delivering very good quality solutions. An incredible service vocation that is reflected in the quality of the services they provide. They really put the customer at the center.`,author:"Jesus Rodriguez",position:"CTO",company:"Sodimac"},{text:"Thanks to Haka Lab, we have been able to establish a robust and automated certification process in our Salesforce CRM platform, which has improved the time-to-market of our developments",author:"Francisco Rodriguez",position:"Subgerente CRM",company:"Consorcio"},{text:"The adaptation to the teams and constant support and commitment to the challenges posed stands out. Therefore I can perfectly recommend any service that Haka Lab can provide in the field of test automation.",author:"Humberto Proschle",position:"Technology Manager",company:"Casa Ideas"}]},clients:{title:"Our clients",description:"We work with leading companies in their industries, helping them achieve their technological objectives with innovative and quality solutions."},partners:{title:"Our partners"}},Jme={hero:{title:"Who are we?",subtitle:"At Haka Lab, we drive technological quality. With more than 7 years of experience, we collaborate with companies from various sectors — retail, banking, health and services — to guarantee technological solutions that align with their objectives and organizational culture.",cta:"Contact us"},identidad:{intro:"We believe that quality is born from human commitment, not just code. That's why our identity is also reflected in Koru and Kai, two characters that symbolize what drives us:"},koru:{descripcion:"Koru represents innovation and automation, always looking for new ways to create value."},kai:{descripcion:"Kai embodies collaboration and trust, the force that ensures that every delivery is accompanied by excellence."},haka:{conclusion:"Together, they do the haka: a dance that conveys unity, energy and shared purpose. This is how we work every day at Haka Lab: with passion, in community and always focused on generating Continuous Value Delivery."},caracteristicas:{esencia:{title:"Our Essence",description:"We are dedicated to continuously improving our processes and services, ensuring that each project exceeds expectations in quality and efficiency."},vision:{title:"Vision",description:"We aspire to positively impact our partners and clients, fostering a culture of innovation and continuous improvement."},mision:{title:"Mission",description:"We focus on offering technological solutions that provide sustainable value, backed by excellent service and a solid organizational culture."},compromiso:{title:"Commitment",description:"We are committed to driving the growth and success of our clients through innovative and high-quality technological solutions."}}
17958,redes:{titulo:"Follow Us on Our Social Networks",subtitulo:"Stay updated with our latest news and updates",verMasNoticias:"See more news"}},Qme={titulo:"Our Services",descripcion:"We offer comprehensive testing and quality solutions designed to ensure the excellence of your technological products. From functional testing to data analysis, we cover all stages of your development cycle.",contactanos:"Contact Us",servicesDescription:"Our services are designed to ensure quality, automation and scalability of your technological solutions.",agileCycle:{introText:"We integrate the quality vision in all stages of the software development lifecycle, making the process more efficient and reducing costs.",centerText:{line1:"Software Development",line2:"Lifecycle"},devStages:["Planning","Design","Development","Testing","Deploy","Review","Launch"],qaStages:[{label:"Analysis",fullName:"Analysis, preconditions and risks",description:"Detailed analysis of requirements, risk identification and establishment of preconditions to ensure quality from the start."},{label:"Test Design",fullName:"Test Design",description:"Detailed design of the test plan with strategies, test cases and acceptance criteria."},{label:"Construction",fullName:"Test Construction",description:"Construction and development of automated and manual tests according to the defined plan."},{label:"Execution",fullName:"Test Execution",description:"Execution of tests in different environments and scenarios to validate software quality."},{label:"Regression Verification (CI/CD)",fullName:"Testing in CI/CD",description:"Integration of tests in the CI/CD pipeline for continuous and automated validation."},{label:"Evaluation",fullName:"Results Evaluation",description:"Analysis of results, report generation and decision making based on quality metrics."},{label:"Measurement",fullName:"Production Indicators Measurement",description:"Measurement and analysis of key productivity and efficiency indicators of the testing process for continuous improvement."}]},performance:{title:"Continuous Performance",subtitle:"Our framework expands the traditional approach to performance testing by integrating Observability and continuous monitoring to ensure infrastru
17958cture and ecosystem preparation against any challenge.",cta:"Request a free demo",features:["Testing strategies that adapt to your business requirements.","Continuous improvement through constant test execution.","Focus on customer experience and business objectives.","Personalized and custom reporting.","Actively integrated process."]},continuos:{title:"Continuous Testing",subtitle:"Functional - Salesforce - SAP"},services:[{title:"Salesforce Testing",description:"We ensure product quality thanks to our specially developed and robust testing framework for Salesforce, optimizing certification times by creating parallel execution strategies, multiple combination scenarios, custom object identification, regression, and continuous integration to minimize the impact on business operations.",benefit:"Accelerate the time-to-market of your Salesforce projects by 70% with specialized testing",features:["Reduction of up to 70% in certification time.","Own Automation Framework.","Custom reporting and evidence","Multi-browser executions"]},{title:"Functional Testing",description:"We implement the highest quality standards throughout the entire software development lifecycle. From the planning stage to final product implementation, we provide technical and methodological support to teams in meeting their challenges, with a central focus on test automation and an integrated approach to the entire process.",benefit:"Reduce operational costs by up to 60% through intelligent automation and early error detection",features:["Parallel certification to reduce delivery by up to 80%.","Highly reusable automation.","Continuous quality strategies."]},{title:"SAP Testing",description:"We integrate legacy systems such as databases, OMS, APIs, IMS, and various e-commerce platforms through our test automation framework. We've also incorporated technologies like computer vision, peripheral control, and everything necessary to ensure effective validations that reduce risks and costs while maximizing benefits.",benefit:"Minimize risks in critical SAP implementations, protecting million-dollar investments",features:["Phased automation and short-term value delivery.","Reduction in certification time.","Customized Reporting."]}],data:{title:"Data Testing",subtitle:"We work on the specific challenges of data infrastructure, we delve into the analysis and evaluation of the integrity, security and efficiency of data systems. Additionally, we identify failures early and areas for improvement, ensuring the robustness and reliability of databases and information storage, optimizing information management and guaranteeing its security.",cta:"Request a free demo",features:["Reduction of up to 90% of time related to data testing processes.","Testing, analysis and evaluation.","Constant regressive executions.","Constant data consistency verification."]}},Xme={titulo2:"Discover our testing tools",hero:{title:"Strategic solutions for your",title2:" software quality",subtitle:"Simplify your quality processes with our tools powered by strategic Artificial Intelligence.",cta:"Request a free demo"},titulo:"Boost your QA and development work with our Haka tools",descripcion:"Simplify your daily tasks, reduce time and automate with intelligence.",hakaboost:{descripcion:"Speed up test creation in Jira by up to 97% with AI"},hakabuddy:{descripcion:"Create manual test reports in minutes, not hours"},hakapath:{descripcion:"Generate XPaths automatically with precision and speed"},hakatools:{descripcion:"Complete suite of tools for test automation"},hakartc:{descripcion:"Capture and export REST traffic for your API tests"}
17958,hakainsight:{descripcion:"Analyze your code and create simple explanations with interactive diagrams automatically"},hakaengine:{descripcion:"BDD test automation framework with Playwright, AI self-healing and 1800+ ready-to-use steps"},hakaaistudio:{descripcion:"Companion to accelerate test automation with our engine and artificial intelligence"},hakaistudio:{descripcion:"VS Code extension with AI that transforms recordings into complete automated tests"}},Yme={titulo:"Testing Cycle",descripcion:"Our products directly impact the different stages of the testing cycle, allowing us to accelerate processes and optimize quality assurance.",productoLabel:"Product:",entendido:"Got it",pasos:[`Planning
17959and analysis`,`Test case
17960design`,`Test
17961execution`,`Defect
17962reporting`,`Closure and
17963validation`,`Continuous
17964improvement`],descriptions:["We define clear quality objectives, identify risks and establish acceptance criteria. We analyze functional and non-functional requirements to ensure that every aspect of the software meets quality standards from the start.","We create exhaustive test scenarios that cover main flows, edge cases and exceptional situations. We design testing strategies that ensure complete code coverage and validation of all business requirements.","We implement robust and maintainable automation scripts. We configure test environments that replicate production and establish CI/CD pipelines to integrate testing at each stage of development, detecting defects early.","We execute functional, regression, performance and security tests automatically. We validate that each functionality operates correctly under different conditions and loads, ensuring system stability and reliability.","We analyze quality metrics, identify defect patterns and generate detailed reports. We provide complete visibility of the software quality status, facilitating informed decisions about the release.","We refine testing processes based on lessons learned. We optimize test coverage, reduce execution times and improve early defect detection. We implement feedback loops to continuously raise quality standards."],productDescriptions:{hakaboost:"Planning and analysis, Test case design",hakabuddy:"Test case design, Execution, Reporting, Analysis and visibility",hakapath:"Test execution",hakartc:"Test case design",hakainsight:"Analyze and understand your source code easily",hakaengine:"Functional test automation without coding",hakaaistudio:"Test automation with Artificial Intelligence"}},Zme={hero:{title:"Do your systems fail when you need them most?",subtitle:"At Haka Lab we solve those pains with technology, speed and real quality. See how companies like yours turned their challenges into success stories - with results in hours saved, bugs eliminated and happy customers.",btn:"Request a free evaluation"},desafioLabel:"Challenge:",solucionLabel:"Solution:",testimonioLabel:"Testimonial",qaLabel:"QA",cta:{titulo:"Want to achieve these results?",descripcion:"Schedule your free diagnosis and discover how we adapt our frameworks to your environment.",boton:"Request a free evaluation"},cases:{walmart:{company:"Walmart",title:"100% Uptime during Cyber Day",problem:"Challenge: Omnichannel operations required guaranteeing system stability during critical high-traffic events (such as launches and promotional campaigns), avoiding errors and production outages.",solution:"Solution: We implemented an E2E automation strategy focused on performance, integrating QMS, ecommerce, APIs, synthetic monitoring and computer vision on dynamic infrastructure.",results:[{metric:"100%",description:"We ensured 100% compliance with time to market, with no delays in key releases."},{metric:"65%",description:"We reduced critical incidents related to system performance by 65%."},{metric:"99.98%",description:"We enabled preventive alerts in real time, raising the availability of the digital ecosystem to 99.98%"}],qa:"We transformed QA into a strategic axis to anticipate risks and improve customer experience."},melt:{company:"Melt Pizzas",title:"Synthetic Monitoring",problem:"Melt Pizzas sought to ensure that its infrastru
17964cture could support the accelerated growth of its digital channels, especially in high-demand contexts.",solution:"We performed synthetic monitoring and performance testing to validate whether the current infrastructure could support expected growth. Strategic recommendations were issued based on load analysis and user experience.",results:[{description:"We established a permanent monitoring base that allows scaling without sacrificing quality or availability."},{description:"Customized reporting to present data obtained from tests, with charts to represent relevant KPIs to management."},{description:"Proactive validation of infrastructure response capacity."}]},consorcio:{company:"Consorcio",title:"CRM Salesforce",problem:"Slow manual certification process without traceability.",solution:"100% automation of Salesforce functional tests with execution from CI/CD.",results:[{description:"We reduced time to production by 70%."},{description:"We improved process visibility and eliminated technical debt in weeks."}],testimonial:{text:"Thanks to Haka Lab, we have been able to establish a robust and automated certification process on our Salesforce CRM platform, which has improved the time to market of our developments",author:"Francisco Rodríguez",position:"Salesforce CRM Sub-Manager",company:"Implementation Leader"}},casaideas:{company:"Casa Ideas",title:"Automation of Ecommerce Flow and SAP and Magento integrations",problem:"Complex E2E flow difficult to certify which had multiple production errors.",solution:"We automated SAP Logon v760 together with the E2E of the purchase in the ecommerce and then validated that the data generated matched and arrived correctly to SAP, Magento, Omnix and Dbnet.",results:[{description:"Automation of comprehensive tests with SAP and legacy systems."},{description:"Test execution on automated virtual machines."}],testimonial:{text:"For the launch of our new e-commerce platform we decided to hire Haka Lab's services as they demonstrated a high degree of technical knowledge in the test automation process. The project achieved its objectives and stands out especially: - Innovation and technology management - Use of Methodologies - Support and accompaniment in the design and development of tests - Constant adaptation to change - Technical support and commitment. Additionally, the adaptation to the teams and constant support and commitment to the challenges posed stands out. Therefore, I can perfectly recommend any service that Haka Lab can provide in the field of test automation.",author:"Casa Ideas Team",position:"",company:"Casa Ideas"}},sodimac:{company:"Sodimac Homecenter",title:"Backoffice closing and reconciliation",problem:"Difficulty in the process and high times for closing and reconciliation of sales points.",solution:"We automated a critical process that previously took 8 hours and reduced it to just 70 minutes, overcoming complex technological barriers with legacy components (UXPOS, SAP, Control-M) and computer vision.",results:[{description:"Reduction of time for the manual Back office Closing and Reconciliation process from 8 hours to 70 minutes automated."},{description:"Automation of UXPOS, SAP and Control-M components"}],testimonial:{text:"The company's great commitment to supporting the organization in the challenges it has faced stands out especially. A high level of technical and professional expertise in its teams delivering very good quality solutions. An incredible vocation for service that is reflected in the quality of the services they provide. They really put the customer at the center.",author:"Jesús Rodríguez",position:"CTO Sodimac",company:""}},scotiabank:{company:"Scotiabank",title:"Digital Factory",problem:"",solution:"We were pioneers in implementing a Continuous Testing and Delivery strategy in the Digital Factory of one of Chile's leading banking entities. We incorporated practices such as ATDD and BDD to align business with development and ensure quality from the first sprint. We took charge of the complete certification of the factory, integrating quality in all layers.",results:[{description:"Total certification of digital products in parallel with development."},{description:"Successful implementation of ATDD and BDD as the basis for QA maturity."},{description:"Reduction in delivery cycles thanks to Continuous Delivery."},{description:"We established a continuous quality model that remains in place today."}]},parquearauco:{company:"Parque Arauco",title:"SAP Hana to AWS Migration",problem:"Challenge: Parque Arauco faced the challenge of ensuring quality in a complex migration to AWS, involving multiple data layers, cloud services and critical business components.",solution:"Solution: We deployed our specialized automation framework for data certification, applying technologies such as Spark, Glue, Hyde, C3, Lambda and Python. We implemented regressive tests with a focus on traceability and end-to-e
17964nd integrity, actively integrating them with the client's teams with iterative deliveries and continuous feedback.",results:[{description:"Reduction in certification times thanks to constant regressions identifying errors early."},{description:"Own Automation Framework for data certifications with technologies such as Spark, Hyde, Glue, C3, Lambda, Python."}]}}},ehe={titulo:"Blog",titleFront:"HakaLab Blog",descripcion:"Articles about testing, software quality and test automation",leerMas:"Read More",verEnBlog:"View on Blog",articulosRelacionados:"Related Articles",volverAlBlog:"Back to Blog",buscar:"Search articles...",filtrarPorEtiqueta:"Filter by Tag",limpiarFiltros:"Clear Filters",noHayArticulos:"No published articles yet",noEncontrados:"No articles found with the selected filters",mostrando:"Showing",de:"of",articulos:"articles",vistas:"views",autor:"Author",creado:"Created",etiquetas:"Tags",por:"By"},the={title:"Schedule a Call",name:"Name",email:"Email",company:"Company",date:"Date",time:"Time",message:"Message (optional)",schedule:"Schedule",scheduling:"Scheduling...",cancel:"Cancel",success:"Call scheduled successfully!",successMessage:"We will send you a confirmation email",errorRequired:"Please fill in all required fields",noCalendarUrl:"Calendar is not configured",close:"Close",calendlyMessage:"Click the button to open the calendar and schedule your call",openCalendar:"Open Calendar"},ahe={title:"The Cost of Bugs in the Development Cycle",subtitle:"Cost of finding a bug in the software development lifecycle",message:"By integrating ourselves into your team, we accelerate bug detection to early stages",conclusion:"That saves money",ciclos:"Development Cycle",stages:[{label:"Planificación"},{label:"Design"},{label:"Coding"},{label:"Testing"},{label:"Production"}]},nhe={titulo:"Official Partner of",titulo2:"XRAY by Sembi",titulo3:"by Sembi",subtitulo:"We are official implementers of XRAY in Jira Cloud and specialists in its professional use to support software quality for our clients.",conversemos:"Let's talk about quality"},ihe={partners:"Strategic Partners",lideres:"Leaders in Salesforce Quality"},rhe={title:"Impact on ROI",title2:"Efficiency"},ohe={welcome:{title:"Haka Lab Quality Self-Assessment",subtitle:"Answer the following questions to measure the quality level you currently apply to your software development",email:"Email",emailPlaceholder:"[email protected]",company:"Company",companyPlaceholder:"Your company name",industry:"Industry",industryPlaceholder:"Select your industry",developmentType:"Development Type",developmentTypePlaceholder:"Select development type",startButton:"Start Assessment",requiredField:"This field is required",invalidEmail:"Email is not valid"},quiz:{progress:"Progress",question:"Question",of:"of",continueButton:"Continue",previousButton:"Previous",seeResultsButton:"See Results",allQuestionsRequired:"Please answer all questions before continuing"},rating:{never:"Never",rarely:"Rarely",sometimes:"Sometimes",frequently:"Frequently",always:"Always"},results:{title:"Your Results",yourScore:"Your Score",outOf:"out of",points:"points",maturityLevel:"Maturity Level",analysis:"Personalized Analysis",redFlags:"Identified Red Flags",noRedFlags:"Excellent! No critical red flags identified.",recommendations:"How can we help you?",recommendationsSubtitle:"Recommended services based on your assessment",contactButton:"Contact HakaLab",learnMore:"Learn more",highScoreMessage:"Congratulations! Your team has an established quality culture. We can help you optimize your processes even further.",savingResults:"Saving results...",resultsSaved:"Results saved successfully"},maturityLevels:{reactive:{name:"Reactive Quality",label:"Critical Level",diagnosis:"The team is firefighting. QA is a bottleneck at the end of the process with little visibility into production."},transition:{name:"Quality in Transition",label:"Medium Level",diagnosis:"Efforts exist (perhaps some unit tests or QA environments), but consistency and metrics for improvement are lacking."},advanced:{name:"Advanced Quality",label:"Pro Level",diagnosis:"The team has a quality culture. QA is integrated and there are metrics."}},redFlags:{silos:{title:"Silos Alert",message:"Your QA team is isolated; this generates rework and high correction costs."},production_risk:{title:"Production Risk Alert",message:"You are flying blind; you are not learning from your production errors."},technical_debt:{title:"Technical Debt Alert",message:"Your manual regression will become unsustainable soon. Automation is your next step."}},services:{qa_assessment:{name:"QA Assessment & Strategy",description:"We define processes from scratch, establish DOR/DOD and shift QA left."},test_automation:{name:"Test Automation",description:"We automate smoke and regression tests to free up time and improve c
17964onfidence."},continuous_testing:{name:"Continuous Testing",description:"We integrate tests into your CI/CD pipeline to detect problems early."},performance_testing:{name:"Performance Testing",description:"We optimize system load and ensure your application scales."},data_testing:{name:"Data Testing",description:"We validate the quality and accuracy of your data in pipelines and reports."},resource_optimization:{name:"Resource Optimization",description:"We optimize your existing QA processes to maximize efficiency and reduce costs."}},errors:{loadingQuestions:"Error loading questions",savingResults:"Error saving results",generic:"An error occurred. Please try again."}},she={hero:{badge:"Automation Engine",title:"Haka Automation Engine",titleHighlight:"Intelligence applied to quality",subtitle:"Our specialized automation engine integrates the best testing technologies to build automated tests up to 40% faster, reducing costs and ensuring continuous quality.",ctaContact:"Request Demo"},diagram:{title:"Engine Architecture",subtitle:"Based on our experience, we created a complete layered solution that optimizes every stage of the testing process.",layer1:{title:"Technology Base",description:"Selenium, Playwright, and Behave (Gherkin) for modern, stable, parallel-run testing"},layer2:{title:"Powered by Experience and AI",description:"It allows you to build tests for front-end, REST API, databases, and Gene AI at high speed."},layer3:{title:"Native Integrations",description:"Direct connection with Jira, Xray, Zephyr, and Grafana for real-time results"},layer4:{title:"Automatic Reports",description:"Automatically generated HTML/Video reports along with tests to facilitate monitoring, indicator review, and complete traceability"},layer5:{title:"CI/CD Ready",description:"Prepared for continuous integration and deployment pipelines"},note:"Our products drive the engine to streamline the process, maximize quality, and reduce the costs of building and running tests."},aiTesting:{badge:"Testing Innovation",title:"AI-Powered Engine",subtitle:"Our engine is prepared to test applications using Generative AI, through advanced semantic analysis and RAG (Retrieval-Augmented Generation) strategies.",innovationBadge:"Innovation",features:{genAI:{title:"Generative AI Testing",description:"Specialized validation for applications that use GEN AI to generate interactions or responses to their users"},semantic:{title:"Semantic Analysis",description:"Intelligent evaluation of the meaning and context of AI-generated responses, saving costs associated with external validators"},rag:{title:"RAG Strategies",description:"Testing systems that combine information retrieval with content generation using different validation strategies and quantitative analysis of results"},validation:{title:"Quality Validation",description:"Verification of accuracy, consistency, and relevance in AI responses in alignment with the client's technological and business expectations"}},stat:{label:"Ready for the future",value:"Gen AI",description:"Specialized testing for the new era of intelligent applications"},diagram:{input:{title:"User Input",description:"Query or prompt"}
17964,genAI:{title:"Generative AI",description:"Processing + RAG"},output:{title:"Generated Response",description:"AI Content"},testing:{title:"Haka Automation Engine",description:"Semantic Validation"}}},comparison:{title:"Efficiency Comparison",subtitle:"Discover how Haka Automation Engine accelerates your testing process, optimizes resources, maximizes efficiency, and saves costs.",traditional:{badge:"Traditional Method",title:"Without Specialized Engine",description:"Manual construction of each test component",point1:"Development from scratch",point2:"Longer implementation time",point3:"High resource costs"},hakalab:{badge:"With Hakalab",title:"Haka Automation Engine",description:"Pre-built and optimized components",point1:"1500+ ready-to-use steps",point2:"Accelerated implementation",point3:"Significant cost reduction"},savings:"Less development time"},benefits:{title:"Key Benefits",subtitle:"Why Haka Automation Engine makes the difference",speed:{title:"Optimized Speed",description:"Reduce test construction time by up to 40% with pre-built components"},coverage:{title:"Maximized Coverage",description:"Tests across all layers: front-end, API REST, databases and Gen AI"},continuous:{title:"Continuous Quality",description:"CI/CD integration for automatic regressions and immediate feedback"},reports:{title:"Robust Reports",description:"Automatic documentation with evidence, metrics and complete traceability"},integrations:{title:"Native Integrations",description:"Direct connection with Jira, Xray, Zephyr and Grafana without complex configuration"},cost:{title:"Cost Savings",description:"Resource optimization and time reduction translates into real savings"}},technologies:{title:"Integrated Technologies",subtitle:"A complete ecosystem of industry-leading tools",products:{title:"Hakalab Products Included",description:"All our products are designed to work with the engine and accelerate your testing"}},cta:{badge:"Start Now",demoTitle:"Automated Execution Demo",demoSubtitle:"Watch how Haka Automation Engine executes automated tests in real-time",videoLoading:"Loading video...",videoLoadingSubtitle:"Please wait a few seconds",title:"Ready to accelerate your testing?",description:"Schedule a personalized demo and discover how Haka Automation Engine can transform your QA process",scheduleDemo:"Schedule Demo",contact:"Contact",stat1:"Less time",stat2:"Pre-built steps",stat3:"Automatable"}},lhe={hero:{badge:"Comprehensive Framework",title:"HakaLab Framework",titleHighlight:"People + Methodology + Technologies",subtitle:"Working together to ensure the quality of your products",ctaContact:"Request Demo"},pillars:{title:"HakaLab Framework",subtitle:"Our solution focuses on three fundamental pillars that work in synergy, learning and continuous improvement",people:{title:"People",description:"We drive operational efficiency through a comprehensive quality strategy. We apply Shift-Left Testing to anticipate defects and reduce technical debt from the beginning of the project to production deployment."},methodology:{title:"Methodological Framework",description:"We implement quality practices throughout the software development lifecycle using industry best practices."},technology:{title:"Technological Framework",description:"We use our own technological solution built on the most robust testing and automation tools available today, powered by AI and our experience."}},methodology:{title:"Methodological Framework",subtitle:"We implement quality practices throughout the development cycle through agile methodologies and continuous improvement",quote:"We integrate the Haka Lab methodological framework according to the client's needs and capabilities in an evolutionary model of continuous improvement, value and constant return on investment.",author:"Matías Carrasco",authorRole:"CEO Haka Lab"},technology:{subtitle:"Robust technologies powered by our engineers' expertise",techTitle:"Technology Stack",aiPowered:"AI Powered",differentiator:{title:"What sets us apart?",description:"It's not just about using the best tools, it's how our engineers master them to accelerate processes, reduce costs and maximize quality. We power every project with our Haka products."},powerups:{title:"Haka Power-Ups",description:"Our proprietary products that multiply the efficiency of the technology framework:"},cta:"Learn about Haka Automation Engine",tools:{selenium:"Web browser automation",playwright:"Modern web application testing",cucumber:"BDD framework with Gherkin",python:"Language for testing scripts",jenkins:"CI/CD automation",docker:"Containers for consistent environments",github:"Version control and collaboration",jira:"Project management and tracking",xray:"Test case management in Jira",grafana:"Metrics visualization and dashboards",html:"Automated HTML reports",apirest:"REST API testing",bbdd:"Database testing",front:"Frontend interface testing",chrome:"Browser for automated testing",appium:"Mobile app automation"}}},che={titulo:"Terms and Conditions of Use",ultimaActualizacion:"Last updated",definiciones:{titulo:"Definitions"},aceptacion:{titulo:"Acceptance of Terms"},licencia:{titulo:"License to Use"},restricciones:{titulo:"Usage Restrictions"},actualizaciones:{titulo:"Updates and Changes to Services"},privacidad:{titulo:"Privacy and Data Protection"},limitacion:{titulo:"Limitation of Liability"},terminacion:{titulo:"Termination"},legislacion:{titulo:"Applicable Law"},modificaciones:{titulo:"Modifications to Terms"},politicaPrivacidad:{titulo:"Haka Lab Privacy Policy",informacion:{titulo:"Information We Collect"},finalidades:{titulo:"Processing Purposes"},baseLegal:{titulo:"Legal Basis and Consent"},transferencia:{titulo:"Data Transfer and Sharing"},seguridad:{titulo:"Information Security"},derechos:{titulo:"Your Rights"},cambios:{titulo:"Changes to this Policy"},contacto:{titulo:"Contact"}}},dhe={titulo:"Frequently Asked Questions about QA and Testing",subt
17964itulo:"Get answers about Quality Assurance services, test automation, and how we can help your business.",items:[{question:"What is QA and why is it important for my company?",answer:"QA (Quality Assurance) is the process that ensures your software works correctly before it reaches your customers.",details:["Without QA, production bugs generate direct financial losses and damage your brand reputation.","Investing in quality from the start reduces operational costs and accelerates delivery timelines.","At HakaLab we have over 10 years of experience helping companies in Chile turn quality into a competitive advantage."],highlight:"over 10 years"},{question:"What QA services does HakaLab offer?",answer:"We offer a comprehensive quality assurance model covering the entire software lifecycle:",details:["Test automation to accelerate releases and reduce delivery times.","Performance testing to ensure availability during critical high-demand moments.","Quality certification for Salesforce and SAP implementations.","Strategic consulting to optimize testing processes and mature teams.","Data validation to ensure the integrity of your information."],highlight:"entire software lifecycle"},{question:"What sets HakaLab apart from other QA companies in Chile?",answer:"Three pillars differentiate us:",details:["Adaptive capability: we integrate into the client's ecosystem without imposing technologies, adapting processes to their business context.","Over 7 proprietary AI-powered products that accelerate quality processes and generate unique efficiencies in the market.","A methodology proven over 10+ years + highly specialized talent = measurable results that directly impact ROI."],highlight:"70% acceleration in delivery cycles"},{question:"How can test automation reduce costs?",answer:"A bug detected in production costs up to 10 times more than preventing it in early stages.",details:["Reduces validation time by up to 80% per delivery.","Frees your team for higher strategic value tasks.","Accelerates time-to-market for new features.","Ensures continuous quality without repetitive manual effort."],highlight:"80% validation time"},{question:"What is HakaLab's technological capability?",answer:"We have a broad and flexible technology ecosystem that adapts to each client:",details:["Industry-leading tools for automation, performance, and continuous integration.","Over 7 proprietary AI products: automation engines, quality copilot, smart reports, and code analysis.","We integrate with the client's existing ecosystems to enhance team capacity without friction."],highlight:"over 7 proprietary products"},{question:"Do you work with companies of any size?",answer:"Yes. Our model adapts to the size and maturity of each organization:",details:["Early-stage startups that need to build a quality strategy from scratch.","Growing mid-size companies looking to scale and professionalize their testing processes.","Fortune 500 corporations that need to optimize and automate QA operations at scale."],highlight:"Fortune 500"},{question:"How long does it take to see results with HakaLab?",answer:"Initial results are visible within the first 2-4 weeks:",details:["Our proprietary automation engine implements solutions up to 40% faster than traditional approaches.","From the first sprint, incremental value deliveries are generated.","Our engine is prepared to test AI-powered applications, positioning us as long-term partners for your tech evolution."],highlight:"40% faster"}]},uhe={header:Ame,nav:Eme,contactModal:Cme,trabajaModal:jme,relatedProducts:Tme,hakaboost:Nme,hakabuddy:Ime,descargaExitoModal:Pme,common:Rme,footer:Lme,cargando:Ome,hakapath:Mme,hakartc:Dme,ctaNewsletter:qme,faq:zme,hakabuddy_queHace:Vme,hakabuddy_faq:Hme,hakapath_queHace:Fme,hakartc_queHace:Bme,potencia_hakartc:Ume,potencia_hakapath:$me,hakaistudio:Wme,hakapath_faq:Gme,home:Kme,nosotros:Jme,servicios:Qme,productos:Xme,cicloTesting:Yme,casosExito:Zme,blog:ehe,scheduleModal:the,bugCostCycle:ahe,partners:nhe,badges:ihe,roibox:rhe,quickAnalysis:ohe,hakaAutomationEngine:she,frameworkHakalab:lhe,terminos:che,faqServicios:dhe},phe={es:{translation:_me},en:{translation:uhe}};wa.use(yH).init({resources:phe,lng:localStorage.getItem("language")||"es",fallbackLng:"es",interpolation:{escapeValue:!1}});xx.createRoot(document.getElementById("root")).render(s.jsx(Re.StrictMode,{children:s.jsx(fP,{children:s.jsx(Dpe,{})})}));

Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.