Created
February 13, 2015 01:47
-
-
Save rokob/755d26de4dabdae66dab to your computer and use it in GitHub Desktop.
fullstory code
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| var _fs_hash = "29adf5ed17f77f56ed2169dc42e99516"; | |
| try { | |
| "undefined" === typeof WeakMap && function() { | |
| var k = Object.defineProperty, | |
| v = Date.now() % 1E9, | |
| a = function() { | |
| this.name = "__st" + (1E9 * Math.random() >>> 0) + (v++ +"__") | |
| }; | |
| a.prototype = { | |
| set: function(a, f) { | |
| var d = a[this.name]; | |
| d && d[0] === a ? d[1] = f : k(a, this.name, { | |
| value: [a, f], | |
| writable: !0 | |
| }) | |
| }, | |
| get: function(a) { | |
| var f; | |
| return (f = a[this.name]) && f[0] === a ? f[1] : void 0 | |
| } | |
| }; | |
| window.WeakMap = a | |
| }() | |
| } catch (e$$12) {}; | |
| try { | |
| (function(k) { | |
| function v() { | |
| r = !1; | |
| var b = p; | |
| p = []; | |
| b.sort(function(a, b) { | |
| return a.uid_ - b.uid_ | |
| }); | |
| var c = !1; | |
| b.forEach(function(b) { | |
| var l = b.takeRecords(); | |
| a(b); | |
| l.length && (b.callback_(l, b), c = !0) | |
| }); | |
| c && v() | |
| } | |
| function a(a) { | |
| a.nodes_.forEach(function(b) { | |
| (b = g.get(b)) && b.forEach(function(b) { | |
| b.observer === a && b.removeTransientObservers() | |
| }) | |
| }) | |
| } | |
| function e(a, b) { | |
| for (var c = a; c; c = c.parentNode) { | |
| var l = g.get(c); | |
| if (l) | |
| for (var q = 0; q < l.length; q++) { | |
| var d = l[q], | |
| s = d.options; | |
| (c === a || s.subtree) && (s = b(s)) && d.enqueue(s) | |
| } | |
| } | |
| } | |
| function f(a) { | |
| this.callback_ = | |
| a; | |
| this.nodes_ = []; | |
| this.records_ = []; | |
| this.uid_ = ++n | |
| } | |
| function d(a, b) { | |
| this.type = a; | |
| this.target = b; | |
| this.addedNodes = []; | |
| this.removedNodes = []; | |
| this.oldValue = this.attributeNamespace = this.attributeName = this.nextSibling = this.previousSibling = null | |
| } | |
| function c(a, b) { | |
| return t = new d(a, b) | |
| } | |
| function b(a) { | |
| if (u) return u; | |
| var b = t, | |
| c = new d(b.type, b.target); | |
| c.addedNodes = b.addedNodes.slice(); | |
| c.removedNodes = b.removedNodes.slice(); | |
| c.previousSibling = b.previousSibling; | |
| c.nextSibling = b.nextSibling; | |
| c.attributeName = b.attributeName; | |
| c.attributeNamespace = | |
| b.attributeNamespace; | |
| c.oldValue = b.oldValue; | |
| u = c; | |
| u.oldValue = a; | |
| return u | |
| } | |
| function l(a, b, c) { | |
| this.observer = a; | |
| this.target = b; | |
| this.options = c; | |
| this.transientObservedNodes = [] | |
| } | |
| var g = new WeakMap, | |
| q = window.msSetImmediate; | |
| if (!q) { | |
| var s = [], | |
| h = String(Math.random()); | |
| window.addEventListener("message", function(a) { | |
| a.data === h && (a = s, s = [], a.forEach(function(a) { | |
| a() | |
| })) | |
| }); | |
| q = function(a) { | |
| s.push(a); | |
| window.postMessage(h, "*") | |
| } | |
| } | |
| var r = !1, | |
| p = [], | |
| n = 0; | |
| f.prototype = { | |
| observe: function(a, b) { | |
| a = window.ShadowDOMPolyfill && window.ShadowDOMPolyfill.wrapIfNeeded(a) || | |
| a; | |
| if (!b.childList && !b.attributes && !b.characterData || b.attributeOldValue && !b.attributes || b.attributeFilter && b.attributeFilter.length && !b.attributes || b.characterDataOldValue && !b.characterData) throw new SyntaxError; | |
| var c = g.get(a); | |
| c || g.set(a, c = []); | |
| for (var q, d = 0; d < c.length; d++) | |
| if (c[d].observer === this) { | |
| q = c[d]; | |
| q.removeListeners(); | |
| q.options = b; | |
| break | |
| } | |
| q || (q = new l(this, a, b), c.push(q), this.nodes_.push(a)); | |
| q.addListeners() | |
| }, | |
| disconnect: function() { | |
| this.nodes_.forEach(function(a) { | |
| a = g.get(a); | |
| for (var b = 0; b < a.length; b++) { | |
| var c = | |
| a[b]; | |
| if (c.observer === this) { | |
| c.removeListeners(); | |
| a.splice(b, 1); | |
| break | |
| } | |
| } | |
| }, this); | |
| this.records_ = [] | |
| }, | |
| takeRecords: function() { | |
| var a = this.records_; | |
| this.records_ = []; | |
| return a | |
| } | |
| }; | |
| var t, u; | |
| l.prototype = { | |
| enqueue: function(a) { | |
| var b = this.observer.records_, | |
| c = b.length; | |
| if (0 < b.length) { | |
| var l = b[c - 1]; | |
| l = l === a ? l : !u || l !== u && l !== t ? null : u; | |
| if (l) { | |
| b[c - 1] = l; | |
| return | |
| } | |
| } else p.push(this.observer), r || (r = !0, q(v)); | |
| b[c] = a | |
| }, | |
| addListeners: function() { | |
| this.addListeners_(this.target) | |
| }, | |
| addListeners_: function(a) { | |
| var b = this.options; | |
| b.attributes && a.addEventListener("DOMAttrModified", | |
| this, !0); | |
| b.characterData && a.addEventListener("DOMCharacterDataModified", this, !0); | |
| b.childList && a.addEventListener("DOMNodeInserted", this, !0); | |
| (b.childList || b.subtree) && a.addEventListener("DOMNodeRemoved", this, !0) | |
| }, | |
| removeListeners: function() { | |
| this.removeListeners_(this.target) | |
| }, | |
| removeListeners_: function(a) { | |
| var b = this.options; | |
| b.attributes && a.removeEventListener("DOMAttrModified", this, !0); | |
| b.characterData && a.removeEventListener("DOMCharacterDataModified", this, !0); | |
| b.childList && a.removeEventListener("DOMNodeInserted", | |
| this, !0); | |
| (b.childList || b.subtree) && a.removeEventListener("DOMNodeRemoved", this, !0) | |
| }, | |
| addTransientObserver: function(a) { | |
| if (a !== this.target) { | |
| this.addListeners_(a); | |
| this.transientObservedNodes.push(a); | |
| var b = g.get(a); | |
| b || g.set(a, b = []); | |
| b.push(this) | |
| } | |
| }, | |
| removeTransientObservers: function() { | |
| var a = this.transientObservedNodes; | |
| this.transientObservedNodes = []; | |
| a.forEach(function(a) { | |
| this.removeListeners_(a); | |
| a = g.get(a); | |
| for (var b = 0; b < a.length; b++) | |
| if (a[b] === this) { | |
| a.splice(b, 1); | |
| break | |
| } | |
| }, this) | |
| }, | |
| handleEvent: function(a) { | |
| switch (a.type) { | |
| case "DOMAttrModified": | |
| var l = | |
| a.attrName, | |
| q = a.relatedNode.namespaceURI, | |
| g = a.target, | |
| d = new c("attributes", g); | |
| d.attributeName = l; | |
| d.attributeNamespace = q; | |
| var s = a.attrChange === MutationEvent.ADDITION ? null : a.prevValue; | |
| e(g, function(a) { | |
| if (a.attributes && (!a.attributeFilter || !a.attributeFilter.length || -1 !== a.attributeFilter.indexOf(l) || -1 !== a.attributeFilter.indexOf(q))) return a.attributeOldValue ? b(s) : d | |
| }); | |
| break; | |
| case "DOMCharacterDataModified": | |
| g = a.target; | |
| d = c("characterData", g); | |
| s = a.prevValue; | |
| e(g, function(a) { | |
| if (a.characterData) return a.characterDataOldValue ? | |
| b(s) : d | |
| }); | |
| break; | |
| case "DOMNodeRemoved": | |
| this.addTransientObserver(a.target); | |
| case "DOMNodeInserted": | |
| var g = a.relatedNode, | |
| h = a.target, | |
| n; | |
| "DOMNodeInserted" === a.type ? (a = [h], n = []) : (a = [], n = [h]); | |
| var r = h.previousSibling, | |
| h = h.nextSibling, | |
| d = c("childList", g); | |
| d.addedNodes = a; | |
| d.removedNodes = n; | |
| d.previousSibling = r; | |
| d.nextSibling = h; | |
| e(g, function(a) { | |
| if (a.childList) return d | |
| }) | |
| } | |
| t = u = void 0 | |
| } | |
| }; | |
| k.JsMutationObserver = f; | |
| !k.MutationObserver && k.WebKitMutationObserver && (k.MutationObserver = k.WebKitMutationObserver); | |
| k.MutationObserver || (k.MutationObserver = | |
| f) | |
| })(this) | |
| } catch (e$$15) {}; | |
| (function() { | |
| var k; | |
| (function(a) { | |
| a.EVENT_MUT_INSERT = 2; | |
| a.EVENT_MUT_REMOVE = 3; | |
| a.EVENT_MUT_ATTR = 4; | |
| a.EVENT_MUT_ATTR_CURVE = 5; | |
| a.EVENT_MUT_TEXT = 6; | |
| a.EVENT_MUT_SKIPIDS = 7; | |
| a.EVENT_MOUSEMOVE = 8; | |
| a.EVENT_MOUSEMOVE_CURVE = 9; | |
| a.EVENT_SCROLL = 10; | |
| a.EVENT_SCROLL_CURVE = 11; | |
| a.EVENT_MOUSEDOWN = 12; | |
| a.EVENT_MOUSEUP = 13; | |
| a.EVENT_KEYDOWN = 14; | |
| a.EVENT_KEYUP = 15; | |
| a.EVENT_CLICK = 16; | |
| a.EVENT_FOCUS = 17; | |
| a.EVENT_VALUECHANGE = 18; | |
| a.EVENT_RESIZE = 19; | |
| a.EVENT_DOMLOADED = 20; | |
| a.EVENT_LOAD = 21; | |
| a.EVENT_PLACEHOLDER_SIZE = 22; | |
| a.EVENT_UNLOAD = 23; | |
| a.EVENT_BLUR = 24; | |
| a.EVENT_SET_FRAME_BASE = | |
| 25; | |
| a.EVENT_TOUCHSTART = 32; | |
| a.EVENT_TOUCHEND = 33; | |
| a.EVENT_TOUCHCANCEL = 34; | |
| a.EVENT_TOUCHMOVE = 35; | |
| a.EVENT_TOUCHMOVE_CURVE = 36; | |
| a.EVENT_NAVIGATE = 37; | |
| a.EVENT_PLAY = 38; | |
| a.EVENT_PAUSE = 39; | |
| a.EVENT_INNERWIDTH = 40; | |
| a.EVENT_INNERWIDTH_CURVE = 41; | |
| a.EVENT_LOG = 48; | |
| a.EVENT_ERROR = 49; | |
| a.EVENT_SYS_SETMETA = 8192; | |
| a.EVENT_SYS_SETVAR = 8193; | |
| a.EVENT_COOKED_LOAD = "load"; | |
| a.EVENT_COOKED_UNLOAD = "unload"; | |
| a.EVENT_COOKED_NAVIGATE = "navigate"; | |
| a.EVENT_COOKED_CLICK = "click"; | |
| a.EVENT_COOKED_FOCUS = "focus"; | |
| a.EVENT_COOKED_CHANGE = "change"; | |
| a.isUserActionEvent = | |
| function(e) { | |
| switch (e) { | |
| case a.EVENT_MOUSEDOWN: | |
| case a.EVENT_MOUSEMOVE: | |
| case a.EVENT_MOUSEMOVE_CURVE: | |
| case a.EVENT_MOUSEUP: | |
| case a.EVENT_KEYDOWN: | |
| case a.EVENT_KEYUP: | |
| case a.EVENT_TOUCHSTART: | |
| case a.EVENT_TOUCHEND: | |
| case a.EVENT_TOUCHMOVE: | |
| case a.EVENT_TOUCHMOVE_CURVE: | |
| case a.EVENT_TOUCHCANCEL: | |
| case a.EVENT_CLICK: | |
| case a.EVENT_SCROLL: | |
| case a.EVENT_SCROLL_CURVE: | |
| case a.EVENT_NAVIGATE: | |
| return !0 | |
| } | |
| return !1 | |
| } | |
| })(k || (k = {})); | |
| (function(a) { | |
| function e(a) { | |
| var c = {}; | |
| if (!a) return c; | |
| if (a.classList) | |
| for (var g = 0; g < a.classList.length; ++g) c[a.classList[g]] = !0; | |
| else | |
| for (a = (null != a.className.animVal ? a.className.animVal : a.className).split(" "), g = 0; g < a.length; ++g) c[a[g].trim()] = !0; | |
| return c | |
| } | |
| a.NYI_KIND = "nyi"; | |
| a.BLOCKED_KIND = "blocked"; | |
| a.HIDE_KIND = "hide"; | |
| var f = function() { | |
| function a(b, c) { | |
| var q = this; | |
| this._parent = b; | |
| this._classes = {}; | |
| this._attrs = {}; | |
| for (var d = 0, h = 0, e = 0, f = function() { | |
| if (0 != e - h) switch (d) { | |
| case 0: | |
| q._tag = c.slice(h, e); | |
| break; | |
| case 1: | |
| q._id = c.slice(h + 1, e); | |
| break; | |
| case 2: | |
| q._classes[c.slice(h + 1, e)] = !0; | |
| break; | |
| case 3: | |
| var a = c.slice(h, e).slice(1).split("="), | |
| b = a[0].trim(), | |
| a = a[1].trim(); | |
| if ("]" != a[a.length - 1]) throw "Unsupported selector"; | |
| a = a.slice(0, a.length - 1); | |
| if ("'" == a[0] || '"' == a[0]) { | |
| if (a[a.length - 1] != a[0]) throw "Unsupported selector"; | |
| a = a.slice(1, a.length - 1) | |
| } | |
| q._attrs[b] = a | |
| } | |
| }, e = 0; e < c.length; ++e) switch (c[e]) { | |
| case "#": | |
| f(); | |
| d = 1; | |
| h = e; | |
| break; | |
| case ".": | |
| f(); | |
| d = 2; | |
| h = e; | |
| break; | |
| case "[": | |
| f(), d = 3, h = e | |
| } | |
| f() | |
| } | |
| a.prototype.parent = function() { | |
| return this._parent | |
| }; | |
| a.prototype.serialize = function() { | |
| var a = ""; | |
| this._tag && (a += this._tag); | |
| this._id && (a += "#" + this._id); | |
| for (var b in this._classes) a += "." + b; | |
| for (var c in this._attrs) a += | |
| "[" + c + "=" + this._attrs[c] + "]"; | |
| return a | |
| }; | |
| a.prototype.matches = function(a, b) { | |
| if (!a || this._tag && a.tagName.toLowerCase() != this._tag || this._id && a.id != this._id) return !1; | |
| for (var c in this._classes) | |
| if (!(c in b)) return !1; | |
| for (var d in this._attrs) | |
| if (a.getAttribute(d) != this._attrs[d]) return !1; | |
| return this._parent ? this._parent.matches(a.parentElement, e(a.parentElement)) : !0 | |
| }; | |
| return a | |
| }(); | |
| a.BlockRuleElem = f; | |
| var d = function() { | |
| function a(b) { | |
| this.kind = b.Kind; | |
| b = b.Selector.split(">"); | |
| for (var c = null, q = 0; q < b.length;) var d = | |
| b[q++].trim(), | |
| c = new f(c, d); | |
| this.rules = c | |
| } | |
| a.prototype.serialize = function() { | |
| for (var a = null, b = this.rules; b; b = b.parent()) a = a ? b.serialize() + ">" + a : b.serialize(); | |
| return a | |
| }; | |
| return a | |
| }(); | |
| a.BlockRule = d; | |
| var c = function() { | |
| function a() { | |
| this._rules = []; | |
| this.rawRules = [] | |
| } | |
| a.prototype.isBlocked = function(a) { | |
| for (var b = e(a), c = 0; c < this._rules.length; ++c) | |
| if (this._rules[c].rules.matches(a, b)) return this._rules[c].kind; | |
| return null | |
| }; | |
| a.prototype.addRule = function(a) { | |
| this.rawRules.push(a); | |
| this._rules.push(new d(a)) | |
| }; | |
| a.prototype.mungeBlockedStyle = | |
| function(a, b) { | |
| var c = a.getBoundingClientRect(), | |
| d = Math.floor(c.width), | |
| c = Math.floor(c.height); | |
| if ("object" == a.tagName.toLowerCase()) | |
| for (var h = a.children, e = 0; e < h.length; e++) { | |
| var f = h[e]; | |
| if ("embed" == f.tagName.toLowerCase()) { | |
| h = f.getBoundingClientRect(); | |
| d = Math.max(d, Math.floor(h.width)); | |
| c = Math.max(c, Math.floor(h.height)); | |
| break | |
| } | |
| } | |
| h = ""; | |
| null != b && (h = b.trim()); | |
| 0 < h.length && ";" != h.charAt(h.length - 1) && (h += ";"); | |
| e = a.style.getPropertyValue("display"); | |
| "inline" == (e ? e : window.getComputedStyle(a).getPropertyValue("display")).toLowerCase() && | |
| (h += "display: inline-block !important;"); | |
| if (0 != d || 0 != c) h += "width:" + d + "px;height:" + c + "px;"; | |
| return h | |
| }; | |
| return a | |
| }(); | |
| a.Blocker = c | |
| })(k || (k = {})); | |
| (function(a) { | |
| a.Node_ELEMENT_NODE = 1; | |
| a.Node_ATTRIBUTE_NODE = 2; | |
| a.Node_TEXT_NODE = 3; | |
| a.Node_CDATA_SECTION_NODE = 4; | |
| a.Node_ENTITY_REFERENCE_NODE = 5; | |
| a.Node_ENTITY_NODE = 6; | |
| a.Node_PROCESSING_INSTRUCTION_NODE = 7; | |
| a.Node_COMMENT_NODE = 8; | |
| a.Node_DOCUMENT_NODE = 9; | |
| a.Node_DOCUMENT_TYPE_NODE = 10; | |
| a.Node_DOCUMENT_FRAGMENT_NODE = 11; | |
| a.Node_NOTATION_NODE = 12; | |
| a.XHR_UNSENT = 0; | |
| a.XHR_OPENED = 1; | |
| a.XHR_HEADERS_RECEIVED = | |
| 2; | |
| a.XHR_LOADING = 3; | |
| a.XHR_DONE = 4 | |
| })(k || (k = {})); | |
| (function(a) { | |
| function e(a) { | |
| return "_fsblocked" in a | |
| } | |
| function f(a, b) { | |
| a._fsblocked = b | |
| } | |
| function d(a) { | |
| return a ? a._fs : null | |
| } | |
| function c(a) { | |
| return (a = d(a)) ? a.id : 0 | |
| } | |
| function b(a, b) { | |
| if (a.attributes && 0 < a.attributes.length) | |
| for (var c = 0; c < a.attributes.length; c++) { | |
| var d = a.attributes[c]; | |
| b(d.name, d.value) | |
| } | |
| } | |
| a.isBlocked = e; | |
| a.blockKind = function(a) { | |
| return a._fsblocked | |
| }; | |
| a.setBlocked = f; | |
| a.mirrorFor = d; | |
| a.fsid = c; | |
| a.fsidIfNotBlocked = function(a) { | |
| return e(a) ? 0 : c(a) | |
| }; | |
| var l = function() { | |
| function c(a, | |
| b) { | |
| this._ctx = a; | |
| this._blocker = b; | |
| this._curId = 1 | |
| } | |
| c.prototype.curId = function() { | |
| return this._curId | |
| }; | |
| c.prototype.tokenizeNode = function(a, b, c, l) { | |
| var g = this._curId; | |
| try { | |
| var e = [], | |
| f = this.tokeNode(c, e, l); | |
| if (f && a) { | |
| var k = d(a), | |
| y = d(b); | |
| f.parent = k; | |
| y == k.child && (k.child = f); | |
| f.next = y; | |
| null == y ? (f.prev = k.lastChild, k.lastChild = f) : f.prev = y.prev; | |
| null != f.prev && (f.prev.next = f); | |
| null != f.next && (f.next.prev = f) | |
| } | |
| return e | |
| } catch (v) { | |
| return this._curId = g, [] | |
| } | |
| }; | |
| c.prototype.removeMirror = function(a) { | |
| a.parent.child == a && (a.parent.child = a.next); | |
| a.parent.lastChild == a && (a.parent.lastChild = a.prev); | |
| a.prev && (a.prev.next = a.next); | |
| a.next && (a.next.prev = a.prev); | |
| a.id = 0; | |
| a.child && this.clearIds(a.child) | |
| }; | |
| c.prototype.clearIds = function(a) { | |
| a.id = 0; | |
| a.next && this.clearIds(a.next); | |
| a.child && this.clearIds(a.child) | |
| }; | |
| c.prototype.tokeNode = function(c, d, l) { | |
| if ("SCRIPT" == c.nodeName || c.nodeType == a.Node_COMMENT_NODE) return null; | |
| var g = { | |
| id: this._curId++, | |
| node: c | |
| }; | |
| c._fs = g; | |
| var e = c.nodeName; | |
| "http://www.w3.org/2000/svg" == c.namespaceURI && (e = "svg:" + e); | |
| d.push("<" + e); | |
| if (this.processBlockedElem(c, | |
| d)) return g; | |
| l && l(c); | |
| b(c, function(a, b) { | |
| d.push(":" + a); | |
| d.push(b) | |
| }); | |
| if (c.firstChild) { | |
| d.push("["); | |
| for (var e = null, f = c.firstChild; f; f = f.nextSibling) { | |
| var k = this.tokeNode(f, d, l); | |
| k && (k.parent = g, e ? (e.next = k, k.prev = e) : g.child = k, e = g.lastChild = k) | |
| } | |
| d.push("]") | |
| } | |
| c.nodeType == a.Node_TEXT_NODE && d.push(c.textContent); | |
| return g | |
| }; | |
| c.prototype.processBlockedElem = function(c, d) { | |
| var l = this; | |
| if (c.nodeType == a.Node_ELEMENT_NODE && this._blocker) { | |
| var g = this._blocker.isBlocked(c); | |
| if (g) { | |
| f(c, g); | |
| var e, k = !1; | |
| b(c, function(a, b) { | |
| if ("class" == | |
| a) b += " _fs_block_" + g, e = !0; | |
| else if ("style" == a) b = l._blocker.mungeBlockedStyle(c, b), k = !0; | |
| else if ("value" == a || "checked" == a) return; | |
| d.push(":" + a); | |
| d.push(b) | |
| }); | |
| e || (d.push(":class"), d.push("_fs_block_" + g)); | |
| k || (d.push(":style"), d.push(this._blocker.mungeBlockedStyle(c, ""))); | |
| return !0 | |
| } | |
| } | |
| return !1 | |
| }; | |
| return c | |
| }(); | |
| a.NodeEncoder = l | |
| })(k || (k = {})); | |
| (function(a) { | |
| function e(a, b, d) { | |
| var g = Object.getOwnPropertyDescriptor(a.prototype, b); | |
| Object.defineProperty(a.prototype, b, { | |
| set: function(a) { | |
| var b = this; | |
| setTimeout(function() { | |
| d(b) | |
| }, | |
| 0); | |
| return g.set.call(this, a) | |
| }, | |
| get: function() { | |
| return g.get.call(this) | |
| } | |
| }) | |
| } | |
| function f(a) { | |
| switch (a.type) { | |
| case "checkbox": | |
| case "radio": | |
| return "" + a.checked; | |
| default: | |
| return a.value | |
| } | |
| } | |
| var d = function() { | |
| function a(b, c) { | |
| this._onchange = b; | |
| this._checkElem = c; | |
| this._fallback = !1; | |
| this._elems = {}; | |
| this._values = {} | |
| } | |
| a.prototype.hookEvents = function() { | |
| this.shimPrototypes() || (this._fallback = !0) | |
| }; | |
| a.prototype.addInput = function(a, c) { | |
| this._fallback && (this._elems[a] = c, this._values[a] = f(c), this._values[a] && this._onchange(c)) | |
| }; | |
| a.prototype.tick = | |
| function() { | |
| if (this._fallback) | |
| for (var a in this._elems) | |
| if (this._checkElem(this._elems[a])) { | |
| var c = this._elems[a], | |
| d = f(c); | |
| d != this._values[a] && (this._onchange(c), this._values[a] = d) | |
| } else delete this._elems[a], delete this._values[a] | |
| }; | |
| a.prototype._usingFallback = function() { | |
| return this._fallback | |
| }; | |
| a.prototype._trackingElem = function(a) { | |
| return !!this._elems[a] | |
| }; | |
| a.prototype.shimPrototypes = function() { | |
| var a = Object.getOwnPropertyDescriptor(HTMLInputElement.prototype, "value"); | |
| if (!a || !a.set) return !1; | |
| e(HTMLInputElement, | |
| "value", this._onchange); | |
| e(HTMLInputElement, "checked", this._onchange); | |
| e(HTMLSelectElement, "value", this._onchange); | |
| e(HTMLTextAreaElement, "value", this._onchange); | |
| return !0 | |
| }; | |
| return a | |
| }(); | |
| a.InputWatcher = d; | |
| a.valueOfInputishElem = f | |
| })(k || (k = {})); | |
| (function(a) { | |
| var e = function() { | |
| function a() { | |
| this.dict = { | |
| idx: -1, | |
| map: {} | |
| }; | |
| this.startIdx = 0 | |
| } | |
| a.prototype.encode = function(a) { | |
| function c() { | |
| l ? 1 < f.length ? g.push([l.idx, f.length]) : g.push(l.idx) : g.push(f[0]) | |
| } | |
| if (0 == a.length) return []; | |
| var b, l = null, | |
| g = [], | |
| e, f = [a[0]]; | |
| for (b = 1; b < a.length; b++) | |
| if (e = | |
| a[b], l && l.map.hasOwnProperty(e)) f.push(e), l = l.map[e]; | |
| else { | |
| c(); | |
| var h = this.startIdx + b - f.length; | |
| null == l && (l = { | |
| idx: h, | |
| map: {} | |
| }, this.dict.map[f[f.length - 1]] = l); | |
| l.map[e] = { | |
| idx: h, | |
| map: {} | |
| }; | |
| f = [e]; | |
| l = this.dict.map.hasOwnProperty(e) ? this.dict.map[e] : null | |
| } | |
| c(); | |
| this.startIdx += a.length; | |
| return g | |
| }; | |
| return a | |
| }(); | |
| a.LZJGWEncoder = e; | |
| e = function() { | |
| function a() { | |
| this._seq = [] | |
| } | |
| a.prototype.sequence = function() { | |
| return this._seq | |
| }; | |
| a.prototype.decode = function(a) { | |
| for (var c = this._seq.length, b = 0; b < a.length; ++b) { | |
| var l = a[b]; | |
| switch (typeof l) { | |
| case "string": | |
| this._seq.push(l); | |
| break; | |
| case "number": | |
| this._seq.push(this._seq[l]); | |
| break; | |
| case "object": | |
| for (var g = 0; g < l[1]; g++) this._seq.push(this._seq[l[0] + g]) | |
| } | |
| } | |
| return c | |
| }; | |
| return a | |
| }(); | |
| a.LZJGWDecoder = e | |
| })(k || (k = {})); | |
| (function(a) { | |
| a.EVENT_PROCESSING_INTERVAL = 250; | |
| a.UPLOAD_INTERVAL = 5E3; | |
| a.USER_INACTIVITY_TIMEOUT = 1E4; | |
| var e = function() { | |
| function a(c) { | |
| this._interval = c; | |
| this._handle = -1 | |
| } | |
| a.prototype.oneShot = function(a) { | |
| setTimeout(a, this._interval) | |
| }; | |
| a.prototype.start = function(a) { | |
| -1 == this._handle && (this._handle = setInterval(a, this._interval)) | |
| }; | |
| a.prototype.stop = | |
| function() { | |
| -1 != this._handle && (clearInterval(this._handle), this._handle = -1) | |
| }; | |
| return a | |
| }(), | |
| f = function() { | |
| function d(c, b, d, g, f, k) { | |
| "undefined" === typeof g && (g = function() {}); | |
| "undefined" === typeof f && (f = new e(a.EVENT_PROCESSING_INTERVAL)); | |
| "undefined" === typeof k && (k = new e(a.UPLOAD_INTERVAL)); | |
| this._ctx = c; | |
| this._processor = b; | |
| this._mutProvider = d; | |
| this._beforeProcessEvents = g; | |
| this._processEventsTicker = f; | |
| this._uploadTicker = k; | |
| this._eventQueue = []; | |
| this._outgoingQueue = []; | |
| this._bundleQueue = []; | |
| this._recordingDisabled = !1; | |
| this._bundleSeq = | |
| 1; | |
| this._lastWhenTime = this._lastPostTime = 0; | |
| this._lastWhen = -1; | |
| this._lastUserAction = 0; | |
| this._lastBundleTime = c.wallTime() | |
| } | |
| d.prototype.rawQueue = function() { | |
| return this._eventQueue | |
| }; | |
| d.prototype.startPipeline = function() { | |
| var a = this; | |
| this._recordingDisabled || this._pipelineStarted || (this.processEvents(), this._processEventsTicker.start(function() { | |
| a.processEvents() | |
| }), this._ctx.amInsideIFrame() || this._uploadTicker.start(function() { | |
| a.enqueueNextBundle() | |
| }), this._pipelineStarted = !0) | |
| }; | |
| d.prototype.enqueue = function(a, | |
| b) { | |
| this.enqueueAt(this._ctx.now(), a, b) | |
| }; | |
| d.prototype.enqueueAt = function(c, b, d) { | |
| this._recordingDisabled || (c <= this._lastWhen && (c = this._lastWhen + 1), this._lastWhen = c, this._eventQueue.push({ | |
| When: c, | |
| Kind: b, | |
| Args: d | |
| }), a.isUserActionEvent(b) && (this._lastUserAction = c)) | |
| }; | |
| d.prototype.disableRecording = function() { | |
| this._recordingDisabled = !0; | |
| this.stopPipeline() | |
| }; | |
| d.prototype.shutdown = function() { | |
| this.processEvents(); | |
| this.maybeSendNextBundle(); | |
| this.disableRecording() | |
| }; | |
| d.prototype.prequeue = function(a, b) { | |
| this._recordingDisabled || | |
| this._eventQueue.unshift({ | |
| When: 0, | |
| Kind: a, | |
| Args: b | |
| }) | |
| }; | |
| d.prototype.appendToOutgoingQueue = function(a) { | |
| this._outgoingQueue = this._outgoingQueue.concat(a) | |
| }; | |
| d.prototype.lastSentEventTime = function() { | |
| return this._lastWhenTime | |
| }; | |
| d.prototype.swanSong = function() { | |
| if (!this._recordingDisabled && !this._ctx.amInsideIFrame() && (this.processEvents(), this.enqueueNextBundle(), 0 < this._bundleQueue.length || this._pendingBundle)) { | |
| var c = this._bundleQueue.concat(); | |
| this._pendingBundle && c.unshift(this._pendingBundle); | |
| a.log("Saving " + | |
| c.length + " bundles in swan-song."); | |
| c = { | |
| UserId: this._ctx.userId(), | |
| SessionId: this._ctx.sessionId(), | |
| PageId: this._ctx.pageId(), | |
| Bundles: c, | |
| PageStartTime: this._ctx.startTime(), | |
| LastBundleTime: this._lastBundleTime | |
| }; | |
| try { | |
| localStorage.swanSong = a.stringify(c) | |
| } catch (b) {} | |
| } | |
| }; | |
| d.prototype.recoverSwanSong = function() { | |
| if (!this._ctx.amInsideIFrame()) try { | |
| if ("swanSong" in localStorage) { | |
| var c = localStorage.swanSong; | |
| delete localStorage.swanSong; | |
| var b = JSON.parse(c); | |
| if (b.Bundles) | |
| if (b.Bundles && b.UserId && b.SessionId && b.PageId) | |
| for (c = | |
| 0; c < b.Bundles.length; ++c) { | |
| var d = null; | |
| 0 == c && (d = this._ctx.wallTime() - b.LastBundleTime); | |
| this.sendSwanSongBundle(b.UserId, b.SessionId, b.PageId, b.PageStartTime, b.Bundles[c], d) | |
| } else a.log("Malformed swan song found. Ignoring it."); | |
| else b.Bundle && b.UserId && b.SessionId && b.PageId ? this.sendSwanSongBundle(b.UserId, b.SessionId, b.PageId, b.PageStartTime || 0, b.Bundle, b.LastBundleTime ? this._ctx.wallTime() - b.LastBundleTime : null) : a.log("Malformed swan song found. Ignoring it.") | |
| } | |
| } catch (g) { | |
| a.log("Error recovering swan-song: " + | |
| g) | |
| } | |
| }; | |
| d.prototype.sendSwanSongBundle = function(c, b, d, g, e, f) { | |
| c = "/rec/bundle?OrgId=" + this._ctx.orgId() + "&UserId=" + c + "&SessionId=" + b + "&PageId=" + d + "&Seq=" + e.Seq; | |
| 0 != g && (c += "&PageStartTime=" + g); | |
| f && (c += "&DeltaT=" + f); | |
| this._ctx.post(c, e, function(b) { | |
| a.log("Sent " + e.Evts.length + " trailing events from last session as Seq " + e.Seq) | |
| }, function() { | |
| a.log("Failed to send events from last session") | |
| }) | |
| }; | |
| d.prototype.rebaseIframe = function(c) { | |
| var b = this._ctx.baseUri(); | |
| 0 < this._eventQueue.length ? this._eventQueue.unshift({ | |
| When: this._eventQueue[0].When, | |
| Kind: a.EVENT_SET_FRAME_BASE, | |
| Args: [b] | |
| }) : this.enqueue(a.EVENT_SET_FRAME_BASE, [b]); | |
| for (var b = 0, d = this._eventQueue.length; b < d; b++) { | |
| var e = this._eventQueue[b], | |
| f = e.When + this._ctx.startTime() - c; | |
| 0 > f && (f = 0); | |
| e.When = f | |
| } | |
| }; | |
| d.prototype.processEvents = function() { | |
| this._beforeProcessEvents(); | |
| if ((this._eventQueue.length || this._mutProvider.hasMutations()) && !(this._ctx.now() - this._lastUserAction > a.USER_INACTIVITY_TIMEOUT)) { | |
| var c = this._eventQueue; | |
| this._eventQueue = []; | |
| c = this._processor.processQueue(c).concat(this._mutProvider.processMutations()); | |
| this.ensureFrameIds(c); | |
| this._ctx.amInsideIFrame() ? parent.postMessage(a.FS_IFRAME_EVENTS + a.FS_DELIMITER + a.stringify(c), "*") : void 0 !== this._ctx.pageId() && (this._outgoingQueue = this._outgoingQueue.concat(c)) | |
| } | |
| }; | |
| d.prototype.ensureFrameIds = function(a) { | |
| var b = this._ctx.frameId(); | |
| if (b) | |
| for (var d = 0; d < a.length; ++d) a[d].FId = b | |
| }; | |
| d.prototype.enqueueNextBundle = function() { | |
| if (0 == this._outgoingQueue.length) return this.maybeSendNextBundle(), null; | |
| var a = { | |
| When: this._outgoingQueue[0].When, | |
| Seq: this._bundleSeq++, | |
| Evts: this._outgoingQueue | |
| }; | |
| this._outgoingQueue = []; | |
| this._bundleQueue.push(a); | |
| this.maybeSendNextBundle() | |
| }; | |
| d.prototype.maybeSendNextBundle = function() { | |
| var c = this; | |
| if (!this._pendingBundle && 0 != this._bundleQueue.length) { | |
| var b = this._pendingBundle = this._bundleQueue.shift(), | |
| d = this._ctx.wallTime(), | |
| e = "/rec/bundle?OrgId=" + this._ctx.orgId() + "&UserId=" + this._ctx.userId() + "&SessionId=" + this._ctx.sessionId() + "&PageId=" + this._ctx.pageId() + "&Seq=" + b.Seq + "&DeltaT=" + (d - this._lastBundleTime); | |
| this._lastPostTime = this._lastBundleTime = d; | |
| this._lastWhenTime = | |
| b.Evts[b.Evts.length - 1].When; | |
| var f = function() { | |
| c._ctx.post(e, b, function(d) { | |
| a.log("Sent bundle " + b.Seq + " with " + b.Evts.length + " events"); | |
| c._pendingBundle = null; | |
| c._ctx.wallTime() - c._lastPostTime > a.UPLOAD_INTERVAL && c.maybeSendNextBundle() | |
| }, function(b) { | |
| a.log("Failed to send events."); | |
| if (404 != b) c._uploadTicker.oneShot(f) | |
| }) | |
| }; | |
| f() | |
| } | |
| }; | |
| d.prototype.stopPipeline = function() { | |
| this._pipelineStarted && (this._processEventsTicker.stop(), this._uploadTicker.stop()) | |
| }; | |
| return d | |
| }(); | |
| a.EventQueue = f | |
| })(k || (k = {})); | |
| (function(a) { | |
| var e = | |
| function() { | |
| function e(d, c, b) { | |
| "undefined" === typeof b && (b = function(a, b) {}); | |
| this._ctx = d; | |
| this._blocker = c; | |
| this._visitor = b; | |
| this._sentDomSnapshot = !1; | |
| this._records = []; | |
| this._lz = new a.LZJGWEncoder; | |
| this._encoder = new a.NodeEncoder(d, c) | |
| } | |
| e.prototype.hasMutations = function() { | |
| return !this._sentDomSnapshot || 0 < this._records.length | |
| }; | |
| e.prototype.hookMutations = function(a) { | |
| var c = this; | |
| "undefined" === typeof a && (a = document.documentElement); | |
| this._root = a; | |
| this._sentDomSnapshot = !1; | |
| (new window.MutationObserver(function(a) { | |
| c._records = | |
| c._records.concat(a) | |
| })).observe(a, { | |
| childList: !0, | |
| attributes: !0, | |
| characterData: !0, | |
| subtree: !0, | |
| attributeOldValue: !0, | |
| characterDataOldValue: !0 | |
| }) | |
| }; | |
| e.prototype.processMutations = function() { | |
| var d = this._ctx.now(), | |
| c = []; | |
| this._sentDomSnapshot || (this.genInsert(d, c, null, this._root, null), this._sentDomSnapshot = !0); | |
| if (0 == this._records.length) return c; | |
| var b = {}, | |
| e = {}; | |
| this.processRecords(d, c, e, b); | |
| for (var g in e) { | |
| var f = g.split(":"); | |
| c.push({ | |
| Kind: a.EVENT_MUT_ATTR, | |
| When: d, | |
| Args: [parseInt(f[0]), f[1], e[g]] | |
| }) | |
| } | |
| for (g in b) c.push({ | |
| Kind: a.EVENT_MUT_TEXT, | |
| When: d, | |
| Args: [parseInt(g), b[g]] | |
| }); | |
| this._records = []; | |
| return c | |
| }; | |
| e.prototype.processRecords = function(d, c, b, e) { | |
| for (var g = {}, f = {}, k = 0; k < this._records.length; ++k) { | |
| var h = this._records[k], | |
| r = a.fsid(h.target); | |
| if (r) switch (g[r] = h.target, h.type) { | |
| case "childList": | |
| if (0 < h.removedNodes.length) | |
| for (var p = 0; p < h.removedNodes.length; ++p) { | |
| var n = a.mirrorFor(h.removedNodes[p]); | |
| n && n.id && n.parent == a.mirrorFor(h.target) && n.next == a.mirrorFor(h.nextSibling) && this.genRemove(d, c, n) | |
| } | |
| r && (f[r] = h.target); | |
| break; | |
| case "characterData": | |
| p = | |
| h.target.textContent; | |
| h.oldValue != p && (a.isBlocked(h.target) || (e[r] = p)); | |
| break; | |
| case "attributes": | |
| n = h.attributeName, h.target.hasAttribute(n) ? (p = h.target.getAttribute(n), h.oldValue != p && (p = this.rewriteAttr(h.target, n, p), null !== p && (b[r + ":" + n] = p))) : b[r + ":" + n] = null | |
| } | |
| } | |
| for (var t in f) b = f[t], (e = a.mirrorFor(b)) && e.id && this.diff(d, c, b, e.child, b.firstChild); | |
| for (t in g) b = g[t], this.maybeAddPlaceholderResize(d, c, b) | |
| }; | |
| e.prototype.diff = function(d, c, b, e, g) { | |
| for (; e && g;) { | |
| var f = a.mirrorFor(g); | |
| a.fsid(g) ? e.id == f.id ? (e = e.next, | |
| g = g.nextSibling) : (this.genRemove(d, c, e), e = e.next) : (this.genInsert(d, c, b, g, e.node), g = g.nextSibling) | |
| } | |
| for (; e; e = e.next) this.genRemove(d, c, e); | |
| for (; g; g = g.nextSibling) this.genInsert(d, c, b, g, null) | |
| }; | |
| e.prototype.maybeAddPlaceholderResize = function(d, c, b) { | |
| for (; b && !a.fsid(b);) b = b.parentNode; | |
| if (b && a.isBlocked(b)) { | |
| var e = b.getBoundingClientRect(), | |
| g = Math.floor(e.width), | |
| e = Math.floor(e.height); | |
| c.push({ | |
| When: d, | |
| Kind: a.EVENT_PLACEHOLDER_SIZE, | |
| Args: [a.fsid(b), g, e] | |
| }) | |
| } | |
| }; | |
| e.prototype.genInsert = function(d, c, b, e, g) { | |
| var f = this; | |
| if (b && a.isBlocked(b)) return null; | |
| e = this._encoder.tokenizeNode(b, g, e, function(a) { | |
| f._visitor(d, a) | |
| }); | |
| 0 < e.length && c.push({ | |
| When: d, | |
| Kind: a.EVENT_MUT_INSERT, | |
| Args: [a.fsid(b) || -1, a.fsid(g) || -1, this._lz.encode(e)] | |
| }) | |
| }; | |
| e.prototype.genRemove = function(e, c, b) { | |
| var f = b.id; | |
| this._encoder.removeMirror(b); | |
| if (0 < c.length && (b = c[c.length - 1], b.Kind == a.EVENT_MUT_REMOVE)) { | |
| b.Args.push(f); | |
| return | |
| } | |
| c.push({ | |
| When: e, | |
| Kind: a.EVENT_MUT_REMOVE, | |
| Args: [f] | |
| }) | |
| }; | |
| e.prototype.rewriteAttr = function(e, c, b) { | |
| switch (c) { | |
| case "style": | |
| a.isBlocked(e) && (b = | |
| this._blocker.mungeBlockedStyle(e, b)); | |
| break; | |
| case "class": | |
| a.isBlocked(e) && 0 > b.indexOf("_fs_block_") && (e = a.blockKind(e), b += " _fs_block_" + e); | |
| break; | |
| case "value": | |
| a.isBlocked(e) && (b = null) | |
| } | |
| return b | |
| }; | |
| return e | |
| }(); | |
| a.MutationHandler = e | |
| })(k || (k = {})); | |
| (function(a) { | |
| var e = function() { | |
| function a(c, b, e) { | |
| this._ctx = c; | |
| this._q = b; | |
| this._valueIndices = e; | |
| this._evts = [] | |
| } | |
| a.prototype.add = function(a) { | |
| 0 == this._evts.length && this._q.push(a); | |
| this._evts.push(a) | |
| }; | |
| a.prototype.finish = function(a, b) { | |
| var e = this._evts.length; | |
| if (1 >= e) return !1; | |
| for (var d = this._evts[0].When, f = this._evts[e - 1].When, k = 0; k < this._valueIndices.length; ++k) { | |
| var h = this._valueIndices[k], | |
| r = this._evts[0].Args[h], | |
| p = (this._evts[1].When - d) / (f - d), | |
| n = (this._evts[1].Args[h] - r) / p, | |
| t = this._evts[e - 1].Args[h], | |
| p = (f - this._evts[e - 2].When) / (f - d); | |
| b.push(r, t, n, (t - this._evts[e - 2].Args[h]) / p) | |
| } | |
| this._evts[0].Kind = a; | |
| this._evts[0].Args = b; | |
| return !0 | |
| }; | |
| a.prototype.evts = function() { | |
| return this._evts | |
| }; | |
| return a | |
| }(), | |
| f = function() { | |
| function d(a, b) { | |
| this._ctx = a; | |
| this._blocker = b; | |
| this._gotInitialScroll = !1 | |
| } | |
| d.prototype.processQueue = | |
| function(c) { | |
| if (0 == c.length) return c; | |
| this.maybeAddInitialScroll(); | |
| for (var b = this._ctx.now(), d = [], f = new e(this._ctx, d, [0, 1]), k = {}, s = {}, h, r = 0; r < c.length; ++r) { | |
| var p = c[r]; | |
| switch (p.Kind) { | |
| case a.EVENT_MOUSEMOVE: | |
| f.add(p); | |
| break; | |
| case a.EVENT_TOUCHMOVE: | |
| var n = p.Args[0]; | |
| n in k || (k[n] = new e(this._ctx, d, [1, 2])); | |
| k[n].add(p); | |
| break; | |
| case a.EVENT_SCROLL: | |
| n = p.Args[0]; | |
| n in s || (s[n] = new e(this._ctx, d, [1, 2])); | |
| s[n].add(p); | |
| break; | |
| case a.EVENT_INNERWIDTH: | |
| h || (h = new e(this._ctx, d, [0])); | |
| h.add(p); | |
| break; | |
| default: | |
| d.push(p) | |
| } | |
| } | |
| f.finish(a.EVENT_MOUSEMOVE_CURVE, [b]) && (c = f.evts(), f = c[c.length - 1].Args, 2 < f.length && f[2] && c[0].Args.push(f[2])); | |
| for (n in s) c = parseInt(n), s[c].finish(a.EVENT_SCROLL_CURVE, [b, c]); | |
| for (n in k) c = parseInt(n), k[c].finish(a.EVENT_TOUCHMOVE_CURVE, [b, c]); | |
| h && h.finish(a.EVENT_INNERWIDTH_CURVE, [b]); | |
| return d | |
| }; | |
| d.prototype.maybeAddInitialScroll = function() { | |
| !this._gotInitialScroll && (document.body && a.fsid(document.body)) && (this._ctx.addWindowScroll(), this._gotInitialScroll = !0) | |
| }; | |
| return d | |
| }(); | |
| a.EventProcessor = f | |
| })(k || (k = {})); | |
| (function(a) { | |
| function e(a) { | |
| E && | |
| console && console.log(a) | |
| } | |
| function f(a) { | |
| var b = Array.prototype.toJSON, | |
| c = String.prototype.toJSON; | |
| b && delete Array.prototype.toJSON; | |
| c && delete String.prototype.toJSON; | |
| a = JSON.stringify(a); | |
| b && (Array.prototype.toJSON = b); | |
| c && (String.prototype.toJSON = c); | |
| return a | |
| } | |
| function d() { | |
| return (new Date).getTime() | |
| } | |
| function c() { | |
| return window != top && !R | |
| } | |
| function b(b, c, d, g) { | |
| "undefined" === typeof g && (g = null); | |
| b = "//" + A + b; | |
| var k = null; | |
| null != c && (k = f(c), H += k.length, e("total bytes written: " + H)); | |
| var h = new XMLHttpRequest; | |
| if ("withCredentials" in | |
| h) h.onreadystatechange = function() { | |
| h.readyState == a.XHR_DONE && (200 == h.status ? d(h.responseText) : g(h.status)) | |
| }, h.open("POST", "https:" + b, !0), h.withCredentials = !0, h.setRequestHeader("Content-Type", "text/plain"), h.send(k); | |
| else { | |
| var l = new XDomainRequest; | |
| l.onload = function() { | |
| d(l.responseText) | |
| }; | |
| l.onerror = function() { | |
| g("Not Found" == l.responseText ? 404 : 500) | |
| }; | |
| l.onprogress = function() {}; | |
| l.open("POST", b); | |
| l.send(k) | |
| } | |
| } | |
| function k() { | |
| if ("baseURI" in document) return document.baseURI; | |
| var a = document.getElementsByTagName("base")[0]; | |
| return a && a.href ? a.href : location.href | |
| } | |
| function g(a) { | |
| (a = a.target.tagName) && (a = a.toLowerCase()); | |
| return a | |
| } | |
| function q(a, b) { | |
| return a.tagName && a.tagName.toLowerCase() in b ? !0 : a.parentNode ? q(a.parentNode, b) : !1 | |
| } | |
| function s(a, b) { | |
| for (var c = 0; c < a.changedTouches.length; ++c) { | |
| var e = a.changedTouches[c]; | |
| m.enqueue(b, [e.identifier, e.clientX, e.clientY]) | |
| } | |
| } | |
| function h() { | |
| var b = document.activeElement; | |
| if (b && "value" in b) { | |
| var c = a.fsidIfNotBlocked(b); | |
| c && m.enqueue(a.EVENT_VALUECHANGE, [c, b.value]) | |
| } | |
| } | |
| function r() { | |
| var b = a.fsid(document.body); | |
| if (b) { | |
| var c, e; | |
| "pageXOffset" in window ? (c = window.pageXOffset, e = window.pageYOffset) : (c = document.body.scrollLeft, e = document.body.scrollTop); | |
| if (c != S || e != T) m.enqueue(a.EVENT_SCROLL, [b, c, e]), S = c, T = e | |
| } | |
| p() | |
| } | |
| function p() { | |
| var b = window.innerWidth; | |
| b != U && (m.enqueue(a.EVENT_INNERWIDTH, [b]), U = b) | |
| } | |
| function n() { | |
| m.enqueue(a.EVENT_RESIZE, [document.documentElement.clientWidth, document.documentElement.clientHeight]) | |
| } | |
| function t() { | |
| var b = location.href; | |
| I != b && (I = b, m.enqueue(a.EVENT_NAVIGATE, [location.href, document.title])) | |
| } | |
| function u(b) { | |
| var c = | |
| a.fsidIfNotBlocked(b); | |
| c && m.enqueue(a.EVENT_VALUECHANGE, [c, a.valueOfInputishElem(b)]) | |
| } | |
| function y() { | |
| V || (V = !0, m.enqueue(a.EVENT_UNLOAD, []), m.swanSong()) | |
| } | |
| function v(b, c) { | |
| for (var e = [b], d = 0; d < c.length; ++d) { | |
| try { | |
| var g = f(c[d]) | |
| } catch (h) { | |
| g = f(c[d].toString()) | |
| } | |
| e.push(g) | |
| } | |
| m.enqueue(a.EVENT_LOG, e) | |
| } | |
| function ea() { | |
| for (var a = {}, b = document.cookie.split(";"), c = 0; c < b.length; c++) { | |
| var e = b[c].replace(/^\s+|\s+$/g, "").split("="); | |
| a[e[0]] = e[1] | |
| } | |
| return a.fs_uid | |
| } | |
| function N(a) { | |
| x = a.UserIntId; | |
| F = a.SessionIntId; | |
| J = a.PageIntId; | |
| W = a.CookieDomain; | |
| X = a.EmbedToken; | |
| document.cookie = "fs_uid=" + x + "; domain=." + encodeURIComponent(W) + "; expires=expires=Fri, 31 Dec 9999 23:59:59 GMT; path=/"; | |
| e("/User," + x + "/Session," + F + "/Page," + J) | |
| } | |
| function O() { | |
| var a = document.doctype; | |
| if (!a) return null; | |
| var b; | |
| b = "<!DOCTYPE " + a.name; | |
| a.publicId && (b += ' PUBLIC "' + a.publicId + '"'); | |
| a.systemId && (b += ' "' + a.systemId + '"'); | |
| return b + ">" | |
| } | |
| function fa() { | |
| (x = ea()) || (x = ""); | |
| var c = document.documentElement, | |
| d = window._fs_hash, | |
| g = window._fs_force_session, | |
| h = window._fs_get_embed; | |
| I = location.href; | |
| if (G) c = { | |
| OrgId: z, | |
| UserId: x, | |
| Url: location.href, | |
| Base: k(), | |
| ScreenWidth: window.screen.width, | |
| ScreenHeight: window.screen.height, | |
| Width: c.clientWidth, | |
| Height: c.clientHeight, | |
| Referrer: document.referrer, | |
| Doctype: O(), | |
| Hash: d | |
| }, h && (c.GetEmbed = !0), g && (c.ForceNewSession = !0), b("/rec/page", c, function(b) { | |
| try { | |
| var c = JSON.parse(b) | |
| } catch (e) { | |
| P(); | |
| return | |
| } | |
| N(c); | |
| m.prequeue(a.EVENT_SYS_SETVAR, ["user", f(c.InitSetUserVars), !0]); | |
| window._fs_ready && window._fs_ready(); | |
| for (b = 0; b < c.Blocks.length; ++b) w.addRule(c.Blocks[b]); | |
| m.startPipeline() | |
| }, function(a) { | |
| P() | |
| }); | |
| else { | |
| e("Unable to record playback stream."); | |
| var n = document.createElement("script"); | |
| window.__fs_startResponse = function(a) { | |
| N(a); | |
| document.body.removeChild(n) | |
| }; | |
| n.src = "//" + A + "/rec/page?OrgId=" + z + "&UserId=" + x + "&Url=" + encodeURIComponent(location.href) + "&Base=" + encodeURIComponent(k()) + "&ScreenWidth=" + window.screen.width + "&ScreenHeight=" + window.screen.height + "&Width=" + c.clientWidth + "&Height=" + c.clientHeight + "&Referrer=" + encodeURIComponent(document.referrer) + "&Doctype=" + encodeURIComponent(O()) + "&Fallback=true" + | |
| (g ? "&ForceNewSession=true" : "") + (h ? "&GetEmbed=true" : "") + (d ? "&Hash=" + d : ""); | |
| document.body.appendChild(n) | |
| } | |
| } | |
| function P() { | |
| m.disableRecording(); | |
| Y(); | |
| e("Disabling FS."); | |
| window._fs_ready && window._fs_ready(!0) | |
| } | |
| function ga() { | |
| Z.hookMutations(); | |
| document.documentElement.addEventListener("scroll", function(b) { | |
| b = b.target; | |
| var c = a.fsid(b); | |
| c && m.enqueue(a.EVENT_SCROLL, [c, b.scrollLeft, b.scrollTop]) | |
| }, !0); | |
| window.addEventListener("mousemove", function(b) { | |
| b = a.fsid(b.target) ? [b.clientX, b.clientY, a.fsid(b.target)] : [b.clientX, | |
| b.clientY | |
| ]; | |
| m.enqueue(a.EVENT_MOUSEMOVE, b) | |
| }, !0); | |
| window.addEventListener("mousedown", function(b) { | |
| m.enqueue(a.EVENT_MOUSEDOWN, [b.clientX, b.clientY]); | |
| !q(b.target, { | |
| button: !0, | |
| a: !0, | |
| input: !0 | |
| }) || "input" == g(b) && "submit" != b.target.type || m.swanSong() | |
| }, !0); | |
| window.addEventListener("mouseup", function(b) { | |
| m.enqueue(a.EVENT_MOUSEUP, [b.clientX, b.clientY]) | |
| }, !0); | |
| window.addEventListener("keydown", function(b) { | |
| h(); | |
| var c = document.activeElement; | |
| c && !a.fsidIfNotBlocked(c) || m.enqueue(a.EVENT_KEYDOWN, [b.keyCode]); | |
| switch (g(b)) { | |
| case "button": | |
| 13 != | |
| b.keyCode && 32 != b.keyCode || m.swanSong(); | |
| break; | |
| case "a": | |
| 13 == b.keyCode && m.swanSong(); | |
| break; | |
| case "input": | |
| "submit" == b.target.type && 13 == b.keyCode && m.swanSong() | |
| } | |
| }, !0); | |
| window.addEventListener("keyup", function(b) { | |
| h(); | |
| var c = document.activeElement; | |
| c && !a.fsidIfNotBlocked(c) || m.enqueue(a.EVENT_KEYUP, [b.keyCode]) | |
| }, !0); | |
| window.addEventListener("scroll", function(a) { | |
| r() | |
| }); | |
| window.addEventListener("resize", function(a) { | |
| n() | |
| }); | |
| document.body.addEventListener("click", function(b) { | |
| (b = a.fsid(b.target)) && m.enqueue(a.EVENT_CLICK, [b]) | |
| }, !0); | |
| document.body.addEventListener("focus", function(b) { | |
| (b = a.fsid(b.target)) && m.enqueue(a.EVENT_FOCUS, [b]) | |
| }, !0); | |
| document.body.addEventListener("blur", function(b) { | |
| (b = a.fsid(b.target)) && m.enqueue(a.EVENT_BLUR, [b]) | |
| }, !0); | |
| document.body.addEventListener("change", function(a) { | |
| u(a.target) | |
| }, !0); | |
| window.addEventListener("touchstart", function(b) { | |
| s(b, a.EVENT_TOUCHSTART); | |
| r() | |
| }, !0); | |
| window.addEventListener("touchend", function(b) { | |
| s(b, a.EVENT_TOUCHEND); | |
| r() | |
| }, !0); | |
| window.addEventListener("touchmove", function(b) { | |
| s(b, | |
| a.EVENT_TOUCHMOVE); | |
| r() | |
| }, !0); | |
| window.addEventListener("touchcancel", function(b) { | |
| s(b, a.EVENT_TOUCHCANCEL) | |
| }, !0); | |
| window.addEventListener("play", function(b) { | |
| var c = a.EVENT_PLAY; | |
| (b = a.fsid(b.target)) && m.enqueue(c, [b]) | |
| }, !0); | |
| window.addEventListener("pause", function(b) { | |
| var c = a.EVENT_PAUSE; | |
| (b = a.fsid(b.target)) && m.enqueue(c, [b]) | |
| }, !0); | |
| K.hookEvents(); | |
| if (history.pushState) { | |
| window.addEventListener("popstate", function() { | |
| t() | |
| }); | |
| var b = history.pushState; | |
| history.pushState = function(a, c, e) { | |
| b.call(this, a, c, e); | |
| t() | |
| }; | |
| var c = history.replaceState; | |
| history.replaceState = function(a, b, e) { | |
| c.call(this, a, b, e); | |
| t() | |
| } | |
| } | |
| var e = console.log, | |
| d = console.info, | |
| f = console.warn, | |
| k = console.error; | |
| console.log = function() { | |
| v("log", arguments); | |
| return e.apply(this, arguments) | |
| }; | |
| console.info = function() { | |
| v("info", arguments); | |
| return d.apply(this, arguments) | |
| }; | |
| console.warn = function() { | |
| v("warn", arguments); | |
| return f.apply(this, arguments) | |
| }; | |
| console.error = function() { | |
| v("error", arguments); | |
| return k.apply(this, arguments) | |
| }; | |
| var l = window.onerror; | |
| window.onerror = function(b, c, e) { | |
| m.enqueue(a.EVENT_ERROR, [b, c, e]); | |
| if (l) return l.apply(this, arguments) | |
| } | |
| } | |
| function ha() { | |
| var b = !1, | |
| e = function() { | |
| b || (b = !0, m.enqueue(a.EVENT_DOMLOADED, []), ga(), n()) | |
| }, | |
| d = !1, | |
| f = function() { | |
| d || (d = !0, m.enqueue(a.EVENT_LOAD, [])) | |
| }; | |
| switch (document.readyState) { | |
| case "interactive": | |
| document.attachEvent || e(); | |
| break; | |
| case "complete": | |
| e(), f() | |
| } | |
| b || document.addEventListener("DOMContentLoaded", function(a) { | |
| e() | |
| }); | |
| d || window.addEventListener("load", function(a) { | |
| e(); | |
| f() | |
| }); | |
| c() || (window.addEventListener("beforeunload", function(a) { | |
| y() | |
| }), window.addEventListener("unload", | |
| function(a) { | |
| y() | |
| })) | |
| } | |
| function Q(b, c) { | |
| var d = {}, | |
| g; | |
| for (g in c) | |
| if (c.hasOwnProperty(g)) { | |
| var h = c[g]; | |
| e("set-var(" + b + '): "' + g + '" = ' + f(h)); | |
| "user" != b && e('invalid scope "' + b + '"; only "user" is supported at present'); | |
| var k; | |
| if (g in $) k = $[g]; | |
| else { | |
| k = g.split("_"); | |
| if (2 != k.length) { | |
| e('variables must be of the form "name_type", where "type" is one of [str, bool, int, real, date]'); | |
| continue | |
| } | |
| k = k[1] | |
| } | |
| k in aa ? aa[k](h) ? ("date" == k && (h = (h.constructor === Date ? h : new Date(h)).toISOString()), d[g] = h) : e("illegal value " + f(h) + " for type " + | |
| k) : e('invalid type "' + k + '"') | |
| } | |
| m.enqueue(a.EVENT_SYS_SETVAR, [b, f(d)]) | |
| } | |
| function ba() { | |
| return x + ":" + F | |
| } | |
| function ia() { | |
| window.addEventListener("message", function(b) { | |
| if ("string" == typeof b.data && 0 == b.data.indexOf(a.FS_MESSAGE_PREFIX)) { | |
| var c = b.data.split(a.FS_DELIMITER); | |
| if (c[0] == a.FS_SET_FRAME_ID_CMD) try { | |
| var d = parseInt(c[1]), | |
| f = parseInt(c[2]); | |
| var g = JSON.parse(c[3]); | |
| if (d) { | |
| e("iframe recording. FrameId: " + d); | |
| D = d; | |
| for (c = 0; c < g.length; ++c) w.addRule(g[c]); | |
| m.rebaseIframe(f); | |
| B = f; | |
| m.startPipeline() | |
| } else e("Outer page gave us a bogus frame Id! Iframe: " + | |
| location.href) | |
| } catch (h) { | |
| e("Failed to parse frameId from message" + b.data) | |
| } else c[0] == a.FS_DISABLE_RECORDING ? (m.disableRecording(), Y()) : e("Invalid _fs postmessage command" + c[0]) | |
| } | |
| }); | |
| D || (0 == D ? e("For some reason the outer window attempted to request a frameId") : parent.postMessage(a.FS_REQUEST_FRAME_ID + a.FS_DELIMITER, "*")) | |
| } | |
| function Y() { | |
| for (var b = 0; b < C.length; b++) { | |
| var c = C[b]; | |
| c.contentWindow && c.contentWindow.postMessage && c.contentWindow.postMessage(a.FS_DISABLE_RECORDING, "*") | |
| } | |
| } | |
| function ja() { | |
| window.addEventListener("message", | |
| function(b) { | |
| if ("string" == typeof b.data && 0 == b.data.indexOf(a.FS_MESSAGE_PREFIX)) { | |
| var c = b.data.split(a.FS_DELIMITER); | |
| if (c[0] == a.FS_IFRAME_EVENTS) { | |
| if (b = JSON.parse(c[1]), 0 < b.length) { | |
| var c = m.lastSentEventTime(), | |
| d = ca[b[0].FId]; | |
| c < d && (c = d); | |
| if (b[0].When < c) | |
| for (var c = c - b[0].When, d = 0, g = b.length; d < g; d++) b[d].When += c; | |
| m.appendToOutgoingQueue(b) | |
| } | |
| } else if (c[0] == a.FS_REQUEST_FRAME_ID) { | |
| a: { | |
| c = b.source; | |
| for (d = 0; d < C.length; d++) | |
| if (C[d].contentWindow == c) { | |
| c = a.fsid(C[d]); | |
| break a | |
| } | |
| e("Unable to locate frame for window"); | |
| c = NaN | |
| } | |
| c ? | |
| (d = f(w.rawRules), b.source.postMessage(a.FS_SET_FRAME_ID_CMD + a.FS_DELIMITER + c + a.FS_DELIMITER + B + a.FS_DELIMITER + d, "*")) : e("No FrameId found. Hoping to send one later.") | |
| } else e("Invalid _fs postmessage command" + c[0]) | |
| } | |
| }) | |
| } | |
| function L(a) { | |
| try { | |
| var b = a.contentDocument; | |
| "_fs" in a.contentDocument && e("FS already defined in iframe. Aborting injection."); | |
| a.contentDocument._fs = !0; | |
| a = "var _fs_org='" + z + "', _fs_host='" + A + "', _fs_run_in_iframe=true, _fs_debug=" + E + "; (function(w,a,t){a=w.createElement('script');a.async=1;a.src='https://'+_fs_host+'/s/fs.js';w.head.appendChild(a)})(document);"; | |
| var c = b.createElement("script"); | |
| c.textContent = a; | |
| b.head.appendChild(c) | |
| } catch (d) { | |
| e("iFrame no injecty. Probably not same origin.") | |
| } | |
| } | |
| function ka(b, c) { | |
| C.push(c); | |
| if (c.hasAttribute("src") && ("about:blank" != c.src && 0 != c.src.indexOf("javascript:") && 0 != c.src.indexOf(la) || "FS" in c.contentWindow)) e("Frame Doesn't need injecting [" + c.src + "]"); | |
| else if (e("Attempting to setup Frame [" + c.src + "]"), L(c), c.onload && "function" == typeof c.onload) { | |
| var d = c.onload; | |
| c.onload = function(a) { | |
| d.call(this, a); | |
| L(c) | |
| } | |
| } else c.onload = function() { | |
| L(c) | |
| }; | |
| if (c.contentWindow.postMessage) { | |
| var g = f(w.rawRules); | |
| c.contentWindow.postMessage(a.FS_SET_FRAME_ID_CMD + a.FS_DELIMITER + b + a.FS_DELIMITER + B + a.FS_DELIMITER + g, "*") | |
| } | |
| } | |
| var E = !1, | |
| H = 0, | |
| z, x, F, J, D, A, W, la = window.location.protocol + "//" + window.location.host, | |
| R, G, B = d(), | |
| I, ca = {}, | |
| da, S = -1, | |
| T = -1, | |
| U = 0, | |
| X, M = { | |
| startTime: function() { | |
| return B | |
| }, | |
| now: function() { | |
| return d() - B | |
| }, | |
| wallTime: d, | |
| orgId: function() { | |
| return z | |
| }, | |
| userId: function() { | |
| return x | |
| }, | |
| sessionId: function() { | |
| return F | |
| }, | |
| pageId: function() { | |
| return J | |
| }, | |
| baseUri: k, | |
| amInsideIFrame: c, | |
| frameId: function() { | |
| return D | |
| }, | |
| post: b, | |
| addWindowScroll: r | |
| }, | |
| w = new a.Blocker, | |
| K = new a.InputWatcher(function(a) { | |
| u(a) | |
| }, function(b) { | |
| return !!a.fsid(b) | |
| }), | |
| Z = new a.MutationHandler(M, w, function(b, c) { | |
| switch (c.nodeName) { | |
| case "INPUT": | |
| case "TEXTAREA": | |
| case "SELECT": | |
| K.addInput(a.fsid(c), c); | |
| break; | |
| case "FRAME": | |
| case "IFRAME": | |
| var d = a.fsid(c); | |
| if (!d) { | |
| e("fsid missing or invalid for iFrame." + c.src); | |
| break | |
| } | |
| da || (ja(), da = !0); | |
| ca[d] = b; | |
| ka(d, c); | |
| break; | |
| case "VIDEO": | |
| case "AUDIO": | |
| c.paused || (d = a.fsid(c), m.enqueue(a.EVENT_PLAY, [d])) | |
| } | |
| }), | |
| ma = new a.EventProcessor(M, w), | |
| m = | |
| new a.EventQueue(M, ma, Z, function() { | |
| K.tick(); | |
| p() | |
| }); | |
| window._fs_shutdown = function(a) { | |
| y(); | |
| m.shutdown(); | |
| a && (a = document.getElementById(a)) && a.setAttribute("_fs_embed_token", X) | |
| }; | |
| a.log = e; | |
| a.stringify = f; | |
| var V = !1; | |
| a._init = function() { | |
| if ("_fs_host" in window || "_fs_ext_host" in window) | |
| if ("_fs_org" in window || "_fs_ext_org" in window) | |
| if ("_fs_ext_debug" in window ? E = !!window._fs_ext_debug : "_fs_debug" in window && (E = !!window._fs_debug), A = window._fs_ext_host || window._fs_host, z = window._fs_ext_org || window._fs_org, R = !!window._fs_is_outer_script, | |
| D = c() ? null : 0, e("host: " + A), e("orgid: " + z), G = !!window.MutationEvent, c()) window._fs_run_in_iframe ? parent.postMessage ? ia() : (G = !1, e("postMessage not supported")) : e("Fullstory recording for this page is NOT allowed within an iFrame."); | |
| else { | |
| w.addRule({ | |
| Selector: "object", | |
| Kind: a.NYI_KIND | |
| }); | |
| w.addRule({ | |
| Selector: "embed", | |
| Kind: a.NYI_KIND | |
| }); | |
| w.addRule({ | |
| Selector: "canvas", | |
| Kind: a.NYI_KIND | |
| }); | |
| w.addRule({ | |
| Selector: "noscript", | |
| Kind: a.BLOCKED_KIND | |
| }); | |
| w.addRule({ | |
| Selector: ".fs-hide", | |
| Kind: a.HIDE_KIND | |
| }); | |
| var b = window.FS.q; | |
| if (b) { | |
| for (var d = | |
| 0; d < b.length; d++) Q(b[d][0], b[d][1]); | |
| delete window.FS.q | |
| } | |
| fa() | |
| } else e("Missing global _fs_org. Recording disabled."); | |
| else e("Missing global _fs_host. Recording disabled.") | |
| }; | |
| a._record = function() { | |
| G && (m.recoverSwanSong(), B = d(), ha()) | |
| }; | |
| var $ = { | |
| uid: "str", | |
| displayName: "str", | |
| email: "str" | |
| }, | |
| aa = { | |
| str: function(a) { | |
| return "string" == typeof a | |
| }, | |
| bool: function(a) { | |
| return "boolean" == typeof a | |
| }, | |
| "int": function(a) { | |
| return "number" == typeof a && 0 == a - Math.floor(a) | |
| }, | |
| real: function(a) { | |
| return "number" == typeof a | |
| }, | |
| date: function(a) { | |
| return !isNaN(a.constructor === | |
| Date ? a : new Date(a)) | |
| } | |
| }; | |
| a._api = Q; | |
| a.setUid = function(b, c, d) { | |
| b && "string" == typeof b ? c && "string" != typeof c ? e("setUid(): second argument (display name) must be a string") : (c || (c = b), d && "object" != typeof d ? e('setUid(): third argument (metadata) must be of the form {name0: "value0", name1: "value1", ...}') : (d = d ? f(d) : "", e("setting uid: " + b + ", meta: " + d), m.enqueue(a.EVENT_SYS_SETMETA, [b, c, d]))) : e("setUid(): first argument (user id) is required and must be a string") | |
| }; | |
| a.getCurrentSessionURL = function() { | |
| return "https://" + | |
| A + "/ui/" + z + "/segments/everyone/session/" + ba() | |
| }; | |
| a.getCurrentSession = ba; | |
| a.FS_MESSAGE_PREFIX = "_fs"; | |
| a.FS_DELIMITER = "\u2603"; | |
| a.FS_REQUEST_FRAME_ID = a.FS_MESSAGE_PREFIX + "RequestFrameId"; | |
| a.FS_SET_FRAME_ID_CMD = a.FS_MESSAGE_PREFIX + "SetFrameId"; | |
| a.FS_IFRAME_EVENTS = a.FS_MESSAGE_PREFIX + "EvtBundle"; | |
| a.FS_DISABLE_RECORDING = a.FS_MESSAGE_PREFIX + "DisableRecording"; | |
| var C = [] | |
| })(k || (k = {})); | |
| try { | |
| "FS" in window || (window.FS = {}), window.FS.setUid = k.setUid, window.FS.getCurrentSessionURL = k.getCurrentSessionURL, window.FS.getCurrentSession = | |
| k.getCurrentSession, window.FS._api = k._api, k._init(), k._record() | |
| } catch (v) { | |
| window.console && console.log && console.log("Failed to initialize FullStory.") | |
| } | |
| })(); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment