this.speakingThreshold){i=!0;break}this.speaking!==i&&(this.speaking=i,this.callback()),this.volumeLooperTimeout=setTimeout(this.volumeLooper,pw)},this.stream=e,this.callback=t,this.speakingVolumeSamples=new Array(fw).fill(-1/0),this.initVolumeMeasuring(),this.measureVolumeActivity(!0)}get isSpeaking(){return this.speaking}measureVolumeActivity(e){if(e){if(!this.audioContext||!this.analyser||!this.frequencyBinCount)return;this.measuringVolumeActivity=!0,this.volumeLooper()}else this.measuringVolumeActivity=!1,this.speakingVolumeSamples.fill(-1/0),this.callback()}initVolumeMeasuring(){const e=window.AudioContext||window.webkitAudioContext;if(!e)return;this.audioContext=new e,this.analyser=this.audioContext.createAnalyser(),this.analyser.fftSize=512,this.analyser.smoothingTimeConstant=.1,this.audioContext.createMediaStreamSource(this.stream).connect(this.analyser),this.frequencyBinCount=new Float32Array(this.analyser.frequencyBinCount)}setSpeakingThreshold(e){this.speakingThreshold=e}stop(){var e;clearTimeout(this.volumeLooperTimeout),this.analyser.disconnect(),(e=this.audioContext)==null||e.close()}}class vw{createPeerConnection(e,t,s){const i=new RTCPeerConnection({iceTransportPolicy:e?"relay":void 0,iceServers:t,iceCandidatePoolSize:s});return new Proxy(i,{get(r,o,c){o==="close"&&console.trace("calling peerConnection.close");const l=r[o];return typeof l=="function"?l.bind(r):l}})}prepareSenderForPurpose(e,t,s){s===Zt.Screenshare&&this.getRidOfRTXCodecs(e,t)}getRidOfRTXCodecs(e,t){var c,l,h,a,u,p;if(!RTCRtpReceiver.getCapabilities||!RTCRtpSender.getCapabilities)return;const s=(l=(c=RTCRtpReceiver.getCapabilities("video"))==null?void 0:c.codecs)!=null?l:[],r=[...(a=(h=RTCRtpSender.getCapabilities("video"))==null?void 0:h.codecs)!=null?a:[],...s];for(const g of r)if(g.mimeType==="video/rtx"){const f=r.indexOf(g);r.splice(f,1)}const o=e.getTransceivers().find(g=>g.sender===t);o&&(((u=o.sender.track)==null?void 0:u.kind)==="video"||((p=o.receiver.track)==null?void 0:p.kind)==="video")&&o.setCodecPreferences(r)}}var es=(n=>(n[n.Dark=0]="Dark",n[n.Light=1]="Light",n))(es||{});function bw(n,e,t){let s=n.replaceAll("#ff00ff",e);if(s=s.replaceAll("#00ffff",t),n===s)throw new Error("svg-colorizer made no color replacements! The input svg should only contain colors #ff00ff (primary, case-sensitive) and #00ffff (secondary, case-sensitive).");return s}class Sw{constructor(e,t,s,i){this._platform=e,this._iconVariables=t,this._resolvedVariables=s,this._manifestLocation=i}async toVariables(){const{parsedStructure:e,promises:t}=await this._fetchAndParseIcons();return await Promise.all(t),this._produceColoredIconVariables(e)}async _fetchAndParseIcons(){const e=[],t={};for(const[s,i]of Object.entries(this._iconVariables)){const r=new URL(`https://${i}`),o=r.hostname,c=new URL(o,new URL(this._manifestLocation,window.location.origin)),l=this._platform.request(c,{method:"GET",format:"text",cache:!0}).response();e.push(l);const h=r.searchParams;t[s]={svg:l,primary:h.get("primary"),secondary:h.get("secondary")}}return{parsedStructure:t,promises:e}}async _produceColoredIconVariables(e){let t={};for(const[s,{svg:i,primary:r,secondary:o}]of Object.entries(e)){const{body:c}=await i;if(!r)throw new Error(`Primary color variable ${r} not in list of variables!`);const l=this._resolvedVariables[r],h=this._resolvedVariables[o],a=bw(c,l,h),u=`url('data:image/svg+xml;utf8,${encodeURIComponent(a)}')`;t[s]=u}return t}}var Or={exports:{}},kw=function(n){var e={};function t(s){if(e[s])return e[s].exports;var i=e[s]={i:s,l:!1,exports:{}};return n[s].call(i.exports,i,i.exports,t),i.l=!0,i.exports}return t.m=n,t.c=e,t.d=function(s,i,r){t.o(s,i)||Object.defineProperty(s,i,{enumerable:!0,get:r})},t.r=function(s){typeof Symbol!="undefined"&&Symbol.toStringTag&&Object.defineProperty(s,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(s,"__esModule",{value:!0})},t.t=function(s,i){if(1&i&&(s=t(s)),8&i||4&i&&typeof s=="object"&&s&&s.__esModule)return s;var r=Object.create(null);if(t.r(r),Object.defineProperty(r,"default",{enumerable:!0,value:s}),2&i&&typeof s!="string")for(var o in s)t.d(r,o,function(c){return s[c]}.bind(null,o));return r},t.n=function(s){var i=s&&s.__esModule?function(){return s.default}:function(){return s};return t.d(i,"a",i),i},t.o=function(s,i){return Object.prototype.hasOwnProperty.call(s,i)},t.p="",t(t.s=0)}([function(n,e,t){function s(h){let a,u;const p={light:function(){return!f()},dark:f,lighten:R,darken:M,saturate:N,desaturate:function(T=0){return N(T*=-1)},increaseContrast:function(T=0){return F(T*=-1)},decreaseContrast:F,active:function(){return F(.123)},highlight:function(){return F(.1)},selected:function(){return F(.066)},text:function(){return u=v()?i("#333333"):i("#FFFFFF"),p},shadow:function(){return u=v()?i("#000000"):i("#FFFFFF"),p},hex:function(){const T=u;return u=a,"#"+T.map(D=>parseInt(D+"",10).toString(16).padStart(2,"0")).join("")},rgb:function(){const T=u;return u=a,`rgb(${T.join()})`},rgba:function(T=1){const D=u;return u=a,`rgba(${D.join()}, ${T})`},setHex:g,setRgb:function(T=[0,0,0]){let[D,B,G]=T;return D=l(D,0,255),B=l(B,0,255),G=l(G,0,255),a=[D,B,G],u=[D,B,G],p}};function g(T="#000000"){return a=i(T),u=a,p}function f(){const[T,D,B]=u;return u=a,(299*T+587*D+114*B)/1e3<128}function v(){const[T,D,B]=u;return(299*T+587*D+114*B)/1e3>=128}function M(T=0){return R(T*=-1)}function R(T=0){let[D,B,G]=c(u);return G=l(G+T,0,1),u=r([D,B,G]),p}function N(T=0){let[D,B,G]=c(u);return B=l(B+T,0,1),u=r([D,B,G]),p}function F(T=0){return v()?M(T):R(T)}return g(h),p}function i(h){if(typeof h!="string")throw new TypeError("Expected a string");(h=h.replace(/^#/,"")).length===3&&(h=h[0]+h[0]+h[1]+h[1]+h[2]+h[2]);var a=parseInt(h,16);return[a>>16,a>>8&255,255&a]}function r(h){const[a,u,p]=h;let g,f,v;if(u===0)g=f=v=p;else{const M=function(F,T,D){return D<0&&(D+=1),D>1&&(D-=1),D<.16666666666666666?F+6*(T-F)*D:D<.5?T:D<.6666666666666666?F+(T-F)*(.6666666666666666-D)*6:F},R=p<.5?p*(1+u):p+u-p*u,N=2*p-R;g=l(M(N,R,a+1/3),0,1),f=l(M(N,R,a),0,1),v=l(M(N,R,a-1/3),0,1)}return[Math.round(255*g),Math.round(255*f),Math.round(255*v)]}t.r(e),t.d(e,"offColor",function(){return s}),t.d(e,"hexRgb",function(){return i}),t.d(e,"hslToRgb",function(){return r}),t.d(e,"color",function(){return o}),t.d(e,"rgbToHsl",function(){return c});const o=s;function c(h){const a=h[0]/255,u=h[1]/255,p=h[2]/255,g=Math.max(a,u,p),f=Math.min(a,u,p);let v=(g+f)/2,M=(g+f)/2;const R=(g+f)/2;if(g===f)v=M=0;else{const N=g-f;switch(M=R>.5?N/(2-g-f):N/(g+f),g){case a:v=(u-p)/N+(u=a?h:a}}]);Or.exports=kw;var Hc=Or.exports,ra;const Jr=(ra=Or.exports.offColor)!=null?ra:Hc.offColor;function sa(n,e,t,s){const i=parseInt(t);switch(s&&(e==="darker"?e="lighter":e==="lighter"&&(e="darker")),e){case"darker":return Jr(n).darken(i/100).hex();case"lighter":return Jr(n).lighten(i/100).hex();case"alpha":return Jr(n).rgba(i/100)}}class Iw{constructor(e,t,s){this._aliases={},this._derivedAliases=[],this._baseVariables=e,this._variablesToDerive=t,this._isDark=s}toVariables(){var t;const e={};this._detectAliases();for(const s of this._variablesToDerive){const i=this._derive(s);i&&(e[s]=i)}for(const[s,i]of Object.entries(this._aliases))e[s]=(t=this._baseVariables[i])!=null?t:e[i];for(const s of this._derivedAliases){const i=this._deriveAlias(s,e);i&&(e[s]=i)}return e}_detectAliases(){const e=[];for(const t of this._variablesToDerive){const[s,i]=t.split("=");i?this._aliases[s]=i:e.push(t)}this._variablesToDerive=e}_derive(e){const t=/(.+)--(.+)-(.+)/,s=e.match(t);if(s){const[,i,r,o]=s,c=this._baseVariables[i];if(!c)if(this._aliases[i]){this._derivedAliases.push(e);return}else throw new Error(`Cannot find value for base variable "${i}"!`);return sa(c,r,o,this._isDark)}}_deriveAlias(e,t){const s=/(.+)--(.+)-(.+)/,i=e.match(s);if(i){const[,r,o,c]=i,l=t[r];if(!l)throw new Error(`Cannot find value for alias "${r}" when trying to derive ${e}!`);return sa(l,o,c,this._isDark)}}}var na;(na=Or.exports.offColor)!=null||Hc.offColor;class Mw{constructor(e,t){this._themeMapping={},this._preferredColorScheme=t,this._platform=e}async parse(e,t,s,i){await i.wrap("RuntimeThemeParser.parse",async()=>{var u;const{cssLocation:r,derivedVariables:o,icons:c}=this._getSourceData(t,s,i),l=e.name;if(!l)throw new Error("Theme name not found in manifest!");let h={},a={};for(const[p,g]of Object.entries((u=e.values)==null?void 0:u.variants))try{const f=`${e.id}-${p}`,{name:v,default:M,dark:R,variables:N}=g,F=new Iw(N,o,R).toVariables();Object.assign(N,F);const T=await new Sw(this._platform,c,N,s).toVariables();Object.assign(N,F,T);const D=`${l} ${v}`;if(M){Object.assign(R?h:a,{variantName:v,id:f,cssLocation:r,variables:N});continue}this._themeMapping[D]={cssLocation:r,id:f,variables:N}}catch(f){console.error(f);continue}if(h.id&&a.id){const p=this._preferredColorScheme===es.Dark?h:a;this._themeMapping[l]={dark:h,light:a,default:p}}else{const p=h.id?h:a;this._themeMapping[`${l} ${p.variantName}`]={id:p.id,cssLocation:p.cssLocation}}})}_getSourceData(e,t,s){return s.wrap("getSourceData",()=>{var l,h,a;const i=(l=e.source)==null?void 0:l["runtime-asset"];if(!i)throw new Error(`Run-time asset not found in source section for theme at ${t}`);const r=new URL(i,new URL(t,window.location.origin)).href,o=(h=e.source)==null?void 0:h["derived-variables"];if(!o)throw new Error(`Derived variables not found in source section for theme at ${t}`);const c=(a=e.source)==null?void 0:a.icon;if(!c)throw new Error(`Icon mapping not found in source section for theme at ${t}`);return{cssLocation:r,derivedVariables:o,icons:c}})}get themeMapping(){return this._themeMapping}}class Cw{constructor(e){this._themeMapping={},this._preferredColorScheme=e}parse(e,t,s){s.wrap("BuiltThemeParser.parse",()=>{var l,h,a;const i=(l=e.source)==null?void 0:l["built-assets"],r=e.name;if(!r)throw new Error(`Theme name not found in manifest at ${t}`);let o={},c={};for(let[u,p]of Object.entries(i)){try{p=new URL(p,new URL(t,window.location.origin)).href}catch{continue}const g=(h=u.match(/.+-(.+)/))==null?void 0:h[1],f=(a=e.values)==null?void 0:a.variants[g];if(!f)throw new Error(`Variant ${g} is missing in manifest at ${t}`);const{name:v,default:M,dark:R}=f,N=`${r} ${v}`;if(M){const F=R?o:c;F.variantName=v,F.id=u,F.cssLocation=p;continue}this._themeMapping[N]={cssLocation:p,id:u}}if(o.id&&c.id){const u=this._preferredColorScheme===es.Dark?o:c;this._themeMapping[r]={dark:o,light:c,default:u}}else{const u=o.id?o:c;this._themeMapping[`${r} ${u.variantName}`]={id:u.id,cssLocation:u.cssLocation}}})}get themeMapping(){return this._themeMapping}}class Ew{constructor(e){this._platform=e}async init(e,t){await this._platform.logger.wrapOrRun(t,"ThemeLoader.init",async s=>{let i=!0;const r=[],o=[],c=await Promise.all(e.map(u=>this._platform.request(u,{method:"GET",format:"json",cache:!0}).response())),l=new Mw(this._platform,this.preferredColorScheme),h=new Cw(this.preferredColorScheme),a=[];for(let u=0;u=200&&g<=299)){console.error(`Failed to load manifest at ${e[u]}, status: ${g}`),s.log({l:"Manifest fetch failed",location:e[u],status:g},Ge.Error),r.push(e[u]);continue}i=!1;try{if(f.extends){const v=c.findIndex(F=>"value"in F&&F.value.body.id===f.extends);if(v===-1)throw new Error(`Base manifest for derived theme at ${e[u]} not found!`);const{body:M}=c[v].value,R=e[v],N=l.parse(f,M,R,s);a.push(N)}else h.parse(f,e[u],s)}catch(v){console.error(v),o.push(v.message)}}if(await Promise.all(a),this._themeMapping=It(It({},h.themeMapping),l.themeMapping),i)throw new Error(`All configured theme manifests failed to load, the following were tried: ${r.join(", ")}`);if(Object.keys(this._themeMapping).length===0&&o.length)throw new Error(`Failed to parse theme manifests, the following errors were encountered: ${o.join(", ")}`);this._addDefaultThemeToMapping(s),s.log({l:"Preferred colorscheme",scheme:this.preferredColorScheme===es.Dark?"dark":"light"}),s.log({l:"Result",themeMapping:this._themeMapping})})}async setTheme(e,t,s){await this._platform.logger.wrapOrRun(s,{l:"change theme",name:e,variant:t},async i=>{let r,o,c=this._themeMapping[e];if("id"in c)r=c.cssLocation,o=c.variables;else{if(!t)throw new Error("themeVariant is undefined!");r=c[t].cssLocation,o=c[t].variables}await this._platform.replaceStylesheet(r,i),o?(s==null||s.log({l:"Derived Theme",variables:o}),this._injectCSSVariables(o)):this._removePreviousCSSVariables(),this._platform.settingsStorage.setString("theme-name",e),t?this._platform.settingsStorage.setString("theme-variant",t):this._platform.settingsStorage.remove("theme-variant")})}_injectCSSVariables(e){const t=document.documentElement;for(const[s,i]of Object.entries(e))t.style.setProperty(`--${s}`,i);this._injectedVariables=e}_removePreviousCSSVariables(){if(!this._injectedVariables)return;const e=document.documentElement;for(const t of Object.keys(this._injectedVariables))e.style.removeProperty(`--${t}`);this._injectedVariables=void 0}get themeMapping(){return this._themeMapping}async getActiveTheme(){let e=await this._platform.settingsStorage.getString("theme-name"),t=await this._platform.settingsStorage.getString("theme-variant");return(!e||!this._themeMapping[e])&&(e="Default"in this._themeMapping?"Default":Object.keys(this._themeMapping)[0],this._themeMapping[e][t]||(t="default"in this._themeMapping[e]?"default":void 0)),{themeName:e,themeVariant:t}}getDefaultTheme(){var e,t;switch(this.preferredColorScheme){case es.Dark:return(e=this._platform.config.defaultTheme)==null?void 0:e.dark;case es.Light:return(t=this._platform.config.defaultTheme)==null?void 0:t.light}}_findThemeDetailsFromId(e){var t,s;for(const[i,r]of Object.entries(this._themeMapping)){if("id"in r&&r.id===e)return{themeName:i,themeData:r};if("light"in r&&((t=r.light)==null?void 0:t.id)===e)return{themeName:i,themeData:r.light};if("dark"in r&&((s=r.dark)==null?void 0:s.id)===e)return{themeName:i,themeData:r.dark}}}_addDefaultThemeToMapping(e){e.wrap("addDefaultThemeToMapping",t=>{const s=this.getDefaultTheme();if(s){const i=this._findThemeDetailsFromId(s);if(i){this._themeMapping.Default={id:"default",cssLocation:i.themeData.cssLocation};const r=i.themeData.variables;r&&(this._themeMapping.Default.variables=r)}}t.log({l:"Default Theme",theme:s})})}get preferredColorScheme(){if(window.matchMedia("(prefers-color-scheme: dark)").matches)return es.Dark;if(window.matchMedia("(prefers-color-scheme: light)").matches)return es.Light}}var Wc=(n=>(n[n.Minute=6e4]="Minute",n[n.Hours=36e5]="Hours",n[n.Day=864e5]="Day",n))(Wc||{});function Rw(n){let e=0,t=0,s=0;n>=864e5&&(e=Math.floor(n/864e5),n-=e*864e5),n>=36e5&&(t=Math.floor(n/36e5),n-=t*36e5),n>=6e4&&(s=Math.floor(n/6e4),n-=s*6e4);const i=Math.floor(n/1e3);let r="";return e&&(r=`${e}d `),(t||e)&&(r+=`${t}h `),(s||t||e)&&(r+=`${s}m `),r+=`${i}s`,r}class Tw{constructor(e){this.clock=e,this.todayMidnight=new Date,this.todayMidnight.setHours(0,0,0,0),this.relativeDayFormatter=new Intl.RelativeTimeFormat(void 0,{numeric:"auto"}),this.weekdayFormatter=new Intl.DateTimeFormat(void 0,{weekday:"long"}),this.currentYearFormatter=new Intl.DateTimeFormat(void 0,{weekday:"long",month:"long",day:"numeric"}),this.otherYearFormatter=new Intl.DateTimeFormat(void 0,{weekday:"long",year:"numeric",month:"long",day:"numeric"}),this.timeFormatter=new Intl.DateTimeFormat(void 0,{hour:"numeric",minute:"2-digit"})}formatTime(e){return this.timeFormatter.format(e)}formatMachineReadableDate(e){return`${e.getFullYear()}-${e.getMonth()+1}-${e.getDate()}`}formatRelativeDate(e){let t=Math.floor((e.getTime()-this.todayMidnight.getTime())/Wc.Day);return t>=-1&&t<=1?Aw(this.relativeDayFormatter.format(t,"day")):t>-7&&t<0?this.weekdayFormatter.format(e):this.todayMidnight.getFullYear()===e.getFullYear()?this.currentYearFormatter.format(e):this.otherYearFormatter.format(e)}formatDuration(e){return Rw(e)}}function Aw(n){return n.slice(0,1).toLocaleUpperCase()+n.slice(1)}function ia(n){return new Promise(function(e,t){var s=document.createElement("script");s.setAttribute("src",n),s.onload=e,s.onerror=t,document.body.appendChild(s)})}async function xw(n){return window.msCrypto&&!window.crypto&&(window.crypto=window.msCrypto),n?(window.WebAssembly?(await ia(n.wasmBundle),await window.Olm.init({locateFile:()=>n.wasm})):(await ia(n.legacyBundle),await window.Olm.init()),window.Olm):null}function Vw(n){return n.startsWith("/")?n:new URL(n,document.location.href).pathname}async function Nw(n){const e=new Ky(n.worker,4);return await e.init(),await e.sendAll({type:"load_olm",path:Vw(n.olm.legacyBundle)}),new kg(e)}function Dw(n){if(!window.visualViewport)return;const e=()=>{const t=n.querySelector(".SessionView");if(!t)return;const s=n.querySelector(".bottom-aligned-scroll");let i,r,o;s&&(i=s.scrollTop,r=s.offsetHeight);const c=t.offsetTop+t.offsetHeight-window.visualViewport.height;n.style.setProperty("--ios-viewport-height",window.visualViewport.height.toString()+"px"),n.style.setProperty("--ios-viewport-top",c.toString()+"px"),s&&(o=s.offsetHeight,s.scrollTop=i+r-o)};return window.visualViewport.addEventListener("resize",e),()=>{window.visualViewport.removeEventListener("resize",e)}}class Uw{constructor({container:e,assetPaths:t,config:s,configURL:i,logger:r,options:o=null,cryptoExtras:c=null}){this._container=e,this._assetPaths=t,this._config=s,this._configURL=i,this.settingsStorage=new ug("hydrogen_setting_v1_"),this.clock=new Iy,this.encoding=new Sg,this.random=Math.random,this.logger=r!=null?r:this._createLogger(o==null?void 0:o.development),this.history=new Ey,this.onlineStatus=new Ry,this.timeFormatter=new Tw,this._serviceWorkerHandler=null,this.sessionInfoStorage=new dg("hydrogen_sessions_v1"),t.serviceWorker&&"serviceWorker"in navigator&&(this._serviceWorkerHandler=new My(this.sessionInfoStorage),this._serviceWorkerHandler.registerAndStart(t.serviceWorker)),this.notificationService=void 0,this._assetPaths.olm&&(this.crypto=new Oy(c)),this.storageFactory=new zd(this._serviceWorkerHandler),this.estimateStorageUsage=Py,typeof fetch=="function"?this.request=hg(this.clock.createTimeout,this._serviceWorkerHandler):this.request=bc;const l=!!window.MSInputMethodContext&&!!document.documentMode;this.isIE11=l;const h=/iPad|iPhone|iPod/.test(navigator.platform)||navigator.platform==="MacIntel"&&navigator.maxTouchPoints>1&&!window.MSStream;this.isIOS=h,this._disposables=new li,this._olmPromise=void 0,this._workerPromise=void 0,this.mediaDevices=new yw(navigator.mediaDevices),this.webRTC=new vw,this._themeLoader=new Ew(this)}async init(){try{await this.logger.run("Platform init",async e=>{var t;if(!this._config){if(!this._configURL)throw new Error("Neither config nor configURL was provided!");const{status:s,body:i}=await this.request(this._configURL,{method:"GET",format:"json",cache:!0}).response();if(s===404)throw new Error(`Could not find ${this._configURL}. Did you copy over config.sample.json?`);if(s>=400)throw new Error(`Got status ${s} while trying to fetch ${this._configURL}`);this._config=i}if(this.notificationService=new Cy(this._serviceWorkerHandler,this._config.push),this._themeLoader){const s=this.config.themeManifests;await((t=this._themeLoader)==null?void 0:t.init(s,e));const{themeName:i,themeVariant:r}=await this._themeLoader.getActiveTheme();e.log({l:"Active theme",name:i,variant:r}),await this._themeLoader.setTheme(i,r,e)}})}catch(e){throw this._container.innerText=e.message,e}}_createLogger(e){const t=new Ag({platform:this}),s=r=>{var o;return(o=r.e)!=null&&o.stack&&(r.e.stack=r.e.stack.replace(/\/\?loginToken=(.+)/,"?loginToken=")),r},i=new Ig({name:"hydrogen_logs",platform:this,serializedTransformer:s});return t.addReporter(i),e&&t.addReporter(new Cg),t}get updateService(){return this._serviceWorkerHandler}loadOlm(){return this._olmPromise||(this._olmPromise=xw(this._assetPaths.olm)),this._olmPromise}get config(){return this._config}async loadOlmWorker(){if(!window.WebAssembly)return this._workerPromise||(this._workerPromise=Nw(this._assetPaths)),this._workerPromise}createAndMountRootView(e){if(this.isIE11&&(this._container.className+=" legacy"),this.isIOS){this._container.className+=" ios";const s=Dw(this._container);s&&this._disposables.track(s)}this._container.addEventListener("error",$o,!0),this._disposables.track(()=>this._container.removeEventListener("error",$o,!0)),window.__hydrogenViewModel=e;const t=new vy(e);this._container.appendChild(t.mount())}setNavigation(e){var t;(t=this._serviceWorkerHandler)==null||t.setNavigation(e)}createBlob(e,t){return Ts.fromBuffer(e,t)}saveFileAs(e,t){navigator.msSaveBlob?navigator.msSaveBlob(e.nativeBlob,t):jy(this._container,this._assetPaths.downloadSandbox,e,t,this.isIOS)}async copyPlaintext(e){return await jf(e)}restart(){document.location.reload()}openFile(e=null){const t=document.createElement("input");t.setAttribute("type","file"),t.className="hidden",e&&t.setAttribute("accept",e);const s=new Promise(i=>{const r=()=>{t.removeEventListener("change",r,!0);const o=t.files[0];this._container.removeChild(t),o?i({name:o.name,blob:Ts.fromBlobUnsafe(o)}):i()};t.addEventListener("change",r,!0)});return this._container.appendChild(t),t.click(),s}openUrl(e){location.href=e}parseHTML(e){return _w(e)}async loadImage(e){return ji.fromBlob(e)}async loadVideo(e){return Bn.fromBlob(e)}hasReadPixelPermission(){return By()}get devicePixelRatio(){return window.devicePixelRatio||1}get version(){return"0.5.1"}get themeLoader(){return this._themeLoader}async replaceStylesheet(e,t){const s=await this.logger.wrapOrRun(t,{l:"replaceStylesheet",location:e},async i=>{let r;const o=document.querySelector("head");document.querySelectorAll(".theme").forEach(h=>h.remove());const c=document.createElement("link");c.href=e,c.rel="stylesheet",c.type="text/css",c.className="theme";const l=new Promise(h=>{c.onerror=()=>{r=new Error(`Failed to load stylesheet from ${e}`),i.catch(r),h()},c.onload=()=>{h()}});return o.appendChild(c),await l,r});if(s)throw s}get description(){var e;return"web-"+((e=navigator.userAgent)!=null?e:"")}dispose(){this._disposables.dispose()}}var Ow="./config.json",Pw="./assets/download-sandbox.48a866e9.html",Fw="./assets/main.bdb9a925.js",Lw="./assets/olm.3fc8dbfe.wasm",Kw="./assets/olm.cf9a793b.js",Bw="./assets/olm_legacy.bc22f405.js",zc={downloadSandbox:Pw,worker:Fw,olm:{wasm:Lw,legacyBundle:Bw,wasmBundle:Kw}};zc.serviceWorker="sw.js";const $w=new Uw({container:document.body,assetPaths:zc,configURL:Ow,options:{development:!1}});ng($w);
+//# sourceMappingURL=index.e65aa065.js.map
diff --git a/hydrogen/assets/index.e65aa065.js.map b/hydrogen/assets/index.e65aa065.js.map
new file mode 100644
index 0000000..dc31a12
--- /dev/null
+++ b/hydrogen/assets/index.e65aa065.js.map
@@ -0,0 +1 @@
+{"version":3,"file":"index.e65aa065.js","sources":["../../src/utils/enum.ts","../../src/matrix/well-known.js","../../src/utils/EventEmitter.ts","../../src/utils/AbortableOperation.ts","../../src/utils/error.ts","../../src/observable/BaseObservable.ts","../../src/observable/value/BaseObservableValue.ts","../../src/observable/value/EventObservableValue.ts","../../src/observable/value/ObservableValue.ts","../../src/observable/value/FlatMapObservableValue.ts","../../src/observable/value/PickMapObservableValue.ts","../../src/observable/value/RetainedObservableValue.ts","../../src/observable/list/BaseObservableList.ts","../../src/utils/sortedIndex.ts","../../src/observable/list/ObservableArray.ts","../../src/observable/list/common.ts","../../src/observable/list/SortedArray.ts","../../src/observable/list/BaseMappedList.ts","../../src/observable/list/AsyncMappedList.ts","../../src/observable/list/ConcatList.ts","../../src/observable/list/SortedMapList.js","../../src/observable/map/BaseObservableMap.ts","../../src/observable/map/ApplyMap.ts","../../src/observable/map/FilteredMap.ts","../../src/observable/map/JoinedMap.ts","../../src/observable/map/MappedMap.ts","../../src/observable/map/ObservableMap.ts","../../src/observable/map/ObservableValueMap.ts","../../src/observable/value/MapSizeObservableValue.ts","../../src/platform/web/dom/BlobHandle.js","../../src/matrix/net/common.ts","../../src/matrix/error.js","../../src/matrix/net/HomeServerRequest.ts","../../src/matrix/net/HomeServerApi.ts","../../src/matrix/net/ExponentialRetryDelay.ts","../../src/matrix/net/Reconnector.ts","../../src/matrix/e2ee/attachment.js","../../src/matrix/net/MediaRepository.ts","../../src/matrix/net/RequestScheduler.ts","../../src/matrix/Sync.js","../../node_modules/another-json/another-json.js","../../src/matrix/e2ee/common.ts","../../src/matrix/room/common.ts","../../src/matrix/room/RoomSummary.js","../../src/matrix/storage/common.ts","../../src/matrix/room/timeline/EventKey.ts","../../src/matrix/room/timeline/entries/BaseEntry.ts","../../src/matrix/room/timeline/relations.js","../../src/matrix/room/timeline/PendingAnnotation.js","../../src/matrix/room/timeline/entries/reply.js","../../src/matrix/room/timeline/entries/BaseEventEntry.js","../../src/matrix/room/timeline/entries/PendingEventEntry.js","../../src/utils/Deferred.ts","../../src/matrix/room/sending/PendingEvent.js","../../src/matrix/room/timeline/entries/EventEntry.js","../../src/matrix/room/timeline/persistence/common.js","../../src/matrix/room/members/RoomMember.js","../../src/matrix/room/timeline/common.js","../../src/matrix/room/timeline/FragmentIdComparer.js","../../vite/preload-helper","../../src/matrix/storage/idb/error.ts","../../src/matrix/storage/idb/utils.ts","../../src/matrix/storage/idb/QueryTarget.ts","../../src/matrix/storage/idb/Store.ts","../../src/utils/typedJSON.ts","../../src/matrix/storage/idb/stores/SessionStore.ts","../../src/matrix/storage/idb/stores/RoomSummaryStore.ts","../../src/matrix/storage/idb/stores/InviteStore.ts","../../src/logging/LogFilter.ts","../../src/logging/NullLogger.ts","../../src/matrix/storage/idb/stores/TimelineEventStore.ts","../../src/matrix/storage/idb/stores/common.ts","../../src/matrix/storage/idb/stores/TimelineRelationStore.ts","../../src/matrix/storage/idb/stores/RoomStateStore.ts","../../src/matrix/storage/idb/stores/RoomMemberStore.ts","../../src/matrix/storage/idb/stores/TimelineFragmentStore.ts","../../src/matrix/storage/idb/stores/PendingEventStore.ts","../../src/matrix/storage/idb/stores/UserIdentityStore.ts","../../src/matrix/storage/idb/stores/DeviceKeyStore.ts","../../src/matrix/storage/idb/stores/CrossSigningKeyStore.ts","../../src/matrix/storage/idb/stores/OlmSessionStore.ts","../../src/matrix/storage/idb/stores/InboundGroupSessionStore.ts","../../src/matrix/storage/idb/stores/OutboundGroupSessionStore.ts","../../src/matrix/storage/idb/stores/GroupSessionDecryptionStore.ts","../../src/matrix/storage/idb/stores/OperationStore.ts","../../src/matrix/storage/idb/stores/AccountDataStore.ts","../../src/matrix/storage/idb/stores/CallStore.ts","../../src/matrix/storage/idb/stores/SharedSecretStore.ts","../../src/matrix/storage/idb/Transaction.ts","../../src/matrix/storage/idb/Storage.ts","../../src/matrix/storage/idb/export.ts","../../src/matrix/verification/common.ts","../../src/matrix/verification/SAS/stages/BaseSASVerificationStage.ts","../../src/matrix/verification/SAS/channel/types.ts","../../src/matrix/verification/SAS/stages/constants.ts","../../src/matrix/verification/SAS/generator.ts","../../src/matrix/verification/SAS/mac.ts","../../src/matrix/verification/SAS/stages/SendDoneStage.ts","../../src/matrix/verification/SAS/stages/VerifyMacStage.ts","../../src/matrix/verification/SAS/stages/SendMacStage.ts","../../src/matrix/verification/SAS/VerificationCancelledError.ts","../../src/matrix/verification/SAS/stages/CalculateSASStage.ts","../../src/matrix/verification/SAS/stages/SendKeyStage.ts","../../src/matrix/verification/SAS/stages/SendAcceptVerificationStage.ts","../../src/matrix/verification/SAS/stages/SelectVerificationMethodStage.ts","../../src/matrix/verification/SAS/stages/SendRequestVerificationStage.ts","../../src/matrix/verification/SAS/stages/SendReadyStage.ts","../../__vite-browser-external","../../node_modules/@matrix-org/olm/olm.js","../../src/matrix/verification/SAS/SASVerification.ts","../../src/matrix/verification/SAS/channel/IChannel.ts","../../src/utils/groupBy.ts","../../src/matrix/common.js","../../src/utils/Disposables.ts","../../src/matrix/verification/SAS/channel/ToDeviceChannel.ts","../../src/matrix/verification/SAS/channel/RoomChannel.ts","../../src/matrix/verification/SAS/SASRequest.ts","../../src/matrix/verification/CrossSigning.ts","../../src/matrix/e2ee/DeviceTracker.ts","../../src/matrix/storage/idb/schema.ts","../../src/matrix/storage/idb/quirks.ts","../../src/matrix/storage/idb/StorageFactory.ts","../../src/matrix/room/timeline/persistence/RelationWriter.js","../../src/matrix/room/timeline/Direction.ts","../../src/matrix/room/timeline/entries/FragmentBoundaryEntry.js","../../src/matrix/room/timeline/persistence/SyncWriter.js","../../src/utils/LRUCache.ts","../../src/matrix/room/timeline/persistence/MemberWriter.js","../../src/matrix/room/timeline/persistence/GapWriter.js","../../src/matrix/room/timeline/persistence/TimelineReader.js","../../src/matrix/room/timeline/entries/NonPersistedEventEntry.js","../../src/utils/RetainedValue.ts","../../src/matrix/User.js","../../src/matrix/room/timeline/Timeline.js","../../src/matrix/room/members/load.js","../../src/matrix/room/members/MemberList.js","../../src/matrix/room/members/Heroes.js","../../src/matrix/room/ObservedEventMap.js","../../src/logging/utils.ts","../../src/matrix/room/PowerLevels.js","../../src/matrix/room/state/ObservedStateTypeMap.ts","../../src/matrix/room/state/ObservedStateKeyValue.ts","../../src/matrix/room/BaseRoom.js","../../src/matrix/room/sending/SendQueue.js","../../src/matrix/room/AttachmentUpload.js","../../src/matrix/room/Room.js","../../src/matrix/room/ArchivedRoom.js","../../src/matrix/profile.ts","../../src/matrix/room/RoomBeingCreated.ts","../../src/matrix/room/Invite.js","../../src/matrix/push/Pusher.ts","../../src/matrix/DeviceMessageHandler.js","../../src/matrix/e2ee/Account.js","../../src/matrix/ssss/common.ts","../../src/matrix/ssss/passphrase.ts","../../src/matrix/ssss/recoveryKey.ts","../../src/matrix/ssss/SecretFetcher.ts","../../src/matrix/ssss/SecretSharing.ts","../../src/matrix/ssss/SecretStorage.ts","../../src/matrix/ssss/index.ts","../../src/matrix/e2ee/Dehydration.js","../../src/utils/Lock.ts","../../src/matrix/e2ee/olm/Session.ts","../../src/matrix/e2ee/DecryptionResult.ts","../../src/matrix/e2ee/olm/types.ts","../../src/matrix/e2ee/olm/Decryption.ts","../../src/matrix/e2ee/olm/Encryption.ts","../../src/matrix/e2ee/megolm/decryption/DecryptionChanges.js","../../src/utils/mergeMap.ts","../../src/matrix/e2ee/megolm/decryption/DecryptionPreparation.js","../../src/matrix/e2ee/megolm/decryption/ReplayDetectionEntry.ts","../../src/matrix/e2ee/megolm/decryption/SessionDecryption.ts","../../src/matrix/e2ee/megolm/decryption/utils.ts","../../src/matrix/e2ee/megolm/decryption/RoomKey.ts","../../src/matrix/e2ee/megolm/Decryption.ts","../../src/matrix/e2ee/megolm/decryption/KeyLoader.ts","../../src/matrix/e2ee/megolm/keybackup/Curve25519.ts","../../src/matrix/e2ee/megolm/keybackup/KeyBackup.ts","../../src/matrix/e2ee/megolm/Encryption.js","../../src/matrix/e2ee/RoomEncryption.js","../../src/utils/LockMap.ts","../../src/utils/recursivelyAssign.ts","../../src/platform/types/MediaDevices.ts","../../src/matrix/calls/common.ts","../../src/matrix/calls/callEventTypes.ts","../../src/matrix/calls/PeerCall.ts","../../src/utils/ErrorBoundary.ts","../../src/matrix/calls/group/Member.ts","../../src/matrix/calls/group/GroupCall.ts","../../src/matrix/calls/TurnServerSource.ts","../../src/matrix/calls/CallHandler.ts","../../src/matrix/room/state/RoomStateHandlerSet.ts","../../src/features.ts","../../src/matrix/Session.js","../../src/matrix/login/PasswordLoginMethod.ts","../../src/matrix/login/TokenLoginMethod.ts","../../src/matrix/login/SSOLoginHelper.ts","../../src/matrix/registration/stages/BaseRegistrationStage.ts","../../src/matrix/registration/stages/DummyAuth.ts","../../src/matrix/registration/stages/TermsAuth.ts","../../src/matrix/registration/stages/TokenAuth.ts","../../src/matrix/registration/Registration.ts","../../src/matrix/Client.js","../../src/domain/ViewModel.ts","../../src/domain/avatar.ts","../../src/domain/session/leftpanel/BaseTileViewModel.js","../../src/domain/session/leftpanel/RoomTileViewModel.js","../../src/domain/session/leftpanel/common.js","../../src/domain/session/leftpanel/InviteTileViewModel.js","../../src/domain/session/leftpanel/RoomBeingCreatedTileViewModel.js","../../src/domain/session/leftpanel/RoomFilter.js","../../src/domain/navigation/Navigation.ts","../../src/domain/navigation/URLRouter.ts","../../src/domain/navigation/index.ts","../../src/domain/session/leftpanel/LeftPanelViewModel.js","../../src/domain/session/room/timeline/tiles/ITile.ts","../../src/domain/session/room/timeline/UpdateAction.js","../../src/domain/session/room/timeline/TilesCollection.js","../../src/domain/session/room/timeline/TimelineViewModel.js","../../src/domain/session/room/ComposerViewModel.js","../../src/domain/rageshake.ts","../../src/domain/ErrorViewModel.ts","../../src/domain/ErrorReportViewModel.ts","../../src/domain/session/room/CallViewModel.ts","../../src/domain/session/common.js","../../src/matrix/calls/LocalMedia.ts","../../src/domain/session/room/timeline/tiles/DateTile.ts","../../src/domain/session/room/timeline/tiles/SimpleTile.ts","../../src/domain/session/room/timeline/tiles/GapTile.js","../../src/domain/session/room/timeline/ReactionsViewModel.js","../../src/domain/session/room/timeline/tiles/BaseMessageTile.js","../../src/domain/session/room/timeline/linkify/regex.ts","../../src/domain/session/room/timeline/linkify/linkify.ts","../../src/domain/session/room/timeline/MessageBody.js","../../src/domain/session/room/timeline/tiles/BaseTextTile.js","../../src/domain/session/room/timeline/deserialize.js","../../src/domain/session/room/timeline/tiles/TextTile.js","../../src/domain/session/room/timeline/tiles/RedactedTile.js","../../src/domain/session/room/timeline/tiles/BaseMediaTile.js","../../src/domain/session/room/timeline/tiles/ImageTile.js","../../src/domain/session/room/timeline/tiles/VideoTile.js","../../src/utils/formatSize.ts","../../src/domain/session/room/timeline/tiles/FileTile.js","../../src/domain/session/room/timeline/tiles/LocationTile.js","../../src/domain/session/room/timeline/tiles/RoomNameTile.js","../../src/domain/session/room/timeline/tiles/RoomMemberTile.js","../../src/domain/session/room/timeline/tiles/EncryptedEventTile.js","../../src/domain/session/room/timeline/tiles/EncryptionEnabledTile.js","../../src/domain/session/room/timeline/tiles/MissingAttachmentTile.js","../../src/domain/session/room/timeline/tiles/CallTile.js","../../src/domain/session/room/timeline/tiles/VerificationTile.ts","../../src/domain/session/room/timeline/tiles/index.ts","../../src/matrix/room/joinRoom.ts","../../src/domain/session/room/RoomViewModel.js","../../src/domain/session/room/UnknownRoomViewModel.js","../../src/domain/session/room/InviteViewModel.js","../../src/domain/session/room/RoomBeingCreatedViewModel.js","../../src/domain/session/room/LightboxViewModel.js","../../src/domain/session/SessionStatusViewModel.js","../../src/domain/session/RoomGridViewModel.js","../../src/domain/session/settings/KeyBackupViewModel.ts","../../src/domain/session/settings/FeaturesViewModel.ts","../../src/domain/session/settings/SettingsViewModel.js","../../src/domain/session/CreateRoomViewModel.js","../../src/domain/session/JoinRoomViewModel.ts","../../src/domain/session/verification/stages/WaitingForOtherUserViewModel.ts","../../src/domain/session/verification/stages/DismissibleVerificationViewModel.ts","../../src/domain/session/verification/stages/VerificationCancelledViewModel.ts","../../src/domain/session/verification/stages/SelectMethodViewModel.ts","../../src/domain/session/verification/stages/VerifyEmojisViewModel.ts","../../src/domain/session/verification/stages/VerificationCompleteViewModel.ts","../../src/domain/session/verification/stages/MissingKeysViewModel.ts","../../src/domain/session/verification/DeviceVerificationViewModel.ts","../../src/domain/session/RoomViewModelObservable.js","../../src/domain/session/rightpanel/RoomDetailsViewModel.js","../../src/domain/session/rightpanel/MemberTileViewModel.js","../../src/domain/session/rightpanel/members/comparator.js","../../src/domain/session/rightpanel/members/disambiguator.js","../../src/domain/session/rightpanel/MemberListViewModel.js","../../src/domain/session/rightpanel/MemberDetailsViewModel.js","../../src/domain/session/rightpanel/InvitePanelViewModel.ts","../../src/domain/session/rightpanel/RightPanelViewModel.js","../../src/domain/session/toast/BaseToastNotificationViewModel.ts","../../src/domain/session/toast/calls/CallToastNotificationViewModel.ts","../../src/domain/session/toast/calls/CallsToastCollectionViewModel.ts","../../src/domain/session/toast/verification/VerificationToastNotificationViewModel.ts","../../src/domain/session/toast/verification/VerificationToastCollectionViewModel.ts","../../src/domain/session/toast/ToastCollectionViewModel.ts","../../src/domain/session/SessionViewModel.js","../../src/domain/AccountSetupViewModel.js","../../src/domain/SessionLoadViewModel.js","../../src/domain/login/PasswordLoginViewModel.ts","../../src/domain/login/StartSSOLoginViewModel.ts","../../src/domain/login/CompleteSSOLoginViewModel.ts","../../src/domain/login/LoginViewModel.ts","../../src/domain/LogoutViewModel.ts","../../src/domain/ForcedLogoutViewModel.ts","../../src/domain/SessionPickerViewModel.js","../../src/domain/RootViewModel.js","../../src/platform/web/main.js","../../src/utils/timeout.ts","../../src/platform/web/dom/request/common.js","../../src/platform/web/dom/request/xhr.js","../../src/platform/web/dom/request/fetch.js","../../src/matrix/sessioninfo/localstorage/SessionInfoStorage.ts","../../src/platform/web/dom/SettingsStorage.js","../../src/platform/web/dom/UTF8.js","../../node_modules/base64-arraybuffer/lib/base64-arraybuffer.js","../../src/platform/web/utils/Base64.js","../../scripts/package-overrides/buffer/index.js","../../node_modules/base-x/src/index.js","../../node_modules/bs58/index.js","../../src/platform/web/utils/Base58.js","../../src/platform/web/utils/Encoding.js","../../src/matrix/e2ee/OlmWorker.js","../../src/logging/IDBLogPersister.ts","../../src/logging/ConsoleReporter.ts","../../src/logging/LogItem.ts","../../src/logging/Logger.ts","../../src/platform/web/ui/general/html.ts","../../src/platform/web/ui/general/utils.ts","../../src/platform/web/ui/general/ListView.ts","../../src/platform/web/ui/general/BaseUpdateView.ts","../../src/platform/web/ui/general/TemplateView.ts","../../src/platform/web/ui/avatar.js","../../src/platform/web/ui/AvatarView.js","../../src/platform/web/ui/common.js","../../src/platform/web/ui/session/leftpanel/RoomTileView.js","../../src/platform/web/ui/general/Menu.js","../../src/platform/web/ui/general/Popup.js","../../src/platform/web/ui/session/leftpanel/LeftPanelView.js","../../src/platform/web/ui/session/room/TimelineView.ts","../../src/platform/web/ui/session/room/TimelineLoadingView.js","../../src/platform/web/ui/session/room/MessageComposer.js","../../src/platform/web/ui/session/room/DisabledComposerView.js","../../src/platform/web/ui/general/ErrorView.ts","../../src/platform/web/ui/session/room/CallView.ts","../../src/platform/web/ui/session/room/RoomView.js","../../src/platform/web/ui/session/room/UnknownRoomView.js","../../src/platform/web/ui/general/StaticView.js","../../src/platform/web/ui/general/LoadingView.js","../../src/platform/web/ui/session/room/RoomBeingCreatedView.js","../../src/platform/web/ui/session/room/InviteView.js","../../src/platform/web/ui/session/room/LightboxView.js","../../src/platform/web/ui/session/SessionStatusView.js","../../src/platform/web/ui/session/RoomGridView.js","../../src/platform/web/ui/session/settings/KeyBackupSettingsView.ts","../../src/platform/web/ui/session/settings/FeaturesView.ts","../../src/platform/web/ui/session/settings/SettingsView.js","../../src/platform/web/ui/session/CreateRoomView.js","../../src/platform/web/ui/session/rightpanel/RoomDetailsView.js","../../src/platform/web/ui/general/Range.ts","../../src/platform/web/ui/general/ListRange.ts","../../src/platform/web/ui/general/LazyListView.ts","../../src/platform/web/ui/session/rightpanel/MemberTileView.js","../../src/platform/web/ui/session/rightpanel/MemberListView.js","../../src/platform/web/ui/session/rightpanel/MemberDetailsView.js","../../src/platform/web/ui/session/verification/stages/WaitingForOtherUserView.ts","../../src/platform/web/ui/session/verification/stages/VerificationCancelledView.ts","../../src/platform/web/ui/session/verification/stages/SelectMethodView.ts","../../src/platform/web/ui/session/verification/stages/VerifyEmojisView.ts","../../src/platform/web/ui/session/verification/stages/VerificationCompleteView.ts","../../src/platform/web/ui/session/verification/stages/MissingKeysView.ts","../../src/platform/web/ui/session/verification/DeviceVerificationView.ts","../../src/platform/web/ui/session/rightpanel/InvitePanelView.ts","../../src/platform/web/ui/session/rightpanel/RightPanelView.js","../../src/platform/web/ui/session/room/timeline/ReactionsView.js","../../src/platform/web/ui/session/room/timeline/BaseMessageView.js","../../src/platform/web/ui/session/room/timeline/ReplyPreviewView.js","../../src/platform/web/ui/session/room/timeline/TextMessageView.js","../../src/platform/web/ui/session/room/timeline/BaseMediaView.js","../../src/platform/web/ui/session/room/timeline/ImageView.js","../../src/platform/web/dom/utils.ts","../../src/platform/web/ui/session/room/timeline/VideoView.js","../../src/platform/web/ui/session/room/timeline/FileView.js","../../src/platform/web/ui/session/room/timeline/LocationView.js","../../src/platform/web/ui/session/room/timeline/MissingAttachmentView.js","../../src/platform/web/ui/session/room/timeline/AnnouncementView.js","../../src/platform/web/ui/session/room/timeline/RedactedView.js","../../src/platform/web/ui/session/room/timeline/GapView.js","../../src/platform/web/ui/session/room/timeline/CallTileView.ts","../../src/platform/web/ui/session/room/timeline/DateHeaderView.ts","../../src/platform/web/ui/session/room/timeline/VerificationTileView.ts","../../src/platform/web/ui/session/room/common.ts","../../src/platform/web/ui/session/JoinRoomView.ts","../../src/platform/web/ui/session/toast/CallToastNotificationView.ts","../../src/platform/web/ui/session/toast/VerificationToastNotificationView.ts","../../src/platform/web/ui/session/toast/ToastCollectionView.ts","../../src/platform/web/ui/session/SessionView.js","../../src/platform/web/ui/login/common.js","../../src/platform/web/ui/login/PasswordLoginView.js","../../src/platform/web/ui/login/AccountSetupView.js","../../src/platform/web/ui/login/SessionLoadStatusView.js","../../src/platform/web/ui/login/CompleteSSOView.js","../../src/platform/web/ui/login/LoginView.js","../../src/platform/web/ui/LogoutView.js","../../src/platform/web/ui/ForcedLogoutView.js","../../src/platform/web/ui/login/SessionLoadView.js","../../src/platform/web/ui/login/SessionPickerView.js","../../src/platform/web/ui/RootView.js","../../src/platform/web/dom/Clock.js","../../src/platform/web/dom/ServiceWorkerHandler.js","../../src/platform/web/dom/NotificationService.js","../../src/platform/web/dom/History.js","../../src/platform/web/dom/OnlineStatus.js","../../src/platform/web/dom/Crypto.js","../../src/platform/web/dom/StorageEstimate.js","../../src/platform/web/dom/WorkerPool.js","../../src/platform/web/dom/ImageHandle.js","../../src/platform/web/dom/download.js","../../node_modules/dompurify/dist/purify.es.js","../../src/platform/web/parsehtml.js","../../src/platform/web/dom/MediaDevices.ts","../../src/platform/web/dom/WebRTC.ts","../../src/platform/web/theming/parsers/types.ts","../../src/platform/web/theming/shared/svg-colorizer.mjs","../../src/platform/web/theming/IconColorizer.ts","../../node_modules/off-color/cjs/index.min.js","../../node_modules/off-color/index.js","../../src/platform/web/theming/shared/color.mjs","../../src/platform/web/theming/DerivedVariables.ts","../../src/platform/web/theming/parsers/RuntimeThemeParser.ts","../../src/platform/web/theming/parsers/BuiltThemeParser.ts","../../src/platform/web/theming/ThemeLoader.ts","../../src/utils/timeFormatting.ts","../../src/platform/web/dom/TimeFormatter.ts","../../src/platform/web/Platform.js","../../src/platform/web/assets/config.json?url","../../src/platform/web/assets/download-sandbox.html?url","../../src/platform/web/worker/main.js?url","../../node_modules/@matrix-org/olm/olm.wasm?url","../../node_modules/@matrix-org/olm/olm.js?url","../../node_modules/@matrix-org/olm/olm_legacy.js?url","../../src/platform/web/sdk/paths/vite.js","../../src/platform/web/index.html?html-proxy&index=0.js"],"sourcesContent":["/*\nCopyright 2020 Bruno Windels \n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at\n\n http://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n*/\n\nexport function createEnum(...values: string[]): Readonly<{}> {\n const obj = {};\n for (const value of values) {\n obj[value] = value;\n }\n return Object.freeze(obj);\n}\n","/*\nCopyright 2021 The Matrix.org Foundation C.I.C.\n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at\n\n http://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n*/\n\nfunction normalizeHomeserver(homeserver) {\n try {\n return new URL(homeserver).origin;\n } catch (err) {\n return new URL(`https://${homeserver}`).origin;\n }\n}\n\nasync function getWellKnownResponse(homeserver, request) {\n const requestOptions = {format: \"json\", timeout: 30000, method: \"GET\"};\n try {\n const wellKnownUrl = `${homeserver}/.well-known/matrix/client`;\n return await request(wellKnownUrl, requestOptions).response();\n } catch (err) {\n if (err.name === \"ConnectionError\") {\n // don't fail lookup on a ConnectionError,\n // there might be a missing CORS header on a 404 response or something,\n // which won't be a problem necessarily with homeserver requests later on ...\n return null;\n } else {\n throw err;\n }\n }\n}\n\nexport async function lookupHomeserver(homeserver, request) {\n homeserver = normalizeHomeserver(homeserver);\n const wellKnownResponse = await getWellKnownResponse(homeserver, request);\n if (wellKnownResponse && wellKnownResponse.status === 200) {\n const {body} = wellKnownResponse;\n const wellKnownHomeserver = body[\"m.homeserver\"]?.[\"base_url\"];\n if (typeof wellKnownHomeserver === \"string\") {\n homeserver = normalizeHomeserver(wellKnownHomeserver);\n }\n }\n return homeserver;\n}\n","/*\nCopyright 2020 Bruno Windels \nCopyright 2021 Daniel Fedorin \n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at\n\n http://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n*/\n\ntype Handler = (value?: T) => void;\n\nexport class EventEmitter {\n private _handlersByName: { [event in keyof T]?: Set> }\n\n constructor() {\n this._handlersByName = {};\n }\n\n emit(name: K, value?: T[K]): void {\n const handlers = this._handlersByName[name];\n if (handlers) {\n handlers.forEach(h => h(value));\n }\n }\n\n disposableOn(name: K, callback: Handler): () => void {\n this.on(name, callback);\n return () => {\n this.off(name, callback);\n }\n }\n\n on(name: K, callback: Handler): void {\n let handlers = this._handlersByName[name];\n if (!handlers) {\n this.onFirstSubscriptionAdded(name);\n this._handlersByName[name] = handlers = new Set();\n }\n handlers.add(callback);\n }\n\n off(name: K, callback: Handler): void {\n const handlers = this._handlersByName[name];\n if (handlers) {\n handlers.delete(callback);\n if (handlers.size === 0) {\n delete this._handlersByName[name];\n this.onLastSubscriptionRemoved(name);\n }\n }\n }\n\n onFirstSubscriptionAdded(name: K): void {}\n\n onLastSubscriptionRemoved(name: K): void {}\n}\n\nexport function tests() {\n return {\n test_on_off(assert) {\n let counter = 0;\n const e = new EventEmitter<{ change: never }>();\n const callback = () => counter += 1;\n e.on(\"change\", callback);\n e.emit(\"change\");\n e.off(\"change\", callback);\n e.emit(\"change\");\n assert.equal(counter, 1);\n },\n\n test_emit_value(assert) {\n let value = 0;\n const e = new EventEmitter<{ change: number }>();\n const callback = (v) => value = v;\n e.on(\"change\", callback);\n e.emit(\"change\", 5);\n e.off(\"change\", callback);\n assert.equal(value, 5);\n },\n\n test_double_on(assert) {\n let counter = 0;\n const e = new EventEmitter<{ change: never }>();\n const callback = () => counter += 1;\n e.on(\"change\", callback);\n e.on(\"change\", callback);\n e.emit(\"change\");\n e.off(\"change\", callback);\n assert.equal(counter, 1);\n }\n };\n}\n","/*\nCopyright 2020 The Matrix.org Foundation C.I.C.\n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at\n\n http://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n*/\n\nimport {EventEmitter} from \"../utils/EventEmitter\";\n\nexport interface IAbortable {\n abort();\n}\n\nexport type SetAbortableFn = (a: IAbortable) => typeof a;\nexport type SetProgressFn = (progress: P) => void;\ntype RunFn = (setAbortable: SetAbortableFn, setProgress: SetProgressFn) => T;\n\nexport class AbortableOperation extends EventEmitter<{change: keyof AbortableOperation}> implements IAbortable {\n public readonly result: T;\n private _abortable?: IAbortable;\n private _progress?: P;\n\n constructor(run: RunFn) {\n super();\n this._abortable = undefined;\n const setAbortable: SetAbortableFn = abortable => {\n this._abortable = abortable;\n return abortable;\n };\n this._progress = undefined;\n const setProgress: SetProgressFn = (progress: P) => {\n this._progress = progress;\n this.emit(\"change\", \"progress\");\n };\n this.result = run(setAbortable, setProgress);\n }\n\n get progress(): P | undefined {\n return this._progress;\n }\n\n abort() {\n this._abortable?.abort();\n this._abortable = undefined;\n }\n}\n","/*\nCopyright 2020 Bruno Windels \n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at\n\n http://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n*/\n\nexport class AbortError extends Error {\n get name(): string {\n return \"AbortError\";\n }\n}\n","/*\nCopyright 2020 Bruno Windels \n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at\n\n http://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n*/\n\n// we return undefined so you can reassign any member\n// that uses `member?: T` syntax in one statement.\nexport type SubscriptionHandle = () => undefined;\n\nexport abstract class BaseObservable {\n protected _handlers: Set = new Set();\n\n onSubscribeFirst(): void {\n\n }\n\n onUnsubscribeLast(): void {\n\n }\n\n subscribe(handler: T): SubscriptionHandle {\n this._handlers.add(handler);\n if (this._handlers.size === 1) {\n this.onSubscribeFirst();\n }\n return (): undefined => {\n return this.unsubscribe(handler);\n };\n }\n\n unsubscribe(handler?: T): undefined {\n if (handler) {\n this._handlers.delete(handler);\n if (this._handlers.size === 0) {\n this.onUnsubscribeLast();\n }\n }\n return undefined;\n }\n\n unsubscribeAll(): void {\n if (this._handlers.size !== 0) {\n this._handlers.clear();\n this.onUnsubscribeLast();\n }\n }\n\n get hasSubscriptions(): boolean {\n return this._handlers.size !== 0;\n }\n\n // Add iterator over handlers here\n}\n\n// eslint-disable-next-line @typescript-eslint/explicit-function-return-type\nexport function tests() {\n class Collection extends BaseObservable<{}> {\n firstSubscribeCalls: number = 0;\n firstUnsubscribeCalls: number = 0;\n\n onSubscribeFirst(): void { this.firstSubscribeCalls += 1; }\n onUnsubscribeLast(): void { this.firstUnsubscribeCalls += 1; }\n }\n\n return {\n test_unsubscribe(assert): void {\n const c = new Collection();\n const unsubscribe = c.subscribe({});\n unsubscribe();\n assert.equal(c.firstSubscribeCalls, 1);\n assert.equal(c.firstUnsubscribeCalls, 1);\n }\n };\n}\n","/*\nCopyright 2020 Bruno Windels \n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at\n\n http://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n*/\n\nimport {AbortError} from \"../../utils/error\";\nimport {BaseObservable} from \"../BaseObservable\";\nimport type {SubscriptionHandle} from \"../BaseObservable\";\nimport {FlatMapObservableValue} from \"./index\";\n\n// like an EventEmitter, but doesn't have an event type\nexport abstract class BaseObservableValue extends BaseObservable<(value: T) => void> {\n emit(argument: T): void {\n for (const h of this._handlers) {\n h(argument);\n }\n }\n\n abstract get(): T;\n\n waitFor(predicate: (value: T) => boolean): IWaitHandle {\n if (predicate(this.get())) {\n return new ResolvedWaitForHandle(Promise.resolve(this.get()));\n } else {\n return new WaitForHandle(this, predicate);\n }\n }\n\n flatMap(mapper: (value: T) => (BaseObservableValue | undefined)): BaseObservableValue {\n return new FlatMapObservableValue(this, mapper);\n }\n}\n\ninterface IWaitHandle {\n promise: Promise;\n dispose(): void;\n}\n\nclass WaitForHandle implements IWaitHandle {\n private _promise: Promise\n private _reject: ((reason?: any) => void) | null;\n private _subscription: (() => void) | null;\n\n constructor(observable: BaseObservableValue, predicate: (value: T) => boolean) {\n this._promise = new Promise((resolve, reject) => {\n this._reject = reject;\n this._subscription = observable.subscribe(v => {\n if (predicate(v)) {\n this._reject = null;\n resolve(v);\n this.dispose();\n }\n });\n });\n }\n\n get promise(): Promise {\n return this._promise;\n }\n\n dispose(): void {\n if (this._subscription) {\n this._subscription();\n this._subscription = null;\n }\n if (this._reject) {\n this._reject(new AbortError());\n this._reject = null;\n }\n }\n}\n\nclass ResolvedWaitForHandle implements IWaitHandle {\n constructor(public promise: Promise) {}\n dispose(): void {}\n}\n","/*\nCopyright 2022 The Matrix.org Foundation C.I.C.\n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at\n\n http://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n*/\n\nimport {BaseObservableValue} from \"./index\";\nimport {EventEmitter} from \"../../utils/EventEmitter\";\n\nexport class EventObservableValue> extends BaseObservableValue {\n private eventSubscription: () => void;\n\n constructor(\n private readonly value: V,\n private readonly eventName: keyof T\n ) {\n super();\n }\n\n onSubscribeFirst(): void {\n this.eventSubscription = this.value.disposableOn(this.eventName, () => {\n this.emit(this.value);\n });\n super.onSubscribeFirst();\n }\n\n onUnsubscribeLast(): void {\n this.eventSubscription!();\n super.onUnsubscribeLast();\n }\n\n get(): V {\n return this.value;\n }\n}\n","/*\nCopyright 2020 Bruno Windels \n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at\n\n http://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n*/\n\nimport {AbortError} from \"../../utils/error\";\nimport {BaseObservableValue} from \"./index\";\n\nexport class ObservableValue extends BaseObservableValue {\n private _value: T;\n\n constructor(initialValue: T) {\n super();\n this._value = initialValue;\n }\n\n get(): T {\n return this._value;\n }\n\n set(value: T): void {\n if (value !== this._value) {\n this._value = value;\n this.emit(this._value);\n }\n }\n}\n\nexport function tests() {\n return {\n \"set emits an update\": (assert): void => {\n const a = new ObservableValue(0);\n let fired = false;\n const subscription = a.subscribe(v => {\n fired = true;\n assert.strictEqual(v, 5);\n });\n a.set(5);\n assert(fired);\n subscription();\n },\n \"set doesn't emit if value hasn't changed\": (assert): void => {\n const a = new ObservableValue(5);\n let fired = false;\n const subscription = a.subscribe(() => {\n fired = true;\n });\n a.set(5);\n a.set(5);\n assert(!fired);\n subscription();\n },\n \"waitFor promise resolves on matching update\": async (assert): Promise => {\n const a = new ObservableValue(5);\n const handle = a.waitFor(v => v === 6);\n await Promise.resolve().then(() => {\n a.set(6);\n });\n await handle.promise;\n assert.strictEqual(a.get(), 6);\n },\n \"waitFor promise rejects when disposed\": async (assert): Promise => {\n const a = new ObservableValue(0);\n const handle = a.waitFor(() => false);\n await Promise.resolve().then(() => {\n handle.dispose();\n });\n await assert.rejects(handle.promise, AbortError);\n },\n };\n}\n","/*\nCopyright 2020 Bruno Windels \n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at\n\n http://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n*/\n\nimport {BaseObservableValue} from \"./index\";\nimport type {SubscriptionHandle} from \"../BaseObservable\";\n\nexport class FlatMapObservableValue extends BaseObservableValue {\n private sourceSubscription?: SubscriptionHandle;\n private targetSubscription?: SubscriptionHandle;\n\n constructor(\n private readonly source: BaseObservableValue,\n private readonly mapper: (value: P) => (BaseObservableValue | undefined)\n ) {\n super();\n }\n\n onUnsubscribeLast(): void {\n super.onUnsubscribeLast();\n this.sourceSubscription = this.sourceSubscription!();\n if (this.targetSubscription) {\n this.targetSubscription = this.targetSubscription();\n }\n }\n\n onSubscribeFirst(): void {\n super.onSubscribeFirst();\n this.sourceSubscription = this.source.subscribe(() => {\n this.updateTargetSubscription();\n this.emit(this.get());\n });\n this.updateTargetSubscription();\n }\n\n private updateTargetSubscription(): void {\n const sourceValue = this.source.get();\n if (sourceValue) {\n const target = this.mapper(sourceValue);\n if (target) {\n if (!this.targetSubscription) {\n this.targetSubscription = target.subscribe(() => this.emit(this.get()));\n }\n return;\n }\n }\n // if no sourceValue or target\n if (this.targetSubscription) {\n this.targetSubscription = this.targetSubscription();\n }\n }\n\n get(): C | undefined {\n const sourceValue = this.source.get();\n if (!sourceValue) {\n return undefined;\n }\n const mapped = this.mapper(sourceValue);\n return mapped?.get();\n }\n}\n\nimport {ObservableValue} from \"./ObservableValue\";\n\nexport function tests() {\n return {\n \"flatMap.get\": (assert): void => {\n const a = new ObservableValue}>(undefined);\n const countProxy = a.flatMap(a => a!.count);\n assert.strictEqual(countProxy.get(), undefined);\n const count = new ObservableValue(0);\n a.set({count});\n assert.strictEqual(countProxy.get(), 0);\n },\n \"flatMap update from source\": (assert): void => {\n const a = new ObservableValue}>(undefined);\n const updates: (number | undefined)[] = [];\n a.flatMap(a => a!.count).subscribe(count => {\n updates.push(count);\n });\n const count = new ObservableValue(0);\n a.set({count});\n assert.deepEqual(updates, [0]);\n },\n \"flatMap update from target\": (assert): void => {\n const a = new ObservableValue}>(undefined);\n const updates: (number | undefined)[] = [];\n a.flatMap(a => a!.count).subscribe(count => {\n updates.push(count);\n });\n const count = new ObservableValue(0);\n a.set({count});\n count.set(5);\n assert.deepEqual(updates, [0, 5]);\n }\n };\n}\n","/*\nCopyright 2020 Bruno Windels \n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at\n\n http://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n*/\n\nimport {BaseObservableValue} from \"./index\";\nimport {BaseObservableMap, IMapObserver} from \"../map/BaseObservableMap\";\nimport {SubscriptionHandle} from \"../BaseObservable\";\n\nfunction pickLowestKey(currentKey: K, newKey: K): boolean {\n return newKey < currentKey;\n}\n\nexport class PickMapObservableValue extends BaseObservableValue implements IMapObserver{\n\n private key?: K;\n private mapSubscription?: SubscriptionHandle;\n\n constructor(\n private readonly map: BaseObservableMap,\n private readonly pickKey: (currentKey: K, newKey: K) => boolean = pickLowestKey\n ) {\n super();\n }\n\n private updateKey(newKey: K): boolean {\n if (this.key === undefined || this.pickKey(this.key, newKey)) {\n this.key = newKey;\n return true;\n }\n return false;\n }\n\n onReset(): void {\n this.key = undefined;\n this.emit(this.get());\n }\n\n onAdd(key: K, value:V): void {\n if (this.updateKey(key)) {\n this.emit(this.get());\n }\n }\n\n onUpdate(key: K, value: V, params: any): void {\n this.emit(this.get());\n }\n\n onRemove(key: K, value: V): void {\n if (key === this.key) {\n this.key = undefined;\n // try to see if there is another key that fullfills pickKey\n for (const [key] of this.map) {\n this.updateKey(key);\n }\n this.emit(this.get());\n }\n }\n\n onSubscribeFirst(): void {\n this.mapSubscription = this.map.subscribe(this);\n for (const [key] of this.map) {\n this.updateKey(key);\n }\n }\n\n onUnsubscribeLast(): void {\n this.mapSubscription!();\n this.key = undefined;\n }\n\n get(): V | undefined {\n if (this.key !== undefined) {\n return this.map.get(this.key);\n }\n return undefined;\n }\n}\n","/*\nCopyright 2020 Bruno Windels \n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at\n\n http://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n*/\n\nimport {ObservableValue} from \"./index\";\n\nexport class RetainedObservableValue extends ObservableValue {\n\n constructor(initialValue: T, private freeCallback: () => void, private startCallback: () => void = () => {}) {\n super(initialValue);\n }\n\n onSubscribeFirst(): void {\n this.startCallback();\n }\n\n onUnsubscribeLast(): void {\n super.onUnsubscribeLast();\n this.freeCallback();\n }\n}\n","/*\nCopyright 2020 Bruno Windels \n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at\n\n http://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n*/\n\nimport {BaseObservable} from \"../BaseObservable\";\n\nexport interface IListObserver {\n onReset(list: BaseObservableList): void;\n onAdd(index: number, value:T, list: BaseObservableList): void;\n onUpdate(index: number, value: T, params: any, list: BaseObservableList): void;\n onRemove(index: number, value: T, list: BaseObservableList): void\n onMove(from: number, to: number, value: T, list: BaseObservableList): void\n}\n\nexport function defaultObserverWith(overrides: { [key in keyof IListObserver]?: IListObserver[key] }): IListObserver {\n const defaults = {\n onReset(): void {},\n onAdd(): void {},\n onUpdate(): void {},\n onRemove(): void {},\n onMove(): void {},\n };\n return Object.assign(defaults, overrides);\n}\n\nexport abstract class BaseObservableList extends BaseObservable> implements Iterable {\n emitReset(): void {\n for(let h of this._handlers) {\n h.onReset(this);\n }\n }\n // we need batch events, mostly on index based collection though?\n // maybe we should get started without?\n emitAdd(index: number, value: T): void {\n for(let h of this._handlers) {\n h.onAdd(index, value, this);\n }\n }\n\n emitUpdate(index: number, value: T, params?: any): void {\n for(let h of this._handlers) {\n h.onUpdate(index, value, params, this);\n }\n }\n\n emitRemove(index: number, value: T): void {\n for(let h of this._handlers) {\n h.onRemove(index, value, this);\n }\n }\n\n // toIdx assumes the item has already\n // been removed from its fromIdx\n emitMove(fromIdx: number, toIdx: number, value: T): void {\n for(let h of this._handlers) {\n h.onMove(fromIdx, toIdx, value, this);\n }\n }\n\n abstract [Symbol.iterator](): Iterator;\n abstract get length(): number;\n}\n","/*\nCopyright 2020 Bruno Windels \n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at\n\n http://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n*/\n\n/**\n * @license\n * Based off baseSortedIndex function in Lodash \n * Copyright JS Foundation and other contributors \n * Released under MIT license \n * Based on Underscore.js 1.8.3 \n * Copyright Jeremy Ashkenas, DocumentCloud and Investigative Reporters & Editors\n */\nexport function sortedIndex(array: T[], value: T, comparator: (x:T, y:T) => number): number {\n let low = 0;\n let high = array.length;\n\n while (low < high) {\n let mid = (low + high) >>> 1;\n let cmpResult = comparator(value, array[mid]);\n\n if (cmpResult > 0) {\n low = mid + 1;\n } else if (cmpResult < 0) {\n high = mid;\n } else {\n low = high = mid;\n }\n }\n return high;\n}\n","/*\nCopyright 2020 Bruno Windels \n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at\n\n http://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n*/\n\nimport {BaseObservableList} from \"./BaseObservableList\";\n\nexport class ObservableArray extends BaseObservableList {\n private _items: T[];\n\n constructor(initialValues: T[] = []) {\n super();\n this._items = initialValues;\n }\n\n append(item: T): void {\n this._items.push(item);\n this.emitAdd(this._items.length - 1, item);\n }\n\n remove(idx: number): void {\n const [item] = this._items.splice(idx, 1);\n this.emitRemove(idx, item);\n }\n\n insertMany(idx: number, items: T[]): void {\n for(let item of items) {\n this.insert(idx, item);\n idx += 1;\n }\n }\n\n insert(idx: number, item: T): void {\n this._items.splice(idx, 0, item);\n this.emitAdd(idx, item);\n }\n\n move(fromIdx: number, toIdx: number): void {\n if (fromIdx < this._items.length && toIdx < this._items.length) {\n const [item] = this._items.splice(fromIdx, 1);\n this._items.splice(toIdx, 0, item);\n this.emitMove(fromIdx, toIdx, item);\n }\n }\n\n update(idx: number, item: T, params: any = null): void {\n if (idx < this._items.length) {\n this._items[idx] = item;\n this.emitUpdate(idx, item, params);\n }\n }\n\n get array(): Readonly {\n return this._items;\n }\n\n at(idx: number): T | undefined {\n if (this._items && idx >= 0 && idx < this._items.length) {\n return this._items[idx];\n }\n }\n\n get length(): number {\n return this._items.length;\n }\n\n [Symbol.iterator](): IterableIterator {\n return this._items.values();\n }\n}\n","/*\nCopyright 2020 Bruno Windels \nCopyright 2021 The Matrix.org Foundation C.I.C.\n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at\n\n http://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n*/\nimport {BaseObservableList} from \"./BaseObservableList\";\n\n/* inline update of item in collection backed by array, without replacing the preexising item */\nexport function findAndUpdateInArray(\n predicate: (value: T) => boolean,\n array: T[],\n observable: BaseObservableList,\n updater: (value: T) => any | false\n): boolean {\n const index = array.findIndex(predicate);\n if (index !== -1) {\n const value = array[index];\n // allow bailing out of sending an emit if updater determined its not needed\n const params = updater(value);\n if (params !== false) {\n observable.emitUpdate(index, value, params);\n }\n // found\n return true;\n }\n return false;\n}\n","/*\nCopyright 2020 Bruno Windels \n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at\n\n http://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n*/\n\nimport {BaseObservableList} from \"./BaseObservableList\";\nimport {sortedIndex} from \"../../utils/sortedIndex\";\nimport {findAndUpdateInArray} from \"./common\";\n\nexport class SortedArray extends BaseObservableList {\n private _comparator: (left: T, right: T) => number;\n private _items: T[] = [];\n\n constructor(comparator: (left: T, right: T) => number) {\n super();\n this._comparator = comparator;\n }\n\n setManyUnsorted(items: T[]): void {\n this.setManySorted(items);\n }\n\n setManySorted(items: T[]): void {\n // TODO: we can make this way faster by only looking up the first and last key,\n // and merging whatever is inbetween with items\n // if items is not sorted, 💩🌀 will follow!\n // should we check?\n // Also, once bulk events are supported in collections,\n // we can do a bulk add event here probably if there are no updates\n // BAD CODE!\n for(let item of items) {\n this.set(item);\n }\n }\n\n findAndUpdate(predicate: (value: T) => boolean, updater: (value: T) => any | false): boolean {\n return findAndUpdateInArray(predicate, this._items, this, updater);\n }\n\n getAndUpdate(item: T, updater: (existing: T, item: T) => any, updateParams: any = null): void {\n const idx = this.indexOf(item);\n if (idx !== -1) {\n const existingItem = this._items[idx];\n const newItem = updater(existingItem, item);\n this._items[idx] = newItem;\n this.emitUpdate(idx, newItem, updateParams);\n }\n }\n\n update(item: T, updateParams: any = null): void {\n const idx = this.indexOf(item);\n if (idx !== -1) {\n this._items[idx] = item;\n this.emitUpdate(idx, item, updateParams);\n }\n }\n\n indexOf(item: T): number {\n const idx = sortedIndex(this._items, item, this._comparator);\n if (idx < this._items.length && this._comparator(this._items[idx], item) === 0) {\n return idx;\n } else {\n return -1;\n }\n }\n\n _getNext(item: T): T | undefined {\n let idx = sortedIndex(this._items, item, this._comparator);\n while(idx < this._items.length && this._comparator(this._items[idx], item) <= 0) {\n idx += 1;\n }\n return this.get(idx);\n }\n\n set(item: T, updateParams: any = null): void {\n const idx = sortedIndex(this._items, item, this._comparator);\n if (idx >= this._items.length || this._comparator(this._items[idx], item) !== 0) {\n this._items.splice(idx, 0, item);\n this.emitAdd(idx, item);\n } else {\n this._items[idx] = item;\n this.emitUpdate(idx, item, updateParams);\n }\n }\n\n get(idx: number): T | undefined {\n return this._items[idx];\n }\n\n remove(idx: number): void {\n const item = this._items[idx];\n this._items.splice(idx, 1);\n this.emitRemove(idx, item);\n }\n\n get array(): T[] {\n return this._items;\n }\n\n get length(): number {\n return this._items.length;\n }\n\n [Symbol.iterator](): Iterator {\n return new Iterator(this);\n }\n}\n\n// iterator that works even if the current value is removed while iterating\nclass Iterator {\n private _sortedArray: SortedArray;\n private _current: T | null | undefined;\n private _consumed: boolean = false;\n\n constructor(sortedArray: SortedArray) {\n this._sortedArray = sortedArray;\n this._current = null;\n }\n\n next(): IteratorResult {\n if (this._consumed) {\n return {value: undefined, done: true};\n }\n this._current = this._current? this._sortedArray._getNext(this._current): this._sortedArray.get(0);\n if (!this._current) {\n this._consumed = true;\n }\n return { value: this._current, done: this._consumed } as IteratorResult;\n }\n}\n\n// eslint-disable-next-line @typescript-eslint/explicit-function-return-type\nexport function tests() {\n return {\n \"setManyUnsorted\": (assert): void => {\n const sa = new SortedArray((a, b) => a.localeCompare(b));\n sa.setManyUnsorted([\"b\", \"a\", \"c\"]);\n assert.equal(sa.length, 3);\n assert.equal(sa.get(0), \"a\");\n assert.equal(sa.get(1), \"b\");\n assert.equal(sa.get(2), \"c\");\n },\n \"_getNext\": (assert): void => {\n const sa = new SortedArray((a, b) => a.localeCompare(b));\n sa.setManyUnsorted([\"b\", \"a\", \"f\"]);\n assert.equal(sa._getNext(\"a\"), \"b\");\n assert.equal(sa._getNext(\"b\"), \"f\");\n // also finds the next if the value is not in the collection\n assert.equal(sa._getNext(\"c\"), \"f\");\n assert.equal(sa._getNext(\"f\"), undefined);\n },\n \"iterator with removals\": (assert): void => {\n const queue = new SortedArray<{idx: number}>((a, b) => a.idx - b.idx);\n queue.setManyUnsorted([{idx: 5}, {idx: 3}, {idx: 1}, {idx: 4}, {idx: 2}]);\n const it = queue[Symbol.iterator]();\n assert.equal(it.next().value.idx, 1);\n assert.equal(it.next().value.idx, 2);\n queue.remove(1);\n assert.equal(it.next().value.idx, 3);\n queue.remove(1);\n assert.equal(it.next().value.idx, 4);\n queue.remove(1);\n assert.equal(it.next().value.idx, 5);\n queue.remove(1);\n assert.equal(it.next().done, true);\n // check done persists\n assert.equal(it.next().done, true);\n }\n };\n}\n","/*\nCopyright 2020 Bruno Windels \nCopyright 2021 The Matrix.org Foundation C.I.C.\n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at\n\n http://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n*/\n\nimport {BaseObservableList} from \"./BaseObservableList\";\nimport {findAndUpdateInArray} from \"./common\";\n\nexport type Mapper = (value: F) => T\nexport type Updater = (mappedValue: T, params: any, value: F) => void;\n\nexport class BaseMappedList extends BaseObservableList {\n protected _sourceList: BaseObservableList;\n protected _sourceUnsubscribe: (() => void) | null = null;\n _mapper: Mapper;\n _updater?: Updater;\n _removeCallback?: (value: T) => void;\n _mappedValues: T[] | null = null;\n\n constructor(sourceList: BaseObservableList, mapper: Mapper, updater?: Updater, removeCallback?: (value: T) => void) {\n super();\n this._sourceList = sourceList;\n this._mapper = mapper;\n this._updater = updater;\n this._removeCallback = removeCallback;\n }\n\n findAndUpdate(predicate: (value: T) => boolean, updater: (value: T) => any | false): boolean {\n return findAndUpdateInArray(predicate, this._mappedValues!, this, updater);\n }\n\n get length(): number {\n return this._mappedValues!.length;\n }\n\n [Symbol.iterator](): IterableIterator {\n return this._mappedValues!.values();\n }\n}\n\nexport function runAdd(list: BaseMappedList, index: number, mappedValue: T): void {\n list._mappedValues!.splice(index, 0, mappedValue);\n list.emitAdd(index, mappedValue);\n}\n\nexport function runUpdate(list: BaseMappedList, index: number, value: F, params: any): void {\n const mappedValue = list._mappedValues![index];\n if (list._updater) {\n list._updater(mappedValue, params, value);\n }\n list.emitUpdate(index, mappedValue, params);\n}\n\nexport function runRemove(list: BaseMappedList, index: number): void {\n const mappedValue = list._mappedValues![index];\n list._mappedValues!.splice(index, 1);\n if (list._removeCallback) {\n list._removeCallback(mappedValue);\n }\n list.emitRemove(index, mappedValue);\n}\n\nexport function runMove(list: BaseMappedList, fromIdx: number, toIdx: number): void {\n const mappedValue = list._mappedValues![fromIdx];\n list._mappedValues!.splice(fromIdx, 1);\n list._mappedValues!.splice(toIdx, 0, mappedValue);\n list.emitMove(fromIdx, toIdx, mappedValue);\n}\n\nexport function runReset(list: BaseMappedList): void {\n list._mappedValues = [];\n list.emitReset();\n}\n","/*\nCopyright 2020 Bruno Windels \nCopyright 2021 The Matrix.org Foundation C.I.C.\n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at\n\n http://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n*/\n\nimport {IListObserver} from \"./BaseObservableList\";\nimport {BaseMappedList, runAdd, runUpdate, runRemove, runMove, runReset} from \"./BaseMappedList\";\n\nexport class AsyncMappedList extends BaseMappedList> implements IListObserver {\n private _eventQueue: AsyncEvent[] | null = null;\n private _flushing: boolean = false;\n\n onSubscribeFirst(): void {\n this._sourceUnsubscribe = this._sourceList.subscribe(this);\n this._eventQueue = [];\n this._mappedValues = [];\n let idx = 0;\n for (const item of this._sourceList) {\n this._eventQueue.push(new AddEvent(idx, item));\n idx += 1;\n }\n void this._flush();\n }\n\n async _flush(): Promise {\n if (this._flushing) {\n return;\n }\n this._flushing = true;\n try {\n while (this._eventQueue!.length) {\n const event = this._eventQueue!.shift();\n await event!.run(this);\n }\n } finally {\n this._flushing = false;\n }\n }\n\n onReset(): void {\n if (this._eventQueue) {\n this._eventQueue.push(new ResetEvent());\n void this._flush();\n }\n }\n\n onAdd(index: number, value: F): void {\n if (this._eventQueue) {\n this._eventQueue.push(new AddEvent(index, value));\n void this._flush();\n }\n }\n\n onUpdate(index: number, value: F, params: any): void {\n if (this._eventQueue) {\n this._eventQueue.push(new UpdateEvent(index, value, params));\n void this._flush();\n }\n }\n\n onRemove(index: number): void {\n if (this._eventQueue) {\n this._eventQueue.push(new RemoveEvent(index));\n void this._flush();\n }\n }\n\n onMove(fromIdx: number, toIdx: number): void {\n if (this._eventQueue) {\n this._eventQueue.push(new MoveEvent(fromIdx, toIdx));\n void this._flush();\n }\n }\n\n onUnsubscribeLast(): void {\n this._sourceUnsubscribe!();\n this._eventQueue = null;\n this._mappedValues = null;\n }\n}\n\ntype AsyncEvent = AddEvent | UpdateEvent | RemoveEvent | MoveEvent | ResetEvent\n\nclass AddEvent {\n constructor(public index: number, public value: F) {}\n\n async run(list: AsyncMappedList): Promise {\n const mappedValue = await list._mapper(this.value);\n runAdd(list, this.index, mappedValue);\n }\n}\n\nclass UpdateEvent {\n constructor(public index: number, public value: F, public params: any) {}\n\n async run(list: AsyncMappedList): Promise {\n runUpdate(list, this.index, this.value, this.params);\n }\n}\n\nclass RemoveEvent {\n constructor(public index: number) {}\n\n async run(list: AsyncMappedList): Promise {\n runRemove(list, this.index);\n }\n}\n\nclass MoveEvent {\n constructor(public fromIdx: number, public toIdx: number) {}\n\n async run(list: AsyncMappedList): Promise {\n runMove(list, this.fromIdx, this.toIdx);\n }\n}\n\nclass ResetEvent {\n async run(list: AsyncMappedList): Promise {\n runReset(list);\n }\n}\n\nimport {ObservableArray} from \"./ObservableArray\";\nimport {ListObserver} from \"../../mocks/ListObserver.js\";\n\n\n// eslint-disable-next-line @typescript-eslint/explicit-function-return-type\nexport function tests() {\n return {\n \"events are emitted in order\": async (assert): Promise