Skip to content

Instantly share code, notes, and snippets.

@adammw
Last active October 1, 2022 20:40
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save adammw/4285451 to your computer and use it in GitHub Desktop.
Save adammw/4285451 to your computer and use it in GitHub Desktop.
Spotify
/*
* https://spapps.spotify.edgekey.net/api/12e172c/scripts/main.js
*
* 15/12/2012
*/
function SpotifyApi() {
this._modules = {};
this._requested = {};
this._moduleQueue = [];
this._delayedFns = [];
this._parallelReqs = 4;
this._contextStack = [];
this._deferredFlush = !1;
this._patchRequestOpen()
}
SpotifyApi.AnalyticsContext = function (a) {
this.name = a;
this.id = SpotifyApi.AnalyticsContext._nextId++;
this.references = 0;
this._begin()
};
SpotifyApi.AnalyticsContext._nextId = 1;
SpotifyApi.AnalyticsContext.prototype.addReference = function () {
this.references++
};
SpotifyApi.AnalyticsContext.prototype.removeReference = function () {
this.references--;
this.references === 0 && this._end()
};
SpotifyApi.AnalyticsContext.prototype._begin = function () {
SpotifyApi.api.request("core_context_begin", [this.id, this.name], this)
};
SpotifyApi.AnalyticsContext.prototype._end = function () {
SpotifyApi.api.request("core_context_end", [this.id], this)
};
SpotifyApi.prototype.analyticsContext = function (a, f) {
var g = new SpotifyApi.AnalyticsContext(a);
g.addReference();
this._contextStack.push(g);
try {
f()
} finally {
this._contextStack.pop(), g.removeReference()
}
};
SpotifyApi.Callback = function (a, f) {
this._func = a;
this._setContextStack(f || SpotifyApi.api._contextStack)
};
SpotifyApi.Callback.prototype.apply = function (a, f) {
try {
var g = SpotifyApi.api._contextStack;
SpotifyApi.api._contextStack = this._contextStack;
this._func.apply(a, f)
} catch (b) {
setTimeout(function () {
throw b;
}, 0)
} finally {
SpotifyApi.api._contextStack = g, this.clear()
}
};
SpotifyApi.Callback.prototype.call = function (a, f) {
this.apply(a, Array.prototype.slice.call(arguments, 1))
};
SpotifyApi.Callback.prototype.copy = function () {
return new this.constructor(this._func, this._contextStack)
};
SpotifyApi.Callback.prototype.clear = function () {
this._releaseContextStack();
delete this._func;
delete this._contextStack
};
SpotifyApi.Callback.prototype._setContextStack = function (a) {
for (var f = 0, g = a.length; f < g; ++f) a[f].addReference();
this._contextStack = a.slice(0)
};
SpotifyApi.Callback.prototype._releaseContextStack = function () {
for (var a = this._contextStack, f = 0, g = a.length; f < g; ++f) a[g - f - 1].removeReference()
};
SpotifyApi.prototype.callback = function (a) {
return new SpotifyApi.Callback(a)
};
SpotifyApi.prototype._getContextIdForRequest = function () {
var a = this._contextStack;
return a.length ? a[a.length - 1].id : 0
};
window.addEventListener("message", function (a) {
if (a.source == window && a.data == "api-delay") {
a.stopPropagation();
for (var a = SpotifyApi.api._delayedFns.splice(0), f = 0, g = a.length; f < g; f++) a[f].call()
}
});
SpotifyApi.prototype._prepareFlush = function () {
if (!this._deferredFlush) this._deferredFlush = !0, this.defer(this, this._flushRequests)
};
SpotifyApi.prototype._flushRequests = function () {
this.request("core_flush", []);
this._deferredFlush = !1
};
SpotifyApi.prototype.defer = function (a, f) {
this._delayedFns.push(this.bind(this.callback(f), a)) == 1 && window.postMessage("api-delay", "*")
};
SpotifyApi.prototype._evalModule = function (a, f, g, b) {
return !/\.lang$/.test(g) ? this._evalJSModule(a, f, g, b) : this._evalLangModule(g, b)
};
SpotifyApi.prototype._evalJSModule = function (a, f, g, b) {
var c = this,
d = {
__name: g
};
try {
return (new Function("require", "exports", "SP", "_code", "eval(_code)")).call({}, function (b, h) {
d.__waiting = !0;
var k = function () {
d.__waiting = !1;
return h.apply(this, arguments)
};
k.__native = !0;
return c._require(g, a, f, b, k)
}, d, this, "'use strict';" + b + "\n//@ sourceURL=" + g), d
} catch (h) {
throw h.message += " in " + g, h;
}
};
SpotifyApi.LangModule = function (a, f) {
this.__name = a;
this.strings = f
};
SpotifyApi.LangModule.prototype.get = function (a, f) {
for (var g = this.strings.hasOwnProperty(a) ? this.strings[a] : a, b = "", c = 0, d, h;
(d = g.indexOf("{", c)) > -1;) {
h = g.indexOf("}", d + 1);
if (h == -1) break;
var i = arguments[parseInt(g.substring(d + 1, h)) + 1];
b += i !== void 0 ? g.substring(c, d) + i : g.substring(c, h + 1);
c = h + 1
}
return c ? b + g.substring(c) : g
};
SpotifyApi.prototype._evalLangModule = function (a, f) {
try {
return new SpotifyApi.LangModule(a, JSON.parse(f))
} catch (g) {
throw Error('Cannot import language file "' + a + '": ' + g.message);
}
};
SpotifyApi.prototype._fireCallbacks = function (a) {
for (; a;) {
a.waiting--;
if (a.waiting) break;
a.unpacked.forEach(function (f) {
var g = f.position,
b = a.args[g],
f = f.property;
if (!(f in b)) throw Error('No "' + f + '" exported in module "' + b.__name + '"');
a.args[g] = b[f]
});
a.callback.apply({}, a.args);
a.waiting = 1 / 0;
a = a.parent
}
};
SpotifyApi.prototype._createRequest = function (a, f) {
var g = new XMLHttpRequest;
g.open("GET", a, !0);
g.onreadystatechange = function () {
if (g.readyState == 4) {
if (g.status != 200 && g.status != 0) throw Error('Could not load module "' + a + '"; Not found.');
f(g.responseText)
}
};
g.send(null)
};
SpotifyApi.prototype._loadModule = function (a, f, g, b, c) {
var d = this,
h = this._modules[g];
h && !h.__waiting ? (a.args[b] = this._modules[g], c && a.unpacked.push({
property: c,
position: b
}), this._fireCallbacks(a)) : this._requested[g] || !this._parallelReqs ? this.defer(this, function () {
this._loadModule(a, f, g, b, c)
}) : (this._requested[g] = !0, this._parallelReqs--, this._createRequest(g, function (h) {
d._parallelReqs++;
h = d._modules[g] = d._evalModule(a, f, g, h);
a.args[b] = h;
c && a.unpacked.push({
property: c,
position: b
});
d._fireCallbacks(a)
}))
};
SpotifyApi.prototype._resolveModule = function (a) {
if (!/\.lang$/.test(a)) {
var f = a.match(/^(\$(?:[^\/]+)\/)(?!scripts)(.*)/);
f && (a = f[1] + "scripts/" + f[2]);
a += ".js"
}
return a
};
SpotifyApi.prototype._require = function (a, f, g, b, c) {
typeof b == "string" && (b = [b]);
if (!b || !b.length) throw Error("Missing modules argument to require().");
if (!c || typeof c != "function") throw Error("Missing callback function argument to require().");
var d = b.length;
if (!c.__native && d != c.length) throw Error("Module-parameter mismatch! Imported " + d + " but only declared " + c.length + " in callback.");
a = {
name: a,
parent: f,
waiting: d,
callback: c,
args: Array(d),
unpacked: []
};
f.waiting++;
for (f = 0; f < d; f++) {
c = b[f];
if (!c) throw Error("Empty module name in require.");
var h = c.split("#"),
c = this._resolveModule(h[0]),
h = h[1],
i = g.slice(0),
j = g.indexOf(c);
i.push(c);
if (j != -1) throw i = i.slice(j).join(" -> "), Error('Circular Dependency on Module "' + c + '": ' + i);
this._loadModule(a, i, c, f, h)
}
};
SpotifyApi.prototype.varargs = function (a, f, g) {
f || (f = 0);
if (Array.isArray(a[f])) {
if (a.length > f + 1) throw Error("Ambiguous use of varargs");
a = a[f];
f = 0
}
return f || g ? Array.prototype.slice.call(a, f) : a
};
SpotifyApi.prototype.uris = function (a, f) {
for (var g = this.varargs(a, f), b = [], c = 0, d = g.length; c < d; c++) b.push(g[c].uri);
return b
};
SpotifyApi.prototype.bind = function (a, f, g) {
if (arguments.length > 2) {
var b = Array.prototype.slice,
c = Function.prototype.bind;
if (c && a.bind === c) return c.apply(a, b.call(arguments, 1));
var d = b.call(arguments, 2);
return function () {
return a.apply(f, arguments.length ? d.concat(b.call(arguments)) : d)
}
} else return function () {
return a.apply(f, arguments)
}
};
SpotifyApi.prototype.inherit = function (a, f) {
var g = function () {};
g.prototype = a._superClass = f.prototype;
a.prototype = new g;
return a.prototype.constructor = a
};
SpotifyApi.prototype._patchRequestOpen = function () {
var a = XMLHttpRequest.prototype.open,
f = document.createElement("a"),
g = window.location;
XMLHttpRequest.prototype.open = function (b, c) {
var d = a.apply(this, arguments);
f.href = c;
f.protocol == g.protocol && f.hostname == g.hostname && this.setRequestHeader("X-Spotify-Requested-With", "XMLHttpRequest");
return d
}
};
function require(a, f) {
return SpotifyApi.api._require("__main__", {
callback: function () {},
waiting: 1 / 0
}, [], a, f)
}
String.prototype.decodeForText = function () {
return this.toString()
};
String.prototype.decodeForHtml = function () {
var a = {
"&": "&amp;",
"<": "&lt;",
">": "&gt;"
}, f = function (g) {
return a[g]
};
return function () {
return this.replace(/[&<>]/g, f)
}
}();
String.prototype.decodeForLink = function () {
return encodeURI(this)
};
SpotifyApi.Bases = {
uri: "spotify",
url: "http://open.spotify.com"
};
SpotifyApi.Exps = {
spotify: /^spotify:(.+)$/,
http: /^https?:\/\/open\.spotify\.com\/(.+)$/
};
String.prototype.toSpotifyURL = function () {
var a = this.match(SpotifyApi.Exps.spotify);
if (!a) return this;
var a = a.pop().replace(/:$/, "").split(/:/),
f = a.shift();
f == "search" && (a = [a.join(":")]);
a.unshift(SpotifyApi.Bases.url, f);
return a.join("/")
};
String.prototype.toSpotifyURI = function () {
var a = this.match(SpotifyApi.Exps.http);
if (!a) return this;
a = a.pop().replace(/\/$/, "").split(/\//);
a.unshift(SpotifyApi.Bases.uri);
return a.join(":")
};
String.prototype.toSpotifyLink = function () {
return this.toSpotifyURI()
};
(function () {
var a = 0,
f = {};
SpotifyApi.prototype._throwError = !0;
var g = window.dependencies,
b = g["static"],
c = b.replace(/\/([^\/]*)$/, ""),
d = c + "/",
h = SpotifyApi.prototype._resolveModule;
SpotifyApi.prototype._resolveModule = function (a) {
var a = h(a),
d = a.match(/^\$([a-z\-\_]+)(\/.*)/),
f = !1,
j, l = !1;
d ? (f = d[1], j = d[2]) : /^\//.exec(a) && (l = !0);
d = !1;
/\.lang$/.exec(a) && (d = "en.loc", a = f ? "$" + f + "/" + (j = "/" + d + j) : (l ? "/" + d : d + "/") + a);
f && g[f] ? a = g[f] + j : (f ? a = "/" + f + j : l || (a = "/" + a), a = (f ? c : b) + a);
return a
};
var i = window.MutationObserver || window.WebKitMutationObserver;
i ? (new i(function (a) {
for (var c = 0, f = a.length; c < f; c++) {
var g = a[c].addedNodes;
if (!g.length) return this;
for (var h = b + "/$", j = 0, l = g.length; j < l; j++) {
var i = g[j];
if (i.tagName.toLowerCase() == "link" && /^\$/.test(i.getAttribute("href"))) i.href = i.href.replace(h, d)
}
}
})).observe(document.head, {
childList: !0
}) : document.head.addEventListener("DOMSubtreeModified", function (a) {
if (a.target === document.head) for (var a = document.head.querySelectorAll('link[href^="$"]'), c = b + "/$", f = 0, g = a.length; f < g; f++) {
var h = a[f];
if (/^\$/.test(h.getAttribute("href"))) h.href = h.href.replace(c, d)
}
});
if ("XDomainRequest" in window) {
var j = SpotifyApi.prototype._createRequest;
SpotifyApi.prototype._createRequest = function (a, c) {
if (!/^http/.test(a)) return j(a, c);
var b = new XDomainRequest;
b.onprogress = function () {};
b.onerror = function () {
throw Error('Could not load module "' + a + '"; Not found.');
};
b.onload = function () {
c(b.responseText)
};
b.open("GET", a);
b.send(null)
}
}
var k = {
hermes_register_schema: 1
};
SpotifyApi.prototype.request = function (b, c, d, h, j) {
var l = window.top;
if (l === window) return this;
c = {
id: a++,
name: b,
args: c
};
if (k[b]) c.deps = g;
l.postMessage(JSON.stringify(c), "*");
if (!h) return this;
f[c.id] = {
success: h,
failed: j,
caller: d
};
this._prepareFlush()
};
SpotifyApi.prototype._requestReply = function (a) {
a = a.data;
if (typeof a == "string") try {
a = JSON.parse(a)
} catch (c) {
return this
}
var b = f[a.id];
if (!b) return this;
a.success && b.success ? b.success.call(b.caller, a.payload) : !a.success && b.failed && b.failed.call(b.caller, a.payload)
};
SpotifyApi.api = new SpotifyApi;
window.addEventListener("message", SpotifyApi.api._requestReply, !1);
SpotifyApi.Bases.url = "https://play.spotify.com";
SpotifyApi.Exps.http = /^https?:\/\/(play|open)\.spotify\.com\/(.+)$/;
String.prototype.toSpotifyLink = function () {
return this.toSpotifyURL()
};
document.documentElement.addEventListener("click", function (a) {
var b = a.target;
if (b.tagName.toLowerCase() === "a") {
var b = b.href,
c = null;
SpotifyApi.Exps.http.test(b) ? c = b.toSpotifyURI() : SpotifyApi.Exps.spotify.test(b) && (c = b);
c && (a.preventDefault(), SpotifyApi.api.request("application_open_uri", [c, null]))
}
});
var l = Array.prototype.slice;
if (!Array.prototype.indexOf) Array.prototype.indexOf = function (a, b) {
for (var c = this.length >>> 0, d = b < 0 ? Math.max(0, c + b) : b || 0; d < c; d++) if (this[d] === a) return d;
return -1
};
if (!String.prototype.trim) String.prototype.trim = function () {
return String(this).replace(/^\s+|\s+$/g, "")
};
if (!Function.prototype.bind) Function.prototype.bind = function (a) {
var b = this,
c = arguments.length > 1 ? l.call(arguments, 1) : null,
d = function () {}, f = function () {
var h = a,
g = arguments.length;
if (this instanceof
f) d.prototype = b.prototype, h = new d;
g = !c && !g ? b.call(h) : b.apply(h, c && g ? c.concat(l.call(arguments)) : c || arguments);
return h == a ? g : h
};
return f
};
({
_modifiers: {},
_keymap: {},
_ignore: {},
_bindings: {},
_empty: function () {},
init: function () {
SpotifyApi.api.request("keyboard_get_bindings", [], this, function (a) {
for (var b in a) a.hasOwnProperty(b) && (this[b] = a[b])
}.bind(this), this._empty);
window.addEventListener("keydown", this.handleOwn.bind(this, !1));
window.addEventListener("keyup", this.handleOwn.bind(this, !0))
},
handleOwn: function (a,
b) {
if (this._ignore[b.target.tagName.toLowerCase()]) return this;
var c = this._keymap[b.which || b.keyCode];
if (!c) return this;
var d = this._modifiers;
b.altKey && (c |= d.alt);
b.metaKey && (c |= d.meta);
b.ctrlKey && (c |= d.ctrl);
c = this._bindings[c];
if (!c) return this;
b.preventDefault();
b.stopPropagation();
a && SpotifyApi.api.request("keyboard_trigger_binding", [c], this, this._empty, this._empty)
}
}).init()
})();
(function (a, f, g) {
function b(a) {
if (a = d[a]) for (var c = a.slice(0), f = 0, k = c.length; f < k; f++) {
var l = c[f];
if (l && (l.waiting > 0 && l.waiting--, !l.waiting)) {
a[f] = null;
var u = l.callback,
z = g[l.name] = {};
u(z);
b(l.name)
}
}
}
function c(a, c, f) {
for (var k = {
name: a,
waiting: 0,
callback: f
}, l = c.length; l--;) {
var u = c[l];
u in g || (k.waiting++, (d[u] || (d[u] = [])).push(k))
}
k.waiting || (c = g[a] = {}, f(c), b(a))
}
var d = {};
c.getState = function () {
return JSON.parse(JSON.stringify(d))
};
a._unrequire = c
})(this, SpotifyApi.api, SpotifyApi.api._modules);
(function (a) {
_unrequire("$api/models", [], function (f) {
function g(e) {
this._items = {};
this._class = e
}
function b() {}
function c(e) {
this.object = e;
this._done = [];
this._fail = []
}
function d() {}
function h() {}
function i() {
this._filters = [];
this._receivers = []
}
function j() {}
function k(e) {
this.resolve("uri", e)
}
function l(e) {
this.resolve("uri", e);
this.resolve("tracks", new r(q, e, "album_disc_tracks"))
}
function u(e, a) {
this.resolve("albums", a && a.albums ? a.albums.map(F) : [])
}
function z() {}
function t() {}
function s(e) {
this.resolve("uri",
e)
}
function v(e, w, b, c, d) {
this.resolve("type", e);
this.resolve("uri", w);
this._snapshot = b;
this._args = c !== void 0 ? c : w;
this._factory = d || a.bind(e.fromURI, e)
}
function r(e, a, b, c, d) {
v.call(this, e, a, this._requestSnapshot, c, d);
this._prefix = b
}
function x(e) {
this.resolve("uri", e)
}
function B(e) {
this.resolve("uri", e);
this.resolve("contexts", new r(x, e, "context_group"))
}
function p(e) {
this.resolve("id", e)
}
function m(e) {
this.resolve("uri", e)
}
function C(e, a) {
this.index = e;
this.uri = a
}
function A() {
this.resolve("user", o.fromURI("spotify:user:@"))
}
function y(e, a, b, c) {
this._collection = e;
this._off = a === void 0 ? 0 : a;
this._len = b === void 0 ? -1 : b;
this._raw = !! c
}
function q(e) {
this.resolve("uri", e)
}
function o(e) {
this.resolve("uri", e)
}
var G = function (e) {
this.object.resolveMany(0, e);
this.setDone()
}, H = function () {
this.setDone()
}, n = function (e, w, b, d) {
e = new c(e);
a.request(w, b, e, d ? G : H, e.setFail);
return e
}, D = function (e) {
return s.fromURI(e.uri, e)
}, F = function (e) {
return k.fromURI(e.uri, e)
}, I = function (e) {
return l.fromURI(e.uri, e)
};
g.lookup = function (e, a) {
return this._cache.lookup(e,
a)
};
g.lookupMany = function (e) {
for (var a = [], b = 0, c = e.length; b < c; b++) a.push(this._cache.lookup(e[b]));
return a
};
g.prototype.cache = function (e, a) {
this._items[e] = a
};
g.prototype.lookup = function (e, a) {
if (!e) return null;
var b = this._items[e];
b || (b = new this._class(e), b.resolveMany(0, a), this._items[e] = b);
return b
};
g.prototype.remove = function (e) {
delete this._items[e]
};
g.prototype.update = function (e, a) {
for (var b = 0, c = e.length; b < c; b++) {
var d = this._items[e[b]];
d && d.resolveMany(0, a)
}
};
b.prototype._observed = function () {};
b.prototype.addEventListener = function (e, a) {
if (a) {
if (!this._ob) this._ob = {}, this._obcount = 0;
var b = this._ob[e];
b ? b.push(a) : this._ob[e] = [a];
this._obcount++;
this._obcount == 1 && this._observed()
}
};
b.prototype.removeEventListener = function (e, a) {
var b = this._ob || {}, c = b[e] || [],
d = c.indexOf(a);
d != -1 && (this._obcount--, c.splice(d, 1), c.length || delete b[e], this._obcount || delete this._ob)
};
b.prototype.dispatchEvent = function (e) {
typeof e == "string" && (e = {
type: e
});
if (!e || !e.type) throw Error("Dispatched event must have a type.");
if (!e.target) e.target = this;
var w = ((this._ob || {})[e.type] || []).slice(0);
if (!w.length) return !0;
var b = !0;
e.preventDefault = function () {
b = !1
};
for (var c = 0; c < w.length; c++) try {
w[c].call(this, e) === !1 && (b = !1)
} catch (d) {
if (a._throwError) throw d;
}
return b
};
c.prototype.always = function (e, w) {
var b, c;
w ? (b = w, c = e) : (b = e, c = this);
if (typeof b != "function") throw Error("A callback function is required");
this._done ? (this._done.push(a.callback(a.bind(b, c))), this._fail.push(a.callback(a.bind(b, c)))) : b.apply(c, this._args);
return this
};
c.prototype.done = function (e, w) {
var b, c;
w ? (b = w, c = e) : (b = e, c = this);
if (typeof b != "function") throw Error("A callback function is required");
this._isDone ? b.apply(c, this._args) : this._done && this._done.push(a.callback(a.bind(b, c)));
return this
};
c.prototype.fail = function (e, b) {
var c, d;
b ? (c = b, d = e) : (c = e, d = this);
if (typeof c != "function") throw Error("A callback function is required");
this._isFail ? c.apply(d, this._args) : this._fail && this._fail.push(a.callback(a.bind(c, d)));
return this
};
c.prototype.each = function (e, b) {
if (this._objs) {
var c,
d;
b ? (c = b, d = e) : (c = e, d = this);
if (typeof c != "function") throw Error("A callback function is required");
this._each && this._each.push(a.callback(a.bind(c, d)));
for (var f = 0, g = this._objs.length; f < g; f++) c.call(d, this._objs[f])
}
return this
};
c.prototype.setDone = function (e) {
if (this._done) {
var a = this._done,
b = this._fail;
delete this._done;
delete this._fail;
if (arguments.length == 1) this.object = e;
this._isDone = !0;
this._args = [this.object];
for (var c = 0, d = a.length; c < d; c++) a[c].apply(void 0, this._args);
a = 0;
for (c = b.length; a < c; a++) b[a].clear();
delete this._each;
delete this._join;
delete this._numResolved;
delete this._oneFailed
}
};
c.prototype.setFail = function (e) {
if (this._done) {
var a = this._fail,
b = this._done;
delete this._done;
delete this._fail;
this._isFail = !0;
this._args = [this.object, e];
for (var e = 0, c = a.length; e < c; e++) a[e].apply(void 0, this._args);
a = 0;
for (e = b.length; a < e; a++) b[a].clear();
delete this._each;
delete this._join;
delete this._numResolved;
delete this._oneFailed
}
};
c.join = function (e) {
var b = new c,
e = a.varargs(arguments,
0, !0);
b._join = e;
b._each = [];
b._objs = [];
b._numResolved = 0;
e.length === 0 && b.setDone([]);
for (var d = 0, f = e.length; d < f; d++) e[d].done(b, b._oneDone).fail(b, b._oneFail);
return b
};
c.prototype._oneEither = function () {
this._numResolved++;
if (!(this._numResolved < this._join.length)) {
this.object = [];
for (var e = 0, a = this._join.length; e < a; e++) this.object.push(this._join[e].object);
e = 0;
for (a = this._each.length; e < a; e++) this._each[e].clear();
this._oneFailed ? this.setFail() : this.setDone()
}
};
c.prototype._oneDone = function (e) {
if (this._done) {
this._objs.push(e);
for (var a = [], b = 0, c = this._each.length; b < c; b++) {
var d = this._each[b];
a.push(d.copy());
d.call(void 0, e)
}
this._each = a;
this._oneEither(e)
}
};
c.prototype._oneFail = function (e) {
if (this._done) this._oneFailed = !0, this._oneEither(e)
};
a.inherit(d, b);
d.define = function (e, a, b) {
e = e.prototype;
if (!e._prop) e._prop = {};
if (!e._next) e._next = 0;
for (var b = {
mask: 0,
func: b
}, c = 0, d = a.length; c < d; c++) {
var f = 1 << e._next++;
b.mask |= f;
e._prop[a[c]] = {
mask: f,
group: b
}
}
};
d.prototype._make = function (e, a) {
var b = this["_make_" + e];
return b ? b(a) : a
};
d.prototype.resolve = function (e, a, b) {
this._prop[e] && (this._done |= this._prop[e].mask, this._wait &= ~this._done, a = this._make(e, a), this.hasOwnProperty(e) && !b ? (b = this[e], b !== a && (this[e] = a, this.dispatchEvent({
type: "change:" + e,
property: e,
oldValue: b
}))) : this[e] = a, this._wait || delete this._wait)
};
d.prototype.resolveMany = function (e, a, b) {
for (var c in a) this.resolve(c, a[c], b);
this._done |= e;
this._wait &= ~e;
this.resolveDone()
};
d.prototype.resolveDone = function () {
if (this._reqs) {
for (var e = [], a = 0; a < this._reqs.length; a++) this._reqs[a]._need & ~this._done || e.push(this._reqs.splice(a--, 1)[0]);
this._reqs.length || delete this._reqs;
this._wait || delete this._wait;
for (var a = 0, b = e.length; a < b; a++) e[a].setDone()
}
};
d.prototype.resolveFail = function (e, a) {
this._wait &= ~e;
if (this._reqs) {
for (var b = [], c = 0; c < this._reqs.length; c++) this._reqs[c]._need & e && b.push(this._reqs.splice(c--, 1)[0]);
this._reqs.length || delete this._reqs;
this._wait || delete this._wait;
for (var c = 0, d = b.length; c < d; c++) b[c].setFail(a)
}
};
d.prototype.load = function (e) {
var b = a.varargs(arguments),
d = new c(this);
d._need = this._neededForLoad(b);
d._need ? (this._reqs ? this._reqs.push(d) : this._reqs = [d], this._requestProperties(d._need)) : d.setDone();
return d
};
d.prototype._neededForLoad = function (e) {
for (var a = 0, b = 0, c = e.length; b < c; b++) {
var d = e[b],
f = this._prop[d];
if (!f) throw Error(d + " is not a property.");
a |= f.mask
}
return a & ~this._done
};
d.prototype._requestProperties = function (e) {
var a = [],
b;
for (b in this._prop) {
var c = this._prop[b],
d = c.group.mask;
if (d & e && !(d & this._wait) && (a.push(c.group), this._wait |= d, e &= ~d, !e)) break
}
e = 0;
for (b = a.length; e < b; e++)(c = this[a[e].func]) && c.call(this, a[e].mask)
};
a.inherit(h, d);
h.prototype.bridgeListen = function (e, a) {
this._requestName = e;
this._requestArgs = a;
this._listening = !0;
this._eventWait()
};
h.prototype.bridgeUnlisten = function () {
delete this._requestName;
delete this._requestArgs;
delete this._listening
};
h.prototype._eventWait = function () {
this._listening && a.request(this._requestName, this._requestArgs, this, this._eventDone, this._eventFail)
};
h.prototype._eventDone = function (e) {
this._eventWait();
this.eventDone(e)
};
h.prototype.eventDone = function (e) {
if (e.receiver && this.hasOwnProperty(e.receiver)) {
var a = this[e.receiver];
a.resolveMany(0, e.data);
a.dispatchEvent(e)
} else this.resolveMany(0, e.data), this.dispatchEvent(e)
};
h.prototype._eventFail = function (e) {
e.error == "timeout" && this._eventWait();
this.eventFail(e)
};
h.prototype.eventFail = function () {};
a.inherit(i, h);
i.prototype.filter = function (e) {
this._filters.push(e)
};
i.prototype.proxyTo = function (e) {
this._receivers.push(e)
};
i.prototype.eventDone = function (e) {
var a,
b, c = !0;
for (a = 0, b = this._filters.length; a < b; a++) this._filters[a](e) === !1 && (c = !1);
if (c) for (a = 0, b = this._receivers.length; a < b; a++) this._receivers[a].eventDone(e)
};
a.inherit(j, h);
j.init = function (e, a) {
e._type = a
};
j.prototype.imageForSize = function (e) {
var a = this.images;
e *= window.devicePixelRatio || 1;
for (var b = 0, c = a ? a.length : 0; b < c; b++) if (a[b][0] >= e || b == c - 1) return a[b][1].replace("{size}", e);
return this.image
};
j.prototype._metadata = function (e) {
a.request(this.constructor._type + "_metadata", [this.uri], this, function (a) {
this.resolveMany(e,
a)
}, function (a) {
this.resolveFail(e, a)
})
};
j.prototype._profile = function (e) {
a.request(this.constructor._type + "_profile", [this.uri], this, function (a) {
this.resolveMany(e, a)
}, function (a) {
this.resolveFail(e, a)
})
};
j.prototype.toString = function () {
return this.uri
};
a.inherit(k, j);
d.define(k, ["uri"]);
d.define(k, "availability,artists,date,discs,image,images,label,name,playable,popularity,type".split(","), "_metadata");
d.define(k, ["copyrights"], "_profile");
d.define(k, ["tracks"], "_collections");
j.init(k, "album");
k.prototype._make_artists = function (e) {
return e && e.map(D)
};
k.prototype._make_discs = function (e) {
return e && e.map(I)
};
k.prototype._collections = function () {
this.resolve("tracks", new r(q, this.uri, "album_tracks"));
this.resolveDone()
};
k.fromURI = g.lookup;
k.fromURIs = g.lookupMany;
k._cache = new g(k);
a.inherit(l, j);
d.define(l, ["uri", "tracks"]);
d.define(l, ["album", "number"], "_metadata");
j.init(l, "disc");
l.prototype._make_album = function (e) {
return e && k.fromURI(e)
};
l.fromURI = g.lookup;
l.fromURIs = g.lookupMany;
l._cache = new g(l);
a.inherit(u, d);
d.define(u, ["albums"]);
u.fromURI = function (e, a) {
return new this(e, a)
};
a.inherit(z, d);
d.define(z, ["features"], "_features");
z.prototype._features = function (e) {
a.request("client_features", [], this, function (a) {
this.resolveMany(e, a)
}, function (a) {
this.resolveFail(e, a)
})
};
z.prototype.showShareUI = function (e, a, b) {
e = [e.uri || e, a || ""];
b && "x" in b && "y" in b && (e.push(b.x), e.push(b.y));
return n(this, "client_show_share_ui", e)
};
z.prototype.showContextUI = function (e, b, c) {
e = [Array.isArray(e) ? a.uris(e) : [e.uri]];
b && "x" in b && "y" in b && (e.push(b.x), e.push(b.y));
c && c.uri && e.push(c.uri);
return n(this, "client_show_context_ui", e)
};
a.inherit(t, h);
d.define(t, ["arguments", "dropped", "identifier", "name", "uri"], "_query");
t.prototype._observed = function () {
this.bridgeListen("application_event_wait", [])
};
t.prototype._make_dropped = function (e) {
return e && e.map(function (e) {
return E(e)
})
};
t.prototype._query = function (e) {
a.request("application_query", [], this, function (a) {
this.resolveMany(e, a)
}, function (a) {
this.resolveFail(e,
a)
})
};
t.prototype.activate = function () {
return n(this, "application_activate", [this.uri])
};
t.prototype.deactivate = function () {
return n(this, "application_deactivate", [this.uri])
};
t.prototype.exit = function (e) {
return n(this, "application_notify_exit", [e || 0])
};
t.prototype.hideLoadingScreen = function () {
a.request("application_notify_loaded", [])
};
t.prototype.readFile = function (e) {
var a = new c,
b = new XMLHttpRequest;
b.open("GET", e, !0);
b.onreadystatechange = function () {
b.readyState === 4 && (b.status !== 200 && b.status !== 0 ? a.setFail() : a.setDone(b.responseText))
};
b.send(null);
return a
};
t.prototype.openURI = function (e, a) {
return n(this, "application_open_uri", [e, a || null])
};
t.prototype.openApp = function (e, b) {
for (var c = a.varargs(arguments, 1), d = ["spotify", "app", e], f = 0, g = c.length; f < g; f++) d.push(encodeURIComponent(c[f]));
return this.openURI(d.join(":"))
};
t.prototype.setTitle = function (e, a) {
return n(this, "application_set_title", [e, a || ""])
};
t.prototype.setPreferredSize = function (e, b) {
var d = new c;
a.request("application_set_preferred_size", [e, b], d, d.setDone, d.setFail);
return d
};
t.prototype.clientEvent = function (a, b, c, d, f) {
return n(this, "application_client_event", [].slice.call(arguments))
};
a.inherit(s, j);
d.define(s, ["uri"]);
d.define(s, ["image", "images", "name", "popularity"], "_metadata");
d.define(s, ["biography", "genres", "portraits", "years"], "_profile");
d.define(s, ["albums", "appearances", "related", "singles"], "_collections");
d.define(s, ["user"], "_associatedUser");
j.init(s, "artist");
s.prototype._collections = function () {
this.resolve("albums",
new r(u, this.uri, "artist_albums"));
this.resolve("appearances", new r(u, this.uri, "artist_appearances"));
this.resolve("related", new r(s, this.uri, "artist_related_artists"));
this.resolve("singles", new r(u, this.uri, "artist_singles"));
this.resolveDone()
};
s.prototype._associatedUser = function (e) {
a.request("artist_associated_user", [this.uri], this, function (a) {
this.resolveMany(e, a)
}, function (a) {
this.resolveFail(e, a)
})
};
s.prototype._make_user = function (a) {
return a && o.fromURI(a)
};
s.fromURI = g.lookup;
s.fromURIs = g.lookupMany;
s._cache = new g(s);
a.inherit(v, d);
d.define(v, ["type", "uri"]);
v.prototype.snapshot = function (a, b, c) {
return (new y(this, a, b, c)).load("length", "range")
};
v.prototype.add = function () {
throw Error("This method has not been implemented.");
};
v.prototype.insert = function () {
throw Error("This method has not been implemented.");
};
v.prototype.remove = function () {
throw Error("This method has not been implemented.");
};
v.prototype.trim = function () {
throw Error("This method has not been implemented.");
};
v.prototype.clear = function () {
throw Error("This method has not been implemented.");
};
v.prototype.sorted = function () {
throw Error("sorting is not implemented");
};
a.inherit(r, v);
r.prototype._requestSnapshot = function (e, b, d, f) {
var g = new c;
a.request(this._prefix + "_snapshot", [e, b, d, f], g, g.setDone, g.setFail);
return g
};
r.prototype.add = function (e) {
var b = a.uris(arguments);
b.unshift(this._args);
return n(this, this._prefix + "_append", b)
};
r.prototype.clear = function () {
return n(this, this._prefix + "_clear", [this._args])
};
r.prototype.insert = function (e, b) {
var c = [this._args, e.index, e.uri],
d = a.uris(arguments,
1);
return n(this, this._prefix + "_insert", c.concat(d))
};
r.prototype.remove = function (a) {
return n(this, this._prefix + "_remove", [this._args, a.index, a.uri])
};
r.prototype.trim = function (a) {
return n(this, this._prefix + "_trim", [this._args, a.index, a.uri])
};
a.inherit(x, d);
d.define(x, ["uri"]);
x.prototype.toString = function () {
return this.uri
};
x.fromURI = function (a) {
return new x(a)
};
a.inherit(B, d);
d.define(B, ["contexts", "uri"]);
B.create = function (e) {
var b = new c;
a.request("context_group_create", [e], b, function (a) {
a = new B(a.uri);
b.setDone(a)
}, b.setFail);
return b
};
a.inherit(p, h);
d.define(p, "context,duration,id,index,playing,position,repeat,shuffle,track,volume".split(","), "_query");
p.prototype._observed = function () {
this.bridgeListen("player_event_wait", [this.id])
};
p.prototype.eventDone = function (a) {
p._superClass.eventDone.call(this, a);
this._queryPosition()
};
p.prototype._make_context = function (a) {
return a && x.fromURI(a.uri, a)
};
p.prototype._make_track = function (a) {
return a && q.fromURI(a.uri, a)
};
p.prototype._query = function (e) {
a.request("player_query", [this.id], this, function (a) {
this.resolveMany(e, a);
this._queryPosition()
}, function (a) {
this.resolveFail(e, a)
})
};
p.prototype._queryPosition = function () {
if (!this._pq && this.playing) {
var e = this;
this._pq = setTimeout(function () {
a.request("player_query", [e.id], e, e._progress)
}, 500)
}
};
p.prototype._progress = function (a) {
this._pq = null;
this.resolve("position", a.position, !0);
delete a.position;
this.resolveMany(0, a);
this._queryPosition()
};
p.prototype.mapTrackIdentifiers = function (a) {
return n(this, "player_map_track_identifiers", [this.id, a])
};
p.prototype.setVolume = function (a) {
return n(this, "player_set_volume", [this.id, a])
};
p.prototype.setRepeat = function (a) {
return n(this, "player_set_repeat", [this.id, a])
};
p.prototype.setShuffle = function (a) {
return n(this, "player_set_shuffle", [this.id, a])
};
p.prototype.play = function () {
return n(this, "player_play", [this.id])
};
p.prototype.pause = function () {
return n(this, "player_pause", [this.id])
};
p.prototype.stop = function () {
return n(this, "player_stop", [this.id])
};
p.prototype.playTrack = function (a,
b, c) {
return n(this, "player_play_track", [this.id, a.uri, b || 0, c != void 0 ? c : -1])
};
p.prototype.playContext = function (a, b, c, d) {
b == null && (b = -1);
return n(this, "player_play_context", [this.id, a.uri, b, c || 0, d != void 0 ? d : -1])
};
p.prototype.playContextGroup = function (a, b, c, d) {
b == void 0 && (b = -1);
c == void 0 && (c = -1);
return n(this, "player_play_context_group", [this.id, a.uri, b, c, d || 0])
};
p.prototype.skipToPrevTrack = function () {
return n(this, "player_skip_to_prev", [this.id])
};
p.prototype.skipToNextTrack = function () {
return n(this,
"player_skip_to_next", [this.id])
};
p.prototype.seek = function (a) {
return n(this, "player_seek", [this.id, a])
};
a.inherit(m, j);
d.define(m, ["uri"]);
d.define(m, "allows,collaborative,description,subscribed,name,owner,published".split(","), "_metadata");
d.define(m, ["image", "images"], "_profile");
d.define(m, ["subscribers", "tracks"], "_collections");
d.define(m, ["popularity"], "_popularity");
j.init(m, "playlist");
m.prototype._make_owner = function (a) {
return a && o.fromURI(a.uri, a)
};
m.prototype._collections = function () {
this.resolve("subscribers",
new r(o, this.uri, "playlist_subscribers"));
this.resolve("tracks", new r(q, this.uri, "playlist_tracks"));
this.resolveDone()
};
m.prototype._popularity = function (b) {
a.request("playlist_popularity", [this.uri], this, function (a) {
this.resolveMany(b, a)
}, function (a) {
this.resolveFail(b, a)
})
};
m._libraryListener = null;
m.fromURI = g.lookup;
m.fromURIs = g.lookupMany;
m._cache = new g(m);
m.createTemporary = function (b) {
var d = new c;
a.request("playlist_create_temporary", [b], d, function (a) {
var c = new m(a.uri);
m._cache.cache(a.uri, c);
c.resolve("name", b);
d.setDone(c)
}, d.setFail);
return d
};
m.removeTemporary = function (b) {
var d = new c;
a.request("playlist_remove_temporary", [b.name], d, function () {
m._cache.remove(b.uri);
d.setDone()
}, d.setFail);
return d
};
m.create = function (b) {
var d = new c;
a.request("playlist_create", [b], d, function (a) {
var c = new m(a.uri);
m._cache.cache(a.uri, c);
c.resolve("name", b);
d.setDone(c)
}, d.setFail);
return d
};
m.getOrCreateLibraryListener = function () {
var a = m._libraryListener;
if (!a) a = new i, a.bridgeListen("library_event_wait", [f.session.user.uri]), a.filter(function (a) {
if (!(a.type != "insert" && a.type != "remove")) {
var b = a.type == "insert";
switch (a.receiver) {
case "playlists":
m._cache.update(a.uris, {
subscribed: b
});
break;
case "published":
m._cache.update(a.uris, {
published: b
})
}
}
}), m._libraryListener = a;
return a
};
m.prototype.load = function () {
var b = a.varargs(arguments);
Array.prototype.indexOf.call(b, "subscribed") >= 0 && m.getOrCreateLibraryListener();
return m._superClass.load.apply(this, b)
};
m.prototype._observed = function () {
this.bridgeListen("playlist_event_wait", [this.uri])
};
m.prototype.eventFail = function (a) {
this._obcount || this.bridgeUnlisten();
m._superClass.eventFail.call(this, a)
};
m.prototype.setDescription = function (a) {
return n(this, "playlist_set_description", [this.uri, a], !0)
};
m.prototype.setImage = function (a) {
return n(this, "playlist_set_image", [this.uri, a], !0)
};
m.prototype.setName = function (a) {
return n(this, "playlist_set_name", [this.uri, a], !0)
};
m.prototype.setSource = function (a, b) {
return n(this, "playlist_set_source", [this.uri, a, b])
};
m.prototype.enforceRules = function (a) {
return n(this, "playlist_enforce_rules", [this.uri, a])
};
a.inherit(A, h);
d.define(A, ["user"]);
d.define(A, "connecting,connection,country,developer,device,incognito,language,online,partner,product,resolution,streaming,testGroup,capabilities".split(","), "_query");
A.prototype._observed = function () {
this.bridgeListen("session_event_wait", [])
};
A.prototype._query = function (b) {
a.request("session_query", [], this, function (a) {
this.resolveMany(b, a)
}, function (a) {
this.resolveFail(b, a)
})
};
a.inherit(y, d);
d.define(y, ["length", "range"], "_request");
y.prototype._request = function () {
var a = this._collection;
a._snapshot(a._args, this._off, this._len, this._raw).done(this, function (a) {
this._uris = a.array;
this._meta = a.metadata || [];
this.resolve("length", a.length);
this.resolve("range", {
offset: this._off,
length: this._uris.length
});
this.resolveDone()
}).fail(this, function (a) {
this.resolveFail(this._neededForLoad(["length", "range"]), a)
})
};
y.prototype.get = function (a) {
if (a instanceof C) a = a.index;
a -= this._off;
return a < 0 || a > this._uris.length ? null : this._collection._factory(this._uris[a], this._meta[a])
};
y.prototype.find = function (a, b) {
if (b instanceof C) b = b.index;
var c = this._uris.indexOf(a.uri, b || 0);
return c == -1 ? null : new C(c + this._off, this._uris[c])
};
y.prototype.loadAll = function () {
for (var a = [], b = this.toArray(), d = 0, f = b.length; d < f; d++) {
var g = b[d];
a.push(g.load.apply(g, arguments))
}
return c.join(a)
};
y.prototype.ref = function (a) {
var b = this.get(a);
return new C(a, b ? b.uri : null)
};
y.prototype.toArray = function () {
for (var a = [], b = this._collection, c = 0, d = this._uris.length; c < d; c++) a[c] = b._factory(this._uris[c], this._meta[c]);
return a
};
y.prototype.toURIs = function () {
return this._uris.slice()
};
a.inherit(q, j);
d.define(q, ["uri"]);
d.define(q, "advertisement,album,artists,availability,disc,duration,explicit,image,images,local,name,number,placeholder,playable,popularity,starred".split(","), "_metadata");
j.init(q, "track");
q.prototype._make_album = function (a) {
return a && k.fromURI(a.uri, a)
};
q.prototype._make_artists = function (a) {
return a && a.map(D)
};
q.fromURI = g.lookup;
q.fromURIs = g.lookupMany;
q._cache = new g(q);
q.prototype.star = function () {
return n(this, "library_star", [f.session.user.uri, this.uri])
};
q.prototype.unstar = function () {
return n(this, "library_unstar", [f.session.user.uri, this.uri])
};
q._trackEventWait = function () {
a.request("track_event_wait_any", [], this, this._trackEventDone, this._trackEventFail)
};
q._trackEventDone = function (a) {
var b = q.fromURI(a.data.uri);
b.resolveMany(0, a.data);
b.dispatchEvent(a);
this._trackEventWait()
};
q._trackEventFail = function (a) {
a.error ==
"timeout" && this._trackEventWait()
};
a.inherit(o, j);
d.define(o, ["uri"]);
d.define(o, "currentUser,identifier,image,images,name,subscribed,username".split(","), "_metadata");
d.define(o, ["artist"], "_associatedArtist");
j.init(o, "user");
o.prototype._associatedArtist = function (b) {
a.request("user_associated_artist", [this.uri], this, function (a) {
this.resolveMany(b, a)
}, function (a) {
this.resolveFail(b, a)
})
};
o.prototype._make_artist = function (a) {
return a && s.fromURI(a)
};
o._relationsListener = null;
o.fromURI = g.lookup;
o.fromURIs = g.lookupMany;
o._cache = new g(o);
o.fromUsername = function (a) {
for (var a = encodeURIComponent(a), b = -1;
(b = a.indexOf("%", b + 1)) > -1;) a = a.substring(0, b + 1) + a.substring(b + 1, b + 3).toLowerCase() + a.substring(b + 3);
return o.fromURI("spotify:user:" + a)
};
o.getOrCreateRelationsListener = function () {
var a = o._relationsListener;
if (!a) a = new i, a.bridgeListen("relations_event_wait", [f.session.user.uri]), a.filter(function (a) {
a.receiver != "subscriptions" || a.type != "add" && a.type != "remove" || o._cache.update(a.uris, {
subscribed: a.type == "add"
})
}), o._relationsListener = a;
return a
};
o.prototype.load = function () {
var b = a.varargs(arguments);
Array.prototype.indexOf.call(b, "subscribed") >= 0 && o.getOrCreateRelationsListener();
return o._superClass.load.apply(this, b)
};
var E = function (a, b) {
var c = a.split(":");
switch (c[1]) {
case "album":
return c.length == 4 ? l.fromURI(a, b) : k.fromURI(a, b);
case "artist":
return s.fromURI(a, b);
case "track":
return q.fromURI(a, b);
case "user":
return c.length > 3 && c[2] != "facebook" ? m.fromURI(a, b) : o.fromURI(a, b)
}
return null
};
q._trackEventWait();
f.Observable = b;
f.Loadable = d;
f.BridgeLoadable = h;
f.Album = k;
f.Application = t;
f.Artist = s;
f.Cache = g;
f.Client = z;
f.Collection = v;
f.BridgeCollection = r;
f.Context = x;
f.Disc = l;
f.Group = B;
f.Player = p;
f.Playlist = m;
f.Promise = c;
f.Session = A;
f.Track = q;
f.User = o;
f.application = new t;
f.client = new z;
f.fromURI = E;
f.player = new p("main");
f.preview = new p("preview");
f.promisedRequest = n;
f.session = new A
})
})(SpotifyApi.api, SpotifyApi.api._modules);
(function (a, f) {
_unrequire("$api/hermes", ["$api/models"], function (g) {
(function (b) {
function c(a) {
return a.schema.id + "#" + a.name
}
function d() {}
function f(a, b, c, d, g) {
j.call(this);
this.resolve("uri", b);
this.resolve("method", a);
this.resolve("timeout", g || 0);
this._rtypes = c;
this._atypes = d;
a = k.join(this._rtypes.map(function (a) {
return a.schema.load("id")
}));
b = k.join(this._atypes.map(function (a) {
return a.schema.load("id")
}));
this._load = k.join(a, b)
}
function i(a) {
j.call(this);
this._urls = a
}
var j = b.Loadable,
k = b.Promise;
d.get = function (a, b, c, d) {
return new f("GET", a, b, c, d)
};
d.request = function (a, b, c, d, g) {
return new f(a, b, c, d, g)
};
a.inherit(f, j);
j.define(f, ["uri", "method", "timeout"]);
f.prototype.send = function (b) {
var d = new k,
f = this,
g = [].slice.call(arguments);
this._load.done(function () {
var b = f._rtypes.map(c),
h = f._atypes.map(c);
a.request("hermes_send_request", [f.uri, f.method, b, h, g, f.timeout], d, function (a) {
d.setDone(a.result)
}, d.setFail)
}).fail(function (a, b) {
d.setFail(b)
});
return d
};
a.inherit(i, j);
j.define(i, ["id"], "_register");
i.fromURL = function (a) {
typeof a === "string" && (a = [a]);
return new this(a)
};
i.prototype.type = function (a) {
return {
schema: this,
name: a
}
};
i.prototype._register = function (b) {
a.request("hermes_register_schema", this._urls, this, function (a) {
this.resolveMany(b, a)
}, function (a) {
this.resolveFail(b, a)
})
};
g.Hermes = d;
g.Schema = i
})(f["$api/models"])
})
})(SpotifyApi.api, SpotifyApi.api._modules);
(function (a, f) {
_unrequire("$api/search", ["$api/models"], function (g) {
(function (b) {
function c(a, b) {
d.call(this);
var c = "spotify:search:" + encodeURIComponent(b).replace(/%20/g, "+");
this.resolve("uri", c);
this.resolve("query", b);
this.resolve("albums", new f(i, null, a + "_albums", b));
this.resolve("artists", new f(j, null, a + "_artists", b));
this.resolve("playlists", new f(k, null, a + "_playlists", b));
this.resolve("tracks", new f(l, c, a + "_tracks", b))
}
var d = b.Loadable,
f = b.BridgeCollection,
i = b.Album,
j = b.Artist,
k = b.Playlist,
l = b.Track;
a.inherit(c, d);
d.define(c, "albums,artists,playlists,query,tracks,uri".split(","));
d.define(c, ["fuzzyMatch"], "_fuzzy");
c.search = function (a) {
return new this("search", a)
};
c.suggest = function (a) {
return new this("suggest", a)
};
c.prototype._fuzzy = function (b) {
a.request("search_fuzzy_match", [this.query], this, function (a) {
this.resolveMany(b, a)
}, function (a) {
this.resolveFail(b, a)
})
};
g.Search = c
})(f["$api/models"])
})
})(SpotifyApi.api, SpotifyApi.api._modules);
(function (a, f) {
_unrequire("$api/toplists", ["$api/models"], function (g) {
(function (b) {
function c(a, b, c, g) {
d.call(this);
this.resolve("uri", c + "tracks" + g);
this.resolve("albums", new f(i, c + "albums" + g, a + "_albums", b));
this.resolve("artists", new f(j, c + "artists" + g, a + "_artists", b));
this.resolve("tracks", new f(l, c + "tracks" + g, a + "_tracks", b));
this.resolve("playlists", new f(k, c + "playlists" + g, a + "_playlists", b))
}
var d = b.Loadable,
f = b.BridgeCollection,
i = b.Album,
j = b.Artist,
k = b.Playlist,
l = b.Track,
u = b.session;
a.inherit(c,
d);
d.define(c, ["albums", "artists", "tracks", "playlists", "uri"]);
c.forCurrentUser = function () {
return new this("toplist_user", u.user.uri, u.user.uri + ":top:", "")
};
c.forUser = function (a) {
return new this("toplist_user", a.uri, a.uri + ":top:", "")
};
c.forWorld = function () {
return new this("toplist_region", "global", "spotify:top:", "")
};
c.forCurrentRegion = function () {
return new this("toplist_region", null, "spotify:top:", ":country:USER")
};
c.forRegion = function (a) {
return new this("toplist_region", a, "spotify:top:", ":country:" + a)
};
c.forArtist = function (a, b) {
return new this("toplist_artist", a.uri, a.uri + ":top:", b ? ":country:" + b : "")
};
g.Toplist = c
})(f["$api/models"])
})
})(SpotifyApi.api, SpotifyApi.api._modules);
(function (a, f) {
_unrequire("$api/location", ["$api/models"], function (g) {
(function (b) {
function c() {
b.Loadable.call(this)
}
a.inherit(c, b.Loadable);
b.Loadable.define(c, ["accuracy", "latitude", "longitude"], "_query");
c.prototype._query = function (b) {
a.request("location_query", [], this, function (a) {
this.resolveMany(b, a)
}, function (a) {
this.resolveFail(b, a)
})
};
c.query = function () {
return new c
};
g.Location = c
})(f["$api/models"])
})
})(SpotifyApi.api, SpotifyApi.api._modules);
(function (a, f) {
_unrequire("$api/library", ["$api/models"], function (g) {
(function (b) {
function c(a) {
b.Track._cache.update(a.uris, {
starred: a.type == "insert"
})
}
function d(a) {
b.BridgeLoadable.call(this);
var d = b.User.fromURI(a);
this.resolve("owner", d);
this.resolve("albums", new b.BridgeCollection(b.Album, null, "library_albums", d.uri));
this.resolve("artists", new b.BridgeCollection(b.Artist, null, "library_artists", d.uri));
this.resolve("playlists", new b.BridgeCollection(b.Playlist, null, "library_playlists", d.uri));
this.resolve("published", new b.BridgeCollection(b.Playlist, null, "library_published", d.uri));
this.resolve("starred", b.Playlist.fromURI(d.uri + ":starred"));
this.resolve("toplist", b.Playlist.fromURI(d.uri + ":toplist"));
this.resolve("tracks", new b.BridgeCollection(b.Track, this.uri, "library_tracks", d.uri));
if (d.uri == b.session.user.uri) b.Playlist.getOrCreateLibraryListener().proxyTo(this), this.starred.addEventListener("insert", c), this.starred.addEventListener("remove", c);
else {
var f = this,
a = function () {
f.bridgeListen("library_event_wait", [d.uri])
};
this.albums._observed = a;
this.artists._observed = a;
this.playlists._observed = a;
this.published._observed = a;
this.tracks._observed = a
}
}
a.inherit(d, b.BridgeLoadable);
d.fromURI = b.Cache.lookup;
d._cache = new b.Cache(d);
b.Loadable.define(d, "albums,artists,owner,playlists,published,starred,toplist,tracks".split(","));
d.prototype.publish = function (c) {
return b.promisedRequest(this, "library_publish", [this.owner.uri].concat(a.uris(arguments)))
};
d.prototype.star = function (c) {
return b.promisedRequest(this, "library_star", [this.owner.uri].concat(a.uris(arguments)))
};
d.prototype.subscribe = function (c) {
return b.promisedRequest(this, "library_subscribe", [this.owner.uri].concat(a.uris(arguments)))
};
d.prototype.unpublish = function (c) {
return b.promisedRequest(this, "library_unpublish", [this.owner.uri].concat(a.uris(arguments)))
};
d.prototype.unstar = function (c) {
return b.promisedRequest(this, "library_unstar", [this.owner.uri].concat(a.uris(arguments)))
};
d.prototype.unsubscribe = function (c) {
return b.promisedRequest(this, "library_unsubscribe", [this.owner.uri].concat(a.uris(arguments)))
};
d.forCurrentUser = function () {
return d.forUser(b.session.user)
};
d.forUser = function (a) {
return d.fromURI(a.uri)
};
g.Library = d
})(f["$api/models"])
})
})(SpotifyApi.api, SpotifyApi.api._modules);
(function (a, f) {
_unrequire("$api/activity", ["$api/models"], function (g) {
(function (b) {
function c(a, b) {
this.resolve("identifier", a);
this.resolveMany(0, b)
}
function d(a) {
b.BridgeLoadable.call(this);
this.resolve("user", a);
this.resolve("activities", new b.BridgeCollection(c, null, "feed_activities", a ? a.uri : null))
}
a.inherit(c, b.Loadable);
b.Loadable.define(c, "activityType,context,item,message,referrer,timestamp,user".split(","));
c.Type = {
PLAYLIST_PUBLISHED: "playlist-published",
PLAYLIST_TRACK_ADDED: "playlist-track-added",
TRACK_FINISHED_PLAYING: "track-finished-playing",
APP_ADDED: "app-added",
TRACK_STARTED_PLAYING: "track-started-playing",
URI_SHARED: "uri-shared",
ARTIST_FOLLOWED: "artist-followed",
UNKNOWN: "unknown"
};
c.prototype._make_activityType = function (a) {
switch (a) {
case 1:
return c.Type.PLAYLIST_PUBLISHED;
case 2:
return c.Type.PLAYLIST_TRACK_ADDED;
case 3:
return c.Type.TRACK_FINISHED_PLAYING;
case 4:
return c.Type.APP_ADDED;
case 5:
return c.Type.TRACK_STARTED_PLAYING;
case 6:
return c.Type.URI_SHARED;
case 7:
return c.Type.ARTIST_FOLLOWED;
default:
return c.Type.UNKNOWN
}
};
c.prototype._make_context = function (a) {
return a && b.fromURI(a.uri, a)
};
c.prototype._make_item = function (a) {
return a && b.fromURI(a.uri, a)
};
c.prototype._make_referrer = function (a) {
return a
};
c.prototype._make_timestamp = function (a) {
return new Date(a)
};
c.fromURI = function (a, b) {
return new c(a, b)
};
a.inherit(d, b.BridgeLoadable);
b.Loadable.define(d, ["activities", "user"]);
d.prototype._observed = function () {
this.bridgeListen("feed_event_wait", [this.user ? this.user.uri : null])
};
d.forCurrentUser = function () {
return new d(b.session.user)
};
d.forUser = function (a) {
return new d(a)
};
d.forRelations = function () {
return new d(null)
};
g.Feed = d
})(f["$api/models"])
})
})(SpotifyApi.api, SpotifyApi.api._modules);
(function (a, f) {
_unrequire("$api/relations", ["$api/models"], function (g) {
(function (b) {
function c(a) {
b.BridgeLoadable.call(this);
a = b.User.fromURI(a);
this.resolve("owner", a);
this.resolve("subscribers", new b.BridgeCollection(b.User, null, "relations_subscribers_users", a.uri));
this.resolve("subscriptions", new b.BridgeCollection(b.User, null, "relations_subscriptions_users", a.uri))
}
function d(a) {
c.call(this, a);
this.resolve("blocked", new b.BridgeCollection(b.User, null, "relations_blocked_users", this.owner.uri));
this.resolve("dismissed", new b.BridgeCollection(b.User, null, "relations_dismissed_users", this.owner.uri));
this.resolve("hidden", new b.BridgeCollection(b.User, null, "relations_hidden_users", this.owner.uri));
b.User.getOrCreateRelationsListener().proxyTo(this)
}
a.inherit(c, b.BridgeLoadable);
c.fromURI = b.Cache.lookup;
c._cache = new b.Cache(c);
b.Loadable.define(c, ["owner", "subscribers", "subscriptions"]);
a.inherit(d, c);
b.Loadable.define(d, ["blocked", "dismissed", "hidden"]);
d.prototype.block = function (c) {
return b.promisedRequest(this,
"relations_block", [this.owner.uri].concat(a.uris(arguments)))
};
d.prototype.dismiss = function (c) {
return b.promisedRequest(this, "relations_dismiss", [this.owner.uri].concat(a.uris(arguments)))
};
d.prototype.subscribe = function (c) {
return b.promisedRequest(this, "relations_subscribe", [this.owner.uri].concat(a.uris(arguments)))
};
d.prototype.unblock = function (c) {
return b.promisedRequest(this, "relations_unblock", [this.owner.uri].concat(a.uris(arguments)))
};
d.prototype.unsubscribe = function (c) {
return b.promisedRequest(this,
"relations_unsubscribe", [this.owner.uri].concat(a.uris(arguments)))
};
c._currentUser = null;
c.forCurrentUser = function () {
if (!c._currentUser) c._currentUser = new d(b.session.user.uri);
return c._currentUser
};
c.forUser = function (a) {
return c.fromURI(a.uri)
};
g.Relations = c
})(f["$api/models"])
})
})(SpotifyApi.api, SpotifyApi.api._modules);
(function (a, f) {
_unrequire("$api/runtime", ["$api/models", "$api/../vendor/js-yaml.min"], function (g) {
(function (b, c) {
function d(a) {
return (a = a.match(/^(\$([^\/]+)\/)/)) ? a[2] : void 0
}
function f(a, c, d) {
b.Loadable.call(this);
this.resolve("level", d);
this.resolve("message", c);
this.resolve("timestamp", new Date(a))
}
function i(a) {
b.BridgeLoadable.call(this);
this.resolve("application", a);
this.resolve("entries", new b.BridgeCollection(f, a.uri, "log_entries"));
this.bridgeListen("log_event_wait", [a.uri])
}
c = window.jsyaml;
a.inherit(f, b.Loadable);
b.Loadable.define(f, ["level", "message", "timestamp"]);
f.fromURI = function (a, b) {
return new f(b.timestamp, b.message, b.level)
};
a.inherit(i, b.BridgeLoadable);
b.Loadable.define(i, ["application", "entries"]);
i.forApplication = function (a) {
return new i(a)
};
i.forCurrentApplication = function () {
return new i(b.application)
};
g.require = function (b, c, f) {
for (var g = [], h = [], i = 0, s = b.length; i < s; i++) {
var v = b[i],
r = d(v);
if (!r) throw Error("Empty module name in require.");
g.push(r);
var x = r.split("@");
h.push(v.replace(r,
x[0]))
}
a.request("application_require", g, this, function () {
window.require(h, c)
}, function (a) {
if (f) f(a);
else throw Error("Error requiring modules: " + b.join(", "));
})
};
g.isRequestImplemented = function (c) {
var d = new b.Promise;
a.request("core_request_lookup", [c], this, function (a) {
d.setDone(a.found)
}, function () {
d.setFail()
});
return d
};
g.getBridgeDefinition = function () {
var a = new b.Promise;
b.application.readFile("$api/bridge/requests.yaml").done(function (b) {
a.setDone(c.load(b))
}).fail(function () {
a.setFail()
});
return a
};
g.Log = i
})(f["$api/models"], f["$api/../vendor/js-yaml.min"])
})
})(SpotifyApi.api, SpotifyApi.api._modules);
(function () {
_unrequire("$api/utils/base", [], function (a) {
var f = Array.prototype.slice;
a.bind = Function.prototype.bind ? function (a, b) {
return a.bind(b)
} : function (a, b) {
return function () {
return !arguments.length ? a.call(b) : a.apply(b, arguments)
}
};
a.partial = Function.prototype.bind ? function (a, b) {
var c = f.call(arguments, 1);
return a.bind.apply(a, c)
} : function (a, b) {
var c = f.call(arguments, 2);
return !c.length ? this.bind(a, b) : function () {
return a.apply(b, !arguments.length ? c : c.concat(f.call(arguments)))
}
}
})
})(SpotifyApi.api,
SpotifyApi.api._modules);
(function () {
_unrequire("$api/utils/css", [], function (a) {
var f = document.head || document.getElementsByTagName("head")[0],
g = {};
a.importSheet = function (a) {
var b = a.match(/^(\$(?:[^\/]+)\/)(?!css)(.*)/);
b && (a = b[1] + "css/" + b[2]);
a += ".css";
if (g[a]) return this;
g[a] = 1;
b = document.createElement("link");
b.rel = "stylesheet";
b.href = a;
f.appendChild(b);
return this
};
a.importSheets = function () {
if (!arguments.length) return this;
if (arguments.length == 1) return this.importSheet(arguments[0]);
for (var a = 0, b = arguments.length; a < b; a++) this.importSheet(arguments[0]);
return this
};
var b = {};
a.appendStyles = function (a, d) {
a = "sp-" + a;
if (b[a]) return getElementById(a);
b[a] = 1;
var g = document.createElement("style");
g.id = g.name = a;
if (!d) return g;
var i = "",
j, k;
for (k in d) if (d.hasOwnProperty(k)) {
var l = d[k];
i += k;
j = [];
for (k in l) l.hasOwnProperty(k) && j.push(k + ": " + l[k]);
i += " {" + j.join("; ") + "}\n"
}
g.innerHTML = i;
f.appendChild(g);
return g
};
a.getStyle = "currentStyle" in f ? function (a, b) {
return a.currentStyle[b]
} : function (a, b) {
var f = a.ownerDocument.defaultView;
if (!f) return null;
f = f.getComputedStyle(a,
null);
return !f ? null : f.getPropertyValue(b)
}
})
})(SpotifyApi.api, SpotifyApi.api._modules);
(function () {
_unrequire("$api/utils/dom", [], function (a) {
var f = Array.prototype.slice;
a.id = function (a) {
return document.getElementById(a)
};
a.query = function (a, b) {
return (b || document).querySelector(a)
};
a.queryAll = function (a, b) {
return f.call((b || document).querySelectorAll(a))
};
a.queryClasses = function (a, b) {
return f.call((b || document).getElementsByClassName(a))
};
a.queryTags = function (a, b) {
return f.call((b || document).getElementsByTagName(className))
}
})
})(SpotifyApi.api, SpotifyApi.api._modules);
// https://play.spotify.com/static/proto/discovery.proto
// 15/12/2012
package spotify.discovery.proto;
message VoidRequest {
}
message UserInfo {
optional string country = 1;
}
message WhatsNewRequest {
optional UserInfo user_info = 1;
}
message SuggestPlaylistsRequest {
repeated string fb_uids = 1;
repeated string staff_ids = 2;
// Number of (in)active playlists to get, will get max_playlists each
optional int32 max_playlists = 3;
optional int32 max_staff_pick_playlists = 4;
}
enum SuggestionSourceType {
SUGGESTION_SOURCE_FRIEND = 1;
SUGGESTION_SOURCE_NON_FRIEND = 2;
SUGGESTION_SOURCE_STAFF = 3;
}
message SuggestedPlaylist {
optional string playlist_uri = 1;
optional string playlist_picture = 2;
optional string playlist_name = 3;
optional string playlist_creator_social_name = 4;
// fb_uid or username depending on what kind of suggested playlist this is
optional string suggestion_source = 5;
optional SuggestionSourceType suggestion_source_type = 6;
}
message SuggestPlaylistsReply {
repeated SuggestedPlaylist inactive_playlists = 1;
repeated SuggestedPlaylist active_playlists = 2;
repeated SuggestedPlaylist staff_pick_playlists = 3;
}
message NewAlbum {
optional string album_uri = 1;
// The artists on the album
repeated string artist_uris = 2;
}
message NewAlbumsReply {
repeated NewAlbum albums = 1;
}
message FriendsPlaylist {
optional string playlist_uri = 1;
repeated string friends = 2;
// Total friends that has this playlist
// This number may be higher than len(friends)
optional int32 total_friends = 3;
optional string playlist_name = 4;
optional string playlist_creator_social_name = 5;
}
message FriendsPlaylistsReply {
repeated FriendsPlaylist playlists = 1;
}
message FriendsTrackToplists {
optional string track_uri = 1;
repeated string friends = 2;
// Total friends that has this playlist
// This number may be higher than len(friends)
optional int32 total_friends = 3;
}
message FriendsToplistEntry {
optional string item_uri = 1;
repeated string friends = 2;
optional int32 total_friends = 3;
}
message FriendsToplist {
optional string toplist_type = 1;
repeated FriendsToplistEntry entries = 2;
}
message FriendsToplistsReply {
repeated FriendsToplist toplists = 1;
}
message FriendsTrackToplistsReply {
repeated FriendsTrackToplists track_toplists = 1;
}
message NewFriendsReply {
repeated string new_friends = 1;
}
message RegionTrack {
optional string track_uri = 1;
}
message RegionTracksReply {
repeated RegionTrack region_tracks = 1;
}
message RegionPlaylist {
optional string playlist_uri = 1;
optional int32 popularity = 2; // in parts per thousand
optional string playlist_name = 3;
optional string playlist_creator_social_name = 4;
}
message RegionPlaylistReply {
repeated RegionPlaylist region_playlists = 1;
}
message WhatsNewReply {
optional NewAlbumsReply new_albums = 1;
optional FriendsPlaylistsReply friends_playlists = 2;
optional FriendsTrackToplistsReply friends_track_toplists = 3;
optional NewFriendsReply new_friends = 4;
optional RegionTracksReply region_tracks = 5;
optional RegionPlaylistReply region_playlists = 6;
}
message RegionTracksPlaylistsReply {
repeated RegionTrack region_tracks = 1;
repeated RegionPlaylist region_playlists = 2;
}
//#service DiscoveryService {
// rpc get_new_albums (VoidRequest) returns (NewAlbumsReply);
// rpc get_friends_playlists (VoidRequest) returns (FriendsPlaylistsReply);
// rpc get_friends_track_toplists (VoidRequest) returns (FriendsTrackToplistsReply);
// rpc get_new_friends (VoidRequest) returns (NewFriendsReply);
//}
/*
* https://spapps.spotify.edgekey.net/player/36b195f/scripts/main.js
*
* 15/12/2012
*/
(function (Y, e) {
_unrequire("/scripts/player.events", [], function (e) {
function f() {
this.listeners = {}
}
f.prototype.subscribe = function (f, g, d) {
this.listeners[f] === void 0 && (this.listeners[f] = []);
this.listeners[f].push([g, d || null])
};
f.prototype.unsubscribe = function (f, g) {
if (this.listeners[f] !== void 0) for (var d = this.listeners[f].length, c = 0; c < d; c++) if (this.listeners[f][c][0] === g) {
this.listeners[f].splice(c, 1);
break
}
};
f.prototype.trigger = function (f, g) {
if (this.listeners[f] !== void 0) for (var d = this.listeners[f].length,
c = 0; c < d; c++) this.listeners[f][c][0].call(this.listeners[f][c][1] || this, g || {})
};
f.prototype.Events = {
TRACK_CHANGED: "TRACK_CHANGED",
AD_CLICKED: "AD_CLICKED",
TRACK_SKIPPED: "TRACK_SKIPPED",
BACK_BUTTON_PRESS_START: "BACK_BUTTON_PRESS_START",
BACK_BUTTON_PRESS_COMPLETE: "BACK_BUTTON_PRESS_COMPLETE"
};
e.EventManager = f
});
_unrequire("/scripts/player.suggestions", ["$api/hermes", "$api/models"], function (i) {
(function (f) {
var o = f.Schema.fromURL(["/static/proto/radio.proto"]);
o.load().done(function () {
var g = f.Hermes;
i.getTrackSuggestions = function (d, c, b, a) {
d = {
salt: Math.floor(Math.random() * 1E6),
uris: d,
lastTracks: [],
length: c
};
g.get("hm://radio/", [o.type("Tracks")], [o.type("RadioRequest")]).send(d).done(b).fail(a)
}
}).fail(function () {})
})(e["$api/hermes"], e["$api/models"])
});
_unrequire("/scripts/player-utils", [], function (e) {
function f(c) {
this._maxLength = c;
this._items = []
}
function o() {
this.store = typeof window.localStorage != "undefined" ? window.localStorage : !1
}
function g(c, b) {
this.utils = d;
this.element = c;
this.maxWidth = b;
this.timer = null;
this.left = 0;
this.shouldScroll = this.scrolling = this.hovered = !1
}
f.prototype.add = function (c) {
for (var b = this._items.slice(0), a = 0; a < b.length; a++) if (b[a].uri === c.uri) return !1;
this._items[0] = c;
for (a = 1; a < this._maxLength; a++) typeof b[a - 1] !== "undefined" && (this._items[a] = b[a - 1]);
return this._items
};
f.prototype.show = function (c) {
if (!c || typeof this.get(0)[c] === "undefined") return this._items;
for (var b = [], a = 0; a < this._items.length; a++) b[a] = this._items[a][c];
return b
};
f.prototype.get = function (c) {
return this._items[c]
};
f.prototype.size = function () {
return this._items.length
};
f.prototype.forEach = function (c) {
for (var b = 0; b < this._items.length; b++) c(this._items[b])
};
o.prototype.set = function (c, b) {
if (!this.store) return !1;
try {
this.store.setItem(c, b)
} catch (a) {
return !1
}
};
o.prototype.get = function (c) {
return !this.store ? !1 : this.store.getItem(c)
};
var d = {
hasClassList: "classList" in document.createElement("a"),
secsToMins: function (c, b) {
var a = Math.floor(c),
d = Math.floor(a / 60) + ":" + ("0" + a % 60).slice(-2);
void 0 !== b && b && (d += "." + Math.round((c - a) * 1E3));
return d
},
getId: function (c) {
return document.getElementById(c)
},
hasClass: function (c, b) {
return this.hasClassList ? c.classList.contains(b) : c.className.match(RegExp("(\\s|^)" + b + "(\\s|$)"))
},
addClass: function (c, b) {
this.hasClass(c, b) || (this.hasClassList ? c.classList.add(b) : c.className += " " + b)
},
removeClass: function (c, b) {
if (this.hasClass(c, b)) this.hasClassList ? c.classList.remove(b) : c.className = c.className.replace(RegExp("(\\s|^)" + b + "(\\s|$)"), " ")
},
addEventSimple: function (c, b, a) {
c.addEventListener ? c.addEventListener(b,
a, !1) : c.attachEvent && c.attachEvent("on" + b, a)
},
removeEventSimple: function (c, b, a) {
c.removeEventListener ? c.removeEventListener(b, a, !1) : c.detachEvent && c.detachEvent("on" + b, a)
},
extendObject: function (c, b) {
for (var a in b) b[a] && b[a].constructor && b[a].constructor === Object ? (c[a] = c[a] || {}, arguments.callee(c[a], b[a])) : c[a] = b[a];
return c
},
proxy: function (c, b) {
return function () {
return c.apply(b, arguments)
}
}
};
g.prototype.init = function () {
this.onMouseOver = this.onMouseOver.bind(this);
this.onMouseOut = this.onMouseOut.bind(this);
this.scroll = this.scroll.bind(this);
this.utils.addEventSimple(this.element, "mouseover", this.onMouseOver);
this.utils.addEventSimple(this.element, "mouseout", this.onMouseOut);
this.element.style.position = "relative"
};
g.prototype.refresh = function () {
this.scrolling && this.stop();
this.textWidth = this.element.offsetWidth;
(this.shouldScroll = this.textWidth > this.maxWidth) ? (this.element.style.left = "0px", this.left = 0) : this.element.style.left = (this.maxWidth - this.element.offsetWidth) / 2 + 5 + "px"
};
g.prototype.widthAdjust = function (c) {
this.maxWidth = c;
this.refresh()
};
g.prototype.stop = function () {
if (this.timer) clearInterval(this.timer), this.element.innerHTML = this._originalText, this.scrolling = !1, this.refresh()
};
g.prototype.scroll = function () {
Math.abs(this.left) === this.textWidth + 10 ? (this.element.style.left = "0px", this.left = 0, this.hovered || this.stop()) : (this.left--, this.element.style.left = "" + this.left + "px")
};
g.prototype.onMouseOver = function () {
if (this.shouldScroll && !this.scrolling) this.scrolling = !0, this._originalText = this.element.innerHTML,
this.element.innerHTML = this._originalText + '<span class="padder"></span>' + this._originalText, this.timer = setInterval(this.scroll, 15)
};
g.prototype.onMouseOut = function () {
this.hovered = !1
};
e.trackHistory = f;
e.playerStorage = o;
e.playerUtils = d;
e.Marquee = g;
e.kc = function () {
var c = [38, 38, 40, 40, 37, 39, 37, 39, 66, 65, 13],
b = c.length,
a = null,
d = null,
j = 0,
f = function (a) {
a.keyCode === c[j] ? (j += 1, j === b && (d(), j = 0)) : j = 0
}, g = function () {
if (a.addEventListener) a.addEventListener("keydown", f, !1);
else if (a.attachEvent) a.attachEvent("onkeydown",
f);
else if (typeof a.onkeydown === "function") {
var b = a.onkeydown;
a.onkeydown = function (a) {
b(a);
f(a)
}
} else a.onkeydown = f
};
return {
onSuccess: function () {},
listenerTarget: window,
init: function () {
d = this.onSuccess;
a = this.listenerTarget;
g()
}
}
}
});
_unrequire("/scripts/player.widgets", ["$api/models", "/scripts/player-utils", "/scripts/player-utils"], function (i) {
(function (f, e, g) {
function d(c, b, a) {
this.element = c;
this.eventManager = a;
this.track = null;
this.artistsAdded = this.artistsWanted = 0;
this.marquee = new g(c, b);
this.marquee.init();
this.eventManager.subscribe(this.eventManager.Events.TRACK_CHANGED, this.setTrack, this)
}
d.prototype.init = function () {
this.onArtistLoaded = this.onArtistLoaded.bind(this);
this.onArtistClicked = this.onArtistClicked.bind(this);
e.addEventSimple(this.element, "click", this.onArtistClicked)
};
d.prototype.resize = function (c) {
this.marquee.widthAdjust(c)
};
d.prototype.onArtistClicked = function (c) {
c.preventDefault();
c.target.href && (this.track.advertisement ? this.eventManager.trigger(this.eventManager.Events.AD_CLICKED) : f.application.openURI(c.target.href.toSpotifyURI()))
};
d.prototype.onArtistLoaded = function (c) {
this.addArtist(c)
};
d.prototype.setTrack = function (c) {
var b = this;
c.load("artists").done(function (a) {
b.clear();
b.track = a;
b.artistsWanted = a.artists && a.artists.length || 0;
for (var c = b.artistsWanted, d = 0; d < c; d++) a.artists[d].load(["name", "uri"]).done(function (a) {
b.onArtistLoaded(a)
})
})
};
d.prototype.addArtist = function (c) {
this.artistsAdded > 0 && this.element.appendChild(document.createTextNode(", "));
var b = document.createElement("a");
b.innerHTML = c.name.decodeForHtml();
b.href = c.uri.toSpotifyURL();
this.element.appendChild(b);
this.artistsAdded++;
this.artistsAdded === this.artistsWanted && this.marquee.refresh()
};
d.prototype.clear = function () {
if (this.track !== null) this.track = null, this.element.innerHTML = "", this.artistsAdded = 0
};
i.ArtistWidget = d
})(e["$api/models"], e["/scripts/player-utils"].playerUtils, e["/scripts/player-utils"].Marquee)
});
_unrequire("/scripts/player.shufflebutton", ["$api/models", "/scripts/player-utils"], function (i) {
(function (f,
e) {
function g(b) {
var a = this,
d = f.player;
a._node = document.getElementById(b);
a._store = new c;
d.load(["shuffle"]).done(function (b) {
a._player = b;
a.init()
})
}
var d = e.playerUtils,
c = e.playerStorage;
f.Loadable.define(f.Player, ["__rules"], "_playapp");
g.prototype.init = function () {
var b = this;
b._player.addEventListener("change:shuffle", function () {
b.updateStatus()
});
d.addEventSimple(b._node, "click", function () {
b.toggle()
});
b._player.addEventListener("change", function () {
b._handleRules()
});
if (b._store.get("spShuffle") ===
"true") b.on()
};
g.prototype._handleRules = function () {
this._player.__rules.shuffle ? this.enableButton() : this.disableButton()
};
g.prototype.updateStatus = function () {
this._player.shuffle ? (d.addClass(this._node, "active"), this._store.set("spShuffle", "true")) : (d.removeClass(this._node, "active"), this._player.__rules && this._player.__rules.shuffle && this._store.set("spShuffle", "false"))
};
g.prototype.on = function () {
var b = this;
b._player.setShuffle(!0).done(function () {
b.updateStatus()
})
};
g.prototype.off = function () {
var b = this;
b._player.setShuffle(!1).done(function () {
b.updateStatus()
})
};
g.prototype.toggle = function () {
if (d.hasClass(this._node, "disabled")) return !1;
if (this._player.shuffle) this.off();
else this.on()
};
g.prototype.disableButton = function () {
d.addClass(this._node, "disabled");
this.updateStatus()
};
g.prototype.enableButton = function () {
d.removeClass(this._node, "disabled");
this.updateStatus()
};
i.ShuffleButton = g
})(e["$api/models"], e["/scripts/player-utils"])
});
_unrequire("/scripts/player.repeatbutton", ["$api/models",
"/scripts/player-utils"], function (i) {
(function (f, e) {
function g(b) {
var a = this,
d = f.player;
a._node = document.getElementById(b);
a._store = new c;
a._disabled = !1;
d.load(["repeat"]).done(function (c) {
a._player = c;
a.init(b)
})
}
var d = e.playerUtils,
c = e.playerStorage;
f.Loadable.define(f.Player, ["__rules"], "_playapp");
g.prototype.init = function () {
var b = this;
b._player.addEventListener("change:repeat", function () {
b.updateStatus()
});
b._player.addEventListener("change", function () {
b._handleRules()
});
d.addEventSimple(b._node,
"click", function () {
b.toggle()
});
if (b._store.get("spRepeat") === "true") b.on()
};
g.prototype._handleRules = function () {
this._player.__rules.repeat ? this.enableButton() : this.disableButton()
};
g.prototype.updateStatus = function () {
this._player.repeat ? (d.addClass(this._node, "active"), this._store.set("spRepeat", "true")) : (d.removeClass(this._node, "active"), this._player.__rules && this._player.__rules.repeat && this._store.set("spRepeat", "false"))
};
g.prototype.on = function () {
var b = this;
b._player.setRepeat(!0).done(function () {
b.updateStatus()
})
};
g.prototype.off = function () {
var b = this;
b._player.setRepeat(!1).done(function () {
b.updateStatus()
})
};
g.prototype.toggle = function () {
if (d.hasClass(this._node, "disabled")) return !1;
if (this._player.repeat) this.off();
else this.on()
};
g.prototype.disableButton = function () {
this._disabled = !0;
d.addClass(this._node, "disabled");
this.updateStatus()
};
g.prototype.enableButton = function () {
this._disabled = !1;
d.removeClass(this._node, "disabled");
this.updateStatus()
};
i.RepeatButton = g
})(e["$api/models"], e["/scripts/player-utils"])
});
_unrequire("/scripts/player.playpausebutton", ["$api/models", "/scripts/player-utils"], function (i) {
(function (f, e) {
function g(c) {
var b = this,
a = f.player;
b._node = document.getElementById(c);
a.load(["playing", "track", "context"]).done(function (a) {
b._player = a;
b.init()
})
}
var d = e.playerUtils;
g.prototype.init = function () {
var c = this;
d.addEventSimple(c._node, "click", function (b) {
c.toggle(b)
});
c._player.addEventListener("change:playing", function () {
c.updateStatus()
});
c._player.addEventListener("change", function () {
c.updateStatus()
});
c.updateStatus()
};
g.prototype.toggle = function (c) {
c && c.preventDefault();
this._player.playing ? this._player.pause() : (this._player.track && this._player.track.advertisement && this._player.volume === 0 && this._player.setVolume(0.1), this._player.play())
};
g.prototype.updateStatus = function () {
this._player.playing ? d.addClass(this._node, "playing") : d.removeClass(this._node, "playing");
!this._player.track && (!this._player.context || !this._player.context.uri) ? this.disableButton() : this.enableButton()
};
g.prototype.disableButton = function () {
d.addClass(this._node, "disabled");
d.removeClass(this._node, "playing")
};
g.prototype.enableButton = function () {
d.removeClass(this._node, "disabled")
};
i.PlayPauseButton = g
})(e["$api/models"], e["/scripts/player-utils"])
});
_unrequire("/scripts/player.nextbackbuttons", ["$api/models", "/scripts/player-utils"], function (i) {
(function (f, e) {
function g(a, c) {
var d = this;
d._node = document.getElementById(a);
d._eventManager = c;
d._disabled = !1;
b.load(["playing"]).done(function (a) {
d._player = a;
d.init()
})
}
function d(a,
c) {
var d = this;
d._eventManager = c;
d._disabled = !1;
d._node = document.getElementById(a);
b.load(["playing"]).done(function (a) {
d._player = a;
d.init()
})
}
var c = e.playerUtils,
b = f.player;
f.Loadable.define(f.Player, ["__rules"], "_playapp");
g.prototype.init = function () {
var a = this;
c.addEventSimple(a._node, "click", function (b) {
b.preventDefault();
a.playerNext();
a._node.blur()
});
a._player.addEventListener("change", function () {
a._handleRules()
})
};
g.prototype._handleRules = function () {
this._player.__rules.next ? !this._player.track || !this._player.context ? this.disableButton() : this.enableButton() : this.disableButton()
};
g.prototype.playerNext = function () {
this._disabled || (this._eventManager.trigger(this._eventManager.Events.TRACK_SKIPPED), this._player.skipToNextTrack())
};
g.prototype.disableButton = function () {
this._disabled = !0;
c.addClass(this._node, "disabled")
};
g.prototype.enableButton = function () {
this._disabled = !1;
c.removeClass(this._node, "disabled")
};
d.prototype.init = function () {
var a = this;
c.addEventSimple(a._node, "click", function (b) {
b.preventDefault();
a.playerBack();
a._node.blur()
});
a._player.addEventListener("change", function () {
a._handleRules()
})
};
d.prototype._handleRules = function () {
this._player.__rules.previous ? (this._disabled && this.enableButton(), !this._player.track || !this._player.context ? this.disableButton() : this.enableButton()) : this.disableButton()
};
d.prototype.playerBack = function () {
if (this._disabled || this._player.track.duration - this._player.position < 500) return !1;
this._eventManager.trigger(this._eventManager.Events.BACK_BUTTON_PRESS_START);
this._player.position > 4E3 || this._player.__index === 0 && !this._player.repeat ? (this._player.seek(0), this._player.playing || this._player.play()) : (this._player.skipToPrevTrack(), this._eventManager.trigger(this._eventManager.Events.TRACK_SKIPPED));
this._eventManager.trigger(this._eventManager.Events.BACK_BUTTON_PRESS_COMPLETE)
};
d.prototype.disableButton = function () {
this._disabled = !0;
c.addClass(this._node, "disabled")
};
d.prototype.enableButton = function () {
this._disabled = !1;
c.removeClass(this._node, "disabled")
};
i.NextButton = g;
i.BackButton = d
})(e["$api/models"], e["/scripts/player-utils"])
});
_unrequire("/scripts/utils.draggable", [], function (e) {
e.Draggable = function (f, e) {
var g = void 0,
d = void 0,
c = void 0,
b = void 0,
a = void 0,
m = !1,
j = {
constrainDir: !1,
constrainParent: !1,
onStart: function () {},
onMove: function () {},
onComplete: function () {}
};
self.element = f;
if (typeof f === "string") self.element = document.getElementById(f);
f.onmousedown = function (a) {
y(a)
};
for (var i in e) j[i] = e[i];
this.setContainerSize = function () {
m = {
maxW: f.offsetParent.offsetWidth,
maxH: f.offsetParent.offsetHeight
}
};
j.constrainParent && this.setContainerSize();
var y = function (e) {
if (j.onStart(f) === !1) return !1;
a && p();
c = f.offsetLeft;
b = f.offsetTop;
a = f;
e = e || window.event;
e.preventDefault();
g = e.clientX;
d = e.clientY;
document.addEventListener("mousemove", w);
document.addEventListener("mouseup", p);
document.addEventListener("mouseout", x);
return !1
}, w = function (f) {
var e = f || window.event;
e.preventDefault();
f = c + (e.clientX - g);
e = b + (e.clientY - d);
if (j.constrainDir !== "y") m && (f < 0 && (f = 0), f > m.maxW - a.offsetWidth && (f = m.maxW - a.offsetWidth)), a.style.left = f + "px";
if (j.constrainDir !== "x") m && (e < 0 && (e = 0), e > m.maxH - a.offsetHeight && (e = m.maxH - a.offsetHeight)), a.style.top = e + "px";
j.onMove(a, f, e);
return !1
}, x = function (a) {
a = a ? a : window.event;
a = a.relatedTarget || a.toElement;
(!a || a.nodeName == "HTML") && p()
}, p = function () {
document.removeEventListener("mousemove", w);
document.removeEventListener("mouseup", p);
document.removeEventListener("mouseout", x);
j.onComplete(a);
a = null
};
this.startDrag = y
}
});
_unrequire("/scripts/utils.slider", ["/scripts/utils.draggable"],
function (i) {
(function (f) {
function e(g, d, c) {
var b = this;
b._opts = {
steps: 100,
start: 0,
onStart: function () {},
onChange: function () {},
onComplete: function () {}
};
b._disabled = !1;
b._element = g;
b._handle = d;
if (typeof d === "string") b._handle = document.getElementById(d);
b.step = b._opts.start;
b.totalPx = g.offsetWidth - b._handle.offsetWidth;
for (var a in c) b._opts[a] = c[a];
b._moveHandle = function () {
b._handle.style.left = b.step / b._opts.steps * b.totalPx + "px"
};
var m = function (a) {
b.step = Math.round(a / b.totalPx * b._opts.steps);
b._opts.onChange.apply(b)
};
this._handleClick = function (a, b) {
if (this._disabled || a.target === d) return !1;
a.stopPropagation();
var c = b || a.offsetX || a.layerX;
c -= this._handle.offsetWidth / 2;
c = c < 0 ? 0 : c > this.totalPx ? this.totalPx : c;
m(c);
this._moveHandle();
this._opts.onChange.apply(this);
this._knob.startDrag(a)
};
this._knob = new f(d, {
constrainParent: !0,
constrainDir: "x",
onStart: function (a) {
if (b._disabled) return !1;
a.className = "dragging";
b._opts.onStart.apply(b)
},
onMove: function (a, b) {
m(b)
},
onComplete: function () {
b._handle.className = "";
b._opts.onComplete.apply(b)
}
});
g.addEventListener("mousedown", function (a) {
b._handleClick(a)
}, !1);
b.handle = b._handle;
b.jumpToStep(b._opts.start, !1)
}
e.prototype.jumpToStep = function (f, d) {
if (self._disabled) return !1;
this.step = f;
this._opts.onChange.apply(this);
this._moveHandle();
d !== !1 && this._opts.onComplete.apply(this)
};
e.prototype.handleResize = function () {
this.totalPx = this._element.offsetWidth - this._handle.offsetWidth;
this._moveHandle();
this._knob.setContainerSize();
this._opts.onChange.apply(this)
};
e.prototype.setSteps = function (f) {
this._opts.steps = f
};
e.prototype.disable = function () {
this._disabled = !0
};
e.prototype.enable = function () {
this._disabled = !1
};
e.prototype.handleClick = function (f, d) {
this._handleClick(f, d)
};
i.Slider = e
})(e["/scripts/utils.draggable"].Draggable)
});
_unrequire("/scripts/player.volumecontrol", ["$api/models", "/scripts/player-utils", "/scripts/utils.slider"], function (i) {
(function (f, e, g) {
function d(a) {
var c = this,
d = f.player;
c._wrapper = document.getElementById(a);
c._dragging = !1;
c._store = new b;
d.load(["volume"]).done(function (a) {
c._player = a;
c.init()
})
}
var c = e.playerUtils,
b = e.playerStorage;
d.prototype.reload = function () {
this._control.handleResize()
};
d.prototype.buildNodes = function () {
this._barOuter = document.createElement("div");
this._barOuter.id = "volume-bar";
this._handle = document.createElement("span");
this._handle.id = "vol-position";
this._barInner = document.createElement("div");
this._barInner.id = "vol-bar-inner";
this._barOuter.appendChild(this._barInner);
this._barOuter.appendChild(this._handle);
this._wrapper.appendChild(this._barOuter);
this._handleWidth = this._handle.offsetWidth
};
d.prototype.init = function () {
var a = this,
b = a._store.get("spVolume") || 100,
b = b < 0 ? 0 : b > 100 ? 100 : b;
a.buildNodes();
a._control = new g(a._barOuter, a._handle, {
steps: 100,
start: parseInt(b, 10),
onStart: function () {
a._dragging = !0;
c.addClass(a._wrapper, "in-use")
},
onChange: function () {
a._player.setVolume(this.step / 100);
a._barInner.style.width = Math.floor(this.step / this._opts.steps * this.totalPx + a._handleWidth) - 2 + "px"
},
onComplete: function () {
a._dragging = !1;
c.removeClass(a._wrapper,
"in-use");
a._store.set("spVolume", this.step)
}
});
a._player.addEventListener("change:volume", function () {
a._dragging || a.setVolume(parseInt(a._player.volume * 100, 10))
})
};
d.prototype.setVolume = function (a) {
if (isNaN(a) || a < 0 || a > 100) throw Error("Volume must be an integer between 0 and 100");
this._control.jumpToStep(a, !0)
};
i.VolumeControl = d
})(e["$api/models"], e["/scripts/player-utils"], e["/scripts/utils.slider"].Slider)
});
_unrequire("/scripts/player.progressbar", ["$api/models", "/scripts/player-utils", "/scripts/utils.slider"],
function (i) {
(function (f, e, g) {
function d(a, c) {
var d = this;
d._wrapper = document.getElementById(a);
d._eventManager = c;
d._timer = null;
d._updateInterval = 310;
d._control = null;
d._isScrubbing = !1;
d._seekingTo = null;
d._timeMarker = null;
d._timeMarkerCenter = 0;
d._currentTrackUID = -1;
d._maxContainerWidth = null;
d._timeMarkerWidth = null;
b.load(["playing", "track", "position"]).done(function (a) {
d._player = a;
d._currentTrackUID = a.__uid;
d.init()
})
}
var c = e.playerUtils,
b = f.player;
f.Loadable.define(f.Player, ["__uid"], "_playapp");
d.prototype.init = function () {
var a = this;
a.buildNodes();
a._control = new g(a._barOuter, a._scrubber, {
steps: a._player.track ? a._player.track.duration : 100,
onStart: function () {
a._isScrubbing = !0;
c.addClass(a._timeMarker, "active");
c.addClass(a._timeMarkerArrow, "active")
},
onChange: function () {
a._player.track && setTimeout(function () {
a.updateElapsedTime(this.step);
a.setPageTitle(this.step);
var b = this.handle.offsetLeft + this.handle.offsetWidth / 2;
a.moveTimeMarker(b);
a._barInner.style.width = b + "px"
}.bind(this), 1)
},
onComplete: function () {
a._player.seek(this.step);
a._seekingTo = this.step;
a._barInner.style.width = this.handle.offsetLeft + this.handle.offsetWidth / 2 + "px";
a._isScrubbing = !1;
c.removeClass(a._timeMarker, "active");
c.removeClass(a._timeMarkerArrow, "active");
a.pauseTimer(600)
}
});
a._wrapper.addEventListener("mousedown", function (b) {
if (b.target.id.indexOf("widget") !== -1) return !1;
var c = b.offsetX || b.layerX;
return b.target.offsetParent === a._wrapper ? a._control.handleClick(b) : a._control.handleClick(b, c)
}, !1);
a._player.addEventListener("change:track", function () {
a._handleTrackChange()
});
a._player.addEventListener("change", function () {
a._currentTrackUID !== b.__uid && a._handleTrackChange()
});
a._eventManager.subscribe(a._eventManager.Events.TRACK_SKIPPED, function () {
a._handleTrackChange()
});
a._eventManager.subscribe(a._eventManager.Events.BACK_BUTTON_PRESS_START, function () {
a._handleTrackChange()
});
a._player.addEventListener("change:playing", function () {
a._player.playing ? a.runTimer() : a.stopTimer()
});
a.moveTimeMarker(0);
a.runTimer()
};
d.prototype.moveTimeMarker = function (a) {
var b = this,
c = function (a) {
a < b._timeMarkerArrowWidth ? a = b._timeMarkerArrowWidth : a > b._maxContainerWidth - b._timeMarkerArrowWidth - 2 && (a = b._maxContainerWidth - b._timeMarkerArrowWidth - 2);
return a = a - b._timeMarkerArrowWidth / 2 + 1
}(a),
d = a - b._timeMarkerCenter;
d < 2 ? d = 2 : a > b._maxContainerWidth - b._timeMarkerCenter - 2 && (d = b._maxContainerWidth - b._timeMarkerWidth - 2);
b._timeMarkerArrow.style.left = c + "px";
b._timeMarker.style.left = d + "px"
};
d.prototype.setPageTitle = function (a, b) {
var d;
d = (d = this._player.track) ? d.name + " - " + (d.artists && d.artists[0].name) ||
"" : "";
if (this._player.playing || a && b) d = "[" + c.secsToMins((a || this._player.position) / 1E3) + "] " + d;
f.application.setTitle(d)
};
d.prototype.buildNodes = function () {
this._barOuter = document.createElement("div");
this._barOuter.id = "bar-outer";
this._barInner = document.createElement("div");
this._barInner.id = "bar-inner";
this._scrubber = document.createElement("span");
this._scrubber.id = "position";
this._barOuter.appendChild(this._barInner);
this._barOuter.appendChild(this._scrubber);
this._wrapper.appendChild(this._barOuter);
this._timeWrapper = document.createElement("div");
this._timeWrapper.id = "time";
this._trackCurrentPos = document.createElement("span");
this._trackCurrentPos.id = "track-current";
this._trackLength = document.createElement("span");
this._trackLength.id = "track-length";
this._timeMarker = document.createElement("div");
this._timeMarker.id = "time-marker";
this._timeMarkerText = document.createElement("div");
this._timeMarkerText.id = "time-marker-text";
this._timeMarkerArrow = document.createElement("span");
this._timeMarkerArrow.id =
"time-marker-arrow";
this._timeMarker.appendChild(this._timeMarkerText);
this._timeMarkerText.appendChild(this._trackCurrentPos);
this._timeMarkerText.appendChild(this._trackLength);
this._trackLength.textContent = c.secsToMins(0);
this._wrapper.appendChild(this._timeMarker);
this._wrapper.appendChild(this._timeMarkerArrow);
this._wrapper.appendChild(this._timeWrapper);
var a = this;
setTimeout(function () {
a.setupMarkerSizing()
}, 10)
};
d.prototype.setupMarkerSizing = function () {
this._timeMarkerWidth = this._timeMarker.offsetWidth;
this._timeMarkerCenter = this._timeMarkerWidth / 2;
this._timeMarkerArrowWidth = this._timeMarkerArrow.offsetWidth;
this._timeMarkerDefaultPos = this._timeMarkerCenter + this._timeMarkerArrowWidth / 2;
this._maxContainerWidth = this._barOuter.offsetWidth;
this._maxMarkerRightPos = this._maxContainerWidth - this._timeMarkerWidth - 2;
this._maxArrowRightPos = this._maxContainerWidth + this._timeMarkerArrowWidth - this._timeMarkerWidth - 2
};
d.prototype._handleTrackChange = function () {
if (!this._player.track) return this.stopTimer(), !1;
this._trackLength.textContent = c.secsToMins(this._player.track.duration / 1E3);
this.updateElapsedTime(0);
this._seekingTo = null;
this._control.jumpToStep(0, !1);
this._control.setSteps(this._player.track.duration);
this._currentTrackUID = b.__uid || -1;
this.pauseTimer(1E3);
this.setPageTitle(0);
this.setupMarkerSizing()
};
d.prototype.runTimer = function () {
var a = this;
!a._timer && a._player.playing ? a._timer = setInterval(function () {
a._isScrubbing || a.updatePosition()
}.bind(a), a._updateInterval) : a._timer && !a._player.playing && a.stopTimer()
};
d.prototype.stopTimer = function () {
clearInterval(this._timer);
this._timer = null
};
d.prototype.pauseTimer = function (a) {
if (!a) throw Error("You must enter a pause time");
var b = this;
b.stopTimer();
setTimeout(function () {
b.runTimer()
}.bind(b), a)
};
d.prototype.updateElapsedTime = function (a) {
this._trackCurrentPos.textContent = c.secsToMins(a / 1E3)
};
d.prototype.enable = function () {
this._control && this._control.enable()
};
d.prototype.disable = function () {
this._control.disable()
};
d.prototype.reload = function () {
this._control.handleResize();
this.setupMarkerSizing()
};
d.prototype.updatePosition = function () {
if (!this._player || !this._player.track || !this._player.playing || this._isScrubbing) return this.stopTimer(), !1;
var a = this._player.position;
if (a > this._player.track.duration) a = this._player.track.duration;
if (this._seekingTo && Math.abs(this._seekingTo - a) > 1500) return !1;
this._seekingTo = null;
this._control.jumpToStep(a, !1);
this.updateElapsedTime(a);
this.setPageTitle(a)
};
i.ProgressBar = d
})(e["$api/models"], e["/scripts/player-utils"], e["/scripts/utils.slider"].Slider)
});
_unrequire("/scripts/player.tracking", ["$api/models"], function (i) {
(function (f) {
function e() {
this.DEFAULT_DATA = {};
this.DEFAULT_CONTEXT = "player-web";
this.DEFAULT_EVENT_VERSION = "1";
this.DEFAULT_TEST_VERSION = "base"
}
e.prototype.track = function (e, d, c, b, a) {
d = d || this.DEFAULT_DATA;
c = c || this.DEFAULT_CONTEXT;
b = b || this.DEFAULT_EVENT_VERSION;
a = a || this.DEFAULT_TEST_VERSION;
f.application.clientEvent(c, e, b, a, d)
};
i.Tracker = e;
i.Events = {
DOWNLOAD_LINK_CLICKED: "download-link-clicked"
}
})(e["$api/models"])
});
_unrequire("scripts/player",
"$api/models,/scripts/player.events,/scripts/player.suggestions,$views/image,/scripts/player-utils,/scripts/player.widgets,/scripts/player.shufflebutton,/scripts/player.repeatbutton,/scripts/player.playpausebutton,/scripts/player.nextbackbuttons,/scripts/player.volumecontrol,/scripts/player.progressbar,/scripts/player.tracking,$views/contextapp".split(","), function (i) {
(function (f, e, g, d, c, b, a, m, j, K, y, w, x, p) {
var k = c.playerUtils,
R = c.trackHistory,
S = c.kc,
q = document.body.offsetWidth,
h = f.player,
D = f.Track,
z = k.getId,
L = -1,
t = z("track-name"),
E = document.getElementById("widget-more"),
F = new c.Marquee(t, q - 10),
n = new e.EventManager,
G = new b.ArtistWidget(z("track-artist"), q - 10, n),
M = new j("play-pause"),
N = new K.NextButton("next", n),
O = new K.BackButton("previous", n),
T = new a("shuffle"),
U = new m("repeat"),
A = new w("progress", n),
H = z("cover-art"),
r = null,
V = new y("volume"),
l = null,
s = new R(3),
B = z("suggestions"),
u = B.querySelector("ul");
new x.Tracker;
var v = null;
f.Loadable.define(f.Player, ["__length", "__rules", "__index", "__owner",
"__uid"], "_playapp");
var I = function () {
if (l.advertisement) {
if (h.__owner.indexOf("http") !== -1) return window.open(h.__owner), window.parent.postMessage('{"ad_clicked":"' + h.__owner + '"}', "*"), !1;
var a = h.__owner.toSpotifyURI();
a.indexOf("spotify:track") !== -1 ? h.playTrack(D.fromURI(a)) : f.application.openURI(a);
window.parent.postMessage("ad_clicked", "*");
return !1
}
return !0
}, W = function () {
u.innerHTML = "";
document.createDocumentFragment();
if (s.size() === 0) return !1;
g.getTrackSuggestions(s.show("uri"), 3, function (b) {
for (var b = b[0].gids, c = 0; c < 3; c++) D.fromURI("spotify:track:" + b[c]).load("name", "image").done(function (b) {
a(b)
})
}, function () {
s.size() < 3 && s.get(0).album.load(["name", "uri", "image"]).done(function (b) {
a(b)
});
s.forEach(a)
});
var a = function (a) {
var b = document.createElement("li"),
c = a instanceof f.Album;
if (c = a instanceof f.Track ? d.forTrack : c ? d.forAlbum : !1) {
c = c(a, {
animate: !0,
height: 50,
width: 50,
style: "embossed"
});
b.appendChild(c.node);
var e = document.createElement("p"),
g = document.createElement("span");
e.innerHTML = a.name;
a.artists[0].load("name").done(function (c) {
g.innerHTML += c.name.decodeForHtml();
b.appendChild(e);
b.appendChild(g);
b.setAttribute("data-uri", a.uri);
k.addEventSimple(b, "click", function (a) {
a.preventDefault();
f.application.openURI(this.getAttribute("data-uri").replace("spotify:", "spotify:radio:"))
});
u.appendChild(b)
})
}
};
B.appendChild(u);
k.addClass(B, "active");
window.setTimeout(function () {
k.addClass(u, "active")
}, 300)
}, J = function () {
if (!h.track) return !1;
k.removeClass(document.body, "noplayback");
k.removeClass(B,
"active");
k.removeClass(u, "active");
D.fromURI(h.track.uri).load("name,uri,image,duration,artists,starred".split(",")).done(function (a) {
var b = document.createElement("a");
t.innerHTML = "";
b.href = a.uri.toSpotifyURL();
b.innerHTML = a.name.decodeForHtml();
t.appendChild(b);
F.refresh();
!a.advertisement && a.uri.indexOf("spotify:ad") === -1 ? (s.add(a), A.enable(), k.removeClass(document.body, "isannons"), k.removeClass(E, "disabled")) : (A.disable(), k.addClass(E, "disabled"), k.addClass(document.body, "isannons"));
if (!l || l.image !== a.image) r ? (r.setImage(h.track), r.setLink(h.__owner && h.__owner.toSpotifyURI() || "")) : (r = (h.track ? d.forTrack : d.forAlbum)(h.track || l.album, {
animate: !0,
height: 250,
width: 250,
style: "plain",
link: h.__owner && h.__owner.toSpotifyURI() || ""
}), H.appendChild(r.node));
l = a;
n.trigger(n.Events.TRACK_CHANGED, a)
})
}, Q = function () {
var a = h.track;
if (L !== h.__uid) L = h.__uid, J();
P();
if (a === null) {
if (l !== null) W(), H.innerHTML = "", r = null, G.clear(), t.innerHTML = "&nbsp;", l = null, A.setPageTitle(), k.addClass(document.body, "noplayback"), N.disableButton(),
O.disableButton(), M.disableButton();
return !1
}
v && C()
}, P = function () {
var a = h.track;
if (a && (a.advertisement || a.uri.indexOf("spotify:ad") !== -1)) h.volume == 0 ? h.pause() : h.paused && h.play()
}, X = function () {
l.starred ? l.unstar().done(function () {
C()
}) : l.star().done(function () {
C()
}).fail(function () {})
}, C = function () {
v && v.postMessage(JSON.stringify(h), "*")
};
i.init = function () {
h.load("track,__uid,__owner,__rules,position,playing".split(",")).done(function () {
k.addEventSimple(t, "click", function (a) {
a.preventDefault();
a.stopPropagation();
if (a.target.href) {
if (l.advertisement) return I(), !1;
f.application.openURI(h.__owner.toSpotifyURI())
}
});
k.addEventSimple(H, "click", function (a) {
a.preventDefault();
I()
});
Q();
J();
h.addEventListener("change", Q);
h.addEventListener("change:volume", P);
h.addEventListener("change:track", J);
G.init();
F.init();
window.addEventListener("resize", function () {
var a = document.body.offsetWidth;
a !== q && (q = a, V.reload(), A.reload(), F.widthAdjust(q - 10), G.resize(q - 10))
}, !1);
window.addEventListener("message", function (a) {
if (a.source === v) switch (a = JSON.parse(a.data), a.miniplayer) {
case "staterequest":
C();
break;
case "playpause":
M.toggle();
break;
case "next":
N.playerNext();
break;
case "back":
O.playerBack();
break;
case "shuffle":
T.toggle();
break;
case "repeat":
U.toggle();
break;
case "star":
X();
break;
case "seek":
h.seek(a.target);
break;
case "volume":
h.setVolume(a.target);
break;
case "openuri":
f.application.openURI(a.target)
}
}, !1);
n.subscribe(n.Events.AD_CLICKED, I);
E.addEventListener("click", function (a) {
a.preventDefault();
l && !k.hasClass(this,
"disabled") && p.show("context-actions", [l.uri], a.target, "spotify:temp-playlist:hellothere")
}, !1);
var a = new S;
a.onSuccess = function () {
v = window.open("vendor/mini/mini.html", "Spotify", "menubar=no,location=no,resizable=no,scrollbars=no,status=no,width=420,height=150")
};
a.init()
})
}
})(e["$api/models"], e["/scripts/player.events"], e["/scripts/player.suggestions"], e["$views/image"].Image, e["/scripts/player-utils"], e["/scripts/player.widgets"], e["/scripts/player.shufflebutton"].ShuffleButton, e["/scripts/player.repeatbutton"].RepeatButton,
e["/scripts/player.playpausebutton"].PlayPauseButton, e["/scripts/player.nextbackbuttons"], e["/scripts/player.volumecontrol"].VolumeControl, e["/scripts/player.progressbar"].ProgressBar, e["/scripts/player.tracking"], e["$views/contextapp"].ContextApp)
});
_unrequire("main", ["scripts/player"], function () {
e["scripts/player"].init()
})
})(SpotifyApi.api, SpotifyApi.api._modules);
<!-- https://play.spotify.edgekey.net/client/c46d547/proto/data.xml -->
<!-- 2013-06-18 -->
<?xml version="1.0" encoding="UTF-8"?>
<services>
<search><![CDATA[
message SearchRequest {
enum Type {
TRACK = 0;
ALBUM = 1;
ARTIST = 2;
PLAYLIST = 3;
USER = 4;
}
optional string query = 1;
optional Type type = 2;
optional int32 limit = 3;
optional int32 offset = 4;
optional bool did_you_mean = 5
}
message Image {
optional Size size = 1;
optional string spotify_uri = 2;
repeated bytes file_id = 3;
optional string url = 4;
optional string slask_id = 5;
}
message Playlist {
optional string uri = 1;
optional string name = 2;
repeated Image image = 3;
}
message User {
optional string username = 1;
optional string full_name = 2;
repeated Image image = 3;
optional sint32 followers = 4;
}
message SearchReply {
optional sint32 hits = 1;
repeated Track track = 2;
repeated Album album = 3;
repeated Artist artist = 4;
repeated Playlist playlist = 5;
optional string did_you_mean = 6;
repeated User user = 7;
}
]]>
</search>
<suggest><![CDATA[
message Track {
optional bytes gid = 1;
optional string name = 2;
optional bytes image = 3;
repeated string artist_name = 4;
repeated bytes artist_gid = 5;
optional uint32 rank = 6;
}
message Artist {
optional bytes gid = 1;
optional string name = 2;
optional bytes image = 3;
optional uint32 rank = 6;
}
message Album {
optional bytes gid = 1;
optional string name = 2;
optional bytes image = 3;
repeated string artist_name = 4;
repeated bytes artist_gid = 5;
optional uint32 rank = 6;
}
message Playlist {
optional string uri = 1;
optional string name = 2;
optional string image_uri = 3;
optional string owner_name = 4;
optional string owner_uri = 5;
optional uint32 rank = 6;
}
message Suggestions {
repeated Track track = 1;
repeated Album album = 2;
repeated Artist artist = 3;
repeated Playlist playlist = 4;
}
]]>
</suggest>
<appstore><![CDATA[
package spotify.appstore.proto;
message AppInfo {
required string app_name = 1;
required int32 original_bundle_version = 2;
}
message AppInfoList {
repeated AppInfo items = 1;
}
message RequestHeader {
enum Platform {
WIN32_X86 = 0;
OSX_X86 = 1;
LINUX_X86 = 2;
IPHONE_ARM = 3;
SYMBIANS60_ARM = 4;
OSX_POWERPC = 5;
ANDROID_ARM = 6;
WINCE_ARM = 7;
LINUX_X86_64 = 8;
OSX_X86_64 = 9;
PALM_ARM = 10;
LINUX_SH = 11;
FREEBSD_X86 = 12;
FREEBSD_X86_64 = 13;
BLACKBERRY_ARM = 14;
SONOS_UNKNOWN = 15;
LINUX_MIPS = 16;
LINUX_ARM = 17;
LOGITECH_ARM = 18;
LINUX_BLACKFIN = 19;
ONKYO_ARM = 21;
QNXNTO_ARM = 22;
BADPLATFORM = 255;
}
enum Priority {
PRIORITY_DEFAULT = 0;
PRIORITY_POLLING = 1;
}
optional string market = 1;
optional Platform platform = 2;
optional Priority priority = 3;
optional int32 client_api_version_low = 4;
optional int32 client_api_version_high = 5;
optional AppInfoList app_infos = 6;
}
message AppItem {
enum Requirement {
REQUIRED_INSTALL = 1;
LAZYLOAD = 2;
OPTIONAL_INSTALL = 3;
}
optional string app_name = 1;
optional Requirement requirement = 2;
optional int32 status = 3;
optional string manifest = 4;
optional string checksum = 5;
optional string bundle_uri = 6;
optional string small_icon_uri = 7;
optional string large_icon_uri = 8;
optional string medium_icon_uri = 9;
optional IdentifierList categories = 10;
}
message AppList {
repeated AppItem items = 1;
}
message IdentifierList {
repeated string identifiers = 1;
}
]]>
</appstore>
<metadata><![CDATA[
package spotify.metadata.proto;
option optimize_for = SPEED;
option java_package = "com.spotify.metadata.proto";
option java_outer_classname = "Metadata";
message TopTracks {
optional string country = 1;
repeated Track track = 2;
}
message ActivityPeriod {
optional sint32 start_year = 1;
optional sint32 end_year = 2;
optional sint32 decade = 3;
}
message Artist {
optional bytes gid = 1;
optional string name = 2;
optional sint32 popularity = 3;
repeated TopTracks top_track = 4;
repeated AlbumGroup album_group = 5;
repeated AlbumGroup single_group = 6;
repeated AlbumGroup compilation_group = 7;
repeated AlbumGroup appears_on_group = 8;
repeated string genre = 9;
repeated ExternalId external_id = 10;
repeated Image portrait = 11;
repeated Biography biography = 12;
repeated ActivityPeriod activity_period = 13;
repeated Restriction restriction = 14;
repeated Artist related = 15;
optional bool is_portrait_album_cover = 16;
optional ImageGroup portrait_group = 17;
}
message AlbumGroup {
repeated Album album = 1;
}
message Date {
optional sint32 year = 1;
optional sint32 month = 2;
optional sint32 day = 3;
}
message Album {
enum Type {
ALBUM = 1;
SINGLE = 2;
COMPILATION = 3;
}
optional bytes gid = 1;
optional string name = 2;
repeated Artist artist = 3;
optional Type type = 4;
optional string label = 5;
optional Date date = 6;
optional sint32 popularity = 7;
repeated string genre = 8;
repeated Image cover = 9;
repeated ExternalId external_id = 10;
repeated Disc disc = 11;
repeated string review = 12;
repeated Copyright copyright = 13;
repeated Restriction restriction = 14;
repeated Album related = 15;
repeated SalePeriod sale_period = 16;
optional ImageGroup cover_group = 17;
}
message Track {
optional bytes gid = 1;
optional string name = 2;
optional Album album = 3;
repeated Artist artist = 4;
optional sint32 number = 5;
optional sint32 disc_number = 6;
optional sint32 duration = 7;
optional sint32 popularity = 8;
optional bool explicit = 9;
repeated ExternalId external_id = 10;
repeated Restriction restriction = 11;
repeated AudioFile file = 12;
repeated Track alternative = 13;
repeated SalePeriod sale_period = 14;
repeated AudioFile preview = 15;
}
message Image {
enum Size {
DEFAULT = 0;
SMALL = 1;
LARGE = 2;
XLARGE = 3;
}
optional bytes file_id = 1;
optional Size size = 2;
optional sint32 width = 3;
optional sint32 height = 4;
}
message ImageGroup {
repeated Image image = 1;
}
message Biography {
optional string text = 1;
repeated Image portrait = 2;
repeated ImageGroup portrait_group = 3;
}
message Disc {
optional sint32 number = 1;
optional string name = 2;
repeated Track track = 3;
}
message Copyright {
enum Type {
P = 0;
C = 1;
}
optional Type type = 1;
optional string text = 2;
}
message Restriction {
enum Catalogue {
AD = 0;
SUBSCRIPTION = 1;
}
enum Type {
STREAMING = 0;
}
repeated Catalogue catalogue = 1;
optional string countries_allowed = 2;
optional string countries_forbidden = 3;
optional Type type = 4;
}
message SalePeriod {
repeated Restriction restriction = 1;
optional Date start = 2;
optional Date end = 3;
}
message ExternalId {
optional string type = 1;
optional string id = 2;
}
message AudioFile {
enum Format {
OGG_VORBIS_96 = 0;
OGG_VORBIS_160 = 1;
OGG_VORBIS_320 = 2;
MP3_256 = 3;
MP3_320 = 4;
MP3_160 = 5;
MP3_96 = 6;
}
optional bytes file_id = 1;
optional Format format = 2;
}
]]>
</metadata>
<mercury><![CDATA[
package spotify.mercury.proto;
message MercuryMultiGetRequest {
repeated MercuryRequest request = 1;
}
message MercuryMultiGetReply {
repeated MercuryReply reply = 1;
}
message MercuryRequest {
optional string uri = 1;
optional string content_type = 2;
optional bytes body = 3;
optional bytes etag = 4;
}
message MercuryReply {
enum CachePolicy {
CACHE_NO = 1;
CACHE_PRIVATE = 2;
CACHE_PUBLIC = 3;
}
optional sint32 status_code = 1;
optional string status_message = 2;
optional CachePolicy cache_policy = 3;
optional sint32 ttl = 4;
optional bytes etag = 5;
optional string content_type = 6;
optional bytes body = 7;
}
]]>
</mercury>
<toplist><![CDATA[
message Toplist {
repeated string items = 1;
}
]]>
</toplist>
<social><![CDATA[
message DecorationData {
optional string username = 1;
optional string full_name = 2;
optional string image_url = 3;
optional string large_image_url = 5;
optional string first_name = 6;
optional string last_name = 7;
optional string facebook_uid = 8;
}
]]>
</social>
<playlist4changes><![CDATA[
package spotify.playlist4.proto;
option optimize_for = SPEED;
option java_package = "com.spotify.playlist4.proto";
message ChangeInfo {
optional string user = 1;
optional int32 timestamp = 2;
optional bool admin = 3;
optional bool undo = 4;
optional bool redo = 5;
optional bool merge = 6;
optional bool compressed = 7;
optional bool migration = 8;
}
message Delta {
optional bytes base_version = 1;
repeated Op ops = 2;
optional ChangeInfo info = 4;
}
message Merge {
optional bytes base_version = 1;
optional bytes merge_version = 2;
optional ChangeInfo info = 4;
}
message ChangeSet {
enum Kind {
KIND_UNKNOWN = 0;
DELTA = 2;
MERGE = 3;
};
required Kind kind = 1;
optional Delta delta = 2;
optional Merge merge = 3;
}
message RevisionTaggedChangeSet {
required bytes revision = 1;
required ChangeSet change_set = 2;
}
message Diff {
required bytes from_revision = 1;
repeated Op ops = 2;
required bytes to_revision = 3;
}
message ListDump {
optional bytes latestRevision = 1;
optional int32 length = 2;
optional ListAttributes attributes = 3;
optional ListChecksum checksum = 4;
optional ListItems contents = 5;
repeated Delta pendingDeltas = 7;
}
message ListChanges {
optional bytes baseRevision = 1;
repeated Delta deltas = 2;
optional bool wantResultingRevisions = 3;
optional bool wantSyncResult = 4;
optional ListDump dump = 5;
repeated int32 nonces = 6;
}
message SelectedListContent {
optional bytes revision = 1;
optional int32 length = 2;
optional ListAttributes attributes = 3;
optional ListChecksum checksum = 4;
optional ListItems contents = 5;
optional Diff diff = 6;
optional Diff syncResult = 7;
repeated bytes resultingRevisions = 8;
optional bool multipleHeads = 9;
optional bool upToDate = 10;
repeated ClientResolveAction resolveAction = 12;
repeated ClientIssue issues = 13;
repeated int32 nonces = 14;
}
]]>
</playlist4changes>
<playlist4content><![CDATA[
package spotify.playlist4.proto;
option optimize_for = SPEED;
option java_package = "com.spotify.playlist4.proto";
message Item {
required string uri = 1;
optional ItemAttributes attributes = 2;
}
message ListItems {
required int32 pos = 1;
required bool truncated = 2;
repeated Item items = 3;
}
message ContentRange {
required int32 pos = 1;
optional int32 length = 2;
}
message ListContentSelection {
optional bool wantRevision = 1;
optional bool wantLength = 2;
optional bool wantAttributes = 3;
optional bool wantChecksum = 4;
optional bool wantContent = 5;
optional ContentRange contentRange = 6;
optional bool wantDiff = 7;
optional bytes baseRevision = 8;
optional bytes hintRevision = 9;
optional bool wantNothingIfUpToDate = 10;
optional bool wantResolveAction = 12;
repeated ClientIssue issues = 13;
repeated ClientResolveAction resolveAction = 14;
}
]]>
</playlist4content>
<playlist4issues><![CDATA[
package spotify.playlist4.proto;
option optimize_for = SPEED;
option java_package = "com.spotify.playlist4.proto";
message ClientIssue {
enum Level {
LEVEL_UNKNOWN = 0;
LEVEL_DEBUG = 1;
LEVEL_INFO = 2;
LEVEL_NOTICE = 3;
LEVEL_WARNING = 4;
LEVEL_ERROR = 5;
}
enum Code {
CODE_UNKNOWN = 0;
CODE_INDEX_OUT_OF_BOUNDS = 1;
CODE_VERSION_MISMATCH = 2;
CODE_CACHED_CHANGE = 3;
CODE_OFFLINE_CHANGE = 4;
CODE_CONCURRENT_CHANGE = 5;
}
optional Level level = 1;
optional Code code = 2;
optional int32 repeatCount = 3;
}
message ClientResolveAction {
enum Code {
CODE_UNKNOWN = 0;
CODE_NO_ACTION = 1;
CODE_RETRY = 2;
CODE_RELOAD = 3;
CODE_DISCARD_LOCAL_CHANGES = 4;
CODE_SEND_DUMP = 5;
CODE_DISPLAY_ERROR_MESSAGE = 6;
}
enum Initiator {
INITIATOR_UNKNOWN = 0;
INITIATOR_SERVER = 1;
INITIATOR_CLIENT = 2;
}
optional Code code = 1;
optional Initiator initiator = 2;
}
]]>
</playlist4issues>
<playlist4meta><![CDATA[
package spotify.playlist4.proto;
option optimize_for = SPEED;
option java_package = "com.spotify.playlist4.proto";
message ListChecksum {
required int32 version = 1;
optional bytes sha1 = 4;
}
message DownloadFormat {
enum Codec {
CODEC_UNKNOWN = 0;
OGG_VORBIS = 1;
FLAC = 2;
MPEG_1_LAYER_3 = 3;
}
required Codec codec = 1;
}
enum ListAttributeKind {
LIST_UNKNOWN = 0;
LIST_NAME = 1;
LIST_DESCRIPTION = 2;
LIST_PICTURE = 3;
LIST_COLLABORATIVE = 4;
LIST_PL3_VERSION = 5;
LIST_DELETED_BY_OWNER = 6;
LIST_RESTRICTED_COLLABORATIVE = 7;
}
message ListAttributes {
optional string name = 1;
optional string description = 2;
optional bytes picture = 3;
optional bool collaborative = 4;
optional string pl3_version = 5;
optional bool deleted_by_owner = 6;
optional bool restricted_collaborative = 7;
}
enum ItemAttributeKind {
ITEM_UNKNOWN = 0;
ITEM_ADDED_BY = 1;
ITEM_TIMESTAMP = 2;
ITEM_MESSAGE = 3;
ITEM_SEEN = 4;
ITEM_DOWNLOAD_COUNT = 5;
ITEM_DOWNLOAD_FORMAT = 6;
ITEM_SEVENDIGITAL_ID = 7;
ITEM_SEVENDIGITAL_LEFT = 8;
ITEM_SEEN_AT = 9;
}
message ItemAttributes {
optional string added_by = 1;
optional int64 timestamp = 2;
optional string message = 3;
optional bool seen = 4;
optional int64 download_count = 5;
optional DownloadFormat download_format = 6;
optional string sevendigital_id = 7;
optional int64 sevendigital_left = 8;
optional int64 seen_at = 9;
}
message StringAttribute {
required string key = 1;
required string value = 2;
}
message StringAttributes {
repeated StringAttribute attribute = 1;
}
]]>
</playlist4meta>
<playlist4ops><![CDATA[
package spotify.playlist4.proto;
option optimize_for = SPEED;
option java_package = "com.spotify.playlist4.proto";
message Add {
optional int32 fromIndex = 1;
repeated Item items = 2;
optional ListChecksum list_checksum = 3;
optional bool addLast = 4;
optional bool addFirst = 5;
}
message Rem {
optional int32 fromIndex = 1;
optional int32 length = 2;
repeated Item items = 3;
optional ListChecksum list_checksum = 4;
optional ListChecksum items_checksum = 5;
optional ListChecksum uris_checksum = 6;
optional bool itemsAsKey = 7;
}
message Mov {
required int32 fromIndex = 1;
required int32 length = 2;
required int32 toIndex = 3;
optional ListChecksum list_checksum = 4;
optional ListChecksum items_checksum = 5;
optional ListChecksum uris_checksum = 6;
}
message ItemAttributesPartialState {
required ItemAttributes values = 1;
repeated ItemAttributeKind no_value = 2;
}
message ListAttributesPartialState {
required ListAttributes values = 1;
repeated ListAttributeKind no_value = 2;
}
message UpdateItemAttributes {
required int32 index = 1;
required ItemAttributesPartialState new_attributes = 2;
optional ItemAttributesPartialState old_attributes = 3;
optional ListChecksum list_checksum = 4;
optional ListChecksum old_attributes_checksum = 5;
}
message UpdateListAttributes {
required ListAttributesPartialState new_attributes = 1;
optional ListAttributesPartialState old_attributes = 2;
optional ListChecksum list_checksum = 3;
optional ListChecksum old_attributes_checksum = 4;
}
message Op {
enum Kind {
KIND_UNKNOWN = 0;
ADD = 2;
REM = 3;
MOV = 4;
UPDATE_ITEM_ATTRIBUTES = 5;
UPDATE_LIST_ATTRIBUTES = 6;
};
required Kind kind = 1;
optional Add add = 2;
optional Rem rem = 3;
optional Mov mov = 4;
optional UpdateItemAttributes update_item_attributes = 5;
optional UpdateListAttributes update_list_attributes = 6;
}
message OpList {
repeated Op ops = 1;
}
]]>
</playlist4ops>
<playlist4service><![CDATA[
package spotify.playlist4.proto;
option optimize_for = SPEED;
message RequestContext {
optional bool administrative = 2;
optional bool migration = 4;
optional string tag = 7;
optional bool useStarredView = 8;
optional bool syncWithPublished = 9;
}
message GetCurrentRevisionArgs {
optional bytes uri = 1;
optional RequestContext context = 2;
}
message GetChangesInSequenceRangeArgs {
optional bytes uri = 1;
optional RequestContext context = 2;
optional int32 fromSequenceNumber = 3;
optional int32 toSequenceNumber = 4;
}
message GetChangesInSequenceRangeMatchingPl3VersionArgs {
optional bytes uri = 1;
optional RequestContext context = 2;
optional int32 fromSequenceNumber = 3;
optional int32 toSequenceNumber = 4;
optional string pl3Version = 5;
}
message GetChangesInSequenceRangeReturn {
repeated RevisionTaggedChangeSet result = 1;
}
message ObliterateListArgs {
optional bytes uri = 1;
optional RequestContext context = 2;
}
message UpdatePublishedArgs {
optional bytes publishedUri = 1;
optional RequestContext context = 2;
optional bytes uri = 3;
optional bool isPublished = 4;
}
message SynchronizeArgs {
optional bytes uri = 1;
optional RequestContext context = 2;
optional ListContentSelection selection = 3;
optional ListChanges changes = 4;
}
message GetSnapshotAtRevisionArgs {
optional bytes uri = 1;
optional RequestContext context = 2;
optional bytes revision = 3;
}
message SubscribeRequest {
repeated bytes uris = 1;
}
message UnsubscribeRequest {
repeated bytes uris = 1;
}
enum Playlist4InboxErrorKind {
INBOX_NOT_ALLOWED = 2;
INBOX_INVALID_USER = 3;
INBOX_INVALID_URI = 4;
INBOX_LIST_TOO_LONG = 5;
}
message Playlist4ServiceException {
optional string why = 1;
optional string symbol = 2;
optional bool permanent = 3;
optional string serviceErrorClass = 4;
optional Playlist4InboxErrorKind inboxErrorKind = 5;
}
message SynchronizeReturn {
optional SelectedListContent result = 1;
optional Playlist4ServiceException exception = 4;
}
enum Playlist4ServiceMethodKind {
METHOD_UNKNOWN = 0;
METHOD_GET_CURRENT_REVISION = 2;
METHOD_GET_CHANGES_IN_SEQUENCE_RANGE = 3;
METHOD_OBLITERATE_LIST = 4;
METHOD_SYNCHRONIZE = 5;
METHOD_UPDATE_PUBLISHED = 6;
METHOD_GET_CHANGES_IN_SEQUENCE_RANGE_MATCHING_PL3_VERSION = 7;
METHOD_GET_SNAPSHOT_AT_REVISION = 8;
}
message Playlist4ServiceCall {
optional Playlist4ServiceMethodKind kind = 1;
optional GetCurrentRevisionArgs getCurrentRevisionArgs = 2;
optional GetChangesInSequenceRangeArgs getChangesInSequenceRangeArgs = 3;
optional ObliterateListArgs obliterateListArgs = 4;
optional SynchronizeArgs synchronizeArgs = 5;
optional UpdatePublishedArgs updatePublishedArgs = 6;
optional GetChangesInSequenceRangeMatchingPl3VersionArgs getChangesInSequenceRangeMatchingPl3VersionArgs = 7;
optional GetSnapshotAtRevisionArgs getSnapshotAtRevisionArgs = 8;
}
message Playlist4ServiceReturn {
optional Playlist4ServiceMethodKind kind = 1;
optional Playlist4ServiceException exception = 2;
optional bytes getCurrentRevisionReturn = 3;
optional GetChangesInSequenceRangeReturn getChangesInSequenceRangeReturn = 4;
optional bool obliterateListReturn = 5;
optional SynchronizeReturn synchronizeReturn = 6;
optional bool updatePublishedReturn = 7;
optional GetChangesInSequenceRangeReturn getChangesInSequenceRangeMatchingPl3VersionReturn = 8;
optional RevisionTaggedListSnapshot getSnapshotAtRevisionReturn = 9;
}
message CreateListReply {
required bytes uri = 1;
optional bytes revision = 2;
}
message ModifyReply {
required bytes uri = 1;
optional bytes revision = 2;
}
message PlaylistModificationInfo {
optional bytes uri = 1;
optional bytes new_revision = 2;
}
]]>
</playlist4service>
<spirc><![CDATA[
package spotify.spirc.proto;
enum MessageType {
kMessageTypeHello = 1;
kMessageTypeGoodbye = 2;
kMessageTypeNotify = 10;
kMessageTypeLoad = 20;
kMessageTypePlay = 21;
kMessageTypePause = 22;
kMessageTypePlayPause = 23;
kMessageTypeSeek = 24;
kMessageTypePrev = 25;
kMessageTypeNext = 26;
kMessageTypeVolume = 27;
kMessageTypeShuffle = 28;
kMessageTypeRepeat = 29;
kMessageTypeQueue = 30;
kMessageTypeVolumeDown = 31;
kMessageTypeVolumeUp = 32;
}
enum PlayStatus {
kPlayStatusStop = 0;
kPlayStatusPlay = 1;
kPlayStatusPause = 2;
kPlayStatusLoading = 3;
kPlayStatusError = 4;
}
message Goodbye {
optional string reason = 1;
}
message State {
optional string trackURI = 1;
optional string contextURI = 2;
optional uint32 index = 3;
optional uint32 position = 4;
optional PlayStatus status = 5;
optional uint32 errorCode = 6;
optional uint32 volume = 8;
optional uint32 duration = 9;
repeated string history = 10;
repeated string queued = 11;
repeated string future = 12;
optional bool shuffle = 13;
optional bool repeat = 14;
optional uint32 volumeCaps = 15;
}
message Frame {
optional uint32 version = 1;
optional string ident = 2;
optional string name = 3;
optional uint32 msgid = 4;
optional MessageType type = 5;
optional Goodbye goodbye = 11;
optional State state = 12;
optional uint32 position = 13;
optional uint32 volume = 14;
repeated string toQueue = 15;
}
message VoidReply {
}
]]>
</spirc>
<pubsub><![CDATA[
package spotify.hermes.pubsub.proto;
message Subscription {
optional string uri = 1;
optional int32 expiry = 2;
optional int32 status_code = 3;
}
]]>
</pubsub>
<popcount><![CDATA[
package spotify.popcount2.proto;
message PopcountRequest {
}
message PopcountResult {
optional sint64 count = 1;
optional bool truncated = 2;
repeated string user = 3;
repeated sint64 subscriptionTimestamps = 4;
repeated sint64 insertionTimestamps = 5;
}
]]>
</popcount>
<presence><![CDATA[
package spotify.presence.proto;
message PlaylistPublishedState {
optional string uri = 1;
optional int64 timestamp = 2;
}
message PlaylistTrackAddedState {
optional string playlist_uri = 1;
optional string track_uri = 2;
optional int64 timestamp = 3;
}
message TrackFinishedPlayingState {
optional string uri = 1;
optional string context_uri = 2;
optional int64 timestamp = 3;
optional string referrer_uri = 4;
}
message FavoriteAppAddedState {
optional string app_uri = 1;
optional int64 timestamp = 2;
}
message TrackStartedPlayingState {
optional string uri = 1;
optional string context_uri = 2;
optional int64 timestamp = 3;
optional string referrer_uri = 4;
}
message UriSharedState {
optional string uri = 1;
optional string message = 2 [default=""];
optional int64 timestamp = 3;
}
message ArtistFollowedState {
optional string uri = 1;
optional string artist_name = 2 [default=""];
optional string artist_cover_uri = 3 [default=""];
optional int64 timestamp = 4;
}
message DeviceInformation {
optional string os = 1;
optional string type = 2;
}
message GenericPresenceState {
optional int32 type = 1;
optional int64 timestamp = 2;
optional string item_uri = 3;
optional string item_name = 4;
optional string item_image = 5;
optional string context_uri = 6;
optional string context_name = 7;
optional string context_image = 8;
optional string referrer_uri = 9;
optional string referrer_name = 10;
optional string referrer_image = 11;
optional string message = 12;
optional DeviceInformation device_information = 13;
}
message State {
optional int64 timestamp = 1;
enum Type {
PLAYLIST_PUBLISHED = 1;
PLAYLIST_TRACK_ADDED = 2;
TRACK_FINISHED_PLAYING = 3;
FAVORITE_APP_ADDED = 4;
TRACK_STARTED_PLAYING = 5;
URI_SHARED = 6;
ARTIST_FOLLOWED = 7;
GENERIC = 11;
}
optional Type type = 2;
optional string uri = 3;
optional PlaylistPublishedState playlist_published = 4;
optional PlaylistTrackAddedState playlist_track_added = 5;
optional TrackFinishedPlayingState track_finished_playing = 6;
optional FavoriteAppAddedState favorite_app_added = 7;
optional TrackStartedPlayingState track_started_playing = 8;
optional UriSharedState uri_shared = 9;
optional ArtistFollowedState artist_followed = 10;
optional GenericPresenceState generic = 11;
}
message StateList {
repeated State states = 1;
}
]]>
</presence>
<socialgraph><![CDATA[
package spotify.socialgraph.proto;
message CountReply {
repeated int32 counts = 1;
}
message UserListRequest {
optional string last_result = 1;
optional int32 count = 2;
optional bool include_length = 3;
}
message UserListReply {
repeated User users = 1;
optional int32 length = 2;
}
message User {
optional string username = 1;
optional int32 subscriber_count = 2;
optional int32 subscription_count = 3;
}
message ArtistListReply {
repeated Artist artists = 1;
}
message Artist {
optional string artistid = 1;
optional int32 subscriber_count = 2;
}
message StringListRequest {
repeated string args = 1;
}
message StringListReply {
repeated string reply = 1;
}
message TopPlaylistsRequest {
optional string username = 1;
optional int32 count = 2;
}
message TopPlaylistsReply {
repeated string uris = 1;
}
]]>
</socialgraph>
<facebook><![CDATA[
message Credential {
optional string facebook_uid = 1;
optional string access_token = 2;
}
message EnableRequest {
optional Credential credential = 1;
}
message EnableReply {
optional Credential credential = 1;
}
message DisableRequest {
optional Credential credential = 1;
}
message RevokeRequest {
optional Credential credential = 1;
}
message InspectCredentialRequest {
optional Credential credential = 1;
}
message InspectCredentialReply {
optional Credential alternative_credential = 1;
optional bool app_user = 2;
optional bool permanent_error = 3;
optional bool transient_error = 4;
}
message UserState {
optional Credential credential = 1;
}
message UpdateUserStateRequest {
optional Credential credential = 1;
}
message OpenGraphError {
repeated string permanent = 1;
repeated string invalid_token = 2;
repeated string retries = 3;
}
message OpenGraphScrobble {
optional int32 create_delay = 1;
}
message OpenGraphConfig {
optional OpenGraphError error = 1;
optional OpenGraphScrobble scrobble = 2;
}
message AuthConfig {
optional string url = 1;
repeated string permissions = 2;
repeated string blacklist = 3;
repeated string whitelist = 4;
repeated string cancel = 5;
}
message ConfigReply {
optional string domain = 1 [default = 'facebook.com'];
optional string app_id = 2 [default = '174829003346'];
optional string app_namespace = 3 [default = 'get-spotify'];
optional AuthConfig auth = 4;
optional OpenGraphConfig og = 5;
}
message UserFields {
optional bool app_user = 1;
optional bool display_name = 2;
optional bool first_name = 3;
optional bool middle_name = 4;
optional bool last_name = 5;
optional bool picture_large = 6;
optional bool picture_square = 7;
optional bool gender = 8;
optional bool email = 9;
}
message UserOptions {
optional bool cache_is_king = 1 [default = true];
}
message UserRequest {
optional UserOptions options = 1;
optional UserFields fields = 2;
}
message User {
optional string spotify_username = 1;
optional string facebook_uid = 2;
optional bool app_user = 3;
optional string display_name = 4;
optional string first_name = 5;
optional string middle_name = 6;
optional string last_name = 7;
optional string picture_large = 8;
optional string picture_square = 9;
optional string gender = 10;
optional string email = 11;
}
message FriendsFields {
optional bool app_user = 1;
optional bool display_name = 2;
optional bool picture_large = 6;
}
message FriendsOptions {
optional int32 limit = 1;
optional int32 offset = 2;
optional bool cache_is_king = 3 [default = true];
optional bool app_friends = 4 [default = true];
optional bool non_app_friends = 5 [default = true];
}
message FriendsRequest {
optional FriendsOptions options = 1;
optional FriendsFields fields = 2;
}
message FriendsReply {
repeated User friends = 1;
optional bool more = 2;
}
message ShareRequest {
optional Credential credential = 1;
optional string uri = 2;
optional string message_text = 3;
}
message ShareReply {
optional string post_id = 1;
}
message InboxRequest {
optional Credential credential = 1;
repeated string facebook_uids = 3;
optional string message_text = 4;
optional string message_link = 5;
}
message InboxReply {
optional string message_id = 1;
optional string thread_id = 2;
}
message PermissionsOptions {
optional bool cache_is_king = 1 [default = true];
}
message PermissionsRequest {
optional Credential credential = 1;
optional PermissionsOptions options = 2;
}
message PermissionsReply {
repeated string permissions = 1;
}
message GrantPermissionsRequest {
optional Credential credential = 1;
repeated string permissions = 2;
}
message GrantPermissionsReply {
repeated string granted = 1;
repeated string failed = 2;
}
message TransferRequest {
optional Credential credential = 1;
optional string source_username = 2;
optional string target_username = 3;
}
]]>
</facebook>
<collection2><![CDATA[
package spotify.collection2.proto;
option java_package = "com.spotify.collection2.proto";
message CollectionItem {
enum Type {
TRACK = 0;
ALBUM = 1;
LOCAL_TRACK = 2;
}
optional Type type = 1;
optional bytes identifier = 2;
optional int32 starred_at = 3;
optional bool unheard = 4;
optional int32 added_at = 5;
optional bool removed = 6;
}
message CollectionItems {
repeated CollectionItem item = 1;
}
]]>
</collection2>
<collection2cache><![CDATA[
package spotify.collection2cache.proto;
option java_package = "com.spotify.collection2cache.proto";
message PlaylistOccurrence {
optional bytes identifier = 1;
optional bytes revision = 2;
optional int32 count = 3 [default = 1];
}
message CollectionTrack {
optional bytes identifier = 1;
optional string name = 2;
optional bool in_collection = 3;
repeated PlaylistOccurrence playlists = 4;
optional int32 added_at = 5;
}
message CollectionAlbum {
optional bytes identifier = 1;
optional int32 track_count = 2;
optional string name = 3;
repeated string artist_names = 4;
}
message CollectionArtist {
optional bytes identifier = 1;
optional int32 track_count = 2;
optional string name = 3;
}
message CollectionTracks {
repeated CollectionTrack track = 1;
}
message CollectionAlbums {
repeated CollectionAlbum album = 1;
}
message CollectionArtists {
repeated CollectionArtist artist = 1;
}
]]>
</collection2cache>
<radio><![CDATA[
package spotify.radio.proto;
message RadioRequest {
repeated string uris = 1;
optional int32 salt = 2;
optional int32 length = 4;
optional string stationId = 5;
repeated string lastTracks = 6;
}
message MultiSeedRequest {
repeated string uris = 1;
}
message Feedback {
optional string uri = 1;
optional string type = 2;
optional double timestamp = 3;
}
message Tracks {
repeated string gids = 1;
optional string source = 2;
optional string identity = 3;
repeated string tokens = 4;
repeated Feedback feedback = 5;
}
message Station {
optional string id = 1;
optional string title = 2;
optional string titleUri = 3;
optional string subtitle = 4;
optional string subtitleUri = 5;
optional string imageUri = 6;
optional double lastListen = 7;
repeated string seeds = 8;
optional int32 thumbsUp = 9;
optional int32 thumbsDown = 10;
}
message Rules {
optional string js = 1;
}
message StationResponse {
optional Station station = 1;
repeated Feedback feedback = 2;
}
message StationList {
repeated Station stations = 1;
}
message LikedPlaylist {
optional string uri = 1;
}
]]>
</radio>
<mergedprofile><![CDATA[
message MergedProfileRequest {
}
message MergedProfileReply {
optional string username = 1;
optional string artistid = 2;
}
]]>
</mergedprofile>
<facebook-publish><![CDATA[
message EventReply {
optional int32 queued = 1;
optional RetryInfo retry = 2;
}
message RetryInfo {
optional int32 retry_delay = 1;
optional int32 max_retry = 2;
}
message Id {
optional string uri = 1;
optional int64 start_time = 2;
}
message Start {
optional int32 length = 1;
optional string context_uri = 2;
optional int64 end_time = 3;
}
message Seek {
optional int64 end_time = 1;
}
message Pause {
optional int32 seconds_played = 1;
optional int64 end_time = 2;
}
message Resume {
optional int32 seconds_played = 1;
optional int64 end_time = 2;
}
message End {
optional int32 seconds_played = 1;
optional int64 end_time = 2;
}
message Event {
optional Id id = 1;
optional Start start = 2;
optional Seek seek = 3;
optional Pause pause = 4;
optional Resume resume = 5;
optional End end = 6;
}
]]>
</facebook-publish>
</services>
/*
* https://spapps.spotify.edgekey.net/radio/692f491/scripts/main.js
*
* 15/12/2012
*/
(function (B, r) {
_unrequire("scripts/imageCarousel", [], function (l) {
l.ImageCarousel = function (l, e, n, j) {
function i() {
d.setStyle("width", g * (k + 2 * h) + "px")
}
var k = 120,
h = 12,
c = 4,
a = null,
d = null,
g = 0,
f = 0,
b = this;
this.addItem = function (b, a, f, e, w, z) {
var u = document.createElement("li"),
p = document.createElement("a");
B.defer(this, function () {
j.loadImgAsync(p, a, b, 120, z);
p.addClass("image-cover");
p.addClass(z);
p.addClass(w);
p.href = b.replace("spotify:", "spotify:radio:").decodeForLink().toSpotifyURL();
p.setStyle("display", "block");
var o = document.createElement("div");
o.setStyle("backgroundImage", "url(img/radio-btn.png)");
o.addClass("imageHover");
p.adopt(o);
u.adopt(p);
o = document.createElement("div");
o.addClass("imageCarouselTitle");
u.adopt(o);
var s = document.createElement("a");
s.set("html", f.name.decodeForHtml());
s.set("href", f.link.decodeForLink().toSpotifyURL());
s.set("title", f.name.decodeForHtml());
s.addClass("main outgoing");
if (f.link == "") s.style.pointerEvents = "none", s.style.cursor = "default";
o.adopt(s);
o.adopt(document.createElement("br"));
for (s = 0; s < e.length; s++) {
var m = e[s],
A = document.createElement("a");
A.addClass("outgoing");
A.set("html", m.name.decodeForHtml());
A.set("href", m.link.decodeForLink().toSpotifyURL());
o.adopt(A);
o.adopt(document.createElement("br"))
}
u.setStyle("paddingLeft", u.style.paddingRight = h + "px");
d.adopt(u);
g++;
g > c && $$(".imageCarouselNext").removeClass("disabled");
i()
})
};
this.scrollTo = function (b) {
function t(b, d) {
var f = a.getElement(b);
d ? f.addClass("disabled") : f.removeClass("disabled")
}
b > g - c && (b = g - c);
b < 0 && (b = 0);
t(".imageCarouselPrev",
b == 0);
t(".imageCarouselNext", b >= g - c);
d.setStyle("marginLeft", "-" + b * (k + 2 * h) + "px");
f = b
};
this.clear = function () {
for (var b = d.getElements("li"), a = 0; a < b.length; a++) d.removeChild(b[a]);
g = 0
};
this.handleResize = function () {
var d = a.getWidth();
c = Math.floor(d / (k + 24));
h = Math.floor((d / c - k) / 2);
for (var g = a.getElements("li"), e = 0; e < g.length; e++) g[e].style.paddingLeft = g[e].style.paddingRight = h + "px";
a.getElement(".imageCarouselTitle").style.paddingLeft = h + "px";
a.getElement(".imageCarouselTitle").style.width = d - 2 * h - 50 + "px";
a.getElement(".imageCarouselPagination").style.paddingRight = h + "px";
i();
b.scrollTo(f)
};
window.addEventListener("resize", b.handleResize);
(function () {
a = document.createElement("div");
a.addClass("imageCarouselWrapper");
$$(l).adopt(a);
var g = document.createElement("h2");
g.addClass("imageCarouselTitle");
g.set("html", e);
a.adopt(g);
g = document.createElement("div");
g.addClass("imageCarouselPagination");
a.adopt(g);
var t = document.createElement("div");
t.addClass("imageCarouselPrev disabled");
g.adopt(t);
var x = document.createElement("div");
x.addClass("imageCarouselNext disabled");
g.adopt(x);
t.addEventListener("click", function () {
b.scrollTo(f - c)
});
x.addEventListener("click", function () {
b.scrollTo(f + c)
});
g = document.createElement("div");
g.addClass("imageCarousel");
a.adopt(g);
d = document.createElement("ul");
g.adopt(d);
b.handleResize();
setTimeout(function () {
b.handleResize()
}, 1E3)
})()
}
});
_unrequire("scripts/util", [], function (l) {
function q(a, d, g, f, b, c) {
b = {
height: b,
width: b
};
if (g === "genre") f = d, b.placeholder = "artist";
if (c && (c === "recent" || c === "header")) b.style =
"embossed";
d = new j(f, b);
a.appendChild(d.node)
}
var e, n, j;
l.init = function (a, d, g) {
e = a;
n = d;
j = g
};
l.loadImgAsync = function (a, d, g, f, b) {
var c;
if (g.indexOf("spotify:track:") === 0) c = e.Track.fromURI(g);
else if (g.indexOf("spotify:album:") == 0) c = e.Album.fromURI(g);
else if (g.indexOf("spotify:artist:") === 0) c = e.Artist.fromURI(g);
else if (g.indexOf("spotify:user:") == 0) c = e.Playlist.fromURI(g);
else if (g.indexOf("spotify:genre:") === 0) {
(d = k(g)) && d.type && q(a, d[d.type].image, d.type, d.item, f, b);
return
}
q(a, null, "not-genre", c,
f, b)
};
l.buildPlaylistMosaic = function (a, d) {
var g = a.split("/"),
g = g[g.length - 1].match(/.{1,40}/g);
g.length === 4 ? d("spotify:mosaic:" + g[0] + ":" + g[1] + ":" + g[2] + ":" + g[3]) : d("spotify:mosaic:" + g[0])
};
var i = l.getTrackMetaData = function (a, d, g) {
var f = {}, b = ["name", "uri"].concat(["album", "artists"]);
f.track = {};
f.album = {};
f.artist = {};
f.type = "track";
f.seed = a.uri;
g && b.push("image");
a.load(b).done(function (a) {
b.each(function (b) {
f.track[b] = a[b]
});
f.artist.name = a.artists[0].name;
f.artist.uri = a.artists[0].uri;
f.album.name = a.album.name;
f.album.uri = a.album.uri;
if (g) f.album.image = a.image;
f.item = a;
d(f)
}).fail(function (b) {
h.error("error loading track data: ", b);
d()
})
}, k = function (a) {
var d = {
type: "genre",
genre: {}
};
d.seed = a;
var g = a.replace("spotify:genre:", "");
if (g in n) d.genre.name = n[g][0], d.genre.mosaic = n[g][2], d.genre.uri = a, d.genre.image = "img/genre-images/genre-" + g + ".jpg";
return d
};
l.getSeedMetadata = function (a, d, g, f) {
var b = {}, c = ["name", "uri"],
t = g || 300;
b.artist = {};
b.playlist = {};
b.album = {};
b.seed = a;
f && c.push("image");
g = c.concat(["artists"]);
a.indexOf("spotify:track:") === 0 ? i(e.Track.fromURI(a), d, f) : a.indexOf("spotify:album:") == 0 ? (b.type = "album", e.Album.fromURI(a).load(g).done(function (a) {
a.artists[0].load(c).done(function (g) {
c.forEach(function (d) {
b.album[d] = a[d];
b.artist[d] = g[d]
});
b.item = a;
if (f) b.image = a.imageForSize(t);
d(b)
}).fail(function (b) {
h.error("problem getting artist data: ", b);
d()
})
}).fail(function (b) {
h.error("problem getting album data: ", b);
d()
})) : a.indexOf("spotify:artist:") === 0 ? (b.type = "artist", e.Artist.fromURI(a).load(c).done(function (a) {
c.forEach(function (d) {
b.artist[d] = a[d]
});
b.item = a;
if (f) b.image = a.imageForSize(t);
d(b)
}).fail(function (b) {
h.error("problem getting artist data: ", b);
d()
})) : a.indexOf("spotify:user:") == 0 ? (b.type = "playlist", e.Playlist.fromURI(a).load(c).done(function (a) {
c.forEach(function (d) {
b.playlist[d] = a[d]
});
b.item = a;
if (f) b.image = a.imageForSize(t);
d(b)
}).fail(function (b) {
h.error("problem getting playlist data: ", b);
d()
})) : a.indexOf("spotify:genre:") === 0 && d(k(a))
};
l.getTopTracks = function (a, d, g) {
var a = a.toArray(),
f = [],
b = [],
e = c("top tracks");
a.each(function (a) {
b.push(a.load(["name",
"uri", "image", "album", "artists"]))
});
d.join(b).done(function (b) {
e.stop();
b ? b.each(function (a, d) {
a.artists[0].load("name").done(function () {
var c = {
type: "track"
};
c.name = a.name;
c.uri = a.uri;
c.albumUri = a.album.uri;
c.image = a.image;
c.item = a;
c.subtitles = [{
name: a.artists[0].name,
link: a.artists[0].uri
}];
f.push(c);
d === b.length - 1 && g(f)
}).fail(function () {
h.error("failed to load artist name")
})
}) : g([])
}).fail(function (b, a) {
h.error("failed to load all promises: ", b, a);
g(f)
})
};
l.getTopArtists = function (a, d, g) {
var f = [],
b = [],
e;
a.toArray().each(function (a) {
b.push(a.load(["name", "image"]))
});
e = c("top artists");
d.join(b).done(function (b) {
e.stop();
b ? (b.each(function (b) {
var a = {
type: "artist"
};
a.name = b.name;
a.uri = b.uri;
a.image = b.image;
a.subtitles = [];
a.item = b;
f.push(a)
}), g(f)) : g([])
}).fail(function (b, a) {
h.error("failed to load all promises: ", b, a);
g(f)
})
};
l.Buffer = function (a) {
var d = {}, c = [];
d.add = function (d) {
d.forEach ? d.forEach(function (b) {
c.length === a && c.shift();
c.push(b)
}) : h.error(d, " does not appear to be an array")
};
d.getItems = function () {
return c.concat()
};
d.clear = function () {
c = []
};
return d
};
var h = l.console = function () {
var a = "log",
d = !1,
c = function () {
d && window.console && window.console[a] && window.console[a].apply && window.console[a].apply(window.console, ["[RADIO] ", arguments])
}, f = {};
["log", "info", "warn", "error", "debug"].forEach(function (b) {
f[b] = function () {
a = b;
c.apply(this, arguments)
}
});
f.enable = function () {
d = !0
};
return f
}(),
c = l.Timer = function (a) {
var d = {};
d.name = a;
d.start = (new Date).getTime();
d.stop = function () {
d.end = (new Date).getTime();
d.result = d.end - d.start;
h.log(a + " timer = " + d.result);
return d.result
};
return d
}
});
_unrequire("scripts/strings.json", [], function (l) {
l.strings = {
by: "by",
"Not Available": "Radio is not available while offline",
"Please Connect": "You must connect to a Wi-Fi or cellular data network to access Radio",
"Current Station": "Current <span>Station</span>",
"Current album station": "Album Radio based on",
"Current artist station": "Artist Radio based on",
"Current genre station": "Genre Radio for",
"Current playlist station": "Playlist Radio for",
"Current track station": "Track Radio based on",
genres: {
"60s": "60s",
"70s": "70s",
"80s": "80s",
"90s": "90s",
Alternative: "Alternative",
"Black Metal": "Black Metal",
Blues: "Blues",
Classical: "Classical",
"Club/House": "Club/House",
Country: "Country",
"Death Metal": "Death Metal",
Electronic: "Electronic",
Emo: "Emo",
Folk: "Folk",
Hardcore: "Hardcore",
"Heavy Metal": "Heavy Metal",
"Hip-Hop": "Hip-Hop",
Indie: "Indie",
Jazz: "Jazz",
Latin: "Latin",
Pop: "Pop",
Punk: "Punk",
"R&B": "R&B",
Reggae: "Reggae",
Rock: "Rock",
"Singer-Songwriter": "Singer-Songwriter",
Soul: "Soul",
Trance: "Trance"
},
Loading: "Loading...",
"Missing station": "<strong>Sorry. This radio station cannot be started.</strong><br/>Please try with something else.",
"Popular Genre Stations": "Popular Genre <span>Stations</span>",
"Popular Stations": "Popular <span>Stations</span>",
"Recent Stations": "Recent <span>Stations</span>",
"Search prompt": "Search for music to create a new station...",
"Create prompt": "Create new station...",
"Your Top Albums Stations": "Your Top Albums <span>Stations</span>",
"Your Top Artists Stations": "Your Top Artists <span>Stations</span>",
"Your Top Tracks Stations": "Your Top Tracks <span>Stations</span>"
}
});
_unrequire("scripts/eventhandler", [], function (l) {
function q(e) {
this.handler_ = e || null;
this.listeners_ = []
}
function e(e, j, i, k) {
this.src = e;
this.type = j;
this.originalListener = i;
this.listener = k ? i.bind(k) : i
}
q.prototype.listen = function (n, j, i) {
n = new e(n, j, i, this.handler_);
this.listeners_.push(n);
n.listen();
return this
};
q.prototype.unlisten = function (e, j, i) {
for (var k = this.listeners_, h = 0; h < k.length; h++) {
var c = k[h];
if (c.src === e && c.type === j && c.originalListener === i) {
c.unlisten();
k.splice(h, 1);
break
}
}
return this
};
q.prototype.removeAll = function () {
for (var e = this.listeners_, j = 0; j < e.length; j++) e[j].unlisten();
e.splice(0)
};
e.prototype.listen = function () {
this.src.addEventListener(this.type, this.listener)
};
e.prototype.unlisten = function () {
this.src.removeEventListener(this.type, this.listener)
};
l.EventHandler = q
});
_unrequire("scripts/cloud", [], function (l) {
l.Cloud = function (l, e) {
function n() {
var k = j.getWidth()[0];
j.getFirst().dispose();
var h = new Element("ul");
h.className = "cloudLine";
j.adopt(h);
for (var c = 0, a = 0; a < e.length; a++) c + i[a] > k ? (h.style.width = c + "px", h = document.createElement("ul"), h.className = "cloudLine", j.adopt(h), c = i[a]) : c += i[a], h.appendChild(e[a]);
h.style.width = c + "px"
}
var j = null,
i = [];
window.addEventListener("resize", n);
(function () {
j = $$(l);
var k = new Element("ul");
j.adopt(k);
for (var h = 0; h < e.length; h++) {
var c = e[h];
k.adopt(c);
i.push(c.getWidth() + 25)
}
j.adopt(k);
n()
})()
}
});
_unrequire("scripts/ui", ["$api/models"], function (l) {
(function (q) {
function e(w, e, u, p) {
b = this;
this.thumbUp = this.thumbDown = this.stationLoaded = !1;
f.call(b);
i = $$(h)[0];
k = w;
a = new u.EventHandler(d);
d = e;
v = d.util;
g = p;
var w = $$("#radio"),
e = $$("#hide-first-time"),
o = $$("#first-time"),
s = $$("#station-error"),
u = $$(c),
m = $$(".auto-completeForm");
a.listen(w[0], "click", y).listen(window, "resize", x).listen(window, "beforeunload", j).listen(e[0], "click", function () {
o.setStyle("display", "none")
}).listen(s[0],
"click", function () {
s.setStyle("visibility", "hidden");
window.clearTimeout(d._stationErrorTimeout)
}).listen(u[0], "click", function (a) {
m.getStyle("display")[0] === "block" ? b.hideAutocomplete() : b.showAutocomplete();
a.stopPropagation()
});
(new Image).src = "img/radio-btn.png";
b.thumbsup = $$("#thumbsup");
b.thumbsdown = $$("#thumbsdown");
b.thumbsup.addEvent("click", function () {
!b.thumbsup.hasClass("selected")[0] && !b.thumbsup.hasClass("disabled")[0] && (b.dispatchEvent({
type: "thumb",
thumbType: "up"
}), b.doThumbsup())
});
b.thumbsdown.addEvent("click", function () {
!b.thumbsdown.hasClass("selected")[0] && !b.thumbsdown.hasClass("disabled")[0] && (b.dispatchEvent({
type: "thumb",
thumbType: "down"
}), b.doThumbsdown())
});
b.radioEl = w;
b.hideFirstTimeButton = e;
b.firstTimeEl = o;
b.stationErrEl = s;
b.createStationEl = u;
b.searchEl = m
}
function n(b) {
b = b.target;
getComputedStyle(b).opacity === "0" && b && b.parentNode.removeChild(b)
}
function j() {
a.removeAll()
}
var i, k, h = "#playing-covers",
c = "#create-station-handler",
a, d, g, f, b, v, t = [];
f = q.Observable;
e.prototype = new f;
e.prototype.disableThumbs = function () {
b.thumbsdown.addClass("disabled");
b.thumbsup.addClass("disabled")
};
e.prototype.enableThumbs = function () {
b.thumbsdown.removeClass("selected");
b.thumbsup.removeClass("selected");
b.thumbsdown.removeClass("disabled");
b.thumbsup.removeClass("disabled");
b.thumbDown = !1;
b.thumbUp = !1
};
e.prototype.resumeThumbs = function () {
b.thumbUp || b.thumbsdown.removeClass("disabled");
b.thumbDown || b.thumbsup.removeClass("disabled")
};
e.prototype.showFeedback = function (b) {
var a = $$(".improvingFeedback"),
d = $$(".improvingFeedbackCover");
a.setStyle("display", "block");
d.setStyle("display", "block");
$$(".improvingFeedbackInfo").setStyle("display", "block");
$$(".improvingFeedbackImg").setStyle("display", "block");
$$(".improvingStation").setStyle("display", "block");
t.push(setTimeout(function () {
b && ($$(".improvingStation").setStyle("display", "none"), $$(".addedToLiked").setStyle("display", "block"));
t.push(setTimeout(function () {
$$(".improvingFeedbackImg").setStyle("display", "none");
$$(".improvingStation").setStyle("display",
"none");
$$(".addedToLiked").setStyle("display", "none");
$$(".doneImproving .improvingFeedbackImg").setStyle("display", "block");
$$(".doneImproving").setStyle("display", "block");
t.push(setTimeout(function () {
a.setStyle("display", "none");
$$(".improvingFeedbackImg").setStyle("display", "none");
$$(".doneImproving .improvingFeedbackImg").setStyle("display", "none");
$$(".doneImproving").setStyle("display", "none")
}, 1E3))
}, 2E3))
}, 3E3))
};
e.prototype.resetFeedback = function () {
for (var b = $$(".improvingFeedback"), a = !1, d = 0, c = t.length; d < c; d++) a = !0, clearTimeout(t.shift());
a && ($$(".improvingStation").setStyle("display", "none"), $$(".improvingFeedbackImg").setStyle("display", "none"), $$(".improvingStation").setStyle("display", "none"), $$(".addedToLiked").setStyle("display", "none"), b.setStyle("display", "none"), $$(".improvingFeedbackImg").setStyle("display", "none"), $$(".doneImproving .improvingFeedbackImg").setStyle("display", "none"), $$(".doneImproving").setStyle("display", "none"))
};
e.prototype.displayThumbUp = function () {
b.thumbsdown.addClass("disabled");
b.thumbsup.addClass("selected");
b.thumbsup.removeClass("disabled");
b.thumbsdown.removeClass("selected")
};
e.prototype.doThumbsup = function () {
b.resetFeedback();
b.displayThumbUp();
b.thumbDown = !1;
b.thumbUp = !0;
setTimeout(function () {
b.showFeedback(!0)
}, 500)
};
e.prototype.displayThumbDown = function () {
b.resetFeedback();
b.thumbsdown.addClass("selected");
b.thumbsup.removeClass("selected");
b.thumbsup.addClass("disabled");
b.thumbsdown.removeClass("disabled")
};
e.prototype.doThumbsdown = function () {
b.displayThumbDown();
b.thumbDown = !0;
b.thumbUp = !1
};
e.prototype.setStationHeader = function (b, a, d, c) {
var o = $$("#radio-seed");
o.setStyle("display", "block");
var f = o.getElement("span");
f[0].empty();
var m = document.createElement("div");
m.addClass("img");
m.addClass(d);
f.adopt(m);
v.loadImgAsync(m, b, c, 36, "header");
o.getElement("h2").set("html", a)
};
e.prototype.showAutocomplete = function () {
b.stationErrEl.setStyle("visibility", "hidden");
b._showingAutocomplete = !0;
this.dispatchEvent("show-search")
};
e.prototype.hideAutocomplete = function () {
b._showingAutocomplete = !1;
this.dispatchEvent("hide-search")
};
e.prototype.showLoadingScreen = function () {
b.stationErrEl.setStyle("visibility", "hidden");
$$("#loading-throbber").setStyle("display", "block");
$$("#loading").setStyle("display", "block");
var a = $$("#playButton");
a != null && a.setStyle("display", "none");
$$("#playing-speaker").setStyle("display", "none");
$$("#playing-skip>a").setStyle("display", "none")
};
e.prototype.loadingStation = function () {
for (var b = window.pageYOffset, a = 1; b >= -100; b -= 100, ++a) setTimeout("window.scrollTo(window.pageXOffset, " + Math.max(b, 0) + ")", 10 * a);
this.stationLoading = !0;
this.disableThumbs();
this.showLoadingScreen()
};
e.prototype.hideLoadingScreen = function () {
$$("#loading").setStyle("display", "none");
$$("#loading-throbber").setStyle("display", "none")
};
e.prototype.hideAppLoadingScreen = function () {
$$("#app-loading").setStyle("display", "none");
$$("#app-loading-throbber").setStyle("display", "none")
};
e.prototype.fillTopList = function (b, a, c) {
var f = this;
setTimeout(function () {
f.hideAppLoadingScreen();
if (typeof c === "undefined" || c.length === 0) $$(b).setStyle("display", "none");
else {
for (var o = new g.ImageCarousel(b, a, d.enStrings, d.util), s = 0; s < c.length && s < 20; s++) {
var m = c[s];
var e = m.image;
e && e.length > 0 && e.substr(e.lastIndexOf(":") + 1);
o.addItem(m.uri, m.image, {
name: m.name,
link: m.albumUri || m.uri
}, m.subtitles, m.type, "recommended")
}
o.scrollTo(0)
}
}, 25)
};
e.prototype.fillGenres = function () {
function b(d, o) {
var c = document.createElement("li"),
m = document.createElement("button");
m.className = "main";
m.addClass("genre");
m.href = ("spotify:radio:genre:" + o).toSpotifyURL();
var f = document.createElement("span");
f.className = "genre-image";
var g = document.createElement("span");
g.className = "genre-text";
g.innerHTML = d;
m.appendChild(f);
m.appendChild(g);
c.appendChild(m);
a.push(c)
}
var a = [],
c;
for (c in d.genreDict) b(d.genreDict[c][0], c);
new k.Cloud("#genres>div", a)
};
e.prototype.fillRecentStationList = function (a) {
setTimeout(function () {
var c = d._recent,
f = $$("#recent"),
g, o;
c.imageCarousel.clear();
if (!a || a.length <= 1) f.setStyle("display", "none");
else {
for (var e = 1; e < 21 && e < a.length; e++) {
var m = a[e];
if (typeof m === "object" && m.seeds) {
o = m.seeds[0];
var v = {}, i = [];
if (o.indexOf("spotify:track") > -1) {
g = "track";
var v = {
name: m.title,
link: m.titleUri
}, h = m.imageUri;
i.push({
name: m.subtitle,
link: m.subtitleUri
})
} else if (o.indexOf("spotify:album") > -1) g = "album", v = {
name: m.title,
link: m.titleUri
}, i.push({
name: m.subtitle,
link: m.subtitleUri
}), h = m.imageUri;
else if (o.indexOf("spotify:artist") > -1) g = "artist", v = {
name: m.title,
link: m.titleUri
}, h = m.imageUri;
else if (o.indexOf("spotify:genre") > -1) g = "genre", v = {
name: m.title,
link: ""
}, h = "img/genre-images/genre-" + m.seeds[0].replace("spotify:genre:", "") + ".jpg";
else if (o.indexOf("spotify:user") > -1) g = "playlist", v = {
name: m.title,
link: m.titleUri
}, h = m.imageUri;
h && c.imageCarousel.addItem(o, h, v, i, g, "recent")
}
}
f.setStyle("display", "block");
c.imageCarousel.handleResize();
c.imageCarousel.scrollTo(0);
b.hideAppLoadingScreen()
}
}, 50)
};
e.prototype.rotateCovers = function (a) {
var c = i.getElement("li"),
f, a = a || this.track;
if (this.stationLoading && a) this.track = a;
else if (a) {
this.newItem ? (f = i.getElement("li"),
this.newItem = null) : (f = document.createElement("li"), c ? i.insertBefore(f, c) : i.insertBefore(f, null));
d.ui.resetFeedback();
c = a.image;
f.addEventListener("webkitTransitionEnd", n);
var g = document.createElement("span");
g.id = "playButton";
g.style.display = "none";
(new Image).src = "img/play-button-XL.png";
f.appendChild(g);
var o = document.createElement("a");
o.href = a.uri.decodeForLink().toSpotifyURL();
o.className = "outgoing";
f.appendChild(o);
f.firstChild.title = a.name.decodeForHtml();
var e = new Image;
e.onerror = function () {
e.src =
"img/300-album.png";
e.onerror = function () {}
};
e.onload = function () {
o.appendChild(e);
$$(e).addClass("imgCoverflow")
};
e.src = c;
f = $$("#radio-track");
c = $$("#radio-artist");
$$("#radio-star");
f.set("html", '<a class="outgoing" href="' + a.uri.decodeForLink().toSpotifyURL() + '">' + a.name.decodeForHtml() + "</a>");
c.set("html", '<a class="outgoing" href="' + a.artists[0].uri.decodeForLink().toSpotifyURL() + '">' + a.artists[0].name.decodeForHtml() + "</a>");
this.track = null;
b.addFeedbackElements();
setTimeout(function () {
b.enableThumbs()
},
500);
b.updatePlayPause(!1)
} else this.newItem = f = document.createElement("li"), i.insertBefore(f, null)
};
e.prototype.addFeedbackElements = function () {
$$(".improvingFeedback").destroy();
var a = $$("#playing-covers li:first-child"),
d = new Element("div.improvingFeedback"),
c = new Element("div.improvingFeedbackImg"),
f = new Element("div.text.improvingStation"),
o = new Element("div.improvingFeedbackCover"),
g = new Element("div.improvingFeedbackInfo"),
m = new Element("div.text.addedToLiked"),
e = new Element("div.text.doneImproving"),
v = new Element("div.improvingFeedbackImg");
f.appendText("Improving Station...");
m.set("html", "Added to playlist:<br>Liked from Radio");
e.set("html", "<p>Done!</p>");
d.adopt(o);
d.adopt(g);
g.adopt(c);
g.adopt(f);
g.adopt(m);
g.adopt(e);
e.adopt(v);
a.adopt(d);
b.thumbDown && setTimeout(function () {
b.showFeedback()
}, 250)
};
e.prototype.playerStateChange = function (a, d) {
a === "playing" && (this.rotateCovers(d), b.updatePlayPause(!0));
a === "resume" && b.updatePlayPause(!1)
};
e.prototype.stationAvailable = function (b, a, c, f) {
var o = $$("#echonest");
if (c) {
this.stationLoaded = !0;
this.stationLoading = !1;
$$("#playing-skip>a").setStyle("display", "block");
b.indexOf("en") >= 0 && (o.setStyle("display", "block"), setTimeout(function () {
o.setStyle("display", "none")
}, 3E3));
if (c.type === "track") {
var g = "<a class='outgoing' href='" + c.track.uri.decodeForLink().toSpotifyURL() + "'>" + c.track.name.decodeForHtml() + "</a>",
b = "<a class='outgoing' href='" + c.artist.uri.decodeForLink().toSpotifyURL() + "'>" + c.artist.name.decodeForHtml() + "</a>",
b = d._("<header>Current track station</header>") + g + " by " + b;
this.setStationHeader(c.album.image, b, c.type, a)
} else c.type === "artist" ? (b = "<a class='outgoing' href='" + c.artist.uri.decodeForLink().toSpotifyURL() + "'>" + c.artist.name.decodeForHtml() + "</a>", b = d._("<header>Current artist station</header>") + b, this.setStationHeader(c.artist.image, b, c.type, a)) : c.type === "album" ? (g = "<a class='outgoing' href='" + c.album.uri.decodeForLink().toSpotifyURL() + "'>" + c.album.name.decodeForHtml() + "</a>", b = "<a class='outgoing' href='" + c.artist.uri.decodeForLink().toSpotifyURL() +
"'>" + c.artist.name.decodeForHtml() + "</a>", b = d._("<header>Current album station</header>") + g + " by " + b, this.setStationHeader(c.album.image, b, c.type, a)) : c.type === "genre" ? (b = d._("<header>Current genre station</header>") + c.genre.name.decodeForHtml(), this.setStationHeader("img/genre-images/genre-" + c.genre.image + ".jpg", b, c.type, a)) : c.type === "playlist" && (b = "<a class='outgoing' href='" + c.playlist.uri.decodeForLink().toSpotifyURL() + "'>" + c.playlist.name.decodeForHtml() + "</a>", this.setStationHeader(c.playlist.image,
d._("<header>Current playlist station</header>") + b, c.type, a));
i.empty();
this.rotateCovers();
this.hideLoadingScreen();
this.updatePlayPause(f)
} else i.empty(), this.rotateCovers(), this.failedStation()
};
var x = e.prototype.adjustHeaderWidth = function () {
var b = $$("#playing-header"),
a = $$("#radio-seed"),
c = $$("#right-header"),
b = b.getSize()[0].x - c.getSize()[0].x - 34 + "px";
a.setStyle("width", b)
}, y = e.prototype.handleClick = function (a) {
b.stationErrEl.setStyle("visibility", "hidden");
for (var c = a.target; c && c !== a.currentTarget; c = c.parentNode) if (c.tagName === "A" || c.tagName === "BUTTON") if (c.href && c.href.indexOf("spotify.com") > -1) {
if (c.className.indexOf("outgoing") === -1) {
a.preventDefault();
for (a = c; a = a.parentNode;) if (a.tagName == "SECTION") break;
a = c.href.toSpotifyURI().replace("spotify:radio:", "spotify:");
b.dispatchEvent({
type: "start-station",
seed: a,
elClass: c.className
})
} else a.preventDefault(), c = c.href.toSpotifyURI(), c.indexOf("spotify:track") > -1 && d._models.Track.fromURI(c).load("album").done(function (b) {
d._models.application.openURI(b.album.uri)
}).fail(function () {}),
d._models.application.openURI(c);
break
} else if (c.href === "radio:skip") {
if (a.preventDefault(), c.className.search("disabled") === -1) {
b.dispatchEvent("skip");
break
}
} else {
if (c.href === "radio:play-pause") {
a.preventDefault();
b.dispatchEvent("play-pause");
break
}
} else if (c.id === "playButton") {
a.preventDefault();
b.dispatchEvent("play-pause");
break
} else b._showingAutocomplete && !c.hasClass("search") && b.hideAutocomplete()
};
e.prototype.updatePlayPause = function (b) {
var a = $$("#playButton")[0],
c = $$("#playing-speaker");
c.setStyle("display", "inline");
if (a) b ? (a.className = "playing", c.className = "playing") : (a.className = "paused", c.className = "paused"), a.style.display === "none" && setTimeout(function () {
a.setStyle("display", "inline")
}, 100)
};
e.prototype.firstTime = function () {
b.firstTimeEl.setStyle("display", "block")
};
e.prototype.disableSkip = function () {
$$("#playing-skip>a").addClass("disabled")
};
e.prototype.enableSkip = function () {
$$("#playing-skip>a").setStyle("display", "block");
$$("#playing-skip>a").removeClass("disabled")
};
e.prototype.enableControls = function () {
this.enableSkip();
this.resumeThumbs();
var b = $$("#playButton")[0];
$$("#playing-speaker").setStyle("display", "inline");
b.setStyle("display", "inline")
};
e.prototype.failedStation = function () {
this.hideAppLoadingScreen();
this.hideLoadingScreen();
this.stationLoading = !1;
this.stationLoaded && this.enableControls();
b.stationErrEl.setStyle("visibility", "visible")
};
l.RadioUi = e
})(r["$api/models"])
});
_unrequire("scripts/station", ["$api/models"], function (l) {
(function (q) {
var e = null,
n, j, i = function (c, a) {
q.Observable.call(this);
this.id = a;
this._tracks = [];
this._radio = c;
this._models = c._models;
this.index = -2;
this._position = 0;
this._state = "loading";
this._hermes = c.hermes.Hermes;
this._schema = c.schema;
this._temporaryPlaylist = this._posIntervalId = this._currentTrack = null;
this._recents = c.util.Buffer(200);
this.thumbed = !1;
this.feedback = {};
n = c.util;
j = n.Timer
};
i.models = q;
e = q.Observable;
i.prototype = new e;
i.prototype.playerStateChanged = function (c) {
try {
var a = this,
d = c.target;
a.player = d;
a._temporaryPlaylist && d.load(["playing", "position", "track",
"index", "context"]).done(function (c) {
var b = c.track,
d = c.context,
g = c.index;
if (d && d.uri === a._temporaryPlaylist.uri) if (c.playing && a._playing === !1) a._playing = !0, a.dispatchEvent("is-playing");
else if (!c.playing && a._playing) a._playing = !1, a.dispatchEvent("paused");
else if (c.position !== 0 && c.position === c.duration) a.dispatchEvent("track-end");
else {
if (b && g > -1 && a.index !== g) a.dispatchEvent({
type: "new-track",
track: b
}), a.index = g, a._currentTrack = b, a._recents.add([b.uri.replace("spotify:track:", "")]), a._position = 0,
a._temporaryPlaylist.sizeNeeded = Math.max(a.index + 40, 30), a._temporaryPlaylist.load(["tracks"]).done(function (b) {
a._refillAndPlayFirst(b.tracks, !1)
}).fail(function () {})
} else a._playing = !1, a.dispatchEvent("leavingRadio")
}).fail(function () {})
} catch (g) {}
};
i.prototype._failedStation = function () {
this.dispatchEvent("failed-station")
};
var k = function (c, a, d, g) {
try {
if (a._temporaryPlaylist) {
var f = 20,
b = a._tracks.length,
e = 0,
i, h = [],
k = a._firstFill,
n = 0,
l = 0,
q;
if (g) f = a._tracks.length;
for (var p = function (b, o) {
q = j("add to tmp playlist");
d.snapshot().done(function (f) {
var m = a.index >= 0 ? a.index : 0,
e;
if (o || !a.thumbed) e = d.add(b);
if (a.thumbed) e = d.insert(f.ref(m), b), a.thumbed = !1;
e.done(function () {
q.stop();
g || (a._temporaryPlaylist.size += b.length);
if (a._firstFill && a._startPlay === !1) a._currentTrack = b[0], a.dispatchEvent({
type: "track-added",
track: b[0]
}), a._firstFill = !1;
a._firstFill = !1;
if (a._startPlay && c.getCurrentStation() === a && a._temporaryPlaylist.size > 0) a.dispatchEvent({
type: "track-added",
track: b[0]
}), a.dispatchEvent({
type: "start-playing",
playlist: a._temporaryPlaylist
}),
a._startPlay = !1;
g && d.snapshot().done(function (c) {
var o = m + b.length;
d.trim(c.ref(o)).done(function () {
a._temporaryPlaylist.size = o + 1
}).fail(function () {})
})
}).fail(function () {})
}).fail(function () {})
}, o = []; b > 0;) {
var s = "spotify:track:" + a._tracks.shift();
o.push(c._models.Track.fromURI(s).load("playable"));
e += 1;
b -= 1;
if (e >= f) break
}
i = j("load done");
c._models.Promise.join(o).done(function () {}).fail(function () {}).always(function (b) {
i.stop();
b.forEach(function (b) {
b.playable ? (k ? (k = !1, l = 1, p([b], !0)) : h.push(b), a._temporaryPlaylist.tracksCache.push(b)) : n += 1;
h.length === e - (n + l) && p(h)
})
})
}
} catch (m) {}
};
i.prototype._refillAndPlayFirst = function (c, a, d) {
try {
var g = this._radio,
f = this;
f._startPlay = a;
if (d || !(f._temporaryPlaylist.size >= f._temporaryPlaylist.sizeNeeded)) if (!d && this._tracks.length > 5) k(g, f, c);
else if (d || this._tracks.length < f._temporaryPlaylist.sizeNeeded - f._temporaryPlaylist.size) a = 50, d && (a = f._temporaryPlaylist.size - f.index), f._hermesCall(f._actualSeed, f._recents.getItems(), a, function (b) {
try {
f._addTracksFromHermesResult(b[0]), k(g, f, c, d)
} catch (a) {}
},
function () {})
} catch (b) {}
};
var h = function (c, a) {
c.feedback = c.feedback || {};
a.forEach(function (a) {
c.feedback["spotify:track:" + a.uri] = a.type
})
};
i.prototype._hermesSuccess = function (c) {
try {
this.hermesTimer.stop(), c && c.length > 0 && c[0].gids && c[0].gids.length > 0 ? this._stationAvailable(c[0], this.originalSeed, this.newSeed, this._startPlay) : this._hermesFailure()
} catch (a) {}
};
i.prototype._hermesFailure = function () {
var c = this;
c.hermesTimer.stop();
try {
c.newSeed.indexOf("spotify:track") === 0 || c.newSeed.indexOf("spotify:album") === 0 ? c._radio.util.getSeedMetadata(c.newSeed, function (a) {
a && a.artist && a.artist.uri ? c._loadStationWithFallback(a.artist.uri, c._startPlay, c.originalSeed) : c._failedStation()
}, null, !1) : c._failedStation()
} catch (a) {}
};
i.prototype._loadStationWithFallback = function (c, a, d) {
try {
c === null ? this._failedStation() : (this.newSeed = c, this.originalSeed = d, this.hermesTimer = j("hermes"), this._hermesCall(c, this._recents.getItems(), 20, this._hermesSuccess, this._hermesFailure))
} catch (g) {}
};
i.prototype.loadStation = function (c, a) {
try {
this.clickToPlayingTimer = j("click to playing"), this._currentTrack = {}, this._currentTrack.uri = "", this.seed = c, this._loading = !0, this._startPlay = a, this.loadStationTimer = j("load station"), this._loadStationWithFallback(c, a, c), this.index = -2, this._playing = !1
} catch (d) {}
};
i.prototype._addTracksFromHermesResult = function (c) {
try {
for (var a = 0, d = c.gids.length; a < d; a++) this._tracks.push(c.gids[a]);
c.feedback && c.feedback.length > 0 && h(this, c.feedback)
} catch (g) {}
};
i.prototype._stationAvailable = function (c, a, d, g) {
try {
var f = this,
b = this._radio,
e = c.source;
f._firstFill = !0;
this.loadStationTimer.stop();
this._actualSeed = d;
var h = j("create temp playlist");
f.dispatchEvent({
type: "stationAvailable",
trackSource: e,
originalSeed: a,
startPlay: g
});
b._models.Playlist.createTemporary(a).done(function (b) {
h.stop();
var a = j("enforce radio rules");
b.enforceRules("radio").done(function (b) {
a.stop();
var d = j("load temp playlist tracks collection");
b.load(["tracks"]).done(function (b) {
d.stop();
var a = b.tracks;
f._temporaryPlaylist = b;
f._temporaryPlaylist.tracksCache = [];
f._temporaryPlaylist.sizeNeeded = 5;
f._temporaryPlaylist.size = 0;
f._tracks = [];
f._addTracksFromHermesResult(c);
(function () {
try {
a.clear().done(function () {
f._refillAndPlayFirst(a, g)
}).fail(function () {})
} catch (b) {}
})()
}).fail(function () {
f._failedStation()
})
}).fail(function () {
f._failedStation()
})
}).fail(function () {
f._failedStation()
})
} catch (i) {
f._failedStation()
}
};
i.prototype._hermesCall = function (c, a, d, g, f) {
var b = this,
e = function (a) {
g.call(b, a)
}, h = function (a) {
f.call(b, a)
}, i = b._radio,
j = {
salt: Math.floor(Math.random() * 1E6),
lastTracks: a,
length: d
},
k = this._hermes.get("hm://radio/", [b._schema.type("Tracks")], [b._schema.type("RadioRequest")]);
if (b.id) j.stationId = b.id;
c.indexOf("spotify:user") === -1 ? (j.uris = [c], k.send(j).done(e).fail(h)) : i._models.Playlist.fromURI(c).load("tracks").done(function (b) {
b.tracks.snapshot(0, 250).done(function (b) {
for (var a = [], b = b.toArray(), c = b.length, d = 0; d < c; d++) {
var g = d + Math.floor(Math.random() * (c - d)),
f = b[g].uri;
if (f.substr(0, 14) !== "spotify:local:" && (a.push(f), a.length >= 50)) break;
b[g] = b[d];
b[d] = f
}
j.uris = a;
k.send(j).done(e).fail(h)
}).fail(h)
}).fail(h)
};
i.prototype._updatePlaylist = function () {
var c = this._temporaryPlaylist;
c.tracksCache = [];
this._tracks = [];
this.index === -2 && this._tracks.push(this._currentTrack.uri.replace("spotify:track:", ""));
this._refillAndPlayFirst(c.tracks, this._startPlay, !0)
};
i.prototype.thumbEvent = function () {
this.thumbed = !0;
this._updatePlaylist()
};
i.prototype.skipTrack = function (c) {
var a = this;
a._models.player.load(["context"]).done(function (d) {
d.context && d.context.uri === a._temporaryPlaylist.uri && d.skipToNextTrack().done(function () {
c && c()
}).fail(function () {
c && c()
})
}).fail(function () {})
};
l.Station = i
})(r["$api/models"])
});
_unrequire("scripts/searchUtil", [], function (l) {
l.init = function () {};
var q = l.setBg = function (e, n) {
var j = "url(" + e.target.src + ")",
i = n.getElementsByClassName("searchImg"),
i = $$(i);
i.setStyle("background-image", j);
i.removeClass("sp-image-placeholder-visible")
};
l.decorate = function (e, n, j) {
var i = function () {};
e === "tracks" && j.Track.fromURI(n.uri).load(["album", "artists"]).done(function (e) {
e.album.load("image").done(function (h) {
e.artists[0].load("name").done(function (c) {
var a = new Image;
a.onload = function (a) {
q(a, n)
};
var d = h.imageForSize(60);
a.src = d;
n.innerHTML = n.innerHTML + " " + c.name.decodeForHtml()
}).fail(i)
}).fail(i)
}).fail(i);
e === "albums" && j.Album.fromURI(n.uri).load(["artists"]).done(function (e) {
e.artists.length < 1 || e.artists[0].load("name").done(function (e) {
n.innerHTML = n.innerHTML + " " + e.name.decodeForHtml()
}).fail(i)
}).fail(i)
};
l.doSearch = function (e, n, j, i) {
function k(a, f, b, e) {
a[f].snapshot(0, d).done(function (b) {
var a = b.toArray();
e && (a = e.concat(a));
if (a.length < 1) j(null);
else {
for (var b = [], d = 0, g = a.length; d < g; d++) b.push(a[d].load(c));
i.Promise.join(b).done(function () {
j(a, f, h)
}).fail(function () {})
}
}).fail(function () {})
}
var h = n,
c = ["name", "uri", "image"],
a = ["artists", "tracks", "albums"],
d = 3;
(function (c, d) {
for (var b = 0, e = a.length; b < e; b++) k(c, a[b], d)
})(e.suggest(n), "suggest")
};
l.throttle = function (e, n) {
var j = null,
i = null;
return function () {
var k = arguments,
h = Date.now(),
c = h - (i || 0);
j && (clearTimeout(j), j = null);
c >= n ? (i = h, e.apply(e, k)) : j = setTimeout(function () {
i = h;
e.apply(e, k)
}, n - c)
}
}
});
_unrequire("scripts/searchWidget", ["$api/search", "scripts/eventhandler", "scripts/searchUtil", "$api/models", "$api/models"], function (l) {
(function (q, e, n, j, i) {
function k() {
var b = this;
b.input = document.createElement("input");
b.input.id = "autocompleteSearchWidget";
b.input.addClass("search");
b.node = document.createElement("div");
b.node.className = "input token-input";
b.node.appendChild(b.input);
h.listen(b.input, "input", function () {
b.input.value.length > 0 ? b.input.value.indexOf("spotify:") > -1 ? (c.dispatchEvent({
type: "open-uri",
seed: b.input.value,
elClass: "searchPaste"
}), c.hide(), b.input.value = "") : b.searchHandler(b.input.value, function (a, c, d) {
a !== null && d && b.input.value === d && b.addTokens(a, c)
}) : c.setInitialResults()
}).listen(b.input, "focus", function () {
$$(b.node).addClass("focus")
}).listen(b.input, "blur", function () {
$$(b.node).removeClass("focus")
})
}
var h = new e.EventHandler(f),
c, a, d = ["artists", "albums", "tracks"],
g = function (b) {
for (var a = b.target; a;) {
if (a.tagName !== "A" && a.hasClass("search")) {
b.preventDefault();
b.stopPropagation();
c.show();
break
} else if (a.tagName === "A") {
b.preventDefault();
b.stopPropagation();
b = a.href.toSpotifyURI().replace("spotify:radio:", "spotify:");
c.dispatchEvent({
type: "open-uri",
seed: b,
elClass: a.className
});
c.hide();
break
}
a = a.parentNode
}
}, f = function (b, d) {
j.call(this);
this.widgetContainer = b[0];
a = d;
n.init(a);
c = this;
this.init();
var f = $$(".auto-completeForm"),
e = new Element("#close-search");
f.adopt(e);
h.listen(e, "click", function (b) {
b.preventDefault();
b.stopPropagation();
c.clear()
});
h.listen(c.widgetContainer,
"click", g)
};
f.prototype = new j;
f.prototype.constructor = f;
f.prototype.onURISearch = function () {};
f.prototype.init = function () {
if (!this.searchHandler) this.searchHandler = n.throttle(function (b, a) {
n.doSearch(q, b, a, i)
}, 500);
this.initInputField();
this.initKeyboardNav();
this.initialResults && this.setInitialResults(this.initialResults)
};
f.prototype.show = function () {
c.widgetContainer.setStyle("display", "block");
c.widgetContainer.getElement("input").focus()
};
f.prototype.hide = function () {
c.widgetContainer.setStyle("display",
"none")
};
f.prototype.setInitialResults = function (b) {
var a = this.widgetContainer.getElement(".albums");
a && a.setStyle("display", "none");
if (b) this.initialResults = b;
for (var c in this.initialResults) this.tokenInput.addTokens(this.initialResults[c], c)
};
f.prototype.initKeyboardNav = function () {
h.listen(window, "keydown", function (b) {
var a = b.keyCode === 38,
d = b.keyCode === 40,
f = b.keyCode === 13,
b = b.keyCode === 27,
e = c.widgetContainer.getElements("a"),
g = c.widgetContainer.getElements("a.selected").pop(),
h = e.indexOf(g);
b === !0 && this.hide();
if (f === !0) return h > -1 && (this.onEnter({
target: g,
currentTarget: null,
preventDefault: function () {
return !1
}
}), this.hide()), !1;
a && (h === -1 ? $$(e[e.length - 1]).addClass("selected") : h > 0 && ($$(g).removeClass("selected"), $$(e[h - 1]).addClass("selected")));
d && (h === -1 ? $$(e[0]).addClass("selected") : h < e.length - 1 && ($$(g).removeClass("selected"), $$(e[h + 1]).addClass("selected")))
}.bind(this))
};
f.prototype.initInputField = function () {
this.tokenInput = new k("uris");
this.tokenInput.callback = this.onURISearch;
this.tokenInput.searchHandler = this.searchHandler;
this.tokenInput.resultHandler = this.onSearchResults;
var b = document.createElement("div");
b.tabIndex = 1;
$$(b).addClass("auto-complete");
$$(b).addClass("show");
$$(b).addClass("search");
this.tokenInput.node.appendChild(b);
this.widgetContainer.adopt(this.tokenInput.node);
for (var a = 0, c = d.length; a < c; a++) {
var e = document.createElement("div");
$$(e).addClass(d[a]);
$$(e).addClass("search");
var f = document.createElement("span");
f.textContent = d[a];
e.appendChild(f);
b.appendChild(e)
}
return this
};
f.prototype.clear = function () {
this.tokenInput.input.value = "";
this.tokenInput.input.focus();
this.setInitialResults();
return this
};
k.prototype.addTokens = function (b, a) {
var c = this.node.getElement("." + a);
c && (c.setStyle("display", "block"), this.clear(c), b.each(function (b) {
c.getElements("a");
var d = document.createElement("a"),
e = document.createElement("div");
d.uri = b.uri;
d.href = b.uri.replace("spotify:", "spotify:radio:").decodeForLink().toSpotifyURL();
d.addClass("search");
var f = new Image;
e.addClass("searchImg");
e.addClass("sp-image-placeholder-visible");
d.appendChild(e);
f.onload = function (b) {
n.setBg(b, d)
};
f.src = b.image;
if (b.imageForSize) f.src = b.imageForSize(60);
if (b.item) f.src = b.item.imageForSize(60);
e = document.createElement("strong");
e.textContent = b.name.decodeForText();
d.appendChild(e);
c.appendChild(d);
n.decorate(a, d, i)
}))
};
k.prototype.clear = function (b) {
b.getElements("a").each(function (b) {
b.parentNode && b.parentNode.removeChild(b)
});
return this
};
k.prototype.disable = function () {
this.input.disabled = !0;
return this
};
k.prototype.enable = function () {
this.input.disabled = !1;
return this
};
l.SearchWidget = f
})(r["$api/search"].Search, r["scripts/eventhandler"], r["scripts/searchUtil"], r["$api/models"].Observable, r["$api/models"])
});
_unrequire("scripts/genreDict", [], function (l) {
l.gd = {
alternative: ["Alternative", 1, "spotify:mosaic:1207d776aa45b693cad70ef95450dc8e0db18d83:47e2da2028246491b0478e406cfdba230ff5b1fa:597def07fa6398d6d35b90d181265fb75424bac5:d386c2a1d1dc719c2940254830831c97c1a8ff0a"],
black_metal: ["Black Metal", 2, "spotify:mosaic:ddbde13be788ae958a3fbbcef448dbf199610b5f:c3edd0e8343dcf84f04d5788df6a93ec3b0654e2:897f6ac957c4e42907646e6c6624273ea65a005b:f6ab9901b9eee306bd1425911ea0bc722d76cfa4"],
blues: ["Blues", 4, "spotify:mosaic:e94afef050d571055224f89d2b5d29ba9e3b9300:91b2278c242c141aebc5f4164cf1e4eaa9c1e9d5:96175d5bda99b24fd05c614137f76f5c5fc31e21:cb6c654d4fc2a4d78ff00be187d95467424096df"],
classical: ["Classical", 8, "spotify:mosaic:fcfc1d5444184b2036664bed9426668ddf0a9fd0:6a69b6cad2ea198a12e4e77fa6cbc5b3875656a6:f91adc2448a5c7b5adb18fc85bf90fc6c9d6d64f:09890f2fd461a1c577afbc42be97363c32b5d49e"],
country: ["Country", 16, "spotify:mosaic:f7641a20c01f7758d58c9d364b13d7edd0e879cd:945e69e836de6b244ca6019ecac26ac4cf229ba7:4c8d5465f8bf657f91837dd15154124c8bbf247a:050cb4785cff6411b62b829b9beb2bc063fb5dd3"],
dance: ["Club/House", 32, "spotify:mosaic:7cd9eb1ae4d684ca87228a90e667008393aaa881:d25f570e5a25bb0f746c2a3e86f906abde0ac281:6b8ec3aee1c373572e32ba0e967cc1cf022faaba:588ffff3ef8f1097aa816f0f00cb7bd0267816b3"],
death_metal: ["Death Metal", 64, "spotify:mosaic:dd184055dad8f57cd693683881ae39a9cf9c5582:9a82b57a4f208740bad05046e1ee876a8f7a1f91:3d921ff52b2a731465a0e8a2f92c5f8233ea02ad:45af8d31e3d994addf90fec7b0867b25dd594543"],
electronic: ["Electronic", 128, "spotify:mosaic:1196dcd5fe2fb9ce78f84f324f2a31dcd6f18b99:171c3048bdf313d824a30d4c52c8dc7bbcc58cfd:8311fdd10a0a9bc60170caaee8ef92e6f9487654:961f901c6b91af8cb640861db629914c0c8a980a"],
emo: ["Emo", 256, "spotify:mosaic:56ff711a44e4770a49f7c240bf228c577effc628:9b4183ba24fcb35cfe40edb6f2762c23fef4aa99:0dfeef9cc746cbf08c9848a929523ec5d088355f:0a919fa5734a469d282876f46825ce5509d33643"],
folk: ["Folk", 512, "spotify:mosaic:3facf19343a4e3204b5c1bf7676ba7f23b1a303e:38f73045ef7424f62d8bffbf304a183e4eb07269:84cb37746c836a900285d7ee0fdf6b2bbf8c7c3d:bb59d4023f2714d5057469f84a4554d2d31e1893"],
hardcore: ["Hardcore", 1024, "spotify:mosaic:e55c3e91200dd089ac78cc1a3c64dfbf3bc5370d:33ad1fb66fb6a45bb8b0f49b774b72188d05c61a:ab854c15cca135c88bb5a8e95373faee5b15166a:1a9cc1af8bc740a539255cdd256a1565e9180c67"],
heavy_metal: ["Heavy Metal", 2048, "spotify:mosaic:61fa42a2ad6c0d6cd57537b2c751b2c6c317758a:910a245bd2dafa05646683d70045bda63d524f2d:7a21c513cd94aff040ad695947321659c9e1b94b:7835b7891fb5d3dba8af1fa361bb600d65469308"],
hip_hop: ["Hip-Hop", 4096, "spotify:mosaic:9b9cc2b96384754810c46f5aa4d4ed89865615ff:753754a3f01bdcbe7c573ca8a74a6c2015ce7611:f55d28ca1a35496d1e41f4893763dd512dc820c0:b37fbe8e3be71234510cff162d1d1ef346336495"],
indie: ["Indie", 8192, "spotify:mosaic:7f6cebe3f3df4a95fde0931678abeab0e40308cd:c61bf879b941b4e3a11b2a46d70706ec788350bb:6620449cd7c56a9d17e068ec67a5645ef6561bb0:bf5c73dafeef02d42195cd42e007fe52d790befd"],
jazz: ["Jazz", 16384, "spotify:mosaic:7f3328e0ed8c9b64dba1bedf5a716226aaa719ad:31af688c12c57f7e5a750f7e678a4f5e9fc5c6dd:02d7097cf5c6383ad6523be736cfb6d916403dfe:9b90ff4da7042657cebba3852e67179baa59c4d5"],
latin: ["Latin", 32768, "spotify:mosaic:4c53a95cc9e6f3f5e93d597be203d7399def992f:4b762fb152e807048cbc026f30bc207d2c829294:642a6caa913fa93829a740b1a3122d195c2cdda1:876cd17f5274d28d153163e83ecf6f26da2b621b"],
pop: ["Pop", 65536, "spotify:mosaic:2abc9491a29d418572d1c0a555dc27217b9e29db:c9a3235bd39a917d588ff1bed66d788cc95bb1bb:b1720e5ca90f9a6428d97a72839cb9b1fe0d9883:0b44e33dd6deefd66e47bf183b04649017fc0552"],
punk: ["Punk", 131072, "spotify:mosaic:ba0aac39d5de6872e28acfeaaca2090eafad3cc2:f2d77487e24929bb389b99081574f8b6810863a6:767e92219e253bc83abab74d6c6dd166499222f1:772a723d0e4970a7f43a8ea4c73d70daeffd7d76"],
reggae: ["Reggae", 262144, "spotify:mosaic:8c06a3c655a3c52cd8cbfb2b5c299f61038e1930:4a07511acf0a83324021e80b7d677f0e66cc483a:e2f9fc0aa7180e037d05c9cf42ac1df730470d42:cf377968f983f926ba6ea6c2167f1f119a65bea6"],
r_n_b: ["R&B", 524288, "spotify:mosaic:8fe5e06c997bc793176af7daeefb43ca07636add:397c26076714475fff46b6cd88db8bb9f421ead6:c8c59aa15f5a52287ed354c9fc65eb6ff74e4c3d:ae763483112428a4336e6ec6323bf79228975789"],
rock: ["Rock", 1048576, "spotify:mosaic:8d3a4a465d857afc78734a8924766bde30260151:a0f1f0457556d6628ad90bf81fd751c061c2d1ba:f1a986d8044336ae6b09b5556cb4e140284cc0b0:1b20bd802ecea1cb1e3e35225debf7744294bda4"],
singer_songwriter: ["Singer-Songwriter", 2097152, "spotify:mosaic:37c7c980c10268efce2f20c6992195bd87a26302:582e3edd5030b7d2d240f09652306c62f9afda9d:6bacef6930b03b43826d0e855ea0b29fa06c2e82:8a99c564dd9be04b255c96050ab039d3250ce7d1"],
soul: ["Soul", 4194304, "spotify:mosaic:74b0d6d7750805926fd459cf114c010510339538:009c43b2bf76a6fa3ed621838f770ebdb393d16a:d4559fcf57b05a0b50a1bfc10cbc1ab1223b0fba:3f86a43016c0f207f12fd4a32da7a567be0d0a09"],
trance: ["Trance", 8388608, "spotify:mosaic:50f92f42b47f048754af4a808a1aca181590e7e8:99e94b809a68b8e37b9bb371535f2b252c213719:b4ad7cf639abd7dcb7f72d7c5888b4986f7dd24e:3ccfcc35121591808ae35c1ee98abc9352f302f7"],
"60s": ["60s", 16777216, "spotify:mosaic:bc2796fd1244da0dd756f12138cb7d918996b301:86be7f57948fa7f3a39c5a56dc5ca2fdb137e1b1:1c9a73dd3c378cd3c521bd01317a3faabcb47817:431b250293487ad8fcdbe490b7c6e21711d0d57e"],
"70s": ["70s", 33554432, "spotify:mosaic:9f55557d77188544d1c9fe3a24bbf8356fd1cf52:5049ca63240c296644f13c4f2eadfa6e7a68f4b0:3326e1f51f1eb147c3b24a4b828ed5f1191e09db:bd1dae68bd817e11177e7eb58a4eb9faa41d7ef1"],
"80s": ["80s", 67108864, "spotify:mosaic:56b7bec5311cee3945a8eceed91778ad13c083d9:25053d53407cfaaa378a8cad745caaea33204503:fc74c5a8e560a296c6c336a2ef73efe2081741ec:59168df306885f6d2f44ad96e6cb8ebb678cbdea"],
"90s": ["90s", 134217728, "spotify:mosaic:7faf97f3580957f9568592e874fb2e3539149817:84851eb084a308fbdf860174d8835b5e72d9548e:0418233365825a89632d628a9a5b1f69f615f7d0:72a43570b40b67b6efbf3128188a211d95ec043a"]
}
});
_unrequire("scripts/RecentStations", [], function (l) {
l.RecentStations = function (l, e, n) {
var j = {}, i = [],
k = function (a) {
var c;
switch (a.type) {
case "track":
c = {
title: a.track.name,
titleUri: a.album.uri,
imageUri: a.album.image,
subtitle: a.artist.name,
subtitleUri: a.artist.uri
};
break;
case "album":
c = {
title: a.album.name,
titleUri: a.album.uri,
imageUri: a.album.image,
subtitle: a.artist.name,
subtitleUri: a.artist.uri
};
break;
case "artist":
c = {
title: a.artist.name,
titleUri: a.artist.uri,
imageUri: a.artist.image,
subtitle: "",
subtitleUri: ""
};
break;
case "genre":
c = {
title: a.genre.name,
titleUri: "",
imageUri: a.genre.mosaic,
subtitle: "",
subtitleUri: ""
};
break;
case "playlist":
c = {
title: a.playlist.name,
titleUri: a.playlist.uri,
imageUri: a.playlist.uri,
subtitle: "",
subtitleUri: ""
}
}
if (c.imageUri.indexOf("http") > -1) {
var e = c.imageUri.split("/");
c.imageUri = "spotify:image:" + e[e.length - 1]
}
c.seeds = [a.seed];
return c
}, h = function (a, c, f) {
var b = l.get("hm://radio/stations/", [e.type("Station")], [e.type("Station")]);
b.method = "POST";
b.send(a).done(function (b) {
j[c.seed] = b[0];
i.push(b[0]);
f(b[0])
}).fail(function () {})
}, c = function (a, c) {
var e = k(a);
setTimeout(function () {
a.type ===
"playlist" ? n.buildPlaylistMosaic(a.playlist.image, function (b) {
e.imageUri = b;
h(e, a, c)
}) : h(e, a, c)
}, 20);
c(e)
}, a = function (a, c) {
var f = j[a.seed];
setTimeout(function () {
var a = l.get("hm://radio/stations/" + f.id, [], [e.type("Station")]);
a.method = "TOUCH";
a.send(f).done(function () {}).fail(function () {})
}, 50);
c(f)
};
return {
list: function (a) {
i.length > 0 ? a(i) : l.get("hm://radio/stations/", [e.type("StationList")], []).send().done(function (c) {
if (c && c[0] && c[0].stations && c[0].stations.length) for (var c = c[0].stations, e = 0; e < c.length; e++) {
var b = c[e];
b.id && b.title && b.imageUri && b.seeds && b.seeds.length && !j[b.seeds[0]] && (i.push(b), j[b.seeds[0]] = b)
}
a(i.concat([]))
}).fail(function () {
a(null)
})
},
store: function (d, e) {
j[d.seed] ? a(d, e) : c(d, e)
},
getId: function (a) {
return j[a] ? j[a].id : null
}
}
}
});
_unrequire("scripts/Feedback", [], function (l) {
l.Feedback = function (l, e, n, j, i, k) {
var h, c, a = function () {
j.call(this)
};
a.prototype = new j;
h = new a;
h.addFeedback = function (a, g, f) {
f === "up" && c.addToLiked(a);
a = {
uri: a.replace("spotify:track:", ""),
type: f
};
g = l.get("hm://radio/stations/" + g + "/feedback/", [], [e.type("Feedback")]);
g.method = "POST";
g.send(a).done(function () {
h.dispatchEvent({
type: "feedback-added",
thumbType: f
})
}).fail(function () {})
};
c = i.LikedPlaylist(l, e, n, k);
return h
}
});
_unrequire("scripts/LikedPlaylist", [], function (l) {
l.LikedPlaylist = function (l, e, n, j) {
var i = null,
k = null,
h = function () {
return function () {}
}, c = function (a) {
a.tracks.add(i).done(function () {}).fail(function () {})
}, a = function (a) {
j.Playlist.fromURI(a).load(["name", "subscribed", "tracks"]).done(function (a) {
var b = ["Liked from Radio",
"Radio-Favoriten", "Favoritas de la radio", "Favoris des radios", "Radio-favorieten"];
a.subscribed && b.indexOf(a.name) !== -1 ? c(a) : f()
}).fail(h("Could not load playlist"))
}, d = function (a) {
k = a.uri;
var b = l.get("hm://radio/liked-playlist", [], [e.type("LikedPlaylist")]);
b.method = "PUT";
b.send({
uri: a.uri
}).done(function () {}).fail(h("could not store playlist uri on server"));
a.load(["tracks"]).done(c).fail(h("Could not load playlist"))
}, g = function (a) {
a.load(["uri"]).done(d).fail(h("Could not load new playlist"))
},
f = function () {
j.Playlist.create("Liked from Radio").done(g).fail(h("Could not create playlist"))
}, b = function (b) {
var c;
if (b && b.length > 0 && b[0].uri) c = b[0].uri;
c ? (k = c, a(c)) : f()
};
return {
addToLiked: function (c) {
i = j.Track.fromURI(c);
k ? a(k) : l.get("hm://radio/liked-playlist", [e.type("LikedPlaylist")], []).send().done(b).fail(h("Could not fetch playlist from backend"))
}
}
}
});
_unrequire("scripts/radio", "$api/models,$api/hermes,$api/toplists,scripts/imageCarousel,scripts/util,scripts/strings.json,scripts/eventhandler,scripts/cloud,scripts/ui,scripts/station,scripts/searchWidget,scripts/genreDict,scripts/RecentStations,scripts/Feedback,scripts/LikedPlaylist,$views/image".split(","),
function (l) {
(function (q, e, n, j, i, k, h, c, a, d, g, f, b, r, t, x) {
function y(a, b, c) {
return a === "playlist" ? "spotify:user:" + c + ":" + a + ":" + b : a === "starred" ? "spotify:user:" + c + ":starred" : "spotify:" + a + ":" + b
}
var w, z, u = function (a, b) {
if (a in k) {
if (b) {
var c = k[a];
return b in c ? c[b] : b
}
return k[a]
} else return a
}, p = function () {
this.topArtists = [];
this.topTracks = [];
this._recent = {
stations: [],
imageCarousel: null
};
this._currentTrack = null;
this._loadingStation = !1;
this._stations = [];
this._currentStation = null;
this._leftRadio = !1;
this._openUri = !0;
this.genreDict = f.gd;
this._models = q;
this.hermes = e;
w = n.Toplist.forCurrentUser();
z = n.Toplist.forWorld();
this.util = i;
this.enStrings = k.strings;
this.ui = a;
this._handler = h;
this._station = d;
this._ = u;
this.schema = this.hermes.Schema.fromURL(["/static/proto/radio.proto"]);
this.util.init(q, f.gd, x);
this.init()
};
p.prototype.init = function () {
var d = this;
d.ui = a = new a.RadioUi(c, d, d._handler, j);
d._loadTopStations(w);
try {
this._recent.stations = JSON.parse(localStorage.getItem("RecentStations")) || []
} catch (f) {}
this._RecentStations = b.RecentStations(e.Hermes, d.schema, d.util);
this._Feedback = r.Feedback(e.Hermes, d.schema, d.util, d._models.Observable, t, q);
this._Feedback.addEventListener("feedback-added", function (a) {
d._feedbackAdded(a)
});
this._recent.imageCarousel = new j.ImageCarousel("#recent", u("Your Stations"), k, d.util);
d._RecentStations.list(function (b) {
d._startStationFromArguments(null, function (c) {
if (b && b.length > 1) d._recent.stations = b, d.ui.fillRecentStationList(b), c || d._showStation(d._recent.stations[0].seeds[0], "recent");
else if (d._recent.stations && d._recent.stations.length > 0 && d._recent.stations[0].seeds) d.ui.fillRecentStationList(d._recent.stations), c || d._showStation(d._recent.stations[0].seeds[0], "recent");
else if (!d._recent.stations || d._recent.stations.length < 1) d.firstTime = !0, a.firstTime(), c || d._showStation(d.topArtists[0].uri, "recommended")
})
});
d.searchWidget = new g.SearchWidget($$(".auto-completeForm"), d.util);
d.searchWidget.onEnter = d.ui.handleClick;
d.searchWidget.addEventListener("open-uri", function (a) {
d._startStation(a)
});
d.ui.addEventListener("show-search",
d.searchWidget.show);
d.ui.addEventListener("hide-search", d.searchWidget.hide);
d.ui.addEventListener("thumb", function (a) {
d.thumb(a)
});
d._models.session.load(["user", "online"]).done(function () {}).fail(function () {});
a.addEventListener("start-station", function (a) {
d._startStation(a)
});
a.addEventListener("play-pause", function () {
d._playPause()
});
a.addEventListener("skip", function () {
d._skip()
});
a.adjustHeaderWidth();
a.fillGenres();
d._models.application.addEventListener("arguments", function (a) {
d._startStationFromArguments(a.data.arguments)
});
d._thumbed = !1
};
p.prototype._feedbackAdded = function () {
this._currentStation.thumbEvent();
this._thumbed = !1
};
p.prototype._displayThumbed = function (a) {
var b = this;
b._currentStation.feedback && b._currentStation.feedback[a.uri] && setTimeout(function () {
b._currentStation.feedback[a.uri] === "up" && b.ui.displayThumbUp();
b._currentStation.feedback[a.uri] === "down" && b.ui.displayThumbDown()
}, 1E3)
};
p.prototype.thumb = function (a) {
a = a.thumbType;
if (this._currentStation.id && this._currentStation.id.length > 0) if (a === "down") this._thumbed =
"down", this._skip();
else if (a === "up") this._thumbed = "up", this._Feedback.addFeedback(this._currentTrack.uri, this._currentStation.id, "up")
};
p.prototype.getCurrentStation = function () {
return this._currentStation
};
p.prototype._addRecentStation = function (a) {
if (a) {
var b = this,
c = this._recent.stations,
d = !0;
c && c.length > 0 && c[0].seeds[0] === a.seed && (d = !1);
var e = function (a) {
var e;
for (e = 0; e < c.length && c[e].seeds[0] !== a.seeds[0]; e++);
c.splice(e, 1);
c.splice(0, 0, a);
c.splice(20);
d && b.ui.fillRecentStationList(c);
localStorage.setItem("RecentStations",
JSON.stringify(c))
};
b._RecentStations.store(a, function (a) {
if (a.id) b._currentStation.id = a.id;
c.length < 1 ? e(a) : c.length > 0 && c[0].seeds[0] !== a.seeds[0] && e(a)
})
}
};
p.prototype._preloadImages = function () {
var a = this;
setTimeout(function () {
a._currentStation._temporaryPlaylist.tracksCache.shift();
for (var b = 0; b < 3; b++) {
var c = a._currentStation._temporaryPlaylist.tracksCache.shift();
if (c && c.image)(new Image).src = c.image
}
}, 50)
};
p.prototype._newTrack = function (a) {
a = a.track;
if (!(this._currentTrack && a.uri === this._currentTrack.uri)) this._preloadImages(),
this._currentTrack = a, this.ui.rotateCovers(a), this.ui.updatePlayPause(!0), this._displayThumbed(a)
};
p.prototype._isPlaying = function () {
this.ui.updatePlayPause(!0)
};
p.prototype._leavingRadio = function () {
this._leftRadio = !0;
this.ui.updatePlayPause(!1)
};
p.prototype._paused = function () {
this.ui.updatePlayPause(!1)
};
p.prototype._skip = function () {
var a = this,
b = a._currentStation;
a._startedPlay && !a._leftRadio ? a._thumbed === "down" ? b.skipTrack(function () {
a._Feedback.addFeedback(a._currentTrack.uri, a._currentStation.id,
"down")
}) : b.skipTrack() : (a._leftRadio ? (a._startPlaying({
playlist: b._temporaryPlaylist,
index: a._currentStation.index + 1
}), a._leftRadio = !1) : (a._startPlaying({
playlist: b._temporaryPlaylist,
index: 1
}), a._startedPlay = !0), a._thumbed === "down" && a._Feedback.addFeedback(a._currentTrack.uri, a._currentStation.id, "down"))
};
p.prototype._loadStation = function (a, b) {
var c = this;
c._startedPlay = b;
c._loadingStation = !0;
c.ui.loadingStation();
try {
var d = new this._station.Station(this, c._RecentStations.getId(a));
if (!d) return null;
d.addEventListener("stationAvailable", function (a) {
c._loadingStation = !1;
d.addEventListener("track-added", function (a) {
c._trackAdded(a)
});
d.addEventListener("start-playing", function (a) {
c._startPlaying(a)
});
d.addEventListener("leavingRadio", function () {
c._leavingRadio()
});
d.addEventListener("is-playing", function () {
c._isPlaying()
});
d.addEventListener("new-track", function (a) {
c._newTrack(a)
});
d.addEventListener("paused", function () {
c._paused()
});
d.addEventListener("track-end", function () {
c.trackEnd()
});
c._currentStation = null;
c._currentStation = d;
if (!c.psc) c.psc = function (a) {
c._currentStation && c._currentStation.playerStateChanged(a)
}, q.player.addEventListener("change", c.psc);
c._stationAvailable(a)
});
d.addEventListener("failed-station", function () {
c._loadingStation = !1;
c.ui.failedStation()
});
d.loadStation(a, b);
return d
} catch (e) {
return null
}
};
p.prototype.trackEnd = function () {
this.ui.disableThumbs()
};
p.prototype._trackAdded = function (a) {
a = a.track;
this._preloadImages();
this._currentTrack = a;
this.ui.rotateCovers(a);
this._displayThumbed(a)
};
p.prototype._stationAvailable = function (a) {
var b = this,
c = a.trackSource,
d = a.originalSeed,
e = a.startPlay;
if (b.firstTime) b.firstTime = !1;
b.util.getSeedMetadata(d, function (a) {
b.ui.stationAvailable(c, d, a, e);
b._addRecentStation(a)
}, null, !0);
b._models.application.clientEvent("", "loadstation", "1", "1", {
source: b.startApp,
context: "",
element: b.startSource,
target: d,
targetsource: c
});
b._openUri && b._models.application.openURI(d.replace("spotify", "spotify:app:radio"), !0);
b._openUri = !0
};
p.prototype._showStation = function (a,
b) {
this._loadStation(a, !1);
this.startApp = "spotify:app:radio";
this.startSource = b
};
p.prototype._startStation = function (a) {
var b = a.seed,
c = a.elClass,
d = "spotify:app:radio";
a.app > 2 && (d = "spotify:app:" + a.app);
this.startApp = d;
if (c.indexOf("recent") > -1) this.startSource = "recent";
else if (c.indexOf("recommended") > -1) this.startSource = "recommended";
else if (c.indexOf("search") > -1) this.startSource = "search";
else if (c.indexOf("genre") > -1) this.startSource = "genre";
else if (c.indexOf("external") > -1) this.startSource = "external";
this._loadStation(b, !0)
};
p.prototype._startStationFromArguments = function (a, b) {
var c = this,
d = function (a) {
if (a.length < 2) b && b();
else {
var d = unescape(a[0]),
e = unescape(a[1]);
if ((a.length === 2 || a.length === 3 || a.length === 4) && (d === "album" || d === "artist" || d === "track" || d === "user" || d === "genre")) {
var f = d,
g;
f === "user" ? (d = unescape(a[1]), a.length === 4 && (f = "playlist", e = unescape(a[3]), g = y(f, e, d)), a.length === 3 && (f = "starred", g = y(f, null, d))) : g = y(d, e);
if (c._currentStation && g !== c._currentStation.originalSeed || !c._currentStation) c._openUri = !1, c._startStation({
seed: g,
elClass: "external",
app: f
});
b && b(!0)
} else b && b(!1)
}
};
a ? d(a) : c._models.application.load("arguments").done(function (a) {
d(a.arguments)
}).fail(function () {})
};
p.prototype._topStationsDone = function () {
this._fillTopStations();
this.searchWidget.setInitialResults({
artists: this.topArtists.slice(0, 3),
tracks: this.topTracks.slice(0, 3)
})
};
p.prototype._loadTopStations = function (a, b) {
var c = this,
d = 0,
e = function () {
d += 1;
d === 2 && (c.topTracks.length > 0 && c.topArtists.length > 0 ? c._topStationsDone() : b ? c._topStationsDone() : c._loadTopStations(z, !0))
};
a.artists.snapshot(0, 10).done(function (a) {
c.util.getTopArtists(a, c._models.Promise, function (a) {
c.topArtists = a;
c.firstTime && c._showStation(c.topArtists[0].uri, "recommended");
e()
})
}).fail(function () {
e()
});
a.tracks.snapshot(0, 10).done(function (a) {
c.util.getTopTracks(a, c._models.Promise, function (a) {
c.topTracks = a;
e()
})
}).fail(function () {
e()
})
};
p.prototype._fillTopStations = function () {
for (var a = this.topArtists, b = this.topTracks, c = [], d = !0, e = 0, f = 0; d;) d = !1, a.length > e && (c.push(a[e]), e += 1, d = !0), b.length > f && (c.push(b[f]), f += 1, d = !0);
this.ui.fillTopList("#topstations", u("Recommended Stations"), c)
};
p.prototype._loadStationFromLinksChanged = function () {
var a = sp.core.getLinks();
return a.length ? (this._loadStation(a[0], "spotify:app:radio", "", "drop", !0), !0) : !1
};
p.prototype._startPlaying = function (a) {
q.player.playContext(a.playlist, a.index || 0).done(function () {}).fail(function () {})
};
p.prototype._playPause = function () {
var a = this;
if (a._leftRadio) {
a._leftRadio = !1;
var b = a._currentStation,
c = 0;
if (b.index > 0) c = b.index;
a._startPlaying({
playlist: b._temporaryPlaylist,
index: c
})
} else a._startedPlay ? q.player.load(["playing"]).done(function (b) {
!a._leftRadio && a._startedPlay && b.playing ? q.player.pause() : q.player.play()
}).fail(function () {}) : (b = a._currentStation, a._startedPlay = !0, a._startPlaying({
playlist: b._temporaryPlaylist
}))
};
l.Radio = p
})(r["$api/models"], r["$api/hermes"], r["$api/toplists"], r["scripts/imageCarousel"], r["scripts/util"], r["scripts/strings.json"], r["scripts/eventhandler"], r["scripts/cloud"],
r["scripts/ui"], r["scripts/station"], r["scripts/searchWidget"], r["scripts/genreDict"], r["scripts/RecentStations"], r["scripts/Feedback"], r["scripts/LikedPlaylist"], r["$views/image"].Image)
});
_unrequire("main", ["scripts/radio", "scripts/util"], function () {
window.env !== "test" && new r["scripts/radio"].Radio
})
})(SpotifyApi.api, SpotifyApi.api._modules);
// https://play.spotify.com/static/proto/radio.proto
// 15/12/2012
package spotify.radio.proto;
message RadioRequest {
repeated string uris = 1; // For a playlist, this will be a list of 20 sampled tracks
optional int32 salt = 2; // If set to 0, it will trigger the old behavior where all 250 tracks are returned
// optional int32 offset = 3; // DEPRECATED
optional int32 length = 4;
optional string stationId = 5; // This is used only for decorating with thumbs up/down, not to pull the uris
repeated string lastTracks = 6; // spotify uri's with spotify:track: stripped
}
// Deprecated
message MultiSeedRequest {
repeated string uris = 1;
}
message Feedback { // i.e. thumb
optional string uri = 1; // omit the spotify:track: prefix
optional string type = 2;
optional double timestamp = 3;
}
// Result from a radio station request
message Tracks {
repeated string gids = 1;
optional string source = 2;
optional string identity = 3;
repeated string tokens = 4; // As many as there are tracks
repeated Feedback feedback = 5; // all thumbs for the station among the tracks returned (no particular order)
}
message Station {
optional string id = 1;
optional string title = 2;
optional string titleUri = 3; // If it's a playlist then this will be a playlist uri
optional string subtitle = 4;
optional string subtitleUri = 5; // For a track radio this will be the artist, etc..
optional string imageUri = 6;
optional double lastListen = 7; // Used for sorting
repeated string seeds = 8; // Not really used today. This should essentially be a list with only [titleUri]
optional int32 thumbsUp = 9;
optional int32 thumbsDown = 10;
}
// Reponse for rules request. Contains the javascript as a string.
message Rules {
optional string js = 1;
}
message StationResponse {
optional Station station = 1;
repeated Feedback feedback = 2;
}
message StationList {
repeated Station stations = 1;
}
message LikedPlaylist {
optional string uri = 1;
}
/*
* https://spapps.spotify.edgekey.net/shared/a1f45b7/scripts/main.js
*
* 15/12/2012
*/
(function () {
_unrequire("$shared/slab", [], function (n) {
(function (o) {
var p, e, h, g, j, k, i, n, w, x, t, y, z, A, B, C, D, E, F, G, u;
function l(a) {
var c = H.call(arguments, 1);
return function () {
return a.apply(null, c.concat(H.call(arguments)))
}
}
function K(a, c) {
return L[c]
}
function M(a, c, b) {
return "_strtmp = (" + q(a, b) + ').toString();%#=#%_buffer_ += _strs[_strtmp] ||(_strs[_strtmp] = _strtmp.replace(/&(?!\\w+;)/g, "&#38;").split("<").join("&#60;").split(">").join("&#62;").split("\\"").join("&#34;").split("\'").join("&#39;").split("/").join("&#47;"));%#=#%'
}
function N(a) {
a.pop();
a.pop();
return "} %#=#%"
}
function O() {
return "} else { %#=#%"
}
function P(a, c, b) {
return "} else if (" + q(a, b) + ") { %#=#%"
}
function Q(a, c, b) {
a.push(null, null);
return "if (" + q(a, b) + ") { %#=#%"
}
function R(a, c, b, d, f) {
d || (b = (d = b, "iterator" + r++));
c = "length" + r++;
f = s(a, f);
a.push(b, d);
return "for (var " + b + " = 0, " + c + " = " + f + ".length; " + b + " < " + c + "; " + b + "++) { %#=#%var " + d + " = " + f + "[" + b + "]"
}
function S(a, c, b, d, f) {
d || (b = (d = b, "iterator" + r++));
f = s(a, f);
a.push(b, d);
return "for (var " + b + " in " + f + "){ %#=#%if (!" + f + ".hasOwnProperty(" + b + ")) continue; %#=#%var " + d + " = " + f + "[" + b + "]"
}
function T(a, c, b, d, f) {
d || (b = (d = b, "iterator" + r++));
f = s(a, f);
a.push(b, d);
return "for (var " + b + " in " + f + "){ %#=#%var " + d + " = " + f + "[" + b + "]"
}
function s(a, c) {
var b = c,
d = c.match(p);
d && (c = d[1]);
return e.test(c) ? c : c.charAt(0) == "." || a.indexOf(c) != -1 || U[c] ? b : "_data_." + b
}
function V(a) {
return a.slice(2)
}
function q(a, c) {
var b = {}, d = 0;
return c.replace(h, function (a, c) {
b[c = "%#%" + d+++"%#%"] = a;
return c
}).replace(g, l(s, a)).replace(e, V).replace(j, function (a) {
return b[a]
})
}
function W(a, c, b) {
var c = '"; %#=#%',
d = b = b.replace(k, K),
b = b.replace(i, O).replace(n, l(P, a)).replace(w, l(Q, a)).replace(x, l(R, a)).replace(t, l(S, a)).replace(t, l(T, a)).replace(y, l(N, a)).replace(z, l(M, a));
b == d && (c += "_buffer_ += ", b = q(a, b));
return c + b.replace(/\t|\n|\r/, "") + '; %#=#%_buffer_ += "'
}
function m(a) {
this.message = a
}
function I() {
this._templates = {};
this._parsed = {};
this._cache = {}
}
function X(a, c, b, d) {
if (c.indexOf(d) != -1) throw c.push(d), new m('Recursive includes for template "' + d + '" (' + c.join(" > ") +
").");
c.push(d);
a = a[d];
if (!a) throw new m('Cannot find template named "' + d + '" (' + c.join(" > ") + ").");
return a
}
function Y(a, c) {
for (var b = l(X, c, []); a != (a = a.replace(C, b)););
return a
}
function Z(a, c) {
var b = c._cache;
if (b[a]) return b[a];
var d = {}, f = 0,
e = a.replace(D, function (a, b) {
d[a = "%#%E" + f+++"%#%"] = b;
return a
}).replace(E, l(W, [])).replace(F, function (a) {
return d[a]
});
return b[a] = ('%#=#%_buffer_ += "' + e + '";').replace(/_buffer_\s\+=\s"";/g, "").replace(/\n/g, "\\n").replace(/\t/g, "\\t").replace(/\r/g, "\\r").replace(A,
"\n").replace(B, "\n")
}
function v(a, c) {
if (!a) throw new m("Template string cannot be empty.");
if (c && !(c instanceof I)) throw new m("Object passed is not a Slab object.");
var a = a.replace(RegExp("\\\\", "g"), "\\\\").replace(/"/g, '\\"'),
c = c || new I,
b = a.replace(G, "").match(u);
if (!b) throw new m("No valid templates found in string.");
for (var d = b.length, f = c._templates, e = c._parsed, g; d--;) {
var h = b[d].replace(u, function (a, b, c) {
g = b;
return c
});
f[g] = h
}
for (var i in f) b = Y(f[i], f), e[i] = Z(b, c);
return c
}
function J(a, c) {
return 'var _buffer_ = "", _strs = {}, _strtmp;' + a + "\nreturn _buffer_;\n// @sourceURL=" + c
}
u = /\{slab\s+([$A-Za-z_][$0-9A-Za-z_]*)\}([^]*?)\{endslab\}/g;
G = /\{\*[^]*?\*\}/g;
D = /\{keep\}([^]*?)\{endslab\}/g;
F = /(%#%)E[0-9]+\1/g;
A = /%#=#%/g;
B = /\n;\s*\n/g;
h = /('|").*?\1/g;
j = /(%#%)[0-9]+\1/g;
g = /\.?[$A-Za-z_][$0-9A-Za-z_]*/g;
e = /__[$0-9A-Za-z_]*/g;
p = /^([$A-Za-z_][$0-9A-Za-z_]*)\./;
k = /\s+(and|or|eq|neq|is|isnt|not)\s+/g;
E = /\{\s*([^}]+?)\s*\}/g;
z = /^:\s*(.+)/;
y = /^end$/;
i = /^else$/;
n = /^else\s+if\s+(.+)$/;
w = /^if\s+(.+)$/;
x = /^each\s+([$A-Za-z_][$0-9A-Za-z_]*)(?:\s*,\s*([$A-Za-z_][0-9A-Za-z_]*))?\s+in\s(.+)$/;
t = /^for\s+([$A-Za-z_][$0-9A-Za-z_]*)(?:\s*,\s*([$A-Za-z_][0-9A-Za-z_]*))?\s+in\s+(.+)$/;
C = /\{include\s+([$A-Za-z_][$0-9A-Za-z_]*)\}/g;
var H = Array.prototype.slice,
L = {
and: " && ",
or: " || ",
eq: " === ",
neq: " !== ",
not: " !",
isnt: " != ",
is: " == "
}, r = 0,
U = {
"true": 1,
"false": 1,
"null": 1,
undefined: 1,
"typeof": 1,
"instanceof": 1,
"if": 1,
"else": 1,
_data_: 1
};
m.prototype = Error();
m.prototype.name = "SlabError";
var $ = 0;
o.slab = {
compile: function (a, c) {
var c = v(a, c),
b = c._parsed,
d;
for (d in b) {
var f = b[d];
try {
c[d] = new Function("_data_",
J(f, d))
} catch (e) {
throw new m("Can't compile slab template. " + e.message);
}
}
return c
},
parse: v,
generate: function (a, c, b) {
a || (a = "slabTemplate" + $++);
var b = v(c, b),
c = [],
b = b._parsed,
d;
for (d in b) c.push(d + ": function(_data_){\n" + J(b[d], a) + "\n}");
return "var " + a + "= {\n" + c.join(",\n") + "};"
}
}
})(typeof n != "undefined" ? n : this)
})
})(SpotifyApi.api, SpotifyApi.api._modules);
(function () {
_unrequire("$shared/events", [], function (n) {
function o(e) {
this._handler = e || null;
this._listeners = []
}
function p(e, h, g, j) {
this.src = e;
this.type = h;
this.originalListener = g;
this.listener = j ? function () {
g.apply(j, arguments)
} : g
}
o.prototype.listen = function (e, h, g) {
e = new p(e, h, g, this._handler);
this._listeners.push(e);
e.listen();
return this
};
o.prototype.unlisten = function (e, h, g) {
var j = this._listeners;
if (g) for (var k = 0; k < j.length; k++) {
var i = j[k];
if (i.src === e && i.type === h && i.originalListener === g) {
i.unlisten();
j.splice(k, 1);
break
}
} else {
g = [];
for (k = 0; k < j.length; k++) i = j[k], i.src === e && i.type === h ? i.unlisten() : g.push(i);
this._listeners = g
}
};
o.prototype.removeAll = function () {
for (var e = this._listeners, h = 0; h < e.length; h++) e[h].unlisten();
e.splice(0)
};
p.prototype.listen = function () {
this.src.addEventListener(this.type, this.listener)
};
p.prototype.unlisten = function () {
this.src.removeEventListener(this.type, this.listener)
};
n.EventHandler = o
})
})(SpotifyApi.api, SpotifyApi.api._modules);
(function () {
_unrequire("$shared/placeholder", [], function () {})
})(SpotifyApi.api, SpotifyApi.api._modules);
/*
* https://play.spotify.edgekey.net/client/geeb4ad7/js/spotify.web.base.js
*
* 15/12/2012
*/
var Spotify = Spotify || {};
Spotify.Web = Spotify.Web || {};
Spotify.Web.Screens = Spotify.Web.Screens || {};
Spotify.Web.Storage = Spotify.Web.Storage || {};
var _ = function(c) {
return "undefined" != typeof spotLang && spotLang[c] ? spotLang[c] : c.replace("_", " ")
};
Spotify.Web.Dotter = function(c, f, a) {
var e = 0, d, b = c.innerHTML;
this.start = function() {
d || (d = setInterval(function() {
e++;
e > f && (e = 0);
for (var d = b, a = 0; a < e; a++)
d += ".";
c.innerHTML = d
}, a))
};
this.stop = function() {
d && clearInterval(d);
c.innerHTML = b
}
};
Spotify.Web.Authenticator = function() {
var c = !1, f = function(a, e, d) {
if (!c) {
c = !0;
var b = new XMLHttpRequest;
b.onreadystatechange = function() {
if (b.readyState === 4 && b.status === 200) {
setTimeout(function() {
c = !1
}, 1E3);
var a = JSON.parse(b.responseText);
a.status === "OK" ? e(a.config) : d(a.error)
}
};
b.open("POST", "/xhr/json/auth.php", !0);
b.setRequestHeader("Content-type", "application/x-www-form-urlencoded");
b.send(a)
}
};
this.authenticateWithFacebookCredentials = function(a, e, d, b, c) {
a = "type=fb&fbuid=" + encodeURIComponent(a) +
"&token=" + encodeURIComponent(e) + "&secret=" + encodeURIComponent(d);
f(a, b, c)
};
this.authenticateWithUsernameAndPassword = function(a, c, d, b, g) {
a = "type=sp&username=" + encodeURIComponent(a) + "&password=" + encodeURIComponent(c) + "&secret=" + encodeURIComponent(d);
f(a, b, g)
}
};
Spotify.Web.Screens.Intermediate = function(c) {
var f = new Spotify.Web.Authenticator, a = document.getElementById("login-screen"), e = document.querySelector("form #secret").value, d = !1, b = !1, g = function(a) {
document.getElementById("timeout").style.display = "block";
var b = new XMLHttpRequest;
b.open("GET", "/xhr/json/log.php?type=FB_CONNECTION_FAILED&error=" + (a || "unknown"), !0);
b.send()
}, h = function(a) {
if (b)
return !0;
return Spotify && Spotify.Web && Spotify.Web.App ? (setTimeout(function() {
b = !0;
Spotify.Web.App.initialize(a,
window.FB)
}, 1), !0) : !1
}, i = function(c) {
d = !0;
b = h(c);
if (!b)
var e = setInterval(function() {
h(c) && clearInterval(e)
}, 2E3);
a.className = "hidden";
setTimeout(function() {
a.style.display = "none"
}, 1E3)
}, k = function() {
g("account_creation_failed")
}, j = function() {
FB.init(c);
FB.getLoginStatus(function(a) {
a.status === "connected" ? f.authenticateWithFacebookCredentials(a.authResponse.userID, a.authResponse.accessToken, e, i, k) : g("not_connected")
})
};
this.init = function() {
var a = new XMLHttpRequest;
a.open("GET", "/xhr/json/log.php?type=INTERMEDIATE_JS_READY",
!0);
a.send();
setTimeout(function() {
d || g("timed_out")
}, 3E4);
window.fbAsyncInit = j;
var b = document.getElementsByTagName("script")[0];
if (!document.getElementById("facebook-jssdk"))
a = document.createElement("script"), a.id = "facebook-jssdk", a.async = !0, a.src = "//connect.facebook.net/en_US/all/vb.js", b.parentNode.insertBefore(a, b)
}
};
Spotify.Web.Screens.Login = function(c, f) {
var a = {invalid_credentials: _("Incorrect username and password"),invalid_country: _("Spotify is currently not available in your country"),capped: _("You have reached your maximum number of login attempts, please try again later"),service_unavailable: _("Service is currently unavailable. Please try again later"),fallback: _("Authentication failed. Please try again.")}, e = new Spotify.Web.Authenticator, d, b = !1, g = document.getElementById("fb-login-btn"), h = new Spotify.Web.Dotter(g,
3, 500), i = document.getElementById("sp-login-form"), k = document.getElementById("login-screen"), j = document.getElementById("login-method"), q = document.getElementById("bg-wrap"), r = document.getElementById("login-spotify"), s = document.getElementById("login-usr"), t = document.getElementById("login-cancel"), o = document.querySelector("#login .error"), l = i.querySelector('[name="secret"]').value, p = function(a) {
if (b)
return !0;
return Spotify && Spotify.Web && Spotify.Web.App ? (setTimeout(function() {
b = !0;
Spotify.Web.App.initialize(a,
window.FB)
}, 1), !0) : !1
}, m = function(a) {
b = p(a);
if (!b)
var c = setInterval(function() {
p(a) && clearInterval(c)
}, 2E3);
h.stop();
k.className = "hidden";
setTimeout(function() {
k.style.display = "none"
}, 1E3)
}, n = function(b) {
o.innerHTML = a[b] ? a[b] : a.fallback;
o.style.display = "block"
}, u = function() {
FB.init(c);
FB.getLoginStatus(function(a) {
d = a
})
}, v = function() {
i.addEventListener("submit", function(a) {
a.preventDefault();
var a = i.querySelector('[name="username"]').value, b = i.querySelector('[name="password"]').value;
e.authenticateWithUsernameAndPassword(a,
b, l, m, n)
});
j.addEventListener("dragstart", function(a) {
a.preventDefault()
});
r.addEventListener("click", function(a) {
a.preventDefault();
j.className = "flip";
s.focus()
});
t.addEventListener("click", function(a) {
a.preventDefault();
j.className = "unflip"
});
g.addEventListener("click", function(a) {
a.preventDefault();
h.start();
typeof d !== "undefined" && (d.status === "connected" ? e.authenticateWithFacebookCredentials(d.authResponse.userID, d.authResponse.accessToken, l, m, n) : FB.login(function(a) {
a.authResponse ? e.authenticateWithFacebookCredentials(a.authResponse.userID,
a.authResponse.accessToken, l, m, n) : h.stop()
}))
})
};
this.init = function() {
v();
var a = new Image;
a.onload = function() {
q.className = "loaded"
};
a.src = f;
window.fbAsyncInit = u;
var b = document.getElementsByTagName("script")[0];
if (!document.getElementById("facebook-jssdk"))
a = document.createElement("script"), a.id = "facebook-jssdk", a.async = !0, a.src = "//connect.facebook.net/en_US/all/vb.js", b.parentNode.insertBefore(a, b)
}
};
This file has been truncated, but you can view the full file.
/*
* https://play.spotify.edgekey.net/client/c46d547/js/spotify.web.client.js
*
* 2013-06-18
*/
/*
Copyright Spotify AB 2012. All rights reserved.
History.getInternetExplorerMajorVersion()
Get's the major version of Internet Explorer
@return {integer}
@license Public Domain
@author Benjamin Arthur Lupton <contact@balupton.com>
@author James Padolsey <https://gist.github.com/527683>
History.isInternetExplorer()
Are we using Internet Explorer?
@return {boolean}
@license Public Domain
@author Benjamin Arthur Lupton <contact@balupton.com>
History.js Core
@author Benjamin Arthur Lupton <contact@balupton.com>
@copyright 2010-2011 Benjamin Arthur Lupton <contact@balupton.com>
@license New BSD License <http://creativecommons.org/licenses/BSD/>
History.js HTML4 Support
Depends on the HTML5 Support
@author Benjamin Arthur Lupton <contact@balupton.com>
@copyright 2010-2011 Benjamin Arthur Lupton <contact@balupton.com>
@license New BSD License <http://creativecommons.org/licenses/BSD/>
SWFObject v2.2 <http://code.google.com/p/swfobject/> is released under the MIT License <http://www.opensource.org/licenses/mit-license.php>.
CryptoJS v3.1.2
code.google.com/p/crypto-js
(c) 2009-2013 by Jeff Mott. All rights reserved.
code.google.com/p/crypto-js/wiki/License
History.js Native Adapter
@author Benjamin Arthur Lupton <contact@balupton.com>
@copyright 2010-2011 Benjamin Arthur Lupton <contact@balupton.com>
@license New BSD License <http://creativecommons.org/licenses/BSD/>
parseUri 1.2.2.
@author Steven Levithan <stevenlevithan.com>
@license MIT License.
*/
Spotify.Web.ABTester = Spotify.Web.ABTester || {};
(function (d) {
function g(f) {
var k = 0,
m = q[f];
if (m) return m;
k = 0;
m = Array(1E4);
for (i = 0; i < m.length; i++) m[i] = i;
var c = b(h(a(f))),
k = parseInt(c.substring(0, 8), 16);
(function (f) {
for (var a = f.length - 1; a >= 1; a--) {
k = 16807 * k % 2147483647;
var m = k % (a + 1),
b = f[a];
f[a] = f[m];
f[m] = b
}
})(m);
return q[f] = m
}
function c(f, k) {
if (k && k.substring(0, 4) == "NTX_") {
var m = g(k),
c = parseInt(b(h(a("spotify:test:" + f))).substring(0, 8), 16),
c = Math.floor(1E4 * c * Math.pow(2, -32));
return Math.floor(m[c] / 10)
} else return m = "spotify:test:", k && (m += k + ":"), m +=
f, m = parseInt(b(h(a(m))).substring(0, 8), 16), Math.floor(1E3 * m * Math.pow(2, -32))
}
function h(a) {
for (var b = Array(a.length >> 2), c = 0; c < b.length; c++) b[c] = 0;
for (c = 0; c < a.length * 8; c += 8) b[c >> 5] |= (a.charCodeAt(c / 8) & 255) << c % 32;
a = a.length * 8;
b[a >> 5] |= 128 << a % 32;
b[(a + 64 >>> 9 << 4) + 14] = a;
for (var a = 1732584193, c = -271733879, h = -1732584194, d = 271733878, g = 0; g < b.length; g += 16) var q = a,
n = c, G = h, B = d, a = k(a, c, h, d, b[g + 0], 7, -680876936), d = k(d, a, c, h, b[g + 1], 12, -389564586), h = k(h, d, a, c, b[g + 2], 17, 606105819), c = k(c, h, d, a, b[g + 3], 22, -1044525330),
a = k(a, c, h, d, b[g + 4], 7, -176418897), d = k(d, a, c, h, b[g + 5], 12, 1200080426), h = k(h, d, a, c, b[g + 6], 17, -1473231341), c = k(c, h, d, a, b[g + 7], 22, -45705983), a = k(a, c, h, d, b[g + 8], 7, 1770035416), d = k(d, a, c, h, b[g + 9], 12, -1958414417), h = k(h, d, a, c, b[g + 10], 17, -42063), c = k(c, h, d, a, b[g + 11], 22, -1990404162), a = k(a, c, h, d, b[g + 12], 7, 1804603682), d = k(d, a, c, h, b[g + 13], 12, -40341101), h = k(h, d, a, c, b[g + 14], 17, -1502002290), c = k(c, h, d, a, b[g + 15], 22, 1236535329), a = m(a, c, h, d, b[g + 1], 5, -165796510), d = m(d, a, c, h, b[g + 6], 9, -1069501632), h = m(h, d, a, c, b[g + 11], 14, 643717713),
c = m(c, h, d, a, b[g + 0], 20, -373897302), a = m(a, c, h, d, b[g + 5], 5, -701558691), d = m(d, a, c, h, b[g + 10], 9, 38016083), h = m(h, d, a, c, b[g + 15], 14, -660478335), c = m(c, h, d, a, b[g + 4], 20, -405537848), a = m(a, c, h, d, b[g + 9], 5, 568446438), d = m(d, a, c, h, b[g + 14], 9, -1019803690), h = m(h, d, a, c, b[g + 3], 14, -187363961), c = m(c, h, d, a, b[g + 8], 20, 1163531501), a = m(a, c, h, d, b[g + 13], 5, -1444681467), d = m(d, a, c, h, b[g + 2], 9, -51403784), h = m(h, d, a, c, b[g + 7], 14, 1735328473), c = m(c, h, d, a, b[g + 12], 20, -1926607734), a = f(c ^ h ^ d, a, c, b[g + 5], 4, -378558), d = f(a ^ c ^ h, d, a, b[g + 8], 11, -2022574463),
h = f(d ^ a ^ c, h, d, b[g + 11], 16, 1839030562), c = f(h ^ d ^ a, c, h, b[g + 14], 23, -35309556), a = f(c ^ h ^ d, a, c, b[g + 1], 4, -1530992060), d = f(a ^ c ^ h, d, a, b[g + 4], 11, 1272893353), h = f(d ^ a ^ c, h, d, b[g + 7], 16, -155497632), c = f(h ^ d ^ a, c, h, b[g + 10], 23, -1094730640), a = f(c ^ h ^ d, a, c, b[g + 13], 4, 681279174), d = f(a ^ c ^ h, d, a, b[g + 0], 11, -358537222), h = f(d ^ a ^ c, h, d, b[g + 3], 16, -722521979), c = f(h ^ d ^ a, c, h, b[g + 6], 23, 76029189), a = f(c ^ h ^ d, a, c, b[g + 9], 4, -640364487), d = f(a ^ c ^ h, d, a, b[g + 12], 11, -421815835), h = f(d ^ a ^ c, h, d, b[g + 15], 16, 530742520), c = f(h ^ d ^ a, c, h, b[g + 2], 23, -995338651),
a = o(a, c, h, d, b[g + 0], 6, -198630844), d = o(d, a, c, h, b[g + 7], 10, 1126891415), h = o(h, d, a, c, b[g + 14], 15, -1416354905), c = o(c, h, d, a, b[g + 5], 21, -57434055), a = o(a, c, h, d, b[g + 12], 6, 1700485571), d = o(d, a, c, h, b[g + 3], 10, -1894986606), h = o(h, d, a, c, b[g + 10], 15, -1051523), c = o(c, h, d, a, b[g + 1], 21, -2054922799), a = o(a, c, h, d, b[g + 8], 6, 1873313359), d = o(d, a, c, h, b[g + 15], 10, -30611744), h = o(h, d, a, c, b[g + 6], 15, -1560198380), c = o(c, h, d, a, b[g + 13], 21, 1309151649), a = o(a, c, h, d, b[g + 4], 6, -145523070), d = o(d, a, c, h, b[g + 11], 10, -1120210379), h = o(h, d, a, c, b[g + 2], 15,
718787259), c = o(c, h, d, a, b[g + 9], 21, -343485551), a = p(a, q), c = p(c, n), h = p(h, G), d = p(d, B);
b = [a, c, h, d];
a = "";
for (c = 0; c < b.length * 32; c += 8) a += String.fromCharCode(b[c >> 5] >>> c % 32 & 255);
return a
}
function b(a) {
for (var f = n ? "0123456789ABCDEF" : "0123456789abcdef", k = "", b, m = 0; m < a.length; m++) b = a.charCodeAt(m), k += f.charAt(b >>> 4 & 15) + f.charAt(b & 15);
return k
}
function a(a) {
for (var f = "", k = -1, b, m; ++k < a.length;) b = a.charCodeAt(k), m = k + 1 < a.length ? a.charCodeAt(k + 1) : 0, 55296 <= b && b <= 56319 && 56320 <= m && m <= 57343 && (b = 65536 + ((b & 1023) << 10) + (m &
1023), k++), b <= 127 ? f += String.fromCharCode(b) : b <= 2047 ? f += String.fromCharCode(192 | b >>> 6 & 31, 128 | b & 63) : b <= 65535 ? f += String.fromCharCode(224 | b >>> 12 & 15, 128 | b >>> 6 & 63, 128 | b & 63) : b <= 2097151 && (f += String.fromCharCode(240 | b >>> 18 & 7, 128 | b >>> 12 & 63, 128 | b >>> 6 & 63, 128 | b & 63));
return f
}
function f(a, f, b, k, m, c) {
a = p(p(f, a), p(k, c));
return p(a << m | a >>> 32 - m, b)
}
function k(a, b, k, m, c, h, d) {
return f(b & k | ~b & m, a, b, c, h, d)
}
function m(a, b, k, m, c, h, d) {
return f(b & m | k & ~m, a, b, c, h, d)
}
function o(a, b, k, m, c, h, d) {
return f(k ^ (b | ~m), a, b, c, h, d)
}
function p(a,
f) {
var b = (a & 65535) + (f & 65535);
return (a >> 16) + (f >> 16) + (b >> 16) << 16 | b & 65535
}
var q = {}, n = 0;
d.getGroupId = c;
d.getDefaultGroupId = function (a) {
return c(a, "")
}
})(Spotify.Web.ABTester);
(function (d, g) {
var c = d.History = d.History || {};
if (typeof c.Adapter !== "undefined") throw Error("History.js Adapter has already been loaded...");
c.Adapter = {
handlers: {},
_uid: 1,
uid: function (h) {
return h._uid || (h._uid = c.Adapter._uid++)
},
bind: function (h, b, a) {
var f = c.Adapter.uid(h);
c.Adapter.handlers[f] = c.Adapter.handlers[f] || {};
c.Adapter.handlers[f][b] = c.Adapter.handlers[f][b] || [];
c.Adapter.handlers[f][b].push(a);
h["on" + b] = function (a, f) {
return function (b) {
c.Adapter.trigger(a, f, b)
}
}(h, b)
},
trigger: function (h,
b, a) {
var a = a || {}, h = c.Adapter.uid(h),
f, k;
c.Adapter.handlers[h] = c.Adapter.handlers[h] || {};
c.Adapter.handlers[h][b] = c.Adapter.handlers[h][b] || [];
for (f = 0, k = c.Adapter.handlers[h][b].length; f < k; ++f) c.Adapter.handlers[h][b][f].apply(this, [a])
},
extractEventData: function (c, b) {
return b && b[c] || g
},
onDomLoad: function (c) {
var b = d.setTimeout(function () {
c()
}, 2E3);
d.onload = function () {
clearTimeout(b);
c()
}
}
};
typeof c.init !== "undefined" && c.init()
})(window);
(function (d, g) {
var c = d.console || g,
h = d.document,
b = d.navigator,
a = d.sessionStorage || !1,
f = d.setTimeout,
k = d.clearTimeout,
m = d.setInterval,
o = d.clearInterval,
p = d.JSON,
q = d.alert,
n = d.History = d.History || {}, s = d.history;
p.stringify = p.stringify || p.encode;
p.parse = p.parse || p.decode;
if (typeof n.init !== "undefined") throw Error("History.js Core has already been loaded...");
n.init = function () {
if (typeof n.Adapter === "undefined") return !1;
typeof n.initCore !== "undefined" && n.initCore();
typeof n.initHtml4 !== "undefined" && n.initHtml4();
return !0
};
n.initCore = function () {
if (typeof n.initCore.initialized !== "undefined") return !1;
else n.initCore.initialized = !0;
n.options = n.options || {};
n.options.hashChangeInterval = n.options.hashChangeInterval || 100;
n.options.safariPollInterval = n.options.safariPollInterval || 500;
n.options.doubleCheckInterval = n.options.doubleCheckInterval || 500;
n.options.storeInterval = n.options.storeInterval || 1E3;
n.options.busyDelay = n.options.busyDelay || 250;
n.options.debug = n.options.debug || !1;
n.options.initialTitle = n.options.initialTitle ||
h.title;
n.intervalList = [];
n.clearAllIntervals = function () {
var a, f = n.intervalList;
if (typeof f !== "undefined" && f !== null) {
for (a = 0; a < f.length; a++) o(f[a]);
n.intervalList = null
}
};
n.debug = function () {
n.options.debug && n.log.apply(n, arguments)
};
n.log = function () {
var a = !(typeof c === "undefined" || typeof c.log === "undefined" || typeof c.log.apply === "undefined"),
f = h.getElementById("log"),
b, k, m, d;
a ? (k = Array.prototype.slice.call(arguments), b = k.shift(), typeof c.debug !== "undefined" ? c.debug.apply(c, [b, k]) : c.log.apply(c, [b,
k
])) : b = "\n" + arguments[0] + "\n";
for (k = 1, m = arguments.length; k < m; ++k) {
d = arguments[k];
if (typeof d === "object" && typeof p !== "undefined") try {
d = p.stringify(d)
} catch (o) {}
b += "\n" + d + "\n"
}
f ? (f.value += b + "\n-----\n", f.scrollTop = f.scrollHeight - f.clientHeight) : a || q(b);
return !0
};
n.getInternetExplorerMajorVersion = function () {
return n.getInternetExplorerMajorVersion.cached = typeof n.getInternetExplorerMajorVersion.cached !== "undefined" ? n.getInternetExplorerMajorVersion.cached : function () {
for (var a = 3, f = h.createElement("div"),
b = f.getElementsByTagName("i");
(f.innerHTML = "<\!--[if gt IE " + ++a + "]><i></i><![endif]--\>") && b[0];);
return a > 4 ? a : !1
}()
};
n.isInternetExplorer = function () {
return n.isInternetExplorer.cached = typeof n.isInternetExplorer.cached !== "undefined" ? n.isInternetExplorer.cached : Boolean(n.getInternetExplorerMajorVersion())
};
n.emulated = {
pushState: !Boolean(d.history && d.history.pushState && d.history.replaceState && !(/ Mobile\/([1-7][a-z]|(8([abcde]|f(1[0-8]))))/i.test(b.userAgent) || /AppleWebKit\/5([0-2]|3[0-2])/i.test(b.userAgent))),
hashChange: Boolean(!("onhashchange" in d || "onhashchange" in h) || n.isInternetExplorer() && n.getInternetExplorerMajorVersion() < 8)
};
n.enabled = !n.emulated.pushState;
n.bugs = {
setHash: Boolean(!n.emulated.pushState && b.vendor === "Apple Computer, Inc." && /AppleWebKit\/5([0-2]|3[0-3])/.test(b.userAgent)),
safariPoll: Boolean(!n.emulated.pushState && b.vendor === "Apple Computer, Inc." && /AppleWebKit\/5([0-2]|3[0-3])/.test(b.userAgent)),
ieDoubleCheck: Boolean(n.isInternetExplorer() && n.getInternetExplorerMajorVersion() < 8),
hashEscape: Boolean(n.isInternetExplorer() && n.getInternetExplorerMajorVersion() < 7)
};
n.isEmptyObject = function (a) {
for (var f in a) return !1;
return !0
};
n.cloneObject = function (a) {
a ? (a = p.stringify(a), a = p.parse(a)) : a = {};
return a
};
n.getRootUrl = function () {
var a = h.location.protocol + "//" + (h.location.hostname || h.location.host);
h.location.port && (a += ":" + h.location.port);
a += "/";
return a
};
n.getBaseHref = function () {
var a = h.getElementsByTagName("base"),
f = null,
f = "";
a.length === 1 && (f = a[0], f = f.href.replace(/[^\/]+$/, ""));
(f = f.replace(/\/+$/, "")) && (f += "/");
return f
};
n.getBaseUrl = function () {
return n.getBaseHref() || n.getBasePageUrl() || n.getRootUrl()
};
n.getPageUrl = function () {
return ((n.getState(!1, !1) || {}).url || h.location.href).replace(/\/+$/, "").replace(/[^\/]+$/, function (a) {
return /\./.test(a) ? a : a + "/"
})
};
n.getBasePageUrl = function () {
return h.location.href.replace(/[#\?].*/, "").replace(/[^\/]+$/, function (a) {
return /[^\/]$/.test(a) ? "" : a
}).replace(/\/+$/, "") + "/"
};
n.getFullUrl = function (a, f) {
var b = a,
k = a.substring(0, 1),
f = typeof f ===
"undefined" ? !0 : f;
/[a-z]+\:\/\//.test(a) || (b = k === "/" ? n.getRootUrl() + a.replace(/^\/+/, "") : k === "#" ? n.getPageUrl().replace(/#.*/, "") + a : k === "?" ? n.getPageUrl().replace(/[\?#].*/, "") + a : f ? n.getBaseUrl() + a.replace(/^(\.\/)+/, "") : n.getBasePageUrl() + a.replace(/^(\.\/)+/, ""));
return b.replace(/\#$/, "")
};
n.getShortUrl = function (a) {
var f = n.getBaseUrl(),
b = n.getRootUrl();
n.emulated.pushState && (a = a.replace(f, ""));
a = a.replace(b, "/");
n.isTraditionalAnchor(a) && (a = "./" + a);
return a = a.replace(/^(\.\/)+/g, "./").replace(/\#$/,
"")
};
n.getLocationHref = function (a) {
a = a || h;
return a.URL === a.location.href ? a.location.href : a.location.href === decodeURIComponent(a.URL) ? a.URL : a.location.hash && decodeURIComponent(a.location.href.replace(/^[^#]+/, "")) === a.location.hash ? a.location.href : a.URL.indexOf("#") == -1 && a.location.href.indexOf("#") != -1 ? a.location.href : a.URL || a.location.href
};
n.store = {};
n.idToState = n.idToState || {};
n.stateToId = n.stateToId || {};
n.urlToId = n.urlToId || {};
n.storedStates = n.storedStates || [];
n.savedStates = n.savedStates || [];
n.normalizeStore = function () {
n.store.idToState = n.store.idToState || {};
n.store.urlToId = n.store.urlToId || {};
n.store.stateToId = n.store.stateToId || {}
};
n.getState = function (a, f) {
typeof a === "undefined" && (a = !0);
typeof f === "undefined" && (f = !0);
var b = n.getLastSavedState();
!b && f && (b = n.createStateObject());
if (a) b = n.cloneObject(b), b.url = b.cleanUrl || b.url;
return b
};
n.getIdByState = function (a) {
var f = n.extractId(a.url),
b;
if (!f)
if (b = n.getStateString(a), typeof n.stateToId[b] !== "undefined") f = n.stateToId[b];
else if (typeof n.store.stateToId[b] !==
"undefined") f = n.store.stateToId[b];
else {
for (;;)
if (f = (new Date).getTime() + String(Math.random()).replace(/\D/g, ""), typeof n.idToState[f] === "undefined" && typeof n.store.idToState[f] === "undefined") break;
n.stateToId[b] = f;
n.idToState[f] = a
}
return f
};
n.normalizeState = function (a) {
var f;
if (!a || typeof a !== "object") a = {};
if (typeof a.normalized !== "undefined") return a;
if (!a.data || typeof a.data !== "object") a.data = {};
f = {
normalized: !0
};
f.title = a.title || "";
f.url = n.getFullUrl(a.url || n.getLocationHref());
f.hash = n.getShortUrl(f.url);
f.data = n.cloneObject(a.data);
f.id = n.getIdByState(f);
f.cleanUrl = f.url.replace(/\??\&_suid.*/, "");
f.url = f.cleanUrl;
a = !n.isEmptyObject(f.data);
if (f.title || a) f.hash = n.getShortUrl(f.url).replace(/\??\&_suid.*/, ""), /\?/.test(f.hash) || (f.hash += "?"), f.hash += "&_suid=" + f.id;
f.hashedUrl = n.getFullUrl(f.hash);
if ((n.emulated.pushState || n.bugs.safariPoll) && n.hasUrlDuplicate(f)) f.url = f.hashedUrl;
return f
};
n.createStateObject = function (a, f, b) {
a = {
data: a,
title: f,
url: b
};
return a = n.normalizeState(a)
};
n.getStateById = function (a) {
a =
String(a);
return n.idToState[a] || n.store.idToState[a] || g
};
n.getStateString = function (a) {
a = {
data: n.normalizeState(a).data,
title: a.title,
url: a.url
};
return p.stringify(a)
};
n.getStateId = function (a) {
return n.normalizeState(a).id
};
n.getHashByState = function (a) {
return n.normalizeState(a).hash
};
n.extractId = function (a) {
return ((a = /(.*)\&_suid=([0-9]+)$/.exec(a)) ? String(a[2] || "") : "") || !1
};
n.isTraditionalAnchor = function (a) {
return !/[\/\?\.]/.test(a)
};
n.extractState = function (a, f) {
var b = null,
k, m, f = f || !1;
(k = n.extractId(a)) &&
(b = n.getStateById(k));
b || (m = n.getFullUrl(a), (k = n.getIdByUrl(m) || !1) && (b = n.getStateById(k)), !b && f && !n.isTraditionalAnchor(a) && (b = n.createStateObject(null, null, m)));
return b
};
n.getIdByUrl = function (a) {
return n.urlToId[a] || n.store.urlToId[a] || g
};
n.getLastSavedState = function () {
return n.savedStates[n.savedStates.length - 1] || g
};
n.getLastStoredState = function () {
return n.storedStates[n.storedStates.length - 1] || g
};
n.hasUrlDuplicate = function (a) {
var f = !1;
return f = (f = n.extractState(a.url)) && f.id !== a.id
};
n.storeState =
function (a) {
n.urlToId[a.url] = a.id;
n.storedStates.push(n.cloneObject(a));
return a
};
n.isLastSavedState = function (a) {
var f = !1;
if (n.savedStates.length) a = a.id, f = n.getLastSavedState(), f = f.id, f = a === f;
return f
};
n.saveState = function (a) {
if (n.isLastSavedState(a)) return !1;
n.savedStates.push(n.cloneObject(a));
return !0
};
n.getStateByIndex = function (a) {
var f = null;
return f = typeof a === "undefined" ? n.savedStates[n.savedStates.length - 1] : a < 0 ? n.savedStates[n.savedStates.length + a] : n.savedStates[a]
};
n.getHash = function () {
return n.unescapeHash(h.location.hash)
};
n.unescapeString = function (a) {
return a
};
n.unescapeHash = function (a) {
a = n.normalizeHash(a);
return a = decodeURI(a)
};
n.normalizeHash = function (a) {
return a.replace(/[^#]*#/, "").replace(/#.*/, "")
};
n.setHash = function (a, f) {
var b, k;
if (f !== !1 && n.busy()) return n.pushQueue({
scope: n,
callback: n.setHash,
args: arguments,
queue: f
}), !1;
b = n.escapeHash(a);
n.busy(!0);
if ((k = n.extractState(a, !0)) && !n.emulated.pushState) n.pushState(k.data, k.title, k.url, !1);
else if (h.location.hash !== b) n.bugs.setHash ? (k = n.getPageUrl(), n.pushState(null,
null, k + "#" + b, !1)) : h.location.hash = b;
return n
};
n.escapeHash = function (a) {
a = n.normalizeHash(a);
a = d.encodeURI(a);
n.bugs.hashEscape || (a = a.replace(/\%21/g, "!").replace(/\%26/g, "&").replace(/\%3D/g, "=").replace(/\%3F/g, "?"));
return a
};
n.getHashByUrl = function (a) {
a = String(a).replace(/([^#]*)#?([^#]*)#?(.*)/, "$2");
return a = n.unescapeHash(a)
};
n.setTitle = function (a) {
var f = a.title,
b;
f || (b = n.getStateByIndex(0)) && b.url === a.url && (f = b.title || n.options.initialTitle);
try {
h.getElementsByTagName("title")[0].innerHTML =
f.replace("<", "&lt;").replace(">", "&gt;").replace(" & ", " &amp; ")
} catch (k) {}
h.title = f;
return n
};
n.queues = [];
n.busy = function (a) {
if (typeof a !== "undefined") n.busy.flag = a;
else if (typeof n.busy.flag === "undefined") n.busy.flag = !1;
if (!n.busy.flag) {
k(n.busy.timeout);
var b = function () {
var a, k;
if (!n.busy.flag)
for (a = n.queues.length - 1; a >= 0; --a)
if (k = n.queues[a], k.length !== 0) k = k.shift(), n.fireQueueItem(k), n.busy.timeout = f(b, n.options.busyDelay)
};
n.busy.timeout = f(b, n.options.busyDelay)
}
return n.busy.flag
};
n.busy.flag = !1;
n.fireQueueItem = function (a) {
return a.callback.apply(a.scope || n, a.args || [])
};
n.pushQueue = function (a) {
n.queues[a.queue || 0] = n.queues[a.queue || 0] || [];
n.queues[a.queue || 0].push(a);
return n
};
n.queue = function (a, f) {
typeof a === "function" && (a = {
callback: a
});
if (typeof f !== "undefined") a.queue = f;
n.busy() ? n.pushQueue(a) : n.fireQueueItem(a);
return n
};
n.clearQueue = function () {
n.busy.flag = !1;
n.queues = [];
return n
};
n.stateChanged = !1;
n.doubleChecker = !1;
n.doubleCheckComplete = function () {
n.stateChanged = !0;
n.doubleCheckClear();
return n
};
n.doubleCheckClear = function () {
if (n.doubleChecker) k(n.doubleChecker), n.doubleChecker = !1;
return n
};
n.doubleCheck = function (a) {
n.stateChanged = !1;
n.doubleCheckClear();
if (n.bugs.ieDoubleCheck) n.doubleChecker = f(function () {
n.doubleCheckClear();
n.stateChanged || a();
return !0
}, n.options.doubleCheckInterval);
return n
};
n.safariStatePoll = function () {
var a = n.extractState(h.location.href);
if (!n.isLastSavedState(a)) return a || n.createStateObject(), n.Adapter.trigger(d, "popstate"), n
};
n.back = function (a) {
if (a !== !1 && n.busy()) return n.pushQueue({
scope: n,
callback: n.back,
args: arguments,
queue: a
}), !1;
n.busy(!0);
n.doubleCheck(function () {
n.back(!1)
});
s.go(-1);
return !0
};
n.forward = function (a) {
if (a !== !1 && n.busy()) return n.pushQueue({
scope: n,
callback: n.forward,
args: arguments,
queue: a
}), !1;
n.busy(!0);
n.doubleCheck(function () {
n.forward(!1)
});
s.go(1);
return !0
};
n.go = function (a, f) {
var b;
if (a > 0)
for (b = 1; b <= a; ++b) n.forward(f);
else if (a < 0)
for (b = -1; b >= a; --b) n.back(f);
else throw Error("History.go: History.go requires a positive or negative integer passed.");
return n
};
if (n.emulated.pushState) {
var t = function () {};
n.pushState = n.pushState || t;
n.replaceState = n.replaceState || t
} else n.onPopState = function (a, f) {
var b = !1,
b = !1;
n.doubleCheckComplete();
if (b = n.getHash()) return (b = n.extractState(b || h.location.href, !0)) ? n.replaceState(b.data, b.title, b.url, !1) : (n.Adapter.trigger(d, "anchorchange"), n.busy(!1)), n.expectedStateId = !1;
(b = (b = n.Adapter.extractEventData("state", a, f) || !1) ? n.getStateById(b) : n.expectedStateId ? n.getStateById(n.expectedStateId) : n.extractState(h.location.href)) ||
(b = n.createStateObject(null, null, h.location.href));
n.expectedStateId = !1;
if (n.isLastSavedState(b)) return n.busy(!1), !1;
n.storeState(b);
n.saveState(b);
n.setTitle(b);
n.Adapter.trigger(d, "statechange");
n.busy(!1);
return !0
}, n.Adapter.bind(d, "popstate", n.onPopState), n.pushState = function (a, f, b, k) {
if (n.getHashByUrl(b) && n.emulated.pushState) throw Error("History.js does not support states with fragement-identifiers (hashes/anchors).");
if (k !== !1 && n.busy()) return n.pushQueue({
scope: n,
callback: n.pushState,
args: arguments,
queue: k
}), !1;
n.busy(!0);
var m = n.createStateObject(a, f, b);
n.isLastSavedState(m) ? n.busy(!1) : (n.storeState(m), n.expectedStateId = m.id, s.pushState(m.id, m.title, m.url), n.Adapter.trigger(d, "popstate"));
return !0
}, n.replaceState = function (a, f, b, k) {
if (n.getHashByUrl(b) && n.emulated.pushState) throw Error("History.js does not support states with fragement-identifiers (hashes/anchors).");
if (k !== !1 && n.busy()) return n.pushQueue({
scope: n,
callback: n.replaceState,
args: arguments,
queue: k
}), !1;
n.busy(!0);
var m = n.createStateObject(a,
f, b);
n.isLastSavedState(m) ? n.busy(!1) : (n.storeState(m), n.expectedStateId = m.id, s.replaceState(m.id, m.title, m.url), n.Adapter.trigger(d, "popstate"));
return !0
}; if (a) try {
n.store = p.parse(a.getItem("History.store")) || {}
} catch (u) {
n.store = {}
} else n.store = {};
n.normalizeStore();
n.Adapter.bind(d, "beforeunload", n.clearAllIntervals);
n.Adapter.bind(d, "unload", n.clearAllIntervals);
n.saveState(n.storeState(n.extractState(h.location.href, !0)));
if (a) n.onUnload = function () {
var f, b;
try {
f = p.parse(a.getItem("History.store")) || {}
} catch (k) {
f = {}
}
f.idToState = f.idToState || {};
f.urlToId = f.urlToId || {};
f.stateToId = f.stateToId || {};
for (b in n.idToState) n.idToState.hasOwnProperty(b) && (f.idToState[b] = n.idToState[b]);
for (b in n.urlToId) n.urlToId.hasOwnProperty(b) && (f.urlToId[b] = n.urlToId[b]);
for (b in n.stateToId) n.stateToId.hasOwnProperty(b) && (f.stateToId[b] = n.stateToId[b]);
n.store = f;
n.normalizeStore();
a.setItem("History.store", p.stringify(f))
}, n.intervalList.push(m(n.onUnload, n.options.storeInterval)), n.Adapter.bind(d, "beforeunload",
n.onUnload), n.Adapter.bind(d, "unload", n.onUnload);
if (!n.emulated.pushState && (n.bugs.safariPoll && n.intervalList.push(m(n.safariStatePoll, n.options.safariPollInterval)), b.vendor === "Apple Computer, Inc." || (b.appCodeName || "") === "Mozilla"))
if (n.Adapter.bind(d, "hashchange", function () {
n.Adapter.trigger(d, "popstate")
}), n.getHash()) n.Adapter.onDomLoad(function () {
n.Adapter.trigger(d, "hashchange")
})
};
n.init()
})(window);
(function (d) {
var g = d.document,
c = d.setInterval || c,
h = d.History = d.History || {};
if (typeof h.initHtml4 !== "undefined") throw Error("History.js HTML4 Support has already been loaded...");
h.initHtml4 = function () {
if (typeof h.initHtml4.initialized !== "undefined") return !1;
else h.initHtml4.initialized = !0;
h.enabled = !0;
h.savedHashes = [];
h.isLastHash = function (b) {
var a = h.getHashByIndex();
return b === a
};
h.saveHash = function (b) {
if (h.isLastHash(b)) return !1;
h.savedHashes.push(b);
return !0
};
h.getHashByIndex = function (b) {
var a =
null;
return a = typeof b === "undefined" ? h.savedHashes[h.savedHashes.length - 1] : b < 0 ? h.savedHashes[h.savedHashes.length + b] : h.savedHashes[b]
};
h.discardedHashes = {};
h.discardedStates = {};
h.discardState = function (b, a, f) {
var k = h.getHashByState(b);
h.discardedStates[k] = {
discardedState: b,
backState: f,
forwardState: a
};
return !0
};
h.discardHash = function (b, a, f) {
h.discardedHashes[b] = {
discardedHash: b,
backState: f,
forwardState: a
};
return !0
};
h.discardedState = function (b) {
b = h.getHashByState(b);
return h.discardedStates[b] || !1
};
h.discardedHash = function (b) {
return h.discardedHashes[b] || !1
};
h.recycleState = function (b) {
var a = h.getHashByState(b);
h.discardedState(b) && delete h.discardedStates[a];
return !0
};
if (h.emulated.hashChange) h.hashChangeInit = function () {
h.checkerFunction = null;
var b = "",
a, f, k;
h.isInternetExplorer() ? (a = g.createElement("iframe"), a.setAttribute("id", "historyjs-iframe"), a.style.display = "none", g.body.appendChild(a), a.contentWindow.document.open(), a.contentWindow.document.close(), f = "", k = !1, h.checkerFunction = function () {
if (k) return !1;
k = !0;
var m = h.getHash() || "",
c = h.unescapeHash(a.contentWindow.document.location.hash) || "";
if (m !== b) {
b = m;
if (c !== m) f = m, a.contentWindow.document.open(), a.contentWindow.document.close(), a.contentWindow.document.location.hash = h.escapeHash(m);
h.Adapter.trigger(d, "hashchange")
} else c !== f && (f = c, h.setHash(c, !1));
k = !1;
return !0
}) : h.checkerFunction = function () {
var a = h.getHash();
a !== b && (b = a, h.Adapter.trigger(d, "hashchange"));
return !0
};
h.intervalList.push(c(h.checkerFunction, h.options.hashChangeInterval));
return !0
},
h.Adapter.onDomLoad(h.hashChangeInit);
if (h.emulated.pushState) h.onHashChange = function (b) {
var a = h.getHashByUrl(b && b.newURL || g.location.href),
b = null;
if (h.isLastHash(a)) return h.busy(!1), !1;
h.doubleCheckComplete();
h.saveHash(a);
if (a && h.isTraditionalAnchor(a)) return h.Adapter.trigger(d, "anchorchange"), h.busy(!1), !1;
b = h.extractState(h.getFullUrl(a || g.location.href, !1), !0);
if (h.isLastSavedState(b)) return h.busy(!1), !1;
h.getHashByState(b);
if (a = h.discardedState(b)) return h.getHashByIndex(-2) === h.getHashByState(a.forwardState) ?
h.back(!1) : h.forward(!1), !1;
h.pushState(b.data, b.title, b.url, !1);
return !0
}, h.Adapter.bind(d, "hashchange", h.onHashChange), h.pushState = function (b, a, f, k) {
if (h.getHashByUrl(f)) throw Error("History.js does not support states with fragement-identifiers (hashes/anchors).");
if (k !== !1 && h.busy()) return h.pushQueue({
scope: h,
callback: h.pushState,
args: arguments,
queue: k
}), !1;
h.busy(!0);
var m = h.createStateObject(b, a, f),
c = h.getHashByState(m),
p = h.getState(!1),
p = h.getHashByState(p),
q = h.getHash();
h.storeState(m);
h.expectedStateId =
m.id;
h.recycleState(m);
h.setTitle(m);
if (c === p) return h.busy(!1), !1;
if (c !== q && c !== h.getShortUrl(g.location.href)) return h.setHash(c, !1), !1;
h.saveState(m);
h.Adapter.trigger(d, "statechange");
h.busy(!1);
return !0
}, h.replaceState = function (b, a, f, k) {
if (h.getHashByUrl(f)) throw Error("History.js does not support states with fragement-identifiers (hashes/anchors).");
if (k !== !1 && h.busy()) return h.pushQueue({
scope: h,
callback: h.replaceState,
args: arguments,
queue: k
}), !1;
h.busy(!0);
var m = h.createStateObject(b, a, f),
c = h.getState(!1),
d = h.getStateByIndex(-2);
h.discardState(c, m, d);
h.pushState(m.data, m.title, m.url, !1);
return !0
};
if (h.emulated.pushState && h.getHash() && !h.emulated.hashChange) h.Adapter.onDomLoad(function () {
h.Adapter.trigger(d, "hashchange")
})
};
typeof h.init !== "undefined" && h.init()
})(window);
swfobject = function () {
function d() {
if (!P) {
try {
var a = E.getElementsByTagName("body")[0].appendChild(E.createElement("span"));
a.parentNode.removeChild(a)
} catch (f) {
return
}
P = !0;
for (var a = K.length, b = 0; b < a; b++) K[b]()
}
}
function g(a) {
P ? a() : K[K.length] = a
}
function c(a) {
if (typeof B.addEventListener != A) B.addEventListener("load", a, !1);
else if (typeof E.addEventListener != A) E.addEventListener("load", a, !1);
else if (typeof B.attachEvent != A) s(B, "onload", a);
else if (typeof B.onload == "function") {
var f =
B.onload;
B.onload = function () {
f();
a()
}
} else B.onload = a
}
function h() {
var a = E.getElementsByTagName("body")[0],
f = E.createElement(x);
f.setAttribute("type", F);
var k = a.appendChild(f);
if (k) {
var m = 0;
(function () {
if (typeof k.GetVariable != A) {
var c = k.GetVariable("$version");
if (c) c = c.split(" ")[1].split(","), J.pv = [parseInt(c[0], 10), parseInt(c[1], 10), parseInt(c[2], 10)]
} else if (m < 10) {
m++;
setTimeout(arguments.callee, 10);
return
}
a.removeChild(f);
k = null;
b()
})()
} else b()
}
function b() {
var b = L.length;
if (b > 0)
for (var c = 0; c <
b; c++) {
var h = L[c].id,
d = L[c].callbackFn,
o = {
success: !1,
id: h
};
if (J.pv[0] > 0) {
var g = n(h);
if (g)
if (t(L[c].swfVersion) && !(J.wk && J.wk < 312)) {
if (w(h, !0), d) o.success = !0, o.ref = a(h), d(o)
} else if (L[c].expressInstall && f()) {
o = {};
o.data = L[c].expressInstall;
o.width = g.getAttribute("width") || "0";
o.height = g.getAttribute("height") || "0";
if (g.getAttribute("class")) o.styleclass = g.getAttribute("class");
if (g.getAttribute("align")) o.align = g.getAttribute("align");
for (var p = {}, g = g.getElementsByTagName("param"), q = g.length, s = 0; s <
q; s++) g[s].getAttribute("name").toLowerCase() != "movie" && (p[g[s].getAttribute("name")] = g[s].getAttribute("value"));
k(o, p, h, d)
} else m(g), d && d(o)
} else if (w(h, !0), d) {
if ((h = a(h)) && typeof h.SetVariable != A) o.success = !0, o.ref = h;
d(o)
}
}
}
function a(a) {
var f = null;
if ((a = n(a)) && a.nodeName == "OBJECT") typeof a.SetVariable != A ? f = a : (a = a.getElementsByTagName(x)[0]) && (f = a);
return f
}
function f() {
return !O && t("6.0.65") && (J.win || J.mac) && !(J.wk && J.wk < 312)
}
function k(a, f, b, k) {
O = !0;
y = k || null;
D = {
success: !1,
id: b
};
var m = n(b);
if (m) {
m.nodeName ==
"OBJECT" ? (z = o(m), C = null) : (z = m, C = b);
a.id = G;
if (typeof a.width == A || !/%$/.test(a.width) && parseInt(a.width, 10) < 310) a.width = "310";
if (typeof a.height == A || !/%$/.test(a.height) && parseInt(a.height, 10) < 137) a.height = "137";
E.title = E.title.slice(0, 47) + " - Flash Player Installation";
k = J.ie && J.win ? "ActiveX" : "PlugIn";
k = "MMredirectURL=" + B.location.toString().replace(/&/g, "%26") + "&MMplayerType=" + k + "&MMdoctitle=" + E.title;
typeof f.flashvars != A ? f.flashvars += "&" + k : f.flashvars = k;
if (J.ie && J.win && m.readyState != 4) k = E.createElement("div"),
b += "SWFObjectNew", k.setAttribute("id", b), m.parentNode.insertBefore(k, m), m.style.display = "none",
function () {
m.readyState == 4 ? m.parentNode.removeChild(m) : setTimeout(arguments.callee, 10)
}();
p(a, f, b)
}
}
function m(a) {
if (J.ie && J.win && a.readyState != 4) {
var f = E.createElement("div");
a.parentNode.insertBefore(f, a);
f.parentNode.replaceChild(o(a), f);
a.style.display = "none";
(function () {
a.readyState == 4 ? a.parentNode.removeChild(a) : setTimeout(arguments.callee, 10)
})()
} else a.parentNode.replaceChild(o(a), a)
}
function o(a) {
var f =
E.createElement("div");
if (J.win && J.ie) f.innerHTML = a.innerHTML;
else if (a = a.getElementsByTagName(x)[0])
if (a = a.childNodes)
for (var b = a.length, k = 0; k < b; k++)!(a[k].nodeType == 1 && a[k].nodeName == "PARAM") && a[k].nodeType != 8 && f.appendChild(a[k].cloneNode(!0));
return f
}
function p(a, f, b) {
var k, m = n(b);
if (J.wk && J.wk < 312) return k;
if (m) {
if (typeof a.id == A) a.id = b;
if (J.ie && J.win) {
var c = "",
h;
for (h in a)
if (a[h] != Object.prototype[h]) h.toLowerCase() == "data" ? f.movie = a[h] : h.toLowerCase() == "styleclass" ? c += ' class="' + a[h] + '"' :
h.toLowerCase() != "classid" && (c += " " + h + '="' + a[h] + '"');
h = "";
for (var d in f) f[d] != Object.prototype[d] && (h += '<param name="' + d + '" value="' + f[d] + '" />');
m.outerHTML = '<object classid="clsid:D27CDB6E-AE6D-11cf-96B8-444553540000"' + c + ">" + h + "</object>";
N[N.length] = a.id;
k = n(a.id)
} else {
d = E.createElement(x);
d.setAttribute("type", F);
for (var o in a) a[o] != Object.prototype[o] && (o.toLowerCase() == "styleclass" ? d.setAttribute("class", a[o]) : o.toLowerCase() != "classid" && d.setAttribute(o, a[o]));
for (c in f) f[c] != Object.prototype[c] &&
c.toLowerCase() != "movie" && (a = d, h = c, o = f[c], b = E.createElement("param"), b.setAttribute("name", h), b.setAttribute("value", o), a.appendChild(b));
m.parentNode.replaceChild(d, m);
k = d
}
}
return k
}
function q(a) {
var f = n(a);
if (f && f.nodeName == "OBJECT") J.ie && J.win ? (f.style.display = "none", function () {
if (f.readyState == 4) {
var b = n(a);
if (b) {
for (var k in b) typeof b[k] == "function" && (b[k] = null);
b.parentNode.removeChild(b)
}
} else setTimeout(arguments.callee, 10)
}()) : f.parentNode.removeChild(f)
}
function n(a) {
var f = null;
try {
f = E.getElementById(a)
} catch (b) {}
return f
}
function s(a, f, b) {
a.attachEvent(f, b);
M[M.length] = [a, f, b]
}
function t(a) {
var f = J.pv,
a = a.split(".");
a[0] = parseInt(a[0], 10);
a[1] = parseInt(a[1], 10) || 0;
a[2] = parseInt(a[2], 10) || 0;
return f[0] > a[0] || f[0] == a[0] && f[1] > a[1] || f[0] == a[0] && f[1] == a[1] && f[2] >= a[2] ? !0 : !1
}
function u(a, f, b, k) {
if (!J.ie || !J.mac) {
var m = E.getElementsByTagName("head")[0];
if (m) {
b = b && typeof b == "string" ? b : "screen";
k && (T = R = null);
if (!R || T != b) k = E.createElement("style"), k.setAttribute("type", "text/css"), k.setAttribute("media", b), R = m.appendChild(k),
J.ie && J.win && typeof E.styleSheets != A && E.styleSheets.length > 0 && (R = E.styleSheets[E.styleSheets.length - 1]), T = b;
J.ie && J.win ? R && typeof R.addRule == x && R.addRule(a, f) : R && typeof E.createTextNode != A && R.appendChild(E.createTextNode(a + " {" + f + "}"))
}
}
}
function w(a, f) {
if (S) {
var b = f ? "visible" : "hidden";
P && n(a) ? n(a).style.visibility = b : u("#" + a, "visibility:" + b)
}
}
function v(a) {
return /[\\\"<>\.;]/.exec(a) != null && typeof encodeURIComponent != A ? encodeURIComponent(a) : a
}
var A = "undefined",
x = "object",
F = "application/x-shockwave-flash",
G = "SWFObjectExprInst",
B = window,
E = document,
H = navigator,
I = !1,
K = [
function () {
I ? h() : b()
}
],
L = [],
N = [],
M = [],
z, C, y, D, P = !1,
O = !1,
R, T, S = !0,
J = function () {
var a = typeof E.getElementById != A && typeof E.getElementsByTagName != A && typeof E.createElement != A,
f = H.userAgent.toLowerCase(),
b = H.platform.toLowerCase(),
k = b ? /win/.test(b) : /win/.test(f),
b = b ? /mac/.test(b) : /mac/.test(f),
f = /webkit/.test(f) ? parseFloat(f.replace(/^.*webkit\/(\d+(\.\d+)?).*$/, "$1")) : !1,
m = !+"\u000b1",
c = [0, 0, 0],
h = null;
if (typeof H.plugins != A && typeof H.plugins["Shockwave Flash"] ==
x) {
if ((h = H.plugins["Shockwave Flash"].description) && !(typeof H.mimeTypes != A && H.mimeTypes[F] && !H.mimeTypes[F].enabledPlugin)) I = !0, m = !1, h = h.replace(/^.*\s+(\S+\s+\S+$)/, "$1"), c[0] = parseInt(h.replace(/^(.*)\..*$/, "$1"), 10), c[1] = parseInt(h.replace(/^.*\.(.*)\s.*$/, "$1"), 10), c[2] = /[a-zA-Z]/.test(h) ? parseInt(h.replace(/^.*[a-zA-Z]+(.*)$/, "$1"), 10) : 0
} else if (typeof B.ActiveXObject != A) try {
var d = new ActiveXObject("ShockwaveFlash.ShockwaveFlash");
if (d && (h = d.GetVariable("$version"))) m = !0, h = h.split(" ")[1].split(","),
c = [parseInt(h[0], 10), parseInt(h[1], 10), parseInt(h[2], 10)]
} catch (o) {}
return {
w3: a,
pv: c,
wk: f,
ie: m,
win: k,
mac: b
}
}();
(function () {
J.w3 && ((typeof E.readyState != A && E.readyState == "complete" || typeof E.readyState == A && (E.getElementsByTagName("body")[0] || E.body)) && d(), P || (typeof E.addEventListener != A && E.addEventListener("DOMContentLoaded", d, !1), J.ie && J.win && (E.attachEvent("onreadystatechange", function () {
E.readyState == "complete" && (E.detachEvent("onreadystatechange", arguments.callee), d())
}), B == top && function () {
if (!P) {
try {
E.documentElement.doScroll("left")
} catch (a) {
setTimeout(arguments.callee,
0);
return
}
d()
}
}()), J.wk && function () {
P || (/loaded|complete/.test(E.readyState) ? d() : setTimeout(arguments.callee, 0))
}(), c(d)))
})();
(function () {
J.ie && J.win && window.attachEvent("onunload", function () {
for (var a = M.length, f = 0; f < a; f++) M[f][0].detachEvent(M[f][1], M[f][2]);
a = N.length;
for (f = 0; f < a; f++) q(N[f]);
for (var b in J) J[b] = null;
J = null;
for (var k in swfobject) swfobject[k] = null;
swfobject = null
})
})();
return {
registerObject: function (a, f, b, k) {
if (J.w3 && a && f) {
var m = {};
m.id = a;
m.swfVersion = f;
m.expressInstall = b;
m.callbackFn =
k;
L[L.length] = m;
w(a, !1)
} else k && k({
success: !1,
id: a
})
},
getObjectById: function (f) {
if (J.w3) return a(f)
},
embedSWF: function (a, b, m, c, h, d, o, q, n, s) {
var u = {
success: !1,
id: b
};
J.w3 && !(J.wk && J.wk < 312) && a && b && m && c && h ? (w(b, !1), g(function () {
m += "";
c += "";
var g = {};
if (n && typeof n === x)
for (var v in n) g[v] = n[v];
g.data = a;
g.width = m;
g.height = c;
v = {};
if (q && typeof q === x)
for (var F in q) v[F] = q[F];
if (o && typeof o === x)
for (var K in o) typeof v.flashvars != A ? v.flashvars += "&" + K + "=" + o[K] : v.flashvars = K + "=" + o[K];
if (t(h)) F = p(g, v, b), g.id ==
b && w(b, !0), u.success = !0, u.ref = F;
else if (d && f()) {
g.data = d;
k(g, v, b, s);
return
} else w(b, !0);
s && s(u)
})) : s && s(u)
},
switchOffAutoHideShow: function () {
S = !1
},
ua: J,
getFlashPlayerVersion: function () {
return {
major: J.pv[0],
minor: J.pv[1],
release: J.pv[2]
}
},
hasFlashPlayerVersion: t,
createSWF: function (a, f, b) {
if (J.w3) return p(a, f, b)
},
showExpressInstall: function (a, b, m, c) {
J.w3 && f() && k(a, b, m, c)
},
removeSWF: function (a) {
J.w3 && q(a)
},
createCSS: function (a, f, b, k) {
J.w3 && u(a, f, b, k)
},
addDomLoadEvent: g,
addLoadEvent: c,
getQueryParamValue: function (a) {
var f =
E.location.search || E.location.hash;
if (f) {
/\?/.test(f) && (f = f.split("?")[1]);
if (a == null) return v(f);
for (var f = f.split("&"), b = 0; b < f.length; b++)
if (f[b].substring(0, f[b].indexOf("=")) == a) return v(f[b].substring(f[b].indexOf("=") + 1))
}
return ""
},
expressInstallCallback: function () {
if (O) {
var a = n(G);
if (a && z) {
a.parentNode.replaceChild(z, a);
if (C && (w(C, !0), J.ie && J.win)) z.style.display = "block";
y && y(D)
}
O = !1
}
}
}
}(),
Spotify = Spotify || {};
Spotify.Cache = Spotify.Cache || {};
Spotify.Logging = Spotify.Logging || {};
Spotify.App = Spotify.App || {};
Spotify.Utils = Spotify.Utils || {};
Spotify.Flash = Spotify.Flash || {};
Spotify.Services = Spotify.Services || {};
Spotify.Services.CollectionStorageImplementation = Spotify.Services.CollectionStorageImplementation || {};
Spotify.Services.CollectionSuggestionsImplementation = Spotify.Services.CollectionSuggestionsImplementation || {};
Spotify.Services.CollectionViewImplementation = Spotify.Services.CollectionViewImplementation || {};
Spotify.Services.CurrentFavoritesImplementation = Spotify.Services.CurrentFavoritesImplementation || {};
Spotify.WebSockets = Spotify.WebSockets || {};
Spotify.Protobuf = Spotify.Protobuf || {};
Spotify.Hermes = Spotify.Hermes || {};
Spotify.Parsers = Spotify.Parsers || {};
Spotify.Models = Spotify.Models || {};
Spotify.HTML5 = Spotify.HTML5 || {};
Spotify.Audio = Spotify.Audio || {};
Spotify.Proto = Spotify.Proto || {};
Spotify.Errors = Spotify.Errors || {};
Spotify.Errors.Domains = Spotify.Errors.Domains || {};
Spotify.Errors.Codes = Spotify.Errors.Codes || {};
Spotify.Calls = Spotify.Calls || {};
Spotify.Managers = Spotify.Managers || {};
DebuggerJS = Spotify.DebuggerJS = new function () {
this.Parsers = {};
this.Loggers = {};
this.Parsers = {};
this.Utils = {
isArray: Array.isArray || function (c) {
return Object.prototype.toString.call(c) == "[object Array]"
}
};
var d = {}, g = {};
this.register = function (c, h, b) {
if (typeof c !== "string" || typeof h === "undefined" || h === null) throw Error("Not valid arguments");
d[c] || (d[c] = h);
g[c] || (g[c] = b || new DebuggerJS.Parsers.Console);
return !0
};
this.log = function () {};
this.warn = function () {};
this.error = function () {};
this.on = function (c, h) {
if (typeof c !==
"undefined" && !DebuggerJS.Utils.isArray(c) && c !== null) throw Error("The modules argument should be an array");
if (typeof h !== "undefined" && !DebuggerJS.Utils.isArray(h) && h !== null) throw Error("The tags argument should be an array");
};
this.off = function () {}
};
DebuggerJS.Parsers.Default = function () {
this.parse = function (d, g, c) {
d += " |";
return [d].concat(g).concat("| Tag: " + c)
}
};
DebuggerJS.Loggers.Console = function () {
this.log = function () {
console.log.apply(console, arguments);
return !0
};
this.error = function () {
console.error.apply(console, arguments);
return !0
};
this.warn = function () {
console.warn.apply(console, arguments);
return !0
}
};
DebuggerJS.Loggers.Memory = function () {
this.log = function () {
return !0
};
this.error = function () {
return !0
};
this.warn = function () {
return !0
}
};
Spotify.Storage = {
localStorage: null,
indexedDB: {
storage: null,
IDBKeyRange: null,
IDBTransaction: null
}
};
(function () {
var d = [].slice;
if (!("bind" in Function.prototype)) Function.prototype.bind = function (c) {
var h = this,
b = null;
arguments.length > 1 && (b = d.call(arguments, 1));
return function () {
var a;
!arguments.length && !b ? a = h.call(c) : h.apply(c, !b ? arguments : !arguments.length ? b : b.concat(d.call(arguments)));
return a
}
};
if (!("indexOf" in Array.prototype)) Array.prototype.indexOf = function () {
for (var c = this.length >>> 0, h = from < 0 ? Math.max(0, c + from) : from || 0; h < c; h++)
if (this[h] === item) return h;
return -1
};
var g;
Spotify.Utils = {
isArray: Array.isArray || function (c) {
return Object.prototype.toString.call(c) == "[object Array]"
},
inherit: function (c, h) {
function b() {}
b.prototype = new c;
h.prototype = new b;
return h.prototype.constructor = h
},
isFunction: function (c) {
return typeof c == "function"
},
toFixed: function (c, h) {
var h = h || 0,
b = c < 0,
a = Math.pow(10, h),
c = Math.round(c * a),
f = String((b ? Math.ceil : Math.floor)(c / a)),
b = String((b ? -c : c) % a),
a = Array(Math.max(h - b.length, 0) + 1).join("0");
return h ? f + "." + a + b : f
},
convertStringToXML: function (c) {
if (window.DOMParser) return g = new DOMParser,
g.parseFromString(c.replace(/\n/g, ""), "text/xml");
else {
var h = new ActiveXObject("Microsoft.XMLDOM");
h.async = !1;
return h.loadXML(c.replace(/\n/g, ""))
}
},
convertXMLToJSON: function (c) {
var h = {}, b = c.nodeType == 1 && c.attributes.length > 0,
a = c.hasChildNodes();
if (!b && !a) return c.data || "";
if (b) {
h["@attributes"] = {};
for (b = 0; b < c.attributes.length; b++) {
var f = c.attributes.item(b);
h["@attributes"][f.nodeName] = f.nodeValue
}
}
if (a) {
if (c.childNodes.length == 1 && c.childNodes[0].nodeName == "#text") return c.childNodes[0].data;
for (a =
0; a < c.childNodes.length; a++) f = c.childNodes[a], b = f.nodeName, f = this.convertXMLToJSON(f), b != "#text" && (typeof h[b] === "undefined" ? h[b] = f : (this.isArray(h[b]) || (h[b] = Array(h[b])), h[b].push(f)))
}
return h
},
hex2str: function (c) {
for (var h = [], b = 0, a = c.length; b < a - 1; b += 2) h.push(String.fromCharCode(parseInt(c.substr(b, 2), 16)));
return h.join("")
},
str2hex: function (c) {
for (var h = "", b = 0, a = c.length; b < a; ++b) h += (c.charCodeAt(b) + 256).toString(16).slice(-2);
return h
},
parseURL: function (c) {
for (var h = "source,protocol,authority,userInfo,user,password,host,port,relative,path,directory,file,query,anchor".split(","),
c = RegExp("^(?:(?![^:@]+:[^:@/]*@)([^:/?#.]+):)?(?://)?((?:(([^:@]*)(?::([^:@]*))?)?@)?([^:/?#]*)(?::(\\d*))?)(((/(?:[^?#](?![^?#/]*\\.[^?#/.]+(?:[?#]|$)))*/?)?([^?#/]*))(?:\\?([^#]*))?(?:#(.*))?)").exec(c), b = {}, a = 14; a--;) b[h[a]] = c[a] || "";
b.queryKey = {};
b[h[12]].replace(/(?:^|&)([^&=]*)=?([^&]*)/g, function (a, k, m) {
k && (b.queryKey[k] = m)
});
return b
}
}
})();
Spotify.Utils.Base62 = function () {
function d(a, b, m) {
for (var c = [0], h = [1], d = 0; d < a.length; ++d) {
for (var g = c, s = h, t = a[d], u = m, w = 0, v = 0; v < s.length; ++v) w = ~~g[v] + s[v] * t + w, g[v] = w % u, w = ~~ (w / u);
for (; w;) w = ~~g[v] + w, g[v] = w % u, w = ~~ (w / u), ++v;
g = h;
s = b;
t = m;
for (u = v = 0; u < g.length; ++u) v = g[u] * s + v, g[u] = v % t, v = ~~ (v / t);
for (; v;) g.push(v % t), v = ~~ (v / t)
}
return c
}
function g(a, b) {
for (var m = 0, c = []; m < a.length; ++m) c.push(b[a[m]]);
return c.reverse()
}
function c(a, b) {
for (; a.length < b;) a.push(0);
return a
}
for (var h = {}, b = {}, a = 0; a < 62; ++a) b["0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ" [a]] =
a;
for (a = 0; a < 16; ++a) h["0123456789abcdef" [a]] = a;
for (a = 0; a < 16; ++a) h["0123456789ABCDEF" [a]] = a;
return {
fromBytes: function (a, b) {
var m = d(a.slice(0).reverse(), 256, 62);
return g(c(m, b), "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ").join("")
},
toBytes: function (a, k) {
var m = d(g(a, b), 62, 256);
return c(m, k).reverse()
},
toHex: function (a, k) {
var m = d(g(a, b), 62, 16);
return g(c(m, k), "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ").join("")
},
fromHex: function (a, b) {
var m = d(g(a, h), 16, 62);
return g(c(m,
b), "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ").join("")
}
}
}();
Spotify.Utils.Base64 = function () {
for (var d = [], g = 0; g < 256; ++g) d[g] = 255;
for (g = 0; g < 64; ++g) d["ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/".charCodeAt(g)] = g;
var c = String.fromCharCode.apply(String, d);
return {
encode: function (c) {
var b, a, f, k, m, d;
f = c.length;
a = 0;
for (b = ""; a < f;) {
k = c.charCodeAt(a++) & 255;
if (a == f) {
b += "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/".charAt(k >> 2);
b += "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/".charAt((k & 3) << 4);
b += "==";
break
}
m =
c.charCodeAt(a++);
if (a == f) {
b += "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/".charAt(k >> 2);
b += "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/".charAt((k & 3) << 4 | (m & 240) >> 4);
b += "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/".charAt((m & 15) << 2);
b += "=";
break
}
d = c.charCodeAt(a++);
b += "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/".charAt(k >> 2);
b += "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/".charAt((k & 3) << 4 | (m &
240) >> 4);
b += "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/".charAt((m & 15) << 2 | (d & 192) >> 6);
b += "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/".charAt(d & 63)
}
return b
},
decode: function (h) {
for (var b = [], a = h.length, f, k, m = 0;;) {
do f = c.charCodeAt(h.charCodeAt(m++) & 255); while (f === 255 && m < a);
do k = c.charCodeAt(h.charCodeAt(m++) & 255); while (k === 255 && m < a);
if (k === 255) break;
b.push((f << 2 | k >> 4) & 255);
do f = c.charCodeAt(h.charCodeAt(m++) & 255); while (f === 255 && m < a);
if (f === 255) break;
b.push((k <<
4 | f >> 2) & 255);
do k = c.charCodeAt(h.charCodeAt(m++) & 255); while (k === 255 && m < a);
if (k === 255) break;
b.push((f << 6 | k) & 255)
}
if (b.length < 4096) b = String.fromCharCode.apply(String, b);
else {
h = 0;
a = [];
do a.push(String.fromCharCode.apply(String, b.slice(h, h + 4096))), h += 4096; while (h < b.length);
b = a.join("")
}
return b
}
}
}();
Spotify.Calls.Hermes = function (d, g, c) {
this.calleeId = "";
this.success = g || function () {};
this.error = c || function () {};
this.type = d.type || "";
this.persistent = typeof d.persistent === "undefined" ? !0 : d.persistent;
this.bypassCache = typeof d.bypassCache === "undefined" ? !1 : d.bypassCache;
this.context = d.context || null;
this.isMultiGet = typeof d.isMultiGet === "undefined" ? !1 : d.isMultiGet;
this.header = {
uri: "",
method: "",
source: "",
content_type: this.isMultiGet ? "vnd.spotify/mercury-mget-request" : ""
};
this.payload = [];
this.payloadSchemas = [];
this.responseSchemas = [];
this.mercuryMultiGetPayloadSchemas = ["mercury#MercuryMultiGetRequest"];
this.mercuryMultiGetResponseSchemas = ["mercury#MercuryMultiGetReply"];
if (d.header) this.header.uri = d.header.uri || "", this.header.method = d.header.method || "", this.header.source = d.header.source || "";
this.payload = d.payload || [];
this.payloadSchemas = d.payloadSchemas || [];
this.responseSchemas = d.responseSchemas || []
};
Spotify.Calls.Simple = function (d, g, c) {
this.calleeId = "";
this.success = g || function () {};
this.error = c || function () {};
this.type = d.type || "";
this.payload = d.payload || [];
this.persistent = d.persistent || !0;
this.bypassCache = d.bypassCache || !1;
this.method = d.method || "";
this.context = d.context || null;
this.retries = d.retries || 2
};
Spotify.Errors.Domains.HERMES_ERROR = 13;
Spotify.Errors.Domains.HERMES_SERVICE_ERROR = 14;
Spotify.Errors.Codes.HM_TOO_MANY_REQUESTS = 429;
Spotify.Errors.Codes.HM_TIMEOUT = 408;
Spotify.Errors.Codes.HM_FAILED_TO_SEND_TO_BACKEND = 1;
Spotify.Errors.Domains.TRACK_ERROR = 12;
Spotify.Errors.Codes.TRACK_REQUEST_RATE_LIMITED = 8;
Spotify.Errors.Codes.TRACK_CAP = 11;
Spotify.Errors.Codes.TIME_CAP = 12;
Spotify.Errors.Codes.ADS_ERROR = 15;
Spotify.Errors.Codes.ADS_SERVER_ERROR = 500;
Spotify.Errors.Codes.ADS_NOT_FOUND = 404;
Spotify.Errors.Error = function (d) {
d = d || [];
this.domain = d[0] || 0;
this.code = d[1] || 0;
this.description = d[2] || "";
this.data = d[3] || null
};
Spotify.RateLimiter = function (d, g) {
Spotify.EventTarget.call(this);
var c = this,
h = !1,
b = [],
a = new Spotify.Events,
f = 0;
this.totalPendingRequests = function () {
return b.length
};
this.getItemAtIndex = function (a) {
return b[a]
};
this.addToBucket = function (a, f) {
typeof f === "undefined" && (f = !0);
typeof a !== "undefined" && (f ? b.push(a) : b[0] = a)
};
this.isStarted = function () {
return h
};
this.start = function () {
h || (h = !0, clearInterval(f), f = setInterval(k, d))
};
var k = function () {
var k = 0,
d, p = g;
if (g > b.length) p = b.length;
for (; k < p; k++) d = b.shift(),
c.trigger(a.RATE_LIMIT_CALL, d);
c.trigger(a.RATE_LIMIT_AFTER_INTERVAL);
b.length === 0 && (h = !1, clearInterval(f), c.trigger(a.RATE_LIMIT_DISABLED))
}
};
Spotify.CallsManager = function () {
var d = 0,
g = {}, c = [0];
this.addCall = function (c, b, a, f, k, m, o, p) {
var q = (new Date).getTime();
d++;
g[d] = {
method: c,
params: b,
callback: a,
errback: f,
context: k,
persistent: m,
retries: typeof o === "undefined" ? 2 : o,
timestamp: q,
callType: p
};
return d
};
this.getCall = function (c, b) {
typeof b === "undefined" && (b = !0);
if (typeof g[c] !== void 0) {
var a = g[c];
b && delete g[c];
return a
}
};
this.getCalls = function () {
var c, b, a = [];
for (b in g) c = b, c = this.getCall(c), c.retries > 0 && a.push(c);
return a
};
this.getPersistentCalls =
function () {
for (var h = 0, b = c.length, a, f = []; h < b; h++) c[h] !== null && c[h] !== 0 && (a = c[h], f.push(this.getCall(a)));
c = [0];
return f
};
this.setPersistent = function (h, b) {
b === !0 ? c.push(h) : c[0] = h
}
};
Spotify.Managers.ProtobufSchemasManager = function () {
var d = Spotify.DebuggerJS,
g = {};
this.registerSchema = function (c, h) {
d.log("Spotify.Managers.ProtobufSchemasManager", ["Registering schema with id", c], "corejs");
typeof g[c] !== "undefined" ? d.error("Spotify.Managers.ProtobufSchemasManager", ["Schema with id", c, "already exists"], "corejs") : (g[c] = new Spotify.Protobuf.Schema([], null, null, null), g[c].id = c, g[c].type = "proto", g[c].setData(h), g[c].encode())
};
this.getProtobufMsgParser = function (c, h) {
return typeof g[c] ===
"undefined" ? null : g[c].msg(h)
}
};
Spotify.ConnectionManager = function () {
Spotify.EventTarget.call(this);
var d = this,
g = 0,
c, h = new Spotify.Events,
b, a = function () {
d.trigger(h.ON_TRY_TO_CONNECT)
}, f = function () {
g = 0;
typeof c !== "undefined" && clearTimeout(c)
};
this.reset = function () {
typeof c !== "undefined" && clearTimeout(c);
g = 0;
c = setTimeout(a, 0)
};
var k = function (f) {
var b = [];
typeof f !== "undefined" && (b = f.params || []);
f = Math.pow(2, g) * 1E3;
g % 4 === 0 && g !== 0 && d.trigger(h.NOTIFY_OF_DISCONNECT, b);
f > 3E4 && (f = 3E4);
g++;
c && clearTimeout(c);
f === 1E3 && (f = 0);
c = setTimeout(a,
f)
};
this.initialize = function (a) {
b = a;
b.bind(h.CONNECTION_ESTABLISHED, f, this);
b.bind(h.FAILED_CONNECTING, k, this)
}
};
Spotify.Worker = function () {
Spotify.EventTarget.call(this);
var d = this,
g, c, h, b = new Spotify.Events,
a = function (a) {
eval(a.params)
}, f = function () {}, k = function () {};
this.reply = function () {
var a = Array.prototype.slice.call(arguments);
h.rpc("work_done", a, k, f, d, !1, 0, "work_done")
};
this.run = function (a) {
c.onReady(function () {
var f = "undefined 0";
g || (g = c.getInterface());
try {
f = g.run(a)
} catch (b) {}
h.rpc("pong_flash", [f], function () {}, function () {}, d, !1, 0, "pong_flash")
}, this)
};
this.initialize = function (f, k) {
h = f;
c = k;
h.bind(b.WORK,
a, this);
h.bind(b.PING_FLASH, a, this)
}
};
(function () {
Spotify.LinkedList = function () {
this.length = 0;
this.last = this.first = null
};
Spotify.LinkedList.prototype.append = function (d) {
if (d === null) throw Error("Node is null!");
if (d.list !== null) throw Error("Node already exists in another list!");
d.list = this;
this.first === null ? this.first = d : (d.prev = this.last, d.next = null, this.last.next = d);
this.last = d;
this.length++
};
Spotify.LinkedList.prototype.insertAfter = function (d, g) {
if (d === null || g === null) throw Error("Node is null!");
if (g.list !== null) throw Error("Node already exists in another list!");
g.list = this;
g.prev = d;
g.next = d.next;
d.next.prev = g;
d.next = g;
if (g.prev === this.last) this.last = g;
this.length++
};
Spotify.LinkedList.prototype.remove = function (d) {
if (d === null) throw Error("Node is null!");
if (this.length == 0 || d.list !== this) return !1;
else if (this.length > 1) {
if (d.prev !== null) d.prev.next = d.next;
if (d.next !== null) d.next.prev = d.prev;
if (d === this.first) this.first = d.next;
else if (d === this.last) this.last = d.prev
} else this.last = this.first = null;
delete d.list;
delete d.prev;
delete d.next;
d.list = null;
d.prev = null;
d.next = null;
this.length--;
return !0
};
Spotify.LinkedList.Node = function (d) {
this.next = this.prev = this.list = null;
this.value = d || null
}
})();
(function () {
Spotify.SimpleCache = function (d) {
this._limit = d || 100;
this._map = {};
this._lru = new Spotify.LinkedList;
this._stats = {
hits: 0,
misses: 0
}
};
Spotify.SimpleCache.prototype.get = function (d) {
if (d = this._map[d]) return this._lru.remove(d), this._lru.append(d), this._stats.hits++, d.value;
this._stats.misses++;
return null
};
Spotify.SimpleCache.prototype.put = function (d, g) {
if (typeof d == "undefined" || d == null || d == "") throw Error("Cache key can't be empty!");
this._lru.length >= this._limit && (delete this._map[this._lru.first.key],
this._lru.remove(this._lru.first));
var c = this._map[d];
c ? (this._lru.remove(c), c.value = g) : (c = new Spotify.LinkedList.Node(g), c.key = d);
this._lru.append(c);
this._map[d] = c
};
Spotify.SimpleCache.prototype.remove = function (d) {
var g = this._map[d];
return g ? (this._lru.remove(g), delete this._map[d], g.value) : null
};
Spotify.SimpleCache.prototype.removeAllContaining = function (d) {
var g, c = [],
h;
for (h in this._map)
if (h.indexOf(d) >= 0 && (g = this._map[h])) this._lru.remove(g), delete this._map[h], c.push(h);
return c
};
Spotify.SimpleCache.prototype.size =
function () {
return this._lru.length
};
Spotify.SimpleCache.prototype.clear = function () {
this._lru = new Spotify.LinkedList;
this._map = {}
}
})();
Spotify.Cache.PackageStore = function (d) {
var g = function (a) {
return a
}, c = function (a) {
return a
}, h = "PackageStore",
b = function () {
var a = {};
Spotify.Storage.localStorage.getItem(h) !== null && (a = JSON.parse(c(Spotify.Storage.localStorage.getItem(h))));
return a
};
if (typeof d !== "undefined") typeof d.storageKey !== "undefined" && (h = d.storageKey), typeof d.encrypt === "function" && (g = d.encrypt), typeof d.decrypt === "function" && (c = d.decrypt);
this.setItem = function (a, f) {
var k = b();
k[a] = f;
return Spotify.Storage.localStorage.setItem(h,
g(JSON.stringify(k)))
};
this.getItem = function (a) {
var f = b();
return typeof f[a] === "undefined" ? null : f[a]
};
this.removeItem = function (a) {
var f = b();
delete f[a];
return Spotify.Storage.localStorage.setItem(h, g(JSON.stringify(f)))
};
this.clear = function () {
return Spotify.Storage.localStorage.removeItem(h)
};
this.length = function () {
var a = b(),
f = 0,
k;
for (k in a) a.hasOwnProperty(k) && (f += 1);
return f
};
this.key = function (a) {
var f = b(),
k = 0,
m;
for (m in f)
if (f.hasOwnProperty(m)) {
if (k === a) return m;
k += 1
}
return null
}
};
Spotify.Cache.Default = function (d, g) {
this._limit = d || 100;
this._storage = g || new Spotify.Cache.MemoryStorage;
this._keyToNode = {};
this._lru = new Spotify.LinkedList;
this._stats = {
hits: 0,
misses: 0
};
this.initialize = function (c, h, b) {
if (!Spotify.Utils.isFunction(c) || !Spotify.Utils.isFunction(h)) throw new TypeError("Argument is not a function!");
var a = function (a, f) {
var b = new Spotify.LinkedList.Node(f);
b.key = a;
this._lru.append(b);
this._keyToNode[a] = b
}, f = function () {
c.call(b, this)
};
this._storage.initialize(function () {
this._storage.each(a,
f, this)
}, h, this)
};
this.get = function (c, h, b) {
if (!Spotify.Utils.isFunction(h)) throw new TypeError("Argument is not a function!");
this._storage.get(c, function (a, f) {
var k = this._keyToNode[a] || null;
f !== null && k !== null ? (this._lru.remove(k), this._lru.append(k), this._stats.hits++, h.call(b, a, f)) : (this._stats.misses++, h.call(b, a, null))
}, this)
};
this.put = function (c, h, b, a, f, k) {
if (typeof c == "undefined" || c == null || c == "") throw Error("Cache key can't be empty!");
var m = function (c, d, g) {
if (d === null)
if (Spotify.Utils.isFunction(f) &&
f.call(k, g), d = Math.floor(this._lru.length * 0.9), d == 0) a.call(k, c, null);
else {
for (; this._lru.length > d;) this._storage.remove(this._lru.first.key), this._lru.remove(this._lru.first);
this._storage.set(c, h, m, this)
} else Spotify.Utils.isFunction(b) && b.call(k, c, d)
};
this._lru.length >= this._limit && (this._storage.remove(this._lru.first.key), this._lru.remove(this._lru.first));
this._storage.get(c, function (a, f) {
var b = this._keyToNode[a] || null;
f !== null && b !== null ? (this._lru.remove(b), b.value = h) : (b = new Spotify.LinkedList.Node(h),
b.key = a);
this._lru.append(b);
this._keyToNode[a] = b;
this._storage.set(a, h, m, this)
}, this)
};
this.remove = function (c, h, b) {
this._storage.get(c, function (a, f) {
var k = this._keyToNode[a] || null;
f !== null && k !== null ? (this._lru.remove(k), this._storage.remove(a, h, b)) : Spotify.Utils.isFunction(h) && h.call(b, a)
}, this)
};
this.removeAllContaining = function (c, h, b) {
this._storage.removeAllContaining(c, function (a) {
for (var f = 0; f < a.length; f++) {
var k = this._keyToNode[a[f]] || null;
k !== null && this._lru.remove(k)
}
Spotify.Utils.isFunction(h) &&
h.call(b, a)
}, this)
};
this.size = function () {
return this._lru.length
};
this.clear = function (c, h) {
this._lru = new Spotify.LinkedList;
this._storage.clear(c, h)
}
};
Spotify.Cache.DummyStorage = function () {
this.initialize = function (d, g, c) {
if (!Spotify.Utils.isFunction(d) || !Spotify.Utils.isFunction(g)) throw new TypeError("Argument is not a function!");
g.call(c)
};
this.isSupported = function () {
return !0
}
};
Spotify.Cache.MemoryStorage = function () {
this._data = {};
this.get = function (d, g, c) {
if (!Spotify.Utils.isFunction(g)) throw new TypeError(ERROR_NOT_A_FUNCTION);
g.call(c, d, this._data[d] || null)
};
this.set = function (d, g, c, h) {
this._data[d] = g;
Spotify.Utils.isFunction(c) && c.call(h, d, g)
};
this.remove = function (d, g, c) {
delete this._data[d];
Spotify.Utils.isFunction(g) && g.call(c, d)
};
this.removeAllContaining = function (d, g, c) {
var h = [],
b = this._data,
a;
for (a in b) a.indexOf(d) >= 0 && (h.push(a), delete this._data[a]);
Spotify.Utils.isFunction(g) &&
g.call(c, h)
};
this.clear = function (d, g) {
this._data = {};
Spotify.Utils.isFunction(d) && d.call(g)
};
this.each = function (d, g, c) {
if (!Spotify.Utils.isFunction(d)) throw new TypeError(ERROR_NOT_A_FUNCTION);
var h = this._data,
b;
for (b in h) d.call(c, b, h[b]);
Spotify.Utils.isFunction(g) && g.call(c)
};
this.initialize = function (d, g, c) {
if (!Spotify.Utils.isFunction(d) || !Spotify.Utils.isFunction(g)) throw new TypeError(ERROR_NOT_A_FUNCTION);
d.call(c)
};
this.isSupported = function () {
return !0
}
};
Spotify.Cache.LocalStorage = function (d) {
this._prefix = "com.spotify.cache." + (d || "generic") + ".";
this.get = function (d, c, h) {
if (!Spotify.Utils.isFunction(c)) throw new TypeError("Argument is not a function!");
var b = Spotify.Storage.localStorage.getItem(this._prefix + d);
c.call(h, d, b ? JSON.parse(b) : null)
};
this.set = function (d, c, h, b) {
try {
Spotify.Storage.localStorage.setItem(this._prefix + d, JSON.stringify(c)), Spotify.Utils.isFunction(h) && h.call(b, d, c)
} catch (a) {
Spotify.Utils.isFunction(h) && h.call(b, d, null, a)
}
};
this.remove =
function (d, c, h) {
Spotify.Storage.localStorage.removeItem(this._prefix + d);
Spotify.Utils.isFunction(c) && c.call(h, d)
};
this.removeAllContaining = function (d, c, h) {
for (var b = [], a = Spotify.Storage.localStorage, d = this._prefix + d, f, k = 0, m = a.length; k < m; k++) f = a.key(k), f.indexOf(d) >= 0 && (b.push(f.substring(this._prefix.length)), a.removeItem(f), k--, m--);
Spotify.Utils.isFunction(c) && c.call(h, b)
};
this.clear = function (d, c) {
for (var h = Spotify.Storage.localStorage, b = h.length - 1; b >= 0; --b) {
var a = h.key(b);
a.indexOf(this._prefix) ==
0 && h.removeItem(a)
}
Spotify.Utils.isFunction(d) && d.call(c)
};
this.each = function (d, c, h) {
if (!Spotify.Utils.isFunction(d)) throw new TypeError("Argument is not a function!");
for (var b = Spotify.Storage.localStorage, a = 0, f = b.length; a < f; ++a) {
var k = b.key(a);
if (k.indexOf(this._prefix) == 0) {
var m = b.getItem(k);
d.call(h, k.slice(this._prefix.length), m ? JSON.parse(m) : null)
}
}
Spotify.Utils.isFunction(c) && c.call(h)
};
this.initialize = function (d, c, h) {
if (!Spotify.Utils.isFunction(d) || !Spotify.Utils.isFunction(c)) throw new TypeError("Argument is not a function!");
d.call(h)
};
this.isSupported = function () {
return typeof Spotify.Storage.localStorage !== "undefined"
}
};
Spotify.Cache.IndexedDBStorage = function (d) {
var g = null,
c = function (b, a, f, k, m) {
var c = Spotify.Storage.indexedDB.storage.open(b, a);
c.onsuccess = function (c) {
var h = c.target.result;
Spotify.Utils.isFunction(h.setVersion) ? (c = parseInt(h.version || "0", 10), c < a ? (c = h.setVersion(a.toString()), c.onsuccess = function () {
h.objectStoreNames.contains(b) || h.createObjectStore(b);
f.call(m, h)
}, c.onerror = function () {
k.call(m)
}) : c == a ? f.call(m, h) : k.call(m)) : f.call(m, h)
};
c.onerror = function () {
k.call()
};
c.onupgradeneeded = function (a) {
a =
a.target.result;
a.objectStoreNames.contains(b) || a.createObjectStore(b)
}
}, h = function (b, a) {
return function (f) {
g = f;
b.call(a)
}
};
this._open = function (b, a, f) {
c(d, 1, h(b, f), a)
};
this._transaction = function (b) {
return g.transaction(d, b).objectStore(d)
};
this.get = function (b, a, f) {
if (!Spotify.Utils.isFunction(a)) throw new TypeError(ERROR_NOT_A_FUNCTION);
var k = this._transaction("readonly").get(b);
k.onsuccess = function (k) {
a.call(f, b, k.target.result)
};
k.onerror = function (k) {
a.call(f, b, null, k.target.errorCode)
}
};
this.set =
function (b, a, f, k) {
var m = this._transaction("readwrite").put(a, b);
if (Spotify.Utils.isFunction(f)) m.onsuccess = function () {
f.call(k, b, a)
}, m.onerror = function (a) {
f.call(k, b, null, a.target.errorCode)
}
};
this.remove = function (b, a, f) {
var k = this._transaction("readwrite")["delete"](b);
if (Spotify.Utils.isFunction(a)) k.onsuccess = function () {
a.call(f, b)
}, k.onerror = function () {
a.call(f, null, e.target.errorCode)
}
};
this.removeAllContaining = function (b, a, f) {
var k = [];
this._transaction("readwrite").openCursor().onsuccess = function (m) {
(m =
m.target.result) ? (m.key.indexOf(b) >= 0 && (k.push(m.key), m["delete"]()), m["continue"]()) : Spotify.Utils.isFunction(a) && a.call(f, k)
}
};
this.clear = function (b, a) {
var f = this._transaction("readwrite").clear();
if (Spotify.Utils.isFunction(b)) f.onsuccess = function () {
b.call(a)
}, f.onerror = function () {
b.call(a)
}
};
this.each = function (b, a, f) {
if (!Spotify.Utils.isFunction(b)) throw new TypeError(ERROR_NOT_A_FUNCTION);
this._transaction("readonly").openCursor().onsuccess = function (k) {
(k = k.target.result) ? (b.call(f, k.key, k.value),
k["continue"]()) : Spotify.Utils.isFunction(a) && a.call(f)
}
};
this.initialize = function (b, a, f) {
if (!Spotify.Utils.isFunction(b) || !Spotify.Utils.isFunction(a)) throw new TypeError(ERROR_NOT_A_FUNCTION);
this._open(b, a, f)
};
this.isSupported = function () {
return Spotify.Storage.indexedDB.storage ? !0 : !1
}
};
Spotify.Cache.FileSystemStorage = function () {
throw Error("Not implemented!");
};
Spotify.Cache.PackageStore = function (d) {
var g = function (a) {
return a
}, c = function (a) {
return a
}, h = "PackageStore",
b = function () {
var a = {};
Spotify.Storage.localStorage.getItem(h) !== null && (a = JSON.parse(c(Spotify.Storage.localStorage.getItem(h))));
return a
};
if (typeof d !== "undefined") typeof d.storageKey !== "undefined" && (h = d.storageKey), typeof d.encrypt === "function" && (g = d.encrypt), typeof d.decrypt === "function" && (c = d.decrypt);
return {
setItem: function (a, f) {
var k = b();
k[a] = f;
return Spotify.Storage.localStorage.setItem(h,
g(JSON.stringify(k)))
},
getItem: function (a) {
var f = b();
return typeof f[a] === "undefined" ? null : f[a]
},
removeItem: function (a) {
var f = b();
delete f[a];
return Spotify.Storage.localStorage.setItem(h, g(JSON.stringify(f)))
},
clear: function () {
return Spotify.Storage.localStorage.remove(h)
},
length: function () {
var a = b(),
f = 0,
k;
for (k in a) a.hasOwnProperty(k) && (f += 1);
return f
},
key: function (a) {
var f = b(),
k = 0,
m;
for (m in f)
if (f.hasOwnProperty(m)) {
if (k === a) return m;
k += 1
}
return null
}
}
};
Spotify.Cache.Types = {
PERSISTENT: "persistent",
TEMPORARY: "temporary"
};
(function () {
var d;
Spotify.Events = function () {
return typeof d !== "undefined" ? d : d = {
REQUEST: "REQUEST",
DATA_ERROR: "DATA_ERROR",
TRACK_PLAY_REQUEST: "TRACK_PLAY_REQUEST",
WAIT_FOR_COMMERCIAL_TO_FINISH: "WAIT_FOR_COMMERCIAL_TO_FINISH",
INTERCEPTED: "intercepted",
USER_INFO_CHANGE: "USER_INFO_CHANGE",
TRACK_ENDED: "TRACK_ENDED",
PLAYER_STATE: "PLAYER_STATE",
BEFORE_END: "BEFORE_END",
BEFORE_SEEK: "BEFORE_SEEK",
LOAD: "LOAD",
SONG_LOADED: "SONG_LOADED",
FIRST_BYTES: "FIRST_BYTES",
POSITION_CHANGED: "POSITION_CHANGED",
VOLUME_CHANGED: "VOLUME_CHANGED",
PLAYING: "PLAYING",
PAUSED: "PAUSED",
STOPPED: "STOPPED",
ACTIVE_PLAYER_CHANGED: "ACTIVE_PLAYER_CHANGED",
CONNECTION_ESTABLISHED: "CONNECTION_ESTABLISHED",
CONNECTION_CLOSED: "CONNECTION_CLOSED",
CONNECTED: "CONNECTED",
DISCONNECTED: "DISCONNECTED",
STREAM_INITIALIZED: "STREAM_INITIALIZED",
PLAYER_LOADED: "PLAYER_LOADED",
PLAYER_EVENT: "PLAYER_EVENT",
STREAM_LIMIT_REACHED: "STREAM_LIMIT_REACHED",
AUTHENTICATED: "AUTHENTICATED",
ERROR: "ERROR",
SUCCESS: "SUCCESS",
FAILED_CONNECTING: "FAILED_CONNECTING",
INVALID_TRACK_URI: "INVALID_TRACK_URI",
CANNOT_PLAY_TRACK: "CANNOT_PLAY_TRACK",
REGION_BLOCKED: "REGION_BLOCKED",
ACCOUNT_IN_USE: "ACCOUNT_IN_USE",
PLAYBACK_FAILED: "PLAYBACK_FAILED",
SECURITY_ERROR: "SECURITY_ERROR",
UNKNOWN_ERROR: "UNKNOWN_ERROR",
RPC_CALLBACK: "RPC_CALLBACK",
RPC_ERRBACK: "RPC_ERRBACK",
RPC_LOGGING_LATENCY_CALLBACK: "RPC_LOGGING_LATENCY_CALLBACK",
RPC_LOGGING_LATENCY_ERRBACK: "RPC_LOGGING_LATENCY_ERRBACK",
RPC_SUCCESS: "RPC_SUCCESS",
RPC_ERROR: "RPC_ERROR",
REAUTHORIZE_SUCCESS: "REAUTHORIZE_SUCCESS",
REAUTHORIZE_FAILED: "REAUTHORIZE_FAILED",
FLASH_LOADED: "FLASH_LOADED",
FLASH_UNAVAILABLE: "FLASH_UNAVAILABLE",
FLASH_AVAILABLE: "FLASH_AVAILABLE",
INITIALIZED: "INITIALIZED",
READY: "READY",
NOT_READY: "NOT_READY",
TOKEN_ACQUIRED: "TOKEN_ACQUIRED",
TOKEN_NOT_ACQUIRED: "TOKEN_NOT_ACQUIRED",
ON_TRY_TO_CONNECT: "ON_TRY_TO_CONNECT",
NOTIFY_OF_DISCONNECT: "NOTIFY_OF_DISCONNECT",
FATAL_ERROR: "FATAL_ERROR",
TOKEN_LOST: "TOKEN_LOST",
WORK: "WORK",
PING_FLASH: "PING_FLASH",
LOGIN_COMPLETE: "LOGIN_COMPLETE",
HERMES_B64_MESSAGE: "HERMES_B64_MESSAGE",
TIMEOUT: "TIMEOUT",
NO_SOUND_CAPABILITIES: "NO_SOUND_CAPABILITIES",
ON_REAUTHENTICATION_SUCCESS: "ON_REAUTHENTICATION_SUCCESS",
ON_REAUTHENTICATION_FAILED: "ON_REAUTHENTICATION_FAILED",
STORAGE_FULL: "STORAGE_FULL",
RATE_LIMIT_CALL: "RATE_LIMIT_CALL",
RATE_LIMIT_DISABLED: "RATE_LIMIT_DISABLED",
RATE_LIMIT_AFTER_INTERVAL: "RATE_LIMIT_AFTER_INTERVAL",
REMOTE_SERVICE_DOWN: "REMOTE_SERVICE_DOWN",
NOTIFICATION: "NOTIFICATION",
RELATIONS_SUBSCRIBE: "RELATIONS_SUBSCRIBE",
RELATIONS_UNSUBSCRIBE: "RELATIONS_UNSUBSCRIBE",
RELATIONS_DISMISS: "RELATIONS_DISMISS",
RELATIONS_UNDISMISS: "RELATIONS_UNDISMISS",
RELATIONS_BLOCK: "RELATIONS_BLOCK",
RELATIONS_UNBLOCK: "RELATIONS_UNBLOCK",
CHANGED: "CHANGED",
DURATION: "DURATION",
PLAYER_CREATED: "PLAYER_CREATED",
PLAYLIST_SUBSCRIBE: "PLAYLIST_SUBSCRIBE",
TIME_CAP: "TIME_CAP",
CHANGE: "CHANGE",
RECORD_AD_EVENT: "RECORD_AD_EVENT"
}
}
})();
Spotify.Resolvers = {
STORAGE_RESOLVER: "STORAGE_RESOLVER",
AD_RESOLVER: "AD_RESOLVER",
PREVIEW_RESOLVER: "PREVIEW_RESOLVER"
};
Spotify.Ajax = function (d) {
var g = Spotify.DebuggerJS,
d = d || {}, c = {};
c.method = d.method || "GET";
c.dataType = d.dataType || "text";
c.url = d.url || void 0;
c.data = d.data || "";
c.async = d.async !== void 0 ? d.async : !0;
c.success = d.success || void 0;
c.error = d.error || void 0;
c.context = d.context || void 0;
this.POST = "POST";
this.GET = "GET";
this.JSON = "json";
this.XML = "xml";
this.TEXT = "text";
this.execute = function () {
var h, b = c.url,
a = "",
f, k = function (a) {
c.context !== void 0 ? c.error.call(c.context, a) : c.error(a)
}, m = function () {
if (typeof c.success !==
"undefined") {
if (c.dataType === "xml") try {
f = h.responseXML || Spotify.Utils.convertStringToXML(h.responseText)
} catch (a) {
k(a)
}
if (c.dataType === "json") try {
f = JSON.parse(h.responseText)
} catch (b) {
k(b)
}
c.dataType === "text" && (f = h.responseText);
c.context !== void 0 ? c.success.call(c.context, f, h) : c.success(f, h)
}
}, d = function () {
typeof c.error !== "undefined" && k()
}, p = function () {
m()
}, q = function (a) {
d(a)
};
h = XMLHttpRequest ? new XMLHttpRequest : new ActiveXObject("Microsoft.XMLHTTP");
c.method === this.POST ? a = c.data : b += c.data !== "" ?
"?" + c.data : "";
try {
try {
h.open(c.method, b, c.async)
} catch (n) {
if (XDomainRequest) g.log("Spotify.Ajax", ["Trying Cors"], "corejs"), h = new XDomainRequest, h.onprogress = function () {}, h.onload = p, h.onerror = q, h.open(c.method, b, c.async);
else throw Error("CORS not supported");
}
h.send(a)
} catch (s) {
g.error("Spotify.Ajax", [s], "corejs"), k(s)
}
h.onreadystatechange = function () {
h.readyState === 4 && h.status >= 200 && h.status < 300 ? m() : h.status >= 400 && d()
};
return h
}
};
Spotify.Service = function () {
Spotify.EventTarget.call(this);
this.url = "";
this.method = "GET";
this.dataType = "text";
this.data = "";
this.async = !0;
this.fetch = function () {
(new Spotify.Ajax({
method: this.method,
dataType: this.dataType,
url: this.url,
data: this.data,
success: d,
error: g,
context: this
})).execute()
};
var d = function (c, h) {
this.trigger("onSuccess", {
result: c,
request: h
})
}, g = function (c) {
this.trigger("onError", {
error: c
})
}
};
Spotify.Proto.Data = function (d, g) {
Spotify.EventTarget.call(this);
var c = this,
h, b = {}, a = new Spotify.Events;
this.initialize = function () {
var a = new Spotify.Service;
a.url = d + "data.xml" + g;
a.async = !1;
a.dataType = "text";
a.bind("onSuccess", f, this);
a.bind("onError", k, this);
a.fetch()
};
this.getDefinition = function (a) {
if (typeof b[a] !== "undefined") return b[a];
var f = h.getElementsByTagName(a);
return typeof f !== "undefined" && f[0] && f[0].firstChild ? (b[a] = f[0].firstChild.data + "\n", b[a]) : ""
};
this.getMultipleDefinitions = function (a) {
var f =
"",
k = 0,
c, d;
if (!Spotify.Utils.isArray(a)) throw Error("Definition identifiers must be an array with strings");
for (; k < a.length; k++) d = a[k], typeof b[d] !== "undefined" ? f += b[d] : (c = h.getElementsByTagName(d), typeof c !== "undefined" && c[0] && c[0].firstChild && (b[d] = c[0].firstChild.data + "\n", f += b[d]));
return f
};
var f = function (f) {
h = Spotify.Utils.convertStringToXML(f.params.result);
c.trigger(a.SUCCESS)
}, k = function (f) {
c.trigger(a.ERROR, f.params)
}
};
(function () {
Spotify.Link = function (a, b) {
this.type = a;
for (var m in b) this[m] = b[m]
};
var d = Spotify.Link;
d.Type = {
EMPTY: "empty",
ALBUM: "album",
AD: "ad",
APPLICATION: "application",
ARTIST: "artist",
ARTIST_TOPLIST: "artist-toplist",
AUDIO_FILE: "audiofile",
COLLECTION: "collection",
COLLECTION_ALBUM: "collection-album",
COLLECTION_MISSING_ALBUM: "collection-missing-album",
COLLECTION_ARTIST: "collection-artist",
CONTEXT_GROUP: "context-group",
FACEBOOK: "facebook",
FOLLOWERS: "followers",
FOLLOWING: "following",
IMAGE: "image",
INBOX: "inbox",
LOCAL_ARTIST: "local-artist",
LOCAL_ALBUM: "local-album",
LOCAL: "local",
LIBRARY: "library",
MOSAIC: "mosaic",
PLAYLIST: "playlist",
PROFILE: "profile",
PUBLISHED_ROOTLIST: "published-rootlist",
RADIO: "radio",
ROOTLIST: "rootlist",
COLLECTION_TRACK_LIST: "collectiontracklist",
SEARCH: "search",
STARRED: "starred",
TEMP_PLAYLIST: "temp-playlist",
TOPLIST: "toplist",
TRACK: "track",
TRACKSET: "trackset",
USER_TOPLIST: "user-toplist",
USET_TOP_TRACKS: "user-top-tracks"
};
var g = function (a) {
return !!a
}, c = function (a, b) {
var m, c = 1;
if (a.indexOf("spotify:") ==
0) m = a.slice(8).split(":"), c = 0;
else if (a.indexOf("http://play.spotify.com/") == 0) m = a.slice(24).split("/");
else if (a.indexOf("https://play.spotify.com/") == 0) m = a.slice(25).split("/");
else if (a.indexOf("http://open.spotify.com/") == 0) m = a.slice(24).split("/");
else if (a.indexOf("https://open.spotify.com/") == 0) m = a.slice(25).split("/");
else throw "Invalid Spotify URI!";
Array.prototype.push.apply(b, m);
return c
}, h = function (a, b) {
a = encodeURIComponent(a);
return b == 0 ? a.replace(/%20/g, "+") : a
}, b = function (a, b) {
return decodeURIComponent(b ==
0 ? a.replace(/\+/g, "%20") : a)
}, a = function (a, b) {
var m, c, g;
a.id && (m = Spotify.Utils.Base62.fromHex(a.id, 22));
switch (a.type) {
case d.Type.ALBUM:
return c = ["album", m], a.disc && c.push(a.disc), c;
case d.Type.AD:
return ["ad", a.id];
case d.Type.ARTIST:
return ["artist", m];
case d.Type.ARTIST_TOPLIST:
return ["artist", m, "top", a.toplist];
case d.Type.SEARCH:
return ["search", h(a.query, b)];
case d.Type.TRACK:
return ["track", m];
case d.Type.TRACKSET:
c = [];
for (m = 0, g = a.tracks.length; m < g; m++) c.push(Spotify.Utils.Base62.fromHex(a.tracks[m].id,
22));
c = [c.join(",")];
a.index !== null && c.push("#", a.index);
return ["trackset", h(a.name)].concat(c);
case d.Type.FACEBOOK:
return ["user", "facebook", a.uid];
case d.Type.AUDIO_FILE:
return ["audiofile", a.extension, a.id];
case d.Type.FOLLOWERS:
return ["user", h(a.username), "followers"];
case d.Type.FOLLOWING:
return ["user", h(a.username), "following"];
case d.Type.PLAYLIST:
return ["user", h(a.username), "playlist", m];
case d.Type.STARRED:
return ["user", h(a.username), "starred"];
case d.Type.TEMP_PLAYLIST:
return ["temp-playlist",
a.origin, a.data];
case d.Type.CONTEXT_GROUP:
return ["context-group", a.origin, a.name];
case d.Type.USER_TOPLIST:
return ["user", h(a.username), "top", a.toplist];
case d.Type.USET_TOP_TRACKS:
return ["user", h(a.username), "toplist"];
case d.Type.TOPLIST:
return ["top", a.toplist].concat(a.global ? ["global"] : ["country", a.country]);
case d.Type.INBOX:
return ["user", h(a.username), "inbox"];
case d.Type.ROOTLIST:
return ["user", h(a.username), "rootlist"];
case d.Type.PUBLISHED_ROOTLIST:
return ["user", h(a.username), "publishedrootlist"];
case d.Type.COLLECTION_TRACK_LIST:
return ["user", h(a.username), "collectiontracklist", m];
case d.Type.PROFILE:
return a.args && a.args.length > 0 ? ["user", h(a.username)].concat(a.args) : ["user", h(a.username)];
case d.Type.LOCAL_ARTIST:
return ["local", h(a.artist, b)];
case d.Type.LOCAL_ALBUM:
return ["local", h(a.artist, b), h(a.album, b)];
case d.Type.LOCAL:
return ["local", h(a.artist, b), h(a.album, b), h(a.track, b), a.duration];
case d.Type.LIBRARY:
return ["user", h(a.username), "library"].concat(a.category ? [a.category] : []);
case d.Type.IMAGE:
return ["image",
a.id];
case d.Type.MOSAIC:
return c = a.ids.slice(0), c.unshift("mosaic"), c;
case d.Type.RADIO:
return ["radio", a.args];
case d.Type.APPLICATION:
c = ["app", a.id];
var q = a.args || [];
for (m = 0, g = q.length; m < g; ++m) c.push(h(q[m], b));
return c;
case d.Type.COLLECTION_ALBUM:
return ["user", h(a.username), "collection", "album", m];
case d.Type.COLLECTION_MISSING_ALBUM:
return ["user", h(a.username), "collection", "album", m, "missing"];
case d.Type.COLLECTION_ARTIST:
return ["user", h(a.username), "collection", "artist", m];
case d.Type.COLLECTION:
return ["user",
h(a.username), "collection"].concat(a.category ? [a.category] : []);
default:
throw "Invalid Spotify URI!";
}
};
d.prototype.toURI = function () {
return "spotify:" + a(this, 0).join(":")
};
d.prototype.toAppLink = function () {
if (this.type == d.Type.APPLICATION) return d.applicationLink(this.id, this.args);
else {
var f = a(this, 1),
k = f.shift();
f.length && (f = f.map(function (a) {
return b(a, 1)
}));
return d.applicationLink(k, this.type == d.Type.RADIO ? f.shift().split(":") : f)
}
};
d.prototype.toAppURI = function () {
return this.type == d.Type.APPLICATION ?
this.toURI() : "spotify:" + ["app"].concat(a(this, 0)).join(":")
};
d.prototype.toURLPath = function () {
var f = a(this, 1);
f[0] === "app" && f.shift();
f[0] != "trackset" && (f = f.filter(g));
return f.join("/")
};
d.prototype.toURL = function (a) {
typeof a === "undefined" && (a = !0);
return a ? "http://play.spotify.com/" + this.toURLPath() : "/" + this.toURLPath()
};
d.prototype.toSecureURL = function () {
return "https://play.spotify.com/" + this.toURLPath()
};
d.prototype.toString = function () {
return this.toURI()
};
d.prototype.idToByteString = function () {
for (var a =
Spotify.Utils.Base62.fromHex(this.id), a = Spotify.Utils.Base62.toBytes(a), a = a.map(function (a) {
return String.fromCharCode(a)
}).join(""); a.length < 16;) a = String.fromCharCode(0) + a;
return a
};
d.fromString = function (a) {
var k = [],
m = c(a, k),
h = 0,
g = function () {
return k[h++]
}, a = function () {
var a = g();
return a.length == 22 ? Spotify.Utils.Base62.toHex(a, 32) : a
}, q = function () {
return k.slice(h).join(m == 0 ? ":" : "/")
}, n = g();
switch (n) {
case "album":
return d.albumLink(a(), parseInt(g(), 10));
case "ad":
return d.adLink(a());
case "artist":
return n =
a(), g() == "top" ? d.artistToplistLink(n, g()) : d.artistLink(n);
case "audiofile":
return d.audioFileLink(g(), g());
case "temp-playlist":
return d.temporaryPlaylistLink(g(), q());
case "search":
return d.searchLink(b(q(), m));
case "track":
return d.trackLink(a());
case "trackset":
var n = b(g()),
s = g(),
a = g(),
t = parseInt(g(), 10);
if (a !== "%23" || isNaN(t)) t = null;
var u = [];
if (s) {
s = b(s).split(",");
for (a = 0, q = s.length; a < q; a++) u.push(d.trackLink(Spotify.Utils.Base62.toHex(s[a], 32)))
}
return d.tracksetLink(u, n, t);
case "context-group":
return d.contextGroupLink(g(),
g());
case "top":
return a = g(), g() == "global" ? d.toplistLink(a, null, !0) : d.toplistLink(a, g(), !1);
case "user":
q = b(g(), m);
n = g();
if (q == "facebook" && n != null) return d.facebookLink(parseInt(n, 10));
else if (n != null) switch (n) {
case "playlist":
return d.playlistLink(q, a());
case "collectiontracklist":
return d.collectionTrackList(q, a());
case "collection":
switch (n = g(), n) {
case "album":
return n = a(), g() === "missing" ? d.collectionMissingAlbumLink(q, n) : d.collectionAlbumLink(q, n);
case "artist":
return d.collectionArtistLink(q,
a());
default:
return d.collectionLink(q, n)
}
case "starred":
return d.starredLink(q);
case "followers":
return d.followersLink(q);
case "following":
return d.followingLink(q);
case "top":
return d.userToplistLink(q, g());
case "inbox":
return d.inboxLink(q);
case "rootlist":
return d.rootlistLink(q);
case "publishedrootlist":
return d.publishedRootlistLink(q);
case "toplist":
return d.userTopTracksLink(q);
case "library":
return d.libraryLink(q, g())
}
a = k.slice(h);
return n != null && a.length > 0 ? d.profileLink(q, [n].concat(a)) :
n != null ? d.profileLink(q, [n]) : d.profileLink(q);
case "local":
return a = (a = g()) && b(a, m), n = (q = g()) && b(q, m), t = (s = g()) && b(s, m), u = g(), u = parseInt(u, 10), s !== void 0 ? d.localLink(a, n, t, u) : q !== void 0 ? d.localAlbumLink(a, n) : d.localArtistLink(a);
case "image":
return d.imageLink(a());
case "mosaic":
return d.mosaicLink(k.slice(h));
case "radio":
return d.radioLink(q());
default:
n = n === "app" ? g() : n;
s = k.slice(h);
for (a = 0, q = s.length; a < q; ++a) s[a] = b(s[a], m);
return d.applicationLink(n, s)
}
throw "Invalid Spotify URI!";
};
d.emptyLink =
function () {
return new d(d.Type.EMPTY, {})
};
d.albumLink = function (a, b) {
return new d(d.Type.ALBUM, {
id: a,
disc: b
})
};
d.adLink = function (a) {
return new d(d.Type.AD, {
id: a
})
};
d.artistLink = function (a) {
return new d(d.Type.ARTIST, {
id: a
})
};
d.artistToplistLink = function (a, b) {
return new d(d.Type.ARTIST_TOPLIST, {
id: a,
toplist: b
})
};
d.searchLink = function (a) {
return new d(d.Type.SEARCH, {
query: a
})
};
d.trackLink = function (a) {
return new d(d.Type.TRACK, {
id: a
})
};
d.tracksetLink = function (a, b, m) {
return new d(d.Type.TRACKSET, {
tracks: a,
name: b || "",
index: isNaN(m) ? null : m
})
};
d.facebookLink = function (a) {
return new d(d.Type.FACEBOOK, {
uid: a
})
};
d.audioFileLink = function (a, b) {
return new d(d.Type.AUDIO_FILE, {
id: b,
extension: a
})
};
d.followersLink = function (a) {
return new d(d.Type.FOLLOWERS, {
username: a
})
};
d.followingLink = function (a) {
return new d(d.Type.FOLLOWING, {
username: a
})
};
d.playlistLink = function (a, b) {
return new d(d.Type.PLAYLIST, {
username: a,
id: b
})
};
d.collectionTrackList = function (a, b) {
return new d(d.Type.COLLECTION_TRACK_LIST, {
username: a,
id: b
})
};
d.starredLink = function (a) {
return new d(d.Type.STARRED, {
username: a
})
};
d.userToplistLink = function (a, b) {
return new d(d.Type.USER_TOPLIST, {
username: a,
toplist: b
})
};
d.userTopTracksLink = function (a) {
return new d(d.Type.USET_TOP_TRACKS, {
username: a
})
};
d.toplistLink = function (a, b, m) {
return new d(d.Type.TOPLIST, {
toplist: a,
country: b,
global: !! m
})
};
d.inboxLink = function (a) {
return new d(d.Type.INBOX, {
username: a
})
};
d.rootlistLink = function (a) {
return new d(d.Type.ROOTLIST, {
username: a
})
};
d.publishedRootlistLink = function (a) {
return new d(d.Type.PUBLISHED_ROOTLIST, {
username: a
})
};
d.localArtistLink = function (a) {
return new d(d.Type.LOCAL_ARTIST, {
artist: a
})
};
d.localAlbumLink = function (a, b) {
return new d(d.Type.LOCAL_ALBUM, {
artist: a,
album: b
})
};
d.localLink = function (a, b, m, c) {
return new d(d.Type.LOCAL, {
artist: a,
album: b,
track: m,
duration: c
})
};
d.libraryLink = function (a, b) {
return new d(d.Type.LIBRARY, {
username: a,
category: b
})
};
d.collectionLink = function (a, b) {
return new d(d.Type.COLLECTION, {
username: a,
category: b
})
};
d.temporaryPlaylistLink = function (a, b) {
return new d(d.Type.TEMP_PLAYLIST, {
origin: a,
data: b
})
};
d.contextGroupLink = function (a, b) {
return new d(d.Type.CONTEXT_GROUP, {
origin: a,
name: b
})
};
d.profileLink = function (a, b) {
return new d(d.Type.PROFILE, {
username: a,
args: b
})
};
d.imageLink = function (a) {
return new d(d.Type.IMAGE, {
id: a
})
};
d.mosaicLink = function (a) {
return new d(d.Type.MOSAIC, {
ids: a
})
};
d.radioLink = function (a) {
a = typeof a === "undefined" ? [] : a;
return new d(d.Type.RADIO, {
args: a
})
};
d.applicationLink = function (a, b) {
b = typeof b === "undefined" ? [] : b;
return new d(d.Type.APPLICATION, {
id: a,
args: b
})
};
d.collectionAlbumLink = function (a, b) {
return new d(d.Type.COLLECTION_ALBUM, {
username: a,
id: b
})
};
d.collectionMissingAlbumLink = function (a, b) {
return new d(d.Type.COLLECTION_MISSING_ALBUM, {
username: a,
id: b
})
};
d.collectionArtistLink = function (a, b) {
return new d(d.Type.COLLECTION_ARTIST, {
username: a,
id: b
})
};
d.fromByteString = function (a, b, m) {
for (var c = [], h = 0; h < b.length; h++) c.push(b.charCodeAt(h));
b = Spotify.Utils.Base62.fromBytes(c, 22);
b = Spotify.Utils.Base62.toHex(b);
m = m || {};
m.id = b;
return new d(a, m)
}
})();
(function () {
var d;
Spotify.Logging.Types = function () {
return typeof d !== "undefined" ? d : d = {
TRACK_END: "TRACK_END",
PREVIEW_END: "PREVIEW_END",
TRACK_EVENT: "TRACK_EVENT",
TRACK_PROGRESS: "TRACK_PROGRESS",
REQUEST_TIME: "REQUEST_TIME",
AD_END: "EndAd"
}
}
})();
Spotify.Logging.TrackEnd = function () {
Spotify.EventTarget.call(this);
var d, g = function () {}, c = function () {};
this.serviceIsReady = !0;
this.log = function (h) {
d.rpc("track_end", [h.lid, h.ms_played, h.ms_played_union, h.n_seeks_forward, h.n_seeks_backward, h.ms_seeks_forward, h.ms_seeks_backward, h.ms_latency, h.display_track, h.play_context, h.source_start, h.source_end, h.reason_start, h.reason_end, h.referrer, h.referrer_version, h.referrer_vendor, h.max_continuous], g, c, this, !0, 2, "track_end")
};
this.init = function (c) {
d = c
}
};
Spotify.Logging.PreviewEnd = function () {
Spotify.EventTarget.call(this);
new Spotify.Logging.Logger;
this.serviceIsReady = !0;
this.log = function () {};
this.init = function () {}
};
Spotify.Logging.TrackEvent = function () {
Spotify.EventTarget.call(this);
var d, g = function () {}, c = function () {};
this.serviceIsReady = !0;
this.log = function (h) {
d.rpc("track_event", [h.lid, h.event, h.ms_where], g, c, this, !0, 2, "track_event")
};
this.init = function (c) {
d = c
}
};
Spotify.Logging.TrackProgress = function () {
Spotify.EventTarget.call(this);
var d = Spotify.DebuggerJS,
g, c = function (b) {
d.log("Spotify.Logging.TrackProgress", ["Track progress success", b], "corejs")
}, h = function (b) {
d.error("Spotify.Logging.TrackProgress", ["On track progress error", b], "corejs")
};
this.serviceIsReady = !0;
this.log = function (b) {
g.rpc("track_progress", [b.lid, b.source_start, b.reason_start, b.ms_played, b.ms_latency, b.play_context, b.display_track, b.referrer, b.referrer_version, b.referrer_vendor], c, h, this, !0, 2, "track_progress")
};
this.init = function (b) {
g = b
}
};
Spotify.Logging.ClientEvent = function () {
var d = function () {}, g = function () {};
this.log = function (c) {
if (typeof c.source !== "string") throw Error("Source must be a string");
if (typeof c.context !== "string") c.context = "";
if (typeof c.event !== "string") throw Error("Event name must be a string");
if (typeof c.event_version !== "string") c.event_version = "";
if (typeof c.test_version !== "string") c.test_version = "";
if (typeof c.source_version !== "string") throw Error("Source version name must be a string");
if (typeof c.source_vendor !==
"string") throw Error("Source vendor name must be a string");
if (typeof c.data !== "string") c.data = "";
this.send(new Spotify.Calls.Simple({
method: "log_ce",
payload: [c.source, c.context, c.event, c.event_version, c.test_version, c.source_version, c.source_vendor, c.data],
context: this,
persistent: !0,
retries: 2,
type: "log_ce"
}, d, g))
}
};
Spotify.Logging.AdEnd = function () {
Spotify.EventTarget.call(this);
var d, g = function () {}, c = function () {};
this.serviceIsReady = !0;
this.log = function (h) {
d.rpc("log_ad", [String(h.file_id), String(h.ad_file_id), String(h.lid), String(h.source_start), String(h.reason_start), String(h.source_end), String(h.reason_end), String(h.bytes_played), String(h.content_length), String(h.ms_played), String(h.ms_played_union), String(h.ms_rcv_latency), String(h.n_seeks_backward), String(h.ms_seeks_backward), String(h.n_seeks_forward),
String(h.ms_seeks_forward), String(h.ms_latency), String(h.num_stutter), String(h.p_lowbuffer), String(h.skipped), String(h.clicked), String(h.token), String(h.last_stream_started_at), String(h["client-ad-count"]), String(h["client-campaign-count"])
], g, c, this, !0, 2, "log_ad")
};
this.init = function (c) {
d = c
}
};
Spotify.Logging.View = function () {
var d = function () {}, g = function () {};
this.log = function (c, h, b, a) {
if (typeof c !== "string") throw Error("Uri must be a string");
if (typeof h !== "string") throw Error("View version must be a string");
if (typeof b !== "string") throw Error("View vendor must be a string");
if (typeof a !== "number") throw Error("Duration must be a number");
this.send(new Spotify.Calls.Simple({
method: "log_view",
payload: [c, h, b, a],
context: this,
persistent: !0,
retries: 2,
type: "log_view"
}, d, g))
}
};
(function () {
var d;
Spotify.Logging.Logger = function () {
if (typeof d !== "undefined") return d;
d = this;
var g = Spotify.DebuggerJS,
c = new Spotify.Events,
h = new Spotify.RateLimiter(3E4, 100),
b = {}, a = function (a) {
g.log("Spotify.Logging.Logger", ["Logging was successfull", a], "corejs")
}, f = function (a) {
g.error("Spotify.Logging.Logger", ["Logging was NOT successfull", a], "corejs")
};
this.logJSExceptions = function (b, k, m, c) {
typeof b === "undefined" || typeof k === "undefined" || typeof m === "undefined" || typeof c === "undefined" || (this.send(new Spotify.Calls.Simple({
method: "log",
payload: [202, 1, b, k, m, c],
context: this,
persistent: !0,
retries: 2,
type: "js_exceptions"
}, a, f)), g.log("Spotify.Logging.Logger", ["js_exceptions", arguments], "corejs"))
};
this.logWindowSize = function (b, k) {
this.send(new Spotify.Calls.Simple({
method: "log",
payload: [41, 1, b, k, 0, 0],
context: this,
persistent: !0,
retries: 0,
type: "window_size"
}, a, f));
g.log("Spotify.Logging.Logger", ["window_size", arguments], "corejs")
};
this.logRequestTime = function (b, k, m, c, h) {
typeof b === "undefined" || typeof k === "undefined" || typeof m === "undefined" ||
typeof c === "undefined" || typeof h === "undefined" || (this.send(new Spotify.Calls.Simple({
method: "log",
payload: [30, 1, b, k, m, c, h],
context: this,
persistent: !0,
retries: 2,
type: "request_time"
}, a, f)), g.log("Spotify.Logging.Logger", ["request_time", arguments], "corejs"))
};
this.logEndPreview = function (b, k, m, c, h, d, u, w, v) {
this.send(new Spotify.Calls.Simple({
method: "log",
payload: [216, 1, b, k, m, c, h, d, u, w, v],
context: this,
persistent: !0,
retries: 2,
type: "end_preview"
}, a, f));
g.log("Spotify.Logging.Logger", ["end_preview", arguments],
"corejs")
};
this.logAggregatedRequestTime = function (a, b) {
typeof a === "undefined" || typeof b === "undefined" || (h.addToBucket({
messageType: 30,
messageVersion: 1,
type: a,
latency: b
}), h.isStarted() || h.start())
};
this.log = function (b, k) {
var m = Array.prototype.slice.call(arguments);
typeof b === "undefined" || typeof k === "undefined" || (this.send(new Spotify.Calls.Simple({
method: "log",
payload: m,
context: this,
persistent: !0,
retries: 2,
type: "log"
}, a, f)), g.log("Spotify.Logging.Logger", ["Log", m], "corejs"))
};
var k = function (a) {
a = a.params;
typeof b[a.type] === "undefined" && (b[a.type] = {
min: Number.MAX_VALUE,
max: 0,
sum: 0,
sumpow2: 0,
count: 0,
mean: 0,
std_deviation: 0
});
b[a.type].count++;
b[a.type].sum += a.latency;
b[a.type].sumpow2 += Math.pow(a.latency, 2);
if (b[a.type].min > a.latency) b[a.type].min = a.latency;
if (b[a.type].max < a.latency) b[a.type].max = a.latency
}, m = function () {
for (var k in b) {
var m = b[k];
m.mean = Math.floor(m.sum / m.count);
m.std_deviation = Math.floor(Math.sqrt(m.sumpow2 - Math.pow(m.mean, 2), 2));
this.send(new Spotify.Calls.Simple({
method: "log",
payload: [232,
1, k, m.count, m.sum, m.sumpow2, m.min, m.max, m.mean, m.std_deviation
],
context: this,
persistent: !0,
retries: 2,
type: "aggregated_request_latencies"
}, a, f))
}
g.log("Spotify.Logging.Logger", ["Aggregated Request Latencies", b], "corejs");
b = {};
h.isStarted() || h.start()
};
this.setup = function () {
h.bind(c.RATE_LIMIT_CALL, k, this);
h.bind(c.RATE_LIMIT_AFTER_INTERVAL, m, this)
}
}
})();
Spotify.PlayerTracker = function (d, g, c) {
Spotify.EventTarget.call(this);
this.id = d;
var h = Spotify.DebuggerJS,
b = !1,
a, f = new Spotify.Events,
k = {}, m, o = 0,
p = 0,
q = 0,
n = 0,
s = [],
t = 0,
u = 0,
w = 0,
v = 0,
A = 0,
x = 0,
F = "",
G = "unknown",
B = "unknown",
E = "unknown",
H = "unknown",
I = "unknown",
K = "unknown",
L = "unknown",
N = "unknown",
M = "",
z = new Spotify.Logging.Types,
C = new Spotify.Cache.Default(100, new Spotify.Cache.LocalStorage("tracker")),
y = !1,
D = !1,
P = !1,
O = {}, R = 0,
T = -1,
S = function (b) {
var c = k[b],
d = 0,
n = {};
if (M !== "" || M === "" && P) {
q = y ? q : ca(s);
F = F || "";
G = G ||
"unknown";
B = B || "unknown";
H = H || "unknown";
K = K || "unknown";
L = L || "unknown";
N = N || "unknown";
if (t === 0 && u === 0 && (b === z.TRACK_END || b === z.AD_END)) o = p = q;
if (b === z.AD_END && g.ad !== void 0) n.ad_file_id = g.ad.file_id, n.lid = g.ad.ad_id, n.file_id = "5", n.bytes_played = 0, n.content_length = 0, n.ms_rcv_latency = 0, n.num_stutter = 0, n.p_lowbuffer = 0, n.skipped = 0, n.last_stream_started_at = (new Date(A)).toISOString(), n.token = g.ad.token, n.clicked = g.ad.has_been_clicked ? 1 : 0, n["client-ad-count"] = g.ad.adPlayCount, n["client-campaign-count"] = g.ad.campaignPlayCount,
n.source_start = "pendad", n.source_end = "trackdone", n.reason_end = "albumtrackdone";
else if (b === z.TRACK_END) n.lid = M, n.source_start = B, n.source_end = E, n.reason_end = I;
else if (b === z.TRACK_PROGRESS) n.lid = M, n.play_track = m, n.source_start = B, n.bitrate = g.bitrate, n.audiocodec = g.audiocodec;
else if (b === z.PREVIEW_END) n.bitrate = g.bitrate, n.audiocodec = g.audiocodec, n.reason_end = I;
n.max_continuous = o;
n.ms_played = p;
n.ms_played_union = q;
n.n_seeks_forward = t;
n.n_seeks_backward = u;
n.ms_seeks_forward = w;
n.ms_seeks_backward = v;
n.ms_latency =
x;
n.display_track = F;
n.play_context = G;
n.reason_start = H;
n.referrer = K;
n.referrer_version = L;
for (n.referrer_vendor = N; d < c.length; d++) c[d].log(n);
b === z.AD_END && g.ad !== void 0 && (y || a.trigger(f.RECORD_AD_EVENT, {
playerId: g.id,
adUri: "spotify:ad:" + g.ad.file_id,
type: "impression"
}), delete g.ad);
y && (y = !1);
h.log("Spotify.PlayerTracker", ["Logging song data -> Type:", b, "-> Arguments:", n, " of player", g.id], "corejs")
}
}, J = function (a) {
var b = k[z.TRACK_EVENT],
f = 0;
if (M !== "")
for (a = {
lid: M,
event: a,
ms_where: g.position()
}; f < b.length; f++) b[f].log(a)
},
V = function (a) {
p += a.params.interval;
n = g.getPlayerState().position;
a = Math.floor(p * 0.001) * 1E3;
if ((a % 15E3 === 0 || p < 1E3) && R < 4 && !D && T !== a) g.isPreview || S(z.TRACK_PROGRESS), R++, T = a
}, W = function (a) {
s.push({
type: "START",
time: parseInt(a)
});
b = !0
}, Y = function (a) {
s.push({
type: "END",
time: parseInt(a)
});
b = !1
}, Z = function () {
h.log("Spotify.PlayerTracker", ["Cache is initialized..."], "corejs");
C.get(Spotify.Utils.Base64.encode(c) + ":stats:" + g.id, aa, a)
}, U = function () {}, Q = function (a) {
h.log("Spotify.PlayerTracker", ["endSongData are now stored",
arguments
], "corejs")
}, X = function (a) {
h.error("Spotify.PlayerTracker", ["endSongData are NOT stored", arguments], "corejs")
}, aa = function (b, f) {
if (f !== null) {
C.remove(b, ea, a);
var k;
k = JSON.parse(Spotify.Utils.Base64.decode(f));
if (D = k.isAd) {
if (!g.ad) g.ad = {};
g.ad.file_id = k.ad_file_id;
g.ad.ad_id = k.ad_id;
A = k.last_stream_started_at;
g.ad.token = k.token;
g.ad.has_been_clicked = k.clicked;
g.ad.adPlayCount = k["client-ad-count"];
g.ad.campaignPlayCount = k["client-campaign-count"]
}
M = k.lid;
P = k.isPreview;
o = k.max_continuous;
q =
k.ms_played_union;
p = k.ms_played;
t = k.n_seeks_forward;
u = k.n_seeks_backward;
w = k.ms_seeks_forward;
v = k.ms_seeks_backward;
x = k.ms_latency;
F = k.display_track;
G = k.play_context;
B = k.source_start;
E = k.source_end;
H = k.reason_start;
I = k.reason_end;
K = k.referrer;
L = k.referrer_version;
N = k.referrer_vendor;
y = !0;
D ? S(z.AD_END) : P ? S(z.PREVIEW_END) : S(z.TRACK_END);
ba()
}
}, ea = function () {}, ba = function () {
P = D = !1;
M = "";
p = 0;
m = "";
q = o = 0;
s = [];
x = v = w = u = t = 0;
F = "";
N = L = K = I = H = E = B = G = "unknown"
}, fa = function (a, b) {
return a.time - b.time
}, ca = function (a) {
for (var b =
0, f = 0, k = 0, m = 0, c = 0, d = 0; c < a.length; c++) c % 2 !== 0 && typeof a[c - 1] !== "undefined" && a[c - 1].type === "START" && (d = a[c].time - a[c - 1].time, o = d > o ? d : o);
h.log("Spotify.PlayerTracker", ["max continuous", o], "corejs");
for (a.sort(fa); m < a.length; m++) a[m].type === "START" && (f === 0 && (k = m), ++f), a[m].type === "END" && (--f, f === 0 && (b += a[m].time - a[k].time));
h.log("Spotify.PlayerTracker", ["Union calculated:", b, "Segments:", a], "corejs");
return b
}, da = function () {
Y(n);
var a = {};
D ? (a.ad_file_id = g.ad.file_id, a.lid = g.ad.ad_id, a.last_stream_started_at =
A, a.token = g.ad.token, a.clicked = g.ad.has_been_clicked, a["client-ad-count"] = g.ad.adPlayCount, a["client-campaign-count"] = g.ad.campaignPlayCount, a.source_start = "pendad") : (a.source_start = B || "unknown", a.lid = M);
a.isAd = D;
a.isPreview = P;
a.source_end = a.source_start;
a.max_continuous = o;
a.ms_played = p;
a.ms_played_union = ca(s);
a.n_seeks_forward = t;
a.n_seeks_backward = u;
a.ms_seeks_forward = w;
a.ms_seeks_backward = v;
a.ms_latency = x;
a.display_track = F || "";
a.play_track = a.display_track;
a.play_context = G || "unknown";
a.reason_start =
H || "unknown";
a.reason_end = "reload";
a.referrer = K || "unknown";
a.referrer_version = L || "unknown";
a.referrer_vendor = N || "unknown";
C.put(Spotify.Utils.Base64.encode(c) + ":stats:" + g.id, Spotify.Utils.Base64.encode(JSON.stringify(a)), Q, X, null, this)
}, ga = function () {
if (M !== "") {
h.log("Spotify.PlayerTracker", ["Tracking the position changed event of player", g.id], "corejs");
var a = parseInt(g.getPlayerState().position);
a !== n && (b && (h.log("Spotify.PlayerTracker", ["Union End from _onPositionChanged", n], "corejs"), Y(n)), a >
n ? (t++, w += a - n, h.log("Spotify.PlayerTracker", ["Went forward", a - n, "ms"], "corejs")) : a < n && (u++, v += n - a, h.log("Spotify.PlayerTracker", ["Went back", n - a, "ms"], "corejs")), n = a, h.log("Spotify.PlayerTracker", ["Union Start from _onPositionChanged", n], "corejs"), W(n))
}
};
this.onConnected = function () {
h.log("Spotify.PlayerTracker", ["Tracking the on connect event"], "corejs");
M !== "" && (g.isPlaying ? (h.log("Spotify.PlayerTracker", ["Tracking the reconnect while playing event"], "corejs"), J(1)) : g.isPaused && (h.log("Spotify.PlayerTracker", ["Tracking the reconnect while being paused event"], "corejs"), J(2)))
};
var ha = function (a) {
A = a.params.timestamp
}, ia = function (a) {
h.log("Spotify.PlayerTracker", ["Tracking the on song loaded event", a], "corejs")
}, ja = function () {
h.log("Spotify.PlayerTracker", ["Tracking the on load event of player", g.id], "corejs");
M = g.lid;
m = g.trackUri;
D = g.isAd;
P = g.isPreview;
x = (new Date).getTime() - A;
F = O.display_track || "";
G = O.play_context || "unknown";
B = O.source_start || "unknown";
H = O.reason_start || "unknown";
K = O.referrer || "unknown";
L = O.referrer_version || "unknown";
N = O.referrer_vendor || "unknown";
n = g.getPlayerState().position;
h.log("Spotify.PlayerTracker", ["Union Start from _onLoaded", n], "corejs");
W(n)
}, ka = function () {
g.getPlayerState();
J(3);
h.log("Spotify.PlayerTracker", ["Tracking the on play event of player", g.id], "corejs")
}, la = function () {
J(4);
h.log("Spotify.PlayerTracker", ["Tracking the on pause event of player", g.id], "corejs")
}, ma = function () {
h.log("Spotify.PlayerTracker", ["Tracking the invalid track uri event of player", g.id],
"corejs")
}, na = function () {
ba();
h.log("Spotify.PlayerTracker", ["Tracking the playback failed event of player", g.id], "corejs")
};
this.setEndSongStartLog = function (a) {
typeof a !== "undefined" && (O = a)
};
this.setEndSongStopLog = function (a) {
typeof a !== "undefined" && (E = a.source_end || "unknown", I = a.reason_end || "unknown")
};
this.stopTrackingAndLog = function () {
h.log("Spotify.PlayerTracker", ["Stopping tracking and logging", g.id], "corejs");
R = 0;
T = -1;
h.log("Spotify.PlayerTracker", ["Union End from _logEndSongData", n], "corejs");
Y(n);
D ? S(z.AD_END) : P ? S(z.PREVIEW_END) : S(z.TRACK_END);
ba()
};
this.dispose = function (b) {
h.log("Spotify.PlayerTracker", ["Disposing tracker with id", this.id], "corejs");
typeof b !== "undefined" && b || da();
h.log("Spotify.PlayerTracker", ["Unbind event listeners"], "corejs");
g.unbind(f.POSITION_CHANGED, ga, a);
g.unbind(f.PLAYING, ka, a);
g.unbind(f.PAUSED, la, a);
g.unbind(f.INVALID_TRACK_URI, ma, a);
g.unbind(f.PLAYBACK_FAILED, na, a);
g.unbind(f.TRACK_PLAY_REQUEST, ha, a);
g.unbind(f.SONG_LOADED, ia, a);
g.unbind(f.LOAD, ja, a);
g.unbind(f.PLAYER_STATE,
V, a)
};
this.addLogger = function (a, b) {
typeof k[a] === "undefined" && (k[a] = []);
k[a].push(b)
};
this.initialize = function () {
a = this;
C.initialize(Z, U, this);
h.log("Spotify.PlayerTracker", ["Binding event listeners"], "corejs");
g.bind(f.POSITION_CHANGED, ga, a);
g.bind(f.PLAYING, ka, a);
g.bind(f.PAUSED, la, a);
g.bind(f.INVALID_TRACK_URI, ma, a);
g.bind(f.PLAYBACK_FAILED, na, a);
g.bind(f.TRACK_PLAY_REQUEST, ha, a);
g.bind(f.SONG_LOADED, ia, a);
g.bind(f.LOAD, ja, a);
g.bind(f.PLAYER_STATE, V, a)
}
};
Spotify.Protobuf.Parser = function () {
function d() {}
function g(a) {
var b = f[a.current.value],
c = a.next().value,
h = a.next().value;
a.expectToken("=");
var d = ~~a.next().value;
a.skipUntil(";");
return {
name: h,
number: d,
label: b,
type: k[c],
type_name: k[c] ? void 0 : c,
default_value: void 0
}
}
function c(a, b) {
b = {
name: a.next().value,
field: [],
nested_type: [],
enum_type: []
};
for (a.expectToken("{"); a.next().type != "}";) switch (a.current.value) {
case "optional":
case "repeated":
case "required":
b.field.push(g(a));
break;
case "message":
b.nested_type.push(c(a));
break;
case "enum":
b.enum_type.push(h(a));
break;
case "extensions":
a.skipUntil(";");
break;
case ";":
break;
default:
a.fail("Unrecognized message token: " + a.current.value)
}
return b
}
function h(a) {
var b = a.next().value;
a.expectToken("{");
for (var f = []; a.next().type != "}";) {
var k = a.current.value;
a.expectToken("=");
var c = ~~a.next().value;
f.push({
name: k,
number: c
});
a.skipUntil(";")
}
return {
name: b,
value: f
}
}
var b = {};
d.Label = {
LABEL_OPTIONAL: 1,
LABEL_REQUIRED: 2,
LABEL_REPEATED: 3
};
d.Type = {
TYPE_DOUBLE: 1,
TYPE_FLOAT: 2,
TYPE_INT64: 3,
TYPE_UINT64: 4,
TYPE_INT32: 5,
TYPE_FIXED64: 6,
TYPE_FIXED32: 7,
TYPE_BOOL: 8,
TYPE_STRING: 9,
TYPE_MESSAGE: 11,
TYPE_BYTES: 12,
TYPE_UINT32: 13,
TYPE_ENUM: 14,
TYPE_SFIXED32: 15,
TYPE_SFIXED64: 16,
TYPE_SINT32: 17,
TYPE_SINT64: 18
};
var a = function (a) {
this.text = a;
this.ptr = 0;
this.current = {
value: "",
type: "",
ptr: 0
}
};
a.prototype = {
where: function (a) {
for (var a = a === void 0 ? this.current.ptr : a, b = 0, f = -1; f && f <= a;) f = this.text.indexOf("\n", f) + 1, ++b;
return "line: " + b
},
fail: function (a, b) {
throw this.where(b) + ": " + a;
},
skipWhitespace: function () {
for (var a =
this.text[this.ptr]; a && " \t\r\n".indexOf(a) != -1;) a = this.text[++this.ptr]
},
skipLineComment: function () {
for (var a = this.text[this.ptr]; a && a !== "\r" && a !== "\n";) a = this.text[++this.ptr];
a === "\r" && (a = this.text[++this.ptr]);
a === "\n" && ++this.ptr
},
skipBlockComment: function () {
for (var a = this.ptr, b = this.text[this.ptr], f = !1; b && !(f && b === "/");) f = b === "*", b = this.text[++this.ptr];
b || this.fail("Expected end of block comment", a);
++this.ptr
},
skipUntil: function (a) {
for (var b = this.ptr; this.next().type !== a;) this.current.type ===
"" && this.fail("Expected: " + a + "(Unexpected end of data)", b)
},
expectToken: function (a) {
this.next().type !== a && this.fail("Expected: " + a)
},
extractWord: function () {
for (var a = this.ptr, b = this.text[this.ptr]; b && "{}[]=; \t\r\n/".indexOf(b) === -1;) b = this.text[++this.ptr];
this.current.type = "word";
this.current.value = this.text.substring(a, this.ptr)
},
extractString: function () {
var a = this.text.indexOf('"', this.ptr + 1);
this.current.type = "string";
this.current.value = this.text.substring(this.ptr + 1, a - 1);
this.ptr = a + 1
},
next: function () {
this.skipWhitespace();
for (var a = this.text[this.ptr]; a === "/";) a = this.text[++this.ptr], a === "/" ? (++this.ptr, this.skipLineComment()) : a === "*" ? (++this.ptr, this.skipBlockComment()) : this.fail("Expecting // or /*", this.ptr - 1), this.skipWhitespace(), a = this.text[this.ptr];
this.current.ptr = this.ptr;
this.ptr >= this.text.length ? (this.current.value = "", this.current.type = "") : "{}[]=;".indexOf(a) !== -1 ? (this.current.value = this.current.type = a, ++this.ptr) : a === '"' ? this.extractString() : this.extractWord();
return this.current
}
};
var f = {
optional: "LABEL_OPTIONAL",
required: "LABEL_REQUIRED",
repeated: "LABEL_REPEATED"
}, k = {
"double": "TYPE_DOUBLE",
"float": "TYPE_FLOAT",
int64: "TYPE_INT64",
uint64: "TYPE_UINT64",
int32: "TYPE_INT32",
fixed64: "TYPE_FIXED64",
fixed32: "TYPE_FIXED32",
bool: "TYPE_BOOL",
string: "TYPE_STRING",
bytes: "TYPE_BYTES",
uint32: "TYPE_UINT32",
sfixed32: "TYPE_SFIXED32",
sfixed64: "TYPE_SFIXED64",
sint32: "TYPE_SINT32",
sint64: "TYPE_SINT64"
};
b.parseFileDescriptor = function (b) {
for (var b = new a(b), f = {
message_type: [],
enum_type: []
}; b.next().type != "";) switch (b.current.value) {
case "package":
case "option":
b.skipUntil(";");
break;
case "message":
f.message_type.push(c(b));
break;
case "enum":
f.enum_type.push(h(b));
break;
default:
b.fail("Unrecognized proto token: " + b.current.value)
}
return f
};
b.FieldDescriptorProto = d;
return b
}();
Spotify.Protobuf.Serialization = function () {
function d() {
this._data = []
}
function g(a, b, f) {
this._data = a;
this._ptr = b;
this._end = this._ptr + f
}
function c(a, b, f, k) {
switch (b.type) {
case "int32":
k.writeVarint(b.id << 3 | 0);
k.writeVarint(f);
break;
case "uint32":
k.writeVarint(b.id << 3 | 0);
k.writeVarint(~~f);
break;
case "sint32":
k.writeVarint(b.id << 3 | 0);
k.writeVarint(f << 1 ^ f >> 31);
break;
case "int64":
case "uint64":
k.writeVarint(b.id << 3 | 0);
k.writeVarint64(Math.floor(f / 4294967296), ~~f);
break;
case "sint64":
k.writeVarint(b.id <<
3 | 0);
b = Math.abs(f) - (f < 0);
k.writeVarint64(Math.floor(b / 2147483648), (b << 1) + (f < 0));
break;
case "bool":
k.writeVarint(b.id << 3 | 0);
k.writeVarint(f ? 1 : 0);
break;
case "string":
k.writeVarint(b.id << 3 | 2);
b = [];
for (a = 0; a < f.length; ++a) {
var m = f.charCodeAt(a);
if (m < 128) b.push(m);
else {
if ((m & 64512) === 55296) var h = f.charCodeAt(++a),
m = ((m & 1023) << 10 | h & 1023) + 65536;
m < 2048 ? b.push(192 | m >> 6) : (m < 65536 ? b.push(224 | m >> 12) : (b.push(240 | m >> 18), b.push(128 | m >> 12 & 63)), b.push(128 | m >> 6 & 63));
b.push(128 | m & 63)
}
}
f = b;
k.writeVarint(f.length);
k.writeAll(f);
break;
case "bytes":
k.writeVarint(b.id << 3 | 2);
b = [];
for (a = 0; a < f.length; ++a) b.push(f.charCodeAt(a));
f = b;
k.writeVarint(f.length);
k.writeAll(f);
break;
case "*":
for (m = 0; m < f.length; ++m) c(a, b.subField, f[m], k);
break;
case "#":
b.enumMap.toNumber.hasOwnProperty(f);
f = b.enumMap.toNumber[f];
k.writeVarint(b.id << 3 | 0);
k.writeVarint(f);
break;
default:
if (a.hasOwnProperty(b.type)) m = new d, a[b.type].serializeToStream(f, m), k.writeVarint(b.id << 3 | 2), k.writeVarint(m._data.length), k.writeAll(m._data);
else throw "Unsupported type";
}
}
function h(a) {
for (var b = [], f = 0; f < a.length;) {
var k = a.charCodeAt(f++);
if (k < 128) b.push(a[f - 1]);
else {
var c;
k < 224 ? (k &= -225, c = 2) : k < 240 ? (k &= -241, c = 3) : (k &= -249, c = 4);
for (; --c && f < a.length;) var m = a.charCodeAt(f++),
k = k << 6 | m & -193;
k < 65536 ? b.push(String.fromCharCode(k)) : (k -= 65536, b.push(String.fromCharCode(55296 | k >> 10, 56320 | k & 1023)))
}
}
return b.join("")
}
function b(a) {
return decodeURIComponent(escape(a))
}
function a(b, f) {
var k = f.name;
switch (f.type) {
case "int32":
return function (a, b, f, c) {
return a === 0 ? (f[k || c] = ~~b.readVarint(), !0) : !1
};
case "uint32":
return function (a, b, f, c) {
return a === 0 ? (f[k || c] = b.readVarint(), !0) : !1
};
case "sint32":
return function (a, b, f, c) {
return a === 0 ? (a = k || c, b = b.readVarint(), f[a] = b >>> 1 ^ -(b & 1), !0) : !1
};
case "int64":
return function (a, b, f, c) {
return a === 0 ? (a = b.readVarint64(), f[k || c] = a.hi * 4294967296 + ((a.lo >>> 1) * 2 + (a.lo & 1)), !0) : !1
};
case "uint64":
return function (a, b, f, c) {
return a === 0 ? (a = b.readVarint64(), f[k || c] = ((a.hi >>> 1) * 2 + (a.hi & 1)) * 4294967296 + ((a.lo >>> 1) * 2 + (a.lo & 1)), !0) : !1
};
case "sint64":
return function (a,
b, f, c) {
return a === 0 ? (a = b.readVarint64(), b = ((a.hi >>> 1) * 2 + (a.hi & 1)) * 2147483648 + (a.lo >>> 1), f[k || c] = a.lo & 1 ? -1 - b : b, !0) : !1
};
case "bool":
return function (a, b, f, c) {
return a === 0 ? (f[k || c] = b.readVarint() !== 0, !0) : !1
};
case "string":
return function (a, b, f, c) {
return a === 2 ? (a = b.readVarint(), f[k || c] = t(b.bytes(a)), !0) : !1
};
case "bytes":
return function (a, b, f, c) {
return a === 2 ? (a = b.readVarint(), f[k || c] = b.bytes(a), !0) : !1
};
case "*":
var c = a(b, f.subField);
return k ? function (a, b, f) {
f = f[k] ? f[k] : f[k] = [];
return c(a, b, f, f.length)
} :
function (a, b, f, k) {
f = f[k] ? f[k] : f[k] = [];
return c(a, b, f, f.length)
};
case "#":
var m = f.enumMap.toName;
return function (a, b, f, c) {
return a === 0 ? (a = b.readVarint(), f[k || c] = m.hasOwnProperty(a) ? m[a] : a, !0) : !1
}
}
return function (a, c, m, h) {
return a === 2 ? (a = c.readVarint(), c = c.substream(a), b[f.type].parseFromStream(c, m[k || h] = {}), !0) : !1
}
}
function f(b) {
for (var f = this, k = 0; k < b.length; ++k)(function (b) {
for (var k = [], m = {}, h = b.fields, o = 0; o < h.length; ++o) {
var p = h[o];
if (p.type[0] === "*") var q = {
type: p.type.substr(1),
id: p.id,
enumMap: p.enumMap
},
p = {
type: "*",
id: p.id,
name: p.name,
subField: q
};
k[p.id] = a(f, p);
m[p.name] = p
}
f[b.name] = {
serializeToStream: function (a, b) {
for (var k in a) m.hasOwnProperty(k) && c(f, m[k], a[k], b)
},
parseFromStream: function (a, f) {
for (; !a.empty();) {
var c = a.readVarint(),
m = c >>> 3;
c &= 7;
var h = k[m];
try {
if (!h || !h(c, a, f)) switch (h = a, c) {
case 0:
h.skipVarint();
break;
case 1:
h.skip(8);
break;
case 2:
var d = h.readVarint();
h.skip(d);
break;
case 3:
case 4:
throw "Deprecated wire type";
case 5:
h.skip(4);
break;
default:
throw "Unsupported wire type";
}
} catch (g) {
throw n.error("Spotify.Protobuf.Serialization", ["Error in", b, m, c], "corejs"), g;
}
}
},
serializeToString: function (a, b) {
b(serializeToStringSync(a))
},
serializeToStringSync: function (a) {
var k = new d;
f[b.name].serializeToStream(a, k);
return k.toString()
},
parseFromString: function (a, b) {
b(parseFromStringSync(a))
},
parseFromStringSync: function (a) {
var a = new g(a, 0, a.length),
k = {};
f[b.name].parseFromStream(a, k);
return k
}
}
})(b[k])
}
function k(a, b, f, k) {
var c = null;
a.type_name ? (c = a.type_name, c = f.hasOwnProperty(k + c) ? f[k + c] : f.hasOwnProperty(c) ? f[c] : null, b = c ? b ? "int32" : "#" :
a.type_name) : b = u[a.type];
return {
id: a.number,
type: (a.label === "LABEL_REPEATED" ? "*" : "") + b,
name: a.name,
typeName: a.type_name,
enumMap: c
}
}
function m(a, b, f, c) {
for (var m = {
name: a.name,
fields: []
}, h = 0; h < a.field.length; ++h) m.fields.push(k(a.field[h], b, f, c + a.name + "."));
return m
}
function o(a, b, f) {
for (var k = 0; k < a.length; ++k) {
for (var c = f + a[k].name, m = b, h = c, d = a[k].value, g = {}, o = {}, p = 0; p < d.length; ++p) {
var n = d[p];
g[n.number] = n.name;
o[n.name] = n.number
}
m[h] = {
name: c,
toName: g,
toNumber: o
}
}
}
function p(a, b, f) {
for (var k = 0; k < a.length; ++k) {
var c =
f + a[k].name + ".";
p(a[k].nested_type, b, c);
o(a[k].enum_type, b, c)
}
}
var q = {}, n = Spotify.DebuggerJS;
d.prototype.write = function (a) {
this._data.push(a)
};
d.prototype.writeAll = function (a) {
Array.prototype.push.apply(this._data, a)
};
d.prototype.writeVarint = function (a) {
for (; a & -128;) this.write(a & 127 | 128), a >>>= 7;
this.write(a)
};
d.prototype.writeVarint64 = function (a, b) {
a ? (this.write(b & 127 | 128), this.write(b >>> 7 & 127 | 128), this.write(b >>> 14 & 127 | 128), this.write(b >>> 21 & 127 | 128), a & -8 ? (this.write((a << 4 | b >>> 28) & 127 | 128), this.writeVarint(a >>>
3)) : this.write((a << 4 | b >>> 28) & 127)) : this.writeVarint(b)
};
d.prototype.toString = function () {
var a;
a = this._data;
if (a.length < s) a = String.fromCharCode.apply(String, a);
else {
var b = 0,
f = [];
do f.push(String.fromCharCode.apply(String, a.slice(b, b + s))), b += s; while (b < a.length);
a = f.join("")
}
return a
};
g.prototype.empty = function () {
return this._ptr >= this._end
};
g.prototype.skipVarint = function () {
for (; this._data.charCodeAt(this._ptr++) >= 128;);
};
g.prototype.readVarint = function () {
var a = 0,
b = 1;
do {
var f = this._data.charCodeAt(this._ptr++);
a += (f & 127) * b;
b *= 128
} while (f >= 128);
return a
};
g.prototype.readVarint64 = function () {
var a = 0,
b = 1 / 4294967296,
f = 0,
k = 1;
do {
var c = this._data.charCodeAt(this._ptr++);
a |= (c & 127) * b;
f |= (c & 127) * k;
b *= 128;
k *= 128
} while (c >= 128);
return {
hi: a,
lo: f
}
};
g.prototype.skip = function (a) {
this._ptr += a
};
g.prototype.substream = function (a) {
var b = this._ptr;
this._ptr += a;
return new g(this._data, b, a)
};
g.prototype.bytes = function (a) {
var b = this._ptr;
this._ptr += a;
return this._data.substr(b, a)
};
var s = 4096,
t = decodeURIComponent && escape ? b : h,
u = {
TYPE_INT32: "int32",
TYPE_SINT32: "sint32",
TYPE_UINT32: "uint32",
TYPE_STRING: "string",
TYPE_BYTES: "bytes",
TYPE_BOOL: "bool",
TYPE_DOUBLE: "double",
TYPE_INT64: "int64",
TYPE_UINT64: "uint64",
TYPE_SINT64: "sint64"
};
q.createFromJson = function (a) {
return new f(a)
};
q.createFromFileDescriptor = function (a, b) {
var k = b === void 0 ? !1 : b,
c = [],
h = {};
o(a.enum_type, h, "");
p(a.message_type, h, "");
for (var d = 0; d < a.message_type.length; ++d) c.push(m(a.message_type[d], k, h, ""));
return new f(c)
};
return q
}();
Spotify.Heartbeat = function () {
var d = new Spotify.Events,
g = null,
c = this;
this.start = function () {
this.stop();
g = setInterval(a, 18E4)
};
this.stop = function () {
g !== null && (clearInterval(g), g = null)
};
var h = function () {}, b = function () {}, a = function () {
var a = new Spotify.Calls.Simple({
method: "echo",
payload: ["h"],
context: c,
persistent: !1,
retries: 0,
type: "heartbeat"
}, h, b);
c.send(a)
};
this.onNotify = function (a) {
switch (a.type) {
case d.DISCONNECTED:
this.stop();
break;
case d.CONNECTED:
this.start()
}
}
};
Spotify.Gateway = function (d) {
Spotify.EventTarget.call(this);
var g = Spotify.DebuggerJS,
c = new Spotify.Logging.Logger,
h = new Spotify.Events,
b = this;
this.isReady = !1;
this.bridge = null;
var a, f, k = !1,
m;
this.isConnected = !1;
this.rpc = function (b, c, h, d, o, p, n, q) {
h = a.addCall(b, c, h, d, o, p, n, q);
g.log("Spotify.Gateway", ["Call with method", b, "calltype", q, "params", c, "and request id", h, "was executed"], "corejs");
this.isConnected ? k ? m.addToBucket(h) : this.bridge.rpc(b, c, h) : (p ? a.setPersistent(h, !0) : a.setPersistent(h, !1), f.reset())
};
this.disconnect = function () {
this.bridge.disconnect()
};
this.connect = function (a, b) {
this.bridge.connect(b, a)
};
var o = function () {
this.isConnected = !0
}, p = function (a) {
g.log("Spotify.Gateway", ["onTimeout", a], "corejs")
}, q = function (a) {
b.trigger(h.HERMES_B64_MESSAGE, a.params)
}, n = function () {
b.trigger(h.USER_INFO_CHANGE)
}, s = function () {
try {
c.logWindowSize(window.innerWidth, window.innerHeight)
} catch (f) {}
for (var k = 0, m = a.getPersistentCalls(), d = m.length, g; k < d; k++) g = m[k], b.rpc(g.method, g.params, g.callback, g.errback, g.context,
g.persistent);
k = 0;
m = a.getCalls();
for (d = m.length; k < d; k++) g = m[k], g.method !== "work_done" && b.rpc(g.method, g.params, g.callback, g.errback, g.context, g.persistent, g.retries--);
b.trigger(h.CONNECTED)
}, t = function () {
this.isConnected = !1
}, u = function () {
b.trigger(h.ON_TRY_TO_CONNECT)
}, w = function (a) {
b.trigger(h.DISCONNECTED, a.params)
}, v = function (b) {
var f = a.getCall(b.params.requestId),
k;
typeof f !== "undefined" && (k = (new Date).getTime() - f.timestamp, g.log("Spotify.Gateway", ["Latency of call with request id", b.params.requestId,
"is", k, "ms"
], "corejs"), f.callback.call(f.context, b.params), f.callType !== "request_time" && f.callType !== "aggregated_request_latencies" && f.callType !== "userdata" && f.callType !== "log_view" && f.callType !== "track_end" && f.callType !== "track_progress" && f.callType !== "end_preview" && f.callType !== "log_ad" && f.callType !== "js_exceptions" && f.callType !== "log" && f.callType !== "log_ce" && c.logAggregatedRequestTime(f.callType, k))
}, A = function (f) {
var h = [],
d = !0;
g.error("Spotify.Gateway", ["Got an RPC Error", f], "corejs");
if (typeof f.params.response !==
"undefined") h = f.params.response;
if (h.length >= 3 && (h[0] === Spotify.Errors.Domains.HERMES_ERROR || h[0] === Spotify.Errors.Domains.HERMES_SERVICE_ERROR) && (h[1] === Spotify.Errors.Codes.HM_TOO_MANY_REQUESTS || h[1] === Spotify.Errors.Codes.HM_FAILED_TO_SEND_TO_BACKEND)) d = !1;
var d = a.getCall(f.params.requestId, d),
o;
typeof d !== "undefined" && (o = (new Date).getTime() - d.timestamp, g.log("Spotify.Gateway", ["Latency of call with request id", f.params.requestId, "is", o, "ms"], "corejs"), h.length >= 3 ? (h[0] === Spotify.Errors.Domains.HERMES_ERROR ||
h[0] === Spotify.Errors.Domains.HERMES_SERVICE_ERROR) && h[1] === Spotify.Errors.Codes.HM_TOO_MANY_REQUESTS ? (k = !0, m.start(), m.addToBucket(f.params.requestId)) : (h[0] === Spotify.Errors.Domains.HERMES_ERROR || h[0] === Spotify.Errors.Domains.HERMES_SERVICE_ERROR) && (h[1] === Spotify.Errors.Codes.HM_TIMEOUT || h[1] === Spotify.Errors.Codes.HM_FAILED_TO_SEND_TO_BACKEND) && d.retries > 0 ? b.rpc(d.method, d.params, d.callback, d.errback, d.context, d.persistent, d.retries - 1, d.callType) : (h.push(f.params.method), d.errback.call(d.context,
new Spotify.Errors.Error(h))) : (g.log("Spotify.Gateway", ["RPC Error callback for method with id:", d.callType, d.params], "corejs"), d.errback.call(d.context, new Spotify.Errors.Error([1, 0, "", f.params]))), d.callType !== "request_time" && d.callType !== "aggregated_request_latencies" && d.callType !== "userdata" && d.callType !== "log_view" && d.callType !== "track_end" && d.callType !== "track_progress" && d.callType !== "end_preview" && d.callType !== "log_ad" && d.callType !== "js_exceptions" && d.callType !== "log" && d.callType !== "log_ce" &&
c.logAggregatedRequestTime(d.callType, o))
}, x = function () {
b.isReady = !0;
b.trigger(h.READY)
}, F = function (a) {
this.trigger(a.type, a.params)
}, G = function () {
b.trigger(h.TOKEN_LOST)
}, B = function (f) {
var f = f.params,
k = a.getCall(f, !1);
g.log("Spotify.Gateway", ["onRateLimitCall Will try run the callback with id", f, k], "corejs");
k && b.bridge.rpc(k.method, k.params, f)
}, E = function () {
k = !1
}, H = function (a) {
b.trigger(a.type, a.params)
};
this.dispose = function () {};
this.initialize = function (k, c) {
a = new Spotify.CallsManager;
m = new Spotify.RateLimiter(1E3,
90);
m.bind(h.RATE_LIMIT_CALL, B, this);
m.bind(h.RATE_LIMIT_DISABLED, E, this);
if (d === Spotify.GatewayTypes.FLASH) this.bridge = new Spotify.Flash.Bridge(k, c);
else if (d === Spotify.GatewayTypes.WEBSOCKETS) this.bridge = new Spotify.WebSockets.Bridge(k);
this.bridge.bind(h.CONNECTION_ESTABLISHED, o, this);
this.bridge.bind(h.FAILED_CONNECTING, t, this);
this.bridge.bind(h.RPC_CALLBACK, v, this);
this.bridge.bind(h.RPC_ERRBACK, A, this);
this.bridge.bind(h.TOKEN_LOST, G, this);
this.bridge.bind(h.HERMES_B64_MESSAGE, q, this);
this.bridge.bind(h.USER_INFO_CHANGE,
n, this);
this.bridge.bind(h.LOGIN_COMPLETE, s, this);
this.bridge.bind(h.TIMEOUT, p, this);
this.bridge.bind(h.READY, x, this);
this.bridge.bind(h.FLASH_AVAILABLE, F, b);
this.bridge.bind(h.FLASH_UNAVAILABLE, F, b);
this.bridge.bind(h.WORK, H, b);
this.bridge.bind(h.PING_FLASH, H, b);
f = new Spotify.ConnectionManager;
f.bind(h.ON_TRY_TO_CONNECT, u, this);
f.bind(h.NOTIFY_OF_DISCONNECT, w, this);
f.initialize(this.bridge);
this.bridge.initialize()
}
};
Spotify.Audio.AudioStream = function (d, g, c) {
Spotify.EventTarget.call(this);
this.id = d;
this.lid = "";
this.isReady = !0;
this.isPreview = this.isAd = !1;
this.trackUrl = this.trackUri = "";
this.bitrate = 160;
this.audiocodec = "mp3";
this.isPaused = this.isPlaying = !1;
this.isStopped = !0;
this.isActive = this.isLoaded = !1;
this.limit = -1;
var h = 0,
b = 0,
a = -1,
f, k = {}, m = 1,
o = this,
p = Spotify.DebuggerJS;
new Spotify.Logging.Logger;
var q = new Spotify.Events,
n = "",
s = 0,
t = !1,
u = 1,
w = 0,
v = 0,
A = !1,
x = function (a) {
p.log("Spotify.Audio.AudioStream", ["Player event:",
o.id, a
], "corejs");
switch (a.type) {
case q.READY:
o.isReady = !0;
o.isLoaded && o.load(o.trackUri, v, !o.isPaused);
break;
case q.NOT_READY:
o.isReady = !1;
E();
break;
case q.DURATION:
w = a.params;
p.log("Spotify.Audio.AudioStream", ["Got duration", a.params], "corejs");
break;
case q.LOAD:
H();
w = 0;
o.isPaused = !0;
o.isStopped = !1;
o.isPlaying = !1;
o.isLoaded = !0;
o.onLoad(a);
break;
case q.PLAYING:
E();
f = setInterval(I, 500);
o.isPaused = !1;
o.isStopped = !1;
o.isPlaying = !0;
o.isActive || o.trigger(q.ACTIVE_PLAYER_CHANGED, {
id: o.id
});
o.onPlay(a);
break;
case q.PAUSED:
E();
o.isPaused = !0;
o.isStopped = !1;
o.isPlaying = !1;
o.onPause(a);
break;
case q.STOPPED:
o.isPaused = !1;
o.isStopped = !0;
o.isPlaying = !1;
o.isLoaded = !1;
o.onStop(a);
H();
break;
case q.BEFORE_SEEK:
o.isPlaying && E();
break;
case q.POSITION_CHANGED:
v = parseInt(a.params);
o.isPlaying && (E(), f = setInterval(I, 500));
o.onPositionChanged(a);
break;
case q.TRACK_ENDED:
H();
o.isPaused = !1;
o.isStopped = !0;
o.isPlaying = !1;
o.isLoaded = !0;
o.stop();
o.onTrackEnded(a);
break;
case q.SONG_LOADED:
o.onSongLoaded(a);
break;
case q.PLAYBACK_FAILED:
H();
o.isStopped = !0;
o.isPaused = !1;
o.isPlaying = !1;
o.isLoaded = !1;
o.onPlaybackFailed(a);
break;
case q.INVALID_TRACK_URI:
H(), o.onPlaybackFailed(a)
}
}, F = function (a) {
a.extra.id === o.id && o.trigger(a.type, a.params)
};
this.load = function (b, f, c, m, h) {
(o.isPaused || o.isPlaying) && o.stop();
p.log("Spotify.Audio.AudioStream", ["Load track", b], "corejs");
var d, u = new Spotify.Link.fromString(b);
this.limit = typeof m !== "undefined" ? m : -1;
a = typeof h !== "undefined" ? h : -1;
this.isAd = this.isPreview = !1;
if (u.type === "audiofile") this.isPreview = !0, this.isAd = !1;
else if (u.type === "ad") this.isPreview = !1, this.isAd = !0;
this.trigger(q.TRACK_PLAY_REQUEST, {
timestamp: (new Date).getTime()
});
s = this.isAd ? 0 : f || 0;
t = typeof c === "undefined" ? !1 : c;
n = b;
d = this.isAd ? k[Spotify.Resolvers.AD_RESOLVER] : this.isPreview ? k[Spotify.Resolvers.PREVIEW_RESOLVER] : k[Spotify.Resolvers.STORAGE_RESOLVER];
d.onReady(function () {
try {
d.list(b, g === Spotify.PlayerTypes.FLASH_RTMPS ? "rtmp" : "", G, B)
} catch (a) {
p.error("Spotify.Audio.AudioStream", [a.message, a.stack], "corejs")
}
}, this)
};
var G =
function (a) {
o.lid = a.lid;
o.trackUrl = a.uri;
o.trackUri = n;
p.log("Spotify.Audio.AudioStream", ["Got a result from the resolver", a], "corejs");
c.load(o.id, o.trackUrl, {
autoplay: t,
startFrom: s,
server: a.server,
protocol: a.protocol
});
v = s;
t = !1;
s = 0
}, B = function (a) {
o.lid = "";
o.trackUrl = "";
n = o.trackUri = "";
s = 0;
p.error("Spotify.Audio.AudioStream", ["Got an error from the storage resolver", a], "corejs");
o.trigger(q.INVALID_TRACK_URI, a)
}, E = function () {
f && (clearInterval(f), f = null);
b = 0
}, H = function () {
E();
h = 0;
A = !1
}, I = function () {
var f =
(new Date).getTime(),
k = f - (b === 0 ? f - 500 : b),
m = c.getPlayerState(o.id);
v = m.position;
w = m.duration;
m.isPlaying = o.isPlaying;
m.isStopped = o.isStopped;
m.isPaused = o.isPaused;
var d = m.duration;
b = f;
o.trigger(q.PLAYER_STATE, {
state: m,
interval: k
});
p.log("Spotify.Audio.AudioStream", ["Tracking state:", m, k], "corejs");
if (o.limit !== -1) d = o.limit;
v >= d - a - 500 && a !== -1 && !A && (p.log("Spotify.Audio.AudioStream", ["BEFORE_END event", m.position, m.duration], "corejs"), A = !0, o.trigger(q.BEFORE_END));
h += k;
h >= o.limit && o.limit !== -1 && (o.trigger(q.TRACK_ENDED),
o.stop())
};
this.play = function (a, b) {
if (typeof b !== "undefined" && b !== -1) this.limit = b;
o.isReady && (h = 0, c.play(this.id, a))
};
this.pause = function () {
o.isPlaying && c.pause(this.id)
};
this.resume = function () {
!o.isPlaying && o.isPaused && o.isLoaded && c.resume(this.id)
};
this.stop = function () {
if (o.isLoaded) a = this.limit = -1, c.stop(this.id), this.trigger(q.STOPPED, {}, this.id)
};
this.playpause = function () {
o.isPaused ? o.resume() : o.pause()
};
this.position = function () {
return o.isLoaded ? v = c.position(this.id) : 0
};
this.getPlayerState =
function () {
var a = {};
a.volume = u;
a.position = v;
a.duration = o.isLoaded ? w : 0;
a.isPlaying = this.isPlaying;
a.isStopped = this.isStopped;
a.isPaused = this.isPaused;
return a
};
this.seek = function (a) {
return o.isLoaded ? (o.trigger(q.BEFORE_SEEK), v = a, c.seek(this.id, a)) : 0
};
this.setVolume = function (a) {
!isNaN(a) && a >= 0 && a <= 1 && (u = a, c.setVolume(this.id, a * m))
};
this.setMasterVolume = function (a) {
!isNaN(a) && a >= 0 && a <= 1 && (m = a, this.setVolume(u))
};
this.getVolume = function () {
return u
};
this.getDuration = function () {
return w
};
this.addFileResolver =
function (a, b) {
k[a] = b
};
this.initialize = function () {
g === Spotify.PlayerTypes.HTML5_HTTP && (c.bind(q.TRACK_ENDED, F), c.bind(q.POSITION_CHANGED, F), c.bind(q.PLAYING, F), c.bind(q.PAUSED, F), c.bind(q.STOPPED, F), c.bind(q.LOAD, F));
this.bind(q.TRACK_ENDED, x, this, 10);
this.bind(q.POSITION_CHANGED, x, this, 10);
this.bind(q.PLAYING, x, this, 10);
this.bind(q.PAUSED, x, this, 10);
this.bind(q.STOPPED, x, this, 10);
this.bind(q.PLAYBACK_FAILED, x, this, 10);
this.bind(q.SONG_LOADED, x, this, 10);
this.bind(q.INVALID_TRACK_URI, x, this, 10);
this.bind(q.LOAD,
x, this, 10);
this.bind(q.READY, x, this, 10);
this.bind(q.NOT_READY, x, this, 10);
this.bind(q.TRACK_PLAY_REQUEST, x, this, 10);
this.bind(q.DURATION, x, this, 10);
this.bind(q.BEFORE_SEEK, x, this, 10);
this.bind(q.FAILED_CONNECTING, x, this, 10);
c.initializePlayerById(this.id)
};
this.dispose = function () {
g === Spotify.PlayerTypes.HTML5_HTTP && (c.unbind(q.TRACK_ENDED, F), c.unbind(q.POSITION_CHANGED, F), c.unbind(q.PLAYING, F), c.unbind(q.PAUSED, F), c.unbind(q.STOPPED, F), c.unbind(q.LOAD, F));
this.unbind(q.TRACK_ENDED, x, this);
this.unbind(q.POSITION_CHANGED,
x, this);
this.unbind(q.PLAYING, x, this);
this.unbind(q.PAUSED, x, this);
this.unbind(q.STOPPED, x, this);
this.unbind(q.PLAYBACK_FAILED, x, this);
this.unbind(q.SONG_LOADED, x, this);
this.unbind(q.INVALID_TRACK_URI, x, this);
this.unbind(q.LOAD, x, this);
this.unbind(q.READY, x, this);
this.unbind(q.NOT_READY, x, this);
this.unbind(q.TRACK_PLAY_REQUEST, x, this);
this.unbind(q.DURATION, x, this);
this.unbind(q.BEFORE_SEEK, x, this);
this.unbind(q.FAILED_CONNECTING, x, this)
};
this.onLoad = function () {};
this.onPlay = function () {};
this.onPause =
function () {};
this.onStop = function () {};
this.onTrackEnded = function () {};
this.onSongLoaded = function () {};
this.onPositionChanged = function () {};
this.onInvalidTrackUri = function () {};
this.onPlaybackFailed = function () {}
};
Spotify.Audio.AudioManager = function (d, g, c) {
Spotify.EventTarget.call(this);
this.isInitialized = this.isReady = !1;
var h = this,
b = 1,
a = {}, f = Spotify.DebuggerJS,
k, m = new Spotify.Events,
o = new Spotify.Logging.Types,
p, q, n, s = [],
t = [],
u = 0,
w, v = "",
A = function (a) {
this.trigger(a.type, a.params)
}, x = function (a) {
v = a.user;
h.addPlayer("Player0");
h.isReady = !0;
h.trigger(m.READY)
}, F = function () {}, G = function () {
this.hasSound() ? (h.isInitialized = !0, h.trigger(m.INITIALIZED), w.onReady(function () {
w.getUserInfo(x, F)
})) : this.trigger(m.NO_SOUND_CAPABILITIES)
},
B = function (a) {
switch (a.type) {
case m.STOPPED:
case m.TRACK_END:
h.getTrackerForPlayerWithId(a.extra).stopTrackingAndLog();
var b = h.getTrackerIndexWithId(a.extra);
t[b].dispose(!0);
t[b] = null;
f.log("Spotify.Audio.AudioManager", ["Stopped event capture", t], "corejs");
I(a.extra, b, h.getPlayerAtIndex(b), v)
}
h.trigger(a.type, a.params, a.extra)
}, E = function (a) {
for (var b = 0, f = s.length; b < f; b += 1) {
var k = s[b];
k.id === a.params.id ? (k.isActive = !0, p = k, h.trigger(a.type, a.params, a.extra)) : k.isActive = !1
}
};
this.onReady = function (a,
b) {
this.isReady ? a.call(b) : h.bind(m.READY, a, b)
};
var H = function (a) {
h.trigger(a.type, a.params)
}, I = function (a, b, k, c) {
var d = new Spotify.Logging.TrackEnd;
d.init(q);
var g = new Spotify.Logging.PreviewEnd;
g.init();
var p = new Spotify.Logging.TrackProgress;
p.init(q);
var n = new Spotify.Logging.TrackEvent;
n.init(q);
var s = new Spotify.Logging.AdEnd;
s.init(q);
a = t[b] = new Spotify.PlayerTracker(a, k, c);
a.bind(m.RECORD_AD_EVENT, H, h);
a.addLogger(o.TRACK_END, d);
a.addLogger(o.PREVIEW_END, g);
a.addLogger(o.TRACK_EVENT, n);
a.addLogger(o.AD_END,
s);
a.addLogger(o.TRACK_PROGRESS, p);
a.initialize();
f.log("Spotify.Audio.AudioManager", ["Created a new tracker at index", b, t], "corejs")
};
this.addPlayer = function (b, f) {
var k;
if (typeof b !== "string") throw Error("The id must be a string");
typeof f === "undefined" && (f = c);
k = 0;
for (var d = s.length; k < d; k += 1)
if (s[k].id === b) throw Error("There is already a player with this id: " + b);
n.addPlayer(u, b, f);
k = s[u] = new Spotify.Audio.AudioStream(b, f, n);
k.addFileResolver(Spotify.Resolvers.STORAGE_RESOLVER, a[Spotify.Resolvers.STORAGE_RESOLVER]);
k.addFileResolver(Spotify.Resolvers.AD_RESOLVER, a[Spotify.Resolvers.AD_RESOLVER]);
k.addFileResolver(Spotify.Resolvers.PREVIEW_RESOLVER, a[Spotify.Resolvers.PREVIEW_RESOLVER]);
k.bind(m.ACTIVE_PLAYER_CHANGED, E, h);
k.bind(m.TRACK_ENDED, B, h);
k.bind(m.POSITION_CHANGED, B, h);
k.bind(m.PLAYING, B, h);
k.bind(m.PAUSED, B, h);
k.bind(m.STOPPED, B, h);
k.bind(m.INVALID_TRACK_URI, B, h);
k.bind(m.PLAYBACK_FAILED, B, h);
k.bind(m.TRACK_PLAY_REQUEST, B, h);
k.bind(m.SONG_LOADED, B, h);
k.bind(m.LOAD, B, h);
k.bind(m.FAILED_CONNECTING, B,
h);
k.initialize();
I(b, u, k, v);
u++;
this.trigger(m.PLAYER_CREATED, {
id: b
});
return k
};
this.getPlayers = function () {
return s
};
this.getActivePlayer = function () {
return p
};
this.getPlayerById = function (a) {
var b;
if (typeof a === "string")
for (var f = 0, k = s.length; f < k; f += 1)
if (b = s[f], b.id === a) return b
};
this.getTrackerIndexWithId = function (a) {
var b;
if (typeof a === "string")
for (var f = 0, k = t.length; f < k; f += 1)
if (b = t[f], b.id === a) return f
};
this.getTrackerForPlayerWithId = function (a) {
var b;
if (typeof a === "string")
for (var f = 0, k = t.length; f <
k; f += 1)
if (b = t[f], b.id === a) return b
};
this.getPlayerAtIndex = function (a) {
if (typeof a === "number" && s[a]) return s[a]
};
this.getTrackerForPlayerAtIndex = function (a) {
if (typeof a === "number" && t[a]) return t[a]
};
this.removePlayerById = function (a) {
var b;
if (typeof a === "string") {
if (a === "Player0") return !1;
for (var f = 0, k = s.length; f < k; f += 1)
if (b = s[f], b.id === a && f !== 0) return this.removePlayerAtIndex(f);
return !1
}
};
this.removePlayerAtIndex = function (a) {
if (typeof a !== "number") return !1;
if (a === 0) return !1;
return s[a] ? (s[a].isActive &&
(p = s[0]), s[a].dispose(), t[a].dispose(!0), delete s[a], delete t[a], s[a] = null, t[a] = null, n.removePlayerAtIndex(a)) : !1
};
this.hasSound = function () {
return n.hasSound()
};
this.setMasterVolume = function (a) {
b = a < 0 ? 0 : a > 1 ? 1 : a;
for (var f = 0, k = s.length; f < k; f += 1) a = s[f], a.setMasterVolume(b)
};
this.getMasterVolume = function () {
return b
};
this.crossfade = function (a, b, f, c) {
k || (k = new Spotify.Audio.Crossfader);
k.crossfade(this.getPlayerById(a), this.getPlayerById(b), f, c)
};
this.dispose = function () {
for (var a, b = 0, f = s.length; b < f; b += 1) a =
s[b], a !== null && a !== void 0 && (a.dispose(), a.isActive && t[b].dispose())
};
this.addFileResolver = function (b, f) {
a[b] = f
};
this.getInterface = function () {
return n
};
this.initialize = function (a, b) {
w = b;
q = a;
c === Spotify.PlayerTypes.FLASH_HTTP || c === Spotify.PlayerTypes.FLASH_RTMPS || c === Spotify.PlayerTypes.FLASH_AAC ? (n = new Spotify.Flash.PlayerInterface(d, g), n.bind(m.FLASH_AVAILABLE, A, this), n.bind(m.FLASH_UNAVAILABLE, A, this)) : c === Spotify.PlayerTypes.HTML5_HTTP && (n = new Spotify.HTML5.PlayerInterface("html5audio"));
n.bind(m.READY,
G, this, 10);
n.initialize()
}
};
Spotify.Audio.Crossfader = function () {
var d = this,
g = Spotify.DebuggerJS,
c, h, b = 1,
a = !1,
f = 0,
k = 0,
m, o;
this.crossfade = function (p, q, n, s) {
a ? (this.stop(), c(), c = null, o = m + (1 - (1 - f) + f) * n) : (q.setVolume(0), m = (new Date).getTime(), o = m + n, b = p.getVolume(), f = 0);
g.log("Spotify.Audio.Crossfader", ["Target volume", b], "corejs");
a = !0;
c = s;
h = setInterval(function () {
var c = (new Date).getTime();
k = (o - c) / n;
f = Math.floor((1 - k) * 100) / 100;
var c = Math.floor(b * (1 - f) * 100) / 100,
m = Math.floor(b * f * 100) / 100,
c = c > 1 ? 1 : c,
c = c < 0 ? 0 : c,
m = m > 1 ? 1 : m,
m = m < 0 ? 0 : m;
p.setVolume(c);
q.setVolume(m);
g.log("Spotify.Audio.Crossfader", [p.id, "will have volume", c, q.id, "will have volume", m], "corejs");
f >= 1 && (a = !1, d.stop(), s())
}, 100)
};
this.stop = function () {
return h ? (clearInterval(h), h = null, !0) : !1
}
};
Spotify.Flash.Bridge = function (d, g) {
Spotify.EventTarget.call(this);
var c = Spotify.DebuggerJS,
h = new Spotify.Events;
this.id = d;
var b, a = function (a) {
this.trigger(a.type, a.params)
};
this.rpc = function (a, k, m) {
typeof b !== void 0 ? b.isLoaded ? b.getSWF().sp_rpc.apply(b.getSWF(), [a, m].concat(k)) : c.error("Bridge", ["Core.Bridge:rpc: Bridge is not initialized"], "corejs") : c.error("Bridge", ["Core.Bridge:rpc: Bridge is not initialized"], "corejs")
};
this.disconnect = function () {
typeof b !== void 0 ? b.isLoaded ? b.getSWF().sp_disconnect.apply(b.getSWF()) :
c.error("Bridge", ["Core.Bridge:Disconnect: Bridge is not initialized"], "corejs") : c.error("Bridge", ["Core.Bridge:Disconnect: Bridge is not initialized"], "corejs")
};
this.connect = function (a, k) {
a = a || "";
typeof b !== void 0 && b.isLoaded && b.getSWF().sp_connect.apply(b.getSWF(), [a, k])
};
this.initialize = function () {
b = new Spotify.Flash.SWFObject({
SWFFlashId: d,
SWFContainerId: g.SWFContainerId,
SWFUrl: g.SWFUrl,
SWFMinVersion: g.SWFMinVersion,
instanceId: d,
logging: g.logging,
length: g.valid,
valid: 0
});
b.bind(h.FLASH_AVAILABLE,
a, this);
b.bind(h.FLASH_UNAVAILABLE, a, this);
b.initialize()
};
this.getFlashObject = function () {
return b
}
};
Spotify.WebSockets.Bridge = function (d, g) {
Spotify.EventTarget.call(this);
var c = Spotify.DebuggerJS;
this.id = d;
var g = g || {}, h = this,
b = new Spotify.Events,
a = g.connectionParams || "",
f, k = null,
m = function () {
this.activate = function () {};
this.connect = function () {};
this.disconnect = function () {};
this.rpc = function () {};
this.onConnect = function () {};
this.onDisconnect = function () {};
this.onMessage = function () {};
this.onError = function () {}
}, o = null,
p = 0,
q = function (a) {
o = n[a];
o.activate()
}, n = {};
n[0] = new function () {
m.call(this);
this.activate =
function () {
clearInterval(p)
};
this.connect = function () {
q(1)
}
};
n[1] = new function () {
m.call(this);
this.activate = function () {
clearInterval(p);
k.connect(f)
};
this.onConnect = function () {
c.log("Spotify.WebSockets.Bridge", ["[State.connecting] Socket connected"], "corejs");
q(2)
};
this.onDisconnect = function (a) {
c.log("Spotify.WebSockets.Bridge", ["[State.connecting] Socket disconnected"], "corejs");
h.trigger(b.FAILED_CONNECTING, a.params || []);
q(0)
};
this.disconnect = function () {
k.disconnect()
};
this.onError = function (a) {
c.error("Spotify.WebSockets.Bridge", ["[State.connecting] Error", a], "corejs");
h.trigger(b.FAILED_CONNECTING, {});
q(0)
}
};
n[2] = new function () {
m.call(this);
this.activate = function () {
c.log("Spotify.WebSockets.Bridge", ["[State.authorizing] Sending auth object"], "corejs");
clearInterval(p);
var b = a.split(":");
if (parseInt(b[0], 10) > 200) var f = b.shift(),
m = b.shift(), b = b.join(":"), b = [f, m, b];
k.sendObject({
name: "connect",
id: "0",
args: b
})
};
this.disconnect = function () {
k.disconnect(!1)
};
this.onDisconnect = function (a) {
c.log("Spotify.WebSockets.Bridge", ["[State.authorizing] Socket disconnected"],
"corejs");
h.trigger(b.FAILED_CONNECTING, a.params || []);
q(0)
};
this.onMessage = function (a) {
c.log("Spotify.WebSockets.Bridge", ["[State.authorizing] Got message", a], "corejs");
try {
var f = JSON.parse(a);
f.result === "ok" ? (h.trigger(b.AUTHENTICATED, {}), h.trigger(b.CONNECTION_ESTABLISHED, {}), q(3)) : f.error && (h.trigger(b.FAILED_CONNECTING, f.error), h.disconnect(), q(0))
} catch (k) {}
}
};
n[3] = new function () {
m.call(this);
this.activate = function () {
clearInterval(p);
p = setInterval(function () {
k.isConnected() || (clearInterval(p),
k.trigger("ondisconnect", []))
}, 1E3)
};
this.onMessage = function (a) {
c.log("Spotify.WebSockets.Bridge", ["[State.authorized] Got message", a], "corejs");
try {
var f = JSON.parse(a)
} catch (k) {
h.trigger(b.ERROR, {
message: "Response not a JSON object"
});
return
}
a = f.message ? f.message[0] : null;
a === "token_lost" ? h.trigger(b.TOKEN_LOST, {}) : a === "do_work" ? h.trigger(b.WORK, f.message[1]) : a === "ping_flash" ? h.trigger(b.PING_FLASH, f.message[1]) : a === "login_complete" ? h.trigger(b.LOGIN_COMPLETE) : a === "hm_b64" ? h.trigger(b.HERMES_B64_MESSAGE,
f.message) : a === "user_info_change" ? h.trigger(b.USER_INFO_CHANGE) : f.id ? f.error ? h.trigger(b.RPC_ERRBACK, {
requestId: f.id,
response: f.error
}) : h.trigger(b.RPC_CALLBACK, {
requestId: f.id,
response: f.result
}) : h.trigger(b.ERROR, {
error: "Response object invalid"
})
};
this.disconnect = function () {
k.disconnect()
};
this.onDisconnect = function () {
c.log("Spotify.WebSockets.Bridge", ["[State.authorized] Socket disconnected"], "corejs");
h.trigger(b.FAILED_CONNECTING, {});
q(0)
};
this.rpc = function (a, b, f) {
c.log("Spotify.WebSockets.Bridge", ["[State.authorized] Doing an RPC call", a, b], "corejs");
k.sendObject({
id: f,
name: "sp/" + a,
args: b
})
};
this.onError = function (a) {
c.error("Spotify.WebSockets.Bridge", ["[State.authorized] onerror", a], "corejs")
}
};
this.rpc = function (a, b, f) {
o.rpc(a, b, f)
};
this.connect = function (b, k) {
b && (a = b);
k && (f = k);
o.connect()
};
this.disconnect = function () {
o.disconnect()
};
this.initialize = function () {
if (f === "") throw Error("Spotify.WebSockets.Bridge connectionUri cannot be empty");
k = new Spotify.WebSockets.Client;
k.bind("onconnect",
function () {
o.onConnect()
});
k.bind("ondisconnect", function (a) {
o.onDisconnect(a)
});
k.bind("onmessage", function (a) {
o.onMessage(a.params.message)
});
k.bind("onerror", function (a) {
o.onError(a.params.message)
});
h.trigger(b.READY, {});
q(0)
}
};
Spotify.WebSockets.Client = function () {
Spotify.EventTarget.call(this);
var d = Spotify.DebuggerJS,
g = null,
c = this;
this.connect = function (h) {
if (h === "") throw Error("Spotify.WebSockets.Client connection Uri was not set");
if (this.isConnected()) return !1;
if (WebSocket === void 0) throw Error("Spotify.WebSockets.Client WebSocket interface not supported");
var b = this.currentConnection = (this.currentConnection || 0) + 1;
g = new WebSocket(h);
g.onopen = function () {
d.log("Spotify.WebSockets.Client", ["onopen", b], "corejs");
b == c.currentConnection &&
c.trigger("onconnect", {})
};
g.onclose = function (a) {
d.log("Spotify.WebSockets.Client", ["onclose", b, a], "corejs");
b == c.currentConnection && c.trigger("ondisconnect", [0, a.code, a.reason])
};
g.onmessage = function (a) {
d.log("Spotify.WebSockets.Client", ["onmessage", a, b], "corejs");
b == c.currentConnection && c.trigger("onmessage", {
message: a.data
})
};
g.onerror = function (a) {
d.error("Spotify.WebSockets.Client", ["onerror", a, b], "corejs");
b == c.currentConnection && c.trigger("onerror", {
message: a
})
}
};
this.disconnect = function (h) {
typeof h ===
"undefined" && (h = !0);
this.isConnected() ? (g.close(), g = null, h && c.trigger("ondisconnect", [0, 0, ""])) : d.error("Spotify.WebSockets.Client", ["Client not connected"], "corejs")
};
this.isConnected = function () {
return g && g.readyState === 1
};
this.send = function (h) {
this.isConnected() ? g.send(h) : (c.trigger("ondisconnect", [0, 0, ""]), d.error("Spotify.WebSockets.Client", ["Client not connected"], "corejs"))
};
this.sendObject = function (h) {
var b = JSON.stringify(h);
b.length > 32768 ? c.trigger("onmessage", {
message: JSON.stringify({
id: h.id,
error: [16, 1, "PACKET_SIZE_EXCEEDED"]
})
}) : this.send(b)
}
};
Spotify.EventTarget = function () {
this._listeners = {};
this.bind = this.addEventListener = function (g, c, h, b) {
typeof b === "undefined" && (b = 0);
if (typeof c !== "undefined" && c !== null) {
var b = {
callback: c,
context: h,
priority: b
}, a = !1,
f;
this._listeners[g] === void 0 && (this._listeners[g] = []);
f = this._listeners[g];
for (var k = 0; k < f.length; k++)
if (f[k].callback === c && f[k].context === h) {
a = !0;
break
}
a === !1 && (this._listeners[g].push(b), this._listeners[g].sort(d))
}
};
this.bindOnce = function (d, c, h, b) {
var a = this,
f;
f = function () {
a.unbind(d,
f);
c.apply(h, arguments)
};
this.bind(d, f, void 0, b)
};
var d = function (d, c) {
return c.priority - d.priority
};
this.trigger = this.dispatchEvent = function (d, c, h) {
var b = this._listeners[d],
c = c || {};
if (typeof b !== "undefined")
for (var b = b.concat(), a = 0, f = b.length; a < f; a++) {
var k = b[a];
k.context ? k.callback.call(k.context, {
type: d,
params: c,
extra: h || {}
}) : k.callback({
type: d,
params: c,
extra: h || {}
})
}
};
this._triggerDeferred = function (d, c, h) {
var b = this._listeners[d],
c = c || {};
if (typeof b !== "undefined")
for (var a = 0; a < b.length; a++) {
var f =
b[a];
setTimeout(f.callback.bind(f.context, {
type: d,
params: c,
extra: h || {}
}), 0)
}
};
this.unbind = this.removeEventListener = function (d, c, h) {
var b = -1,
a = this._listeners[d];
if (typeof c !== "undefined") {
if (typeof a !== "undefined") {
for (var f = 0; f < a.length; f++)
if (a[f].callback === c && a[f].context === h) {
b = f;
break
}
b !== -1 && this._listeners[d].splice(b, 1)
}
} else this._listeners[d] = []
}
};
Spotify.Protobuf.Schema = function (d, g, c, h) {
Spotify.EventTarget.call(this);
var b, a = 0,
f = [];
this.id = "";
this.PROTO = "proto";
this.type = this.JSON = "json";
this.load = function () {
var b, f;
if (this.type === this.JSON) f = "json";
else if (this.type === this.PROTO) f = "text";
else throw Error("Not a valid descriptor file for the protobuf schema");
for (b = a = 0; b < d.length; b++)
if (typeof d[b] === "string") {
a++;
var c = new Spotify.Service;
c.url = d[b];
c.dataType = f;
c.bind("onSuccess", this.done, this);
c.bind("onError", this.error, this);
c.fetch()
}
};
this.reset = function () {
f = null
};
this.getSchema = function () {
return b
};
this.msg = function (a) {
return b[a]
};
this.parse = function (a) {
f = f === null ? a : f.concat(a)
};
this.encode = function () {
var a;
this.type == this.JSON ? b = Spotify.Protobuf.Serialization.createFromJson(f) : (a = Spotify.Protobuf.Parser.parseFileDescriptor(f), b = Spotify.Protobuf.Serialization.createFromFileDescriptor(a))
};
this.done = function (b) {
this.parse(b.params.result);
a--;
a === 0 && (this.encode(), typeof h !== "undefined" ? typeof g !== "undefined" && g.call(h, this.id) :
typeof g !== "undefined" && g(this.id))
};
this.setData = function (a) {
f = a
};
this.error = function (a) {
typeof h !== "undefined" ? typeof c !== "undefined" && c.call(h, a) : typeof c !== "undefined" && c(a)
}
};
Spotify.HermesCache = function () {
var d = Spotify.Cache.Default,
g = ["GET", "HEAD"],
c = this,
h = [null, null],
b = new Spotify.Events,
a = function () {
return h[Spotify.Cache.Types.TEMPORARY] != null && h[Spotify.Cache.Types.PERSISTENT] != null
}, f = function (f) {
return function (k) {
var m = "com.spotify.cache." + (f || "generic") + ".version",
d = function () {
localStorage.setItem(m, (5).toString());
h[f] = k;
a() && c.trigger(b.READY)
};
parseInt(localStorage.getItem(m)) != 5 ? k.clear(d) : d()
}
}, k = function () {
throw Error("Failed creating caches!");
}, m = function (a) {
return a.indexOf("hm://playlist/") >=
0 ? h[Spotify.Cache.Types.PERSISTENT] : h[Spotify.Cache.Types.TEMPORARY]
}, o = function (a, b, f, k, c, h) {
var d = m(a);
d.get(b, function (a, b) {
b == null ? k.call(h) : b.expires < (new Date).getTime() ? b.etag ? c.call(h, b.frames, b.etag) : (d.remove(a), k.call(h)) : f.call(h, b.frames)
})
};
c.onReady = function (f, k) {
a() ? f.call(k) : c.bind(b.READY, f, k)
};
c.isRequestCacheable = function (a) {
return g.indexOf(a.getMethod()) != -1
};
c.getCacheKey = function (a) {
for (var b = [a.getMethod(), a.getURI()], f = 0, k = a.getRequestFrameCount(); f < k; ++f) b.push(a.getRequestFrame(f));
return b.join("")
};
c.getCachedFrames = function (b, f, k, c, m, h) {
a() ? o(b, f, k, c, m, h) : c.call(h)
};
c.setCachedFrames = function (b, f, k, h, d, g) {
if (a() && h && (k == "CACHE_PRIVATE" || k == "CACHE_PUBLIC")) {
k = {
frames: g,
expires: (new Date).getTime() + h * 1E3
};
if (d) k.etag = d;
m(b).put(f, k, null, null, c.onfull)
}
};
c.removeAllContaining = function (a, b) {
m(a).removeAllContaining(a, b)
};
c.onfull = function () {};
c.migrateToIndexedDB = function (a, b, f) {
if (JSON.parse(localStorage.getItem("indexeddb") || !1)) a.call(f);
else {
var k = h[Spotify.Cache.Types.PERSISTENT],
c = new d(5E3, new Spotify.Cache.IndexedDBStorage("Spotify.Mercury.Cache"));
delete h[Spotify.Cache.Types.PERSISTENT];
var m = function (a, b) {
c.put(a, b)
}, g = function () {
h[Spotify.Cache.Types.PERSISTENT] = c;
k.clear();
localStorage.setItem("indexeddb", "true");
a.call(f, this)
};
c.initialize(function () {
k._storage.each(m, g, this)
}, b, f)
}
};
(function () {
Spotify.EventTarget.call(c);
var a = new d(500, new Spotify.Cache.MemoryStorage("Spotify.Mercury.Cache"));
a.initialize(f(Spotify.Cache.Types.TEMPORARY), k);
a = JSON.parse(localStorage.getItem("indexeddb") || !1) ? new d(5E3, new Spotify.Cache.IndexedDBStorage("Spotify.Mercury.Cache")) : new d(5E3, new Spotify.Cache.LocalStorage("Spotify.Mercury.Cache"));
a.initialize(f(Spotify.Cache.Types.PERSISTENT), k)
})()
};
(function () {
if (typeof window.btoa !== "function") window.btoa = Spotify.Utils.Base64.encode;
if (typeof window.atob !== "function") window.atob = Spotify.Utils.Base64.decode;
var d = Spotify.DebuggerJS,
g = Spotify.Protobuf.Serialization.createFromJson([{
name: "Header",
fields: [{
id: 1,
type: "string",
name: "uri"
}, {
id: 2,
type: "string",
name: "content_type"
}, {
id: 3,
type: "string",
name: "method"
}, {
id: 4,
type: "sint32",
name: "status_code"
}, {
id: 5,
type: "string",
name: "source"
}, {
id: 6,
type: "*UserField",
name: "user_fields"
}]
}, {
name: "UserField",
fields: [{
id: 1,
type: "string",
name: "name"
}, {
id: 2,
type: "bytes",
name: "value"
}]
}]).Header;
Spotify.Hermes.Header = g;
Spotify.Hermes.Request = function (c) {
if (c.uri == void 0) throw Error("URI not specified!");
var h = Spotify.Hermes.Cache;
this.getMethod = function () {
return c.method
};
this.getURI = function () {
return c.uri
};
this.getRequestFrameCount = function () {
return 0
};
this.getRequestFrameData = function () {
return null
};
this.setRequestFrameData = function () {};
this.getRequestFrame = function () {
return null
};
this.parseResponseFrame =
function (a, b) {
return b
};
var b = function (a) {
for (var b = [], f = (new Date).getTime(), k = 1, c = a.length; k < c; ++k) b.push(this.parseResponseFrame(k - 1, a[k]));
d.log("Spotify.Hermes.Request", ["It took", (new Date).getTime() - f, "ms to parse the frames"], "parsing_times");
return b
}, a = function (a) {
for (var b = [], f = 0, k = a.length; f < k; ++f) b.push(window.atob(a[f]));
return b
}, f = function (a) {
var b = {};
if (a.user_fields)
for (var f = 0, k = a.user_fields.length; f < k; ++f) {
var c = a.user_fields[f];
switch (c.name) {
case "MC-Cache-Policy":
if (c.value ==
"private") b.cache_policy = "CACHE_PRIVATE";
else if (c.value == "public") b.cache_policy = "CACHE_PUBLIC";
break;
case "MC-TTL":
b.ttl = c.value;
break;
case "MC-ETag":
b.etag = c.value
}
}
return b
}, k = function (a, b, f) {
a.user_fields = a.user_fields || [];
a.user_fields.push({
name: b,
value: f
})
}, m = function (a) {
switch (a) {
case "SUB":
return 1;
case "UNSUB":
return 2
}
return 0
}, o = function (k, o, p, n, q, A, x) {
n != null && q != null ? c.user_fields = [{
name: "MC-ETag",
value: q
}] : delete c.user_fields;
for (var F = m(this.getMethod()), q = (new Date).getTime(), F = [F, window.btoa(g.serializeToStringSync(c))], G = 0, B = this.getRequestFrameCount(); G < B; ++G) F.push(window.btoa(this.getRequestFrame(G)));
d.log("Spotify.Hermes.Request", ["It took", (new Date).getTime() - q, "ms to serialize the request"], "parsing_times");
k.rpc("hm_b64", F, function (k) {
var k = a(k.response),
c = g.parseFromStringSync(k[0]),
m = c.status_code;
if (m >= 200 && m <= 299) {
var d = f(c);
h.setCachedFrames(this.getURI(), h.getCacheKey(this), d.cache_policy, d.ttl, d.etag, k);
o(b.call(this, k), m, c)
} else m == 304 ? o(b.call(this, n),
m, c) : p(new Spotify.Errors.Error([13, m, null, c]))
}, p, this, A || !1, 2, x)
}, p = function (a) {
if (a.length != 2) throw Error("Invalid number of frames!");
var b = g.parseFromStringSync(a[0]),
a = {
content_type: b.content_type,
status_code: b.status_code,
body: a[1]
}, b = f(b),
k;
for (k in b) a[k] = b[k];
return a
}, q = function (a, b) {
var f = {
uri: b,
content_type: a.content_type,
status_code: a.status_code
};
a.cache_policy == "CACHE_PUBLIC" ? k(f, "MC-Cache-Policy", "public") : a.cache_policy == "CACHE_PRIVATE" && k(f, "MC-Cache-Policy", "private");
a.ttl !==
void 0 && k(f, "MC-TTL", a.ttl);
a.etag !== void 0 && k(f, "MC-ETag", a.etag);
return [g.serializeToStringSync(f), a.body]
}, n = function (b, f, k, m, o, n) {
o = typeof o !== "undefined" ? o : !1;
if (this.getRequestFrameCount() != 1) throw Error("Invalid number of request frames!");
var x = this.getRequestFrameData(0).request,
F = x.length,
G = [],
B = [],
E = Array(F),
H = function (b) {
var c = a(b.response),
m = g.parseFromStringSync(c[0]),
b = m.status_code;
if (Spotify.Hermes.Request.isSuccess(b))
if (m.content_type != "vnd.spotify/mercury-mget-reply") k(new Spotify.Errors.Error([Spotify.Errors.Domains.HERMES_ERROR,
500, "Server didn't send a multi-GET reply!"
]));
else if (c.length != 2) k(new Spotify.Errors.Error([Spotify.Errors.Domains.HERMES_ERROR, 500, "Invalid number of frames in multi-GET reply!"]));
else {
for (var c = this.parseResponseFrame(0, c[1]).reply, m = (new Date).getTime(), o = 0, n = c.length; o < n; ++o) {
var s = G[o],
v = c[o],
w = B.shift();
v.status_code == 304 ? (E[w] = p(s.cachedFrames), E[w].status_code = 200) : Spotify.Hermes.Request.isSuccess(v.status_code) ? (E[w] = v, h.setCachedFrames(s.uri, "GET" + s.uri + (s.body || ""), v.cache_policy, v.ttl,
v.etag, q(v, s.uri))) : delete E[w]
}
d.log("Spotify.Hermes.Request", ["It took", (new Date).getTime() - m, "ms to parse the frames"], "parsing_times");
f([{
reply: E
}], b)
} else k(new Spotify.Errors.Error([Spotify.Errors.Domains.HERMES_ERROR, b]))
}, I = function () {
if (G.length == 0) f([{
reply: E
}], 200);
else {
var a = (new Date).getTime(),
h = [0, window.btoa(g.serializeToStringSync(c))];
this.setRequestFrameData(0, {
request: G
});
h.push(window.btoa(this.getRequestFrame(0)));
d.log("Spotify.Hermes.Request", ["It took", (new Date).getTime() -
a, "ms to serialize the request"
], "parsing_times");
b.rpc("hm_b64", h, H, k, this, m || !1, 2, n)
}
}, K = function (a) {
return function (b) {
E[a] = p(b);
--F <= 0 && I.call(this)
}
}, L = function (a) {
return function () {
G.push(x[a]);
B.push(a);
--F <= 0 && I.call(this)
}
}, N = function (a) {
return function (b, f) {
x[a].etag = f;
x[a].cachedFrames = b;
G.push(x[a]);
B.push(a);
--F <= 0 && I.call(this)
}
};
if (o)
for (var o = 0, M = x.length; o < M; ++o) L(o).call(this);
else {
o = 0;
for (M = x.length; o < M; ++o) {
var z = x[o];
h.getCachedFrames(z.uri, "GET" + z.uri + (z.body || ""), K(o), L(o),
N(o), this)
}
}
};
this.send = function (a, f, k, m, d, g) {
d = typeof d !== "undefined" ? d : !1;
if (c.content_type == "vnd.spotify/mercury-mget-request") n.call(this, a, f, k, m, d, g);
else {
var p = function (a) {
f(b.call(this, a), 200)
}, q = function () {
o.call(this, a, f, k, null, null, m, g)
}, G = function (b, c) {
o.call(this, a, f, k, b, c, m, g)
};
d || !h.isRequestCacheable(this) ? q.call(this) : h.getCachedFrames(this.getURI(), h.getCacheKey(this), p, q, G, this)
}
}
};
Spotify.Hermes.Request.isSuccess = function (c) {
return c >= 200 && c < 300
};
Spotify.Hermes.Request.isRedirect =
function (c) {
return c >= 300 && c < 400
};
Spotify.Hermes.Request.isClientError = function (c) {
return c >= 400 && c < 500
};
Spotify.Hermes.Request.isServerError = function (c) {
return c >= 500 && c < 600
};
Spotify.Hermes.StringRequest = function (c, h) {
var b = new Spotify.Hermes.Request(c);
b.getRequestFrameCount = function () {
return h.length
};
b.getRequestFrameData = function (a) {
return h[a]
};
b.setRequestFrameData = function (a, b) {
h[a] = b
};
b.getRequestFrame = function (a) {
return h[a]
};
b.parseResponseFrame = function (a, b) {
return b
};
return b
};
Spotify.Hermes.ProtobufRequest =
function (c, h, b, a) {
c = new Spotify.Hermes.Request(c);
c.getRequestFrameCount = function () {
return h.length
};
c.getRequestFrameData = function (a) {
return h[a]
};
c.setRequestFrameData = function (a, b) {
h[a] = b
};
c.getRequestFrame = function (a) {
return b[a] ? b[a].serializeToStringSync(h[a]) : h[a]
};
c.parseResponseFrame = function (b, k) {
return b < a.length ? a[b].parseFromStringSync(k) : k
};
return c
}
})();
Spotify.Hermes.Handler = function () {
Spotify.EventTarget.call(this);
var d = {}, g, c = function (c) {
var b;
if (typeof c !== void 0 && (b = c.split("#"), Spotify.Utils.isArray(b) && b.length == 2)) return c = b[0], b = b[1], typeof d[c] !== "undefined" ? d[c].msg(b) : null;
throw Error("Not a valid message!");
};
this.send = function (h, b, a, f, k, m, d, p, q) {
var p = p || !1,
n = [],
s = [];
if (!Spotify.Utils.isArray(a) && !Spotify.Utils.isArray(f)) throw "Hermes:send Wrong arguments";
for (var t = 0; t < a.length; t++) n.push(c(a[t]));
for (t = 0; t < f.length; t++) s.push(c(f[t]));
(new Spotify.Hermes.ProtobufRequest({
uri: h,
method: b
}, k, n, s)).send(g, m, d, p, q, "hermes")
};
this.loadSchemas = function (c, b, a, f) {
var k;
if (Spotify.Utils.isArray(c))
if (k = Spotify.Utils.Base64.encode(c.join("_")) + "_", typeof d[k] !== "undefined") a(k);
else try {
var m = new Spotify.Protobuf.Schema(c, a, f, null);
d[k] = m;
if (b !== m.PROTO && b !== m.JSON) b = m.JSON;
m.id = k;
m.type = b;
m.reset();
m.load()
} catch (g) {
throw typeof f !== "undefined" && f(g), g;
} else f(Error("Schemas is not an array"))
};
this.loadSchemaData = function (c, b, a) {
var f =
(new Date).getTime() + Math.floor(Math.random() * 1E3),
f = Spotify.Utils.Base64.encode(f.toString()) + "_",
k, m;
if (Spotify.Utils.isArray(c)) {
c = c.join("\n");
for (k in d) a = d[k], a === c[0] && (m = a, f = k);
if (typeof m === "undefined") m = new Spotify.Protobuf.Schema([], null, null, null), m.id = f, m.type = "proto", m.setData(c), m.encode(), d[f] = m;
b(f)
} else a(Error("Schemas is not an array"))
};
this.init = function (c) {
g = c
}
};
Spotify.GatewayTypes = {
FLASH: "FLASH",
WEBSOCKETS: "WEBSOCKETS"
};
Spotify.PlayerTypes = {
FLASH_RTMPS: "FLASH_RTMPS",
FLASH_HTTP: "FLASH_HTTP",
FLASH_AAC: "FLASH_AAC",
WEBSOCKETS_STREAMING: "WEBSOCKETS_STREAMING",
HTML5_HTTP: "HTML5_HTTP"
};
Spotify.Protocols = {
RTMPS: "RTMPS",
RTMP: "RTMP",
HTTP: "HTTP",
HTTPS: "HTTPS"
};
Spotify.Instances = function () {
var d = {};
return {
add: function (g) {
g.id = "SPFBIn_" + Math.floor(Math.random() * 1E4);
d[g.id] = g;
return !0
},
get: function (g) {
if (typeof d[g] !== void 0) return d[g]
}
}
}();
Spotify.Features = function (d) {
var g = d || {};
this.isEnabled = function (c) {
return !!g[c]
};
this.getAll = function () {
return g
}
};
Spotify.Flash.SWFObject = function (d) {
Spotify.EventTarget.call(this);
var g = Spotify.DebuggerJS,
c = this;
this.isLoaded = !1;
var h = new Spotify.Events;
this.getSWF = function () {
if (this.isLoaded) {
if (window.document[d.SWFFlashId]) return window.document[d.SWFFlashId];
if (navigator.appName.indexOf("Microsoft Internet") === -1) {
if (document.embeds && document.embeds[d.SWFFlashId]) return document.embeds[d.SWFFlashId]
} else return document.getElementById(d.SWFFlashId)
} else g.error("Spotify.Flash.SWFObject", ["SWF Object is not loaded...."],
"corejs")
};
this.initialize = function () {
swfobject.hasFlashPlayerVersion("11.0.0") ? swfobject.embedSWF(d.SWFUrl, d.SWFContainerId, "1", "1", "11.0.0", "", {
playerType: d.playerType || "",
valid: 0,
id: d.SWFFlashId || "",
length: 0,
instanceId: d.instanceId,
logging: d.logging
}, {
quality: "high",
allowscriptaccess: "always",
wmode: "window",
bgcolor: "#2c2c2d"
}, {
id: d.SWFFlashId,
name: d.SWFFlashId,
align: "middle"
}, b) : (c.trigger(h.FLASH_UNAVAILABLE), g.error("Spotify.Flash.SWFObject", ["Your Flash is not up to date: 11.0.0"], "corejs"))
};
var b = function (a) {
!1 === a.success ? (c.trigger(h.FLASH_UNAVAILABLE), g.error("Spotify.Flash.SWFObject", ["Cannot load SWF object"], "corejs")) : (c.trigger(h.FLASH_AVAILABLE), c.isLoaded = !0)
}
};
Spotify.Flash.PlayerInterface = function (d, g) {
Spotify.EventTarget.call(this);
var c = this,
h = new Spotify.Events,
b;
this.hasSoundCapabilities = !0;
var a = function (a) {
this.trigger(a.type, a.params)
};
this.run = function (a) {
return typeof b !== "undefined" && b.isLoaded ? b.getSWF().sp_run(a) : !1
};
this.playpause = function (a) {
return typeof b !== "undefined" && b.isLoaded && this.hasSoundCapabilities ? b.getSWF().sp_playpause(a) : !1
};
this.position = function (a) {
try {
if (typeof b !== "undefined" && b.isLoaded && this.hasSoundCapabilities) return b.getSWF().sp_time(a)
} catch (k) {
return 0
}
};
this.getPlayerState = function (a) {
typeof b !== "undefined" && b.isLoaded && this.hasSoundCapabilities && (response = b.getSWF().sp_playerState(a));
return response
};
this.seek = function (a, k) {
if (typeof b !== "undefined" && b.isLoaded && this.hasSoundCapabilities) return b.getSWF().sp_seek(a, k)
};
this.pause = function (a) {
typeof b !== "undefined" && b.isLoaded && this.hasSoundCapabilities && b.getSWF().sp_pause(a)
};
this.resume = function (a) {
typeof b !== "undefined" && b.isLoaded && this.hasSoundCapabilities && b.getSWF().sp_resume(a)
};
this.stop =
function (a) {
typeof b !== "undefined" && b.isLoaded && this.hasSoundCapabilities && b.getSWF().sp_stop(a)
};
this.load = function (a, k, m) {
m = m || {};
typeof b !== "undefined" && b.isLoaded && c.hasSoundCapabilities && b.getSWF().sp_load(a, k, m)
};
this.play = function (a, k) {
typeof b !== "undefined" && b.isLoaded && c.hasSoundCapabilities && b.getSWF().sp_play(a, k)
};
this.setVolume = function (a, k) {
if (typeof b !== "undefined" && b.isLoaded && this.hasSoundCapabilities) try {
b.getSWF().sp_setVolume(a, k)
} catch (c) {}
};
this.getVolume = function (a) {
if (typeof b !==
"undefined" && b.isLoaded && this.hasSoundCapabilities) try {
return b.getSWF().sp_getVolume(a)
} catch (k) {}
return 1
};
this.getDuration = function (a) {
if (typeof b !== "undefined" && b.isLoaded && this.hasSoundCapabilities) try {
return b.getSWF().sp_getDuration(a)
} catch (k) {}
return 0
};
this.hasSound = function () {
return typeof b !== "undefined" && b.isLoaded ? this.hasSoundCapabilities = b.getSWF().sp_hasSound() : !1
};
this.addPlayer = function (a, k, m) {
if (typeof b !== "undefined" && b.isLoaded && c.hasSoundCapabilities) return b.getSWF().sp_addPlayer(a,
k, m)
};
this.removePlayerAtIndex = function (a) {
return typeof b !== "undefined" && b.isLoaded && c.hasSoundCapabilities ? (b.getSWF().sp_removePlayerAtIndex(a), !0) : !1
};
this.initializePlayerById = function (a) {
typeof b !== "undefined" && b.isLoaded && c.hasSoundCapabilities && b.getSWF().sp_initializePlayerById(a)
};
this.initialize = function () {
b = new Spotify.Flash.SWFObject({
playerType: g.playerType,
SWFFlashId: d + "_player",
SWFContainerId: g.SWFPlayerContainerId,
SWFUrl: g.SWFPlayerUrl,
SWFMinVersion: g.SWFMinVersion,
instanceId: d,
logging: g.logging,
length: g.valid,
valid: 0
});
b.bind(h.FLASH_AVAILABLE, a, this);
b.bind(h.FLASH_UNAVAILABLE, a, this);
b.initialize()
};
this.onLoad = function () {};
this.onPlay = function () {};
this.onPause = function () {};
this.onStop = function () {};
this.onTrackEnded = function () {};
this.onSongLoaded = function () {};
this.onPositionChanged = function () {};
this.onInvalidTrackUri = function () {};
this.onPlaybackFailed = function () {}
};
Spotify.HTML5.PlayerInterface = function (d) {
Spotify.EventTarget.call(this);
document.getElementById(d);
var g = new Spotify.Events;
this.hasSoundCapabilities = !0;
this.playpause = function () {};
this.position = function () {
return 0
};
this.getPlayerState = function () {
return {
position: 0,
duration: 0,
isPaused: !1,
isPlaying: !1,
isStopped: !0
}
};
this.seek = function () {};
this.pause = function () {};
this.resume = function () {};
this.stop = function () {};
this.load = function () {};
this.play = function () {};
this.setVolume = function () {};
this.getVolume =
function () {
return 0
};
this.getDuration = function () {
return 0
};
this.hasSound = function () {
return !0
};
this.addPlayer = function () {};
this.removePlayerAtIndex = function () {};
this.initializePlayerById = function () {};
this.initialize = function () {
this.trigger(g.READY)
};
this.onLoad = function () {};
this.onPlay = function () {};
this.onPause = function () {};
this.onStop = function () {};
this.onTrackEnded = function () {};
this.onSongLoaded = function () {};
this.onPositionChanged = function () {};
this.onInvalidTrackUri = function () {};
this.onPlaybackFailed =
function () {}
};
Spotify.Parsers.Facebook = function () {
this.makeCredential = function (d, g) {
var c = {};
if (d || g) {
var h = c.credential = {};
if (d) h.facebook_uid = d;
if (g) h.access_token = g
}
return c
};
this.parseConfig = function (d) {
return d[0]
};
this.parseCredential = function (d, g) {
var c, h = null,
b = null;
g || (g = "credential");
d && d[0] && (c = d[0][g]);
if (c) {
if (c.facebook_uid) h = c.facebook_uid;
if (c.access_token) b = c.access_token
}
return {
facebookUid: h,
accessToken: b
}
};
this.parseCredentialInspection = function (d) {
var g = d[0],
c = null;
g.alternative_credential && (c =
this.parseCredential(d, "alternative_credential"));
return {
alternativeCredential: c,
appUser: g.app_user || null,
permanentError: g.permanent_error || !1,
transientError: g.transient_error || !1
}
};
this.parseFriend = function (d) {
return {
facebookUid: d.facebook_uid,
appUser: d.app_user || null,
username: d.spotify_username || null,
name: d.display_name || null,
picture: d.picture_large || null
}
};
this.parseFriendList = function (d) {
for (var g = [], d = d[0].friends, c = 0; c < d.length; c++) g.push(this.parseFriend(d[c]));
return g
};
this.parsePermissions =
function (d) {
return d[0].permissions
};
this.parsePostId = function (d) {
return d[0].post_id
}
};
Spotify.Parsers.Metadata = function () {
var d = Spotify.Utils,
g = ["album_group", "single_group", "compilation_group", "appears_on_group"],
c = function (c, b) {
for (var a = 0, f = b.length; a < f; a += 2)
if (c[0] == b[a] && c[1] == b[a + 1]) return !0;
return !1
};
this.isPlayable = function (c, b) {
return c == "premium" && b.catalogue == "premium" ? !0 : c == "available"
};
this.parseAlbum = function (c, b) {
if (c.gid != void 0) c.id = d.str2hex(c.gid), delete c.gid;
if (c.artist != void 0)
for (var a = 0, f = c.artist.length; a < f; ++a) c.artist[a] = this.parseArtist(c.artist[a], null);
if (c.disc != void 0) {
a = 0;
for (f = c.disc.length; a < f; ++a) c.disc[a] = this.parseDisc(c.disc[a])
}
if (b != null) c.availability = this.parseRestrictions(c.restriction, b), c.playable = this.isPlayable(c.availability, b);
c.restriction != void 0 && delete c.restriction;
if (c.related != void 0) {
a = 0;
for (f = c.related.length; a < f; ++a) c.related[a] = this.parseAlbum(c.related[a], null)
}
c.cover != void 0 && delete c.cover;
return c
};
this.parseAlbumGroup = function (c, b) {
var a = [];
if (c.album != void 0)
for (var a = c.album, f = 0, k = a.length; f < k; ++f) a[f] = this.parseAlbum(a[f],
b);
return a
};
this.parseArtist = function (c, b) {
if (c.gid != void 0) c.id = d.str2hex(c.gid), delete c.gid;
if (c.top_track != void 0) c.top_track = this.parseTopTracks(c.top_track, b);
for (var a = 0, f = g.length; a < f; ++a) {
var k = g[a];
if (c[k] != void 0) {
for (var m = c[k], o = 0, p = m.length; o < p; ++o) m[o] = this.parseAlbumGroup(m[o], b);
c[k] = m
}
}
if (c.biography != void 0) {
a = 0;
for (f = c.biography.length; a < f; ++a) k = c.biography, m = a, o = c.biography[a], o.portrait != void 0 && delete o.portrait, k[m] = o
}
if (b != null) c.availability = this.parseRestrictions(c.restriction,
b), c.playable = this.isPlayable(c.availability, b);
c.restriction != void 0 && delete c.restriction;
if (c.related != void 0) {
a = 0;
for (f = c.related.length; a < f; ++a) c.related[a] = this.parseArtist(c.related[a], null)
}
c.portrait != void 0 && delete c.portrait;
return c
};
this.parseDisc = function (c) {
if (c.track != void 0)
for (var b = 0, a = c.track.length; b < a; ++b) c.track[b] = this.parseTrack(c.track[b], null);
return c
};
this.parseRestrictions = function (d, b) {
var a = {}, f = !1;
if (typeof d === "undefined" || d.length == 0) return "available";
for (var k =
0, m = d.length; k < m; ++k) {
var g = d[k],
p, q = !0;
g.countries_allowed != void 0 ? (q = g.countries_allowed.length != 0, p = c(b.country, g.countries_allowed)) : p = g.countries_forbidden !== void 0 ? !c(b.country, g.countries_forbidden) : !1;
if (p && g.catalogue != void 0)
for (p = 0; p < g.catalogue.length; ++p) {
var n = g.catalogue[p];
if (n.toLowerCase() == "ad" || n.toLowerCase() == "free") a.free = !0;
else if (n.toLowerCase() == "subscription" || n.toLowerCase() == "premium") a.premium = !0
}
if (g.type == void 0 || g.type.toLowerCase() == "streaming") f |= q
}
return f && b.catalogue ==
"all" ? "available" : a[b.catalogue] ? b.catalogue == "premium" ? "premium" : "available" : a.premium ? "premium" : f ? "regional" : "unavailable"
};
this.parseTopTracks = function (c, b) {
for (var a = [], f = 0, k = c.length; f < k; ++f) {
var m = c[f];
if (m.country != void 0 && m.country == b.country) {
if (m.track != void 0) a = c[f].track;
break
}
}
f = 0;
for (k = a.length; f < k; ++f) a[f] = this.parseTrack(a[f], null);
return a
};
this.parseTrack = function (c, b) {
if (c.gid != void 0) c.id = d.str2hex(c.gid), delete c.gid;
if (c.album != void 0) c.album = this.parseAlbum(c.album, null);
if (c.artist !=
void 0)
for (var a = 0, f = c.artist.length; a < f; ++a) c.artist[a] = this.parseArtist(c.artist[a], null);
if (b != null) {
var a = this.parseRestrictions(c.restriction, b),
f = this.isPlayable(a, b),
k;
if (k = f) {
a: {
if (c.file != void 0) {
k = 0;
for (var m = c.file.length; k < m; ++k)
if (c.file[k].format == "MP3_160") {
k = !0;
break a
}
delete c.file
}
k = !1
}
k = !k
}
k && (a = "unavailable", f = !1);
c.availability = a;
c.playable = f
}
c.restriction != void 0 && delete c.restriction;
if (c.playable) c.playableId = c.id;
else if (c.alternative != void 0) {
a = 0;
for (f = c.alternative.length; a <
f; ++a)
if (k = this.parseTrack(c.alternative[a], b), k.playable) {
c.availability = k.availability;
c.playable = k.playable;
c.playableId = k.id;
break
}
delete c.alternative
}
return c
}
};
Spotify.Parsers.AdMetadata = function () {
this.toTrackMetadata = function (d) {
return {
__pid: d.file_id,
name: d.title,
disc: 1,
duration: parseInt(d.duration * 1E3, 10),
number: 1,
popularity: d.tracking_url,
availability: "available",
playable: !0,
explicit: !1,
image: Spotify.SourceURLs.normal + d.image_id,
starred: !1,
advertisement: !0,
ad_metadata: {
type: d.ad_type,
embed: {
width: d.embed ? d.embed.width : 100,
height: d.embed ? d.embed.height : 100,
background_image: d.embed ? Spotify.SourceURLs.original + d.embed.background_image : ""
},
targetUrl: d.target_url
},
artists: [{
uri: d.target_url,
name: d.advertiser
}]
}
}
};
Spotify.Parsers.Search = function () {
var d = Spotify.DebuggerJS,
g = new Spotify.Parsers.Metadata,
c = function (a) {
return a ? Spotify.Utils.isArray(a) ? a : [a] : []
}, h = function (b, f) {
if (!b.id) return {};
if (b["album-type"]) b.type = b["album-type"].toUpperCase();
if (b["artist-id"] && b["artist-name"]) {
var c = b.artists = [];
if (Spotify.Utils.isArray(b["artist-id"]) && Spotify.Utils.isArray(b["artist-name"]))
for (var m = Math.min(b["artist-id"].length, b["artist-name"].length), d = 0; d < m; ++d) c.push({
id: b["artist-id"][d],
name: b["artist-name"][d]
});
else c.push({
id: b["artist-id"],
name: b["artist-name"]
})
}
b.cover = a(b);
if (b.popularity) b.popularity = Math.round(parseFloat(b.popularity) * 100);
if (b.restrictions) b.restrictions = k(b.restrictions.restriction);
b.availability = g.parseRestrictions(b.restrictions, f);
b.playable = g.isPlayable(b.availability, f);
delete b.restrictions;
delete b["album-type"];
delete b["artist-id"];
delete b["artist-name"];
delete b["external-ids"];
delete b["cover-small"];
delete b["cover-large"];
return b
}, b = function (a, b) {
if (!a.id) return {};
if (a.portrait) {
var f = a.portrait,
c = [];
f.id && c.push({
size: "DEFAULT",
file_id: f.id,
width: parseInt(f.width),
height: parseInt(f.height)
});
f.small && c.push({
size: "SMALL",
file_id: f.small
});
f.large && c.push({
size: "LARGE",
file_id: f.large
});
a.portrait = c
}
if (a.popularity) a.popularity = Math.round(parseFloat(a.popularity) * 100);
if (a.restrictions) a.restrictions = k(a.restrictions.restriction);
a.availability = g.parseRestrictions(a.restrictions, b);
a.playable = g.isPlayable(a.availability, b);
delete a.restrictions;
return a
}, a =
function (a) {
var b = [];
a.cover && (b.push({
size: "DEFAULT",
file_id: a.cover
}), delete a.cover);
a["cover-small"] && (b.push({
size: "SMALL",
file_id: a["cover-small"]
}), delete a["cover-small"]);
a["cover-large"] && (b.push({
size: "LARGE",
file_id: a["cover-large"]
}), delete a["cover-large"]);
return b
}, f = function (a) {
return !a.uri ? {} : a
}, k = function (a) {
for (var a = c(a), b = 0, f = a.length; b < f; ++b) {
var k = a[b]["@attributes"],
m = {};
if (k.allowed !== void 0) m.countries_allowed = k.allowed.replace(/,/g, "");
if (k.forbidden !== void 0) m.countries_forbidden =
k.forbidden.replace(/,/g, "");
if (k.catalogues !== void 0) m.catalogue = k.catalogues.split(",");
a[b] = m
}
return a
}, m = function (b, f) {
if (!b.id) return {};
if (b.album && b["album-id"]) b.album = {
name: b.album,
id: b["album-id"],
artist: {
name: b["album-artist"],
id: b["album-artist-id"]
},
cover: a(b)
};
if (b["album-artist"] && b["album-artist-id"]) {
b.album = b.album || {};
var d = b.album.artists = [];
if (Spotify.Utils.isArray(b["album-artist"]) && Spotify.Utils.isArray(b["album-artist-id"]))
for (var h = Math.min(b["album-artist"].length, b["album-artist-id"].length),
o = 0; o < h; ++o) d.push({
id: b["album-artist-id"][o],
name: b["album-artist"][o]
});
else d.push({
id: b["album-artist-id"],
name: b["album-artist"]
})
}
if (b.artist && b["artist-id"])
if (d = b.artists = [], Spotify.Utils.isArray(b.artist) && Spotify.Utils.isArray(b["artist-id"])) {
h = Math.min(b.artist.length, b["artist-id"].length);
for (o = 0; o < h; ++o) d.push({
id: b["artist-id"][o],
name: b.artist[o]
})
} else d.push({
id: b["artist-id"],
name: b.artist
});
if (b.length) b.length = parseInt(b.length);
if (b.popularity) b.popularity = Math.round(parseFloat(b.popularity) *
100);
if (b.number) b.number = parseInt(b["track-number"]);
if (b.year) b.year = parseInt(b.year);
if (b.title) b.name = b.title;
if (b.restrictions) b.restrictions = k(b.restrictions.restriction);
b.availability = g.parseRestrictions(b.restrictions, f);
b.playable = g.isPlayable(b.availability, f);
if (b.playable) b.playableId = b.id;
else if (b.alternatives) {
d = c(b.alternatives.track);
o = 0;
for (h = d.length; o < h; ++o) {
var u = m(d[o], f);
if (u.playable) {
b.availability = u.availability;
b.playable = u.playable;
b.playableId = u.id;
break
}
}
}
delete b.alternatives;
delete b.restrictions;
delete b["album-id"];
delete b["album-artist"];
delete b["album-artist-id"];
delete b.artist;
delete b.cover;
delete b["cover-small"];
delete b["cover-large"];
delete b["artist-id"];
delete b["external-ids"];
delete b.files;
delete b["track-number"];
delete b.title;
return b
}, o = function (a, b, f) {
for (var a = c(a), k = 0, m = a.length; k < m; ++k) a[k] = f(a[k], b);
return a
};
this.parse = function (a, k) {
var c = (new Date).getTime(),
g = Spotify.Utils.convertStringToXML(a),
g = Spotify.Utils.convertXMLToJSON(g.documentElement);
if (g.albums) g.albums = o(g.albums.album, k, h);
if (g.artists) g.artists = o(g.artists.artist, k, b);
if (g.tracks) g.tracks = o(g.tracks.track, k, m);
if (g.playlists) g.playlists = o(g.playlists.playlist, k, f);
if (g["did-you-mean"]) g.didYouMean = g["did-you-mean"], delete g["did-you-mean"];
g.total = {
albums: parseInt(g["total-albums"]),
artists: parseInt(g["total-artists"]),
tracks: parseInt(g["total-tracks"]),
playlists: parseInt(g["total-playlists"])
};
delete g["total-albums"];
delete g["total-artists"];
delete g["total-tracks"];
delete g["total-playlists"];
delete g.version;
d.log("Spotify.Parsers.Search", ["It took", (new Date).getTime() - c, "ms to parse the search result"], "parsing_times");
return g
}
};
Spotify.Parsers.Suggest = function () {
var d = Spotify.Link,
g = Spotify.Utils,
c = function (c) {
for (var b = 0, a = c.length; b < a; ++b) {
var f = c[b];
if (f.gid) f.id = g.str2hex(f.gid), delete f.gid;
if (f.image) f.image = g.str2hex(f.image);
if (f.image_uri) {
var k = d.fromString(f.image_uri);
f.image = k.id || k.ids[0];
delete f.image_uri
}
k = f.artists = [];
if (Spotify.Utils.isArray(f.artist_gid) && Spotify.Utils.isArray(f.artist_name))
for (var m = Math.min(f.artist_name.length, f.artist_gid.length), o = 0; o < m; ++o) k.push({
id: g.str2hex(f.artist_gid[o]),
name: f.artist_name[o]
});
delete f.artist_gid;
delete f.artist_name;
if (f.owner_uri && f.owner_name) f.user = {
uri: f.owner_uri,
name: f.owner_name
};
delete f.owner_name;
delete f.owner_uri;
if (f.rank) f.popularity = Math.round(f.rank * 100 / 2147483647), delete f.rank
}
return c
};
this.parse = function (d) {
return {
artists: c(d.artist || []),
albums: c(d.album || []),
tracks: c(d.track || []),
playlist: c(d.playlist || [])
}
}
};
Spotify.Parsers.Playlist = function () {
var d = function (d, c) {
var h = [],
b = {};
if (typeof d !== "undefined" && typeof d.items !== "undefined")
for (var a = 0; a < d.items.length; a++) {
var f;
f = d.items[a];
var k = c,
m = null,
o = {};
if (typeof f !== "undefined" && typeof f.uri !== "undefined") try {
m = Spotify.Link.fromString(f.uri);
m.type === "collectiontracklist" && (m = Spotify.Link.starredLink(m.username));
if (f.attributes) o = f.attributes;
if (!o.added_by) o.added_by = decodeURIComponent(k);
if (!o.timestamp) o.timestamp = 0;
if (m.username && encodeURIComponent(m.username) ==
m.username) m.username = decodeURIComponent(m.username)
} catch (p) {
m = Spotify.Link.emptyLink()
}
f = {
link: m || Spotify.Link.emptyLink(),
attributes: o
};
if (f.link.type === "starred")
if (typeof b[f.link.username] === "undefined") b[f.link.username] = !0;
else continue;
f !== null && h.push({
uri: f.link,
attributes: f.attributes
})
}
return {
contents: h
}
};
this.parsePlaylist = function (g, c) {
if (typeof g.contents !== "undefined") {
var h = d(g.contents, c);
g.contents = h.contents
}
if (typeof g.revision !== "undefined") g.revision = Spotify.Utils.str2hex(g.revision);
return g
};
this.parsePublishedPlaylist = function (g, c) {
if (typeof g.contents !== "undefined") {
var h = d(g.contents, c);
g.contents = h.contents;
g.length = g.contents.length
}
if (typeof g.revision !== "undefined") g.revision = Spotify.Utils.str2hex(g.revision);
return g
};
this.parseMetadata = function (d) {
return d.attributes
}
};
Spotify.Parsers.AdChooser = function () {
this.parseServerResponse = function (d) {
d = Spotify.Utils.convertStringToXML(d);
return Spotify.Utils.convertXMLToJSON(d.documentElement)
};
this.parseAudioAdsVersion1 = function (d) {
var g = {
"audio-ad-break": {},
AdQueueEntry: []
}, c = {};
try {
if (typeof d.rules.rule !== "undefined")
for (var h = 0, b = d.rules.rule.length; h < b; h += 1) {
var a = d.rules.rule[h];
c[a.id] = a
}
g["audio-ad-break"] = d["audio-ad-break"];
if (typeof d.ads["audio-ad"] !== "undefined") {
var f = [];
d.ads["audio-ad"].length > 0 ? f = d.ads["audio-ad"] :
typeof d.ads["audio-ad"].ad_version !== "undefined" && f.push(d.ads["audio-ad"]);
h = 0;
for (b = f.length; h < b; h += 1) {
for (var k = f[h], d = [], m = 0, o = k.rules.id.length; m < o; m += 1) a = k.rules.id[m], d.push(c[a]);
for (var m = null, p = 0, q = k.files.file.length; p < q; p += 1) {
var n = k.files.file[p];
if (n["@attributes"].format === "MPEG 1 layer 3,160000,0,1,1") {
m = n["@attributes"].id;
break
}
}
var s = {
ad_type: typeof k["embed-width"] === "string" ? "lightbox" : "audio",
has_been_played: !1,
has_been_clicked: !1,
adPlayCount: 0,
campaignPlayCount: 0,
ids_valid: !0,
non_explicit: k["non-explicit-only"] || 0,
is_test_ad: !1,
priority: parseFloat(k.priority),
duration: parseInt(k.duration, 10),
min_duration: 0,
ad_version: k.ad_version || 1,
start_time_earliest: parseInt(k.starttime),
start_time_latest: parseInt(k.endtime),
campaign_expiry: parseInt(k.expiry),
adclass: 0,
adchooserkind: null,
adkind: "ENC_AD_AUDIO",
rules: d,
ad_id: k.id,
campaign_id: k.campaign,
advertiser: k.advertiser,
target_url: k.url,
token: k.token,
tracking_url: typeof k["tracking-url"] === "string" ? k["tracking-url"] : null,
files: k.files,
image_id: k.image,
embed: {
width: k["embed-width"],
height: k["embed-height"],
background_image: typeof k["embed-background-image"] === "string" ? k["embed-background-image"] : ""
},
banner_size: null,
banner_type: null,
html: null,
title: k.title,
caption: k.caption,
file_id: m,
large_bgcolor: null,
large_image_id: null,
fullscreen_delay: null,
fullscreen_inactivity_timeout: null,
background_target_url: null,
message: null,
level: null
};
g.AdQueueEntry.push(s)
}
}
} catch (t) {}
return g
}
};
Spotify.Parsers.Social = function () {
var d = Spotify.DebuggerJS;
this.parse = function (g) {
var c = (new Date).getTime();
if (!g.username) g.username = "";
if (!g.full_name) g.full_name = "";
if (!g.image_url) g.image_url = "";
if (!g.large_image_url) g.large_image_url = "";
if (!g.first_name) g.first_name = "";
if (!g.last_name) g.last_name = "";
if (!g.facebook_uid) g.facebook_uid = "";
d.log("Spotify.Parsers.Social", ["It took", (new Date).getTime() - c, "ms to parse the social result"], "parsing_times");
return g
}
};
Spotify.Parsers.URL = function () {
this.parseRTMPUrl = function (d) {
var g = Spotify.Utils.parseURL(d);
return {
server: g.protocol + "://" + g.host + (g.port !== "" ? ":" + g.port : "") + "/cfx/st",
protocol: g.protocol,
url: d,
file: "mp3:" + g.relative.replace("/cfx/st/", "")
}
};
this.parseHTTPUrl = function (d) {
var g = Spotify.Utils.parseURL(d);
return {
server: g.protocol + "://" + g.host + (g.port !== "" ? ":" + g.port : ""),
protocol: g.protocol,
url: d,
file: g.relative
}
}
};
Spotify.Services.Base = function (d) {
Spotify.EventTarget.call(this);
this.id = "";
this.serviceIsReady = !1;
this.services = {};
this._totalDependenciesReady = 0;
this._dependencies = [];
var g = new Spotify.Events;
this._onServiceReady = function () {
this._totalDependenciesReady++;
if (this._totalDependenciesReady >= this._dependencies.length) delete this._dependencies, delete this._totalDependenciesReady, this.serviceIsReady = !0, this.setup(), this.trigger(g.READY)
};
this.setup = function () {};
this.onReady = function (c, d) {
this.serviceIsReady ?
c.call(d) : this.bind(g.READY, c, d)
};
this._initialize = function (c) {
c.length === 0 && this._onServiceReady();
for (var d = 0, b = c.length; d < b; d += 1) this.services[c[d].id] = c[d], c[d].onReady(this._onServiceReady, this)
};
this.send = function (c) {
c.calleeId = this.id;
this.trigger(g.REQUEST, c)
};
this.onNotify = function () {};
this.getProtobufMsgParser = d.getProtobufMsgParser;
this.dispose = function () {}
};
Spotify.Services.Time = function () {
var d;
this.getServerTime = function (g, c, h) {
this.serviceIsReady ? (typeof h === "undefined" && (h = !1), typeof d !== "undefined" && !h ? g(Math.floor((new Date).getTime() / 1E3) + d) : this.send(new Spotify.Calls.Simple({
method: "time",
payload: [],
context: this,
persistent: !1,
retries: 2,
type: "time"
}, function (b) {
var a = Math.floor((new Date).getTime() / 1E3);
d = b.response - a;
g(b.response)
}, c))) : c(new Spotify.Errors.Error([503, 0, "Time service not ready!"]))
}
};
Spotify.Services.Suggest = function () {
var d = this,
g = new Spotify.Parsers.Suggest;
this.suggest = function (c, h, b) {
this.serviceIsReady ? this.services.user.getUserInfo(function (a) {
a = new Spotify.Calls.Hermes({
header: {
uri: "hm://searchsuggest/suggest/" + encodeURIComponent(c) + "?country=" + a.country + "&catalogues=" + a.catalogue,
method: "GET"
},
responseSchemas: ["suggest#Suggestions"],
type: "searchsuggest"
}, function (a, k) {
if (k == 200) {
var c = g.parse(a[0]);
h(c, k)
} else b(new Spotify.Errors.Error([13, k, ""]))
}, b);
d.send(a)
}, function (a) {
b(a)
}) :
b(new Spotify.Errors.Error([13, 503, "Suggest service not ready!"]))
}
};
Spotify.Services.AppStore = function () {
this.list = function (d, g, c) {
this.serviceIsReady ? this.send(new Spotify.Calls.Hermes({
header: {
uri: "hm://appstore/app/list",
method: "GET"
},
payload: d,
payloadSchemas: ["appstore#RequestHeader"],
responseSchemas: ["appstore#AppList"],
type: "appstore"
}, g, c)) : c(new Spotify.Errors.Error([13, 503, "Appstore service not ready!"]))
}
};
Spotify.Services.PopCount = function () {
this.get = function (d, g, c, h, b, a) {
this.serviceIsReady ? (g = typeof g === "number" ? g : 100, c = typeof c === "boolean" ? "&friendsFirst=" + c : "", h = typeof h === "string" ? "&afterUser=" + h : "", d = Spotify.Link.fromString(d).toURLPath(), this.send(new Spotify.Calls.Hermes({
header: {
uri: "hm://popcount/" + d + "?maxUsers=" + g + c + h,
method: "GET"
},
payload: [],
payloadSchemas: [],
responseSchemas: ["popcount#PopcountResult"],
type: "PopCount"
}, b, a))) : a(new Spotify.Errors.Error([13, 503, "PopCount service not ready!"]))
}
};
Spotify.Services.Metadata = function () {
var d = Spotify.Link,
g = this,
c = new Spotify.Parsers.Metadata;
new Spotify.Events;
var h = function (a) {
switch (a.type) {
case d.Type.TRACK:
return "hm://metadata/track/" + a.id;
case d.Type.ALBUM:
return "hm://metadata/album/" + a.id;
case d.Type.ARTIST:
return "hm://metadata/artist/" + a.id;
default:
throw Error("Unsupported link type!");
}
}, b = function (a) {
switch (a) {
case d.Type.TRACK:
return "metadata#Track";
case d.Type.ALBUM:
return "metadata#Album";
case d.Type.ARTIST:
return "metadata#Artist";
default:
throw Error("Unsupported link type!");
}
}, a = function (a) {
switch (a) {
case d.Type.TRACK:
return c.parseTrack.bind(c);
case d.Type.ALBUM:
return c.parseAlbum.bind(c);
case d.Type.ARTIST:
return c.parseArtist.bind(c);
default:
throw Error("Unsupported link type!");
}
}, f = function (f, k, c) {
var m = function (b, m) {
if (Spotify.Hermes.Request.isSuccess(m)) {
var d = b[0],
h = a(f.type);
g.services.user.getUserInfo(function (a) {
d = h(d, a);
k(d, m)
}, function (a) {
c(a)
})
} else c(m)
};
this.send = function () {
var a = new Spotify.Calls.Hermes({
header: {
uri: h(f),
method: "GET"
},
payload: [],
payloadSchemas: [],
responseSchemas: [b(f.type)],
type: "metadata",
persistent: !1,
bypassCache: !1
}, m, c);
g.send(a)
}
}, k = function (f, k, c) {
var m = f[0].type,
s = a(m),
t = function (a, b) {
var f = [];
g.services.user.getUserInfo(function (c) {
for (var m = 0, d = a.length; m < d; m += 1)
if (a[m]) {
var h = s(a[m], c);
f.push(h)
}
k(f, b)
}, function (a) {
c(a)
})
};
this.send = function () {
for (var a = [], k = 0, p = f.length; k < p; ++k) a.push({
uri: h(f[k])
});
k = Spotify.Calls.Hermes;
a: switch (m) {
case d.Type.TRACK:
p = "hm://metadata/tracks";
break a;
case d.Type.ALBUM:
p =
"hm://metadata/albums";
break a;
case d.Type.ARTIST:
p = "hm://metadata/artists";
break a;
default:
throw Error("Unsupported link type!");
}
a = new k({
header: {
uri: p,
method: "GET"
},
payload: [{
request: a
}],
payloadSchemas: [],
responseSchemas: [b(m)],
type: "metadata",
isMultiGet: !0,
persistent: !1,
bypassCache: !1
}, t, c);
g.send(a)
}
}, m = function (a) {
if (a instanceof Spotify.Link) return a;
else if (typeof a === "string" || a instanceof String) return d.fromString(a);
else throw Error("Invalid argument!");
};
this.lookup = function (a, b, c) {
if (g.serviceIsReady)
if (Spotify.Utils.isArray(a))
if (a.length >
1) {
for (var d = Math.ceil(a.length / 100), h = !1, t = [], u = Array(d), w = function (a) {
return function (f) {
h || (u[a] = f, --d == 0 && b(Array.prototype.concat.apply([], u), 200))
}
}, v = function (a) {
h = !0;
c(a)
}, A = 0, x = a.length; A < x; ++A) t.push(m(a[A]));
a = 0;
do(new k(t.splice(0, 100), w(a++), v)).send(); while (t.length > 0)
} else a.length == 1 ? (new f(m(a[0]), function (a, f) {
b([a], f)
}, c)).send() : c(Error("Array does not contain any items!"));
else(new f(m(a), b, c)).send();
else c(Error("Service not ready!"))
}
};
Spotify.Services.Search = function () {
var d = this,
g = new Spotify.Parsers.Search;
this.DEFAULT_TOTAL_RESULTS = 50;
this.TRACKS = 1;
this.ALBUMS = 2;
this.ARTISTS = 4;
this.PLAYLISTS = 8;
this.ALL = this.TRACKS | this.ALBUMS | this.ARTISTS | this.PLAYLISTS;
this.search = function (c, h, b, a) {
if (this.serviceIsReady)
if (typeof c === "undefined" || c === "") a(new Spotify.Errors.Error([403, 0, "You haven't provided a valid query"]));
else {
h = h || {};
h.type = h.type || this.ALL;
h.total = h.total || this.DEFAULT_TOTAL_RESULTS;
h.offset = h.offset || 0;
if (h.total > this.DEFAULT_TOTAL_RESULTS) h.total =
this.DEFAULT_TOTAL_RESULTS;
this.send(new Spotify.Calls.Simple({
method: "search",
payload: [c, h.type, h.total, h.offset],
context: this,
persistent: !1,
retries: 2,
type: "search"
}, function (f) {
d.services.user.getUserInfo(function (a) {
a = g.parse(f.response, a);
b(a)
}, function (b) {
a(b)
})
}, a))
} else a(new Spotify.Errors.Error([503, 0, "Search service not ready!"]))
}
};
Spotify.Services.SearchHermes = function () {
this.TRACKS = "TRACK";
this.ALBUMS = "ALBUM";
this.ARTISTS = "ARTIST";
this.PLAYLISTS = "PLAYLIST";
this.USERS = "USER";
this.DEFAULT_TOTAL_RESULTS = 200;
this.search = function (d, g, c, h) {
this.serviceIsReady ? typeof d === "undefined" || d === "" ? h(new Spotify.Errors.Error([403, 0, "You haven't provided a valid query"])) : (g = g || {}, g.query = d, g.type = g.type || this.TRACKS, g.limit = g.total || this.DEFAULT_TOTAL_RESULTS, delete g.total, g.offset = g.offset || 0, this.send(new Spotify.Calls.Hermes({
header: {
uri: "hm://search/search",
method: "GET"
},
payload: [g],
payloadSchemas: ["searchHermes_FULL#SearchRequest"],
responseSchemas: ["searchHermes_FULL#SearchReply"],
type: "search_hermes"
}, c, h))) : h(new Spotify.Errors.Error([503, 0, "Search service not ready!"]))
}
};
Spotify.Services.Toplist = function () {
var d = this,
g = {};
this.TRACK = "track";
this.ALBUM = "album";
this.ARTIST = "artist";
this.PLAYLIST = "playlist";
this.GLOBAL = "global";
var c = {
track: Spotify.Link.trackLink,
album: Spotify.Link.albumLink,
artist: Spotify.Link.artistLink,
playlist: Spotify.Link.playlistLink
}, h = function (b, a, f, k, m, h, p) {
var q = function (a) {
if (a[0].items != void 0) {
for (var a = a[0].items, m = 0, d = a.length; m < d; ++m) a[m] = c[f](a[m]);
g[b] = a;
k(a, f, 200)
} else if (a[0].uris != void 0) {
a = a[0].uris;
m = 0;
for (d = a.length; m < d; ++m) a[m] =
Spotify.Link.fromString(a[m]);
g[b] = a;
k(a, f, 200)
} else g[b] = [], k([], f, 200)
}, n = function (b, c) {
if (c != null) k(c, f, 200);
else {
var h = [],
g = [],
o = [];
f === "playlist" ? (h = ["socialgraph#TopPlaylistsRequest"], g = ["socialgraph#TopPlaylistsReply"], o.push({
username: p
})) : g = ["toplist#Toplist"];
h = new Spotify.Calls.Hermes({
header: {
uri: a,
method: "GET"
},
payload: o,
payloadSchemas: h,
responseSchemas: g,
type: "toplist"
}, q, m);
d.send(h)
}
};
h ? n(b, null) : n(b, g[b])
};
this.lookupForUser = function (b, a, f, k, c) {
this.serviceIsReady ? this.services.user.getUserInfo(function (d) {
b =
b ? b : d.user;
var d = Spotify.Link.userToplistLink(b, a).toURI(),
g = "hm://toplist/toplist/user/" + encodeURIComponent(b) + "?type=" + a;
a === "playlist" && (g = "hm://socialgraph/suggestions/topplaylists");
h(d, g, a, f, k, c, b)
}, k) : k(new Spotify.Errors.Error([13, 503, "Toplist service not ready!"]))
};
this.lookupForRegion = function (b, a, f, k, c) {
this.serviceIsReady ? this.services.user.getUserInfo(function (d) {
b = b ? b : d.country;
var d = b == "global",
g = Spotify.Link.toplistLink(a, d ? null : b, d).toURI();
h(g, d ? "hm://toplist/toplist/region?type=" +
a : "hm://toplist/toplist/region/" + b + "?type=" + a, a, f, k, c)
}, k) : k(new Spotify.Errors.Error([13, 503, "Toplist service not ready!"]))
}
};
Spotify.Services.Playlist = function () {
this.DEFAULT_TOTAL_RESULTS = 200;
var d = Spotify.Utils.isArray,
g = Spotify.DebuggerJS,
c = this,
h = new Spotify.Events,
b = new Spotify.Parsers.Playlist,
a = [],
f = null,
k = {}, m = function (a, b) {
b = typeof b !== "undefined" && b.length ? "?" + b.join("&") : "";
return "hm://playlist/" + a.split(":").join("/").substr(8) + b
}, o = function (a) {
return function () {
for (var b = 0; b < a.length; b++) typeof a[b] === "function" && a[b].apply(this, arguments)
}
}, p = function (a, b, f, d, h, g) {
var o = [];
a === "ADD" && o.push("add_first=true");
a = "APPEND" === a ? "ADD" : a;
(a === "REMOVE" || a === "MODIFY") && Spotify.Link.fromString(b).type !== "inbox" && o.push("syncpublished=true");
var q = [],
q = a === "REMOVE" || a === "ADD" || a === "APPEND" ? [] : ["playlist_FULL#OpList"],
p = [];
a === "MODIFY" ? p = ["playlist_FULL#ModifyReply"] : a === "PUT" && (p = ["playlist_FULL#CreateListReply"]);
f && a === "MODIFY" && (f = w(f.revision), o.push("revision=" + f));
var s = 0,
t = 0,
u = function () {
var f = new Spotify.Calls.Hermes({
header: {
uri: m(b, o),
method: a
},
payload: [d],
payloadSchemas: q,
responseSchemas: p,
type: "playlist",
persistent: !1,
bypassCache: !1
}, function (m) {
c.services.user.getUserInfo(function (c) {
k[b] = w(Spotify.Utils.str2hex(m[0].revision || m[0]));
var g = [],
o = [];
typeof d === "string" && (g = d.split(","));
for (var q = 0, p = g.length; q < p; q += 1) {
var s = {
uri: Spotify.Link.fromString(g[q])
};
a === "ADD" && b !== Spotify.Link.publishedRootlistLink(c.user).toURI() && s.uri.type === "playlist" && o.push(s)
}
o.length > 0 && n(o);
typeof h === "function" && (a === "PUT" ? h(m, {
revision: k[b]
}) : h(!0, {
revision: k[b]
}));
c = f.header.uri.split("?")[0];
g = "GET";
if (a ===
"MODIFY" && d.ops.length && (d.ops[0].kind === "UPDATE_LIST_ATTRIBUTES" || d.ops[0].kind === "UPDATE_ITEM_ATTRIBUTES")) g = "HEAD";
Spotify.Hermes.Cache.removeAllContaining(g + c)
}, g)
}, M);
c.send(f)
}, M = function () {
t >= 4 ? typeof g === "function" && g.apply(this, arguments) : (s = Math.floor(2 * t * Math.random()) * 500, t++, setTimeout(u, s))
};
return u
}, q = function () {
var a;
c.serviceIsReady ? c.services.user.getUserInfo(function (b) {
a = Spotify.Link.profileLink(b.user);
g.log("Spotify.Services.Playlist", ["Will try to subscribe to", a.username],
"corejs");
n([{
uri: a
}]);
c.rootlist({
total: -1,
offset: 0
}, function (a) {
for (var f = [], c = 0, k = a.contents.length; c < k; c += 1) {
var m = a.contents[c];
m.username !== b.user && f.push(m)
}
f.length > 0 && (g.log("Spotify.Services.Playlist", ["Will try to subscribe to", f], "corejs"), n(f))
}, t)
}, t) : g.error("Spotify.Services.Playlist", ["Playlist service not ready"], "corejs")
}, n = function (a) {
var b = [];
if (!Spotify.Utils.isArray(a)) throw "Playlists argument must be an array";
if (a.length !== 0) {
for (var f = 0, k = a.length; f < k; f += 1) typeof a[f] !==
"undefined" && typeof a[f].uri !== "undefined" && b.push("hm://playlist/" + a[f].uri.toURLPath());
c.services.pubsub.subscribe("hm://playlist/", [{
uris: b
}], ["playlist_FULL#SubscribeRequest"], s, t, u, c)
}
}, s = function (a) {
g.log("Spotify.Services.Playlist", ["Subscription was a success", a], "corejs")
}, t = function (a) {
g.error("Spotify.Services.Playlist", ["Subscription failed", a], "corejs")
}, u = function (a) {
if (a.length > 0) {
a = c.getProtobufMsgParser("playlist4service", "PlaylistModificationInfo").parseFromStringSync(Spotify.Utils.Base64.decode(a[3]));
if (typeof a.new_revision !== "undefined") a.new_revision = w(Spotify.Utils.str2hex(a.new_revision));
g.log("Spotify.Services.Playlist", ["Got a notification", a], "corejs");
typeof a.uri !== "undefined" && (Spotify.Link.fromString(a.uri).type === "collectiontracklist" ? g.log("Spotify.Services.Playlist", ["The notification is about the starred list but by using the legacy object collectiontracklist"], "corejs") : (c.trigger(h.CHANGE, {
localRevision: k[a.uri],
revision: a.new_revision,
uri: a.uri
}), g.log("Spotify.Services.Playlist", ["Triggered change event for ", a.uri, " with new revision: ", a.new_revision], "corejs")))
}
}, w = function (a) {
var b = parseInt(a.substr(0, 8), 16),
a = a.substr(8);
return b + "," + a
};
this.metadata = function (a, f, k) {
c.serviceIsReady ? (typeof a == "string" && (a = Spotify.Link.fromString(a)), this.send(new Spotify.Calls.Hermes({
header: {
uri: m(a.toURI()),
method: "HEAD"
},
payload: [],
payloadSchemas: [],
responseSchemas: ["playlist_FULL#SelectedListContent"],
type: "playlist",
persistent: !1,
bypassCache: !1
}, function (c) {
var m = a.toURI();
if (typeof c ==
"undefined" || typeof c[0] == "undefined") k(new Spotify.Errors.Error([13, 404, "No results", m]));
else {
var d = b.parseMetadata(c[0]);
d.owner = Spotify.Link.fromString(m).username;
d.uri = m;
d.revision = w(Spotify.Utils.str2hex(c[0].revision));
f(d)
}
}, function (b) {
b.data = a.toURI();
k(b)
}))) : k(new Spotify.Errors.Error([13, 503, "Playlist service not ready!"]))
};
this.getChangesBetweenRevisionAndHead = function (a, b, f, d) {
b = new Spotify.Calls.Hermes({
header: {
uri: m(a) + "?revision=" + b,
method: "DIFF"
},
payload: [],
payloadSchemas: [],
responseSchemas: ["playlist_FULL#SelectedListContent"],
type: "playlist",
persistent: !1,
bypassCache: !1
}, function (b) {
var c = {};
c.operations = b[0].diff.ops;
c.uri = a;
c.revision = w(Spotify.Utils.str2hex(b[0].revision));
k[a] = c.revision;
f(c)
}, d);
c.send(b)
};
this.subscribe = function (b, k, m) {
clearTimeout(f);
if (c.serviceIsReady) {
if (typeof b.publish === "undefined") b.publish = !1;
for (var n = d(b.uri) ? b.uri : [b.uri], q = n.length; q--;) {
var s = Spotify.Link.fromString(n[q]);
n[q] = s.toURI()
}
a.push({
username: b.username,
uri: n,
callback: k,
errback: m
});
var t = this,
u;
f = setTimeout(function () {
u = a.slice(0);
f = null;
a = [];
for (var k = {}, m = {}, d = {}, n = {}, q = 0; q < u.length; q++) n = u[q], k[n.username] = k[n.username] || [], m[n.username] = m[n.username] || [], d[n.username] = d[n.username] || [], k[n.username] = k[n.username].concat(n.uri), m[n.username].push(n.callback), d[n.username].push(n.errback);
for (var s in k) {
var w = k[n.username],
A = o(m[n.username]),
x = o(d[n.username]),
F = Spotify.Link.rootlistLink(b.username).toURI();
t.list({
uri: F,
total: -1
}, function (a) {
for (var b = F, f = A,
k = x, m = w.slice(0), d = 0; d < a.contents.length; d++) {
var g = a.contents[d].uri;
if (g.type != "empty")
for (var o = 0; o < m.length; o++) g.toURI() == m[o] && delete m[o]
}
a = [];
for (d = 0; d < m.length; d++) m[d] && a.push(m[d]);
a.length > 0 ? (p("ADD", b, null, a.join(","), f, k)(), c.trigger(h.PLAYLIST_SUBSCRIBE, {
uris: a
})) : typeof f === "function" && f(!0)
}, x);
b.publish && setTimeout(function () {
t.publishPlaylists(w, function () {
g.log("Spotify.Services.Playlist", ["Playlists were published too", w], "corejs")
}, function () {
g.error("Spotify.Services.Playlist", ["Playlists couldn't be published", w], "corejs")
})
}, 2E3)
}
}, 100)
} else m(new Spotify.Errors.Error([13, 503, "Playlist service not ready!"]))
};
this.list = function (a, f, d) {
if (c.serviceIsReady) {
if (a.total > this.DEFAULT_TOTAL_RESULTS) a.total = this.DEFAULT_TOTAL_RESULTS;
else if (!a.total) a.total = -1;
if (typeof a.offset === "undefined") a.offset = 0;
var h = Spotify.Link.fromString(a.uri),
g = {
uri: m(h.toURI()),
method: "GET"
};
typeof a.offset !== "undefined" && typeof a.total !== "undefined" && (g.uri += "?from=" + a.offset, a.total !== -1 &&
(g.uri += "&length=" + a.total));
this.send(new Spotify.Calls.Hermes({
header: g,
payload: [],
payloadSchemas: [],
responseSchemas: ["playlist_FULL#SelectedListContent"],
type: "playlist",
persistent: !1,
bypassCache: !1
}, function (a) {
if (typeof a == "undefined" || typeof a[0] == "undefined") d(new Spotify.Errors.Error([13, 404, "No results"]));
else {
var c;
c = h.type === "published-rootlist" ? b.parsePublishedPlaylist(a[0], h.username) : b.parsePlaylist(a[0], h.username);
k[h.toURI()] = w(a[0].revision) || "";
h.type == "starred" && c.contents.reverse();
f(c, {
revision: k[h.toURI()]
})
}
}, d))
} else d(new Spotify.Errors.Error([13, 503, "Playlist service not ready!"]))
};
this.rootlist = function (a, b, f) {
this.services.user.getUserInfo(function (k) {
a.username = k.user;
a.uri = Spotify.Link.rootlistLink(a.username).toURI();
c.list(a, b, f)
}, f)
};
this.publishedRootlist = function (a, b, f) {
a.offset && delete a.offset;
a.total = -1;
a.uri = Spotify.Link.publishedRootlistLink(a.username).toURI();
this.list(a, b, f)
};
this.starredPlaylist = function (a, b, f) {
a.uri = Spotify.Link.starredLink(a.username).toURI();
this.list(a, b, f)
};
this.publishPlaylists = function (a, b, f) {
this.services.user.getUserInfo(function (c) {
c = Spotify.Link.publishedRootlistLink(c.user).toURI();
p("ADD", c, null, a.join(","), b, f)()
}, f)
};
this.unpublishPlaylists = function (a, b, f) {
this.services.user.getUserInfo(function (k) {
k = Spotify.Link.publishedRootlistLink(k.user).toURI();
c.removeFromPlaylistByUri(k, a, b, f)
}, f)
};
this.addToPlaylist = function (a, b, f, c) {
p("APPEND", a, null, b.join(","), f, c)()
};
this.addToPlaylistWithAttributes = function (a, b, f, c) {
for (var k = [], m = 0, d = b.length; m < d; m += 1) {
var h = b[m];
k.push({
uri: h.uri,
attributes: {
added_by: h.addedBy || "",
message: h.message || ""
}
})
}
p("MODIFY", a, null, {
ops: [{
kind: "ADD",
add: {
addLast: !0,
items: k
}
}]
}, f, c)()
};
this.addTracksInPlaylist = function (a, b, f, k) {
c.addToPlaylist(a, b, f, k)
};
this.removeFromPlaylistByUri = function (a, b, f, k) {
p("REMOVE", a, null, b.join(","), f, k)()
};
this.removeFromPlaylist = function (a, b, f, k, c) {
this.list({
uri: a,
total: -1
}, function (m) {
p("MODIFY", a, m, {
ops: [{
kind: "REM",
rem: {
fromIndex: b,
length: f
}
}]
}, k, c)()
}, function (a) {
c(a)
})
};
this.starTracks = function (a, b, f) {
this.services.user.getUserInfo(function (k) {
k = Spotify.Link.starredLink(k.user).toURI();
c.addToPlaylist(k, a, b, f)
}, f)
};
this.unstarTracks = function (a, b, f) {
this.services.user.getUserInfo(function (k) {
k = Spotify.Link.starredLink(k.user).toURI();
c.removeFromPlaylistByUri(k, a, b, f)
}, f)
};
this.createPlaylist = function (a, b, f) {
this.services.user.getUserInfo(function (k) {
var m = Spotify.Link.profileLink(k.user).toURI();
p("PUT", m, null, {
ops: [{
kind: "UPDATE_LIST_ATTRIBUTES",
update_list_attributes: {
new_attributes: {
values: {
name: a.name
}
}
}
}]
},
function (m, d) {
c.subscribe({
username: k.user,
uri: m[0].uri,
publish: a.publish
}, function () {
b(m[0].uri, {
revision: w(d.revision)
})
}, f)
}, f)()
}, f)
};
this.renamePlaylist = function (a, b, f, k) {
p("MODIFY", a, null, {
ops: [{
kind: "UPDATE_LIST_ATTRIBUTES",
update_list_attributes: {
new_attributes: {
values: {
name: b
}
}
}
}]
}, function (a, b) {
f(!0, b)
}, k)()
};
this.updateItemAttributes = function (a, b, f, k, c) {
var m = {
ops: [{
kind: "UPDATE_ITEM_ATTRIBUTES",
update_item_attributes: {
index: b,
new_attributes: {
values: f
}
}
}]
};
this.list({
uri: a,
total: -1
}, function (b) {
p("MODIFY",
a, b, m, function (a, b) {
k(!0, b)
}, c)()
}, c)
};
this.synchronize = function (a, b, f, k) {
this.send(new Spotify.Calls.Hermes({
header: {
uri: m(a),
method: "CALL"
},
payload: requestData,
payloadSchemas: ["playlist_FULL#Playlist4ServiceCall"],
responseSchemas: ["playlist_FULL#Playlist4ServiceReturn"],
type: "playlist",
persistent: !1,
bypassCache: !1
}, f, k))
};
this.onNotify = function (a) {
switch (a.type) {
case h.CONNECTED:
q()
}
}
};
Spotify.Services.User = function () {
var d = this,
g = new Spotify.Events,
c = null,
h = !1,
b = [];
this.getUserInfo = function (a, f, k) {
typeof k === "undefined" && (k = !1);
c !== null && !k ? a(c) : (b.push({
onSuccess: a,
onError: f
}), h || (h = !0, this.send(new Spotify.Calls.Simple({
method: "user_info",
payload: [],
context: this,
persistent: !1,
retries: 2,
type: "userdata"
}, function (a) {
c = a.response;
h = !1;
for (var a = 0, f = b.length; a < f; a += 1) b[a].onSuccess(c);
b = []
}, function (a) {
h = !1;
for (var f = 0, k = b.length; f < k; f += 1) b[f].onError(a);
b = []
}))))
};
this.setUserAttribute =
function (a, b, k, m) {
this.send(new Spotify.Calls.Simple({
method: "set_ua",
payload: [a, b],
context: this,
persistent: !1,
retries: 2,
type: "userdata"
}, function () {
c[a] = b;
k(!0, 200);
d.trigger(g.USER_INFO_CHANGE)
}, m))
};
this.onNotify = function (a) {
switch (a.type) {
case g.USER_INFO_CHANGE:
this.trigger(g.USER_INFO_CHANGE)
}
}
};
Spotify.Services.Social = function () {
new Spotify.Parsers.Social;
this.getUsers = function (d, g, c, h) {
var b = 0,
a = [],
f = 0;
typeof g === "undefined" ? g = "fast" : g !== "fast" && g !== "complete" && (g = "fast");
for (b = d.length; f < b; ++f) a.push({
uri: "hm://social/decoration/user/" + encodeURIComponent(d[f])
});
this.send(new Spotify.Calls.Hermes({
header: {
uri: "hm://social/decorations/" + g,
method: "GET"
},
isMultiGet: !0,
payload: [{
request: a
}],
responseSchemas: ["social#DecorationData"],
type: "social"
}, c, h))
}
};
Spotify.SourceURLs = {
normal: "https://d3rt1990lpmkn.cloudfront.net/300/",
original: "https://d3rt1990lpmkn.cloudfront.net/unbranded/"
};
Spotify.Services.SongUriResolver = function () {
var d = Spotify.DebuggerJS,
g = new Spotify.Events,
c = this,
h = new Spotify.Parsers.URL,
b, a = !1;
this.IN_CDN = 0;
this.ONLY_ON_STORAGE = 1;
this.RATE_LIMIT_REACHED = 2;
this.TRACK_RESTRICTED = 3;
var f = function (a) {
var b = a.params.trackUri,
f = a.params.callback,
k = a.params.errback,
a = a.params.schema;
d.log("Spotify.Services.SongUriResolver", ["Rate limit is calling again:", b], "corejs");
c.list(b, a, f, k)
}, k = function () {
d.log("Spotify.Services.SongUriResolver", ["Rate limit is disabled"], "corejs");
a = !1
};
this.list = function (f, k, p, q) {
var n = Spotify.Link.fromString(f);
if (this.serviceIsReady) {
if (!(n instanceof Spotify.Link)) return d.error("Spotify.Services.SongUriResolver", ["Invalid arguments"], "corejs"), q(Error("Services:SongUriResolver:list Invalid arguments")), !1;
if (a && b.totalPendingRequests() !== 0) {
n = b.getItemAtIndex(0);
if (n !== null && typeof n !== "undefined") {
var s = new Spotify.Errors.Error([Spotify.Errors.Domains.TRACK_ERROR, Spotify.Errors.Codes.TRACK_REQUEST_RATE_LIMITED, ""]);
n.errback(s)
}
b.addToBucket({
trackUri: f,
schema: k,
callback: p,
errback: q
}, !1)
} else n = new Spotify.Calls.Simple({
method: "track_uri",
payload: ["mp3160", n.id, k],
context: c,
persistent: !0,
retries: 2,
type: "track_uri"
}, function (a) {
if (a.response !== null) {
var b = a.response.type;
if (b === c.IN_CDN) k === "rtmp" ? (b = h.parseRTMPUrl(a.response.uri), a.response.uri = b.file) : b = h.parseHTTPUrl(a.response.uri), a.response.server = b.server, a.response.protocol = b.protocol, p(a.response, 200), d.log("Spotify.Services.SongUriResolver", ["Song can be loaded", a.response], "corejs");
else {
a =
new Spotify.Errors.Error([Spotify.Errors.Domains.TRACK_ERROR, 0, ""]);
a.code = b;
if (b === c.ONLY_ON_STORAGE) a.description = "Song only on storage";
else if (b === c.RATE_LIMIT_REACHED) a.description = "Rate limit reached";
else if (b === c.TRACK_RESTRICTED) a.description = "Track restricted";
a.data = f;
q(a);
d.error("Spotify.Services.SongUriResolver", ["I could not load the song", a], "corejs")
}
} else a = new Spotify.Errors.Error([Spotify.Errors.Domains.TRACK_ERROR, 0, "Response was null"]), a.data = f, q(a), d.error("Spotify.Services.SongUriResolver", ["I could not load the song", a], "corejs")
}, function (k) {
k.data = f;
k.domain === Spotify.Errors.Domains.TRACK_ERROR && k.code === Spotify.Errors.Codes.TRACK_REQUEST_RATE_LIMITED ? (d.warn("Spotify.Services.SongUriResolver", ["Rate limit is enabled"], "corejs"), a = !0, b.start(), b.addToBucket({
trackUri: f,
callback: p,
errback: q
}, !1)) : (k.domain === Spotify.Errors.Domains.TRACK_ERROR && k.code === Spotify.Errors.Codes.TIME_CAP && c.trigger(g.TIME_CAP, k), q(k));
d.error("Spotify.Services.SongUriResolver", ["I could not load the song",
k
], "corejs")
}), c.send(n)
} else d.error("Spotify.Services.SongUriResolver", ["Service is not ready"], "corejs"), q(Error("Services.SongUriResolver:list Service is not ready"))
};
this.initialize = function () {
b = new Spotify.RateLimiter(1E4, 1);
b.bind(g.RATE_LIMIT_CALL, f, this);
b.bind(g.RATE_LIMIT_DISABLED, k, this)
};
this.initialize.call(this)
};
Spotify.Services.AdUriResolver = function () {
var d = Spotify.DebuggerJS,
g = new Spotify.Parsers.URL,
c = this;
this.list = function (h, b, a, f) {
var k = Spotify.Link.fromString(h);
if (this.serviceIsReady) {
if (!(k instanceof Spotify.Link)) return f(new Spotify.Errors.Error([15, 400, "Invalid arguments"])), !1;
(function (k) {
var o = k.response.type;
if (o === 0) b === "rtmp" ? (o = g.parseRTMPUrl(k.response.uri), k.response.uri = o.file) : o = g.parseHTTPUrl(k.response.uri), k.response.server = o.server, k.response.protocol = o.protocol, a(k.response,
200);
else {
k = {
method: "ad_uri",
response: k
};
if (o === c.ONLY_ON_STORAGE) k.response = "Song only on storage";
else if (o === c.RATE_LIMIT_REACHED) k.response = "Rate limit reached";
else if (o === c.TRACK_RESTRICTED) k.response = "Track restricted";
k.adUri = h;
d.error("Spotify.Services.AdUriResolver", ["Error with track", k], "corejs");
f(k)
}
})({
method: "ad_uri",
response: {
type: 0,
uri: b === "rtmp" ? "rtmp://saa23rvd7l5c6.cloudfront.net/cfx/st/mp3-ad/" + k.id : "http://d7zatysqm84hv.cloudfront.net/mp3-ad/" + k.id
}
})
} else f(new Spotify.Errors.Error([15,
503, "AdUriResolver service not ready!"
]))
}
};
Spotify.Services.PreviewsUriResolver = function () {
var d = new Spotify.Parsers.URL;
new Spotify.Events;
this.list = function (g, c, h) {
var b = {}, g = Spotify.Link.fromString(g).id;
c === "rtmp" ? (c = d.parseRTMPUrl("rtmp://soamh0g9lumcr.cloudfront.net/cfx/st/mp3-preview/" + g), b.uri = c.file) : (c = d.parseHTTPUrl("http://d318706lgtcm8e.cloudfront.net/mp3-preview/" + g), b.uri = "http://d318706lgtcm8e.cloudfront.net/mp3-preview/" + g);
b.server = c.server;
b.protocol = c.protocol;
b.lid = "";
b.type = 0;
h(b)
}
};
Spotify.Services.AdChooser = function () {
Spotify.EventTarget.call(this);
var d = Spotify.DebuggerJS,
g = this,
c = new Spotify.Parsers.AdChooser,
h = new Spotify.Parsers.AdMetadata,
b, a = [],
f, k = new Spotify.Events,
m = !1,
o = null,
p = null,
q = 0,
n = null,
s = null,
t = null,
u = [0, 60],
w = 35,
v = 0,
A = 0,
x = 600,
F = 0,
G = [],
B = {}, E = [],
H = null,
I = null;
this.serviceIsReady = !1;
var K = function (a) {
d.error("Spotify.Services.AdChooser", ["AdChooser Error.. " + ["Domain: " + a.domain, "Code: " + a.code, "Description: " + a.description, "Data: " + a.data].join(",")], "corejs")
},
L = function (a, b) {
if (typeof a === "function" && typeof b === "function") {
var k = E.slice(0);
k.slice(0, 1021);
var c = [0, 1, k.length];
c.push.apply(c, k);
try {
f.rpc("ads", c, a, b, this)
} catch (m) {
R({
serverError: !0
}), K(new Spotify.Errors.Error([Spotify.Errors.Codes.ADS_ERROR, Spotify.Errors.Codes.ADS_SERVER_ERROR, "Exception thrown communicating with ad server", {
extra: m
}]))
}
} else K(new Spotify.Errors.Error([Spotify.Errors.Codes.ADS_ERROR, Spotify.Errors.Codes.ADS_SERVER_ERROR, "Invalid callbacks specified for _retrieveAudioAdsFromServer", {
extra: e
}]))
}, N = function (a) {
var b = null;
R();
z(function (a) {
a = a.response;
parseInt(a) > 0 ? F = O() - a : K(new Spotify.Errors.Error([Spotify.Errors.Codes.ADS_ERROR, Spotify.Errors.Codes.ADS_SERVER_ERROR, "Invalid server time specified", {
extra: e
}]))
}, function (a) {
K(new Spotify.Errors.Error([Spotify.Errors.Codes.ADS_ERROR, Spotify.Errors.Codes.ADS_SERVER_ERROR, "Exception thrown retrieving server time", {
extra: a
}]))
});
b = c.parseServerResponse(a.response);
return C(b)
}, M = function (a, b, k) {
if (typeof b === "function" && typeof k ===
"function") {
a = [a];
try {
f.rpc("get_ad", a, b, k, this)
} catch (c) {
K(new Spotify.Errors.Error([Spotify.Errors.Codes.ADS_ERROR, Spotify.Errors.Codes.ADS_SERVER_ERROR, "Exception thrown communicating with ad metadata server", {
extra: c
}]))
}
} else K(new Spotify.Errors.Error([Spotify.Errors.Codes.ADS_ERROR, Spotify.Errors.Codes.ADS_SERVER_ERROR, "Invalid callbacks specified for _retrieveAudioAdMetadataFromServer", {
extra: e
}]))
}, z = function (a, b) {
typeof a === "function" && typeof b === "function" ? f.rpc("time", [0], a, b, this) : K(new Spotify.Errors.Error([Spotify.Errors.Codes.ADS_ERROR,
Spotify.Errors.Codes.ADS_SERVER_ERROR, "Invalid callbacks for retrieveAdServerTime"
]))
}, C = function (a) {
var b = parseInt(a["@attributes"].version, 10) | 0,
f = null,
k = null,
m = f = null,
d = null;
if (b === 0) K(new Spotify.Errors.Error([Spotify.Errors.Codes.ADS_ERROR, Spotify.Errors.Codes.ADS_SERVER_ERROR, "Missing version attribute from audio queue data structure", {
extra: e
}]));
else if (f = c["parseAudioAdsVersion" + b], typeof f === "function") {
f = f(a);
a = parseInt(f["audio-ad-break"].length);
try {
w = a, I.setItem("defaultAdBreakLength",
w)
} catch (h) {
K(new Spotify.Errors.Error([Spotify.Errors.Codes.ADS_ERROR, Spotify.Errors.Codes.ADS_SERVER_ERROR, "Unable to set audio ad break length", {
extra: h
}]))
}
a = parseInt(f["audio-ad-break"].time_between);
try {
x = a, I.setItem("timeBetweenAdBreak", x)
} catch (g) {
K(new Spotify.Errors.Error([Spotify.Errors.Codes.ADS_ERROR, Spotify.Errors.Codes.ADS_SERVER_ERROR, "Unable to set audio ad break time between", {
extra: g
}]))
}
if (typeof (f.AdQueueEntry !== "undefined" && f.AdQueueEntry.length > 0)) {
for (m = 0, d = f.AdQueueEntry.length; m <
d; m += 1) k = f.AdQueueEntry[m], G.push(k), typeof B[k.ad_id] === "undefined" && J(k.ad_id);
y();
I.setItem("audioQueue", JSON.stringify(G))
} else R({
serverError: !0
}), K(new Spotify.Errors.Error([Spotify.Errors.Codes.ADS_ERROR, Spotify.Errors.Codes.ADS_SERVER_ERROR, "No ads received from the ad server"]))
} else K(new Spotify.Errors.Error([Spotify.Errors.Codes.ADS_ERROR, Spotify.Errors.Codes.ADS_SERVER_ERROR, "No parser exists for audio queue version " + b]))
}, y = function (a) {
try {
typeof a === "undefined" ? G.sort(function (a, b) {
return b.priority -
a.priority
}) : G.sort(a)
} catch (b) {
K(new Spotify.Errors.Error([Spotify.Errors.Codes.ADS_ERROR, Spotify.Errors.Codes.ADS_SERVER_ERROR, "Unable to prioritize ad queue", {
extra: b
}]))
}
}, D = function (a) {
try {
E.indexOf(a) === -1 && (E.push(a), I.setItem("forbiddenAds", JSON.stringify(E)))
} catch (b) {
K(new Spotify.Errors.Error([Spotify.Errors.Codes.ADS_ERROR, Spotify.Errors.Codes.ADS_SERVER_ERROR, "Unable to add forbidden ad", {
extra: b
}]))
}
}, P = function (a) {
try {
v += a, v > w * 2 && (v = w * 2), I.setItem("audioAdBreakAvailableTime", v)
} catch (b) {
K(new Spotify.Errors.Error([Spotify.Errors.Codes.ADS_ERROR,
Spotify.Errors.Codes.ADS_SERVER_ERROR, "Unable to set audio ad break available time", {
extra: b
}
]))
}
}, O = function () {
return Math.round((new Date).getTime() / 1E3)
}, R = function (a) {
var b = !1,
f = O(),
k = Math.floor(Math.random() * u[1] + u[0]);
typeof a !== "undefined" && a.serverError === !0 && (b = !0);
A = b === !1 ? f + 600 + k : f + 3600 + k;
I.setItem("timeOfNextAdServerRequest", A)
}, T = function (a) {
var b = [],
f = B[a.ad_id],
k = O() + F,
c = {
max_campaign_repeats_within: function (b, f) {
var c = k - b,
m = [],
d = a.campaign_id,
h = null;
for (h in B) B.hasOwnProperty(h) &&
B[h].campaign_id === d && m.concat(B[h].event_history.map(function (a) {
if (a.event === "impression" && a.timestamp >= c) return a
}));
return m.length < f
},
max_repeats_within: function (a, b) {
var c = k - a;
return f.event_history.map(function (a) {
if (a.event === "impression" && a.timestamp >= c) return a
}).length < b
},
max_attempts_within: function (a, b) {
var c = k - a;
return f.event_history.map(function (a) {
if (a.event === "attempt" && a.timestamp >= c) return a
}).length < b
},
max_clicks_within: function (a, b) {
var c = k - a;
return f.event_history.map(function (a) {
if (a.event ===
"click" && a.timestamp >= c) return a
}).length < b
}
};
if (f.rules.length > 0)
for (r in f.rules)
if (f.rules.hasOwnProperty(r)) {
var m = f.rules[r];
b.push(c[m.type](parseInt(m.interval), parseInt(m.times)))
}
return b.indexOf(!1) === -1
}, S = function () {
try {
var a = [],
b = null,
f = null,
k = null;
for (f = 0, k = G.length; f < k; f += 1) b = G[f], b.start_time_latest <= O() + F ? (d.log("Spotify.Services.AdChooser", ["Removing expired ad", result], "corejs"), D(b.ad_id)) : T(b) === !1 ? (d.log("Spotify.Services.AdChooser", ["Removing ad with expired rules"], "corejs"),
D(b.ad_id)) : a.push(b);
G = a;
I.setItem("audioQueue", JSON.stringify(G));
return G.length - a.length
} catch (c) {
K(new Spotify.Errors.Error([Spotify.Errors.Codes.ADS_ERROR, Spotify.Errors.Codes.ADS_SERVER_ERROR, "Unable to clear invalid ads in audio ad queue", {
extra: c
}]))
}
}, J = function (a, b) {
var f;
a: {
var k = f = null,
c = null;
for (f = 0, k = G.length; f < k; f += 1)
if (c = G[f], c.ad_id === a) {
f = c;
break a
}
f = null
}
f !== null ? (typeof B[a] === "undefined" && (B[a] = {
campaign_id: f.campaign_id,
expiry_time: f.campaign_expiry,
rules: f.rules,
event_history: []
}),
typeof b !== "undefined" && B[a].event_history.push({
timestamp: O() + F,
event: b
}), I.setItem("adHistory", JSON.stringify(B))) : K(new Spotify.Errors.Error([Spotify.Errors.Codes.ADS_ERROR, Spotify.Errors.Codes.ADS_SERVER_ERROR, "Unable to locate ad queue entry", {
extra: b
}]))
}, V = function (a, b) {
var f;
f = a.split("spotify:ad:")[1];
f = X(f);
var k = null;
if (f === null) K(new Spotify.Errors.Error([Spotify.Errors.Codes.ADS_ERROR, Spotify.Errors.Codes.ADS_NOT_FOUND, "Unable to locate ad to record ad event", {
extra: a
}]));
else {
a: {
var c =
k = null,
m = null;
for (k = 0, c = G.length; k < c; k += 1)
if (m = G[k], m.ad_id === f.ad_id) break a;
k = null
}
k === null && K(new Spotify.Errors.Error([Spotify.Errors.Codes.ADS_ERROR, Spotify.Errors.Codes.ADS_NOT_FOUND, "Unable to locate ad queue index", {
extra: f
}]));
switch (b) {
case "click":
G[k].has_been_clicked = !0;
J(f.ad_id, "click");
break;
case "attempt":
J(f.ad_id, "attempt");
break;
case "impression":
G[k].has_been_played = !0;
G[k].adPlayCount += 1;
G[k].campaignPlayCount += 1;
J(f.ad_id, "impression");
break;
default:
K(new Spotify.Errors.Error([Spotify.Errors.Codes.ADS_ERROR,
Spotify.Errors.Codes.ADS_SERVER_ERROR, "Invalid ad event", {
extra: b
}
]))
}
}
}, W = function (a) {
V(a.params.adUri, a.params.type)
}, Y = function () {
m === !1 && (o = setInterval(function () {
m = !0;
t.isPlaying === !0 && t.isAd === !1 && q++
}, 1E3), p = setInterval(function () {
I.setItem("streamTimeSinceLastAdBreak", q);
d.log("Spotify.Services.AdChooser", ["Stream time: ", q], "corejs")
}, 1E4))
}, Z = function () {
clearInterval(o);
clearInterval(p);
m = !1
}, U = function (f) {
f = b.getPlayerById(f.params.id);
f.bind(k.PLAYING, Y, g);
f.bind(k.PAUSED, Z, g);
a.push(f)
},
Q = function (a) {
g.trigger(a.type, a.params)
}, X = function (a) {
var b = null,
f = null,
k = null;
for (b = 0, f = G.length; b < f; b += 1)
if (k = G[b], k.file_id === a) return k;
return null
};
this.onReady = function (a, b) {
this.serviceIsReady ? a.call(b) : this.bind(k.READY, a, b)
};
this.recordAdEvent = function (a, b) {
V(a, b)
};
this.getNextAd = function () {
var a = null,
b = null;
var a = Object.keys(B),
f;
try {
for (var b = 0, k = a.length; b < k; b++)(f = B[a[b]]) && f.expiry_time <= O() + F && (f.event_history = []);
I.setItem(_AD_HISTORY_KEY, JSON.stringify(B))
} catch (c) {
K(new Spotify.Errors.Error([Spotify.Errors.Codes.ADS_ERROR,
Spotify.Errors.Codes.ADS_SERVER_ERROR, "Unable to purge expired ad history", {
extra: c
}
]))
}
if (q >= x && t.isAd === !1) {
d.log("Spotify.Services.AdChooser", ["Injecting ad!"], "corejs");
P(w);
f = [];
var k = !1,
m = b = a = null;
S();
for (y(); v > 0 && k === !1;)
for (a = 0, b = G.length, k = !0; a < b; a += 1) m = G[a], m.duration < v && (f.push(m), P(m.duration * -1), k = !1);
a = f;
if (a.length > 0) s.setIntercept(H), b = h.toTrackMetadata(a[0]), H.appendWithMeta("spotify:ad:" + a[0].file_id, b), H.setOwner(b.artists[0].uri), s.intercept(), t.ad = a[0]
} else d.log("Spotify.Services.AdChooser", [x - q + " seconds left until ad..."], "corejs")
};
this.lookup = function (a, b) {
var f = [],
k = null,
m = null;
Spotify.Utils.isArray(a) && a.length === 1 ? (m = Spotify.Link.fromString(a[0]), k = X(m.id), k !== null ? (f.push(h.toTrackMetadata(k)), b(f, 200)) : M(m.id, function (a) {
var a = c.parseServerResponse(a.response),
k = parseInt(a["@attributes"].version, 10) | 0,
a = (0, c["parseAudioAdsVersion" + k])(a);
f.push(h.toTrackMetadata(a.AdQueueEntry[0]));
b(f, 200)
}, function (a) {
K(new Spotify.Errors.Error([Spotify.Errors.Codes.ADS_ERROR, Spotify.Errors.Codes.ADS_SERVER_ERROR,
a
]))
})) : K(new Spotify.Errors.Error([Spotify.Errors.Codes.ADS_ERROR, Spotify.Errors.Codes.ADS_NOT_FOUND, "Array does not contain any items!"]))
};
this.maybeRetrieveAds = function () {
A <= O() && (d.log("Spotify.Services.AdChooser", ["Retrieving ads from server."], "corejs"), L(N, function () {
R({
serverError: !0
})
}))
};
this.init = function (a, c, m) {
f = a;
b = c;
b.bind(k.PLAYER_CREATED, U, g);
b.bind(k.RECORD_AD_EVENT, W, g);
b.onReady(function () {
t = c.getPlayerAtIndex(0);
m.onReady(function () {
m.getUserInfo(function (a) {
I = new Spotify.Cache.PackageStore({
storageKey: Spotify.Utils.Base64.encode(a.user +
"-" + a.catalogue)
});
I.getItem("timeBetweenAdBreak") !== null && (x = parseInt(I.getItem("timeBetweenAdBreak"), 10));
I.getItem("defaultAdBreakLength") !== null && (w = parseInt(I.getItem("defaultAdBreakLength"), 10));
I.getItem("timeOfNextAdServerRequest") !== null && (A = parseInt(I.getItem("timeOfNextAdServerRequest"), 10));
I.getItem("streamTimeSinceLastAdBreak") !== null && (q = parseInt(I.getItem("streamTimeSinceLastAdBreak"), 0));
I.getItem("audioQueue") !== null && (G = JSON.parse(I.getItem("audioQueue")));
I.getItem("adHistory") !==
null && (B = JSON.parse(I.getItem("adHistory")));
I.getItem("forbiddenAds") !== null && (E = JSON.parse(I.getItem("forbiddenAds")));
S();
g.maybeRetrieveAds();
g.serviceIsReady = !0;
g.trigger(k.READY)
}, function (a) {
K(new Spotify.Errors.Error([Spotify.Errors.Codes.ADS_ERROR, Spotify.Errors.Codes.ADS_SERVER_ERROR, "Exception thrown gathering user info", {
extra: a
}]))
})
}, this)
}, this)
};
this.initializeContext = function (a, b) {
n = a;
s = b;
s.addEvent(k.INTERCEPTED, Q);
H = n.create("spotify:ads");
H.setRule("intercept");
s.addEvents({
beforeContextChange: g.getNextAd,
beforeNext: g.getNextAd,
beforePrevious: g.getNextAd,
ended: function () {
t.trackUri.indexOf("spotify:ad:") > -1 && (q = 0)
}
})
}
};
Spotify.Services.Pubsub = function () {
var d = this,
g = new Spotify.Events,
c = {};
this.subscribe = function (h, b, a, f, k, m, g) {
function p(a) {
k.call(g, a)
}
typeof h === "undefined" || typeof m === "undefined" || typeof f === "undefined" || typeof k === "undefined" || typeof g === "undefined" ? k.call(g, new Spotify.Errors.Error([0, 16, "Not all argments are provided"])) : (Spotify.Utils.isArray(b) || (b = []), Spotify.Utils.isArray(a) || (a = []), this.serviceIsReady ? this.send(new Spotify.Calls.Hermes({
header: {
uri: h,
method: "SUB"
},
payload: b,
payloadSchemas: a,
responseSchemas: [],
type: "pubsub",
persistent: !1,
bypassCache: !0
}, function (a) {
var b = d.getProtobufMsgParser("pubsub", "Subscription"),
k = [];
if (a) {
for (var h = !1, u = 0; u < a.length; ++u) {
var w = b.parseFromStringSync(a[u]);
if (w.status_code === 200) h = w.uri, k.push(h), typeof c[h] === "undefined" && (c[h] = []), c[h].push({
callback: m,
context: g,
uri: h,
arguments: []
}), h = !0
}
if (!h) {
p();
return
}
}
f.call(g, k)
}, p)) : k.call(g, new Spotify.Errors.Error([13, 503, "Suggest service not ready!"])))
};
this.onNotify = function (d) {
switch (d.type) {
case g.HERMES_B64_MESSAGE:
var b =
Spotify.Hermes.Header.parseFromStringSync(Spotify.Utils.Base64.decode(d.params[2]));
if (b) {
var a = c[b.uri],
f;
if (b.status_code === 200)
for (var k = 0, m = a.length; k < m; k += 1) f = a[k], f.callback.call(f.context, d.params);
else {
k = 0;
for (m = a.length; k < m; k += 1) f = a[k], f.errorCallback.call(f.context, b)
}
}
}
}
};
Spotify.Services.Presence = function () {
var d = Spotify.DebuggerJS,
g = this,
c = new Spotify.Events,
h = {
PLAYLIST_PUBLISHED: {
name: "playlist_published",
id: 1,
decorator: function (a, b) {
a.item_uri = b.uri
}
},
PLAYLIST_TRACK_ADDED: {
name: "playlist_track_added",
id: 2,
decorator: function (a, b) {
a.item_uri = b.playlist_uri;
a.context_uri = b.track_uri
}
},
TRACK_FINISHED_PLAYING: {
name: "track_finished_playing",
id: 3,
decorator: function (a, b) {
a.item_uri = b.uri;
a.context_uri = b.context_uri;
a.referrer_uri = b.referrer_uri
}
},
FAVORITE_APP_ADDED: {
name: "favorite_app_added",
id: 4,
decorator: function (a, b) {
a.item_uri = b.app_uri
}
},
TRACK_STARTED_PLAYING: {
name: "track_started_playing",
id: 5,
decorator: function (a, b) {
a.item_uri = b.uri;
a.context_uri = b.context_uri;
a.referrer_uri = b.referrer_uri
}
},
URI_SHARED: {
name: "uri_shared",
id: 6,
decorator: function (a, b) {
a.item_uri = b.uri;
a.message = b.message
}
},
ARTIST_FOLLOWED: {
name: "artist_followed",
id: 7,
decorator: function (a, b) {
a.item_uri = b.uri;
a.item_name = b.artist_name;
a.item_image = b.artist_cover_uri
}
},
GENERIC: {
name: "generic",
id: 11,
decorator: function (a,
b) {
a.type = b.type;
a.timestamp = b.timestamp;
a.item_uri = b.item_uri;
a.item_name = b.item_name;
a.item_image = b.item_image;
a.context_uri = b.context_uri;
a.context_name = b.context_name;
a.context_image = b.context_image;
a.referrer_uri = b.referrer_uri;
a.referrer_name = b.referrer_name;
a.referrer_image = b.referrer_image;
a.message = b.message;
a.device_information = b.device_information
}
}
}, b = function (a) {
a.length > 0 && (a = g.getProtobufMsgParser("presence", "State").parseFromStringSync(Spotify.Utils.Base64.decode(a[3])), g.trigger(c.NOTIFICATION,
a))
}, a = function (a) {
d.log("Spotify.Services.Presence", ["Broadcast success", a], "corejs")
}, f = function (a) {
d.error("Spotify.Services.Presence", ["Broadcast error", a], "corejs")
}, k = function (a) {
d.error("Spotify.Services.Presence", ["Statuses error", a], "corejs")
}, m = function (b, k) {
g.services.user.getUserInfo(function (c) {
c = new Spotify.Calls.Hermes({
header: {
uri: "hm://presence/user/" + encodeURIComponent(c.user),
method: "SET"
},
payload: [b],
payloadSchemas: ["presence#State"],
responseSchemas: [],
type: "Presence",
bypassCache: !1,
persistent: !1
}, k || a, f);
g.send(c)
}, f)
}, o = function (a, b) {
var f = new Spotify.Calls.Hermes({
header: {
uri: "hm://presence/user/",
method: "GET"
},
payload: [a],
payloadSchemas: [],
responseSchemas: ["presence#State"],
type: "Presence",
bypassCache: !1,
persistent: !1
}, function (f, k) {
var c = [],
m = f[0];
if (!m || typeof m !== "object") b([]);
else {
for (var d in m)
if (m.hasOwnProperty(d)) {
var g = m[d],
o = h[d.toUpperCase()],
n = {
timestamp: g.timestamp,
type: o.id,
username: a
};
o.decorator(n, g);
n.device_information || c.push(n)
}
b(c, k)
}
}, k);
g.send(f)
};
this.subscribe = function (a, f, k, c) {
this.serviceIsReady ? typeof a === "undefined" ? k.call(c, new Spotify.Errors.Error([0, 16, "Not all argments are provided"])) : Spotify.Utils.isArray(a) ? this.services.pubsub.subscribe("hm://presence/user/", a, [], f, k, b, g) : k.call(c, new Spotify.Errors.Error([0, 16, "Users arguments must be an array"])) : k.call(c, new Spotify.Errors.Error([13, 503, "Presence service not ready!"]))
};
this.broadcastPlaylistPublished = function (a, b) {
var f = {
generic: {
type: h.PLAYLIST_PUBLISHED.id,
item_uri: a,
timestamp: (new Date).getTime() / 1E3
}
};
m(f, b)
};
this.broadcastTrackAdded = function (a, b, f) {
a = {
generic: {
type: h.PLAYLIST_TRACK_ADDED.id,
context_uri: a,
item_uri: b,
timestamp: (new Date).getTime() / 1E3
}
};
m(a, f)
};
this.broadcastTrackStartedPlaying = function (a, b, f, k) {
a = {
generic: {
type: h.TRACK_STARTED_PLAYING.id,
item_uri: a,
context_uri: b,
referrer_uri: f,
timestamp: (new Date).getTime() / 1E3
}
};
m(a, k)
};
this.broadcastTrackFinishedPlaying = function (a, b, f, k) {
a = {
generic: {
type: h.TRACK_FINISHED_PLAYING.id,
item_uri: a,
context_uri: b,
referrer_uri: f,
timestamp: (new Date).getTime() / 1E3
}
};
m(a, k)
};
this.broadcastFavoriteAppAdded = function (a, b) {
var f = {
generic: {
type: h.FAVORITE_APP_ADDED.id,
item_uri: a,
timestamp: (new Date).getTime() / 1E3
}
};
m(f, b)
};
this.broadcastUriShared = function (a, b, f) {
a = {
generic: {
type: h.URI_SHARED.id,
item_uri: a,
message: b,
timestamp: (new Date).getTime() / 1E3
}
};
m(a, f)
};
this.broadcastArtistFollowed = function (a, b, f, k) {
a = {
generic: {
type: h.ARTIST_FOLLOWED.id,
item_uri: a,
item_name: b,
item_image: f,
timestamp: (new Date).getTime() / 1E3
}
};
m(a, k)
};
this.getStatuses = function (a, b, f) {
o(a,
b, f)
}
};
Spotify.Services.SocialGraph = function () {
var d = Spotify.DebuggerJS,
g = this,
c = new Spotify.Events,
h = {
subscriptions: {
add: c.RELATIONS_SUBSCRIBE,
remove: c.RELATIONS_UNSUBSCRIBE
},
dismissed: {
add: c.RELATIONS_DISMISS,
remove: c.RELATIONS_UNDISMISS
},
blocked: {
add: c.RELATIONS_BLOCK,
remove: c.RELATIONS_UNBLOCK
}
}, b = function (a, k) {
var k = k || 0,
c = function (c) {
if (c = c[0].users) {
for (var m = 0, d = c.length; m < d; m++) f[a][c[m].username] = m;
c.length === 1E3 && (k += c.length, b(a, k))
}
}, h = function () {
d.error("Spotify.Services.SocialGraph", ["We failed to cache the user's " +
a, arguments
], "corejs")
};
g.services.user.getUserInfo(function (b) {
m(a, b.user, 1E3, k, c, h)
}, h)
}, a = {
subscribers: {},
subscriptions: {},
dismissed: {},
blocked: {}
}, f = {
subscribers: {},
subscriptions: {},
dismissed: {},
blocked: {}
}, k = function (b, f) {
var k = a[b],
c = "";
if (k[f] && k[f].lastResult) c = k[f].lastResult;
return c
}, m = function (b, f, c, m, d, h, o) {
g.services.user.getUserInfo(function (n) {
var q = [];
if (!f) f = n.user;
n = "hm://socialgraph/" + b + "/user/" + encodeURIComponent(f);
o && (n += "/relevant");
var p = [{
count: c,
include_length: !0
}];
o ? p = [] : (q = ["socialgraph#UserListRequest"], p[0].last_result = m === 0 ? "" : k(b, f));
q = new Spotify.Calls.Hermes({
header: {
uri: n,
method: "GET"
},
payload: p,
payloadSchemas: q,
responseSchemas: ["socialgraph#UserListReply"],
type: "socialgraph"
}, function (k, c) {
var m = k[0].users;
if (m) {
var h = f,
m = m[m.length - 1].username,
g = a[b];
g[h] = g[h] || {};
g[h].lastResult = m
}
d(k, c)
}, h);
g.send(q)
}, h)
}, o = function (a, b, f, k) {
g.services.user.getUserInfo(function (c) {
b || (b = [c.user]);
c = new Spotify.Calls.Hermes({
header: {
uri: "hm://socialgraph/" + a + "/count/",
method: "GET"
},
payload: [{
args: b
}],
payloadSchemas: ["socialgraph#StringListRequest"],
responseSchemas: ["socialgraph#CountReply"],
type: "socialgraph"
}, f, k);
g.send(c)
}, k)
}, p = function (a, b, k, c, m) {
m = new Spotify.Calls.Hermes({
header: {
uri: "hm://socialgraph/" + a,
method: b ? "DELETE" : "POST"
},
payload: [{
args: k
}],
payloadSchemas: ["socialgraph#StringListRequest"],
responseSchemas: ["socialgraph#StringListReply"],
type: "socialgraph"
}, function (m, d) {
c(m, d);
var o = h[a];
g.trigger(b ? o.remove : o.add, {
users: k
});
for (var o = 0, n = k.length; o <
n; o++) b ? delete f[a][k[o]] : f[a][k[o]] = o
}, m);
g.send(m)
}, q = function (a) {
for (var a = a.params.uris, b = {}, k = 0, c = a.length; k < c; k++) {
var m = Spotify.Link.fromString(a[k]).username;
m in f.subscriptions || (b[m] = !0)
}
p("subscriptions", !1, Object.keys(b), function () {}, function () {
d.error("Spotify.Services.SocialGraph", ["We failed to subscribe to the following playist owners", b], "corejs")
})
}, n = function (a, b, f, k, c) {
a = "hm://socialgraph/" + a + "/user/" + encodeURIComponent(b) + "/exists";
f = new Spotify.Calls.Hermes({
header: {
uri: a,
method: "GET"
},
payload: [{
args: f
}],
payloadSchemas: ["socialgraph#StringListRequest"],
responseSchemas: ["socialgraph#StringListReply"],
type: "socialgraph"
}, k, c);
g.send(f)
};
this.setup = function () {
this.services.playlist.bind(c.PLAYLIST_SUBSCRIBE, q, this)
};
this.getSubscribers = function (a, b, f, k, c) {
m("subscribers", a, b, f, k, c)
};
this.getRelevantSubscribers = function (a, b, f, k, c) {
m("subscribers", a, b, f, k, c, !0)
};
this.getSubscriptions = function (a, b, f, k, c) {
m("subscriptions", a, b, f, k, c)
};
this.getRelevantSubscriptions = function (a, b, f, k, c) {
m("subscriptions",
a, b, f, k, c, !0)
};
this.getDismissed = function (a, b, f, k, c) {
m("dismissed", a, b, f, k, c)
};
this.getBlocked = function (a, b, f, k, c) {
m("blocked", a, b, f, k, c)
};
this.getSubscribersCount = function (a, b, f) {
o("subscribers", a, b, f)
};
this.getSubscriptionsCount = function (a, b, f) {
o("subscriptions", a, b, f)
};
this.subscribeTo = function (a, b, f) {
p("subscriptions", !1, a, b, f)
};
this.unsubscribeFrom = function (a, b, f) {
p("subscriptions", !0, a, b, f)
};
this.dismiss = function (a, b, f) {
p("dismissed", !1, a, b, f)
};
this.undismiss = function (a, b, f) {
p("dismissed", !0,
a, b, f)
};
this.block = function (a, b, f) {
p("blocked", !1, a, b, f)
};
this.unblock = function (a, b, f) {
p("blocked", !0, a, b, f)
};
this.isSubscribed = function (a) {
for (var b = [], k = 0, c = a.length; k < c; k++) b.push(a[k] in f.subscriptions);
return b
};
this.hasSubscribers = function (a, b, f, k) {
n("subscribers", a, b, f, k)
};
this.hasSubscriptions = function (a, b, f, k) {
n("subscriptions", a, b, f, k)
};
this.hasDismissed = function (a, b, f, k) {
n("dismissed", a, b, f, k)
};
this.hasBlocked = function (a, b, f, k) {
n("blocked", a, b, f, k)
};
this.hasHidden = function (a, b, f, k) {
n("hidden",
a, b, f, k)
};
this.preloadCurrentUserRelations = function () {
for (var a in f) b(a)
}
};
Spotify.Services.MergedProfile = function () {
var d = this,
g = function (c, h, b, a) {
d.serviceIsReady ? (c = new Spotify.Calls.Hermes({
header: {
uri: "hm://mergedprofile/mergedprofile/" + c + "/" + encodeURIComponent(h),
method: "GET"
},
payload: [],
payloadSchemas: [],
responseSchemas: ["mergedprofile#MergedProfileReply"],
type: "mergedprofile"
}, function (a) {
for (var k, c = 0, d = a.length; c < d; c += 1) k = a[c], k.artist = typeof k.artistid !== "undefined" ? "spotify:artist:" + k.artistid : null, k.user = typeof k.username !== "undefined" ? Spotify.Link.profileLink(k.username).toURI() :
null, delete k.artistid, delete k.username;
b(a, 200)
}, a), d.send(c)) : a(new Spotify.Errors.Error([13, 503, "MergedProfile service not ready!"]))
};
this.forUser = function (c, d, b) {
g("user", c, d, b)
};
this.forArtist = function (c, d, b) {
g("artist", c, d, b)
}
};
Spotify.Services.Inbox = function () {
this.getInbox = function (d, g, c) {
this.serviceIsReady ? this.services.playlist.list({
uri: Spotify.Link.inboxLink(d.username).toURI(),
offset: d.offset,
total: d.total
}, g, c) : c(new Spotify.Errors.Error([13, 503, "Inbox service not ready!"]))
};
this.addToInbox = function (d, g, c) {
if (this.serviceIsReady)
if (typeof d.items === "undefined") c(new Spotify.Errors.Error([13, 503, "You need to provide at least one item to send"]));
else if (d.recipient)
if (d.sender) {
for (var h = 0, b = d.items.length; h < b; h +=
1) d.items[h].addedBy = d.sender || "";
this.services.playlist.addToPlaylistWithAttributes(Spotify.Link.inboxLink(d.recipient).toURI(), d.items, g, c)
} else c(new Spotify.Errors.Error([13, 503, "You need to provide a sender"]));
else c(new Spotify.Errors.Error([13, 503, "You need to provide a recipient"]));
else c(new Spotify.Errors.Error([13, 503, "Inbox service not ready!"]))
};
this.deleteFromInbox = function (d, g, c) {
if (typeof d.username === "undefined") c(new Spotify.Errors.Error([13, 503, "You need to provide a username"]));
else {
var h = d.offset || 0,
b = d.total || 1;
this.services.playlist.removeFromPlaylist(Spotify.Link.inboxLink(d.username).toURI(), h, b, g, c)
}
};
this.markAsRead = function (d, g, c) {
typeof d.username === "undefined" ? c(new Spotify.Errors.Error([13, 503, "You need to provide a username"])) : typeof d.itemIndex === "undefined" ? c(new Spotify.Errors.Error([13, 503, "You need to provide an index for the item you want to mark as read"])) : this.services.playlist.updateItemAttributes(Spotify.Link.inboxLink(d.username).toURI(), d.itemIndex, {
seen: 1
}, g, c)
}
};
Spotify.InstanceFactory = function (d) {
this.createInstance = d.createInstance;
this.waitReady = d.waitReady || function (d, c) {
if (d.onReady) d.onReady(c.bind(void 0, d));
else c(d)
};
this.destroyInstance = d.destroyInstance || function () {}
};
Spotify.InstanceFactory.fromService = function (d, g) {
return new Spotify.InstanceFactory({
createInstance: function (c) {
var h = new d;
h.init && h.init.apply(h, (g || []).concat(c || []));
return h
},
waitReady: function (c, d) {
if (c.onReady) c.onReady(d.bind(void 0, c));
else d(c)
},
destroyInstance: function (c) {
c.shutdown && c.shutdown()
}
})
};
Spotify.InstanceFactory.fromFactoryMethod = function (d, g, c) {
return new Spotify.InstanceFactory({
createInstance: d,
destroyInstance: g,
waitReady: c
})
};
Spotify.InstanceCache = function (d) {
var g = {}, c = d;
this.reset = function (d, b) {
d && (c = d);
if (!b) {
for (var a in g) {
var f = g[a];
f.factory.destroyInstance(f.instance)
}
g = {}
}
};
this.createAwaitReady = function (c, b, a) {
var f = b.createInstance(c),
c = g[c] = {
instance: f,
factory: b
};
c.factory.waitReady(c.instance, a.bind(void 0, c.instance))
};
this.get = function (d) {
var b = g[d];
if (b) return b.instance;
else if (c) return b = c.createInstance(d), g[d] = {
instance: b,
factory: c
}, b;
else throw "No such key and no default factory specified";
};
this.getAwaitReady =
function (d, b, a) {
var f = g[d];
if (f) f.factory.waitReady(f.instance, b.bind(void 0, f.instance));
else if (c) this.createAwaitReady(d, c, b, a);
else if (a) a("No such key and no default factory specified");
else throw "No such key and no default factory specified";
}
};
Spotify.DependencyObject = function () {
Spotify.EventTarget.call(this);
var d = this,
g = new Spotify.Events;
this.serviceIsReady = !1;
this.onReady = function (c, d) {
this.serviceIsReady ? c.call(d) : this.bind(g.READY, c, d)
};
this.markReady = function () {
d.serviceIsReady = !0;
d.trigger(g.READY)
};
this.dependsOn = function (c, h) {
if (!c || c.length == 0) return d.markReady();
var b = 0,
a = function () {
b++;
b == c.length && (h ? h.length == 0 ? (h(), d.markReady()) : h(function () {
d.markReady()
}) : d.markReady())
};
c.forEach(function (b) {
if (typeof b == "function") b(a);
else b.onReady(a)
})
}
};
Spotify.Services.Collection2Cache = function () {
Spotify.DependencyObject.call(this);
new Spotify.Events;
var d, g, c;
this.init = function (h, b, a) {
c = a;
if (!a) throw "Username must be defined";
g = new Spotify.Protobuf.Schema([], null, null, null);
g.id = "collection2cache";
g.type = "proto";
g.setData(h);
g.encode();
d = b;
this.markReady()
};
this.getTracks = function (h, b, a) {
(new Spotify.Hermes.ProtobufRequest({
uri: "hm://collection-cache/tracks/" + encodeURIComponent(c) + "?union=" + !! h,
method: "GET"
}, [], [], [g.msg("CollectionTracks")])).send(d, function (a) {
b(a[0].track || [])
}, a, !1, !1, "collection2cache")
};
this.getAlbums = function (h, b, a) {
(new Spotify.Hermes.ProtobufRequest({
uri: "hm://collection-cache/albums/" + encodeURIComponent(c) + "?union=" + !! h,
method: "GET"
}, [], [], [g.msg("CollectionAlbums")])).send(d, function (a) {
b(a[0].album || [])
}, a, !1, !1, "collection2cache")
};
this.getArtists = function (h, b, a) {
(new Spotify.Hermes.ProtobufRequest({
uri: "hm://collection-cache/artists/" + encodeURIComponent(c) + "?union=" + !! h,
method: "GET"
}, [], [], [g.msg("CollectionArtists")])).send(d, function (a) {
b(a[0].artist || [])
}, a, !1, !1, "collection2cache")
}
};
Spotify.Services.CollectionStorageImplementation.Backend = function () {
Spotify.DependencyObject.call(this);
var d = this,
g = new Spotify.Events,
c, h, b, a, f = Spotify.DebuggerJS,
k = function (a) {
return a.map(function (a) {
a.type == "TRACK" ? a.uri = Spotify.Link.fromByteString(Spotify.Link.Type.TRACK, a.identifier).toURI() : a.type == "ALBUM" ? a.uri = Spotify.Link.fromByteString(Spotify.Link.Type.ALBUM, a.identifier).toURI() : (f.error("Spotify.Services.CollectionStorageImplementation.Backend", ["Not supported type: ", a.type], "corejs"),
a = void 0);
return a
}).filter(function (a) {
return a
})
}, m = function (a) {
a.length > 0 && (a = b.msg("CollectionItems").parseFromStringSync(Spotify.Utils.Base64.decode(a[3])), a.item && (a = k(a.item), d.trigger(g.CHANGED, {
items: a
})))
}, o = function (b) {
c.subscribe("hm://collection/collection/" + encodeURIComponent(a), [], [], b, function () {}, m, d)
};
this.init = function (f, k, m, d) {
c = f;
a = d;
if (!d) throw "Username must be defined";
b = new Spotify.Protobuf.Schema([], null, null, null);
b.id = "collection2";
b.type = "proto";
b.setData(k);
b.encode();
h = m;
h.bind(g.CONNECTED, function () {
o(function () {})
}, this);
this.dependsOn([f], o)
};
this.get = function (f, c) {
(new Spotify.Hermes.ProtobufRequest({
uri: "hm://collection/collection/" + encodeURIComponent(a) + "?sort=descending",
method: "GET",
content_type: "vnd.spotify/collection-items"
}, [], [], [b.msg("CollectionItems")])).send(h, function (a) {
a = a[0].item || [];
a = k(a);
f(a)
}, c, !1, !1, "collection")
};
this.change = function (f, k, c) {
f.forEach(function (a) {
a.type = "TRACK";
a.identifier = Spotify.Link.fromString(a.uri).idToByteString()
});
(new Spotify.Hermes.ProtobufRequest({
uri: "hm://collection/collection/" + encodeURIComponent(a),
method: "PATCH",
content_type: "vnd.spotify/collection-items"
}, [{
item: f
}], [b.msg("CollectionItems")], [])).send(h, function (a) {
k(a)
}, c, !0, !1, "collection")
}
};
Spotify.Services.CollectionStorageImplementation.Mock = function () {
Spotify.DependencyObject.call(this);
var d = this,
g = {};
[{
uri: "spotify:track:7pYInkuxFsh625wA82Uf8W",
name: "Away From The Sun - 17 Days Acoustic Version"
}, {
uri: "spotify:track:7i6x7pxU92f9Lazp4Y1dbZ",
name: "Warsaw Or The First Breath You Take After You Give Up"
}, {
uri: "spotify:track:7e5B4aloHuniGxtxSV83g0",
name: "Vem"
}, {
uri: "spotify:track:7bTiNxyu4FlHwBes8eG8sE",
name: "Jag tror p?? dig"
}, {
uri: "spotify:track:7KonowmHhdoW6gn0ZNvgOn",
name: "Spinning In Daffodils"
}, {
uri: "spotify:track:7E680BITbk5khHVIE0DrIV",
name: "Sober - Bimbo Jones Radio Edit"
}, {
uri: "spotify:track:7980zwuuUReCHIjSVcItPy",
name: "Big Pimpin' - Live"
}, {
uri: "spotify:track:6pi0NzmQkouL2R5EDIV7YH",
name: "Bonito"
}, {
uri: "spotify:track:6kmewkv1yTxyUD963qiEbQ",
name: "Linger"
}, {
uri: "spotify:track:6ZqvAJ2SBUqscWtqjZr0EA",
name: "Criminal Intent"
}, {
uri: "spotify:track:6T1Xc4BNJO7bkgiEyH7vCm",
name: "For an Angel - Radio Mix '09"
}, {
uri: "spotify:track:65lMlV6eqqFQ9Eskj0f9Me",
name: "Caligulove"
}, {
uri: "spotify:track:62duQFVb51gug9ajR6Qdiz",
name: "Gangsta Rap Made Me Do It"
}, {
uri: "spotify:track:5qXxGJlfiAh0aKCRYHL2V0",
name: "Up Where We Belong"
}, {
uri: "spotify:track:5hIjE1vig7y1rb2LRLgRfp",
name: "The Crying Light"
}, {
uri: "spotify:track:5TTiXxO7SPIYHulRCSyYzR",
name: "Harder Now That It's Over"
}, {
uri: "spotify:track:5NaV3m1KmpygBsCUkaVIK0",
name: "How To Save A Life (made famous by The Fray)"
}, {
uri: "spotify:track:4ni0Vt7dQev9fS1O97a7jw",
name: "Wonderful Tonight"
}, {
uri: "spotify:track:4ibFD6UnSsExXMV0Ptycsq",
name: "Smells Like Teen Spirit (made famous by Nirvana)"
}, {
uri: "spotify:track:4dhAjyKOEc5YPIk6tTY3Q8",
name: "Interlude With Ludes"
}, {
uri: "spotify:track:4VBmMhjrJ1Bu7ebnl0Gbmj",
name: "The Lovers Are Losing"
}, {
uri: "spotify:track:48s2DVrUoICD8B37y6H06g",
name: "Show Me What You Got - Album Version (Edited)"
}, {
uri: "spotify:track:3f5BGbxhywHIV7gVrqtVqI",
name: "Sail Away (made famous by Enya)"
}, {
uri: "spotify:track:3NT4deyIUzzqL63rNHgYNM",
name: "Foolish - Mainstream Edit"
}, {
uri: "spotify:track:3I8dxmjvDQNyiWXMcScsCv",
name: "Secret Smile - Album Edit"
}, {
uri: "spotify:track:3DjPNEk6Yd5xhXs6RGNKNs",
name: "No Diggity"
}, {
uri: "spotify:track:2udjspYLl1PvGV7gERAuxg",
name: "That Ole Devil Called Love - Single Version"
}, {
uri: "spotify:track:2l5k6k0XYdjtZslUibsPeA",
name: "Show Me Heaven"
}, {
uri: "spotify:track:2aRnHc1Q8ydUOSEYo68ztS",
name: "Hot N Cold (Manhattan Clique Remix Radio Edit)"
}, {
uri: "spotify:track:2DemiHqRL0bAa0e3JEnaW8",
name: "Congratulations - Revisited"
}, {
uri: "spotify:track:18HLZDh4NyDHcAn7gwZrb2",
name: "Black Girls (feat. Travis Barker)"
}, {
uri: "spotify:track:15Cl88mjOLGp3uM2Opm5iT",
name: "On The Wings Of Love"
}, {
uri: "spotify:track:0oHKGL4obpVZlFxZb5AeKW",
name: "Include Me Out"
}, {
uri: "spotify:track:7oSwuLOwlCMqTQi30ME0zR",
name: "Unchained Melody"
}, {
uri: "spotify:track:7nNTYx6f54SUPX2GaTUcf7",
name: "5th Avenue Bar"
}].forEach(function (c) {
g[c.uri] = {
uri: c.uri,
starred: !1,
unheard: !0,
added_at: Math.floor(Date.now() / 1E3),
starred_at: Math.floor(Date.now() / 1E3)
}
});
var c = new Spotify.Events;
this.init = function () {
this.markReady()
};
this.get = function (c) {
var b = [],
a;
for (a in g) b.push(g[a]);
c(b)
};
this.change = function (h, b) {
h.forEach(function (a) {
if (a.removed) delete g[a.uri];
else {
if (a.added_at === void 0) a.added_at = Math.floor(Date.now() / 1E3);
g[a.uri] = a
}
});
b();
d.trigger(c.CHANGED, {
items: h
})
}
};
Spotify.Services.CollectionStorageImplementation.CacheAttributes = function () {
Spotify.DependencyObject.call(this);
var d = this,
g = {}, c = new Spotify.Events,
h = function (a) {
var b = [],
m = !1;
a.forEach(function (a) {
var f = g[a.uri];
b.push(f);
if (a.removed) delete g[a.uri], f && (m = !0);
else if (g[a.uri] = a, !f || a.unheard != f.unheard) m = !0
});
m && d.trigger(c.CHANGED, {
items: a,
oldItems: b
})
}, b, a = function (a) {
h(a.params.items)
};
this.init = function (f) {
b = f;
b.bind(c.CHANGED, a);
this.dependsOn([b], function (a) {
b.get(function (b) {
b.forEach(function (a) {
g[a.uri] =
a
});
a()
}, function () {
a()
})
})
};
this.get = function (a) {
var b = [],
c;
for (c in g) b.push(JSON.parse(JSON.stringify(g[c])));
a(b)
};
this.change = function (a, k, c) {
a = a.map(function (a) {
var b = g[a.uri];
if (b) {
if (a.unheard === void 0) a.unheard = b.unheard;
a.added_at = b.added_at
} else {
if (a.unheard === void 0) a.unheard = !0;
if (a.removed === void 0) a.removed = !1;
a.added_at = Math.floor(Date.now() / 1E3)
}
return a
});
h(a);
b.change(a, function () {}, c);
k()
}
};
Spotify.Services.CollectionStorage = function (d, g) {
Spotify.DependencyObject.call(this);
var c = d || {};
c.implementation = c.implementation || "backend";
var h = {}, b;
this.config = function (a) {
c = a;
b.reset(h[c.implementation])
};
this.init = function (a, f) {
h.mock = new Spotify.InstanceFactory({
createInstance: function () {
var a = new Spotify.Services.CollectionStorageImplementation.Mock;
a.init();
var b = new Spotify.Services.CollectionStorageImplementation.CacheAttributes;
b.init(a);
return b
}
});
h.backend = new Spotify.InstanceFactory({
createInstance: function (b) {
var c =
new Spotify.Services.CollectionStorageImplementation.Backend;
c.init(f, g, a, b);
b = new Spotify.Services.CollectionStorageImplementation.CacheAttributes;
b.init(c);
return b
}
});
b = new Spotify.InstanceCache;
this.config(c);
this.markReady()
};
this.getInstance = function (a, f, k) {
b.getAwaitReady(a, function (a) {
f(a)
}, k)
}
};
Spotify.Services.CollectionViewImplementation.CollectionViewForUser = function () {
Spotify.DependencyObject.call(this);
var d = this,
g;
this.init = function (a, f, k, c, d, n, s) {
g = n;
q = new Spotify.Services.Collection2Cache;
q.init(c, d, n);
m = a;
o = k;
this.dependsOn([q, a, f, k], function (a) {
k.bind(h.CHANGE, A);
f.getInstance(n, function (f) {
p = f;
p.bind(h.CHANGED, x);
K(s, a, function () {
b.error("Spotify.Services.CollectionViewImplementation.CollectionViewForUser", ["Load data failed"], "corejs")
})
})
})
};
this.artistsSnapshot = function (a,
b, f, k) {
B("artists", a, b, f, k)
};
this.albumsSnapshot = function (a, b, f, k) {
B("albums", a, b, f, k)
};
this.tracksSnapshot = function (a, b, f, k) {
B("tracks", a, b, f, k)
};
var c = function (b, f, k) {
var c = [];
f.forEach(function (f) {
c.push( !! a[b][f])
});
k(c)
};
this.tracksContains = function (a, b, f) {
c("tracks", a, b, f)
};
this.albumsContains = function (a, b, f) {
c("albums", a, b, f)
};
this.tracksAdd = function (a, b, f) {
s(a, function (k) {
var c = [],
m = [];
a.forEach(function (a) {
c.push({
uri: a,
sources: {
collection: !0,
playlists: {}
}
});
m.push({
uri: a
})
});
w(c, k);
p.change(m,
b, f)
}, f)
};
this.albumsAdd = function (a, b, f) {
m.lookup(a, function (a) {
var k = {};
a.forEach(function (a) {
a && a.disc.forEach(function (a) {
a.track.forEach(function (a) {
a = Spotify.Link.trackLink(a.id).toURI();
k[a] = a
})
})
});
k = Object.keys(k);
d.tracksAdd(k, b, f)
}, f)
};
this.tracksRemove = function (b, f, k) {
s(b, function (c) {
var m = [],
d = [],
h = [];
b.forEach(function (b) {
var f = a.tracks[b];
h.push({
uri: b,
sources: f.sources
});
f.sources.collection && d.push({
uri: b,
removed: !0
});
for (var k in f.sources.playlists) m.push(o.removeFromPlaylistByUri.bind(o,
k, [b]))
});
v(h, c);
d.length > 0 && m.push(p.change.bind(p, d));
F(m, f, k)
}, k)
};
this.albumsRemove = function (b, f, k) {
m.lookup(b, function (b) {
var c = {};
b.forEach(function (b) {
b && b.disc.forEach(function (b) {
b.track.forEach(function (b) {
b = Spotify.Link.trackLink(b.id).toURI();
a.tracks[b] && (c[b] = b)
})
})
});
c = Object.keys(c);
d.tracksRemove(c, f, k)
}, k)
};
this.tracksClear = function (b, f) {
var c = a;
a = {
tracks: {},
albums: {},
artists: {}
};
k = {};
p.get(function (a) {
a = a.map(function (a) {
return {
uri: a.uri,
removed: !0
}
});
a.length == 0 ? b() : p.change(a,
b, f);
a = {
source: "all",
removed: {
artists: {
uris: Object.keys(c.artists),
indices: Object.keys(c.artists).map(function (a, b) {
return b
})
},
albums: {
uris: Object.keys(c.albums),
indices: Object.keys(c.albums).map(function (a, b) {
return b
})
},
tracks: {
uris: Object.keys(c.tracks),
indices: Object.keys(c.tracks).map(function (a, b) {
return b
})
}
}
};
d.trigger(h.CHANGED, a)
}, f)
};
this.getSources = function (b, f, k) {
var c = Spotify.Link.fromString(b);
c.type === Spotify.Link.Type.ALBUM ? m.lookup(b, function (b) {
var k = {
collection: !1,
playlists: {}
};
b.disc.forEach(function (b) {
b.track.forEach(function (b) {
b = Spotify.Link.trackLink(b.id).toURI();
if (b = a.tracks[b]) {
if (b.sources.collection) k.collection = !0;
if (b.sources.playlists)
for (var f in b.sources.playlists) k.playlists[f] = (k.playlists[f] || 0) + b.sources.playlists[f]
}
})
});
f(k)
}, k) : c.type === Spotify.Link.Type.TRACK ? (b = a.tracks[b]) ? f(b.sources) : f({
collection: !1,
playlists: {}
}) : k("Unsupported type: " + c.type)
};
var h = new Spotify.Events,
b = Spotify.DebuggerJS,
a = {
tracks: {},
albums: {},
artists: {}
}, f = {}, k = {}, m, o,
p, q, n = {
tracks: function (a) {
var b = [],
f;
for (f in a) b.push(a[f]);
return b.sort(function (a, b) {
var f = (b.added_at || 0) - (a.added_at || 0);
return f === 0 ? a.uri > b.uri ? 1 : -1 : f > 0 ? 1 : -1
}).map(function (a) {
return a.uri
})
},
albums: function (a) {
var b = [],
f;
for (f in a) b.push(a[f]);
return b.sort(function (a, b) {
return a.artistNames[0] == b.artistNames[0] && a.name === b.name ? a.uri > b.uri ? 1 : -1 : a.artistNames[0] == b.artistNames[0] ? a.name > b.name ? 1 : -1 : a.artistNames[0] > b.artistNames[0] ? 1 : -1
}).map(function (a) {
return a.uri
})
},
artists: function (a) {
var b = [],
f;
for (f in a) b.push(a[f]);
return b.sort(function (a, b) {
return a.name === b.name ? a.uri > b.uri : a.name > b.name ? 1 : -1
}).map(function (a) {
return a.uri
})
}
}, s = function (a, b, f) {
m.lookup(a, function (a) {
var f = {};
a.forEach(function (a) {
f[Spotify.Link.trackLink(a.id).toURI()] = a
});
b(f)
}, f)
}, t = function (a, b) {
return b.map(function (b) {
return a.indexOf(b)
})
}, u = function (a, b) {
var f = {
uris: [],
indices: []
};
t(G(a), b).map(function (a, f) {
return {
index: a,
uri: b[f]
}
}).sort(function (a, b) {
return a.index - b.index
}).map(function (a, b) {
f.uris.push(a.uri);
f.indices.push(a.index - b)
});
return f
}, w = function (b, f) {
k = {};
var c = [];
b.forEach(function (b) {
var k = a.tracks[b.uri];
if (k) {
if (b.sources.collection === !0) k.sources.collection = !0;
for (var m in b.sources.playlists) k.sources.playlists[m] = (k.sources.playlists[m] || 0) + b.sources.playlists[m]
} else a.tracks[b.uri] = k = {
uri: b.uri,
added_at: Math.floor(Date.now() / 1E3),
name: f[b.uri].name,
sources: {
collection: b.sources.collection,
playlists: b.sources.playlists || {}
}
}, c.push(k.uri)
});
if (c.length > 0) {
var m = [],
g = [];
c.forEach(function (b) {
var b =
f[b],
k = Spotify.Link.albumLink(b.album.id).toURI(),
c = a.albums[k];
c || (c = {
uri: k,
name: b.album.name,
artistNames: b.album.artist ? b.album.artist.map(function (a) {
return a.name
}) : [],
count: 0
}, a.albums[k] = c, m.push(k));
c.count++;
k = Spotify.Link.artistLink(b.artist[0].id).toURI();
c = a.artists[k];
c || (c = {
uri: k,
name: b.artist[0].name,
count: 0
}, a.artists[k] = c, g.push(k));
c.count++
});
var o = {
source: "all",
inserted: {
artists: u("artists", g),
albums: u("albums", m),
tracks: u("tracks", c)
}
};
d.trigger(h.CHANGED, o)
}
}, v = function (b, f) {
var c =
k;
k = {};
var m = [];
b.forEach(function (b) {
var f = a.tracks[b.uri];
if (f) {
if (b.sources.collection === !0) f.sources.collection = !1;
for (var k in b.sources.playlists) f.sources.playlists[k] -= b.sources.playlists[k] || 0, f.sources.playlists[k] === 0 && delete f.sources.playlists[k];
!f.sources.collection && Object.keys(f.sources.playlists).length === 0 && (delete a.tracks[f.uri], m.push(f.uri))
}
});
if (m.length > 0) {
var g = [],
o = [];
m.forEach(function (b) {
var b = f[b],
k = Spotify.Link.albumLink(b.album.id).toURI(),
c = a.albums[k];
c && (c.count--,
c.count <= 0 && (delete a.albums[k], g.push(k)));
b = Spotify.Link.artistLink(b.artist[0].id).toURI();
if (k = a.artists[b]) k.count--, k.count <= 0 && (delete a.artists[b], o.push(b))
});
c = {
source: "all",
removed: {
artists: {
uris: o,
indices: t(c.artists || [], o)
},
albums: {
uris: g,
indices: t(c.albums || [], g)
},
tracks: {
uris: m,
indices: t(c.tracks || [], m)
}
}
};
d.trigger(h.CHANGED, c)
}
}, A = function (a) {
var k = f[a.params.uri] || a.params.localRevision;
f[a.params.uri] = a.params.revision;
o.getChangesBetweenRevisionAndHead(a.params.uri, k, function (k) {
var c =
k.operations;
if (c) f[a.params.uri] = k.revision, c.forEach(function (f) {
var k = [];
if (f.kind == "ADD") {
var c = [];
f.add.items.forEach(function (b) {
if (Spotify.Link.fromString(b.uri).type == Spotify.Link.Type.TRACK) {
var f = {
uri: b.uri,
sources: {
collection: !1,
playlists: {}
}
};
f.sources.playlists[a.params.uri] = 1;
c.push(f);
k.push(b.uri)
}
});
s(k, function (a) {
w(c, a)
}, function () {
b.error("Spotify.Services.CollectionViewImplementation.CollectionViewForUser", ["Playlist changed: Can't load metadata"], "corejs")
})
} else if (f.kind ==
"REM") {
var m = [];
f.rem.items.forEach(function (b) {
if (Spotify.Link.fromString(b.uri).type == Spotify.Link.Type.TRACK) {
var f = {
uri: b.uri,
sources: {
playlists: {}
}
};
f.sources.playlists[a.params.uri] = 1;
m.push(f);
k.push(b.uri)
}
});
s(k, function (a) {
v(m, a)
}, function () {
b.error("Spotify.Services.CollectionViewImplementation.CollectionViewForUser", ["Playlist changed: Can't load metadata"], "corejs")
})
}
})
}, function () {
b.error("Spotify.Services.CollectionViewImplementation.CollectionViewForUser", ["Playlist changed: Can't get changes"],
"corejs")
})
}, x = function (a) {
var f = [],
k = [];
a.params.items.forEach(function (b, c) {
b.type == "TRACK" && (b.removed ? k.push(b.uri) : a.params.oldItems[c] === void 0 && f.push(b.uri))
});
if (f.length > 0) {
var c = f.map(function (a) {
return {
uri: a,
sources: {
collection: !0,
playlists: {}
}
}
});
s(f, function (a) {
w(c, a)
}, function () {
b.error("Spotify.Services.CollectionViewImplementation.CollectionViewForUser", ["Collection changed: Can't load metadata"], "corejs")
})
}
if (k.length > 0) {
var m = k.map(function (a) {
return {
uri: a,
sources: {
collection: !0,
playlists: {}
}
}
});
s(k, function (a) {
v(m, a)
}, function () {
b.error("Spotify.Services.CollectionViewImplementation.CollectionViewForUser", ["Collection changed: Can't load metadata"], "corejs")
})
}
}, F = function (a, b, f) {
var k = 0,
c = Array(a.length);
a.forEach(function (m, d) {
m(function (f) {
c[d] = f;
k++;
k == a.length && b(c)
}, function () {
f()
})
})
}, G = function (b) {
k[b] || (k[b] = n[b](a[b]));
return k[b]
}, B = function (a, b, f, k) {
a = G(a);
b = b >= 0 && f >= 0 ? a.slice(b, b + f) : b >= 0 ? a.slice(b) : a;
k(b, a.length)
}, E = function (a, b, f) {
q.getTracks(a, function (a) {
var f = {}, k = {};
a.forEach(function (a) {
var b = {};
b.uri = Spotify.Link.fromByteString(Spotify.Link.Type.TRACK, a.identifier).toURI();
b.added_at = a.added_at;
b.name = a.name;
b.sources = {
collection: a.in_collection === void 0 ? !0 : a.in_collection,
playlists: {}
};
a.playlists && a.playlists.forEach(function (a) {
var f = Spotify.Link.fromByteString(Spotify.Link.Type.PLAYLIST, a.identifier, {
username: g
}).toURI();
b.sources.playlists[f] = a.count || 1;
k[f] = a.revision
});
f[b.uri] = b
});
b(f, k)
}, f)
}, H = function (a, b, f) {
q.getAlbums(a, function (a) {
var f = {};
a.forEach(function (a) {
var b = {};
b.uri = Spotify.Link.fromByteString(Spotify.Link.Type.ALBUM, a.identifier).toURI();
b.count = a.track_count;
b.artistNames = a.artist_names;
b.name = a.name;
f[b.uri] = b
});
b(f)
}, f)
}, I = function (a, b, f) {
q.getArtists(a, function (a) {
var f = {};
a.forEach(function (a) {
var b = {};
b.uri = Spotify.Link.fromByteString(Spotify.Link.Type.ARTIST, a.identifier).toURI();
b.count = a.track_count;
b.name = a.name;
f[b.uri] = b
});
b(f)
}, f)
}, K = function (b, k, c) {
F([
function (k) {
E(b, function (b, c) {
a.tracks = b;
f = c;
k()
}, c)
},
function (f) {
H(b, function (b) {
a.albums = b;
f()
}, c)
},
function (f) {
I(b, function (b) {
a.artists = b;
f()
}, c)
}
], k, c)
}
};
Spotify.Services.CollectionView = function (d) {
Spotify.DependencyObject.call(this);
var g = d || {};
if (g.union === void 0) g.union = !0;
var c, h, b, a, f;
this.config = function (b) {
g = b;
f.reset(a)
};
this.init = function (k, m, d, p, q, n) {
c = k;
h = m;
b = d;
a = Spotify.InstanceFactory.fromFactoryMethod(function (a) {
var b = new Spotify.Services.CollectionViewImplementation.CollectionViewForUser;
b.init(m, k, d, n, q, a, g.union);
return b
});
f = new Spotify.InstanceCache;
this.config(g);
this.dependsOn([c, h, b, p], function (a) {
p.getUserInfo(function (b) {
f.getAwaitReady(b.user,
function () {}, function () {
throw arguments;
});
a()
})
})
};
this.getInstance = function (a, b, c) {
f.getAwaitReady(a, function (a) {
b(a)
}, c)
}
};
Spotify.Services.CollectionUnplayed = function () {
Spotify.DependencyObject.call(this);
var d = this,
g, c, h = {}, b, a, f, k, m = new Spotify.Events,
o = function () {
var a = k.getState().track.uri,
b;
b = a ? Spotify.Link.fromString(a).type == Spotify.Link.Type.TRACK ? !0 : !1 : !1;
if (b) d.onReady(function () {
g.get(function (b) {
for (var f, k = 0, c = b.length; k < c; k++)
if (b[k].uri === a) {
f = b[k];
break
}
f ? f.unheard !== !1 && g.change([{
uri: a,
unheard: !1
}], function () {}) : h[a] = !0
})
})
}, p = function (b) {
g.get(function (k) {
a = k;
f = {};
for (k = 0; k < a.length; k++) f[a[k].uri] =
a[k].unheard;
b()
})
}, q = function (a) {
var b = a.params.oldItems,
f = [],
k = !1,
c = {
inserted: [],
removed: []
};
a.params.items.forEach(function (a, m) {
var d = !b[m],
g = d || a.unheard != b[m].unheard;
if (a.unheard && h[a.uri]) a.unheard = !1, delete h[a.uri], f.push({
uri: a.uri,
unheard: !1
});
else if (d || g) k = !0, d ? c.inserted.push(a.uri) : g && c[a.unheard ? "inserted" : "removed"].push(a.uri)
});
f.length > 0 && g.change(f, function () {});
k && p(function () {
d.trigger(m.CHANGED, {
insertedItems: c.inserted,
removedItems: c.removed
})
})
};
this.init = function (a, f) {
c =
f;
this.dependsOn([a, c], function (f) {
c.getUserInfo(function (k) {
b = k.user;
a.getInstance(b, function (a) {
g = a;
a.bind(m.CHANGED, q);
p(f)
})
})
})
};
this.initializeContext = function (a) {
k = a;
k.addEvent("play", o)
};
this.isUnplayed = function (a, k, c) {
if (a != b) throw Error("Only supported for current user");
var m = [];
k.forEach(function (a) {
m.push(f[a])
});
c(m)
}
};
Spotify.Services.Facebook = function () {
function d(b) {
return function (a) {
a = h.parseCredential(a);
b(a)
}
}
var g = this,
c = Spotify.DebuggerJS,
h = new Spotify.Parsers.Facebook;
this.enable = function (b, a, f) {
this.services.user.getUserInfo(function (k) {
k = new Spotify.Calls.Hermes({
header: {
uri: "hm://facebook/user/" + encodeURIComponent(k.user),
method: "CREATE"
},
payload: [h.makeCredential(null, b)],
payloadSchemas: ["facebook#EnableRequest"],
responseSchemas: ["facebook#EnableReply"],
type: "facebook",
bypassCache: !0,
persistent: !1
},
d(a), f);
g._sendRetry(k)
}, f)
};
this.disable = function (b, a, f, k) {
this.services.user.getUserInfo(function (c) {
c = new Spotify.Calls.Hermes({
header: {
uri: "hm://facebook/user/" + encodeURIComponent(c.user),
method: "DELETE"
},
payload: [h.makeCredential(b, a)],
payloadSchemas: ["facebook#DisableRequest"],
responseSchemas: [],
type: "facebook",
bypassCache: !0,
persistent: !1
}, f, k);
g._sendRetry(c)
}, k)
};
this.getState = function (b, a, f, k) {
this.services.user.getUserInfo(function (c) {
c = new Spotify.Calls.Hermes({
header: {
uri: "hm://facebook/user/" + encodeURIComponent(c.user),
method: "GET"
},
payload: [h.makeCredential(b, a)],
payloadSchemas: ["facebook#UserState"],
responseSchemas: ["facebook#UserState"],
type: "facebook",
bypassCache: !0,
persistent: !1
}, d(f), k);
g._sendRetry(c)
}, k)
};
this.updateState = function (b, a, f, k) {
this.services.user.getUserInfo(function (c) {
c = new Spotify.Calls.Hermes({
header: {
uri: "hm://facebook/user/" + encodeURIComponent(c.user),
method: "GET"
},
payload: [h.makeCredential(b, a)],
payloadSchemas: ["facebook#UpdateUserStateRequest"],
responseSchemas: ["facebook#UserState"],
type: "facebook",
bypassCache: !0,
persistent: !1
}, d(f), k);
g._sendRetry(c)
}, k)
};
this.getFriends = function (b, a) {
this.services.user.getUserInfo(function (f) {
f = new Spotify.Calls.Hermes({
header: {
uri: "hm://facebook/user/" + encodeURIComponent(f.user) + "/friends",
method: "GET"
},
payload: [{
fields: {
app_user: !0,
display_name: !0,
picture_large: !0
}
}],
payloadSchemas: ["facebook#FriendsRequest"],
responseSchemas: ["facebook#FriendsReply"],
type: "facebook"
}, function (a) {
a = h.parseFriendList(a);
b(a)
}, a);
g._sendRetry(f)
}, a)
};
this.getConfig =
function (b, a) {
var f = new Spotify.Calls.Hermes({
header: {
uri: "hm://facebook/config",
method: "GET"
},
responseSchemas: ["facebook#ConfigReply"],
type: "facebook"
}, function (a) {
a = h.parseConfig(a);
b(a)
}, a);
g._sendRetry(f)
};
this.share = function (b, a, f, k, c, d) {
this.services.user.getUserInfo(function (p) {
var q = h.makeCredential(b, a);
q.uri = f;
if (k) q.message_text = k;
p = new Spotify.Calls.Hermes({
header: {
uri: "hm://facebook/user/" + encodeURIComponent(p.user) + "/share",
method: "POST"
},
payload: [q],
payloadSchemas: ["facebook#ShareRequest"],
responseSchemas: ["facebook#ShareReply"],
type: "facebook",
bypassCache: !0
}, function (a) {
a = h.parsePostId(a);
c(a)
}, d);
g._sendRetry(p)
}, d)
};
this.getPermissions = function (b, a, f, k) {
this.services.user.getUserInfo(function (c) {
var d = h.makeCredential(b, a);
d.options = {
cache_is_king: !1
};
c = new Spotify.Calls.Hermes({
header: {
uri: "hm://facebook/user/" + encodeURIComponent(c.user) + "/permissions",
method: "GET"
},
payload: [d],
payloadSchemas: ["facebook#PermissionsRequest"],
responseSchemas: ["facebook#PermissionsReply"],
type: "facebook",
bypassCache: !0
}, function (a) {
a = h.parsePermissions(a);
f(a)
}, k);
g._sendRetry(c)
}, k)
};
this._sendRetry = function (b, a) {
var f = 0,
k = b.error,
a = a || 3,
m = function () {
g.send(b)
};
b.error = function (d) {
var h;
f + 1 < a && (statusCode = d.code || 0, Spotify.Hermes.Request.isServerError(statusCode) && (h = Math.pow(f, 2) + Math.random(), f++));
h !== void 0 ? (c.log("Spotify.Services.Facebook", ["Scheduling retry to request", b.header.method, b.header.uri, "in", h, "second(s) due to error", d], "corejs"), setTimeout(m, h * 1E3)) : k(d)
};
m()
};
this.inspectCredential =
function (b, a, f, k) {
this.services.user.getUserInfo(function (c) {
c = new Spotify.Calls.Hermes({
header: {
uri: "hm://facebook/user/" + encodeURIComponent(c.user) + "/inspect",
method: "POST"
},
payload: [h.makeCredential(b, a)],
payloadSchemas: ["facebook#InspectCredentialRequest"],
responseSchemas: ["facebook#InspectCredentialReply"],
type: "facebook",
bypassCache: !0
}, function (a) {
a = h.parseCredentialInspection(a);
f(a)
}, k);
g._sendRetry(c)
}, k)
}
};
Spotify.Services.FacebookPublish = function () {
var d = this,
g = new Spotify.Events,
c, h = [],
b = function (a, b, f, k, h, g) {
d.serviceIsReady ? (c.addToBucket({
uri: a,
startTime: b,
eventName: f,
event: k,
callback: h,
errback: g
}), c.isStarted() || c.start()) : g(new Spotify.Errors.Error([13, 503, "Facebook-publish service not ready!"]))
}, a = function (a) {
d.services.user.getUserInfo(function (b) {
for (var f = [], k = [], c = [], h = 0; h < a.length; h++) {
var g = a[h],
u = {
id: {
uri: g.uri,
startTime: g.startTime
}
};
u[g.eventName] = g.event;
f.push(u);
k.push("facebook-publish#Event");
c.push("facebook-publish#EventReply")
}
b = new Spotify.Calls.Hermes({
header: {
uri: "hm://facebook-publish/user/" + encodeURIComponent(b.user) + "/music/listen",
method: "POST"
},
payload: f,
payloadSchemas: k,
responseSchemas: c,
type: "facebook-publish",
bypassCache: !1,
persistent: !1
}, function () {
for (var b = 0; b < a.length; b++) a[b].callback.apply(this, arguments)
}, function () {
for (var b = 0; b < a.length; b++) a[b].errback.apply(this, arguments)
});
d.send(b)
}, function () {})
}, f = function (a) {
h.push(a.params)
}, k = function () {
a(h);
h = []
};
this.scrobbleStart =
function (a, f, k, c, d, h, g) {
c = {
length: d,
end_time: c
};
if (f) c.context_uri = f;
b(a, k, "start", c, h, g)
};
this.scrobbleSeek = function (a, f, k, c, d) {
b(a, f, "seek", {
end_time: k
}, c, d)
};
this.scrobblePause = function (a, f, k, c, d, h) {
b(a, f, "pause", {
seconds_played: k,
end_time: c
}, d, h)
};
this.scrobbleResume = function (a, f, k, c, d, h) {
b(a, f, "resume", {
seconds_played: k,
end_time: c
}, d, h)
};
this.scrobbleEnd = function (a, f, k, c, d, h) {
b(a, f, "end", {
seconds_played: k,
end_time: c
}, d, h)
};
this.setup = function () {
c = new Spotify.RateLimiter(1E3, 25);
c.bind(g.RATE_LIMIT_CALL,
f);
c.bind(g.RATE_LIMIT_AFTER_INTERVAL, k)
}
};
Spotify.Core = function (d, g) {
Spotify.EventTarget.call(this);
Spotify.DebuggerJS.register("console", new Spotify.DebuggerJS.Loggers.Console, new Spotify.DebuggerJS.Parsers.Default);
Spotify.Hermes.Cache = new Spotify.HermesCache;
var c = this,
h = Spotify.DebuggerJS,
b, a, f = !1,
k = typeof swfobject !== "undefined" ? Spotify.PlayerTypes.FLASH_RTMPS : Spotify.PlayerTypes.HTML5_HTTP,
m = {
playerType: k,
SWFContainerId: g.SWFContainerId || "",
SWFPlayerContainerId: g.SWFPlayerContainerId || "",
SWFPlayerUrl: g.SWFPlayerUrl || "player.swf",
SWFUrl: g.SWFUrl || "bridge.swf",
SWFMinVersion: g.SWFMinVersion || "10.2.0",
logging: g.logging || 0,
length: g.length || 0,
valid: g.valid || 0,
cdn: g.cdn || "",
protoSchemasLocation: g.protoSchemasLocation || "proto/",
protoSchemasLocationRandomizer: g.protoSchemasLocationRandomizer || "",
services: g.services || {}
};
this.id = "";
var o = d || Spotify.GatewayTypes.FLASH,
p, q = new Spotify.Events,
n, s = {}, t = new Spotify.Managers.ProtobufSchemasManager;
this.services = {};
this.previewUriResolver = this.adUriResolver = this.storageResolver = this._bridge = this.facebookPublish =
this.mergedProfile = this.adChooser = this.presence = this.hermes = this.collectionUnplayed = this.collectionView = this.collectionStorage = this.facebook = this.socialGraph = this.social = this.toplist = this.user = this.search = this.popcount = this.appstore = this.playlist = this.metadata = this.pubsub = this.time = this.suggest = this.player = null;
this.logging = {};
this.isReady = !1;
this.onConnect = function () {};
this.onDisconnect = function () {};
this.onTokenLost = function () {};
this.connect = function (a, b) {
p.connect(a, b)
};
this.connectWithToken = function (a,
b) {
p.connect(a, b)
};
this.connectWithCredentials = function (a, b, f) {
p.connect(a, "1:" + b + ":" + f)
};
this.disconnect = function () {
p.disconnect()
};
this.migrateToIndexedDBStorage = function (a, b, f) {
Spotify.Hermes.Cache.migrateToIndexedDB(a, b, f)
};
this.initialize = function () {
n = new Spotify.Proto.Data(m.protoSchemasLocation, m.protoSchemasLocationRandomizer);
n.bind(q.SUCCESS, F);
n.bind(q.ERROR, H);
n.initialize()
};
var u = function (a) {
var b = a.params;
if (b instanceof Spotify.Calls.Hermes) {
for (var a = b.success, f = b.isMultiGet ? b.mercuryMultiGetPayloadSchemas :
b.payloadSchemas, k = b.isMultiGet ? b.mercuryMultiGetResponseSchemas : b.responseSchemas, m = [], d = [], h = 0, g = f.length; h < g; h += 1) m.push(t.getProtobufMsgParser.apply(c, f[h].split("#")));
f = 0;
for (g = k.length; f < g; f += 1) d.push(t.getProtobufMsgParser.apply(c, k[f].split("#")));
b.isMultiGet && (a = function (a, f) {
for (var k = 0; k < a.length; k += 1) {
var m = a[k],
d = [];
if (typeof m.reply === "undefined") {
b.error(new Spotify.Errors.Error([13, 400]));
return
}
if (b.responseSchemas[k]) var h = t.getProtobufMsgParser.apply(c, b.responseSchemas[k].split("#"));
for (var m = m.reply, g = 0, o = m.length; g < o; g += 1) {
var n = m[g],
n = n && n.status_code ? n.status_code >= 200 && n.status_code < 300 ? h ? h.parseFromStringSync(n.body) : n : null : null;
d.push(n)
}
}
b.success(d, f)
});
(new Spotify.Hermes.ProtobufRequest(b.header, b.payload, m, d)).send(p, a, b.error, b.persistent, b.bypassCache, b.type)
} else b instanceof Spotify.Calls.Simple && p.rpc(b.method, b.payload, b.success, b.error, b.context, b.persistent, b.retries, b.type)
};
this.registerService = function (a, b, f, k, c) {
if (typeof this.services[a] !== "undefined") return h.error("Spotify.Core", ["A service with id", a, "already exists"], "corejs"), null;
if (typeof c === "undefined") c = Spotify.Services.Base;
k = Spotify.Utils.inherit(c.bind(this, t), k);
s[a] = f;
f = new k;
this.services[a] = f;
f._dependencies = b;
f.id = a;
f.bind(q.REQUEST, u, this);
return this.services[a]
};
this.dispose = function () {
for (var a in this.services) {
try {
this.services[a].dispose()
} catch (b) {}
this.services[a] = null
}
this.audioManager.dispose();
p.dispose()
};
this.onReady = function (a, b) {
this.isReady ? a.call(b) : this.bind(q.READY, a, b)
};
var w = function (a) {
var b =
c.audioManager.getActivePlayer();
b && b.pause();
c.onTokenLost(a)
}, v = function (a) {
A(a)
}, A = function (a) {
for (var b in c.services) try {
c.services[b].onNotify(a)
} catch (f) {}
}, x = function (a) {
A(a)
}, F = function () {
Spotify.Instances.add(c);
t.registerSchema("mercury", n.getDefinition("mercury"));
t.registerSchema("pubsub", n.getDefinition("pubsub"));
c.registerService("user", [], [], Spotify.Services.User);
c.user = c.services.user;
c.registerService("logging_clientEvent", [], [], Spotify.Logging.ClientEvent);
c.logging.clientEvent =
c.services.logging_clientEvent;
c.registerService("logging_view", [], [], Spotify.Logging.View);
c.logging.view = c.services.logging_view;
c.registerService("logging_logger", [], [], Spotify.Logging.Logger);
c.logging.logger = c.services.logging_logger;
c.registerService("heartbeat", [], [], Spotify.Heartbeat);
c.registerService("storageResolver", [], [], Spotify.Services.SongUriResolver);
c.storageResolver = c.services.storageResolver;
c.storageResolver.bind(q.TIME_CAP, G, c);
c.registerService("adResolver", [], [], Spotify.Services.AdUriResolver);
c.adUriResolver = c.services.adResolver;
c.registerService("previewResolver", [], [], Spotify.Services.PreviewsUriResolver);
c.previewUriResolver = c.services.previewResolver;
c.registerService("pubsub", [], ["pubsub"], Spotify.Services.Pubsub);
c.pubsub = c.services.pubsub;
p = new Spotify.Gateway(o);
p.bind(q.READY, z, c);
p.bind(q.ON_TRY_TO_CONNECT, y, c);
p.bind(q.CONNECTED, L, c);
p.bind(q.DISCONNECTED, c.onDisconnect, c);
p.bind(q.TOKEN_LOST, w, c);
p.bind(q.FLASH_AVAILABLE, E, c);
p.bind(q.FLASH_UNAVAILABLE, E, c);
p.bind(q.HERMES_B64_MESSAGE,
v, c);
p.bind(q.USER_INFO_CHANGE, B, c);
Spotify.Hermes.Cache.onfull = K;
c.features = new Spotify.Features(g.features);
c.hermes = new Spotify.Hermes.Handler;
c.hermes.init(p);
c.audioManager = new Spotify.Audio.AudioManager(c.id, m, k);
c.audioManager.bind(q.FLASH_AVAILABLE, E, c);
c.audioManager.bind(q.FLASH_UNAVAILABLE, E, c);
c.audioManager.bind(q.NO_SOUND_CAPABILITIES, I);
c.audioManager.bind(q.INITIALIZED, C, c);
c.audioManager.bind(q.TRACK_ENDED, x, c);
c.audioManager.bind(q.POSITION_CHANGED, x, c);
c.audioManager.bind(q.PLAYING,
x, c);
c.audioManager.bind(q.PAUSED, x, c);
c.audioManager.bind(q.STOPPED, x, c);
c.audioManager.bind(q.LOAD, x, c);
c.audioManager.addFileResolver(Spotify.Resolvers.STORAGE_RESOLVER, c.services.storageResolver);
c.audioManager.addFileResolver(Spotify.Resolvers.AD_RESOLVER, c.services.adResolver);
c.audioManager.addFileResolver(Spotify.Resolvers.PREVIEW_RESOLVER, c.services.previewResolver);
c.audioManager.initialize(p, c.user);
b = new Spotify.Worker;
b.initialize(p, c.audioManager);
p.initialize(c.id, m);
c._bridge = p.bridge
},
G = function (a) {
c.trigger(q.TIME_CAP, a.params)
}, B = function (a) {
A(a)
}, E = function (b) {
b.type === q.UNAVAILABLE ? c.trigger(q.FLASH_UNAVAILABLE) : (a && clearTimeout(a), a = setTimeout(function () {
p.isReady && c.audioManager.isInitialized ? h.log("Spotify.Core", ["Flash is available"], "corejs") : (h.error("Spotify.Core", ["Flash is NOT available"], "corejs"), c.trigger(q.FLASH_UNAVAILABLE))
}, 1E4))
}, H = function (a) {
c.trigger(q.DATA_ERROR, a)
}, I = function () {
c.trigger(q.NO_SOUND_CAPABILITIES)
}, K = function () {
c.trigger(q.STORAGE_FULL)
},
L = function (a) {
if (!f) {
f = !0;
c.registerService("appstore", [], ["appstore"], Spotify.Services.AppStore);
c.appstore = c.services.appstore;
c.registerService("mergedProfile", [], ["mergedprofile"], Spotify.Services.MergedProfile);
c.mergedProfile = c.services.mergedProfile;
c.registerService("popcount", [], ["popcount"], Spotify.Services.PopCount);
c.popcount = c.services.popcount;
c.registerService("social", [], ["social"], Spotify.Services.Social);
c.social = c.services.social;
c.registerService("searchHermes", [], ["metadata",
"search"
], Spotify.Services.SearchHermes);
c.registerService("suggest", ["user"], ["suggest"], Spotify.Services.Suggest);
c.suggest = c.services.suggest;
c.registerService("toplist", ["user"], ["toplist", "socialgraph"], Spotify.Services.Toplist);
c.toplist = c.services.toplist;
c.registerService("search", ["user"], [], Spotify.Services.Search);
c.search = c.services.search;
c.registerService("playlist", ["user", "toplist", "pubsub"], "playlist4changes,playlist4content,playlist4issues,playlist4meta,playlist4ops,playlist4service".split(","),
Spotify.Services.Playlist);
c.playlist = c.services.playlist;
c.registerService("presence", ["pubsub", "user"], ["presence"], Spotify.Services.Presence);
c.presence = c.services.presence;
c.registerService("socialGraph", ["user", "playlist"], ["socialgraph"], Spotify.Services.SocialGraph);
c.socialGraph = c.services.socialGraph;
c.registerService("facebook", ["user"], ["facebook"], Spotify.Services.Facebook);
c.facebook = c.services.facebook;
c.registerService("facebookPublish", ["user"], ["facebook-publish"], Spotify.Services.FacebookPublish);
c.facebookPublish = c.services.facebookPublish;
c.registerService("metadata", ["user"], ["metadata"], Spotify.Services.Metadata);
c.metadata = c.services.metadata;
c.registerService("time", [], [], Spotify.Services.Time);
c.registerService("inbox", ["playlist"], [], Spotify.Services.Inbox);
c.adChooser = new Spotify.Services.AdChooser;
c.services.adChooser = c.adChooser;
c.adChooser.bind(q.INTERCEPTED, N);
c.adChooser.init(p, c.audioManager, c.user);
c.collectionStorage = new Spotify.Services.CollectionStorage(m.services.collection_storage,
n.getDefinition("collection2"));
c.services.collectionStorage = c.collectionStorage;
c.collectionStorage.init(p, c.pubsub);
c.collectionView = new Spotify.Services.CollectionView(m.services.collection_view);
c.services.collectionView = c.collectionView;
c.collectionView.init(c.collectionStorage, c.metadata, c.playlist, c.user, p, n.getDefinition("collection2cache"));
c.collectionUnplayed = new Spotify.Services.CollectionUnplayed(m.services.collection_unplayed);
c.collectionUnplayed.init(c.collectionStorage, c.user);
for (var b in c.services) {
var k = !1,
d = [];
if (c.services[b]._dependencies) {
for (var h = 0, g = c.services[b]._dependencies.length; h < g; h += 1) {
var o = c.services[c.services[b]._dependencies[h]];
if (typeof o === "undefined") {
k = !0;
break
}
d.push(o)
}
if (!k) {
k = 0;
for (h = s[b].length; k < h; k += 1) g = s[b][k], t.registerSchema(g, n.getMultipleDefinitions([g]));
s[b].length > 1 && t.registerSchema(b + "_FULL", n.getMultipleDefinitions(s[b]));
c.services[b]._initialize.call(c.services[b], d)
}
}
}
}
A(a);
c.onConnect(a)
}, N = function () {
c.trigger(q.WAIT_FOR_COMMERCIAL_TO_FINISH)
}, M = function () {
if (!c.isReady &&
p.isReady && c.audioManager.isInitialized) c.isReady = !0, c.trigger(q.READY)
}, z = function () {
M()
}, C = function () {
M()
}, y = function (a) {
A({
type: q.DISCONNECTED,
params: {},
extra: {}
});
c.trigger(a.type)
};
this.initialize.call(this)
};
(function () {
Spotify.Shell = {}
})();
(function () {
function d(c) {
var d = c.data;
if (typeof d == "string") try {
d = JSON.parse(d)
} catch (b) {
return
}
var a = g[d.type];
a && a.call(this, c, d)
}
var g = {};
window.attachEvent && !window.addEventListener ? window.attachEvent("onmessage", d) : window.addEventListener("message", d, !1);
Spotify.addMessageHandler = function (c, d) {
if (g[c]) throw Error('Rehandling of message "' + c + '" not allowed.');
g[c] = d
};
Spotify.removeMessageHandler = function (c, d) {
return g[c] == d ? (g[c] = null, !0) : !1
}
})();
(function () {
var d = [],
g = window.postMessage.bind(window, '{"type": "execute_deferreds"}', window.location.origin || [window.location.protocol, window.location.hostname].join("//"));
Spotify.addMessageHandler("execute_deferreds", function () {
var c = d.splice(0);
if (c.length)
for (var h = 0, b = c.length; h < b; h++) {
var a = !0;
try {
c[h](), a = !1
} finally {
a && (a = !d.length, d = c.slice(++h).concat(d), a && g())
}
}
});
Spotify.defer = function (c) {
var h = !d.length;
d.push(c);
h && g()
}
})();
(function () {
var d;
function g(b, a) {
b.then(function (b) {
a.fulfill(b)
}, function (b) {
a.fail(b)
})
}
function c() {
this._state = d;
this._value = null;
this._handlers = [];
this._deferred = !1
}
var h = Array.prototype.slice;
d = 0;
Spotify.Promise = c;
c.defer = typeof setImmediate == "function" ? function (b) {
setImmediate(b)
} : Spotify.defer;
c.prototype.isUnfulfilled = function () {
return this._state == d
};
c.prototype.isFulfilled = function () {
return this._state == 1
};
c.prototype.isFailed = function () {
return this._state == 2
};
c.prototype.fulfill = function (b) {
var a =
this;
if (this._state === d && (this._value = b, this._state = 1, !this._deferred)) c.defer(function () {
a._runHandlers()
}), this._deferred = !0
};
c.prototype.fail = function (b) {
var a = this;
if (this._state === d && (this._value = b, this._state = 2, !this._deferred)) c.defer(function () {
a._runHandlers()
}), this._deferred = !0
};
c.prototype.then = function (b, a) {
var f = this,
k = new c;
this._handlers.push({
fulfilled: b,
failed: a,
promise: k
});
if (this._state !== d && !this._deferred) c.defer(function () {
f._runHandlers()
}), this._deferred = !0;
return k
};
c.prototype.pipe =
function (b) {
this.then(function (a) {
b.fulfill(a)
}, function (a) {
b.fail(a)
})
};
c.prototype._runHandlers = function () {
this._deferred = !1;
var b = this._value;
if (this._state != d)
for (var a = this._state === 1, f = this._handlers.splice(0), k = 0, c = f.length; k < c; k++) {
var h = f[k],
p = h[a ? "fulfilled" : "failed"],
h = h.promise;
if (!p || typeof p != "function") b && typeof b.then == "function" ? g(b, h) : a ? h.fulfill(b) : h.fail(b);
else {
try {
var q = p(b)
} catch (n) {
h.fail(n);
continue
}
q && typeof q.then == "function" ? g(q, h) : h.fulfill(q)
}
}
};
c.prototype.catchError =
function (b) {
return this.then(null, b)
};
c.prototype.get = function (b) {
var a = new c;
this.then(function (f) {
a.fulfill(f[b])
}, function (b) {
a.fail(b)
});
return a
};
c.prototype.call = function (b, a) {
var f = h.call(arguments, 1),
k = new c;
this.then(function (a) {
try {
k.fulfill(a[b].apply(a, f))
} catch (c) {
k.fail(c)
}
}, function (a) {
k.fail(a)
});
return k
};
c.prototype.thenSpread = function (b, a) {
return this.then(function (a) {
return Array.isArray(a) ? b.apply(this, a) : b.call(this, a)
}, a)
};
c.join = function (b) {
for (var b = Array.isArray(b) ? b : h.call(arguments),
a = new c, f = b.length, k = [], m = !1, d = function (b, c) {
m || (k[b] = c, f--, f || a.fulfill(k))
}, g = function (b) {
m || (m = !0, a.fail(b))
}, q = 0, n = f; q < n; q++) b[q].then(d.bind(null, q), g);
return a
};
c.group = function (b) {
for (var b = Array.isArray(b) ? b : h.call(arguments), a = new c, f = 0, k = b.length; f < k; f++) a.pipe(b[f]);
return a
}
})();
(function () {
var d = Array.prototype.slice,
g = Object.prototype.toString,
c = Spotify.Link;
if (!Array.isArray) Array.isArray = function (c) {
return g.call(c) == "[object Array]"
};
Array.prototype.spliceWith || Object.defineProperty(Array.prototype, "spliceWith", {
configurable: !0,
enumerable: !1,
writeable: !0,
value: function (c, b, a) {
if (a == void 0) return this.splice(c, b);
Array.isArray(a) || (a = [a]);
return this.splice.apply(this, [c, b].concat(a))
}
});
Array.prototype.insertFrom || Object.defineProperty(Array.prototype, "insertFrom", {
configurable: !0,
enumerable: !1,
writeable: !0,
value: function (c, b) {
if (b == void 0) return this;
Array.isArray(b) || (b = [b]);
for (var a = b.length; a--;) this[a + c] = b[a];
return this
}
});
Spotify.inherit = function (c, b) {
function a() {}
var f = b.prototype;
a.prototype = c._super = f;
a.prototype.constructor = b;
c.prototype = new a;
c.prototype._super = function (a, b) {
b = typeof b == "arguments" || Array.isArray(b) ? b : d.call(arguments, 1);
return f[a].apply(this, b)
}
};
Spotify.LinkHelper = {};
Spotify.LinkHelper.from = function (d) {
try {
return d instanceof c ? d : c.fromString(d.toString())
} catch (b) {
return null
}
}
})();
(function () {
function d() {
this._ids = [];
this._values = {}
}
Spotify.Shell.RequestQueue = d;
d.prototype.push = function (d, c) {
var h = this._ids,
b = this._values,
d = d.toString();
b[d] || h.push(d);
(b[d] || (b[d] = [])).push(c);
return this
};
d.prototype.takeIds = function (d) {
var c = this._ids,
d = d != void 0 ? d : c.length;
return c.splice(0, d)
};
d.prototype.takeValues = function (d, c) {
var h = this._values[d];
if (!h) return [];
var c = c != void 0 ? c : h.length,
b = h.splice(0, c);
h.length || (this._values[d] = null);
return b
}
})();
(function () {
function d() {
this._events = {}
}
var g = Spotify.defer;
Spotify.Shell.EventEmitter = d;
d.prototype.addEvent = function (c, d) {
var b = this._events[c] || (this._events[c] = []);
if (b.indexOf(d) != -1) return this;
b.push(d);
return this
};
d.prototype.addEvents = function (c) {
for (var d in c) c.hasOwnProperty(d) && this.addEvent(d, c[d])
};
d.prototype.addOnceEvent = function (c, d) {
var b = this,
a = function () {
var f = d.apply(this, arguments);
b.removeEvent(c, a);
return f
};
return this.addEvent(c, a)
};
d.prototype.removeEvent = function (c,
d) {
var b = this._events[c];
if (!b || !b.length) return this;
var a = b.indexOf(d);
if (a == -1) return this;
b.splice(a, 1);
return this
};
d.prototype.fireEvent = function (c, d, b) {
var a = this,
c = this._events[c];
if (!c || !c.length) return this;
c = c.slice(0);
Array.isArray(d) || (d = [d]);
for (var f = c.length; f--;)(function (f) {
b ? f.apply(a, d) : g(function () {
f.apply(a, d)
})
})(c[f]);
return this
};
d.prototype.fireEventSync = function (c, d) {
var b = this._events[c];
if (!b || !b.length) return this;
b = b.slice(0);
Array.isArray(d) || (d = [d]);
for (var a = b.length; a--;) b[a].apply(this,
d);
return this
}
})();
(function () {
function d(c, h, b) {
if (!(this instanceof d)) return new d(c, h, b);
var c = c != null ? c : 0,
h = h != null ? h : -1,
b = b != null ? b : Infinity,
a = h == -1 ? b : h;
this.length = h = h == -1 ? b : Math.min(h, b);
this.expectedLength = a;
this.begin = c;
this.last = c + h;
this.end = c + h - 1
}
var g = Array.prototype.slice;
Spotify.Shell.Range = d;
d.prototype.contains = function (c) {
return !(c.begin < this.begin || c.begin > this.end || c.end > this.end || c.end < this.begin)
};
d.prototype.has = function (c) {
return c >= this.begin && c <= this.end
};
d.prototype.equals = function (c) {
return this.begin ==
c.begin && this.end == c.end
};
d.prototype.intersects = function (c) {
return this.begin <= c.end && c.begin <= this.end
};
d.prototype.contiguous = function (c) {
return this.last == c.begin || c.last == this.begin
};
d.prototype.intersect = function (c) {
if (this.end < c.begin || c.end < this.begin) return new d(NaN, 0);
var h = Math.max(c.begin, this.begin),
c = Math.min(c.end, this.end) - h + 1;
return new d(h, c)
};
d.prototype.add = function (c) {
var h = Math.min(c.begin, this.begin),
c = Math.max(c.end, this.end) - h + 1;
return new d(h, c)
};
d.prototype.subtract = function (c) {
if (this.equals(c)) return [];
if (this.contains(c)) {
var h = [],
b = new d(this.begin, c.begin - this.begin),
c = new d(c.end + 1, this.end - c.end);
b.length && h.push(b);
c.length && h.push(c);
return h
} else if (c.contains(this)) return c.subtract(this);
else if (this.intersects(c)) return this.add(c).subtract(this.intersect(c));
return [this, c]
};
d.prototype.subtractMany = function (c) {
for (var c = Array.isArray(c) ? c : g.call(arguments), d = [], b = this, a = 0, f = c.length; a < f; a++) {
var k = c[a];
if (!b.intersects(k)) break;
b = b.subtract(b.intersect(k));
switch (b.length) {
case 2:
d.push(b[0]);
b = b[1];
break;
case 1:
b = b[0];
break;
default:
return []
}
}
d.push(b);
return d
};
d.prototype.fill = function (c) {
if (this.intersects(c)) return new d(NaN, 0);
var h;
Math.min(this.begin, c.begin) == this.begin ? h = this : (h = c, c = this);
return new d(h.end + 1, c.begin - h.end - 1)
};
d.prototype.split = function (c) {
if (c >= this.length) return [new d(this.begin, this.length)];
for (var h = [], b = this.begin, a = this.length; a;) {
if (a < c) {
h.push(new d(b, a));
break
} else h.push(new d(b, c));
a -= c;
b += c
}
return h
};
d.prototype.findContainer = function (c) {
for (var c =
Array.isArray(c) ? c : g.call(arguments), d = 0, b = c.length; d < b; d++)
if (c[d].contains(this)) return c[d];
return null
};
d.simplify = function (c) {
var c = Array.isArray(c) ? c : g.call(arguments),
d = [],
b = null;
c.sort(function (a, b) {
return a.begin - b.begin
});
for (var a = 0, f = c.length; a < f; a++) {
var k = c[a];
!isNaN(k.begin) && !isNaN(k.length) && k.length && (b && (b.intersects(k) || b.contiguous(k) ? k = b.add(k) : d.push(b)), b = k)
}
b && d.push(b);
return d
}
})();
(function () {
Spotify.ItemList = {};
Spotify.ItemList.LIST_START = new function () {};
Spotify.ItemList.LIST_END = new function () {};
Spotify.ItemList.NULL_VALUE = new function () {};
Spotify.ItemList.LoadedState = {
UNLOADED: "unloaded",
LOADING: "loading",
PARTIAL: "partial",
COMPLETE: "complete"
}
})();
(function () {
function d(a, b) {
return a - b
}
function g(a, b) {
return b - a
}
function c(a, b) {
return a > b ? 1 : a == b ? 0 : -1
}
function h(a, b) {
return a > b ? -1 : a == b ? 0 : 1
}
Spotify.ItemList.SortingOrder = {
ASC: "asc",
DESC: "desc"
};
Spotify.ItemList.ComparisonResult = {
GREATER: 1,
EQUAL: 0,
LESS: -1
};
var b = Spotify.ItemList.Comparators = {};
b.forNumber = function () {
return d
};
b.forNumberReversed = function () {
return g
};
b.forString = function () {
return c
};
b.forStringReversed = function () {
return h
};
var a = {}, f = {};
b.forNumberProperty = function (b) {
return a[b] ||
(a[b] = function (a, f) {
a = a[b];
f = f[b];
return a - f
})
};
b.forNumberPropertyReversed = function (b) {
var f = b + "_reverse";
return a[f] || (a[f] = function (a, f) {
a = a[b];
f = f[b];
return f - a
})
};
b.forStringProperty = function (a) {
return f[a] || (f[a] = function (b, f) {
b = (b[a] || "").toString();
f = (f[a] || "").toString();
return b > f ? 1 : b == f ? 0 : -1
})
};
b.forStringPropertyReversed = function (a) {
var b = a + "_reverse";
return f[b] || (f[b] = function (b, f) {
b = (b[a] || "").toString();
f = (f[a] || "").toString();
return b > f ? -1 : b == f ? 0 : 1
})
};
b.forProperty = function (a, b) {
return function (f,
c) {
return b(f[a], c[a])
}
}
})();
(function () {
Spotify.ItemList.PredicateOperator = {
EQUAL: "=",
NOT_EQUAL: "!=",
GREATER_THAN: ">",
LESS_THAN: "<",
GREATER_THAN_OR_EQUAL: ">=",
LESS_THAN_OR_EQUAL: "<=",
STARTS_WITH: "startswith",
CONTAINS: "contains"
};
var d = Spotify.ItemList.Predicates = {};
d.forOperator = function (d, c) {
switch (d) {
case "=":
return this.forEqual(c);
case "!=":
return this.forNotEqual(c);
case ">":
return this.forGreaterThan(c);
case "<":
return this.forLessThan(c);
case ">=":
return this.forGreaterThanOrEqual(c);
case "<=":
return this.forLessThanOrEqual(c);
case "startswith":
return this.forBeginsWith(c);
case "contains":
return this.forContains(c);
default:
return null
}
};
d.forPropertyOperator = function (d, c, h) {
switch (c) {
case "=":
return this.forPropertyEqual(d, h);
case "!=":
return this.forPropertyNotEqual(d, h);
case ">":
return this.forPropertyGreaterThan(d, h);
case "<":
return this.forPropertyLessThan(d, h);
case ">=":
return this.forPropertyGreaterThanOrEqual(d, h);
case "<=":
return this.forPropertyLessThanOrEqual(d, h);
case "startswith":
return this.forPropertyBeginsWith(d, h);
case "contains":
return this.forPropertyContains(d,
h);
default:
return null
}
};
d.forNotNull = function () {
return function (d) {
return d != null
}
};
d.forEqual = function (d) {
return function (c) {
return c === d
}
};
d.forGreaterThan = function (d) {
return function (c) {
return c > d
}
};
d.forLessThan = function (d) {
return function (c) {
return c < d
}
};
d.forGreaterThanOrEqual = function (d) {
return function (c) {
return c >= d
}
};
d.forLessThanOrEqual = function (d) {
return function (c) {
return c <= d
}
};
d.forNotEqual = function (d) {
return function (c) {
return c != d
}
};
d.forBeginsWith = function (d) {
return function (c) {
return !c ? !1 : c.toString().indexOf(d) == 0
}
};
d.forContains = function (d) {
return function (c) {
return !c ? !1 : c.toString().indexOf(d) != -1
}
};
d.forPropertyNotNull = function (d) {
return function (c) {
return c[d] != null
}
};
d.forPropertyEqual = function (d, c) {
return function (h) {
return h[d] == c
}
};
d.forPropertyGreaterThan = function (d, c) {
return function (h) {
return h[d] > c
}
};
d.forPropertyLessThan = function (d, c) {
return function (h) {
return h[d] < c
}
};
d.forPropertyGreaterThanOrEqual = function (d, c) {
return function (h) {
return h[d] >= c
}
};
d.forPropertyLessThanOrEqual =
function (d, c) {
return function (h) {
return h[d] <= c
}
};
d.forPropertyNotEqual = function (d, c) {
return function (h) {
return h[d] != c
}
};
d.forPropertyBeginsWith = function (d, c) {
return function (h) {
return !h || !h[d] ? !1 : h[d].toString().indexOf(c) == 0
}
};
d.forPropertyContains = function (d, c) {
return function (h) {
return !h || !h[d] ? !1 : h[d].toString().indexOf(c) != -1
}
}
})();
(function () {
function d(a) {
if (!(this instanceof d)) return new d(a);
if (!a) return this;
for (var b in a) this[b] = a[b]
}
function g(a) {
if (!(this instanceof g)) return new g(a);
d.call(this, a)
}
function c(a, b, k, d, h) {
if (!(this instanceof c)) return new c(a, b, k, d, h);
this._applied = !1;
this._applyMutation = a;
this._checkVersion = b;
this._ruleset = k;
this._version = d;
this._length = h;
this._changes = []
}
var h = Spotify.Promise;
Spotify.ItemList.MutationResult = {
SUCCESS: "success",
ALLOWED: "allowed",
FORBIDDEN: "forbidden",
LIST_FULL: "listFull",
OUT_OF_BOUNDS: "outOfBounds",
EXPIRED: "expired"
};
var b = Spotify.ItemList.MutationResult;
Spotify.ItemList.MutationRuleset = d;
d.prototype.add = b.ALLOWED;
d.prototype.insert = b.ALLOWED;
d.prototype.remove = b.ALLOWED;
d.prototype.move = b.ALLOWED;
Spotify.inherit(g, d);
Spotify.ItemList.MutationRuleset.Immutable = g;
g.prototype.add = b.FORBIDDEN;
g.prototype.insert = b.FORBIDDEN;
g.prototype.remove = b.FORBIDDEN;
g.prototype.move = b.FORBIDDEN;
Spotify.ItemList.Mutator = c;
c.prototype.isApplied = function () {
return !!this._applied
};
c.prototype.isExpired =
function () {
return !this._checkVersion(this._version)
};
c.prototype.canInsert = function (a) {
return this._ruleset.insert == b.FORBIDDEN ? b.FORBIDDEN : this._applied || !this._checkVersion(this._version) ? b.EXPIRED : a < 0 || a > this._length ? b.OUT_OF_BOUNDS : b.ALLOWED
};
c.prototype.canAdd = function () {
return this._ruleset.add == b.FORBIDDEN ? b.FORBIDDEN : this._applied || !this._checkVersion(this._version) ? b.EXPIRED : b.ALLOWED
};
c.prototype.canRemove = function (a, f) {
return this._ruleset.remove == b.FORBIDDEN ? b.FORBIDDEN : this._applied || !this._checkVersion(this._version) ? b.EXPIRED : a < 0 || a > this._length ? b.OUT_OF_BOUNDS : a + f > this._length ? b.OUT_OF_BOUNDS : b.ALLOWED
};
c.prototype.canMove = function (a, f, k) {
return this._ruleset.move == b.FORBIDDEN ? b.FORBIDDEN : this._applied || !this._checkVersion(this._version) ? b.EXPIRED : a < 0 || a > this._length ? b.OUT_OF_BOUNDS : f < 0 || f > this._length ? b.OUT_OF_BOUNDS : a + k > this._length ? b.OUT_OF_BOUNDS : b.ALLOWED
};
c.prototype.apply = function () {
var a = new h;
if (this._applied) return a.fulfill(b.EXPIRED), a;
this._applied = !0;
this._applyMutation(this._version,
this._changes).pipe(a);
return a
};
c.prototype.insert = function (a, f, k) {
var c = this.canInsert(a, f.length);
if (c != b.ALLOWED) return c;
if (!f.length) return b.SUCCESS;
this._length += f.length;
a = {
type: "insert",
begin: a,
items: f.slice(0)
};
this._changes.push(a);
k && k.push(a);
return b.SUCCESS
};
c.prototype.add = function (a, f) {
var k = this.canAdd(a.length);
return k != b.ALLOWED ? k : !a.length ? b.SUCCESS : this.insert(this._length, a, f)
};
c.prototype.remove = function (a, f, k) {
var c = this.canRemove(a, f);
if (c != b.ALLOWED) return c;
if (f == 0) return b.SUCCESS;
this._length -= f;
a = {
type: "remove",
begin: a,
length: f
};
this._changes.push(a);
k && k.push(a);
return b.SUCCESS
};
c.prototype.move = function (a, f, k, c) {
var d = this.canMove(a, f, k);
if (d != b.ALLOWED) return d;
if (a == f || k == 0) return b.SUCCESS;
a = {
type: "move",
begin: a,
end: f,
length: k
};
this._changes.push(a);
c && c.push(a);
return b.SUCCESS
}
})();
(function () {
function d(c, h, b, a) {
if (!(this instanceof d)) return new d(c, h, b);
this._version = c;
this._versionedAccessor = h;
this._range = b;
this._listLength = a
}
var g = Spotify.ItemList;
Spotify.ItemList.Snapshot = d;
d.prototype.getOffset = function () {
return this._range.begin
};
d.prototype.getLength = function () {
return this._range.length
};
d.prototype.getListLength = function () {
return this._listLength
};
d.prototype.getVersion = function () {
return this._version
};
d.prototype.get = function (c) {
var d = this._range,
b = d.begin + c;
return b <
0 || b < d.begin || b > d.end ? g.NULL_VALUE : this._versionedAccessor(this._version, b, c)
};
d.prototype.toArray = function () {
for (var c = [], d = 0, b = this._range.length; d < b; d++) {
var a = this.get(d);
a != g.NULL_VALUE && c.push(a)
}
return c
};
d.prototype.toFullArray = function () {
for (var c = [], d = 0, b = this._range.length; d < b; d++) {
var a = this.get(d);
c.push(a)
}
return c
}
})();
(function () {
function d(a) {
if (!(this instanceof d)) return new d(a);
this._base = a || null;
this._descriptor = null;
this._observers = [];
this._version = 0;
this._list = [];
this._length = null;
this._snapshotLimit = 1E3;
this._loadLimit = 200;
this._loadedState = f.UNLOADED;
this._loadedRanges = [];
this._snapshotQueue = [];
this.makeMutable()
}
var g = Spotify.Promise,
c = Spotify.Shell.Range,
h = Spotify.ItemList,
b = Spotify.ItemList.Comparators,
a = Spotify.ItemList.Predicates,
f = h.LoadedState,
k = h.MutationRuleset,
m = h.MutationResult,
o = h.Mutator,
p = h.Snapshot;
Spotify.ItemList.Base = d;
d.prototype.setDescriptor = function (a) {
this._descriptor = a;
return this
};
d.prototype.getDescriptor = function () {
return this._descriptor
};
d.prototype.makeMutable = function () {
this._ruleset = new k
};
d.prototype.makeImmutable = function () {
this._ruleset = new k.Immutable;
return this
};
d.prototype.getVersion = function () {
return this._version
};
d.prototype.getBaseList = function () {
return this._base || null
};
d.prototype.getRootBaseList = function () {
if (!this._base) return this;
for (var a = this,
b = this; a = a._base;) b = a;
return b
};
d.prototype.layersList = function (a) {
if (!this._base) return this == a;
for (var b = this; b = b._base;)
if (b == a) return !0;
return !1
};
d.prototype.layersListType = function (a) {
if (!this._base) return this instanceof a;
for (var b = this; b = b._base;)
if (b instanceof a) return !0;
return !1
};
d.prototype.createComparator = function (a, f) {
return f == "asc" ? b.forString() : b.forStringReversed()
};
d.prototype.createPredicate = function () {
return a.forNotNull()
};
d.prototype.observe = function (a) {
this._observers.push(a);
return this
};
d.prototype.unobserve = function (a) {
a = this._observers.indexOf(a);
a != -1 && this._observers.splice(a, 1);
return this
};
d.prototype.notify = function (a, b) {
for (var f = this._observers.slice(0), c = 0, k = f.length; c < k; c++) {
var d = f[c],
m = d[a];
m && m.call(d, b, this)
}
return this
};
d.prototype.onBeforeMutate = function () {};
d.prototype.onMutate = function () {};
d.prototype.createMutator = function () {
if (this._loadedState != f.COMPLETE) return null;
var a = this._createMutationApplicator(),
b = this._createVersionComparator();
return new o(a,
b, this._ruleset, this._version, this._length)
};
d.prototype._createMutationApplicator = function () {
var a = this;
return function (b, f) {
var k = new g;
if (a._version != b) return k.fulfill(m.EXPIRED), k;
a.notify("onBeforeMutate", new p(a._version, a._createVersionedAccessor(), new c(0, a._length), a._length));
for (var d = [], h = 0, o = f.length; h < o; h++) {
var A = f[h],
x = null;
switch (A.type) {
case "insert":
x = a._applyInsertMutation(A);
break;
case "remove":
x = a._applyRemoveMutation(A);
break;
case "move":
x = a._applyMoveMutation(A)
}
x && d.push(x)
}
a._version++;
a.notify("onMutate", d);
k.fulfill(m.SUCCESS);
return k
}
};
d.prototype._applyInsertMutation = function (a) {
var b = a.items;
this._list.spliceWith(a.begin, 0, b);
this._length += b.length;
return a
};
d.prototype._applyRemoveMutation = function (a) {
var b = a.length;
this._list.splice(a.begin, b);
this._length -= b;
return a
};
d.prototype._applyMoveMutation = function (a) {
var b = a.end,
f = this._list,
k = f.splice(a.begin, a.length);
f.spliceWith(b, 0, k);
return a
};
d.prototype._unqueueSnapshots = function () {
for (var a = this._snapshotQueue, b = 0, f =
a.length; b < f; b++) {
var k = a[b];
this.snapshot(k[0], k[1]).pipe(k[2])
}
};
d.prototype._queueSnapshot = function (a, b, f) {
this._snapshotQueue.push([a, b, f]);
return this
};
d.prototype._fill = function (a) {
var b = this._loadedState,
k = this._loadLimit,
d = new g;
if (b == f.COMPLETE) d.fulfill(this);
else {
for (var b = Math.floor(a.begin * (1 / k)) * k, a = Math.ceil(a.last * (1 / k)) * k, a = new c(b, a - b), b = a.subtractMany(this._loadedRanges), a = [], m = 0, h = b.length; m < h; m++) a.push.apply(a, b[m].split(k));
if (!a.length) return d.fulfill(this), d;
k = [];
b = 0;
for (m =
a.length; b < m; b++) k.push(this._load(a[b]).then(this._insertLoadedData.bind(this)));
g.join(k).pipe(d)
}
return d
};
d.prototype._insertLoadedData = function (a) {
var b = a.range;
this._list.insertFrom(b.begin, a.items);
this._updateRanges(b);
this._updateState();
return a
};
d.prototype._updateRanges = function (a) {
var b = this._loadedRanges;
b.push(a);
this._loadedRanges = c.simplify(b)
};
d.prototype._updateState = function () {
var a = this._loadedRanges;
this._loadedState = a.length == 1 && a[0].length >= this._length ? f.COMPLETE : f.PARTIAL
};
d.prototype._load = function () {
var a = new g;
a.fulfill({
state: f.COMPLETE,
range: new c(0, 0),
items: []
});
return a
};
d.prototype._loadLength = function () {
var a = new g,
b = this._length = 0;
a.fulfill({
length: b
});
return a
};
d.prototype.fillFromArray = function (a, b, k) {
this._list.spliceWith(k.begin, k.length, a);
this._length = b;
a = this._loadedRanges;
a.push(k);
this._loadedRanges = a = c.simplify(a);
this._loadedState = a.length == 1 && a[0].length == b ? f.COMPLETE : f.PARTIAL
};
d.prototype.fillFullFromArray = function (a) {
this._list.spliceWith(0,
0, a);
this._length = a.length;
this._loadedRanges = [new c(0, a.length)];
this._loadedState = f.COMPLETE
};
d.prototype._createVersionComparator = function () {
var a = this;
return function (b) {
return a._version == b
}
};
d.prototype._createVersionedAccessor = function () {
var a = this,
b = this._list;
return function (f, k) {
if (a._version != f) throw Error("Cannot access item with an expired snapshot.");
return k in b ? b[k] : h.NULL_VALUE
}
};
d.prototype.snapshot = function (a, b) {
var k = this,
d = this._version,
m = new g,
h;
if (b == 0 && this._length != null) return m.fulfill(new p(d,
this._createVersionedAccessor(), new c(a, 0), this._length)), m;
switch (this._loadedState) {
case f.COMPLETE:
h = new c(a, b, Math.max(this._length - a, 0));
m.fulfill(new p(d, this._createVersionedAccessor(), h, this._length));
break;
case f.PARTIAL:
h = new c(a, b, Math.max(this._length - a, 0));
h.findContainer(this._loadedRanges) ? m.fulfill(new p(d, this._createVersionedAccessor(), h, this._length)) : this._fill(h).then(function () {
k.snapshot(a, b).pipe(m)
}).catchError(function (a) {
m.fail(a)
});
break;
case f.UNLOADED:
this._loadLength().then(function (d) {
d.length ?
this._fill(new c(a, b, Math.min(this._snapshotLimit, this._length))).then(function () {
k.snapshot(a, b).pipe(m)
}).catchError(function (a) {
m.fail(a)
}) : (this._loadedState = f.COMPLETE, this.snapshot(a, b).pipe(m))
}.bind(this))
}
return m
};
d.prototype.snapshotRange = function (a) {
return this.snapshot(a.begin, a.length)
};
d.prototype.getLength = function () {
return this.snapshot(0, 0).call("getListLength")
}
})();
(function () {
function d(c, h) {
if (!(this instanceof d)) return new d(c, h);
g.call(this, h);
this.fillFullFromArray(c || [])
}
var g = Spotify.ItemList.Base;
Spotify.inherit(d, g);
Spotify.ItemList.Array = d
})();
(function () {
function d(a) {
if (!(this instanceof d)) return new d(list);
if (!a || !a.length) throw new TypeError("ConcatenatedItemList: Argument `lists` cannot be empty.");
b.call(this);
this._sublists = a.slice(0);
this._offsets = [];
this._ruleset = new f.Immutable
}
var g = Spotify.Promise,
c = Spotify.Shell.Range,
h = Spotify.ItemList,
b = h.Base,
a = h.Snapshot,
f = h.MutationRuleset;
Spotify.inherit(d, b);
Spotify.ItemList.Concatenated = d;
d.prototype._load = function (a) {
for (var b = this._sublists, f = this._offsets, d = [], h = 0, n = f.length; h <
n; h++) {
var s = f[h],
s = new c(s, (h + 1 in f ? f[h + 1] : this._length) - s);
s.intersects(a) && (s = s.intersect(a), d.push(b[h].snapshot(s.begin, s.length)))
}
return g.join(d).then(function (b) {
for (var f = [], c = 0, d = b.length; c < d; c++) f.push.apply(f, b[c].toArray());
return {
range: a,
items: f
}
})
};
d.prototype._loadLength = function () {
for (var a = this._sublists, b = [], f = 0, c = a.length; f < c; f++) {
var d = a[f];
d.observe(this);
b.push(d.snapshot(0, -1))
}
return g.join(b).then(this._processInitialSnapshots.bind(this))
};
d.prototype._processInitialSnapshots =
function (a) {
for (var b = this._list, f = this._offsets, d = this._length = 0, h = a.length; d < h; d++) {
var g = a[d],
s = g.toFullArray(),
t = new c(g.getOffset() + this._length, s.length);
b.insertFrom(t.begin, s);
f[d] = this._length;
this._length += g.getListLength();
this._updateRanges(t);
this._updateState()
}
return {
length: this._length
}
};
d.prototype.onMutate = function (a, b) {
a.length && this._applyMutations(a, b)
};
d.prototype._applyMutations = function (b, f) {
this.notify("onBeforeMutate", new a(this._version, this._createVersionedAccessor(), new c(0,
this._length), this._length));
var d = this._sublists.indexOf(f);
if (d != -1) {
var h = this._offsets[d];
if (h != null) {
for (var g = [], n = 0, s = b.length; n < s; n++) {
var t = b[n],
u = null;
switch (t.type) {
case "insert":
if (u = this._applyInsertMutation({
type: "insert",
begin: h + t.begin,
items: t.items
})) this._incrementOffsets(d + 1, u.items.length), g.push(u);
break;
case "remove":
if (u = this._applyRemoveMutation({
type: "remove",
begin: h + t.begin,
length: t.length
})) this._decrementOffsets(d + 1, u.length), g.push(u);
break;
case "move":
(u = this._applyMoveMutation({
type: "move",
begin: h + t.begin,
end: h + t.end,
length: t.length
})) && g.push(u)
}
}
this._version++;
this.notify("onMutate", g);
return g
}
}
};
d.prototype._incrementOffsets = function (a, b) {
for (var f = this._offsets, c = a, d = f.length; c < d; c++) f[c] += b;
return this
};
d.prototype._decrementOffsets = function (a, b) {
for (var f = this._offsets, c = a, d = f.length; c < d; c++) f[c] -= b;
return this
}
})();
(function () {
function d(c) {
if (!(this instanceof d)) return new d(c);
if (!c) throw Error("Required base argument must not be undefined");
g.call(this, c);
this._base.observe(this)
}
var g = Spotify.ItemList.Base;
Spotify.inherit(d, g);
Spotify.ItemList.Layered = d;
d.prototype.createComparator = function (c, d) {
return this._base.createComparator(c, d)
};
d.prototype.createPredicate = function (c, d, b) {
return this._base.createPredicate(c, d, b)
};
d.prototype.onBeforeMutate = function (c) {
this.notify("onBeforeMutate", c)
};
d.prototype.onMutate =
function (c) {
for (var d = 0, b = c.length; d < b; d++) {
var a = c[d];
switch (a.type) {
case "insert":
this._length += a.items.length;
break;
case "remove":
this._length -= a.length
}
}
this._version++;
this.notify("onMutate", c);
return c
};
d.prototype.createMutator = function () {
return this._base.createMutator()
};
d.prototype.snapshot = function (c, d) {
return this._base.snapshot(c, d)
};
d.prototype.getLength = function () {
var c = this;
return this.snapshot(0, 1).call("getListLength").then(function (d) {
return c._length = d
})
}
})();
(function () {
function d(a, b, c) {
h.call(this, a);
this._range = new g(b, c);
this._baseListLength = 0;
this.makeImmutable()
}
var g = Spotify.Shell.Range,
c = Spotify.ItemList,
h = c.Layered,
b = c.Snapshot;
Spotify.inherit(d, h);
c.Ranged = d;
d.prototype.onBeforeMutate = function (a) {
this._list = a.toArray()
};
d.prototype.onMutate = function (a) {
var b = this;
this.snapshot(0, -1).then(function (c) {
b._applyMutations(a, c)
})
};
d.prototype._applyMutations = function (a, f) {
var c = this._version;
this.notify("onBeforeMutate", new b(c, this._createVersionedAccessor(c,
0, f), new g(0, this._range.length), this._range.length));
for (var c = [], d = 0, h = a.length; d < h; d++) {
var p = a[d],
q = null;
switch (p.type) {
case "insert":
q = this._applyInsertMutation(p);
break;
case "remove":
q = this._applyRemoveMutation(p);
break;
case "move":
q = this._applyMoveMutation(p)
}
q.length && c.push.apply(c, q)
}
this._version++;
this.notify("onMutate", c);
return c
};
d.prototype._applyInsertMutation = function (a) {
var b = this._range,
c = [];
if (a.begin >= b.last) return this._list.spliceWith(a.begin, 0, a.items), c;
var d = new g(a.begin,
a.items.length),
h = this._list.length,
p = Math.max(0, Math.min(b.length, b.last - h)),
d = (new g(0, b.last)).intersect(d).length,
h = Math.max(0, b.begin - h),
h = Math.min(b.length, d - h),
d = Math.max(0, h - p),
p = b.last - d - p;
d > 0 && c.push({
type: "remove",
begin: p - b.begin,
length: d
});
this._list.spliceWith(a.begin, 0, a.items);
h > 0 && (a = Math.max(0, a.begin - b.begin), b = a + b.begin, c.push({
type: "insert",
begin: a,
items: this._list.slice(b, b + h)
}));
return c
};
d.prototype._applyRemoveMutation = function (a) {
var b = this._range,
c = null,
d = [];
if (a.begin >=
a.last) return this._list.spliceWith(a.begin, a.length), d;
var c = this._list.length,
h = c - a.length,
g = Math.max(0, c - b.begin),
h = Math.max(0, h - b.begin),
c = Math.max(0, a.begin - b.begin),
c = Math.min(g - h, b.length - c),
q = Math.min(b.length, g) - c,
g = b.length - q,
h = Math.min(g, h - q);
c > 0 && (c = {
type: "remove",
begin: Math.max(0, a.begin - b.begin),
length: c
}, d.push(c));
this._list.spliceWith(a.begin, a.length);
h > 0 && (a = b.length - g, b = a + b.begin, c = {
type: "insert",
begin: a,
items: this._list.slice(b, b + h)
}, d.push(c));
return d
};
d.prototype._applyMoveMutation =
function (a) {
var b = [],
c = {
type: "remove",
begin: a.begin,
length: a.length
}, d = a.end;
d > a.begin && (d -= a.length);
a = {
type: "insert",
begin: d,
items: this._list.slice(a.begin, a.begin + a.length)
};
d = null;
d = this._applyRemoveMutation(c);
d.length && b.push.apply(b, d);
d = this._applyInsertMutation(a);
d.length && b.push.apply(b, d);
return b
};
d.prototype.snapshot = function (a, f) {
var c = this,
d = this._base,
h = this._range,
p = this._version,
q = new g(h.begin + (a || 0), f, h.length - a);
return d.snapshot(q.begin, q.length).then(function (d) {
var m = c._createVersionedAccessor(p,
a, d),
q = new g(a, f, Math.min(h.length, d.getLength())),
d = Math.min(d.getListLength(), h.length);
return new b(p, m, q, d)
})
};
d.prototype._createVersionedAccessor = function (a, b, c) {
var d = this;
return function (a, h) {
if (d._version != a) throw Error("Cannot access item with an expired snapshot.");
return c.get(h - b)
}
}
})();
(function () {
function d(a, b) {
m.call(this, a);
this._baseList = [];
this._sortedList = null;
this._rawComparator = b || k.forString();
this._comparator = this._wrapComparator(this._rawComparator);
this._ruleset = new p({
insert: q.FORBIDDEN,
move: q.FORBIDDEN
});
this._init()
}
function g(a, b, f) {
this._baseList = a.slice(0);
this._sortedList = b.slice(0);
this._length = a.length;
this._rawComparator = this._comparator = f;
this._version = 0
}
function c(a, b, f, k, d, m, h) {
if (!(this instanceof c)) return new c(a);
n.call(this, null, k, d, m, h);
this._baseMutator =
a;
this._resolveIndex = f;
this._mutationMock = b
}
var h = Array.prototype.slice,
b = Spotify.Promise,
a = Spotify.Shell.Range,
f = Spotify.ItemList,
k = f.Comparators,
m = f.Layered,
o = f.LoadedState,
p = f.MutationRuleset,
q = f.MutationResult,
n = f.Mutator,
s = f.Snapshot;
Spotify.inherit(d, m);
Spotify.ItemList.Sorted = d;
d.prototype._init = function () {
this._base.snapshot(0, -1).then(this._buildInitial.bind(this)).catchError(function () {})
};
d.prototype._wrapComparator = function (a) {
var b = this._baseList;
return function (f, c) {
var k = a(b[f], b[c]);
return k == 0 ? f - c : k
}
};
d.prototype._buildInitial = function (a) {
this._length = a.getListLength();
this._baseList.spliceWith(0, 0, a.toArray());
this._sortInitial();
this._unqueueSnapshots()
};
d.prototype._sortInitial = function () {
for (var a = this._baseList.length, b = this._sortedList = Array(a); a--;) b[a] = a;
b.sort(this._comparator);
this._loadedState = o.COMPLETE
};
d.prototype.snapshot = function (f, c) {
var k = new b,
d = new a(f, c, Math.max(this._length - f, 0));
this._loadedState != o.COMPLETE ? this._queueSnapshot(f, c, k) : (d = new s(this._version,
this._createVersionedAccessor(), d, this._length), k.fulfill(d));
return k
};
d.prototype._createVersionedAccessor = function () {
var a = this,
b = this._baseList,
c = this._sortedList;
return function (k, d) {
if (a._version != k) throw Error("Cannot access item with an expired snapshot.");
return d in c ? b[c[d]] : f.NULL_VALUE
}
};
d.prototype._createIndexResolver = function () {
var a = this._sortedList;
return function (b) {
return b in a ? a[b] : f.NULL_VALUE
}
};
d.prototype._createMutationMock = function () {
return new g(this._baseList, this._sortedList,
this._rawComparator)
};
d.prototype.createMutator = function () {
var a = this._base.createMutator();
if (!a) return null;
var b = this._createMutationMock(),
f = this._createIndexResolver(),
k = this._createVersionComparator();
return new c(a, b, f, k, this._ruleset, this._version, this._length)
};
d.prototype.onMutate = function (a) {
a.length && this._applyMutations(a)
};
d.prototype._applyMutations = function (b) {
this.notify("onBeforeMutate", new s(this._version, this._createVersionedAccessor(), new a(0, this._length), this._length));
for (var f = [], c = 0, k = b.length; c < k; c++) {
var d = b[c],
m = null,
h, g, o;
switch (d.type) {
case "remove":
h = d.begin;
g = d.length;
for (d = 0, o = g; d < o; d++) m = {
type: "remove",
begin: h,
length: 1
}, (m = this._applyRemoveMutation(m)) && f.push(m);
break;
case "move":
m = this._applyMoveMutation(d);
m.length && f.push.apply(f, m);
break;
case "insert":
h = d.begin;
g = d.items;
for (d = 0, o = g.length; d < o; d++) m = h + d, m = {
type: "insert",
begin: m,
items: [g[d]]
}, (m = this._applyInsertMutation(m)) && f.push(m)
}
}
this._version++;
this.notify("onMutate", f);
return f
};
d.prototype._getInsertionIndex =
function (a, b) {
var f = this._baseList,
c = this._sortedList,
k = this._length,
d = this._rawComparator,
m = 0,
h = k - 1,
g = a,
o = 0;
if (k == 0) return 0;
if (k == 1) return k = d(b, f[0]), k == 0 ? a > 0 ? 1 : -1 : k > 0 ? 1 : 0;
for (; m <= h;)
if (g = Math.floor((m + h) / 2), k = d(b, f[c[g]]), k > 0) m = g + 1, o = 1;
else if (k < 0) h = g - 1, o = 0;
else {
if (a == c[g]) break;
else a > c[g] ? g += 1 : g -= 1, o = 1;
break
}
return g + o
};
d.prototype._applyInsertMutation = function (a) {
var b = a.begin,
a = a.items[0],
f = this._baseList,
c = this._sortedList,
k = {
type: "insert",
begin: b,
items: [a]
}, d = this._getInsertionIndex(b, a);
this._incrementSortedIndices(b);
c.splice(d, 0, b);
k.begin = d;
f.splice(b, 0, a);
this._length++;
return k
};
d.prototype._incrementSortedIndices = function (a) {
for (var a = a || 0, b = this._sortedList, f = 0, c = b.length; f < c; f++) b[f] >= a && b[f]++
};
d.prototype._decrementSortedIndices = function (a) {
for (var a = a || 0, b = this._sortedList, f = 0, c = b.length; f < c; f++) b[f] >= a && b[f]--
};
d.prototype._applyRemoveMutation = function (a) {
var a = a.begin,
b = this._baseList,
f = this._sortedList,
c = f.indexOf(a);
f.splice(f.indexOf(a), 1);
this._decrementSortedIndices(a);
b.splice(a, 1);
this._length--;
return {
type: "remove",
begin: c,
length: 1
}
};
d.prototype._applyMoveMutation = function (a) {
for (var b = this._baseList, f = this._sortedList, c = a.begin, k = a.end, d = [], m = 0, a = a.length; m < a; m++) {
var h = f.indexOf(c),
g = b[c],
o = h;
k < c ? (b.splice(c, 1), b.splice(k, 0, g), this._decrementSortedIndices(c), this._incrementSortedIndices(k), f.splice(h, 1), o = this._getInsertionIndex(k, g), f.splice(o, 0, k), k++, c++) : k > c && (b.splice(k, 0, g), b.splice(c, 1), this._incrementSortedIndices(k), this._decrementSortedIndices(c),
f.splice(h, 1), o = this._getInsertionIndex(k - 1, g), f.splice(o, 0, k - 1));
o > h && o++;
h != o && d.push({
type: "move",
begin: h,
end: o,
length: 1
})
}
return d
};
g.prototype.applyMutations = function (a) {
a = Array.isArray(a) ? a : h.call(arguments);
return this._applyMutations(a)
};
g.prototype.notify = function () {};
g.prototype._createVersionedAccessor = function () {};
g.prototype._applyMutations = d.prototype._applyMutations;
g.prototype._getInsertionIndex = d.prototype._getInsertionIndex;
g.prototype._incrementSortedIndices = d.prototype._incrementSortedIndices;
g.prototype._decrementSortedIndices = d.prototype._decrementSortedIndices;
g.prototype._applyInsertMutation = d.prototype._applyInsertMutation;
g.prototype._applyRemoveMutation = d.prototype._applyRemoveMutation;
Spotify.inherit(c, n);
c.prototype.apply = function () {
return this._baseMutator.apply()
};
c.prototype.add = function (a, b) {
var f = this.canAdd(a.length);
if (f != q.ALLOWED) return f;
if (!a.length) return q.SUCCESS;
var f = this._baseMutator,
c = f.canAdd(a.length);
if (c != q.ALLOWED) return c;
c = [];
f.add(a, c);
f = this._mutationMock.applyMutations(c);
b && b.push.apply(b, f);
return q.SUCCESS
};
c.prototype.remove = function (a, b, f) {
var c = this.canRemove(a, b);
if (c != q.ALLOWED) return c;
if (b == 0) return q.SUCCESS;
for (var c = this._baseMutator, d = [], m = 0; m < b; m++) {
var h = this._resolveIndex(a + m),
g = c.canRemove(h, 1);
if (g != q.ALLOWED) return g;
d.push(h)
}
d.sort(k.forNumber());
m = [];
for (h = 0; h < b; h++) c.remove(d[h] - h, 1, m);
this._length -= b;
this._mutationMock.applyMutations(m);
a = {
type: "remove",
begin: a,
length: b
};
f && f.push(a);
return q.SUCCESS
}
})();
(function () {
function d(a, b) {
f.call(this, a);
this._baseList = [];
this._loadedBaseRanges = [];
this._predicate = b
}
function g(a, b, f, c) {
this._baseList = a.slice(0);
this._list = b.slice(0);
this._length = f;
this._predicate = c;
this._version = 0
}
function c(a, b, f, k, d, m, h) {
if (!(this instanceof c)) return new c(a);
o.call(this, null, k, d, m, h);
this._baseMutator = a;
this._resolveIndex = f;
this._mutationMock = b
}
var h = Spotify.Promise,
b = Spotify.Shell.Range,
a = Spotify.ItemList,
f = a.Layered,
k = a.LoadedState,
m = a.MutationResult,
o = a.Mutator,
p = a.Snapshot;
Spotify.inherit(d, f);
Spotify.ItemList.Filtered = d;
d.prototype._buildList = function (f, c) {
for (var d = this._list, m = d.length, h = 0, g = this._predicate, o = 0, p = c.length; o < p; o++) {
var x = c[o];
x != a.NULL_VALUE && g(x) && (d.push(f.begin + o), h++)
}
h && this._updateRanges(new b(m, h));
this._baseList.insertFrom(f.begin, c);
m = this._loadedBaseRanges;
m.push(f);
this._loadedBaseRanges = m = b.simplify(m);
m.length == 1 && m[0].length >= this._baseLength ? (this._length = d.length, this._loadedState = k.COMPLETE) : this._loadedState = k.PARTIAL;
return this
};
d.prototype._createVersionedAccessor = function (b, f) {
var c = this,
k = this._list;
return function (d, m) {
return c._version != d ? a.NULL_VALUE : m in k ? f[k[m] - b] : a.NULL_VALUE
}
};
d.prototype._snapshot = function (a, f, c) {
var d = this,
m = new h,
g = new b(a, f),
o, A;
switch (this._loadedState) {
case k.COMPLETE:
if (f == -1) f = this._length;
o = this._list.slice(a, a + f);
A = (new b(o[0], 0)).add(new b(o[o.length - 1], 1));
this._base.snapshotRange(A).then(function (f) {
f = new p(d._version, d._createVersionedAccessor(A.begin, f.toFullArray()), new b(a, o.length),
d._length);
m.fulfill(f)
});
break;
case k.PARTIAL:
if (g.findContainer(this._loadedRanges)) {
if (f == -1) f = this._length;
o = this._list.slice(a, a + f);
A = (new b(o[0], 0)).add(new b(o[o.length - 1], 1));
this._base.snapshotRange(A).then(function (f) {
f = new p(d._version, d._createVersionedAccessor(A.begin, f.toFullArray()), new b(a, o.length), o.length);
m.fulfill(f)
})
} else f = this._loadedBaseRanges[this._loadedBaseRanges.length - 1], f = new b(f.last, 10 * c), this._base.snapshotRange(f).then(function (a) {
d._buildList(new b(a.getOffset(),
a.getLength()), a.toFullArray());
d._snapshot(g.begin, g.length, ++c).pipe(m)
});
break;
case k.UNLOADED:
this._base.snapshotRange(new b(0, g.last - g.begin + 10 * c)).then(function (a) {
d._length = d._baseLength = a.getListLength();
d._buildList(new b(a.getOffset(), a.getLength()), a.toFullArray());
d._snapshot(g.begin, g.length, ++c).pipe(m)
})
}
return m
};
d.prototype.snapshot = function (a, b) {
return this._snapshot(a, b, 1)
};
d.prototype.onBeforeMutate = function (a) {
this._baseList = a.toFullArray()
};
d.prototype.onMutate = function (a) {
a.length &&
this._applyMutations(a)
};
d.prototype._applyMutations = function (a) {
this.notify("onBeforeMutate", new p(this._version, this._createVersionedAccessor(0, this._baseList), new b(0, this._length), this._length));
for (var f = [], c = 0, k = a.length; c < k; c++) {
var d = a[c],
m = null;
switch (d.type) {
case "insert":
m = this._applyInsertMutation(d);
break;
case "remove":
m = this._applyRemoveMutation(d);
break;
case "move":
m = this._applyMoveMutation(d)
}
m && f.push(m)
}
this._version++;
this.notify("onMutate", f);
return f
};
d.prototype._applyInsertMutation =
function (a) {
var b = this._list,
f = a.begin,
c = a.items;
if (!c.length) return null;
var k = this._filterMutationItems(c),
a = k.items,
k = k.indices,
d = this._findInsertionIndex(f);
this._updateIndices(d, b.length, c.length);
for (var c = 0, m = k.length; c < m; c++) b.splice(d + c, 0, f + k[c]);
this._length += k.length;
return {
type: "insert",
begin: d,
items: a
}
};
d.prototype._applyRemoveMutation = function (a) {
var b = this._list,
f = a.begin,
a = a.length,
c = f + a;
if (!a) return null;
for (var k = -1, d = 0, m = 0, h = b.length; m < h; m++) {
var g = b[m];
g >= c ? b[m] -= a : g >= f && (k == -1 &&
(k = m), d++)
}
b.splice(k, d);
this._length -= d;
return {
type: "remove",
begin: k,
length: d
}
};
d.prototype._applyMoveMutation = function (a) {
var f = this._list,
c = a.begin,
k = a.end,
a = a.length;
if (c == k) return null;
var d = this._getIndicesInRange(new b(c, a)),
m = this._findInsertionIndex(c),
h = this._findInsertionIndex(k);
c < k ? (c = k - c - a, this._updateIndices(m + d.length, h, -a), f.spliceWith(h, 0, d), f.splice(m, d.length), this._updateIndices(h - d.length, h, c)) : (c = k - c, this._updateIndices(h, m, a), f.splice(m, d.length), f.spliceWith(h, 0, d), this._updateIndices(h,
h + d.length, c));
return m == h ? null : {
type: "move",
begin: m,
end: h,
length: d.length
}
};
d.prototype._filterMutationItems = function (a) {
for (var b = [], f = [], c = this._predicate, k = 0, d = a.length; k < d; k++) {
var m = a[k];
c(m) && (b.push(m), f.push(k))
}
return {
items: b,
indices: f
}
};
d.prototype._findInsertionIndex = function (a) {
for (var b = this._list, f = 0, c = b.length; f < c; f++)
if (b[f] >= a) return f;
return c
};
d.prototype._getIndicesInRange = function (a) {
for (var b = this._list, f = [], c = 0, k = b.length; c < k; c++) {
var d = b[c];
a.has(d) && f.push(d)
}
return f
};
d.prototype._createMutationMock =
function () {
return new g(this._baseList, this._list, this._length, this._predicate)
};
d.prototype.createMutator = function () {
var a = this._base.createMutator();
if (!a) return null;
var b = this._createMutationMock(),
f = this._createIndexResolver(),
k = this._createVersionComparator();
return new c(a, b, f, k, this._ruleset, this._version, this._length)
};
d.prototype._createIndexResolver = function () {
var b = this._list;
return function (f) {
return f in b ? b[f] : a.NULL_VALUE
}
};
d.prototype._updateIndices = function (a, b, f) {
for (var c = this._list; a <
b; a++) c[a] += f
};
g.prototype.applyMutations = function (a) {
a = Array.isArray(a) ? a : slice.call(arguments);
return this._applyMutations(a)
};
g.prototype.notify = function () {};
g.prototype._createVersionedAccessor = function () {};
g.prototype._applyMutations = d.prototype._applyMutations;
g.prototype._applyInsertMutation = d.prototype._applyInsertMutation;
g.prototype._applyRemoveMutation = d.prototype._applyRemoveMutation;
g.prototype._applyMoveMutation = d.prototype._applyMoveMutation;
g.prototype._filterMutationItems = d.prototype._filterMutationItems;
g.prototype._findInsertionIndex = d.prototype._findInsertionIndex;
g.prototype._getIndicesInRange = d.prototype._getIndicesInRange;
g.prototype._updateIndices = d.prototype._updateIndices;
Spotify.inherit(c, o);
Spotify.ItemList.Mutator.Filtered = c;
c.prototype.apply = function () {
return this._baseMutator.apply()
};
c.prototype.add = function (a, b) {
var f = this.canAdd(a.length);
if (f != m.ALLOWED) return f;
if (!a.length) return m.SUCCESS;
var f = this._baseMutator,
c = f.canAdd(a.length);
if (c != m.ALLOWED) return c;
c = [];
f.add(a, c);
f =
this._mutationMock.applyMutations(c);
b && b.push.apply(b, f);
return m.SUCCESS
};
c.prototype.insert = function (a, b, f) {
var c = this.canInsert(a, b.length);
if (c != m.ALLOWED) return c;
if (!b.length) return m.SUCCESS;
var a = this._resolveIndex(a),
c = this._baseMutator,
k = c.canInsert(a, b.length);
if (k != m.ALLOWED) return k;
k = [];
c.insert(a, b, k);
b = this._mutationMock.applyMutations(k);
this._length = this._mutationMock._length;
f && f.push.apply(f, b);
return m.SUCCESS
};
c.prototype.remove = function (a, b, f) {
var c = this.canRemove(a, b);
if (c !=
m.ALLOWED) return c;
if (b == 0) return m.SUCCESS;
for (var c = this._baseMutator, k = [], d = 0; d < b; d++) {
var h = this._resolveIndex(a + d),
g = c.canRemove(h, 1);
if (g != m.ALLOWED) return g;
k.push(h)
}
k.sort(function (a, b) {
return a - b
});
d = [];
for (h = 0; h < b; h++) c.remove(k[h] - h, 1, d);
this._length -= b;
this._mutationMock.applyMutations(d);
a = {
type: "remove",
begin: a,
length: b
};
f && f.push(a);
return m.SUCCESS
};
c.prototype.move = function (a, b, f, c) {
var k = this.canMove(a, b, f);
if (k != m.ALLOWED) return k;
if (a == b || f == 0) return m.SUCCESS;
for (var k = this._baseMutator,
d = [], h = 0; h < f; h++) {
var g = this._resolveIndex(a + h),
o = k.canMove(g, a, 1);
if (o != m.ALLOWED) return o;
d.push(g)
}
for (var h = this._resolveIndex(b), g = [], o = 0, p = d.length; o < p; o++) k.move(d[o] - o, h, 1, g);
this._mutationMock.applyMutations(g);
a = {
type: "move",
begin: a,
end: b,
length: f
};
c && c.push(a);
return m.SUCCESS
}
})();
(function () {
function d() {
this.type = null
}
function g(a) {
if (!(this instanceof g)) return new g(a);
if (!a) throw Error("Invalid arguments.");
this.type = "list";
this.uri = a
}
function c(a) {
if (!(this instanceof c)) return new c(uri);
if (!a) throw Error("Invalid arguments.");
this.lists = a;
this.type = "concatenate"
}
function h(a, b, f) {
if (!(this instanceof h)) return new h(uri);
if (b == void 0 || a == void 0 || f == void 0) throw Error("Invalid arguments.");
this.args = b;
this.list = a;
this.type = "sort";
this.version = f;
this.field = b[0];
this.order =
b[1]
}
function b(a, f, c) {
if (!(this instanceof b)) return new b(uri);
if (f == void 0 || a == void 0 || c == void 0) throw Error("Invalid arguments.");
this.args = f;
this.list = a;
this.type = "filter";
this.version = c;
this.operator = f[0];
this.field = f[1];
this.matcher = f[2]
}
function a(b, f, c) {
if (!(this instanceof a)) return new a(uri);
if (f == void 0 || b == void 0 || c == void 0) throw Error("Invalid arguments.");
this.args = f;
this.list = b;
this.type = "range";
this.version = c;
this.offset = f[0];
this.length = f[1]
}
function f(a, b, c) {
if (!(this instanceof f)) return new f(uri);
if (b == void 0 || a == void 0 || c == void 0) throw Error("Invalid arguments.");
this.args = b;
this.list = a;
this.type = "shuffle";
this.version = c;
this.seed = b[0]
}
Spotify.ItemList.Descriptor = {};
Spotify.ItemList.Descriptor.from = function (a) {
return !a ? null : typeof descriptor == "string" ? this.fromString(a) : this.fromObject(a)
};
Spotify.ItemList.Descriptor.fromString = function (a) {
try {
var b = this.fromObject(JSON.parse(a));
return b instanceof d ? b : null
} catch (f) {
return null
}
};
Spotify.ItemList.Descriptor.fromObject =
function (k) {
if (k instanceof d) return k;
try {
switch (k.type) {
case "list":
return new g(k.uri);
case "concatenate":
for (var o = [], p = 0, q = k.lists.length; p < q; p++) {
var n = this.fromObject(k.lists[p]);
if (!n) return null;
o.push(n)
}
return new c(o);
case "sort":
return new h(this.fromObject(k.list), k.args, k.version);
case "filter":
return new b(this.fromObject(k.list), k.args, k.version);
case "range":
return new a(this.fromObject(k.list), k.args, k.version);
case "shuffle":
return new f(this.fromObject(k.list), k.args, k.version);
default:
return null
}
} catch (s) {
return null
}
};
Spotify.ItemList.Descriptor.occludeFields = function (a, b) {
return a == "operator" || a == "field" || a == "matcher" || a == "offset" || a == "length" || a == "seed" || a == "order" ? void 0 : b
};
Spotify.ItemList.Descriptor.Base = d;
var k = Spotify.ItemList.Descriptor.occludeFields;
d.prototype.serialize = function () {
return JSON.stringify(this, k)
};
g.prototype = new d;
Spotify.ItemList.Descriptor.List = g;
c.prototype = new d;
Spotify.ItemList.Descriptor.Concatenated = c;
h.prototype = new d;
Spotify.ItemList.Descriptor.Sorted =
h;
b.prototype = new d;
Spotify.ItemList.Descriptor.Filtered = b;
a.prototype = new d;
Spotify.ItemList.Descriptor.Ranged = a;
f.prototype = new d;
Spotify.ItemList.Descriptor.Shuffled = f
})();
(function () {
function d(a, f) {
b.call(this, a);
this._index = -1;
this._loadLimit = f || 10;
this._infinite = !1;
this._callQueue = [];
this._init()
}
var g = Spotify.Promise,
c = Spotify.Shell.Range,
h = Spotify.ItemList,
b = h.Layered,
a = h.LoadedState,
f = h.Snapshot;
Spotify.inherit(d, b);
Spotify.ItemList.Iterable = d;
d.prototype._init = function () {
this._loadLength().then(this._unqueueCalls.bind(this))
};
d.prototype._queueCall = function () {
var a = new g,
b = this._queueCall.caller;
this._callQueue.push({
fn: b,
args: b.arguments,
promise: a
});
return a
};
d.prototype._unqueueCalls = function () {
for (var a = this._callQueue, b = 0, f = a.length; b < f; b++) {
var c = a[b];
c.fn.apply(this, c.args).pipe(c.promise)
}
};
d.prototype._load = function (a) {
return this._base.snapshotRange(a).then(function (a) {
return {
range: new c(a.getOffset(), a.getLength()),
items: a.toArray()
}
})
};
d.prototype._loadLength = function () {
var b = this;
return this._base.getLength().then(function (f) {
b._length = f;
b._loadedState = a.PARTIAL;
return {
length: f
}
})
};
d.prototype.makeInfinite = function () {
this._infinite = !0
};
d.prototype.makeFinite =
function () {
this._infinite = !1
};
d.prototype.startAt = function (b) {
if (this._loadedState == a.UNLOADED) return this._queueCall();
var f = new g;
this._index = b == -1 || b > this._length ? this._length : b < 0 ? -1 : b - 1;
f.fulfill(!0);
return f
};
d.prototype.rewind = function () {
this._index = -1;
return this
};
d.prototype.getIndex = function () {
var a = this._index;
return a < 0 ? h.LIST_START : a >= this._length ? h.LIST_END : a
};
d.prototype.preload = function (b) {
if (this._loadedState == a.UNLOADED) return this._queueCall();
var f = this._loadLimit,
b = new c((b == void 0 ?
0 : b) - f, (f || 1) * 2);
b.begin < 0 && (b = b.subtract(new c(0, 0)), b = b[1].add(new c(b[1].last, b[0].length)));
return this._fill(b).then(function () {
return !0
}, function () {
return !1
})
};
d.prototype.hasNext = function () {
if (this._loadedState == a.UNLOADED) return this._queueCall();
var b = this._index,
f = new g;
return this._infinite ? (f.fulfill(!0), f) : b + 1 >= this.length ? (f.fulfill(!1), f) : this.snapshot(b + 1, 1).then(function (a) {
return a.get(0) !== h.NULL_VALUE
}, function () {
return !1
})
};
d.prototype.hasPrevious = function () {
if (this._loadedState ==
a.UNLOADED) return this._queueCall();
var b = this._index,
f = new g;
return this._infinite ? (f.fulfill(!0), f) : b - 1 < 0 ? (f.fulfill(!1), f) : this.snapshot(b - 1, 1).then(function (a) {
return a.get(0) !== h.NULL_VALUE
}, function () {
return !1
})
};
d.prototype.next = function () {
if (this._loadedState == a.UNLOADED) return this._queueCall();
var b = this._index;
if (this._infinite && b + 1 == this._length) this._index = b = 0;
else if (b + 1 > this._length - 1) return this._index = b = this._length, b = new g, b.fulfill(h.LIST_END), b;
else this._index = b += 1;
return this.snapshot(b,
1).then(function (a) {
a = a.get(0);
return a == h.NULL_VALUE ? h.LIST_END : a
}, function () {
return h.LIST_END
})
};
d.prototype.previous = function () {
if (this._loadedState == a.UNLOADED) return this._queueCall();
var b = this._index;
if (this._infinite && b - 1 == -1) this._index = b = this._length - 1;
else if (b - 1 < 0) return this._index = b = -1, b = new g, b.fulfill(h.LIST_START), b;
else this._index = b -= 1;
return this.snapshot(b, 1).then(function (a) {
a = a.get(0);
return a == h.NULL_VALUE ? h.LIST_START : a
}, function () {
return h.LIST_START
})
};
d.prototype.pop =
function () {
var b = this;
if (this._loadedState == a.UNLOADED) return this._queueCall();
var f = new g;
this.snapshot(0, 1).then(function (a) {
var c = b._base.createMutator(),
d = a.get(0);
d == h.NULL_VALUE || c.canRemove(0, 1) != h.MutationResult.ALLOWED ? f.fulfill(h.NULL_VALUE) : (c.remove(0, 1), c.apply().then(function (a) {
a == h.MutationResult.SUCCESS ? f.fulfill(d) : f.fulfill(h.NULL_VALUE)
}, function () {
f.fulfill(h.NULL_VALUE)
}))
}, function () {
f.fulfill(h.NULL_VALUE)
});
return f
};
d.prototype.onMutate = function (a) {
a.length && this._applyMutations(a)
};
d.prototype._applyMutations = function (a) {
this.notify("onBeforeMutate", new f(this._version, this._createVersionedAccessor(), new c(0, this._length), this._length));
if (this._index != -1)
for (var b = 0, d = a.length; b < d; b++) {
var h = a[b];
switch (h.type) {
case "insert":
this._applyInsertMutation(h);
break;
case "remove":
this._applyRemoveMutation(h);
break;
case "move":
this._applyMoveMutation(h)
}
}
this._version++;
this.notify("onMutate", a);
return a
};
d.prototype._applyInsertMutation = function (a) {
var b = a.begin,
f = a.items.length;
if (!f) return a;
this._length += f;
b <= this._index + 1 && (this._index += f + 1);
return a
};
d.prototype._applyRemoveMutation = function (a) {
var b = a.begin,
f = a.length;
if (!f) return a;
var d = new c(b, f);
this._length -= f;
b == this._index ? this._index-- : d.has(this._index) ? this._index = b - 1 : b < this._index && (this._index -= f);
return a
};
d.prototype._applyMoveMutation = function (a) {
var b = a.begin,
f = a.end,
d = a.length;
if (!d) return a;
var h = new c(b, d);
h.has(this._index + 1) ? this._index = h.end + (this._index - h.begin) : b > f ? this._index += d : this._index -=
d;
return a
}
})();
(function () {
function d(a, f) {
this._property = a;
this._baseSnapshot = f;
this._range = new b(f.getOffset(), f.getLength());
this._version = f.getVersion();
this._listLength = f.getListLength()
}
function g(a, b) {
if (!(this instanceof g)) return new g(a, b);
if (!b) throw new TypeError("PropertyItemList: Argument property must not be undefined.");
h.call(this, a);
this._property = b
}
var c = Spotify.ItemList,
h = c.Layered,
b = Spotify.Shell.Range;
Spotify.inherit(d, c.Snapshot);
Spotify.ItemList.PropertySnapshot = d;
d.prototype.get = function (a) {
var b =
this._property,
a = this._baseSnapshot.get(a);
a != c.NULL_VALUE && (a = b in a ? a[b] : c.NULL_VALUE);
return a
};
Spotify.inherit(g, h);
Spotify.ItemList.Property = g;
g.prototype.onBeforeMutate = function (a) {
this.notify("onBeforeMutate", new d(this._property, a))
};
g.prototype.onMutate = function (a) {
a.length && this._applyMutations(a)
};
g.prototype._applyMutations = function (a) {
for (var b = [], k = 0, d = a.length; k < d; k++) {
var h = a[k];
switch (h.type) {
case "insert":
for (var g = this._property, q = h.items, n = q.length, s = Array(n); n--;) s[n] = g in q[n] ?
q[n][g] : c.NULL_VALUE;
this._length += n;
b.push({
type: "insert",
begin: h.begin,
items: s
});
break;
case "remove":
this._length -= h.length;
b.push(h);
break;
case "move":
b.push(h)
}
}
this._version++;
this.notify("onMutate", b);
return b
};
g.prototype.snapshot = function (a, b) {
var c = this._property;
return this._base.snapshot(a, b).then(function (a) {
return new d(c, a)
})
}
})();
(function () {
function d(c) {
if (!(this instanceof d)) return new d(c);
this.uri = c.toString()
}
var g = Spotify.Utils;
Spotify.Shell.Entities = {};
Spotify.Shell.Entities.Base = d;
Spotify.Shell.Entities.createImages = function (c, d) {
for (var d = d || "", b = null, a = [], f = 0, k = c.length; f < k; f++) {
var m = c[f];
if (m.file_id) {
var o = d + g.str2hex(m.file_id);
a.push([m.width < m.height ? m.width : m.height, o]);
!b && m.size.toLowerCase() == "default" && (b = o)
}
}!b && a.length && (b = a[0][1]);
a.sort(function (a, b) {
return a[0] - b[0]
});
return {
image: b,
images: a
}
};
Spotify.Shell.Entities.createSearchImages = function (c, d) {
for (var d = d || "", b = null, a = [], f = {
small: 120,
large: 640,
"default": 300
}, k = 0, m = c.length; k < m; k++) {
var g = c[k];
if (g.file_id) {
var p = d + g.file_id;
a.push([f[g.size.toLowerCase()], p]);
!b && g.size.toLowerCase() == "default" && (b = p)
}
}!b && a.length && (b = a[0][1]);
a.sort(function (a, b) {
return a[0] - b[0]
});
return {
image: b,
images: a
}
}
})();
(function () {
function d(b, a) {
if (!(this instanceof d)) return new d(b, a);
this.uri = b.toString();
a && this._fill(a)
}
var g = Spotify.Link,
c = Spotify.Promise,
h = Spotify.Shell.Entities;
Spotify.Shell.Entities.Album = d;
d.prototype._fill = function (b) {
var a, f;
this.artistName = "";
this.artists = [];
this.availability = b.availability;
this.copyrights = [];
this.date = b.date || {};
this.discs = [];
this.image = null;
this.images = [];
this.label = b.label;
this.name = b.name;
this.playable = b.playable;
this.popularity = b.popularity;
this.type = (b.type ||
"").toLowerCase();
var c = b.artist,
d = this.artists = [],
o = [];
this.artistName = "";
if (c && c.length) {
for (a = 0, f = c.length; a < f; a++) {
var p = c[a];
d.push({
uri: g.artistLink(p.id).toString(),
name: p.name
});
o.push(p.name)
}
this.artistName = o.join(";")
}
if (a = b.cover_group && b.cover_group.image) a = h.createImages(a, b.resourceUrl), this.image = a.image, this.images = a.images;
c = this.discs;
if (d = b.disc) {
o = g.fromString(this.uri);
for (a = 0, f = d.length; a < f; a++) {
p = d[a];
o.disc = p.number;
for (var q = [], n = 0, s = p.track.length; n < s; n++) q.push(g.trackLink(p.track[n].id).toString());
c.push({
album: this.uri,
number: p.number,
tracks: q,
uri: o.toString()
})
}
}
if (b = b.copyright) {
c = this.copyrights;
for (a = 0, f = b.length; a < f; a++) {
var t = b[a];
c[a] = t.text.replace(/^(\([A-Z]+\))?(.*)$/, function (a, b, f) {
return b ? a : "(" + t.type + ") " + f
})
}
}
};
d.create = function (b, a) {
var f = new c;
try {
f.fulfill(new d(b, a))
} catch (k) {
f.fail(k)
}
return f
};
d.createComparator = function () {
return null
};
d.createPredicate = function () {
return null
}
})();
(function () {
function d(b, a) {
if (!(this instanceof d)) return new d(b, a);
this.uri = b.toString();
a && this._fill(a)
}
var g = Spotify.Link,
c = Spotify.Promise,
h = Spotify.Shell.Entities;
Spotify.Shell.Entities.Artist = d;
d.prototype._fill = function (b) {
var a, f, c, d;
this.name = b.name;
this.popularity = b.popularity;
this.image = null;
this.images = [];
this.genres = [];
this.biography = "";
this.portraits = [];
this.years = null;
if (b.genre) this.genres = b.genre.slice();
if (c = b.portrait_group && b.portrait_group.image) c = h.createImages(c, b.resourceUrl),
this.image = c.image, this.images = c.images;
if ((c = b.biography) && c.length)
for (d = c.length; d--;) {
a = c[d];
if (a.text) this.biography = a.text;
if (a.portrait_group) {
var g = a.portrait_group;
for (a = 0, f = g.length; a < f; a++) {
var p = g[a] && g[a].image;
p && (p = h.createImages(p, b.resourceUrl), p.image && this.portraits.push(p.image))
}
}
}
if ((a = b.activity_period) && a.length) {
f = [];
for (c = 0, d = a.length; c < d; c++) p = a[c], g = p.start_year || p.decade, p = p.end_year || p.decade + 9, isNaN(p) && (p = (new Date).getFullYear()), f.push({
start: g,
end: p
});
if (f.length) this.years = {
from: f[0].start,
to: f[f.length - 1].end
}
}
this.getAlbumGroups = this.getAlbumGroups.bind(this, b);
this.getAppearsOnGroups = this.getAppearsOnGroups.bind(this, b);
this.getSingleGroups = this.getSingleGroups.bind(this, b);
this.getRelatedArtists = this.getRelatedArtists.bind(this, b);
this.getTopTracks = this.getTopTracks.bind(this, b)
};
d.prototype.getAlbumGroups = function (b) {
var a = [],
f = b.album_group;
if (f && f.length)
for (var c = 0, d = f.length; c < d; c++) {
for (var h = f[c], b = [], p = 0, q = h.length; p < q; p++) b.push(g.albumLink(h[p].id).toURI());
a.push(b)
}
return a
};
d.prototype.getAppearsOnGroups = function (b) {
var a = [],
f = b.appears_on_group;
if (f && f.length)
for (var c = 0, d = f.length; c < d; c++) {
for (var h = f[c], b = [], p = 0, q = h.length; p < q; p++) b.push(g.albumLink(h[p].id).toURI());
a.push(b)
}
return a
};
d.prototype.getSingleGroups = function (b) {
var a = [],
f = b.single_group;
if (f && f.length)
for (var c = 0, d = f.length; c < d; c++) {
for (var h = f[c], b = [], p = 0, q = h.length; p < q; p++) b.push(g.albumLink(h[p].id).toURI());
a.push(b)
}
return a
};
d.prototype.getRelatedArtists = function (b) {
var a = [];
if ((b = b.related) && b.length)
for (var f = 0, c = b.length; f < c; f++) a.push(g.artistLink(b[f].id).toURI());
return a
};
d.prototype.getTopTracks = function (b) {
var a = [];
if ((b = b.top_track) && b.length)
for (i = 0, l = b.length; i < l; i++) a.push(g.trackLink(b[i].id).toURI());
return a
};
d.create = function (b, a) {
var f = new c;
f.fulfill(new d(b, a));
return f
};
d.createComparator = function () {};
d.createPredicate = function () {}
})();
(function () {
function d(a, b) {
if (!(this instanceof d)) return new d(a, b);
this.uri = a.toString();
b && this._fill(b)
}
function g(a, b) {
if (!(this instanceof g)) return new g(a, b);
this.uri = a.toString();
b && this._fill(b)
}
var c = Spotify.Link,
h = Spotify.Promise,
b = Spotify.ItemList,
a = b.Comparators,
f = b.Predicates,
k = Spotify.Shell.Entities;
Spotify.Shell.Entities.Playlist = d;
d.prototype._fill = function (a) {
this.name = a.name;
this.owner_name = a.owner;
this.owner = {
uri: c.profileLink(a.owner).toString()
};
this.collaborative = !! a.collaborative;
this.description = a.description || "";
if (a.picture) {
var b = a.picture;
try {
b = decodeURIComponent(b)
} catch (f) {}
a = k.createImages([{
width: 300,
height: 300,
file_id: b
}], a.resourceUrl);
this.image = a.image;
this.images = a.images
}
};
d.create = function (a, b) {
var f = new h;
try {
f.fulfill(new d(a, b))
} catch (c) {
f.fail(c)
}
return f
};
d.prototype.createComparator = function () {
return null
};
d.prototype.createPredicate = function () {
return null
};
Spotify.Shell.Entities.PlaylistRow = g;
g.prototype._fill = function (a) {
this.creator = (this.creatorName =
a.added_by) ? c.profileLink(a.added_by) : null;
this.addTime = a.timestamp;
this.track = a.track
};
g.prototype.setTrack = function (a) {
this.track = a
};
g.create = function (a, b) {
var f = new h;
try {
f.fulfill(new g(a, b))
} catch (c) {
f.fail(c)
}
return f
};
g.createComparator = function (b, f) {
switch (b) {
case "uri":
case "creator":
return f == "desc" ? a.forStringPropertyReversed(b) : a.forStringProperty(b);
case "addTime":
return f == "desc" ? a.forNumberPropertyReversed(b) : a.forNumberProperty(b);
default:
var c = k.Track.createComparator(b, f);
if (c) return function (a,
b) {
return c(a && a.track, b && b.track)
}
}
return null
};
g.createPredicate = function (a, b, c) {
switch (a) {
case "uri":
case "creator":
case "addTime":
return f.forPropertyOperator(a, b, c);
default:
var d = k.Track.createPredicate(a, b, c);
if (d) return function (a) {
return d(a && a.track)
}
}
return null
}
})();
(function () {
function d(a, b) {
if (!(this instanceof d)) return new d(a, b);
this.uri = a.toString();
b && this._fill(b)
}
function g(a, b) {
if (!(this instanceof g)) return new g(a, b);
this.uri = a.toString();
b && this._fill(b)
}
function c(a, b) {
if (!(this instanceof c)) return new c(a, b);
this.uri = a.toString();
b && this._fill(b)
}
function h(a, b) {
if (!(this instanceof h)) return new h(a, b);
this.uri = a.toString();
b && this._fill(b)
}
var b = Spotify.Link,
a = Spotify.Shell.Entities;
Spotify.Shell.Entities.SearchAlbum = d;
d.prototype._fill = function (f) {
var c,
d;
this.artistName = "";
this.artists = [];
this.availability = f.availability;
this.image = void 0;
this.images = [];
this.name = f.name;
this.playable = f.playable;
this.popularity = f.popularity;
this.type = (f.type || "").toLowerCase();
var h = f.artists,
g = this.artists,
q = [];
this.artistName = "";
if (h && h.length) {
for (c = 0, d = h.length; c < d; c++) {
var n = h[c];
g.push({
uri: b.artistLink(n.id).toString(),
name: n.name
});
q.push(n.name)
}
this.artistName = q.join(";")
}
if (c = f.cover) f = a.createSearchImages(c, f.resourceUrl), this.image = f.image, this.images =
f.images
};
Spotify.Shell.Entities.SearchArtist = g;
g.prototype._fill = function (b) {
this.availability = b.availability;
this.image = void 0;
this.images = [];
this.name = b.name;
this.playable = b.playable;
this.popularity = b.popularity;
var c = b.portrait;
if (c) b = a.createSearchImages(c, b.resourceUrl), this.image = b.image, this.images = b.images
};
Spotify.Shell.Entities.SearchPlaylist = c;
c.prototype._fill = function (a) {
this.image = void 0;
this.images = [];
this.name = a.name;
this.owner_name = a.owner;
this.owner = {
uri: b.profileLink(a.owner).toString()
};
var c = a.image;
if (c) {
var d = this.images,
c = c.split(":").splice(2, c.length - 1).join(""),
c = this.image = a.resourceUrls.normal + c;
d.push([300, c]);
if (c = a["image-large"]) c = c.split(":").splice(2, c.length - 1).join(""), d.push([640, a.resourceUrl.large + c]);
if (c = a["image-small"]) c = c.split(":").splice(2, c.length - 1).join(""), d.push([120, a.resourceUrl.small + c])
}
};
Spotify.Shell.Entities.SearchTrack = h;
h.prototype._fill = function (f) {
this._pid = this.playableId = f.playableId;
this.availability = f.availability;
this.duration = f.length;
this.name = f.name;
this.playable = f.playable;
this.playableURI = b.trackLink(this._pid);
this.popularity = f.popularity;
var c = f.album,
d = this.album = {};
if (c && (this.albumUri = d.uri = b.albumLink(c.id).toString(), this.albumName = d.name = c.name, c = c.cover)) c = a.createSearchImages(c, f.resourceUrl), d.image = c.image, d.images = c.images;
f = f.artist || f.artists;
d = this.artists = [];
c = [];
this.artistName = "";
if (f && f.length) {
for (var h = 0, g = f.length; h < g; h++) {
var q = f[h];
d.push({
uri: b.artistLink(q.id).toString(),
name: q.name
});
c.push(q.name)
}
this.artistName =
c.join(";")
}
}
})();
(function () {
function d(a, b) {
if (!(this instanceof d)) return new d(a, b);
this.uri = a.toString();
b && this._fill(b)
}
var g = Spotify.Link,
c = Spotify.Promise,
h = Spotify.ItemList,
b = h.Comparators,
a = h.Predicates,
f = Spotify.Shell.Entities;
Spotify.Shell.Entities.Track = d;
d.prototype._fill = function (a) {
this._pid = this.playableId = a.playableId;
this.playableURI = g.trackLink(this._pid);
this.name = a.name;
this.disc = a.disc_number == void 0 ? a.disc_number : parseInt(a.disc_number, 10);
this.duration = a.duration;
this.number = a.number == void 0 ?
a.number : parseInt(a.number, 10);
this.popularity = a.popularity;
this.availability = a.availability;
this.playable = a.playable;
this.image = a.image;
this.images = a.images;
this.starred = a.starred;
this.explicit = !! a.explicit;
this.advertisement = !! a.ad;
this.seen = !0;
var b = a.album,
c = this.album = {};
if (b && (this.albumUri = c.uri = g.albumLink(b.id).toString(), this.albumName = c.name = b.name, b = b.cover_group && b.cover_group.image)) b = f.createImages(b, a.resourceUrl), this.image = b.image, this.images = b.images;
a = a.artist || a.artists;
b = this.artists = [];
c = [];
this.artistName = "";
if (a && a.length) {
for (var d = 0, h = a.length; d < h; d++) {
var n = a[d];
b.push({
uri: g.artistLink(n.id).toString(),
name: n.name
});
c.push(n.name)
}
this.artistName = c.join(";")
}
};
d.create = function (a, b) {
var f = new c;
try {
f.fulfill(new d(a, b))
} catch (h) {
f.fail(h)
}
return f
};
d.createComparator = function (a, f) {
switch (a) {
case "uri":
case "name":
return f != "desc" ? b.forStringProperty(a) : b.forStringPropertyReversed(a);
case "disc":
case "duration":
case "number":
case "popularity":
case "seen":
case "starred":
return f !=
"desc" ? b.forNumberProperty(a) : b.forNumberPropertyReversed(a);
case "artists.name":
return f != "desc" ? b.forStringProperty("artistName") : b.forStringPropertyReversed("artistName");
case "album.name":
return f != "desc" ? b.forStringProperty("albumName") : b.forStringPropertyReversed("albumName")
}
return null
};
d.createPredicate = function (b, f, c) {
switch (b) {
case "uri":
case "name":
case "disc":
case "duration":
case "number":
case "popularity":
case "seen":
case "starred":
return a.forPropertyOperator(b, f, c);
case "artists.name":
return a.forPropertyOperator("artistName",
f, c);
case "album.name":
return a.forPropertyOperator("albumName", f, c)
}
return null
}
})();
(function () {
function d(a, c) {
if (!(this instanceof d)) return new d(a, c);
b.call(this, c);
this._uri = a.toString();
this._loadLimit = 500
}
function g(b, c) {
if (!(this instanceof g)) return new g(b, c);
a.call(this, c);
this._uri = b.toString()
}
var c = Spotify.Shell.Entities,
h = Spotify.ItemList,
b = h.Array,
a = h.Concatenated;
Spotify.inherit(d, b);
Spotify.ItemList.DiscTrack = d;
Spotify.inherit(g, a);
Spotify.ItemList.AlbumTrack = g;
g.prototype.createComparator = function (a, b) {
return c.Track.createComparator(a, b)
};
g.prototype.createPredicate =
function (a, b, d) {
return c.Track.createPredicate(a, b, d)
}
})();
(function () {
function d(b, c) {
if (!(this instanceof d)) return new d(b, c);
a.call(this);
this._uri = b.toString();
this._loadLimit = 200;
this._itemLoader = c
}
var g = Spotify.Promise,
c = Spotify.Shell,
h = c.Range,
b = c.Entities,
a = Spotify.ItemList.Base;
Spotify.inherit(d, a);
Spotify.ItemList.PlaylistRow = d;
d.prototype._load = function (a) {
var b = this,
c = new g;
this._itemLoader(this._uri, a).then(function (d) {
c.fulfill({
range: a,
items: b._createRows(d)
})
});
return c
};
d.prototype._loadLength = function () {
var a = this,
b = new g;
this._itemLoader(this._uri,
new h(0, this._loadLimit)).then(function (c) {
var d = a._length = c.length;
a._insertLoadedData({
range: new h(0, Math.min(d, a._loadLimit)),
items: a._createRows(c)
});
b.fulfill({
length: d
})
}, function () {
var c = a._length = 0;
b.fulfill({
length: c
})
});
return b
};
d.prototype._createRows = function (a) {
for (var a = a.contents, c = [], d = 0, h = a.length; d < h; d++) {
var g = a[d];
c.push(new b.PlaylistRow(g.uri, g.attributes))
}
return c
};
d.prototype.createComparator = function (a, c) {
return b.PlaylistRow.createComparator(a, c)
};
d.prototype.createPredicate =
function (a, c, d) {
return b.PlaylistRow.createPredicate(a, c, d)
}
})();
(function () {
function d(a, b) {
q.call(this);
this._uri = a.toString();
this._loadLimit = 50;
this._itemLoader = b;
this._timestamp = (new Date).getTime()
}
function g(a, b) {
if (!(this instanceof g)) return new g(a, b);
d.call(this, a, b)
}
function c(a, b) {
if (!(this instanceof c)) return new c(a, b);
d.call(this, a, b)
}
function h(a, b) {
if (!(this instanceof h)) return new h(a, b);
d.call(this, a, b)
}
function b(a, f) {
if (!(this instanceof b)) return new b(a, f);
d.call(this, a, f)
}
var a = Spotify.Link,
f = Spotify.Promise,
k = Spotify.Shell,
m = k.Entities,
o = k.Range,
p = Spotify.ItemList,
q = p.Base;
Spotify.Shell.SearchTypes = {
ALBUMS: "albums",
ARTISTS: "artists",
PLAYLISTS: "playlists",
TRACKS: "tracks"
};
Spotify.inherit(d, q);
Spotify.ItemList.Search = d;
d.create = function (a, b, f) {
switch (a) {
case "albums":
return new p.SearchAlbums(b, f);
case "artists":
return new p.SearchArtists(b, f);
case "playlists":
return new p.SearchPlaylists(b, f);
case "tracks":
return new p.SearchTracks(b, f);
default:
return null
}
};
d.prototype._load = function (a) {
var b = this,
c = new f;
this._itemLoader(a).then(function (f) {
c.fulfill({
range: a,
items: b._createRows(f.items)
})
}, function (a) {
c.fail(a)
});
return c
};
d.prototype._loadLength = function () {
var a = this,
b = new f;
this._itemLoader(new o(0, this._loadLimit)).then(function (f) {
var c = a._length = Math.min(f.length, 1E4);
a._insertLoadedData({
range: new o(0, Math.min(c, a._loadLimit)),
items: a._createRows(f.items)
});
b.fulfill({
length: c
})
}, function () {
var f = a._length = 0;
b.fulfill({
length: f
})
});
return b
};
d.prototype._createRows = function (a) {
return a
};
d.prototype.isOlderThan = function (a) {
return (new Date).getTime() -
this._timestamp >= a
};
Spotify.inherit(g, d);
Spotify.ItemList.SearchAlbums = g;
g.prototype._createRows = function (a) {
for (var b = 0, f = a.length; b < f; b++) {
var c = a[b];
a[b] = new m.SearchAlbum(new Spotify.Link.albumLink(c.id), c)
}
return a
};
Spotify.inherit(c, d);
Spotify.ItemList.SearchArtists = c;
c.prototype._createRows = function (a) {
for (var b = 0, f = a.length; b < f; b++) {
var c = a[b];
a[b] = new m.SearchArtist(new Spotify.Link.artistLink(c.id), c)
}
return a
};
Spotify.inherit(h, d);
Spotify.ItemList.SearchPlaylists = h;
h.prototype._createRows =
function (b) {
for (var f = 0, c = b.length; f < c; f++) {
var k = b[f],
d = a.fromString(k.uri);
k.owner = d.username;
b[f] = new m.SearchPlaylist(d, k)
}
return b
};
Spotify.inherit(b, d);
Spotify.ItemList.SearchTracks = b;
b.prototype._createRows = function (a) {
for (var b = 0, f = a.length; b < f; b++) {
var c = a[b];
a[b] = new m.SearchTrack(new Spotify.Link.trackLink(c.id), c)
}
return a
}
})();
(function () {
function d(a, b) {
if (!(this instanceof d)) return new d(a, b);
if (!b || !Array.isArray(b)) throw new TypeError("ToplistItemList: Argument `array` must be an array.");
for (var b = b.slice(0), c = b.length; c--;) b[c] = b[c].toString();
f.call(this, b);
this._uri = a.toString()
}
function g(a, b) {
if (!(this instanceof g)) return new g(a, b);
d.call(this, a, b)
}
function c(a, b) {
if (!(this instanceof c)) return new c(a, b);
d.call(this, a, b)
}
function h(a, b) {
if (!(this instanceof h)) return new h(a, b);
d.call(this, a, b)
}
function b(a,
f) {
if (!(this instanceof b)) return new b(a, f);
d.call(this, a, f)
}
var a = Spotify.ItemList,
f = a.Array;
Spotify.Shell.ToplistTypes = {
ALBUM: "album",
ARTIST: "artist",
PLAYLIST: "playlist",
TRACK: "track"
};
Spotify.inherit(d, f);
Spotify.ItemList.Toplist = d;
d.create = function (b, f, c) {
switch (b) {
case "artist":
return new a.ToplistArtist(f, c);
case "album":
return new a.ToplistAlbum(f, c);
case "playlist":
return new a.ToplistPlaylist(f, c);
default:
return new a.ToplistTrack(f, c)
}
};
Spotify.inherit(g, d);
Spotify.ItemList.ToplistAlbum =
g;
Spotify.inherit(c, d);
Spotify.ItemList.ToplistArtist = c;
Spotify.inherit(h, d);
Spotify.ItemList.ToplistPlaylist = h;
Spotify.inherit(b, d);
Spotify.ItemList.ToplistTrack = b
})();
(function () {
function d(a, b) {
if (!(this instanceof d)) return new d(a, b);
if (!b) throw new TypeError("ContextItemList: Constructor argument `owner` cannot be undefined.");
h.call(this, a, 10);
this._owner = b;
this._shuffled = !1;
this._shuffledList = null
}
var g = Spotify.Promise,
c = Spotify.ItemList,
h = c.Iterable,
b = c.LoadedState;
Spotify.inherit(d, h);
Spotify.ItemList.Context = d;
d.prototype.shuffle = function (a) {
if (this._loadedState == b.UNLOADED) return this._queueCall();
var f = new g;
f.fulfill(!0);
if (this._shuffled) return f;
this._shuffled = !0;
for (var k = this._length, d = Array(k); k--;) d[k] = k;
for (var k = this.getIndex(), k = k == 0 || k == c.LIST_START || k == c.LIST_END ? null : d.splice(k, 1).pop(), h = d.length; h;) {
var p = Math.floor(Math.random() * h--),
q = d[h];
d[h] = d[p];
d[p] = q
}
if (k != null) d.unshift(k), this._index = a ? 0 : -1;
this._shuffledList = d;
return f
};
d.prototype.unshuffle = function () {
if (this._loadedState == b.UNLOADED) return this._queueCall();
var a = new g;
a.fulfill(!0);
if (!this._shuffled) return a;
this._shuffled = !1;
if (this._shuffledList) {
var f = this.getIndex();
if (f != 0 || f != c.LIST_START || f != c.LIST_END) this._index = this._shuffledList[f];
return a
}
};
d.prototype.snapshot = function (a, b) {
this._shuffled && this._shuffledList && this._shuffledList.length && (a = this._shuffledList[a]);
return this._super("snapshot", a, b)
};
d.prototype.getOwner = function () {
return this._owner
}
})();
(function () {
function d(a, f) {
b.call(this, a);
if (!f) throw new TypeError("Argument requestSender is null.");
this._requestSender = f;
this._decoratedMap = {};
this._init()
}
var g = Spotify.Promise,
c = Spotify.Shell.Range,
h = Spotify.ItemList,
b = h.Layered,
a = h.LoadedState,
f = h.Snapshot;
Spotify.inherit(d, b);
Spotify.ItemList.Decorator = d;
d.prototype._init = function () {
this._base.getLength().then(function (b) {
this._length = b;
this._loadedState = a.PARTIAL;
this._unqueueSnapshots()
}.bind(this)).catchError(function () {})
};
d.prototype._buildList =
function (a) {
var b = this._list,
f = new c(a.getOffset(), a.getLength()),
a = a.toArray();
b.insertFrom(f.begin, a);
return this._decorateItems(a, f)
};
d.prototype._decorateItems = function (a, b) {
var f = this,
c = new g,
d = this._decoratedMap;
this._requestSender(a).then(function (h) {
for (var g = 0, t = a.length; g < t; g++) {
var u = a[g];
d[u] = h[u]
}
f._updateRanges(b);
f._updateState();
c.fulfill(a)
});
return c
};
d.prototype.snapshot = function (b, d) {
var h = this,
p = new g,
q = new c(b, d, Math.max(this._length - b, 0));
switch (this._loadedState) {
case a.COMPLETE:
this._base.snapshot(b,
d).then(function (a) {
a = new f(h._version, h._createVersionedAccessor(a.toArray()), new c(a.getOffset(), a.getLength(), a.getListLength()), a.getListLength());
p.fulfill(a)
}, p.fail.bind(p));
break;
case a.PARTIAL:
q.findContainer(this._loadedRanges) ? this._base.snapshot(b, d).then(function (a) {
a = new f(h._version, h._createVersionedAccessor(a.toArray()), new c(a.getOffset(), a.getLength(), a.getListLength()), a.getListLength());
p.fulfill(a)
}, p.fail.bind(p)) : this._base.snapshot(b, d).then(function (a) {
return h._buildList(a)
}).then(function () {
return h.snapshot(b,
d).pipe(p)
}).catchError(function (a) {
p.fail(a)
});
break;
case a.UNLOADED:
this._queueSnapshot(b, d, p)
}
return p
};
d.prototype._createVersionedAccessor = function (a) {
var b = this,
f = this._decoratedMap;
return function (c, d, h) {
if (b._version != c) throw Error("Cannot access item with an expired snapshot.");
return f[a[h]].metadata
}
};
d.prototype.onMutate = function (a) {
this.notify("onBeforeMutate", new f(this._version, this._createVersionedAccessor(this._list), new c(snapshot.getOffset(), snapshot.getLength(), snapshot.getListLength()),
snapshot.getListLength()));
for (var b = [], d = 0, h = a.length; d < h; d++) {
var q = a[d];
switch (q.type) {
case "insert":
b.push(this._applyInsertMutation(q));
break;
case "remove":
b.push(this._applyRemoveMutation(q));
break;
case "move":
b.push(this._applyMoveMutation(q))
}
}
b.length && g.join(b).then(function (a) {
this._version++;
this.notify("onMutate", a)
}.bind(this))
};
d.prototype._applyInsertMutation = function (a) {
var b = a.begin,
a = a.items;
this._list.spliceWith(b, 0, a);
this._length += a.length;
return this._decorateItems(a, new c(b,
a.length)).then(function (a) {
return {
type: "insert",
begin: b,
items: a
}
})
};
d.prototype._applyRemoveMutation = function (a) {
var b = new g,
f = a.length;
this._list.splice(a.begin, f);
this._length -= f;
b.fulfill(a);
return b
};
d.prototype._applyMoveMutation = function () {
var a = new g,
b = mutation.end,
f = this._list,
c = f.splice(mutation.begin, mutation.length);
f.spliceWith(b, 0, c);
a.fulfill(mutation);
return a
}
})();
(function () {
function d(c, d) {
g.call(this, c, d)
}
var g = Spotify.ItemList.Decorator;
Spotify.inherit(d, g);
Spotify.ItemList.MetadataDecorator = d;
d.prototype._decorateItems = function (c, d) {
return this._requestSender(c).then(this._processMetadata.bind(this, c, d), function () {})
};
d.prototype._processMetadata = function (c, d, b) {
for (var a = this._decoratedMap, f = c.length, k = Array(f); f--;) {
var m = c[f],
g = a[m];
g ? g.count++ : g = a[m] = {
count: 1,
metadata: b[m]
};
k[f] = g.metadata
}
this._updateRanges(d);
this._updateState();
return k
};
d.prototype._createVersionedAccessor =
function (c) {
var d = this,
b = this._decoratedMap;
return function (a, f, k) {
if (d._version != a) throw Error("Cannot access item with an expired snapshot.");
return b[c[k]].metadata
}
}
})();
(function () {
function d(c, d) {
g.call(this, c, d);
this._rows = []
}
var g = Spotify.ItemList.Decorator;
Spotify.inherit(d, g);
Spotify.ItemList.PlaylistTrackDecorator = d;
d.prototype._decorateItems = function (c, d) {
for (var b = c.length, a = Array(b); b--;) a[b] = c[b].uri;
return this._requestSender(a).then(this._processMetadata.bind(this, c, d), function () {})
};
d.prototype._processMetadata = function (c, d, b) {
for (var a = this._rows, f = c.length, k = Array(f); f--;) {
var m = c[f];
m.setTrack(b[m.uri]);
k[f] = m
}
a.insertFrom(d.begin, k);
this._updateRanges(d);
this._updateState();
return k
};
d.prototype._createVersionedAccessor = function () {
var c = this,
d = this._rows;
return function (b, a) {
if (c._version != b) throw Error("Cannot access item with an expired snapshot.");
return d[a]
}
}
})();
(function () {
function d(a) {
if (!(this instanceof d)) return new d(a);
this._audioManager = a;
this._stack = [];
this._players = {}
}
function g(c, d) {
if (!(this instanceof g)) return new g(player);
if (!c) throw new TypeError("ContextPlayer: Argument `id` cannot be undefined.");
if (!d) throw new TypeError("ContextPlayer: Argument `audioManager` cannot be undefined.");
f.call(this);
this._id = c;
this._uid = 0;
this._audioManager = d;
this._player = d.addPlayer(c + ":A");
this._alternatePlayer = d.addPlayer(c + ":B");
this._interceptContextList =
new a(new b([]), "intercept");
this._queueContextList = new a(new b([]), "queue");
this._previousPlayCall = this._currentTrack = this._currentContextOptions = this._currentContextList = null;
this._shuffled = this._fakePlayState = !1;
this._nextMovement = "next";
this._crossfading = this._crossfade = this._stopped = !1;
this._crossfadeAmount = 0;
this._crossfadeBuffer = 1E3;
this._initEvents(this._player);
this._initEvents(this._alternatePlayer)
}
var c = Spotify.Promise,
h = Spotify.ItemList,
b = Spotify.ItemList.Array,
a = h.Context,
f = Spotify.Shell.EventEmitter;
Spotify.Shell.ContextOperationResult = {
CONTEXT_END: "contextEnd",
EMPTY: "empty",
FORBIDDEN: "forbidden",
INVALID: "invalid",
NO_CONTEXT: "nonContext",
SUCCESS: "success"
};
var k = Spotify.Shell.ContextOperationResult;
Spotify.Shell.ContextPlayerGroup = d;
d.prototype.create = function (a) {
var b = this._players;
if (b[a]) throw new TypeError('A player with the id "' + a + '" already exists.');
var f = new g(a, this._audioManager);
f.addEvents({
trackLoaded: this._onTrackLoaded.bind(this),
play: this._onPlayerPlay.bind(this),
contextEnd: this._onContextStop.bind(this),
stop: this._onContextStop.bind(this)
});
return b[a] = f
};
d.prototype.get = function (a) {
return this._players[a] || null
};
d.prototype._onTrackLoaded = function (a) {
var b = a.player,
a = this._stack;
if (!a.length) return this;
var f = a[0];
if (f.player == b) return this;
f.state = f.player.getState();
this._audioManager.crossfade(f.player.getPlayerId(), b.getPlayerId(), 800, function () {
f.player.pause();
b.setPlayerVolume(1)
})
};
d.prototype._onPlayerPlay = function (a) {
var a = a.player,
b = this._stack;
b.length && b[0].player == a || b.unshift({
player: a,
state: {}
})
};
d.prototype._onContextStop = function () {
var a = this._stack,
b = a.shift();
if (a.length) {
var f = a[0];
f.state.playing ? (f.player.resume(), this._audioManager.crossfade(b.player.getPlayerId(), f.player.getPlayerId(), 800, function () {
f.player.setPlayerVolume(1)
})) : f.player.setPlayerVolume(1)
}
};
Spotify.inherit(g, f);
Spotify.Shell.ContextPlayer = g;
g.prototype._initEvents = function (a) {
a.onPlay = this._handlePlay.bind(this);
a.onPause = this._handlePause.bind(this);
a.onTrackEnded = this._handleEnded.bind(this);
a.onInvalidTrackUri =
a.onPlaybackFailed = this._handleInvalid.bind(this);
a.bind("BEFORE_END", this._handleBeforeEnded.bind(this))
};
g.prototype._handlePlay = function (a) {
this.fireEvent("play", {
player: this,
track: this._currentTrack,
position: typeof a.params == "number" ? a.params : 0,
context: this._currentContextList,
options: this._currentContextOptions
})
};
g.prototype._handlePause = function (a) {
this.fireEvent("pause", {
player: this,
track: this._currentTrack,
position: typeof a.params == "number" ? a.params : 0,
context: this._currentContextList,
options: this._currentContextOptions
})
};
g.prototype._handleEnded = function () {
this.fireEvent("playEnd", {
player: this,
track: this._currentTrack,
context: this._currentContextList,
options: this._currentContextOptions
});
if (!this._crossfade) {
var a = this._nextMovement;
a == "next" ? this.next("trackdone") : a == "previous" && this.previous("trackdone")
}
};
g.prototype._handleBeforeEnded = function () {
this.fireEvent("beforePlayEnd", {
player: this,
track: this._currentTrack,
context: this._currentContextList,
options: this._currentContextOptions
});
if (this._crossfade) {
var a =
this._nextMovement;
a == "next" ? this.next("trackdone") : a == "previous" && this.previous("trackdone")
}
};
g.prototype._handleInvalid = function (a) {
a = a.params;
if (a.domain == 12) switch (a.code) {
case 8:
this.fireEvent("requestCap", {
player: this
});
break;
case 12:
this.fireEvent("playCap", {
player: this
});
break;
case 11:
this.fireEvent("trackCap", {
player: this
}), this.next("trackdone")
} else this.next("trackdone")
};
g.prototype.getPlayerId = function () {
return this._player.id
};
g.prototype.getInterceptList = function () {
return this._interceptContextList
};
g.prototype.getQueueList = function () {
return this._queueContextList
};
g.prototype.getState = function () {
var a = this._player.getPlayerState(),
b = this._currentContextList,
f = this._currentTrack;
b.getRootBaseList().getDescriptor();
return {
__uid: this._uid,
__rules: null,
__owner: b ? b.getOwner() : null,
__index: b ? b.getIndex() : null,
playing: this._fakePlayState ? !0 : !a.isPaused && !a.isStopped,
index: b ? b.getIndex() : null,
track: f,
context: b,
position: a.position,
duration: a.duration,
repeat: this._repeat,
shuffle: this._shuffled
}
};
g.prototype.setCrossfade =
function (a) {
var b = new c;
if (typeof a != "number") return b.fail(k.INVALID), b;
a < 1E3 ? (this._crossfade = !1, this._crossfadeAmount = 0, this._crossfadeBuffer = 1E3) : (this._crossfade = !0, this._crossfadeAmount = a, this._crossfadeBuffer = a + 3E3);
b.fulfill(k.SUCCESS);
return b
};
g.prototype.isCrossfading = function () {
return this._crossfade ? !1 : !! this._crossfading
};
g.prototype.setVolume = function (a) {
var b = new c;
if (typeof a != "number") return b.fail(k.INVALID), b;
this.audioManager.setMasterVolume(a);
this.fireEvent("volumeChange", {
player: this
});
b.fulfill(k.SUCCESS);
return b
};
g.prototype.setPlayerVolume = function (a) {
var b = new c;
if (typeof a != "number") return b.fail(k.INVALID), b;
this._player.setVolume(a);
this.fireEvent("internalVolumeChange", {
player: this
});
b.fulfill(k.SUCCESS);
return b
};
g.prototype.setShuffle = function (a) {
this._shuffled = a;
var b = this._currentContextList;
b && (a ? b.shuffle(this.getState().playing) : b.unshuffle());
a = new c;
a.fulfill(k.SUCCESS);
return a
};
g.prototype.seek = function (a) {
var b = new c;
typeof a != "number" ? b.fail(k.INVALID) : this._currentContextList ?
(this._player.seek(a), b.fulfill(k.SUCCESS)) : b.fail(k.NO_CONTEXT);
return b
};
g.prototype.togglePlay = function () {
var a = new c;
this._currentContextList ? (this._player.playpause(), a.fulfill(k.SUCCESS)) : a.fail(k.NO_CONTEXT);
return a
};
g.prototype.resume = function () {
var a = new c;
this._currentContextList ? (this._player.resume(), a.fulfill(k.SUCCESS)) : a.fail(k.NO_CONTEXT);
return a
};
g.prototype.pause = function () {
var a = new c;
this._currentContextList ? (this._player.pause(), a.fulfill(k.SUCCESS)) : a.fail(k.NO_CONTEXT);
return a
};
g.prototype.stop = function () {
this._stopped = !0;
this._player.stop();
this.fireEvent("stop", {
player: this
});
return this
};
g.prototype.clear = function () {
this.stop();
this._currentContextOptions = this._currentContextList = this._currentTrack = null;
return this
};
g.prototype.play = function (b, f) {
b instanceof a || (b = new a(b, f.owner));
this._stopped = !1;
return b.getLength().then(function (a) {
return a == 0 ? (a = new c, a.fail(k.EMPTY), a) : (this.fireEventSync("beforeContextChange", {
player: this,
newContext: b,
newOptions: f,
oldContext: this._currentContextList,
oldOptions: this._currentContextOptions
}), b.startAt(f.index == -1 ? 0 : f.index), this._shuffled ? b.shuffle() : b.unshuffle(), this._repeat ? b.makeInfinite() : b.makeFinite(), this._currentContextList = b, this._currentContextOptions = f, this.fireEvent("contextChange", {
player: this,
context: b,
options: f
}), this.next(f.reason))
}.bind(this))
};
g.prototype.next = function (a) {
var b = new c,
f = this;
if (!this._currentContextList) return b.fail(k.NO_CONTEXT), b;
return !a ? (b.fail(k.INVALID), b) : this._interceptContextList.pop().then(function (a) {
return a !=
h.NULL_VALUE ? (f._nextMovement = "next", a) : f._queueContextList.pop()
}).then(function (a) {
return a != h.NULL_VALUE ? a : f._currentContextList.next()
}).then(function (b) {
if (b == h.LIST_END) return this.fireEvent("contextEnd", {
player: this,
context: this._currentContextList,
options: this._currentContextOptions
}), this.stop(), k.CONTEXT_END;
else {
this.fireEvent("beforeNextTrack", {
player: this,
newTrack: b,
oldTrack: this._currentTrack,
reason: a
});
var f = this._playTrack(b);
this.fireEvent("nextTrack", {
player: this,
track: b,
reason: a
});
return f
}
}.bind(this))
};
g.prototype.previous = function (a) {
var b = new c,
f = this;
if (!this._currentContextList) return b.fail(k.NO_CONTEXT), b;
return !a ? (b.fail(k.INVALID), b) : this._interceptContextList.pop().then(function (a) {
return a != h.NULL_VALUE ? (f._nextMovement = "previous", a) : (f._nextMovement = "next", f._currentContextList.previous())
}).then(function (b) {
if (b == h.LIST_START) return this.fireEvent("contextEnd", {
player: this,
context: this._currentContextList,
options: this._currentContextOptions
}), this.stop(), k.CONTEXT_END;
else {
this.fireEvent("beforePreviousTrack", {
player: this,
newTrack: b,
oldTrack: this._currentTrack,
reason: a
});
var f = this._playTrack(b);
this.fireEvent("previousTrack", {
player: this,
track: b,
reason: a
});
return f
}
}.bind(this))
};
g.prototype._playTrack = function (a) {
if (this._stopped) return k.SUCCESS;
this.fireEvent("beforePlay", {
player: this,
context: this._currentContextList,
options: this._currentContextOptions,
track: a
});
this._previousPlayCall ? (clearTimeout(this._previousPlayCall), this._previousPlayCall = setTimeout(this._loadTrackForPlayback.bind(this,
a), 1E3)) : (this._previousPlayCall = 1, this._previousPlayCall = setTimeout(this._loadTrackForPlayback.bind(this, a), 10));
return k.SUCCESS
};
g.prototype._loadTrackForPlayback = function (a) {
if (!this._stopped) {
var b = this._player,
f = this._alternatePlayer,
c = this._currentContextOptions;
this._uid++;
this._currentTrack = a;
var a = a.playableURI,
d = !c.pause;
c.pause = !1;
var k = c.offset || 0,
h = -1;
!isNaN(c.duration) && c.duration > 0 && (h = k + c.duration);
c = null;
b.getPlayerState().isPlaying && this._crossfade ? (c = f, f.onLoad = this._alternateLoaded.bind(this,
b, f, d)) : (c = b, b.onLoad = this._playerLoaded.bind(this, b, f, d));
c.load(a.toString(), k, d, h, this._crossfadeBuffer);
this._previousPlayCall = null
}
};
g.prototype._playerLoaded = function (a, b, f) {
this.fireEventSync("trackLoaded", {
player: this,
play: f,
mainPlayer: a,
alternatePlayer: b
})
};
g.prototype._alternateLoaded = function (a, b, f) {
this.fireEventSync("trackLoaded", {
player: this,
play: f,
mainPlayer: b,
alternatePlayer: a
});
if (!this._stopped) this._crossfading = !0, this.fireEventSync("crossfadeStart", {
player: this,
mainPlayer: a,
alternatePlayer: b
}),
this._audioManager.crossfade(a.id, b.id, this._crossfadeAmount, function () {
this._crossfading = !1;
this.fireEventSync("crossfadeEnd", {
player: this,
mainPlayer: a,
alternatePlayer: b
});
if (!this._stopped) a.pause(), b.setVolume(1), this._alternatePlayer = a, this._player = b
}.bind(this))
}
})();
(function () {
function d() {
this._handlers = {}
}
function g(a) {
function b() {}
if (typeof a != "object") return a;
b.prototype = a;
return new b
}
function c(a, b, f, d) {
if (!(this instanceof c)) return new c(a, b, f, d);
if (!a) throw new TypeError("DispatcherRequest: Argument `method` missing.");
if (!b) throw new TypeError("DispatcherRequest: Argument `path` missing.");
this.method = a;
this.path = b;
this.headers = f ? g(f) : {};
this.body = d ? g(d) : {}
}
function h(a, b, c) {
if (!(this instanceof h)) return new h(a, header, c);
this.status = f.OK;
this.statusText =
k[200];
this.headers = {};
this.body = {};
a != void 0 && this.setStatus(a);
b != void 0 && this.setHeaders(b);
c != void 0 && this.setBody(c)
}
function b() {
if (!(this instanceof b)) return new b;
this._ready = !1;
this._requestQueue = [];
this._handlers = new d;
this._requestSenders = {}
}
var a = Spotify.Promise;
Spotify.Shell.ResponseStatus = {
OK: 200,
CREATED: 201,
ACCEPTED: 202,
BAD_REQUEST: 400,
UNAUTHORIZED: 401,
FORBIDDEN: 403,
NOT_FOUND: 404,
METHOD_NOT_ALLOWED: 405,
TIMED_OUT: 408,
CONFLICT: 409,
GONE: 410,
INTERNAL_SERVER_ERROR: 500,
NOT_IMPLEMENTED: 501,
BAD_GATEWAY: 502,
SERVICE_UNAVAILABLE: 503
};
var f = Spotify.Shell.ResponseStatus;
Spotify.Shell.ResponseStatusText = {
200: "Ok",
201: "Created",
202: "Accepted",
400: "Bad Request",
401: "Unauthorized",
403: "Forbidden",
404: "Not Found",
405: "Method Not Allowed",
408: "Timed Out",
409: "Conflict",
410: "Gone",
500: "Internal Server Error",
501: "Not Implemented",
502: "Bad Gateway",
503: "Service Unavailable"
};
var k = Spotify.Shell.ResponseStatusText;
Spotify.Shell.RequestMethod = {
CREATE: "CREATE",
FLUSH: "FLUSH",
GET: "GET",
REMOVE: "REMOVE",
UPDATE: "UPDATE"
};
var m = Spotify.Shell.RequestMethod;
Spotify.Shell.MethodRequestMap = d;
d.prototype.get = function (a, b) {
var f = this._handlers,
a = a.toString().toUpperCase(),
f = f[a];
return !f ? null : f[b] || null
};
d.prototype.set = function (a, b, f) {
var c = this._handlers,
a = a.toString().toUpperCase();
(c[a] || (c[a] = {}))[b] = f;
return this
};
d.prototype.remove = function (a, b, f) {
var c = this._handlers,
a = a.toString().toUpperCase(),
a = c[a];
if (!a) return null;
c = a[b];
if (!c) return this;
c == f && (a[b] = null);
return this
};
Spotify.Shell.DispatcherRequest =
c;
Spotify.Shell.DispatcherResponse = h;
h.prototype.setStatus = function (a) {
this.status = a;
this.statusText = k[a];
return this
};
h.prototype.setHeader = function (a, b) {
this.headers[a] = b;
return this
};
h.prototype.setHeaders = function (a) {
for (var b in a) this.headers[b] = a[b];
return this
};
h.prototype.setBodyField = function (a, b) {
this.body[a] = b;
return this
};
h.prototype.setBodyFields = function (a) {
var b = this.body,
f;
for (f in a) a.hasOwnProperty(f) && (b[f] = a[f]);
return this
};
h.prototype.setBody = function (a) {
if (!a || typeof a != "object" ||
Array.isArray(a)) throw Error("DispatcherResponse.setBody: `body` must be an object.");
this.body = a;
return this
};
Spotify.Shell.Dispatcher = b;
b.prototype.setReady = function () {
this._ready = !0;
this._unqueue();
return this
};
b.prototype._queue = function (a, b) {
this._requestQueue.push({
args: a,
promise: b
});
return b
};
b.prototype._unqueue = function () {
for (var a = this._requestQueue.splice(0), b = 0, f = a.length; b < f; b++) {
var c = a[b];
this.request.apply(this, c.args).pipe(c.promise)
}
return this
};
b.prototype.register = function (a, b,
f) {
this._handlers.set(a, b, f);
return this
};
b.prototype.createRequestSender = function (a, b) {
var f = this,
c = this._requestSenders,
d = a + " " + b;
return c[d] || (c[d] = function (c, d) {
return f.request(a, b, c, d)
})
};
b.prototype.request = function (b, d, k, m) {
var g = new a;
if (!this._ready) return this._queue(arguments, g);
var b = (b || "").toString().toUpperCase(),
d = d || "/",
t = this._handlers.get(b, d);
if (t) {
var u = new c(b, d, k, m);
try {
var w = t.call(null, u, this);
w.pipe ? w.pipe(g) : g.fulfill(w)
} catch (v) {
g.fail(v)
}
} else g.fail(new h(f.NOT_IMPLEMENTED));
return g
};
b.prototype.create = function (a, b, f) {
return this.request(m.CREATE, a, b, f)
};
b.prototype.get = function (a, b, f) {
return this.request(m.GET, a, b, f)
};
b.prototype.flush = function (a, b, f) {
return this.request(m.FLUSH, a, b, f)
};
b.prototype.remove = function (a, b, f) {
return this.request(m.REMOVE, a, b, f)
};
b.prototype.update = function (a, b, f) {
return this.request(m.UPDATE, a, b, f)
}
})();
(function () {
function d() {
if (!(this instanceof d)) return new d;
this._mediator = new f;
this._reactors = []
}
function g(a) {
function b(a) {
this._ready = !1;
this._requestQueue = [];
this._mediator = a;
a = f.call(this);
return a === void 0 ? this : a
}
if (!(this instanceof g)) return new g(a);
this._registry = [];
var a = a || {}, f = a._construct || function () {};
b.prototype = this;
b.prototype.constructor = g;
var c = /([A-Z]+)\s+(.+)/,
d;
for (d in a)
if (a.hasOwnProperty(d)) {
var h = a[d],
s = d.match(c);
s && typeof h == "function" ? this._createHandler(s[1], s[2],
h) : this[d] = h
}
return b
}
var c = Array.prototype.slice,
h = Spotify.Promise,
b = Spotify.Shell,
a = b.DispatcherResponse,
f = b.EventEmitter;
Spotify.Shell.ReactorSet = d;
d.prototype.create = function (a) {
a = new g(a);
this._reactors.push(a);
return a
};
d.prototype.remove = function (a) {
var b = this._reactors,
f = b.indexOf(a);
b.indexOf(a) != -1 && b.splice(f, 1);
return this
};
d.prototype.add = function (a) {
if (typeof a != "function" || !(a.prototype instanceof g)) throw new TypeError("Argument `reactor` must be a reactor.");
var b = this._reactors;
b.indexOf(a) == -1 && b.push(a);
return this
};
d.prototype.attach = function (a) {
for (var b = this._reactors, f = 0, c = b.length; f < c; f++)(new b[f](this._mediator)).attach(a);
return this
};
Spotify.Shell.DefaultReactors = new d;
Spotify.Shell.Reactor = g;
g.prototype._createHandler = function (a, b, f) {
var c = f.name;
if (!c || c == "anonymous") {
c = a.toLowerCase();
pathSections = b.split("/");
c = [c];
if (pathSections.length == 2 && !pathSections[0] && !pathSections[1]) c.push("Root");
else
for (var d = function (a) {
return a.toUpperCase()
}, h = 0, g = pathSections.length; h <
g; h++) {
var t = pathSections[h];
t && c.push(t.replace(/^[a-z]/, d))
}
c = c.join("")
}
this[c] = f;
this._registry.push({
method: a,
path: b,
handler: c
})
};
g.prototype._createQueueable = function (a) {
var b = this,
f = this[a],
a = f ? function () {
return !b._ready ? b._queue() : f.apply(b, arguments)
} : function () {
var a = b._createPromise();
a.fail(new TypeError("Method not found."));
return a
};
a._origin = f;
return a
};
g.prototype._subscribe = function (a, b) {
this._mediator.addEvent(a, b.bind(this));
return this
};
g.prototype._subscribeAll = function (a) {
for (var b in a) a.hasOwnProperty(b) &&
this._mediator.addEvent(b, a[b].bind(this));
return this
};
g.prototype._unsubscribe = function (a, b) {
typeof a == "object" ? this._mediator.removeEvents(a) : this._mediator.removeEvents(a, b);
return this
};
g.prototype._broadcast = function (a, b) {
b = c.call(arguments, 1);
this._mediator.fireEvent(a, b);
return this
};
g.prototype._broadcastFlush = function () {
this._broadcast("resources.flush")
};
g.prototype._waitForServices = function (a) {
var b = 0,
f = [],
c;
for (c in a) f.push(this[c] = a[c]), b++;
a = function () {
!--b && this._onServicesReady &&
this._onServicesReady()
}.bind(this);
for (c = b; c--;) f[c].onReady(a, this);
return this
};
g.prototype._onServicesReady = function () {
this._ready = !0;
this._unqueue()
};
g.prototype._createResponse = function (b, f, c) {
return new a(b, f, c)
};
g.prototype._createPromise = function () {
return new h
};
g.prototype._wrapDecoratorRequest = function (a) {
return function (b) {
return a({
flush: !0
}, {
uris: b
}).then(function (a) {
return a.body.result
})
}
};
g.prototype._setReady = function () {
this._ready = !0;
this._unqueue()
};
g.prototype._queue = function () {
var a =
this._createPromise(),
b = this._queue.caller;
this._requestQueue.push({
fn: b,
args: b.arguments,
promise: a
});
return a
};
g.prototype._unqueue = function () {
for (var a = this._requestQueue, b = 0, f = a.length; b < f; b++) {
var c = a[b];
c.fn.apply(this, c.args).pipe(c.promise)
}
this._requestQueue = [];
return this
};
g.prototype.attach = function (a) {
if (!a || typeof a.register != "function") throw new TypeError("Reactor.attach: Argument `dispatcher` must be a Dispatcher object.");
for (var b = this._registry, f = [], c = 0, d = b.length; c < d; c++) {
var h =
b[c],
g = h.method,
t = h.path,
h = this._createQueueable(h.handler);
a.register(g, t, h);
f.push({
method: g,
path: t,
handler: h
})
}
return f
}
})();
(function () {
function d(a, f) {
if (f && f.substring(0, 4) == "NTX_") {
var d = g(f),
k = parseInt(h(c(b("spotify:test:" + a))).substring(0, 8), 16),
k = Math.floor(1E4 * k * Math.pow(2, -32));
return Math.floor(d[k] / 10)
} else return d = "spotify:test:", f && (d += f + ":"), d += a, digest = parseInt(h(c(b(d))).substring(0, 8), 16), Math.floor(1E3 * digest * Math.pow(2, -32))
}
function g(a) {
var f = 0,
d = q[a];
if (d) return d;
f = 0;
d = Array(1E4);
for (i = 0; i < d.length; i++) d[i] = i;
var k = h(c(b(a))),
f = parseInt(k.substring(0, 8), 16);
(function (a) {
for (var b = a.length - 1; b >=
1; b--) {
f = 16807 * f % 2147483647;
var c = f % (b + 1),
d = a[b];
a[b] = a[c];
a[c] = d
}
})(d);
return q[a] = d
}
function c(b) {
var c = Array(b.length >> 2),
d, h;
for (d = 0, h = c.length; d < h; d++) c[d] = 0;
for (d = 0, h = b.length * 8; d < h; d += 8) c[d >> 5] |= (b.charCodeAt(d / 8) & 255) << d % 32;
b = b.length * 8;
c[b >> 5] |= 128 << b % 32;
c[(b + 64 >>> 9 << 4) + 14] = b;
b = 1732584193;
d = -271733879;
h = -1732584194;
for (var g = 271733878, n = 0; n < c.length; n += 16) {
var p = b,
q = d,
G = h,
B = g,
b = f(b, d, h, g, c[n + 0], 7, -680876936),
g = f(g, b, d, h, c[n + 1], 12, -389564586);
h = f(h, g, b, d, c[n + 2], 17, 606105819);
d = f(d, h, g, b, c[n +
3], 22, -1044525330);
b = f(b, d, h, g, c[n + 4], 7, -176418897);
g = f(g, b, d, h, c[n + 5], 12, 1200080426);
h = f(h, g, b, d, c[n + 6], 17, -1473231341);
d = f(d, h, g, b, c[n + 7], 22, -45705983);
b = f(b, d, h, g, c[n + 8], 7, 1770035416);
g = f(g, b, d, h, c[n + 9], 12, -1958414417);
h = f(h, g, b, d, c[n + 10], 17, -42063);
d = f(d, h, g, b, c[n + 11], 22, -1990404162);
b = f(b, d, h, g, c[n + 12], 7, 1804603682);
g = f(g, b, d, h, c[n + 13], 12, -40341101);
h = f(h, g, b, d, c[n + 14], 17, -1502002290);
d = f(d, h, g, b, c[n + 15], 22, 1236535329);
b = k(b, d, h, g, c[n + 1], 5, -165796510);
g = k(g, b, d, h, c[n + 6], 9, -1069501632);
h = k(h,
g, b, d, c[n + 11], 14, 643717713);
d = k(d, h, g, b, c[n + 0], 20, -373897302);
b = k(b, d, h, g, c[n + 5], 5, -701558691);
g = k(g, b, d, h, c[n + 10], 9, 38016083);
h = k(h, g, b, d, c[n + 15], 14, -660478335);
d = k(d, h, g, b, c[n + 4], 20, -405537848);
b = k(b, d, h, g, c[n + 9], 5, 568446438);
g = k(g, b, d, h, c[n + 14], 9, -1019803690);
h = k(h, g, b, d, c[n + 3], 14, -187363961);
d = k(d, h, g, b, c[n + 8], 20, 1163531501);
b = k(b, d, h, g, c[n + 13], 5, -1444681467);
g = k(g, b, d, h, c[n + 2], 9, -51403784);
h = k(h, g, b, d, c[n + 7], 14, 1735328473);
d = k(d, h, g, b, c[n + 12], 20, -1926607734);
b = a(d ^ h ^ g, b, d, c[n + 5], 4, -378558);
g =
a(b ^ d ^ h, g, b, c[n + 8], 11, -2022574463);
h = a(g ^ b ^ d, h, g, c[n + 11], 16, 1839030562);
d = a(h ^ g ^ b, d, h, c[n + 14], 23, -35309556);
b = a(d ^ h ^ g, b, d, c[n + 1], 4, -1530992060);
g = a(b ^ d ^ h, g, b, c[n + 4], 11, 1272893353);
h = a(g ^ b ^ d, h, g, c[n + 7], 16, -155497632);
d = a(h ^ g ^ b, d, h, c[n + 10], 23, -1094730640);
b = a(d ^ h ^ g, b, d, c[n + 13], 4, 681279174);
g = a(b ^ d ^ h, g, b, c[n + 0], 11, -358537222);
h = a(g ^ b ^ d, h, g, c[n + 3], 16, -722521979);
d = a(h ^ g ^ b, d, h, c[n + 6], 23, 76029189);
b = a(d ^ h ^ g, b, d, c[n + 9], 4, -640364487);
g = a(b ^ d ^ h, g, b, c[n + 12], 11, -421815835);
h = a(g ^ b ^ d, h, g, c[n + 15], 16, 530742520);
d = a(h ^ g ^ b, d, h, c[n + 2], 23, -995338651);
b = m(b, d, h, g, c[n + 0], 6, -198630844);
g = m(g, b, d, h, c[n + 7], 10, 1126891415);
h = m(h, g, b, d, c[n + 14], 15, -1416354905);
d = m(d, h, g, b, c[n + 5], 21, -57434055);
b = m(b, d, h, g, c[n + 12], 6, 1700485571);
g = m(g, b, d, h, c[n + 3], 10, -1894986606);
h = m(h, g, b, d, c[n + 10], 15, -1051523);
d = m(d, h, g, b, c[n + 1], 21, -2054922799);
b = m(b, d, h, g, c[n + 8], 6, 1873313359);
g = m(g, b, d, h, c[n + 15], 10, -30611744);
h = m(h, g, b, d, c[n + 6], 15, -1560198380);
d = m(d, h, g, b, c[n + 13], 21, 1309151649);
b = m(b, d, h, g, c[n + 4], 6, -145523070);
g = m(g, b, d, h, c[n + 11], 10, -1120210379);
h = m(h, g, b, d, c[n + 2], 15, 718787259);
d = m(d, h, g, b, c[n + 9], 21, -343485551);
b = o(b, p);
d = o(d, q);
h = o(h, G);
g = o(g, B)
}
c = [b, d, h, g];
b = "";
for (d = 0; d < c.length * 32; d += 8) b += String.fromCharCode(c[d >> 5] >>> d % 32 & 255);
return b
}
function h(a) {
for (var b = n ? "0123456789ABCDEF" : "0123456789abcdef", f = "", c, d = 0; d < a.length; d++) c = a.charCodeAt(d), f += b.charAt(c >>> 4 & 15) + b.charAt(c & 15);
return f
}
function b(a) {
for (var b = "", f = -1, c, d; ++f < a.length;) c = a.charCodeAt(f), d = f + 1 < a.length ? a.charCodeAt(f + 1) : 0, 55296 <= c && c <= 56319 && 56320 <= d && d <=
57343 && (c = 65536 + ((c & 1023) << 10) + (d & 1023), f++), c <= 127 ? b += String.fromCharCode(c) : c <= 2047 ? b += String.fromCharCode(192 | c >>> 6 & 31, 128 | c & 63) : c <= 65535 ? b += String.fromCharCode(224 | c >>> 12 & 15, 128 | c >>> 6 & 63, 128 | c & 63) : c <= 2097151 && (b += String.fromCharCode(240 | c >>> 18 & 7, 128 | c >>> 12 & 63, 128 | c >>> 6 & 63, 128 | c & 63));
return b
}
function a(a, b, f, c, d, k) {
a = o(o(b, a), o(c, k));
return o(a << d | a >>> 32 - d, f)
}
function f(b, f, c, d, k, h, g) {
return a(f & c | ~f & d, b, f, k, h, g)
}
function k(b, f, c, d, k, h, g) {
return a(f & d | c & ~d, b, f, k, h, g)
}
function m(b, f, c, d, k, h, g) {
return a(c ^
(f | ~d), b, f, k, h, g)
}
function o(a, b) {
var f = (a & 65535) + (b & 65535);
return (a >> 16) + (b >> 16) + (f >> 16) << 16 | f & 65535
}
var p = Spotify.Shell.ResponseStatus;
Spotify.Shell.DefaultReactors.create({
_construct: function () {
this._setReady()
},
"GET /user/groupid": function (a) {
var b = a.body,
a = this._createPromise(),
f = this._createResponse();
!b.username || !b.salt || typeof b.salt != "string" ? (f.setStatus(p.BAD_REQUEST), a.fail(f)) : (b = d(b.username, b.salt), f.setBodyField("id", b), a.fulfill(f));
return a
}
});
Spotify.getGroupId = d;
Spotify.getDefaultGroupId =
function (a) {
return d(a, "")
};
var q = {}, n = 0
})();
(function () {
var d = Spotify.SimpleCache,
g = Spotify.ItemList,
c = g.Descriptor,
h = Spotify.Shell.ResponseStatus;
Spotify.Shell.DefaultReactors.create({
_construct: function () {
this._baseLists = {};
this._cache = new d(100);
this._setReady()
},
_retrieveList: function (b) {
var a = null,
f = null,
c = this._cache,
d = b.serialize(),
h = c.get(d);
if (h) return h;
try {
switch (b.type) {
case "list":
return this._baseLists[b.uri] || null;
case "concatenate":
for (var h = [], p = 0, q = b.lists.length; p < q; p++) {
f = this._retrieveList(b.lists[p]);
if (!f) return null;
h.push(f)
}
a = new g.Concatenated(h);
a.setDescriptor(b);
c.put(d, a);
break;
case "sort":
f = this._retrieveList(b.list);
if (!f) return null;
p = f.createComparator(b.field, b.order);
if (!p) return null;
a = new g.Sorted(f, p);
a.setDescriptor(b);
c.put(d, a);
break;
case "filter":
f = this._retrieveList(b.list);
if (!f) return null;
var n = f.createPredicate(b.field, b.operator, b.matcher);
if (!n) return null;
a = new g.Filtered(f, n);
a.setDescriptor(b);
c.put(d, a);
break;
case "range":
f = this._retrieveList(b.list);
if (!f) return null;
a = new g.Ranged(f,
b.offset, b.length);
a.setDescriptor(b);
c.put(d, a)
}
return a
} catch (s) {
return a
}
},
"GET /list": function (b) {
var a = this._createPromise(),
f = this._createResponse();
(b = b.body.descriptor) && !(b instanceof c.Base) && (b = c.from(b));
f.setBodyField("descriptor", b);
if (!b) return f.setStatus(h.BAD_REQUEST), a.fail(f), a;
(b = this._retrieveList(b)) ? (f.setStatus(h.OK).setBodyField("list", b), a.fulfill(f)) : (f.setStatus(h.NOT_FOUND), a.fail(f));
return a
},
"UPDATE /list": function (b) {
var a = this._baseLists,
f = this._createPromise(),
c = this._createResponse(),
d = b.body.descriptor,
b = b.body.list;
b.setDescriptor(d);
switch (d.type) {
case "list":
a[d.uri] = b, c.setStatus(h.OK).setBodyField("descriptor", d), f.fulfill(c)
}
return f
}
})
})();
(function () {
var d = Spotify.SimpleCache,
g = Spotify.LinkHelper,
c = Spotify.Promise,
h = Spotify.Shell.RequestQueue,
b = Spotify.Shell.Entities,
a = Spotify.ItemList,
f = a.Descriptor,
k = Spotify.Shell.ResponseStatus;
Spotify.Shell.DefaultReactors.create({
_construct: function () {
this._metadataService = this._cdnUrls = null;
this._albumCache = new d(1E3);
this._artistCache = new d(1E3);
this._trackCache = new d(1E3);
this._albumQueue = new h;
this._artistQueue = new h;
this._trackQueue = new h;
this._processAlbum = this._createProcessor(b.Album,
this._albumCache);
this._processArtist = this._createProcessor(b.Artist, this._artistCache);
this._processTrack = this._createProcessor(b.Track, this._trackCache);
this._handleAlbumError = this._createErrorHandler(this._albumCache);
this._handleArtistError = this._createErrorHandler(this._artistCache);
this._handleTrackError = this._createErrorHandler(this._trackCache);
this._subscribeAll({
"resources.core": this._onCore,
"resources.flush": this._onFlush,
"resources.image": this._onImageResources
})
},
_onCore: function (a) {
this._waitForServices({
_metadataService: a.metadata
})
},
_onFlush: function () {
this._queryMetadataService(this._albumQueue, this._processAlbum, this._handleAlbumError);
this._queryMetadataService(this._artistQueue, this._processArtist, this._handleArtistError);
this._queryMetadataService(this._trackQueue, this._processTrack, this._handleTrackError)
},
_onImageResources: function (a) {
this._cdnUrls = a;
this._ready && this._unqueue()
},
_onServicesReady: function () {
this._ready = !0;
this._cdnUrls && this._unqueue()
},
_queryMetadataService: function (a, b, f) {
var c = a.takeIds();
c.length &&
this._metadataService.lookup(c, b.bind(this, c, a), f.bind(this, c, a))
},
_createProcessor: function (a, b) {
return function (f, c, d) {
Array.isArray(f) || (f = [f]);
for (var k = 0, h = f.length; k < h; k++) this._processServiceItem(a, c, f[k], d[k]).then(b.put.bind(b, f[k]))
}
},
_processServiceItem: function (a, b, f, d) {
var h = this._createResponse(),
b = b.takeValues(f),
g = c.group(b),
b = this._cdnUrls.unbranded;
h.setBodyField("uri", f);
if (d) {
if (!d.resourceUrl) d.resourceUrl = b;
a.create(f, d).then(function (a) {
g.fulfill(h.setBodyField("result", a))
},
function () {
g.fail(h.setStatus(k.BAD_GATEWAY))
})
} else g.fail(h.setStatus(k.NOT_FOUND));
return g
},
_createErrorHandler: function (a) {
return function (b, f, d) {
Array.isArray(b) || (b = [b]);
for (var k = 0, h = b.length; k < h; k++) {
var g = b[k],
u = this._createResponse().setBodyField("uri", g),
w = f.takeValues(g),
w = c.group(w);
w.then(a.put.bind(a, g));
w.fail(u.setStatus(d.code))
}
}
},
_multiplexMetadataRequest: function (a, b, f) {
for (var c = a.headers, a = a.body, d = this._createPromise(), h = a.uris, g = h.length, u = {}, w = this._createResponse(), a = function (a) {
var b =
a.body;
u[b.uri] = a.status == k.OK ? b.result : null;
--g || d.fulfill(w.setBodyFields({
uris: h,
result: u
}))
}, v = 0, A = h.length; v < A; v++) b.get(f, {}, {
uri: h[v]
}).then(a, a);
c.flush && this._broadcastFlush();
return d
},
_getArtistSublist: function (a, b, f, c) {
var d = a.body,
a = this._createPromise(),
d = g.from(d.uri);
if (!d || d.type != "artist") return b = this._createResponse(), b.setHeader(k.BAD_REQUEST), a.fail(b), a;
f = d.toURI() + ":" + f;
c = this._handleListFetch.bind(this, d, c.bind(this, f, b), b);
return b.get("/list", {}, {
descriptor: {
type: "list",
uri: f
}
}).then(c, c)
},
_handleListFetch: function (a, b, f, c) {
var d = this._createResponse();
if (c.status == k.OK) return a = c.body.list, d.setStatus(k.OK).setBodyField("list", a), d;
else if (c.status == k.NOT_FOUND) return c = f.get("/artist", {
flush: !0
}, {
uri: a
}).then(function (a) {
a = b(a);
d.setBodyField("list", a);
return d
}), c.then(this._storeList.bind(this, a, f)), c;
else throw c;
},
_storeList: function (a, b, f) {
b.update("/list", {}, {
descriptor: {
type: "list",
uri: a
},
list: f.body.list
})
},
_processAlbum: function () {},
_processArtist: function () {},
_processTrack: function () {},
_createAlbumDecorator: function (b, d, k) {
var h = this,
b = this._createPromise(),
g = this._createPromise();
b.then(function (b) {
var k = b.body && b.body.result,
m = [];
if (k) {
for (var p = k.discs, v = [], A = 0, x = p.length; A < x; A++) {
var F = p[A],
G = h._wrapDecoratorRequest(d.createRequestSender("GET", "/tracks")),
B = new a.DiscTrack(F.uri, F.tracks),
B = new a.MetadataDecorator(B, G);
v.push(B);
m.push(d.update("/list", {}, {
descriptor: new f.List(F.uri),
list: B
}))
}
p = new a.AlbumTrack(k.uri, v);
m.push(d.update("/list", {}, {
descriptor: new f.List(k.uri),
list: p
}))
}
b = g.fulfill.bind(g, b);
c.join(m).then(b, b);
return g
}, function (a) {
g.fail(a);
return g
}).pipe(k);
return b
},
_createArtistDecorator: function () {
var a = this._createPromise();
a.then(function (a) {
return a
});
return a
},
_createTrackDecorator: function () {
var a = this._createPromise();
a.then(function (a) {
return a
});
return a
},
_createAlbumGroupList: function (b, f, c) {
return new a.Array(c.body.result.getAlbumGroups())
},
_createAppearsOnGroupList: function (b, f, c) {
return new a.Array(c.body.result.getAppearsOnGroups())
},
_createSingleGroupList: function (b, f, c) {
return new a.Array(c.body.result.getSingleGroups())
},
_createRelatedList: function (b, f, c) {
b = new a.Array(c.body.result.getRelatedArtists());
f = this._wrapDecoratorRequest(f.createRequestSender("GET", "/artists"));
return new a.MetadataDecorator(b, f)
},
_createToptracksList: function (b, f, c) {
b = new a.Array(c.body.result.getTopTracks());
f = this._wrapDecoratorRequest(f.createRequestSender("GET", "/tracks"));
return new a.MetadataDecorator(b, f)
},
"GET /track": function (a) {
var b =
a.headers,
f = a.body,
a = this._createPromise(),
f = g.from(f.uri);
if (!f || f.type != "track") return b = this._createResponse(), b.setHeader(k.BAD_REQUEST), a.fail(b), a;
var c = this._trackCache.get(f);
c ? c.status != k.OK ? a.fail(c) : a.fulfill(c) : (c = this._createTrackDecorator(), c.pipe(a), this._trackQueue.push(f, c), b.flush && this._broadcastFlush());
return a
},
"GET /tracks": function (a, b) {
return this._multiplexMetadataRequest(a, b, "/track")
},
"GET /album": function (a, b) {
var f = a.headers,
c = a.body,
d = this._createPromise(),
c = g.from(c.uri);
if (!c || c.type != "album") return f = this._createResponse(), f.setHeader(k.BAD_REQUEST), d.fail(f), d;
var h = this._albumCache.get(c);
h ? h.status != k.OK ? d.fail(h) : d.fulfill(h) : (h = this._createAlbumDecorator(a, b, d), this._albumQueue.push(c, h), f.flush && this._broadcastFlush());
return d
},
"GET /albums": function (a, b) {
return this._multiplexMetadataRequest(a, b, "/album")
},
"GET /album/tracks": function (a, b) {
var f = this._createPromise(),
c = g.from(a.body.uri),
d = this._createResponse();
if (!c || c.type != "album") return d.setHeader(k.BAD_REQUEST),
f.fail(d), f;
var h = b.createRequestSender("GET", "/list").bind(null, {}, {
descriptor: {
type: "list",
uri: c.toString()
}
}),
t = b.createRequestSender("GET", "/album").bind(null, {
flush: !0
}, {
uri: c.toString()
}),
u = function (a) {
return d.setBodyField("list", a.body.list)
};
return h().then(u, function () {
return t().then(function () {
return h()
}).then(u).catchError(function (a) {
throw a;
})
})
},
"GET /artist": function (a) {
var b = a.headers,
f = a.body,
a = this._createPromise(),
f = g.from(f.uri);
if (!f || f.type != "artist") return b = this._createResponse(),
b.setHeader(k.BAD_REQUEST), a.fail(b), a;
var c = this._artistCache.get(f);
c ? c.status != k.OK ? a.fail(c) : a.fulfill(c) : (c = this._createArtistDecorator(), c.pipe(a), this._artistQueue.push(f, c), b.flush && this._broadcastFlush());
return a
},
"GET /artists": function (a, b) {
return this._multiplexMetadataRequest(a, b, "/artist")
},
"GET /artist/albums": function (a, b) {
return this._getArtistSublist(a, b, "albums", this._createAlbumGroupList)
},
"GET /artist/appearances": function (a, b) {
return this._getArtistSublist(a, b, "appearances",
this._createAppearsOnGroupList)
},
"GET /artist/singles": function (a, b) {
return this._getArtistSublist(a, b, "singles", this._createSingleGroupList)
},
"GET /artist/related": function (a, b) {
return this._getArtistSublist(a, b, "related", this._createRelatedList)
},
"GET /artist/toptracks": function (a, b) {
return this._getArtistSublist(a, b, "top:tracks", this._createToptracksList)
}
})
})();
(function () {
var d = Spotify.SimpleCache,
g = Spotify.Promise,
c = Spotify.ItemList,
h = c.Descriptor,
b = Spotify.Shell.Entities,
a = Spotify.Shell.ResponseStatus;
Spotify.Shell.DefaultReactors.create({
_construct: function () {
this._cdnUrls = null;
this._metadataCache = new d(1E3);
this._popcountService = this._metadataService = null;
this._subscribeAll({
"resources.core": this._onCore,
"resources.image": this._onImageResources
})
},
_onCore: function (a) {
_core = a;
this._waitForServices({
_playlistService: a.playlist,
_popcountService: a.popcount
})
},
_onImageResources: function (a) {
this._cdnUrls = a;
this._ready && this._unqueue()
},
_queryPlaylistMetadataService: function (a) {
var b = this,
c = this._createPromise();
this._playlistService.metadata(a, function (d) {
b._processPlaylistMetadata(a, d).pipe(c)
}, function (d) {
b._handleMetadataError(a, d).pipe(c)
});
return c
},
_processPlaylistMetadata: function (f, c) {
var d = this._createPromise(),
h = this._cdnUrls.unbranded,
g = this._createResponse();
g.setBodyField("uri", f);
this._metadataCache.put(f, g);
if (!c.resourceUrl) c.resourceUrl =
h;
b.Playlist.create(f, c).then(function (a) {
d.fulfill(g.setBodyField("result", a))
}, function () {
d.fail(g.setStatus(a.BAD_GATEWAY))
});
return d
},
_handleMetadataError: function (a, b) {
var c = this._createPromise(),
d = this._createResponse();
d.setStatus(b.code).setBodyField("uri", a);
b.code == 404 && this._metadataCache.put(a, d);
c.fail(d);
return c
},
_createPlaylistTrackLoader: function () {
var a = this._playlistService;
return function (b, c) {
var d = new g;
a.list({
uri: b,
offset: c.begin,
length: c.length
}, d.fulfill.bind(d), d.fail.bind(d));
return d
}
},
_createPlaylistDecorator: function (a) {
var b = this,
d = this._createPromise(),
g = d.then(function (d) {
var g = d.body && d.body.uri;
if (g) {
var m = b._wrapDecoratorRequest(a.createRequestSender("GET", "/tracks")),
o = new c.PlaylistRow(g, b._createPlaylistTrackLoader()),
o = new c.PlaylistTrackDecorator(o, m);
return a.update("/list", {}, {
descriptor: new h.List(g),
list: o
}).then(function () {
return d
})
}
return d
}, function (a) {
throw a;
});
return {
promise: d,
decorated: g
}
},
"GET /playlist": function (b, c) {
var d = b.body,
h = this._createPromise(),
d = d.uri,
g = this._metadataCache.get(d);
g ? g.status != a.OK ? h.fail(g) : h.fulfill(g) : (g = this._createPlaylistDecorator(c), g.decorated.pipe(h), this._queryPlaylistMetadataService(d).pipe(g.promise));
return h
},
"GET /playlists": function (b, c) {
for (var d = b.headers, h = b.body, g = this._createPromise(), q = h.uris, n = q.length, s = {}, t = this._createResponse(), h = function (b) {
var f = b.body;
s[f.uri] = b.status == a.OK ? f.result : null;
--n || g.fulfill(t.setBodyFields({
uris: q,
result: s
}))
}, u = 0, w = q.length; u < w; u++) c.get("/playlist", {}, {
uri: q[u]
}).then(h,
h);
d.flush && this._broadcastFlush();
return g
}
})
})();
(function () {
Spotify.Shell.DefaultReactors.create({
_construct: function () {
this._playerGroup = this._listManager = this._CDNUrls = this._core = null;
this._coreRequestPromise = this._createPromise();
this._sourceRequestPromise = this._createPromise();
this._listManagerRequestPromise = this._createPromise();
this._playerGroupPromise = this._createPromise();
this._setReady()
},
"FLUSH /resources": function () {
var d = this._createPromise();
d.fulfill(!0);
this._broadcastFlush();
return d
},
"CREATE /resources/core": function (d) {
var g =
this._createPromise();
if (!this._core) this._core = d.body.core, this._broadcast("resources.core", this._core), this._coreRequestPromise.fulfill(this._core), g.fulfill(!0);
return g
},
"GET /resources/core": function () {
var d = this._createPromise();
this._core ? d.fulfill(this._core) : this._coreRequestPromise.pipe(d);
return d
},
"CREATE /resources/image": function (d) {
var d = d.body,
g = this._createPromise();
d.sources ? (this._CDNUrls = d.sources, this._broadcast("resources.image", this._CDNUrls), this._sourceRequestPromise.fulfill(this._CDNUrls),
g.fulfill(!0)) : g.fulfill(!1);
return g
},
"GET /resources/image": function () {
var d = this._createPromise();
this._CDNUrls ? d.fulfill(this._CDNUrls) : this._sourceRequestPromise.pipe(d);
return d
},
"CREATE /resources/listmanager": function (d) {
var d = d.body,
g = this._createPromise();
d.listManager ? (this._listManager = d.listManager, this._broadcast("resources.listmanager", this._listManager), this._listManagerRequestPromise.fulfill(this._listManager), g.fulfill(!0)) : g.fulfill(!1);
return g
},
"GET /resources/listmanager": function () {
var d =
this._createPromise();
this._listManager ? d.fulfill(this._listManager) : this._listManagerRequestPromise.pipe(d);
return d
},
"CREATE /resources/playergroup": function (d) {
var d = d.body,
g = this._createPromise();
d.playerGroup ? (this._playerGroup = d.playerGroup, this._broadcast("resources.playergroup", this._playerGroup), this._playerGroupPromise.fulfill(this._playerGroup), g.fulfill(!0)) : g.fulfill(!1);
return g
},
"GET /resources/playergroup": function () {
var d = this._createPromise();
this._playerGroup ? d.fulfill(this._playerGroup) :
this._playerGroupPromise.pipe(d);
return d
}
})
})();
(function () {
var d = Spotify.ItemList,
g = Spotify.Shell.SearchTypes;
Spotify.Shell.DefaultReactors.create({
_construct: function () {
this._fuzzyMatches = {};
this._searchTTL = 36E5;
this._searchService = this._cdnUrls = null;
this._subscribeAll({
"resources.core": this._onCore,
"resources.flush": this._onFlush,
"resources.image": this._onImageResources
})
},
_onCore: function (c) {
this._waitForServices({
_searchService: c.search
})
},
_onFlush: function () {},
_onImageResources: function (c) {
this._cdnUrls = c;
this._ready && this._unqueue()
},
_onServicesReady: function () {
this._ready = !0;
this._cdnUrls && this._unqueue()
},
_createSearchItemsLoader: function (c, d) {
var b = this,
a = this._fuzzyMatches,
f = this._searchService,
k = null,
m = this._cdnUrls;
switch (d) {
case g.ALBUMS:
k = f.ALBUMS;
break;
case g.ARTISTS:
k = f.ARTISTS;
break;
case g.PLAYLISTS:
k = f.PLAYLISTS;
break;
default:
k = f.TRACKS
}
return function (g) {
var p = b._createPromise();
f.search(c, {
type: k,
offset: g.begin,
length: g.length
}, function (b) {
if (b.didYouMean) a[c] = b.didYouMean;
for (var f = b[d].slice(0), k = 0, g = f.length; k < g; k++)
if (f[k]) f[k].resourceUrl = m.unbranded,
f[k].resourceUrls = m;
p.fulfill({
length: b.total[d],
items: f
})
}, function (a) {
p.fail(a)
});
return p
}
},
_handleListFetch: function (c, d, b, a) {
var f = null,
k = this._createResponse();
if (a.status == 200) return f = a.body.list, f.getRootBaseList().isOlderThan(this._searchTTL) ? this._createSearchList(c, d, b, k) : k.setBodyField("list", f);
else if (a.status == 404) return this._createSearchList(c, d, b, k);
else throw a;
},
_createSearchList: function (c, h, b, a) {
var f = c.toString() + ":" + b,
k = this._createSearchItemsLoader(c.query, b),
g = d.Search.create(b,
c, k),
g = new d.Property(g, "uri"),
c = this._wrapDecoratorRequest(h.createRequestSender("GET", "/" + b)),
g = new d.MetadataDecorator(g, c);
return h.update("/list", {}, {
descriptor: {
type: "list",
uri: f
},
list: g
}).then(function () {
return a.setBodyField("list", g)
})
},
"GET /search/tracks": function (c, d) {
var b = c.body.uri,
a = b.toString() + ":tracks",
b = this._handleListFetch.bind(this, b, d, "tracks");
return d.get("/list", {}, {
descriptor: {
type: "list",
uri: a
}
}).then(b, b)
},
"GET /search/artists": function (c, d) {
var b = c.body.uri,
a = b.toString() +
":artists",
b = this._handleListFetch.bind(this, b, d, "artists");
return d.get("/list", {}, {
descriptor: {
type: "list",
uri: a
}
}).then(b, b)
},
"GET /search/albums": function (c, d) {
var b = c.body.uri,
a = b.toString() + ":albums",
b = this._handleListFetch.bind(this, b, d, "albums");
return d.get("/list", {}, {
descriptor: {
type: "list",
uri: a
}
}).then(b, b)
},
"GET /search/playlists": function (c, d) {
var b = c.body.uri,
a = b.toString() + ":playlists",
b = this._handleListFetch.bind(this, b, d, "playlists");
return d.get("/list", {}, {
descriptor: {
type: "list",
uri: a
}
}).then(b, b)
},
"GET /search/fuzzymatch": function (c) {
var d = this._createPromise(),
b = this._searchService,
a = this._fuzzyMatches,
f = c.body.query,
k = this._createResponse();
f in a ? (k.setBodyField("match", a[f]), d.fulfill(k)) : b.search(f, {
type: b.TRACKS,
offset: 0,
total: 20
}, function (b) {
b = b.didYouMean || null;
a[f] = b;
k.setBodyField("match", b);
d.fulfill(k)
}, function () {
a[f] = null;
k.setBodyField("match", null);
d.fulfill(k)
});
return d
}
})
})();
(function () {
var d = Spotify.Link,
g = Spotify.ItemList,
c = Spotify.Shell.ResponseStatus;
Spotify.Shell.DefaultReactors.create({
_construct: function () {
this._toplistService = null;
this._subscribe("resources.core", this._onCore)
},
_onCore: function (c) {
this._waitForServices({
_toplistService: c.toplist
})
},
_handleServiceError: function (c) {
var b = this._createPromise(),
a = this._createResponse();
a.setStatus(c.code);
b.fail(a);
return b
},
_queryToplistForUser: function (c, b) {
var a = this,
f = this._createPromise();
this._toplistService.lookupForUser(c,
b, function (a, b) {
f.fulfill({
type: b,
array: a
})
}, function (b) {
a._handleServiceError(b).pipe(f)
});
return f
},
_queryToplistForRegion: function (c, b) {
var a = this,
f = this._createPromise();
this._toplistService.lookupForRegion(c, b, function (a, b) {
f.fulfill({
type: b,
array: a
})
}, function (b) {
a._handleServiceError(b).pipe(f)
});
return f
},
_createToplist: function (c, b, a) {
var f = a.type,
d = g.Toplist.create(f, c, a.array),
a = this._wrapDecoratorRequest(b.createRequestSender("GET", "/" + f + "s")),
d = new g.MetadataDecorator(d, a);
return b.update("/list", {}, {
descriptor: {
type: "list",
uri: c.toString()
},
list: d
}).then(function () {
return d
})
},
_handleUserToplistQuery: function (d, b, a, f) {
var k = null,
g = this._createResponse();
if (f.status == c.OK) return k = f.body.list, g.setBodyField("list", k);
else if (f.status == c.NOT_FOUND) return this._queryToplistForUser(d.username, a).then(this._createToplist.bind(this, d, b), function (a) {
throw a;
}).then(function (a) {
return g.setBodyField("list", a)
});
else throw f;
},
_handleRegionToplistQuery: function (d, b, a, f) {
var k = null,
g = this._createResponse();
if (f.status == c.OK) return k = f.body.list, g.setBodyField("list", k);
else if (f.status == c.NOT_FOUND) return this._queryToplistForRegion(d.country || null, a).then(this._createToplist.bind(this, d, b), function (a) {
throw a;
}).then(function (a) {
return g.setBodyField("list", a)
});
else throw f;
},
"GET /toplist": function (h, b) {
var a = this._createResponse(),
f = this._createPromise(),
k = h.body,
g = k.uri || null;
if (typeof g == "string") try {
g = d.fromString(g)
} catch (o) {}
if (!g) return a.setStatus(c.BAD_REQUEST), f.fail(a), f;
k.uri = g;
k = null;
switch (g.type) {
case "toplist":
k = "/toplist/region";
break;
case "user-toplist":
k = "/toplist/user"
}
return !k ? (a.setStatus(c.BAD_REQUEST), f.fail(a), f) : b.get(k, h.headers, h.body)
},
"GET /toplist/user": function (h, b) {
var a = this._toplistService,
f = this._createResponse(),
k = this._createPromise(),
g = h.body.uri || null;
if (typeof g == "string") try {
g = d.fromString(g)
} catch (o) {}
if (!g) return f.setStatus(c.BAD_REQUEST), k.fail(f), k;
f = null;
switch (g.toplist) {
case "albums":
f = a.ALBUM;
break;
case "artists":
f = a.ARTIST;
break;
case "playlists":
f =
a.PLAYLIST;
break;
default:
f = a.TRACK
}
a = this._handleUserToplistQuery.bind(this, g, b, f);
return b.get("/list", {}, {
descriptor: {
type: "list",
uri: g.toURI()
}
}).then(a, a)
},
"GET /toplist/region": function (h, b) {
var a = this._toplistService,
f = this._createResponse(),
k = this._createPromise(),
g = h.body.uri || null;
if (typeof g == "string") try {
g = d.fromString(g)
} catch (o) {}
if (!g) return f.setStatus(c.BAD_REQUEST), k.fail(f), k;
f = null;
switch (g.toplist) {
case "albums":
f = a.ALBUM;
break;
case "artists":
f = a.ARTIST;
break;
case "playlists":
f =
a.PLAYLIST;
break;
default:
f = a.TRACK
}
a = this._handleRegionToplistQuery.bind(this, g, b, f);
return b.get("/list", {}, {
descriptor: {
type: "list",
uri: g.toURI()
}
}).then(a, a)
}
})
})();
(function () {
Spotify.Bridge = new Spotify.Shell.EventEmitter;
Spotify.Bridge.SourceURLs = {
unbranded: "https://d3rt1990lpmkn.cloudfront.net/unbranded/",
tiny: "https://d3rt1990lpmkn.cloudfront.net/60/",
normal: "https://d3rt1990lpmkn.cloudfront.net/300/",
small: "https://d3rt1990lpmkn.cloudfront.net/120/",
large: "https://d3rt1990lpmkn.cloudfront.net/640/",
avatar: "https://d3rt1990lpmkn.cloudfront.net/artist_image/"
}
})();
(function () {
function d(b) {
this._storage = c[b] || (c[b] = {});
this._watchers = h[b] || (h[b] = {})
}
var g = !1,
c = {}, h = {};
d.prototype.wait = function (b, a) {
var f = this._watchers[b] || (this._watchers[b] = []);
f.indexOf(a) == -1 && f.push(a);
return this
};
d.prototype.store = function (b, a) {
var f = this._storage,
c = this._watchers[b],
d = f[b];
f[b] = a;
if (c && c.length)
for (var f = 0, h = c.length; f < h; f++) c[f](a, d);
return this
};
d.prototype.retrieve = function (b) {
var a = this._storage;
return b in a ? a[b] : null
};
Spotify.getStorage = function (b) {
if (g) throw Error("Cannot fetch from locked storage.");
return new d(b)
};
Spotify.lockStorage = function () {
g = !0
}
})();
(function () {
function d(a) {
Error.apply(this, arguments);
this.message = a
}
function g(a) {
d.call(this, a)
}
function c(a) {
d.call(this, a)
}
function h(a) {
d.call(this, a)
}
function b(a) {
d.call(this, a)
}
function a(a) {
d.call(this, a)
}
function f(a) {
d.call(this, a)
}
function k(a) {
d.call(this, a)
}
function m(a) {
d.call(this, a)
}
function o(a) {
d.call(this, a)
}
function p(a) {
d.call(this, a)
}
function q(a) {
d.call(this, a)
}
function n(a) {
d.call(this, a)
}
function s(a) {
d.call(this, a)
}
function t(a) {
d.call(this, a)
}
function u(a) {
d.call(this,
a)
}
var w = Spotify.Shell.ResponseStatus;
Spotify.Bridge.translateShellError = function (a) {
if (a instanceof Error) b = new d.Transient("Operation errored while performing request.");
else {
var b = a;
switch (a.status) {
case w.NOT_FOUND:
b = new d.NotFound("Resource not found.");
break;
case w.BAD_REQUEST:
b = new d.InvalidRequest("Request failed because of invalid arguments.")
}
}
throw b;
};
Spotify.inherit(d, Error);
d.prototype.name = "BridgeError";
d.prototype.type = "bridge-error";
Spotify.Bridge.Error = d;
d.Aborted = g;
d.Forbidden =
c;
d.Hermes = h;
d.InvalidRequest = b;
d.InvalidURI = a;
d.NotConnected = f;
d.NotFound = k;
d.NotImplemented = m;
d.OutOfDate = o;
d.PlayCapped = p;
d.RateLimited = q;
d.Timeout = n;
d.Transient = s;
d.Unknown = t;
d.Unplayable = u;
Spotify.inherit(g, d);
g.prototype.name = "BridgeAbortedError";
g.prototype.type = "aborted";
Spotify.inherit(c, d);
c.prototype.name = "BridgeForbiddenError";
c.prototype.type = "forbidden";
Spotify.inherit(h, d);
h.prototype.name = "BridgeHermesError";
h.prototype.type = "hermes";
Spotify.inherit(b, d);
b.prototype.name = "BridgeInvalidRequestError";
b.prototype.type = "invalid-request";
Spotify.inherit(a, d);
a.prototype.name = "BridgeInvalidURIError";
a.prototype.type = "invalid-uri";
Spotify.inherit(f, d);
f.prototype.name = "BridgeNotConnectedError";
f.prototype.type = "not-connected";
Spotify.inherit(k, d);
k.prototype.name = "BridgeNotFoundError";
k.prototype.type = "not-found";
Spotify.inherit(m, d);
m.prototype.name = "BridgeNotImplementedError";
m.prototype.type = "not-implemented";
Spotify.inherit(o, d);
o.prototype.name = "BridgeOutOfDateError";
o.prototype.type = "out-of-date";
Spotify.inherit(p, d);
p.prototype.name = "BridgePlayCappedError";
p.prototype.type = "play-capped";
Spotify.inherit(q, d);
q.prototype.name = "BridgeRateLimitedError";
q.prototype.type = "rate-limited";
Spotify.inherit(n, d);
n.prototype.name = "BridgeTimeoutError";
n.prototype.type = "timeout";
Spotify.inherit(s, d);
s.prototype.name = "BridgeTransientError";
s.prototype.type = "transient";
Spotify.inherit(t, d);
t.prototype.name = "BridgeUnknownError";
t.prototype.type = "unknown";
Spotify.inherit(u, d);
u.prototype.name = "BridgeUnplayableError";
u.prototype.type = "unplayable"
})();
(function () {
function d(b, a) {
for (var f in a) a.hasOwnProperty(f) && (b[f] = a[f]);
return b
}
function g(b, a, f) {
if (!(this instanceof g)) return new g(b, a, f);
this.timestamp = (new Date).getTime();
this._id = b;
this._origin = a;
this._source = f;
this._payload = null;
this._success = !0;
this._sent = this._persisted = this._hasPartial = !1
}
function c(b, a) {
if (!(this instanceof c)) return new c(b, a);
this._done = b;
this._error = a;
this._payload = null;
this._success = !0;
this._sent = this._persisted = this._hasPartial = !1
}
var h = Spotify.Bridge.Error;
Spotify.Bridge.Reply = g;
g.prototype.persist = function () {
this._persisted = !0;
return this
};
g.prototype.addPartial = function (b) {
if (!(this._sent || typeof b != "object")) this._hasPartial ? this._payload = d(this._payload, b) : (this._payload = d({}, b), this._hasPartial = !0)
};
g.prototype.send = function (b) {
if (this._sent) return null;
this._sent = !0;
this._hasPartial && (b = d(this._payload, b));
if (this._source) {
var a = {
id: this._id,
success: this._success,
payload: b
};
if (b.type) {
if (b.data) b.event = b.type;
if (b.receiver) b.target = b.receiver
}
this._source !==
window && this._source.postMessage(JSON.stringify(a), this._origin);
this._payload = this._source = this._origin = null
}
};
g.prototype.fail = function (b, a, f) {
if (this._sent) return null;
if (b instanceof h) f = b.code, a = b.message, b = b.type;
b = typeof b == "string" ? {
error: b,
message: a,
code: f
} : b;
this._success = !1;
return this.send(b)
};
g.prototype.timeout = function () {
return this._sent || this._persisted ? !1 : this.fail(new h.Timeout("Request timed-out."))
};
Spotify.inherit(c, g);
Spotify.Bridge.Reply.Internal = c;
c.prototype.send = function (b) {
if (this._sent) return null;
this._sent = !0;
this._hasPartial && (b = d(this._payload, b));
this._success && this._done ? this._done(b) : !this._success && this._error && this._error(b)
}
})();
(function () {
function d() {
this._requests = {};
this._hostMap = {}
}
function g(c, d, b) {
this._id = c;
this._request = d;
this._params = b || [];
this._status = "pending";
this._timestamp = (new Date).getTime();
this._roundtrip = 0
}
Spotify.Bridge.RequestLogger = d;
d.prototype.enter = function (c, d, b, a) {
var f = this._requests,
f = f[c] || (f[c] = {
total: 0,
success: 0,
failure: 0,
pending: 0,
requests: {}
});
f.total++;
f.pending++;
f.requests[d] = new g(d, b, a);
this._hostMap[d] = c
};
d.prototype.succeed = function (c, d) {
var b = this._hostMap[c];
if (!b) return this;
b = this._requests[b];
b.success++;
b.pending--;
b.requests[c].finish(d);
return this
};
d.prototype.fail = function (c, d) {
var b = this._hostMap[c];
if (!b) return this;
b = this._requests[b];
b.failure++;
b.pending--;
b.requests[c].finish(d);
return this
};
d.prototype.get = function (c) {
return this._requests[c] || null
};
d.prototype.formatted = function (c) {
var d = this.get(c);
if (!d) return "No logs for item.";
var b = [];
b.push([c, "- total:", d.total, "- success:", d.success, "- failed:", d.failure, "- pending:", d.pending].join(" "));
var c =
d.requests,
a;
for (a in c) b.push(c[a].toString());
return b.join("\n")
};
g.prototype.finish = function (c) {
this._status = c;
this._roundtrip = (new Date).getTime() - this._timestamp;
return this
};
g.prototype.toString = function () {
for (var c = this._params.slice(0, 5), d = Math.max(this._params.length - 5, 0), b = c.length; b--;) c[b] = JSON.stringify(c[b]);
return [" |", [" |- ", this._request, ": ", this._status].join(""), [" | [", this._status == "pending" ? "P" : this._roundtrip + "ms", "] params: [", c.join(", "), d !== 0 ? ", plus " + d + " more.." : "",
"]"
].join("")].join("\n")
};
g.prototype.toJSON = g.prototype.toString
})();
(function () {
function d(a, b, f) {
return function () {
if (!this._ready) return this.queue(f);
a[f].fn = b;
return b.apply(this, arguments)
}
}
function g(a) {
for (var b in a)
if (a.hasOwnProperty(b)) {
var f = b,
c = a[b];
switch (!0) {
case f == "flushRequests":
p.push(c.bind(this));
break;
case !!(matches = f.match(/^(\*|@)(\1)?([^*@]+)$/)):
var k = matches[1] == "*",
h = matches[2] ? o : m,
f = matches[3];
if (f in h) throw Error('Redefinition of message handler "' + f + '".');
if (typeof c == "string") {
if (c = h[c]) h[f] = c;
else throw Error('Aliasing of undefined message handler "' +
f + '".');
break
}
h[f] = {
bound: this,
fn: d(h, c, f),
passApp: k
};
break;
default:
this[f] = c
}
}
this._queue = [];
this.create && this.create();
if (this.init) Spotify.Bridge.onReady(this.init.bind(this));
return this
}
var c = Spotify.Promise,
h = Spotify.defer,
b = Spotify.Bridge,
a = b.Error,
f = b.Reply,
k = b.SourceURLs;
Spotify.getStorage("app.message.ns");
var m = {}, o = {}, p = [],
q = {}, n = {}, s = null;
Spotify.Bridge.Responder = g;
g.getHandler = function (a) {
return m[a]
};
g.respondsTo = function (a) {
return a in m
};
g.setPublisher = function (a) {
s = a;
return this
};
g.block = function (a) {
n[a] = !0;
return this
};
g.blockAll = function (a) {
for (var b = a.length; b--;) n[a[b]] = !0;
return this
};
g.unblock = function (a) {
n[a] = null;
return this
};
g.unblockAll = function () {
n = {};
return this
};
g.hasBlocked = function (a) {
return !!n[a]
};
g.handleBlocked = function (a, b, f) {
s && s.notify("LIMITED_FEATURE_CALL", {
origin: a.source,
feature: f,
callback: function () {}
});
return b.fail("restricted", "Cannot perform action in this session.")
};
g.prototype.traceOut = function () {
return function () {}
};
g.prototype.traceError =
function () {
return function () {}
};
g.flush = function () {
for (var a = p.length; a--;) p[a]()
};
g.prototype.use = function (a) {
var b = 0,
f = [],
c;
for (c in a) this[c] = a[c], f.push(a[c]), b++;
a = function () {
--b || this.start()
}.bind(this);
for (c = b; c--;) f[c].onReady(a, this);
return this
};
g.prototype._createPromise = function () {
return new c
};
g.prototype.queue = function (a) {
var b = this.queue.caller;
this._queue.push({
name: a,
fn: b,
args: b.arguments
})
};
g.prototype.unqueue = function () {
for (var a = this._queue, b = 0, f = a.length; b < f; b++) {
var c = a[b];
n[c.name] ? g.handleBlocked.apply(this, c.args.concat(c.name)) : c.fn.apply(this, c.args)
}
this._queue = [];
return this
};
g.prototype.store = function (a, b, f) {
(q[b] || (q[b] = new Spotify.SimpleCache(1E3))).put(a, f);
return this
};
g.prototype.retrieve = function (a, b) {
return q[b] ? q[b].get(a) || null : null
};
g.prototype.trigger = function (a, b, c, d) {
a = m[a] || o[a];
if (!a) return typeof d !== "undefined" ? d({
error: "not-implemented"
}) : null;
Array.isArray(b) && (b = {
args: b
});
c = new f.Internal(c, d);
(b = a.fn.call(a.bound || {}, b, c)) && b.then && b.then(c.send.bind(c),
c.fail.bind(c));
h(function () {
g.flush()
})
};
g.prototype._request = function (f, c, d) {
var k = this._createPromise(),
f = m[f] || o[f];
if (!f || !f.passApp) return k.fail(new a.NotImplemented("Message not implemented.")), k;
(c = f.fn.call(f.bound || {}, d, c)) && c.then ? c.catchError(b.translateShellError).pipe(k) : k.fulfill(c);
return k
};
g.prototype.createImageSizes = function (a, b) {
var f = [
[60, k.tiny + a],
[120, k.small + a],
[300, k.normal + a],
[640, k.large + a]
];
b && (f.shift(), f.pop());
return f
};
g.prototype.createUserImageSizes = function (a,
b) {
var f = [];
a && f.push([50, a]);
b && f.push([180, b]);
for (var c = 0, d = f.length; c < d; c++) {
var k = f[c][1].match(/^spotify:image:(.+)/);
k && (f[c][1] = Spotify.Bridge.SourceURLs.avatar + k[1])
}
return f
};
g.prototype.createSnapshot = function (a, b, f, c) {
var d = a[1] || 0,
a = a[2] || -1,
a = a == -1 ? b.length : a;
return {
range: {
offset: d,
length: a
},
length: f || b.length,
array: b.slice(d, d + a),
metadata: (c || []).slice(d, d + a)
}
};
g.prototype.createDimensions = function (a, b, f) {
a = a || 0;
f = f || 500;
b = b == -1 ? f : Math.min(b, f);
return {
start: a,
end: a + b - 1,
length: b
}
}
})();
(function () {
function d() {
this._keys = [];
this._values = []
}
Spotify.Bridge.WeakMap = d;
d.prototype.get = function (d) {
d = this._keys.indexOf(d);
return d == -1 ? null : this._values[d]
};
d.prototype.getKey = function (d) {
d = this._values.indexOf(d);
return d == -1 ? null : this._keys[d]
};
d.prototype.set = function (d, c) {
var h = this._keys,
b = this._values,
a = h.indexOf(d);
if (a != -1) return b[a] = c, this;
h.push(d);
b.push(c);
return this
};
d.prototype.remove = function (d) {
var c = this._keys,
h = this._values,
d = c.indexOf(d);
if (d == -1) return this;
c.splice(d,
1);
h.splice(d, 1);
return this
};
d.prototype.clear = function () {
this._keys.splice(0, this._keys.length);
this._values.splice(0, this._values.length);
return this
}
})();
(function () {
function d(a, b, c) {
for (var d = 0, h = b, b = c.length + b; h < b; d++, h++) a[h] = c[d]
}
function g(a) {
for (var b = a.length; b;) {
var c = Math.floor(Math.random() * b--),
d = a[b];
a[b] = a[c];
a[c] = d
}
return a
}
function c(a, f) {
this._id = a;
this._rule = b.defaults;
this._currentIndex = 0;
this._shuffled = this._repeated = !1;
this._shuffledList = null;
this._metadata = [];
var c = this._list = this._origin = [];
if (!f) return this;
for (var d = 0, h = f.length; d < h; d++) d in f && f[d] && c.push(f[d])
}
var h = Spotify.getStorage("app.context.ns");
h.store("quickShuffle",
g);
var b = {
defaults: {
skipCount: -1,
volume: !0,
seek: !0,
indexing: !0,
previous: !0,
next: !0,
shuffle: !0,
repeat: !0
},
intercept: {
skipcount: -1,
volume: !1,
seek: !1,
indexing: !0,
previous: !1,
next: !1,
shuffle: !1,
repeat: !1
},
radio: {
skipCount: -1,
volume: !0,
seek: !0,
indexing: !0,
previous: !1,
next: !0,
shuffle: !1,
repeat: !1
},
dmca: {
skipCount: 6,
volume: !0,
seek: !0,
indexing: !0,
previous: !1,
next: !0,
shuffle: !1,
repeat: !1
},
stream: {
skipcount: -1,
volume: !0,
seek: !1,
indexing: !0,
previous: !1,
next: !1,
shuffle: !1,
repeat: !1
}
};
h.store("Context", c);
c.prototype.getId =
function () {
return this._anonymous ? null : this._id
};
c.prototype.setAnonymous = function (a) {
this._anonymous = !! a;
return this
};
c.prototype.setRule = function (a) {
return (a = b[a]) ? (this._rule = a, !0) : !1
};
c.prototype.getRule = function () {
return this._rule
};
c.prototype.setRepeat = function (a) {
return !this._rule.repeat ? !1 : this._repeated = a
};
c.prototype.isRepeated = function () {
return this._repeated
};
c.prototype.setShuffle = function (a) {
if (!this._rule.shuffle) return !1;
(this._shuffled = a) ? this._shuffle() : this._unshuffle();
return a
};
c.prototype.isShuffled = function () {
return this._shuffled
};
c.prototype.setExpiry = function (a) {
if (!a || a < 0) return this;
this._time = (new Date).getTime();
this._ttl = a;
return this
};
c.prototype.isExpired = function () {
var a = this._ttl;
return !a ? !1 : (new Date).getTime() - this._time >= a
};
c.prototype.mapToURI = function (a, b) {
return b || a
};
c.prototype.mapToId = function (a, b) {
return b || a
};
c.prototype._shufflePartial = function (a) {
var b = this._shuffledList;
if (!b) return this;
for (var c = this._origin.length - a, d = Array(c); c--;) d[c] = a +
c;
g(d).unshift(a, 0);
b.splice.apply(b, d);
return this
};
c.prototype._shuffle = function (a) {
if (a != void 0) return this._shufflePartial(a);
for (var b = this._origin.length, a = Array(b); b--;) a[b] = b;
b = a.splice(this._currentIndex, 1).pop();
g(a).unshift(b);
this._list = this._shuffledList = a;
this._currentIndex = 0;
return this
};
c.prototype._unshuffle = function () {
if (!this._shuffledList) return this;
this._list = this._origin;
this._currentIndex = this._shuffledList[this._currentIndex];
return this
};
c.prototype.get = function (a) {
var b =
this._origin;
if (a < 0 || a > b.length) return null;
this._shuffled && (a = this._shuffledList[a]);
b = b[a];
a = this._metadata[a];
return !b || !a ? null : {
item: b,
metadata: a
}
};
c.prototype.getList = function () {
return this._origin
};
c.prototype.getLength = function () {
return this._origin.length
};
c.prototype.setFullLength = function (a) {
if (typeof a != "number" && (a = parseInt(a, 10), isNaN(a))) throw new TypeError("Cannot set possible length to a non-number");
this._actualLen = a;
return this
};
c.prototype.getFullLength = function () {
return this._actualLen !=
void 0 ? Math.max(this._actualLen, this.getLength()) : this.getLength()
};
c.prototype.append = function (a) {
if (!a) return this;
if (this._resolved) Spotify.Bridge.trigger("track_multi_metadata", [a], function (b) {
var f = this._origin.push(a) - 1;
this._metadata.push(b[a]);
this._shuffled && this._shuffle(f)
}.bind(this));
else {
var b = this._origin.push(a) - 1;
this._shuffled && this._shuffle(b)
}
return this
};
c.prototype.prependMany = function (a) {
a = Array.isArray(a) ? a : [a];
this._resolved ? Spotify.Bridge.trigger("track_multi_metadata", a,
function (b) {
this._origin.unshift.apply(this._origin, a);
for (var c = [], d = 0, h = a.length; d < h; d++) c[d] = b[a[d]];
this._metadata.unshift.apply(this._metadata, c);
this._shuffled && this._shuffle(0)
}.bind(this)) : (this._origin.unshift.apply(this._origin, a), this._shuffled && this._shuffle(0));
return this
};
c.prototype.appendWithMeta = function (a, b) {
if (!a || !b) return this;
var c = this._origin.push(a) - 1;
this._metadata[c] = b;
this._shuffled && this._shuffle(c);
return this
};
c.prototype.concat = function (a) {
if (!a || !a.length) return this;
if (this._resolved) Spotify.Bridge.trigger("track_multi_metadata", a, function (b) {
for (var f = 0, c = a.length; f < c; f++) this._origin.push(a[f]), this._metadata.push(b[a[f]]);
this._shuffled && this._shuffle(this._origin.length - a.length - 1)
}.bind(this));
else {
for (var b = 0, c = a.length; b < c; b++) this._origin.push(a[b]);
this._shuffled && this._shuffle(this._origin.length - a.length - 1)
}
return this
};
c.prototype.splice = function (a, b) {
if (typeof a == "undefined" || !b || !b.length) return this;
if (this._resolved) Spotify.Bridge.trigger("track_multi_metadata",
b, function (c) {
for (var k = [], h = [], g = 0, m = b.length; g < m; g++) g in b && b[g] && (k.push(b[g]), h.push(c[b[g]]));
d(this._origin, a, b);
d(this._metadata, a, h);
this._shuffled && this._shuffle(a)
}.bind(this));
else {
for (var c = [], h = 0, g = b.length; h < g; h++) h in b && b[h] && c.push(b[h]);
d(this._origin, a, c);
this._shuffled && this._shuffle(a)
}
};
c.prototype.trim = function (a, b) {
var c = this._origin;
if (c[a] != b) return !1;
a += 1;
var d = c.length;
c.splice(a, d);
this._resolved && this._metadata.splice(a, d);
this._shuffled && this._shuffle();
return !0
};
c.prototype.insert =
function (a, b, c) {
if (!c) return !1;
typeof c == "string" && (c = [c]);
var d = this._origin;
if (d[a] != b) return !1;
this._resolved ? Spotify.Bridge.trigger("track_multi_metadata", c, function (h) {
d.splice.apply(d, [a, 1, b].concat(c));
for (var g = [], q = 0, n = c.length; q < n; q++) g.push(h[c[q]]);
this._metadata.splice.apply(this._metadata, [a + 1, 0].concat(g))
}.bind(this)) : d.splice.apply(d, [a, 1, b].concat(c));
return !0
};
c.prototype.remove = function (a, b) {
if (!b) return !1;
var c = this._origin;
if (c[a] != b) return !1;
c.splice(a, 1);
this._resolved && this._metadata.splice(a,
1);
this._shuffled && this._shuffle();
return !0
};
c.prototype.clear = function () {
var a = this._origin,
b = this._metadata;
a.splice(0, a.length);
b.splice(0, b.length);
return this
};
c.prototype.hasRange = function (a, b) {
var c = this._origin;
if (a < 0) return !1;
if (b >= c.length) return !1;
for (var c = c.slice(a, b), d = c.length; d--;)
if (!(d in c)) return !1;
return !0
};
c.prototype.slice = function (a, b) {
return this._origin.slice(a, b)
};
c.prototype.indexOf = function (a) {
return this._list.indexOf(a)
};
c.prototype.getIndex = function () {
return this._rule.indexing ?
this._currentIndex : 0
};
c.prototype.getPlayingIndex = function () {
return this._shuffled ? this._shuffledList[this._currentIndex] : this._currentIndex
};
c.prototype.startFrom = function (a) {
var b = a.track;
if (this._shuffled) {
a = this._shuffledList;
if (b == -1) {
do b = Math.floor(Math.random() * a.length); while (b >= a.length)
}
for (var c = a.length; c--;)
if (a[c] === b) {
b = a[0];
a[0] = a[c];
a[c] = b;
this._currentIndex = 0;
break
}
} else this._currentIndex = b == -1 ? 0 : b;
return this
};
c.prototype.current = function () {
var a = this._shuffled ? this._list[this._currentIndex] :
this._currentIndex;
return {
item: this._origin[a],
metadata: this._metadata[a]
}
};
c.prototype.shift = function () {
var a = this._shuffled ? this._list[this._currentIndex] : this._currentIndex;
if (!this._origin[a]) return null;
var b = {
item: this._origin[a],
metadata: this._metadata[a]
};
this._origin.splice(a, 1);
this._metadata.splice(a, 1);
this._shuffled && this._list.splice(this._currentIndex, 1);
return b
};
c.prototype.hasNext = function () {
return this._repeated || this._currentIndex + 1 < this._origin.length
};
c.prototype.next = function () {
if (!this._rule.next) return !1;
var a = ++this._currentIndex,
b = this._origin;
if (this._repeated) {
if (a >= b.length) a = this._currentIndex = 0;
this._shuffled && (a = this._shuffledList[a]);
return {
item: b[a],
metadata: this._metadata[a]
}
} else if (a < b.length) return this._shuffled && (a = this._shuffledList[a]), {
item: b[a],
metadata: this._metadata[a]
};
this._currentIndex--;
return null
};
c.prototype.hasPrevious = function () {
return this._repeated || this._currentIndex - 1 >= 0
};
c.prototype.previous = function () {
if (!this._rule.previous) return !1;
var a = --this._currentIndex,
b = this._origin;
if (this._repeated) {
if (a < 0) a = this._currentIndex = b.length - 1;
this._shuffled && (a = this._shuffledList[a]);
return {
item: b[a],
metadata: this._metadata[a]
}
} else if (a >= 0) return this._shuffled && (a = this._shuffledList[a]), {
item: b[a],
metadata: this._metadata[a]
};
this._currentIndex++;
return null
};
c.prototype._loader = null;
c.prototype.setLoader = function (a) {
if (typeof a != "function") return this;
this._loader = a;
return this
};
c.prototype._requestContents = function (a, b) {
return !this._loader || this._origin.length ==
this.getFullLength() ? b.call(this) : this._loader.call(this, this, a.track, b.bind(this))
};
c.prototype._resolved = !1;
c.prototype._resolvePartial = function (a, b, c, d, h) {
for (var g = this._metadata, q = a.length; q--;) g[a[q].idx] = h[a[q]];
this._resolved = !0;
if (!b) return this;
c(this);
this._requestMeta(b, null, null, d)
};
c.prototype._requestMeta = function (a, b, c, d) {
Spotify.Bridge.trigger("track_multi_metadata", a, this._resolvePartial.bind(this, a, b, c, d), d.bind(null))
};
c.prototype._resolve = function (a, b, c) {
b = b || function () {};
c = c ||
function () {};
if (this._resolved) return b(this);
var a = a == -1 ? 0 : a || 0,
d = this._origin,
h = this._shuffledList,
g = Math.max(a - 7, 0),
q, n, s, t = [];
if (this._shuffled) {
for (q = 0, n = h.length; q < n; q++) s = new String(d[h[q]]), s.idx = h[q], h[q] == a ? (h.unshift(h.splice(q, 1).pop()), t.unshift(s)) : t.push(s);
g = this._currentIndex = 0
} else
for (q = 0, n = d.length; q < n; q++) s = new String(d[q]), s.idx = q, t.push(s);
this._requestMeta(t.splice(g, 15), t, b, c)
};
c.prototype.resolve = function (a, b, c) {
this._requestContents(a, this._resolve.bind(this, a.track, b, c))
}
})();
(function () {
function d(a) {
this._id = a;
this._repeated = this._shuffled = !1;
this._currentContext = 0;
this._contexts = [];
this._shuffledContexts = [];
this._noReset = new g;
this._ttl = (new Date).getTime();
this.setRule("defaults")
}
var g = Spotify.Bridge.WeakMap,
c = Spotify.getStorage("app.context.ns"),
h = c.retrieve("quickShuffle"),
b = c.retrieve("Context");
c.store("ContextGroup", d);
d.prototype.mapToId = b.prototype.mapToId;
d.prototype.mapToURI = b.prototype.mapToURI;
d.prototype.setExpiry = b.prototype.setExpiry;
d.prototype.isExpired =
b.prototype.isExpired;
d.prototype.setRule = b.prototype.setRule;
d.prototype.getContext = function (a) {
a = a != void 0 ? a : this._currentContext;
return this._shuffled ? this._contexts[this._shuffledContexts[a]] : this._contexts[a]
};
d.prototype.getContextIds = function () {
var a = [],
b = this._contexts,
c = b.length;
if (!c) return a;
for (; c--;) a[c] = b[c].getId();
return a
};
d.prototype.getRule = function () {
return this.getContext().getRule()
};
d.prototype.setShuffle = function (a) {
if (!this._rule.shuffle) return !1;
(this._shuffled = a) ? this._shuffle() :
this._unshuffle();
return a
};
d.prototype.isShuffled = function () {
return this._shuffled
};
d.prototype.setRepeat = function (a) {
return !this._rule.repeat ? !1 : this._repeated = a
};
d.prototype.isRepeated = function () {
return this._repeated
};
d.prototype.startFrom = function (a) {
var b = a.context;
if (this._shuffled) {
var c = this._shuffledContexts;
if (b == -1) {
do b = Math.floor(Math.random() * c.length); while (b >= c.length)
}
for (var d = c.length; d--;)
if (c[d] === b) {
b = c[0];
c[0] = c[d];
c[d] = b;
this._currentContext = 0;
break
}
} else this._currentContext =
b == -1 ? 0 : b;
(c = this.getContext()) && c.startFrom(a);
return this
};
d.prototype._shufflePartial = function (a) {
var b = this._shuffledContexts;
if (!b) return this;
for (var c = this._contexts, d = c.length - a, g = Array(d); d--;) {
var p = c[a + d];
p && p.setShuffle(!0);
g[d] = a + d
}
h(g).unshift(a, 0);
b.splice.apply(b, g)
};
d.prototype._shuffle = function (a) {
if (a != void 0) return this._shufflePartial(a);
for (var b = this._contexts.slice(0), a = this._shuffledContexts = [], c = 0, d = b.length; c < d; c++) b[c].setShuffle(!0), a.push(c);
b = a.splice(this._currentContext,
1).pop();
h(a).unshift(b);
this._currentContext = 0;
this._noReset.clear();
this._noReset.set(this.getContext(), !0);
return this
};
d.prototype._unshuffle = function () {
this._currentContext = this._shuffledContexts[this._currentContext];
for (var a = this._contexts.slice(0), b = 0, c = a.length; b < c; b++) a[b].setShuffle(!1);
this._noReset.clear();
return this
};
d.prototype.append = function (a) {
this._contexts.push(a.unwrap());
this._resolved && a.resolve({
track: 0,
context: 0
});
this._shuffled && this._shuffle(this.length - 1);
return this
};
d.prototype.concat = function (a) {
if (!a || !a.length) return this;
for (var b = 0, c = a.length; b < c; b++) this._contexts.push(a[b].unwrap()), this._resolved && a[b].resolve({
track: 0,
context: 0
});
this._shuffled && this._shuffle(this._contexts.length - a.length)
};
d.prototype.splice = function (a, b) {
if (typeof a == "undefined" || !b || !b.length) return this;
for (var c = [a, b.length], d = 0, h = b.length; d < h; d++) d in b && b[d] && (c.push(b[d].unwrap()), this._resolved && b[d].resolve({
track: 0,
context: 0
}));
this._contexts.splice.apply(this._origin, c);
this._shuffled && this._shuffle(a)
};
d.prototype.insert = function (a, b, c) {
if (!c) return !1;
var d = this._contexts,
b = b.unwrap(),
c = c.unwrap();
if (d[a] != b) return !1;
d.splice(a, 1, b, c);
this._resolved && c.resolve({
track: 0,
context: 0
});
return !0
};
d.prototype.remove = function (a, b) {
if (!b) return !1;
var c = this._contexts,
b = b.unwrap();
if (c[a] != b) return !1;
c.splice(a, 1);
this._shuffled && this._shuffle();
return !0
};
d.prototype.clear = function () {
var a = this._contexts;
a.splice(0, a.length);
return this
};
d.prototype.slice = function (a, b) {
return this._contexts.slice(a,
b)
};
d.prototype.get = function (a) {
for (var b = this._contexts, c = 0, d = b.length; c < d; c++) {
var h = b[c],
g = h.getLength();
if (g < a) a -= g;
else return h.get(a)
}
return null
};
d.prototype.current = function () {
return this.getContext().current()
};
d.prototype.getIndex = function (a) {
var b = this.getContext().getIndex();
if (!a) return b;
for (var a = this._currentContext, c = this._contexts, d = 0; d != a; d++) b += c[d]._origin.length;
return b
};
d.prototype.getPlayingIndex = function () {
return this.getContext().getPlayingIndex()
};
d.prototype.getContextIndex =
function () {
return this._shuffled ? this._shuffledContexts[this._currentContext] : this._currentContext
};
d.prototype.getLength = function (a) {
if (!a) return this.getContext().getLength();
for (var a = 0, b = this._contexts.length; b--;) a += this._contexts[b]._origin.length;
return a
};
d.prototype.getFullLength = function () {
return this.getContext().getFullLength()
};
d.prototype.getContextsLength = function () {
return this._contexts.length
};
d.prototype.previous = function () {
if (!this._rule.previous) return !1;
var a = this._contexts,
b =
a.length,
c = null,
d;
if (this._shuffled)
for (var h = this._noReset; b--;) {
d = --this._currentContext;
if (d < 0) d = this._currentContext = a.length - 1;
d = a[this._shuffledContexts[d]];
if (!d) return null;
if (this._repeated && d._currentIndex == 0) d._currentIndex = d.getLength();
h.get(d) || (d._currentIndex++, h.set(d, !0));
if (c = this.getContext().previous()) break
} else
for (; b--;) {
if (c = this.getContext().previous()) break;
d = --this._currentContext;
if (d < 0) {
if (!this._repeated) {
this._currentContext++;
break
}
d = this._currentContext = a.length -
1
}
d = a[d];
if (!d) return null;
d._currentIndex = d.getLength()
}
return c
};
d.prototype.next = function () {
if (!this._rule.next) return !1;
var a = this._contexts,
b = a.length,
c = null,
d;
if (this._shuffled)
for (var h = this._noReset; b--;) {
d = ++this._currentContext;
if (d >= a.length) d = this._currentContext = 0;
next = a[this._shuffledContexts[d]];
if (!next) return null;
if (this._repeated && next._currentIndex == next.getLength() - 1) next._currentIndex = -1;
h.get(next) || (next._currentIndex--, h.set(next, !0));
if (c = this.getContext().next()) break
} else
for (; b--;) {
if (c =
this.getContext().next()) break;
d = ++this._currentContext;
if (d >= a.length) {
if (!this._repeated) {
this._currentContext--;
break
}
d = this._currentContext = 0
}
next = a[d];
if (!next) return null;
next._currentIndex = -1
}
return c
};
d.prototype.getId = function () {
return this.getContext().getId()
};
d.prototype.resolve = function (a, b, c) {
this.startFrom(a);
var d = this._contexts;
if (this._resolved) return b();
this.getContext().resolve(a, function () {
this._resolved = !0;
b();
for (var c = d.length; c--;) d[c].resolve(a)
}.bind(this), c)
}
})();
(function () {
function d(a) {
this._context = a;
this._owner = ""
}
function g() {
this.cache = new b(1E3)
}
function c(a, b, c) {
a = new a(b.toString());
this.cache.put(b, a);
return (new d(a)).setExpiry(c)
}
function h(a, b, c, f) {
var h = this.cache.get(b.toString());
if (h)
if (h.isExpired()) this.cache.remove(h);
else return (new d(h)).setExpiry(f);
return c ? a == k ? this.create(b, f) : this.createGroup(b, f) : null
}
var b = Spotify.SimpleCache,
a = Spotify.getStorage("app.ns"),
f = Spotify.getStorage("app.context.ns"),
k = f.retrieve("Context"),
m = f.retrieve("ContextGroup");
d.prototype.getOwner = function () {
return this._owner
};
d.prototype.unwrap = function () {
return this._context
};
d.prototype.setOwner = function (a) {
if (a) this._owner = a;
return this
};
d.prototype.isContext = function () {
return this._context instanceof k
};
d.prototype.isContextGroup = function () {
return this._context instanceof m
};
for (var o in k.prototype)(function (a) {
d.prototype[a] = function () {
var b = this._context,
c = b[a];
if (!c) throw Error('Context object has no method "' + a + '"');
c = c.apply(b, arguments);
return c == b ? this : c
}
})(o);
a.store("ContextManager", g);
g.prototype.create = function (a, b) {
return c.call(this, k, a, b)
};
g.prototype.createGroup = function (a, b) {
return c.call(this, m, a, b)
};
g.prototype.get = function (a, b, c) {
return h.call(this, k, a, b, c)
};
g.prototype.getGroup = function (a, b, c) {
return h.call(this, m, a, b, c)
};
g.prototype.remove = function (a) {
return this.cache.remove(a.toString())
}
})();
(function () {
function d(a, b, c, d) {
var f;
h.call(this);
this._available = this._uid = 0;
this._previous = {};
this._incoming = {};
f = this.audioManager = a.audioManager, a = f;
this.player = b;
this.logging = a.getTrackerForPlayerWithId(b.id);
this.alternate = c;
this._fade = !! d;
this._intercept = !1;
this._interceptions = this._intercepted = null;
this._queue = [];
this._history = [];
this.setup()
}
var g = Spotify.Link,
c = Spotify.defer,
h = Spotify.Shell.EventEmitter,
b = Spotify.getStorage("app.ns"),
a = [].slice;
d.prototype = new h;
d.prototype.constructor =
d;
b.store("ContextPlayer", d);
d.prototype.setup = function () {
var a = this.player;
a.bind("BEFORE_END", this.onBeforeEnded, this);
a.onPlay = this.onPlay.bind(this);
a.onPause = this.onPause.bind(this);
a.onTrackEnded = this.onEnded.bind(this);
a.onInvalidTrackUri = a.onPlaybackFailed = this.onInvalid.bind(this)
};
d.prototype.onPlay = function () {
if (!this._hardStopped) {
this._available++;
this._keepPlay && this.player.resume();
delete this._keepPlay;
this.fireEvent("play");
var a = this.player.trackUri,
b = this._incoming[a];
delete this._incoming[a];
b && c(b.bind(this))
}
};
d.prototype.onPause = function () {
this.fireEvent("pause")
};
d.prototype.onBeforeEnded = function () {
var a = this;
if (this._fade && !this._currentContext.hasNext()) a._crossfading = !0, this._fadeback != null && this._fadeback && a.alternate.resume(), this.audioManager.crossfade(this.player.id, this.alternate.id, 800, function () {
a.player.pause();
a._fadeback = null;
a._crossfading = !1
})
};
d.prototype.onEnded = function () {
delete this._keepPlay;
this.fireEvent("ended");
this._playIntercepted() || this.next(!0)
};
d.prototype.onInvalid =
function (a) {
delete this._keepPlay;
var b = a.params.data,
d = this._incoming[b];
delete this._incoming[b];
d && c(d.bind(this, "unplayable"));
b = this.next.bind(this, !0, function (a) {
if (!(a !== "no-context" || a !== "forbidden" || a !== "no-tracks")) a = this._previous, this._currentContext = a.context, this._currentTrack = a.track, this._currentGroup = a.group
}.bind(this));
a.params.domain == 12 && (a.params.code == 8 || a.params.code == 12) || b()
};
d.prototype._shuffled = !1;
d.prototype.setShuffle = function (a) {
this._shuffled = a = !! a;
var b = this._currentContext;
b && b.setShuffle(a);
return !0
};
d.prototype._repeated = !1;
d.prototype.setRepeat = function (a) {
this._repeated = a = !! a;
var b = this._currentContext;
b && b.setRepeat(a);
return !0
};
d.prototype.setVolume = function (a) {
if (typeof a != "number") return !1;
this.audioManager.setMasterVolume(a);
return !0
};
d.prototype.getState = function (a) {
var b = this.player.getPlayerState(),
c = this._currentContext,
b = {
__uid: this._uid,
__index: c ? c.getIndex(!0) : null,
__length: c ? c.getLength(!0) : null,
__rules: c ? c.getRule() : {},
__owner: c ? c.getOwner() : null,
playing: this._keepPlay ? !0 : !b.isPaused && !b.isStopped,
context: c ? {
uri: c.getId()
} : null,
index: !c ? null : c.getPlayingIndex(),
track: this._currentTrack || {
View raw

(Sorry about that, but we can’t show files that are this big right now.)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment