From b98c9de82e14f4c963318f1b7dfc9e588d4baeee Mon Sep 17 00:00:00 2001 From: Yuki Ito Date: Fri, 30 Jul 2021 15:58:40 +0900 Subject: [PATCH] 2021.1.3 --- dist/sora.js | 23 +++++++++++++++++------ dist/sora.min.js | 4 ++-- dist/sora.mjs | 23 +++++++++++++++++------ lerna.json | 2 +- package.json | 2 +- packages/sdk/package.json | 2 +- 6 files changed, 39 insertions(+), 17 deletions(-) diff --git a/dist/sora.js b/dist/sora.js index 6794223f..de20e2f8 100644 --- a/dist/sora.js +++ b/dist/sora.js @@ -1,7 +1,7 @@ /** * @sora/sdk * undefined - * @version: 2021.1.2 + * @version: 2021.1.3 * @author: Shiguredo Inc. * @license: Apache-2.0 **/ @@ -1599,7 +1599,7 @@ } const message = { type: "connect", - sora_client: "Sora JavaScript SDK 2021.1.2", + sora_client: "Sora JavaScript SDK 2021.1.3", environment: window.navigator.userAgent, role: role, channel_id: channelId, @@ -2256,9 +2256,13 @@ closeDataChannels(); resolve(); }; - // onclose がすべて発火したかどうかを拾うための Promsie を生成する + // すべての DataChannel の readyState が "closed" になったことを確認する Promsie を生成する const p = () => { return new Promise((res, rej) => { + if (dataChannel.readyState === "closed") { + res(); + return; + } dataChannel.onerror = () => { rej(); }; @@ -2266,7 +2270,9 @@ const channel = event.currentTarget; this.writeDataChannelTimelineLog("onclose", channel); this.trace("CLOSE DATA CHANNEL", channel.label); - res(); + if (channel.readyState === "closed") { + res(); + } }; }); }; @@ -2370,7 +2376,12 @@ } this.initializeConnection(); if (event) { - this.writeSoraTimelineLog("disconnect-normal", event); + if (event.type === "abend") { + this.writeSoraTimelineLog("disconnect-abend", event); + } + else if (event.type === "normal") { + this.writeSoraTimelineLog("disconnect-normal", event); + } this.callbacks.disconnect(event); } } @@ -3433,7 +3444,7 @@ return new SoraConnection(signalingUrl, debug); }, version: function () { - return "2021.1.2"; + return "2021.1.3"; }, helpers: { applyMediaStreamConstraints, diff --git a/dist/sora.min.js b/dist/sora.min.js index 1558941b..04f629b2 100644 --- a/dist/sora.min.js +++ b/dist/sora.min.js @@ -1,8 +1,8 @@ /** * @sora/sdk * undefined - * @version: 2021.1.2 + * @version: 2021.1.3 * @author: Shiguredo Inc. * @license: Apache-2.0 - **/(function(e,n){"object"==typeof exports&&"undefined"!=typeof module?module.exports=n():"function"==typeof define&&define.amd?define(n):(e="undefined"==typeof globalThis?e||self:globalThis,e.Sora=n())})(this,function(){'use strict';var n=Math.min,g=Math.ceil,t=Math.max;function a(){(()=>{if("undefined"!=typeof global);else if("undefined"!=typeof window)window.global=window;else if("undefined"!=typeof self)self.global=self;else throw new Error("cannot export Go (neither global, window nor self is defined)");if(global.require||"undefined"==typeof require||(global.require=require),!global.fs&&global.require){const e=require("fs");0!==Object.keys(e)&&(global.fs=e)}const e=()=>{const e=new Error("not implemented");return e.code="ENOSYS",e};if(!global.fs){let n="";global.fs={constants:{O_WRONLY:-1,O_RDWR:-1,O_CREAT:-1,O_TRUNC:-1,O_APPEND:-1,O_EXCL:-1},writeSync(e,g){n+=i.decode(g);const t=n.lastIndexOf("\n");return-1!=t&&(console.log(n.substr(0,t)),n=n.substr(t+1)),g.length},write(i,g,t,a,o,l){if(0!==t||a!==g.length||null!==o)return void l(e());const c=this.writeSync(i,g);l(null,c)},chmod(n,i,g){g(e())},chown(n,i,g,t){t(e())},close(n,i){i(e())},fchmod(n,i,g){g(e())},fchown(n,i,g,t){t(e())},fstat(n,i){i(e())},fsync(e,n){n(null)},ftruncate(n,i,g){g(e())},lchown(n,i,g,t){t(e())},link(n,i,g){g(e())},lstat(n,i){i(e())},mkdir(n,i,g){g(e())},open(n,i,g,t){t(e())},read(n,i,g,t,a,o){o(e())},readdir(n,i){i(e())},readlink(n,i){i(e())},rename(n,i,g){g(e())},rmdir(n,i){i(e())},stat(n,i){i(e())},symlink(n,i,g){g(e())},truncate(n,i,g){g(e())},unlink(n,i){i(e())},utimes(n,i,g,t){t(e())}}}if(global.process||(global.process={getuid(){return-1},getgid(){return-1},geteuid(){return-1},getegid(){return-1},getgroups(){throw e()},pid:-1,ppid:-1,umask(){throw e()},cwd(){throw e()},chdir(){throw e()}}),!global.crypto){const e=require("crypto");global.crypto={getRandomValues(n){e.randomFillSync(n)}}}global.performance||(global.performance={now(){const[e,n]=process.hrtime();return 1e3*e+n/1e6}}),global.TextEncoder||(global.TextEncoder=require("util").TextEncoder),global.TextDecoder||(global.TextDecoder=require("util").TextDecoder);const n=new TextEncoder("utf-8"),i=new TextDecoder("utf-8");if(global.Go=class{constructor(){this.argv=["js"],this.env={},this.exit=e=>{0!==e&&console.warn("exit code:",e)},this._exitPromise=new Promise(e=>{this._resolveExitPromise=e}),this._pendingEvent=null,this._scheduledTimeouts=new Map,this._nextCallbackTimeoutID=1;const e=(e,n)=>{var i=Math.floor;this.mem.setUint32(e+0,n,!0),this.mem.setUint32(e+4,i(n/4294967296),!0)},g=e=>{const n=this.mem.getUint32(e+0,!0),i=this.mem.getInt32(e+4,!0);return n+4294967296*i},t=e=>{const n=this.mem.getFloat64(e,!0);if(0!==n){if(!isNaN(n))return n;const i=this.mem.getUint32(e,!0);return this._values[i]}},a=(e,n)=>{if("number"==typeof n&&0!==n)return isNaN(n)?(this.mem.setUint32(e+4,2146959360,!0),void this.mem.setUint32(e,0,!0)):void this.mem.setFloat64(e,n,!0);if(void 0===n)return void this.mem.setFloat64(e,0,!0);let i=this._ids.get(n);void 0===i&&(i=this._idPool.pop(),void 0===i&&(i=this._values.length),this._values[i]=n,this._goRefCounts[i]=0,this._ids.set(n,i)),this._goRefCounts[i]++;let g=0;switch(typeof n){case"object":null!==n&&(g=1);break;case"string":g=2;break;case"symbol":g=3;break;case"function":g=4;}this.mem.setUint32(e+4,2146959360|g,!0),this.mem.setUint32(e,i,!0)},o=e=>{const n=g(e+0),i=g(e+8);return new Uint8Array(this._inst.exports.mem.buffer,n,i)},l=e=>{const n=g(e+0),o=g(e+8),l=Array(o);for(let g=0;g{const n=g(e+0),t=g(e+8);return i.decode(new DataView(this._inst.exports.mem.buffer,n,t))},d=Date.now()-performance.now();this.importObject={go:{"runtime.wasmExit":e=>{const n=this.mem.getInt32(e+8,!0);this.exited=!0,delete this._inst,delete this._values,delete this._goRefCounts,delete this._ids,delete this._idPool,this.exit(n)},"runtime.wasmWrite":e=>{const i=g(e+8),t=g(e+16),a=this.mem.getInt32(e+24,!0);fs.writeSync(i,new Uint8Array(this._inst.exports.mem.buffer,t,a))},"runtime.resetMemoryDataView":()=>{this.mem=new DataView(this._inst.exports.mem.buffer)},"runtime.nanotime1":n=>{e(n+8,1e6*(d+performance.now()))},"runtime.walltime1":n=>{const i=new Date().getTime();e(n+8,i/1e3),this.mem.setInt32(n+16,1e6*(i%1e3),!0)},"runtime.scheduleTimeoutEvent":e=>{const n=this._nextCallbackTimeoutID;this._nextCallbackTimeoutID++,this._scheduledTimeouts.set(n,setTimeout(()=>{for(this._resume();this._scheduledTimeouts.has(n);)console.warn("scheduleTimeoutEvent: missed timeout event"),this._resume()},g(e+8)+1)),this.mem.setInt32(e+16,n,!0)},"runtime.clearTimeoutEvent":e=>{const n=this.mem.getInt32(e+8,!0);clearTimeout(this._scheduledTimeouts.get(n)),this._scheduledTimeouts.delete(n)},"runtime.getRandomData":e=>{crypto.getRandomValues(o(e+8))},"syscall/js.finalizeRef":e=>{const n=this.mem.getUint32(e+8,!0);if(this._goRefCounts[n]--,0===this._goRefCounts[n]){const e=this._values[n];this._values[n]=null,this._ids.delete(e),this._idPool.push(n)}},"syscall/js.stringVal":e=>{a(e+24,c(e+8))},"syscall/js.valueGet":e=>{const n=Reflect.get(t(e+8),c(e+16));e=this._inst.exports.getsp(),a(e+32,n)},"syscall/js.valueSet":e=>{Reflect.set(t(e+8),c(e+16),t(e+32))},"syscall/js.valueDelete":e=>{Reflect.deleteProperty(t(e+8),c(e+16))},"syscall/js.valueIndex":e=>{a(e+24,Reflect.get(t(e+8),g(e+16)))},"syscall/js.valueSetIndex":e=>{Reflect.set(t(e+8),g(e+16),t(e+24))},"syscall/js.valueCall":e=>{try{const n=t(e+8),i=Reflect.get(n,c(e+16)),g=l(e+32),o=Reflect.apply(i,n,g);e=this._inst.exports.getsp(),a(e+56,o),this.mem.setUint8(e+64,1)}catch(n){a(e+56,n),this.mem.setUint8(e+64,0)}},"syscall/js.valueInvoke":e=>{try{const n=t(e+8),i=l(e+16),g=Reflect.apply(n,void 0,i);e=this._inst.exports.getsp(),a(e+40,g),this.mem.setUint8(e+48,1)}catch(n){a(e+40,n),this.mem.setUint8(e+48,0)}},"syscall/js.valueNew":e=>{try{const n=t(e+8),i=l(e+16),g=Reflect.construct(n,i);e=this._inst.exports.getsp(),a(e+40,g),this.mem.setUint8(e+48,1)}catch(n){a(e+40,n),this.mem.setUint8(e+48,0)}},"syscall/js.valueLength":n=>{e(n+16,parseInt(t(n+8).length))},"syscall/js.valuePrepareString":i=>{const g=n.encode(t(i+8)+"");a(i+16,g),e(i+24,g.length)},"syscall/js.valueLoadString":e=>{const n=t(e+8);o(e+16).set(n)},"syscall/js.valueInstanceOf":e=>{this.mem.setUint8(e+24,t(e+8)instanceof t(e+16)?1:0)},"syscall/js.copyBytesToGo":n=>{const i=o(n+8),g=t(n+32);if(!(g instanceof Uint8Array||g instanceof Uint8ClampedArray))return void this.mem.setUint8(n+48,0);const a=g.subarray(0,i.length);i.set(a),e(n+40,a.length),this.mem.setUint8(n+48,1)},"syscall/js.copyBytesToJS":n=>{const i=t(n+8),g=o(n+16);if(!(i instanceof Uint8Array||i instanceof Uint8ClampedArray))return void this.mem.setUint8(n+48,0);const a=g.subarray(0,i.length);i.set(a),e(n+40,a.length),this.mem.setUint8(n+48,1)},debug:e=>{console.log(e)}}}}async run(e){this._inst=e,this.mem=new DataView(this._inst.exports.mem.buffer),this._values=[NaN,0,null,!0,!1,global,this],this._goRefCounts=Array(this._values.length).fill(1/0),this._ids=new Map([[0,1],[null,2],[!0,3],[!1,4],[global,5],[this,6]]),this._idPool=[],this.exited=!1;let i=4096;const g=e=>{const g=i,t=n.encode(e+"\0");return new Uint8Array(this.mem.buffer,i,t.length).set(t),i+=t.length,0!=i%8&&(i+=8-i%8),g},t=this.argv.length,a=[];this.argv.forEach(e=>{a.push(g(e))}),a.push(0);const o=Object.keys(this.env).sort();o.forEach(e=>{a.push(g(`${e}=${this.env[e]}`))}),a.push(0);const l=i;a.forEach(e=>{this.mem.setUint32(i,e,!0),this.mem.setUint32(i+4,0,!0),i+=8}),this._inst.exports.run(t,l),this.exited&&this._resolveExitPromise(),await this._exitPromise}_resume(){if(this.exited)throw new Error("Go program has already exited");this._inst.exports.resume(),this.exited&&this._resolveExitPromise()}_makeFuncWrapper(e){const n=this;return function(){const i={id:e,this:this,args:arguments};return n._pendingEvent=i,n._resume(),i.result}}},global.require&&global.require.main===module&&global.process&&global.process.versions&&!global.process.versions.electron){3>process.argv.length&&(console.error("usage: go_js_wasm_exec [wasm binary] [arguments]"),process.exit(1));const e=new Go;e.argv=process.argv.slice(2),e.env=Object.assign({TMPDIR:require("os").tmpdir()},process.env),e.exit=process.exit,WebAssembly.instantiate(fs.readFileSync(process.argv[2]),e.importObject).then(n=>(process.on("exit",n=>{0!==n||e.exited||(e._pendingEvent={id:0},e._resume())}),e.run(n.instance))).catch(e=>{console.error(e),process.exit(1)})}})()}function o(e,n){n||(n={});var i=ce();i.p(e);var g=de(e,n,2,4);return se(g,n),Ce(g,g.length-4,i.d()),g}function l(e,n){return z((Ie(e),e.subarray(2,-4)),n)}function c(){const e=window.navigator.userAgent.toLocaleLowerCase();if(-1!==e.indexOf("edge"))return"edge";return-1!==e.indexOf("chrome")&&-1===e.indexOf("edge")?"chrome":-1!==e.indexOf("safari")&&-1===e.indexOf("chrome")?"safari":-1===e.indexOf("opera")?-1===e.indexOf("firefox")?null:"firefox":"opera"}function d(){if(!window.RTCRtpSender)return!1;if(!RTCRtpSender.getCapabilities)return!1;const e=RTCRtpSender.getCapabilities("video");if(!e)return!1;const n=e.headerExtensions.map(e=>e.uri),i=["urn:ietf:params:rtp-hdrext:sdes:mid","urn:ietf:params:rtp-hdrext:sdes:rtp-stream-id","urn:ietf:params:rtp-hdrext:sdes:repaired-rtp-stream-id"].every(e=>n.includes(e));return i}function C(){return"safari"===c()}function s(e,n,i,g,t){if("sendrecv"!==n&&"sendonly"!==n&&"recvonly"!==n)throw new Error("Unknown role type");if(null===i||void 0===i)throw new Error("channelId can not be null or undefined");const a={type:"connect",sora_client:"Sora JavaScript SDK 2021.1.2",environment:window.navigator.userAgent,role:n,channel_id:i,sdp:e,audio:!0,video:!0};if(void 0!==g&&(a.metadata=g),"signalingNotifyMetadata"in t&&(a.signaling_notify_metadata=t.signalingNotifyMetadata),"multistream"in t&&!0===t.multistream&&(a.multistream=!0,"spotlight"in t&&(a.spotlight=t.spotlight,"spotlightNumber"in t&&(a.spotlight_number=t.spotlightNumber)),!0===a.spotlight)){const e=["none","r0","r1","r2"];void 0!==t.spotlightFocusRid&&0<=e.indexOf(t.spotlightFocusRid)&&(a.spotlight_focus_rid=t.spotlightFocusRid),void 0!==t.spotlightUnfocusRid&&0<=e.indexOf(t.spotlightUnfocusRid)&&(a.spotlight_unfocus_rid=t.spotlightUnfocusRid)}if("simulcast"in t||"simulcastRid"in t){"simulcast"in t&&!0===t.simulcast&&(a.simulcast=!0);void 0!==t.simulcastRid&&0<=["r0","r1","r2"].indexOf(t.simulcastRid)&&(a.simulcast_rid=t.simulcastRid)}"clientId"in t&&void 0!==t.clientId&&(a.client_id=t.clientId),"dataChannelSignaling"in t&&"boolean"==typeof t.dataChannelSignaling&&(a.data_channel_signaling=t.dataChannelSignaling),"ignoreDisconnectWebSocket"in t&&"boolean"==typeof t.ignoreDisconnectWebSocket&&(a.ignore_disconnect_websocket=t.ignoreDisconnectWebSocket);const o=["audioCodecType","audioBitRate"],l=["audioOpusParamsChannels","audioOpusParamsClockRate","audioOpusParamsMaxplaybackrate","audioOpusParamsStereo","audioOpusParamsSpropStereo","audioOpusParamsMinptime","audioOpusParamsPtime","audioOpusParamsUseinbandfec","audioOpusParamsUsedtx"],c=["videoCodecType","videoBitRate"],C=Object.assign({},t);Object.keys(C).forEach(e=>{"audio"===e&&"boolean"==typeof C[e]||"video"===e&&"boolean"==typeof C[e]||0<=o.indexOf(e)&&null!==C[e]||0<=l.indexOf(e)&&null!==C[e]||0<=c.indexOf(e)&&null!==C[e]||delete C[e]}),void 0!==C.audio&&(a.audio=C.audio);const s=Object.keys(C).some(e=>0<=o.indexOf(e));a.audio&&s&&(a.audio={},"audioCodecType"in C&&(a.audio.codec_type=C.audioCodecType),"audioBitRate"in C&&(a.audio.bit_rate=C.audioBitRate));const I=Object.keys(C).some(e=>0<=l.indexOf(e));a.audio&&I&&("object"!=typeof a.audio&&(a.audio={}),a.audio.opus_params={},"audioOpusParamsChannels"in C&&(a.audio.opus_params.channels=C.audioOpusParamsChannels),"audioOpusParamsClockRate"in C&&(a.audio.opus_params.clock_rate=C.audioOpusParamsClockRate),"audioOpusParamsMaxplaybackrate"in C&&(a.audio.opus_params.maxplaybackrate=C.audioOpusParamsMaxplaybackrate),"audioOpusParamsStereo"in C&&(a.audio.opus_params.stereo=C.audioOpusParamsStereo),"audioOpusParamsSpropStereo"in C&&(a.audio.opus_params.sprop_stereo=C.audioOpusParamsSpropStereo),"audioOpusParamsMinptime"in C&&(a.audio.opus_params.minptime=C.audioOpusParamsMinptime),"audioOpusParamsPtime"in C&&(a.audio.opus_params.ptime=C.audioOpusParamsPtime),"audioOpusParamsUseinbandfec"in C&&(a.audio.opus_params.useinbandfec=C.audioOpusParamsUseinbandfec),"audioOpusParamsUsedtx"in C&&(a.audio.opus_params.usedtx=C.audioOpusParamsUsedtx)),void 0!==C.video&&(a.video=C.video);const r=Object.keys(C).some(e=>0<=c.indexOf(e));if(a.video&&r&&(a.video={},"videoCodecType"in C&&(a.video.codec_type=C.videoCodecType),"videoBitRate"in C&&(a.video.bit_rate=C.videoBitRate)),a.simulcast&&!d()&&"recvonly"!==n)throw new Error("Simulcast can not be used with this browser");if(!0===t.e2ee){if(void 0===a.signaling_notify_metadata&&(a.signaling_notify_metadata={}),null===a.signaling_notify_metadata||"object"!=typeof a.signaling_notify_metadata)throw new Error("E2EE failed. Options signalingNotifyMetadata must be type 'object'");!0===a.video&&(a.video={}),a.video&&(a.video.codec_type="VP8"),a.e2ee=!0}return a}function I(e){if(e.authn_metadata!==void 0)return e.authn_metadata;return void 0===e.metadata?null:e.metadata}function r(e){if(e.data&&Array.isArray(e.data))return e.data;return e.metadata_list&&Array.isArray(e.metadata_list)?e.metadata_list:[]}function m(e){return"object"==typeof e&&null!==e&&"pre_key_bundle"in e?e.pre_key_bundle:null}function A(e,n,i){const g=e=>{if(e&&"object"==typeof e){let n=null;try{n=Object.keys(JSON.parse(JSON.stringify(e)))}catch(e){}n&&Array.isArray(n)?n.forEach(n=>{console.group(n),g(e[n]),console.groupEnd()}):console.info(e)}else console.info(e)};let t="";window.performance&&(t="["+(window.performance.now()/1e3).toFixed(3)+"]"),e&&(t=t+"["+e+"]"),console.info!==void 0&&console.group!==void 0?(console.group(t+" "+n),g(i),console.groupEnd()):console.log(t+" "+n+"\n",i)}function Z(e,n,i){const g=new Event(e);try{g.data=JSON.parse(JSON.stringify(n))}catch(e){g.data=n}return g.transportType=i,g}function u(e){return{binaryType:e.binaryType,bufferedAmount:e.bufferedAmount,bufferedAmountLowThreshold:e.bufferedAmountLowThreshold,id:e.id,label:e.label,maxPacketLifeTime:e.maxPacketLifeTime,maxRetransmits:e.maxRetransmits,negotiated:e.negotiated,ordered:e.ordered,protocol:e.protocol,readyState:e.readyState,reliable:e.reliable}}function b(e,n,i,g,t){const a=new Event(e);try{a.data=JSON.parse(JSON.stringify(n))}catch(e){a.data=n}return a.logType=i,a.dataChannelId=g,a.dataChannelLabel=t,a}class p{constructor(){const e=!!RTCRtpSender.prototype.createEncodedStreams;if(!e)throw new Error("E2EE is not supported in this browser.");this.worker=null,this.onWorkerDisconnect=null}startWorker(){const e=atob("InVzZSBzdHJpY3QiOwovKiBlc2xpbnQtZGlzYWJsZSBAdHlwZXNjcmlwdC1lc2xpbnQvbm8tdW51c2VkLXZhcnMgKi8KY29uc3QgY29ubmVjdGlvbklkTGVuZ3RoID0gMjY7CmZ1bmN0aW9uIGJ5dGVDb3VudChuKSB7CiAgICBpZiAobiA9PSAwKSB7CiAgICAgICAgcmV0dXJuIDE7CiAgICB9CiAgICAvLyBsb2cyNTYoeCkgPSBsb2coeCkgLyBsb2coMjU2KQogICAgcmV0dXJuIE1hdGguZmxvb3IoTWF0aC5sb2cobikgLyBNYXRoLmxvZygyICoqIDgpICsgMSk7Cn0KZnVuY3Rpb24gYXJyYXlCdWZmZXJUb051bWJlcihhcnJheUJ1ZmZlcikgewogICAgLy8gMzJiaXQg44G+44Gn44KS5oOz5a6aIChCaWdJbnQg44G444Gu5pu444GN5o+b44GI5pmC44Gr6KaB5L+u5q2jKQogICAgY29uc3QgbmV3QXJyYXlCdWZmZXIgPSBuZXcgQXJyYXlCdWZmZXIoVWludDMyQXJyYXkuQllURVNfUEVSX0VMRU1FTlQpOwogICAgY29uc3QgbmV3RGF0YVZpZXcgPSBuZXcgRGF0YVZpZXcobmV3QXJyYXlCdWZmZXIpOwogICAgY29uc3QgZGF0YVZpZXcgPSBuZXcgRGF0YVZpZXcoYXJyYXlCdWZmZXIpOwogICAgY29uc3QgcGFkZGluZ0xlbmd0aCA9IFVpbnQzMkFycmF5LkJZVEVTX1BFUl9FTEVNRU5UIC0gZGF0YVZpZXcuYnl0ZUxlbmd0aDsKICAgIGZvciAobGV0IGkgPSAwOyBpIDwgcGFkZGluZ0xlbmd0aDsgaSArPSAxKSB7CiAgICAgICAgbmV3RGF0YVZpZXcuc2V0VWludDgoaSwgMCk7CiAgICB9CiAgICBmb3IgKGxldCBpID0gcGFkZGluZ0xlbmd0aCwgaiA9IDA7IGkgPCBVaW50MzJBcnJheS5CWVRFU19QRVJfRUxFTUVOVDsgaSArPSAxLCBqICs9IDEpIHsKICAgICAgICBuZXdEYXRhVmlldy5zZXRVaW50OChpLCBkYXRhVmlldy5nZXRVaW50OChqKSk7CiAgICB9CiAgICByZXR1cm4gbmV3RGF0YVZpZXcuZ2V0VWludDMyKDApOwp9CmZ1bmN0aW9uIGVuY29kZVNGcmFtZUhlYWRlcihzLCBjb3VudCwga2V5SWQpIHsKICAgIC8vICAwIDEgMiAzIDQgNSA2IDcKICAgIC8vICstKy0rLSstKy0rLSstKy0rLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tKy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSsKICAgIC8vIHxTfExFTiAgfDF8S0xFTiB8ICAgS0lELi4uIChsZW5ndGg9S0xFTikgICAgfCAgICBDVFIuLi4gKGxlbmd0aD1MRU4pICAgIHwKICAgIC8vICstKy0rLSstKy0rLSstKy0rLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tKy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSsKICAgIC8vIFM6IDEgYml0CiAgICAvLyBMRU46IDMgYml0CiAgICAvLyBYOiAxIGJpdAogICAgLy8gS0xFTjogMyBiaXQKICAgIC8vIEtJRDogS0xFTiBieXRlCiAgICAvLyBDVFI6IExFTiBieXRlCiAgICAvLyBUT0RPOiBrZXlJZCAoS0lEKSDjgYwgTnVtYmVyLk1BWF9TQUZFX0lOVEVHRVIsIDcgYnl0ZSDjgpLotoXjgYjjgabjgYTjgZ/loLTlkIjjga/jgqjjg6njg7zjgYvkvovlpJYKICAgIC8vIFRPRE86IGNvdW50IChDVFIpIOOBjCBOdW1iZXIuTUFYX1NBRkVfSU5URUdFUiwgNyBieXRlIOOCkui2heOBiOOBpuOBhOOBn+WgtOWQiOOBr+OCqOODqeODvOOBi+S+i+WklgogICAgaWYgKG1heEtleUlkIDwga2V5SWQgfHwgbWF4Q291bnQgPCBjb3VudCkgewogICAgICAgIHRocm93IG5ldyBFcnJvcigiRVhDRUVERUQtTUFYSU1VTS1CUk9BRENBU1RJTkctVElNRSIpOwogICAgfQogICAgY29uc3Qga2xlbiA9IGJ5dGVDb3VudChrZXlJZCk7CiAgICBjb25zdCBsZW4gPSBieXRlQ291bnQoY291bnQpOwogICAgY29uc3QgaGVhZGVyQnVmZmVyID0gbmV3IEFycmF5QnVmZmVyKDEgKyBrbGVuICsgbGVuKTsKICAgIGNvbnN0IGhlYWRlckRhdGFWaWV3ID0gbmV3IERhdGFWaWV3KGhlYWRlckJ1ZmZlcik7CiAgICAvLyBTLCBMRU4sIDEsIEtMRU4g44GnIDEgYnl0ZQogICAgaGVhZGVyRGF0YVZpZXcuc2V0VWludDgoMCwgKHMgPDwgNykgKyAobGVuIDw8IDQpICsgKDEgPDwgMykgKyBrbGVuKTsKICAgIGNvbnN0IGhlYWRlclVpbnQ4QXJyYXkgPSBuZXcgVWludDhBcnJheShoZWFkZXJCdWZmZXIpOwogICAgY29uc3Qga2V5SWRCdWZmZXIgPSBuZXcgQXJyYXlCdWZmZXIoVWludDMyQXJyYXkuQllURVNfUEVSX0VMRU1FTlQpOwogICAgY29uc3Qga2V5SWREYXRhVmlldyA9IG5ldyBEYXRhVmlldyhrZXlJZEJ1ZmZlcik7CiAgICBrZXlJZERhdGFWaWV3LnNldFVpbnQzMigwLCBrZXlJZCk7CiAgICBjb25zdCBrZXlJZFVpbnQ4QXJyYXkgPSBuZXcgVWludDhBcnJheShrZXlJZEJ1ZmZlcik7CiAgICBoZWFkZXJVaW50OEFycmF5LnNldChrZXlJZFVpbnQ4QXJyYXkuc3ViYXJyYXkoVWludDMyQXJyYXkuQllURVNfUEVSX0VMRU1FTlQgLSBrbGVuKSwgMSk7CiAgICBjb25zdCBjb3VudEJ1ZmZlciA9IG5ldyBBcnJheUJ1ZmZlcihVaW50MzJBcnJheS5CWVRFU19QRVJfRUxFTUVOVCk7CiAgICBjb25zdCBjb3VudERhdGFWaWV3ID0gbmV3IERhdGFWaWV3KGNvdW50QnVmZmVyKTsKICAgIGNvdW50RGF0YVZpZXcuc2V0VWludDMyKDAsIGNvdW50KTsKICAgIGNvbnN0IGNvdW50VWludDhBcnJheSA9IG5ldyBVaW50OEFycmF5KGNvdW50QnVmZmVyKTsKICAgIGhlYWRlclVpbnQ4QXJyYXkuc2V0KGNvdW50VWludDhBcnJheS5zdWJhcnJheShVaW50MzJBcnJheS5CWVRFU19QRVJfRUxFTUVOVCAtIGxlbiksIGtsZW4gKyAxKTsKICAgIHJldHVybiBoZWFkZXJVaW50OEFycmF5Owp9CmZ1bmN0aW9uIHNwbGl0SGVhZGVyKHNmcmFtZSkgewogICAgY29uc3Qgc2ZyYW1lRGF0YVZpZXcgPSBuZXcgRGF0YVZpZXcoc2ZyYW1lKTsKICAgIGNvbnN0IGhlYWRlciA9IHNmcmFtZURhdGFWaWV3LmdldFVpbnQ4KDApOwogICAgY29uc3QgbGVuID0gKGhlYWRlciAmIDB4NzApID4+IDQ7CiAgICBjb25zdCBrbGVuID0gaGVhZGVyICYgMHgwNzsKICAgIGNvbnN0IHNmcmFtZUhlYWRlckxlbmd0aCA9IDEgKyBrbGVuICsgbGVuOwogICAgY29uc3Qgc2ZyYW1lSGVhZGVyID0gc2ZyYW1lLnNsaWNlKDAsIHNmcmFtZUhlYWRlckxlbmd0aCk7CiAgICBpZiAoc2ZyYW1lSGVhZGVyLmJ5dGVMZW5ndGggPCBzZnJhbWVIZWFkZXJMZW5ndGgpIHsKICAgICAgICB0aHJvdyBuZXcgRXJyb3IoIlVORVhQRUNURUQtU0ZSQU1FLUxFTkdUSCIpOwogICAgfQogICAgY29uc3QgY29ubmVjdGlvbklkID0gc2ZyYW1lLnNsaWNlKHNmcmFtZUhlYWRlckxlbmd0aCwgc2ZyYW1lSGVhZGVyTGVuZ3RoICsgY29ubmVjdGlvbklkTGVuZ3RoKTsKICAgIGNvbnN0IGVuY3J5cHRlZEZyYW1lID0gc2ZyYW1lLnNsaWNlKHNmcmFtZUhlYWRlckxlbmd0aCArIGNvbm5lY3Rpb25JZExlbmd0aCwgc2ZyYW1lLmJ5dGVMZW5ndGgpOwogICAgcmV0dXJuIFtzZnJhbWVIZWFkZXIsIGNvbm5lY3Rpb25JZCwgZW5jcnlwdGVkRnJhbWVdOwp9CmZ1bmN0aW9uIHBhcnNlU0ZyYW1lSGVhZGVyKHNmcmFtZUhlYWRlcikgewogICAgY29uc3Qgc2ZyYW1lSGVhZGVyRGF0YVZpZXcgPSBuZXcgRGF0YVZpZXcoc2ZyYW1lSGVhZGVyKTsKICAgIGNvbnN0IGhlYWRlciA9IHNmcmFtZUhlYWRlckRhdGFWaWV3LmdldFVpbnQ4KDApOwogICAgY29uc3QgcyA9IChoZWFkZXIgJiAweDgwKSA+PiA3OwogICAgY29uc3QgbGVuID0gKGhlYWRlciAmIDB4NzApID4+IDQ7CiAgICBjb25zdCB4ID0gKGhlYWRlciAmIDB4MDgpID4+IDM7CiAgICBjb25zdCBrbGVuID0gaGVhZGVyICYgMHgwNzsKICAgIC8vIHggZmxhZwogICAgaWYgKHggIT09IDEpIHsKICAgICAgICB0aHJvdyBuZXcgRXJyb3IoIlVORVhQRUNURUQtWC1GTEFHIik7CiAgICB9CiAgICBjb25zdCBoZWFkZXJMZW5ndGggPSAxICsga2xlbiArIGxlbjsKICAgIGlmIChzZnJhbWVIZWFkZXJEYXRhVmlldy5ieXRlTGVuZ3RoIDwgaGVhZGVyTGVuZ3RoKSB7CiAgICAgICAgdGhyb3cgbmV3IEVycm9yKCJVTkVYUEVDVEVELVNGUkFNRS1IRUFERVItTEVOR1RIIik7CiAgICB9CiAgICBjb25zdCBrZXlJZEJ1ZmZlciA9IHNmcmFtZUhlYWRlci5zbGljZSgxLCAxICsga2xlbik7CiAgICBjb25zdCBrZXlJZCA9IGFycmF5QnVmZmVyVG9OdW1iZXIoa2V5SWRCdWZmZXIpOwogICAgY29uc3QgY291bnRCdWZmZXIgPSBzZnJhbWVIZWFkZXIuc2xpY2UoMSArIGtsZW4sIGhlYWRlckxlbmd0aCk7CiAgICBjb25zdCBjb3VudCA9IGFycmF5QnVmZmVyVG9OdW1iZXIoY291bnRCdWZmZXIpOwogICAgcmV0dXJuIFtzLCBjb3VudCwga2V5SWRdOwp9Ci8qIGVzbGludC1kaXNhYmxlIEB0eXBlc2NyaXB0LWVzbGludC90cmlwbGUtc2xhc2gtcmVmZXJlbmNlLCBAdHlwZXNjcmlwdC1lc2xpbnQvbm8tdW51c2VkLXZhcnMgKi8KLy8vIDxyZWZlcmVuY2UgcGF0aD0iLi9zZnJhbWUudHMiLz4KLy8gVE9ETzog5omx44GG5pWw5YCk44GM5aSn44GN44GE566H5omA44Gn44GvIE51bWJlciDjgYvjgokgQmlnSW50IOOBq+e9ruOBjeaPm+OBiOOCiwovLyBUT0RPOiBCaWdJbnQg44Gr572u44GN5o+b44GI44KL6Zqb44Gr5aSJ5pu044GZ44KLCmNvbnN0IG1heEtleUlkID0gMiAqKiAzMjsKY29uc3QgbWF4Q291bnQgPSAyICoqIDMyOwpjb25zdCBzZWxmRGVyaXZlS2V5TWFwID0gbmV3IE1hcCgpOwpjb25zdCBjb3VudE1hcCA9IG5ldyBNYXAoKTsKY29uc3Qgd3JpdGVJVk1hcCA9IG5ldyBNYXAoKTsKY29uc3QgcmVtb3RlRGVyaXZlS2V5TWFwID0gbmV3IE1hcCgpOwpjb25zdCBsYXRlc3RSZW1vdGVLZXlJZE1hcCA9IG5ldyBNYXAoKTsKY29uc3QgbGl0dGxlRW5kaWFuID0gdHJ1ZTsKY29uc3QgYmlnRW5kaWFuID0gIWxpdHRsZUVuZGlhbjsKY29uc3QgdGV4dEVuY29kZXIgPSBuZXcgVGV4dEVuY29kZXIoKTsKY29uc3QgdGV4dERlY29kZXIgPSBuZXcgVGV4dERlY29kZXIoKTsKLy8gVlA4IOOBruOBvwovLyBUT0RPKG5ha2FpKTogVlA5IC8gQVYxIOOCguWwhuadpeeahOOBq+WvvuW/nOOCguiAg+OBiOOCiwpjb25zdCB1bmVuY3J5cHRlZEJ5dGVzID0gewogICAgLy8gSSDjg5Xjg6zjg7zjg6AKICAgIGtleTogMTAsCiAgICAvLyDpnZ4gSSDjg5Xjg6zjg7zjg6AKICAgIGRlbHRhOiAzLAogICAgLy8g44Kq44O844OH44Kj44KqCiAgICB1bmRlZmluZWQ6IDEsCn07CmZ1bmN0aW9uIGdldENvdW50KGNvbm5lY3Rpb25JZCkgewogICAgcmV0dXJuIGNvdW50TWFwLmdldChjb25uZWN0aW9uSWQpIHx8IDA7Cn0KZnVuY3Rpb24gc2V0Q291bnQoY29ubmVjdGlvbklkLCBjb3VudCkgewogICAgcmV0dXJuIGNvdW50TWFwLnNldChjb25uZWN0aW9uSWQsIGNvdW50KTsKfQpmdW5jdGlvbiBnZXRSZW1vdGVEZXJpdmVLZXkoY29ubmVjdGlvbklkLCBrZXlJZCkgewogICAgaWYgKCFyZW1vdGVEZXJpdmVLZXlNYXAuaGFzKGNvbm5lY3Rpb25JZCkpIHsKICAgICAgICB0aHJvdyBuZXcgRXJyb3IoIlJFTU9URS1ERVJJVkVLRVktTUFQLU5PVC1GT1VORCIpOwogICAgfQogICAgY29uc3QgZGVyaXZlS2V5TWFwID0gcmVtb3RlRGVyaXZlS2V5TWFwLmdldChjb25uZWN0aW9uSWQpOwogICAgaWYgKCFkZXJpdmVLZXlNYXApIHsKICAgICAgICByZXR1cm47CiAgICB9CiAgICByZXR1cm4gZGVyaXZlS2V5TWFwLmdldChrZXlJZCk7Cn0KZnVuY3Rpb24gc2V0UmVtb3RlRGVyaXZlS2V5KGNvbm5lY3Rpb25JZCwga2V5SWQsIGRlcml2ZUtleSkgewogICAgbGV0IGRlcml2ZUtleU1hcCA9IHJlbW90ZURlcml2ZUtleU1hcC5nZXQoY29ubmVjdGlvbklkKTsKICAgIGlmICghZGVyaXZlS2V5TWFwKSB7CiAgICAgICAgZGVyaXZlS2V5TWFwID0gbmV3IE1hcCgpOwogICAgfQogICAgZGVyaXZlS2V5TWFwLnNldChrZXlJZCwgZGVyaXZlS2V5KTsKICAgIHJlbW90ZURlcml2ZUtleU1hcC5zZXQoY29ubmVjdGlvbklkLCBkZXJpdmVLZXlNYXApOwp9CmZ1bmN0aW9uIHNldExhdGVzdFJlbW90ZUtleUlkKGNvbm5lY3Rpb25JZCwga2V5SWQpIHsKICAgIGNvbnN0IGxhdGVzdFJlbW90ZUtleUlkID0gbGF0ZXN0UmVtb3RlS2V5SWRNYXAuZ2V0KGNvbm5lY3Rpb25JZCk7CiAgICBpZiAobGF0ZXN0UmVtb3RlS2V5SWQpIHsKICAgICAgICBpZiAobGF0ZXN0UmVtb3RlS2V5SWQgPCBrZXlJZCkgewogICAgICAgICAgICBsYXRlc3RSZW1vdGVLZXlJZE1hcC5zZXQoY29ubmVjdGlvbklkLCBrZXlJZCk7CiAgICAgICAgfQogICAgfQogICAgZWxzZSB7CiAgICAgICAgbGF0ZXN0UmVtb3RlS2V5SWRNYXAuc2V0KGNvbm5lY3Rpb25JZCwga2V5SWQpOwogICAgfQp9CmZ1bmN0aW9uIHJlbW92ZU9sZFJlbW90ZURlcml2ZUtleXMoKSB7CiAgICBsYXRlc3RSZW1vdGVLZXlJZE1hcC5mb3JFYWNoKChsYXRlc3RLZXlJZCwgY29ubmVjdGlvbklkKSA9PiB7CiAgICAgICAgY29uc3QgZGVyaXZlS2V5TWFwID0gcmVtb3RlRGVyaXZlS2V5TWFwLmdldChjb25uZWN0aW9uSWQpOwogICAgICAgIGlmIChkZXJpdmVLZXlNYXApIHsKICAgICAgICAgICAgZGVyaXZlS2V5TWFwLmZvckVhY2goKF8sIGtleUlkKSA9PiB7CiAgICAgICAgICAgICAgICBpZiAobGF0ZXN0S2V5SWQgIT09IGtleUlkKSB7CiAgICAgICAgICAgICAgICAgICAgZGVyaXZlS2V5TWFwLmRlbGV0ZShrZXlJZCk7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0pOwogICAgICAgIH0KICAgIH0pOwp9CmZ1bmN0aW9uIHJlbW92ZURlcml2ZUtleShjb25uZWN0aW9uSWQpIHsKICAgIGxhdGVzdFJlbW90ZUtleUlkTWFwLmRlbGV0ZShjb25uZWN0aW9uSWQpOwogICAgcmVtb3RlRGVyaXZlS2V5TWFwLmRlbGV0ZShjb25uZWN0aW9uSWQpOwp9CmZ1bmN0aW9uIGdldExhdGVzdFNlbGZEZXJpdmVLZXkoKSB7CiAgICBjb25zdCBkZXJpdmVLZXkgPSBzZWxmRGVyaXZlS2V5TWFwLmdldCgibGF0ZXN0Iik7CiAgICBpZiAoIWRlcml2ZUtleSkgewogICAgICAgIHRocm93IG5ldyBFcnJvcigiTEFURVNULVNFTEYtREVSSVZFS0VZLU5PVF9GT1VORCIpOwogICAgfQogICAgcmV0dXJuIGRlcml2ZUtleTsKfQpmdW5jdGlvbiBzZXRTZWxmRGVyaXZlS2V5KGNvbm5lY3Rpb25JZCwga2V5SWQsIGRlcml2ZUtleSkgewogICAgY29uc3QgY3VycmVudFNlbGZEZXJpdmVLZXkgPSBzZWxmRGVyaXZlS2V5TWFwLmdldCgibGF0ZXN0Iik7CiAgICBpZiAoY3VycmVudFNlbGZEZXJpdmVLZXkpIHsKICAgICAgICBpZiAoY3VycmVudFNlbGZEZXJpdmVLZXlbImtleUlkIl0gPCBrZXlJZCkgewogICAgICAgICAgICBjb25zdCBuZXh0U2VsZkRlcml2ZUtleSA9IHsgY29ubmVjdGlvbklkLCBrZXlJZCwgZGVyaXZlS2V5IH07CiAgICAgICAgICAgIHNlbGZEZXJpdmVLZXlNYXAuc2V0KCJsYXRlc3QiLCBuZXh0U2VsZkRlcml2ZUtleSk7CiAgICAgICAgfQogICAgfQogICAgZWxzZSB7CiAgICAgICAgY29uc3QgbmV4dFNlbGZEZXJpdmVLZXkgPSB7IGNvbm5lY3Rpb25JZCwga2V5SWQsIGRlcml2ZUtleSB9OwogICAgICAgIHNlbGZEZXJpdmVLZXlNYXAuc2V0KCJsYXRlc3QiLCBuZXh0U2VsZkRlcml2ZUtleSk7CiAgICB9Cn0KZnVuY3Rpb24gc2lsZW5jZUZyYW1lKGVuY29kZWRGcmFtZSkgewogICAgLy8gY29ubmVjdGlvbi5jcmVhdGVkLCByZWNlaXZlTWVzc2FnZSDlj5fkv6HliY3jga7loLTlkIgKICAgIGlmIChlbmNvZGVkRnJhbWUudHlwZSA9PT0gdW5kZWZpbmVkKSB7CiAgICAgICAgLy8g6Z+z5aOw44Gv5pqX5Y+35YyW44Gv44GE44KL44Go6IGe44GR44Gf44KC44Gu44GY44KD44Gq44GE44Gu44Gn572u44GN5o+b44GI44KLCiAgICAgICAgY29uc3QgbmV3RGF0YSA9IG5ldyBBcnJheUJ1ZmZlcigzKTsKICAgICAgICBjb25zdCBuZXdVaW50OCA9IG5ldyBVaW50OEFycmF5KG5ld0RhdGEpOwogICAgICAgIC8vIE9wdXMg44K144Kk44Os44Oz44K544OV44Os44O844OgCiAgICAgICAgbmV3VWludDguc2V0KFsweGQ4LCAweGZmLCAweGZlXSk7CiAgICAgICAgZW5jb2RlZEZyYW1lLmRhdGEgPSBuZXdEYXRhOwogICAgfQogICAgZWxzZSB7CiAgICAgICAgLy8g5pig5YOP44GM5q2j5bi444GY44KD44Gq44GE44Gf44KBIFBMSSDjgrnjg4jjg7zjg6DjgYznmbrnlJ/jgZfjgabjgZfjgb7jgYYKICAgICAgICAvLyDjgZ3jga7jgZ/jgoEgMzIweDI0MCDjga7nnJ/jgaPpu5LjgarnlLvpnaLjgavnva7jgY3mj5vjgYjjgosKICAgICAgICBjb25zdCBuZXdEYXRhID0gbmV3IEFycmF5QnVmZmVyKDYwKTsKICAgICAgICBjb25zdCBuZXdVaW50OCA9IG5ldyBVaW50OEFycmF5KG5ld0RhdGEpOwogICAgICAgIC8vIHByZXR0aWVyLWlnbm9yZQogICAgICAgIG5ld1VpbnQ4LnNldChbMHhiMCwgMHgwNSwgMHgwMCwgMHg5ZCwgMHgwMSwgMHgyYSwgMHhhMCwgMHgwMCwgMHg1YSwgMHgwMCwKICAgICAgICAgICAgMHgzOSwgMHgwMywgMHgwMCwgMHgwMCwgMHgxYywgMHgyMiwgMHgxNiwgMHgxNiwgMHgyMiwgMHg2NiwKICAgICAgICAgICAgMHgxMiwgMHgyMCwgMHgwNCwgMHg5MCwgMHg0MCwgMHgwMCwgMHhjNSwgMHgwMSwgMHhlMCwgMHg3YywKICAgICAgICAgICAgMHg0ZCwgMHgyZiwgMHhmYSwgMHhkZCwgMHg0ZCwgMHhhNSwgMHg3ZiwgMHg4OSwgMHhhNSwgMHhmZiwKICAgICAgICAgICAgMHg1YiwgMHhhOSwgMHhiNCwgMHhhZiwgMHhmMSwgMHgzNCwgMHhiZiwgMHhlYiwgMHg3NSwgMHgzNiwKICAgICAgICAgICAgMHg5NSwgMHhmZSwgMHgyNiwgMHg5NiwgMHg2MCwgMHhmZSwgMHhmZiwgMHhiYSwgMHhmZiwgMHg0MCwKICAgICAgICBdKTsKICAgICAgICBlbmNvZGVkRnJhbWUuZGF0YSA9IG5ld0RhdGE7CiAgICB9CiAgICByZXR1cm4gZW5jb2RlZEZyYW1lOwp9CmZ1bmN0aW9uIHNldFdyaXRlSVYoY29ubmVjdGlvbklkLCBrZXlJZCwgd3JpdGVJVikgewogICAgY29uc3Qga2V5ID0gW2Nvbm5lY3Rpb25JZCwga2V5SWQudG9TdHJpbmcoKV0uam9pbigiOiIpOwogICAgd3JpdGVJVk1hcC5zZXQoa2V5LCB3cml0ZUlWKTsKfQpmdW5jdGlvbiBnZXRXcml0ZUlWKGNvbm5lY3Rpb25JZCwga2V5SWQpIHsKICAgIGNvbnN0IGtleSA9IFtjb25uZWN0aW9uSWQsIGtleUlkLnRvU3RyaW5nKCldLmpvaW4oIjoiKTsKICAgIHJldHVybiB3cml0ZUlWTWFwLmdldChrZXkpOwp9CmZ1bmN0aW9uIGdlbmVyYXRlSVYoY291bnQsIGNvbm5lY3Rpb25JZCwga2V5SWQpIHsKICAgIC8vIFRPRE86IGtleUlkIOOBjCBOdW1iZXIuTUFYX1NBRkVfSU5URUdFUiwgNyBieXRlIOOCkui2heOBiOOBpuOBhOOBn+WgtOWQiOOBr+OCqOODqeODvOOBi+S+i+WklgogICAgLy8gVE9ETzogY291bnQg44GMIE51bWJlci5NQVhfU0FGRV9JTlRFR0VSLCA3IGJ5dGUg44KS6LaF44GI44Gm44GE44Gf5aC05ZCI44Gv44Ko44Op44O844GL5L6L5aSWCiAgICAvLyAzMiBiaXQg44G+44GnCiAgICBpZiAobWF4S2V5SWQgPCBrZXlJZCB8fCBtYXhDb3VudCA8IGNvdW50KSB7CiAgICAgICAgdGhyb3cgbmV3IEVycm9yKCJFWENFRURFRC1NQVhJTVVNLUJST0FEQ0FTVElORy1USU1FIik7CiAgICB9CiAgICBjb25zdCB3cml0ZUlWID0gZ2V0V3JpdGVJVihjb25uZWN0aW9uSWQsIGtleUlkKTsKICAgIGlmICghd3JpdGVJVikgewogICAgICAgIHRocm93IG5ldyBFcnJvcigiV1JJVEVJVi1OT1QtRk9VTkQiKTsKICAgIH0KICAgIGNvbnN0IHBhZGRpbmdMZW5ndGggPSBObiAtIFVpbnQzMkFycmF5LkJZVEVTX1BFUl9FTEVNRU5UOwogICAgY29uc3QgY291bnRXaXRoUGFkZGluZ0J1ZmZlciA9IG5ldyBBcnJheUJ1ZmZlcihObik7CiAgICBjb25zdCBjb3VudFdpdGhQYWRkaW5nRGF0YVZpZXcgPSBuZXcgRGF0YVZpZXcoY291bnRXaXRoUGFkZGluZ0J1ZmZlcik7CiAgICBjb3VudFdpdGhQYWRkaW5nRGF0YVZpZXcuc2V0VWludDMyKHBhZGRpbmdMZW5ndGgsIGNvdW50LCBiaWdFbmRpYW4pOwogICAgY29uc3QgaXYgPSBuZXcgVWludDhBcnJheShObik7CiAgICBjb25zdCBjb3VudFdpdGhQYWRkaW5nID0gbmV3IFVpbnQ4QXJyYXkoY291bnRXaXRoUGFkZGluZ0J1ZmZlcik7CiAgICBmb3IgKGxldCBpID0gMDsgaSA8IE5uOyBpKyspIHsKICAgICAgICBpdltpXSA9IHdyaXRlSVZbaV0gXiBjb3VudFdpdGhQYWRkaW5nW2ldOwogICAgfQogICAgcmV0dXJuIGl2Owp9CmZ1bmN0aW9uIHBhcnNlUGF5bG9hZChwYXlsb2FkVHlwZSwgcGF5bG9hZCkgewogICAgcmV0dXJuIFsKICAgICAgICBuZXcgVWludDhBcnJheShwYXlsb2FkLCAwLCB1bmVuY3J5cHRlZEJ5dGVzW3BheWxvYWRUeXBlXSksCiAgICAgICAgbmV3IFVpbnQ4QXJyYXkocGF5bG9hZCwgdW5lbmNyeXB0ZWRCeXRlc1twYXlsb2FkVHlwZV0pLAogICAgXTsKfQpmdW5jdGlvbiBlbmNvZGVGcmFtZUFkZChoZWFkZXIsIHNmcmFtZUhlYWRlciwgY29ubmVjdGlvbklkKSB7CiAgICBjb25zdCBjb25uZWN0aW9uSWREYXRhID0gdGV4dEVuY29kZXIuZW5jb2RlKGNvbm5lY3Rpb25JZCk7CiAgICBjb25zdCBmcmFtZUFkZCA9IG5ldyBVaW50OEFycmF5KGhlYWRlci5ieXRlTGVuZ3RoICsgc2ZyYW1lSGVhZGVyLmJ5dGVMZW5ndGggKyBjb25uZWN0aW9uSWREYXRhLmJ5dGVMZW5ndGgpOwogICAgZnJhbWVBZGQuc2V0KGhlYWRlciwgMCk7CiAgICBmcmFtZUFkZC5zZXQoc2ZyYW1lSGVhZGVyLCBoZWFkZXIuYnl0ZUxlbmd0aCk7CiAgICBmcmFtZUFkZC5zZXQoY29ubmVjdGlvbklkRGF0YSwgaGVhZGVyLmJ5dGVMZW5ndGggKyBzZnJhbWVIZWFkZXIuYnl0ZUxlbmd0aCk7CiAgICByZXR1cm4gZnJhbWVBZGQ7Cn0KYXN5bmMgZnVuY3Rpb24gZW5jcnlwdEZ1bmN0aW9uKGVuY29kZWRGcmFtZSwgY29udHJvbGxlcikgewogICAgY29uc3QgeyBjb25uZWN0aW9uSWQsIGtleUlkLCBkZXJpdmVLZXkgfSA9IGdldExhdGVzdFNlbGZEZXJpdmVLZXkoKTsKICAgIGlmICghZGVyaXZlS2V5KSB7CiAgICAgICAgcmV0dXJuOwogICAgfQogICAgY29uc3QgY3VycmVudENvdW50ID0gZ2V0Q291bnQoY29ubmVjdGlvbklkKTsKICAgIC8vIGNvdW50IOOBjCAzMiBiaXQg5Lul5LiK44Gu5aC05ZCI44Gv5YGc5q2i44GZ44KLCiAgICBpZiAoY3VycmVudENvdW50ID4gbWF4Q291bnQpIHsKICAgICAgICBwb3N0TWVzc2FnZSh7IHR5cGU6ICJkaXNjb25uZWN0IiB9KTsKICAgIH0KICAgIGNvbnN0IGl2ID0gZ2VuZXJhdGVJVihjdXJyZW50Q291bnQsIGNvbm5lY3Rpb25JZCwga2V5SWQpOwogICAgaWYgKCFpdikgewogICAgICAgIHJldHVybjsKICAgIH0KICAgIGNvbnN0IFtoZWFkZXIsIHBheWxvYWRdID0gcGFyc2VQYXlsb2FkKGVuY29kZWRGcmFtZS50eXBlLCBlbmNvZGVkRnJhbWUuZGF0YSk7CiAgICBjb25zdCBzZnJhbWVIZWFkZXIgPSBlbmNvZGVTRnJhbWVIZWFkZXIoMCwgY3VycmVudENvdW50LCBrZXlJZCk7CiAgICBjb25zdCBmcmFtZUFkZCA9IGVuY29kZUZyYW1lQWRkKGhlYWRlciwgc2ZyYW1lSGVhZGVyLCBjb25uZWN0aW9uSWQpOwogICAgY3J5cHRvLnN1YnRsZQogICAgICAgIC5lbmNyeXB0KHsKICAgICAgICBuYW1lOiAiQUVTLUdDTSIsCiAgICAgICAgaXY6IGl2LAogICAgICAgIC8vIOaal+WPt+WMluOBleOCjOOBpuOBhOOBquOBhOmDqOWIhgogICAgICAgIGFkZGl0aW9uYWxEYXRhOiBmcmFtZUFkZCwKICAgIH0sIGRlcml2ZUtleSwgcGF5bG9hZCkKICAgICAgICAudGhlbigoY2lwaGVyVGV4dCkgPT4gewogICAgICAgIGNvbnN0IG5ld0RhdGEgPSBuZXcgQXJyYXlCdWZmZXIoZnJhbWVBZGQuYnl0ZUxlbmd0aCArIGNpcGhlclRleHQuYnl0ZUxlbmd0aCk7CiAgICAgICAgY29uc3QgbmV3RGF0YVVpbnQ4ID0gbmV3IFVpbnQ4QXJyYXkobmV3RGF0YSk7CiAgICAgICAgbmV3RGF0YVVpbnQ4LnNldChmcmFtZUFkZCwgMCk7CiAgICAgICAgbmV3RGF0YVVpbnQ4LnNldChuZXcgVWludDhBcnJheShjaXBoZXJUZXh0KSwgZnJhbWVBZGQuYnl0ZUxlbmd0aCk7CiAgICAgICAgZW5jb2RlZEZyYW1lLmRhdGEgPSBuZXdEYXRhOwogICAgICAgIGNvbnRyb2xsZXIuZW5xdWV1ZShlbmNvZGVkRnJhbWUpOwogICAgfSk7CiAgICBzZXRDb3VudChjb25uZWN0aW9uSWQsIGN1cnJlbnRDb3VudCArIDEpOwp9CmFzeW5jIGZ1bmN0aW9uIGRlY3J5cHRGdW5jdGlvbihlbmNvZGVkRnJhbWUsIGNvbnRyb2xsZXIpIHsKICAgIC8vIOepuuODleODrOODvOODoOWvvuW/nAogICAgaWYgKGVuY29kZWRGcmFtZS5kYXRhLmJ5dGVMZW5ndGggPCAxKSB7CiAgICAgICAgcmV0dXJuOwogICAgfQogICAgdHJ5IHsKICAgICAgICBjb25zdCBmcmFtZU1ldGFkYXRhQnVmZmVyID0gZW5jb2RlZEZyYW1lLmRhdGEuc2xpY2UoMCwgdW5lbmNyeXB0ZWRCeXRlc1tlbmNvZGVkRnJhbWUudHlwZV0pOwogICAgICAgIGNvbnN0IGZyYW1lTWV0YWRhdGEgPSBuZXcgVWludDhBcnJheShmcmFtZU1ldGFkYXRhQnVmZmVyKTsKICAgICAgICBjb25zdCBbc2ZyYW1lSGVhZGVyQnVmZmVyLCBjb25uZWN0aW9uSWRCdWZmZXIsIGVuY3J5cHRlZEZyYW1lQnVmZmVyXSA9IHNwbGl0SGVhZGVyKGVuY29kZWRGcmFtZS5kYXRhLnNsaWNlKHVuZW5jcnlwdGVkQnl0ZXNbZW5jb2RlZEZyYW1lLnR5cGVdKSk7CiAgICAgICAgY29uc3Qgc2ZyYW1lSGVhZGVyID0gbmV3IFVpbnQ4QXJyYXkoc2ZyYW1lSGVhZGVyQnVmZmVyKTsKICAgICAgICBjb25zdCBjb25uZWN0aW9uSWQgPSB0ZXh0RGVjb2Rlci5kZWNvZGUoY29ubmVjdGlvbklkQnVmZmVyKTsKICAgICAgICBjb25zdCBbcywgY291bnQsIGtleUlkXSA9IHBhcnNlU0ZyYW1lSGVhZGVyKHNmcmFtZUhlYWRlckJ1ZmZlcik7CiAgICAgICAgLy8g5LuK5Zue44GvIHMgZmxhZyDjga8gMCDjga7jgb8KICAgICAgICBpZiAocyAhPT0gMCkgewogICAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoIlVORVhQRUNURUQtUy1GTEFHIik7CiAgICAgICAgfQogICAgICAgIGNvbnN0IGRlcml2ZUtleSA9IGdldFJlbW90ZURlcml2ZUtleShjb25uZWN0aW9uSWQsIGtleUlkKTsKICAgICAgICBpZiAoIWRlcml2ZUtleSkgewogICAgICAgICAgICByZXR1cm47CiAgICAgICAgfQogICAgICAgIGNvbnN0IGl2ID0gZ2VuZXJhdGVJVihjb3VudCwgY29ubmVjdGlvbklkLCBrZXlJZCk7CiAgICAgICAgaWYgKCFpdikgewogICAgICAgICAgICByZXR1cm47CiAgICAgICAgfQogICAgICAgIGNvbnN0IGZyYW1lQWRkID0gZW5jb2RlRnJhbWVBZGQoZnJhbWVNZXRhZGF0YSwgc2ZyYW1lSGVhZGVyLCBjb25uZWN0aW9uSWQpOwogICAgICAgIGNyeXB0by5zdWJ0bGUKICAgICAgICAgICAgLmRlY3J5cHQoewogICAgICAgICAgICBuYW1lOiAiQUVTLUdDTSIsCiAgICAgICAgICAgIGl2OiBpdiwKICAgICAgICAgICAgYWRkaXRpb25hbERhdGE6IGZyYW1lQWRkLAogICAgICAgIH0sIGRlcml2ZUtleSwgbmV3IFVpbnQ4QXJyYXkoZW5jcnlwdGVkRnJhbWVCdWZmZXIpKQogICAgICAgICAgICAudGhlbigocGxhaW5UZXh0KSA9PiB7CiAgICAgICAgICAgIGNvbnN0IG5ld0RhdGEgPSBuZXcgQXJyYXlCdWZmZXIoZnJhbWVNZXRhZGF0YUJ1ZmZlci5ieXRlTGVuZ3RoICsgcGxhaW5UZXh0LmJ5dGVMZW5ndGgpOwogICAgICAgICAgICBjb25zdCBuZXdVaW50OCA9IG5ldyBVaW50OEFycmF5KG5ld0RhdGEpOwogICAgICAgICAgICBuZXdVaW50OC5zZXQobmV3IFVpbnQ4QXJyYXkoZnJhbWVNZXRhZGF0YUJ1ZmZlciwgMCwgdW5lbmNyeXB0ZWRCeXRlc1tlbmNvZGVkRnJhbWUudHlwZV0pKTsKICAgICAgICAgICAgbmV3VWludDguc2V0KG5ldyBVaW50OEFycmF5KHBsYWluVGV4dCksIHVuZW5jcnlwdGVkQnl0ZXNbZW5jb2RlZEZyYW1lLnR5cGVdKTsKICAgICAgICAgICAgZW5jb2RlZEZyYW1lLmRhdGEgPSBuZXdEYXRhOwogICAgICAgICAgICBjb250cm9sbGVyLmVucXVldWUoZW5jb2RlZEZyYW1lKTsKICAgICAgICB9KTsKICAgIH0KICAgIGNhdGNoIChlKSB7CiAgICAgICAgLy8g5oOz5a6a5aSW44Gu44OR44Kx44OD44OI44OV44Kp44O844Oe44OD44OI44KS5Y+X5L+h44GX44Gf5aC05ZCICiAgICAgICAgY29udHJvbGxlci5lbnF1ZXVlKHNpbGVuY2VGcmFtZShlbmNvZGVkRnJhbWUpKTsKICAgIH0KfQovKiBlc2xpbnQtZGlzYWJsZSBAdHlwZXNjcmlwdC1lc2xpbnQvdHJpcGxlLXNsYXNoLXJlZmVyZW5jZSAqLwovLy8gPHJlZmVyZW5jZSBwYXRoPSIuL2UyZWUudHMiLz4KLy8gbm9uY2Ug44K144Kk44K6CmNvbnN0IE5uID0gMTI7Ci8vIGtleSDjgrXjgqTjgroKY29uc3QgTmsgPSAxNjsKLy8ga2V5IOOCteOCpOOCuu+8iGJpdO+8iQpjb25zdCBrZXlMZW5ndGggPSBOayAqIDg7CmFzeW5jIGZ1bmN0aW9uIGdlbmVyYXRlRGVyaXZlS2V5KG1hdGVyaWFsKSB7CiAgICBjb25zdCBzYWx0ID0gdGV4dEVuY29kZXIuZW5jb2RlKCJTRnJhbWUxMCIpOwogICAgY29uc3QgaW5mbyA9IHRleHRFbmNvZGVyLmVuY29kZSgia2V5Iik7CiAgICBjb25zdCBkZXJpdmVLZXkgPSBhd2FpdCBjcnlwdG8uc3VidGxlLmRlcml2ZUtleSh7CiAgICAgICAgbmFtZTogIkhLREYiLAogICAgICAgIHNhbHQ6IHNhbHQsCiAgICAgICAgaGFzaDogIlNIQS0yNTYiLAogICAgICAgIGluZm86IGluZm8sCiAgICB9LCBtYXRlcmlhbCwgewogICAgICAgIG5hbWU6ICJBRVMtR0NNIiwKICAgICAgICBsZW5ndGg6IGtleUxlbmd0aCwKICAgIH0sIGZhbHNlLCBbImVuY3J5cHQiLCAiZGVjcnlwdCJdKTsKICAgIHJldHVybiBkZXJpdmVLZXk7Cn0KYXN5bmMgZnVuY3Rpb24gZ2VuZXJhdGVXcml0ZUlWKG1hdGVyaWFsKSB7CiAgICBjb25zdCBzYWx0ID0gdGV4dEVuY29kZXIuZW5jb2RlKCJTRnJhbWUxMCIpOwogICAgY29uc3QgaW5mbyA9IHRleHRFbmNvZGVyLmVuY29kZSgic2FsdCIpOwogICAgY29uc3Qgd3JpdGVJVkJ1ZmZlciA9IGF3YWl0IGNyeXB0by5zdWJ0bGUuZGVyaXZlQml0cyh7CiAgICAgICAgbmFtZTogIkhLREYiLAogICAgICAgIHNhbHQ6IHNhbHQsCiAgICAgICAgaGFzaDogIlNIQS0zODQiLAogICAgICAgIGluZm86IGluZm8sCiAgICB9LCBtYXRlcmlhbCwgCiAgICAvLyBJViDjga8gOTYg44OT44OD44OI44Gq44Gu44GnCiAgICBObiAqIDgpOwogICAgY29uc3Qgd3JpdGVJViA9IG5ldyBVaW50OEFycmF5KHdyaXRlSVZCdWZmZXIpOwogICAgcmV0dXJuIHdyaXRlSVY7Cn0KbGV0IHJlbW92YWxUaW1lb3V0SWQgPSAwOwpvbm1lc3NhZ2UgPSAoZXZlbnQpID0+IHsKICAgIGNvbnN0IHsgdHlwZSB9ID0gZXZlbnQuZGF0YTsKICAgIGlmICh0eXBlID09PSAic2VsZlNlY3JldEtleU1hdGVyaWFsIikgewogICAgICAgIGNvbnN0IHsgc2VsZlNlY3JldEtleU1hdGVyaWFsLCBzZWxmQ29ubmVjdGlvbklkLCBzZWxmS2V5SWQsIHdhaXRpbmdUaW1lIH0gPSBldmVudC5kYXRhOwogICAgICAgIGNvbnN0IHRpbWVvdXRJZCA9IHNldFRpbWVvdXQoKCkgPT4gewogICAgICAgICAgICBjcnlwdG8uc3VidGxlCiAgICAgICAgICAgICAgICAuaW1wb3J0S2V5KCJyYXciLCBzZWxmU2VjcmV0S2V5TWF0ZXJpYWwuYnVmZmVyLCAiSEtERiIsIGZhbHNlLCBbImRlcml2ZUJpdHMiLCAiZGVyaXZlS2V5Il0pCiAgICAgICAgICAgICAgICAudGhlbigobWF0ZXJpYWwpID0+IHsKICAgICAgICAgICAgICAgIGdlbmVyYXRlRGVyaXZlS2V5KG1hdGVyaWFsKS50aGVuKChkZXJpdmVLZXkpID0+IHsKICAgICAgICAgICAgICAgICAgICBzZXRTZWxmRGVyaXZlS2V5KHNlbGZDb25uZWN0aW9uSWQsIHNlbGZLZXlJZCwgZGVyaXZlS2V5KTsKICAgICAgICAgICAgICAgIH0pOwogICAgICAgICAgICAgICAgZ2VuZXJhdGVXcml0ZUlWKG1hdGVyaWFsKS50aGVuKCh3cml0ZUlWKSA9PiB7CiAgICAgICAgICAgICAgICAgICAgc2V0V3JpdGVJVihzZWxmQ29ubmVjdGlvbklkLCBzZWxmS2V5SWQsIHdyaXRlSVYpOwogICAgICAgICAgICAgICAgfSk7CiAgICAgICAgICAgICAgICBjbGVhclRpbWVvdXQodGltZW91dElkKTsKICAgICAgICAgICAgfSk7CiAgICAgICAgfSwgd2FpdGluZ1RpbWUgfHwgMCk7CiAgICAgICAgLy8gVE9ETzogKzEwMDAg44Gn6Y2155Sf5oiQ5b6M44Gr5a6f6KGM44GV44KM44KL44KI44GG44Gr44GX44Gm44GE44KL44GM55+t44GE5aC05ZCI44Gv5Ly444Gw44GZCiAgICAgICAgY29uc3QgcmVtb3ZhbFdhaXRpbmdUaW1lID0gKHdhaXRpbmdUaW1lIHx8IDApICsgMTAwMDsKICAgICAgICBpZiAocmVtb3ZhbFRpbWVvdXRJZCkgewogICAgICAgICAgICAvLyDli5XkvZzmuIjjgb/jgr/jgqTjg57jg7zmnInjgooKICAgICAgICAgICAgaWYgKHdhaXRpbmdUaW1lKSB7CiAgICAgICAgICAgICAgICAvLyBjb25uZWN0aW9uLmRlc3Ryb3llZAogICAgICAgICAgICAgICAgY2xlYXJUaW1lb3V0KHJlbW92YWxUaW1lb3V0SWQpOwogICAgICAgICAgICAgICAgcmVtb3ZhbFRpbWVvdXRJZCA9IHNldFRpbWVvdXQoKCkgPT4gewogICAgICAgICAgICAgICAgICAgIHJlbW92ZU9sZFJlbW90ZURlcml2ZUtleXMoKTsKICAgICAgICAgICAgICAgICAgICBjbGVhclRpbWVvdXQocmVtb3ZhbFRpbWVvdXRJZCk7CiAgICAgICAgICAgICAgICAgICAgcmVtb3ZhbFRpbWVvdXRJZCA9IDA7CiAgICAgICAgICAgICAgICB9LCByZW1vdmFsV2FpdGluZ1RpbWUpOwogICAgICAgICAgICB9CiAgICAgICAgfQogICAgICAgIGVsc2UgewogICAgICAgICAgICAvLyDli5XkvZzmuIjjgb/jgr/jgqTjg57jg7zjgarjgZcKICAgICAgICAgICAgLy8gY29ubmVjdGlvbi5jcmVhdGVkIOOBruWgtOWQiOOCguWwkeOBl+Wun+ihjOOCkumBheOCieOBm+OCiwogICAgICAgICAgICByZW1vdmFsVGltZW91dElkID0gc2V0VGltZW91dCgoKSA9PiB7CiAgICAgICAgICAgICAgICByZW1vdmVPbGRSZW1vdGVEZXJpdmVLZXlzKCk7CiAgICAgICAgICAgICAgICBjbGVhclRpbWVvdXQocmVtb3ZhbFRpbWVvdXRJZCk7CiAgICAgICAgICAgICAgICByZW1vdmFsVGltZW91dElkID0gMDsKICAgICAgICAgICAgfSwgcmVtb3ZhbFdhaXRpbmdUaW1lKTsKICAgICAgICB9CiAgICB9CiAgICBlbHNlIGlmICh0eXBlID09PSAicmVtb3RlU2VjcmV0S2V5TWF0ZXJpYWxzIikgewogICAgICAgIGNvbnN0IHsgcmVtb3RlU2VjcmV0S2V5TWF0ZXJpYWxzIH0gPSBldmVudC5kYXRhOwogICAgICAgIGZvciAoY29uc3QgW2Nvbm5lY3Rpb25JZCwgcmVtb3RlU2VjcmV0S2V5TWF0ZXJpYWxdIG9mIE9iamVjdC5lbnRyaWVzKHJlbW90ZVNlY3JldEtleU1hdGVyaWFscykpIHsKICAgICAgICAgICAgY29uc3QgeyBrZXlJZCwgc2VjcmV0S2V5TWF0ZXJpYWwgfSA9IHJlbW90ZVNlY3JldEtleU1hdGVyaWFsOwogICAgICAgICAgICBjcnlwdG8uc3VidGxlCiAgICAgICAgICAgICAgICAuaW1wb3J0S2V5KCJyYXciLCBzZWNyZXRLZXlNYXRlcmlhbC5idWZmZXIsICJIS0RGIiwgZmFsc2UsIFsiZGVyaXZlQml0cyIsICJkZXJpdmVLZXkiXSkKICAgICAgICAgICAgICAgIC50aGVuKChtYXRlcmlhbCkgPT4gewogICAgICAgICAgICAgICAgZ2VuZXJhdGVEZXJpdmVLZXkobWF0ZXJpYWwpLnRoZW4oKGRlcml2ZUtleSkgPT4gewogICAgICAgICAgICAgICAgICAgIHNldFJlbW90ZURlcml2ZUtleShjb25uZWN0aW9uSWQsIGtleUlkLCBkZXJpdmVLZXkpOwogICAgICAgICAgICAgICAgfSk7CiAgICAgICAgICAgICAgICBnZW5lcmF0ZVdyaXRlSVYobWF0ZXJpYWwpLnRoZW4oKHdyaXRlSVYpID0+IHsKICAgICAgICAgICAgICAgICAgICBzZXRXcml0ZUlWKGNvbm5lY3Rpb25JZCwga2V5SWQsIHdyaXRlSVYpOwogICAgICAgICAgICAgICAgfSk7CiAgICAgICAgICAgICAgICBzZXRMYXRlc3RSZW1vdGVLZXlJZChjb25uZWN0aW9uSWQsIGtleUlkKTsKICAgICAgICAgICAgfSk7CiAgICAgICAgfQogICAgfQogICAgZWxzZSBpZiAodHlwZSA9PT0gInJlbW92ZVJlbW90ZURlcml2ZUtleSIpIHsKICAgICAgICBjb25zdCB7IGNvbm5lY3Rpb25JZCB9ID0gZXZlbnQuZGF0YTsKICAgICAgICByZW1vdmVEZXJpdmVLZXkoY29ubmVjdGlvbklkKTsKICAgIH0KICAgIGVsc2UgaWYgKHR5cGUgPT09ICJlbmNyeXB0IikgewogICAgICAgIGNvbnN0IHsgcmVhZGFibGVTdHJlYW0sIHdyaXRhYmxlU3RyZWFtIH0gPSBldmVudC5kYXRhOwogICAgICAgIGNvbnN0IHRyYW5zZm9ybVN0cmVhbSA9IG5ldyBUcmFuc2Zvcm1TdHJlYW0oewogICAgICAgICAgICB0cmFuc2Zvcm06IGVuY3J5cHRGdW5jdGlvbiwKICAgICAgICB9KTsKICAgICAgICByZWFkYWJsZVN0cmVhbS5waXBlVGhyb3VnaCh0cmFuc2Zvcm1TdHJlYW0pLnBpcGVUbyh3cml0YWJsZVN0cmVhbSk7CiAgICB9CiAgICBlbHNlIGlmICh0eXBlID09PSAiZGVjcnlwdCIpIHsKICAgICAgICBjb25zdCB7IHJlYWRhYmxlU3RyZWFtLCB3cml0YWJsZVN0cmVhbSB9ID0gZXZlbnQuZGF0YTsKICAgICAgICBjb25zdCB0cmFuc2Zvcm1TdHJlYW0gPSBuZXcgVHJhbnNmb3JtU3RyZWFtKHsKICAgICAgICAgICAgdHJhbnNmb3JtOiBkZWNyeXB0RnVuY3Rpb24sCiAgICAgICAgfSk7CiAgICAgICAgcmVhZGFibGVTdHJlYW0ucGlwZVRocm91Z2godHJhbnNmb3JtU3RyZWFtKS5waXBlVG8od3JpdGFibGVTdHJlYW0pOwogICAgfQogICAgZWxzZSBpZiAodHlwZSA9PT0gImNsZWFyIikgewogICAgICAgIGNvdW50TWFwLmNsZWFyKCk7CiAgICAgICAgd3JpdGVJVk1hcC5jbGVhcigpOwogICAgICAgIHJlbW90ZURlcml2ZUtleU1hcC5jbGVhcigpOwogICAgICAgIGxhdGVzdFJlbW90ZUtleUlkTWFwLmNsZWFyKCk7CiAgICAgICAgc2VsZkRlcml2ZUtleU1hcC5jbGVhcigpOwogICAgfQp9Owo=");this.worker=new Worker(URL.createObjectURL(new Blob([e],{type:"application/javascript"}))),this.worker.onmessage=e=>{const{operation:n}=e.data;"disconnect"===n&&"function"==typeof this.onWorkerDisconnect&&this.onWorkerDisconnect()}}clearWorker(){this.worker&&this.worker.postMessage({type:"clear"})}terminateWorker(){this.worker&&this.worker.terminate()}async init(){const{preKeyBundle:e}=await window.e2ee.init();return e}setupSenderTransform(e){if(!e.track)return;const n=e.createEncodedStreams(),i=n.readableStream||n.readable,g=n.writableStream||n.writable;if(!this.worker)throw new Error("Worker is null. Call startWorker in advance.");this.worker.postMessage({type:"encrypt",readableStream:i,writableStream:g},[i,g])}setupReceiverTransform(e){const n=e.createEncodedStreams(),i=n.readableStream||n.readable,g=n.writableStream||n.writable;if(!this.worker)throw new Error("Worker is null. Call startWorker in advance.");this.worker.postMessage({type:"decrypt",readableStream:i,writableStream:g},[i,g])}postRemoteSecretKeyMaterials(e){if(!this.worker)throw new Error("Worker is null. Call startWorker in advance.");this.worker.postMessage({type:"remoteSecretKeyMaterials",remoteSecretKeyMaterials:e.remoteSecretKeyMaterials})}postRemoveRemoteDeriveKey(e){if(!this.worker)throw new Error("Worker is null. Call startWorker in advance.");this.worker.postMessage({type:"removeRemoteDeriveKey",connectionId:e})}postSelfSecretKeyMaterial(e,n,i,g=0){if(!this.worker)throw new Error("Worker is null. Call startWorker in advance.");this.worker.postMessage({type:"selfSecretKeyMaterial",selfConnectionId:e,selfKeyId:n,selfSecretKeyMaterial:i,waitingTime:g})}startSession(e,n){const[i,g]=window.e2ee.startSession(e,n.identityKey,n.signedPreKey,n.preKeySignature);if(g)throw g;return i}stopSession(e){const[n,i]=window.e2ee.stopSession(e);if(i)throw i;return n}receiveMessage(e){const[n,i]=window.e2ee.receiveMessage(e);if(i)throw i;return n}start(e){const[n,i]=window.e2ee.start(e);if(i)throw i;return n}addPreKeyBundle(e,n){const i=window.e2ee.addPreKeyBundle(e,n.identityKey,n.signedPreKey,n.preKeySignature);if(i)throw i}selfFingerprint(){return window.e2ee.selfFingerprint()}remoteFingerprints(){return window.e2ee.remoteFingerprints()}static async loadWasm(e){if(void 0===!window.e2ee)return void console.warn("E2ee wasm is already loaded. Will not be reload.");if(a(),!window.Go)throw new Error(`Failed to load module Go. window.Go is ${window.Go}.`);const n=new Go,{instance:i}=await WebAssembly.instantiateStreaming(fetch(e),n.importObject);if(n.run(i),!window.e2ee)throw new Error(`Failed to load module e2ee. window.e2ee is ${window.e2ee}.`)}static version(){return"2021.1.0"}static wasmVersion(){return window.e2ee.version()}}var V=Uint8Array,G=Uint16Array,S=Uint32Array,W=new V([0,0,0,0,0,0,0,0,1,1,1,1,2,2,2,2,3,3,3,3,4,4,4,4,5,5,5,5,0,0,0,0]),h=new V([0,0,0,0,1,1,2,2,3,3,4,4,5,5,6,6,7,7,8,8,9,9,10,10,11,11,12,12,13,13,0,0]),y=new V([16,17,18,0,8,7,9,6,10,5,11,4,12,3,13,2,14,1,15]),k=function(e,n){for(var g=new G(31),t=0;31>t;++t)g[t]=n+=1<t;++t)for(var o=g[t];oN;++N)X=(43690&N)>>>1|(21845&N)<<1,X=(52428&X)>>>2|(13107&X)<<2,X=(61680&X)>>>4|(3855&X)<<4,Y[N]=((65280&X)>>>8|(255&X)<<8)>>>1;for(var v=function(e,n,g){for(var t=e.length,a=0,o=new G(n);a>>15-n]=d}else for(c=new G(t),a=0;a>>15-e[a]);return c},E=new V(288),N=0;144>N;++N)E[N]=8;for(var N=144;256>N;++N)E[N]=9;for(var N=256;280>N;++N)E[N]=7;for(var N=280;288>N;++N)E[N]=8;for(var O=new V(32),N=0;32>N;++N)O[N]=5;var K=v(E,9,0),F=v(E,9,1),L=v(O,5,0),J=v(O,5,1),U=function(e){for(var n=e[0],g=1;gn&&(n=e[g]);return n},Q=function(e,n,i){var g=0|n/8;return(e[g]|e[g+1]<<8)>>(7&n)&i},D=function(e,n){var i=0|n/8;return(e[i]|e[i+1]<<8|e[i+2]<<16)>>(7&n)},H=function(e){return(0|e/8)+(7&e&&1)},M=function(i,g,t){(null==g||0>g)&&(g=0),(null==t||t>i.length)&&(t=i.length);var a=new(i instanceof G?G:i instanceof S?S:V)(t-g);return a.set(i.subarray(g,t)),a},P=["unexpected EOF","invalid block type","invalid length/literal","invalid distance","stream finished","no stream handler",,"no callback","invalid UTF-8 data","extra field too long","date not in range 1980-2099","filename too long","stream finishing","invalid zip data"],j=function(n,i,g){var t=new Error(i||P[n]);if(t.code=n,Error.captureStackTrace&&Error.captureStackTrace(t,j),!g)throw t;return t},z=function(g,a,o){var C=g.length;if(!C||o&&!o.l&&5>C)return a||new V(0);var I=!a||o,m=!o||o.i;o||(o={}),a||(a=new V(3*C));var A=function(e){var n=a.length;if(e>n){var i=new V(t(2*n,e));i.set(a),a=i}},Z=o.f||0,u=o.p||0,p=o.b||0,G=o.l,S=o.d,k=o.m,w=o.n,R=8*C;do{if(!G){o.f=Z=Q(g,u,1);var X=Q(g,u+1,3);if(u+=3,!X){var f=H(u)+4,T=g[f-4]|g[f-3]<<8,l=f+T;if(l>C){m&&j(0);break}I&&A(p+T),a.set(g.subarray(f,l),p),o.b=p+=T,o.p=u=8*l;continue}else if(1==X)G=F,S=J,k=9,w=5;else if(2==X){var Y=Q(g,u,31)+257,N=Q(g,u+10,15)+4,E=Y+Q(g,u+5,31)+1;u+=14;for(var O=new V(E),K=new V(19),L=0;L>>4;if(16>f)O[L++]=f;else{var _=0,q=0;for(16==f?(q=3+Q(g,u,3),u+=2,_=O[L-1]):17==f?(q=3+Q(g,u,7),u+=3):18==f&&(q=11+Q(g,u,127),u+=7);q--;)O[L++]=_}}var $=O.subarray(0,Y),ee=O.subarray(Y);k=U($),w=U(ee),G=v($,k,1),S=v(ee,w,1)}else j(1);if(u>R){m&&j(0);break}}I&&A(p+131072);for(var ne=(1<>>4;if(u+=15&_,u>R){m&&j(0);break}if(_||j(2),256>te)a[p++]=te;else if(256==te){ge=u,G=null;break}else{var ae=te-254;if(264>>4;le||j(3),u+=15≤var ee=B[d];if(3R){m&&j(0);break}I&&A(p+131072);for(var ce=p+ae;p>>8},q=function(e,n,i){i<<=7&n;var g=0|n/8;e[g]|=i,e[g+1]|=i>>>8,e[g+2]|=i>>>16},$=function(e,n){for(var g=[],t=0;tA&&(A=o[t].s);var Z=new G(A+1),u=ee(g[I-1],Z,0);if(u>n){var t=0,b=0,p=u-n;for(o.sort(function(e,n){return Z[n.s]-Z[e.s]||e.f-n.f});tn)b+=(1<>>=p;0>>8,e[a+2]=255^e[a],e[a+3]=255^e[a+1];for(var o=0;oz;++z){x=P[z];for(var ee,f=0;f>>5),s+=x[f]>>>12)}}else Q=K,D=E,j=L,H=O;for(var f=0;f>>18;q(n,s,Q[ee+257]),s+=D[ee+257],7>>23),s+=W[ee]);var te=31&t[f];q(n,s,j[te]),s+=H[te],3>>5),s+=h[te])}else q(n,s,Q[t[f]]),s+=D[t[f]];return q(n,s,Q[256]),s+D[256]},ae=new S([65540,131080,131088,131104,262176,1048704,1048832,2114560,2117632]),oe=new V(0),le=function(t,a,c,C,I,r){var m=t.length,s=new V(C+m+5*(1+g(m/7e3))+I),o=s.subarray(C,s.length-I),A=0;if(!a||8>m)for(var Z,u=0;u<=m;u+=65535)Z=u+65535,ZQ;++Q)B[Q]=0;for(var Q=0;30>Q;++Q)Y[Q]=0}var D=2,x=0,P=8191&b,z=32767&L-J;if(2>>13,U)-1,q=n(32767,u),$=n(258,U);z<=q&&--P&&L!=J;){if(t[u+D]==t[u+D-z]){for(var ee=0;ee<$&&t[u+ee]==t[u+ee-z];++ee);if(ee>D){if(D=ee,x=z,ee>_)break;for(var ne=n(z,ee-2),ie=0,Q=0;Qie&&(ie=de,J=le)}}}L=J,J=y[L],z+=32767&L-J+32768}if(x){f[E++]=268435456|R[D]<<18|T[x];var Ce=31&R[D],se=31&T[x];v+=W[Ce]+h[se],++B[257+Ce],++Y[se],O=u+D,++N}else f[E++]=t[u],++B[t[u]]}}A=te(t,o,r,f,B,Y,v,E,K,u-K,A),!r&&7&A&&(A=ge(o,A+1,oe))}return M(s,0,C+H(A)+I)},ce=function(){var g=1,t=0;return{p:function(a){for(var o,c=g,d=t,C=a.length,l=0;l!=C;){for(o=n(l+2655,C);l>16),d=(65535&d)+15*(d>>16)}g=c,t=d},d:function(){return g%=65521,t%=65521,(255&g)<<24|g>>>8<<16|(255&t)<<8|t>>>8}}},de=function(e,i,a,o,l){return le(e,null==i.level?6:i.level,null==i.mem?g(1.5*t(8,n(13,Math.log(e.length)))):12+i.mem,a,o,!l)},Ce=function(e,n,i){for(;i;++n)e[n]=i,i>>>=8},se=function(e,n){var i=n.level,g=0==i?0:6>i?1:9==i?3:2;e[0]=120,e[1]=g<<6|(g?32-2*g:1)},Ie=function(e){(8!=(15&e[0])||7>>4||(e[0]<<8|e[1])%31)&&j(6,"invalid zlib data"),32&e[1]&&j(6,"invalid zlib data: preset dictionaries not supported")},re="undefined"!=typeof TextDecoder&&new TextDecoder,me=0;try{re.decode(oe,{stream:!0}),me=1}catch(n){}class Ae extends Error{}class Ze{constructor(e,n,i,g,t,a){this.role=n,this.channelId=i,this.metadata=g,this.signalingUrl=e,this.options=t,this.connectionTimeout=6e4,"number"==typeof this.options.timeout&&(console.warn("@deprecated timeout option will be removed in a future version. Use connectionTimeout."),this.connectionTimeout=this.options.timeout),"number"==typeof this.options.connectionTimeout&&(this.connectionTimeout=this.options.connectionTimeout),this.disconnectWaitTimeout=3e3,"number"==typeof this.options.disconnectWaitTimeout&&(this.disconnectWaitTimeout=this.options.disconnectWaitTimeout),this.constraints=null,this.debug=a,this.clientId=null,this.connectionId=null,this.remoteConnectionIds=[],this.stream=null,this.ws=null,this.pc=null,this.encodings=[],this.callbacks={disconnect:()=>{},push:()=>{},addstream:()=>{},track:()=>{},removestream:()=>{},removetrack:()=>{},notify:()=>{},log:()=>{},timeout:()=>{},timeline:()=>{},signaling:()=>{}},this.authMetadata=null,this.e2ee=null,this.connectionTimeoutTimerId=0,this.monitorSignalingWebSocketEventTimerId=0,this.monitorIceConnectionStateChangeTimerId=0,this.dataChannels={},this.mids={audio:"",video:""},this.signalingSwitched=!1,this.dataChannelsCompress={}}on(e,n){"addstream"===e?console.warn("@deprecated addstream callback will be removed in a future version. Use track callback."):"removestream"==e&&console.warn("@deprecated removestream callback will be removed in a future version. Use removetrack callback."),e in this.callbacks&&(this.callbacks[e]=n)}stopAudioTrack(e){for(const n of e.getAudioTracks())n.enabled=!1;return new Promise(n=>{setTimeout(async()=>{for(const n of e.getAudioTracks())if(n.stop(),e.removeTrack(n),null!==this.pc){const e=this.pc.getSenders().find(e=>e.track&&e.track.id===n.id);e&&(await e.replaceTrack(null))}n()},100)})}stopVideoTrack(e){for(const n of e.getVideoTracks())n.enabled=!1;return new Promise(n=>{setTimeout(async()=>{for(const n of e.getVideoTracks())if(n.stop(),e.removeTrack(n),null!==this.pc){const e=this.pc.getSenders().find(e=>e.track&&e.track.id===n.id);e&&(await e.replaceTrack(null))}n()},100)})}async replaceAudioTrack(e,n){await this.stopAudioTrack(e);const i=this.getAudioTransceiver();if(null===i)throw new Error("Unable to set an audio track. Audio track sender is undefined");e.addTrack(n),await i.sender.replaceTrack(n)}async replaceVideoTrack(e,n){await this.stopVideoTrack(e);const i=this.getVideoTransceiver();if(null===i)throw new Error("Unable to set video track. Video track sender is undefined");e.addTrack(n),await i.sender.replaceTrack(n)}stopStream(){return new Promise(e=>(this.debug&&console.warn("@deprecated closing MediaStream in disconnect will be removed in a future version. Close every track in the MediaStream by yourself."),!this.stream)?e():(this.stream.getTracks().forEach(e=>{e.stop()}),this.stream=null,e()))}async signalingTerminate(){await this.stopStream();for(const e of Object.keys(this.dataChannels)){const n=this.dataChannels[e];n&&n.close(),delete this.dataChannels[e]}this.ws&&(this.ws.close(),this.ws=null),this.pc&&this.pc.close(),this.e2ee&&this.e2ee.terminateWorker(),this.initializeConnection()}async abendPeerConnectionState(e){this.clearMonitorIceConnectionStateChange(),await this.stopStream(),this.pc&&(this.pc.ondatachannel=null,this.pc.oniceconnectionstatechange=null,this.pc.onicegatheringstatechange=null,this.pc.onconnectionstatechange=null),this.ws&&(this.ws.onclose=()=>{this.writeWebSocketTimelineLog("onclose")},this.ws.onmessage=null,this.ws.onerror=null);for(const n of Object.keys(this.dataChannels)){const e=this.dataChannels[n];e&&(e.onclose=e=>{const n=e.currentTarget;this.writeDataChannelTimelineLog("onclose",n),this.trace("CLOSE DATA CHANNEL",n.label)},e.onmessage=null,e.onerror=null)}for(const n of Object.keys(this.dataChannels)){const e=this.dataChannels[n];e&&e.close(),delete this.dataChannels[n]}this.ws&&(this.ws.close(),this.ws=null),this.pc&&this.pc.close(),this.e2ee&&this.e2ee.terminateWorker(),this.initializeConnection();const n=this.soraCloseEvent("abend",e);this.callbacks.disconnect(n),this.writeSoraTimelineLog("disconnect-abend",n)}async abend(e,n){this.clearMonitorIceConnectionStateChange(),await this.stopStream(),this.pc&&(this.pc.ondatachannel=null,this.pc.oniceconnectionstatechange=null,this.pc.onicegatheringstatechange=null,this.pc.onconnectionstatechange=null),this.ws&&(this.ws.onclose=()=>{this.writeWebSocketTimelineLog("onclose")},this.ws.onmessage=null,this.ws.onerror=null);for(const i of Object.keys(this.dataChannels)){const e=this.dataChannels[i];e&&(e.onclose=e=>{const n=e.currentTarget;this.writeDataChannelTimelineLog("onclose",n),this.trace("CLOSE DATA CHANNEL",n.label)},e.onmessage=null,e.onerror=null)}try{await this.disconnectDataChannel(e)}catch(e){}await this.disconnectWebSocket(e),await this.disconnectPeerConnection(),this.e2ee&&this.e2ee.terminateWorker(),this.initializeConnection();const i=this.soraCloseEvent("abend",e,n);this.writeSoraTimelineLog("disconnect-abend",i),this.callbacks.disconnect(this.soraCloseEvent("abend",e,n))}initializeConnection(){this.clientId=null,this.connectionId=null,this.remoteConnectionIds=[],this.stream=null,this.ws=null,this.pc=null,this.encodings=[],this.authMetadata=null,this.e2ee=null,this.dataChannels={},this.mids={audio:"",video:""},this.signalingSwitched=!1,this.clearConnectionTimeout()}disconnectWebSocket(e){let n=0;return this.signalingSwitched?(this.ws&&(this.ws.close(),this.ws=null),Promise.resolve(null)):new Promise(i=>{if(!this.ws)return i(null);if(this.ws.onclose=e=>(this.ws&&(this.ws.close(),this.ws=null),clearTimeout(n),this.writeWebSocketTimelineLog("onclose",{code:e.code,reason:e.reason}),i({code:e.code,reason:e.reason})),1===this.ws.readyState){const i={type:"disconnect",reason:e};this.ws.send(JSON.stringify(i)),this.writeWebSocketSignalingLog("send-disconnect",i),n=setTimeout(()=>{this.ws&&(this.ws.close(),this.ws=null)},this.disconnectWaitTimeout)}else return this.ws.close(),this.ws=null,i(null)})}disconnectDataChannel(e){const n=()=>{for(const e of Object.keys(this.dataChannels)){const n=this.dataChannels[e];n&&n.close(),delete this.dataChannels[e]}};return new Promise((i,g)=>{if(!this.dataChannels.signaling)return n(),i();const t=setTimeout(()=>(n(),g()),this.disconnectWaitTimeout),a=[];for(const e of Object.keys(this.dataChannels)){const g=this.dataChannels[e];if(g){g.onerror=()=>{clearTimeout(t),n(),i()};a.push((()=>new Promise((e,n)=>{g.onerror=()=>{n()},g.onclose=n=>{const i=n.currentTarget;this.writeDataChannelTimelineLog("onclose",i),this.trace("CLOSE DATA CHANNEL",i.label),e()}}))())}}Promise.all(a).then(()=>{i()}).finally(()=>{n(),clearTimeout(t)});const l={type:"disconnect",reason:e};if(!0===this.dataChannelsCompress.signaling){const e=new TextEncoder().encode(JSON.stringify(l)),n=o(e,{});if("open"===this.dataChannels.signaling.readyState)try{this.dataChannels.signaling.send(n),this.writeDataChannelSignalingLog("send-disconnect",this.dataChannels.signaling,l)}catch(n){const e=n.message;this.writeDataChannelSignalingLog("failed-to-send-disconnect",this.dataChannels.signaling,e)}}else if("open"===this.dataChannels.signaling.readyState)try{this.dataChannels.signaling.send(JSON.stringify(l)),this.writeDataChannelSignalingLog("send-disconnect",this.dataChannels.signaling,l)}catch(n){const e=n.message;this.writeDataChannelSignalingLog("failed-to-send-disconnect",this.dataChannels.signaling,e)}})}disconnectPeerConnection(){return new Promise(e=>(this.pc&&"closed"!==this.pc.connectionState&&this.pc.close(),e()))}async disconnect(){this.clearMonitorIceConnectionStateChange(),await this.stopStream(),this.pc&&(this.pc.ondatachannel=null,this.pc.oniceconnectionstatechange=null,this.pc.onicegatheringstatechange=null,this.pc.onconnectionstatechange=null),this.ws&&(this.ws.onclose=()=>{this.writeWebSocketTimelineLog("onclose")},this.ws.onmessage=null,this.ws.onerror=null);for(const e of Object.keys(this.dataChannels)){const n=this.dataChannels[e];n&&(n.onmessage=null)}let e=null;if(this.signalingSwitched){e=this.soraCloseEvent("normal","DISCONNECT",{code:4999,reason:""});try{await this.disconnectDataChannel("NO-ERROR")}catch(n){e=this.soraCloseEvent("abend","DISCONNECT-TIMEOUT")}await this.disconnectWebSocket("NO-ERROR"),await this.disconnectPeerConnection()}else{const n=await this.disconnectWebSocket("NO-ERROR");await this.disconnectPeerConnection(),null!==n&&(e=this.soraCloseEvent("normal","DISCONNECT",n))}this.e2ee&&this.e2ee.terminateWorker(),this.initializeConnection(),e&&(this.writeSoraTimelineLog("disconnect-normal",e),this.callbacks.disconnect(e))}setupE2EE(){!0===this.options.e2ee&&(this.e2ee=new p,this.e2ee.onWorkerDisconnect=async()=>{await this.abend("INTERNAL-ERROR",{reason:"CRASH-E2EE-WORKER"})},this.e2ee.startWorker())}startE2EE(){if(!0===this.options.e2ee&&this.e2ee){if(!this.connectionId){const e=new Error;throw e.message=`E2EE failed. Self connectionId is null`,e}this.e2ee.clearWorker();const e=this.e2ee.start(this.connectionId);this.e2ee.postSelfSecretKeyMaterial(this.connectionId,e.selfKeyId,e.selfSecretKeyMaterial)}}signaling(e){return this.trace("CREATE OFFER",e),new Promise((n,i)=>{null===this.ws&&(this.ws=new WebSocket(this.signalingUrl),this.writeWebSocketSignalingLog("new-websocket",this.signalingUrl)),this.ws.binaryType="arraybuffer",this.ws.onclose=async e=>{const n=new Ae(`Signaling failed. CloseEventCode:${e.code} CloseEventReason:'${e.reason}'`);n.code=e.code,n.reason=e.reason,this.writeWebSocketTimelineLog("onclose",n),await this.signalingTerminate(),i(n)},this.ws.onopen=async()=>{this.writeWebSocketSignalingLog("onopen");let n;try{n=s(e.sdp||"",this.role,this.channelId,this.metadata,this.options)}catch(e){return void i(e)}if(n.e2ee&&this.e2ee){const e=await this.e2ee.init();n.signaling_notify_metadata.pre_key_bundle=e}this.trace("SIGNALING CONNECT MESSAGE",n),this.ws&&(this.ws.send(JSON.stringify(n)),this.writeWebSocketSignalingLog(`send-${n.type}`,n))},this.ws.onmessage=async e=>{if(e.data instanceof ArrayBuffer)return this.writeWebSocketSignalingLog("onmessage-e2ee",e.data),void this.signalingOnMessageE2EE(e.data);const i=JSON.parse(e.data);"offer"==i.type?(this.writeWebSocketSignalingLog("onmessage-offer",i),this.signalingOnMessageTypeOffer(i),n(i)):"update"==i.type?(this.writeWebSocketSignalingLog("onmessage-update",i),await this.signalingOnMessageTypeUpdate(i)):"re-offer"==i.type?(this.writeWebSocketSignalingLog("onmessage-re-offer",i),await this.signalingOnMessageTypeReOffer(i)):"ping"==i.type?await this.signalingOnMessageTypePing(i):"push"==i.type?this.callbacks.push(i,"websocket"):"notify"==i.type?("connection.created"===i.event_type?this.writeWebSocketTimelineLog("notify-connection.created",i):"connection.destroyed"===i.event_type&&this.writeWebSocketTimelineLog("notify-connection.destroyed",i),this.signalingOnMessageTypeNotify(i,"websocket")):"switched"==i.type&&(this.writeWebSocketSignalingLog("onmessage-switched",i),this.signalingOnMessageTypeSwitched(i))}})}async createOffer(){const e=new window.RTCPeerConnection({iceServers:[]});if(C()){e.addTransceiver("video",{direction:"recvonly"}),e.addTransceiver("audio",{direction:"recvonly"});const n=await e.createOffer();return e.close(),this.writePeerConnectionTimelineLog("create-offer",n),n}const n=await e.createOffer({offerToReceiveAudio:!0,offerToReceiveVideo:!0});return e.close(),this.writePeerConnectionTimelineLog("create-offer",n),n}async connectPeerConnection(e){let n=Object.assign({},e.config);if(this.e2ee&&(n=Object.assign({encodedInsertableStreams:!0},n)),void 0!==window.RTCPeerConnection.generateCertificate){const e=await window.RTCPeerConnection.generateCertificate({name:"ECDSA",namedCurve:"P-256"});n=Object.assign({certificates:[e]},n)}return this.trace("PEER CONNECTION CONFIG",n),this.writePeerConnectionTimelineLog("new-peerconnection",n),this.pc=new window.RTCPeerConnection(n,this.constraints),this.pc.oniceconnectionstatechange=()=>{this.pc&&(this.writePeerConnectionTimelineLog("oniceconnectionstatechange",{connectionState:this.pc.connectionState,iceConnectionState:this.pc.iceConnectionState,iceGatheringState:this.pc.iceGatheringState}),this.trace("ONICECONNECTIONSTATECHANGE ICECONNECTIONSTATE",this.pc.iceConnectionState))},this.pc.onicegatheringstatechange=()=>{this.pc&&this.writePeerConnectionTimelineLog("onicegatheringstatechange",{connectionState:this.pc.connectionState,iceConnectionState:this.pc.iceConnectionState,iceGatheringState:this.pc.iceGatheringState})},this.pc.onconnectionstatechange=()=>{this.pc&&this.writePeerConnectionTimelineLog("onconnectionstatechange",{connectionState:this.pc.connectionState,iceConnectionState:this.pc.iceConnectionState,iceGatheringState:this.pc.iceGatheringState})},void(this.pc.ondatachannel=e=>{this.onDataChannel(e)})}async setRemoteDescription(e){if(this.pc){const n=new RTCSessionDescription({type:"offer",sdp:e.sdp});return await this.pc.setRemoteDescription(n),void this.writePeerConnectionTimelineLog("set-remote-description",n)}}async createAnswer(e){if(this.pc){for(const e of Object.values(this.mids)){const n=this.pc.getTransceivers().find(n=>n.mid===e);n&&"recvonly"===n.direction&&(n.direction="sendrecv")}if(this.options.simulcast&&("sendrecv"===this.role||"sendonly"===this.role)){const n=this.pc.getTransceivers().find(e=>{if(e.mid&&0<=e.mid.indexOf("video")&&null!==e.sender.track&&(null===e.currentDirection||"sendonly"===e.currentDirection))return e});if(n){await this.setSenderParameters(n,this.encodings),await this.setRemoteDescription(e),this.trace("TRANSCEIVER SENDER GET_PARAMETERS",n.sender.getParameters()),await this.setSenderParameters(n,this.encodings);const i=await this.pc.createAnswer();return await this.pc.setLocalDescription(i),void this.trace("TRANSCEIVER SENDER GET_PARAMETERS",n.sender.getParameters())}}const n=await this.pc.createAnswer();return this.writePeerConnectionTimelineLog("create-answer",n),await this.pc.setLocalDescription(n),void this.writePeerConnectionTimelineLog("set-local-description",n)}}sendAnswer(){if(this.pc&&this.ws&&this.pc.localDescription){this.trace("ANSWER SDP",this.pc.localDescription.sdp);const e={type:"answer",sdp:this.pc.localDescription.sdp};this.ws.send(JSON.stringify(e)),this.writeWebSocketSignalingLog("send-answer",e)}}onIceCandidate(){return new Promise(e=>{this.pc&&(this.pc.oniceconnectionstatechange=()=>{this.pc&&(this.writePeerConnectionTimelineLog("oniceconnectionstatechange",{connectionState:this.pc.connectionState,iceConnectionState:this.pc.iceConnectionState,iceGatheringState:this.pc.iceGatheringState}),this.trace("ONICECONNECTIONSTATECHANGE ICECONNECTIONSTATE",this.pc.iceConnectionState),"connected"===this.pc.iceConnectionState&&e())},this.pc.onicecandidate=n=>{if(this.writePeerConnectionTimelineLog("onicecandidate",n.candidate),this.pc&&this.trace("ONICECANDIDATE ICEGATHERINGSTATE",this.pc.iceGatheringState),null===n.candidate)e();else{const e=n.candidate.toJSON(),i=Object.assign(e,{type:"candidate"});this.trace("ONICECANDIDATE CANDIDATE MESSAGE",i),this.sendMessage(i)}})})}waitChangeConnectionStateConnected(){return new Promise((e,n)=>{if(this.pc&&void 0===this.pc.connectionState)return void e();const i=setInterval(()=>{if(!this.pc){const e=new Error;e.message="PeerConnection connectionState did not change to 'connected'",clearInterval(i),n(e)}else this.pc&&"connected"===this.pc.connectionState&&(clearInterval(i),e())},10)})}monitorSignalingWebSocketEvent(){return new Promise((e,n)=>{this.monitorSignalingWebSocketEventTimerId=setInterval(()=>{this.ws&&(this.clearMonitorSignalingWebSocketEvent(),this.ws.onclose=async e=>{const i=new Ae(`Signaling failed. CloseEventCode:${e.code} CloseEventReason:'${e.reason}'`);i.code=e.code,i.reason=e.reason,this.writeWebSocketTimelineLog("onclose",i),await this.signalingTerminate(),n(i)},this.ws.onerror=async()=>{const e=new Ae(`Signaling failed. WebSocket onerror was called`);this.writeWebSocketSignalingLog("onerror",e),await this.signalingTerminate(),n(e)})},100)})}monitorWebSocketEvent(){this.ws&&(this.ws.onclose=async e=>{this.writeWebSocketTimelineLog("onclose"),1e3===e.code||1005===e.code?await this.disconnect():await this.abend("WEBSOCKET-ONCLOSE",{code:e.code,reason:e.reason})},this.ws.onerror=async()=>{this.writeWebSocketSignalingLog("onerror"),await this.abend("WEBSOCKET-ONERROR")})}monitorPeerConnectionState(){this.pc&&(this.pc.oniceconnectionstatechange=async()=>{this.pc&&this.pc.connectionState===void 0&&(this.writePeerConnectionTimelineLog("oniceconnectionstatechange",{connectionState:this.pc.connectionState,iceConnectionState:this.pc.iceConnectionState,iceGatheringState:this.pc.iceGatheringState}),this.trace("ONICECONNECTIONSTATECHANGE ICECONNECTIONSTATE",this.pc.iceConnectionState),clearTimeout(this.monitorIceConnectionStateChangeTimerId),"failed"===this.pc.iceConnectionState?await this.abendPeerConnectionState("ICE-CONNECTION-STATE-FAILED"):"disconnected"===this.pc.iceConnectionState&&(this.monitorIceConnectionStateChangeTimerId=setTimeout(async()=>{this.pc&&"disconnected"===this.pc.iceConnectionState&&(await this.abendPeerConnectionState("ICE-CONNECTION-STATE-DISCONNECTED-TIMEOUT"))},1e4)))},this.pc.onconnectionstatechange=async()=>{this.pc&&(this.writePeerConnectionTimelineLog("onconnectionstatechange",{connectionState:this.pc.connectionState,iceConnectionState:this.pc.iceConnectionState,iceGatheringState:this.pc.iceGatheringState}),"failed"===this.pc.connectionState&&(await this.abendPeerConnectionState("CONNECTION-STATE-FAILED")))})}setConnectionTimeout(){return new Promise((e,n)=>{0{if(!this.pc||this.pc&&this.pc.connectionState!==void 0&&"connected"!==this.pc.connectionState){const e=new Error;e.message="Signaling connection timeout",this.callbacks.timeout(),this.trace("DISCONNECT","Signaling connection timeout"),this.writePeerConnectionTimelineLog("signaling-connection-timeout",{connectionTimeout:this.connectionTimeout}),await this.signalingTerminate(),n(e)}},this.connectionTimeout))})}clearConnectionTimeout(){clearTimeout(this.connectionTimeoutTimerId)}clearMonitorSignalingWebSocketEvent(){clearInterval(this.monitorSignalingWebSocketEventTimerId)}clearMonitorIceConnectionStateChange(){clearInterval(this.monitorIceConnectionStateChangeTimerId)}trace(e,n){this.callbacks.log(e,n);this.debug&&A(this.clientId,e,n)}writeWebSocketSignalingLog(e,n){this.callbacks.signaling(Z(e,n,"websocket")),this.writeWebSocketTimelineLog(e,n)}writeDataChannelSignalingLog(e,n,i){this.callbacks.signaling(Z(e,i,"datachannel")),this.writeDataChannelTimelineLog(e,n,i)}writeWebSocketTimelineLog(e,n){const i=b(e,n,"websocket");this.callbacks.timeline(i)}writeDataChannelTimelineLog(e,n,i){const g=b(e,i,"datachannel",n.id,n.label);this.callbacks.timeline(g)}writePeerConnectionTimelineLog(e,n){const i=b(e,n,"peerconnection");this.callbacks.timeline(i)}writeSoraTimelineLog(e,n){const i=b(e,n,"sora");this.callbacks.timeline(i)}signalingOnMessageE2EE(e){if(this.e2ee){const n=new Uint8Array(e),i=this.e2ee.receiveMessage(n);this.e2ee.postRemoteSecretKeyMaterials(i),i.messages.forEach(e=>{this.sendE2EEMessage(e.buffer)})}}signalingOnMessageTypeOffer(e){if(this.clientId=e.client_id,this.connectionId=e.connection_id,void 0!==e.metadata&&(this.authMetadata=e.metadata),Array.isArray(e.encodings)&&(this.encodings=e.encodings),void 0!==e.mid&&void 0!==e.mid.audio&&(this.mids.audio=e.mid.audio),void 0!==e.mid&&void 0!==e.mid.video&&(this.mids.video=e.mid.video),e.data_channels)for(const n of e.data_channels)this.dataChannelsCompress[n.label]=n.compress;this.trace("SIGNALING OFFER MESSAGE",e),this.trace("OFFER SDP",e.sdp)}sendUpdateAnswer(){this.pc&&this.ws&&this.pc.localDescription&&(this.trace("ANSWER SDP",this.pc.localDescription.sdp),this.sendMessage({type:"update",sdp:this.pc.localDescription.sdp}))}sendReAnswer(){this.pc&&this.pc.localDescription&&(this.trace("RE ANSWER SDP",this.pc.localDescription.sdp),this.sendMessage({type:"re-answer",sdp:this.pc.localDescription.sdp}))}async signalingOnMessageTypeUpdate(e){this.trace("SIGNALING UPDATE MESSGE",e),this.trace("UPDATE SDP",e.sdp),await this.setRemoteDescription(e),await this.createAnswer(e),this.sendUpdateAnswer()}async signalingOnMessageTypeReOffer(e){this.trace("SIGNALING RE OFFER MESSGE",e),this.trace("RE OFFER SDP",e.sdp),await this.setRemoteDescription(e),await this.createAnswer(e),this.sendReAnswer()}async signalingOnMessageTypePing(e){const n={type:"pong"};if(e.stats){const e=await this.getStats();n.stats=e}this.ws&&this.ws.send(JSON.stringify(n))}signalingOnMessageTypeNotify(e,n){if("connection.created"===e.event_type){const n=e.connection_id;if(this.connectionId!==n){const i=I(e),g=m(i);if(g&&this.e2ee&&n){const e=this.e2ee.startSession(n,g);this.e2ee.postRemoteSecretKeyMaterials(e),e.messages.forEach(e=>{this.sendE2EEMessage(e.buffer)}),this.e2ee.postSelfSecretKeyMaterial(e.selfConnectionId,e.selfKeyId,e.selfSecretKeyMaterial)}}const i=r(e);i.forEach(e=>{const n=I(e),i=m(n),g=e.connection_id;g&&this.e2ee&&i&&this.e2ee.addPreKeyBundle(g,i)})}else if("connection.destroyed"===e.event_type){const n=I(e),i=m(n),g=e.connection_id;if(i&&this.e2ee&&g){const e=this.e2ee.stopSession(g);this.e2ee.postSelfSecretKeyMaterial(e.selfConnectionId,e.selfKeyId,e.selfSecretKeyMaterial,5e3),e.messages.forEach(e=>{this.sendE2EEMessage(e.buffer)}),this.e2ee.postRemoveRemoteDeriveKey(g)}}this.callbacks.notify(e,n)}signalingOnMessageTypeSwitched(e){this.signalingSwitched=!0;!this.ws||e.ignore_disconnect_websocket&&(this.ws&&(this.ws.onclose=null,this.ws.close(),this.ws=null),this.writeWebSocketSignalingLog("close"))}async setSenderParameters(e,n){const i=e.sender.getParameters();return i.encodings=n,await e.sender.setParameters(i),this.trace("TRANSCEIVER SENDER SET_PARAMETERS",i),void this.writePeerConnectionTimelineLog("transceiver-sender-set-parameters",i)}async getStats(){const e=[];if(!this.pc)return e;const n=await this.pc.getStats();return n.forEach(n=>{e.push(n)}),e}onDataChannel(e){const n=e.channel;this.writeDataChannelTimelineLog("ondatachannel",n,u(n)),e.channel.onbufferedamountlow=e=>{const n=e.currentTarget;this.writeDataChannelTimelineLog("onbufferedamountlow",n)},e.channel.onopen=e=>{const n=e.currentTarget;n.bufferedAmountLowThreshold=65536,n.binaryType="arraybuffer",this.dataChannels[n.label]=n,this.trace("OPEN DATA CHANNEL",n.label),"signaling"===n.label&&this.ws?this.writeDataChannelSignalingLog("onopen",n):this.writeDataChannelTimelineLog("onopen",n)},e.channel.onclose=async e=>{const n=e.currentTarget;this.writeDataChannelTimelineLog("onclose",n),this.trace("CLOSE DATA CHANNEL",n.label),await this.disconnect()},e.channel.onerror=async e=>{const n=e.currentTarget;this.writeDataChannelTimelineLog("onerror",n),this.trace("ERROR DATA CHANNEL",n.label),await this.abend("DATA-CHANNEL-ONERROR",{label:n.label})},"signaling"===e.channel.label?e.channel.onmessage=async e=>{const n=e.currentTarget;let i=e.data;if(!0===this.dataChannelsCompress.signaling){const n=l(new Uint8Array(e.data));i=new TextDecoder().decode(n)}const g=JSON.parse(i);this.writeDataChannelSignalingLog(`onmessage-${g.type}`,n,g),"re-offer"===g.type&&(await this.signalingOnMessageTypeReOffer(g))}:"notify"===e.channel.label?e.channel.onmessage=e=>{const n=e.currentTarget;let i=e.data;if(!0===this.dataChannelsCompress.notify){const n=l(new Uint8Array(e.data));i=new TextDecoder().decode(n)}const g=JSON.parse(i);"connection.created"===g.event_type?this.writeDataChannelTimelineLog("notify-connection.created",n,g):"connection.destroyed"===g.event_type&&this.writeDataChannelTimelineLog("notify-connection.destroyed",n,g),this.signalingOnMessageTypeNotify(g,"datachannel")}:"push"===e.channel.label?e.channel.onmessage=e=>{let n=e.data;if(!0===this.dataChannelsCompress.push){const i=l(new Uint8Array(e.data));n=new TextDecoder().decode(i)}const i=JSON.parse(n);this.callbacks.push(i,"datachannel")}:"e2ee"===e.channel.label?e.channel.onmessage=e=>{const n=e.currentTarget,i=e.data;this.signalingOnMessageE2EE(i),this.writeDataChannelSignalingLog("onmessage-e2ee",n,i)}:"stats"===e.channel.label&&(e.channel.onmessage=async e=>{let n=e.data;if(!0===this.dataChannelsCompress.stats){const i=l(new Uint8Array(e.data));n=new TextDecoder().decode(i)}const i=JSON.parse(n);if("req-stats"===i.type){const e=await this.getStats();this.sendStatsMessage(e)}})}sendMessage(e){if(this.dataChannels.signaling){if(!0===this.dataChannelsCompress.signaling){const n=new TextEncoder().encode(JSON.stringify(e)),i=o(n,{});this.dataChannels.signaling.send(i)}else this.dataChannels.signaling.send(JSON.stringify(e));this.callbacks.signaling(Z(`send-${e.type}`,e,"datachannel"))}else null!==this.ws&&(this.ws.send(JSON.stringify(e)),this.callbacks.signaling(Z(`send-${e.type}`,e,"websocket")))}sendE2EEMessage(e){this.dataChannels.e2ee?(this.dataChannels.e2ee.send(e),this.writeDataChannelSignalingLog("send-e2ee",this.dataChannels.e2ee,e)):null!==this.ws&&(this.ws.send(e),this.writeWebSocketSignalingLog("send-e2ee",e))}sendStatsMessage(e){if(this.dataChannels.stats){const n={type:"stats",reports:e};if(!0===this.dataChannelsCompress.stats){const e=new TextEncoder().encode(JSON.stringify(n)),i=o(e,{});this.dataChannels.stats.send(i)}else this.dataChannels.stats.send(JSON.stringify(n))}}getAudioTransceiver(){if(this.pc&&this.mids.audio){const e=this.pc.getTransceivers().find(e=>e.mid===this.mids.audio);return e||null}return null}getVideoTransceiver(){if(this.pc&&this.mids.video){const e=this.pc.getTransceivers().find(e=>e.mid===this.mids.video);return e||null}return null}soraCloseEvent(e,n,i){const g=class extends Event{constructor(e,n,i){super(e),i&&(i.code&&(this.code=i.code),i.reason&&(this.reason=i.reason),i.params&&(this.params=i.params)),this.title=n}};return new g(e,n,i)}get e2eeSelfFingerprint(){return this.options.e2ee&&this.e2ee?this.e2ee.selfFingerprint():void 0}get e2eeRemoteFingerprints(){return this.options.e2ee&&this.e2ee?this.e2ee.remoteFingerprints():void 0}get audio(){return null!==this.getAudioTransceiver()}get video(){return null!==this.getVideoTransceiver()}}class ue extends Ze{async connect(e){return this.options.multistream?await Promise.race([this.multiStream(e).finally(()=>{this.clearConnectionTimeout(),this.clearMonitorSignalingWebSocketEvent()}),this.setConnectionTimeout(),this.monitorSignalingWebSocketEvent()]):await Promise.race([this.singleStream(e).finally(()=>{this.clearConnectionTimeout(),this.clearMonitorSignalingWebSocketEvent()}),this.setConnectionTimeout(),this.monitorSignalingWebSocketEvent()]),this.monitorWebSocketEvent(),this.monitorPeerConnectionState(),e}async singleStream(e){await this.disconnect(),this.setupE2EE();const n=await this.createOffer(),i=await this.signaling(n);return this.startE2EE(),await this.connectPeerConnection(i),await this.setRemoteDescription(i),e.getTracks().forEach(n=>{this.pc&&this.pc.addTrack(n,e)}),this.stream=e,await this.createAnswer(i),this.sendAnswer(),this.pc&&this.e2ee&&this.pc.getSenders().forEach(e=>{this.e2ee&&this.e2ee.setupSenderTransform(e)}),await this.onIceCandidate(),await this.waitChangeConnectionStateConnected(),e}async multiStream(e){await this.disconnect(),this.setupE2EE();const n=await this.createOffer(),i=await this.signaling(n);return this.startE2EE(),await this.connectPeerConnection(i),this.pc&&(this.pc.ontrack=e=>{this.writePeerConnectionTimelineLog("ontrack");const n=e.streams[0];n&&"default"!==n.id&&n.id!==this.connectionId&&(this.e2ee&&this.e2ee.setupReceiverTransform(e.receiver),this.callbacks.track(e),n.onremovetrack=e=>{if(this.callbacks.removetrack(e),e.target){const n=this.remoteConnectionIds.indexOf(e.target.id);-1{this.pc&&this.pc.addTrack(n,e)}),this.stream=e,await this.createAnswer(i),this.sendAnswer(),this.pc&&this.e2ee&&this.pc.getSenders().forEach(e=>{this.e2ee&&this.e2ee.setupSenderTransform(e)}),await this.onIceCandidate(),await this.waitChangeConnectionStateConnected(),e}}class be extends Ze{async connect(){if(this.options.multistream)return await Promise.race([this.multiStream().finally(()=>{this.clearConnectionTimeout(),this.clearMonitorSignalingWebSocketEvent()}),this.setConnectionTimeout(),this.monitorSignalingWebSocketEvent()]),this.monitorWebSocketEvent(),void this.monitorPeerConnectionState();else{const e=await Promise.race([this.singleStream().finally(()=>{this.clearConnectionTimeout(),this.clearMonitorSignalingWebSocketEvent()}),this.setConnectionTimeout(),this.monitorSignalingWebSocketEvent()]);return this.monitorWebSocketEvent(),this.monitorPeerConnectionState(),e}}async singleStream(){await this.disconnect(),this.setupE2EE();const e=await this.createOffer(),n=await this.signaling(e);return this.startE2EE(),await this.connectPeerConnection(n),this.pc&&(this.pc.ontrack=e=>{this.writePeerConnectionTimelineLog("ontrack"),this.stream=e.streams[0];const n=this.stream.id;"default"!==n&&(this.e2ee&&this.e2ee.setupReceiverTransform(e.receiver),this.callbacks.track(e),this.stream.onremovetrack=e=>{if(this.callbacks.removetrack(e),e.target){const n=this.remoteConnectionIds.indexOf(e.target.id);-1{this.writePeerConnectionTimelineLog("ontrack");const n=e.streams[0];"default"!==n.id&&n.id!==this.connectionId&&(this.e2ee&&this.e2ee.setupReceiverTransform(e.receiver),this.callbacks.track(e),n.onremovetrack=e=>{if(this.callbacks.removetrack(e),e.target){const n=this.remoteConnectionIds.indexOf(e.target.id);-1{if("undefined"!=typeof global);else if("undefined"!=typeof window)window.global=window;else if("undefined"!=typeof self)self.global=self;else throw new Error("cannot export Go (neither global, window nor self is defined)");if(global.require||"undefined"==typeof require||(global.require=require),!global.fs&&global.require){const e=require("fs");0!==Object.keys(e)&&(global.fs=e)}const e=()=>{const e=new Error("not implemented");return e.code="ENOSYS",e};if(!global.fs){let n="";global.fs={constants:{O_WRONLY:-1,O_RDWR:-1,O_CREAT:-1,O_TRUNC:-1,O_APPEND:-1,O_EXCL:-1},writeSync(e,t){n+=i.decode(t);const g=n.lastIndexOf("\n");return-1!=g&&(console.log(n.substr(0,g)),n=n.substr(g+1)),t.length},write(i,t,g,a,o,l){if(0!==g||a!==t.length||null!==o)return void l(e());const c=this.writeSync(i,t);l(null,c)},chmod(n,i,t){t(e())},chown(n,i,t,g){g(e())},close(n,i){i(e())},fchmod(n,i,t){t(e())},fchown(n,i,t,g){g(e())},fstat(n,i){i(e())},fsync(e,n){n(null)},ftruncate(n,i,t){t(e())},lchown(n,i,t,g){g(e())},link(n,i,t){t(e())},lstat(n,i){i(e())},mkdir(n,i,t){t(e())},open(n,i,t,g){g(e())},read(n,i,t,g,a,o){o(e())},readdir(n,i){i(e())},readlink(n,i){i(e())},rename(n,i,t){t(e())},rmdir(n,i){i(e())},stat(n,i){i(e())},symlink(n,i,t){t(e())},truncate(n,i,t){t(e())},unlink(n,i){i(e())},utimes(n,i,t,g){g(e())}}}if(global.process||(global.process={getuid(){return-1},getgid(){return-1},geteuid(){return-1},getegid(){return-1},getgroups(){throw e()},pid:-1,ppid:-1,umask(){throw e()},cwd(){throw e()},chdir(){throw e()}}),!global.crypto){const e=require("crypto");global.crypto={getRandomValues(n){e.randomFillSync(n)}}}global.performance||(global.performance={now(){const[e,n]=process.hrtime();return 1e3*e+n/1e6}}),global.TextEncoder||(global.TextEncoder=require("util").TextEncoder),global.TextDecoder||(global.TextDecoder=require("util").TextDecoder);const n=new TextEncoder("utf-8"),i=new TextDecoder("utf-8");if(global.Go=class{constructor(){this.argv=["js"],this.env={},this.exit=e=>{0!==e&&console.warn("exit code:",e)},this._exitPromise=new Promise(e=>{this._resolveExitPromise=e}),this._pendingEvent=null,this._scheduledTimeouts=new Map,this._nextCallbackTimeoutID=1;const e=(e,n)=>{var i=Math.floor;this.mem.setUint32(e+0,n,!0),this.mem.setUint32(e+4,i(n/4294967296),!0)},t=e=>{const n=this.mem.getUint32(e+0,!0),i=this.mem.getInt32(e+4,!0);return n+4294967296*i},g=e=>{const n=this.mem.getFloat64(e,!0);if(0!==n){if(!isNaN(n))return n;const i=this.mem.getUint32(e,!0);return this._values[i]}},a=(e,n)=>{if("number"==typeof n&&0!==n)return isNaN(n)?(this.mem.setUint32(e+4,2146959360,!0),void this.mem.setUint32(e,0,!0)):void this.mem.setFloat64(e,n,!0);if(void 0===n)return void this.mem.setFloat64(e,0,!0);let i=this._ids.get(n);void 0===i&&(i=this._idPool.pop(),void 0===i&&(i=this._values.length),this._values[i]=n,this._goRefCounts[i]=0,this._ids.set(n,i)),this._goRefCounts[i]++;let t=0;switch(typeof n){case"object":null!==n&&(t=1);break;case"string":t=2;break;case"symbol":t=3;break;case"function":t=4;}this.mem.setUint32(e+4,2146959360|t,!0),this.mem.setUint32(e,i,!0)},o=e=>{const n=t(e+0),i=t(e+8);return new Uint8Array(this._inst.exports.mem.buffer,n,i)},l=e=>{const n=t(e+0),o=t(e+8),l=Array(o);for(let t=0;t{const n=t(e+0),g=t(e+8);return i.decode(new DataView(this._inst.exports.mem.buffer,n,g))},d=Date.now()-performance.now();this.importObject={go:{"runtime.wasmExit":e=>{const n=this.mem.getInt32(e+8,!0);this.exited=!0,delete this._inst,delete this._values,delete this._goRefCounts,delete this._ids,delete this._idPool,this.exit(n)},"runtime.wasmWrite":e=>{const i=t(e+8),g=t(e+16),a=this.mem.getInt32(e+24,!0);fs.writeSync(i,new Uint8Array(this._inst.exports.mem.buffer,g,a))},"runtime.resetMemoryDataView":()=>{this.mem=new DataView(this._inst.exports.mem.buffer)},"runtime.nanotime1":n=>{e(n+8,1e6*(d+performance.now()))},"runtime.walltime1":n=>{const i=new Date().getTime();e(n+8,i/1e3),this.mem.setInt32(n+16,1e6*(i%1e3),!0)},"runtime.scheduleTimeoutEvent":e=>{const n=this._nextCallbackTimeoutID;this._nextCallbackTimeoutID++,this._scheduledTimeouts.set(n,setTimeout(()=>{for(this._resume();this._scheduledTimeouts.has(n);)console.warn("scheduleTimeoutEvent: missed timeout event"),this._resume()},t(e+8)+1)),this.mem.setInt32(e+16,n,!0)},"runtime.clearTimeoutEvent":e=>{const n=this.mem.getInt32(e+8,!0);clearTimeout(this._scheduledTimeouts.get(n)),this._scheduledTimeouts.delete(n)},"runtime.getRandomData":e=>{crypto.getRandomValues(o(e+8))},"syscall/js.finalizeRef":e=>{const n=this.mem.getUint32(e+8,!0);if(this._goRefCounts[n]--,0===this._goRefCounts[n]){const e=this._values[n];this._values[n]=null,this._ids.delete(e),this._idPool.push(n)}},"syscall/js.stringVal":e=>{a(e+24,c(e+8))},"syscall/js.valueGet":e=>{const n=Reflect.get(g(e+8),c(e+16));e=this._inst.exports.getsp(),a(e+32,n)},"syscall/js.valueSet":e=>{Reflect.set(g(e+8),c(e+16),g(e+32))},"syscall/js.valueDelete":e=>{Reflect.deleteProperty(g(e+8),c(e+16))},"syscall/js.valueIndex":e=>{a(e+24,Reflect.get(g(e+8),t(e+16)))},"syscall/js.valueSetIndex":e=>{Reflect.set(g(e+8),t(e+16),g(e+24))},"syscall/js.valueCall":e=>{try{const n=g(e+8),i=Reflect.get(n,c(e+16)),t=l(e+32),o=Reflect.apply(i,n,t);e=this._inst.exports.getsp(),a(e+56,o),this.mem.setUint8(e+64,1)}catch(n){a(e+56,n),this.mem.setUint8(e+64,0)}},"syscall/js.valueInvoke":e=>{try{const n=g(e+8),i=l(e+16),t=Reflect.apply(n,void 0,i);e=this._inst.exports.getsp(),a(e+40,t),this.mem.setUint8(e+48,1)}catch(n){a(e+40,n),this.mem.setUint8(e+48,0)}},"syscall/js.valueNew":e=>{try{const n=g(e+8),i=l(e+16),t=Reflect.construct(n,i);e=this._inst.exports.getsp(),a(e+40,t),this.mem.setUint8(e+48,1)}catch(n){a(e+40,n),this.mem.setUint8(e+48,0)}},"syscall/js.valueLength":n=>{e(n+16,parseInt(g(n+8).length))},"syscall/js.valuePrepareString":i=>{const t=n.encode(g(i+8)+"");a(i+16,t),e(i+24,t.length)},"syscall/js.valueLoadString":e=>{const n=g(e+8);o(e+16).set(n)},"syscall/js.valueInstanceOf":e=>{this.mem.setUint8(e+24,g(e+8)instanceof g(e+16)?1:0)},"syscall/js.copyBytesToGo":n=>{const i=o(n+8),t=g(n+32);if(!(t instanceof Uint8Array||t instanceof Uint8ClampedArray))return void this.mem.setUint8(n+48,0);const a=t.subarray(0,i.length);i.set(a),e(n+40,a.length),this.mem.setUint8(n+48,1)},"syscall/js.copyBytesToJS":n=>{const i=g(n+8),t=o(n+16);if(!(i instanceof Uint8Array||i instanceof Uint8ClampedArray))return void this.mem.setUint8(n+48,0);const a=t.subarray(0,i.length);i.set(a),e(n+40,a.length),this.mem.setUint8(n+48,1)},debug:e=>{console.log(e)}}}}async run(e){this._inst=e,this.mem=new DataView(this._inst.exports.mem.buffer),this._values=[NaN,0,null,!0,!1,global,this],this._goRefCounts=Array(this._values.length).fill(1/0),this._ids=new Map([[0,1],[null,2],[!0,3],[!1,4],[global,5],[this,6]]),this._idPool=[],this.exited=!1;let i=4096;const t=e=>{const t=i,g=n.encode(e+"\0");return new Uint8Array(this.mem.buffer,i,g.length).set(g),i+=g.length,0!=i%8&&(i+=8-i%8),t},g=this.argv.length,a=[];this.argv.forEach(e=>{a.push(t(e))}),a.push(0);const o=Object.keys(this.env).sort();o.forEach(e=>{a.push(t(`${e}=${this.env[e]}`))}),a.push(0);const l=i;a.forEach(e=>{this.mem.setUint32(i,e,!0),this.mem.setUint32(i+4,0,!0),i+=8}),this._inst.exports.run(g,l),this.exited&&this._resolveExitPromise(),await this._exitPromise}_resume(){if(this.exited)throw new Error("Go program has already exited");this._inst.exports.resume(),this.exited&&this._resolveExitPromise()}_makeFuncWrapper(e){const n=this;return function(){const i={id:e,this:this,args:arguments};return n._pendingEvent=i,n._resume(),i.result}}},global.require&&global.require.main===module&&global.process&&global.process.versions&&!global.process.versions.electron){3>process.argv.length&&(console.error("usage: go_js_wasm_exec [wasm binary] [arguments]"),process.exit(1));const e=new Go;e.argv=process.argv.slice(2),e.env=Object.assign({TMPDIR:require("os").tmpdir()},process.env),e.exit=process.exit,WebAssembly.instantiate(fs.readFileSync(process.argv[2]),e.importObject).then(n=>(process.on("exit",n=>{0!==n||e.exited||(e._pendingEvent={id:0},e._resume())}),e.run(n.instance))).catch(e=>{console.error(e),process.exit(1)})}})()}function o(e,n){n||(n={});var i=ce();i.p(e);var t=de(e,n,2,4);return se(t,n),Ce(t,t.length-4,i.d()),t}function l(e,n){return z((Ie(e),e.subarray(2,-4)),n)}function c(){const e=window.navigator.userAgent.toLocaleLowerCase();if(-1!==e.indexOf("edge"))return"edge";return-1!==e.indexOf("chrome")&&-1===e.indexOf("edge")?"chrome":-1!==e.indexOf("safari")&&-1===e.indexOf("chrome")?"safari":-1===e.indexOf("opera")?-1===e.indexOf("firefox")?null:"firefox":"opera"}function d(){if(!window.RTCRtpSender)return!1;if(!RTCRtpSender.getCapabilities)return!1;const e=RTCRtpSender.getCapabilities("video");if(!e)return!1;const n=e.headerExtensions.map(e=>e.uri),i=["urn:ietf:params:rtp-hdrext:sdes:mid","urn:ietf:params:rtp-hdrext:sdes:rtp-stream-id","urn:ietf:params:rtp-hdrext:sdes:repaired-rtp-stream-id"].every(e=>n.includes(e));return i}function C(){return"safari"===c()}function s(e,n,i,t,g){if("sendrecv"!==n&&"sendonly"!==n&&"recvonly"!==n)throw new Error("Unknown role type");if(null===i||void 0===i)throw new Error("channelId can not be null or undefined");const a={type:"connect",sora_client:"Sora JavaScript SDK 2021.1.3",environment:window.navigator.userAgent,role:n,channel_id:i,sdp:e,audio:!0,video:!0};if(void 0!==t&&(a.metadata=t),"signalingNotifyMetadata"in g&&(a.signaling_notify_metadata=g.signalingNotifyMetadata),"multistream"in g&&!0===g.multistream&&(a.multistream=!0,"spotlight"in g&&(a.spotlight=g.spotlight,"spotlightNumber"in g&&(a.spotlight_number=g.spotlightNumber)),!0===a.spotlight)){const e=["none","r0","r1","r2"];void 0!==g.spotlightFocusRid&&0<=e.indexOf(g.spotlightFocusRid)&&(a.spotlight_focus_rid=g.spotlightFocusRid),void 0!==g.spotlightUnfocusRid&&0<=e.indexOf(g.spotlightUnfocusRid)&&(a.spotlight_unfocus_rid=g.spotlightUnfocusRid)}if("simulcast"in g||"simulcastRid"in g){"simulcast"in g&&!0===g.simulcast&&(a.simulcast=!0);void 0!==g.simulcastRid&&0<=["r0","r1","r2"].indexOf(g.simulcastRid)&&(a.simulcast_rid=g.simulcastRid)}"clientId"in g&&void 0!==g.clientId&&(a.client_id=g.clientId),"dataChannelSignaling"in g&&"boolean"==typeof g.dataChannelSignaling&&(a.data_channel_signaling=g.dataChannelSignaling),"ignoreDisconnectWebSocket"in g&&"boolean"==typeof g.ignoreDisconnectWebSocket&&(a.ignore_disconnect_websocket=g.ignoreDisconnectWebSocket);const o=["audioCodecType","audioBitRate"],l=["audioOpusParamsChannels","audioOpusParamsClockRate","audioOpusParamsMaxplaybackrate","audioOpusParamsStereo","audioOpusParamsSpropStereo","audioOpusParamsMinptime","audioOpusParamsPtime","audioOpusParamsUseinbandfec","audioOpusParamsUsedtx"],c=["videoCodecType","videoBitRate"],C=Object.assign({},g);Object.keys(C).forEach(e=>{"audio"===e&&"boolean"==typeof C[e]||"video"===e&&"boolean"==typeof C[e]||0<=o.indexOf(e)&&null!==C[e]||0<=l.indexOf(e)&&null!==C[e]||0<=c.indexOf(e)&&null!==C[e]||delete C[e]}),void 0!==C.audio&&(a.audio=C.audio);const s=Object.keys(C).some(e=>0<=o.indexOf(e));a.audio&&s&&(a.audio={},"audioCodecType"in C&&(a.audio.codec_type=C.audioCodecType),"audioBitRate"in C&&(a.audio.bit_rate=C.audioBitRate));const I=Object.keys(C).some(e=>0<=l.indexOf(e));a.audio&&I&&("object"!=typeof a.audio&&(a.audio={}),a.audio.opus_params={},"audioOpusParamsChannels"in C&&(a.audio.opus_params.channels=C.audioOpusParamsChannels),"audioOpusParamsClockRate"in C&&(a.audio.opus_params.clock_rate=C.audioOpusParamsClockRate),"audioOpusParamsMaxplaybackrate"in C&&(a.audio.opus_params.maxplaybackrate=C.audioOpusParamsMaxplaybackrate),"audioOpusParamsStereo"in C&&(a.audio.opus_params.stereo=C.audioOpusParamsStereo),"audioOpusParamsSpropStereo"in C&&(a.audio.opus_params.sprop_stereo=C.audioOpusParamsSpropStereo),"audioOpusParamsMinptime"in C&&(a.audio.opus_params.minptime=C.audioOpusParamsMinptime),"audioOpusParamsPtime"in C&&(a.audio.opus_params.ptime=C.audioOpusParamsPtime),"audioOpusParamsUseinbandfec"in C&&(a.audio.opus_params.useinbandfec=C.audioOpusParamsUseinbandfec),"audioOpusParamsUsedtx"in C&&(a.audio.opus_params.usedtx=C.audioOpusParamsUsedtx)),void 0!==C.video&&(a.video=C.video);const r=Object.keys(C).some(e=>0<=c.indexOf(e));if(a.video&&r&&(a.video={},"videoCodecType"in C&&(a.video.codec_type=C.videoCodecType),"videoBitRate"in C&&(a.video.bit_rate=C.videoBitRate)),a.simulcast&&!d()&&"recvonly"!==n)throw new Error("Simulcast can not be used with this browser");if(!0===g.e2ee){if(void 0===a.signaling_notify_metadata&&(a.signaling_notify_metadata={}),null===a.signaling_notify_metadata||"object"!=typeof a.signaling_notify_metadata)throw new Error("E2EE failed. Options signalingNotifyMetadata must be type 'object'");!0===a.video&&(a.video={}),a.video&&(a.video.codec_type="VP8"),a.e2ee=!0}return a}function I(e){if(e.authn_metadata!==void 0)return e.authn_metadata;return void 0===e.metadata?null:e.metadata}function r(e){if(e.data&&Array.isArray(e.data))return e.data;return e.metadata_list&&Array.isArray(e.metadata_list)?e.metadata_list:[]}function m(e){return"object"==typeof e&&null!==e&&"pre_key_bundle"in e?e.pre_key_bundle:null}function A(e,n,i){const t=e=>{if(e&&"object"==typeof e){let n=null;try{n=Object.keys(JSON.parse(JSON.stringify(e)))}catch(e){}n&&Array.isArray(n)?n.forEach(n=>{console.group(n),t(e[n]),console.groupEnd()}):console.info(e)}else console.info(e)};let g="";window.performance&&(g="["+(window.performance.now()/1e3).toFixed(3)+"]"),e&&(g=g+"["+e+"]"),console.info!==void 0&&console.group!==void 0?(console.group(g+" "+n),t(i),console.groupEnd()):console.log(g+" "+n+"\n",i)}function Z(e,n,i){const t=new Event(e);try{t.data=JSON.parse(JSON.stringify(n))}catch(e){t.data=n}return t.transportType=i,t}function u(e){return{binaryType:e.binaryType,bufferedAmount:e.bufferedAmount,bufferedAmountLowThreshold:e.bufferedAmountLowThreshold,id:e.id,label:e.label,maxPacketLifeTime:e.maxPacketLifeTime,maxRetransmits:e.maxRetransmits,negotiated:e.negotiated,ordered:e.ordered,protocol:e.protocol,readyState:e.readyState,reliable:e.reliable}}function b(e,n,i,t,g){const a=new Event(e);try{a.data=JSON.parse(JSON.stringify(n))}catch(e){a.data=n}return a.logType=i,a.dataChannelId=t,a.dataChannelLabel=g,a}class p{constructor(){const e=!!RTCRtpSender.prototype.createEncodedStreams;if(!e)throw new Error("E2EE is not supported in this browser.");this.worker=null,this.onWorkerDisconnect=null}startWorker(){const e=atob("InVzZSBzdHJpY3QiOwovKiBlc2xpbnQtZGlzYWJsZSBAdHlwZXNjcmlwdC1lc2xpbnQvbm8tdW51c2VkLXZhcnMgKi8KY29uc3QgY29ubmVjdGlvbklkTGVuZ3RoID0gMjY7CmZ1bmN0aW9uIGJ5dGVDb3VudChuKSB7CiAgICBpZiAobiA9PSAwKSB7CiAgICAgICAgcmV0dXJuIDE7CiAgICB9CiAgICAvLyBsb2cyNTYoeCkgPSBsb2coeCkgLyBsb2coMjU2KQogICAgcmV0dXJuIE1hdGguZmxvb3IoTWF0aC5sb2cobikgLyBNYXRoLmxvZygyICoqIDgpICsgMSk7Cn0KZnVuY3Rpb24gYXJyYXlCdWZmZXJUb051bWJlcihhcnJheUJ1ZmZlcikgewogICAgLy8gMzJiaXQg44G+44Gn44KS5oOz5a6aIChCaWdJbnQg44G444Gu5pu444GN5o+b44GI5pmC44Gr6KaB5L+u5q2jKQogICAgY29uc3QgbmV3QXJyYXlCdWZmZXIgPSBuZXcgQXJyYXlCdWZmZXIoVWludDMyQXJyYXkuQllURVNfUEVSX0VMRU1FTlQpOwogICAgY29uc3QgbmV3RGF0YVZpZXcgPSBuZXcgRGF0YVZpZXcobmV3QXJyYXlCdWZmZXIpOwogICAgY29uc3QgZGF0YVZpZXcgPSBuZXcgRGF0YVZpZXcoYXJyYXlCdWZmZXIpOwogICAgY29uc3QgcGFkZGluZ0xlbmd0aCA9IFVpbnQzMkFycmF5LkJZVEVTX1BFUl9FTEVNRU5UIC0gZGF0YVZpZXcuYnl0ZUxlbmd0aDsKICAgIGZvciAobGV0IGkgPSAwOyBpIDwgcGFkZGluZ0xlbmd0aDsgaSArPSAxKSB7CiAgICAgICAgbmV3RGF0YVZpZXcuc2V0VWludDgoaSwgMCk7CiAgICB9CiAgICBmb3IgKGxldCBpID0gcGFkZGluZ0xlbmd0aCwgaiA9IDA7IGkgPCBVaW50MzJBcnJheS5CWVRFU19QRVJfRUxFTUVOVDsgaSArPSAxLCBqICs9IDEpIHsKICAgICAgICBuZXdEYXRhVmlldy5zZXRVaW50OChpLCBkYXRhVmlldy5nZXRVaW50OChqKSk7CiAgICB9CiAgICByZXR1cm4gbmV3RGF0YVZpZXcuZ2V0VWludDMyKDApOwp9CmZ1bmN0aW9uIGVuY29kZVNGcmFtZUhlYWRlcihzLCBjb3VudCwga2V5SWQpIHsKICAgIC8vICAwIDEgMiAzIDQgNSA2IDcKICAgIC8vICstKy0rLSstKy0rLSstKy0rLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tKy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSsKICAgIC8vIHxTfExFTiAgfDF8S0xFTiB8ICAgS0lELi4uIChsZW5ndGg9S0xFTikgICAgfCAgICBDVFIuLi4gKGxlbmd0aD1MRU4pICAgIHwKICAgIC8vICstKy0rLSstKy0rLSstKy0rLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tKy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSsKICAgIC8vIFM6IDEgYml0CiAgICAvLyBMRU46IDMgYml0CiAgICAvLyBYOiAxIGJpdAogICAgLy8gS0xFTjogMyBiaXQKICAgIC8vIEtJRDogS0xFTiBieXRlCiAgICAvLyBDVFI6IExFTiBieXRlCiAgICAvLyBUT0RPOiBrZXlJZCAoS0lEKSDjgYwgTnVtYmVyLk1BWF9TQUZFX0lOVEVHRVIsIDcgYnl0ZSDjgpLotoXjgYjjgabjgYTjgZ/loLTlkIjjga/jgqjjg6njg7zjgYvkvovlpJYKICAgIC8vIFRPRE86IGNvdW50IChDVFIpIOOBjCBOdW1iZXIuTUFYX1NBRkVfSU5URUdFUiwgNyBieXRlIOOCkui2heOBiOOBpuOBhOOBn+WgtOWQiOOBr+OCqOODqeODvOOBi+S+i+WklgogICAgaWYgKG1heEtleUlkIDwga2V5SWQgfHwgbWF4Q291bnQgPCBjb3VudCkgewogICAgICAgIHRocm93IG5ldyBFcnJvcigiRVhDRUVERUQtTUFYSU1VTS1CUk9BRENBU1RJTkctVElNRSIpOwogICAgfQogICAgY29uc3Qga2xlbiA9IGJ5dGVDb3VudChrZXlJZCk7CiAgICBjb25zdCBsZW4gPSBieXRlQ291bnQoY291bnQpOwogICAgY29uc3QgaGVhZGVyQnVmZmVyID0gbmV3IEFycmF5QnVmZmVyKDEgKyBrbGVuICsgbGVuKTsKICAgIGNvbnN0IGhlYWRlckRhdGFWaWV3ID0gbmV3IERhdGFWaWV3KGhlYWRlckJ1ZmZlcik7CiAgICAvLyBTLCBMRU4sIDEsIEtMRU4g44GnIDEgYnl0ZQogICAgaGVhZGVyRGF0YVZpZXcuc2V0VWludDgoMCwgKHMgPDwgNykgKyAobGVuIDw8IDQpICsgKDEgPDwgMykgKyBrbGVuKTsKICAgIGNvbnN0IGhlYWRlclVpbnQ4QXJyYXkgPSBuZXcgVWludDhBcnJheShoZWFkZXJCdWZmZXIpOwogICAgY29uc3Qga2V5SWRCdWZmZXIgPSBuZXcgQXJyYXlCdWZmZXIoVWludDMyQXJyYXkuQllURVNfUEVSX0VMRU1FTlQpOwogICAgY29uc3Qga2V5SWREYXRhVmlldyA9IG5ldyBEYXRhVmlldyhrZXlJZEJ1ZmZlcik7CiAgICBrZXlJZERhdGFWaWV3LnNldFVpbnQzMigwLCBrZXlJZCk7CiAgICBjb25zdCBrZXlJZFVpbnQ4QXJyYXkgPSBuZXcgVWludDhBcnJheShrZXlJZEJ1ZmZlcik7CiAgICBoZWFkZXJVaW50OEFycmF5LnNldChrZXlJZFVpbnQ4QXJyYXkuc3ViYXJyYXkoVWludDMyQXJyYXkuQllURVNfUEVSX0VMRU1FTlQgLSBrbGVuKSwgMSk7CiAgICBjb25zdCBjb3VudEJ1ZmZlciA9IG5ldyBBcnJheUJ1ZmZlcihVaW50MzJBcnJheS5CWVRFU19QRVJfRUxFTUVOVCk7CiAgICBjb25zdCBjb3VudERhdGFWaWV3ID0gbmV3IERhdGFWaWV3KGNvdW50QnVmZmVyKTsKICAgIGNvdW50RGF0YVZpZXcuc2V0VWludDMyKDAsIGNvdW50KTsKICAgIGNvbnN0IGNvdW50VWludDhBcnJheSA9IG5ldyBVaW50OEFycmF5KGNvdW50QnVmZmVyKTsKICAgIGhlYWRlclVpbnQ4QXJyYXkuc2V0KGNvdW50VWludDhBcnJheS5zdWJhcnJheShVaW50MzJBcnJheS5CWVRFU19QRVJfRUxFTUVOVCAtIGxlbiksIGtsZW4gKyAxKTsKICAgIHJldHVybiBoZWFkZXJVaW50OEFycmF5Owp9CmZ1bmN0aW9uIHNwbGl0SGVhZGVyKHNmcmFtZSkgewogICAgY29uc3Qgc2ZyYW1lRGF0YVZpZXcgPSBuZXcgRGF0YVZpZXcoc2ZyYW1lKTsKICAgIGNvbnN0IGhlYWRlciA9IHNmcmFtZURhdGFWaWV3LmdldFVpbnQ4KDApOwogICAgY29uc3QgbGVuID0gKGhlYWRlciAmIDB4NzApID4+IDQ7CiAgICBjb25zdCBrbGVuID0gaGVhZGVyICYgMHgwNzsKICAgIGNvbnN0IHNmcmFtZUhlYWRlckxlbmd0aCA9IDEgKyBrbGVuICsgbGVuOwogICAgY29uc3Qgc2ZyYW1lSGVhZGVyID0gc2ZyYW1lLnNsaWNlKDAsIHNmcmFtZUhlYWRlckxlbmd0aCk7CiAgICBpZiAoc2ZyYW1lSGVhZGVyLmJ5dGVMZW5ndGggPCBzZnJhbWVIZWFkZXJMZW5ndGgpIHsKICAgICAgICB0aHJvdyBuZXcgRXJyb3IoIlVORVhQRUNURUQtU0ZSQU1FLUxFTkdUSCIpOwogICAgfQogICAgY29uc3QgY29ubmVjdGlvbklkID0gc2ZyYW1lLnNsaWNlKHNmcmFtZUhlYWRlckxlbmd0aCwgc2ZyYW1lSGVhZGVyTGVuZ3RoICsgY29ubmVjdGlvbklkTGVuZ3RoKTsKICAgIGNvbnN0IGVuY3J5cHRlZEZyYW1lID0gc2ZyYW1lLnNsaWNlKHNmcmFtZUhlYWRlckxlbmd0aCArIGNvbm5lY3Rpb25JZExlbmd0aCwgc2ZyYW1lLmJ5dGVMZW5ndGgpOwogICAgcmV0dXJuIFtzZnJhbWVIZWFkZXIsIGNvbm5lY3Rpb25JZCwgZW5jcnlwdGVkRnJhbWVdOwp9CmZ1bmN0aW9uIHBhcnNlU0ZyYW1lSGVhZGVyKHNmcmFtZUhlYWRlcikgewogICAgY29uc3Qgc2ZyYW1lSGVhZGVyRGF0YVZpZXcgPSBuZXcgRGF0YVZpZXcoc2ZyYW1lSGVhZGVyKTsKICAgIGNvbnN0IGhlYWRlciA9IHNmcmFtZUhlYWRlckRhdGFWaWV3LmdldFVpbnQ4KDApOwogICAgY29uc3QgcyA9IChoZWFkZXIgJiAweDgwKSA+PiA3OwogICAgY29uc3QgbGVuID0gKGhlYWRlciAmIDB4NzApID4+IDQ7CiAgICBjb25zdCB4ID0gKGhlYWRlciAmIDB4MDgpID4+IDM7CiAgICBjb25zdCBrbGVuID0gaGVhZGVyICYgMHgwNzsKICAgIC8vIHggZmxhZwogICAgaWYgKHggIT09IDEpIHsKICAgICAgICB0aHJvdyBuZXcgRXJyb3IoIlVORVhQRUNURUQtWC1GTEFHIik7CiAgICB9CiAgICBjb25zdCBoZWFkZXJMZW5ndGggPSAxICsga2xlbiArIGxlbjsKICAgIGlmIChzZnJhbWVIZWFkZXJEYXRhVmlldy5ieXRlTGVuZ3RoIDwgaGVhZGVyTGVuZ3RoKSB7CiAgICAgICAgdGhyb3cgbmV3IEVycm9yKCJVTkVYUEVDVEVELVNGUkFNRS1IRUFERVItTEVOR1RIIik7CiAgICB9CiAgICBjb25zdCBrZXlJZEJ1ZmZlciA9IHNmcmFtZUhlYWRlci5zbGljZSgxLCAxICsga2xlbik7CiAgICBjb25zdCBrZXlJZCA9IGFycmF5QnVmZmVyVG9OdW1iZXIoa2V5SWRCdWZmZXIpOwogICAgY29uc3QgY291bnRCdWZmZXIgPSBzZnJhbWVIZWFkZXIuc2xpY2UoMSArIGtsZW4sIGhlYWRlckxlbmd0aCk7CiAgICBjb25zdCBjb3VudCA9IGFycmF5QnVmZmVyVG9OdW1iZXIoY291bnRCdWZmZXIpOwogICAgcmV0dXJuIFtzLCBjb3VudCwga2V5SWRdOwp9Ci8qIGVzbGludC1kaXNhYmxlIEB0eXBlc2NyaXB0LWVzbGludC90cmlwbGUtc2xhc2gtcmVmZXJlbmNlLCBAdHlwZXNjcmlwdC1lc2xpbnQvbm8tdW51c2VkLXZhcnMgKi8KLy8vIDxyZWZlcmVuY2UgcGF0aD0iLi9zZnJhbWUudHMiLz4KLy8gVE9ETzog5omx44GG5pWw5YCk44GM5aSn44GN44GE566H5omA44Gn44GvIE51bWJlciDjgYvjgokgQmlnSW50IOOBq+e9ruOBjeaPm+OBiOOCiwovLyBUT0RPOiBCaWdJbnQg44Gr572u44GN5o+b44GI44KL6Zqb44Gr5aSJ5pu044GZ44KLCmNvbnN0IG1heEtleUlkID0gMiAqKiAzMjsKY29uc3QgbWF4Q291bnQgPSAyICoqIDMyOwpjb25zdCBzZWxmRGVyaXZlS2V5TWFwID0gbmV3IE1hcCgpOwpjb25zdCBjb3VudE1hcCA9IG5ldyBNYXAoKTsKY29uc3Qgd3JpdGVJVk1hcCA9IG5ldyBNYXAoKTsKY29uc3QgcmVtb3RlRGVyaXZlS2V5TWFwID0gbmV3IE1hcCgpOwpjb25zdCBsYXRlc3RSZW1vdGVLZXlJZE1hcCA9IG5ldyBNYXAoKTsKY29uc3QgbGl0dGxlRW5kaWFuID0gdHJ1ZTsKY29uc3QgYmlnRW5kaWFuID0gIWxpdHRsZUVuZGlhbjsKY29uc3QgdGV4dEVuY29kZXIgPSBuZXcgVGV4dEVuY29kZXIoKTsKY29uc3QgdGV4dERlY29kZXIgPSBuZXcgVGV4dERlY29kZXIoKTsKLy8gVlA4IOOBruOBvwovLyBUT0RPKG5ha2FpKTogVlA5IC8gQVYxIOOCguWwhuadpeeahOOBq+WvvuW/nOOCguiAg+OBiOOCiwpjb25zdCB1bmVuY3J5cHRlZEJ5dGVzID0gewogICAgLy8gSSDjg5Xjg6zjg7zjg6AKICAgIGtleTogMTAsCiAgICAvLyDpnZ4gSSDjg5Xjg6zjg7zjg6AKICAgIGRlbHRhOiAzLAogICAgLy8g44Kq44O844OH44Kj44KqCiAgICB1bmRlZmluZWQ6IDEsCn07CmZ1bmN0aW9uIGdldENvdW50KGNvbm5lY3Rpb25JZCkgewogICAgcmV0dXJuIGNvdW50TWFwLmdldChjb25uZWN0aW9uSWQpIHx8IDA7Cn0KZnVuY3Rpb24gc2V0Q291bnQoY29ubmVjdGlvbklkLCBjb3VudCkgewogICAgcmV0dXJuIGNvdW50TWFwLnNldChjb25uZWN0aW9uSWQsIGNvdW50KTsKfQpmdW5jdGlvbiBnZXRSZW1vdGVEZXJpdmVLZXkoY29ubmVjdGlvbklkLCBrZXlJZCkgewogICAgaWYgKCFyZW1vdGVEZXJpdmVLZXlNYXAuaGFzKGNvbm5lY3Rpb25JZCkpIHsKICAgICAgICB0aHJvdyBuZXcgRXJyb3IoIlJFTU9URS1ERVJJVkVLRVktTUFQLU5PVC1GT1VORCIpOwogICAgfQogICAgY29uc3QgZGVyaXZlS2V5TWFwID0gcmVtb3RlRGVyaXZlS2V5TWFwLmdldChjb25uZWN0aW9uSWQpOwogICAgaWYgKCFkZXJpdmVLZXlNYXApIHsKICAgICAgICByZXR1cm47CiAgICB9CiAgICByZXR1cm4gZGVyaXZlS2V5TWFwLmdldChrZXlJZCk7Cn0KZnVuY3Rpb24gc2V0UmVtb3RlRGVyaXZlS2V5KGNvbm5lY3Rpb25JZCwga2V5SWQsIGRlcml2ZUtleSkgewogICAgbGV0IGRlcml2ZUtleU1hcCA9IHJlbW90ZURlcml2ZUtleU1hcC5nZXQoY29ubmVjdGlvbklkKTsKICAgIGlmICghZGVyaXZlS2V5TWFwKSB7CiAgICAgICAgZGVyaXZlS2V5TWFwID0gbmV3IE1hcCgpOwogICAgfQogICAgZGVyaXZlS2V5TWFwLnNldChrZXlJZCwgZGVyaXZlS2V5KTsKICAgIHJlbW90ZURlcml2ZUtleU1hcC5zZXQoY29ubmVjdGlvbklkLCBkZXJpdmVLZXlNYXApOwp9CmZ1bmN0aW9uIHNldExhdGVzdFJlbW90ZUtleUlkKGNvbm5lY3Rpb25JZCwga2V5SWQpIHsKICAgIGNvbnN0IGxhdGVzdFJlbW90ZUtleUlkID0gbGF0ZXN0UmVtb3RlS2V5SWRNYXAuZ2V0KGNvbm5lY3Rpb25JZCk7CiAgICBpZiAobGF0ZXN0UmVtb3RlS2V5SWQpIHsKICAgICAgICBpZiAobGF0ZXN0UmVtb3RlS2V5SWQgPCBrZXlJZCkgewogICAgICAgICAgICBsYXRlc3RSZW1vdGVLZXlJZE1hcC5zZXQoY29ubmVjdGlvbklkLCBrZXlJZCk7CiAgICAgICAgfQogICAgfQogICAgZWxzZSB7CiAgICAgICAgbGF0ZXN0UmVtb3RlS2V5SWRNYXAuc2V0KGNvbm5lY3Rpb25JZCwga2V5SWQpOwogICAgfQp9CmZ1bmN0aW9uIHJlbW92ZU9sZFJlbW90ZURlcml2ZUtleXMoKSB7CiAgICBsYXRlc3RSZW1vdGVLZXlJZE1hcC5mb3JFYWNoKChsYXRlc3RLZXlJZCwgY29ubmVjdGlvbklkKSA9PiB7CiAgICAgICAgY29uc3QgZGVyaXZlS2V5TWFwID0gcmVtb3RlRGVyaXZlS2V5TWFwLmdldChjb25uZWN0aW9uSWQpOwogICAgICAgIGlmIChkZXJpdmVLZXlNYXApIHsKICAgICAgICAgICAgZGVyaXZlS2V5TWFwLmZvckVhY2goKF8sIGtleUlkKSA9PiB7CiAgICAgICAgICAgICAgICBpZiAobGF0ZXN0S2V5SWQgIT09IGtleUlkKSB7CiAgICAgICAgICAgICAgICAgICAgZGVyaXZlS2V5TWFwLmRlbGV0ZShrZXlJZCk7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0pOwogICAgICAgIH0KICAgIH0pOwp9CmZ1bmN0aW9uIHJlbW92ZURlcml2ZUtleShjb25uZWN0aW9uSWQpIHsKICAgIGxhdGVzdFJlbW90ZUtleUlkTWFwLmRlbGV0ZShjb25uZWN0aW9uSWQpOwogICAgcmVtb3RlRGVyaXZlS2V5TWFwLmRlbGV0ZShjb25uZWN0aW9uSWQpOwp9CmZ1bmN0aW9uIGdldExhdGVzdFNlbGZEZXJpdmVLZXkoKSB7CiAgICBjb25zdCBkZXJpdmVLZXkgPSBzZWxmRGVyaXZlS2V5TWFwLmdldCgibGF0ZXN0Iik7CiAgICBpZiAoIWRlcml2ZUtleSkgewogICAgICAgIHRocm93IG5ldyBFcnJvcigiTEFURVNULVNFTEYtREVSSVZFS0VZLU5PVF9GT1VORCIpOwogICAgfQogICAgcmV0dXJuIGRlcml2ZUtleTsKfQpmdW5jdGlvbiBzZXRTZWxmRGVyaXZlS2V5KGNvbm5lY3Rpb25JZCwga2V5SWQsIGRlcml2ZUtleSkgewogICAgY29uc3QgY3VycmVudFNlbGZEZXJpdmVLZXkgPSBzZWxmRGVyaXZlS2V5TWFwLmdldCgibGF0ZXN0Iik7CiAgICBpZiAoY3VycmVudFNlbGZEZXJpdmVLZXkpIHsKICAgICAgICBpZiAoY3VycmVudFNlbGZEZXJpdmVLZXlbImtleUlkIl0gPCBrZXlJZCkgewogICAgICAgICAgICBjb25zdCBuZXh0U2VsZkRlcml2ZUtleSA9IHsgY29ubmVjdGlvbklkLCBrZXlJZCwgZGVyaXZlS2V5IH07CiAgICAgICAgICAgIHNlbGZEZXJpdmVLZXlNYXAuc2V0KCJsYXRlc3QiLCBuZXh0U2VsZkRlcml2ZUtleSk7CiAgICAgICAgfQogICAgfQogICAgZWxzZSB7CiAgICAgICAgY29uc3QgbmV4dFNlbGZEZXJpdmVLZXkgPSB7IGNvbm5lY3Rpb25JZCwga2V5SWQsIGRlcml2ZUtleSB9OwogICAgICAgIHNlbGZEZXJpdmVLZXlNYXAuc2V0KCJsYXRlc3QiLCBuZXh0U2VsZkRlcml2ZUtleSk7CiAgICB9Cn0KZnVuY3Rpb24gc2lsZW5jZUZyYW1lKGVuY29kZWRGcmFtZSkgewogICAgLy8gY29ubmVjdGlvbi5jcmVhdGVkLCByZWNlaXZlTWVzc2FnZSDlj5fkv6HliY3jga7loLTlkIgKICAgIGlmIChlbmNvZGVkRnJhbWUudHlwZSA9PT0gdW5kZWZpbmVkKSB7CiAgICAgICAgLy8g6Z+z5aOw44Gv5pqX5Y+35YyW44Gv44GE44KL44Go6IGe44GR44Gf44KC44Gu44GY44KD44Gq44GE44Gu44Gn572u44GN5o+b44GI44KLCiAgICAgICAgY29uc3QgbmV3RGF0YSA9IG5ldyBBcnJheUJ1ZmZlcigzKTsKICAgICAgICBjb25zdCBuZXdVaW50OCA9IG5ldyBVaW50OEFycmF5KG5ld0RhdGEpOwogICAgICAgIC8vIE9wdXMg44K144Kk44Os44Oz44K544OV44Os44O844OgCiAgICAgICAgbmV3VWludDguc2V0KFsweGQ4LCAweGZmLCAweGZlXSk7CiAgICAgICAgZW5jb2RlZEZyYW1lLmRhdGEgPSBuZXdEYXRhOwogICAgfQogICAgZWxzZSB7CiAgICAgICAgLy8g5pig5YOP44GM5q2j5bi444GY44KD44Gq44GE44Gf44KBIFBMSSDjgrnjg4jjg7zjg6DjgYznmbrnlJ/jgZfjgabjgZfjgb7jgYYKICAgICAgICAvLyDjgZ3jga7jgZ/jgoEgMzIweDI0MCDjga7nnJ/jgaPpu5LjgarnlLvpnaLjgavnva7jgY3mj5vjgYjjgosKICAgICAgICBjb25zdCBuZXdEYXRhID0gbmV3IEFycmF5QnVmZmVyKDYwKTsKICAgICAgICBjb25zdCBuZXdVaW50OCA9IG5ldyBVaW50OEFycmF5KG5ld0RhdGEpOwogICAgICAgIC8vIHByZXR0aWVyLWlnbm9yZQogICAgICAgIG5ld1VpbnQ4LnNldChbMHhiMCwgMHgwNSwgMHgwMCwgMHg5ZCwgMHgwMSwgMHgyYSwgMHhhMCwgMHgwMCwgMHg1YSwgMHgwMCwKICAgICAgICAgICAgMHgzOSwgMHgwMywgMHgwMCwgMHgwMCwgMHgxYywgMHgyMiwgMHgxNiwgMHgxNiwgMHgyMiwgMHg2NiwKICAgICAgICAgICAgMHgxMiwgMHgyMCwgMHgwNCwgMHg5MCwgMHg0MCwgMHgwMCwgMHhjNSwgMHgwMSwgMHhlMCwgMHg3YywKICAgICAgICAgICAgMHg0ZCwgMHgyZiwgMHhmYSwgMHhkZCwgMHg0ZCwgMHhhNSwgMHg3ZiwgMHg4OSwgMHhhNSwgMHhmZiwKICAgICAgICAgICAgMHg1YiwgMHhhOSwgMHhiNCwgMHhhZiwgMHhmMSwgMHgzNCwgMHhiZiwgMHhlYiwgMHg3NSwgMHgzNiwKICAgICAgICAgICAgMHg5NSwgMHhmZSwgMHgyNiwgMHg5NiwgMHg2MCwgMHhmZSwgMHhmZiwgMHhiYSwgMHhmZiwgMHg0MCwKICAgICAgICBdKTsKICAgICAgICBlbmNvZGVkRnJhbWUuZGF0YSA9IG5ld0RhdGE7CiAgICB9CiAgICByZXR1cm4gZW5jb2RlZEZyYW1lOwp9CmZ1bmN0aW9uIHNldFdyaXRlSVYoY29ubmVjdGlvbklkLCBrZXlJZCwgd3JpdGVJVikgewogICAgY29uc3Qga2V5ID0gW2Nvbm5lY3Rpb25JZCwga2V5SWQudG9TdHJpbmcoKV0uam9pbigiOiIpOwogICAgd3JpdGVJVk1hcC5zZXQoa2V5LCB3cml0ZUlWKTsKfQpmdW5jdGlvbiBnZXRXcml0ZUlWKGNvbm5lY3Rpb25JZCwga2V5SWQpIHsKICAgIGNvbnN0IGtleSA9IFtjb25uZWN0aW9uSWQsIGtleUlkLnRvU3RyaW5nKCldLmpvaW4oIjoiKTsKICAgIHJldHVybiB3cml0ZUlWTWFwLmdldChrZXkpOwp9CmZ1bmN0aW9uIGdlbmVyYXRlSVYoY291bnQsIGNvbm5lY3Rpb25JZCwga2V5SWQpIHsKICAgIC8vIFRPRE86IGtleUlkIOOBjCBOdW1iZXIuTUFYX1NBRkVfSU5URUdFUiwgNyBieXRlIOOCkui2heOBiOOBpuOBhOOBn+WgtOWQiOOBr+OCqOODqeODvOOBi+S+i+WklgogICAgLy8gVE9ETzogY291bnQg44GMIE51bWJlci5NQVhfU0FGRV9JTlRFR0VSLCA3IGJ5dGUg44KS6LaF44GI44Gm44GE44Gf5aC05ZCI44Gv44Ko44Op44O844GL5L6L5aSWCiAgICAvLyAzMiBiaXQg44G+44GnCiAgICBpZiAobWF4S2V5SWQgPCBrZXlJZCB8fCBtYXhDb3VudCA8IGNvdW50KSB7CiAgICAgICAgdGhyb3cgbmV3IEVycm9yKCJFWENFRURFRC1NQVhJTVVNLUJST0FEQ0FTVElORy1USU1FIik7CiAgICB9CiAgICBjb25zdCB3cml0ZUlWID0gZ2V0V3JpdGVJVihjb25uZWN0aW9uSWQsIGtleUlkKTsKICAgIGlmICghd3JpdGVJVikgewogICAgICAgIHRocm93IG5ldyBFcnJvcigiV1JJVEVJVi1OT1QtRk9VTkQiKTsKICAgIH0KICAgIGNvbnN0IHBhZGRpbmdMZW5ndGggPSBObiAtIFVpbnQzMkFycmF5LkJZVEVTX1BFUl9FTEVNRU5UOwogICAgY29uc3QgY291bnRXaXRoUGFkZGluZ0J1ZmZlciA9IG5ldyBBcnJheUJ1ZmZlcihObik7CiAgICBjb25zdCBjb3VudFdpdGhQYWRkaW5nRGF0YVZpZXcgPSBuZXcgRGF0YVZpZXcoY291bnRXaXRoUGFkZGluZ0J1ZmZlcik7CiAgICBjb3VudFdpdGhQYWRkaW5nRGF0YVZpZXcuc2V0VWludDMyKHBhZGRpbmdMZW5ndGgsIGNvdW50LCBiaWdFbmRpYW4pOwogICAgY29uc3QgaXYgPSBuZXcgVWludDhBcnJheShObik7CiAgICBjb25zdCBjb3VudFdpdGhQYWRkaW5nID0gbmV3IFVpbnQ4QXJyYXkoY291bnRXaXRoUGFkZGluZ0J1ZmZlcik7CiAgICBmb3IgKGxldCBpID0gMDsgaSA8IE5uOyBpKyspIHsKICAgICAgICBpdltpXSA9IHdyaXRlSVZbaV0gXiBjb3VudFdpdGhQYWRkaW5nW2ldOwogICAgfQogICAgcmV0dXJuIGl2Owp9CmZ1bmN0aW9uIHBhcnNlUGF5bG9hZChwYXlsb2FkVHlwZSwgcGF5bG9hZCkgewogICAgcmV0dXJuIFsKICAgICAgICBuZXcgVWludDhBcnJheShwYXlsb2FkLCAwLCB1bmVuY3J5cHRlZEJ5dGVzW3BheWxvYWRUeXBlXSksCiAgICAgICAgbmV3IFVpbnQ4QXJyYXkocGF5bG9hZCwgdW5lbmNyeXB0ZWRCeXRlc1twYXlsb2FkVHlwZV0pLAogICAgXTsKfQpmdW5jdGlvbiBlbmNvZGVGcmFtZUFkZChoZWFkZXIsIHNmcmFtZUhlYWRlciwgY29ubmVjdGlvbklkKSB7CiAgICBjb25zdCBjb25uZWN0aW9uSWREYXRhID0gdGV4dEVuY29kZXIuZW5jb2RlKGNvbm5lY3Rpb25JZCk7CiAgICBjb25zdCBmcmFtZUFkZCA9IG5ldyBVaW50OEFycmF5KGhlYWRlci5ieXRlTGVuZ3RoICsgc2ZyYW1lSGVhZGVyLmJ5dGVMZW5ndGggKyBjb25uZWN0aW9uSWREYXRhLmJ5dGVMZW5ndGgpOwogICAgZnJhbWVBZGQuc2V0KGhlYWRlciwgMCk7CiAgICBmcmFtZUFkZC5zZXQoc2ZyYW1lSGVhZGVyLCBoZWFkZXIuYnl0ZUxlbmd0aCk7CiAgICBmcmFtZUFkZC5zZXQoY29ubmVjdGlvbklkRGF0YSwgaGVhZGVyLmJ5dGVMZW5ndGggKyBzZnJhbWVIZWFkZXIuYnl0ZUxlbmd0aCk7CiAgICByZXR1cm4gZnJhbWVBZGQ7Cn0KYXN5bmMgZnVuY3Rpb24gZW5jcnlwdEZ1bmN0aW9uKGVuY29kZWRGcmFtZSwgY29udHJvbGxlcikgewogICAgY29uc3QgeyBjb25uZWN0aW9uSWQsIGtleUlkLCBkZXJpdmVLZXkgfSA9IGdldExhdGVzdFNlbGZEZXJpdmVLZXkoKTsKICAgIGlmICghZGVyaXZlS2V5KSB7CiAgICAgICAgcmV0dXJuOwogICAgfQogICAgY29uc3QgY3VycmVudENvdW50ID0gZ2V0Q291bnQoY29ubmVjdGlvbklkKTsKICAgIC8vIGNvdW50IOOBjCAzMiBiaXQg5Lul5LiK44Gu5aC05ZCI44Gv5YGc5q2i44GZ44KLCiAgICBpZiAoY3VycmVudENvdW50ID4gbWF4Q291bnQpIHsKICAgICAgICBwb3N0TWVzc2FnZSh7IHR5cGU6ICJkaXNjb25uZWN0IiB9KTsKICAgIH0KICAgIGNvbnN0IGl2ID0gZ2VuZXJhdGVJVihjdXJyZW50Q291bnQsIGNvbm5lY3Rpb25JZCwga2V5SWQpOwogICAgaWYgKCFpdikgewogICAgICAgIHJldHVybjsKICAgIH0KICAgIGNvbnN0IFtoZWFkZXIsIHBheWxvYWRdID0gcGFyc2VQYXlsb2FkKGVuY29kZWRGcmFtZS50eXBlLCBlbmNvZGVkRnJhbWUuZGF0YSk7CiAgICBjb25zdCBzZnJhbWVIZWFkZXIgPSBlbmNvZGVTRnJhbWVIZWFkZXIoMCwgY3VycmVudENvdW50LCBrZXlJZCk7CiAgICBjb25zdCBmcmFtZUFkZCA9IGVuY29kZUZyYW1lQWRkKGhlYWRlciwgc2ZyYW1lSGVhZGVyLCBjb25uZWN0aW9uSWQpOwogICAgY3J5cHRvLnN1YnRsZQogICAgICAgIC5lbmNyeXB0KHsKICAgICAgICBuYW1lOiAiQUVTLUdDTSIsCiAgICAgICAgaXY6IGl2LAogICAgICAgIC8vIOaal+WPt+WMluOBleOCjOOBpuOBhOOBquOBhOmDqOWIhgogICAgICAgIGFkZGl0aW9uYWxEYXRhOiBmcmFtZUFkZCwKICAgIH0sIGRlcml2ZUtleSwgcGF5bG9hZCkKICAgICAgICAudGhlbigoY2lwaGVyVGV4dCkgPT4gewogICAgICAgIGNvbnN0IG5ld0RhdGEgPSBuZXcgQXJyYXlCdWZmZXIoZnJhbWVBZGQuYnl0ZUxlbmd0aCArIGNpcGhlclRleHQuYnl0ZUxlbmd0aCk7CiAgICAgICAgY29uc3QgbmV3RGF0YVVpbnQ4ID0gbmV3IFVpbnQ4QXJyYXkobmV3RGF0YSk7CiAgICAgICAgbmV3RGF0YVVpbnQ4LnNldChmcmFtZUFkZCwgMCk7CiAgICAgICAgbmV3RGF0YVVpbnQ4LnNldChuZXcgVWludDhBcnJheShjaXBoZXJUZXh0KSwgZnJhbWVBZGQuYnl0ZUxlbmd0aCk7CiAgICAgICAgZW5jb2RlZEZyYW1lLmRhdGEgPSBuZXdEYXRhOwogICAgICAgIGNvbnRyb2xsZXIuZW5xdWV1ZShlbmNvZGVkRnJhbWUpOwogICAgfSk7CiAgICBzZXRDb3VudChjb25uZWN0aW9uSWQsIGN1cnJlbnRDb3VudCArIDEpOwp9CmFzeW5jIGZ1bmN0aW9uIGRlY3J5cHRGdW5jdGlvbihlbmNvZGVkRnJhbWUsIGNvbnRyb2xsZXIpIHsKICAgIC8vIOepuuODleODrOODvOODoOWvvuW/nAogICAgaWYgKGVuY29kZWRGcmFtZS5kYXRhLmJ5dGVMZW5ndGggPCAxKSB7CiAgICAgICAgcmV0dXJuOwogICAgfQogICAgdHJ5IHsKICAgICAgICBjb25zdCBmcmFtZU1ldGFkYXRhQnVmZmVyID0gZW5jb2RlZEZyYW1lLmRhdGEuc2xpY2UoMCwgdW5lbmNyeXB0ZWRCeXRlc1tlbmNvZGVkRnJhbWUudHlwZV0pOwogICAgICAgIGNvbnN0IGZyYW1lTWV0YWRhdGEgPSBuZXcgVWludDhBcnJheShmcmFtZU1ldGFkYXRhQnVmZmVyKTsKICAgICAgICBjb25zdCBbc2ZyYW1lSGVhZGVyQnVmZmVyLCBjb25uZWN0aW9uSWRCdWZmZXIsIGVuY3J5cHRlZEZyYW1lQnVmZmVyXSA9IHNwbGl0SGVhZGVyKGVuY29kZWRGcmFtZS5kYXRhLnNsaWNlKHVuZW5jcnlwdGVkQnl0ZXNbZW5jb2RlZEZyYW1lLnR5cGVdKSk7CiAgICAgICAgY29uc3Qgc2ZyYW1lSGVhZGVyID0gbmV3IFVpbnQ4QXJyYXkoc2ZyYW1lSGVhZGVyQnVmZmVyKTsKICAgICAgICBjb25zdCBjb25uZWN0aW9uSWQgPSB0ZXh0RGVjb2Rlci5kZWNvZGUoY29ubmVjdGlvbklkQnVmZmVyKTsKICAgICAgICBjb25zdCBbcywgY291bnQsIGtleUlkXSA9IHBhcnNlU0ZyYW1lSGVhZGVyKHNmcmFtZUhlYWRlckJ1ZmZlcik7CiAgICAgICAgLy8g5LuK5Zue44GvIHMgZmxhZyDjga8gMCDjga7jgb8KICAgICAgICBpZiAocyAhPT0gMCkgewogICAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoIlVORVhQRUNURUQtUy1GTEFHIik7CiAgICAgICAgfQogICAgICAgIGNvbnN0IGRlcml2ZUtleSA9IGdldFJlbW90ZURlcml2ZUtleShjb25uZWN0aW9uSWQsIGtleUlkKTsKICAgICAgICBpZiAoIWRlcml2ZUtleSkgewogICAgICAgICAgICByZXR1cm47CiAgICAgICAgfQogICAgICAgIGNvbnN0IGl2ID0gZ2VuZXJhdGVJVihjb3VudCwgY29ubmVjdGlvbklkLCBrZXlJZCk7CiAgICAgICAgaWYgKCFpdikgewogICAgICAgICAgICByZXR1cm47CiAgICAgICAgfQogICAgICAgIGNvbnN0IGZyYW1lQWRkID0gZW5jb2RlRnJhbWVBZGQoZnJhbWVNZXRhZGF0YSwgc2ZyYW1lSGVhZGVyLCBjb25uZWN0aW9uSWQpOwogICAgICAgIGNyeXB0by5zdWJ0bGUKICAgICAgICAgICAgLmRlY3J5cHQoewogICAgICAgICAgICBuYW1lOiAiQUVTLUdDTSIsCiAgICAgICAgICAgIGl2OiBpdiwKICAgICAgICAgICAgYWRkaXRpb25hbERhdGE6IGZyYW1lQWRkLAogICAgICAgIH0sIGRlcml2ZUtleSwgbmV3IFVpbnQ4QXJyYXkoZW5jcnlwdGVkRnJhbWVCdWZmZXIpKQogICAgICAgICAgICAudGhlbigocGxhaW5UZXh0KSA9PiB7CiAgICAgICAgICAgIGNvbnN0IG5ld0RhdGEgPSBuZXcgQXJyYXlCdWZmZXIoZnJhbWVNZXRhZGF0YUJ1ZmZlci5ieXRlTGVuZ3RoICsgcGxhaW5UZXh0LmJ5dGVMZW5ndGgpOwogICAgICAgICAgICBjb25zdCBuZXdVaW50OCA9IG5ldyBVaW50OEFycmF5KG5ld0RhdGEpOwogICAgICAgICAgICBuZXdVaW50OC5zZXQobmV3IFVpbnQ4QXJyYXkoZnJhbWVNZXRhZGF0YUJ1ZmZlciwgMCwgdW5lbmNyeXB0ZWRCeXRlc1tlbmNvZGVkRnJhbWUudHlwZV0pKTsKICAgICAgICAgICAgbmV3VWludDguc2V0KG5ldyBVaW50OEFycmF5KHBsYWluVGV4dCksIHVuZW5jcnlwdGVkQnl0ZXNbZW5jb2RlZEZyYW1lLnR5cGVdKTsKICAgICAgICAgICAgZW5jb2RlZEZyYW1lLmRhdGEgPSBuZXdEYXRhOwogICAgICAgICAgICBjb250cm9sbGVyLmVucXVldWUoZW5jb2RlZEZyYW1lKTsKICAgICAgICB9KTsKICAgIH0KICAgIGNhdGNoIChlKSB7CiAgICAgICAgLy8g5oOz5a6a5aSW44Gu44OR44Kx44OD44OI44OV44Kp44O844Oe44OD44OI44KS5Y+X5L+h44GX44Gf5aC05ZCICiAgICAgICAgY29udHJvbGxlci5lbnF1ZXVlKHNpbGVuY2VGcmFtZShlbmNvZGVkRnJhbWUpKTsKICAgIH0KfQovKiBlc2xpbnQtZGlzYWJsZSBAdHlwZXNjcmlwdC1lc2xpbnQvdHJpcGxlLXNsYXNoLXJlZmVyZW5jZSAqLwovLy8gPHJlZmVyZW5jZSBwYXRoPSIuL2UyZWUudHMiLz4KLy8gbm9uY2Ug44K144Kk44K6CmNvbnN0IE5uID0gMTI7Ci8vIGtleSDjgrXjgqTjgroKY29uc3QgTmsgPSAxNjsKLy8ga2V5IOOCteOCpOOCuu+8iGJpdO+8iQpjb25zdCBrZXlMZW5ndGggPSBOayAqIDg7CmFzeW5jIGZ1bmN0aW9uIGdlbmVyYXRlRGVyaXZlS2V5KG1hdGVyaWFsKSB7CiAgICBjb25zdCBzYWx0ID0gdGV4dEVuY29kZXIuZW5jb2RlKCJTRnJhbWUxMCIpOwogICAgY29uc3QgaW5mbyA9IHRleHRFbmNvZGVyLmVuY29kZSgia2V5Iik7CiAgICBjb25zdCBkZXJpdmVLZXkgPSBhd2FpdCBjcnlwdG8uc3VidGxlLmRlcml2ZUtleSh7CiAgICAgICAgbmFtZTogIkhLREYiLAogICAgICAgIHNhbHQ6IHNhbHQsCiAgICAgICAgaGFzaDogIlNIQS0yNTYiLAogICAgICAgIGluZm86IGluZm8sCiAgICB9LCBtYXRlcmlhbCwgewogICAgICAgIG5hbWU6ICJBRVMtR0NNIiwKICAgICAgICBsZW5ndGg6IGtleUxlbmd0aCwKICAgIH0sIGZhbHNlLCBbImVuY3J5cHQiLCAiZGVjcnlwdCJdKTsKICAgIHJldHVybiBkZXJpdmVLZXk7Cn0KYXN5bmMgZnVuY3Rpb24gZ2VuZXJhdGVXcml0ZUlWKG1hdGVyaWFsKSB7CiAgICBjb25zdCBzYWx0ID0gdGV4dEVuY29kZXIuZW5jb2RlKCJTRnJhbWUxMCIpOwogICAgY29uc3QgaW5mbyA9IHRleHRFbmNvZGVyLmVuY29kZSgic2FsdCIpOwogICAgY29uc3Qgd3JpdGVJVkJ1ZmZlciA9IGF3YWl0IGNyeXB0by5zdWJ0bGUuZGVyaXZlQml0cyh7CiAgICAgICAgbmFtZTogIkhLREYiLAogICAgICAgIHNhbHQ6IHNhbHQsCiAgICAgICAgaGFzaDogIlNIQS0zODQiLAogICAgICAgIGluZm86IGluZm8sCiAgICB9LCBtYXRlcmlhbCwgCiAgICAvLyBJViDjga8gOTYg44OT44OD44OI44Gq44Gu44GnCiAgICBObiAqIDgpOwogICAgY29uc3Qgd3JpdGVJViA9IG5ldyBVaW50OEFycmF5KHdyaXRlSVZCdWZmZXIpOwogICAgcmV0dXJuIHdyaXRlSVY7Cn0KbGV0IHJlbW92YWxUaW1lb3V0SWQgPSAwOwpvbm1lc3NhZ2UgPSAoZXZlbnQpID0+IHsKICAgIGNvbnN0IHsgdHlwZSB9ID0gZXZlbnQuZGF0YTsKICAgIGlmICh0eXBlID09PSAic2VsZlNlY3JldEtleU1hdGVyaWFsIikgewogICAgICAgIGNvbnN0IHsgc2VsZlNlY3JldEtleU1hdGVyaWFsLCBzZWxmQ29ubmVjdGlvbklkLCBzZWxmS2V5SWQsIHdhaXRpbmdUaW1lIH0gPSBldmVudC5kYXRhOwogICAgICAgIGNvbnN0IHRpbWVvdXRJZCA9IHNldFRpbWVvdXQoKCkgPT4gewogICAgICAgICAgICBjcnlwdG8uc3VidGxlCiAgICAgICAgICAgICAgICAuaW1wb3J0S2V5KCJyYXciLCBzZWxmU2VjcmV0S2V5TWF0ZXJpYWwuYnVmZmVyLCAiSEtERiIsIGZhbHNlLCBbImRlcml2ZUJpdHMiLCAiZGVyaXZlS2V5Il0pCiAgICAgICAgICAgICAgICAudGhlbigobWF0ZXJpYWwpID0+IHsKICAgICAgICAgICAgICAgIGdlbmVyYXRlRGVyaXZlS2V5KG1hdGVyaWFsKS50aGVuKChkZXJpdmVLZXkpID0+IHsKICAgICAgICAgICAgICAgICAgICBzZXRTZWxmRGVyaXZlS2V5KHNlbGZDb25uZWN0aW9uSWQsIHNlbGZLZXlJZCwgZGVyaXZlS2V5KTsKICAgICAgICAgICAgICAgIH0pOwogICAgICAgICAgICAgICAgZ2VuZXJhdGVXcml0ZUlWKG1hdGVyaWFsKS50aGVuKCh3cml0ZUlWKSA9PiB7CiAgICAgICAgICAgICAgICAgICAgc2V0V3JpdGVJVihzZWxmQ29ubmVjdGlvbklkLCBzZWxmS2V5SWQsIHdyaXRlSVYpOwogICAgICAgICAgICAgICAgfSk7CiAgICAgICAgICAgICAgICBjbGVhclRpbWVvdXQodGltZW91dElkKTsKICAgICAgICAgICAgfSk7CiAgICAgICAgfSwgd2FpdGluZ1RpbWUgfHwgMCk7CiAgICAgICAgLy8gVE9ETzogKzEwMDAg44Gn6Y2155Sf5oiQ5b6M44Gr5a6f6KGM44GV44KM44KL44KI44GG44Gr44GX44Gm44GE44KL44GM55+t44GE5aC05ZCI44Gv5Ly444Gw44GZCiAgICAgICAgY29uc3QgcmVtb3ZhbFdhaXRpbmdUaW1lID0gKHdhaXRpbmdUaW1lIHx8IDApICsgMTAwMDsKICAgICAgICBpZiAocmVtb3ZhbFRpbWVvdXRJZCkgewogICAgICAgICAgICAvLyDli5XkvZzmuIjjgb/jgr/jgqTjg57jg7zmnInjgooKICAgICAgICAgICAgaWYgKHdhaXRpbmdUaW1lKSB7CiAgICAgICAgICAgICAgICAvLyBjb25uZWN0aW9uLmRlc3Ryb3llZAogICAgICAgICAgICAgICAgY2xlYXJUaW1lb3V0KHJlbW92YWxUaW1lb3V0SWQpOwogICAgICAgICAgICAgICAgcmVtb3ZhbFRpbWVvdXRJZCA9IHNldFRpbWVvdXQoKCkgPT4gewogICAgICAgICAgICAgICAgICAgIHJlbW92ZU9sZFJlbW90ZURlcml2ZUtleXMoKTsKICAgICAgICAgICAgICAgICAgICBjbGVhclRpbWVvdXQocmVtb3ZhbFRpbWVvdXRJZCk7CiAgICAgICAgICAgICAgICAgICAgcmVtb3ZhbFRpbWVvdXRJZCA9IDA7CiAgICAgICAgICAgICAgICB9LCByZW1vdmFsV2FpdGluZ1RpbWUpOwogICAgICAgICAgICB9CiAgICAgICAgfQogICAgICAgIGVsc2UgewogICAgICAgICAgICAvLyDli5XkvZzmuIjjgb/jgr/jgqTjg57jg7zjgarjgZcKICAgICAgICAgICAgLy8gY29ubmVjdGlvbi5jcmVhdGVkIOOBruWgtOWQiOOCguWwkeOBl+Wun+ihjOOCkumBheOCieOBm+OCiwogICAgICAgICAgICByZW1vdmFsVGltZW91dElkID0gc2V0VGltZW91dCgoKSA9PiB7CiAgICAgICAgICAgICAgICByZW1vdmVPbGRSZW1vdGVEZXJpdmVLZXlzKCk7CiAgICAgICAgICAgICAgICBjbGVhclRpbWVvdXQocmVtb3ZhbFRpbWVvdXRJZCk7CiAgICAgICAgICAgICAgICByZW1vdmFsVGltZW91dElkID0gMDsKICAgICAgICAgICAgfSwgcmVtb3ZhbFdhaXRpbmdUaW1lKTsKICAgICAgICB9CiAgICB9CiAgICBlbHNlIGlmICh0eXBlID09PSAicmVtb3RlU2VjcmV0S2V5TWF0ZXJpYWxzIikgewogICAgICAgIGNvbnN0IHsgcmVtb3RlU2VjcmV0S2V5TWF0ZXJpYWxzIH0gPSBldmVudC5kYXRhOwogICAgICAgIGZvciAoY29uc3QgW2Nvbm5lY3Rpb25JZCwgcmVtb3RlU2VjcmV0S2V5TWF0ZXJpYWxdIG9mIE9iamVjdC5lbnRyaWVzKHJlbW90ZVNlY3JldEtleU1hdGVyaWFscykpIHsKICAgICAgICAgICAgY29uc3QgeyBrZXlJZCwgc2VjcmV0S2V5TWF0ZXJpYWwgfSA9IHJlbW90ZVNlY3JldEtleU1hdGVyaWFsOwogICAgICAgICAgICBjcnlwdG8uc3VidGxlCiAgICAgICAgICAgICAgICAuaW1wb3J0S2V5KCJyYXciLCBzZWNyZXRLZXlNYXRlcmlhbC5idWZmZXIsICJIS0RGIiwgZmFsc2UsIFsiZGVyaXZlQml0cyIsICJkZXJpdmVLZXkiXSkKICAgICAgICAgICAgICAgIC50aGVuKChtYXRlcmlhbCkgPT4gewogICAgICAgICAgICAgICAgZ2VuZXJhdGVEZXJpdmVLZXkobWF0ZXJpYWwpLnRoZW4oKGRlcml2ZUtleSkgPT4gewogICAgICAgICAgICAgICAgICAgIHNldFJlbW90ZURlcml2ZUtleShjb25uZWN0aW9uSWQsIGtleUlkLCBkZXJpdmVLZXkpOwogICAgICAgICAgICAgICAgfSk7CiAgICAgICAgICAgICAgICBnZW5lcmF0ZVdyaXRlSVYobWF0ZXJpYWwpLnRoZW4oKHdyaXRlSVYpID0+IHsKICAgICAgICAgICAgICAgICAgICBzZXRXcml0ZUlWKGNvbm5lY3Rpb25JZCwga2V5SWQsIHdyaXRlSVYpOwogICAgICAgICAgICAgICAgfSk7CiAgICAgICAgICAgICAgICBzZXRMYXRlc3RSZW1vdGVLZXlJZChjb25uZWN0aW9uSWQsIGtleUlkKTsKICAgICAgICAgICAgfSk7CiAgICAgICAgfQogICAgfQogICAgZWxzZSBpZiAodHlwZSA9PT0gInJlbW92ZVJlbW90ZURlcml2ZUtleSIpIHsKICAgICAgICBjb25zdCB7IGNvbm5lY3Rpb25JZCB9ID0gZXZlbnQuZGF0YTsKICAgICAgICByZW1vdmVEZXJpdmVLZXkoY29ubmVjdGlvbklkKTsKICAgIH0KICAgIGVsc2UgaWYgKHR5cGUgPT09ICJlbmNyeXB0IikgewogICAgICAgIGNvbnN0IHsgcmVhZGFibGVTdHJlYW0sIHdyaXRhYmxlU3RyZWFtIH0gPSBldmVudC5kYXRhOwogICAgICAgIGNvbnN0IHRyYW5zZm9ybVN0cmVhbSA9IG5ldyBUcmFuc2Zvcm1TdHJlYW0oewogICAgICAgICAgICB0cmFuc2Zvcm06IGVuY3J5cHRGdW5jdGlvbiwKICAgICAgICB9KTsKICAgICAgICByZWFkYWJsZVN0cmVhbS5waXBlVGhyb3VnaCh0cmFuc2Zvcm1TdHJlYW0pLnBpcGVUbyh3cml0YWJsZVN0cmVhbSk7CiAgICB9CiAgICBlbHNlIGlmICh0eXBlID09PSAiZGVjcnlwdCIpIHsKICAgICAgICBjb25zdCB7IHJlYWRhYmxlU3RyZWFtLCB3cml0YWJsZVN0cmVhbSB9ID0gZXZlbnQuZGF0YTsKICAgICAgICBjb25zdCB0cmFuc2Zvcm1TdHJlYW0gPSBuZXcgVHJhbnNmb3JtU3RyZWFtKHsKICAgICAgICAgICAgdHJhbnNmb3JtOiBkZWNyeXB0RnVuY3Rpb24sCiAgICAgICAgfSk7CiAgICAgICAgcmVhZGFibGVTdHJlYW0ucGlwZVRocm91Z2godHJhbnNmb3JtU3RyZWFtKS5waXBlVG8od3JpdGFibGVTdHJlYW0pOwogICAgfQogICAgZWxzZSBpZiAodHlwZSA9PT0gImNsZWFyIikgewogICAgICAgIGNvdW50TWFwLmNsZWFyKCk7CiAgICAgICAgd3JpdGVJVk1hcC5jbGVhcigpOwogICAgICAgIHJlbW90ZURlcml2ZUtleU1hcC5jbGVhcigpOwogICAgICAgIGxhdGVzdFJlbW90ZUtleUlkTWFwLmNsZWFyKCk7CiAgICAgICAgc2VsZkRlcml2ZUtleU1hcC5jbGVhcigpOwogICAgfQp9Owo=");this.worker=new Worker(URL.createObjectURL(new Blob([e],{type:"application/javascript"}))),this.worker.onmessage=e=>{const{operation:n}=e.data;"disconnect"===n&&"function"==typeof this.onWorkerDisconnect&&this.onWorkerDisconnect()}}clearWorker(){this.worker&&this.worker.postMessage({type:"clear"})}terminateWorker(){this.worker&&this.worker.terminate()}async init(){const{preKeyBundle:e}=await window.e2ee.init();return e}setupSenderTransform(e){if(!e.track)return;const n=e.createEncodedStreams(),i=n.readableStream||n.readable,t=n.writableStream||n.writable;if(!this.worker)throw new Error("Worker is null. Call startWorker in advance.");this.worker.postMessage({type:"encrypt",readableStream:i,writableStream:t},[i,t])}setupReceiverTransform(e){const n=e.createEncodedStreams(),i=n.readableStream||n.readable,t=n.writableStream||n.writable;if(!this.worker)throw new Error("Worker is null. Call startWorker in advance.");this.worker.postMessage({type:"decrypt",readableStream:i,writableStream:t},[i,t])}postRemoteSecretKeyMaterials(e){if(!this.worker)throw new Error("Worker is null. Call startWorker in advance.");this.worker.postMessage({type:"remoteSecretKeyMaterials",remoteSecretKeyMaterials:e.remoteSecretKeyMaterials})}postRemoveRemoteDeriveKey(e){if(!this.worker)throw new Error("Worker is null. Call startWorker in advance.");this.worker.postMessage({type:"removeRemoteDeriveKey",connectionId:e})}postSelfSecretKeyMaterial(e,n,i,t=0){if(!this.worker)throw new Error("Worker is null. Call startWorker in advance.");this.worker.postMessage({type:"selfSecretKeyMaterial",selfConnectionId:e,selfKeyId:n,selfSecretKeyMaterial:i,waitingTime:t})}startSession(e,n){const[i,t]=window.e2ee.startSession(e,n.identityKey,n.signedPreKey,n.preKeySignature);if(t)throw t;return i}stopSession(e){const[n,i]=window.e2ee.stopSession(e);if(i)throw i;return n}receiveMessage(e){const[n,i]=window.e2ee.receiveMessage(e);if(i)throw i;return n}start(e){const[n,i]=window.e2ee.start(e);if(i)throw i;return n}addPreKeyBundle(e,n){const i=window.e2ee.addPreKeyBundle(e,n.identityKey,n.signedPreKey,n.preKeySignature);if(i)throw i}selfFingerprint(){return window.e2ee.selfFingerprint()}remoteFingerprints(){return window.e2ee.remoteFingerprints()}static async loadWasm(e){if(void 0===!window.e2ee)return void console.warn("E2ee wasm is already loaded. Will not be reload.");if(a(),!window.Go)throw new Error(`Failed to load module Go. window.Go is ${window.Go}.`);const n=new Go,{instance:i}=await WebAssembly.instantiateStreaming(fetch(e),n.importObject);if(n.run(i),!window.e2ee)throw new Error(`Failed to load module e2ee. window.e2ee is ${window.e2ee}.`)}static version(){return"2021.1.0"}static wasmVersion(){return window.e2ee.version()}}var V=Uint8Array,G=Uint16Array,S=Uint32Array,W=new V([0,0,0,0,0,0,0,0,1,1,1,1,2,2,2,2,3,3,3,3,4,4,4,4,5,5,5,5,0,0,0,0]),h=new V([0,0,0,0,1,1,2,2,3,3,4,4,5,5,6,6,7,7,8,8,9,9,10,10,11,11,12,12,13,13,0,0]),y=new V([16,17,18,0,8,7,9,6,10,5,11,4,12,3,13,2,14,1,15]),k=function(e,n){for(var t=new G(31),g=0;31>g;++g)t[g]=n+=1<g;++g)for(var o=t[g];oN;++N)X=(43690&N)>>>1|(21845&N)<<1,X=(52428&X)>>>2|(13107&X)<<2,X=(61680&X)>>>4|(3855&X)<<4,Y[N]=((65280&X)>>>8|(255&X)<<8)>>>1;for(var v=function(e,n,t){for(var g=e.length,a=0,o=new G(n);a>>15-n]=d}else for(c=new G(g),a=0;a>>15-e[a]);return c},E=new V(288),N=0;144>N;++N)E[N]=8;for(var N=144;256>N;++N)E[N]=9;for(var N=256;280>N;++N)E[N]=7;for(var N=280;288>N;++N)E[N]=8;for(var O=new V(32),N=0;32>N;++N)O[N]=5;var K=v(E,9,0),F=v(E,9,1),L=v(O,5,0),J=v(O,5,1),U=function(e){for(var n=e[0],t=1;tn&&(n=e[t]);return n},Q=function(e,n,i){var t=0|n/8;return(e[t]|e[t+1]<<8)>>(7&n)&i},D=function(e,n){var i=0|n/8;return(e[i]|e[i+1]<<8|e[i+2]<<16)>>(7&n)},H=function(e){return(0|e/8)+(7&e&&1)},M=function(i,t,g){(null==t||0>t)&&(t=0),(null==g||g>i.length)&&(g=i.length);var a=new(i instanceof G?G:i instanceof S?S:V)(g-t);return a.set(i.subarray(t,g)),a},P=["unexpected EOF","invalid block type","invalid length/literal","invalid distance","stream finished","no stream handler",,"no callback","invalid UTF-8 data","extra field too long","date not in range 1980-2099","filename too long","stream finishing","invalid zip data"],j=function(n,i,t){var g=new Error(i||P[n]);if(g.code=n,Error.captureStackTrace&&Error.captureStackTrace(g,j),!t)throw g;return g},z=function(a,o,C){var I=a.length;if(!I||C&&!C.l&&5>I)return o||new V(0);var m=!o||C,A=!C||C.i;C||(C={}),o||(o=new V(3*I));var Z=function(e){var n=o.length;if(e>n){var i=new V(g(2*n,e));i.set(o),o=i}},u=C.f||0,p=C.p||0,G=C.b||0,S=C.l,k=C.d,w=C.m,R=C.n,X=8*I;do{if(!S){C.f=u=Q(a,p,1);var f=Q(a,p+1,3);if(p+=3,!f){var T=H(p)+4,Y=a[T-4]|a[T-3]<<8,l=T+Y;if(l>I){A&&j(0);break}m&&Z(G+Y),o.set(a.subarray(T,l),G),C.b=G+=Y,C.p=p=8*l;continue}else if(1==f)S=F,k=J,w=9,R=5;else if(2==f){var t=Q(a,p,31)+257,N=Q(a,p+10,15)+4,E=t+Q(a,p+5,31)+1;p+=14;for(var O=new V(E),K=new V(19),L=0;L>>4;if(16>T)O[L++]=T;else{var _=0,q=0;for(16==T?(q=3+Q(a,p,3),p+=2,_=O[L-1]):17==T?(q=3+Q(a,p,7),p+=3):18==T&&(q=11+Q(a,p,127),p+=7);q--;)O[L++]=_}}var $=O.subarray(0,t),ee=O.subarray(t);w=U($),R=U(ee),S=v($,w,1),k=v(ee,R,1)}else j(1);if(p>X){A&&j(0);break}}m&&Z(G+131072);for(var ne=(1<>>4;if(p+=15&_,p>X){A&&j(0);break}if(_||j(2),256>ge)o[G++]=ge;else if(256==ge){te=p,S=null;break}else{var ae=ge-254;if(264>>4;le||j(3),p+=15≤var ee=B[d];if(3X){A&&j(0);break}m&&Z(G+131072);for(var ce=G+ae;G>>8},q=function(e,n,i){i<<=7&n;var t=0|n/8;e[t]|=i,e[t+1]|=i>>>8,e[t+2]|=i>>>16},$=function(e,n){for(var g=[],t=0;tA&&(A=o[t].s);var Z=new G(A+1),u=ee(g[I-1],Z,0);if(u>n){var t=0,b=0,p=u-n;for(o.sort(function(e,n){return Z[n.s]-Z[e.s]||e.f-n.f});tn)b+=(1<>>=p;0>>8,e[a+2]=255^e[a],e[a+3]=255^e[a+1];for(var o=0;oz;++z){x=P[z];for(var ee,f=0;f>>5),s+=x[f]>>>12)}}else Q=K,D=E,j=L,H=O;for(var f=0;f>>18;q(n,s,Q[ee+257]),s+=D[ee+257],7>>23),s+=W[ee]);var ge=31&g[f];q(n,s,j[ge]),s+=H[ge],3>>5),s+=h[ge])}else q(n,s,Q[g[f]]),s+=D[g[f]];return q(n,s,Q[256]),s+D[256]},ae=new S([65540,131080,131088,131104,262176,1048704,1048832,2114560,2117632]),oe=new V(0),le=function(g,a,c,C,I,r){var m=g.length,s=new V(C+m+5*(1+t(m/7e3))+I),o=s.subarray(C,s.length-I),A=0;if(!a||8>m)for(var Z,u=0;u<=m;u+=65535)Z=u+65535,ZQ;++Q)B[Q]=0;for(var Q=0;30>Q;++Q)Y[Q]=0}var D=2,x=0,P=8191&b,z=32767&L-J;if(2>>13,U)-1,q=n(32767,u),$=n(258,U);z<=q&&--P&&L!=J;){if(g[u+D]==g[u+D-z]){for(var ee=0;ee<$&&g[u+ee]==g[u+ee-z];++ee);if(ee>D){if(D=ee,x=z,ee>_)break;for(var ne=n(z,ee-2),ie=0,Q=0;Qie&&(ie=de,J=le)}}}L=J,J=y[L],z+=32767&L-J+32768}if(x){f[E++]=268435456|R[D]<<18|T[x];var Ce=31&R[D],se=31&T[x];v+=W[Ce]+h[se],++B[257+Ce],++Y[se],O=u+D,++N}else f[E++]=g[u],++B[g[u]]}}A=ge(g,o,r,f,B,Y,v,E,K,u-K,A),!r&&7&A&&(A=te(o,A+1,oe))}return M(s,0,C+H(A)+I)},ce=function(){var t=1,g=0;return{p:function(a){for(var o,c=t,d=g,C=a.length,l=0;l!=C;){for(o=n(l+2655,C);l>16),d=(65535&d)+15*(d>>16)}t=c,g=d},d:function(){return t%=65521,g%=65521,(255&t)<<24|t>>>8<<16|(255&g)<<8|g>>>8}}},de=function(e,i,a,o,l){return le(e,null==i.level?6:i.level,null==i.mem?t(1.5*g(8,n(13,Math.log(e.length)))):12+i.mem,a,o,!l)},Ce=function(e,n,i){for(;i;++n)e[n]=i,i>>>=8},se=function(e,n){var i=n.level,t=0==i?0:6>i?1:9==i?3:2;e[0]=120,e[1]=t<<6|(t?32-2*t:1)},Ie=function(e){(8!=(15&e[0])||7>>4||(e[0]<<8|e[1])%31)&&j(6,"invalid zlib data"),32&e[1]&&j(6,"invalid zlib data: preset dictionaries not supported")},re="undefined"!=typeof TextDecoder&&new TextDecoder,me=0;try{re.decode(oe,{stream:!0}),me=1}catch(n){}class Ae extends Error{}class Ze{constructor(e,n,i,t,g,a){this.role=n,this.channelId=i,this.metadata=t,this.signalingUrl=e,this.options=g,this.connectionTimeout=6e4,"number"==typeof this.options.timeout&&(console.warn("@deprecated timeout option will be removed in a future version. Use connectionTimeout."),this.connectionTimeout=this.options.timeout),"number"==typeof this.options.connectionTimeout&&(this.connectionTimeout=this.options.connectionTimeout),this.disconnectWaitTimeout=3e3,"number"==typeof this.options.disconnectWaitTimeout&&(this.disconnectWaitTimeout=this.options.disconnectWaitTimeout),this.constraints=null,this.debug=a,this.clientId=null,this.connectionId=null,this.remoteConnectionIds=[],this.stream=null,this.ws=null,this.pc=null,this.encodings=[],this.callbacks={disconnect:()=>{},push:()=>{},addstream:()=>{},track:()=>{},removestream:()=>{},removetrack:()=>{},notify:()=>{},log:()=>{},timeout:()=>{},timeline:()=>{},signaling:()=>{}},this.authMetadata=null,this.e2ee=null,this.connectionTimeoutTimerId=0,this.monitorSignalingWebSocketEventTimerId=0,this.monitorIceConnectionStateChangeTimerId=0,this.dataChannels={},this.mids={audio:"",video:""},this.signalingSwitched=!1,this.dataChannelsCompress={}}on(e,n){"addstream"===e?console.warn("@deprecated addstream callback will be removed in a future version. Use track callback."):"removestream"==e&&console.warn("@deprecated removestream callback will be removed in a future version. Use removetrack callback."),e in this.callbacks&&(this.callbacks[e]=n)}stopAudioTrack(e){for(const n of e.getAudioTracks())n.enabled=!1;return new Promise(n=>{setTimeout(async()=>{for(const n of e.getAudioTracks())if(n.stop(),e.removeTrack(n),null!==this.pc){const e=this.pc.getSenders().find(e=>e.track&&e.track.id===n.id);e&&(await e.replaceTrack(null))}n()},100)})}stopVideoTrack(e){for(const n of e.getVideoTracks())n.enabled=!1;return new Promise(n=>{setTimeout(async()=>{for(const n of e.getVideoTracks())if(n.stop(),e.removeTrack(n),null!==this.pc){const e=this.pc.getSenders().find(e=>e.track&&e.track.id===n.id);e&&(await e.replaceTrack(null))}n()},100)})}async replaceAudioTrack(e,n){await this.stopAudioTrack(e);const i=this.getAudioTransceiver();if(null===i)throw new Error("Unable to set an audio track. Audio track sender is undefined");e.addTrack(n),await i.sender.replaceTrack(n)}async replaceVideoTrack(e,n){await this.stopVideoTrack(e);const i=this.getVideoTransceiver();if(null===i)throw new Error("Unable to set video track. Video track sender is undefined");e.addTrack(n),await i.sender.replaceTrack(n)}stopStream(){return new Promise(e=>(this.debug&&console.warn("@deprecated closing MediaStream in disconnect will be removed in a future version. Close every track in the MediaStream by yourself."),!this.stream)?e():(this.stream.getTracks().forEach(e=>{e.stop()}),this.stream=null,e()))}async signalingTerminate(){await this.stopStream();for(const e of Object.keys(this.dataChannels)){const n=this.dataChannels[e];n&&n.close(),delete this.dataChannels[e]}this.ws&&(this.ws.close(),this.ws=null),this.pc&&this.pc.close(),this.e2ee&&this.e2ee.terminateWorker(),this.initializeConnection()}async abendPeerConnectionState(e){this.clearMonitorIceConnectionStateChange(),await this.stopStream(),this.pc&&(this.pc.ondatachannel=null,this.pc.oniceconnectionstatechange=null,this.pc.onicegatheringstatechange=null,this.pc.onconnectionstatechange=null),this.ws&&(this.ws.onclose=()=>{this.writeWebSocketTimelineLog("onclose")},this.ws.onmessage=null,this.ws.onerror=null);for(const n of Object.keys(this.dataChannels)){const e=this.dataChannels[n];e&&(e.onclose=e=>{const n=e.currentTarget;this.writeDataChannelTimelineLog("onclose",n),this.trace("CLOSE DATA CHANNEL",n.label)},e.onmessage=null,e.onerror=null)}for(const n of Object.keys(this.dataChannels)){const e=this.dataChannels[n];e&&e.close(),delete this.dataChannels[n]}this.ws&&(this.ws.close(),this.ws=null),this.pc&&this.pc.close(),this.e2ee&&this.e2ee.terminateWorker(),this.initializeConnection();const n=this.soraCloseEvent("abend",e);this.callbacks.disconnect(n),this.writeSoraTimelineLog("disconnect-abend",n)}async abend(e,n){this.clearMonitorIceConnectionStateChange(),await this.stopStream(),this.pc&&(this.pc.ondatachannel=null,this.pc.oniceconnectionstatechange=null,this.pc.onicegatheringstatechange=null,this.pc.onconnectionstatechange=null),this.ws&&(this.ws.onclose=()=>{this.writeWebSocketTimelineLog("onclose")},this.ws.onmessage=null,this.ws.onerror=null);for(const i of Object.keys(this.dataChannels)){const e=this.dataChannels[i];e&&(e.onclose=e=>{const n=e.currentTarget;this.writeDataChannelTimelineLog("onclose",n),this.trace("CLOSE DATA CHANNEL",n.label)},e.onmessage=null,e.onerror=null)}try{await this.disconnectDataChannel(e)}catch(e){}await this.disconnectWebSocket(e),await this.disconnectPeerConnection(),this.e2ee&&this.e2ee.terminateWorker(),this.initializeConnection();const i=this.soraCloseEvent("abend",e,n);this.writeSoraTimelineLog("disconnect-abend",i),this.callbacks.disconnect(this.soraCloseEvent("abend",e,n))}initializeConnection(){this.clientId=null,this.connectionId=null,this.remoteConnectionIds=[],this.stream=null,this.ws=null,this.pc=null,this.encodings=[],this.authMetadata=null,this.e2ee=null,this.dataChannels={},this.mids={audio:"",video:""},this.signalingSwitched=!1,this.clearConnectionTimeout()}disconnectWebSocket(e){let n=0;return this.signalingSwitched?(this.ws&&(this.ws.close(),this.ws=null),Promise.resolve(null)):new Promise(i=>{if(!this.ws)return i(null);if(this.ws.onclose=e=>(this.ws&&(this.ws.close(),this.ws=null),clearTimeout(n),this.writeWebSocketTimelineLog("onclose",{code:e.code,reason:e.reason}),i({code:e.code,reason:e.reason})),1===this.ws.readyState){const i={type:"disconnect",reason:e};this.ws.send(JSON.stringify(i)),this.writeWebSocketSignalingLog("send-disconnect",i),n=setTimeout(()=>{this.ws&&(this.ws.close(),this.ws=null)},this.disconnectWaitTimeout)}else return this.ws.close(),this.ws=null,i(null)})}disconnectDataChannel(e){const n=()=>{for(const e of Object.keys(this.dataChannels)){const n=this.dataChannels[e];n&&n.close(),delete this.dataChannels[e]}};return new Promise((i,t)=>{if(!this.dataChannels.signaling)return n(),i();const g=setTimeout(()=>(n(),t()),this.disconnectWaitTimeout),a=[];for(const e of Object.keys(this.dataChannels)){const t=this.dataChannels[e];if(t){t.onerror=()=>{clearTimeout(g),n(),i()};a.push((()=>new Promise((e,n)=>"closed"===t.readyState?void e():void(t.onerror=()=>{n()},t.onclose=n=>{const i=n.currentTarget;this.writeDataChannelTimelineLog("onclose",i),this.trace("CLOSE DATA CHANNEL",i.label),"closed"===i.readyState&&e()})))())}}Promise.all(a).then(()=>{i()}).finally(()=>{n(),clearTimeout(g)});const l={type:"disconnect",reason:e};if(!0===this.dataChannelsCompress.signaling){const e=new TextEncoder().encode(JSON.stringify(l)),n=o(e,{});if("open"===this.dataChannels.signaling.readyState)try{this.dataChannels.signaling.send(n),this.writeDataChannelSignalingLog("send-disconnect",this.dataChannels.signaling,l)}catch(n){const e=n.message;this.writeDataChannelSignalingLog("failed-to-send-disconnect",this.dataChannels.signaling,e)}}else if("open"===this.dataChannels.signaling.readyState)try{this.dataChannels.signaling.send(JSON.stringify(l)),this.writeDataChannelSignalingLog("send-disconnect",this.dataChannels.signaling,l)}catch(n){const e=n.message;this.writeDataChannelSignalingLog("failed-to-send-disconnect",this.dataChannels.signaling,e)}})}disconnectPeerConnection(){return new Promise(e=>(this.pc&&"closed"!==this.pc.connectionState&&this.pc.close(),e()))}async disconnect(){this.clearMonitorIceConnectionStateChange(),await this.stopStream(),this.pc&&(this.pc.ondatachannel=null,this.pc.oniceconnectionstatechange=null,this.pc.onicegatheringstatechange=null,this.pc.onconnectionstatechange=null),this.ws&&(this.ws.onclose=()=>{this.writeWebSocketTimelineLog("onclose")},this.ws.onmessage=null,this.ws.onerror=null);for(const e of Object.keys(this.dataChannels)){const n=this.dataChannels[e];n&&(n.onmessage=null)}let e=null;if(this.signalingSwitched){e=this.soraCloseEvent("normal","DISCONNECT",{code:4999,reason:""});try{await this.disconnectDataChannel("NO-ERROR")}catch(n){e=this.soraCloseEvent("abend","DISCONNECT-TIMEOUT")}await this.disconnectWebSocket("NO-ERROR"),await this.disconnectPeerConnection()}else{const n=await this.disconnectWebSocket("NO-ERROR");await this.disconnectPeerConnection(),null!==n&&(e=this.soraCloseEvent("normal","DISCONNECT",n))}this.e2ee&&this.e2ee.terminateWorker(),this.initializeConnection(),e&&("abend"===e.type?this.writeSoraTimelineLog("disconnect-abend",e):"normal"===e.type&&this.writeSoraTimelineLog("disconnect-normal",e),this.callbacks.disconnect(e))}setupE2EE(){!0===this.options.e2ee&&(this.e2ee=new p,this.e2ee.onWorkerDisconnect=async()=>{await this.abend("INTERNAL-ERROR",{reason:"CRASH-E2EE-WORKER"})},this.e2ee.startWorker())}startE2EE(){if(!0===this.options.e2ee&&this.e2ee){if(!this.connectionId){const e=new Error;throw e.message=`E2EE failed. Self connectionId is null`,e}this.e2ee.clearWorker();const e=this.e2ee.start(this.connectionId);this.e2ee.postSelfSecretKeyMaterial(this.connectionId,e.selfKeyId,e.selfSecretKeyMaterial)}}signaling(e){return this.trace("CREATE OFFER",e),new Promise((n,i)=>{null===this.ws&&(this.ws=new WebSocket(this.signalingUrl),this.writeWebSocketSignalingLog("new-websocket",this.signalingUrl)),this.ws.binaryType="arraybuffer",this.ws.onclose=async e=>{const n=new Ae(`Signaling failed. CloseEventCode:${e.code} CloseEventReason:'${e.reason}'`);n.code=e.code,n.reason=e.reason,this.writeWebSocketTimelineLog("onclose",n),await this.signalingTerminate(),i(n)},this.ws.onopen=async()=>{this.writeWebSocketSignalingLog("onopen");let n;try{n=s(e.sdp||"",this.role,this.channelId,this.metadata,this.options)}catch(e){return void i(e)}if(n.e2ee&&this.e2ee){const e=await this.e2ee.init();n.signaling_notify_metadata.pre_key_bundle=e}this.trace("SIGNALING CONNECT MESSAGE",n),this.ws&&(this.ws.send(JSON.stringify(n)),this.writeWebSocketSignalingLog(`send-${n.type}`,n))},this.ws.onmessage=async e=>{if(e.data instanceof ArrayBuffer)return this.writeWebSocketSignalingLog("onmessage-e2ee",e.data),void this.signalingOnMessageE2EE(e.data);const i=JSON.parse(e.data);"offer"==i.type?(this.writeWebSocketSignalingLog("onmessage-offer",i),this.signalingOnMessageTypeOffer(i),n(i)):"update"==i.type?(this.writeWebSocketSignalingLog("onmessage-update",i),await this.signalingOnMessageTypeUpdate(i)):"re-offer"==i.type?(this.writeWebSocketSignalingLog("onmessage-re-offer",i),await this.signalingOnMessageTypeReOffer(i)):"ping"==i.type?await this.signalingOnMessageTypePing(i):"push"==i.type?this.callbacks.push(i,"websocket"):"notify"==i.type?("connection.created"===i.event_type?this.writeWebSocketTimelineLog("notify-connection.created",i):"connection.destroyed"===i.event_type&&this.writeWebSocketTimelineLog("notify-connection.destroyed",i),this.signalingOnMessageTypeNotify(i,"websocket")):"switched"==i.type&&(this.writeWebSocketSignalingLog("onmessage-switched",i),this.signalingOnMessageTypeSwitched(i))}})}async createOffer(){const e=new window.RTCPeerConnection({iceServers:[]});if(C()){e.addTransceiver("video",{direction:"recvonly"}),e.addTransceiver("audio",{direction:"recvonly"});const n=await e.createOffer();return e.close(),this.writePeerConnectionTimelineLog("create-offer",n),n}const n=await e.createOffer({offerToReceiveAudio:!0,offerToReceiveVideo:!0});return e.close(),this.writePeerConnectionTimelineLog("create-offer",n),n}async connectPeerConnection(e){let n=Object.assign({},e.config);if(this.e2ee&&(n=Object.assign({encodedInsertableStreams:!0},n)),void 0!==window.RTCPeerConnection.generateCertificate){const e=await window.RTCPeerConnection.generateCertificate({name:"ECDSA",namedCurve:"P-256"});n=Object.assign({certificates:[e]},n)}return this.trace("PEER CONNECTION CONFIG",n),this.writePeerConnectionTimelineLog("new-peerconnection",n),this.pc=new window.RTCPeerConnection(n,this.constraints),this.pc.oniceconnectionstatechange=()=>{this.pc&&(this.writePeerConnectionTimelineLog("oniceconnectionstatechange",{connectionState:this.pc.connectionState,iceConnectionState:this.pc.iceConnectionState,iceGatheringState:this.pc.iceGatheringState}),this.trace("ONICECONNECTIONSTATECHANGE ICECONNECTIONSTATE",this.pc.iceConnectionState))},this.pc.onicegatheringstatechange=()=>{this.pc&&this.writePeerConnectionTimelineLog("onicegatheringstatechange",{connectionState:this.pc.connectionState,iceConnectionState:this.pc.iceConnectionState,iceGatheringState:this.pc.iceGatheringState})},this.pc.onconnectionstatechange=()=>{this.pc&&this.writePeerConnectionTimelineLog("onconnectionstatechange",{connectionState:this.pc.connectionState,iceConnectionState:this.pc.iceConnectionState,iceGatheringState:this.pc.iceGatheringState})},void(this.pc.ondatachannel=e=>{this.onDataChannel(e)})}async setRemoteDescription(e){if(this.pc){const n=new RTCSessionDescription({type:"offer",sdp:e.sdp});return await this.pc.setRemoteDescription(n),void this.writePeerConnectionTimelineLog("set-remote-description",n)}}async createAnswer(e){if(this.pc){for(const e of Object.values(this.mids)){const n=this.pc.getTransceivers().find(n=>n.mid===e);n&&"recvonly"===n.direction&&(n.direction="sendrecv")}if(this.options.simulcast&&("sendrecv"===this.role||"sendonly"===this.role)){const n=this.pc.getTransceivers().find(e=>{if(e.mid&&0<=e.mid.indexOf("video")&&null!==e.sender.track&&(null===e.currentDirection||"sendonly"===e.currentDirection))return e});if(n){await this.setSenderParameters(n,this.encodings),await this.setRemoteDescription(e),this.trace("TRANSCEIVER SENDER GET_PARAMETERS",n.sender.getParameters()),await this.setSenderParameters(n,this.encodings);const i=await this.pc.createAnswer();return await this.pc.setLocalDescription(i),void this.trace("TRANSCEIVER SENDER GET_PARAMETERS",n.sender.getParameters())}}const n=await this.pc.createAnswer();return this.writePeerConnectionTimelineLog("create-answer",n),await this.pc.setLocalDescription(n),void this.writePeerConnectionTimelineLog("set-local-description",n)}}sendAnswer(){if(this.pc&&this.ws&&this.pc.localDescription){this.trace("ANSWER SDP",this.pc.localDescription.sdp);const e={type:"answer",sdp:this.pc.localDescription.sdp};this.ws.send(JSON.stringify(e)),this.writeWebSocketSignalingLog("send-answer",e)}}onIceCandidate(){return new Promise(e=>{this.pc&&(this.pc.oniceconnectionstatechange=()=>{this.pc&&(this.writePeerConnectionTimelineLog("oniceconnectionstatechange",{connectionState:this.pc.connectionState,iceConnectionState:this.pc.iceConnectionState,iceGatheringState:this.pc.iceGatheringState}),this.trace("ONICECONNECTIONSTATECHANGE ICECONNECTIONSTATE",this.pc.iceConnectionState),"connected"===this.pc.iceConnectionState&&e())},this.pc.onicecandidate=n=>{if(this.writePeerConnectionTimelineLog("onicecandidate",n.candidate),this.pc&&this.trace("ONICECANDIDATE ICEGATHERINGSTATE",this.pc.iceGatheringState),null===n.candidate)e();else{const e=n.candidate.toJSON(),i=Object.assign(e,{type:"candidate"});this.trace("ONICECANDIDATE CANDIDATE MESSAGE",i),this.sendMessage(i)}})})}waitChangeConnectionStateConnected(){return new Promise((e,n)=>{if(this.pc&&void 0===this.pc.connectionState)return void e();const i=setInterval(()=>{if(!this.pc){const e=new Error;e.message="PeerConnection connectionState did not change to 'connected'",clearInterval(i),n(e)}else this.pc&&"connected"===this.pc.connectionState&&(clearInterval(i),e())},10)})}monitorSignalingWebSocketEvent(){return new Promise((e,n)=>{this.monitorSignalingWebSocketEventTimerId=setInterval(()=>{this.ws&&(this.clearMonitorSignalingWebSocketEvent(),this.ws.onclose=async e=>{const i=new Ae(`Signaling failed. CloseEventCode:${e.code} CloseEventReason:'${e.reason}'`);i.code=e.code,i.reason=e.reason,this.writeWebSocketTimelineLog("onclose",i),await this.signalingTerminate(),n(i)},this.ws.onerror=async()=>{const e=new Ae(`Signaling failed. WebSocket onerror was called`);this.writeWebSocketSignalingLog("onerror",e),await this.signalingTerminate(),n(e)})},100)})}monitorWebSocketEvent(){this.ws&&(this.ws.onclose=async e=>{this.writeWebSocketTimelineLog("onclose"),1e3===e.code||1005===e.code?await this.disconnect():await this.abend("WEBSOCKET-ONCLOSE",{code:e.code,reason:e.reason})},this.ws.onerror=async()=>{this.writeWebSocketSignalingLog("onerror"),await this.abend("WEBSOCKET-ONERROR")})}monitorPeerConnectionState(){this.pc&&(this.pc.oniceconnectionstatechange=async()=>{this.pc&&this.pc.connectionState===void 0&&(this.writePeerConnectionTimelineLog("oniceconnectionstatechange",{connectionState:this.pc.connectionState,iceConnectionState:this.pc.iceConnectionState,iceGatheringState:this.pc.iceGatheringState}),this.trace("ONICECONNECTIONSTATECHANGE ICECONNECTIONSTATE",this.pc.iceConnectionState),clearTimeout(this.monitorIceConnectionStateChangeTimerId),"failed"===this.pc.iceConnectionState?await this.abendPeerConnectionState("ICE-CONNECTION-STATE-FAILED"):"disconnected"===this.pc.iceConnectionState&&(this.monitorIceConnectionStateChangeTimerId=setTimeout(async()=>{this.pc&&"disconnected"===this.pc.iceConnectionState&&(await this.abendPeerConnectionState("ICE-CONNECTION-STATE-DISCONNECTED-TIMEOUT"))},1e4)))},this.pc.onconnectionstatechange=async()=>{this.pc&&(this.writePeerConnectionTimelineLog("onconnectionstatechange",{connectionState:this.pc.connectionState,iceConnectionState:this.pc.iceConnectionState,iceGatheringState:this.pc.iceGatheringState}),"failed"===this.pc.connectionState&&(await this.abendPeerConnectionState("CONNECTION-STATE-FAILED")))})}setConnectionTimeout(){return new Promise((e,n)=>{0{if(!this.pc||this.pc&&this.pc.connectionState!==void 0&&"connected"!==this.pc.connectionState){const e=new Error;e.message="Signaling connection timeout",this.callbacks.timeout(),this.trace("DISCONNECT","Signaling connection timeout"),this.writePeerConnectionTimelineLog("signaling-connection-timeout",{connectionTimeout:this.connectionTimeout}),await this.signalingTerminate(),n(e)}},this.connectionTimeout))})}clearConnectionTimeout(){clearTimeout(this.connectionTimeoutTimerId)}clearMonitorSignalingWebSocketEvent(){clearInterval(this.monitorSignalingWebSocketEventTimerId)}clearMonitorIceConnectionStateChange(){clearInterval(this.monitorIceConnectionStateChangeTimerId)}trace(e,n){this.callbacks.log(e,n);this.debug&&A(this.clientId,e,n)}writeWebSocketSignalingLog(e,n){this.callbacks.signaling(Z(e,n,"websocket")),this.writeWebSocketTimelineLog(e,n)}writeDataChannelSignalingLog(e,n,i){this.callbacks.signaling(Z(e,i,"datachannel")),this.writeDataChannelTimelineLog(e,n,i)}writeWebSocketTimelineLog(e,n){const i=b(e,n,"websocket");this.callbacks.timeline(i)}writeDataChannelTimelineLog(e,n,i){const t=b(e,i,"datachannel",n.id,n.label);this.callbacks.timeline(t)}writePeerConnectionTimelineLog(e,n){const i=b(e,n,"peerconnection");this.callbacks.timeline(i)}writeSoraTimelineLog(e,n){const i=b(e,n,"sora");this.callbacks.timeline(i)}signalingOnMessageE2EE(e){if(this.e2ee){const n=new Uint8Array(e),i=this.e2ee.receiveMessage(n);this.e2ee.postRemoteSecretKeyMaterials(i),i.messages.forEach(e=>{this.sendE2EEMessage(e.buffer)})}}signalingOnMessageTypeOffer(e){if(this.clientId=e.client_id,this.connectionId=e.connection_id,void 0!==e.metadata&&(this.authMetadata=e.metadata),Array.isArray(e.encodings)&&(this.encodings=e.encodings),void 0!==e.mid&&void 0!==e.mid.audio&&(this.mids.audio=e.mid.audio),void 0!==e.mid&&void 0!==e.mid.video&&(this.mids.video=e.mid.video),e.data_channels)for(const n of e.data_channels)this.dataChannelsCompress[n.label]=n.compress;this.trace("SIGNALING OFFER MESSAGE",e),this.trace("OFFER SDP",e.sdp)}sendUpdateAnswer(){this.pc&&this.ws&&this.pc.localDescription&&(this.trace("ANSWER SDP",this.pc.localDescription.sdp),this.sendMessage({type:"update",sdp:this.pc.localDescription.sdp}))}sendReAnswer(){this.pc&&this.pc.localDescription&&(this.trace("RE ANSWER SDP",this.pc.localDescription.sdp),this.sendMessage({type:"re-answer",sdp:this.pc.localDescription.sdp}))}async signalingOnMessageTypeUpdate(e){this.trace("SIGNALING UPDATE MESSGE",e),this.trace("UPDATE SDP",e.sdp),await this.setRemoteDescription(e),await this.createAnswer(e),this.sendUpdateAnswer()}async signalingOnMessageTypeReOffer(e){this.trace("SIGNALING RE OFFER MESSGE",e),this.trace("RE OFFER SDP",e.sdp),await this.setRemoteDescription(e),await this.createAnswer(e),this.sendReAnswer()}async signalingOnMessageTypePing(e){const n={type:"pong"};if(e.stats){const e=await this.getStats();n.stats=e}this.ws&&this.ws.send(JSON.stringify(n))}signalingOnMessageTypeNotify(e,n){if("connection.created"===e.event_type){const n=e.connection_id;if(this.connectionId!==n){const i=I(e),t=m(i);if(t&&this.e2ee&&n){const e=this.e2ee.startSession(n,t);this.e2ee.postRemoteSecretKeyMaterials(e),e.messages.forEach(e=>{this.sendE2EEMessage(e.buffer)}),this.e2ee.postSelfSecretKeyMaterial(e.selfConnectionId,e.selfKeyId,e.selfSecretKeyMaterial)}}const i=r(e);i.forEach(e=>{const n=I(e),i=m(n),t=e.connection_id;t&&this.e2ee&&i&&this.e2ee.addPreKeyBundle(t,i)})}else if("connection.destroyed"===e.event_type){const n=I(e),i=m(n),t=e.connection_id;if(i&&this.e2ee&&t){const e=this.e2ee.stopSession(t);this.e2ee.postSelfSecretKeyMaterial(e.selfConnectionId,e.selfKeyId,e.selfSecretKeyMaterial,5e3),e.messages.forEach(e=>{this.sendE2EEMessage(e.buffer)}),this.e2ee.postRemoveRemoteDeriveKey(t)}}this.callbacks.notify(e,n)}signalingOnMessageTypeSwitched(e){this.signalingSwitched=!0;!this.ws||e.ignore_disconnect_websocket&&(this.ws&&(this.ws.onclose=null,this.ws.close(),this.ws=null),this.writeWebSocketSignalingLog("close"))}async setSenderParameters(e,n){const i=e.sender.getParameters();return i.encodings=n,await e.sender.setParameters(i),this.trace("TRANSCEIVER SENDER SET_PARAMETERS",i),void this.writePeerConnectionTimelineLog("transceiver-sender-set-parameters",i)}async getStats(){const e=[];if(!this.pc)return e;const n=await this.pc.getStats();return n.forEach(n=>{e.push(n)}),e}onDataChannel(e){const n=e.channel;this.writeDataChannelTimelineLog("ondatachannel",n,u(n)),e.channel.onbufferedamountlow=e=>{const n=e.currentTarget;this.writeDataChannelTimelineLog("onbufferedamountlow",n)},e.channel.onopen=e=>{const n=e.currentTarget;n.bufferedAmountLowThreshold=65536,n.binaryType="arraybuffer",this.dataChannels[n.label]=n,this.trace("OPEN DATA CHANNEL",n.label),"signaling"===n.label&&this.ws?this.writeDataChannelSignalingLog("onopen",n):this.writeDataChannelTimelineLog("onopen",n)},e.channel.onclose=async e=>{const n=e.currentTarget;this.writeDataChannelTimelineLog("onclose",n),this.trace("CLOSE DATA CHANNEL",n.label),await this.disconnect()},e.channel.onerror=async e=>{const n=e.currentTarget;this.writeDataChannelTimelineLog("onerror",n),this.trace("ERROR DATA CHANNEL",n.label),await this.abend("DATA-CHANNEL-ONERROR",{label:n.label})},"signaling"===e.channel.label?e.channel.onmessage=async e=>{const n=e.currentTarget;let i=e.data;if(!0===this.dataChannelsCompress.signaling){const n=l(new Uint8Array(e.data));i=new TextDecoder().decode(n)}const t=JSON.parse(i);this.writeDataChannelSignalingLog(`onmessage-${t.type}`,n,t),"re-offer"===t.type&&(await this.signalingOnMessageTypeReOffer(t))}:"notify"===e.channel.label?e.channel.onmessage=e=>{const n=e.currentTarget;let i=e.data;if(!0===this.dataChannelsCompress.notify){const n=l(new Uint8Array(e.data));i=new TextDecoder().decode(n)}const t=JSON.parse(i);"connection.created"===t.event_type?this.writeDataChannelTimelineLog("notify-connection.created",n,t):"connection.destroyed"===t.event_type&&this.writeDataChannelTimelineLog("notify-connection.destroyed",n,t),this.signalingOnMessageTypeNotify(t,"datachannel")}:"push"===e.channel.label?e.channel.onmessage=e=>{let n=e.data;if(!0===this.dataChannelsCompress.push){const i=l(new Uint8Array(e.data));n=new TextDecoder().decode(i)}const i=JSON.parse(n);this.callbacks.push(i,"datachannel")}:"e2ee"===e.channel.label?e.channel.onmessage=e=>{const n=e.currentTarget,i=e.data;this.signalingOnMessageE2EE(i),this.writeDataChannelSignalingLog("onmessage-e2ee",n,i)}:"stats"===e.channel.label&&(e.channel.onmessage=async e=>{let n=e.data;if(!0===this.dataChannelsCompress.stats){const i=l(new Uint8Array(e.data));n=new TextDecoder().decode(i)}const i=JSON.parse(n);if("req-stats"===i.type){const e=await this.getStats();this.sendStatsMessage(e)}})}sendMessage(e){if(this.dataChannels.signaling){if(!0===this.dataChannelsCompress.signaling){const n=new TextEncoder().encode(JSON.stringify(e)),i=o(n,{});this.dataChannels.signaling.send(i)}else this.dataChannels.signaling.send(JSON.stringify(e));this.callbacks.signaling(Z(`send-${e.type}`,e,"datachannel"))}else null!==this.ws&&(this.ws.send(JSON.stringify(e)),this.callbacks.signaling(Z(`send-${e.type}`,e,"websocket")))}sendE2EEMessage(e){this.dataChannels.e2ee?(this.dataChannels.e2ee.send(e),this.writeDataChannelSignalingLog("send-e2ee",this.dataChannels.e2ee,e)):null!==this.ws&&(this.ws.send(e),this.writeWebSocketSignalingLog("send-e2ee",e))}sendStatsMessage(e){if(this.dataChannels.stats){const n={type:"stats",reports:e};if(!0===this.dataChannelsCompress.stats){const e=new TextEncoder().encode(JSON.stringify(n)),i=o(e,{});this.dataChannels.stats.send(i)}else this.dataChannels.stats.send(JSON.stringify(n))}}getAudioTransceiver(){if(this.pc&&this.mids.audio){const e=this.pc.getTransceivers().find(e=>e.mid===this.mids.audio);return e||null}return null}getVideoTransceiver(){if(this.pc&&this.mids.video){const e=this.pc.getTransceivers().find(e=>e.mid===this.mids.video);return e||null}return null}soraCloseEvent(e,n,i){const t=class extends Event{constructor(e,n,i){super(e),i&&(i.code&&(this.code=i.code),i.reason&&(this.reason=i.reason),i.params&&(this.params=i.params)),this.title=n}};return new t(e,n,i)}get e2eeSelfFingerprint(){return this.options.e2ee&&this.e2ee?this.e2ee.selfFingerprint():void 0}get e2eeRemoteFingerprints(){return this.options.e2ee&&this.e2ee?this.e2ee.remoteFingerprints():void 0}get audio(){return null!==this.getAudioTransceiver()}get video(){return null!==this.getVideoTransceiver()}}class ue extends Ze{async connect(e){return this.options.multistream?await Promise.race([this.multiStream(e).finally(()=>{this.clearConnectionTimeout(),this.clearMonitorSignalingWebSocketEvent()}),this.setConnectionTimeout(),this.monitorSignalingWebSocketEvent()]):await Promise.race([this.singleStream(e).finally(()=>{this.clearConnectionTimeout(),this.clearMonitorSignalingWebSocketEvent()}),this.setConnectionTimeout(),this.monitorSignalingWebSocketEvent()]),this.monitorWebSocketEvent(),this.monitorPeerConnectionState(),e}async singleStream(e){await this.disconnect(),this.setupE2EE();const n=await this.createOffer(),i=await this.signaling(n);return this.startE2EE(),await this.connectPeerConnection(i),await this.setRemoteDescription(i),e.getTracks().forEach(n=>{this.pc&&this.pc.addTrack(n,e)}),this.stream=e,await this.createAnswer(i),this.sendAnswer(),this.pc&&this.e2ee&&this.pc.getSenders().forEach(e=>{this.e2ee&&this.e2ee.setupSenderTransform(e)}),await this.onIceCandidate(),await this.waitChangeConnectionStateConnected(),e}async multiStream(e){await this.disconnect(),this.setupE2EE();const n=await this.createOffer(),i=await this.signaling(n);return this.startE2EE(),await this.connectPeerConnection(i),this.pc&&(this.pc.ontrack=e=>{this.writePeerConnectionTimelineLog("ontrack");const n=e.streams[0];n&&"default"!==n.id&&n.id!==this.connectionId&&(this.e2ee&&this.e2ee.setupReceiverTransform(e.receiver),this.callbacks.track(e),n.onremovetrack=e=>{if(this.callbacks.removetrack(e),e.target){const n=this.remoteConnectionIds.indexOf(e.target.id);-1{this.pc&&this.pc.addTrack(n,e)}),this.stream=e,await this.createAnswer(i),this.sendAnswer(),this.pc&&this.e2ee&&this.pc.getSenders().forEach(e=>{this.e2ee&&this.e2ee.setupSenderTransform(e)}),await this.onIceCandidate(),await this.waitChangeConnectionStateConnected(),e}}class be extends Ze{async connect(){if(this.options.multistream)return await Promise.race([this.multiStream().finally(()=>{this.clearConnectionTimeout(),this.clearMonitorSignalingWebSocketEvent()}),this.setConnectionTimeout(),this.monitorSignalingWebSocketEvent()]),this.monitorWebSocketEvent(),void this.monitorPeerConnectionState();else{const e=await Promise.race([this.singleStream().finally(()=>{this.clearConnectionTimeout(),this.clearMonitorSignalingWebSocketEvent()}),this.setConnectionTimeout(),this.monitorSignalingWebSocketEvent()]);return this.monitorWebSocketEvent(),this.monitorPeerConnectionState(),e}}async singleStream(){await this.disconnect(),this.setupE2EE();const e=await this.createOffer(),n=await this.signaling(e);return this.startE2EE(),await this.connectPeerConnection(n),this.pc&&(this.pc.ontrack=e=>{this.writePeerConnectionTimelineLog("ontrack"),this.stream=e.streams[0];const n=this.stream.id;"default"!==n&&(this.e2ee&&this.e2ee.setupReceiverTransform(e.receiver),this.callbacks.track(e),this.stream.onremovetrack=e=>{if(this.callbacks.removetrack(e),e.target){const n=this.remoteConnectionIds.indexOf(e.target.id);-1{this.writePeerConnectionTimelineLog("ontrack");const n=e.streams[0];"default"!==n.id&&n.id!==this.connectionId&&(this.e2ee&&this.e2ee.setupReceiverTransform(e.receiver),this.callbacks.track(e),n.onremovetrack=e=>{if(this.callbacks.removetrack(e),e.target){const n=this.remoteConnectionIds.indexOf(e.target.id);-1 { return new Promise((res, rej) => { + if (dataChannel.readyState === "closed") { + res(); + return; + } dataChannel.onerror = () => { rej(); }; @@ -2260,7 +2264,9 @@ class ConnectionBase { const channel = event.currentTarget; this.writeDataChannelTimelineLog("onclose", channel); this.trace("CLOSE DATA CHANNEL", channel.label); - res(); + if (channel.readyState === "closed") { + res(); + } }; }); }; @@ -2364,7 +2370,12 @@ class ConnectionBase { } this.initializeConnection(); if (event) { - this.writeSoraTimelineLog("disconnect-normal", event); + if (event.type === "abend") { + this.writeSoraTimelineLog("disconnect-abend", event); + } + else if (event.type === "normal") { + this.writeSoraTimelineLog("disconnect-normal", event); + } this.callbacks.disconnect(event); } } @@ -3427,7 +3438,7 @@ var sora = { return new SoraConnection(signalingUrl, debug); }, version: function () { - return "2021.1.2"; + return "2021.1.3"; }, helpers: { applyMediaStreamConstraints, diff --git a/lerna.json b/lerna.json index 543c0c28..612d62a8 100644 --- a/lerna.json +++ b/lerna.json @@ -2,5 +2,5 @@ "packages": [ "packages/*" ], - "version": "2021.1.2" + "version": "2021.1.3" } diff --git a/package.json b/package.json index d1ae0245..f2a3d1e6 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "sora-js-sdk", - "version": "2021.1.2", + "version": "2021.1.3", "description": "WebRTC SFU Sora JavaScript SDK", "main": "dist/sora.min.js", "module": "dist/sora.mjs", diff --git a/packages/sdk/package.json b/packages/sdk/package.json index 6be0e668..0e0f49db 100644 --- a/packages/sdk/package.json +++ b/packages/sdk/package.json @@ -1,6 +1,6 @@ { "name": "@sora/sdk", - "version": "2021.1.2", + "version": "2021.1.3", "author": "Shiguredo Inc.", "license": "Apache-2.0", "main": "dist/sora.min.js",