diff --git a/backend/public/assets/index-CRKRzJj1.js b/backend/public/assets/index-CRKRzJj1.js new file mode 100644 index 0000000..badf865 --- /dev/null +++ b/backend/public/assets/index-CRKRzJj1.js @@ -0,0 +1,272 @@ +var uy=Object.defineProperty;var cy=(e,t,n)=>t in e?uy(e,t,{enumerable:!0,configurable:!0,writable:!0,value:n}):e[t]=n;var ve=(e,t,n)=>cy(e,typeof t!="symbol"?t+"":t,n);function dy(e,t){for(var n=0;nr[i]})}}}return Object.freeze(Object.defineProperty(e,Symbol.toStringTag,{value:"Module"}))}(function(){const t=document.createElement("link").relList;if(t&&t.supports&&t.supports("modulepreload"))return;for(const i of document.querySelectorAll('link[rel="modulepreload"]'))r(i);new MutationObserver(i=>{for(const s of i)if(s.type==="childList")for(const o of s.addedNodes)o.tagName==="LINK"&&o.rel==="modulepreload"&&r(o)}).observe(document,{childList:!0,subtree:!0});function n(i){const s={};return i.integrity&&(s.integrity=i.integrity),i.referrerPolicy&&(s.referrerPolicy=i.referrerPolicy),i.crossOrigin==="use-credentials"?s.credentials="include":i.crossOrigin==="anonymous"?s.credentials="omit":s.credentials="same-origin",s}function r(i){if(i.ep)return;i.ep=!0;const s=n(i);fetch(i.href,s)}})();function fy(e){return e&&e.__esModule&&Object.prototype.hasOwnProperty.call(e,"default")?e.default:e}var Kp={exports:{}},fl={},Xp={exports:{}},ie={};/** + * @license React + * react.production.min.js + * + * Copyright (c) Facebook, Inc. and its affiliates. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + */var bs=Symbol.for("react.element"),py=Symbol.for("react.portal"),hy=Symbol.for("react.fragment"),my=Symbol.for("react.strict_mode"),gy=Symbol.for("react.profiler"),vy=Symbol.for("react.provider"),yy=Symbol.for("react.context"),wy=Symbol.for("react.forward_ref"),xy=Symbol.for("react.suspense"),ky=Symbol.for("react.memo"),Sy=Symbol.for("react.lazy"),Rd=Symbol.iterator;function Ey(e){return e===null||typeof e!="object"?null:(e=Rd&&e[Rd]||e["@@iterator"],typeof e=="function"?e:null)}var Jp={isMounted:function(){return!1},enqueueForceUpdate:function(){},enqueueReplaceState:function(){},enqueueSetState:function(){}},Zp=Object.assign,eh={};function si(e,t,n){this.props=e,this.context=t,this.refs=eh,this.updater=n||Jp}si.prototype.isReactComponent={};si.prototype.setState=function(e,t){if(typeof e!="object"&&typeof e!="function"&&e!=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,e,t,"setState")};si.prototype.forceUpdate=function(e){this.updater.enqueueForceUpdate(this,e,"forceUpdate")};function th(){}th.prototype=si.prototype;function rc(e,t,n){this.props=e,this.context=t,this.refs=eh,this.updater=n||Jp}var ic=rc.prototype=new th;ic.constructor=rc;Zp(ic,si.prototype);ic.isPureReactComponent=!0;var Od=Array.isArray,nh=Object.prototype.hasOwnProperty,sc={current:null},rh={key:!0,ref:!0,__self:!0,__source:!0};function ih(e,t,n){var r,i={},s=null,o=null;if(t!=null)for(r in t.ref!==void 0&&(o=t.ref),t.key!==void 0&&(s=""+t.key),t)nh.call(t,r)&&!rh.hasOwnProperty(r)&&(i[r]=t[r]);var l=arguments.length-2;if(l===1)i.children=n;else if(1>>1,$=O[L];if(0>>1;Li(J,P))oe<$&&0>i(le,J)?(O[L]=le,O[oe]=P,L=oe):(O[L]=J,O[G]=P,L=G);else if(oe<$&&0>i(le,P))O[L]=le,O[oe]=P,L=oe;else break e}}return b}function i(O,b){var P=O.sortIndex-b.sortIndex;return P!==0?P:O.id-b.id}if(typeof performance=="object"&&typeof performance.now=="function"){var s=performance;e.unstable_now=function(){return s.now()}}else{var o=Date,l=o.now();e.unstable_now=function(){return o.now()-l}}var a=[],u=[],d=1,f=null,p=3,w=!1,h=!1,v=!1,k=typeof setTimeout=="function"?setTimeout:null,g=typeof clearTimeout=="function"?clearTimeout:null,m=typeof setImmediate<"u"?setImmediate:null;typeof navigator<"u"&&navigator.scheduling!==void 0&&navigator.scheduling.isInputPending!==void 0&&navigator.scheduling.isInputPending.bind(navigator.scheduling);function y(O){for(var b=n(u);b!==null;){if(b.callback===null)r(u);else if(b.startTime<=O)r(u),b.sortIndex=b.expirationTime,t(a,b);else break;b=n(u)}}function C(O){if(v=!1,y(O),!h)if(n(a)!==null)h=!0,Q(j);else{var b=n(u);b!==null&&se(C,b.startTime-O)}}function j(O,b){h=!1,v&&(v=!1,g(_),_=-1),w=!0;var P=p;try{for(y(b),f=n(a);f!==null&&(!(f.expirationTime>b)||O&&!q());){var L=f.callback;if(typeof L=="function"){f.callback=null,p=f.priorityLevel;var $=L(f.expirationTime<=b);b=e.unstable_now(),typeof $=="function"?f.callback=$:f===n(a)&&r(a),y(b)}else r(a);f=n(a)}if(f!==null)var H=!0;else{var G=n(u);G!==null&&se(C,G.startTime-b),H=!1}return H}finally{f=null,p=P,w=!1}}var S=!1,N=null,_=-1,D=5,M=-1;function q(){return!(e.unstable_now()-MO||125L?(O.sortIndex=P,t(u,O),n(a)===null&&O===n(u)&&(v?(g(_),_=-1):v=!0,se(C,P-L))):(O.sortIndex=$,t(a,O),h||w||(h=!0,Q(j))),O},e.unstable_shouldYield=q,e.unstable_wrapCallback=function(O){var b=p;return function(){var P=p;p=b;try{return O.apply(this,arguments)}finally{p=P}}}})(uh);ah.exports=uh;var My=ah.exports;/** + * @license React + * react-dom.production.min.js + * + * Copyright (c) Facebook, Inc. and its affiliates. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + */var Dy=x,_t=My;function I(e){for(var t="https://reactjs.org/docs/error-decoder.html?invariant="+e,n=1;n"u"||typeof window.document>"u"||typeof window.document.createElement>"u"),$a=Object.prototype.hasOwnProperty,Ay=/^[: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]*$/,Id={},Md={};function $y(e){return $a.call(Md,e)?!0:$a.call(Id,e)?!1:Ay.test(e)?Md[e]=!0:(Id[e]=!0,!1)}function zy(e,t,n,r){if(n!==null&&n.type===0)return!1;switch(typeof t){case"function":case"symbol":return!0;case"boolean":return r?!1:n!==null?!n.acceptsBooleans:(e=e.toLowerCase().slice(0,5),e!=="data-"&&e!=="aria-");default:return!1}}function Fy(e,t,n,r){if(t===null||typeof t>"u"||zy(e,t,n,r))return!0;if(r)return!1;if(n!==null)switch(n.type){case 3:return!t;case 4:return t===!1;case 5:return isNaN(t);case 6:return isNaN(t)||1>t}return!1}function ht(e,t,n,r,i,s,o){this.acceptsBooleans=t===2||t===3||t===4,this.attributeName=r,this.attributeNamespace=i,this.mustUseProperty=n,this.propertyName=e,this.type=t,this.sanitizeURL=s,this.removeEmptyString=o}var Ze={};"children dangerouslySetInnerHTML defaultValue defaultChecked innerHTML suppressContentEditableWarning suppressHydrationWarning style".split(" ").forEach(function(e){Ze[e]=new ht(e,0,!1,e,null,!1,!1)});[["acceptCharset","accept-charset"],["className","class"],["htmlFor","for"],["httpEquiv","http-equiv"]].forEach(function(e){var t=e[0];Ze[t]=new ht(t,1,!1,e[1],null,!1,!1)});["contentEditable","draggable","spellCheck","value"].forEach(function(e){Ze[e]=new ht(e,2,!1,e.toLowerCase(),null,!1,!1)});["autoReverse","externalResourcesRequired","focusable","preserveAlpha"].forEach(function(e){Ze[e]=new ht(e,2,!1,e,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(e){Ze[e]=new ht(e,3,!1,e.toLowerCase(),null,!1,!1)});["checked","multiple","muted","selected"].forEach(function(e){Ze[e]=new ht(e,3,!0,e,null,!1,!1)});["capture","download"].forEach(function(e){Ze[e]=new ht(e,4,!1,e,null,!1,!1)});["cols","rows","size","span"].forEach(function(e){Ze[e]=new ht(e,6,!1,e,null,!1,!1)});["rowSpan","start"].forEach(function(e){Ze[e]=new ht(e,5,!1,e.toLowerCase(),null,!1,!1)});var lc=/[\-:]([a-z])/g;function ac(e){return e[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-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(e){var t=e.replace(lc,ac);Ze[t]=new ht(t,1,!1,e,null,!1,!1)});"xlink:actuate xlink:arcrole xlink:role xlink:show xlink:title xlink:type".split(" ").forEach(function(e){var t=e.replace(lc,ac);Ze[t]=new ht(t,1,!1,e,"http://www.w3.org/1999/xlink",!1,!1)});["xml:base","xml:lang","xml:space"].forEach(function(e){var t=e.replace(lc,ac);Ze[t]=new ht(t,1,!1,e,"http://www.w3.org/XML/1998/namespace",!1,!1)});["tabIndex","crossOrigin"].forEach(function(e){Ze[e]=new ht(e,1,!1,e.toLowerCase(),null,!1,!1)});Ze.xlinkHref=new ht("xlinkHref",1,!1,"xlink:href","http://www.w3.org/1999/xlink",!0,!1);["src","href","action","formAction"].forEach(function(e){Ze[e]=new ht(e,1,!1,e.toLowerCase(),null,!0,!0)});function uc(e,t,n,r){var i=Ze.hasOwnProperty(t)?Ze[t]:null;(i!==null?i.type!==0:r||!(2l||i[o]!==s[l]){var a=` +`+i[o].replace(" at new "," at ");return e.displayName&&a.includes("")&&(a=a.replace("",e.displayName)),a}while(1<=o&&0<=l);break}}}finally{Zl=!1,Error.prepareStackTrace=n}return(e=e?e.displayName||e.name:"")?Mi(e):""}function Uy(e){switch(e.tag){case 5:return Mi(e.type);case 16:return Mi("Lazy");case 13:return Mi("Suspense");case 19:return Mi("SuspenseList");case 0:case 2:case 15:return e=ea(e.type,!1),e;case 11:return e=ea(e.type.render,!1),e;case 1:return e=ea(e.type,!0),e;default:return""}}function Ba(e){if(e==null)return null;if(typeof e=="function")return e.displayName||e.name||null;if(typeof e=="string")return e;switch(e){case Or:return"Fragment";case Rr:return"Portal";case za:return"Profiler";case cc:return"StrictMode";case Fa:return"Suspense";case Ua:return"SuspenseList"}if(typeof e=="object")switch(e.$$typeof){case fh:return(e.displayName||"Context")+".Consumer";case dh:return(e._context.displayName||"Context")+".Provider";case dc:var t=e.render;return e=e.displayName,e||(e=t.displayName||t.name||"",e=e!==""?"ForwardRef("+e+")":"ForwardRef"),e;case fc:return t=e.displayName||null,t!==null?t:Ba(e.type)||"Memo";case Nn:t=e._payload,e=e._init;try{return Ba(e(t))}catch{}}return null}function By(e){var t=e.type;switch(e.tag){case 24:return"Cache";case 9:return(t.displayName||"Context")+".Consumer";case 10:return(t._context.displayName||"Context")+".Provider";case 18:return"DehydratedFragment";case 11:return e=t.render,e=e.displayName||e.name||"",t.displayName||(e!==""?"ForwardRef("+e+")":"ForwardRef");case 7:return"Fragment";case 5:return t;case 4:return"Portal";case 3:return"Root";case 6:return"Text";case 16:return Ba(t);case 8:return t===cc?"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 t=="function")return t.displayName||t.name||null;if(typeof t=="string")return t}return null}function Bn(e){switch(typeof e){case"boolean":case"number":case"string":case"undefined":return e;case"object":return e;default:return""}}function hh(e){var t=e.type;return(e=e.nodeName)&&e.toLowerCase()==="input"&&(t==="checkbox"||t==="radio")}function Wy(e){var t=hh(e)?"checked":"value",n=Object.getOwnPropertyDescriptor(e.constructor.prototype,t),r=""+e[t];if(!e.hasOwnProperty(t)&&typeof n<"u"&&typeof n.get=="function"&&typeof n.set=="function"){var i=n.get,s=n.set;return Object.defineProperty(e,t,{configurable:!0,get:function(){return i.call(this)},set:function(o){r=""+o,s.call(this,o)}}),Object.defineProperty(e,t,{enumerable:n.enumerable}),{getValue:function(){return r},setValue:function(o){r=""+o},stopTracking:function(){e._valueTracker=null,delete e[t]}}}}function Fs(e){e._valueTracker||(e._valueTracker=Wy(e))}function mh(e){if(!e)return!1;var t=e._valueTracker;if(!t)return!0;var n=t.getValue(),r="";return e&&(r=hh(e)?e.checked?"true":"false":e.value),e=r,e!==n?(t.setValue(e),!0):!1}function To(e){if(e=e||(typeof document<"u"?document:void 0),typeof e>"u")return null;try{return e.activeElement||e.body}catch{return e.body}}function Wa(e,t){var n=t.checked;return je({},t,{defaultChecked:void 0,defaultValue:void 0,value:void 0,checked:n??e._wrapperState.initialChecked})}function Ad(e,t){var n=t.defaultValue==null?"":t.defaultValue,r=t.checked!=null?t.checked:t.defaultChecked;n=Bn(t.value!=null?t.value:n),e._wrapperState={initialChecked:r,initialValue:n,controlled:t.type==="checkbox"||t.type==="radio"?t.checked!=null:t.value!=null}}function gh(e,t){t=t.checked,t!=null&&uc(e,"checked",t,!1)}function Ha(e,t){gh(e,t);var n=Bn(t.value),r=t.type;if(n!=null)r==="number"?(n===0&&e.value===""||e.value!=n)&&(e.value=""+n):e.value!==""+n&&(e.value=""+n);else if(r==="submit"||r==="reset"){e.removeAttribute("value");return}t.hasOwnProperty("value")?Va(e,t.type,n):t.hasOwnProperty("defaultValue")&&Va(e,t.type,Bn(t.defaultValue)),t.checked==null&&t.defaultChecked!=null&&(e.defaultChecked=!!t.defaultChecked)}function $d(e,t,n){if(t.hasOwnProperty("value")||t.hasOwnProperty("defaultValue")){var r=t.type;if(!(r!=="submit"&&r!=="reset"||t.value!==void 0&&t.value!==null))return;t=""+e._wrapperState.initialValue,n||t===e.value||(e.value=t),e.defaultValue=t}n=e.name,n!==""&&(e.name=""),e.defaultChecked=!!e._wrapperState.initialChecked,n!==""&&(e.name=n)}function Va(e,t,n){(t!=="number"||To(e.ownerDocument)!==e)&&(n==null?e.defaultValue=""+e._wrapperState.initialValue:e.defaultValue!==""+n&&(e.defaultValue=""+n))}var Di=Array.isArray;function Wr(e,t,n,r){if(e=e.options,t){t={};for(var i=0;i"+t.valueOf().toString()+"",t=Us.firstChild;e.firstChild;)e.removeChild(e.firstChild);for(;t.firstChild;)e.appendChild(t.firstChild)}});function ts(e,t){if(t){var n=e.firstChild;if(n&&n===e.lastChild&&n.nodeType===3){n.nodeValue=t;return}}e.textContent=t}var Bi={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},Hy=["Webkit","ms","Moz","O"];Object.keys(Bi).forEach(function(e){Hy.forEach(function(t){t=t+e.charAt(0).toUpperCase()+e.substring(1),Bi[t]=Bi[e]})});function xh(e,t,n){return t==null||typeof t=="boolean"||t===""?"":n||typeof t!="number"||t===0||Bi.hasOwnProperty(e)&&Bi[e]?(""+t).trim():t+"px"}function kh(e,t){e=e.style;for(var n in t)if(t.hasOwnProperty(n)){var r=n.indexOf("--")===0,i=xh(n,t[n],r);n==="float"&&(n="cssFloat"),r?e.setProperty(n,i):e[n]=i}}var Vy=je({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 Ga(e,t){if(t){if(Vy[e]&&(t.children!=null||t.dangerouslySetInnerHTML!=null))throw Error(I(137,e));if(t.dangerouslySetInnerHTML!=null){if(t.children!=null)throw Error(I(60));if(typeof t.dangerouslySetInnerHTML!="object"||!("__html"in t.dangerouslySetInnerHTML))throw Error(I(61))}if(t.style!=null&&typeof t.style!="object")throw Error(I(62))}}function Ya(e,t){if(e.indexOf("-")===-1)return typeof t.is=="string";switch(e){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 Ka=null;function pc(e){return e=e.target||e.srcElement||window,e.correspondingUseElement&&(e=e.correspondingUseElement),e.nodeType===3?e.parentNode:e}var Xa=null,Hr=null,Vr=null;function Ud(e){if(e=js(e)){if(typeof Xa!="function")throw Error(I(280));var t=e.stateNode;t&&(t=vl(t),Xa(e.stateNode,e.type,t))}}function Sh(e){Hr?Vr?Vr.push(e):Vr=[e]:Hr=e}function Eh(){if(Hr){var e=Hr,t=Vr;if(Vr=Hr=null,Ud(e),t)for(e=0;e>>=0,e===0?32:31-(nw(e)/rw|0)|0}var Bs=64,Ws=4194304;function Ai(e){switch(e&-e){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 e&4194240;case 4194304:case 8388608:case 16777216:case 33554432:case 67108864:return e&130023424;case 134217728:return 134217728;case 268435456:return 268435456;case 536870912:return 536870912;case 1073741824:return 1073741824;default:return e}}function Ro(e,t){var n=e.pendingLanes;if(n===0)return 0;var r=0,i=e.suspendedLanes,s=e.pingedLanes,o=n&268435455;if(o!==0){var l=o&~i;l!==0?r=Ai(l):(s&=o,s!==0&&(r=Ai(s)))}else o=n&~i,o!==0?r=Ai(o):s!==0&&(r=Ai(s));if(r===0)return 0;if(t!==0&&t!==r&&!(t&i)&&(i=r&-r,s=t&-t,i>=s||i===16&&(s&4194240)!==0))return t;if(r&4&&(r|=n&16),t=e.entangledLanes,t!==0)for(e=e.entanglements,t&=r;0n;n++)t.push(e);return t}function Ns(e,t,n){e.pendingLanes|=t,t!==536870912&&(e.suspendedLanes=0,e.pingedLanes=0),e=e.eventTimes,t=31-Kt(t),e[t]=n}function lw(e,t){var n=e.pendingLanes&~t;e.pendingLanes=t,e.suspendedLanes=0,e.pingedLanes=0,e.expiredLanes&=t,e.mutableReadLanes&=t,e.entangledLanes&=t,t=e.entanglements;var r=e.eventTimes;for(e=e.expirationTimes;0=Hi),Kd=" ",Xd=!1;function Wh(e,t){switch(e){case"keyup":return Mw.indexOf(t.keyCode)!==-1;case"keydown":return t.keyCode!==229;case"keypress":case"mousedown":case"focusout":return!0;default:return!1}}function Hh(e){return e=e.detail,typeof e=="object"&&"data"in e?e.data:null}var Lr=!1;function Aw(e,t){switch(e){case"compositionend":return Hh(t);case"keypress":return t.which!==32?null:(Xd=!0,Kd);case"textInput":return e=t.data,e===Kd&&Xd?null:e;default:return null}}function $w(e,t){if(Lr)return e==="compositionend"||!kc&&Wh(e,t)?(e=Uh(),po=yc=Pn=null,Lr=!1,e):null;switch(e){case"paste":return null;case"keypress":if(!(t.ctrlKey||t.altKey||t.metaKey)||t.ctrlKey&&t.altKey){if(t.char&&1=t)return{node:n,offset:t-e};e=r}e:{for(;n;){if(n.nextSibling){n=n.nextSibling;break e}n=n.parentNode}n=void 0}n=tf(n)}}function Gh(e,t){return e&&t?e===t?!0:e&&e.nodeType===3?!1:t&&t.nodeType===3?Gh(e,t.parentNode):"contains"in e?e.contains(t):e.compareDocumentPosition?!!(e.compareDocumentPosition(t)&16):!1:!1}function Yh(){for(var e=window,t=To();t instanceof e.HTMLIFrameElement;){try{var n=typeof t.contentWindow.location.href=="string"}catch{n=!1}if(n)e=t.contentWindow;else break;t=To(e.document)}return t}function Sc(e){var t=e&&e.nodeName&&e.nodeName.toLowerCase();return t&&(t==="input"&&(e.type==="text"||e.type==="search"||e.type==="tel"||e.type==="url"||e.type==="password")||t==="textarea"||e.contentEditable==="true")}function qw(e){var t=Yh(),n=e.focusedElem,r=e.selectionRange;if(t!==n&&n&&n.ownerDocument&&Gh(n.ownerDocument.documentElement,n)){if(r!==null&&Sc(n)){if(t=r.start,e=r.end,e===void 0&&(e=t),"selectionStart"in n)n.selectionStart=t,n.selectionEnd=Math.min(e,n.value.length);else if(e=(t=n.ownerDocument||document)&&t.defaultView||window,e.getSelection){e=e.getSelection();var i=n.textContent.length,s=Math.min(r.start,i);r=r.end===void 0?s:Math.min(r.end,i),!e.extend&&s>r&&(i=r,r=s,s=i),i=nf(n,s);var o=nf(n,r);i&&o&&(e.rangeCount!==1||e.anchorNode!==i.node||e.anchorOffset!==i.offset||e.focusNode!==o.node||e.focusOffset!==o.offset)&&(t=t.createRange(),t.setStart(i.node,i.offset),e.removeAllRanges(),s>r?(e.addRange(t),e.extend(o.node,o.offset)):(t.setEnd(o.node,o.offset),e.addRange(t)))}}for(t=[],e=n;e=e.parentNode;)e.nodeType===1&&t.push({element:e,left:e.scrollLeft,top:e.scrollTop});for(typeof n.focus=="function"&&n.focus(),n=0;n=document.documentMode,Ir=null,ru=null,Qi=null,iu=!1;function rf(e,t,n){var r=n.window===n?n.document:n.nodeType===9?n:n.ownerDocument;iu||Ir==null||Ir!==To(r)||(r=Ir,"selectionStart"in r&&Sc(r)?r={start:r.selectionStart,end:r.selectionEnd}:(r=(r.ownerDocument&&r.ownerDocument.defaultView||window).getSelection(),r={anchorNode:r.anchorNode,anchorOffset:r.anchorOffset,focusNode:r.focusNode,focusOffset:r.focusOffset}),Qi&&ls(Qi,r)||(Qi=r,r=Io(ru,"onSelect"),0Ar||(e.current=cu[Ar],cu[Ar]=null,Ar--)}function ke(e,t){Ar++,cu[Ar]=e.current,e.current=t}var Wn={},st=Qn(Wn),yt=Qn(!1),hr=Wn;function Xr(e,t){var n=e.type.contextTypes;if(!n)return Wn;var r=e.stateNode;if(r&&r.__reactInternalMemoizedUnmaskedChildContext===t)return r.__reactInternalMemoizedMaskedChildContext;var i={},s;for(s in n)i[s]=t[s];return r&&(e=e.stateNode,e.__reactInternalMemoizedUnmaskedChildContext=t,e.__reactInternalMemoizedMaskedChildContext=i),i}function wt(e){return e=e.childContextTypes,e!=null}function Do(){Ee(yt),Ee(st)}function df(e,t,n){if(st.current!==Wn)throw Error(I(168));ke(st,t),ke(yt,n)}function im(e,t,n){var r=e.stateNode;if(t=t.childContextTypes,typeof r.getChildContext!="function")return n;r=r.getChildContext();for(var i in r)if(!(i in t))throw Error(I(108,By(e)||"Unknown",i));return je({},n,r)}function Ao(e){return e=(e=e.stateNode)&&e.__reactInternalMemoizedMergedChildContext||Wn,hr=st.current,ke(st,e),ke(yt,yt.current),!0}function ff(e,t,n){var r=e.stateNode;if(!r)throw Error(I(169));n?(e=im(e,t,hr),r.__reactInternalMemoizedMergedChildContext=e,Ee(yt),Ee(st),ke(st,e)):Ee(yt),ke(yt,n)}var pn=null,yl=!1,ha=!1;function sm(e){pn===null?pn=[e]:pn.push(e)}function s0(e){yl=!0,sm(e)}function qn(){if(!ha&&pn!==null){ha=!0;var e=0,t=me;try{var n=pn;for(me=1;e>=o,i-=o,hn=1<<32-Kt(t)+i|n<_?(D=N,N=null):D=N.sibling;var M=p(g,N,y[_],C);if(M===null){N===null&&(N=D);break}e&&N&&M.alternate===null&&t(g,N),m=s(M,m,_),S===null?j=M:S.sibling=M,S=M,N=D}if(_===y.length)return n(g,N),be&&tr(g,_),j;if(N===null){for(;__?(D=N,N=null):D=N.sibling;var q=p(g,N,M.value,C);if(q===null){N===null&&(N=D);break}e&&N&&q.alternate===null&&t(g,N),m=s(q,m,_),S===null?j=q:S.sibling=q,S=q,N=D}if(M.done)return n(g,N),be&&tr(g,_),j;if(N===null){for(;!M.done;_++,M=y.next())M=f(g,M.value,C),M!==null&&(m=s(M,m,_),S===null?j=M:S.sibling=M,S=M);return be&&tr(g,_),j}for(N=r(g,N);!M.done;_++,M=y.next())M=w(N,g,_,M.value,C),M!==null&&(e&&M.alternate!==null&&N.delete(M.key===null?_:M.key),m=s(M,m,_),S===null?j=M:S.sibling=M,S=M);return e&&N.forEach(function(X){return t(g,X)}),be&&tr(g,_),j}function k(g,m,y,C){if(typeof y=="object"&&y!==null&&y.type===Or&&y.key===null&&(y=y.props.children),typeof y=="object"&&y!==null){switch(y.$$typeof){case zs:e:{for(var j=y.key,S=m;S!==null;){if(S.key===j){if(j=y.type,j===Or){if(S.tag===7){n(g,S.sibling),m=i(S,y.props.children),m.return=g,g=m;break e}}else if(S.elementType===j||typeof j=="object"&&j!==null&&j.$$typeof===Nn&&mf(j)===S.type){n(g,S.sibling),m=i(S,y.props),m.ref=Ni(g,S,y),m.return=g,g=m;break e}n(g,S);break}else t(g,S);S=S.sibling}y.type===Or?(m=dr(y.props.children,g.mode,C,y.key),m.return=g,g=m):(C=ko(y.type,y.key,y.props,null,g.mode,C),C.ref=Ni(g,m,y),C.return=g,g=C)}return o(g);case Rr:e:{for(S=y.key;m!==null;){if(m.key===S)if(m.tag===4&&m.stateNode.containerInfo===y.containerInfo&&m.stateNode.implementation===y.implementation){n(g,m.sibling),m=i(m,y.children||[]),m.return=g,g=m;break e}else{n(g,m);break}else t(g,m);m=m.sibling}m=Sa(y,g.mode,C),m.return=g,g=m}return o(g);case Nn:return S=y._init,k(g,m,S(y._payload),C)}if(Di(y))return h(g,m,y,C);if(ki(y))return v(g,m,y,C);Ks(g,y)}return typeof y=="string"&&y!==""||typeof y=="number"?(y=""+y,m!==null&&m.tag===6?(n(g,m.sibling),m=i(m,y),m.return=g,g=m):(n(g,m),m=ka(y,g.mode,C),m.return=g,g=m),o(g)):n(g,m)}return k}var Zr=um(!0),cm=um(!1),Fo=Qn(null),Uo=null,Fr=null,Nc=null;function Tc(){Nc=Fr=Uo=null}function jc(e){var t=Fo.current;Ee(Fo),e._currentValue=t}function pu(e,t,n){for(;e!==null;){var r=e.alternate;if((e.childLanes&t)!==t?(e.childLanes|=t,r!==null&&(r.childLanes|=t)):r!==null&&(r.childLanes&t)!==t&&(r.childLanes|=t),e===n)break;e=e.return}}function qr(e,t){Uo=e,Nc=Fr=null,e=e.dependencies,e!==null&&e.firstContext!==null&&(e.lanes&t&&(vt=!0),e.firstContext=null)}function zt(e){var t=e._currentValue;if(Nc!==e)if(e={context:e,memoizedValue:t,next:null},Fr===null){if(Uo===null)throw Error(I(308));Fr=e,Uo.dependencies={lanes:0,firstContext:e}}else Fr=Fr.next=e;return t}var lr=null;function _c(e){lr===null?lr=[e]:lr.push(e)}function dm(e,t,n,r){var i=t.interleaved;return i===null?(n.next=n,_c(t)):(n.next=i.next,i.next=n),t.interleaved=n,xn(e,r)}function xn(e,t){e.lanes|=t;var n=e.alternate;for(n!==null&&(n.lanes|=t),n=e,e=e.return;e!==null;)e.childLanes|=t,n=e.alternate,n!==null&&(n.childLanes|=t),n=e,e=e.return;return n.tag===3?n.stateNode:null}var Tn=!1;function Pc(e){e.updateQueue={baseState:e.memoizedState,firstBaseUpdate:null,lastBaseUpdate:null,shared:{pending:null,interleaved:null,lanes:0},effects:null}}function fm(e,t){e=e.updateQueue,t.updateQueue===e&&(t.updateQueue={baseState:e.baseState,firstBaseUpdate:e.firstBaseUpdate,lastBaseUpdate:e.lastBaseUpdate,shared:e.shared,effects:e.effects})}function gn(e,t){return{eventTime:e,lane:t,tag:0,payload:null,callback:null,next:null}}function An(e,t,n){var r=e.updateQueue;if(r===null)return null;if(r=r.shared,ae&2){var i=r.pending;return i===null?t.next=t:(t.next=i.next,i.next=t),r.pending=t,xn(e,n)}return i=r.interleaved,i===null?(t.next=t,_c(r)):(t.next=i.next,i.next=t),r.interleaved=t,xn(e,n)}function mo(e,t,n){if(t=t.updateQueue,t!==null&&(t=t.shared,(n&4194240)!==0)){var r=t.lanes;r&=e.pendingLanes,n|=r,t.lanes=n,mc(e,n)}}function gf(e,t){var n=e.updateQueue,r=e.alternate;if(r!==null&&(r=r.updateQueue,n===r)){var i=null,s=null;if(n=n.firstBaseUpdate,n!==null){do{var o={eventTime:n.eventTime,lane:n.lane,tag:n.tag,payload:n.payload,callback:n.callback,next:null};s===null?i=s=o:s=s.next=o,n=n.next}while(n!==null);s===null?i=s=t:s=s.next=t}else i=s=t;n={baseState:r.baseState,firstBaseUpdate:i,lastBaseUpdate:s,shared:r.shared,effects:r.effects},e.updateQueue=n;return}e=n.lastBaseUpdate,e===null?n.firstBaseUpdate=t:e.next=t,n.lastBaseUpdate=t}function Bo(e,t,n,r){var i=e.updateQueue;Tn=!1;var s=i.firstBaseUpdate,o=i.lastBaseUpdate,l=i.shared.pending;if(l!==null){i.shared.pending=null;var a=l,u=a.next;a.next=null,o===null?s=u:o.next=u,o=a;var d=e.alternate;d!==null&&(d=d.updateQueue,l=d.lastBaseUpdate,l!==o&&(l===null?d.firstBaseUpdate=u:l.next=u,d.lastBaseUpdate=a))}if(s!==null){var f=i.baseState;o=0,d=u=a=null,l=s;do{var p=l.lane,w=l.eventTime;if((r&p)===p){d!==null&&(d=d.next={eventTime:w,lane:0,tag:l.tag,payload:l.payload,callback:l.callback,next:null});e:{var h=e,v=l;switch(p=t,w=n,v.tag){case 1:if(h=v.payload,typeof h=="function"){f=h.call(w,f,p);break e}f=h;break e;case 3:h.flags=h.flags&-65537|128;case 0:if(h=v.payload,p=typeof h=="function"?h.call(w,f,p):h,p==null)break e;f=je({},f,p);break e;case 2:Tn=!0}}l.callback!==null&&l.lane!==0&&(e.flags|=64,p=i.effects,p===null?i.effects=[l]:p.push(l))}else w={eventTime:w,lane:p,tag:l.tag,payload:l.payload,callback:l.callback,next:null},d===null?(u=d=w,a=f):d=d.next=w,o|=p;if(l=l.next,l===null){if(l=i.shared.pending,l===null)break;p=l,l=p.next,p.next=null,i.lastBaseUpdate=p,i.shared.pending=null}}while(!0);if(d===null&&(a=f),i.baseState=a,i.firstBaseUpdate=u,i.lastBaseUpdate=d,t=i.shared.interleaved,t!==null){i=t;do o|=i.lane,i=i.next;while(i!==t)}else s===null&&(i.shared.lanes=0);vr|=o,e.lanes=o,e.memoizedState=f}}function vf(e,t,n){if(e=t.effects,t.effects=null,e!==null)for(t=0;tn?n:4,e(!0);var r=ga.transition;ga.transition={};try{e(!1),t()}finally{me=n,ga.transition=r}}function _m(){return Ft().memoizedState}function u0(e,t,n){var r=zn(e);if(n={lane:r,action:n,hasEagerState:!1,eagerState:null,next:null},Pm(e))Rm(t,n);else if(n=dm(e,t,n,r),n!==null){var i=ft();Xt(n,e,r,i),Om(n,t,r)}}function c0(e,t,n){var r=zn(e),i={lane:r,action:n,hasEagerState:!1,eagerState:null,next:null};if(Pm(e))Rm(t,i);else{var s=e.alternate;if(e.lanes===0&&(s===null||s.lanes===0)&&(s=t.lastRenderedReducer,s!==null))try{var o=t.lastRenderedState,l=s(o,n);if(i.hasEagerState=!0,i.eagerState=l,Zt(l,o)){var a=t.interleaved;a===null?(i.next=i,_c(t)):(i.next=a.next,a.next=i),t.interleaved=i;return}}catch{}finally{}n=dm(e,t,i,r),n!==null&&(i=ft(),Xt(n,e,r,i),Om(n,t,r))}}function Pm(e){var t=e.alternate;return e===Te||t!==null&&t===Te}function Rm(e,t){qi=Ho=!0;var n=e.pending;n===null?t.next=t:(t.next=n.next,n.next=t),e.pending=t}function Om(e,t,n){if(n&4194240){var r=t.lanes;r&=e.pendingLanes,n|=r,t.lanes=n,mc(e,n)}}var Vo={readContext:zt,useCallback:tt,useContext:tt,useEffect:tt,useImperativeHandle:tt,useInsertionEffect:tt,useLayoutEffect:tt,useMemo:tt,useReducer:tt,useRef:tt,useState:tt,useDebugValue:tt,useDeferredValue:tt,useTransition:tt,useMutableSource:tt,useSyncExternalStore:tt,useId:tt,unstable_isNewReconciler:!1},d0={readContext:zt,useCallback:function(e,t){return sn().memoizedState=[e,t===void 0?null:t],e},useContext:zt,useEffect:wf,useImperativeHandle:function(e,t,n){return n=n!=null?n.concat([e]):null,vo(4194308,4,Cm.bind(null,t,e),n)},useLayoutEffect:function(e,t){return vo(4194308,4,e,t)},useInsertionEffect:function(e,t){return vo(4,2,e,t)},useMemo:function(e,t){var n=sn();return t=t===void 0?null:t,e=e(),n.memoizedState=[e,t],e},useReducer:function(e,t,n){var r=sn();return t=n!==void 0?n(t):t,r.memoizedState=r.baseState=t,e={pending:null,interleaved:null,lanes:0,dispatch:null,lastRenderedReducer:e,lastRenderedState:t},r.queue=e,e=e.dispatch=u0.bind(null,Te,e),[r.memoizedState,e]},useRef:function(e){var t=sn();return e={current:e},t.memoizedState=e},useState:yf,useDebugValue:$c,useDeferredValue:function(e){return sn().memoizedState=e},useTransition:function(){var e=yf(!1),t=e[0];return e=a0.bind(null,e[1]),sn().memoizedState=e,[t,e]},useMutableSource:function(){},useSyncExternalStore:function(e,t,n){var r=Te,i=sn();if(be){if(n===void 0)throw Error(I(407));n=n()}else{if(n=t(),Ye===null)throw Error(I(349));gr&30||gm(r,t,n)}i.memoizedState=n;var s={value:n,getSnapshot:t};return i.queue=s,wf(ym.bind(null,r,s,e),[e]),r.flags|=2048,ms(9,vm.bind(null,r,s,n,t),void 0,null),n},useId:function(){var e=sn(),t=Ye.identifierPrefix;if(be){var n=mn,r=hn;n=(r&~(1<<32-Kt(r)-1)).toString(32)+n,t=":"+t+"R"+n,n=ps++,0<\/script>",e=e.removeChild(e.firstChild)):typeof r.is=="string"?e=o.createElement(n,{is:r.is}):(e=o.createElement(n),n==="select"&&(o=e,r.multiple?o.multiple=!0:r.size&&(o.size=r.size))):e=o.createElementNS(e,n),e[on]=t,e[cs]=r,Bm(e,t,!1,!1),t.stateNode=e;e:{switch(o=Ya(n,r),n){case"dialog":Se("cancel",e),Se("close",e),i=r;break;case"iframe":case"object":case"embed":Se("load",e),i=r;break;case"video":case"audio":for(i=0;i<$i.length;i++)Se($i[i],e);i=r;break;case"source":Se("error",e),i=r;break;case"img":case"image":case"link":Se("error",e),Se("load",e),i=r;break;case"details":Se("toggle",e),i=r;break;case"input":Ad(e,r),i=Wa(e,r),Se("invalid",e);break;case"option":i=r;break;case"select":e._wrapperState={wasMultiple:!!r.multiple},i=je({},r,{value:void 0}),Se("invalid",e);break;case"textarea":zd(e,r),i=Qa(e,r),Se("invalid",e);break;default:i=r}Ga(n,i),l=i;for(s in l)if(l.hasOwnProperty(s)){var a=l[s];s==="style"?kh(e,a):s==="dangerouslySetInnerHTML"?(a=a?a.__html:void 0,a!=null&&wh(e,a)):s==="children"?typeof a=="string"?(n!=="textarea"||a!=="")&&ts(e,a):typeof a=="number"&&ts(e,""+a):s!=="suppressContentEditableWarning"&&s!=="suppressHydrationWarning"&&s!=="autoFocus"&&(es.hasOwnProperty(s)?a!=null&&s==="onScroll"&&Se("scroll",e):a!=null&&uc(e,s,a,o))}switch(n){case"input":Fs(e),$d(e,r,!1);break;case"textarea":Fs(e),Fd(e);break;case"option":r.value!=null&&e.setAttribute("value",""+Bn(r.value));break;case"select":e.multiple=!!r.multiple,s=r.value,s!=null?Wr(e,!!r.multiple,s,!1):r.defaultValue!=null&&Wr(e,!!r.multiple,r.defaultValue,!0);break;default:typeof i.onClick=="function"&&(e.onclick=Mo)}switch(n){case"button":case"input":case"select":case"textarea":r=!!r.autoFocus;break e;case"img":r=!0;break e;default:r=!1}}r&&(t.flags|=4)}t.ref!==null&&(t.flags|=512,t.flags|=2097152)}return nt(t),null;case 6:if(e&&t.stateNode!=null)Hm(e,t,e.memoizedProps,r);else{if(typeof r!="string"&&t.stateNode===null)throw Error(I(166));if(n=ar(fs.current),ar(cn.current),Ys(t)){if(r=t.stateNode,n=t.memoizedProps,r[on]=t,(s=r.nodeValue!==n)&&(e=jt,e!==null))switch(e.tag){case 3:Gs(r.nodeValue,n,(e.mode&1)!==0);break;case 5:e.memoizedProps.suppressHydrationWarning!==!0&&Gs(r.nodeValue,n,(e.mode&1)!==0)}s&&(t.flags|=4)}else r=(n.nodeType===9?n:n.ownerDocument).createTextNode(r),r[on]=t,t.stateNode=r}return nt(t),null;case 13:if(Ee(Ne),r=t.memoizedState,e===null||e.memoizedState!==null&&e.memoizedState.dehydrated!==null){if(be&&Tt!==null&&t.mode&1&&!(t.flags&128))am(),Jr(),t.flags|=98560,s=!1;else if(s=Ys(t),r!==null&&r.dehydrated!==null){if(e===null){if(!s)throw Error(I(318));if(s=t.memoizedState,s=s!==null?s.dehydrated:null,!s)throw Error(I(317));s[on]=t}else Jr(),!(t.flags&128)&&(t.memoizedState=null),t.flags|=4;nt(t),s=!1}else Qt!==null&&(_u(Qt),Qt=null),s=!0;if(!s)return t.flags&65536?t:null}return t.flags&128?(t.lanes=n,t):(r=r!==null,r!==(e!==null&&e.memoizedState!==null)&&r&&(t.child.flags|=8192,t.mode&1&&(e===null||Ne.current&1?We===0&&(We=3):Vc())),t.updateQueue!==null&&(t.flags|=4),nt(t),null);case 4:return ei(),ku(e,t),e===null&&as(t.stateNode.containerInfo),nt(t),null;case 10:return jc(t.type._context),nt(t),null;case 17:return wt(t.type)&&Do(),nt(t),null;case 19:if(Ee(Ne),s=t.memoizedState,s===null)return nt(t),null;if(r=(t.flags&128)!==0,o=s.rendering,o===null)if(r)Ti(s,!1);else{if(We!==0||e!==null&&e.flags&128)for(e=t.child;e!==null;){if(o=Wo(e),o!==null){for(t.flags|=128,Ti(s,!1),r=o.updateQueue,r!==null&&(t.updateQueue=r,t.flags|=4),t.subtreeFlags=0,r=n,n=t.child;n!==null;)s=n,e=r,s.flags&=14680066,o=s.alternate,o===null?(s.childLanes=0,s.lanes=e,s.child=null,s.subtreeFlags=0,s.memoizedProps=null,s.memoizedState=null,s.updateQueue=null,s.dependencies=null,s.stateNode=null):(s.childLanes=o.childLanes,s.lanes=o.lanes,s.child=o.child,s.subtreeFlags=0,s.deletions=null,s.memoizedProps=o.memoizedProps,s.memoizedState=o.memoizedState,s.updateQueue=o.updateQueue,s.type=o.type,e=o.dependencies,s.dependencies=e===null?null:{lanes:e.lanes,firstContext:e.firstContext}),n=n.sibling;return ke(Ne,Ne.current&1|2),t.child}e=e.sibling}s.tail!==null&&Le()>ni&&(t.flags|=128,r=!0,Ti(s,!1),t.lanes=4194304)}else{if(!r)if(e=Wo(o),e!==null){if(t.flags|=128,r=!0,n=e.updateQueue,n!==null&&(t.updateQueue=n,t.flags|=4),Ti(s,!0),s.tail===null&&s.tailMode==="hidden"&&!o.alternate&&!be)return nt(t),null}else 2*Le()-s.renderingStartTime>ni&&n!==1073741824&&(t.flags|=128,r=!0,Ti(s,!1),t.lanes=4194304);s.isBackwards?(o.sibling=t.child,t.child=o):(n=s.last,n!==null?n.sibling=o:t.child=o,s.last=o)}return s.tail!==null?(t=s.tail,s.rendering=t,s.tail=t.sibling,s.renderingStartTime=Le(),t.sibling=null,n=Ne.current,ke(Ne,r?n&1|2:n&1),t):(nt(t),null);case 22:case 23:return Hc(),r=t.memoizedState!==null,e!==null&&e.memoizedState!==null!==r&&(t.flags|=8192),r&&t.mode&1?Nt&1073741824&&(nt(t),t.subtreeFlags&6&&(t.flags|=8192)):nt(t),null;case 24:return null;case 25:return null}throw Error(I(156,t.tag))}function w0(e,t){switch(Cc(t),t.tag){case 1:return wt(t.type)&&Do(),e=t.flags,e&65536?(t.flags=e&-65537|128,t):null;case 3:return ei(),Ee(yt),Ee(st),Lc(),e=t.flags,e&65536&&!(e&128)?(t.flags=e&-65537|128,t):null;case 5:return Oc(t),null;case 13:if(Ee(Ne),e=t.memoizedState,e!==null&&e.dehydrated!==null){if(t.alternate===null)throw Error(I(340));Jr()}return e=t.flags,e&65536?(t.flags=e&-65537|128,t):null;case 19:return Ee(Ne),null;case 4:return ei(),null;case 10:return jc(t.type._context),null;case 22:case 23:return Hc(),null;case 24:return null;default:return null}}var Js=!1,rt=!1,x0=typeof WeakSet=="function"?WeakSet:Set,B=null;function Ur(e,t){var n=e.ref;if(n!==null)if(typeof n=="function")try{n(null)}catch(r){Re(e,t,r)}else n.current=null}function Su(e,t,n){try{n()}catch(r){Re(e,t,r)}}var Pf=!1;function k0(e,t){if(su=Oo,e=Yh(),Sc(e)){if("selectionStart"in e)var n={start:e.selectionStart,end:e.selectionEnd};else e:{n=(n=e.ownerDocument)&&n.defaultView||window;var r=n.getSelection&&n.getSelection();if(r&&r.rangeCount!==0){n=r.anchorNode;var i=r.anchorOffset,s=r.focusNode;r=r.focusOffset;try{n.nodeType,s.nodeType}catch{n=null;break e}var o=0,l=-1,a=-1,u=0,d=0,f=e,p=null;t:for(;;){for(var w;f!==n||i!==0&&f.nodeType!==3||(l=o+i),f!==s||r!==0&&f.nodeType!==3||(a=o+r),f.nodeType===3&&(o+=f.nodeValue.length),(w=f.firstChild)!==null;)p=f,f=w;for(;;){if(f===e)break t;if(p===n&&++u===i&&(l=o),p===s&&++d===r&&(a=o),(w=f.nextSibling)!==null)break;f=p,p=f.parentNode}f=w}n=l===-1||a===-1?null:{start:l,end:a}}else n=null}n=n||{start:0,end:0}}else n=null;for(ou={focusedElem:e,selectionRange:n},Oo=!1,B=t;B!==null;)if(t=B,e=t.child,(t.subtreeFlags&1028)!==0&&e!==null)e.return=t,B=e;else for(;B!==null;){t=B;try{var h=t.alternate;if(t.flags&1024)switch(t.tag){case 0:case 11:case 15:break;case 1:if(h!==null){var v=h.memoizedProps,k=h.memoizedState,g=t.stateNode,m=g.getSnapshotBeforeUpdate(t.elementType===t.type?v:Ht(t.type,v),k);g.__reactInternalSnapshotBeforeUpdate=m}break;case 3:var y=t.stateNode.containerInfo;y.nodeType===1?y.textContent="":y.nodeType===9&&y.documentElement&&y.removeChild(y.documentElement);break;case 5:case 6:case 4:case 17:break;default:throw Error(I(163))}}catch(C){Re(t,t.return,C)}if(e=t.sibling,e!==null){e.return=t.return,B=e;break}B=t.return}return h=Pf,Pf=!1,h}function Gi(e,t,n){var r=t.updateQueue;if(r=r!==null?r.lastEffect:null,r!==null){var i=r=r.next;do{if((i.tag&e)===e){var s=i.destroy;i.destroy=void 0,s!==void 0&&Su(t,n,s)}i=i.next}while(i!==r)}}function kl(e,t){if(t=t.updateQueue,t=t!==null?t.lastEffect:null,t!==null){var n=t=t.next;do{if((n.tag&e)===e){var r=n.create;n.destroy=r()}n=n.next}while(n!==t)}}function Eu(e){var t=e.ref;if(t!==null){var n=e.stateNode;switch(e.tag){case 5:e=n;break;default:e=n}typeof t=="function"?t(e):t.current=e}}function Vm(e){var t=e.alternate;t!==null&&(e.alternate=null,Vm(t)),e.child=null,e.deletions=null,e.sibling=null,e.tag===5&&(t=e.stateNode,t!==null&&(delete t[on],delete t[cs],delete t[uu],delete t[r0],delete t[i0])),e.stateNode=null,e.return=null,e.dependencies=null,e.memoizedProps=null,e.memoizedState=null,e.pendingProps=null,e.stateNode=null,e.updateQueue=null}function Qm(e){return e.tag===5||e.tag===3||e.tag===4}function Rf(e){e:for(;;){for(;e.sibling===null;){if(e.return===null||Qm(e.return))return null;e=e.return}for(e.sibling.return=e.return,e=e.sibling;e.tag!==5&&e.tag!==6&&e.tag!==18;){if(e.flags&2||e.child===null||e.tag===4)continue e;e.child.return=e,e=e.child}if(!(e.flags&2))return e.stateNode}}function Cu(e,t,n){var r=e.tag;if(r===5||r===6)e=e.stateNode,t?n.nodeType===8?n.parentNode.insertBefore(e,t):n.insertBefore(e,t):(n.nodeType===8?(t=n.parentNode,t.insertBefore(e,n)):(t=n,t.appendChild(e)),n=n._reactRootContainer,n!=null||t.onclick!==null||(t.onclick=Mo));else if(r!==4&&(e=e.child,e!==null))for(Cu(e,t,n),e=e.sibling;e!==null;)Cu(e,t,n),e=e.sibling}function bu(e,t,n){var r=e.tag;if(r===5||r===6)e=e.stateNode,t?n.insertBefore(e,t):n.appendChild(e);else if(r!==4&&(e=e.child,e!==null))for(bu(e,t,n),e=e.sibling;e!==null;)bu(e,t,n),e=e.sibling}var Xe=null,Vt=!1;function Cn(e,t,n){for(n=n.child;n!==null;)qm(e,t,n),n=n.sibling}function qm(e,t,n){if(un&&typeof un.onCommitFiberUnmount=="function")try{un.onCommitFiberUnmount(pl,n)}catch{}switch(n.tag){case 5:rt||Ur(n,t);case 6:var r=Xe,i=Vt;Xe=null,Cn(e,t,n),Xe=r,Vt=i,Xe!==null&&(Vt?(e=Xe,n=n.stateNode,e.nodeType===8?e.parentNode.removeChild(n):e.removeChild(n)):Xe.removeChild(n.stateNode));break;case 18:Xe!==null&&(Vt?(e=Xe,n=n.stateNode,e.nodeType===8?pa(e.parentNode,n):e.nodeType===1&&pa(e,n),ss(e)):pa(Xe,n.stateNode));break;case 4:r=Xe,i=Vt,Xe=n.stateNode.containerInfo,Vt=!0,Cn(e,t,n),Xe=r,Vt=i;break;case 0:case 11:case 14:case 15:if(!rt&&(r=n.updateQueue,r!==null&&(r=r.lastEffect,r!==null))){i=r=r.next;do{var s=i,o=s.destroy;s=s.tag,o!==void 0&&(s&2||s&4)&&Su(n,t,o),i=i.next}while(i!==r)}Cn(e,t,n);break;case 1:if(!rt&&(Ur(n,t),r=n.stateNode,typeof r.componentWillUnmount=="function"))try{r.props=n.memoizedProps,r.state=n.memoizedState,r.componentWillUnmount()}catch(l){Re(n,t,l)}Cn(e,t,n);break;case 21:Cn(e,t,n);break;case 22:n.mode&1?(rt=(r=rt)||n.memoizedState!==null,Cn(e,t,n),rt=r):Cn(e,t,n);break;default:Cn(e,t,n)}}function Of(e){var t=e.updateQueue;if(t!==null){e.updateQueue=null;var n=e.stateNode;n===null&&(n=e.stateNode=new x0),t.forEach(function(r){var i=P0.bind(null,e,r);n.has(r)||(n.add(r),r.then(i,i))})}}function Wt(e,t){var n=t.deletions;if(n!==null)for(var r=0;ri&&(i=o),r&=~s}if(r=i,r=Le()-r,r=(120>r?120:480>r?480:1080>r?1080:1920>r?1920:3e3>r?3e3:4320>r?4320:1960*E0(r/1960))-r,10e?16:e,Rn===null)var r=!1;else{if(e=Rn,Rn=null,Go=0,ae&6)throw Error(I(331));var i=ae;for(ae|=4,B=e.current;B!==null;){var s=B,o=s.child;if(B.flags&16){var l=s.deletions;if(l!==null){for(var a=0;aLe()-Bc?cr(e,0):Uc|=n),xt(e,t)}function tg(e,t){t===0&&(e.mode&1?(t=Ws,Ws<<=1,!(Ws&130023424)&&(Ws=4194304)):t=1);var n=ft();e=xn(e,t),e!==null&&(Ns(e,t,n),xt(e,n))}function _0(e){var t=e.memoizedState,n=0;t!==null&&(n=t.retryLane),tg(e,n)}function P0(e,t){var n=0;switch(e.tag){case 13:var r=e.stateNode,i=e.memoizedState;i!==null&&(n=i.retryLane);break;case 19:r=e.stateNode;break;default:throw Error(I(314))}r!==null&&r.delete(t),tg(e,n)}var ng;ng=function(e,t,n){if(e!==null)if(e.memoizedProps!==t.pendingProps||yt.current)vt=!0;else{if(!(e.lanes&n)&&!(t.flags&128))return vt=!1,v0(e,t,n);vt=!!(e.flags&131072)}else vt=!1,be&&t.flags&1048576&&om(t,zo,t.index);switch(t.lanes=0,t.tag){case 2:var r=t.type;yo(e,t),e=t.pendingProps;var i=Xr(t,st.current);qr(t,n),i=Mc(null,t,r,e,i,n);var s=Dc();return t.flags|=1,typeof i=="object"&&i!==null&&typeof i.render=="function"&&i.$$typeof===void 0?(t.tag=1,t.memoizedState=null,t.updateQueue=null,wt(r)?(s=!0,Ao(t)):s=!1,t.memoizedState=i.state!==null&&i.state!==void 0?i.state:null,Pc(t),i.updater=xl,t.stateNode=i,i._reactInternals=t,mu(t,r,e,n),t=yu(null,t,r,!0,s,n)):(t.tag=0,be&&s&&Ec(t),ut(null,t,i,n),t=t.child),t;case 16:r=t.elementType;e:{switch(yo(e,t),e=t.pendingProps,i=r._init,r=i(r._payload),t.type=r,i=t.tag=O0(r),e=Ht(r,e),i){case 0:t=vu(null,t,r,e,n);break e;case 1:t=Tf(null,t,r,e,n);break e;case 11:t=bf(null,t,r,e,n);break e;case 14:t=Nf(null,t,r,Ht(r.type,e),n);break e}throw Error(I(306,r,""))}return t;case 0:return r=t.type,i=t.pendingProps,i=t.elementType===r?i:Ht(r,i),vu(e,t,r,i,n);case 1:return r=t.type,i=t.pendingProps,i=t.elementType===r?i:Ht(r,i),Tf(e,t,r,i,n);case 3:e:{if(zm(t),e===null)throw Error(I(387));r=t.pendingProps,s=t.memoizedState,i=s.element,fm(e,t),Bo(t,r,null,n);var o=t.memoizedState;if(r=o.element,s.isDehydrated)if(s={element:r,isDehydrated:!1,cache:o.cache,pendingSuspenseBoundaries:o.pendingSuspenseBoundaries,transitions:o.transitions},t.updateQueue.baseState=s,t.memoizedState=s,t.flags&256){i=ti(Error(I(423)),t),t=jf(e,t,r,n,i);break e}else if(r!==i){i=ti(Error(I(424)),t),t=jf(e,t,r,n,i);break e}else for(Tt=Dn(t.stateNode.containerInfo.firstChild),jt=t,be=!0,Qt=null,n=cm(t,null,r,n),t.child=n;n;)n.flags=n.flags&-3|4096,n=n.sibling;else{if(Jr(),r===i){t=kn(e,t,n);break e}ut(e,t,r,n)}t=t.child}return t;case 5:return pm(t),e===null&&fu(t),r=t.type,i=t.pendingProps,s=e!==null?e.memoizedProps:null,o=i.children,lu(r,i)?o=null:s!==null&&lu(r,s)&&(t.flags|=32),$m(e,t),ut(e,t,o,n),t.child;case 6:return e===null&&fu(t),null;case 13:return Fm(e,t,n);case 4:return Rc(t,t.stateNode.containerInfo),r=t.pendingProps,e===null?t.child=Zr(t,null,r,n):ut(e,t,r,n),t.child;case 11:return r=t.type,i=t.pendingProps,i=t.elementType===r?i:Ht(r,i),bf(e,t,r,i,n);case 7:return ut(e,t,t.pendingProps,n),t.child;case 8:return ut(e,t,t.pendingProps.children,n),t.child;case 12:return ut(e,t,t.pendingProps.children,n),t.child;case 10:e:{if(r=t.type._context,i=t.pendingProps,s=t.memoizedProps,o=i.value,ke(Fo,r._currentValue),r._currentValue=o,s!==null)if(Zt(s.value,o)){if(s.children===i.children&&!yt.current){t=kn(e,t,n);break e}}else for(s=t.child,s!==null&&(s.return=t);s!==null;){var l=s.dependencies;if(l!==null){o=s.child;for(var a=l.firstContext;a!==null;){if(a.context===r){if(s.tag===1){a=gn(-1,n&-n),a.tag=2;var u=s.updateQueue;if(u!==null){u=u.shared;var d=u.pending;d===null?a.next=a:(a.next=d.next,d.next=a),u.pending=a}}s.lanes|=n,a=s.alternate,a!==null&&(a.lanes|=n),pu(s.return,n,t),l.lanes|=n;break}a=a.next}}else if(s.tag===10)o=s.type===t.type?null:s.child;else if(s.tag===18){if(o=s.return,o===null)throw Error(I(341));o.lanes|=n,l=o.alternate,l!==null&&(l.lanes|=n),pu(o,n,t),o=s.sibling}else o=s.child;if(o!==null)o.return=s;else for(o=s;o!==null;){if(o===t){o=null;break}if(s=o.sibling,s!==null){s.return=o.return,o=s;break}o=o.return}s=o}ut(e,t,i.children,n),t=t.child}return t;case 9:return i=t.type,r=t.pendingProps.children,qr(t,n),i=zt(i),r=r(i),t.flags|=1,ut(e,t,r,n),t.child;case 14:return r=t.type,i=Ht(r,t.pendingProps),i=Ht(r.type,i),Nf(e,t,r,i,n);case 15:return Dm(e,t,t.type,t.pendingProps,n);case 17:return r=t.type,i=t.pendingProps,i=t.elementType===r?i:Ht(r,i),yo(e,t),t.tag=1,wt(r)?(e=!0,Ao(t)):e=!1,qr(t,n),Lm(t,r,i),mu(t,r,i,n),yu(null,t,r,!0,e,n);case 19:return Um(e,t,n);case 22:return Am(e,t,n)}throw Error(I(156,t.tag))};function rg(e,t){return Ph(e,t)}function R0(e,t,n,r){this.tag=e,this.key=n,this.sibling=this.child=this.return=this.stateNode=this.type=this.elementType=null,this.index=0,this.ref=null,this.pendingProps=t,this.dependencies=this.memoizedState=this.updateQueue=this.memoizedProps=null,this.mode=r,this.subtreeFlags=this.flags=0,this.deletions=null,this.childLanes=this.lanes=0,this.alternate=null}function At(e,t,n,r){return new R0(e,t,n,r)}function Qc(e){return e=e.prototype,!(!e||!e.isReactComponent)}function O0(e){if(typeof e=="function")return Qc(e)?1:0;if(e!=null){if(e=e.$$typeof,e===dc)return 11;if(e===fc)return 14}return 2}function Fn(e,t){var n=e.alternate;return n===null?(n=At(e.tag,t,e.key,e.mode),n.elementType=e.elementType,n.type=e.type,n.stateNode=e.stateNode,n.alternate=e,e.alternate=n):(n.pendingProps=t,n.type=e.type,n.flags=0,n.subtreeFlags=0,n.deletions=null),n.flags=e.flags&14680064,n.childLanes=e.childLanes,n.lanes=e.lanes,n.child=e.child,n.memoizedProps=e.memoizedProps,n.memoizedState=e.memoizedState,n.updateQueue=e.updateQueue,t=e.dependencies,n.dependencies=t===null?null:{lanes:t.lanes,firstContext:t.firstContext},n.sibling=e.sibling,n.index=e.index,n.ref=e.ref,n}function ko(e,t,n,r,i,s){var o=2;if(r=e,typeof e=="function")Qc(e)&&(o=1);else if(typeof e=="string")o=5;else e:switch(e){case Or:return dr(n.children,i,s,t);case cc:o=8,i|=8;break;case za:return e=At(12,n,t,i|2),e.elementType=za,e.lanes=s,e;case Fa:return e=At(13,n,t,i),e.elementType=Fa,e.lanes=s,e;case Ua:return e=At(19,n,t,i),e.elementType=Ua,e.lanes=s,e;case ph:return El(n,i,s,t);default:if(typeof e=="object"&&e!==null)switch(e.$$typeof){case dh:o=10;break e;case fh:o=9;break e;case dc:o=11;break e;case fc:o=14;break e;case Nn:o=16,r=null;break e}throw Error(I(130,e==null?e:typeof e,""))}return t=At(o,n,t,i),t.elementType=e,t.type=r,t.lanes=s,t}function dr(e,t,n,r){return e=At(7,e,r,t),e.lanes=n,e}function El(e,t,n,r){return e=At(22,e,r,t),e.elementType=ph,e.lanes=n,e.stateNode={isHidden:!1},e}function ka(e,t,n){return e=At(6,e,null,t),e.lanes=n,e}function Sa(e,t,n){return t=At(4,e.children!==null?e.children:[],e.key,t),t.lanes=n,t.stateNode={containerInfo:e.containerInfo,pendingChildren:null,implementation:e.implementation},t}function L0(e,t,n,r,i){this.tag=t,this.containerInfo=e,this.finishedWork=this.pingCache=this.current=this.pendingChildren=null,this.timeoutHandle=-1,this.callbackNode=this.pendingContext=this.context=null,this.callbackPriority=0,this.eventTimes=na(0),this.expirationTimes=na(-1),this.entangledLanes=this.finishedLanes=this.mutableReadLanes=this.expiredLanes=this.pingedLanes=this.suspendedLanes=this.pendingLanes=0,this.entanglements=na(0),this.identifierPrefix=r,this.onRecoverableError=i,this.mutableSourceEagerHydrationData=null}function qc(e,t,n,r,i,s,o,l,a){return e=new L0(e,t,n,l,a),t===1?(t=1,s===!0&&(t|=8)):t=0,s=At(3,null,null,t),e.current=s,s.stateNode=e,s.memoizedState={element:r,isDehydrated:n,cache:null,transitions:null,pendingSuspenseBoundaries:null},Pc(s),e}function I0(e,t,n){var r=3"u"||typeof __REACT_DEVTOOLS_GLOBAL_HOOK__.checkDCE!="function"))try{__REACT_DEVTOOLS_GLOBAL_HOOK__.checkDCE(lg)}catch(e){console.error(e)}}lg(),lh.exports=Rt;var z0=lh.exports,Ff=z0;Aa.createRoot=Ff.createRoot,Aa.hydrateRoot=Ff.hydrateRoot;/** + * @remix-run/router v1.23.0 + * + * Copyright (c) Remix Software Inc. + * + * This source code is licensed under the MIT license found in the + * LICENSE.md file in the root directory of this source tree. + * + * @license MIT + */function vs(){return vs=Object.assign?Object.assign.bind():function(e){for(var t=1;t"u")throw new Error(t)}function ag(e,t){if(!e){typeof console<"u"&&console.warn(t);try{throw new Error(t)}catch{}}}function U0(){return Math.random().toString(36).substr(2,8)}function Bf(e,t){return{usr:e.state,key:e.key,idx:t}}function Pu(e,t,n,r){return n===void 0&&(n=null),vs({pathname:typeof e=="string"?e:e.pathname,search:"",hash:""},typeof t=="string"?ai(t):t,{state:n,key:t&&t.key||r||U0()})}function Xo(e){let{pathname:t="/",search:n="",hash:r=""}=e;return n&&n!=="?"&&(t+=n.charAt(0)==="?"?n:"?"+n),r&&r!=="#"&&(t+=r.charAt(0)==="#"?r:"#"+r),t}function ai(e){let t={};if(e){let n=e.indexOf("#");n>=0&&(t.hash=e.substr(n),e=e.substr(0,n));let r=e.indexOf("?");r>=0&&(t.search=e.substr(r),e=e.substr(0,r)),e&&(t.pathname=e)}return t}function B0(e,t,n,r){r===void 0&&(r={});let{window:i=document.defaultView,v5Compat:s=!1}=r,o=i.history,l=On.Pop,a=null,u=d();u==null&&(u=0,o.replaceState(vs({},o.state,{idx:u}),""));function d(){return(o.state||{idx:null}).idx}function f(){l=On.Pop;let k=d(),g=k==null?null:k-u;u=k,a&&a({action:l,location:v.location,delta:g})}function p(k,g){l=On.Push;let m=Pu(v.location,k,g);u=d()+1;let y=Bf(m,u),C=v.createHref(m);try{o.pushState(y,"",C)}catch(j){if(j instanceof DOMException&&j.name==="DataCloneError")throw j;i.location.assign(C)}s&&a&&a({action:l,location:v.location,delta:1})}function w(k,g){l=On.Replace;let m=Pu(v.location,k,g);u=d();let y=Bf(m,u),C=v.createHref(m);o.replaceState(y,"",C),s&&a&&a({action:l,location:v.location,delta:0})}function h(k){let g=i.location.origin!=="null"?i.location.origin:i.location.href,m=typeof k=="string"?k:Xo(k);return m=m.replace(/ $/,"%20"),Ie(g,"No window.location.(origin|href) available to create URL for href: "+m),new URL(m,g)}let v={get action(){return l},get location(){return e(i,o)},listen(k){if(a)throw new Error("A history only accepts one active listener");return i.addEventListener(Uf,f),a=k,()=>{i.removeEventListener(Uf,f),a=null}},createHref(k){return t(i,k)},createURL:h,encodeLocation(k){let g=h(k);return{pathname:g.pathname,search:g.search,hash:g.hash}},push:p,replace:w,go(k){return o.go(k)}};return v}var Wf;(function(e){e.data="data",e.deferred="deferred",e.redirect="redirect",e.error="error"})(Wf||(Wf={}));function W0(e,t,n){return n===void 0&&(n="/"),H0(e,t,n)}function H0(e,t,n,r){let i=typeof t=="string"?ai(t):t,s=Xc(i.pathname||"/",n);if(s==null)return null;let o=ug(e);V0(o);let l=null;for(let a=0;l==null&&a{let a={relativePath:l===void 0?s.path||"":l,caseSensitive:s.caseSensitive===!0,childrenIndex:o,route:s};a.relativePath.startsWith("/")&&(Ie(a.relativePath.startsWith(r),'Absolute route path "'+a.relativePath+'" nested under path '+('"'+r+'" is not valid. An absolute child route path ')+"must start with the combined path of all its parent routes."),a.relativePath=a.relativePath.slice(r.length));let u=Un([r,a.relativePath]),d=n.concat(a);s.children&&s.children.length>0&&(Ie(s.index!==!0,"Index routes must not have child routes. Please remove "+('all child routes from route path "'+u+'".')),ug(s.children,t,d,u)),!(s.path==null&&!s.index)&&t.push({path:u,score:J0(u,s.index),routesMeta:d})};return e.forEach((s,o)=>{var l;if(s.path===""||!((l=s.path)!=null&&l.includes("?")))i(s,o);else for(let a of cg(s.path))i(s,o,a)}),t}function cg(e){let t=e.split("/");if(t.length===0)return[];let[n,...r]=t,i=n.endsWith("?"),s=n.replace(/\?$/,"");if(r.length===0)return i?[s,""]:[s];let o=cg(r.join("/")),l=[];return l.push(...o.map(a=>a===""?s:[s,a].join("/"))),i&&l.push(...o),l.map(a=>e.startsWith("/")&&a===""?"/":a)}function V0(e){e.sort((t,n)=>t.score!==n.score?n.score-t.score:Z0(t.routesMeta.map(r=>r.childrenIndex),n.routesMeta.map(r=>r.childrenIndex)))}const Q0=/^:[\w-]+$/,q0=3,G0=2,Y0=1,K0=10,X0=-2,Hf=e=>e==="*";function J0(e,t){let n=e.split("/"),r=n.length;return n.some(Hf)&&(r+=X0),t&&(r+=G0),n.filter(i=>!Hf(i)).reduce((i,s)=>i+(Q0.test(s)?q0:s===""?Y0:K0),r)}function Z0(e,t){return e.length===t.length&&e.slice(0,-1).every((r,i)=>r===t[i])?e[e.length-1]-t[t.length-1]:0}function ex(e,t,n){let{routesMeta:r}=e,i={},s="/",o=[];for(let l=0;l{let{paramName:p,isOptional:w}=d;if(p==="*"){let v=l[f]||"";o=s.slice(0,s.length-v.length).replace(/(.)\/+$/,"$1")}const h=l[f];return w&&!h?u[p]=void 0:u[p]=(h||"").replace(/%2F/g,"/"),u},{}),pathname:s,pathnameBase:o,pattern:e}}function nx(e,t,n){t===void 0&&(t=!1),n===void 0&&(n=!0),ag(e==="*"||!e.endsWith("*")||e.endsWith("/*"),'Route path "'+e+'" will be treated as if it were '+('"'+e.replace(/\*$/,"/*")+'" because the `*` character must ')+"always follow a `/` in the pattern. To get rid of this warning, "+('please change the route path to "'+e.replace(/\*$/,"/*")+'".'));let r=[],i="^"+e.replace(/\/*\*?$/,"").replace(/^\/*/,"/").replace(/[\\.*+^${}|()[\]]/g,"\\$&").replace(/\/:([\w-]+)(\?)?/g,(o,l,a)=>(r.push({paramName:l,isOptional:a!=null}),a?"/?([^\\/]+)?":"/([^\\/]+)"));return e.endsWith("*")?(r.push({paramName:"*"}),i+=e==="*"||e==="/*"?"(.*)$":"(?:\\/(.+)|\\/*)$"):n?i+="\\/*$":e!==""&&e!=="/"&&(i+="(?:(?=\\/|$))"),[new RegExp(i,t?void 0:"i"),r]}function rx(e){try{return e.split("/").map(t=>decodeURIComponent(t).replace(/\//g,"%2F")).join("/")}catch(t){return ag(!1,'The URL path "'+e+'" could not be decoded because it is is a malformed URL segment. This is probably due to a bad percent '+("encoding ("+t+").")),e}}function Xc(e,t){if(t==="/")return e;if(!e.toLowerCase().startsWith(t.toLowerCase()))return null;let n=t.endsWith("/")?t.length-1:t.length,r=e.charAt(n);return r&&r!=="/"?null:e.slice(n)||"/"}function ix(e,t){t===void 0&&(t="/");let{pathname:n,search:r="",hash:i=""}=typeof e=="string"?ai(e):e;return{pathname:n?n.startsWith("/")?n:sx(n,t):t,search:ax(r),hash:ux(i)}}function sx(e,t){let n=t.replace(/\/+$/,"").split("/");return e.split("/").forEach(i=>{i===".."?n.length>1&&n.pop():i!=="."&&n.push(i)}),n.length>1?n.join("/"):"/"}function Ea(e,t,n,r){return"Cannot include a '"+e+"' character in a manually specified "+("`to."+t+"` field ["+JSON.stringify(r)+"]. Please separate it out to the ")+("`to."+n+"` field. Alternatively you may provide the full path as ")+'a string in and the router will parse it for you.'}function ox(e){return e.filter((t,n)=>n===0||t.route.path&&t.route.path.length>0)}function Jc(e,t){let n=ox(e);return t?n.map((r,i)=>i===n.length-1?r.pathname:r.pathnameBase):n.map(r=>r.pathnameBase)}function Zc(e,t,n,r){r===void 0&&(r=!1);let i;typeof e=="string"?i=ai(e):(i=vs({},e),Ie(!i.pathname||!i.pathname.includes("?"),Ea("?","pathname","search",i)),Ie(!i.pathname||!i.pathname.includes("#"),Ea("#","pathname","hash",i)),Ie(!i.search||!i.search.includes("#"),Ea("#","search","hash",i)));let s=e===""||i.pathname==="",o=s?"/":i.pathname,l;if(o==null)l=n;else{let f=t.length-1;if(!r&&o.startsWith("..")){let p=o.split("/");for(;p[0]==="..";)p.shift(),f-=1;i.pathname=p.join("/")}l=f>=0?t[f]:"/"}let a=ix(i,l),u=o&&o!=="/"&&o.endsWith("/"),d=(s||o===".")&&n.endsWith("/");return!a.pathname.endsWith("/")&&(u||d)&&(a.pathname+="/"),a}const Un=e=>e.join("/").replace(/\/\/+/g,"/"),lx=e=>e.replace(/\/+$/,"").replace(/^\/*/,"/"),ax=e=>!e||e==="?"?"":e.startsWith("?")?e:"?"+e,ux=e=>!e||e==="#"?"":e.startsWith("#")?e:"#"+e;function cx(e){return e!=null&&typeof e.status=="number"&&typeof e.statusText=="string"&&typeof e.internal=="boolean"&&"data"in e}const dg=["post","put","patch","delete"];new Set(dg);const dx=["get",...dg];new Set(dx);/** + * React Router v6.30.1 + * + * Copyright (c) Remix Software Inc. + * + * This source code is licensed under the MIT license found in the + * LICENSE.md file in the root directory of this source tree. + * + * @license MIT + */function ys(){return ys=Object.assign?Object.assign.bind():function(e){for(var t=1;t{l.current=!0}),x.useCallback(function(u,d){if(d===void 0&&(d={}),!l.current)return;if(typeof u=="number"){r.go(u);return}let f=Zc(u,JSON.parse(o),s,d.relative==="path");e==null&&t!=="/"&&(f.pathname=f.pathname==="/"?t:Un([t,f.pathname])),(d.replace?r.replace:r.push)(f,d.state,d)},[t,r,o,s,e])}function hg(e,t){let{relative:n}=t===void 0?{}:t,{future:r}=x.useContext(Gn),{matches:i}=x.useContext(Yn),{pathname:s}=ci(),o=JSON.stringify(Jc(i,r.v7_relativeSplatPath));return x.useMemo(()=>Zc(e,JSON.parse(o),s,n==="path"),[e,o,s,n])}function mx(e,t){return gx(e,t)}function gx(e,t,n,r){ui()||Ie(!1);let{navigator:i}=x.useContext(Gn),{matches:s}=x.useContext(Yn),o=s[s.length-1],l=o?o.params:{};o&&o.pathname;let a=o?o.pathnameBase:"/";o&&o.route;let u=ci(),d;if(t){var f;let k=typeof t=="string"?ai(t):t;a==="/"||(f=k.pathname)!=null&&f.startsWith(a)||Ie(!1),d=k}else d=u;let p=d.pathname||"/",w=p;if(a!=="/"){let k=a.replace(/^\//,"").split("/");w="/"+p.replace(/^\//,"").split("/").slice(k.length).join("/")}let h=W0(e,{pathname:w}),v=kx(h&&h.map(k=>Object.assign({},k,{params:Object.assign({},l,k.params),pathname:Un([a,i.encodeLocation?i.encodeLocation(k.pathname).pathname:k.pathname]),pathnameBase:k.pathnameBase==="/"?a:Un([a,i.encodeLocation?i.encodeLocation(k.pathnameBase).pathname:k.pathnameBase])})),s,n,r);return t&&v?x.createElement(jl.Provider,{value:{location:ys({pathname:"/",search:"",hash:"",state:null,key:"default"},d),navigationType:On.Pop}},v):v}function vx(){let e=bx(),t=cx(e)?e.status+" "+e.statusText:e instanceof Error?e.message:JSON.stringify(e),n=e instanceof Error?e.stack:null,i={padding:"0.5rem",backgroundColor:"rgba(200,200,200, 0.5)"};return x.createElement(x.Fragment,null,x.createElement("h2",null,"Unexpected Application Error!"),x.createElement("h3",{style:{fontStyle:"italic"}},t),n?x.createElement("pre",{style:i},n):null,null)}const yx=x.createElement(vx,null);class wx extends x.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,n){return n.location!==t.location||n.revalidation!=="idle"&&t.revalidation==="idle"?{error:t.error,location:t.location,revalidation:t.revalidation}:{error:t.error!==void 0?t.error:n.error,location:n.location,revalidation:t.revalidation||n.revalidation}}componentDidCatch(t,n){console.error("React Router caught the following error during render",t,n)}render(){return this.state.error!==void 0?x.createElement(Yn.Provider,{value:this.props.routeContext},x.createElement(fg.Provider,{value:this.state.error,children:this.props.component})):this.props.children}}function xx(e){let{routeContext:t,match:n,children:r}=e,i=x.useContext(ed);return i&&i.static&&i.staticContext&&(n.route.errorElement||n.route.ErrorBoundary)&&(i.staticContext._deepestRenderedBoundaryId=n.route.id),x.createElement(Yn.Provider,{value:t},r)}function kx(e,t,n,r){var i;if(t===void 0&&(t=[]),n===void 0&&(n=null),r===void 0&&(r=null),e==null){var s;if(!n)return null;if(n.errors)e=n.matches;else if((s=r)!=null&&s.v7_partialHydration&&t.length===0&&!n.initialized&&n.matches.length>0)e=n.matches;else return null}let o=e,l=(i=n)==null?void 0:i.errors;if(l!=null){let d=o.findIndex(f=>f.route.id&&(l==null?void 0:l[f.route.id])!==void 0);d>=0||Ie(!1),o=o.slice(0,Math.min(o.length,d+1))}let a=!1,u=-1;if(n&&r&&r.v7_partialHydration)for(let d=0;d=0?o=o.slice(0,u+1):o=[o[0]];break}}}return o.reduceRight((d,f,p)=>{let w,h=!1,v=null,k=null;n&&(w=l&&f.route.id?l[f.route.id]:void 0,v=f.route.errorElement||yx,a&&(u<0&&p===0?(Tx("route-fallback"),h=!0,k=null):u===p&&(h=!0,k=f.route.hydrateFallbackElement||null)));let g=t.concat(o.slice(0,p+1)),m=()=>{let y;return w?y=v:h?y=k:f.route.Component?y=x.createElement(f.route.Component,null):f.route.element?y=f.route.element:y=d,x.createElement(xx,{match:f,routeContext:{outlet:d,matches:g,isDataRoute:n!=null},children:y})};return n&&(f.route.ErrorBoundary||f.route.errorElement||p===0)?x.createElement(wx,{location:n.location,revalidation:n.revalidation,component:v,error:w,children:m(),routeContext:{outlet:null,matches:g,isDataRoute:!0}}):m()},null)}var mg=function(e){return e.UseBlocker="useBlocker",e.UseRevalidator="useRevalidator",e.UseNavigateStable="useNavigate",e}(mg||{}),gg=function(e){return e.UseBlocker="useBlocker",e.UseLoaderData="useLoaderData",e.UseActionData="useActionData",e.UseRouteError="useRouteError",e.UseNavigation="useNavigation",e.UseRouteLoaderData="useRouteLoaderData",e.UseMatches="useMatches",e.UseRevalidator="useRevalidator",e.UseNavigateStable="useNavigate",e.UseRouteId="useRouteId",e}(gg||{});function Sx(e){let t=x.useContext(ed);return t||Ie(!1),t}function Ex(e){let t=x.useContext(fx);return t||Ie(!1),t}function Cx(e){let t=x.useContext(Yn);return t||Ie(!1),t}function vg(e){let t=Cx(),n=t.matches[t.matches.length-1];return n.route.id||Ie(!1),n.route.id}function bx(){var e;let t=x.useContext(fg),n=Ex(),r=vg();return t!==void 0?t:(e=n.errors)==null?void 0:e[r]}function Nx(){let{router:e}=Sx(mg.UseNavigateStable),t=vg(gg.UseNavigateStable),n=x.useRef(!1);return pg(()=>{n.current=!0}),x.useCallback(function(i,s){s===void 0&&(s={}),n.current&&(typeof i=="number"?e.navigate(i):e.navigate(i,ys({fromRouteId:t},s)))},[e,t])}const Vf={};function Tx(e,t,n){Vf[e]||(Vf[e]=!0)}function jx(e,t){e==null||e.v7_startTransition,e==null||e.v7_relativeSplatPath}function yg(e){let{to:t,replace:n,state:r,relative:i}=e;ui()||Ie(!1);let{future:s,static:o}=x.useContext(Gn),{matches:l}=x.useContext(Yn),{pathname:a}=ci(),u=Kn(),d=Zc(t,Jc(l,s.v7_relativeSplatPath),a,i==="path"),f=JSON.stringify(d);return x.useEffect(()=>u(JSON.parse(f),{replace:n,state:r,relative:i}),[u,f,i,n,r]),null}function rr(e){Ie(!1)}function _x(e){let{basename:t="/",children:n=null,location:r,navigationType:i=On.Pop,navigator:s,static:o=!1,future:l}=e;ui()&&Ie(!1);let a=t.replace(/^\/*/,"/"),u=x.useMemo(()=>({basename:a,navigator:s,static:o,future:ys({v7_relativeSplatPath:!1},l)}),[a,l,s,o]);typeof r=="string"&&(r=ai(r));let{pathname:d="/",search:f="",hash:p="",state:w=null,key:h="default"}=r,v=x.useMemo(()=>{let k=Xc(d,a);return k==null?null:{location:{pathname:k,search:f,hash:p,state:w,key:h},navigationType:i}},[a,d,f,p,w,h,i]);return v==null?null:x.createElement(Gn.Provider,{value:u},x.createElement(jl.Provider,{children:n,value:v}))}function Px(e){let{children:t,location:n}=e;return mx(Ru(t),n)}new Promise(()=>{});function Ru(e,t){t===void 0&&(t=[]);let n=[];return x.Children.forEach(e,(r,i)=>{if(!x.isValidElement(r))return;let s=[...t,i];if(r.type===x.Fragment){n.push.apply(n,Ru(r.props.children,s));return}r.type!==rr&&Ie(!1),!r.props.index||!r.props.children||Ie(!1);let o={id:r.props.id||s.join("-"),caseSensitive:r.props.caseSensitive,element:r.props.element,Component:r.props.Component,index:r.props.index,path:r.props.path,loader:r.props.loader,action:r.props.action,errorElement:r.props.errorElement,ErrorBoundary:r.props.ErrorBoundary,hasErrorBoundary:r.props.ErrorBoundary!=null||r.props.errorElement!=null,shouldRevalidate:r.props.shouldRevalidate,handle:r.props.handle,lazy:r.props.lazy};r.props.children&&(o.children=Ru(r.props.children,s)),n.push(o)}),n}/** + * React Router DOM v6.30.1 + * + * Copyright (c) Remix Software Inc. + * + * This source code is licensed under the MIT license found in the + * LICENSE.md file in the root directory of this source tree. + * + * @license MIT + */function Ou(){return Ou=Object.assign?Object.assign.bind():function(e){for(var t=1;t=0)&&(n[i]=e[i]);return n}function Ox(e){return!!(e.metaKey||e.altKey||e.ctrlKey||e.shiftKey)}function Lx(e,t){return e.button===0&&(!t||t==="_self")&&!Ox(e)}function Lu(e){return e===void 0&&(e=""),new URLSearchParams(typeof e=="string"||Array.isArray(e)||e instanceof URLSearchParams?e:Object.keys(e).reduce((t,n)=>{let r=e[n];return t.concat(Array.isArray(r)?r.map(i=>[n,i]):[[n,r]])},[]))}function Ix(e,t){let n=Lu(e);return t&&t.forEach((r,i)=>{n.has(i)||t.getAll(i).forEach(s=>{n.append(i,s)})}),n}const Mx=["onClick","relative","reloadDocument","replace","state","target","to","preventScrollReset","viewTransition"],Dx="6";try{window.__reactRouterVersion=Dx}catch{}const Ax="startTransition",Qf=jy[Ax];function $x(e){let{basename:t,children:n,future:r,window:i}=e,s=x.useRef();s.current==null&&(s.current=F0({window:i,v5Compat:!0}));let o=s.current,[l,a]=x.useState({action:o.action,location:o.location}),{v7_startTransition:u}=r||{},d=x.useCallback(f=>{u&&Qf?Qf(()=>a(f)):a(f)},[a,u]);return x.useLayoutEffect(()=>o.listen(d),[o,d]),x.useEffect(()=>jx(r),[r]),x.createElement(_x,{basename:t,children:n,location:l.location,navigationType:l.action,navigator:o,future:r})}const zx=typeof window<"u"&&typeof window.document<"u"&&typeof window.document.createElement<"u",Fx=/^(?:[a-z][a-z0-9+.-]*:|\/\/)/i,wg=x.forwardRef(function(t,n){let{onClick:r,relative:i,reloadDocument:s,replace:o,state:l,target:a,to:u,preventScrollReset:d,viewTransition:f}=t,p=Rx(t,Mx),{basename:w}=x.useContext(Gn),h,v=!1;if(typeof u=="string"&&Fx.test(u)&&(h=u,zx))try{let y=new URL(window.location.href),C=u.startsWith("//")?new URL(y.protocol+u):new URL(u),j=Xc(C.pathname,w);C.origin===y.origin&&j!=null?u=j+C.search+C.hash:v=!0}catch{}let k=px(u,{relative:i}),g=Ux(u,{replace:o,state:l,target:a,preventScrollReset:d,relative:i,viewTransition:f});function m(y){r&&r(y),y.defaultPrevented||g(y)}return x.createElement("a",Ou({},p,{href:h||k,onClick:v||s?r:m,ref:n,target:a}))});var qf;(function(e){e.UseScrollRestoration="useScrollRestoration",e.UseSubmit="useSubmit",e.UseSubmitFetcher="useSubmitFetcher",e.UseFetcher="useFetcher",e.useViewTransitionState="useViewTransitionState"})(qf||(qf={}));var Gf;(function(e){e.UseFetcher="useFetcher",e.UseFetchers="useFetchers",e.UseScrollRestoration="useScrollRestoration"})(Gf||(Gf={}));function Ux(e,t){let{target:n,replace:r,state:i,preventScrollReset:s,relative:o,viewTransition:l}=t===void 0?{}:t,a=Kn(),u=ci(),d=hg(e,{relative:o});return x.useCallback(f=>{if(Lx(f,n)){f.preventDefault();let p=r!==void 0?r:Xo(u)===Xo(d);a(e,{replace:p,state:i,preventScrollReset:s,relative:o,viewTransition:l})}},[u,a,d,r,i,n,e,s,o,l])}function Bx(e){let t=x.useRef(Lu(e)),n=x.useRef(!1),r=ci(),i=x.useMemo(()=>Ix(r.search,n.current?null:t.current),[r.search]),s=Kn(),o=x.useCallback((l,a)=>{const u=Lu(typeof l=="function"?l(i):l);n.current=!0,s("?"+u,a)},[s,i]);return[i,o]}var xg={exports:{}},kg={};/** + * @license React + * use-sync-external-store-with-selector.production.js + * + * Copyright (c) Meta Platforms, Inc. and affiliates. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + */var Ps=x;function Wx(e,t){return e===t&&(e!==0||1/e===1/t)||e!==e&&t!==t}var Hx=typeof Object.is=="function"?Object.is:Wx,Vx=Ps.useSyncExternalStore,Qx=Ps.useRef,qx=Ps.useEffect,Gx=Ps.useMemo,Yx=Ps.useDebugValue;kg.useSyncExternalStoreWithSelector=function(e,t,n,r,i){var s=Qx(null);if(s.current===null){var o={hasValue:!1,value:null};s.current=o}else o=s.current;s=Gx(function(){function a(w){if(!u){if(u=!0,d=w,w=r(w),i!==void 0&&o.hasValue){var h=o.value;if(i(h,w))return f=h}return f=w}if(h=f,Hx(d,w))return h;var v=r(w);return i!==void 0&&i(h,v)?(d=w,h):(d=w,f=v)}var u=!1,d,f,p=n===void 0?null:n;return[function(){return a(t())},p===null?void 0:function(){return a(p())}]},[t,n,r,i]);var l=Vx(e,s[0],s[1]);return qx(function(){o.hasValue=!0,o.value=l},[l]),Yx(l),l};xg.exports=kg;var Kx=xg.exports;function Xx(e){e()}function Jx(){let e=null,t=null;return{clear(){e=null,t=null},notify(){Xx(()=>{let n=e;for(;n;)n.callback(),n=n.next})},get(){const n=[];let r=e;for(;r;)n.push(r),r=r.next;return n},subscribe(n){let r=!0;const i=t={callback:n,next:null,prev:t};return i.prev?i.prev.next=i:e=i,function(){!r||e===null||(r=!1,i.next?i.next.prev=i.prev:t=i.prev,i.prev?i.prev.next=i.next:e=i.next)}}}}var Yf={notify(){},get:()=>[]};function Zx(e,t){let n,r=Yf,i=0,s=!1;function o(v){d();const k=r.subscribe(v);let g=!1;return()=>{g||(g=!0,k(),f())}}function l(){r.notify()}function a(){h.onStateChange&&h.onStateChange()}function u(){return s}function d(){i++,n||(n=e.subscribe(a),r=Jx())}function f(){i--,n&&i===0&&(n(),n=void 0,r.clear(),r=Yf)}function p(){s||(s=!0,d())}function w(){s&&(s=!1,f())}const h={addNestedSub:o,notifyNestedSubs:l,handleChangeWrapper:a,isSubscribed:u,trySubscribe:p,tryUnsubscribe:w,getListeners:()=>r};return h}var ek=()=>typeof window<"u"&&typeof window.document<"u"&&typeof window.document.createElement<"u",tk=ek(),nk=()=>typeof navigator<"u"&&navigator.product==="ReactNative",rk=nk(),ik=()=>tk||rk?x.useLayoutEffect:x.useEffect,sk=ik(),Ca=Symbol.for("react-redux-context"),ba=typeof globalThis<"u"?globalThis:{};function ok(){if(!x.createContext)return{};const e=ba[Ca]??(ba[Ca]=new Map);let t=e.get(x.createContext);return t||(t=x.createContext(null),e.set(x.createContext,t)),t}var Hn=ok();function lk(e){const{children:t,context:n,serverState:r,store:i}=e,s=x.useMemo(()=>{const a=Zx(i);return{store:i,subscription:a,getServerState:r?()=>r:void 0}},[i,r]),o=x.useMemo(()=>i.getState(),[i]);sk(()=>{const{subscription:a}=s;return a.onStateChange=a.notifyNestedSubs,a.trySubscribe(),o!==i.getState()&&a.notifyNestedSubs(),()=>{a.tryUnsubscribe(),a.onStateChange=void 0}},[s,o]);const l=n||Hn;return x.createElement(l.Provider,{value:s},t)}var ak=lk;function td(e=Hn){return function(){return x.useContext(e)}}var Sg=td();function Eg(e=Hn){const t=e===Hn?Sg:td(e),n=()=>{const{store:r}=t();return r};return Object.assign(n,{withTypes:()=>n}),n}var uk=Eg();function ck(e=Hn){const t=e===Hn?uk:Eg(e),n=()=>t().dispatch;return Object.assign(n,{withTypes:()=>n}),n}var dk=ck(),fk=(e,t)=>e===t;function pk(e=Hn){const t=e===Hn?Sg:td(e),n=(r,i={})=>{const{equalityFn:s=fk}=typeof i=="function"?{equalityFn:i}:i,o=t(),{store:l,subscription:a,getServerState:u}=o;x.useRef(!0);const d=x.useCallback({[r.name](p){return r(p)}}[r.name],[r]),f=Kx.useSyncExternalStoreWithSelector(a.addNestedSub,l.getState,u||l.getState,d,s);return x.useDebugValue(f),f};return Object.assign(n,{withTypes:()=>n}),n}var hk=pk();function Ke(e){return`Minified Redux error #${e}; visit https://redux.js.org/Errors?code=${e} for the full message or use the non-minified dev environment for full errors. `}var mk=typeof Symbol=="function"&&Symbol.observable||"@@observable",Kf=mk,Na=()=>Math.random().toString(36).substring(7).split("").join("."),gk={INIT:`@@redux/INIT${Na()}`,REPLACE:`@@redux/REPLACE${Na()}`,PROBE_UNKNOWN_ACTION:()=>`@@redux/PROBE_UNKNOWN_ACTION${Na()}`},Jo=gk;function nd(e){if(typeof e!="object"||e===null)return!1;let t=e;for(;Object.getPrototypeOf(t)!==null;)t=Object.getPrototypeOf(t);return Object.getPrototypeOf(e)===t||Object.getPrototypeOf(e)===null}function Cg(e,t,n){if(typeof e!="function")throw new Error(Ke(2));if(typeof t=="function"&&typeof n=="function"||typeof n=="function"&&typeof arguments[3]=="function")throw new Error(Ke(0));if(typeof t=="function"&&typeof n>"u"&&(n=t,t=void 0),typeof n<"u"){if(typeof n!="function")throw new Error(Ke(1));return n(Cg)(e,t)}let r=e,i=t,s=new Map,o=s,l=0,a=!1;function u(){o===s&&(o=new Map,s.forEach((k,g)=>{o.set(g,k)}))}function d(){if(a)throw new Error(Ke(3));return i}function f(k){if(typeof k!="function")throw new Error(Ke(4));if(a)throw new Error(Ke(5));let g=!0;u();const m=l++;return o.set(m,k),function(){if(g){if(a)throw new Error(Ke(6));g=!1,u(),o.delete(m),s=null}}}function p(k){if(!nd(k))throw new Error(Ke(7));if(typeof k.type>"u")throw new Error(Ke(8));if(typeof k.type!="string")throw new Error(Ke(17));if(a)throw new Error(Ke(9));try{a=!0,i=r(i,k)}finally{a=!1}return(s=o).forEach(m=>{m()}),k}function w(k){if(typeof k!="function")throw new Error(Ke(10));r=k,p({type:Jo.REPLACE})}function h(){const k=f;return{subscribe(g){if(typeof g!="object"||g===null)throw new Error(Ke(11));function m(){const C=g;C.next&&C.next(d())}return m(),{unsubscribe:k(m)}},[Kf](){return this}}}return p({type:Jo.INIT}),{dispatch:p,subscribe:f,getState:d,replaceReducer:w,[Kf]:h}}function vk(e){Object.keys(e).forEach(t=>{const n=e[t];if(typeof n(void 0,{type:Jo.INIT})>"u")throw new Error(Ke(12));if(typeof n(void 0,{type:Jo.PROBE_UNKNOWN_ACTION()})>"u")throw new Error(Ke(13))})}function yk(e){const t=Object.keys(e),n={};for(let s=0;s"u")throw l&&l.type,new Error(Ke(14));u[f]=h,a=a||h!==w}return a=a||r.length!==Object.keys(o).length,a?u:o}}function Zo(...e){return e.length===0?t=>t:e.length===1?e[0]:e.reduce((t,n)=>(...r)=>t(n(...r)))}function wk(...e){return t=>(n,r)=>{const i=t(n,r);let s=()=>{throw new Error(Ke(15))};const o={getState:i.getState,dispatch:(a,...u)=>s(a,...u)},l=e.map(a=>a(o));return s=Zo(...l)(i.dispatch),{...i,dispatch:s}}}function xk(e){return nd(e)&&"type"in e&&typeof e.type=="string"}var bg=Symbol.for("immer-nothing"),Xf=Symbol.for("immer-draftable"),Pt=Symbol.for("immer-state");function Yt(e,...t){throw new Error(`[Immer] minified error nr: ${e}. Full error at: https://bit.ly/3cXEKWf`)}var ws=Object.getPrototypeOf;function wr(e){return!!e&&!!e[Pt]}function Sn(e){var t;return e?Ng(e)||Array.isArray(e)||!!e[Xf]||!!((t=e.constructor)!=null&&t[Xf])||Rs(e)||Pl(e):!1}var kk=Object.prototype.constructor.toString(),Jf=new WeakMap;function Ng(e){if(!e||typeof e!="object")return!1;const t=Object.getPrototypeOf(e);if(t===null||t===Object.prototype)return!0;const n=Object.hasOwnProperty.call(t,"constructor")&&t.constructor;if(n===Object)return!0;if(typeof n!="function")return!1;let r=Jf.get(n);return r===void 0&&(r=Function.toString.call(n),Jf.set(n,r)),r===kk}function el(e,t,n=!0){_l(e)===0?(n?Reflect.ownKeys(e):Object.keys(e)).forEach(i=>{t(i,e[i],e)}):e.forEach((r,i)=>t(i,r,e))}function _l(e){const t=e[Pt];return t?t.type_:Array.isArray(e)?1:Rs(e)?2:Pl(e)?3:0}function Iu(e,t){return _l(e)===2?e.has(t):Object.prototype.hasOwnProperty.call(e,t)}function Tg(e,t,n){const r=_l(e);r===2?e.set(t,n):r===3?e.add(n):e[t]=n}function Sk(e,t){return e===t?e!==0||1/e===1/t:e!==e&&t!==t}function Rs(e){return e instanceof Map}function Pl(e){return e instanceof Set}function ir(e){return e.copy_||e.base_}function Mu(e,t){if(Rs(e))return new Map(e);if(Pl(e))return new Set(e);if(Array.isArray(e))return Array.prototype.slice.call(e);const n=Ng(e);if(t===!0||t==="class_only"&&!n){const r=Object.getOwnPropertyDescriptors(e);delete r[Pt];let i=Reflect.ownKeys(r);for(let s=0;s1&&Object.defineProperties(e,{set:to,add:to,clear:to,delete:to}),Object.freeze(e),t&&Object.values(e).forEach(n=>rd(n,!0))),e}function Ek(){Yt(2)}var to={value:Ek};function Rl(e){return e===null||typeof e!="object"?!0:Object.isFrozen(e)}var Ck={};function xr(e){const t=Ck[e];return t||Yt(0,e),t}var xs;function jg(){return xs}function bk(e,t){return{drafts_:[],parent_:e,immer_:t,canAutoFreeze_:!0,unfinalizedDrafts_:0}}function Zf(e,t){t&&(xr("Patches"),e.patches_=[],e.inversePatches_=[],e.patchListener_=t)}function Du(e){Au(e),e.drafts_.forEach(Nk),e.drafts_=null}function Au(e){e===xs&&(xs=e.parent_)}function ep(e){return xs=bk(xs,e)}function Nk(e){const t=e[Pt];t.type_===0||t.type_===1?t.revoke_():t.revoked_=!0}function tp(e,t){t.unfinalizedDrafts_=t.drafts_.length;const n=t.drafts_[0];return e!==void 0&&e!==n?(n[Pt].modified_&&(Du(t),Yt(4)),Sn(e)&&(e=tl(t,e),t.parent_||nl(t,e)),t.patches_&&xr("Patches").generateReplacementPatches_(n[Pt].base_,e,t.patches_,t.inversePatches_)):e=tl(t,n,[]),Du(t),t.patches_&&t.patchListener_(t.patches_,t.inversePatches_),e!==bg?e:void 0}function tl(e,t,n){if(Rl(t))return t;const r=e.immer_.shouldUseStrictIteration(),i=t[Pt];if(!i)return el(t,(s,o)=>np(e,i,t,s,o,n),r),t;if(i.scope_!==e)return t;if(!i.modified_)return nl(e,i.base_,!0),i.base_;if(!i.finalized_){i.finalized_=!0,i.scope_.unfinalizedDrafts_--;const s=i.copy_;let o=s,l=!1;i.type_===3&&(o=new Set(s),s.clear(),l=!0),el(o,(a,u)=>np(e,i,s,a,u,n,l),r),nl(e,s,!1),n&&e.patches_&&xr("Patches").generatePatches_(i,n,e.patches_,e.inversePatches_)}return i.copy_}function np(e,t,n,r,i,s,o){if(i==null||typeof i!="object"&&!o)return;const l=Rl(i);if(!(l&&!o)){if(wr(i)){const a=s&&t&&t.type_!==3&&!Iu(t.assigned_,r)?s.concat(r):void 0,u=tl(e,i,a);if(Tg(n,r,u),wr(u))e.canAutoFreeze_=!1;else return}else o&&n.add(i);if(Sn(i)&&!l){if(!e.immer_.autoFreeze_&&e.unfinalizedDrafts_<1||t&&t.base_&&t.base_[r]===i&&l)return;tl(e,i),(!t||!t.scope_.parent_)&&typeof r!="symbol"&&(Rs(n)?n.has(r):Object.prototype.propertyIsEnumerable.call(n,r))&&nl(e,i)}}}function nl(e,t,n=!1){!e.parent_&&e.immer_.autoFreeze_&&e.canAutoFreeze_&&rd(t,n)}function Tk(e,t){const n=Array.isArray(e),r={type_:n?1:0,scope_:t?t.scope_:jg(),modified_:!1,finalized_:!1,assigned_:{},parent_:t,base_:e,draft_:null,copy_:null,revoke_:null,isManual_:!1};let i=r,s=id;n&&(i=[r],s=ks);const{revoke:o,proxy:l}=Proxy.revocable(i,s);return r.draft_=l,r.revoke_=o,l}var id={get(e,t){if(t===Pt)return e;const n=ir(e);if(!Iu(n,t))return jk(e,n,t);const r=n[t];return e.finalized_||!Sn(r)?r:r===Ta(e.base_,t)?(ja(e),e.copy_[t]=zu(r,e)):r},has(e,t){return t in ir(e)},ownKeys(e){return Reflect.ownKeys(ir(e))},set(e,t,n){const r=_g(ir(e),t);if(r!=null&&r.set)return r.set.call(e.draft_,n),!0;if(!e.modified_){const i=Ta(ir(e),t),s=i==null?void 0:i[Pt];if(s&&s.base_===n)return e.copy_[t]=n,e.assigned_[t]=!1,!0;if(Sk(n,i)&&(n!==void 0||Iu(e.base_,t)))return!0;ja(e),$u(e)}return e.copy_[t]===n&&(n!==void 0||t in e.copy_)||Number.isNaN(n)&&Number.isNaN(e.copy_[t])||(e.copy_[t]=n,e.assigned_[t]=!0),!0},deleteProperty(e,t){return Ta(e.base_,t)!==void 0||t in e.base_?(e.assigned_[t]=!1,ja(e),$u(e)):delete e.assigned_[t],e.copy_&&delete e.copy_[t],!0},getOwnPropertyDescriptor(e,t){const n=ir(e),r=Reflect.getOwnPropertyDescriptor(n,t);return r&&{writable:!0,configurable:e.type_!==1||t!=="length",enumerable:r.enumerable,value:n[t]}},defineProperty(){Yt(11)},getPrototypeOf(e){return ws(e.base_)},setPrototypeOf(){Yt(12)}},ks={};el(id,(e,t)=>{ks[e]=function(){return arguments[0]=arguments[0][0],t.apply(this,arguments)}});ks.deleteProperty=function(e,t){return ks.set.call(this,e,t,void 0)};ks.set=function(e,t,n){return id.set.call(this,e[0],t,n,e[0])};function Ta(e,t){const n=e[Pt];return(n?ir(n):e)[t]}function jk(e,t,n){var i;const r=_g(t,n);return r?"value"in r?r.value:(i=r.get)==null?void 0:i.call(e.draft_):void 0}function _g(e,t){if(!(t in e))return;let n=ws(e);for(;n;){const r=Object.getOwnPropertyDescriptor(n,t);if(r)return r;n=ws(n)}}function $u(e){e.modified_||(e.modified_=!0,e.parent_&&$u(e.parent_))}function ja(e){e.copy_||(e.copy_=Mu(e.base_,e.scope_.immer_.useStrictShallowCopy_))}var _k=class{constructor(e){this.autoFreeze_=!0,this.useStrictShallowCopy_=!1,this.useStrictIteration_=!0,this.produce=(t,n,r)=>{if(typeof t=="function"&&typeof n!="function"){const s=n;n=t;const o=this;return function(a=s,...u){return o.produce(a,d=>n.call(this,d,...u))}}typeof n!="function"&&Yt(6),r!==void 0&&typeof r!="function"&&Yt(7);let i;if(Sn(t)){const s=ep(this),o=zu(t,void 0);let l=!0;try{i=n(o),l=!1}finally{l?Du(s):Au(s)}return Zf(s,r),tp(i,s)}else if(!t||typeof t!="object"){if(i=n(t),i===void 0&&(i=t),i===bg&&(i=void 0),this.autoFreeze_&&rd(i,!0),r){const s=[],o=[];xr("Patches").generateReplacementPatches_(t,i,s,o),r(s,o)}return i}else Yt(1,t)},this.produceWithPatches=(t,n)=>{if(typeof t=="function")return(o,...l)=>this.produceWithPatches(o,a=>t(a,...l));let r,i;return[this.produce(t,n,(o,l)=>{r=o,i=l}),r,i]},typeof(e==null?void 0:e.autoFreeze)=="boolean"&&this.setAutoFreeze(e.autoFreeze),typeof(e==null?void 0:e.useStrictShallowCopy)=="boolean"&&this.setUseStrictShallowCopy(e.useStrictShallowCopy),typeof(e==null?void 0:e.useStrictIteration)=="boolean"&&this.setUseStrictIteration(e.useStrictIteration)}createDraft(e){Sn(e)||Yt(8),wr(e)&&(e=Pk(e));const t=ep(this),n=zu(e,void 0);return n[Pt].isManual_=!0,Au(t),n}finishDraft(e,t){const n=e&&e[Pt];(!n||!n.isManual_)&&Yt(9);const{scope_:r}=n;return Zf(r,t),tp(void 0,r)}setAutoFreeze(e){this.autoFreeze_=e}setUseStrictShallowCopy(e){this.useStrictShallowCopy_=e}setUseStrictIteration(e){this.useStrictIteration_=e}shouldUseStrictIteration(){return this.useStrictIteration_}applyPatches(e,t){let n;for(n=t.length-1;n>=0;n--){const i=t[n];if(i.path.length===0&&i.op==="replace"){e=i.value;break}}n>-1&&(t=t.slice(n+1));const r=xr("Patches").applyPatches_;return wr(e)?r(e,t):this.produce(e,i=>r(i,t))}};function zu(e,t){const n=Rs(e)?xr("MapSet").proxyMap_(e,t):Pl(e)?xr("MapSet").proxySet_(e,t):Tk(e,t);return(t?t.scope_:jg()).drafts_.push(n),n}function Pk(e){return wr(e)||Yt(10,e),Pg(e)}function Pg(e){if(!Sn(e)||Rl(e))return e;const t=e[Pt];let n,r=!0;if(t){if(!t.modified_)return t.base_;t.finalized_=!0,n=Mu(e,t.scope_.immer_.useStrictShallowCopy_),r=t.scope_.immer_.shouldUseStrictIteration()}else n=Mu(e,!0);return el(n,(i,s)=>{Tg(n,i,Pg(s))},r),t&&(t.finalized_=!1),n}var Rk=new _k,Rg=Rk.produce;function Og(e){return({dispatch:n,getState:r})=>i=>s=>typeof s=="function"?s(n,r,e):i(s)}var Ok=Og(),Lk=Og,Ik=typeof window<"u"&&window.__REDUX_DEVTOOLS_EXTENSION_COMPOSE__?window.__REDUX_DEVTOOLS_EXTENSION_COMPOSE__:function(){if(arguments.length!==0)return typeof arguments[0]=="object"?Zo:Zo.apply(null,arguments)};function rp(e,t){function n(...r){if(t){let i=t(...r);if(!i)throw new Error(vn(0));return{type:e,payload:i.payload,..."meta"in i&&{meta:i.meta},..."error"in i&&{error:i.error}}}return{type:e,payload:r[0]}}return n.toString=()=>`${e}`,n.type=e,n.match=r=>xk(r)&&r.type===e,n}var Lg=class zi extends Array{constructor(...t){super(...t),Object.setPrototypeOf(this,zi.prototype)}static get[Symbol.species](){return zi}concat(...t){return super.concat.apply(this,t)}prepend(...t){return t.length===1&&Array.isArray(t[0])?new zi(...t[0].concat(this)):new zi(...t.concat(this))}};function ip(e){return Sn(e)?Rg(e,()=>{}):e}function no(e,t,n){return e.has(t)?e.get(t):e.set(t,n(t)).get(t)}function Mk(e){return typeof e=="boolean"}var Dk=()=>function(t){const{thunk:n=!0,immutableCheck:r=!0,serializableCheck:i=!0,actionCreatorCheck:s=!0}=t??{};let o=new Lg;return n&&(Mk(n)?o.push(Ok):o.push(Lk(n.extraArgument))),o},Ak="RTK_autoBatch",sp=e=>t=>{setTimeout(t,e)},$k=(e={type:"raf"})=>t=>(...n)=>{const r=t(...n);let i=!0,s=!1,o=!1;const l=new Set,a=e.type==="tick"?queueMicrotask:e.type==="raf"?typeof window<"u"&&window.requestAnimationFrame?window.requestAnimationFrame:sp(10):e.type==="callback"?e.queueNotification:sp(e.timeout),u=()=>{o=!1,s&&(s=!1,l.forEach(d=>d()))};return Object.assign({},r,{subscribe(d){const f=()=>i&&d(),p=r.subscribe(f);return l.add(d),()=>{p(),l.delete(d)}},dispatch(d){var f;try{return i=!((f=d==null?void 0:d.meta)!=null&&f[Ak]),s=!i,s&&(o||(o=!0,a(u))),r.dispatch(d)}finally{i=!0}}})},zk=e=>function(n){const{autoBatch:r=!0}=n??{};let i=new Lg(e);return r&&i.push($k(typeof r=="object"?r:void 0)),i};function Fk(e){const t=Dk(),{reducer:n=void 0,middleware:r,devTools:i=!0,preloadedState:s=void 0,enhancers:o=void 0}=e||{};let l;if(typeof n=="function")l=n;else if(nd(n))l=yk(n);else throw new Error(vn(1));let a;typeof r=="function"?a=r(t):a=t();let u=Zo;i&&(u=Ik({trace:!1,...typeof i=="object"&&i}));const d=wk(...a),f=zk(d);let p=typeof o=="function"?o(f):f();const w=u(...p);return Cg(l,s,w)}function Ig(e){const t={},n=[];let r;const i={addCase(s,o){const l=typeof s=="string"?s:s.type;if(!l)throw new Error(vn(28));if(l in t)throw new Error(vn(29));return t[l]=o,i},addAsyncThunk(s,o){return o.pending&&(t[s.pending.type]=o.pending),o.rejected&&(t[s.rejected.type]=o.rejected),o.fulfilled&&(t[s.fulfilled.type]=o.fulfilled),o.settled&&n.push({matcher:s.settled,reducer:o.settled}),i},addMatcher(s,o){return n.push({matcher:s,reducer:o}),i},addDefaultCase(s){return r=s,i}};return e(i),[t,n,r]}function Uk(e){return typeof e=="function"}function Bk(e,t){let[n,r,i]=Ig(t),s;if(Uk(e))s=()=>ip(e());else{const l=ip(e);s=()=>l}function o(l=s(),a){let u=[n[a.type],...r.filter(({matcher:d})=>d(a)).map(({reducer:d})=>d)];return u.filter(d=>!!d).length===0&&(u=[i]),u.reduce((d,f)=>{if(f)if(wr(d)){const w=f(d,a);return w===void 0?d:w}else{if(Sn(d))return Rg(d,p=>f(p,a));{const p=f(d,a);if(p===void 0){if(d===null)return d;throw Error("A case reducer on a non-draftable value must not return undefined")}return p}}return d},l)}return o.getInitialState=s,o}var Wk=Symbol.for("rtk-slice-createasyncthunk");function Hk(e,t){return`${e}/${t}`}function Vk({creators:e}={}){var n;const t=(n=e==null?void 0:e.asyncThunk)==null?void 0:n[Wk];return function(i){const{name:s,reducerPath:o=s}=i;if(!s)throw new Error(vn(11));const l=(typeof i.reducers=="function"?i.reducers(qk()):i.reducers)||{},a=Object.keys(l),u={sliceCaseReducersByName:{},sliceCaseReducersByType:{},actionCreators:{},sliceMatchers:[]},d={addCase(C,j){const S=typeof C=="string"?C:C.type;if(!S)throw new Error(vn(12));if(S in u.sliceCaseReducersByType)throw new Error(vn(13));return u.sliceCaseReducersByType[S]=j,d},addMatcher(C,j){return u.sliceMatchers.push({matcher:C,reducer:j}),d},exposeAction(C,j){return u.actionCreators[C]=j,d},exposeCaseReducer(C,j){return u.sliceCaseReducersByName[C]=j,d}};a.forEach(C=>{const j=l[C],S={reducerName:C,type:Hk(s,C),createNotation:typeof i.reducers=="function"};Yk(j)?Xk(S,j,d,t):Gk(S,j,d)});function f(){const[C={},j=[],S=void 0]=typeof i.extraReducers=="function"?Ig(i.extraReducers):[i.extraReducers],N={...C,...u.sliceCaseReducersByType};return Bk(i.initialState,_=>{for(let D in N)_.addCase(D,N[D]);for(let D of u.sliceMatchers)_.addMatcher(D.matcher,D.reducer);for(let D of j)_.addMatcher(D.matcher,D.reducer);S&&_.addDefaultCase(S)})}const p=C=>C,w=new Map,h=new WeakMap;let v;function k(C,j){return v||(v=f()),v(C,j)}function g(){return v||(v=f()),v.getInitialState()}function m(C,j=!1){function S(_){let D=_[C];return typeof D>"u"&&j&&(D=no(h,S,g)),D}function N(_=p){const D=no(w,j,()=>new WeakMap);return no(D,_,()=>{const M={};for(const[q,X]of Object.entries(i.selectors??{}))M[q]=Qk(X,_,()=>no(h,_,g),j);return M})}return{reducerPath:C,getSelectors:N,get selectors(){return N(S)},selectSlice:S}}const y={name:s,reducer:k,actions:u.actionCreators,caseReducers:u.sliceCaseReducersByName,getInitialState:g,...m(o),injectInto(C,{reducerPath:j,...S}={}){const N=j??o;return C.inject({reducerPath:N,reducer:k},S),{...y,...m(N,!0)}}};return y}}function Qk(e,t,n,r){function i(s,...o){let l=t(s);return typeof l>"u"&&r&&(l=n()),e(l,...o)}return i.unwrapped=e,i}var Ol=Vk();function qk(){function e(t,n){return{_reducerDefinitionType:"asyncThunk",payloadCreator:t,...n}}return e.withTypes=()=>e,{reducer(t){return Object.assign({[t.name](...n){return t(...n)}}[t.name],{_reducerDefinitionType:"reducer"})},preparedReducer(t,n){return{_reducerDefinitionType:"reducerWithPrepare",prepare:t,reducer:n}},asyncThunk:e}}function Gk({type:e,reducerName:t,createNotation:n},r,i){let s,o;if("reducer"in r){if(n&&!Kk(r))throw new Error(vn(17));s=r.reducer,o=r.prepare}else s=r;i.addCase(e,s).exposeCaseReducer(t,s).exposeAction(t,o?rp(e,o):rp(e))}function Yk(e){return e._reducerDefinitionType==="asyncThunk"}function Kk(e){return e._reducerDefinitionType==="reducerWithPrepare"}function Xk({type:e,reducerName:t},n,r,i){if(!i)throw new Error(vn(18));const{payloadCreator:s,fulfilled:o,pending:l,rejected:a,settled:u,options:d}=n,f=i(e,s,d);r.exposeAction(t,f),o&&r.addCase(f.fulfilled,o),l&&r.addCase(f.pending,l),a&&r.addCase(f.rejected,a),u&&r.addMatcher(f.settled,u),r.exposeCaseReducer(t,{fulfilled:o||ro,pending:l||ro,rejected:a||ro,settled:u||ro})}function ro(){}function vn(e){return`Minified Redux Toolkit error #${e}; visit https://redux-toolkit.js.org/Errors?code=${e} for the full message or use the non-minified dev environment for full errors. `}const Jk={isAuthenticated:localStorage.getItem("isAuthenticated")==="true",userId:null,username:localStorage.getItem("username")||null,loading:!1},Mg=Ol({name:"auth",initialState:Jk,reducers:{setAuth:(e,t)=>{e.isAuthenticated=!0,e.userId=t.payload.userId,e.username=t.payload.username,localStorage.setItem("isAuthenticated","true"),localStorage.setItem("username",t.payload.username)},clearAuth:e=>{e.isAuthenticated=!1,e.userId=null,e.username=null,localStorage.removeItem("isAuthenticated"),localStorage.removeItem("username")}}}),{setAuth:sd,clearAuth:fr}=Mg.actions,Zk=Mg.reducer,e1={notes:[],allNotes:[],archivedNotes:[],selectedDate:null,selectedTag:null,searchQuery:"",loading:!1,editingNoteId:null},Dg=Ol({name:"notes",initialState:e1,reducers:{setNotes:(e,t)=>{e.notes=t.payload},setAllNotes:(e,t)=>{e.allNotes=t.payload},addNote:(e,t)=>{e.notes.unshift(t.payload),e.allNotes.unshift(t.payload)},updateNote:(e,t)=>{const n=e.notes.findIndex(i=>i.id===t.payload.id);n!==-1&&(e.notes[n]=t.payload);const r=e.allNotes.findIndex(i=>i.id===t.payload.id);r!==-1&&(e.allNotes[r]=t.payload)},deleteNote:(e,t)=>{e.notes=e.notes.filter(n=>n.id!==t.payload),e.allNotes=e.allNotes.filter(n=>n.id!==t.payload)},setSelectedDate:(e,t)=>{e.selectedDate=t.payload},setSelectedTag:(e,t)=>{e.selectedTag=t.payload},setSearchQuery:(e,t)=>{e.searchQuery=t.payload},setEditingNote:(e,t)=>{e.editingNoteId=t.payload}}}),{setNotes:t1,setAllNotes:n1,addNote:fT,updateNote:pT,deleteNote:hT,setSelectedDate:Fu,setSelectedTag:rl,setSearchQuery:Uu,setEditingNote:mT}=Dg.actions,r1=Dg.reducer,i1=()=>{const e=localStorage.getItem("theme");return e==="dark"||e==="light"?e:window.matchMedia("(prefers-color-scheme: dark)").matches?"dark":"light"},s1={theme:i1(),accentColor:localStorage.getItem("accentColor")||"#007bff",notifications:[],isMobileSidebarOpen:!1,isPreviewMode:!1},Ag=Ol({name:"ui",initialState:s1,reducers:{toggleTheme:e=>{e.theme=e.theme==="light"?"dark":"light",localStorage.setItem("theme",e.theme)},setTheme:(e,t)=>{e.theme=t.payload,localStorage.setItem("theme",e.theme)},setAccentColor:(e,t)=>{e.accentColor=t.payload,localStorage.setItem("accentColor",t.payload)},addNotification:(e,t)=>{const n=`notification-${Date.now()}-${Math.random().toString(36).substr(2,9)}`;e.notifications.push({...t.payload,id:n})},removeNotification:(e,t)=>{e.notifications=e.notifications.filter(n=>n.id!==t.payload)},toggleMobileSidebar:e=>{e.isMobileSidebarOpen=!e.isMobileSidebarOpen},closeMobileSidebar:e=>{e.isMobileSidebarOpen=!1},togglePreviewMode:e=>{e.isPreviewMode=!e.isPreviewMode}}}),{toggleTheme:o1,setTheme:l1,setAccentColor:il,addNotification:a1,removeNotification:$g,toggleMobileSidebar:gT,closeMobileSidebar:vT,togglePreviewMode:u1}=Ag.actions,c1=Ag.reducer,d1={user:null,aiSettings:null,aiEnabled:!1,loading:!1},zg=Ol({name:"profile",initialState:d1,reducers:{setUser:(e,t)=>{e.user=t.payload},setAiSettings:(e,t)=>{e.aiSettings=t.payload,e.aiEnabled=t.payload.ai_enabled===1},setLoading:(e,t)=>{e.loading=t.payload}}}),{setUser:od,setAiSettings:ld,setLoading:yT}=zg.actions,f1=zg.reducer,p1=Fk({reducer:{auth:Zk,notes:r1,ui:c1,profile:f1}}),ot=()=>dk(),ye=hk;function Fg(e,t){return function(){return e.apply(t,arguments)}}const{toString:h1}=Object.prototype,{getPrototypeOf:ad}=Object,{iterator:Ll,toStringTag:Ug}=Symbol,Il=(e=>t=>{const n=h1.call(t);return e[n]||(e[n]=n.slice(8,-1).toLowerCase())})(Object.create(null)),en=e=>(e=e.toLowerCase(),t=>Il(t)===e),Ml=e=>t=>typeof t===e,{isArray:di}=Array,ri=Ml("undefined");function Os(e){return e!==null&&!ri(e)&&e.constructor!==null&&!ri(e.constructor)&&kt(e.constructor.isBuffer)&&e.constructor.isBuffer(e)}const Bg=en("ArrayBuffer");function m1(e){let t;return typeof ArrayBuffer<"u"&&ArrayBuffer.isView?t=ArrayBuffer.isView(e):t=e&&e.buffer&&Bg(e.buffer),t}const g1=Ml("string"),kt=Ml("function"),Wg=Ml("number"),Ls=e=>e!==null&&typeof e=="object",v1=e=>e===!0||e===!1,So=e=>{if(Il(e)!=="object")return!1;const t=ad(e);return(t===null||t===Object.prototype||Object.getPrototypeOf(t)===null)&&!(Ug in e)&&!(Ll in e)},y1=e=>{if(!Ls(e)||Os(e))return!1;try{return Object.keys(e).length===0&&Object.getPrototypeOf(e)===Object.prototype}catch{return!1}},w1=en("Date"),x1=en("File"),k1=en("Blob"),S1=en("FileList"),E1=e=>Ls(e)&&kt(e.pipe),C1=e=>{let t;return e&&(typeof FormData=="function"&&e instanceof FormData||kt(e.append)&&((t=Il(e))==="formdata"||t==="object"&&kt(e.toString)&&e.toString()==="[object FormData]"))},b1=en("URLSearchParams"),[N1,T1,j1,_1]=["ReadableStream","Request","Response","Headers"].map(en),P1=e=>e.trim?e.trim():e.replace(/^[\s\uFEFF\xA0]+|[\s\uFEFF\xA0]+$/g,"");function Is(e,t,{allOwnKeys:n=!1}={}){if(e===null||typeof e>"u")return;let r,i;if(typeof e!="object"&&(e=[e]),di(e))for(r=0,i=e.length;r0;)if(i=n[r],t===i.toLowerCase())return i;return null}const ur=typeof globalThis<"u"?globalThis:typeof self<"u"?self:typeof window<"u"?window:global,Vg=e=>!ri(e)&&e!==ur;function Bu(){const{caseless:e,skipUndefined:t}=Vg(this)&&this||{},n={},r=(i,s)=>{const o=e&&Hg(n,s)||s;So(n[o])&&So(i)?n[o]=Bu(n[o],i):So(i)?n[o]=Bu({},i):di(i)?n[o]=i.slice():(!t||!ri(i))&&(n[o]=i)};for(let i=0,s=arguments.length;i(Is(t,(i,s)=>{n&&kt(i)?e[s]=Fg(i,n):e[s]=i},{allOwnKeys:r}),e),O1=e=>(e.charCodeAt(0)===65279&&(e=e.slice(1)),e),L1=(e,t,n,r)=>{e.prototype=Object.create(t.prototype,r),e.prototype.constructor=e,Object.defineProperty(e,"super",{value:t.prototype}),n&&Object.assign(e.prototype,n)},I1=(e,t,n,r)=>{let i,s,o;const l={};if(t=t||{},e==null)return t;do{for(i=Object.getOwnPropertyNames(e),s=i.length;s-- >0;)o=i[s],(!r||r(o,e,t))&&!l[o]&&(t[o]=e[o],l[o]=!0);e=n!==!1&&ad(e)}while(e&&(!n||n(e,t))&&e!==Object.prototype);return t},M1=(e,t,n)=>{e=String(e),(n===void 0||n>e.length)&&(n=e.length),n-=t.length;const r=e.indexOf(t,n);return r!==-1&&r===n},D1=e=>{if(!e)return null;if(di(e))return e;let t=e.length;if(!Wg(t))return null;const n=new Array(t);for(;t-- >0;)n[t]=e[t];return n},A1=(e=>t=>e&&t instanceof e)(typeof Uint8Array<"u"&&ad(Uint8Array)),$1=(e,t)=>{const r=(e&&e[Ll]).call(e);let i;for(;(i=r.next())&&!i.done;){const s=i.value;t.call(e,s[0],s[1])}},z1=(e,t)=>{let n;const r=[];for(;(n=e.exec(t))!==null;)r.push(n);return r},F1=en("HTMLFormElement"),U1=e=>e.toLowerCase().replace(/[-_\s]([a-z\d])(\w*)/g,function(n,r,i){return r.toUpperCase()+i}),op=(({hasOwnProperty:e})=>(t,n)=>e.call(t,n))(Object.prototype),B1=en("RegExp"),Qg=(e,t)=>{const n=Object.getOwnPropertyDescriptors(e),r={};Is(n,(i,s)=>{let o;(o=t(i,s,e))!==!1&&(r[s]=o||i)}),Object.defineProperties(e,r)},W1=e=>{Qg(e,(t,n)=>{if(kt(e)&&["arguments","caller","callee"].indexOf(n)!==-1)return!1;const r=e[n];if(kt(r)){if(t.enumerable=!1,"writable"in t){t.writable=!1;return}t.set||(t.set=()=>{throw Error("Can not rewrite read-only method '"+n+"'")})}})},H1=(e,t)=>{const n={},r=i=>{i.forEach(s=>{n[s]=!0})};return di(e)?r(e):r(String(e).split(t)),n},V1=()=>{},Q1=(e,t)=>e!=null&&Number.isFinite(e=+e)?e:t;function q1(e){return!!(e&&kt(e.append)&&e[Ug]==="FormData"&&e[Ll])}const G1=e=>{const t=new Array(10),n=(r,i)=>{if(Ls(r)){if(t.indexOf(r)>=0)return;if(Os(r))return r;if(!("toJSON"in r)){t[i]=r;const s=di(r)?[]:{};return Is(r,(o,l)=>{const a=n(o,i+1);!ri(a)&&(s[l]=a)}),t[i]=void 0,s}}return r};return n(e,0)},Y1=en("AsyncFunction"),K1=e=>e&&(Ls(e)||kt(e))&&kt(e.then)&&kt(e.catch),qg=((e,t)=>e?setImmediate:t?((n,r)=>(ur.addEventListener("message",({source:i,data:s})=>{i===ur&&s===n&&r.length&&r.shift()()},!1),i=>{r.push(i),ur.postMessage(n,"*")}))(`axios@${Math.random()}`,[]):n=>setTimeout(n))(typeof setImmediate=="function",kt(ur.postMessage)),X1=typeof queueMicrotask<"u"?queueMicrotask.bind(ur):typeof process<"u"&&process.nextTick||qg,J1=e=>e!=null&&kt(e[Ll]),T={isArray:di,isArrayBuffer:Bg,isBuffer:Os,isFormData:C1,isArrayBufferView:m1,isString:g1,isNumber:Wg,isBoolean:v1,isObject:Ls,isPlainObject:So,isEmptyObject:y1,isReadableStream:N1,isRequest:T1,isResponse:j1,isHeaders:_1,isUndefined:ri,isDate:w1,isFile:x1,isBlob:k1,isRegExp:B1,isFunction:kt,isStream:E1,isURLSearchParams:b1,isTypedArray:A1,isFileList:S1,forEach:Is,merge:Bu,extend:R1,trim:P1,stripBOM:O1,inherits:L1,toFlatObject:I1,kindOf:Il,kindOfTest:en,endsWith:M1,toArray:D1,forEachEntry:$1,matchAll:z1,isHTMLForm:F1,hasOwnProperty:op,hasOwnProp:op,reduceDescriptors:Qg,freezeMethods:W1,toObjectSet:H1,toCamelCase:U1,noop:V1,toFiniteNumber:Q1,findKey:Hg,global:ur,isContextDefined:Vg,isSpecCompliantForm:q1,toJSONObject:G1,isAsyncFn:Y1,isThenable:K1,setImmediate:qg,asap:X1,isIterable:J1};function ee(e,t,n,r,i){Error.call(this),Error.captureStackTrace?Error.captureStackTrace(this,this.constructor):this.stack=new Error().stack,this.message=e,this.name="AxiosError",t&&(this.code=t),n&&(this.config=n),r&&(this.request=r),i&&(this.response=i,this.status=i.status?i.status:null)}T.inherits(ee,Error,{toJSON:function(){return{message:this.message,name:this.name,description:this.description,number:this.number,fileName:this.fileName,lineNumber:this.lineNumber,columnNumber:this.columnNumber,stack:this.stack,config:T.toJSONObject(this.config),code:this.code,status:this.status}}});const Gg=ee.prototype,Yg={};["ERR_BAD_OPTION_VALUE","ERR_BAD_OPTION","ECONNABORTED","ETIMEDOUT","ERR_NETWORK","ERR_FR_TOO_MANY_REDIRECTS","ERR_DEPRECATED","ERR_BAD_RESPONSE","ERR_BAD_REQUEST","ERR_CANCELED","ERR_NOT_SUPPORT","ERR_INVALID_URL"].forEach(e=>{Yg[e]={value:e}});Object.defineProperties(ee,Yg);Object.defineProperty(Gg,"isAxiosError",{value:!0});ee.from=(e,t,n,r,i,s)=>{const o=Object.create(Gg);T.toFlatObject(e,o,function(d){return d!==Error.prototype},u=>u!=="isAxiosError");const l=e&&e.message?e.message:"Error",a=t==null&&e?e.code:t;return ee.call(o,l,a,n,r,i),e&&o.cause==null&&Object.defineProperty(o,"cause",{value:e,configurable:!0}),o.name=e&&e.name||"Error",s&&Object.assign(o,s),o};const Z1=null;function Wu(e){return T.isPlainObject(e)||T.isArray(e)}function Kg(e){return T.endsWith(e,"[]")?e.slice(0,-2):e}function lp(e,t,n){return e?e.concat(t).map(function(i,s){return i=Kg(i),!n&&s?"["+i+"]":i}).join(n?".":""):t}function eS(e){return T.isArray(e)&&!e.some(Wu)}const tS=T.toFlatObject(T,{},null,function(t){return/^is[A-Z]/.test(t)});function Dl(e,t,n){if(!T.isObject(e))throw new TypeError("target must be an object");t=t||new FormData,n=T.toFlatObject(n,{metaTokens:!0,dots:!1,indexes:!1},!1,function(v,k){return!T.isUndefined(k[v])});const r=n.metaTokens,i=n.visitor||d,s=n.dots,o=n.indexes,a=(n.Blob||typeof Blob<"u"&&Blob)&&T.isSpecCompliantForm(t);if(!T.isFunction(i))throw new TypeError("visitor must be a function");function u(h){if(h===null)return"";if(T.isDate(h))return h.toISOString();if(T.isBoolean(h))return h.toString();if(!a&&T.isBlob(h))throw new ee("Blob is not supported. Use a Buffer instead.");return T.isArrayBuffer(h)||T.isTypedArray(h)?a&&typeof Blob=="function"?new Blob([h]):Buffer.from(h):h}function d(h,v,k){let g=h;if(h&&!k&&typeof h=="object"){if(T.endsWith(v,"{}"))v=r?v:v.slice(0,-2),h=JSON.stringify(h);else if(T.isArray(h)&&eS(h)||(T.isFileList(h)||T.endsWith(v,"[]"))&&(g=T.toArray(h)))return v=Kg(v),g.forEach(function(y,C){!(T.isUndefined(y)||y===null)&&t.append(o===!0?lp([v],C,s):o===null?v:v+"[]",u(y))}),!1}return Wu(h)?!0:(t.append(lp(k,v,s),u(h)),!1)}const f=[],p=Object.assign(tS,{defaultVisitor:d,convertValue:u,isVisitable:Wu});function w(h,v){if(!T.isUndefined(h)){if(f.indexOf(h)!==-1)throw Error("Circular reference detected in "+v.join("."));f.push(h),T.forEach(h,function(g,m){(!(T.isUndefined(g)||g===null)&&i.call(t,g,T.isString(m)?m.trim():m,v,p))===!0&&w(g,v?v.concat(m):[m])}),f.pop()}}if(!T.isObject(e))throw new TypeError("data must be an object");return w(e),t}function ap(e){const t={"!":"%21","'":"%27","(":"%28",")":"%29","~":"%7E","%20":"+","%00":"\0"};return encodeURIComponent(e).replace(/[!'()~]|%20|%00/g,function(r){return t[r]})}function ud(e,t){this._pairs=[],e&&Dl(e,this,t)}const Xg=ud.prototype;Xg.append=function(t,n){this._pairs.push([t,n])};Xg.toString=function(t){const n=t?function(r){return t.call(this,r,ap)}:ap;return this._pairs.map(function(i){return n(i[0])+"="+n(i[1])},"").join("&")};function nS(e){return encodeURIComponent(e).replace(/%3A/gi,":").replace(/%24/g,"$").replace(/%2C/gi,",").replace(/%20/g,"+")}function Jg(e,t,n){if(!t)return e;const r=n&&n.encode||nS;T.isFunction(n)&&(n={serialize:n});const i=n&&n.serialize;let s;if(i?s=i(t,n):s=T.isURLSearchParams(t)?t.toString():new ud(t,n).toString(r),s){const o=e.indexOf("#");o!==-1&&(e=e.slice(0,o)),e+=(e.indexOf("?")===-1?"?":"&")+s}return e}class up{constructor(){this.handlers=[]}use(t,n,r){return this.handlers.push({fulfilled:t,rejected:n,synchronous:r?r.synchronous:!1,runWhen:r?r.runWhen:null}),this.handlers.length-1}eject(t){this.handlers[t]&&(this.handlers[t]=null)}clear(){this.handlers&&(this.handlers=[])}forEach(t){T.forEach(this.handlers,function(r){r!==null&&t(r)})}}const Zg={silentJSONParsing:!0,forcedJSONParsing:!0,clarifyTimeoutError:!1},rS=typeof URLSearchParams<"u"?URLSearchParams:ud,iS=typeof FormData<"u"?FormData:null,sS=typeof Blob<"u"?Blob:null,oS={isBrowser:!0,classes:{URLSearchParams:rS,FormData:iS,Blob:sS},protocols:["http","https","file","blob","url","data"]},cd=typeof window<"u"&&typeof document<"u",Hu=typeof navigator=="object"&&navigator||void 0,lS=cd&&(!Hu||["ReactNative","NativeScript","NS"].indexOf(Hu.product)<0),aS=typeof WorkerGlobalScope<"u"&&self instanceof WorkerGlobalScope&&typeof self.importScripts=="function",uS=cd&&window.location.href||"http://localhost",cS=Object.freeze(Object.defineProperty({__proto__:null,hasBrowserEnv:cd,hasStandardBrowserEnv:lS,hasStandardBrowserWebWorkerEnv:aS,navigator:Hu,origin:uS},Symbol.toStringTag,{value:"Module"})),it={...cS,...oS};function dS(e,t){return Dl(e,new it.classes.URLSearchParams,{visitor:function(n,r,i,s){return it.isNode&&T.isBuffer(n)?(this.append(r,n.toString("base64")),!1):s.defaultVisitor.apply(this,arguments)},...t})}function fS(e){return T.matchAll(/\w+|\[(\w*)]/g,e).map(t=>t[0]==="[]"?"":t[1]||t[0])}function pS(e){const t={},n=Object.keys(e);let r;const i=n.length;let s;for(r=0;r=n.length;return o=!o&&T.isArray(i)?i.length:o,a?(T.hasOwnProp(i,o)?i[o]=[i[o],r]:i[o]=r,!l):((!i[o]||!T.isObject(i[o]))&&(i[o]=[]),t(n,r,i[o],s)&&T.isArray(i[o])&&(i[o]=pS(i[o])),!l)}if(T.isFormData(e)&&T.isFunction(e.entries)){const n={};return T.forEachEntry(e,(r,i)=>{t(fS(r),i,n,0)}),n}return null}function hS(e,t,n){if(T.isString(e))try{return(t||JSON.parse)(e),T.trim(e)}catch(r){if(r.name!=="SyntaxError")throw r}return(n||JSON.stringify)(e)}const Ms={transitional:Zg,adapter:["xhr","http","fetch"],transformRequest:[function(t,n){const r=n.getContentType()||"",i=r.indexOf("application/json")>-1,s=T.isObject(t);if(s&&T.isHTMLForm(t)&&(t=new FormData(t)),T.isFormData(t))return i?JSON.stringify(ev(t)):t;if(T.isArrayBuffer(t)||T.isBuffer(t)||T.isStream(t)||T.isFile(t)||T.isBlob(t)||T.isReadableStream(t))return t;if(T.isArrayBufferView(t))return t.buffer;if(T.isURLSearchParams(t))return n.setContentType("application/x-www-form-urlencoded;charset=utf-8",!1),t.toString();let l;if(s){if(r.indexOf("application/x-www-form-urlencoded")>-1)return dS(t,this.formSerializer).toString();if((l=T.isFileList(t))||r.indexOf("multipart/form-data")>-1){const a=this.env&&this.env.FormData;return Dl(l?{"files[]":t}:t,a&&new a,this.formSerializer)}}return s||i?(n.setContentType("application/json",!1),hS(t)):t}],transformResponse:[function(t){const n=this.transitional||Ms.transitional,r=n&&n.forcedJSONParsing,i=this.responseType==="json";if(T.isResponse(t)||T.isReadableStream(t))return t;if(t&&T.isString(t)&&(r&&!this.responseType||i)){const o=!(n&&n.silentJSONParsing)&&i;try{return JSON.parse(t,this.parseReviver)}catch(l){if(o)throw l.name==="SyntaxError"?ee.from(l,ee.ERR_BAD_RESPONSE,this,null,this.response):l}}return t}],timeout:0,xsrfCookieName:"XSRF-TOKEN",xsrfHeaderName:"X-XSRF-TOKEN",maxContentLength:-1,maxBodyLength:-1,env:{FormData:it.classes.FormData,Blob:it.classes.Blob},validateStatus:function(t){return t>=200&&t<300},headers:{common:{Accept:"application/json, text/plain, */*","Content-Type":void 0}}};T.forEach(["delete","get","head","post","put","patch"],e=>{Ms.headers[e]={}});const mS=T.toObjectSet(["age","authorization","content-length","content-type","etag","expires","from","host","if-modified-since","if-unmodified-since","last-modified","location","max-forwards","proxy-authorization","referer","retry-after","user-agent"]),gS=e=>{const t={};let n,r,i;return e&&e.split(` +`).forEach(function(o){i=o.indexOf(":"),n=o.substring(0,i).trim().toLowerCase(),r=o.substring(i+1).trim(),!(!n||t[n]&&mS[n])&&(n==="set-cookie"?t[n]?t[n].push(r):t[n]=[r]:t[n]=t[n]?t[n]+", "+r:r)}),t},cp=Symbol("internals");function _i(e){return e&&String(e).trim().toLowerCase()}function Eo(e){return e===!1||e==null?e:T.isArray(e)?e.map(Eo):String(e)}function vS(e){const t=Object.create(null),n=/([^\s,;=]+)\s*(?:=\s*([^,;]+))?/g;let r;for(;r=n.exec(e);)t[r[1]]=r[2];return t}const yS=e=>/^[-_a-zA-Z0-9^`|~,!#$%&'*+.]+$/.test(e.trim());function _a(e,t,n,r,i){if(T.isFunction(r))return r.call(this,t,n);if(i&&(t=n),!!T.isString(t)){if(T.isString(r))return t.indexOf(r)!==-1;if(T.isRegExp(r))return r.test(t)}}function wS(e){return e.trim().toLowerCase().replace(/([a-z\d])(\w*)/g,(t,n,r)=>n.toUpperCase()+r)}function xS(e,t){const n=T.toCamelCase(" "+t);["get","set","has"].forEach(r=>{Object.defineProperty(e,r+n,{value:function(i,s,o){return this[r].call(this,t,i,s,o)},configurable:!0})})}let St=class{constructor(t){t&&this.set(t)}set(t,n,r){const i=this;function s(l,a,u){const d=_i(a);if(!d)throw new Error("header name must be a non-empty string");const f=T.findKey(i,d);(!f||i[f]===void 0||u===!0||u===void 0&&i[f]!==!1)&&(i[f||a]=Eo(l))}const o=(l,a)=>T.forEach(l,(u,d)=>s(u,d,a));if(T.isPlainObject(t)||t instanceof this.constructor)o(t,n);else if(T.isString(t)&&(t=t.trim())&&!yS(t))o(gS(t),n);else if(T.isObject(t)&&T.isIterable(t)){let l={},a,u;for(const d of t){if(!T.isArray(d))throw TypeError("Object iterator must return a key-value pair");l[u=d[0]]=(a=l[u])?T.isArray(a)?[...a,d[1]]:[a,d[1]]:d[1]}o(l,n)}else t!=null&&s(n,t,r);return this}get(t,n){if(t=_i(t),t){const r=T.findKey(this,t);if(r){const i=this[r];if(!n)return i;if(n===!0)return vS(i);if(T.isFunction(n))return n.call(this,i,r);if(T.isRegExp(n))return n.exec(i);throw new TypeError("parser must be boolean|regexp|function")}}}has(t,n){if(t=_i(t),t){const r=T.findKey(this,t);return!!(r&&this[r]!==void 0&&(!n||_a(this,this[r],r,n)))}return!1}delete(t,n){const r=this;let i=!1;function s(o){if(o=_i(o),o){const l=T.findKey(r,o);l&&(!n||_a(r,r[l],l,n))&&(delete r[l],i=!0)}}return T.isArray(t)?t.forEach(s):s(t),i}clear(t){const n=Object.keys(this);let r=n.length,i=!1;for(;r--;){const s=n[r];(!t||_a(this,this[s],s,t,!0))&&(delete this[s],i=!0)}return i}normalize(t){const n=this,r={};return T.forEach(this,(i,s)=>{const o=T.findKey(r,s);if(o){n[o]=Eo(i),delete n[s];return}const l=t?wS(s):String(s).trim();l!==s&&delete n[s],n[l]=Eo(i),r[l]=!0}),this}concat(...t){return this.constructor.concat(this,...t)}toJSON(t){const n=Object.create(null);return T.forEach(this,(r,i)=>{r!=null&&r!==!1&&(n[i]=t&&T.isArray(r)?r.join(", "):r)}),n}[Symbol.iterator](){return Object.entries(this.toJSON())[Symbol.iterator]()}toString(){return Object.entries(this.toJSON()).map(([t,n])=>t+": "+n).join(` +`)}getSetCookie(){return this.get("set-cookie")||[]}get[Symbol.toStringTag](){return"AxiosHeaders"}static from(t){return t instanceof this?t:new this(t)}static concat(t,...n){const r=new this(t);return n.forEach(i=>r.set(i)),r}static accessor(t){const r=(this[cp]=this[cp]={accessors:{}}).accessors,i=this.prototype;function s(o){const l=_i(o);r[l]||(xS(i,o),r[l]=!0)}return T.isArray(t)?t.forEach(s):s(t),this}};St.accessor(["Content-Type","Content-Length","Accept","Accept-Encoding","User-Agent","Authorization"]);T.reduceDescriptors(St.prototype,({value:e},t)=>{let n=t[0].toUpperCase()+t.slice(1);return{get:()=>e,set(r){this[n]=r}}});T.freezeMethods(St);function Pa(e,t){const n=this||Ms,r=t||n,i=St.from(r.headers);let s=r.data;return T.forEach(e,function(l){s=l.call(n,s,i.normalize(),t?t.status:void 0)}),i.normalize(),s}function tv(e){return!!(e&&e.__CANCEL__)}function fi(e,t,n){ee.call(this,e??"canceled",ee.ERR_CANCELED,t,n),this.name="CanceledError"}T.inherits(fi,ee,{__CANCEL__:!0});function nv(e,t,n){const r=n.config.validateStatus;!n.status||!r||r(n.status)?e(n):t(new ee("Request failed with status code "+n.status,[ee.ERR_BAD_REQUEST,ee.ERR_BAD_RESPONSE][Math.floor(n.status/100)-4],n.config,n.request,n))}function kS(e){const t=/^([-+\w]{1,25})(:?\/\/|:)/.exec(e);return t&&t[1]||""}function SS(e,t){e=e||10;const n=new Array(e),r=new Array(e);let i=0,s=0,o;return t=t!==void 0?t:1e3,function(a){const u=Date.now(),d=r[s];o||(o=u),n[i]=a,r[i]=u;let f=s,p=0;for(;f!==i;)p+=n[f++],f=f%e;if(i=(i+1)%e,i===s&&(s=(s+1)%e),u-o{n=d,i=null,s&&(clearTimeout(s),s=null),e(...u)};return[(...u)=>{const d=Date.now(),f=d-n;f>=r?o(u,d):(i=u,s||(s=setTimeout(()=>{s=null,o(i)},r-f)))},()=>i&&o(i)]}const sl=(e,t,n=3)=>{let r=0;const i=SS(50,250);return ES(s=>{const o=s.loaded,l=s.lengthComputable?s.total:void 0,a=o-r,u=i(a),d=o<=l;r=o;const f={loaded:o,total:l,progress:l?o/l:void 0,bytes:a,rate:u||void 0,estimated:u&&l&&d?(l-o)/u:void 0,event:s,lengthComputable:l!=null,[t?"download":"upload"]:!0};e(f)},n)},dp=(e,t)=>{const n=e!=null;return[r=>t[0]({lengthComputable:n,total:e,loaded:r}),t[1]]},fp=e=>(...t)=>T.asap(()=>e(...t)),CS=it.hasStandardBrowserEnv?((e,t)=>n=>(n=new URL(n,it.origin),e.protocol===n.protocol&&e.host===n.host&&(t||e.port===n.port)))(new URL(it.origin),it.navigator&&/(msie|trident)/i.test(it.navigator.userAgent)):()=>!0,bS=it.hasStandardBrowserEnv?{write(e,t,n,r,i,s,o){if(typeof document>"u")return;const l=[`${e}=${encodeURIComponent(t)}`];T.isNumber(n)&&l.push(`expires=${new Date(n).toUTCString()}`),T.isString(r)&&l.push(`path=${r}`),T.isString(i)&&l.push(`domain=${i}`),s===!0&&l.push("secure"),T.isString(o)&&l.push(`SameSite=${o}`),document.cookie=l.join("; ")},read(e){if(typeof document>"u")return null;const t=document.cookie.match(new RegExp("(?:^|; )"+e+"=([^;]*)"));return t?decodeURIComponent(t[1]):null},remove(e){this.write(e,"",Date.now()-864e5,"/")}}:{write(){},read(){return null},remove(){}};function NS(e){return/^([a-z][a-z\d+\-.]*:)?\/\//i.test(e)}function TS(e,t){return t?e.replace(/\/?\/$/,"")+"/"+t.replace(/^\/+/,""):e}function rv(e,t,n){let r=!NS(t);return e&&(r||n==!1)?TS(e,t):t}const pp=e=>e instanceof St?{...e}:e;function kr(e,t){t=t||{};const n={};function r(u,d,f,p){return T.isPlainObject(u)&&T.isPlainObject(d)?T.merge.call({caseless:p},u,d):T.isPlainObject(d)?T.merge({},d):T.isArray(d)?d.slice():d}function i(u,d,f,p){if(T.isUndefined(d)){if(!T.isUndefined(u))return r(void 0,u,f,p)}else return r(u,d,f,p)}function s(u,d){if(!T.isUndefined(d))return r(void 0,d)}function o(u,d){if(T.isUndefined(d)){if(!T.isUndefined(u))return r(void 0,u)}else return r(void 0,d)}function l(u,d,f){if(f in t)return r(u,d);if(f in e)return r(void 0,u)}const a={url:s,method:s,data:s,baseURL:o,transformRequest:o,transformResponse:o,paramsSerializer:o,timeout:o,timeoutMessage:o,withCredentials:o,withXSRFToken:o,adapter:o,responseType:o,xsrfCookieName:o,xsrfHeaderName:o,onUploadProgress:o,onDownloadProgress:o,decompress:o,maxContentLength:o,maxBodyLength:o,beforeRedirect:o,transport:o,httpAgent:o,httpsAgent:o,cancelToken:o,socketPath:o,responseEncoding:o,validateStatus:l,headers:(u,d,f)=>i(pp(u),pp(d),f,!0)};return T.forEach(Object.keys({...e,...t}),function(d){const f=a[d]||i,p=f(e[d],t[d],d);T.isUndefined(p)&&f!==l||(n[d]=p)}),n}const iv=e=>{const t=kr({},e);let{data:n,withXSRFToken:r,xsrfHeaderName:i,xsrfCookieName:s,headers:o,auth:l}=t;if(t.headers=o=St.from(o),t.url=Jg(rv(t.baseURL,t.url,t.allowAbsoluteUrls),e.params,e.paramsSerializer),l&&o.set("Authorization","Basic "+btoa((l.username||"")+":"+(l.password?unescape(encodeURIComponent(l.password)):""))),T.isFormData(n)){if(it.hasStandardBrowserEnv||it.hasStandardBrowserWebWorkerEnv)o.setContentType(void 0);else if(T.isFunction(n.getHeaders)){const a=n.getHeaders(),u=["content-type","content-length"];Object.entries(a).forEach(([d,f])=>{u.includes(d.toLowerCase())&&o.set(d,f)})}}if(it.hasStandardBrowserEnv&&(r&&T.isFunction(r)&&(r=r(t)),r||r!==!1&&CS(t.url))){const a=i&&s&&bS.read(s);a&&o.set(i,a)}return t},jS=typeof XMLHttpRequest<"u",_S=jS&&function(e){return new Promise(function(n,r){const i=iv(e);let s=i.data;const o=St.from(i.headers).normalize();let{responseType:l,onUploadProgress:a,onDownloadProgress:u}=i,d,f,p,w,h;function v(){w&&w(),h&&h(),i.cancelToken&&i.cancelToken.unsubscribe(d),i.signal&&i.signal.removeEventListener("abort",d)}let k=new XMLHttpRequest;k.open(i.method.toUpperCase(),i.url,!0),k.timeout=i.timeout;function g(){if(!k)return;const y=St.from("getAllResponseHeaders"in k&&k.getAllResponseHeaders()),j={data:!l||l==="text"||l==="json"?k.responseText:k.response,status:k.status,statusText:k.statusText,headers:y,config:e,request:k};nv(function(N){n(N),v()},function(N){r(N),v()},j),k=null}"onloadend"in k?k.onloadend=g:k.onreadystatechange=function(){!k||k.readyState!==4||k.status===0&&!(k.responseURL&&k.responseURL.indexOf("file:")===0)||setTimeout(g)},k.onabort=function(){k&&(r(new ee("Request aborted",ee.ECONNABORTED,e,k)),k=null)},k.onerror=function(C){const j=C&&C.message?C.message:"Network Error",S=new ee(j,ee.ERR_NETWORK,e,k);S.event=C||null,r(S),k=null},k.ontimeout=function(){let C=i.timeout?"timeout of "+i.timeout+"ms exceeded":"timeout exceeded";const j=i.transitional||Zg;i.timeoutErrorMessage&&(C=i.timeoutErrorMessage),r(new ee(C,j.clarifyTimeoutError?ee.ETIMEDOUT:ee.ECONNABORTED,e,k)),k=null},s===void 0&&o.setContentType(null),"setRequestHeader"in k&&T.forEach(o.toJSON(),function(C,j){k.setRequestHeader(j,C)}),T.isUndefined(i.withCredentials)||(k.withCredentials=!!i.withCredentials),l&&l!=="json"&&(k.responseType=i.responseType),u&&([p,h]=sl(u,!0),k.addEventListener("progress",p)),a&&k.upload&&([f,w]=sl(a),k.upload.addEventListener("progress",f),k.upload.addEventListener("loadend",w)),(i.cancelToken||i.signal)&&(d=y=>{k&&(r(!y||y.type?new fi(null,e,k):y),k.abort(),k=null)},i.cancelToken&&i.cancelToken.subscribe(d),i.signal&&(i.signal.aborted?d():i.signal.addEventListener("abort",d)));const m=kS(i.url);if(m&&it.protocols.indexOf(m)===-1){r(new ee("Unsupported protocol "+m+":",ee.ERR_BAD_REQUEST,e));return}k.send(s||null)})},PS=(e,t)=>{const{length:n}=e=e?e.filter(Boolean):[];if(t||n){let r=new AbortController,i;const s=function(u){if(!i){i=!0,l();const d=u instanceof Error?u:this.reason;r.abort(d instanceof ee?d:new fi(d instanceof Error?d.message:d))}};let o=t&&setTimeout(()=>{o=null,s(new ee(`timeout ${t} of ms exceeded`,ee.ETIMEDOUT))},t);const l=()=>{e&&(o&&clearTimeout(o),o=null,e.forEach(u=>{u.unsubscribe?u.unsubscribe(s):u.removeEventListener("abort",s)}),e=null)};e.forEach(u=>u.addEventListener("abort",s));const{signal:a}=r;return a.unsubscribe=()=>T.asap(l),a}},RS=function*(e,t){let n=e.byteLength;if(n{const i=OS(e,t);let s=0,o,l=a=>{o||(o=!0,r&&r(a))};return new ReadableStream({async pull(a){try{const{done:u,value:d}=await i.next();if(u){l(),a.close();return}let f=d.byteLength;if(n){let p=s+=f;n(p)}a.enqueue(new Uint8Array(d))}catch(u){throw l(u),u}},cancel(a){return l(a),i.return()}},{highWaterMark:2})},mp=64*1024,{isFunction:io}=T,IS=(({Request:e,Response:t})=>({Request:e,Response:t}))(T.global),{ReadableStream:gp,TextEncoder:vp}=T.global,yp=(e,...t)=>{try{return!!e(...t)}catch{return!1}},MS=e=>{e=T.merge.call({skipUndefined:!0},IS,e);const{fetch:t,Request:n,Response:r}=e,i=t?io(t):typeof fetch=="function",s=io(n),o=io(r);if(!i)return!1;const l=i&&io(gp),a=i&&(typeof vp=="function"?(h=>v=>h.encode(v))(new vp):async h=>new Uint8Array(await new n(h).arrayBuffer())),u=s&&l&&yp(()=>{let h=!1;const v=new n(it.origin,{body:new gp,method:"POST",get duplex(){return h=!0,"half"}}).headers.has("Content-Type");return h&&!v}),d=o&&l&&yp(()=>T.isReadableStream(new r("").body)),f={stream:d&&(h=>h.body)};i&&["text","arrayBuffer","blob","formData","stream"].forEach(h=>{!f[h]&&(f[h]=(v,k)=>{let g=v&&v[h];if(g)return g.call(v);throw new ee(`Response type '${h}' is not supported`,ee.ERR_NOT_SUPPORT,k)})});const p=async h=>{if(h==null)return 0;if(T.isBlob(h))return h.size;if(T.isSpecCompliantForm(h))return(await new n(it.origin,{method:"POST",body:h}).arrayBuffer()).byteLength;if(T.isArrayBufferView(h)||T.isArrayBuffer(h))return h.byteLength;if(T.isURLSearchParams(h)&&(h=h+""),T.isString(h))return(await a(h)).byteLength},w=async(h,v)=>{const k=T.toFiniteNumber(h.getContentLength());return k??p(v)};return async h=>{let{url:v,method:k,data:g,signal:m,cancelToken:y,timeout:C,onDownloadProgress:j,onUploadProgress:S,responseType:N,headers:_,withCredentials:D="same-origin",fetchOptions:M}=iv(h),q=t||fetch;N=N?(N+"").toLowerCase():"text";let X=PS([m,y&&y.toAbortSignal()],C),te=null;const K=X&&X.unsubscribe&&(()=>{X.unsubscribe()});let z;try{if(S&&u&&k!=="get"&&k!=="head"&&(z=await w(_,g))!==0){let L=new n(v,{method:"POST",body:g,duplex:"half"}),$;if(T.isFormData(g)&&($=L.headers.get("content-type"))&&_.setContentType($),L.body){const[H,G]=dp(z,sl(fp(S)));g=hp(L.body,mp,H,G)}}T.isString(D)||(D=D?"include":"omit");const Q=s&&"credentials"in n.prototype,se={...M,signal:X,method:k.toUpperCase(),headers:_.normalize().toJSON(),body:g,duplex:"half",credentials:Q?D:void 0};te=s&&new n(v,se);let O=await(s?q(te,M):q(v,se));const b=d&&(N==="stream"||N==="response");if(d&&(j||b&&K)){const L={};["status","statusText","headers"].forEach(J=>{L[J]=O[J]});const $=T.toFiniteNumber(O.headers.get("content-length")),[H,G]=j&&dp($,sl(fp(j),!0))||[];O=new r(hp(O.body,mp,H,()=>{G&&G(),K&&K()}),L)}N=N||"text";let P=await f[T.findKey(f,N)||"text"](O,h);return!b&&K&&K(),await new Promise((L,$)=>{nv(L,$,{data:P,headers:St.from(O.headers),status:O.status,statusText:O.statusText,config:h,request:te})})}catch(Q){throw K&&K(),Q&&Q.name==="TypeError"&&/Load failed|fetch/i.test(Q.message)?Object.assign(new ee("Network Error",ee.ERR_NETWORK,h,te),{cause:Q.cause||Q}):ee.from(Q,Q&&Q.code,h,te)}}},DS=new Map,sv=e=>{let t=e&&e.env||{};const{fetch:n,Request:r,Response:i}=t,s=[r,i,n];let o=s.length,l=o,a,u,d=DS;for(;l--;)a=s[l],u=d.get(a),u===void 0&&d.set(a,u=l?new Map:MS(t)),d=u;return u};sv();const dd={http:Z1,xhr:_S,fetch:{get:sv}};T.forEach(dd,(e,t)=>{if(e){try{Object.defineProperty(e,"name",{value:t})}catch{}Object.defineProperty(e,"adapterName",{value:t})}});const wp=e=>`- ${e}`,AS=e=>T.isFunction(e)||e===null||e===!1;function $S(e,t){e=T.isArray(e)?e:[e];const{length:n}=e;let r,i;const s={};for(let o=0;o`adapter ${a} `+(u===!1?"is not supported by the environment":"is not available in the build"));let l=n?o.length>1?`since : +`+o.map(wp).join(` +`):" "+wp(o[0]):"as no adapter specified";throw new ee("There is no suitable adapter to dispatch the request "+l,"ERR_NOT_SUPPORT")}return i}const ov={getAdapter:$S,adapters:dd};function Ra(e){if(e.cancelToken&&e.cancelToken.throwIfRequested(),e.signal&&e.signal.aborted)throw new fi(null,e)}function xp(e){return Ra(e),e.headers=St.from(e.headers),e.data=Pa.call(e,e.transformRequest),["post","put","patch"].indexOf(e.method)!==-1&&e.headers.setContentType("application/x-www-form-urlencoded",!1),ov.getAdapter(e.adapter||Ms.adapter,e)(e).then(function(r){return Ra(e),r.data=Pa.call(e,e.transformResponse,r),r.headers=St.from(r.headers),r},function(r){return tv(r)||(Ra(e),r&&r.response&&(r.response.data=Pa.call(e,e.transformResponse,r.response),r.response.headers=St.from(r.response.headers))),Promise.reject(r)})}const lv="1.13.1",Al={};["object","boolean","number","function","string","symbol"].forEach((e,t)=>{Al[e]=function(r){return typeof r===e||"a"+(t<1?"n ":" ")+e}});const kp={};Al.transitional=function(t,n,r){function i(s,o){return"[Axios v"+lv+"] Transitional option '"+s+"'"+o+(r?". "+r:"")}return(s,o,l)=>{if(t===!1)throw new ee(i(o," has been removed"+(n?" in "+n:"")),ee.ERR_DEPRECATED);return n&&!kp[o]&&(kp[o]=!0,console.warn(i(o," has been deprecated since v"+n+" and will be removed in the near future"))),t?t(s,o,l):!0}};Al.spelling=function(t){return(n,r)=>(console.warn(`${r} is likely a misspelling of ${t}`),!0)};function zS(e,t,n){if(typeof e!="object")throw new ee("options must be an object",ee.ERR_BAD_OPTION_VALUE);const r=Object.keys(e);let i=r.length;for(;i-- >0;){const s=r[i],o=t[s];if(o){const l=e[s],a=l===void 0||o(l,s,e);if(a!==!0)throw new ee("option "+s+" must be "+a,ee.ERR_BAD_OPTION_VALUE);continue}if(n!==!0)throw new ee("Unknown option "+s,ee.ERR_BAD_OPTION)}}const Co={assertOptions:zS,validators:Al},nn=Co.validators;let pr=class{constructor(t){this.defaults=t||{},this.interceptors={request:new up,response:new up}}async request(t,n){try{return await this._request(t,n)}catch(r){if(r instanceof Error){let i={};Error.captureStackTrace?Error.captureStackTrace(i):i=new Error;const s=i.stack?i.stack.replace(/^.+\n/,""):"";try{r.stack?s&&!String(r.stack).endsWith(s.replace(/^.+\n.+\n/,""))&&(r.stack+=` +`+s):r.stack=s}catch{}}throw r}}_request(t,n){typeof t=="string"?(n=n||{},n.url=t):n=t||{},n=kr(this.defaults,n);const{transitional:r,paramsSerializer:i,headers:s}=n;r!==void 0&&Co.assertOptions(r,{silentJSONParsing:nn.transitional(nn.boolean),forcedJSONParsing:nn.transitional(nn.boolean),clarifyTimeoutError:nn.transitional(nn.boolean)},!1),i!=null&&(T.isFunction(i)?n.paramsSerializer={serialize:i}:Co.assertOptions(i,{encode:nn.function,serialize:nn.function},!0)),n.allowAbsoluteUrls!==void 0||(this.defaults.allowAbsoluteUrls!==void 0?n.allowAbsoluteUrls=this.defaults.allowAbsoluteUrls:n.allowAbsoluteUrls=!0),Co.assertOptions(n,{baseUrl:nn.spelling("baseURL"),withXsrfToken:nn.spelling("withXSRFToken")},!0),n.method=(n.method||this.defaults.method||"get").toLowerCase();let o=s&&T.merge(s.common,s[n.method]);s&&T.forEach(["delete","get","head","post","put","patch","common"],h=>{delete s[h]}),n.headers=St.concat(o,s);const l=[];let a=!0;this.interceptors.request.forEach(function(v){typeof v.runWhen=="function"&&v.runWhen(n)===!1||(a=a&&v.synchronous,l.unshift(v.fulfilled,v.rejected))});const u=[];this.interceptors.response.forEach(function(v){u.push(v.fulfilled,v.rejected)});let d,f=0,p;if(!a){const h=[xp.bind(this),void 0];for(h.unshift(...l),h.push(...u),p=h.length,d=Promise.resolve(n);f{if(!r._listeners)return;let s=r._listeners.length;for(;s-- >0;)r._listeners[s](i);r._listeners=null}),this.promise.then=i=>{let s;const o=new Promise(l=>{r.subscribe(l),s=l}).then(i);return o.cancel=function(){r.unsubscribe(s)},o},t(function(s,o,l){r.reason||(r.reason=new fi(s,o,l),n(r.reason))})}throwIfRequested(){if(this.reason)throw this.reason}subscribe(t){if(this.reason){t(this.reason);return}this._listeners?this._listeners.push(t):this._listeners=[t]}unsubscribe(t){if(!this._listeners)return;const n=this._listeners.indexOf(t);n!==-1&&this._listeners.splice(n,1)}toAbortSignal(){const t=new AbortController,n=r=>{t.abort(r)};return this.subscribe(n),t.signal.unsubscribe=()=>this.unsubscribe(n),t.signal}static source(){let t;return{token:new av(function(i){t=i}),cancel:t}}};function US(e){return function(n){return e.apply(null,n)}}function BS(e){return T.isObject(e)&&e.isAxiosError===!0}const Vu={Continue:100,SwitchingProtocols:101,Processing:102,EarlyHints:103,Ok:200,Created:201,Accepted:202,NonAuthoritativeInformation:203,NoContent:204,ResetContent:205,PartialContent:206,MultiStatus:207,AlreadyReported:208,ImUsed:226,MultipleChoices:300,MovedPermanently:301,Found:302,SeeOther:303,NotModified:304,UseProxy:305,Unused:306,TemporaryRedirect:307,PermanentRedirect:308,BadRequest:400,Unauthorized:401,PaymentRequired:402,Forbidden:403,NotFound:404,MethodNotAllowed:405,NotAcceptable:406,ProxyAuthenticationRequired:407,RequestTimeout:408,Conflict:409,Gone:410,LengthRequired:411,PreconditionFailed:412,PayloadTooLarge:413,UriTooLong:414,UnsupportedMediaType:415,RangeNotSatisfiable:416,ExpectationFailed:417,ImATeapot:418,MisdirectedRequest:421,UnprocessableEntity:422,Locked:423,FailedDependency:424,TooEarly:425,UpgradeRequired:426,PreconditionRequired:428,TooManyRequests:429,RequestHeaderFieldsTooLarge:431,UnavailableForLegalReasons:451,InternalServerError:500,NotImplemented:501,BadGateway:502,ServiceUnavailable:503,GatewayTimeout:504,HttpVersionNotSupported:505,VariantAlsoNegotiates:506,InsufficientStorage:507,LoopDetected:508,NotExtended:510,NetworkAuthenticationRequired:511,WebServerIsDown:521,ConnectionTimedOut:522,OriginIsUnreachable:523,TimeoutOccurred:524,SslHandshakeFailed:525,InvalidSslCertificate:526};Object.entries(Vu).forEach(([e,t])=>{Vu[t]=e});function uv(e){const t=new pr(e),n=Fg(pr.prototype.request,t);return T.extend(n,pr.prototype,t,{allOwnKeys:!0}),T.extend(n,t,null,{allOwnKeys:!0}),n.create=function(i){return uv(kr(e,i))},n}const De=uv(Ms);De.Axios=pr;De.CanceledError=fi;De.CancelToken=FS;De.isCancel=tv;De.VERSION=lv;De.toFormData=Dl;De.AxiosError=ee;De.Cancel=De.CanceledError;De.all=function(t){return Promise.all(t)};De.spread=US;De.isAxiosError=BS;De.mergeConfig=kr;De.AxiosHeaders=St;De.formToJSON=e=>ev(T.isHTMLForm(e)?new FormData(e):e);De.getAdapter=ov.getAdapter;De.HttpStatusCode=Vu;De.default=De;const{Axios:kT,AxiosError:ST,CanceledError:ET,isCancel:CT,CancelToken:bT,VERSION:NT,all:TT,Cancel:jT,isAxiosError:_T,spread:PT,toFormData:RT,AxiosHeaders:OT,HttpStatusCode:LT,formToJSON:IT,getAdapter:MT,mergeConfig:DT}=De,fe=De.create({baseURL:"/api",withCredentials:!0,headers:{"Content-Type":"application/json"}});fe.interceptors.request.use(e=>{var t;return console.log("API Request:",(t=e.method)==null?void 0:t.toUpperCase(),e.url),e},e=>Promise.reject(e));fe.interceptors.response.use(e=>(console.log("API Response:",e.status,e.config.url),e),e=>{var t,n,r,i;return console.error("API Error:",{url:(t=e.config)==null?void 0:t.url,status:(n=e.response)==null?void 0:n.status,message:e.message,data:(r=e.response)==null?void 0:r.data}),((i=e.response)==null?void 0:i.status)===401&&(["/login","/register","/notes/archived/all","/user/delete-account"].some(l=>{var a,u;return(u=(a=e.config)==null?void 0:a.url)==null?void 0:u.includes(l)})||(localStorage.removeItem("isAuthenticated"),window.location.href="/")),e.response||console.error("Network error - server might be down or proxy not working"),Promise.reject(e)});const Sr={login:async(e,t)=>{const{data:n}=await fe.post("/login",{username:e,password:t});return n},register:async(e,t,n)=>{const{data:r}=await fe.post("/register",{username:e,password:t,confirmPassword:n});return r},checkStatus:async()=>{const{data:e}=await fe.get("/auth/status");return e},logout:async()=>{await fe.post("/logout")}},Tr=()=>{const e=ot();return{showNotification:x.useCallback((n,r="info")=>{const s=e(a1({message:n,type:r})).payload.id;setTimeout(()=>{e($g(s))},4e3)},[e])}},Xi=/^[a-z0-9]+(-[a-z0-9]+)*$/,$l=(e,t,n,r="")=>{const i=e.split(":");if(e.slice(0,1)==="@"){if(i.length<2||i.length>3)return null;r=i.shift().slice(1)}if(i.length>3||!i.length)return null;if(i.length>1){const l=i.pop(),a=i.pop(),u={provider:i.length>0?i[0]:r,prefix:a,name:l};return t&&!bo(u)?null:u}const s=i[0],o=s.split("-");if(o.length>1){const l={provider:r,prefix:o.shift(),name:o.join("-")};return t&&!bo(l)?null:l}if(n&&r===""){const l={provider:r,prefix:"",name:s};return t&&!bo(l,n)?null:l}return null},bo=(e,t)=>e?!!((e.provider===""||e.provider.match(Xi))&&(t&&e.prefix===""||e.prefix.match(Xi))&&e.name.match(Xi)):!1,cv=Object.freeze({left:0,top:0,width:16,height:16}),ol=Object.freeze({rotate:0,vFlip:!1,hFlip:!1}),fd=Object.freeze({...cv,...ol}),Qu=Object.freeze({...fd,body:"",hidden:!1});function WS(e,t){const n={};!e.hFlip!=!t.hFlip&&(n.hFlip=!0),!e.vFlip!=!t.vFlip&&(n.vFlip=!0);const r=((e.rotate||0)+(t.rotate||0))%4;return r&&(n.rotate=r),n}function Sp(e,t){const n=WS(e,t);for(const r in Qu)r in ol?r in e&&!(r in n)&&(n[r]=ol[r]):r in t?n[r]=t[r]:r in e&&(n[r]=e[r]);return n}function HS(e,t){const n=e.icons,r=e.aliases||Object.create(null),i=Object.create(null);function s(o){if(n[o])return i[o]=[];if(!(o in i)){i[o]=null;const l=r[o]&&r[o].parent,a=l&&s(l);a&&(i[o]=[l].concat(a))}return i[o]}return Object.keys(n).concat(Object.keys(r)).forEach(s),i}function VS(e,t,n){const r=e.icons,i=e.aliases||Object.create(null);let s={};function o(l){s=Sp(r[l]||i[l],s)}return o(t),n.forEach(o),Sp(e,s)}function dv(e,t){const n=[];if(typeof e!="object"||typeof e.icons!="object")return n;e.not_found instanceof Array&&e.not_found.forEach(i=>{t(i,null),n.push(i)});const r=HS(e);for(const i in r){const s=r[i];s&&(t(i,VS(e,i,s)),n.push(i))}return n}const QS={provider:"",aliases:{},not_found:{},...cv};function Oa(e,t){for(const n in t)if(n in e&&typeof e[n]!=typeof t[n])return!1;return!0}function fv(e){if(typeof e!="object"||e===null)return null;const t=e;if(typeof t.prefix!="string"||!e.icons||typeof e.icons!="object"||!Oa(e,QS))return null;const n=t.icons;for(const i in n){const s=n[i];if(!i.match(Xi)||typeof s.body!="string"||!Oa(s,Qu))return null}const r=t.aliases||Object.create(null);for(const i in r){const s=r[i],o=s.parent;if(!i.match(Xi)||typeof o!="string"||!n[o]&&!r[o]||!Oa(s,Qu))return null}return t}const Ep=Object.create(null);function qS(e,t){return{provider:e,prefix:t,icons:Object.create(null),missing:new Set}}function Er(e,t){const n=Ep[e]||(Ep[e]=Object.create(null));return n[t]||(n[t]=qS(e,t))}function pd(e,t){return fv(t)?dv(t,(n,r)=>{r?e.icons[n]=r:e.missing.add(n)}):[]}function GS(e,t,n){try{if(typeof n.body=="string")return e.icons[t]={...n},!0}catch{}return!1}let Ss=!1;function pv(e){return typeof e=="boolean"&&(Ss=e),Ss}function YS(e){const t=typeof e=="string"?$l(e,!0,Ss):e;if(t){const n=Er(t.provider,t.prefix),r=t.name;return n.icons[r]||(n.missing.has(r)?null:void 0)}}function KS(e,t){const n=$l(e,!0,Ss);if(!n)return!1;const r=Er(n.provider,n.prefix);return GS(r,n.name,t)}function XS(e,t){if(typeof e!="object")return!1;if(typeof t!="string"&&(t=e.provider||""),Ss&&!t&&!e.prefix){let i=!1;return fv(e)&&(e.prefix="",dv(e,(s,o)=>{o&&KS(s,o)&&(i=!0)})),i}const n=e.prefix;if(!bo({provider:t,prefix:n,name:"a"}))return!1;const r=Er(t,n);return!!pd(r,e)}const hv=Object.freeze({width:null,height:null}),mv=Object.freeze({...hv,...ol}),JS=/(-?[0-9.]*[0-9]+[0-9.]*)/g,ZS=/^-?[0-9.]*[0-9]+[0-9.]*$/g;function Cp(e,t,n){if(t===1)return e;if(n=n||100,typeof e=="number")return Math.ceil(e*t*n)/n;if(typeof e!="string")return e;const r=e.split(JS);if(r===null||!r.length)return e;const i=[];let s=r.shift(),o=ZS.test(s);for(;;){if(o){const l=parseFloat(s);isNaN(l)?i.push(s):i.push(Math.ceil(l*t*n)/n)}else i.push(s);if(s=r.shift(),s===void 0)return i.join("");o=!o}}const eE=e=>e==="unset"||e==="undefined"||e==="none";function tE(e,t){const n={...fd,...e},r={...mv,...t},i={left:n.left,top:n.top,width:n.width,height:n.height};let s=n.body;[n,r].forEach(h=>{const v=[],k=h.hFlip,g=h.vFlip;let m=h.rotate;k?g?m+=2:(v.push("translate("+(i.width+i.left).toString()+" "+(0-i.top).toString()+")"),v.push("scale(-1 1)"),i.top=i.left=0):g&&(v.push("translate("+(0-i.left).toString()+" "+(i.height+i.top).toString()+")"),v.push("scale(1 -1)"),i.top=i.left=0);let y;switch(m<0&&(m-=Math.floor(m/4)*4),m=m%4,m){case 1:y=i.height/2+i.top,v.unshift("rotate(90 "+y.toString()+" "+y.toString()+")");break;case 2:v.unshift("rotate(180 "+(i.width/2+i.left).toString()+" "+(i.height/2+i.top).toString()+")");break;case 3:y=i.width/2+i.left,v.unshift("rotate(-90 "+y.toString()+" "+y.toString()+")");break}m%2===1&&(i.left!==i.top&&(y=i.left,i.left=i.top,i.top=y),i.width!==i.height&&(y=i.width,i.width=i.height,i.height=y)),v.length&&(s=''+s+"")});const o=r.width,l=r.height,a=i.width,u=i.height;let d,f;o===null?(f=l===null?"1em":l==="auto"?u:l,d=Cp(f,a/u)):(d=o==="auto"?a:o,f=l===null?Cp(d,u/a):l==="auto"?u:l);const p={},w=(h,v)=>{eE(v)||(p[h]=v.toString())};return w("width",d),w("height",f),p.viewBox=i.left.toString()+" "+i.top.toString()+" "+a.toString()+" "+u.toString(),{attributes:p,body:s}}const nE=/\sid="(\S+)"/g,rE="IconifyId"+Date.now().toString(16)+(Math.random()*16777216|0).toString(16);let iE=0;function sE(e,t=rE){const n=[];let r;for(;r=nE.exec(e);)n.push(r[1]);if(!n.length)return e;const i="suffix"+(Math.random()*16777216|Date.now()).toString(16);return n.forEach(s=>{const o=typeof t=="function"?t(s):t+(iE++).toString(),l=s.replace(/[.*+?^${}()|[\]\\]/g,"\\$&");e=e.replace(new RegExp('([#;"])('+l+')([")]|\\.[a-z])',"g"),"$1"+o+i+"$3")}),e=e.replace(new RegExp(i,"g"),""),e}const qu=Object.create(null);function oE(e,t){qu[e]=t}function Gu(e){return qu[e]||qu[""]}function hd(e){let t;if(typeof e.resources=="string")t=[e.resources];else if(t=e.resources,!(t instanceof Array)||!t.length)return null;return{resources:t,path:e.path||"/",maxURL:e.maxURL||500,rotate:e.rotate||750,timeout:e.timeout||5e3,random:e.random===!0,index:e.index||0,dataAfterTimeout:e.dataAfterTimeout!==!1}}const md=Object.create(null),Pi=["https://api.simplesvg.com","https://api.unisvg.com"],No=[];for(;Pi.length>0;)Pi.length===1||Math.random()>.5?No.push(Pi.shift()):No.push(Pi.pop());md[""]=hd({resources:["https://api.iconify.design"].concat(No)});function lE(e,t){const n=hd(t);return n===null?!1:(md[e]=n,!0)}function gd(e){return md[e]}const aE=()=>{let e;try{if(e=fetch,typeof e=="function")return e}catch{}};let bp=aE();function uE(e,t){const n=gd(e);if(!n)return 0;let r;if(!n.maxURL)r=0;else{let i=0;n.resources.forEach(o=>{i=Math.max(i,o.length)});const s=t+".json?icons=";r=n.maxURL-i-n.path.length-s.length}return r}function cE(e){return e===404}const dE=(e,t,n)=>{const r=[],i=uE(e,t),s="icons";let o={type:s,provider:e,prefix:t,icons:[]},l=0;return n.forEach((a,u)=>{l+=a.length+1,l>=i&&u>0&&(r.push(o),o={type:s,provider:e,prefix:t,icons:[]},l=a.length),o.icons.push(a)}),r.push(o),r};function fE(e){if(typeof e=="string"){const t=gd(e);if(t)return t.path}return"/"}const pE=(e,t,n)=>{if(!bp){n("abort",424);return}let r=fE(t.provider);switch(t.type){case"icons":{const s=t.prefix,l=t.icons.join(","),a=new URLSearchParams({icons:l});r+=s+".json?"+a.toString();break}case"custom":{const s=t.uri;r+=s.slice(0,1)==="/"?s.slice(1):s;break}default:n("abort",400);return}let i=503;bp(e+r).then(s=>{const o=s.status;if(o!==200){setTimeout(()=>{n(cE(o)?"abort":"next",o)});return}return i=501,s.json()}).then(s=>{if(typeof s!="object"||s===null){setTimeout(()=>{s===404?n("abort",s):n("next",i)});return}setTimeout(()=>{n("success",s)})}).catch(()=>{n("next",i)})},hE={prepare:dE,send:pE};function mE(e){const t={loaded:[],missing:[],pending:[]},n=Object.create(null);e.sort((i,s)=>i.provider!==s.provider?i.provider.localeCompare(s.provider):i.prefix!==s.prefix?i.prefix.localeCompare(s.prefix):i.name.localeCompare(s.name));let r={provider:"",prefix:"",name:""};return e.forEach(i=>{if(r.name===i.name&&r.prefix===i.prefix&&r.provider===i.provider)return;r=i;const s=i.provider,o=i.prefix,l=i.name,a=n[s]||(n[s]=Object.create(null)),u=a[o]||(a[o]=Er(s,o));let d;l in u.icons?d=t.loaded:o===""||u.missing.has(l)?d=t.missing:d=t.pending;const f={provider:s,prefix:o,name:l};d.push(f)}),t}function gv(e,t){e.forEach(n=>{const r=n.loaderCallbacks;r&&(n.loaderCallbacks=r.filter(i=>i.id!==t))})}function gE(e){e.pendingCallbacksFlag||(e.pendingCallbacksFlag=!0,setTimeout(()=>{e.pendingCallbacksFlag=!1;const t=e.loaderCallbacks?e.loaderCallbacks.slice(0):[];if(!t.length)return;let n=!1;const r=e.provider,i=e.prefix;t.forEach(s=>{const o=s.icons,l=o.pending.length;o.pending=o.pending.filter(a=>{if(a.prefix!==i)return!0;const u=a.name;if(e.icons[u])o.loaded.push({provider:r,prefix:i,name:u});else if(e.missing.has(u))o.missing.push({provider:r,prefix:i,name:u});else return n=!0,!0;return!1}),o.pending.length!==l&&(n||gv([e],s.id),s.callback(o.loaded.slice(0),o.missing.slice(0),o.pending.slice(0),s.abort))})}))}let vE=0;function yE(e,t,n){const r=vE++,i=gv.bind(null,n,r);if(!t.pending.length)return i;const s={id:r,icons:t,callback:e,abort:i};return n.forEach(o=>{(o.loaderCallbacks||(o.loaderCallbacks=[])).push(s)}),i}function wE(e,t=!0,n=!1){const r=[];return e.forEach(i=>{const s=typeof i=="string"?$l(i,t,n):i;s&&r.push(s)}),r}var xE={resources:[],index:0,timeout:2e3,rotate:750,random:!1,dataAfterTimeout:!1};function kE(e,t,n,r){const i=e.resources.length,s=e.random?Math.floor(Math.random()*i):e.index;let o;if(e.random){let S=e.resources.slice(0);for(o=[];S.length>1;){const N=Math.floor(Math.random()*S.length);o.push(S[N]),S=S.slice(0,N).concat(S.slice(N+1))}o=o.concat(S)}else o=e.resources.slice(s).concat(e.resources.slice(0,s));const l=Date.now();let a="pending",u=0,d,f=null,p=[],w=[];typeof r=="function"&&w.push(r);function h(){f&&(clearTimeout(f),f=null)}function v(){a==="pending"&&(a="aborted"),h(),p.forEach(S=>{S.status==="pending"&&(S.status="aborted")}),p=[]}function k(S,N){N&&(w=[]),typeof S=="function"&&w.push(S)}function g(){return{startTime:l,payload:t,status:a,queriesSent:u,queriesPending:p.length,subscribe:k,abort:v}}function m(){a="failed",w.forEach(S=>{S(void 0,d)})}function y(){p.forEach(S=>{S.status==="pending"&&(S.status="aborted")}),p=[]}function C(S,N,_){const D=N!=="success";switch(p=p.filter(M=>M!==S),a){case"pending":break;case"failed":if(D||!e.dataAfterTimeout)return;break;default:return}if(N==="abort"){d=_,m();return}if(D){d=_,p.length||(o.length?j():m());return}if(h(),y(),!e.random){const M=e.resources.indexOf(S.resource);M!==-1&&M!==e.index&&(e.index=M)}a="completed",w.forEach(M=>{M(_)})}function j(){if(a!=="pending")return;h();const S=o.shift();if(S===void 0){if(p.length){f=setTimeout(()=>{h(),a==="pending"&&(y(),m())},e.timeout);return}m();return}const N={status:"pending",resource:S,callback:(_,D)=>{C(N,_,D)}};p.push(N),u++,f=setTimeout(j,e.rotate),n(S,t,N.callback)}return setTimeout(j),g}function vv(e){const t={...xE,...e};let n=[];function r(){n=n.filter(l=>l().status==="pending")}function i(l,a,u){const d=kE(t,l,a,(f,p)=>{r(),u&&u(f,p)});return n.push(d),d}function s(l){return n.find(a=>l(a))||null}return{query:i,find:s,setIndex:l=>{t.index=l},getIndex:()=>t.index,cleanup:r}}function Np(){}const La=Object.create(null);function SE(e){if(!La[e]){const t=gd(e);if(!t)return;const n=vv(t),r={config:t,redundancy:n};La[e]=r}return La[e]}function EE(e,t,n){let r,i;if(typeof e=="string"){const s=Gu(e);if(!s)return n(void 0,424),Np;i=s.send;const o=SE(e);o&&(r=o.redundancy)}else{const s=hd(e);if(s){r=vv(s);const o=e.resources?e.resources[0]:"",l=Gu(o);l&&(i=l.send)}}return!r||!i?(n(void 0,424),Np):r.query(t,i,n)().abort}const Tp="iconify2",Es="iconify",yv=Es+"-count",jp=Es+"-version",wv=36e5,CE=168;function Yu(e,t){try{return e.getItem(t)}catch{}}function vd(e,t,n){try{return e.setItem(t,n),!0}catch{}}function _p(e,t){try{e.removeItem(t)}catch{}}function Ku(e,t){return vd(e,yv,t.toString())}function Xu(e){return parseInt(Yu(e,yv))||0}const zl={local:!0,session:!0},xv={local:new Set,session:new Set};let yd=!1;function bE(e){yd=e}let so=typeof window>"u"?{}:window;function kv(e){const t=e+"Storage";try{if(so&&so[t]&&typeof so[t].length=="number")return so[t]}catch{}zl[e]=!1}function Sv(e,t){const n=kv(e);if(!n)return;const r=Yu(n,jp);if(r!==Tp){if(r){const l=Xu(n);for(let a=0;a{const a=Es+l.toString(),u=Yu(n,a);if(typeof u=="string"){try{const d=JSON.parse(u);if(typeof d=="object"&&typeof d.cached=="number"&&d.cached>i&&typeof d.provider=="string"&&typeof d.data=="object"&&typeof d.data.prefix=="string"&&t(d,l))return!0}catch{}_p(n,a)}};let o=Xu(n);for(let l=o-1;l>=0;l--)s(l)||(l===o-1?(o--,Ku(n,o)):xv[e].add(l))}function Ev(){if(!yd){bE(!0);for(const e in zl)Sv(e,t=>{const n=t.data,r=t.provider,i=n.prefix,s=Er(r,i);if(!pd(s,n).length)return!1;const o=n.lastModified||-1;return s.lastModifiedCached=s.lastModifiedCached?Math.min(s.lastModifiedCached,o):o,!0})}}function NE(e,t){const n=e.lastModifiedCached;if(n&&n>=t)return n===t;if(e.lastModifiedCached=t,n)for(const r in zl)Sv(r,i=>{const s=i.data;return i.provider!==e.provider||s.prefix!==e.prefix||s.lastModified===t});return!0}function TE(e,t){yd||Ev();function n(r){let i;if(!zl[r]||!(i=kv(r)))return;const s=xv[r];let o;if(s.size)s.delete(o=Array.from(s).shift());else if(o=Xu(i),!Ku(i,o+1))return;const l={cached:Math.floor(Date.now()/wv),provider:e.provider,data:t};return vd(i,Es+o.toString(),JSON.stringify(l))}t.lastModified&&!NE(e,t.lastModified)||Object.keys(t.icons).length&&(t.not_found&&(t=Object.assign({},t),delete t.not_found),n("local")||n("session"))}function Pp(){}function jE(e){e.iconsLoaderFlag||(e.iconsLoaderFlag=!0,setTimeout(()=>{e.iconsLoaderFlag=!1,gE(e)}))}function _E(e,t){e.iconsToLoad?e.iconsToLoad=e.iconsToLoad.concat(t).sort():e.iconsToLoad=t,e.iconsQueueFlag||(e.iconsQueueFlag=!0,setTimeout(()=>{e.iconsQueueFlag=!1;const{provider:n,prefix:r}=e,i=e.iconsToLoad;delete e.iconsToLoad;let s;if(!i||!(s=Gu(n)))return;s.prepare(n,r,i).forEach(l=>{EE(n,l,a=>{if(typeof a!="object")l.icons.forEach(u=>{e.missing.add(u)});else try{const u=pd(e,a);if(!u.length)return;const d=e.pendingIcons;d&&u.forEach(f=>{d.delete(f)}),TE(e,a)}catch(u){console.error(u)}jE(e)})})}))}const PE=(e,t)=>{const n=wE(e,!0,pv()),r=mE(n);if(!r.pending.length){let a=!0;return t&&setTimeout(()=>{a&&t(r.loaded,r.missing,r.pending,Pp)}),()=>{a=!1}}const i=Object.create(null),s=[];let o,l;return r.pending.forEach(a=>{const{provider:u,prefix:d}=a;if(d===l&&u===o)return;o=u,l=d,s.push(Er(u,d));const f=i[u]||(i[u]=Object.create(null));f[d]||(f[d]=[])}),r.pending.forEach(a=>{const{provider:u,prefix:d,name:f}=a,p=Er(u,d),w=p.pendingIcons||(p.pendingIcons=new Set);w.has(f)||(w.add(f),i[u][d].push(f))}),s.forEach(a=>{const{provider:u,prefix:d}=a;i[u][d].length&&_E(a,i[u][d])}),t?yE(t,r,s):Pp};function RE(e,t){const n={...e};for(const r in t){const i=t[r],s=typeof i;r in hv?(i===null||i&&(s==="string"||s==="number"))&&(n[r]=i):s===typeof n[r]&&(n[r]=r==="rotate"?i%4:i)}return n}const OE=/[\s,]+/;function LE(e,t){t.split(OE).forEach(n=>{switch(n.trim()){case"horizontal":e.hFlip=!0;break;case"vertical":e.vFlip=!0;break}})}function IE(e,t=0){const n=e.replace(/^-?[0-9.]*/,"");function r(i){for(;i<0;)i+=4;return i%4}if(n===""){const i=parseInt(e);return isNaN(i)?0:r(i)}else if(n!==e){let i=0;switch(n){case"%":i=25;break;case"deg":i=90}if(i){let s=parseFloat(e.slice(0,e.length-n.length));return isNaN(s)?0:(s=s/i,s%1===0?r(s):0)}}return t}function ME(e,t){let n=e.indexOf("xlink:")===-1?"":' xmlns:xlink="http://www.w3.org/1999/xlink"';for(const r in t)n+=" "+r+'="'+t[r]+'"';return'"+e+""}function DE(e){return e.replace(/"/g,"'").replace(/%/g,"%25").replace(/#/g,"%23").replace(//g,"%3E").replace(/\s+/g," ")}function AE(e){return"data:image/svg+xml,"+DE(e)}function $E(e){return'url("'+AE(e)+'")'}let Ji;function zE(){try{Ji=window.trustedTypes.createPolicy("iconify",{createHTML:e=>e})}catch{Ji=null}}function FE(e){return Ji===void 0&&zE(),Ji?Ji.createHTML(e):e}const Cv={...mv,inline:!1},UE={xmlns:"http://www.w3.org/2000/svg",xmlnsXlink:"http://www.w3.org/1999/xlink","aria-hidden":!0,role:"img"},BE={display:"inline-block"},Ju={backgroundColor:"currentColor"},bv={backgroundColor:"transparent"},Rp={Image:"var(--svg)",Repeat:"no-repeat",Size:"100% 100%"},Op={WebkitMask:Ju,mask:Ju,background:bv};for(const e in Op){const t=Op[e];for(const n in Rp)t[e+n]=Rp[n]}const WE={...Cv,inline:!0};function Lp(e){return e+(e.match(/^[-0-9.]+$/)?"px":"")}const HE=(e,t,n,r)=>{const i=n?WE:Cv,s=RE(i,t),o=t.mode||"svg",l={},a=t.style||{},u={...o==="svg"?UE:{},ref:r};for(let g in t){const m=t[g];if(m!==void 0)switch(g){case"icon":case"style":case"children":case"onLoad":case"mode":case"_ref":case"_inline":break;case"inline":case"hFlip":case"vFlip":s[g]=m===!0||m==="true"||m===1;break;case"flip":typeof m=="string"&&LE(s,m);break;case"color":l.color=m;break;case"rotate":typeof m=="string"?s[g]=IE(m):typeof m=="number"&&(s[g]=m);break;case"ariaHidden":case"aria-hidden":m!==!0&&m!=="true"&&delete u["aria-hidden"];break;default:i[g]===void 0&&(u[g]=m)}}const d=tE(e,s),f=d.attributes;if(s.inline&&(l.verticalAlign="-0.125em"),o==="svg"){u.style={...l,...a},Object.assign(u,f);let g=0,m=t.id;return typeof m=="string"&&(m=m.replace(/-/g,"_")),u.dangerouslySetInnerHTML={__html:FE(sE(d.body,m?()=>m+"ID"+g++:"iconifyReact"))},Jt.createElement("svg",u)}const{body:p,width:w,height:h}=e,v=o==="mask"||(o==="bg"?!1:p.indexOf("currentColor")!==-1),k=ME(p,{...f,width:w+"",height:h+""});return u.style={...l,"--svg":$E(k),width:Lp(f.width),height:Lp(f.height),...BE,...v?Ju:bv,...a},Jt.createElement("span",u)};pv(!0);oE("",hE);if(typeof document<"u"&&typeof window<"u"){Ev();const e=window;if(e.IconifyPreload!==void 0){const t=e.IconifyPreload,n="Invalid IconifyPreload syntax.";typeof t=="object"&&t!==null&&(t instanceof Array?t:[t]).forEach(r=>{try{(typeof r!="object"||r===null||r instanceof Array||typeof r.icons!="object"||typeof r.prefix!="string"||!XS(r))&&console.error(n)}catch{console.error(n)}})}if(e.IconifyProviders!==void 0){const t=e.IconifyProviders;if(typeof t=="object"&&t!==null)for(let n in t){const r="IconifyProviders["+n+"] is invalid.";try{const i=t[n];if(typeof i!="object"||!i||i.resources===void 0)continue;lE(n,i)||console.error(r)}catch{console.error(r)}}}}class Nv extends Jt.Component{constructor(t){super(t),this.state={icon:null}}_abortLoading(){this._loading&&(this._loading.abort(),this._loading=null)}_setData(t){this.state.icon!==t&&this.setState({icon:t})}_checkIcon(t){const n=this.state,r=this.props.icon;if(typeof r=="object"&&r!==null&&typeof r.body=="string"){this._icon="",this._abortLoading(),(t||n.icon===null)&&this._setData({data:r});return}let i;if(typeof r!="string"||(i=$l(r,!1,!0))===null){this._abortLoading(),this._setData(null);return}const s=YS(i);if(!s){(!this._loading||this._loading.name!==r)&&(this._abortLoading(),this._icon="",this._setData(null),s!==null&&(this._loading={name:r,abort:PE([i],this._checkIcon.bind(this,!1))}));return}if(this._icon!==r||n.icon===null){this._abortLoading(),this._icon=r;const o=["iconify"];i.prefix!==""&&o.push("iconify--"+i.prefix),i.provider!==""&&o.push("iconify--"+i.provider),this._setData({data:s,classes:o}),this.props.onLoad&&this.props.onLoad(r)}}componentDidMount(){this._checkIcon(!1)}componentDidUpdate(t){t.icon!==this.props.icon&&this._checkIcon(!0)}componentWillUnmount(){this._abortLoading()}render(){const t=this.props,n=this.state.icon;if(n===null)return t.children?t.children:Jt.createElement("span",{});let r=t;return n.classes&&(r={...t,className:(typeof t.className=="string"?t.className+" ":"")+n.classes.join(" ")}),HE({...fd,...n.data},r,t._inline,t._ref)}}const F=Jt.forwardRef(function(t,n){const r={...t,_ref:n,_inline:!1};return Jt.createElement(Nv,r)});Jt.forwardRef(function(t,n){const r={...t,_ref:n,_inline:!0};return Jt.createElement(Nv,r)});const VE=e=>{const t=e.replace("#",""),n=parseInt(t.substring(0,2),16),r=parseInt(t.substring(2,4),16),i=parseInt(t.substring(4,6),16);return`${n}, ${r}, ${i}`},Cs=e=>{document.documentElement.style.setProperty("--accent-color",e);const t=VE(e);document.documentElement.style.setProperty("--accent-color-rgb",t)},Tv=()=>{const e=ye(r=>r.ui.theme),t=ye(r=>r.ui.accentColor),n=ot();return x.useEffect(()=>{document.documentElement.setAttribute("data-theme",e),Cs(t);const r=document.querySelector('meta[name="theme-color"]');r&&r.setAttribute("content",e==="dark"?"#1a1a1a":t)},[e,t]),x.useEffect(()=>{const r=window.matchMedia("(prefers-color-scheme: dark)"),i=s=>{localStorage.getItem("theme")||n(l1(s.matches?"dark":"light"))};return r.addEventListener("change",i),()=>r.removeEventListener("change",i)},[n]),{theme:e,accentColor:t,toggleTheme:()=>n(o1())}},Ds=()=>{const{theme:e,toggleTheme:t}=Tv();return c.jsx("button",{id:"theme-toggle-btn",className:"theme-toggle-btn",onClick:t,title:"Переключить тему",children:c.jsx(F,{icon:e==="dark"?"mdi:weather-sunny":"mdi:weather-night"})})},QE=()=>{const[e,t]=x.useState(""),[n,r]=x.useState(""),[i,s]=x.useState(!1),o=Kn(),l=ot(),{showNotification:a}=Tr(),u=ye(p=>p.auth.isAuthenticated),[d]=Bx();x.useEffect(()=>{u&&o("/notes")},[u,o]),x.useEffect(()=>{d.get("error")==="invalid_password"&&a("Неверный пароль!","error")},[d,a]);const f=async p=>{var w;if(p.preventDefault(),!e.trim()||!n){a("Логин и пароль обязательны","error");return}s(!0);try{console.log("Attempting login...");const h=await Sr.login(e,n);if(console.log("Login response:",h),h.success){const v=await Sr.checkStatus();l(sd({userId:v.userId,username:v.username})),a("Успешный вход!","success"),o("/notes")}else a(h.error||"Ошибка входа","error")}catch(h){console.error("Login error details:",h),console.error("Error response:",h.response),console.error("Error message:",h.message);let v="Ошибка соединения с сервером";h.response?v=((w=h.response.data)==null?void 0:w.error)||`Ошибка ${h.response.status}`:h.request?v="Сервер не отвечает. Проверьте, запущен ли backend на порту 3000":v=h.message||"Ошибка соединения с сервером",a(v,"error")}finally{s(!1)}};return c.jsxs("div",{className:"container",children:[c.jsx("header",{children:c.jsxs("div",{style:{display:"flex",alignItems:"center",justifyContent:"space-between"},children:[c.jsxs("span",{children:[c.jsx(F,{icon:"mdi:login"})," Вход в систему"]}),c.jsx(Ds,{})]})}),c.jsxs("div",{className:"login-form",children:[c.jsxs("form",{id:"loginForm",onSubmit:f,children:[c.jsxs("div",{className:"form-group",children:[c.jsx("label",{htmlFor:"username",children:"Логин:"}),c.jsx("input",{type:"text",id:"username",name:"username",value:e,onChange:p=>t(p.target.value),required:!0,placeholder:"Введите ваш логин"})]}),c.jsxs("div",{className:"form-group",children:[c.jsx("label",{htmlFor:"password",children:"Пароль:"}),c.jsx("input",{type:"password",id:"password",name:"password",value:n,onChange:p=>r(p.target.value),required:!0,placeholder:"Введите пароль"})]}),c.jsx("button",{type:"submit",className:"btnSave",disabled:i,children:i?"Вход...":"Войти"})]}),c.jsxs("p",{className:"auth-link",children:["Нет аккаунта? ",c.jsx(wg,{to:"/register",children:"Зарегистрируйтесь"})]})]}),c.jsx("div",{className:"footer",children:c.jsxs("p",{children:["Создатель: ",c.jsx("span",{children:"Fovway"})]})})]})},qE=()=>{const[e,t]=x.useState(""),[n,r]=x.useState(""),[i,s]=x.useState(""),[o,l]=x.useState(!1),a=Kn(),u=ot(),{showNotification:d}=Tr(),f=ye(w=>w.auth.isAuthenticated);x.useEffect(()=>{f&&a("/notes")},[f,a]);const p=async w=>{var h;if(w.preventDefault(),!e.trim()||!n||!i){d("Все поля обязательны","error");return}if(e.length<3){d("Логин должен быть не менее 3 символов","error");return}if(n.length<6){d("Пароль должен быть не менее 6 символов","error");return}if(n!==i){d("Пароли не совпадают","error");return}l(!0);try{console.log("Attempting registration...");const v=await Sr.register(e,n,i);if(console.log("Register response:",v),v.success){const k=await Sr.checkStatus();u(sd({userId:k.userId,username:k.username})),d("Регистрация успешна!","success"),a("/notes")}else d(v.error||"Ошибка регистрации","error")}catch(v){console.error("Register error details:",v),console.error("Error response:",v.response),console.error("Error message:",v.message);let k="Ошибка соединения с сервером";v.response?k=((h=v.response.data)==null?void 0:h.error)||`Ошибка ${v.response.status}`:v.request?k="Сервер не отвечает. Проверьте, запущен ли backend на порту 3000":k=v.message||"Ошибка соединения с сервером",d(k,"error")}finally{l(!1)}};return c.jsxs("div",{className:"container",children:[c.jsx("header",{children:c.jsxs("div",{style:{display:"flex",alignItems:"center",justifyContent:"space-between"},children:[c.jsxs("span",{children:[c.jsx(F,{icon:"mdi:account-plus"})," Регистрация"]}),c.jsx(Ds,{})]})}),c.jsxs("div",{className:"login-form",children:[c.jsxs("form",{id:"registerForm",onSubmit:p,children:[c.jsxs("div",{className:"form-group",children:[c.jsx("label",{htmlFor:"username",children:"Логин:"}),c.jsx("input",{type:"text",id:"username",name:"username",value:e,onChange:w=>t(w.target.value),required:!0,placeholder:"Введите ваш логин (мин. 3 символа)"})]}),c.jsxs("div",{className:"form-group",children:[c.jsx("label",{htmlFor:"password",children:"Пароль:"}),c.jsx("input",{type:"password",id:"password",name:"password",value:n,onChange:w=>r(w.target.value),required:!0,placeholder:"Введите пароль (мин. 6 символов)"})]}),c.jsxs("div",{className:"form-group",children:[c.jsx("label",{htmlFor:"confirmPassword",children:"Подтвердите пароль:"}),c.jsx("input",{type:"password",id:"confirmPassword",name:"confirmPassword",value:i,onChange:w=>s(w.target.value),required:!0,placeholder:"Подтвердите пароль"})]}),c.jsx("button",{type:"submit",className:"btnSave",disabled:o,children:o?"Регистрация...":"Зарегистрироваться"})]}),c.jsxs("p",{className:"auth-link",children:["Уже есть аккаунт? ",c.jsx(wg,{to:"/",children:"Войдите"})]})]}),c.jsx("div",{className:"footer",children:c.jsxs("p",{children:["Создатель: ",c.jsx("span",{children:"Fovway"})]})})]})},ct={getProfile:async()=>{const{data:e}=await fe.get("/user");return e},updateProfile:async e=>{const{data:t}=await fe.put("/user/profile",e);return t},uploadAvatar:async e=>{const t=new FormData;t.append("avatar",e);const{data:n}=await fe.post("/user/avatar",t,{headers:{"Content-Type":"multipart/form-data"}});return n},deleteAvatar:async()=>{await fe.delete("/user/avatar")},deleteAccount:async e=>{const{data:t}=await fe.delete("/user/delete-account",{data:{password:e}});return t},getAiSettings:async()=>{const{data:e}=await fe.get("/user/ai-settings");return e},updateAiSettings:async e=>{const{data:t}=await fe.put("/user/ai-settings",e);return t}},GE=({onFilterChange:e,onToggleSidebar:t})=>{const n=Kn(),r=ot(),i=ye(u=>u.profile.user),s=ye(u=>u.notes.selectedDate),o=ye(u=>u.notes.selectedTag),l=ye(u=>u.notes.searchQuery);x.useEffect(()=>{a()},[]),x.useEffect(()=>{const u=!!(s||o||l);e==null||e(u)},[s,o,l,e]);const a=async()=>{try{const u=await ct.getProfile();r(od(u));const d=u.accent_color||"#007bff";r(il(d)),Cs(d);try{const f=await ct.getAiSettings();r(ld(f))}catch(f){console.error("Ошибка загрузки AI настроек:",f)}}catch(u){console.error("Ошибка загрузки информации о пользователе:",u)}};return c.jsxs(c.Fragment,{children:[t&&c.jsx("button",{className:"mobile-menu-btn",onClick:t,children:c.jsx(F,{icon:"mdi:menu"})}),c.jsxs("header",{className:"notes-header",children:[c.jsx("div",{className:"notes-header-left",children:c.jsxs("span",{children:[c.jsx(F,{icon:"mdi:note-text"})," Мои заметки"]})}),c.jsxs("div",{className:"user-info",children:[i!=null&&i.avatar?c.jsx("div",{className:"user-avatar-mini",style:{display:"block"},title:"Перейти в профиль",onClick:()=>n("/profile"),children:c.jsx("img",{src:i.avatar,alt:"Аватар",loading:"lazy"})}):c.jsx("div",{className:"user-avatar-mini user-avatar-placeholder-mini",style:{display:"flex"},title:"Перейти в профиль",onClick:()=>n("/profile"),children:c.jsx(F,{icon:"mdi:account"})}),c.jsx(Ds,{}),c.jsx("button",{className:"settings-icon-btn",title:"Настройки",onClick:()=>n("/settings"),children:c.jsx(F,{icon:"mdi:cog"})})]})]})]})};function ll(e){"@babel/helpers - typeof";return ll=typeof Symbol=="function"&&typeof Symbol.iterator=="symbol"?function(t){return typeof t}:function(t){return t&&typeof Symbol=="function"&&t.constructor===Symbol&&t!==Symbol.prototype?"symbol":typeof t},ll(e)}function Ut(e){if(e===null||e===!0||e===!1)return NaN;var t=Number(e);return isNaN(t)?t:t<0?Math.ceil(t):Math.floor(t)}function we(e,t){if(t.length1?"s":"")+" required, but only "+t.length+" present")}function Me(e){we(1,arguments);var t=Object.prototype.toString.call(e);return e instanceof Date||ll(e)==="object"&&t==="[object Date]"?new Date(e.getTime()):typeof e=="number"||t==="[object Number]"?new Date(e):((typeof e=="string"||t==="[object String]")&&typeof console<"u"&&(console.warn("Starting with v2.0.0-beta.1 date-fns doesn't accept strings as date arguments. Please use `parseISO` to parse strings. See: https://github.com/date-fns/date-fns/blob/master/docs/upgradeGuide.md#string-arguments"),console.warn(new Error().stack)),new Date(NaN))}function jv(e,t){we(2,arguments);var n=Me(e),r=Ut(t);if(isNaN(r))return new Date(NaN);if(!r)return n;var i=n.getDate(),s=new Date(n.getTime());s.setMonth(n.getMonth()+r+1,0);var o=s.getDate();return i>=o?s:(n.setFullYear(s.getFullYear(),s.getMonth(),i),n)}function YE(e,t){we(2,arguments);var n=Me(e).getTime(),r=Ut(t);return new Date(n+r)}var KE={};function pi(){return KE}function XE(e,t){var n,r,i,s,o,l,a,u;we(1,arguments);var d=pi(),f=Ut((n=(r=(i=(s=t==null?void 0:t.weekStartsOn)!==null&&s!==void 0?s:t==null||(o=t.locale)===null||o===void 0||(l=o.options)===null||l===void 0?void 0:l.weekStartsOn)!==null&&i!==void 0?i:d.weekStartsOn)!==null&&r!==void 0?r:(a=d.locale)===null||a===void 0||(u=a.options)===null||u===void 0?void 0:u.weekStartsOn)!==null&&n!==void 0?n:0);if(!(f>=0&&f<=6))throw new RangeError("weekStartsOn must be between 0 and 6 inclusively");var p=Me(e),w=p.getDay(),h=(w=0&&f<=6))throw new RangeError("weekStartsOn must be between 0 and 6 inclusively");var p=Me(e),w=p.getDay(),h=(w=i.getTime()?n+1:t.getTime()>=o.getTime()?n:n-1}function uC(e){we(1,arguments);var t=Rv(e),n=new Date(0);n.setUTCFullYear(t,0,4),n.setUTCHours(0,0,0,0);var r=al(n);return r}var cC=6048e5;function dC(e){we(1,arguments);var t=Me(e),n=al(t).getTime()-uC(t).getTime();return Math.round(n/cC)+1}function ii(e,t){var n,r,i,s,o,l,a,u;we(1,arguments);var d=pi(),f=Ut((n=(r=(i=(s=t==null?void 0:t.weekStartsOn)!==null&&s!==void 0?s:t==null||(o=t.locale)===null||o===void 0||(l=o.options)===null||l===void 0?void 0:l.weekStartsOn)!==null&&i!==void 0?i:d.weekStartsOn)!==null&&r!==void 0?r:(a=d.locale)===null||a===void 0||(u=a.options)===null||u===void 0?void 0:u.weekStartsOn)!==null&&n!==void 0?n:0);if(!(f>=0&&f<=6))throw new RangeError("weekStartsOn must be between 0 and 6 inclusively");var p=Me(e),w=p.getUTCDay(),h=(w=1&&w<=7))throw new RangeError("firstWeekContainsDate must be between 1 and 7 inclusively");var h=new Date(0);h.setUTCFullYear(f+1,0,w),h.setUTCHours(0,0,0,0);var v=ii(h,t),k=new Date(0);k.setUTCFullYear(f,0,w),k.setUTCHours(0,0,0,0);var g=ii(k,t);return d.getTime()>=v.getTime()?f+1:d.getTime()>=g.getTime()?f:f-1}function fC(e,t){var n,r,i,s,o,l,a,u;we(1,arguments);var d=pi(),f=Ut((n=(r=(i=(s=t==null?void 0:t.firstWeekContainsDate)!==null&&s!==void 0?s:t==null||(o=t.locale)===null||o===void 0||(l=o.options)===null||l===void 0?void 0:l.firstWeekContainsDate)!==null&&i!==void 0?i:d.firstWeekContainsDate)!==null&&r!==void 0?r:(a=d.locale)===null||a===void 0||(u=a.options)===null||u===void 0?void 0:u.firstWeekContainsDate)!==null&&n!==void 0?n:1),p=Ov(e,t),w=new Date(0);w.setUTCFullYear(p,0,f),w.setUTCHours(0,0,0,0);var h=ii(w,t);return h}var pC=6048e5;function hC(e,t){we(1,arguments);var n=Me(e),r=ii(n,t).getTime()-fC(n,t).getTime();return Math.round(r/pC)+1}function he(e,t){for(var n=e<0?"-":"",r=Math.abs(e).toString();r.length0?r:1-r;return he(n==="yy"?i%100:i,n.length)},M:function(t,n){var r=t.getUTCMonth();return n==="M"?String(r+1):he(r+1,2)},d:function(t,n){return he(t.getUTCDate(),n.length)},a:function(t,n){var r=t.getUTCHours()/12>=1?"pm":"am";switch(n){case"a":case"aa":return r.toUpperCase();case"aaa":return r;case"aaaaa":return r[0];case"aaaa":default:return r==="am"?"a.m.":"p.m."}},h:function(t,n){return he(t.getUTCHours()%12||12,n.length)},H:function(t,n){return he(t.getUTCHours(),n.length)},m:function(t,n){return he(t.getUTCMinutes(),n.length)},s:function(t,n){return he(t.getUTCSeconds(),n.length)},S:function(t,n){var r=n.length,i=t.getUTCMilliseconds(),s=Math.floor(i*Math.pow(10,r-3));return he(s,n.length)}},Pr={midnight:"midnight",noon:"noon",morning:"morning",afternoon:"afternoon",evening:"evening",night:"night"},mC={G:function(t,n,r){var i=t.getUTCFullYear()>0?1:0;switch(n){case"G":case"GG":case"GGG":return r.era(i,{width:"abbreviated"});case"GGGGG":return r.era(i,{width:"narrow"});case"GGGG":default:return r.era(i,{width:"wide"})}},y:function(t,n,r){if(n==="yo"){var i=t.getUTCFullYear(),s=i>0?i:1-i;return r.ordinalNumber(s,{unit:"year"})}return bn.y(t,n)},Y:function(t,n,r,i){var s=Ov(t,i),o=s>0?s:1-s;if(n==="YY"){var l=o%100;return he(l,2)}return n==="Yo"?r.ordinalNumber(o,{unit:"year"}):he(o,n.length)},R:function(t,n){var r=Rv(t);return he(r,n.length)},u:function(t,n){var r=t.getUTCFullYear();return he(r,n.length)},Q:function(t,n,r){var i=Math.ceil((t.getUTCMonth()+1)/3);switch(n){case"Q":return String(i);case"QQ":return he(i,2);case"Qo":return r.ordinalNumber(i,{unit:"quarter"});case"QQQ":return r.quarter(i,{width:"abbreviated",context:"formatting"});case"QQQQQ":return r.quarter(i,{width:"narrow",context:"formatting"});case"QQQQ":default:return r.quarter(i,{width:"wide",context:"formatting"})}},q:function(t,n,r){var i=Math.ceil((t.getUTCMonth()+1)/3);switch(n){case"q":return String(i);case"qq":return he(i,2);case"qo":return r.ordinalNumber(i,{unit:"quarter"});case"qqq":return r.quarter(i,{width:"abbreviated",context:"standalone"});case"qqqqq":return r.quarter(i,{width:"narrow",context:"standalone"});case"qqqq":default:return r.quarter(i,{width:"wide",context:"standalone"})}},M:function(t,n,r){var i=t.getUTCMonth();switch(n){case"M":case"MM":return bn.M(t,n);case"Mo":return r.ordinalNumber(i+1,{unit:"month"});case"MMM":return r.month(i,{width:"abbreviated",context:"formatting"});case"MMMMM":return r.month(i,{width:"narrow",context:"formatting"});case"MMMM":default:return r.month(i,{width:"wide",context:"formatting"})}},L:function(t,n,r){var i=t.getUTCMonth();switch(n){case"L":return String(i+1);case"LL":return he(i+1,2);case"Lo":return r.ordinalNumber(i+1,{unit:"month"});case"LLL":return r.month(i,{width:"abbreviated",context:"standalone"});case"LLLLL":return r.month(i,{width:"narrow",context:"standalone"});case"LLLL":default:return r.month(i,{width:"wide",context:"standalone"})}},w:function(t,n,r,i){var s=hC(t,i);return n==="wo"?r.ordinalNumber(s,{unit:"week"}):he(s,n.length)},I:function(t,n,r){var i=dC(t);return n==="Io"?r.ordinalNumber(i,{unit:"week"}):he(i,n.length)},d:function(t,n,r){return n==="do"?r.ordinalNumber(t.getUTCDate(),{unit:"date"}):bn.d(t,n)},D:function(t,n,r){var i=aC(t);return n==="Do"?r.ordinalNumber(i,{unit:"dayOfYear"}):he(i,n.length)},E:function(t,n,r){var i=t.getUTCDay();switch(n){case"E":case"EE":case"EEE":return r.day(i,{width:"abbreviated",context:"formatting"});case"EEEEE":return r.day(i,{width:"narrow",context:"formatting"});case"EEEEEE":return r.day(i,{width:"short",context:"formatting"});case"EEEE":default:return r.day(i,{width:"wide",context:"formatting"})}},e:function(t,n,r,i){var s=t.getUTCDay(),o=(s-i.weekStartsOn+8)%7||7;switch(n){case"e":return String(o);case"ee":return he(o,2);case"eo":return r.ordinalNumber(o,{unit:"day"});case"eee":return r.day(s,{width:"abbreviated",context:"formatting"});case"eeeee":return r.day(s,{width:"narrow",context:"formatting"});case"eeeeee":return r.day(s,{width:"short",context:"formatting"});case"eeee":default:return r.day(s,{width:"wide",context:"formatting"})}},c:function(t,n,r,i){var s=t.getUTCDay(),o=(s-i.weekStartsOn+8)%7||7;switch(n){case"c":return String(o);case"cc":return he(o,n.length);case"co":return r.ordinalNumber(o,{unit:"day"});case"ccc":return r.day(s,{width:"abbreviated",context:"standalone"});case"ccccc":return r.day(s,{width:"narrow",context:"standalone"});case"cccccc":return r.day(s,{width:"short",context:"standalone"});case"cccc":default:return r.day(s,{width:"wide",context:"standalone"})}},i:function(t,n,r){var i=t.getUTCDay(),s=i===0?7:i;switch(n){case"i":return String(s);case"ii":return he(s,n.length);case"io":return r.ordinalNumber(s,{unit:"day"});case"iii":return r.day(i,{width:"abbreviated",context:"formatting"});case"iiiii":return r.day(i,{width:"narrow",context:"formatting"});case"iiiiii":return r.day(i,{width:"short",context:"formatting"});case"iiii":default:return r.day(i,{width:"wide",context:"formatting"})}},a:function(t,n,r){var i=t.getUTCHours(),s=i/12>=1?"pm":"am";switch(n){case"a":case"aa":return r.dayPeriod(s,{width:"abbreviated",context:"formatting"});case"aaa":return r.dayPeriod(s,{width:"abbreviated",context:"formatting"}).toLowerCase();case"aaaaa":return r.dayPeriod(s,{width:"narrow",context:"formatting"});case"aaaa":default:return r.dayPeriod(s,{width:"wide",context:"formatting"})}},b:function(t,n,r){var i=t.getUTCHours(),s;switch(i===12?s=Pr.noon:i===0?s=Pr.midnight:s=i/12>=1?"pm":"am",n){case"b":case"bb":return r.dayPeriod(s,{width:"abbreviated",context:"formatting"});case"bbb":return r.dayPeriod(s,{width:"abbreviated",context:"formatting"}).toLowerCase();case"bbbbb":return r.dayPeriod(s,{width:"narrow",context:"formatting"});case"bbbb":default:return r.dayPeriod(s,{width:"wide",context:"formatting"})}},B:function(t,n,r){var i=t.getUTCHours(),s;switch(i>=17?s=Pr.evening:i>=12?s=Pr.afternoon:i>=4?s=Pr.morning:s=Pr.night,n){case"B":case"BB":case"BBB":return r.dayPeriod(s,{width:"abbreviated",context:"formatting"});case"BBBBB":return r.dayPeriod(s,{width:"narrow",context:"formatting"});case"BBBB":default:return r.dayPeriod(s,{width:"wide",context:"formatting"})}},h:function(t,n,r){if(n==="ho"){var i=t.getUTCHours()%12;return i===0&&(i=12),r.ordinalNumber(i,{unit:"hour"})}return bn.h(t,n)},H:function(t,n,r){return n==="Ho"?r.ordinalNumber(t.getUTCHours(),{unit:"hour"}):bn.H(t,n)},K:function(t,n,r){var i=t.getUTCHours()%12;return n==="Ko"?r.ordinalNumber(i,{unit:"hour"}):he(i,n.length)},k:function(t,n,r){var i=t.getUTCHours();return i===0&&(i=24),n==="ko"?r.ordinalNumber(i,{unit:"hour"}):he(i,n.length)},m:function(t,n,r){return n==="mo"?r.ordinalNumber(t.getUTCMinutes(),{unit:"minute"}):bn.m(t,n)},s:function(t,n,r){return n==="so"?r.ordinalNumber(t.getUTCSeconds(),{unit:"second"}):bn.s(t,n)},S:function(t,n){return bn.S(t,n)},X:function(t,n,r,i){var s=i._originalDate||t,o=s.getTimezoneOffset();if(o===0)return"Z";switch(n){case"X":return Dp(o);case"XXXX":case"XX":return sr(o);case"XXXXX":case"XXX":default:return sr(o,":")}},x:function(t,n,r,i){var s=i._originalDate||t,o=s.getTimezoneOffset();switch(n){case"x":return Dp(o);case"xxxx":case"xx":return sr(o);case"xxxxx":case"xxx":default:return sr(o,":")}},O:function(t,n,r,i){var s=i._originalDate||t,o=s.getTimezoneOffset();switch(n){case"O":case"OO":case"OOO":return"GMT"+Mp(o,":");case"OOOO":default:return"GMT"+sr(o,":")}},z:function(t,n,r,i){var s=i._originalDate||t,o=s.getTimezoneOffset();switch(n){case"z":case"zz":case"zzz":return"GMT"+Mp(o,":");case"zzzz":default:return"GMT"+sr(o,":")}},t:function(t,n,r,i){var s=i._originalDate||t,o=Math.floor(s.getTime()/1e3);return he(o,n.length)},T:function(t,n,r,i){var s=i._originalDate||t,o=s.getTime();return he(o,n.length)}};function Mp(e,t){var n=e>0?"-":"+",r=Math.abs(e),i=Math.floor(r/60),s=r%60;if(s===0)return n+String(i);var o=t;return n+String(i)+o+he(s,2)}function Dp(e,t){if(e%60===0){var n=e>0?"-":"+";return n+he(Math.abs(e)/60,2)}return sr(e,t)}function sr(e,t){var n=t||"",r=e>0?"-":"+",i=Math.abs(e),s=he(Math.floor(i/60),2),o=he(i%60,2);return r+s+n+o}var Ap=function(t,n){switch(t){case"P":return n.date({width:"short"});case"PP":return n.date({width:"medium"});case"PPP":return n.date({width:"long"});case"PPPP":default:return n.date({width:"full"})}},Lv=function(t,n){switch(t){case"p":return n.time({width:"short"});case"pp":return n.time({width:"medium"});case"ppp":return n.time({width:"long"});case"pppp":default:return n.time({width:"full"})}},gC=function(t,n){var r=t.match(/(P+)(p+)?/)||[],i=r[1],s=r[2];if(!s)return Ap(t,n);var o;switch(i){case"P":o=n.dateTime({width:"short"});break;case"PP":o=n.dateTime({width:"medium"});break;case"PPP":o=n.dateTime({width:"long"});break;case"PPPP":default:o=n.dateTime({width:"full"});break}return o.replace("{{date}}",Ap(i,n)).replace("{{time}}",Lv(s,n))},vC={p:Lv,P:gC},yC=["D","DD"],wC=["YY","YYYY"];function xC(e){return yC.indexOf(e)!==-1}function kC(e){return wC.indexOf(e)!==-1}function $p(e,t,n){if(e==="YYYY")throw new RangeError("Use `yyyy` instead of `YYYY` (in `".concat(t,"`) for formatting years to the input `").concat(n,"`; see: https://github.com/date-fns/date-fns/blob/master/docs/unicodeTokens.md"));if(e==="YY")throw new RangeError("Use `yy` instead of `YY` (in `".concat(t,"`) for formatting years to the input `").concat(n,"`; see: https://github.com/date-fns/date-fns/blob/master/docs/unicodeTokens.md"));if(e==="D")throw new RangeError("Use `d` instead of `D` (in `".concat(t,"`) for formatting days of the month to the input `").concat(n,"`; see: https://github.com/date-fns/date-fns/blob/master/docs/unicodeTokens.md"));if(e==="DD")throw new RangeError("Use `dd` instead of `DD` (in `".concat(t,"`) for formatting days of the month to the input `").concat(n,"`; see: https://github.com/date-fns/date-fns/blob/master/docs/unicodeTokens.md"))}var SC={lessThanXSeconds:{one:"less than a second",other:"less than {{count}} seconds"},xSeconds:{one:"1 second",other:"{{count}} seconds"},halfAMinute:"half a minute",lessThanXMinutes:{one:"less than a minute",other:"less than {{count}} minutes"},xMinutes:{one:"1 minute",other:"{{count}} minutes"},aboutXHours:{one:"about 1 hour",other:"about {{count}} hours"},xHours:{one:"1 hour",other:"{{count}} hours"},xDays:{one:"1 day",other:"{{count}} days"},aboutXWeeks:{one:"about 1 week",other:"about {{count}} weeks"},xWeeks:{one:"1 week",other:"{{count}} weeks"},aboutXMonths:{one:"about 1 month",other:"about {{count}} months"},xMonths:{one:"1 month",other:"{{count}} months"},aboutXYears:{one:"about 1 year",other:"about {{count}} years"},xYears:{one:"1 year",other:"{{count}} years"},overXYears:{one:"over 1 year",other:"over {{count}} years"},almostXYears:{one:"almost 1 year",other:"almost {{count}} years"}},EC=function(t,n,r){var i,s=SC[t];return typeof s=="string"?i=s:n===1?i=s.one:i=s.other.replace("{{count}}",n.toString()),r!=null&&r.addSuffix?r.comparison&&r.comparison>0?"in "+i:i+" ago":i};function Yr(e){return function(){var t=arguments.length>0&&arguments[0]!==void 0?arguments[0]:{},n=t.width?String(t.width):e.defaultWidth,r=e.formats[n]||e.formats[e.defaultWidth];return r}}var CC={full:"EEEE, MMMM do, y",long:"MMMM do, y",medium:"MMM d, y",short:"MM/dd/yyyy"},bC={full:"h:mm:ss a zzzz",long:"h:mm:ss a z",medium:"h:mm:ss a",short:"h:mm a"},NC={full:"{{date}} 'at' {{time}}",long:"{{date}} 'at' {{time}}",medium:"{{date}}, {{time}}",short:"{{date}}, {{time}}"},TC={date:Yr({formats:CC,defaultWidth:"full"}),time:Yr({formats:bC,defaultWidth:"full"}),dateTime:Yr({formats:NC,defaultWidth:"full"})},jC={lastWeek:"'last' eeee 'at' p",yesterday:"'yesterday at' p",today:"'today at' p",tomorrow:"'tomorrow at' p",nextWeek:"eeee 'at' p",other:"P"},_C=function(t,n,r,i){return jC[t]};function ln(e){return function(t,n){var r=n!=null&&n.context?String(n.context):"standalone",i;if(r==="formatting"&&e.formattingValues){var s=e.defaultFormattingWidth||e.defaultWidth,o=n!=null&&n.width?String(n.width):s;i=e.formattingValues[o]||e.formattingValues[s]}else{var l=e.defaultWidth,a=n!=null&&n.width?String(n.width):e.defaultWidth;i=e.values[a]||e.values[l]}var u=e.argumentCallback?e.argumentCallback(t):t;return i[u]}}var PC={narrow:["B","A"],abbreviated:["BC","AD"],wide:["Before Christ","Anno Domini"]},RC={narrow:["1","2","3","4"],abbreviated:["Q1","Q2","Q3","Q4"],wide:["1st quarter","2nd quarter","3rd quarter","4th quarter"]},OC={narrow:["J","F","M","A","M","J","J","A","S","O","N","D"],abbreviated:["Jan","Feb","Mar","Apr","May","Jun","Jul","Aug","Sep","Oct","Nov","Dec"],wide:["January","February","March","April","May","June","July","August","September","October","November","December"]},LC={narrow:["S","M","T","W","T","F","S"],short:["Su","Mo","Tu","We","Th","Fr","Sa"],abbreviated:["Sun","Mon","Tue","Wed","Thu","Fri","Sat"],wide:["Sunday","Monday","Tuesday","Wednesday","Thursday","Friday","Saturday"]},IC={narrow:{am:"a",pm:"p",midnight:"mi",noon:"n",morning:"morning",afternoon:"afternoon",evening:"evening",night:"night"},abbreviated:{am:"AM",pm:"PM",midnight:"midnight",noon:"noon",morning:"morning",afternoon:"afternoon",evening:"evening",night:"night"},wide:{am:"a.m.",pm:"p.m.",midnight:"midnight",noon:"noon",morning:"morning",afternoon:"afternoon",evening:"evening",night:"night"}},MC={narrow:{am:"a",pm:"p",midnight:"mi",noon:"n",morning:"in the morning",afternoon:"in the afternoon",evening:"in the evening",night:"at night"},abbreviated:{am:"AM",pm:"PM",midnight:"midnight",noon:"noon",morning:"in the morning",afternoon:"in the afternoon",evening:"in the evening",night:"at night"},wide:{am:"a.m.",pm:"p.m.",midnight:"midnight",noon:"noon",morning:"in the morning",afternoon:"in the afternoon",evening:"in the evening",night:"at night"}},DC=function(t,n){var r=Number(t),i=r%100;if(i>20||i<10)switch(i%10){case 1:return r+"st";case 2:return r+"nd";case 3:return r+"rd"}return r+"th"},AC={ordinalNumber:DC,era:ln({values:PC,defaultWidth:"wide"}),quarter:ln({values:RC,defaultWidth:"wide",argumentCallback:function(t){return t-1}}),month:ln({values:OC,defaultWidth:"wide"}),day:ln({values:LC,defaultWidth:"wide"}),dayPeriod:ln({values:IC,defaultWidth:"wide",formattingValues:MC,defaultFormattingWidth:"wide"})};function an(e){return function(t){var n=arguments.length>1&&arguments[1]!==void 0?arguments[1]:{},r=n.width,i=r&&e.matchPatterns[r]||e.matchPatterns[e.defaultMatchWidth],s=t.match(i);if(!s)return null;var o=s[0],l=r&&e.parsePatterns[r]||e.parsePatterns[e.defaultParseWidth],a=Array.isArray(l)?zC(l,function(f){return f.test(o)}):$C(l,function(f){return f.test(o)}),u;u=e.valueCallback?e.valueCallback(a):a,u=n.valueCallback?n.valueCallback(u):u;var d=t.slice(o.length);return{value:u,rest:d}}}function $C(e,t){for(var n in e)if(e.hasOwnProperty(n)&&t(e[n]))return n}function zC(e,t){for(var n=0;n1&&arguments[1]!==void 0?arguments[1]:{},r=t.match(e.matchPattern);if(!r)return null;var i=r[0],s=t.match(e.parsePattern);if(!s)return null;var o=e.valueCallback?e.valueCallback(s[0]):s[0];o=n.valueCallback?n.valueCallback(o):o;var l=t.slice(i.length);return{value:o,rest:l}}}var FC=/^(\d+)(th|st|nd|rd)?/i,UC=/\d+/i,BC={narrow:/^(b|a)/i,abbreviated:/^(b\.?\s?c\.?|b\.?\s?c\.?\s?e\.?|a\.?\s?d\.?|c\.?\s?e\.?)/i,wide:/^(before christ|before common era|anno domini|common era)/i},WC={any:[/^b/i,/^(a|c)/i]},HC={narrow:/^[1234]/i,abbreviated:/^q[1234]/i,wide:/^[1234](th|st|nd|rd)? quarter/i},VC={any:[/1/i,/2/i,/3/i,/4/i]},QC={narrow:/^[jfmasond]/i,abbreviated:/^(jan|feb|mar|apr|may|jun|jul|aug|sep|oct|nov|dec)/i,wide:/^(january|february|march|april|may|june|july|august|september|october|november|december)/i},qC={narrow:[/^j/i,/^f/i,/^m/i,/^a/i,/^m/i,/^j/i,/^j/i,/^a/i,/^s/i,/^o/i,/^n/i,/^d/i],any:[/^ja/i,/^f/i,/^mar/i,/^ap/i,/^may/i,/^jun/i,/^jul/i,/^au/i,/^s/i,/^o/i,/^n/i,/^d/i]},GC={narrow:/^[smtwf]/i,short:/^(su|mo|tu|we|th|fr|sa)/i,abbreviated:/^(sun|mon|tue|wed|thu|fri|sat)/i,wide:/^(sunday|monday|tuesday|wednesday|thursday|friday|saturday)/i},YC={narrow:[/^s/i,/^m/i,/^t/i,/^w/i,/^t/i,/^f/i,/^s/i],any:[/^su/i,/^m/i,/^tu/i,/^w/i,/^th/i,/^f/i,/^sa/i]},KC={narrow:/^(a|p|mi|n|(in the|at) (morning|afternoon|evening|night))/i,any:/^([ap]\.?\s?m\.?|midnight|noon|(in the|at) (morning|afternoon|evening|night))/i},XC={any:{am:/^a/i,pm:/^p/i,midnight:/^mi/i,noon:/^no/i,morning:/morning/i,afternoon:/afternoon/i,evening:/evening/i,night:/night/i}},JC={ordinalNumber:Iv({matchPattern:FC,parsePattern:UC,valueCallback:function(t){return parseInt(t,10)}}),era:an({matchPatterns:BC,defaultMatchWidth:"wide",parsePatterns:WC,defaultParseWidth:"any"}),quarter:an({matchPatterns:HC,defaultMatchWidth:"wide",parsePatterns:VC,defaultParseWidth:"any",valueCallback:function(t){return t+1}}),month:an({matchPatterns:QC,defaultMatchWidth:"wide",parsePatterns:qC,defaultParseWidth:"any"}),day:an({matchPatterns:GC,defaultMatchWidth:"wide",parsePatterns:YC,defaultParseWidth:"any"}),dayPeriod:an({matchPatterns:KC,defaultMatchWidth:"any",parsePatterns:XC,defaultParseWidth:"any"})},ZC={code:"en-US",formatDistance:EC,formatLong:TC,formatRelative:_C,localize:AC,match:JC,options:{weekStartsOn:0,firstWeekContainsDate:1}},eb=/[yYQqMLwIdDecihHKkms]o|(\w)\1*|''|'(''|[^'])+('|$)|./g,tb=/P+p+|P+|p+|''|'(''|[^'])+('|$)|./g,nb=/^'([^]*?)'?$/,rb=/''/g,ib=/[a-zA-Z]/;function Fi(e,t,n){var r,i,s,o,l,a,u,d,f,p,w,h,v,k,g,m,y,C;we(2,arguments);var j=String(t),S=pi(),N=(r=(i=n==null?void 0:n.locale)!==null&&i!==void 0?i:S.locale)!==null&&r!==void 0?r:ZC,_=Ut((s=(o=(l=(a=n==null?void 0:n.firstWeekContainsDate)!==null&&a!==void 0?a:n==null||(u=n.locale)===null||u===void 0||(d=u.options)===null||d===void 0?void 0:d.firstWeekContainsDate)!==null&&l!==void 0?l:S.firstWeekContainsDate)!==null&&o!==void 0?o:(f=S.locale)===null||f===void 0||(p=f.options)===null||p===void 0?void 0:p.firstWeekContainsDate)!==null&&s!==void 0?s:1);if(!(_>=1&&_<=7))throw new RangeError("firstWeekContainsDate must be between 1 and 7 inclusively");var D=Ut((w=(h=(v=(k=n==null?void 0:n.weekStartsOn)!==null&&k!==void 0?k:n==null||(g=n.locale)===null||g===void 0||(m=g.options)===null||m===void 0?void 0:m.weekStartsOn)!==null&&v!==void 0?v:S.weekStartsOn)!==null&&h!==void 0?h:(y=S.locale)===null||y===void 0||(C=y.options)===null||C===void 0?void 0:C.weekStartsOn)!==null&&w!==void 0?w:0);if(!(D>=0&&D<=6))throw new RangeError("weekStartsOn must be between 0 and 6 inclusively");if(!N.localize)throw new RangeError("locale must contain localize property");if(!N.formatLong)throw new RangeError("locale must contain formatLong property");var M=Me(e);if(!tC(M))throw new RangeError("Invalid time value");var q=JE(M),X=oC(M,q),te={firstWeekContainsDate:_,weekStartsOn:D,locale:N,_originalDate:M},K=j.match(tb).map(function(z){var Q=z[0];if(Q==="p"||Q==="P"){var se=vC[Q];return se(z,N.formatLong)}return z}).join("").match(eb).map(function(z){if(z==="''")return"'";var Q=z[0];if(Q==="'")return sb(z);var se=mC[Q];if(se)return!(n!=null&&n.useAdditionalWeekYearTokens)&&kC(z)&&$p(z,t,String(e)),!(n!=null&&n.useAdditionalDayOfYearTokens)&&xC(z)&&$p(z,t,String(e)),se(X,z,N.localize,te);if(Q.match(ib))throw new RangeError("Format string contains an unescaped latin alphabet character `"+Q+"`");return z}).join("");return K}function sb(e){var t=e.match(nb);return t?t[1].replace(rb,"'"):e}function ob(e,t){we(2,arguments);var n=Me(e),r=Me(t);return n.getFullYear()===r.getFullYear()&&n.getMonth()===r.getMonth()}function lb(e,t){var n;we(1,arguments);var r=Ut((n=void 0)!==null&&n!==void 0?n:2);if(r!==2&&r!==1&&r!==0)throw new RangeError("additionalDigits must be 0, 1 or 2");if(!(typeof e=="string"||Object.prototype.toString.call(e)==="[object String]"))return new Date(NaN);var i=db(e),s;if(i.date){var o=fb(i.date,r);s=pb(o.restDateString,o.year)}if(!s||isNaN(s.getTime()))return new Date(NaN);var l=s.getTime(),a=0,u;if(i.time&&(a=hb(i.time),isNaN(a)))return new Date(NaN);if(i.timezone){if(u=mb(i.timezone),isNaN(u))return new Date(NaN)}else{var d=new Date(l+a),f=new Date(0);return f.setFullYear(d.getUTCFullYear(),d.getUTCMonth(),d.getUTCDate()),f.setHours(d.getUTCHours(),d.getUTCMinutes(),d.getUTCSeconds(),d.getUTCMilliseconds()),f}return new Date(l+a+u)}var oo={dateTimeDelimiter:/[T ]/,timeZoneDelimiter:/[Z ]/i,timezone:/([Z+-].*)$/},ab=/^-?(?:(\d{3})|(\d{2})(?:-?(\d{2}))?|W(\d{2})(?:-?(\d{1}))?|)$/,ub=/^(\d{2}(?:[.,]\d*)?)(?::?(\d{2}(?:[.,]\d*)?))?(?::?(\d{2}(?:[.,]\d*)?))?$/,cb=/^([+-])(\d{2})(?::?(\d{2}))?$/;function db(e){var t={},n=e.split(oo.dateTimeDelimiter),r;if(n.length>2)return t;if(/:/.test(n[0])?r=n[0]:(t.date=n[0],r=n[1],oo.timeZoneDelimiter.test(t.date)&&(t.date=e.split(oo.timeZoneDelimiter)[0],r=e.substr(t.date.length,e.length))),r){var i=oo.timezone.exec(r);i?(t.time=r.replace(i[1],""),t.timezone=i[1]):t.time=r}return t}function fb(e,t){var n=new RegExp("^(?:(\\d{4}|[+-]\\d{"+(4+t)+"})|(\\d{2}|[+-]\\d{"+(2+t)+"})$)"),r=e.match(n);if(!r)return{year:NaN,restDateString:""};var i=r[1]?parseInt(r[1]):null,s=r[2]?parseInt(r[2]):null;return{year:s===null?i:s*100,restDateString:e.slice((r[1]||r[2]).length)}}function pb(e,t){if(t===null)return new Date(NaN);var n=e.match(ab);if(!n)return new Date(NaN);var r=!!n[4],i=Ri(n[1]),s=Ri(n[2])-1,o=Ri(n[3]),l=Ri(n[4]),a=Ri(n[5])-1;if(r)return xb(t,l,a)?gb(t,l,a):new Date(NaN);var u=new Date(0);return!yb(t,s,o)||!wb(t,i)?new Date(NaN):(u.setUTCFullYear(t,s,Math.max(i,o)),u)}function Ri(e){return e?parseInt(e):1}function hb(e){var t=e.match(ub);if(!t)return NaN;var n=Ia(t[1]),r=Ia(t[2]),i=Ia(t[3]);return kb(n,r,i)?n*Pv+r*_v+i*1e3:NaN}function Ia(e){return e&&parseFloat(e.replace(",","."))||0}function mb(e){if(e==="Z")return 0;var t=e.match(cb);if(!t)return 0;var n=t[1]==="+"?-1:1,r=parseInt(t[2]),i=t[3]&&parseInt(t[3])||0;return Sb(r,i)?n*(r*Pv+i*_v):NaN}function gb(e,t,n){var r=new Date(0);r.setUTCFullYear(e,0,4);var i=r.getUTCDay()||7,s=(t-1)*7+n+1-i;return r.setUTCDate(r.getUTCDate()+s),r}var vb=[31,null,31,30,31,30,31,31,30,31,30,31];function Mv(e){return e%400===0||e%4===0&&e%100!==0}function yb(e,t,n){return t>=0&&t<=11&&n>=1&&n<=(vb[t]||(Mv(e)?29:28))}function wb(e,t){return t>=1&&t<=(Mv(e)?366:365)}function xb(e,t,n){return t>=1&&t<=53&&n>=0&&n<=6}function kb(e,t,n){return e===24?t===0&&n===0:n>=0&&n<60&&t>=0&&t<60&&e>=0&&e<25}function Sb(e,t){return t>=0&&t<=59}function Eb(e,t){we(2,arguments);var n=Ut(t);return jv(e,-n)}function zp(e,t,n){we(2,arguments);var r=ii(e,n),i=ii(t,n);return r.getTime()===i.getTime()}function Oi(e,t){if(e.one!==void 0&&t===1)return e.one;var n=t%10,r=t%100;return n===1&&r!==11?e.singularNominative.replace("{{count}}",String(t)):n>=2&&n<=4&&(r<10||r>20)?e.singularGenitive.replace("{{count}}",String(t)):e.pluralGenitive.replace("{{count}}",String(t))}function at(e){return function(t,n){return n!=null&&n.addSuffix?n.comparison&&n.comparison>0?e.future?Oi(e.future,t):"через "+Oi(e.regular,t):e.past?Oi(e.past,t):Oi(e.regular,t)+" назад":Oi(e.regular,t)}}var Cb={lessThanXSeconds:at({regular:{one:"меньше секунды",singularNominative:"меньше {{count}} секунды",singularGenitive:"меньше {{count}} секунд",pluralGenitive:"меньше {{count}} секунд"},future:{one:"меньше, чем через секунду",singularNominative:"меньше, чем через {{count}} секунду",singularGenitive:"меньше, чем через {{count}} секунды",pluralGenitive:"меньше, чем через {{count}} секунд"}}),xSeconds:at({regular:{singularNominative:"{{count}} секунда",singularGenitive:"{{count}} секунды",pluralGenitive:"{{count}} секунд"},past:{singularNominative:"{{count}} секунду назад",singularGenitive:"{{count}} секунды назад",pluralGenitive:"{{count}} секунд назад"},future:{singularNominative:"через {{count}} секунду",singularGenitive:"через {{count}} секунды",pluralGenitive:"через {{count}} секунд"}}),halfAMinute:function(t,n){return n!=null&&n.addSuffix?n.comparison&&n.comparison>0?"через полминуты":"полминуты назад":"полминуты"},lessThanXMinutes:at({regular:{one:"меньше минуты",singularNominative:"меньше {{count}} минуты",singularGenitive:"меньше {{count}} минут",pluralGenitive:"меньше {{count}} минут"},future:{one:"меньше, чем через минуту",singularNominative:"меньше, чем через {{count}} минуту",singularGenitive:"меньше, чем через {{count}} минуты",pluralGenitive:"меньше, чем через {{count}} минут"}}),xMinutes:at({regular:{singularNominative:"{{count}} минута",singularGenitive:"{{count}} минуты",pluralGenitive:"{{count}} минут"},past:{singularNominative:"{{count}} минуту назад",singularGenitive:"{{count}} минуты назад",pluralGenitive:"{{count}} минут назад"},future:{singularNominative:"через {{count}} минуту",singularGenitive:"через {{count}} минуты",pluralGenitive:"через {{count}} минут"}}),aboutXHours:at({regular:{singularNominative:"около {{count}} часа",singularGenitive:"около {{count}} часов",pluralGenitive:"около {{count}} часов"},future:{singularNominative:"приблизительно через {{count}} час",singularGenitive:"приблизительно через {{count}} часа",pluralGenitive:"приблизительно через {{count}} часов"}}),xHours:at({regular:{singularNominative:"{{count}} час",singularGenitive:"{{count}} часа",pluralGenitive:"{{count}} часов"}}),xDays:at({regular:{singularNominative:"{{count}} день",singularGenitive:"{{count}} дня",pluralGenitive:"{{count}} дней"}}),aboutXWeeks:at({regular:{singularNominative:"около {{count}} недели",singularGenitive:"около {{count}} недель",pluralGenitive:"около {{count}} недель"},future:{singularNominative:"приблизительно через {{count}} неделю",singularGenitive:"приблизительно через {{count}} недели",pluralGenitive:"приблизительно через {{count}} недель"}}),xWeeks:at({regular:{singularNominative:"{{count}} неделя",singularGenitive:"{{count}} недели",pluralGenitive:"{{count}} недель"}}),aboutXMonths:at({regular:{singularNominative:"около {{count}} месяца",singularGenitive:"около {{count}} месяцев",pluralGenitive:"около {{count}} месяцев"},future:{singularNominative:"приблизительно через {{count}} месяц",singularGenitive:"приблизительно через {{count}} месяца",pluralGenitive:"приблизительно через {{count}} месяцев"}}),xMonths:at({regular:{singularNominative:"{{count}} месяц",singularGenitive:"{{count}} месяца",pluralGenitive:"{{count}} месяцев"}}),aboutXYears:at({regular:{singularNominative:"около {{count}} года",singularGenitive:"около {{count}} лет",pluralGenitive:"около {{count}} лет"},future:{singularNominative:"приблизительно через {{count}} год",singularGenitive:"приблизительно через {{count}} года",pluralGenitive:"приблизительно через {{count}} лет"}}),xYears:at({regular:{singularNominative:"{{count}} год",singularGenitive:"{{count}} года",pluralGenitive:"{{count}} лет"}}),overXYears:at({regular:{singularNominative:"больше {{count}} года",singularGenitive:"больше {{count}} лет",pluralGenitive:"больше {{count}} лет"},future:{singularNominative:"больше, чем через {{count}} год",singularGenitive:"больше, чем через {{count}} года",pluralGenitive:"больше, чем через {{count}} лет"}}),almostXYears:at({regular:{singularNominative:"почти {{count}} год",singularGenitive:"почти {{count}} года",pluralGenitive:"почти {{count}} лет"},future:{singularNominative:"почти через {{count}} год",singularGenitive:"почти через {{count}} года",pluralGenitive:"почти через {{count}} лет"}})},bb=function(t,n,r){return Cb[t](n,r)},Nb={full:"EEEE, d MMMM y 'г.'",long:"d MMMM y 'г.'",medium:"d MMM y 'г.'",short:"dd.MM.y"},Tb={full:"H:mm:ss zzzz",long:"H:mm:ss z",medium:"H:mm:ss",short:"H:mm"},jb={any:"{{date}}, {{time}}"},_b={date:Yr({formats:Nb,defaultWidth:"full"}),time:Yr({formats:Tb,defaultWidth:"full"}),dateTime:Yr({formats:jb,defaultWidth:"any"})},wd=["воскресенье","понедельник","вторник","среду","четверг","пятницу","субботу"];function Pb(e){var t=wd[e];switch(e){case 0:return"'в прошлое "+t+" в' p";case 1:case 2:case 4:return"'в прошлый "+t+" в' p";case 3:case 5:case 6:return"'в прошлую "+t+" в' p"}}function Fp(e){var t=wd[e];return e===2?"'во "+t+" в' p":"'в "+t+" в' p"}function Rb(e){var t=wd[e];switch(e){case 0:return"'в следующее "+t+" в' p";case 1:case 2:case 4:return"'в следующий "+t+" в' p";case 3:case 5:case 6:return"'в следующую "+t+" в' p"}}var Ob={lastWeek:function(t,n,r){var i=t.getUTCDay();return zp(t,n,r)?Fp(i):Pb(i)},yesterday:"'вчера в' p",today:"'сегодня в' p",tomorrow:"'завтра в' p",nextWeek:function(t,n,r){var i=t.getUTCDay();return zp(t,n,r)?Fp(i):Rb(i)},other:"P"},Lb=function(t,n,r,i){var s=Ob[t];return typeof s=="function"?s(n,r,i):s},Ib={narrow:["до н.э.","н.э."],abbreviated:["до н. э.","н. э."],wide:["до нашей эры","нашей эры"]},Mb={narrow:["1","2","3","4"],abbreviated:["1-й кв.","2-й кв.","3-й кв.","4-й кв."],wide:["1-й квартал","2-й квартал","3-й квартал","4-й квартал"]},Db={narrow:["Я","Ф","М","А","М","И","И","А","С","О","Н","Д"],abbreviated:["янв.","фев.","март","апр.","май","июнь","июль","авг.","сент.","окт.","нояб.","дек."],wide:["январь","февраль","март","апрель","май","июнь","июль","август","сентябрь","октябрь","ноябрь","декабрь"]},Ab={narrow:["Я","Ф","М","А","М","И","И","А","С","О","Н","Д"],abbreviated:["янв.","фев.","мар.","апр.","мая","июн.","июл.","авг.","сент.","окт.","нояб.","дек."],wide:["января","февраля","марта","апреля","мая","июня","июля","августа","сентября","октября","ноября","декабря"]},$b={narrow:["В","П","В","С","Ч","П","С"],short:["вс","пн","вт","ср","чт","пт","сб"],abbreviated:["вск","пнд","втр","срд","чтв","птн","суб"],wide:["воскресенье","понедельник","вторник","среда","четверг","пятница","суббота"]},zb={narrow:{am:"ДП",pm:"ПП",midnight:"полн.",noon:"полд.",morning:"утро",afternoon:"день",evening:"веч.",night:"ночь"},abbreviated:{am:"ДП",pm:"ПП",midnight:"полн.",noon:"полд.",morning:"утро",afternoon:"день",evening:"веч.",night:"ночь"},wide:{am:"ДП",pm:"ПП",midnight:"полночь",noon:"полдень",morning:"утро",afternoon:"день",evening:"вечер",night:"ночь"}},Fb={narrow:{am:"ДП",pm:"ПП",midnight:"полн.",noon:"полд.",morning:"утра",afternoon:"дня",evening:"веч.",night:"ночи"},abbreviated:{am:"ДП",pm:"ПП",midnight:"полн.",noon:"полд.",morning:"утра",afternoon:"дня",evening:"веч.",night:"ночи"},wide:{am:"ДП",pm:"ПП",midnight:"полночь",noon:"полдень",morning:"утра",afternoon:"дня",evening:"вечера",night:"ночи"}},Ub=function(t,n){var r=Number(t),i=n==null?void 0:n.unit,s;return i==="date"?s="-е":i==="week"||i==="minute"||i==="second"?s="-я":s="-й",r+s},Bb={ordinalNumber:Ub,era:ln({values:Ib,defaultWidth:"wide"}),quarter:ln({values:Mb,defaultWidth:"wide",argumentCallback:function(t){return t-1}}),month:ln({values:Db,defaultWidth:"wide",formattingValues:Ab,defaultFormattingWidth:"wide"}),day:ln({values:$b,defaultWidth:"wide"}),dayPeriod:ln({values:zb,defaultWidth:"any",formattingValues:Fb,defaultFormattingWidth:"wide"})},Wb=/^(\d+)(-?(е|я|й|ое|ье|ая|ья|ый|ой|ий|ый))?/i,Hb=/\d+/i,Vb={narrow:/^((до )?н\.?\s?э\.?)/i,abbreviated:/^((до )?н\.?\s?э\.?)/i,wide:/^(до нашей эры|нашей эры|наша эра)/i},Qb={any:[/^д/i,/^н/i]},qb={narrow:/^[1234]/i,abbreviated:/^[1234](-?[ыои]?й?)? кв.?/i,wide:/^[1234](-?[ыои]?й?)? квартал/i},Gb={any:[/1/i,/2/i,/3/i,/4/i]},Yb={narrow:/^[яфмаисонд]/i,abbreviated:/^(янв|фев|март?|апр|ма[йя]|июн[ья]?|июл[ья]?|авг|сент?|окт|нояб?|дек)\.?/i,wide:/^(январ[ья]|феврал[ья]|марта?|апрел[ья]|ма[йя]|июн[ья]|июл[ья]|августа?|сентябр[ья]|октябр[ья]|октябр[ья]|ноябр[ья]|декабр[ья])/i},Kb={narrow:[/^я/i,/^ф/i,/^м/i,/^а/i,/^м/i,/^и/i,/^и/i,/^а/i,/^с/i,/^о/i,/^н/i,/^я/i],any:[/^я/i,/^ф/i,/^мар/i,/^ап/i,/^ма[йя]/i,/^июн/i,/^июл/i,/^ав/i,/^с/i,/^о/i,/^н/i,/^д/i]},Xb={narrow:/^[впсч]/i,short:/^(вс|во|пн|по|вт|ср|чт|че|пт|пя|сб|су)\.?/i,abbreviated:/^(вск|вос|пнд|пон|втр|вто|срд|сре|чтв|чет|птн|пят|суб).?/i,wide:/^(воскресень[ея]|понедельника?|вторника?|сред[аы]|четверга?|пятниц[аы]|суббот[аы])/i},Jb={narrow:[/^в/i,/^п/i,/^в/i,/^с/i,/^ч/i,/^п/i,/^с/i],any:[/^в[ос]/i,/^п[он]/i,/^в/i,/^ср/i,/^ч/i,/^п[ят]/i,/^с[уб]/i]},Zb={narrow:/^([дп]п|полн\.?|полд\.?|утр[оа]|день|дня|веч\.?|ноч[ьи])/i,abbreviated:/^([дп]п|полн\.?|полд\.?|утр[оа]|день|дня|веч\.?|ноч[ьи])/i,wide:/^([дп]п|полночь|полдень|утр[оа]|день|дня|вечера?|ноч[ьи])/i},eN={any:{am:/^дп/i,pm:/^пп/i,midnight:/^полн/i,noon:/^полд/i,morning:/^у/i,afternoon:/^д[ен]/i,evening:/^в/i,night:/^н/i}},tN={ordinalNumber:Iv({matchPattern:Wb,parsePattern:Hb,valueCallback:function(t){return parseInt(t,10)}}),era:an({matchPatterns:Vb,defaultMatchWidth:"wide",parsePatterns:Qb,defaultParseWidth:"any"}),quarter:an({matchPatterns:qb,defaultMatchWidth:"wide",parsePatterns:Gb,defaultParseWidth:"any",valueCallback:function(t){return t+1}}),month:an({matchPatterns:Yb,defaultMatchWidth:"wide",parsePatterns:Kb,defaultParseWidth:"any"}),day:an({matchPatterns:Xb,defaultMatchWidth:"wide",parsePatterns:Jb,defaultParseWidth:"any"}),dayPeriod:an({matchPatterns:Zb,defaultMatchWidth:"wide",parsePatterns:eN,defaultParseWidth:"any"})},Dv={code:"ru",formatDistance:bb,formatLong:_b,formatRelative:Lb,localize:Bb,match:tN,options:{weekStartsOn:1,firstWeekContainsDate:1}};const Zu=e=>lb(e.replace(" ","T")+"Z"),Up=e=>{const t=String(e.getDate()).padStart(2,"0"),n=String(e.getMonth()+1).padStart(2,"0"),r=e.getFullYear(),i=String(e.getHours()).padStart(2,"0"),s=String(e.getMinutes()).padStart(2,"0");return`${t}.${n}.${r} ${i}:${s}`.substring(0,16)},nN=e=>Fi(e,"dd.MM.yyyy",{locale:Dv}),Bp=e=>{const t=Zu(e);return nN(t)},Av=({notes:e=[]})=>{const[t,n]=x.useState(new Date),r=ye(g=>g.notes.selectedDate),i=ot(),s=iC(t),o=nC(t),l=XE(s,{weekStartsOn:1}),a=sC(o,{weekStartsOn:1}),u=rC({start:l,end:a}),d=new Set,f=new Set;e.forEach(g=>{g.created_at&&d.add(Bp(g.created_at)),g.updated_at&&g.created_at!==g.updated_at&&f.add(Bp(g.updated_at))});const p=g=>{const m=Fi(g,"dd.MM.yyyy");i(Fu(r===m?null:m))},w=()=>{n(Eb(t,1))},h=()=>{n(jv(t,1))},v=Fi(t,"MMMM yyyy",{locale:Dv}),k=v.charAt(0).toUpperCase()+v.slice(1);return c.jsxs("div",{className:"mini-calendar",children:[c.jsxs("div",{className:"calendar-header",children:[c.jsx("button",{className:"calendar-nav",onClick:w,children:"‹"}),c.jsx("span",{className:"calendar-month-year",children:k}),c.jsx("button",{className:"calendar-nav",onClick:h,children:"›"})]}),c.jsxs("div",{className:"calendar-weekdays",children:[c.jsx("div",{className:"calendar-weekday",children:"Пн"}),c.jsx("div",{className:"calendar-weekday",children:"Вт"}),c.jsx("div",{className:"calendar-weekday",children:"Ср"}),c.jsx("div",{className:"calendar-weekday",children:"Чт"}),c.jsx("div",{className:"calendar-weekday",children:"Пт"}),c.jsx("div",{className:"calendar-weekday",children:"Сб"}),c.jsx("div",{className:"calendar-weekday",children:"Вс"})]}),c.jsx("div",{className:"calendar-days",children:u.map((g,m)=>{const y=Fi(g,"dd.MM.yyyy"),C=ob(g,t),j=r===y,S=d.has(y),N=f.has(y),_=ZE(g,new Date);return c.jsx("div",{className:`calendar-day ${C?"":"other-month"} ${S?"has-notes":""} ${N?"has-edited-notes":""} ${j?"selected":""} ${_?"today":""}`,"data-date":y,onClick:()=>p(g),children:Fi(g,"d")},m)})})]})},$v=()=>{const[e,t]=x.useState(""),n=ot(),r=x.useRef(null);x.useEffect(()=>(r.current&&clearTimeout(r.current),r.current=setTimeout(()=>{n(Uu(e))},300),()=>{r.current&&clearTimeout(r.current)}),[e,n]);const i=()=>{t(""),n(Uu(""))};return c.jsxs("div",{className:"search-section",children:[c.jsx("div",{className:"search-header",children:c.jsxs("span",{className:"search-title",children:[c.jsx(F,{icon:"mdi:magnify"})," Поиск"]})}),c.jsxs("div",{className:"search-container",children:[c.jsx("input",{type:"text",className:"search-input",placeholder:"Поиск по заметкам...",value:e,onChange:s=>t(s.target.value)}),e&&c.jsx("button",{className:"clear-search-btn",onClick:i,title:"Очистить поиск",children:"✕"})]})]})};function xd(){return{async:!1,breaks:!1,extensions:null,gfm:!0,hooks:null,pedantic:!1,renderer:null,silent:!1,tokenizer:null,walkTokens:null}}var jr=xd();function zv(e){jr=e}var Zi={exec:()=>null};function ce(e,t=""){let n=typeof e=="string"?e:e.source,r={replace:(i,s)=>{let o=typeof s=="string"?s:s.source;return o=o.replace(dt.caret,"$1"),n=n.replace(i,o),r},getRegex:()=>new RegExp(n,t)};return r}var dt={codeRemoveIndent:/^(?: {1,4}| {0,3}\t)/gm,outputLinkReplace:/\\([\[\]])/g,indentCodeCompensation:/^(\s+)(?:```)/,beginningSpace:/^\s+/,endingHash:/#$/,startingSpaceChar:/^ /,endingSpaceChar:/ $/,nonSpaceChar:/[^ ]/,newLineCharGlobal:/\n/g,tabCharGlobal:/\t/g,multipleSpaceGlobal:/\s+/g,blankLine:/^[ \t]*$/,doubleBlankLine:/\n[ \t]*\n[ \t]*$/,blockquoteStart:/^ {0,3}>/,blockquoteSetextReplace:/\n {0,3}((?:=+|-+) *)(?=\n|$)/g,blockquoteSetextReplace2:/^ {0,3}>[ \t]?/gm,listReplaceTabs:/^\t+/,listReplaceNesting:/^ {1,4}(?=( {4})*[^ ])/g,listIsTask:/^\[[ xX]\] /,listReplaceTask:/^\[[ xX]\] +/,anyLine:/\n.*\n/,hrefBrackets:/^<(.*)>$/,tableDelimiter:/[:|]/,tableAlignChars:/^\||\| *$/g,tableRowBlankLine:/\n[ \t]*$/,tableAlignRight:/^ *-+: *$/,tableAlignCenter:/^ *:-+: *$/,tableAlignLeft:/^ *:-+ *$/,startATag:/^/i,startPreScriptTag:/^<(pre|code|kbd|script)(\s|>)/i,endPreScriptTag:/^<\/(pre|code|kbd|script)(\s|>)/i,startAngleBracket:/^$/,pedanticHrefTitle:/^([^'"]*[^\s])\s+(['"])(.*)\2/,unicodeAlphaNumeric:/[\p{L}\p{N}]/u,escapeTest:/[&<>"']/,escapeReplace:/[&<>"']/g,escapeTestNoEncode:/[<>"']|&(?!(#\d{1,7}|#[Xx][a-fA-F0-9]{1,6}|\w+);)/,escapeReplaceNoEncode:/[<>"']|&(?!(#\d{1,7}|#[Xx][a-fA-F0-9]{1,6}|\w+);)/g,unescapeTest:/&(#(?:\d+)|(?:#x[0-9A-Fa-f]+)|(?:\w+));?/ig,caret:/(^|[^\[])\^/g,percentDecode:/%25/g,findPipe:/\|/g,splitPipe:/ \|/,slashPipe:/\\\|/g,carriageReturn:/\r\n|\r/g,spaceLine:/^ +$/gm,notSpaceStart:/^\S*/,endingNewline:/\n$/,listItemRegex:e=>new RegExp(`^( {0,3}${e})((?:[ ][^\\n]*)?(?:\\n|$))`),nextBulletRegex:e=>new RegExp(`^ {0,${Math.min(3,e-1)}}(?:[*+-]|\\d{1,9}[.)])((?:[ ][^\\n]*)?(?:\\n|$))`),hrRegex:e=>new RegExp(`^ {0,${Math.min(3,e-1)}}((?:- *){3,}|(?:_ *){3,}|(?:\\* *){3,})(?:\\n+|$)`),fencesBeginRegex:e=>new RegExp(`^ {0,${Math.min(3,e-1)}}(?:\`\`\`|~~~)`),headingBeginRegex:e=>new RegExp(`^ {0,${Math.min(3,e-1)}}#`),htmlBeginRegex:e=>new RegExp(`^ {0,${Math.min(3,e-1)}}<(?:[a-z].*>|!--)`,"i")},rN=/^(?:[ \t]*(?:\n|$))+/,iN=/^((?: {4}| {0,3}\t)[^\n]+(?:\n(?:[ \t]*(?:\n|$))*)?)+/,sN=/^ {0,3}(`{3,}(?=[^`\n]*(?:\n|$))|~{3,})([^\n]*)(?:\n|$)(?:|([\s\S]*?)(?:\n|$))(?: {0,3}\1[~`]* *(?=\n|$)|$)/,As=/^ {0,3}((?:-[\t ]*){3,}|(?:_[ \t]*){3,}|(?:\*[ \t]*){3,})(?:\n+|$)/,oN=/^ {0,3}(#{1,6})(?=\s|$)(.*)(?:\n+|$)/,kd=/(?:[*+-]|\d{1,9}[.)])/,Fv=/^(?!bull |blockCode|fences|blockquote|heading|html|table)((?:.|\n(?!\s*?\n|bull |blockCode|fences|blockquote|heading|html|table))+?)\n {0,3}(=+|-+) *(?:\n+|$)/,Uv=ce(Fv).replace(/bull/g,kd).replace(/blockCode/g,/(?: {4}| {0,3}\t)/).replace(/fences/g,/ {0,3}(?:`{3,}|~{3,})/).replace(/blockquote/g,/ {0,3}>/).replace(/heading/g,/ {0,3}#{1,6}/).replace(/html/g,/ {0,3}<[^\n>]+>\n/).replace(/\|table/g,"").getRegex(),lN=ce(Fv).replace(/bull/g,kd).replace(/blockCode/g,/(?: {4}| {0,3}\t)/).replace(/fences/g,/ {0,3}(?:`{3,}|~{3,})/).replace(/blockquote/g,/ {0,3}>/).replace(/heading/g,/ {0,3}#{1,6}/).replace(/html/g,/ {0,3}<[^\n>]+>\n/).replace(/table/g,/ {0,3}\|?(?:[:\- ]*\|)+[\:\- ]*\n/).getRegex(),Sd=/^([^\n]+(?:\n(?!hr|heading|lheading|blockquote|fences|list|html|table| +\n)[^\n]+)*)/,aN=/^[^\n]+/,Ed=/(?!\s*\])(?:\\[\s\S]|[^\[\]\\])+/,uN=ce(/^ {0,3}\[(label)\]: *(?:\n[ \t]*)?([^<\s][^\s]*|<.*?>)(?:(?: +(?:\n[ \t]*)?| *\n[ \t]*)(title))? *(?:\n+|$)/).replace("label",Ed).replace("title",/(?:"(?:\\"?|[^"\\])*"|'[^'\n]*(?:\n[^'\n]+)*\n?'|\([^()]*\))/).getRegex(),cN=ce(/^( {0,3}bull)([ \t][^\n]+?)?(?:\n|$)/).replace(/bull/g,kd).getRegex(),Fl="address|article|aside|base|basefont|blockquote|body|caption|center|col|colgroup|dd|details|dialog|dir|div|dl|dt|fieldset|figcaption|figure|footer|form|frame|frameset|h[1-6]|head|header|hr|html|iframe|legend|li|link|main|menu|menuitem|meta|nav|noframes|ol|optgroup|option|p|param|search|section|summary|table|tbody|td|tfoot|th|thead|title|tr|track|ul",Cd=/|$))/,dN=ce("^ {0,3}(?:<(script|pre|style|textarea)[\\s>][\\s\\S]*?(?:[^\\n]*\\n+|$)|comment[^\\n]*(\\n+|$)|<\\?[\\s\\S]*?(?:\\?>\\n*|$)|\\n*|$)|\\n*|$)|)[\\s\\S]*?(?:(?:\\n[ ]*)+\\n|$)|<(?!script|pre|style|textarea)([a-z][\\w-]*)(?:attribute)*? */?>(?=[ \\t]*(?:\\n|$))[\\s\\S]*?(?:(?:\\n[ ]*)+\\n|$)|(?=[ \\t]*(?:\\n|$))[\\s\\S]*?(?:(?:\\n[ ]*)+\\n|$))","i").replace("comment",Cd).replace("tag",Fl).replace("attribute",/ +[a-zA-Z:_][\w.:-]*(?: *= *"[^"\n]*"| *= *'[^'\n]*'| *= *[^\s"'=<>`]+)?/).getRegex(),Bv=ce(Sd).replace("hr",As).replace("heading"," {0,3}#{1,6}(?:\\s|$)").replace("|lheading","").replace("|table","").replace("blockquote"," {0,3}>").replace("fences"," {0,3}(?:`{3,}(?=[^`\\n]*\\n)|~{3,})[^\\n]*\\n").replace("list"," {0,3}(?:[*+-]|1[.)]) ").replace("html",")|<(?:script|pre|style|textarea|!--)").replace("tag",Fl).getRegex(),fN=ce(/^( {0,3}> ?(paragraph|[^\n]*)(?:\n|$))+/).replace("paragraph",Bv).getRegex(),bd={blockquote:fN,code:iN,def:uN,fences:sN,heading:oN,hr:As,html:dN,lheading:Uv,list:cN,newline:rN,paragraph:Bv,table:Zi,text:aN},Wp=ce("^ *([^\\n ].*)\\n {0,3}((?:\\| *)?:?-+:? *(?:\\| *:?-+:? *)*(?:\\| *)?)(?:\\n((?:(?! *\\n|hr|heading|blockquote|code|fences|list|html).*(?:\\n|$))*)\\n*|$)").replace("hr",As).replace("heading"," {0,3}#{1,6}(?:\\s|$)").replace("blockquote"," {0,3}>").replace("code","(?: {4}| {0,3} )[^\\n]").replace("fences"," {0,3}(?:`{3,}(?=[^`\\n]*\\n)|~{3,})[^\\n]*\\n").replace("list"," {0,3}(?:[*+-]|1[.)]) ").replace("html",")|<(?:script|pre|style|textarea|!--)").replace("tag",Fl).getRegex(),pN={...bd,lheading:lN,table:Wp,paragraph:ce(Sd).replace("hr",As).replace("heading"," {0,3}#{1,6}(?:\\s|$)").replace("|lheading","").replace("table",Wp).replace("blockquote"," {0,3}>").replace("fences"," {0,3}(?:`{3,}(?=[^`\\n]*\\n)|~{3,})[^\\n]*\\n").replace("list"," {0,3}(?:[*+-]|1[.)]) ").replace("html",")|<(?:script|pre|style|textarea|!--)").replace("tag",Fl).getRegex()},hN={...bd,html:ce(`^ *(?:comment *(?:\\n|\\s*$)|<(tag)[\\s\\S]+? *(?:\\n{2,}|\\s*$)|\\s]*)*?/?> *(?:\\n{2,}|\\s*$))`).replace("comment",Cd).replace(/tag/g,"(?!(?:a|em|strong|small|s|cite|q|dfn|abbr|data|time|code|var|samp|kbd|sub|sup|i|b|u|mark|ruby|rt|rp|bdi|bdo|span|br|wbr|ins|del|img)\\b)\\w+(?!:|[^\\w\\s@]*@)\\b").getRegex(),def:/^ *\[([^\]]+)\]: *]+)>?(?: +(["(][^\n]+[")]))? *(?:\n+|$)/,heading:/^(#{1,6})(.*)(?:\n+|$)/,fences:Zi,lheading:/^(.+?)\n {0,3}(=+|-+) *(?:\n+|$)/,paragraph:ce(Sd).replace("hr",As).replace("heading",` *#{1,6} *[^ +]`).replace("lheading",Uv).replace("|table","").replace("blockquote"," {0,3}>").replace("|fences","").replace("|list","").replace("|html","").replace("|tag","").getRegex()},mN=/^\\([!"#$%&'()*+,\-./:;<=>?@\[\]\\^_`{|}~])/,gN=/^(`+)([^`]|[^`][\s\S]*?[^`])\1(?!`)/,Wv=/^( {2,}|\\)\n(?!\s*$)/,vN=/^(`+|[^`])(?:(?= {2,}\n)|[\s\S]*?(?:(?=[\\`+)[^`]+\\k(?!`))*?\\]\\((?:\\\\[\\s\\S]|[^\\\\\\(\\)]|\\((?:\\\\[\\s\\S]|[^\\\\\\(\\)])*\\))*\\)")).replace("code",new RegExp("(?`+)[^`]+\\k(?!`)")).replace("html",/<(?! )[^<>]*?>/).getRegex(),Qv=/^(?:\*+(?:((?!\*)punct)|[^\s*]))|^_+(?:((?!_)punct)|([^\s_]))/,SN=ce(Qv,"u").replace(/punct/g,Ul).getRegex(),EN=ce(Qv,"u").replace(/punct/g,Vv).getRegex(),qv="^[^_*]*?__[^_*]*?\\*[^_*]*?(?=__)|[^*]+(?=[^*])|(?!\\*)punct(\\*+)(?=[\\s]|$)|notPunctSpace(\\*+)(?!\\*)(?=punctSpace|$)|(?!\\*)punctSpace(\\*+)(?=notPunctSpace)|[\\s](\\*+)(?!\\*)(?=punct)|(?!\\*)punct(\\*+)(?!\\*)(?=punct)|notPunctSpace(\\*+)(?=notPunctSpace)",CN=ce(qv,"gu").replace(/notPunctSpace/g,Hv).replace(/punctSpace/g,Nd).replace(/punct/g,Ul).getRegex(),bN=ce(qv,"gu").replace(/notPunctSpace/g,xN).replace(/punctSpace/g,wN).replace(/punct/g,Vv).getRegex(),NN=ce("^[^_*]*?\\*\\*[^_*]*?_[^_*]*?(?=\\*\\*)|[^_]+(?=[^_])|(?!_)punct(_+)(?=[\\s]|$)|notPunctSpace(_+)(?!_)(?=punctSpace|$)|(?!_)punctSpace(_+)(?=notPunctSpace)|[\\s](_+)(?!_)(?=punct)|(?!_)punct(_+)(?!_)(?=punct)","gu").replace(/notPunctSpace/g,Hv).replace(/punctSpace/g,Nd).replace(/punct/g,Ul).getRegex(),TN=ce(/\\(punct)/,"gu").replace(/punct/g,Ul).getRegex(),jN=ce(/^<(scheme:[^\s\x00-\x1f<>]*|email)>/).replace("scheme",/[a-zA-Z][a-zA-Z0-9+.-]{1,31}/).replace("email",/[a-zA-Z0-9.!#$%&'*+/=?^_`{|}~-]+(@)[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?(?:\.[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?)+(?![-_])/).getRegex(),_N=ce(Cd).replace("(?:-->|$)","-->").getRegex(),PN=ce("^comment|^|^<[a-zA-Z][\\w-]*(?:attribute)*?\\s*/?>|^<\\?[\\s\\S]*?\\?>|^|^").replace("comment",_N).replace("attribute",/\s+[a-zA-Z:_][\w.:-]*(?:\s*=\s*"[^"]*"|\s*=\s*'[^']*'|\s*=\s*[^\s"'=<>`]+)?/).getRegex(),ul=/(?:\[(?:\\[\s\S]|[^\[\]\\])*\]|\\[\s\S]|`+[^`]*?`+(?!`)|[^\[\]\\`])*?/,RN=ce(/^!?\[(label)\]\(\s*(href)(?:(?:[ \t]*(?:\n[ \t]*)?)(title))?\s*\)/).replace("label",ul).replace("href",/<(?:\\.|[^\n<>\\])+>|[^ \t\n\x00-\x1f]*/).replace("title",/"(?:\\"?|[^"\\])*"|'(?:\\'?|[^'\\])*'|\((?:\\\)?|[^)\\])*\)/).getRegex(),Gv=ce(/^!?\[(label)\]\[(ref)\]/).replace("label",ul).replace("ref",Ed).getRegex(),Yv=ce(/^!?\[(ref)\](?:\[\])?/).replace("ref",Ed).getRegex(),ON=ce("reflink|nolink(?!\\()","g").replace("reflink",Gv).replace("nolink",Yv).getRegex(),Hp=/[hH][tT][tT][pP][sS]?|[fF][tT][pP]/,Td={_backpedal:Zi,anyPunctuation:TN,autolink:jN,blockSkip:kN,br:Wv,code:gN,del:Zi,emStrongLDelim:SN,emStrongRDelimAst:CN,emStrongRDelimUnd:NN,escape:mN,link:RN,nolink:Yv,punctuation:yN,reflink:Gv,reflinkSearch:ON,tag:PN,text:vN,url:Zi},LN={...Td,link:ce(/^!?\[(label)\]\((.*?)\)/).replace("label",ul).getRegex(),reflink:ce(/^!?\[(label)\]\s*\[([^\]]*)\]/).replace("label",ul).getRegex()},ec={...Td,emStrongRDelimAst:bN,emStrongLDelim:EN,url:ce(/^((?:protocol):\/\/|www\.)(?:[a-zA-Z0-9\-]+\.?)+[^\s<]*|^email/).replace("protocol",Hp).replace("email",/[A-Za-z0-9._+-]+(@)[a-zA-Z0-9-_]+(?:\.[a-zA-Z0-9-_]*[a-zA-Z0-9])+(?![-_])/).getRegex(),_backpedal:/(?:[^?!.,:;*_'"~()&]+|\([^)]*\)|&(?![a-zA-Z0-9]+;$)|[?!.,:;*_'"~)]+(?!$))+/,del:/^(~~?)(?=[^\s~])((?:\\[\s\S]|[^\\])*?(?:\\[\s\S]|[^\s~\\]))\1(?=[^~]|$)/,text:ce(/^([`~]+|[^`~])(?:(?= {2,}\n)|(?=[a-zA-Z0-9.!#$%&'*+\/=?_`{\|}~-]+@)|[\s\S]*?(?:(?=[\\":">",'"':""","'":"'"},Vp=e=>MN[e];function rn(e,t){if(t){if(dt.escapeTest.test(e))return e.replace(dt.escapeReplace,Vp)}else if(dt.escapeTestNoEncode.test(e))return e.replace(dt.escapeReplaceNoEncode,Vp);return e}function Qp(e){try{e=encodeURI(e).replace(dt.percentDecode,"%")}catch{return null}return e}function qp(e,t){var s;let n=e.replace(dt.findPipe,(o,l,a)=>{let u=!1,d=l;for(;--d>=0&&a[d]==="\\";)u=!u;return u?"|":" |"}),r=n.split(dt.splitPipe),i=0;if(r[0].trim()||r.shift(),r.length>0&&!((s=r.at(-1))!=null&&s.trim())&&r.pop(),t)if(r.length>t)r.splice(t);else for(;r.length0?-2:-1}function Gp(e,t,n,r,i){let s=t.href,o=t.title||null,l=e[1].replace(i.other.outputLinkReplace,"$1");r.state.inLink=!0;let a={type:e[0].charAt(0)==="!"?"image":"link",raw:n,href:s,title:o,text:l,tokens:r.inlineTokens(l)};return r.state.inLink=!1,a}function AN(e,t,n){let r=e.match(n.other.indentCodeCompensation);if(r===null)return t;let i=r[1];return t.split(` +`).map(s=>{let o=s.match(n.other.beginningSpace);if(o===null)return s;let[l]=o;return l.length>=i.length?s.slice(i.length):s}).join(` +`)}var cl=class{constructor(e){ve(this,"options");ve(this,"rules");ve(this,"lexer");this.options=e||jr}space(e){let t=this.rules.block.newline.exec(e);if(t&&t[0].length>0)return{type:"space",raw:t[0]}}code(e){let t=this.rules.block.code.exec(e);if(t){let n=t[0].replace(this.rules.other.codeRemoveIndent,"");return{type:"code",raw:t[0],codeBlockStyle:"indented",text:this.options.pedantic?n:Ii(n,` +`)}}}fences(e){let t=this.rules.block.fences.exec(e);if(t){let n=t[0],r=AN(n,t[3]||"",this.rules);return{type:"code",raw:n,lang:t[2]?t[2].trim().replace(this.rules.inline.anyPunctuation,"$1"):t[2],text:r}}}heading(e){let t=this.rules.block.heading.exec(e);if(t){let n=t[2].trim();if(this.rules.other.endingHash.test(n)){let r=Ii(n,"#");(this.options.pedantic||!r||this.rules.other.endingSpaceChar.test(r))&&(n=r.trim())}return{type:"heading",raw:t[0],depth:t[1].length,text:n,tokens:this.lexer.inline(n)}}}hr(e){let t=this.rules.block.hr.exec(e);if(t)return{type:"hr",raw:Ii(t[0],` +`)}}blockquote(e){let t=this.rules.block.blockquote.exec(e);if(t){let n=Ii(t[0],` +`).split(` +`),r="",i="",s=[];for(;n.length>0;){let o=!1,l=[],a;for(a=0;a1,i={type:"list",raw:"",ordered:r,start:r?+n.slice(0,-1):"",loose:!1,items:[]};n=r?`\\d{1,9}\\${n.slice(-1)}`:`\\${n}`,this.options.pedantic&&(n=r?n:"[*+-]");let s=this.rules.other.listItemRegex(n),o=!1;for(;e;){let a=!1,u="",d="";if(!(t=s.exec(e))||this.rules.block.hr.test(e))break;u=t[0],e=e.substring(u.length);let f=t[2].split(` +`,1)[0].replace(this.rules.other.listReplaceTabs,g=>" ".repeat(3*g.length)),p=e.split(` +`,1)[0],w=!f.trim(),h=0;if(this.options.pedantic?(h=2,d=f.trimStart()):w?h=t[1].length+1:(h=t[2].search(this.rules.other.nonSpaceChar),h=h>4?1:h,d=f.slice(h),h+=t[1].length),w&&this.rules.other.blankLine.test(p)&&(u+=p+` +`,e=e.substring(p.length+1),a=!0),!a){let g=this.rules.other.nextBulletRegex(h),m=this.rules.other.hrRegex(h),y=this.rules.other.fencesBeginRegex(h),C=this.rules.other.headingBeginRegex(h),j=this.rules.other.htmlBeginRegex(h);for(;e;){let S=e.split(` +`,1)[0],N;if(p=S,this.options.pedantic?(p=p.replace(this.rules.other.listReplaceNesting," "),N=p):N=p.replace(this.rules.other.tabCharGlobal," "),y.test(p)||C.test(p)||j.test(p)||g.test(p)||m.test(p))break;if(N.search(this.rules.other.nonSpaceChar)>=h||!p.trim())d+=` +`+N.slice(h);else{if(w||f.replace(this.rules.other.tabCharGlobal," ").search(this.rules.other.nonSpaceChar)>=4||y.test(f)||C.test(f)||m.test(f))break;d+=` +`+p}!w&&!p.trim()&&(w=!0),u+=S+` +`,e=e.substring(S.length+1),f=N.slice(h)}}i.loose||(o?i.loose=!0:this.rules.other.doubleBlankLine.test(u)&&(o=!0));let v=null,k;this.options.gfm&&(v=this.rules.other.listIsTask.exec(d),v&&(k=v[0]!=="[ ] ",d=d.replace(this.rules.other.listReplaceTask,""))),i.items.push({type:"list_item",raw:u,task:!!v,checked:k,loose:!1,text:d,tokens:[]}),i.raw+=u}let l=i.items.at(-1);if(l)l.raw=l.raw.trimEnd(),l.text=l.text.trimEnd();else return;i.raw=i.raw.trimEnd();for(let a=0;af.type==="space"),d=u.length>0&&u.some(f=>this.rules.other.anyLine.test(f.raw));i.loose=d}if(i.loose)for(let a=0;a({text:a,tokens:this.lexer.inline(a),header:!1,align:s.align[u]})));return s}}lheading(e){let t=this.rules.block.lheading.exec(e);if(t)return{type:"heading",raw:t[0],depth:t[2].charAt(0)==="="?1:2,text:t[1],tokens:this.lexer.inline(t[1])}}paragraph(e){let t=this.rules.block.paragraph.exec(e);if(t){let n=t[1].charAt(t[1].length-1)===` +`?t[1].slice(0,-1):t[1];return{type:"paragraph",raw:t[0],text:n,tokens:this.lexer.inline(n)}}}text(e){let t=this.rules.block.text.exec(e);if(t)return{type:"text",raw:t[0],text:t[0],tokens:this.lexer.inline(t[0])}}escape(e){let t=this.rules.inline.escape.exec(e);if(t)return{type:"escape",raw:t[0],text:t[1]}}tag(e){let t=this.rules.inline.tag.exec(e);if(t)return!this.lexer.state.inLink&&this.rules.other.startATag.test(t[0])?this.lexer.state.inLink=!0:this.lexer.state.inLink&&this.rules.other.endATag.test(t[0])&&(this.lexer.state.inLink=!1),!this.lexer.state.inRawBlock&&this.rules.other.startPreScriptTag.test(t[0])?this.lexer.state.inRawBlock=!0:this.lexer.state.inRawBlock&&this.rules.other.endPreScriptTag.test(t[0])&&(this.lexer.state.inRawBlock=!1),{type:"html",raw:t[0],inLink:this.lexer.state.inLink,inRawBlock:this.lexer.state.inRawBlock,block:!1,text:t[0]}}link(e){let t=this.rules.inline.link.exec(e);if(t){let n=t[2].trim();if(!this.options.pedantic&&this.rules.other.startAngleBracket.test(n)){if(!this.rules.other.endAngleBracket.test(n))return;let s=Ii(n.slice(0,-1),"\\");if((n.length-s.length)%2===0)return}else{let s=DN(t[2],"()");if(s===-2)return;if(s>-1){let o=(t[0].indexOf("!")===0?5:4)+t[1].length+s;t[2]=t[2].substring(0,s),t[0]=t[0].substring(0,o).trim(),t[3]=""}}let r=t[2],i="";if(this.options.pedantic){let s=this.rules.other.pedanticHrefTitle.exec(r);s&&(r=s[1],i=s[3])}else i=t[3]?t[3].slice(1,-1):"";return r=r.trim(),this.rules.other.startAngleBracket.test(r)&&(this.options.pedantic&&!this.rules.other.endAngleBracket.test(n)?r=r.slice(1):r=r.slice(1,-1)),Gp(t,{href:r&&r.replace(this.rules.inline.anyPunctuation,"$1"),title:i&&i.replace(this.rules.inline.anyPunctuation,"$1")},t[0],this.lexer,this.rules)}}reflink(e,t){let n;if((n=this.rules.inline.reflink.exec(e))||(n=this.rules.inline.nolink.exec(e))){let r=(n[2]||n[1]).replace(this.rules.other.multipleSpaceGlobal," "),i=t[r.toLowerCase()];if(!i){let s=n[0].charAt(0);return{type:"text",raw:s,text:s}}return Gp(n,i,n[0],this.lexer,this.rules)}}emStrong(e,t,n=""){let r=this.rules.inline.emStrongLDelim.exec(e);if(!(!r||r[3]&&n.match(this.rules.other.unicodeAlphaNumeric))&&(!(r[1]||r[2])||!n||this.rules.inline.punctuation.exec(n))){let i=[...r[0]].length-1,s,o,l=i,a=0,u=r[0][0]==="*"?this.rules.inline.emStrongRDelimAst:this.rules.inline.emStrongRDelimUnd;for(u.lastIndex=0,t=t.slice(-1*e.length+i);(r=u.exec(t))!=null;){if(s=r[1]||r[2]||r[3]||r[4]||r[5]||r[6],!s)continue;if(o=[...s].length,r[3]||r[4]){l+=o;continue}else if((r[5]||r[6])&&i%3&&!((i+o)%3)){a+=o;continue}if(l-=o,l>0)continue;o=Math.min(o,o+l+a);let d=[...r[0]][0].length,f=e.slice(0,i+r.index+d+o);if(Math.min(i,o)%2){let w=f.slice(1,-1);return{type:"em",raw:f,text:w,tokens:this.lexer.inlineTokens(w)}}let p=f.slice(2,-2);return{type:"strong",raw:f,text:p,tokens:this.lexer.inlineTokens(p)}}}}codespan(e){let t=this.rules.inline.code.exec(e);if(t){let n=t[2].replace(this.rules.other.newLineCharGlobal," "),r=this.rules.other.nonSpaceChar.test(n),i=this.rules.other.startingSpaceChar.test(n)&&this.rules.other.endingSpaceChar.test(n);return r&&i&&(n=n.substring(1,n.length-1)),{type:"codespan",raw:t[0],text:n}}}br(e){let t=this.rules.inline.br.exec(e);if(t)return{type:"br",raw:t[0]}}del(e){let t=this.rules.inline.del.exec(e);if(t)return{type:"del",raw:t[0],text:t[2],tokens:this.lexer.inlineTokens(t[2])}}autolink(e){let t=this.rules.inline.autolink.exec(e);if(t){let n,r;return t[2]==="@"?(n=t[1],r="mailto:"+n):(n=t[1],r=n),{type:"link",raw:t[0],text:n,href:r,tokens:[{type:"text",raw:n,text:n}]}}}url(e){var n;let t;if(t=this.rules.inline.url.exec(e)){let r,i;if(t[2]==="@")r=t[0],i="mailto:"+r;else{let s;do s=t[0],t[0]=((n=this.rules.inline._backpedal.exec(t[0]))==null?void 0:n[0])??"";while(s!==t[0]);r=t[0],t[1]==="www."?i="http://"+t[0]:i=t[0]}return{type:"link",raw:t[0],text:r,href:i,tokens:[{type:"text",raw:r,text:r}]}}}inlineText(e){let t=this.rules.inline.text.exec(e);if(t){let n=this.lexer.state.inRawBlock;return{type:"text",raw:t[0],text:t[0],escaped:n}}}},qt=class tc{constructor(t){ve(this,"tokens");ve(this,"options");ve(this,"state");ve(this,"tokenizer");ve(this,"inlineQueue");this.tokens=[],this.tokens.links=Object.create(null),this.options=t||jr,this.options.tokenizer=this.options.tokenizer||new cl,this.tokenizer=this.options.tokenizer,this.tokenizer.options=this.options,this.tokenizer.lexer=this,this.inlineQueue=[],this.state={inLink:!1,inRawBlock:!1,top:!0};let n={other:dt,block:lo.normal,inline:Li.normal};this.options.pedantic?(n.block=lo.pedantic,n.inline=Li.pedantic):this.options.gfm&&(n.block=lo.gfm,this.options.breaks?n.inline=Li.breaks:n.inline=Li.gfm),this.tokenizer.rules=n}static get rules(){return{block:lo,inline:Li}}static lex(t,n){return new tc(n).lex(t)}static lexInline(t,n){return new tc(n).inlineTokens(t)}lex(t){t=t.replace(dt.carriageReturn,` +`),this.blockTokens(t,this.tokens);for(let n=0;n(l=u.call({lexer:this},t,n))?(t=t.substring(l.raw.length),n.push(l),!0):!1))continue;if(l=this.tokenizer.space(t)){t=t.substring(l.raw.length);let u=n.at(-1);l.raw.length===1&&u!==void 0?u.raw+=` +`:n.push(l);continue}if(l=this.tokenizer.code(t)){t=t.substring(l.raw.length);let u=n.at(-1);(u==null?void 0:u.type)==="paragraph"||(u==null?void 0:u.type)==="text"?(u.raw+=(u.raw.endsWith(` +`)?"":` +`)+l.raw,u.text+=` +`+l.text,this.inlineQueue.at(-1).src=u.text):n.push(l);continue}if(l=this.tokenizer.fences(t)){t=t.substring(l.raw.length),n.push(l);continue}if(l=this.tokenizer.heading(t)){t=t.substring(l.raw.length),n.push(l);continue}if(l=this.tokenizer.hr(t)){t=t.substring(l.raw.length),n.push(l);continue}if(l=this.tokenizer.blockquote(t)){t=t.substring(l.raw.length),n.push(l);continue}if(l=this.tokenizer.list(t)){t=t.substring(l.raw.length),n.push(l);continue}if(l=this.tokenizer.html(t)){t=t.substring(l.raw.length),n.push(l);continue}if(l=this.tokenizer.def(t)){t=t.substring(l.raw.length);let u=n.at(-1);(u==null?void 0:u.type)==="paragraph"||(u==null?void 0:u.type)==="text"?(u.raw+=(u.raw.endsWith(` +`)?"":` +`)+l.raw,u.text+=` +`+l.raw,this.inlineQueue.at(-1).src=u.text):this.tokens.links[l.tag]||(this.tokens.links[l.tag]={href:l.href,title:l.title},n.push(l));continue}if(l=this.tokenizer.table(t)){t=t.substring(l.raw.length),n.push(l);continue}if(l=this.tokenizer.lheading(t)){t=t.substring(l.raw.length),n.push(l);continue}let a=t;if((o=this.options.extensions)!=null&&o.startBlock){let u=1/0,d=t.slice(1),f;this.options.extensions.startBlock.forEach(p=>{f=p.call({lexer:this},d),typeof f=="number"&&f>=0&&(u=Math.min(u,f))}),u<1/0&&u>=0&&(a=t.substring(0,u+1))}if(this.state.top&&(l=this.tokenizer.paragraph(a))){let u=n.at(-1);r&&(u==null?void 0:u.type)==="paragraph"?(u.raw+=(u.raw.endsWith(` +`)?"":` +`)+l.raw,u.text+=` +`+l.text,this.inlineQueue.pop(),this.inlineQueue.at(-1).src=u.text):n.push(l),r=a.length!==t.length,t=t.substring(l.raw.length);continue}if(l=this.tokenizer.text(t)){t=t.substring(l.raw.length);let u=n.at(-1);(u==null?void 0:u.type)==="text"?(u.raw+=(u.raw.endsWith(` +`)?"":` +`)+l.raw,u.text+=` +`+l.text,this.inlineQueue.pop(),this.inlineQueue.at(-1).src=u.text):n.push(l);continue}if(t){let u="Infinite loop on byte: "+t.charCodeAt(0);if(this.options.silent){console.error(u);break}else throw new Error(u)}}return this.state.top=!0,n}inline(t,n=[]){return this.inlineQueue.push({src:t,tokens:n}),n}inlineTokens(t,n=[]){var l,a,u,d,f;let r=t,i=null;if(this.tokens.links){let p=Object.keys(this.tokens.links);if(p.length>0)for(;(i=this.tokenizer.rules.inline.reflinkSearch.exec(r))!=null;)p.includes(i[0].slice(i[0].lastIndexOf("[")+1,-1))&&(r=r.slice(0,i.index)+"["+"a".repeat(i[0].length-2)+"]"+r.slice(this.tokenizer.rules.inline.reflinkSearch.lastIndex))}for(;(i=this.tokenizer.rules.inline.anyPunctuation.exec(r))!=null;)r=r.slice(0,i.index)+"++"+r.slice(this.tokenizer.rules.inline.anyPunctuation.lastIndex);for(;(i=this.tokenizer.rules.inline.blockSkip.exec(r))!=null;)r=r.slice(0,i.index)+"["+"a".repeat(i[0].length-2)+"]"+r.slice(this.tokenizer.rules.inline.blockSkip.lastIndex);r=((a=(l=this.options.hooks)==null?void 0:l.emStrongMask)==null?void 0:a.call({lexer:this},r))??r;let s=!1,o="";for(;t;){s||(o=""),s=!1;let p;if((d=(u=this.options.extensions)==null?void 0:u.inline)!=null&&d.some(h=>(p=h.call({lexer:this},t,n))?(t=t.substring(p.raw.length),n.push(p),!0):!1))continue;if(p=this.tokenizer.escape(t)){t=t.substring(p.raw.length),n.push(p);continue}if(p=this.tokenizer.tag(t)){t=t.substring(p.raw.length),n.push(p);continue}if(p=this.tokenizer.link(t)){t=t.substring(p.raw.length),n.push(p);continue}if(p=this.tokenizer.reflink(t,this.tokens.links)){t=t.substring(p.raw.length);let h=n.at(-1);p.type==="text"&&(h==null?void 0:h.type)==="text"?(h.raw+=p.raw,h.text+=p.text):n.push(p);continue}if(p=this.tokenizer.emStrong(t,r,o)){t=t.substring(p.raw.length),n.push(p);continue}if(p=this.tokenizer.codespan(t)){t=t.substring(p.raw.length),n.push(p);continue}if(p=this.tokenizer.br(t)){t=t.substring(p.raw.length),n.push(p);continue}if(p=this.tokenizer.del(t)){t=t.substring(p.raw.length),n.push(p);continue}if(p=this.tokenizer.autolink(t)){t=t.substring(p.raw.length),n.push(p);continue}if(!this.state.inLink&&(p=this.tokenizer.url(t))){t=t.substring(p.raw.length),n.push(p);continue}let w=t;if((f=this.options.extensions)!=null&&f.startInline){let h=1/0,v=t.slice(1),k;this.options.extensions.startInline.forEach(g=>{k=g.call({lexer:this},v),typeof k=="number"&&k>=0&&(h=Math.min(h,k))}),h<1/0&&h>=0&&(w=t.substring(0,h+1))}if(p=this.tokenizer.inlineText(w)){t=t.substring(p.raw.length),p.raw.slice(-1)!=="_"&&(o=p.raw.slice(-1)),s=!0;let h=n.at(-1);(h==null?void 0:h.type)==="text"?(h.raw+=p.raw,h.text+=p.text):n.push(p);continue}if(t){let h="Infinite loop on byte: "+t.charCodeAt(0);if(this.options.silent){console.error(h);break}else throw new Error(h)}}return n}},dl=class{constructor(e){ve(this,"options");ve(this,"parser");this.options=e||jr}space(e){return""}code({text:e,lang:t,escaped:n}){var s;let r=(s=(t||"").match(dt.notSpaceStart))==null?void 0:s[0],i=e.replace(dt.endingNewline,"")+` +`;return r?'
'+(n?i:rn(i,!0))+`
+`:"
"+(n?i:rn(i,!0))+`
+`}blockquote({tokens:e}){return`
+${this.parser.parse(e)}
+`}html({text:e}){return e}def(e){return""}heading({tokens:e,depth:t}){return`${this.parser.parseInline(e)} +`}hr(e){return`
+`}list(e){let t=e.ordered,n=e.start,r="";for(let o=0;o +`+r+" +`}listitem(e){var n;let t="";if(e.task){let r=this.checkbox({checked:!!e.checked});e.loose?((n=e.tokens[0])==null?void 0:n.type)==="paragraph"?(e.tokens[0].text=r+" "+e.tokens[0].text,e.tokens[0].tokens&&e.tokens[0].tokens.length>0&&e.tokens[0].tokens[0].type==="text"&&(e.tokens[0].tokens[0].text=r+" "+rn(e.tokens[0].tokens[0].text),e.tokens[0].tokens[0].escaped=!0)):e.tokens.unshift({type:"text",raw:r+" ",text:r+" ",escaped:!0}):t+=r+" "}return t+=this.parser.parse(e.tokens,!!e.loose),`
  • ${t}
  • +`}checkbox({checked:e}){return"'}paragraph({tokens:e}){return`

    ${this.parser.parseInline(e)}

    +`}table(e){let t="",n="";for(let i=0;i${r}`),` + +`+t+` +`+r+`
    +`}tablerow({text:e}){return` +${e} +`}tablecell(e){let t=this.parser.parseInline(e.tokens),n=e.header?"th":"td";return(e.align?`<${n} align="${e.align}">`:`<${n}>`)+t+` +`}strong({tokens:e}){return`${this.parser.parseInline(e)}`}em({tokens:e}){return`${this.parser.parseInline(e)}`}codespan({text:e}){return`${rn(e,!0)}`}br(e){return"
    "}del({tokens:e}){return`${this.parser.parseInline(e)}`}link({href:e,title:t,tokens:n}){let r=this.parser.parseInline(n),i=Qp(e);if(i===null)return r;e=i;let s='
    ",s}image({href:e,title:t,text:n,tokens:r}){r&&(n=this.parser.parseInline(r,this.parser.textRenderer));let i=Qp(e);if(i===null)return rn(n);e=i;let s=`${n}{let a=o[l].flat(1/0);n=n.concat(this.walkTokens(a,t))}):o.tokens&&(n=n.concat(this.walkTokens(o.tokens,t)))}}return n}use(...e){let t=this.defaults.extensions||{renderers:{},childTokens:{}};return e.forEach(n=>{let r={...n};if(r.async=this.defaults.async||r.async||!1,n.extensions&&(n.extensions.forEach(i=>{if(!i.name)throw new Error("extension name required");if("renderer"in i){let s=t.renderers[i.name];s?t.renderers[i.name]=function(...o){let l=i.renderer.apply(this,o);return l===!1&&(l=s.apply(this,o)),l}:t.renderers[i.name]=i.renderer}if("tokenizer"in i){if(!i.level||i.level!=="block"&&i.level!=="inline")throw new Error("extension level must be 'block' or 'inline'");let s=t[i.level];s?s.unshift(i.tokenizer):t[i.level]=[i.tokenizer],i.start&&(i.level==="block"?t.startBlock?t.startBlock.push(i.start):t.startBlock=[i.start]:i.level==="inline"&&(t.startInline?t.startInline.push(i.start):t.startInline=[i.start]))}"childTokens"in i&&i.childTokens&&(t.childTokens[i.name]=i.childTokens)}),r.extensions=t),n.renderer){let i=this.defaults.renderer||new dl(this.defaults);for(let s in n.renderer){if(!(s in i))throw new Error(`renderer '${s}' does not exist`);if(["options","parser"].includes(s))continue;let o=s,l=n.renderer[o],a=i[o];i[o]=(...u)=>{let d=l.apply(i,u);return d===!1&&(d=a.apply(i,u)),d||""}}r.renderer=i}if(n.tokenizer){let i=this.defaults.tokenizer||new cl(this.defaults);for(let s in n.tokenizer){if(!(s in i))throw new Error(`tokenizer '${s}' does not exist`);if(["options","rules","lexer"].includes(s))continue;let o=s,l=n.tokenizer[o],a=i[o];i[o]=(...u)=>{let d=l.apply(i,u);return d===!1&&(d=a.apply(i,u)),d}}r.tokenizer=i}if(n.hooks){let i=this.defaults.hooks||new Ui;for(let s in n.hooks){if(!(s in i))throw new Error(`hook '${s}' does not exist`);if(["options","block"].includes(s))continue;let o=s,l=n.hooks[o],a=i[o];Ui.passThroughHooks.has(s)?i[o]=u=>{if(this.defaults.async&&Ui.passThroughHooksRespectAsync.has(s))return(async()=>{let f=await l.call(i,u);return a.call(i,f)})();let d=l.call(i,u);return a.call(i,d)}:i[o]=(...u)=>{if(this.defaults.async)return(async()=>{let f=await l.apply(i,u);return f===!1&&(f=await a.apply(i,u)),f})();let d=l.apply(i,u);return d===!1&&(d=a.apply(i,u)),d}}r.hooks=i}if(n.walkTokens){let i=this.defaults.walkTokens,s=n.walkTokens;r.walkTokens=function(o){let l=[];return l.push(s.call(this,o)),i&&(l=l.concat(i.call(this,o))),l}}this.defaults={...this.defaults,...r}}),this}setOptions(e){return this.defaults={...this.defaults,...e},this}lexer(e,t){return qt.lex(e,t??this.defaults)}parser(e,t){return Gt.parse(e,t??this.defaults)}parseMarkdown(e){return(t,n)=>{let r={...n},i={...this.defaults,...r},s=this.onError(!!i.silent,!!i.async);if(this.defaults.async===!0&&r.async===!1)return s(new Error("marked(): The async option was set to true by an extension. Remove async: false from the parse options object to return a Promise."));if(typeof t>"u"||t===null)return s(new Error("marked(): input parameter is undefined or null"));if(typeof t!="string")return s(new Error("marked(): input parameter is of type "+Object.prototype.toString.call(t)+", string expected"));if(i.hooks&&(i.hooks.options=i,i.hooks.block=e),i.async)return(async()=>{let o=i.hooks?await i.hooks.preprocess(t):t,l=await(i.hooks?await i.hooks.provideLexer():e?qt.lex:qt.lexInline)(o,i),a=i.hooks?await i.hooks.processAllTokens(l):l;i.walkTokens&&await Promise.all(this.walkTokens(a,i.walkTokens));let u=await(i.hooks?await i.hooks.provideParser():e?Gt.parse:Gt.parseInline)(a,i);return i.hooks?await i.hooks.postprocess(u):u})().catch(s);try{i.hooks&&(t=i.hooks.preprocess(t));let o=(i.hooks?i.hooks.provideLexer():e?qt.lex:qt.lexInline)(t,i);i.hooks&&(o=i.hooks.processAllTokens(o)),i.walkTokens&&this.walkTokens(o,i.walkTokens);let l=(i.hooks?i.hooks.provideParser():e?Gt.parse:Gt.parseInline)(o,i);return i.hooks&&(l=i.hooks.postprocess(l)),l}catch(o){return s(o)}}}onError(e,t){return n=>{if(n.message+=` +Please report this to https://github.com/markedjs/marked.`,e){let r="

    An error occurred:

    "+rn(n.message+"",!0)+"
    ";return t?Promise.resolve(r):r}if(t)return Promise.reject(n);throw n}}},Cr=new $N;function pe(e,t){return Cr.parse(e,t)}pe.options=pe.setOptions=function(e){return Cr.setOptions(e),pe.defaults=Cr.defaults,zv(pe.defaults),pe};pe.getDefaults=xd;pe.defaults=jr;pe.use=function(...e){return Cr.use(...e),pe.defaults=Cr.defaults,zv(pe.defaults),pe};pe.walkTokens=function(e,t){return Cr.walkTokens(e,t)};pe.parseInline=Cr.parseInline;pe.Parser=Gt;pe.parser=Gt.parse;pe.Renderer=dl;pe.TextRenderer=jd;pe.Lexer=qt;pe.lexer=qt.lex;pe.Tokenizer=cl;pe.Hooks=Ui;pe.parse=pe;pe.options;pe.setOptions;pe.use;pe.walkTokens;pe.parseInline;Gt.parse;qt.lex;const zN={name:"spoiler",level:"inline",start(e){var t;return(t=e.match(/\|\|/))==null?void 0:t.index},tokenizer(e){const n=/^\|\|(.*?)\|\|/.exec(e);if(n)return{type:"spoiler",raw:n[0],text:n[1].trim()}},renderer(e){return`${e.text}`}},FN={link(e){const t=e.href,n=e.title,r=e.text;try{if(new URL(t,window.location.href).origin!==window.location.origin)return`
    ${r}`}catch{}return`${r}`},listitem(e){const t=e.text,n=e.task,r=e.checked;return n?`
  • ${``} ${t}
  • +`:`
  • ${t}
  • +`}};pe.use({extensions:[zN],gfm:!0,breaks:!0,renderer:FN});const _d=e=>pe.parse(e),UN=e=>{const t=/#([а-яё\w]+)/gi,n=[];let r;for(;(r=t.exec(e))!==null;){const i=r.index,s=e.substring(Math.max(0,i-100),i),o=e.substring(i+r[0].length,Math.min(e.length,i+r[0].length+100)),l=s.lastIndexOf("<"),a=s.lastIndexOf(">");if(l>a)continue;const u=Math.max(s.lastIndexOf('"'),s.lastIndexOf("'")),d=s.lastIndexOf("=");if(d>-1&&u>d&&Math.min(o.indexOf('"')!==-1?o.indexOf('"'):1/0,o.indexOf("'")!==-1?o.indexOf("'"):1/0)!==1/0)continue;const f=r[1].toLowerCase();n.includes(f)||n.push(f)}return n},BN=e=>{const t=/#([а-яё\w]+)/gi,n=[];let r;for(;(r=t.exec(e))!==null;)n.push({fullMatch:r[0],tag:r[1],index:r.index});let i=e;for(let s=n.length-1;s>=0;s--){const o=n[s],l=i.substring(0,o.index),a=i.substring(o.index+o.fullMatch.length),u=l.lastIndexOf("<"),d=l.lastIndexOf(">");if(u>d)continue;const f=l.substring(Math.max(0,o.index-100)),p=Math.max(f.lastIndexOf('"'),f.lastIndexOf("'")),w=f.lastIndexOf("=");if(w>-1&&p>w){const v=a.substring(0,Math.min(100,a.length));if(Math.min(v.indexOf('"')!==-1?v.indexOf('"'):1/0,v.indexOf("'")!==-1?v.indexOf("'"):1/0)!==1/0)continue}const h=`${o.fullMatch}`;i=l+h+a}return i},WN=(e,t)=>{if(!t.trim())return e;const n=t.replace(/[.*+?^${}()|[\]\\]/g,"\\$&"),r=new RegExp(`(${n})`,"gi");return e.replace(r,'$1')},Kv=({notes:e=[]})=>{const t=ye(l=>l.notes.selectedTag),n=ot(),i=(()=>{const l={};return e.forEach(a=>{UN(a.content).forEach(d=>{l[d]=(l[d]||0)+1})}),l})(),s=Object.keys(i).sort(),o=l=>{n(rl(t===l?null:l))};return s.length===0?c.jsxs("div",{className:"tags-section",children:[c.jsx("div",{className:"tags-header",children:c.jsxs("span",{className:"tags-title",children:[c.jsx(F,{icon:"mdi:tag"})," Теги"]})}),c.jsx("div",{className:"tags-container",children:c.jsx("div",{style:{fontSize:"10px",color:"#999",textAlign:"center"},children:"Нет тегов"})})]}):c.jsxs("div",{className:"tags-section",children:[c.jsx("div",{className:"tags-header",children:c.jsxs("span",{className:"tags-title",children:[c.jsx(F,{icon:"mdi:tag"})," Теги"]})}),c.jsx("div",{className:"tags-container",children:s.map(l=>{const a=i[l],u=t===l;return c.jsxs("span",{className:`tag ${u?"active":""}`,"data-tag":l,onClick:()=>o(l),children:["#",l,c.jsx("span",{className:"tag-count",children:a})]},l)})})]})},HN=({notes:e})=>c.jsxs("div",{className:"container-leftside",children:[c.jsx(Av,{notes:e}),c.jsx($v,{}),c.jsx(Kv,{notes:e})]}),VN=({isOpen:e,onClose:t})=>{const n=ye(r=>r.notes.allNotes);return c.jsxs(c.Fragment,{children:[c.jsx("div",{className:`mobile-sidebar-overlay ${e?"open":""}`,onClick:t}),c.jsxs("div",{className:`mobile-sidebar ${e?"open":""}`,children:[c.jsx("button",{className:"sidebar-close-btn",onClick:t,children:c.jsx(F,{icon:"mdi:close"})}),c.jsxs("div",{className:"sidebar-content",children:[c.jsx("div",{className:"mobile-calendar-section",children:c.jsx(Av,{notes:n})}),c.jsx("div",{className:"mobile-search-section",children:c.jsx($v,{})}),c.jsx("div",{className:"mobile-tags-section",children:c.jsx(Kv,{notes:n})})]})]})]})},Xv=({onInsert:e,onImageClick:t,onFileClick:n,onPreviewToggle:r,isPreviewMode:i})=>{const[s,o]=x.useState(!1),l=ot(),a=x.useRef(null),u=x.useRef(null),d=x.useRef(null),f=x.useRef(null),[p,w]=x.useState(!1),[h,v]=x.useState(0),[k,g]=x.useState(0),[m,y]=x.useState(null);x.useEffect(()=>{const _=M=>{a.current&&!a.current.contains(M.target)&&d.current&&!d.current.contains(M.target)&&(o(!1),y(null))},D=()=>{if(u.current&&s){const M=u.current.getBoundingClientRect();y({top:M.bottom+window.scrollY+2,left:M.left+window.scrollX})}};if(s){D();const M=setTimeout(()=>{document.addEventListener("mousedown",_),window.addEventListener("resize",D),window.addEventListener("scroll",D)},100);return()=>{clearTimeout(M),document.removeEventListener("mousedown",_),window.removeEventListener("resize",D),window.removeEventListener("scroll",D)}}else y(null)},[s]);const C=_=>{_.target.closest(".btnMarkdown")||f.current&&(w(!0),v(_.pageX-f.current.offsetLeft),g(f.current.scrollLeft))},j=_=>{if(!p||!f.current)return;_.preventDefault();const M=(_.pageX-f.current.offsetLeft-h)*2;f.current.scrollLeft=k-M},S=()=>{w(!1)};x.useEffect(()=>(p?(document.addEventListener("mousemove",j),document.addEventListener("mouseup",S)):(document.removeEventListener("mousemove",j),document.removeEventListener("mouseup",S)),()=>{document.removeEventListener("mousemove",j),document.removeEventListener("mouseup",S)}),[p]);const N=[];return c.jsxs("div",{className:"markdown-buttons",ref:f,onMouseDown:C,style:{cursor:p?"grabbing":f.current&&f.current.scrollWidth>f.current.clientWidth?"grab":"default"},children:[N.map(_=>c.jsx("button",{className:"btnMarkdown",onClick:()=>{_.action?_.action():e(_.before,_.after)},title:_.title,children:c.jsx(F,{icon:_.icon})},_.id)),c.jsxs("div",{className:"header-dropdown",ref:a,children:[c.jsxs("button",{ref:u,className:"btnMarkdown",onMouseDown:_=>{_.stopPropagation()},onClick:_=>{_.stopPropagation(),o(!s)},title:"Заголовок",children:[c.jsx(F,{icon:"mdi:format-header-pound"}),c.jsx(F,{icon:"mdi:menu-down",style:{fontSize:"10px",marginLeft:"-2px"}})]}),s&&m&&c.jsx("div",{ref:d,className:"header-dropdown-menu",style:{position:"fixed",top:`${m.top}px`,left:`${m.left}px`},children:[1,2,3,4,5].map(_=>c.jsxs("button",{onClick:D=>{D.stopPropagation(),e("#".repeat(_)+" ",""),o(!1),y(null)},children:["H",_]},_))})]}),c.jsx("button",{className:"btnMarkdown",onClick:()=>e("- ",""),title:"Список",children:c.jsx(F,{icon:"mdi:format-list-bulleted"})}),c.jsx("button",{className:"btnMarkdown",onClick:()=>e("1. ",""),title:"Нумерованный список",children:c.jsx(F,{icon:"mdi:format-list-numbered"})}),c.jsx("button",{className:"btnMarkdown",onClick:()=>e("> ",""),title:"Цитата",children:c.jsx(F,{icon:"mdi:format-quote-close"})}),c.jsx("button",{className:"btnMarkdown",onClick:()=>e("`","`"),title:"Код",children:c.jsx(F,{icon:"mdi:code-tags"})}),c.jsx("button",{className:"btnMarkdown",onClick:()=>e("[текст ссылки](",")"),title:"Ссылка",children:c.jsx(F,{icon:"mdi:link"})}),c.jsx("button",{className:"btnMarkdown",onClick:()=>e("- [ ] ",""),title:"To-Do список",children:c.jsx(F,{icon:"mdi:checkbox-marked-outline"})}),c.jsx("button",{className:"btnMarkdown",onClick:()=>t==null?void 0:t(),title:"Загрузить изображения",children:c.jsx(F,{icon:"mdi:image-plus"})}),c.jsx("button",{className:"btnMarkdown",onClick:()=>n==null?void 0:n(),title:"Прикрепить файлы",children:c.jsx(F,{icon:"mdi:file-plus"})}),c.jsx("button",{className:`btnMarkdown ${i?"active":""}`,onClick:r||(()=>l(u1())),title:"Предпросмотр",children:c.jsx(F,{icon:"mdi:monitor-eye"})})]})},Jv=({textareaRef:e,onFormat:t,visible:n,position:r,onHide:i,onInsertColor:s,activeFormats:o={},hasSelection:l=!1})=>{const a=x.useRef(null),[u,d]=x.useState(!1),[f,p]=x.useState(0),[w,h]=x.useState(0);x.useEffect(()=>{n&&a.current&&setTimeout(()=>{if(!a.current)return;const S=a.current,N=S.getBoundingClientRect(),_=window.innerWidth,D=window.innerHeight,M=10,q=S.querySelector(".floating-toolbar"),X=q?q.scrollWidth:N.width,te=_-M*2;let K=r.top-N.height-M,z=r.left;X>te&&(S.style.maxWidth=`${te}px`),z+N.width>_-M&&(X>te?z=M:z=Math.max(M,_-N.width-M)),zD-M&&(K=D-N.height-M),S.style.top=`${K}px`,S.style.left=`${z}px`},0)},[n,r]);const v=S=>{S.target.closest(".floating-toolbar-btn")||a.current&&(d(!0),p(S.pageX-a.current.offsetLeft),h(a.current.scrollLeft))},k=S=>{if(!u||!a.current)return;S.preventDefault();const _=(S.pageX-a.current.offsetLeft-f)*2;a.current.scrollLeft=w-_},g=()=>{d(!1)};x.useEffect(()=>(u?(document.addEventListener("mousemove",k),document.addEventListener("mouseup",g)):(document.removeEventListener("mousemove",k),document.removeEventListener("mouseup",g)),()=>{document.removeEventListener("mousemove",k),document.removeEventListener("mouseup",g)}),[u]);const m=(S,N)=>{t(S,N),setTimeout(()=>{if(e.current){e.current.focus();const _=e.current.selectionStart,D=e.current.selectionEnd;_!==D&&e.current.setSelectionRange(_,D)}},0)},y=async()=>{const S=e.current;if(!S)return;const N=S.selectionStart,_=S.selectionEnd;if(N===_)return;const D=S.value.substring(N,_);try{await navigator.clipboard.writeText(D)}catch{const q=document.createElement("textarea");q.value=D,q.style.position="fixed",q.style.left="-999999px",document.body.appendChild(q),q.select(),document.execCommand("copy"),document.body.removeChild(q)}},C=async()=>{var X;const S=e.current;if(!S)return;const N=S.selectionStart,_=S.selectionEnd;if(N===_)return;const D=S.value.substring(N,_);try{await navigator.clipboard.writeText(D)}catch{const K=document.createElement("textarea");K.value=D,K.style.position="fixed",K.style.left="-999999px",document.body.appendChild(K),K.select(),document.execCommand("copy"),document.body.removeChild(K)}const M=S.value.substring(0,N)+S.value.substring(_),q=(X=Object.getOwnPropertyDescriptor(window.HTMLTextAreaElement.prototype,"value"))==null?void 0:X.set;if(q){q.call(S,M);const te=new Event("input",{bubbles:!0});S.dispatchEvent(te)}else{S.value=M;const te=new Event("input",{bubbles:!0});S.dispatchEvent(te)}S.setSelectionRange(N,N),S.focus()},j=async()=>{var D;const S=e.current;if(!S)return;const N=S.selectionStart,_=S.selectionEnd;try{const M=await navigator.clipboard.readText(),q=S.value.substring(0,N)+M+S.value.substring(_),X=(D=Object.getOwnPropertyDescriptor(window.HTMLTextAreaElement.prototype,"value"))==null?void 0:D.set;if(X){X.call(S,q);const K=new Event("input",{bubbles:!0});S.dispatchEvent(K)}else{S.value=q;const K=new Event("input",{bubbles:!0});S.dispatchEvent(K)}const te=N+M.length;S.setSelectionRange(te,te),S.focus()}catch{S.focus(),document.execCommand("paste")}};return!n||!l?null:c.jsx("div",{ref:a,className:"floating-toolbar-wrapper",style:{position:"fixed",top:`${r.top}px`,left:`${r.left}px`,zIndex:1e3,cursor:u?"grabbing":a.current&&a.current.scrollWidth>a.current.clientWidth?"grab":"default"},onMouseDown:S=>{S.preventDefault(),v(S)},onContextMenu:S=>{S.preventDefault()},children:c.jsxs("div",{className:"floating-toolbar",children:[c.jsx("button",{className:"floating-toolbar-btn",onClick:i,title:"Закрыть",children:c.jsx(F,{icon:"mdi:close"})}),l&&c.jsxs(c.Fragment,{children:[c.jsx("button",{className:"floating-toolbar-btn",onClick:y,title:"Копировать",children:c.jsx(F,{icon:"mdi:content-copy"})}),c.jsx("button",{className:"floating-toolbar-btn",onClick:C,title:"Вырезать",children:c.jsx(F,{icon:"mdi:content-cut"})}),c.jsx("button",{className:"floating-toolbar-btn",onClick:j,title:"Вставить",children:c.jsx(F,{icon:"mdi:content-paste"})})]}),l&&c.jsxs(c.Fragment,{children:[c.jsx("div",{className:"floating-toolbar-separator"}),c.jsx("button",{className:`floating-toolbar-btn ${o.bold?"active":""}`,onClick:()=>m("**","**"),title:"Жирный",children:c.jsx(F,{icon:"mdi:format-bold"})}),c.jsx("button",{className:`floating-toolbar-btn ${o.italic?"active":""}`,onClick:()=>m("*","*"),title:"Курсив",children:c.jsx(F,{icon:"mdi:format-italic"})}),c.jsx("button",{className:`floating-toolbar-btn ${o.strikethrough?"active":""}`,onClick:()=>m("~~","~~"),title:"Зачеркнутый",children:c.jsx(F,{icon:"mdi:format-strikethrough"})}),c.jsx("div",{className:"floating-toolbar-separator"}),c.jsx("button",{className:"floating-toolbar-btn",onClick:()=>s==null?void 0:s(),title:"Цвет текста",children:c.jsx(F,{icon:"mdi:palette"})}),c.jsx("button",{className:"floating-toolbar-btn",onClick:()=>m("||","||"),title:"Скрытый текст",children:c.jsx(F,{icon:"mdi:eye-off"})}),c.jsx("button",{className:"floating-toolbar-btn",onClick:()=>m("`","`"),title:"Код",children:c.jsx(F,{icon:"mdi:code-tags"})}),c.jsx("button",{className:"floating-toolbar-btn",onClick:()=>m("> ",""),title:"Цитата",children:c.jsx(F,{icon:"mdi:format-quote-close"})})]})]})})},Ge={getAll:async()=>{const{data:e}=await fe.get("/notes");return e},search:async e=>{const{data:t}=await fe.get("/notes/search",{params:e});return t},create:async e=>{const{data:t}=await fe.post("/notes",e);return t},update:async(e,t,n)=>{const{data:r}=await fe.put(`/notes/${e}`,{content:t,skipTimestamp:n});return r},delete:async e=>{await fe.delete(`/notes/${e}`)},pin:async e=>{const{data:t}=await fe.put(`/notes/${e}/pin`);return t},archive:async e=>{const{data:t}=await fe.put(`/notes/${e}/archive`);return t},unarchive:async e=>{const{data:t}=await fe.put(`/notes/${e}/unarchive`);return t},uploadImages:async(e,t)=>{const n=new FormData;t.forEach(i=>n.append("images",i));const{data:r}=await fe.post(`/notes/${e}/images`,n,{headers:{"Content-Type":"multipart/form-data"}});return r},uploadFiles:async(e,t)=>{const n=new FormData;t.forEach(i=>n.append("files",i));const{data:r}=await fe.post(`/notes/${e}/files`,n,{headers:{"Content-Type":"multipart/form-data"}});return r},deleteImage:async(e,t)=>{await fe.delete(`/notes/${e}/images/${t}`)},deleteFile:async(e,t)=>{await fe.delete(`/notes/${e}/files/${t}`)},getArchived:async()=>{const{data:e}=await fe.get("/notes/archived");return e},deleteArchived:async e=>{await fe.delete(`/notes/archived/${e}`)},deleteAllArchived:async e=>{const{data:t}=await fe.delete("/notes/archived/all",{data:{password:e}});return t}},QN={getLogs:async e=>{const{data:t}=await fe.get("/logs",{params:e});return t}},Zv=e=>{const t=x.useCallback(()=>{document.querySelectorAll(".spoiler").forEach(s=>{if(!s._clickHandler){const o=function(l){this.classList.contains("revealed")||(l.stopPropagation(),this.classList.add("revealed"))};s._clickHandler=o,s.addEventListener("click",o)}}),document.querySelectorAll(".external-link").forEach(s=>{if(!s._externalClickHandler){const o=function(l){(window.matchMedia("(display-mode: standalone)").matches||window.navigator.standalone===!0)&&(l.preventDefault(),window.open(this.href,"_blank","noopener,noreferrer"))};s._externalClickHandler=o,s.addEventListener("click",o)}}),document.querySelectorAll(".note-preview-content input[type='checkbox'], .textNote input[type='checkbox']").forEach(s=>{if(!s._checkboxHandler){const o=async function(){if(this.closest(".note-preview-content"))return;const l=this.closest("[data-note-id]");if(!l)return;const a=parseInt(l.getAttribute("data-note-id")||"0");if(!a)return;const u=l.querySelector(".textNote");if(!u)return;const d=u.getAttribute("data-original-content");if(d)try{const p=Array.from(u.querySelectorAll("input[type='checkbox']")).indexOf(this);if(p===-1)return;const w=d.split(` +`);let h=0,v="";for(let k=0;k{const n=new MutationObserver(()=>{t()});return n.observe(document.body,{childList:!0,subtree:!0}),t(),()=>{n.disconnect()}},[t])},ey=({content:e})=>{Zv();const t=_d(e);return c.jsxs("div",{className:"note-preview-container",style:{display:"block"},children:[c.jsx("div",{className:"note-preview-header",children:c.jsx("span",{children:"Предпросмотр:"})}),c.jsx("div",{className:"note-preview-content",dangerouslySetInnerHTML:{__html:t}})]})},ty=({images:e,onChange:t})=>{const n=i=>{t(e.filter((s,o)=>o!==i))},r=()=>{t([])};return e.length===0?null:c.jsxs("div",{className:"image-preview-container",style:{display:"block"},children:[c.jsxs("div",{className:"image-preview-header",children:[c.jsx("span",{children:"Загруженные изображения:"}),c.jsx("button",{type:"button",className:"clear-images-btn",onClick:r,children:"Очистить все"})]}),c.jsx("div",{className:"image-preview-list",children:e.map((i,s)=>c.jsxs("div",{className:"image-preview-item",children:[c.jsx("img",{src:URL.createObjectURL(i),alt:`Preview ${s+1}`,className:"image-preview-thumbnail"}),c.jsx("button",{className:"image-preview-remove",onClick:()=>n(s),title:"Удалить",children:c.jsx(F,{icon:"mdi:close"})})]},s))})]})},ny=({files:e,onChange:t})=>{const n=o=>{t(e.filter((l,a)=>a!==o))},r=()=>{t([])},i=o=>{var a;const l=((a=o.split(".").pop())==null?void 0:a.toLowerCase())||"";return l==="pdf"?"mdi:file-pdf":["doc","docx"].includes(l)?"mdi:file-word":["xls","xlsx"].includes(l)?"mdi:file-excel":l==="txt"?"mdi:file-document":["zip","rar","7z"].includes(l)?"mdi:folder-zip":"mdi:file"},s=o=>(o/1024/1024).toFixed(2)+" MB";return e.length===0?null:c.jsxs("div",{className:"file-preview-container",style:{display:"block"},children:[c.jsxs("div",{className:"file-preview-header",children:[c.jsx("span",{children:"Прикрепленные файлы:"}),c.jsx("button",{type:"button",className:"clear-files-btn",onClick:r,children:"Очистить все"})]}),c.jsx("div",{className:"file-preview-list",children:e.map((o,l)=>c.jsxs("div",{className:"file-preview-item",children:[c.jsx(F,{icon:i(o.name),className:"file-icon"}),c.jsxs("div",{className:"file-info",children:[c.jsx("div",{className:"file-name",children:o.name}),c.jsx("div",{className:"file-size",children:s(o.size)})]}),c.jsx("button",{className:"file-preview-remove",onClick:()=>n(l),title:"Удалить",children:c.jsx(F,{icon:"mdi:close"})})]},l))})]})},ry={improveText:async e=>{const{data:t}=await fe.post("/ai/improve",{text:e});return t.improvedText}},qN=({onSave:e})=>{const[t,n]=x.useState(""),[r,i]=x.useState([]),[s,o]=x.useState([]),[l,a]=x.useState(!1),[u,d]=x.useState(!1),[f,p]=x.useState({top:0,left:0}),[w,h]=x.useState(!1),[v,k]=x.useState({bold:!1,italic:!1,strikethrough:!1}),g=x.useRef(null),m=ye(b=>b.ui.isPreviewMode),{showNotification:y}=Tr(),C=ye(b=>b.profile.aiEnabled),j=async()=>{if(!t.trim()){y("Введите текст заметки","warning");return}try{const b=new Date,P=b.toLocaleDateString("ru-RU"),L=b.toLocaleTimeString("ru-RU",{hour:"2-digit",minute:"2-digit"}),$=await Ge.create({content:t,date:P,time:L});r.length>0&&await Ge.uploadImages($.id,r),s.length>0&&await Ge.uploadFiles($.id,s),y("Заметка сохранена!","success"),n(""),i([]),o([]),e()}catch(b){console.error("Ошибка сохранения заметки:",b),y("Ошибка сохранения заметки","error")}},S=async()=>{if(!t.trim()){y("Введите текст для улучшения","warning");return}a(!0);try{const b=await ry.improveText(t);n(b),y("Текст улучшен!","success")}catch(b){console.error("Ошибка улучшения текста:",b),y("Ошибка улучшения текста","error")}finally{a(!1)}},N=x.useCallback(()=>{const b=g.current;if(!b)return{bold:!1,italic:!1,strikethrough:!1};const P=b.selectionStart,L=b.selectionEnd;if(P===L)return{bold:!1,italic:!1,strikethrough:!1};const $=t.substring(P,L),H={bold:!1,italic:!1,strikethrough:!1},G=10,J=Math.max(0,P-G),oe=Math.min(t.length,L+G),le=t.substring(J,oe),xe=P-J,ne=le.substring(0,xe),Ae=le.substring(xe+$.length),Lt=(Xn,yi)=>{let Jn=0;for(let dn=Xn.length-1;dn>=0&&Xn[dn]===yi;dn--)Jn++;return Jn},_e=(Xn,yi)=>{let Jn=0;for(let dn=0;dn=4;(R||V)&&(H.strikethrough=!0);const Y=Lt(ne,"*"),de=_e(Ae,"*"),He=_e($,"*"),$e=Lt($,"*"),hi=Y>=2,mi=de>=2,gi=He>=2&&$e>=2;(hi&&mi||gi&&$.length>=4)&&(H.bold=!0);const vi=Y===1||Y>=3&&Y%2===1,Bl=de===1||de>=3&&de%2===1,Wl=He===1&&$e===1||He>=3&&$e>=3&&He%2===1&&$e%2===1;return vi&&Bl&&!H.bold?H.italic=!0:Y>=3&&de>=3?(H.italic=!0,H.bold=!0):(Wl&&$.length>=2||He===1&&$e===1&&$.length>=2&&!$.startsWith("**")&&!$.endsWith("**"))&&(H.italic=!0),H.bold&&(Y>=3||de>=3||He>=3||$e>=3)&&(H.italic=!0),H},[t]),_=x.useCallback((b,P="")=>{const L=g.current;if(!L)return;const $=L.selectionStart,H=L.selectionEnd,G=t.substring($,H),J=b.length,oe=Math.max(0,$-J),le=Math.min(t.length,H+J),xe=t.substring(oe,le),ne=$-oe,Ae=xe.substring(0,ne),Lt=xe.substring(ne+G.length),_e=Ae.endsWith(b),Ce=Lt.startsWith(P),Pe=G.startsWith(b),R=G.endsWith(P);let V=!1;if(b==="*"&&P==="*"){const $e=$>1?t[$-2]:"",hi=H+1=2&&!G.startsWith("**")&&!G.endsWith("**");V=mi&&gi||vi}else b==="**"&&P==="**"||b==="~~"&&P==="~~"?V=_e&&Ce||Pe&&R&&G.length>=4:V=_e&&Ce||Pe&&R&&G.length>=J*2;let Y,de,He;if(V)if(_e&&Ce)Y=t.substring(0,$-J)+G+t.substring(H+J),de=$-J,He=H-J;else{const $e=G.substring(J,G.length-J);Y=t.substring(0,$)+$e+t.substring(H),de=$,He=$+$e.length}else Y=t.substring(0,$)+b+G+P+t.substring(H),de=$+b.length,He=H+b.length;n(Y),setTimeout(()=>{L.focus(),L.setSelectionRange(de,He);const $e=N();k($e)},0)},[t,N]),D=x.useCallback(()=>{const b=document.createElement("input");b.type="color",b.style.display="none",document.body.appendChild(b),b.addEventListener("change",function(){const P=this.value,L=g.current;if(!L)return;const $=L.selectionStart,H=L.selectionEnd,G=t.substring($,H),J=t.substring(0,$),oe=t.substring(H);let le;G.trim()===""?le=`Текст`:le=`${G}`;const xe=J+le+oe;n(xe),setTimeout(()=>{L.focus();const ne=$+le.length;L.setSelectionRange(ne,ne)},0),document.body.removeChild(this)}),b.addEventListener("cancel",function(){document.body.removeChild(this)}),b.click()},[t]),M=b=>{if((b.altKey||b.ctrlKey)&&b.key==="Enter")b.preventDefault(),j();else if(b.key==="Enter"){const P=b.currentTarget,L=P.selectionStart,$=P.value,H=$.split(` +`);let G=0,J="";for(let ne=0;ne=L){J=H[ne];break}G+=Ae+1}const oe=[/^(\s*)- \[ \] /,/^(\s*)- \[x\] /i,/^(\s*)- /,/^(\s*)\* /,/^(\s*)\+ /,/^(\s*)(\d+)\. /,/^(\s*)(\w+)\. /,/^(\s*)1\. /];let le=null,xe=null;for(const ne of oe){const Ae=J.match(ne);if(Ae){le=Ae,ne===oe[0]||ne===oe[1]?xe="checkbox":ne===oe[2]||ne===oe[3]||ne===oe[4]?xe="unordered":ne===oe[7]?xe="numbered":xe="ordered";break}}if(le){b.preventDefault();const ne=le[1]||"",Ae=le[0].slice(ne.length);if(J.slice(le[0].length).trim()===""){const _e=$.substring(0,L),Ce=$.substring(L),Pe=_e.replace(/\n\s*- \[ \] \s*$|\n\s*- \[x\] \s*$|\n\s*[-*+]\s*$|\n\s*\d+\.\s*$|\n\s*\w+\.\s*$/i,` +`),R=Pe+Ce;n(R),setTimeout(()=>{const V=Pe.length;P.setSelectionRange(V,V)},0)}else{const _e=$.substring(0,L),Ce=$.substring(L);let Pe="";if(xe==="checkbox")Pe=ne+"- [ ] ";else if(xe==="unordered")Pe=ne+Ae;else if(xe==="ordered"){const Y=parseInt(le[2])+1,de=le[2].replace(/\d+/,Y.toString());Pe=ne+de+". "}else xe==="numbered"&&(Pe=ne+"1. ");const R=_e+` +`+Pe+Ce;n(R),setTimeout(()=>{const V=L+1+Pe.length;P.setSelectionRange(V,V)},0)}}}},q=x.useCallback(()=>{const b=g.current;if(!b)return null;const P=b.selectionStart,L=b.selectionEnd,$=P!==L,H=$?Math.floor((P+L)/2):P,J=b.value.substring(0,H).split(` +`),oe=J.length-1,le=J[J.length-1],xe=b.getBoundingClientRect(),ne=window.getComputedStyle(b),Ae=parseInt(ne.lineHeight)||20,Lt=parseInt(ne.paddingTop)||0,_e=parseInt(ne.paddingLeft)||0,Ce=document.createElement("span");Ce.style.position="absolute",Ce.style.visibility="hidden",Ce.style.whiteSpace="pre",Ce.style.font=ne.font,Ce.textContent=le,document.body.appendChild(Ce);const Pe=Ce.offsetWidth;document.body.removeChild(Ce);const R=xe.top+Lt+oe*Ae+Ae/2,V=xe.left+_e+Pe;return{top:R,left:V,hasSelection:$}},[]),X=x.useCallback(()=>{if(m){d(!1);return}const b=t.trim().length>0,P=q();if(P&&b)if(p({top:P.top,left:P.left}),h(P.hasSelection),d(!0),P.hasSelection){const L=N();k(L)}else k({bold:!1,italic:!1,strikethrough:!1});else d(!1),h(!1),k({bold:!1,italic:!1,strikethrough:!1})},[m,t,q,N]);x.useEffect(()=>{const b=g.current;if(!b||m)return;const P=()=>{setTimeout(X,0)},L=G=>{G.buttons===1&&setTimeout(X,0)},$=()=>{setTimeout(X,0)},H=G=>{const J=G.target;if(J===b||b.contains(J)){const oe=b.value.trim().length>0,le=b.selectionStart!==b.selectionEnd;oe&&le&&(G.preventDefault(),G.stopPropagation())}};return b.addEventListener("mouseup",P),b.addEventListener("mousemove",L),b.addEventListener("keyup",$),b.addEventListener("contextmenu",H),document.addEventListener("selectionchange",X),document.addEventListener("contextmenu",H,!0),()=>{b.removeEventListener("mouseup",P),b.removeEventListener("mousemove",L),b.removeEventListener("keyup",$),b.removeEventListener("contextmenu",H),document.removeEventListener("selectionchange",X),document.removeEventListener("contextmenu",H,!0)}},[m,X]),x.useEffect(()=>{const b=P=>{const L=g.current,$=P.target,H=document.querySelector(".floating-toolbar");H&&H.contains($)||L&&!L.contains($)&&setTimeout(()=>{L.selectionStart===L.selectionEnd&&d(!1)},0)};return document.addEventListener("mousedown",b),()=>{document.removeEventListener("mousedown",b)}},[]),x.useEffect(()=>{if(!u)return;const b=()=>{const L=q();if(L&&(p({top:L.top,left:L.left}),h(L.hasSelection),L.hasSelection)){const $=N();k($)}},P=g.current;return P&&(P.addEventListener("scroll",b),window.addEventListener("scroll",b,!0)),()=>{P&&P.removeEventListener("scroll",b),window.removeEventListener("scroll",b,!0)}},[u,q,N]),Jt.useEffect(()=>{const b=g.current;if(!b)return;const P=()=>{b.style.height="auto",b.style.height=b.scrollHeight+"px"};return b.addEventListener("input",P),P(),()=>{b.removeEventListener("input",P)}},[t]);const te=x.useRef(null),K=x.useRef(null),z=()=>{var b;(b=te.current)==null||b.click()},Q=()=>{var b;(b=K.current)==null||b.click()},se=b=>{const L=Array.from(b.target.files||[]).filter($=>$.type.startsWith("image/")&&$.size<=10*1024*1024);if(L.length+r.length>10){y("Можно загрузить максимум 10 изображений","warning");return}i([...r,...L]),te.current&&(te.current.value="")},O=b=>{const P=Array.from(b.target.files||[]),L=/pdf|doc|docx|xls|xlsx|txt|zip|rar|7z/,$=["application/pdf","application/msword","application/vnd.openxmlformats-officedocument.wordprocessingml.document","application/vnd.ms-excel","application/vnd.openxmlformats-officedocument.spreadsheetml.sheet","text/plain","application/zip","application/x-zip-compressed","application/x-rar-compressed","application/x-7z-compressed"],H=P.filter(G=>{var J;return($.includes(G.type)||L.test(((J=G.name.split(".").pop())==null?void 0:J.toLowerCase())||""))&&G.size<=50*1024*1024});o([...s,...H]),K.current&&(K.current.value="")};return c.jsxs("div",{className:"main",children:[c.jsx(Xv,{onInsert:_,onImageClick:z,onFileClick:Q}),c.jsx("input",{ref:te,type:"file",id:"imageInput",accept:"image/*",multiple:!0,style:{display:"none"},onChange:se}),c.jsx("input",{ref:K,type:"file",id:"fileInput",accept:".pdf,.doc,.docx,.xls,.xlsx,.txt,.zip,.rar,.7z",multiple:!0,style:{display:"none"},onChange:O}),!m&&c.jsxs(c.Fragment,{children:[c.jsx("textarea",{ref:g,className:"textInput",id:"noteInput",placeholder:"Ваша заметка...",value:t,onChange:b=>n(b.target.value),onKeyDown:M,onContextMenu:b=>{const P=g.current;if(P){const L=P.value.trim().length>0,$=P.selectionStart!==P.selectionEnd;L&&$&&b.preventDefault()}}}),c.jsx(Jv,{textareaRef:g,onFormat:_,visible:u,position:f,onHide:()=>d(!1),onInsertColor:D,activeFormats:v,hasSelection:w})]}),m&&c.jsx(ey,{content:t}),c.jsx(ty,{images:r,onChange:i}),c.jsx(ny,{files:s,onChange:o}),c.jsxs("div",{className:"save-button-container",children:[c.jsxs("div",{className:"action-buttons",children:[C&&c.jsxs("button",{className:"btnSave btnAI",onClick:S,disabled:l,title:"Улучшить или создать текст через ИИ",children:[c.jsx(F,{icon:"mdi:robot"}),l?"Обработка...":"Помощь ИИ"]}),c.jsx("button",{className:"btnSave",onClick:j,children:"Сохранить"})]}),c.jsx("span",{className:"save-hint",children:"или нажмите Alt + Enter"})]})]})},Pd=({isOpen:e,onClose:t,onConfirm:n,title:r,message:i,confirmText:s="OK",cancelText:o="Отмена",confirmType:l="primary"})=>(x.useEffect(()=>{const a=u=>{u.key==="Escape"&&t()};return e&&document.addEventListener("keydown",a),()=>document.removeEventListener("keydown",a)},[e,t]),e?c.jsx("div",{className:"modal",style:{display:"block"},onClick:t,children:c.jsxs("div",{className:"modal-content",onClick:a=>a.stopPropagation(),children:[c.jsxs("div",{className:"modal-header",children:[c.jsx("h3",{children:r}),c.jsx("span",{className:"modal-close",onClick:t,children:"×"})]}),c.jsx("div",{className:"modal-body",children:typeof i=="string"?c.jsx("p",{children:i}):i}),c.jsxs("div",{className:"modal-footer",children:[c.jsx("button",{className:l==="danger"?"btn-danger":"btn-primary",onClick:n,style:{marginRight:"10px"},children:s}),c.jsx("button",{className:"btn-secondary",onClick:t,children:o})]})]})}):null);function Ma(e,t,n){return e.startsWith("http://")||e.startsWith("https://")||e.startsWith("/api")||e.startsWith("/uploads")?e:e.startsWith("/")?`/api${e}`:`/api/notes/${t}/images/${n}`}function GN(e,t,n){return e.startsWith("http://")||e.startsWith("https://")||e.startsWith("/api")||e.startsWith("/uploads")?e:e.startsWith("/")?`/api${e}`:`/api/notes/${t}/files/${n}`}const YN=({note:e,onPin:t,onArchive:n,onReload:r})=>{const[i,s]=x.useState(!1),[o,l]=x.useState(e.content),[a,u]=x.useState(!1),[d,f]=x.useState([]),[p,w]=x.useState([]),[h,v]=x.useState([]),[k,g]=x.useState([]),[m,y]=x.useState(!1),[C,j]=x.useState(!1),[S,N]=x.useState({top:0,left:0}),[_,D]=x.useState(!1),[M,q]=x.useState({bold:!1,italic:!1,strikethrough:!1}),[X,te]=x.useState(!1),[K,z]=x.useState(!1),[Q,se]=x.useState(!1),O=x.useRef(null),b=x.useRef(null),P=x.useRef(null),L=x.useRef(null),$=ye(E=>E.notes.searchQuery),H=ye(E=>E.ui.isPreviewMode),G=ye(E=>E.profile.aiEnabled),{showNotification:J}=Tr(),oe=ot();Zv({onNoteUpdate:r});const le=()=>{s(!0),l(e.content),f([]),w([]),v([]),g([]),j(!1),q({bold:!1,italic:!1,strikethrough:!1}),te(!1)},xe=()=>{te(!X),j(!1)},ne=async()=>{if(!o.trim()){J("Введите текст заметки","warning");return}try{await Ge.update(e.id,o);for(const E of h)await Ge.deleteImage(e.id,E);for(const E of k)await Ge.deleteFile(e.id,E);d.length>0&&await Ge.uploadImages(e.id,d),p.length>0&&await Ge.uploadFiles(e.id,p),J("Заметка обновлена!","success"),s(!1),f([]),w([]),v([]),g([]),r()}catch(E){console.error("Ошибка обновления заметки:",E),J("Ошибка обновления заметки","error")}},Ae=()=>{s(!1),l(e.content),f([]),w([]),v([]),g([]),j(!1),q({bold:!1,italic:!1,strikethrough:!1}),te(!1)},Lt=E=>{v([...h,E])},_e=E=>{g([...k,E])},Ce=E=>{v(h.filter(A=>A!==E))},Pe=E=>{g(k.filter(A=>A!==E))},R=async()=>{if(!o.trim()){J("Введите текст для улучшения","warning");return}y(!0);try{const E=await ry.improveText(o);l(E),J("Текст улучшен!","success")}catch(E){console.error("Ошибка улучшения текста:",E),J("Ошибка улучшения текста","error")}finally{y(!1)}},V=x.useCallback(()=>{const E=O.current;if(!E)return{bold:!1,italic:!1,strikethrough:!1};const A=E.selectionStart,U=E.selectionEnd;if(A===U)return{bold:!1,italic:!1,strikethrough:!1};const W=o.substring(A,U),Z={bold:!1,italic:!1,strikethrough:!1},re=10,ge=Math.max(0,A-re),Ve=Math.min(o.length,U+re),Oe=o.substring(ge,Ve),Ue=A-ge,ue=Oe.substring(0,Ue),lt=Oe.substring(Ue+W.length),Zn=(wi,Kl)=>{let xi=0;for(let er=wi.length-1;er>=0&&wi[er]===Kl;er--)xi++;return xi},mt=(wi,Kl)=>{let xi=0;for(let er=0;er=4;(It||et)&&(Z.strikethrough=!0);const Et=Zn(ue,"*"),Ct=mt(lt,"*"),Bt=mt(W,"*"),bt=Zn(W,"*"),Ql=Et>=2,ql=Ct>=2,Gl=Bt>=2&&bt>=2;(Ql&&ql||Gl&&W.length>=4)&&(Z.bold=!0);const Yl=Et===1||Et>=3&&Et%2===1,ly=Ct===1||Ct>=3&&Ct%2===1,ay=Bt===1&&bt===1||Bt>=3&&bt>=3&&Bt%2===1&&bt%2===1;return Yl&&ly&&!Z.bold?Z.italic=!0:Et>=3&&Ct>=3?(Z.italic=!0,Z.bold=!0):(ay&&W.length>=2||Bt===1&&bt===1&&W.length>=2&&!W.startsWith("**")&&!W.endsWith("**"))&&(Z.italic=!0),Z.bold&&(Et>=3||Ct>=3||Bt>=3||bt>=3)&&(Z.italic=!0),Z},[o]),Y=x.useCallback((E,A="")=>{const U=O.current;if(!U)return;const W=U.selectionStart,Z=U.selectionEnd,re=o.substring(W,Z),ge=E.length,Ve=Math.max(0,W-ge),Oe=Math.min(o.length,Z+ge),Ue=o.substring(Ve,Oe),ue=W-Ve,lt=Ue.substring(0,ue),Zn=Ue.substring(ue+re.length),mt=lt.endsWith(E),ze=Zn.startsWith(A),Qe=re.startsWith(E),It=re.endsWith(A);let et=!1;if(E==="*"&&A==="*"){const bt=W>1?o[W-2]:"",Ql=Z+1=2&&!re.startsWith("**")&&!re.endsWith("**");et=ql&&Gl||Yl}else E==="**"&&A==="**"||E==="~~"&&A==="~~"?et=mt&&ze||Qe&&It&&re.length>=4:et=mt&&ze||Qe&&It&&re.length>=ge*2;let Et,Ct,Bt;if(et)if(mt&&ze)Et=o.substring(0,W-ge)+re+o.substring(Z+ge),Ct=W-ge,Bt=Z-ge;else{const bt=re.substring(ge,re.length-ge);Et=o.substring(0,W)+bt+o.substring(Z),Ct=W,Bt=W+bt.length}else Et=o.substring(0,W)+E+re+A+o.substring(Z),Ct=W+E.length,Bt=Z+E.length;l(Et),setTimeout(()=>{U.focus(),U.setSelectionRange(Ct,Bt);const bt=V();q(bt)},0)},[o,V]),de=x.useCallback(()=>{const E=document.createElement("input");E.type="color",E.style.display="none",document.body.appendChild(E),E.addEventListener("change",function(){const A=this.value,U=O.current;if(!U)return;const W=U.selectionStart,Z=U.selectionEnd,re=o.substring(W,Z),ge=o.substring(0,W),Ve=o.substring(Z);let Oe;re.trim()===""?Oe=`Текст`:Oe=`${re}`;const Ue=ge+Oe+Ve;l(Ue),setTimeout(()=>{U.focus();const ue=W+Oe.length;U.setSelectionRange(ue,ue)},0),document.body.removeChild(this)}),E.addEventListener("cancel",function(){document.body.removeChild(this)}),E.click()},[o]),He=x.useCallback(()=>{const E=O.current;if(!E)return null;const A=E.selectionStart,U=E.selectionEnd,W=A!==U,Z=W?Math.floor((A+U)/2):A,ge=E.value.substring(0,Z).split(` +`),Ve=ge.length-1,Oe=ge[ge.length-1],Ue=E.getBoundingClientRect(),ue=window.getComputedStyle(E),lt=parseInt(ue.lineHeight)||20,Zn=parseInt(ue.paddingTop)||0,mt=parseInt(ue.paddingLeft)||0,ze=document.createElement("span");ze.style.position="absolute",ze.style.visibility="hidden",ze.style.whiteSpace="pre",ze.style.font=ue.font,ze.textContent=Oe,document.body.appendChild(ze);const Qe=ze.offsetWidth;document.body.removeChild(ze);const It=Ue.top+Zn+Ve*lt+lt/2,et=Ue.left+mt+Qe;return{top:It,left:et,hasSelection:W}},[]),$e=x.useCallback(()=>{if(X){j(!1);return}const E=o.trim().length>0,A=He();if(A&&E)if(N({top:A.top,left:A.left}),D(A.hasSelection),j(!0),A.hasSelection){const U=V();q(U)}else q({bold:!1,italic:!1,strikethrough:!1});else j(!1),D(!1),q({bold:!1,italic:!1,strikethrough:!1})},[X,o,He,V]),hi=()=>{var E;(E=b.current)==null||E.click()},mi=()=>{var E;(E=P.current)==null||E.click()},gi=E=>{const U=Array.from(E.target.files||[]).filter(W=>W.type.startsWith("image/")&&W.size<=10*1024*1024);if(U.length+d.length>10){J("Можно загрузить максимум 10 изображений","warning");return}f([...d,...U]),b.current&&(b.current.value="")},vi=E=>{const A=Array.from(E.target.files||[]),U=/pdf|doc|docx|xls|xlsx|txt|zip|rar|7z/,W=["application/pdf","application/msword","application/vnd.openxmlformats-officedocument.wordprocessingml.document","application/vnd.ms-excel","application/vnd.openxmlformats-officedocument.spreadsheetml.sheet","text/plain","application/zip","application/x-zip-compressed","application/x-rar-compressed","application/x-7z-compressed"],Z=A.filter(re=>{var ge;return(W.includes(re.type)||U.test(((ge=re.name.split(".").pop())==null?void 0:ge.toLowerCase())||""))&&re.size<=50*1024*1024});w([...p,...Z]),P.current&&(P.current.value="")},Bl=E=>{if((E.altKey||E.ctrlKey)&&E.key==="Enter")E.preventDefault(),ne();else if(E.key==="Escape")E.preventDefault(),Ae();else if(E.key==="Enter"){const A=E.currentTarget,U=A.selectionStart,W=A.value,Z=W.split(` +`);let re=0,ge="";for(let ue=0;ue=U){ge=Z[ue];break}re+=lt+1}const Ve=[/^(\s*)- \[ \] /,/^(\s*)- \[x\] /i,/^(\s*)- /,/^(\s*)\* /,/^(\s*)\+ /,/^(\s*)(\d+)\. /,/^(\s*)(\w+)\. /,/^(\s*)1\. /];let Oe=null,Ue=null;for(const ue of Ve){const lt=ge.match(ue);if(lt){Oe=lt,ue===Ve[0]||ue===Ve[1]?Ue="checkbox":ue===Ve[2]||ue===Ve[3]||ue===Ve[4]?Ue="unordered":ue===Ve[7]?Ue="numbered":Ue="ordered";break}}if(Oe){E.preventDefault();const ue=Oe[1]||"",lt=Oe[0].slice(ue.length);if(ge.slice(Oe[0].length).trim()===""){const mt=W.substring(0,U),ze=W.substring(U),Qe=mt.replace(/\n\s*- \[ \] \s*$|\n\s*- \[x\] \s*$|\n\s*[-*+]\s*$|\n\s*\d+\.\s*$|\n\s*\w+\.\s*$/i,` +`),It=Qe+ze;l(It),setTimeout(()=>{const et=Qe.length;A.setSelectionRange(et,et)},0)}else{const mt=W.substring(0,U),ze=W.substring(U);let Qe="";if(Ue==="checkbox")Qe=ue+"- [ ] ";else if(Ue==="unordered")Qe=ue+lt;else if(Ue==="ordered"){const Et=parseInt(Oe[2])+1,Ct=Oe[2].replace(/\d+/,Et.toString());Qe=ue+Ct+". "}else Ue==="numbered"&&(Qe=ue+"1. ");const It=mt+` +`+Qe+ze;l(It),setTimeout(()=>{const et=U+1+Qe.length;A.setSelectionRange(et,et)},0)}}}},Wl=()=>{u(!0)};x.useEffect(()=>{if(!i)return;const E=O.current;if(!E)return;const A=()=>{E.style.height="auto",E.style.height=E.scrollHeight+"px"};return E.addEventListener("input",A),A(),()=>{E.removeEventListener("input",A)}},[i,o]),x.useEffect(()=>{i&&O.current&&!X&&setTimeout(()=>{var A;(A=O.current)==null||A.focus();const E=O.current;E&&E.setSelectionRange(o.length,o.length)},100)},[i,X,o]),x.useEffect(()=>{if(!i)return;const E=O.current;if(!E||X)return;const A=()=>{setTimeout($e,0)},U=re=>{re.buttons===1&&setTimeout($e,0)},W=()=>{setTimeout($e,0)},Z=re=>{const ge=re.target;if(ge===E||E.contains(ge)){const Ve=E.value.trim().length>0,Oe=E.selectionStart!==E.selectionEnd;Ve&&Oe&&(re.preventDefault(),re.stopPropagation())}};return E.addEventListener("mouseup",A),E.addEventListener("mousemove",U),E.addEventListener("keyup",W),E.addEventListener("contextmenu",Z),document.addEventListener("selectionchange",$e),document.addEventListener("contextmenu",Z,!0),()=>{E.removeEventListener("mouseup",A),E.removeEventListener("mousemove",U),E.removeEventListener("keyup",W),E.removeEventListener("contextmenu",Z),document.removeEventListener("selectionchange",$e),document.removeEventListener("contextmenu",Z,!0)}},[i,H,$e]),x.useEffect(()=>{if(!i)return;const E=A=>{const U=O.current,W=A.target,Z=document.querySelector(".floating-toolbar");Z&&Z.contains(W)||U&&!U.contains(W)&&setTimeout(()=>{U.selectionStart===U.selectionEnd&&j(!1)},0)};return document.addEventListener("mousedown",E),()=>{document.removeEventListener("mousedown",E)}},[i]),x.useEffect(()=>{if(!i||!C)return;const E=()=>{const U=He();if(U&&(N({top:U.top,left:U.left}),D(U.hasSelection),U.hasSelection)){const W=V();q(W)}},A=O.current;return A&&(A.addEventListener("scroll",E),window.addEventListener("scroll",E,!0)),()=>{A&&A.removeEventListener("scroll",E),window.removeEventListener("scroll",E,!0)}},[i,C,He,V]);const Xn=()=>{u(!1),n(e.id)},yi=E=>E?E.length>5&&E.match(/^\d{2}:\d{2}/)?E.substring(0,5):E:E||"",Jn=()=>{if(e.created_at){const E=Zu(e.created_at),U=Up(E).replace(/(\d{2}\.\d{2}\.\d{4} \d{2}:\d{2})\d*.*/,"$1");if(e.updated_at&&e.created_at!==e.updated_at){const W=Zu(e.updated_at),re=Up(W).replace(/(\d{2}\.\d{2}\.\d{4} \d{2}:\d{2})\d*.*/,"$1");return c.jsxs(c.Fragment,{children:[U,c.jsx("span",{className:"date-separator",children:" | "}),c.jsx(F,{icon:"mdi:pencil",style:{fontSize:"12px",margin:"0 2px"}}),re]})}else return U}else{const E=yi(e.time);return`${e.date} ${E}`}},dn=()=>{let E=e.content;$&&(E=WN(E,$));const A=BN(E);return _d(A)},Hl=E=>{var U;const A=((U=E.split(".").pop())==null?void 0:U.toLowerCase())||"";return A==="pdf"?"mdi:file-pdf":["doc","docx"].includes(A)?"mdi:file-word":["xls","xlsx"].includes(A)?"mdi:file-excel":A==="txt"?"mdi:file-document":["zip","rar","7z"].includes(A)?"mdi:folder-zip":"mdi:file"},Vl=E=>(E/1024/1024).toFixed(2)+" MB",iy=E=>{const A=document.getElementById("imageModal"),U=document.getElementById("modalImage");A&&U&&(U.setAttribute("src",E),A.style.display="block")},sy=(E,A)=>{E.stopPropagation(),oe(rl(A))},oy=()=>{z(!K)};return x.useEffect(()=>{if(i){z(!1),se(!1);return}if(!L.current)return;const A=setTimeout(()=>{const U=L.current;if(!U)return;const W=U.classList.contains("collapsed");W&&U.classList.remove("collapsed");const Z=U.scrollHeight;W&&!K&&U.classList.add("collapsed");const re=Z>300;se(re)},100);return()=>clearTimeout(A)},[e.content,i,K]),x.useEffect(()=>{z(!1)},[e.id]),c.jsxs(c.Fragment,{children:[c.jsxs("div",{className:`container ${e.is_pinned?"note-pinned":""}`,"data-note-id":e.id,children:[c.jsxs("div",{className:"date",children:[c.jsxs("span",{className:"date-text",children:[Jn(),e.is_pinned?c.jsxs("span",{className:"pin-indicator",children:[c.jsx(F,{icon:"mdi:pin"}),"Закреплено"]}):null]}),c.jsxs("div",{className:"note-actions",children:[c.jsx("div",{className:"notesHeaderBtn",onClick:()=>t(e.id),title:e.is_pinned?"Открепить":"Закрепить",children:c.jsx(F,{icon:e.is_pinned?"mdi:pin-off":"mdi:pin"})}),c.jsx("div",{className:"notesHeaderBtn",onClick:le,title:"Редактировать",children:c.jsx(F,{icon:"mdi:pencil"})}),c.jsx("div",{className:"notesHeaderBtn",onClick:Wl,title:"В архив",children:c.jsx(F,{icon:"mdi:delete"})})]})]}),i?c.jsxs("div",{className:"note-edit-mode",children:[c.jsx(Xv,{onInsert:Y,onImageClick:hi,onFileClick:mi,onPreviewToggle:xe,isPreviewMode:X}),c.jsx("input",{ref:b,type:"file",id:"imageInput",accept:"image/*",multiple:!0,style:{display:"none"},onChange:gi}),c.jsx("input",{ref:P,type:"file",id:"fileInput",accept:".pdf,.doc,.docx,.xls,.xlsx,.txt,.zip,.rar,.7z",multiple:!0,style:{display:"none"},onChange:vi}),!X&&c.jsxs(c.Fragment,{children:[c.jsx("textarea",{ref:O,className:"textInput",value:o,onChange:E=>l(E.target.value),onKeyDown:Bl,style:{minHeight:"100px"},onContextMenu:E=>{const A=O.current;if(A){const U=A.value.trim().length>0,W=A.selectionStart!==A.selectionEnd;U&&W&&E.preventDefault()}}}),c.jsx(Jv,{textareaRef:O,onFormat:Y,visible:C,position:S,onHide:()=>j(!1),onInsertColor:de,activeFormats:M,hasSelection:_})]}),X&&c.jsx(ey,{content:o}),e.images&&e.images.length>0&&c.jsxs("div",{className:"image-preview-container",style:{display:"block"},children:[c.jsx("div",{className:"image-preview-header",children:c.jsx("span",{children:"Прикрепленные изображения:"})}),c.jsx("div",{className:"image-preview-list",children:e.images.filter(E=>!h.includes(E.id)).map(E=>{const A=Ma(E.file_path,e.id,E.id);return c.jsxs("div",{className:"image-preview-item",children:[c.jsx("img",{src:A,alt:E.original_name,className:"image-preview-thumbnail"}),c.jsx("button",{className:"image-preview-remove",onClick:()=>Lt(E.id),title:"Удалить",children:c.jsx(F,{icon:"mdi:close"})})]},E.id)})})]}),h.length>0&&c.jsxs("div",{className:"image-preview-container",style:{display:"block",opacity:.5},children:[c.jsx("div",{className:"image-preview-header",children:c.jsx("span",{children:"Изображения для удаления:"})}),c.jsx("div",{className:"image-preview-list",children:e.images.filter(E=>h.includes(E.id)).map(E=>{const A=Ma(E.file_path,e.id,E.id);return c.jsxs("div",{className:"image-preview-item",children:[c.jsx("img",{src:A,alt:E.original_name,className:"image-preview-thumbnail",style:{opacity:.5}}),c.jsx("button",{className:"image-preview-remove restore-btn",onClick:()=>Ce(E.id),title:"Восстановить",children:c.jsx(F,{icon:"mdi:restore"})})]},E.id)})})]}),e.files&&e.files.length>0&&c.jsxs("div",{className:"file-preview-container",style:{display:"block"},children:[c.jsx("div",{className:"file-preview-header",children:c.jsx("span",{children:"Прикрепленные файлы:"})}),c.jsx("div",{className:"file-preview-list",children:e.files.filter(E=>!k.includes(E.id)).map(E=>c.jsxs("div",{className:"file-preview-item",children:[c.jsx(F,{icon:Hl(E.original_name),className:"file-icon"}),c.jsxs("div",{className:"file-info",children:[c.jsx("div",{className:"file-name",children:E.original_name}),c.jsx("div",{className:"file-size",children:Vl(E.file_size)})]}),c.jsx("button",{className:"file-preview-remove",onClick:()=>_e(E.id),title:"Удалить",children:c.jsx(F,{icon:"mdi:close"})})]},E.id))})]}),k.length>0&&c.jsxs("div",{className:"file-preview-container",style:{display:"block",opacity:.5},children:[c.jsx("div",{className:"file-preview-header",children:c.jsx("span",{children:"Файлы для удаления:"})}),c.jsx("div",{className:"file-preview-list",children:e.files.filter(E=>k.includes(E.id)).map(E=>c.jsxs("div",{className:"file-preview-item",children:[c.jsx(F,{icon:Hl(E.original_name),className:"file-icon",style:{opacity:.5}}),c.jsxs("div",{className:"file-info",children:[c.jsx("div",{className:"file-name",style:{opacity:.5},children:E.original_name}),c.jsx("div",{className:"file-size",style:{opacity:.5},children:Vl(E.file_size)})]}),c.jsx("button",{className:"file-preview-remove restore-btn",onClick:()=>Pe(E.id),title:"Восстановить",children:c.jsx(F,{icon:"mdi:restore"})})]},E.id))})]}),c.jsx(ty,{images:d,onChange:f}),c.jsx(ny,{files:p,onChange:w}),c.jsxs("div",{className:"save-button-container",children:[c.jsxs("div",{className:"action-buttons",children:[G&&c.jsxs("button",{className:"btnSave btnAI",onClick:R,disabled:m,title:"Улучшить или создать текст через ИИ",children:[c.jsx(F,{icon:"mdi:robot"}),m?"Обработка...":"Помощь ИИ"]}),c.jsx("button",{className:"btnSave",onClick:ne,children:"Сохранить"}),c.jsx("button",{className:"btn-secondary",onClick:Ae,children:"Отмена"})]}),c.jsx("span",{className:"save-hint",children:"Alt + Enter для сохранения, Esc для отмены"})]})]}):c.jsxs(c.Fragment,{children:[c.jsx("div",{ref:L,className:`textNote ${Q&&!K?"collapsed":""}`,"data-original-content":e.content,dangerouslySetInnerHTML:{__html:dn()},onClick:E=>{const A=E.target;if(A.classList.contains("tag-in-note")){const U=A.getAttribute("data-tag");U&&sy(E,U)}}}),Q&&c.jsxs("button",{className:"show-more-btn",onClick:oy,type:"button",children:[c.jsx(F,{icon:K?"mdi:chevron-up":"mdi:chevron-down"}),c.jsx("span",{children:K?"Скрыть":"Раскрыть"})]}),e.images&&e.images.length>0&&c.jsx("div",{className:"note-images-container",children:e.images.map(E=>{const A=Ma(E.file_path,e.id,E.id);return c.jsx("div",{className:"note-image-item",children:c.jsx("img",{src:A,alt:E.original_name,className:"note-image lazy","data-src":A,"data-image-id":E.id,loading:"lazy",onClick:()=>iy(A)})},E.id)})}),e.files&&e.files.length>0&&c.jsx("div",{className:"note-files-container",children:e.files.map(E=>{const A=GN(E.file_path,e.id,E.id);return c.jsx("div",{className:"note-file-item",children:c.jsxs("a",{href:A,download:E.original_name,className:"note-file-link","data-file-id":E.id,children:[c.jsx(F,{icon:Hl(E.original_name),className:"file-icon"}),c.jsxs("div",{className:"file-info",children:[c.jsx("div",{className:"file-name",children:E.original_name}),c.jsx("div",{className:"file-size",children:Vl(E.file_size)})]})]})},E.id)})})]})]}),c.jsx(Pd,{isOpen:a,onClose:()=>u(!1),onConfirm:Xn,title:"Подтверждение архивирования",message:"Архивировать эту заметку? Её можно будет восстановить из настроек.",confirmText:"Архивировать",cancelText:"Отмена"})]})},KN=x.forwardRef((e,t)=>{const n=ye(h=>h.notes.notes),r=ye(h=>h.auth.userId),i=ye(h=>h.notes.searchQuery),s=ye(h=>h.notes.selectedDate),o=ye(h=>h.notes.selectedTag),l=ot(),{showNotification:a}=Tr(),u=async()=>{try{const h=await Ge.getAll();let v=h;r&&(v=h.filter(g=>g.user_id===r)),l(n1(v));let k;i||s||o?(k=await Ge.search({q:i||void 0,date:s||void 0,tag:o||void 0}),r&&(k=k.filter(g=>g.user_id===r))):k=v,l(t1(k))}catch(h){console.error("Ошибка загрузки заметок:",h),a("Ошибка загрузки заметок","error")}};x.useEffect(()=>{r&&u()},[r,i,s,o]),x.useImperativeHandle(t,()=>({reloadNotes:u}));const d=async h=>{try{await Ge.delete(h),a("Заметка удалена","success"),u()}catch(v){console.error("Ошибка удаления заметки:",v),a("Ошибка удаления заметки","error")}},f=async h=>{try{await Ge.pin(h),u()}catch(v){console.error("Ошибка закрепления заметки:",v),a("Ошибка закрепления заметки","error")}},p=async h=>{try{await Ge.archive(h),a("Заметка архивирована","success"),u()}catch(v){console.error("Ошибка архивирования заметки:",v),a("Ошибка архивирования заметки","error")}};if(n.length===0){let h="Заметок пока нет. Создайте первую!";return s&&o?h=`Нет заметок за ${s} с тегом #${o}`:s?h=`Нет заметок за выбранную дату (${s})`:o?h=`Нет заметок с тегом #${o}`:i&&(h="Ничего не найдено по запросу"),c.jsx("div",{className:"notes-container",children:c.jsx("p",{className:"empty-message",children:h})})}const w=[...n].sort((h,v)=>{if(h.is_pinned!==v.is_pinned)return v.is_pinned-h.is_pinned;if(h.is_pinned&&v.is_pinned){const m=h.pinned_at?new Date(h.pinned_at).getTime():0;return(v.pinned_at?new Date(v.pinned_at).getTime():0)-m}const k=new Date(h.created_at).getTime();return new Date(v.created_at).getTime()-k});return c.jsx("div",{className:"notes-container",children:w.map(h=>c.jsx(YN,{note:h,onDelete:d,onPin:f,onArchive:p,onReload:u},h.id))})}),XN=()=>{const[e,t]=x.useState(!1),[n,r]=x.useState("");x.useEffect(()=>{const o=l=>{const a=l.target;if(a.classList.contains("note-image")){const u=a.getAttribute("src")||a.getAttribute("data-src");u&&(r(u),t(!0))}};return document.addEventListener("click",o),()=>{document.removeEventListener("click",o)}},[]),x.useEffect(()=>{const o=l=>{l.key==="Escape"&&e&&t(!1)};return document.addEventListener("keydown",o),()=>document.removeEventListener("keydown",o)},[e]);const i=()=>{t(!1)},s=o=>{o.target===o.currentTarget&&i()};return e?c.jsxs("div",{id:"imageModal",className:"image-modal",style:{display:"block"},onClick:s,children:[c.jsx("span",{className:"image-modal-close",onClick:i,children:"×"}),c.jsx("img",{className:"image-modal-content",id:"modalImage",src:n,alt:"Preview"})]}):null},JN=()=>{const e=ye(v=>v.notes.allNotes),t=x.useRef(null),[n,r]=x.useState(!1),i=ot(),s=ye(v=>v.notes.selectedDate),o=ye(v=>v.notes.selectedTag),l=ye(v=>v.notes.searchQuery),a=!!(s||o||l),u=()=>{i(Fu(null)),i(rl(null)),i(Uu(""))},f=(()=>{const v=[];return l&&v.push(`Поиск: "${l}"`),s&&v.push(`Дата: ${s}`),o&&v.push(`Тег: #${o}`),v})(),p=()=>{t.current&&t.current.reloadNotes()},w=()=>{r(!n)},h=()=>{r(!1)};return c.jsxs(c.Fragment,{children:[c.jsx(VN,{isOpen:n,onClose:h}),c.jsx(HN,{notes:e}),c.jsxs("div",{className:"center",children:[c.jsxs("div",{className:"container",children:[c.jsx(GE,{onToggleSidebar:w}),a&&c.jsxs("div",{className:"filter-indicator",children:[c.jsxs("span",{className:"filter-indicator-text",children:["Фильтр: ",f.join(", ")]})," ",c.jsx("button",{onClick:u,children:"✕"})]}),c.jsx(qN,{onSave:p})]}),c.jsx(KN,{ref:t}),c.jsx("div",{className:"footer",children:c.jsxs("p",{children:["Создатель: ",c.jsx("span",{children:"Fovway"})]})})]}),c.jsx(XN,{})]})},ZN=()=>{const e=Kn(),t=ot(),{showNotification:n}=Tr(),[r,i]=x.useState(""),[s,o]=x.useState(""),[l,a]=x.useState(null),[u,d]=x.useState(!1),[f,p]=x.useState(""),[w,h]=x.useState(""),[v,k]=x.useState(""),[g,m]=x.useState(!1),[y,C]=x.useState(""),[j,S]=x.useState(!1),N=x.useRef(null);x.useEffect(()=>{_()},[]);const _=async()=>{try{const z=await ct.getProfile();t(od(z)),i(z.username||""),o(z.email||"");const Q=z.accent_color||"#007bff";t(il(Q)),Cs(Q),z.avatar?(a(z.avatar),d(!0)):(a(null),d(!1));try{const se=await ct.getAiSettings();t(ld(se))}catch(se){console.error("Ошибка загрузки AI настроек:",se)}}catch(z){console.error("Ошибка загрузки профиля:",z),n("Ошибка загрузки данных профиля","error")}},D=async z=>{var O,b,P;const Q=(O=z.target.files)==null?void 0:O[0];if(!Q)return;if(Q.size>5*1024*1024){n("Файл слишком большой. Максимальный размер: 5 МБ","error");return}if(!["image/jpeg","image/jpg","image/png","image/gif"].includes(Q.type)){n("Недопустимый формат файла. Используйте JPG, PNG или GIF","error");return}try{const L=await ct.uploadAvatar(Q);a(L.avatar+"?t="+Date.now()),d(!0),await _(),n("Аватарка успешно загружена","success")}catch(L){console.error("Ошибка загрузки аватарки:",L),n(((P=(b=L.response)==null?void 0:b.data)==null?void 0:P.error)||"Ошибка загрузки аватарки","error")}N.current&&(N.current.value="")},M=async()=>{var z,Q;try{await ct.deleteAvatar(),a(null),d(!1),await _(),n("Аватарка успешно удалена","success")}catch(se){console.error("Ошибка удаления аватарки:",se),n(((Q=(z=se.response)==null?void 0:z.data)==null?void 0:Q.error)||"Ошибка удаления аватарки","error")}},q=async()=>{var z,Q;if(!r.trim()){n("Логин не может быть пустым","error");return}if(r.length<3){n("Логин должен быть не менее 3 символов","error");return}if(s&&!K(s)){n("Некорректный email адрес","error");return}try{await ct.updateProfile({username:r.trim(),email:s.trim()||void 0}),await _(),n("Профиль успешно обновлен","success")}catch(se){console.error("Ошибка обновления профиля:",se),n(((Q=(z=se.response)==null?void 0:z.data)==null?void 0:Q.error)||"Ошибка обновления профиля","error")}},X=async()=>{var z,Q;if(!f){n("Введите текущий пароль","error");return}if(!w){n("Введите новый пароль","error");return}if(w.length<6){n("Новый пароль должен быть не менее 6 символов","error");return}if(w!==v){n("Новый пароль и подтверждение не совпадают","error");return}try{await ct.updateProfile({currentPassword:f,newPassword:w}),p(""),h(""),k(""),n("Пароль успешно изменен","success")}catch(se){console.error("Ошибка изменения пароля:",se),n(((Q=(z=se.response)==null?void 0:z.data)==null?void 0:Q.error)||"Ошибка изменения пароля","error")}},te=async()=>{var z,Q;if(!y.trim()){n("Введите пароль","warning");return}S(!0);try{await ct.deleteAccount(y),n("Аккаунт успешно удален","success"),t(fr()),setTimeout(()=>{e("/")},2e3)}catch(se){console.error("Ошибка удаления аккаунта:",se),n(((Q=(z=se.response)==null?void 0:z.data)==null?void 0:Q.error)||"Ошибка удаления аккаунта","error"),S(!1)}},K=z=>/^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(z);return c.jsxs("div",{className:"container",children:[c.jsxs("header",{className:"notes-header",children:[c.jsxs("span",{children:[c.jsx(F,{icon:"mdi:account"})," Личный кабинет"]}),c.jsxs("div",{className:"user-info",children:[c.jsx(Ds,{}),c.jsx("button",{className:"notes-btn",onClick:()=>e("/notes"),title:"К заметкам",children:c.jsx(F,{icon:"mdi:note-text"})}),c.jsx("button",{className:"settings-btn",onClick:()=>e("/settings"),title:"Настройки",children:c.jsx(F,{icon:"mdi:cog"})}),c.jsx("button",{className:"logout-btn",title:"Выйти",onClick:async()=>{try{await Sr.logout(),t(fr()),e("/")}catch(z){console.error("Ошибка выхода:",z),t(fr()),e("/")}},children:c.jsx(F,{icon:"mdi:logout"})})]})]}),c.jsxs("div",{className:"profile-container",children:[c.jsxs("div",{className:"avatar-section",children:[c.jsx("div",{className:"avatar-wrapper",children:u&&l?c.jsx("img",{src:l,alt:"Аватар",className:"avatar-preview",loading:"lazy"}):c.jsx("div",{className:"avatar-placeholder",children:c.jsx(F,{icon:"mdi:account"})})}),c.jsxs("div",{className:"avatar-buttons",children:[c.jsxs("label",{htmlFor:"avatarInput",className:"btn-upload",children:[c.jsx(F,{icon:"mdi:upload"})," Загрузить аватар"]}),c.jsx("input",{ref:N,type:"file",id:"avatarInput",accept:"image/*",style:{display:"none"},onChange:D}),u&&c.jsxs("button",{className:"btn-delete",onClick:M,children:[c.jsx(F,{icon:"mdi:delete"})," Удалить"]})]}),c.jsx("p",{className:"avatar-hint",children:"Максимальный размер: 5 МБ. Форматы: JPG, PNG, GIF"})]}),c.jsxs("div",{className:"profile-form",children:[c.jsx("h3",{children:"Данные профиля"}),c.jsxs("div",{className:"form-group",children:[c.jsx("label",{htmlFor:"username",children:"Логин"}),c.jsx("input",{type:"text",id:"username",placeholder:"Логин",minLength:3,value:r,onChange:z=>i(z.target.value)})]}),c.jsxs("div",{className:"form-group",children:[c.jsx("label",{htmlFor:"email",children:"Email (необязательно)"}),c.jsx("input",{type:"email",id:"email",placeholder:"example@example.com",value:s,onChange:z=>o(z.target.value)})]}),c.jsx("button",{className:"btnSave",onClick:q,children:"Сохранить изменения"}),c.jsx("hr",{className:"separator"}),c.jsx("h3",{children:"Изменить пароль"}),c.jsxs("div",{className:"form-group",children:[c.jsx("label",{htmlFor:"currentPassword",children:"Текущий пароль"}),c.jsx("input",{type:"password",id:"currentPassword",placeholder:"Текущий пароль",value:f,onChange:z=>p(z.target.value)})]}),c.jsxs("div",{className:"form-group",children:[c.jsx("label",{htmlFor:"newPassword",children:"Новый пароль"}),c.jsx("input",{type:"password",id:"newPassword",placeholder:"Новый пароль (минимум 6 символов)",minLength:6,value:w,onChange:z=>h(z.target.value)})]}),c.jsxs("div",{className:"form-group",children:[c.jsx("label",{htmlFor:"confirmPassword",children:"Подтвердите новый пароль"}),c.jsx("input",{type:"password",id:"confirmPassword",placeholder:"Подтвердите новый пароль",value:v,onChange:z=>k(z.target.value)})]}),c.jsx("button",{className:"btnSave",onClick:X,children:"Изменить пароль"}),c.jsx("hr",{className:"separator"}),c.jsxs("button",{className:"btn-danger",onClick:()=>m(!0),children:[c.jsx(F,{icon:"mdi:account-remove"})," Удалить аккаунт"]}),c.jsx("p",{style:{color:"#666",fontSize:"14px",marginBottom:"15px"},children:"Удаление аккаунта - это необратимое действие. Все ваши заметки, изображения и данные будут удалены навсегда."})]})]}),c.jsx(Pd,{isOpen:g,onClose:()=>{m(!1),C("")},onConfirm:te,title:"Удаление аккаунта",message:c.jsxs(c.Fragment,{children:[c.jsx("p",{style:{color:"#dc3545",fontWeight:"bold",marginBottom:"15px"},children:"⚠️ ВНИМАНИЕ: Это действие нельзя отменить!"}),c.jsx("p",{style:{marginBottom:"20px"},children:"Вы действительно хотите удалить свой аккаунт? Все ваши заметки, изображения, настройки и данные будут удалены навсегда."}),c.jsxs("div",{style:{marginBottom:"15px"},children:[c.jsx("label",{htmlFor:"deleteAccountPassword",style:{display:"block",marginBottom:"5px",fontWeight:"bold"},children:"Введите пароль для подтверждения:"}),c.jsx("input",{type:"password",id:"deleteAccountPassword",placeholder:"Пароль от аккаунта",className:"modal-password-input",value:y,onChange:z=>C(z.target.value),onKeyPress:z=>{z.key==="Enter"&&!j&&te()}})]})]}),confirmText:j?"Удаление...":"Удалить аккаунт",cancelText:"Отмена",confirmType:"danger"})]})},eT=()=>{const e=Kn(),t=ot(),{showNotification:n}=Tr(),[r,i]=x.useState("appearance"),[s,o]=x.useState("#007bff"),[l,a]=x.useState(""),[u,d]=x.useState(""),[f,p]=x.useState(""),[w,h]=x.useState(!1),[v,k]=x.useState([]),[g,m]=x.useState(!1),[y,C]=x.useState([]),[j,S]=x.useState(0),[N,_]=x.useState(!0),[D,M]=x.useState(""),[q,X]=x.useState(!1),[te,K]=x.useState(!1),[z,Q]=x.useState(""),[se,O]=x.useState(!1),b=50,P=[{color:"#007bff",title:"Синий"},{color:"#28a745",title:"Зеленый"},{color:"#dc3545",title:"Красный"},{color:"#fd7e14",title:"Оранжевый"},{color:"#6f42c1",title:"Фиолетовый"},{color:"#e83e8c",title:"Розовый"}];x.useEffect(()=>{L()},[]),x.useEffect(()=>{r==="archive"?xe():r==="logs"?_e(!0):r==="ai"&&$()},[r]);const L=async()=>{try{const R=await ct.getProfile();t(od(R));const V=R.accent_color||"#007bff";o(V),t(il(V)),Cs(V);try{const Y=await ct.getAiSettings();t(ld(Y))}catch(Y){console.error("Ошибка загрузки AI настроек:",Y)}}catch(R){console.error("Ошибка загрузки информации о пользователе:",R)}},$=async()=>{try{const R=await ct.getAiSettings();a(R.openai_api_key||""),d(R.openai_base_url||""),p(R.openai_model||""),h(R.ai_enabled===1),localStorage.setItem("ai_enabled",R.ai_enabled?"1":"0")}catch(R){console.error("Ошибка загрузки AI настроек:",R)}},H=async()=>{var R,V;try{await ct.updateProfile({accent_color:s}),t(il(s)),Cs(s),await L(),n("Цветовой акцент успешно обновлен","success")}catch(Y){console.error("Ошибка обновления цветового акцента:",Y),n(((V=(R=Y.response)==null?void 0:R.data)==null?void 0:V.error)||"Ошибка обновления","error")}},G=async()=>{var R,V;if(!l.trim()){n("API ключ обязателен","error");return}if(!u.trim()){n("Base URL обязателен","error");return}if(!f.trim()){n("Название модели обязательно","error");return}try{await ct.updateAiSettings({openai_api_key:l,openai_base_url:u,openai_model:f}),n("AI настройки успешно сохранены","success"),le()}catch(Y){console.error("Ошибка сохранения AI настроек:",Y),n(((V=(R=Y.response)==null?void 0:R.data)==null?void 0:V.error)||"Ошибка сохранения","error")}},J=async R=>{var V,Y;if(R&&!oe()){n("Сначала заполните все AI настройки","warning");return}try{await ct.updateAiSettings({ai_enabled:R?1:0}),h(R),localStorage.setItem("ai_enabled",R?"1":"0"),n(R?"Помощь ИИ включена":"Помощь ИИ отключена","success")}catch(de){console.error("Ошибка сохранения настройки AI:",de),n(((Y=(V=de.response)==null?void 0:V.data)==null?void 0:Y.error)||"Ошибка сохранения","error"),h(!R)}},oe=()=>l.trim()&&u.trim()&&f.trim(),le=()=>{oe()||h(!1)},xe=async()=>{m(!0);try{const R=await Ge.getArchived();k(R)}catch(R){console.error("Ошибка загрузки архивных заметок:",R),n("Ошибка загрузки архивных заметок","error")}finally{m(!1)}},ne=async R=>{var V,Y;try{await Ge.unarchive(R),await xe(),n("Заметка восстановлена!","success")}catch(de){console.error("Ошибка восстановления заметки:",de),n(((Y=(V=de.response)==null?void 0:V.data)==null?void 0:Y.error)||"Ошибка восстановления","error")}},Ae=async R=>{var V,Y;try{await Ge.deleteArchived(R),await xe(),n("Заметка удалена окончательно","success")}catch(de){console.error("Ошибка удаления заметки:",de),n(((Y=(V=de.response)==null?void 0:V.data)==null?void 0:Y.error)||"Ошибка удаления","error")}},Lt=async()=>{var R,V;if(!z.trim()){n("Введите пароль","warning");return}O(!0);try{await Ge.deleteAllArchived(z),n("Все архивные заметки удалены","success"),K(!1),Q(""),await xe()}catch(Y){console.error("Ошибка:",Y),n(((V=(R=Y.response)==null?void 0:R.data)==null?void 0:V.error)||"Ошибка удаления","error")}finally{O(!1)}},_e=x.useCallback(async(R=!1)=>{X(!0);try{const V=R?0:j,Y=await QN.getLogs({action_type:D||void 0,limit:b,offset:V});R?(C(Y),S(Y.length)):(C(de=>[...de,...Y]),S(de=>de+Y.length)),_(Y.length===b)}catch(V){console.error("Ошибка загрузки логов:",V),n("Ошибка загрузки логов","error")}finally{X(!1)}},[D,b,n,j]),Ce=R=>{M(R),S(0),_(!0)};x.useEffect(()=>{r==="logs"&&_e(!0)},[D,r,_e]);const Pe=R=>({login:"Вход",logout:"Выход",register:"Регистрация",note_create:"Создание заметки",note_update:"Редактирование",note_delete:"Удаление",note_pin:"Закрепление",note_archive:"Архивирование",note_unarchive:"Восстановление",note_delete_permanent:"Окончательное удаление",profile_update:"Обновление профиля",ai_improve:"Улучшение через AI"})[R]||R;return c.jsxs("div",{className:"container",children:[c.jsxs("header",{className:"notes-header",children:[c.jsxs("span",{children:[c.jsx(F,{icon:"mdi:cog"})," Настройки"]}),c.jsxs("div",{className:"user-info",children:[c.jsx(Ds,{}),c.jsx("button",{className:"notes-btn",onClick:()=>e("/notes"),title:"К заметкам",children:c.jsx(F,{icon:"mdi:note-text"})}),c.jsx("button",{className:"profile-btn",onClick:()=>e("/profile"),title:"Профиль",children:c.jsx(F,{icon:"mdi:account"})}),c.jsx("button",{className:"logout-btn",title:"Выйти",onClick:async()=>{try{await Sr.logout(),t(fr()),e("/")}catch(R){console.error("Ошибка выхода:",R),t(fr()),e("/")}},children:c.jsx(F,{icon:"mdi:logout"})})]})]}),c.jsxs("div",{className:"settings-tabs",children:[c.jsxs("button",{className:`settings-tab ${r==="appearance"?"active":""}`,onClick:()=>i("appearance"),children:[c.jsx(F,{icon:"mdi:palette"})," Внешний вид"]}),c.jsxs("button",{className:`settings-tab ${r==="ai"?"active":""}`,onClick:()=>i("ai"),children:[c.jsx(F,{icon:"mdi:robot"})," AI настройки"]}),c.jsxs("button",{className:`settings-tab ${r==="archive"?"active":""}`,onClick:()=>i("archive"),children:[c.jsx(F,{icon:"mdi:archive"})," Архив заметок"]}),c.jsxs("button",{className:`settings-tab ${r==="logs"?"active":""}`,onClick:()=>i("logs"),children:[c.jsx(F,{icon:"mdi:history"})," История действий"]})]}),c.jsxs("div",{className:"settings-content",children:[r==="appearance"&&c.jsxs("div",{className:"tab-content active",children:[c.jsx("h3",{children:"Внешний вид"}),c.jsxs("div",{className:"form-group",children:[c.jsx("label",{htmlFor:"settings-accentColor",children:"Цветовой акцент"}),c.jsx("div",{className:"accent-color-picker",children:P.map(R=>c.jsx("div",{className:`color-option ${s===R.color?"selected":""}`,"data-color":R.color,style:{backgroundColor:R.color},title:R.title,onClick:()=>o(R.color)},R.color))})]}),c.jsx("button",{className:"btnSave",onClick:H,children:"Сохранить изменения"})]}),r==="ai"&&c.jsxs("div",{className:"tab-content active",children:[c.jsx("h3",{children:"Настройки AI"}),c.jsx("div",{className:"form-group ai-toggle-group",children:c.jsxs("label",{className:`ai-toggle-label ${oe()?"":"disabled"}`,children:[c.jsxs("div",{className:"toggle-label-content",children:[c.jsx("span",{className:"toggle-text-main",children:"Включить помощь ИИ"}),c.jsx("span",{className:"toggle-text-desc",children:oe()?'Показывать кнопку "Помощь ИИ" в редакторах заметок':"Сначала заполните API Key, Base URL и Модель ниже"})]}),c.jsxs("div",{className:"toggle-switch-wrapper",children:[c.jsx("input",{type:"checkbox",id:"ai-enabled-toggle",className:"toggle-checkbox",checked:w,disabled:!oe(),onChange:R=>J(R.target.checked)}),c.jsx("span",{className:"toggle-slider"})]})]})}),c.jsxs("div",{className:"form-group",children:[c.jsx("label",{htmlFor:"openai-api-key",children:"OpenAI API Key"}),c.jsx("input",{type:"password",id:"openai-api-key",placeholder:"sk-...",className:"form-input",value:l,onChange:R=>{a(R.target.value),le()}}),c.jsx("p",{style:{color:"#666",fontSize:"12px",marginTop:"5px"},children:"Введите ваш OpenAI API ключ"})]}),c.jsxs("div",{className:"form-group",children:[c.jsx("label",{htmlFor:"openai-base-url",children:"OpenAI Base URL"}),c.jsx("input",{type:"text",id:"openai-base-url",placeholder:"https://api.openai.com/v1",className:"form-input",value:u,onChange:R=>{d(R.target.value),le()}}),c.jsx("p",{style:{color:"#666",fontSize:"12px",marginTop:"5px"},children:"URL для API запросов (например, https://api.openai.com/v1)"})]}),c.jsxs("div",{className:"form-group",children:[c.jsx("label",{htmlFor:"openai-model",children:"Модель"}),c.jsx("input",{type:"text",id:"openai-model",placeholder:"gpt-3.5-turbo",className:"form-input",value:f,onChange:R=>{p(R.target.value),le()}}),c.jsxs("p",{style:{color:"#666",fontSize:"12px",marginTop:"5px"},children:["Название модели (например, gpt-4, deepseek/deepseek-chat).",c.jsxs("a",{href:"https://openrouter.ai/models",target:"_blank",rel:"noopener noreferrer",style:{color:"var(--accent-color)"},children:[" ","Список доступных моделей"]})]})]}),c.jsx("button",{className:"btnSave",onClick:G,children:"Сохранить AI настройки"})]}),r==="archive"&&c.jsxs("div",{className:"tab-content active",children:[c.jsxs("div",{style:{display:"flex",justifyContent:"space-between",alignItems:"center",marginBottom:"10px"},children:[c.jsx("h3",{children:"Архивные заметки"}),c.jsxs("button",{className:"btn-danger",style:{fontSize:"14px",padding:"8px 16px"},onClick:()=>K(!0),children:[c.jsx(F,{icon:"mdi:delete-sweep"})," Удалить все"]})]}),c.jsx("p",{style:{color:"#666",fontSize:"14px",marginBottom:"20px"},children:"Архивированные заметки можно восстановить или удалить окончательно"}),c.jsx("div",{className:"archived-notes-list",children:g?c.jsx("p",{style:{textAlign:"center",color:"#999"},children:"Загрузка..."}):v.length===0?c.jsx("p",{style:{textAlign:"center",color:"#999"},children:"Архив пуст"}):v.map(R=>{const V=new Date(R.created_at.replace(" ","T")+"Z"),Y=new Intl.DateTimeFormat("ru-RU",{day:"2-digit",month:"2-digit",year:"numeric",hour:"2-digit",minute:"2-digit"}).format(V),de=_d(R.content),He=de.substring(0,200)+(de.length>200?"...":"");return c.jsxs("div",{className:"archived-note-item",children:[c.jsxs("div",{className:"archived-note-header",children:[c.jsx("span",{className:"archived-note-date",children:Y}),c.jsxs("div",{className:"archived-note-actions",children:[c.jsxs("button",{className:"btn-restore",onClick:()=>ne(R.id),title:"Восстановить",children:[c.jsx(F,{icon:"mdi:restore"})," Восстановить"]}),c.jsxs("button",{className:"btn-delete-permanent",onClick:()=>Ae(R.id),title:"Удалить навсегда",children:[c.jsx(F,{icon:"mdi:delete-forever"})," Удалить"]})]})]}),c.jsx("div",{className:"archived-note-content",dangerouslySetInnerHTML:{__html:He}}),R.images&&R.images.length>0&&c.jsxs("div",{className:"archived-note-images",children:[R.images.length," изображений"]})]},R.id)})})]}),r==="logs"&&c.jsxs("div",{className:"tab-content active",children:[c.jsx("h3",{children:"История действий"}),c.jsxs("div",{className:"logs-filters",children:[c.jsxs("select",{id:"logTypeFilter",className:"log-filter-select",value:D,onChange:R=>Ce(R.target.value),children:[c.jsx("option",{value:"",children:"Все действия"}),c.jsx("option",{value:"login",children:"Вход"}),c.jsx("option",{value:"logout",children:"Выход"}),c.jsx("option",{value:"register",children:"Регистрация"}),c.jsx("option",{value:"note_create",children:"Создание заметки"}),c.jsx("option",{value:"note_update",children:"Редактирование заметки"}),c.jsx("option",{value:"note_delete",children:"Удаление заметки"}),c.jsx("option",{value:"note_pin",children:"Закрепление"}),c.jsx("option",{value:"note_archive",children:"Архивирование"}),c.jsx("option",{value:"note_unarchive",children:"Восстановление"}),c.jsx("option",{value:"note_delete_permanent",children:"Окончательное удаление"}),c.jsx("option",{value:"profile_update",children:"Обновление профиля"}),c.jsx("option",{value:"ai_improve",children:"Улучшение через AI"})]}),c.jsxs("button",{className:"btnSave",onClick:()=>_e(!0),children:[c.jsx(F,{icon:"mdi:refresh"})," Обновить"]})]}),c.jsx("div",{className:"logs-table-container",children:c.jsxs("table",{className:"logs-table",children:[c.jsx("thead",{children:c.jsxs("tr",{children:[c.jsx("th",{children:"Дата и время"}),c.jsx("th",{children:"Действие"}),c.jsx("th",{children:"Детали"})]})}),c.jsx("tbody",{children:q&&y.length===0?c.jsx("tr",{children:c.jsx("td",{colSpan:3,style:{textAlign:"center"},children:"Загрузка..."})}):y.length===0?c.jsx("tr",{children:c.jsx("td",{colSpan:3,style:{textAlign:"center",color:"#999"},children:"Логов пока нет"})}):y.map(R=>{const V=new Date(R.created_at.replace(" ","T")+"Z"),Y=new Intl.DateTimeFormat("ru-RU",{day:"2-digit",month:"2-digit",year:"numeric",hour:"2-digit",minute:"2-digit",second:"2-digit"}).format(V);return c.jsxs("tr",{children:[c.jsx("td",{children:Y}),c.jsx("td",{children:c.jsx("span",{className:`log-action-badge log-action-${R.action_type}`,children:Pe(R.action_type)})}),c.jsx("td",{children:R.details||"-"})]},R.id)})})]})}),N&&y.length>0&&c.jsx("div",{className:"load-more-container",children:c.jsx("button",{className:"btnSave",onClick:()=>_e(!1),children:"Загрузить еще"})})]})]}),c.jsx(Pd,{isOpen:te,onClose:()=>{K(!1),Q("")},onConfirm:Lt,title:"Подтверждение удаления",message:c.jsxs(c.Fragment,{children:[c.jsx("p",{style:{color:"#dc3545",fontWeight:"bold",marginBottom:"15px"},children:"⚠️ ВНИМАНИЕ: Это действие нельзя отменить!"}),c.jsx("p",{style:{marginBottom:"20px"},children:"Вы действительно хотите удалить ВСЕ архивные заметки? Все заметки и их изображения будут удалены навсегда."}),c.jsxs("div",{style:{marginBottom:"15px"},children:[c.jsx("label",{htmlFor:"deleteAllPassword",style:{display:"block",marginBottom:"5px",fontWeight:"bold"},children:"Введите пароль для подтверждения:"}),c.jsx("input",{type:"password",id:"deleteAllPassword",placeholder:"Пароль от аккаунта",className:"modal-password-input",value:z,onChange:R=>Q(R.target.value),onKeyPress:R=>{R.key==="Enter"&&!se&&Lt()}})]})]}),confirmText:se?"Удаление...":"Удалить все",cancelText:"Отмена",confirmType:"danger"})]})},tT=()=>{const e=ye(n=>n.ui.notifications),t=ot();return c.jsx("div",{className:"notification-stack",children:e.map((n,r)=>c.jsx(nT,{notification:n,index:r,onRemove:()=>t($g(n.id))},n.id))})},nT=({notification:e,index:t,onRemove:n})=>{const[r,i]=x.useState(!1);x.useEffect(()=>{setTimeout(()=>i(!0),100)},[]),x.useEffect(()=>{const o=setTimeout(()=>{s()},4e3);return()=>clearTimeout(o)},[]);const s=()=>{i(!1),setTimeout(n,300)};return c.jsx("div",{className:`notification notification-${e.type} ${r?"visible":""}`,style:{top:`${20+t*70}px`},onClick:s,children:e.message})},rT=()=>c.jsx("div",{className:"loading-overlay",children:c.jsx("div",{className:"loading-content",children:c.jsx("div",{className:"loading-text",children:"Загрузка..."})})}),Da=({children:e})=>{const t=ye(s=>s.auth.isAuthenticated),n=ot(),[r,i]=x.useState(!0);return x.useEffect(()=>{t?(async()=>{try{const o=await Sr.checkStatus();o.authenticated?n(sd({userId:o.userId,username:o.username})):n(fr())}catch{n(fr())}finally{i(!1)}})():i(!1)},[n,t]),r?c.jsx(rT,{}):t?c.jsx(c.Fragment,{children:e}):c.jsx(yg,{to:"/",replace:!0})},iT=()=>{const[e,t]=x.useState(null),[n,r]=x.useState(!1),[i,s]=x.useState(!1);x.useEffect(()=>{if(window.matchMedia("(display-mode: standalone)").matches||window.navigator.standalone===!0){s(!0);return}const a=localStorage.getItem("pwa-install-dismissed");if(a){const f=parseInt(a,10);if((Date.now()-f)/(1e3*60*60*24)<7)return}const u=f=>{f.preventDefault(),t(f),setTimeout(()=>r(!0),3e3)},d=()=>{s(!0),r(!1),t(null)};return window.addEventListener("beforeinstallprompt",u),window.addEventListener("appinstalled",d),()=>{window.removeEventListener("beforeinstallprompt",u),window.removeEventListener("appinstalled",d)}},[]);const o=async()=>{if(!e)return;e.prompt();const{outcome:a}=await e.userChoice;a==="accepted"&&(r(!1),s(!0)),t(null)},l=()=>{r(!1),localStorage.setItem("pwa-install-dismissed",Date.now().toString())};return i||!n||!e?null:c.jsxs("div",{className:"pwa-install-prompt",children:[c.jsxs("div",{className:"pwa-install-prompt-content",children:[c.jsx("div",{className:"pwa-install-prompt-icon",children:c.jsx(F,{icon:"mdi:download",width:32,height:32})}),c.jsxs("div",{className:"pwa-install-prompt-text",children:[c.jsx("h3",{children:"Установить NoteJS"}),c.jsx("p",{children:"Установите приложение для быстрого доступа и работы офлайн"})]}),c.jsxs("div",{className:"pwa-install-prompt-actions",children:[c.jsx("button",{className:"pwa-install-btn-primary",onClick:o,children:"Установить"}),c.jsx("button",{className:"pwa-install-btn-secondary",onClick:l,"aria-label":"Закрыть",children:c.jsx(F,{icon:"mdi:close",width:20,height:20})})]})]}),c.jsx("style",{children:` + .pwa-install-prompt { + position: fixed; + bottom: 20px; + left: 50%; + transform: translateX(-50%); + z-index: 10000; + max-width: 400px; + width: calc(100% - 40px); + animation: slideUp 0.3s ease-out; + } + + @keyframes slideUp { + from { + transform: translateX(-50%) translateY(100%); + opacity: 0; + } + to { + transform: translateX(-50%) translateY(0); + opacity: 1; + } + } + + .pwa-install-prompt-content { + background: var(--bg-primary); + border: 1px solid var(--border-primary); + border-radius: 12px; + padding: 16px; + box-shadow: 0 4px 20px var(--shadow-light); + display: flex; + align-items: center; + gap: 12px; + } + + .pwa-install-prompt-icon { + color: var(--accent-color); + flex-shrink: 0; + } + + .pwa-install-prompt-text { + flex: 1; + min-width: 0; + } + + .pwa-install-prompt-text h3 { + margin: 0 0 4px 0; + font-size: 16px; + font-weight: 600; + color: var(--text-primary); + } + + .pwa-install-prompt-text p { + margin: 0; + font-size: 13px; + color: var(--text-primary); + opacity: 0.8; + } + + .pwa-install-prompt-actions { + display: flex; + align-items: center; + gap: 8px; + flex-shrink: 0; + } + + .pwa-install-btn-primary { + background: var(--accent-color); + color: white; + border: none; + border-radius: 8px; + padding: 8px 16px; + font-size: 14px; + font-weight: 500; + cursor: pointer; + transition: opacity 0.2s; + } + + .pwa-install-btn-primary:hover { + opacity: 0.9; + } + + .pwa-install-btn-primary:active { + opacity: 0.8; + } + + .pwa-install-btn-secondary { + background: transparent; + color: var(--text-primary); + border: none; + padding: 4px; + cursor: pointer; + border-radius: 4px; + display: flex; + align-items: center; + justify-content: center; + transition: background 0.2s; + } + + .pwa-install-btn-secondary:hover { + background: var(--border-primary); + } + + @media (max-width: 480px) { + .pwa-install-prompt-content { + flex-direction: column; + text-align: center; + } + + .pwa-install-prompt-actions { + width: 100%; + justify-content: center; + } + + .pwa-install-btn-primary { + flex: 1; + } + } + `})]})},sT=()=>(Tv(),c.jsxs(c.Fragment,{children:[c.jsx(tT,{}),c.jsx(iT,{}),c.jsx($x,{children:c.jsxs(Px,{children:[c.jsx(rr,{path:"/",element:c.jsx(QE,{})}),c.jsx(rr,{path:"/register",element:c.jsx(qE,{})}),c.jsx(rr,{path:"/notes",element:c.jsx(Da,{children:c.jsx(JN,{})})}),c.jsx(rr,{path:"/profile",element:c.jsx(Da,{children:c.jsx(ZN,{})})}),c.jsx(rr,{path:"/settings",element:c.jsx(Da,{children:c.jsx(eT,{})})}),c.jsx(rr,{path:"*",element:c.jsx(yg,{to:"/",replace:!0})})]})})]})),oT=()=>c.jsx(ak,{store:p1,children:c.jsx(sT,{})}),lT="modulepreload",aT=function(e){return"/"+e},Yp={},uT=function(t,n,r){let i=Promise.resolve();if(n&&n.length>0){document.getElementsByTagName("link");const o=document.querySelector("meta[property=csp-nonce]"),l=(o==null?void 0:o.nonce)||(o==null?void 0:o.getAttribute("nonce"));i=Promise.allSettled(n.map(a=>{if(a=aT(a),a in Yp)return;Yp[a]=!0;const u=a.endsWith(".css"),d=u?'[rel="stylesheet"]':"";if(document.querySelector(`link[href="${a}"]${d}`))return;const f=document.createElement("link");if(f.rel=u?"stylesheet":lT,u||(f.as="script"),f.crossOrigin="",f.href=a,l&&f.setAttribute("nonce",l),document.head.appendChild(f),u)return new Promise((p,w)=>{f.addEventListener("load",p),f.addEventListener("error",()=>w(new Error(`Unable to preload CSS for ${a}`)))})}))}function s(o){const l=new Event("vite:preloadError",{cancelable:!0});if(l.payload=o,window.dispatchEvent(l),!l.defaultPrevented)throw o}return i.then(o=>{for(const l of o||[])l.status==="rejected"&&s(l.reason);return t().catch(s)})};function cT(e={}){const{immediate:t=!1,onNeedRefresh:n,onOfflineReady:r,onRegistered:i,onRegisteredSW:s,onRegisterError:o}=e;let l,a,u;const d=async(p=!0)=>{await a,await(u==null?void 0:u())};async function f(){if("serviceWorker"in navigator){if(l=await uT(async()=>{const{Workbox:p}=await import("./workbox-window.prod.es5-B9K5rw8f.js");return{Workbox:p}},[]).then(({Workbox:p})=>new p("/sw.js",{scope:"/",type:"classic"})).catch(p=>{o==null||o(p)}),!l)return;u=async()=>{await(l==null?void 0:l.messageSkipWaiting())};{let p=!1;const w=()=>{p=!0,l==null||l.addEventListener("controlling",h=>{h.isUpdate&&window.location.reload()}),n==null||n()};l.addEventListener("installed",h=>{typeof h.isUpdate>"u"?typeof h.isExternal<"u"?h.isExternal?w():!p&&(r==null||r()):h.isExternal?window.location.reload():!p&&(r==null||r()):h.isUpdate||r==null||r()}),l.addEventListener("waiting",w),l.addEventListener("externalwaiting",w)}l.register({immediate:t}).then(p=>{s?s("/sw.js",p):i==null||i(p)}).catch(p=>{o==null||o(p)})}}return a=f(),d}"serviceWorker"in navigator&&cT({onNeedRefresh(){console.log("Доступно новое обновление приложения")},onOfflineReady(){console.log("Приложение готово к работе офлайн")}})();Aa.createRoot(document.getElementById("root")).render(c.jsx(Jt.StrictMode,{children:c.jsx(oT,{})})); diff --git a/backend/public/assets/index-QEK5TGz3.css b/backend/public/assets/index-QEK5TGz3.css new file mode 100644 index 0000000..d3cf2c1 --- /dev/null +++ b/backend/public/assets/index-QEK5TGz3.css @@ -0,0 +1 @@ +body{font-family:-apple-system,BlinkMacSystemFont,Segoe UI,Roboto,Oxygen,Ubuntu,Cantarell,Fira Sans,Droid Sans,Helvetica Neue,sans-serif;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale}code{font-family:source-code-pro,Menlo,Monaco,Consolas,Courier New,monospace}:root{--accent-color: #007bff}[data-theme=light]{--bg-color: #ffffff;--text-color: #333333;--border-color: #e0e0e0;--shadow: rgba(0, 0, 0, .1)}[data-theme=dark]{--bg-color: #1a1a1a;--text-color: #e0e0e0;--border-color: #333333;--shadow: rgba(0, 0, 0, .5)}body{background-color:var(--bg-color);color:var(--text-color)}:root{--accent-color: #007bff;--accent-color-rgb: 0, 123, 255;--bg-primary: #f5f5f5;--bg-secondary: #ffffff;--bg-tertiary: #f8f9fa;--bg-quaternary: #e9ecef;--bg-hover: #e7f3ff;--text-primary: #333333;--text-secondary: #666666;--text-muted: #999999;--text-light: #757575;--border-primary: #e0e0e0;--border-secondary: #dddddd;--border-focus: var(--accent-color);--shadow-light: rgba(0, 0, 0, .1);--shadow-medium: rgba(0, 0, 0, .15);--icon-search: #2196f3;--icon-tags: #4caf50;--icon-notes: #ff9800;--icon-user: #9c27b0;--icon-danger: #dc3545}[data-theme=dark]{--bg-primary: #1a1a1a;--bg-secondary: #2d2d2d;--bg-tertiary: #3a3a3a;--bg-quaternary: #4a4a4a;--bg-hover: #2a4a6b;--text-primary: #ffffff;--text-secondary: #cccccc;--text-muted: #999999;--text-light: #aaaaaa;--border-primary: #404040;--border-secondary: #555555;--border-focus: var(--accent-color);--shadow-light: rgba(0, 0, 0, .3);--shadow-medium: rgba(0, 0, 0, .4);--icon-search: #64b5f6;--icon-tags: #81c784;--icon-notes: #ffb74d;--icon-user: #ba68c8;--icon-danger: #f44336}*{margin:0;padding:0;box-sizing:border-box}body{font-family:Open Sans,sans-serif;margin:0;background:var(--bg-primary);color:var(--text-primary);display:flex;flex-direction:row;justify-content:center;align-items:flex-start;gap:30px;padding:0 15px;transition:background-color .3s ease,color .3s ease}#root{display:contents}.notification-stack{position:fixed;top:0;left:0;right:0;z-index:10000;pointer-events:none}.notification-stack .notification{pointer-events:all}.iconify{font-size:16px;vertical-align:middle;display:inline-block;width:1em;height:1em}button{-webkit-tap-highlight-color:transparent;-moz-tap-highlight-color:transparent;tap-highlight-color:transparent;outline:none;box-shadow:none}button:focus,button:active{outline:none;box-shadow:none}input[type=button],input[type=submit],input[type=reset],a,div[role=button]{-webkit-tap-highlight-color:transparent;-moz-tap-highlight-color:transparent;tap-highlight-color:transparent;outline:none;box-shadow:none}input[type=button]:focus,input[type=submit]:focus,input[type=reset]:focus,a:focus,div[role=button]:focus,input[type=button]:active,input[type=submit]:active,input[type=reset]:active,a:active,div[role=button]:active{outline:none;box-shadow:none}iconify-icon{font-size:16px;vertical-align:middle;display:inline-block;width:1em;height:1em}header .iconify{font-size:20px;margin-right:8px}.search-title .iconify,.tags-title .iconify{font-size:14px;margin-right:6px}.search-title .iconify[data-icon="mdi:magnify"]{color:var(--icon-search)}.tags-title .iconify[data-icon="mdi:tag"]{color:var(--icon-tags)}header .iconify[data-icon="mdi:note-text"]{color:var(--icon-notes)}header .iconify[data-icon="mdi:account"],.username-clickable .iconify[data-icon="mdi:account"]{color:var(--icon-user)}.theme-toggle-btn{width:40px;height:40px;border-radius:50%;border:none;background:var(--bg-secondary);color:var(--text-secondary);cursor:pointer;font-size:18px;transition:all .3s ease;display:flex;align-items:center;justify-content:center;flex-shrink:0}.theme-toggle-btn:hover{background-color:var(--accent-color, #007bff);color:#fff;transform:scale(1.1)}.theme-toggle-btn .iconify{font-size:18px;color:var(--text-secondary);transition:color .3s ease;margin:0}.theme-toggle-btn:hover .iconify{color:#fff}header .iconify[data-icon="mdi:login"]{color:#2196f3}header .iconify[data-icon="mdi:account-plus"]{color:#4caf50}.btnMarkdown .iconify[data-icon="mdi:format-bold"]{color:#d32f2f}.btnMarkdown .iconify[data-icon="mdi:format-italic"]{color:#f57c00}.btnMarkdown .iconify[data-icon="mdi:palette"]{color:#e91e63}.btnMarkdown .iconify[data-icon="mdi:format-header-1"],.btnMarkdown .iconify[data-icon="mdi:format-header-pound"]{color:#1976d2}.btnMarkdown .iconify[data-icon="mdi:format-list-bulleted"]{color:#388e3c}.btnMarkdown .iconify[data-icon="mdi:format-quote-close"]{color:#f57c00}.btnMarkdown .iconify[data-icon="mdi:code-tags"]{color:#7b1fa2}.btnMarkdown .iconify[data-icon="mdi:link"]{color:#0288d1}.btnMarkdown .iconify[data-icon="mdi:format-strikethrough"]{color:#ff6f00}.btnMarkdown .iconify[data-icon="mdi:format-list-numbered"]{color:#4caf50}.btnMarkdown .iconify[data-icon="mdi:checkbox-marked-outline"]{color:#ff9800}.btnMarkdown .iconify[data-icon="mdi:image-plus"]{color:#2196f3}.btnMarkdown .iconify[data-icon="mdi:eye"]{color:#607d8b}.btnMarkdown .iconify[data-icon="mdi:file-plus"]{color:#9c27b0}.btnMarkdown .iconify[data-icon="mdi:eye-off"]{color:#e91e63}.btnMarkdown .iconify[data-icon="mdi:robot"]{color:#ff6f00}.notesHeaderBtn .iconify[data-icon="mdi:pencil"]{color:#2196f3}.notesHeaderBtn .iconify[data-icon="mdi:delete"]{color:#dc3545}header{font-size:20px;font-weight:700}.notes-header{display:flex;justify-content:space-between;align-items:flex-start;width:100%;box-sizing:border-box}.notes-header-left{display:flex;flex-direction:column;align-items:flex-start;flex:1;min-width:0}.search-section{margin-top:15px;padding-top:15px;border-top:1px solid var(--border-primary)}.search-header{margin-bottom:10px}.search-title{font-size:12px;font-weight:700;color:var(--text-primary)}.search-container{position:relative;width:100%}.search-input{width:100%;padding:6px 30px 6px 10px;border:1px solid var(--border-secondary);border-radius:15px;font-size:12px;background-color:var(--bg-tertiary);color:var(--text-primary);transition:all .3s ease;box-sizing:border-box}.search-input:focus{outline:none;border-color:var(--border-focus);background-color:var(--bg-secondary);box-shadow:0 0 0 2px rgba(var(--accent-color-rgb),.25)}.clear-search-btn{position:absolute;right:6px;top:50%;transform:translateY(-50%);background:none;border:none;color:#999;cursor:pointer;font-size:14px;padding:2px 4px;border-radius:50%;transition:all .2s ease}.clear-search-btn:hover{background-color:var(--bg-quaternary);color:var(--text-secondary)}.filter-indicator{display:inline-flex;align-items:center;margin-top:15px;padding:4px 10px;background-color:rgba(var(--accent-color-rgb),.1);border:1px solid rgba(var(--accent-color-rgb),.3);border-radius:15px;font-size:12px;color:var(--accent-color);font-weight:500;max-width:min(300px,100%);box-sizing:border-box}.filter-indicator-text{flex:1;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;min-width:0}.filter-indicator button{background:none;border:none;color:var(--icon-danger);cursor:pointer;margin-left:8px;font-weight:700;padding:2px 4px;font-size:14px;border-radius:3px;min-width:20px;min-height:20px;display:flex;align-items:center;justify-content:center;transition:all .2s ease}.filter-indicator button:hover{color:#ff6b6b;background-color:#ff6b6b1a}.user-info{display:flex;align-items:center;gap:15px;flex-shrink:0}.user-info span{font-size:14px;color:#666;font-weight:500}.user-avatar-mini{width:40px;height:40px;border-radius:50%;overflow:hidden;cursor:pointer;transition:all .3s ease;border:2px solid var(--accent-color, #007bff);flex-shrink:0}.user-avatar-mini:hover{transform:scale(1.05);box-shadow:0 0 0 3px rgba(var(--accent-color-rgb),.2)}.user-avatar-mini img{width:100%;height:100%;object-fit:cover}.user-avatar-placeholder-mini{display:flex;align-items:center;justify-content:center;background:#e0e0e0;color:#999;font-size:24px}.user-avatar-placeholder-mini .iconify{margin:0;padding:0;line-height:1;vertical-align:baseline}.settings-icon-btn{width:40px;height:40px;border-radius:50%;border:none;background:var(--bg-secondary);color:var(--text-secondary);cursor:pointer;font-size:18px;transition:all .3s ease;display:flex;align-items:center;justify-content:center;flex-shrink:0}.settings-icon-btn:hover{background-color:var(--accent-color, #007bff);color:#fff;transform:scale(1.1)}.settings-icon-btn .iconify{font-size:18px;color:var(--text-secondary);transition:color .3s ease;margin:0}.settings-icon-btn:hover .iconify{color:#fff}.logout-btn{width:40px;height:40px;border-radius:50%;border:none;background:var(--bg-secondary);color:var(--text-secondary);cursor:pointer;display:flex;align-items:center;justify-content:center;transition:all .3s ease;flex-shrink:0}.logout-btn:hover{background-color:#dc3545}.logout-btn .iconify{font-size:20px;color:#dc3545;transition:color .3s ease;margin:0;padding:0;line-height:1;vertical-align:baseline}.logout-btn:hover .iconify{color:#fff}.notes-btn{width:40px;height:40px;border-radius:50%;border:none;background:var(--bg-secondary);color:var(--text-secondary);cursor:pointer;display:flex;align-items:center;justify-content:center;transition:all .3s ease;flex-shrink:0}.notes-btn:hover{background-color:var(--accent-color, #007bff)}.notes-btn .iconify{font-size:20px;color:#666;transition:color .3s ease;margin:0;padding:0;line-height:1;vertical-align:baseline}.notes-btn:hover .iconify{color:#fff}.settings-btn{width:40px;height:40px;border-radius:50%;border:none;background:var(--bg-secondary);color:var(--text-secondary);cursor:pointer;display:flex;align-items:center;justify-content:center;transition:all .3s ease;flex-shrink:0}.settings-btn:hover{background-color:var(--accent-color, #007bff)}.settings-btn .iconify{font-size:20px;color:#666;transition:color .3s ease;margin:0;padding:0;line-height:1;vertical-align:baseline}.settings-btn:hover .iconify{color:#fff}.profile-btn{width:40px;height:40px;border-radius:50%;border:none;background:var(--bg-secondary);color:var(--text-secondary);cursor:pointer;display:flex;align-items:center;justify-content:center;transition:all .3s ease;flex-shrink:0}.profile-btn:hover{background-color:var(--accent-color, #007bff)}.profile-btn .iconify{font-size:20px;color:#666;transition:color .3s ease;margin:0;padding:0;line-height:1;vertical-align:baseline}.profile-btn:hover .iconify{color:#fff}.auth-link{text-align:center;margin-top:15px;font-size:14px}.auth-link a{color:var(--accent-color, #007bff);text-decoration:none;font-weight:500}.auth-link a:hover{text-decoration:underline}.container{width:90%;max-width:600px;box-shadow:0 0 10px var(--shadow-light);border-radius:8px;padding:15px;margin-top:20px;background:var(--bg-secondary);color:var(--text-primary);box-sizing:border-box;word-wrap:break-word;overflow-wrap:break-word;overflow:visible;transition:background-color .3s ease,color .3s ease,box-shadow .3s ease}.notes-container .container{margin-top:0}.notes-container{margin-top:8px}.empty-message{text-align:center;color:#999;margin-top:50px;word-break:break-word;overflow-wrap:break-word;max-width:100%;padding:0 20px;box-sizing:border-box}.login-form{margin-top:20px}.form-group{margin-bottom:15px}.form-group label{display:block;margin-bottom:5px;font-weight:700;color:var(--text-primary)}.form-group input{width:100%;padding:10px;border:1px solid var(--border-secondary);border-radius:5px;font-size:16px;background-color:var(--bg-tertiary);color:var(--text-primary);box-sizing:border-box;transition:all .3s ease}.form-group input:focus{outline:none;border-color:var(--border-focus);background-color:var(--bg-secondary);box-shadow:0 0 0 2px rgba(var(--accent-color-rgb),.25)}.ai-toggle-group{margin-bottom:20px}.ai-toggle-label{display:flex;align-items:center;justify-content:space-between;cursor:pointer;-webkit-user-select:none;user-select:none;font-weight:400!important;margin-bottom:0!important;padding:16px 20px;background-color:var(--bg-tertiary);border:1px solid var(--border-secondary);border-radius:8px;transition:all .3s ease}.ai-toggle-label:hover{background-color:var(--bg-secondary);border-color:var(--accent-color)}.ai-toggle-label.disabled{opacity:.6;cursor:not-allowed;background-color:var(--bg-secondary)}.ai-toggle-label.disabled:hover{background-color:var(--bg-secondary);border-color:var(--border-secondary)}.ai-toggle-label.disabled .toggle-text-main{color:var(--text-secondary)}.ai-toggle-label.disabled .toggle-text-desc{color:#e67e22;font-weight:500}.ai-toggle-label.disabled .toggle-slider{background-color:#999;cursor:not-allowed}.ai-toggle-label.disabled .toggle-slider:before{background-color:#ddd}.toggle-label-content{display:flex;flex-direction:column;gap:4px;flex:1;min-width:0}.toggle-text-main{color:var(--text-primary);font-size:15px;font-weight:500}.toggle-text-desc{color:var(--text-secondary);font-size:12px;line-height:1.4}.toggle-switch-wrapper{flex-shrink:0;margin-left:20px;position:relative}.toggle-checkbox{display:none}.toggle-slider{position:relative;display:block;width:50px;height:26px;background-color:#ccc;border-radius:26px;transition:background-color .3s ease;box-shadow:inset 0 1px 3px #0003}.toggle-slider:before{content:"";position:absolute;width:22px;height:22px;border-radius:50%;background-color:#fff;top:2px;left:2px;transition:transform .3s ease;box-shadow:0 2px 4px #0003}.toggle-checkbox:checked+.toggle-slider{background-color:var(--accent-color, #007bff);box-shadow:inset 0 1px 3px #0000004d}.toggle-checkbox:checked+.toggle-slider:before{transform:translate(24px)}.error-message{color:var(--icon-danger);margin-top:10px;padding:10px;background-color:#dc35451a;border:1px solid rgba(220,53,69,.3);border-radius:5px}textarea{width:100%;min-height:50px;resize:none;border:none;background:var(--bg-secondary);color:var(--text-primary);margin-bottom:5px;overflow-y:hidden;transition:background-color .3s ease,color .3s ease;-webkit-user-select:text;-moz-user-select:text;-ms-user-select:text;user-select:text}textarea:focus{outline:none}.save-button-container{display:flex;flex-direction:column;gap:10px}.action-buttons{display:flex;align-items:center;gap:10px}.btnAI{background:linear-gradient(135deg,#667eea,#764ba2);color:#fff;display:flex;align-items:center;gap:6px}.btnAI:hover{background:linear-gradient(135deg,#5568d3,#5a3f7d);transform:translateY(-2px)}.btnAI:active{transform:translateY(0)}.btnAI .iconify{font-size:18px}.save-hint{font-size:12px;color:#999;font-style:italic}.btnSave{padding:10px 20px;cursor:pointer;border-width:1px;background:var(--bg-secondary);color:var(--text-primary);border:1px solid var(--border-secondary);border-radius:5px;font-family:Open Sans,sans-serif;transition:all .3s ease;font-size:16px}.btnSave:hover{background-color:var(--accent-color, #007bff);color:#fff;border-color:var(--accent-color, #007bff)}.date{font-size:11px;color:gray;display:flex;align-items:center;justify-content:space-between;gap:10px;flex-wrap:wrap}.date .date-text{flex:1;overflow:hidden;text-overflow:ellipsis;display:flex;align-items:center;gap:4px;flex-wrap:wrap}.date-separator{color:#999;font-weight:400;margin:0 2px}.note-actions{display:flex;align-items:center;gap:4px;flex-wrap:wrap}.notesHeaderBtn{display:inline-flex;align-items:center;justify-content:center;gap:4px;cursor:pointer;color:var(--text-primary);font-weight:700;white-space:nowrap;padding:2px 4px;border-radius:4px;transition:all .2s ease;font-size:10px}.notesHeaderBtn:hover{background:var(--bg-quaternary)}#pinBtn:hover{background:#ffc10733;color:#ffc107}#archiveBtn:hover{background:var(--bg-quaternary);color:var(--text-primary)}#editBtn:hover{background:#0dcaf033;color:#0dcaf0}#deleteBtn:hover{background:#dc354533;color:var(--icon-danger)}.textNote{margin-top:10px;white-space:pre-wrap;position:relative;transition:max-height .3s ease;word-wrap:break-word;overflow-wrap:break-word;word-break:break-word}.textNote.collapsed{max-height:300px;overflow:hidden}.textNote.collapsed:after{content:"";position:absolute;bottom:0;left:0;right:0;height:80px;background:linear-gradient(to bottom,transparent,var(--bg-secondary));pointer-events:none}.show-more-btn{display:flex;align-items:center;justify-content:center;width:100%;margin-top:10px;padding:8px;background-color:var(--bg-tertiary);border:1px solid var(--border-secondary);border-radius:5px;color:var(--accent-color, #007bff);font-size:14px;cursor:pointer;transition:all .3s ease;text-align:center;gap:5px}.show-more-btn:hover{background-color:var(--accent-color, #007bff);color:#fff;border-color:var(--accent-color, #007bff)}.textNote p{margin:0;padding:0;word-wrap:break-word;overflow-wrap:break-word}.textNote h1,.textNote h2,.textNote h3,.textNote h4,.textNote h5,.textNote h6{margin:0;padding:0;word-wrap:break-word;overflow-wrap:break-word;word-break:break-word}.textNote ul,.textNote ol{margin:0;padding-left:20px;word-wrap:break-word;overflow-wrap:break-word;line-height:.5}.textNote li{margin:0;padding:0;line-height:1;word-wrap:break-word;overflow-wrap:break-word}.textNote a{color:var(--accent-color, #007bff);text-decoration:none;word-wrap:break-word;overflow-wrap:break-word}.textNote a.external-link{position:relative;padding-right:16px}.textNote a.external-link:after{content:"↗";position:absolute;right:0;top:0;font-size:.8em;opacity:.7;transition:opacity .3s ease}.textNote a.external-link:hover:after{opacity:1}.textNote a:hover{text-decoration:underline}.textNote blockquote{border-left:4px solid var(--accent-color, #007bff);margin:10px 0;color:var(--text-secondary);font-style:italic;background-color:var(--bg-tertiary);padding:10px 16px;border-radius:0 4px 4px 0;word-wrap:break-word;overflow-wrap:break-word}.textNote blockquote p{margin:0}.textNote pre{background-color:var(--bg-tertiary);color:var(--text-primary);padding:10px;border-radius:5px;font-size:14px;overflow-x:auto;word-wrap:break-word;overflow-wrap:break-word;white-space:pre-wrap}.textNote code{background-color:var(--bg-tertiary);color:var(--text-primary);padding:2px 4px;border-radius:5px;font-size:14px;word-wrap:break-word;overflow-wrap:break-word;word-break:break-word}.textNote input[type=checkbox]{cursor:pointer;margin-right:8px;width:18px;height:18px;accent-color:var(--accent-color, #007bff);vertical-align:middle;position:relative;top:-1px}.textNote .task-list-item{list-style-type:none;margin-left:-20px;padding:0;line-height:1.5;transition:all .3s ease}.textNote .task-list-item:has(input[type=checkbox]:checked){opacity:.65;text-decoration:line-through;color:#999}.textNote .task-list-item input[type=checkbox]:checked~*{text-decoration:line-through;color:#999}.textNote .task-list-item:has(input[type=checkbox]:checked) *{text-decoration:line-through;color:#999}.textNote input[type=checkbox]:checked{text-decoration:none}.textNote input[type=checkbox]:checked+*{text-decoration:line-through;color:#999}.textNote .task-list-item:hover{background-color:rgba(var(--accent-color-rgb),.05);border-radius:4px;padding-left:4px;margin-left:-24px}.textNote li:has(input[type=checkbox]){list-style-type:none;margin-left:-20px;padding:0;line-height:1.5;transition:all .3s ease}.textNote li:has(input[type=checkbox]:checked){opacity:.65;text-decoration:line-through;color:#999}.textNote li:has(input[type=checkbox]) input[type=checkbox]:checked{text-decoration:none}.textNote li:has(input[type=checkbox]:checked) label,.textNote li:has(input[type=checkbox]:checked) span,.textNote li:has(input[type=checkbox]:checked) p{text-decoration:line-through;color:#999}.textNote li:has(input[type=checkbox]:checked) *{text-decoration:line-through;color:#999}.textNote li:has(input[type=checkbox]):hover{background-color:rgba(var(--accent-color-rgb),.05);border-radius:4px;padding-left:4px;margin-left:-24px}.notes-container{width:100%;display:flex;flex-direction:column;align-items:center;padding-bottom:60px;margin-top:16px;gap:16px;word-wrap:break-word;overflow-wrap:break-word}#notesList{width:100%;display:flex;flex-direction:column;align-items:center}.markdown-buttons{margin-top:10px;margin-bottom:10px;overflow-x:auto;overflow-y:hidden;position:relative;display:flex;flex-wrap:nowrap;gap:8px;align-items:center;scrollbar-width:none}.markdown-buttons::-webkit-scrollbar{display:none}.markdown-buttons.markdown-buttons--edit{display:flex;flex-wrap:nowrap;gap:8px;overflow-x:auto;overflow-y:hidden;scrollbar-width:none}.markdown-buttons.markdown-buttons--edit::-webkit-scrollbar{display:none}.markdown-buttons.markdown-buttons--edit .btnMarkdown{padding:5px 10px;margin-right:0;border:none;background-color:transparent;color:var(--text-primary);border-radius:4px;font-size:14px;touch-action:manipulation;-webkit-tap-highlight-color:transparent;user-select:none;-webkit-user-select:none;min-height:44px;display:inline-flex;align-items:center;justify-content:center;transition:all .3s ease}.markdown-buttons.markdown-buttons--edit .btnMarkdown:hover{background-color:var(--bg-quaternary)}@media (max-width: 768px){.markdown-buttons.markdown-buttons--edit .btnMarkdown{min-height:48px;padding:8px 12px;margin:0}}.markdown-buttons .btnMarkdown{padding:5px 10px;margin-right:0;cursor:pointer;border:none;background-color:transparent;color:var(--text-primary);border-radius:4px;font-size:14px;touch-action:manipulation;-webkit-tap-highlight-color:transparent;user-select:none;-webkit-user-select:none;min-height:44px;display:inline-flex;align-items:center;justify-content:center;transition:all .3s ease}.markdown-buttons .btnMarkdown:hover{background-color:var(--bg-quaternary)}.btnMarkdown.active{background-color:var(--accent-color);color:#fff}.btnMarkdown.active .iconify{color:#fff!important}.header-dropdown{position:relative;display:inline-block;overflow:visible;z-index:1}.header-dropdown-menu{display:block;position:fixed;background:var(--bg-secondary);border:1px solid var(--border-secondary);border-radius:5px;box-shadow:0 2px 8px var(--shadow-medium);z-index:1001;min-width:60px;max-width:120px}.header-dropdown-menu button{display:block;width:100%;padding:8px 16px;border:none;background:none;text-align:left;cursor:pointer;font-size:14px;font-weight:500;color:var(--text-primary);transition:background .2s ease}.header-dropdown-menu button:hover{background:var(--bg-quaternary)}.header-dropdown-menu button:first-child{border-radius:5px 5px 0 0}.header-dropdown-menu button:last-child{border-radius:0 0 5px 5px}.floating-toolbar-wrapper{overflow-x:auto;overflow-y:hidden;scrollbar-width:none;scroll-behavior:smooth;max-width:calc(100vw - 20px)}.floating-toolbar-wrapper::-webkit-scrollbar{display:none}.floating-toolbar{display:flex;gap:4px;background-color:var(--bg-secondary);border:1px solid var(--border-secondary);border-radius:8px;padding:6px;box-shadow:0 4px 12px #00000026;animation:fadeIn .2s ease-out;align-items:center;flex-shrink:0;min-width:fit-content;width:max-content}@keyframes fadeIn{0%{opacity:0;transform:translateY(-5px)}to{opacity:1;transform:translateY(0)}}.floating-toolbar-btn{padding:6px 10px;border:none;background-color:transparent;color:var(--text-primary);border-radius:4px;cursor:pointer;font-size:16px;display:flex;align-items:center;justify-content:center;transition:all .2s ease;min-width:32px;min-height:32px}.floating-toolbar-btn:hover{background-color:var(--bg-quaternary)}.floating-toolbar-btn:active{transform:scale(.95)}.floating-toolbar-btn:disabled{opacity:.5;cursor:not-allowed;pointer-events:none}.floating-toolbar-btn .iconify{font-size:18px}.floating-toolbar-btn .iconify[data-icon="mdi:format-bold"]{color:#1976d2}.floating-toolbar-btn .iconify[data-icon="mdi:format-italic"]{color:#7b1fa2}.floating-toolbar-btn .iconify[data-icon="mdi:format-strikethrough"]{color:#ff6f00}.floating-toolbar-btn.active{background-color:var(--bg-quaternary);box-shadow:0 0 0 2px var(--border-focus)}.floating-toolbar-btn.active .iconify{opacity:1;filter:brightness(1.2)}.floating-toolbar-separator{width:1px;height:20px;background-color:var(--border-secondary);margin:0 4px}@media (max-width: 768px){.header-dropdown-menu{min-width:50px;right:-10px}}.footer{text-align:center;font-size:12px;color:#999;position:fixed;bottom:0;width:100%;padding:10px 0}.footer span{font-weight:700}.profile-container{margin-top:20px}.avatar-section{text-align:center;padding:20px;border-bottom:1px solid #e0e0e0;margin-bottom:20px}.avatar-wrapper{margin-bottom:15px;display:flex;justify-content:center;align-items:center}.avatar-preview{width:150px;height:150px;border-radius:50%;object-fit:cover;border:3px solid var(--accent-color, #007bff)}.avatar-placeholder{width:150px;height:150px;border-radius:50%;background-color:#e0e0e0;display:inline-flex;align-items:center;justify-content:center;font-size:64px;color:#999}.avatar-buttons{display:flex;justify-content:center;gap:10px;margin-top:15px}.btn-upload,.btn-delete{padding:8px 16px;cursor:pointer;border:1px solid var(--border-secondary);background-color:var(--bg-tertiary);color:var(--text-primary);border-radius:5px;font-size:14px;transition:all .3s ease;display:inline-block}.btn-upload:hover{background-color:var(--accent-color, #007bff);color:#fff;border-color:var(--accent-color, #007bff)}.btn-delete{color:#dc3545}.btn-delete:hover{background-color:#dc3545;color:#fff;border-color:#dc3545}.avatar-hint{font-size:12px;color:#999;margin-top:10px}.profile-form{padding:0 10px;margin-bottom:80px}.profile-form h3{margin-bottom:15px;color:var(--text-primary)}.separator{margin:30px 0;border:none;border-top:1px solid var(--border-primary)}.notification{position:fixed;top:20px;left:50%;transform:translate(-50%) translateY(-100%);padding:12px 20px;border-radius:8px;color:#fff;font-weight:500;z-index:10000;max-width:350px;box-shadow:0 4px 12px #0000004d;transition:transform .3s ease,top .3s ease;font-size:14px;line-height:1.4;word-wrap:break-word}.notification-success{background-color:#28a745}.notification-error{background-color:#dc3545}.notification-warning{background-color:#ffc107;color:#000}.notification-info{background-color:var(--accent-color, #007bff)}.notification.visible{transform:translate(-50%) translateY(0)}@media (max-width: 768px){.notification{left:10px;right:10px;max-width:none;transform:translateY(-100%)}.notification.visible{transform:translateY(0)}}.back-btn{padding:8px 16px;border:1px solid var(--border-secondary);background-color:var(--bg-tertiary);border-radius:5px;font-size:14px;color:var(--border-focus);text-decoration:none;transition:all .3s ease;display:inline-block}.back-btn:hover{background-color:var(--accent-color, #007bff);color:#fff;border-color:var(--accent-color, #007bff)}.username-clickable{cursor:pointer;transition:color .3s ease}.username-clickable:hover{color:var(--accent-color, #007bff);text-decoration:underline}.center{display:flex;justify-content:center;align-items:center;flex-direction:column;width:600px;height:100%}.container-leftside{width:220px;height:auto;max-width:220px;box-shadow:0 0 10px var(--shadow-light);border-radius:8px;padding:12px;margin-top:20px;background:var(--bg-secondary);color:var(--text-primary);transition:background-color .3s ease,color .3s ease,box-shadow .3s ease}.mini-calendar{width:100%}.calendar-header{display:flex;justify-content:space-between;align-items:center;margin-bottom:10px}.calendar-month-year{font-size:13px;font-weight:700;color:var(--text-primary);text-align:center;flex:1}.calendar-nav{background:none;border:none;font-size:18px;cursor:pointer;color:var(--text-secondary);padding:0 3px;transition:color .3s ease}.calendar-nav:hover{color:var(--accent-color)}.calendar-weekdays{display:grid;grid-template-columns:repeat(7,1fr);gap:1px;margin-bottom:3px}.calendar-weekday{text-align:center;font-size:9px;font-weight:700;color:var(--text-secondary);padding:3px 0}.calendar-day{aspect-ratio:1;display:flex;align-items:center;justify-content:center;font-size:11px;cursor:pointer;border-radius:3px;transition:all .2s ease;color:var(--text-primary);padding:2px;font-weight:500;position:relative;background-color:transparent;border:1px solid transparent}.calendar-day:hover{background-color:transparent;border-color:var(--accent-color, #007bff)}.calendar-day.today{background-color:transparent;color:var(--text-primary);font-weight:700;border:1px solid var(--accent-color, #007bff)}.calendar-day.today:hover{background-color:transparent;border-color:var(--accent-color, #007bff)}.calendar-day.other-month{color:var(--text-muted);background-color:transparent;border:1px solid transparent}.calendar-day.selected{background-color:var(--accent-color, #007bff);color:#fff;font-weight:700;opacity:1;border:1px solid var(--accent-color, #007bff)}.calendar-day.selected:hover{background-color:var(--accent-color, #007bff);border-color:var(--accent-color, #007bff)}@media (min-width: 769px){.mini-calendar,.container-leftside .mini-calendar{background-color:transparent}.calendar-month-year{font-size:14px;font-weight:600;color:var(--text-primary)}.calendar-nav{font-size:20px;color:var(--text-secondary);font-weight:400}.calendar-nav:hover{color:var(--accent-color)}.calendar-weekdays{margin-bottom:5px}.calendar-weekday{font-size:10px;font-weight:400;color:#999;text-transform:none}.calendar-day{font-size:12px;border-radius:4px;color:#fff;font-weight:400;background-color:transparent;border:1px solid transparent}.calendar-day:hover{background-color:transparent;border-color:var(--accent-color, #007bff)}.calendar-day.other-month{color:#999;background-color:transparent;border:1px solid transparent}.calendar-day.other-month:hover{border-color:var(--accent-color, #007bff)}.calendar-day.selected{background-color:var(--accent-color, #007bff);color:#fff;font-weight:500;opacity:1;border-radius:4px;border:1px solid var(--accent-color, #007bff)}.calendar-day.selected:hover{background-color:var(--accent-color, #007bff);border-color:var(--accent-color, #007bff)}.calendar-day.today{background-color:transparent;color:#fff;font-weight:500;border:1px solid var(--accent-color, #007bff)}.calendar-day.today:hover{background-color:transparent;border-color:var(--accent-color, #007bff)}}.calendar-day.has-notes:after{content:"";position:absolute;bottom:2px;left:50%;transform:translate(-50%);width:4px;height:4px;background-color:#28a745;border-radius:50%}.calendar-day.has-edited-notes:before{content:"";position:absolute;bottom:2px;left:50%;transform:translate(-50%);width:4px;height:4px;background-color:#ffc107;border-radius:50%}.calendar-day.has-notes.has-edited-notes:before{transform:translate(-150%)}.calendar-day.has-notes.has-edited-notes:after{transform:translate(50%)}.calendar-day.selected.has-notes:after{background-color:#28a745;border:1px solid #fff;box-shadow:0 0 3px #00000080}.calendar-day.selected.has-edited-notes:before{background-color:#ffc107;border:1px solid #fff;box-shadow:0 0 3px #00000080}.calendar-day.today.has-notes:after{background-color:#28a745;border:1px solid #fff;box-shadow:0 0 3px #00000080}.calendar-day.today.has-edited-notes:before{background-color:#ffc107;border:1px solid #fff;box-shadow:0 0 3px #00000080}.calendar-day.selected.has-notes.has-edited-notes:before,.calendar-day.selected.has-notes.has-edited-notes:after{border:1px solid #fff;box-shadow:0 0 3px #00000080}.calendar-day.today.has-notes.has-edited-notes:before,.calendar-day.today.has-notes.has-edited-notes:after{border:1px solid #fff;box-shadow:0 0 3px #00000080}@media (min-width: 769px){[data-theme=dark] .mini-calendar,[data-theme=dark] .container-leftside .mini-calendar{background-color:transparent}[data-theme=dark] .calendar-day{background-color:transparent;color:#fff;border:1px solid transparent}[data-theme=dark] .calendar-day:hover{background-color:transparent;border-color:var(--accent-color, #007bff)}[data-theme=dark] .calendar-day.other-month{background-color:transparent;color:#999;border:1px solid transparent}[data-theme=dark] .calendar-day.other-month:hover{border-color:var(--accent-color, #007bff)}[data-theme=dark] .calendar-day.today{background-color:transparent;color:#fff;border:1px solid var(--accent-color, #007bff)}[data-theme=dark] .calendar-day.today:hover{background-color:transparent;border-color:var(--accent-color, #007bff)}[data-theme=dark] .calendar-day.selected{background-color:var(--accent-color, #007bff);color:#fff;opacity:1;border:1px solid var(--accent-color, #007bff)}[data-theme=dark] .calendar-day.selected:hover{background-color:var(--accent-color, #007bff);border-color:var(--accent-color, #007bff)}[data-theme=dark] .calendar-nav{color:#fff}[data-theme=dark] .calendar-nav:hover{opacity:.8}[data-theme=dark] .calendar-weekday{color:#999}[data-theme=dark] .calendar-month-year{color:#fff}[data-theme=dark] .calendar-day.has-notes:after{background-color:#28a745}[data-theme=dark] .calendar-day.has-edited-notes:before{background-color:#ffc107}}[data-theme=dark] .calendar-day.has-notes:after{background-color:#28a745;box-shadow:0 0 2px #28a74599}[data-theme=dark] .calendar-day.has-edited-notes:before{background-color:#ffc107;box-shadow:0 0 2px #ffc10799}.tags-section{margin-top:15px;padding-top:15px;border-top:1px solid var(--border-primary)}.tags-header{margin-bottom:10px}.tags-title{font-size:12px;font-weight:700;color:var(--text-primary)}.tags-container{display:flex;flex-wrap:wrap;gap:5px}.tag{display:inline-block;padding:4px 8px;background-color:rgba(var(--accent-color-rgb),.1);color:var(--accent-color);border:1px solid rgba(var(--accent-color-rgb),.3);border-radius:12px;font-size:10px;font-weight:500;cursor:pointer;transition:all .2s ease;-webkit-user-select:none;user-select:none;max-width:100%;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;word-break:break-word}.tag:hover{background-color:var(--accent-color, #007bff);color:#fff}.tag.active{background-color:var(--accent-color, #007bff);color:#fff;font-weight:700}.tag-count{margin-left:4px;font-size:9px;opacity:.8}.textNote .tag-in-note{display:inline-block;padding:2px 6px;background-color:rgba(var(--accent-color-rgb),.1);color:var(--accent-color);border:1px solid rgba(var(--accent-color-rgb),.3);border-radius:8px;font-size:12px;font-weight:500;cursor:pointer;transition:all .2s ease;text-decoration:none;margin:0 2px;word-wrap:break-word;overflow-wrap:break-word}.textNote .tag-in-note:hover{background-color:var(--accent-color, #007bff);color:#fff;transform:translateY(-1px);box-shadow:0 2px 4px rgba(var(--accent-color-rgb),.3)}.search-highlight{background-color:#fff3cd;padding:1px 2px;border-radius:2px;font-weight:500}.search-highlight.current{background-color:#ffc107;color:#000}.mobile-sidebar{display:flex;position:fixed;top:0;left:-85vw;width:85vw;max-width:320px;height:100vh;background:var(--bg-secondary);color:var(--text-primary);box-shadow:2px 0 10px var(--shadow-light);z-index:1000;overflow-y:auto;transition:left .3s ease;flex-direction:column;padding:0}.sidebar-close-btn{display:flex;align-items:center;justify-content:center;width:40px;height:40px;padding:0;margin:10px 10px 10px auto;background:var(--bg-tertiary);border:1px solid var(--border-secondary);border-radius:8px;cursor:pointer;transition:all .2s ease;flex-shrink:0}.mobile-sidebar .mini-calendar{width:100%;margin-bottom:15px}.mobile-sidebar .calendar-header{display:flex;justify-content:space-between;align-items:center;margin-bottom:8px;gap:4px}.mobile-sidebar .calendar-month-year{font-size:12px;font-weight:700;color:var(--text-primary);text-align:center;flex:1}.mobile-sidebar .calendar-nav{background:none;border:none;font-size:16px;cursor:pointer;color:var(--text-secondary);padding:0 3px;transition:color .3s ease}.mobile-sidebar .calendar-nav:hover{color:var(--accent-color)}.mobile-sidebar .calendar-days{display:grid;grid-template-columns:repeat(7,1fr);gap:1px;margin-bottom:15px}.mobile-sidebar .calendar-day{aspect-ratio:1;display:flex;align-items:center;justify-content:center;font-size:9px;cursor:pointer;border-radius:3px;transition:all .2s ease;color:var(--text-primary);padding:1px;font-weight:500;position:relative;background-color:transparent;border:1px solid transparent}.mobile-sidebar .calendar-day:hover{background-color:transparent;border-color:var(--accent-color, #007bff)}.mobile-sidebar .calendar-day.today{background-color:transparent;color:var(--text-primary);font-weight:700;border:1px solid var(--accent-color, #007bff)}.mobile-sidebar .calendar-day.today:hover{background-color:transparent;border-color:var(--accent-color, #007bff)}.mobile-sidebar .calendar-day.selected{background-color:var(--accent-color, #007bff);color:#fff;font-weight:700;opacity:1;border:1px solid var(--accent-color, #007bff)}.mobile-sidebar .calendar-day.selected:hover{background-color:var(--accent-color, #007bff);border-color:var(--accent-color, #007bff)}.mobile-sidebar .calendar-day.other-month{color:var(--text-muted);background-color:transparent;border:1px solid transparent}.mobile-sidebar .calendar-day.other-month:hover{border-color:var(--accent-color, #007bff)}[data-theme=dark] .mobile-sidebar .calendar-day{background-color:transparent;color:var(--text-primary);border:1px solid transparent}[data-theme=dark] .mobile-sidebar .calendar-day:hover{background-color:transparent;border-color:var(--accent-color, #007bff)}[data-theme=dark] .mobile-sidebar .calendar-day.other-month{background-color:transparent;color:var(--text-muted);border:1px solid transparent}[data-theme=dark] .mobile-sidebar .calendar-day.other-month:hover{border-color:var(--accent-color, #007bff)}[data-theme=dark] .mobile-sidebar .calendar-day.today{background-color:transparent;color:var(--text-primary);border:1px solid var(--accent-color, #007bff)}[data-theme=dark] .mobile-sidebar .calendar-day.today:hover{background-color:transparent;border-color:var(--accent-color, #007bff)}[data-theme=dark] .mobile-sidebar .calendar-day.selected{background-color:var(--accent-color, #007bff);color:#fff;opacity:1;border:1px solid var(--accent-color, #007bff)}[data-theme=dark] .mobile-sidebar .calendar-day.selected:hover{background-color:var(--accent-color, #007bff);border-color:var(--accent-color, #007bff)}[data-theme=dark] .mobile-sidebar .calendar-nav:hover{color:var(--border-focus)}[data-theme=dark] .mobile-sidebar .calendar-weekday{color:var(--text-secondary)}[data-theme=dark] .mobile-sidebar .calendar-day.has-notes:after{background-color:#28a745;box-shadow:0 0 2px #28a74599}[data-theme=dark] .mobile-sidebar .calendar-day.has-edited-notes:before{background-color:#ffc107;box-shadow:0 0 2px #ffc10799}.mobile-sidebar .search-section{margin-bottom:15px;padding-bottom:15px;border-bottom:1px solid var(--border-primary)}.mobile-sidebar .search-title{font-size:11px;font-weight:700;color:var(--text-primary);display:block;margin-bottom:8px}.mobile-sidebar .search-input{width:100%;padding:6px 10px;border:1px solid var(--border-secondary);border-radius:15px;font-size:11px;background-color:var(--bg-tertiary);color:var(--text-primary);transition:all .3s ease;box-sizing:border-box}.mobile-sidebar .search-input:focus{outline:none;border-color:var(--accent-color, #007bff);background-color:var(--bg-secondary);box-shadow:0 0 0 2px rgba(var(--accent-color-rgb),.25)}.mobile-sidebar .tags-section{margin-top:0;padding-top:0;border-top:none}.mobile-sidebar .tags-title{font-size:11px;font-weight:700;color:var(--text-primary);display:block;margin-bottom:8px}.mobile-sidebar .tags-container{display:flex;flex-wrap:wrap;gap:5px}.mobile-sidebar .tag{display:inline-block;padding:4px 8px;background-color:rgba(var(--accent-color-rgb),.1);color:var(--accent-color);border:1px solid rgba(var(--accent-color-rgb),.3);border-radius:12px;font-size:9px;font-weight:500;cursor:pointer;transition:all .2s ease;-webkit-user-select:none;user-select:none;max-width:100%;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;word-break:break-word}.mobile-sidebar .tag:hover{background-color:var(--accent-color, #007bff);color:#fff}.mobile-sidebar .tag.active{background-color:var(--accent-color, #007bff);color:#fff;font-weight:700}.mobile-sidebar .tag-count{margin-left:3px;font-size:8px;opacity:.8}@media (max-width: 768px){.ai-toggle-label{padding:12px 16px}.toggle-text-main{font-size:14px}.toggle-text-desc{font-size:11px}.toggle-switch-wrapper{margin-left:12px}.toggle-slider{width:44px;height:24px}.toggle-slider:before{width:20px;height:20px}.toggle-checkbox:checked+.toggle-slider:before{transform:translate(20px)}.mobile-menu-btn{display:flex;align-items:center;justify-content:center}.container-leftside{display:none!important}body{flex-direction:column;gap:0;padding:0 10px;justify-content:flex-start;align-items:center}.center{width:100%;max-width:600px;margin:60px auto 0}.container{width:100%;max-width:none;margin-top:5px;padding:10px;box-sizing:border-box}.center>.container:first-child{margin-top:3px}.notes-container .container{margin-top:0}.notes-container{margin-top:5px}.notes-header{flex-direction:row;align-items:center;gap:10px;width:100%}.notes-header-left{flex:1;min-width:0}.user-info{flex-shrink:0;flex-wrap:wrap;gap:8px}.user-info .back-btn{font-size:12px;padding:6px 8px;white-space:nowrap}.user-info .theme-toggle-btn{flex-shrink:0}@media (max-width: 480px){.user-info{flex-shrink:0;gap:4px}.user-info .back-btn{font-size:11px;padding:4px 6px}.user-info .theme-toggle-btn{width:32px;height:32px;padding:6px}.user-info .theme-toggle-btn .iconify{font-size:16px}.settings-icon-btn{width:32px;height:32px;padding:6px}.settings-icon-btn .iconify{font-size:16px}}.markdown-buttons{display:flex;flex-wrap:nowrap;gap:8px;width:100%;justify-content:flex-start;overflow-x:auto;overflow-y:hidden;scrollbar-width:none}.markdown-buttons::-webkit-scrollbar{display:none}.markdown-buttons .btnMarkdown{flex:0 1 auto;min-width:auto;margin-right:0;padding:8px 12px;font-size:14px;border:none;background-color:transparent}textarea{min-height:100px}.save-button-container,.action-buttons{width:100%;flex-direction:column}.btnSave,.btnAI,.btn-secondary{width:100%;text-align:center;justify-content:center}.footer{position:relative;margin-top:20px}}.image-preview-container{margin:15px 0;padding:15px;background:#f8f9fa;border:2px dashed #dee2e6;border-radius:8px;touch-action:manipulation;-webkit-tap-highlight-color:transparent}.image-preview-header{display:flex;justify-content:space-between;align-items:center;margin-bottom:10px;font-weight:600;color:#495057}.note-preview-container{margin:15px 0;padding:15px;background:var(--bg-tertiary);border:2px solid var(--accent-color, #007bff);border-radius:8px;min-height:200px;max-height:600px;overflow-y:auto;transition:background-color .3s ease,border-color .3s ease}.note-preview-header{display:flex;justify-content:space-between;align-items:center;margin-bottom:15px;padding-bottom:10px;border-bottom:2px solid var(--border-primary);font-weight:600;color:var(--accent-color, #007bff);font-size:16px;transition:color .3s ease,border-color .3s ease}.note-preview-content{background:var(--bg-secondary);color:var(--text-primary);padding:15px;border-radius:6px;min-height:150px;transition:background-color .3s ease,color .3s ease}.textNote .markdown-buttons--edit,.textNote .note-preview-container,.textNote .image-preview-container,.textNote .file-preview-container,.textNote .textInput,.textNote textarea.textInput{width:100%;box-sizing:border-box}.textNote .file-preview-container .file-preview-item{padding:6px 10px;min-height:40px}.textNote .file-preview-container .file-preview-item .file-icon{font-size:24px}.textNote .file-preview-container .file-preview-item .file-name{font-size:14px;line-height:1.2}.textNote .file-preview-container .file-preview-item .file-size{font-size:11px;margin-top:1px;line-height:1.2}.textNote .file-preview-container .file-preview-item .remove-file-btn{width:24px;height:24px;font-size:14px}.note-preview-content h1,.note-preview-content h2,.note-preview-content h3,.note-preview-content h4,.note-preview-content h5,.note-preview-content h6{margin-top:.5em;margin-bottom:.5em;color:var(--text-primary);transition:color .3s ease}.note-preview-content p{margin:.5em 0;color:var(--text-primary);transition:color .3s ease}.note-preview-content ul,.note-preview-content ol{margin:.5em 0;padding-left:2em;color:var(--text-primary);transition:color .3s ease}.note-preview-content li{color:var(--text-primary);transition:color .3s ease}.note-preview-content a{color:var(--accent-color, #007bff);text-decoration:none;transition:color .3s ease}.note-preview-content a:hover{text-decoration:underline}.note-preview-content code{background:var(--bg-quaternary);color:var(--text-primary);padding:2px 6px;border-radius:4px;font-family:Courier New,monospace;transition:background-color .3s ease,color .3s ease}.note-preview-content pre{background:var(--bg-quaternary);color:var(--text-primary);padding:10px;border-radius:6px;overflow-x:auto;border:1px solid var(--border-primary);transition:background-color .3s ease,color .3s ease,border-color .3s ease}.note-preview-content pre code{background:transparent;padding:0;border-radius:0}.note-preview-content blockquote{border-left:4px solid var(--accent-color, #007bff);margin:10px 0;color:var(--text-secondary);background-color:var(--bg-tertiary);padding:8px 15px;border-radius:0 4px 4px 0;transition:color .3s ease,background-color .3s ease,border-color .3s ease}.note-preview-content blockquote p{color:var(--text-secondary);margin:0}.note-preview-content img{max-width:100%;height:auto;border-radius:6px;margin:10px 0;box-shadow:0 2px 4px var(--shadow-light);transition:box-shadow .3s ease}.note-preview-content table{width:100%;border-collapse:collapse;margin:10px 0;background:var(--bg-secondary);border-radius:6px;overflow:hidden;box-shadow:0 1px 3px var(--shadow-light);transition:background-color .3s ease,box-shadow .3s ease}.note-preview-content th,.note-preview-content td{padding:8px 12px;text-align:left;border-bottom:1px solid var(--border-primary);color:var(--text-primary);transition:color .3s ease,border-color .3s ease}.note-preview-content th{background:var(--bg-tertiary);font-weight:700;color:var(--text-primary);transition:background-color .3s ease,color .3s ease}.note-preview-content tr:hover{background:var(--bg-quaternary);transition:background-color .3s ease}.note-preview-content hr{border:none;height:1px;background:var(--border-primary);margin:20px 0;transition:background-color .3s ease}[data-theme=dark] .note-preview-container{background:var(--bg-tertiary);border-color:var(--accent-color)}[data-theme=dark] .note-preview-header{color:var(--accent-color);border-bottom-color:var(--border-primary)}[data-theme=dark] .note-preview-content{background:var(--bg-secondary);color:var(--text-primary)}[data-theme=dark] .note-preview-content code,[data-theme=dark] .note-preview-content pre{background:var(--bg-quaternary);color:#e6e6e6;border:1px solid var(--border-primary)}[data-theme=dark] .note-preview-content pre code{background:transparent;border:none;color:#e6e6e6}[data-theme=dark] .note-preview-content blockquote{background-color:var(--bg-tertiary);border-left-color:var(--accent-color);color:var(--text-secondary)}[data-theme=dark] .note-preview-content table{background:var(--bg-secondary);box-shadow:0 1px 3px var(--shadow-light)}[data-theme=dark] .note-preview-content th{background:var(--bg-tertiary);color:var(--text-primary)}[data-theme=dark] .note-preview-content th,[data-theme=dark] .note-preview-content td{border-bottom-color:var(--border-primary);color:var(--text-primary)}[data-theme=dark] .note-preview-content tr:hover{background:var(--bg-quaternary)}[data-theme=dark] .note-preview-content img{box-shadow:0 2px 4px var(--shadow-light)}.note-preview-content input[type=checkbox]{cursor:pointer;margin-right:8px;width:18px;height:18px;accent-color:var(--accent-color, #007bff);vertical-align:middle;position:relative;top:-1px}.note-preview-content .task-list-item{list-style-type:none;margin-left:-20px;padding:0;line-height:1.5;transition:all .3s ease}.note-preview-content .task-list-item:has(input[type=checkbox]:checked){opacity:.65;text-decoration:line-through;color:var(--text-muted)}.note-preview-content .task-list-item input[type=checkbox]:checked~*{text-decoration:line-through;color:var(--text-muted)}.note-preview-content .task-list-item:has(input[type=checkbox]:checked) *{text-decoration:line-through;color:var(--text-muted)}.note-preview-content .task-list-item:hover{background-color:rgba(var(--accent-color-rgb),.05);border-radius:4px;padding-left:4px;margin-left:-24px}.note-preview-content input[type=checkbox]:checked{text-decoration:none}.note-preview-content input[type=checkbox]:checked+*{text-decoration:line-through;color:var(--text-muted)}.note-preview-content li:has(input[type=checkbox]){list-style-type:none;margin-left:-20px;padding:0;line-height:1.5;transition:all .3s ease}.note-preview-content li:has(input[type=checkbox]:checked){opacity:.65;text-decoration:line-through;color:var(--text-muted)}.note-preview-content li:has(input[type=checkbox]) input[type=checkbox]:checked{text-decoration:none}.note-preview-content li:has(input[type=checkbox]:checked) label,.note-preview-content li:has(input[type=checkbox]:checked) span,.note-preview-content li:has(input[type=checkbox]:checked) p{text-decoration:line-through;color:var(--text-muted)}.note-preview-content li:has(input[type=checkbox]:checked) *{text-decoration:line-through;color:var(--text-muted)}.note-preview-content li:has(input[type=checkbox]):hover{background-color:rgba(var(--accent-color-rgb),.05);border-radius:4px;padding-left:4px;margin-left:-24px}.clear-images-btn{background:#dc3545;color:#fff;border:none;padding:4px 8px;border-radius:4px;cursor:pointer;font-size:12px;transition:background-color .3s ease}.clear-images-btn:hover{background:#c82333}.image-preview-list{display:flex;flex-wrap:wrap;gap:10px}.image-preview-item{position:relative;border:1px solid #dee2e6;border-radius:6px;overflow:hidden;background:#fff}.image-preview-item img{width:100px;height:100px;object-fit:cover;display:block}.image-preview-item .remove-image-btn{position:absolute;top:2px;right:2px;background:#dc3545cc;color:#fff;border:none;border-radius:50%;width:24px;height:24px;cursor:pointer;font-size:14px;display:flex;align-items:center;justify-content:center;transition:background-color .3s ease;touch-action:manipulation;-webkit-tap-highlight-color:transparent;user-select:none;-webkit-user-select:none}.image-preview-item .remove-image-btn:hover{background:#dc3545}.image-preview-item .image-preview-remove{position:absolute;top:2px;right:2px;background:#dc3545e6;color:#fff;border:none;border-radius:50%;width:28px;height:28px;cursor:pointer;font-size:16px;display:flex;align-items:center;justify-content:center;transition:all .3s ease;touch-action:manipulation;-webkit-tap-highlight-color:transparent;user-select:none;-webkit-user-select:none;box-shadow:0 2px 4px #0003;z-index:10}.image-preview-item .image-preview-remove:hover{background:#dc3545;transform:scale(1.1);box-shadow:0 3px 6px #0000004d}.image-preview-item .image-preview-remove:active{transform:scale(.95)}.file-preview-item .file-preview-remove{background:#dc3545e6;color:#fff;border:none;border-radius:50%;width:28px;height:28px;cursor:pointer;font-size:16px;display:flex;align-items:center;justify-content:center;flex-shrink:0;transition:all .3s ease;touch-action:manipulation;-webkit-tap-highlight-color:transparent;user-select:none;-webkit-user-select:none;box-shadow:0 2px 4px #0003;margin-left:auto}.file-preview-item .file-preview-remove:hover{background:#dc3545;transform:scale(1.1);box-shadow:0 3px 6px #0000004d}.file-preview-item .file-preview-remove:active{transform:scale(.95)}.image-preview-item .image-preview-remove.restore-btn,.file-preview-item .file-preview-remove.restore-btn{background:#28a745e6!important}.image-preview-item .image-preview-remove.restore-btn:hover,.file-preview-item .file-preview-remove.restore-btn:hover{background:#28a745!important}.image-preview-item .image-preview-remove[style*=green],.file-preview-item .file-preview-remove[style*=green]{background:#28a745e6!important}.image-preview-item .image-preview-remove[style*=green]:hover,.file-preview-item .file-preview-remove[style*=green]:hover{background:#28a745!important}.image-preview-item .image-info{padding:4px 6px;font-size:10px;color:#6c757d;background:#f8f9fa;word-break:break-all}.note-image{width:150px;height:150px;object-fit:cover;border-radius:6px;margin:10px 0;box-shadow:0 2px 4px #0000001a;cursor:pointer;transition:transform .2s ease}.note-image:hover{transform:scale(1.02);box-shadow:0 4px 8px #0003}.note-image:after{content:"🔍";position:absolute;top:50%;left:50%;transform:translate(-50%,-50%);background:#000000b3;color:#fff;padding:8px;border-radius:50%;font-size:16px;opacity:0;transition:opacity .2s ease;pointer-events:none}.note-image:hover:after{opacity:1}.note-images-container{margin:10px 0;display:flex;flex-wrap:wrap;gap:10px}.note-image-item{position:relative;display:inline-block}.note-image-item .note-image{position:relative}.note-files-container{margin:10px 0;display:flex;flex-direction:column;gap:8px}.note-file-item{display:flex;align-items:center}.note-file-link{display:flex;align-items:center;padding:10px;background:#f8f9fa;border:1px solid #dee2e6;border-radius:6px;text-decoration:none;color:inherit;gap:12px;width:100%;transition:all .2s}.note-file-link:hover{background:#e9ecef;border-color:var(--accent-color, #007bff);transform:translateY(-1px);box-shadow:0 2px 4px #0000001a}.note-file-link .file-icon{font-size:32px;color:var(--accent-color, #007bff);flex-shrink:0}.note-file-link .file-info{flex:1;min-width:0}.note-file-link .file-name{font-weight:500;color:#333;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.note-file-link .file-size{font-size:12px;color:#666;margin-top:2px}.note-image-item .remove-note-image-btn{position:absolute;top:5px;right:5px;background:#dc3545cc;color:#fff;border:none;border-radius:50%;width:24px;height:24px;cursor:pointer;font-size:14px;display:flex;align-items:center;justify-content:center;transition:background-color .3s ease;opacity:0}.note-image-item:hover .remove-note-image-btn{opacity:1}.note-image-item .remove-note-image-btn:hover{background:#dc3545}.image-modal{display:none;position:fixed;z-index:1000;left:0;top:0;width:100%;height:100%;background-color:#000000e6;cursor:pointer}.image-modal-content{position:absolute;top:50%;left:50%;transform:translate(-50%,-50%);max-width:90%;max-height:90%;object-fit:contain}.image-modal-close{position:absolute;top:15px;right:35px;color:#f1f1f1;font-size:40px;font-weight:700;cursor:pointer}.image-modal-close:hover{color:#bbb}.modal{display:none;position:fixed;z-index:1000;left:0;top:0;width:100%;height:100%;background-color:#00000080;-webkit-backdrop-filter:blur(2px);backdrop-filter:blur(2px)}.modal-content{background-color:#fff;margin:10% auto;padding:0;border-radius:8px;width:90%;max-width:500px;box-shadow:0 4px 20px #0000004d;animation:modalFadeIn .3s ease-out}@keyframes modalFadeIn{0%{opacity:0;transform:translateY(-20px)}to{opacity:1;transform:translateY(0)}}.modal-header{padding:20px 25px;border-bottom:1px solid #eee;display:flex;justify-content:space-between;align-items:center}.modal-header h3{margin:0;color:#333;font-size:20px}.modal-close{color:#aaa;font-size:28px;font-weight:700;cursor:pointer;line-height:1}.modal-close:hover{color:#666}.modal-body{padding:25px;color:#555;line-height:1.5}.modal-footer{padding:20px 25px;border-top:1px solid #eee;display:flex;justify-content:flex-end;gap:10px}[data-theme=dark] .modal-content{background-color:var(--bg-secondary);color:var(--text-primary)}[data-theme=dark] .modal-header{border-bottom-color:var(--border-primary)}[data-theme=dark] .modal-header h3{color:var(--text-primary)}[data-theme=dark] .modal-close{color:var(--text-secondary)}[data-theme=dark] .modal-close:hover{color:var(--text-primary)}[data-theme=dark] .modal-body{color:var(--text-secondary)}[data-theme=dark] .modal-footer{border-top-color:var(--border-primary)}.modal-password-input{width:100%;padding:10px;border:1px solid var(--border-secondary);border-radius:4px;font-size:16px;background-color:var(--bg-tertiary);color:var(--text-primary);box-sizing:border-box;transition:all .3s ease}.modal-password-input:focus{outline:none;border-color:var(--border-focus);background-color:var(--bg-secondary);box-shadow:0 0 0 2px #4a9eff40}.modal-password-input::placeholder{color:var(--text-muted)}@media (max-width: 768px){.image-preview-list,.note-images-container{justify-content:center}.image-preview-item img{width:80px;height:80px}.markdown-buttons .btnMarkdown{min-height:48px;padding:8px 12px;margin:2px}.image-preview-item .remove-image-btn{width:28px;height:28px;font-size:16px}.image-preview-item .image-preview-remove,.file-preview-item .file-preview-remove{width:32px;height:32px;font-size:18px}.clear-images-btn{min-height:44px;padding:8px 16px;font-size:14px}.note-image{width:120px;height:120px}}.accent-color-picker{display:flex;gap:10px;margin-bottom:10px;flex-wrap:wrap}.color-option{width:40px;height:40px;border-radius:50%;cursor:pointer;border:3px solid transparent;transition:all .3s ease;position:relative}.color-option:hover{transform:scale(1.1);box-shadow:0 2px 8px #0003}.color-option.selected{border-color:#333;transform:scale(1.1);box-shadow:0 0 0 2px #fff,0 0 0 4px #333}.color-option:after{content:"✓";position:absolute;top:50%;left:50%;transform:translate(-50%,-50%);color:#fff;font-weight:700;font-size:18px;opacity:0;transition:opacity .2s ease}.color-option.selected:after{opacity:1}#accentColor{width:60px;height:40px;border:none;border-radius:5px;cursor:pointer}.settings-tabs{display:flex;gap:10px;margin:20px 0;border-bottom:2px solid #e0e0e0;flex-wrap:wrap}.settings-tab{padding:10px 20px;background:none;border:none;border-bottom:3px solid transparent;cursor:pointer;font-size:16px;color:#666;transition:all .3s ease;display:flex;align-items:center;gap:8px}.settings-tab:hover{color:var(--accent-color, #007bff);background:rgba(var(--accent-color-rgb),.05)}.settings-tab.active{color:var(--accent-color, #007bff);border-bottom-color:var(--accent-color, #007bff);font-weight:700}.settings-content{margin-top:20px}.tab-content{display:none}.tab-content.active{display:block}.archived-notes-list{display:flex;flex-direction:column;gap:15px}.archived-note-item{background:var(--bg-secondary);border:1px solid var(--border-primary);border-radius:8px;padding:15px;transition:all .3s ease;color:var(--text-primary)}.archived-note-item:hover{box-shadow:0 2px 8px var(--shadow-light)}.archived-note-header{display:flex;justify-content:space-between;align-items:center;margin-bottom:10px;flex-wrap:wrap;gap:10px}.archived-note-date{font-size:12px;color:var(--text-muted)}.archived-note-actions{display:flex;gap:8px}.btn-restore,.btn-delete-permanent{padding:6px 12px;border:1px solid var(--border-secondary);border-radius:5px;background:var(--bg-tertiary);color:var(--text-primary);cursor:pointer;font-size:13px;transition:all .3s ease;display:flex;align-items:center;gap:4px}.btn-restore{color:var(--accent-color, #007bff);border-color:var(--accent-color, #007bff)}.btn-restore:hover{background:var(--accent-color, #007bff);color:#fff}.btn-delete-permanent{color:#dc3545;border-color:#dc3545}.btn-delete-permanent:hover{background:#dc3545;color:#fff}.btn-primary{background-color:var(--accent-color, #007bff);color:#fff;border:1px solid var(--accent-color, #007bff);padding:10px 20px;border-radius:5px;cursor:pointer;font-size:14px;transition:all .3s ease;display:inline-flex;align-items:center;gap:6px}.btn-primary:hover{background-color:var(--accent-color, #007bff);border-color:var(--accent-color, #007bff);opacity:.9;filter:brightness(.9)}.btn-primary:disabled{background-color:#6c757d;border-color:#6c757d;cursor:not-allowed;opacity:.6}.btn-danger{background-color:#dc3545;color:#fff;border:1px solid #dc3545;padding:10px 20px;border-radius:5px;cursor:pointer;font-size:14px;transition:all .3s ease;display:inline-flex;align-items:center;gap:6px}.btn-danger:hover{background-color:#c82333;border-color:#bd2130}.btn-danger:disabled{background-color:#6c757d;border-color:#6c757d;cursor:not-allowed;opacity:.6}.danger-zone{background-color:var(--bg-secondary);border:2px solid #dc3545;border-radius:8px;padding:20px;margin-top:20px;position:relative}.danger-zone:before{content:"⚠️";position:absolute;top:-10px;left:20px;background-color:var(--bg-primary);padding:0 10px;font-size:16px}.danger-zone h3{color:#dc3545;margin-top:0;margin-bottom:15px;font-size:18px;font-weight:700}.danger-zone p{color:var(--text-secondary);font-size:14px;line-height:1.5;margin-bottom:15px}.danger-zone .btn-danger{background-color:#dc3545;border-color:#dc3545;font-weight:600;padding:12px 24px;font-size:15px}.danger-zone .btn-danger:hover{background-color:#c82333;border-color:#bd2130;transform:translateY(-1px);box-shadow:0 4px 8px #dc35454d}.btn-secondary{background-color:var(--bg-tertiary);color:var(--text-primary);border:1px solid var(--border-secondary);padding:10px 20px;border-radius:5px;cursor:pointer;font-size:14px;transition:all .3s ease}.btn-secondary:hover{background-color:var(--bg-quaternary)}.btn-secondary.active{background-color:var(--accent-color);color:#fff;border-color:var(--accent-color)}.archived-note-content{font-size:14px;color:var(--text-primary);line-height:1.5;max-height:100px;overflow:hidden;text-overflow:ellipsis;word-wrap:break-word;overflow-wrap:break-word}.archived-note-images{margin-top:10px;font-size:12px;color:var(--text-secondary);font-style:italic}.logs-filters{display:flex;gap:10px;margin-bottom:20px;flex-wrap:wrap}.log-filter-select{flex:1;min-width:200px;padding:8px 12px;border:1px solid var(--border-secondary);border-radius:5px;font-size:14px;background-color:var(--bg-tertiary);color:var(--text-primary)}.log-filter-select:focus{outline:none;border-color:var(--accent-color, #007bff)}.logs-table-container{overflow-x:auto;margin-bottom:20px}.logs-table{width:100%;border-collapse:collapse;background:var(--bg-secondary);color:var(--text-primary);border-radius:8px;overflow:hidden;box-shadow:0 1px 3px var(--shadow-light)}.logs-table thead{background:var(--bg-tertiary)}.logs-table th{padding:12px;text-align:left;font-weight:700;color:var(--text-primary);border-bottom:2px solid var(--border-primary);font-size:14px}.logs-table td{padding:12px;border-bottom:1px solid var(--border-primary);font-size:13px;color:var(--text-secondary)}.logs-table tbody tr:hover{background:var(--bg-quaternary)}.log-action-badge{display:inline-block;padding:4px 8px;border-radius:4px;font-size:12px;font-weight:500;white-space:nowrap}.log-action-login,.log-action-register{background:#d4edda;color:#155724}.log-action-logout{background:#f8d7da;color:#721c24}.log-action-note_create{background:#d1ecf1;color:#0c5460}.log-action-note_update{background:#fff3cd;color:#856404}.log-action-note_delete,.log-action-note_delete_permanent{background:#f8d7da;color:#721c24}.log-action-note_pin{background:#e7e7ff;color:#4a4aff}.log-action-note_archive{background:#e2e3e5;color:#383d41}.log-action-note_unarchive{background:#d4edda;color:#155724}.log-action-profile_update{background:#fce4ec;color:#c2185b}.load-more-container{text-align:center;margin:20px 0}.note-pinned{border-left:4px solid #ffc107;background:var(--bg-secondary)}.pin-indicator{display:inline-flex;align-items:center;gap:4px;color:#ffc107;font-size:12px;font-weight:700;margin-left:10px}@media (max-width: 768px){.settings-tabs{flex-direction:column}.settings-tab{width:100%;justify-content:center}.archived-note-header{flex-direction:column;align-items:flex-start}.archived-note-actions{width:100%;justify-content:flex-start}.logs-table{font-size:12px}.logs-table th,.logs-table td{padding:8px}.logs-filters{flex-direction:column}.log-filter-select{width:100%}}@keyframes spin{0%{transform:rotate(0)}to{transform:rotate(360deg)}}.log-action-ai_improve{background:#d1ecf1;color:#0c5460}.spoiler{background:linear-gradient(45deg,#f0f0f0,#e8e8e8);color:transparent;cursor:pointer;border-radius:4px;padding:3px 6px;-webkit-user-select:none;user-select:none;transition:all .3s ease;position:relative;border:1px solid #ddd;font-weight:500;backdrop-filter:blur(2px);-webkit-backdrop-filter:blur(2px);text-shadow:0 0 8px rgba(0,0,0,.3)}.spoiler:before{content:"";position:absolute;top:0;left:0;right:0;bottom:0;background:#fffc;border-radius:4px;filter:blur(1px);z-index:-1}.spoiler:hover{background:linear-gradient(45deg,#e8e8e8,#d8d8d8);transform:scale(1.02);box-shadow:0 2px 8px #00000026}.spoiler:hover:before{background:#ffffffe6}.spoiler.revealed{background:linear-gradient(45deg,#e8f5e8,#d4edda);color:#155724;border-color:#c3e6cb;box-shadow:0 0 0 2px #28a74540;text-shadow:none;user-select:text;-webkit-user-select:text;cursor:text}.spoiler.revealed:before{display:none}.spoiler.revealed:hover{background:linear-gradient(45deg,#d4edda,#c3e6cb);box-shadow:0 0 0 2px #28a74559}.file-preview-container{margin:15px 0;padding:15px;background:#f0f8ff;border:2px dashed #b0d4f1;border-radius:8px;touch-action:manipulation;-webkit-tap-highlight-color:transparent}.file-preview-header{display:flex;justify-content:space-between;align-items:center;margin-bottom:10px;font-weight:600;color:#495057}.file-preview-list{display:flex;flex-direction:column;gap:10px}.file-preview-item{display:flex;align-items:center;padding:6px 10px;background:#fff;border-radius:6px;border:1px solid #dee2e6;gap:12px;min-height:40px}.file-preview-item .file-icon{font-size:24px;color:var(--accent-color, #007bff);flex-shrink:0}.file-preview-item .file-info,.file-preview-item .file-info-edit{flex:1;min-width:0}.file-preview-item .file-name{font-weight:500;color:#333;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;font-size:14px;line-height:1.2}.file-preview-item .file-size{font-size:11px;color:#666;margin-top:1px;line-height:1.2}.file-info-edit .file-name{font-weight:500;color:#333;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;font-size:14px;line-height:1.2}.file-info-edit .file-size{font-size:11px;color:#666;margin-top:1px;line-height:1.2}.file-preview-item .remove-file-btn{background:#dc3545;color:#fff;border:none;border-radius:50%;width:24px;height:24px;cursor:pointer;font-size:14px;display:flex;align-items:center;justify-content:center;flex-shrink:0;transition:background-color .2s}.file-preview-item .remove-file-btn:hover{background:#c82333}.clear-files-btn{background:#dc3545;color:#fff;border:none;padding:4px 8px;border-radius:4px;cursor:pointer;font-size:12px;transition:background-color .3s ease}.clear-files-btn:hover{background:#c82333}[data-theme=dark] .file-preview-container{background:#2a3a4a;border-color:#4a5a6a}[data-theme=dark] .file-preview-header{color:var(--text-primary)}[data-theme=dark] .file-preview-item{background:var(--bg-secondary);border-color:var(--border-primary)}[data-theme=dark] .file-preview-item .file-name{color:var(--text-primary);font-size:14px;line-height:1.2}[data-theme=dark] .file-preview-item .file-size{color:var(--text-secondary);font-size:11px;margin-top:1px;line-height:1.2}[data-theme=dark] .file-info-edit .file-name{color:var(--text-primary);font-size:14px;line-height:1.2}[data-theme=dark] .file-info-edit .file-size{color:var(--text-secondary);font-size:11px;margin-top:1px;line-height:1.2}[data-theme=dark] .textNote .file-preview-container .file-preview-item .file-name{color:var(--text-primary);font-size:14px;line-height:1.2}[data-theme=dark] .textNote .file-preview-container .file-preview-item .file-size{color:var(--text-secondary);font-size:11px;margin-top:1px;line-height:1.2}[data-theme=dark] .note-file-link{background:var(--bg-tertiary);border-color:var(--border-primary);color:var(--text-primary)}[data-theme=dark] .note-file-link:hover{background:var(--bg-hover);border-color:var(--accent-color)}[data-theme=dark] .note-file-link .file-name{color:var(--text-primary)}[data-theme=dark] .note-file-link .file-size{color:var(--text-secondary)}[data-theme=dark] .image-preview-container{background:#2a3a4a;border-color:#4a5a6a}[data-theme=dark] .image-preview-header{color:var(--text-primary)}[data-theme=dark] .image-preview-item{background:var(--bg-secondary);border-color:var(--border-primary)}[data-theme=dark] .image-preview-item .image-info{background:var(--bg-tertiary);color:var(--text-secondary)}[data-theme=dark] .image-preview-item .image-preview-remove{background:#dc3545d9;box-shadow:0 2px 4px #0006}[data-theme=dark] .image-preview-item .image-preview-remove:hover{background:#dc3545;box-shadow:0 3px 6px #00000080}[data-theme=dark] .file-preview-item .file-preview-remove{background:#dc3545d9;box-shadow:0 2px 4px #0006}[data-theme=dark] .file-preview-item .file-preview-remove:hover{background:#dc3545;box-shadow:0 3px 6px #00000080}[data-theme=dark] .image-preview-item .image-preview-remove.restore-btn,[data-theme=dark] .file-preview-item .file-preview-remove.restore-btn{background:#28a745d9!important}[data-theme=dark] .image-preview-item .image-preview-remove.restore-btn:hover,[data-theme=dark] .file-preview-item .file-preview-remove.restore-btn:hover{background:#28a745!important}[data-theme=dark] .image-preview-item .image-preview-remove[style*=green],[data-theme=dark] .file-preview-item .file-preview-remove[style*=green]{background:#28a745d9!important}[data-theme=dark] .image-preview-item .image-preview-remove[style*=green]:hover,[data-theme=dark] .file-preview-item .file-preview-remove[style*=green]:hover{background:#28a745!important}[data-theme=dark] .note-images-container{background:transparent}[data-theme=dark] .note-image-item,[data-theme=dark] .note-image{border-color:var(--border-primary)}[data-theme=dark] .note-image:hover:after{background:#000000b3}.btnMarkdown .iconify[data-icon="mdi:menu-down"]{color:#1976d2}.mobile-menu-btn{display:none;position:fixed;top:15px;left:15px;z-index:999;background:var(--bg-secondary);border:1px solid var(--border-secondary);border-radius:8px;padding:10px 12px;cursor:pointer;box-shadow:0 2px 8px var(--shadow-light);transition:all .3s ease}.mobile-menu-btn:hover{background:var(--bg-quaternary);box-shadow:0 4px 12px var(--shadow-medium)}.mobile-menu-btn .iconify{font-size:24px;color:var(--text-primary)}.mobile-sidebar{display:flex;flex-direction:column;position:fixed;top:0;left:-85vw;width:85vw;max-width:320px;height:100vh;background:var(--bg-secondary);color:var(--text-primary);box-shadow:2px 0 10px var(--shadow-light);transition:left .3s ease;z-index:1000;overflow-y:auto}.mobile-sidebar.open{left:0}.sidebar-close-btn{display:flex;align-items:center;justify-content:center;width:40px;height:40px;padding:0;margin:10px 10px 10px auto;background:var(--bg-tertiary);border:1px solid var(--border-secondary);border-radius:8px;cursor:pointer;transition:background .3s ease}.sidebar-close-btn:hover{background:var(--bg-quaternary)}.sidebar-close-btn .iconify{font-size:20px;color:var(--text-primary)}.sidebar-content{padding:10px 12px;overflow-y:auto;flex:1}.mobile-calendar-section,.mobile-search-section,.mobile-tags-section{margin-bottom:20px;padding-bottom:15px;border-bottom:1px solid var(--border-primary)}.mobile-tags-section{border-bottom:none}.search-header,.tags-header{margin-bottom:10px}.search-title,.tags-title{font-size:13px;font-weight:700;color:var(--text-primary);display:flex;align-items:center;gap:5px}.search-title .iconify,.tags-title .iconify{font-size:16px;color:var(--accent-color)}.mobile-sidebar-overlay{display:none;position:fixed;top:0;left:0;right:0;bottom:0;background:#00000080;z-index:999;opacity:0;transition:opacity .3s ease}.mobile-sidebar-overlay.open{display:block;opacity:1}@media (max-width: 768px){.mobile-menu-btn{display:flex;align-items:center;justify-content:center}.container-leftside,.sidebar{display:none!important}body{flex-direction:column;gap:0;padding:20px 10px 0}.center{width:100%!important;max-width:100%!important}.container{width:100%;max-width:100%;margin-top:60px}.center>.container:first-child{margin-top:3px}.notes-container .container{margin-top:0}.notes-container{padding-bottom:80px;margin-top:16px;gap:16px}.empty-message{padding:0 15px;font-size:14px}.notes-header{gap:10px;align-items:flex-start}.notes-header-left{width:auto;min-width:0;align-items:flex-start;gap:8px}.filter-indicator{font-size:12px;display:inline-flex!important;max-width:min(300px,100%)!important;width:fit-content!important;box-sizing:border-box!important}.filter-indicator-text{overflow:hidden!important;text-overflow:ellipsis!important;white-space:nowrap!important}.markdown-buttons .btnMarkdown{min-height:44px;padding:8px 10px;margin:2px;font-size:13px}.textInput{font-size:14px;min-height:100px}.image-preview-list,.note-images-container{justify-content:center}.image-preview-item img,.note-image{width:80px;height:80px}.notification{left:10px;right:10px;max-width:none}.footer{font-size:11px;padding:8px 0}}@media (max-width: 480px){.mobile-menu-btn{top:10px;left:10px;padding:8px 10px}.mobile-menu-btn .iconify{font-size:20px}.container{margin-top:50px;padding:12px}.markdown-buttons .btnMarkdown{padding:6px 8px;font-size:12px}.user-info>*{font-size:12px}}.loading-overlay{position:fixed;top:0;left:0;width:100%;height:100%;background-color:#00000080;-webkit-backdrop-filter:blur(2px);backdrop-filter:blur(2px);display:flex;justify-content:center;align-items:center;z-index:1000}.loading-content{background-color:var(--bg-color);padding:20px 30px;border-radius:8px;box-shadow:0 4px 20px #0000004d;display:flex;align-items:center;justify-content:center;min-width:150px}.loading-text{color:var(--text-color);font-size:16px;font-weight:500;text-align:center}[data-theme=dark] .loading-content{box-shadow:0 4px 20px #0009}.main-wrapper{display:flex;gap:15px;align-items:flex-start;width:100%}.calendar-box{flex-shrink:0;width:190px;background:#fff;box-shadow:0 0 10px #0000001a;border-radius:8px;padding:10px}.calendar-header{display:flex;justify-content:space-between;align-items:center;margin-bottom:8px;gap:4px}.calendar-header h3{margin:0;font-size:11px;font-weight:600;color:#333;min-width:75px;text-align:center;flex:1}.calendar-nav-btn{background:#f0f0f0;border:1px solid #ddd;border-radius:3px;padding:2px 5px;cursor:pointer;font-size:11px;color:#333;transition:all .2s ease}.calendar-nav-btn:hover{background:var(--accent-color, #007bff);color:#fff;border-color:var(--accent-color, #007bff)}.calendar-weekdays{display:grid;grid-template-columns:repeat(7,1fr);gap:1px;margin-bottom:5px}.weekday{text-align:center;font-size:8px;font-weight:600;color:#666;padding:1px 0;text-transform:uppercase}.calendar-days{display:grid;grid-template-columns:repeat(7,1fr);gap:1px}.calendar-day{aspect-ratio:1;display:flex;align-items:center;justify-content:center;font-size:10px;border-radius:3px;cursor:pointer;background:transparent;color:#666;border:1px solid transparent;transition:all .2s ease;position:relative}.calendar-day:hover{background:transparent;border-color:var(--accent-color, #007bff)}.calendar-day.other-month{color:#ccc;background:transparent}.calendar-day.other-month:hover{border-color:var(--accent-color, #007bff)}.calendar-day.today{background:transparent;color:#666;font-weight:600;border-color:var(--accent-color, #007bff)}.calendar-day.today:hover{background:transparent;border-color:var(--accent-color, #007bff)}.calendar-day.selected{background:var(--accent-color, #007bff);color:#fff;font-weight:600;border-color:var(--accent-color, #007bff)}.calendar-day.selected:hover{background:var(--accent-color, #007bff);border-color:var(--accent-color, #007bff)}.main{flex:1;min-width:300px}@media (max-width: 768px){.main-wrapper{flex-direction:column}.calendar-box{width:100%}.main{min-width:auto}.container{max-width:100%}} diff --git a/backend/public/assets/workbox-window.prod.es5-B9K5rw8f.js b/backend/public/assets/workbox-window.prod.es5-B9K5rw8f.js new file mode 100644 index 0000000..8f3684a --- /dev/null +++ b/backend/public/assets/workbox-window.prod.es5-B9K5rw8f.js @@ -0,0 +1,2 @@ +try{self["workbox:window:7.2.0"]&&_()}catch{}function E(n,r){return new Promise(function(t){var i=new MessageChannel;i.port1.onmessage=function(c){t(c.data)},n.postMessage(r,[i.port2])})}function W(n){var r=function(t,i){if(typeof t!="object"||!t)return t;var c=t[Symbol.toPrimitive];if(c!==void 0){var h=c.call(t,i);if(typeof h!="object")return h;throw new TypeError("@@toPrimitive must return a primitive value.")}return String(t)}(n,"string");return typeof r=="symbol"?r:r+""}function k(n,r){for(var t=0;tn.length)&&(r=n.length);for(var t=0,i=new Array(r);t=n.length?{done:!0}:{done:!1,value:n[i++]}}}throw new TypeError(`Invalid attempt to iterate non-iterable instance. +In order to be iterable, non-array objects must have a [Symbol.iterator]() method.`)}try{self["workbox:core:7.2.0"]&&_()}catch{}var w=function(){var n=this;this.promise=new Promise(function(r,t){n.resolve=r,n.reject=t})};function b(n,r){var t=location.href;return new URL(n,t).href===new URL(r,t).href}var g=function(n,r){this.type=n,Object.assign(this,r)};function d(n,r,t){return t?r?r(n):n:(n&&n.then||(n=Promise.resolve(n)),r?n.then(r):n)}function O(){}var x={type:"SKIP_WAITING"};function S(n,r){return n&&n.then?n.then(O):Promise.resolve()}var U=function(n){function r(v,u){var e,o;return u===void 0&&(u={}),(e=n.call(this)||this).nn={},e.tn=0,e.rn=new w,e.en=new w,e.on=new w,e.un=0,e.an=new Set,e.cn=function(){var s=e.fn,a=s.installing;e.tn>0||!b(a.scriptURL,e.sn.toString())||performance.now()>e.un+6e4?(e.vn=a,s.removeEventListener("updatefound",e.cn)):(e.hn=a,e.an.add(a),e.rn.resolve(a)),++e.tn,a.addEventListener("statechange",e.ln)},e.ln=function(s){var a=e.fn,f=s.target,p=f.state,m=f===e.vn,y={sw:f,isExternal:m,originalEvent:s};!m&&e.mn&&(y.isUpdate=!0),e.dispatchEvent(new g(p,y)),p==="installed"?e.wn=self.setTimeout(function(){p==="installed"&&a.waiting===f&&e.dispatchEvent(new g("waiting",y))},200):p==="activating"&&(clearTimeout(e.wn),m||e.en.resolve(f))},e.yn=function(s){var a=e.hn,f=a!==navigator.serviceWorker.controller;e.dispatchEvent(new g("controlling",{isExternal:f,originalEvent:s,sw:a,isUpdate:e.mn})),f||e.on.resolve(a)},e.gn=(o=function(s){var a=s.data,f=s.ports,p=s.source;return d(e.getSW(),function(){e.an.has(p)&&e.dispatchEvent(new g("message",{data:a,originalEvent:s,ports:f,sw:p}))})},function(){for(var s=[],a=0;a - - - - - - NoteJS Backend - - - + + + + + + NoteJS - Система заметок + + + + + - - -
    -
    🚀
    -

    NoteJS Backend API

    - -
    ✅ Сервер работает
    - -
    -

    Это Backend API сервер NoteJS React.

    -

    Для доступа к приложению используйте Frontend:

    -
    - -
    - Frontend (Development):
    - http://localhost:5173 -
    - - Открыть приложение - -
    -

    Backend API: http://localhost:3001

    -

    - Endpoints: /api/auth, /api/notes, /api/user, /api/ai -

    -
    -
    - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    + + diff --git a/backend/public/manifest.json b/backend/public/manifest.json index a346426..ac17bce 100644 --- a/backend/public/manifest.json +++ b/backend/public/manifest.json @@ -13,6 +13,23 @@ "categories": ["productivity", "utilities"], "prefer_related_applications": false, "display_override": ["window-controls-overlay", "standalone"], + "dir": "ltr", + "shortcuts": [ + { + "name": "Новая заметка", + "short_name": "Новая", + "description": "Создать новую заметку", + "url": "/notes?new=true", + "icons": [{ "src": "/icons/icon-192x192.png", "sizes": "192x192" }] + }, + { + "name": "Мой профиль", + "short_name": "Профиль", + "description": "Открыть профиль", + "url": "/profile", + "icons": [{ "src": "/icons/icon-192x192.png", "sizes": "192x192" }] + } + ], "screenshots": [ { "src": "/icons/icon-512x512.png", diff --git a/backend/public/manifest.webmanifest b/backend/public/manifest.webmanifest new file mode 100644 index 0000000..e54a957 --- /dev/null +++ b/backend/public/manifest.webmanifest @@ -0,0 +1 @@ +{"name":"NoteJS - Система заметок","short_name":"NoteJS","start_url":"/","display":"standalone","background_color":"#ffffff","lang":"en","scope":"/","description":"Современная система заметок с поддержкой Markdown, изображений, тегов и календаря","theme_color":"#007bff","orientation":"portrait-primary","icons":[{"src":"/icons/icon-72x72.png","sizes":"72x72","type":"image/png","purpose":"any"},{"src":"/icons/icon-96x96.png","sizes":"96x96","type":"image/png","purpose":"any"},{"src":"/icons/icon-128x128.png","sizes":"128x128","type":"image/png","purpose":"any"},{"src":"/icons/icon-144x144.png","sizes":"144x144","type":"image/png","purpose":"any"},{"src":"/icons/icon-152x152.png","sizes":"152x152","type":"image/png","purpose":"any"},{"src":"/icons/icon-192x192.png","sizes":"192x192","type":"image/png","purpose":"any"},{"src":"/icons/icon-384x384.png","sizes":"384x384","type":"image/png","purpose":"any"},{"src":"/icons/icon-512x512.png","sizes":"512x512","type":"image/png","purpose":"any"},{"src":"/icons/icon-192x192.png","sizes":"192x192","type":"image/png","purpose":"maskable"},{"src":"/icons/icon-512x512.png","sizes":"512x512","type":"image/png","purpose":"maskable"}]} diff --git a/backend/public/sw.js b/backend/public/sw.js index 3bee337..0f41c4a 100644 --- a/backend/public/sw.js +++ b/backend/public/sw.js @@ -1,17 +1 @@ -// NoteJS Backend Service Worker -// Минимальный SW для предотвращения ошибок - -self.addEventListener("install", (event) => { - console.log("Backend SW installed"); - self.skipWaiting(); -}); - -self.addEventListener("activate", (event) => { - console.log("Backend SW activated"); - event.waitUntil(self.clients.claim()); -}); - -self.addEventListener("fetch", (event) => { - // Просто пропускаем все запросы через сеть - event.respondWith(fetch(event.request)); -}); +if(!self.define){let e,i={};const n=(n,c)=>(n=new URL(n+".js",c).href,i[n]||new Promise(i=>{if("document"in self){const e=document.createElement("script");e.src=n,e.onload=i,document.head.appendChild(e)}else e=n,importScripts(n),i()}).then(()=>{let e=i[n];if(!e)throw new Error(`Module ${n} didn’t register its module`);return e}));self.define=(c,o)=>{const s=e||("document"in self?document.currentScript.src:"")||location.href;if(i[s])return;let r={};const d=e=>n(e,s),a={module:{uri:s},exports:r,require:d};i[s]=Promise.all(c.map(e=>a[e]||d(e))).then(e=>(o(...e),r))}}define(["./workbox-57555046"],function(e){"use strict";self.addEventListener("message",e=>{e.data&&"SKIP_WAITING"===e.data.type&&self.skipWaiting()}),e.precacheAndRoute([{url:"assets/index-CRKRzJj1.js",revision:null},{url:"assets/index-QEK5TGz3.css",revision:null},{url:"assets/workbox-window.prod.es5-B9K5rw8f.js",revision:null},{url:"icon.svg",revision:"537ae73d8f9e90e6a01816aa6d527d16"},{url:"icons/icon-128x128.png",revision:"fa71db17e345406d5f7d847f88c65ac4"},{url:"icons/icon-144x144.png",revision:"e790ff42758ea1a2a46eb84201630757"},{url:"icons/icon-152x152.png",revision:"88f2400f6617a32cc9cd62c70fb49a05"},{url:"icons/icon-16x16.png",revision:"101c13808e9fd0956f247bc446a8ac1e"},{url:"icons/icon-192x192.png",revision:"7d86d2d2ada99d7cee015dff0fdcb497"},{url:"icons/icon-32x32.png",revision:"22ee5d42535bc339ab0e19cb496378a5"},{url:"icons/icon-384x384.png",revision:"c601fa602952a903389e5e8f8a699617"},{url:"icons/icon-48x48.png",revision:"cfdd3bebd931375f2e0277d638ec8781"},{url:"icons/icon-512x512.png",revision:"8731edef999b9e7deba310d72a739925"},{url:"icons/icon-72x72.png",revision:"6b3cb1b2537ec91921698260a9c2f47c"},{url:"icons/icon-96x96.png",revision:"7efd757a81217207d981de88ef199d86"},{url:"index.html",revision:"52c85beb0841c0c7c8ddf774370cff39"},{url:"logo.svg",revision:"11616ede8898b4c24203e331b3ec6dc3"},{url:"icons/icon-72x72.png",revision:"6b3cb1b2537ec91921698260a9c2f47c"},{url:"icons/icon-96x96.png",revision:"7efd757a81217207d981de88ef199d86"},{url:"icons/icon-128x128.png",revision:"fa71db17e345406d5f7d847f88c65ac4"},{url:"icons/icon-144x144.png",revision:"e790ff42758ea1a2a46eb84201630757"},{url:"icons/icon-152x152.png",revision:"88f2400f6617a32cc9cd62c70fb49a05"},{url:"icons/icon-192x192.png",revision:"7d86d2d2ada99d7cee015dff0fdcb497"},{url:"icons/icon-384x384.png",revision:"c601fa602952a903389e5e8f8a699617"},{url:"icons/icon-512x512.png",revision:"8731edef999b9e7deba310d72a739925"},{url:"manifest.webmanifest",revision:"1c071cadebd7a1b0dc1eeb0270e73fb8"}],{}),e.cleanupOutdatedCaches(),e.registerRoute(new e.NavigationRoute(e.createHandlerBoundToURL("index.html"))),e.registerRoute(/^https:\/\/api\./i,new e.NetworkFirst({cacheName:"api-cache",networkTimeoutSeconds:10,plugins:[new e.ExpirationPlugin({maxEntries:50,maxAgeSeconds:86400})]}),"GET"),e.registerRoute(/\.(?:png|jpg|jpeg|svg|gif|webp)$/i,new e.CacheFirst({cacheName:"image-cache",plugins:[new e.ExpirationPlugin({maxEntries:100,maxAgeSeconds:2592e3})]}),"GET")}); diff --git a/backend/public/workbox-57555046.js b/backend/public/workbox-57555046.js new file mode 100644 index 0000000..ed24ae5 --- /dev/null +++ b/backend/public/workbox-57555046.js @@ -0,0 +1 @@ +define(["exports"],function(t){"use strict";try{self["workbox:core:7.2.0"]&&_()}catch(t){}const e=(t,...e)=>{let s=t;return e.length>0&&(s+=` :: ${JSON.stringify(e)}`),s};class s extends Error{constructor(t,s){super(e(t,s)),this.name=t,this.details=s}}try{self["workbox:routing:7.2.0"]&&_()}catch(t){}const n=t=>t&&"object"==typeof t?t:{handle:t};class i{constructor(t,e,s="GET"){this.handler=n(e),this.match=t,this.method=s}setCatchHandler(t){this.catchHandler=n(t)}}class r extends i{constructor(t,e,s){super(({url:e})=>{const s=t.exec(e.href);if(s&&(e.origin===location.origin||0===s.index))return s.slice(1)},e,s)}}class a{constructor(){this.t=new Map,this.i=new Map}get routes(){return this.t}addFetchListener(){self.addEventListener("fetch",t=>{const{request:e}=t,s=this.handleRequest({request:e,event:t});s&&t.respondWith(s)})}addCacheListener(){self.addEventListener("message",t=>{if(t.data&&"CACHE_URLS"===t.data.type){const{payload:e}=t.data,s=Promise.all(e.urlsToCache.map(e=>{"string"==typeof e&&(e=[e]);const s=new Request(...e);return this.handleRequest({request:s,event:t})}));t.waitUntil(s),t.ports&&t.ports[0]&&s.then(()=>t.ports[0].postMessage(!0))}})}handleRequest({request:t,event:e}){const s=new URL(t.url,location.href);if(!s.protocol.startsWith("http"))return;const n=s.origin===location.origin,{params:i,route:r}=this.findMatchingRoute({event:e,request:t,sameOrigin:n,url:s});let a=r&&r.handler;const o=t.method;if(!a&&this.i.has(o)&&(a=this.i.get(o)),!a)return;let c;try{c=a.handle({url:s,request:t,event:e,params:i})}catch(t){c=Promise.reject(t)}const h=r&&r.catchHandler;return c instanceof Promise&&(this.o||h)&&(c=c.catch(async n=>{if(h)try{return await h.handle({url:s,request:t,event:e,params:i})}catch(t){t instanceof Error&&(n=t)}if(this.o)return this.o.handle({url:s,request:t,event:e});throw n})),c}findMatchingRoute({url:t,sameOrigin:e,request:s,event:n}){const i=this.t.get(s.method)||[];for(const r of i){let i;const a=r.match({url:t,sameOrigin:e,request:s,event:n});if(a)return i=a,(Array.isArray(i)&&0===i.length||a.constructor===Object&&0===Object.keys(a).length||"boolean"==typeof a)&&(i=void 0),{route:r,params:i}}return{}}setDefaultHandler(t,e="GET"){this.i.set(e,n(t))}setCatchHandler(t){this.o=n(t)}registerRoute(t){this.t.has(t.method)||this.t.set(t.method,[]),this.t.get(t.method).push(t)}unregisterRoute(t){if(!this.t.has(t.method))throw new s("unregister-route-but-not-found-with-method",{method:t.method});const e=this.t.get(t.method).indexOf(t);if(!(e>-1))throw new s("unregister-route-route-not-registered");this.t.get(t.method).splice(e,1)}}let o;const c=()=>(o||(o=new a,o.addFetchListener(),o.addCacheListener()),o);function h(t,e,n){let a;if("string"==typeof t){const s=new URL(t,location.href);a=new i(({url:t})=>t.href===s.href,e,n)}else if(t instanceof RegExp)a=new r(t,e,n);else if("function"==typeof t)a=new i(t,e,n);else{if(!(t instanceof i))throw new s("unsupported-route-type",{moduleName:"workbox-routing",funcName:"registerRoute",paramName:"capture"});a=t}return c().registerRoute(a),a}const u={googleAnalytics:"googleAnalytics",precache:"precache-v2",prefix:"workbox",runtime:"runtime",suffix:"undefined"!=typeof registration?registration.scope:""},l=t=>[u.prefix,t,u.suffix].filter(t=>t&&t.length>0).join("-"),f=t=>t||l(u.precache),w=t=>t||l(u.runtime);function d(t){t.then(()=>{})}const p=new Set;function y(){return y=Object.assign?Object.assign.bind():function(t){for(var e=1;e(t[e]=s,!0),has:(t,e)=>t instanceof IDBTransaction&&("done"===e||"store"===e)||e in t};function x(t){return t!==IDBDatabase.prototype.transaction||"objectStoreNames"in IDBTransaction.prototype?(g||(g=[IDBCursor.prototype.advance,IDBCursor.prototype.continue,IDBCursor.prototype.continuePrimaryKey])).includes(t)?function(...e){return t.apply(E(this),e),L(R.get(this))}:function(...e){return L(t.apply(E(this),e))}:function(e,...s){const n=t.call(E(this),e,...s);return b.set(n,e.sort?e.sort():[e]),L(n)}}function I(t){return"function"==typeof t?x(t):(t instanceof IDBTransaction&&function(t){if(v.has(t))return;const e=new Promise((e,s)=>{const n=()=>{t.removeEventListener("complete",i),t.removeEventListener("error",r),t.removeEventListener("abort",r)},i=()=>{e(),n()},r=()=>{s(t.error||new DOMException("AbortError","AbortError")),n()};t.addEventListener("complete",i),t.addEventListener("error",r),t.addEventListener("abort",r)});v.set(t,e)}(t),e=t,(m||(m=[IDBDatabase,IDBObjectStore,IDBIndex,IDBCursor,IDBTransaction])).some(t=>e instanceof t)?new Proxy(t,U):t);var e}function L(t){if(t instanceof IDBRequest)return function(t){const e=new Promise((e,s)=>{const n=()=>{t.removeEventListener("success",i),t.removeEventListener("error",r)},i=()=>{e(L(t.result)),n()},r=()=>{s(t.error),n()};t.addEventListener("success",i),t.addEventListener("error",r)});return e.then(e=>{e instanceof IDBCursor&&R.set(e,t)}).catch(()=>{}),D.set(e,t),e}(t);if(q.has(t))return q.get(t);const e=I(t);return e!==t&&(q.set(t,e),D.set(e,t)),e}const E=t=>D.get(t);const C=["get","getKey","getAll","getAllKeys","count"],N=["put","add","delete","clear"],O=new Map;function k(t,e){if(!(t instanceof IDBDatabase)||e in t||"string"!=typeof e)return;if(O.get(e))return O.get(e);const s=e.replace(/FromIndex$/,""),n=e!==s,i=N.includes(s);if(!(s in(n?IDBIndex:IDBObjectStore).prototype)||!i&&!C.includes(s))return;const r=async function(t,...e){const r=this.transaction(t,i?"readwrite":"readonly");let a=r.store;return n&&(a=a.index(e.shift())),(await Promise.all([a[s](...e),i&&r.done]))[0]};return O.set(e,r),r}U=(t=>y({},t,{get:(e,s,n)=>k(e,s)||t.get(e,s,n),has:(e,s)=>!!k(e,s)||t.has(e,s)}))(U);try{self["workbox:expiration:7.2.0"]&&_()}catch(t){}const B="cache-entries",T=t=>{const e=new URL(t,location.href);return e.hash="",e.href};class M{constructor(t){this.h=null,this.u=t}l(t){const e=t.createObjectStore(B,{keyPath:"id"});e.createIndex("cacheName","cacheName",{unique:!1}),e.createIndex("timestamp","timestamp",{unique:!1})}p(t){this.l(t),this.u&&function(t,{blocked:e}={}){const s=indexedDB.deleteDatabase(t);e&&s.addEventListener("blocked",t=>e(t.oldVersion,t)),L(s).then(()=>{})}(this.u)}async setTimestamp(t,e){const s={url:t=T(t),timestamp:e,cacheName:this.u,id:this.m(t)},n=(await this.getDb()).transaction(B,"readwrite",{durability:"relaxed"});await n.store.put(s),await n.done}async getTimestamp(t){const e=await this.getDb(),s=await e.get(B,this.m(t));return null==s?void 0:s.timestamp}async expireEntries(t,e){const s=await this.getDb();let n=await s.transaction(B).store.index("timestamp").openCursor(null,"prev");const i=[];let r=0;for(;n;){const s=n.value;s.cacheName===this.u&&(t&&s.timestamp=e?i.push(n.value):r++),n=await n.continue()}const a=[];for(const t of i)await s.delete(B,t.id),a.push(t.url);return a}m(t){return this.u+"|"+T(t)}async getDb(){return this.h||(this.h=await function(t,e,{blocked:s,upgrade:n,blocking:i,terminated:r}={}){const a=indexedDB.open(t,e),o=L(a);return n&&a.addEventListener("upgradeneeded",t=>{n(L(a.result),t.oldVersion,t.newVersion,L(a.transaction),t)}),s&&a.addEventListener("blocked",t=>s(t.oldVersion,t.newVersion,t)),o.then(t=>{r&&t.addEventListener("close",()=>r()),i&&t.addEventListener("versionchange",t=>i(t.oldVersion,t.newVersion,t))}).catch(()=>{}),o}("workbox-expiration",1,{upgrade:this.p.bind(this)})),this.h}}class P{constructor(t,e={}){this.R=!1,this.v=!1,this.q=e.maxEntries,this.D=e.maxAgeSeconds,this.U=e.matchOptions,this.u=t,this._=new M(t)}async expireEntries(){if(this.R)return void(this.v=!0);this.R=!0;const t=this.D?Date.now()-1e3*this.D:0,e=await this._.expireEntries(t,this.q),s=await self.caches.open(this.u);for(const t of e)await s.delete(t,this.U);this.R=!1,this.v&&(this.v=!1,d(this.expireEntries()))}async updateTimestamp(t){await this._.setTimestamp(t,Date.now())}async isURLExpired(t){if(this.D){const e=await this._.getTimestamp(t),s=Date.now()-1e3*this.D;return void 0===e||e200===t.status||0===t.status?t:null};function j(t,e){const s=new URL(t);for(const t of e)s.searchParams.delete(t);return s.href}class S{constructor(){this.promise=new Promise((t,e)=>{this.resolve=t,this.reject=e})}}function K(t){return"string"==typeof t?new Request(t):t}class A{constructor(t,e){this.I={},Object.assign(this,e),this.event=e.event,this.L=t,this.C=new S,this.N=[],this.O=[...t.plugins],this.k=new Map;for(const t of this.O)this.k.set(t,{});this.event.waitUntil(this.C.promise)}async fetch(t){const{event:e}=this;let n=K(t);if("navigate"===n.mode&&e instanceof FetchEvent&&e.preloadResponse){const t=await e.preloadResponse;if(t)return t}const i=this.hasCallback("fetchDidFail")?n.clone():null;try{for(const t of this.iterateCallbacks("requestWillFetch"))n=await t({request:n.clone(),event:e})}catch(t){if(t instanceof Error)throw new s("plugin-error-request-will-fetch",{thrownErrorMessage:t.message})}const r=n.clone();try{let t;t=await fetch(n,"navigate"===n.mode?void 0:this.L.fetchOptions);for(const s of this.iterateCallbacks("fetchDidSucceed"))t=await s({event:e,request:r,response:t});return t}catch(t){throw i&&await this.runCallbacks("fetchDidFail",{error:t,event:e,originalRequest:i.clone(),request:r.clone()}),t}}async fetchAndCachePut(t){const e=await this.fetch(t),s=e.clone();return this.waitUntil(this.cachePut(t,s)),e}async cacheMatch(t){const e=K(t);let s;const{cacheName:n,matchOptions:i}=this.L,r=await this.getCacheKey(e,"read"),a=Object.assign(Object.assign({},i),{cacheName:n});s=await caches.match(r,a);for(const t of this.iterateCallbacks("cachedResponseWillBeUsed"))s=await t({cacheName:n,matchOptions:i,cachedResponse:s,request:r,event:this.event})||void 0;return s}async cachePut(t,e){const n=K(t);var i;await(i=0,new Promise(t=>setTimeout(t,i)));const r=await this.getCacheKey(n,"write");if(!e)throw new s("cache-put-with-no-response",{url:(a=r.url,new URL(String(a),location.href).href.replace(new RegExp(`^${location.origin}`),""))});var a;const o=await this.B(e);if(!o)return!1;const{cacheName:c,matchOptions:h}=this.L,u=await self.caches.open(c),l=this.hasCallback("cacheDidUpdate"),f=l?await async function(t,e,s,n){const i=j(e.url,s);if(e.url===i)return t.match(e,n);const r=Object.assign(Object.assign({},n),{ignoreSearch:!0}),a=await t.keys(e,r);for(const e of a)if(i===j(e.url,s))return t.match(e,n)}(u,r.clone(),["__WB_REVISION__"],h):null;try{await u.put(r,l?o.clone():o)}catch(t){if(t instanceof Error)throw"QuotaExceededError"===t.name&&await async function(){for(const t of p)await t()}(),t}for(const t of this.iterateCallbacks("cacheDidUpdate"))await t({cacheName:c,oldResponse:f,newResponse:o.clone(),request:r,event:this.event});return!0}async getCacheKey(t,e){const s=`${t.url} | ${e}`;if(!this.I[s]){let n=t;for(const t of this.iterateCallbacks("cacheKeyWillBeUsed"))n=K(await t({mode:e,request:n,event:this.event,params:this.params}));this.I[s]=n}return this.I[s]}hasCallback(t){for(const e of this.L.plugins)if(t in e)return!0;return!1}async runCallbacks(t,e){for(const s of this.iterateCallbacks(t))await s(e)}*iterateCallbacks(t){for(const e of this.L.plugins)if("function"==typeof e[t]){const s=this.k.get(e),n=n=>{const i=Object.assign(Object.assign({},n),{state:s});return e[t](i)};yield n}}waitUntil(t){return this.N.push(t),t}async doneWaiting(){let t;for(;t=this.N.shift();)await t}destroy(){this.C.resolve(null)}async B(t){let e=t,s=!1;for(const t of this.iterateCallbacks("cacheWillUpdate"))if(e=await t({request:this.request,response:e,event:this.event})||void 0,s=!0,!e)break;return s||e&&200!==e.status&&(e=void 0),e}}class F{constructor(t={}){this.cacheName=w(t.cacheName),this.plugins=t.plugins||[],this.fetchOptions=t.fetchOptions,this.matchOptions=t.matchOptions}handle(t){const[e]=this.handleAll(t);return e}handleAll(t){t instanceof FetchEvent&&(t={event:t,request:t.request});const e=t.event,s="string"==typeof t.request?new Request(t.request):t.request,n="params"in t?t.params:void 0,i=new A(this,{event:e,request:s,params:n}),r=this.T(i,s,e);return[r,this.M(r,i,s,e)]}async T(t,e,n){let i;await t.runCallbacks("handlerWillStart",{event:n,request:e});try{if(i=await this.P(e,t),!i||"error"===i.type)throw new s("no-response",{url:e.url})}catch(s){if(s instanceof Error)for(const r of t.iterateCallbacks("handlerDidError"))if(i=await r({error:s,event:n,request:e}),i)break;if(!i)throw s}for(const s of t.iterateCallbacks("handlerWillRespond"))i=await s({event:n,request:e,response:i});return i}async M(t,e,s,n){let i,r;try{i=await t}catch(r){}try{await e.runCallbacks("handlerDidRespond",{event:n,request:s,response:i}),await e.doneWaiting()}catch(t){t instanceof Error&&(r=t)}if(await e.runCallbacks("handlerDidComplete",{event:n,request:s,response:i,error:r}),e.destroy(),r)throw r}}function H(t,e){const s=e();return t.waitUntil(s),s}try{self["workbox:precaching:7.2.0"]&&_()}catch(t){}function $(t){if(!t)throw new s("add-to-cache-list-unexpected-type",{entry:t});if("string"==typeof t){const e=new URL(t,location.href);return{cacheKey:e.href,url:e.href}}const{revision:e,url:n}=t;if(!n)throw new s("add-to-cache-list-unexpected-type",{entry:t});if(!e){const t=new URL(n,location.href);return{cacheKey:t.href,url:t.href}}const i=new URL(n,location.href),r=new URL(n,location.href);return i.searchParams.set("__WB_REVISION__",e),{cacheKey:i.href,url:r.href}}class G{constructor(){this.updatedURLs=[],this.notUpdatedURLs=[],this.handlerWillStart=async({request:t,state:e})=>{e&&(e.originalRequest=t)},this.cachedResponseWillBeUsed=async({event:t,state:e,cachedResponse:s})=>{if("install"===t.type&&e&&e.originalRequest&&e.originalRequest instanceof Request){const t=e.originalRequest.url;s?this.notUpdatedURLs.push(t):this.updatedURLs.push(t)}return s}}}class V{constructor({precacheController:t}){this.cacheKeyWillBeUsed=async({request:t,params:e})=>{const s=(null==e?void 0:e.cacheKey)||this.W.getCacheKeyForURL(t.url);return s?new Request(s,{headers:t.headers}):t},this.W=t}}let J,Q;async function z(t,e){let n=null;if(t.url){n=new URL(t.url).origin}if(n!==self.location.origin)throw new s("cross-origin-copy-response",{origin:n});const i=t.clone(),r={headers:new Headers(i.headers),status:i.status,statusText:i.statusText},a=e?e(r):r,o=function(){if(void 0===J){const t=new Response("");if("body"in t)try{new Response(t.body),J=!0}catch(t){J=!1}J=!1}return J}()?i.body:await i.blob();return new Response(o,a)}class X extends F{constructor(t={}){t.cacheName=f(t.cacheName),super(t),this.j=!1!==t.fallbackToNetwork,this.plugins.push(X.copyRedirectedCacheableResponsesPlugin)}async P(t,e){const s=await e.cacheMatch(t);return s||(e.event&&"install"===e.event.type?await this.S(t,e):await this.K(t,e))}async K(t,e){let n;const i=e.params||{};if(!this.j)throw new s("missing-precache-entry",{cacheName:this.cacheName,url:t.url});{const s=i.integrity,r=t.integrity,a=!r||r===s;n=await e.fetch(new Request(t,{integrity:"no-cors"!==t.mode?r||s:void 0})),s&&a&&"no-cors"!==t.mode&&(this.A(),await e.cachePut(t,n.clone()))}return n}async S(t,e){this.A();const n=await e.fetch(t);if(!await e.cachePut(t,n.clone()))throw new s("bad-precaching-response",{url:t.url,status:n.status});return n}A(){let t=null,e=0;for(const[s,n]of this.plugins.entries())n!==X.copyRedirectedCacheableResponsesPlugin&&(n===X.defaultPrecacheCacheabilityPlugin&&(t=s),n.cacheWillUpdate&&e++);0===e?this.plugins.push(X.defaultPrecacheCacheabilityPlugin):e>1&&null!==t&&this.plugins.splice(t,1)}}X.defaultPrecacheCacheabilityPlugin={cacheWillUpdate:async({response:t})=>!t||t.status>=400?null:t},X.copyRedirectedCacheableResponsesPlugin={cacheWillUpdate:async({response:t})=>t.redirected?await z(t):t};class Y{constructor({cacheName:t,plugins:e=[],fallbackToNetwork:s=!0}={}){this.F=new Map,this.H=new Map,this.$=new Map,this.L=new X({cacheName:f(t),plugins:[...e,new V({precacheController:this})],fallbackToNetwork:s}),this.install=this.install.bind(this),this.activate=this.activate.bind(this)}get strategy(){return this.L}precache(t){this.addToCacheList(t),this.G||(self.addEventListener("install",this.install),self.addEventListener("activate",this.activate),this.G=!0)}addToCacheList(t){const e=[];for(const n of t){"string"==typeof n?e.push(n):n&&void 0===n.revision&&e.push(n.url);const{cacheKey:t,url:i}=$(n),r="string"!=typeof n&&n.revision?"reload":"default";if(this.F.has(i)&&this.F.get(i)!==t)throw new s("add-to-cache-list-conflicting-entries",{firstEntry:this.F.get(i),secondEntry:t});if("string"!=typeof n&&n.integrity){if(this.$.has(t)&&this.$.get(t)!==n.integrity)throw new s("add-to-cache-list-conflicting-integrities",{url:i});this.$.set(t,n.integrity)}if(this.F.set(i,t),this.H.set(i,r),e.length>0){const t=`Workbox is precaching URLs without revision info: ${e.join(", ")}\nThis is generally NOT safe. Learn more at https://bit.ly/wb-precache`;console.warn(t)}}}install(t){return H(t,async()=>{const e=new G;this.strategy.plugins.push(e);for(const[e,s]of this.F){const n=this.$.get(s),i=this.H.get(e),r=new Request(e,{integrity:n,cache:i,credentials:"same-origin"});await Promise.all(this.strategy.handleAll({params:{cacheKey:s},request:r,event:t}))}const{updatedURLs:s,notUpdatedURLs:n}=e;return{updatedURLs:s,notUpdatedURLs:n}})}activate(t){return H(t,async()=>{const t=await self.caches.open(this.strategy.cacheName),e=await t.keys(),s=new Set(this.F.values()),n=[];for(const i of e)s.has(i.url)||(await t.delete(i),n.push(i.url));return{deletedURLs:n}})}getURLsToCacheKeys(){return this.F}getCachedURLs(){return[...this.F.keys()]}getCacheKeyForURL(t){const e=new URL(t,location.href);return this.F.get(e.href)}getIntegrityForCacheKey(t){return this.$.get(t)}async matchPrecache(t){const e=t instanceof Request?t.url:t,s=this.getCacheKeyForURL(e);if(s){return(await self.caches.open(this.strategy.cacheName)).match(s)}}createHandlerBoundToURL(t){const e=this.getCacheKeyForURL(t);if(!e)throw new s("non-precached-url",{url:t});return s=>(s.request=new Request(t),s.params=Object.assign({cacheKey:e},s.params),this.strategy.handle(s))}}const Z=()=>(Q||(Q=new Y),Q);class tt extends i{constructor(t,e){super(({request:s})=>{const n=t.getURLsToCacheKeys();for(const i of function*(t,{ignoreURLParametersMatching:e=[/^utm_/,/^fbclid$/],directoryIndex:s="index.html",cleanURLs:n=!0,urlManipulation:i}={}){const r=new URL(t,location.href);r.hash="",yield r.href;const a=function(t,e=[]){for(const s of[...t.searchParams.keys()])e.some(t=>t.test(s))&&t.searchParams.delete(s);return t}(r,e);if(yield a.href,s&&a.pathname.endsWith("/")){const t=new URL(a.href);t.pathname+=s,yield t.href}if(n){const t=new URL(a.href);t.pathname+=".html",yield t.href}if(i){const t=i({url:r});for(const e of t)yield e.href}}(s.url,e)){const e=n.get(i);if(e){return{cacheKey:e,integrity:t.getIntegrityForCacheKey(e)}}}},t.strategy)}}t.CacheFirst=class extends F{async P(t,e){let n,i=await e.cacheMatch(t);if(!i)try{i=await e.fetchAndCachePut(t)}catch(t){t instanceof Error&&(n=t)}if(!i)throw new s("no-response",{url:t.url,error:n});return i}},t.ExpirationPlugin=class{constructor(t={}){this.cachedResponseWillBeUsed=async({event:t,request:e,cacheName:s,cachedResponse:n})=>{if(!n)return null;const i=this.V(n),r=this.J(s);d(r.expireEntries());const a=r.updateTimestamp(e.url);if(t)try{t.waitUntil(a)}catch(t){}return i?n:null},this.cacheDidUpdate=async({cacheName:t,request:e})=>{const s=this.J(t);await s.updateTimestamp(e.url),await s.expireEntries()},this.X=t,this.D=t.maxAgeSeconds,this.Y=new Map,t.purgeOnQuotaError&&function(t){p.add(t)}(()=>this.deleteCacheAndMetadata())}J(t){if(t===w())throw new s("expire-custom-caches-only");let e=this.Y.get(t);return e||(e=new P(t,this.X),this.Y.set(t,e)),e}V(t){if(!this.D)return!0;const e=this.Z(t);if(null===e)return!0;return e>=Date.now()-1e3*this.D}Z(t){if(!t.headers.has("date"))return null;const e=t.headers.get("date"),s=new Date(e).getTime();return isNaN(s)?null:s}async deleteCacheAndMetadata(){for(const[t,e]of this.Y)await self.caches.delete(t),await e.delete();this.Y=new Map}},t.NavigationRoute=class extends i{constructor(t,{allowlist:e=[/./],denylist:s=[]}={}){super(t=>this.tt(t),t),this.et=e,this.st=s}tt({url:t,request:e}){if(e&&"navigate"!==e.mode)return!1;const s=t.pathname+t.search;for(const t of this.st)if(t.test(s))return!1;return!!this.et.some(t=>t.test(s))}},t.NetworkFirst=class extends F{constructor(t={}){super(t),this.plugins.some(t=>"cacheWillUpdate"in t)||this.plugins.unshift(W),this.nt=t.networkTimeoutSeconds||0}async P(t,e){const n=[],i=[];let r;if(this.nt){const{id:s,promise:a}=this.it({request:t,logs:n,handler:e});r=s,i.push(a)}const a=this.rt({timeoutId:r,request:t,logs:n,handler:e});i.push(a);const o=await e.waitUntil((async()=>await e.waitUntil(Promise.race(i))||await a)());if(!o)throw new s("no-response",{url:t.url});return o}it({request:t,logs:e,handler:s}){let n;return{promise:new Promise(e=>{n=setTimeout(async()=>{e(await s.cacheMatch(t))},1e3*this.nt)}),id:n}}async rt({timeoutId:t,request:e,logs:s,handler:n}){let i,r;try{r=await n.fetchAndCachePut(e)}catch(t){t instanceof Error&&(i=t)}return t&&clearTimeout(t),!i&&r||(r=await n.cacheMatch(e)),r}},t.cleanupOutdatedCaches=function(){self.addEventListener("activate",t=>{const e=f();t.waitUntil((async(t,e="-precache-")=>{const s=(await self.caches.keys()).filter(s=>s.includes(e)&&s.includes(self.registration.scope)&&s!==t);return await Promise.all(s.map(t=>self.caches.delete(t))),s})(e).then(t=>{}))})},t.createHandlerBoundToURL=function(t){return Z().createHandlerBoundToURL(t)},t.precacheAndRoute=function(t,e){!function(t){Z().precache(t)}(t),function(t){const e=Z();h(new tt(e,t))}(e)},t.registerRoute=h}); diff --git a/dev-dist/registerSW.js b/dev-dist/registerSW.js new file mode 100644 index 0000000..1d5625f --- /dev/null +++ b/dev-dist/registerSW.js @@ -0,0 +1 @@ +if('serviceWorker' in navigator) navigator.serviceWorker.register('/dev-sw.js?dev-sw', { scope: '/', type: 'classic' }) \ No newline at end of file diff --git a/dev-dist/sw.js b/dev-dist/sw.js new file mode 100644 index 0000000..0fc6f17 --- /dev/null +++ b/dev-dist/sw.js @@ -0,0 +1,109 @@ +/** + * Copyright 2018 Google Inc. All Rights Reserved. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * http://www.apache.org/licenses/LICENSE-2.0 + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +// If the loader is already loaded, just stop. +if (!self.define) { + let registry = {}; + + // Used for `eval` and `importScripts` where we can't get script URL by other means. + // In both cases, it's safe to use a global var because those functions are synchronous. + let nextDefineUri; + + const singleRequire = (uri, parentUri) => { + uri = new URL(uri + ".js", parentUri).href; + return registry[uri] || ( + + new Promise(resolve => { + if ("document" in self) { + const script = document.createElement("script"); + script.src = uri; + script.onload = resolve; + document.head.appendChild(script); + } else { + nextDefineUri = uri; + importScripts(uri); + resolve(); + } + }) + + .then(() => { + let promise = registry[uri]; + if (!promise) { + throw new Error(`Module ${uri} didn’t register its module`); + } + return promise; + }) + ); + }; + + self.define = (depsNames, factory) => { + const uri = nextDefineUri || ("document" in self ? document.currentScript.src : "") || location.href; + if (registry[uri]) { + // Module is already loading or loaded. + return; + } + let exports = {}; + const require = depUri => singleRequire(depUri, uri); + const specialDeps = { + module: { uri }, + exports, + require + }; + registry[uri] = Promise.all(depsNames.map( + depName => specialDeps[depName] || require(depName) + )).then(deps => { + factory(...deps); + return exports; + }); + }; +} +define(['./workbox-8cfb3eb5'], (function (workbox) { 'use strict'; + + self.addEventListener('message', event => { + if (event.data && event.data.type === 'SKIP_WAITING') { + self.skipWaiting(); + } + }); + + /** + * The precacheAndRoute() method efficiently caches and responds to + * requests for URLs in the manifest. + * See https://goo.gl/S9QRab + */ + workbox.precacheAndRoute([{ + "url": "registerSW.js", + "revision": "3ca0b8505b4bec776b69afdba2768812" + }, { + "url": "index.html", + "revision": "0.h9luj2l3mv8" + }], {}); + workbox.cleanupOutdatedCaches(); + workbox.registerRoute(new workbox.NavigationRoute(workbox.createHandlerBoundToURL("index.html"), { + allowlist: [/^\/$/] + })); + workbox.registerRoute(/^https:\/\/api\./, new workbox.NetworkFirst({ + "cacheName": "api-cache", + plugins: [new workbox.ExpirationPlugin({ + maxEntries: 50, + maxAgeSeconds: 3600 + })] + }), 'GET'); + workbox.registerRoute(/\.(?:png|jpg|jpeg|svg|gif|webp)$/, new workbox.CacheFirst({ + "cacheName": "images-cache", + plugins: [new workbox.ExpirationPlugin({ + maxEntries: 100, + maxAgeSeconds: 2592000 + })] + }), 'GET'); + +})); diff --git a/dev-dist/workbox-8cfb3eb5.js b/dev-dist/workbox-8cfb3eb5.js new file mode 100644 index 0000000..32efc37 --- /dev/null +++ b/dev-dist/workbox-8cfb3eb5.js @@ -0,0 +1,4600 @@ +define(['exports'], (function (exports) { 'use strict'; + + // @ts-ignore + try { + self['workbox:core:7.2.0'] && _(); + } catch (e) {} + + /* + Copyright 2019 Google LLC + Use of this source code is governed by an MIT-style + license that can be found in the LICENSE file or at + https://opensource.org/licenses/MIT. + */ + const logger = (() => { + // Don't overwrite this value if it's already set. + // See https://github.com/GoogleChrome/workbox/pull/2284#issuecomment-560470923 + if (!('__WB_DISABLE_DEV_LOGS' in globalThis)) { + self.__WB_DISABLE_DEV_LOGS = false; + } + let inGroup = false; + const methodToColorMap = { + debug: `#7f8c8d`, + log: `#2ecc71`, + warn: `#f39c12`, + error: `#c0392b`, + groupCollapsed: `#3498db`, + groupEnd: null // No colored prefix on groupEnd + }; + const print = function (method, args) { + if (self.__WB_DISABLE_DEV_LOGS) { + return; + } + if (method === 'groupCollapsed') { + // Safari doesn't print all console.groupCollapsed() arguments: + // https://bugs.webkit.org/show_bug.cgi?id=182754 + if (/^((?!chrome|android).)*safari/i.test(navigator.userAgent)) { + console[method](...args); + return; + } + } + const styles = [`background: ${methodToColorMap[method]}`, `border-radius: 0.5em`, `color: white`, `font-weight: bold`, `padding: 2px 0.5em`]; + // When in a group, the workbox prefix is not displayed. + const logPrefix = inGroup ? [] : ['%cworkbox', styles.join(';')]; + console[method](...logPrefix, ...args); + if (method === 'groupCollapsed') { + inGroup = true; + } + if (method === 'groupEnd') { + inGroup = false; + } + }; + // eslint-disable-next-line @typescript-eslint/ban-types + const api = {}; + const loggerMethods = Object.keys(methodToColorMap); + for (const key of loggerMethods) { + const method = key; + api[method] = (...args) => { + print(method, args); + }; + } + return api; + })(); + + /* + Copyright 2018 Google LLC + + Use of this source code is governed by an MIT-style + license that can be found in the LICENSE file or at + https://opensource.org/licenses/MIT. + */ + const messages$1 = { + 'invalid-value': ({ + paramName, + validValueDescription, + value + }) => { + if (!paramName || !validValueDescription) { + throw new Error(`Unexpected input to 'invalid-value' error.`); + } + return `The '${paramName}' parameter was given a value with an ` + `unexpected value. ${validValueDescription} Received a value of ` + `${JSON.stringify(value)}.`; + }, + 'not-an-array': ({ + moduleName, + className, + funcName, + paramName + }) => { + if (!moduleName || !className || !funcName || !paramName) { + throw new Error(`Unexpected input to 'not-an-array' error.`); + } + return `The parameter '${paramName}' passed into ` + `'${moduleName}.${className}.${funcName}()' must be an array.`; + }, + 'incorrect-type': ({ + expectedType, + paramName, + moduleName, + className, + funcName + }) => { + if (!expectedType || !paramName || !moduleName || !funcName) { + throw new Error(`Unexpected input to 'incorrect-type' error.`); + } + const classNameStr = className ? `${className}.` : ''; + return `The parameter '${paramName}' passed into ` + `'${moduleName}.${classNameStr}` + `${funcName}()' must be of type ${expectedType}.`; + }, + 'incorrect-class': ({ + expectedClassName, + paramName, + moduleName, + className, + funcName, + isReturnValueProblem + }) => { + if (!expectedClassName || !moduleName || !funcName) { + throw new Error(`Unexpected input to 'incorrect-class' error.`); + } + const classNameStr = className ? `${className}.` : ''; + if (isReturnValueProblem) { + return `The return value from ` + `'${moduleName}.${classNameStr}${funcName}()' ` + `must be an instance of class ${expectedClassName}.`; + } + return `The parameter '${paramName}' passed into ` + `'${moduleName}.${classNameStr}${funcName}()' ` + `must be an instance of class ${expectedClassName}.`; + }, + 'missing-a-method': ({ + expectedMethod, + paramName, + moduleName, + className, + funcName + }) => { + if (!expectedMethod || !paramName || !moduleName || !className || !funcName) { + throw new Error(`Unexpected input to 'missing-a-method' error.`); + } + return `${moduleName}.${className}.${funcName}() expected the ` + `'${paramName}' parameter to expose a '${expectedMethod}' method.`; + }, + 'add-to-cache-list-unexpected-type': ({ + entry + }) => { + return `An unexpected entry was passed to ` + `'workbox-precaching.PrecacheController.addToCacheList()' The entry ` + `'${JSON.stringify(entry)}' isn't supported. You must supply an array of ` + `strings with one or more characters, objects with a url property or ` + `Request objects.`; + }, + 'add-to-cache-list-conflicting-entries': ({ + firstEntry, + secondEntry + }) => { + if (!firstEntry || !secondEntry) { + throw new Error(`Unexpected input to ` + `'add-to-cache-list-duplicate-entries' error.`); + } + return `Two of the entries passed to ` + `'workbox-precaching.PrecacheController.addToCacheList()' had the URL ` + `${firstEntry} but different revision details. Workbox is ` + `unable to cache and version the asset correctly. Please remove one ` + `of the entries.`; + }, + 'plugin-error-request-will-fetch': ({ + thrownErrorMessage + }) => { + if (!thrownErrorMessage) { + throw new Error(`Unexpected input to ` + `'plugin-error-request-will-fetch', error.`); + } + return `An error was thrown by a plugins 'requestWillFetch()' method. ` + `The thrown error message was: '${thrownErrorMessage}'.`; + }, + 'invalid-cache-name': ({ + cacheNameId, + value + }) => { + if (!cacheNameId) { + throw new Error(`Expected a 'cacheNameId' for error 'invalid-cache-name'`); + } + return `You must provide a name containing at least one character for ` + `setCacheDetails({${cacheNameId}: '...'}). Received a value of ` + `'${JSON.stringify(value)}'`; + }, + 'unregister-route-but-not-found-with-method': ({ + method + }) => { + if (!method) { + throw new Error(`Unexpected input to ` + `'unregister-route-but-not-found-with-method' error.`); + } + return `The route you're trying to unregister was not previously ` + `registered for the method type '${method}'.`; + }, + 'unregister-route-route-not-registered': () => { + return `The route you're trying to unregister was not previously ` + `registered.`; + }, + 'queue-replay-failed': ({ + name + }) => { + return `Replaying the background sync queue '${name}' failed.`; + }, + 'duplicate-queue-name': ({ + name + }) => { + return `The Queue name '${name}' is already being used. ` + `All instances of backgroundSync.Queue must be given unique names.`; + }, + 'expired-test-without-max-age': ({ + methodName, + paramName + }) => { + return `The '${methodName}()' method can only be used when the ` + `'${paramName}' is used in the constructor.`; + }, + 'unsupported-route-type': ({ + moduleName, + className, + funcName, + paramName + }) => { + return `The supplied '${paramName}' parameter was an unsupported type. ` + `Please check the docs for ${moduleName}.${className}.${funcName} for ` + `valid input types.`; + }, + 'not-array-of-class': ({ + value, + expectedClass, + moduleName, + className, + funcName, + paramName + }) => { + return `The supplied '${paramName}' parameter must be an array of ` + `'${expectedClass}' objects. Received '${JSON.stringify(value)},'. ` + `Please check the call to ${moduleName}.${className}.${funcName}() ` + `to fix the issue.`; + }, + 'max-entries-or-age-required': ({ + moduleName, + className, + funcName + }) => { + return `You must define either config.maxEntries or config.maxAgeSeconds` + `in ${moduleName}.${className}.${funcName}`; + }, + 'statuses-or-headers-required': ({ + moduleName, + className, + funcName + }) => { + return `You must define either config.statuses or config.headers` + `in ${moduleName}.${className}.${funcName}`; + }, + 'invalid-string': ({ + moduleName, + funcName, + paramName + }) => { + if (!paramName || !moduleName || !funcName) { + throw new Error(`Unexpected input to 'invalid-string' error.`); + } + return `When using strings, the '${paramName}' parameter must start with ` + `'http' (for cross-origin matches) or '/' (for same-origin matches). ` + `Please see the docs for ${moduleName}.${funcName}() for ` + `more info.`; + }, + 'channel-name-required': () => { + return `You must provide a channelName to construct a ` + `BroadcastCacheUpdate instance.`; + }, + 'invalid-responses-are-same-args': () => { + return `The arguments passed into responsesAreSame() appear to be ` + `invalid. Please ensure valid Responses are used.`; + }, + 'expire-custom-caches-only': () => { + return `You must provide a 'cacheName' property when using the ` + `expiration plugin with a runtime caching strategy.`; + }, + 'unit-must-be-bytes': ({ + normalizedRangeHeader + }) => { + if (!normalizedRangeHeader) { + throw new Error(`Unexpected input to 'unit-must-be-bytes' error.`); + } + return `The 'unit' portion of the Range header must be set to 'bytes'. ` + `The Range header provided was "${normalizedRangeHeader}"`; + }, + 'single-range-only': ({ + normalizedRangeHeader + }) => { + if (!normalizedRangeHeader) { + throw new Error(`Unexpected input to 'single-range-only' error.`); + } + return `Multiple ranges are not supported. Please use a single start ` + `value, and optional end value. The Range header provided was ` + `"${normalizedRangeHeader}"`; + }, + 'invalid-range-values': ({ + normalizedRangeHeader + }) => { + if (!normalizedRangeHeader) { + throw new Error(`Unexpected input to 'invalid-range-values' error.`); + } + return `The Range header is missing both start and end values. At least ` + `one of those values is needed. The Range header provided was ` + `"${normalizedRangeHeader}"`; + }, + 'no-range-header': () => { + return `No Range header was found in the Request provided.`; + }, + 'range-not-satisfiable': ({ + size, + start, + end + }) => { + return `The start (${start}) and end (${end}) values in the Range are ` + `not satisfiable by the cached response, which is ${size} bytes.`; + }, + 'attempt-to-cache-non-get-request': ({ + url, + method + }) => { + return `Unable to cache '${url}' because it is a '${method}' request and ` + `only 'GET' requests can be cached.`; + }, + 'cache-put-with-no-response': ({ + url + }) => { + return `There was an attempt to cache '${url}' but the response was not ` + `defined.`; + }, + 'no-response': ({ + url, + error + }) => { + let message = `The strategy could not generate a response for '${url}'.`; + if (error) { + message += ` The underlying error is ${error}.`; + } + return message; + }, + 'bad-precaching-response': ({ + url, + status + }) => { + return `The precaching request for '${url}' failed` + (status ? ` with an HTTP status of ${status}.` : `.`); + }, + 'non-precached-url': ({ + url + }) => { + return `createHandlerBoundToURL('${url}') was called, but that URL is ` + `not precached. Please pass in a URL that is precached instead.`; + }, + 'add-to-cache-list-conflicting-integrities': ({ + url + }) => { + return `Two of the entries passed to ` + `'workbox-precaching.PrecacheController.addToCacheList()' had the URL ` + `${url} with different integrity values. Please remove one of them.`; + }, + 'missing-precache-entry': ({ + cacheName, + url + }) => { + return `Unable to find a precached response in ${cacheName} for ${url}.`; + }, + 'cross-origin-copy-response': ({ + origin + }) => { + return `workbox-core.copyResponse() can only be used with same-origin ` + `responses. It was passed a response with origin ${origin}.`; + }, + 'opaque-streams-source': ({ + type + }) => { + const message = `One of the workbox-streams sources resulted in an ` + `'${type}' response.`; + if (type === 'opaqueredirect') { + return `${message} Please do not use a navigation request that results ` + `in a redirect as a source.`; + } + return `${message} Please ensure your sources are CORS-enabled.`; + } + }; + + /* + Copyright 2018 Google LLC + + Use of this source code is governed by an MIT-style + license that can be found in the LICENSE file or at + https://opensource.org/licenses/MIT. + */ + const generatorFunction = (code, details = {}) => { + const message = messages$1[code]; + if (!message) { + throw new Error(`Unable to find message for code '${code}'.`); + } + return message(details); + }; + const messageGenerator = generatorFunction; + + /* + Copyright 2018 Google LLC + + Use of this source code is governed by an MIT-style + license that can be found in the LICENSE file or at + https://opensource.org/licenses/MIT. + */ + /** + * Workbox errors should be thrown with this class. + * This allows use to ensure the type easily in tests, + * helps developers identify errors from workbox + * easily and allows use to optimise error + * messages correctly. + * + * @private + */ + class WorkboxError extends Error { + /** + * + * @param {string} errorCode The error code that + * identifies this particular error. + * @param {Object=} details Any relevant arguments + * that will help developers identify issues should + * be added as a key on the context object. + */ + constructor(errorCode, details) { + const message = messageGenerator(errorCode, details); + super(message); + this.name = errorCode; + this.details = details; + } + } + + /* + Copyright 2018 Google LLC + + Use of this source code is governed by an MIT-style + license that can be found in the LICENSE file or at + https://opensource.org/licenses/MIT. + */ + /* + * This method throws if the supplied value is not an array. + * The destructed values are required to produce a meaningful error for users. + * The destructed and restructured object is so it's clear what is + * needed. + */ + const isArray = (value, details) => { + if (!Array.isArray(value)) { + throw new WorkboxError('not-an-array', details); + } + }; + const hasMethod = (object, expectedMethod, details) => { + const type = typeof object[expectedMethod]; + if (type !== 'function') { + details['expectedMethod'] = expectedMethod; + throw new WorkboxError('missing-a-method', details); + } + }; + const isType = (object, expectedType, details) => { + if (typeof object !== expectedType) { + details['expectedType'] = expectedType; + throw new WorkboxError('incorrect-type', details); + } + }; + const isInstance = (object, + // Need the general type to do the check later. + // eslint-disable-next-line @typescript-eslint/ban-types + expectedClass, details) => { + if (!(object instanceof expectedClass)) { + details['expectedClassName'] = expectedClass.name; + throw new WorkboxError('incorrect-class', details); + } + }; + const isOneOf = (value, validValues, details) => { + if (!validValues.includes(value)) { + details['validValueDescription'] = `Valid values are ${JSON.stringify(validValues)}.`; + throw new WorkboxError('invalid-value', details); + } + }; + const isArrayOfClass = (value, + // Need general type to do check later. + expectedClass, + // eslint-disable-line + details) => { + const error = new WorkboxError('not-array-of-class', details); + if (!Array.isArray(value)) { + throw error; + } + for (const item of value) { + if (!(item instanceof expectedClass)) { + throw error; + } + } + }; + const finalAssertExports = { + hasMethod, + isArray, + isInstance, + isOneOf, + isType, + isArrayOfClass + }; + + // @ts-ignore + try { + self['workbox:routing:7.2.0'] && _(); + } catch (e) {} + + /* + Copyright 2018 Google LLC + + Use of this source code is governed by an MIT-style + license that can be found in the LICENSE file or at + https://opensource.org/licenses/MIT. + */ + /** + * The default HTTP method, 'GET', used when there's no specific method + * configured for a route. + * + * @type {string} + * + * @private + */ + const defaultMethod = 'GET'; + /** + * The list of valid HTTP methods associated with requests that could be routed. + * + * @type {Array} + * + * @private + */ + const validMethods = ['DELETE', 'GET', 'HEAD', 'PATCH', 'POST', 'PUT']; + + /* + Copyright 2018 Google LLC + + Use of this source code is governed by an MIT-style + license that can be found in the LICENSE file or at + https://opensource.org/licenses/MIT. + */ + /** + * @param {function()|Object} handler Either a function, or an object with a + * 'handle' method. + * @return {Object} An object with a handle method. + * + * @private + */ + const normalizeHandler = handler => { + if (handler && typeof handler === 'object') { + { + finalAssertExports.hasMethod(handler, 'handle', { + moduleName: 'workbox-routing', + className: 'Route', + funcName: 'constructor', + paramName: 'handler' + }); + } + return handler; + } else { + { + finalAssertExports.isType(handler, 'function', { + moduleName: 'workbox-routing', + className: 'Route', + funcName: 'constructor', + paramName: 'handler' + }); + } + return { + handle: handler + }; + } + }; + + /* + Copyright 2018 Google LLC + + Use of this source code is governed by an MIT-style + license that can be found in the LICENSE file or at + https://opensource.org/licenses/MIT. + */ + /** + * A `Route` consists of a pair of callback functions, "match" and "handler". + * The "match" callback determine if a route should be used to "handle" a + * request by returning a non-falsy value if it can. The "handler" callback + * is called when there is a match and should return a Promise that resolves + * to a `Response`. + * + * @memberof workbox-routing + */ + class Route { + /** + * Constructor for Route class. + * + * @param {workbox-routing~matchCallback} match + * A callback function that determines whether the route matches a given + * `fetch` event by returning a non-falsy value. + * @param {workbox-routing~handlerCallback} handler A callback + * function that returns a Promise resolving to a Response. + * @param {string} [method='GET'] The HTTP method to match the Route + * against. + */ + constructor(match, handler, method = defaultMethod) { + { + finalAssertExports.isType(match, 'function', { + moduleName: 'workbox-routing', + className: 'Route', + funcName: 'constructor', + paramName: 'match' + }); + if (method) { + finalAssertExports.isOneOf(method, validMethods, { + paramName: 'method' + }); + } + } + // These values are referenced directly by Router so cannot be + // altered by minificaton. + this.handler = normalizeHandler(handler); + this.match = match; + this.method = method; + } + /** + * + * @param {workbox-routing-handlerCallback} handler A callback + * function that returns a Promise resolving to a Response + */ + setCatchHandler(handler) { + this.catchHandler = normalizeHandler(handler); + } + } + + /* + Copyright 2018 Google LLC + + Use of this source code is governed by an MIT-style + license that can be found in the LICENSE file or at + https://opensource.org/licenses/MIT. + */ + /** + * RegExpRoute makes it easy to create a regular expression based + * {@link workbox-routing.Route}. + * + * For same-origin requests the RegExp only needs to match part of the URL. For + * requests against third-party servers, you must define a RegExp that matches + * the start of the URL. + * + * @memberof workbox-routing + * @extends workbox-routing.Route + */ + class RegExpRoute extends Route { + /** + * If the regular expression contains + * [capture groups]{@link https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/RegExp#grouping-back-references}, + * the captured values will be passed to the + * {@link workbox-routing~handlerCallback} `params` + * argument. + * + * @param {RegExp} regExp The regular expression to match against URLs. + * @param {workbox-routing~handlerCallback} handler A callback + * function that returns a Promise resulting in a Response. + * @param {string} [method='GET'] The HTTP method to match the Route + * against. + */ + constructor(regExp, handler, method) { + { + finalAssertExports.isInstance(regExp, RegExp, { + moduleName: 'workbox-routing', + className: 'RegExpRoute', + funcName: 'constructor', + paramName: 'pattern' + }); + } + const match = ({ + url + }) => { + const result = regExp.exec(url.href); + // Return immediately if there's no match. + if (!result) { + return; + } + // Require that the match start at the first character in the URL string + // if it's a cross-origin request. + // See https://github.com/GoogleChrome/workbox/issues/281 for the context + // behind this behavior. + if (url.origin !== location.origin && result.index !== 0) { + { + logger.debug(`The regular expression '${regExp.toString()}' only partially matched ` + `against the cross-origin URL '${url.toString()}'. RegExpRoute's will only ` + `handle cross-origin requests if they match the entire URL.`); + } + return; + } + // If the route matches, but there aren't any capture groups defined, then + // this will return [], which is truthy and therefore sufficient to + // indicate a match. + // If there are capture groups, then it will return their values. + return result.slice(1); + }; + super(match, handler, method); + } + } + + /* + Copyright 2018 Google LLC + + Use of this source code is governed by an MIT-style + license that can be found in the LICENSE file or at + https://opensource.org/licenses/MIT. + */ + const getFriendlyURL = url => { + const urlObj = new URL(String(url), location.href); + // See https://github.com/GoogleChrome/workbox/issues/2323 + // We want to include everything, except for the origin if it's same-origin. + return urlObj.href.replace(new RegExp(`^${location.origin}`), ''); + }; + + /* + Copyright 2018 Google LLC + + Use of this source code is governed by an MIT-style + license that can be found in the LICENSE file or at + https://opensource.org/licenses/MIT. + */ + /** + * The Router can be used to process a `FetchEvent` using one or more + * {@link workbox-routing.Route}, responding with a `Response` if + * a matching route exists. + * + * If no route matches a given a request, the Router will use a "default" + * handler if one is defined. + * + * Should the matching Route throw an error, the Router will use a "catch" + * handler if one is defined to gracefully deal with issues and respond with a + * Request. + * + * If a request matches multiple routes, the **earliest** registered route will + * be used to respond to the request. + * + * @memberof workbox-routing + */ + class Router { + /** + * Initializes a new Router. + */ + constructor() { + this._routes = new Map(); + this._defaultHandlerMap = new Map(); + } + /** + * @return {Map>} routes A `Map` of HTTP + * method name ('GET', etc.) to an array of all the corresponding `Route` + * instances that are registered. + */ + get routes() { + return this._routes; + } + /** + * Adds a fetch event listener to respond to events when a route matches + * the event's request. + */ + addFetchListener() { + // See https://github.com/Microsoft/TypeScript/issues/28357#issuecomment-436484705 + self.addEventListener('fetch', event => { + const { + request + } = event; + const responsePromise = this.handleRequest({ + request, + event + }); + if (responsePromise) { + event.respondWith(responsePromise); + } + }); + } + /** + * Adds a message event listener for URLs to cache from the window. + * This is useful to cache resources loaded on the page prior to when the + * service worker started controlling it. + * + * The format of the message data sent from the window should be as follows. + * Where the `urlsToCache` array may consist of URL strings or an array of + * URL string + `requestInit` object (the same as you'd pass to `fetch()`). + * + * ``` + * { + * type: 'CACHE_URLS', + * payload: { + * urlsToCache: [ + * './script1.js', + * './script2.js', + * ['./script3.js', {mode: 'no-cors'}], + * ], + * }, + * } + * ``` + */ + addCacheListener() { + // See https://github.com/Microsoft/TypeScript/issues/28357#issuecomment-436484705 + self.addEventListener('message', event => { + // event.data is type 'any' + // eslint-disable-next-line @typescript-eslint/no-unsafe-member-access + if (event.data && event.data.type === 'CACHE_URLS') { + // eslint-disable-next-line @typescript-eslint/no-unsafe-assignment + const { + payload + } = event.data; + { + logger.debug(`Caching URLs from the window`, payload.urlsToCache); + } + const requestPromises = Promise.all(payload.urlsToCache.map(entry => { + if (typeof entry === 'string') { + entry = [entry]; + } + const request = new Request(...entry); + return this.handleRequest({ + request, + event + }); + // TODO(philipwalton): TypeScript errors without this typecast for + // some reason (probably a bug). The real type here should work but + // doesn't: `Array | undefined>`. + })); // TypeScript + event.waitUntil(requestPromises); + // If a MessageChannel was used, reply to the message on success. + if (event.ports && event.ports[0]) { + void requestPromises.then(() => event.ports[0].postMessage(true)); + } + } + }); + } + /** + * Apply the routing rules to a FetchEvent object to get a Response from an + * appropriate Route's handler. + * + * @param {Object} options + * @param {Request} options.request The request to handle. + * @param {ExtendableEvent} options.event The event that triggered the + * request. + * @return {Promise|undefined} A promise is returned if a + * registered route can handle the request. If there is no matching + * route and there's no `defaultHandler`, `undefined` is returned. + */ + handleRequest({ + request, + event + }) { + { + finalAssertExports.isInstance(request, Request, { + moduleName: 'workbox-routing', + className: 'Router', + funcName: 'handleRequest', + paramName: 'options.request' + }); + } + const url = new URL(request.url, location.href); + if (!url.protocol.startsWith('http')) { + { + logger.debug(`Workbox Router only supports URLs that start with 'http'.`); + } + return; + } + const sameOrigin = url.origin === location.origin; + const { + params, + route + } = this.findMatchingRoute({ + event, + request, + sameOrigin, + url + }); + let handler = route && route.handler; + const debugMessages = []; + { + if (handler) { + debugMessages.push([`Found a route to handle this request:`, route]); + if (params) { + debugMessages.push([`Passing the following params to the route's handler:`, params]); + } + } + } + // If we don't have a handler because there was no matching route, then + // fall back to defaultHandler if that's defined. + const method = request.method; + if (!handler && this._defaultHandlerMap.has(method)) { + { + debugMessages.push(`Failed to find a matching route. Falling ` + `back to the default handler for ${method}.`); + } + handler = this._defaultHandlerMap.get(method); + } + if (!handler) { + { + // No handler so Workbox will do nothing. If logs is set of debug + // i.e. verbose, we should print out this information. + logger.debug(`No route found for: ${getFriendlyURL(url)}`); + } + return; + } + { + // We have a handler, meaning Workbox is going to handle the route. + // print the routing details to the console. + logger.groupCollapsed(`Router is responding to: ${getFriendlyURL(url)}`); + debugMessages.forEach(msg => { + if (Array.isArray(msg)) { + logger.log(...msg); + } else { + logger.log(msg); + } + }); + logger.groupEnd(); + } + // Wrap in try and catch in case the handle method throws a synchronous + // error. It should still callback to the catch handler. + let responsePromise; + try { + responsePromise = handler.handle({ + url, + request, + event, + params + }); + } catch (err) { + responsePromise = Promise.reject(err); + } + // Get route's catch handler, if it exists + const catchHandler = route && route.catchHandler; + if (responsePromise instanceof Promise && (this._catchHandler || catchHandler)) { + responsePromise = responsePromise.catch(async err => { + // If there's a route catch handler, process that first + if (catchHandler) { + { + // Still include URL here as it will be async from the console group + // and may not make sense without the URL + logger.groupCollapsed(`Error thrown when responding to: ` + ` ${getFriendlyURL(url)}. Falling back to route's Catch Handler.`); + logger.error(`Error thrown by:`, route); + logger.error(err); + logger.groupEnd(); + } + try { + return await catchHandler.handle({ + url, + request, + event, + params + }); + } catch (catchErr) { + if (catchErr instanceof Error) { + err = catchErr; + } + } + } + if (this._catchHandler) { + { + // Still include URL here as it will be async from the console group + // and may not make sense without the URL + logger.groupCollapsed(`Error thrown when responding to: ` + ` ${getFriendlyURL(url)}. Falling back to global Catch Handler.`); + logger.error(`Error thrown by:`, route); + logger.error(err); + logger.groupEnd(); + } + return this._catchHandler.handle({ + url, + request, + event + }); + } + throw err; + }); + } + return responsePromise; + } + /** + * Checks a request and URL (and optionally an event) against the list of + * registered routes, and if there's a match, returns the corresponding + * route along with any params generated by the match. + * + * @param {Object} options + * @param {URL} options.url + * @param {boolean} options.sameOrigin The result of comparing `url.origin` + * against the current origin. + * @param {Request} options.request The request to match. + * @param {Event} options.event The corresponding event. + * @return {Object} An object with `route` and `params` properties. + * They are populated if a matching route was found or `undefined` + * otherwise. + */ + findMatchingRoute({ + url, + sameOrigin, + request, + event + }) { + const routes = this._routes.get(request.method) || []; + for (const route of routes) { + let params; + // route.match returns type any, not possible to change right now. + // eslint-disable-next-line @typescript-eslint/no-unsafe-assignment + const matchResult = route.match({ + url, + sameOrigin, + request, + event + }); + if (matchResult) { + { + // Warn developers that using an async matchCallback is almost always + // not the right thing to do. + if (matchResult instanceof Promise) { + logger.warn(`While routing ${getFriendlyURL(url)}, an async ` + `matchCallback function was used. Please convert the ` + `following route to use a synchronous matchCallback function:`, route); + } + } + // See https://github.com/GoogleChrome/workbox/issues/2079 + // eslint-disable-next-line @typescript-eslint/no-unsafe-assignment + params = matchResult; + if (Array.isArray(params) && params.length === 0) { + // Instead of passing an empty array in as params, use undefined. + params = undefined; + } else if (matchResult.constructor === Object && + // eslint-disable-line + Object.keys(matchResult).length === 0) { + // Instead of passing an empty object in as params, use undefined. + params = undefined; + } else if (typeof matchResult === 'boolean') { + // For the boolean value true (rather than just something truth-y), + // don't set params. + // See https://github.com/GoogleChrome/workbox/pull/2134#issuecomment-513924353 + params = undefined; + } + // Return early if have a match. + return { + route, + params + }; + } + } + // If no match was found above, return and empty object. + return {}; + } + /** + * Define a default `handler` that's called when no routes explicitly + * match the incoming request. + * + * Each HTTP method ('GET', 'POST', etc.) gets its own default handler. + * + * Without a default handler, unmatched requests will go against the + * network as if there were no service worker present. + * + * @param {workbox-routing~handlerCallback} handler A callback + * function that returns a Promise resulting in a Response. + * @param {string} [method='GET'] The HTTP method to associate with this + * default handler. Each method has its own default. + */ + setDefaultHandler(handler, method = defaultMethod) { + this._defaultHandlerMap.set(method, normalizeHandler(handler)); + } + /** + * If a Route throws an error while handling a request, this `handler` + * will be called and given a chance to provide a response. + * + * @param {workbox-routing~handlerCallback} handler A callback + * function that returns a Promise resulting in a Response. + */ + setCatchHandler(handler) { + this._catchHandler = normalizeHandler(handler); + } + /** + * Registers a route with the router. + * + * @param {workbox-routing.Route} route The route to register. + */ + registerRoute(route) { + { + finalAssertExports.isType(route, 'object', { + moduleName: 'workbox-routing', + className: 'Router', + funcName: 'registerRoute', + paramName: 'route' + }); + finalAssertExports.hasMethod(route, 'match', { + moduleName: 'workbox-routing', + className: 'Router', + funcName: 'registerRoute', + paramName: 'route' + }); + finalAssertExports.isType(route.handler, 'object', { + moduleName: 'workbox-routing', + className: 'Router', + funcName: 'registerRoute', + paramName: 'route' + }); + finalAssertExports.hasMethod(route.handler, 'handle', { + moduleName: 'workbox-routing', + className: 'Router', + funcName: 'registerRoute', + paramName: 'route.handler' + }); + finalAssertExports.isType(route.method, 'string', { + moduleName: 'workbox-routing', + className: 'Router', + funcName: 'registerRoute', + paramName: 'route.method' + }); + } + if (!this._routes.has(route.method)) { + this._routes.set(route.method, []); + } + // Give precedence to all of the earlier routes by adding this additional + // route to the end of the array. + this._routes.get(route.method).push(route); + } + /** + * Unregisters a route with the router. + * + * @param {workbox-routing.Route} route The route to unregister. + */ + unregisterRoute(route) { + if (!this._routes.has(route.method)) { + throw new WorkboxError('unregister-route-but-not-found-with-method', { + method: route.method + }); + } + const routeIndex = this._routes.get(route.method).indexOf(route); + if (routeIndex > -1) { + this._routes.get(route.method).splice(routeIndex, 1); + } else { + throw new WorkboxError('unregister-route-route-not-registered'); + } + } + } + + /* + Copyright 2019 Google LLC + + Use of this source code is governed by an MIT-style + license that can be found in the LICENSE file or at + https://opensource.org/licenses/MIT. + */ + let defaultRouter; + /** + * Creates a new, singleton Router instance if one does not exist. If one + * does already exist, that instance is returned. + * + * @private + * @return {Router} + */ + const getOrCreateDefaultRouter = () => { + if (!defaultRouter) { + defaultRouter = new Router(); + // The helpers that use the default Router assume these listeners exist. + defaultRouter.addFetchListener(); + defaultRouter.addCacheListener(); + } + return defaultRouter; + }; + + /* + Copyright 2019 Google LLC + + Use of this source code is governed by an MIT-style + license that can be found in the LICENSE file or at + https://opensource.org/licenses/MIT. + */ + /** + * Easily register a RegExp, string, or function with a caching + * strategy to a singleton Router instance. + * + * This method will generate a Route for you if needed and + * call {@link workbox-routing.Router#registerRoute}. + * + * @param {RegExp|string|workbox-routing.Route~matchCallback|workbox-routing.Route} capture + * If the capture param is a `Route`, all other arguments will be ignored. + * @param {workbox-routing~handlerCallback} [handler] A callback + * function that returns a Promise resulting in a Response. This parameter + * is required if `capture` is not a `Route` object. + * @param {string} [method='GET'] The HTTP method to match the Route + * against. + * @return {workbox-routing.Route} The generated `Route`. + * + * @memberof workbox-routing + */ + function registerRoute(capture, handler, method) { + let route; + if (typeof capture === 'string') { + const captureUrl = new URL(capture, location.href); + { + if (!(capture.startsWith('/') || capture.startsWith('http'))) { + throw new WorkboxError('invalid-string', { + moduleName: 'workbox-routing', + funcName: 'registerRoute', + paramName: 'capture' + }); + } + // We want to check if Express-style wildcards are in the pathname only. + // TODO: Remove this log message in v4. + const valueToCheck = capture.startsWith('http') ? captureUrl.pathname : capture; + // See https://github.com/pillarjs/path-to-regexp#parameters + const wildcards = '[*:?+]'; + if (new RegExp(`${wildcards}`).exec(valueToCheck)) { + logger.debug(`The '$capture' parameter contains an Express-style wildcard ` + `character (${wildcards}). Strings are now always interpreted as ` + `exact matches; use a RegExp for partial or wildcard matches.`); + } + } + const matchCallback = ({ + url + }) => { + { + if (url.pathname === captureUrl.pathname && url.origin !== captureUrl.origin) { + logger.debug(`${capture} only partially matches the cross-origin URL ` + `${url.toString()}. This route will only handle cross-origin requests ` + `if they match the entire URL.`); + } + } + return url.href === captureUrl.href; + }; + // If `capture` is a string then `handler` and `method` must be present. + route = new Route(matchCallback, handler, method); + } else if (capture instanceof RegExp) { + // If `capture` is a `RegExp` then `handler` and `method` must be present. + route = new RegExpRoute(capture, handler, method); + } else if (typeof capture === 'function') { + // If `capture` is a function then `handler` and `method` must be present. + route = new Route(capture, handler, method); + } else if (capture instanceof Route) { + route = capture; + } else { + throw new WorkboxError('unsupported-route-type', { + moduleName: 'workbox-routing', + funcName: 'registerRoute', + paramName: 'capture' + }); + } + const defaultRouter = getOrCreateDefaultRouter(); + defaultRouter.registerRoute(route); + return route; + } + + /* + Copyright 2018 Google LLC + + Use of this source code is governed by an MIT-style + license that can be found in the LICENSE file or at + https://opensource.org/licenses/MIT. + */ + const _cacheNameDetails = { + googleAnalytics: 'googleAnalytics', + precache: 'precache-v2', + prefix: 'workbox', + runtime: 'runtime', + suffix: typeof registration !== 'undefined' ? registration.scope : '' + }; + const _createCacheName = cacheName => { + return [_cacheNameDetails.prefix, cacheName, _cacheNameDetails.suffix].filter(value => value && value.length > 0).join('-'); + }; + const eachCacheNameDetail = fn => { + for (const key of Object.keys(_cacheNameDetails)) { + fn(key); + } + }; + const cacheNames = { + updateDetails: details => { + eachCacheNameDetail(key => { + if (typeof details[key] === 'string') { + _cacheNameDetails[key] = details[key]; + } + }); + }, + getGoogleAnalyticsName: userCacheName => { + return userCacheName || _createCacheName(_cacheNameDetails.googleAnalytics); + }, + getPrecacheName: userCacheName => { + return userCacheName || _createCacheName(_cacheNameDetails.precache); + }, + getPrefix: () => { + return _cacheNameDetails.prefix; + }, + getRuntimeName: userCacheName => { + return userCacheName || _createCacheName(_cacheNameDetails.runtime); + }, + getSuffix: () => { + return _cacheNameDetails.suffix; + } + }; + + /* + Copyright 2019 Google LLC + Use of this source code is governed by an MIT-style + license that can be found in the LICENSE file or at + https://opensource.org/licenses/MIT. + */ + /** + * A helper function that prevents a promise from being flagged as unused. + * + * @private + **/ + function dontWaitFor(promise) { + // Effective no-op. + void promise.then(() => {}); + } + + /* + Copyright 2018 Google LLC + + Use of this source code is governed by an MIT-style + license that can be found in the LICENSE file or at + https://opensource.org/licenses/MIT. + */ + // Callbacks to be executed whenever there's a quota error. + // Can't change Function type right now. + // eslint-disable-next-line @typescript-eslint/ban-types + const quotaErrorCallbacks = new Set(); + + /* + Copyright 2019 Google LLC + + Use of this source code is governed by an MIT-style + license that can be found in the LICENSE file or at + https://opensource.org/licenses/MIT. + */ + /** + * Adds a function to the set of quotaErrorCallbacks that will be executed if + * there's a quota error. + * + * @param {Function} callback + * @memberof workbox-core + */ + // Can't change Function type + // eslint-disable-next-line @typescript-eslint/ban-types + function registerQuotaErrorCallback(callback) { + { + finalAssertExports.isType(callback, 'function', { + moduleName: 'workbox-core', + funcName: 'register', + paramName: 'callback' + }); + } + quotaErrorCallbacks.add(callback); + { + logger.log('Registered a callback to respond to quota errors.', callback); + } + } + + function _extends() { + return _extends = Object.assign ? Object.assign.bind() : function (n) { + for (var e = 1; e < arguments.length; e++) { + var t = arguments[e]; + for (var r in t) ({}).hasOwnProperty.call(t, r) && (n[r] = t[r]); + } + return n; + }, _extends.apply(null, arguments); + } + + const instanceOfAny = (object, constructors) => constructors.some(c => object instanceof c); + let idbProxyableTypes; + let cursorAdvanceMethods; + // This is a function to prevent it throwing up in node environments. + function getIdbProxyableTypes() { + return idbProxyableTypes || (idbProxyableTypes = [IDBDatabase, IDBObjectStore, IDBIndex, IDBCursor, IDBTransaction]); + } + // This is a function to prevent it throwing up in node environments. + function getCursorAdvanceMethods() { + return cursorAdvanceMethods || (cursorAdvanceMethods = [IDBCursor.prototype.advance, IDBCursor.prototype.continue, IDBCursor.prototype.continuePrimaryKey]); + } + const cursorRequestMap = new WeakMap(); + const transactionDoneMap = new WeakMap(); + const transactionStoreNamesMap = new WeakMap(); + const transformCache = new WeakMap(); + const reverseTransformCache = new WeakMap(); + function promisifyRequest(request) { + const promise = new Promise((resolve, reject) => { + const unlisten = () => { + request.removeEventListener('success', success); + request.removeEventListener('error', error); + }; + const success = () => { + resolve(wrap(request.result)); + unlisten(); + }; + const error = () => { + reject(request.error); + unlisten(); + }; + request.addEventListener('success', success); + request.addEventListener('error', error); + }); + promise.then(value => { + // Since cursoring reuses the IDBRequest (*sigh*), we cache it for later retrieval + // (see wrapFunction). + if (value instanceof IDBCursor) { + cursorRequestMap.set(value, request); + } + // Catching to avoid "Uncaught Promise exceptions" + }).catch(() => {}); + // This mapping exists in reverseTransformCache but doesn't doesn't exist in transformCache. This + // is because we create many promises from a single IDBRequest. + reverseTransformCache.set(promise, request); + return promise; + } + function cacheDonePromiseForTransaction(tx) { + // Early bail if we've already created a done promise for this transaction. + if (transactionDoneMap.has(tx)) return; + const done = new Promise((resolve, reject) => { + const unlisten = () => { + tx.removeEventListener('complete', complete); + tx.removeEventListener('error', error); + tx.removeEventListener('abort', error); + }; + const complete = () => { + resolve(); + unlisten(); + }; + const error = () => { + reject(tx.error || new DOMException('AbortError', 'AbortError')); + unlisten(); + }; + tx.addEventListener('complete', complete); + tx.addEventListener('error', error); + tx.addEventListener('abort', error); + }); + // Cache it for later retrieval. + transactionDoneMap.set(tx, done); + } + let idbProxyTraps = { + get(target, prop, receiver) { + if (target instanceof IDBTransaction) { + // Special handling for transaction.done. + if (prop === 'done') return transactionDoneMap.get(target); + // Polyfill for objectStoreNames because of Edge. + if (prop === 'objectStoreNames') { + return target.objectStoreNames || transactionStoreNamesMap.get(target); + } + // Make tx.store return the only store in the transaction, or undefined if there are many. + if (prop === 'store') { + return receiver.objectStoreNames[1] ? undefined : receiver.objectStore(receiver.objectStoreNames[0]); + } + } + // Else transform whatever we get back. + return wrap(target[prop]); + }, + set(target, prop, value) { + target[prop] = value; + return true; + }, + has(target, prop) { + if (target instanceof IDBTransaction && (prop === 'done' || prop === 'store')) { + return true; + } + return prop in target; + } + }; + function replaceTraps(callback) { + idbProxyTraps = callback(idbProxyTraps); + } + function wrapFunction(func) { + // Due to expected object equality (which is enforced by the caching in `wrap`), we + // only create one new func per func. + // Edge doesn't support objectStoreNames (booo), so we polyfill it here. + if (func === IDBDatabase.prototype.transaction && !('objectStoreNames' in IDBTransaction.prototype)) { + return function (storeNames, ...args) { + const tx = func.call(unwrap(this), storeNames, ...args); + transactionStoreNamesMap.set(tx, storeNames.sort ? storeNames.sort() : [storeNames]); + return wrap(tx); + }; + } + // Cursor methods are special, as the behaviour is a little more different to standard IDB. In + // IDB, you advance the cursor and wait for a new 'success' on the IDBRequest that gave you the + // cursor. It's kinda like a promise that can resolve with many values. That doesn't make sense + // with real promises, so each advance methods returns a new promise for the cursor object, or + // undefined if the end of the cursor has been reached. + if (getCursorAdvanceMethods().includes(func)) { + return function (...args) { + // Calling the original function with the proxy as 'this' causes ILLEGAL INVOCATION, so we use + // the original object. + func.apply(unwrap(this), args); + return wrap(cursorRequestMap.get(this)); + }; + } + return function (...args) { + // Calling the original function with the proxy as 'this' causes ILLEGAL INVOCATION, so we use + // the original object. + return wrap(func.apply(unwrap(this), args)); + }; + } + function transformCachableValue(value) { + if (typeof value === 'function') return wrapFunction(value); + // This doesn't return, it just creates a 'done' promise for the transaction, + // which is later returned for transaction.done (see idbObjectHandler). + if (value instanceof IDBTransaction) cacheDonePromiseForTransaction(value); + if (instanceOfAny(value, getIdbProxyableTypes())) return new Proxy(value, idbProxyTraps); + // Return the same value back if we're not going to transform it. + return value; + } + function wrap(value) { + // We sometimes generate multiple promises from a single IDBRequest (eg when cursoring), because + // IDB is weird and a single IDBRequest can yield many responses, so these can't be cached. + if (value instanceof IDBRequest) return promisifyRequest(value); + // If we've already transformed this value before, reuse the transformed value. + // This is faster, but it also provides object equality. + if (transformCache.has(value)) return transformCache.get(value); + const newValue = transformCachableValue(value); + // Not all types are transformed. + // These may be primitive types, so they can't be WeakMap keys. + if (newValue !== value) { + transformCache.set(value, newValue); + reverseTransformCache.set(newValue, value); + } + return newValue; + } + const unwrap = value => reverseTransformCache.get(value); + + /** + * Open a database. + * + * @param name Name of the database. + * @param version Schema version. + * @param callbacks Additional callbacks. + */ + function openDB(name, version, { + blocked, + upgrade, + blocking, + terminated + } = {}) { + const request = indexedDB.open(name, version); + const openPromise = wrap(request); + if (upgrade) { + request.addEventListener('upgradeneeded', event => { + upgrade(wrap(request.result), event.oldVersion, event.newVersion, wrap(request.transaction), event); + }); + } + if (blocked) { + request.addEventListener('blocked', event => blocked( + // Casting due to https://github.com/microsoft/TypeScript-DOM-lib-generator/pull/1405 + event.oldVersion, event.newVersion, event)); + } + openPromise.then(db => { + if (terminated) db.addEventListener('close', () => terminated()); + if (blocking) { + db.addEventListener('versionchange', event => blocking(event.oldVersion, event.newVersion, event)); + } + }).catch(() => {}); + return openPromise; + } + /** + * Delete a database. + * + * @param name Name of the database. + */ + function deleteDB(name, { + blocked + } = {}) { + const request = indexedDB.deleteDatabase(name); + if (blocked) { + request.addEventListener('blocked', event => blocked( + // Casting due to https://github.com/microsoft/TypeScript-DOM-lib-generator/pull/1405 + event.oldVersion, event)); + } + return wrap(request).then(() => undefined); + } + const readMethods = ['get', 'getKey', 'getAll', 'getAllKeys', 'count']; + const writeMethods = ['put', 'add', 'delete', 'clear']; + const cachedMethods = new Map(); + function getMethod(target, prop) { + if (!(target instanceof IDBDatabase && !(prop in target) && typeof prop === 'string')) { + return; + } + if (cachedMethods.get(prop)) return cachedMethods.get(prop); + const targetFuncName = prop.replace(/FromIndex$/, ''); + const useIndex = prop !== targetFuncName; + const isWrite = writeMethods.includes(targetFuncName); + if ( + // Bail if the target doesn't exist on the target. Eg, getAll isn't in Edge. + !(targetFuncName in (useIndex ? IDBIndex : IDBObjectStore).prototype) || !(isWrite || readMethods.includes(targetFuncName))) { + return; + } + const method = async function (storeName, ...args) { + // isWrite ? 'readwrite' : undefined gzipps better, but fails in Edge :( + const tx = this.transaction(storeName, isWrite ? 'readwrite' : 'readonly'); + let target = tx.store; + if (useIndex) target = target.index(args.shift()); + // Must reject if op rejects. + // If it's a write operation, must reject if tx.done rejects. + // Must reject with op rejection first. + // Must resolve with op value. + // Must handle both promises (no unhandled rejections) + return (await Promise.all([target[targetFuncName](...args), isWrite && tx.done]))[0]; + }; + cachedMethods.set(prop, method); + return method; + } + replaceTraps(oldTraps => _extends({}, oldTraps, { + get: (target, prop, receiver) => getMethod(target, prop) || oldTraps.get(target, prop, receiver), + has: (target, prop) => !!getMethod(target, prop) || oldTraps.has(target, prop) + })); + + // @ts-ignore + try { + self['workbox:expiration:7.2.0'] && _(); + } catch (e) {} + + /* + Copyright 2018 Google LLC + + Use of this source code is governed by an MIT-style + license that can be found in the LICENSE file or at + https://opensource.org/licenses/MIT. + */ + const DB_NAME = 'workbox-expiration'; + const CACHE_OBJECT_STORE = 'cache-entries'; + const normalizeURL = unNormalizedUrl => { + const url = new URL(unNormalizedUrl, location.href); + url.hash = ''; + return url.href; + }; + /** + * Returns the timestamp model. + * + * @private + */ + class CacheTimestampsModel { + /** + * + * @param {string} cacheName + * + * @private + */ + constructor(cacheName) { + this._db = null; + this._cacheName = cacheName; + } + /** + * Performs an upgrade of indexedDB. + * + * @param {IDBPDatabase} db + * + * @private + */ + _upgradeDb(db) { + // TODO(philipwalton): EdgeHTML doesn't support arrays as a keyPath, so we + // have to use the `id` keyPath here and create our own values (a + // concatenation of `url + cacheName`) instead of simply using + // `keyPath: ['url', 'cacheName']`, which is supported in other browsers. + const objStore = db.createObjectStore(CACHE_OBJECT_STORE, { + keyPath: 'id' + }); + // TODO(philipwalton): once we don't have to support EdgeHTML, we can + // create a single index with the keyPath `['cacheName', 'timestamp']` + // instead of doing both these indexes. + objStore.createIndex('cacheName', 'cacheName', { + unique: false + }); + objStore.createIndex('timestamp', 'timestamp', { + unique: false + }); + } + /** + * Performs an upgrade of indexedDB and deletes deprecated DBs. + * + * @param {IDBPDatabase} db + * + * @private + */ + _upgradeDbAndDeleteOldDbs(db) { + this._upgradeDb(db); + if (this._cacheName) { + void deleteDB(this._cacheName); + } + } + /** + * @param {string} url + * @param {number} timestamp + * + * @private + */ + async setTimestamp(url, timestamp) { + url = normalizeURL(url); + const entry = { + url, + timestamp, + cacheName: this._cacheName, + // Creating an ID from the URL and cache name won't be necessary once + // Edge switches to Chromium and all browsers we support work with + // array keyPaths. + id: this._getId(url) + }; + const db = await this.getDb(); + const tx = db.transaction(CACHE_OBJECT_STORE, 'readwrite', { + durability: 'relaxed' + }); + await tx.store.put(entry); + await tx.done; + } + /** + * Returns the timestamp stored for a given URL. + * + * @param {string} url + * @return {number | undefined} + * + * @private + */ + async getTimestamp(url) { + const db = await this.getDb(); + const entry = await db.get(CACHE_OBJECT_STORE, this._getId(url)); + return entry === null || entry === void 0 ? void 0 : entry.timestamp; + } + /** + * Iterates through all the entries in the object store (from newest to + * oldest) and removes entries once either `maxCount` is reached or the + * entry's timestamp is less than `minTimestamp`. + * + * @param {number} minTimestamp + * @param {number} maxCount + * @return {Array} + * + * @private + */ + async expireEntries(minTimestamp, maxCount) { + const db = await this.getDb(); + let cursor = await db.transaction(CACHE_OBJECT_STORE).store.index('timestamp').openCursor(null, 'prev'); + const entriesToDelete = []; + let entriesNotDeletedCount = 0; + while (cursor) { + const result = cursor.value; + // TODO(philipwalton): once we can use a multi-key index, we + // won't have to check `cacheName` here. + if (result.cacheName === this._cacheName) { + // Delete an entry if it's older than the max age or + // if we already have the max number allowed. + if (minTimestamp && result.timestamp < minTimestamp || maxCount && entriesNotDeletedCount >= maxCount) { + // TODO(philipwalton): we should be able to delete the + // entry right here, but doing so causes an iteration + // bug in Safari stable (fixed in TP). Instead we can + // store the keys of the entries to delete, and then + // delete the separate transactions. + // https://github.com/GoogleChrome/workbox/issues/1978 + // cursor.delete(); + // We only need to return the URL, not the whole entry. + entriesToDelete.push(cursor.value); + } else { + entriesNotDeletedCount++; + } + } + cursor = await cursor.continue(); + } + // TODO(philipwalton): once the Safari bug in the following issue is fixed, + // we should be able to remove this loop and do the entry deletion in the + // cursor loop above: + // https://github.com/GoogleChrome/workbox/issues/1978 + const urlsDeleted = []; + for (const entry of entriesToDelete) { + await db.delete(CACHE_OBJECT_STORE, entry.id); + urlsDeleted.push(entry.url); + } + return urlsDeleted; + } + /** + * Takes a URL and returns an ID that will be unique in the object store. + * + * @param {string} url + * @return {string} + * + * @private + */ + _getId(url) { + // Creating an ID from the URL and cache name won't be necessary once + // Edge switches to Chromium and all browsers we support work with + // array keyPaths. + return this._cacheName + '|' + normalizeURL(url); + } + /** + * Returns an open connection to the database. + * + * @private + */ + async getDb() { + if (!this._db) { + this._db = await openDB(DB_NAME, 1, { + upgrade: this._upgradeDbAndDeleteOldDbs.bind(this) + }); + } + return this._db; + } + } + + /* + Copyright 2018 Google LLC + + Use of this source code is governed by an MIT-style + license that can be found in the LICENSE file or at + https://opensource.org/licenses/MIT. + */ + /** + * The `CacheExpiration` class allows you define an expiration and / or + * limit on the number of responses stored in a + * [`Cache`](https://developer.mozilla.org/en-US/docs/Web/API/Cache). + * + * @memberof workbox-expiration + */ + class CacheExpiration { + /** + * To construct a new CacheExpiration instance you must provide at least + * one of the `config` properties. + * + * @param {string} cacheName Name of the cache to apply restrictions to. + * @param {Object} config + * @param {number} [config.maxEntries] The maximum number of entries to cache. + * Entries used the least will be removed as the maximum is reached. + * @param {number} [config.maxAgeSeconds] The maximum age of an entry before + * it's treated as stale and removed. + * @param {Object} [config.matchOptions] The [`CacheQueryOptions`](https://developer.mozilla.org/en-US/docs/Web/API/Cache/delete#Parameters) + * that will be used when calling `delete()` on the cache. + */ + constructor(cacheName, config = {}) { + this._isRunning = false; + this._rerunRequested = false; + { + finalAssertExports.isType(cacheName, 'string', { + moduleName: 'workbox-expiration', + className: 'CacheExpiration', + funcName: 'constructor', + paramName: 'cacheName' + }); + if (!(config.maxEntries || config.maxAgeSeconds)) { + throw new WorkboxError('max-entries-or-age-required', { + moduleName: 'workbox-expiration', + className: 'CacheExpiration', + funcName: 'constructor' + }); + } + if (config.maxEntries) { + finalAssertExports.isType(config.maxEntries, 'number', { + moduleName: 'workbox-expiration', + className: 'CacheExpiration', + funcName: 'constructor', + paramName: 'config.maxEntries' + }); + } + if (config.maxAgeSeconds) { + finalAssertExports.isType(config.maxAgeSeconds, 'number', { + moduleName: 'workbox-expiration', + className: 'CacheExpiration', + funcName: 'constructor', + paramName: 'config.maxAgeSeconds' + }); + } + } + this._maxEntries = config.maxEntries; + this._maxAgeSeconds = config.maxAgeSeconds; + this._matchOptions = config.matchOptions; + this._cacheName = cacheName; + this._timestampModel = new CacheTimestampsModel(cacheName); + } + /** + * Expires entries for the given cache and given criteria. + */ + async expireEntries() { + if (this._isRunning) { + this._rerunRequested = true; + return; + } + this._isRunning = true; + const minTimestamp = this._maxAgeSeconds ? Date.now() - this._maxAgeSeconds * 1000 : 0; + const urlsExpired = await this._timestampModel.expireEntries(minTimestamp, this._maxEntries); + // Delete URLs from the cache + const cache = await self.caches.open(this._cacheName); + for (const url of urlsExpired) { + await cache.delete(url, this._matchOptions); + } + { + if (urlsExpired.length > 0) { + logger.groupCollapsed(`Expired ${urlsExpired.length} ` + `${urlsExpired.length === 1 ? 'entry' : 'entries'} and removed ` + `${urlsExpired.length === 1 ? 'it' : 'them'} from the ` + `'${this._cacheName}' cache.`); + logger.log(`Expired the following ${urlsExpired.length === 1 ? 'URL' : 'URLs'}:`); + urlsExpired.forEach(url => logger.log(` ${url}`)); + logger.groupEnd(); + } else { + logger.debug(`Cache expiration ran and found no entries to remove.`); + } + } + this._isRunning = false; + if (this._rerunRequested) { + this._rerunRequested = false; + dontWaitFor(this.expireEntries()); + } + } + /** + * Update the timestamp for the given URL. This ensures the when + * removing entries based on maximum entries, most recently used + * is accurate or when expiring, the timestamp is up-to-date. + * + * @param {string} url + */ + async updateTimestamp(url) { + { + finalAssertExports.isType(url, 'string', { + moduleName: 'workbox-expiration', + className: 'CacheExpiration', + funcName: 'updateTimestamp', + paramName: 'url' + }); + } + await this._timestampModel.setTimestamp(url, Date.now()); + } + /** + * Can be used to check if a URL has expired or not before it's used. + * + * This requires a look up from IndexedDB, so can be slow. + * + * Note: This method will not remove the cached entry, call + * `expireEntries()` to remove indexedDB and Cache entries. + * + * @param {string} url + * @return {boolean} + */ + async isURLExpired(url) { + if (!this._maxAgeSeconds) { + { + throw new WorkboxError(`expired-test-without-max-age`, { + methodName: 'isURLExpired', + paramName: 'maxAgeSeconds' + }); + } + } else { + const timestamp = await this._timestampModel.getTimestamp(url); + const expireOlderThan = Date.now() - this._maxAgeSeconds * 1000; + return timestamp !== undefined ? timestamp < expireOlderThan : true; + } + } + /** + * Removes the IndexedDB object store used to keep track of cache expiration + * metadata. + */ + async delete() { + // Make sure we don't attempt another rerun if we're called in the middle of + // a cache expiration. + this._rerunRequested = false; + await this._timestampModel.expireEntries(Infinity); // Expires all. + } + } + + /* + Copyright 2018 Google LLC + + Use of this source code is governed by an MIT-style + license that can be found in the LICENSE file or at + https://opensource.org/licenses/MIT. + */ + /** + * This plugin can be used in a `workbox-strategy` to regularly enforce a + * limit on the age and / or the number of cached requests. + * + * It can only be used with `workbox-strategy` instances that have a + * [custom `cacheName` property set](/web/tools/workbox/guides/configure-workbox#custom_cache_names_in_strategies). + * In other words, it can't be used to expire entries in strategy that uses the + * default runtime cache name. + * + * Whenever a cached response is used or updated, this plugin will look + * at the associated cache and remove any old or extra responses. + * + * When using `maxAgeSeconds`, responses may be used *once* after expiring + * because the expiration clean up will not have occurred until *after* the + * cached response has been used. If the response has a "Date" header, then + * a light weight expiration check is performed and the response will not be + * used immediately. + * + * When using `maxEntries`, the entry least-recently requested will be removed + * from the cache first. + * + * @memberof workbox-expiration + */ + class ExpirationPlugin { + /** + * @param {ExpirationPluginOptions} config + * @param {number} [config.maxEntries] The maximum number of entries to cache. + * Entries used the least will be removed as the maximum is reached. + * @param {number} [config.maxAgeSeconds] The maximum age of an entry before + * it's treated as stale and removed. + * @param {Object} [config.matchOptions] The [`CacheQueryOptions`](https://developer.mozilla.org/en-US/docs/Web/API/Cache/delete#Parameters) + * that will be used when calling `delete()` on the cache. + * @param {boolean} [config.purgeOnQuotaError] Whether to opt this cache in to + * automatic deletion if the available storage quota has been exceeded. + */ + constructor(config = {}) { + /** + * A "lifecycle" callback that will be triggered automatically by the + * `workbox-strategies` handlers when a `Response` is about to be returned + * from a [Cache](https://developer.mozilla.org/en-US/docs/Web/API/Cache) to + * the handler. It allows the `Response` to be inspected for freshness and + * prevents it from being used if the `Response`'s `Date` header value is + * older than the configured `maxAgeSeconds`. + * + * @param {Object} options + * @param {string} options.cacheName Name of the cache the response is in. + * @param {Response} options.cachedResponse The `Response` object that's been + * read from a cache and whose freshness should be checked. + * @return {Response} Either the `cachedResponse`, if it's + * fresh, or `null` if the `Response` is older than `maxAgeSeconds`. + * + * @private + */ + this.cachedResponseWillBeUsed = async ({ + event, + request, + cacheName, + cachedResponse + }) => { + if (!cachedResponse) { + return null; + } + const isFresh = this._isResponseDateFresh(cachedResponse); + // Expire entries to ensure that even if the expiration date has + // expired, it'll only be used once. + const cacheExpiration = this._getCacheExpiration(cacheName); + dontWaitFor(cacheExpiration.expireEntries()); + // Update the metadata for the request URL to the current timestamp, + // but don't `await` it as we don't want to block the response. + const updateTimestampDone = cacheExpiration.updateTimestamp(request.url); + if (event) { + try { + event.waitUntil(updateTimestampDone); + } catch (error) { + { + // The event may not be a fetch event; only log the URL if it is. + if ('request' in event) { + logger.warn(`Unable to ensure service worker stays alive when ` + `updating cache entry for ` + `'${getFriendlyURL(event.request.url)}'.`); + } + } + } + } + return isFresh ? cachedResponse : null; + }; + /** + * A "lifecycle" callback that will be triggered automatically by the + * `workbox-strategies` handlers when an entry is added to a cache. + * + * @param {Object} options + * @param {string} options.cacheName Name of the cache that was updated. + * @param {string} options.request The Request for the cached entry. + * + * @private + */ + this.cacheDidUpdate = async ({ + cacheName, + request + }) => { + { + finalAssertExports.isType(cacheName, 'string', { + moduleName: 'workbox-expiration', + className: 'Plugin', + funcName: 'cacheDidUpdate', + paramName: 'cacheName' + }); + finalAssertExports.isInstance(request, Request, { + moduleName: 'workbox-expiration', + className: 'Plugin', + funcName: 'cacheDidUpdate', + paramName: 'request' + }); + } + const cacheExpiration = this._getCacheExpiration(cacheName); + await cacheExpiration.updateTimestamp(request.url); + await cacheExpiration.expireEntries(); + }; + { + if (!(config.maxEntries || config.maxAgeSeconds)) { + throw new WorkboxError('max-entries-or-age-required', { + moduleName: 'workbox-expiration', + className: 'Plugin', + funcName: 'constructor' + }); + } + if (config.maxEntries) { + finalAssertExports.isType(config.maxEntries, 'number', { + moduleName: 'workbox-expiration', + className: 'Plugin', + funcName: 'constructor', + paramName: 'config.maxEntries' + }); + } + if (config.maxAgeSeconds) { + finalAssertExports.isType(config.maxAgeSeconds, 'number', { + moduleName: 'workbox-expiration', + className: 'Plugin', + funcName: 'constructor', + paramName: 'config.maxAgeSeconds' + }); + } + } + this._config = config; + this._maxAgeSeconds = config.maxAgeSeconds; + this._cacheExpirations = new Map(); + if (config.purgeOnQuotaError) { + registerQuotaErrorCallback(() => this.deleteCacheAndMetadata()); + } + } + /** + * A simple helper method to return a CacheExpiration instance for a given + * cache name. + * + * @param {string} cacheName + * @return {CacheExpiration} + * + * @private + */ + _getCacheExpiration(cacheName) { + if (cacheName === cacheNames.getRuntimeName()) { + throw new WorkboxError('expire-custom-caches-only'); + } + let cacheExpiration = this._cacheExpirations.get(cacheName); + if (!cacheExpiration) { + cacheExpiration = new CacheExpiration(cacheName, this._config); + this._cacheExpirations.set(cacheName, cacheExpiration); + } + return cacheExpiration; + } + /** + * @param {Response} cachedResponse + * @return {boolean} + * + * @private + */ + _isResponseDateFresh(cachedResponse) { + if (!this._maxAgeSeconds) { + // We aren't expiring by age, so return true, it's fresh + return true; + } + // Check if the 'date' header will suffice a quick expiration check. + // See https://github.com/GoogleChromeLabs/sw-toolbox/issues/164 for + // discussion. + const dateHeaderTimestamp = this._getDateHeaderTimestamp(cachedResponse); + if (dateHeaderTimestamp === null) { + // Unable to parse date, so assume it's fresh. + return true; + } + // If we have a valid headerTime, then our response is fresh iff the + // headerTime plus maxAgeSeconds is greater than the current time. + const now = Date.now(); + return dateHeaderTimestamp >= now - this._maxAgeSeconds * 1000; + } + /** + * This method will extract the data header and parse it into a useful + * value. + * + * @param {Response} cachedResponse + * @return {number|null} + * + * @private + */ + _getDateHeaderTimestamp(cachedResponse) { + if (!cachedResponse.headers.has('date')) { + return null; + } + const dateHeader = cachedResponse.headers.get('date'); + const parsedDate = new Date(dateHeader); + const headerTime = parsedDate.getTime(); + // If the Date header was invalid for some reason, parsedDate.getTime() + // will return NaN. + if (isNaN(headerTime)) { + return null; + } + return headerTime; + } + /** + * This is a helper method that performs two operations: + * + * - Deletes *all* the underlying Cache instances associated with this plugin + * instance, by calling caches.delete() on your behalf. + * - Deletes the metadata from IndexedDB used to keep track of expiration + * details for each Cache instance. + * + * When using cache expiration, calling this method is preferable to calling + * `caches.delete()` directly, since this will ensure that the IndexedDB + * metadata is also cleanly removed and open IndexedDB instances are deleted. + * + * Note that if you're *not* using cache expiration for a given cache, calling + * `caches.delete()` and passing in the cache's name should be sufficient. + * There is no Workbox-specific method needed for cleanup in that case. + */ + async deleteCacheAndMetadata() { + // Do this one at a time instead of all at once via `Promise.all()` to + // reduce the chance of inconsistency if a promise rejects. + for (const [cacheName, cacheExpiration] of this._cacheExpirations) { + await self.caches.delete(cacheName); + await cacheExpiration.delete(); + } + // Reset this._cacheExpirations to its initial state. + this._cacheExpirations = new Map(); + } + } + + // @ts-ignore + try { + self['workbox:strategies:7.2.0'] && _(); + } catch (e) {} + + /* + Copyright 2018 Google LLC + + Use of this source code is governed by an MIT-style + license that can be found in the LICENSE file or at + https://opensource.org/licenses/MIT. + */ + const cacheOkAndOpaquePlugin = { + /** + * Returns a valid response (to allow caching) if the status is 200 (OK) or + * 0 (opaque). + * + * @param {Object} options + * @param {Response} options.response + * @return {Response|null} + * + * @private + */ + cacheWillUpdate: async ({ + response + }) => { + if (response.status === 200 || response.status === 0) { + return response; + } + return null; + } + }; + + /* + Copyright 2020 Google LLC + Use of this source code is governed by an MIT-style + license that can be found in the LICENSE file or at + https://opensource.org/licenses/MIT. + */ + function stripParams(fullURL, ignoreParams) { + const strippedURL = new URL(fullURL); + for (const param of ignoreParams) { + strippedURL.searchParams.delete(param); + } + return strippedURL.href; + } + /** + * Matches an item in the cache, ignoring specific URL params. This is similar + * to the `ignoreSearch` option, but it allows you to ignore just specific + * params (while continuing to match on the others). + * + * @private + * @param {Cache} cache + * @param {Request} request + * @param {Object} matchOptions + * @param {Array} ignoreParams + * @return {Promise} + */ + async function cacheMatchIgnoreParams(cache, request, ignoreParams, matchOptions) { + const strippedRequestURL = stripParams(request.url, ignoreParams); + // If the request doesn't include any ignored params, match as normal. + if (request.url === strippedRequestURL) { + return cache.match(request, matchOptions); + } + // Otherwise, match by comparing keys + const keysOptions = Object.assign(Object.assign({}, matchOptions), { + ignoreSearch: true + }); + const cacheKeys = await cache.keys(request, keysOptions); + for (const cacheKey of cacheKeys) { + const strippedCacheKeyURL = stripParams(cacheKey.url, ignoreParams); + if (strippedRequestURL === strippedCacheKeyURL) { + return cache.match(cacheKey, matchOptions); + } + } + return; + } + + /* + Copyright 2018 Google LLC + + Use of this source code is governed by an MIT-style + license that can be found in the LICENSE file or at + https://opensource.org/licenses/MIT. + */ + /** + * The Deferred class composes Promises in a way that allows for them to be + * resolved or rejected from outside the constructor. In most cases promises + * should be used directly, but Deferreds can be necessary when the logic to + * resolve a promise must be separate. + * + * @private + */ + class Deferred { + /** + * Creates a promise and exposes its resolve and reject functions as methods. + */ + constructor() { + this.promise = new Promise((resolve, reject) => { + this.resolve = resolve; + this.reject = reject; + }); + } + } + + /* + Copyright 2018 Google LLC + + Use of this source code is governed by an MIT-style + license that can be found in the LICENSE file or at + https://opensource.org/licenses/MIT. + */ + /** + * Runs all of the callback functions, one at a time sequentially, in the order + * in which they were registered. + * + * @memberof workbox-core + * @private + */ + async function executeQuotaErrorCallbacks() { + { + logger.log(`About to run ${quotaErrorCallbacks.size} ` + `callbacks to clean up caches.`); + } + for (const callback of quotaErrorCallbacks) { + await callback(); + { + logger.log(callback, 'is complete.'); + } + } + { + logger.log('Finished running callbacks.'); + } + } + + /* + Copyright 2019 Google LLC + Use of this source code is governed by an MIT-style + license that can be found in the LICENSE file or at + https://opensource.org/licenses/MIT. + */ + /** + * Returns a promise that resolves and the passed number of milliseconds. + * This utility is an async/await-friendly version of `setTimeout`. + * + * @param {number} ms + * @return {Promise} + * @private + */ + function timeout(ms) { + return new Promise(resolve => setTimeout(resolve, ms)); + } + + /* + Copyright 2020 Google LLC + + Use of this source code is governed by an MIT-style + license that can be found in the LICENSE file or at + https://opensource.org/licenses/MIT. + */ + function toRequest(input) { + return typeof input === 'string' ? new Request(input) : input; + } + /** + * A class created every time a Strategy instance instance calls + * {@link workbox-strategies.Strategy~handle} or + * {@link workbox-strategies.Strategy~handleAll} that wraps all fetch and + * cache actions around plugin callbacks and keeps track of when the strategy + * is "done" (i.e. all added `event.waitUntil()` promises have resolved). + * + * @memberof workbox-strategies + */ + class StrategyHandler { + /** + * Creates a new instance associated with the passed strategy and event + * that's handling the request. + * + * The constructor also initializes the state that will be passed to each of + * the plugins handling this request. + * + * @param {workbox-strategies.Strategy} strategy + * @param {Object} options + * @param {Request|string} options.request A request to run this strategy for. + * @param {ExtendableEvent} options.event The event associated with the + * request. + * @param {URL} [options.url] + * @param {*} [options.params] The return value from the + * {@link workbox-routing~matchCallback} (if applicable). + */ + constructor(strategy, options) { + this._cacheKeys = {}; + /** + * The request the strategy is performing (passed to the strategy's + * `handle()` or `handleAll()` method). + * @name request + * @instance + * @type {Request} + * @memberof workbox-strategies.StrategyHandler + */ + /** + * The event associated with this request. + * @name event + * @instance + * @type {ExtendableEvent} + * @memberof workbox-strategies.StrategyHandler + */ + /** + * A `URL` instance of `request.url` (if passed to the strategy's + * `handle()` or `handleAll()` method). + * Note: the `url` param will be present if the strategy was invoked + * from a workbox `Route` object. + * @name url + * @instance + * @type {URL|undefined} + * @memberof workbox-strategies.StrategyHandler + */ + /** + * A `param` value (if passed to the strategy's + * `handle()` or `handleAll()` method). + * Note: the `param` param will be present if the strategy was invoked + * from a workbox `Route` object and the + * {@link workbox-routing~matchCallback} returned + * a truthy value (it will be that value). + * @name params + * @instance + * @type {*|undefined} + * @memberof workbox-strategies.StrategyHandler + */ + { + finalAssertExports.isInstance(options.event, ExtendableEvent, { + moduleName: 'workbox-strategies', + className: 'StrategyHandler', + funcName: 'constructor', + paramName: 'options.event' + }); + } + Object.assign(this, options); + this.event = options.event; + this._strategy = strategy; + this._handlerDeferred = new Deferred(); + this._extendLifetimePromises = []; + // Copy the plugins list (since it's mutable on the strategy), + // so any mutations don't affect this handler instance. + this._plugins = [...strategy.plugins]; + this._pluginStateMap = new Map(); + for (const plugin of this._plugins) { + this._pluginStateMap.set(plugin, {}); + } + this.event.waitUntil(this._handlerDeferred.promise); + } + /** + * Fetches a given request (and invokes any applicable plugin callback + * methods) using the `fetchOptions` (for non-navigation requests) and + * `plugins` defined on the `Strategy` object. + * + * The following plugin lifecycle methods are invoked when using this method: + * - `requestWillFetch()` + * - `fetchDidSucceed()` + * - `fetchDidFail()` + * + * @param {Request|string} input The URL or request to fetch. + * @return {Promise} + */ + async fetch(input) { + const { + event + } = this; + let request = toRequest(input); + if (request.mode === 'navigate' && event instanceof FetchEvent && event.preloadResponse) { + const possiblePreloadResponse = await event.preloadResponse; + if (possiblePreloadResponse) { + { + logger.log(`Using a preloaded navigation response for ` + `'${getFriendlyURL(request.url)}'`); + } + return possiblePreloadResponse; + } + } + // If there is a fetchDidFail plugin, we need to save a clone of the + // original request before it's either modified by a requestWillFetch + // plugin or before the original request's body is consumed via fetch(). + const originalRequest = this.hasCallback('fetchDidFail') ? request.clone() : null; + try { + for (const cb of this.iterateCallbacks('requestWillFetch')) { + request = await cb({ + request: request.clone(), + event + }); + } + } catch (err) { + if (err instanceof Error) { + throw new WorkboxError('plugin-error-request-will-fetch', { + thrownErrorMessage: err.message + }); + } + } + // The request can be altered by plugins with `requestWillFetch` making + // the original request (most likely from a `fetch` event) different + // from the Request we make. Pass both to `fetchDidFail` to aid debugging. + const pluginFilteredRequest = request.clone(); + try { + let fetchResponse; + // See https://github.com/GoogleChrome/workbox/issues/1796 + fetchResponse = await fetch(request, request.mode === 'navigate' ? undefined : this._strategy.fetchOptions); + if ("development" !== 'production') { + logger.debug(`Network request for ` + `'${getFriendlyURL(request.url)}' returned a response with ` + `status '${fetchResponse.status}'.`); + } + for (const callback of this.iterateCallbacks('fetchDidSucceed')) { + fetchResponse = await callback({ + event, + request: pluginFilteredRequest, + response: fetchResponse + }); + } + return fetchResponse; + } catch (error) { + { + logger.log(`Network request for ` + `'${getFriendlyURL(request.url)}' threw an error.`, error); + } + // `originalRequest` will only exist if a `fetchDidFail` callback + // is being used (see above). + if (originalRequest) { + await this.runCallbacks('fetchDidFail', { + error: error, + event, + originalRequest: originalRequest.clone(), + request: pluginFilteredRequest.clone() + }); + } + throw error; + } + } + /** + * Calls `this.fetch()` and (in the background) runs `this.cachePut()` on + * the response generated by `this.fetch()`. + * + * The call to `this.cachePut()` automatically invokes `this.waitUntil()`, + * so you do not have to manually call `waitUntil()` on the event. + * + * @param {Request|string} input The request or URL to fetch and cache. + * @return {Promise} + */ + async fetchAndCachePut(input) { + const response = await this.fetch(input); + const responseClone = response.clone(); + void this.waitUntil(this.cachePut(input, responseClone)); + return response; + } + /** + * Matches a request from the cache (and invokes any applicable plugin + * callback methods) using the `cacheName`, `matchOptions`, and `plugins` + * defined on the strategy object. + * + * The following plugin lifecycle methods are invoked when using this method: + * - cacheKeyWillBeUsed() + * - cachedResponseWillBeUsed() + * + * @param {Request|string} key The Request or URL to use as the cache key. + * @return {Promise} A matching response, if found. + */ + async cacheMatch(key) { + const request = toRequest(key); + let cachedResponse; + const { + cacheName, + matchOptions + } = this._strategy; + const effectiveRequest = await this.getCacheKey(request, 'read'); + const multiMatchOptions = Object.assign(Object.assign({}, matchOptions), { + cacheName + }); + cachedResponse = await caches.match(effectiveRequest, multiMatchOptions); + { + if (cachedResponse) { + logger.debug(`Found a cached response in '${cacheName}'.`); + } else { + logger.debug(`No cached response found in '${cacheName}'.`); + } + } + for (const callback of this.iterateCallbacks('cachedResponseWillBeUsed')) { + cachedResponse = (await callback({ + cacheName, + matchOptions, + cachedResponse, + request: effectiveRequest, + event: this.event + })) || undefined; + } + return cachedResponse; + } + /** + * Puts a request/response pair in the cache (and invokes any applicable + * plugin callback methods) using the `cacheName` and `plugins` defined on + * the strategy object. + * + * The following plugin lifecycle methods are invoked when using this method: + * - cacheKeyWillBeUsed() + * - cacheWillUpdate() + * - cacheDidUpdate() + * + * @param {Request|string} key The request or URL to use as the cache key. + * @param {Response} response The response to cache. + * @return {Promise} `false` if a cacheWillUpdate caused the response + * not be cached, and `true` otherwise. + */ + async cachePut(key, response) { + const request = toRequest(key); + // Run in the next task to avoid blocking other cache reads. + // https://github.com/w3c/ServiceWorker/issues/1397 + await timeout(0); + const effectiveRequest = await this.getCacheKey(request, 'write'); + { + if (effectiveRequest.method && effectiveRequest.method !== 'GET') { + throw new WorkboxError('attempt-to-cache-non-get-request', { + url: getFriendlyURL(effectiveRequest.url), + method: effectiveRequest.method + }); + } + // See https://github.com/GoogleChrome/workbox/issues/2818 + const vary = response.headers.get('Vary'); + if (vary) { + logger.debug(`The response for ${getFriendlyURL(effectiveRequest.url)} ` + `has a 'Vary: ${vary}' header. ` + `Consider setting the {ignoreVary: true} option on your strategy ` + `to ensure cache matching and deletion works as expected.`); + } + } + if (!response) { + { + logger.error(`Cannot cache non-existent response for ` + `'${getFriendlyURL(effectiveRequest.url)}'.`); + } + throw new WorkboxError('cache-put-with-no-response', { + url: getFriendlyURL(effectiveRequest.url) + }); + } + const responseToCache = await this._ensureResponseSafeToCache(response); + if (!responseToCache) { + { + logger.debug(`Response '${getFriendlyURL(effectiveRequest.url)}' ` + `will not be cached.`, responseToCache); + } + return false; + } + const { + cacheName, + matchOptions + } = this._strategy; + const cache = await self.caches.open(cacheName); + const hasCacheUpdateCallback = this.hasCallback('cacheDidUpdate'); + const oldResponse = hasCacheUpdateCallback ? await cacheMatchIgnoreParams( + // TODO(philipwalton): the `__WB_REVISION__` param is a precaching + // feature. Consider into ways to only add this behavior if using + // precaching. + cache, effectiveRequest.clone(), ['__WB_REVISION__'], matchOptions) : null; + { + logger.debug(`Updating the '${cacheName}' cache with a new Response ` + `for ${getFriendlyURL(effectiveRequest.url)}.`); + } + try { + await cache.put(effectiveRequest, hasCacheUpdateCallback ? responseToCache.clone() : responseToCache); + } catch (error) { + if (error instanceof Error) { + // See https://developer.mozilla.org/en-US/docs/Web/API/DOMException#exception-QuotaExceededError + if (error.name === 'QuotaExceededError') { + await executeQuotaErrorCallbacks(); + } + throw error; + } + } + for (const callback of this.iterateCallbacks('cacheDidUpdate')) { + await callback({ + cacheName, + oldResponse, + newResponse: responseToCache.clone(), + request: effectiveRequest, + event: this.event + }); + } + return true; + } + /** + * Checks the list of plugins for the `cacheKeyWillBeUsed` callback, and + * executes any of those callbacks found in sequence. The final `Request` + * object returned by the last plugin is treated as the cache key for cache + * reads and/or writes. If no `cacheKeyWillBeUsed` plugin callbacks have + * been registered, the passed request is returned unmodified + * + * @param {Request} request + * @param {string} mode + * @return {Promise} + */ + async getCacheKey(request, mode) { + const key = `${request.url} | ${mode}`; + if (!this._cacheKeys[key]) { + let effectiveRequest = request; + for (const callback of this.iterateCallbacks('cacheKeyWillBeUsed')) { + effectiveRequest = toRequest(await callback({ + mode, + request: effectiveRequest, + event: this.event, + // params has a type any can't change right now. + params: this.params // eslint-disable-line + })); + } + this._cacheKeys[key] = effectiveRequest; + } + return this._cacheKeys[key]; + } + /** + * Returns true if the strategy has at least one plugin with the given + * callback. + * + * @param {string} name The name of the callback to check for. + * @return {boolean} + */ + hasCallback(name) { + for (const plugin of this._strategy.plugins) { + if (name in plugin) { + return true; + } + } + return false; + } + /** + * Runs all plugin callbacks matching the given name, in order, passing the + * given param object (merged ith the current plugin state) as the only + * argument. + * + * Note: since this method runs all plugins, it's not suitable for cases + * where the return value of a callback needs to be applied prior to calling + * the next callback. See + * {@link workbox-strategies.StrategyHandler#iterateCallbacks} + * below for how to handle that case. + * + * @param {string} name The name of the callback to run within each plugin. + * @param {Object} param The object to pass as the first (and only) param + * when executing each callback. This object will be merged with the + * current plugin state prior to callback execution. + */ + async runCallbacks(name, param) { + for (const callback of this.iterateCallbacks(name)) { + // TODO(philipwalton): not sure why `any` is needed. It seems like + // this should work with `as WorkboxPluginCallbackParam[C]`. + await callback(param); + } + } + /** + * Accepts a callback and returns an iterable of matching plugin callbacks, + * where each callback is wrapped with the current handler state (i.e. when + * you call each callback, whatever object parameter you pass it will + * be merged with the plugin's current state). + * + * @param {string} name The name fo the callback to run + * @return {Array} + */ + *iterateCallbacks(name) { + for (const plugin of this._strategy.plugins) { + if (typeof plugin[name] === 'function') { + const state = this._pluginStateMap.get(plugin); + const statefulCallback = param => { + const statefulParam = Object.assign(Object.assign({}, param), { + state + }); + // TODO(philipwalton): not sure why `any` is needed. It seems like + // this should work with `as WorkboxPluginCallbackParam[C]`. + return plugin[name](statefulParam); + }; + yield statefulCallback; + } + } + } + /** + * Adds a promise to the + * [extend lifetime promises]{@link https://w3c.github.io/ServiceWorker/#extendableevent-extend-lifetime-promises} + * of the event event associated with the request being handled (usually a + * `FetchEvent`). + * + * Note: you can await + * {@link workbox-strategies.StrategyHandler~doneWaiting} + * to know when all added promises have settled. + * + * @param {Promise} promise A promise to add to the extend lifetime promises + * of the event that triggered the request. + */ + waitUntil(promise) { + this._extendLifetimePromises.push(promise); + return promise; + } + /** + * Returns a promise that resolves once all promises passed to + * {@link workbox-strategies.StrategyHandler~waitUntil} + * have settled. + * + * Note: any work done after `doneWaiting()` settles should be manually + * passed to an event's `waitUntil()` method (not this handler's + * `waitUntil()` method), otherwise the service worker thread my be killed + * prior to your work completing. + */ + async doneWaiting() { + let promise; + while (promise = this._extendLifetimePromises.shift()) { + await promise; + } + } + /** + * Stops running the strategy and immediately resolves any pending + * `waitUntil()` promises. + */ + destroy() { + this._handlerDeferred.resolve(null); + } + /** + * This method will call cacheWillUpdate on the available plugins (or use + * status === 200) to determine if the Response is safe and valid to cache. + * + * @param {Request} options.request + * @param {Response} options.response + * @return {Promise} + * + * @private + */ + async _ensureResponseSafeToCache(response) { + let responseToCache = response; + let pluginsUsed = false; + for (const callback of this.iterateCallbacks('cacheWillUpdate')) { + responseToCache = (await callback({ + request: this.request, + response: responseToCache, + event: this.event + })) || undefined; + pluginsUsed = true; + if (!responseToCache) { + break; + } + } + if (!pluginsUsed) { + if (responseToCache && responseToCache.status !== 200) { + responseToCache = undefined; + } + { + if (responseToCache) { + if (responseToCache.status !== 200) { + if (responseToCache.status === 0) { + logger.warn(`The response for '${this.request.url}' ` + `is an opaque response. The caching strategy that you're ` + `using will not cache opaque responses by default.`); + } else { + logger.debug(`The response for '${this.request.url}' ` + `returned a status code of '${response.status}' and won't ` + `be cached as a result.`); + } + } + } + } + } + return responseToCache; + } + } + + /* + Copyright 2020 Google LLC + + Use of this source code is governed by an MIT-style + license that can be found in the LICENSE file or at + https://opensource.org/licenses/MIT. + */ + /** + * An abstract base class that all other strategy classes must extend from: + * + * @memberof workbox-strategies + */ + class Strategy { + /** + * Creates a new instance of the strategy and sets all documented option + * properties as public instance properties. + * + * Note: if a custom strategy class extends the base Strategy class and does + * not need more than these properties, it does not need to define its own + * constructor. + * + * @param {Object} [options] + * @param {string} [options.cacheName] Cache name to store and retrieve + * requests. Defaults to the cache names provided by + * {@link workbox-core.cacheNames}. + * @param {Array} [options.plugins] [Plugins]{@link https://developers.google.com/web/tools/workbox/guides/using-plugins} + * to use in conjunction with this caching strategy. + * @param {Object} [options.fetchOptions] Values passed along to the + * [`init`](https://developer.mozilla.org/en-US/docs/Web/API/WindowOrWorkerGlobalScope/fetch#Parameters) + * of [non-navigation](https://github.com/GoogleChrome/workbox/issues/1796) + * `fetch()` requests made by this strategy. + * @param {Object} [options.matchOptions] The + * [`CacheQueryOptions`]{@link https://w3c.github.io/ServiceWorker/#dictdef-cachequeryoptions} + * for any `cache.match()` or `cache.put()` calls made by this strategy. + */ + constructor(options = {}) { + /** + * Cache name to store and retrieve + * requests. Defaults to the cache names provided by + * {@link workbox-core.cacheNames}. + * + * @type {string} + */ + this.cacheName = cacheNames.getRuntimeName(options.cacheName); + /** + * The list + * [Plugins]{@link https://developers.google.com/web/tools/workbox/guides/using-plugins} + * used by this strategy. + * + * @type {Array} + */ + this.plugins = options.plugins || []; + /** + * Values passed along to the + * [`init`]{@link https://developer.mozilla.org/en-US/docs/Web/API/WindowOrWorkerGlobalScope/fetch#Parameters} + * of all fetch() requests made by this strategy. + * + * @type {Object} + */ + this.fetchOptions = options.fetchOptions; + /** + * The + * [`CacheQueryOptions`]{@link https://w3c.github.io/ServiceWorker/#dictdef-cachequeryoptions} + * for any `cache.match()` or `cache.put()` calls made by this strategy. + * + * @type {Object} + */ + this.matchOptions = options.matchOptions; + } + /** + * Perform a request strategy and returns a `Promise` that will resolve with + * a `Response`, invoking all relevant plugin callbacks. + * + * When a strategy instance is registered with a Workbox + * {@link workbox-routing.Route}, this method is automatically + * called when the route matches. + * + * Alternatively, this method can be used in a standalone `FetchEvent` + * listener by passing it to `event.respondWith()`. + * + * @param {FetchEvent|Object} options A `FetchEvent` or an object with the + * properties listed below. + * @param {Request|string} options.request A request to run this strategy for. + * @param {ExtendableEvent} options.event The event associated with the + * request. + * @param {URL} [options.url] + * @param {*} [options.params] + */ + handle(options) { + const [responseDone] = this.handleAll(options); + return responseDone; + } + /** + * Similar to {@link workbox-strategies.Strategy~handle}, but + * instead of just returning a `Promise` that resolves to a `Response` it + * it will return an tuple of `[response, done]` promises, where the former + * (`response`) is equivalent to what `handle()` returns, and the latter is a + * Promise that will resolve once any promises that were added to + * `event.waitUntil()` as part of performing the strategy have completed. + * + * You can await the `done` promise to ensure any extra work performed by + * the strategy (usually caching responses) completes successfully. + * + * @param {FetchEvent|Object} options A `FetchEvent` or an object with the + * properties listed below. + * @param {Request|string} options.request A request to run this strategy for. + * @param {ExtendableEvent} options.event The event associated with the + * request. + * @param {URL} [options.url] + * @param {*} [options.params] + * @return {Array} A tuple of [response, done] + * promises that can be used to determine when the response resolves as + * well as when the handler has completed all its work. + */ + handleAll(options) { + // Allow for flexible options to be passed. + if (options instanceof FetchEvent) { + options = { + event: options, + request: options.request + }; + } + const event = options.event; + const request = typeof options.request === 'string' ? new Request(options.request) : options.request; + const params = 'params' in options ? options.params : undefined; + const handler = new StrategyHandler(this, { + event, + request, + params + }); + const responseDone = this._getResponse(handler, request, event); + const handlerDone = this._awaitComplete(responseDone, handler, request, event); + // Return an array of promises, suitable for use with Promise.all(). + return [responseDone, handlerDone]; + } + async _getResponse(handler, request, event) { + await handler.runCallbacks('handlerWillStart', { + event, + request + }); + let response = undefined; + try { + response = await this._handle(request, handler); + // The "official" Strategy subclasses all throw this error automatically, + // but in case a third-party Strategy doesn't, ensure that we have a + // consistent failure when there's no response or an error response. + if (!response || response.type === 'error') { + throw new WorkboxError('no-response', { + url: request.url + }); + } + } catch (error) { + if (error instanceof Error) { + for (const callback of handler.iterateCallbacks('handlerDidError')) { + response = await callback({ + error, + event, + request + }); + if (response) { + break; + } + } + } + if (!response) { + throw error; + } else { + logger.log(`While responding to '${getFriendlyURL(request.url)}', ` + `an ${error instanceof Error ? error.toString() : ''} error occurred. Using a fallback response provided by ` + `a handlerDidError plugin.`); + } + } + for (const callback of handler.iterateCallbacks('handlerWillRespond')) { + response = await callback({ + event, + request, + response + }); + } + return response; + } + async _awaitComplete(responseDone, handler, request, event) { + let response; + let error; + try { + response = await responseDone; + } catch (error) { + // Ignore errors, as response errors should be caught via the `response` + // promise above. The `done` promise will only throw for errors in + // promises passed to `handler.waitUntil()`. + } + try { + await handler.runCallbacks('handlerDidRespond', { + event, + request, + response + }); + await handler.doneWaiting(); + } catch (waitUntilError) { + if (waitUntilError instanceof Error) { + error = waitUntilError; + } + } + await handler.runCallbacks('handlerDidComplete', { + event, + request, + response, + error: error + }); + handler.destroy(); + if (error) { + throw error; + } + } + } + /** + * Classes extending the `Strategy` based class should implement this method, + * and leverage the {@link workbox-strategies.StrategyHandler} + * arg to perform all fetching and cache logic, which will ensure all relevant + * cache, cache options, fetch options and plugins are used (per the current + * strategy instance). + * + * @name _handle + * @instance + * @abstract + * @function + * @param {Request} request + * @param {workbox-strategies.StrategyHandler} handler + * @return {Promise} + * + * @memberof workbox-strategies.Strategy + */ + + /* + Copyright 2018 Google LLC + + Use of this source code is governed by an MIT-style + license that can be found in the LICENSE file or at + https://opensource.org/licenses/MIT. + */ + const messages = { + strategyStart: (strategyName, request) => `Using ${strategyName} to respond to '${getFriendlyURL(request.url)}'`, + printFinalResponse: response => { + if (response) { + logger.groupCollapsed(`View the final response here.`); + logger.log(response || '[No response returned]'); + logger.groupEnd(); + } + } + }; + + /* + Copyright 2018 Google LLC + + Use of this source code is governed by an MIT-style + license that can be found in the LICENSE file or at + https://opensource.org/licenses/MIT. + */ + /** + * An implementation of a + * [network first](https://developer.chrome.com/docs/workbox/caching-strategies-overview/#network-first-falling-back-to-cache) + * request strategy. + * + * By default, this strategy will cache responses with a 200 status code as + * well as [opaque responses](https://developer.chrome.com/docs/workbox/caching-resources-during-runtime/#opaque-responses). + * Opaque responses are are cross-origin requests where the response doesn't + * support [CORS](https://enable-cors.org/). + * + * If the network request fails, and there is no cache match, this will throw + * a `WorkboxError` exception. + * + * @extends workbox-strategies.Strategy + * @memberof workbox-strategies + */ + class NetworkFirst extends Strategy { + /** + * @param {Object} [options] + * @param {string} [options.cacheName] Cache name to store and retrieve + * requests. Defaults to cache names provided by + * {@link workbox-core.cacheNames}. + * @param {Array} [options.plugins] [Plugins]{@link https://developers.google.com/web/tools/workbox/guides/using-plugins} + * to use in conjunction with this caching strategy. + * @param {Object} [options.fetchOptions] Values passed along to the + * [`init`](https://developer.mozilla.org/en-US/docs/Web/API/WindowOrWorkerGlobalScope/fetch#Parameters) + * of [non-navigation](https://github.com/GoogleChrome/workbox/issues/1796) + * `fetch()` requests made by this strategy. + * @param {Object} [options.matchOptions] [`CacheQueryOptions`](https://w3c.github.io/ServiceWorker/#dictdef-cachequeryoptions) + * @param {number} [options.networkTimeoutSeconds] If set, any network requests + * that fail to respond within the timeout will fallback to the cache. + * + * This option can be used to combat + * "[lie-fi]{@link https://developers.google.com/web/fundamentals/performance/poor-connectivity/#lie-fi}" + * scenarios. + */ + constructor(options = {}) { + super(options); + // If this instance contains no plugins with a 'cacheWillUpdate' callback, + // prepend the `cacheOkAndOpaquePlugin` plugin to the plugins list. + if (!this.plugins.some(p => 'cacheWillUpdate' in p)) { + this.plugins.unshift(cacheOkAndOpaquePlugin); + } + this._networkTimeoutSeconds = options.networkTimeoutSeconds || 0; + { + if (this._networkTimeoutSeconds) { + finalAssertExports.isType(this._networkTimeoutSeconds, 'number', { + moduleName: 'workbox-strategies', + className: this.constructor.name, + funcName: 'constructor', + paramName: 'networkTimeoutSeconds' + }); + } + } + } + /** + * @private + * @param {Request|string} request A request to run this strategy for. + * @param {workbox-strategies.StrategyHandler} handler The event that + * triggered the request. + * @return {Promise} + */ + async _handle(request, handler) { + const logs = []; + { + finalAssertExports.isInstance(request, Request, { + moduleName: 'workbox-strategies', + className: this.constructor.name, + funcName: 'handle', + paramName: 'makeRequest' + }); + } + const promises = []; + let timeoutId; + if (this._networkTimeoutSeconds) { + const { + id, + promise + } = this._getTimeoutPromise({ + request, + logs, + handler + }); + timeoutId = id; + promises.push(promise); + } + const networkPromise = this._getNetworkPromise({ + timeoutId, + request, + logs, + handler + }); + promises.push(networkPromise); + const response = await handler.waitUntil((async () => { + // Promise.race() will resolve as soon as the first promise resolves. + return (await handler.waitUntil(Promise.race(promises))) || ( + // If Promise.race() resolved with null, it might be due to a network + // timeout + a cache miss. If that were to happen, we'd rather wait until + // the networkPromise resolves instead of returning null. + // Note that it's fine to await an already-resolved promise, so we don't + // have to check to see if it's still "in flight". + await networkPromise); + })()); + { + logger.groupCollapsed(messages.strategyStart(this.constructor.name, request)); + for (const log of logs) { + logger.log(log); + } + messages.printFinalResponse(response); + logger.groupEnd(); + } + if (!response) { + throw new WorkboxError('no-response', { + url: request.url + }); + } + return response; + } + /** + * @param {Object} options + * @param {Request} options.request + * @param {Array} options.logs A reference to the logs array + * @param {Event} options.event + * @return {Promise} + * + * @private + */ + _getTimeoutPromise({ + request, + logs, + handler + }) { + let timeoutId; + const timeoutPromise = new Promise(resolve => { + const onNetworkTimeout = async () => { + { + logs.push(`Timing out the network response at ` + `${this._networkTimeoutSeconds} seconds.`); + } + resolve(await handler.cacheMatch(request)); + }; + timeoutId = setTimeout(onNetworkTimeout, this._networkTimeoutSeconds * 1000); + }); + return { + promise: timeoutPromise, + id: timeoutId + }; + } + /** + * @param {Object} options + * @param {number|undefined} options.timeoutId + * @param {Request} options.request + * @param {Array} options.logs A reference to the logs Array. + * @param {Event} options.event + * @return {Promise} + * + * @private + */ + async _getNetworkPromise({ + timeoutId, + request, + logs, + handler + }) { + let error; + let response; + try { + response = await handler.fetchAndCachePut(request); + } catch (fetchError) { + if (fetchError instanceof Error) { + error = fetchError; + } + } + if (timeoutId) { + clearTimeout(timeoutId); + } + { + if (response) { + logs.push(`Got response from network.`); + } else { + logs.push(`Unable to get a response from the network. Will respond ` + `with a cached response.`); + } + } + if (error || !response) { + response = await handler.cacheMatch(request); + { + if (response) { + logs.push(`Found a cached response in the '${this.cacheName}'` + ` cache.`); + } else { + logs.push(`No response found in the '${this.cacheName}' cache.`); + } + } + } + return response; + } + } + + /* + Copyright 2018 Google LLC + + Use of this source code is governed by an MIT-style + license that can be found in the LICENSE file or at + https://opensource.org/licenses/MIT. + */ + /** + * An implementation of a [cache-first](https://developer.chrome.com/docs/workbox/caching-strategies-overview/#cache-first-falling-back-to-network) + * request strategy. + * + * A cache first strategy is useful for assets that have been revisioned, + * such as URLs like `/styles/example.a8f5f1.css`, since they + * can be cached for long periods of time. + * + * If the network request fails, and there is no cache match, this will throw + * a `WorkboxError` exception. + * + * @extends workbox-strategies.Strategy + * @memberof workbox-strategies + */ + class CacheFirst extends Strategy { + /** + * @private + * @param {Request|string} request A request to run this strategy for. + * @param {workbox-strategies.StrategyHandler} handler The event that + * triggered the request. + * @return {Promise} + */ + async _handle(request, handler) { + const logs = []; + { + finalAssertExports.isInstance(request, Request, { + moduleName: 'workbox-strategies', + className: this.constructor.name, + funcName: 'makeRequest', + paramName: 'request' + }); + } + let response = await handler.cacheMatch(request); + let error = undefined; + if (!response) { + { + logs.push(`No response found in the '${this.cacheName}' cache. ` + `Will respond with a network request.`); + } + try { + response = await handler.fetchAndCachePut(request); + } catch (err) { + if (err instanceof Error) { + error = err; + } + } + { + if (response) { + logs.push(`Got response from network.`); + } else { + logs.push(`Unable to get a response from the network.`); + } + } + } else { + { + logs.push(`Found a cached response in the '${this.cacheName}' cache.`); + } + } + { + logger.groupCollapsed(messages.strategyStart(this.constructor.name, request)); + for (const log of logs) { + logger.log(log); + } + messages.printFinalResponse(response); + logger.groupEnd(); + } + if (!response) { + throw new WorkboxError('no-response', { + url: request.url, + error + }); + } + return response; + } + } + + /* + Copyright 2020 Google LLC + Use of this source code is governed by an MIT-style + license that can be found in the LICENSE file or at + https://opensource.org/licenses/MIT. + */ + /** + * A utility method that makes it easier to use `event.waitUntil` with + * async functions and return the result. + * + * @param {ExtendableEvent} event + * @param {Function} asyncFn + * @return {Function} + * @private + */ + function waitUntil(event, asyncFn) { + const returnPromise = asyncFn(); + event.waitUntil(returnPromise); + return returnPromise; + } + + // @ts-ignore + try { + self['workbox:precaching:7.2.0'] && _(); + } catch (e) {} + + /* + Copyright 2018 Google LLC + + Use of this source code is governed by an MIT-style + license that can be found in the LICENSE file or at + https://opensource.org/licenses/MIT. + */ + // Name of the search parameter used to store revision info. + const REVISION_SEARCH_PARAM = '__WB_REVISION__'; + /** + * Converts a manifest entry into a versioned URL suitable for precaching. + * + * @param {Object|string} entry + * @return {string} A URL with versioning info. + * + * @private + * @memberof workbox-precaching + */ + function createCacheKey(entry) { + if (!entry) { + throw new WorkboxError('add-to-cache-list-unexpected-type', { + entry + }); + } + // If a precache manifest entry is a string, it's assumed to be a versioned + // URL, like '/app.abcd1234.js'. Return as-is. + if (typeof entry === 'string') { + const urlObject = new URL(entry, location.href); + return { + cacheKey: urlObject.href, + url: urlObject.href + }; + } + const { + revision, + url + } = entry; + if (!url) { + throw new WorkboxError('add-to-cache-list-unexpected-type', { + entry + }); + } + // If there's just a URL and no revision, then it's also assumed to be a + // versioned URL. + if (!revision) { + const urlObject = new URL(url, location.href); + return { + cacheKey: urlObject.href, + url: urlObject.href + }; + } + // Otherwise, construct a properly versioned URL using the custom Workbox + // search parameter along with the revision info. + const cacheKeyURL = new URL(url, location.href); + const originalURL = new URL(url, location.href); + cacheKeyURL.searchParams.set(REVISION_SEARCH_PARAM, revision); + return { + cacheKey: cacheKeyURL.href, + url: originalURL.href + }; + } + + /* + Copyright 2020 Google LLC + + Use of this source code is governed by an MIT-style + license that can be found in the LICENSE file or at + https://opensource.org/licenses/MIT. + */ + /** + * A plugin, designed to be used with PrecacheController, to determine the + * of assets that were updated (or not updated) during the install event. + * + * @private + */ + class PrecacheInstallReportPlugin { + constructor() { + this.updatedURLs = []; + this.notUpdatedURLs = []; + this.handlerWillStart = async ({ + request, + state + }) => { + // TODO: `state` should never be undefined... + if (state) { + state.originalRequest = request; + } + }; + this.cachedResponseWillBeUsed = async ({ + event, + state, + cachedResponse + }) => { + if (event.type === 'install') { + if (state && state.originalRequest && state.originalRequest instanceof Request) { + // TODO: `state` should never be undefined... + const url = state.originalRequest.url; + if (cachedResponse) { + this.notUpdatedURLs.push(url); + } else { + this.updatedURLs.push(url); + } + } + } + return cachedResponse; + }; + } + } + + /* + Copyright 2020 Google LLC + + Use of this source code is governed by an MIT-style + license that can be found in the LICENSE file or at + https://opensource.org/licenses/MIT. + */ + /** + * A plugin, designed to be used with PrecacheController, to translate URLs into + * the corresponding cache key, based on the current revision info. + * + * @private + */ + class PrecacheCacheKeyPlugin { + constructor({ + precacheController + }) { + this.cacheKeyWillBeUsed = async ({ + request, + params + }) => { + // Params is type any, can't change right now. + /* eslint-disable */ + const cacheKey = (params === null || params === void 0 ? void 0 : params.cacheKey) || this._precacheController.getCacheKeyForURL(request.url); + /* eslint-enable */ + return cacheKey ? new Request(cacheKey, { + headers: request.headers + }) : request; + }; + this._precacheController = precacheController; + } + } + + /* + Copyright 2018 Google LLC + + Use of this source code is governed by an MIT-style + license that can be found in the LICENSE file or at + https://opensource.org/licenses/MIT. + */ + /** + * @param {string} groupTitle + * @param {Array} deletedURLs + * + * @private + */ + const logGroup = (groupTitle, deletedURLs) => { + logger.groupCollapsed(groupTitle); + for (const url of deletedURLs) { + logger.log(url); + } + logger.groupEnd(); + }; + /** + * @param {Array} deletedURLs + * + * @private + * @memberof workbox-precaching + */ + function printCleanupDetails(deletedURLs) { + const deletionCount = deletedURLs.length; + if (deletionCount > 0) { + logger.groupCollapsed(`During precaching cleanup, ` + `${deletionCount} cached ` + `request${deletionCount === 1 ? ' was' : 's were'} deleted.`); + logGroup('Deleted Cache Requests', deletedURLs); + logger.groupEnd(); + } + } + + /* + Copyright 2018 Google LLC + + Use of this source code is governed by an MIT-style + license that can be found in the LICENSE file or at + https://opensource.org/licenses/MIT. + */ + /** + * @param {string} groupTitle + * @param {Array} urls + * + * @private + */ + function _nestedGroup(groupTitle, urls) { + if (urls.length === 0) { + return; + } + logger.groupCollapsed(groupTitle); + for (const url of urls) { + logger.log(url); + } + logger.groupEnd(); + } + /** + * @param {Array} urlsToPrecache + * @param {Array} urlsAlreadyPrecached + * + * @private + * @memberof workbox-precaching + */ + function printInstallDetails(urlsToPrecache, urlsAlreadyPrecached) { + const precachedCount = urlsToPrecache.length; + const alreadyPrecachedCount = urlsAlreadyPrecached.length; + if (precachedCount || alreadyPrecachedCount) { + let message = `Precaching ${precachedCount} file${precachedCount === 1 ? '' : 's'}.`; + if (alreadyPrecachedCount > 0) { + message += ` ${alreadyPrecachedCount} ` + `file${alreadyPrecachedCount === 1 ? ' is' : 's are'} already cached.`; + } + logger.groupCollapsed(message); + _nestedGroup(`View newly precached URLs.`, urlsToPrecache); + _nestedGroup(`View previously precached URLs.`, urlsAlreadyPrecached); + logger.groupEnd(); + } + } + + /* + Copyright 2019 Google LLC + + Use of this source code is governed by an MIT-style + license that can be found in the LICENSE file or at + https://opensource.org/licenses/MIT. + */ + let supportStatus; + /** + * A utility function that determines whether the current browser supports + * constructing a new `Response` from a `response.body` stream. + * + * @return {boolean} `true`, if the current browser can successfully + * construct a `Response` from a `response.body` stream, `false` otherwise. + * + * @private + */ + function canConstructResponseFromBodyStream() { + if (supportStatus === undefined) { + const testResponse = new Response(''); + if ('body' in testResponse) { + try { + new Response(testResponse.body); + supportStatus = true; + } catch (error) { + supportStatus = false; + } + } + supportStatus = false; + } + return supportStatus; + } + + /* + Copyright 2019 Google LLC + + Use of this source code is governed by an MIT-style + license that can be found in the LICENSE file or at + https://opensource.org/licenses/MIT. + */ + /** + * Allows developers to copy a response and modify its `headers`, `status`, + * or `statusText` values (the values settable via a + * [`ResponseInit`]{@link https://developer.mozilla.org/en-US/docs/Web/API/Response/Response#Syntax} + * object in the constructor). + * To modify these values, pass a function as the second argument. That + * function will be invoked with a single object with the response properties + * `{headers, status, statusText}`. The return value of this function will + * be used as the `ResponseInit` for the new `Response`. To change the values + * either modify the passed parameter(s) and return it, or return a totally + * new object. + * + * This method is intentionally limited to same-origin responses, regardless of + * whether CORS was used or not. + * + * @param {Response} response + * @param {Function} modifier + * @memberof workbox-core + */ + async function copyResponse(response, modifier) { + let origin = null; + // If response.url isn't set, assume it's cross-origin and keep origin null. + if (response.url) { + const responseURL = new URL(response.url); + origin = responseURL.origin; + } + if (origin !== self.location.origin) { + throw new WorkboxError('cross-origin-copy-response', { + origin + }); + } + const clonedResponse = response.clone(); + // Create a fresh `ResponseInit` object by cloning the headers. + const responseInit = { + headers: new Headers(clonedResponse.headers), + status: clonedResponse.status, + statusText: clonedResponse.statusText + }; + // Apply any user modifications. + const modifiedResponseInit = modifier ? modifier(responseInit) : responseInit; + // Create the new response from the body stream and `ResponseInit` + // modifications. Note: not all browsers support the Response.body stream, + // so fall back to reading the entire body into memory as a blob. + const body = canConstructResponseFromBodyStream() ? clonedResponse.body : await clonedResponse.blob(); + return new Response(body, modifiedResponseInit); + } + + /* + Copyright 2020 Google LLC + + Use of this source code is governed by an MIT-style + license that can be found in the LICENSE file or at + https://opensource.org/licenses/MIT. + */ + /** + * A {@link workbox-strategies.Strategy} implementation + * specifically designed to work with + * {@link workbox-precaching.PrecacheController} + * to both cache and fetch precached assets. + * + * Note: an instance of this class is created automatically when creating a + * `PrecacheController`; it's generally not necessary to create this yourself. + * + * @extends workbox-strategies.Strategy + * @memberof workbox-precaching + */ + class PrecacheStrategy extends Strategy { + /** + * + * @param {Object} [options] + * @param {string} [options.cacheName] Cache name to store and retrieve + * requests. Defaults to the cache names provided by + * {@link workbox-core.cacheNames}. + * @param {Array} [options.plugins] {@link https://developers.google.com/web/tools/workbox/guides/using-plugins|Plugins} + * to use in conjunction with this caching strategy. + * @param {Object} [options.fetchOptions] Values passed along to the + * {@link https://developer.mozilla.org/en-US/docs/Web/API/WindowOrWorkerGlobalScope/fetch#Parameters|init} + * of all fetch() requests made by this strategy. + * @param {Object} [options.matchOptions] The + * {@link https://w3c.github.io/ServiceWorker/#dictdef-cachequeryoptions|CacheQueryOptions} + * for any `cache.match()` or `cache.put()` calls made by this strategy. + * @param {boolean} [options.fallbackToNetwork=true] Whether to attempt to + * get the response from the network if there's a precache miss. + */ + constructor(options = {}) { + options.cacheName = cacheNames.getPrecacheName(options.cacheName); + super(options); + this._fallbackToNetwork = options.fallbackToNetwork === false ? false : true; + // Redirected responses cannot be used to satisfy a navigation request, so + // any redirected response must be "copied" rather than cloned, so the new + // response doesn't contain the `redirected` flag. See: + // https://bugs.chromium.org/p/chromium/issues/detail?id=669363&desc=2#c1 + this.plugins.push(PrecacheStrategy.copyRedirectedCacheableResponsesPlugin); + } + /** + * @private + * @param {Request|string} request A request to run this strategy for. + * @param {workbox-strategies.StrategyHandler} handler The event that + * triggered the request. + * @return {Promise} + */ + async _handle(request, handler) { + const response = await handler.cacheMatch(request); + if (response) { + return response; + } + // If this is an `install` event for an entry that isn't already cached, + // then populate the cache. + if (handler.event && handler.event.type === 'install') { + return await this._handleInstall(request, handler); + } + // Getting here means something went wrong. An entry that should have been + // precached wasn't found in the cache. + return await this._handleFetch(request, handler); + } + async _handleFetch(request, handler) { + let response; + const params = handler.params || {}; + // Fall back to the network if we're configured to do so. + if (this._fallbackToNetwork) { + { + logger.warn(`The precached response for ` + `${getFriendlyURL(request.url)} in ${this.cacheName} was not ` + `found. Falling back to the network.`); + } + const integrityInManifest = params.integrity; + const integrityInRequest = request.integrity; + const noIntegrityConflict = !integrityInRequest || integrityInRequest === integrityInManifest; + // Do not add integrity if the original request is no-cors + // See https://github.com/GoogleChrome/workbox/issues/3096 + response = await handler.fetch(new Request(request, { + integrity: request.mode !== 'no-cors' ? integrityInRequest || integrityInManifest : undefined + })); + // It's only "safe" to repair the cache if we're using SRI to guarantee + // that the response matches the precache manifest's expectations, + // and there's either a) no integrity property in the incoming request + // or b) there is an integrity, and it matches the precache manifest. + // See https://github.com/GoogleChrome/workbox/issues/2858 + // Also if the original request users no-cors we don't use integrity. + // See https://github.com/GoogleChrome/workbox/issues/3096 + if (integrityInManifest && noIntegrityConflict && request.mode !== 'no-cors') { + this._useDefaultCacheabilityPluginIfNeeded(); + const wasCached = await handler.cachePut(request, response.clone()); + { + if (wasCached) { + logger.log(`A response for ${getFriendlyURL(request.url)} ` + `was used to "repair" the precache.`); + } + } + } + } else { + // This shouldn't normally happen, but there are edge cases: + // https://github.com/GoogleChrome/workbox/issues/1441 + throw new WorkboxError('missing-precache-entry', { + cacheName: this.cacheName, + url: request.url + }); + } + { + const cacheKey = params.cacheKey || (await handler.getCacheKey(request, 'read')); + // Workbox is going to handle the route. + // print the routing details to the console. + logger.groupCollapsed(`Precaching is responding to: ` + getFriendlyURL(request.url)); + logger.log(`Serving the precached url: ${getFriendlyURL(cacheKey instanceof Request ? cacheKey.url : cacheKey)}`); + logger.groupCollapsed(`View request details here.`); + logger.log(request); + logger.groupEnd(); + logger.groupCollapsed(`View response details here.`); + logger.log(response); + logger.groupEnd(); + logger.groupEnd(); + } + return response; + } + async _handleInstall(request, handler) { + this._useDefaultCacheabilityPluginIfNeeded(); + const response = await handler.fetch(request); + // Make sure we defer cachePut() until after we know the response + // should be cached; see https://github.com/GoogleChrome/workbox/issues/2737 + const wasCached = await handler.cachePut(request, response.clone()); + if (!wasCached) { + // Throwing here will lead to the `install` handler failing, which + // we want to do if *any* of the responses aren't safe to cache. + throw new WorkboxError('bad-precaching-response', { + url: request.url, + status: response.status + }); + } + return response; + } + /** + * This method is complex, as there a number of things to account for: + * + * The `plugins` array can be set at construction, and/or it might be added to + * to at any time before the strategy is used. + * + * At the time the strategy is used (i.e. during an `install` event), there + * needs to be at least one plugin that implements `cacheWillUpdate` in the + * array, other than `copyRedirectedCacheableResponsesPlugin`. + * + * - If this method is called and there are no suitable `cacheWillUpdate` + * plugins, we need to add `defaultPrecacheCacheabilityPlugin`. + * + * - If this method is called and there is exactly one `cacheWillUpdate`, then + * we don't have to do anything (this might be a previously added + * `defaultPrecacheCacheabilityPlugin`, or it might be a custom plugin). + * + * - If this method is called and there is more than one `cacheWillUpdate`, + * then we need to check if one is `defaultPrecacheCacheabilityPlugin`. If so, + * we need to remove it. (This situation is unlikely, but it could happen if + * the strategy is used multiple times, the first without a `cacheWillUpdate`, + * and then later on after manually adding a custom `cacheWillUpdate`.) + * + * See https://github.com/GoogleChrome/workbox/issues/2737 for more context. + * + * @private + */ + _useDefaultCacheabilityPluginIfNeeded() { + let defaultPluginIndex = null; + let cacheWillUpdatePluginCount = 0; + for (const [index, plugin] of this.plugins.entries()) { + // Ignore the copy redirected plugin when determining what to do. + if (plugin === PrecacheStrategy.copyRedirectedCacheableResponsesPlugin) { + continue; + } + // Save the default plugin's index, in case it needs to be removed. + if (plugin === PrecacheStrategy.defaultPrecacheCacheabilityPlugin) { + defaultPluginIndex = index; + } + if (plugin.cacheWillUpdate) { + cacheWillUpdatePluginCount++; + } + } + if (cacheWillUpdatePluginCount === 0) { + this.plugins.push(PrecacheStrategy.defaultPrecacheCacheabilityPlugin); + } else if (cacheWillUpdatePluginCount > 1 && defaultPluginIndex !== null) { + // Only remove the default plugin; multiple custom plugins are allowed. + this.plugins.splice(defaultPluginIndex, 1); + } + // Nothing needs to be done if cacheWillUpdatePluginCount is 1 + } + } + PrecacheStrategy.defaultPrecacheCacheabilityPlugin = { + async cacheWillUpdate({ + response + }) { + if (!response || response.status >= 400) { + return null; + } + return response; + } + }; + PrecacheStrategy.copyRedirectedCacheableResponsesPlugin = { + async cacheWillUpdate({ + response + }) { + return response.redirected ? await copyResponse(response) : response; + } + }; + + /* + Copyright 2019 Google LLC + + Use of this source code is governed by an MIT-style + license that can be found in the LICENSE file or at + https://opensource.org/licenses/MIT. + */ + /** + * Performs efficient precaching of assets. + * + * @memberof workbox-precaching + */ + class PrecacheController { + /** + * Create a new PrecacheController. + * + * @param {Object} [options] + * @param {string} [options.cacheName] The cache to use for precaching. + * @param {string} [options.plugins] Plugins to use when precaching as well + * as responding to fetch events for precached assets. + * @param {boolean} [options.fallbackToNetwork=true] Whether to attempt to + * get the response from the network if there's a precache miss. + */ + constructor({ + cacheName, + plugins = [], + fallbackToNetwork = true + } = {}) { + this._urlsToCacheKeys = new Map(); + this._urlsToCacheModes = new Map(); + this._cacheKeysToIntegrities = new Map(); + this._strategy = new PrecacheStrategy({ + cacheName: cacheNames.getPrecacheName(cacheName), + plugins: [...plugins, new PrecacheCacheKeyPlugin({ + precacheController: this + })], + fallbackToNetwork + }); + // Bind the install and activate methods to the instance. + this.install = this.install.bind(this); + this.activate = this.activate.bind(this); + } + /** + * @type {workbox-precaching.PrecacheStrategy} The strategy created by this controller and + * used to cache assets and respond to fetch events. + */ + get strategy() { + return this._strategy; + } + /** + * Adds items to the precache list, removing any duplicates and + * stores the files in the + * {@link workbox-core.cacheNames|"precache cache"} when the service + * worker installs. + * + * This method can be called multiple times. + * + * @param {Array} [entries=[]] Array of entries to precache. + */ + precache(entries) { + this.addToCacheList(entries); + if (!this._installAndActiveListenersAdded) { + self.addEventListener('install', this.install); + self.addEventListener('activate', this.activate); + this._installAndActiveListenersAdded = true; + } + } + /** + * This method will add items to the precache list, removing duplicates + * and ensuring the information is valid. + * + * @param {Array} entries + * Array of entries to precache. + */ + addToCacheList(entries) { + { + finalAssertExports.isArray(entries, { + moduleName: 'workbox-precaching', + className: 'PrecacheController', + funcName: 'addToCacheList', + paramName: 'entries' + }); + } + const urlsToWarnAbout = []; + for (const entry of entries) { + // See https://github.com/GoogleChrome/workbox/issues/2259 + if (typeof entry === 'string') { + urlsToWarnAbout.push(entry); + } else if (entry && entry.revision === undefined) { + urlsToWarnAbout.push(entry.url); + } + const { + cacheKey, + url + } = createCacheKey(entry); + const cacheMode = typeof entry !== 'string' && entry.revision ? 'reload' : 'default'; + if (this._urlsToCacheKeys.has(url) && this._urlsToCacheKeys.get(url) !== cacheKey) { + throw new WorkboxError('add-to-cache-list-conflicting-entries', { + firstEntry: this._urlsToCacheKeys.get(url), + secondEntry: cacheKey + }); + } + if (typeof entry !== 'string' && entry.integrity) { + if (this._cacheKeysToIntegrities.has(cacheKey) && this._cacheKeysToIntegrities.get(cacheKey) !== entry.integrity) { + throw new WorkboxError('add-to-cache-list-conflicting-integrities', { + url + }); + } + this._cacheKeysToIntegrities.set(cacheKey, entry.integrity); + } + this._urlsToCacheKeys.set(url, cacheKey); + this._urlsToCacheModes.set(url, cacheMode); + if (urlsToWarnAbout.length > 0) { + const warningMessage = `Workbox is precaching URLs without revision ` + `info: ${urlsToWarnAbout.join(', ')}\nThis is generally NOT safe. ` + `Learn more at https://bit.ly/wb-precache`; + { + logger.warn(warningMessage); + } + } + } + } + /** + * Precaches new and updated assets. Call this method from the service worker + * install event. + * + * Note: this method calls `event.waitUntil()` for you, so you do not need + * to call it yourself in your event handlers. + * + * @param {ExtendableEvent} event + * @return {Promise} + */ + install(event) { + // waitUntil returns Promise + // eslint-disable-next-line @typescript-eslint/no-unsafe-return + return waitUntil(event, async () => { + const installReportPlugin = new PrecacheInstallReportPlugin(); + this.strategy.plugins.push(installReportPlugin); + // Cache entries one at a time. + // See https://github.com/GoogleChrome/workbox/issues/2528 + for (const [url, cacheKey] of this._urlsToCacheKeys) { + const integrity = this._cacheKeysToIntegrities.get(cacheKey); + const cacheMode = this._urlsToCacheModes.get(url); + const request = new Request(url, { + integrity, + cache: cacheMode, + credentials: 'same-origin' + }); + await Promise.all(this.strategy.handleAll({ + params: { + cacheKey + }, + request, + event + })); + } + const { + updatedURLs, + notUpdatedURLs + } = installReportPlugin; + { + printInstallDetails(updatedURLs, notUpdatedURLs); + } + return { + updatedURLs, + notUpdatedURLs + }; + }); + } + /** + * Deletes assets that are no longer present in the current precache manifest. + * Call this method from the service worker activate event. + * + * Note: this method calls `event.waitUntil()` for you, so you do not need + * to call it yourself in your event handlers. + * + * @param {ExtendableEvent} event + * @return {Promise} + */ + activate(event) { + // waitUntil returns Promise + // eslint-disable-next-line @typescript-eslint/no-unsafe-return + return waitUntil(event, async () => { + const cache = await self.caches.open(this.strategy.cacheName); + const currentlyCachedRequests = await cache.keys(); + const expectedCacheKeys = new Set(this._urlsToCacheKeys.values()); + const deletedURLs = []; + for (const request of currentlyCachedRequests) { + if (!expectedCacheKeys.has(request.url)) { + await cache.delete(request); + deletedURLs.push(request.url); + } + } + { + printCleanupDetails(deletedURLs); + } + return { + deletedURLs + }; + }); + } + /** + * Returns a mapping of a precached URL to the corresponding cache key, taking + * into account the revision information for the URL. + * + * @return {Map} A URL to cache key mapping. + */ + getURLsToCacheKeys() { + return this._urlsToCacheKeys; + } + /** + * Returns a list of all the URLs that have been precached by the current + * service worker. + * + * @return {Array} The precached URLs. + */ + getCachedURLs() { + return [...this._urlsToCacheKeys.keys()]; + } + /** + * Returns the cache key used for storing a given URL. If that URL is + * unversioned, like `/index.html', then the cache key will be the original + * URL with a search parameter appended to it. + * + * @param {string} url A URL whose cache key you want to look up. + * @return {string} The versioned URL that corresponds to a cache key + * for the original URL, or undefined if that URL isn't precached. + */ + getCacheKeyForURL(url) { + const urlObject = new URL(url, location.href); + return this._urlsToCacheKeys.get(urlObject.href); + } + /** + * @param {string} url A cache key whose SRI you want to look up. + * @return {string} The subresource integrity associated with the cache key, + * or undefined if it's not set. + */ + getIntegrityForCacheKey(cacheKey) { + return this._cacheKeysToIntegrities.get(cacheKey); + } + /** + * This acts as a drop-in replacement for + * [`cache.match()`](https://developer.mozilla.org/en-US/docs/Web/API/Cache/match) + * with the following differences: + * + * - It knows what the name of the precache is, and only checks in that cache. + * - It allows you to pass in an "original" URL without versioning parameters, + * and it will automatically look up the correct cache key for the currently + * active revision of that URL. + * + * E.g., `matchPrecache('index.html')` will find the correct precached + * response for the currently active service worker, even if the actual cache + * key is `'/index.html?__WB_REVISION__=1234abcd'`. + * + * @param {string|Request} request The key (without revisioning parameters) + * to look up in the precache. + * @return {Promise} + */ + async matchPrecache(request) { + const url = request instanceof Request ? request.url : request; + const cacheKey = this.getCacheKeyForURL(url); + if (cacheKey) { + const cache = await self.caches.open(this.strategy.cacheName); + return cache.match(cacheKey); + } + return undefined; + } + /** + * Returns a function that looks up `url` in the precache (taking into + * account revision information), and returns the corresponding `Response`. + * + * @param {string} url The precached URL which will be used to lookup the + * `Response`. + * @return {workbox-routing~handlerCallback} + */ + createHandlerBoundToURL(url) { + const cacheKey = this.getCacheKeyForURL(url); + if (!cacheKey) { + throw new WorkboxError('non-precached-url', { + url + }); + } + return options => { + options.request = new Request(url); + options.params = Object.assign({ + cacheKey + }, options.params); + return this.strategy.handle(options); + }; + } + } + + /* + Copyright 2019 Google LLC + + Use of this source code is governed by an MIT-style + license that can be found in the LICENSE file or at + https://opensource.org/licenses/MIT. + */ + let precacheController; + /** + * @return {PrecacheController} + * @private + */ + const getOrCreatePrecacheController = () => { + if (!precacheController) { + precacheController = new PrecacheController(); + } + return precacheController; + }; + + /* + Copyright 2018 Google LLC + + Use of this source code is governed by an MIT-style + license that can be found in the LICENSE file or at + https://opensource.org/licenses/MIT. + */ + /** + * Removes any URL search parameters that should be ignored. + * + * @param {URL} urlObject The original URL. + * @param {Array} ignoreURLParametersMatching RegExps to test against + * each search parameter name. Matches mean that the search parameter should be + * ignored. + * @return {URL} The URL with any ignored search parameters removed. + * + * @private + * @memberof workbox-precaching + */ + function removeIgnoredSearchParams(urlObject, ignoreURLParametersMatching = []) { + // Convert the iterable into an array at the start of the loop to make sure + // deletion doesn't mess up iteration. + for (const paramName of [...urlObject.searchParams.keys()]) { + if (ignoreURLParametersMatching.some(regExp => regExp.test(paramName))) { + urlObject.searchParams.delete(paramName); + } + } + return urlObject; + } + + /* + Copyright 2019 Google LLC + + Use of this source code is governed by an MIT-style + license that can be found in the LICENSE file or at + https://opensource.org/licenses/MIT. + */ + /** + * Generator function that yields possible variations on the original URL to + * check, one at a time. + * + * @param {string} url + * @param {Object} options + * + * @private + * @memberof workbox-precaching + */ + function* generateURLVariations(url, { + ignoreURLParametersMatching = [/^utm_/, /^fbclid$/], + directoryIndex = 'index.html', + cleanURLs = true, + urlManipulation + } = {}) { + const urlObject = new URL(url, location.href); + urlObject.hash = ''; + yield urlObject.href; + const urlWithoutIgnoredParams = removeIgnoredSearchParams(urlObject, ignoreURLParametersMatching); + yield urlWithoutIgnoredParams.href; + if (directoryIndex && urlWithoutIgnoredParams.pathname.endsWith('/')) { + const directoryURL = new URL(urlWithoutIgnoredParams.href); + directoryURL.pathname += directoryIndex; + yield directoryURL.href; + } + if (cleanURLs) { + const cleanURL = new URL(urlWithoutIgnoredParams.href); + cleanURL.pathname += '.html'; + yield cleanURL.href; + } + if (urlManipulation) { + const additionalURLs = urlManipulation({ + url: urlObject + }); + for (const urlToAttempt of additionalURLs) { + yield urlToAttempt.href; + } + } + } + + /* + Copyright 2020 Google LLC + + Use of this source code is governed by an MIT-style + license that can be found in the LICENSE file or at + https://opensource.org/licenses/MIT. + */ + /** + * A subclass of {@link workbox-routing.Route} that takes a + * {@link workbox-precaching.PrecacheController} + * instance and uses it to match incoming requests and handle fetching + * responses from the precache. + * + * @memberof workbox-precaching + * @extends workbox-routing.Route + */ + class PrecacheRoute extends Route { + /** + * @param {PrecacheController} precacheController A `PrecacheController` + * instance used to both match requests and respond to fetch events. + * @param {Object} [options] Options to control how requests are matched + * against the list of precached URLs. + * @param {string} [options.directoryIndex=index.html] The `directoryIndex` will + * check cache entries for a URLs ending with '/' to see if there is a hit when + * appending the `directoryIndex` value. + * @param {Array} [options.ignoreURLParametersMatching=[/^utm_/, /^fbclid$/]] An + * array of regex's to remove search params when looking for a cache match. + * @param {boolean} [options.cleanURLs=true] The `cleanURLs` option will + * check the cache for the URL with a `.html` added to the end of the end. + * @param {workbox-precaching~urlManipulation} [options.urlManipulation] + * This is a function that should take a URL and return an array of + * alternative URLs that should be checked for precache matches. + */ + constructor(precacheController, options) { + const match = ({ + request + }) => { + const urlsToCacheKeys = precacheController.getURLsToCacheKeys(); + for (const possibleURL of generateURLVariations(request.url, options)) { + const cacheKey = urlsToCacheKeys.get(possibleURL); + if (cacheKey) { + const integrity = precacheController.getIntegrityForCacheKey(cacheKey); + return { + cacheKey, + integrity + }; + } + } + { + logger.debug(`Precaching did not find a match for ` + getFriendlyURL(request.url)); + } + return; + }; + super(match, precacheController.strategy); + } + } + + /* + Copyright 2019 Google LLC + Use of this source code is governed by an MIT-style + license that can be found in the LICENSE file or at + https://opensource.org/licenses/MIT. + */ + /** + * Add a `fetch` listener to the service worker that will + * respond to + * [network requests]{@link https://developer.mozilla.org/en-US/docs/Web/API/Service_Worker_API/Using_Service_Workers#Custom_responses_to_requests} + * with precached assets. + * + * Requests for assets that aren't precached, the `FetchEvent` will not be + * responded to, allowing the event to fall through to other `fetch` event + * listeners. + * + * @param {Object} [options] See the {@link workbox-precaching.PrecacheRoute} + * options. + * + * @memberof workbox-precaching + */ + function addRoute(options) { + const precacheController = getOrCreatePrecacheController(); + const precacheRoute = new PrecacheRoute(precacheController, options); + registerRoute(precacheRoute); + } + + /* + Copyright 2019 Google LLC + + Use of this source code is governed by an MIT-style + license that can be found in the LICENSE file or at + https://opensource.org/licenses/MIT. + */ + /** + * Adds items to the precache list, removing any duplicates and + * stores the files in the + * {@link workbox-core.cacheNames|"precache cache"} when the service + * worker installs. + * + * This method can be called multiple times. + * + * Please note: This method **will not** serve any of the cached files for you. + * It only precaches files. To respond to a network request you call + * {@link workbox-precaching.addRoute}. + * + * If you have a single array of files to precache, you can just call + * {@link workbox-precaching.precacheAndRoute}. + * + * @param {Array} [entries=[]] Array of entries to precache. + * + * @memberof workbox-precaching + */ + function precache(entries) { + const precacheController = getOrCreatePrecacheController(); + precacheController.precache(entries); + } + + /* + Copyright 2019 Google LLC + + Use of this source code is governed by an MIT-style + license that can be found in the LICENSE file or at + https://opensource.org/licenses/MIT. + */ + /** + * This method will add entries to the precache list and add a route to + * respond to fetch events. + * + * This is a convenience method that will call + * {@link workbox-precaching.precache} and + * {@link workbox-precaching.addRoute} in a single call. + * + * @param {Array} entries Array of entries to precache. + * @param {Object} [options] See the + * {@link workbox-precaching.PrecacheRoute} options. + * + * @memberof workbox-precaching + */ + function precacheAndRoute(entries, options) { + precache(entries); + addRoute(options); + } + + /* + Copyright 2018 Google LLC + + Use of this source code is governed by an MIT-style + license that can be found in the LICENSE file or at + https://opensource.org/licenses/MIT. + */ + const SUBSTRING_TO_FIND = '-precache-'; + /** + * Cleans up incompatible precaches that were created by older versions of + * Workbox, by a service worker registered under the current scope. + * + * This is meant to be called as part of the `activate` event. + * + * This should be safe to use as long as you don't include `substringToFind` + * (defaulting to `-precache-`) in your non-precache cache names. + * + * @param {string} currentPrecacheName The cache name currently in use for + * precaching. This cache won't be deleted. + * @param {string} [substringToFind='-precache-'] Cache names which include this + * substring will be deleted (excluding `currentPrecacheName`). + * @return {Array} A list of all the cache names that were deleted. + * + * @private + * @memberof workbox-precaching + */ + const deleteOutdatedCaches = async (currentPrecacheName, substringToFind = SUBSTRING_TO_FIND) => { + const cacheNames = await self.caches.keys(); + const cacheNamesToDelete = cacheNames.filter(cacheName => { + return cacheName.includes(substringToFind) && cacheName.includes(self.registration.scope) && cacheName !== currentPrecacheName; + }); + await Promise.all(cacheNamesToDelete.map(cacheName => self.caches.delete(cacheName))); + return cacheNamesToDelete; + }; + + /* + Copyright 2019 Google LLC + + Use of this source code is governed by an MIT-style + license that can be found in the LICENSE file or at + https://opensource.org/licenses/MIT. + */ + /** + * Adds an `activate` event listener which will clean up incompatible + * precaches that were created by older versions of Workbox. + * + * @memberof workbox-precaching + */ + function cleanupOutdatedCaches() { + // See https://github.com/Microsoft/TypeScript/issues/28357#issuecomment-436484705 + self.addEventListener('activate', event => { + const cacheName = cacheNames.getPrecacheName(); + event.waitUntil(deleteOutdatedCaches(cacheName).then(cachesDeleted => { + { + if (cachesDeleted.length > 0) { + logger.log(`The following out-of-date precaches were cleaned up ` + `automatically:`, cachesDeleted); + } + } + })); + }); + } + + /* + Copyright 2018 Google LLC + + Use of this source code is governed by an MIT-style + license that can be found in the LICENSE file or at + https://opensource.org/licenses/MIT. + */ + /** + * NavigationRoute makes it easy to create a + * {@link workbox-routing.Route} that matches for browser + * [navigation requests]{@link https://developers.google.com/web/fundamentals/primers/service-workers/high-performance-loading#first_what_are_navigation_requests}. + * + * It will only match incoming Requests whose + * {@link https://fetch.spec.whatwg.org/#concept-request-mode|mode} + * is set to `navigate`. + * + * You can optionally only apply this route to a subset of navigation requests + * by using one or both of the `denylist` and `allowlist` parameters. + * + * @memberof workbox-routing + * @extends workbox-routing.Route + */ + class NavigationRoute extends Route { + /** + * If both `denylist` and `allowlist` are provided, the `denylist` will + * take precedence and the request will not match this route. + * + * The regular expressions in `allowlist` and `denylist` + * are matched against the concatenated + * [`pathname`]{@link https://developer.mozilla.org/en-US/docs/Web/API/HTMLHyperlinkElementUtils/pathname} + * and [`search`]{@link https://developer.mozilla.org/en-US/docs/Web/API/HTMLHyperlinkElementUtils/search} + * portions of the requested URL. + * + * *Note*: These RegExps may be evaluated against every destination URL during + * a navigation. Avoid using + * [complex RegExps](https://github.com/GoogleChrome/workbox/issues/3077), + * or else your users may see delays when navigating your site. + * + * @param {workbox-routing~handlerCallback} handler A callback + * function that returns a Promise resulting in a Response. + * @param {Object} options + * @param {Array} [options.denylist] If any of these patterns match, + * the route will not handle the request (even if a allowlist RegExp matches). + * @param {Array} [options.allowlist=[/./]] If any of these patterns + * match the URL's pathname and search parameter, the route will handle the + * request (assuming the denylist doesn't match). + */ + constructor(handler, { + allowlist = [/./], + denylist = [] + } = {}) { + { + finalAssertExports.isArrayOfClass(allowlist, RegExp, { + moduleName: 'workbox-routing', + className: 'NavigationRoute', + funcName: 'constructor', + paramName: 'options.allowlist' + }); + finalAssertExports.isArrayOfClass(denylist, RegExp, { + moduleName: 'workbox-routing', + className: 'NavigationRoute', + funcName: 'constructor', + paramName: 'options.denylist' + }); + } + super(options => this._match(options), handler); + this._allowlist = allowlist; + this._denylist = denylist; + } + /** + * Routes match handler. + * + * @param {Object} options + * @param {URL} options.url + * @param {Request} options.request + * @return {boolean} + * + * @private + */ + _match({ + url, + request + }) { + if (request && request.mode !== 'navigate') { + return false; + } + const pathnameAndSearch = url.pathname + url.search; + for (const regExp of this._denylist) { + if (regExp.test(pathnameAndSearch)) { + { + logger.log(`The navigation route ${pathnameAndSearch} is not ` + `being used, since the URL matches this denylist pattern: ` + `${regExp.toString()}`); + } + return false; + } + } + if (this._allowlist.some(regExp => regExp.test(pathnameAndSearch))) { + { + logger.debug(`The navigation route ${pathnameAndSearch} ` + `is being used.`); + } + return true; + } + { + logger.log(`The navigation route ${pathnameAndSearch} is not ` + `being used, since the URL being navigated to doesn't ` + `match the allowlist.`); + } + return false; + } + } + + /* + Copyright 2019 Google LLC + + Use of this source code is governed by an MIT-style + license that can be found in the LICENSE file or at + https://opensource.org/licenses/MIT. + */ + /** + * Helper function that calls + * {@link PrecacheController#createHandlerBoundToURL} on the default + * {@link PrecacheController} instance. + * + * If you are creating your own {@link PrecacheController}, then call the + * {@link PrecacheController#createHandlerBoundToURL} on that instance, + * instead of using this function. + * + * @param {string} url The precached URL which will be used to lookup the + * `Response`. + * @param {boolean} [fallbackToNetwork=true] Whether to attempt to get the + * response from the network if there's a precache miss. + * @return {workbox-routing~handlerCallback} + * + * @memberof workbox-precaching + */ + function createHandlerBoundToURL(url) { + const precacheController = getOrCreatePrecacheController(); + return precacheController.createHandlerBoundToURL(url); + } + + exports.CacheFirst = CacheFirst; + exports.ExpirationPlugin = ExpirationPlugin; + exports.NavigationRoute = NavigationRoute; + exports.NetworkFirst = NetworkFirst; + exports.cleanupOutdatedCaches = cleanupOutdatedCaches; + exports.createHandlerBoundToURL = createHandlerBoundToURL; + exports.precacheAndRoute = precacheAndRoute; + exports.registerRoute = registerRoute; + +})); diff --git a/public/manifest.json b/public/manifest.json index a346426..ad0f651 100644 --- a/public/manifest.json +++ b/public/manifest.json @@ -9,10 +9,10 @@ "orientation": "portrait-primary", "scope": "/", "lang": "ru", - "id": "/", "categories": ["productivity", "utilities"], "prefer_related_applications": false, "display_override": ["window-controls-overlay", "standalone"], + "dir": "ltr", "screenshots": [ { "src": "/icons/icon-512x512.png", diff --git a/src/App.tsx b/src/App.tsx index 2a9e481..9b7c16e 100644 --- a/src/App.tsx +++ b/src/App.tsx @@ -8,6 +8,7 @@ import NotesPage from "./pages/NotesPage"; import ProfilePage from "./pages/ProfilePage"; import SettingsPage from "./pages/SettingsPage"; import { NotificationStack } from "./components/common/Notification"; +import { InstallPrompt } from "./components/common/InstallPrompt"; import { ProtectedRoute } from "./components/ProtectedRoute"; import { useTheme } from "./hooks/useTheme"; @@ -17,6 +18,7 @@ const AppContent: React.FC = () => { return ( <> + } /> diff --git a/src/components/common/InstallPrompt.tsx b/src/components/common/InstallPrompt.tsx new file mode 100644 index 0000000..ba343b4 --- /dev/null +++ b/src/components/common/InstallPrompt.tsx @@ -0,0 +1,155 @@ +import React, { useState, useEffect } from "react"; +import { Icon } from "@iconify/react"; + +interface BeforeInstallPromptEvent extends Event { + prompt(): Promise; + userChoice: Promise<{ outcome: "accepted" | "dismissed" }>; +} + +export const InstallPrompt: React.FC = () => { + const [deferredPrompt, setDeferredPrompt] = + useState(null); + const [showPrompt, setShowPrompt] = useState(false); + + useEffect(() => { + const handler = (e: Event) => { + e.preventDefault(); + setDeferredPrompt(e as BeforeInstallPromptEvent); + // Показываем промпт через небольшую задержку + setTimeout(() => setShowPrompt(true), 2000); + }; + + window.addEventListener("beforeinstallprompt", handler); + + // Проверяем, не установлено ли приложение уже + if (window.matchMedia("(display-mode: standalone)").matches) { + setShowPrompt(false); + } + + return () => { + window.removeEventListener("beforeinstallprompt", handler); + }; + }, []); + + const handleInstallClick = async () => { + if (!deferredPrompt) return; + + deferredPrompt.prompt(); + const { outcome } = await deferredPrompt.userChoice; + + if (outcome === "accepted") { + console.log("Пользователь принял предложение об установке"); + } else { + console.log("Пользователь отклонил предложение об установке"); + } + + setDeferredPrompt(null); + setShowPrompt(false); + }; + + const handleDismiss = () => { + setShowPrompt(false); + // Сохраняем в localStorage, что пользователь закрыл промпт + localStorage.setItem("pwa-install-dismissed", "true"); + }; + + // Не показываем, если пользователь уже закрыл промпт + useEffect(() => { + if (localStorage.getItem("pwa-install-dismissed") === "true") { + setShowPrompt(false); + } + }, []); + + if (!showPrompt || !deferredPrompt) { + return null; + } + + return ( +
    +
    +
    + Установить NoteJS? +
    +
    + Установите приложение для быстрого доступа +
    +
    +
    + + +
    +
    + ); +}; + diff --git a/src/components/layout/Header.tsx b/src/components/layout/Header.tsx index 82049d2..a16cb67 100644 --- a/src/components/layout/Header.tsx +++ b/src/components/layout/Header.tsx @@ -2,11 +2,6 @@ import React, { useEffect } from "react"; import { useNavigate } from "react-router-dom"; import { Icon } from "@iconify/react"; import { useAppSelector, useAppDispatch } from "../../store/hooks"; -import { - setSelectedDate, - setSelectedTag, - setSearchQuery, -} from "../../store/slices/notesSlice"; import { userApi } from "../../api/userApi"; import { ThemeToggle } from "../common/ThemeToggle"; import { setUser, setAiSettings } from "../../store/slices/profileSlice"; @@ -60,35 +55,6 @@ export const Header: React.FC = ({ } }; - const handleClearFilters = () => { - dispatch(setSelectedDate(null)); - dispatch(setSelectedTag(null)); - dispatch(setSearchQuery("")); - }; - - const hasFilters = !!(selectedDate || selectedTag || searchQuery); - - // Формируем список активных фильтров - const getActiveFilters = () => { - const filters: string[] = []; - - if (searchQuery) { - filters.push(`Поиск: "${searchQuery}"`); - } - - if (selectedDate) { - filters.push(`Дата: ${selectedDate}`); - } - - if (selectedTag) { - filters.push(`Тег: #${selectedTag}`); - } - - return filters; - }; - - const activeFilters = getActiveFilters(); - return ( <> {/* Кнопка мобильного меню */} @@ -103,14 +69,6 @@ export const Header: React.FC = ({ Мои заметки - {hasFilters && ( -
    - - Фильтр: {activeFilters.join(", ")} - {" "} - -
    - )}
    {user?.avatar ? ( diff --git a/src/components/notes/MarkdownToolbar.tsx b/src/components/notes/MarkdownToolbar.tsx index e9babc4..e6d7817 100644 --- a/src/components/notes/MarkdownToolbar.tsx +++ b/src/components/notes/MarkdownToolbar.tsx @@ -27,7 +27,10 @@ export const MarkdownToolbar: React.FC = ({ const [isDragging, setIsDragging] = useState(false); const [startX, setStartX] = useState(0); const [scrollLeft, setScrollLeft] = useState(0); - const [menuPosition, setMenuPosition] = useState<{ top: number; left: number } | null>(null); + const [menuPosition, setMenuPosition] = useState<{ + top: number; + left: number; + } | null>(null); useEffect(() => { const handleClickOutside = (event: MouseEvent) => { @@ -163,7 +166,7 @@ export const MarkdownToolbar: React.FC = ({ /> {showHeaderDropdown && menuPosition && ( -
    = ({ onSave }) => { // Проверяем, есть ли текст в редакторе const hasText = content.trim().length > 0; - + const position = getCursorPosition(); if (position && hasText) { setToolbarPosition({ top: position.top, left: position.left }); @@ -831,7 +831,8 @@ export const NoteEditor: React.FC = ({ onSave }) => { const textarea = textareaRef.current; if (textarea) { const hasText = textarea.value.trim().length > 0; - const hasSelection = textarea.selectionStart !== textarea.selectionEnd; + const hasSelection = + textarea.selectionStart !== textarea.selectionEnd; // Блокируем браузерное меню только если есть текст И есть выделение if (hasText && hasSelection) { e.preventDefault(); diff --git a/src/components/notes/NoteItem.tsx b/src/components/notes/NoteItem.tsx index 83ecb80..bdfd45e 100644 --- a/src/components/notes/NoteItem.tsx +++ b/src/components/notes/NoteItem.tsx @@ -534,7 +534,7 @@ export const NoteItem: React.FC = ({ // Проверяем, есть ли текст в редакторе const hasText = editContent.trim().length > 0; - + const position = getCursorPosition(); if (position && hasText) { setToolbarPosition({ top: position.top, left: position.left }); @@ -1115,7 +1115,8 @@ export const NoteItem: React.FC = ({ const textarea = editTextareaRef.current; if (textarea) { const hasText = textarea.value.trim().length > 0; - const hasSelection = textarea.selectionStart !== textarea.selectionEnd; + const hasSelection = + textarea.selectionStart !== textarea.selectionEnd; // Блокируем браузерное меню только если есть текст И есть выделение if (hasText && hasSelection) { e.preventDefault(); @@ -1337,7 +1338,9 @@ export const NoteItem: React.FC = ({ <>
    { @@ -1356,7 +1359,9 @@ export const NoteItem: React.FC = ({ onClick={toggleExpand} type="button" > - + {isExpanded ? "Скрыть" : "Раскрыть"} )} diff --git a/src/components/notes/NotesList.tsx b/src/components/notes/NotesList.tsx index 1803268..60e63f5 100644 --- a/src/components/notes/NotesList.tsx +++ b/src/components/notes/NotesList.tsx @@ -111,9 +111,7 @@ export const NotesList = forwardRef((props, ref) => { return (
    -

    - {message} -

    +

    {message}

    ); } diff --git a/src/main.tsx b/src/main.tsx index fcd4ade..99987ac 100644 --- a/src/main.tsx +++ b/src/main.tsx @@ -6,6 +6,8 @@ import "./styles/theme.css"; import "./styles/style.css"; import "./styles/style-calendar.css"; +// Регистрация PWA (vite-plugin-pwa автоматически внедряет регистрацию через injectRegister: "auto") + ReactDOM.createRoot(document.getElementById("root")!).render( diff --git a/src/pages/LoginPage.tsx b/src/pages/LoginPage.tsx index 2546b68..2cbffd1 100644 --- a/src/pages/LoginPage.tsx +++ b/src/pages/LoginPage.tsx @@ -135,11 +135,6 @@ const LoginPage: React.FC = () => { Нет аккаунта? Зарегистрируйтесь

    -
    -

    - Создатель: Fovway -

    -
    ); }; diff --git a/src/pages/NotesPage.tsx b/src/pages/NotesPage.tsx index 8ec9b51..77037cf 100644 --- a/src/pages/NotesPage.tsx +++ b/src/pages/NotesPage.tsx @@ -5,12 +5,49 @@ import { MobileSidebar } from "../components/layout/MobileSidebar"; import { NoteEditor } from "../components/notes/NoteEditor"; import { NotesList, NotesListRef } from "../components/notes/NotesList"; import { ImageModal } from "../components/common/ImageModal"; -import { useAppSelector } from "../store/hooks"; +import { useAppSelector, useAppDispatch } from "../store/hooks"; +import { + setSelectedDate, + setSelectedTag, + setSearchQuery, +} from "../store/slices/notesSlice"; const NotesPage: React.FC = () => { const allNotes = useAppSelector((state) => state.notes.allNotes); const notesListRef = useRef(null); const [isMobileSidebarOpen, setIsMobileSidebarOpen] = useState(false); + const dispatch = useAppDispatch(); + const selectedDate = useAppSelector((state) => state.notes.selectedDate); + const selectedTag = useAppSelector((state) => state.notes.selectedTag); + const searchQuery = useAppSelector((state) => state.notes.searchQuery); + + const hasFilters = !!(selectedDate || selectedTag || searchQuery); + + const handleClearFilters = () => { + dispatch(setSelectedDate(null)); + dispatch(setSelectedTag(null)); + dispatch(setSearchQuery("")); + }; + + const getActiveFilters = () => { + const filters: string[] = []; + + if (searchQuery) { + filters.push(`Поиск: "${searchQuery}"`); + } + + if (selectedDate) { + filters.push(`Дата: ${selectedDate}`); + } + + if (selectedTag) { + filters.push(`Тег: #${selectedTag}`); + } + + return filters; + }; + + const activeFilters = getActiveFilters(); const handleNoteSave = () => { // Вызываем перезагрузку заметок после создания новой заметки @@ -37,14 +74,17 @@ const NotesPage: React.FC = () => {
    + {hasFilters && ( +
    + + Фильтр: {activeFilters.join(", ")} + {" "} + +
    + )}
    -
    -

    - Создатель: Fovway -

    -
    diff --git a/src/pages/RegisterPage.tsx b/src/pages/RegisterPage.tsx index e5b48ea..aed3c19 100644 --- a/src/pages/RegisterPage.tsx +++ b/src/pages/RegisterPage.tsx @@ -156,11 +156,6 @@ const RegisterPage: React.FC = () => { Уже есть аккаунт? Войдите

    -
    -

    - Создатель: Fovway -

    -
    ); }; diff --git a/src/styles/style.css b/src/styles/style.css index d0e73f4..c984662 100644 --- a/src/styles/style.css +++ b/src/styles/style.css @@ -329,19 +329,22 @@ header .iconify[data-icon="mdi:account-plus"] { header { font-size: 20px; font-weight: bold; - margin-bottom: 20px; } .notes-header { display: flex; justify-content: space-between; align-items: flex-start; + width: 100%; + box-sizing: border-box; } .notes-header-left { display: flex; flex-direction: column; align-items: flex-start; + flex: 1; + min-width: 0; } /* Стили для секции поиска в левой панели */ @@ -408,7 +411,7 @@ header { .filter-indicator { display: inline-flex; align-items: center; - margin-top: 5px; + margin-top: 15px; padding: 4px 10px; background-color: rgba(var(--accent-color-rgb), 0.1); border: 1px solid rgba(var(--accent-color-rgb), 0.3); @@ -416,7 +419,8 @@ header { font-size: 12px; color: var(--accent-color); font-weight: 500; - max-width: 300px; + max-width: min(300px, 100%); + box-sizing: border-box; } .filter-indicator-text { @@ -454,6 +458,7 @@ header { display: flex; align-items: center; gap: 15px; + flex-shrink: 0; } .user-info span { @@ -510,27 +515,25 @@ header { background: var(--bg-secondary); color: var(--text-secondary); cursor: pointer; + font-size: 18px; + transition: all 0.3s ease; display: flex; align-items: center; justify-content: center; - transition: all 0.3s ease; flex-shrink: 0; } .settings-icon-btn:hover { - background: var(--accent-color, #007bff); + background-color: var(--accent-color, #007bff); color: white; - transform: rotate(45deg); + transform: scale(1.1); } .settings-icon-btn .iconify { - font-size: 20px; - color: #666; + font-size: 18px; + color: var(--text-secondary); transition: color 0.3s ease; margin: 0; - padding: 0; - line-height: 1; - vertical-align: baseline; } .settings-icon-btn:hover .iconify { @@ -2698,10 +2701,8 @@ textarea:focus { .user-info { flex-shrink: 0; - justify-content: flex-end; flex-wrap: wrap; gap: 8px; - max-width: calc(100vw - 120px); } .user-info .back-btn { @@ -2717,7 +2718,7 @@ textarea:focus { /* Дополнительная адаптация для очень маленьких экранов */ @media (max-width: 480px) { .user-info { - max-width: calc(100vw - 100px); + flex-shrink: 0; gap: 4px; } @@ -2735,6 +2736,16 @@ textarea:focus { .user-info .theme-toggle-btn .iconify { font-size: 16px; } + + .settings-icon-btn { + width: 32px; + height: 32px; + padding: 6px; + } + + .settings-icon-btn .iconify { + font-size: 16px; + } } /* Адаптируем кнопки markdown */ @@ -4750,18 +4761,12 @@ textarea:focus { gap: 8px; } - .user-info { - justify-content: flex-end; - } - /* Фильтры */ .filter-indicator { font-size: 12px; display: inline-flex !important; - width: auto !important; - min-width: 0 !important; - flex: 0 0 auto !important; - align-self: flex-start !important; + max-width: min(300px, 100%) !important; + width: fit-content !important; box-sizing: border-box !important; } diff --git a/vite.config.ts b/vite.config.ts index 69908fe..fa06bd7 100644 --- a/vite.config.ts +++ b/vite.config.ts @@ -8,13 +8,122 @@ export default defineConfig({ react(), VitePWA({ registerType: "prompt", + injectRegister: "auto", + includeAssets: [ + "icon.svg", + "icons/icon-192x192.png", + "icons/icon-512x512.png", + ], + manifest: { + name: "NoteJS - Система заметок", + short_name: "NoteJS", + description: + "Современная система заметок с поддержкой Markdown, изображений, тегов и календаря", + theme_color: "#007bff", + background_color: "#ffffff", + display: "standalone", + orientation: "portrait-primary", + scope: "/", + start_url: "/", + icons: [ + { + src: "/icons/icon-72x72.png", + sizes: "72x72", + type: "image/png", + purpose: "any", + }, + { + src: "/icons/icon-96x96.png", + sizes: "96x96", + type: "image/png", + purpose: "any", + }, + { + src: "/icons/icon-128x128.png", + sizes: "128x128", + type: "image/png", + purpose: "any", + }, + { + src: "/icons/icon-144x144.png", + sizes: "144x144", + type: "image/png", + purpose: "any", + }, + { + src: "/icons/icon-152x152.png", + sizes: "152x152", + type: "image/png", + purpose: "any", + }, + { + src: "/icons/icon-192x192.png", + sizes: "192x192", + type: "image/png", + purpose: "any", + }, + { + src: "/icons/icon-384x384.png", + sizes: "384x384", + type: "image/png", + purpose: "any", + }, + { + src: "/icons/icon-512x512.png", + sizes: "512x512", + type: "image/png", + purpose: "any", + }, + { + src: "/icons/icon-192x192.png", + sizes: "192x192", + type: "image/png", + purpose: "maskable", + }, + { + src: "/icons/icon-512x512.png", + sizes: "512x512", + type: "image/png", + purpose: "maskable", + }, + ], + }, workbox: { - globPatterns: ["**/*.{js,css,html,ico,png,svg}"], + globPatterns: ["**/*.{js,css,html,ico,png,svg,woff,woff2,ttf,eot}"], + runtimeCaching: [ + { + urlPattern: /^https:\/\/api\./, + handler: "NetworkFirst", + options: { + cacheName: "api-cache", + expiration: { + maxEntries: 50, + maxAgeSeconds: 60 * 60, // 1 hour + }, + }, + }, + { + urlPattern: /\.(?:png|jpg|jpeg|svg|gif|webp)$/, + handler: "CacheFirst", + options: { + cacheName: "images-cache", + expiration: { + maxEntries: 100, + maxAgeSeconds: 30 * 24 * 60 * 60, // 30 days + }, + }, + }, + ], + }, + devOptions: { + enabled: true, + type: "module", }, }), ], server: { port: 5173, + allowedHosts: ["notes.fovway.ru", "localhost"], proxy: { "/api": { target: "http://localhost:3001",