Skip to content

Instantly share code, notes, and snippets.

@jermspeaks
Forked from anonymous/1fg3js.js
Last active September 21, 2017 18:40
Show Gist options
  • Save jermspeaks/1ff3a70e8ea95bf0ccf7b3116e8d2cd0 to your computer and use it in GitHub Desktop.
Save jermspeaks/1ff3a70e8ea95bf0ccf7b3116e8d2cd0 to your computer and use it in GitHub Desktop.
var IV = (function(SCOPE) {
SCOPE.baseData = {};
SCOPE.baseData.app_data = {
"isPreroll": true,
"video": {
"url": "",
"width": 1920,
"height": 1080,
"duration": 15.061,
"renditions": {
"webm": "https:\/\/s-static.innovid.com\/media\/encoded\/08_17\/92805\/3_source_44961_127247.webm",
"low.mp4": "https:\/\/s-static.innovid.com\/media\/encoded\/08_17\/92805\/5_source_44961_127247.mp4",
"high.mp4": "https:\/\/s-static.innovid.com\/media\/encoded\/08_17\/92805\/8_source_44961_127247.mp4",
"iphone_stream": "https:\/\/s-static.innovid.com\/media\/encoded\/08_17\/92805\/27_source_44961_127247.m3u8",
"short_segment_iphone_stream": "https:\/\/s-static.innovid.com\/media\/encoded\/08_17\/92805\/29_source_44961_127247.m3u8"
}
},
"video-clicks": {
"click-thru-url": "https:\/\/ad.doubleclick.net\/ddm\/clk\/403893800;204149384;f"
},
"placement-config": {
"hotspot-clicks": [{
"id": "main",
"type": "click-thru",
"main": "https:\/\/ad.doubleclick.net\/ddm\/clk\/403893800;204149384;f"
}],
"placement-hash": "1fg3js",
"project-hash": "1hl7gi",
"client-id": 1585,
"channel-id": 587053,
"publisher-id": 689,
"advertiser-id": 313,
"placements-group-id": 602149,
"campaign-id": 44961,
"video-id": 228793,
"placement-tag-id": 0,
"project-state": 2,
"child-manual-project-state": 9,
"child-auto-project-state": 11,
"real_estate_id": 241796,
"survey-data": null,
"tracking-events": {
"playingStart": [{
"type": "url-tracking",
"data": "https:\/\/ad.doubleclick.net\/ddm\/ad\/N8667.280727.NEWSDISTRIBUTIONNET\/B20248118.204149384;sz=1x1;ord=[timestamp];dc_lat=;dc_rdid=;tag_for_child_directed_treatment=?"
}, {
"type": "url-tracking",
"data": "https:\/\/dts.innovid.com\/placement\/1fg3js\/uuid?cb=[timestamp]"
}]
}
},
"error-monitoring-enabled": false,
"service-config": {
"dv": {
"blocking": true,
"clientId": 971108,
"timeout": 600,
"useRealBlocking": true
}
}
};
SCOPE.baseData.config_data = {
"iconSizes": [24, 32, 48, 64, 128],
"previewParam": {
"width": 500,
"height": 281,
"iconSize": 32,
"trayMargin": 1.05
},
"platformScaling": {
"mobile": 1,
"tablet": 1,
"desktop": 1,
"tv": 2
},
"aspectRatio": 1.3,
"googleMapsApiKey": "AIzaSyAIvRFdH46ZxXWyLgE3_OjsL61tjxCDtS4",
"moat": {
"disableFlash": 0,
"partnerCode": "innovidintvpaid2js125985325015"
},
"dv": {
"url": "https:\/\/cdn.doubleverify.com\/dvvid_src.js?ctx=<%= ctx %>&cmp=<%= cmp %>&sid=<%= sid %>&crt=1&plc=<%= plc %>&adsrv=118&tagformat=2&tagtype=video&dvtagver=6.1.src&DVP_GVACB=<%= cb %>",
"blocking-url": "https:\/\/cdn.doubleverify.com\/dvbs_src.js?ctx=<%= ctx %>&cmp=<%= cmp %>&sid=<%= sid %>&crt=1&plc=<%= plc %>&adsrv=118&tagformat=2&tagtype=video&dvtagver=6.1.src&adid=<%= cb %>&DVP_DCB=<%= bcb %>"
},
"comscore": {
"partnerId": "Innovid"
},
"nielsen_dbe": {
"survey_url": "secure-gl.imrworldwide.com\/u\/t\/00\/02\/86\/21\/video_tag.html?ca={survey-id}&cr={iv_creativeid}&ce={iv_publisherid}&pc={iv_placementid}&wc=wc1&am=52&tt=5&view=300x300&show={show}&mode=s&width={player-width}&height={player-height}&bgcolor=000000&uuid={sessionid}"
}
};
SCOPE.baseData.cssPath = 'https://s-static.innovid.com/mobileapps/s/js/vpaid/1fg3js.css?cb=4.6.2939&secured=1';
SCOPE.baseData.config_data.mode = 'js';
SCOPE.baseData.targetElement = 'div#content';
SCOPE.baseData.appPath = 'https://s-cdn.innovid.com/m/';
SCOPE.baseData.servicePath = 'https://s-c-service.innovid.com';
SCOPE.baseData.nonCdnServicePath = 'https://service.innovid.com';
SCOPE.baseData.reportUrl = 'https://s.innovid.com/1x1.gif';
SCOPE.baseData.errorReportUrl = 'https://s3.amazonaws.com/innovid-iroll-runtime/1x1.gif';
SCOPE.baseData.runtimeConfigUrl = 'https://s-static.innovid.com/runtime/iroll-runtime-config.js';
SCOPE.baseData.mobileCoreVersion = '4.6.2939';
return SCOPE;
})(IV || {});
/* Zepto v1.1.4 - zepto event ajax form ie - zeptojs.com/license */
var Zepto = function() {
function L(t) {
return null == t ? String(t) : j[S.call(t)] || "object"
}
function Z(t) {
return "function" == L(t)
}
function $(t) {
return null != t && t == t.window
}
function _(t) {
return null != t && t.nodeType == t.DOCUMENT_NODE
}
function D(t) {
return "object" == L(t)
}
function R(t) {
return D(t) && !$(t) && Object.getPrototypeOf(t) == Object.prototype
}
function M(t) {
return "number" == typeof t.length
}
function k(t) {
return s.call(t, function(t) {
return null != t
})
}
function z(t) {
return t.length > 0 ? n.fn.concat.apply([], t) : t
}
function F(t) {
return t.replace(/::/g, "/").replace(/([A-Z]+)([A-Z][a-z])/g, "$1_$2").replace(/([a-z\d])([A-Z])/g, "$1_$2").replace(/_/g, "-").toLowerCase()
}
function q(t) {
return t in f ? f[t] : f[t] = new RegExp("(^|\\s)" + t + "(\\s|$)")
}
function H(t, e) {
return "number" != typeof e || c[F(t)] ? e : e + "px"
}
function I(t) {
var e, n;
return u[t] || (e = a.createElement(t), a.body.appendChild(e), n = getComputedStyle(e, "").getPropertyValue("display"), e.parentNode.removeChild(e), "none" == n && (n = "block"), u[t] = n), u[t]
}
function V(t) {
return "children" in t ? o.call(t.children) : n.map(t.childNodes, function(t) {
return 1 == t.nodeType ? t : void 0
})
}
function B(n, i, r) {
for (e in i) r && (R(i[e]) || A(i[e])) ? (R(i[e]) && !R(n[e]) && (n[e] = {}), A(i[e]) && !A(n[e]) && (n[e] = []), B(n[e], i[e], r)) : i[e] !== t && (n[e] = i[e])
}
function U(t, e) {
return null == e ? n(t) : n(t).filter(e)
}
function J(t, e, n, i) {
return Z(e) ? e.call(t, n, i) : e
}
function X(t, e, n) {
null == n ? t.removeAttribute(e) : t.setAttribute(e, n)
}
function W(e, n) {
var i = e.className,
r = i && i.baseVal !== t;
return n === t ? r ? i.baseVal : i : void(r ? i.baseVal = n : e.className = n)
}
function Y(t) {
var e;
try {
return t ? "true" == t || ("false" == t ? !1 : "null" == t ? null : /^0/.test(t) || isNaN(e = Number(t)) ? /^[\[\{]/.test(t) ? n.parseJSON(t) : t : e) : t
} catch (i) {
return t
}
}
function G(t, e) {
e(t);
for (var n = 0, i = t.childNodes.length; i > n; n++) G(t.childNodes[n], e)
}
var t, e, n, i, C, N, r = [],
o = r.slice,
s = r.filter,
a = window.document,
u = {},
f = {},
c = {
"column-count": 1,
columns: 1,
"font-weight": 1,
"line-height": 1,
opacity: 1,
"z-index": 1,
zoom: 1
},
l = /^\s*<(\w+|!)[^>]*>/,
h = /^<(\w+)\s*\/?>(?:<\/\1>|)$/,
p = /<(?!area|br|col|embed|hr|img|input|link|meta|param)(([\w:]+)[^>]*)\/>/gi,
d = /^(?:body|html)$/i,
m = /([A-Z])/g,
g = ["val", "css", "html", "text", "data", "width", "height", "offset"],
v = ["after", "prepend", "before", "append"],
y = a.createElement("table"),
x = a.createElement("tr"),
b = {
tr: a.createElement("tbody"),
tbody: y,
thead: y,
tfoot: y,
td: x,
th: x,
"*": a.createElement("div")
},
w = /complete|loaded|interactive/,
E = /^[\w-]*$/,
j = {},
S = j.toString,
T = {},
O = a.createElement("div"),
P = {
tabindex: "tabIndex",
readonly: "readOnly",
"for": "htmlFor",
"class": "className",
maxlength: "maxLength",
cellspacing: "cellSpacing",
cellpadding: "cellPadding",
rowspan: "rowSpan",
colspan: "colSpan",
usemap: "useMap",
frameborder: "frameBorder",
contenteditable: "contentEditable"
},
A = Array.isArray || function(t) {
return t instanceof Array
};
return T.matches = function(t, e) {
if (!e || !t || 1 !== t.nodeType) return !1;
var n = t.webkitMatchesSelector || t.mozMatchesSelector || t.oMatchesSelector || t.matchesSelector;
if (n) return n.call(t, e);
var i, r = t.parentNode,
o = !r;
return o && (r = O).appendChild(t), i = ~T.qsa(r, e).indexOf(t), o && O.removeChild(t), i
}, C = function(t) {
return t.replace(/-+(.)?/g, function(t, e) {
return e ? e.toUpperCase() : ""
})
}, N = function(t) {
return s.call(t, function(e, n) {
return t.indexOf(e) == n
})
}, T.fragment = function(e, i, r) {
var s, u, f;
return h.test(e) && (s = n(a.createElement(RegExp.$1))), s || (e.replace && (e = e.replace(p, "<$1></$2>")), i === t && (i = l.test(e) && RegExp.$1), i in b || (i = "*"), f = b[i], f.innerHTML = "" + e, s = n.each(o.call(f.childNodes), function() {
f.removeChild(this)
})), R(r) && (u = n(s), n.each(r, function(t, e) {
g.indexOf(t) > -1 ? u[t](e) : u.attr(t, e)
})), s
}, T.Z = function(t, e) {
return t = t || [], t.__proto__ = n.fn, t.selector = e || "", t
}, T.isZ = function(t) {
return t instanceof T.Z
}, T.init = function(e, i) {
var r;
if (!e) return T.Z();
if ("string" == typeof e)
if (e = e.trim(), "<" == e[0] && l.test(e)) r = T.fragment(e, RegExp.$1, i), e = null;
else {
if (i !== t) return n(i).find(e);
r = T.qsa(a, e)
} else {
if (Z(e)) return n(a).ready(e);
if (T.isZ(e)) return e;
if (A(e)) r = k(e);
else if (D(e)) r = [e], e = null;
else if (l.test(e)) r = T.fragment(e.trim(), RegExp.$1, i), e = null;
else {
if (i !== t) return n(i).find(e);
r = T.qsa(a, e)
}
}
return T.Z(r, e)
}, n = function(t, e) {
return T.init(t, e)
}, n.extend = function(t) {
var e, n = o.call(arguments, 1);
return "boolean" == typeof t && (e = t, t = n.shift()), n.forEach(function(n) {
B(t, n, e)
}), t
}, T.qsa = function(t, e) {
var n, i = "#" == e[0],
r = !i && "." == e[0],
s = i || r ? e.slice(1) : e,
a = E.test(s);
return _(t) && a && i ? (n = t.getElementById(s)) ? [n] : [] : 1 !== t.nodeType && 9 !== t.nodeType ? [] : o.call(a && !i ? r ? t.getElementsByClassName(s) : t.getElementsByTagName(e) : t.querySelectorAll(e))
}, n.contains = a.documentElement.contains ? function(t, e) {
return t !== e && t.contains(e)
} : function(t, e) {
for (; e && (e = e.parentNode);)
if (e === t) return !0;
return !1
}, n.type = L, n.isFunction = Z, n.isWindow = $, n.isArray = A, n.isPlainObject = R, n.isEmptyObject = function(t) {
var e;
for (e in t) return !1;
return !0
}, n.inArray = function(t, e, n) {
return r.indexOf.call(e, t, n)
}, n.camelCase = C, n.trim = function(t) {
return null == t ? "" : String.prototype.trim.call(t)
}, n.uuid = 0, n.support = {}, n.expr = {}, n.map = function(t, e) {
var n, r, o, i = [];
if (M(t))
for (r = 0; r < t.length; r++) n = e(t[r], r), null != n && i.push(n);
else
for (o in t) n = e(t[o], o), null != n && i.push(n);
return z(i)
}, n.each = function(t, e) {
var n, i;
if (M(t)) {
for (n = 0; n < t.length; n++)
if (e.call(t[n], n, t[n]) === !1) return t
} else
for (i in t)
if (e.call(t[i], i, t[i]) === !1) return t; return t
}, n.grep = function(t, e) {
return s.call(t, e)
}, window.JSON && (n.parseJSON = JSON.parse), n.each("Boolean Number String Function Array Date RegExp Object Error".split(" "), function(t, e) {
j["[object " + e + "]"] = e.toLowerCase()
}), n.fn = {
forEach: r.forEach,
reduce: r.reduce,
push: r.push,
sort: r.sort,
indexOf: r.indexOf,
concat: r.concat,
map: function(t) {
return n(n.map(this, function(e, n) {
return t.call(e, n, e)
}))
},
slice: function() {
return n(o.apply(this, arguments))
},
ready: function(t) {
return w.test(a.readyState) && a.body ? t(n) : a.addEventListener("DOMContentLoaded", function() {
t(n)
}, !1), this
},
get: function(e) {
return e === t ? o.call(this) : this[e >= 0 ? e : e + this.length]
},
toArray: function() {
return this.get()
},
size: function() {
return this.length
},
remove: function() {
return this.each(function() {
null != this.parentNode && this.parentNode.removeChild(this)
})
},
each: function(t) {
return r.every.call(this, function(e, n) {
return t.call(e, n, e) !== !1
}), this
},
filter: function(t) {
return Z(t) ? this.not(this.not(t)) : n(s.call(this, function(e) {
return T.matches(e, t)
}))
},
add: function(t, e) {
return n(N(this.concat(n(t, e))))
},
is: function(t) {
return this.length > 0 && T.matches(this[0], t)
},
not: function(e) {
var i = [];
if (Z(e) && e.call !== t) this.each(function(t) {
e.call(this, t) || i.push(this)
});
else {
var r = "string" == typeof e ? this.filter(e) : M(e) && Z(e.item) ? o.call(e) : n(e);
this.forEach(function(t) {
r.indexOf(t) < 0 && i.push(t)
})
}
return n(i)
},
has: function(t) {
return this.filter(function() {
return D(t) ? n.contains(this, t) : n(this).find(t).size()
})
},
eq: function(t) {
return -1 === t ? this.slice(t) : this.slice(t, +t + 1)
},
first: function() {
var t = this[0];
return t && !D(t) ? t : n(t)
},
last: function() {
var t = this[this.length - 1];
return t && !D(t) ? t : n(t)
},
find: function(t) {
var e, i = this;
return e = t ? "object" == typeof t ? n(t).filter(function() {
var t = this;
return r.some.call(i, function(e) {
return n.contains(e, t)
})
}) : 1 == this.length ? n(T.qsa(this[0], t)) : this.map(function() {
return T.qsa(this, t)
}) : []
},
closest: function(t, e) {
var i = this[0],
r = !1;
for ("object" == typeof t && (r = n(t)); i && !(r ? r.indexOf(i) >= 0 : T.matches(i, t));) i = i !== e && !_(i) && i.parentNode;
return n(i)
},
parents: function(t) {
for (var e = [], i = this; i.length > 0;) i = n.map(i, function(t) {
return (t = t.parentNode) && !_(t) && e.indexOf(t) < 0 ? (e.push(t), t) : void 0
});
return U(e, t)
},
parent: function(t) {
return U(N(this.pluck("parentNode")), t)
},
children: function(t) {
return U(this.map(function() {
return V(this)
}), t)
},
contents: function() {
return this.map(function() {
return o.call(this.childNodes)
})
},
siblings: function(t) {
return U(this.map(function(t, e) {
return s.call(V(e.parentNode), function(t) {
return t !== e
})
}), t)
},
empty: function() {
return this.each(function() {
this.innerHTML = ""
})
},
pluck: function(t) {
return n.map(this, function(e) {
return e[t]
})
},
show: function() {
return this.each(function() {
"none" == this.style.display && (this.style.display = ""), "none" == (getComputedStyle(this, "") ? getComputedStyle(this, "").getPropertyValue("display") : "") && (this.style.display = I(this.nodeName))
})
},
replaceWith: function(t) {
return this.before(t).remove()
},
wrap: function(t) {
var e = Z(t);
if (this[0] && !e) var i = n(t).get(0),
r = i.parentNode || this.length > 1;
return this.each(function(o) {
n(this).wrapAll(e ? t.call(this, o) : r ? i.cloneNode(!0) : i)
})
},
wrapAll: function(t) {
if (this[0]) {
n(this[0]).before(t = n(t));
for (var e;
(e = t.children()).length;) t = e.first();
n(t).append(this)
}
return this
},
wrapInner: function(t) {
var e = Z(t);
return this.each(function(i) {
var r = n(this),
o = r.contents(),
s = e ? t.call(this, i) : t;
o.length ? o.wrapAll(s) : r.append(s)
})
},
unwrap: function() {
return this.parent().each(function() {
n(this).replaceWith(n(this).children())
}), this
},
clone: function() {
return this.map(function() {
return this.cloneNode(!0)
})
},
hide: function() {
return this.css("display", "none")
},
toggle: function(e) {
return this.each(function() {
var i = n(this);
(e === t ? "none" == i.css("display") : e) ? i.show(): i.hide()
})
},
prev: function(t) {
return n(this.pluck("previousElementSibling")).filter(t || "*")
},
next: function(t) {
return n(this.pluck("nextElementSibling")).filter(t || "*")
},
html: function(t) {
return 0 in arguments ? this.each(function(e) {
var i = this.innerHTML;
n(this).empty().append(J(this, t, e, i))
}) : 0 in this ? this[0].innerHTML : null
},
text: function(t) {
return 0 in arguments ? this.each(function(e) {
var n = J(this, t, e, this.textContent);
this.textContent = null == n ? "" : "" + n
}) : 0 in this ? this[0].textContent : null
},
attr: function(n, i) {
var r;
return "string" != typeof n || 1 in arguments ? this.each(function(t) {
if (1 === this.nodeType)
if (D(n))
for (e in n) X(this, e, n[e]);
else X(this, n, J(this, i, t, this.getAttribute(n)))
}) : this.length && 1 === this[0].nodeType ? !(r = this[0].getAttribute(n)) && n in this[0] ? this[0][n] : r : t
},
removeAttr: function(t) {
return this.each(function() {
1 === this.nodeType && X(this, t)
})
},
prop: function(t, e) {
return t = P[t] || t, 1 in arguments ? this.each(function(n) {
this[t] = J(this, e, n, this[t])
}) : this[0] && this[0][t]
},
data: function(e, n) {
var i = "data-" + e.replace(m, "-$1").toLowerCase(),
r = 1 in arguments ? this.attr(i, n) : this.attr(i);
return null !== r ? Y(r) : t
},
val: function(t) {
return 0 in arguments ? this.each(function(e) {
this.value = J(this, t, e, this.value)
}) : this[0] && (this[0].multiple ? n(this[0]).find("option").filter(function() {
return this.selected
}).pluck("value") : this[0].value)
},
offset: function(t) {
if (t) return this.each(function(e) {
var i = n(this),
r = J(this, t, e, i.offset()),
o = i.offsetParent().offset(),
s = {
top: r.top - o.top,
left: r.left - o.left
};
"static" == i.css("position") && (s.position = "relative"), i.css(s)
});
if (!this.length) return null;
var e;
try {
e = this[0].getBoundingClientRect()
} catch (ex) {
e = {
left: 0,
top: 0,
width: 0,
height: 0
}
};
return {
left: e.left + window.pageXOffset,
top: e.top + window.pageYOffset,
width: Math.round(e.width),
height: Math.round(e.height)
}
},
css: function(t, i) {
if (arguments.length < 2) {
var r = this[0],
o = getComputedStyle(r, "");
if (!r) return;
if ("string" == typeof t) return r.style[C(t)] || o.getPropertyValue(t);
if (A(t)) {
var s = {};
return n.each(A(t) ? t : [t], function(t, e) {
s[e] = r.style[C(e)] || o.getPropertyValue(e)
}), s
}
}
var a = "";
if ("string" == L(t)) i || 0 === i ? a = F(t) + ":" + H(t, i) : this.each(function() {
this.style.removeProperty(F(t))
});
else
for (e in t) t[e] || 0 === t[e] ? a += F(e) + ":" + H(e, t[e]) + ";" : this.each(function() {
this.style.removeProperty(F(e))
});
return this.each(function() {
this.style.cssText += ";" + a
})
},
index: function(t) {
return t ? this.indexOf(n(t)[0]) : this.parent().children().indexOf(this[0])
},
hasClass: function(t) {
return t ? r.some.call(this, function(t) {
return this.test(W(t))
}, q(t)) : !1
},
addClass: function(t) {
return t ? this.each(function(e) {
i = [];
var r = W(this),
o = J(this, t, e, r);
o.split(/\s+/g).forEach(function(t) {
n(this).hasClass(t) || i.push(t)
}, this), i.length && W(this, r + (r ? " " : "") + i.join(" "))
}) : this
},
removeClass: function(e) {
return this.each(function(n) {
return e === t ? W(this, "") : (i = W(this), J(this, e, n, i).split(/\s+/g).forEach(function(t) {
i = i.replace(q(t), " ")
}), void W(this, i.trim()))
})
},
toggleClass: function(e, i) {
return e ? this.each(function(r) {
var o = n(this),
s = J(this, e, r, W(this));
s.split(/\s+/g).forEach(function(e) {
(i === t ? !o.hasClass(e) : i) ? o.addClass(e): o.removeClass(e)
})
}) : this
},
scrollTop: function(e) {
if (this.length) {
var n = "scrollTop" in this[0];
return e === t ? n ? this[0].scrollTop : this[0].pageYOffset : this.each(n ? function() {
this.scrollTop = e
} : function() {
this.scrollTo(this.scrollX, e)
})
}
},
scrollLeft: function(e) {
if (this.length) {
var n = "scrollLeft" in this[0];
return e === t ? n ? this[0].scrollLeft : this[0].pageXOffset : this.each(n ? function() {
this.scrollLeft = e
} : function() {
this.scrollTo(e, this.scrollY)
})
}
},
position: function() {
if (this.length) {
var t = this[0],
e = this.offsetParent(),
i = this.offset(),
r = d.test(e[0].nodeName) ? {
top: 0,
left: 0
} : e.offset();
return i.top -= parseFloat(n(t).css("margin-top")) || 0, i.left -= parseFloat(n(t).css("margin-left")) || 0, r.top += parseFloat(n(e[0]).css("border-top-width")) || 0, r.left += parseFloat(n(e[0]).css("border-left-width")) || 0, {
top: i.top - r.top,
left: i.left - r.left
}
}
},
offsetParent: function() {
return this.map(function() {
for (var t = this.offsetParent || a.body; t && !d.test(t.nodeName) && "static" == n(t).css("position");) t = t.offsetParent;
return t
})
}
}, n.fn.detach = n.fn.remove, ["width", "height"].forEach(function(e) {
var i = e.replace(/./, function(t) {
return t[0].toUpperCase()
});
n.fn[e] = function(r) {
var o, s = this[0];
return r === t ? $(s) ? s["inner" + i] : _(s) ? s.documentElement["scroll" + i] : (o = this.offset()) && o[e] : this.each(function(t) {
s = n(this), s.css(e, J(this, r, t, s[e]()))
})
}
}), v.forEach(function(t, e) {
var i = e % 2;
n.fn[t] = function() {
var t, o, r = n.map(arguments, function(e) {
return t = L(e), "object" == t || "array" == t || null == e ? e : T.fragment(e)
}),
s = this.length > 1;
return r.length < 1 ? this : this.each(function(t, u) {
o = i ? u : u.parentNode, u = 0 == e ? u.nextSibling : 1 == e ? u.firstChild : 2 == e ? u : null;
var f = n.contains(a.documentElement, o);
r.forEach(function(t) {
if (s) t = t.cloneNode(!0);
else if (!o) return n(t).remove();
o.insertBefore(t, u), f && G(t, function(t) {
null == t.nodeName || "SCRIPT" !== t.nodeName.toUpperCase() || t.type && "text/javascript" !== t.type || t.src || window.eval.call(window, t.innerHTML)
})
})
})
}, n.fn[i ? t + "To" : "insert" + (e ? "Before" : "After")] = function(e) {
return n(e)[t](this), this
}
}), T.Z.prototype = n.fn, T.uniq = N, T.deserializeValue = Y, n.zepto = T, n
}();
window.Zepto = Zepto, void 0 === window.$ && (window.$ = Zepto),
function(t) {
function l(t) {
return t._zid || (t._zid = e++)
}
function h(t, e, n, i) {
if (e = p(e), e.ns) var r = d(e.ns);
return (s[l(t)] || []).filter(function(t) {
return !(!t || e.e && t.e != e.e || e.ns && !r.test(t.ns) || n && l(t.fn) !== l(n) || i && t.sel != i)
})
}
function p(t) {
var e = ("" + t).split(".");
return {
e: e[0],
ns: e.slice(1).sort().join(" ")
}
}
function d(t) {
return new RegExp("(?:^| )" + t.replace(" ", " .* ?") + "(?: |$)")
}
function m(t, e) {
return t.del && !u && t.e in f || !!e
}
function g(t) {
return c[t] || u && f[t] || t
}
function v(e, i, r, o, a, u, f) {
var h = l(e),
d = s[h] || (s[h] = []);
i.split(/\s/).forEach(function(i) {
if ("ready" == i) return t(document).ready(r);
var s = p(i);
s.fn = r, s.sel = a, s.e in c && (r = function(e) {
var n = e.relatedTarget;
return !n || n !== this && !t.contains(this, n) ? s.fn.apply(this, arguments) : void 0
}), s.del = u;
var l = u || r;
s.proxy = function(t) {
if (t = j(t), !t.isImmediatePropagationStopped()) {
t.data = o;
var i = l.apply(e, t._args == n ? [t] : [t].concat(t._args));
return i === !1 && (t.preventDefault(), t.stopPropagation()), i
}
}, s.i = d.length, d.push(s), "addEventListener" in e && e.addEventListener(g(s.e), s.proxy, m(s, f))
})
}
function y(t, e, n, i, r) {
var o = l(t);
(e || "").split(/\s/).forEach(function(e) {
h(t, e, n, i).forEach(function(e) {
delete s[o][e.i], "removeEventListener" in t && t.removeEventListener(g(e.e), e.proxy, m(e, r))
})
})
}
function j(e, i) {
return (i || !e.isDefaultPrevented) && (i || (i = e), t.each(E, function(t, n) {
var r = i[t];
e[t] = function() {
return this[n] = x, r && r.apply(i, arguments)
}, e[n] = b
}), (i.defaultPrevented !== n ? i.defaultPrevented : "returnValue" in i ? i.returnValue === !1 : i.getPreventDefault && i.getPreventDefault()) && (e.isDefaultPrevented = x)), e
}
function S(t) {
var e, i = {
originalEvent: t
};
for (e in t) w.test(e) || t[e] === n || (i[e] = t[e]);
return j(i, t)
}
var n, e = 1,
i = Array.prototype.slice,
r = t.isFunction,
o = function(t) {
return "string" == typeof t
},
s = {},
a = {},
u = "onfocusin" in window,
f = {
focus: "focusin",
blur: "focusout"
},
c = {
mouseenter: "mouseover",
mouseleave: "mouseout"
};
a.click = a.mousedown = a.mouseup = a.mousemove = "MouseEvents", t.event = {
add: v,
remove: y
}, t.proxy = function(e, n) {
var s = 2 in arguments && i.call(arguments, 2);
if (r(e)) {
var a = function() {
return e.apply(n, s ? s.concat(i.call(arguments)) : arguments)
};
return a._zid = l(e), a
}
if (o(n)) return s ? (s.unshift(e[n], e), t.proxy.apply(null, s)) : t.proxy(e[n], e);
throw new TypeError("expected function")
}, t.fn.bind = function(t, e, n) {
return this.on(t, e, n)
}, t.fn.unbind = function(t, e) {
return this.off(t, e)
}, t.fn.one = function(t, e, n, i) {
return this.on(t, e, n, i, 1)
};
var x = function() {
return !0
},
b = function() {
return !1
},
w = /^([A-Z]|returnValue$|layer[XY]$)/,
E = {
preventDefault: "isDefaultPrevented",
stopImmediatePropagation: "isImmediatePropagationStopped",
stopPropagation: "isPropagationStopped"
};
t.fn.delegate = function(t, e, n) {
return this.on(e, t, n)
}, t.fn.undelegate = function(t, e, n) {
return this.off(e, t, n)
}, t.fn.live = function(e, n) {
return t(document.body).delegate(this.selector, e, n), this
}, t.fn.die = function(e, n) {
return t(document.body).undelegate(this.selector, e, n), this
}, t.fn.on = function(e, s, a, u, f) {
var c, l, h = this;
return e && !o(e) ? (t.each(e, function(t, e) {
h.on(t, s, a, e, f)
}), h) : (o(s) || r(u) || u === !1 || (u = a, a = s, s = n), (r(a) || a === !1) && (u = a, a = n), u === !1 && (u = b), h.each(function(n, r) {
f && (c = function(t) {
return y(r, t.type, u), u.apply(this, arguments)
}), s && (l = function(e) {
var n, o = t(e.target).closest(s, r).get(0);
return o && o !== r ? (n = t.extend(S(e), {
currentTarget: o,
liveFired: r
}), (c || u).apply(o, [n].concat(i.call(arguments, 1)))) : void 0
}), v(r, e, u, a, s, l || c)
}))
}, t.fn.off = function(e, i, s) {
var a = this;
return e && !o(e) ? (t.each(e, function(t, e) {
a.off(t, i, e)
}), a) : (o(i) || r(s) || s === !1 || (s = i, i = n), s === !1 && (s = b), a.each(function() {
y(this, e, s, i)
}))
}, t.fn.trigger = function(e, n) {
return e = o(e) || t.isPlainObject(e) ? t.Event(e) : j(e), e._args = n, this.each(function() {
"dispatchEvent" in this ? this.dispatchEvent(e) : t(this).triggerHandler(e, n)
})
}, t.fn.triggerHandler = function(e, n) {
var i, r;
return this.each(function(s, a) {
i = S(o(e) ? t.Event(e) : e), i._args = n, i.target = a, t.each(h(a, e.type || e), function(t, e) {
return r = e.proxy(i), i.isImmediatePropagationStopped() ? !1 : void 0
})
}), r
}, "focusin focusout load resize scroll unload click dblclick mousedown mouseup mousemove mouseover mouseout mouseenter mouseleave change select keydown keypress keyup error".split(" ").forEach(function(e) {
t.fn[e] = function(t) {
return t ? this.bind(e, t) : this.trigger(e)
}
}), ["focus", "blur"].forEach(function(e) {
t.fn[e] = function(t) {
return t ? this.bind(e, t) : this.each(function() {
try {
this[e]()
} catch (t) {}
}), this
}
}), t.Event = function(t, e) {
o(t) || (e = t, t = e.type);
var n = document.createEvent(a[t] || "Events"),
i = !0;
if (e)
for (var r in e) "bubbles" == r ? i = !!e[r] : n[r] = e[r];
return n.initEvent(t, i, !0), j(n)
}
}(Zepto),
function(t) {
function l(e, n, i) {
var r = t.Event(n);
return t(e).trigger(r, i), !r.isDefaultPrevented()
}
function h(t, e, i, r) {
return t.global ? l(e || n, i, r) : void 0
}
function p(e) {
e.global && 0 === t.active++ && h(e, null, "ajaxStart")
}
function d(e) {
e.global && !--t.active && h(e, null, "ajaxStop")
}
function m(t, e) {
var n = e.context;
return e.beforeSend.call(n, t, e) === !1 || h(e, n, "ajaxBeforeSend", [t, e]) === !1 ? !1 : void h(e, n, "ajaxSend", [t, e])
}
function g(t, e, n, i) {
var r = n.context,
o = "success";
n.success.call(r, t, o, e), i && i.resolveWith(r, [t, o, e]), h(n, r, "ajaxSuccess", [e, n, t]), y(o, e, n)
}
function v(t, e, n, i, r) {
var o = i.context;
i.error.call(o, n, e, t), r && r.rejectWith(o, [n, e, t]), h(i, o, "ajaxError", [n, i, t || e]), y(e, n, i)
}
function y(t, e, n) {
var i = n.context;
n.complete.call(i, e, t), h(n, i, "ajaxComplete", [e, n]), d(n)
}
function x() {}
function b(t) {
return t && (t = t.split(";", 2)[0]), t && (t == f ? "html" : t == u ? "json" : s.test(t) ? "script" : a.test(t) && "xml") || "text"
}
function w(t, e) {
return "" == e ? t : (t + "&" + e).replace(/[&?]{1,2}/, "?")
}
function E(e) {
e.processData && e.data && "string" != t.type(e.data) && (e.data = t.param(e.data, e.traditional)), !e.data || e.type && "GET" != e.type.toUpperCase() || (e.url = w(e.url, e.data), e.data = void 0)
}
function j(e, n, i, r) {
return t.isFunction(n) && (r = i, i = n, n = void 0), t.isFunction(i) || (r = i, i = void 0), {
url: e,
data: n,
success: i,
dataType: r
}
}
function T(e, n, i, r) {
var o, s = t.isArray(n),
a = t.isPlainObject(n);
t.each(n, function(n, u) {
o = t.type(u), r && (n = i ? r : r + "[" + (a || "object" == o || "array" == o ? n : "") + "]"), !r && s ? e.add(u.name, u.value) : "array" == o || !i && "object" == o ? T(e, u, i, n) : e.add(n, u)
})
}
var i, r, e = 0,
n = window.document,
o = /<script\b[^<]*(?:(?!<\/script>)<[^<]*)*<\/script>/gi,
s = /^(?:text|application)\/javascript/i,
a = /^(?:text|application)\/xml/i,
u = "application/json",
f = "text/html",
c = /^\s*$/;
t.active = 0, t.ajaxJSONP = function(i, r) {
if (!("type" in i)) return t.ajax(i);
var f, h, o = i.jsonpCallback,
s = (t.isFunction(o) ? o() : o) || "jsonp" + ++e,
a = n.createElement("script"),
u = window[s],
c = function(e) {
t(a).triggerHandler("error", e || "abort")
},
l = {
abort: c
};
return r && r.promise(l), t(a).on("load error", function(e, n) {
clearTimeout(h), t(a).off().remove(), "error" != e.type && f ? g(f[0], l, i, r) : v(null, n || "error", l, i, r), window[s] = u, f && t.isFunction(u) && u(f[0]), u = f = void 0
}), m(l, i) === !1 ? (c("abort"), l) : (window[s] = function() {
f = arguments
}, a.src = i.url.replace(/\?(.+)=\?/, "?$1=" + s), n.head.appendChild(a), i.timeout > 0 && (h = setTimeout(function() {
c("timeout")
}, i.timeout)), l)
}, t.ajaxSettings = {
type: "GET",
beforeSend: x,
success: x,
error: x,
complete: x,
context: null,
global: !0,
xhr: function() {
return new window.XMLHttpRequest
},
accepts: {
script: "text/javascript, application/javascript, application/x-javascript",
json: u,
xml: "application/xml, text/xml",
html: f,
text: "text/plain"
},
crossDomain: !1,
timeout: 0,
processData: !0,
cache: !0
}, t.ajax = function(e) {
var n = t.extend({}, e || {}),
o = t.Deferred && t.Deferred();
for (i in t.ajaxSettings) void 0 === n[i] && (n[i] = t.ajaxSettings[i]);
p(n), n.crossDomain || (n.crossDomain = /^([\w-]+:)?\/\/([^\/]+)/.test(n.url) && RegExp.$2 != window.location.host), n.url || (n.url = window.location.toString()), E(n);
var s = n.dataType,
a = /\?.+=\?/.test(n.url);
if (a && (s = "jsonp"), n.cache !== !1 && (e && e.cache === !0 || "script" != s && "jsonp" != s) || (n.url = w(n.url, "_=" + Date.now())), "jsonp" == s) return a || (n.url = w(n.url, n.jsonp ? n.jsonp + "=?" : n.jsonp === !1 ? "" : "callback=?")), t.ajaxJSONP(n, o);
var j, u = n.accepts[s],
f = {},
l = function(t, e) {
f[t.toLowerCase()] = [t, e]
},
h = /^([\w-]+:)\/\//.test(n.url) ? RegExp.$1 : window.location.protocol,
d = n.xhr(),
y = d.setRequestHeader;
if (o && o.promise(d), n.crossDomain || l("X-Requested-With", "XMLHttpRequest"), l("Accept", u || "*/*"), (u = n.mimeType || u) && (u.indexOf(",") > -1 && (u = u.split(",", 2)[0]), d.overrideMimeType && d.overrideMimeType(u)), (n.contentType || n.contentType !== !1 && n.data && "GET" != n.type.toUpperCase()) && l("Content-Type", n.contentType || "application/x-www-form-urlencoded"), n.headers)
for (r in n.headers) l(r, n.headers[r]);
if (d.setRequestHeader = l, d.onreadystatechange = function() {
if (4 == d.readyState) {
d.onreadystatechange = x, clearTimeout(j);
var e, i = !1;
if (d.status >= 200 && d.status < 300 || 304 == d.status || 0 == d.status && "file:" == h) {
s = s || b(n.mimeType || d.getResponseHeader("content-type")), e = d.responseText;
try {
"script" == s ? (1, eval)(e) : "xml" == s ? e = d.responseXML : "json" == s && (e = c.test(e) ? null : t.parseJSON(e))
} catch (r) {
i = r
}
i ? v(i, "parsererror", d, n, o) : g(e, d, n, o)
} else v(d.statusText || null, d.status ? "error" : "abort", d, n, o)
}
}, m(d, n) === !1) return d.abort(), v(null, "abort", d, n, o), d;
if (n.xhrFields)
for (r in n.xhrFields) d[r] = n.xhrFields[r];
var S = "async" in n ? n.async : !0;
d.open(n.type, n.url, S, n.username, n.password);
for (r in f) y.apply(d, f[r]);
return n.timeout > 0 && (j = setTimeout(function() {
d.onreadystatechange = x, d.abort(), v(null, "timeout", d, n, o)
}, n.timeout)), d.send(n.data ? n.data : null), d
}, t.get = function() {
return t.ajax(j.apply(null, arguments))
}, t.post = function() {
var e = j.apply(null, arguments);
return e.type = "POST", t.ajax(e)
}, t.getJSON = function() {
var e = j.apply(null, arguments);
return e.dataType = "json", t.ajax(e)
}, t.fn.load = function(e, n, i) {
if (!this.length) return this;
var a, r = this,
s = e.split(/\s/),
u = j(e, n, i),
f = u.success;
return s.length > 1 && (u.url = s[0], a = s[1]), u.success = function(e) {
r.html(a ? t("<div>").html(e.replace(o, "")).find(a) : e), f && f.apply(r, arguments)
}, t.ajax(u), this
};
var S = encodeURIComponent;
t.param = function(t, e) {
var n = [];
return n.add = function(t, e) {
this.push(S(t) + "=" + S(e))
}, T(n, t, e), n.join("&").replace(/%20/g, "+")
}
}(Zepto),
function(t) {
t.fn.serializeArray = function() {
var n, e = [];
return t([].slice.call(this.get(0).elements)).each(function() {
n = t(this);
var i = n.attr("type");
"fieldset" != this.nodeName.toLowerCase() && !this.disabled && "submit" != i && "reset" != i && "button" != i && ("radio" != i && "checkbox" != i || this.checked) && e.push({
name: n.attr("name"),
value: n.val()
})
}), e
}, t.fn.serialize = function() {
var t = [];
return this.serializeArray().forEach(function(e) {
t.push(encodeURIComponent(e.name) + "=" + encodeURIComponent(e.value))
}), t.join("&")
}, t.fn.submit = function(e) {
if (e) this.bind("submit", e);
else if (this.length) {
var n = t.Event("submit");
this.eq(0).trigger(n), n.isDefaultPrevented() || this.get(0).submit()
}
return this
}
}(Zepto),
function(t) {
"__proto__" in {} || t.extend(t.zepto, {
Z: function(e, n) {
return e = e || [], t.extend(e, t.fn), e.selector = n || "", e.__Z = !0, e
},
isZ: function(e) {
return "array" === t.type(e) && "__Z" in e
}
});
try {
getComputedStyle(void 0)
} catch (e) {
var n = getComputedStyle;
window.getComputedStyle = function(t) {
try {
return n(t)
} catch (e) {
return null
}
}
}
}(Zepto);
// Underscore.js 1.7.0// http://underscorejs.org// (c) 2009-2014 Jeremy Ashkenas, DocumentCloud and Investigative Reporters & Editors// Underscore may be freely distributed under the MIT license.(function(){var n=this,t=n._,r=Array.prototype,e=Object.prototype,u=Function.prototype,i=r.push,a=r.slice,o=r.concat,l=e.toString,c=e.hasOwnProperty,f=Array.isArray,s=Object.keys,p=u.bind,h=function(n){return n instanceof h?n:this instanceof h?void(this._wrapped=n):new h(n)};"undefined"!=typeof exports?("undefined"!=typeof module&&module.exports&&(exports=module.exports=h),exports._=h):n._=h,h.VERSION="1.7.0";var g=function(n,t,r){if(t===void 0)return n;switch(null==r?3:r){case 1:return function(r){return n.call(t,r)};case 2:return function(r,e){return n.call(t,r,e)};case 3:return function(r,e,u){return n.call(t,r,e,u)};case 4:return function(r,e,u,i){return n.call(t,r,e,u,i)}}return function(){return n.apply(t,arguments)}};h.iteratee=function(n,t,r){return null==n?h.identity:h.isFunction(n)?g(n,t,r):h.isObject(n)?h.matches(n):h.property(n)},h.each=h.forEach=function(n,t,r){if(null==n)return n;t=g(t,r);var e,u=n.length;if(u===+u)for(e=0;u>e;e++)t(n[e],e,n);else{var i=h.keys(n);for(e=0,u=i.length;u>e;e++)t(n[i[e]],i[e],n)}return n},h.map=h.collect=function(n,t,r){if(null==n)return[];t=h.iteratee(t,r);for(var e,u=n.length!==+n.length&&h.keys(n),i=(u||n).length,a=Array(i),o=0;i>o;o++)e=u?u[o]:o,a[o]=t(n[e],e,n);return a};var v="Reduce of empty array with no initial value";h.reduce=h.foldl=h.inject=function(n,t,r,e){null==n&&(n=[]),t=g(t,e,4);var u,i=n.length!==+n.length&&h.keys(n),a=(i||n).length,o=0;if(arguments.length<3){if(!a)throw new TypeError(v);r=n[i?i[o++]:o++]}for(;a>o;o++)u=i?i[o]:o,r=t(r,n[u],u,n);return r},h.reduceRight=h.foldr=function(n,t,r,e){null==n&&(n=[]),t=g(t,e,4);var u,i=n.length!==+n.length&&h.keys(n),a=(i||n).length;if(arguments.length<3){if(!a)throw new TypeError(v);r=n[i?i[--a]:--a]}for(;a--;)u=i?i[a]:a,r=t(r,n[u],u,n);return r},h.find=h.detect=function(n,t,r){var e;return t=h.iteratee(t,r),h.some(n,function(n,r,u){return t(n,r,u)?(e=n,!0):void 0}),e},h.filter=h.select=function(n,t,r){var e=[];return null==n?e:(t=h.iteratee(t,r),h.each(n,function(n,r,u){t(n,r,u)&&e.push(n)}),e)},h.reject=function(n,t,r){return h.filter(n,h.negate(h.iteratee(t)),r)},h.every=h.all=function(n,t,r){if(null==n)return!0;t=h.iteratee(t,r);var e,u,i=n.length!==+n.length&&h.keys(n),a=(i||n).length;for(e=0;a>e;e++)if(u=i?i[e]:e,!t(n[u],u,n))return!1;return!0},h.some=h.any=function(n,t,r){if(null==n)return!1;t=h.iteratee(t,r);var e,u,i=n.length!==+n.length&&h.keys(n),a=(i||n).length;for(e=0;a>e;e++)if(u=i?i[e]:e,t(n[u],u,n))return!0;return!1},h.contains=h.include=function(n,t){return null==n?!1:(n.length!==+n.length&&(n=h.values(n)),h.indexOf(n,t)>=0)},h.invoke=function(n,t){var r=a.call(arguments,2),e=h.isFunction(t);return h.map(n,function(n){return(e?t:n[t]).apply(n,r)})},h.pluck=function(n,t){return h.map(n,h.property(t))},h.where=function(n,t){return h.filter(n,h.matches(t))},h.findWhere=function(n,t){return h.find(n,h.matches(t))},h.max=function(n,t,r){var e,u,i=-1/0,a=-1/0;if(null==t&&null!=n){n=n.length===+n.length?n:h.values(n);for(var o=0,l=n.length;l>o;o++)e=n[o],e>i&&(i=e)}else t=h.iteratee(t,r),h.each(n,function(n,r,e){u=t(n,r,e),(u>a||u===-1/0&&i===-1/0)&&(i=n,a=u)});return i},h.min=function(n,t,r){var e,u,i=1/0,a=1/0;if(null==t&&null!=n){n=n.length===+n.length?n:h.values(n);for(var o=0,l=n.length;l>o;o++)e=n[o],i>e&&(i=e)}else t=h.iteratee(t,r),h.each(n,function(n,r,e){u=t(n,r,e),(a>u||1/0===u&&1/0===i)&&(i=n,a=u)});return i},h.shuffle=function(n){for(var t,r=n&&n.length===+n.length?n:h.values(n),e=r.length,u=Array(e),i=0;e>i;i++)t=h.random(0,i),t!==i&&(u[i]=u[t]),u[t]=r[i];return u},h.sample=function(n,t,r){return null==t||r?(n.length!==+n.length&&(n=h.values(n)),n[h.random(n.length-1)]):h.shuffle(n).slice(0,Math.max(0,t))},h.sortBy=function(n,t,r){return t=h.iteratee(t,r),h.pluck(h.map(n,function(n,r,e){return{value:n,index:r,criteria:t(n,r,e)}}).sort(function(n,t){var r=n.criteria,e=t.criteria;if(r!==e){if(r>e||r===void 0)return 1;if(e>r||e===void 0)return-1}return n.index-t.index}),"value")};var m=function(n){return function(t,r,e){var u={};return r=h.iteratee(r,e),h.each(t,function(e,i){var a=r(e,i,t);n(u,e,a)}),u}};h.groupBy=m(function(n,t,r){h.has(n,r)?n[r].push(t):n[r]=[t]}),h.indexBy=m(function(n,t,r){n[r]=t}),h.countBy=m(function(n,t,r){h.has(n,r)?n[r]++:n[r]=1}),h.sortedIndex=function(n,t,r,e){r=h.iteratee(r,e,1);for(var u=r(t),i=0,a=n.length;a>i;){var o=i+a>>>1;r(n[o])<u?i=o+1:a=o}return i},h.toArray=function(n){return n?h.isArray(n)?a.call(n):n.length===+n.length?h.map(n,h.identity):h.values(n):[]},h.size=function(n){return null==n?0:n.length===+n.length?n.length:h.keys(n).length},h.partition=function(n,t,r){t=h.iteratee(t,r);var e=[],u=[];return h.each(n,function(n,r,i){(t(n,r,i)?e:u).push(n)}),[e,u]},h.first=h.head=h.take=function(n,t,r){return null==n?void 0:null==t||r?n[0]:0>t?[]:a.call(n,0,t)},h.initial=function(n,t,r){return a.call(n,0,Math.max(0,n.length-(null==t||r?1:t)))},h.last=function(n,t,r){return null==n?void 0:null==t||r?n[n.length-1]:a.call(n,Math.max(n.length-t,0))},h.rest=h.tail=h.drop=function(n,t,r){return a.call(n,null==t||r?1:t)},h.compact=function(n){return h.filter(n,h.identity)};var y=function(n,t,r,e){if(t&&h.every(n,h.isArray))return o.apply(e,n);for(var u=0,a=n.length;a>u;u++){var l=n[u];h.isArray(l)||h.isArguments(l)?t?i.apply(e,l):y(l,t,r,e):r||e.push(l)}return e};h.flatten=function(n,t){return y(n,t,!1,[])},h.without=function(n){return h.difference(n,a.call(arguments,1))},h.uniq=h.unique=function(n,t,r,e){if(null==n)return[];h.isBoolean(t)||(e=r,r=t,t=!1),null!=r&&(r=h.iteratee(r,e));for(var u=[],i=[],a=0,o=n.length;o>a;a++){var l=n[a];if(t)a&&i===l||u.push(l),i=l;else if(r){var c=r(l,a,n);h.indexOf(i,c)<0&&(i.push(c),u.push(l))}else h.indexOf(u,l)<0&&u.push(l)}return u},h.union=function(){return h.uniq(y(arguments,!0,!0,[]))},h.intersection=function(n){if(null==n)return[];for(var t=[],r=arguments.length,e=0,u=n.length;u>e;e++){var i=n[e];if(!h.contains(t,i)){for(var a=1;r>a&&h.contains(arguments[a],i);a++);a===r&&t.push(i)}}return t},h.difference=function(n){var t=y(a.call(arguments,1),!0,!0,[]);return h.filter(n,function(n){return!h.contains(t,n)})},h.zip=function(n){if(null==n)return[];for(var t=h.max(arguments,"length").length,r=Array(t),e=0;t>e;e++)r[e]=h.pluck(arguments,e);return r},h.object=function(n,t){if(null==n)return{};for(var r={},e=0,u=n.length;u>e;e++)t?r[n[e]]=t[e]:r[n[e][0]]=n[e][1];return r},h.indexOf=function(n,t,r){if(null==n)return-1;var e=0,u=n.length;if(r){if("number"!=typeof r)return e=h.sortedIndex(n,t),n[e]===t?e:-1;e=0>r?Math.max(0,u+r):r}for(;u>e;e++)if(n[e]===t)return e;return-1},h.lastIndexOf=function(n,t,r){if(null==n)return-1;var e=n.length;for("number"==typeof r&&(e=0>r?e+r+1:Math.min(e,r+1));--e>=0;)if(n[e]===t)return e;return-1},h.range=function(n,t,r){arguments.length<=1&&(t=n||0,n=0),r=r||1;for(var e=Math.max(Math.ceil((t-n)/r),0),u=Array(e),i=0;e>i;i++,n+=r)u[i]=n;return u};var d=function(){};h.bind=function(n,t){var r,e;if(p&&n.bind===p)return p.apply(n,a.call(arguments,1));if(!h.isFunction(n))throw new TypeError("Bind must be called on a function");return r=a.call(arguments,2),e=function(){if(!(this instanceof e))return n.apply(t,r.concat(a.call(arguments)));d.prototype=n.prototype;var u=new d;d.prototype=null;var i=n.apply(u,r.concat(a.call(arguments)));return h.isObject(i)?i:u}},h.partial=function(n){var t=a.call(arguments,1);return function(){for(var r=0,e=t.slice(),u=0,i=e.length;i>u;u++)e[u]===h&&(e[u]=arguments[r++]);for(;r<arguments.length;)e.push(arguments[r++]);return n.apply(this,e)}},h.bindAll=function(n){var t,r,e=arguments.length;if(1>=e)throw new Error("bindAll must be passed function names");for(t=1;e>t;t++)r=arguments[t],n[r]=h.bind(n[r],n);return n},h.memoize=function(n,t){var r=function(e){var u=r.cache,i=t?t.apply(this,arguments):e;return h.has(u,i)||(u[i]=n.apply(this,arguments)),u[i]};return r.cache={},r},h.delay=function(n,t){var r=a.call(arguments,2);return setTimeout(function(){return n.apply(null,r)},t)},h.defer=function(n){return h.delay.apply(h,[n,1].concat(a.call(arguments,1)))},h.throttle=function(n,t,r){var e,u,i,a=null,o=0;r||(r={});var l=function(){o=r.leading===!1?0:h.now(),a=null,i=n.apply(e,u),a||(e=u=null)};return function(){var c=h.now();o||r.leading!==!1||(o=c);var f=t-(c-o);return e=this,u=arguments,0>=f||f>t?(clearTimeout(a),a=null,o=c,i=n.apply(e,u),a||(e=u=null)):a||r.trailing===!1||(a=setTimeout(l,f)),i}},h.debounce=function(n,t,r){var e,u,i,a,o,l=function(){var c=h.now()-a;t>c&&c>0?e=setTimeout(l,t-c):(e=null,r||(o=n.apply(i,u),e||(i=u=null)))};return function(){i=this,u=arguments,a=h.now();var c=r&&!e;return e||(e=setTimeout(l,t)),c&&(o=n.apply(i,u),i=u=null),o}},h.wrap=function(n,t){return h.partial(t,n)},h.negate=function(n){return function(){return!n.apply(this,arguments)}},h.compose=function(){var n=arguments,t=n.length-1;return function(){for(var r=t,e=n[t].apply(this,arguments);r--;)e=n[r].call(this,e);return e}},h.after=function(n,t){return function(){return--n<1?t.apply(this,arguments):void 0}},h.before=function(n,t){var r;return function(){return--n>0?r=t.apply(this,arguments):t=null,r}},h.once=h.partial(h.before,2),h.keys=function(n){if(!h.isObject(n))return[];if(s)return s(n);var t=[];for(var r in n)h.has(n,r)&&t.push(r);return t},h.values=function(n){for(var t=h.keys(n),r=t.length,e=Array(r),u=0;r>u;u++)e[u]=n[t[u]];return e},h.pairs=function(n){for(var t=h.keys(n),r=t.length,e=Array(r),u=0;r>u;u++)e[u]=[t[u],n[t[u]]];return e},h.invert=function(n){for(var t={},r=h.keys(n),e=0,u=r.length;u>e;e++)t[n[r[e]]]=r[e];return t},h.functions=h.methods=function(n){var t=[];for(var r in n)h.isFunction(n[r])&&t.push(r);return t.sort()},h.extend=function(n){if(!h.isObject(n))return n;for(var t,r,e=1,u=arguments.length;u>e;e++){t=arguments[e];for(r in t)c.call(t,r)&&(n[r]=t[r])}return n},h.pick=function(n,t,r){var e,u={};if(null==n)return u;if(h.isFunction(t)){t=g(t,r);for(e in n){var i=n[e];t(i,e,n)&&(u[e]=i)}}else{var l=o.apply([],a.call(arguments,1));n=new Object(n);for(var c=0,f=l.length;f>c;c++)e=l[c],e in n&&(u[e]=n[e])}return u},h.omit=function(n,t,r){if(h.isFunction(t))t=h.negate(t);else{var e=h.map(o.apply([],a.call(arguments,1)),String);t=function(n,t){return!h.contains(e,t)}}return h.pick(n,t,r)},h.defaults=function(n){if(!h.isObject(n))return n;for(var t=1,r=arguments.length;r>t;t++){var e=arguments[t];for(var u in e)n[u]===void 0&&(n[u]=e[u])}return n},h.clone=function(n){return h.isObject(n)?h.isArray(n)?n.slice():h.extend({},n):n},h.tap=function(n,t){return t(n),n};var b=function(n,t,r,e){if(n===t)return 0!==n||1/n===1/t;if(null==n||null==t)return n===t;n instanceof h&&(n=n._wrapped),t instanceof h&&(t=t._wrapped);var u=l.call(n);if(u!==l.call(t))return!1;switch(u){case"[object RegExp]":case"[object String]":return""+n==""+t;case"[object Number]":return+n!==+n?+t!==+t:0===+n?1/+n===1/t:+n===+t;case"[object Date]":case"[object Boolean]":return+n===+t}if("object"!=typeof n||"object"!=typeof t)return!1;for(var i=r.length;i--;)if(r[i]===n)return e[i]===t;var a=n.constructor,o=t.constructor;if(a!==o&&"constructor"in n&&"constructor"in t&&!(h.isFunction(a)&&a instanceof a&&h.isFunction(o)&&o instanceof o))return!1;r.push(n),e.push(t);var c,f;if("[object Array]"===u){if(c=n.length,f=c===t.length)for(;c--&&(f=b(n[c],t[c],r,e)););}else{var s,p=h.keys(n);if(c=p.length,f=h.keys(t).length===c)for(;c--&&(s=p[c],f=h.has(t,s)&&b(n[s],t[s],r,e)););}return r.pop(),e.pop(),f};h.isEqual=function(n,t){return b(n,t,[],[])},h.isEmpty=function(n){if(null==n)return!0;if(h.isArray(n)||h.isString(n)||h.isArguments(n))return 0===n.length;for(var t in n)if(h.has(n,t))return!1;return!0},h.isElement=function(n){return!(!n||1!==n.nodeType)},h.isArray=f||function(n){return"[object Array]"===l.call(n)},h.isObject=function(n){var t=typeof n;return"function"===t||"object"===t&&!!n},h.each(["Arguments","Function","String","Number","Date","RegExp"],function(n){h["is"+n]=function(t){return l.call(t)==="[object "+n+"]"}}),h.isArguments(arguments)||(h.isArguments=function(n){return h.has(n,"callee")}),"function"!=typeof/./&&(h.isFunction=function(n){return"function"==typeof n||!1}),h.isFinite=function(n){return isFinite(n)&&!isNaN(parseFloat(n))},h.isNaN=function(n){return h.isNumber(n)&&n!==+n},h.isBoolean=function(n){return n===!0||n===!1||"[object Boolean]"===l.call(n)},h.isNull=function(n){return null===n},h.isUndefined=function(n){return n===void 0},h.has=function(n,t){return null!=n&&c.call(n,t)},h.noConflict=function(){return n._=t,this},h.identity=function(n){return n},h.constant=function(n){return function(){return n}},h.noop=function(){},h.property=function(n){return function(t){return t[n]}},h.matches=function(n){var t=h.pairs(n),r=t.length;return function(n){if(null==n)return!r;n=new Object(n);for(var e=0;r>e;e++){var u=t[e],i=u[0];if(u[1]!==n[i]||!(i in n))return!1}return!0}},h.times=function(n,t,r){var e=Array(Math.max(0,n));t=g(t,r,1);for(var u=0;n>u;u++)e[u]=t(u);return e},h.random=function(n,t){return null==t&&(t=n,n=0),n+Math.floor(Math.random()*(t-n+1))},h.now=Date.now||function(){return(new Date).getTime()};var _={"&":"&amp;","<":"&lt;",">":"&gt;",'"':"&quot;","'":"&#x27;","`":"&#x60;"},w=h.invert(_),j=function(n){var t=function(t){return n[t]},r="(?:"+h.keys(n).join("|")+")",e=RegExp(r),u=RegExp(r,"g");return function(n){return n=null==n?"":""+n,e.test(n)?n.replace(u,t):n}};h.escape=j(_),h.unescape=j(w),h.result=function(n,t){if(null==n)return void 0;var r=n[t];return h.isFunction(r)?n[t]():r};var x=0;h.uniqueId=function(n){var t=++x+"";return n?n+t:t},h.templateSettings={evaluate:/<%([\s\S]+?)%>/g,interpolate:/<%=([\s\S]+?)%>/g,escape:/<%-([\s\S]+?)%>/g};var A=/(.)^/,k={"'":"'","\\":"\\","\r":"r","\n":"n","\u2028":"u2028","\u2029":"u2029"},O=/\\|'|\r|\n|\u2028|\u2029/g,F=function(n){return"\\"+k[n]};h.template=function(n,t,r){!t&&r&&(t=r),t=h.defaults({},t,h.templateSettings);var e=RegExp([(t.escape||A).source,(t.interpolate||A).source,(t.evaluate||A).source].join("|")+"|$","g"),u=0,i="__p+='";n.replace(e,function(t,r,e,a,o){return i+=n.slice(u,o).replace(O,F),u=o+t.length,r?i+="'+\n((__t=("+r+"))==null?'':_.escape(__t))+\n'":e?i+="'+\n((__t=("+e+"))==null?'':__t)+\n'":a&&(i+="';\n"+a+"\n__p+='"),t}),i+="';\n",t.variable||(i="with(obj||{}){\n"+i+"}\n"),i="var __t,__p='',__j=Array.prototype.join,"+"print=function(){__p+=__j.call(arguments,'');};\n"+i+"return __p;\n";try{var a=new Function(t.variable||"obj","_",i)}catch(o){throw o.source=i,o}var l=function(n){return a.call(this,n,h)},c=t.variable||"obj";return l.source="function("+c+"){\n"+i+"}",l},h.chain=function(n){var t=h(n);return t._chain=!0,t};var E=function(n){return this._chain?h(n).chain():n};h.mixin=function(n){h.each(h.functions(n),function(t){var r=h[t]=n[t];h.prototype[t]=function(){var n=[this._wrapped];return i.apply(n,arguments),E.call(this,r.apply(h,n))}})},h.mixin(h),h.each(["pop","push","reverse","shift","sort","splice","unshift"],function(n){var t=r[n];h.prototype[n]=function(){var r=this._wrapped;return t.apply(r,arguments),"shift"!==n&&"splice"!==n||0!==r.length||delete r[0],E.call(this,r)}}),h.each(["concat","join","slice"],function(n){var t=r[n];h.prototype[n]=function(){return E.call(this,t.apply(this._wrapped,arguments))}}),h.prototype.value=function(){return this._wrapped},"function"==typeof define&&define.amd&&define("underscore",[],function(){return h})}).call(this);
// Backbone.js 0.9.2
// (c) 2010-2012 Jeremy Ashkenas, DocumentCloud Inc.// Backbone may be freely distributed under the MIT license.// For all details and documentation:// http://backbonejs.org(function(){var l=this,y=l.Backbone,z=Array.prototype.slice,A=Array.prototype.splice,g;g="undefined"!==typeof exports?exports:l.Backbone={};g.VERSION="0.9.2";var f=l._;!f&&"undefined"!==typeof require&&(f=require("underscore"));var i=l.jQuery||l.Zepto||l.ender;g.setDomLibrary=function(a){i=a};g.noConflict=function(){l.Backbone=y;return this};g.emulateHTTP=!1;g.emulateJSON=!1;var p=/\s+/,k=g.Events={on:function(a,b,c){var d,e,f,g,j;if(!b)return this;a=a.split(p);for(d=this._callbacks||(this._callbacks={});e=a.shift();)f=(j=d[e])?j.tail:{},f.next=g={},f.context=c,f.callback=b,d[e]={tail:g,next:j?j.next:f};return this},off:function(a,b,c){var d,e,h,g,j,q;if(e=this._callbacks){if(!a&&!b&&!c)return delete this._callbacks,this;for(a=a?a.split(p):f.keys(e);d=a.shift();)if(h=e[d],delete e[d],h&&(b||c))for(g=h.tail;(h=h.next)!==g;)if(j=h.callback,q=h.context,b&&j!==b||c&&q!==c)this.on(d,j,q);return this}},trigger:function(a){var b,c,d,e,f,g;if(!(d=this._callbacks))return this;f=d.all;a=a.split(p);for(g=z.call(arguments,1);b=a.shift();){if(c=d[b])for(e=c.tail;(c=c.next)!==e;)c.callback.apply(c.context||this,g);if(c=f){e=c.tail;for(b=[b].concat(g);(c=c.next)!==e;)c.callback.apply(c.context||this,b)}}return this}};k.bind=k.on;k.unbind=k.off;var o=g.Model=function(a,b){var c;a||(a={});b&&b.parse&&(a=this.parse(a));if(c=n(this,"defaults"))a=f.extend({},c,a);b&&b.collection&&(this.collection=b.collection);this.attributes={};this._escapedAttributes={};this.cid=f.uniqueId("c");this.changed={};this._silent={};this._pending={};this.set(a,{silent:!0});this.changed={};this._silent={};this._pending={};this._previousAttributes=f.clone(this.attributes);this.initialize.apply(this,arguments)};f.extend(o.prototype,k,{changed:null,_silent:null,_pending:null,idAttribute:"id",initialize:function(){},toJSON:function(){return f.clone(this.attributes)},get:function(a){return this.attributes[a]},escape:function(a){var b;if(b=this._escapedAttributes[a])return b;b=this.get(a);return this._escapedAttributes[a]=f.escape(null==b?"":""+b)},has:function(a){return null!=this.get(a)},set:function(a,b,c){var d,e;f.isObject(a)||null==a?(d=a,c=b):(d={},d[a]=b);c||(c={});if(!d)return this;d instanceof o&&(d=d.attributes);if(c.unset)for(e in d)d[e]=void 0;if(!this._validate(d,c))return!1;this.idAttribute in d&&(this.id=d[this.idAttribute]);var b=c.changes={},h=this.attributes,g=this._escapedAttributes,j=this._previousAttributes||{};for(e in d){a=d[e];if(!f.isEqual(h[e],a)||c.unset&&f.has(h,e))delete g[e],(c.silent?this._silent:b)[e]=!0;c.unset?delete h[e]:h[e]=a;!f.isEqual(j[e],a)||f.has(h,e)!=f.has(j,e)?(this.changed[e]=a,c.silent||(this._pending[e]=!0)):(delete this.changed[e],delete this._pending[e])}c.silent||this.change(c);return this},unset:function(a,b){(b||(b={})).unset=!0;return this.set(a,null,b)},clear:function(a){(a||(a={})).unset=!0;return this.set(f.clone(this.attributes),a)},fetch:function(a){var a=a?f.clone(a):{},b=this,c=a.success;a.success=function(d,e,f){if(!b.set(b.parse(d,f),a))return!1;c&&c(b,d)};a.error=g.wrapError(a.error,b,a);return(this.sync||g.sync).call(this,"read",this,a)},save:function(a,b,c){var d,e;f.isObject(a)||null==a?(d=a,c=b):(d={},d[a]=b);c=c?f.clone(c):{};if(c.wait){if(!this._validate(d,c))return!1;e=f.clone(this.attributes)}a=f.extend({},c,{silent:!0});if(d&&!this.set(d,c.wait?a:c))return!1;var h=this,i=c.success;c.success=function(a,b,e){b=h.parse(a,e);if(c.wait){delete c.wait;b=f.extend(d||{},b)}if(!h.set(b,c))return false;i?i(h,a):h.trigger("sync",h,a,c)};c.error=g.wrapError(c.error,h,c);b=this.isNew()?"create":"update";b=(this.sync||g.sync).call(this,b,this,c);c.wait&&this.set(e,a);return b},destroy:function(a){var a=a?f.clone(a):{},b=this,c=a.success,d=function(){b.trigger("destroy",b,b.collection,a)};if(this.isNew())return d(),!1;a.success=function(e){a.wait&&d();c?c(b,e):b.trigger("sync",b,e,a)};a.error=g.wrapError(a.error,b,a);var e=(this.sync||g.sync).call(this,"delete",this,a);a.wait||d();return e},url:function(){var a=n(this,"urlRoot")||n(this.collection,"url")||t();return this.isNew()?a:a+("/"==a.charAt(a.length-1)?"":"/")+encodeURIComponent(this.id)},parse:function(a){return a},clone:function(){return new this.constructor(this.attributes)},isNew:function(){return null==this.id},change:function(a){a||(a={});var b=this._changing;this._changing=!0;for(var c in this._silent)this._pending[c]=!0;var d=f.extend({},a.changes,this._silent);this._silent={};for(c in d)this.trigger("change:"+c,this,this.get(c),a);if(b)return this;for(;!f.isEmpty(this._pending);){this._pending={};this.trigger("change",this,a);for(c in this.changed)!this._pending[c]&&!this._silent[c]&&delete this.changed[c];this._previousAttributes=f.clone(this.attributes)}this._changing=!1;return this},hasChanged:function(a){return!arguments.length?!f.isEmpty(this.changed):f.has(this.changed,a)},changedAttributes:function(a){if(!a)return this.hasChanged()?f.clone(this.changed):!1;var b,c=!1,d=this._previousAttributes,e;for(e in a)if(!f.isEqual(d[e],b=a[e]))(c||(c={}))[e]=b;return c},previous:function(a){return!arguments.length||!this._previousAttributes?null:this._previousAttributes[a]},previousAttributes:function(){return f.clone(this._previousAttributes)},isValid:function(){return!this.validate(this.attributes)},_validate:function(a,b){if(b.silent||!this.validate)return!0;var a=f.extend({},this.attributes,a),c=this.validate(a,b);if(!c)return!0;b&&b.error?b.error(this,c,b):this.trigger("error",this,c,b);return!1}});var r=g.Collection=function(a,b){b||(b={});b.model&&(this.model=b.model);b.comparator&&(this.comparator=b.comparator);this._reset();this.initialize.apply(this,arguments);a&&this.reset(a,{silent:!0,parse:b.parse})};f.extend(r.prototype,k,{model:o,initialize:function(){},toJSON:function(a){return this.map(function(b){return b.toJSON(a)})},add:function(a,b){var c,d,e,g,i,j={},k={},l=[];b||(b={});a=f.isArray(a)?a.slice():[a];c=0;for(d=a.length;c<d;c++){if(!(e=a[c]=this._prepareModel(a[c],b)))throw Error("Can't add an invalid model to a collection");g=e.cid;i=e.id;j[g]||this._byCid[g]||null!=i&&(k[i]||this._byId[i])?l.push(c):j[g]=k[i]=e}for(c=l.length;c--;)a.splice(l[c],1);c=0;for(d=a.length;c<d;c++)(e=a[c]).on("all",this._onModelEvent,this),this._byCid[e.cid]=e,null!=e.id&&(this._byId[e.id]=e);this.length+=d;A.apply(this.models,[null!=b.at?b.at:this.models.length,0].concat(a));this.comparator&&this.sort({silent:!0});if(b.silent)return this;c=0;for(d=this.models.length;c<d;c++)if(j[(e=this.models[c]).cid])b.index=c,e.trigger("add",e,this,b);return this},remove:function(a,b){var c,d,e,g;b||(b={});a=f.isArray(a)?a.slice():[a];c=0;for(d=a.length;c<d;c++)if(g=this.getByCid(a[c])||this.get(a[c]))delete this._byId[g.id],delete this._byCid[g.cid],e=this.indexOf(g),this.models.splice(e,1),this.length--,b.silent||(b.index=e,g.trigger("remove",g,this,b)),this._removeReference(g);return this},push:function(a,b){a=this._prepareModel(a,b);this.add(a,b);return a},pop:function(a){var b=this.at(this.length-1);this.remove(b,a);return b},unshift:function(a,b){a=this._prepareModel(a,b);this.add(a,f.extend({at:0},b));return a},shift:function(a){var b=this.at(0);this.remove(b,a);return b},get:function(a){return null==a?void 0:this._byId[null!=a.id?a.id:a]},getByCid:function(a){return a&&this._byCid[a.cid||a]},at:function(a){return this.models[a]},where:function(a){return f.isEmpty(a)?[]:this.filter(function(b){for(var c in a)if(a[c]!==b.get(c))return!1;return!0})},sort:function(a){a||(a={});if(!this.comparator)throw Error("Cannot sort a set without a comparator");var b=f.bind(this.comparator,this);1==this.comparator.length?this.models=this.sortBy(b):this.models.sort(b);a.silent||this.trigger("reset",this,a);return this},pluck:function(a){return f.map(this.models,function(b){return b.get(a)})},reset:function(a,b){a||(a=[]);b||(b={});for(var c=0,d=this.models.length;c<d;c++)this._removeReference(this.models[c]);this._reset();this.add(a,f.extend({silent:!0},b));b.silent||this.trigger("reset",this,b);return this},fetch:function(a){a=a?f.clone(a):{};void 0===a.parse&&(a.parse=!0);var b=this,c=a.success;a.success=function(d,e,f){b[a.add?"add":"reset"](b.parse(d,f),a);c&&c(b,d)};a.error=g.wrapError(a.error,b,a);return(this.sync||g.sync).call(this,"read",this,a)},create:function(a,b){var c=this,b=b?f.clone(b):{},a=this._prepareModel(a,b);if(!a)return!1;b.wait||c.add(a,b);var d=b.success;b.success=function(e,f){b.wait&&c.add(e,b);d?d(e,f):e.trigger("sync",a,f,b)};a.save(null,b);return a},parse:function(a){return a},chain:function(){return f(this.models).chain()},_reset:function(){this.length=0;this.models=[];this._byId={};this._byCid={}},_prepareModel:function(a,b){b||(b={});a instanceof o?a.collection||(a.collection=this):(b.collection=this,a=new this.model(a,b),a._validate(a.attributes,b)||(a=!1));return a},_removeReference:function(a){this==a.collection&&delete a.collection;a.off("all",this._onModelEvent,this)},_onModelEvent:function(a,b,c,d){("add"==a||"remove"==a)&&c!=this||("destroy"==a&&this.remove(b,d),b&&a==="change:"+b.idAttribute&&(delete this._byId[b.previous(b.idAttribute)],this._byId[b.id]=b),this.trigger.apply(this,arguments))}});f.each("forEach,each,map,reduce,reduceRight,find,detect,filter,select,reject,every,all,some,any,include,contains,invoke,max,min,sortBy,sortedIndex,toArray,size,first,initial,rest,last,without,indexOf,shuffle,lastIndexOf,isEmpty,groupBy".split(","),function(a){r.prototype[a]=function(){return f[a].apply(f,[this.models].concat(f.toArray(arguments)))}});var v=g.View=function(a){this.cid=f.uniqueId("view");this._configure(a||{});this._ensureElement();this.initialize.apply(this,arguments);this.delegateEvents()},F=/^(\S+)\s*(.*)$/,w="model,collection,el,id,attributes,className,tagName".split(",");f.extend(v.prototype,k,{tagName:"div",$:function(a){return this.$el.find(a)},initialize:function(){},render:function(){return this},remove:function(){this.$el.remove();return this},make:function(a,b,c){a=document.createElement(a);b&&i(a).attr(b);c&&i(a).html(c);return a},setElement:function(a,b){this.$el&&this.undelegateEvents();this.$el=a instanceof i?a:i(a);this.el=this.$el[0];!1!==b&&this.delegateEvents();return this},delegateEvents:function(a){if(a||(a=n(this,"events"))){this.undelegateEvents();for(var b in a){var c=a[b];f.isFunction(c)||(c=this[a[b]]);if(!c)throw Error('Method "'+a[b]+'" does not exist');var d=b.match(F),e=d[1],d=d[2],c=f.bind(c,this),e=e+(".delegateEvents"+this.cid);""===d?this.$el.bind(e,c):this.$el.delegate(d,e,c)}}},undelegateEvents:function(){this.$el.unbind(".delegateEvents"+this.cid)},_configure:function(a){this.options&&(a=f.extend({},this.options,a));for(var b=0,c=w.length;b<c;b++){var d=w[b];a[d]&&(this[d]=a[d])}this.options=a},_ensureElement:function(){if(this.el)this.setElement(this.el,!1);else{var a=n(this,"attributes")||{};this.id&&(a.id=this.id);this.className&&(a["class"]=this.className);this.setElement(this.make(this.tagName,a),!1)}}});o.extend=r.extend=v.extend=function(a,b){var c=G(this,a,b);c.extend=this.extend;return c};var H={create:"POST",update:"PUT","delete":"DELETE",read:"GET"};g.sync=function(a,b,c){var d=H[a];c||(c={});var e={type:d,dataType:"json"};c.url||(e.url=n(b,"url")||t());if(!c.data&&b&&("create"==a||"update"==a))e.contentType="application/json",e.data=JSON.stringify(b.toJSON());g.emulateJSON&&(e.contentType="application/x-www-form-urlencoded",e.data=e.data?{model:e.data}:{});if(g.emulateHTTP&&("PUT"===d||"DELETE"===d))g.emulateJSON&&(e.data._method=d),e.type="POST",e.beforeSend=function(a){a.setRequestHeader("X-HTTP-Method-Override",d)};"GET"!==e.type&&!g.emulateJSON&&(e.processData=!1);return i.ajax(f.extend(e,c))};g.wrapError=function(a,b,c){return function(d,e){e=d===b?e:d;a?a(b,e,c):b.trigger("error",b,e,c)}};var x=function(){},G=function(a,b,c){var d;d=b&&b.hasOwnProperty("constructor")?b.constructor:function(){a.apply(this,arguments)};f.extend(d,a);x.prototype=a.prototype;d.prototype=new x;b&&f.extend(d.prototype,b);c&&f.extend(d,c);d.prototype.constructor=d;d.__super__=a.prototype;return d},n=function(a,b){return!a||!a[b]?null:f.isFunction(a[b])?a[b]():a[b]},t=function(){throw Error('A "url" property or function must be specified');}}).call(this);
['width', 'height'].forEach(function(dimension) {
var offset, Dimension = dimension.replace(/./, function(m) {
return m[0].toUpperCase()
});
$.fn['outer' + Dimension] = function(margin) {
var elem = this;
if (elem) {
var size = elem[dimension]();
var sides = {
'width': ['left', 'right'],
'height': ['top', 'bottom']
};
sides[dimension].forEach(function(side) {
if (margin) size += parseInt(elem.css('margin-' + side), 10);
});
return size;
} else {
return null;
}
};
});
$.fn['end'] = function() {
return this.prevObject || $();
};
(function($) {
var data = {},
dataAttr = $.fn.data,
camelize = $.camelCase,
exp = $.expando = 'Zepto' + (+new Date())
function getData(node, name) {
var id = node[exp],
store = id && data[id]
if (name === undefined) return store || setData(node)
else {
if (store) {
if (name in store) return store[name]
var camelName = camelize(name) if (camelName in store) return store[camelName]
}
return dataAttr.call($(node), name)
}
}
function setData(node, name, value) {
var id = node[exp] || (node[exp] = ++$.uuid),
store = data[id] || (data[id] = attributeData(node)) if (name !== undefined) store[camelize(name)] = valuereturn store
}
function attributeData(node) {
var store = {}
$.each(node.attributes, function(i, attr) {
if (attr.name.indexOf('data-') == 0) store[camelize(attr.name.replace('data-', ''))] = $.zepto.deserializeValue(attr.value)
}) return store
}
$.fn.data = function(name, value) {
return value === undefined ? $.isPlainObject(name) ? this.each(function(i, node) {
$.each(name, function(key, value) {
setData(node, key, value)
})
}) : this.length == 0 ? undefined : getData(this[0], name) : this.each(function() {
setData(this, name, value)
})
}
$.fn.removeData = function(names) {
if (typeof names == 'string') names = names.split(/\s+/) return this.each(function() {
var id = this[exp],
store = id && data[id]
if (store) $.each(names, function() {
delete store[camelize(this)]
})
})
}
})(Zepto);
(function($) {
var touch = {},
touchTimeout, tapTimeout, swipeTimeout, longTapTimeout, longTapDelay = 750,
gesturefunction swipeDirection(x1, x2, y1, y2) {
return Math.abs(x1 - x2) >= Math.abs(y1 - y2) ? (x1 - x2 > 0 ? 'Left' : 'Right') : (y1 - y2 > 0 ? 'Up' : 'Down')
}
function longTap() {
longTapTimeout = nullif(touch.last) {
touch.el.trigger('longTap') touch = {}
}
}
function cancelLongTap() {
if (longTapTimeout) clearTimeout(longTapTimeout) longTapTimeout = null
}
function cancelAll() {
if (touchTimeout) clearTimeout(touchTimeout) if (tapTimeout) clearTimeout(tapTimeout) if (swipeTimeout) clearTimeout(swipeTimeout) if (longTapTimeout) clearTimeout(longTapTimeout) touchTimeout = tapTimeout = swipeTimeout = longTapTimeout = nulltouch = {}
}
function cancelEvent(event) {
event = event || window.event;
if (event.preventDefault) {
event.preventDefault();
event.stopPropagation();
} else {
event.returnValue = false;
event.cancelBubble = true;
}
}
function isPrimaryTouch(event) {
return (event.pointerType == 'touch' || event.pointerType == event.MSPOINTER_TYPE_TOUCH) && event.isPrimary
}
function isPointerEventType(e, type) {
return (e.type == 'pointer' + type || e.type.toLowerCase() == 'mspointer' + type)
}
$.fn.registerTouch = function() {
var now, delta, deltaX = 0,
deltaY = 0,
firstTouch, _isPointerTypeif('MSGesture' in window) {
gesture = new MSGesture() gesture.target = this[0];
}
this.bind('MSGestureEnd', function(e) {
var swipeDirectionFromVelocity = e.velocityX > 1 ? 'Right' : e.velocityX < -1 ? 'Left' : e.velocityY > 1 ? 'Down' : e.velocityY < -1 ? 'Up' : null;
if (swipeDirectionFromVelocity) {
touch.el.trigger('swipe') touch.el.trigger('swipe' + swipeDirectionFromVelocity)
}
}).on('touchstart MSPointerDown pointerdown', function(e) {
if ((_isPointerType = isPointerEventType(e, 'down')) && !isPrimaryTouch(e)) returnfirstTouch = _isPointerType ? e : e.touches[0]
if (e.touches && e.touches.length === 1 && touch.x2) {
touch.x2 = undefinedtouch.y2 = undefined
}
now = Date.now() delta = now - (touch.last || now) touch.el = $('tagName' in firstTouch.target ? firstTouch.target : firstTouch.target.parentNode) touchTimeout && clearTimeout(touchTimeout) touch.x1 = firstTouch.pageXtouch.y1 = firstTouch.pageYif(delta > 0 && delta <= 250) touch.isDoubleTap = truetouch.last = nowlongTapTimeout = setTimeout(longTap, longTapDelay) if (gesture && _isPointerType) gesture.addPointer(e.pointerId);
}).on('touchmove MSPointerMove pointermove', function(e) {
if ((_isPointerType = isPointerEventType(e, 'move')) && !isPrimaryTouch(e)) returnfirstTouch = _isPointerType ? e : e.touches[0] cancelLongTap() touch.x2 = firstTouch.pageXtouch.y2 = firstTouch.pageYvar hDistance = Math.abs(touch.x1 - touch.x2) deltaX += hDistancedeltaY += Math.abs(touch.y1 - touch.y2) if (hDistance > 20) {
var event = $.Event('drag') event.distance = hDistanceevent.direction = (touch.x1 > touch.x2) ? "left" : "right"
touch.el.trigger(event) cancelEvent(e);
}
}).on('touchend MSPointerUp pointerup', function(e) {
if ((_isPointerType = isPointerEventType(e, 'up')) && !isPrimaryTouch(e)) returncancelLongTap() var event = $.Event('dragend') event.distance = touch.x1 - touch.x2;
event.direction = (touch.x1 > touch.x2) ? "left" : "right"
touch.el.trigger(event) if ((touch.x2 && Math.abs(touch.x1 - touch.x2) > 30) || (touch.y2 && Math.abs(touch.y1 - touch.y2) > 30)) swipeTimeout = setTimeout(function() {
touch.el.trigger('swipe') touch.el.trigger('swipe' + (swipeDirection(touch.x1, touch.x2, touch.y1, touch.y2))) touch = {}
}, 0)
else
if ('last' in touch)
if (deltaX < 30 && deltaY < 30) {
tapTimeout = setTimeout(function() {
var event = $.Event('tap') event.cancelTouch = cancelAlltouch.el.trigger(event) if (touch.isDoubleTap) {
if (touch.el) touch.el.trigger('doubleTap') touch = {}
} else {
touchTimeout = setTimeout(function() {
touchTimeout = nullif(touch.el) touch.el.trigger('singleTap') touch = {}
}, 250)
}
}, 0)
} else {
touch = {}
}
deltaX = deltaY = 0
}).on('touchcancel MSPointerCancel pointercancel', cancelAll) $(window).on('scroll', cancelAll)
};
['drag', 'dragend', 'swipe', 'swipeLeft', 'swipeRight', 'swipeUp', 'swipeDown', 'doubleTap', 'tap', 'singleTap', 'longTap'].forEach(function(eventName) {
$.fn[eventName] = function(callback) {
return this.on(eventName, callback)
}
})
})(Zepto);;
(function($, undefined) {
var prefix = '',
eventPrefix, endEventName, endAnimationName, vendors = {
Webkit: 'webkit',
Moz: '',
O: 'o'
},
document = window.document,
testEl = document.createElement('div'),
supportedTransforms = /^((translate|rotate|scale)(X|Y|Z|3d)?|matrix(3d)?|perspective|skew(X|Y)?)$/i,
transform, transitionProperty, transitionDuration, transitionTiming, transitionDelay, animationName, animationDuration, animationTiming, animationDelay, cssReset = {}
function dasherize(str) {
return str.replace(/([a-z])([A-Z])/, '$1-$2').toLowerCase()
}
function normalizeEvent(name) {
return eventPrefix ? eventPrefix + name : name.toLowerCase()
}
$.each(vendors, function(vendor, event) {
if (testEl.style[vendor + 'TransitionProperty'] !== undefined) {
prefix = '-' + vendor.toLowerCase() + '-'
eventPrefix = eventreturn false
}
}) transform = prefix + 'transform'
cssReset[transitionProperty = prefix + 'transition-property'] = cssReset[transitionDuration = prefix + 'transition-duration'] = cssReset[transitionDelay = prefix + 'transition-delay'] = cssReset[transitionTiming = prefix + 'transition-timing-function'] = cssReset[animationName = prefix + 'animation-name'] = cssReset[animationDuration = prefix + 'animation-duration'] = cssReset[animationDelay = prefix + 'animation-delay'] = cssReset[animationTiming = prefix + 'animation-timing-function'] = ''
$.fx = {
off: (eventPrefix === undefined && testEl.style.transitionProperty === undefined),
speeds: {
_default: 400,
fast: 200,
slow: 600
},
cssPrefix: prefix,
transitionEnd: normalizeEvent('TransitionEnd'),
animationEnd: normalizeEvent('AnimationEnd')
}
$.fn.animate = function(properties, duration, ease, callback, delay) {
if ($.isFunction(duration)) callback = duration, ease = undefined, duration = undefinedif($.isFunction(ease)) callback = ease, ease = undefinedif($.isPlainObject(duration)) ease = duration.easing, callback = duration.complete, delay = duration.delay, duration = duration.durationif(duration) duration = (typeof duration == 'number' ? duration : ($.fx.speeds[duration] || $.fx.speeds._default)) / 1000
if (delay) delay = parseFloat(delay) / 1000
return this.anim(properties, duration, ease, callback, delay)
}
$.fn.anim = function(properties, duration, ease, callback, delay) {
var key, cssValues = {},
cssProperties, transforms = '',
that = this,
wrappedCallback, endEvent = $.fx.transitionEnd,
fired = falseif(duration === undefined) duration = $.fx.speeds._default / 1000
if (delay === undefined) delay = 0
if ($.fx.off) duration = 0
if (typeof properties == 'string') {
cssValues[animationName] = propertiescssValues[animationDuration] = duration + 's'
cssValues[animationDelay] = delay + 's'
cssValues[animationTiming] = (ease || 'linear') endEvent = $.fx.animationEnd
} else {
cssProperties = []
for (key in properties)
if (supportedTransforms.test(key)) transforms += key + '(' + properties[key] + ') '
else cssValues[key] = properties[key], cssProperties.push(dasherize(key)) if (transforms) cssValues[transform] = transforms, cssProperties.push(transform) if (duration > 0 && typeof properties === 'object') {
cssValues[transitionProperty] = cssProperties.join(', ') cssValues[transitionDuration] = duration + 's'
cssValues[transitionDelay] = delay + 's'
cssValues[transitionTiming] = (ease || 'linear')
}
}
wrappedCallback = function(event) {
if (typeof event !== 'undefined') {
if (event.target !== event.currentTarget) return$(event.target).unbind(endEvent, wrappedCallback)
}
else$(this).unbind(endEvent, wrappedCallback) fired = true$(this).css(cssReset) callback && callback.call(this)
}
if (duration > 0) {
this.bind(endEvent, wrappedCallback) setTimeout(function() {
if (fired) returnwrappedCallback.call(that)
}, (duration * 1000) + 25)
}
this.size() && this.get(0).clientLeftthis.css(cssValues) if (duration <= 0) setTimeout(function() {
that.each(function() {
wrappedCallback.call(this)
})
}, 0) return this
}
testEl = null
})(Zepto);
(function(SCOPE) {
SCOPE.ErrorDetector = function(iRoll) {
var id = iRoll.get('id'),
that = this;
that.startListener = function() {
SCOPE.Events.on(id + ':video_error', function(e) {
var eventValue = "";
if (e && (e.target instanceof HTMLMediaElement)) {
eventValue = e.target.error.code;
}
that.trigger('video_error', eventValue);
});
SCOPE.Events.on(id + ':video_source_error', function(e) {
var eventValue = "";
if (e && (e.target instanceof HTMLSourceElement)) {
eventValue = e.target.parentNode.networkState;
that.trigger('video_source_error', eventValue);
}
});
SCOPE.Events.on(id + ':video_high_buffering_count', function(count) {
that.trigger('video_high_buffering_count', count);
});
SCOPE.Events.on(id + ':video_long_buffering_time', function(time) {
if (!isNaN(time)) {
that.trigger('video_long_buffering_time', time);
}
});
SCOPE.Events.on(id + ":ad_started", function() {
var winSize = this.canvas.getSize();
if (!winSize.width || !winSize.height) {
that.trigger('bad_window_size_at_video_start');
}
if (this.get('checkForVisibility')) {
if (this.isHidden()) {
that.trigger('document_not_visible_at_video_start');
}
}
var now = _.now();
var LATE_IMPRESSION_THRESHOLD_MS = 3000;
if (now - this.initTimestamp > LATE_IMPRESSION_THRESHOLD_MS) {
that.trigger('late_impression', LATE_IMPRESSION_THRESHOLD_MS);
}
var VERY_LATE_IMPRESSION_THRESHOLD_MS = 5000;
if (now - this.initTimestamp > VERY_LATE_IMPRESSION_THRESHOLD_MS) {
that.trigger('very_late_impression', VERY_LATE_IMPRESSION_THRESHOLD_MS);
}
}, iRoll);
SCOPE.Events.on(id + ':video_started', function() {
var good_duration = true;
var good_currentTime = true;
if (iRoll.get('videoPlayer')) {
var duration = iRoll.get('videoPlayer').getDuration();
var currentTime = iRoll.get('videoPlayer').getCurrentTime();
good_duration = _.isNumber(duration) && isFinite(duration);
good_currentTime = _.isNumber(currentTime) && isFinite(currentTime);
var sendErrorReports = [sendDurationErrorReport, sendCurrentTimeErrorReport, sendDurationAndCurrentTimeErrorReport];
sendErrorReports.forEach(function(sendErrorReport) {
sendErrorReport();
});
}
function sendDurationErrorReport() {
if (!good_duration && good_currentTime) {
that.trigger('video_bad_properties', "duration: " + duration);
}
}
function sendCurrentTimeErrorReport() {
if (!good_currentTime && good_duration) {
that.trigger('video_bad_properties', "currentTime: " + currentTime);
}
}
function sendDurationAndCurrentTimeErrorReport() {
if (!good_duration && !good_currentTime) {
that.trigger('video_bad_properties', "duration: " + duration + "; currentTime: " + currentTime);
}
}
});
SCOPE.Events.on(id + ':container_error', function(message, action) {
var eventValue = "";
if (_.isString(action)) {
eventValue += "(Action:" + action + ")";
}
if (_.isString(message)) {
eventValue += "(Message:" + message + ")";
}
that.trigger('container_error', eventValue);
});
SCOPE.Events.on(id + ':video_videoPassed75', function() {
[25, 50].forEach(function(vp) {
if (!iRoll.report.wasPixelLoaded({
action: 'vpoint',
event_value: vp
})) {
that.trigger('vpoint_missing', vp);
}
});
});
SCOPE.Events.on(id + ":ad_interface_error", function(module, e) {
var msg = e.message ? e.message.substr(0, 500) : "";
that.trigger(module + "_error", msg);
});
SCOPE.Events.on(id + ":video_timeupdate_event_missing", function() {
that.trigger("video_timeupdate_event_missing");
});
window.onerror = _.throttle(function(e) {
if (typeof e === "string") {
that.trigger('js_error', e.substring(0, 256))
}
}, 500);
};
};
_.extend(SCOPE.ErrorDetector.prototype, Backbone.Events);
})(IV);
(function(SCOPE) {
SCOPE.Session = function(config) {
var sampleRateRec = getSampleRateRecord(config);
this.isMonitored = function() {
return sampleRateRec.isMonitored;
};
this.getSampleRate = function() {
return sampleRateRec.sampleRate;
};
function getSampleRateRecord(config) {
var sampleRate = 0,
isMonitored = false;
if (isPreviewMode()) {
sampleRate = 1;
isMonitored = true;
} else if (config["error-monitoring-enabled"]) {
sampleRate = toSampleRate(config["error-monitoring-rate"] || 0);
isMonitored = flipCoin(sampleRate);
}
return {
sampleRate: sampleRate,
isMonitored: isMonitored
}
}
function isPreviewMode() {
return (_.isUndefined(config['placement-config']) || config['placement-config']['placement-hash'] === "-1");
}
function toSampleRate(val) {
var rate = val | 0;
return rate / 100.0;
}
function flipCoin(sampleRate) {
var rand = Math.random(),
result = false;
if (rand < sampleRate) {
result = true;
}
return result;
}
};
_.extend(SCOPE.Session.prototype, Backbone.Events);
})(IV);
(function(SCOPE) {
SCOPE.Canvas = function(iroll, canvasAppender) {
var el = document.createElement("DIV"),
defaultFontSize = 16,
that = this,
currentWidth, currentHeight, currentOrientation;
el.id = "iv-iroll";
canvasAppender.appendToContainer(el);
$(el).one('mouseover', "*", function(event) {
event.stopPropagation();
if (SCOPE.device.getPlatformType() === 'desktop') {
SCOPE.Events.trigger(iroll.get('id') + ':interact');
}
});
function init() {
var adSize = that.getSize();
currentWidth = adSize.width;
currentHeight = adSize.height;
currentOrientation = SCOPE.device.getDeviceOrientation(adSize.width, adSize.height);
setInterval(monitorWindowWidth, 500);
if (typeof $.fn.registerTouch === 'function') {
$(el).registerTouch();
}
$(el).attr("platform-type", SCOPE.device.getPlatformType());
$(el).attr("os-type", SCOPE.device.getOSType());
addMouseCaptureOverlay();
}
function monitorWindowWidth() {
var adSize = that.getSize();
if (currentWidth !== adSize.width || currentHeight !== adSize.height) {
currentWidth = adSize.width;
currentHeight = adSize.height;
SCOPE.Events.trigger('winResize');
}
var newOrientation = SCOPE.device.getDeviceOrientation(adSize.width, adSize.height);
if (currentOrientation !== newOrientation) {
currentOrientation = newOrientation;
SCOPE.Events.trigger('orientationChange');
}
$(el).attr("orientation", newOrientation);
}
function addMouseCaptureOverlay() {
var overlay = buildResponsiveContainer();
overlay.addClass("iv-mouse-capture-overlay");
$(el).append(overlay);
$(overlay).on(iroll.getVideoClickEventType(), function(ev) {
SCOPE.Events.trigger("video_click", ev);
});
$(overlay).on("touchmove", function(ev) {
ev.preventDefault();
})
}
function buildResponsiveContainer(className) {
var cont = $('<div/>'),
sizes = that.getSize();
cont.addClass(className);
cont.width(sizes.width).height(sizes.height);
SCOPE.Events.on('winResize', function() {
var newSizes = that.getSize();
cont.width(newSizes.width).height(newSizes.height);
});
return cont;
}
this.addElement = function(elem) {
if (elem) {
$(el).append(elem);
}
};
this.addResponsiveElement = function(elem) {
if (elem) {
var cont = buildResponsiveContainer("iv-elem-cont");
cont.append(elem);
$(el).append(cont);
}
};
this.getSize = function() {
return canvasAppender.getSize();
};
this.getScale = function() {
var adSize = this.getSize(),
config = iroll.get('config'),
platformScale = SCOPE.toolkit.getPlatformScaleParameter(config.platformScaling) var maxAdDimension = Math.max(adSize.width, adSize.height),
adScale = maxAdDimension / config.previewParam.width;
return adScale / platformScale;
};
this.getDefaultFontSize = function() {
return defaultFontSize
};
this.setScale = function(scale) {
$(el).css({
fontSize: scale
});
};
this.remove = function() {
if (el !== null) {
while (el.firstChild) {
el.removeChild(el.firstChild);
}
el.parentNode.removeChild(el);
el = null;
}
};
this.injectCss = function(cssPath) {
var ownerDoc = el.ownerDocument;
var linkRef = ownerDoc.createElement("link");
linkRef.setAttribute("rel", "stylesheet");
linkRef.setAttribute("type", "text/css");
linkRef.setAttribute("href", cssPath);
(ownerDoc.head || ownerDoc.getElementsByTagName("head")[0]).appendChild(linkRef);
};
this.registerInteractEvent = function() {
$(el).on(iroll.get('mainEngagementEvent'), "*", function(event) {
event.stopPropagation();
$(event.currentTarget).trigger("interact", event);
});
$(el).on(iroll.getVideoClickEventType(), "*", function(event) {
event.stopPropagation();
$(event.currentTarget).trigger("interact-to-play", event);
});
};
init.apply(this);
};
})(IV);
(function(SCOPE) {
SCOPE.AppsCore = Backbone.Model.extend({
defaults: {
sendLogs: false,
playStartTime: null,
interface: null,
debug: false,
autoscale: false,
appPath: '',
servicePath: '',
nonCdnServicePath: '',
reportUrl: '',
errorReportUrl: '',
runtimeConfigUrl: '',
version: 'unknown',
el: null,
mainContainer: null,
videoContainer: null,
appsContainer: null,
durationBar: null,
plugins: {},
data: {},
config: {},
toolbar: null,
id: null,
sysLog: [],
CloseButton: false,
BackButton: false,
CloseButtonTimeout: 5000,
windowOpen: null,
appModeCustomEvents: {
iOSPauseURL: 'EXTENSION_STOP',
iOSPlayURL: 'EXTENSION_PLAY',
iOSClickThrewURL: 'EXTENSION_OPEN_URL:'
},
showClickToResume: true,
delayAppVisibility: true,
mainEngagementEvent: 'tap',
displayVideo: true,
supportHLS: true,
inlinePlaybackForced: false,
videoPlayer: null,
enableErrorReporting: true,
checkForVisibility: false,
linearOverStream: false,
reportDummyErrorPixel: false,
sessionMonitoringRate: 1,
reportImpressionsToLog: true,
reportEventsToConsole: false,
initialized: false,
waitForCreativeToLoad: false,
wrapCreativeWithIframe: false
},
canvas: null,
session: null,
report: null,
errorDetector: null,
videoClickHandler: null,
initTimestamp: 0,
progressReporter: null,
macroMapper: null,
initialize: function() {
var that = this,
baseData = SCOPE.baseData;
if (!this.get('autoscale')) {
$('head').append('<meta name="viewport" content="user-scalable=no, initial-scale=1, maximum-scale=1, ' + 'minimum-scale=1, width=device-width, target-densitydpi=device-dpi">');
}
new SCOPE.DataInjector().injectCustomParams(this);
this.set({
'appPath': baseData.appPath,
'servicePath': baseData.servicePath,
'nonCdnServicePath': baseData.nonCdnServicePath,
'cssPath': baseData.cssPath,
'reportUrl': baseData.reportUrl,
'errorReportUrl': baseData.errorReportUrl,
'runtimeConfigUrl': baseData.runtimeConfigUrl,
'version': baseData.mobileCoreVersion
});
this.set('id', _.uniqueId('IV_'));
if (!this.get('sendLogs')) {
this.bindTrackingEvents();
}
this.set("canvasAppender", new SCOPE.CanvasAppender(this));
this.session = new SCOPE.Session(baseData.app_data);
this.macroMapper = new SCOPE.MacroMapper(this.get('data'));
var iframeInjector = new SCOPE.FriendlyIframeInjector(SCOPE.ThirdPartyTrackingReporter.THIRD_PARTY_TRACKING_IFRAME_ID);
var htmlTagInjector = new SCOPE.HtmlTextTagInjector(iframeInjector);
var thirdPartyTrackingReporter = new SCOPE.ThirdPartyTrackingReporter(htmlTagInjector, this.macroMapper);
this.report = this.report || new SCOPE.reportAnalytics({
instance: this.toJSON(),
instanceClass: this,
session: this.session,
thirdPartyTrackingReporter: thirdPartyTrackingReporter
});
this.bindErrorEvents();
this.on('init', function() {
that.bindAnalyticsEvents();
that.bindSystemEvents();
var id = that.get('id');
SCOPE.Events.on(id + ':video_videoPassed1Sec', function() {
if (that.get('delayAppVisibility')) {
$(".iv-in-app-icon, #iv-tray, .iv-floating-icon-container").css({
"visibility": "visible"
});
}
});
that.createCanvas();
SCOPE.Events.trigger("IRollInit", that);
that.initTimestamp = new Date().getTime();
if (!that.shouldWaitForCreativeToLoad()) {
that.set('initialized', true);
SCOPE.Events.trigger(id + ':core_initialized', that);
}
});
SCOPE.Events.on(this.get('id') + ':appClickThru', function() {
if (this.get('videoPlayer') && this.get('videoPlayer').isPlaying()) {
this.get('videoPlayer').pause();
}
}, that);
},
shouldWaitForCreativeToLoad: function() {
return !!this.get("waitForCreativeToLoad");
},
shouldWrapCreativeWithIframe: function() {
return !!this.get("wrapCreativeWithIframe");
},
setAttribute: function(attrs) {
if (_.isObject(attrs)) {
this.set(attrs, {
silent: true
});
}
},
$log: function() {
if (this.get('debug')) {}
},
injectVideo: function() {
var data = this.get('data'),
that = this;
if (!this.has('videoPlayer')) {
this.set('videoPlayer', new SCOPE.InternalVideoPlayer(this));
}
this.get('videoPlayer').init(data, this);
if (data.video) {
this.loadVideoSource(data.video.renditions, this);
}
this.videoClickHandler = new SCOPE.VideoClickHandler(this, SCOPE.baseData, SCOPE.Events, this.macroMapper);
this.get('videoPlayer').on("interact", function(ev) {
that.videoClickHandler.handleClick(ev);
});
},
loadVideoSource: function(renditions) {
if (this.get('linearOverStream') !== true) {
this.get('videoPlayer').loadVideoSource(renditions);
}
},
injectCSSToDoc: function() {
this.canvas.injectCss(this.get('cssPath'));
},
removeVideo: function() {
if (this.get('videoPlayer')) {
this.get('videoPlayer').pause();
}
},
cleanUp: function() {
SCOPE.Events.off();
if (this.get('videoPlayer') && typeof this.get('videoPlayer').cleanUp === 'function') {
this.get('videoPlayer').cleanUp();
}
this.canvas.remove();
},
initAppsSystem: function() {
if (this.get('reportDummyErrorPixel')) {
this.report.reportLog({
event_id: 'dummy'
});
}
if (this.get('displayVideo')) {
this.injectVideo();
}
SCOPE.Events.trigger('IRollReady', this, this.get('data'));
SCOPE.Events.trigger(this.get('id') + ':impression', this);
},
createCanvas: function() {
var canvasContainer = null;
if (_.isNull(this.get("mainContainer"))) {
canvasContainer = document.body;
} else {
canvasContainer = this.get("mainContainer");
}
var canvasAppender = this.get("canvasAppender");
canvasAppender.setContainer(canvasContainer);
this.canvas = new SCOPE.Canvas(this, canvasAppender);
},
windowOpen: function(url) {
url = new SCOPE.MacroMapper(this.get('data')).expandAll(url);
SCOPE.Events.trigger(this.get('id') + ':openUrl', url);
SCOPE.Events.trigger(this.get('id') + ':appClickThru', url);
if (_.isFunction(this.get('interface')['windowOpen'])) {
this.get('interface')['windowOpen'](url);
}
},
supportFeature: function(feature) {
var externalInterface = this.get('interface');
if (externalInterface !== null && typeof externalInterface.supports === 'function') {
return externalInterface.supports(feature);
} else {
return false;
}
},
onInteract: function(elem, func) {
elem.on(this.get('mainEngagementEvent'), func);
},
reportEngage: function(eventId) {
var that = this;
that.report.submit({
action: 'engage',
event_id: eventId
});
SCOPE.Events.trigger(that.get('id') + ":engage");
},
reportInteract: function() {
this.report.submit({
action: 'intrct'
});
this.fireTrackingEvent('adFirstInteraction');
},
bindAnalyticsEvents: function() {
var that = this,
id = this.get('id'),
playFired = false,
engaged = false,
interactedBeforePlay = false,
customMetrics = that.get('data').customMetrics;
SCOPE.Events.on(id + ':userClick', function() {
if (engaged) {
return;
}
engaged = true;
that.reportEngage('user');
});
SCOPE.Events.on(id + ':auto_engage', function() {
if (engaged) {
return;
}
engaged = true;
that.reportEngage('default');
});
SCOPE.Events.on(id + ':core_initialized', function() {
that.report.submit({
action: 'init',
size: $(window).width() + 'x' + $(window).height()
});
});
SCOPE.Events.on(id + ':interact', _.once(function() {
if (playFired) {
that.reportInteract();
} else {
interactedBeforePlay = true;
}
}));
this.progressReporter = new SCOPE.AdProgressReporter(id, this.report, customMetrics, this.fireTrackingEvent.bind(this));
this.progressReporter.startReporting(function() {
playFired = true;
that.set({
playStartTime: new Date().getTime()
});
if (that.get('reportImpressionsToLog')) {
that.report.reportLog({
event_id: 'impression'
});
}
if (interactedBeforePlay) {
that.reportInteract();
}
});
},
bindSystemEvents: function() {
SCOPE.Events.on('appsDataReady', this.initAppsSystem, this);
SCOPE.Events.on('startApps', this.initAppsSystem, this);
SCOPE.Events.on('orientationchange', function() {
SCOPE.Events.trigger('repaint');
});
this.on('start', this.initAppsSystem, this);
},
bindTrackingEvents: function() {
var that = this,
id = this.get('id');
var eventsList = {};
if (_.isObject(this.get('data')['placement-config'])) {
eventsList = this.get('data')['placement-config']['tracking-events'];
}
_.forEach(eventsList, function(trackingItems, eventName) {
var handler = _.bind(that.reportTrackingEvent, that, eventName, trackingItems);
SCOPE.Events.on(id + ':tracking:' + eventName, handler);
});
},
bindErrorEvents: function() {
this.errorDetector = new SCOPE.ErrorDetector(this);
this.errorDetector.on("all", function(eventId, eventValue) {
this.report.reportLog({
event_id: eventId,
event_value: eventValue || ''
});
}, this);
this.errorDetector.startListener();
},
fireTrackingEvent: function(eventName) {
var id = this.get('id'),
event = id + ':tracking:' + eventName;
SCOPE.Events.trigger(event);
},
reportTrackingEvent: function(eventName, trackingItems) {
this.report.submit3rdPartyTracking(trackingItems);
},
getVideoClickEventType: function() {
if (SCOPE.device.needsClickEventToPlay()) {
return 'click';
} else {
return this.get('mainEngagementEvent');
}
},
isHidden: function() {
var prop = SCOPE.device.getHiddenProp();
if (!prop) return false;
return document[prop];
}
});
})(IV);
(function(SCOPE) {
if (_.isUndefined(SCOPE.Events)) {
SCOPE.Events = function() {};
_.extend(SCOPE.Events, Backbone.Events);
}
})(IV);
(function(SCOPE) {
SCOPE.VideoSpy = function(videoElem) {
this.videoElem = videoElem;
this.state = null;
var instance = this,
activityLog = new SCOPE.ActivityLog(),
passedPoints = {
pass1sec: false,
pass25: false,
pass50: false,
pass75: false,
cvv: false
},
customPoint = null,
lastPlayingTime = 0,
timeUpdateIntervalId = 0,
timeUpdateEventFired = false,
lastTimeUpdated = 0;
this.MAX_BUFFERING_COUNT = 5;
this.MAX_BUFFERING_TIMES = [4000, 6000, 8000];
this.SHORT_BUFFERING_TIME = 200;
this.setCustomPoint = function(time) {
customPoint = time
};
function fireEvent(eventName, newState, ev) {
instance.trigger(eventName, ev);
if (newState) {
if (isValidState(newState)) {
instance.state = newState;
activityLog.log(newState);
} else {
throw ("invalid video state");
}
}
}
function fireErrorEvent(errorType, ev) {
instance.trigger(errorType, ev);
}
function isValidState(state) {
var validStates = ['playing', 'paused', 'ended'];
return (validStates.indexOf(state) != -1);
}
function onTimeUpdate(elem, ev) {
timeUpdateEventFired = true;
updateTime(elem, ev);
}
function playingHeartbeat(currentTime) {
lastPlayingTime = currentTime;
activityLog.log('playing');
}
function setPassedPoint(currentTime, duration) {
var currentProgress = 100 * currentTime / duration;
if (currentTime > 1 && !passedPoints.pass1sec) {
passedPoints.pass1sec = true;
fireEvent('video_videoPassed1Sec', null);
}
if (currentProgress > 25 && !passedPoints.pass25) {
passedPoints.pass25 = true;
fireEvent('video_videoPassed25', null);
}
if (currentProgress > 50 && !passedPoints.pass50) {
passedPoints.pass50 = true;
fireEvent('video_videoPassed50', null);
}
if (currentProgress > 75 && !passedPoints.pass75) {
passedPoints.pass75 = true;
fireEvent('video_videoPassed75', null);
}
if (customPoint !== null) {
if (currentTime > customPoint && !passedPoints.cvv) {
passedPoints.cvv = true;
fireEvent('video_videoPassedCustomPoint', null);
}
}
}
function startBackupTimeUpdate() {
timeUpdateIntervalId = setInterval(updateTime.bind({}, videoElem), 500);
}
function stopBackupTimeUpdate() {
if (timeUpdateIntervalId) clearInterval(timeUpdateIntervalId);
timeUpdateIntervalId = 0;
}
function missingTimeUpdateCheck() {
if (!timeUpdateEventFired) instance.trigger("video_timeupdate_event_missing");
}
function updateTime(elem, ev) {
if (lastTimeUpdated !== elem.getCurrentTime() && isFinite(elem.getCurrentTime()) && !isNaN(elem.getCurrentTime())) {
lastTimeUpdated = elem.getCurrentTime();
var tDelta = (elem.getCurrentTime() - lastPlayingTime);
if (tDelta > 1.0) {
playingHeartbeat(elem.getCurrentTime());
}
setPassedPoint(elem.getCurrentTime(), elem.getDuration());
var data = {
"currentTime": elem.getCurrentTime(),
"duration": elem.getDuration(),
"ev": ev
};
fireEvent('video_timeupdate', null, data);
}
}
videoElem.on('stalled', function() {
if (instance.state !== "paused") {
activityLog.log('buffering');
fireEvent("buffering", null);
}
});
videoElem.on('waiting', function() {
if (instance.state !== "paused") {
activityLog.log('buffering');
fireEvent("buffering", null);
}
});
videoElem.on('playing', function() {
activityLog.log('playing');
});
videoElem.on('playing', _.once(startBackupTimeUpdate));
videoElem.on('ended', stopBackupTimeUpdate);
videoElem.on('ended', missingTimeUpdateCheck);
videoElem.on('durationchange', fireEvent.bind({}, 'video_durationchange', null));
videoElem.on('playing', fireEvent.bind({}, 'video_play', 'playing'));
videoElem.on('playing', _.once(fireEvent.bind({}, 'video_started', null)));
videoElem.on('pause', fireEvent.bind({}, 'video_pause', 'paused'));
videoElem.on('timeupdate', onTimeUpdate.bind({}, videoElem));
videoElem.on('ended', fireEvent.bind({}, 'video_ended', 'ended'));
videoElem.on('webkitendfullscreen', fireEvent.bind({}, 'video_exitfullscreen', null));
videoElem.on('error', fireErrorEvent.bind({}, 'video_error'));
_.each(videoElem.getAllSourceChildren(), function(elem) {
$(elem).on('error', fireErrorEvent.bind({}, 'video_source_error'));
});
activityLog.onCount('buffering', this.MAX_BUFFERING_COUNT, fireErrorEvent.bind({}, 'video_high_buffering_count', this.MAX_BUFFERING_COUNT));
_.each(this.MAX_BUFFERING_TIMES, function(time) {
activityLog.onTime('buffering', time, fireErrorEvent.bind({}, 'video_long_buffering_time', time));
});
activityLog.onTime('buffering', this.SHORT_BUFFERING_TIME, fireEvent.bind({}, "video_short_buffering_time", null));
};
_.extend(SCOPE.VideoSpy.prototype, Backbone.Events);
})(IV);
var IV;
(function(IV) {
var AdProgressReporter = (function() {
function AdProgressReporter(irollId, reporter, customMetrics, trackingEventCallback) {
this.irollId = irollId;
this.reporter = reporter;
this.customMetrics = customMetrics;
this.trackingEventCallback = trackingEventCallback;
this.playReported = false;
}
AdProgressReporter.prototype.startReporting = function(playCallback) {
var _this = this;
var completeCallback = _.once(function() {
_this.reportAdComplete();
});
this.playCallback = function() {
_this.playReported = true;
playCallback();
};
IV.Events.on(this.irollId + ":ad_play", _.once(function(forceImmediateImpression) {
if (typeof forceImmediateImpression === "undefined") {
forceImmediateImpression = false;
}
if (forceImmediateImpression) {
_this.reportAdPlay();
} else {
_this.waitForTimeUpdateBeforeImpression(function() {
_this.reportAdPlay();
});
}
}));
IV.Events.on(this.irollId + ":video_videoPassed25", _.once(function() {
_this.reportAdFirstQuartile();
}));
IV.Events.on(this.irollId + ":video_videoPassed50", _.once(function() {
_this.reportAdMidpoint();
}));
IV.Events.on(this.irollId + ":video_videoPassed75", _.once(function() {
_this.reportAdThirdQuartile();
}));
["video_ended", "ad_ended"].forEach(function(eventName) {
IV.Events.on(_this.irollId + ":" + eventName, completeCallback);
});
IV.Events.on(this.irollId + ":video_videoPassedCustomPoint", function() {
_this.customMetrics.forEach(function(url) {
_this.reporter.submit3rdPartyTracking([{
data: url,
type: IV.ThirdPartyTrackingReporter.URL_TRACKING_TYPE
}]);
});
});
};
AdProgressReporter.prototype.waitForTimeUpdateBeforeImpression = function(callback) {
var _this = this;
var onTimeUpdate = function(data) {
if (typeof data.currentTime !== "undefined" && data.currentTime > 0) {
IV.Events.off(_this.irollId + ":video_timeupdate", onTimeUpdate);
callback();
}
};
IV.Events.on(this.irollId + ":video_timeupdate", onTimeUpdate);
};
AdProgressReporter.prototype.reportAdPlay = function() {
IV.Events.trigger(this.irollId + ":videoStarted");
IV.Events.trigger(this.irollId + ":ad_started");
this.reporter.submit({
action: "play"
});
this.trackingEventCallback("playingStart");
this.playCallback();
};
AdProgressReporter.prototype.reportAdFirstQuartile = function() {
this.reporter.submit({
action: "vpoint",
event_value: 25,
event_id: "percent"
});
this.trackingEventCallback("playingFirstQuartile");
};
AdProgressReporter.prototype.reportAdMidpoint = function() {
this.reporter.submit({
action: "vpoint",
event_value: 50,
event_id: "percent"
});
this.trackingEventCallback("playingMidpoint");
};
AdProgressReporter.prototype.reportAdThirdQuartile = function() {
this.reporter.submit({
action: "vpoint",
event_value: 75,
event_id: "percent"
});
this.trackingEventCallback("playingThirdQuartile");
};
AdProgressReporter.prototype.reportAdComplete = function() {
this.reporter.submit({
action: "vpoint",
event_value: 100,
event_id: "percent"
});
this.trackingEventCallback("playingComplete");
};
return AdProgressReporter;
})();
IV.AdProgressReporter = AdProgressReporter;
})(IV || (IV = {}));
var IV;
(function(IV) {
var CanvasAppender = (function() {
function CanvasAppender(core) {
this.core = core;
}
CanvasAppender.prototype.getSize = function() {
var externalInterface = this.core.get("interface");
if (externalInterface !== null && _.isFunction(externalInterface.getAdSize)) {
return externalInterface.getAdSize();
} else {
return {
"width": $(window).width(),
"height": $(window).height()
};
}
};
CanvasAppender.prototype.setContainer = function(mainContainer) {
this.mainContainer = mainContainer;
};
CanvasAppender.prototype.appendToContainer = function(elem) {
this.mainContainer.appendChild(elem);
};
return CanvasAppender;
})();
IV.CanvasAppender = CanvasAppender;
})(IV || (IV = {}));
var IV;
(function(IV) {
var DataInjector = (function() {
function DataInjector(qstRdr, tool) {
if (qstRdr === void 0) {
qstRdr = new IV.QueryStringReader();
}
if (tool === void 0) {
tool = IV.toolkit;
}
this.tool = tool;
this.qstRdr = qstRdr;
}
DataInjector.prototype.injectCustomParams = function(core) {
var htmldata = DataInjector.HTML_DATA;
var ecp = DataInjector.EXTERNAL_CUSTOM_PARAMETERS;
var newData = core.get("data") || {};
newData[htmldata] = newData[htmldata] || {};
newData[htmldata][ecp] = this.getCustomParams();
core.set("data", newData);
};
DataInjector.prototype.getCustomParams = function() {
var ret = this.qstRdr.getExternalCustomParams(IV._currentScript, document.location.search);
return ret.hasOwnProperty("ivc") ? this.tool.parseQueryString(ret["ivc"]) : ret;
};
DataInjector.HTML_DATA = "html-custom-data";
DataInjector.EXTERNAL_CUSTOM_PARAMETERS = "EXTERNAL_CUSTOM_PARAMETERS";
return DataInjector;
})();
IV.DataInjector = DataInjector;
})(IV || (IV = {}));
var IV;
(function(IV) {
var HtmlTextTagInjector = (function() {
function HtmlTextTagInjector(iframeInjector) {
this.iframeInjector = iframeInjector;
}
HtmlTextTagInjector.prototype.injectTextTagIntoIframe = function(textTag) {
var injectedIframe = this.iframeInjector.injectIframeIntoDoc(document);
var ifrDoc = injectedIframe.contentWindow.document;
this.writeTextTagInsideIframe(ifrDoc, textTag);
};
HtmlTextTagInjector.prototype.writeTextTagInsideIframe = function(ifrDoc, textTag) {
var _this = this;
textTag = this.trimStratEndWhiteSpaces(textTag);
textTag = this.addBackslashBeforeApostropheMark(textTag);
textTag = this.splitScriptTag(textTag);
var iframeHTML = "<html><body marginwidth='0' marginheight='0' topmargin='0' leftmargin='0'><scr" + "ipt>";
var codeLines = this.splitTextTagIntoLines(textTag);
codeLines.forEach(function(line) {
iframeHTML += "document.write('" + _this.trimStratEndWhiteSpaces(line) + "');\n";
});
iframeHTML += "</scr" + "ipt></body></html>";
ifrDoc.open().write("" + iframeHTML);
ifrDoc.close();
};
HtmlTextTagInjector.prototype.trimStratEndWhiteSpaces = function(text) {
return text.replace(/^\s+|\s+$/g, "");
};
HtmlTextTagInjector.prototype.addBackslashBeforeApostropheMark = function(text) {
return text.replace(/'/ig, "\\'");
};
HtmlTextTagInjector.prototype.splitScriptTag = function(text) {
text = text.replace(/<script/ig, "<scr\' + \'ipt");
return text.replace(/\/script>/ig, "/scr\' + \'ipt>");
};
HtmlTextTagInjector.prototype.splitTextTagIntoLines = function(text) {
var tempCode = text.replace(/(\r\n|\n|\r)/gm, "!!NEWLINE!!");
return tempCode.split("!!NEWLINE!!");
};
return HtmlTextTagInjector;
})();
IV.HtmlTextTagInjector = HtmlTextTagInjector;
})(IV || (IV = {}));
var IV;
(function(IV) {
var InnovidLogger = (function() {
function InnovidLogger(debugMode, toolKit) {
if (toolKit === void 0) {
toolKit = IV.toolkit;
}
this.debugMode = debugMode;
this.toolKit = toolKit;
}
Object.defineProperty(InnovidLogger, "DEBUG_MODE", {
get: function() {
return "[INNOVID.DEBUG]";
},
enumerable: true,
configurable: true
});
InnovidLogger.prototype.debug = function() {
var valuesToWrite = [];
for (var _i = 0; _i < arguments.length; _i++) {
valuesToWrite[_i - 0] = arguments[_i];
}
if (this.debugMode) {
var now = this.toolKit.generateDate();
var message = "[" + now + "]" + InnovidLogger.DEBUG_MODE + " " + valuesToWrite.join(" ");
console.log(message);
}
};
return InnovidLogger;
})();
IV.InnovidLogger = InnovidLogger;
})(IV || (IV = {}));
var IV;
(function(IV) {
var MacroMapper = (function() {
function MacroMapper(data, htmlData, ecp) {
if (data === void 0) {
data = {};
}
if (htmlData === void 0) {
htmlData = IV.DataInjector.HTML_DATA;
}
if (ecp === void 0) {
ecp = IV.DataInjector.EXTERNAL_CUSTOM_PARAMETERS;
}
var customData = data[htmlData] || {};
this.publisherValues = customData[ecp] || {};
}
Object.defineProperty(MacroMapper, "CDATA_OPEN", {
get: function() {
return "<![CDATA[";
},
enumerable: true,
configurable: true
});
Object.defineProperty(MacroMapper, "CDATA_CLOSE", {
get: function() {
return "]]>";
},
enumerable: true,
configurable: true
});
Object.defineProperty(MacroMapper, "CDATA_MACRO_OPEN", {
get: function() {
return /(\$\$__CDATA__\$\$)/;
},
enumerable: true,
configurable: true
});
Object.defineProperty(MacroMapper, "CDATA_MACRO_END", {
get: function() {
return /(\$\$__CDATA_CLOSE__\$\$)/;
},
enumerable: true,
configurable: true
});
MacroMapper.prototype.expandSessionId = function(trackingData, sessionId) {
if (trackingData === void 0) {
trackingData = "";
}
return this.expandStaticMacro(/(\{iv_sessionid\})/ig, sessionId, trackingData);
};
MacroMapper.prototype.expandTimeStamp = function(trackingData) {
if (trackingData === void 0) {
trackingData = "";
}
return this.expandStaticMacro(/(\[timestamp\])/ig, (new Date().getTime()).toString(), trackingData);
};
MacroMapper.prototype.expandAll = function(pixel) {
var macrosInPixel = _.uniq(pixel.match(/(%257B|{|%7B)ivc_\w+(%257D|}|%7D)/ig));
return this.foundMatches(macrosInPixel) ? this.expand(macrosInPixel, pixel) : pixel;
};
MacroMapper.prototype.fixCDATA = function(blob) {
var fixedCdataOpen = this.expandStaticMacro(MacroMapper.CDATA_MACRO_OPEN, MacroMapper.CDATA_OPEN, blob);
return this.expandStaticMacro(MacroMapper.CDATA_MACRO_END, MacroMapper.CDATA_CLOSE, fixedCdataOpen);
};
MacroMapper.prototype.expandStaticMacro = function(pattern, replace, reportUrl) {
if (reportUrl === void 0) {
reportUrl = "";
}
reportUrl = _.isArray(reportUrl) ? IV.toolkit.trim(reportUrl.shift() || "") : IV.toolkit.trim(reportUrl);
return pattern.exec(reportUrl) ? reportUrl.replace(pattern, replace) : reportUrl;
};
MacroMapper.prototype.encode = function(value, macro) {
var encodeTwice = /(%7B)ivc_\w+(%7D)/ig,
encodeOnce = /({)ivc_\w+(})/ig;
return encodeOnce.test(macro) ? encodeURIComponent(value) : encodeTwice.test(macro) ? encodeURIComponent(encodeURIComponent(value)) : encodeURIComponent(encodeURIComponent(encodeURIComponent(value)));
};
MacroMapper.prototype.expand = function(macrosInPixel, pixel) {
var _this = this;
macrosInPixel.forEach(function(macro) {
var key = macro.replace(/{|}|%7B|%7D|%257B|%257D/ig, "");
pixel = _this.publisherValues.hasOwnProperty(key) ? pixel.replace(macro, _this.encode(_this.publisherValues[key], macro)) : pixel.replace(macro, "");
});
return pixel;
};
MacroMapper.prototype.foundMatches = function(arr) {
return arr && arr.length > 0;
};
return MacroMapper;
})();
IV.MacroMapper = MacroMapper;
})(IV || (IV = {}));
var IV;
(function(IV) {
var SkipAdHandler = (function() {
function SkipAdHandler(iroll) {
this.iroll = iroll;
}
SkipAdHandler.prototype.skipAd = function() {
IV.Events.trigger(this.iroll.get('id') + ":skip");
var reporter = this.iroll.report;
reporter.submit({
action: 'skip',
relative_time: (new Date().getTime() - this.iroll.get('playStartTime'))
});
IV.Events.trigger(this.iroll.get('id') + ':close');
};
return SkipAdHandler;
})();
IV.SkipAdHandler = SkipAdHandler;
})(IV || (IV = {}));
var IV;
(function(IV) {
var ThirdPartyTrackingReporter = (function() {
function ThirdPartyTrackingReporter(htmlTagInjector, mapper) {
this.mapper = mapper;
this.htmlTagInjector = htmlTagInjector;
}
Object.defineProperty(ThirdPartyTrackingReporter, "URL_TRACKING_TYPE", {
get: function() {
return "url-tracking";
},
enumerable: true,
configurable: true
});
Object.defineProperty(ThirdPartyTrackingReporter, "HTML_TRACKING_TYPE", {
get: function() {
return "html-tracking";
},
enumerable: true,
configurable: true
});
Object.defineProperty(ThirdPartyTrackingReporter, "INJECT_HTML_TRACKING_ERROR", {
get: function() {
return "inject-html-tracking-tag-error";
},
enumerable: true,
configurable: true
});
Object.defineProperty(ThirdPartyTrackingReporter, "THIRD_PARTY_TRACKING_IFRAME_ID", {
get: function() {
return "3rdparty-tracking";
},
enumerable: true,
configurable: true
});
ThirdPartyTrackingReporter.prototype.report = function(trackingData, trackingType, sessionId, firePixelCb, reportLogCb) {
trackingData = this.mapper.expandAll(this.mapper.expandTimeStamp(this.mapper.expandSessionId(trackingData, sessionId)));
if (trackingType === null || trackingType === ThirdPartyTrackingReporter.URL_TRACKING_TYPE) {
this.firePixel(trackingData, firePixelCb);
} else if (trackingType === ThirdPartyTrackingReporter.HTML_TRACKING_TYPE) {
this.injectHtmlTextTag(trackingData, reportLogCb);
}
};
ThirdPartyTrackingReporter.prototype.firePixel = function(trackingData, firePixelCb) {
firePixelCb(trackingData);
};
ThirdPartyTrackingReporter.prototype.injectHtmlTextTag = function(trackingData, reportLogCb) {
try {
this.htmlTagInjector.injectTextTagIntoIframe(this.mapper.fixCDATA(trackingData));
} catch (e) {
reportLogCb({
event_id: ThirdPartyTrackingReporter.INJECT_HTML_TRACKING_ERROR,
event_value: e.message + ": " + trackingData
});
}
};
return ThirdPartyTrackingReporter;
})();
IV.ThirdPartyTrackingReporter = ThirdPartyTrackingReporter;
})(IV || (IV = {}));
var IV;
(function(IV) {
var VideoClickBehaviour;
(function(VideoClickBehaviour) {
VideoClickBehaviour[VideoClickBehaviour["CLICKTHRU"] = 0] = "CLICKTHRU";
VideoClickBehaviour[VideoClickBehaviour["OPEN_MICROSITE"] = 1] = "OPEN_MICROSITE";
VideoClickBehaviour[VideoClickBehaviour["DO_NOTHING"] = 2] = "DO_NOTHING";
})(VideoClickBehaviour || (VideoClickBehaviour = {}));
var VideoClickHandler = (function() {
function VideoClickHandler(core, adConfig, eventBus, mapper) {
this.core = core;
this.adConfig = adConfig;
this.eventBus = eventBus;
this.mapper = mapper;
}
VideoClickHandler.prototype.handleClick = function(ev) {
this.core.report.submit({
action: "click",
event_id: "position",
event_value: ev.pageX + "x" + ev.pageY,
relative_time: (_.now() - this.core.get("playStartTime"))
});
var clickBehaviour = this.detectClickBehaviour();
if (clickBehaviour === VideoClickBehaviour.OPEN_MICROSITE) {
this.handleMicrositeBehaviour();
} else if (clickBehaviour === VideoClickBehaviour.CLICKTHRU) {
this.handleClickthruBehaviour();
ev.stopPropagation();
ev.preventDefault();
}
};
VideoClickHandler.prototype.detectClickBehaviour = function() {
var clickBehaviour = VideoClickBehaviour.DO_NOTHING;
var data = this.adConfig.app_data;
var toolbar = data["toolbar"];
var isMicrosite = toolbar && toolbar.data.engagementType === "minisite";
if (isMicrosite && (!toolbar.data.clickBehavior || toolbar.data.clickBehavior === "open-microsite")) {
clickBehaviour = VideoClickBehaviour.OPEN_MICROSITE;
} else if (data["video-clicks"] && data["video-clicks"]["click-thru-url"]) {
clickBehaviour = VideoClickBehaviour.CLICKTHRU;
}
return clickBehaviour;
};
VideoClickHandler.prototype.handleMicrositeBehaviour = function() {
this.eventBus.trigger("openMicrosite", true);
};
VideoClickHandler.prototype.handleClickthruBehaviour = function() {
var clickthruUrl = this.adConfig.app_data["video-clicks"]["click-thru-url"];
clickthruUrl = this.mapper.expandAll(clickthruUrl);
var videoPlayer = this.core.get("videoPlayer");
videoPlayer.pause();
this.core.report.submit({
action: "clktru",
event_id: "main",
relative_time: (_.now() - this.core.get("playStartTime"))
});
var coreId = this.core.get("id");
this.eventBus.trigger(coreId + ":userClick");
this.eventBus.trigger(coreId + ":openUrl", clickthruUrl);
this.reportTrackingUrl();
if (_.isFunction(this.core.get("interface")["windowOpen"])) {
this.core.get("interface")["windowOpen"](clickthruUrl);
}
};
VideoClickHandler.prototype.reportTrackingUrl = function() {
var _this = this;
var data = this.adConfig.app_data;
if (data["placement-config"] && data["placement-config"]["hotspot-clicks"]) {
data["placement-config"]["hotspot-clicks"].filter(function(hotspot) {
return hotspot.id === "main" && _.isArray(hotspot.tracking);
}).forEach(function(hotspot) {
_this.core.report.submit3rdPartyTracking(hotspot.tracking);
});
}
};
return VideoClickHandler;
})();
IV.VideoClickHandler = VideoClickHandler;
})(IV || (IV = {}));
var IV;
(function(IV) {
var VideoVolumeHandler = (function() {
function VideoVolumeHandler(videoElement) {
this.videoElement = videoElement;
}
VideoVolumeHandler.prototype.onVolumeChange = function(volume) {
if (this.isVolumeValid(volume)) {
this.setVideoVolume(volume);
}
};
VideoVolumeHandler.prototype.isVolumeValid = function(volume) {
var currentVolume = this.videoElement.volume;
return typeof volume !== "undefined" && !isNaN(volume) && volume >= 0 && volume <= 1 && currentVolume !== volume;
};
VideoVolumeHandler.prototype.setVideoVolume = function(volume) {
if (typeof volume !== "number") {
volume = parseFloat(volume);
}
this.videoElement.volume = volume;
};
VideoVolumeHandler.prototype.bindVolumeChangeEvent = function(initialVolume) {
if (this.isVolumeValid(initialVolume)) {
this.setVideoVolume(initialVolume);
}
var onVolumeChange = this.onVolumeChange;
IV.Events.on("volumechange", onVolumeChange, this);
};
VideoVolumeHandler.prototype.unbindVolumeChangeEvent = function() {
var onVolumeChange = this.onVolumeChange;
IV.Events.off("volumechange", onVolumeChange);
};
return VideoVolumeHandler;
})();
IV.VideoVolumeHandler = VideoVolumeHandler;
})(IV || (IV = {}));
(function(SCOPE) {
SCOPE.ActivityLog = function() {
var eventsMap = [],
countListeners = [],
timers = [],
runningTimers = [];
this.log = function(event) {
var now = new Date().getTime(),
newCount;
if (this.has(event)) {
newCount = ++eventsMap[event].count;
eventsMap[event].time = now;
} else {
newCount = 1;
eventsMap[event] = {
"count": newCount,
"time": now
};
}
resetAllTimers();
startEventTimers(event);
notifyCountListeners(event, newCount);
return this;
};
this.getCount = function(event) {
var count = 0;
if (this.has(event)) {
count = eventsMap[event].count;
}
return count;
};
this.has = function(event) {
return event in eventsMap;
};
this.onCount = function(event, count, cb, context) {
if (!(event in countListeners)) {
countListeners[event] = [];
}
if (!(count in countListeners[event])) {
countListeners[event][count] = [];
}
countListeners[event][count].push({
"callback": cb,
"context": context
});
};
this.onTime = function(event, time, cb, context) {
if (!(event in timers)) {
timers[event] = [];
}
timers[event].push({
"time": time,
"cb": cb,
"context": context
});
};
function notifyCountListeners(ev, count) {
if (ev in countListeners && count in countListeners[ev]) {
for (var cb in countListeners[ev][count]) {
if (countListeners[ev][count].hasOwnProperty(cb)) {
var listenerObj = countListeners[ev][count][cb];
var context = listenerObj.context !== 'undefined' ? listenerObj.context : null;
listenerObj.callback.call(context, ev, count);
}
}
}
}
function resetAllTimers() {
for (var i = 0; i < runningTimers.length; i++) {
if (typeof runningTimers[i] === "number") {
clearTimeout(runningTimers[i]);
}
}
}
function startEventTimers(ev) {
if (ev in timers) {
for (var i = 0; i < timers[ev].length; i++) {
var job = timers[ev][i];
var taskId = createTimeoutTask(job.cb, job.context, job.time);
runningTimers.push(taskId);
}
}
}
function createTimeoutTask(cb, context, time) {
return setTimeout(function() {
cb.apply(context)
}, time);
}
};
})(IV);
(function(SCOPE) {
var device = function() {
var that = this;
this.getPlatformType = _.memoize(function() {
var ua = that.getNavigatorUserAgent();
return ua.match(/GoogleTV|SmartTV|Internet.TV|NetCast|NETTV|AppleTV|boxee|Kylo|Roku|DLNADOC|CE\-HTML/i) ? 'tv' : ua.match(/Xbox|PLAYSTATION.3|PLAYSTATION.4|Wii/i) ? 'tv' : ua.match(/iPad/i) || ua.match(/tablet/i) && !ua.match(/RX-34/i) || ua.match(/FOLIO/i) ? 'tablet' : ua.match(/Linux/i) && ua.match(/Android/i) && !ua.match(/Fennec|mobi|HTC.Magic|HTCX06HT|Nexus.One|SC-02B|fone.945/i) ? 'tablet' : ua.match(/Kindle/i) || ua.match(/Mac.OS/i) && ua.match(/Silk/i) ? 'tablet' : ua.match(/Opera/i) && ua.match(/Windows.NT.5/i) && ua.match(/HTC|Xda|Mini|Vario|SAMSUNG\-GT\-i8000|SAMSUNG\-SGH\-i9/i) ? 'mobile' : ua.match(/Windows.(NT|XP|ME|9)/) && !ua.match(/Phone/i) || ua.match(/Win(9|.9|NT)/i) ? 'desktop' : ua.match(/Macintosh|PowerPC/i) && !ua.match(/Silk/i) ? 'desktop' : ua.match(/Linux/i) && ua.match(/X11/i) ? 'desktop' : ua.match(/Solaris|SunOS|BSD/i) ? 'desktop' : 'mobile'
});
this.isInApp = function() {
var isIosWebview = /(iPhone|iPod|iPad).+AppleWebKit.*Mobile(?!.*Safari)/i.test(navigator.userAgent);
var isAndroidWebview = /\(.*Android.*\).+AppleWebKit.*Version\/\d/i.test(navigator.userAgent);
return isIosWebview || isAndroidWebview;
};
this.isAndroid = function() {
var userAgent = this.getNavigatorUserAgent();
return (userAgent.match(/android/i) !== null);
};
this.is_iOS = function() {
var userAgent = this.getNavigatorUserAgent();
return userAgent.match('iPod') || userAgent.match('iPhone') || userAgent.match('iPad');
};
this.getOSType = function() {
if (this.is_iOS()) {
return "ios";
} else if (this.isAndroid()) {
return "android";
} else {
return "other"
}
};
this.getDeviceName = function() {
var userAgent = this.getNavigatorUserAgent();
if (userAgent.match('iPod')) {
return 'iPod';
} else if (userAgent.match('iPad')) {
return 'iPad';
} else if (userAgent.match('iPhone')) {
return 'iPhone';
} else if (userAgent.match(/android/i)) {
return 'Android';
} else if (this.getPlatformType() === 'desktop') {
return 'Desktop';
}
return undefined;
};
this.isDeviceHLSSupported = function() {
if (this.is_iOS()) {
return true;
} else if (this.isAndroid() && versionAtLeastAsNewAs(this.getAndroidOSVersion(), "5.0")) {
return true;
}
return false;
};
this.getDeviceInformation = function() {
var device, resolution, version, orientation, os;
var userAgent = this.getNavigatorUserAgent();
if (userAgent.match('iPod')) {
device = 'iPod';
os = 'iOS';
} else if (userAgent.match('iPad')) {
device = 'iPad';
os = 'iOS';
} else if (userAgent.match('iPhone')) {
device = 'iPhone';
os = 'iOS';
} else if (userAgent.match(/android/i)) {
device = 'Android';
os = 'Android';
} else {
return userAgent;
}
resolution = '(' + window.screen.width + 'x' + window.screen.height + ')';
if (os == "iOS") {
version = this.getiPhoneOSVersion();
} else if (os == "Android") {
version = this.getAndroidOSVersion();
}
orientation = this.getDeviceOrientation();
return [device, resolution, version, orientation].join(', ');
};
this.getWebsiteHost = function() {
var website;
try {
website = this.getLocationHost();
} catch (e) {}
if (_.isUndefined(website)) {
website = getHostName(document.referrer);
}
return website;
};
this.canPlayInline = function() {
var deviceName = this.getDeviceName();
if (deviceName === "iPod" || deviceName === "iPhone") {
return supportsInline(this);
} else {
return true;
}
};
this.getLocationHost = function() {
return window.top.location.host;
};
this.getDeviceScreenSize = function() {
return {
w: Math.round(window.screen.width * window.devicePixelRatio),
h: Math.round(window.screen.height * window.devicePixelRatio)
};
};
this.getiPhoneOSVersion = function() {
var match, userAgent = this.getNavigatorUserAgent();
var version = this.is_iOS() ? 1.0 : false;
if (!(match = /iP.+ OS (.*) like Mac OS X/.exec(userAgent))) {} else {
version = match[1].split('_').join('.');
}
return version;
};
this.getAndroidOSVersion = function() {
var match, userAgent = this.getNavigatorUserAgent();
var version = '';
if (!(match = /Android (\d+(?:\.\d+)+)/.exec(userAgent))) {} else {
version = match[1];
}
return version;
};
this.getDeviceOrientation = function(width, height) {
var deviceHeight = _.isUndefined(height) ? window.innerHeight : height,
deviceWidth = _.isUndefined(width) ? window.innerWidth : width,
aspectRatio = 1.3;
return (deviceHeight * aspectRatio > deviceWidth) ? 'Portrait' : 'Landscape';
};
this.getDeviceScreenSizeClass = function() {
var dim = this.getDeviceScreenSize();
if (!this.getiPhoneOSVersion() && !this.getAndroidOSVersion()) return 'small';
return (dim.h >= 960 || dim.w >= 1280) ? 'big' : 'small';
};
this.supportsAnimations = function() {
return (this.isAndroid() && versionAtLeastAsNewAs(this.getAndroidOSVersion().toString(), "4.1")) || (this.is_iOS() && versionAtLeastAsNewAs(this.getiPhoneOSVersion().toString(), "5.2"));
};
this.getNavigatorUserAgent = function() {
return navigator.userAgent;
};
this.needsClickEventToPlay = function() {
return this.isAndroid();
};
this.getHiddenProp = function() {
var prefixes = ['webkit', 'moz', 'ms', 'o'];
if ('hidden' in document) return 'hidden';
for (var i = 0; i < prefixes.length; i++) {
if ((prefixes[i] + 'Hidden') in document) return prefixes[i] + 'Hidden';
}
return null;
};
this.needsElemForcedRedraw = function() {
return this.isAndroid();
};
this.getDocumentQueryString = function() {
return document.location.search;
};
this.getDeviceIdFromRequest = function() {
var queryStringReader = new SCOPE.QueryStringReader();
return queryStringReader.getDeviceIdFromRequest(SCOPE._currentScript, this.getDocumentQueryString());
};
function getHostName(url) {
var a = document.createElement('a');
a.href = url;
return a.hostname;
}
function supportsInline(currentDeviceInfo) {
var canDoInline = SCOPE.InlineVideoValidator.shouldTransformToInlineVideo(currentDeviceInfo);
if (!canDoInline && currentDeviceInfo.is_iOS()) {
var currentDeviceVersion = currentDeviceInfo.getiPhoneOSVersion();
canDoInline = versionAtLeastAsNewAs(currentDeviceVersion.toString(), "10.0.0");
}
return canDoInline;
}
function versionAtLeastAsNewAs(version, comparedTo) {
if (!_.isString(version)) {
return false;
}
var versionParts = version.split('.');
var compareToParts = comparedTo.split('.');
var i = 0,
isNewer = true;
while (isNewer === true && i < compareToParts.length) {
if (i < versionParts.length) {
var versionPartNum = parseInt(versionParts[i], 10);
var compareToPartNum = parseInt(compareToParts[i], 10);
var delta = versionPartNum - compareToPartNum;
if (delta > 0) {
break;
} else if (delta < 0) {
isNewer = false;
}
} else {
isNewer = false;
}
i++;
}
return isNewer;
}
};
SCOPE.device = new device();
SCOPE._currentScript = document.currentScript;
})(IV || {});
(function(SCOPE) {
var icons = function() {
this.setupIcon = function(app, delayAppVisibility) {
var icon = $('<div></div>').addClass('iv-icon').addClass('iv-in-app-icon').css({
display: 'inline-block',
visibility: 'hidden',
zIndex: 25 + (app.get('app-order-index') || 0),
cursor: 'pointer'
});
if (delayAppVisibility) {
icon.css({
visibility: 'hidden'
});
}
app.set('icon', icon);
return icon;
};
this.setIconDimensions = function(app, scaleParams, trayIconWidth, placeholder) {
var iconCss, iconScale = scaleParams.floatingIconScale / scaleParams.iconScaling,
iconWidth = trayIconWidth / scaleParams.iconScaling;
if (placeholder.type === 'docked' && app.get('app-id') !== 'app-skip-ad') {
iconScale = scaleParams.iconScale;
iconWidth = trayIconWidth;
}
if (app.get('customLauncher') && app.get('customLauncher').url) {
var iconData = app.get('customLauncher');
iconCss = this.getCustomIconCss(iconData, iconScale);
iconCss.backgroundImage = 'url(' + iconData.url + ')';
iconCss.backgroundSize = 'contain';
} else {
if (app.get('app-id') === 'app-custom-icon') {
iconCss = this.getCustomIconCss(app.get('data'), iconScale);
} else if ((app.get('app-id') !== 'app-text-label') && (app.get('app-id') !== 'app-skip-ad')) {
var iconImageSize = scaleParams.iconImageSize;
iconCss = this.getIconCss(app.get('icons'), iconImageSize, iconWidth);
}
}
app.get('icon').css(iconCss);
};
this.getIconCss = function(iconImages, iconImageSize, trayIconWidth) {
var imageUrl = '',
maxWidth = 0;
_.each(iconImages, function(appIcon) {
if (appIcon.width <= iconImageSize && appIcon.width > maxWidth) {
imageUrl = appIcon.url;
maxWidth = appIcon.width;
}
});
return {
width: trayIconWidth,
height: trayIconWidth,
backgroundImage: (imageUrl) ? 'url(' + imageUrl + ')' : '',
backgroundSize: 'contain',
backgroundRepeat: 'no-repeat',
lineHeight: trayIconWidth
}
};
this.setIconPosition = function(icon, placeholder, scale, appsContainer, orderIndex) {
var bounds = {
width: $(appsContainer).width(),
height: $(appsContainer).height()
};
var iconRect = icon[0].getBoundingClientRect(),
floatingIconWidth = iconRect.width,
floatingIconHeight = iconRect.height;
var left = (((bounds.width - floatingIconWidth) * placeholder.left) / 100) + (placeholder.offsetX * scale);
var top = (((bounds.height - floatingIconHeight) * placeholder.top) / 100) + (placeholder.offsetY * scale);
var style = {
zIndex: 25 + (orderIndex || 0),
position: "absolute",
left: Math.round(left) + 'px',
top: Math.round(top) + 'px'
};
icon.css(style);
forceIconRedraw(icon[0]);
};
this.getCustomIconCss = function(iconData, scale) {
var width = Math.floor(iconData.width * iconData.scale * scale);
var height = Math.floor(iconData.height * iconData.scale * scale);
return {
width: width,
height: height,
lineHeight: height
}
};
this.getCustomLauncherCss = function(iconData, scale) {
var customCss = {
width: iconData.width,
height: iconData.height,
lineHeight: iconData.height
};
var cssScale = 'scale(' + (iconData.scale * scale) + ')',
cssOrigin = 'top left';
customCss = _.chain(customCss).extend(SCOPE.toolkit.addCssPrefixes('transform', cssScale)).extend(SCOPE.toolkit.addCssPrefixes('transform-origin', cssOrigin)).value();
customCss.backgroundImage = 'url(' + iconData.url + ')';
customCss.backgroundSize = 'contain';
return customCss;
};
function forceIconRedraw(elem) {
if (SCOPE.device.needsElemForcedRedraw()) {
elem.style.display = 'inline-block';
setTimeout(function() {
elem.style.display = '';
}, 0);
}
}
};
SCOPE.icons = new icons();
})(IV);
(function(SCOPE) {
var html5video = function(options, container, initialVolume) {
var that = this,
params = options || {},
defaults = {},
iroll = options.iroll;
var videoControls = options.controls || ['resume'];
var _videoControls = function(args) {
var defaults = {
show: false,
showControls: videoControls || ['resume']
};
var params = args || {};
var options = _.extend(defaults, params);
var controlsBar = _.template('<div class="video-controls"></div>');
var controlsButtons = {
resume: '<a class="control control-resume" data-fn="play">&nbsp;</a>',
play: '<a class="control control-play" data-fn="play">&nbsp;</a>'
};
if (options.show) {
if (container.find('.video-controls').length > 0) {
$(container.find('.video-controls').remove());
}
var controls = $(controlsBar());
_.each(options.showControls, function(control) {
var ctrl = controlsButtons[control];
controls.append(ctrl);
controls.find('.control').each(function() {
$(this).css({
display: 'inline-block',
cursor: 'pointer'
});
});
});
$(container).append(controls).on(iroll.getVideoClickEventType(), '.control', function(ev) {
ev.preventDefault();
var action = $(this).attr('data-fn');
if (_.isFunction(that[action])) that[action]();
});
} else {
$(container.find('.video-controls').remove());
}
};
var _init = function() {
that.el = document.createElement('video');
if (SCOPE.InlineVideoValidator.shouldTransformToInlineVideo(SCOPE.device)) {
SCOPE.InlineVideoFactory.create(that.el);
}
SCOPE.InlineVideoTransformer.checkAndOverrideFastSeek(that.el);
$(that.el).css({
width: "100%",
height: "100%",
top: 0,
left: 0,
position: 'absolute',
'pointer-events': 'visible'
});
that.el.preload = true;
that.el.controls = false;
$(that.el).attr('webkit-playsinline', 'webkit-playsinline');
$(that.el).attr('playsinline', 'playsinline');
$(that.el).addClass('iv-main-video');
if (that.params.preview) {
$(that.el).attr("poster", that.params.preview);
} else {
$(that.el).attr("poster", "data:image/gif;base64,R0lGODlhAQABAIAAAAUEBAAAACwAAAAAAQABAAACAkQBADs=");
}
var videoVolumeHandler = new SCOPE.VideoVolumeHandler(that.el);
videoVolumeHandler.bindVolumeChangeEvent(initialVolume);
};
this.setVideoSource = function(renditions) {
var elem = new SCOPE.VideoElementWrapper(that.el);
var videoLoader = new SCOPE.VideoSourceLoader(elem, iroll);
videoLoader.loadVideoSource(renditions);
return videoLoader.isLoaded();
};
this.play = function() {
this.el.play();
_videoControls({
show: false
});
};
this.resume = this.play;
this.pause = function(hideControls) {
this.el.pause();
if (hideControls !== true) {
_videoControls({
show: true
});
}
};
this.stop = function() {
this.el.stop();
_videoControls({
show: false
});
};
this.showControls = function(controls) {
_videoControls(_.extend({
show: true
}, controls || {}));
};
this.setSrc = function(src) {
this.el.src = src;
};
this.getDuration = function() {
return this.el.duration;
};
this.getCurrentTime = function() {
return this.el.currentTime;
};
this.getRemainingTime = function() {
return this.getDuration() - this.getCurrentTime();
};
this.load = function() {
this.el.load();
};
this.events = _.extend({}, Backbone.Events);
this.params = _.extend(defaults, params);
_init();
};
SCOPE.html5video = html5video;
})(IV);
(function(SCOPE) {
SCOPE.IRollSimpleTracker = function(eventHandler, eventPrefix) {
var map = {
"expand": "dialogOpened",
"clickthru": "openUrl",
"engage": "engage",
"impression": "ad_started",
"firstquartile": "video_videoPassed25",
"midpoint": "video_videoPassed50",
"thirdquartile": "video_videoPassed75",
"completion": "ad_ended"
};
this.registerCustomPixels = function(customPixels) {
_.each(customPixels, function(urls, eventName) {
var iRollEventName = mapEventNameToIRollEventName(eventPrefix, eventName);
if (iRollEventName !== null) {
var urlArr = urls;
if (!_.isArray(urlArr)) {
urlArr = new Array(urlArr);
}
_.each(urlArr, function(val) {
eventHandler.on(iRollEventName, function() {
fireCustomPixel(val);
});
});
}
});
};
function fireCustomPixel(url) {
var req = new Image();
req.src = url;
}
function mapEventNameToIRollEventName(eventPrefix, eventName) {
if (map.hasOwnProperty(eventName)) {
return eventPrefix + map[eventName];
} else {
return null;
}
}
};
})(IV);
(function(SCOPE) {
SCOPE.reportAnalytics = Backbone.Model.extend({
defaults: {
sendLogs: true,
instance: null,
instanceClass: null,
session: null,
defaultReportData: {
'ad_criteria': null,
placement_tag_id: 0,
r: '',
viewer_id: '',
action: '',
session_id: '',
client_id: -1,
channel_id: 0,
project_state: 0,
video_id: 0,
project_hash: '',
placement_hash: -1,
impression_id: '',
event_id: '',
website: 'unknown',
publisher_id: 0,
event_value: '',
fver: null,
real_estate_id: 0
},
childReportData: {
manual_select_project_state: 8,
auto_select_project_state: 10
}
},
CONTEXT: {
MANUAL_SELECT: 'manual_select_project_state',
AUTO_SELECT: 'auto_select_project_state'
},
reportedUrls: [],
reportedOptions: [],
errorLogQueue: [],
loadedOptions: [],
postLoadedPixelCallbackActions: {},
postReportedPixelCallbackActions: {},
initialize: function() {
var that = this,
instanceData = this.get('instance'),
reportData = {},
childReportData = this.get('childReportData'),
placementConfig = instanceData.data['placement-config'];
_.extend(reportData, this.get('defaultReportData'));
that.reportedUrls = [];
that.errorLogQueue = [];
that.reportedOptions = [];
that.loadedOptions = [];
that.postLoadedPixelCallbackActions = {};
that.postReportedPixelCallbackActions = {};
that.get('instanceClass').set({
sendLogs: true
});
reportData.session_id = SCOPE.toolkit.randomId();
reportData.viewer_id = SCOPE.toolkit.randomId();
reportData.impression_id = SCOPE.toolkit.randomId();
reportData.ver = instanceData.data['version'];
reportData.website = (SCOPE.device.getPlatformType() === "desktop" ? SCOPE.device.getWebsiteHost() : SCOPE.device.getDeviceInformation()).substring(0, 128);
if (_.isObject(placementConfig)) {
reportData.placement_hash = placementConfig['placement-hash'] || '';
reportData.placement_tag_id = placementConfig['placement-tag-id'] || 0;
reportData.publisher_id = placementConfig['publisher-id'];
reportData.channel_id = placementConfig['channel-id'];
reportData.client_id = placementConfig['client-id'];
reportData.project_hash = placementConfig['project-hash'];
reportData.video_id = placementConfig['video-id'];
reportData.project_state = placementConfig['project-state'];
reportData.real_estate_id = placementConfig['real_estate_id'];
childReportData.manual_select_project_state = placementConfig['child-manual-project-state'];
childReportData.auto_select_project_state = placementConfig['child-auto-project-state'];
} else {
reportData.project_hash = instanceData.data['id'];
}
var deviceId = SCOPE.device.getDeviceIdFromRequest();
if (deviceId) {
reportData.device_id = deviceId;
}
this.url = this.get('instance').reportUrl;
this.set("reportData", reportData);
},
submit3rdPartyTracking: function(trackingItems) {
if (!this.get('sendLogs')) return;
var that = this;
_.each(trackingItems, function(trackingItem) {
var trackingData = trackingItem.hasOwnProperty("data") ? trackingItem.data : trackingItem;
var trackingType = trackingItem.hasOwnProperty("type") ? trackingItem.type : null;
var session_id = that.get("reportData").session_id;
var thirdPartyTrackingReporter = that.get("thirdPartyTrackingReporter");
thirdPartyTrackingReporter.report(trackingData, trackingType, session_id, that.firePixel.bind(that), that.reportLog.bind(that));
});
},
addReportDataToReportUrl: function(reportData, reportUrl) {
_.each(reportData, function(val, key) {
if (val === '') return;
if (key == 'relative_time') {
val = (val / 1000).toFixed(3);
}
if (_.indexOf(['init', 'play', 'vpoint', 'engage'], reportData.action) !== -1) {
if (key == 'impression_id') return;
}
if (key == 'ad_criteria') {
if (_.indexOf(['click', 'clktru', 'clkint', 'cxon', 'cxoff'], reportData.action) != -1) {
val = null;
} else {
return;
}
}
if (key == 'real_estate_id') {
if (_.indexOf(['click', 'clktru', 'clkint', 'cxon', 'cxoff', 'engage'], reportData.action) == -1) {
return;
}
}
reportUrl += key + '=' + encodeURIComponent(val) + '&';
});
reportUrl = reportUrl.slice(0, -1);
return reportUrl;
},
submit: function(options, context) {
if (!this.get('sendLogs')) return;
var that = this,
params = options || {},
data = _.extend({}, this.toJSON()['reportData']);
if (typeof context !== 'undefined') {
params['project_state'] = this.get('childReportData')[context];
}
var reportData = _.extend(data, params);
reportData.r = SCOPE.toolkit.randomId();
var reportUrlPrefix = this.get('instance').reportUrl;
reportUrlPrefix += '?';
var reportUrl = this.addReportDataToReportUrl(reportData, reportUrlPrefix);
if (_.indexOf(['click', 'clktru', 'engage'], reportData.action) !== -1) {
setTimeout(function() {
that.firePixel(reportUrl, options);
}, 100);
} else {
this.firePixel(reportUrl, options);
}
},
getReportingTrackingItems: function(action, reporting) {
if (!this.get('sendLogs')) {
return [];
}
var reportingData = _.clone(reporting),
eventName = action || '',
resultArr = [];
if (reportingData.hotspots && _.size(reportingData.hotspots) && reportingData.hotspots[eventName]) {
_.each(reportingData.hotspots[eventName], function(item) {
if (!_.isUndefined(item['tracking'])) {
_.each(item['tracking'], function(url) {
resultArr.push(url);
});
}
});
}
return resultArr;
},
click: function(ev) {
this.submit({
action: 'click',
event_id: 'position',
event_value: ev.pageX + 'x' + ev.pageY
});
},
submitError: function(options) {
options.action = 'error';
options.runtime_type = 'html';
options.sample_rate = this.get('session').getSampleRate();
options.suffix = this.get('instance').version.split('.').splice(0, 2).join('_');
this.cutPixel(options);
var params = options || {},
data = _.extend({}, this.toJSON()['reportData']),
reportData = _.extend(data, params);
delete reportData.website;
reportData.r = SCOPE.toolkit.randomId();
var reportUrlPrefix = this.get('instance').errorReportUrl;
reportUrlPrefix += '?';
var reportUrl = this.addReportDataToReportUrl(reportData, reportUrlPrefix);
this.fireErrorPixel(reportUrl);
},
reportLog: function(options) {
if (this.get('instance').enableErrorReporting && this.get('instance').errorReportUrl) {
if (this.get('session').isMonitored(options.event_id)) {
this.submitError(options);
} else {
this.errorLogQueue.push(options);
}
}
},
flushErrorQueue: function() {
for (var i = 0; i < this.errorLogQueue.length; i++) {
if (this.get('session').isMonitored(this.errorLogQueue[i].event_id)) {
this.submitError(this.errorLogQueue[i]);
}
}
this.errorLogQueue = [];
},
firePixel: function(reportUrl, options) {
SCOPE.toolkit.debug("Fire Pixel - ", reportUrl);
var that = this;
var img = new Image(1, 1);
if (options) {
img.onload = this.loadedPixelCallback.bind(this, options);
}
img.onerror = function() {
that.reportLog({
event_id: "pixel_error",
event_value: reportUrl
});
};
try {
img.src = reportUrl;
this.reportedUrls.push(reportUrl);
if (options) {
this.reportedPixelCallback(options);
}
} catch (e) {
this.reportLog({
event_id: "pixel_error_message",
event_value: e.message + ": " + reportUrl
});
}
return img;
},
fireErrorPixel: function(reportUrl) {
var img = this.firePixel(reportUrl);
var irollAd = this.get('instanceClass');
var appendImageToElement = function(element, img) {
if (element && _.isElement(element)) {
try {
img.style.display = "none";
element.ownerDocument.body.appendChild(img);
return true;
} catch (e) {
return false;
}
} else {
return false;
}
};
var videoContainer = irollAd.get("videoContainer");
var mainContainer = irollAd.get("mainContainer");
if (!appendImageToElement(videoContainer, img)) {
appendImageToElement(mainContainer, img);
}
},
cutPixel: function(options) {
var MAX_LEN = 125;
if (!options.event_value) return;
options.event_value = options.event_value.length > MAX_LEN ? options.event_value.substring(0, MAX_LEN) : options.event_value;
},
reportedPixelCallback: function(options) {
pixelCallback(this.reportedOptions, this.postReportedPixelCallbackActions, options);
},
wasPixelReported: function(options) {
return !!_.findWhere(this.reportedOptions, options);
},
addPostReportedPixelCallback: function(cb, action) {
addActionCallback(this.postReportedPixelCallbackActions, cb, action);
},
loadedPixelCallback: function(options) {
pixelCallback(this.loadedOptions, this.postLoadedPixelCallbackActions, options);
},
wasPixelLoaded: function(options) {
return !!_.findWhere(this.loadedOptions, options);
},
addPostLoadedPixelCallback: function(cb, action) {
addActionCallback(this.postLoadedPixelCallbackActions, cb, action);
}
});
function pixelCallback(pixelOptionsArr, callbackActionsObj, options) {
pixelOptionsArr.push(options);
if (callbackActionsObj.hasOwnProperty(options.action)) {
callbackActionsObj[options.action].forEach(function(postReportPixelCb) {
postReportPixelCb();
});
}
}
function addActionCallback(callbackActionsObj, cb, action) {
if (callbackActionsObj.hasOwnProperty(action)) {
callbackActionsObj[action].push(cb);
} else {
callbackActionsObj[action] = [cb];
}
}
})(IV);
(function(SCOPE) {
if (!_.isObject(SCOPE.toolkit)) {
SCOPE.toolkit = {};
}
var logger = null;
SCOPE.toolkit.debug = function() {
if (logger === null) {
logger = createLogger();
}
logger.debug.apply(logger, arguments);
};
function createLogger() {
var queryReader = new SCOPE.QueryStringReader();
var customParams = new SCOPE.DataInjector(queryReader, SCOPE.toolkit).getCustomParams();
var isDebugMode = customParams.hasOwnProperty("innovid_debug") ? customParams["innovid_debug"] === "1" : false;
return new SCOPE.InnovidLogger(isDebugMode);
}
SCOPE.toolkit.randomId = function() {
var res = "";
for (var i = 0; i < 8; i++) {
res += (0x10000 | Math.random() * 0x10000).toString(16).substr(1);
}
return res;
};
SCOPE.toolkit.getEnvironmentFromURL = function(url) {
url = url.replace(/^https?:\/\//, '');
var urlParts = url.split("/");
var host = urlParts[0];
return host.split(".").slice(-2).join(".");
};
SCOPE.toolkit.getURLparts = function(url) {
var uriBreakeDownRexExp = new RegExp("^(([^:/?#]+):)?(//([^/?#]*))?([^?#]*)(\\?([^#]*))?(#(.*))?");
var urlPartsArray = url.split(uriBreakeDownRexExp);
var urlPartObj = {
scheme: urlPartsArray[2],
authority: urlPartsArray[4],
path: urlPartsArray[5],
query: urlPartsArray[7],
fragment: urlPartsArray[9]
};
return urlPartObj;
};
SCOPE.toolkit.getURISchemeFromURL = function(url) {
return SCOPE.toolkit.getURLparts(url).scheme;
};
SCOPE.toolkit.trim = function(str) {
return str.replace(/^\s+|\s+$/g, "");
};
SCOPE.toolkit.getRGBcolorFromMScolor = function(color) {
var red, blue, green;
red = Math.floor(Math.floor(color / 256) / 256);
color = color - red * 256 * 256;
green = Math.floor(color / 256);
blue = color - green * 256;
return {
red: red,
green: green,
blue: blue
};
};
SCOPE.toolkit.dayCodesToDaysInWeek = function(recurrence) {
var pos, days = recurrence.split(","),
daysInWeek = [],
dayCodes = ["SU", "MO", "TU", "WE", "TH", "FR", "SA"];
_.each(days, function(dayCode) {
pos = dayCodes.indexOf(dayCode);
if (pos != -1) {
daysInWeek.push(pos);
}
});
return daysInWeek;
};
SCOPE.toolkit.dateToString = function(date) {
var weekday = ["Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday"];
var dateParts = date.toDateString().split(" ");
return weekday[date.getDay()] + ", " + dateParts[1] + ". " + dateParts[2] + ", " + dateParts[3];
};
SCOPE.toolkit.getExpirationDate = function(date) {
var expires = new Date(date);
expires.setFullYear(expires.getFullYear() + 1);
return expires.getFullYear() + "-" + SCOPE.toolkit.padDigits((expires.getUTCMonth() + 1), 2) + "-" + SCOPE.toolkit.padDigits(expires.getUTCDate(), 2) + "T" + SCOPE.toolkit.padDigits(expires.getUTCHours(), 2) + ":" + SCOPE.toolkit.padDigits(expires.getUTCMinutes(), 2) + ":" + SCOPE.toolkit.padDigits(expires.getUTCSeconds(), 2);
};
SCOPE.toolkit.padDigits = function(number, digits) {
return Array(Math.max(digits - String(number).length + 1, 0)).join(0) + number;
};
SCOPE.toolkit.getIconImageSize = function(sizeArray, iconSize) {
var iconImageSize = null;
var nextIndex = 0;
for (var i in sizeArray) {
if (iconImageSize == null || Math.abs(sizeArray[i] - iconSize) < Math.abs(iconImageSize - iconSize)) {
iconImageSize = sizeArray[i];
nextIndex++;
}
}
if ((nextIndex < sizeArray.length) && (iconSize > iconImageSize)) {
iconImageSize = sizeArray[nextIndex];
}
return iconImageSize
};
SCOPE.toolkit.getPlatformScaleParameter = function(platformScaling) {
var scale = 1;
var platform = SCOPE.device.getPlatformType();
switch (platform) {
case "mobile":
scale = platformScaling.mobile;
break;
case "tablet":
scale = platformScaling.tablet;
break;
case "desktop":
scale = platformScaling.desktop;
break;
case "tv":
scale = platformScaling.tv;
break;
}
return scale
};
SCOPE.toolkit.secondsToHMS = function(seconds) {
var seconds = Number(seconds);
var h = Math.floor(seconds / 3600);
var m = Math.floor(seconds % 3600 / 60);
var s = Math.floor(seconds % 3600 % 60);
return ((h > 0 ? h + ":" : "") + (m > 0 ? (m < 10 ? "0" : "") + m + ":" : "00:") + (s < 10 ? "0" : "") + s);
};
SCOPE.toolkit.addDaySuffix = function(i) {
var j = i % 10;
if (j == 1 && i != 11) {
return i + "st";
}
if (j == 2 && i != 12) {
return i + "nd";
}
if (j == 3 && i != 13) {
return i + "rd";
}
return i + "th";
};
SCOPE.toolkit.getDateLabel = function(date) {
var daysDiff = SCOPE.toolkit.calcDiffInDays(date, new Date());
switch (daysDiff) {
case 0:
return "Today";
case 1:
return "Tomorrow";
default:
return date.toDateString().split(" ")[1] + " " + SCOPE.toolkit.addDaySuffix(date.getDate());
}
};
SCOPE.toolkit.calcDiffInDays = function(from, to) {
var diff = from - to;
return Math.max(Math.ceil(diff / 1000 / 60 / 60 / 24), 0);
};
function removeQuestionMark(str) {
return str.charAt(0) === "?" ? str.substring(1) : str;
}
SCOPE.toolkit.parseQueryString = function(querystring) {
var res = {};
if (querystring && typeof querystring === "string") {
var paramString = removeQuestionMark(querystring);
var paramPartArray = paramString.split("&");
_.each(paramPartArray, function(paramPart) {
var splittedParam = paramPart.split("=");
res[splittedParam[0]] = splittedParam[1] ? decodeURIComponent(splittedParam[1]) : "";
});
}
return res;
};
SCOPE.toolkit.addCssPrefixes = function(prop, value) {
var cssStyle = {};
_.each(this.getCssPrefixes(), function(prefix) {
cssStyle[prefix + prop] = value;
});
return cssStyle;
};
SCOPE.toolkit.getCssPrefixes = function() {
return ['', '-webkit-', '-moz-', '-ms-', '-o-'];
};
SCOPE.toolkit.generateDate = function() {
var now = new Date();
var date = [now.getFullYear(), now.getMonth() + 1, now.getDate()];
var time = [now.getHours(), now.getMinutes(), now.getSeconds()];
return date.join('-') + ' ' + time.join(':') + '.' + now.getMilliseconds();
}
})(IV);
(function(SCOPE) {
SCOPE.VideoRenditions = (function() {
function VideoRenditions() {
var renditionsMap = {
"iphone_stream": {
"mimetype": "application/x-mpegurl",
"device": ["iPhone", "iPod", "iPad", "Android"],
"extension": "m3u8",
"isHLS": true
},
"low.mp4": {
"mimetype": "video/mp4"
},
"mp4": {
"mimetype": "video/mp4"
},
"high.mp4": {
"mimetype": "video/mp4",
"device": ["Desktop"]
},
"webm": {
"mimetype": "video/webm"
},
"specificRendition": {}
};
var extensionToRenditionMap = {
"m3u8": "iphone_stream",
"mp4": "mp4",
"webm": "webm"
};
var renditionsPriority = ["specificRendition", "high.mp4", "iphone_stream", "low.mp4", "mp4", "webm"];
this.disableSupport = function(name) {
if (supported(name)) {
delete renditionsMap[name];
}
return this;
};
this.add = function(name, url) {
if (supported(name)) {
renditionsMap[name]["src"] = filterURL(name, url);
}
return this;
};
this.isDeviceSupported = function(name, device, supportsHLS) {
var deviceSupported = false;
if (supported(name)) {
var rend = renditionsMap[name];
if (rend.hasOwnProperty("device")) {
deviceSupported = (rend["isHLS"]) ? (rend["device"].indexOf(device) != -1) && supportsHLS : (rend["device"].indexOf(device) != -1);
} else {
deviceSupported = true;
}
}
return deviceSupported;
};
this.getIterator = function() {
return new VideoRenditionsIterator(renditionsMap, renditionsPriority);
};
function supported(name) {
return renditionsMap.hasOwnProperty(name);
}
function filterURL(name, url) {
if (renditionsMap.hasOwnProperty(name)) {
var rendition = renditionsMap[name];
if (rendition.hasOwnProperty("extension")) {
url = url.replace("." + name, "." + rendition["extension"]);
}
}
return url;
}
this.hasMimeType = function(name) {
return renditionsMap[name].hasOwnProperty('mimetype');
};
function getMimeTypeFromSource(extension) {
var renditionInMap = extensionToRenditionMap[extension];
return renditionsMap[renditionInMap]['mimetype'];
}
this.setMimeTypeBySource = function(name, src) {
var extension = src.substring(src.lastIndexOf('.') + 1);
if (extensionToRenditionMap.hasOwnProperty(extension)) {
renditionsMap[name]['mimetype'] = getMimeTypeFromSource(extension);
}
};
}
var VideoRenditionsIterator = (function() {
function VideoRenditionsIterator(renditions, order) {
this.renditions = renditions;
this.order = order;
this.current = 0;
}
VideoRenditionsIterator.prototype.next = function() {
var i = this.current;
var rendWithSrc = null;
while (i < _.size(this.order) && rendWithSrc === null) {
var rend = this.renditions[this.order[i]];
if (_.isObject(rend) && rend.hasOwnProperty("src")) {
rendWithSrc = rend;
this.current = i + 1;
}
i++;
}
return rendWithSrc;
};
VideoRenditionsIterator.prototype.reset = function() {
this.current = 0;
};
return VideoRenditionsIterator;
})();
return VideoRenditions;
})();
})(IV);
(function(SCOPE) {
function renderCloseButton(core) {
var closeButton = $('<div id="iv-close-btn" />');
closeButton.on(core.get('mainEngagementEvent'), function(ev) {
ev.preventDefault();
core.report.submit({
action: 'close',
event_value: 'click'
});
SCOPE.Events.trigger(core.get('id') + ':close');
});
core.canvas.addElement(closeButton);
SCOPE.Events.trigger("closeButtonRendered");
}
function unrenderCloseButton() {
SCOPE.Events.trigger("closeButtonUnrendered");
}
SCOPE.Events.on("IRollReady", function(core) {
var showCloseButton = core.get('CloseButton'),
waitTillImpression = core.get('CloseButtonWaitToImpression');
if (showCloseButton || waitTillImpression) {
SCOPE.Events.trigger("closeButtonEnabled");
var renderFn;
if (showCloseButton) {
renderFn = _.once(renderCloseButton.bind(this, core));
} else {
renderFn = unrenderCloseButton;
}
var timeout = parseInt(core.get('CloseButtonTimeout'), 10);
if (isNaN(timeout)) timeout = 0;
var timer = setTimeout(function() {
renderFn();
}, timeout);
SCOPE.Events.on(core.get('id') + ':ad_started', function() {
clearTimeout(timer);
renderFn();
});
}
});
})(IV);
(function(SCOPE) {
SCOPE.Events.on("videoPlayerReady", function(core, videoPlayer, videoSpy) {
var elem, coreId = core.get('id'),
enabled = true;
function buildElem() {
elem = $("<div class='iv-video-controls' />");
elem.hide();
elem.on(core.getVideoClickEventType(), function() {
videoPlayer.play();
IV.Events.trigger(coreId + ":video_controls_play");
});
}
function bindEvents() {
var pauseTimerId = null;
["video_play", "video_ended", "buffering"].forEach(function(ev) {
videoSpy.on(ev, function() {
hideControls();
});
});
videoSpy.on("video_pause", function() {
showControls();
});
["dialogClosed", "slateClosed"].forEach(function(ev) {
IV.Events.on(coreId + ':' + ev, function() {
enabled = true
});
});
["dialogOpened", "slateOpened"].forEach(function(ev) {
IV.Events.on(coreId + ':' + ev, function() {
enabled = false
});
});
function hideControls() {
if (pauseTimerId) {
clearTimeout(pauseTimerId);
pauseTimerId = null;
}
elem.hide();
}
function showControls() {
pauseTimerId = setTimeout(function() {
if (enabled && !hasVideoEnded()) elem.show();
pauseTimerId = null;
}, 500);
}
}
function hasVideoEnded() {
return videoPlayer.getState() === "ended";
}
if (core.get('showClickToResume') === true) {
buildElem();
core.canvas.addResponsiveElement(elem);
bindEvents();
}
});
})(IV);
(function(SCOPE) {
SCOPE.VideoElementWrapper = function(elem) {
this.elem = elem;
this.fallbackDuration = 0;
};
SCOPE.VideoElementWrapper.prototype.play = function() {
this.elem.play();
};
SCOPE.VideoElementWrapper.prototype.pause = function() {
this.elem.pause();
};
SCOPE.VideoElementWrapper.prototype.getAllSourceChildren = function() {
return this.elem.children || [];
};
SCOPE.VideoElementWrapper.prototype.setSrc = function(src) {
this.elem.src = src;
};
SCOPE.VideoElementWrapper.prototype.hasSrc = function() {
return !!this.elem.src;
};
SCOPE.VideoElementWrapper.prototype.getDuration = function() {
return (isFinite(this.elem.duration) && this.elem.duration > 0) ? this.elem.duration : this.fallbackDuration;
};
SCOPE.VideoElementWrapper.prototype.setFallbackDuration = function(fallbackDuration) {
this.fallbackDuration = fallbackDuration;
};
SCOPE.VideoElementWrapper.prototype.getCurrentTime = function() {
return this.elem.currentTime;
};
SCOPE.VideoElementWrapper.prototype.getElem = function() {
return this.elem;
};
SCOPE.VideoElementWrapper.prototype.on = function(event, callback) {
this.elem.addEventListener(event, callback);
};
SCOPE.VideoElementWrapper.prototype.canPlayType = function(mimeType) {
var canPlay;
if (this.elem.canPlayType) {
canPlay = this.elem.canPlayType(mimeType);
} else {
var tempVideo = document.createElement('video');
if (typeof tempVideo.canPlayType === "function") {
canPlay = tempVideo.canPlayType(mimeType);
}
}
return (canPlay === 'probably' || canPlay === 'maybe');
};
SCOPE.VideoElementWrapper.prototype.load = function() {
if (this.elem.load) {
this.elem.load();
}
};
SCOPE.VideoElementWrapper.prototype.seekTo = function(secs) {
this.elem.currentTime = secs;
};
SCOPE.VideoElementWrapper.prototype.getVolume = function() {
if (typeof this.elem.volume !== 'undefined') {
return this.elem.volume;
} else {
return -1;
}
};
SCOPE.VideoElementWrapper.prototype.setVolume = function(val) {
if (typeof this.elem.volume !== 'undefined') {
var volumeNum = parseFloat(val);
if (!isNaN(volumeNum) && volumeNum >= 0 && volumeNum <= 1) {
this.elem.volume = volumeNum;
}
}
};
SCOPE.VideoElementWrapper.prototype.exitFullScreen = function() {
if (this.elem.exitFullscreen) {
this.elem.exitFullscreen();
} else if (this.elem.webkitExitFullscreen) {
this.elem.webkitExitFullscreen();
}
};
SCOPE.VideoElementWrapper.prototype.hasTracks = function() {
return _.isElement(this.elem) && $(this.elem).find("track").size() > 0;
};
})(IV);
(function(SCOPE) {
SCOPE.InternalVideoPlayer = function(core, initialVolume) {
var elem;
this.video = null;
this.core = null;
this.spy = null;
this.loaded = false;
this.everPlayed = false;
var videoOptions = {
preview: false,
controls: [],
autoplay: true,
iroll: core
};
this.videoContainer = $('<div class="video-container" />');
var initialVol = _.isUndefined(initialVolume) ? 1 : initialVolume;
this.video = new SCOPE.html5video(videoOptions, this.videoContainer, initialVol);
elem = new SCOPE.VideoElementWrapper(this.video.el);
this.init = function(data, core) {
var that = this;
this.spy = new SCOPE.VideoSpy(elem);
if (data.customMetricsEnabled) {
this.spy.setCustomPoint(data.customMetricsTime)
}
this.spy.on("all", function(eventName, ev) {
SCOPE.Events.trigger(core.get('id') + ':' + eventName, ev);
if (eventName === "video_short_buffering_time" || eventName === "video_long_buffering_time") {
SCOPE.Events.trigger('buffering');
} else if (eventName !== "video_timeupdate" && eventName !== "buffering") {
SCOPE.Events.trigger('not_buffering');
}
});
this.core = core;
this.videoContainer.append(this.video.el);
core.canvas.addElement(this.videoContainer);
SCOPE.Events.on("video_click", function(ev) {
that.trigger("interact", ev)
});
SCOPE.Events.on('winResize', setSizes.bind(null, this));
setSizes(this);
SCOPE.Events.trigger("videoPlayerReady", core, this, this.spy);
};
this.loadVideoSource = function(renditionsConfig) {
this.loaded = this.video.setVideoSource(renditionsConfig);
};
var setSizes = function(context) {
var core = context.core;
var adSize = core.canvas.getSize();
context.videoContainer.css({
width: adSize.width,
height: adSize.height
});
};
this.getDuration = function() {
return this.video.getDuration();
};
this.getRemainingTime = function() {
return this.video.getRemainingTime();
};
this.getCurrentTime = function() {
return this.video.getCurrentTime();
};
this.play = function() {
if (this.loaded) {
this.video.play();
this.everPlayed = true;
} else {
throw ("Failed to load video");
}
};
this.resume = function() {
this.video.resume();
};
this.pause = function() {
this.video.pause(true);
};
this.getState = function() {
return this.spy.state;
};
this.isPlaying = function() {
return (this.spy.state === "playing");
};
this.isEverPlayed = function() {
return this.everPlayed;
};
this.preparePlay = function() {
if (!this.everPlayed) {
this.video.load();
}
};
this.getVolume = function() {
return elem.getVolume();
};
this.setVolume = function(val) {
elem.setVolume(val);
};
this.exitFullScreen = function() {
elem.exitFullScreen();
};
};
_.extend(SCOPE.InternalVideoPlayer.prototype, Backbone.Events);
})(IV);
(function(SCOPE) {
SCOPE.SharedVideoPlayer = function(elem) {
this.spy = null;
this.active = true;
this.loaded = false;
this.elem = elem;
this.init = function(data, core) {
var that = this;
if (!elem instanceof IV.VideoElementWrapper) {
throw {
'name': 'TypeError',
'message': 'elem must be a VideoElementWrapper'
};
}
if (data.video) {
elem.setFallbackDuration(data.video.duration);
}
this.spy = new SCOPE.VideoSpy(elem);
this.videoLoader = new SCOPE.VideoSourceLoader(elem, core);
if (data.customMetricsEnabled) {
this.spy.setCustomPoint(data.customMetricsTime)
}
this.spy.on("all", function(eventName, ev) {
SCOPE.Events.trigger(core.get('id') + ':' + eventName, ev);
if (eventName === "video_short_buffering_time" || eventName === "video_long_buffering_time") {
SCOPE.Events.trigger('buffering');
} else if (eventName !== "video_timeupdate") {
SCOPE.Events.trigger('not_buffering');
}
});
var bareElem = elem.getElem();
if (_.isElement(bareElem)) {
videoDecorators.applyByVideoId(bareElem.id, bareElem, core);
}
SCOPE.Events.on("video_click", function(ev) {
if (that.active) {
that.trigger("interact", ev);
}
});
SCOPE.Events.trigger("videoPlayerReady", core, this, this.spy);
};
this.loadVideoSource = function(renditionsConfig) {
this.videoLoader.loadVideoSource(renditionsConfig);
this.loaded = this.videoLoader.isLoaded();
};
this.getCurrentTime = function() {
return elem.getCurrentTime();
};
this.getDuration = function() {
return elem.getDuration();
};
this.getRemainingTime = function() {
return this.getDuration() - this.getCurrentTime();
};
this.play = function() {
if (this.loaded) {
elem.play();
} else {
throw new Error("Failed to load video");
}
};
this.resume = function() {
elem.play();
};
this.pause = function() {
elem.pause();
};
this.getState = function() {
return this.spy.state;
};
this.isPlaying = function() {
return (this.spy.state === "playing");
};
this.isEverPlayed = function() {
return true;
};
this.preparePlay = function() {};
this.cleanUp = function() {
if (this.spy) this.spy.off();
this.active = false;
};
this.getVolume = function() {
return elem.getVolume();
};
this.setVolume = function(val) {
elem.setVolume(val);
};
this.exitFullScreen = function() {
elem.exitFullScreen();
};
var videoDecorators = {
applyByVideoId: function(videoId, videoElement, iroll) {
if (this.decorators.hasOwnProperty(videoId)) {
this.decorators[videoId].call(this, videoElement, iroll);
SCOPE.Events.on('winResize', this.decorators[videoId].bind(this, videoElement, iroll));
}
},
decorators: {
"fwVPAIDPlayer": function(videoElement, iroll) {
$(videoElement).attr("webkit-playsinline", "webkit-playsinline");
$(videoElement).attr("playsinline", "playsinline");
var adSize = iroll.canvas.getSize();
$(videoElement).css("width", adSize.width || "100%").css("height", adSize.height || "100%");
}
}
};
};
_.extend(SCOPE.SharedVideoPlayer.prototype, Backbone.Events);
})(IV);
(function(SCOPE) {
SCOPE.VideoSourceLoader = function(videoElem, core) {
var isLoaded = false;
this.loadVideoSource = function(renditionsConfig) {
var renditions = new SCOPE.VideoRenditions(),
foundSuitableSource = false;
if (!core.get('supportHLS') || videoElem.hasTracks()) {
renditions.disableSupport("iphone_stream");
}
if (SCOPE.InlineVideoValidator.shouldTransformToInlineVideo(SCOPE.device)) {
renditions.disableSupport("iphone_stream");
}
if (_.isObject(renditionsConfig) && _.size(renditionsConfig) > 0) {
_.each(renditionsConfig, function(src, name) {
if (renditions.isDeviceSupported(name, SCOPE.device.getDeviceName(), SCOPE.device.isDeviceHLSSupported())) {
renditions.add(name, src);
if (!renditions.hasMimeType(name)) {
renditions.setMimeTypeBySource(name, src);
}
}
});
var iterator = renditions.getIterator();
var rend = iterator.next();
while (rend !== null && foundSuitableSource === false) {
if (videoElem.canPlayType(rend['mimetype'])) {
var hadSrc = videoElem.hasSrc();
videoElem.setSrc(rend['src']);
if (hadSrc) {
videoElem.load();
}
foundSuitableSource = true;
} else {
rend = iterator.next();
}
}
if (!foundSuitableSource) {
SCOPE.Events.trigger(core.get('id') + ':video_error');
}
}
isLoaded = foundSuitableSource;
};
this.isLoaded = function() {
return isLoaded;
}
};
})(IV);
(function(SCOPE) {
var updateOrientation = function() {
$('body').attr('orientation', SCOPE.device.getDeviceOrientation());
SCOPE.Events.trigger('orientationchange');
};
$(document).on('ready', function() {
SCOPE.Events.trigger('domReady');
});
$(window).on('load', function() {
SCOPE.Events.trigger('winLoad');
});
$(window).on('resize', function() {
$('body').attr('orientation', SCOPE.device.getDeviceOrientation());
});
window.onorientationchange = updateOrientation;
SCOPE.enableAnimations = SCOPE.device.supportsAnimations();
$(function() {
SCOPE.editingMode = false;
$('body').css({
"margin": 0,
"padding": 0,
"border": 0,
"fontSize": "100%",
"font": "inherit",
"verticalAlign": "baseline"
});
$('body').attr('orientation', SCOPE.device.getDeviceOrientation());
$('html').attr('screen-size', SCOPE.device.getDeviceScreenSizeClass()).attr('auto-scale', SCOPE.device.getAndroidOSVersion() !== '');
$('body').on('focus', ".editable", function() {
SCOPE.editingMode = true;
});
$('body').on("blur", ".editable", function() {
SCOPE.editingMode = false;
});
});
})(IV);
var IV;
(function(IV) {
var BufferingIndicator = (function() {
function BufferingIndicator(canvas) {
var _this = this;
this._canvas = canvas;
this._bufferIndicator = $('<div class="iv-wrapper"></div>');
IV.Events.on('buffering', function() {
_this._bufferIndicator.addClass("iv-buffering");
});
IV.Events.on('not_buffering', function() {
_this._bufferIndicator.removeClass("iv-buffering");
});
}
BufferingIndicator.prototype.add = function() {
var _this = this;
this._canvas.addElement(this._bufferIndicator);
IV.Events.on('winResize', _.debounce(function() {
_this.setSize();
}, 30));
IV.Events.on('orientationchange', _.debounce(function() {
_this.setSize();
}, 30));
this.setSize();
};
BufferingIndicator.prototype.setSize = function() {
var adSize = this._canvas.getSize();
this._bufferIndicator.css({
width: adSize.width,
height: adSize.height,
position: 'absolute',
top: '0em',
left: '0em',
overflow: 'hidden'
});
};
return BufferingIndicator;
})();
IV.BufferingIndicator = BufferingIndicator;
})(IV || (IV = {}));
var IV;
(function(IV) {
var PrerollFormat = (function() {
function PrerollFormat(core) {
this._core = core;
}
PrerollFormat.prototype.start = function() {
var _this = this;
var bufferingIndicator = new IV.BufferingIndicator(this._core.canvas);
IV.Events.on(this._core.get("id") + ":video_ended", function() {
IV.Events.trigger(_this._core.get("id") + ":ad_ended");
});
IV.Events.on(this._core.get("id") + ":video_play", function() {
var forceImmediateImpression = true;
IV.Events.trigger(_this._core.get("id") + ":ad_play", !forceImmediateImpression);
});
if (this._core.get("displayVideo")) {
this._core.get("videoPlayer").play();
}
bufferingIndicator.add();
IV.Events.trigger(this._core.get("id") + ":impression", this._core);
};
return PrerollFormat;
})();
IV.PrerollFormat = PrerollFormat;
})(IV || (IV = {}));
var IV;
(function(IV) {
var QueryStringReader = (function() {
function QueryStringReader(tool) {
if (tool === void 0) {
tool = IV.toolkit;
}
this.DEVICE_ID_PARAM_NAME = "deviceid";
this.toolkit = tool;
}
QueryStringReader.prototype.getExternalCustomParams = function(currentScript, locationSearch) {
if (currentScript && currentScript.src) {
locationSearch = currentScript.src.split("?")[1];
}
return this.toolkit.parseQueryString(locationSearch);
};
QueryStringReader.prototype.getDeviceIdFromRequest = function(currentScript, locationsSearch) {
locationsSearch = this.fromCurrentScript(currentScript, locationsSearch);
var params = this.toolkit.parseQueryString(locationsSearch);
return this.isDeviceIdValid(params[this.DEVICE_ID_PARAM_NAME]) ? params[this.DEVICE_ID_PARAM_NAME] : undefined;
};
QueryStringReader.prototype.fromCurrentScript = function(currentScript, defaultValue) {
if (currentScript && currentScript.src) {
var scriptQueryString = currentScript.src.split("?")[1];
if (scriptQueryString && scriptQueryString.indexOf(this.DEVICE_ID_PARAM_NAME) !== -1) {
defaultValue = scriptQueryString;
}
}
return defaultValue;
};
QueryStringReader.prototype.isDeviceIdValid = function(dId) {
return dId && dId.length > 0;
};
return QueryStringReader;
})();
IV.QueryStringReader = QueryStringReader;
})(IV || (IV = {}));
var IV;
(function(IV) {
var InlineVideoEventRouter = (function() {
function InlineVideoEventRouter(videoElem) {
this.videoEventMap = {};
this.audioTemporaryEventMap = {};
this.videoElem = videoElem;
this.audioElem = null;
}
Object.defineProperty(InlineVideoEventRouter, "VIDEO_EVENTS", {
get: function() {
return ["playing", "ended", "pause", "play", "timeupdate", "durationchange", "volumechange", "seeked"];
},
enumerable: true,
configurable: true
});
InlineVideoEventRouter.prototype.setAudioContext = function(audioElem) {
var _this = this;
this.audioElem = audioElem;
_.each(this.audioTemporaryEventMap, function(listeners, type) {
listeners.forEach(function(listener) {
_this.audioElem.addEventListener(type, listener.bind(_this.videoElem));
});
});
this.audioTemporaryEventMap = {};
};
InlineVideoEventRouter.prototype.route = function(type, listener) {
if (this.isVideoEvent(type)) {
if (this.videoEventMap.hasOwnProperty(type)) {
this.videoEventMap[type].push(listener);
} else {
this.videoEventMap[type] = [listener];
}
} else if (this.audioElem !== null) {
this.audioElem.addEventListener(type, listener.bind(this.videoElem));
} else {
if (this.audioTemporaryEventMap.hasOwnProperty(type)) {
this.audioTemporaryEventMap[type].push(listener);
} else {
this.audioTemporaryEventMap[type] = [listener];
}
}
};
InlineVideoEventRouter.prototype.raise = function(type) {
var _this = this;
if (this.isVideoEvent(type)) {
if (this.videoEventMap.hasOwnProperty(type)) {
var listeners = this.videoEventMap[type];
listeners.forEach(function(listener) {
listener.call(_this.videoElem);
});
}
}
};
InlineVideoEventRouter.prototype.isVideoEvent = function(type) {
return _.contains(InlineVideoEventRouter.VIDEO_EVENTS, type);
};
return InlineVideoEventRouter;
})();
IV.InlineVideoEventRouter = InlineVideoEventRouter;
})(IV || (IV = {}));
var IV;
(function(IV) {
var InlineVideoFactory = (function() {
function InlineVideoFactory() {}
InlineVideoFactory.create = function(videoElem, props) {
if (props === void 0) {
props = null;
}
if (props === null) {
props = {
autoplayWithoutSound: false,
showUnmuteButton: false
};
}
var router = new IV.InlineVideoEventRouter(videoElem);
var inlineVideoWrapper = new IV.InlineVideoWrapper(videoElem, router, props, document);
var renderer = new IV.InlineVideoRenderer(inlineVideoWrapper);
var transformer = new IV.InlineVideoTransformer(inlineVideoWrapper, renderer);
transformer.transform();
return videoElem;
};
return InlineVideoFactory;
})();
IV.InlineVideoFactory = InlineVideoFactory;
})(IV || (IV = {}));
var IV;
(function(IV) {
var InlineVideoRenderer = (function() {
function InlineVideoRenderer(inlineVideo, fps) {
if (fps === void 0) {
fps = 25;
}
this.inlineVideo = inlineVideo;
this.canvas = null;
this.context = null;
this.lastTimeRendered = 0;
this.fps = fps;
this.force = false;
}
InlineVideoRenderer.prototype.render = function() {
var currTime = new Date().getTime();
if (this.inlineVideo.isVideoDone()) {
return;
}
if (this.inlineVideo.isVideoPaused()) {
return;
}
this.inlineVideo.beforeAnimation();
if (this.lastTimeRendered === 0) {
this.lastTimeRendered = currTime;
this.force = true;
} else {
this.force = false;
}
var timeToAdd = (currTime - this.lastTimeRendered) / 1000;
if (this.shouldRender(timeToAdd)) {
if (this.inlineVideo.isAudioStarted()) {
this.inlineVideo.syncTimeToAudio();
} else {
if (this.inlineVideo.currentTime + timeToAdd > this.inlineVideo.duration) {
timeToAdd = this.inlineVideo.duration - this.inlineVideo.currentTime;
}
this.inlineVideo.updateTime(timeToAdd);
}
this.lastTimeRendered = currTime;
}
this.inlineVideo.afterAnimation();
this.drawNextFrame();
};
InlineVideoRenderer.prototype.drawNextFrame = function() {
var _this = this;
requestAnimationFrame(function() {
_this.render();
});
};
InlineVideoRenderer.prototype.shouldRender = function(timeToAdd) {
return this.force ? true : timeToAdd >= 1 / this.fps;
};
return InlineVideoRenderer;
})();
IV.InlineVideoRenderer = InlineVideoRenderer;
})(IV || (IV = {}));
var IV;
(function(IV) {
var InlineVideoTransformer = (function() {
function InlineVideoTransformer(inlineVideo, renderer) {
this.inlineVideo = inlineVideo;
this.renderer = renderer;
}
InlineVideoTransformer.prototype.transform = function() {
this.overrideMethods();
this.overrideProperties();
};
InlineVideoTransformer.prototype.startVideoRendering = function() {
this.renderer.render();
this.inlineVideo.dispatch("playing");
};
InlineVideoTransformer.checkAndOverrideFastSeek = function(videoElem) {
if (typeof videoElem["fastSeek"] !== "function") {
videoElem["fastSeek"] = function(time) {
videoElem.currentTime = time;
};
}
};
InlineVideoTransformer.prototype.overrideMethods = function() {
var _this = this;
var videoElem = this.inlineVideo.elem;
videoElem["play"] = function() {
if (_this.inlineVideo.isVideoPaused()) {
_this.inlineVideo.resume(function() {
_this.startVideoRendering();
});
} else {
_this.inlineVideo.play(function() {
_this.startVideoRendering();
});
}
};
videoElem["pause"] = function() {
_this.inlineVideo.pause();
};
videoElem["addEventListener"] = function(type, listener) {
_this.inlineVideo.addEventListener(type, listener);
};
videoElem["fastSeek"] = function(time) {
_this.inlineVideo.setTime(time);
};
};
InlineVideoTransformer.prototype.overrideProperties = function() {
var _this = this;
var videoElem = this.inlineVideo.elem;
Object.defineProperty(videoElem, "volume", {
get: function() {
return _this.inlineVideo.volume;
},
set: function(vol) {
_this.inlineVideo.setVolume(vol);
},
enumerable: true,
configurable: true
});
var oldSrc = videoElem.src;
Object.defineProperty(videoElem, "src", {
set: function(newSrc) {
if (oldSrc !== newSrc) {
oldSrc = newSrc;
videoElem.setAttribute("src", newSrc);
_this.inlineVideo.setSource(newSrc);
}
},
get: function() {
return oldSrc;
},
enumerable: true,
configurable: true
});
var oldCurrSrc = videoElem.currentSrc;
Object.defineProperty(videoElem, "currentSrc", {
set: function(newCurrSrc) {
if (oldCurrSrc !== newCurrSrc) {
oldCurrSrc = newCurrSrc;
videoElem.setAttribute("currentSrc", newCurrSrc);
_this.inlineVideo.setSource(newCurrSrc);
}
},
get: function() {
return oldCurrSrc;
},
enumerable: true,
configurable: true
});
};
return InlineVideoTransformer;
})();
IV.InlineVideoTransformer = InlineVideoTransformer;
})(IV || (IV = {}));
var IV;
(function(IV) {
var InlineVideoValidator = (function() {
function InlineVideoValidator() {}
Object.defineProperty(InlineVideoValidator, "VALID_DEVICE_NAMES", {
get: function() {
return ["iPhone", "iPod"];
},
enumerable: true,
configurable: true
});;
Object.defineProperty(InlineVideoValidator, "VALID_iOS_VERSIONS", {
get: function() {
return ["8.", "9.", "10."];
},
enumerable: true,
configurable: true
});;
InlineVideoValidator.shouldTransformToInlineVideo = function(deviceInfo, force) {
if (force === void 0) {
force = false;
}
if (InlineVideoValidator.config === null) {
InlineVideoValidator.config = window["IV"].baseData.app_data;
}
if (force) {
return true;
}
if (typeof InlineVideoValidator.config !== "undefined" && InlineVideoValidator.config.hasOwnProperty("iphone-inline") && InlineVideoValidator.config["iphone-inline"] === false) {
return false;
}
if (typeof deviceInfo === "undefined") {
return false;
}
return InlineVideoValidator.isMobileBrowserPlatform() && InlineVideoValidator.isIOS(deviceInfo) && InlineVideoValidator.isValidDeviceName(deviceInfo) && InlineVideoValidator.isValidOS(deviceInfo);
};
InlineVideoValidator.isValidOS = function(deviceInfo) {
var valid = false;
InlineVideoValidator.VALID_iOS_VERSIONS.forEach(function(osVersionPrefix) {
if (deviceInfo.getiPhoneOSVersion().indexOf(osVersionPrefix) === 0) {
valid = true;
}
});
return valid;
};
InlineVideoValidator.isValidDeviceName = function(deviceInfo) {
var valid = false;
InlineVideoValidator.VALID_DEVICE_NAMES.forEach(function(deviceName) {
if (deviceInfo.getDeviceName() === deviceName) {
valid = true;
}
});
return valid;
};
InlineVideoValidator.isMobileBrowserPlatform = function() {
if (typeof window["IVAPPS"] !== "undefined") {
if (window["IVAPPS"] === window["IV"].default) {
return true;
}
}
return false;
};
InlineVideoValidator.isIOS = function(deviceInfo) {
return deviceInfo.is_iOS();
};
InlineVideoValidator.config = null;
return InlineVideoValidator;
})();
IV.InlineVideoValidator = InlineVideoValidator;
})(IV || (IV = {}));
var IV;
(function(IV) {
var InlineVideoProperties = (function() {
function InlineVideoProperties() {
this.showUnmuteButton = false;
this.autoplayWithoutSound = false;
}
return InlineVideoProperties;
})();
IV.InlineVideoProperties = InlineVideoProperties;
var InlineVideoWrapper = (function() {
function InlineVideoWrapper(videoElem, router, props, contextDocument) {
this.videoElem = videoElem;
this.props = props;
this.creativeElementsInitialized = false;
this.audioElem = null;
this.source = videoElem.src || videoElem.currentSrc;
this.paused = false;
this.loaded = false;
this.ended = false;
this.audioStarted = false;
this.currentVolume = 1;
this.animating = false;
this.audioPlayListener = null;
this.router = router;
this.contextDocument = contextDocument;
this.bindEvents();
}
Object.defineProperty(InlineVideoWrapper, "UNMUTE_BUTTON_SCALE", {
get: function() {
return 0.08;
},
enumerable: true,
configurable: true
});
InlineVideoWrapper.prototype.load = function() {
if (this.loaded) {
return;
}
if (this.audioElem) {
this.audioElem.load();
}
this.videoElem.load();
this.videoElem.currentTime = 0;
this.loaded = true;
this.initCreativeElements();
};
InlineVideoWrapper.prototype.bindEvents = function() {
var _this = this;
var hiddenKey = null,
visibilityChangeEventName = null;
this.videoElem.addEventListener("loadedmetadata", function() {
_this.dispatch("durationchange");
});
if (typeof this.contextDocument["hidden"] !== "undefined") {
hiddenKey = "hidden";
visibilityChangeEventName = "visibilitychange";
} else if (typeof this.contextDocument["webkitHidden"] !== "undefined") {
hiddenKey = "webkitHidden";
visibilityChangeEventName = "webkitvisibilitychange";
}
if (hiddenKey !== null) {
this.contextDocument.addEventListener(visibilityChangeEventName, function() {
if (_this.contextDocument[hiddenKey] === true) {
_this.pause();
}
});
}
};
InlineVideoWrapper.prototype.initCreativeElements = function() {
if (!this.creativeElementsInitialized) {
this.creativeElementsInitialized = true;
this.hideNativePlayButton();
this.hideControls();
if (this.props.showUnmuteButton) {
this.showUnmuteButton();
}
}
};
InlineVideoWrapper.prototype.playAudio = function() {
if (!this.audioElem) {
this.extractAudioFromVideo();
}
if (this.isAudioStarted() && this.paused) {
this.audioElem.play();
} else if (!this.isAudioStarted()) {
this.audioElem.play();
}
};
InlineVideoWrapper.prototype.play = function(renderCallback) {
if (!this.paused) {
this.load();
}
if (!this.props.autoplayWithoutSound) {
this.registerToAudioPlayEvent(renderCallback);
this.playAudio();
} else {
renderCallback();
}
this.paused = false;
this.ended = false;
};
InlineVideoWrapper.prototype.pause = function() {
if (this.paused) {
return;
}
this.paused = true;
if (this.audioElem) {
this.audioElem.pause();
}
this.dispatch("pause");
};
InlineVideoWrapper.prototype.resume = function(renderCallback) {
this.play(renderCallback);
this.dispatch("play");
};
Object.defineProperty(InlineVideoWrapper.prototype, "volume", {
get: function() {
return this.currentVolume;
},
enumerable: true,
configurable: true
});
InlineVideoWrapper.prototype.setVolume = function(vol) {
if (this.audioElem) {
this.audioElem.volume = vol;
}
this.currentVolume = vol;
this.dispatch("volumechange");
};
InlineVideoWrapper.prototype.isAudioStarted = function() {
return this.audioStarted;
};
InlineVideoWrapper.prototype.isVideoPaused = function() {
return this.paused;
};
InlineVideoWrapper.prototype.isVideoAlreadyLoaded = function() {
return this.loaded;
};
Object.defineProperty(InlineVideoWrapper.prototype, "width", {
get: function() {
return this.videoElem.width || this.videoElem.offsetWidth;
},
enumerable: true,
configurable: true
});
Object.defineProperty(InlineVideoWrapper.prototype, "height", {
get: function() {
return this.videoElem.height || this.videoElem.offsetHeight;
},
enumerable: true,
configurable: true
});
Object.defineProperty(InlineVideoWrapper.prototype, "top", {
get: function() {
return this.videoElem.offsetTop;
},
enumerable: true,
configurable: true
});
Object.defineProperty(InlineVideoWrapper.prototype, "left", {
get: function() {
return this.videoElem.offsetLeft;
},
enumerable: true,
configurable: true
});
Object.defineProperty(InlineVideoWrapper.prototype, "duration", {
get: function() {
return this.videoElem.duration;
},
enumerable: true,
configurable: true
});
Object.defineProperty(InlineVideoWrapper.prototype, "currentTime", {
get: function() {
return this.videoElem.currentTime;
},
enumerable: true,
configurable: true
});
InlineVideoWrapper.prototype.syncTimeToAudio = function() {
this.setTime(this.audioElem.currentTime);
};
InlineVideoWrapper.prototype.updateTime = function(timeToAdd) {
this.setTime(this.videoElem.currentTime + timeToAdd);
};
InlineVideoWrapper.prototype.setTime = function(time) {
if (!this.animating && this.audioElem) {
this.audioElem.currentTime = time;
}
this.videoElem.currentTime = time;
this.dispatch("timeupdate");
this.dispatch("seeked");
if (this.isVideoDone()) {
this.ended = true;
this.dispatch("ended");
}
};
InlineVideoWrapper.prototype.beforeAnimation = function() {
this.animating = true;
};
InlineVideoWrapper.prototype.afterAnimation = function() {
this.animating = false;
};
InlineVideoWrapper.prototype.setSource = function(source) {
this.source = source;
if (this.audioElem) {
this.audioElem.src = source;
}
};
Object.defineProperty(InlineVideoWrapper.prototype, "src", {
get: function() {
return this.videoElem.src || this.videoElem.currentSrc;
},
enumerable: true,
configurable: true
});
InlineVideoWrapper.prototype.isVideoDone = function() {
return this.videoElem.currentTime >= this.videoElem.duration;
};
InlineVideoWrapper.prototype.addEventListener = function(type, listener) {
this.router.route(type, listener);
};
InlineVideoWrapper.prototype.dispatch = function(type) {
this.router.raise(type);
};
Object.defineProperty(InlineVideoWrapper.prototype, "elem", {
get: function() {
return this.videoElem;
},
enumerable: true,
configurable: true
});
InlineVideoWrapper.prototype.extractAudioFromVideo = function() {
var _this = this;
this.audioElem = this.contextDocument.createElement("audio");
this.audioElem.id = "iv-inline-audio";
this.audioElem.src = this.source;
this.audioElem.volume = this.videoElem.volume;
this.audioElem.addEventListener("playing", function() {
_this.audioStarted = true;
_this.audioElem.currentTime = _this.videoElem.currentTime;
if (_this.audioPlayListener) {
_this.audioPlayListener.call(_this);
}
});
this.router.setAudioContext(this.audioElem);
};
InlineVideoWrapper.prototype.hideNativePlayButton = function() {
var style = this.contextDocument.createElement("style");
style.innerHTML = "video::-webkit-media-controls-start-playback-button { display: none; }";
this.contextDocument.getElementsByTagName("head")[0].appendChild(style);
};
InlineVideoWrapper.prototype.hideControls = function() {
var style = this.contextDocument.createElement("style");
style.innerHTML = "video::-webkit-media-controls { display:none !important; }";
this.contextDocument.getElementsByTagName("head")[0].appendChild(style);
};
InlineVideoWrapper.prototype.showUnmuteButton = function() {
var _this = this;
var div = this.contextDocument.createElement("div");
var size = (this.width * InlineVideoWrapper.UNMUTE_BUTTON_SCALE);
div.id = "iv-inline-unmute-container";
div.style.width = size + "px";
div.style.height = size + "px";
div.style.top = ((this.top + this.height - 5) - size) + "px";
div.style.left = (this.left + 5) + "px";
div.style.position = "absolute";
div.style.zIndex = "25";
div.style.backgroundImage = "url('___PATH___/assets/images/ui/unmute-button.png')";
div.style.backgroundSize = "cover";
div.onclick = function() {
div.style.display = "none";
_this.playAudio();
};
this.contextDocument.body.appendChild(div);
};
InlineVideoWrapper.prototype.registerToAudioPlayEvent = function(renderCallback) {
this.audioPlayListener = renderCallback;
};
return InlineVideoWrapper;
})();
IV.InlineVideoWrapper = InlineVideoWrapper;
})(IV || (IV = {}));
var IV;
(function(IV) {
var IframeInjector = (function() {
function IframeInjector(id, container, iframeConfig) {
if (container === void 0) {
container = null;
}
if (iframeConfig === void 0) {
iframeConfig = null;
}
this.container = null;
this.id = id;
this.container = container;
this.iframeConfig = iframeConfig ? iframeConfig : this.getDefaultIframeConfig();
}
IframeInjector.prototype.createIframe = function() {
return document.createElement("IFRAME");
};
IframeInjector.prototype.injectIframeIntoDoc = function(targetDoc, createdIframe) {
if (targetDoc === void 0) {
targetDoc = null;
}
if (createdIframe === void 0) {
createdIframe = null;
}
var ifr = (createdIframe) ? createdIframe : this.createIframe();
ifr.id = ("iv-ext-ifr-" + this.id + "-") + (new Date().getTime()).toString();
ifr.width = this.iframeConfig.width;
ifr.height = this.iframeConfig.height;
ifr.frameBorder = this.iframeConfig.border;
this.setIframeSpecificAttributes(ifr);
if (!this.injectIframe(targetDoc, this.container, ifr)) {
return null;
}
return ifr;
};
IframeInjector.prototype.injectIframeOnElement = function(container, ifr) {
if (container) {
container.appendChild(ifr);
return true;
}
return false;
};
IframeInjector.prototype.getDefaultIframeConfig = function() {
return new IV.IframeConfigBuilder().setWidth("0").setHeight("0").setDisplay("none").setBorder("0").build();
};
return IframeInjector;
})();
IV.IframeInjector = IframeInjector;
})(IV || (IV = {}));
var __extends = (this && this.__extends) || function(d, b) {
for (var p in b)
if (b.hasOwnProperty(p)) d[p] = b[p];
function __() {
this.constructor = d;
}
d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
};
var IV;
(function(IV) {
var FriendlyIframeInjector = (function(_super) {
__extends(FriendlyIframeInjector, _super);
function FriendlyIframeInjector() {
_super.apply(this, arguments);
}
FriendlyIframeInjector.prototype.injectIframe = function(targetDoc, container, ifr) {
return this.injectIframeOnElement(targetDoc.body, ifr) || this.injectIframeOnElement(container, ifr);
};
FriendlyIframeInjector.prototype.setIframeSpecificAttributes = function(ifr) {
ifr.style.display = this.iframeConfig.display;
};
return FriendlyIframeInjector;
})(IV.IframeInjector);
IV.FriendlyIframeInjector = FriendlyIframeInjector;
})(IV || (IV = {}));
var IV;
(function(IV) {
var IframeConfig = (function() {
function IframeConfig(builder) {
this._width = builder.width;
this._height = builder.height;
this._display = builder.display;
this._border = builder.border;
this._src = builder.src;
this._zIndex = builder.zIndex;
this._position = builder.position;
this._left = builder.left;
this._top = builder.top;
}
Object.defineProperty(IframeConfig.prototype, "width", {
get: function() {
return this._width;
},
enumerable: true,
configurable: true
});
Object.defineProperty(IframeConfig.prototype, "height", {
get: function() {
return this._height;
},
enumerable: true,
configurable: true
});
Object.defineProperty(IframeConfig.prototype, "display", {
get: function() {
return this._display;
},
enumerable: true,
configurable: true
});
Object.defineProperty(IframeConfig.prototype, "border", {
get: function() {
return this._border;
},
enumerable: true,
configurable: true
});
Object.defineProperty(IframeConfig.prototype, "src", {
get: function() {
return this._src;
},
enumerable: true,
configurable: true
});
Object.defineProperty(IframeConfig.prototype, "zIndex", {
get: function() {
return this._zIndex;
},
enumerable: true,
configurable: true
});
Object.defineProperty(IframeConfig.prototype, "position", {
get: function() {
return this._position;
},
enumerable: true,
configurable: true
});
Object.defineProperty(IframeConfig.prototype, "left", {
get: function() {
return this._left;
},
enumerable: true,
configurable: true
});
Object.defineProperty(IframeConfig.prototype, "top", {
get: function() {
return this._top;
},
enumerable: true,
configurable: true
});
return IframeConfig;
})();
IV.IframeConfig = IframeConfig;
})(IV || (IV = {}));
var IV;
(function(IV) {
var IframeConfigBuilder = (function() {
function IframeConfigBuilder() {}
Object.defineProperty(IframeConfigBuilder.prototype, "width", {
get: function() {
return this._width;
},
enumerable: true,
configurable: true
});
Object.defineProperty(IframeConfigBuilder.prototype, "height", {
get: function() {
return this._height;
},
enumerable: true,
configurable: true
});
Object.defineProperty(IframeConfigBuilder.prototype, "display", {
get: function() {
return this._display;
},
enumerable: true,
configurable: true
});
Object.defineProperty(IframeConfigBuilder.prototype, "zIndex", {
get: function() {
return this._zIndex;
},
enumerable: true,
configurable: true
});
Object.defineProperty(IframeConfigBuilder.prototype, "border", {
get: function() {
return this._border;
},
enumerable: true,
configurable: true
});
Object.defineProperty(IframeConfigBuilder.prototype, "src", {
get: function() {
return this._src;
},
enumerable: true,
configurable: true
});
Object.defineProperty(IframeConfigBuilder.prototype, "position", {
get: function() {
return this._position;
},
enumerable: true,
configurable: true
});
Object.defineProperty(IframeConfigBuilder.prototype, "left", {
get: function() {
return this._left;
},
enumerable: true,
configurable: true
});
Object.defineProperty(IframeConfigBuilder.prototype, "top", {
get: function() {
return this._top;
},
enumerable: true,
configurable: true
});
IframeConfigBuilder.prototype.setWidth = function(value) {
this._width = value;
return this;
};
IframeConfigBuilder.prototype.setHeight = function(value) {
this._height = value;
return this;
};
IframeConfigBuilder.prototype.setDisplay = function(value) {
this._display = value;
return this;
};
IframeConfigBuilder.prototype.setZIndex = function(value) {
this._zIndex = value;
return this;
};
IframeConfigBuilder.prototype.setPosition = function(value) {
this._position = value;
return this;
};
IframeConfigBuilder.prototype.setLeft = function(value) {
this._left = value;
return this;
};
IframeConfigBuilder.prototype.setTop = function(value) {
this._top = value;
return this;
};
IframeConfigBuilder.prototype.setBorder = function(value) {
this._border = value;
return this;
};
IframeConfigBuilder.prototype.setSrc = function(value) {
this._src = value;
return this;
};
IframeConfigBuilder.prototype.build = function() {
return new IV.IframeConfig(this);
};
return IframeConfigBuilder;
})();
IV.IframeConfigBuilder = IframeConfigBuilder;
})(IV || (IV = {}));
var __extends = (this && this.__extends) || function(d, b) {
for (var p in b)
if (b.hasOwnProperty(p)) d[p] = b[p];
function __() {
this.constructor = d;
}
d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
};
var IV;
(function(IV) {
var NonFriendlyIframeInjector = (function(_super) {
__extends(NonFriendlyIframeInjector, _super);
function NonFriendlyIframeInjector() {
_super.apply(this, arguments);
}
NonFriendlyIframeInjector.prototype.injectIframe = function(targetDoc, container, ifr) {
return this.injectIframeOnElement(container, ifr);
};
NonFriendlyIframeInjector.prototype.setIframeSpecificAttributes = function(ifr) {
ifr.src = this.iframeConfig.src;
ifr.style.zIndex = this.iframeConfig.zIndex;
ifr.style.position = this.iframeConfig.position;
ifr.style.left = this.iframeConfig.left;
ifr.style.top = this.iframeConfig.top;
};
return NonFriendlyIframeInjector;
})(IV.IframeInjector);
IV.NonFriendlyIframeInjector = NonFriendlyIframeInjector;
})(IV || (IV = {}));
(function(SCOPE) {
var format;
SCOPE.Events.on("IRollInit", function(core) {
format = new SCOPE.PrerollFormat(core);
});
SCOPE.Events.on("IRollReady", function() {
if (format) {
format.start();
} else {
throw new ReferenceError("format not initialized");
}
});
})(IV);
var VPAIDAd = function() {
this.irollAd = null;
this.width = 0;
this.height = 0;
this.initialWidth = 0;
this.initialHeight = 0;
this.slot = null;
this.videoSlot = null;
this.videoSlotCanAutoPlay = false;
this.callbacks = {};
this.adDuration = -2;
this.adRemainingTime = -2;
this.adExpanded = false;
this.AD_STOP_DELAY_TIME_MS = 200;
this._stopped = false;
this._volume = -1;
this.loggedEvents = [];
this.adStoppableState = false;
this._verificationBlockingHandler = null;
this._adCompletionHandler = null;
this.viewMode = "";
this._surveyHandler = null;
};
VPAIDAd.prototype.initAd = function(width, height, viewMode, desiredBitrate, creativeData, environmentVars) {
var that = this,
initAdStartTime = new Date().getTime(),
doneWaitingForBlockingDecisionOrTimeout = false;
this.initialWidth = this.width = this._dimToNum(width);
this.initialHeight = this.height = this._dimToNum(height);
this.viewMode = viewMode;
this._prepareEnvironmentVars(environmentVars);
this.irollAd = this._createIrollAd();
this._adCompletionHandler = new IV.VpaidAdCompletionHandler(this.irollAd.report);
this._verificationBlockingHandler = new IV.VerificationNonBlockingHandler();
this._surveyHandler = new IV.NonSurveyHandler();
var fireAdLoadedOnce = _.once(function() {
var totalInitAdTime = new Date().getTime() - initAdStartTime;
that.irollAd.report.reportLog({
event_id: "vpaid-init-ad-total-time",
event_value: totalInitAdTime.toString()
});
setTimeout(function() {
that._fire("AdLoaded");
}, 0);
});
this._prepareVideoPlayer(this.videoSlot);
this._prepareCreativeData(creativeData, this.slot, this.videoSlot);
IV.Events.on(this.irollAd.get("id") + ":core_initialized", function() {
if (doneWaitingForBlockingDecisionOrTimeout) {
fireAdLoadedOnce();
}
});
IV.vpaidExtensions.execute(IV.vpaidExtensions.EXTENSION_POINTS.BEFORE_AD_LOAD, this);
setTimeout(function() {
that.irollAd.trigger('init');
that.irollAd.injectCSSToDoc();
}, 0);
this._verificationBlockingHandler.waitForBlockingDecisionOrTimeout(function() {
doneWaitingForBlockingDecisionOrTimeout = true;
if (that.irollAd.get('initialized')) {
fireAdLoadedOnce();
}
});
};
VPAIDAd.prototype.handshakeVersion = function() {
return "2.0";
};
VPAIDAd.prototype.startAd = function() {
var that = this;
this.irollAd.report.reportLog({
event_id: "vpaid-start-ad"
});
this._verificationBlockingHandler.notifyAdStarted();
if (this._verificationBlockingHandler.shouldBlockAd()) {
this._fire("AdStarted");
this.stopAd();
} else {
IV.vpaidExtensions.execute(IV.vpaidExtensions.EXTENSION_POINTS.BEFORE_AD_START, this);
this._mapIRollEventsToVPAID();
this._fire("AdStarted");
this._surveyHandler.waitForBeforeAdAction(function() {
that.irollAd.trigger('start');
});
}
};
VPAIDAd.prototype.stopAd = function() {
var that = this;
this._cleanAdResources(function() {
that._fire("AdStopped");
});
};
VPAIDAd.prototype.resizeAd = function(width, height, viewMode) {
this.width = this._dimToNum(width);
this.height = this._dimToNum(height);
this.viewMode = viewMode;
if (!!this.slot) {
this._fixAdSlotDimensions(this.slot, this.height, this.width);
}
IV.Events.trigger("winResize");
this._fire("AdSizeChange");
};
VPAIDAd.prototype.pauseAd = function() {
this.irollAd.get('videoPlayer').pause();
this._fire("AdPaused");
};
VPAIDAd.prototype.resumeAd = function() {
if (!this.adExpanded) {
this.irollAd.get('videoPlayer').play();
}
this._fire("AdPlaying");
};
VPAIDAd.prototype.expandAd = function() {};
VPAIDAd.prototype.collapseAd = function() {
if (this.adExpanded) {
IV.Events.trigger("closeSlates");
}
};
VPAIDAd.prototype.skipAd = function() {
var that = this;
this._cleanAdResources(function() {
that._fire("AdSkipped");
that._fire("AdStopped");
});
};
VPAIDAd.prototype.subscribe = function(aCallback, eventName, aContext) {
this._subscribe(aCallback, eventName, aContext, false, "VPAID_Internal");
};
VPAIDAd.prototype.safeSubscribe = function(aCallback, eventName, aContext, moduleName) {
this._subscribe(aCallback, eventName, aContext, true, moduleName);
};
VPAIDAd.prototype.unsubscribe = function(aCallback, eventName) {
if (this.callbacks.hasOwnProperty(eventName) && (typeof this.callbacks[eventName] !== "undefined")) {
this.callbacks[eventName] = _.filter(this.callbacks[eventName], function(cb) {
return cb.callback !== aCallback;
});
}
};
VPAIDAd.prototype.getAdExpanded = function() {
return this.adExpanded;
};
VPAIDAd.prototype.getAdSize = function() {
return {
"width": this.width,
"height": this.height
};
};
VPAIDAd.prototype.getAdSkippableState = function() {
return true;
};
VPAIDAd.prototype.getAdWidth = function() {
return this.width;
};
VPAIDAd.prototype.getAdHeight = function() {
return this.height;
};
VPAIDAd.prototype.getAdCompanions = function() {
return "";
};
VPAIDAd.prototype.getAdIcons = function() {
return false;
};
VPAIDAd.prototype.getAdLinear = function() {
return true;
};
VPAIDAd.prototype.setAdVolume = function(vol) {
if (vol !== this._volume) {
this.irollAd.get('videoPlayer').setVolume(vol);
this._volume = vol;
this._fire("AdVolumeChange");
IV.Events.trigger("volumechange", vol);
}
};
VPAIDAd.prototype.getAdVolume = function() {
var vol = this.irollAd.get('videoPlayer').getVolume();
if (vol === -1) {
vol = this._volume;
}
return vol;
};
VPAIDAd.prototype.getAdDuration = function() {
return this.adDuration;
};
VPAIDAd.prototype.getAdRemainingTime = function() {
return this.adRemainingTime;
};
VPAIDAd.prototype.getAdStoppableState = function() {
return this.adStoppableState;
};
VPAIDAd.prototype._subscribe = function(aCallback, eventName, aContext, handleErrors, moduleName) {
var fns = this.callbacks[eventName];
if (!fns) {
fns = [];
this.callbacks[eventName] = fns;
}
fns.push({
"callback": aCallback,
"context": aContext,
"handleErrors": handleErrors,
"module": moduleName
});
};
VPAIDAd.prototype._cleanAdResources = function(callback) {
var that = this;
if (!this._stopped) {
setTimeout(function() {
that.irollAd.cleanUp();
callback();
}, this.AD_STOP_DELAY_TIME_MS);
this._stopped = true;
}
};
VPAIDAd.prototype._fire = function(eventName) {
var props = Array.prototype.slice.call(arguments, 1);
var that = this;
IV.toolkit.debug("VPAID Event -", eventName, props);
var callbacks = this.callbacks[eventName] || [];
callbacks.forEach(function(cb) {
var scope = null;
if (typeof cb.context !== 'undefined') {
scope = cb.context;
}
if (cb.handleErrors) {
try {
cb.callback.apply(scope, props);
} catch (e) {
IV.Events.trigger(that.irollAd.get("id") + ":ad_interface_error", cb.module, e);
}
} else {
cb.callback.apply(scope, props);
}
});
this.loggedEvents.push(eventName);
};
VPAIDAd.prototype._prepareEnvironmentVars = function(environmentVars) {
if (typeof environmentVars !== 'undefined') {
if (environmentVars.hasOwnProperty('slot')) {
this.slot = environmentVars.slot;
this._fixAdSlotDimensions(this.slot, this.initialHeight, this.initialWidth);
}
if (environmentVars.hasOwnProperty('videoSlot')) {
this.videoSlot = environmentVars.videoSlot;
}
if (environmentVars.hasOwnProperty('videoSlotCanAutoPlay')) {
this.videoSlotCanAutoPlay = environmentVars.videoSlotCanAutoPlay;
}
}
};
VPAIDAd.prototype._createIrollAd = function() {
return new IV.AppsCore({
data: IV.baseData.app_data,
config: IV.baseData.config_data,
interface: this,
delayAppVisibility: false,
showClickToResume: true,
BackButton: true,
mainEngagementEvent: "click",
checkForVisibility: false
});
};
VPAIDAd.prototype._prepareVideoPlayer = function(videoSlot) {
if (videoSlot !== null) {
var elementWrapper = new IV.VideoElementWrapper(videoSlot);
var videoPlayer = new IV.SharedVideoPlayer(elementWrapper);
this.irollAd.setAttribute({
"videoPlayer": videoPlayer
});
} else {
this.irollAd.setAttribute({
videoPlayer: new IV.InternalVideoPlayer(this.irollAd, this._volume)
});
}
};
VPAIDAd.prototype._prepareCreativeData = function(creativeData, adSlot, videoSlot) {
if (typeof creativeSettings !== 'undefined') {
this.irollAd.setAttribute(creativeSettings);
}
if (typeof creativeData !== 'undefined') {
var creativeParams = this._parseCreativeParams(creativeData);
this.irollAd.setAttribute(creativeParams);
}
if (adSlot !== null) {
this.irollAd.setAttribute({
"mainContainer": adSlot
});
}
if (videoSlot !== null) {
this.irollAd.setAttribute({
"videoContainer": videoSlot
});
}
};
VPAIDAd.prototype._setAdDuration = function(duration) {
this.adDuration = duration;
};
VPAIDAd.prototype._setAdRemainingTime = function(time) {
this.adRemainingTime = time;
};
VPAIDAd.prototype._mapIRollEventsToVPAID = function() {
var id = this.irollAd.get('id'),
vpaidAd = this,
irollAd = this.irollAd;
IV.Events.on(id + ':ad_started', function() {
vpaidAd._fire('AdImpression');
vpaidAd._fire('AdVideoStart');
});
IV.Events.on(id + ':video_videoPassed25', function() {
vpaidAd._fire('AdVideoFirstQuartile');
});
IV.Events.on(id + ':video_videoPassed50', function() {
vpaidAd._fire('AdVideoMidpoint');
});
IV.Events.on(id + ':video_videoPassed75', function() {
vpaidAd._fire('AdVideoThirdQuartile');
});
IV.Events.on(id + ':video_timeupdate', function() {
vpaidAd._setAdRemainingTime(irollAd.get('videoPlayer').getRemainingTime());
});
[id + ':video_started', id + ':video_durationchange'].forEach(function(eventName) {
IV.Events.on(eventName, function() {
var duration = irollAd.get('videoPlayer').getDuration();
if (duration > 0 && duration !== vpaidAd.getAdDuration()) {
vpaidAd._setAdDuration(duration);
vpaidAd._setAdRemainingTime(duration);
vpaidAd._fire('AdDurationChange');
}
});
});
IV.Events.on(id + ':video_ended', function() {
vpaidAd._fire('AdVideoComplete');
vpaidAd.adStoppableState = true;
vpaidAd._fire("AdStoppableStateChange");
});
IV.Events.on(id + ':ad_ended', function() {
vpaidAd._surveyHandler.waitForAfterAdAction(function() {
vpaidAd._adCompletionHandler.waitForCompletionPixelToBeLoaded(function() {
vpaidAd.stopAd();
});
});
});
IV.Events.on(id + ':skip', function() {
vpaidAd.skipAd();
});
IV.Events.on(id + ':close', function() {
vpaidAd.stopAd();
});
IV.Events.on(id + ':openUrl', function(url) {
vpaidAd._fire('AdClickThru', url, null, true);
vpaidAd._fire("AdPaused");
});
IV.Events.on(id + ':userClick', function() {
vpaidAd._fire('AdInteraction');
});
IV.Events.on(id + ':dialogOpened', function() {
vpaidAd.adExpanded = true;
vpaidAd._fire("AdPaused");
vpaidAd._fire('AdExpandedChange');
});
IV.Events.on(id + ':dialogClosed', function() {
vpaidAd.adExpanded = false;
vpaidAd._fire('AdExpandedChange');
vpaidAd._fire("AdPlaying");
});
["slateOpened", "surveyOpened"].forEach(function(ev) {
IV.Events.on(id + ':' + ev, function() {
vpaidAd.adExpanded = true;
vpaidAd._fire("AdPaused");
vpaidAd._fire('AdExpandedChange');
});
});
["slateClosed", "surveyClosed"].forEach(function(ev) {
IV.Events.on(id + ':' + ev, function() {
vpaidAd.adExpanded = false;
vpaidAd._fire('AdExpandedChange');
vpaidAd._fire("AdPlaying");
});
});
IV.Events.on(id + ':video_error', function() {
setTimeout(function() {
vpaidAd.irollAd.cleanUp();
vpaidAd._fire("AdError");
}, vpaidAd.AD_STOP_DELAY_TIME_MS);
});
IV.Events.on(id + ":video_controls_play", function() {
vpaidAd._fire("AdPlaying");
});
};
VPAIDAd.prototype._parseCreativeParams = function(creativeData) {
function _str2bool(str) {
return str == "true" ? true : ((str == "false") ? false : str);
}
var createDataObj = {};
var creativeDataString = "";
if (creativeData) {
if (creativeData.hasOwnProperty("AdParameters") && typeof creativeData.AdParameters === 'string') {
creativeDataString = creativeData.AdParameters;
} else if (typeof creativeData === 'string') {
creativeDataString = creativeData;
}
_.each(creativeDataString.split(';'), function(param) {
var parts = param.split('=');
if (parts.length == 2) {
createDataObj[parts[0]] = _str2bool(parts[1]);
}
});
}
return createDataObj;
};
VPAIDAd.prototype._dimToNum = function(dim) {
return Number(dim) || 0;
};
VPAIDAd.prototype._fixAdSlotDimensions = function(slot, height, width) {
if (typeof slot.style !== "undefined") {
if ($(slot).height() === 0) {
$(slot).height(height);
}
if ($(slot).width() === 0) {
$(slot).width(width);
}
}
};
VPAIDAd.prototype._overrideSurveyHandler = function(handler) {
this._surveyHandler = handler;
}
VPAIDAd.prototype._overrideVerificationBlockingHandlerAndStartTimer = function(handler) {
this._verificationBlockingHandler = handler;
handler.startTimeoutTimer();
};
(function(SCOPE) {
SCOPE.VPAIDExtensions = function() {
var extensions = {};
this.EXTENSION_POINTS = {
"BEFORE_AD_LOAD": 1,
"BEFORE_AD_START": 2
};
this.PRIORTIES = {
"LOW": 1,
"HIGH": 2,
"MONITOR": 3
};
this.PRIORITY_ORDER = [this.PRIORTIES.LOW, this.PRIORTIES.HIGH, this.PRIORTIES.MONITOR];
this.register = function(func, extensionPoint, priority) {
if (typeof priority === "undefined") {
priority = this.PRIORTIES.LOW;
}
if (!extensions.hasOwnProperty(extensionPoint)) {
extensions[extensionPoint] = {};
_.each(this.PRIORTIES, function(val) {
extensions[extensionPoint][val] = [];
});
}
extensions[extensionPoint][priority].push(func);
};
this.unregisterAll = function() {
extensions = {};
};
this.execute = function(extPoint, context) {
if (extensions.hasOwnProperty(extPoint)) {
_.each(this.PRIORITY_ORDER, function(pr) {
_.each(extensions[extPoint][pr], function(func) {
func.call(this, context);
});
});
}
};
};
SCOPE.vpaidExtensions = new SCOPE.VPAIDExtensions();
})(IV);
(function(SCOPE) {
SCOPE.VPAIDAdProxy = function(vpaidAd) {
var wrapAndLogWithArgs = function(func, funcName) {
return function() {
func.apply(vpaidAd, arguments);
SCOPE.toolkit.debug("VPAID method -", funcName, "(", Array.prototype.slice.call(arguments), ")");
};
};
var wrapAndLogReturnValue = function(func, funcName) {
return function() {
var returnValue = func.apply(vpaidAd, arguments);
SCOPE.toolkit.debug("VPAID method -", funcName, "(", returnValue, ")");
return returnValue;
};
};
var vpaidSpec = {
initAd: wrapAndLogWithArgs(vpaidAd.initAd, "initAd"),
handshakeVersion: vpaidAd.handshakeVersion.bind(vpaidAd),
startAd: wrapAndLogWithArgs(vpaidAd.startAd, "startAd"),
stopAd: wrapAndLogWithArgs(vpaidAd.stopAd, "stopAd"),
pauseAd: wrapAndLogWithArgs(vpaidAd.pauseAd, "pauseAd"),
resumeAd: wrapAndLogWithArgs(vpaidAd.resumeAd, "resumeAd"),
resizeAd: wrapAndLogWithArgs(vpaidAd.resizeAd, "resizeAd"),
expandAd: wrapAndLogWithArgs(vpaidAd.expandAd, "expandAd"),
collapseAd: wrapAndLogWithArgs(vpaidAd.collapseAd, "collapseAd"),
skipAd: wrapAndLogWithArgs(vpaidAd.skipAd, "skipAd"),
subscribe: vpaidAd.subscribe.bind(vpaidAd),
unsubscribe: vpaidAd.unsubscribe.bind(vpaidAd),
getAdExpanded: wrapAndLogReturnValue(vpaidAd.getAdExpanded, "getAdExpanded"),
getAdSkippableState: wrapAndLogReturnValue(vpaidAd.getAdSkippableState, "getAdSkippableState"),
getAdWidth: wrapAndLogReturnValue(vpaidAd.getAdWidth, "getAdWidth"),
getAdHeight: wrapAndLogReturnValue(vpaidAd.getAdHeight, "getAdHeight"),
getAdCompanions: wrapAndLogReturnValue(vpaidAd.getAdCompanions, "getAdCompanions"),
getAdIcons: wrapAndLogReturnValue(vpaidAd.getAdIcons, "getAdIcons"),
getAdLinear: wrapAndLogReturnValue(vpaidAd.getAdLinear, "getAdLinear"),
getAdVolume: wrapAndLogReturnValue(vpaidAd.getAdVolume, "getAdVolume"),
getAdDuration: wrapAndLogReturnValue(vpaidAd.getAdDuration, "getAdDuration"),
getAdRemainingTime: wrapAndLogReturnValue(vpaidAd.getAdRemainingTime, "getAdRemainingTime"),
getAdStoppableState: wrapAndLogReturnValue(vpaidAd.getAdStoppableState, "getAdStoppableState"),
setAdVolume: wrapAndLogWithArgs(vpaidAd.setAdVolume, "setAdVolume")
};
return vpaidSpec;
}
})(IV);
var getVPAIDAd = (function() {
var vpaidAdProxy = IV.VPAIDAdProxy(new VPAIDAd());
return function() {
return vpaidAdProxy;
}
})();
(function(SCOPE) {
SCOPE.vpaidExtensions.register(function VPAIDFullScreenDetection(vpaidAd) {
vardoc = vpaidAd.slot.ownerDocument, videoSlot = vpaidAd.videoSlot, _isFullScreen = false;
function toggleFullScreen(isFullScreen) {
_isFullScreen = isFullScreen;
if (isFullScreen) {
if (screen.width > 0 && screen.height > 0) {
vpaidAd.resizeAd(screen.width, screen.height);
}
} else {
vpaidAd.resizeAd(vpaidAd.initialWidth, vpaidAd.initialHeight);
}
}
$(doc).on("fullscreenchange", function() {
toggleFullScreen(doc["fullscreen"]);
}).on("mozfullscreenchange", function() {
toggleFullScreen(doc["mozFullScreen"]);
}).on("webkitfullscreenchange", function() {
toggleFullScreen(doc["webkitIsFullScreen"]);
}).on("MSFullscreenChange", function() {
toggleFullScreen(!!doc["msFullscreenElement"]);
});
$(videoSlot).on("webkitbeginfullscreen", function() {
toggleFullScreen(true);
}).on("webkitendfullscreen", function() {
toggleFullScreen(false);
});
var view = doc.parentWindow || doc.defaultView;
$(view).on("orientationchange", function() {
setTimeout(function() {
if (_isFullScreen) {
vpaidAd.resizeAd($(view).width(), $(view).height());
}
}, 300);
});
}, SCOPE.vpaidExtensions.EXTENSION_POINTS.BEFORE_AD_START);
})(IV);
var IV;
(function(IV) {
var VpaidPixelLoadedHandler = (function() {
function VpaidPixelLoadedHandler(actionName) {
this.pixelFired = false;
this.actionName = actionName;
}
VpaidPixelLoadedHandler.prototype.waitForPixelToFire = function(firedCb) {
if (firedCb) {
this.firedCb = _.once(firedCb);
if (this.pixelFired) {
this.firedCb();
}
}
};
VpaidPixelLoadedHandler.prototype.postFiredPixel = function() {
this.pixelFired = this.wasPixelFired();
if (this.pixelFired) {
if (this.firedCb) {
this.firedCb();
}
}
};
return VpaidPixelLoadedHandler;
})();
IV.VpaidPixelLoadedHandler = VpaidPixelLoadedHandler;
})(IV || (IV = {}));
var __extends = (this && this.__extends) || function(d, b) {
for (var p in b)
if (b.hasOwnProperty(p)) d[p] = b[p];
function __() {
this.constructor = d;
}
d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
};
var IV;
(function(IV) {
var VpaidAdCompletionHandler = (function(_super) {
__extends(VpaidAdCompletionHandler, _super);
function VpaidAdCompletionHandler(irollReporter) {
var _this = this;
_super.call(this, VpaidAdCompletionHandler.QUARTILES_ACTION_NAME);
this.timerId = null;
this.irollReporter = irollReporter;
this.irollReporter.addPostLoadedPixelCallback(function() {
return _this.postFiredPixel();
}, VpaidAdCompletionHandler.QUARTILES_ACTION_NAME);
}
Object.defineProperty(VpaidAdCompletionHandler, "COMPLETION_PIXEL_TIMEOUT_MS", {
get: function() {
return 1000;
},
enumerable: true,
configurable: true
});
Object.defineProperty(VpaidAdCompletionHandler, "COMPLETION_TIMEOUT_EVENT_ID", {
get: function() {
return "vpaid-completion-pixel-timeout";
},
enumerable: true,
configurable: true
});
Object.defineProperty(VpaidAdCompletionHandler, "QUARTILES_ACTION_NAME", {
get: function() {
return "vpoint";
},
enumerable: true,
configurable: true
});
Object.defineProperty(VpaidAdCompletionHandler, "QUARTILES_EVENT_ID", {
get: function() {
return "percent";
},
enumerable: true,
configurable: true
});
Object.defineProperty(VpaidAdCompletionHandler, "COMPLETION_PIXEL_OPTIONS", {
get: function() {
return {
action: VpaidAdCompletionHandler.QUARTILES_ACTION_NAME,
event_id: VpaidAdCompletionHandler.QUARTILES_EVENT_ID,
event_value: 100
};
},
enumerable: true,
configurable: true
});;
VpaidAdCompletionHandler.prototype.postFiredPixel = function() {
if (this.wasPixelFired() && this.timerId) {
clearTimeout(this.timerId);
this.timerId = null;
}
_super.prototype.postFiredPixel.call(this);
};
VpaidAdCompletionHandler.prototype.wasPixelFired = function() {
return this.irollReporter.wasPixelLoaded(VpaidAdCompletionHandler.COMPLETION_PIXEL_OPTIONS);
};
VpaidAdCompletionHandler.prototype.waitForCompletionPixelToBeLoaded = function(loadedCb) {
var _this = this;
this.waitForPixelToFire(loadedCb);
if (!this.pixelFired) {
this.timerId = setTimeout(function() {
if (!_this.pixelFired) {
_this.timerId = null;
_this.irollReporter.reportLog({
event_id: VpaidAdCompletionHandler.COMPLETION_TIMEOUT_EVENT_ID,
event_value: VpaidAdCompletionHandler.COMPLETION_PIXEL_TIMEOUT_MS.toString()
});
}
loadedCb();
}, VpaidAdCompletionHandler.COMPLETION_PIXEL_TIMEOUT_MS);
}
};
return VpaidAdCompletionHandler;
})(IV.VpaidPixelLoadedHandler);
IV.VpaidAdCompletionHandler = VpaidAdCompletionHandler;
})(IV || (IV = {}));
var IV;
(function(IV) {
var VerificationNonBlockingHandler = (function() {
function VerificationNonBlockingHandler() {}
VerificationNonBlockingHandler.prototype.waitForBlockingDecisionOrTimeout = function(postWaitCallback) {
postWaitCallback();
};
VerificationNonBlockingHandler.prototype.shouldBlockAd = function() {
return false;
};
VerificationNonBlockingHandler.prototype.notifyAdStarted = function() {};
VerificationNonBlockingHandler.prototype.startTimeoutTimer = function() {};
return VerificationNonBlockingHandler;
})();
IV.VerificationNonBlockingHandler = VerificationNonBlockingHandler;
})(IV || (IV = {}));
var IV;
(function(IV) {
var NonSurveyHandler = (function() {
function NonSurveyHandler() {}
NonSurveyHandler.prototype.waitForBeforeAdAction = function(postCallback) {
postCallback();
};
NonSurveyHandler.prototype.waitForAfterAdAction = function(postCallback) {
postCallback();
};
return NonSurveyHandler;
})();
IV.NonSurveyHandler = NonSurveyHandler;
})(IV || (IV = {}));
(function(SCOPE) {
SCOPE.VPAIDAdWrapper = function(vpaidAd, moduleName) {
this.handshakeVersion = function() {
return vpaidAd.handshakeVersion();
};
this.subscribe = function(aCallback, eventName, aContext) {
if (typeof aContext === "undefined") aContext = this;
vpaidAd.safeSubscribe(aCallback, eventName, aContext, moduleName);
};
this.unsubscribe = function(aCallback, eventName) {
vpaidAd.unsubscribe(aCallback, eventName);
};
this.getAdExpanded = function() {
return vpaidAd.getAdExpanded();
};
this.getAdSize = function() {
return vpaidAd.getAdSize();
};
this.getAdSkippableState = function() {
return vpaidAd.getAdSkippableState();
};
this.getAdWidth = function() {
return vpaidAd.getAdWidth();
};
this.getAdHeight = function() {
return vpaidAd.getAdHeight();
};
this.getAdCompanions = function() {
return vpaidAd.getAdCompanions();
};
this.getAdIcons = function() {
return vpaidAd.getAdIcons();
};
this.getAdLinear = function() {
return vpaidAd.getAdLinear();
};
this.getAdVolume = function() {
return vpaidAd.getAdVolume();
};
this.getAdDuration = function() {
return vpaidAd.getAdDuration();
};
this.getAdRemainingTime = function() {
return vpaidAd.getAdRemainingTime();
};
this.getPlayer = function() {
var player = vpaidAd.videoSlot;
return _.isElement(player) ? player : null;
};
this.getSlot = function() {
return vpaidAd.slot;
};
this.getPreviousEvents = function() {
return vpaidAd.loggedEvents;
};
this.getViewMode = function() {
return vpaidAd.viewMode;
}
};
})(IV);;
var IV;
(function(IV) {
var IframeInjection = (function() {
function IframeInjection() {}
IframeInjection.prototype.setInjection = function(fn) {
this.injectionFn = fn;
};
IframeInjection.prototype.onTimeout = function(fn) {
this.timeoutCb = fn;
};
IframeInjection.prototype.onInjection = function(fn) {
this.injectCb = fn;
};
IframeInjection.prototype.inject = function() {
if (this.injectCb) {
this.injectCb();
}
if (this.injectionFn) {
return this.injectionFn();
} else {
return null;
}
};
IframeInjection.prototype.timeout = function() {
this.timeoutCb && this.timeoutCb();
};
return IframeInjection;
})();
IV.IframeInjection = IframeInjection;
})(IV || (IV = {}));
var IV;
(function(IV) {
var IframeIntegrationLoader = (function() {
function IframeIntegrationLoader(vpaidWrapper, irollReporter, iframeInjector) {
this.scriptLoaded = false;
this.integrationTimeoutTimerId = null;
this.irollReporter = irollReporter;
this.vpaidWrapper = vpaidWrapper;
this.iframeInjector = iframeInjector;
this.randomIframeContextName = this.generateRandomIframeContextName();
}
Object.defineProperty(IframeIntegrationLoader, "MONITORING_LOAD_TIMEOUT_MS", {
get: function() {
return 5000;
},
enumerable: true,
configurable: true
});
Object.defineProperty(IframeIntegrationLoader, "SCRIPT_STATE", {
get: function() {
return {
READY: "READY",
NOT_READY: "NOT READY"
};
},
enumerable: true,
configurable: true
});
Object.defineProperty(IframeIntegrationLoader, "INTEGRATION_CALLBACK_NAME", {
get: function() {
return "ivOnIntegrationReady";
},
enumerable: true,
configurable: true
});
Object.defineProperty(IframeIntegrationLoader, "IFRAME_CONTEXT_NAME", {
get: function() {
return "ivIfrIntCtxObj";
},
enumerable: true,
configurable: true
});
IframeIntegrationLoader.prototype.load = function(targetWindow, injectionContext) {
var _this = this;
this.injection = injectionContext;
this.vpaidWrapper.subscribe(function() {
_this.adImpression();
}, "AdImpression");
var injectedIframe = this.iframeInjector.injectIframeIntoDoc(targetWindow.document);
this.injection.onTimeout(function() {
_this.reportTimeoutError();
});
this.integrationTimeoutTimerId = setTimeout(function() {
_this.injection.timeout();
}, IframeIntegrationLoader.MONITORING_LOAD_TIMEOUT_MS);
this.injection.onInjection(function() {
_this.stopTimeoutTimer();
_this.scriptLoaded = true;
});
if (injectedIframe) {
injectedIframe.contentWindow[this.randomIframeContextName] = targetWindow;
this.injectScriptIntoIframe(targetWindow, injectedIframe);
}
};
IframeIntegrationLoader.prototype.reportTimeoutError = function() {
this.irollReporter.reportLog({
event_id: this.timeoutErrorEventId(),
event_value: IframeIntegrationLoader.MONITORING_LOAD_TIMEOUT_MS.toString()
});
};
IframeIntegrationLoader.prototype.isScriptLoaded = function() {
return this.scriptLoaded;
};
IframeIntegrationLoader.prototype.adImpression = function() {
var evtValue = this.isScriptLoaded() ? IframeIntegrationLoader.SCRIPT_STATE.READY : IframeIntegrationLoader.SCRIPT_STATE.NOT_READY;
this.irollReporter.reportLog({
event_id: this.impressionEventId(),
event_value: evtValue
});
};
IframeIntegrationLoader.prototype.generateRandomIframeContextName = function() {
var randomNumber = Math.floor(Math.random() * Math.pow(10, 9));
return IframeIntegrationLoader.IFRAME_CONTEXT_NAME + "_" + randomNumber.toString(10);
};
IframeIntegrationLoader.prototype.stopTimeoutTimer = function() {
if (this.integrationTimeoutTimerId) {
clearTimeout(this.integrationTimeoutTimerId);
}
};
return IframeIntegrationLoader;
})();
IV.IframeIntegrationLoader = IframeIntegrationLoader;
})(IV || (IV = {}));;
var __extends = (this && this.__extends) || function(d, b) {
for (var p in b)
if (b.hasOwnProperty(p)) d[p] = b[p];
function __() {
this.constructor = d;
}
d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
};
var IV;
(function(IV) {
var DvIntegrationLoader = (function(_super) {
__extends(DvIntegrationLoader, _super);
function DvIntegrationLoader(vpaidWrapper, irollReporter, iframeInjector, loadableScript) {
_super.call(this, vpaidWrapper, irollReporter, iframeInjector);
this.loadableScript = loadableScript;
}
Object.defineProperty(DvIntegrationLoader, "IMPRESSION_EVENT_NAME", {
get: function() {
return "dv-impression";
},
enumerable: true,
configurable: true
});
Object.defineProperty(DvIntegrationLoader, "TIMEOUT_ERROR_EVENT_ID", {
get: function() {
return "dv-not-loaded";
},
enumerable: true,
configurable: true
});
DvIntegrationLoader.prototype.injectScriptIntoIframe = function(targetWindow, injectedIframe) {
var _this = this;
var ifrDoc = injectedIframe.contentWindow.document;
this.injection.setInjection(function() {
return _this.vpaidWrapper;
});
targetWindow[DvIntegrationLoader.INTEGRATION_CALLBACK_NAME] = function() {
return _this.injection.inject();
};
this.writeScriptInsideIframe(ifrDoc);
};
DvIntegrationLoader.prototype.writeScriptInsideIframe = function(ifrDoc) {
ifrDoc.open().write("\n <body onload=\"addSrc()\">\n <script>\n function addSrc() {\n var js = document.createElement('script');\n js.async = true;\n js.src = '" + this.loadableScript.scriptUrl + "';\n document.body.appendChild(js);\n }\n function " + this.loadableScript.scriptCallBackName + "() { return " + this.randomIframeContextName + "." + DvIntegrationLoader.INTEGRATION_CALLBACK_NAME + "(); }\n </script>\n </body>");
ifrDoc.close();
};
DvIntegrationLoader.prototype.timeoutErrorEventId = function() {
return DvIntegrationLoader.TIMEOUT_ERROR_EVENT_ID;
};
DvIntegrationLoader.prototype.impressionEventId = function() {
return DvIntegrationLoader.IMPRESSION_EVENT_NAME;
};
return DvIntegrationLoader;
})(IV.IframeIntegrationLoader);
IV.DvIntegrationLoader = DvIntegrationLoader;
})(IV || (IV = {}));
var IV;
(function(IV) {
var DvScriptComposer = (function() {
function DvScriptComposer() {}
Object.defineProperty(DvScriptComposer, "CALLBACK_READY_NAME", {
get: function() {
return "dvReady";
},
enumerable: true,
configurable: true
});
DvScriptComposer.prototype.compose = function(adConfig) {
return {
scriptUrl: this.createSourceUrl(adConfig),
scriptCallBackName: DvScriptComposer.CALLBACK_READY_NAME
};
};
DvScriptComposer.prototype.createSourceUrl = function(adConfig) {
var values = this.urlQueryValues(adConfig);
var dvTemplateUrl = this.scriptTemplateUrl(adConfig);
var compiledTemplate = _.template(dvTemplateUrl);
return compiledTemplate(values);
};
DvScriptComposer.prototype.scriptTemplateUrl = function(adConfig) {
return adConfig.config_data["dv"]["url"];
};
DvScriptComposer.prototype.urlQueryValues = function(adConfig) {
var placementConfig = adConfig.app_data["placement-config"];
var dvClientId = adConfig.app_data["service-config"]["dv"]["clientId"];
return {
"ctx": dvClientId,
"cmp": placementConfig["campaign-id"],
"sid": placementConfig["publisher-id"],
"plc": placementConfig["placements-group-id"],
"cb": DvScriptComposer.CALLBACK_READY_NAME
};
};
return DvScriptComposer;
})();
IV.DvScriptComposer = DvScriptComposer;
})(IV || (IV = {}));
var IV;
(function(IV) {
var VerificationBlockingConfig = (function() {
function VerificationBlockingConfig(decisionHandler, timeoutHandler, useRealBlocking, irollReporter, integrationName) {
this._decisionHandler = decisionHandler;
this._timeoutHandler = timeoutHandler;
this._useRealBlocking = useRealBlocking;
this._irollReporter = irollReporter;
this._integrationName = integrationName;
}
Object.defineProperty(VerificationBlockingConfig.prototype, "decisionHandler", {
get: function() {
return this._decisionHandler;
},
enumerable: true,
configurable: true
});
Object.defineProperty(VerificationBlockingConfig.prototype, "timeoutHandler", {
get: function() {
return this._timeoutHandler;
},
enumerable: true,
configurable: true
});
Object.defineProperty(VerificationBlockingConfig.prototype, "useRealBlocking", {
get: function() {
return this._useRealBlocking;
},
enumerable: true,
configurable: true
});
Object.defineProperty(VerificationBlockingConfig.prototype, "irollReporter", {
get: function() {
return this._irollReporter;
},
enumerable: true,
configurable: true
});
Object.defineProperty(VerificationBlockingConfig.prototype, "integrationName", {
get: function() {
return this._integrationName;
},
enumerable: true,
configurable: true
});
return VerificationBlockingConfig;
})();
IV.VerificationBlockingConfig = VerificationBlockingConfig;
})(IV || (IV = {}));
var IV;
(function(IV) {
var VerificationBlockingDecisionHandler = (function() {
function VerificationBlockingDecisionHandler(irollReporter, vpaidWrapper) {
this.decisionMade = false;
this.irollReporter = irollReporter;
this.vpaidWrapper = vpaidWrapper;
this.registerToAdVideoComplete();
}
Object.defineProperty(VerificationBlockingDecisionHandler, "AD_COMPLETE_EVENT_VALUE", {
get: function() {
return "ad_complete";
},
enumerable: true,
configurable: true
});
VerificationBlockingDecisionHandler.prototype.decisionWasOnTime = function(decision) {
this.decisionMade = true;
this.irollReporter.reportLog({
event_id: this.blockingDecisionEventIdPrefix() + "-on-time",
event_value: this.toDecisionString(decision)
});
};
VerificationBlockingDecisionHandler.prototype.decisionWasTooLate = function(decision, totalTime) {
this.decisionMade = true;
this.irollReporter.reportLog({
event_id: this.blockingDecisionEventIdPrefix() + "-after-timeout-total",
event_value: totalTime.toString()
});
this.irollReporter.reportLog({
event_id: this.blockingDecisionEventIdPrefix() + "-after-timeout-value",
event_value: this.toDecisionString(decision)
});
};
VerificationBlockingDecisionHandler.prototype.isDecisionMade = function() {
return this.decisionMade;
};
VerificationBlockingDecisionHandler.prototype.toDecisionString = function(decision) {
return decision.toString();
};
VerificationBlockingDecisionHandler.prototype.registerToAdVideoComplete = function() {
var _this = this;
this.vpaidWrapper.subscribe(function() {
return _this.onAdComplete();
}, "AdVideoComplete", this);
};
VerificationBlockingDecisionHandler.prototype.onAdComplete = function() {
if (!this.isDecisionMade()) {
this.irollReporter.reportLog({
event_id: this.blockingDecisionEventIdPrefix() + "-not-made",
event_value: VerificationBlockingDecisionHandler.AD_COMPLETE_EVENT_VALUE
});
}
};
return VerificationBlockingDecisionHandler;
})();
IV.VerificationBlockingDecisionHandler = VerificationBlockingDecisionHandler;
})(IV || (IV = {}));
var IV;
(function(IV) {
var VerificationBlockingHandler = (function() {
function VerificationBlockingHandler(verificationBlockingConfig) {
this.blockAd = false;
this.startTime = 0;
this.decisionTime = 0;
this.adStarted = false;
this.decisionHandler = verificationBlockingConfig.decisionHandler;
this.timeoutHandler = verificationBlockingConfig.timeoutHandler;
this.useRealBlocking = verificationBlockingConfig.useRealBlocking;
this.irollReporter = verificationBlockingConfig.irollReporter;
this.integrationName = verificationBlockingConfig.integrationName;
}
VerificationBlockingHandler.prototype.waitForBlockingDecisionOrTimeout = function(postWaitCallback) {
this.postWaitCallback = postWaitCallback;
if (this.decisionHandler.isDecisionMade() || this.timeoutHandler.isTimeoutOccurred()) {
this.timeoutHandler.stopTimer();
this.postWaitCallback();
}
};
VerificationBlockingHandler.prototype.shouldBlockAd = function() {
if (this.blockAd) {
return this.useRealBlocking;
}
return false;
};
VerificationBlockingHandler.prototype.onDecisionMade = function(decision) {
this.decisionTime = new Date().getTime();
this.blockAd = this.decisionHandler.shouldBlockAd(decision);
if (!this.isAdStarted()) {
this.timeoutHandler.stopTimer();
this.decisionHandler.decisionWasOnTime(decision);
if (this.postWaitCallback && !this.timeoutHandler.isTimeoutOccurred()) {
this.postWaitCallback();
}
} else {
this.decisionHandler.decisionWasTooLate(decision, this.decisionTime - this.startTime);
}
};
VerificationBlockingHandler.prototype.startTimeoutTimer = function() {
var _this = this;
this.startTime = new Date().getTime();
this.timeoutHandler.startTimer(function() {
if (_this.postWaitCallback) {
_this.postWaitCallback();
}
});
};
VerificationBlockingHandler.prototype.notifyAdStarted = function() {
this.adStarted = true;
if (!this.decisionHandler.isDecisionMade() && this.timeoutHandler.isTimeoutOccurred()) {
this.reportBlockingDecisionTimedOut();
}
};
VerificationBlockingHandler.prototype.eventIdForBlockingTimeout = function() {
return this.integrationName + "-blocking-timeout";
};
VerificationBlockingHandler.prototype.reportBlockingDecisionTimedOut = function() {
this.irollReporter.reportLog({
event_id: this.eventIdForBlockingTimeout(),
event_value: this.timeoutHandler.getTimeoutValueMs().toString()
});
};
VerificationBlockingHandler.prototype.isAdStarted = function() {
return this.adStarted;
};
return VerificationBlockingHandler;
})();
IV.VerificationBlockingHandler = VerificationBlockingHandler;
})(IV || (IV = {}));
var IV;
(function(IV) {
var VerificationBlockingTimeoutHandler = (function() {
function VerificationBlockingTimeoutHandler(timeoutMs) {
this.timeoutOccurred = false;
this.timeoutMs = timeoutMs;
}
VerificationBlockingTimeoutHandler.prototype.startTimer = function(onTimeoutCallback) {
var _this = this;
this.timerId = setTimeout(function() {
_this.timeoutOccurred = true;
_this.timerId = null;
onTimeoutCallback();
}, this.timeoutMs);
};
VerificationBlockingTimeoutHandler.prototype.stopTimer = function() {
if (this.timerId) {
clearTimeout(this.timerId);
this.timerId = null;
}
};
VerificationBlockingTimeoutHandler.prototype.isTimeoutOccurred = function() {
return this.timeoutOccurred;
};
VerificationBlockingTimeoutHandler.prototype.getTimeoutValueMs = function() {
return this.timeoutMs;
};
return VerificationBlockingTimeoutHandler;
})();
IV.VerificationBlockingTimeoutHandler = VerificationBlockingTimeoutHandler;
})(IV || (IV = {}));
var IV;
(function(IV) {
var DvBlockingAcknowledgeHandler = (function() {
function DvBlockingAcknowledgeHandler(irollReporter) {
this.ackCallback = null;
this.readyToAck = false;
this.irollReporter = irollReporter;
}
Object.defineProperty(DvBlockingAcknowledgeHandler, "BLOCKING_ACKNOWLEDGE_EVENT_ID", {
get: function() {
return "dv-blocking-acknowledge";
},
enumerable: true,
configurable: true
});
DvBlockingAcknowledgeHandler.prototype.setAckCallback = function(ackCallback) {
var _this = this;
if (!this.ackCallback && !!ackCallback) {
this.ackCallback = _.once(function(wasAdPlayed, wasBlockingDecisionUsed, cStartTS, cEndTS, dReceivedTS) {
ackCallback(wasAdPlayed, wasBlockingDecisionUsed, cStartTS, cEndTS, dReceivedTS);
_this.irollReporter.reportLog({
event_id: DvBlockingAcknowledgeHandler.BLOCKING_ACKNOWLEDGE_EVENT_ID,
event_value: _this.acknowledgeValue(wasAdPlayed, wasBlockingDecisionUsed)
});
_this.irollReporter.reportLog({
event_id: DvBlockingAcknowledgeHandler.BLOCKING_ACKNOWLEDGE_EVENT_ID + "-total-decision-window",
event_value: (cEndTS - cStartTS).toString()
});
_this.irollReporter.reportLog({
event_id: DvBlockingAcknowledgeHandler.BLOCKING_ACKNOWLEDGE_EVENT_ID + "-decision-time",
event_value: (dReceivedTS - cStartTS).toString()
});
});
} else {
this.irollReporter.reportLog({
event_id: DvBlockingAcknowledgeHandler.BLOCKING_ACKNOWLEDGE_EVENT_ID + "-undefined",
event_value: "undefined_or_twice"
});
}
};
DvBlockingAcknowledgeHandler.prototype.acknowledge = function(wasAdPlayed, wasBlockingDecisionUsed, cStartTS, cEndTS, dReceivedTS) {
if (!!this.ackCallback) {
this.ackCallback(wasAdPlayed, wasBlockingDecisionUsed, cStartTS, cEndTS, dReceivedTS);
} else {
this.readyToAck = true;
}
};
DvBlockingAcknowledgeHandler.prototype.isReadyToAck = function() {
return this.readyToAck;
};
DvBlockingAcknowledgeHandler.prototype.acknowledgeValue = function(wasAdPlayed, wasBlockingDecisionUsed) {
return (wasAdPlayed ? "played" : "blocked") + ";" + (wasBlockingDecisionUsed ? "used" : "ignored");
};
return DvBlockingAcknowledgeHandler;
})();
IV.DvBlockingAcknowledgeHandler = DvBlockingAcknowledgeHandler;
})(IV || (IV = {}));
var __extends = (this && this.__extends) || function(d, b) {
for (var p in b)
if (b.hasOwnProperty(p)) d[p] = b[p];
function __() {
this.constructor = d;
}
d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
};
var IV;
(function(IV) {
var DvBlockingDecisionHandler = (function(_super) {
__extends(DvBlockingDecisionHandler, _super);
function DvBlockingDecisionHandler() {
_super.apply(this, arguments);
}
Object.defineProperty(DvBlockingDecisionHandler, "BLOCKING_DECISION_EVENT_ID", {
get: function() {
return "dv-blocking-decision";
},
enumerable: true,
configurable: true
});
Object.defineProperty(DvBlockingDecisionHandler, "BLOCKING_DECISION", {
get: function() {
return {
BLOCK: 1,
ALLOW: 2,
UNKNOWN: 3
};
},
enumerable: true,
configurable: true
});
DvBlockingDecisionHandler.prototype.shouldBlockAd = function(decision) {
return decision === DvBlockingDecisionHandler.BLOCKING_DECISION.BLOCK;
};
DvBlockingDecisionHandler.prototype.blockingDecisionEventIdPrefix = function() {
return DvBlockingDecisionHandler.BLOCKING_DECISION_EVENT_ID;
};
DvBlockingDecisionHandler.prototype.toDecisionString = function(decision) {
var stringMap = {};
stringMap[DvBlockingDecisionHandler.BLOCKING_DECISION.BLOCK] = "block";
stringMap[DvBlockingDecisionHandler.BLOCKING_DECISION.ALLOW] = "allow";
stringMap[DvBlockingDecisionHandler.BLOCKING_DECISION.UNKNOWN] = "unknown";
return stringMap[decision];
};
return DvBlockingDecisionHandler;
})(IV.VerificationBlockingDecisionHandler);
IV.DvBlockingDecisionHandler = DvBlockingDecisionHandler;
})(IV || (IV = {}));
var __extends = (this && this.__extends) || function(d, b) {
for (var p in b)
if (b.hasOwnProperty(p)) d[p] = b[p];
function __() {
this.constructor = d;
}
d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
};
var IV;
(function(IV) {
var DvBlockingHandler = (function(_super) {
__extends(DvBlockingHandler, _super);
function DvBlockingHandler(verificationBlockingConfig, vpaidWrapper, acknowledgeHandler) {
_super.call(this, verificationBlockingConfig);
this.cStartTS = 0;
this.cEndTS = 0;
this.dReceivedTS = 0;
this.blockingDecisionOccurredBeforeAdStarted = false;
this.vpaidWrapper = vpaidWrapper;
this.acknowledgeHandler = acknowledgeHandler;
this.registerToAdImpression();
}
DvBlockingHandler.prototype.notifyAdStarted = function() {
this.cEndTS = new Date().getTime();
this.blockingDecisionOccurredBeforeAdStarted = this.decisionHandler.isDecisionMade();
if (this.blockAd) {
this.acknowledge();
}
_super.prototype.notifyAdStarted.call(this);
};
DvBlockingHandler.prototype.onDecisionMadeWithAckCallback = function(decision, ackCallback) {
this.dReceivedTS = new Date().getTime();
this.acknowledgeHandler.setAckCallback(ackCallback);
_super.prototype.onDecisionMade.call(this, decision);
if (this.acknowledgeHandler.isReadyToAck()) {
this.acknowledge();
}
};
DvBlockingHandler.prototype.acknowledge = function() {
this.acknowledgeHandler.acknowledge(this.wasAdPlayed(), this.wasBlockingDecisionUsed(), this.cStartTS, this.cEndTS, this.dReceivedTS);
};
DvBlockingHandler.prototype.wasAdPlayed = function() {
return !this.blockAd || !this.wasBlockingDecisionUsed();
};
DvBlockingHandler.prototype.wasBlockingDecisionUsed = function() {
return this.blockingDecisionOccurredBeforeAdStarted;
};
DvBlockingHandler.prototype.registerToAdImpression = function() {
var _this = this;
this.vpaidWrapper.subscribe(function() {
return _this.acknowledge();
}, "AdImpression", this);
};
DvBlockingHandler.prototype.notifyBlockingScriptInjected = function() {
this.cStartTS = new Date().getTime();
};
DvBlockingHandler.prototype.isBlockDecision = function(decision) {
return this.decisionHandler.shouldBlockAd(decision);
};
return DvBlockingHandler;
})(IV.VerificationBlockingHandler);
IV.DvBlockingHandler = DvBlockingHandler;
})(IV || (IV = {}));
var __extends = (this && this.__extends) || function(d, b) {
for (var p in b)
if (b.hasOwnProperty(p)) d[p] = b[p];
function __() {
this.constructor = d;
}
d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
};
var IV;
(function(IV) {
var DvBlockingIntegrationLoader = (function(_super) {
__extends(DvBlockingIntegrationLoader, _super);
function DvBlockingIntegrationLoader(vpaidWrapper, irollReporter, iframeInjector, loadableScript, blockingHandler) {
_super.call(this, vpaidWrapper, irollReporter, iframeInjector, loadableScript);
this.blockingHandler = blockingHandler;
}
Object.defineProperty(DvBlockingIntegrationLoader, "BLOCKING_DECISION_CALLBACK_NAME", {
get: function() {
return "ivOnIntegrationBlockingDecision";
},
enumerable: true,
configurable: true
});
Object.defineProperty(DvBlockingIntegrationLoader, "BLOCKING_SCRIPT_INJECTION_CALLBACK_NAME", {
get: function() {
return "ivOnDvScriptInjection";
},
enumerable: true,
configurable: true
});
DvBlockingIntegrationLoader.prototype.load = function(targetWindow, injectionContext) {
this.doLoadAsync(targetWindow, injectionContext);
};
DvBlockingIntegrationLoader.prototype.doLoadAsync = function(targetWindow, injectionContext) {
var _this = this;
setTimeout(function() {
_super.prototype.load.call(_this, targetWindow, injectionContext);
}, 0);
};
DvBlockingIntegrationLoader.prototype.injectScriptIntoIframe = function(targetWindow, injectedIframe) {
this.registerBlockingScriptInjectionCallback(targetWindow);
this.registerBlockingDecisionCallback(targetWindow, injectedIframe.contentWindow);
_super.prototype.injectScriptIntoIframe.call(this, targetWindow, injectedIframe);
};
DvBlockingIntegrationLoader.prototype.writeScriptInsideIframe = function(ifrDoc) {
ifrDoc.open().write("\n <body>\n \n <script> \n function " + this.loadableScript.scriptCallBackName + "() { \n return " + this.randomIframeContextName + "." + DvBlockingIntegrationLoader.INTEGRATION_CALLBACK_NAME + "(); \n }\n \n function " + this.loadableScript.blockingCallbackName + "(decision, ackCallbackName) { \n " + this.randomIframeContextName + "." + DvBlockingIntegrationLoader.BLOCKING_DECISION_CALLBACK_NAME + "(decision, ackCallbackName); \n } \n </script> \n \n <script>\n " + this.randomIframeContextName + "." + DvBlockingIntegrationLoader.BLOCKING_SCRIPT_INJECTION_CALLBACK_NAME + "();\n </script>\n \n <script type=\"text/javascript\" src=\"" + this.loadableScript.scriptUrl + "\"></script> \n \n </body>");
ifrDoc.close();
};
DvBlockingIntegrationLoader.prototype.registerBlockingDecisionCallback = function(targetWindow, iframeWindow) {
var _this = this;
targetWindow[DvBlockingIntegrationLoader.BLOCKING_DECISION_CALLBACK_NAME] = function(decision, ackCallbackName) {
if (_this.blockingHandler.isBlockDecision(decision)) {
_this.stopTimeoutTimer();
}
_this.blockingHandler.onDecisionMadeWithAckCallback(decision, iframeWindow[ackCallbackName]);
};
};
DvBlockingIntegrationLoader.prototype.registerBlockingScriptInjectionCallback = function(targetWindow) {
var _this = this;
targetWindow[DvBlockingIntegrationLoader.BLOCKING_SCRIPT_INJECTION_CALLBACK_NAME] = function() {
_this.blockingHandler.notifyBlockingScriptInjected();
};
};
return DvBlockingIntegrationLoader;
})(IV.DvIntegrationLoader);
IV.DvBlockingIntegrationLoader = DvBlockingIntegrationLoader;
})(IV || (IV = {}));
var __extends = (this && this.__extends) || function(d, b) {
for (var p in b)
if (b.hasOwnProperty(p)) d[p] = b[p];
function __() {
this.constructor = d;
}
d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
};
var IV;
(function(IV) {
var DvBlockingScriptComposer = (function(_super) {
__extends(DvBlockingScriptComposer, _super);
function DvBlockingScriptComposer() {
_super.apply(this, arguments);
}
Object.defineProperty(DvBlockingScriptComposer, "BLOCKING_CALLBACK_NAME", {
get: function() {
return "dvBlockingDecision";
},
enumerable: true,
configurable: true
});
DvBlockingScriptComposer.prototype.compose = function(adConfig) {
var loadableScript = _super.prototype.compose.call(this, adConfig);
loadableScript.blockingCallbackName = DvBlockingScriptComposer.BLOCKING_CALLBACK_NAME;
return loadableScript;
};
DvBlockingScriptComposer.prototype.scriptTemplateUrl = function(adConfig) {
return adConfig.config_data["dv"]["blocking-url"];
};
DvBlockingScriptComposer.prototype.urlQueryValues = function(adConfig) {
var values = _super.prototype.urlQueryValues.call(this, adConfig);
values["bcb"] = DvBlockingScriptComposer.BLOCKING_CALLBACK_NAME;
return values;
};
return DvBlockingScriptComposer;
})(IV.DvScriptComposer);
IV.DvBlockingScriptComposer = DvBlockingScriptComposer;
})(IV || (IV = {}));
(function(SCOPE) {
SCOPE.vpaidExtensions.register(function(vpaidAd) {
var INTEGRATION_NAME = "dv";
var dvConfig = SCOPE.baseData.app_data["service-config"]["dv"],
timeoutMs = dvConfig["timeout"],
useRealBlocking = dvConfig["useRealBlocking"];
var loadableScript = new SCOPE.DvBlockingScriptComposer().compose(SCOPE.baseData);
var vpaidWrapper = new SCOPE.VPAIDAdWrapper(vpaidAd, INTEGRATION_NAME);
var iframeInjector = new SCOPE.FriendlyIframeInjector(INTEGRATION_NAME, vpaidAd.slot);
var reporter = vpaidAd.irollAd.report;
var decisionHandler = new SCOPE.DvBlockingDecisionHandler(reporter, vpaidWrapper),
timeoutHandler = new SCOPE.VerificationBlockingTimeoutHandler(timeoutMs),
acknowledgeHandler = new SCOPE.DvBlockingAcknowledgeHandler(reporter);
var blockingHandlerConfig = new SCOPE.VerificationBlockingConfig(decisionHandler, timeoutHandler, useRealBlocking, reporter, INTEGRATION_NAME);
var blockingHandler = new SCOPE.DvBlockingHandler(blockingHandlerConfig, vpaidWrapper, acknowledgeHandler);
vpaidAd._overrideVerificationBlockingHandlerAndStartTimer(blockingHandler);
var dvLoader = new SCOPE.DvBlockingIntegrationLoader(vpaidWrapper, reporter, iframeInjector, loadableScript, blockingHandler);
dvLoader.load(window, new IV.IframeInjection());
}, SCOPE.vpaidExtensions.EXTENSION_POINTS.BEFORE_AD_LOAD);
})(IV);
(function(SCOPE) {
SCOPE.VPAIDAdWrapper = function(vpaidAd, moduleName) {
this.handshakeVersion = function() {
return vpaidAd.handshakeVersion();
};
this.subscribe = function(aCallback, eventName, aContext) {
if (typeof aContext === "undefined") aContext = this;
vpaidAd.safeSubscribe(aCallback, eventName, aContext, moduleName);
};
this.unsubscribe = function(aCallback, eventName) {
vpaidAd.unsubscribe(aCallback, eventName);
};
this.getAdExpanded = function() {
return vpaidAd.getAdExpanded();
};
this.getAdSize = function() {
return vpaidAd.getAdSize();
};
this.getAdSkippableState = function() {
return vpaidAd.getAdSkippableState();
};
this.getAdWidth = function() {
return vpaidAd.getAdWidth();
};
this.getAdHeight = function() {
return vpaidAd.getAdHeight();
};
this.getAdCompanions = function() {
return vpaidAd.getAdCompanions();
};
this.getAdIcons = function() {
return vpaidAd.getAdIcons();
};
this.getAdLinear = function() {
return vpaidAd.getAdLinear();
};
this.getAdVolume = function() {
return vpaidAd.getAdVolume();
};
this.getAdDuration = function() {
return vpaidAd.getAdDuration();
};
this.getAdRemainingTime = function() {
return vpaidAd.getAdRemainingTime();
};
this.getPlayer = function() {
var player = vpaidAd.videoSlot;
return _.isElement(player) ? player : null;
};
this.getSlot = function() {
return vpaidAd.slot;
};
this.getPreviousEvents = function() {
return vpaidAd.loggedEvents;
};
this.getViewMode = function() {
return vpaidAd.viewMode;
}
};
})(IV);
var __extends = (this && this.__extends) || function(d, b) {
for (var p in b)
if (b.hasOwnProperty(p)) d[p] = b[p];
function __() {
this.constructor = d;
}
d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
};
var IV;
(function(IV) {
var VpaidAdImpressionHandler = (function(_super) {
__extends(VpaidAdImpressionHandler, _super);
function VpaidAdImpressionHandler(irollReporter) {
var _this = this;
_super.call(this, VpaidAdImpressionHandler.IMPRESSION_ACTION_NAME);
this.irollReporter = irollReporter;
this.irollReporter.addPostReportedPixelCallback(function() {
return _this.postFiredPixel();
}, VpaidAdImpressionHandler.IMPRESSION_ACTION_NAME);
}
Object.defineProperty(VpaidAdImpressionHandler, "IMPRESSION_PIXEL_TIMEOUT_MS", {
get: function() {
return 5000;
},
enumerable: true,
configurable: true
});
Object.defineProperty(VpaidAdImpressionHandler, "IMPRESSION_TIMEOUT_EVENT_ID", {
get: function() {
return "vpaid-impression-pixel-timeout";
},
enumerable: true,
configurable: true
});
Object.defineProperty(VpaidAdImpressionHandler, "IMPRESSION_ACTION_NAME", {
get: function() {
return "play";
},
enumerable: true,
configurable: true
});
Object.defineProperty(VpaidAdImpressionHandler, "IMPRESSION_PIXEL_OPTIONS", {
get: function() {
return {
action: VpaidAdImpressionHandler.IMPRESSION_ACTION_NAME
};
},
enumerable: true,
configurable: true
});;
VpaidAdImpressionHandler.prototype.wasPixelFired = function() {
return this.irollReporter.wasPixelReported(VpaidAdImpressionHandler.IMPRESSION_PIXEL_OPTIONS);
};
VpaidAdImpressionHandler.prototype.waitForImpressionPixelToBeReported = function(loadedCb) {
var _this = this;
this.waitForPixelToFire(loadedCb);
if (!this.pixelFired) {
setTimeout(function() {
if (!_this.pixelFired) {
_this.irollReporter.reportLog({
event_id: VpaidAdImpressionHandler.IMPRESSION_TIMEOUT_EVENT_ID,
event_value: VpaidAdImpressionHandler.IMPRESSION_PIXEL_TIMEOUT_MS.toString()
});
}
}, VpaidAdImpressionHandler.IMPRESSION_PIXEL_TIMEOUT_MS);
}
};
return VpaidAdImpressionHandler;
})(IV.VpaidPixelLoadedHandler);
IV.VpaidAdImpressionHandler = VpaidAdImpressionHandler;
})(IV || (IV = {}));
(function(SCOPE) {
SCOPE.vpaidExtensions.register(function(vpaidAd) {
var INTEGRATION_NAME = SCOPE.ViewabilityManager.MODULE_NAME;
var globalCoreEventsId = vpaidAd.irollAd.get("id");
var reporter = vpaidAd.irollAd.report;
var isInApp = SCOPE.device.isInApp();
var SCREEN_OFFSET = isInApp ? 0 : 50;
var vpaidWrapper = new SCOPE.VPAIDAdWrapper(vpaidAd, INTEGRATION_NAME);
var defaultViewabilityObject = new SCOPE.ViewabilityCheckResult();
var geometryCalculator = new SCOPE.GeometryCalculator();
var intersectionObserverCalculator = new SCOPE.IntersectionObserverCalculator(defaultViewabilityObject);
var domObscuringCalculator = new IV.DomObscuringCalculator(document);
var fullscreenHelper = new SCOPE.FullscreenHelper(SCREEN_OFFSET);
var viewabilityCalculator = new SCOPE.ViewabilityCalculator(window, defaultViewabilityObject, geometryCalculator, intersectionObserverCalculator, domObscuringCalculator, fullscreenHelper);
var adSizeChangeHelper = new SCOPE.ViewabilityAdSizeChangeHelper(window, vpaidWrapper, viewabilityCalculator, fullscreenHelper);
var viewabilityReporters = isInApp ? [new SCOPE.ViewabilityLogsReporter(reporter), new SCOPE.ViewabilityStatsReporter(reporter)] : [new SCOPE.ViewabilityStatsReporter(reporter)];
var viewabilityEventsDispatcher = new SCOPE.ViewabilityEventsDispatcher(vpaidAd.irollAd.fireTrackingEvent.bind(vpaidAd.irollAd));
var listener = new SCOPE.ViewabilityListener(globalCoreEventsId, viewabilityCalculator);
var videoPlayer = vpaidAd.irollAd.get("videoPlayer");
var adImpressionHanlder = new SCOPE.VpaidAdImpressionHandler(reporter);
var manager = new SCOPE.ViewabilityManager(globalCoreEventsId, vpaidWrapper, listener, viewabilityReporters, viewabilityCalculator, viewabilityEventsDispatcher, adImpressionHanlder, adSizeChangeHelper, videoPlayer);
manager.start();
}, SCOPE.vpaidExtensions.EXTENSION_POINTS.BEFORE_AD_LOAD);
})(IV);;
var IV;
(function(IV) {
var ViewabilityAdSizeChangeHelper = (function() {
function ViewabilityAdSizeChangeHelper(contextWindow, vpaidWrapper, viewabilityCalculator, fullscreenHelper) {
this.contextWindow = contextWindow;
this.vpaidWrapper = vpaidWrapper;
this.viewabilityCalculator = viewabilityCalculator;
this.fullscreenHelper = fullscreenHelper;
}
ViewabilityAdSizeChangeHelper.prototype.listenToSizeChange = function() {
var _this = this;
this.vpaidWrapper.subscribe(function() {
return _this.onAdSizeChange();
}, "AdSizeChange", this);
};
ViewabilityAdSizeChangeHelper.prototype.onAdSizeChange = function() {
var width = this.vpaidWrapper.getAdWidth();
var height = this.vpaidWrapper.getAdHeight();
this.viewabilityCalculator.toggleFullscreen(this.fullscreenHelper.isSameOrBiggerThanScreenSize(this.contextWindow, width, height));
};
return ViewabilityAdSizeChangeHelper;
})();
IV.ViewabilityAdSizeChangeHelper = ViewabilityAdSizeChangeHelper;
})(IV || (IV = {}));
var IV;
(function(IV) {
var ViewabilityConsecutiveTimeResult = (function() {
function ViewabilityConsecutiveTimeResult(_checkResult, _ctTime, _ctCountThreshold, _ctFocus) {
this.checkResult = _checkResult;
this.ctTime = _ctTime;
this.ctCountThreshold = _ctCountThreshold;
this.ctFocus = _ctFocus;
}
ViewabilityConsecutiveTimeResult.prototype.setVolume = function(volume) {
this.checkResult.volume = volume;
};
ViewabilityConsecutiveTimeResult.prototype.toString = function() {
return this.checkResult.toString() + ";" + this.ctTime + ";" + this.ctCountThreshold + ";" + this.ctFocus;
};
return ViewabilityConsecutiveTimeResult;
})();
IV.ViewabilityConsecutiveTimeResult = ViewabilityConsecutiveTimeResult;
})(IV || (IV = {}));
var IV;
(function(IV) {
var ViewabilityEventsDispatcher = (function() {
function ViewabilityEventsDispatcher(fireTrackingEventCb) {
this.fireTrackingEventCb = fireTrackingEventCb;
}
ViewabilityEventsDispatcher.prototype.dispatchMeasurableEvent = function() {
this.fireTrackingEventCb("measurable");
};
ViewabilityEventsDispatcher.prototype.dispatchViewableEvent = function() {
this.fireTrackingEventCb("viewable");
};
return ViewabilityEventsDispatcher;
})();
IV.ViewabilityEventsDispatcher = ViewabilityEventsDispatcher;
})(IV || (IV = {}));
var IV;
(function(IV) {
var ViewabilityListener = (function() {
function ViewabilityListener(globalCoreEventsId, viewabilityCalculator) {
this.videoTimeUpdateFn = null;
this.lastTime = 0;
this.accumulatedTime = 0;
this.paused = false;
this.globalCoreEventsId = globalCoreEventsId;
this.viewabilityCalculator = viewabilityCalculator;
}
Object.defineProperty(ViewabilityListener, "MINIMUM_INTERVAL", {
get: function() {
return 150;
},
enumerable: true,
configurable: true
});
Object.defineProperty(ViewabilityListener, "VIEWABLE_DURATION", {
get: function() {
return 2000;
},
enumerable: true,
configurable: true
});
ViewabilityListener.prototype.onVideoTimeUpdate = function(viewabilityElement, adSlot, onMeasurable, onConsecutiveTime, onError) {
if (this.isPaused()) {
return;
}
var currentTime = (new Date()).getTime();
if (this.lastTime === 0) {
this.lastTime = currentTime;
return;
}
try {
var result = this.viewabilityCalculator.checkViewability(viewabilityElement, adSlot);
if (result.isMeasurable()) {
onMeasurable(result);
}
if (result.isViewable()) {
this.accumulatedTime += currentTime - this.lastTime;
this.lastTime = currentTime;
if (this.accumulatedTime >= ViewabilityListener.VIEWABLE_DURATION) {
this.stop();
onConsecutiveTime(new IV.ViewabilityConsecutiveTimeResult(result, this.accumulatedTime, 1, result.focusState));
}
} else {
this.reset();
}
} catch (e) {
onError(e);
}
};
ViewabilityListener.prototype.start = function(viewabilityElement, adSlot, onMeasurable, onConsecutiveTime, onError) {
if (!this.isStarted()) {
this.registerToPlayPause();
this.videoTimeUpdateFn = this.throttleTimeUpdateCallback(viewabilityElement, adSlot, onMeasurable, onConsecutiveTime, onError);
IV.Events.on(this.globalCoreEventsId + ":video_timeupdate", this.videoTimeUpdateFn);
}
};
ViewabilityListener.prototype.resume = function() {
this.paused = false;
};
ViewabilityListener.prototype.pause = function() {
this.paused = true;
this.lastTime = 0;
};
ViewabilityListener.prototype.stop = function() {
if (this.isStarted()) {
IV.Events.off(this.globalCoreEventsId + ":video_timeupdate", this.videoTimeUpdateFn);
this.videoTimeUpdateFn = null;
}
};
ViewabilityListener.prototype.reset = function() {
this.accumulatedTime = 0;
this.lastTime = 0;
};
ViewabilityListener.prototype.isStarted = function() {
return !!this.videoTimeUpdateFn;
};
ViewabilityListener.prototype.isPaused = function() {
return this.paused;
};
ViewabilityListener.prototype.throttleTimeUpdateCallback = function(viewabilityElement, adSlot, onMeasurable, onConsecutiveTime, onError) {
var _this = this;
return _.throttle(function() {
return _this.onVideoTimeUpdate(viewabilityElement, adSlot, onMeasurable, onConsecutiveTime, onError);
}, ViewabilityListener.MINIMUM_INTERVAL, {
trailing: false
});
};
ViewabilityListener.prototype.registerToPlayPause = function() {
var _this = this;
IV.Events.on(this.globalCoreEventsId + ":video_play", function() {
_this.resume();
});
IV.Events.on(this.globalCoreEventsId + ":video_pause", function() {
_this.pause();
});
};
return ViewabilityListener;
})();
IV.ViewabilityListener = ViewabilityListener;
})(IV || (IV = {}));
var IV;
(function(IV) {
var ViewabilityLogsReporter = (function() {
function ViewabilityLogsReporter(reporter) {
this.reporter = reporter;
}
ViewabilityLogsReporter.prototype.reportViewability = function(eventId, checkResult) {
this.reporter.reportLog({
event_id: IV.ViewabilityPixelEvents.ACTION_NAME + "_" + eventId,
event_value: checkResult.toString()
});
};
ViewabilityLogsReporter.prototype.reportConsecutiveTime = function(consecutiveTimeResult) {
this.reporter.reportLog({
event_id: IV.ViewabilityPixelEvents.ACTION_NAME + "_" + IV.ViewabilityPixelEvents.EventId.CONSECUTIVE_TIME,
event_value: consecutiveTimeResult.toString()
});
};
return ViewabilityLogsReporter;
})();
IV.ViewabilityLogsReporter = ViewabilityLogsReporter;
})(IV || (IV = {}));
var IV;
(function(IV) {
var ViewabilityManager = (function() {
function ViewabilityManager(globalCoreEventsId, vpaidWrapper, viewabilityListener, viewabilityReporters, viewabilityCalculator, viewabilityEventsDispatcher, adImpressionHandler, adSizeChangeHelper, player) {
this.impressionOccurred = false;
this.globalCoreEventsId = globalCoreEventsId;
this.vpaidWrapper = vpaidWrapper;
this.viewabilityListener = viewabilityListener;
this.viewabilityReporters = viewabilityReporters;
this.viewabilityCalculator = viewabilityCalculator;
this.viewabilityEventsDispatcher = viewabilityEventsDispatcher;
this.adImpressionHandler = adImpressionHandler;
this.adSizeChangeHelper = adSizeChangeHelper;
this.player = player;
var videoSlot = this.vpaidWrapper.getPlayer();
this.adSlot = this.vpaidWrapper.getSlot();
this.viewabilityElement = videoSlot !== null ? videoSlot : this.adSlot;
this.reportVp1sOnce = _.once(this.reportVP1S);
this.reportConsecutiveTimeOnce = _.once(this.reportConsecutiveTime);
}
Object.defineProperty(ViewabilityManager, "MODULE_NAME", {
get: function() {
return "innovid_viewability";
},
enumerable: true,
configurable: true
});
ViewabilityManager.prototype.start = function() {
var _this = this;
this.adSizeChangeHelper.listenToSizeChange();
try {
this.viewabilityCalculator.initialize(this.viewabilityElement);
} catch (e) {
this.reportError(e);
}
this.vpaidWrapper.subscribe(function() {
return _this.onAdImpression();
}, "AdImpression", this);
this.vpaidWrapper.subscribe(function() {
return _this.onAdFirstQuartile();
}, "AdVideoFirstQuartile", this);
this.vpaidWrapper.subscribe(function() {
return _this.onAdMidpoint();
}, "AdVideoMidpoint", this);
this.vpaidWrapper.subscribe(function() {
return _this.onAdThirdQuartile();
}, "AdVideoThirdQuartile", this);
this.vpaidWrapper.subscribe(function() {
return _this.onAdComplete();
}, "AdVideoComplete", this);
this.vpaidWrapper.subscribe(function() {
return _this.onAdPaused();
}, "AdPaused", this);
this.vpaidWrapper.subscribe(function() {
return _this.onAdPlaying();
}, "AdPlaying", this);
this.vpaidWrapper.subscribe(function() {
return _this.onAdStopped();
}, "AdStopped", this);
this.vpaidWrapper.subscribe(function() {
return _this.onAdStopped();
}, "AdError", this);
};
ViewabilityManager.prototype.onAdImpression = function() {
var _this = this;
this.adImpressionHandler.waitForImpressionPixelToBeReported(function() {
_this.impressionOccurred = true;
_this.checkAndReportViewability(IV.ViewabilityPixelEvents.EventId.VP_START);
_this.startCheckingViewability();
});
};
ViewabilityManager.prototype.startCheckingViewability = function() {
var _this = this;
this.viewabilityListener.start(this.viewabilityElement, this.adSlot, function(result) {
_this.reportVp1sOnce(result);
}, function(result) {
_this.reportConsecutiveTimeOnce(result);
}, function(e) {
return _this.reportError(e);
});
};
ViewabilityManager.prototype.onAdFirstQuartile = function() {
this.checkAndReportViewability(IV.ViewabilityPixelEvents.EventId.VP_FIRST_QUARTILE);
};
ViewabilityManager.prototype.onAdMidpoint = function() {
this.checkAndReportViewability(IV.ViewabilityPixelEvents.EventId.VP_MIDPOINT);
};
ViewabilityManager.prototype.onAdThirdQuartile = function() {
this.checkAndReportViewability(IV.ViewabilityPixelEvents.EventId.VP_THIRD_QUARTILE);
};
ViewabilityManager.prototype.onAdComplete = function() {
var FORCE_VP1S = true;
this.checkAndReportViewability(IV.ViewabilityPixelEvents.EventId.VP_COMPLETE, FORCE_VP1S);
this.viewabilityListener.stop();
};
ViewabilityManager.prototype.onAdPaused = function() {
this.viewabilityListener.pause();
};
ViewabilityManager.prototype.onAdPlaying = function() {
this.viewabilityListener.resume();
};
ViewabilityManager.prototype.onAdStopped = function() {
try {
this.viewabilityListener.stop();
if (this.impressionOccurred) {
var result = this.viewabilityCalculator.checkViewability(this.viewabilityElement, this.adSlot);
this.reportVp1sOnce(result);
}
this.viewabilityCalculator.dispose();
} catch (e) {
this.reportError(e);
}
};
ViewabilityManager.prototype.checkAndReportViewability = function(eventId, forceVp1s) {
if (forceVp1s === void 0) {
forceVp1s = false;
}
try {
var result = this.viewabilityCalculator.checkViewability(this.viewabilityElement, this.adSlot);
result.volume = this.getVolume();
for (var _i = 0, _a = this.viewabilityReporters; _i < _a.length; _i++) {
var viewabilityReporter = _a[_i];
viewabilityReporter.reportViewability(eventId, result);
}
if (forceVp1s || result.isMeasurable()) {
this.reportVp1sOnce(result);
}
} catch (e) {
this.reportError(e);
}
};
ViewabilityManager.prototype.reportConsecutiveTime = function(result) {
var _this = this;
if (this.impressionOccurred) {
result.setVolume(this.getVolume());
for (var _i = 0, _a = this.viewabilityReporters; _i < _a.length; _i++) {
var viewabilityReporter = _a[_i];
viewabilityReporter.reportConsecutiveTime(result);
}
this.dispatchAsyncEvent(function() {
return _this.viewabilityEventsDispatcher.dispatchViewableEvent();
});
}
};
ViewabilityManager.prototype.reportVP1S = function(result) {
var _this = this;
if (this.impressionOccurred) {
for (var _i = 0, _a = this.viewabilityReporters; _i < _a.length; _i++) {
var viewabilityReporter = _a[_i];
viewabilityReporter.reportViewability(IV.ViewabilityPixelEvents.EventId.VP_1S, result);
}
this.dispatchAsyncEvent(function() {
return _this.viewabilityEventsDispatcher.dispatchMeasurableEvent();
});
}
};
ViewabilityManager.prototype.reportError = function(e) {
IV.Events.trigger(this.globalCoreEventsId + ":ad_interface_error", ViewabilityManager.MODULE_NAME, e);
};
ViewabilityManager.prototype.getVolume = function() {
var volume = this.player.getVolume();
return volume >= 0 ? volume * 100 : 0;
};
ViewabilityManager.prototype.dispatchAsyncEvent = function(eventCallback) {
setTimeout(eventCallback, 0);
};
return ViewabilityManager;
})();
IV.ViewabilityManager = ViewabilityManager;
})(IV || (IV = {}));
var IV;
(function(IV) {
var ViewabilityPixelEvents = (function() {
function ViewabilityPixelEvents() {}
Object.defineProperty(ViewabilityPixelEvents, "ACTION_NAME", {
get: function() {
return "viewability";
},
enumerable: true,
configurable: true
});
Object.defineProperty(ViewabilityPixelEvents, "EventId", {
get: function() {
return {
VP_START: "vp000",
VP_FIRST_QUARTILE: "vp025",
VP_MIDPOINT: "vp050",
VP_THIRD_QUARTILE: "vp075",
VP_COMPLETE: "vp100",
VP_1S: "vp1s",
CONSECUTIVE_TIME: "consecutiveTime"
};
},
enumerable: true,
configurable: true
});
return ViewabilityPixelEvents;
})();
IV.ViewabilityPixelEvents = ViewabilityPixelEvents;
})(IV || (IV = {}));
var IV;
(function(IV) {
var ViewabilityStatsReporter = (function() {
function ViewabilityStatsReporter(reporter) {
this.reporter = reporter;
}
ViewabilityStatsReporter.prototype.reportViewability = function(eventId, checkResult) {
this.reporter.submit({
action: IV.ViewabilityPixelEvents.ACTION_NAME,
event_id: eventId,
event_value: checkResult.toString()
});
};
ViewabilityStatsReporter.prototype.reportConsecutiveTime = function(consecutiveTimeResult) {
this.reporter.submit({
action: IV.ViewabilityPixelEvents.ACTION_NAME,
event_id: IV.ViewabilityPixelEvents.EventId.CONSECUTIVE_TIME,
event_value: consecutiveTimeResult.toString()
});
};
return ViewabilityStatsReporter;
})();
IV.ViewabilityStatsReporter = ViewabilityStatsReporter;
})(IV || (IV = {}));
var IV;
(function(IV) {
var DomElementUtils = (function() {
function DomElementUtils() {}
Object.defineProperty(DomElementUtils, "ELEMENT_NODE_TYPE", {
get: function() {
return 1;
},
enumerable: true,
configurable: true
});
DomElementUtils.getObjectRect = function(elem) {
var objRect = null;
if (elem && (elem.getClientRects || elem.getBoundingClientRect)) {
try {
objRect = elem.getClientRects()[0];
} catch (e) {
objRect = elem.getBoundingClientRect();
}
}
return objRect;
};
DomElementUtils.getOverlappingArea = function(rect, elem) {
var playerArea = rect.width * rect.height;
var xOverlap = Math.max(0, Math.min(rect.right, elem.right) - Math.max(rect.left, elem.left));
var yOverlap = Math.max(0, Math.min(rect.bottom, elem.bottom) - Math.max(rect.top, elem.top));
return (xOverlap * yOverlap) / playerArea;
};
DomElementUtils.isDomElement = function(elem) {
return !!(elem && elem.nodeType === DomElementUtils.ELEMENT_NODE_TYPE);
};
return DomElementUtils;
})();
IV.DomElementUtils = DomElementUtils;
})(IV || (IV = {}));
var IV;
(function(IV) {
var DomObscuringCalculator = (function() {
function DomObscuringCalculator(contextDocument) {
this.contextDocument = contextDocument;
}
DomObscuringCalculator.prototype.checkDomObscuring = function(player, adSlot) {
var playerRect = IV.DomElementUtils.getObjectRect(player),
offset = 12,
xLeft = playerRect.left + offset,
xRight = playerRect.right - offset,
yTop = playerRect.top + offset,
yBottom = playerRect.bottom - offset,
xCenter = Math.floor(playerRect.left + playerRect.width / 2),
yCenter = Math.floor(playerRect.top + playerRect.height / 2),
testPoints = [{
x: xLeft,
y: yTop
}, {
x: xCenter,
y: yTop
}, {
x: xRight,
y: yTop
}, {
x: xLeft,
y: yCenter
}, {
x: xCenter,
y: yCenter
}, {
x: xRight,
y: yCenter
}, {
x: xLeft,
y: yBottom
}, {
x: xCenter,
y: yBottom
}, {
x: xRight,
y: yBottom
}];
for (var p in testPoints) {
if (testPoints[p] && testPoints[p].x >= 0 && testPoints[p].y >= 0) {
var elem = this.contextDocument.elementFromPoint(testPoints[p].x, testPoints[p].y);
if (elem !== null && elem !== player && !player.contains(elem)) {
var isPartOfAdSlot = typeof adSlot !== "undefined" ? adSlot.contains(elem) : false;
if (!isPartOfAdSlot) {
var overlappingArea = IV.DomElementUtils.getOverlappingArea(playerRect, IV.DomElementUtils.getObjectRect(elem));
if (overlappingArea > 0) {
return 100 * overlappingArea;
}
}
}
}
}
return 0;
};
return DomObscuringCalculator;
})();
IV.DomObscuringCalculator = DomObscuringCalculator;
})(IV || (IV = {}));
var IV;
(function(IV) {
var FullscreenHelper = (function() {
function FullscreenHelper(screenOffset) {
this.screenOffset = screenOffset;
}
Object.defineProperty(FullscreenHelper, "FULLSCREEN_ATTRIBUTES", {
get: function() {
return ["fullscreen", "webkitIsFullScreen", "mozFullScreen", "msFullscreenElement", "webkitFullscreenElement"];
},
enumerable: true,
configurable: true
});
FullscreenHelper.prototype.isFullscreen = function(adSlot, contextWindow, friendlyIframe) {
var isFS = this.isDocumentFullscreen(contextWindow.document, adSlot) || this.isElementSizeFullscreen(contextWindow, adSlot);
var currWindow = contextWindow;
while (!isFS && friendlyIframe && currWindow !== currWindow.parent) {
currWindow = currWindow.parent;
isFS = this.isDocumentFullscreen(currWindow.document);
}
return isFS;
};
FullscreenHelper.prototype.isElementSizeFullscreen = function(contextWindow, adSlot) {
if (adSlot) {
var width = adSlot.clientWidth;
var height = adSlot.clientHeight;
return this.isSameOrBiggerThanScreenSize(contextWindow, width, height);
}
return false;
};
FullscreenHelper.prototype.isSameOrBiggerThanScreenSize = function(contextWindow, width, height) {
var screenWidth = contextWindow.screen.width;
var screenHeight = contextWindow.screen.height;
return this.isScreenSizeValid(screenWidth, screenHeight) && (this.isPortraitFullscreen(width, height, screenWidth, screenHeight) || this.isLandscapeFullscreen(width, height, screenWidth, screenHeight));
};
FullscreenHelper.prototype.isPortraitFullscreen = function(width, height, screenWidth, screenHeight) {
return width >= screenWidth - this.screenOffset && height >= screenHeight - this.screenOffset;
};
FullscreenHelper.prototype.isLandscapeFullscreen = function(width, height, screenWidth, screenHeight) {
return width >= screenHeight - this.screenOffset && height >= screenWidth - this.screenOffset;
};
FullscreenHelper.prototype.isScreenSizeValid = function(screenWidth, screenHeight) {
return screenWidth > 0 && screenHeight > 0 && screenWidth >= this.screenOffset && screenHeight >= this.screenOffset;
};
FullscreenHelper.prototype.isDocumentFullscreen = function(doc, adSlot) {
var isFS = false;
if (doc) {
isFS = FullscreenHelper.FULLSCREEN_ATTRIBUTES.some(function(attr) {
return !!doc[attr];
});
if (!isFS && adSlot && adSlot.ownerDocument) {
isFS = this.isDocumentFullscreen(adSlot.ownerDocument);
}
}
return isFS;
};
return FullscreenHelper;
})();
IV.FullscreenHelper = FullscreenHelper;
})(IV || (IV = {}));
var IV;
(function(IV) {
var GeometryCalculator = (function() {
function GeometryCalculator() {}
GeometryCalculator.prototype.getViewabilityState = function(elem, contextWindow) {
var minViewPortSize = this.getMinViewPortSize(contextWindow),
viewablePercentage;
if (minViewPortSize.area === Infinity) {
throw Error("Failed to determine viewport");
}
var assetRect = IV.DomElementUtils.getObjectRect(elem);
var playerArea = assetRect.width * assetRect.height;
if ((minViewPortSize.area / playerArea) < 0.5) {
viewablePercentage = Math.floor(100 * minViewPortSize.area / playerArea);
}
var viewPortSize = this.getViewPortSize(contextWindow.top),
visibleAssetSize = this.getAssetVisibleDimension(elem, contextWindow);
if (visibleAssetSize.bottom < 0 || visibleAssetSize.right < 0 || visibleAssetSize.top > viewPortSize.height || visibleAssetSize.left > viewPortSize.width) {
viewablePercentage = 0;
} else if (visibleAssetSize.left > 0 && visibleAssetSize.top > 0 && visibleAssetSize.bottom < viewPortSize.height && visibleAssetSize.right < viewPortSize.width) {
viewablePercentage = 100;
} else {
if (visibleAssetSize.bottom > viewPortSize.height) {
visibleAssetSize.height -= (visibleAssetSize.bottom - viewPortSize.height);
}
if (visibleAssetSize.top < 0) {
visibleAssetSize.height += visibleAssetSize.top;
}
if (visibleAssetSize.left < 0) {
visibleAssetSize.width += visibleAssetSize.left;
}
if (visibleAssetSize.right > viewPortSize.width) {
visibleAssetSize.width -= (visibleAssetSize.right - viewPortSize.width);
}
viewablePercentage = Math.floor(100 * (visibleAssetSize.width * visibleAssetSize.height) / playerArea);
}
return {
clientWidth: viewPortSize.width,
clientHeight: viewPortSize.height,
objTop: assetRect.top,
objBottom: assetRect.bottom,
objLeft: assetRect.left,
objRight: assetRect.right,
percentViewable: viewablePercentage
};
};
GeometryCalculator.prototype.getMinViewPortSize = function(contextWindow) {
var minViewPortSize = this.getViewPortSize(contextWindow),
minViewPortArea = minViewPortSize.area,
currentWindow = contextWindow;
while (currentWindow !== currentWindow.top) {
currentWindow = currentWindow.parent;
var viewPortSize = this.getViewPortSize(currentWindow);
if (viewPortSize.area < minViewPortArea) {
minViewPortArea = viewPortSize.area;
minViewPortSize = viewPortSize;
}
}
return minViewPortSize;
};
GeometryCalculator.prototype.getViewPortSize = function(contextWindow) {
var viewPortSize = {
width: Infinity,
height: Infinity,
area: Infinity
};
if (!isNaN(contextWindow.document.body.clientWidth) && contextWindow.document.body.clientWidth > 0) {
viewPortSize.width = contextWindow.document.body.clientWidth;
}
if (!isNaN(contextWindow.document.body.clientHeight) && contextWindow.document.body.clientHeight > 0) {
viewPortSize.height = contextWindow.document.body.clientHeight;
}
if (!!contextWindow.document.documentElement && !!contextWindow.document.documentElement.clientWidth && !isNaN(contextWindow.document.documentElement.clientWidth)) {
viewPortSize.width = contextWindow.document.documentElement.clientWidth;
}
if (!!contextWindow.document.documentElement && !!contextWindow.document.documentElement.clientHeight && !isNaN(contextWindow.document.documentElement.clientHeight)) {
viewPortSize.height = contextWindow.document.documentElement.clientHeight;
}
if (!!contextWindow.innerWidth && !isNaN(contextWindow.innerWidth)) {
viewPortSize.width = Math.min(viewPortSize.width, contextWindow.innerWidth);
}
if (!!contextWindow.innerHeight && !isNaN(contextWindow.innerHeight)) {
viewPortSize.height = Math.min(viewPortSize.height, contextWindow.innerHeight);
}
viewPortSize.area = viewPortSize.height * viewPortSize.width;
return viewPortSize;
};
GeometryCalculator.prototype.getAssetVisibleDimension = function(elem, contextWindow) {
var currWindow = contextWindow;
var parentWindow = contextWindow.parent;
var resultDimension = {
width: 0,
height: 0,
left: 0,
right: 0,
top: 0,
bottom: 0
};
if (elem) {
var elementRect = this.getPositionRelativeToViewPort(elem, contextWindow);
elementRect.width = elementRect.right - elementRect.left;
elementRect.height = elementRect.bottom - elementRect.top;
resultDimension = elementRect;
if (currWindow !== parentWindow) {
var parentDimension = this.getAssetVisibleDimension(currWindow.frameElement, parentWindow);
if (parentDimension.bottom < resultDimension.bottom) {
if (parentDimension.bottom < resultDimension.top) {
resultDimension.top = parentDimension.bottom;
}
resultDimension.bottom = parentDimension.bottom;
}
if (parentDimension.right < resultDimension.right) {
if (parentDimension.right < resultDimension.left) {
resultDimension.left = parentDimension.right;
}
resultDimension.right = parentDimension.right;
}
resultDimension.width = resultDimension.right - resultDimension.left;
resultDimension.height = resultDimension.bottom - resultDimension.top;
}
}
return resultDimension;
};
GeometryCalculator.prototype.getPositionRelativeToViewPort = function(elem, contextWindow) {
var currWindow = contextWindow;
var parentWindow = contextWindow.parent;
var resultPosition = {
left: 0,
right: 0,
top: 0,
bottom: 0
};
if (elem) {
var elementRect = IV.DomElementUtils.getObjectRect(elem);
if (currWindow !== parentWindow) {
resultPosition = this.getPositionRelativeToViewPort(currWindow.frameElement, parentWindow);
} else {
resultPosition = {
left: elementRect.left + resultPosition.left,
right: elementRect.right + resultPosition.left,
top: elementRect.top + resultPosition.top,
bottom: elementRect.bottom + resultPosition.top
};
}
}
return resultPosition;
};
return GeometryCalculator;
})();
IV.GeometryCalculator = GeometryCalculator;
})(IV || (IV = {}));
var IV;
(function(IV) {
var IntersectionObserverCalculator = (function() {
function IntersectionObserverCalculator(checkResult) {
var _this = this;
this.observationCallback = function(changes) {
changes.forEach(function(change) {
_this.updateCheckObject(change);
});
};
var thresholds = this.setThresholds(IntersectionObserverCalculator.IO_THRESHOLD_RESOLUTION);
this._check = checkResult.clone();
if (typeof window.IntersectionObserver !== "undefined") {
this._observer = new window.IntersectionObserver(this.observationCallback, {
threshold: thresholds
});
this.initializeViewabilityCheckResultForIO();
}
}
Object.defineProperty(IntersectionObserverCalculator, "IO_THRESHOLD_RESOLUTION", {
get: function() {
return 0.05;
},
enumerable: true,
configurable: true
});
IntersectionObserverCalculator.prototype.isSupported = function() {
return !!this._observer;
};
IntersectionObserverCalculator.prototype.observeAd = function(adElement) {
if (this._adElement === adElement) {
return;
}
this._adElement = adElement;
if (this.isSupported()) {
this._observer.observe(this._adElement);
}
};
IntersectionObserverCalculator.prototype.disconnect = function() {
this._observer.disconnect();
};
IntersectionObserverCalculator.prototype.checkViewability = function() {
return this._check.clone();
};
IntersectionObserverCalculator.prototype.setThresholds = function(resolution) {
var thresholdLevel = 0,
thresholds = [];
for (var i = 0; i <= (1 / resolution); i++) {
thresholds[i] = parseFloat(thresholdLevel.toFixed(2));
thresholdLevel += resolution;
}
return thresholds;
};
IntersectionObserverCalculator.prototype.updateCheckObject = function(intersectionObserverCheck) {
var targetWidth = intersectionObserverCheck.boundingClientRect.right - intersectionObserverCheck.boundingClientRect.left;
var targetHeight = intersectionObserverCheck.boundingClientRect.bottom - intersectionObserverCheck.boundingClientRect.top;
this._check = this._check.clone();
this._check.viewablePercentage = 100 * intersectionObserverCheck.intersectionRatio;
if (targetWidth > 0 && targetHeight > 0) {
this._check.playerRectangle = new IV.PlayerRectangle(intersectionObserverCheck.boundingClientRect.left, intersectionObserverCheck.boundingClientRect.top, targetWidth, targetHeight);
}
if (intersectionObserverCheck.rootBounds) {
this._check.clientDimensions = new IV.ClientDimensions(intersectionObserverCheck.rootBounds.width, intersectionObserverCheck.rootBounds.height);
} else {
this._check.clientDimensions = new IV.ClientDimensions(targetWidth, targetHeight);
}
};
IntersectionObserverCalculator.prototype.initializeViewabilityCheckResultForIO = function() {
this._check.checkMethod = IV.ViewabilityCheckResult.CheckMethod.IO;
this._check.status = IV.ViewabilityCheckResult.Status.OK;
};
return IntersectionObserverCalculator;
})();
IV.IntersectionObserverCalculator = IntersectionObserverCalculator;
})(IV || (IV = {}));
var IV;
(function(IV) {
var ViewabilityCalculator = (function() {
function ViewabilityCalculator(contextWindow, defaultCheckObj, geometryCalculator, intersectionObserverCalculator, domObscuringCalculator, fullscreenHelper) {
this.forceFullscreen = false;
this.contextWindow = contextWindow;
this.contextDocument = contextWindow.document;
this.defaultCheckObj = defaultCheckObj;
this.geometryCalculator = geometryCalculator;
this.intersectionObserverCalculator = intersectionObserverCalculator;
this.domObscuringCalculator = domObscuringCalculator;
this.fullscreenHelper = fullscreenHelper;
}
ViewabilityCalculator.prototype.initialize = function(player) {
this.intersectionObserverCalculator.observeAd(player);
};
ViewabilityCalculator.prototype.checkViewability = function(player, adSlot) {
var check = this.defaultCheckObj.clone();
var adSlotRect = IV.DomElementUtils.getObjectRect(adSlot);
if (adSlotRect) {
check.clientDimensions = this.getClientDimensions(adSlotRect.width, adSlotRect.height);
check.playerRectangle = new IV.PlayerRectangle(adSlotRect.left, adSlotRect.top, adSlotRect.width, adSlotRect.height);
}
if (IV.DomElementUtils.isDomElement(player)) {
check = this.checkIntersectionObserver(player, this.checkGeometry(player, this.checkFullScreen(adSlot, this.checkDomObscuring(player, adSlot, this.checkCssInvisibility(player, check)))));
}
if (check.checkMethod !== IV.ViewabilityCheckResult.CheckMethod.FULL_SCREEN) {
check.focusState = this.isInFocus(adSlot) ? IV.ViewabilityCheckResult.FocusState.ON : IV.ViewabilityCheckResult.FocusState.OFF;
}
check.iframeState = this.isIframe() ? IV.ViewabilityCheckResult.IFrameState.IN_IFRAME : IV.ViewabilityCheckResult.IFrameState.NOT_IN_IFRAME;
if (this.isIframe() && check.checkMethod === IV.ViewabilityCheckResult.CheckMethod.NONE) {
check.status = IV.ViewabilityCheckResult.Status.IN_IFRAME;
}
return check;
};
ViewabilityCalculator.prototype.dispose = function() {
this.intersectionObserverCalculator.disconnect();
};
ViewabilityCalculator.prototype.checkGeometry = function(player, check) {
if (check.checkMethod !== IV.ViewabilityCheckResult.CheckMethod.NONE || this.isIframe()) {
return check;
}
var originalCheck = check.clone();
try {
var viewabilityResult = this.geometryCalculator.getViewabilityState(player, this.contextWindow);
check.checkMethod = IV.ViewabilityCheckResult.CheckMethod.GEOMETRY;
check.status = IV.ViewabilityCheckResult.Status.OK;
if (viewabilityResult.objRight > viewabilityResult.objLeft && viewabilityResult.objBottom > viewabilityResult.objTop) {
check.playerRectangle = new IV.PlayerRectangle(viewabilityResult.objLeft, viewabilityResult.objTop, viewabilityResult.objBottom - viewabilityResult.objTop, viewabilityResult.objRight - viewabilityResult.objLeft);
}
check.clientDimensions = new IV.ClientDimensions(viewabilityResult.clientWidth, viewabilityResult.clientHeight);
check.viewablePercentage = viewabilityResult.percentViewable - check.percentObscured;
return check;
} catch (ignore) {}
return originalCheck;
};
ViewabilityCalculator.prototype.checkIntersectionObserver = function(player, check) {
if (check.checkMethod !== IV.ViewabilityCheckResult.CheckMethod.NONE || !this.intersectionObserverCalculator.isSupported()) {
return check;
}
var originalCheck = check.clone();
try {
this.intersectionObserverCalculator.observeAd(player);
return this.intersectionObserverCalculator.checkViewability();
} catch (ignore) {}
return originalCheck;
};
ViewabilityCalculator.prototype.checkFullScreen = function(adSlot, check) {
var originalCheck = check.clone();
try {
if (this.isFullScreen(adSlot)) {
check.status = IV.ViewabilityCheckResult.Status.OK;
check.checkMethod = IV.ViewabilityCheckResult.CheckMethod.FULL_SCREEN;
check.viewablePercentage = 100;
check.playerRectangle = new IV.PlayerRectangle(0, 0, this.contextWindow.screen.width, this.contextWindow.screen.height);
check.focusState = IV.ViewabilityCheckResult.FocusState.ON;
}
return check;
} catch (ignore) {}
return originalCheck;
};
ViewabilityCalculator.prototype.checkCssInvisibility = function(player, check) {
var originalCheck = check.clone();
try {
var style = this.contextWindow.getComputedStyle(player, null);
var visibility = style.getPropertyValue("visibility");
var display = style.getPropertyValue("display");
if (visibility === "hidden" || display === "none") {
check.checkMethod = IV.ViewabilityCheckResult.CheckMethod.CSS_INVISIBILITY;
check.status = IV.ViewabilityCheckResult.Status.OK;
check.viewablePercentage = 0;
}
return check;
} catch (ignore) {}
return originalCheck;
};
ViewabilityCalculator.prototype.checkDomObscuring = function(player, adSlot, check) {
var originalCheck = check.clone();
try {
check.percentObscured = this.domObscuringCalculator.checkDomObscuring(player, adSlot);
if (check.percentObscured > 50) {
check.viewablePercentage = 100 - check.percentObscured;
check.checkMethod = IV.ViewabilityCheckResult.CheckMethod.DOM_OBSCURING;
check.status = IV.ViewabilityCheckResult.Status.OK;
return check;
}
return check;
} catch (ignore) {}
return originalCheck;
};
ViewabilityCalculator.prototype.isFullScreen = function(adSlot) {
return this.forceFullscreen || this.fullscreenHelper.isFullscreen(adSlot, this.contextWindow, this.isIframe() ? !this.isCrossdomainIframe() : true);
};
ViewabilityCalculator.prototype.isInFocus = function(adSlot) {
if (adSlot && adSlot.ownerDocument && typeof adSlot.ownerDocument.hidden !== "undefined") {
if (adSlot.ownerDocument.hidden === true) {
return false;
}
}
if (this.isCrossdomainIframe()) {
return true;
}
if (this.contextWindow.top.document.hasFocus) {
return this.contextWindow.top.document.hasFocus();
}
return true;
};
ViewabilityCalculator.prototype.isCrossdomainIframe = function() {
try {
var referrerDomain = this.getDomainFromFullUrl(this.contextDocument.referrer);
if (!this.isIframe()) {
return false;
} else if (referrerDomain && this.contextDocument.domain && this.contextDocument.domain !== referrerDomain) {
return true;
} else if (this.contextWindow.top.document.domain === this.contextWindow.document.domain) {
return false;
}
} catch (ignore) {}
return true;
};
ViewabilityCalculator.prototype.isIframe = function() {
return this.contextWindow.top !== this.contextWindow;
};
ViewabilityCalculator.prototype.getClientDimensions = function(fallbackWidth, fallbackHeight) {
var clientDimensions = new IV.ClientDimensions(0, 0);
if (!this.isCrossdomainIframe()) {
var topDoc = this.contextWindow.top.document;
clientDimensions = new IV.ClientDimensions(topDoc.body.clientWidth, topDoc.body.clientHeight);
} else if (this.contextDocument.body.clientWidth && this.contextDocument.body.clientHeight) {
clientDimensions = new IV.ClientDimensions(this.contextDocument.body.clientWidth, this.contextDocument.body.clientHeight);
} else {
clientDimensions = new IV.ClientDimensions(fallbackWidth, fallbackHeight);
}
return clientDimensions;
};
ViewabilityCalculator.prototype.getDomainFromFullUrl = function(url) {
if (url) {
var a = document.createElement("a");
a.href = url;
return a.hostname;
}
return null;
};
ViewabilityCalculator.prototype.toggleFullscreen = function(isFullscreen) {
this.forceFullscreen = isFullscreen;
};
return ViewabilityCalculator;
})();
IV.ViewabilityCalculator = ViewabilityCalculator;
})(IV || (IV = {}));
var IV;
(function(IV) {
var IntegerUtils = (function() {
function IntegerUtils() {}
IntegerUtils.toInteger = function(num) {
if (isNaN(num)) {
return 0;
} else {
return num | 0;
}
};
return IntegerUtils;
})();
var ClientDimensions = (function() {
function ClientDimensions(_width, _height) {
this._width = IntegerUtils.toInteger(_width);
this._height = IntegerUtils.toInteger(_height);
}
ClientDimensions.prototype.toString = function() {
return this._width + "," + this._height;
};
ClientDimensions.prototype.clone = function() {
return new ClientDimensions(this._width, this._height);
};
return ClientDimensions;
})();
IV.ClientDimensions = ClientDimensions;
var PlayerRectangle = (function() {
function PlayerRectangle(_left, _top, _width, _height) {
this._left = IntegerUtils.toInteger(_left);
this._top = IntegerUtils.toInteger(_top);
this._width = IntegerUtils.toInteger(_width);
this._height = IntegerUtils.toInteger(_height);
}
PlayerRectangle.prototype.toString = function() {
return this._left + "," + this._top + "," + this._width + "," + this._height;
};
PlayerRectangle.prototype.clone = function() {
return new PlayerRectangle(this._left, this._top, this._width, this._height);
};
return PlayerRectangle;
})();
IV.PlayerRectangle = PlayerRectangle;
var ViewabilityCheckResult = (function() {
function ViewabilityCheckResult(_status, _checkMethod, _viewablePercentage, _clientDimensions, _playerRectangle, _focusState, _volume, _iframeState) {
if (_status === void 0) {
_status = ViewabilityCheckResult.Status.UNKNOWN;
}
if (_checkMethod === void 0) {
_checkMethod = ViewabilityCheckResult.CheckMethod.NONE;
}
if (_viewablePercentage === void 0) {
_viewablePercentage = 0;
}
if (_clientDimensions === void 0) {
_clientDimensions = new ClientDimensions(0, 0);
}
if (_playerRectangle === void 0) {
_playerRectangle = new PlayerRectangle(0, 0, 0, 0);
}
if (_focusState === void 0) {
_focusState = ViewabilityCheckResult.FocusState.OFF;
}
if (_volume === void 0) {
_volume = 0;
}
if (_iframeState === void 0) {
_iframeState = ViewabilityCheckResult.IFrameState.NOT_IN_IFRAME;
}
this.status = ViewabilityCheckResult.Status.UNKNOWN;
this.viewablePercentage = 0;
this.clientDimensions = new ClientDimensions(0, 0);
this.playerRectangle = new PlayerRectangle(0, 0, 0, 0);
this.focusState = ViewabilityCheckResult.FocusState.OFF;
this.volume = 0;
this.checkMethod = ViewabilityCheckResult.CheckMethod.NONE;
this.iframeState = ViewabilityCheckResult.IFrameState.NOT_IN_IFRAME;
this.percentObscured = 0;
this.status = _status;
this.viewablePercentage = _viewablePercentage;
this.clientDimensions = _clientDimensions;
this.playerRectangle = _playerRectangle;
this.focusState = _focusState;
this.volume = _volume;
this.checkMethod = _checkMethod;
this.iframeState = _iframeState;
this.percentObscured = 0;
}
Object.defineProperty(ViewabilityCheckResult, "Status", {
get: function() {
return {
OK: 1,
NO_ACCESS: -1,
PLAYER_NOT_FOUND: -2,
IN_IFRAME: -3,
UNKNOWN: -4
};
},
enumerable: true,
configurable: true
});
Object.defineProperty(ViewabilityCheckResult, "CheckMethod", {
get: function() {
return {
NONE: -1,
GEOMETRY: 0,
BEACON: 1,
IO: 2,
CSS_INVISIBILITY: 3,
DOM_OBSCURING: 4,
FULL_SCREEN: 5
};
},
enumerable: true,
configurable: true
});
Object.defineProperty(ViewabilityCheckResult, "FocusState", {
get: function() {
return {
OFF: 0,
ON: 1
};
},
enumerable: true,
configurable: true
});
Object.defineProperty(ViewabilityCheckResult, "IFrameState", {
get: function() {
return {
NOT_IN_IFRAME: 0,
IN_IFRAME: 1
};
},
enumerable: true,
configurable: true
});
Object.defineProperty(ViewabilityCheckResult, "VIEWABLE_PERCENTAGE", {
get: function() {
return 50;
},
enumerable: true,
configurable: true
});
ViewabilityCheckResult.prototype.toString = function() {
return (this.status + ";") + (IntegerUtils.toInteger(this.viewablePercentage) + ";") + (this.clientDimensions.toString() + ";") + (this.playerRectangle.toString() + ";") + (this.focusState + ";") + (IntegerUtils.toInteger(this.volume) + ";") + "1;" + (this.checkMethod + ";") + ("" + this.iframeState);
};
ViewabilityCheckResult.prototype.clone = function() {
var clientDimensions = this.clientDimensions ? this.clientDimensions.clone() : this.clientDimensions;
var playerRectangle = this.playerRectangle ? this.playerRectangle.clone() : this.playerRectangle;
return new ViewabilityCheckResult(this.status, this.checkMethod, this.viewablePercentage, clientDimensions, playerRectangle, this.focusState, this.volume, this.iframeState);
};
ViewabilityCheckResult.prototype.isMeasurable = function() {
return this.status === ViewabilityCheckResult.Status.OK;
};
ViewabilityCheckResult.prototype.isViewable = function() {
return this.isMeasurable() && this.isInViewableSpace() && this.isInFocus();
};
ViewabilityCheckResult.prototype.isInViewableSpace = function() {
return this.viewablePercentage >= ViewabilityCheckResult.VIEWABLE_PERCENTAGE;
};
ViewabilityCheckResult.prototype.isInFocus = function() {
return this.focusState === ViewabilityCheckResult.FocusState.ON;
};
return ViewabilityCheckResult;
})();
IV.ViewabilityCheckResult = ViewabilityCheckResult;
})(IV || (IV = {}));
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment