diff --git a/CHANGELOG.md b/CHANGELOG.md index c5f8e38806..c72f2525f4 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -48,6 +48,9 @@ future styling). ## 1.7.12 +### JavaScript Client Bug Fixes + * Fix all unjoined channels from being removed from the socket when channel leave is called on any single unjoined channel instance + ### Enhancements * [phx.gen.auth] Add enhanced session fixation protection. For applications whichs previously used `phx.gen.auth`, the following line can be added to the `renew_session` function in the auth module: diff --git a/assets/js/phoenix/socket.js b/assets/js/phoenix/socket.js index 88866b8fd1..0ec992d3e3 100644 --- a/assets/js/phoenix/socket.js +++ b/assets/js/phoenix/socket.js @@ -543,7 +543,7 @@ export default class Socket { */ remove(channel){ this.off(channel.stateChangeRefs) - this.channels = this.channels.filter(c => c.joinRef() !== channel.joinRef()) + this.channels = this.channels.filter(c => c !== channel) } /** diff --git a/priv/static/phoenix.cjs.js b/priv/static/phoenix.cjs.js index 7b15531a0e..676c99a0a5 100644 --- a/priv/static/phoenix.cjs.js +++ b/priv/static/phoenix.cjs.js @@ -1461,7 +1461,7 @@ var Socket = class { */ remove(channel) { this.off(channel.stateChangeRefs); - this.channels = this.channels.filter((c) => c.joinRef() !== channel.joinRef()); + this.channels = this.channels.filter((c) => c !== channel); } /** * Removes `onOpen`, `onClose`, `onError,` and `onMessage` registrations. diff --git a/priv/static/phoenix.cjs.js.map b/priv/static/phoenix.cjs.js.map index 7c00d78c47..536e2669eb 100644 --- a/priv/static/phoenix.cjs.js.map +++ b/priv/static/phoenix.cjs.js.map @@ -1,7 +1,7 @@ { "version": 3, "sources": ["../../assets/js/phoenix/index.js", "../../assets/js/phoenix/utils.js", "../../assets/js/phoenix/constants.js", "../../assets/js/phoenix/push.js", "../../assets/js/phoenix/timer.js", "../../assets/js/phoenix/channel.js", "../../assets/js/phoenix/ajax.js", "../../assets/js/phoenix/longpoll.js", "../../assets/js/phoenix/presence.js", "../../assets/js/phoenix/serializer.js", "../../assets/js/phoenix/socket.js"], - "sourcesContent": ["/**\n * Phoenix Channels JavaScript client\n *\n * ## Socket Connection\n *\n * A single connection is established to the server and\n * channels are multiplexed over the connection.\n * Connect to the server using the `Socket` class:\n *\n * ```javascript\n * let socket = new Socket(\"/socket\", {params: {userToken: \"123\"}})\n * socket.connect()\n * ```\n *\n * The `Socket` constructor takes the mount point of the socket,\n * the authentication params, as well as options that can be found in\n * the Socket docs, such as configuring the `LongPoll` transport, and\n * heartbeat.\n *\n * ## Channels\n *\n * Channels are isolated, concurrent processes on the server that\n * subscribe to topics and broker events between the client and server.\n * To join a channel, you must provide the topic, and channel params for\n * authorization. Here's an example chat room example where `\"new_msg\"`\n * events are listened for, messages are pushed to the server, and\n * the channel is joined with ok/error/timeout matches:\n *\n * ```javascript\n * let channel = socket.channel(\"room:123\", {token: roomToken})\n * channel.on(\"new_msg\", msg => console.log(\"Got message\", msg) )\n * $input.onEnter( e => {\n * channel.push(\"new_msg\", {body: e.target.val}, 10000)\n * .receive(\"ok\", (msg) => console.log(\"created message\", msg) )\n * .receive(\"error\", (reasons) => console.log(\"create failed\", reasons) )\n * .receive(\"timeout\", () => console.log(\"Networking issue...\") )\n * })\n *\n * channel.join()\n * .receive(\"ok\", ({messages}) => console.log(\"catching up\", messages) )\n * .receive(\"error\", ({reason}) => console.log(\"failed join\", reason) )\n * .receive(\"timeout\", () => console.log(\"Networking issue. Still waiting...\"))\n *```\n *\n * ## Joining\n *\n * Creating a channel with `socket.channel(topic, params)`, binds the params to\n * `channel.params`, which are sent up on `channel.join()`.\n * Subsequent rejoins will send up the modified params for\n * updating authorization params, or passing up last_message_id information.\n * Successful joins receive an \"ok\" status, while unsuccessful joins\n * receive \"error\".\n *\n * With the default serializers and WebSocket transport, JSON text frames are\n * used for pushing a JSON object literal. If an `ArrayBuffer` instance is provided,\n * binary encoding will be used and the message will be sent with the binary\n * opcode.\n *\n * *Note*: binary messages are only supported on the WebSocket transport.\n *\n * ## Duplicate Join Subscriptions\n *\n * While the client may join any number of topics on any number of channels,\n * the client may only hold a single subscription for each unique topic at any\n * given time. When attempting to create a duplicate subscription,\n * the server will close the existing channel, log a warning, and\n * spawn a new channel for the topic. The client will have their\n * `channel.onClose` callbacks fired for the existing channel, and the new\n * channel join will have its receive hooks processed as normal.\n *\n * ## Pushing Messages\n *\n * From the previous example, we can see that pushing messages to the server\n * can be done with `channel.push(eventName, payload)` and we can optionally\n * receive responses from the push. Additionally, we can use\n * `receive(\"timeout\", callback)` to abort waiting for our other `receive` hooks\n * and take action after some period of waiting. The default timeout is 10000ms.\n *\n *\n * ## Socket Hooks\n *\n * Lifecycle events of the multiplexed connection can be hooked into via\n * `socket.onError()` and `socket.onClose()` events, ie:\n *\n * ```javascript\n * socket.onError( () => console.log(\"there was an error with the connection!\") )\n * socket.onClose( () => console.log(\"the connection dropped\") )\n * ```\n *\n *\n * ## Channel Hooks\n *\n * For each joined channel, you can bind to `onError` and `onClose` events\n * to monitor the channel lifecycle, ie:\n *\n * ```javascript\n * channel.onError( () => console.log(\"there was an error!\") )\n * channel.onClose( () => console.log(\"the channel has gone away gracefully\") )\n * ```\n *\n * ### onError hooks\n *\n * `onError` hooks are invoked if the socket connection drops, or the channel\n * crashes on the server. In either case, a channel rejoin is attempted\n * automatically in an exponential backoff manner.\n *\n * ### onClose hooks\n *\n * `onClose` hooks are invoked only in two cases. 1) the channel explicitly\n * closed on the server, or 2). The client explicitly closed, by calling\n * `channel.leave()`\n *\n *\n * ## Presence\n *\n * The `Presence` object provides features for syncing presence information\n * from the server with the client and handling presences joining and leaving.\n *\n * ### Syncing state from the server\n *\n * To sync presence state from the server, first instantiate an object and\n * pass your channel in to track lifecycle events:\n *\n * ```javascript\n * let channel = socket.channel(\"some:topic\")\n * let presence = new Presence(channel)\n * ```\n *\n * Next, use the `presence.onSync` callback to react to state changes\n * from the server. For example, to render the list of users every time\n * the list changes, you could write:\n *\n * ```javascript\n * presence.onSync(() => {\n * myRenderUsersFunction(presence.list())\n * })\n * ```\n *\n * ### Listing Presences\n *\n * `presence.list` is used to return a list of presence information\n * based on the local state of metadata. By default, all presence\n * metadata is returned, but a `listBy` function can be supplied to\n * allow the client to select which metadata to use for a given presence.\n * For example, you may have a user online from different devices with\n * a metadata status of \"online\", but they have set themselves to \"away\"\n * on another device. In this case, the app may choose to use the \"away\"\n * status for what appears on the UI. The example below defines a `listBy`\n * function which prioritizes the first metadata which was registered for\n * each user. This could be the first tab they opened, or the first device\n * they came online from:\n *\n * ```javascript\n * let listBy = (id, {metas: [first, ...rest]}) => {\n * first.count = rest.length + 1 // count of this user's presences\n * first.id = id\n * return first\n * }\n * let onlineUsers = presence.list(listBy)\n * ```\n *\n * ### Handling individual presence join and leave events\n *\n * The `presence.onJoin` and `presence.onLeave` callbacks can be used to\n * react to individual presences joining and leaving the app. For example:\n *\n * ```javascript\n * let presence = new Presence(channel)\n *\n * // detect if user has joined for the 1st time or from another tab/device\n * presence.onJoin((id, current, newPres) => {\n * if(!current){\n * console.log(\"user has entered for the first time\", newPres)\n * } else {\n * console.log(\"user additional presence\", newPres)\n * }\n * })\n *\n * // detect if user has left from all tabs/devices, or is still present\n * presence.onLeave((id, current, leftPres) => {\n * if(current.metas.length === 0){\n * console.log(\"user has left from all devices\", leftPres)\n * } else {\n * console.log(\"user left from a device\", leftPres)\n * }\n * })\n * // receive presence data from server\n * presence.onSync(() => {\n * displayUsers(presence.list())\n * })\n * ```\n * @module phoenix\n */\n\nimport Channel from \"./channel\"\nimport LongPoll from \"./longpoll\"\nimport Presence from \"./presence\"\nimport Serializer from \"./serializer\"\nimport Socket from \"./socket\"\n\nexport {\n Channel,\n LongPoll,\n Presence,\n Serializer,\n Socket\n}\n", "// wraps value in closure or returns closure\nexport let closure = (value) => {\n if(typeof value === \"function\"){\n return value\n } else {\n let closure = function (){ return value }\n return closure\n }\n}\n", "export const globalSelf = typeof self !== \"undefined\" ? self : null\nexport const phxWindow = typeof window !== \"undefined\" ? window : null\nexport const global = globalSelf || phxWindow || global\nexport const DEFAULT_VSN = \"2.0.0\"\nexport const SOCKET_STATES = {connecting: 0, open: 1, closing: 2, closed: 3}\nexport const DEFAULT_TIMEOUT = 10000\nexport const WS_CLOSE_NORMAL = 1000\nexport const CHANNEL_STATES = {\n closed: \"closed\",\n errored: \"errored\",\n joined: \"joined\",\n joining: \"joining\",\n leaving: \"leaving\",\n}\nexport const CHANNEL_EVENTS = {\n close: \"phx_close\",\n error: \"phx_error\",\n join: \"phx_join\",\n reply: \"phx_reply\",\n leave: \"phx_leave\"\n}\n\nexport const TRANSPORTS = {\n longpoll: \"longpoll\",\n websocket: \"websocket\"\n}\nexport const XHR_STATES = {\n complete: 4\n}\n", "/**\n * Initializes the Push\n * @param {Channel} channel - The Channel\n * @param {string} event - The event, for example `\"phx_join\"`\n * @param {Object} payload - The payload, for example `{user_id: 123}`\n * @param {number} timeout - The push timeout in milliseconds\n */\nexport default class Push {\n constructor(channel, event, payload, timeout){\n this.channel = channel\n this.event = event\n this.payload = payload || function (){ return {} }\n this.receivedResp = null\n this.timeout = timeout\n this.timeoutTimer = null\n this.recHooks = []\n this.sent = false\n }\n\n /**\n *\n * @param {number} timeout\n */\n resend(timeout){\n this.timeout = timeout\n this.reset()\n this.send()\n }\n\n /**\n *\n */\n send(){\n if(this.hasReceived(\"timeout\")){ return }\n this.startTimeout()\n this.sent = true\n this.channel.socket.push({\n topic: this.channel.topic,\n event: this.event,\n payload: this.payload(),\n ref: this.ref,\n join_ref: this.channel.joinRef()\n })\n }\n\n /**\n *\n * @param {*} status\n * @param {*} callback\n */\n receive(status, callback){\n if(this.hasReceived(status)){\n callback(this.receivedResp.response)\n }\n\n this.recHooks.push({status, callback})\n return this\n }\n\n /**\n * @private\n */\n reset(){\n this.cancelRefEvent()\n this.ref = null\n this.refEvent = null\n this.receivedResp = null\n this.sent = false\n }\n\n /**\n * @private\n */\n matchReceive({status, response, _ref}){\n this.recHooks.filter(h => h.status === status)\n .forEach(h => h.callback(response))\n }\n\n /**\n * @private\n */\n cancelRefEvent(){\n if(!this.refEvent){ return }\n this.channel.off(this.refEvent)\n }\n\n /**\n * @private\n */\n cancelTimeout(){\n clearTimeout(this.timeoutTimer)\n this.timeoutTimer = null\n }\n\n /**\n * @private\n */\n startTimeout(){\n if(this.timeoutTimer){ this.cancelTimeout() }\n this.ref = this.channel.socket.makeRef()\n this.refEvent = this.channel.replyEventName(this.ref)\n\n this.channel.on(this.refEvent, payload => {\n this.cancelRefEvent()\n this.cancelTimeout()\n this.receivedResp = payload\n this.matchReceive(payload)\n })\n\n this.timeoutTimer = setTimeout(() => {\n this.trigger(\"timeout\", {})\n }, this.timeout)\n }\n\n /**\n * @private\n */\n hasReceived(status){\n return this.receivedResp && this.receivedResp.status === status\n }\n\n /**\n * @private\n */\n trigger(status, response){\n this.channel.trigger(this.refEvent, {status, response})\n }\n}\n", "/**\n *\n * Creates a timer that accepts a `timerCalc` function to perform\n * calculated timeout retries, such as exponential backoff.\n *\n * @example\n * let reconnectTimer = new Timer(() => this.connect(), function(tries){\n * return [1000, 5000, 10000][tries - 1] || 10000\n * })\n * reconnectTimer.scheduleTimeout() // fires after 1000\n * reconnectTimer.scheduleTimeout() // fires after 5000\n * reconnectTimer.reset()\n * reconnectTimer.scheduleTimeout() // fires after 1000\n *\n * @param {Function} callback\n * @param {Function} timerCalc\n */\nexport default class Timer {\n constructor(callback, timerCalc){\n this.callback = callback\n this.timerCalc = timerCalc\n this.timer = null\n this.tries = 0\n }\n\n reset(){\n this.tries = 0\n clearTimeout(this.timer)\n }\n\n /**\n * Cancels any previous scheduleTimeout and schedules callback\n */\n scheduleTimeout(){\n clearTimeout(this.timer)\n\n this.timer = setTimeout(() => {\n this.tries = this.tries + 1\n this.callback()\n }, this.timerCalc(this.tries + 1))\n }\n}\n", "import {closure} from \"./utils\"\nimport {\n CHANNEL_EVENTS,\n CHANNEL_STATES,\n} from \"./constants\"\n\nimport Push from \"./push\"\nimport Timer from \"./timer\"\n\n/**\n *\n * @param {string} topic\n * @param {(Object|function)} params\n * @param {Socket} socket\n */\nexport default class Channel {\n constructor(topic, params, socket){\n this.state = CHANNEL_STATES.closed\n this.topic = topic\n this.params = closure(params || {})\n this.socket = socket\n this.bindings = []\n this.bindingRef = 0\n this.timeout = this.socket.timeout\n this.joinedOnce = false\n this.joinPush = new Push(this, CHANNEL_EVENTS.join, this.params, this.timeout)\n this.pushBuffer = []\n this.stateChangeRefs = []\n\n this.rejoinTimer = new Timer(() => {\n if(this.socket.isConnected()){ this.rejoin() }\n }, this.socket.rejoinAfterMs)\n this.stateChangeRefs.push(this.socket.onError(() => this.rejoinTimer.reset()))\n this.stateChangeRefs.push(this.socket.onOpen(() => {\n this.rejoinTimer.reset()\n if(this.isErrored()){ this.rejoin() }\n })\n )\n this.joinPush.receive(\"ok\", () => {\n this.state = CHANNEL_STATES.joined\n this.rejoinTimer.reset()\n this.pushBuffer.forEach(pushEvent => pushEvent.send())\n this.pushBuffer = []\n })\n this.joinPush.receive(\"error\", () => {\n this.state = CHANNEL_STATES.errored\n if(this.socket.isConnected()){ this.rejoinTimer.scheduleTimeout() }\n })\n this.onClose(() => {\n this.rejoinTimer.reset()\n if(this.socket.hasLogger()) this.socket.log(\"channel\", `close ${this.topic} ${this.joinRef()}`)\n this.state = CHANNEL_STATES.closed\n this.socket.remove(this)\n })\n this.onError(reason => {\n if(this.socket.hasLogger()) this.socket.log(\"channel\", `error ${this.topic}`, reason)\n if(this.isJoining()){ this.joinPush.reset() }\n this.state = CHANNEL_STATES.errored\n if(this.socket.isConnected()){ this.rejoinTimer.scheduleTimeout() }\n })\n this.joinPush.receive(\"timeout\", () => {\n if(this.socket.hasLogger()) this.socket.log(\"channel\", `timeout ${this.topic} (${this.joinRef()})`, this.joinPush.timeout)\n let leavePush = new Push(this, CHANNEL_EVENTS.leave, closure({}), this.timeout)\n leavePush.send()\n this.state = CHANNEL_STATES.errored\n this.joinPush.reset()\n if(this.socket.isConnected()){ this.rejoinTimer.scheduleTimeout() }\n })\n this.on(CHANNEL_EVENTS.reply, (payload, ref) => {\n this.trigger(this.replyEventName(ref), payload)\n })\n }\n\n /**\n * Join the channel\n * @param {integer} timeout\n * @returns {Push}\n */\n join(timeout = this.timeout){\n if(this.joinedOnce){\n throw new Error(\"tried to join multiple times. 'join' can only be called a single time per channel instance\")\n } else {\n this.timeout = timeout\n this.joinedOnce = true\n this.rejoin()\n return this.joinPush\n }\n }\n\n /**\n * Hook into channel close\n * @param {Function} callback\n */\n onClose(callback){\n this.on(CHANNEL_EVENTS.close, callback)\n }\n\n /**\n * Hook into channel errors\n * @param {Function} callback\n */\n onError(callback){\n return this.on(CHANNEL_EVENTS.error, reason => callback(reason))\n }\n\n /**\n * Subscribes on channel events\n *\n * Subscription returns a ref counter, which can be used later to\n * unsubscribe the exact event listener\n *\n * @example\n * const ref1 = channel.on(\"event\", do_stuff)\n * const ref2 = channel.on(\"event\", do_other_stuff)\n * channel.off(\"event\", ref1)\n * // Since unsubscription, do_stuff won't fire,\n * // while do_other_stuff will keep firing on the \"event\"\n *\n * @param {string} event\n * @param {Function} callback\n * @returns {integer} ref\n */\n on(event, callback){\n let ref = this.bindingRef++\n this.bindings.push({event, ref, callback})\n return ref\n }\n\n /**\n * Unsubscribes off of channel events\n *\n * Use the ref returned from a channel.on() to unsubscribe one\n * handler, or pass nothing for the ref to unsubscribe all\n * handlers for the given event.\n *\n * @example\n * // Unsubscribe the do_stuff handler\n * const ref1 = channel.on(\"event\", do_stuff)\n * channel.off(\"event\", ref1)\n *\n * // Unsubscribe all handlers from event\n * channel.off(\"event\")\n *\n * @param {string} event\n * @param {integer} ref\n */\n off(event, ref){\n this.bindings = this.bindings.filter((bind) => {\n return !(bind.event === event && (typeof ref === \"undefined\" || ref === bind.ref))\n })\n }\n\n /**\n * @private\n */\n canPush(){ return this.socket.isConnected() && this.isJoined() }\n\n /**\n * Sends a message `event` to phoenix with the payload `payload`.\n * Phoenix receives this in the `handle_in(event, payload, socket)`\n * function. if phoenix replies or it times out (default 10000ms),\n * then optionally the reply can be received.\n *\n * @example\n * channel.push(\"event\")\n * .receive(\"ok\", payload => console.log(\"phoenix replied:\", payload))\n * .receive(\"error\", err => console.log(\"phoenix errored\", err))\n * .receive(\"timeout\", () => console.log(\"timed out pushing\"))\n * @param {string} event\n * @param {Object} payload\n * @param {number} [timeout]\n * @returns {Push}\n */\n push(event, payload, timeout = this.timeout){\n payload = payload || {}\n if(!this.joinedOnce){\n throw new Error(`tried to push '${event}' to '${this.topic}' before joining. Use channel.join() before pushing events`)\n }\n let pushEvent = new Push(this, event, function (){ return payload }, timeout)\n if(this.canPush()){\n pushEvent.send()\n } else {\n pushEvent.startTimeout()\n this.pushBuffer.push(pushEvent)\n }\n\n return pushEvent\n }\n\n /** Leaves the channel\n *\n * Unsubscribes from server events, and\n * instructs channel to terminate on server\n *\n * Triggers onClose() hooks\n *\n * To receive leave acknowledgements, use the `receive`\n * hook to bind to the server ack, ie:\n *\n * @example\n * channel.leave().receive(\"ok\", () => alert(\"left!\") )\n *\n * @param {integer} timeout\n * @returns {Push}\n */\n leave(timeout = this.timeout){\n this.rejoinTimer.reset()\n this.joinPush.cancelTimeout()\n\n this.state = CHANNEL_STATES.leaving\n let onClose = () => {\n if(this.socket.hasLogger()) this.socket.log(\"channel\", `leave ${this.topic}`)\n this.trigger(CHANNEL_EVENTS.close, \"leave\")\n }\n let leavePush = new Push(this, CHANNEL_EVENTS.leave, closure({}), timeout)\n leavePush.receive(\"ok\", () => onClose())\n .receive(\"timeout\", () => onClose())\n leavePush.send()\n if(!this.canPush()){ leavePush.trigger(\"ok\", {}) }\n\n return leavePush\n }\n\n /**\n * Overridable message hook\n *\n * Receives all events for specialized message handling\n * before dispatching to the channel callbacks.\n *\n * Must return the payload, modified or unmodified\n * @param {string} event\n * @param {Object} payload\n * @param {integer} ref\n * @returns {Object}\n */\n onMessage(_event, payload, _ref){ return payload }\n\n /**\n * @private\n */\n isMember(topic, event, payload, joinRef){\n if(this.topic !== topic){ return false }\n\n if(joinRef && joinRef !== this.joinRef()){\n if(this.socket.hasLogger()) this.socket.log(\"channel\", \"dropping outdated message\", {topic, event, payload, joinRef})\n return false\n } else {\n return true\n }\n }\n\n /**\n * @private\n */\n joinRef(){ return this.joinPush.ref }\n\n /**\n * @private\n */\n rejoin(timeout = this.timeout){\n if(this.isLeaving()){ return }\n this.socket.leaveOpenTopic(this.topic)\n this.state = CHANNEL_STATES.joining\n this.joinPush.resend(timeout)\n }\n\n /**\n * @private\n */\n trigger(event, payload, ref, joinRef){\n let handledPayload = this.onMessage(event, payload, ref, joinRef)\n if(payload && !handledPayload){ throw new Error(\"channel onMessage callbacks must return the payload, modified or unmodified\") }\n\n let eventBindings = this.bindings.filter(bind => bind.event === event)\n\n for(let i = 0; i < eventBindings.length; i++){\n let bind = eventBindings[i]\n bind.callback(handledPayload, ref, joinRef || this.joinRef())\n }\n }\n\n /**\n * @private\n */\n replyEventName(ref){ return `chan_reply_${ref}` }\n\n /**\n * @private\n */\n isClosed(){ return this.state === CHANNEL_STATES.closed }\n\n /**\n * @private\n */\n isErrored(){ return this.state === CHANNEL_STATES.errored }\n\n /**\n * @private\n */\n isJoined(){ return this.state === CHANNEL_STATES.joined }\n\n /**\n * @private\n */\n isJoining(){ return this.state === CHANNEL_STATES.joining }\n\n /**\n * @private\n */\n isLeaving(){ return this.state === CHANNEL_STATES.leaving }\n}\n", "import {\n global,\n XHR_STATES\n} from \"./constants\"\n\nexport default class Ajax {\n\n static request(method, endPoint, accept, body, timeout, ontimeout, callback){\n if(global.XDomainRequest){\n let req = new global.XDomainRequest() // IE8, IE9\n return this.xdomainRequest(req, method, endPoint, body, timeout, ontimeout, callback)\n } else {\n let req = new global.XMLHttpRequest() // IE7+, Firefox, Chrome, Opera, Safari\n return this.xhrRequest(req, method, endPoint, accept, body, timeout, ontimeout, callback)\n }\n }\n\n static xdomainRequest(req, method, endPoint, body, timeout, ontimeout, callback){\n req.timeout = timeout\n req.open(method, endPoint)\n req.onload = () => {\n let response = this.parseJSON(req.responseText)\n callback && callback(response)\n }\n if(ontimeout){ req.ontimeout = ontimeout }\n\n // Work around bug in IE9 that requires an attached onprogress handler\n req.onprogress = () => { }\n\n req.send(body)\n return req\n }\n\n static xhrRequest(req, method, endPoint, accept, body, timeout, ontimeout, callback){\n req.open(method, endPoint, true)\n req.timeout = timeout\n req.setRequestHeader(\"Content-Type\", accept)\n req.onerror = () => callback && callback(null)\n req.onreadystatechange = () => {\n if(req.readyState === XHR_STATES.complete && callback){\n let response = this.parseJSON(req.responseText)\n callback(response)\n }\n }\n if(ontimeout){ req.ontimeout = ontimeout }\n\n req.send(body)\n return req\n }\n\n static parseJSON(resp){\n if(!resp || resp === \"\"){ return null }\n\n try {\n return JSON.parse(resp)\n } catch (e){\n console && console.log(\"failed to parse JSON response\", resp)\n return null\n }\n }\n\n static serialize(obj, parentKey){\n let queryStr = []\n for(var key in obj){\n if(!Object.prototype.hasOwnProperty.call(obj, key)){ continue }\n let paramKey = parentKey ? `${parentKey}[${key}]` : key\n let paramVal = obj[key]\n if(typeof paramVal === \"object\"){\n queryStr.push(this.serialize(paramVal, paramKey))\n } else {\n queryStr.push(encodeURIComponent(paramKey) + \"=\" + encodeURIComponent(paramVal))\n }\n }\n return queryStr.join(\"&\")\n }\n\n static appendParams(url, params){\n if(Object.keys(params).length === 0){ return url }\n\n let prefix = url.match(/\\?/) ? \"&\" : \"?\"\n return `${url}${prefix}${this.serialize(params)}`\n }\n}\n", "import {\n SOCKET_STATES,\n TRANSPORTS\n} from \"./constants\"\n\nimport Ajax from \"./ajax\"\n\nlet arrayBufferToBase64 = (buffer) => {\n let binary = \"\"\n let bytes = new Uint8Array(buffer)\n let len = bytes.byteLength\n for(let i = 0; i < len; i++){ binary += String.fromCharCode(bytes[i]) }\n return btoa(binary)\n}\n\nexport default class LongPoll {\n\n constructor(endPoint){\n this.endPoint = null\n this.token = null\n this.skipHeartbeat = true\n this.reqs = new Set()\n this.awaitingBatchAck = false\n this.currentBatch = null\n this.currentBatchTimer = null\n this.batchBuffer = []\n this.onopen = function (){ } // noop\n this.onerror = function (){ } // noop\n this.onmessage = function (){ } // noop\n this.onclose = function (){ } // noop\n this.pollEndpoint = this.normalizeEndpoint(endPoint)\n this.readyState = SOCKET_STATES.connecting\n // we must wait for the caller to finish setting up our callbacks and timeout properties\n setTimeout(() => this.poll(), 0)\n }\n\n normalizeEndpoint(endPoint){\n return (endPoint\n .replace(\"ws://\", \"http://\")\n .replace(\"wss://\", \"https://\")\n .replace(new RegExp(\"(.*)\\/\" + TRANSPORTS.websocket), \"$1/\" + TRANSPORTS.longpoll))\n }\n\n endpointURL(){\n return Ajax.appendParams(this.pollEndpoint, {token: this.token})\n }\n\n closeAndRetry(code, reason, wasClean){\n this.close(code, reason, wasClean)\n this.readyState = SOCKET_STATES.connecting\n }\n\n ontimeout(){\n this.onerror(\"timeout\")\n this.closeAndRetry(1005, \"timeout\", false)\n }\n\n isActive(){ return this.readyState === SOCKET_STATES.open || this.readyState === SOCKET_STATES.connecting }\n\n poll(){\n this.ajax(\"GET\", \"application/json\", null, () => this.ontimeout(), resp => {\n if(resp){\n var {status, token, messages} = resp\n this.token = token\n } else {\n status = 0\n }\n\n switch(status){\n case 200:\n messages.forEach(msg => {\n // Tasks are what things like event handlers, setTimeout callbacks,\n // promise resolves and more are run within.\n // In modern browsers, there are two different kinds of tasks,\n // microtasks and macrotasks.\n // Microtasks are mainly used for Promises, while macrotasks are\n // used for everything else.\n // Microtasks always have priority over macrotasks. If the JS engine\n // is looking for a task to run, it will always try to empty the\n // microtask queue before attempting to run anything from the\n // macrotask queue.\n //\n // For the WebSocket transport, messages always arrive in their own\n // event. This means that if any promises are resolved from within,\n // their callbacks will always finish execution by the time the\n // next message event handler is run.\n //\n // In order to emulate this behaviour, we need to make sure each\n // onmessage handler is run within its own macrotask.\n setTimeout(() => this.onmessage({data: msg}), 0)\n })\n this.poll()\n break\n case 204:\n this.poll()\n break\n case 410:\n this.readyState = SOCKET_STATES.open\n this.onopen({})\n this.poll()\n break\n case 403:\n this.onerror(403)\n this.close(1008, \"forbidden\", false)\n break\n case 0:\n case 500:\n this.onerror(500)\n this.closeAndRetry(1011, \"internal server error\", 500)\n break\n default: throw new Error(`unhandled poll status ${status}`)\n }\n })\n }\n\n // we collect all pushes within the current event loop by\n // setTimeout 0, which optimizes back-to-back procedural\n // pushes against an empty buffer\n\n send(body){\n if(typeof(body) !== \"string\"){ body = arrayBufferToBase64(body) }\n if(this.currentBatch){\n this.currentBatch.push(body)\n } else if(this.awaitingBatchAck){\n this.batchBuffer.push(body)\n } else {\n this.currentBatch = [body]\n this.currentBatchTimer = setTimeout(() => {\n this.batchSend(this.currentBatch)\n this.currentBatch = null\n }, 0)\n }\n }\n\n batchSend(messages){\n this.awaitingBatchAck = true\n this.ajax(\"POST\", \"application/x-ndjson\", messages.join(\"\\n\"), () => this.onerror(\"timeout\"), resp => {\n this.awaitingBatchAck = false\n if(!resp || resp.status !== 200){\n this.onerror(resp && resp.status)\n this.closeAndRetry(1011, \"internal server error\", false)\n } else if(this.batchBuffer.length > 0){\n this.batchSend(this.batchBuffer)\n this.batchBuffer = []\n }\n })\n }\n\n close(code, reason, wasClean){\n for(let req of this.reqs){ req.abort() }\n this.readyState = SOCKET_STATES.closed\n let opts = Object.assign({code: 1000, reason: undefined, wasClean: true}, {code, reason, wasClean})\n this.batchBuffer = []\n clearTimeout(this.currentBatchTimer)\n this.currentBatchTimer = null\n if(typeof(CloseEvent) !== \"undefined\"){\n this.onclose(new CloseEvent(\"close\", opts))\n } else {\n this.onclose(opts)\n }\n }\n\n ajax(method, contentType, body, onCallerTimeout, callback){\n let req\n let ontimeout = () => {\n this.reqs.delete(req)\n onCallerTimeout()\n }\n req = Ajax.request(method, this.endpointURL(), contentType, body, this.timeout, ontimeout, resp => {\n this.reqs.delete(req)\n if(this.isActive()){ callback(resp) }\n })\n this.reqs.add(req)\n }\n}\n", "/**\n * Initializes the Presence\n * @param {Channel} channel - The Channel\n * @param {Object} opts - The options,\n * for example `{events: {state: \"state\", diff: \"diff\"}}`\n */\nexport default class Presence {\n\n constructor(channel, opts = {}){\n let events = opts.events || {state: \"presence_state\", diff: \"presence_diff\"}\n this.state = {}\n this.pendingDiffs = []\n this.channel = channel\n this.joinRef = null\n this.caller = {\n onJoin: function (){ },\n onLeave: function (){ },\n onSync: function (){ }\n }\n\n this.channel.on(events.state, newState => {\n let {onJoin, onLeave, onSync} = this.caller\n\n this.joinRef = this.channel.joinRef()\n this.state = Presence.syncState(this.state, newState, onJoin, onLeave)\n\n this.pendingDiffs.forEach(diff => {\n this.state = Presence.syncDiff(this.state, diff, onJoin, onLeave)\n })\n this.pendingDiffs = []\n onSync()\n })\n\n this.channel.on(events.diff, diff => {\n let {onJoin, onLeave, onSync} = this.caller\n\n if(this.inPendingSyncState()){\n this.pendingDiffs.push(diff)\n } else {\n this.state = Presence.syncDiff(this.state, diff, onJoin, onLeave)\n onSync()\n }\n })\n }\n\n onJoin(callback){ this.caller.onJoin = callback }\n\n onLeave(callback){ this.caller.onLeave = callback }\n\n onSync(callback){ this.caller.onSync = callback }\n\n list(by){ return Presence.list(this.state, by) }\n\n inPendingSyncState(){\n return !this.joinRef || (this.joinRef !== this.channel.joinRef())\n }\n\n // lower-level public static API\n\n /**\n * Used to sync the list of presences on the server\n * with the client's state. An optional `onJoin` and `onLeave` callback can\n * be provided to react to changes in the client's local presences across\n * disconnects and reconnects with the server.\n *\n * @returns {Presence}\n */\n static syncState(currentState, newState, onJoin, onLeave){\n let state = this.clone(currentState)\n let joins = {}\n let leaves = {}\n\n this.map(state, (key, presence) => {\n if(!newState[key]){\n leaves[key] = presence\n }\n })\n this.map(newState, (key, newPresence) => {\n let currentPresence = state[key]\n if(currentPresence){\n let newRefs = newPresence.metas.map(m => m.phx_ref)\n let curRefs = currentPresence.metas.map(m => m.phx_ref)\n let joinedMetas = newPresence.metas.filter(m => curRefs.indexOf(m.phx_ref) < 0)\n let leftMetas = currentPresence.metas.filter(m => newRefs.indexOf(m.phx_ref) < 0)\n if(joinedMetas.length > 0){\n joins[key] = newPresence\n joins[key].metas = joinedMetas\n }\n if(leftMetas.length > 0){\n leaves[key] = this.clone(currentPresence)\n leaves[key].metas = leftMetas\n }\n } else {\n joins[key] = newPresence\n }\n })\n return this.syncDiff(state, {joins: joins, leaves: leaves}, onJoin, onLeave)\n }\n\n /**\n *\n * Used to sync a diff of presence join and leave\n * events from the server, as they happen. Like `syncState`, `syncDiff`\n * accepts optional `onJoin` and `onLeave` callbacks to react to a user\n * joining or leaving from a device.\n *\n * @returns {Presence}\n */\n static syncDiff(state, diff, onJoin, onLeave){\n let {joins, leaves} = this.clone(diff)\n if(!onJoin){ onJoin = function (){ } }\n if(!onLeave){ onLeave = function (){ } }\n\n this.map(joins, (key, newPresence) => {\n let currentPresence = state[key]\n state[key] = this.clone(newPresence)\n if(currentPresence){\n let joinedRefs = state[key].metas.map(m => m.phx_ref)\n let curMetas = currentPresence.metas.filter(m => joinedRefs.indexOf(m.phx_ref) < 0)\n state[key].metas.unshift(...curMetas)\n }\n onJoin(key, currentPresence, newPresence)\n })\n this.map(leaves, (key, leftPresence) => {\n let currentPresence = state[key]\n if(!currentPresence){ return }\n let refsToRemove = leftPresence.metas.map(m => m.phx_ref)\n currentPresence.metas = currentPresence.metas.filter(p => {\n return refsToRemove.indexOf(p.phx_ref) < 0\n })\n onLeave(key, currentPresence, leftPresence)\n if(currentPresence.metas.length === 0){\n delete state[key]\n }\n })\n return state\n }\n\n /**\n * Returns the array of presences, with selected metadata.\n *\n * @param {Object} presences\n * @param {Function} chooser\n *\n * @returns {Presence}\n */\n static list(presences, chooser){\n if(!chooser){ chooser = function (key, pres){ return pres } }\n\n return this.map(presences, (key, presence) => {\n return chooser(key, presence)\n })\n }\n\n // private\n\n static map(obj, func){\n return Object.getOwnPropertyNames(obj).map(key => func(key, obj[key]))\n }\n\n static clone(obj){ return JSON.parse(JSON.stringify(obj)) }\n}\n", "/* The default serializer for encoding and decoding messages */\nimport {\n CHANNEL_EVENTS\n} from \"./constants\"\n\nexport default {\n HEADER_LENGTH: 1,\n META_LENGTH: 4,\n KINDS: {push: 0, reply: 1, broadcast: 2},\n\n encode(msg, callback){\n if(msg.payload.constructor === ArrayBuffer){\n return callback(this.binaryEncode(msg))\n } else {\n let payload = [msg.join_ref, msg.ref, msg.topic, msg.event, msg.payload]\n return callback(JSON.stringify(payload))\n }\n },\n\n decode(rawPayload, callback){\n if(rawPayload.constructor === ArrayBuffer){\n return callback(this.binaryDecode(rawPayload))\n } else {\n let [join_ref, ref, topic, event, payload] = JSON.parse(rawPayload)\n return callback({join_ref, ref, topic, event, payload})\n }\n },\n\n // private\n\n binaryEncode(message){\n let {join_ref, ref, event, topic, payload} = message\n let metaLength = this.META_LENGTH + join_ref.length + ref.length + topic.length + event.length\n let header = new ArrayBuffer(this.HEADER_LENGTH + metaLength)\n let view = new DataView(header)\n let offset = 0\n\n view.setUint8(offset++, this.KINDS.push) // kind\n view.setUint8(offset++, join_ref.length)\n view.setUint8(offset++, ref.length)\n view.setUint8(offset++, topic.length)\n view.setUint8(offset++, event.length)\n Array.from(join_ref, char => view.setUint8(offset++, char.charCodeAt(0)))\n Array.from(ref, char => view.setUint8(offset++, char.charCodeAt(0)))\n Array.from(topic, char => view.setUint8(offset++, char.charCodeAt(0)))\n Array.from(event, char => view.setUint8(offset++, char.charCodeAt(0)))\n\n var combined = new Uint8Array(header.byteLength + payload.byteLength)\n combined.set(new Uint8Array(header), 0)\n combined.set(new Uint8Array(payload), header.byteLength)\n\n return combined.buffer\n },\n\n binaryDecode(buffer){\n let view = new DataView(buffer)\n let kind = view.getUint8(0)\n let decoder = new TextDecoder()\n switch(kind){\n case this.KINDS.push: return this.decodePush(buffer, view, decoder)\n case this.KINDS.reply: return this.decodeReply(buffer, view, decoder)\n case this.KINDS.broadcast: return this.decodeBroadcast(buffer, view, decoder)\n }\n },\n\n decodePush(buffer, view, decoder){\n let joinRefSize = view.getUint8(1)\n let topicSize = view.getUint8(2)\n let eventSize = view.getUint8(3)\n let offset = this.HEADER_LENGTH + this.META_LENGTH - 1 // pushes have no ref\n let joinRef = decoder.decode(buffer.slice(offset, offset + joinRefSize))\n offset = offset + joinRefSize\n let topic = decoder.decode(buffer.slice(offset, offset + topicSize))\n offset = offset + topicSize\n let event = decoder.decode(buffer.slice(offset, offset + eventSize))\n offset = offset + eventSize\n let data = buffer.slice(offset, buffer.byteLength)\n return {join_ref: joinRef, ref: null, topic: topic, event: event, payload: data}\n },\n\n decodeReply(buffer, view, decoder){\n let joinRefSize = view.getUint8(1)\n let refSize = view.getUint8(2)\n let topicSize = view.getUint8(3)\n let eventSize = view.getUint8(4)\n let offset = this.HEADER_LENGTH + this.META_LENGTH\n let joinRef = decoder.decode(buffer.slice(offset, offset + joinRefSize))\n offset = offset + joinRefSize\n let ref = decoder.decode(buffer.slice(offset, offset + refSize))\n offset = offset + refSize\n let topic = decoder.decode(buffer.slice(offset, offset + topicSize))\n offset = offset + topicSize\n let event = decoder.decode(buffer.slice(offset, offset + eventSize))\n offset = offset + eventSize\n let data = buffer.slice(offset, buffer.byteLength)\n let payload = {status: event, response: data}\n return {join_ref: joinRef, ref: ref, topic: topic, event: CHANNEL_EVENTS.reply, payload: payload}\n },\n\n decodeBroadcast(buffer, view, decoder){\n let topicSize = view.getUint8(1)\n let eventSize = view.getUint8(2)\n let offset = this.HEADER_LENGTH + 2\n let topic = decoder.decode(buffer.slice(offset, offset + topicSize))\n offset = offset + topicSize\n let event = decoder.decode(buffer.slice(offset, offset + eventSize))\n offset = offset + eventSize\n let data = buffer.slice(offset, buffer.byteLength)\n\n return {join_ref: null, ref: null, topic: topic, event: event, payload: data}\n }\n}\n", "import {\n global,\n phxWindow,\n CHANNEL_EVENTS,\n DEFAULT_TIMEOUT,\n DEFAULT_VSN,\n SOCKET_STATES,\n TRANSPORTS,\n WS_CLOSE_NORMAL\n} from \"./constants\"\n\nimport {\n closure\n} from \"./utils\"\n\nimport Ajax from \"./ajax\"\nimport Channel from \"./channel\"\nimport LongPoll from \"./longpoll\"\nimport Serializer from \"./serializer\"\nimport Timer from \"./timer\"\n\n/** Initializes the Socket *\n *\n * For IE8 support use an ES5-shim (https://github.com/es-shims/es5-shim)\n *\n * @param {string} endPoint - The string WebSocket endpoint, ie, `\"ws://example.com/socket\"`,\n * `\"wss://example.com\"`\n * `\"/socket\"` (inherited host & protocol)\n * @param {Object} [opts] - Optional configuration\n * @param {Function} [opts.transport] - The Websocket Transport, for example WebSocket or Phoenix.LongPoll.\n *\n * Defaults to WebSocket with automatic LongPoll fallback if WebSocket is not defined.\n * To fallback to LongPoll when WebSocket attempts fail, use `longPollFallbackMs: 2500`.\n *\n * @param {Function} [opts.longPollFallbackMs] - The millisecond time to attempt the primary transport\n * before falling back to the LongPoll transport. Disabled by default.\n *\n * @param {Function} [opts.debug] - When true, enables debug logging. Default false.\n *\n * @param {Function} [opts.encode] - The function to encode outgoing messages.\n *\n * Defaults to JSON encoder.\n *\n * @param {Function} [opts.decode] - The function to decode incoming messages.\n *\n * Defaults to JSON:\n *\n * ```javascript\n * (payload, callback) => callback(JSON.parse(payload))\n * ```\n *\n * @param {number} [opts.timeout] - The default timeout in milliseconds to trigger push timeouts.\n *\n * Defaults `DEFAULT_TIMEOUT`\n * @param {number} [opts.heartbeatIntervalMs] - The millisec interval to send a heartbeat message\n * @param {number} [opts.reconnectAfterMs] - The optional function that returns the millisec\n * socket reconnect interval.\n *\n * Defaults to stepped backoff of:\n *\n * ```javascript\n * function(tries){\n * return [10, 50, 100, 150, 200, 250, 500, 1000, 2000][tries - 1] || 5000\n * }\n * ````\n *\n * @param {number} [opts.rejoinAfterMs] - The optional function that returns the millisec\n * rejoin interval for individual channels.\n *\n * ```javascript\n * function(tries){\n * return [1000, 2000, 5000][tries - 1] || 10000\n * }\n * ````\n *\n * @param {Function} [opts.logger] - The optional function for specialized logging, ie:\n *\n * ```javascript\n * function(kind, msg, data) {\n * console.log(`${kind}: ${msg}`, data)\n * }\n * ```\n *\n * @param {number} [opts.longpollerTimeout] - The maximum timeout of a long poll AJAX request.\n *\n * Defaults to 20s (double the server long poll timer).\n *\n * @param {(Object|function)} [opts.params] - The optional params to pass when connecting\n * @param {string} [opts.binaryType] - The binary type to use for binary WebSocket frames.\n *\n * Defaults to \"arraybuffer\"\n *\n * @param {vsn} [opts.vsn] - The serializer's protocol version to send on connect.\n *\n * Defaults to DEFAULT_VSN.\n *\n * @param {Object} [opts.sessionStorage] - An optional Storage compatible object\n * Phoenix uses sessionStorage for longpoll fallback history. Overriding the store is\n * useful when Phoenix won't have access to `sessionStorage`. For example, This could\n * happen if a site loads a cross-domain channel in an iframe. Example usage:\n *\n * class InMemoryStorage {\n * constructor() { this.storage = {} }\n * getItem(keyName) { return this.storage[keyName] || null }\n * removeItem(keyName) { delete this.storage[keyName] }\n * setItem(keyName, keyValue) { this.storage[keyName] = keyValue }\n * }\n *\n*/\nexport default class Socket {\n constructor(endPoint, opts = {}){\n this.stateChangeCallbacks = {open: [], close: [], error: [], message: []}\n this.channels = []\n this.sendBuffer = []\n this.ref = 0\n this.timeout = opts.timeout || DEFAULT_TIMEOUT\n this.transport = opts.transport || global.WebSocket || LongPoll\n this.primaryPassedHealthCheck = false\n this.longPollFallbackMs = opts.longPollFallbackMs\n this.fallbackTimer = null\n this.sessionStore = opts.sessionStorage || global.sessionStorage\n this.establishedConnections = 0\n this.defaultEncoder = Serializer.encode.bind(Serializer)\n this.defaultDecoder = Serializer.decode.bind(Serializer)\n this.closeWasClean = false\n this.binaryType = opts.binaryType || \"arraybuffer\"\n this.connectClock = 1\n if(this.transport !== LongPoll){\n this.encode = opts.encode || this.defaultEncoder\n this.decode = opts.decode || this.defaultDecoder\n } else {\n this.encode = this.defaultEncoder\n this.decode = this.defaultDecoder\n }\n let awaitingConnectionOnPageShow = null\n if(phxWindow && phxWindow.addEventListener){\n phxWindow.addEventListener(\"pagehide\", _e => {\n if(this.conn){\n this.disconnect()\n awaitingConnectionOnPageShow = this.connectClock\n }\n })\n phxWindow.addEventListener(\"pageshow\", _e => {\n if(awaitingConnectionOnPageShow === this.connectClock){\n awaitingConnectionOnPageShow = null\n this.connect()\n }\n })\n }\n this.heartbeatIntervalMs = opts.heartbeatIntervalMs || 30000\n this.rejoinAfterMs = (tries) => {\n if(opts.rejoinAfterMs){\n return opts.rejoinAfterMs(tries)\n } else {\n return [1000, 2000, 5000][tries - 1] || 10000\n }\n }\n this.reconnectAfterMs = (tries) => {\n if(opts.reconnectAfterMs){\n return opts.reconnectAfterMs(tries)\n } else {\n return [10, 50, 100, 150, 200, 250, 500, 1000, 2000][tries - 1] || 5000\n }\n }\n this.logger = opts.logger || null\n if(!this.logger && opts.debug){\n this.logger = (kind, msg, data) => { console.log(`${kind}: ${msg}`, data) }\n }\n this.longpollerTimeout = opts.longpollerTimeout || 20000\n this.params = closure(opts.params || {})\n this.endPoint = `${endPoint}/${TRANSPORTS.websocket}`\n this.vsn = opts.vsn || DEFAULT_VSN\n this.heartbeatTimeoutTimer = null\n this.heartbeatTimer = null\n this.pendingHeartbeatRef = null\n this.reconnectTimer = new Timer(() => {\n this.teardown(() => this.connect())\n }, this.reconnectAfterMs)\n }\n\n /**\n * Returns the LongPoll transport reference\n */\n getLongPollTransport(){ return LongPoll }\n\n /**\n * Disconnects and replaces the active transport\n *\n * @param {Function} newTransport - The new transport class to instantiate\n *\n */\n replaceTransport(newTransport){\n this.connectClock++\n this.closeWasClean = true\n clearTimeout(this.fallbackTimer)\n this.reconnectTimer.reset()\n if(this.conn){\n this.conn.close()\n this.conn = null\n }\n this.transport = newTransport\n }\n\n /**\n * Returns the socket protocol\n *\n * @returns {string}\n */\n protocol(){ return location.protocol.match(/^https/) ? \"wss\" : \"ws\" }\n\n /**\n * The fully qualified socket url\n *\n * @returns {string}\n */\n endPointURL(){\n let uri = Ajax.appendParams(\n Ajax.appendParams(this.endPoint, this.params()), {vsn: this.vsn})\n if(uri.charAt(0) !== \"/\"){ return uri }\n if(uri.charAt(1) === \"/\"){ return `${this.protocol()}:${uri}` }\n\n return `${this.protocol()}://${location.host}${uri}`\n }\n\n /**\n * Disconnects the socket\n *\n * See https://developer.mozilla.org/en-US/docs/Web/API/CloseEvent#Status_codes for valid status codes.\n *\n * @param {Function} callback - Optional callback which is called after socket is disconnected.\n * @param {integer} code - A status code for disconnection (Optional).\n * @param {string} reason - A textual description of the reason to disconnect. (Optional)\n */\n disconnect(callback, code, reason){\n this.connectClock++\n this.closeWasClean = true\n clearTimeout(this.fallbackTimer)\n this.reconnectTimer.reset()\n this.teardown(callback, code, reason)\n }\n\n /**\n *\n * @param {Object} params - The params to send when connecting, for example `{user_id: userToken}`\n *\n * Passing params to connect is deprecated; pass them in the Socket constructor instead:\n * `new Socket(\"/socket\", {params: {user_id: userToken}})`.\n */\n connect(params){\n if(params){\n console && console.log(\"passing params to connect is deprecated. Instead pass :params to the Socket constructor\")\n this.params = closure(params)\n }\n if(this.conn){ return }\n if(this.longPollFallbackMs && this.transport !== LongPoll){\n this.connectWithFallback(LongPoll, this.longPollFallbackMs)\n } else {\n this.transportConnect()\n }\n }\n\n /**\n * Logs the message. Override `this.logger` for specialized logging. noops by default\n * @param {string} kind\n * @param {string} msg\n * @param {Object} data\n */\n log(kind, msg, data){ this.logger && this.logger(kind, msg, data) }\n\n /**\n * Returns true if a logger has been set on this socket.\n */\n hasLogger(){ return this.logger !== null }\n\n /**\n * Registers callbacks for connection open events\n *\n * @example socket.onOpen(function(){ console.info(\"the socket was opened\") })\n *\n * @param {Function} callback\n */\n onOpen(callback){\n let ref = this.makeRef()\n this.stateChangeCallbacks.open.push([ref, callback])\n return ref\n }\n\n /**\n * Registers callbacks for connection close events\n * @param {Function} callback\n */\n onClose(callback){\n let ref = this.makeRef()\n this.stateChangeCallbacks.close.push([ref, callback])\n return ref\n }\n\n /**\n * Registers callbacks for connection error events\n *\n * @example socket.onError(function(error){ alert(\"An error occurred\") })\n *\n * @param {Function} callback\n */\n onError(callback){\n let ref = this.makeRef()\n this.stateChangeCallbacks.error.push([ref, callback])\n return ref\n }\n\n /**\n * Registers callbacks for connection message events\n * @param {Function} callback\n */\n onMessage(callback){\n let ref = this.makeRef()\n this.stateChangeCallbacks.message.push([ref, callback])\n return ref\n }\n\n /**\n * Pings the server and invokes the callback with the RTT in milliseconds\n * @param {Function} callback\n *\n * Returns true if the ping was pushed or false if unable to be pushed.\n */\n ping(callback){\n if(!this.isConnected()){ return false }\n let ref = this.makeRef()\n let startTime = Date.now()\n this.push({topic: \"phoenix\", event: \"heartbeat\", payload: {}, ref: ref})\n let onMsgRef = this.onMessage(msg => {\n if(msg.ref === ref){\n this.off([onMsgRef])\n callback(Date.now() - startTime)\n }\n })\n return true\n }\n\n /**\n * @private\n */\n\n transportConnect(){\n this.connectClock++\n this.closeWasClean = false\n this.conn = new this.transport(this.endPointURL())\n this.conn.binaryType = this.binaryType\n this.conn.timeout = this.longpollerTimeout\n this.conn.onopen = () => this.onConnOpen()\n this.conn.onerror = error => this.onConnError(error)\n this.conn.onmessage = event => this.onConnMessage(event)\n this.conn.onclose = event => this.onConnClose(event)\n }\n\n getSession(key){ return this.sessionStore && this.sessionStore.getItem(key) }\n\n storeSession(key, val){ this.sessionStore && this.sessionStore.setItem(key, val) }\n\n connectWithFallback(fallbackTransport, fallbackThreshold = 2500){\n clearTimeout(this.fallbackTimer)\n let established = false\n let primaryTransport = true\n let openRef, errorRef\n let fallback = (reason) => {\n this.log(\"transport\", `falling back to ${fallbackTransport.name}...`, reason)\n this.off([openRef, errorRef])\n primaryTransport = false\n this.replaceTransport(fallbackTransport)\n this.transportConnect()\n }\n if(this.getSession(`phx:fallback:${fallbackTransport.name}`)){ return fallback(\"memorized\") }\n\n this.fallbackTimer = setTimeout(fallback, fallbackThreshold)\n\n errorRef = this.onError(reason => {\n this.log(\"transport\", \"error\", reason)\n if(primaryTransport && !established) {\n clearTimeout(this.fallbackTimer)\n fallback(reason)\n }\n })\n this.onOpen(() => {\n established = true\n if(!primaryTransport){\n // only memorize LP if we never connected to primary\n if(!this.primaryPassedHealthCheck){ this.storeSession(`phx:fallback:${fallbackTransport.name}`, \"true\") }\n return this.log(\"transport\", `established ${fallbackTransport.name} fallback`)\n }\n // if we've established primary, give the fallback a new period to attempt ping\n clearTimeout(this.fallbackTimer)\n this.fallbackTimer = setTimeout(fallback, fallbackThreshold)\n this.ping(rtt => {\n this.log(\"transport\", \"connected to primary after\", rtt)\n this.primaryPassedHealthCheck = true\n clearTimeout(this.fallbackTimer)\n })\n })\n this.transportConnect()\n }\n\n clearHeartbeats(){\n clearTimeout(this.heartbeatTimer)\n clearTimeout(this.heartbeatTimeoutTimer)\n }\n\n onConnOpen(){\n if(this.hasLogger()) this.log(\"transport\", `${this.transport.name} connected to ${this.endPointURL()}`)\n this.closeWasClean = false\n this.establishedConnections++\n this.flushSendBuffer()\n this.reconnectTimer.reset()\n this.resetHeartbeat()\n this.stateChangeCallbacks.open.forEach(([, callback]) => callback())\n }\n\n /**\n * @private\n */\n\n heartbeatTimeout(){\n if(this.pendingHeartbeatRef){\n this.pendingHeartbeatRef = null\n if(this.hasLogger()){ this.log(\"transport\", \"heartbeat timeout. Attempting to re-establish connection\") }\n this.triggerChanError()\n this.closeWasClean = false\n this.teardown(() => this.reconnectTimer.scheduleTimeout(), WS_CLOSE_NORMAL, \"heartbeat timeout\")\n }\n }\n\n resetHeartbeat(){\n if(this.conn && this.conn.skipHeartbeat){ return }\n this.pendingHeartbeatRef = null\n this.clearHeartbeats()\n this.heartbeatTimer = setTimeout(() => this.sendHeartbeat(), this.heartbeatIntervalMs)\n }\n\n teardown(callback, code, reason){\n if(!this.conn){\n return callback && callback()\n }\n\n this.waitForBufferDone(() => {\n if(this.conn){\n if(code){ this.conn.close(code, reason || \"\") } else { this.conn.close() }\n }\n\n this.waitForSocketClosed(() => {\n if(this.conn){\n this.conn.onopen = function (){ } // noop\n this.conn.onerror = function (){ } // noop\n this.conn.onmessage = function (){ } // noop\n this.conn.onclose = function (){ } // noop\n this.conn = null\n }\n\n callback && callback()\n })\n })\n }\n\n waitForBufferDone(callback, tries = 1){\n if(tries === 5 || !this.conn || !this.conn.bufferedAmount){\n callback()\n return\n }\n\n setTimeout(() => {\n this.waitForBufferDone(callback, tries + 1)\n }, 150 * tries)\n }\n\n waitForSocketClosed(callback, tries = 1){\n if(tries === 5 || !this.conn || this.conn.readyState === SOCKET_STATES.closed){\n callback()\n return\n }\n\n setTimeout(() => {\n this.waitForSocketClosed(callback, tries + 1)\n }, 150 * tries)\n }\n\n onConnClose(event){\n let closeCode = event && event.code\n if(this.hasLogger()) this.log(\"transport\", \"close\", event)\n this.triggerChanError()\n this.clearHeartbeats()\n if(!this.closeWasClean && closeCode !== 1000){\n this.reconnectTimer.scheduleTimeout()\n }\n this.stateChangeCallbacks.close.forEach(([, callback]) => callback(event))\n }\n\n /**\n * @private\n */\n onConnError(error){\n if(this.hasLogger()) this.log(\"transport\", error)\n let transportBefore = this.transport\n let establishedBefore = this.establishedConnections\n this.stateChangeCallbacks.error.forEach(([, callback]) => {\n callback(error, transportBefore, establishedBefore)\n })\n if(transportBefore === this.transport || establishedBefore > 0){\n this.triggerChanError()\n }\n }\n\n /**\n * @private\n */\n triggerChanError(){\n this.channels.forEach(channel => {\n if(!(channel.isErrored() || channel.isLeaving() || channel.isClosed())){\n channel.trigger(CHANNEL_EVENTS.error)\n }\n })\n }\n\n /**\n * @returns {string}\n */\n connectionState(){\n switch(this.conn && this.conn.readyState){\n case SOCKET_STATES.connecting: return \"connecting\"\n case SOCKET_STATES.open: return \"open\"\n case SOCKET_STATES.closing: return \"closing\"\n default: return \"closed\"\n }\n }\n\n /**\n * @returns {boolean}\n */\n isConnected(){ return this.connectionState() === \"open\" }\n\n /**\n * @private\n *\n * @param {Channel}\n */\n remove(channel){\n this.off(channel.stateChangeRefs)\n this.channels = this.channels.filter(c => c.joinRef() !== channel.joinRef())\n }\n\n /**\n * Removes `onOpen`, `onClose`, `onError,` and `onMessage` registrations.\n *\n * @param {refs} - list of refs returned by calls to\n * `onOpen`, `onClose`, `onError,` and `onMessage`\n */\n off(refs){\n for(let key in this.stateChangeCallbacks){\n this.stateChangeCallbacks[key] = this.stateChangeCallbacks[key].filter(([ref]) => {\n return refs.indexOf(ref) === -1\n })\n }\n }\n\n /**\n * Initiates a new channel for the given topic\n *\n * @param {string} topic\n * @param {Object} chanParams - Parameters for the channel\n * @returns {Channel}\n */\n channel(topic, chanParams = {}){\n let chan = new Channel(topic, chanParams, this)\n this.channels.push(chan)\n return chan\n }\n\n /**\n * @param {Object} data\n */\n push(data){\n if(this.hasLogger()){\n let {topic, event, payload, ref, join_ref} = data\n this.log(\"push\", `${topic} ${event} (${join_ref}, ${ref})`, payload)\n }\n\n if(this.isConnected()){\n this.encode(data, result => this.conn.send(result))\n } else {\n this.sendBuffer.push(() => this.encode(data, result => this.conn.send(result)))\n }\n }\n\n /**\n * Return the next message ref, accounting for overflows\n * @returns {string}\n */\n makeRef(){\n let newRef = this.ref + 1\n if(newRef === this.ref){ this.ref = 0 } else { this.ref = newRef }\n\n return this.ref.toString()\n }\n\n sendHeartbeat(){\n if(this.pendingHeartbeatRef && !this.isConnected()){ return }\n this.pendingHeartbeatRef = this.makeRef()\n this.push({topic: \"phoenix\", event: \"heartbeat\", payload: {}, ref: this.pendingHeartbeatRef})\n this.heartbeatTimeoutTimer = setTimeout(() => this.heartbeatTimeout(), this.heartbeatIntervalMs)\n }\n\n flushSendBuffer(){\n if(this.isConnected() && this.sendBuffer.length > 0){\n this.sendBuffer.forEach(callback => callback())\n this.sendBuffer = []\n }\n }\n\n onConnMessage(rawMessage){\n this.decode(rawMessage.data, msg => {\n let {topic, event, payload, ref, join_ref} = msg\n if(ref && ref === this.pendingHeartbeatRef){\n this.clearHeartbeats()\n this.pendingHeartbeatRef = null\n this.heartbeatTimer = setTimeout(() => this.sendHeartbeat(), this.heartbeatIntervalMs)\n }\n\n if(this.hasLogger()) this.log(\"receive\", `${payload.status || \"\"} ${topic} ${event} ${ref && \"(\" + ref + \")\" || \"\"}`, payload)\n\n for(let i = 0; i < this.channels.length; i++){\n const channel = this.channels[i]\n if(!channel.isMember(topic, event, payload, join_ref)){ continue }\n channel.trigger(event, payload, ref, join_ref)\n }\n\n for(let i = 0; i < this.stateChangeCallbacks.message.length; i++){\n let [, callback] = this.stateChangeCallbacks.message[i]\n callback(msg)\n }\n })\n }\n\n leaveOpenTopic(topic){\n let dupChannel = this.channels.find(c => c.topic === topic && (c.isJoined() || c.isJoining()))\n if(dupChannel){\n if(this.hasLogger()) this.log(\"transport\", `leaving duplicate topic \"${topic}\"`)\n dupChannel.leave()\n }\n }\n}\n"], - "mappings": "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", + "sourcesContent": ["/**\n * Phoenix Channels JavaScript client\n *\n * ## Socket Connection\n *\n * A single connection is established to the server and\n * channels are multiplexed over the connection.\n * Connect to the server using the `Socket` class:\n *\n * ```javascript\n * let socket = new Socket(\"/socket\", {params: {userToken: \"123\"}})\n * socket.connect()\n * ```\n *\n * The `Socket` constructor takes the mount point of the socket,\n * the authentication params, as well as options that can be found in\n * the Socket docs, such as configuring the `LongPoll` transport, and\n * heartbeat.\n *\n * ## Channels\n *\n * Channels are isolated, concurrent processes on the server that\n * subscribe to topics and broker events between the client and server.\n * To join a channel, you must provide the topic, and channel params for\n * authorization. Here's an example chat room example where `\"new_msg\"`\n * events are listened for, messages are pushed to the server, and\n * the channel is joined with ok/error/timeout matches:\n *\n * ```javascript\n * let channel = socket.channel(\"room:123\", {token: roomToken})\n * channel.on(\"new_msg\", msg => console.log(\"Got message\", msg) )\n * $input.onEnter( e => {\n * channel.push(\"new_msg\", {body: e.target.val}, 10000)\n * .receive(\"ok\", (msg) => console.log(\"created message\", msg) )\n * .receive(\"error\", (reasons) => console.log(\"create failed\", reasons) )\n * .receive(\"timeout\", () => console.log(\"Networking issue...\") )\n * })\n *\n * channel.join()\n * .receive(\"ok\", ({messages}) => console.log(\"catching up\", messages) )\n * .receive(\"error\", ({reason}) => console.log(\"failed join\", reason) )\n * .receive(\"timeout\", () => console.log(\"Networking issue. Still waiting...\"))\n *```\n *\n * ## Joining\n *\n * Creating a channel with `socket.channel(topic, params)`, binds the params to\n * `channel.params`, which are sent up on `channel.join()`.\n * Subsequent rejoins will send up the modified params for\n * updating authorization params, or passing up last_message_id information.\n * Successful joins receive an \"ok\" status, while unsuccessful joins\n * receive \"error\".\n *\n * With the default serializers and WebSocket transport, JSON text frames are\n * used for pushing a JSON object literal. If an `ArrayBuffer` instance is provided,\n * binary encoding will be used and the message will be sent with the binary\n * opcode.\n *\n * *Note*: binary messages are only supported on the WebSocket transport.\n *\n * ## Duplicate Join Subscriptions\n *\n * While the client may join any number of topics on any number of channels,\n * the client may only hold a single subscription for each unique topic at any\n * given time. When attempting to create a duplicate subscription,\n * the server will close the existing channel, log a warning, and\n * spawn a new channel for the topic. The client will have their\n * `channel.onClose` callbacks fired for the existing channel, and the new\n * channel join will have its receive hooks processed as normal.\n *\n * ## Pushing Messages\n *\n * From the previous example, we can see that pushing messages to the server\n * can be done with `channel.push(eventName, payload)` and we can optionally\n * receive responses from the push. Additionally, we can use\n * `receive(\"timeout\", callback)` to abort waiting for our other `receive` hooks\n * and take action after some period of waiting. The default timeout is 10000ms.\n *\n *\n * ## Socket Hooks\n *\n * Lifecycle events of the multiplexed connection can be hooked into via\n * `socket.onError()` and `socket.onClose()` events, ie:\n *\n * ```javascript\n * socket.onError( () => console.log(\"there was an error with the connection!\") )\n * socket.onClose( () => console.log(\"the connection dropped\") )\n * ```\n *\n *\n * ## Channel Hooks\n *\n * For each joined channel, you can bind to `onError` and `onClose` events\n * to monitor the channel lifecycle, ie:\n *\n * ```javascript\n * channel.onError( () => console.log(\"there was an error!\") )\n * channel.onClose( () => console.log(\"the channel has gone away gracefully\") )\n * ```\n *\n * ### onError hooks\n *\n * `onError` hooks are invoked if the socket connection drops, or the channel\n * crashes on the server. In either case, a channel rejoin is attempted\n * automatically in an exponential backoff manner.\n *\n * ### onClose hooks\n *\n * `onClose` hooks are invoked only in two cases. 1) the channel explicitly\n * closed on the server, or 2). The client explicitly closed, by calling\n * `channel.leave()`\n *\n *\n * ## Presence\n *\n * The `Presence` object provides features for syncing presence information\n * from the server with the client and handling presences joining and leaving.\n *\n * ### Syncing state from the server\n *\n * To sync presence state from the server, first instantiate an object and\n * pass your channel in to track lifecycle events:\n *\n * ```javascript\n * let channel = socket.channel(\"some:topic\")\n * let presence = new Presence(channel)\n * ```\n *\n * Next, use the `presence.onSync` callback to react to state changes\n * from the server. For example, to render the list of users every time\n * the list changes, you could write:\n *\n * ```javascript\n * presence.onSync(() => {\n * myRenderUsersFunction(presence.list())\n * })\n * ```\n *\n * ### Listing Presences\n *\n * `presence.list` is used to return a list of presence information\n * based on the local state of metadata. By default, all presence\n * metadata is returned, but a `listBy` function can be supplied to\n * allow the client to select which metadata to use for a given presence.\n * For example, you may have a user online from different devices with\n * a metadata status of \"online\", but they have set themselves to \"away\"\n * on another device. In this case, the app may choose to use the \"away\"\n * status for what appears on the UI. The example below defines a `listBy`\n * function which prioritizes the first metadata which was registered for\n * each user. This could be the first tab they opened, or the first device\n * they came online from:\n *\n * ```javascript\n * let listBy = (id, {metas: [first, ...rest]}) => {\n * first.count = rest.length + 1 // count of this user's presences\n * first.id = id\n * return first\n * }\n * let onlineUsers = presence.list(listBy)\n * ```\n *\n * ### Handling individual presence join and leave events\n *\n * The `presence.onJoin` and `presence.onLeave` callbacks can be used to\n * react to individual presences joining and leaving the app. For example:\n *\n * ```javascript\n * let presence = new Presence(channel)\n *\n * // detect if user has joined for the 1st time or from another tab/device\n * presence.onJoin((id, current, newPres) => {\n * if(!current){\n * console.log(\"user has entered for the first time\", newPres)\n * } else {\n * console.log(\"user additional presence\", newPres)\n * }\n * })\n *\n * // detect if user has left from all tabs/devices, or is still present\n * presence.onLeave((id, current, leftPres) => {\n * if(current.metas.length === 0){\n * console.log(\"user has left from all devices\", leftPres)\n * } else {\n * console.log(\"user left from a device\", leftPres)\n * }\n * })\n * // receive presence data from server\n * presence.onSync(() => {\n * displayUsers(presence.list())\n * })\n * ```\n * @module phoenix\n */\n\nimport Channel from \"./channel\"\nimport LongPoll from \"./longpoll\"\nimport Presence from \"./presence\"\nimport Serializer from \"./serializer\"\nimport Socket from \"./socket\"\n\nexport {\n Channel,\n LongPoll,\n Presence,\n Serializer,\n Socket\n}\n", "// wraps value in closure or returns closure\nexport let closure = (value) => {\n if(typeof value === \"function\"){\n return value\n } else {\n let closure = function (){ return value }\n return closure\n }\n}\n", "export const globalSelf = typeof self !== \"undefined\" ? self : null\nexport const phxWindow = typeof window !== \"undefined\" ? window : null\nexport const global = globalSelf || phxWindow || global\nexport const DEFAULT_VSN = \"2.0.0\"\nexport const SOCKET_STATES = {connecting: 0, open: 1, closing: 2, closed: 3}\nexport const DEFAULT_TIMEOUT = 10000\nexport const WS_CLOSE_NORMAL = 1000\nexport const CHANNEL_STATES = {\n closed: \"closed\",\n errored: \"errored\",\n joined: \"joined\",\n joining: \"joining\",\n leaving: \"leaving\",\n}\nexport const CHANNEL_EVENTS = {\n close: \"phx_close\",\n error: \"phx_error\",\n join: \"phx_join\",\n reply: \"phx_reply\",\n leave: \"phx_leave\"\n}\n\nexport const TRANSPORTS = {\n longpoll: \"longpoll\",\n websocket: \"websocket\"\n}\nexport const XHR_STATES = {\n complete: 4\n}\n", "/**\n * Initializes the Push\n * @param {Channel} channel - The Channel\n * @param {string} event - The event, for example `\"phx_join\"`\n * @param {Object} payload - The payload, for example `{user_id: 123}`\n * @param {number} timeout - The push timeout in milliseconds\n */\nexport default class Push {\n constructor(channel, event, payload, timeout){\n this.channel = channel\n this.event = event\n this.payload = payload || function (){ return {} }\n this.receivedResp = null\n this.timeout = timeout\n this.timeoutTimer = null\n this.recHooks = []\n this.sent = false\n }\n\n /**\n *\n * @param {number} timeout\n */\n resend(timeout){\n this.timeout = timeout\n this.reset()\n this.send()\n }\n\n /**\n *\n */\n send(){\n if(this.hasReceived(\"timeout\")){ return }\n this.startTimeout()\n this.sent = true\n this.channel.socket.push({\n topic: this.channel.topic,\n event: this.event,\n payload: this.payload(),\n ref: this.ref,\n join_ref: this.channel.joinRef()\n })\n }\n\n /**\n *\n * @param {*} status\n * @param {*} callback\n */\n receive(status, callback){\n if(this.hasReceived(status)){\n callback(this.receivedResp.response)\n }\n\n this.recHooks.push({status, callback})\n return this\n }\n\n /**\n * @private\n */\n reset(){\n this.cancelRefEvent()\n this.ref = null\n this.refEvent = null\n this.receivedResp = null\n this.sent = false\n }\n\n /**\n * @private\n */\n matchReceive({status, response, _ref}){\n this.recHooks.filter(h => h.status === status)\n .forEach(h => h.callback(response))\n }\n\n /**\n * @private\n */\n cancelRefEvent(){\n if(!this.refEvent){ return }\n this.channel.off(this.refEvent)\n }\n\n /**\n * @private\n */\n cancelTimeout(){\n clearTimeout(this.timeoutTimer)\n this.timeoutTimer = null\n }\n\n /**\n * @private\n */\n startTimeout(){\n if(this.timeoutTimer){ this.cancelTimeout() }\n this.ref = this.channel.socket.makeRef()\n this.refEvent = this.channel.replyEventName(this.ref)\n\n this.channel.on(this.refEvent, payload => {\n this.cancelRefEvent()\n this.cancelTimeout()\n this.receivedResp = payload\n this.matchReceive(payload)\n })\n\n this.timeoutTimer = setTimeout(() => {\n this.trigger(\"timeout\", {})\n }, this.timeout)\n }\n\n /**\n * @private\n */\n hasReceived(status){\n return this.receivedResp && this.receivedResp.status === status\n }\n\n /**\n * @private\n */\n trigger(status, response){\n this.channel.trigger(this.refEvent, {status, response})\n }\n}\n", "/**\n *\n * Creates a timer that accepts a `timerCalc` function to perform\n * calculated timeout retries, such as exponential backoff.\n *\n * @example\n * let reconnectTimer = new Timer(() => this.connect(), function(tries){\n * return [1000, 5000, 10000][tries - 1] || 10000\n * })\n * reconnectTimer.scheduleTimeout() // fires after 1000\n * reconnectTimer.scheduleTimeout() // fires after 5000\n * reconnectTimer.reset()\n * reconnectTimer.scheduleTimeout() // fires after 1000\n *\n * @param {Function} callback\n * @param {Function} timerCalc\n */\nexport default class Timer {\n constructor(callback, timerCalc){\n this.callback = callback\n this.timerCalc = timerCalc\n this.timer = null\n this.tries = 0\n }\n\n reset(){\n this.tries = 0\n clearTimeout(this.timer)\n }\n\n /**\n * Cancels any previous scheduleTimeout and schedules callback\n */\n scheduleTimeout(){\n clearTimeout(this.timer)\n\n this.timer = setTimeout(() => {\n this.tries = this.tries + 1\n this.callback()\n }, this.timerCalc(this.tries + 1))\n }\n}\n", "import {closure} from \"./utils\"\nimport {\n CHANNEL_EVENTS,\n CHANNEL_STATES,\n} from \"./constants\"\n\nimport Push from \"./push\"\nimport Timer from \"./timer\"\n\n/**\n *\n * @param {string} topic\n * @param {(Object|function)} params\n * @param {Socket} socket\n */\nexport default class Channel {\n constructor(topic, params, socket){\n this.state = CHANNEL_STATES.closed\n this.topic = topic\n this.params = closure(params || {})\n this.socket = socket\n this.bindings = []\n this.bindingRef = 0\n this.timeout = this.socket.timeout\n this.joinedOnce = false\n this.joinPush = new Push(this, CHANNEL_EVENTS.join, this.params, this.timeout)\n this.pushBuffer = []\n this.stateChangeRefs = []\n\n this.rejoinTimer = new Timer(() => {\n if(this.socket.isConnected()){ this.rejoin() }\n }, this.socket.rejoinAfterMs)\n this.stateChangeRefs.push(this.socket.onError(() => this.rejoinTimer.reset()))\n this.stateChangeRefs.push(this.socket.onOpen(() => {\n this.rejoinTimer.reset()\n if(this.isErrored()){ this.rejoin() }\n })\n )\n this.joinPush.receive(\"ok\", () => {\n this.state = CHANNEL_STATES.joined\n this.rejoinTimer.reset()\n this.pushBuffer.forEach(pushEvent => pushEvent.send())\n this.pushBuffer = []\n })\n this.joinPush.receive(\"error\", () => {\n this.state = CHANNEL_STATES.errored\n if(this.socket.isConnected()){ this.rejoinTimer.scheduleTimeout() }\n })\n this.onClose(() => {\n this.rejoinTimer.reset()\n if(this.socket.hasLogger()) this.socket.log(\"channel\", `close ${this.topic} ${this.joinRef()}`)\n this.state = CHANNEL_STATES.closed\n this.socket.remove(this)\n })\n this.onError(reason => {\n if(this.socket.hasLogger()) this.socket.log(\"channel\", `error ${this.topic}`, reason)\n if(this.isJoining()){ this.joinPush.reset() }\n this.state = CHANNEL_STATES.errored\n if(this.socket.isConnected()){ this.rejoinTimer.scheduleTimeout() }\n })\n this.joinPush.receive(\"timeout\", () => {\n if(this.socket.hasLogger()) this.socket.log(\"channel\", `timeout ${this.topic} (${this.joinRef()})`, this.joinPush.timeout)\n let leavePush = new Push(this, CHANNEL_EVENTS.leave, closure({}), this.timeout)\n leavePush.send()\n this.state = CHANNEL_STATES.errored\n this.joinPush.reset()\n if(this.socket.isConnected()){ this.rejoinTimer.scheduleTimeout() }\n })\n this.on(CHANNEL_EVENTS.reply, (payload, ref) => {\n this.trigger(this.replyEventName(ref), payload)\n })\n }\n\n /**\n * Join the channel\n * @param {integer} timeout\n * @returns {Push}\n */\n join(timeout = this.timeout){\n if(this.joinedOnce){\n throw new Error(\"tried to join multiple times. 'join' can only be called a single time per channel instance\")\n } else {\n this.timeout = timeout\n this.joinedOnce = true\n this.rejoin()\n return this.joinPush\n }\n }\n\n /**\n * Hook into channel close\n * @param {Function} callback\n */\n onClose(callback){\n this.on(CHANNEL_EVENTS.close, callback)\n }\n\n /**\n * Hook into channel errors\n * @param {Function} callback\n */\n onError(callback){\n return this.on(CHANNEL_EVENTS.error, reason => callback(reason))\n }\n\n /**\n * Subscribes on channel events\n *\n * Subscription returns a ref counter, which can be used later to\n * unsubscribe the exact event listener\n *\n * @example\n * const ref1 = channel.on(\"event\", do_stuff)\n * const ref2 = channel.on(\"event\", do_other_stuff)\n * channel.off(\"event\", ref1)\n * // Since unsubscription, do_stuff won't fire,\n * // while do_other_stuff will keep firing on the \"event\"\n *\n * @param {string} event\n * @param {Function} callback\n * @returns {integer} ref\n */\n on(event, callback){\n let ref = this.bindingRef++\n this.bindings.push({event, ref, callback})\n return ref\n }\n\n /**\n * Unsubscribes off of channel events\n *\n * Use the ref returned from a channel.on() to unsubscribe one\n * handler, or pass nothing for the ref to unsubscribe all\n * handlers for the given event.\n *\n * @example\n * // Unsubscribe the do_stuff handler\n * const ref1 = channel.on(\"event\", do_stuff)\n * channel.off(\"event\", ref1)\n *\n * // Unsubscribe all handlers from event\n * channel.off(\"event\")\n *\n * @param {string} event\n * @param {integer} ref\n */\n off(event, ref){\n this.bindings = this.bindings.filter((bind) => {\n return !(bind.event === event && (typeof ref === \"undefined\" || ref === bind.ref))\n })\n }\n\n /**\n * @private\n */\n canPush(){ return this.socket.isConnected() && this.isJoined() }\n\n /**\n * Sends a message `event` to phoenix with the payload `payload`.\n * Phoenix receives this in the `handle_in(event, payload, socket)`\n * function. if phoenix replies or it times out (default 10000ms),\n * then optionally the reply can be received.\n *\n * @example\n * channel.push(\"event\")\n * .receive(\"ok\", payload => console.log(\"phoenix replied:\", payload))\n * .receive(\"error\", err => console.log(\"phoenix errored\", err))\n * .receive(\"timeout\", () => console.log(\"timed out pushing\"))\n * @param {string} event\n * @param {Object} payload\n * @param {number} [timeout]\n * @returns {Push}\n */\n push(event, payload, timeout = this.timeout){\n payload = payload || {}\n if(!this.joinedOnce){\n throw new Error(`tried to push '${event}' to '${this.topic}' before joining. Use channel.join() before pushing events`)\n }\n let pushEvent = new Push(this, event, function (){ return payload }, timeout)\n if(this.canPush()){\n pushEvent.send()\n } else {\n pushEvent.startTimeout()\n this.pushBuffer.push(pushEvent)\n }\n\n return pushEvent\n }\n\n /** Leaves the channel\n *\n * Unsubscribes from server events, and\n * instructs channel to terminate on server\n *\n * Triggers onClose() hooks\n *\n * To receive leave acknowledgements, use the `receive`\n * hook to bind to the server ack, ie:\n *\n * @example\n * channel.leave().receive(\"ok\", () => alert(\"left!\") )\n *\n * @param {integer} timeout\n * @returns {Push}\n */\n leave(timeout = this.timeout){\n this.rejoinTimer.reset()\n this.joinPush.cancelTimeout()\n\n this.state = CHANNEL_STATES.leaving\n let onClose = () => {\n if(this.socket.hasLogger()) this.socket.log(\"channel\", `leave ${this.topic}`)\n this.trigger(CHANNEL_EVENTS.close, \"leave\")\n }\n let leavePush = new Push(this, CHANNEL_EVENTS.leave, closure({}), timeout)\n leavePush.receive(\"ok\", () => onClose())\n .receive(\"timeout\", () => onClose())\n leavePush.send()\n if(!this.canPush()){ leavePush.trigger(\"ok\", {}) }\n\n return leavePush\n }\n\n /**\n * Overridable message hook\n *\n * Receives all events for specialized message handling\n * before dispatching to the channel callbacks.\n *\n * Must return the payload, modified or unmodified\n * @param {string} event\n * @param {Object} payload\n * @param {integer} ref\n * @returns {Object}\n */\n onMessage(_event, payload, _ref){ return payload }\n\n /**\n * @private\n */\n isMember(topic, event, payload, joinRef){\n if(this.topic !== topic){ return false }\n\n if(joinRef && joinRef !== this.joinRef()){\n if(this.socket.hasLogger()) this.socket.log(\"channel\", \"dropping outdated message\", {topic, event, payload, joinRef})\n return false\n } else {\n return true\n }\n }\n\n /**\n * @private\n */\n joinRef(){ return this.joinPush.ref }\n\n /**\n * @private\n */\n rejoin(timeout = this.timeout){\n if(this.isLeaving()){ return }\n this.socket.leaveOpenTopic(this.topic)\n this.state = CHANNEL_STATES.joining\n this.joinPush.resend(timeout)\n }\n\n /**\n * @private\n */\n trigger(event, payload, ref, joinRef){\n let handledPayload = this.onMessage(event, payload, ref, joinRef)\n if(payload && !handledPayload){ throw new Error(\"channel onMessage callbacks must return the payload, modified or unmodified\") }\n\n let eventBindings = this.bindings.filter(bind => bind.event === event)\n\n for(let i = 0; i < eventBindings.length; i++){\n let bind = eventBindings[i]\n bind.callback(handledPayload, ref, joinRef || this.joinRef())\n }\n }\n\n /**\n * @private\n */\n replyEventName(ref){ return `chan_reply_${ref}` }\n\n /**\n * @private\n */\n isClosed(){ return this.state === CHANNEL_STATES.closed }\n\n /**\n * @private\n */\n isErrored(){ return this.state === CHANNEL_STATES.errored }\n\n /**\n * @private\n */\n isJoined(){ return this.state === CHANNEL_STATES.joined }\n\n /**\n * @private\n */\n isJoining(){ return this.state === CHANNEL_STATES.joining }\n\n /**\n * @private\n */\n isLeaving(){ return this.state === CHANNEL_STATES.leaving }\n}\n", "import {\n global,\n XHR_STATES\n} from \"./constants\"\n\nexport default class Ajax {\n\n static request(method, endPoint, accept, body, timeout, ontimeout, callback){\n if(global.XDomainRequest){\n let req = new global.XDomainRequest() // IE8, IE9\n return this.xdomainRequest(req, method, endPoint, body, timeout, ontimeout, callback)\n } else {\n let req = new global.XMLHttpRequest() // IE7+, Firefox, Chrome, Opera, Safari\n return this.xhrRequest(req, method, endPoint, accept, body, timeout, ontimeout, callback)\n }\n }\n\n static xdomainRequest(req, method, endPoint, body, timeout, ontimeout, callback){\n req.timeout = timeout\n req.open(method, endPoint)\n req.onload = () => {\n let response = this.parseJSON(req.responseText)\n callback && callback(response)\n }\n if(ontimeout){ req.ontimeout = ontimeout }\n\n // Work around bug in IE9 that requires an attached onprogress handler\n req.onprogress = () => { }\n\n req.send(body)\n return req\n }\n\n static xhrRequest(req, method, endPoint, accept, body, timeout, ontimeout, callback){\n req.open(method, endPoint, true)\n req.timeout = timeout\n req.setRequestHeader(\"Content-Type\", accept)\n req.onerror = () => callback && callback(null)\n req.onreadystatechange = () => {\n if(req.readyState === XHR_STATES.complete && callback){\n let response = this.parseJSON(req.responseText)\n callback(response)\n }\n }\n if(ontimeout){ req.ontimeout = ontimeout }\n\n req.send(body)\n return req\n }\n\n static parseJSON(resp){\n if(!resp || resp === \"\"){ return null }\n\n try {\n return JSON.parse(resp)\n } catch (e){\n console && console.log(\"failed to parse JSON response\", resp)\n return null\n }\n }\n\n static serialize(obj, parentKey){\n let queryStr = []\n for(var key in obj){\n if(!Object.prototype.hasOwnProperty.call(obj, key)){ continue }\n let paramKey = parentKey ? `${parentKey}[${key}]` : key\n let paramVal = obj[key]\n if(typeof paramVal === \"object\"){\n queryStr.push(this.serialize(paramVal, paramKey))\n } else {\n queryStr.push(encodeURIComponent(paramKey) + \"=\" + encodeURIComponent(paramVal))\n }\n }\n return queryStr.join(\"&\")\n }\n\n static appendParams(url, params){\n if(Object.keys(params).length === 0){ return url }\n\n let prefix = url.match(/\\?/) ? \"&\" : \"?\"\n return `${url}${prefix}${this.serialize(params)}`\n }\n}\n", "import {\n SOCKET_STATES,\n TRANSPORTS\n} from \"./constants\"\n\nimport Ajax from \"./ajax\"\n\nlet arrayBufferToBase64 = (buffer) => {\n let binary = \"\"\n let bytes = new Uint8Array(buffer)\n let len = bytes.byteLength\n for(let i = 0; i < len; i++){ binary += String.fromCharCode(bytes[i]) }\n return btoa(binary)\n}\n\nexport default class LongPoll {\n\n constructor(endPoint){\n this.endPoint = null\n this.token = null\n this.skipHeartbeat = true\n this.reqs = new Set()\n this.awaitingBatchAck = false\n this.currentBatch = null\n this.currentBatchTimer = null\n this.batchBuffer = []\n this.onopen = function (){ } // noop\n this.onerror = function (){ } // noop\n this.onmessage = function (){ } // noop\n this.onclose = function (){ } // noop\n this.pollEndpoint = this.normalizeEndpoint(endPoint)\n this.readyState = SOCKET_STATES.connecting\n // we must wait for the caller to finish setting up our callbacks and timeout properties\n setTimeout(() => this.poll(), 0)\n }\n\n normalizeEndpoint(endPoint){\n return (endPoint\n .replace(\"ws://\", \"http://\")\n .replace(\"wss://\", \"https://\")\n .replace(new RegExp(\"(.*)\\/\" + TRANSPORTS.websocket), \"$1/\" + TRANSPORTS.longpoll))\n }\n\n endpointURL(){\n return Ajax.appendParams(this.pollEndpoint, {token: this.token})\n }\n\n closeAndRetry(code, reason, wasClean){\n this.close(code, reason, wasClean)\n this.readyState = SOCKET_STATES.connecting\n }\n\n ontimeout(){\n this.onerror(\"timeout\")\n this.closeAndRetry(1005, \"timeout\", false)\n }\n\n isActive(){ return this.readyState === SOCKET_STATES.open || this.readyState === SOCKET_STATES.connecting }\n\n poll(){\n this.ajax(\"GET\", \"application/json\", null, () => this.ontimeout(), resp => {\n if(resp){\n var {status, token, messages} = resp\n this.token = token\n } else {\n status = 0\n }\n\n switch(status){\n case 200:\n messages.forEach(msg => {\n // Tasks are what things like event handlers, setTimeout callbacks,\n // promise resolves and more are run within.\n // In modern browsers, there are two different kinds of tasks,\n // microtasks and macrotasks.\n // Microtasks are mainly used for Promises, while macrotasks are\n // used for everything else.\n // Microtasks always have priority over macrotasks. If the JS engine\n // is looking for a task to run, it will always try to empty the\n // microtask queue before attempting to run anything from the\n // macrotask queue.\n //\n // For the WebSocket transport, messages always arrive in their own\n // event. This means that if any promises are resolved from within,\n // their callbacks will always finish execution by the time the\n // next message event handler is run.\n //\n // In order to emulate this behaviour, we need to make sure each\n // onmessage handler is run within its own macrotask.\n setTimeout(() => this.onmessage({data: msg}), 0)\n })\n this.poll()\n break\n case 204:\n this.poll()\n break\n case 410:\n this.readyState = SOCKET_STATES.open\n this.onopen({})\n this.poll()\n break\n case 403:\n this.onerror(403)\n this.close(1008, \"forbidden\", false)\n break\n case 0:\n case 500:\n this.onerror(500)\n this.closeAndRetry(1011, \"internal server error\", 500)\n break\n default: throw new Error(`unhandled poll status ${status}`)\n }\n })\n }\n\n // we collect all pushes within the current event loop by\n // setTimeout 0, which optimizes back-to-back procedural\n // pushes against an empty buffer\n\n send(body){\n if(typeof(body) !== \"string\"){ body = arrayBufferToBase64(body) }\n if(this.currentBatch){\n this.currentBatch.push(body)\n } else if(this.awaitingBatchAck){\n this.batchBuffer.push(body)\n } else {\n this.currentBatch = [body]\n this.currentBatchTimer = setTimeout(() => {\n this.batchSend(this.currentBatch)\n this.currentBatch = null\n }, 0)\n }\n }\n\n batchSend(messages){\n this.awaitingBatchAck = true\n this.ajax(\"POST\", \"application/x-ndjson\", messages.join(\"\\n\"), () => this.onerror(\"timeout\"), resp => {\n this.awaitingBatchAck = false\n if(!resp || resp.status !== 200){\n this.onerror(resp && resp.status)\n this.closeAndRetry(1011, \"internal server error\", false)\n } else if(this.batchBuffer.length > 0){\n this.batchSend(this.batchBuffer)\n this.batchBuffer = []\n }\n })\n }\n\n close(code, reason, wasClean){\n for(let req of this.reqs){ req.abort() }\n this.readyState = SOCKET_STATES.closed\n let opts = Object.assign({code: 1000, reason: undefined, wasClean: true}, {code, reason, wasClean})\n this.batchBuffer = []\n clearTimeout(this.currentBatchTimer)\n this.currentBatchTimer = null\n if(typeof(CloseEvent) !== \"undefined\"){\n this.onclose(new CloseEvent(\"close\", opts))\n } else {\n this.onclose(opts)\n }\n }\n\n ajax(method, contentType, body, onCallerTimeout, callback){\n let req\n let ontimeout = () => {\n this.reqs.delete(req)\n onCallerTimeout()\n }\n req = Ajax.request(method, this.endpointURL(), contentType, body, this.timeout, ontimeout, resp => {\n this.reqs.delete(req)\n if(this.isActive()){ callback(resp) }\n })\n this.reqs.add(req)\n }\n}\n", "/**\n * Initializes the Presence\n * @param {Channel} channel - The Channel\n * @param {Object} opts - The options,\n * for example `{events: {state: \"state\", diff: \"diff\"}}`\n */\nexport default class Presence {\n\n constructor(channel, opts = {}){\n let events = opts.events || {state: \"presence_state\", diff: \"presence_diff\"}\n this.state = {}\n this.pendingDiffs = []\n this.channel = channel\n this.joinRef = null\n this.caller = {\n onJoin: function (){ },\n onLeave: function (){ },\n onSync: function (){ }\n }\n\n this.channel.on(events.state, newState => {\n let {onJoin, onLeave, onSync} = this.caller\n\n this.joinRef = this.channel.joinRef()\n this.state = Presence.syncState(this.state, newState, onJoin, onLeave)\n\n this.pendingDiffs.forEach(diff => {\n this.state = Presence.syncDiff(this.state, diff, onJoin, onLeave)\n })\n this.pendingDiffs = []\n onSync()\n })\n\n this.channel.on(events.diff, diff => {\n let {onJoin, onLeave, onSync} = this.caller\n\n if(this.inPendingSyncState()){\n this.pendingDiffs.push(diff)\n } else {\n this.state = Presence.syncDiff(this.state, diff, onJoin, onLeave)\n onSync()\n }\n })\n }\n\n onJoin(callback){ this.caller.onJoin = callback }\n\n onLeave(callback){ this.caller.onLeave = callback }\n\n onSync(callback){ this.caller.onSync = callback }\n\n list(by){ return Presence.list(this.state, by) }\n\n inPendingSyncState(){\n return !this.joinRef || (this.joinRef !== this.channel.joinRef())\n }\n\n // lower-level public static API\n\n /**\n * Used to sync the list of presences on the server\n * with the client's state. An optional `onJoin` and `onLeave` callback can\n * be provided to react to changes in the client's local presences across\n * disconnects and reconnects with the server.\n *\n * @returns {Presence}\n */\n static syncState(currentState, newState, onJoin, onLeave){\n let state = this.clone(currentState)\n let joins = {}\n let leaves = {}\n\n this.map(state, (key, presence) => {\n if(!newState[key]){\n leaves[key] = presence\n }\n })\n this.map(newState, (key, newPresence) => {\n let currentPresence = state[key]\n if(currentPresence){\n let newRefs = newPresence.metas.map(m => m.phx_ref)\n let curRefs = currentPresence.metas.map(m => m.phx_ref)\n let joinedMetas = newPresence.metas.filter(m => curRefs.indexOf(m.phx_ref) < 0)\n let leftMetas = currentPresence.metas.filter(m => newRefs.indexOf(m.phx_ref) < 0)\n if(joinedMetas.length > 0){\n joins[key] = newPresence\n joins[key].metas = joinedMetas\n }\n if(leftMetas.length > 0){\n leaves[key] = this.clone(currentPresence)\n leaves[key].metas = leftMetas\n }\n } else {\n joins[key] = newPresence\n }\n })\n return this.syncDiff(state, {joins: joins, leaves: leaves}, onJoin, onLeave)\n }\n\n /**\n *\n * Used to sync a diff of presence join and leave\n * events from the server, as they happen. Like `syncState`, `syncDiff`\n * accepts optional `onJoin` and `onLeave` callbacks to react to a user\n * joining or leaving from a device.\n *\n * @returns {Presence}\n */\n static syncDiff(state, diff, onJoin, onLeave){\n let {joins, leaves} = this.clone(diff)\n if(!onJoin){ onJoin = function (){ } }\n if(!onLeave){ onLeave = function (){ } }\n\n this.map(joins, (key, newPresence) => {\n let currentPresence = state[key]\n state[key] = this.clone(newPresence)\n if(currentPresence){\n let joinedRefs = state[key].metas.map(m => m.phx_ref)\n let curMetas = currentPresence.metas.filter(m => joinedRefs.indexOf(m.phx_ref) < 0)\n state[key].metas.unshift(...curMetas)\n }\n onJoin(key, currentPresence, newPresence)\n })\n this.map(leaves, (key, leftPresence) => {\n let currentPresence = state[key]\n if(!currentPresence){ return }\n let refsToRemove = leftPresence.metas.map(m => m.phx_ref)\n currentPresence.metas = currentPresence.metas.filter(p => {\n return refsToRemove.indexOf(p.phx_ref) < 0\n })\n onLeave(key, currentPresence, leftPresence)\n if(currentPresence.metas.length === 0){\n delete state[key]\n }\n })\n return state\n }\n\n /**\n * Returns the array of presences, with selected metadata.\n *\n * @param {Object} presences\n * @param {Function} chooser\n *\n * @returns {Presence}\n */\n static list(presences, chooser){\n if(!chooser){ chooser = function (key, pres){ return pres } }\n\n return this.map(presences, (key, presence) => {\n return chooser(key, presence)\n })\n }\n\n // private\n\n static map(obj, func){\n return Object.getOwnPropertyNames(obj).map(key => func(key, obj[key]))\n }\n\n static clone(obj){ return JSON.parse(JSON.stringify(obj)) }\n}\n", "/* The default serializer for encoding and decoding messages */\nimport {\n CHANNEL_EVENTS\n} from \"./constants\"\n\nexport default {\n HEADER_LENGTH: 1,\n META_LENGTH: 4,\n KINDS: {push: 0, reply: 1, broadcast: 2},\n\n encode(msg, callback){\n if(msg.payload.constructor === ArrayBuffer){\n return callback(this.binaryEncode(msg))\n } else {\n let payload = [msg.join_ref, msg.ref, msg.topic, msg.event, msg.payload]\n return callback(JSON.stringify(payload))\n }\n },\n\n decode(rawPayload, callback){\n if(rawPayload.constructor === ArrayBuffer){\n return callback(this.binaryDecode(rawPayload))\n } else {\n let [join_ref, ref, topic, event, payload] = JSON.parse(rawPayload)\n return callback({join_ref, ref, topic, event, payload})\n }\n },\n\n // private\n\n binaryEncode(message){\n let {join_ref, ref, event, topic, payload} = message\n let metaLength = this.META_LENGTH + join_ref.length + ref.length + topic.length + event.length\n let header = new ArrayBuffer(this.HEADER_LENGTH + metaLength)\n let view = new DataView(header)\n let offset = 0\n\n view.setUint8(offset++, this.KINDS.push) // kind\n view.setUint8(offset++, join_ref.length)\n view.setUint8(offset++, ref.length)\n view.setUint8(offset++, topic.length)\n view.setUint8(offset++, event.length)\n Array.from(join_ref, char => view.setUint8(offset++, char.charCodeAt(0)))\n Array.from(ref, char => view.setUint8(offset++, char.charCodeAt(0)))\n Array.from(topic, char => view.setUint8(offset++, char.charCodeAt(0)))\n Array.from(event, char => view.setUint8(offset++, char.charCodeAt(0)))\n\n var combined = new Uint8Array(header.byteLength + payload.byteLength)\n combined.set(new Uint8Array(header), 0)\n combined.set(new Uint8Array(payload), header.byteLength)\n\n return combined.buffer\n },\n\n binaryDecode(buffer){\n let view = new DataView(buffer)\n let kind = view.getUint8(0)\n let decoder = new TextDecoder()\n switch(kind){\n case this.KINDS.push: return this.decodePush(buffer, view, decoder)\n case this.KINDS.reply: return this.decodeReply(buffer, view, decoder)\n case this.KINDS.broadcast: return this.decodeBroadcast(buffer, view, decoder)\n }\n },\n\n decodePush(buffer, view, decoder){\n let joinRefSize = view.getUint8(1)\n let topicSize = view.getUint8(2)\n let eventSize = view.getUint8(3)\n let offset = this.HEADER_LENGTH + this.META_LENGTH - 1 // pushes have no ref\n let joinRef = decoder.decode(buffer.slice(offset, offset + joinRefSize))\n offset = offset + joinRefSize\n let topic = decoder.decode(buffer.slice(offset, offset + topicSize))\n offset = offset + topicSize\n let event = decoder.decode(buffer.slice(offset, offset + eventSize))\n offset = offset + eventSize\n let data = buffer.slice(offset, buffer.byteLength)\n return {join_ref: joinRef, ref: null, topic: topic, event: event, payload: data}\n },\n\n decodeReply(buffer, view, decoder){\n let joinRefSize = view.getUint8(1)\n let refSize = view.getUint8(2)\n let topicSize = view.getUint8(3)\n let eventSize = view.getUint8(4)\n let offset = this.HEADER_LENGTH + this.META_LENGTH\n let joinRef = decoder.decode(buffer.slice(offset, offset + joinRefSize))\n offset = offset + joinRefSize\n let ref = decoder.decode(buffer.slice(offset, offset + refSize))\n offset = offset + refSize\n let topic = decoder.decode(buffer.slice(offset, offset + topicSize))\n offset = offset + topicSize\n let event = decoder.decode(buffer.slice(offset, offset + eventSize))\n offset = offset + eventSize\n let data = buffer.slice(offset, buffer.byteLength)\n let payload = {status: event, response: data}\n return {join_ref: joinRef, ref: ref, topic: topic, event: CHANNEL_EVENTS.reply, payload: payload}\n },\n\n decodeBroadcast(buffer, view, decoder){\n let topicSize = view.getUint8(1)\n let eventSize = view.getUint8(2)\n let offset = this.HEADER_LENGTH + 2\n let topic = decoder.decode(buffer.slice(offset, offset + topicSize))\n offset = offset + topicSize\n let event = decoder.decode(buffer.slice(offset, offset + eventSize))\n offset = offset + eventSize\n let data = buffer.slice(offset, buffer.byteLength)\n\n return {join_ref: null, ref: null, topic: topic, event: event, payload: data}\n }\n}\n", "import {\n global,\n phxWindow,\n CHANNEL_EVENTS,\n DEFAULT_TIMEOUT,\n DEFAULT_VSN,\n SOCKET_STATES,\n TRANSPORTS,\n WS_CLOSE_NORMAL\n} from \"./constants\"\n\nimport {\n closure\n} from \"./utils\"\n\nimport Ajax from \"./ajax\"\nimport Channel from \"./channel\"\nimport LongPoll from \"./longpoll\"\nimport Serializer from \"./serializer\"\nimport Timer from \"./timer\"\n\n/** Initializes the Socket *\n *\n * For IE8 support use an ES5-shim (https://github.com/es-shims/es5-shim)\n *\n * @param {string} endPoint - The string WebSocket endpoint, ie, `\"ws://example.com/socket\"`,\n * `\"wss://example.com\"`\n * `\"/socket\"` (inherited host & protocol)\n * @param {Object} [opts] - Optional configuration\n * @param {Function} [opts.transport] - The Websocket Transport, for example WebSocket or Phoenix.LongPoll.\n *\n * Defaults to WebSocket with automatic LongPoll fallback if WebSocket is not defined.\n * To fallback to LongPoll when WebSocket attempts fail, use `longPollFallbackMs: 2500`.\n *\n * @param {Function} [opts.longPollFallbackMs] - The millisecond time to attempt the primary transport\n * before falling back to the LongPoll transport. Disabled by default.\n *\n * @param {Function} [opts.debug] - When true, enables debug logging. Default false.\n *\n * @param {Function} [opts.encode] - The function to encode outgoing messages.\n *\n * Defaults to JSON encoder.\n *\n * @param {Function} [opts.decode] - The function to decode incoming messages.\n *\n * Defaults to JSON:\n *\n * ```javascript\n * (payload, callback) => callback(JSON.parse(payload))\n * ```\n *\n * @param {number} [opts.timeout] - The default timeout in milliseconds to trigger push timeouts.\n *\n * Defaults `DEFAULT_TIMEOUT`\n * @param {number} [opts.heartbeatIntervalMs] - The millisec interval to send a heartbeat message\n * @param {number} [opts.reconnectAfterMs] - The optional function that returns the millisec\n * socket reconnect interval.\n *\n * Defaults to stepped backoff of:\n *\n * ```javascript\n * function(tries){\n * return [10, 50, 100, 150, 200, 250, 500, 1000, 2000][tries - 1] || 5000\n * }\n * ````\n *\n * @param {number} [opts.rejoinAfterMs] - The optional function that returns the millisec\n * rejoin interval for individual channels.\n *\n * ```javascript\n * function(tries){\n * return [1000, 2000, 5000][tries - 1] || 10000\n * }\n * ````\n *\n * @param {Function} [opts.logger] - The optional function for specialized logging, ie:\n *\n * ```javascript\n * function(kind, msg, data) {\n * console.log(`${kind}: ${msg}`, data)\n * }\n * ```\n *\n * @param {number} [opts.longpollerTimeout] - The maximum timeout of a long poll AJAX request.\n *\n * Defaults to 20s (double the server long poll timer).\n *\n * @param {(Object|function)} [opts.params] - The optional params to pass when connecting\n * @param {string} [opts.binaryType] - The binary type to use for binary WebSocket frames.\n *\n * Defaults to \"arraybuffer\"\n *\n * @param {vsn} [opts.vsn] - The serializer's protocol version to send on connect.\n *\n * Defaults to DEFAULT_VSN.\n *\n * @param {Object} [opts.sessionStorage] - An optional Storage compatible object\n * Phoenix uses sessionStorage for longpoll fallback history. Overriding the store is\n * useful when Phoenix won't have access to `sessionStorage`. For example, This could\n * happen if a site loads a cross-domain channel in an iframe. Example usage:\n *\n * class InMemoryStorage {\n * constructor() { this.storage = {} }\n * getItem(keyName) { return this.storage[keyName] || null }\n * removeItem(keyName) { delete this.storage[keyName] }\n * setItem(keyName, keyValue) { this.storage[keyName] = keyValue }\n * }\n *\n*/\nexport default class Socket {\n constructor(endPoint, opts = {}){\n this.stateChangeCallbacks = {open: [], close: [], error: [], message: []}\n this.channels = []\n this.sendBuffer = []\n this.ref = 0\n this.timeout = opts.timeout || DEFAULT_TIMEOUT\n this.transport = opts.transport || global.WebSocket || LongPoll\n this.primaryPassedHealthCheck = false\n this.longPollFallbackMs = opts.longPollFallbackMs\n this.fallbackTimer = null\n this.sessionStore = opts.sessionStorage || global.sessionStorage\n this.establishedConnections = 0\n this.defaultEncoder = Serializer.encode.bind(Serializer)\n this.defaultDecoder = Serializer.decode.bind(Serializer)\n this.closeWasClean = false\n this.binaryType = opts.binaryType || \"arraybuffer\"\n this.connectClock = 1\n if(this.transport !== LongPoll){\n this.encode = opts.encode || this.defaultEncoder\n this.decode = opts.decode || this.defaultDecoder\n } else {\n this.encode = this.defaultEncoder\n this.decode = this.defaultDecoder\n }\n let awaitingConnectionOnPageShow = null\n if(phxWindow && phxWindow.addEventListener){\n phxWindow.addEventListener(\"pagehide\", _e => {\n if(this.conn){\n this.disconnect()\n awaitingConnectionOnPageShow = this.connectClock\n }\n })\n phxWindow.addEventListener(\"pageshow\", _e => {\n if(awaitingConnectionOnPageShow === this.connectClock){\n awaitingConnectionOnPageShow = null\n this.connect()\n }\n })\n }\n this.heartbeatIntervalMs = opts.heartbeatIntervalMs || 30000\n this.rejoinAfterMs = (tries) => {\n if(opts.rejoinAfterMs){\n return opts.rejoinAfterMs(tries)\n } else {\n return [1000, 2000, 5000][tries - 1] || 10000\n }\n }\n this.reconnectAfterMs = (tries) => {\n if(opts.reconnectAfterMs){\n return opts.reconnectAfterMs(tries)\n } else {\n return [10, 50, 100, 150, 200, 250, 500, 1000, 2000][tries - 1] || 5000\n }\n }\n this.logger = opts.logger || null\n if(!this.logger && opts.debug){\n this.logger = (kind, msg, data) => { console.log(`${kind}: ${msg}`, data) }\n }\n this.longpollerTimeout = opts.longpollerTimeout || 20000\n this.params = closure(opts.params || {})\n this.endPoint = `${endPoint}/${TRANSPORTS.websocket}`\n this.vsn = opts.vsn || DEFAULT_VSN\n this.heartbeatTimeoutTimer = null\n this.heartbeatTimer = null\n this.pendingHeartbeatRef = null\n this.reconnectTimer = new Timer(() => {\n this.teardown(() => this.connect())\n }, this.reconnectAfterMs)\n }\n\n /**\n * Returns the LongPoll transport reference\n */\n getLongPollTransport(){ return LongPoll }\n\n /**\n * Disconnects and replaces the active transport\n *\n * @param {Function} newTransport - The new transport class to instantiate\n *\n */\n replaceTransport(newTransport){\n this.connectClock++\n this.closeWasClean = true\n clearTimeout(this.fallbackTimer)\n this.reconnectTimer.reset()\n if(this.conn){\n this.conn.close()\n this.conn = null\n }\n this.transport = newTransport\n }\n\n /**\n * Returns the socket protocol\n *\n * @returns {string}\n */\n protocol(){ return location.protocol.match(/^https/) ? \"wss\" : \"ws\" }\n\n /**\n * The fully qualified socket url\n *\n * @returns {string}\n */\n endPointURL(){\n let uri = Ajax.appendParams(\n Ajax.appendParams(this.endPoint, this.params()), {vsn: this.vsn})\n if(uri.charAt(0) !== \"/\"){ return uri }\n if(uri.charAt(1) === \"/\"){ return `${this.protocol()}:${uri}` }\n\n return `${this.protocol()}://${location.host}${uri}`\n }\n\n /**\n * Disconnects the socket\n *\n * See https://developer.mozilla.org/en-US/docs/Web/API/CloseEvent#Status_codes for valid status codes.\n *\n * @param {Function} callback - Optional callback which is called after socket is disconnected.\n * @param {integer} code - A status code for disconnection (Optional).\n * @param {string} reason - A textual description of the reason to disconnect. (Optional)\n */\n disconnect(callback, code, reason){\n this.connectClock++\n this.closeWasClean = true\n clearTimeout(this.fallbackTimer)\n this.reconnectTimer.reset()\n this.teardown(callback, code, reason)\n }\n\n /**\n *\n * @param {Object} params - The params to send when connecting, for example `{user_id: userToken}`\n *\n * Passing params to connect is deprecated; pass them in the Socket constructor instead:\n * `new Socket(\"/socket\", {params: {user_id: userToken}})`.\n */\n connect(params){\n if(params){\n console && console.log(\"passing params to connect is deprecated. Instead pass :params to the Socket constructor\")\n this.params = closure(params)\n }\n if(this.conn){ return }\n if(this.longPollFallbackMs && this.transport !== LongPoll){\n this.connectWithFallback(LongPoll, this.longPollFallbackMs)\n } else {\n this.transportConnect()\n }\n }\n\n /**\n * Logs the message. Override `this.logger` for specialized logging. noops by default\n * @param {string} kind\n * @param {string} msg\n * @param {Object} data\n */\n log(kind, msg, data){ this.logger && this.logger(kind, msg, data) }\n\n /**\n * Returns true if a logger has been set on this socket.\n */\n hasLogger(){ return this.logger !== null }\n\n /**\n * Registers callbacks for connection open events\n *\n * @example socket.onOpen(function(){ console.info(\"the socket was opened\") })\n *\n * @param {Function} callback\n */\n onOpen(callback){\n let ref = this.makeRef()\n this.stateChangeCallbacks.open.push([ref, callback])\n return ref\n }\n\n /**\n * Registers callbacks for connection close events\n * @param {Function} callback\n */\n onClose(callback){\n let ref = this.makeRef()\n this.stateChangeCallbacks.close.push([ref, callback])\n return ref\n }\n\n /**\n * Registers callbacks for connection error events\n *\n * @example socket.onError(function(error){ alert(\"An error occurred\") })\n *\n * @param {Function} callback\n */\n onError(callback){\n let ref = this.makeRef()\n this.stateChangeCallbacks.error.push([ref, callback])\n return ref\n }\n\n /**\n * Registers callbacks for connection message events\n * @param {Function} callback\n */\n onMessage(callback){\n let ref = this.makeRef()\n this.stateChangeCallbacks.message.push([ref, callback])\n return ref\n }\n\n /**\n * Pings the server and invokes the callback with the RTT in milliseconds\n * @param {Function} callback\n *\n * Returns true if the ping was pushed or false if unable to be pushed.\n */\n ping(callback){\n if(!this.isConnected()){ return false }\n let ref = this.makeRef()\n let startTime = Date.now()\n this.push({topic: \"phoenix\", event: \"heartbeat\", payload: {}, ref: ref})\n let onMsgRef = this.onMessage(msg => {\n if(msg.ref === ref){\n this.off([onMsgRef])\n callback(Date.now() - startTime)\n }\n })\n return true\n }\n\n /**\n * @private\n */\n\n transportConnect(){\n this.connectClock++\n this.closeWasClean = false\n this.conn = new this.transport(this.endPointURL())\n this.conn.binaryType = this.binaryType\n this.conn.timeout = this.longpollerTimeout\n this.conn.onopen = () => this.onConnOpen()\n this.conn.onerror = error => this.onConnError(error)\n this.conn.onmessage = event => this.onConnMessage(event)\n this.conn.onclose = event => this.onConnClose(event)\n }\n\n getSession(key){ return this.sessionStore && this.sessionStore.getItem(key) }\n\n storeSession(key, val){ this.sessionStore && this.sessionStore.setItem(key, val) }\n\n connectWithFallback(fallbackTransport, fallbackThreshold = 2500){\n clearTimeout(this.fallbackTimer)\n let established = false\n let primaryTransport = true\n let openRef, errorRef\n let fallback = (reason) => {\n this.log(\"transport\", `falling back to ${fallbackTransport.name}...`, reason)\n this.off([openRef, errorRef])\n primaryTransport = false\n this.replaceTransport(fallbackTransport)\n this.transportConnect()\n }\n if(this.getSession(`phx:fallback:${fallbackTransport.name}`)){ return fallback(\"memorized\") }\n\n this.fallbackTimer = setTimeout(fallback, fallbackThreshold)\n\n errorRef = this.onError(reason => {\n this.log(\"transport\", \"error\", reason)\n if(primaryTransport && !established) {\n clearTimeout(this.fallbackTimer)\n fallback(reason)\n }\n })\n this.onOpen(() => {\n established = true\n if(!primaryTransport){\n // only memorize LP if we never connected to primary\n if(!this.primaryPassedHealthCheck){ this.storeSession(`phx:fallback:${fallbackTransport.name}`, \"true\") }\n return this.log(\"transport\", `established ${fallbackTransport.name} fallback`)\n }\n // if we've established primary, give the fallback a new period to attempt ping\n clearTimeout(this.fallbackTimer)\n this.fallbackTimer = setTimeout(fallback, fallbackThreshold)\n this.ping(rtt => {\n this.log(\"transport\", \"connected to primary after\", rtt)\n this.primaryPassedHealthCheck = true\n clearTimeout(this.fallbackTimer)\n })\n })\n this.transportConnect()\n }\n\n clearHeartbeats(){\n clearTimeout(this.heartbeatTimer)\n clearTimeout(this.heartbeatTimeoutTimer)\n }\n\n onConnOpen(){\n if(this.hasLogger()) this.log(\"transport\", `${this.transport.name} connected to ${this.endPointURL()}`)\n this.closeWasClean = false\n this.establishedConnections++\n this.flushSendBuffer()\n this.reconnectTimer.reset()\n this.resetHeartbeat()\n this.stateChangeCallbacks.open.forEach(([, callback]) => callback())\n }\n\n /**\n * @private\n */\n\n heartbeatTimeout(){\n if(this.pendingHeartbeatRef){\n this.pendingHeartbeatRef = null\n if(this.hasLogger()){ this.log(\"transport\", \"heartbeat timeout. Attempting to re-establish connection\") }\n this.triggerChanError()\n this.closeWasClean = false\n this.teardown(() => this.reconnectTimer.scheduleTimeout(), WS_CLOSE_NORMAL, \"heartbeat timeout\")\n }\n }\n\n resetHeartbeat(){\n if(this.conn && this.conn.skipHeartbeat){ return }\n this.pendingHeartbeatRef = null\n this.clearHeartbeats()\n this.heartbeatTimer = setTimeout(() => this.sendHeartbeat(), this.heartbeatIntervalMs)\n }\n\n teardown(callback, code, reason){\n if(!this.conn){\n return callback && callback()\n }\n\n this.waitForBufferDone(() => {\n if(this.conn){\n if(code){ this.conn.close(code, reason || \"\") } else { this.conn.close() }\n }\n\n this.waitForSocketClosed(() => {\n if(this.conn){\n this.conn.onopen = function (){ } // noop\n this.conn.onerror = function (){ } // noop\n this.conn.onmessage = function (){ } // noop\n this.conn.onclose = function (){ } // noop\n this.conn = null\n }\n\n callback && callback()\n })\n })\n }\n\n waitForBufferDone(callback, tries = 1){\n if(tries === 5 || !this.conn || !this.conn.bufferedAmount){\n callback()\n return\n }\n\n setTimeout(() => {\n this.waitForBufferDone(callback, tries + 1)\n }, 150 * tries)\n }\n\n waitForSocketClosed(callback, tries = 1){\n if(tries === 5 || !this.conn || this.conn.readyState === SOCKET_STATES.closed){\n callback()\n return\n }\n\n setTimeout(() => {\n this.waitForSocketClosed(callback, tries + 1)\n }, 150 * tries)\n }\n\n onConnClose(event){\n let closeCode = event && event.code\n if(this.hasLogger()) this.log(\"transport\", \"close\", event)\n this.triggerChanError()\n this.clearHeartbeats()\n if(!this.closeWasClean && closeCode !== 1000){\n this.reconnectTimer.scheduleTimeout()\n }\n this.stateChangeCallbacks.close.forEach(([, callback]) => callback(event))\n }\n\n /**\n * @private\n */\n onConnError(error){\n if(this.hasLogger()) this.log(\"transport\", error)\n let transportBefore = this.transport\n let establishedBefore = this.establishedConnections\n this.stateChangeCallbacks.error.forEach(([, callback]) => {\n callback(error, transportBefore, establishedBefore)\n })\n if(transportBefore === this.transport || establishedBefore > 0){\n this.triggerChanError()\n }\n }\n\n /**\n * @private\n */\n triggerChanError(){\n this.channels.forEach(channel => {\n if(!(channel.isErrored() || channel.isLeaving() || channel.isClosed())){\n channel.trigger(CHANNEL_EVENTS.error)\n }\n })\n }\n\n /**\n * @returns {string}\n */\n connectionState(){\n switch(this.conn && this.conn.readyState){\n case SOCKET_STATES.connecting: return \"connecting\"\n case SOCKET_STATES.open: return \"open\"\n case SOCKET_STATES.closing: return \"closing\"\n default: return \"closed\"\n }\n }\n\n /**\n * @returns {boolean}\n */\n isConnected(){ return this.connectionState() === \"open\" }\n\n /**\n * @private\n *\n * @param {Channel}\n */\n remove(channel){\n this.off(channel.stateChangeRefs)\n this.channels = this.channels.filter(c => c !== channel)\n }\n\n /**\n * Removes `onOpen`, `onClose`, `onError,` and `onMessage` registrations.\n *\n * @param {refs} - list of refs returned by calls to\n * `onOpen`, `onClose`, `onError,` and `onMessage`\n */\n off(refs){\n for(let key in this.stateChangeCallbacks){\n this.stateChangeCallbacks[key] = this.stateChangeCallbacks[key].filter(([ref]) => {\n return refs.indexOf(ref) === -1\n })\n }\n }\n\n /**\n * Initiates a new channel for the given topic\n *\n * @param {string} topic\n * @param {Object} chanParams - Parameters for the channel\n * @returns {Channel}\n */\n channel(topic, chanParams = {}){\n let chan = new Channel(topic, chanParams, this)\n this.channels.push(chan)\n return chan\n }\n\n /**\n * @param {Object} data\n */\n push(data){\n if(this.hasLogger()){\n let {topic, event, payload, ref, join_ref} = data\n this.log(\"push\", `${topic} ${event} (${join_ref}, ${ref})`, payload)\n }\n\n if(this.isConnected()){\n this.encode(data, result => this.conn.send(result))\n } else {\n this.sendBuffer.push(() => this.encode(data, result => this.conn.send(result)))\n }\n }\n\n /**\n * Return the next message ref, accounting for overflows\n * @returns {string}\n */\n makeRef(){\n let newRef = this.ref + 1\n if(newRef === this.ref){ this.ref = 0 } else { this.ref = newRef }\n\n return this.ref.toString()\n }\n\n sendHeartbeat(){\n if(this.pendingHeartbeatRef && !this.isConnected()){ return }\n this.pendingHeartbeatRef = this.makeRef()\n this.push({topic: \"phoenix\", event: \"heartbeat\", payload: {}, ref: this.pendingHeartbeatRef})\n this.heartbeatTimeoutTimer = setTimeout(() => this.heartbeatTimeout(), this.heartbeatIntervalMs)\n }\n\n flushSendBuffer(){\n if(this.isConnected() && this.sendBuffer.length > 0){\n this.sendBuffer.forEach(callback => callback())\n this.sendBuffer = []\n }\n }\n\n onConnMessage(rawMessage){\n this.decode(rawMessage.data, msg => {\n let {topic, event, payload, ref, join_ref} = msg\n if(ref && ref === this.pendingHeartbeatRef){\n this.clearHeartbeats()\n this.pendingHeartbeatRef = null\n this.heartbeatTimer = setTimeout(() => this.sendHeartbeat(), this.heartbeatIntervalMs)\n }\n\n if(this.hasLogger()) this.log(\"receive\", `${payload.status || \"\"} ${topic} ${event} ${ref && \"(\" + ref + \")\" || \"\"}`, payload)\n\n for(let i = 0; i < this.channels.length; i++){\n const channel = this.channels[i]\n if(!channel.isMember(topic, event, payload, join_ref)){ continue }\n channel.trigger(event, payload, ref, join_ref)\n }\n\n for(let i = 0; i < this.stateChangeCallbacks.message.length; i++){\n let [, callback] = this.stateChangeCallbacks.message[i]\n callback(msg)\n }\n })\n }\n\n leaveOpenTopic(topic){\n let dupChannel = this.channels.find(c => c.topic === topic && (c.isJoined() || c.isJoining()))\n if(dupChannel){\n if(this.hasLogger()) this.log(\"transport\", `leaving duplicate topic \"${topic}\"`)\n dupChannel.leave()\n }\n }\n}\n"], + "mappings": "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", "names": ["closure"] } diff --git a/priv/static/phoenix.js b/priv/static/phoenix.js index 2ecf403c43..e97d2c51f5 100644 --- a/priv/static/phoenix.js +++ b/priv/static/phoenix.js @@ -1461,7 +1461,7 @@ var Phoenix = (() => { */ remove(channel) { this.off(channel.stateChangeRefs); - this.channels = this.channels.filter((c) => c.joinRef() !== channel.joinRef()); + this.channels = this.channels.filter((c) => c !== channel); } /** * Removes `onOpen`, `onClose`, `onError,` and `onMessage` registrations. diff --git a/priv/static/phoenix.min.js b/priv/static/phoenix.min.js index 3050fb2ce4..ab5df84e17 100644 --- a/priv/static/phoenix.min.js +++ b/priv/static/phoenix.min.js @@ -1,2 +1,2 @@ -var Phoenix=(()=>{var x=Object.defineProperty;var $=Object.getOwnPropertyDescriptor;var M=Object.getOwnPropertyNames;var P=Object.prototype.hasOwnProperty;var D=(a,e)=>{for(var t in e)x(a,t,{get:e[t],enumerable:!0})},U=(a,e,t,i)=>{if(e&&typeof e=="object"||typeof e=="function")for(let s of M(e))!P.call(a,s)&&s!==t&&x(a,s,{get:()=>e[s],enumerable:!(i=$(e,s))||i.enumerable});return a};var J=a=>U(x({},"__esModule",{value:!0}),a);var F={};D(F,{Channel:()=>j,LongPoll:()=>m,Presence:()=>g,Serializer:()=>y,Socket:()=>w});var v=a=>typeof a=="function"?a:function(){return a};var z=typeof self!="undefined"?self:null,k=typeof window!="undefined"?window:null,C=z||k||C,H="2.0.0",d={connecting:0,open:1,closing:2,closed:3},N=1e4,O=1e3,u={closed:"closed",errored:"errored",joined:"joined",joining:"joining",leaving:"leaving"},p={close:"phx_close",error:"phx_error",join:"phx_join",reply:"phx_reply",leave:"phx_leave"},A={longpoll:"longpoll",websocket:"websocket"},B={complete:4};var b=class{constructor(e,t,i,s){this.channel=e,this.event=t,this.payload=i||function(){return{}},this.receivedResp=null,this.timeout=s,this.timeoutTimer=null,this.recHooks=[],this.sent=!1}resend(e){this.timeout=e,this.reset(),this.send()}send(){this.hasReceived("timeout")||(this.startTimeout(),this.sent=!0,this.channel.socket.push({topic:this.channel.topic,event:this.event,payload:this.payload(),ref:this.ref,join_ref:this.channel.joinRef()}))}receive(e,t){return this.hasReceived(e)&&t(this.receivedResp.response),this.recHooks.push({status:e,callback:t}),this}reset(){this.cancelRefEvent(),this.ref=null,this.refEvent=null,this.receivedResp=null,this.sent=!1}matchReceive({status:e,response:t,_ref:i}){this.recHooks.filter(s=>s.status===e).forEach(s=>s.callback(t))}cancelRefEvent(){this.refEvent&&this.channel.off(this.refEvent)}cancelTimeout(){clearTimeout(this.timeoutTimer),this.timeoutTimer=null}startTimeout(){this.timeoutTimer&&this.cancelTimeout(),this.ref=this.channel.socket.makeRef(),this.refEvent=this.channel.replyEventName(this.ref),this.channel.on(this.refEvent,e=>{this.cancelRefEvent(),this.cancelTimeout(),this.receivedResp=e,this.matchReceive(e)}),this.timeoutTimer=setTimeout(()=>{this.trigger("timeout",{})},this.timeout)}hasReceived(e){return this.receivedResp&&this.receivedResp.status===e}trigger(e,t){this.channel.trigger(this.refEvent,{status:e,response:t})}};var R=class{constructor(e,t){this.callback=e,this.timerCalc=t,this.timer=null,this.tries=0}reset(){this.tries=0,clearTimeout(this.timer)}scheduleTimeout(){clearTimeout(this.timer),this.timer=setTimeout(()=>{this.tries=this.tries+1,this.callback()},this.timerCalc(this.tries+1))}};var j=class{constructor(e,t,i){this.state=u.closed,this.topic=e,this.params=v(t||{}),this.socket=i,this.bindings=[],this.bindingRef=0,this.timeout=this.socket.timeout,this.joinedOnce=!1,this.joinPush=new b(this,p.join,this.params,this.timeout),this.pushBuffer=[],this.stateChangeRefs=[],this.rejoinTimer=new R(()=>{this.socket.isConnected()&&this.rejoin()},this.socket.rejoinAfterMs),this.stateChangeRefs.push(this.socket.onError(()=>this.rejoinTimer.reset())),this.stateChangeRefs.push(this.socket.onOpen(()=>{this.rejoinTimer.reset(),this.isErrored()&&this.rejoin()})),this.joinPush.receive("ok",()=>{this.state=u.joined,this.rejoinTimer.reset(),this.pushBuffer.forEach(s=>s.send()),this.pushBuffer=[]}),this.joinPush.receive("error",()=>{this.state=u.errored,this.socket.isConnected()&&this.rejoinTimer.scheduleTimeout()}),this.onClose(()=>{this.rejoinTimer.reset(),this.socket.hasLogger()&&this.socket.log("channel",`close ${this.topic} ${this.joinRef()}`),this.state=u.closed,this.socket.remove(this)}),this.onError(s=>{this.socket.hasLogger()&&this.socket.log("channel",`error ${this.topic}`,s),this.isJoining()&&this.joinPush.reset(),this.state=u.errored,this.socket.isConnected()&&this.rejoinTimer.scheduleTimeout()}),this.joinPush.receive("timeout",()=>{this.socket.hasLogger()&&this.socket.log("channel",`timeout ${this.topic} (${this.joinRef()})`,this.joinPush.timeout),new b(this,p.leave,v({}),this.timeout).send(),this.state=u.errored,this.joinPush.reset(),this.socket.isConnected()&&this.rejoinTimer.scheduleTimeout()}),this.on(p.reply,(s,o)=>{this.trigger(this.replyEventName(o),s)})}join(e=this.timeout){if(this.joinedOnce)throw new Error("tried to join multiple times. 'join' can only be called a single time per channel instance");return this.timeout=e,this.joinedOnce=!0,this.rejoin(),this.joinPush}onClose(e){this.on(p.close,e)}onError(e){return this.on(p.error,t=>e(t))}on(e,t){let i=this.bindingRef++;return this.bindings.push({event:e,ref:i,callback:t}),i}off(e,t){this.bindings=this.bindings.filter(i=>!(i.event===e&&(typeof t=="undefined"||t===i.ref)))}canPush(){return this.socket.isConnected()&&this.isJoined()}push(e,t,i=this.timeout){if(t=t||{},!this.joinedOnce)throw new Error(`tried to push '${e}' to '${this.topic}' before joining. Use channel.join() before pushing events`);let s=new b(this,e,function(){return t},i);return this.canPush()?s.send():(s.startTimeout(),this.pushBuffer.push(s)),s}leave(e=this.timeout){this.rejoinTimer.reset(),this.joinPush.cancelTimeout(),this.state=u.leaving;let t=()=>{this.socket.hasLogger()&&this.socket.log("channel",`leave ${this.topic}`),this.trigger(p.close,"leave")},i=new b(this,p.leave,v({}),e);return i.receive("ok",()=>t()).receive("timeout",()=>t()),i.send(),this.canPush()||i.trigger("ok",{}),i}onMessage(e,t,i){return t}isMember(e,t,i,s){return this.topic!==e?!1:s&&s!==this.joinRef()?(this.socket.hasLogger()&&this.socket.log("channel","dropping outdated message",{topic:e,event:t,payload:i,joinRef:s}),!1):!0}joinRef(){return this.joinPush.ref}rejoin(e=this.timeout){this.isLeaving()||(this.socket.leaveOpenTopic(this.topic),this.state=u.joining,this.joinPush.resend(e))}trigger(e,t,i,s){let o=this.onMessage(e,t,i,s);if(t&&!o)throw new Error("channel onMessage callbacks must return the payload, modified or unmodified");let r=this.bindings.filter(n=>n.event===e);for(let n=0;n{let h=this.parseJSON(e.responseText);n&&n(h)},r&&(e.ontimeout=r),e.onprogress=()=>{},e.send(s),e}static xhrRequest(e,t,i,s,o,r,n,h){return e.open(t,i,!0),e.timeout=r,e.setRequestHeader("Content-Type",s),e.onerror=()=>h&&h(null),e.onreadystatechange=()=>{if(e.readyState===B.complete&&h){let l=this.parseJSON(e.responseText);h(l)}},n&&(e.ontimeout=n),e.send(o),e}static parseJSON(e){if(!e||e==="")return null;try{return JSON.parse(e)}catch(t){return console&&console.log("failed to parse JSON response",e),null}}static serialize(e,t){let i=[];for(var s in e){if(!Object.prototype.hasOwnProperty.call(e,s))continue;let o=t?`${t}[${s}]`:s,r=e[s];typeof r=="object"?i.push(this.serialize(r,o)):i.push(encodeURIComponent(o)+"="+encodeURIComponent(r))}return i.join("&")}static appendParams(e,t){if(Object.keys(t).length===0)return e;let i=e.match(/\?/)?"&":"?";return`${e}${i}${this.serialize(t)}`}};var I=a=>{let e="",t=new Uint8Array(a),i=t.byteLength;for(let s=0;sthis.poll(),0)}normalizeEndpoint(e){return e.replace("ws://","http://").replace("wss://","https://").replace(new RegExp("(.*)/"+A.websocket),"$1/"+A.longpoll)}endpointURL(){return T.appendParams(this.pollEndpoint,{token:this.token})}closeAndRetry(e,t,i){this.close(e,t,i),this.readyState=d.connecting}ontimeout(){this.onerror("timeout"),this.closeAndRetry(1005,"timeout",!1)}isActive(){return this.readyState===d.open||this.readyState===d.connecting}poll(){this.ajax("GET","application/json",null,()=>this.ontimeout(),e=>{if(e){var{status:t,token:i,messages:s}=e;this.token=i}else t=0;switch(t){case 200:s.forEach(o=>{setTimeout(()=>this.onmessage({data:o}),0)}),this.poll();break;case 204:this.poll();break;case 410:this.readyState=d.open,this.onopen({}),this.poll();break;case 403:this.onerror(403),this.close(1008,"forbidden",!1);break;case 0:case 500:this.onerror(500),this.closeAndRetry(1011,"internal server error",500);break;default:throw new Error(`unhandled poll status ${t}`)}})}send(e){typeof e!="string"&&(e=I(e)),this.currentBatch?this.currentBatch.push(e):this.awaitingBatchAck?this.batchBuffer.push(e):(this.currentBatch=[e],this.currentBatchTimer=setTimeout(()=>{this.batchSend(this.currentBatch),this.currentBatch=null},0))}batchSend(e){this.awaitingBatchAck=!0,this.ajax("POST","application/x-ndjson",e.join(` -`),()=>this.onerror("timeout"),t=>{this.awaitingBatchAck=!1,!t||t.status!==200?(this.onerror(t&&t.status),this.closeAndRetry(1011,"internal server error",!1)):this.batchBuffer.length>0&&(this.batchSend(this.batchBuffer),this.batchBuffer=[])})}close(e,t,i){for(let o of this.reqs)o.abort();this.readyState=d.closed;let s=Object.assign({code:1e3,reason:void 0,wasClean:!0},{code:e,reason:t,wasClean:i});this.batchBuffer=[],clearTimeout(this.currentBatchTimer),this.currentBatchTimer=null,typeof CloseEvent!="undefined"?this.onclose(new CloseEvent("close",s)):this.onclose(s)}ajax(e,t,i,s,o){let r,n=()=>{this.reqs.delete(r),s()};r=T.request(e,this.endpointURL(),t,i,this.timeout,n,h=>{this.reqs.delete(r),this.isActive()&&o(h)}),this.reqs.add(r)}};var g=class{constructor(e,t={}){let i=t.events||{state:"presence_state",diff:"presence_diff"};this.state={},this.pendingDiffs=[],this.channel=e,this.joinRef=null,this.caller={onJoin:function(){},onLeave:function(){},onSync:function(){}},this.channel.on(i.state,s=>{let{onJoin:o,onLeave:r,onSync:n}=this.caller;this.joinRef=this.channel.joinRef(),this.state=g.syncState(this.state,s,o,r),this.pendingDiffs.forEach(h=>{this.state=g.syncDiff(this.state,h,o,r)}),this.pendingDiffs=[],n()}),this.channel.on(i.diff,s=>{let{onJoin:o,onLeave:r,onSync:n}=this.caller;this.inPendingSyncState()?this.pendingDiffs.push(s):(this.state=g.syncDiff(this.state,s,o,r),n())})}onJoin(e){this.caller.onJoin=e}onLeave(e){this.caller.onLeave=e}onSync(e){this.caller.onSync=e}list(e){return g.list(this.state,e)}inPendingSyncState(){return!this.joinRef||this.joinRef!==this.channel.joinRef()}static syncState(e,t,i,s){let o=this.clone(e),r={},n={};return this.map(o,(h,l)=>{t[h]||(n[h]=l)}),this.map(t,(h,l)=>{let f=o[h];if(f){let c=l.metas.map(S=>S.phx_ref),E=f.metas.map(S=>S.phx_ref),L=l.metas.filter(S=>E.indexOf(S.phx_ref)<0),_=f.metas.filter(S=>c.indexOf(S.phx_ref)<0);L.length>0&&(r[h]=l,r[h].metas=L),_.length>0&&(n[h]=this.clone(f),n[h].metas=_)}else r[h]=l}),this.syncDiff(o,{joins:r,leaves:n},i,s)}static syncDiff(e,t,i,s){let{joins:o,leaves:r}=this.clone(t);return i||(i=function(){}),s||(s=function(){}),this.map(o,(n,h)=>{let l=e[n];if(e[n]=this.clone(h),l){let f=e[n].metas.map(E=>E.phx_ref),c=l.metas.filter(E=>f.indexOf(E.phx_ref)<0);e[n].metas.unshift(...c)}i(n,l,h)}),this.map(r,(n,h)=>{let l=e[n];if(!l)return;let f=h.metas.map(c=>c.phx_ref);l.metas=l.metas.filter(c=>f.indexOf(c.phx_ref)<0),s(n,l,h),l.metas.length===0&&delete e[n]}),e}static list(e,t){return t||(t=function(i,s){return s}),this.map(e,(i,s)=>t(i,s))}static map(e,t){return Object.getOwnPropertyNames(e).map(i=>t(i,e[i]))}static clone(e){return JSON.parse(JSON.stringify(e))}};var y={HEADER_LENGTH:1,META_LENGTH:4,KINDS:{push:0,reply:1,broadcast:2},encode(a,e){if(a.payload.constructor===ArrayBuffer)return e(this.binaryEncode(a));{let t=[a.join_ref,a.ref,a.topic,a.event,a.payload];return e(JSON.stringify(t))}},decode(a,e){if(a.constructor===ArrayBuffer)return e(this.binaryDecode(a));{let[t,i,s,o,r]=JSON.parse(a);return e({join_ref:t,ref:i,topic:s,event:o,payload:r})}},binaryEncode(a){let{join_ref:e,ref:t,event:i,topic:s,payload:o}=a,r=this.META_LENGTH+e.length+t.length+s.length+i.length,n=new ArrayBuffer(this.HEADER_LENGTH+r),h=new DataView(n),l=0;h.setUint8(l++,this.KINDS.push),h.setUint8(l++,e.length),h.setUint8(l++,t.length),h.setUint8(l++,s.length),h.setUint8(l++,i.length),Array.from(e,c=>h.setUint8(l++,c.charCodeAt(0))),Array.from(t,c=>h.setUint8(l++,c.charCodeAt(0))),Array.from(s,c=>h.setUint8(l++,c.charCodeAt(0))),Array.from(i,c=>h.setUint8(l++,c.charCodeAt(0)));var f=new Uint8Array(n.byteLength+o.byteLength);return f.set(new Uint8Array(n),0),f.set(new Uint8Array(o),n.byteLength),f.buffer},binaryDecode(a){let e=new DataView(a),t=e.getUint8(0),i=new TextDecoder;switch(t){case this.KINDS.push:return this.decodePush(a,e,i);case this.KINDS.reply:return this.decodeReply(a,e,i);case this.KINDS.broadcast:return this.decodeBroadcast(a,e,i)}},decodePush(a,e,t){let i=e.getUint8(1),s=e.getUint8(2),o=e.getUint8(3),r=this.HEADER_LENGTH+this.META_LENGTH-1,n=t.decode(a.slice(r,r+i));r=r+i;let h=t.decode(a.slice(r,r+s));r=r+s;let l=t.decode(a.slice(r,r+o));r=r+o;let f=a.slice(r,a.byteLength);return{join_ref:n,ref:null,topic:h,event:l,payload:f}},decodeReply(a,e,t){let i=e.getUint8(1),s=e.getUint8(2),o=e.getUint8(3),r=e.getUint8(4),n=this.HEADER_LENGTH+this.META_LENGTH,h=t.decode(a.slice(n,n+i));n=n+i;let l=t.decode(a.slice(n,n+s));n=n+s;let f=t.decode(a.slice(n,n+o));n=n+o;let c=t.decode(a.slice(n,n+r));n=n+r;let E=a.slice(n,a.byteLength),L={status:c,response:E};return{join_ref:h,ref:l,topic:f,event:p.reply,payload:L}},decodeBroadcast(a,e,t){let i=e.getUint8(1),s=e.getUint8(2),o=this.HEADER_LENGTH+2,r=t.decode(a.slice(o,o+i));o=o+i;let n=t.decode(a.slice(o,o+s));o=o+s;let h=a.slice(o,a.byteLength);return{join_ref:null,ref:null,topic:r,event:n,payload:h}}};var w=class{constructor(e,t={}){this.stateChangeCallbacks={open:[],close:[],error:[],message:[]},this.channels=[],this.sendBuffer=[],this.ref=0,this.timeout=t.timeout||N,this.transport=t.transport||C.WebSocket||m,this.primaryPassedHealthCheck=!1,this.longPollFallbackMs=t.longPollFallbackMs,this.fallbackTimer=null,this.sessionStore=t.sessionStorage||C.sessionStorage,this.establishedConnections=0,this.defaultEncoder=y.encode.bind(y),this.defaultDecoder=y.decode.bind(y),this.closeWasClean=!1,this.binaryType=t.binaryType||"arraybuffer",this.connectClock=1,this.transport!==m?(this.encode=t.encode||this.defaultEncoder,this.decode=t.decode||this.defaultDecoder):(this.encode=this.defaultEncoder,this.decode=this.defaultDecoder);let i=null;k&&k.addEventListener&&(k.addEventListener("pagehide",s=>{this.conn&&(this.disconnect(),i=this.connectClock)}),k.addEventListener("pageshow",s=>{i===this.connectClock&&(i=null,this.connect())})),this.heartbeatIntervalMs=t.heartbeatIntervalMs||3e4,this.rejoinAfterMs=s=>t.rejoinAfterMs?t.rejoinAfterMs(s):[1e3,2e3,5e3][s-1]||1e4,this.reconnectAfterMs=s=>t.reconnectAfterMs?t.reconnectAfterMs(s):[10,50,100,150,200,250,500,1e3,2e3][s-1]||5e3,this.logger=t.logger||null,!this.logger&&t.debug&&(this.logger=(s,o,r)=>{console.log(`${s}: ${o}`,r)}),this.longpollerTimeout=t.longpollerTimeout||2e4,this.params=v(t.params||{}),this.endPoint=`${e}/${A.websocket}`,this.vsn=t.vsn||H,this.heartbeatTimeoutTimer=null,this.heartbeatTimer=null,this.pendingHeartbeatRef=null,this.reconnectTimer=new R(()=>{this.teardown(()=>this.connect())},this.reconnectAfterMs)}getLongPollTransport(){return m}replaceTransport(e){this.connectClock++,this.closeWasClean=!0,clearTimeout(this.fallbackTimer),this.reconnectTimer.reset(),this.conn&&(this.conn.close(),this.conn=null),this.transport=e}protocol(){return location.protocol.match(/^https/)?"wss":"ws"}endPointURL(){let e=T.appendParams(T.appendParams(this.endPoint,this.params()),{vsn:this.vsn});return e.charAt(0)!=="/"?e:e.charAt(1)==="/"?`${this.protocol()}:${e}`:`${this.protocol()}://${location.host}${e}`}disconnect(e,t,i){this.connectClock++,this.closeWasClean=!0,clearTimeout(this.fallbackTimer),this.reconnectTimer.reset(),this.teardown(e,t,i)}connect(e){e&&(console&&console.log("passing params to connect is deprecated. Instead pass :params to the Socket constructor"),this.params=v(e)),!this.conn&&(this.longPollFallbackMs&&this.transport!==m?this.connectWithFallback(m,this.longPollFallbackMs):this.transportConnect())}log(e,t,i){this.logger&&this.logger(e,t,i)}hasLogger(){return this.logger!==null}onOpen(e){let t=this.makeRef();return this.stateChangeCallbacks.open.push([t,e]),t}onClose(e){let t=this.makeRef();return this.stateChangeCallbacks.close.push([t,e]),t}onError(e){let t=this.makeRef();return this.stateChangeCallbacks.error.push([t,e]),t}onMessage(e){let t=this.makeRef();return this.stateChangeCallbacks.message.push([t,e]),t}ping(e){if(!this.isConnected())return!1;let t=this.makeRef(),i=Date.now();this.push({topic:"phoenix",event:"heartbeat",payload:{},ref:t});let s=this.onMessage(o=>{o.ref===t&&(this.off([s]),e(Date.now()-i))});return!0}transportConnect(){this.connectClock++,this.closeWasClean=!1,this.conn=new this.transport(this.endPointURL()),this.conn.binaryType=this.binaryType,this.conn.timeout=this.longpollerTimeout,this.conn.onopen=()=>this.onConnOpen(),this.conn.onerror=e=>this.onConnError(e),this.conn.onmessage=e=>this.onConnMessage(e),this.conn.onclose=e=>this.onConnClose(e)}getSession(e){return this.sessionStore&&this.sessionStore.getItem(e)}storeSession(e,t){this.sessionStore&&this.sessionStore.setItem(e,t)}connectWithFallback(e,t=2500){clearTimeout(this.fallbackTimer);let i=!1,s=!0,o,r,n=h=>{this.log("transport",`falling back to ${e.name}...`,h),this.off([o,r]),s=!1,this.replaceTransport(e),this.transportConnect()};if(this.getSession(`phx:fallback:${e.name}`))return n("memorized");this.fallbackTimer=setTimeout(n,t),r=this.onError(h=>{this.log("transport","error",h),s&&!i&&(clearTimeout(this.fallbackTimer),n(h))}),this.onOpen(()=>{if(i=!0,!s)return this.primaryPassedHealthCheck||this.storeSession(`phx:fallback:${e.name}`,"true"),this.log("transport",`established ${e.name} fallback`);clearTimeout(this.fallbackTimer),this.fallbackTimer=setTimeout(n,t),this.ping(h=>{this.log("transport","connected to primary after",h),this.primaryPassedHealthCheck=!0,clearTimeout(this.fallbackTimer)})}),this.transportConnect()}clearHeartbeats(){clearTimeout(this.heartbeatTimer),clearTimeout(this.heartbeatTimeoutTimer)}onConnOpen(){this.hasLogger()&&this.log("transport",`${this.transport.name} connected to ${this.endPointURL()}`),this.closeWasClean=!1,this.establishedConnections++,this.flushSendBuffer(),this.reconnectTimer.reset(),this.resetHeartbeat(),this.stateChangeCallbacks.open.forEach(([,e])=>e())}heartbeatTimeout(){this.pendingHeartbeatRef&&(this.pendingHeartbeatRef=null,this.hasLogger()&&this.log("transport","heartbeat timeout. Attempting to re-establish connection"),this.triggerChanError(),this.closeWasClean=!1,this.teardown(()=>this.reconnectTimer.scheduleTimeout(),O,"heartbeat timeout"))}resetHeartbeat(){this.conn&&this.conn.skipHeartbeat||(this.pendingHeartbeatRef=null,this.clearHeartbeats(),this.heartbeatTimer=setTimeout(()=>this.sendHeartbeat(),this.heartbeatIntervalMs))}teardown(e,t,i){if(!this.conn)return e&&e();this.waitForBufferDone(()=>{this.conn&&(t?this.conn.close(t,i||""):this.conn.close()),this.waitForSocketClosed(()=>{this.conn&&(this.conn.onopen=function(){},this.conn.onerror=function(){},this.conn.onmessage=function(){},this.conn.onclose=function(){},this.conn=null),e&&e()})})}waitForBufferDone(e,t=1){if(t===5||!this.conn||!this.conn.bufferedAmount){e();return}setTimeout(()=>{this.waitForBufferDone(e,t+1)},150*t)}waitForSocketClosed(e,t=1){if(t===5||!this.conn||this.conn.readyState===d.closed){e();return}setTimeout(()=>{this.waitForSocketClosed(e,t+1)},150*t)}onConnClose(e){let t=e&&e.code;this.hasLogger()&&this.log("transport","close",e),this.triggerChanError(),this.clearHeartbeats(),!this.closeWasClean&&t!==1e3&&this.reconnectTimer.scheduleTimeout(),this.stateChangeCallbacks.close.forEach(([,i])=>i(e))}onConnError(e){this.hasLogger()&&this.log("transport",e);let t=this.transport,i=this.establishedConnections;this.stateChangeCallbacks.error.forEach(([,s])=>{s(e,t,i)}),(t===this.transport||i>0)&&this.triggerChanError()}triggerChanError(){this.channels.forEach(e=>{e.isErrored()||e.isLeaving()||e.isClosed()||e.trigger(p.error)})}connectionState(){switch(this.conn&&this.conn.readyState){case d.connecting:return"connecting";case d.open:return"open";case d.closing:return"closing";default:return"closed"}}isConnected(){return this.connectionState()==="open"}remove(e){this.off(e.stateChangeRefs),this.channels=this.channels.filter(t=>t.joinRef()!==e.joinRef())}off(e){for(let t in this.stateChangeCallbacks)this.stateChangeCallbacks[t]=this.stateChangeCallbacks[t].filter(([i])=>e.indexOf(i)===-1)}channel(e,t={}){let i=new j(e,t,this);return this.channels.push(i),i}push(e){if(this.hasLogger()){let{topic:t,event:i,payload:s,ref:o,join_ref:r}=e;this.log("push",`${t} ${i} (${r}, ${o})`,s)}this.isConnected()?this.encode(e,t=>this.conn.send(t)):this.sendBuffer.push(()=>this.encode(e,t=>this.conn.send(t)))}makeRef(){let e=this.ref+1;return e===this.ref?this.ref=0:this.ref=e,this.ref.toString()}sendHeartbeat(){this.pendingHeartbeatRef&&!this.isConnected()||(this.pendingHeartbeatRef=this.makeRef(),this.push({topic:"phoenix",event:"heartbeat",payload:{},ref:this.pendingHeartbeatRef}),this.heartbeatTimeoutTimer=setTimeout(()=>this.heartbeatTimeout(),this.heartbeatIntervalMs))}flushSendBuffer(){this.isConnected()&&this.sendBuffer.length>0&&(this.sendBuffer.forEach(e=>e()),this.sendBuffer=[])}onConnMessage(e){this.decode(e.data,t=>{let{topic:i,event:s,payload:o,ref:r,join_ref:n}=t;r&&r===this.pendingHeartbeatRef&&(this.clearHeartbeats(),this.pendingHeartbeatRef=null,this.heartbeatTimer=setTimeout(()=>this.sendHeartbeat(),this.heartbeatIntervalMs)),this.hasLogger()&&this.log("receive",`${o.status||""} ${i} ${s} ${r&&"("+r+")"||""}`,o);for(let h=0;hi.topic===e&&(i.isJoined()||i.isJoining()));t&&(this.hasLogger()&&this.log("transport",`leaving duplicate topic "${e}"`),t.leave())}};return J(F);})(); +var Phoenix=(()=>{var x=Object.defineProperty;var $=Object.getOwnPropertyDescriptor;var M=Object.getOwnPropertyNames;var P=Object.prototype.hasOwnProperty;var D=(a,e)=>{for(var t in e)x(a,t,{get:e[t],enumerable:!0})},U=(a,e,t,i)=>{if(e&&typeof e=="object"||typeof e=="function")for(let s of M(e))!P.call(a,s)&&s!==t&&x(a,s,{get:()=>e[s],enumerable:!(i=$(e,s))||i.enumerable});return a};var J=a=>U(x({},"__esModule",{value:!0}),a);var F={};D(F,{Channel:()=>y,LongPoll:()=>m,Presence:()=>g,Serializer:()=>j,Socket:()=>w});var v=a=>typeof a=="function"?a:function(){return a};var z=typeof self!="undefined"?self:null,k=typeof window!="undefined"?window:null,C=z||k||C,H="2.0.0",d={connecting:0,open:1,closing:2,closed:3},N=1e4,O=1e3,u={closed:"closed",errored:"errored",joined:"joined",joining:"joining",leaving:"leaving"},p={close:"phx_close",error:"phx_error",join:"phx_join",reply:"phx_reply",leave:"phx_leave"},A={longpoll:"longpoll",websocket:"websocket"},B={complete:4};var b=class{constructor(e,t,i,s){this.channel=e,this.event=t,this.payload=i||function(){return{}},this.receivedResp=null,this.timeout=s,this.timeoutTimer=null,this.recHooks=[],this.sent=!1}resend(e){this.timeout=e,this.reset(),this.send()}send(){this.hasReceived("timeout")||(this.startTimeout(),this.sent=!0,this.channel.socket.push({topic:this.channel.topic,event:this.event,payload:this.payload(),ref:this.ref,join_ref:this.channel.joinRef()}))}receive(e,t){return this.hasReceived(e)&&t(this.receivedResp.response),this.recHooks.push({status:e,callback:t}),this}reset(){this.cancelRefEvent(),this.ref=null,this.refEvent=null,this.receivedResp=null,this.sent=!1}matchReceive({status:e,response:t,_ref:i}){this.recHooks.filter(s=>s.status===e).forEach(s=>s.callback(t))}cancelRefEvent(){this.refEvent&&this.channel.off(this.refEvent)}cancelTimeout(){clearTimeout(this.timeoutTimer),this.timeoutTimer=null}startTimeout(){this.timeoutTimer&&this.cancelTimeout(),this.ref=this.channel.socket.makeRef(),this.refEvent=this.channel.replyEventName(this.ref),this.channel.on(this.refEvent,e=>{this.cancelRefEvent(),this.cancelTimeout(),this.receivedResp=e,this.matchReceive(e)}),this.timeoutTimer=setTimeout(()=>{this.trigger("timeout",{})},this.timeout)}hasReceived(e){return this.receivedResp&&this.receivedResp.status===e}trigger(e,t){this.channel.trigger(this.refEvent,{status:e,response:t})}};var R=class{constructor(e,t){this.callback=e,this.timerCalc=t,this.timer=null,this.tries=0}reset(){this.tries=0,clearTimeout(this.timer)}scheduleTimeout(){clearTimeout(this.timer),this.timer=setTimeout(()=>{this.tries=this.tries+1,this.callback()},this.timerCalc(this.tries+1))}};var y=class{constructor(e,t,i){this.state=u.closed,this.topic=e,this.params=v(t||{}),this.socket=i,this.bindings=[],this.bindingRef=0,this.timeout=this.socket.timeout,this.joinedOnce=!1,this.joinPush=new b(this,p.join,this.params,this.timeout),this.pushBuffer=[],this.stateChangeRefs=[],this.rejoinTimer=new R(()=>{this.socket.isConnected()&&this.rejoin()},this.socket.rejoinAfterMs),this.stateChangeRefs.push(this.socket.onError(()=>this.rejoinTimer.reset())),this.stateChangeRefs.push(this.socket.onOpen(()=>{this.rejoinTimer.reset(),this.isErrored()&&this.rejoin()})),this.joinPush.receive("ok",()=>{this.state=u.joined,this.rejoinTimer.reset(),this.pushBuffer.forEach(s=>s.send()),this.pushBuffer=[]}),this.joinPush.receive("error",()=>{this.state=u.errored,this.socket.isConnected()&&this.rejoinTimer.scheduleTimeout()}),this.onClose(()=>{this.rejoinTimer.reset(),this.socket.hasLogger()&&this.socket.log("channel",`close ${this.topic} ${this.joinRef()}`),this.state=u.closed,this.socket.remove(this)}),this.onError(s=>{this.socket.hasLogger()&&this.socket.log("channel",`error ${this.topic}`,s),this.isJoining()&&this.joinPush.reset(),this.state=u.errored,this.socket.isConnected()&&this.rejoinTimer.scheduleTimeout()}),this.joinPush.receive("timeout",()=>{this.socket.hasLogger()&&this.socket.log("channel",`timeout ${this.topic} (${this.joinRef()})`,this.joinPush.timeout),new b(this,p.leave,v({}),this.timeout).send(),this.state=u.errored,this.joinPush.reset(),this.socket.isConnected()&&this.rejoinTimer.scheduleTimeout()}),this.on(p.reply,(s,o)=>{this.trigger(this.replyEventName(o),s)})}join(e=this.timeout){if(this.joinedOnce)throw new Error("tried to join multiple times. 'join' can only be called a single time per channel instance");return this.timeout=e,this.joinedOnce=!0,this.rejoin(),this.joinPush}onClose(e){this.on(p.close,e)}onError(e){return this.on(p.error,t=>e(t))}on(e,t){let i=this.bindingRef++;return this.bindings.push({event:e,ref:i,callback:t}),i}off(e,t){this.bindings=this.bindings.filter(i=>!(i.event===e&&(typeof t=="undefined"||t===i.ref)))}canPush(){return this.socket.isConnected()&&this.isJoined()}push(e,t,i=this.timeout){if(t=t||{},!this.joinedOnce)throw new Error(`tried to push '${e}' to '${this.topic}' before joining. Use channel.join() before pushing events`);let s=new b(this,e,function(){return t},i);return this.canPush()?s.send():(s.startTimeout(),this.pushBuffer.push(s)),s}leave(e=this.timeout){this.rejoinTimer.reset(),this.joinPush.cancelTimeout(),this.state=u.leaving;let t=()=>{this.socket.hasLogger()&&this.socket.log("channel",`leave ${this.topic}`),this.trigger(p.close,"leave")},i=new b(this,p.leave,v({}),e);return i.receive("ok",()=>t()).receive("timeout",()=>t()),i.send(),this.canPush()||i.trigger("ok",{}),i}onMessage(e,t,i){return t}isMember(e,t,i,s){return this.topic!==e?!1:s&&s!==this.joinRef()?(this.socket.hasLogger()&&this.socket.log("channel","dropping outdated message",{topic:e,event:t,payload:i,joinRef:s}),!1):!0}joinRef(){return this.joinPush.ref}rejoin(e=this.timeout){this.isLeaving()||(this.socket.leaveOpenTopic(this.topic),this.state=u.joining,this.joinPush.resend(e))}trigger(e,t,i,s){let o=this.onMessage(e,t,i,s);if(t&&!o)throw new Error("channel onMessage callbacks must return the payload, modified or unmodified");let r=this.bindings.filter(n=>n.event===e);for(let n=0;n{let h=this.parseJSON(e.responseText);n&&n(h)},r&&(e.ontimeout=r),e.onprogress=()=>{},e.send(s),e}static xhrRequest(e,t,i,s,o,r,n,h){return e.open(t,i,!0),e.timeout=r,e.setRequestHeader("Content-Type",s),e.onerror=()=>h&&h(null),e.onreadystatechange=()=>{if(e.readyState===B.complete&&h){let l=this.parseJSON(e.responseText);h(l)}},n&&(e.ontimeout=n),e.send(o),e}static parseJSON(e){if(!e||e==="")return null;try{return JSON.parse(e)}catch(t){return console&&console.log("failed to parse JSON response",e),null}}static serialize(e,t){let i=[];for(var s in e){if(!Object.prototype.hasOwnProperty.call(e,s))continue;let o=t?`${t}[${s}]`:s,r=e[s];typeof r=="object"?i.push(this.serialize(r,o)):i.push(encodeURIComponent(o)+"="+encodeURIComponent(r))}return i.join("&")}static appendParams(e,t){if(Object.keys(t).length===0)return e;let i=e.match(/\?/)?"&":"?";return`${e}${i}${this.serialize(t)}`}};var I=a=>{let e="",t=new Uint8Array(a),i=t.byteLength;for(let s=0;sthis.poll(),0)}normalizeEndpoint(e){return e.replace("ws://","http://").replace("wss://","https://").replace(new RegExp("(.*)/"+A.websocket),"$1/"+A.longpoll)}endpointURL(){return T.appendParams(this.pollEndpoint,{token:this.token})}closeAndRetry(e,t,i){this.close(e,t,i),this.readyState=d.connecting}ontimeout(){this.onerror("timeout"),this.closeAndRetry(1005,"timeout",!1)}isActive(){return this.readyState===d.open||this.readyState===d.connecting}poll(){this.ajax("GET","application/json",null,()=>this.ontimeout(),e=>{if(e){var{status:t,token:i,messages:s}=e;this.token=i}else t=0;switch(t){case 200:s.forEach(o=>{setTimeout(()=>this.onmessage({data:o}),0)}),this.poll();break;case 204:this.poll();break;case 410:this.readyState=d.open,this.onopen({}),this.poll();break;case 403:this.onerror(403),this.close(1008,"forbidden",!1);break;case 0:case 500:this.onerror(500),this.closeAndRetry(1011,"internal server error",500);break;default:throw new Error(`unhandled poll status ${t}`)}})}send(e){typeof e!="string"&&(e=I(e)),this.currentBatch?this.currentBatch.push(e):this.awaitingBatchAck?this.batchBuffer.push(e):(this.currentBatch=[e],this.currentBatchTimer=setTimeout(()=>{this.batchSend(this.currentBatch),this.currentBatch=null},0))}batchSend(e){this.awaitingBatchAck=!0,this.ajax("POST","application/x-ndjson",e.join(` +`),()=>this.onerror("timeout"),t=>{this.awaitingBatchAck=!1,!t||t.status!==200?(this.onerror(t&&t.status),this.closeAndRetry(1011,"internal server error",!1)):this.batchBuffer.length>0&&(this.batchSend(this.batchBuffer),this.batchBuffer=[])})}close(e,t,i){for(let o of this.reqs)o.abort();this.readyState=d.closed;let s=Object.assign({code:1e3,reason:void 0,wasClean:!0},{code:e,reason:t,wasClean:i});this.batchBuffer=[],clearTimeout(this.currentBatchTimer),this.currentBatchTimer=null,typeof CloseEvent!="undefined"?this.onclose(new CloseEvent("close",s)):this.onclose(s)}ajax(e,t,i,s,o){let r,n=()=>{this.reqs.delete(r),s()};r=T.request(e,this.endpointURL(),t,i,this.timeout,n,h=>{this.reqs.delete(r),this.isActive()&&o(h)}),this.reqs.add(r)}};var g=class{constructor(e,t={}){let i=t.events||{state:"presence_state",diff:"presence_diff"};this.state={},this.pendingDiffs=[],this.channel=e,this.joinRef=null,this.caller={onJoin:function(){},onLeave:function(){},onSync:function(){}},this.channel.on(i.state,s=>{let{onJoin:o,onLeave:r,onSync:n}=this.caller;this.joinRef=this.channel.joinRef(),this.state=g.syncState(this.state,s,o,r),this.pendingDiffs.forEach(h=>{this.state=g.syncDiff(this.state,h,o,r)}),this.pendingDiffs=[],n()}),this.channel.on(i.diff,s=>{let{onJoin:o,onLeave:r,onSync:n}=this.caller;this.inPendingSyncState()?this.pendingDiffs.push(s):(this.state=g.syncDiff(this.state,s,o,r),n())})}onJoin(e){this.caller.onJoin=e}onLeave(e){this.caller.onLeave=e}onSync(e){this.caller.onSync=e}list(e){return g.list(this.state,e)}inPendingSyncState(){return!this.joinRef||this.joinRef!==this.channel.joinRef()}static syncState(e,t,i,s){let o=this.clone(e),r={},n={};return this.map(o,(h,l)=>{t[h]||(n[h]=l)}),this.map(t,(h,l)=>{let f=o[h];if(f){let c=l.metas.map(S=>S.phx_ref),E=f.metas.map(S=>S.phx_ref),L=l.metas.filter(S=>E.indexOf(S.phx_ref)<0),_=f.metas.filter(S=>c.indexOf(S.phx_ref)<0);L.length>0&&(r[h]=l,r[h].metas=L),_.length>0&&(n[h]=this.clone(f),n[h].metas=_)}else r[h]=l}),this.syncDiff(o,{joins:r,leaves:n},i,s)}static syncDiff(e,t,i,s){let{joins:o,leaves:r}=this.clone(t);return i||(i=function(){}),s||(s=function(){}),this.map(o,(n,h)=>{let l=e[n];if(e[n]=this.clone(h),l){let f=e[n].metas.map(E=>E.phx_ref),c=l.metas.filter(E=>f.indexOf(E.phx_ref)<0);e[n].metas.unshift(...c)}i(n,l,h)}),this.map(r,(n,h)=>{let l=e[n];if(!l)return;let f=h.metas.map(c=>c.phx_ref);l.metas=l.metas.filter(c=>f.indexOf(c.phx_ref)<0),s(n,l,h),l.metas.length===0&&delete e[n]}),e}static list(e,t){return t||(t=function(i,s){return s}),this.map(e,(i,s)=>t(i,s))}static map(e,t){return Object.getOwnPropertyNames(e).map(i=>t(i,e[i]))}static clone(e){return JSON.parse(JSON.stringify(e))}};var j={HEADER_LENGTH:1,META_LENGTH:4,KINDS:{push:0,reply:1,broadcast:2},encode(a,e){if(a.payload.constructor===ArrayBuffer)return e(this.binaryEncode(a));{let t=[a.join_ref,a.ref,a.topic,a.event,a.payload];return e(JSON.stringify(t))}},decode(a,e){if(a.constructor===ArrayBuffer)return e(this.binaryDecode(a));{let[t,i,s,o,r]=JSON.parse(a);return e({join_ref:t,ref:i,topic:s,event:o,payload:r})}},binaryEncode(a){let{join_ref:e,ref:t,event:i,topic:s,payload:o}=a,r=this.META_LENGTH+e.length+t.length+s.length+i.length,n=new ArrayBuffer(this.HEADER_LENGTH+r),h=new DataView(n),l=0;h.setUint8(l++,this.KINDS.push),h.setUint8(l++,e.length),h.setUint8(l++,t.length),h.setUint8(l++,s.length),h.setUint8(l++,i.length),Array.from(e,c=>h.setUint8(l++,c.charCodeAt(0))),Array.from(t,c=>h.setUint8(l++,c.charCodeAt(0))),Array.from(s,c=>h.setUint8(l++,c.charCodeAt(0))),Array.from(i,c=>h.setUint8(l++,c.charCodeAt(0)));var f=new Uint8Array(n.byteLength+o.byteLength);return f.set(new Uint8Array(n),0),f.set(new Uint8Array(o),n.byteLength),f.buffer},binaryDecode(a){let e=new DataView(a),t=e.getUint8(0),i=new TextDecoder;switch(t){case this.KINDS.push:return this.decodePush(a,e,i);case this.KINDS.reply:return this.decodeReply(a,e,i);case this.KINDS.broadcast:return this.decodeBroadcast(a,e,i)}},decodePush(a,e,t){let i=e.getUint8(1),s=e.getUint8(2),o=e.getUint8(3),r=this.HEADER_LENGTH+this.META_LENGTH-1,n=t.decode(a.slice(r,r+i));r=r+i;let h=t.decode(a.slice(r,r+s));r=r+s;let l=t.decode(a.slice(r,r+o));r=r+o;let f=a.slice(r,a.byteLength);return{join_ref:n,ref:null,topic:h,event:l,payload:f}},decodeReply(a,e,t){let i=e.getUint8(1),s=e.getUint8(2),o=e.getUint8(3),r=e.getUint8(4),n=this.HEADER_LENGTH+this.META_LENGTH,h=t.decode(a.slice(n,n+i));n=n+i;let l=t.decode(a.slice(n,n+s));n=n+s;let f=t.decode(a.slice(n,n+o));n=n+o;let c=t.decode(a.slice(n,n+r));n=n+r;let E=a.slice(n,a.byteLength),L={status:c,response:E};return{join_ref:h,ref:l,topic:f,event:p.reply,payload:L}},decodeBroadcast(a,e,t){let i=e.getUint8(1),s=e.getUint8(2),o=this.HEADER_LENGTH+2,r=t.decode(a.slice(o,o+i));o=o+i;let n=t.decode(a.slice(o,o+s));o=o+s;let h=a.slice(o,a.byteLength);return{join_ref:null,ref:null,topic:r,event:n,payload:h}}};var w=class{constructor(e,t={}){this.stateChangeCallbacks={open:[],close:[],error:[],message:[]},this.channels=[],this.sendBuffer=[],this.ref=0,this.timeout=t.timeout||N,this.transport=t.transport||C.WebSocket||m,this.primaryPassedHealthCheck=!1,this.longPollFallbackMs=t.longPollFallbackMs,this.fallbackTimer=null,this.sessionStore=t.sessionStorage||C.sessionStorage,this.establishedConnections=0,this.defaultEncoder=j.encode.bind(j),this.defaultDecoder=j.decode.bind(j),this.closeWasClean=!1,this.binaryType=t.binaryType||"arraybuffer",this.connectClock=1,this.transport!==m?(this.encode=t.encode||this.defaultEncoder,this.decode=t.decode||this.defaultDecoder):(this.encode=this.defaultEncoder,this.decode=this.defaultDecoder);let i=null;k&&k.addEventListener&&(k.addEventListener("pagehide",s=>{this.conn&&(this.disconnect(),i=this.connectClock)}),k.addEventListener("pageshow",s=>{i===this.connectClock&&(i=null,this.connect())})),this.heartbeatIntervalMs=t.heartbeatIntervalMs||3e4,this.rejoinAfterMs=s=>t.rejoinAfterMs?t.rejoinAfterMs(s):[1e3,2e3,5e3][s-1]||1e4,this.reconnectAfterMs=s=>t.reconnectAfterMs?t.reconnectAfterMs(s):[10,50,100,150,200,250,500,1e3,2e3][s-1]||5e3,this.logger=t.logger||null,!this.logger&&t.debug&&(this.logger=(s,o,r)=>{console.log(`${s}: ${o}`,r)}),this.longpollerTimeout=t.longpollerTimeout||2e4,this.params=v(t.params||{}),this.endPoint=`${e}/${A.websocket}`,this.vsn=t.vsn||H,this.heartbeatTimeoutTimer=null,this.heartbeatTimer=null,this.pendingHeartbeatRef=null,this.reconnectTimer=new R(()=>{this.teardown(()=>this.connect())},this.reconnectAfterMs)}getLongPollTransport(){return m}replaceTransport(e){this.connectClock++,this.closeWasClean=!0,clearTimeout(this.fallbackTimer),this.reconnectTimer.reset(),this.conn&&(this.conn.close(),this.conn=null),this.transport=e}protocol(){return location.protocol.match(/^https/)?"wss":"ws"}endPointURL(){let e=T.appendParams(T.appendParams(this.endPoint,this.params()),{vsn:this.vsn});return e.charAt(0)!=="/"?e:e.charAt(1)==="/"?`${this.protocol()}:${e}`:`${this.protocol()}://${location.host}${e}`}disconnect(e,t,i){this.connectClock++,this.closeWasClean=!0,clearTimeout(this.fallbackTimer),this.reconnectTimer.reset(),this.teardown(e,t,i)}connect(e){e&&(console&&console.log("passing params to connect is deprecated. Instead pass :params to the Socket constructor"),this.params=v(e)),!this.conn&&(this.longPollFallbackMs&&this.transport!==m?this.connectWithFallback(m,this.longPollFallbackMs):this.transportConnect())}log(e,t,i){this.logger&&this.logger(e,t,i)}hasLogger(){return this.logger!==null}onOpen(e){let t=this.makeRef();return this.stateChangeCallbacks.open.push([t,e]),t}onClose(e){let t=this.makeRef();return this.stateChangeCallbacks.close.push([t,e]),t}onError(e){let t=this.makeRef();return this.stateChangeCallbacks.error.push([t,e]),t}onMessage(e){let t=this.makeRef();return this.stateChangeCallbacks.message.push([t,e]),t}ping(e){if(!this.isConnected())return!1;let t=this.makeRef(),i=Date.now();this.push({topic:"phoenix",event:"heartbeat",payload:{},ref:t});let s=this.onMessage(o=>{o.ref===t&&(this.off([s]),e(Date.now()-i))});return!0}transportConnect(){this.connectClock++,this.closeWasClean=!1,this.conn=new this.transport(this.endPointURL()),this.conn.binaryType=this.binaryType,this.conn.timeout=this.longpollerTimeout,this.conn.onopen=()=>this.onConnOpen(),this.conn.onerror=e=>this.onConnError(e),this.conn.onmessage=e=>this.onConnMessage(e),this.conn.onclose=e=>this.onConnClose(e)}getSession(e){return this.sessionStore&&this.sessionStore.getItem(e)}storeSession(e,t){this.sessionStore&&this.sessionStore.setItem(e,t)}connectWithFallback(e,t=2500){clearTimeout(this.fallbackTimer);let i=!1,s=!0,o,r,n=h=>{this.log("transport",`falling back to ${e.name}...`,h),this.off([o,r]),s=!1,this.replaceTransport(e),this.transportConnect()};if(this.getSession(`phx:fallback:${e.name}`))return n("memorized");this.fallbackTimer=setTimeout(n,t),r=this.onError(h=>{this.log("transport","error",h),s&&!i&&(clearTimeout(this.fallbackTimer),n(h))}),this.onOpen(()=>{if(i=!0,!s)return this.primaryPassedHealthCheck||this.storeSession(`phx:fallback:${e.name}`,"true"),this.log("transport",`established ${e.name} fallback`);clearTimeout(this.fallbackTimer),this.fallbackTimer=setTimeout(n,t),this.ping(h=>{this.log("transport","connected to primary after",h),this.primaryPassedHealthCheck=!0,clearTimeout(this.fallbackTimer)})}),this.transportConnect()}clearHeartbeats(){clearTimeout(this.heartbeatTimer),clearTimeout(this.heartbeatTimeoutTimer)}onConnOpen(){this.hasLogger()&&this.log("transport",`${this.transport.name} connected to ${this.endPointURL()}`),this.closeWasClean=!1,this.establishedConnections++,this.flushSendBuffer(),this.reconnectTimer.reset(),this.resetHeartbeat(),this.stateChangeCallbacks.open.forEach(([,e])=>e())}heartbeatTimeout(){this.pendingHeartbeatRef&&(this.pendingHeartbeatRef=null,this.hasLogger()&&this.log("transport","heartbeat timeout. Attempting to re-establish connection"),this.triggerChanError(),this.closeWasClean=!1,this.teardown(()=>this.reconnectTimer.scheduleTimeout(),O,"heartbeat timeout"))}resetHeartbeat(){this.conn&&this.conn.skipHeartbeat||(this.pendingHeartbeatRef=null,this.clearHeartbeats(),this.heartbeatTimer=setTimeout(()=>this.sendHeartbeat(),this.heartbeatIntervalMs))}teardown(e,t,i){if(!this.conn)return e&&e();this.waitForBufferDone(()=>{this.conn&&(t?this.conn.close(t,i||""):this.conn.close()),this.waitForSocketClosed(()=>{this.conn&&(this.conn.onopen=function(){},this.conn.onerror=function(){},this.conn.onmessage=function(){},this.conn.onclose=function(){},this.conn=null),e&&e()})})}waitForBufferDone(e,t=1){if(t===5||!this.conn||!this.conn.bufferedAmount){e();return}setTimeout(()=>{this.waitForBufferDone(e,t+1)},150*t)}waitForSocketClosed(e,t=1){if(t===5||!this.conn||this.conn.readyState===d.closed){e();return}setTimeout(()=>{this.waitForSocketClosed(e,t+1)},150*t)}onConnClose(e){let t=e&&e.code;this.hasLogger()&&this.log("transport","close",e),this.triggerChanError(),this.clearHeartbeats(),!this.closeWasClean&&t!==1e3&&this.reconnectTimer.scheduleTimeout(),this.stateChangeCallbacks.close.forEach(([,i])=>i(e))}onConnError(e){this.hasLogger()&&this.log("transport",e);let t=this.transport,i=this.establishedConnections;this.stateChangeCallbacks.error.forEach(([,s])=>{s(e,t,i)}),(t===this.transport||i>0)&&this.triggerChanError()}triggerChanError(){this.channels.forEach(e=>{e.isErrored()||e.isLeaving()||e.isClosed()||e.trigger(p.error)})}connectionState(){switch(this.conn&&this.conn.readyState){case d.connecting:return"connecting";case d.open:return"open";case d.closing:return"closing";default:return"closed"}}isConnected(){return this.connectionState()==="open"}remove(e){this.off(e.stateChangeRefs),this.channels=this.channels.filter(t=>t!==e)}off(e){for(let t in this.stateChangeCallbacks)this.stateChangeCallbacks[t]=this.stateChangeCallbacks[t].filter(([i])=>e.indexOf(i)===-1)}channel(e,t={}){let i=new y(e,t,this);return this.channels.push(i),i}push(e){if(this.hasLogger()){let{topic:t,event:i,payload:s,ref:o,join_ref:r}=e;this.log("push",`${t} ${i} (${r}, ${o})`,s)}this.isConnected()?this.encode(e,t=>this.conn.send(t)):this.sendBuffer.push(()=>this.encode(e,t=>this.conn.send(t)))}makeRef(){let e=this.ref+1;return e===this.ref?this.ref=0:this.ref=e,this.ref.toString()}sendHeartbeat(){this.pendingHeartbeatRef&&!this.isConnected()||(this.pendingHeartbeatRef=this.makeRef(),this.push({topic:"phoenix",event:"heartbeat",payload:{},ref:this.pendingHeartbeatRef}),this.heartbeatTimeoutTimer=setTimeout(()=>this.heartbeatTimeout(),this.heartbeatIntervalMs))}flushSendBuffer(){this.isConnected()&&this.sendBuffer.length>0&&(this.sendBuffer.forEach(e=>e()),this.sendBuffer=[])}onConnMessage(e){this.decode(e.data,t=>{let{topic:i,event:s,payload:o,ref:r,join_ref:n}=t;r&&r===this.pendingHeartbeatRef&&(this.clearHeartbeats(),this.pendingHeartbeatRef=null,this.heartbeatTimer=setTimeout(()=>this.sendHeartbeat(),this.heartbeatIntervalMs)),this.hasLogger()&&this.log("receive",`${o.status||""} ${i} ${s} ${r&&"("+r+")"||""}`,o);for(let h=0;hi.topic===e&&(i.isJoined()||i.isJoining()));t&&(this.hasLogger()&&this.log("transport",`leaving duplicate topic "${e}"`),t.leave())}};return J(F);})(); diff --git a/priv/static/phoenix.mjs b/priv/static/phoenix.mjs index 7107a82888..67e605dd5e 100644 --- a/priv/static/phoenix.mjs +++ b/priv/static/phoenix.mjs @@ -1432,7 +1432,7 @@ var Socket = class { */ remove(channel) { this.off(channel.stateChangeRefs); - this.channels = this.channels.filter((c) => c.joinRef() !== channel.joinRef()); + this.channels = this.channels.filter((c) => c !== channel); } /** * Removes `onOpen`, `onClose`, `onError,` and `onMessage` registrations. diff --git a/priv/static/phoenix.mjs.map b/priv/static/phoenix.mjs.map index 50d43fc347..3c0f0580a8 100644 --- a/priv/static/phoenix.mjs.map +++ b/priv/static/phoenix.mjs.map @@ -1,7 +1,7 @@ { "version": 3, "sources": ["../../assets/js/phoenix/utils.js", "../../assets/js/phoenix/constants.js", "../../assets/js/phoenix/push.js", "../../assets/js/phoenix/timer.js", "../../assets/js/phoenix/channel.js", "../../assets/js/phoenix/ajax.js", "../../assets/js/phoenix/longpoll.js", "../../assets/js/phoenix/presence.js", "../../assets/js/phoenix/serializer.js", "../../assets/js/phoenix/socket.js"], - "sourcesContent": ["// wraps value in closure or returns closure\nexport let closure = (value) => {\n if(typeof value === \"function\"){\n return value\n } else {\n let closure = function (){ return value }\n return closure\n }\n}\n", "export const globalSelf = typeof self !== \"undefined\" ? self : null\nexport const phxWindow = typeof window !== \"undefined\" ? window : null\nexport const global = globalSelf || phxWindow || global\nexport const DEFAULT_VSN = \"2.0.0\"\nexport const SOCKET_STATES = {connecting: 0, open: 1, closing: 2, closed: 3}\nexport const DEFAULT_TIMEOUT = 10000\nexport const WS_CLOSE_NORMAL = 1000\nexport const CHANNEL_STATES = {\n closed: \"closed\",\n errored: \"errored\",\n joined: \"joined\",\n joining: \"joining\",\n leaving: \"leaving\",\n}\nexport const CHANNEL_EVENTS = {\n close: \"phx_close\",\n error: \"phx_error\",\n join: \"phx_join\",\n reply: \"phx_reply\",\n leave: \"phx_leave\"\n}\n\nexport const TRANSPORTS = {\n longpoll: \"longpoll\",\n websocket: \"websocket\"\n}\nexport const XHR_STATES = {\n complete: 4\n}\n", "/**\n * Initializes the Push\n * @param {Channel} channel - The Channel\n * @param {string} event - The event, for example `\"phx_join\"`\n * @param {Object} payload - The payload, for example `{user_id: 123}`\n * @param {number} timeout - The push timeout in milliseconds\n */\nexport default class Push {\n constructor(channel, event, payload, timeout){\n this.channel = channel\n this.event = event\n this.payload = payload || function (){ return {} }\n this.receivedResp = null\n this.timeout = timeout\n this.timeoutTimer = null\n this.recHooks = []\n this.sent = false\n }\n\n /**\n *\n * @param {number} timeout\n */\n resend(timeout){\n this.timeout = timeout\n this.reset()\n this.send()\n }\n\n /**\n *\n */\n send(){\n if(this.hasReceived(\"timeout\")){ return }\n this.startTimeout()\n this.sent = true\n this.channel.socket.push({\n topic: this.channel.topic,\n event: this.event,\n payload: this.payload(),\n ref: this.ref,\n join_ref: this.channel.joinRef()\n })\n }\n\n /**\n *\n * @param {*} status\n * @param {*} callback\n */\n receive(status, callback){\n if(this.hasReceived(status)){\n callback(this.receivedResp.response)\n }\n\n this.recHooks.push({status, callback})\n return this\n }\n\n /**\n * @private\n */\n reset(){\n this.cancelRefEvent()\n this.ref = null\n this.refEvent = null\n this.receivedResp = null\n this.sent = false\n }\n\n /**\n * @private\n */\n matchReceive({status, response, _ref}){\n this.recHooks.filter(h => h.status === status)\n .forEach(h => h.callback(response))\n }\n\n /**\n * @private\n */\n cancelRefEvent(){\n if(!this.refEvent){ return }\n this.channel.off(this.refEvent)\n }\n\n /**\n * @private\n */\n cancelTimeout(){\n clearTimeout(this.timeoutTimer)\n this.timeoutTimer = null\n }\n\n /**\n * @private\n */\n startTimeout(){\n if(this.timeoutTimer){ this.cancelTimeout() }\n this.ref = this.channel.socket.makeRef()\n this.refEvent = this.channel.replyEventName(this.ref)\n\n this.channel.on(this.refEvent, payload => {\n this.cancelRefEvent()\n this.cancelTimeout()\n this.receivedResp = payload\n this.matchReceive(payload)\n })\n\n this.timeoutTimer = setTimeout(() => {\n this.trigger(\"timeout\", {})\n }, this.timeout)\n }\n\n /**\n * @private\n */\n hasReceived(status){\n return this.receivedResp && this.receivedResp.status === status\n }\n\n /**\n * @private\n */\n trigger(status, response){\n this.channel.trigger(this.refEvent, {status, response})\n }\n}\n", "/**\n *\n * Creates a timer that accepts a `timerCalc` function to perform\n * calculated timeout retries, such as exponential backoff.\n *\n * @example\n * let reconnectTimer = new Timer(() => this.connect(), function(tries){\n * return [1000, 5000, 10000][tries - 1] || 10000\n * })\n * reconnectTimer.scheduleTimeout() // fires after 1000\n * reconnectTimer.scheduleTimeout() // fires after 5000\n * reconnectTimer.reset()\n * reconnectTimer.scheduleTimeout() // fires after 1000\n *\n * @param {Function} callback\n * @param {Function} timerCalc\n */\nexport default class Timer {\n constructor(callback, timerCalc){\n this.callback = callback\n this.timerCalc = timerCalc\n this.timer = null\n this.tries = 0\n }\n\n reset(){\n this.tries = 0\n clearTimeout(this.timer)\n }\n\n /**\n * Cancels any previous scheduleTimeout and schedules callback\n */\n scheduleTimeout(){\n clearTimeout(this.timer)\n\n this.timer = setTimeout(() => {\n this.tries = this.tries + 1\n this.callback()\n }, this.timerCalc(this.tries + 1))\n }\n}\n", "import {closure} from \"./utils\"\nimport {\n CHANNEL_EVENTS,\n CHANNEL_STATES,\n} from \"./constants\"\n\nimport Push from \"./push\"\nimport Timer from \"./timer\"\n\n/**\n *\n * @param {string} topic\n * @param {(Object|function)} params\n * @param {Socket} socket\n */\nexport default class Channel {\n constructor(topic, params, socket){\n this.state = CHANNEL_STATES.closed\n this.topic = topic\n this.params = closure(params || {})\n this.socket = socket\n this.bindings = []\n this.bindingRef = 0\n this.timeout = this.socket.timeout\n this.joinedOnce = false\n this.joinPush = new Push(this, CHANNEL_EVENTS.join, this.params, this.timeout)\n this.pushBuffer = []\n this.stateChangeRefs = []\n\n this.rejoinTimer = new Timer(() => {\n if(this.socket.isConnected()){ this.rejoin() }\n }, this.socket.rejoinAfterMs)\n this.stateChangeRefs.push(this.socket.onError(() => this.rejoinTimer.reset()))\n this.stateChangeRefs.push(this.socket.onOpen(() => {\n this.rejoinTimer.reset()\n if(this.isErrored()){ this.rejoin() }\n })\n )\n this.joinPush.receive(\"ok\", () => {\n this.state = CHANNEL_STATES.joined\n this.rejoinTimer.reset()\n this.pushBuffer.forEach(pushEvent => pushEvent.send())\n this.pushBuffer = []\n })\n this.joinPush.receive(\"error\", () => {\n this.state = CHANNEL_STATES.errored\n if(this.socket.isConnected()){ this.rejoinTimer.scheduleTimeout() }\n })\n this.onClose(() => {\n this.rejoinTimer.reset()\n if(this.socket.hasLogger()) this.socket.log(\"channel\", `close ${this.topic} ${this.joinRef()}`)\n this.state = CHANNEL_STATES.closed\n this.socket.remove(this)\n })\n this.onError(reason => {\n if(this.socket.hasLogger()) this.socket.log(\"channel\", `error ${this.topic}`, reason)\n if(this.isJoining()){ this.joinPush.reset() }\n this.state = CHANNEL_STATES.errored\n if(this.socket.isConnected()){ this.rejoinTimer.scheduleTimeout() }\n })\n this.joinPush.receive(\"timeout\", () => {\n if(this.socket.hasLogger()) this.socket.log(\"channel\", `timeout ${this.topic} (${this.joinRef()})`, this.joinPush.timeout)\n let leavePush = new Push(this, CHANNEL_EVENTS.leave, closure({}), this.timeout)\n leavePush.send()\n this.state = CHANNEL_STATES.errored\n this.joinPush.reset()\n if(this.socket.isConnected()){ this.rejoinTimer.scheduleTimeout() }\n })\n this.on(CHANNEL_EVENTS.reply, (payload, ref) => {\n this.trigger(this.replyEventName(ref), payload)\n })\n }\n\n /**\n * Join the channel\n * @param {integer} timeout\n * @returns {Push}\n */\n join(timeout = this.timeout){\n if(this.joinedOnce){\n throw new Error(\"tried to join multiple times. 'join' can only be called a single time per channel instance\")\n } else {\n this.timeout = timeout\n this.joinedOnce = true\n this.rejoin()\n return this.joinPush\n }\n }\n\n /**\n * Hook into channel close\n * @param {Function} callback\n */\n onClose(callback){\n this.on(CHANNEL_EVENTS.close, callback)\n }\n\n /**\n * Hook into channel errors\n * @param {Function} callback\n */\n onError(callback){\n return this.on(CHANNEL_EVENTS.error, reason => callback(reason))\n }\n\n /**\n * Subscribes on channel events\n *\n * Subscription returns a ref counter, which can be used later to\n * unsubscribe the exact event listener\n *\n * @example\n * const ref1 = channel.on(\"event\", do_stuff)\n * const ref2 = channel.on(\"event\", do_other_stuff)\n * channel.off(\"event\", ref1)\n * // Since unsubscription, do_stuff won't fire,\n * // while do_other_stuff will keep firing on the \"event\"\n *\n * @param {string} event\n * @param {Function} callback\n * @returns {integer} ref\n */\n on(event, callback){\n let ref = this.bindingRef++\n this.bindings.push({event, ref, callback})\n return ref\n }\n\n /**\n * Unsubscribes off of channel events\n *\n * Use the ref returned from a channel.on() to unsubscribe one\n * handler, or pass nothing for the ref to unsubscribe all\n * handlers for the given event.\n *\n * @example\n * // Unsubscribe the do_stuff handler\n * const ref1 = channel.on(\"event\", do_stuff)\n * channel.off(\"event\", ref1)\n *\n * // Unsubscribe all handlers from event\n * channel.off(\"event\")\n *\n * @param {string} event\n * @param {integer} ref\n */\n off(event, ref){\n this.bindings = this.bindings.filter((bind) => {\n return !(bind.event === event && (typeof ref === \"undefined\" || ref === bind.ref))\n })\n }\n\n /**\n * @private\n */\n canPush(){ return this.socket.isConnected() && this.isJoined() }\n\n /**\n * Sends a message `event` to phoenix with the payload `payload`.\n * Phoenix receives this in the `handle_in(event, payload, socket)`\n * function. if phoenix replies or it times out (default 10000ms),\n * then optionally the reply can be received.\n *\n * @example\n * channel.push(\"event\")\n * .receive(\"ok\", payload => console.log(\"phoenix replied:\", payload))\n * .receive(\"error\", err => console.log(\"phoenix errored\", err))\n * .receive(\"timeout\", () => console.log(\"timed out pushing\"))\n * @param {string} event\n * @param {Object} payload\n * @param {number} [timeout]\n * @returns {Push}\n */\n push(event, payload, timeout = this.timeout){\n payload = payload || {}\n if(!this.joinedOnce){\n throw new Error(`tried to push '${event}' to '${this.topic}' before joining. Use channel.join() before pushing events`)\n }\n let pushEvent = new Push(this, event, function (){ return payload }, timeout)\n if(this.canPush()){\n pushEvent.send()\n } else {\n pushEvent.startTimeout()\n this.pushBuffer.push(pushEvent)\n }\n\n return pushEvent\n }\n\n /** Leaves the channel\n *\n * Unsubscribes from server events, and\n * instructs channel to terminate on server\n *\n * Triggers onClose() hooks\n *\n * To receive leave acknowledgements, use the `receive`\n * hook to bind to the server ack, ie:\n *\n * @example\n * channel.leave().receive(\"ok\", () => alert(\"left!\") )\n *\n * @param {integer} timeout\n * @returns {Push}\n */\n leave(timeout = this.timeout){\n this.rejoinTimer.reset()\n this.joinPush.cancelTimeout()\n\n this.state = CHANNEL_STATES.leaving\n let onClose = () => {\n if(this.socket.hasLogger()) this.socket.log(\"channel\", `leave ${this.topic}`)\n this.trigger(CHANNEL_EVENTS.close, \"leave\")\n }\n let leavePush = new Push(this, CHANNEL_EVENTS.leave, closure({}), timeout)\n leavePush.receive(\"ok\", () => onClose())\n .receive(\"timeout\", () => onClose())\n leavePush.send()\n if(!this.canPush()){ leavePush.trigger(\"ok\", {}) }\n\n return leavePush\n }\n\n /**\n * Overridable message hook\n *\n * Receives all events for specialized message handling\n * before dispatching to the channel callbacks.\n *\n * Must return the payload, modified or unmodified\n * @param {string} event\n * @param {Object} payload\n * @param {integer} ref\n * @returns {Object}\n */\n onMessage(_event, payload, _ref){ return payload }\n\n /**\n * @private\n */\n isMember(topic, event, payload, joinRef){\n if(this.topic !== topic){ return false }\n\n if(joinRef && joinRef !== this.joinRef()){\n if(this.socket.hasLogger()) this.socket.log(\"channel\", \"dropping outdated message\", {topic, event, payload, joinRef})\n return false\n } else {\n return true\n }\n }\n\n /**\n * @private\n */\n joinRef(){ return this.joinPush.ref }\n\n /**\n * @private\n */\n rejoin(timeout = this.timeout){\n if(this.isLeaving()){ return }\n this.socket.leaveOpenTopic(this.topic)\n this.state = CHANNEL_STATES.joining\n this.joinPush.resend(timeout)\n }\n\n /**\n * @private\n */\n trigger(event, payload, ref, joinRef){\n let handledPayload = this.onMessage(event, payload, ref, joinRef)\n if(payload && !handledPayload){ throw new Error(\"channel onMessage callbacks must return the payload, modified or unmodified\") }\n\n let eventBindings = this.bindings.filter(bind => bind.event === event)\n\n for(let i = 0; i < eventBindings.length; i++){\n let bind = eventBindings[i]\n bind.callback(handledPayload, ref, joinRef || this.joinRef())\n }\n }\n\n /**\n * @private\n */\n replyEventName(ref){ return `chan_reply_${ref}` }\n\n /**\n * @private\n */\n isClosed(){ return this.state === CHANNEL_STATES.closed }\n\n /**\n * @private\n */\n isErrored(){ return this.state === CHANNEL_STATES.errored }\n\n /**\n * @private\n */\n isJoined(){ return this.state === CHANNEL_STATES.joined }\n\n /**\n * @private\n */\n isJoining(){ return this.state === CHANNEL_STATES.joining }\n\n /**\n * @private\n */\n isLeaving(){ return this.state === CHANNEL_STATES.leaving }\n}\n", "import {\n global,\n XHR_STATES\n} from \"./constants\"\n\nexport default class Ajax {\n\n static request(method, endPoint, accept, body, timeout, ontimeout, callback){\n if(global.XDomainRequest){\n let req = new global.XDomainRequest() // IE8, IE9\n return this.xdomainRequest(req, method, endPoint, body, timeout, ontimeout, callback)\n } else {\n let req = new global.XMLHttpRequest() // IE7+, Firefox, Chrome, Opera, Safari\n return this.xhrRequest(req, method, endPoint, accept, body, timeout, ontimeout, callback)\n }\n }\n\n static xdomainRequest(req, method, endPoint, body, timeout, ontimeout, callback){\n req.timeout = timeout\n req.open(method, endPoint)\n req.onload = () => {\n let response = this.parseJSON(req.responseText)\n callback && callback(response)\n }\n if(ontimeout){ req.ontimeout = ontimeout }\n\n // Work around bug in IE9 that requires an attached onprogress handler\n req.onprogress = () => { }\n\n req.send(body)\n return req\n }\n\n static xhrRequest(req, method, endPoint, accept, body, timeout, ontimeout, callback){\n req.open(method, endPoint, true)\n req.timeout = timeout\n req.setRequestHeader(\"Content-Type\", accept)\n req.onerror = () => callback && callback(null)\n req.onreadystatechange = () => {\n if(req.readyState === XHR_STATES.complete && callback){\n let response = this.parseJSON(req.responseText)\n callback(response)\n }\n }\n if(ontimeout){ req.ontimeout = ontimeout }\n\n req.send(body)\n return req\n }\n\n static parseJSON(resp){\n if(!resp || resp === \"\"){ return null }\n\n try {\n return JSON.parse(resp)\n } catch (e){\n console && console.log(\"failed to parse JSON response\", resp)\n return null\n }\n }\n\n static serialize(obj, parentKey){\n let queryStr = []\n for(var key in obj){\n if(!Object.prototype.hasOwnProperty.call(obj, key)){ continue }\n let paramKey = parentKey ? `${parentKey}[${key}]` : key\n let paramVal = obj[key]\n if(typeof paramVal === \"object\"){\n queryStr.push(this.serialize(paramVal, paramKey))\n } else {\n queryStr.push(encodeURIComponent(paramKey) + \"=\" + encodeURIComponent(paramVal))\n }\n }\n return queryStr.join(\"&\")\n }\n\n static appendParams(url, params){\n if(Object.keys(params).length === 0){ return url }\n\n let prefix = url.match(/\\?/) ? \"&\" : \"?\"\n return `${url}${prefix}${this.serialize(params)}`\n }\n}\n", "import {\n SOCKET_STATES,\n TRANSPORTS\n} from \"./constants\"\n\nimport Ajax from \"./ajax\"\n\nlet arrayBufferToBase64 = (buffer) => {\n let binary = \"\"\n let bytes = new Uint8Array(buffer)\n let len = bytes.byteLength\n for(let i = 0; i < len; i++){ binary += String.fromCharCode(bytes[i]) }\n return btoa(binary)\n}\n\nexport default class LongPoll {\n\n constructor(endPoint){\n this.endPoint = null\n this.token = null\n this.skipHeartbeat = true\n this.reqs = new Set()\n this.awaitingBatchAck = false\n this.currentBatch = null\n this.currentBatchTimer = null\n this.batchBuffer = []\n this.onopen = function (){ } // noop\n this.onerror = function (){ } // noop\n this.onmessage = function (){ } // noop\n this.onclose = function (){ } // noop\n this.pollEndpoint = this.normalizeEndpoint(endPoint)\n this.readyState = SOCKET_STATES.connecting\n // we must wait for the caller to finish setting up our callbacks and timeout properties\n setTimeout(() => this.poll(), 0)\n }\n\n normalizeEndpoint(endPoint){\n return (endPoint\n .replace(\"ws://\", \"http://\")\n .replace(\"wss://\", \"https://\")\n .replace(new RegExp(\"(.*)\\/\" + TRANSPORTS.websocket), \"$1/\" + TRANSPORTS.longpoll))\n }\n\n endpointURL(){\n return Ajax.appendParams(this.pollEndpoint, {token: this.token})\n }\n\n closeAndRetry(code, reason, wasClean){\n this.close(code, reason, wasClean)\n this.readyState = SOCKET_STATES.connecting\n }\n\n ontimeout(){\n this.onerror(\"timeout\")\n this.closeAndRetry(1005, \"timeout\", false)\n }\n\n isActive(){ return this.readyState === SOCKET_STATES.open || this.readyState === SOCKET_STATES.connecting }\n\n poll(){\n this.ajax(\"GET\", \"application/json\", null, () => this.ontimeout(), resp => {\n if(resp){\n var {status, token, messages} = resp\n this.token = token\n } else {\n status = 0\n }\n\n switch(status){\n case 200:\n messages.forEach(msg => {\n // Tasks are what things like event handlers, setTimeout callbacks,\n // promise resolves and more are run within.\n // In modern browsers, there are two different kinds of tasks,\n // microtasks and macrotasks.\n // Microtasks are mainly used for Promises, while macrotasks are\n // used for everything else.\n // Microtasks always have priority over macrotasks. If the JS engine\n // is looking for a task to run, it will always try to empty the\n // microtask queue before attempting to run anything from the\n // macrotask queue.\n //\n // For the WebSocket transport, messages always arrive in their own\n // event. This means that if any promises are resolved from within,\n // their callbacks will always finish execution by the time the\n // next message event handler is run.\n //\n // In order to emulate this behaviour, we need to make sure each\n // onmessage handler is run within its own macrotask.\n setTimeout(() => this.onmessage({data: msg}), 0)\n })\n this.poll()\n break\n case 204:\n this.poll()\n break\n case 410:\n this.readyState = SOCKET_STATES.open\n this.onopen({})\n this.poll()\n break\n case 403:\n this.onerror(403)\n this.close(1008, \"forbidden\", false)\n break\n case 0:\n case 500:\n this.onerror(500)\n this.closeAndRetry(1011, \"internal server error\", 500)\n break\n default: throw new Error(`unhandled poll status ${status}`)\n }\n })\n }\n\n // we collect all pushes within the current event loop by\n // setTimeout 0, which optimizes back-to-back procedural\n // pushes against an empty buffer\n\n send(body){\n if(typeof(body) !== \"string\"){ body = arrayBufferToBase64(body) }\n if(this.currentBatch){\n this.currentBatch.push(body)\n } else if(this.awaitingBatchAck){\n this.batchBuffer.push(body)\n } else {\n this.currentBatch = [body]\n this.currentBatchTimer = setTimeout(() => {\n this.batchSend(this.currentBatch)\n this.currentBatch = null\n }, 0)\n }\n }\n\n batchSend(messages){\n this.awaitingBatchAck = true\n this.ajax(\"POST\", \"application/x-ndjson\", messages.join(\"\\n\"), () => this.onerror(\"timeout\"), resp => {\n this.awaitingBatchAck = false\n if(!resp || resp.status !== 200){\n this.onerror(resp && resp.status)\n this.closeAndRetry(1011, \"internal server error\", false)\n } else if(this.batchBuffer.length > 0){\n this.batchSend(this.batchBuffer)\n this.batchBuffer = []\n }\n })\n }\n\n close(code, reason, wasClean){\n for(let req of this.reqs){ req.abort() }\n this.readyState = SOCKET_STATES.closed\n let opts = Object.assign({code: 1000, reason: undefined, wasClean: true}, {code, reason, wasClean})\n this.batchBuffer = []\n clearTimeout(this.currentBatchTimer)\n this.currentBatchTimer = null\n if(typeof(CloseEvent) !== \"undefined\"){\n this.onclose(new CloseEvent(\"close\", opts))\n } else {\n this.onclose(opts)\n }\n }\n\n ajax(method, contentType, body, onCallerTimeout, callback){\n let req\n let ontimeout = () => {\n this.reqs.delete(req)\n onCallerTimeout()\n }\n req = Ajax.request(method, this.endpointURL(), contentType, body, this.timeout, ontimeout, resp => {\n this.reqs.delete(req)\n if(this.isActive()){ callback(resp) }\n })\n this.reqs.add(req)\n }\n}\n", "/**\n * Initializes the Presence\n * @param {Channel} channel - The Channel\n * @param {Object} opts - The options,\n * for example `{events: {state: \"state\", diff: \"diff\"}}`\n */\nexport default class Presence {\n\n constructor(channel, opts = {}){\n let events = opts.events || {state: \"presence_state\", diff: \"presence_diff\"}\n this.state = {}\n this.pendingDiffs = []\n this.channel = channel\n this.joinRef = null\n this.caller = {\n onJoin: function (){ },\n onLeave: function (){ },\n onSync: function (){ }\n }\n\n this.channel.on(events.state, newState => {\n let {onJoin, onLeave, onSync} = this.caller\n\n this.joinRef = this.channel.joinRef()\n this.state = Presence.syncState(this.state, newState, onJoin, onLeave)\n\n this.pendingDiffs.forEach(diff => {\n this.state = Presence.syncDiff(this.state, diff, onJoin, onLeave)\n })\n this.pendingDiffs = []\n onSync()\n })\n\n this.channel.on(events.diff, diff => {\n let {onJoin, onLeave, onSync} = this.caller\n\n if(this.inPendingSyncState()){\n this.pendingDiffs.push(diff)\n } else {\n this.state = Presence.syncDiff(this.state, diff, onJoin, onLeave)\n onSync()\n }\n })\n }\n\n onJoin(callback){ this.caller.onJoin = callback }\n\n onLeave(callback){ this.caller.onLeave = callback }\n\n onSync(callback){ this.caller.onSync = callback }\n\n list(by){ return Presence.list(this.state, by) }\n\n inPendingSyncState(){\n return !this.joinRef || (this.joinRef !== this.channel.joinRef())\n }\n\n // lower-level public static API\n\n /**\n * Used to sync the list of presences on the server\n * with the client's state. An optional `onJoin` and `onLeave` callback can\n * be provided to react to changes in the client's local presences across\n * disconnects and reconnects with the server.\n *\n * @returns {Presence}\n */\n static syncState(currentState, newState, onJoin, onLeave){\n let state = this.clone(currentState)\n let joins = {}\n let leaves = {}\n\n this.map(state, (key, presence) => {\n if(!newState[key]){\n leaves[key] = presence\n }\n })\n this.map(newState, (key, newPresence) => {\n let currentPresence = state[key]\n if(currentPresence){\n let newRefs = newPresence.metas.map(m => m.phx_ref)\n let curRefs = currentPresence.metas.map(m => m.phx_ref)\n let joinedMetas = newPresence.metas.filter(m => curRefs.indexOf(m.phx_ref) < 0)\n let leftMetas = currentPresence.metas.filter(m => newRefs.indexOf(m.phx_ref) < 0)\n if(joinedMetas.length > 0){\n joins[key] = newPresence\n joins[key].metas = joinedMetas\n }\n if(leftMetas.length > 0){\n leaves[key] = this.clone(currentPresence)\n leaves[key].metas = leftMetas\n }\n } else {\n joins[key] = newPresence\n }\n })\n return this.syncDiff(state, {joins: joins, leaves: leaves}, onJoin, onLeave)\n }\n\n /**\n *\n * Used to sync a diff of presence join and leave\n * events from the server, as they happen. Like `syncState`, `syncDiff`\n * accepts optional `onJoin` and `onLeave` callbacks to react to a user\n * joining or leaving from a device.\n *\n * @returns {Presence}\n */\n static syncDiff(state, diff, onJoin, onLeave){\n let {joins, leaves} = this.clone(diff)\n if(!onJoin){ onJoin = function (){ } }\n if(!onLeave){ onLeave = function (){ } }\n\n this.map(joins, (key, newPresence) => {\n let currentPresence = state[key]\n state[key] = this.clone(newPresence)\n if(currentPresence){\n let joinedRefs = state[key].metas.map(m => m.phx_ref)\n let curMetas = currentPresence.metas.filter(m => joinedRefs.indexOf(m.phx_ref) < 0)\n state[key].metas.unshift(...curMetas)\n }\n onJoin(key, currentPresence, newPresence)\n })\n this.map(leaves, (key, leftPresence) => {\n let currentPresence = state[key]\n if(!currentPresence){ return }\n let refsToRemove = leftPresence.metas.map(m => m.phx_ref)\n currentPresence.metas = currentPresence.metas.filter(p => {\n return refsToRemove.indexOf(p.phx_ref) < 0\n })\n onLeave(key, currentPresence, leftPresence)\n if(currentPresence.metas.length === 0){\n delete state[key]\n }\n })\n return state\n }\n\n /**\n * Returns the array of presences, with selected metadata.\n *\n * @param {Object} presences\n * @param {Function} chooser\n *\n * @returns {Presence}\n */\n static list(presences, chooser){\n if(!chooser){ chooser = function (key, pres){ return pres } }\n\n return this.map(presences, (key, presence) => {\n return chooser(key, presence)\n })\n }\n\n // private\n\n static map(obj, func){\n return Object.getOwnPropertyNames(obj).map(key => func(key, obj[key]))\n }\n\n static clone(obj){ return JSON.parse(JSON.stringify(obj)) }\n}\n", "/* The default serializer for encoding and decoding messages */\nimport {\n CHANNEL_EVENTS\n} from \"./constants\"\n\nexport default {\n HEADER_LENGTH: 1,\n META_LENGTH: 4,\n KINDS: {push: 0, reply: 1, broadcast: 2},\n\n encode(msg, callback){\n if(msg.payload.constructor === ArrayBuffer){\n return callback(this.binaryEncode(msg))\n } else {\n let payload = [msg.join_ref, msg.ref, msg.topic, msg.event, msg.payload]\n return callback(JSON.stringify(payload))\n }\n },\n\n decode(rawPayload, callback){\n if(rawPayload.constructor === ArrayBuffer){\n return callback(this.binaryDecode(rawPayload))\n } else {\n let [join_ref, ref, topic, event, payload] = JSON.parse(rawPayload)\n return callback({join_ref, ref, topic, event, payload})\n }\n },\n\n // private\n\n binaryEncode(message){\n let {join_ref, ref, event, topic, payload} = message\n let metaLength = this.META_LENGTH + join_ref.length + ref.length + topic.length + event.length\n let header = new ArrayBuffer(this.HEADER_LENGTH + metaLength)\n let view = new DataView(header)\n let offset = 0\n\n view.setUint8(offset++, this.KINDS.push) // kind\n view.setUint8(offset++, join_ref.length)\n view.setUint8(offset++, ref.length)\n view.setUint8(offset++, topic.length)\n view.setUint8(offset++, event.length)\n Array.from(join_ref, char => view.setUint8(offset++, char.charCodeAt(0)))\n Array.from(ref, char => view.setUint8(offset++, char.charCodeAt(0)))\n Array.from(topic, char => view.setUint8(offset++, char.charCodeAt(0)))\n Array.from(event, char => view.setUint8(offset++, char.charCodeAt(0)))\n\n var combined = new Uint8Array(header.byteLength + payload.byteLength)\n combined.set(new Uint8Array(header), 0)\n combined.set(new Uint8Array(payload), header.byteLength)\n\n return combined.buffer\n },\n\n binaryDecode(buffer){\n let view = new DataView(buffer)\n let kind = view.getUint8(0)\n let decoder = new TextDecoder()\n switch(kind){\n case this.KINDS.push: return this.decodePush(buffer, view, decoder)\n case this.KINDS.reply: return this.decodeReply(buffer, view, decoder)\n case this.KINDS.broadcast: return this.decodeBroadcast(buffer, view, decoder)\n }\n },\n\n decodePush(buffer, view, decoder){\n let joinRefSize = view.getUint8(1)\n let topicSize = view.getUint8(2)\n let eventSize = view.getUint8(3)\n let offset = this.HEADER_LENGTH + this.META_LENGTH - 1 // pushes have no ref\n let joinRef = decoder.decode(buffer.slice(offset, offset + joinRefSize))\n offset = offset + joinRefSize\n let topic = decoder.decode(buffer.slice(offset, offset + topicSize))\n offset = offset + topicSize\n let event = decoder.decode(buffer.slice(offset, offset + eventSize))\n offset = offset + eventSize\n let data = buffer.slice(offset, buffer.byteLength)\n return {join_ref: joinRef, ref: null, topic: topic, event: event, payload: data}\n },\n\n decodeReply(buffer, view, decoder){\n let joinRefSize = view.getUint8(1)\n let refSize = view.getUint8(2)\n let topicSize = view.getUint8(3)\n let eventSize = view.getUint8(4)\n let offset = this.HEADER_LENGTH + this.META_LENGTH\n let joinRef = decoder.decode(buffer.slice(offset, offset + joinRefSize))\n offset = offset + joinRefSize\n let ref = decoder.decode(buffer.slice(offset, offset + refSize))\n offset = offset + refSize\n let topic = decoder.decode(buffer.slice(offset, offset + topicSize))\n offset = offset + topicSize\n let event = decoder.decode(buffer.slice(offset, offset + eventSize))\n offset = offset + eventSize\n let data = buffer.slice(offset, buffer.byteLength)\n let payload = {status: event, response: data}\n return {join_ref: joinRef, ref: ref, topic: topic, event: CHANNEL_EVENTS.reply, payload: payload}\n },\n\n decodeBroadcast(buffer, view, decoder){\n let topicSize = view.getUint8(1)\n let eventSize = view.getUint8(2)\n let offset = this.HEADER_LENGTH + 2\n let topic = decoder.decode(buffer.slice(offset, offset + topicSize))\n offset = offset + topicSize\n let event = decoder.decode(buffer.slice(offset, offset + eventSize))\n offset = offset + eventSize\n let data = buffer.slice(offset, buffer.byteLength)\n\n return {join_ref: null, ref: null, topic: topic, event: event, payload: data}\n }\n}\n", "import {\n global,\n phxWindow,\n CHANNEL_EVENTS,\n DEFAULT_TIMEOUT,\n DEFAULT_VSN,\n SOCKET_STATES,\n TRANSPORTS,\n WS_CLOSE_NORMAL\n} from \"./constants\"\n\nimport {\n closure\n} from \"./utils\"\n\nimport Ajax from \"./ajax\"\nimport Channel from \"./channel\"\nimport LongPoll from \"./longpoll\"\nimport Serializer from \"./serializer\"\nimport Timer from \"./timer\"\n\n/** Initializes the Socket *\n *\n * For IE8 support use an ES5-shim (https://github.com/es-shims/es5-shim)\n *\n * @param {string} endPoint - The string WebSocket endpoint, ie, `\"ws://example.com/socket\"`,\n * `\"wss://example.com\"`\n * `\"/socket\"` (inherited host & protocol)\n * @param {Object} [opts] - Optional configuration\n * @param {Function} [opts.transport] - The Websocket Transport, for example WebSocket or Phoenix.LongPoll.\n *\n * Defaults to WebSocket with automatic LongPoll fallback if WebSocket is not defined.\n * To fallback to LongPoll when WebSocket attempts fail, use `longPollFallbackMs: 2500`.\n *\n * @param {Function} [opts.longPollFallbackMs] - The millisecond time to attempt the primary transport\n * before falling back to the LongPoll transport. Disabled by default.\n *\n * @param {Function} [opts.debug] - When true, enables debug logging. Default false.\n *\n * @param {Function} [opts.encode] - The function to encode outgoing messages.\n *\n * Defaults to JSON encoder.\n *\n * @param {Function} [opts.decode] - The function to decode incoming messages.\n *\n * Defaults to JSON:\n *\n * ```javascript\n * (payload, callback) => callback(JSON.parse(payload))\n * ```\n *\n * @param {number} [opts.timeout] - The default timeout in milliseconds to trigger push timeouts.\n *\n * Defaults `DEFAULT_TIMEOUT`\n * @param {number} [opts.heartbeatIntervalMs] - The millisec interval to send a heartbeat message\n * @param {number} [opts.reconnectAfterMs] - The optional function that returns the millisec\n * socket reconnect interval.\n *\n * Defaults to stepped backoff of:\n *\n * ```javascript\n * function(tries){\n * return [10, 50, 100, 150, 200, 250, 500, 1000, 2000][tries - 1] || 5000\n * }\n * ````\n *\n * @param {number} [opts.rejoinAfterMs] - The optional function that returns the millisec\n * rejoin interval for individual channels.\n *\n * ```javascript\n * function(tries){\n * return [1000, 2000, 5000][tries - 1] || 10000\n * }\n * ````\n *\n * @param {Function} [opts.logger] - The optional function for specialized logging, ie:\n *\n * ```javascript\n * function(kind, msg, data) {\n * console.log(`${kind}: ${msg}`, data)\n * }\n * ```\n *\n * @param {number} [opts.longpollerTimeout] - The maximum timeout of a long poll AJAX request.\n *\n * Defaults to 20s (double the server long poll timer).\n *\n * @param {(Object|function)} [opts.params] - The optional params to pass when connecting\n * @param {string} [opts.binaryType] - The binary type to use for binary WebSocket frames.\n *\n * Defaults to \"arraybuffer\"\n *\n * @param {vsn} [opts.vsn] - The serializer's protocol version to send on connect.\n *\n * Defaults to DEFAULT_VSN.\n *\n * @param {Object} [opts.sessionStorage] - An optional Storage compatible object\n * Phoenix uses sessionStorage for longpoll fallback history. Overriding the store is\n * useful when Phoenix won't have access to `sessionStorage`. For example, This could\n * happen if a site loads a cross-domain channel in an iframe. Example usage:\n *\n * class InMemoryStorage {\n * constructor() { this.storage = {} }\n * getItem(keyName) { return this.storage[keyName] || null }\n * removeItem(keyName) { delete this.storage[keyName] }\n * setItem(keyName, keyValue) { this.storage[keyName] = keyValue }\n * }\n *\n*/\nexport default class Socket {\n constructor(endPoint, opts = {}){\n this.stateChangeCallbacks = {open: [], close: [], error: [], message: []}\n this.channels = []\n this.sendBuffer = []\n this.ref = 0\n this.timeout = opts.timeout || DEFAULT_TIMEOUT\n this.transport = opts.transport || global.WebSocket || LongPoll\n this.primaryPassedHealthCheck = false\n this.longPollFallbackMs = opts.longPollFallbackMs\n this.fallbackTimer = null\n this.sessionStore = opts.sessionStorage || global.sessionStorage\n this.establishedConnections = 0\n this.defaultEncoder = Serializer.encode.bind(Serializer)\n this.defaultDecoder = Serializer.decode.bind(Serializer)\n this.closeWasClean = false\n this.binaryType = opts.binaryType || \"arraybuffer\"\n this.connectClock = 1\n if(this.transport !== LongPoll){\n this.encode = opts.encode || this.defaultEncoder\n this.decode = opts.decode || this.defaultDecoder\n } else {\n this.encode = this.defaultEncoder\n this.decode = this.defaultDecoder\n }\n let awaitingConnectionOnPageShow = null\n if(phxWindow && phxWindow.addEventListener){\n phxWindow.addEventListener(\"pagehide\", _e => {\n if(this.conn){\n this.disconnect()\n awaitingConnectionOnPageShow = this.connectClock\n }\n })\n phxWindow.addEventListener(\"pageshow\", _e => {\n if(awaitingConnectionOnPageShow === this.connectClock){\n awaitingConnectionOnPageShow = null\n this.connect()\n }\n })\n }\n this.heartbeatIntervalMs = opts.heartbeatIntervalMs || 30000\n this.rejoinAfterMs = (tries) => {\n if(opts.rejoinAfterMs){\n return opts.rejoinAfterMs(tries)\n } else {\n return [1000, 2000, 5000][tries - 1] || 10000\n }\n }\n this.reconnectAfterMs = (tries) => {\n if(opts.reconnectAfterMs){\n return opts.reconnectAfterMs(tries)\n } else {\n return [10, 50, 100, 150, 200, 250, 500, 1000, 2000][tries - 1] || 5000\n }\n }\n this.logger = opts.logger || null\n if(!this.logger && opts.debug){\n this.logger = (kind, msg, data) => { console.log(`${kind}: ${msg}`, data) }\n }\n this.longpollerTimeout = opts.longpollerTimeout || 20000\n this.params = closure(opts.params || {})\n this.endPoint = `${endPoint}/${TRANSPORTS.websocket}`\n this.vsn = opts.vsn || DEFAULT_VSN\n this.heartbeatTimeoutTimer = null\n this.heartbeatTimer = null\n this.pendingHeartbeatRef = null\n this.reconnectTimer = new Timer(() => {\n this.teardown(() => this.connect())\n }, this.reconnectAfterMs)\n }\n\n /**\n * Returns the LongPoll transport reference\n */\n getLongPollTransport(){ return LongPoll }\n\n /**\n * Disconnects and replaces the active transport\n *\n * @param {Function} newTransport - The new transport class to instantiate\n *\n */\n replaceTransport(newTransport){\n this.connectClock++\n this.closeWasClean = true\n clearTimeout(this.fallbackTimer)\n this.reconnectTimer.reset()\n if(this.conn){\n this.conn.close()\n this.conn = null\n }\n this.transport = newTransport\n }\n\n /**\n * Returns the socket protocol\n *\n * @returns {string}\n */\n protocol(){ return location.protocol.match(/^https/) ? \"wss\" : \"ws\" }\n\n /**\n * The fully qualified socket url\n *\n * @returns {string}\n */\n endPointURL(){\n let uri = Ajax.appendParams(\n Ajax.appendParams(this.endPoint, this.params()), {vsn: this.vsn})\n if(uri.charAt(0) !== \"/\"){ return uri }\n if(uri.charAt(1) === \"/\"){ return `${this.protocol()}:${uri}` }\n\n return `${this.protocol()}://${location.host}${uri}`\n }\n\n /**\n * Disconnects the socket\n *\n * See https://developer.mozilla.org/en-US/docs/Web/API/CloseEvent#Status_codes for valid status codes.\n *\n * @param {Function} callback - Optional callback which is called after socket is disconnected.\n * @param {integer} code - A status code for disconnection (Optional).\n * @param {string} reason - A textual description of the reason to disconnect. (Optional)\n */\n disconnect(callback, code, reason){\n this.connectClock++\n this.closeWasClean = true\n clearTimeout(this.fallbackTimer)\n this.reconnectTimer.reset()\n this.teardown(callback, code, reason)\n }\n\n /**\n *\n * @param {Object} params - The params to send when connecting, for example `{user_id: userToken}`\n *\n * Passing params to connect is deprecated; pass them in the Socket constructor instead:\n * `new Socket(\"/socket\", {params: {user_id: userToken}})`.\n */\n connect(params){\n if(params){\n console && console.log(\"passing params to connect is deprecated. Instead pass :params to the Socket constructor\")\n this.params = closure(params)\n }\n if(this.conn){ return }\n if(this.longPollFallbackMs && this.transport !== LongPoll){\n this.connectWithFallback(LongPoll, this.longPollFallbackMs)\n } else {\n this.transportConnect()\n }\n }\n\n /**\n * Logs the message. Override `this.logger` for specialized logging. noops by default\n * @param {string} kind\n * @param {string} msg\n * @param {Object} data\n */\n log(kind, msg, data){ this.logger && this.logger(kind, msg, data) }\n\n /**\n * Returns true if a logger has been set on this socket.\n */\n hasLogger(){ return this.logger !== null }\n\n /**\n * Registers callbacks for connection open events\n *\n * @example socket.onOpen(function(){ console.info(\"the socket was opened\") })\n *\n * @param {Function} callback\n */\n onOpen(callback){\n let ref = this.makeRef()\n this.stateChangeCallbacks.open.push([ref, callback])\n return ref\n }\n\n /**\n * Registers callbacks for connection close events\n * @param {Function} callback\n */\n onClose(callback){\n let ref = this.makeRef()\n this.stateChangeCallbacks.close.push([ref, callback])\n return ref\n }\n\n /**\n * Registers callbacks for connection error events\n *\n * @example socket.onError(function(error){ alert(\"An error occurred\") })\n *\n * @param {Function} callback\n */\n onError(callback){\n let ref = this.makeRef()\n this.stateChangeCallbacks.error.push([ref, callback])\n return ref\n }\n\n /**\n * Registers callbacks for connection message events\n * @param {Function} callback\n */\n onMessage(callback){\n let ref = this.makeRef()\n this.stateChangeCallbacks.message.push([ref, callback])\n return ref\n }\n\n /**\n * Pings the server and invokes the callback with the RTT in milliseconds\n * @param {Function} callback\n *\n * Returns true if the ping was pushed or false if unable to be pushed.\n */\n ping(callback){\n if(!this.isConnected()){ return false }\n let ref = this.makeRef()\n let startTime = Date.now()\n this.push({topic: \"phoenix\", event: \"heartbeat\", payload: {}, ref: ref})\n let onMsgRef = this.onMessage(msg => {\n if(msg.ref === ref){\n this.off([onMsgRef])\n callback(Date.now() - startTime)\n }\n })\n return true\n }\n\n /**\n * @private\n */\n\n transportConnect(){\n this.connectClock++\n this.closeWasClean = false\n this.conn = new this.transport(this.endPointURL())\n this.conn.binaryType = this.binaryType\n this.conn.timeout = this.longpollerTimeout\n this.conn.onopen = () => this.onConnOpen()\n this.conn.onerror = error => this.onConnError(error)\n this.conn.onmessage = event => this.onConnMessage(event)\n this.conn.onclose = event => this.onConnClose(event)\n }\n\n getSession(key){ return this.sessionStore && this.sessionStore.getItem(key) }\n\n storeSession(key, val){ this.sessionStore && this.sessionStore.setItem(key, val) }\n\n connectWithFallback(fallbackTransport, fallbackThreshold = 2500){\n clearTimeout(this.fallbackTimer)\n let established = false\n let primaryTransport = true\n let openRef, errorRef\n let fallback = (reason) => {\n this.log(\"transport\", `falling back to ${fallbackTransport.name}...`, reason)\n this.off([openRef, errorRef])\n primaryTransport = false\n this.replaceTransport(fallbackTransport)\n this.transportConnect()\n }\n if(this.getSession(`phx:fallback:${fallbackTransport.name}`)){ return fallback(\"memorized\") }\n\n this.fallbackTimer = setTimeout(fallback, fallbackThreshold)\n\n errorRef = this.onError(reason => {\n this.log(\"transport\", \"error\", reason)\n if(primaryTransport && !established) {\n clearTimeout(this.fallbackTimer)\n fallback(reason)\n }\n })\n this.onOpen(() => {\n established = true\n if(!primaryTransport){\n // only memorize LP if we never connected to primary\n if(!this.primaryPassedHealthCheck){ this.storeSession(`phx:fallback:${fallbackTransport.name}`, \"true\") }\n return this.log(\"transport\", `established ${fallbackTransport.name} fallback`)\n }\n // if we've established primary, give the fallback a new period to attempt ping\n clearTimeout(this.fallbackTimer)\n this.fallbackTimer = setTimeout(fallback, fallbackThreshold)\n this.ping(rtt => {\n this.log(\"transport\", \"connected to primary after\", rtt)\n this.primaryPassedHealthCheck = true\n clearTimeout(this.fallbackTimer)\n })\n })\n this.transportConnect()\n }\n\n clearHeartbeats(){\n clearTimeout(this.heartbeatTimer)\n clearTimeout(this.heartbeatTimeoutTimer)\n }\n\n onConnOpen(){\n if(this.hasLogger()) this.log(\"transport\", `${this.transport.name} connected to ${this.endPointURL()}`)\n this.closeWasClean = false\n this.establishedConnections++\n this.flushSendBuffer()\n this.reconnectTimer.reset()\n this.resetHeartbeat()\n this.stateChangeCallbacks.open.forEach(([, callback]) => callback())\n }\n\n /**\n * @private\n */\n\n heartbeatTimeout(){\n if(this.pendingHeartbeatRef){\n this.pendingHeartbeatRef = null\n if(this.hasLogger()){ this.log(\"transport\", \"heartbeat timeout. Attempting to re-establish connection\") }\n this.triggerChanError()\n this.closeWasClean = false\n this.teardown(() => this.reconnectTimer.scheduleTimeout(), WS_CLOSE_NORMAL, \"heartbeat timeout\")\n }\n }\n\n resetHeartbeat(){\n if(this.conn && this.conn.skipHeartbeat){ return }\n this.pendingHeartbeatRef = null\n this.clearHeartbeats()\n this.heartbeatTimer = setTimeout(() => this.sendHeartbeat(), this.heartbeatIntervalMs)\n }\n\n teardown(callback, code, reason){\n if(!this.conn){\n return callback && callback()\n }\n\n this.waitForBufferDone(() => {\n if(this.conn){\n if(code){ this.conn.close(code, reason || \"\") } else { this.conn.close() }\n }\n\n this.waitForSocketClosed(() => {\n if(this.conn){\n this.conn.onopen = function (){ } // noop\n this.conn.onerror = function (){ } // noop\n this.conn.onmessage = function (){ } // noop\n this.conn.onclose = function (){ } // noop\n this.conn = null\n }\n\n callback && callback()\n })\n })\n }\n\n waitForBufferDone(callback, tries = 1){\n if(tries === 5 || !this.conn || !this.conn.bufferedAmount){\n callback()\n return\n }\n\n setTimeout(() => {\n this.waitForBufferDone(callback, tries + 1)\n }, 150 * tries)\n }\n\n waitForSocketClosed(callback, tries = 1){\n if(tries === 5 || !this.conn || this.conn.readyState === SOCKET_STATES.closed){\n callback()\n return\n }\n\n setTimeout(() => {\n this.waitForSocketClosed(callback, tries + 1)\n }, 150 * tries)\n }\n\n onConnClose(event){\n let closeCode = event && event.code\n if(this.hasLogger()) this.log(\"transport\", \"close\", event)\n this.triggerChanError()\n this.clearHeartbeats()\n if(!this.closeWasClean && closeCode !== 1000){\n this.reconnectTimer.scheduleTimeout()\n }\n this.stateChangeCallbacks.close.forEach(([, callback]) => callback(event))\n }\n\n /**\n * @private\n */\n onConnError(error){\n if(this.hasLogger()) this.log(\"transport\", error)\n let transportBefore = this.transport\n let establishedBefore = this.establishedConnections\n this.stateChangeCallbacks.error.forEach(([, callback]) => {\n callback(error, transportBefore, establishedBefore)\n })\n if(transportBefore === this.transport || establishedBefore > 0){\n this.triggerChanError()\n }\n }\n\n /**\n * @private\n */\n triggerChanError(){\n this.channels.forEach(channel => {\n if(!(channel.isErrored() || channel.isLeaving() || channel.isClosed())){\n channel.trigger(CHANNEL_EVENTS.error)\n }\n })\n }\n\n /**\n * @returns {string}\n */\n connectionState(){\n switch(this.conn && this.conn.readyState){\n case SOCKET_STATES.connecting: return \"connecting\"\n case SOCKET_STATES.open: return \"open\"\n case SOCKET_STATES.closing: return \"closing\"\n default: return \"closed\"\n }\n }\n\n /**\n * @returns {boolean}\n */\n isConnected(){ return this.connectionState() === \"open\" }\n\n /**\n * @private\n *\n * @param {Channel}\n */\n remove(channel){\n this.off(channel.stateChangeRefs)\n this.channels = this.channels.filter(c => c.joinRef() !== channel.joinRef())\n }\n\n /**\n * Removes `onOpen`, `onClose`, `onError,` and `onMessage` registrations.\n *\n * @param {refs} - list of refs returned by calls to\n * `onOpen`, `onClose`, `onError,` and `onMessage`\n */\n off(refs){\n for(let key in this.stateChangeCallbacks){\n this.stateChangeCallbacks[key] = this.stateChangeCallbacks[key].filter(([ref]) => {\n return refs.indexOf(ref) === -1\n })\n }\n }\n\n /**\n * Initiates a new channel for the given topic\n *\n * @param {string} topic\n * @param {Object} chanParams - Parameters for the channel\n * @returns {Channel}\n */\n channel(topic, chanParams = {}){\n let chan = new Channel(topic, chanParams, this)\n this.channels.push(chan)\n return chan\n }\n\n /**\n * @param {Object} data\n */\n push(data){\n if(this.hasLogger()){\n let {topic, event, payload, ref, join_ref} = data\n this.log(\"push\", `${topic} ${event} (${join_ref}, ${ref})`, payload)\n }\n\n if(this.isConnected()){\n this.encode(data, result => this.conn.send(result))\n } else {\n this.sendBuffer.push(() => this.encode(data, result => this.conn.send(result)))\n }\n }\n\n /**\n * Return the next message ref, accounting for overflows\n * @returns {string}\n */\n makeRef(){\n let newRef = this.ref + 1\n if(newRef === this.ref){ this.ref = 0 } else { this.ref = newRef }\n\n return this.ref.toString()\n }\n\n sendHeartbeat(){\n if(this.pendingHeartbeatRef && !this.isConnected()){ return }\n this.pendingHeartbeatRef = this.makeRef()\n this.push({topic: \"phoenix\", event: \"heartbeat\", payload: {}, ref: this.pendingHeartbeatRef})\n this.heartbeatTimeoutTimer = setTimeout(() => this.heartbeatTimeout(), this.heartbeatIntervalMs)\n }\n\n flushSendBuffer(){\n if(this.isConnected() && this.sendBuffer.length > 0){\n this.sendBuffer.forEach(callback => callback())\n this.sendBuffer = []\n }\n }\n\n onConnMessage(rawMessage){\n this.decode(rawMessage.data, msg => {\n let {topic, event, payload, ref, join_ref} = msg\n if(ref && ref === this.pendingHeartbeatRef){\n this.clearHeartbeats()\n this.pendingHeartbeatRef = null\n this.heartbeatTimer = setTimeout(() => this.sendHeartbeat(), this.heartbeatIntervalMs)\n }\n\n if(this.hasLogger()) this.log(\"receive\", `${payload.status || \"\"} ${topic} ${event} ${ref && \"(\" + ref + \")\" || \"\"}`, payload)\n\n for(let i = 0; i < this.channels.length; i++){\n const channel = this.channels[i]\n if(!channel.isMember(topic, event, payload, join_ref)){ continue }\n channel.trigger(event, payload, ref, join_ref)\n }\n\n for(let i = 0; i < this.stateChangeCallbacks.message.length; i++){\n let [, callback] = this.stateChangeCallbacks.message[i]\n callback(msg)\n }\n })\n }\n\n leaveOpenTopic(topic){\n let dupChannel = this.channels.find(c => c.topic === topic && (c.isJoined() || c.isJoining()))\n if(dupChannel){\n if(this.hasLogger()) this.log(\"transport\", `leaving duplicate topic \"${topic}\"`)\n dupChannel.leave()\n }\n }\n}\n"], - "mappings": "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", + "sourcesContent": ["// wraps value in closure or returns closure\nexport let closure = (value) => {\n if(typeof value === \"function\"){\n return value\n } else {\n let closure = function (){ return value }\n return closure\n }\n}\n", "export const globalSelf = typeof self !== \"undefined\" ? self : null\nexport const phxWindow = typeof window !== \"undefined\" ? window : null\nexport const global = globalSelf || phxWindow || global\nexport const DEFAULT_VSN = \"2.0.0\"\nexport const SOCKET_STATES = {connecting: 0, open: 1, closing: 2, closed: 3}\nexport const DEFAULT_TIMEOUT = 10000\nexport const WS_CLOSE_NORMAL = 1000\nexport const CHANNEL_STATES = {\n closed: \"closed\",\n errored: \"errored\",\n joined: \"joined\",\n joining: \"joining\",\n leaving: \"leaving\",\n}\nexport const CHANNEL_EVENTS = {\n close: \"phx_close\",\n error: \"phx_error\",\n join: \"phx_join\",\n reply: \"phx_reply\",\n leave: \"phx_leave\"\n}\n\nexport const TRANSPORTS = {\n longpoll: \"longpoll\",\n websocket: \"websocket\"\n}\nexport const XHR_STATES = {\n complete: 4\n}\n", "/**\n * Initializes the Push\n * @param {Channel} channel - The Channel\n * @param {string} event - The event, for example `\"phx_join\"`\n * @param {Object} payload - The payload, for example `{user_id: 123}`\n * @param {number} timeout - The push timeout in milliseconds\n */\nexport default class Push {\n constructor(channel, event, payload, timeout){\n this.channel = channel\n this.event = event\n this.payload = payload || function (){ return {} }\n this.receivedResp = null\n this.timeout = timeout\n this.timeoutTimer = null\n this.recHooks = []\n this.sent = false\n }\n\n /**\n *\n * @param {number} timeout\n */\n resend(timeout){\n this.timeout = timeout\n this.reset()\n this.send()\n }\n\n /**\n *\n */\n send(){\n if(this.hasReceived(\"timeout\")){ return }\n this.startTimeout()\n this.sent = true\n this.channel.socket.push({\n topic: this.channel.topic,\n event: this.event,\n payload: this.payload(),\n ref: this.ref,\n join_ref: this.channel.joinRef()\n })\n }\n\n /**\n *\n * @param {*} status\n * @param {*} callback\n */\n receive(status, callback){\n if(this.hasReceived(status)){\n callback(this.receivedResp.response)\n }\n\n this.recHooks.push({status, callback})\n return this\n }\n\n /**\n * @private\n */\n reset(){\n this.cancelRefEvent()\n this.ref = null\n this.refEvent = null\n this.receivedResp = null\n this.sent = false\n }\n\n /**\n * @private\n */\n matchReceive({status, response, _ref}){\n this.recHooks.filter(h => h.status === status)\n .forEach(h => h.callback(response))\n }\n\n /**\n * @private\n */\n cancelRefEvent(){\n if(!this.refEvent){ return }\n this.channel.off(this.refEvent)\n }\n\n /**\n * @private\n */\n cancelTimeout(){\n clearTimeout(this.timeoutTimer)\n this.timeoutTimer = null\n }\n\n /**\n * @private\n */\n startTimeout(){\n if(this.timeoutTimer){ this.cancelTimeout() }\n this.ref = this.channel.socket.makeRef()\n this.refEvent = this.channel.replyEventName(this.ref)\n\n this.channel.on(this.refEvent, payload => {\n this.cancelRefEvent()\n this.cancelTimeout()\n this.receivedResp = payload\n this.matchReceive(payload)\n })\n\n this.timeoutTimer = setTimeout(() => {\n this.trigger(\"timeout\", {})\n }, this.timeout)\n }\n\n /**\n * @private\n */\n hasReceived(status){\n return this.receivedResp && this.receivedResp.status === status\n }\n\n /**\n * @private\n */\n trigger(status, response){\n this.channel.trigger(this.refEvent, {status, response})\n }\n}\n", "/**\n *\n * Creates a timer that accepts a `timerCalc` function to perform\n * calculated timeout retries, such as exponential backoff.\n *\n * @example\n * let reconnectTimer = new Timer(() => this.connect(), function(tries){\n * return [1000, 5000, 10000][tries - 1] || 10000\n * })\n * reconnectTimer.scheduleTimeout() // fires after 1000\n * reconnectTimer.scheduleTimeout() // fires after 5000\n * reconnectTimer.reset()\n * reconnectTimer.scheduleTimeout() // fires after 1000\n *\n * @param {Function} callback\n * @param {Function} timerCalc\n */\nexport default class Timer {\n constructor(callback, timerCalc){\n this.callback = callback\n this.timerCalc = timerCalc\n this.timer = null\n this.tries = 0\n }\n\n reset(){\n this.tries = 0\n clearTimeout(this.timer)\n }\n\n /**\n * Cancels any previous scheduleTimeout and schedules callback\n */\n scheduleTimeout(){\n clearTimeout(this.timer)\n\n this.timer = setTimeout(() => {\n this.tries = this.tries + 1\n this.callback()\n }, this.timerCalc(this.tries + 1))\n }\n}\n", "import {closure} from \"./utils\"\nimport {\n CHANNEL_EVENTS,\n CHANNEL_STATES,\n} from \"./constants\"\n\nimport Push from \"./push\"\nimport Timer from \"./timer\"\n\n/**\n *\n * @param {string} topic\n * @param {(Object|function)} params\n * @param {Socket} socket\n */\nexport default class Channel {\n constructor(topic, params, socket){\n this.state = CHANNEL_STATES.closed\n this.topic = topic\n this.params = closure(params || {})\n this.socket = socket\n this.bindings = []\n this.bindingRef = 0\n this.timeout = this.socket.timeout\n this.joinedOnce = false\n this.joinPush = new Push(this, CHANNEL_EVENTS.join, this.params, this.timeout)\n this.pushBuffer = []\n this.stateChangeRefs = []\n\n this.rejoinTimer = new Timer(() => {\n if(this.socket.isConnected()){ this.rejoin() }\n }, this.socket.rejoinAfterMs)\n this.stateChangeRefs.push(this.socket.onError(() => this.rejoinTimer.reset()))\n this.stateChangeRefs.push(this.socket.onOpen(() => {\n this.rejoinTimer.reset()\n if(this.isErrored()){ this.rejoin() }\n })\n )\n this.joinPush.receive(\"ok\", () => {\n this.state = CHANNEL_STATES.joined\n this.rejoinTimer.reset()\n this.pushBuffer.forEach(pushEvent => pushEvent.send())\n this.pushBuffer = []\n })\n this.joinPush.receive(\"error\", () => {\n this.state = CHANNEL_STATES.errored\n if(this.socket.isConnected()){ this.rejoinTimer.scheduleTimeout() }\n })\n this.onClose(() => {\n this.rejoinTimer.reset()\n if(this.socket.hasLogger()) this.socket.log(\"channel\", `close ${this.topic} ${this.joinRef()}`)\n this.state = CHANNEL_STATES.closed\n this.socket.remove(this)\n })\n this.onError(reason => {\n if(this.socket.hasLogger()) this.socket.log(\"channel\", `error ${this.topic}`, reason)\n if(this.isJoining()){ this.joinPush.reset() }\n this.state = CHANNEL_STATES.errored\n if(this.socket.isConnected()){ this.rejoinTimer.scheduleTimeout() }\n })\n this.joinPush.receive(\"timeout\", () => {\n if(this.socket.hasLogger()) this.socket.log(\"channel\", `timeout ${this.topic} (${this.joinRef()})`, this.joinPush.timeout)\n let leavePush = new Push(this, CHANNEL_EVENTS.leave, closure({}), this.timeout)\n leavePush.send()\n this.state = CHANNEL_STATES.errored\n this.joinPush.reset()\n if(this.socket.isConnected()){ this.rejoinTimer.scheduleTimeout() }\n })\n this.on(CHANNEL_EVENTS.reply, (payload, ref) => {\n this.trigger(this.replyEventName(ref), payload)\n })\n }\n\n /**\n * Join the channel\n * @param {integer} timeout\n * @returns {Push}\n */\n join(timeout = this.timeout){\n if(this.joinedOnce){\n throw new Error(\"tried to join multiple times. 'join' can only be called a single time per channel instance\")\n } else {\n this.timeout = timeout\n this.joinedOnce = true\n this.rejoin()\n return this.joinPush\n }\n }\n\n /**\n * Hook into channel close\n * @param {Function} callback\n */\n onClose(callback){\n this.on(CHANNEL_EVENTS.close, callback)\n }\n\n /**\n * Hook into channel errors\n * @param {Function} callback\n */\n onError(callback){\n return this.on(CHANNEL_EVENTS.error, reason => callback(reason))\n }\n\n /**\n * Subscribes on channel events\n *\n * Subscription returns a ref counter, which can be used later to\n * unsubscribe the exact event listener\n *\n * @example\n * const ref1 = channel.on(\"event\", do_stuff)\n * const ref2 = channel.on(\"event\", do_other_stuff)\n * channel.off(\"event\", ref1)\n * // Since unsubscription, do_stuff won't fire,\n * // while do_other_stuff will keep firing on the \"event\"\n *\n * @param {string} event\n * @param {Function} callback\n * @returns {integer} ref\n */\n on(event, callback){\n let ref = this.bindingRef++\n this.bindings.push({event, ref, callback})\n return ref\n }\n\n /**\n * Unsubscribes off of channel events\n *\n * Use the ref returned from a channel.on() to unsubscribe one\n * handler, or pass nothing for the ref to unsubscribe all\n * handlers for the given event.\n *\n * @example\n * // Unsubscribe the do_stuff handler\n * const ref1 = channel.on(\"event\", do_stuff)\n * channel.off(\"event\", ref1)\n *\n * // Unsubscribe all handlers from event\n * channel.off(\"event\")\n *\n * @param {string} event\n * @param {integer} ref\n */\n off(event, ref){\n this.bindings = this.bindings.filter((bind) => {\n return !(bind.event === event && (typeof ref === \"undefined\" || ref === bind.ref))\n })\n }\n\n /**\n * @private\n */\n canPush(){ return this.socket.isConnected() && this.isJoined() }\n\n /**\n * Sends a message `event` to phoenix with the payload `payload`.\n * Phoenix receives this in the `handle_in(event, payload, socket)`\n * function. if phoenix replies or it times out (default 10000ms),\n * then optionally the reply can be received.\n *\n * @example\n * channel.push(\"event\")\n * .receive(\"ok\", payload => console.log(\"phoenix replied:\", payload))\n * .receive(\"error\", err => console.log(\"phoenix errored\", err))\n * .receive(\"timeout\", () => console.log(\"timed out pushing\"))\n * @param {string} event\n * @param {Object} payload\n * @param {number} [timeout]\n * @returns {Push}\n */\n push(event, payload, timeout = this.timeout){\n payload = payload || {}\n if(!this.joinedOnce){\n throw new Error(`tried to push '${event}' to '${this.topic}' before joining. Use channel.join() before pushing events`)\n }\n let pushEvent = new Push(this, event, function (){ return payload }, timeout)\n if(this.canPush()){\n pushEvent.send()\n } else {\n pushEvent.startTimeout()\n this.pushBuffer.push(pushEvent)\n }\n\n return pushEvent\n }\n\n /** Leaves the channel\n *\n * Unsubscribes from server events, and\n * instructs channel to terminate on server\n *\n * Triggers onClose() hooks\n *\n * To receive leave acknowledgements, use the `receive`\n * hook to bind to the server ack, ie:\n *\n * @example\n * channel.leave().receive(\"ok\", () => alert(\"left!\") )\n *\n * @param {integer} timeout\n * @returns {Push}\n */\n leave(timeout = this.timeout){\n this.rejoinTimer.reset()\n this.joinPush.cancelTimeout()\n\n this.state = CHANNEL_STATES.leaving\n let onClose = () => {\n if(this.socket.hasLogger()) this.socket.log(\"channel\", `leave ${this.topic}`)\n this.trigger(CHANNEL_EVENTS.close, \"leave\")\n }\n let leavePush = new Push(this, CHANNEL_EVENTS.leave, closure({}), timeout)\n leavePush.receive(\"ok\", () => onClose())\n .receive(\"timeout\", () => onClose())\n leavePush.send()\n if(!this.canPush()){ leavePush.trigger(\"ok\", {}) }\n\n return leavePush\n }\n\n /**\n * Overridable message hook\n *\n * Receives all events for specialized message handling\n * before dispatching to the channel callbacks.\n *\n * Must return the payload, modified or unmodified\n * @param {string} event\n * @param {Object} payload\n * @param {integer} ref\n * @returns {Object}\n */\n onMessage(_event, payload, _ref){ return payload }\n\n /**\n * @private\n */\n isMember(topic, event, payload, joinRef){\n if(this.topic !== topic){ return false }\n\n if(joinRef && joinRef !== this.joinRef()){\n if(this.socket.hasLogger()) this.socket.log(\"channel\", \"dropping outdated message\", {topic, event, payload, joinRef})\n return false\n } else {\n return true\n }\n }\n\n /**\n * @private\n */\n joinRef(){ return this.joinPush.ref }\n\n /**\n * @private\n */\n rejoin(timeout = this.timeout){\n if(this.isLeaving()){ return }\n this.socket.leaveOpenTopic(this.topic)\n this.state = CHANNEL_STATES.joining\n this.joinPush.resend(timeout)\n }\n\n /**\n * @private\n */\n trigger(event, payload, ref, joinRef){\n let handledPayload = this.onMessage(event, payload, ref, joinRef)\n if(payload && !handledPayload){ throw new Error(\"channel onMessage callbacks must return the payload, modified or unmodified\") }\n\n let eventBindings = this.bindings.filter(bind => bind.event === event)\n\n for(let i = 0; i < eventBindings.length; i++){\n let bind = eventBindings[i]\n bind.callback(handledPayload, ref, joinRef || this.joinRef())\n }\n }\n\n /**\n * @private\n */\n replyEventName(ref){ return `chan_reply_${ref}` }\n\n /**\n * @private\n */\n isClosed(){ return this.state === CHANNEL_STATES.closed }\n\n /**\n * @private\n */\n isErrored(){ return this.state === CHANNEL_STATES.errored }\n\n /**\n * @private\n */\n isJoined(){ return this.state === CHANNEL_STATES.joined }\n\n /**\n * @private\n */\n isJoining(){ return this.state === CHANNEL_STATES.joining }\n\n /**\n * @private\n */\n isLeaving(){ return this.state === CHANNEL_STATES.leaving }\n}\n", "import {\n global,\n XHR_STATES\n} from \"./constants\"\n\nexport default class Ajax {\n\n static request(method, endPoint, accept, body, timeout, ontimeout, callback){\n if(global.XDomainRequest){\n let req = new global.XDomainRequest() // IE8, IE9\n return this.xdomainRequest(req, method, endPoint, body, timeout, ontimeout, callback)\n } else {\n let req = new global.XMLHttpRequest() // IE7+, Firefox, Chrome, Opera, Safari\n return this.xhrRequest(req, method, endPoint, accept, body, timeout, ontimeout, callback)\n }\n }\n\n static xdomainRequest(req, method, endPoint, body, timeout, ontimeout, callback){\n req.timeout = timeout\n req.open(method, endPoint)\n req.onload = () => {\n let response = this.parseJSON(req.responseText)\n callback && callback(response)\n }\n if(ontimeout){ req.ontimeout = ontimeout }\n\n // Work around bug in IE9 that requires an attached onprogress handler\n req.onprogress = () => { }\n\n req.send(body)\n return req\n }\n\n static xhrRequest(req, method, endPoint, accept, body, timeout, ontimeout, callback){\n req.open(method, endPoint, true)\n req.timeout = timeout\n req.setRequestHeader(\"Content-Type\", accept)\n req.onerror = () => callback && callback(null)\n req.onreadystatechange = () => {\n if(req.readyState === XHR_STATES.complete && callback){\n let response = this.parseJSON(req.responseText)\n callback(response)\n }\n }\n if(ontimeout){ req.ontimeout = ontimeout }\n\n req.send(body)\n return req\n }\n\n static parseJSON(resp){\n if(!resp || resp === \"\"){ return null }\n\n try {\n return JSON.parse(resp)\n } catch (e){\n console && console.log(\"failed to parse JSON response\", resp)\n return null\n }\n }\n\n static serialize(obj, parentKey){\n let queryStr = []\n for(var key in obj){\n if(!Object.prototype.hasOwnProperty.call(obj, key)){ continue }\n let paramKey = parentKey ? `${parentKey}[${key}]` : key\n let paramVal = obj[key]\n if(typeof paramVal === \"object\"){\n queryStr.push(this.serialize(paramVal, paramKey))\n } else {\n queryStr.push(encodeURIComponent(paramKey) + \"=\" + encodeURIComponent(paramVal))\n }\n }\n return queryStr.join(\"&\")\n }\n\n static appendParams(url, params){\n if(Object.keys(params).length === 0){ return url }\n\n let prefix = url.match(/\\?/) ? \"&\" : \"?\"\n return `${url}${prefix}${this.serialize(params)}`\n }\n}\n", "import {\n SOCKET_STATES,\n TRANSPORTS\n} from \"./constants\"\n\nimport Ajax from \"./ajax\"\n\nlet arrayBufferToBase64 = (buffer) => {\n let binary = \"\"\n let bytes = new Uint8Array(buffer)\n let len = bytes.byteLength\n for(let i = 0; i < len; i++){ binary += String.fromCharCode(bytes[i]) }\n return btoa(binary)\n}\n\nexport default class LongPoll {\n\n constructor(endPoint){\n this.endPoint = null\n this.token = null\n this.skipHeartbeat = true\n this.reqs = new Set()\n this.awaitingBatchAck = false\n this.currentBatch = null\n this.currentBatchTimer = null\n this.batchBuffer = []\n this.onopen = function (){ } // noop\n this.onerror = function (){ } // noop\n this.onmessage = function (){ } // noop\n this.onclose = function (){ } // noop\n this.pollEndpoint = this.normalizeEndpoint(endPoint)\n this.readyState = SOCKET_STATES.connecting\n // we must wait for the caller to finish setting up our callbacks and timeout properties\n setTimeout(() => this.poll(), 0)\n }\n\n normalizeEndpoint(endPoint){\n return (endPoint\n .replace(\"ws://\", \"http://\")\n .replace(\"wss://\", \"https://\")\n .replace(new RegExp(\"(.*)\\/\" + TRANSPORTS.websocket), \"$1/\" + TRANSPORTS.longpoll))\n }\n\n endpointURL(){\n return Ajax.appendParams(this.pollEndpoint, {token: this.token})\n }\n\n closeAndRetry(code, reason, wasClean){\n this.close(code, reason, wasClean)\n this.readyState = SOCKET_STATES.connecting\n }\n\n ontimeout(){\n this.onerror(\"timeout\")\n this.closeAndRetry(1005, \"timeout\", false)\n }\n\n isActive(){ return this.readyState === SOCKET_STATES.open || this.readyState === SOCKET_STATES.connecting }\n\n poll(){\n this.ajax(\"GET\", \"application/json\", null, () => this.ontimeout(), resp => {\n if(resp){\n var {status, token, messages} = resp\n this.token = token\n } else {\n status = 0\n }\n\n switch(status){\n case 200:\n messages.forEach(msg => {\n // Tasks are what things like event handlers, setTimeout callbacks,\n // promise resolves and more are run within.\n // In modern browsers, there are two different kinds of tasks,\n // microtasks and macrotasks.\n // Microtasks are mainly used for Promises, while macrotasks are\n // used for everything else.\n // Microtasks always have priority over macrotasks. If the JS engine\n // is looking for a task to run, it will always try to empty the\n // microtask queue before attempting to run anything from the\n // macrotask queue.\n //\n // For the WebSocket transport, messages always arrive in their own\n // event. This means that if any promises are resolved from within,\n // their callbacks will always finish execution by the time the\n // next message event handler is run.\n //\n // In order to emulate this behaviour, we need to make sure each\n // onmessage handler is run within its own macrotask.\n setTimeout(() => this.onmessage({data: msg}), 0)\n })\n this.poll()\n break\n case 204:\n this.poll()\n break\n case 410:\n this.readyState = SOCKET_STATES.open\n this.onopen({})\n this.poll()\n break\n case 403:\n this.onerror(403)\n this.close(1008, \"forbidden\", false)\n break\n case 0:\n case 500:\n this.onerror(500)\n this.closeAndRetry(1011, \"internal server error\", 500)\n break\n default: throw new Error(`unhandled poll status ${status}`)\n }\n })\n }\n\n // we collect all pushes within the current event loop by\n // setTimeout 0, which optimizes back-to-back procedural\n // pushes against an empty buffer\n\n send(body){\n if(typeof(body) !== \"string\"){ body = arrayBufferToBase64(body) }\n if(this.currentBatch){\n this.currentBatch.push(body)\n } else if(this.awaitingBatchAck){\n this.batchBuffer.push(body)\n } else {\n this.currentBatch = [body]\n this.currentBatchTimer = setTimeout(() => {\n this.batchSend(this.currentBatch)\n this.currentBatch = null\n }, 0)\n }\n }\n\n batchSend(messages){\n this.awaitingBatchAck = true\n this.ajax(\"POST\", \"application/x-ndjson\", messages.join(\"\\n\"), () => this.onerror(\"timeout\"), resp => {\n this.awaitingBatchAck = false\n if(!resp || resp.status !== 200){\n this.onerror(resp && resp.status)\n this.closeAndRetry(1011, \"internal server error\", false)\n } else if(this.batchBuffer.length > 0){\n this.batchSend(this.batchBuffer)\n this.batchBuffer = []\n }\n })\n }\n\n close(code, reason, wasClean){\n for(let req of this.reqs){ req.abort() }\n this.readyState = SOCKET_STATES.closed\n let opts = Object.assign({code: 1000, reason: undefined, wasClean: true}, {code, reason, wasClean})\n this.batchBuffer = []\n clearTimeout(this.currentBatchTimer)\n this.currentBatchTimer = null\n if(typeof(CloseEvent) !== \"undefined\"){\n this.onclose(new CloseEvent(\"close\", opts))\n } else {\n this.onclose(opts)\n }\n }\n\n ajax(method, contentType, body, onCallerTimeout, callback){\n let req\n let ontimeout = () => {\n this.reqs.delete(req)\n onCallerTimeout()\n }\n req = Ajax.request(method, this.endpointURL(), contentType, body, this.timeout, ontimeout, resp => {\n this.reqs.delete(req)\n if(this.isActive()){ callback(resp) }\n })\n this.reqs.add(req)\n }\n}\n", "/**\n * Initializes the Presence\n * @param {Channel} channel - The Channel\n * @param {Object} opts - The options,\n * for example `{events: {state: \"state\", diff: \"diff\"}}`\n */\nexport default class Presence {\n\n constructor(channel, opts = {}){\n let events = opts.events || {state: \"presence_state\", diff: \"presence_diff\"}\n this.state = {}\n this.pendingDiffs = []\n this.channel = channel\n this.joinRef = null\n this.caller = {\n onJoin: function (){ },\n onLeave: function (){ },\n onSync: function (){ }\n }\n\n this.channel.on(events.state, newState => {\n let {onJoin, onLeave, onSync} = this.caller\n\n this.joinRef = this.channel.joinRef()\n this.state = Presence.syncState(this.state, newState, onJoin, onLeave)\n\n this.pendingDiffs.forEach(diff => {\n this.state = Presence.syncDiff(this.state, diff, onJoin, onLeave)\n })\n this.pendingDiffs = []\n onSync()\n })\n\n this.channel.on(events.diff, diff => {\n let {onJoin, onLeave, onSync} = this.caller\n\n if(this.inPendingSyncState()){\n this.pendingDiffs.push(diff)\n } else {\n this.state = Presence.syncDiff(this.state, diff, onJoin, onLeave)\n onSync()\n }\n })\n }\n\n onJoin(callback){ this.caller.onJoin = callback }\n\n onLeave(callback){ this.caller.onLeave = callback }\n\n onSync(callback){ this.caller.onSync = callback }\n\n list(by){ return Presence.list(this.state, by) }\n\n inPendingSyncState(){\n return !this.joinRef || (this.joinRef !== this.channel.joinRef())\n }\n\n // lower-level public static API\n\n /**\n * Used to sync the list of presences on the server\n * with the client's state. An optional `onJoin` and `onLeave` callback can\n * be provided to react to changes in the client's local presences across\n * disconnects and reconnects with the server.\n *\n * @returns {Presence}\n */\n static syncState(currentState, newState, onJoin, onLeave){\n let state = this.clone(currentState)\n let joins = {}\n let leaves = {}\n\n this.map(state, (key, presence) => {\n if(!newState[key]){\n leaves[key] = presence\n }\n })\n this.map(newState, (key, newPresence) => {\n let currentPresence = state[key]\n if(currentPresence){\n let newRefs = newPresence.metas.map(m => m.phx_ref)\n let curRefs = currentPresence.metas.map(m => m.phx_ref)\n let joinedMetas = newPresence.metas.filter(m => curRefs.indexOf(m.phx_ref) < 0)\n let leftMetas = currentPresence.metas.filter(m => newRefs.indexOf(m.phx_ref) < 0)\n if(joinedMetas.length > 0){\n joins[key] = newPresence\n joins[key].metas = joinedMetas\n }\n if(leftMetas.length > 0){\n leaves[key] = this.clone(currentPresence)\n leaves[key].metas = leftMetas\n }\n } else {\n joins[key] = newPresence\n }\n })\n return this.syncDiff(state, {joins: joins, leaves: leaves}, onJoin, onLeave)\n }\n\n /**\n *\n * Used to sync a diff of presence join and leave\n * events from the server, as they happen. Like `syncState`, `syncDiff`\n * accepts optional `onJoin` and `onLeave` callbacks to react to a user\n * joining or leaving from a device.\n *\n * @returns {Presence}\n */\n static syncDiff(state, diff, onJoin, onLeave){\n let {joins, leaves} = this.clone(diff)\n if(!onJoin){ onJoin = function (){ } }\n if(!onLeave){ onLeave = function (){ } }\n\n this.map(joins, (key, newPresence) => {\n let currentPresence = state[key]\n state[key] = this.clone(newPresence)\n if(currentPresence){\n let joinedRefs = state[key].metas.map(m => m.phx_ref)\n let curMetas = currentPresence.metas.filter(m => joinedRefs.indexOf(m.phx_ref) < 0)\n state[key].metas.unshift(...curMetas)\n }\n onJoin(key, currentPresence, newPresence)\n })\n this.map(leaves, (key, leftPresence) => {\n let currentPresence = state[key]\n if(!currentPresence){ return }\n let refsToRemove = leftPresence.metas.map(m => m.phx_ref)\n currentPresence.metas = currentPresence.metas.filter(p => {\n return refsToRemove.indexOf(p.phx_ref) < 0\n })\n onLeave(key, currentPresence, leftPresence)\n if(currentPresence.metas.length === 0){\n delete state[key]\n }\n })\n return state\n }\n\n /**\n * Returns the array of presences, with selected metadata.\n *\n * @param {Object} presences\n * @param {Function} chooser\n *\n * @returns {Presence}\n */\n static list(presences, chooser){\n if(!chooser){ chooser = function (key, pres){ return pres } }\n\n return this.map(presences, (key, presence) => {\n return chooser(key, presence)\n })\n }\n\n // private\n\n static map(obj, func){\n return Object.getOwnPropertyNames(obj).map(key => func(key, obj[key]))\n }\n\n static clone(obj){ return JSON.parse(JSON.stringify(obj)) }\n}\n", "/* The default serializer for encoding and decoding messages */\nimport {\n CHANNEL_EVENTS\n} from \"./constants\"\n\nexport default {\n HEADER_LENGTH: 1,\n META_LENGTH: 4,\n KINDS: {push: 0, reply: 1, broadcast: 2},\n\n encode(msg, callback){\n if(msg.payload.constructor === ArrayBuffer){\n return callback(this.binaryEncode(msg))\n } else {\n let payload = [msg.join_ref, msg.ref, msg.topic, msg.event, msg.payload]\n return callback(JSON.stringify(payload))\n }\n },\n\n decode(rawPayload, callback){\n if(rawPayload.constructor === ArrayBuffer){\n return callback(this.binaryDecode(rawPayload))\n } else {\n let [join_ref, ref, topic, event, payload] = JSON.parse(rawPayload)\n return callback({join_ref, ref, topic, event, payload})\n }\n },\n\n // private\n\n binaryEncode(message){\n let {join_ref, ref, event, topic, payload} = message\n let metaLength = this.META_LENGTH + join_ref.length + ref.length + topic.length + event.length\n let header = new ArrayBuffer(this.HEADER_LENGTH + metaLength)\n let view = new DataView(header)\n let offset = 0\n\n view.setUint8(offset++, this.KINDS.push) // kind\n view.setUint8(offset++, join_ref.length)\n view.setUint8(offset++, ref.length)\n view.setUint8(offset++, topic.length)\n view.setUint8(offset++, event.length)\n Array.from(join_ref, char => view.setUint8(offset++, char.charCodeAt(0)))\n Array.from(ref, char => view.setUint8(offset++, char.charCodeAt(0)))\n Array.from(topic, char => view.setUint8(offset++, char.charCodeAt(0)))\n Array.from(event, char => view.setUint8(offset++, char.charCodeAt(0)))\n\n var combined = new Uint8Array(header.byteLength + payload.byteLength)\n combined.set(new Uint8Array(header), 0)\n combined.set(new Uint8Array(payload), header.byteLength)\n\n return combined.buffer\n },\n\n binaryDecode(buffer){\n let view = new DataView(buffer)\n let kind = view.getUint8(0)\n let decoder = new TextDecoder()\n switch(kind){\n case this.KINDS.push: return this.decodePush(buffer, view, decoder)\n case this.KINDS.reply: return this.decodeReply(buffer, view, decoder)\n case this.KINDS.broadcast: return this.decodeBroadcast(buffer, view, decoder)\n }\n },\n\n decodePush(buffer, view, decoder){\n let joinRefSize = view.getUint8(1)\n let topicSize = view.getUint8(2)\n let eventSize = view.getUint8(3)\n let offset = this.HEADER_LENGTH + this.META_LENGTH - 1 // pushes have no ref\n let joinRef = decoder.decode(buffer.slice(offset, offset + joinRefSize))\n offset = offset + joinRefSize\n let topic = decoder.decode(buffer.slice(offset, offset + topicSize))\n offset = offset + topicSize\n let event = decoder.decode(buffer.slice(offset, offset + eventSize))\n offset = offset + eventSize\n let data = buffer.slice(offset, buffer.byteLength)\n return {join_ref: joinRef, ref: null, topic: topic, event: event, payload: data}\n },\n\n decodeReply(buffer, view, decoder){\n let joinRefSize = view.getUint8(1)\n let refSize = view.getUint8(2)\n let topicSize = view.getUint8(3)\n let eventSize = view.getUint8(4)\n let offset = this.HEADER_LENGTH + this.META_LENGTH\n let joinRef = decoder.decode(buffer.slice(offset, offset + joinRefSize))\n offset = offset + joinRefSize\n let ref = decoder.decode(buffer.slice(offset, offset + refSize))\n offset = offset + refSize\n let topic = decoder.decode(buffer.slice(offset, offset + topicSize))\n offset = offset + topicSize\n let event = decoder.decode(buffer.slice(offset, offset + eventSize))\n offset = offset + eventSize\n let data = buffer.slice(offset, buffer.byteLength)\n let payload = {status: event, response: data}\n return {join_ref: joinRef, ref: ref, topic: topic, event: CHANNEL_EVENTS.reply, payload: payload}\n },\n\n decodeBroadcast(buffer, view, decoder){\n let topicSize = view.getUint8(1)\n let eventSize = view.getUint8(2)\n let offset = this.HEADER_LENGTH + 2\n let topic = decoder.decode(buffer.slice(offset, offset + topicSize))\n offset = offset + topicSize\n let event = decoder.decode(buffer.slice(offset, offset + eventSize))\n offset = offset + eventSize\n let data = buffer.slice(offset, buffer.byteLength)\n\n return {join_ref: null, ref: null, topic: topic, event: event, payload: data}\n }\n}\n", "import {\n global,\n phxWindow,\n CHANNEL_EVENTS,\n DEFAULT_TIMEOUT,\n DEFAULT_VSN,\n SOCKET_STATES,\n TRANSPORTS,\n WS_CLOSE_NORMAL\n} from \"./constants\"\n\nimport {\n closure\n} from \"./utils\"\n\nimport Ajax from \"./ajax\"\nimport Channel from \"./channel\"\nimport LongPoll from \"./longpoll\"\nimport Serializer from \"./serializer\"\nimport Timer from \"./timer\"\n\n/** Initializes the Socket *\n *\n * For IE8 support use an ES5-shim (https://github.com/es-shims/es5-shim)\n *\n * @param {string} endPoint - The string WebSocket endpoint, ie, `\"ws://example.com/socket\"`,\n * `\"wss://example.com\"`\n * `\"/socket\"` (inherited host & protocol)\n * @param {Object} [opts] - Optional configuration\n * @param {Function} [opts.transport] - The Websocket Transport, for example WebSocket or Phoenix.LongPoll.\n *\n * Defaults to WebSocket with automatic LongPoll fallback if WebSocket is not defined.\n * To fallback to LongPoll when WebSocket attempts fail, use `longPollFallbackMs: 2500`.\n *\n * @param {Function} [opts.longPollFallbackMs] - The millisecond time to attempt the primary transport\n * before falling back to the LongPoll transport. Disabled by default.\n *\n * @param {Function} [opts.debug] - When true, enables debug logging. Default false.\n *\n * @param {Function} [opts.encode] - The function to encode outgoing messages.\n *\n * Defaults to JSON encoder.\n *\n * @param {Function} [opts.decode] - The function to decode incoming messages.\n *\n * Defaults to JSON:\n *\n * ```javascript\n * (payload, callback) => callback(JSON.parse(payload))\n * ```\n *\n * @param {number} [opts.timeout] - The default timeout in milliseconds to trigger push timeouts.\n *\n * Defaults `DEFAULT_TIMEOUT`\n * @param {number} [opts.heartbeatIntervalMs] - The millisec interval to send a heartbeat message\n * @param {number} [opts.reconnectAfterMs] - The optional function that returns the millisec\n * socket reconnect interval.\n *\n * Defaults to stepped backoff of:\n *\n * ```javascript\n * function(tries){\n * return [10, 50, 100, 150, 200, 250, 500, 1000, 2000][tries - 1] || 5000\n * }\n * ````\n *\n * @param {number} [opts.rejoinAfterMs] - The optional function that returns the millisec\n * rejoin interval for individual channels.\n *\n * ```javascript\n * function(tries){\n * return [1000, 2000, 5000][tries - 1] || 10000\n * }\n * ````\n *\n * @param {Function} [opts.logger] - The optional function for specialized logging, ie:\n *\n * ```javascript\n * function(kind, msg, data) {\n * console.log(`${kind}: ${msg}`, data)\n * }\n * ```\n *\n * @param {number} [opts.longpollerTimeout] - The maximum timeout of a long poll AJAX request.\n *\n * Defaults to 20s (double the server long poll timer).\n *\n * @param {(Object|function)} [opts.params] - The optional params to pass when connecting\n * @param {string} [opts.binaryType] - The binary type to use for binary WebSocket frames.\n *\n * Defaults to \"arraybuffer\"\n *\n * @param {vsn} [opts.vsn] - The serializer's protocol version to send on connect.\n *\n * Defaults to DEFAULT_VSN.\n *\n * @param {Object} [opts.sessionStorage] - An optional Storage compatible object\n * Phoenix uses sessionStorage for longpoll fallback history. Overriding the store is\n * useful when Phoenix won't have access to `sessionStorage`. For example, This could\n * happen if a site loads a cross-domain channel in an iframe. Example usage:\n *\n * class InMemoryStorage {\n * constructor() { this.storage = {} }\n * getItem(keyName) { return this.storage[keyName] || null }\n * removeItem(keyName) { delete this.storage[keyName] }\n * setItem(keyName, keyValue) { this.storage[keyName] = keyValue }\n * }\n *\n*/\nexport default class Socket {\n constructor(endPoint, opts = {}){\n this.stateChangeCallbacks = {open: [], close: [], error: [], message: []}\n this.channels = []\n this.sendBuffer = []\n this.ref = 0\n this.timeout = opts.timeout || DEFAULT_TIMEOUT\n this.transport = opts.transport || global.WebSocket || LongPoll\n this.primaryPassedHealthCheck = false\n this.longPollFallbackMs = opts.longPollFallbackMs\n this.fallbackTimer = null\n this.sessionStore = opts.sessionStorage || global.sessionStorage\n this.establishedConnections = 0\n this.defaultEncoder = Serializer.encode.bind(Serializer)\n this.defaultDecoder = Serializer.decode.bind(Serializer)\n this.closeWasClean = false\n this.binaryType = opts.binaryType || \"arraybuffer\"\n this.connectClock = 1\n if(this.transport !== LongPoll){\n this.encode = opts.encode || this.defaultEncoder\n this.decode = opts.decode || this.defaultDecoder\n } else {\n this.encode = this.defaultEncoder\n this.decode = this.defaultDecoder\n }\n let awaitingConnectionOnPageShow = null\n if(phxWindow && phxWindow.addEventListener){\n phxWindow.addEventListener(\"pagehide\", _e => {\n if(this.conn){\n this.disconnect()\n awaitingConnectionOnPageShow = this.connectClock\n }\n })\n phxWindow.addEventListener(\"pageshow\", _e => {\n if(awaitingConnectionOnPageShow === this.connectClock){\n awaitingConnectionOnPageShow = null\n this.connect()\n }\n })\n }\n this.heartbeatIntervalMs = opts.heartbeatIntervalMs || 30000\n this.rejoinAfterMs = (tries) => {\n if(opts.rejoinAfterMs){\n return opts.rejoinAfterMs(tries)\n } else {\n return [1000, 2000, 5000][tries - 1] || 10000\n }\n }\n this.reconnectAfterMs = (tries) => {\n if(opts.reconnectAfterMs){\n return opts.reconnectAfterMs(tries)\n } else {\n return [10, 50, 100, 150, 200, 250, 500, 1000, 2000][tries - 1] || 5000\n }\n }\n this.logger = opts.logger || null\n if(!this.logger && opts.debug){\n this.logger = (kind, msg, data) => { console.log(`${kind}: ${msg}`, data) }\n }\n this.longpollerTimeout = opts.longpollerTimeout || 20000\n this.params = closure(opts.params || {})\n this.endPoint = `${endPoint}/${TRANSPORTS.websocket}`\n this.vsn = opts.vsn || DEFAULT_VSN\n this.heartbeatTimeoutTimer = null\n this.heartbeatTimer = null\n this.pendingHeartbeatRef = null\n this.reconnectTimer = new Timer(() => {\n this.teardown(() => this.connect())\n }, this.reconnectAfterMs)\n }\n\n /**\n * Returns the LongPoll transport reference\n */\n getLongPollTransport(){ return LongPoll }\n\n /**\n * Disconnects and replaces the active transport\n *\n * @param {Function} newTransport - The new transport class to instantiate\n *\n */\n replaceTransport(newTransport){\n this.connectClock++\n this.closeWasClean = true\n clearTimeout(this.fallbackTimer)\n this.reconnectTimer.reset()\n if(this.conn){\n this.conn.close()\n this.conn = null\n }\n this.transport = newTransport\n }\n\n /**\n * Returns the socket protocol\n *\n * @returns {string}\n */\n protocol(){ return location.protocol.match(/^https/) ? \"wss\" : \"ws\" }\n\n /**\n * The fully qualified socket url\n *\n * @returns {string}\n */\n endPointURL(){\n let uri = Ajax.appendParams(\n Ajax.appendParams(this.endPoint, this.params()), {vsn: this.vsn})\n if(uri.charAt(0) !== \"/\"){ return uri }\n if(uri.charAt(1) === \"/\"){ return `${this.protocol()}:${uri}` }\n\n return `${this.protocol()}://${location.host}${uri}`\n }\n\n /**\n * Disconnects the socket\n *\n * See https://developer.mozilla.org/en-US/docs/Web/API/CloseEvent#Status_codes for valid status codes.\n *\n * @param {Function} callback - Optional callback which is called after socket is disconnected.\n * @param {integer} code - A status code for disconnection (Optional).\n * @param {string} reason - A textual description of the reason to disconnect. (Optional)\n */\n disconnect(callback, code, reason){\n this.connectClock++\n this.closeWasClean = true\n clearTimeout(this.fallbackTimer)\n this.reconnectTimer.reset()\n this.teardown(callback, code, reason)\n }\n\n /**\n *\n * @param {Object} params - The params to send when connecting, for example `{user_id: userToken}`\n *\n * Passing params to connect is deprecated; pass them in the Socket constructor instead:\n * `new Socket(\"/socket\", {params: {user_id: userToken}})`.\n */\n connect(params){\n if(params){\n console && console.log(\"passing params to connect is deprecated. Instead pass :params to the Socket constructor\")\n this.params = closure(params)\n }\n if(this.conn){ return }\n if(this.longPollFallbackMs && this.transport !== LongPoll){\n this.connectWithFallback(LongPoll, this.longPollFallbackMs)\n } else {\n this.transportConnect()\n }\n }\n\n /**\n * Logs the message. Override `this.logger` for specialized logging. noops by default\n * @param {string} kind\n * @param {string} msg\n * @param {Object} data\n */\n log(kind, msg, data){ this.logger && this.logger(kind, msg, data) }\n\n /**\n * Returns true if a logger has been set on this socket.\n */\n hasLogger(){ return this.logger !== null }\n\n /**\n * Registers callbacks for connection open events\n *\n * @example socket.onOpen(function(){ console.info(\"the socket was opened\") })\n *\n * @param {Function} callback\n */\n onOpen(callback){\n let ref = this.makeRef()\n this.stateChangeCallbacks.open.push([ref, callback])\n return ref\n }\n\n /**\n * Registers callbacks for connection close events\n * @param {Function} callback\n */\n onClose(callback){\n let ref = this.makeRef()\n this.stateChangeCallbacks.close.push([ref, callback])\n return ref\n }\n\n /**\n * Registers callbacks for connection error events\n *\n * @example socket.onError(function(error){ alert(\"An error occurred\") })\n *\n * @param {Function} callback\n */\n onError(callback){\n let ref = this.makeRef()\n this.stateChangeCallbacks.error.push([ref, callback])\n return ref\n }\n\n /**\n * Registers callbacks for connection message events\n * @param {Function} callback\n */\n onMessage(callback){\n let ref = this.makeRef()\n this.stateChangeCallbacks.message.push([ref, callback])\n return ref\n }\n\n /**\n * Pings the server and invokes the callback with the RTT in milliseconds\n * @param {Function} callback\n *\n * Returns true if the ping was pushed or false if unable to be pushed.\n */\n ping(callback){\n if(!this.isConnected()){ return false }\n let ref = this.makeRef()\n let startTime = Date.now()\n this.push({topic: \"phoenix\", event: \"heartbeat\", payload: {}, ref: ref})\n let onMsgRef = this.onMessage(msg => {\n if(msg.ref === ref){\n this.off([onMsgRef])\n callback(Date.now() - startTime)\n }\n })\n return true\n }\n\n /**\n * @private\n */\n\n transportConnect(){\n this.connectClock++\n this.closeWasClean = false\n this.conn = new this.transport(this.endPointURL())\n this.conn.binaryType = this.binaryType\n this.conn.timeout = this.longpollerTimeout\n this.conn.onopen = () => this.onConnOpen()\n this.conn.onerror = error => this.onConnError(error)\n this.conn.onmessage = event => this.onConnMessage(event)\n this.conn.onclose = event => this.onConnClose(event)\n }\n\n getSession(key){ return this.sessionStore && this.sessionStore.getItem(key) }\n\n storeSession(key, val){ this.sessionStore && this.sessionStore.setItem(key, val) }\n\n connectWithFallback(fallbackTransport, fallbackThreshold = 2500){\n clearTimeout(this.fallbackTimer)\n let established = false\n let primaryTransport = true\n let openRef, errorRef\n let fallback = (reason) => {\n this.log(\"transport\", `falling back to ${fallbackTransport.name}...`, reason)\n this.off([openRef, errorRef])\n primaryTransport = false\n this.replaceTransport(fallbackTransport)\n this.transportConnect()\n }\n if(this.getSession(`phx:fallback:${fallbackTransport.name}`)){ return fallback(\"memorized\") }\n\n this.fallbackTimer = setTimeout(fallback, fallbackThreshold)\n\n errorRef = this.onError(reason => {\n this.log(\"transport\", \"error\", reason)\n if(primaryTransport && !established) {\n clearTimeout(this.fallbackTimer)\n fallback(reason)\n }\n })\n this.onOpen(() => {\n established = true\n if(!primaryTransport){\n // only memorize LP if we never connected to primary\n if(!this.primaryPassedHealthCheck){ this.storeSession(`phx:fallback:${fallbackTransport.name}`, \"true\") }\n return this.log(\"transport\", `established ${fallbackTransport.name} fallback`)\n }\n // if we've established primary, give the fallback a new period to attempt ping\n clearTimeout(this.fallbackTimer)\n this.fallbackTimer = setTimeout(fallback, fallbackThreshold)\n this.ping(rtt => {\n this.log(\"transport\", \"connected to primary after\", rtt)\n this.primaryPassedHealthCheck = true\n clearTimeout(this.fallbackTimer)\n })\n })\n this.transportConnect()\n }\n\n clearHeartbeats(){\n clearTimeout(this.heartbeatTimer)\n clearTimeout(this.heartbeatTimeoutTimer)\n }\n\n onConnOpen(){\n if(this.hasLogger()) this.log(\"transport\", `${this.transport.name} connected to ${this.endPointURL()}`)\n this.closeWasClean = false\n this.establishedConnections++\n this.flushSendBuffer()\n this.reconnectTimer.reset()\n this.resetHeartbeat()\n this.stateChangeCallbacks.open.forEach(([, callback]) => callback())\n }\n\n /**\n * @private\n */\n\n heartbeatTimeout(){\n if(this.pendingHeartbeatRef){\n this.pendingHeartbeatRef = null\n if(this.hasLogger()){ this.log(\"transport\", \"heartbeat timeout. Attempting to re-establish connection\") }\n this.triggerChanError()\n this.closeWasClean = false\n this.teardown(() => this.reconnectTimer.scheduleTimeout(), WS_CLOSE_NORMAL, \"heartbeat timeout\")\n }\n }\n\n resetHeartbeat(){\n if(this.conn && this.conn.skipHeartbeat){ return }\n this.pendingHeartbeatRef = null\n this.clearHeartbeats()\n this.heartbeatTimer = setTimeout(() => this.sendHeartbeat(), this.heartbeatIntervalMs)\n }\n\n teardown(callback, code, reason){\n if(!this.conn){\n return callback && callback()\n }\n\n this.waitForBufferDone(() => {\n if(this.conn){\n if(code){ this.conn.close(code, reason || \"\") } else { this.conn.close() }\n }\n\n this.waitForSocketClosed(() => {\n if(this.conn){\n this.conn.onopen = function (){ } // noop\n this.conn.onerror = function (){ } // noop\n this.conn.onmessage = function (){ } // noop\n this.conn.onclose = function (){ } // noop\n this.conn = null\n }\n\n callback && callback()\n })\n })\n }\n\n waitForBufferDone(callback, tries = 1){\n if(tries === 5 || !this.conn || !this.conn.bufferedAmount){\n callback()\n return\n }\n\n setTimeout(() => {\n this.waitForBufferDone(callback, tries + 1)\n }, 150 * tries)\n }\n\n waitForSocketClosed(callback, tries = 1){\n if(tries === 5 || !this.conn || this.conn.readyState === SOCKET_STATES.closed){\n callback()\n return\n }\n\n setTimeout(() => {\n this.waitForSocketClosed(callback, tries + 1)\n }, 150 * tries)\n }\n\n onConnClose(event){\n let closeCode = event && event.code\n if(this.hasLogger()) this.log(\"transport\", \"close\", event)\n this.triggerChanError()\n this.clearHeartbeats()\n if(!this.closeWasClean && closeCode !== 1000){\n this.reconnectTimer.scheduleTimeout()\n }\n this.stateChangeCallbacks.close.forEach(([, callback]) => callback(event))\n }\n\n /**\n * @private\n */\n onConnError(error){\n if(this.hasLogger()) this.log(\"transport\", error)\n let transportBefore = this.transport\n let establishedBefore = this.establishedConnections\n this.stateChangeCallbacks.error.forEach(([, callback]) => {\n callback(error, transportBefore, establishedBefore)\n })\n if(transportBefore === this.transport || establishedBefore > 0){\n this.triggerChanError()\n }\n }\n\n /**\n * @private\n */\n triggerChanError(){\n this.channels.forEach(channel => {\n if(!(channel.isErrored() || channel.isLeaving() || channel.isClosed())){\n channel.trigger(CHANNEL_EVENTS.error)\n }\n })\n }\n\n /**\n * @returns {string}\n */\n connectionState(){\n switch(this.conn && this.conn.readyState){\n case SOCKET_STATES.connecting: return \"connecting\"\n case SOCKET_STATES.open: return \"open\"\n case SOCKET_STATES.closing: return \"closing\"\n default: return \"closed\"\n }\n }\n\n /**\n * @returns {boolean}\n */\n isConnected(){ return this.connectionState() === \"open\" }\n\n /**\n * @private\n *\n * @param {Channel}\n */\n remove(channel){\n this.off(channel.stateChangeRefs)\n this.channels = this.channels.filter(c => c !== channel)\n }\n\n /**\n * Removes `onOpen`, `onClose`, `onError,` and `onMessage` registrations.\n *\n * @param {refs} - list of refs returned by calls to\n * `onOpen`, `onClose`, `onError,` and `onMessage`\n */\n off(refs){\n for(let key in this.stateChangeCallbacks){\n this.stateChangeCallbacks[key] = this.stateChangeCallbacks[key].filter(([ref]) => {\n return refs.indexOf(ref) === -1\n })\n }\n }\n\n /**\n * Initiates a new channel for the given topic\n *\n * @param {string} topic\n * @param {Object} chanParams - Parameters for the channel\n * @returns {Channel}\n */\n channel(topic, chanParams = {}){\n let chan = new Channel(topic, chanParams, this)\n this.channels.push(chan)\n return chan\n }\n\n /**\n * @param {Object} data\n */\n push(data){\n if(this.hasLogger()){\n let {topic, event, payload, ref, join_ref} = data\n this.log(\"push\", `${topic} ${event} (${join_ref}, ${ref})`, payload)\n }\n\n if(this.isConnected()){\n this.encode(data, result => this.conn.send(result))\n } else {\n this.sendBuffer.push(() => this.encode(data, result => this.conn.send(result)))\n }\n }\n\n /**\n * Return the next message ref, accounting for overflows\n * @returns {string}\n */\n makeRef(){\n let newRef = this.ref + 1\n if(newRef === this.ref){ this.ref = 0 } else { this.ref = newRef }\n\n return this.ref.toString()\n }\n\n sendHeartbeat(){\n if(this.pendingHeartbeatRef && !this.isConnected()){ return }\n this.pendingHeartbeatRef = this.makeRef()\n this.push({topic: \"phoenix\", event: \"heartbeat\", payload: {}, ref: this.pendingHeartbeatRef})\n this.heartbeatTimeoutTimer = setTimeout(() => this.heartbeatTimeout(), this.heartbeatIntervalMs)\n }\n\n flushSendBuffer(){\n if(this.isConnected() && this.sendBuffer.length > 0){\n this.sendBuffer.forEach(callback => callback())\n this.sendBuffer = []\n }\n }\n\n onConnMessage(rawMessage){\n this.decode(rawMessage.data, msg => {\n let {topic, event, payload, ref, join_ref} = msg\n if(ref && ref === this.pendingHeartbeatRef){\n this.clearHeartbeats()\n this.pendingHeartbeatRef = null\n this.heartbeatTimer = setTimeout(() => this.sendHeartbeat(), this.heartbeatIntervalMs)\n }\n\n if(this.hasLogger()) this.log(\"receive\", `${payload.status || \"\"} ${topic} ${event} ${ref && \"(\" + ref + \")\" || \"\"}`, payload)\n\n for(let i = 0; i < this.channels.length; i++){\n const channel = this.channels[i]\n if(!channel.isMember(topic, event, payload, join_ref)){ continue }\n channel.trigger(event, payload, ref, join_ref)\n }\n\n for(let i = 0; i < this.stateChangeCallbacks.message.length; i++){\n let [, callback] = this.stateChangeCallbacks.message[i]\n callback(msg)\n }\n })\n }\n\n leaveOpenTopic(topic){\n let dupChannel = this.channels.find(c => c.topic === topic && (c.isJoined() || c.isJoining()))\n if(dupChannel){\n if(this.hasLogger()) this.log(\"transport\", `leaving duplicate topic \"${topic}\"`)\n dupChannel.leave()\n }\n }\n}\n"], + "mappings": ";AACO,IAAI,UAAU,CAAC,UAAU;AAC9B,MAAG,OAAO,UAAU,YAAW;AAC7B,WAAO;AAAA,EACT,OAAO;AACL,QAAIA,WAAU,WAAW;AAAE,aAAO;AAAA,IAAM;AACxC,WAAOA;AAAA,EACT;AACF;;;ACRO,IAAM,aAAa,OAAO,SAAS,cAAc,OAAO;AACxD,IAAM,YAAY,OAAO,WAAW,cAAc,SAAS;AAC3D,IAAM,SAAS,cAAc,aAAa;AAC1C,IAAM,cAAc;AACpB,IAAM,gBAAgB,EAAC,YAAY,GAAG,MAAM,GAAG,SAAS,GAAG,QAAQ,EAAC;AACpE,IAAM,kBAAkB;AACxB,IAAM,kBAAkB;AACxB,IAAM,iBAAiB;AAAA,EAC5B,QAAQ;AAAA,EACR,SAAS;AAAA,EACT,QAAQ;AAAA,EACR,SAAS;AAAA,EACT,SAAS;AACX;AACO,IAAM,iBAAiB;AAAA,EAC5B,OAAO;AAAA,EACP,OAAO;AAAA,EACP,MAAM;AAAA,EACN,OAAO;AAAA,EACP,OAAO;AACT;AAEO,IAAM,aAAa;AAAA,EACxB,UAAU;AAAA,EACV,WAAW;AACb;AACO,IAAM,aAAa;AAAA,EACxB,UAAU;AACZ;;;ACrBA,IAAqB,OAArB,MAA0B;AAAA,EACxB,YAAY,SAAS,OAAO,SAAS,SAAQ;AAC3C,SAAK,UAAU;AACf,SAAK,QAAQ;AACb,SAAK,UAAU,WAAW,WAAW;AAAE,aAAO,CAAC;AAAA,IAAE;AACjD,SAAK,eAAe;AACpB,SAAK,UAAU;AACf,SAAK,eAAe;AACpB,SAAK,WAAW,CAAC;AACjB,SAAK,OAAO;AAAA,EACd;AAAA;AAAA;AAAA;AAAA;AAAA,EAMA,OAAO,SAAQ;AACb,SAAK,UAAU;AACf,SAAK,MAAM;AACX,SAAK,KAAK;AAAA,EACZ;AAAA;AAAA;AAAA;AAAA,EAKA,OAAM;AACJ,QAAG,KAAK,YAAY,SAAS,GAAE;AAAE;AAAA,IAAO;AACxC,SAAK,aAAa;AAClB,SAAK,OAAO;AACZ,SAAK,QAAQ,OAAO,KAAK;AAAA,MACvB,OAAO,KAAK,QAAQ;AAAA,MACpB,OAAO,KAAK;AAAA,MACZ,SAAS,KAAK,QAAQ;AAAA,MACtB,KAAK,KAAK;AAAA,MACV,UAAU,KAAK,QAAQ,QAAQ;AAAA,IACjC,CAAC;AAAA,EACH;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAOA,QAAQ,QAAQ,UAAS;AACvB,QAAG,KAAK,YAAY,MAAM,GAAE;AAC1B,eAAS,KAAK,aAAa,QAAQ;AAAA,IACrC;AAEA,SAAK,SAAS,KAAK,EAAC,QAAQ,SAAQ,CAAC;AACrC,WAAO;AAAA,EACT;AAAA;AAAA;AAAA;AAAA,EAKA,QAAO;AACL,SAAK,eAAe;AACpB,SAAK,MAAM;AACX,SAAK,WAAW;AAChB,SAAK,eAAe;AACpB,SAAK,OAAO;AAAA,EACd;AAAA;AAAA;AAAA;AAAA,EAKA,aAAa,EAAC,QAAQ,UAAU,KAAI,GAAE;AACpC,SAAK,SAAS,OAAO,OAAK,EAAE,WAAW,MAAM,EAC1C,QAAQ,OAAK,EAAE,SAAS,QAAQ,CAAC;AAAA,EACtC;AAAA;AAAA;AAAA;AAAA,EAKA,iBAAgB;AACd,QAAG,CAAC,KAAK,UAAS;AAAE;AAAA,IAAO;AAC3B,SAAK,QAAQ,IAAI,KAAK,QAAQ;AAAA,EAChC;AAAA;AAAA;AAAA;AAAA,EAKA,gBAAe;AACb,iBAAa,KAAK,YAAY;AAC9B,SAAK,eAAe;AAAA,EACtB;AAAA;AAAA;AAAA;AAAA,EAKA,eAAc;AACZ,QAAG,KAAK,cAAa;AAAE,WAAK,cAAc;AAAA,IAAE;AAC5C,SAAK,MAAM,KAAK,QAAQ,OAAO,QAAQ;AACvC,SAAK,WAAW,KAAK,QAAQ,eAAe,KAAK,GAAG;AAEpD,SAAK,QAAQ,GAAG,KAAK,UAAU,aAAW;AACxC,WAAK,eAAe;AACpB,WAAK,cAAc;AACnB,WAAK,eAAe;AACpB,WAAK,aAAa,OAAO;AAAA,IAC3B,CAAC;AAED,SAAK,eAAe,WAAW,MAAM;AACnC,WAAK,QAAQ,WAAW,CAAC,CAAC;AAAA,IAC5B,GAAG,KAAK,OAAO;AAAA,EACjB;AAAA;AAAA;AAAA;AAAA,EAKA,YAAY,QAAO;AACjB,WAAO,KAAK,gBAAgB,KAAK,aAAa,WAAW;AAAA,EAC3D;AAAA;AAAA;AAAA;AAAA,EAKA,QAAQ,QAAQ,UAAS;AACvB,SAAK,QAAQ,QAAQ,KAAK,UAAU,EAAC,QAAQ,SAAQ,CAAC;AAAA,EACxD;AACF;;;AC9GA,IAAqB,QAArB,MAA2B;AAAA,EACzB,YAAY,UAAU,WAAU;AAC9B,SAAK,WAAW;AAChB,SAAK,YAAY;AACjB,SAAK,QAAQ;AACb,SAAK,QAAQ;AAAA,EACf;AAAA,EAEA,QAAO;AACL,SAAK,QAAQ;AACb,iBAAa,KAAK,KAAK;AAAA,EACzB;AAAA;AAAA;AAAA;AAAA,EAKA,kBAAiB;AACf,iBAAa,KAAK,KAAK;AAEvB,SAAK,QAAQ,WAAW,MAAM;AAC5B,WAAK,QAAQ,KAAK,QAAQ;AAC1B,WAAK,SAAS;AAAA,IAChB,GAAG,KAAK,UAAU,KAAK,QAAQ,CAAC,CAAC;AAAA,EACnC;AACF;;;AC1BA,IAAqB,UAArB,MAA6B;AAAA,EAC3B,YAAY,OAAO,QAAQ,QAAO;AAChC,SAAK,QAAQ,eAAe;AAC5B,SAAK,QAAQ;AACb,SAAK,SAAS,QAAQ,UAAU,CAAC,CAAC;AAClC,SAAK,SAAS;AACd,SAAK,WAAW,CAAC;AACjB,SAAK,aAAa;AAClB,SAAK,UAAU,KAAK,OAAO;AAC3B,SAAK,aAAa;AAClB,SAAK,WAAW,IAAI,KAAK,MAAM,eAAe,MAAM,KAAK,QAAQ,KAAK,OAAO;AAC7E,SAAK,aAAa,CAAC;AACnB,SAAK,kBAAkB,CAAC;AAExB,SAAK,cAAc,IAAI,MAAM,MAAM;AACjC,UAAG,KAAK,OAAO,YAAY,GAAE;AAAE,aAAK,OAAO;AAAA,MAAE;AAAA,IAC/C,GAAG,KAAK,OAAO,aAAa;AAC5B,SAAK,gBAAgB,KAAK,KAAK,OAAO,QAAQ,MAAM,KAAK,YAAY,MAAM,CAAC,CAAC;AAC7E,SAAK,gBAAgB;AAAA,MAAK,KAAK,OAAO,OAAO,MAAM;AACjD,aAAK,YAAY,MAAM;AACvB,YAAG,KAAK,UAAU,GAAE;AAAE,eAAK,OAAO;AAAA,QAAE;AAAA,MACtC,CAAC;AAAA,IACD;AACA,SAAK,SAAS,QAAQ,MAAM,MAAM;AAChC,WAAK,QAAQ,eAAe;AAC5B,WAAK,YAAY,MAAM;AACvB,WAAK,WAAW,QAAQ,eAAa,UAAU,KAAK,CAAC;AACrD,WAAK,aAAa,CAAC;AAAA,IACrB,CAAC;AACD,SAAK,SAAS,QAAQ,SAAS,MAAM;AACnC,WAAK,QAAQ,eAAe;AAC5B,UAAG,KAAK,OAAO,YAAY,GAAE;AAAE,aAAK,YAAY,gBAAgB;AAAA,MAAE;AAAA,IACpE,CAAC;AACD,SAAK,QAAQ,MAAM;AACjB,WAAK,YAAY,MAAM;AACvB,UAAG,KAAK,OAAO,UAAU;AAAG,aAAK,OAAO,IAAI,WAAW,SAAS,KAAK,SAAS,KAAK,QAAQ,GAAG;AAC9F,WAAK,QAAQ,eAAe;AAC5B,WAAK,OAAO,OAAO,IAAI;AAAA,IACzB,CAAC;AACD,SAAK,QAAQ,YAAU;AACrB,UAAG,KAAK,OAAO,UAAU;AAAG,aAAK,OAAO,IAAI,WAAW,SAAS,KAAK,SAAS,MAAM;AACpF,UAAG,KAAK,UAAU,GAAE;AAAE,aAAK,SAAS,MAAM;AAAA,MAAE;AAC5C,WAAK,QAAQ,eAAe;AAC5B,UAAG,KAAK,OAAO,YAAY,GAAE;AAAE,aAAK,YAAY,gBAAgB;AAAA,MAAE;AAAA,IACpE,CAAC;AACD,SAAK,SAAS,QAAQ,WAAW,MAAM;AACrC,UAAG,KAAK,OAAO,UAAU;AAAG,aAAK,OAAO,IAAI,WAAW,WAAW,KAAK,UAAU,KAAK,QAAQ,MAAM,KAAK,SAAS,OAAO;AACzH,UAAI,YAAY,IAAI,KAAK,MAAM,eAAe,OAAO,QAAQ,CAAC,CAAC,GAAG,KAAK,OAAO;AAC9E,gBAAU,KAAK;AACf,WAAK,QAAQ,eAAe;AAC5B,WAAK,SAAS,MAAM;AACpB,UAAG,KAAK,OAAO,YAAY,GAAE;AAAE,aAAK,YAAY,gBAAgB;AAAA,MAAE;AAAA,IACpE,CAAC;AACD,SAAK,GAAG,eAAe,OAAO,CAAC,SAAS,QAAQ;AAC9C,WAAK,QAAQ,KAAK,eAAe,GAAG,GAAG,OAAO;AAAA,IAChD,CAAC;AAAA,EACH;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAOA,KAAK,UAAU,KAAK,SAAQ;AAC1B,QAAG,KAAK,YAAW;AACjB,YAAM,IAAI,MAAM,4FAA4F;AAAA,IAC9G,OAAO;AACL,WAAK,UAAU;AACf,WAAK,aAAa;AAClB,WAAK,OAAO;AACZ,aAAO,KAAK;AAAA,IACd;AAAA,EACF;AAAA;AAAA;AAAA;AAAA;AAAA,EAMA,QAAQ,UAAS;AACf,SAAK,GAAG,eAAe,OAAO,QAAQ;AAAA,EACxC;AAAA;AAAA;AAAA;AAAA;AAAA,EAMA,QAAQ,UAAS;AACf,WAAO,KAAK,GAAG,eAAe,OAAO,YAAU,SAAS,MAAM,CAAC;AAAA,EACjE;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAmBA,GAAG,OAAO,UAAS;AACjB,QAAI,MAAM,KAAK;AACf,SAAK,SAAS,KAAK,EAAC,OAAO,KAAK,SAAQ,CAAC;AACzC,WAAO;AAAA,EACT;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAoBA,IAAI,OAAO,KAAI;AACb,SAAK,WAAW,KAAK,SAAS,OAAO,CAAC,SAAS;AAC7C,aAAO,EAAE,KAAK,UAAU,UAAU,OAAO,QAAQ,eAAe,QAAQ,KAAK;AAAA,IAC/E,CAAC;AAAA,EACH;AAAA;AAAA;AAAA;AAAA,EAKA,UAAS;AAAE,WAAO,KAAK,OAAO,YAAY,KAAK,KAAK,SAAS;AAAA,EAAE;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAkB/D,KAAK,OAAO,SAAS,UAAU,KAAK,SAAQ;AAC1C,cAAU,WAAW,CAAC;AACtB,QAAG,CAAC,KAAK,YAAW;AAClB,YAAM,IAAI,MAAM,kBAAkB,cAAc,KAAK,iEAAiE;AAAA,IACxH;AACA,QAAI,YAAY,IAAI,KAAK,MAAM,OAAO,WAAW;AAAE,aAAO;AAAA,IAAQ,GAAG,OAAO;AAC5E,QAAG,KAAK,QAAQ,GAAE;AAChB,gBAAU,KAAK;AAAA,IACjB,OAAO;AACL,gBAAU,aAAa;AACvB,WAAK,WAAW,KAAK,SAAS;AAAA,IAChC;AAEA,WAAO;AAAA,EACT;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAkBA,MAAM,UAAU,KAAK,SAAQ;AAC3B,SAAK,YAAY,MAAM;AACvB,SAAK,SAAS,cAAc;AAE5B,SAAK,QAAQ,eAAe;AAC5B,QAAI,UAAU,MAAM;AAClB,UAAG,KAAK,OAAO,UAAU;AAAG,aAAK,OAAO,IAAI,WAAW,SAAS,KAAK,OAAO;AAC5E,WAAK,QAAQ,eAAe,OAAO,OAAO;AAAA,IAC5C;AACA,QAAI,YAAY,IAAI,KAAK,MAAM,eAAe,OAAO,QAAQ,CAAC,CAAC,GAAG,OAAO;AACzE,cAAU,QAAQ,MAAM,MAAM,QAAQ,CAAC,EACpC,QAAQ,WAAW,MAAM,QAAQ,CAAC;AACrC,cAAU,KAAK;AACf,QAAG,CAAC,KAAK,QAAQ,GAAE;AAAE,gBAAU,QAAQ,MAAM,CAAC,CAAC;AAAA,IAAE;AAEjD,WAAO;AAAA,EACT;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAcA,UAAU,QAAQ,SAAS,MAAK;AAAE,WAAO;AAAA,EAAQ;AAAA;AAAA;AAAA;AAAA,EAKjD,SAAS,OAAO,OAAO,SAAS,SAAQ;AACtC,QAAG,KAAK,UAAU,OAAM;AAAE,aAAO;AAAA,IAAM;AAEvC,QAAG,WAAW,YAAY,KAAK,QAAQ,GAAE;AACvC,UAAG,KAAK,OAAO,UAAU;AAAG,aAAK,OAAO,IAAI,WAAW,6BAA6B,EAAC,OAAO,OAAO,SAAS,QAAO,CAAC;AACpH,aAAO;AAAA,IACT,OAAO;AACL,aAAO;AAAA,IACT;AAAA,EACF;AAAA;AAAA;AAAA;AAAA,EAKA,UAAS;AAAE,WAAO,KAAK,SAAS;AAAA,EAAI;AAAA;AAAA;AAAA;AAAA,EAKpC,OAAO,UAAU,KAAK,SAAQ;AAC5B,QAAG,KAAK,UAAU,GAAE;AAAE;AAAA,IAAO;AAC7B,SAAK,OAAO,eAAe,KAAK,KAAK;AACrC,SAAK,QAAQ,eAAe;AAC5B,SAAK,SAAS,OAAO,OAAO;AAAA,EAC9B;AAAA;AAAA;AAAA;AAAA,EAKA,QAAQ,OAAO,SAAS,KAAK,SAAQ;AACnC,QAAI,iBAAiB,KAAK,UAAU,OAAO,SAAS,KAAK,OAAO;AAChE,QAAG,WAAW,CAAC,gBAAe;AAAE,YAAM,IAAI,MAAM,6EAA6E;AAAA,IAAE;AAE/H,QAAI,gBAAgB,KAAK,SAAS,OAAO,UAAQ,KAAK,UAAU,KAAK;AAErE,aAAQ,IAAI,GAAG,IAAI,cAAc,QAAQ,KAAI;AAC3C,UAAI,OAAO,cAAc,CAAC;AAC1B,WAAK,SAAS,gBAAgB,KAAK,WAAW,KAAK,QAAQ,CAAC;AAAA,IAC9D;AAAA,EACF;AAAA;AAAA;AAAA;AAAA,EAKA,eAAe,KAAI;AAAE,WAAO,cAAc;AAAA,EAAM;AAAA;AAAA;AAAA;AAAA,EAKhD,WAAU;AAAE,WAAO,KAAK,UAAU,eAAe;AAAA,EAAO;AAAA;AAAA;AAAA;AAAA,EAKxD,YAAW;AAAE,WAAO,KAAK,UAAU,eAAe;AAAA,EAAQ;AAAA;AAAA;AAAA;AAAA,EAK1D,WAAU;AAAE,WAAO,KAAK,UAAU,eAAe;AAAA,EAAO;AAAA;AAAA;AAAA;AAAA,EAKxD,YAAW;AAAE,WAAO,KAAK,UAAU,eAAe;AAAA,EAAQ;AAAA;AAAA;AAAA;AAAA,EAK1D,YAAW;AAAE,WAAO,KAAK,UAAU,eAAe;AAAA,EAAQ;AAC5D;;;ACjTA,IAAqB,OAArB,MAA0B;AAAA,EAExB,OAAO,QAAQ,QAAQ,UAAU,QAAQ,MAAM,SAAS,WAAW,UAAS;AAC1E,QAAG,OAAO,gBAAe;AACvB,UAAI,MAAM,IAAI,OAAO,eAAe;AACpC,aAAO,KAAK,eAAe,KAAK,QAAQ,UAAU,MAAM,SAAS,WAAW,QAAQ;AAAA,IACtF,OAAO;AACL,UAAI,MAAM,IAAI,OAAO,eAAe;AACpC,aAAO,KAAK,WAAW,KAAK,QAAQ,UAAU,QAAQ,MAAM,SAAS,WAAW,QAAQ;AAAA,IAC1F;AAAA,EACF;AAAA,EAEA,OAAO,eAAe,KAAK,QAAQ,UAAU,MAAM,SAAS,WAAW,UAAS;AAC9E,QAAI,UAAU;AACd,QAAI,KAAK,QAAQ,QAAQ;AACzB,QAAI,SAAS,MAAM;AACjB,UAAI,WAAW,KAAK,UAAU,IAAI,YAAY;AAC9C,kBAAY,SAAS,QAAQ;AAAA,IAC/B;AACA,QAAG,WAAU;AAAE,UAAI,YAAY;AAAA,IAAU;AAGzC,QAAI,aAAa,MAAM;AAAA,IAAE;AAEzB,QAAI,KAAK,IAAI;AACb,WAAO;AAAA,EACT;AAAA,EAEA,OAAO,WAAW,KAAK,QAAQ,UAAU,QAAQ,MAAM,SAAS,WAAW,UAAS;AAClF,QAAI,KAAK,QAAQ,UAAU,IAAI;AAC/B,QAAI,UAAU;AACd,QAAI,iBAAiB,gBAAgB,MAAM;AAC3C,QAAI,UAAU,MAAM,YAAY,SAAS,IAAI;AAC7C,QAAI,qBAAqB,MAAM;AAC7B,UAAG,IAAI,eAAe,WAAW,YAAY,UAAS;AACpD,YAAI,WAAW,KAAK,UAAU,IAAI,YAAY;AAC9C,iBAAS,QAAQ;AAAA,MACnB;AAAA,IACF;AACA,QAAG,WAAU;AAAE,UAAI,YAAY;AAAA,IAAU;AAEzC,QAAI,KAAK,IAAI;AACb,WAAO;AAAA,EACT;AAAA,EAEA,OAAO,UAAU,MAAK;AACpB,QAAG,CAAC,QAAQ,SAAS,IAAG;AAAE,aAAO;AAAA,IAAK;AAEtC,QAAI;AACF,aAAO,KAAK,MAAM,IAAI;AAAA,IACxB,SAAS,GAAP;AACA,iBAAW,QAAQ,IAAI,iCAAiC,IAAI;AAC5D,aAAO;AAAA,IACT;AAAA,EACF;AAAA,EAEA,OAAO,UAAU,KAAK,WAAU;AAC9B,QAAI,WAAW,CAAC;AAChB,aAAQ,OAAO,KAAI;AACjB,UAAG,CAAC,OAAO,UAAU,eAAe,KAAK,KAAK,GAAG,GAAE;AAAE;AAAA,MAAS;AAC9D,UAAI,WAAW,YAAY,GAAG,aAAa,SAAS;AACpD,UAAI,WAAW,IAAI,GAAG;AACtB,UAAG,OAAO,aAAa,UAAS;AAC9B,iBAAS,KAAK,KAAK,UAAU,UAAU,QAAQ,CAAC;AAAA,MAClD,OAAO;AACL,iBAAS,KAAK,mBAAmB,QAAQ,IAAI,MAAM,mBAAmB,QAAQ,CAAC;AAAA,MACjF;AAAA,IACF;AACA,WAAO,SAAS,KAAK,GAAG;AAAA,EAC1B;AAAA,EAEA,OAAO,aAAa,KAAK,QAAO;AAC9B,QAAG,OAAO,KAAK,MAAM,EAAE,WAAW,GAAE;AAAE,aAAO;AAAA,IAAI;AAEjD,QAAI,SAAS,IAAI,MAAM,IAAI,IAAI,MAAM;AACrC,WAAO,GAAG,MAAM,SAAS,KAAK,UAAU,MAAM;AAAA,EAChD;AACF;;;AC3EA,IAAI,sBAAsB,CAAC,WAAW;AACpC,MAAI,SAAS;AACb,MAAI,QAAQ,IAAI,WAAW,MAAM;AACjC,MAAI,MAAM,MAAM;AAChB,WAAQ,IAAI,GAAG,IAAI,KAAK,KAAI;AAAE,cAAU,OAAO,aAAa,MAAM,CAAC,CAAC;AAAA,EAAE;AACtE,SAAO,KAAK,MAAM;AACpB;AAEA,IAAqB,WAArB,MAA8B;AAAA,EAE5B,YAAY,UAAS;AACnB,SAAK,WAAW;AAChB,SAAK,QAAQ;AACb,SAAK,gBAAgB;AACrB,SAAK,OAAO,oBAAI,IAAI;AACpB,SAAK,mBAAmB;AACxB,SAAK,eAAe;AACpB,SAAK,oBAAoB;AACzB,SAAK,cAAc,CAAC;AACpB,SAAK,SAAS,WAAW;AAAA,IAAE;AAC3B,SAAK,UAAU,WAAW;AAAA,IAAE;AAC5B,SAAK,YAAY,WAAW;AAAA,IAAE;AAC9B,SAAK,UAAU,WAAW;AAAA,IAAE;AAC5B,SAAK,eAAe,KAAK,kBAAkB,QAAQ;AACnD,SAAK,aAAa,cAAc;AAEhC,eAAW,MAAM,KAAK,KAAK,GAAG,CAAC;AAAA,EACjC;AAAA,EAEA,kBAAkB,UAAS;AACzB,WAAQ,SACL,QAAQ,SAAS,SAAS,EAC1B,QAAQ,UAAU,UAAU,EAC5B,QAAQ,IAAI,OAAO,UAAW,WAAW,SAAS,GAAG,QAAQ,WAAW,QAAQ;AAAA,EACrF;AAAA,EAEA,cAAa;AACX,WAAO,KAAK,aAAa,KAAK,cAAc,EAAC,OAAO,KAAK,MAAK,CAAC;AAAA,EACjE;AAAA,EAEA,cAAc,MAAM,QAAQ,UAAS;AACnC,SAAK,MAAM,MAAM,QAAQ,QAAQ;AACjC,SAAK,aAAa,cAAc;AAAA,EAClC;AAAA,EAEA,YAAW;AACT,SAAK,QAAQ,SAAS;AACtB,SAAK,cAAc,MAAM,WAAW,KAAK;AAAA,EAC3C;AAAA,EAEA,WAAU;AAAE,WAAO,KAAK,eAAe,cAAc,QAAQ,KAAK,eAAe,cAAc;AAAA,EAAW;AAAA,EAE1G,OAAM;AACJ,SAAK,KAAK,OAAO,oBAAoB,MAAM,MAAM,KAAK,UAAU,GAAG,UAAQ;AACzE,UAAG,MAAK;AACN,YAAI,EAAC,QAAQ,OAAO,SAAQ,IAAI;AAChC,aAAK,QAAQ;AAAA,MACf,OAAO;AACL,iBAAS;AAAA,MACX;AAEA,cAAO,QAAO;AAAA,QACZ,KAAK;AACH,mBAAS,QAAQ,SAAO;AAmBtB,uBAAW,MAAM,KAAK,UAAU,EAAC,MAAM,IAAG,CAAC,GAAG,CAAC;AAAA,UACjD,CAAC;AACD,eAAK,KAAK;AACV;AAAA,QACF,KAAK;AACH,eAAK,KAAK;AACV;AAAA,QACF,KAAK;AACH,eAAK,aAAa,cAAc;AAChC,eAAK,OAAO,CAAC,CAAC;AACd,eAAK,KAAK;AACV;AAAA,QACF,KAAK;AACH,eAAK,QAAQ,GAAG;AAChB,eAAK,MAAM,MAAM,aAAa,KAAK;AACnC;AAAA,QACF,KAAK;AAAA,QACL,KAAK;AACH,eAAK,QAAQ,GAAG;AAChB,eAAK,cAAc,MAAM,yBAAyB,GAAG;AACrD;AAAA,QACF;AAAS,gBAAM,IAAI,MAAM,yBAAyB,QAAQ;AAAA,MAC5D;AAAA,IACF,CAAC;AAAA,EACH;AAAA;AAAA;AAAA;AAAA,EAMA,KAAK,MAAK;AACR,QAAG,OAAO,SAAU,UAAS;AAAE,aAAO,oBAAoB,IAAI;AAAA,IAAE;AAChE,QAAG,KAAK,cAAa;AACnB,WAAK,aAAa,KAAK,IAAI;AAAA,IAC7B,WAAU,KAAK,kBAAiB;AAC9B,WAAK,YAAY,KAAK,IAAI;AAAA,IAC5B,OAAO;AACL,WAAK,eAAe,CAAC,IAAI;AACzB,WAAK,oBAAoB,WAAW,MAAM;AACxC,aAAK,UAAU,KAAK,YAAY;AAChC,aAAK,eAAe;AAAA,MACtB,GAAG,CAAC;AAAA,IACN;AAAA,EACF;AAAA,EAEA,UAAU,UAAS;AACjB,SAAK,mBAAmB;AACxB,SAAK,KAAK,QAAQ,wBAAwB,SAAS,KAAK,IAAI,GAAG,MAAM,KAAK,QAAQ,SAAS,GAAG,UAAQ;AACpG,WAAK,mBAAmB;AACxB,UAAG,CAAC,QAAQ,KAAK,WAAW,KAAI;AAC9B,aAAK,QAAQ,QAAQ,KAAK,MAAM;AAChC,aAAK,cAAc,MAAM,yBAAyB,KAAK;AAAA,MACzD,WAAU,KAAK,YAAY,SAAS,GAAE;AACpC,aAAK,UAAU,KAAK,WAAW;AAC/B,aAAK,cAAc,CAAC;AAAA,MACtB;AAAA,IACF,CAAC;AAAA,EACH;AAAA,EAEA,MAAM,MAAM,QAAQ,UAAS;AAC3B,aAAQ,OAAO,KAAK,MAAK;AAAE,UAAI,MAAM;AAAA,IAAE;AACvC,SAAK,aAAa,cAAc;AAChC,QAAI,OAAO,OAAO,OAAO,EAAC,MAAM,KAAM,QAAQ,QAAW,UAAU,KAAI,GAAG,EAAC,MAAM,QAAQ,SAAQ,CAAC;AAClG,SAAK,cAAc,CAAC;AACpB,iBAAa,KAAK,iBAAiB;AACnC,SAAK,oBAAoB;AACzB,QAAG,OAAO,eAAgB,aAAY;AACpC,WAAK,QAAQ,IAAI,WAAW,SAAS,IAAI,CAAC;AAAA,IAC5C,OAAO;AACL,WAAK,QAAQ,IAAI;AAAA,IACnB;AAAA,EACF;AAAA,EAEA,KAAK,QAAQ,aAAa,MAAM,iBAAiB,UAAS;AACxD,QAAI;AACJ,QAAI,YAAY,MAAM;AACpB,WAAK,KAAK,OAAO,GAAG;AACpB,sBAAgB;AAAA,IAClB;AACA,UAAM,KAAK,QAAQ,QAAQ,KAAK,YAAY,GAAG,aAAa,MAAM,KAAK,SAAS,WAAW,UAAQ;AACjG,WAAK,KAAK,OAAO,GAAG;AACpB,UAAG,KAAK,SAAS,GAAE;AAAE,iBAAS,IAAI;AAAA,MAAE;AAAA,IACtC,CAAC;AACD,SAAK,KAAK,IAAI,GAAG;AAAA,EACnB;AACF;;;ACxKA,IAAqB,WAArB,MAA8B;AAAA,EAE5B,YAAY,SAAS,OAAO,CAAC,GAAE;AAC7B,QAAI,SAAS,KAAK,UAAU,EAAC,OAAO,kBAAkB,MAAM,gBAAe;AAC3E,SAAK,QAAQ,CAAC;AACd,SAAK,eAAe,CAAC;AACrB,SAAK,UAAU;AACf,SAAK,UAAU;AACf,SAAK,SAAS;AAAA,MACZ,QAAQ,WAAW;AAAA,MAAE;AAAA,MACrB,SAAS,WAAW;AAAA,MAAE;AAAA,MACtB,QAAQ,WAAW;AAAA,MAAE;AAAA,IACvB;AAEA,SAAK,QAAQ,GAAG,OAAO,OAAO,cAAY;AACxC,UAAI,EAAC,QAAQ,SAAS,OAAM,IAAI,KAAK;AAErC,WAAK,UAAU,KAAK,QAAQ,QAAQ;AACpC,WAAK,QAAQ,SAAS,UAAU,KAAK,OAAO,UAAU,QAAQ,OAAO;AAErE,WAAK,aAAa,QAAQ,UAAQ;AAChC,aAAK,QAAQ,SAAS,SAAS,KAAK,OAAO,MAAM,QAAQ,OAAO;AAAA,MAClE,CAAC;AACD,WAAK,eAAe,CAAC;AACrB,aAAO;AAAA,IACT,CAAC;AAED,SAAK,QAAQ,GAAG,OAAO,MAAM,UAAQ;AACnC,UAAI,EAAC,QAAQ,SAAS,OAAM,IAAI,KAAK;AAErC,UAAG,KAAK,mBAAmB,GAAE;AAC3B,aAAK,aAAa,KAAK,IAAI;AAAA,MAC7B,OAAO;AACL,aAAK,QAAQ,SAAS,SAAS,KAAK,OAAO,MAAM,QAAQ,OAAO;AAChE,eAAO;AAAA,MACT;AAAA,IACF,CAAC;AAAA,EACH;AAAA,EAEA,OAAO,UAAS;AAAE,SAAK,OAAO,SAAS;AAAA,EAAS;AAAA,EAEhD,QAAQ,UAAS;AAAE,SAAK,OAAO,UAAU;AAAA,EAAS;AAAA,EAElD,OAAO,UAAS;AAAE,SAAK,OAAO,SAAS;AAAA,EAAS;AAAA,EAEhD,KAAK,IAAG;AAAE,WAAO,SAAS,KAAK,KAAK,OAAO,EAAE;AAAA,EAAE;AAAA,EAE/C,qBAAoB;AAClB,WAAO,CAAC,KAAK,WAAY,KAAK,YAAY,KAAK,QAAQ,QAAQ;AAAA,EACjE;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAYA,OAAO,UAAU,cAAc,UAAU,QAAQ,SAAQ;AACvD,QAAI,QAAQ,KAAK,MAAM,YAAY;AACnC,QAAI,QAAQ,CAAC;AACb,QAAI,SAAS,CAAC;AAEd,SAAK,IAAI,OAAO,CAAC,KAAK,aAAa;AACjC,UAAG,CAAC,SAAS,GAAG,GAAE;AAChB,eAAO,GAAG,IAAI;AAAA,MAChB;AAAA,IACF,CAAC;AACD,SAAK,IAAI,UAAU,CAAC,KAAK,gBAAgB;AACvC,UAAI,kBAAkB,MAAM,GAAG;AAC/B,UAAG,iBAAgB;AACjB,YAAI,UAAU,YAAY,MAAM,IAAI,OAAK,EAAE,OAAO;AAClD,YAAI,UAAU,gBAAgB,MAAM,IAAI,OAAK,EAAE,OAAO;AACtD,YAAI,cAAc,YAAY,MAAM,OAAO,OAAK,QAAQ,QAAQ,EAAE,OAAO,IAAI,CAAC;AAC9E,YAAI,YAAY,gBAAgB,MAAM,OAAO,OAAK,QAAQ,QAAQ,EAAE,OAAO,IAAI,CAAC;AAChF,YAAG,YAAY,SAAS,GAAE;AACxB,gBAAM,GAAG,IAAI;AACb,gBAAM,GAAG,EAAE,QAAQ;AAAA,QACrB;AACA,YAAG,UAAU,SAAS,GAAE;AACtB,iBAAO,GAAG,IAAI,KAAK,MAAM,eAAe;AACxC,iBAAO,GAAG,EAAE,QAAQ;AAAA,QACtB;AAAA,MACF,OAAO;AACL,cAAM,GAAG,IAAI;AAAA,MACf;AAAA,IACF,CAAC;AACD,WAAO,KAAK,SAAS,OAAO,EAAC,OAAc,OAAc,GAAG,QAAQ,OAAO;AAAA,EAC7E;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAWA,OAAO,SAAS,OAAO,MAAM,QAAQ,SAAQ;AAC3C,QAAI,EAAC,OAAO,OAAM,IAAI,KAAK,MAAM,IAAI;AACrC,QAAG,CAAC,QAAO;AAAE,eAAS,WAAW;AAAA,MAAE;AAAA,IAAE;AACrC,QAAG,CAAC,SAAQ;AAAE,gBAAU,WAAW;AAAA,MAAE;AAAA,IAAE;AAEvC,SAAK,IAAI,OAAO,CAAC,KAAK,gBAAgB;AACpC,UAAI,kBAAkB,MAAM,GAAG;AAC/B,YAAM,GAAG,IAAI,KAAK,MAAM,WAAW;AACnC,UAAG,iBAAgB;AACjB,YAAI,aAAa,MAAM,GAAG,EAAE,MAAM,IAAI,OAAK,EAAE,OAAO;AACpD,YAAI,WAAW,gBAAgB,MAAM,OAAO,OAAK,WAAW,QAAQ,EAAE,OAAO,IAAI,CAAC;AAClF,cAAM,GAAG,EAAE,MAAM,QAAQ,GAAG,QAAQ;AAAA,MACtC;AACA,aAAO,KAAK,iBAAiB,WAAW;AAAA,IAC1C,CAAC;AACD,SAAK,IAAI,QAAQ,CAAC,KAAK,iBAAiB;AACtC,UAAI,kBAAkB,MAAM,GAAG;AAC/B,UAAG,CAAC,iBAAgB;AAAE;AAAA,MAAO;AAC7B,UAAI,eAAe,aAAa,MAAM,IAAI,OAAK,EAAE,OAAO;AACxD,sBAAgB,QAAQ,gBAAgB,MAAM,OAAO,OAAK;AACxD,eAAO,aAAa,QAAQ,EAAE,OAAO,IAAI;AAAA,MAC3C,CAAC;AACD,cAAQ,KAAK,iBAAiB,YAAY;AAC1C,UAAG,gBAAgB,MAAM,WAAW,GAAE;AACpC,eAAO,MAAM,GAAG;AAAA,MAClB;AAAA,IACF,CAAC;AACD,WAAO;AAAA,EACT;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAUA,OAAO,KAAK,WAAW,SAAQ;AAC7B,QAAG,CAAC,SAAQ;AAAE,gBAAU,SAAU,KAAK,MAAK;AAAE,eAAO;AAAA,MAAK;AAAA,IAAE;AAE5D,WAAO,KAAK,IAAI,WAAW,CAAC,KAAK,aAAa;AAC5C,aAAO,QAAQ,KAAK,QAAQ;AAAA,IAC9B,CAAC;AAAA,EACH;AAAA;AAAA,EAIA,OAAO,IAAI,KAAK,MAAK;AACnB,WAAO,OAAO,oBAAoB,GAAG,EAAE,IAAI,SAAO,KAAK,KAAK,IAAI,GAAG,CAAC,CAAC;AAAA,EACvE;AAAA,EAEA,OAAO,MAAM,KAAI;AAAE,WAAO,KAAK,MAAM,KAAK,UAAU,GAAG,CAAC;AAAA,EAAE;AAC5D;;;AC5JA,IAAO,qBAAQ;AAAA,EACb,eAAe;AAAA,EACf,aAAa;AAAA,EACb,OAAO,EAAC,MAAM,GAAG,OAAO,GAAG,WAAW,EAAC;AAAA,EAEvC,OAAO,KAAK,UAAS;AACnB,QAAG,IAAI,QAAQ,gBAAgB,aAAY;AACzC,aAAO,SAAS,KAAK,aAAa,GAAG,CAAC;AAAA,IACxC,OAAO;AACL,UAAI,UAAU,CAAC,IAAI,UAAU,IAAI,KAAK,IAAI,OAAO,IAAI,OAAO,IAAI,OAAO;AACvE,aAAO,SAAS,KAAK,UAAU,OAAO,CAAC;AAAA,IACzC;AAAA,EACF;AAAA,EAEA,OAAO,YAAY,UAAS;AAC1B,QAAG,WAAW,gBAAgB,aAAY;AACxC,aAAO,SAAS,KAAK,aAAa,UAAU,CAAC;AAAA,IAC/C,OAAO;AACL,UAAI,CAAC,UAAU,KAAK,OAAO,OAAO,OAAO,IAAI,KAAK,MAAM,UAAU;AAClE,aAAO,SAAS,EAAC,UAAU,KAAK,OAAO,OAAO,QAAO,CAAC;AAAA,IACxD;AAAA,EACF;AAAA;AAAA,EAIA,aAAa,SAAQ;AACnB,QAAI,EAAC,UAAU,KAAK,OAAO,OAAO,QAAO,IAAI;AAC7C,QAAI,aAAa,KAAK,cAAc,SAAS,SAAS,IAAI,SAAS,MAAM,SAAS,MAAM;AACxF,QAAI,SAAS,IAAI,YAAY,KAAK,gBAAgB,UAAU;AAC5D,QAAI,OAAO,IAAI,SAAS,MAAM;AAC9B,QAAI,SAAS;AAEb,SAAK,SAAS,UAAU,KAAK,MAAM,IAAI;AACvC,SAAK,SAAS,UAAU,SAAS,MAAM;AACvC,SAAK,SAAS,UAAU,IAAI,MAAM;AAClC,SAAK,SAAS,UAAU,MAAM,MAAM;AACpC,SAAK,SAAS,UAAU,MAAM,MAAM;AACpC,UAAM,KAAK,UAAU,UAAQ,KAAK,SAAS,UAAU,KAAK,WAAW,CAAC,CAAC,CAAC;AACxE,UAAM,KAAK,KAAK,UAAQ,KAAK,SAAS,UAAU,KAAK,WAAW,CAAC,CAAC,CAAC;AACnE,UAAM,KAAK,OAAO,UAAQ,KAAK,SAAS,UAAU,KAAK,WAAW,CAAC,CAAC,CAAC;AACrE,UAAM,KAAK,OAAO,UAAQ,KAAK,SAAS,UAAU,KAAK,WAAW,CAAC,CAAC,CAAC;AAErE,QAAI,WAAW,IAAI,WAAW,OAAO,aAAa,QAAQ,UAAU;AACpE,aAAS,IAAI,IAAI,WAAW,MAAM,GAAG,CAAC;AACtC,aAAS,IAAI,IAAI,WAAW,OAAO,GAAG,OAAO,UAAU;AAEvD,WAAO,SAAS;AAAA,EAClB;AAAA,EAEA,aAAa,QAAO;AAClB,QAAI,OAAO,IAAI,SAAS,MAAM;AAC9B,QAAI,OAAO,KAAK,SAAS,CAAC;AAC1B,QAAI,UAAU,IAAI,YAAY;AAC9B,YAAO,MAAK;AAAA,MACV,KAAK,KAAK,MAAM;AAAM,eAAO,KAAK,WAAW,QAAQ,MAAM,OAAO;AAAA,MAClE,KAAK,KAAK,MAAM;AAAO,eAAO,KAAK,YAAY,QAAQ,MAAM,OAAO;AAAA,MACpE,KAAK,KAAK,MAAM;AAAW,eAAO,KAAK,gBAAgB,QAAQ,MAAM,OAAO;AAAA,IAC9E;AAAA,EACF;AAAA,EAEA,WAAW,QAAQ,MAAM,SAAQ;AAC/B,QAAI,cAAc,KAAK,SAAS,CAAC;AACjC,QAAI,YAAY,KAAK,SAAS,CAAC;AAC/B,QAAI,YAAY,KAAK,SAAS,CAAC;AAC/B,QAAI,SAAS,KAAK,gBAAgB,KAAK,cAAc;AACrD,QAAI,UAAU,QAAQ,OAAO,OAAO,MAAM,QAAQ,SAAS,WAAW,CAAC;AACvE,aAAS,SAAS;AAClB,QAAI,QAAQ,QAAQ,OAAO,OAAO,MAAM,QAAQ,SAAS,SAAS,CAAC;AACnE,aAAS,SAAS;AAClB,QAAI,QAAQ,QAAQ,OAAO,OAAO,MAAM,QAAQ,SAAS,SAAS,CAAC;AACnE,aAAS,SAAS;AAClB,QAAI,OAAO,OAAO,MAAM,QAAQ,OAAO,UAAU;AACjD,WAAO,EAAC,UAAU,SAAS,KAAK,MAAM,OAAc,OAAc,SAAS,KAAI;AAAA,EACjF;AAAA,EAEA,YAAY,QAAQ,MAAM,SAAQ;AAChC,QAAI,cAAc,KAAK,SAAS,CAAC;AACjC,QAAI,UAAU,KAAK,SAAS,CAAC;AAC7B,QAAI,YAAY,KAAK,SAAS,CAAC;AAC/B,QAAI,YAAY,KAAK,SAAS,CAAC;AAC/B,QAAI,SAAS,KAAK,gBAAgB,KAAK;AACvC,QAAI,UAAU,QAAQ,OAAO,OAAO,MAAM,QAAQ,SAAS,WAAW,CAAC;AACvE,aAAS,SAAS;AAClB,QAAI,MAAM,QAAQ,OAAO,OAAO,MAAM,QAAQ,SAAS,OAAO,CAAC;AAC/D,aAAS,SAAS;AAClB,QAAI,QAAQ,QAAQ,OAAO,OAAO,MAAM,QAAQ,SAAS,SAAS,CAAC;AACnE,aAAS,SAAS;AAClB,QAAI,QAAQ,QAAQ,OAAO,OAAO,MAAM,QAAQ,SAAS,SAAS,CAAC;AACnE,aAAS,SAAS;AAClB,QAAI,OAAO,OAAO,MAAM,QAAQ,OAAO,UAAU;AACjD,QAAI,UAAU,EAAC,QAAQ,OAAO,UAAU,KAAI;AAC5C,WAAO,EAAC,UAAU,SAAS,KAAU,OAAc,OAAO,eAAe,OAAO,QAAgB;AAAA,EAClG;AAAA,EAEA,gBAAgB,QAAQ,MAAM,SAAQ;AACpC,QAAI,YAAY,KAAK,SAAS,CAAC;AAC/B,QAAI,YAAY,KAAK,SAAS,CAAC;AAC/B,QAAI,SAAS,KAAK,gBAAgB;AAClC,QAAI,QAAQ,QAAQ,OAAO,OAAO,MAAM,QAAQ,SAAS,SAAS,CAAC;AACnE,aAAS,SAAS;AAClB,QAAI,QAAQ,QAAQ,OAAO,OAAO,MAAM,QAAQ,SAAS,SAAS,CAAC;AACnE,aAAS,SAAS;AAClB,QAAI,OAAO,OAAO,MAAM,QAAQ,OAAO,UAAU;AAEjD,WAAO,EAAC,UAAU,MAAM,KAAK,MAAM,OAAc,OAAc,SAAS,KAAI;AAAA,EAC9E;AACF;;;ACFA,IAAqB,SAArB,MAA4B;AAAA,EAC1B,YAAY,UAAU,OAAO,CAAC,GAAE;AAC9B,SAAK,uBAAuB,EAAC,MAAM,CAAC,GAAG,OAAO,CAAC,GAAG,OAAO,CAAC,GAAG,SAAS,CAAC,EAAC;AACxE,SAAK,WAAW,CAAC;AACjB,SAAK,aAAa,CAAC;AACnB,SAAK,MAAM;AACX,SAAK,UAAU,KAAK,WAAW;AAC/B,SAAK,YAAY,KAAK,aAAa,OAAO,aAAa;AACvD,SAAK,2BAA2B;AAChC,SAAK,qBAAqB,KAAK;AAC/B,SAAK,gBAAgB;AACrB,SAAK,eAAe,KAAK,kBAAkB,OAAO;AAClD,SAAK,yBAAyB;AAC9B,SAAK,iBAAiB,mBAAW,OAAO,KAAK,kBAAU;AACvD,SAAK,iBAAiB,mBAAW,OAAO,KAAK,kBAAU;AACvD,SAAK,gBAAgB;AACrB,SAAK,aAAa,KAAK,cAAc;AACrC,SAAK,eAAe;AACpB,QAAG,KAAK,cAAc,UAAS;AAC7B,WAAK,SAAS,KAAK,UAAU,KAAK;AAClC,WAAK,SAAS,KAAK,UAAU,KAAK;AAAA,IACpC,OAAO;AACL,WAAK,SAAS,KAAK;AACnB,WAAK,SAAS,KAAK;AAAA,IACrB;AACA,QAAI,+BAA+B;AACnC,QAAG,aAAa,UAAU,kBAAiB;AACzC,gBAAU,iBAAiB,YAAY,QAAM;AAC3C,YAAG,KAAK,MAAK;AACX,eAAK,WAAW;AAChB,yCAA+B,KAAK;AAAA,QACtC;AAAA,MACF,CAAC;AACD,gBAAU,iBAAiB,YAAY,QAAM;AAC3C,YAAG,iCAAiC,KAAK,cAAa;AACpD,yCAA+B;AAC/B,eAAK,QAAQ;AAAA,QACf;AAAA,MACF,CAAC;AAAA,IACH;AACA,SAAK,sBAAsB,KAAK,uBAAuB;AACvD,SAAK,gBAAgB,CAAC,UAAU;AAC9B,UAAG,KAAK,eAAc;AACpB,eAAO,KAAK,cAAc,KAAK;AAAA,MACjC,OAAO;AACL,eAAO,CAAC,KAAM,KAAM,GAAI,EAAE,QAAQ,CAAC,KAAK;AAAA,MAC1C;AAAA,IACF;AACA,SAAK,mBAAmB,CAAC,UAAU;AACjC,UAAG,KAAK,kBAAiB;AACvB,eAAO,KAAK,iBAAiB,KAAK;AAAA,MACpC,OAAO;AACL,eAAO,CAAC,IAAI,IAAI,KAAK,KAAK,KAAK,KAAK,KAAK,KAAM,GAAI,EAAE,QAAQ,CAAC,KAAK;AAAA,MACrE;AAAA,IACF;AACA,SAAK,SAAS,KAAK,UAAU;AAC7B,QAAG,CAAC,KAAK,UAAU,KAAK,OAAM;AAC5B,WAAK,SAAS,CAAC,MAAM,KAAK,SAAS;AAAE,gBAAQ,IAAI,GAAG,SAAS,OAAO,IAAI;AAAA,MAAE;AAAA,IAC5E;AACA,SAAK,oBAAoB,KAAK,qBAAqB;AACnD,SAAK,SAAS,QAAQ,KAAK,UAAU,CAAC,CAAC;AACvC,SAAK,WAAW,GAAG,YAAY,WAAW;AAC1C,SAAK,MAAM,KAAK,OAAO;AACvB,SAAK,wBAAwB;AAC7B,SAAK,iBAAiB;AACtB,SAAK,sBAAsB;AAC3B,SAAK,iBAAiB,IAAI,MAAM,MAAM;AACpC,WAAK,SAAS,MAAM,KAAK,QAAQ,CAAC;AAAA,IACpC,GAAG,KAAK,gBAAgB;AAAA,EAC1B;AAAA;AAAA;AAAA;AAAA,EAKA,uBAAsB;AAAE,WAAO;AAAA,EAAS;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAQxC,iBAAiB,cAAa;AAC5B,SAAK;AACL,SAAK,gBAAgB;AACrB,iBAAa,KAAK,aAAa;AAC/B,SAAK,eAAe,MAAM;AAC1B,QAAG,KAAK,MAAK;AACX,WAAK,KAAK,MAAM;AAChB,WAAK,OAAO;AAAA,IACd;AACA,SAAK,YAAY;AAAA,EACnB;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAOA,WAAU;AAAE,WAAO,SAAS,SAAS,MAAM,QAAQ,IAAI,QAAQ;AAAA,EAAK;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAOpE,cAAa;AACX,QAAI,MAAM,KAAK;AAAA,MACb,KAAK,aAAa,KAAK,UAAU,KAAK,OAAO,CAAC;AAAA,MAAG,EAAC,KAAK,KAAK,IAAG;AAAA,IAAC;AAClE,QAAG,IAAI,OAAO,CAAC,MAAM,KAAI;AAAE,aAAO;AAAA,IAAI;AACtC,QAAG,IAAI,OAAO,CAAC,MAAM,KAAI;AAAE,aAAO,GAAG,KAAK,SAAS,KAAK;AAAA,IAAM;AAE9D,WAAO,GAAG,KAAK,SAAS,OAAO,SAAS,OAAO;AAAA,EACjD;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAWA,WAAW,UAAU,MAAM,QAAO;AAChC,SAAK;AACL,SAAK,gBAAgB;AACrB,iBAAa,KAAK,aAAa;AAC/B,SAAK,eAAe,MAAM;AAC1B,SAAK,SAAS,UAAU,MAAM,MAAM;AAAA,EACtC;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EASA,QAAQ,QAAO;AACb,QAAG,QAAO;AACR,iBAAW,QAAQ,IAAI,yFAAyF;AAChH,WAAK,SAAS,QAAQ,MAAM;AAAA,IAC9B;AACA,QAAG,KAAK,MAAK;AAAE;AAAA,IAAO;AACtB,QAAG,KAAK,sBAAsB,KAAK,cAAc,UAAS;AACxD,WAAK,oBAAoB,UAAU,KAAK,kBAAkB;AAAA,IAC5D,OAAO;AACL,WAAK,iBAAiB;AAAA,IACxB;AAAA,EACF;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAQA,IAAI,MAAM,KAAK,MAAK;AAAE,SAAK,UAAU,KAAK,OAAO,MAAM,KAAK,IAAI;AAAA,EAAE;AAAA;AAAA;AAAA;AAAA,EAKlE,YAAW;AAAE,WAAO,KAAK,WAAW;AAAA,EAAK;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EASzC,OAAO,UAAS;AACd,QAAI,MAAM,KAAK,QAAQ;AACvB,SAAK,qBAAqB,KAAK,KAAK,CAAC,KAAK,QAAQ,CAAC;AACnD,WAAO;AAAA,EACT;AAAA;AAAA;AAAA;AAAA;AAAA,EAMA,QAAQ,UAAS;AACf,QAAI,MAAM,KAAK,QAAQ;AACvB,SAAK,qBAAqB,MAAM,KAAK,CAAC,KAAK,QAAQ,CAAC;AACpD,WAAO;AAAA,EACT;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EASA,QAAQ,UAAS;AACf,QAAI,MAAM,KAAK,QAAQ;AACvB,SAAK,qBAAqB,MAAM,KAAK,CAAC,KAAK,QAAQ,CAAC;AACpD,WAAO;AAAA,EACT;AAAA;AAAA;AAAA;AAAA;AAAA,EAMA,UAAU,UAAS;AACjB,QAAI,MAAM,KAAK,QAAQ;AACvB,SAAK,qBAAqB,QAAQ,KAAK,CAAC,KAAK,QAAQ,CAAC;AACtD,WAAO;AAAA,EACT;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAQA,KAAK,UAAS;AACZ,QAAG,CAAC,KAAK,YAAY,GAAE;AAAE,aAAO;AAAA,IAAM;AACtC,QAAI,MAAM,KAAK,QAAQ;AACvB,QAAI,YAAY,KAAK,IAAI;AACzB,SAAK,KAAK,EAAC,OAAO,WAAW,OAAO,aAAa,SAAS,CAAC,GAAG,IAAQ,CAAC;AACvE,QAAI,WAAW,KAAK,UAAU,SAAO;AACnC,UAAG,IAAI,QAAQ,KAAI;AACjB,aAAK,IAAI,CAAC,QAAQ,CAAC;AACnB,iBAAS,KAAK,IAAI,IAAI,SAAS;AAAA,MACjC;AAAA,IACF,CAAC;AACD,WAAO;AAAA,EACT;AAAA;AAAA;AAAA;AAAA,EAMA,mBAAkB;AAChB,SAAK;AACL,SAAK,gBAAgB;AACrB,SAAK,OAAO,IAAI,KAAK,UAAU,KAAK,YAAY,CAAC;AACjD,SAAK,KAAK,aAAa,KAAK;AAC5B,SAAK,KAAK,UAAU,KAAK;AACzB,SAAK,KAAK,SAAS,MAAM,KAAK,WAAW;AACzC,SAAK,KAAK,UAAU,WAAS,KAAK,YAAY,KAAK;AACnD,SAAK,KAAK,YAAY,WAAS,KAAK,cAAc,KAAK;AACvD,SAAK,KAAK,UAAU,WAAS,KAAK,YAAY,KAAK;AAAA,EACrD;AAAA,EAEA,WAAW,KAAI;AAAE,WAAO,KAAK,gBAAgB,KAAK,aAAa,QAAQ,GAAG;AAAA,EAAE;AAAA,EAE5E,aAAa,KAAK,KAAI;AAAE,SAAK,gBAAgB,KAAK,aAAa,QAAQ,KAAK,GAAG;AAAA,EAAE;AAAA,EAEjF,oBAAoB,mBAAmB,oBAAoB,MAAK;AAC9D,iBAAa,KAAK,aAAa;AAC/B,QAAI,cAAc;AAClB,QAAI,mBAAmB;AACvB,QAAI,SAAS;AACb,QAAI,WAAW,CAAC,WAAW;AACzB,WAAK,IAAI,aAAa,mBAAmB,kBAAkB,WAAW,MAAM;AAC5E,WAAK,IAAI,CAAC,SAAS,QAAQ,CAAC;AAC5B,yBAAmB;AACnB,WAAK,iBAAiB,iBAAiB;AACvC,WAAK,iBAAiB;AAAA,IACxB;AACA,QAAG,KAAK,WAAW,gBAAgB,kBAAkB,MAAM,GAAE;AAAE,aAAO,SAAS,WAAW;AAAA,IAAE;AAE5F,SAAK,gBAAgB,WAAW,UAAU,iBAAiB;AAE3D,eAAW,KAAK,QAAQ,YAAU;AAChC,WAAK,IAAI,aAAa,SAAS,MAAM;AACrC,UAAG,oBAAoB,CAAC,aAAa;AACnC,qBAAa,KAAK,aAAa;AAC/B,iBAAS,MAAM;AAAA,MACjB;AAAA,IACF,CAAC;AACD,SAAK,OAAO,MAAM;AAChB,oBAAc;AACd,UAAG,CAAC,kBAAiB;AAEnB,YAAG,CAAC,KAAK,0BAAyB;AAAE,eAAK,aAAa,gBAAgB,kBAAkB,QAAQ,MAAM;AAAA,QAAE;AACxG,eAAO,KAAK,IAAI,aAAa,eAAe,kBAAkB,eAAe;AAAA,MAC/E;AAEA,mBAAa,KAAK,aAAa;AAC/B,WAAK,gBAAgB,WAAW,UAAU,iBAAiB;AAC3D,WAAK,KAAK,SAAO;AACf,aAAK,IAAI,aAAa,8BAA8B,GAAG;AACvD,aAAK,2BAA2B;AAChC,qBAAa,KAAK,aAAa;AAAA,MACjC,CAAC;AAAA,IACH,CAAC;AACD,SAAK,iBAAiB;AAAA,EACxB;AAAA,EAEA,kBAAiB;AACf,iBAAa,KAAK,cAAc;AAChC,iBAAa,KAAK,qBAAqB;AAAA,EACzC;AAAA,EAEA,aAAY;AACV,QAAG,KAAK,UAAU;AAAG,WAAK,IAAI,aAAa,GAAG,KAAK,UAAU,qBAAqB,KAAK,YAAY,GAAG;AACtG,SAAK,gBAAgB;AACrB,SAAK;AACL,SAAK,gBAAgB;AACrB,SAAK,eAAe,MAAM;AAC1B,SAAK,eAAe;AACpB,SAAK,qBAAqB,KAAK,QAAQ,CAAC,CAAC,EAAE,QAAQ,MAAM,SAAS,CAAC;AAAA,EACrE;AAAA;AAAA;AAAA;AAAA,EAMA,mBAAkB;AAChB,QAAG,KAAK,qBAAoB;AAC1B,WAAK,sBAAsB;AAC3B,UAAG,KAAK,UAAU,GAAE;AAAE,aAAK,IAAI,aAAa,0DAA0D;AAAA,MAAE;AACxG,WAAK,iBAAiB;AACtB,WAAK,gBAAgB;AACrB,WAAK,SAAS,MAAM,KAAK,eAAe,gBAAgB,GAAG,iBAAiB,mBAAmB;AAAA,IACjG;AAAA,EACF;AAAA,EAEA,iBAAgB;AACd,QAAG,KAAK,QAAQ,KAAK,KAAK,eAAc;AAAE;AAAA,IAAO;AACjD,SAAK,sBAAsB;AAC3B,SAAK,gBAAgB;AACrB,SAAK,iBAAiB,WAAW,MAAM,KAAK,cAAc,GAAG,KAAK,mBAAmB;AAAA,EACvF;AAAA,EAEA,SAAS,UAAU,MAAM,QAAO;AAC9B,QAAG,CAAC,KAAK,MAAK;AACZ,aAAO,YAAY,SAAS;AAAA,IAC9B;AAEA,SAAK,kBAAkB,MAAM;AAC3B,UAAG,KAAK,MAAK;AACX,YAAG,MAAK;AAAE,eAAK,KAAK,MAAM,MAAM,UAAU,EAAE;AAAA,QAAE,OAAO;AAAE,eAAK,KAAK,MAAM;AAAA,QAAE;AAAA,MAC3E;AAEA,WAAK,oBAAoB,MAAM;AAC7B,YAAG,KAAK,MAAK;AACX,eAAK,KAAK,SAAS,WAAW;AAAA,UAAE;AAChC,eAAK,KAAK,UAAU,WAAW;AAAA,UAAE;AACjC,eAAK,KAAK,YAAY,WAAW;AAAA,UAAE;AACnC,eAAK,KAAK,UAAU,WAAW;AAAA,UAAE;AACjC,eAAK,OAAO;AAAA,QACd;AAEA,oBAAY,SAAS;AAAA,MACvB,CAAC;AAAA,IACH,CAAC;AAAA,EACH;AAAA,EAEA,kBAAkB,UAAU,QAAQ,GAAE;AACpC,QAAG,UAAU,KAAK,CAAC,KAAK,QAAQ,CAAC,KAAK,KAAK,gBAAe;AACxD,eAAS;AACT;AAAA,IACF;AAEA,eAAW,MAAM;AACf,WAAK,kBAAkB,UAAU,QAAQ,CAAC;AAAA,IAC5C,GAAG,MAAM,KAAK;AAAA,EAChB;AAAA,EAEA,oBAAoB,UAAU,QAAQ,GAAE;AACtC,QAAG,UAAU,KAAK,CAAC,KAAK,QAAQ,KAAK,KAAK,eAAe,cAAc,QAAO;AAC5E,eAAS;AACT;AAAA,IACF;AAEA,eAAW,MAAM;AACf,WAAK,oBAAoB,UAAU,QAAQ,CAAC;AAAA,IAC9C,GAAG,MAAM,KAAK;AAAA,EAChB;AAAA,EAEA,YAAY,OAAM;AAChB,QAAI,YAAY,SAAS,MAAM;AAC/B,QAAG,KAAK,UAAU;AAAG,WAAK,IAAI,aAAa,SAAS,KAAK;AACzD,SAAK,iBAAiB;AACtB,SAAK,gBAAgB;AACrB,QAAG,CAAC,KAAK,iBAAiB,cAAc,KAAK;AAC3C,WAAK,eAAe,gBAAgB;AAAA,IACtC;AACA,SAAK,qBAAqB,MAAM,QAAQ,CAAC,CAAC,EAAE,QAAQ,MAAM,SAAS,KAAK,CAAC;AAAA,EAC3E;AAAA;AAAA;AAAA;AAAA,EAKA,YAAY,OAAM;AAChB,QAAG,KAAK,UAAU;AAAG,WAAK,IAAI,aAAa,KAAK;AAChD,QAAI,kBAAkB,KAAK;AAC3B,QAAI,oBAAoB,KAAK;AAC7B,SAAK,qBAAqB,MAAM,QAAQ,CAAC,CAAC,EAAE,QAAQ,MAAM;AACxD,eAAS,OAAO,iBAAiB,iBAAiB;AAAA,IACpD,CAAC;AACD,QAAG,oBAAoB,KAAK,aAAa,oBAAoB,GAAE;AAC7D,WAAK,iBAAiB;AAAA,IACxB;AAAA,EACF;AAAA;AAAA;AAAA;AAAA,EAKA,mBAAkB;AAChB,SAAK,SAAS,QAAQ,aAAW;AAC/B,UAAG,EAAE,QAAQ,UAAU,KAAK,QAAQ,UAAU,KAAK,QAAQ,SAAS,IAAG;AACrE,gBAAQ,QAAQ,eAAe,KAAK;AAAA,MACtC;AAAA,IACF,CAAC;AAAA,EACH;AAAA;AAAA;AAAA;AAAA,EAKA,kBAAiB;AACf,YAAO,KAAK,QAAQ,KAAK,KAAK,YAAW;AAAA,MACvC,KAAK,cAAc;AAAY,eAAO;AAAA,MACtC,KAAK,cAAc;AAAM,eAAO;AAAA,MAChC,KAAK,cAAc;AAAS,eAAO;AAAA,MACnC;AAAS,eAAO;AAAA,IAClB;AAAA,EACF;AAAA;AAAA;AAAA;AAAA,EAKA,cAAa;AAAE,WAAO,KAAK,gBAAgB,MAAM;AAAA,EAAO;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAOxD,OAAO,SAAQ;AACb,SAAK,IAAI,QAAQ,eAAe;AAChC,SAAK,WAAW,KAAK,SAAS,OAAO,OAAK,MAAM,OAAO;AAAA,EACzD;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAQA,IAAI,MAAK;AACP,aAAQ,OAAO,KAAK,sBAAqB;AACvC,WAAK,qBAAqB,GAAG,IAAI,KAAK,qBAAqB,GAAG,EAAE,OAAO,CAAC,CAAC,GAAG,MAAM;AAChF,eAAO,KAAK,QAAQ,GAAG,MAAM;AAAA,MAC/B,CAAC;AAAA,IACH;AAAA,EACF;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EASA,QAAQ,OAAO,aAAa,CAAC,GAAE;AAC7B,QAAI,OAAO,IAAI,QAAQ,OAAO,YAAY,IAAI;AAC9C,SAAK,SAAS,KAAK,IAAI;AACvB,WAAO;AAAA,EACT;AAAA;AAAA;AAAA;AAAA,EAKA,KAAK,MAAK;AACR,QAAG,KAAK,UAAU,GAAE;AAClB,UAAI,EAAC,OAAO,OAAO,SAAS,KAAK,SAAQ,IAAI;AAC7C,WAAK,IAAI,QAAQ,GAAG,SAAS,UAAU,aAAa,QAAQ,OAAO;AAAA,IACrE;AAEA,QAAG,KAAK,YAAY,GAAE;AACpB,WAAK,OAAO,MAAM,YAAU,KAAK,KAAK,KAAK,MAAM,CAAC;AAAA,IACpD,OAAO;AACL,WAAK,WAAW,KAAK,MAAM,KAAK,OAAO,MAAM,YAAU,KAAK,KAAK,KAAK,MAAM,CAAC,CAAC;AAAA,IAChF;AAAA,EACF;AAAA;AAAA;AAAA;AAAA;AAAA,EAMA,UAAS;AACP,QAAI,SAAS,KAAK,MAAM;AACxB,QAAG,WAAW,KAAK,KAAI;AAAE,WAAK,MAAM;AAAA,IAAE,OAAO;AAAE,WAAK,MAAM;AAAA,IAAO;AAEjE,WAAO,KAAK,IAAI,SAAS;AAAA,EAC3B;AAAA,EAEA,gBAAe;AACb,QAAG,KAAK,uBAAuB,CAAC,KAAK,YAAY,GAAE;AAAE;AAAA,IAAO;AAC5D,SAAK,sBAAsB,KAAK,QAAQ;AACxC,SAAK,KAAK,EAAC,OAAO,WAAW,OAAO,aAAa,SAAS,CAAC,GAAG,KAAK,KAAK,oBAAmB,CAAC;AAC5F,SAAK,wBAAwB,WAAW,MAAM,KAAK,iBAAiB,GAAG,KAAK,mBAAmB;AAAA,EACjG;AAAA,EAEA,kBAAiB;AACf,QAAG,KAAK,YAAY,KAAK,KAAK,WAAW,SAAS,GAAE;AAClD,WAAK,WAAW,QAAQ,cAAY,SAAS,CAAC;AAC9C,WAAK,aAAa,CAAC;AAAA,IACrB;AAAA,EACF;AAAA,EAEA,cAAc,YAAW;AACvB,SAAK,OAAO,WAAW,MAAM,SAAO;AAClC,UAAI,EAAC,OAAO,OAAO,SAAS,KAAK,SAAQ,IAAI;AAC7C,UAAG,OAAO,QAAQ,KAAK,qBAAoB;AACzC,aAAK,gBAAgB;AACrB,aAAK,sBAAsB;AAC3B,aAAK,iBAAiB,WAAW,MAAM,KAAK,cAAc,GAAG,KAAK,mBAAmB;AAAA,MACvF;AAEA,UAAG,KAAK,UAAU;AAAG,aAAK,IAAI,WAAW,GAAG,QAAQ,UAAU,MAAM,SAAS,SAAS,OAAO,MAAM,MAAM,OAAO,MAAM,OAAO;AAE7H,eAAQ,IAAI,GAAG,IAAI,KAAK,SAAS,QAAQ,KAAI;AAC3C,cAAM,UAAU,KAAK,SAAS,CAAC;AAC/B,YAAG,CAAC,QAAQ,SAAS,OAAO,OAAO,SAAS,QAAQ,GAAE;AAAE;AAAA,QAAS;AACjE,gBAAQ,QAAQ,OAAO,SAAS,KAAK,QAAQ;AAAA,MAC/C;AAEA,eAAQ,IAAI,GAAG,IAAI,KAAK,qBAAqB,QAAQ,QAAQ,KAAI;AAC/D,YAAI,CAAC,EAAE,QAAQ,IAAI,KAAK,qBAAqB,QAAQ,CAAC;AACtD,iBAAS,GAAG;AAAA,MACd;AAAA,IACF,CAAC;AAAA,EACH;AAAA,EAEA,eAAe,OAAM;AACnB,QAAI,aAAa,KAAK,SAAS,KAAK,OAAK,EAAE,UAAU,UAAU,EAAE,SAAS,KAAK,EAAE,UAAU,EAAE;AAC7F,QAAG,YAAW;AACZ,UAAG,KAAK,UAAU;AAAG,aAAK,IAAI,aAAa,4BAA4B,QAAQ;AAC/E,iBAAW,MAAM;AAAA,IACnB;AAAA,EACF;AACF;", "names": ["closure"] }