Skip to content

Instantly share code, notes, and snippets.

@plasticine
Created April 5, 2013 03:17
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save plasticine/5316347 to your computer and use it in GitHub Desktop.
Save plasticine/5316347 to your computer and use it in GitHub Desktop.
<!DOCTYPE html>
<html>
<head>
<meta http-equiv="X-UA-Compatible" content="IE=Edge" />
<script charset="UTF-8" type="text/javascript">var Locale = {"currency": {"nok": {"position": "end", "symbol": " kr."}, "mxn": {"position": "start", "symbol": "$"}, "brl": {"symbol": "R$"}, "ltl": {"position": "end", "symbol": " Lt"}, "sek": {"position": "end", "symbol": " kr."}, "usd": {"symbol": "$"}, "aud": {"symbol": "$"}, "isk": {"position": "end", "symbol": " kr."}, "gbp": {"symbol": "\u00a3"}, "nzd": {"symbol": "$"}, "lvl": {"position": "end", "symbol": " Ls"}, "cad": {"symbol": "$"}, "dkk": {"position": "end", "symbol": " kr."}, "eur": {"position": "end", "symbol": "\u20ac"}}, "defaultCurrencyCode": "usd", "currencyForCountryCode": {"ee": "eur", "ca": "cad", "it": "eur", "au": "aud", "at": "eur", "ie": "eur", "es": "eur", "nl": "eur", "pt": "eur", "no": "nok", "lt": "ltl", "lv": "lvl", "nz": "nzd", "is": "isk", "be": "eur", "fr": "eur", "dk": "dkk", "de": "eur", "br": "brl", "fi": "eur", "us": "usd", "mx": "mxn", "se": "sek", "gb": "gbp"}, "longDate": "%B %-d, %Y", "pluralizationRules": ["num == 1", "true"], "timeFormat": "%I:%M %p", "shortDate": "%m/%d/%y", "percent": "%", "number": {"decimal": ".", "delimiterPos": 3, "delimiter": ","}, "strings": {}};</script>
<script charset="UTF-8" type="text/javascript" >
/*! LAB.js (LABjs :: Loading And Blocking JavaScript)
v2.0.3 (c) Kyle Simpson
MIT License
*/
(function(o){var K=o.$LAB,y="UseLocalXHR",z="AlwaysPreserveOrder",u="AllowDuplicates",A="CacheBust",B="BasePath",C=/^[^?#]*\//.exec(location.href)[0],D=/^\w+\:\/\/\/?[^\/]+/.exec(C)[0],i=document.head||document.getElementsByTagName("head"),L=(o.opera&&Object.prototype.toString.call(o.opera)=="[object Opera]")||("MozAppearance"in document.documentElement.style),q=document.createElement("script"),E=typeof q.preload=="boolean",r=E||(q.readyState&&q.readyState=="uninitialized"),F=!r&&q.async===true,M=!r&&!F&&!L;function G(a){return Object.prototype.toString.call(a)=="[object Function]"}function H(a){return Object.prototype.toString.call(a)=="[object Array]"}function N(a,c){var b=/^\w+\:\/\//;if(/^\/\/\/?/.test(a)){a=location.protocol+a}else if(!b.test(a)&&a.charAt(0)!="/"){a=(c||"")+a}return b.test(a)?a:((a.charAt(0)=="/"?D:C)+a)}function s(a,c){for(var b in a){if(a.hasOwnProperty(b)){c[b]=a[b]}}return c}function O(a){var c=false;for(var b=0;b<a.scripts.length;b++){if(a.scripts[b].ready&&a.scripts[b].exec_trigger){c=true;a.scripts[b].exec_trigger();a.scripts[b].exec_trigger=null}}return c}function t(a,c,b,d){a.onload=a.onreadystatechange=function(){if((a.readyState&&a.readyState!="complete"&&a.readyState!="loaded")||c[b])return;a.onload=a.onreadystatechange=null;d()}}function I(a){a.ready=a.finished=true;for(var c=0;c<a.finished_listeners.length;c++){a.finished_listeners[c]()}a.ready_listeners=[];a.finished_listeners=[]}function P(d,f,e,g,h){setTimeout(function(){var a,c=f.real_src,b;if("item"in i){if(!i[0]){setTimeout(arguments.callee,25);return}i=i[0]}a=document.createElement("script");if(f.type)a.type=f.type;if(f.charset)a.charset=f.charset;if(h){if(r){e.elem=a;if(E){a.preload=true;a.onpreload=g}else{a.onreadystatechange=function(){if(a.readyState=="loaded")g()}}a.src=c}else if(h&&c.indexOf(D)==0&&d[y]){b=new XMLHttpRequest();b.onreadystatechange=function(){if(b.readyState==4){b.onreadystatechange=function(){};e.text=b.responseText+"\n//@ sourceURL="+c;g()}};b.open("GET",c);b.send()}else{a.type="text/cache-script";t(a,e,"ready",function(){i.removeChild(a);g()});a.src=c;i.insertBefore(a,i.firstChild)}}else if(F){a.async=false;t(a,e,"finished",g);a.src=c;i.insertBefore(a,i.firstChild)}else{t(a,e,"finished",g);a.src=c;i.insertBefore(a,i.firstChild)}},0)}function J(){var l={},Q=r||M,n=[],p={},m;l[y]=true;l[z]=false;l[u]=false;l[A]=false;l[B]="";function R(a,c,b){var d;function f(){if(d!=null){d=null;I(b)}}if(p[c.src].finished)return;if(!a[u])p[c.src].finished=true;d=b.elem||document.createElement("script");if(c.type)d.type=c.type;if(c.charset)d.charset=c.charset;t(d,b,"finished",f);if(b.elem){b.elem=null}else if(b.text){d.onload=d.onreadystatechange=null;d.text=b.text}else{d.src=c.real_src}i.insertBefore(d,i.firstChild);if(b.text){f()}}function S(c,b,d,f){var e,g,h=function(){b.ready_cb(b,function(){R(c,b,e)})},j=function(){b.finished_cb(b,d)};b.src=N(b.src,c[B]);b.real_src=b.src+(c[A]?((/\?.*$/.test(b.src)?"&_":"?_")+~~(Math.random()*1E9)+"="):"");if(!p[b.src])p[b.src]={items:[],finished:false};g=p[b.src].items;if(c[u]||g.length==0){e=g[g.length]={ready:false,finished:false,ready_listeners:[h],finished_listeners:[j]};P(c,b,e,((f)?function(){e.ready=true;for(var a=0;a<e.ready_listeners.length;a++){e.ready_listeners[a]()}e.ready_listeners=[]}:function(){I(e)}),f)}else{e=g[0];if(e.finished){j()}else{e.finished_listeners.push(j)}}}function v(){var e,g=s(l,{}),h=[],j=0,w=false,k;function T(a,c){a.ready=true;a.exec_trigger=c;x()}function U(a,c){a.ready=a.finished=true;a.exec_trigger=null;for(var b=0;b<c.scripts.length;b++){if(!c.scripts[b].finished)return}c.finished=true;x()}function x(){while(j<h.length){if(G(h[j])){try{h[j++]()}catch(err){}continue}else if(!h[j].finished){if(O(h[j]))continue;break}j++}if(j==h.length){w=false;k=false}}function V(){if(!k||!k.scripts){h.push(k={scripts:[],finished:true})}}e={script:function(){for(var f=0;f<arguments.length;f++){(function(a,c){var b;if(!H(a)){c=[a]}for(var d=0;d<c.length;d++){V();a=c[d];if(G(a))a=a();if(!a)continue;if(H(a)){b=[].slice.call(a);b.unshift(d,1);[].splice.apply(c,b);d--;continue}if(typeof a=="string")a={src:a};a=s(a,{ready:false,ready_cb:T,finished:false,finished_cb:U});k.finished=false;k.scripts.push(a);S(g,a,k,(Q&&w));w=true;if(g[z])e.wait()}})(arguments[f],arguments[f])}return e},wait:function(){if(arguments.length>0){for(var a=0;a<arguments.length;a++){h.push(arguments[a])}k=h[h.length-1]}else k=false;x();return e}};return{script:e.script,wait:e.wait,setOptions:function(a){s(a,g);return e}}}m={setGlobalDefaults:function(a){s(a,l);return m},setOptions:function(){return v().setOptions.apply(null,arguments)},script:function(){return v().script.apply(null,arguments)},wait:function(){return v().wait.apply(null,arguments)},queueScript:function(){n[n.length]={type:"script",args:[].slice.call(arguments)};return m},queueWait:function(){n[n.length]={type:"wait",args:[].slice.call(arguments)};return m},runQueue:function(){var a=m,c=n.length,b=c,d;for(;--b>=0;){d=n.shift();a=a[d.type].apply(null,d.args)}return a},noConflict:function(){o.$LAB=K;return m},sandbox:function(){return J()}};return m}o.$LAB=J();(function(a,c,b){if(document.readyState==null&&document[a]){document.readyState="loading";document[a](c,b=function(){document.removeEventListener(c,b,false);document.readyState="complete"},false)}})("addEventListener","DOMContentLoaded")})(this);
"object"!==typeof JSON&&(JSON={});
(function(){function l(a){return 10>a?"0"+a:a}function q(a){r.lastIndex=0;return r.test(a)?'"'+a.replace(r,function(a){var c=t[a];return"string"===typeof c?c:"\\u"+("0000"+a.charCodeAt(0).toString(16)).slice(-4)})+'"':'"'+a+'"'}function n(a,k){var c,d,h,p,g=e,f,b=k[a];b&&("object"===typeof b&&"function"===typeof b.toJSON)&&(b=b.toJSON(a));"function"===typeof j&&(b=j.call(k,a,b));switch(typeof b){case "string":return q(b);case "number":return isFinite(b)?String(b):"null";case "boolean":case "null":return String(b);
case "object":if(!b)return"null";e+=m;f=[];if("[object Array]"===Object.prototype.toString.apply(b)){p=b.length;for(c=0;c<p;c+=1)f[c]=n(c,b)||"null";h=0===f.length?"[]":e?"[\n"+e+f.join(",\n"+e)+"\n"+g+"]":"["+f.join(",")+"]";e=g;return h}if(j&&"object"===typeof j){p=j.length;for(c=0;c<p;c+=1)"string"===typeof j[c]&&(d=j[c],(h=n(d,b))&&f.push(q(d)+(e?": ":":")+h))}else for(d in b)Object.prototype.hasOwnProperty.call(b,d)&&(h=n(d,b))&&f.push(q(d)+(e?": ":":")+h);h=0===f.length?"{}":e?"{\n"+e+f.join(",\n"+
e)+"\n"+g+"}":"{"+f.join(",")+"}";e=g;return h}}"function"!==typeof Date.prototype.toJSON&&(Date.prototype.toJSON=function(){return isFinite(this.valueOf())?this.getUTCFullYear()+"-"+l(this.getUTCMonth()+1)+"-"+l(this.getUTCDate())+"T"+l(this.getUTCHours())+":"+l(this.getUTCMinutes())+":"+l(this.getUTCSeconds())+"Z":null},String.prototype.toJSON=Number.prototype.toJSON=Boolean.prototype.toJSON=function(){return this.valueOf()});var s=/[\u0000\u00ad\u0600-\u0604\u070f\u17b4\u17b5\u200c-\u200f\u2028-\u202f\u2060-\u206f\ufeff\ufff0-\uffff]/g,
r=/[\\\"\x00-\x1f\x7f-\x9f\u00ad\u0600-\u0604\u070f\u17b4\u17b5\u200c-\u200f\u2028-\u202f\u2060-\u206f\ufeff\ufff0-\uffff]/g,e,m,t={"\b":"\\b","\t":"\\t","\n":"\\n","\f":"\\f","\r":"\\r",'"':'\\"',"\\":"\\\\"},j;"function"!==typeof JSON.stringify&&(JSON.stringify=function(a,k,c){var d;m=e="";if("number"===typeof c)for(d=0;d<c;d+=1)m+=" ";else"string"===typeof c&&(m=c);if((j=k)&&"function"!==typeof k&&("object"!==typeof k||"number"!==typeof k.length))throw Error("JSON.stringify");return n("",{"":a})});
"function"!==typeof JSON.parse&&(JSON.parse=function(a,e){function c(a,d){var g,f,b=a[d];if(b&&"object"===typeof b)for(g in b)Object.prototype.hasOwnProperty.call(b,g)&&(f=c(b,g),void 0!==f?b[g]=f:delete b[g]);return e.call(a,d,b)}var d;a=String(a);s.lastIndex=0;s.test(a)&&(a=a.replace(s,function(a){return"\\u"+("0000"+a.charCodeAt(0).toString(16)).slice(-4)}));if(/^[\],:{}\s]*$/.test(a.replace(/\\(?:["\\\/bfnrt]|u[0-9a-fA-F]{4})/g,"@").replace(/"[^"\\\n\r]*"|true|false|null|-?\d+(?:\.\d*)?(?:[eE][+\-]?\d+)?/g,
"]").replace(/(?:^|:|,)(?:\s*\[)+/g,"")))return d=eval("("+a+")"),"function"===typeof e?c({"":d},""):d;throw new SyntaxError("JSON.parse");})})();
/*jshint evil:true */
/*globals $LAB ActiveXObject */
(function() {
"use strict";
var root = this;
var headEl = document.getElementsByTagName('head')[0];
var targetBase = '/';
var resourceBase = '';
var pathFactories;
function time(name) {
try {
if (typeof console !== 'undefined' && console.time) {
console.time(name);
}
Env.timers[name] = new Date();
} catch (e) { }
}
function timeEnd(name) {
try {
if (typeof console !== 'undefined' && console.timeEnd) {
console.timeEnd(name);
}
Env.timers[name] = new Date() - Env.timers[name];
} catch (e) { }
}
function defaultPathFactory(file) {
if (file.ext) {
return file.file + '.' + file.ext;
}
return file.file;
}
function getXhr() {
if (root.XMLHttpRequest) {
return new XMLHttpRequest();
} else {
// This might fail if there's no support for any sort
// of AJAX. I don't really know what to tell you in that case,
// so I'm not going to handle it.
return new ActiveXObject("MSXML2.XMLHTTP.3.0");
}
}
function flattenList(list, absolute) {
if (!list) {
return [];
}
var len = list.length;
var flattened = [];
var basePath, fileList, numFiles, file, pathFactory;
for (var i = 0; i < len; i++) {
basePath = list[i][0];
// We assume that basePath ends in /, so fix it if it doesn't
if (basePath.charAt(basePath.length - 1) !== '/') {
basePath = basePath + '/';
}
if (!absolute) {
basePath = resourceBase + basePath;
}
fileList = list[i][1];
numFiles = fileList.length;
for (var j = 0; j < numFiles; j++) {
file = fileList[j];
if (typeof file == 'string') {
flattened.push(basePath + file);
} else {
pathFactory = pathFactories[file.ext] || defaultPathFactory;
flattened.push(basePath + pathFactory(file));
}
}
}
return flattened;
}
// A collection of functions that deals with merging target
// JSON files together.
var Target = {
load: function(target, callback) {
var xhr = getXhr();
var targetUrl = targetBase + target + '.json';
var parsedTarget;
xhr.open('GET', targetUrl);
xhr.onreadystatechange = function() {
if (xhr.readyState === 4) {
if (xhr.status === 200) {
try {
parsedTarget = JSON.parse(xhr.responseText);
} catch(e) {
console.error("Could not parse target:", target);
throw e;
}
Target.flatten(parsedTarget, callback);
} else {
callback("Could not load " + target);
}
}
};
xhr.send(null);
},
flatten: function(target, callback) {
var targetDeps = target.targetDependencies;
var targetsToMerge = [];
function loaded(err, dependentTarget) {
if (err) {
return callback(err);
}
targetsToMerge.push(dependentTarget);
if (targetsToMerge.length === targetDeps.length) {
targetsToMerge.push(target);
callback(null, Target.merge(targetsToMerge));
}
}
var len = targetDeps && targetDeps.length;
if (len) {
for (var i = 0; i < len; i++) {
Target.load(targetDeps[i], loaded);
}
} else {
callback(null, target);
}
},
merge: function(targetList) {
var current;
var merged = {};
var len = targetList.length;
for (var i = 0; i < len; i++) {
current = targetList[i];
for (var field in current) {
if (current.hasOwnProperty(field)) {
merged[field] = Target.mergeField(merged[field], current[field]);
}
}
}
return merged;
},
mergeField: function(a, b) {
if (!a) {
return b;
} else if (a instanceof Array) {
// For an array, the earlier values come before the latter values
return a.concat(b);
} else if (typeof b == 'string') {
// For a string, the last one wins.
if (b) {
return b;
}
return a;
} else {
// For a dict, latter values override earlier values
for (var field in b) {
if (b.hasOwnProperty(field)) {
a[field] = b[field];
}
}
return a;
}
}
};
// Flattens the various lists of JS files and uses LAB.js to load
// and evaluate the scripts in the correct order.
function loadJavascript(target, options) {
var fileList = [];
var toLoad = ['dependencies', 'scripts', 'models'];
if (options.dev) {
toLoad.splice(1, 0, 'devDependencies');
}
for (var i = 0; i < toLoad.length; i++) {
fileList = fileList.concat(flattenList(target[toLoad[i]]));
}
time("loading.js");
// We need the JS to load in order, and since we're doing this from JS,
// it will be async. Making async script loading parallel and in order is
// a bit tricky, but luckily LAB.js does it for us!
$LAB.setOptions({ AlwaysPreserveOrder: true }).script(fileList).wait(function() {
timeEnd("loading.js");
// After all the js is loaded, call the
// `main` function and start the program
eval(target.main).call(root, options.mainOptions);
});
}
// Flattens the css and less lists and injects the elements into the head
function loadStyles(target, options) {
var toLoad = ['externalCss', 'css'];
if (options.dev) {
toLoad.push('less');
}
var el, field, files, numFiles;
for (var i = 0; i < toLoad.length; i++) {
field = toLoad[i];
files = flattenList(target[field], field === 'externalCss');
numFiles = files.length;
for (var j = 0; j < numFiles; j++) {
el = document.createElement('link');
el.rel = field === 'less' ? 'stylesheet/less' : 'stylesheet';
el.type = 'text/css';
el.href = files[j];
headEl.appendChild(el);
}
}
}
root.R = root.R || {};
/**
* R.boot(app, options) -> undefined
* - app (string): The name of the app to load
* - options (object): Options object (documented below)
*
* ## Options
*
* - environment (object): An object that contains objects that
* describe something about the environment this app is being loaded
* in. A good example is server configuration or the current user.
* - targetBase (string): The base url for requesting the target
* that is used to describe how to load the application.
* - resourceBase (string): The base url for requesting the resources
* described in the target file.
* - dev (boolean): Whether to load dev dependencies or not.
* - mainOptions (object): Options object to pass to the `main` function.
* - pathFactories (object): A map of extension to function that will
* construct the correct file name for a given file object in a target.
* Files that are just strings are assumed to be complete.
* - unstyled (Boolean): If `true`, don't load styles.
**/
R.boot = function(app, options) {
options = options || {};
root.Env = options.environment;
Env.timers = {};
if (options.targetBase) {
targetBase = options.targetBase;
}
if (typeof targetBase === 'function') {
targetBase = targetBase();
}
if (options.resourceBase) {
resourceBase = options.resourceBase;
}
if (typeof resourceBase === 'function') {
resourceBase = resourceBase();
}
pathFactories = options.pathFactories || {};
var timer = 'loading.target.' + app;
time(timer);
Target.load(app, function(err, target) {
timeEnd(timer);
if (err) {
throw new Error(err);
}
Env.target = target;
if (!options.unstyled) {
loadStyles(target, options);
}
loadJavascript(target, options);
});
}
}).call(this);
/**
* class R.TargetMux
*
* A class for selecting a target given the current running environment.
*
* It has no JS dependencies.
**/
(function() {
"use strict";
var root = this;
/**
* new R.TargetMux(rules[, options])
* - rules (Array): A list of rules to evaluate. See below.
* - options (Object): Options object.
*
* ## Making Rules
*
* The `rules` argument should be a list of rules that conform to a
* specific format. Only the fields documented below are permitted, though
* additional rules can be created by passing them into the [[R.TargetMux]]
* constructor.
*
* - `rules` (Array): Additional rules to recursively go through and call
* [[R.TargetMux#find]] on.
* - `host` (RegExp): `location.host` must match this regular expression.
* - `pathname` (RegExp): `location.pathname` must match this regex. This
* does not break down the path as it descends into sub-rules.
* - `auth` (Boolean): If `true`, user must be authenticated. If `false`, user
* must be anonymous.
* - `prod` (Boolean): If `true`, we must be in prod. If `false`, we must be
* in dev.
**/
function Mux(rules, options) {
this.options = options || {};
this.rules = rules;
var rule;
var len = rules.length;
for (var i = 0; i < len; i++) {
rule = rules[i];
if (rule.rules) {
rule.rules = new Mux(rule.rules, options);
}
}
}
/**
* R.TargetMux#tests -> Object
*
* A set of tests to run on a particular rule to find out if it matches.
* If a rule has an attribute of the same name as one of the entries in this
* object, the value of that attribute will be passed to the test. If the
* test returns true, then that attribute of the route is a match.
*
* See [[R.TargetMux#find]] for more information on matching rules.
**/
Mux.prototype.tests = {
pathname: function(location, regex) {
var path = location.pathname;
if (location.pathname === '/' && location.hash) {
path = location.hash.replace('#', '/');
}
return regex.test(path);
},
host: function(location, regex) {
return regex.test(location.host);
},
// Things start getting pretty Rdio specific down here.
auth: function(location, authRequired) {
if (authRequired === true && Env.currentUser.key !== 's-1') {
return true;
} else if (authRequired === false && Env.currentUser.key === 's-1') {
return true;
}
return false;
},
prod: function(location, prodRequired) {
return Env.serverInfo.prod === prodRequired;
},
zuul: function(location, rule) {
return Env.currentUser.features[rule];
}
};
// Secure is an odd test because it has to be run after the route is
// found. At that point, if the secure test fails, we reload under
// the appropriate security. So it's not about whether or not the
// route matches, it's about whether or not other action is required.
Mux.prototype._checkSecure = function(location, rule) {
// In dev we don't enforce this unless we're testing.
if (!Env.serverInfo.prod && !Env.serverInfo.simulateDevHttps) {
return rule;
}
if (rule.secure === true && location.protocol !== 'https:') {
location.href = location.href.replace(/^http/, 'https');
} else if (rule.secure === false && location.protocol != 'http:') {
location.href = location.href.replace(/^https/, 'http');
}
return rule;
};
/**
* R.TargetMux#find(location) -> Object | null
* - location (object|string): Either a location object similar to
* `window.location` or a URL fragment to evaluate against. If
* a url fragment is passed in, the rest of the information about
* the URL will be taken from `window.location`.
*
* This function is used to figure out which application target should
* be running for a URL. If there is a match, that route rule will be
* returned. Once that rule is returned, then the caller is free to do
* as they please. We suggest loading that application to handle the
* actual URL routing or redirecting to something that can handle it.
*
* Returns `null` if no rule is found.
**/
Mux.prototype.find = function(locationOrPath) {
var i, j, rule, test, testName, ruleValue, match;
var len = this.rules.length;
var testsLen = this.tests.length;
var location = locationOrPath;
if (typeof locationOrPath === 'string') {
location = _.clone(root.location);
location.pathname = locationOrPath;
}
// This is slightly twisted logic.
// 1. loop through each rule
// 2. For each rule, loop through each test to see if it matches.
// 3. If each test that's valid for the rule matches, we have a match
// 4. If we have a match and the rule has subrules, return the result
// of trying to match on those subrules, or the original match if
// no subrule matches.
// 5. If there is no match, proceed to the next rule.
// 6. If no rules match, return `null`.
for (i = 0; i < len; i++) {
rule = this.rules[i];
var match = true;
for (testName in this.tests) {
if (this.tests.hasOwnProperty(testName)) {
test = this.tests[testName];
ruleValue = rule[testName];
if (ruleValue !== (void 0) && !test.call(this, location, ruleValue)) {
match = false;
break;
}
}
}
if (match) {
if (rule.rules) {
return this._checkSecure(location, rule.rules.find(location) || rule);
}
return this._checkSecure(location, rule);
}
}
return null;
};
R.TargetMux = Mux;
}).call(this);
(function() {
"use strict";
var rules = [
{
// We assume that the appropriate subdomain has been worked
// out before we ever get here. In prod, it will usually be www.
// In dev, there is no www. For bots, there may be other locales
// as the subdomain.
host: /[A-Za-z]+\.rdio\.com|^rdio\./,
rules: [
{ pathname: /^\/demo\//, target: 'demo', prod: false },
{ pathname: /^\/test\//, target: 'test', prod: false },
{ pathname: /^\/api\/iframe\//, target: 'api-iframe', unstyled: true },
{ pathname: /^\/secure_dialog\//, target: 'secure', secure: true },
{ pathname: /^\/i\//, target: 'rdio-embed' },
{ pathname: /^\/account\//, target: 'rdio-marketing', zuul: 'newsignup', secure: true },
{ pathname: /^\/developers\//, target: 'rdio-dev', zuul: 'devsite' },
{ pathname: /\/.*/, target: 'rdio', secure: false }
]
}, {
host: /[A-Za-z]+\.vdio\.com|^vdio\./,
rules: [
{ pathname: /^\/demo\//, target: 'demo', prod: false },
{ pathname: /^\/test\//, target: 'test', prod: false },
{ pathname: /^\/secure_dialog\//, target: 'secure', secure: true },
{ pathname: /^\/home\//, target: 'vdio-marketing', secure: true },
{ pathname: /^\/signin\//, target: 'vdio-marketing', secure: true },
{ pathname: /^\/legal\/.*/, target: 'vdio-marketing', secure: true },
{ pathname: /^\/account\//, target: 'vdio-marketing', secure: true },
{ pathname: /^\//, target: 'vdio', zuul: 'vdio', auth: true, secure: false },
{ pathname: /^\/.*/, target: 'vdio-marketing', secure: true },
{ pathname: /^\/.+/, target: 'vdio', secure: false }
]
}
];
R.muxer = new R.TargetMux(rules);
}).call(this);
R.supportsDataUris = true;
R.theme = /vdio/.test(window.location.hostname) ? 'vdio' : 'rdio';
(function() {
var data = new Image();
data.onload = data.onerror = function() {
if (this.width != 1 || this.height != 1) {
R.supportsDataUris = false;
}
}
data.src = "data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///ywAAAAAAQABAAACAUwAOw==";
})();
Env = {
VERSION: {"version": 1365122168},
currentUser: {"subscriptionType": 2, "features": {"rdio2": true, "echonest_reporting": true, "newsignup": true, "vdio_paypal": true, "vdio_sub_launch": true, "paypal": true, "vdio_sub_notify": true, "notifications": true, "protected_accounts": true, "vdio_user_specific_hr": true, "echonest_radio": true}, "baseIcon": "user/3/0/5/0000000000145503/2/square-100.jpg", "compSubscriptionType": null, "isTrial": false, "deviceCount": 3, "subscription_type": 2, "last_name": "Morris", "rdio_wallet_available_amount": 0.0, "has_lastfm": true, "vanityName": "justinmorris", "id": 1332483, "isFreeExpired": false, "first_name": "Justin", "icon250": "http://cdn3.rd.io/user/3/0/5/0000000000145503/2/square-250.jpg", "actualSubscriptionType": 2, "libraryVersion": 378, "freeLimited": null, "vanity_name": "justinmorris", "invite_count": -1, "trialEndDate": "2012-02-20 07:56:54", "isFree": false, "rdioAcceptedTOS": "20130402", "free_trial": {"trial_end_date": "2012-02-20T07:56:54"}, "rdioWalletAvailableBalance": {"currency": null, "amount": 0.0}, "prefs": {"v_collection": "", "n_mobile_promo": "true", "ca_rate_dialog": null, "lastfmScrobble": 1, "locale": "en", "n_vsp": null, "ce": null, "p_c_as": null, "v_people_sidebar": true, "sw_pr": true, "playlistsOrder": ["p2253372", "p2253370", "p2127603", "p1920767", "p1920766", "p1920764", "p1920763", "p1861405", "p819921", "p1284848", "p676504", "p1203378", "p785274", "p785281"], "v_releases": "", "outOfMusicTriggered": null, "v_cas": true, "rdio2_notified": null, "freeRefreshNotificationClosed": null, "fbScrobble": false, "hasSeenTour": true, "v_collection_sort": "dateAdded", "pr": null, "s_sd": true, "sw_or": true, "c_wp": null, "n_maint": "2013-03-30T06:00:00", "v_artist_songs_sort": "", "dc": null, "sw_oa": true, "v_artist_albums_sort": "", "p_c_bh": null, "e_your_music": true, "fbmusicdialog": null, "compDismiss": null, "v_charts": "albums", "p_c_ts": null, "vdioTermsAgreed": null}, "type": "s", "email": "justin@pixelbloom.com", "artistAccountArtists": {"items": [], "type": "list"}, "vdio_wallet_available_amount": 0.0, "new_user": false, "isProtected": null, "vdioUnreadNotificationsCount": 3, "tender_multipass": "fb3AC5pGFp5rErEvD0S2MSdk3IOlr8GuW2qHeP8Ghz60qq_QiO09RLpRJl664rOeR8V11XTqfrEM_orDWFNX3K3Ns1vZXeaLlmacZUjRe0KDzHj2s-T1H-Dm-MJmTgexU8sG8auQB4w87jDCFwSw4zrRVZTQjJsSjLID4aooRfo", "has_payment_profile": true, "hideTrialBar": false, "vdioWalletAvailableBalance": {"currency": null, "amount": 0.0}, "hasSubscriptionFailure": false, "icon500": "http://cdn3.rd.io/user/3/0/5/0000000000145503/2/square-500.jpg", "key": "s1332483", "facebookId": 212901390, "freeRemaining": 100, "vdioAcceptedTOS": null, "compEndDate": null, "rdioUnreadNotificationsCount": 2, "icon": "http://cdn3.rd.io/user/3/0/5/0000000000145503/2/square-100.jpg", "authorizationKey": "eyJyYW5kIjogMzQ4MTM2MDQwNSwgImtleSI6ICJzMTMzMjQ4MyIsICJ0aW1lIjogMTM2NTEzMTM0NH0.9HJfkGjoup6ZAEgWNBLAlaNhZd0", "hasOutstandingPurchase": false, "firstName": "Justin", "stations": [{"type": "h", "name": "Heavy Rotation Station", "key": "h1332483"}, {"type": "e", "name": "Heavy Rotation Station", "key": "e1332483"}, {"type": "c", "name": "Collection Station", "key": "c1332483"}], "url": "/people/justinmorris/", "gender": "m", "subscriptionInfo": {"familyInvited": {"items": [], "total": 0, "type": "list"}, "isInFamilyPlan": false, "cancelSubscription": false, "nextBillDate": "2013-04-30T03:04:11", "subscriptionType": 2, "paymentProfile": {"onlyUsedForSubscriptions": false, "profileShortName": "mastercard", "countryCode": "AU", "profileTypeName": "MasterCard", "canDelete": true, "defaultProfile": false, "currencyCode": "AUD", "synacorPartnerShortName": null, "usedForSubscription": true, "lastFour": "8795", "expirationDate": "2016-03-01", "profileId": 1251385, "canTrial": true, "paypalEmail": null, "id": 1251385}, "isLocked": false, "cost": 12.9, "familySlots": 0, "lockedMessages": null, "familyMembers": {"items": [], "type": "list"}}, "freeRefreshDate": "2013-04-28T23:59:59", "has_twitter": true, "subscription": {"subscription_type": 2}, "has_facebook": true, "lastName": "Morris", "followingCount": 44, "comp": null, "isAnonymous": false},
serverInfo: {"various_artist_key": "r62", "twitterName": "@RdioAU", "isHappyHourPermitted": false, "vdioBaseUrl": "http://www.vdio.com", "flashMediaUrl": "/media/", "stealthMode": false, "isOi": false, "assistlyEmailUrl": "http://help.rdio.com/customer/authentication/multipass/callback?multipass=cffudpaQK_6z3SFDn5QKyhcy95OPv2raDnoQDeIJNPU_lmigHpiiI0ubac4jftW4Q1o6ouOVY0nY8tRZUqGPmgV0B47XiARIEksf25TOV_4tBGMbHBf_l_TuO9qHASi6BKVyTjdTImLTCu7iYM7yQRiC75jAu9sjPnuCQZqZ1GSVsIMq6aS5JpJnYCYhkKSPlEZ2qimCEzqQeihTFTKsxxj5NDQblpcWjqW06CPSQGX8icaw2L_HfOnpumw_HdrS", "theme": "rdio", "omnitureData": {"userCampaign": null, "omnitureAccount": "rdiocomprod"}, "pixelTracking": {"bingPixelUrl": "//flex.atdmt.com/mstag/tag/015b6fe6-942d-4cc2-8c00-04ea3e5e5e0c/analytics.html?dedup=1&domainId=1602430&type=1&actionid=52597", "dartPixelUrls": {"registered": "//fls.doubleclick.net/activityi;src=3815645;type=rdioq368;cat=rdior620;ord=8358898941698?", "signup": "//fls.doubleclick.net/activityi;src=3815645;type=rdioq368;cat=rdios199;ord=1367468856619?"}, "ampushPixelUrl": null, "googlePixelUrl": "//www.googleadservices.com/pagead/conversion/1009559828/?label=GnqjCMyh9QIQlNKy4QM&amp;guid=ON&amp;script=0", "dartTagUserId": 8966632478525}, "rdioAccountKey": "s1186166", "various_artist_id": 62, "daysInTrial": 14, "prices": {"web": 8.9, "itunesUnlimited": 20.99, "family": null, "unlimited": 12.9, "familyPlusOne": null, "numDiscountedSubaccounts": null, "familySubaccount": null}, "isFamilyPlanPermitted": false, "secureHost": "www.rdio.com", "ignored_urls": ["/artist/Various_Artists/", "/artist/Various_Artists/bio/", "/artist/Various_Artists/albums/"], "availableCreditCardsByCountry": {"BE": ["visa", "mastercard", "americanexpress"], "FR": ["visa", "mastercard", "americanexpress"], "DK": ["visa", "mastercard", "americanexpress"], "DE": ["visa", "mastercard", "americanexpress"], "BR": ["visa", "mastercard"], "FI": ["visa", "mastercard", "americanexpress"], "NL": ["visa", "mastercard", "americanexpress"], "PT": ["visa", "mastercard", "americanexpress"], "NO": ["visa", "mastercard", "americanexpress"], "NZ": ["visa", "mastercard", "americanexpress"], "LV": ["visa", "mastercard", "americanexpress"], "LT": ["visa", "mastercard", "americanexpress"], "IS": ["visa", "mastercard", "americanexpress"], "EE": ["visa", "mastercard", "americanexpress"], "CA": ["visa", "mastercard", "americanexpress", "discover"], "IT": ["visa", "mastercard", "americanexpress"], "AU": ["visa", "mastercard", "americanexpress"], "GB": ["visa", "mastercard", "americanexpress"], "IE": ["visa", "mastercard", "americanexpress"], "ES": ["visa", "mastercard", "americanexpress"], "US": ["visa", "mastercard", "americanexpress", "discover"], "MX": ["visa", "mastercard"], "SE": ["visa", "mastercard", "americanexpress"], "AT": ["visa", "mastercard", "americanexpress"]}, "allow_offline": true, "appDownloadUrls": {"windows": "/media/static/desktop/win/Rdio.application", "mac": "/media/static/desktop/mac/Rdio.dmg", "ios": "http://itunes.apple.com/us/app/rdio/id335060889", "android": "https://play.google.com/store/apps/details?id=com.rdio.android.ui&feature=search_result#?t=W251bGwsMSwxLDEsImNvbS5yZGlvLmFuZHJvaWQudWkiXQ..", "windows_phone": "https://www.windowsphone.com/en-us/store/app/rdio/aab4252d-a0e0-df11-a844-00237de2db9e"}, "giftcardValidRegion": true, "fbLocale": "en_US", "debug": false, "helpUrl": "http://help.rdio.com/customer/authentication/multipass/callback?multipass=cffudpaQK_6z3SFDn5QKyhcy95OPv2raDnoQDeIJNPXTZQwGX64Y_zjvrVjXM13hiTPTQ4nK6K2qcmp8CCiSr86oIq9f4M2B29LMHfhCTK4kvcjITPkKyTB3NUBXIeDCxPcstM7U57CtY_hORQWTOLTvjYb2Ie7yMdynWOtaqb3tytxTKZAKLpJB4gvr5byLxvsKzR-VFkQpOvV8bAHgt-P-1lM5Wlcdc7ZC5RzkuDGVWgLX-sVKbMaTZYZwhaJ0", "countryCode": "AU", "availableSubscriptionTypes": [{"subscriptionId": 1, "type": "web"}, {"subscriptionId": 2, "type": "unlimited"}], "locale": "en", "isAmazonBillingPermitted": false, "marketingTarget": " target=\"_blank\"", "helpBaseUrl": "http://help.rdio.com/customer/portal/articles/", "favicon": "//rdio-a.akamaihd.net/media/favicon_rdio_2012_11_15.ico", "vppaCountries": ["US"], "media_address": "//rdio-a.akamaihd.net/media/", "is_address": "http://rdio-a.akamaihd.net/_is/", "singlePage": true, "prod": true, "awsFpsLive": true, "product_name": "Rdio", "silence_mp3_url": "cdn3.rd.io/playlist/silence.mp3", "resourceVersions": {"api.swf": "515b6b80a5f7bfd5e9533ace5a0e34a4", "sec.css": "7bfa8605b25e87cfedd93602594cadba", "player.swf": "a27305001f969a86eba8828fdd0ce36f", "embed_loader.swf": "40dfc41404f1d8ead08866886e43cb3b", "ie7fixes.js": "d89ffa52c5896a953d7d23dadbe1f4fb", "embed.swf": "3895a3f33e9531bd6a8f533145bad18a", "oauth_c.css": "6c3798023b96bc39a56a6743cfd4a9c5", "rdio.datauri.css": "bc9949b93dbb62adeaccbdcf9143771f", "rdio.css": "bb441a022d328ab8ee3774afad45ab05", "desktop_app_rdio2.css": "688bb520188fe1b0568656e90650dd7d", "ie8.css": "3f8bf9cd61f3b2d015ad70cc4c04f946", "desktop_app.js": "7d6d6a89ce9b7f60cc7a135fc6bdb892", "sec.js": "4ef515ebf56433d34bb6159c4667ee71", "pretty_stats.js": "ee43daa2665c2a1ec53c73b9e3f1f301", "ie7.css": "86afc1833c0b4e7f99331dbfefdaa6b3", "admin.js": "d41d8cd98f00b204e9800998ecf8427e", "admin.css": "88bbbd125759b9ed20c69d86ae334bde", "fallback.swf": "e9f16c0b574a4752c29639c658cf02c2", "pretty_stats.css": "f2424f42dc2e4390b9a24379593a369b", "rdio.js": "2434bc34ed3e9c60ecaca7a107b854bf", "desktop_app.css": "3e96254d94e2404fc4ef1c511d905bb1", "mob.css": "991735506a961ec9aa339dc268f8908c", "oauth_c.js": "83da8f1c4bdeb2d4757ec59514b1eeff", "circleview.swf": "bee1b6f643a45616eec9d570ff56317c", "mob.js": "a1fdd5f7f6a3e2a016c1a7776871fcb0", "vdioplayer.swf": "56177b6ab9273438ed3627c805cb27b2"}, "macAppIsLive": true, "simulateDevHttps": false, "free_limited": true, "availableCreditCards": ["visa", "mastercard", "americanexpress", "discover"], "countryName": "Australia", "oiPaymentsLive": true, "fbid": "100322856680770", "maintenanceDates": {"start": "2013-03-30T06:00:00", "end": "2013-03-30T08:00:00"}, "urls": {"about": "/aboutus/", "resolveSubscription": "/settings/resolve_subscription/", "subscriptions": "/settings/subscription/", "legalPaymentTerms": "/legal/paymentterms/", "oauthTwitter": "/connect/twitter/", "legalTos": "/legal/tos/", "oauthFacebook": "/connect/facebook/", "legal": "/legal/", "contact": "/contact/", "oauthGmailStart": "/invite/start_google/", "secureDialog": "/secure_dialog/", "oauthLiveStart": "/invite/start_windowslive/", "legalPrivacyPolicy": "/legal/privacypolicy/", "oauthLastfm": "/connect/lastfm/", "oauthYahooStart": "/invite/start_yahoo/", "appsMobile": "/apps/mobile/", "oauthArtistTwitter": "/connect/artist_twitter/"}}
};
(function() {
var rule = R.muxer.find(location);
if (!rule || !rule.target) {
document.write("Not found");
if (location.pathname !== "/") {
location.pathname = "/";
}
return;
}
Env.loadedTarget = rule.target;
R.boot(Env.loadedTarget, {
environment: Env,
pathFactories: {
css: function(file) {
var fileName = file.file + '.' + R.theme;
if (R.supportsDataUris && file.themeVersions[R.theme].datauriVersion) {
fileName = fileName + '.datauri.' + file.themeVersions[R.theme].datauriVersion;
} else if (file.themeVersions[R.theme].version) {
fileName = fileName + '.' + file.themeVersions[R.theme].version;
}
return fileName + '.css'
}
},
targetBase: '/media/fresh/now/targets/',
resourceBase: '//rdio-a.akamaihd.net/media/',
mainOptions: {},
dev: false,
unstyled: rule.unstyled
});
})();
</script>
<meta http-equiv="Content-Type" content="text/html;charset=utf-8" />
<meta name="application-name" content="Rdio" />
<meta name="application-url" content="http://www.rdio.com/" />
<meta name="viewport" content="user-scalable=no, initial-scale=1.0, minimum-scale=1.0, maximum-scale=1.0, width=device-width" />
</head>
<body style="margin: 0">
<noscript><iframe src="/client/noscript/" style="position: absolute; height: 100%; width: 100%; border: 0;"></iframe></noscript>
</body>
</html>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment