From bcaeed51911794c27650f58aa6e9af0f8997c6af Mon Sep 17 00:00:00 2001 From: sairaj mote Date: Mon, 23 Oct 2023 18:43:12 +0530 Subject: [PATCH] Bug fixes --- components/dist/form.js | 9 ++++++--- components/dist/form.min.js | 2 +- main_UI.js | 27 +++++++++++++-------------- main_UI.min.js | 2 +- 4 files changed, 21 insertions(+), 19 deletions(-) diff --git a/components/dist/form.js b/components/dist/form.js index 16148b3..9a0f5a6 100644 --- a/components/dist/form.js +++ b/components/dist/form.js @@ -132,6 +132,9 @@ customElements.define('sm-form', class extends HTMLElement { } this._checkValidity(); } + checkIfSupported = (elem) => { + return elem.nodeType === 1 && (elem.tagName.includes('-') || elem.tagName === 'input') || elem.querySelector(this.supportedElements) + } connectedCallback() { const updateFormDecedents = this.debounce(this.elementsChanged, 100); this.addEventListener('input', this.debounce(this._checkValidity, 100)); @@ -141,8 +144,8 @@ customElements.define('sm-form', class extends HTMLElement { mutations.forEach(mutation => { if ( mutation.type === 'childList' && - [...mutation.addedNodes].some(node => node.nodeType === 1 && node.querySelector(this.supportedElements)) || - [...mutation.removedNodes].some(node => node.nodeType === 1 && node.querySelector(this.supportedElements)) + [...mutation.addedNodes].some(node => this.checkIfSupported(node)) || + [...mutation.removedNodes].some(node => this.checkIfSupported(node)) ) { updateFormDecedents(); } @@ -152,7 +155,7 @@ customElements.define('sm-form', class extends HTMLElement { } attributeChangedCallback(name, oldValue, newValue) { if (name === 'skip-submit') { - this.skipSubmit = newValue !== null; + this.skipSubmit = this.hasAttribute('skip-submit'); } } diff --git a/components/dist/form.min.js b/components/dist/form.min.js index a7b5084..b8d4c83 100644 --- a/components/dist/form.min.js +++ b/components/dist/form.min.js @@ -1 +1 @@ -const smForm=document.createElement("template");smForm.innerHTML='\n \n
\n \n
\n ',customElements.define("sm-form",class extends HTMLElement{constructor(){super(),this.attachShadow({mode:"open"}).append(smForm.content.cloneNode(!0)),this.form=this.shadowRoot.querySelector("form"),this.invalidFieldsCount,this.skipSubmit=!1,this.isFormValid=void 0,this.supportedElements="input, sm-input, sm-textarea, sm-checkbox, tags-input, file-input, sm-switch, sm-radio",this.formElements=[],this._requiredElements=[]}static get observedAttributes(){return["skip-submit"]}get validity(){return this.isFormValid}debounce=(callback,wait)=>{let timeoutId=null;return(...args)=>{window.clearTimeout(timeoutId),timeoutId=window.setTimeout((()=>{callback.apply(null,args)}),wait)}};_checkValidity=()=>{this.submitButton&&0!==this._requiredElements.length&&(this.invalidFieldsCount=0,this._requiredElements.forEach((([elem,isWC])=>{(!elem.disabled&&isWC&&!elem.isValid||!isWC&&!elem.checkValidity())&&this.invalidFieldsCount++})),this.isFormValid!==(0===this.invalidFieldsCount)&&(this.isFormValid=0===this.invalidFieldsCount,this.dispatchEvent(new CustomEvent(this.isFormValid?"valid":"invalid",{bubbles:!0,composed:!0})),this.skipSubmit||(this.submitButton.disabled=!this.isFormValid)))};handleKeydown=e=>{if("Enter"===e.key&&e.target.tagName.includes("INPUT"))if(0===this.invalidFieldsCount)this.submitButton&&this.submitButton.click(),this.dispatchEvent(new CustomEvent("submit",{bubbles:!0,composed:!0}));else for(const[elem,isWC]of this._requiredElements){if(isWC?!elem.isValid:!elem.checkValidity()){(elem?.shadowRoot?.lastElementChild||elem).animate([{transform:"translateX(-1rem)"},{transform:"translateX(1rem)"},{transform:"translateX(-0.5rem)"},{transform:"translateX(0.5rem)"},{transform:"translateX(0)"}],{duration:300,easing:"ease"}),isWC?(elem.focusIn(),"SM-INPUT"===elem.tagName&&""===elem.value.trim()&&elem.showError()):elem.focus();break}}};reset=()=>{this.formElements.forEach((([elem,isWC])=>{if(isWC)elem.reset();else switch(elem.type){case"checkbox":case"radio":elem.checked=!1;break;default:elem.value=""}})),this._checkValidity()};elementsChanged=()=>{this.formElements=[...this.querySelectorAll(this.supportedElements)].map((elem=>[elem,elem.tagName.includes("-")])),this._requiredElements=this.formElements.filter((([elem])=>elem.hasAttribute("required"))),this.submitButton=this.querySelector('[variant="primary"], [type="submit"]'),this.resetButton=this.querySelector('[type="reset"]'),this.resetButton&&this.resetButton.addEventListener("click",this.reset),this._checkValidity()};connectedCallback(){const updateFormDecedents=this.debounce(this.elementsChanged,100);this.addEventListener("input",this.debounce(this._checkValidity,100)),this.addEventListener("keydown",this.debounce(this.handleKeydown,100)),this.shadowRoot.querySelector("slot").addEventListener("slotchange",updateFormDecedents),this.mutationObserver=new MutationObserver((mutations=>{mutations.forEach((mutation=>{("childList"===mutation.type&&[...mutation.addedNodes].some((node=>1===node.nodeType&&node.querySelector(this.supportedElements)))||[...mutation.removedNodes].some((node=>1===node.nodeType&&node.querySelector(this.supportedElements))))&&updateFormDecedents()}))})),this.mutationObserver.observe(this,{childList:!0,subtree:!0})}attributeChangedCallback(name,oldValue,newValue){"skip-submit"===name&&(this.skipSubmit=null!==newValue)}disconnectedCallback(){this.removeEventListener("input",this.debounce(this._checkValidity,100)),this.removeEventListener("keydown",this.debounce(this.handleKeydown,100)),this.mutationObserver.disconnect()}}); \ No newline at end of file +const smForm=document.createElement("template");smForm.innerHTML='\n \n
\n \n
\n ',customElements.define("sm-form",class extends HTMLElement{constructor(){super(),this.attachShadow({mode:"open"}).append(smForm.content.cloneNode(!0)),this.form=this.shadowRoot.querySelector("form"),this.invalidFieldsCount,this.skipSubmit=!1,this.isFormValid=void 0,this.supportedElements="input, sm-input, sm-textarea, sm-checkbox, tags-input, file-input, sm-switch, sm-radio",this.formElements=[],this._requiredElements=[]}static get observedAttributes(){return["skip-submit"]}get validity(){return this.isFormValid}debounce=(callback,wait)=>{let timeoutId=null;return(...args)=>{window.clearTimeout(timeoutId),timeoutId=window.setTimeout((()=>{callback.apply(null,args)}),wait)}};_checkValidity=()=>{this.submitButton&&0!==this._requiredElements.length&&(this.invalidFieldsCount=0,this._requiredElements.forEach((([elem,isWC])=>{(!elem.disabled&&isWC&&!elem.isValid||!isWC&&!elem.checkValidity())&&this.invalidFieldsCount++})),this.isFormValid!==(0===this.invalidFieldsCount)&&(this.isFormValid=0===this.invalidFieldsCount,this.dispatchEvent(new CustomEvent(this.isFormValid?"valid":"invalid",{bubbles:!0,composed:!0})),this.skipSubmit||(this.submitButton.disabled=!this.isFormValid)))};handleKeydown=e=>{if("Enter"===e.key&&e.target.tagName.includes("INPUT"))if(0===this.invalidFieldsCount)this.submitButton&&this.submitButton.click(),this.dispatchEvent(new CustomEvent("submit",{bubbles:!0,composed:!0}));else for(const[elem,isWC]of this._requiredElements){if(isWC?!elem.isValid:!elem.checkValidity()){(elem?.shadowRoot?.lastElementChild||elem).animate([{transform:"translateX(-1rem)"},{transform:"translateX(1rem)"},{transform:"translateX(-0.5rem)"},{transform:"translateX(0.5rem)"},{transform:"translateX(0)"}],{duration:300,easing:"ease"}),isWC?(elem.focusIn(),"SM-INPUT"===elem.tagName&&""===elem.value.trim()&&elem.showError()):elem.focus();break}}};reset=()=>{this.formElements.forEach((([elem,isWC])=>{if(isWC)elem.reset();else switch(elem.type){case"checkbox":case"radio":elem.checked=!1;break;default:elem.value=""}})),this._checkValidity()};elementsChanged=()=>{this.formElements=[...this.querySelectorAll(this.supportedElements)].map((elem=>[elem,elem.tagName.includes("-")])),this._requiredElements=this.formElements.filter((([elem])=>elem.hasAttribute("required"))),this.submitButton=this.querySelector('[variant="primary"], [type="submit"]'),this.resetButton=this.querySelector('[type="reset"]'),this.resetButton&&this.resetButton.addEventListener("click",this.reset),this._checkValidity()};checkIfSupported=elem=>1===elem.nodeType&&(elem.tagName.includes("-")||"input"===elem.tagName)||elem.querySelector(this.supportedElements);connectedCallback(){const updateFormDecedents=this.debounce(this.elementsChanged,100);this.addEventListener("input",this.debounce(this._checkValidity,100)),this.addEventListener("keydown",this.debounce(this.handleKeydown,100)),this.shadowRoot.querySelector("slot").addEventListener("slotchange",updateFormDecedents),this.mutationObserver=new MutationObserver((mutations=>{mutations.forEach((mutation=>{("childList"===mutation.type&&[...mutation.addedNodes].some((node=>this.checkIfSupported(node)))||[...mutation.removedNodes].some((node=>this.checkIfSupported(node))))&&updateFormDecedents()}))})),this.mutationObserver.observe(this,{childList:!0,subtree:!0})}attributeChangedCallback(name,oldValue,newValue){"skip-submit"===name&&(this.skipSubmit=this.hasAttribute("skip-submit"))}disconnectedCallback(){this.removeEventListener("input",this.debounce(this._checkValidity,100)),this.removeEventListener("keydown",this.debounce(this.handleKeydown,100)),this.mutationObserver.disconnect()}}); \ No newline at end of file diff --git a/main_UI.js b/main_UI.js index 5f4a097..73d66ce 100644 --- a/main_UI.js +++ b/main_UI.js @@ -810,34 +810,33 @@ function buttonLoader(id, show) { let currentSubscriber = null; /** * @param {any} initialValue - initial value for the signal + * @param {function} [Optional] callback - function to be called when the signal changes * @returns {array} - array containing getter and setter for the signal * @example * const [getCount, setCount] = $signal(0); */ -function $signal(initialValue) { +function $signal(initialValue, callback) { let value = initialValue; const subscribers = new Set(); - - function getter() { + let hasCustomSubscriber = false; + function getter(subscriber) { if (currentSubscriber) { - const weakRef = new WeakRef({ func: currentSubscriber }); - subscribers.add(weakRef); + subscribers.add(currentSubscriber); + } + if (!hasCustomSubscriber && subscriber) { + subscribers.add(subscriber) + hasCustomSubscriber = true } return value; } function setter(newValue) { - if (newValue !== value) { - value = newValue; - for (const subscriber of subscribers) { - const ref = subscriber.deref(); - if (ref) { - ref.func(); - } - } + if (newValue === value) return; + value = newValue; + for (const subscriber of subscribers) { + subscriber(); } } - return [getter, setter]; } /** diff --git a/main_UI.min.js b/main_UI.min.js index 5df6a03..177cdd6 100644 --- a/main_UI.min.js +++ b/main_UI.min.js @@ -1 +1 @@ -!function(e,t){var o=o||{};"function"==typeof o&&o.amd?o([],t):"object"==typeof exports&&"object"==typeof module?module.exports=t():"object"==typeof exports?exports.RelativeTime=t():e.RelativeTime=t()}(this,(function(){const e={year:31536e6,month:2628e6,day:864e5,hour:36e5,minute:6e4,second:1e3},o={numeric:"auto"};function n(e){e={locale:(e=e||{}).locale||"en",options:{...o,...e.options}},this.rtf=new Intl.RelativeTimeFormat(e.locale,e.options)}return n.prototype={from(t,o){const n=t-(o||new Date);for(let t in e)if(Math.abs(n)>e[t]||"second"==t)return this.rtf.format(Math.round(n/e[t]),t)}},n}));const relativeTime=new RelativeTime({style:"narrow"}),uiGlobals={};let timerId;function getRef(id){return document.getElementById(id)}const uiUtils={createElement(tagName,options){const{className:className,textContent:textContent,innerHTML:innerHTML,attributes:attributes={}}=options,elem=document.createElement(tagName);for(let attribute in attributes)elem.setAttribute(attribute,attributes[attribute]);return className&&(elem.className=className),textContent&&(elem.textContent=textContent),innerHTML&&(elem.innerHTML=innerHTML),elem},debounce:(callback,wait)=>{let timeoutId=null;return(...args)=>{window.clearTimeout(timeoutId),timeoutId=window.setTimeout((()=>{callback.apply(null,args)}),wait)}},throttle(func,delay){timerId||(timerId=setTimeout((function(){func(),timerId=void 0}),delay))},delegate(el,event,selector,fn){el.addEventListener(event,(function(e){const potentialTarget=e.target.closest(selector);potentialTarget&&(e.delegateTarget=potentialTarget,fn.call(this,e))}))},formatTime(timestamp,format){try{String(timestamp).length<13&&(timestamp*=1e3);let[day,month,date,year]=new Date(timestamp).toString().split(" "),minutes=new Date(timestamp).getMinutes(),hours=new Date(timestamp).getHours();(new Date).toString().split(" ");minutes=minutes<10?`0${minutes}`:minutes;let finalHours="";switch(finalHours=hours>12?`${hours-12}:${minutes}`:0===hours?`12:${minutes}`:`${hours}:${minutes}`,finalHours=hours>=12?`${finalHours} PM`:`${finalHours} AM`,format){case"date-only":return`${month} ${date}, ${year}`;case"time-only":return finalHours;case"relative":return Date.now()-new Date(timestamp)<864e5?`${finalHours}`:relativeTime.from(timestamp);default:return`${month} ${date}, ${year} at ${finalHours}`}}catch(e){return console.error(e),timestamp}},formatAmount:(amount=0,currency="inr")=>amount?amount.toLocaleString(void 0,{currency:currency,maximumFractionDigits:8,minimumFractionDigits:0}):"0"};uiGlobals.connectionErrorNotification=[],navigator.onLine||uiGlobals.connectionErrorNotification.push(notify("There seems to be a problem connecting to the internet, Please check you internet connection.","error")),window.addEventListener("offline",(()=>{uiGlobals.connectionErrorNotification.push(notify("There seems to be a problem connecting to the internet, Please check you internet connection.","error"))})),window.addEventListener("online",(()=>{uiGlobals.connectionErrorNotification.forEach((notification=>notification.remove())),notify("We are back online.","success"),location.reload(),uiGlobals.connectionErrorNotification=[]}));let zIndex=50;function openPopup(popupId,pinned){return void 0===popupStack.peek()&&document.addEventListener("keydown",(e=>{"Escape"===e.key&&closePopup()})),zIndex++,getRef(popupId).setAttribute("style",`z-index: ${zIndex}`),getRef(popupId).show({pinned:pinned}),getRef(popupId)}function closePopup(options={}){void 0!==popupStack.peek()&&popupStack.peek().popup.hide(options)}document.addEventListener("popupopened",(async e=>{history.pushState({type:"popup"},null,null),e.target.id})),document.addEventListener("popupclosed",(e=>{zIndex--,e.target.id,void 0===popupStack.peek()&&document.removeEventListener("keydown",(e=>{"Escape"===e.key&&closePopup()}))})),window.addEventListener("popstate",(e=>{if(e.state&&"popup"===e.state.type)closePopup()}));const getConfirmation=(title,options={})=>new Promise((resolve=>{const{message:message="",cancelText:cancelText="Cancel",confirmText:confirmText="OK",danger:danger=!1}=options;getRef("confirm_title").innerText=title,getRef("confirm_message").innerText=message;const cancelButton=getRef("confirmation_popup").querySelector(".cancel-button"),confirmButton=getRef("confirmation_popup").querySelector(".confirm-button");confirmButton.textContent=confirmText,cancelButton.textContent=cancelText,danger?confirmButton.classList.add("button--danger"):confirmButton.classList.remove("button--danger");const{opened:opened,closed:closed}=openPopup("confirmation_popup");confirmButton.onclick=()=>{closePopup({payload:!0})},cancelButton.onclick=()=>{closePopup()},closed.then((payload=>{confirmButton.onclick=null,cancelButton.onclick=null,resolve(!!payload)}))}));function getPromptInput(title,message="",options={}){let{placeholder:placeholder="",isPassword:isPassword=!1,cancelText:cancelText="Cancel",confirmText:confirmText="OK"}=options;getRef("prompt_title").innerText=title,getRef("prompt_message").innerText=message;const cancelButton=getRef("prompt_popup").querySelector(".cancel-button"),confirmButton=getRef("prompt_popup").querySelector(".confirm-button");return isPassword&&(placeholder="Password",getRef("prompt_input").setAttribute("type","password")),getRef("prompt_input").setAttribute("placeholder",placeholder),getRef("prompt_input").focusIn(),cancelButton.textContent=cancelText,confirmButton.textContent=confirmText,openPopup("prompt_popup",!0),new Promise(((resolve,reject)=>{cancelButton.addEventListener("click",(()=>(closePopup(),null)),{once:!0}),confirmButton.addEventListener("click",(()=>{closePopup(),resolve(getRef("prompt_input").value)}),{once:!0})}))}function notify(message,mode,options={}){let icon;switch(mode){case"success":icon='';break;case"error":icon='',options.pinned=!0}return"error"===mode&&console.error(message),getRef("notification_drawer").push(message,{icon:icon,...options})}function detectBrowser(){let tem,ua=navigator.userAgent,M=ua.match(/(opera|chrome|safari|firefox|msie|trident(?=\/))\/?\s*(\d+)/i)||[];return/trident/i.test(M[1])?(tem=/\brv[ :]+(\d+)/g.exec(ua)||[],"IE "+(tem[1]||"")):"Chrome"===M[1]&&(tem=ua.match(/\b(OPR|Edge)\/(\d+)/),null!=tem)?tem.slice(1).join(" ").replace("OPR","Opera"):(M=M[2]?[M[1],M[2]]:[navigator.appName,navigator.appVersion,"-?"],null!=(tem=ua.match(/version\/(\d+)/i))&&M.splice(1,1,tem[1]),M.join(" "))}function createRipple(event,target){const circle=document.createElement("span"),diameter=Math.max(target.clientWidth,target.clientHeight),radius=diameter/2,targetDimensions=target.getBoundingClientRect();circle.style.width=circle.style.height=`${diameter}px`,circle.style.left=event.clientX-(targetDimensions.left+radius)+"px",circle.style.top=event.clientY-(targetDimensions.top+radius)+"px",circle.classList.add("ripple");const rippleAnimation=circle.animate([{transform:"scale(3)",opacity:0}],{duration:1e3,fill:"forwards",easing:"ease-out"});target.append(circle),rippleAnimation.onfinish=()=>{circle.remove()}}window.addEventListener("hashchange",(e=>routeTo(window.location.hash))),window.addEventListener("load",(()=>{const[browserName,browserVersion]=detectBrowser().split(" "),supportedVersions={Chrome:85,Firefox:75,Safari:13};browserName in supportedVersions?parseInt(browserVersion){"Escape"===e.key&&closePopup()})),document.addEventListener("copy",(()=>{notify("copied","success")})),document.addEventListener("pointerdown",(e=>{e.target.closest("button:not([disabled]), .interactive")&&createRipple(e,e.target.closest("button, .interactive"))})),document.querySelectorAll(".popup__header__close, .close-popup-on-click").forEach((elem=>{elem.addEventListener("click",(()=>{closePopup()}))}))}));class Router{constructor(options={}){const{routes:routes={},state:state={},routingStart:routingStart,routingEnd:routingEnd}=options;this.routes=routes,this.state=state,this.routingStart=routingStart,this.routingEnd=routingEnd,this.lastPage=null,window.addEventListener("hashchange",(e=>this.routeTo(window.location.hash)))}addRoute(route,callback){this.routes[route]=callback}async routeTo(path){try{let page,queryString,params,wildcards=[];if([path,queryString]=path.split("?"),path.includes("#")&&(path=path.split("#")[1]),path.includes("/")?[,page,...wildcards]=path.split("/"):page=path,this.state={page:page,wildcards:wildcards,lastPage:this.lastPage},queryString&&(params=new URLSearchParams(queryString),this.state.params=Object.fromEntries(params)),this.routingStart&&this.routingStart(this.state),this.routes[page]){if(!document.startViewTransition)return await this.routes[page](this.state),void(this.lastPage=page);document.startViewTransition((async()=>{await this.routes[page](this.state),this.lastPage=page}))}else this.routes[404]?this.routes[404](this.state):console.error(`No route found for '${page}' and no '404' route is defined.`);this.routingEnd&&this.routingEnd(this.state)}catch(e){console.error(e)}}}const appState={params:{},openedPages:new Set},generalPages=["sign_up","sign_in","loading","landing"];async function routeTo(targetPage,options={}){const{firstLoad:firstLoad}=options;let pageId,subPageId1,subPageId2,searchParams,params;if(""===targetPage)try{floDapps.user.id&&(pageId="chat_page")}catch(e){pageId="landing"}else if(targetPage.includes("/")){let path;[path,searchParams]=targetPage.split("?"),[,pageId,subPageId1,subPageId2]=path.split("/")}else pageId=targetPage;if(document.querySelector(`#${pageId}`)?.classList.contains("inner-page")){try{floDapps.user.id&&generalPages.includes(pageId)&&(history.replaceState(null,null,"#/chat_page"),pageId="chat_page")}catch(e){if(!generalPages.includes(pageId))return}if(appState.currentPage=pageId,searchParams){const urlSearchParams=new URLSearchParams("?"+searchParams);params=Object.fromEntries(urlSearchParams.entries())}switch(params&&(appState.params=params),pageId){case"sign_in":setTimeout((()=>{getRef("private_key_field").focusIn()}),0);break;case"sign_up":getRef("keys_generator").generateKeys()}if(appState.lastPage!==pageId){document.querySelectorAll(".page").forEach((page=>page.classList.add("hidden"))),getRef(pageId).closest(".page").classList.remove("hidden"),document.querySelectorAll(".inner-page").forEach((page=>page.classList.add("hidden"))),getRef(pageId).classList.remove("hidden"),getRef(pageId).animate([{opacity:0,transform:"translateY(1rem)"},{opacity:1,transform:"translateY(0)"}],{duration:300,easing:"cubic-bezier(0.175, 0.885, 0.32, 1.275)"}).onfinish=()=>{},appState.lastPage=pageId}params&&(appState.params=params),appState.openedPages.add(pageId)}}class LazyLoader{constructor(container,elementsToRender,renderFn,options={}){const{batchSize:batchSize=10,freshRender:freshRender,bottomFirst:bottomFirst=!1,onEnd:onEnd}=options;this.elementsToRender=elementsToRender,this.arrayOfElements="function"==typeof elementsToRender?this.elementsToRender():elementsToRender||[],this.renderFn=renderFn,this.intersectionObserver,this.batchSize=batchSize,this.freshRender=freshRender,this.bottomFirst=bottomFirst,this.onEnd=onEnd,this.shouldLazyLoad=!1,this.lastScrollTop=0,this.lastScrollHeight=0,this.lazyContainer=document.querySelector(container),this.update=this.update.bind(this),this.render=this.render.bind(this),this.init=this.init.bind(this),this.clear=this.clear.bind(this)}get elements(){return this.arrayOfElements}init(){this.mutationObserver&&this.mutationObserver.disconnect(),this.intersectionObserver&&this.intersectionObserver.disconnect(),this.intersectionObserver=new IntersectionObserver(((entries,observer)=>{entries.forEach((entry=>{entry.isIntersecting&&(observer.disconnect(),this.render({lazyLoad:!0}))}))}),{root:this.lazyContainer}),this.mutationObserver=new MutationObserver((mutationList=>{mutationList.forEach((mutation=>{"childList"===mutation.type&&mutation.addedNodes.length&&(this.bottomFirst?this.lazyContainer.firstElementChild&&this.intersectionObserver.observe(this.lazyContainer.firstElementChild):this.lazyContainer.lastElementChild&&this.intersectionObserver.observe(this.lazyContainer.lastElementChild))}))})),this.mutationObserver.observe(this.lazyContainer,{childList:!0}),this.render()}update(elementsToRender){this.arrayOfElements="function"==typeof elementsToRender?this.elementsToRender():elementsToRender||[]}render(options={}){let{lazyLoad:lazyLoad=!1}=options;this.shouldLazyLoad=lazyLoad;const frag=document.createDocumentFragment();lazyLoad?this.bottomFirst?(this.updateEndIndex=this.updateStartIndex,this.updateStartIndex=this.updateEndIndex-this.batchSize):(this.updateStartIndex=this.updateEndIndex,this.updateEndIndex=this.updateEndIndex+this.batchSize):(this.intersectionObserver.disconnect(),this.bottomFirst?(this.updateEndIndex=this.arrayOfElements.length,this.updateStartIndex=this.updateEndIndex-this.batchSize-1):(this.updateStartIndex=0,this.updateEndIndex=this.batchSize),this.lazyContainer.innerHTML=""),this.updateStartIndex=Math.max(this.updateStartIndex,0),this.lastScrollHeight=this.lazyContainer.scrollHeight,this.lastScrollTop=this.lazyContainer.scrollTop,this.arrayOfElements.slice(this.updateStartIndex,this.updateEndIndex).forEach(((element,index)=>{frag.append(this.renderFn(element))})),this.bottomFirst?(this.lazyContainer.prepend(frag),this.lastScrollTop+=this.lazyContainer.scrollHeight-this.lastScrollHeight,this.lazyContainer.scrollTo({top:this.lastScrollTop}),this.lastScrollHeight=this.lazyContainer.scrollHeight,this.updateStartIndex<=0&&this.onEnd&&(this.mutationObserver.disconnect(),this.intersectionObserver.disconnect(),this.onEnd())):(this.lazyContainer.append(frag),this.updateEndIndex>=this.arrayOfElements.length&&this.onEnd&&(this.mutationObserver.disconnect(),this.intersectionObserver.disconnect(),this.onEnd())),!lazyLoad&&this.bottomFirst&&(this.lazyContainer.scrollTop=this.lazyContainer.scrollHeight),!lazyLoad&&this.freshRender&&this.freshRender()}clear(){this.intersectionObserver.disconnect(),this.mutationObserver.disconnect(),this.lazyContainer.innerHTML=""}reset(){this.arrayOfElements="function"==typeof this.elementsToRender?this.elementsToRender():this.elementsToRender||[],this.render()}}const slideInLeft=[{opacity:0,transform:"translateX(1.5rem)"},{opacity:1,transform:"translateX(0)"}],slideOutLeft=[{opacity:1,transform:"translateX(0)"},{opacity:0,transform:"translateX(-1.5rem)"}],slideInRight=[{opacity:0,transform:"translateX(-1.5rem)"},{opacity:1,transform:"translateX(0)"}],slideOutRight=[{opacity:1,transform:"translateX(0)"},{opacity:0,transform:"translateX(1.5rem)"}],slideInDown=[{opacity:0,transform:"translateY(-1.5rem)"},{opacity:1,transform:"translateY(0)"}],slideOutUp=[{opacity:1,transform:"translateY(0)"},{opacity:0,transform:"translateY(-1.5rem)"}];function showChildElement(id,index,options={}){return new Promise((resolve=>{const{mobileView:mobileView=!1,entry:entry,exit:exit}=options,animOptions={duration:150,easing:"ease",fill:"forwards"},parent="string"==typeof id?document.getElementById(id):id,visibleElement=[...parent.children].find((elem=>!elem.classList.contains(mobileView?"hide-on-mobile":"hidden")));visibleElement!==parent.children[index]&&(visibleElement.getAnimations().forEach((anim=>anim.cancel())),parent.children[index].getAnimations().forEach((anim=>anim.cancel())),visibleElement?exit?visibleElement.animate(exit,animOptions).onfinish=()=>{visibleElement.classList.add(mobileView?"hide-on-mobile":"hidden"),parent.children[index].classList.remove(mobileView?"hide-on-mobile":"hidden"),entry&&(parent.children[index].animate(entry,animOptions).onfinish=()=>resolve())}:(visibleElement.classList.add(mobileView?"hide-on-mobile":"hidden"),parent.children[index].classList.remove(mobileView?"hide-on-mobile":"hidden"),resolve()):(parent.children[index].classList.remove(mobileView?"hide-on-mobile":"hidden"),parent.children[index].animate(entry,animOptions).onfinish=()=>resolve()))}))}function buttonLoader(id,show){const button="string"==typeof id?document.getElementById(id):id;button.disabled=show;const animOptions={duration:200,fill:"forwards",easing:"ease"};if(show)button.parentNode.append(createElement("sm-spinner")),button.animate([{clipPath:"circle(100%)"},{clipPath:"circle(0)"}],animOptions);else{button.getAnimations().forEach((anim=>anim.cancel()));const potentialTarget=button.parentNode.querySelector("sm-spinner");potentialTarget&&potentialTarget.remove()}}let currentSubscriber=null;function $signal(initialValue){let value=initialValue;const subscribers=new Set;return[function(){if(currentSubscriber){const weakRef=new WeakRef({func:currentSubscriber});subscribers.add(weakRef)}return value},function(newValue){if(newValue!==value){value=newValue;for(const subscriber of subscribers){const ref=subscriber.deref();ref&&ref.func()}}}]}async function $effect(fn){currentSubscriber=fn;const result=fn();try{result instanceof Promise&&await result}catch(e){console.error(e)}finally{currentSubscriber=null}} \ No newline at end of file +!function(e,t){var o=o||{};"function"==typeof o&&o.amd?o([],t):"object"==typeof exports&&"object"==typeof module?module.exports=t():"object"==typeof exports?exports.RelativeTime=t():e.RelativeTime=t()}(this,(function(){const e={year:31536e6,month:2628e6,day:864e5,hour:36e5,minute:6e4,second:1e3},o={numeric:"auto"};function n(e){e={locale:(e=e||{}).locale||"en",options:{...o,...e.options}},this.rtf=new Intl.RelativeTimeFormat(e.locale,e.options)}return n.prototype={from(t,o){const n=t-(o||new Date);for(let t in e)if(Math.abs(n)>e[t]||"second"==t)return this.rtf.format(Math.round(n/e[t]),t)}},n}));const relativeTime=new RelativeTime({style:"narrow"}),uiGlobals={};let timerId;function getRef(id){return document.getElementById(id)}const uiUtils={createElement(tagName,options){const{className:className,textContent:textContent,innerHTML:innerHTML,attributes:attributes={}}=options,elem=document.createElement(tagName);for(let attribute in attributes)elem.setAttribute(attribute,attributes[attribute]);return className&&(elem.className=className),textContent&&(elem.textContent=textContent),innerHTML&&(elem.innerHTML=innerHTML),elem},debounce:(callback,wait)=>{let timeoutId=null;return(...args)=>{window.clearTimeout(timeoutId),timeoutId=window.setTimeout((()=>{callback.apply(null,args)}),wait)}},throttle(func,delay){timerId||(timerId=setTimeout((function(){func(),timerId=void 0}),delay))},delegate(el,event,selector,fn){el.addEventListener(event,(function(e){const potentialTarget=e.target.closest(selector);potentialTarget&&(e.delegateTarget=potentialTarget,fn.call(this,e))}))},formatTime(timestamp,format){try{String(timestamp).length<13&&(timestamp*=1e3);let[day,month,date,year]=new Date(timestamp).toString().split(" "),minutes=new Date(timestamp).getMinutes(),hours=new Date(timestamp).getHours();(new Date).toString().split(" ");minutes=minutes<10?`0${minutes}`:minutes;let finalHours="";switch(finalHours=hours>12?`${hours-12}:${minutes}`:0===hours?`12:${minutes}`:`${hours}:${minutes}`,finalHours=hours>=12?`${finalHours} PM`:`${finalHours} AM`,format){case"date-only":return`${month} ${date}, ${year}`;case"time-only":return finalHours;case"relative":return Date.now()-new Date(timestamp)<864e5?`${finalHours}`:relativeTime.from(timestamp);default:return`${month} ${date}, ${year} at ${finalHours}`}}catch(e){return console.error(e),timestamp}},formatAmount:(amount=0,currency="inr")=>amount?amount.toLocaleString(void 0,{currency:currency,maximumFractionDigits:8,minimumFractionDigits:0}):"0"};uiGlobals.connectionErrorNotification=[],navigator.onLine||uiGlobals.connectionErrorNotification.push(notify("There seems to be a problem connecting to the internet, Please check you internet connection.","error")),window.addEventListener("offline",(()=>{uiGlobals.connectionErrorNotification.push(notify("There seems to be a problem connecting to the internet, Please check you internet connection.","error"))})),window.addEventListener("online",(()=>{uiGlobals.connectionErrorNotification.forEach((notification=>notification.remove())),notify("We are back online.","success"),location.reload(),uiGlobals.connectionErrorNotification=[]}));let zIndex=50;function openPopup(popupId,pinned){return void 0===popupStack.peek()&&document.addEventListener("keydown",(e=>{"Escape"===e.key&&closePopup()})),zIndex++,getRef(popupId).setAttribute("style",`z-index: ${zIndex}`),getRef(popupId).show({pinned:pinned}),getRef(popupId)}function closePopup(options={}){void 0!==popupStack.peek()&&popupStack.peek().popup.hide(options)}document.addEventListener("popupopened",(async e=>{history.pushState({type:"popup"},null,null),e.target.id})),document.addEventListener("popupclosed",(e=>{zIndex--,e.target.id,void 0===popupStack.peek()&&document.removeEventListener("keydown",(e=>{"Escape"===e.key&&closePopup()}))})),window.addEventListener("popstate",(e=>{if(e.state&&"popup"===e.state.type)closePopup()}));const getConfirmation=(title,options={})=>new Promise((resolve=>{const{message:message="",cancelText:cancelText="Cancel",confirmText:confirmText="OK",danger:danger=!1}=options;getRef("confirm_title").innerText=title,getRef("confirm_message").innerText=message;const cancelButton=getRef("confirmation_popup").querySelector(".cancel-button"),confirmButton=getRef("confirmation_popup").querySelector(".confirm-button");confirmButton.textContent=confirmText,cancelButton.textContent=cancelText,danger?confirmButton.classList.add("button--danger"):confirmButton.classList.remove("button--danger");const{opened:opened,closed:closed}=openPopup("confirmation_popup");confirmButton.onclick=()=>{closePopup({payload:!0})},cancelButton.onclick=()=>{closePopup()},closed.then((payload=>{confirmButton.onclick=null,cancelButton.onclick=null,resolve(!!payload)}))}));function getPromptInput(title,message="",options={}){let{placeholder:placeholder="",isPassword:isPassword=!1,cancelText:cancelText="Cancel",confirmText:confirmText="OK"}=options;getRef("prompt_title").innerText=title,getRef("prompt_message").innerText=message;const cancelButton=getRef("prompt_popup").querySelector(".cancel-button"),confirmButton=getRef("prompt_popup").querySelector(".confirm-button");return isPassword&&(placeholder="Password",getRef("prompt_input").setAttribute("type","password")),getRef("prompt_input").setAttribute("placeholder",placeholder),getRef("prompt_input").focusIn(),cancelButton.textContent=cancelText,confirmButton.textContent=confirmText,openPopup("prompt_popup",!0),new Promise(((resolve,reject)=>{cancelButton.addEventListener("click",(()=>(closePopup(),null)),{once:!0}),confirmButton.addEventListener("click",(()=>{closePopup(),resolve(getRef("prompt_input").value)}),{once:!0})}))}function notify(message,mode,options={}){let icon;switch(mode){case"success":icon='';break;case"error":icon='',options.pinned=!0}return"error"===mode&&console.error(message),getRef("notification_drawer").push(message,{icon:icon,...options})}function detectBrowser(){let tem,ua=navigator.userAgent,M=ua.match(/(opera|chrome|safari|firefox|msie|trident(?=\/))\/?\s*(\d+)/i)||[];return/trident/i.test(M[1])?(tem=/\brv[ :]+(\d+)/g.exec(ua)||[],"IE "+(tem[1]||"")):"Chrome"===M[1]&&(tem=ua.match(/\b(OPR|Edge)\/(\d+)/),null!=tem)?tem.slice(1).join(" ").replace("OPR","Opera"):(M=M[2]?[M[1],M[2]]:[navigator.appName,navigator.appVersion,"-?"],null!=(tem=ua.match(/version\/(\d+)/i))&&M.splice(1,1,tem[1]),M.join(" "))}function createRipple(event,target){const circle=document.createElement("span"),diameter=Math.max(target.clientWidth,target.clientHeight),radius=diameter/2,targetDimensions=target.getBoundingClientRect();circle.style.width=circle.style.height=`${diameter}px`,circle.style.left=event.clientX-(targetDimensions.left+radius)+"px",circle.style.top=event.clientY-(targetDimensions.top+radius)+"px",circle.classList.add("ripple");const rippleAnimation=circle.animate([{transform:"scale(3)",opacity:0}],{duration:1e3,fill:"forwards",easing:"ease-out"});target.append(circle),rippleAnimation.onfinish=()=>{circle.remove()}}window.addEventListener("hashchange",(e=>routeTo(window.location.hash))),window.addEventListener("load",(()=>{const[browserName,browserVersion]=detectBrowser().split(" "),supportedVersions={Chrome:85,Firefox:75,Safari:13};browserName in supportedVersions?parseInt(browserVersion){"Escape"===e.key&&closePopup()})),document.addEventListener("copy",(()=>{notify("copied","success")})),document.addEventListener("pointerdown",(e=>{e.target.closest("button:not([disabled]), .interactive")&&createRipple(e,e.target.closest("button, .interactive"))})),document.querySelectorAll(".popup__header__close, .close-popup-on-click").forEach((elem=>{elem.addEventListener("click",(()=>{closePopup()}))}))}));class Router{constructor(options={}){const{routes:routes={},state:state={},routingStart:routingStart,routingEnd:routingEnd}=options;this.routes=routes,this.state=state,this.routingStart=routingStart,this.routingEnd=routingEnd,this.lastPage=null,window.addEventListener("hashchange",(e=>this.routeTo(window.location.hash)))}addRoute(route,callback){this.routes[route]=callback}async routeTo(path){try{let page,queryString,params,wildcards=[];if([path,queryString]=path.split("?"),path.includes("#")&&(path=path.split("#")[1]),path.includes("/")?[,page,...wildcards]=path.split("/"):page=path,this.state={page:page,wildcards:wildcards,lastPage:this.lastPage},queryString&&(params=new URLSearchParams(queryString),this.state.params=Object.fromEntries(params)),this.routingStart&&this.routingStart(this.state),this.routes[page]){if(!document.startViewTransition)return await this.routes[page](this.state),void(this.lastPage=page);document.startViewTransition((async()=>{await this.routes[page](this.state),this.lastPage=page}))}else this.routes[404]?this.routes[404](this.state):console.error(`No route found for '${page}' and no '404' route is defined.`);this.routingEnd&&this.routingEnd(this.state)}catch(e){console.error(e)}}}const appState={params:{},openedPages:new Set},generalPages=["sign_up","sign_in","loading","landing"];async function routeTo(targetPage,options={}){const{firstLoad:firstLoad}=options;let pageId,subPageId1,subPageId2,searchParams,params;if(""===targetPage)try{floDapps.user.id&&(pageId="chat_page")}catch(e){pageId="landing"}else if(targetPage.includes("/")){let path;[path,searchParams]=targetPage.split("?"),[,pageId,subPageId1,subPageId2]=path.split("/")}else pageId=targetPage;if(document.querySelector(`#${pageId}`)?.classList.contains("inner-page")){try{floDapps.user.id&&generalPages.includes(pageId)&&(history.replaceState(null,null,"#/chat_page"),pageId="chat_page")}catch(e){if(!generalPages.includes(pageId))return}if(appState.currentPage=pageId,searchParams){const urlSearchParams=new URLSearchParams("?"+searchParams);params=Object.fromEntries(urlSearchParams.entries())}switch(params&&(appState.params=params),pageId){case"sign_in":setTimeout((()=>{getRef("private_key_field").focusIn()}),0);break;case"sign_up":getRef("keys_generator").generateKeys()}if(appState.lastPage!==pageId){document.querySelectorAll(".page").forEach((page=>page.classList.add("hidden"))),getRef(pageId).closest(".page").classList.remove("hidden"),document.querySelectorAll(".inner-page").forEach((page=>page.classList.add("hidden"))),getRef(pageId).classList.remove("hidden"),getRef(pageId).animate([{opacity:0,transform:"translateY(1rem)"},{opacity:1,transform:"translateY(0)"}],{duration:300,easing:"cubic-bezier(0.175, 0.885, 0.32, 1.275)"}).onfinish=()=>{},appState.lastPage=pageId}params&&(appState.params=params),appState.openedPages.add(pageId)}}class LazyLoader{constructor(container,elementsToRender,renderFn,options={}){const{batchSize:batchSize=10,freshRender:freshRender,bottomFirst:bottomFirst=!1,onEnd:onEnd}=options;this.elementsToRender=elementsToRender,this.arrayOfElements="function"==typeof elementsToRender?this.elementsToRender():elementsToRender||[],this.renderFn=renderFn,this.intersectionObserver,this.batchSize=batchSize,this.freshRender=freshRender,this.bottomFirst=bottomFirst,this.onEnd=onEnd,this.shouldLazyLoad=!1,this.lastScrollTop=0,this.lastScrollHeight=0,this.lazyContainer=document.querySelector(container),this.update=this.update.bind(this),this.render=this.render.bind(this),this.init=this.init.bind(this),this.clear=this.clear.bind(this)}get elements(){return this.arrayOfElements}init(){this.mutationObserver&&this.mutationObserver.disconnect(),this.intersectionObserver&&this.intersectionObserver.disconnect(),this.intersectionObserver=new IntersectionObserver(((entries,observer)=>{entries.forEach((entry=>{entry.isIntersecting&&(observer.disconnect(),this.render({lazyLoad:!0}))}))}),{root:this.lazyContainer}),this.mutationObserver=new MutationObserver((mutationList=>{mutationList.forEach((mutation=>{"childList"===mutation.type&&mutation.addedNodes.length&&(this.bottomFirst?this.lazyContainer.firstElementChild&&this.intersectionObserver.observe(this.lazyContainer.firstElementChild):this.lazyContainer.lastElementChild&&this.intersectionObserver.observe(this.lazyContainer.lastElementChild))}))})),this.mutationObserver.observe(this.lazyContainer,{childList:!0}),this.render()}update(elementsToRender){this.arrayOfElements="function"==typeof elementsToRender?this.elementsToRender():elementsToRender||[]}render(options={}){let{lazyLoad:lazyLoad=!1}=options;this.shouldLazyLoad=lazyLoad;const frag=document.createDocumentFragment();lazyLoad?this.bottomFirst?(this.updateEndIndex=this.updateStartIndex,this.updateStartIndex=this.updateEndIndex-this.batchSize):(this.updateStartIndex=this.updateEndIndex,this.updateEndIndex=this.updateEndIndex+this.batchSize):(this.intersectionObserver.disconnect(),this.bottomFirst?(this.updateEndIndex=this.arrayOfElements.length,this.updateStartIndex=this.updateEndIndex-this.batchSize-1):(this.updateStartIndex=0,this.updateEndIndex=this.batchSize),this.lazyContainer.innerHTML=""),this.updateStartIndex=Math.max(this.updateStartIndex,0),this.lastScrollHeight=this.lazyContainer.scrollHeight,this.lastScrollTop=this.lazyContainer.scrollTop,this.arrayOfElements.slice(this.updateStartIndex,this.updateEndIndex).forEach(((element,index)=>{frag.append(this.renderFn(element))})),this.bottomFirst?(this.lazyContainer.prepend(frag),this.lastScrollTop+=this.lazyContainer.scrollHeight-this.lastScrollHeight,this.lazyContainer.scrollTo({top:this.lastScrollTop}),this.lastScrollHeight=this.lazyContainer.scrollHeight,this.updateStartIndex<=0&&this.onEnd&&(this.mutationObserver.disconnect(),this.intersectionObserver.disconnect(),this.onEnd())):(this.lazyContainer.append(frag),this.updateEndIndex>=this.arrayOfElements.length&&this.onEnd&&(this.mutationObserver.disconnect(),this.intersectionObserver.disconnect(),this.onEnd())),!lazyLoad&&this.bottomFirst&&(this.lazyContainer.scrollTop=this.lazyContainer.scrollHeight),!lazyLoad&&this.freshRender&&this.freshRender()}clear(){this.intersectionObserver.disconnect(),this.mutationObserver.disconnect(),this.lazyContainer.innerHTML=""}reset(){this.arrayOfElements="function"==typeof this.elementsToRender?this.elementsToRender():this.elementsToRender||[],this.render()}}const slideInLeft=[{opacity:0,transform:"translateX(1.5rem)"},{opacity:1,transform:"translateX(0)"}],slideOutLeft=[{opacity:1,transform:"translateX(0)"},{opacity:0,transform:"translateX(-1.5rem)"}],slideInRight=[{opacity:0,transform:"translateX(-1.5rem)"},{opacity:1,transform:"translateX(0)"}],slideOutRight=[{opacity:1,transform:"translateX(0)"},{opacity:0,transform:"translateX(1.5rem)"}],slideInDown=[{opacity:0,transform:"translateY(-1.5rem)"},{opacity:1,transform:"translateY(0)"}],slideOutUp=[{opacity:1,transform:"translateY(0)"},{opacity:0,transform:"translateY(-1.5rem)"}];function showChildElement(id,index,options={}){return new Promise((resolve=>{const{mobileView:mobileView=!1,entry:entry,exit:exit}=options,animOptions={duration:150,easing:"ease",fill:"forwards"},parent="string"==typeof id?document.getElementById(id):id,visibleElement=[...parent.children].find((elem=>!elem.classList.contains(mobileView?"hide-on-mobile":"hidden")));visibleElement!==parent.children[index]&&(visibleElement.getAnimations().forEach((anim=>anim.cancel())),parent.children[index].getAnimations().forEach((anim=>anim.cancel())),visibleElement?exit?visibleElement.animate(exit,animOptions).onfinish=()=>{visibleElement.classList.add(mobileView?"hide-on-mobile":"hidden"),parent.children[index].classList.remove(mobileView?"hide-on-mobile":"hidden"),entry&&(parent.children[index].animate(entry,animOptions).onfinish=()=>resolve())}:(visibleElement.classList.add(mobileView?"hide-on-mobile":"hidden"),parent.children[index].classList.remove(mobileView?"hide-on-mobile":"hidden"),resolve()):(parent.children[index].classList.remove(mobileView?"hide-on-mobile":"hidden"),parent.children[index].animate(entry,animOptions).onfinish=()=>resolve()))}))}function buttonLoader(id,show){const button="string"==typeof id?document.getElementById(id):id;button.disabled=show;const animOptions={duration:200,fill:"forwards",easing:"ease"};if(show)button.parentNode.append(createElement("sm-spinner")),button.animate([{clipPath:"circle(100%)"},{clipPath:"circle(0)"}],animOptions);else{button.getAnimations().forEach((anim=>anim.cancel()));const potentialTarget=button.parentNode.querySelector("sm-spinner");potentialTarget&&potentialTarget.remove()}}let currentSubscriber=null;function $signal(initialValue,callback){let value=initialValue;const subscribers=new Set;let hasCustomSubscriber=!1;return[function(subscriber){return currentSubscriber&&subscribers.add(currentSubscriber),!hasCustomSubscriber&&subscriber&&(subscribers.add(subscriber),hasCustomSubscriber=!0),value},function(newValue){if(newValue!==value){value=newValue;for(const subscriber of subscribers)subscriber()}}]}async function $effect(fn){currentSubscriber=fn;const result=fn();try{result instanceof Promise&&await result}catch(e){console.error(e)}finally{currentSubscriber=null}} \ No newline at end of file