function _toConsumableArray(a) { if (Array.isArray(a)) { for (var b = 0, c = Array(a.length); b < a.length; b++) c[b] = a[b]; return c } return Array.from(a) } function _classCallCheck(a, b) { if (!(a instanceof b)) throw new TypeError('Cannot call a class as a function') } function _classCallCheck(a, b) { if (!(a instanceof b)) throw new TypeError('Cannot call a class as a function') } function _toConsumableArray(a) { if (Array.isArray(a)) { for (var b = 0, c = Array(a.length); b < a.length; b++) c[b] = a[b]; return c } return Array.from(a) } function _objectWithoutProperties(a, b) { var c = { }; for (var d in a) b.indexOf(d) >= 0 || Object.prototype.hasOwnProperty.call(a, d) && (c[d] = a[d]); return c } define('core/utils/getEmbeddedData', [ ], function () { 'use strict'; return function (a) { var b = window.document.getElementById('disqus-' + a); try { return b && JSON.parse(b.textContent || b.innerHTML) } catch (c) { return null } } }), define('core/utils/cookies', [ ], function () { 'use strict'; var a = { _doc: window.document, create: function (b, c, d) { d || (d = { }); var e = b + '=' + c + '; path=' + (d.path || '/'), f = d.domain, g = d.expiresIn; if (f && (e += '; domain=.' + f), '[object Number]' === Object.prototype.toString.call(g)) { var h = new Date((new Date).getTime() + g); e += '; expires=' + h.toGMTString() } 'https:' === a._doc.location.protocol && (e += '; secure'), e += '; SameSite=None', a._doc.cookie = e }, read: function (b) { for (var c, d = b + '=', e = a._doc.cookie.split(';'), f = 0; f < e.length; f++) if (c = e[f].replace(/^\s+/, ''), 0 === c.indexOf(d)) return c.substring(d.length); return null }, erase: function (b, c) { var d = { }; for (var e in c) c.hasOwnProperty(e) && (d[e] = c[e]); return d.expiresIn = - 1, a.create(b, '', d) }, supported: function () { return a.create('cookie_support', '1'), '1' === a.read('cookie_support') && (a.erase('cookie_support'), !0) } }; return a }), define('core/utils/fingerprint', [ ], function () { 'use strict'; function a(a) { a = a || { }; var b = a.Math || window.Math, c = a.Date || window.Date; try { var d = (new c).getTimezoneOffset(), e = 1, f = window.screen; f && f.availWidth ? e = f.availWidth * f.availHeight + f.colorDepth : f && f.width && (e = f.width * f.height); var g = window.document.documentElement, h = g.clientWidth * g.clientHeight; return b.abs(17 * d + 25 * e - h) } catch (i) { return 1 } } return { get: a } }), define('core/utils/guid', [ 'core/utils/fingerprint' ], function (a) { 'use strict'; function b(a) { a = a || { }; var b = a.Uint32Array || window.Uint32Array, c = a.crypto || window.crypto, d = a.Math || window.Math; try { var e = new b(1); return c.getRandomValues(e), e[0] } catch (f) { return d.floor(1000000000 * d.random()) } } function c() { var a = window.performance, b = a && a.timing; if (!b) return 100000; var c = b.domainLookupEnd - b.domainLookupStart, d = b.connectEnd - b.connectStart, e = b.responseStart - b.navigationStart; return 11 * c + 13 * d + 17 * e } function d(d) { d = d || { }; var e = d.Math || window.Math, f = Number((new Date).getTime().toString().substring(3)), g = e.abs(f + c() - a.get()).toString(32); return g += b(d).toString(32) } return { generate: d } }), define('core/utils/hash', [ ], function () { 'use strict'; var a = function (a) { var b, c, d, e = 0; if (0 === a.length) return e; for (b = 0, c = a.length; b < c; b++) d = a.charCodeAt(b), e = (e << 5) - e + d, e |= 0; return e }; return { calculate: a } }), define('core/analytics/identity', [ 'exports', 'core/utils/cookies', 'core/utils/guid', 'core/utils/hash', 'core/utils/fingerprint' ], function (a, b, c, d, e) { 'use strict'; var f = !1, g = a.ImpressionManager = function () { this.isPrivate = !0, this.impId = c.generate() }; g.prototype.COOKIE_NAME = '__jid', g.prototype.TTL = 1800000, g.prototype.init = function (a) { this.isPrivate = a && a.isPrivate, this.isPrivate || (this.prevImp = b.read(this.COOKIE_NAME)), this.persist() }, g.prototype.setImpressionId = function (a) { this.impId = a, this.persist() }, g.prototype.persist = function () { return this.isPrivate ? void b.erase(this.COOKIE_NAME) : void b.create(this.COOKIE_NAME, this.impId, { expiresIn: this.TTL }) }; var h = a.UniqueManager = function () { this.isPrivate = !0 }; h.prototype.COOKIE_NAME = 'disqus_unique', h.prototype.TTL = 31536000000, h.prototype.init = function (a) { return this.isPrivate = a && a.isPrivate, this.isPrivate ? void b.erase(this.COOKIE_NAME, { domain: window.location.host.split(':') [0] }) : (this.value = b.read(this.COOKIE_NAME) || c.generate(), void b.create(this.COOKIE_NAME, this.value, { domain: window.location.host.split(':') [0], expiresIn: this.TTL })) }, h.prototype.isPersistent = function () { return !this.isPrivate && b.read(this.COOKIE_NAME) === this.value }, a.init = function (b, c) { f && !c || (a.impression.init(b), a.unique.init(b), f = !0) }, a.reset = function () { f = !1, a.impression = new g, a.unique = new h }, a.reset(), a.clientId = function () { var b, c = a.unique; return c.isPersistent() && (b = c.value), b || e.get().toString() }, a.getPercentBucketForString = function (a, b) { var c = 100, e = Math.abs(d.calculate(a)); if (b) { var f = Math.pow(10, b); return e % (c * f) / f } return e % c }, a.clientPercent = function () { return a.getPercentBucketForString(a.clientId()) } }), define('core/config/urls', [ 'common/urls' ], function (a) { 'use strict'; return a }), define('core/analytics/jester', [ 'jquery', 'underscore', 'backbone', 'core/analytics/identity', 'core/config/urls' ], function (a, b, c, d, e) { 'use strict'; var f = c.Model.extend({ url: e.jester + '/event.js', defaults: { experiment: 'default', variant: 'control' }, setHostReferrer: function (a) { a ? a.indexOf('http') === - 1 || this.set('page_referrer', a) : this.set('page_referrer', 'direct') }, decoratePayload: function (c) { c.event || (c.event = 'activity'), c = b.extend(this.toJSON(), c), b.extend(c, { imp: d.impression.impId, prev_imp: d.impression.prevImp }), c.section || (c.section = 'default'), c.area || (c.area = 'n/a'); var e = a.param(c).length; if (e > 2048 && this.has('page_referrer')) { var f = window.document.createElement('a'); f.href = this.get('page_referrer'); var g = f.hostname; g && (c.page_referrer_domain = g), delete c.page_referrer } return c }, emit: function (c) { return a.ajax({ url: b.result(this, 'url'), data: this.decoratePayload(c), dataType: 'script', cache: !0 }) } }), g = function (b) { var c = new window.Image; return c.src = e.jester + '/stat.gif?' + a.param({ event: b }), c }, h = function (c, d) { if (!b.any(d, function (a) { return a < 0 })) { b.each(d, function (a, b) { d[b] = Math.round(a) }); var f = new window.Image; return f.src = e.jester + '/telemetry/' + c + '.gif?' + a.param(d), f } }, i = new f; return i.setHostReferrer(window.document.referrer), { ActivityClient: f, client: i, logStat: g, telemetry: h } }), define('core/utils/urls', [ ], function () { 'use strict'; var a = { }, b = window.document.createElement('a'); return a.getOrigin = function (a) { b.href = a; var c = b.href.split('/'); return c[0] + '//' + c[2] }, a.getHostName = function (a) { return b.href = a, b.hostname }, a.getDomainPart = function (b, c) { 'undefined' == typeof c && (c = 0); var d = a.getHostName(b), e = d.split('.').reverse(); return e[c] }, a.getQuery = function (a) { return b.href = a, b.search }, a.getPathname = function (a) { return b.href = a, b.pathname }, a }), define('core/frameBus', [ 'jquery', 'underscore', 'backbone', 'core/utils/urls' ], function (a, b, c, d) { 'use strict'; var e = window.opener || window.parent, f = window.name, g = window.document.referrer, h = { }; h.client = d.getOrigin(window.document.location.href), h.secureClient = h.client.replace(/^\w+:\/\//, 'https://'), h.host = g ? d.getOrigin(g) : h.client; var i = { origins: h, messageHandler: function (a) { a = a.originalEvent; var b; try { b = JSON.parse(a.data) } catch (c) { return } b.name && '!' === b.name[0] && a.origin !== h.client && a.origin !== h.secureClient || 'client' === b.scope && i.trigger(b.name, b.data) }, postMessage: function (a) { a = JSON.stringify(a), e.postMessage(a, '*') }, sendHostMessage: function (a, b) { b = b || [ ], i.postMessage({ scope: 'host', sender: f, name: a, data: b }) } }; return b.extend(i, c.Events), a(window).on('message', i.messageHandler), a(window).on('unload', function () { i.sendHostMessage('die') }), window.DISQUS = window.DISQUS || { }, window.DISQUS.Bus = i, i }), define('core/bus', [ 'backbone', 'underscore', 'core/frameBus' ], function (a, b, c) { 'use strict'; var d = b.extend({ }, a.Events); return d.frame = c, d }), define('core/utils/storage', [ ], function () { 'use strict'; var a = function (a) { var b = '_dsqstorage_'; try { return a.localStorage.setItem(b, b), a.localStorage.getItem(b), a.localStorage.removeItem(b), !0 } catch (c) { return !1 } }(window), b = function () { var a = { }; return { getItem: function (b) { return a.hasOwnProperty(b) ? a[b] : null }, setItem: function (b, c) { a[b] = String(c) }, removeItem: function (b) { delete a[b] }, clear: function () { a = { } } } }(); return { get: function (a) { var b = null; try { return b = this.backend.getItem(a), JSON.parse(b) } catch (c) { return b } }, set: function (a, b) { try { this.backend.setItem(a, JSON.stringify(b)) } catch (c) { } }, remove: function (a) { try { this.backend.removeItem(a) } catch (b) { } }, clear: function () { try { this.backend.clear() } catch (a) { } }, backend: a ? window.localStorage : b, isPersistent: a } }), define('core/utils/auth', [ 'core/utils/cookies' ], function (a) { 'use strict'; var b = { }, c = 'disqusauth'; return b.getFromCookie = function () { var b = (a.read(c) || '').replace(/"/g, '').split('|'); !b || b[1] && b[6] || (b = [ ], a.erase(c, { })); var d = parseInt(b[6] || '0', 10); return { avatarUrl: b[7] ? decodeURIComponent(b[7]) : void 0, datetimeFormatting: parseInt(b[4], 10) ? 'absolute' : 'relative', id: d, isModerator: parseInt(b[8], 10) > 0, staff: Boolean(parseInt(b[2], 10)), tzOffset: b[5], username: b[1], isAuthenticated: Boolean(d && '0' !== d) } }, b }), define('core/switches', [ 'underscore', 'remote/config', 'core/analytics/identity', 'core/utils/storage', 'core/utils/auth' ], function (a, b, c, d, e) { 'use strict'; var f = 'switch:', g = { }, h = { }; return h._getKey = function (a) { return f + a }, h.disableFeature = function (a) { g[a] = !1 }, h.resetFeature = function (a) { g[a] = null }, h.forceFeature = function (a) { g[a] = !0 }, h.getSwitchContext = function (a) { var c = d.get(this._getKey(a)); if (null !== c) return c; var e = g[a]; return null != e ? e : (b.lounge && b.lounge.switches || { }) [a] }, h.isFeatureActive = function (b, d) { var f = h.getSwitchContext(b); if (a.isBoolean(f)) return f; if (!f) return !1; var g = e.getFromCookie(), i = { percent: c.clientPercent(), user_id: g.id, username: g.username, is_staff: g.staff, is_moderator: g.isModerator }, j = a.defaults(d || { }, i); return a.any(f, function (b, d) { var e = j[d]; if (/percent$/.test(d) && a.isNumber(b)) { if (a.isNumber(e)) return b > e; if (a.isString(e)) { var f = 0; return b !== Math.round(b) && (f = b.toString().split('.').pop().length), b > c.getPercentBucketForString(e, f) } return !1 } return a.isArray(b) ? a.contains(b, e) : b === e }) }, h }), define('core/utils/url/serializeArgs', [ 'require', 'exports', 'module', 'core/utils/collection/each' ], function (a, b, c) { 'use strict'; var d = a('core/utils/collection/each'); c.exports = function (a) { var b = [ ]; return d(a, function (a, c) { void 0 !== a && b.push(encodeURIComponent(c) + (null === a ? '' : '=' + encodeURIComponent(a))) }), b.join('&') } }), define('core/utils/url/serialize', [ 'require', 'exports', 'module', 'core/utils/url/serializeArgs' ], function (a, b, c) { 'use strict'; var d = a('core/utils/url/serializeArgs'); c.exports = function e(a, b, c) { if (b && (a.indexOf('?') === - 1 ? a += '?' : '&' !== a.charAt(a.length - 1) && (a += '&'), a += d(b)), c) { var f = { }; return f[(new Date).getTime()] = null, e(a, f) } var g = a.length; return '&' === a.charAt(g - 1) ? a.slice(0, g - 1) : a } }), define('core/utils/isAdBlockEnabled', [ ], function () { 'use strict'; function a() { var a = d.createElement('div'); return a.setAttribute('class', 'pub_300x250 pub_300x250m pub_728x90 text-ad textAd text_ad text_ads text-ads text-ad-links ad-text adSense adBlock adContent adBanner'), a.setAttribute('style', 'width: 1px !important; height: 1px !important; position: absolute !important; left: -10000px !important; top: -1000px !important;'), a } function b(a) { if (null === a.offsetParent || 0 === a.offsetHeight || 0 === a.offsetLeft || 0 === a.offsetTop || 0 === a.offsetWidth || 0 === a.clientHeight || 0 === a.clientWidth) return !0; if (void 0 !== window.getComputedStyle) { var b = window.getComputedStyle(a, null); if (b && ('none' === b.getPropertyValue('display') || 'hidden' === b.getPropertyValue('visibility'))) return !0 } return !1 } var c = 100, d = window.document; return function (e) { var f = a(); d.body.appendChild(f), setTimeout(function () { var a = b(f); d.body.removeChild(f), e(a) }, c) } }), define('core/utils/html/toRGBColorString', [ ], function () { 'use strict'; var a = 'Color components should be numbers.'; return function (b) { var c = Number(b.red), d = Number(b.green), e = Number(b.blue); if (isNaN(c) || isNaN(d) || isNaN(e)) throw new Error(a); var f = 'rgb', g = [ c, d, e ], h = b.alpha; if (h) { if (h = Number(h), isNaN(h)) throw new Error(a); f += 'a', g.push(h) } return f + '(' + g + ')' } }), define('core/utils/lang/isString', [ ], function () { 'use strict'; return function (a) { return '[object String]' === Object.prototype.toString.call(a) } }), define('core/utils/html/setInlineStyle', [ 'require', 'core/utils/collection/each', 'core/utils/lang/isString', 'core/utils/object/extend' ], function (a) { 'use strict'; function b(a) { return a.replace(/\s+/g, '').toLowerCase() } var c = a('core/utils/collection/each'), d = a('core/utils/lang/isString'), e = a('core/utils/object/extend'); return function (a, f, g) { var h = { }; d(f) ? h[f] = g : h = f; var i = e({ }, h); c(i, function (a, c) { var d = b(c); d !== c && (delete i[c], i[d] = a), null === a && (i[d] = ''), void 0 === a && delete i[d] }); var j = a.style; c(i, function (a, b) { j.setProperty(b, String(a), 'important') }) } }), define('core/utils/html/parseColor', [ 'require', 'core/utils/html/setInlineStyle' ], function (a) { 'use strict'; function b(a) { return a.replace(/\s+/g, '').toLowerCase() } function c(a) { return a = a.replace(/^#([a-f0-9])([a-f0-9])([a-f0-9])$/, '#$1$1$2$2$3$3'), a = a.slice(1), { red: parseInt(a.slice(0, 2), 16), green: parseInt(a.slice(2, 4), 16), blue: parseInt(a.slice(4, 6), 16) } } function d(a) { var b = a.match(/^rgb\((\d+),(\d+),(\d+)\)$/); return { red: parseInt(b[1], 10), green: parseInt(b[2], 10), blue: parseInt(b[3], 10) } } function e(a) { var b = a.match(/^rgba\((\d+),(\d+),(\d+),([\d.]+)\)$/); return { red: parseInt(b[1], 10), green: parseInt(b[2], 10), blue: parseInt(b[3], 10), alpha: parseFloat(b[4]) } } function f(a, b, c, d) { return b = window.document.createElement(b), h(b, { visibility: 'hidden', color: c }), a.appendChild(b), c = d(b), a.removeChild(b), c } function g(a, c) { c = c || { }; var e = c.container || window.document.body; return window.getComputedStyle ? (a = f(e, 'span', a, function (a) { return window.getComputedStyle(a, null).getPropertyValue('color') }), d(b(a))) : (a = f(e, 'textarea', a, function (a) { return a.createTextRange().queryCommandValue('ForeColor') }), { red: 255 & a, blue: a >>> 16, green: (65280 & a) >>> 8 }) } var h = a('core/utils/html/setInlineStyle'); return function (a, f) { a = b(a); var h; if ('transparent' === a) return { red: 0, green: 0, blue: 0, alpha: 0 }; if ('#' === a.charAt(0)) h = c; else if ('rgba(' === a.slice(0, 5)) h = e; else if ('rgb(' === a.slice(0, 4)) h = d; else { if (!/^[a-z]+$/.test(a)) throw new Error('parseColor received unparseable color: ' + a); h = g } return h(a, f) } }), define('core/host/globalFromSandbox', [ 'require' ], function (a) { 'use strict'; var b = window.document, c = b.createElement('iframe'); return c.style.display = 'none', function (a, d) { var e = d && d[a] || null; try { return c.parentNode !== b.body && b.body.appendChild(c), c.contentWindow[a] || e } catch (f) { return e } } }), define('core/host/utils', [ 'require', 'core/utils/browser', 'core/utils/lang/isString', 'core/utils/html/getCurrentStyle', 'core/utils/html/parseColor', 'core/host/globalFromSandbox' ], function (a) { 'use strict'; function b(a) { for (var b = [ /(https?:)?\/\/(www\.)?disqus\.com\/forums\/([\w_-]+)/i, /(https?:)?\/\/(www\.)?([\w_-]+)\.disqus\.com/i, /(https?:)?\/\/(www\.)?dev\.disqus\.org\/forums\/([\w_-]+)/i, /(https?:)?\/\/(www\.)?([\w_-]+)\.dev\.disqus\.org/i ], c = 0; c < b.length; c++) { var d = a.match(b[c]); if (d && d.length && 4 === d.length) return d[3] } return null } function c(a, c, d) { var e = a.querySelector('script[src*="disqus"][src$="' + c + '"]'); if (e) { var f = e.getAttribute ? e.getAttribute('src') : e.src; d = d || b; var g = d(f); return g ? g.toLowerCase() : null } return null } function d(a, b) { var c, d, e = 0, f = new Array(a.length); for (c = 0; c <= a.length; c++) for (f[c] = new Array(b.length), d = 0; d <= b.length; d++) f[c][d] = 0; for (c = 0; c < a.length; c++) for (d = 0; d < b.length; d++) a[c] === b[d] && (f[c + 1][d + 1] = f[c][d] + 1, f[c + 1][d + 1] > e && (e = f[c + 1][d + 1])); return e } function e() { for (var a = t.getElementsByTagName('h1'), b = t.title, c = b.length, e = b, f = 0.6, g = function (a) { var g, h = a.textContent || a.innerText; null !== h && void 0 !== h && (g = d(b, h) / c, g > f && (f = g, e = h)) }, h = 0; h < a.length; h++) g(a[h]); return e } function f(a) { return a.toLowerCase().replace(/^\s+|\s+$/g, '').replace(/['"]/g, '') } function g(a) { var b = 0, c = 1, d = 2; if (!s('atob') || !s('requestAnimationFrame')) return c; try { a.postMessage('ping', '*') } catch (e) { return d } return b } function h(a, b, c) { c = c || b; var d = q(a, b, c); return !d || /color/i.test(b) && 0 === r(d).alpha ? a && h(a.parentNode, b, c) || d : d || null } function i(a, b, c, d) { p(b) && (b = t.createElement(b)); var e = null; return b.style.visibility = 'hidden', a.appendChild(b), e = h(b, c, d), a.removeChild(b), e } function j(a) { for (var b, c = i(a, 'span', 'font-family', 'fontFamily'), d = c.split(','), e = { courier: 1, times: 1, 'times new roman': 1, georgia: 1, palatino: 1, serif: 1 }, g = 0; g < d.length; g++) if (b = f(d[g]), e.hasOwnProperty(b)) return !0; return !1 } function k(a) { var b = t.createElement('a'); return b.href = Number(new Date), r(i(a, b, 'color'), { container: a }) } function l(a) { var b = a.red, c = a.green, d = a.blue; if (a.hasOwnProperty('alpha')) { var e = a.alpha, f = function (a) { return Math.round(a * e + 255 * (1 - e)) }; b = f(b), c = f(c), d = f(d) } return (299 * b + 587 * c + 114 * d) / 1000 } function m(a) { var b = i(a, 'span', 'background-color', 'backgroundColor'), c = r(b, { container: a }); return 0 === c.alpha ? 'light' : l(c) < 128 ? 'dark' : 'light' } function n(a) { var b = k(a); return 0 === b.alpha ? 'light' : l(b) < 128 ? 'dark' : 'light' } var o = a('core/utils/browser'), p = a('core/utils/lang/isString'), q = a('core/utils/html/getCurrentStyle'), r = a('core/utils/html/parseColor'), s = a('core/host/globalFromSandbox'), t = window.document, u = function () { var a, b, c = function () { return !1 }; if ('hidden' in t) a = 'hidden', b = 'visibilitychange'; else { if (!('webkitHidden' in t)) return { isHidden: c, listen: c, stopListening: c }; a = 'webkitHidden', b = 'webkitvisibilitychange' } return { isHidden: function () { return t[a] }, listen: function (a) { return t.addEventListener(b, a) }, stopListening: function (a) { return t.removeEventListener(b, a) } } }(), v = function () { var a = t.createElement('div'); a.style.visibility = 'hidden', a.style.width = '100px', a.style.msOverflowStyle = 'scrollbar', t.body.appendChild(a); var b = a.offsetWidth; a.style.overflow = 'scroll'; var c = t.createElement('div'); c.style.width = '100%', a.appendChild(c); var d = c.offsetWidth; return a.parentNode.removeChild(a), b - d }, w = { getItem: function (a) { try { return window.localStorage.getItem(a) } catch (b) { } }, setItem: function (a, b) { try { return window.localStorage.setItem(a, b) } catch (c) { } } }, x = 1, y = function (a) { if (a.nodeType === x) { var b = q(a, 'max-height', 'maxHeight'), c = q(a, 'overflow-y', 'overflowY'); return b && 'none' !== b && c && 'visible' !== c } }, z = 4, A = function (a) { if (a.nodeType === x) return a.scrollHeight - a.clientHeight > z }, B = function () { if (t.querySelector) { var a = t.querySelector('link[rel=canonical]'); if (a) return a.href } }; return { MAX_Z_INDEX: 2147483647, getShortnameFromUrl: b, getForum: c, guessThreadTitle: e, getContrastYIQ: l, getColorScheme: m, getElementStyle: i, getAnchorColor: k, getAnchorColorScheme: n, normalizeFontValue: f, isSerif: j, getBrowserSupport: g, pageVisibility: u, getScrollbarWidth: v, browser: o, storage: w, appearsToHideContent: y, hasOverflow: A, getCanonicalUrl: B } }), define('common/utils', [ 'jquery', 'underscore', 'loglevel', 'common/main', 'common/urls', 'core/host/utils', 'core/utils/cookies', 'core/utils/html/parseColor' ], function (a, b, c, d, e, f, g, h) { 'use strict'; var i = window.document, j = { }; j.globalUniqueId = function (a) { return b.uniqueId(a) + '_' + Number(new Date) }, j.setPublisherColor = function (a) { i.documentElement.style.setProperty('--publisher-color', a); var b = f.getContrastYIQ(h(a)); b > 5 && b < 250 && i.documentElement.style.setProperty('--publisher-color-safe', a) }, j.addStylesheetRules = function (a) { function c() { var e = b.find(i.styleSheets, function (a) { var b = a.ownerNode || a.owningElement; return b.id === d }); if (!e) return void setTimeout(c, 50); for (var f = 0, g = a.length; f < g; f++) { var h = 1, j = a[f], k = j[0], l = ''; '[object Array]' === Object.prototype.toString.call(j[1][0]) && (j = j[1], h = 0); for (var m = j.length; h < m; h++) { var n = j[h]; l += n[0] + ':' + n[1] + (n[2] ? ' !important' : '') + ';\n' } e.insertRule ? e.insertRule(k + '{' + l + '}', e.cssRules.length) : e.addRule(k, l, - 1) } } var d = 'css_' + (new Date).getTime(), e = i.createElement('style'); e.id = d, i.getElementsByTagName('head') [0].appendChild(e), window.createPopup || e.appendChild(i.createTextNode('')), c() }; var k = j.CORS = { handler: function (a, b, c) { a && c >= 200 && c < 300 ? a() : b && (c < 200 || c >= 300) && b() }, XHR2: function (a, b, c, d) { var e = k.handler, f = new window.XMLHttpRequest; return f.open(a, b, !0), f.onreadystatechange = function () { f.readyState === window.XMLHttpRequest.DONE && e(c, d, f.status) }, f } }; k.request = function () { return 'withCredentials' in new window.XMLHttpRequest ? k.XHR2 : function () { return null } }(), j.isWindowClosed = function (a) { if (!a) return !0; try { return a.closed || void 0 === a.closed } catch (b) { return !0 } }, j.truncate = function (a, b, c) { return c = c || '...', a.length > b ? a.slice(0, b) + c : a }, j.extractDomainForCookies = function (a) { return a.split('/') [2].replace(/:[0-9]+/, '') }, j.cookies = { domain: j.extractDomainForCookies(e.root), create: function (a, b) { var c = 31536000000; g.create(a, b, { domain: j.cookies.domain, expiresIn: c }) }, read: g.read, erase: function (a) { g.erase(a, { domain: j.cookies.domain }) } }, j.updateURL = function (a, c) { var d, e = i.createElement('a'); return c = c || { }, e.href = a, c.hostname && c.hostname.match(/\.$/) && (c.hostname += e.hostname), d = b.extend({ protocol: e.protocol, hostname: e.hostname, pathname: e.pathname, search: e.search }, c), d.pathname.match(/^\//) || (d.pathname = '/' + d.pathname), d.protocol + '//' + d.hostname + d.pathname + d.search }, j.injectBaseElement = function (a, b) { b = b || i; var c = b.getElementsByTagName('base') [0] || b.createElement('base'); c.target = '_parent', a ? c.href = a : c.removeAttribute('href'), c.parentNode || (b.head || b.getElementsByTagName('head') [0]).appendChild(c) }, j.syntaxHighlighter = function () { var c = 1, e = 2, f = null, g = null, h = [ ], i = { highlight: function (a) { null === g && i._load(), h.push(a), g === e && i.scheduleHighlight() }, _highlight: function (b) { var c = a(b).html(); a(b).html(c.replace(/^
/, '')), f.highlightBlock(b), i.scheduleHighlight() }, scheduleHighlight: function () { var a = h.shift(); a && window.requestAnimationFrame(b.bind(i._highlight, i, a)) }, _load: function () { g = c, d.loadCss('https://c.disquscdn.com/next/embed/styles/highlight.3128dd90ecaebd8542ac3442033f3f00.css'), require(['common/vendor_extensions/highlight'], function (a) { g = e, f = a, i.scheduleHighlight() }) } }; return i }(); var l = a('html'); j.getPageHeight = function () { var b = a('#tos__message'), c = b.outerHeight(); return c && (c += b.offset().top), Math.max(c, l.height()) }, j.calculatePositionFullscreen = function () { return { pageOffset: a(window).scrollTop(), height: i.documentElement.clientHeight, frameOffset: { left: 0, top: 0 } } }, j.triggerClick = function (a, b) { var c, d, e = a[0], f = { altKey: !1, button: 0, ctrlKey: !1, metaKey: !1, shiftKey: !1 }; if (i.createEvent) { if (c = i.createEvent('MouseEvents'), b) for (d in f) f.hasOwnProperty(d) && b.hasOwnProperty(d) && (f[d] = b[d]); c.initMouseEvent('click', !0, !0, window, 0, 0, 0, 0, 0, f.ctrlKey, f.altKey, f.shiftKey, f.metaKey, 0, null), e.dispatchEvent && e.dispatchEvent(c) } else if (i.createEventObject) { if (c = i.createEventObject(), c.eventType = 'click', b) for (d in f) f.hasOwnProperty(d) && b.hasOwnProperty(d) && (c[d] = b[d]); e.fireEvent('onclick', c) } }, j.delayLinkClick = function (a, c) { a.preventDefault(), b.delay(b.bind(j.triggerClick, this, c, a.originalEvent), 100) }, j.mixin = function (a, c, d) { var e = a.prototype, f = b.extend({ }, c, d); if (b.defaults(e, f), b.defaults(e.events, f.events), void 0 !== e.initialize && void 0 !== f.initialize) { var g = e.initialize; e.initialize = function () { var a = g.apply(this, arguments); return f.initialize.apply(this, arguments), a } } return a }, j.extractService = function (b, c) { var d = '[data-action^=' + c + ']', e = a(b); e = e.is(d) && e || e.closest(d); var f = e.attr('data-action') || ':', g = f.split(':') [1]; return g }, j.getConfigFromHash = function (a) { var d, e = a.location.hash; try { d = JSON.parse(decodeURIComponent(String(e).substr(1))) } catch (f) { c.debug('Failed to parse config from URL hash', f) } return b.isObject(d) ? d : { } }; var m = /[<>]|:\/\//; return j.isPlainText = function (a) { return !a.match(m) }, j.isDNTEnabled = function (a) { return a || (a = window), '1' === a.navigator.doNotTrack || 'yes' === a.navigator.doNotTrack || '1' === a.navigator.msDoNotTrack }, j.shouldSample = function (a) { var b = parseInt(a, 10); return !!b && (!(b > 100) && Math.random() < b / 100) }, j.decorate = function () { var a, c = b.toArray(arguments), d = c.pop(); return b.isFunction(d) || (a = d, d = c.pop()), b.reduceRight(c, function (b, c) { return c.call(a || this, b) }, function () { return d.apply(a || this, arguments) }) }, j }), define('lounge/common', [ ], function () { 'use strict'; var a, b = function (b) { a = b }, c = function () { return a }; return { setLounge: b, getLounge: c } }); var _extends = Object.assign || function (a) { for (var b = 1; b < arguments.length; b++) { var c = arguments[b]; for (var d in c) Object.prototype.hasOwnProperty.call(c, d) && (a[d] = c[d]) } return a }; define('lounge/tracking', [ 'jquery', 'underscore', 'raven', 'core/analytics/identity', 'core/analytics/jester', 'core/bus', 'common/urls', 'core/switches', 'core/utils', 'core/utils/hash', 'core/utils/url/serialize', 'core/utils/isAdBlockEnabled', 'core/utils/html/toRGBColorString', 'remote/config', 'common/utils', 'common/main', 'lounge/common' ], function (a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p, q) { 'use strict'; function r(n, q) { function r(a, c, f) { var i = { abe: f ? '1' : '0', embed_hidden: q.config.isBehindClick ? '1' : '0', integration: q.config.integration, load_time: Number(new Date) - p.timings.initStart - (p.timings.renderStart && p.timings.bootstrapStart ? p.timings.renderStart - p.timings.bootstrapStart : 0) }; if (h.isFeatureActive('init_embed_activity')) b.extend(i, { verb: 'load', object_type: 'product', object_id: 'embed' }), e.client.emit(i); else { var j = a.user.id, l = o.isDNTEnabled(); b.extend(i, { event: 'init_embed', thread: C, forum: z, forum_id: A, imp: d.impression.impId, prev_imp: d.impression.prevImp, thread_slug: B.get('slug'), user_type: a.user.get('user_type') || 'anon', referrer: n.document.referrer, theme: 'next', dnt: l ? '1' : '0', tracking_enabled: c ? '1' : '0' }, q.config.experiment), j && '0' !== j && (i.user_id = j); var m = y.get('settings'); m && b.has(m, 'adsProductLinksEnabled') && b.extend(i, { promoted_enabled: m.adsProductLinksEnabled, max_enabled: m.adsPositionTopEnabled }), (new n.Image).src = k(g.jester + '/event.gif', i, !1) } if (B.isModerator(a.user)) { var r = n.document.createElement('iframe'); r.src = 'https://disqusads.com/enable-logging', r.style.display = 'none', n.document.body.appendChild(r) } } function t(a) { w = !0, x = a, s.shouldTrack(y, q.session.user) && (d.init({ }, !0), s.load3rdParties(B, q)) } var y = q.forum, z = y.id, A = y.get('pk'), B = q.thread, C = B.id; q.session.on('change:id', function (a) { e.client.set('user_id', a.id) }), q.session.once('change:id', function () { var b = this, c = s.shouldTrack(y, this.user), e = s.shouldTrack(y, this.user, !0); if (q.config.isPrivate && this.user && this.user.get('hasAcceptedGdprTerms') && d.init({ isPrivate: !1 }, !0), c && s.load3rdParties(B, q), !v && y.get('settings').adsEnabled && h.isFeatureActive('zyncOnly') && e) { var j = (new Date).getTime(); a('body').append(a('').hide().attr('src', g.zyncPixelImage + '&cid=c' + d.unique.value + '&cache_buster=' + j)), v = !0 } l(function (a) { r(b, c, a) }), f.frame.sendHostMessage('tracking:init', { shouldTrack: c, isMobile: i.isMobileUserAgent(n), hostIdentityActive: h.isFeatureActive('hostIdentityActive', { forum: y.id, forum_percent: y.id }), liveConnectActive: e && h.isFeatureActive('liveConnectActive', { forum: y.id, forum_percent: y.id }), unique: d.unique.value }) }), e.client.set({ product: 'embed', thread: C, thread_id: C, forum: z, forum_id: A, zone: 'thread', version: p.version }), q.once('bootstrap:complete', function () { e.client.set({ page_url: q.config.referrer }); var a = q.config.experiment; a && e.client.set({ experiment: a.experiment, variant: a.variant, service: a.service }), e.client.setHostReferrer(q.config.hostReferrer) }); var D = { inViewport: function () { var c = q.config, d = { color_scheme: c.colorScheme, anchor_color: m(c.anchorColor), typeface: c.typeface, width: a(n.document).width() }, f = { gpc: window.navigator.globalPrivacyControl ? 1 : 0 }; q.meta.topics && (f.topics = q.meta.topics.map(function (a) { return a.topic.toString() }).join(',')), d = b.pick(d, function (a, c) { switch (c) { case 'width': return b.isNumber(a); default: return b.isString(a) && '' !== a } }), e.client.emit({ verb: 'view', object_type: 'product', object_id: 'embed', extra_data: JSON.stringify(_extends({ }, d, f)) }), q.off('inViewport') }, 'uiCallback:postCreated': function (a, c) { c = c || { }, b.extend(c, { object_type: 'post', object_id: a.id, verb: 'post' }), a.has('parent') && (c.target_type = 'post', c.target_id = a.get('parent')), e.client.emit(c) }, 'uiCallback:postUpdated': function (a, c) { c = c || { }, b.extend(c, { object_type: 'post', object_id: a.id, verb: 'update' }), e.client.emit(c) }, 'uiAction:postStartUpdate': function (a, c) { c = c || { }, b.extend(c, { verb: 'click', adjective: 'edit', object_type: 'link', object_id: a.id }), e.client.emit(c) }, 'uiAction:seeMore': function (a) { e.client.emit({ verb: 'open', object_type: 'section', object_id: 'thread/page-' + a }) }, 'uiAction:seeMoreChildren': function (a) { e.client.emit({ verb: 'click', object_type: 'link', object_id: 'show_more_comments', area: s.getEventTrackingArea(a) }) }, 'uiAction:postUpvote': function (a, b) { e.client.emit({ verb: 'like', object_type: 'post', object_id: a.id, area: s.getEventTrackingArea(b) }) }, 'uiAction:postUnvote': function (a, b) { e.client.emit({ verb: 'unlike', object_type: 'post', object_id: a.id, area: s.getEventTrackingArea(b) }) }, 'uiAction:postDownvote': function (a, b) { e.client.emit({ verb: 'dislike', object_type: 'post', object_id: a.id, area: s.getEventTrackingArea(b) }) }, 'uiAction:threadUnlike': function () { e.client.emit({ verb: 'unlike', object_type: 'thread', zone: 'thread' }) }, 'uiAction:threadLike': function () { e.client.emit({ verb: 'like', object_type: 'thread' }) }, 'uiAction:postShare': function (a, b) { e.client.emit({ verb: 'share', object_type: 'post', object_id: a.id, target_type: 'service', target_id: b }) }, 'uiAction:threadShare': function (a) { e.client.emit({ verb: 'share', object_type: 'thread', target_type: 'service', target_id: a }) }, 'uiAction:clickLink': function (a, b) { e.client.emit({ verb: 'click', object_type: 'link', object_id: a[0].href, area: s.getEventTrackingArea(b) }) }, 'uiAction:followUser': function (a) { e.client.emit({ verb: 'follow', object_type: 'user', object_id: a.id }) }, 'uiAction:unfollowUser': function (a) { e.client.emit({ verb: 'stop-following', object_type: 'user', object_id: a.id }) }, 'uiAction:openLogin': function (a) { e.client.emit({ verb: 'open', object_type: 'login', object_id: a }) }, 'uiAction:onboardAlertShow': function () { e.client.emit({ verb: 'view', object_type: 'area', object_id: 'onboard_alert' }) }, 'uiAction:onboardAlertDismiss': function () { e.client.emit({ verb: 'close', object_type: 'area', object_id: 'onboard_alert' }) }, 'uiAction:openHome': function (a, b) { e.client.emit({ verb: 'open', object_type: 'product', object_id: b ? 'bridge' : 'home', section: a }) }, 'uiAction:viewBanUser': function () { e.client.emit({ verb: 'view', object_type: 'area', object_id: 'ban_user' }) }, 'uiAction:clickBanUser': function (a) { e.client.emit({ verb: 'click', object_type: 'button', object_id: 'ban_user', extra_data: a }) }, 'uiAction:viewFlagPost': function () { e.client.emit({ verb: 'view', object_type: 'area', object_id: 'flag_post' }) }, 'uiAction:clickFlagPost': function () { e.client.emit({ verb: 'click', object_type: 'button', object_id: 'flag_post' }) }, 'uiAction:viewBlockUser': function () { e.client.emit({ verb: 'view', object_type: 'area', object_id: 'block_user' }) }, 'uiAction:clickBlockUser': function () { e.client.emit({ verb: 'click', object_type: 'button', object_id: 'block_user' }) }, 'uiAction:viewUpgradeCard': function () { e.client.emit({ verb: 'hover', object_type: 'icon', object_id: 'disqus_pro', organization_id: y.get('organizationId') }) }, 'uiAction:clickUpgrade': function () { e.client.emit({ verb: 'click', object_type: 'button', object_id: 'subscriptions', organization_id: y.get('organizationId') }) }, 'uiAction:clickCommentPolicy': function (a) { e.client.emit({ verb: 'click', object_type: 'link', section: 'comment_policy', object_id: a }) }, 'uiAction:clickThreadPremoderate': function () { e.client.emit({ verb: 'click', object_type: 'button', object_id: 'premoderate_thread' }) }, viewActivity: function (a, b) { var c = { verb: 'view', object_type: a, object_id: b }; e.client.emit(c) }, 'uiAction:loadEmailSubscriptionPrompt': function (a) { e.client.emit({ verb: 'load', object_type: 'section', object_id: 'email_subscriptions', section: 'email_subscriptions', extra_data: JSON.stringify({ user_verified: Boolean(q.session.user && q.session.user.get('isVerified')), email_subscription_prompt: a }) }) }, 'uiAction:viewEmailSubscriptionPrompt': function (a) { e.client.emit({ verb: 'view', object_type: 'section', object_id: 'email_subscriptions', section: 'email_subscriptions', extra_data: JSON.stringify({ user_verified: Boolean(q.session.user && q.session.user.get('isVerified')), email_subscription_prompt: a }) }) }, 'uiAction:clickEmailSubscriptionPromptSubscribe': function (a) { e.client.emit({ verb: 'click', object_type: 'button', object_id: 'subscribe', section: 'email_subscriptions', extra_data: JSON.stringify({ user_verified: Boolean(q.session.user && q.session.user.get('isVerified')), email_subscription_prompt: a }) }) }, 'uiAction:clickEmailSubscriptionPromptDismiss': function (a) { e.client.emit({ verb: 'click', object_type: 'button', object_id: 'hide_this_message', section: 'email_subscriptions', extra_data: JSON.stringify({ user_verified: Boolean(q.session.user && q.session.user.get('isVerified')), email_subscription_prompt: a }) }) }, 'uiAction:viewReactionsPromotion': function () { e.client.emit({ verb: 'view', object_type: 'section', object_id: 'reactions_onboarding', zone: 'thread', section: 'reactions_onboarding' }) }, 'uiAction:reactionsEnable': function () { e.client.emit({ verb: 'click', object_type: 'button', object_id: 'enable_reactions', zone: 'thread', section: 'reactions_onboarding' }) }, 'uiAction:reactionsDefer': function () { e.client.emit({ verb: 'click', object_type: 'button', object_id: 'maybe_later', zone: 'thread', section: 'reactions_onboarding' }) }, 'uiAction:reactionsVote': function (a) { e.client.emit({ verb: 'vote', object_type: 'thread', adjective: a.get('text'), zone: 'thread', section: 'reactions', extra_data: JSON.stringify({ reaction_id: a.id }) }) }, 'uiAction:gifsClickButton': function () { e.client.emit({ verb: 'click', object_type: 'button', adjective: 'gif_picker', object_id: 'thread', zone: 'thread' }) }, 'uiAction:gifsScrollToBottom': function () { e.client.emit({ verb: 'view', adverb: 'results', object_type: 'zone', adjective: 'end', object_id: 'thread', zone: 'thread' }) }, 'uiAction:loadLiveComments': function () { e.client.emit({ verb: 'click', adverb: 'comments', object_type: 'notification', adjective: 'realtime', object_id: 'thread', zone: 'thread' }) }, 'uiAction:loadLiveReplies': function () { e.client.emit({ verb: 'click', adverb: 'replies', object_type: 'notification', adjective: 'realtime', object_id: 'thread', zone: 'thread' }) }, 'uiAction:clickBadge': function (a, b) { e.client.emit({ verb: 'click', object_type: 'badge', object_id: b, section: 'profile/badges', zone: 'thread', area: s.getEventTrackingArea(a) }) }, 'uiAction:viewBadgeModal': function () { e.client.emit({ verb: 'view', object_type: 'modal', object_id: 'badge', section: 'manage_badges', zone: 'thread' }) }, 'uiAction:awardBadge': function (a) { e.client.emit({ verb: 'award', object_type: 'badge', object_id: a, section: 'manage_badges', zone: 'thread' }) }, 'uiAction:removeBadge': function (a) { e.client.emit({ verb: 'remove', object_type: 'badge', object_id: a, section: 'manage_badges', zone: 'thread' }) }, 'uiAction:behindClickButton': function () { e.client.emit({ verb: 'click', object_type: 'button', adjective: 'behind_click', object_id: 'thread', zone: 'thread' }) }, 'uiAction:toggleClassicDisqus': function (a) { e.client.emit({ verb: 'click', object_type: 'button', adjective: a, object_id: 'toggle_classic_disqus', zone: 'thread' }) } }; q.on(D), f.on(D), f.frame.once('cmp.consent', t), f.frame.once('tracking.hostIdentity', function (b) { if (!u) { var e = [ j.calculate(b.domain), b.id, d.unique.value ], f = a('body'), h = g.logger + '/1/' + n.btoa(JSON.stringify(e)); try { f.append(a('').hide().attr('src', h)) } catch (i) { c.captureException(i) } u = !0 } }) } var s = { }, t = !1, u = !1, v = !1, w = !1, x = { }; return s.init = function (a) { r(window, a) }, s.getEventTrackingArea = function (b) { return a(b.currentTarget).closest('[data-tracking-area]').attr('data-tracking-area') }, s.load3rdParties = function (d, f) { if (g.glitter && !t) { var h = n.lounge.tracking || { }, i = h.iframe_limit || 0, j = { postCount: d.get('posts') || 0, likeCount: d.get('likes') || 0, postVoteCount: b.reduce(d.posts.pluck('likes'), function (a, b) { return a + b }, 0), referrer: encodeURIComponent(f.config.referrer), tcString: x.tcString || '' }; a.ajax({ dataType: 'jsonp', cache: !0, url: g.glitter, data: { forum_shortname: d.forum.id, thread_id: d.id, referer: f.config.hostReferrer, tc: x.tcString || '' }, jsonpCallback: 'dsqGlitterResponseHandler', success: function (d) { var f = a('body'); b.each(d, function (d) { if (!('img' !== d.type && 'iframe' !== d.type || 'iframe' === d.type && (i -= 1, i < 0))) { var g; try { g = d.url.replace(/\{\{(.+?)\}\}/g, function (a, c) { var d = c.trim(); if (!j.hasOwnProperty(d)) throw new Error('Unknown template variable in tracker URL: ' + d); return b.escape(j[d]) }); var h = a('<' + d.type + '>').hide().attr('src', g); d.logging && h.on('load', function () { e.logStat('glitter.loaded.' + d.logging) }), f.append(h) } catch (k) { c.captureException(k) } } }) }, error: function () { e.logStat('glitter.error') } }), t = !0 } }, s.shouldTrack = function (a, b) { var c = arguments.length > 2 && void 0 !== arguments[2] && arguments[2]; return !(Boolean(a && a.get('settings').disable3rdPartyTrackers ^ c) || b && b.get('disable3rdPartyTrackers') || '1' === o.cookies.read('disqus_tracking_optout') || o.isDNTEnabled() || s.isPrivate(b)) }, s.isPrivate = function (a) { return q.getLounge().config.isPrivate && (!a || !a.get('hasAcceptedGdprTerms')) && !w }, s.reset = function () { t = !1, u = !1, v = !1, w = !1, x = { } }, s }), define('common/jsxUtils', [ 'underscore' ], function (a) { 'use strict'; return { append: function (b, c) { var d = function e(c) { if (null !== c) return a.isArray(c) ? void c.forEach(e) : a.isElement(c) || c && c.nodeType === window.Node.DOCUMENT_FRAGMENT_NODE ? void b.appendChild(c) : void b.appendChild(window.document.createTextNode(c)) }; d(c) } } }); var _extends = Object.assign || function (a) { for (var b = 1; b < arguments.length; b++) { var c = arguments[b]; for (var d in c) Object.prototype.hasOwnProperty.call(c, d) && (a[d] = c[d]) } return a }; define('react', [ 'jquery', 'underscore', 'common/jsxUtils' ], function (a, b, c) { 'use strict'; var d = window.document; return { createElement: function (e, f) { for (var g = arguments.length, h = Array(g > 2 ? g - 2 : 0), i = 2; i < g; i++) h[i - 2] = arguments[i]; if ('function' == typeof e) { h.length > 0 && (f = _extends({ children: 1 === h.length ? h[0] : h }, f)); var j = e(f); if (b.isArray(j)) { var k = d.createDocumentFragment(); return c.append(k, j), k } return j } if ('string' != typeof e) throw new Error('Unknown type'); var l = d.createElement(e), m = !1; return f && Object.keys(f).forEach(function (b) { var c = f[b]; if (/^(?:data-|aria-|role$)/.test(b)) null !== c && l.setAttribute(b, c); else if ('dangerouslySetInnerHTML' === b) m = !0, l.innerHTML = c && c.__html || ''; else if ('style' === b) Object.keys(c).forEach(function (a) { l.style[a] = c[a] }); else if (/^on[A-Z]/.test(b)) c && a(l).on(b.slice(2).toLowerCase(), c); else if ('key' === b); else try { l[b] = c } catch (d) { } }), m || c.append(l, h), l } } }), define('react-dom', [ 'common/jsxUtils' ], function (a) { 'use strict'; return { render: function (b, c, d) { return c && (c.innerHTML = '', a.append(c, b)), d && d(), null } } }), define('core/shared/urls', [ 'require', 'core/utils/object/extend', 'core/utils/url/serialize', 'core/utils/url/serializeArgs' ], function (a) { 'use strict'; var b = a('core/utils/object/extend'), c = a('core/utils/url/serialize'), d = a('core/utils/url/serializeArgs'), e = 'default', f = { lounge: 'http://disqus.com/embed/comments/', home: 'https://disqus.com/home/'.replace('home/', ''), recommendations: 'http://disqus.com/recommendations/' }, g = function (a) { return 'https://' + a.replace(/^\s*(\w+:)?\/\//, '') }, h = function (a, h, i, j) { var k = f[a]; if (!k) throw new Error('Unknown app: ' + a); 'preview' === e && j && (e += '-' + j); var l = g(k), m = b({ base: e }, h || { }), n = i ? '#' + d(i) : ''; return c(l, m) + n }; return { BASE: e, apps: f, get: h, ensureHTTPSProtocol: g } }), define('core/apps/BaseApp', [ 'require', 'core/Events', 'core/utils/object/extend', 'core/utils/object/has', 'core/utils/uniqueId' ], function (a) { 'use strict'; var b = a('core/Events'), c = a('core/utils/object/extend'), d = a('core/utils/object/has'), e = a('core/utils/uniqueId'), f = function (a) { this.uid = e('dsq-app'), this.settings = a || { }; var b = [ ], c = this.constructor.prototype; do b.unshift(c), c = c.constructor.__super__; while (c); for (var f = 0, g = b.length; f < g; f++) c = b[f], d(c, 'events') && this.on(c.events, this), d(c, 'onceEvents') && this.once(c.onceEvents, this) }; return c(f.prototype, b), f.prototype.destroy = function () { this.off(), this.stopListening() }, f.extend = function (a, b) { var e, f = this; e = a && d(a, 'constructor') ? a.constructor : function () { return f.apply(this, arguments) }, c(e, f, b); var g = function () { this.constructor = e }; return g.prototype = f.prototype, e.prototype = new g, a && c(e.prototype, a), e.__super__ = f.prototype, e }, f }), define('core/common/kernel/utils', [ 'require' ], function (a) { 'use strict'; function b(a) { return e.getElementById(a) || e.body || e.documentElement } function c(a) { return f.href = a, f.hostname } function d(a, b) { b = b || e.documentElement; for (var c = a, d = 0, f = 0; c && c !== b; ) d += c.offsetLeft, f += c.offsetTop, c = c.offsetParent; return { top: f, left: d, height: a.offsetHeight, width: a.offsetWidth } } var e = window.document, f = e.createElement('a'); return { getContainer: b, getHost: c, getOffset: d } }), define('core/host/json', [ 'require', 'core/host/globalFromSandbox' ], function (a) { 'use strict'; var b, c = window, d = a('core/host/globalFromSandbox'); return b = '[object JSON]' === c.Object.prototype.toString.call(c.JSON) ? c.JSON : d('JSON', c), b ? b : { } }), define('core/common/kernel/WindowBase', [ 'require', 'core/Events', 'core/utils/object/extend', 'core/utils/uniqueId', 'core/common/kernel/utils', 'core/host/json' ], function (a) { 'use strict'; var b = a('core/Events'), c = a('core/utils/object/extend'), d = a('core/utils/uniqueId'), e = a('core/common/kernel/utils'), f = a('core/host/json'), g = function (a) { a = a || { }, this.state = g.INIT, this.uid = a.uid || d('dsq-frame'), this.origin = a.origin, a.useSourcelessFrame ? this.host = e.getHost(window.location.href) : this.host = e.getHost(this.origin), this.target = a.target, this.sandbox = a.sandbox, this.window = null, g.windows[this.uid] = this, this.on('ready', function () { this.state = g.READY }, this), this.on('die', function () { this.state = g.KILLED }, this) }; return c(g, { INIT: 0, READY: 1, KILLED: 2, windows: { }, postMessage: function (a, b, c) { return a.postMessage(b, c) } }), c(g.prototype, b), g.prototype.requiresWindow = function (a) { var b = this; return function () { var c = Array.prototype.slice.call(arguments), d = function () { var e = b.window; e ? a.apply(b, c) : setTimeout(d, 500) }; b.isReady() ? d() : b.on('ready', d) } }, g.prototype.sendMessage = function (a, b) { var c = f.stringify({ scope: 'client', name: a, data: b }); this.requiresWindow(function (a) { g.postMessage(this.window, a, this.origin) }) (c) }, g.prototype.hide = function () { }, g.prototype.show = function () { }, g.prototype.url = function () { return this.target }, g.prototype.destroy = function () { this.state = g.KILLED, this.off() }, g.prototype.isReady = function () { return this.state === g.READY }, g.prototype.isKilled = function () { return this.state === g.KILLED }, g }), define('core/common/kernel/Iframe', [ 'require', 'core/utils/html/setInlineStyle', 'core/utils/object/extend', 'core/common/kernel/WindowBase', 'core/common/kernel/utils' ], function (a) { 'use strict'; var b = a('core/utils/html/setInlineStyle'), c = a('core/utils/object/extend'), d = a('core/common/kernel/WindowBase'), e = a('core/common/kernel/utils'), f = window.document, g = function (a) { d.call(this, a), this.styles = a.styles || { }, this.tabIndex = a.tabIndex || 0, this.title = a.title || 'Disqus', this.sandbox = a.sandbox, this.container = a.container, this.elem = null }; return c(g.prototype, d.prototype), g.prototype.load = function () { var a = this.elem = f.createElement('iframe'); a.setAttribute('id', this.uid), a.setAttribute('name', this.uid), a.setAttribute('allowTransparency', 'true'), a.setAttribute('frameBorder', '0'), a.setAttribute('scrolling', 'no'), this.role && a.setAttribute('role', this.role), a.setAttribute('tabindex', this.tabIndex), a.setAttribute('title', this.title), 'string' == typeof this.sandbox && a.setAttribute('sandbox', this.sandbox), this.setInlineStyle(this.styles) }, g.prototype.getOffset = function (a) { return e.getOffset(this.elem, a) }, g.prototype.setInlineStyle = function (a, c) { return b(this.elem, a, c) }, g.prototype.removeInlineStyle = function (a) { var b = this.elem.style; return 'removeProperty' in b ? void b.removeProperty(a) : void (b[a] = '') }, g.prototype.hide = function () { this.setInlineStyle('display', 'none') }, g.prototype.show = function () { this.removeInlineStyle('display') }, g.prototype.destroy = function () { return this.elem && this.elem.parentNode && (this.elem.parentNode.removeChild(this.elem), this.elem = null), d.prototype.destroy.call(this) }, g }), define('core/host/kernel', [ 'require', 'exports', 'module', 'core/Events', 'core/utils/lang/isString', 'core/utils/object/has', 'core/utils/object/extend', 'core/common/kernel/Iframe', 'core/common/kernel/utils', 'core/common/kernel/WindowBase', 'core/host/json', 'core/utils/function/throttle' ], function (a, b) { 'use strict'; var c = a('core/Events'), d = a('core/utils/lang/isString'), e = a('core/utils/object/has'), f = a('core/utils/object/extend'), g = a('core/common/kernel/Iframe'), h = a('core/common/kernel/utils'), i = a('core/common/kernel/WindowBase'), j = a('core/host/json'), k = window.document; b.throttle = a('core/utils/function/throttle'), window.addEventListener('message', function (a) { var c; try { c = j.parse(a.data) } catch (d) { return } var f = c.sender, g = e(i.windows, f) && i.windows[f]; g && h.getHost(a.origin) === g.host && (a.origin !== g.origin && (g.origin = a.origin), 'host' === c.scope && g.trigger(c.name, c.data), 'error' === c.name && b.trigger('error', c.data)) }), window.addEventListener('hashchange', function () { b.trigger('window.hashchange', { hash: window.location.hash }) }), window.addEventListener('resize', b.throttle(function () { b.trigger('window.resize') }, 250, 50)), k.addEventListener('mousemove', b.throttle(function () { b.trigger('window.mousemove') }, 250, 50)); var l = function () { b.trigger('window.scroll') }; window.addEventListener('scroll', b.throttle(l, 250, 50), !1), k.addEventListener('click', function () { b.trigger('window.click') }); var m = b.Popup = function (a) { a.uid = a.windowName, i.call(this, a) }; f(m.prototype, i.prototype), m.prototype.load = function () { var a = this.window = window.open('', this.uid || '_blank'); a.location = this.url() }, m.prototype.isKilled = function () { return i.prototype.isKilled() || this.window.closed }; var n = b.Channel = function (a) { var b = this; b.window = null, g.call(b, a), this.insertBeforeEl = a.insertBeforeEl, this.insertAfterEl = a.insertAfterEl, b.useSourcelessFrame = a.useSourcelessFrame, b.styles = f({ width: '1px', 'min-width': '100%', border: 'none', overflow: 'hidden', height: '0' }, a.styles || { }) }; f(n.prototype, g.prototype), n.prototype.load = function (a) { var b = this; g.prototype.load.call(b); var c = b.elem; if (c.setAttribute('width', '100%'), b.useSourcelessFrame) { var e = function () { var a = new window.XMLHttpRequest; a.open('GET', b.url()), a.onreadystatechange = function () { c.contentWindow && a.readyState === c.contentWindow.XMLHttpRequest.DONE && 200 === a.status && (c.contentWindow.document.open(), c.contentWindow.document.write(a.responseText), c.contentWindow.document.close()) }, a.send() }; b.on('redirect', function (a) { b.target = a, e() }), e() } else c.setAttribute('src', b.url()); c.addEventListener('load', function () { b.window = c.contentWindow, a && a() }); var f = d(b.container) ? h.getContainer(b.container) : b.container, i = (b.insertAfterEl ? b.insertAfterEl.nextSibling : b.insertBeforeEl) || null; f.insertBefore(c, i) }, n.prototype.destroy = function () { return this.window = null, g.prototype.destroy.call(this) }, b.on = c.on, b.off = c.off, b.trigger = c.trigger }), define('core/apps/WindowedApp', [ 'require', 'core/utils/object/extend', 'core/shared/urls', 'core/apps/BaseApp', 'core/host/kernel' ], function (a) { 'use strict'; var b = a('core/utils/object/extend'), c = a('core/shared/urls'), d = a('core/apps/BaseApp'), e = a('core/host/kernel'), f = window.document, g = d.extend({ name: null, loaderVersion: null, frame: null, origin: c.ensureHTTPSProtocol('https://disqus.com'), state: null, getUrl: function (a, d) { return this.loaderVersion && (d = b({ version: this.loaderVersion }, d)), c.ensureHTTPSProtocol(c.get(this.name, a, d, this.settings.previewVersion)) }, getFrameSettings: function () { var a = { target: this.getUrl(), origin: this.origin, uid: this.uid, sandbox: this.sandbox }, b = this.settings; return b.windowName ? a.windowName = b.windowName : a.container = b.container || f.body, b.styles && (a.styles = b.styles), a.useSourcelessFrame = b.useSourcelessFrame, a }, getFrame: function () { var a = this.getFrameSettings(), b = a.windowName ? e.Popup : e.Channel; return new b(a) }, setState: function (a) { var b = this.constructor; return a in b.states && (this.state = b.states[a], void this.trigger('state:' + a)) }, init: function () { var a, b = this; b.frame = a = this.getFrame(), b.listenTo(a, 'all', function (c, d) { b.trigger('frame:' + c, d, a) }), b.listenTo(a, 'resize', function (a) { b.lastResizedHeight = a.height }), b.trigger('change:frame', a), b.frame.load(function () { b.setState('LOADED') }), b.setState('INIT') }, destroy: function () { var a = this.frame; a && (this.stopListening(a), a.destroy()), this.setState('KILLED'), this.frame = null, d.prototype.destroy.call(this) }, events: { 'frame:ready': function () { this.setState('READY') } } }, { states: { INIT: 0, LOADED: 1, READY: 2, RUNNING: 3, KILLED: 4 } }); return g }), define('core/utils/OnceTimer', [ 'require', 'exports', 'module' ], function (a, b, c) { 'use strict'; c.exports = function (a, b) { var c = null, d = !1; this.start = function () { d || (c = setTimeout(function () { d = !0, a() }, b)) }, this.clear = function () { clearTimeout(c) } } }), define('core/utils/html/toHexColorString', [ ], function () { 'use strict'; function a(a) { if (a = Number(a), isNaN(a) || a > 255) throw new Error('Color components should be numbers less than 256'); return a = a.toString(16), 1 === a.length ? '0' + a : String(a) } return function (b) { return '#' + a(b.red) + a(b.green) + a(b.blue) } }), define('core/utils/sandbox', [ ], function () { 'use strict'; var a = [ 'allow-forms', 'allow-pointer-lock', 'allow-popups', 'allow-same-origin', 'allow-scripts', 'allow-top-navigation' ], b = function (b) { return b ? a.reduce(function (a, c) { return b[c] && (a += c + ' '), a }, '').trim() : '' }; return { getAttribute: b } }), define('core/utils/url/parseQueryString', [ 'core/utils/collection/each' ], function (a) { 'use strict'; return function (b) { 'undefined' == typeof b && (b = window.location.search); var c = { }; return a(b.substr(1).split('&'), function (a) { var b = a.split('=').map(function (a) { return decodeURIComponent(a.replace(/\+/g, '%20')) }); b[0] && (c[b[0]] = b[1]) }), c } }), define('core/analytics/reporting', [ 'require', 'core/utils/collection/each', 'core/utils/url/serialize', 'core/config/urls' ], function (a) { 'use strict'; function b(a) { var b = a.split('.'), c = b.length > 2 ? b[b.length - 2] : ''; return c.match(/^[0-9a-f]{32}$/i) && c } function c(a) { (new window.Image).src = g(i + '/stat.gif', { event: a }) } function d(a) { (new window.Image).src = g(i + '/event.gif', a) } function e(a) { var b = new window.URLSearchParams; f(a, function (a, c) { void 0 !== a && b.append(c, a) }); var c = new window.XMLHttpRequest; c.open('POST', i + '/event.json', !0), c.withCredentials = !0, c.send(b) } var f = a('core/utils/collection/each'), g = a('core/utils/url/serialize'), h = a('core/config/urls'), i = h.jester; return { getLoaderVersionFromUrl: b, logStat: c, reportJester: d, reportJesterPOST: e } }), define('core/ads/safeFrameUtils', [ ], function () { 'use strict'; var a = function (a) { return null !== a && !isNaN(Number(a)) && isFinite(a) }, b = function (a) { return Math.min.apply(Math, _toConsumableArray(a)) || 0 }, c = function (a) { return Math.max.apply(Math, _toConsumableArray(a)) || 0 }; return { min: b, max: c, isNumeric: a } }); var _createClass = function () { function a(a, b) { for (var c = 0; c < b.length; c++) { var d = b[c]; d.enumerable = d.enumerable || !1, d.configurable = !0, 'value' in d && (d.writable = !0), Object.defineProperty(a, d.key, d) } } return function (b, c, d) { return c && a(b.prototype, c), d && a(b, d), b } }(); define('core/ads/NodeRect', [ 'core/ads/safeFrameUtils' ], function (a) { 'use strict'; var b = function () { function b() { return _classCallCheck(this, b), 1 !== arguments.length || a.isNumeric(arguments[0]) ? void this.fromArray(arguments) : Array.isArray(arguments[0]) ? this.fromArray(arguments[0]) : this.fromObject(arguments[0]) } return _createClass(b, [ { key: 'fromArray', value: function (a) { this.reset(), a.length >= 6 ? (this.top = a[0], this.right = a[1], this.bottom = a[2], this.left = a[3], this.width = a[4], this.height = a[5]) : a.length >= 4 ? (this.top = a[0], this.right = a[1], this.bottom = a[2], this.left = a[3]) : 3 === a.length ? (this.top = a[0], this.right = a[1], this.bottom = a[2], this.left = 0) : 2 === a.length ? (this.top = a[0], this.right = a[1], this.bottom = a[0], this.left = a[1]) : (this.top = a[0], this.right = a[0], this.bottom = a[0], this.left = a[0]), this.update() } }, { key: 'fromObject', value: function (a) { return this.fromArray([a.top, a.right, a.bottom, a.left, a.width, a.height]) } }, { key: 'update', value: function () { this.width || (this.width = this.right - this.left), this.height || (this.height = this.bottom - this.top) } }, { key: 'reset', value: function (a) { a = a || 0, this.top = a, this.right = a, this.bottom = a, this.left = a, this.width = a, this.height = a } }, { key: 'getArea', value: function () { return (this.right - this.left) * (this.bottom - this.top) } } ]), b }(); return b.getOverlapRect = function (c, d) { var e = a.max([c.left, d.left]), f = a.min([c.left + c.width, d.left + d.width]), g = a.max([c.top, d.top]), h = a.min([c.top + c.height, d.top + d.height]); return f >= e && h >= g && new b(g, f, h, e, f - e, h - g) }, b.getOverlapArea = function (b, c) { var d = a.max([0, a.min([b.right, c.right]) - a.max([b.left, c.left])]), e = a.max([0, a.min([b.bottom, c.bottom]) - a.max([b.top, c.top])]); return d * e }, b }), define('core/ads/domUtils', [ 'core/ads/NodeRect' ], function (a) { 'use strict'; var b = 9, c = function (a) { return a && a.parentNode }, d = function (a, b) { if (!a) return null; var c = window.document.defaultView.getComputedStyle(a); return b && c.hasOwnProperty(b) ? c[b] : c }, e = function () { return { x: window.pageXOffset, y: window.pageYOffset } }, f = function (b) { var c = void 0; if (b && b.style) { var d = b.style.display; b.style.display = 'block', c = b.getBoundingClientRect(), b.style.display = d, c = new a(c); var f = e(); c.left += f.x, c.right += f.x, c.top += f.y, c.bottom += f.y } else c = new a(0); return c }, g = function (a, b) { var c = f(a); if (b) { var d = f(b); c.top = d.top - d.top + b.scrollTop, c.bottom = c.top + c.height + b.scrollTop, c.left = c.left - d.left + b.scrollLeft, c.right = c.left + c.width + b.scrollLeft } return c }, h = function () { var b = e(), c = b.y, d = b.x + window.innerWidth, f = b.y + window.innerHeight, g = b.x, h = window.innerWidth, i = window.innerHeight; return new a(c, d, f, g, h, i) }, i = function (a) { try { return a.nodeType === b ? a : a.ownerDocument } catch (c) { return null } }, j = function (a) { var b = i(a), c = void 0; try { b && (c = b.parentWindow || b.defaultView || window) } catch (d) { c = window } return c }, k = function (b) { var c = j(b), d = new a(0, c.innerWidth, c.innerHeight, 0, c.innerWidth, c.innerHeight), f = e(); return d.left += f.x, d.right += f.x, d.top += f.y, d.bottom += f.y, d }, l = function (a) { var b = i(a); if (b) return b.documentElement || b.body }, m = function (b) { var c = l(b) || { }, d = new a; return d.right = d.width = c.scrollWidth || 0, d.bottom = d.height = c.scrollHeight || 0, d }, n = function (a, b) { for (; b; ) { if (b === a) return !0; b = b.parentNode } return !1 }, o = function (a) { var b = d(a); return 'inline-block' === b.display || 'none' !== b['float'] || 'absolute' === b.position || 'fixed' === b.position || 'auto' !== b.width || 'auto' !== b.height }, p = function (a) { var b = d(a), c = { }; return 'scroll' === b.overflowX || 'auto' === b.overflowX ? c.xscroll = a.offsetWidth - a.clientWidth : c.xscroll = 0, 'scroll' === b.overflowY || 'auto' === b.overflowY ? c.yscroll = a.offsetHeight - a.clientHeight : c.yscroll = 0, c.xhidden = 'hidden' === b.overflowX, c.yhidden = 'hidden' === b.overflowY, c }, q = function (a) { var b = d(a); return !!(b.clip && 'auto' !== b.clip || b.clipPath && 'none' !== b.clipPath) }; return { getParentNode: c, getWindow: j, getScroll: e, getRect: f, getRectRelativeTo: g, getViewportRect: h, getDocument: i, getWindowRect: k, getRootNode: l, getRootRect: m, getNodeStyle: d, isParentOf: n, hasLayout: o, getNodeOverflow: p, isNodeClipped: q } }); var _createClass = function () { function a(a, b) { for (var c = 0; c < b.length; c++) { var d = b[c]; d.enumerable = d.enumerable || !1, d.configurable = !0, 'value' in d && (d.writable = !0), Object.defineProperty(a, d.key, d) } } return function (b, c, d) { return c && a(b.prototype, c), d && a(b, d), b } }(); define('core/ads/Geom', [ 'core/ads/domUtils', 'core/ads/safeFrameUtils' ], function (a, b) { 'use strict'; var c = 1, d = function () { function d(b) { _classCallCheck(this, d), this.node = b, this.document = a.getDocument(b), this.window = a.getWindow(b), this.root = a.getRootNode(b), this.ref = this.getRefNode(b.parentNode) } return _createClass(d, [ { key: 'getRefNode', value: function (b) { for (; b && b.nodeType === c; ) { var d = a.getNodeStyle(b); if (a.hasLayout(b) || 'block' === d.display || 'none' !== d.clear) { var e = a.getNodeOverflow(b); if (e.xscroll || e.yscroll || e.xhidden || e.yhidden) return b; if (a.isNodeClipped(b)) return b } b = b.parentNode } return this.root } }, { key: 'getNodesOver', value: function (d, e) { e = e || 1; var f = [ ], g = a.getRect(d), h = a.getRect(this.ref), i = a.getViewportRect(d); if (!window.document.elementFromPoint) return f; for (var j = { top: b.max([g.top, h.top]) - i.top, right: b.min([g.right, h.right]) - i.left, bottom: b.min([g.bottom, h.bottom]) - i.top, left: b.max([g.left, h.left]) - i.left }, k = (j.right - j.left) / 10, l = (j.bottom - j.top) / 10, m = j.left; m < j.right; m += k) for (var n = j.top; n < j.bottom; n += l) { for (var o = window.document.elementFromPoint(m, n); o && o.nodeType === c; ) { var p = a.getNodeStyle(o); if (a.hasLayout(o) || 'block' === p.display || 'none' !== p.clear) break; o = o.parentNode } o && o.nodeType === c && o !== this.node && o !== this.root && !a.isParentOf(o, this.node) && (f.push(o), f.length >= e && (m = j.right, n = j.bottom)) } return f } }, { key: 'getWindowGeom', value: function () { var a = this.window.innerHeight || 0, b = this.window.innerWidth || 0, c = this.window.screenY || this.window.screenTop || 0, d = c + a, e = this.window.screenX || this.window.screenLeft || 0, f = e + b; return { t: c, r: f, b: d, l: e, w: b, h: a } } }, { key: 'getSelfGeom', value: function () { var c = a.getRect(this.node), d = a.getRect(this.ref), e = a.getNodeStyle(this.node), f = a.getWindowRect(this.node), g = c.width, h = c.height; this.ref !== this.root && (g = b.max([0, b.min([c.right, d.right]) - b.max([c.left, d.left])]), h = b.max([0, b.min([c.bottom, d.bottom]) - b.max([c.top, d.top])])); var i = b.max([0, b.min(c.right, f.right) - b.max([c.left, f.left])]), j = b.max([0, b.min([c.bottom, f.bottom]) - b.max([c.top, f.top])]), k = b.min([g, i]), l = b.min([h, j]), m = c.width ? k / c.width : 0, n = c.height ? l / c.height : 0, o = k * l / (c.width * c.height), p = 1, q = this.getNodesOver(this.node, p); if (q.length) { var r = a.getRect(q[0]), s = b.max([0, b.min([r.right, c.right]) - b.max([r.left, c.left])]), t = b.max([0, b.min([r.bottom, c.bottom]) - b.max([r.top, c.top])]); o = b.max([0, (k * l - s * t) / (c.width * c.height)]) } var u = a.getScroll(); return { t: c.top - u.y, r: c.right - u.x, b: c.bottom - u.y, l: c.left - u.x, z: e.zIndex, w: c.width, h: c.height, xiv: 1 === m ? '1' : Number(m).toFixed(2), yiv: 1 === n ? '1' : Number(n).toFixed(2), iv: 1 === o ? '1' : Number(o).toFixed(2) } } }, { key: 'getExpandGeom', value: function () { var c = a.getRect(this.ref), d = a.getRect(this.node), e = a.getWindowRect(this.node), f = { top: b.max([c.top, e.top]), right: b.min([c.right, e.right]), bottom: b.min([c.bottom, e.bottom]), left: b.max([c.left, e.left]) }, g = a.getNodeOverflow(this.ref); return { t: b.max([0, d.top - f.top]), r: b.max([0, f.right - d.right]), b: b.max([0, f.bottom - d.bottom]), l: b.max([0, d.left - f.left]), xs: Boolean(g.yscroll), yx: Boolean(g.xscroll) } } }, { key: 'getGeom', value: function () { return { win: this.getWindowGeom(), self: this.getSelfGeom(), exp: this.getExpandGeom() } } } ]), d }(), e = { get: function (a) { var b = new d(a); return b.getGeom() } }; return e }), define('core/ads/ads', [ 'require', 'core/shared/urls', 'core/apps/WindowedApp', 'core/host/json', 'stance/main', 'stance/utils', 'core/common/kernel/WindowBase', 'core/utils/OnceTimer', 'core/utils/html/toHexColorString', 'core/utils/object/extend', 'core/utils/sandbox', 'core/utils/url/parseQueryString', 'core/utils/url/serialize', 'core/utils/urls', 'core/utils/urls', 'core/analytics/reporting', 'core/ads/Geom' ], function (a) { 'use strict'; var b = a('core/shared/urls'), c = a('core/apps/WindowedApp'), d = a('core/host/json'), e = a('stance/main'), f = a('stance/utils'), g = a('core/common/kernel/WindowBase'), h = a('core/utils/OnceTimer'), i = a('core/utils/html/toHexColorString'), j = a('core/utils/object/extend'), k = a('core/utils/sandbox'), l = a('core/utils/url/parseQueryString'), m = a('core/utils/url/serialize'), n = a('core/utils/urls').getOrigin, o = a('core/utils/urls').getQuery, p = a('core/analytics/reporting'), q = a('core/ads/Geom'), r = c.extend({ name: 'ads', origin: void 0, onceEvents: { 'view:enter': function () { this._reportLegacy({ verb: 'view', adverb: '0ms-no50perc' }) }, 'view:iab': function () { this._reportLegacy({ verb: 'view', adverb: 'iab-scroll' }) } }, events: { 'frame:ready': function (a) { this.forumId = a.forumId, this._reportLegacy({ verb: 'load', extra_data: a.extraData, advertisement_id: a.advertisement_id, provider: a.provider }), this.bindViewEvents(), this.triggerGeomUpdate() }, 'frame:resize': function (a) { this.frame.setInlineStyle('height', a.height + 'px'), 0 === a.height ? this.trigger('ad-placement-empty') : (a.adWidth && this.frame.setInlineStyle('width', a.adWidth + 'px'), this.trigger('ad-placement-filled')), this.triggerGeomUpdate() }, 'frame:click': function () { this._reportOnce({ verb: 'click' }, 'click') }, 'frame:hover': function () { this._reportOnce({ verb: 'hover' }, 'hover') }, 'frame:error-provider-not-ready': function (a) { this._reportLegacy({ verb: 'fail', object_type: 'provider', object_id: a.provider || this.getProvider(), adverb: 'provider_not_ready' }) }, 'frame:error-no-height': function (a) { this._reportLegacy({ verb: 'fail', object_type: 'provider', object_id: a.provider || this.getProvider(), adverb: 'no_height' }) }, 'frame:clearSandbox': function () { this.frame.elem.hasAttribute('sandbox') && this.frame.elem.removeAttribute('sandbox') }, 'frame:$sf-init': function () { this.settings.isOnHostPage && (this.isSafeframe = !0) }, 'frame:error': function (a) { this.settings.isOnHostPage && this.postMessageDirect({ event: 'error', data: { error: a } }) } }, constructor: function () { c.apply(this, arguments), this.origin = n(this.settings.adUrl), this._reportOnceHistory = { }, this.settings.isOnHostPage && (this.detectLazyload = this.detectLazyload.bind(this), window.addEventListener('scroll', this.detectLazyload)); var a = this.settings.adUrl.indexOf('/ads-iframe/taboola/') >= 0; this.settings.useSourcelessFrame = this.settings.sourcelessIframe && this.settings.isOnHostPage && (!this.settings.defaultPlacementUrl || !this.settings.adBlockEnabled) && !a }, init: function () { if (this.settings.forum = l(o(this.settings.adUrl)).shortname, this.settings.forum) { var a = window.navigator && window.navigator.userAgent || window.navigator && window.navigator.vendor || window.opera, d = this.settings.disableAdsIos && /iP(hone|od|ad)/.test(a) || this.settings.disableAdsAndroid && /Android/.test(a), e = this.settings.disableAds, f = this.settings.isInHome || this.settings.isOnHostPage && 0 === window.location.href.indexOf(b.apps.home); if (!f && e && this.settings.canDisableAds || d) return void this.trigger('prevented-ad-load'); this._reportOnce({ verb: 'call', object_type: 'provider', object_id: this.getProvider(), adjective: 1 }, 'call'), this.settings.sandboxAds && (this.sandbox = k.getAttribute({ 'allow-scripts': !0, 'allow-same-origin': !0, 'allow-forms': !0, 'allow-popups': !0 })), c.prototype.init.call(this) } }, detectLazyload: function () { if (this.frame && this.settings.isOnHostPage) { var a = this.frame.elem.getBoundingClientRect().top, b = a - window.innerHeight, c = window.innerHeight * this.settings.lazyloadViewports; b < c && (this.postMessageDirect({ event: 'lazyload' }), window.removeEventListener('scroll', this.detectLazyload)) } }, getProvider: function () { if (this._provider) return this._provider; var a = this.settings.adUrl.match(/provider=(\w+)/); return a && (this._provider = a[1]), this._provider }, getUrl: function () { var a, b = this.settings; return a = 'inthreaddisqusadstxt' === b.experiment.experiment && 'active' === b.experiment.variant && 'inthread' === b.placement ? window.document.location.href : b.isOnHostPage ? b.url || window.document.location.href : b.url || b.referrer, m(b.adUrl, { anchorColor: i(b.anchorColor), colorScheme: b.colorScheme, sourceUrl: a, typeface: b.typeface, canonicalUrl: b.canonicalUrl, disqus_version: b.version, deviceWidth: b.deviceWidth, maxWidth: b.maxWidth }) }, triggerGeomUpdate: function () { if (this.frame.elem && this.isSafeframe && this.settings.isOnHostPage) { var a = q.get(this.frame.elem); this.postMessageDirect({ event: 'geom-update', data: { geom: a } }) } }, bindViewEvents: function () { if (!this._viewEventsBound) { this._viewEventsBound = !0, e.bindWindowEvents(!0); var a = this, b = function (b, c) { a.postMessageDirect({ event: b, percentViewable: c }) }, c = 1000, d = new h(function () { a.trigger('view:iab'), b('view:iab') }, c), g = !1; this.listenTo(e({ el: this.frame.elem }), { enter: function () { a.trigger('view:enter'), b('view:enter'), a.triggerGeomUpdate() }, exit: function () { b('view:exit'), g && (g = !1, b('view:50out'), d.clear()), a.triggerGeomUpdate() }, visible: function (c, e) { var h = f.visiblePercent(e, c.offset()), i = 50; h >= i && !g ? (g = !0, b('view:50in'), d.start()) : h < i && g && (g = !1, b('view:50out'), d.clear()), b('view', h), a.triggerGeomUpdate() } }) } }, postMessageDirect: function (a) { this.frame.requiresWindow(function (a) { var b = d.stringify(j({ }, a, { space: 'disqus' })); g.postMessage(this.window, b, this.origin), g.postMessage(this.window, 'disqus.' + a.event, this.origin) }) (a) }, _report: function (a) { var b = arguments.length > 1 && void 0 !== arguments[1] ? arguments[1] : { }, c = this.settings, d = b.provider || this.getProvider(); a.forum_id = c.forumId || this.forumId; var e; e = c.placement && c.placement.indexOf('timeline') > - 1 ? 'home' : 'recommendations' === c.placement ? 'recommendations' : 'embed'; var f = b.usePOST ? 'reportJesterPOST' : 'reportJester'; p[f](j({ imp: c.impressionId, experiment: c.experiment.experiment, variant: c.experiment.variant, service: c.experiment.service, area: c.placement, product: e, forum: c.forum, zone: 'thread', version: c.loaderVersion, page_url: c.referrer || window.document.location.href, page_referrer: c.hostReferrer || window.document.referrer, object_type: 'advertisement', provider: d, event: 'activity' }, a)) }, _reportLegacy: function (a) { var b = this.settings; this._report(j({ ad_product_name: 'iab_display', ad_product_layout: 'iab_display', bin: 'embed:promoted_discovery:' + b.experiment.service + ':' + b.experiment.experiment + ':' + b.experiment.variant, object_id: a.advertisement_id ? '[' + a.advertisement_id + ']' : '', section: 'default' }, a)) }, _reportOnce: function (a, b) { this._reportOnceHistory[b] || (this._reportLegacy(a), this._reportOnceHistory[b] = !0); }, getFrameSettings: function () { var a = c.prototype.getFrameSettings.call(this); return a.insertBeforeEl = this.settings.insertBeforeEl, a.insertAfterEl = this.settings.insertAfterEl, a } }), s = function (a) { return a = a || { }, a.experiment || (a.experiment = { experiment: a.experimentName, variant: a.experimentVariant, service: a.experimentService }), new r(a) }; return { Ads: s } }), define('core/api', [ 'jquery', 'underscore', 'backbone', 'core/config', 'core/utils' ], function (a, b, c, d, e) { 'use strict'; function f(a) { return l.href = a, l.origin || l.protocol + '//' + l.hostname + (l.port ? ':' + l.port : '') } function g(a) { return a.replace(/^(http:)?\/\//, 'https://') } function h(c) { c = b.defaults(c, m), c.traditional = !0, f(window.location.href) !== f(c.url) && (c.xhrFields = { withCredentials: !0 }), c.omitDisqusApiKey || (c.data = c.data || { }, window.FormData && c.data instanceof window.FormData ? c.url = e.serialize(c.url, { api_key: d.keys.api }) : c.data.api_key = d.keys.api); var g = c.error; return c.error = function (a) { n.trigger('error', a), b.isFunction(g) && g(a) }, a.ajax(c) } function i(a) { return /(https?:)?\/\//.test(a) ? g(a) : d.urls.api + a } function j(a, c) { return c = c || { }, c.url = i(a), c.omitDisqusApiKey || (c.data = b.extend(c.data || { }, { api_key: d.keys.api })), n.trigger('call', c), h(c).always(b.bind(this.trigger, this, 'complete', c)) } var k = window.document, l = k.createElement('a'), m = { }, n = { ERROR_CODES: { OBJ_NOT_FOUND: 8, MAX_ITEMS_REACHED: 24 }, ajax: h, call: j, getURL: i, defaults: function (a) { Object.keys(a).forEach(function (c) { var d = a[c], e = m[c]; b.isObject(d) && b.isObject(e) ? b.extend(e, d) : m[c] = d }) }, headers: function (a) { var c = b.extend({ }, m.headers, a); return m.headers = b.pick(c, Boolean), m.headers }, makeHttps: g }; return b.extend(n, c.Events), n }), define('core/mediaConfig', [ 'underscore', 'backbone' ], function (a, b) { 'use strict'; function c() { var b = window.document.body.offsetWidth, c = d, e = c.length; return a.find(c, function (a, d) { return d + 1 === e || Math.abs(c[d + 1] - b) > Math.abs(c[d] - b) }) } var d = [ 320, 480, 600, 800 ], e = new b.Model({ collapsed: !1, defaultIframeHeight: 300, mediaPersistedWidths: d, loadedThumbnailWidth: c() }); return e.findClosestThumbnailSize = c, e }), define('core/mixins/appliesPublisherClasses', [ 'jquery', 'underscore', 'core/switches', 'remote/config' ], function (a, b, c, d) { 'use strict'; function e() { this._getStyleProperty = function (a) { var b = this.forum.get(a); return this.config.forceAutoStyles || 'auto' === b ? this.config[a] : b }, this.getTypeface = function () { return this._getStyleProperty('typeface') }, this.getColorScheme = function () { return this._getStyleProperty('colorScheme') }, this.getAnchorColorScheme = function () { return this.config.anchorColorScheme }, this.getFont = function () { return this.forum.get('customFont') }, this.convertFontToClass = function (a) { return a ? a.toLowerCase().replace(/\+/g, '-') : '' }, this.convertFontToStyle = function (a) { return a ? a.replace(/\+/g, ' ') : '' }, this.isFontAllowed = function (a) { return !(!a || !d.lounge.font_options) && d.lounge.font_options.some(function (b) { return a === b.name }) }, this.downloadFont = function (a) { var b = window.document, c = b.createElement('style'); c.type = 'text/css'; var d = this.convertFontToClass(a.name), e = this.convertFontToStyle(a.name), f = a.category, g = '@import url("https://fonts.googleapis.com/css2?family=' + a.name + ':ital,wght@0,400;0,500;0,600;0,700;1,400;1,700&display=swap"); ', h = [ '', 'input', 'select', 'textarea' ].map(function (a) { return 'body.' + d + ' ' + a }).join(', '); g += h + ' { font-family: ' + e + ', ' + f + '; }', c.styleSheet ? c.styleSheet.cssText = g : c.appendChild(b.createTextNode(g)); var i = b.head || b.getElementsByTagName('head') [0] || b.body; i.appendChild(c) }, this.applyPublisherClasses = function () { var e = a('body'), f = this.getFont(); !f && c.isFeatureActive('embed_refresh', { forum: this.forum.id }) && 'sans-serif' === this.getTypeface() && (f = 'Roboto'); var g = f && b.find(d.lounge.font_options, function (a) { return a.name === f }); g ? (this.downloadFont(g), e.addClass(this.convertFontToClass(g.name))) : 'serif' === this.getTypeface() ? e.addClass('serif') : e.addClass('sans-serif'), 'dark' === this.getColorScheme() && e.addClass('dark'), c.isFeatureActive('embed_refresh', { forum: this.forum.id }) && ('dark' === this.getAnchorColorScheme() ? e.addClass('dark-anchor') : e.addClass('light-anchor')) } } return e }), define('core/templates/handlebars.partials', [ 'handlebars' ], function (a) { a.registerPartial('cardGuestUser', a.template({ 1: function (a, b, c, d, e) { var f, g = null != b ? b : a.nullContext || { }, h = a.lambda, i = a.escapeExpression; return '
  • \n\n' + (null != (f = c['if'].call(g, null != b ? b.isRefreshEnabled : b, { name: 'if', hash: { }, fn: a.program(6, e, 0), inverse: a.program(8, e, 0), data: e, loc: { start: { line: 4, column: 0 }, end: { line: 8, column: 7 } } })) ? f : '') + '\n\n' + i(h(null != b ? b.guestText : b, b)) + '\n\n
  • \n' }, 2: function (a, b, c, d, e) { return 'highlight' }, 4: function (a, b, c, d, e) { return 'avatar--refresh' }, 6: function (a, b, c, d, e) { return '
    G
    \n' }, 8: function (a, b, c, d, e) { var f = a.escapeExpression; return '' + f(c.gettext.call(null != b ? b : a.nullContext || {
      }, 'Avatar', {
        name: 'gettext',
        hash: {
        },
        data: e,
        loc: {
          start: {
            line: 7,
            column: 35
          },
          end: {
            line: 7,
            column: 55
          }
        }
      })) + '\n' }, 10: function (a, b, c, d, e) { return 'username--refresh' }, compiler: [ 8, '>= 4.3.0' ], main: function (a, b, c, d, e) { var f; return null != (f = c['if'].call(null != b ? b : a.nullContext || { }, null != b ? b.guestCount : b, { name: 'if', hash: { }, fn: a.program(1, e, 0), inverse: a.noop, data: e, loc: { start: { line: 1, column: 0 }, end: { line: 14, column: 7 } } })) ? f : '' }, useData: !0 })), a.registerPartial('cardGuestVoterText', a.template({ 1: function (a, b, c, d, e) { return ' ' + a.escapeExpression(c.gettext.call(null != b ? b : a.nullContext || { }, '%(guestCount)s Guest Votes', { name: 'gettext', hash: { guestCount: null != b ? b.guestCount : b }, data: e, loc: { start: { line: 1, column: 26 }, end: { line: 1, column: 90 } } })) + ' ' }, 3: function (a, b, c, d, e) { return ' ' + a.escapeExpression(c.gettext.call(null != b ? b : a.nullContext || { }, '1 Guest Vote', { name: 'gettext', hash: { }, data: e, loc: { start: { line: 1, column: 100 }, end: { line: 1, column: 126 } } })) + ' ' }, compiler: [ 8, '>= 4.3.0' ], main: function (a, b, c, d, e) { var f, g = null != b ? b : a.nullContext || { }; return (null != (f = c['if'].call(g, c.gt.call(g, null != b ? b.guestCount : b, 1, { name: 'gt', hash: { }, data: e, loc: { start: { line: 1, column: 6 }, end: { line: 1, column: 23 } } }), { name: 'if', hash: { }, fn: a.program(1, e, 0), inverse: a.program(3, e, 0), data: e, loc: { start: { line: 1, column: 0 }, end: { line: 1, column: 134 } } })) ? f : '') + '\n' }, useData: !0 })), a.registerPartial('cardOtherUserText', a.template({ 1: function (a, b, c, d, e) { return ' ' + a.escapeExpression(c.gettext.call(null != b ? b : a.nullContext || { }, '%(guestCount)s Others', { name: 'gettext', hash: { guestCount: null != b ? b.guestCount : b }, data: e, loc: { start: { line: 1, column: 26 }, end: { line: 1, column: 85 } } })) + ' ' }, 3: function (a, b, c, d, e) { return ' ' + a.escapeExpression(c.gettext.call(null != b ? b : a.nullContext || { }, '1 Other', { name: 'gettext', hash: { }, data: e, loc: { start: { line: 1, column: 95 }, end: { line: 1, column: 116 } } })) + ' ' }, compiler: [ 8, '>= 4.3.0' ], main: function (a, b, c, d, e) { var f, g = null != b ? b : a.nullContext || { }; return (null != (f = c['if'].call(g, c.gt.call(g, null != b ? b.guestCount : b, 1, { name: 'gt', hash: { }, data: e, loc: { start: { line: 1, column: 6 }, end: { line: 1, column: 23 } } }), { name: 'if', hash: { }, fn: a.program(1, e, 0), inverse: a.program(3, e, 0), data: e, loc: { start: { line: 1, column: 0 }, end: { line: 1, column: 124 } } })) ? f : '') + '\n' }, useData: !0 })), a.registerPartial('cardUser', a.template({ 1: function (a, b, c, d, e) { return 'highlight' }, 3: function (a, b, c, d, e) { return 'data-action="profile"' }, 5: function (a, b, c, d, e) { var f, g = null != b ? b : a.nullContext || { }; return '\n' + (null != (f = c['if'].call(g, null != b ? b.isRefreshEnabled : b, { name: 'if', hash: { }, fn: a.program(8, e, 0), inverse: a.program(9, e, 0), data: e, loc: { start: { line: 5, column: 0 }, end: { line: 13, column: 7 } } })) ? f : '') + '\n\n' + a.escapeExpression(a.lambda(null != b ? b.name : b, b)) + '\n\n' }, 6: function (a, b, c, d, e) { return 'avatar--refresh' }, 8: function (a, b, c, d, e) { var f; return null != (f = c['if'].call(null != b ? b : a.nullContext || { }, null != (f = null != b ? b.avatar : b) ? f.isCustom : f, { name: 'if', hash: { }, fn: a.program(9, e, 0), inverse: a.program(11, e, 0), data: e, loc: { start: { line: 6, column: 0 }, end: { line: 10, column: 7 } } })) ? f : '' }, 9: function (a, b, c, d, e) { var f, g = a.escapeExpression; return '' + g(c.gettext.call(null != b ? b : a.nullContext || {
      }, 'Avatar', {
        name: 'gettext',
        hash: {
        },
        data: e,
        loc: {
          start: {
            line: 7,
            column: 33
          },
          end: {
            line: 7,
            column: 53
          }
        }
      })) + '\n' }, 11: function (a, b, c, d, e) { return '
    ' + a.escapeExpression(a.lambda(null != b ? b.initials : b, b)) + '
    \n' }, 13: function (a, b, c, d, e) { return 'username--refresh' }, 15: function (a, b, c, d, e) { var f, g = null != b ? b : a.nullContext || { }, h = a.lambda, i = a.escapeExpression; return '\n' + (null != (f = c['if'].call(g, null != b ? b.isRefreshEnabled : b, { name: 'if', hash: { }, fn: a.program(8, e, 0), inverse: a.program(9, e, 0), data: e, loc: { start: { line: 20, column: 0 }, end: { line: 28, column: 7 } } })) ? f : '') + '\n\n' + i(h(null != b ? b.name : b, b)) + '\n\n' }, compiler: [ 8, '>= 4.3.0' ], main: function (a, b, c, d, e) { var f, g = null != b ? b : a.nullContext || { }; return '
  • \n' + (null != (f = c.if_all.call(g, c['switch'].call(g, 'sso_less_branding', { name: 'switch', hash: { forum: null != b ? b.forumId : b }, data: e, loc: { start: { line: 3, column: 10 }, end: { line: 3, column: 52 } } }), c.ne.call(g, null != b ? b.isSSOProfileUrl : b, !0, { name: 'ne', hash: { }, data: e, loc: { start: { line: 3, column: 53 }, end: { line: 3, column: 78 } } }), { name: 'if_all', hash: { }, fn: a.program(5, e, 0), inverse: a.program(15, e, 0), data: e, loc: { start: { line: 3, column: 0 }, end: { line: 33, column: 11 } } })) ? f : '') + '
  • \n' }, useData: !0 })), a.registerPartial('carouselArrowLeft', a.template({ compiler: [ 8, '>= 4.3.0' ], main: function (a, b, c, d, e) { return '\n' }, useData: !0 })), a.registerPartial('carouselArrowRight', a.template({ compiler: [ 8, '>= 4.3.0' ], main: function (a, b, c, d, e) { return '\n' }, useData: !0 })), a.registerPartial('channelsHeader', a.template({ compiler: [ 8, '>= 4.3.0' ], main: function (a, b, c, d, e) { var f = null != b ? b : a.nullContext || { }, g = a.escapeExpression; return '
    \n
    \n
    \n
    \n\n
    \n
    \n

    ' + g(c.gettext.call(f, 'Channels', { name: 'gettext', hash: { }, data: e, loc: { start: { line: 8, column: 36 }, end: { line: 8, column: 58 } } })) + '

    \n
    \n
    \n

    ' + g(c.gettext.call(f, 'Places to start your own discussions.', { name: 'gettext', hash: { }, data: e, loc: { start: { line: 11, column: 55 }, end: { line: 11, column: 106 } } })) + '

    \n
    \n
    \n\n' + g(c.gettext.call(f, 'About', { name: 'gettext', hash: { }, data: e, loc: { start: { line: 18, column: 0 }, end: { line: 18, column: 19 } } })) + '\n\n
    \n
    \n
    \n\n\n\n

    ' + g(c.gettext.call(f, 'About Channels', { name: 'gettext', hash: { }, data: e, loc: { start: { line: 29, column: 37 }, end: { line: 29, column: 65 } } })) + '

    \n
    \n' }, useData: !0 })), a.registerPartial('genericFollowButton', a.template({ 1: function (a, b, c, d, e) { return ' active' }, 3: function (a, b, c, d, e) { var f; return null != (f = c.unless.call(null != b ? b : a.nullContext || { }, null != b ? b.isFollowing : b, { name: 'unless', hash: { }, fn: a.program(4, e, 0), inverse: a.noop, data: e, loc: { start: { line: 1, column: 85 }, end: { line: 1, column: 127 } } })) ? f : '' }, 4: function (a, b, c, d, e) { return 'disabled' }, compiler: [ 8, '>= 4.3.0' ], main: function (a, b, c, d, e) { var f, g = null != b ? b : a.nullContext || { }, h = a.escapeExpression; return '\n' }, useData: !0 })) }), define('core/extensions/helpers/eq', [ ], function () { 'use strict'; return function (a, b) { return a === b } }), define('core/extensions/helpers/ne', [ ], function () { 'use strict'; return function (a, b) { return a !== b } }), define('core/extensions/helpers/gt', [ ], function () { 'use strict'; return function (a, b) { return a > b } }), define('core/extensions/helpers/lt', [ ], function () { 'use strict'; return function (a, b) { return a < b } }), define('core/extensions/helpers/ge', [ ], function () { 'use strict'; return function (a, b) { return a >= b } }), define('core/extensions/helpers/le', [ ], function () { 'use strict'; return function (a, b) { return a <= b } }), define('core/extensions/helpers/typeof', [ ], function () { 'use strict'; return function (a, b) { return typeof a === b } }), define('core/extensions/helpers/notNull', [ ], function () { 'use strict'; return function (a) { return null !== a } }), define('core/extensions/helpers/any', [ ], function () { 'use strict'; return function () { for (var a = arguments.length, b = 0; b < a - 1; b++) if (arguments[b]) return arguments[b] } }), define('core/extensions/helpers/if_any', [ ], function () { 'use strict'; return function () { for (var a = arguments.length, b = arguments[a - 1], c = 0; c < a - 1; c++) if (arguments[c]) return b.fn(this); return b.inverse(this) } }), define('core/extensions/helpers/if_all', [ ], function () { 'use strict'; return function () { for (var a = arguments.length, b = arguments[a - 1], c = 0; c < a - 1; c++) if (!arguments[c]) return b.inverse(this); return b.fn(this) } }), define('core/extensions/helpers/switch', [ 'core/switches', 'core/utils/object/extend' ], function (a, b) { 'use strict'; return function (c, d) { return a.isFeatureActive(c, b({ }, d.hash)) } }), define('core/extensions/helpers/partial', [ 'handlebars' ], function (a) { 'use strict'; return function (b, c) { a.registerPartial(b, c.fn) } }), define('core/extensions/helpers/getPartial', [ 'handlebars' ], function (a) { 'use strict'; return function (b, c, d) { return 'undefined' == typeof d && (d = c, c = this, a.Utils.extend(c, d.hash)), new a.SafeString(a.partials[b](c, d)) } }), define('core/extensions/helpers/gettext', [ 'handlebars', 'core/strings' ], function (a, b) { 'use strict'; return function () { var c, d, e, f, g = arguments.length, h = arguments[g - 1], i = h.hash, j = arguments[0], k = a.partials; j = a.Utils.escapeExpression(b.get(j)); for (e in i) i.hasOwnProperty(e) && (d = new RegExp('%\\((' + e + ')\\)s', 'gm'), c = i[e], f = c && c.executePartial, f && (c = k[c.partial].call(this, c.context, h)), void 0 === c || null === c || 'number' == typeof c && isNaN(c) ? c = '' : f || (c = a.Utils.escapeExpression(c)), j = j.replace(d, c.toString())); return new a.SafeString(j) } }), define('core/utils/object/get', [ ], function () { 'use strict'; return function (a, b, c) { for (var d = 0, e = b.length; a && d < e; ) a = a[b[d]], d += 1; return d < e || void 0 === a ? c : a } }), define('core/extensions/helpers/urlfor', [ 'core/config/urls', 'core/utils/object/get' ], function (a, b) { 'use strict'; return function (c) { return b(a, c.split('.')) } }), define('core/extensions/helpers/html', [ 'handlebars' ], function (a) { 'use strict'; return function (b) { return new a.SafeString(b || '') } }), define('core/extensions/helpers/with', [ ], function () { 'use strict'; return function () { var a = arguments.length, b = arguments[a - 1], c = arguments[0]; return 3 === a ? (c = { }, c[arguments[0]] = arguments[1]) : '_window_' === c && (c = window), b.fn(c) } }), define('core/extensions/helpers/each', [ 'handlebars' ], function (a) { 'use strict'; return function (b, c) { var d, e, f, g = c.fn, h = c.inverse, i = 0, j = ''; if (c.data && (d = a.createFrame(c.data)), b && 'object' == typeof b) if ('[object Array]' === Object.prototype.toString.call(b)) for (f = b.length; i < f; i++) d && (d.index = i, d.length = b.length), j += g(b[i], { data: d }); else for (e in b) b.hasOwnProperty(e) && (d && (d.key = e), j += g(b[e], { data: d }), i += 1); return 0 === i && (j = h(this)), j } }), define('core/extensions/helpers/log', [ ], function () { 'use strict'; return function (a) { console.log(a, this) } }), define('core/extensions/helpers/debug', [ ], function () { 'use strict'; return function () { } }), define('core/extensions/helpers/geturl', [ ], function () { 'use strict'; return window.geturl || function (a) { return a } }), define('core/extensions/helpers/tag', [ 'handlebars' ], function (a) { 'use strict'; return function (b, c) { var d = [ '<' + b ], e = c.hash.text; delete c.hash.text; for (var f in c.hash) c.hash.hasOwnProperty(f) && d.push(' ' + f + '="' + a.escapeExpression(c.hash[f]) + '"'); return d.push('>' + a.escapeExpression(e) + ''), new a.SafeString(d.join('')) } }), define('core/extensions/helpers/now', [ 'moment' ], function (a) { 'use strict'; return function (b) { return a().format(b) } }), define('core/extensions/helpers/ternary', [ ], function () { 'use strict'; return function (a, b, c) { return a ? b : c } }), define('core/extensions/handlebars.helpers', [ 'require', 'handlebars', './helpers/eq', './helpers/ne', './helpers/gt', './helpers/lt', './helpers/ge', './helpers/le', './helpers/typeof', './helpers/notNull', './helpers/any', './helpers/if_any', './helpers/if_all', './helpers/switch', './helpers/partial', './helpers/getPartial', './helpers/gettext', './helpers/urlfor', './helpers/html', './helpers/with', './helpers/each', './helpers/log', './helpers/debug', './helpers/geturl', './helpers/tag', './helpers/now', './helpers/ternary' ], function (a) { 'use strict'; var b = a('handlebars'); return b.registerHelper('eq', a('./helpers/eq')), b.registerHelper('ne', a('./helpers/ne')), b.registerHelper('gt', a('./helpers/gt')), b.registerHelper('lt', a('./helpers/lt')), b.registerHelper('ge', a('./helpers/ge')), b.registerHelper('le', a('./helpers/le')), b.registerHelper('typeof', a('./helpers/typeof')), b.registerHelper('notNull', a('./helpers/notNull')), b.registerHelper('any', a('./helpers/any')), b.registerHelper('if_any', a('./helpers/if_any')), b.registerHelper('if_all', a('./helpers/if_all')), b.registerHelper('switch', a('./helpers/switch')), b.registerHelper('partial', a('./helpers/partial')), b.registerHelper('getPartial', a('./helpers/getPartial')), b.registerHelper('gettext', a('./helpers/gettext')), b.registerHelper('urlfor', a('./helpers/urlfor')), b.registerHelper('html', a('./helpers/html')), b.registerHelper('with', a('./helpers/with')), b.registerHelper('each', a('./helpers/each')), b.registerHelper('log', a('./helpers/log')), b.registerHelper('debug', a('./helpers/debug')), b.registerHelper('geturl', a('./helpers/geturl')), b.registerHelper('tag', a('./helpers/tag')), b.registerHelper('now', a('./helpers/now')), b.registerHelper('ternary', a('./helpers/ternary')), b }), define('core/templates/alert', [ 'handlebars', 'core/templates/handlebars.partials', 'core/extensions/handlebars.helpers' ], function (a) { return a.template({ 1: function (a, b, c, d, e) { return '\n' }, 3: function (a, b, c, d, e) { var f; return (null != (f = a.lambda(null != b ? b.message : b, b)) ? f : '') + '\n' }, 5: function (a, b, c, d, e) { return a.escapeExpression(a.lambda(null != b ? b.message : b, b)) + '\n' }, compiler: [ 8, '>= 4.3.0' ], main: function (a, b, c, d, e) { var f, g = null != b ? b : a.nullContext || { }; return '×\n\n' + (null != (f = c['if'].call(g, null != b ? b.icon : b, { name: 'if', hash: { }, fn: a.program(1, e, 0), inverse: a.noop, data: e, loc: { start: { line: 3, column: 0 }, end: { line: 5, column: 7 } } })) ? f : '') + (null != (f = c['if'].call(g, null != b ? b.safe : b, { name: 'if', hash: { }, fn: a.program(3, e, 0), inverse: a.program(5, e, 0), data: e, loc: { start: { line: 6, column: 0 }, end: { line: 10, column: 7 } } })) ? f : '') + '\n' }, useData: !0 }) }), define('core/views/AlertView', [ 'backbone', 'core/templates/alert' ], function (a, b) { 'use strict'; var c = a.View.extend({ defaultClassName: 'alert', events: { 'click [data-action=dismiss]': 'dismiss' }, initialize: function (a) { this.options = a, this.message = a.message, this.safe = a.safe, this.type = a.type, this.className = a.className || this.defaultClassName }, render: function () { var a = this.$el; return a.html(b({ message: this.message, safe: this.safe, icon: Boolean(this.type), iconType: 'error' === this.type || 'warn' === this.type ? 'warning' : this.type })), a.attr('class', this.className), this.type && a.addClass(this.type), this }, dismiss: function (a) { a && a.preventDefault && a.preventDefault(), this.remove(), this.trigger('dismiss') } }); return c }), define('core/mixins/withAlert', [ 'underscore', 'core/views/AlertView' ], function (a, b) { 'use strict'; var c = { alert: function (c, d) { a.isObject(d) || (d = { }); var e = d.target || this._alertSelector; this.dismissAlert(); var f = this._alert = new b(a.extend({ message: c }, d)); if (this.listenToOnce(this._alert, 'dismiss', function () { this._alert = null }), f.render(), e) { var g = this.$el.find(e); g.length ? g.prepend(f.el) : this.listenToOnce(this, 'threadView:render', function () { return this.alert(c, d) }) } else this.el.parentNode && this.el.parentNode.insertBefore(f.el, this.el); return f }, dismissAlert: function (a) { this._alert && (a && !a(this._alert) || (this.stopListening(this._alert), this._alert.dismiss(), this._alert = null)) }, getAlert: function () { return this._alert || null }, setAlertSelector: function (a) { this._alertSelector = a } }, d = function () { return a.extend(this, c) }; return d }), define('core/models/ThreadVote', [ 'backbone' ], function (a) { 'use strict'; var b = a.Model.extend({ defaults: { score: 0 } }); return b }), define('core/models/Vote', [ 'backbone' ], function (a) { 'use strict'; var b = a.Model.extend({ defaults: { score: 0 } }); return b }), define('core/constants/voteConstants', [ 'exports' ], function (a) { 'use strict'; a.VOTING_TYPES = { DETAILED: 0, DOWNVOTE_LIMITED: 1, DOWNVOTE_DISABLED: 2, DISABLED: 3 }, a.DEFAULT_VOTING_TYPE = a.VOTING_TYPES.DETAILED }), define('core/time', [ ], function () { 'use strict'; function a(a) { return a.indexOf('+') >= 0 ? a : a + '+00:00' } var b = 'YYYY-MM-DDTHH:mm:ssZ'; return { ISO_8601: b, assureTzOffset: a } }), define('core/models/BaseUser', [ 'backbone', 'core/config' ], function (a, b) { 'use strict'; var c = a.Model.extend({ defaults: { about: null, avatar: { cache: b.urls.avatar.generic, permalink: b.urls.avatar.generic }, connections: { }, badges: [ ], email: null, isAnonymous: !0, isFollowedBy: null, isFollowing: null, joinedAt: null, name: null, profileUrl: null, url: null, username: null, numPosts: null, numFollowing: null, numForumsFollowing: null, numFollowers: null, numLikesReceived: null, isFlagged: null }, hasValidAvatar: function (a) { var b = a ? a.avatar : this.get('avatar'); return b && b.cache }, isAnonymous: function () { return !this.get('id') }, isRegistered: function () { return !this.isAnonymous() }, validate: function (a) { if (!this.hasValidAvatar(a)) return 'None of the avatar related properties can be null, undefined or empty on User models.' }, toJSON: function () { var b = a.Model.prototype.toJSON.apply(this, arguments); return b.thread = { }, this.hasValidAvatar() || (b.avatar = this.defaults.avatar), b.isRegistered = this.isRegistered(), b } }); return c }), define('core/models/User', [ 'jquery', 'underscore', 'moment', 'core/config', 'core/time', 'core/utils', 'core/strings', 'core/switches', 'core/api', 'core/models/BaseUser' ], function (a, b, c, d, e, f, g, h, i, j) { 'use strict'; function k(a, b, c) { a[b] = a[b] || [ ], a[b].push(c) } var l = g.get, m = j.extend({ url: i.getURL('users/details'), validate: function (c) { var d = { }; if (c.display_name && (c.display_name = a.trim(c.display_name)), c.display_name || k(d, 'display_name', l('Please enter your name.')), c.email || k(d, 'email', l('Please enter your email address.')), f.validateEmail(c.email) || k(d, 'email', l('Invalid email address.')), this.isNew() && (c.password ? c.password.length < m.MIN_PASSWORD_LEN && k(d, 'password', l('Password must have at least 6 characters.')) : k(d, 'password', l('Please enter a password.'))), c.name && (c.name.length < m.MIN_NAME_LEN && k(d, 'name', g.interpolate(l('Name must have at least %(minLength)s characters.'), { minLength: m.MIN_NAME_LEN })), c.name.length > m.MAX_NAME_LEN && k(d, 'name', g.interpolate(l('Name must have less than %(maxLength)s characters.'), { maxLength: m.MAX_NAME_LEN }))), c.location && c.location.length > m.MAX_LOCATION_LEN && k(d, 'location', g.interpolate(l('Location must have less than %(maxLength)s characters.'), { maxLength: m.MAX_LOCATION_LEN })), c.url && (c.url.length > m.MAX_URL_LEN && k(d, 'url', g.interpolate(l('Site must have less than %(maxLength)s characters.'), { maxLength: m.MAX_URL_LEN })), f.isUrl(c.url) || k(d, 'url', l('Please enter a valid site.'))), !b.isEmpty(d)) return d }, prepareFetchOptions: function (a) { a = a ? b.clone(a) : { }; var c = { }; return this.get('id') ? c.user = this.get('id') : this.get('username') && (c.user = 'username:' + this.get('username')), b.extend(c, a.data), a.data = c, a }, fetch: function (a) { return a = this.prepareFetchOptions(a), j.prototype.fetch.call(this, a) }, parse: function (a) { var b = a.response || a; return b = this.handleBadgesUpdate(b) }, register: function (a) { var c = this; return a = a || { }, i.call('internal/users/register.json', { data: b.extend(this.toRegisterJSON(), { gRecaptchaResponse: a.gRecaptchaResponse }), method: 'POST', success: function (d) { i.call('users/acceptTerms', { method: 'POST' }), c.set(b.extend({ }, d.response, { hasAcceptedGdprTerms: !0 })), a.success && a.success(d) }, error: a.error }) }, saveAvatar: function (a) { var b = new window.FormData; return b.append('avatar_file', a), b.append('api_key', d.keys.api), i.call('internal/users/updateAvatar.json', { method: 'post', data: b, cache: !1, contentType: !1, processData: !1 }) }, saveProfile: function () { return i.call('users/updateProfile.json', { method: 'POST', data: { name: this.get('name'), about: this.get('about'), location: this.get('location'), url: this.get('url') } }) }, toRegisterJSON: function () { return b.pick(this.toJSON(), 'display_name', 'email', 'password') }, isSession: function (a) { return a.user.id && a.user.id === this.id }, isEditable: function (a) { return this.isSession(a) && !this.get('remote') }, toJSON: function (a) { a = a || { }; var b = j.prototype.toJSON.call(this), c = this.collection && this.collection.thread; return b.thread.canModerate = Boolean(c && c.isModerator(this)), b.thread.isOP = Boolean(c && c.isOP(this)), a.session && (b.isSession = this.isSession(a.session), b.isEditable = this.isEditable(a.session)), b }, _changeFollowState: function (a) { this.set({ isFollowing: a, numFollowers: Math.max(0, this.get('numFollowers') + (a ? 1 : - 1)) }); var b = 'users/' + (a ? 'follow' : 'unfollow'), c = this; return i.call(b + '.json', { data: { target: this.get('id') }, method: 'POST', success: function (a) { c.trigger('sync', c, a, { }) } }) }, follow: function () { return this._changeFollowState(!0) }, unfollow: function () { return this._changeFollowState(!1) }, _changeBlockState: function (a) { var b = 'users/block/' + (a ? 'create' : 'delete'), c = this; return i.call(b + '.json', { data: { user: this.get('id') }, method: 'POST', success: function (a) { c.set(a.response) } }) }, block: function () { return this._changeBlockState(!0) }, unblock: function () { return this._changeBlockState(!1) }, report: function (a) { var b = this; return i.call('users/report.json', { data: { reason: a, user: this.get('id') }, method: 'POST', success: function () { b.set('isFlagged', !0) } }) }, toggleFollowState: function () { return this._changeFollowState(!this.get('isFollowing')) }, registeredLessThan: function (a, b) { var d = e.assureTzOffset(this.get('joinedAt')), f = c().subtract(a, b); return c(d).isAfter(f) }, registeredToday: function () { return this.registeredLessThan(1, 'day') }, registeredThisWeek: function () { return this.registeredLessThan(1, 'week') }, shouldHomeOnboard: function () { return !this.get('homeOnboardingComplete') && !h.isFeatureActive('onboarding_without_channels') }, setHomeOnboardComplete: function (a) { this.updateFlags({ homeOnboardingComplete: a }), a && this.listenTo(this, 'change:homeOnboardingComplete', b.bind(this.set, this, 'homeOnboardingComplete', a, { silent: !0 })) }, handleBadgesUpdate: function (a) { if (this.collection && this.collection.thread && this.collection.thread.forum && this.collection.thread.forum.get('badges')) { var b = this.collection.thread.forum.get('badges'); a.badges = a.badges ? a.badges.filter(function (a) { return b[a.id] }) : [ ] } return a }, updateFlags: function (a) { return this.set(a), i.call('internal/users/updateFlags.json', { data: b.mapObject(a, function (a) { return a ? 1 : 0 }), method: 'POST' }) } }, { MIN_PASSWORD_LEN: 6, MIN_NAME_LEN: 2, MAX_NAME_LEN: 30, MAX_LOCATION_LEN: 255, MAX_URL_LEN: 200 }); return m }), define('core/utils/html', [ ], function () { 'use strict'; var a = '...', b = a.length, c = function (a) { var b; try { b = (new window.DOMParser).parseFromString(' ', 'text/html') } catch (c) { } return b || (b = window.document.implementation.createHTMLDocument('')), b.body && (b.body.innerHTML = a), b }; return { stripTags: function (a) { var b = c(a).body; return (b.textContent || b.innerText).replace(/\r?\n/g, ' ') }, replaceAnchors: function (a, d) { var e = c(a); return [].forEach.call(e.querySelectorAll('a'), function (a) { var c = a.getAttribute('href') || '', e = a.innerHTML, f = d(a); 0 === c.indexOf(e.slice(0, - b)) ? e = f : c.length && e.indexOf(c) !== - 1 ? e = e.replace(c, f) : e += ' ' + f, a.insertAdjacentHTML('afterend', e), a.parentNode.removeChild(a) }), e.body.innerHTML.trim() } } }), define('core/advice', [ 'underscore' ], function (a) { 'use strict'; function b() { a.each(['before', 'after', 'around'], function (a) { this[a] = function (b, d) { return 'function' == typeof this[b] ? this[b] = c[a](this[b], d) : this[b] = d, this[b] } }, this) } var c = { around: function (b, c) { return function () { var d = a.toArray(arguments); return c.apply(this, [ a.bind(b, this) ].concat(d)) } }, before: function (b, d) { return c.around(b, function () { var b = a.toArray(arguments), c = b.shift(); return d.apply(this, b), c.apply(this, b) }) }, after: function (b, d) { return c.around(b, function () { var b = a.toArray(arguments), c = b.shift(), e = c.apply(this, b); return d.apply(this, b), e }) } }; return { withAdvice: b } }), define('core/models/mixins', [ 'underscore', 'moment', 'core/time' ], function (a, b, c) { 'use strict'; function d() { b.locale('en', { relativeTime: { future: '%s from now', past: '%s ago', s: 'a few seconds', ss: '%d seconds', m: 'a minute', mm: '%d minutes', h: 'an hour', hh: '%d hours', d: 'a day', dd: '%d days', M: 'a month', MM: '%d months', y: 'a year', yy: '%d years' } }), this._getCreatedMoment = a.memoize(function (a) { var d = this.get(a || 'createdAt'); if (d) return b(c.assureTzOffset(d), c.ISO_8601) }, function (a) { return this.get(a || 'createdAt') }), this.getRelativeCreatedAt = function (a) { var b = this._getCreatedMoment(a); return b && b.from(Number(new Date)) }, this.getFormattedCreatedAt = a.memoize(function (a) { var b = this._getCreatedMoment(a); return b && b.format('LLLL') }, function (a) { return this.get(a || 'createdAt') }) } return { withCreatedAt: d } }), define('core/collections/UserCollection', [ 'jquery', 'backbone', 'core/models/User' ], function (a, b, c) { 'use strict'; var d = b.Collection.extend({ model: c, initialize: function (a, c) { b.Collection.prototype.initialize.apply(this, arguments), this.thread = c && c.thread }, fetch: function () { return a.when(!0) } }); return d }), define('core/collections/VotersUserCollection', [ 'underscore', 'backbone', 'core/api', 'core/collections/UserCollection' ], function (a, b, c, d) { 'use strict'; var e = d.extend({ LIMIT: 50, url: function () { return c.getURL('posts/listUsersVotedPost') }, initialize: function (a, b) { this.postId = b.postId, this.threadId = b.threadId }, fetch: function (c) { return b.Collection.prototype.fetch.call(this, a.extend({ data: { post: this.postId, thread: this.threadId, vote: c.vote, limit: this.LIMIT } }, c)) } }); return e }), define('core/collections/VoteCollection', [ 'backbone', 'core/models/Vote' ], function (a, b) { 'use strict'; var c = a.Collection.extend({ model: b }); return c }), define('core/models/Post', [ 'jquery', 'underscore', 'backbone', 'moment', 'core/config/urls', 'core/api', 'core/strings', 'core/time', 'core/utils', 'core/utils/html', 'core/advice', 'remote/config', 'core/models/mixins', 'core/collections/VotersUserCollection', 'core/collections/VoteCollection' ], function (a, b, c, d, e, f, g, h, i, j, k, l, m, n, o) { 'use strict'; var p = 1000, q = 0, r = 25000, s = function () { var b = a.now(); return !(b - q < p) && (q = b, !0) }, t = g.get, u = c.Model.extend({ votersCollectionClass: n, defaults: function () { return { createdAt: d().format(h.ISO_8601), editableUntil: d().add(l.max_post_edit_days, 'days').format(h.ISO_8601), dislikes: 0, isApproved: !0, isDeleted: !1, isEdited: !1, isFlagged: !1, isFlaggedByUser: !1, isHighlighted: !1, isRealtime: !1, isImmediateReply: !1, isMinimized: null, hasMedia: !1, message: null, raw_message: null, likes: 0, media: [ ], parent: null, points: 0, depth: 0, userScore: 0, rating: null } }, initialize: function () { this.votes = new o }, messageText: function () { var a = this.get('message'); return a && j.stripTags(a) }, permalink: function (a, b) { var c = this.id; if (!c || !a) return ''; var d = b !== !1 && a.currentUrl || a.permalink(), e = window.document.createElement('a'); return e.href = d, e.hash = '#comment-' + c, e.href }, shortLink: function () { return e.shortener + '/p/' + Number(this.id).toString(36) }, twitterText: function (a) { var b = 140, c = this.author.get('name') || this.author.get('username'); b -= c.length + 3, b -= a.length + 1, b -= 2; var d = i.niceTruncate(this.messageText(), b); return '"' + d + '" — ' + c }, toJSON: function (a) { var b = c.Model.prototype.toJSON.call(this); if (a) { var d = a.session, e = a.thread; b.canBeEdited = this.canBeEdited(d, e), b.canBeRepliedTo = this.canBeRepliedTo(d, e), b.canBeShared = this.canBeShared(), b.permalink = this.permalink(e) } return b.shortLink = this.shortLink(), b.isMinimized = this.isMinimized(), b.plaintext = this.messageText(), b.relativeCreatedAt = this.getRelativeCreatedAt(), b.formattedCreatedAt = this.getFormattedCreatedAt(), b.cid = this.cid, b }, isPublic: function () { return !(!this.get('isHighlighted') && !this.get('isSponsored')) || !this.get('isDeleted') && this.get('isApproved') }, isMinimized: function () { return !this.get('isHighlighted') && (this.get('isMinimized') !== !1 && !this.get('isApproved')) }, isAuthorSessionUser: function () { return !1 }, canBeEdited: function () { return !1 }, canBeRepliedTo: function () { return !1 }, canBeShared: function () { return !1 }, validateMessage: function (a) { if (b.isString(a.raw_message)) { if ('' === a.raw_message) return t('Comments can\'t be blank.'); if (a.raw_message.length < 2) return t('Comments must have at least 2 characters.'); if (a.raw_message.length > r) return g.interpolate(t('Comments can\'t be longer than %(maxLength)s characters (currently %(currentLength)s characters).'), { maxLength: r, currentLength: a.raw_message.length }) } }, validate: function (c) { if (!this.id && !c.id) { var d = this.validateMessage(c); return d ? d : (c.author_email && (c.author_email = a.trim(c.author_email)), c.author_name && (c.author_name = a.trim(c.author_name)), '' === c.author_email && '' === c.author_name ? t('Please sign in or enter a name and email address.') : '' === c.author_email || '' === c.author_name ? t('Please enter both a name and email address.') : b.isString(c.author_email) && !this.validateEmail(c.author_email) ? t('Invalid email address format.') : void 0) } }, validateEmail: function (a) { return i.validateEmail(a) }, report: function (a) { this.set('isFlagged', !0); var b = { post: this.id }; a && (b.reason = a), f.call('posts/report.json', { data: b, method: 'POST' }) }, _highlight: function (a) { this.set('isHighlighted', a), f.call('posts/' + (a ? 'highlight' : 'unhighlight') + '.json', { data: { post: this.id }, method: 'POST' }) }, highlight: function () { this._highlight(!0) }, unhighlight: function () { this._highlight(!1) }, getThreadId: function () { return this.get('thread') }, getUpvotersUserCollection: b.memoize(function () { var a = this.votersCollectionClass; return new a((void 0), { postId: this.id, threadId: this.getThreadId() }) }, function () { return [this.id, '1'].join('') }), getDownvotersUserCollection: b.memoize(function () { var a = this.votersCollectionClass; return new a((void 0), { postId: this.id, threadId: this.getThreadId() }) }, function () { return [this.id, '-1'].join('') }), _vote: function (a, b, c) { var d = a - b, e = { likes: this.get('likes'), dislikes: this.get('dislikes'), points: this.get('points') }; return 0 === d ? d : (a > 0 ? (e.likes += a, e.dislikes += b) : a < 0 ? (e.dislikes -= a, e.likes -= b) : b > 0 ? e.likes -= b : e.dislikes += b, e.points += d, c && (1 === a ? (this.getUpvotersUserCollection().add(c), this.getDownvotersUserCollection().remove(c)) : (this.getDownvotersUserCollection().add(c), this.getUpvotersUserCollection().remove(c))), this.set(e), d) }, vote: function (a) { if (!s()) return 0; var b = this, c = b._vote(a, b.get('userScore')); if (0 !== c) { var d = b.author ? b.author.get('numLikesReceived') : 0; 1 === b.get('userScore') ? d -= 1 : 1 === a && (d += 1), b.set('userScore', a), f.call('posts/vote.json', { data: { post: b.id, vote: a }, method: 'POST', success: function (c) { b.votes.add({ id: c.response.id, score: a }, { merge: !0 }), b.author && b.author.set('numLikesReceived', d) } }) } }, _delete: function () { return this.set({ isApproved: !1, isDeleted: !0 }), f.call('posts/remove.json', { data: { post: this.id }, method: 'POST' }) }, spam: function () { this.set({ isApproved: !1, isDeleted: !0, isSpam: !0 }), this.trigger('spam'), f.call('posts/spam.json', { data: { post: this.id }, method: 'POST' }) }, _create: function (a, b) { var c = this, d = a.attributes, e = { thread: d.thread, message: d.raw_message, rating: d.rating }; return d.parent && (e.parent = d.parent), d.author_name && (e.author_name = d.author_name, e.author_email = d.author_email), f.call('posts/create.json', { data: e, method: 'POST', success: function (a) { c.set(a.response), b.success && b.success() }, error: b.error }) }, _update: function (a, b) { var c = this, d = a.attributes, e = { post: d.id, message: d.raw_message, rating: d.rating }; return f.call('posts/update.json', { data: e, method: 'POST', success: function (a) { c.set(a.response), b.success && b.success() }, error: b.error }) }, _read: function (a, b) { var c = this; return b = b || { }, f.call('posts/details.json', { data: { post: c.id }, method: 'GET', success: function (a) { b.isHighlighted && !a.response.isHighlighted && (a.response.isHighlighted = !0), c.set(a.response), b.success && b.success() }, error: b.error }) }, sync: function (a, b, c) { c = c || { }; var d = c.error; switch (d && (c.error = function (a) { var b = { }; try { b = JSON.parse(a.responseText) } catch (c) { } d(b) }), a) { case 'create': return this._create(b, c); case 'update': return this._update(b, c); case 'delete': return this._delete(); case 'read': return this._read(b, c); default: return null } }, storageKey: function () { if (this.isNew() && this.getThreadId()) return ['drafts', 'thread', this.getThreadId(), 'parent', this.get('parent') || 0].join(':') } }, { formatMessage: function () { var a = /(?:\r\n|\r|\n){2,}/, c = /\r\n|\r|\n/; return function (d) { var e = b.chain(d.split(a)).compact().value(), f = b.map(e, function (a) { return b.chain(a.split(c)).compact().map(b.escape).join('
    ').value() }).join('

    '); return '

    ' + f + '

    ' } }() }); return m.withCreatedAt.call(u.prototype), k.withAdvice.call(u.prototype), u.withAuthor = function (a) { this.around('set', function (c, d, e, f) { var g; if (null == d) return this; 'object' == typeof d ? (g = d, f = e) : (g = { }, g[d] = e); var h = g.author; if (h) { if (b.isString(h) || b.isNumber(h)) { var i = h; h = { }, h[a.prototype.idAttribute || 'id'] = i } var j = this.collection || this.author && this.author.collection, k = j && j.thread && j.thread.forum; if (this.author && this.author.get('badges').length && this.author.get('badges') [0].id) h.badges = this.author.get('badges'); else if (k && k.get('badges') && h.badges) { var l = [ ], m = h.badges || [ ], n = k.get('badges'); m.forEach(function (a) { n[a] && l.push(n[a]) }), h.badges = l } this.author = new a(h), this.trigger('changeRelated:author'), delete g.author } return c.call(this, g, f) }), this.around('toJSON', function (a) { var c = a.apply(this, b.rest(arguments)); return this.author && (c.author = this.author.toJSON()), c }) }, u.withMediaCollection = function (a) { this.after('set', function (c) { c && 'string' != typeof c && (b.isUndefined(c.media) || (this.media ? this.media.reset(c.media) : this.media = new a(c.media), delete c.media)) }), this.around('toJSON', function (a) { var c = a.apply(this, b.rest(arguments)); return this.media && (c.media = this.media.toJSON()), c }) }, u }), define('core/utils/threadRatingsHelpers', [ 'core/utils/object/get' ], function (a) { 'use strict'; var b = { }; return b.isThreadRatingsEnabled = function (b, c) { return !!(b && b.forum && c && c.id === b.forum) && Boolean(a(b, [ 'ratingsEnabled' ]) && a(c, [ 'settings', 'threadRatingsEnabled' ]) && a(c, [ 'features', 'threadRatings' ])) }, b.isThreadModelRatingsEnabled = function (a) { if (!a || !a.forum) return !1; var b = a.forum.get('settings'), c = a.forum.get('features'); return Boolean(a.get('ratingsEnabled') && b && b.threadRatingsEnabled && c && c.threadRatings) }, b.isForumRatingsEnabled = function (b) { return !!b && Boolean(a(b, [ 'settings', 'threadRatingsEnabled' ]) && a(b, [ 'features', 'threadRatings' ])) }, b.isForumModelRatingsEnabled = function (a) { if (!a) return !1; var b = a.get('settings'), c = a.get('features'); return Boolean(b && b.threadRatingsEnabled && c && c.threadRatings) }, b }), define('core/models/Thread', [ 'underscore', 'backbone', 'loglevel', 'core/config/urls', 'core/utils', 'core/api', 'core/config', 'core/advice', 'core/UniqueModel', 'core/utils/threadRatingsHelpers', 'core/models/User' ], function (a, b, c, d, e, f, g, h, i, j, k) { 'use strict'; var l = b.Model, m = l.prototype, n = l.extend({ defaults: { author: null, category: null, createdAt: null, forum: null, identifiers: [ ], ipAddress: null, isClosed: !1, isDeleted: !1, hasStreaming: !1, link: null, message: null, slug: null, title: null, userSubscription: !1, posts: 0, likes: 0, dislikes: 0, userScore: 0 }, initialize: function (a, b) { b = b || { }, this.moderators = b.moderators, this.forum = b.forum, this.on('change:userScore', function () { var a = this.get('userScore'); a > 0 && 0 === this.get('likes') && this.set('likes', a) }, this) }, _vote: function (a, b) { var c = a - b; return 0 === c ? c : (this.set('likes', this.get('likes') + c), c) }, vote: function (a) { var b = this, c = b._vote(a, b.get('userScore')); 0 !== c && (this.set('userScore', a), f.call('threads/vote.json', { data: { thread: this.id, vote: a }, method: 'POST', success: function (a) { a.response.id && b.trigger('vote:success', a) } })) }, fetch: function (a) { var b, d = this, e = d.attributes; a = a || { }, b = e.identifier ? 'ident:' + e.identifier : 'link:' + e.url, f.call('threads/details.json', { data: { thread: b, forum: e.forum }, success: function (b) { d.set(b.response), a.success && a.success() }, error: function () { g.debug ? d.save({ }, { success: a.success }) : c.info('Couldn\'t find thread; not creating in production.') } }) }, _toggleState: function (a, b) { b || (b = { }); var c = a ? 'open.json' : 'close.json'; return this.set('isClosed', !a), f.call('threads/' + c, { method: 'POST', data: { thread: this.id }, success: b.success, error: b.error }) }, open: function (a) { return this._toggleState(!0, a) }, close: function (a) { return this._toggleState(!1, a) }, premoderate: function (b, c) { return this.set('validateAllPosts', b), f.call('threads/update', a.extend({ }, c, { method: 'POST', data: a.extend({ thread: this.id, validateAllPosts: b ? 1 : 0 }, c && c.data) })) }, sync: function () { var a = this, b = a.attributes; f.call('threads/create.json', { data: { title: b.title, forum: b.forum, identifier: b.identifier, url: b.url }, method: 'POST', success: function (b) { a.set(b.response) } }) }, fetchRatings: function () { var a = this, b = { thread: a.id }; return f.call('threads/ratingsSummary.json', { data: b, method: 'GET', success: function (b) { a.set('ratings', b.response) } }) }, toggleRatingsEnabled: function () { var a = this; if (j.isForumModelRatingsEnabled(a.forum)) { var b = a.get('ratingsEnabled'), c = { thread: a.id, ratingsEnabled: b ? 0 : 1 }; return a.set('ratingsEnabled', !b), f.call('threads/update.json', { data: c, method: 'POST' }) } }, incrementPostCount: function (a) { var b = this.get('posts') + a; this.set('posts', b > 0 ? b : 0) }, isModerator: function (b) { var c; if (this.moderators) return c = b instanceof k || a.isObject(b) ? b.id : b, c = parseInt(c, 10), a(this.moderators).contains(c) }, isOP: function (b) { var c = b instanceof k || a.isObject(b) ? b.id : b; return this.get('author') === c }, subscribe: function (a) { a = a !== !1; var b = this.get('userSubscription'); if (b !== a) { this.set('userSubscription', a); var c = a ? 'subscribe.json' : 'unsubscribe.json', d = { thread: this.id }; return f.call('threads/' + c, { data: d, method: 'POST' }) } }, twitterText: function (a) { var b = 140 - (a.length + 1), c = this.get('clean_title'); return c = e.niceTruncate(c, b) }, permalink: function () { return this.get('url') || this.get('link') || this.currentUrl }, shortLink: function () { return d.shortener + '/t/' + Number(this.id).toString(36) }, toJSON: function () { var a = m.toJSON.call(this); return a.permalink = this.permalink(), a.shortLink = this.shortLink(), a }, getDiscussionRoute: function (a) { var b = [ '', 'home', 'discussion', this.forum.id, this.get('slug'), '' ]; return a = a || this.forum.channel, a && (a = a.attributes || a, b.splice(2, 0, 'channel', a.slug), b.splice(1, 1)), b.join('/') } }); return h.withAdvice.call(n.prototype), n.withThreadVoteCollection = function (a) { this.after('initialize', function () { this.votes = new a, this.on('vote:success', function (a) { this.votes.get(a.response.id) || this.votes.add({ id: a.response.id, score: a.response.vote, currentUser: !0 }) }, this) }) }, n.withPostCollection = function (b) { this.after('initialize', function (c) { c = c || { }, this.posts = new b(c.posts, { thread: this, cursor: c.postCursor, order: c.order, perPage: this.postsPerPage }), this.listenTo(this.posts, 'add reset', function (b) { b = b.models ? b.models : [ b ], this.users && a.each(b, function (a) { this.users.get(a.author.id) || this.users.add(a.author) }), this.recalculatePostCount() }), this.listenTo(this.posts, 'change:isDeleted change:isFlagged', function (a, b) { b && this.incrementPostCount( - 1) }) }), this.recalculatePostCount = function () { var a = this.get('posts'); a > 50 || (a = this.posts.reduce(function (a, b) { return b.isPublic() ? a + 1 : a }, 0), this.set('posts', a)) } }, i.addType('Thread', n), n }), define('core/models/Forum', [ 'backbone', 'core/UniqueModel', 'core/api' ], function (a, b, c) { 'use strict'; var d = a.Model.extend({ defaults: { settings: { }, badges: [ ], followUrl: 'forums/follow', unfollowUrl: 'forums/unfollow', isFollowing: !1 }, initialize: function (a, b) { b && b.channel && (this.channel = b.channel), this.getFeatures(), this.on('change:id', this.getFeatures), this.on('change:id', this.getBadges) }, _changeFollowingState: function (a) { return c.call(a, { method: 'POST', data: { target: this.get('id') } }) }, follow: function () { return this.set('isFollowing', !0), this._changeFollowingState(this.get('followUrl')) }, unfollow: function () { return this.set('isFollowing', !1), this._changeFollowingState(this.get('unfollowUrl')) }, toggleFollowed: function () { if (this.channel && this.channel.get('options').isCurationOnlyChannel) return this.channel.toggleFollowed(); var a = this.get('isFollowing') ? this.unfollow() : this.follow(); return this.trigger('toggled:isFollowing'), a }, getFeatures: function () { var a = this; a.id && c.call('forums/details', { data: { forum: this.id, attach: 'forumFeatures' }, success: function (b) { b && b.response && a.set('features', b.response.features) } }) }, getBadges: function () { if (this.id && this.get('badges')) { var a = { }, b = { }; b.id = this.get('pk'), b.url = this.get('id'), this.get('badges').forEach(function (c) { c.forum = b, a[c.id] = c }), this.set('badges', a) } } }); return b.addType('Forum', d), d }), define('core/models/Media', [ 'underscore', 'backbone', 'core/api', 'core/UniqueModel' ], function (a, b, c, d) { 'use strict'; var e = b.Model.extend({ idAttribute: 'url', defaults: { mediaType: null, html: '', htmlWidth: null, htmlHeight: null, thumbnailUrl: '', thumbnailWidth: null, thumbnailHeight: null, url: '', urlRedirect: '', resolvedUrl: '', resolvedUrlRedirect: '', title: '', description: '', providerName: '' }, parse: function (a) { return a.response }, sync: function (b, d, e) { if ('read' !== b) throw new Error('Media models do not support methods other than "read".'); return c.call('media/details.json', a.extend({ method: 'POST', data: { url: this.get('url'), forum: e.forum } }, e)) } }, { MEDIA_TYPES: { IMAGE: '1', IMAGE_UPLOAD: '2', YOUTUBE_VIDEO: '3', WEBPAGE: '4', TWITTER_STATUS: '5', FACEBOOK_PAGE: '6', FACEBOOK_POST: '7', FACEBOOK_PHOTO: '8', FACEBOOK_VIDEO: '9', SOUNDCLOUD_SOUND: '10', GOOGLE_MAP: '11', VIMEO_VIDEO: '12', VINE_VIDEO: '14', GIF_VIDEO: '15', MP4_VIDEO: '16' }, WEBPAGE_TYPES: [ '4', '6', '7' ] }); return d.addType('Media', e), e }), define('core/collections/MediaCollection', [ 'backbone', 'core/models/Media' ], function (a, b) { 'use strict'; var c = a.Collection.extend({ model: b }); return c }), define('common/collections/VotersUserCollection', [ 'core/collections/VotersUserCollection' ], function (a) { 'use strict'; var b = a.extend({ initialize: function (b, c) { a.prototype.initialize.call(this, b, c); var d = require('common/Session'); this.session = d.get() }, parse: function (a) { return this.session.get('canModerate') && a.response && a.response.forEach(function (a) { a.isBlocking = !1 }), a.response } }); return b }), define('common/models', [ 'require', 'jquery', 'underscore', 'backbone', 'modernizr', 'core/api', 'core/UniqueModel', 'core/models/User', 'core/models/Post', 'core/models/Thread', 'core/models/Forum', 'core/collections/MediaCollection', 'core/utils/object/get', 'core/utils/url/serialize', 'core/utils/guid', 'common/utils', 'core/utils', 'common/urls', 'core/shared/urls', 'common/collections/VotersUserCollection', 'backbone.uniquemodel' ], function (a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p, q, r, s, t) { 'use strict'; var u = k.extend({ defaults: { settings: { } }, toJSON: function () { return c.extend(d.Model.prototype.toJSON.apply(this, arguments), { homeUrl: s.apps.home + 'home/forums/' + this.id + '/' }) } }), v = j.extend({ initialize: function (b, d) { j.prototype.initialize.apply(this, arguments), d = d || { }; var e = this, f = a('common/collections'); e.users = new f.UserCollection(d.users, { thread: e }), e.forum && (e.moderatorList = new f.ModeratorCollection(null, { forum: e.forum.get('id') })), e.posts = new f.SubpaginatedPostCollection(d.posts, { thread: e, cursor: d.postCursor, order: d.order, perPage: q.isMobileUserAgent() ? 20 : 50 }), e.votes = new f.ThreadVoteCollection, e.posts.on('add reset', function (a) { a = a.models ? a.models : [ a ], c.each(a, function (a) { e.users.get(a.author.id) || e.users.add(a.author) }), e.recalculatePostCount() }), e.listenTo(e.posts, 'change:isDeleted change:isFlagged', function (a, b) { b && e.incrementPostCount( - 1) }), e.queue = new f.QueuedPostCollection(null, { thread: e }) }, recalculatePostCount: function () { var a = this.get('posts'); a > 50 || (a = this.posts.buffer.reduce(function (a, b) { var c = b.isPublic() && (!b.get('sb') || b.isAuthorSessionUser()); return c ? a + 1 : a }, 0), this.set('posts', a)) }, toJSON: function () { var a = this.get('forum'), b = c.isObject(a) ? a.id : a; return c.extend(j.prototype.toJSON.apply(this, arguments), { homeUrl: s.apps.home + 'home/discussions/' + b + '/' + this.get('slug') + '/' }) } }); j.withThreadVoteCollection.call(v.prototype, d.Collection); var w = i.extend({ votersCollectionClass: t, initialize: function () { i.prototype.initialize.apply(this, arguments); var b = a('common/collections'); this.usersTyping = new b.TypingUserCollection }, isAuthorSessionUser: function (b) { var c = a('common/Session'), d = m(b, [ 'user', 'id' ]) || c.fromCookie().id; return !!(d && this.author && this.author.id) && this.author.id.toString() === d.toString() }, canBeEdited: function (a, b) { var c = this.get('editableUntil'), d = (new Date).toISOString(); return !b.get('isClosed') && !this.get('isDeleted') && a.isLoggedIn() && this.isAuthorSessionUser(a) && this.get('raw_message') && !this.get('isHighlighted') && !this.get('isSponsored') && d < c }, canBeRepliedTo: function (a, b) { return !b.get('isClosed') && a.get('canReply') && !this.get('isDeleted') && (this.get('isApproved') || b.isModerator(a.user)) }, canBeShared: function () { return !this.get('isDeleted') && !this.get('isSponsored') }, getParent: function () { var a = this.get('parent'); if (a) return new g(w, { id: String(a) }) } }, { fetchContext: function (a, d, e) { e = e || { }; var h = b.Deferred(); return f.call('posts/getContext.json', { method: 'GET', data: { post: a, order: d.posts.buffer.order }, success: function (a) { var b = c.filter(a.response, function (a) { return a.thread === d.get('id') }); return b ? (c.each(b, function (a) { d.posts.get(a.id) && delete a.hasMore, a = new g(w, a), e.requestedByPermalink && (a.requestedByPermalink = !0), d.posts.add(a) }), void h.resolve(b)) : void h.reject() } }), h.promise() } }); i.withAuthor.call(w.prototype, g.wrap(h)), i.withMediaCollection.call(w.prototype, l), g.addType('Post', w); var x = d.Model.extend({ defaults: { user: null, message: null, parentId: null, immedReply: !1, createdAt: void 0 }, getVisibleParent: function (a) { for (var b, c = this; c.get('parentId'); ) { if (b = a.posts.get(c.get('parentId'))) return b; if (c = a.queue.get(c.get('parentId')), !c) return null } return null }, toPost: function (a) { var b = this, c = a.posts.get(b.get('parentId')), d = c ? c.get('depth') + 1 : 0, e = new g(w, { id: b.id, forum: a.get('forum'), thread: a.id, message: b.get('message'), parent: b.get('parentId'), depth: d, createdAt: b.get('createdAt'), isRealtime: !0, media: b.get('media'), isImmediateReply: b.get('immedReply') }); return e.author = b.get('user'), e } }), y = d.Model.extend({ defaults: { user: null, post: null, thread: null, client_context: null, typing: !0 }, idAttribute: 'client_context', set: function () { return this.lastModified = new Date, d.Model.prototype.set.apply(this, arguments) }, sync: function () { var a = this.toJSON(), b = n(r.realertime + '/api/typing', a); try { p.CORS.request('GET', b).send() } catch (c) { } } }, { make: function (a) { return a.client_context || (a.client_context = o.generate()), new g(y, a) } }); g.addType('TypingUser', y); var z = h.prototype.toJSON; c.extend(h.prototype, { getFollowing: function () { var b = a('common/collections/profile'); return this.following || (this.following = new b.FollowingCollection(null, { user: this })) }, hasDisqusProfileUrl: function () { var a = z.apply(this, arguments); if (!a.profileUrl) return !1; var b = a.profileUrl.match(/^https?:\/\/([^/?#]+)(?:[/?#]|$)/i); return b && b.length >= 2 && ('disqus.com' === b[1] || 'dev.disqus.org:8000' === b[1]) }, toJSON: function () { var b = z.apply(this, arguments), c = a('common/Session'), d = c.get(), e = d && d.get('sso') && d.get('sso').profile_url; e && (e = String(e), 0 === e.indexOf('//') && (e = 'https:' + e), /https?:\/\//.test(e) || (e = null), /\{username\}/.test(e) && b.name || (e = null)); var f = this.hasDisqusProfileUrl(); return b.isSSOProfileUrl = !f || Boolean(e), f && e && (b.profileUrl = e.replace(/\{username\}/gi, encodeURIComponent(b.name))), b } }), g.addType('User', h); var A = h.extend({ defaults: c.extend({ numPosts: 0 }, h.prototype.defaults) }), B = e.sessionstorage ? 'sessionStorage' : null, C = d.UniqueModel(h, 'User', B), D = d.UniqueModel(A, 'User', B), E = d.Model.extend({ }), F = d.Model.extend({ defaults: { id: '', title: '', rating: 'g', 'default': { url: '', height: '', width: '' }, fixedWidth200: { url: '', height: '', width: '' }, fixedWidth100: { url: '', height: '', width: '' } } }); return { Forum: u, Thread: v, Post: w, QueuedPost: x, TypingUser: y, User: h, TopUser: A, Switch: E, SyncedUser: C, SyncedTopUser: D, GifObject: F } }), define('core/models/Channel', [ 'underscore', 'backbone', 'core/UniqueModel', 'core/api', 'core/models/Forum', 'core/strings' ], function (a, b, c, d, e, f) { 'use strict'; var g = f.get, h = b.Model.extend({ defaults: { primaryForum: { }, slug: null, name: null, options: { }, followUrl: 'channels/follow', unfollowUrl: 'channels/unfollow' }, idAttribute: 'slug', initialize: function (a, b) { this.buildPrimaryForum(b), this.listenTo(this, 'change:primaryForum', this.updatePrimaryForum), this.listenTo(this, 'change:primaryCategory', this.updatePrimaryCategory) }, buildPrimaryForum: function () { if (!this.primaryForum) { var a = this.get('primaryForum'); a && (this.primaryForum = new c(e, a, { channel: this }), this.unset('primaryForum')) } }, updatePrimaryForum: function () { var a = this.get('primaryForum'); a && (this.primaryForum || this.buildPrimaryForum(), this.primaryForum.set(a), this.unset('primaryForum')) }, updatePrimaryCategory: function () { var a = this.get('primaryCategory'), b = this.primaryCategory; null === a ? this.primaryCategory = void 0 : b ? b.set(a) : this.primaryCategory = new c(h, a), this.unset('primaryCategory'), this.trigger('changeRelated:primaryCategory') }, fetch: function (c) { return c = c ? a.clone(c) : { }, c.data = this.buildFetchData(c.data), b.Model.prototype.fetch.call(this, c) }, buildFetchData: function (b) { var c = b ? a.clone(b) : { }; return this.id && (c.channel = this.id), c }, url: function (a) { return d.getURL(this.constructor.URLS[a] || this.constructor.URLS.read) }, sync: function (c, d, e) { var f = d.attributes; e = a.extend({ url: this.url(c), emulateHTTP: !0 }, e); var g = { bannerColor: f.bannerColor, description: f.description, primaryCategory: d.primaryCategory && d.primaryCategory.get('slug') || '' }; switch ('default' === e.avatarType ? g.avatar = '' : f.avatar && !a.isString(f.avatar) && (g.avatar = f.avatar), 'file' !== e.bannerType ? g.banner = '' : f.banner && !a.isString(f.banner) && (g.banner = f.banner), c) { case 'create': e.processData = !1, e.contentType = !1, g.name = f.name, e.data = this.toFormData(a.extend({ }, g, e.data)); break; case 'update': e.processData = !1, e.contentType = !1, g.channel = f.slug, e.data = this.toFormData(a.extend({ }, g, e.data)) } return b.sync(c, d, e) }, toFormData: function (b) { return a.reduce(b, function (b, c, d) { return b.append(d, a.isString(c) ? c.trim() : c), b }, new window.FormData) }, parse: function (a) { return a.response || a }, shouldFetch: function () { return !this.get('name') || !this.get('dateAdded') }, ensureFetched: function () { this.shouldFetch() && this.fetch() }, validate: function (b) { var c = [ ], d = b.name.trim(); d.length < this.constructor.MIN_NAME_LENGTH ? c.push({ attrName: 'name', message: f.interpolate(g('Name must have at least %(minLength)s characters.'), { minLength: this.constructor.MIN_NAME_LENGTH }) }) : d.length > this.constructor.MAX_NAME_LENGTH && c.push({ attrName: 'name', message: f.interpolate(g('Name must have less than %(maxLength)s characters.'), { maxLength: this.constructor.MAX_NAME_LENGTH }) }); var e = b.description.trim(); if (e.length < this.constructor.MIN_DESCRIPTION_LENGTH ? c.push({ attrName: 'description', message: f.interpolate(g('Description must have at least %(minLength)s characters.'), { minLength: this.constructor.MIN_DESCRIPTION_LENGTH }) }) : e.length > this.constructor.MAX_DESCRIPTION_LENGTH && c.push({ attrName: 'description', message: f.interpolate(g('Description must have less than %(maxLength)s characters.'), { maxLength: this.constructor.MAX_DESCRIPTION_LENGTH }) }), this.constructor.BANNER_COLORS[b.bannerColor] || c.push({ attrName: 'bannerColor', message: f.interpolate(g('Banner color must be one of ' + a.invoke(a.values(this.constructor.BANNER_COLORS), 'toLowerCase').join(', ')) + '.') }), !a.isEmpty(c)) return c }, _changeFollowingState: function (b, c) { return c = c || { }, c.type = 'POST', c.data = a.extend({ target: this.get('slug') }, c.data), d.call(b, c) }, follow: function (a) { return this.primaryForum.set('isFollowing', !0), this._changeFollowingState(this.get('followUrl'), a) }, unfollow: function (a) { return this.primaryForum.set('isFollowing', !1), this._changeFollowingState(this.get('unfollowUrl'), a) }, toggleFollowed: function () { if (this.get('options').isCurationOnlyChannel && this.primaryForum) { var a = this.primaryForum.get('isFollowing') ? this.unfollow() : this.follow(); return this.primaryForum.trigger('toggled:isFollowing'), a } }, toJSON: function () { var c = b.Model.prototype.toJSON.call(this); return a.defaults({ primaryCategory: this.primaryCategory ? this.primaryCategory.toJSON() : { } }, c) } }, { URLS: { read: 'channels/details', create: 'channels/create', update: 'channels/update' }, BANNER_COLORS: { gray: g('Gray'), blue: g('Blue'), green: g('Green'), yellow: g('Yellow'), orange: g('Orange'), red: g('Red'), purple: g('Purple') }, MIN_NAME_LENGTH: 3, MAX_NAME_LENGTH: 100, MIN_DESCRIPTION_LENGTH: 5, MAX_DESCRIPTION_LENGTH: 200 }); return c.addType('Channel', h), h }), define('core/utils/objectExpander', [ 'underscore', 'core/UniqueModel', 'core/models/Channel', 'core/models/Thread' ], function (a, b, c, d) { 'use strict'; return { Channel: c, Thread: d, parseObject: function (b, c) { return a.isString(c) ? b[c] : c }, buildThread: function (c, d) { if (d instanceof this.Thread) return d; if (d = this.parseObject(c, d), a.isString(d.author)) { var e = d.author.replace('auth.User?id=', ''); d.author = c['auth.User?id=' + e] || e } return new b(this.Thread, d, { forum: this.parseObject(c, d.forum), author: d.author }) }, buildChannel: function (a, c) { return c instanceof this.Channel ? c : (c = this.parseObject(a, c), new b(this.Channel, c)) } } }), define('core/collections/PaginatedCollection', [ 'underscore', 'backbone' ], function (a, b) { 'use strict'; var c = b.Collection.extend({ PER_PAGE: 30, initialize: function (b, c) { this.cid = a.uniqueId('collection'), c = c || { }, this.cursor = c.cursor || { } }, ensureFetched: a.memoize(function () { return this.fetch() }, function () { return this.cid }), fetch: function (c) { return c = c || { }, c.data = a.defaults(c.data || { }, { cursor: c.cursor || '', limit: c.limit || this.PER_PAGE }), b.Collection.prototype.fetch.call(this, c) }, hasPrev: function () { return this.cursor.hasPrev }, hasNext: function () { return this.cursor.hasNext }, next: function (b) { return this.cursor.hasNext ? this.fetch(a.extend({ }, b, { add: !0, remove: !0, cursor: this.cursor.next })) : void this.trigger('nodata') }, prev: function (b) { return this.cursor.hasPrev ? this.fetch(a.extend({ }, b, { add: !0, remove: !0, cursor: this.cursor.prev })) : void this.trigger('nodata') }, more: function (b) { function c(a) { f.push(a) } var d = this; if (b = b || { }, b.post ? !b.post.attributes.hasMore : !this.cursor.hasNext) return void d.trigger('nodata'); var e, f = [ ]; if (b.post) { var g = this.postCursors[b.post.id]; e = g && g.cursor ? g.cursor.next : '' } else e = this.cursor.next; return this.on('add', c), this.fetch(a.extend({ }, b, { add: !0, remove: !1, cursor: e, limit: this.PER_PAGE || this.perPage, success: function () { d.trigger('add:many', f, d, b), d.off('add', c), b.success && b.success.apply(this, arguments) } })) }, parse: function (c) { return Array.isArray(c) && a.every(c, function (a) { return a instanceof b.Model }) ? c : (this.cursor = c.cursor || { hasNext: !1 }, c.response) }, getLength: function () { return this.length } }); return c }), define('core/collections/ChannelCollection', [ 'underscore', 'core/collections/PaginatedCollection', 'core/UniqueModel', 'core/api', 'core/models/Channel', 'core/utils/objectExpander' ], function (a, b, c, d, e, f) { 'use strict'; var g = b.extend({ url: d.getURL('channels/list'), model: c.boundModel(e), initialize: function (a, c) { b.prototype.initialize.call(this, a, c), c = c || { }, this.listName = c.listName }, fetch: function (c) { return c = c || { }, this.listName && (c.data = a.extend({ listName: this.listName }, c.data)), b.prototype.fetch.call(this, c) }, parse: function (c) { return c = b.prototype.parse.call(this, c), c.items ? a.map(c.items, function (a) { return f.buildChannel(c.objects, a.reference) }) : c } }); return g }), define('core/common/cached-storage', [ 'underscore', 'core/utils/storage' ], function (a, b) { 'use strict'; var c = function (a, b) { this.namespace = a, this.ttl = b || 300, this.cache = this.getFromStorage() }; return a.extend(c.prototype, { getItem: function (a) { var b = this.cache[a]; if (b) { if (!this.isExpired(b)) return b.value; delete this.cache[a] } }, getCurrentTime: function () { return Math.floor((new Date).getTime() / 1000) }, persist: function () { b.set(this.namespace, this.cache) }, getFromStorage: function () { var c = b.get(this.namespace); return a.isObject(c) ? c : { } }, isExpired: function (a) { return this.getCurrentTime() > a.expiry }, setItem: function (a, b) { this.cache[a] = { value: b, expiry: this.getCurrentTime() + this.ttl }, this.persist() }, removeItem: function (a) { delete this.cache[a], this.persist() }, getAll: function () { var b = a.chain(this.cache).map(function (a, b) { return this.getItem(b) }, this).compact().value(); return this.persist(), b } }), c }), define('common/collections', [ 'underscore', 'backbone', 'moment', 'core/api', 'core/utils/objectExpander', 'core/utils/storage', 'core/collections/UserCollection', 'core/collections/PaginatedCollection', 'core/collections/ChannelCollection', 'core/models/ThreadVote', 'core/UniqueModel', 'common/models', 'core/common/cached-storage', 'core/constants/voteConstants', 'lounge/common' ], function (a, b, c, d, e, f, g, h, i, j, k, l, m, n, o) { 'use strict'; var p = b.Collection.extend({ model: j }), q = h.extend({ PER_PAGE: 50, model: k.wrap(l.Post), url: d.getURL('threads/listPostsThreaded'), initialize: function (a, b) { h.prototype.initialize.apply(this, arguments), b = b || { }, this.thread = b.thread, this.setOrder(b.order) }, fetch: function (b) { return b = b || { }, a.extend(b, { data: { limit: this.PER_PAGE, thread: this.thread.id, forum: this.thread.get('forum'), order: this.getOrder() } }), h.prototype.fetch.call(this, b) }, getOrder: function () { return this.order }, setOrder: function (a) { 'popular' === a && this.thread.forum.get('votingType') === n.VOTING_TYPES.DISABLED ? this.order = 'desc' : this.order = a } }), r = b.Collection.extend({ collection: b.Collection, initialize: function (a, b) { this.lounge = o.getLounge(), this.thread = b.thread, this.perPage = b.perPage || 20, this.buffer = new this.collection(a, b), this.resetPage(), this.listenTo(this.buffer, 'reset', this.resetPage) }, resetPage: function (c, d) { d = d || { }; var e = a.isUndefined(d.customThreadLength) ? this.perPage : Math.min(d.customThreadLength, this.perPage), f = this.buffer.slice(0, e); return this.postCursors = { }, this.fetchedReplies = 0, this.trigger('set:done', f), b.Collection.prototype.reset.call(this, f, d) }, currentPage: function () { var a = Math.floor((this.length - this.fetchedReplies) / this.perPage); return (this.length - this.fetchedReplies) % this.perPage && (a += 1), a }, setPageFor: function (a, b) { var c = this.buffer.get(a), d = this.perPage; c && (d = this.perPage * Math.floor(this.buffer.indexOf(c) / this.perPage + 1)), this.add(this.buffer.slice(0, d), b) }, hasNext: function () { return this.buffer.length > this.length || this.buffer.hasNext() }, more: function (a) { a = a || { }; var b = this, c = b.length + b.perPage, d = a.success; a.success = function () { a.post || b.add(b.buffer.slice(0, c)), b.trigger('set:done', b.models), d && d() }; var e = a.post ? b.get(a.post.id) : null; e && e.attributes.hasMore ? b.collection.prototype.more.call(b, a) : !e && b.buffer.length < b.length + b.perPage && b.buffer.hasNext() ? (b.add(b.buffer.slice(0, c)), b.buffer.more(a)) : a.success() } }); a.each(['setOrder', 'getOrder', 'reset'], function (a) { r.prototype[a] = function () { return this.buffer[a].apply(this.buffer, arguments) } }), a.each(['add', 'remove'], function (a) { r.prototype[a] = function () { return this.buffer[a].apply(this.buffer, arguments), b.Collection.prototype[a].apply(this, arguments) } }); var s = r.extend({ model: q.prototype.model, collection: q, initialize: function () { r.prototype.initialize.apply(this, arguments), this.postCursors = { }, this.fetchedReplies = 0, this.submittedPostsCache = new m('submitted_posts_cache'), this.on('set:done', this.mapStartPosts) }, restoreFromCache: function () { var b = this.submittedPostsCache.getAll(), c = this; this.add(a.chain(b).reject(function (a) { return c.thread.get('id') !== a.thread || a.parent && !c.get(a.parent) }).map(function (a) { return a.isCached = !0, a }).value()) }, removeFromCache: function (a) { this.submittedPostsCache.removeItem(a.id) }, saveToCache: function (a) { this.submittedPostsCache.setItem(a.id, a.toJSON()) }, mapStartPosts: function (c) { if (null !== c) { var d = this; c = Array.isArray(c) ? c : [ c ], a.forEach(c.slice().reverse(), function (a) { var c = a instanceof b.Model ? a.get('parent') : a.parent; c && !d.postCursors[c] && (d.postCursors[c] = Object.defineProperty({ }, 'startPost', { value: a.id, writeable: !1 })) }) } }, fetch: function (c) { if (c = c || { }, !c.post) return this.buffer.fetch(c); var e = this; return c = a.extend({ url: d.getURL('posts/getDescendants'), data: { limit: c.limit || this.perPage, order: this.getOrder(), post: c.post.id, start_post: this.postCursors[c.post.id] ? e.postCursors[c.post.id].startPost : '', cursor: c.cursor || '' } }, c), b.Collection.prototype.fetch.call(e, c) }, parse: function (a, b) { if (!(b.url && b.url.indexOf('posts/getDescendants') > - 1)) return this.buffer.parse(a, b); this.postCursors[b.data.post] || (this.postCursors[b.data.post] = { }), this.postCursors[b.data.post].cursor = a.cursor, b.post.set('hasMore', a.cursor.hasNext), this.fetchedReplies += a.response.length; var c = this.buffer.indexOf(b.post), d = this.getDescendantsFromBuffer(b.post); return d && this.add(d, { at: c }), this.buffer.add(a.response, { at: c + d.length }), a.response }, getDescendantsFromBuffer: function (b) { var c = { }; c[b.id] = b; var d = this.buffer.slice(this.buffer.indexOf(b) + 1); return a.some(d, function (a) { var b = a.get('parent'); return !b || !c[b] || (c[a.id] = a, !1) }), a.values(c) } }), t = b.Collection.extend({ model: l.QueuedPost, initialize: function (a, b) { var c = this; c.thread = b.thread, c.counters = { comments: 0, replies: { } }, c.on('add', function (a) { var b = a.getVisibleParent(c.thread), d = c.counters.replies; b ? (d[b.id] = (d[b.id] || 0) + 1, b.id === a.get('parentId') && a.set('immedReply', !0)) : c.counters.comments += 1 }) }, comparator: function (a) { return parseInt(a.id, 10) }, isDescendant: function (b, c) { var d = b.get('parentId'), e = d ? this.get(d) : null, f = { }; for (a.each(c, function (a) { f[a] = !0 }); e; ) { if (f[e.get('id')] === !0) return !0; d = e.get('parentId'), e = d ? this.get(d) : null } return !1 }, drain: function D(b) { function c(a) { var b = [ ]; e.each(function (a) { null === a.get('parentId') && b.push(a.get('id')) }), e.reset(e.filter(function (c) { return null === c.get('parentId') || e.isDescendant(c, b) ? void a(c) : c })), e.counters.comments = 0 } function d(c) { var d, f = [ ]; d = e.filter(function (a) { var c = a.getVisibleParent(e.thread); return c && c.get('id') === b ? void f.push(a) : a }), f = a.sortBy(f, function (a) { return parseInt(a.get('id'), 10) }), a.each(f, function (a) { c(a) }), e.reset(d), e.counters.replies[b] = 0 } var e = this, D = b ? d : c; return D(function (a) { e.thread.posts.add(a.toPost(e.thread)) }) } }), u = b.Collection.extend({ models: l.TypingUser, initialize: function () { var b = this; b.gc = null, b.on('add remove reset', function () { var c = b.count(); return c > 0 && null === b.gc ? void (b.gc = setInterval(a.bind(b.cleanup, b), 60000)) : void (c <= 0 && null !== b.gc && (clearInterval(b.gc), b.gc = null)) }, b) }, count: function (a) { var b = this.filter(function (b) { return !(a && b.id === a) && b.get('typing') }); return b.length }, cleanup: function () { var a = c(); this.reset(this.filter(function (b) { return a.diff(b.lastModified, 'minutes') < 5 })) } }), v = h.extend({ model: k.wrap(l.Post), url: d.getURL('users/listPostActivity') }), w = h.extend({ model: l.Thread, url: d.getURL('timelines/ranked'), initialize: function (a, b) { b = b || { }, this.type = b.type, this.target = b.target }, fetch: function (b) { return b = b || { }, b.data = a.extend({ type: this.type, target: this.target }, b.data), h.prototype.fetch.call(this, b) }, parse: function (b) { return b = h.prototype.parse.call(this, b), a.map(b.activities, function (a) { return e.buildThread(b.objects, a.items[0].object) }) } }), x = b.Collection.extend({ model: l.SyncedTopUser, url: d.getURL('forums/listMostActiveUsers'), initialize: function (a, b) { this.forum = b.forum, this.limit = b.limit }, fetch: function (c) { return b.Collection.prototype.fetch.call(this, a.extend({ data: { forum: this.forum, limit: this.limit } }, c)) }, parse: function (b) { return a.filter(b.response, function (a) { if (parseFloat(a.rep) > 0.7) return a }) } }); g.prototype.model = k.wrap(l.User); var y = b.Collection.extend({ model: l.SyncedUser, url: d.getURL('forums/listModerators'), initialize: function (a, b) { this.forum = b.forum }, fetch: function (c) { return b.Collection.prototype.fetch.call(this, a.extend({ data: { forum: this.forum } }, c)) }, parse: function (b) { return a.map(b.response, function (a) { return a.user }) } }), z = 'reaction-vote', A = b.Collection.extend({ url: d.getURL('threadReactions/loadReactions'), initialize: function (a, b) { this.thread = b.thread, this.enabled = Boolean(a.length), this.eligible = Boolean(b.eligible), this.userIsAnonymous = b.userIsAnonymous }, fetch: function (c) { return b.Collection.prototype.fetch.call(this, a.extend({ data: { thread: this.thread.id } }, c)) }, parse: function (a) { var b = a.response, c = b.reactions, d = b.selected && b.selected.id; if (!d && this.userIsAnonymous) { var e = f.get(z); d = e && e[this.thread.get('id')] } if (d) { var g = c.filter(function (a) { return a.id === d }); g.length && (g[0].isSelected = !0, g[0].votes || (g[0].votes = 1)) } return this.enabled = Boolean(c.length), this.eligible = b.eligible, this.prompt = b.prompt, c }, toggleEnabled: function () { var a = this; d.call('threadReactions/disableForThread', { method: 'POST', data: { thread: this.thread.get('id'), enable: this.enabled ? 0 : 1 }, success: function () { a.enabled = !a.enabled, a.trigger('change:enabled'), a.enabled && !a.length && a.fetch() } }) }, vote: function (b, c) { var e = this.at(b); if (e && !e.get('isSelected')) { c = c || { }, this.trigger('vote:start'); var g = this; d.call('threadReactions/vote', a.extend({ }, c, { method: 'POST', data: { thread: this.thread.get('id'), reaction: e.get('id') }, success: function () { if (g.forEach(function (a, c) { var d = c === b, e = a.get('votes'); d && (e += 1), a.get('isSelected') && (e = Math.max(0, e - 1)), a.set({ isSelected: d, votes: e }) }, g), g.trigger('vote:end'), g.userIsAnonymous) { var a = f.get(z) || { }; a[g.thread.get('id')] = e.get('id'), f.set(z, a) } c.success && c.success() }, error: function () { g.trigger('vote:end'), c.error && c.error() } })) } } }), B = b.Collection.extend({ url: d.getURL('gifs/search'), model: l.GifObject, query: null, page: null, fetch: function (c) { return c.query === this.query ? this.page += 1 : this.page = 1, b.Collection.prototype.fetch.call(this, a.extend({ data: { forum: c.forum, query: c.query, page: this.page } }, c)) }, parse: function (a, b) { var c = a.response, d = this.toJSON(); return b.query === this.query ? d.concat(c) : (this.query = b.query, c) }, reset: function () { return this.query = null, this.page = null, b.Collection.prototype.reset.call(this) } }), C = b.Collection.extend({ url: d.getURL('mentions/listUsers'), model: l.SyncedUser, LIMIT: 5, query: null, cursor: null, initialize: function (a, b) { this.threadId = b && b.threadId }, fetch: function (c) { var d = this.cursor && this.cursor.hasNext; if (this.query !== c.query || d) return b.Collection.prototype.fetch.call(this, a.extend({ data: { thread: this.threadId, cursor: c.next && d && this.cursor.next ? this.cursor.next.slice(2) : null, query: c.query, limit: c.limit || this.LIMIT } }, c)) }, parse: function (a, c) { var d = a.response, e = a.cursor, f = this.toJSON(); return f = c.query === this.query ? f.concat(d) : d, this.query = c.query, this.cursor = e, this.set(f), b.Collection.prototype.parse.call(this, f), f }, reset: function () { return this.query = null, this.cursor = null, b.Collection.prototype.reset.call(this) } }); return { PaginatedCollection: h, UserCollection: g, ChannelCollection: i, PostCollection: q, SubpaginatedPostCollection: s, TypingUserCollection: u, TopUserCollection: x, RankedThreadCollection: w, ThreadVoteCollection: p, PostActivityCollection: v, QueuedPostCollection: t, ModeratorCollection: y, ReactionsCollection: A, GifObjectsCollection: B, UserSuggestionsCollection: C } }), define('core/constants/storageConstants', [ 'exports' ], function (a) { 'use strict'; a.STORAGE_KEY_SESSION_ID = 'sessionId' }), define('core/models/Session', [ 'jquery', 'underscore', 'backbone', 'moment', 'core/api', 'core/bus', 'core/config', 'core/constants/storageConstants', 'core/time', 'core/utils', 'core/utils/cookies', 'core/utils/guid', 'core/utils/auth', 'core/utils/storage', 'core/models/BaseUser', 'core/models/User' ], function (a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p) { 'use strict'; var q = function () { return m.getFromCookie() }, r = function () { return n.get(h.STORAGE_KEY_SESSION_ID) }, s = c.Model.extend({ initialize: function () { this.constructor.fromCookie = b.once(q), this.user = this.getAnonUserInstance() }, setUser: function (a) { this.user && this.stopListening(this.user), this.user = a, this.setIfNewUser(), this.listenTo(a, 'all', this.trigger), this.trigger('change:id', a) }, isLoggedOut: function () { return !this.isLoggedIn() }, isLoggedIn: function () { return Boolean(this.user.get('id')) }, fetch: function (a) { var c = a || { }; return e.call('users/details.json', { data: c.data, success: b.bind(function (a) { a = a.response, a.id && this.setUser(this.getUserInstance(a)), c.success && c.success(a), c.complete && c.complete(a) }, this), error: function (a) { c.error && c.error(a), c.complete && c.complete(a) } }) }, getAnonUserInstance: function (a) { return new o(a) }, getUserInstance: function (a) { return new p(a) }, getCsrfToken: function () { var a = k.read('csrftoken'); return a || (a = l.generate().replace(/\W/g, ''), k.create('csrftoken', a, { domain: window.location.hostname, expiresIn: 31536000000 })), a }, authenticate: function (c) { var d = this.authServices[c]; if (d) { if (b.isFunction(d)) return d.call(this); f.trigger('uiAction:openLogin', c); var e = this.getAuthWindowArgs(d), g = d.url; g += (g.indexOf('?') > - 1 ? '&' : '?') + a.param(e), this.openAuthWindow(g, d.width, d.height) } }, authServices: { disqus: { url: g.urls.login, width: 460, height: 355, attachExperiment: !0 }, twitter: { url: g.urls.oauth.twitter, width: 650, height: 680, csrf: !0, attachExperiment: !0 }, facebook: { url: g.urls.oauth.facebook, width: 550, height: 320, csrf: !0, attachExperiment: !0 }, google: { url: g.urls.oauth.google, width: 445, height: 635, csrf: !0, attachExperiment: !0 }, microsoft: { url: g.urls.oauth.microsoft, width: 650, height: 635, csrf: !0, attachExperiment: !0 }, apple: { url: g.urls.oauth.apple, width: 445, height: 750, csrf: !0, attachExperiment: !0 } }, getAuthWindowArgs: function (a) { var c = { }; return a.csrf && (c.ctkn = this.getCsrfToken()), b.extend(c, a.params), c }, openAuthWindow: function (a, b, c) { return j.openWindow(a, '_blank', { width: b, height: c }) }, setIfNewUser: function () { var a = this.user.get('joinedAt'); if (this.user.get('isAnonymous') || !a) return void this.user.set('joinedRecently', !1); var b = i.assureTzOffset(a); this.user.set('joinedRecently', d().subtract(10, 'seconds').isBefore(b)) } }); return s.fromCookie = q, s.fromLocalStorage = r, s.isKnownToBeLoggedOut = function () { return !s.fromCookie().id && !s.fromLocalStorage() }, s }), define('core/WindowBus', [ 'jquery', 'underscore', 'backbone', 'modernizr' ], function (a, b, c, d) { 'use strict'; var e = c.Model.extend({ initialize: function () { d.localstorage && a(window).on('storage', b.bind(this.onStorageEvent, this)) }, broadcast: function (a, b) { if (d.localstorage) { var c = JSON.stringify({ name: a, data: b, time: (new Date).getTime() }); try { window.localStorage.setItem(this.constructor.STORAGE_KEY, c) } catch (e) { } } }, onStorageEvent: function (a) { var b = a.originalEvent.key, c = a.originalEvent.newValue; if (c && b === this.constructor.STORAGE_KEY) try { c = JSON.parse(c), this.trigger(c.name, c.data) } catch (d) { } } }, { STORAGE_KEY: 'disqus.bus' }); return e }), define('templates/lounge/threadVotes', [ 'react', 'core/config/urls', 'core/strings', 'core/switches', 'core/utils/object/get' ], function (a, b, c, d, e) { 'use strict'; var f = c.gettext, g = function (c) { var g = c.thread && c.thread.forum, h = d.isFeatureActive('embed_refresh', { forum: g }), i = h && d.isFeatureActive('embed_refresh_v2', { forum: g }), j = h ? 'favorite-button-toggle' : 'dropdown-toggle', k = h ? 'label-count-refresh' : 'label-count', l = i ? 'favorite-icon favorite-icon--refresh-v2' : 'favorite-icon', m = function () { return i ? a.createElement('span', { className: 'label label-default' }, a.createElement('span', { className: l + ' icon-heart-empty' })) : h ? null : a.createElement('span', { className: 'label label-default' }, a.createElement('span', { className: 'favorite-icon icon-heart-empty' })) }, n = function () { return i ? a.createElement('span', { className: 'label label-favorited' }, a.createElement('span', { className: l + ' icon-heart' })) : h ? null : a.createElement('span', { className: 'label label-favorited' }, a.createElement('span', { className: 'favorite-icon icon-heart' })) }, o = function () { return h && !i ? a.createElement('div', { className: 'favorite-icon-wrapper' }, a.createElement('i', { className: 'favorite-icon-refresh' })) : null }; return a.createElement('div', null, a.createElement('a', { href: '#', 'data-action': 'favorite', title: f('Favorite this discussion'), className: j + ' ' + (i ? j + '--v2' : '') + ' ' + (e(c.thread, [ 'userScore' ]) ? 'upvoted' : ''), 'aria-label': f('Favorite this discussion') }, m(), n(), o(), ' ', e(c.thread, [ 'likes' ]) ? a.createElement('span', { className: 'label ' + k + ' ' + (i ? k + '--v2' : '') }, e(c.thread, [ 'likes' ], null)) : null), a.createElement('ul', { className: 'dropdown-menu dropdown-menu--coachmark pull-right' }, a.createElement('li', null, c.loggedIn ? a.createElement('div', null, a.createElement('h2', { className: 'coachmark__heading' }, f('Your 1st favorited discussion!')), a.createElement('p', { className: 'coachmark__description' }, f('Favoriting means this is a discussion worth sharing. It gets shared to your followers\' %(Disqus)s feeds if you log in, and gives the creator kudos!', { Disqus: 'Disqus' }))) : a.createElement('div', null, a.createElement('h2', { className: 'coachmark__heading' }, f('Discussion Favorited!')), a.createElement('p', { className: 'coachmark__description' }, f('Favoriting means this is a discussion worth sharing. It gets shared to your followers\' %(Disqus)s feeds, and gives the creator kudos!', { Disqus: 'Disqus' }))), ' ', a.createElement('a', { href: (b.root || '') + '/home/?utm_source=disqus_embed&utm_content=recommend_btn', className: 'btn btn-primary coachmark__button', target: '_blank', rel: 'noopener noreferrer' }, f(c.loggedIn ? 'See Your Feed' : 'Find More Discussions'))))) }; return g }), define('lounge/views/favorite-button', [ 'backbone', 'core/utils/storage', 'templates/lounge/threadVotes' ], function (a, b, c) { 'use strict'; var d = a.View.extend({ className: 'thread-likes', events: { 'click [data-action=favorite]': 'favoriteHandler' }, initialize: function (a) { this.session = a.session, this.thread = a.thread, this.loggedOutFavoriteFlag = this.session.getLoggedOutUserFlags().get(d.ONBOARDING_KEY), this.listenTo(this.thread, 'change:userScore', this.render), this.listenTo(this.thread, 'change:likes', this.render), this.listenTo(this.session, 'change:id', this.startFavoriteOnboarding), this.setTooltipEnabled() }, setTooltipEnabled: function () { this.tooltipEnabled = this.session.isLoggedIn() ? b.get(d.ONBOARDING_KEY) : !this.loggedOutFavoriteFlag.isRead() }, render: function () { return this.$el.html(c({ thread: this.thread.toJSON(), user: this.session.toJSON(), loggedIn: this.session.isLoggedIn() })), this }, startFavoriteOnboarding: function () { this.session.user.get('joinedRecently') && b.set(d.ONBOARDING_KEY, 'true'), this.setTooltipEnabled() }, favoriteHandler: function (a) { a.stopPropagation(), a.preventDefault(); var b = 0 === this.thread.get('userScore'); this.trigger(b ? 'vote:like' : 'vote:unlike'), this.thread.vote(b ? 1 : 0), this.toggleTooltip(b), this.tooltipEnabled && b && this.markAsSeen() }, markAsSeen: function () { this.session.isLoggedIn() ? b.remove(d.ONBOARDING_KEY) : this.loggedOutFavoriteFlag.markRead() }, toggleTooltip: function (a) { this.tooltipEnabled && (a ? this.$el.parent().addClass('open') : this.$el.parent().removeClass('open')) } }, { ONBOARDING_KEY: 'showRecommendOnboarding' }); return d }), define('common/collections/LoggedOutCache', [ 'backbone', 'core/common/cached-storage', 'lounge/views/favorite-button' ], function (a, b, c) { 'use strict'; var d = [ { id: 'welcome', title: '', body: '' } ], e = [ { id: c.ONBOARDING_KEY } ], f = new b('notes', 7776000), g = a.Model.extend({ markRead: function () { f.setItem(this.id, !0) }, isRead: function () { return Boolean(f.getItem(this.id)) } }), h = a.Collection.extend({ initialize: function (a, b) { this.session = b.session }, model: g, markAllRead: function () { return this.each(function (a) { a.markRead() }), this.session.set('notificationCount', 0), this }, getUnread: function () { return this.filter(function (a) { return !a.isRead() }) } }); return { storage: f, Collection: h, Model: g, LOGGED_OUT_NOTES: d, LOGGED_OUT_FLAGS: e } }), define('common/Session', [ 'jquery', 'underscore', 'core/analytics/jester', 'core/api', 'core/bus', 'core/config', 'core/constants/storageConstants', 'common/models', 'common/urls', 'core/models/Session', 'core/switches', 'core/UniqueModel', 'core/utils/cookies', 'core/utils/url/serialize', 'core/WindowBus', 'core/utils/storage', 'common/collections/LoggedOutCache', 'common/keys', 'common/utils', 'lounge/common', 'lounge/tracking' ], function (a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p, q, r, s, t, u) { 'use strict'; var v, w = 3500, x = { }, y = new o, z = j.extend({ _defaults: { canReply: !0, canModerate: !1, audienceSyncVerified: !1, sso: null }, socialLoginProviders: { facebook: function () { var b = a.Deferred(); return require(['fb'], b.resolve.bind(b), b.reject.bind(b)), b.promise().then(function () { window.FB.init({ appId: r.facebook, xfbml: !1, status: !0, version: 'v2.8' }); var b = a.Deferred(); return window.FB.getLoginStatus(function (a) { 'connected' === a.status ? b.resolve(a) : b.reject() }), b.promise() }).then(function (a) { c.logStat('lounge.auto_login.fb'); var b = a.authResponse; return { grant_type: 'urn:disqus:params:oauth:grant-type:facebook-login', client_id: r.embedAPI, expires: b.expiresIn, fb_access_token: b.accessToken } }) }, google: function () { var b = a.Deferred(); return require(['gapi'], function (a) { setTimeout(b.reject.bind(b), w), a.load('auth2', b.resolve.bind(b, a)) }, b.reject.bind(b)), b.promise().then(function (b) { var c = b.auth2.init({ client_id: r.google, fetch_basic_profile: !1, scope: 'profile email' }), d = a.Deferred(); return c.then(function () { c.isSignedIn.get() ? d.resolve(c.currentUser.get()) : d.reject() }), d.promise() }).then(function (a) { c.logStat('lounge.auto_login.google'); var b = a.getAuthResponse(); return { grant_type: 'urn:disqus:params:oauth:grant-type:google-login', client_id: r.embedAPI, expires: b.expires_in, google_access_token: JSON.stringify(b) } }) } }, initialize: function () { z.__super__.initialize.apply(this, arguments), !x.fromCookie().isAuthenticated && this.getSessionId() && d.headers({ 'X-Sessionid': this.getSessionId() }) }, setSessionId: function (a) { p.set(g.STORAGE_KEY_SESSION_ID, a) }, removeSessionId: function () { p.remove(g.STORAGE_KEY_SESSION_ID) }, getSessionId: function () { return p.get(g.STORAGE_KEY_SESSION_ID) }, defaults: function () { var a = new q.Collection(q.LOGGED_OUT_NOTES, { session: this }); return b.extend(this._defaults, { notificationCount: a.getUnread().length }) }, start: function (b) { var c = b || { }; if (this.set(c), this.listenTo(y, 'auth:success', this.fetch), this.listenTo(e.frame, { '!auth:success': function (a) { a && (a.sessionId && (d.headers({ 'X-Sessionid': a.sessionId }), x.fromCookie().isAuthenticated || this.setSessionId(a.sessionId)), a.message && this.trigger('alert', a.message, { type: 'info' }), a.logEvent && e.trigger('uiAction:' + a.logEvent)), y.broadcast('auth:success'), this.fetch() } }), this.bindAudienceSyncHandlers(), this.shouldFetchSession()) this.fetch(); else if (m.read('no_auto_login') || u.isPrivate()) this.loginAsAnon(); else { var f = this.socialLoginProviders, g = !1, h = 0, i = a.Deferred(), j = Object.keys(f).map(function (a) { return f[a].call(this) }, this), k = function (a) { g || (g = !0, i.resolve(a)) }, l = function (a) { h += 1, h === j.length && i.reject(a) }; j.forEach(function (a) { a.then(k).fail(l) }), i.promise().then(function (b) { return a.post('https://disqus.com/api/oauth/2.0/access_token/', b) }).then(function (a) { this.fetch({ data: { access_token: a.access_token } }) }.bind(this)).fail(this.loginAsAnon.bind(this)) } }, stop: function () { this.stopListening(), this.off() }, loginAsAnon: function () { this.setUser(this.getAnonUserInstance()) }, shouldFetchSession: function () { return Boolean(this.get('remoteAuthS3') || x.fromCookie().id || this.getSessionId()) }, getUserInstance: function (a) { return new l(h.User, a) }, toJSON: function () { var a = this.user.toJSON.apply(this.user, arguments); return a.thread.canReply = this.get('canReply'), a.thread.canModerate || (a.thread.canModerate = this.get('canModerate')), a }, fetch: function (a) { var b = this, c = a || { }; b.has('thread') && (c.thread = b.get('thread')); var d = c.thread ? b.fetchThreadDetails(c) : j.prototype.fetch.call(b, c); return d.done(function () { b.set('notificationCount', 0) }), d }, fetchNotificationCount: function () { var b = this; return b.isLoggedIn() ? d.call('timelines/getUnreadCount.json', { data: { type: 'notifications', routingVersion: f.feedApiVersion } }).done(function (a) { b.set('notificationCount', a.response) }) : a.Deferred().resolve() }, fetchThreadDetails: function (a) { var c = this, e = a.thread; c._request && (c._request.abort(), c._request = null); var f = { thread: e.id, post: e.posts.pluck('id') }; return c._request = d.call('embed/threadDetails.json', { data: f, success: function (a) { var d = a.response, f = { }; if (d.user && (b.extend(f, d.user, { votes: d.votes }), f = b.omit(f, 'badges')), d.blockedUsers || d.blockingUsers) { var g = d.session.canModerate ? new Set(d.blockedUsers) : new Set([].concat(_toConsumableArray(d.blockedUsers), _toConsumableArray(d.blockingUsers))); b.extend(f, d.user, { blockedUserIdSet: g }), f.blockedUserIdSet.forEach(function (a) { new l(h.User, { id: a }).set({ isBlocked: !0 }) }) } var i = c.get('thread') && c.get('thread').forum && c.get('thread').forum.id; k.isFeatureActive('embed_refresh', { forum: i }) && d.followingUsers && (b.extend(f, d.user, { followingUserIdSet: new Set(d.followingUsers) }), f.followingUserIdSet.forEach(function (a) { return new l(h.User, { id: a, isFollowing: !0 }) })), c.set(d.session), f.id ? (c.setUser(new l(h.User, f)), e.users.add(c.user), d.thread && (e.set('userScore', d.thread.userScore), e.set('userSubscription', d.thread.userSubscription), e.set('userRating', d.thread.userRating))) : c.loginAsAnon(), c.trigger('fetchThreadDetails:success') }, complete: function () { c._request = null } }), c._request }, logout: function () { this.removeSessionId(); var a = this.get('sso'); this.isSSO() && a && a.logout ? e.frame.sendHostMessage('navigate', a.logout) : this.locationReplace(n(i.logout, { redirect: window.location.href })) }, locationReplace: function (a) { window.location.replace(a) }, isSSO: function () { return this.user && 'sso' === this.user.get('user_type') }, getAuthWindowArgs: function (a) { var c = j.prototype.getAuthWindowArgs.call(this, a), d = t.getLounge().config; if (a.attachExperiment && d && d.experiment) { var e = d.experiment; c.evs = window.btoa([e.experiment, e.variant, e.service].join(':')) } return b.defaults({ forum: this.get('thread') && this.get('thread').forum.id }, c) }, openAuthWindow: function (a, b, c) { try { var d = this.get('thread'), e = d && d.currentUrl; window.sessionStorage && e && window.sessionStorage.setItem('discussionUrl', e) } catch (f) { } return j.prototype.openAuthWindow.call(this, a, b, c) }, authServices: b.defaults({ disqusDotcom: { url: i.dotcomLogin, width: 478, height: 590, params: { next: i.login }, attachExperiment: !0 }, sso: function A() { var A = this.get('sso'), a = parseInt(A.width || '800', 10), c = parseInt(A.height || '500', 10), d = this.openAuthWindow(A.url, a, c); !function f() { s.isWindowClosed(d) ? e.frame.sendHostMessage('reload') : b.delay(f, 500) }() } }, j.prototype.authServices), bindAudienceSyncHandlers: function () { this.listenTo(this, 'change:id change:audienceSyncVerified', function () { this.get('audienceSyncVerified') && e.frame.sendHostMessage('session.identify', this.user.id) }), this.listenTo(e.frame, { '!audiencesync:grant': function () { this.set('audienceSyncVerified', !0) } }) }, getAudienceSyncUrl: function () { var a = { client_id: this.get('apiKey'), response_type: 'audiencesync', forum_id: this.get('thread').forum.id }; return 'https:' === window.location.protocol && (a.ssl = 1), n(i.authorize, a) }, getRecaptchaKey: function () { return this.get('recaptchaPublicKey') }, audienceSync: function () { this.openAuthWindow(this.getAudienceSyncUrl(), 460, 355) }, needsAudienceSyncAuth: function (a) { return a.get('settings').audienceSyncEnabled && this.isLoggedIn() && !this.get('audienceSyncVerified') }, getLoggedOutUserFlags: function () { return this._loggedOutUserFlags ? this._loggedOutUserFlags : (this._loggedOutUserFlags = new q.Collection(q.LOGGED_OUT_FLAGS, { session: this }), this._loggedOutUserFlags) } }); return b.extend(x, b.chain(z).keys().map(function (a) { return [a, z[a]] }).object().value(), { get: function () { return v = v || new z }, setDefaults: function (a) { if (v) throw new Error('Session defaults cannot be changed after a session instance is created!'); return z._defaults = b.extend(z.prototype._defaults, a), z._defaults }, forget: function () { v && (v.stop(), v = null) } }), x }), define('common/views/mixins', [ 'jquery', 'underscore', 'core/bus', 'core/UniqueModel', 'common/models', 'common/Session' ], function (a, b, c, d, e, f) { 'use strict'; var g = { proxyViewEvents: function (a) { this.listenTo(a, 'all', function (a) { 0 === a.indexOf('uiAction:') && this.trigger.apply(this, arguments) }, this) } }, h = { updateUserAvatarHelper: function (b, c) { a('img[data-user=' + b + '][data-role="user-avatar"]').attr('src', c) }, updateUserNameHelper: function (c, d) { var e = '[data-username="' + c + '"][data-role=username]'; a('a' + e + ', span' + e).html(b.escape(d)) }, bindProfileUIListeners: function (a) { this.listenTo(a, { 'change:avatar': function () { this.updateUserAvatarHelper(a.user.id, a.user.get('avatar').cache) }, 'change:name': function () { this.updateUserNameHelper(a.user.get('username'), a.user.get('name')) } }) } }, i = { toggleFollow: function (b) { b.preventDefault(), b.stopPropagation(); var c, g = b && a(b.target).closest('a[data-user]').attr('data-user'); c = this.collection && g ? this.collection.get(g) : this.user ? this.user : d.get(e.User, g); var h = f.get(); return h.isLoggedOut() ? (this.trigger('authenticating'), this.listenToOnce(h, 'change:id', function () { h.isLoggedIn() && this.follow(c) }), h.get('sso') && h.get('sso').url ? void h.authenticate('sso') : void h.authenticate('disqusDotcom')) : void (c.get('isFollowing') ? this.unfollow(c) : this.follow(c)) }, unfollow: function (a) { a.unfollow(), c.trigger('uiAction:unfollowUser', a) }, follow: function (a) { a.follow(), c.trigger('uiAction:followUser', a) } }; return { FollowButtonMixin: i, UiActionEventProxy: g, ProfileHtmlHelpers: h } }), define('core/utils/isIframed', [ ], function () { 'use strict'; return function (a) { try { return a.self !== a.top } catch (b) { return !0 } } }), define('core/utils/addElement', [ ], function () { 'use strict'; var a = window.document; return function (b, c, d) { var e = a.createElement(c); return d && Object.keys(d).forEach(function (a) { e.setAttribute(a, d[a]) }), b.appendChild(e), e } }), define('core/utils/isMediaTradecraftAdEnabled', [ 'core/utils/url/parseQueryString', 'core/switches', 'core/utils/addElement' ], function (a, b, c) { 'use strict'; function d() { var b = a(); if (!window.isMtcAdded) { window.isMtcAdded = !0; var d = window.document.head; c(d, 'link', { rel: 'preconnect', href: 'https://01.cdn.mediatradecraft.com/', crossorigin: '' }), c(d, 'link', { rel: 'dns-prefetch', href: 'https://01.cdn.mediatradecraft.com/' }), c(d, 'link', { rel: 'preconnect', href: 'https://securepubads.g.doubleclick.net/', crossorigin: '' }), c(d, 'link', { rel: 'dns-prefetch', href: 'https://securepubads.g.doubleclick.net/' }), c(d, 'link', { rel: 'preconnect', href: 'https://c.amazon-adsystem.com/', crossorigin: '' }), c(d, 'link', { rel: 'dns-prefetch', href: 'https://c.amazon-adsystem.com/' }), c(d, 'link', { rel: 'preconnect', href: 'https://micro.rubiconproject.com/', crossorigin: '' }), c(d, 'link', { rel: 'dns-prefetch', href: 'https://micro.rubiconproject.com/' }), c(d, 'script', { src: 'https://c.amazon-adsystem.com/aax2/apstag.js', async: 'true' }), c(d, 'script', { src: 'https://securepubads.g.doubleclick.net/tag/js/gpt.js', async: 'true' }), 'true' === b.mtctest && 'true' !== b.mtcprod ? (c(d, 'script', { src: 'https://01.cdn.mediatradecraft.com/disqus/stg/main.js', async: 'true' }), c(d, 'link', { href: 'https://01.cdn.mediatradecraft.com/disqus/stg/main.css', media: 'print', onload: 'this.media=\'all\'', rel: 'stylesheet' })) : (c(d, 'script', { src: 'https://01.cdn.mediatradecraft.com/disqus/main.js', async: 'true' }), c(d, 'link', { href: 'https://01.cdn.mediatradecraft.com/disqus/main.css', media: 'print', onload: 'this.media=\'all\'', rel: 'stylesheet' })) } } return function (c, e) { var f = a(); if ('false' === f.mtctest) return !1; var g = (!e || !e.channelId || 'true' === f.mtctest || b.isFeatureActive('mtc_ads_channels')) && (c && 'mtcdisabled' === c.experiment.experiment && 'active' === c.experiment.variant || 'true' === f.mtctest || b.isFeatureActive('mtc_ads')); return g ? d() : window.isMtcAdded && location.reload(), g } }), define('core/viglink', [ 'remote/config' ], function (a) { 'use strict'; var b = { }, c = null; return b.resetVersion = function () { c = null }, b.forceVersion = function (a) { c = a }, b.getVersion = function () { return c ? c : a.lounge && a.lounge.viglink && a.lounge.viglink.version || 'none' }, b.getExperimentVersion = function () { return a.lounge && a.lounge.viglink && a.lounge.viglink.experiment_version || 'none' }, b }), define('common/outboundlinkhandler', [ 'jquery', 'underscore', 'core/utils', 'common/utils' ], function (a, b, c, d) { 'use strict'; function e() { this.handlers = [ ], this.locked = { }, this.timeout = 1000 } return b.extend(e.prototype, { handleClick: function (d) { var e = a(d.currentTarget), f = this.getLinkTrackingId(e); if (this.shouldHandleClick(d, e, f)) { var g = b.chain(this.handlers).map(function (a) { return a[0].call(a[1], d, e) }).compact().value(); c.willOpenNewWindow(d, e) || (d.preventDefault(), this.setLatestClick(f), this.delayNavigation(d, e, g)) } }, delayNavigation: function (c, e, f) { this.lockLink(this.getLinkTrackingId(e)); var g = b.bind(function () { this.isLatestClick(this.getLinkTrackingId(e)) && d.triggerClick(e, c.originalEvent) }, this); b.delay(g, this.timeout), a.when.apply(a, f).always(g) }, registerBeforeNavigationHandler: function (a, b) { this.handlers.push([a, b]) }, getLinkTrackingId: function (a) { var c = a.attr('data-tid'); return c || (c = b.uniqueId(), a.attr('data-tid', c)), c }, shouldHandleClick: function (a, b) { if (!this.isLinkLocked(this.getLinkTrackingId(b))) { if (a.isDefaultPrevented()) return !1; if (!b.is('a')) return !1; var c = /#.*/, d = (b.attr('href') || '').replace(c, ''); return !!d } }, setLatestClick: function (a) { this.latestLinkId = a }, isLatestClick: function (a) { return this.latestLinkId === a }, lockLink: function (a) { this.locked[a] = !0 }, isLinkLocked: function (a) { return this.locked[a] } }), e }), define('core/mixins/withEmailVerifyLink', [ 'jquery', 'underscore', 'core/config', 'core/utils' ], function (a, b, c, d) { 'use strict'; var e = d.preventDefaultHandler, f = { events: { 'click [data-action=verify-email]': 'showVerifyEmailPopup' }, showVerifyEmailPopup: e(function (b) { var e = a(b.target).attr('data-forum'), f = c.urls.verifyEmail; return e && (f = f + '?f=' + e), d.openWindow(f, '_blank', { width: 460, height: 355 }) }) }; return function () { this.events = b.defaults({ }, this.events, f.events), b.extend(this, b.pick(f, 'showVerifyEmailPopup')) } }), define('core/constants/behindClickConstants', [ 'exports', 'core/strings' ], function (a, b) { 'use strict'; var c = b.get; a.DEFAULT_BUTTON_TEXT = b.interpolate(c('Show Comments (%(count)s)'), { count: '{postCount}' }) }), define('core/templates/react/BehindClickTemplate', [ 'react', 'core/constants/behindClickConstants' ], function (a, b) { 'use strict'; function c(a) { if (!a || a.indexOf(':') === - 1) return { }; var b = { }, c = a.split(';'); return c.forEach(function (a) { var c = a.split(':').map(function (a) { return a.trim() }); if (c[0].indexOf('-') > 0) { var d = c[0].split('-'); c[0] = d[0] + d[1].charAt(0).toUpperCase() + d[1].slice(1) } b[c.splice(0, 1) [0]] = c.join(':') }), b } function d(a, b) { return a ? a.replace('{postCount}', b.toLocaleString()) : a } var e = function (e) { var f = e.postCount, g = e.buttonText, h = e.buttonCSS, i = e.titleEnabled, j = e.titleText, k = e.titleCSS; return a.createElement('div', { id: 'behind-click__container' }, i ? a.createElement('h3', { id: 'behind-click__title', style: c(k) }, d(j, f)) : null, a.createElement('button', { id: 'thread-visibility__button', className: 'btn alert', 'data-action': 'toggle-thread-visibility', style: c(h) }, g ? d(g, f) : d(b.DEFAULT_BUTTON_TEXT, f))) }; return e }), define('templates/lounge/partials/badgesMessage', [ 'react', 'core/strings', 'core/switches', 'core/bus' ], function (a, b, c, d) { 'use strict'; var e = b.gettext, f = function (b) { var c = b.url; return a.createElement('a', { href: c, target: '_blank', rel: 'noopener noreferrer', className: 'policy-link publisher-anchor-color', onClick: function (a) { a.stopPropagation(), d.trigger('uiAction:clickBadgesMessage', c) } }, e('See the available badges')) }, g = function (b) { var d = b.forum, g = b.forumBadgesLink, h = c.isFeatureActive('embed_refresh', { forum: d.id }), i = h ? 'comment-policy-refresh' : 'comment-policy', j = h ? 'comment-policy-refresh__text' : 'comment-policy-text', k = h ? 'comment-policy-refresh__heading' : 'comment-policy-text text-bold', l = h ? 'comment-policy-refresh__link' : 'comment-policy-link'; return a.createElement('div', { id: 'badges-message', className: 'badges-message ' + i + ' publisher-anchor-color' }, a.createElement('span', { 'data-action': 'close-badges-message', className: 'badges-message-close', tabIndex: '0' }), a.createElement('div', { className: 'content' }, a.createElement('p', { className: k }, e('Earn badges on %(forumName)s!', { forumName: d.name })), a.createElement('p', { className: j }, e('Badges are awarded for commenting, receiving upvotes, and other conditions established by the publisher. Awarded badges will be displayed next to your name in comments on this site as well as on your profile.'), a.createElement('p', { className: l }, a.createElement(f, { url: g, isRefreshEnabled: h })))), a.createElement('span', { 'aria-hidden': 'true', className: 'badges-message-icon' })) }; return g }), define('templates/lounge/partials/commentPolicy', [ 'react', 'core/strings', 'core/bus', 'core/switches' ], function (a, b, c, d) { 'use strict'; var e = b.gettext, f = function (b) { var d = b.url, e = b.className, f = void 0 === e ? '' : e, g = b.children, h = b.isRefreshEnabled, i = h ? 'comment-policy-refresh__link' : 'comment-policy-link'; return a.createElement('a', { href: d, target: '_blank', rel: 'noopener noreferrer', className: f + ' ' + i, onClick: function (a) { a.stopPropagation(), c.trigger('uiAction:clickCommentPolicy', d) } }, g) }, g = function (b) { var c = b.forum, d = b.isRefreshEnabled; if (!c.commentPolicyLink) return null; var g = e('Please read our %(commentPolicyLink)s before commenting.', { commentPolicyLink: a.createElement(f, { url: c.commentPolicyLink, isRefreshEnabled: d }, e('Comment Policy')) }); return g }, h = function (b) { var c = b.forum, f = b.isPolicyAccepted, h = d.isFeatureActive('embed_refresh', { forum: c.id }), i = h && d.isFeatureActive('embed_refresh_v2', { forum: c.id }), j = h ? 'comment-policy-refresh ' + (i ? 'comment-policy-refresh--v2' : '') : 'comment-policy', k = h ? 'comment-policy-refresh__text' : 'comment-policy-text', l = h ? 'comment-policy-refresh__heading' : 'comment-policy-text text-bold'; return a.createElement('div', { id: 'comment-policy', className: j + ' publisher-anchor-color ' + (f ? 'hidden' : '') }, a.createElement('div', { className: 'content' }, a.createElement('p', { className: l }, e('%(forumName)s Comment Policy', { forumName: c.name })), a.createElement('p', { className: k }, c.commentPolicyText || null, a.createElement('p', { className: 'comment-policy-refresh__prompt' }, a.createElement(g, { forum: c, isRefreshEnabled: h })))), h ? a.createElement('button', { className: 'btn comment-policy-refresh__button publisher-background-color', 'data-action': 'accept-comment-policy' }, e('Got it')) : a.createElement('span', { 'aria-hidden': 'true', className: 'icon icon-chat-bubble' })) }; return h }), define('core/templates/react/ThreadTemplate', [ 'react', 'core/constants/voteConstants', 'core/strings', 'core/switches', 'core/utils/object/get', 'templates/lounge/partials/badgesMessage', 'templates/lounge/partials/commentPolicy' ], function (a, b, c, d, e, f, g) { 'use strict'; var h = c.gettext, i = function (b) { var c = d.isFeatureActive('embed_refresh', { forum: b.forum.id }), e = c && d.isFeatureActive('embed_refresh_v2', { forum: b.forum.id }), f = !1, i = c ? 'disqus-footer__wrapper disqus-footer__wrapper--refresh' : 'disqus-footer__wrapper', j = c ? 'load-more-refresh ' + (e ? 'load-more-refresh--v2' : '') : 'load-more', k = c ? 'btn load-more-refresh__button ' + (e ? '' : 'publisher-background-color-refresh') : 'btn load-more__button', l = c ? 'alert alert--realtime alert--realtime--refresh ' + (e ? 'alert--realtime--refresh-v2' : '') : 'alert alert--realtime', m = (b.forum.commentPolicyText || b.forum.commentPolicyLink) && !b.isPolicyAccepted, n = a.createElement('button', { className: l, style: { display: 'none' }, 'data-role': 'realtime-notification' }), o = f ? null : a.createElement('div', { id: 'highlighted-post', 'data-tracking-area': 'highlighted', className: 'highlighted-post' }); return a.createElement('div', { id: 'thread__wrapper' }, a.createElement('div', { id: 'placement-top', 'data-tracking-area': 'discovery-north' }), a.createElement('div', { id: 'onboard', 'data-tracking-area': 'onboard' }), m && c ? a.createElement(g, { forum: b.forum, isPolicyAccepted: b.isPolicyAccepted }) : null, a.createElement('div', { id: 'reactions__container' }), a.createElement('div', { id: 'ratings__container' }), m && !c ? a.createElement(g, { forum: b.forum, isPolicyAccepted: b.isPolicyAccepted }) : null, a.createElement('div', { id: 'badges-message__container' }), c ? null : o, a.createElement('div', { id: 'global-alert' }), a.createElement('div', { id: 'tos__container' }), b.inHome ? null : a.createElement('header', { id: 'main-nav', 'data-tracking-area': 'main-nav' }), a.createElement('section', { id: 'conversation', 'data-role': 'main', 'data-tracking-area': 'main' }, a.createElement('div', { id: 'posts' }, a.createElement('div', { id: 'form', className: 'textarea-outer-wrapper--top-level' }), c ? null : n, a.createElement('div', { id: 'email-signup' }), a.createElement('div', { id: 'secondary-navigation' }), a.createElement('div', { id: 'no-posts', style: { display: 'none' } }), c ? o : null, c ? n : null, f ? a.createElement('div', { id: 'embed_v2-thread' }) : a.createElement('ul', { id: 'post-list', className: 'post-list loading' }), a.createElement('div', { className: j, 'data-role': 'more', style: { display: 'none' } }, a.createElement('a', { href: '#', 'data-action': 'more-posts', className: k }, h('Load more comments'))))), a.createElement('div', { id: 'placement-bottom', 'data-tracking-area': 'discovery-south' }), b.hideFooter ? null : a.createElement('footer', { id: 'footer', 'data-tracking-area': 'footer', className: i })) }; return i }), define('lounge/menu-handler', [ 'jquery', 'core/bus' ], function (a, b) { 'use strict'; return { init: function (c) { function d() { a('.dropdown').removeClass('open') } a('html').on('click', d), a('body').delegate('[data-toggle]', 'click', function (b) { b.stopPropagation(), b.preventDefault(); var e = a(b.currentTarget), f = e.closest('.' + e.attr('data-toggle')), g = 'disabled' !== f.attr('data-dropdown') && !f.hasClass('open'); if (f.attr('data-dropdown', 'enabled'), d(), g) { f.addClass('open'); var h = f.data('view-id'); h && c.trigger('opened:' + h, f) } }), b.frame.on('window.click', d) } } }), define('lounge/mixins', [ 'core/utils/url/serialize', 'core/strings' ], function (a, b) { 'use strict'; var c = b.gettext, d = { _sharePopup: function (a, b) { return window.open(a, '_blank', b || 'width=550,height=520') }, share: function (a) { this.sharers[a].call(this) }, sharers: { twitter: function () { var b = 'https://twitter.com/intent/tweet', c = this.model.shortLink(); this._sharePopup(a(b, { url: c, text: this.model.twitterText(c) })) }, facebook: function () { this._sharePopup(a('https://www.facebook.com/sharer.php', { u: this.model.shortLink() }), 'width=655,height=352') }, email: function () { window.location.href = a('mailto:', { subject: c('Somebody has shared this with you on Disqus'), body: c('Check out this discussion') + ': ' + this.model.shortLink() }) } } }, e = function () { function a() { return this.collapseTarget && this.collapseTarget.length || (this.collapseTarget = this.collapseTargetSelector ? this[this.collapseScope].find(this.collapseTargetSelector) : this[this.collapseScope]), this.collapseTarget } function b() { var b = this; if (b.isCollapseAllowed) { var c = a.call(b); c && c.length && (c.height(b.collapsedHeight), e.call(b)) } } function c(a) { var b = this; if (b.collapseTarget && b.collapseTarget.length) { var c = b.collapseTarget; c.css('height', 'auto'), c.css('maxHeight', 'none'), f.call(b), a || (b.isCollapseAllowed = !1) } } function d() { return this.seeMoreButton && this.seeMoreButton.length || (this.seeMoreButton = a.call(this).siblings('[data-action=see-more]')), this.seeMoreButton } function e() { var a = this; d.call(this).removeClass('hidden').on('click', function () { a.expand() }) } function f() { d.call(this).addClass('hidden').off('click') } return function (a) { var d = this; d.isCollapseAllowed = !0, d.collapsedHeight = a.collapsedHeight, d.collapseTargetSelector = a.collapseTargetSelector, d.collapseScope = a.collapseScope || '$el', d.collapse = b, d.expand = c } }(); return { ShareMixin: d, asCollapsible: e } }), define('lounge/realtime', [ 'underscore', 'backbone', 'loglevel', 'remote/config', 'common/urls', 'core/utils/url/serialize', 'common/utils' ], function (a, b, c, d, e, f, g) { 'use strict'; function h() { s.apply(this, arguments), this.marker = 0, this.interval = m, this._boundOnError = a.bind(this.onError, this), this._boundOnLoad = a.bind(this.onLoad, this), this._boundOnProgress = a.bind(this.onProgress, this) } function i() { s.apply(this, arguments), this.handshakeSuccess = null, this.interval = m, this.handshakeFails = 0, this._boundOnOpen = a.bind(this.onOpen, this), this._boundError = a.bind(this.onError, this), this._boundClose = a.bind(this.onClose, this), this._boundMessage = a.compose(a.bind(this.onMessage, this), function (a) { return JSON.parse(a.data) }) } var j = d.lounge.REALTIME || { }, k = j.EXP_BASE || 2, l = j.BACKOFF_LIMIT || 300, m = j.BACKOFF_INTERVAL || 1, n = j.MAX_HANDSHAKE_FAILS || 1, o = j.WEBSOCKETS_ENABLED !== !1 && window.WebSocket && 2 === window.WebSocket.CLOSING, p = j.XHR_ENABLED !== !1, q = function () { }, r = function () { throw new Error('Pipe class cannot be used directly.') }, s = function (b) { this.channel = b, this.connection = null, this.paused = !1, this._msgBuffer = [ ], this._boundOpen = a.bind(this.open, this) }; a.extend(s.prototype, b.Events, { getUrl: function (b) { var c = { }; return a.extend(c, b), f(this.baseUrl + this.channel, c) }, onMessage: function (a) { var b = a.message_type, d = a.firehose_id; this.lastEventId = d, c.debug('RT: new message:', b, d); var e = { type: b, data: a.message_body, lastEventId: d }; this.trigger(b, e) }, _msgToBuffer: function () { this._msgBuffer.push(a.toArray(arguments)) }, pause: function (a) { this.paused || (this.paused = !0, this._trigger = this.trigger, this.trigger = a === !1 ? q : this._msgToBuffer, c.debug('RT: paused, buffered: %s', a !== !1)) }, resume: function () { if (this.paused) { this.paused = !1, this.trigger = this._trigger, c.debug('RT: resumed, buffered messages: %s', this._msgBuffer.length); for (var a; a = this._msgBuffer.shift(); ) this.trigger.apply(this, a) } }, open: r, close: function () { var a = this.connection; return !!a && (this.connection = null, a) } }), a.extend(h.prototype, s.prototype, { baseUrl: e.realertime + '/api/2/', onError: function () { this.connection && (this.connection = null, this.trigger('error', this), this.interval <= l && (this.interval *= k), c.info('RT: Connection error, backing off %s secs', this.interval), a.delay(this._boundOpen, 1000 * this.interval)) }, onLoad: function () { this.connection && (this.connection = null, this.trigger('success', this), a.defer(this._boundOpen)) }, onProgress: function () { if (this.connection) { var a, b, d, e, f = this.connection.responseText, g = 0; if (f && !(this.marker >= f.length)) { a = f.slice(this.marker).split('\n'); for (var h = a.length, i = 0; i < h; i++) if (b = a[i], g += b.length + 1, d = b.replace(/^\s+|\s+$/g, '')) { try { e = JSON.parse(d) } catch (j) { if (i === h - 1) { g -= b.length + 1; break } c.debug('RT: unable to parse: ', d, b); continue } this.onMessage(e) } else c.debug('RT: ignoring empty row...'); g > 0 && (this.marker += g - 1) } } }, open: function () { this.close(); var a = this.connection = g.CORS.request('GET', this.getUrl(), this._boundOnLoad, this._boundOnError); if (!a) return void c.debug('RT: Cannot use any cross-domain request tool with StreamPipe. Bailing out.'); a.onprogress = this._boundOnProgress, this.connection = a, this.marker = 0; try { a.send() } catch (b) { this.connection = null, c.debug('RT: Attempt to send a CORS request failed.') } }, close: function () { var a = s.prototype.close.apply(this); return a && a.abort() } }), a.extend(i.prototype, s.prototype, { baseUrl: 'wss:' + e.realertime + '/ws/2/', onOpen: function () { c.debug('RT: [Socket] Connection established.'), this.handshakeSuccess = !0 }, onError: function () { if (!this.handshakeSuccess) { if (this.handshakeFails >= n) return c.debug('RT: [Socket] Error before open, bailing out.'), void this.trigger('fail'); this.handshakeFails += 1 } this.connection && (this.connection = null, this.trigger('error'), this.interval <= l && (this.interval *= k), c.error('RT: Connection error, backing off %s secs', this.interval), a.delay(this._boundOpen, 1000 * this.interval)) }, onClose: function (a) { if (this.connection) { if (!a.wasClean) return this.onError(); this.connection = null, c.debug('RT: [Socket] Connection closed. Restarting...'), this.trigger('close'), this.open() } }, open: function () { this.close(); try { this.connection = new window.WebSocket(this.getUrl()) } catch (a) { return this.onError() } var b = this.connection; b.onopen = this._boundOnOpen, b.onerror = this._boundError, b.onmessage = this._boundMessage, b.onclose = this._boundClose }, close: function () { var a = s.prototype.close.apply(this); return a && a.close() } }); var t = { _wsSupported: o, initialize: function (b, c, d) { this.close(), this._initArgs = [ b, c, d ]; var e = this._wsSupported, f = e && i || p && h; if (f) { var g = this.pipe = new f(b); a.chain(c).pairs().each(function (a) { g.on(a[0], a[1], d) }), e && g.on('fail', function () { this._wsSupported = !1, g.off(), this.initialize.apply(this, this._initArgs) }, this), g.open() } }, pause: function (a) { this.pipe && this.pipe.pause(a) }, resume: function () { this.pipe && this.pipe.resume() }, close: function () { this.pipe && (this.pipe.close(), this.pipe = null) } }; return window.addEventListener('unload', a.bind(t.close, t)), { Pipe: s, StreamPipe: h, SocketPipe: i, Manager: t, MAX_HANDSHAKE_FAILS: n } }), define('lounge/views/badges-message', [ 'jquery', 'underscore', 'backbone', 'react', 'react-dom', 'core/switches', 'core/common/cached-storage', 'templates/lounge/partials/badgesMessage' ], function (a, b, c, d, e, f, g, h) { 'use strict'; var i = new g('badges-message', 7776000); i.getAll(); var j = c.View.extend({ events: { 'click [data-action=close-badges-message]': 'handleDismiss', 'keyup [data-action=close-badges-message]': 'handleDismiss' }, initialize: function (a) { b.extend(this, b.pick(a, [ 'forum', 'session' ])), this.model = new c.Model({ dismissed: Boolean(i.getItem(this.forum.id)) }), this.handleDismiss = this.handleDismiss.bind(this), this.listenTo(this.model, 'change', this.render) }, handleDismiss: function (a) { var b = 13; if (!a.keyCode || a.keyCode === b) return this.model.set('dismissed', !0), i.setItem(this.forum.id, !0), Promise.resolve() }, render: function () { var a = this.forum.get('badges'); if (!a || !Object.keys(a).length || this.model.get('dismissed')) return this.$el.empty(), this; var b = '//disqus.com/home/forum/' + this.forum.get('id') + '/badges'; return e.render(d.createElement(h, { forum: this.forum.toJSON(), forumBadgesLink: b }), this.el), this } }); return j }), define('core/templates/react/aet/EmailSignupComplete', [ 'react', 'core/switches' ], function (a, b) { 'use strict'; var c = function (c) { var d = c.forum, e = c.isVerified, f = c.onDismiss; return a.createElement('div', { className: 'newsletter-box spacing-bottom-large text-center' }, a.createElement('div', { className: b.isFeatureActive('embed_refresh', { forum: d.name }) ? 'text-large spacing-bottom-small' : 'text-medium spacing-bottom-small' }, a.createElement('strong', null, 'Thanks for subscribing!')), e ? a.createElement('div', { className: 'spacing-bottom-small' }, (d.aetBannerConfirmation || '').split('\n').map(function (b, c) { return a.createElement('div', { key: c }, b) })) : a.createElement('div', { className: 'spacing-bottom-small' }, 'To begin receiving email updates from ', d.name, ', please click the link in the confirmation email we\'ve sent to your inbox.'), a.createElement('a', { className: 'newsletter-box__hide', href: '#', onClick: function (a) { a.preventDefault(), f() } }, 'Dismiss this message')) }; return c }), define('core/templates/react/aet/EmailSignupForm', [ 'react', 'core/strings', 'core/switches' ], function (a, b, c) { 'use strict'; var d = b.gettext, e = function (b) { var e = b.forum, f = b.isLoading, g = b.isLoggedIn, h = b.onDismiss, i = b.onSubscribe, j = b.allowEmpty; return a.createElement('div', { className: 'newsletter-box spacing-bottom-large' }, a.createElement('div', { className: c.isFeatureActive('embed_refresh', { forum: e.name }) ? 'text-large spacing-bottom-small' : 'text-medium spacing-bottom-small' }, a.createElement('strong', null, e.aetBannerTitle)), g ? a.createElement('button', { className: 'button button-fill--brand button-padding-wider pull-right', disabled: f, onClick: function () { i && i() } }, 'Subscribe') : null, a.createElement('div', { className: 'spacing-bottom' }, (e.aetBannerDescription || '').split('\n').map(function (b, c) { return a.createElement('div', { key: c }, b) })), a.createElement('div', { className: 'align align--wrap' }, g ? null : a.createElement('form', { className: 'align__item--grow', onSubmit: function (a) { a.preventDefault(); var b = a.target.elements.email.value.trim(); (b || j) && i && i(b) } }, a.createElement('div', { className: 'newsletter-box__input-group' }, a.createElement('span', { className: 'icon icon-mail text-large newsletter-box__input-group__icon' }), a.createElement('input', { type: 'email', name: 'email', placeholder: d('Enter email address'), 'aria-label': 'Enter your email address here to opt into receiving a weekly digest of the latest articles from this publisher' })), a.createElement('input', { type: 'submit', className: 'button button-fill--brand button-padding-wider newsletter-box__submit', disabled: f, value: d('Subscribe'), 'aria-label': 'Submit your email address' })), a.createElement('a', { href: '#', className: 'newsletter-box__hide publisher-anchor-color', onClick: function (a) { a.preventDefault(), h && h() } }, d('Hide this message')))) }; return e }), define('lounge/views/email-signup', [ 'backbone', 'react', 'react-dom', 'stance', 'core/api', 'core/bus', 'core/templates/react/aet/EmailSignupComplete', 'core/templates/react/aet/EmailSignupForm', 'core/common/cached-storage' ], function (a, b, c, d, e, f, g, h, i) { 'use strict'; var j = 0, k = 2, l = new i('aet-dismiss'); l.getAll(); var m = a.View.extend({ initialize: function (b) { var c = b.forum, d = b.session; this.forum = c, this.session = d, this.model = new a.Model({ dismissed: Boolean(l.getItem(this.forum.id)), loading: !1, signupComplete: !1 }), this._isFirstRender = !0, this.handleCompleteDismiss = this.handleCompleteDismiss.bind(this), this.handleDismiss = this.handleDismiss.bind(this), this.handleSubscribe = this.handleSubscribe.bind(this), this.listenTo(this.model, 'change', this.render), this.listenTo(this.session, 'change', this.render) }, getTrackingCopy: function () { return { title: this.forum.get('aetBannerTitle'), description_copy: this.forum.get('aetBannerDescription'), confirmation_copy: this.forum.get('aetBannerConfirmation') } }, isLoggedIn: function () { return Boolean(this.session.user && this.session.user.id) }, handleDismiss: function () { return this.model.set('dismissed', !0), f.trigger('uiAction:clickEmailSubscriptionPromptDismiss', this.getTrackingCopy()), this.isLoggedIn() ? Promise.resolve(e.call('aet/dismiss', { data: { forum: this.forum.id }, method: 'POST' })) : (l.setItem(this.forum.id, !0), Promise.resolve()) }, handleCompleteDismiss: function () { this.model.set('dismissed', !0) }, handleSubscribe: function () { var a = this, b = arguments.length > 0 && void 0 !== arguments[0] ? arguments[0] : null; if (!this.model.get('loading')) return f.trigger('uiAction:clickEmailSubscriptionPromptSubscribe', this.getTrackingCopy()), this.model.set('loading', !0), Promise.resolve(b ? e.call('aet/anonymousSubscribe', { data: { email: b, forum: this.forum.id }, method: 'POST' }) : e.call('aet/subscribe', { data: { forum: this.forum.id }, method: 'POST' })).then(function (b) { return a.model.set({ loading: !1, signupComplete: !0 }), b }) ['catch'](function () { a.model.set('loading', !1) }) }, reportView: function () { f.trigger('uiAction:viewEmailSubscriptionPrompt', this.getTrackingCopy()) }, render: function () { if (!this.forum.get('aetEnabled') || this.model.get('dismissed')) return this.$el.empty(), this; var a = this.session.shouldFetchSession() ? this.session.get('aetBannerStatus') : j; switch (a) { case j: case k: if (this.model.get('signupComplete') || a === k ? c.render(b.createElement(g, { forum: this.forum.toJSON(), isVerified: Boolean(this.session.user && this.session.user.get('isVerified')), onDismiss: this.handleCompleteDismiss }), this.el) : c.render(b.createElement(h, { forum: this.forum.toJSON(), isLoading: this.model.get('loading'), isLoggedIn: this.isLoggedIn(), onDismiss: this.handleDismiss, onSubscribe: this.handleSubscribe }), this.el), this._isFirstRender) { this._isFirstRender = !1, f.trigger('uiAction:loadEmailSubscriptionPrompt', this.getTrackingCopy()); var e = d(this); e.isVisible() ? this.reportView() : this.listenToOnce(e, 'enter', this.reportView) } break; default: this.$el.empty() } return this } }); return m }), define('react-dom/server', [ 'underscore' ], function (a) { 'use strict'; var b = function c(b) { if (null === b) return ''; if (a.isArray(b)) return b.map(c).join(''); if (a.isElement(b)) return b.outerHTML; if (b && b.nodeType === window.Node.DOCUMENT_FRAGMENT_NODE) { var d = window.document.createElement('div'); return d.appendChild(b), d.innerHTML } return a.escape(String(b)) }; return { renderToString: b, renderToStaticMarkup: b } }), define('core/utils/media/upload', [ 'underscore', 'exports', 'core/api', 'core/models/Media', 'core/UniqueModel' ], function (a, b, c, d, e) { 'use strict'; b.uploadSupported = Boolean(window.FormData), b._extractFirstImageFile = function (b) { return a.find(b, function (a) { return a.type.match(/^image\//) }) }, b._uploadViaApi = function (a, b, d) { return Promise.resolve(c.call(a, { data: b, contentType: !1, processData: !1, method: 'POST', xhr: function () { var a = new window.XMLHttpRequest, b = d && d.onProgress; return b && a.upload.addEventListener('progress', function (a) { a.total && b(100 * a.loaded / a.total) }), a } })) }, b.UPLOAD_URL = 'https://uploads.services.disqus.com/api/3.0/media/create.json', b.uploadMediaUrl = function (c, f) { var g, h = new window.FormData, i = b._extractFirstImageFile(c); return i ? (h.append('upload', i), h.append('permanent', 1), b._uploadViaApi(b.UPLOAD_URL, h, f).then(function (b) { var c = b.response, f = a.first(a.values(c)); if (!f || !f.ok) throw g = new Error('Upload failed'), g.code = f && f['error-code'], g; return new e(d, { mediaType: d.MEDIA_TYPES.IMAGE_UPLOAD, url: f.url, thumbnailUrl: f.url }) }, function (a) { if (a.responseJSON && 4 === a.responseJSON.code) throw g = new Error('Upload failed'), g.code = 'not-authenticated', g; throw a })) : (g = new Error('No image file to upload'), g.code = 'invalid-content-type', Promise.reject(g)) } }), define('core/views/media/DragDropUploadView', [ 'underscore', 'backbone', 'core/utils' ], function (a, b, c) { 'use strict'; var d = c.stopEventHandler, e = b.View.extend({ events: { dragover: '_dragOn', dragenter: '_dragOn', dragleave: '_dragOff', dragexit: '_dragOff', drop: '_drop' }, _dragOn: d(function () { this.trigger('uploader:dragEnter'), this._toggleDragPlaceholder(!0) }), _dragOff: d(function () { this._toggleDragPlaceholder(!1) }), _drop: d(function (a) { this._toggleDragPlaceholder(!1); var b = a.originalEvent.dataTransfer.files; return b.length ? void this.trigger('uploader:attachMedia', b) : void this.trigger('uploader:dropError', 'No files') }), _toggleDragPlaceholder: a.throttle(function (a) { a ? this.trigger('uploader:showPlaceholder') : this.trigger('uploader:hidePlaceholder') }, 50) }); return e }), define('core/templates/postMediaUploadButton', [ 'handlebars', 'core/templates/handlebars.partials', 'core/extensions/handlebars.helpers' ], function (a) { return a.template({ compiler: [ 8, '>= 4.3.0' ], main: function (a, b, c, d, e) { return '\n
    \n\n\n' }, useData: !0 }) }), define('core/views/media/UploadButtonView', [ 'jquery', 'underscore', 'backbone', 'core/templates/postMediaUploadButton', 'core/utils' ], function (a, b, c, d, e) { 'use strict'; var f = e.stopEventHandler, g = 'input[type=file][data-role=media-upload]', h = c.View.extend({ events: function () { var a = { 'click [data-action=attach]': '_attachMedia', 'keydown [data-action=attach]': 'keydownHandler' }; return a['change ' + g] = '_selectorChange', a }(), initialize: function (a) { this.template = a && a.template || this.generateImageUploadButton }, keydownHandler: function (a) { var b = 13, c = 32; a.keyCode !== b && a.keyCode !== c || (a.preventDefault(), this._attachMedia()) }, generateImageUploadButton: function () { return d({ imageUrl: 'https://c.disquscdn.com/next/embed/assets/img/attach.03c320b14aa9c071da30c904d0a0827f.svg' }) }, render: function () { return this.$el.html(this.template()), this }, _attachMedia: f(b.throttle(function () { this.$(g).click() }, 1000, { trailing: !1 })), _selectorChange: function (b) { var c = b.target, d = c.files; d.length && (this.trigger('uploader:attachMedia', d), a(c).replaceWith(c.cloneNode())) } }); return h }), define('core/templates/postMediaUploadProgress', [ 'handlebars', 'core/templates/handlebars.partials', 'core/extensions/handlebars.helpers' ], function (a) { return a.template({ 1: function (a, b, c, d, e) { return '
  • \n
    \n
    \n
    \n
    \n
    \n
  • \n' }, compiler: [ 8, '>= 4.3.0' ], main: function (a, b, c, d, e) { var f; return null != (f = c.each.call(null != b ? b : a.nullContext || { }, null != b ? b.collection : b, { name: 'each', hash: { }, fn: a.program(1, e, 0), inverse: a.noop, data: e, loc: { start: { line: 1, column: 0 }, end: { line: 9, column: 9 } } })) ? f : '' }, useData: !0 }) }), define('core/views/media/UploadsProgressSubView', [ 'backbone', 'core/templates/postMediaUploadProgress' ], function (a, b) { 'use strict'; var c = a.View.extend({ initialize: function () { this.collection = new a.Collection, this.listenTo(this.collection, 'add remove change', this.render) }, hasVisible: function () { return Boolean(this.collection.length) }, render: function () { return this.$el.html(b({ collection: this.collection.toJSON() })), this } }); return c }), define('core/templates/postMediaUploadRich', [ 'handlebars', 'core/templates/handlebars.partials', 'core/extensions/handlebars.helpers' ], function (a) { return a.template({ 1: function (a, b, c, d, e) { return '\n' }, 3: function (a, b, c, d, e) { var f; return '' + (null != (f = c['if'].call(null != b ? b : a.nullContext || {
      }, null != (f = null != b ? b.media : b) ? f.title : f, {
        name: 'if',
        hash: {
        },
        fn: a.program(4, e, 0),
        inverse: a.program(6, e, 0),
        data: e,
        loc: {
          start: {
            line: 9,
            column: 33
          },
          end: {
            line: 9,
            column: 112
          }
        }
      })) ? f : '') + '\n' }, 4: function (a, b, c, d, e) { var f; return a.escapeExpression(a.lambda(null != (f = null != b ? b.media : b) ? f.title : f, b)) }, 6: function (a, b, c, d, e) { return a.escapeExpression(c.gettext.call(null != b ? b : a.nullContext || { }, 'Media attachment', { name: 'gettext', hash: { }, data: e, loc: { start: { line: 9, column: 75 }, end: { line: 9, column: 105 } } })) }, compiler: [ 8, '>= 4.3.0' ], main: function (a, b, c, d, e) { var f; return '
  • \n\n
  • \n' }, useData: !0 }) }), define('core/views/media/UploadsRichSubView', [ 'underscore', 'backbone', 'core/models/Media', 'core/UniqueModel', 'core/utils', 'core/templates/postMediaUploadRich' ], function (a, b, c, d, e, f) { 'use strict'; var g = b.View.extend({ initialize: function () { this._hasVisible = !1, this.collection = new b.Collection([], { model: c, comparator: 'index' }), this.listenTo(this.collection, 'add remove reset sort change:thumbnailUrl change:mediaType change:editsFinished', this.render), this.listenTo(this.collection, 'change:index', a.bind(this.collection.sort, this.collection)) }, render: function () { return this.$el.empty(), this._hasVisible = !1, this.collection.each(function (b) { b.get('thumbnailUrl') && (a.contains(c.WEBPAGE_TYPES, b.get('mediaType')) || b.get('editsFinished') && (this.$el.append(f({ media: b.toJSON(), isVideo: this.isVideo(b), thumbnailUrl: b.get('thumbnailUrl') })), this._hasVisible = !0)) }, this), this }, isVideo: function (a) { return a.get('mediaType') === c.MEDIA_TYPES.MP4_VIDEO }, hasVisible: function () { return this._hasVisible }, addMedia: function (a, b) { var e = d.get(c, a.url); if (e) e.set(a); else { if (!a.editsFinished) return; e = new d(c, a), e.fetch(b) } return this.collection.add(e), e }, updateFromText: function (b, c, d) { if (!b) return void this.collection.reset(); var f = e.bleachFindUrls(b); f = a.uniq(f, !1, function (a) { return a.url }); var g = { }; a.each(f, function (e) { g[e.url] = !0; var f = a.pick(e, 'index', 'url'), h = e.index < c && c <= e.endIndex || '.' === b[e.endIndex]; h && !d.isPasteEvent || (f.editsFinished = !0), this.addMedia(f, d) }, this); var h = this.collection.pluck('url'); g = a.keys(g); var i = a.difference(h, g); this.collection.remove(this.collection.filter(function (b) { return a.contains(i, b.get('url')) })) } }); return g }), define('core/templates/postMediaUploads', [ 'handlebars', 'core/templates/handlebars.partials', 'core/extensions/handlebars.helpers' ], function (a) { return a.template({ compiler: [ 8, '>= 4.3.0' ], main: function (a, b, c, d, e) { return '\n\n
    \n' + a.escapeExpression(c.gettext.call(null != b ? b : a.nullContext || {
      }, 'Media preview placeholder', {
        name: 'gettext',
        hash: {
        },
        data: e,
        loc: {
          start: {
            line: 6,
            column: 46
          },
          end: {
            line: 6,
            column: 85
          }
        }
      })) + '\n
    \n' }, useData: !0 }) }), define('core/views/media/UploadsView', [ 'backbone', 'core/views/media/UploadsProgressSubView', 'core/views/media/UploadsRichSubView', 'core/templates/postMediaUploads' ], function (a, b, c, d) { 'use strict'; var e = a.View.extend({ initialize: function () { this.richView = new c, this.rich = this.richView.collection, this.uploadProgressView = new b, this.uploadProgress = this.uploadProgressView.collection, this.listenTo(this.rich, 'all', this._updateEmpty), this.listenTo(this.uploadProgress, 'all', this._updateEmpty) }, render: function () { return this.richView.$el.detach(), this.uploadProgressView.$el.detach(), this.$el.html(d()), this._updateEmpty(), this.richView.setElement(this.$('[data-role=media-rich-list]') [0]), this.uploadProgressView.setElement(this.$('[data-role=media-progress-list]') [0]), this }, clear: function () { this.rich.reset(), this.uploadProgress.reset() }, _updateEmpty: function () { this.richView.hasVisible() || this.uploadProgressView.hasVisible() ? this.$el.removeClass('empty') : this.$el.addClass('empty') } }); return e }), define('core/mixins/withUploadForm', [ 'underscore', 'backbone', 'core/strings', 'core/utils', 'core/utils/media/upload', 'core/utils/storage', 'core/views/media/DragDropUploadView', 'core/views/media/UploadButtonView', 'core/views/media/UploadsView' ], function (a, b, c, d, e, f, g, h, i) { 'use strict'; var j = c.get, k = function () { a.defaults(this, k.bothProto, k.uploadsProto, k.previewsProto) }, l = { 'invalid-image-file': j('Unfortunately your image upload failed. Please verify that the file is valid and in a supported format (JPEG, PNG, or GIF).'), 'invalid-content-type': j('Unfortunately your image upload failed. Please verify that the file is in a supported format (JPEG, PNG, or GIF).'), 'file-too-large': j('Unfortunately your image upload failed. Please verify that your image is under 5MB.'), 'not-authenticated': j('You must be logged in to upload an image.') }, m = j('Unfortunately your image upload failed. Please verify that your image is in a supported format (JPEG, PNG, or GIF) and under 5MB. If you continue seeing this error, please try again later.'); return k.previewsProto = { initMediaPreviews: function (b, c) { this.mediaUploadsView = new i({ el: b[0] }), this.mediaUploadsView.render(), this.updateLiveMediaDebounced = a.partial(a.debounce(this.updateLiveMedia, 500), c, !1), this.stopListening(c, 'keychange'), this.stopListening(c, 'paste'), this.listenTo(c, { keychange: this.updateLiveMediaDebounced, paste: function (b, d) { d && d.fake || a.defer(a.bind(this.updateLiveMedia, this, c, !0)) } }), this.updateLiveMedia(c, !0) }, clearMediaPreviews: function () { this.mediaUploadsView && this.mediaUploadsView.clear() }, updateLiveMedia: function (a, b) { if (this.mediaUploadsView) { var c = a.get(), d = a.offset(); this.mediaUploadsView.richView.updateFromText(c, d, { isPasteEvent: b, forum: this.thread.forum.id }) } } }, k.uploadsProto = { initMediaUploads: function (a, b, c) { this.mediaDragDropView && this.stopListening(this.mediaDragDropView), this.mediaDragDropView = new g({ el: b[0] }), this.listenTo(this.mediaDragDropView, { 'uploader:attachMedia': function () { f.set('usedDragDrop', 1), this.handleAttachMedia.apply(this, arguments) }, 'uploader:dragEnter': function () { this.$el.addClass('expanded') }, 'uploader:showPlaceholder': function () { a.show() }, 'uploader:hidePlaceholder': function () { a.hide() }, 'uploader:dropError': function () { var a = j('Sorry we didn\'t catch that. Try again?'); this.alert(a, { type: 'error', isUploadError: !0 }) } }), this.mediaUploadButtonView && this.stopListening(this.mediaUploadButtonView), this.mediaUploadButtonView = new h({ el: c[0] }), this.listenTo(this.mediaUploadButtonView, { 'uploader:attachMedia': this.handleUploadViaButton }), this.mediaUploadButtonView.render() }, handleUploadViaButton: function (a) { if (a && f.isPersistent && !f.get('usedDragDrop') && !d.isMobileUserAgent()) { var b = this.alert(j('Did you know you can drag and drop images too? Try it now!')); this.listenToOnce(b, 'dismiss', function () { f.set('usedDragDrop', 1) }) } this.handleAttachMedia.apply(this, arguments) }, handleAttachMedia: function (c, d) { var f = this, g = new b.Model({ remainingPerc: 100 }); f.mediaUploadsView.uploadProgress.add(g), d = a.extend(d || { }, { onProgress: function (a) { g.set('remainingPerc', 100 - a) } }); var h = function () { f.mediaUploadsView.uploadProgress.remove(g) }; e.uploadMediaUrl(c, d).then(function (a) { a.fetch({ forum: f.thread.forum.id }), f.textarea.insertAtCursor(a.get('url')), f.updateLiveMedia(f.textarea, !0), f.dismissUploadError() }) ['catch'](function (a) { var b; a && a.code && (b = l[a.code]), b || (b = m), f.alert(b, { type: 'error', isUploadError: !0 }) }).then(h, h) }, dismissUploadError: function () { this.dismissAlert(function (a) { return a.options && a.options.isUploadError }) }, uploadSupported: e.uploadSupported, isUploadInProgress: function () { return this.mediaUploadsView && this.mediaUploadsView.uploadProgress.length } }, k.bothProto = { initMediaViews: function (a) { (a.mediaembedEnabled || a.gifPickerEnabled) && this.initMediaPreviews(this.$('[data-role=media-preview]'), a.textarea), a.allowUploads && this.initMediaUploads(this.$('[data-role=drag-drop-placeholder]'), this.$('[data-role=textarea]'), this.$('[data-role=media-uploader]')) } }, k }), define('core/editable', [ ], function () { 'use strict'; function a(a) { return a.replace(e, ' ') } function b(c, d, e) { var f, h, i, j, k = '', l = [ ]; for ('string' != typeof e && (e = '\n\n'), j = 0; j < c.length; ++j) h = c[j], f = h.nodeName.toLowerCase(), 1 === h.nodeType ? (i = d && d(h), i ? k += i : g.hasOwnProperty(f) ? (k && l.push(k), k = b(h.childNodes, d, e)) : k += 'br' === f ? '\n' : b(h.childNodes, d, e)) : 3 === h.nodeType && (k += a(h.nodeValue)); return l.push(k), l.join(e) } var c = window.document, d = 'character', e = new RegExp(String.fromCharCode(160), 'gi'), f = 'h1 h2 h3 h4 h5 h6 p pre blockquote address ul ol dir menu li dl div form'.split(' '), g = { }, h = 0; for (h = 0; h < f.length; h++) g[f[h]] = !0; var i = function (a, b, c) { var d = this; if (!a || !a.contentEditable) throw new Error('First argument must be contentEditable'); this.elem = a, this.emulateTextarea = a.getAttribute('plaintext-only') || b, this.emulateTextarea && (this.pasteHandler = function (a) { var b = a && a.clipboardData || window.clipboardData; b && !b.getData('text') && (a.preventDefault(), a.stopPropagation()); var c = d.plainTextReformat, e = function () { c.timeout = null, c.call(d) }; c.timeout && clearTimeout(c.timeout), c.timeout = setTimeout(e, 0) }, a.addEventListener('paste', this.pasteHandler)); for (var e in c) c.hasOwnProperty(e) && (this[e] = c[e]) }; return i.prototype = { insertHTML: function (a) { if (c.all) { var b = c.selection.createRange(); return b.pasteHTML(a), b.collapse(!1), b.select() } return c.execCommand('insertHTML', !1, a) }, insertNode: function (a) { var b, d, e; window.getSelection ? (b = window.getSelection(), b.getRangeAt && b.rangeCount && (d = b.getRangeAt(0), d.deleteContents(), d.insertNode(a), d.collapse(!1), b.removeAllRanges(), b.addRange(d))) : c.selection && c.selection.createRange && (d = c.selection.createRange(), e = 3 === a.nodeType ? a.data : a.outerHTML, d.pasteHTML(e), d.collapse(!1)) }, getTextNodes: function (a) { var b = this.elem; a && a.nodeType ? a = [ a ] : a || (a = b.childNodes); for (var c, d = [ ], e = 0; e < a.length; ++e) if (c = a[e]) switch (c.nodeType) { case 1: d = d.concat(this.getTextNodes(c.childNodes)); break; case 3: /^\n\s+/.test(c.nodeValue) || d.push(c) } return d }, text: function (a) { var c, d, e, f = this.elem; try { d = Array.prototype.slice.call(f.childNodes) } catch (g) { for (d = [ ], e = 0; e < f.childNodes.length; ++e) d.push(f.childNodes[e]) } return c = b(d, a, this.emulateTextarea && '\n'), c.replace(/^\s+|\s+$/g, '') }, setText: function (a) { a = a || ''; var b, d, e, f = c.createDocumentFragment(), g = [ a ], h = g && g.length; for (b = 0; b < h; b++) d = g[b], e = this.createParagraph(d), f.appendChild(e); if (f.lastChild.appendChild(c.createElement('br')), this.elem.innerHTML = '', this.elem.appendChild(f), 'WebkitAppearance' in c.documentElement.style && window.navigator.userAgent.indexOf('Firefox') === - 1 && window.navigator.userAgent.indexOf('MSIE') === - 1) { var i = window.getSelection && window.getSelection(); i && i.anchorNode === this.elem && i.modify && i.modify('move', 'forward', 'line') } }, createParagraph: function (a) { var b, d, e, f, g, h, i, j = c.createElement('p'); for (e = a.split(/\r\n|\r|\n/), d = 0, g = e.length; d < g; d++) { for (f = e[d], i = this.getHtmlElements(f), b = 0, h = i.length; b < h; b++) j.appendChild(i[b]); j.appendChild(c.createElement('br')) } return j.lastChild && j.removeChild(j.lastChild), j }, getHtmlElements: function (a) { return [c.createTextNode(a)] }, plainTextReformat: function () { if (!(this.elem.getElementsByTagName('p').length <= 1)) { this.emulateTextarea = !1; var a = this.text(); this.emulateTextarea = !0, this.setText(a) } }, removeNode: function (a) { var b, d, e; window.getSelection ? (b = a.previousSibling, a.parentNode.removeChild(a), d = window.getSelection(), e = c.createRange(), b && (e.setStart(b, b.length), e.setEnd(b, b.length)), d.addRange(e)) : a.parentNode.removeChild(a) }, selectedTextNode: function () { var b, e, f, g, h, i, j, k, l, m = this.elem; if (window.getSelection) return b = window.getSelection(), b.anchorNode; if (c.selection.createRange) { for (e = c.selection.createRange().duplicate(); e.moveStart(d, - 1000) === - 1000; ); var n = e.text; for (k = 0; k < m.childNodes.length; ++k) for (f = m.childNodes[k], h = this.getTextNodes(f), l = 0; l < h.length; ++l) if (g = h[l], j = a(g.nodeValue), n.indexOf(j) > - 1) i = g, n = n.replace(j, ''); else if (j.indexOf(n) > - 1) return g; return i } }, selectedTextNodeOffset: function (b) { var e, f, g; if (window.getSelection) { var h = window.getSelection(); h && h.anchorOffset && (g = h.anchorOffset) } else if (b && c.selection.createRange) { var i = a(b.nodeValue); e = c.selection.createRange(); var j = e.duplicate(), k = j.parentElement(); for (f = 0; 0 !== e.moveStart(d, - 1) && (0 !== i.indexOf(a(e.text)) && k === e.parentElement()); f++) j = e.duplicate(), k = j.parentElement(); g = f } return isNaN(g) ? 0 : g }, offset: function () { function b(d, e) { function f(a) { i += a[0]; for (var b = 1; b < a.length; ++b) h.push(i), i = a[b] } 'string' != typeof e && (e = '\n\n'); for (var h = [ ], i = '', j = 0; j < d.length; ++j) { var k = d[j], l = k.nodeName.toLowerCase(); 1 === k.nodeType ? g.hasOwnProperty(l) ? (i && (i += e), f(b(k.childNodes, e))) : 'br' === l ? i += '\n' : f(b(k.childNodes, e)) : 3 === k.nodeType && (k === c.anchorNode ? (i += a(k.nodeValue.slice(0, c.anchorOffset)), h.push(i), i = a(k.nodeValue.slice(c.anchorOffset))) : i += a(k.nodeValue)) } return h.push(i), h } var c = window.getSelection(); if (!c || !c.anchorNode || 3 !== c.anchorNode.nodeType) return 0; var d, e = this.elem; try { d = Array.prototype.slice.call(e.childNodes) } catch (f) { d = [ ]; for (var h = 0; h < e.childNodes.length; ++h) d.push(e.childNodes[h]) } var i = b(d, this.emulateTextarea && '\n'); if (1 === i.length) return 0; var j = i[0].length, k = i.join(''), l = k.match(/\s+$/); if (l) { var m = l[0].length; j = Math.min(j, k.length - m) } var n = k.match(/^\s+/); if (n) { var o = n[0].length; j -= o } return j }, selectNodeText: function (b, e, f) { var g, h, i = this.elem; if (window.getSelection) return g = window.getSelection(), g.removeAllRanges(), h = c.createRange(), h.setStart(b, e), h.setEnd(b, f), g.addRange(h), g; if (c.selection.createRange) { h = c.selection.createRange(); var j = a(b.nodeValue); if ('body' === h.parentElement().nodeName.toLowerCase()) { for (i.focus(), h = c.selection.createRange(); h.moveStart(d, - 1000) === - 1000; ); for (; 1000 === h.moveEnd(d, 1000); ); var k = a(h.text), l = k.indexOf(j); l > 0 && h.moveStart(d, l + 2), h.collapse() } for (; h.moveStart(d, - 1) === - 1 && 0 !== j.indexOf(a(h.text)); ); for (; 1 === h.moveEnd(d, 1) && j !== a(h.text); ); return h.moveStart(d, e), h.moveEnd(d, - 1 * (f - e - h.text.length)), h.select(), h } } }, i.normalizeSpace = a, i }), define('core/utils/html/nodeTypes', [ ], function () { 'use strict'; var a = function (a) { return 'p' === a.nodeName.toLowerCase() }, b = function (a) { return 'div' === a.nodeName.toLowerCase() }, c = function (a) { return '#text' === a.nodeName.toLowerCase() }, d = function (a) { return 'br' === a.nodeName.toLowerCase() }, e = function (a) { return 'button' === a.nodeName.toLowerCase() }, f = function (a) { return 'br' === a.nodeName.toLowerCase() || '#text' === a.nodeName.toLowerCase() && '\n' === a.nodeValue }, g = function (a) { return 'p' === a.nodeName.toLowerCase() || 'div' === a.nodeName.toLowerCase() }, h = function (a) { return 'span' === a.nodeName.toLowerCase() }; return { isP: a, isDiv: b, isText: c, isBr: d, isButton: e, isNewline: f, isPorDiv: g, isSpan: h } }), define('core/CappedStorage', [ 'core/utils/storage' ], function (a) { 'use strict'; var b = function (a, b) { this.max = a || 10, this.queueKey = b || '__queue', this.getQueue() || this.setQueue([]) }; return b.prototype.set = function (b, c) { var d = this.getQueue() || this.setQueue([]); d.length === this.max && a.remove(d.shift()), a.set(b, c), d.push(b), this.setQueue(d) }, b.prototype.get = function (b) { return a.get(b) }, b.prototype.remove = function (b) { a.remove(b); for (var c = this.getQueue() || [ ], d = 0; d < c.length; d++) if (c[d] === b) { c.splice(d, 1); break } this.setQueue(c) }, b.prototype.clear = function () { a.clear(), this.setQueue([]) }, b.prototype.getQueue = function () { return a.get(this.queueKey) }, b.prototype.setQueue = function (b) { return a.set(this.queueKey, b), b }, b }), define('core/extensions/jquery.autoresize', [ 'jquery', 'underscore' ], function (a, b) { 'use strict'; return a.fn.autoresize = function (c) { var d = b.extend({ extraSpace: 0, maxHeight: 1000 }, c); return this.each(function () { var c = a(this).css({ resize: 'none', overflow: 'hidden' }), e = 'true' === String(c[0].contentEditable) ? 'html' : 'val', f = 'html' === e ? '
    ' : '\n', g = c.height(), h = function () { var d = { }; b.each(d, function (a, b) { d[b] = c.css(b) }); var e = a(c[0].cloneNode(!0)); return e.removeAttr('id').removeAttr('name').css({ visibility: 'hidden', position: 'absolute', top: '-9999px', left: '-9999px', contentEditable: !1 }).css(d).attr('tabIndex', '-1'), e.insertAfter(c[0]), e }(), i = null, j = function () { h[0].style.height = 0, h[e](c[e]() + f), h.scrollTop(h[0].scrollHeight); var a = Math.max(h[0].scrollHeight, g) + parseInt(d.extraSpace, 10); d.maxHeight && (a >= d.maxHeight ? (c.css('overflow', ''), a = d.maxHeight) : c.css('overflow', 'hidden')), i !== a && (i = a, c.height(a), c.trigger && c.trigger('resize')) }, k = b.throttle(j, 500), l = function (a) { 13 === a.keyCode ? j() : k() }; c.bind('keyup', l).bind('paste', j).css('overflow', 'hidden'), j() }) }, a }), define('core/views/TextareaView', [ 'underscore', 'jquery', 'backbone', 'core/utils', 'core/utils/html/nodeTypes', 'core/CappedStorage', 'core/extensions/jquery.autoresize' ], function (a, b, c, d, e, f) { 'use strict'; var g = c.View.extend({ events: { 'keydown [data-role=editable]': 'handleKeyDown', 'keyup [data-role=editable]': 'handleKeyUp', 'paste [data-role=editable]': 'handlePaste', 'focusin [data-role=editable]': 'handleFocusIn', 'blur [data-role=editable]': 'handleBlur' }, initialize: function (b) { b = b || { }, this.storageKey = b.storageKey, this.value = b.value || this.getDraft() [0], this.history = [ this.value ], this.historyPosition = 0, this.placeholder = b.placeholder, this.selectionIndices = { start: 0, end: 0, endElemInd: 0, endElemSelectionInd: 0, startElemInd: 0, startElemSelectionInd: 0 }, this.inputFixed = !1, this.listenTo(this, 'keychange', a.debounce(this.saveDraft, this.constructor.SAVE_DRAFT_INTERVAL)) }, render: function () { return this.$input = this.createInput(), this.set(this.value), this.$el.append(this.$input), this.$input.autoresize({ maxHeight: this.constructor.MAX_TEXTAREA_HEIGHT }), this }, createInput: function () { return b('