basti1012.bplaced.net

Du siehst gerade eine vereinfachte Darstellung unserer Inhalte. Normale Ansicht mit richtiger Formatierung.
    Errechnet dir die Downloadzeit bei Angaben von Größe der Datei und Internet geschwindigkeit

    Code

                                        
                                    <html data-lt-installed="true"><head>
    <meta charset="UTF-8">
    <title>Download time calculator</title>
     
    <style>
    window,body{
    	width: 100%;
    	height: 100%;
    }
    body{
    	font-family: Helvetica, Arial, sans-serif;
    	background-color: #f8f8f8;
    }
    .content{
    	display:block;
    	margin-left:auto;
    	margin-right:auto;
    	width: 600px;
    }
    h1,h2,h3,h4{
    	color: #444;
    }
    .content #speed,
    .content #file,
    .content #results,
    .content #downloadSimulatorWindow_{
    	margin-bottom: 20px;
    	border: 1px solid red;
    	border: 1px solid gray;
    	border-radius: 3px;
    	background-color: #EEE;
    	box-shadow: 0px 2px 3px rgba(0,0,0,0.5);
    	
    }
    input, button{
    	font-size: 16pt;
    }
    #speed {
    	text-align: center;
    }
    #speed input{
    	font-size: 16pt;
    	text-align: right;
    }
    #speed .idkSpeed{
    	font-size: 8pt;
    }
    #speed .idkSpeed.mobile{
    	font-size: 11pt;
    }
    .overhead-p{
    	font-size: 8pt;
    }
    #file{
    	text-align: center;
    }
    #file input{
    	font-size: 16pt;
    	text-align: right;
    }
    .examples-p{
    	font-size: 8pt;
    }
    #results{
    	background-color: #FFF !important;
    	text-align: center;
    	visibility: hidden;
    }
    #results .time{
    	font-style:normal;
    	font-size:24px;
    }
    #results .time em{
    	font-style:normal;
    	font-size:32px;
    }
    #downloadSimulatorWindow {
    	position: relative;
    	width: 600px;
    	height: 99px;
    	color: gray;
    	opacity: 0.5;
    	border: 1px solid gray;
    	border-radius: 5px;
    	visibility: hidden;
    	box-shadow: 0px 1px 16px rgba(0,0,0,0.5);
    }
    #downloadSimulatorWindow .filename {
    	position: absolute;
    	left: 85px;
    	top: 18px;
    	width: 355px;
    	height: 15px;
    }
    #downloadSimulatorWindow .progresrbar {
        position: absolute;
        left: 85px;
        top: 38px;
        width: 398px;
        height: 22px;
    }
    #downloadSimulatorWindow progress{
        width: 100%;
    }
    #downloadSimulatorWindow .percent {
        position: absolute;
        left: 435px;
        top: 15px;
        width: 49px;
        height: 17px;
        text-align: right;
    }
    #downloadSimulatorWindow .details {
        position: absolute;
        left: 85px;
        top: 63px;
        width: 401px;
        height: 19px;
        padding-left: 0.5em;
        font-size: 14px;
    }
    #downloadSimulatorWindow .icon {
    	position: absolute;
    	left: 10px;
    	top: 18px;
    	width: 64px;
    	height: 64px;
    }
    #downloadSimulatorWindow .ps {
    	position: absolute;
    	right: 0px;
    	bottom: -20px;
    	width: 514px;
    	height: 18px;
    	font-size: 10px;
    	text-align: right;
    }
    
    .footer{
    	text-align: center;
    	font-size: 9pt;
    	padding: 1em;
    }
    #calculateButton{
    	padding-left: 1em;
    	padding-right: 1em;
    }
    #speedtest_mobile{
    	display: none;
    	margin: 30px;
    	background: #333;
    	color: #FFF;
    }
    #speedtest_mobile a{
    	color: #FFF;
    	margin:20px;
    }
    .mobile-iphone-btn,
    .mobile-windows-btn,
    .mobile-android-btn,
    .mobile-amazon-btn{
    	width: 230px;
    	height: 74px;
    	background: url(http://www.speedtest.net/mobile/../images/app-store-sprite.png);
    	background-position: 0px -2px;
    	display: block;
    	float: left;
    	display: inline-block;
    }
    .mobile-iphone-btn{
    	background-position: 0px -2px;
    }
    .mobile-windows-btn{
    	background-position: 245px -2px;
    }
    .mobile-android-btn{
    	background-position: 483px -2px;
    }
    .mobile-amazon-btn{
    	background-position: 0 -2px;
    	background: url(http://www.speedtest.net/mobile/../images/app-store-amazon.png);
    }
    .speedtest-mobile-ico{
    	width: 124px;
    	height: 124px;
    	background-image: url(http://www.speedtest.net/mobile/../images/placeholder-mobile-header.png);
    	-webkit-background-size: 124px 124px;
    	-moz-background-size: 124px 124px;
    	background-size: 124px 124px;
    	background-repeat: no-repeat;
    	width: 70px;
    	height: 70px;
    	-webkit-background-size: 70px 70px;
    	-moz-background-size: 70px 70px;
    	background-size: 70px 70px;
    	float: left;
    	margin-left: 8px;
    	margin-right: 15px;
    	margin-left: 50px;
    	margin-top: 35px;
    
    	display: inline-block;
    }
    
    /******/
    .collapse{
    	font-size: 8pt;
    	display: block;
    	line-height: 44px;
    	
    	color: gray;
    }
    .collapse:hover{
    	color: white;
    	-background-color: #FCFCFC;
    }
    .collapse + input{
      display:none;
    }
    .collapse + input + div{
      display:none;
    }
    .collapse+ input:checked + div{
      display:block;
    }
    
    </style>
    <script>
      (function(a) {
        function b() {
            return {
                empty: !1,
                unusedTokens: [],
                unusedInput: [],
                overflow: -2,
                charsLeftOver: 0,
                nullInput: !1,
                invalidMonth: null,
                invalidFormat: !1,
                userInvalidated: !1,
                iso: !1
            }
        }
        function c(a, b) {
            return function(c) {
                return k(a.call(this, c), b)
            }
        }
        function d(a, b) {
            return function(c) {
                return this.lang().ordinal(a.call(this, c), b)
            }
        }
        function e() {}
        function f(a) {
            w(a),
            h(this, a)
        }
        function g(a) {
            var b = q(a)
              , c = b.year || 0
              , d = b.month || 0
              , e = b.week || 0
              , f = b.day || 0
              , g = b.hour || 0
              , h = b.minute || 0
              , i = b.second || 0
              , j = b.millisecond || 0;
            this._milliseconds = +j + 1e3 * i + 6e4 * h + 36e5 * g,
            this._days = +f + 7 * e,
            this._months = +d + 12 * c,
            this._data = {},
            this._bubble()
        }
        function h(a, b) {
            for (var c in b)
                b.hasOwnProperty(c) && (a[c] = b[c]);
            return b.hasOwnProperty("toString") && (a.toString = b.toString),
            b.hasOwnProperty("valueOf") && (a.valueOf = b.valueOf),
            a
        }
        function i(a) {
            var b, c = {};
            for (b in a)
                a.hasOwnProperty(b) && qb.hasOwnProperty(b) && (c[b] = a[b]);
            return c
        }
        function j(a) {
            return 0 > a ? Math.ceil(a) : Math.floor(a)
        }
        function k(a, b, c) {
            for (var d = "" + Math.abs(a), e = a >= 0; d.length < b; )
                d = "0" + d;
            return (e ? c ? "+" : "" : "-") + d
        }
        function l(a, b, c, d) {
            var e, f, g = b._milliseconds, h = b._days, i = b._months;
            g && a._d.setTime(+a._d + g * c),
            (h || i) && (e = a.minute(),
            f = a.hour()),
            h && a.date(a.date() + h * c),
            i && a.month(a.month() + i * c),
            g && !d && db.updateOffset(a),
            (h || i) && (a.minute(e),
            a.hour(f))
        }
        function m(a) {
            return "[object Array]" === Object.prototype.toString.call(a)
        }
        function n(a) {
            return "[object Date]" === Object.prototype.toString.call(a) || a instanceof Date
        }
        function o(a, b, c) {
            var d, e = Math.min(a.length, b.length), f = Math.abs(a.length - b.length), g = 0;
            for (d = 0; e > d; d++)
                (c && a[d] !== b[d] || !c && s(a[d]) !== s(b[d])) && g++;
            return g + f
        }
        function p(a) {
            if (a) {
                var b = a.toLowerCase().replace(/(.)s$/, "$1");
                a = Tb[a] || Ub[b] || b
            }
            return a
        }
        function q(a) {
            var b, c, d = {};
            for (c in a)
                a.hasOwnProperty(c) && (b = p(c),
                b && (d[b] = a[c]));
            return d
        }
        function r(b) {
            var c, d;
            if (0 === b.indexOf("week"))
                c = 7,
                d = "day";
            else {
                if (0 !== b.indexOf("month"))
                    return;
                c = 12,
                d = "month"
            }
            db[b] = function(e, f) {
                var g, h, i = db.fn._lang[b], j = [];
                if ("number" == typeof e && (f = e,
                e = a),
                h = function(a) {
                    var b = db().utc().set(d, a);
                    return i.call(db.fn._lang, b, e || "")
                }
                ,
                null != f)
                    return h(f);
                for (g = 0; c > g; g++)
                    j.push(h(g));
                return j
            }
        }
        function s(a) {
            var b = +a
              , c = 0;
            return 0 !== b && isFinite(b) && (c = b >= 0 ? Math.floor(b) : Math.ceil(b)),
            c
        }
        function t(a, b) {
            return new Date(Date.UTC(a, b + 1, 0)).getUTCDate()
        }
        function u(a) {
            return v(a) ? 366 : 365
        }
        function v(a) {
            return a % 4 === 0 && a % 100 !== 0 || a % 400 === 0
        }
        function w(a) {
            var b;
            a._a && -2 === a._pf.overflow && (b = a._a[jb] < 0 || a._a[jb] > 11 ? jb : a._a[kb] < 1 || a._a[kb] > t(a._a[ib], a._a[jb]) ? kb : a._a[lb] < 0 || a._a[lb] > 23 ? lb : a._a[mb] < 0 || a._a[mb] > 59 ? mb : a._a[nb] < 0 || a._a[nb] > 59 ? nb : a._a[ob] < 0 || a._a[ob] > 999 ? ob : -1,
            a._pf._overflowDayOfYear && (ib > b || b > kb) && (b = kb),
            a._pf.overflow = b)
        }
        function x(a) {
            return null == a._isValid && (a._isValid = !isNaN(a._d.getTime()) && a._pf.overflow < 0 && !a._pf.empty && !a._pf.invalidMonth && !a._pf.nullInput && !a._pf.invalidFormat && !a._pf.userInvalidated,
            a._strict && (a._isValid = a._isValid && 0 === a._pf.charsLeftOver && 0 === a._pf.unusedTokens.length)),
            a._isValid
        }
        function y(a) {
            return a ? a.toLowerCase().replace("_", "-") : a
        }
        function z(a, b) {
            return b._isUTC ? db(a).zone(b._offset || 0) : db(a).local()
        }
        function A(a, b) {
            return b.abbr = a,
            pb[a] || (pb[a] = new e),
            pb[a].set(b),
            pb[a]
        }
        function B(a) {
            delete pb[a]
        }
        function C(a) {
            var b, c, d, e, f = 0, g = function(a) {
                if (!pb[a] && rb)
                    try {
                        require("./lang/" + a)
                    } catch (b) {}
                return pb[a]
            };
            if (!a)
                return db.fn._lang;
            if (!m(a)) {
                if (c = g(a))
                    return c;
                a = [a]
            }
            for (; f < a.length; ) {
                for (e = y(a[f]).split("-"),
                b = e.length,
                d = y(a[f + 1]),
                d = d ? d.split("-") : null; b > 0; ) {
                    if (c = g(e.slice(0, b).join("-")))
                        return c;
                    if (d && d.length >= b && o(e, d, !0) >= b - 1)
                        break;
                    b--
                }
                f++
            }
            return db.fn._lang
        }
        function D(a) {
            return a.match(/\[[\s\S]/) ? a.replace(/^\[|\]$/g, "") : a.replace(/\\/g, "")
        }
        function E(a) {
            var b, c, d = a.match(vb);
            for (b = 0,
            c = d.length; c > b; b++)
                d[b] = Yb[d[b]] ? Yb[d[b]] : D(d[b]);
            return function(e) {
                var f = "";
                for (b = 0; c > b; b++)
                    f += d[b]instanceof Function ? d[b].call(e, a) : d[b];
                return f
            }
        }
        function F(a, b) {
            return a.isValid() ? (b = G(b, a.lang()),
            Vb[b] || (Vb[b] = E(b)),
            Vb[b](a)) : a.lang().invalidDate()
        }
        function G(a, b) {
            function c(a) {
                return b.longDateFormat(a) || a
            }
            var d = 5;
            for (wb.lastIndex = 0; d >= 0 && wb.test(a); )
                a = a.replace(wb, c),
                wb.lastIndex = 0,
                d -= 1;
            return a
        }
        function H(a, b) {
            var c, d = b._strict;
            switch (a) {
            case "DDDD":
                return Ib;
            case "YYYY":
            case "GGGG":
            case "gggg":
                return d ? Jb : zb;
            case "Y":
            case "G":
            case "g":
                return Lb;
            case "YYYYYY":
            case "YYYYY":
            case "GGGGG":
            case "ggggg":
                return d ? Kb : Ab;
            case "S":
                if (d)
                    return Gb;
            case "SS":
                if (d)
                    return Hb;
            case "SSS":
                if (d)
                    return Ib;
            case "DDD":
                return yb;
            case "MMM":
            case "MMMM":
            case "dd":
            case "ddd":
            case "dddd":
                return Cb;
            case "a":
            case "A":
                return C(b._l)._meridiemParse;
            case "X":
                return Fb;
            case "Z":
            case "ZZ":
                return Db;
            case "T":
                return Eb;
            case "SSSS":
                return Bb;
            case "MM":
            case "DD":
            case "YY":
            case "GG":
            case "gg":
            case "HH":
            case "hh":
            case "mm":
            case "ss":
            case "ww":
            case "WW":
                return d ? Hb : xb;
            case "M":
            case "D":
            case "d":
            case "H":
            case "h":
            case "m":
            case "s":
            case "w":
            case "W":
            case "e":
            case "E":
                return xb;
            default:
                return c = new RegExp(P(O(a.replace("\\", "")), "i"))
            }
        }
        function I(a) {
            a = a || "";
            var b = a.match(Db) || []
              , c = b[b.length - 1] || []
              , d = (c + "").match(Qb) || ["-", 0, 0]
              , e = +(60 * d[1]) + s(d[2]);
            return "+" === d[0] ? -e : e
        }
        function J(a, b, c) {
            var d, e = c._a;
            switch (a) {
            case "M":
            case "MM":
                null != b && (e[jb] = s(b) - 1);
                break;
            case "MMM":
            case "MMMM":
                d = C(c._l).monthsParse(b),
                null != d ? e[jb] = d : c._pf.invalidMonth = b;
                break;
            case "D":
            case "DD":
                null != b && (e[kb] = s(b));
                break;
            case "DDD":
            case "DDDD":
                null != b && (c._dayOfYear = s(b));
                break;
            case "YY":
                e[ib] = s(b) + (s(b) > 68 ? 1900 : 2e3);
                break;
            case "YYYY":
            case "YYYYY":
            case "YYYYYY":
                e[ib] = s(b);
                break;
            case "a":
            case "A":
                c._isPm = C(c._l).isPM(b);
                break;
            case "H":
            case "HH":
            case "h":
            case "hh":
                e[lb] = s(b);
                break;
            case "m":
            case "mm":
                e[mb] = s(b);
                break;
            case "s":
            case "ss":
                e[nb] = s(b);
                break;
            case "S":
            case "SS":
            case "SSS":
            case "SSSS":
                e[ob] = s(1e3 * ("0." + b));
                break;
            case "X":
                c._d = new Date(1e3 * parseFloat(b));
                break;
            case "Z":
            case "ZZ":
                c._useUTC = !0,
                c._tzm = I(b);
                break;
            case "w":
            case "ww":
            case "W":
            case "WW":
            case "d":
            case "dd":
            case "ddd":
            case "dddd":
            case "e":
            case "E":
                a = a.substr(0, 1);
            case "gg":
            case "gggg":
            case "GG":
            case "GGGG":
            case "GGGGG":
                a = a.substr(0, 2),
                b && (c._w = c._w || {},
                c._w[a] = b)
            }
        }
        function K(a) {
            var b, c, d, e, f, g, h, i, j, k, l = [];
            if (!a._d) {
                for (d = M(a),
                a._w && null == a._a[kb] && null == a._a[jb] && (f = function(b) {
                    var c = parseInt(b, 10);
                    return b ? b.length < 3 ? c > 68 ? 1900 + c : 2e3 + c : c : null == a._a[ib] ? db().weekYear() : a._a[ib]
                }
                ,
                g = a._w,
                null != g.GG || null != g.W || null != g.E ? h = Z(f(g.GG), g.W || 1, g.E, 4, 1) : (i = C(a._l),
                j = null != g.d ? V(g.d, i) : null != g.e ? parseInt(g.e, 10) + i._week.dow : 0,
                k = parseInt(g.w, 10) || 1,
                null != g.d && j < i._week.dow && k++,
                h = Z(f(g.gg), k, j, i._week.doy, i._week.dow)),
                a._a[ib] = h.year,
                a._dayOfYear = h.dayOfYear),
                a._dayOfYear && (e = null == a._a[ib] ? d[ib] : a._a[ib],
                a._dayOfYear > u(e) && (a._pf._overflowDayOfYear = !0),
                c = U(e, 0, a._dayOfYear),
                a._a[jb] = c.getUTCMonth(),
                a._a[kb] = c.getUTCDate()),
                b = 0; 3 > b && null == a._a[b]; ++b)
                    a._a[b] = l[b] = d[b];
                for (; 7 > b; b++)
                    a._a[b] = l[b] = null == a._a[b] ? 2 === b ? 1 : 0 : a._a[b];
                l[lb] += s((a._tzm || 0) / 60),
                l[mb] += s((a._tzm || 0) % 60),
                a._d = (a._useUTC ? U : T).apply(null, l)
            }
        }
        function L(a) {
            var b;
            a._d || (b = q(a._i),
            a._a = [b.year, b.month, b.day, b.hour, b.minute, b.second, b.millisecond],
            K(a))
        }
        function M(a) {
            var b = new Date;
            return a._useUTC ? [b.getUTCFullYear(), b.getUTCMonth(), b.getUTCDate()] : [b.getFullYear(), b.getMonth(), b.getDate()]
        }
        function N(a) {
            a._a = [],
            a._pf.empty = !0;
            var b, c, d, e, f, g = C(a._l), h = "" + a._i, i = h.length, j = 0;
            for (d = G(a._f, g).match(vb) || [],
            b = 0; b < d.length; b++)
                e = d[b],
                c = (h.match(H(e, a)) || [])[0],
                c && (f = h.substr(0, h.indexOf(c)),
                f.length > 0 && a._pf.unusedInput.push(f),
                h = h.slice(h.indexOf(c) + c.length),
                j += c.length),
                Yb[e] ? (c ? a._pf.empty = !1 : a._pf.unusedTokens.push(e),
                J(e, c, a)) : a._strict && !c && a._pf.unusedTokens.push(e);
            a._pf.charsLeftOver = i - j,
            h.length > 0 && a._pf.unusedInput.push(h),
            a._isPm && a._a[lb] < 12 && (a._a[lb] += 12),
            a._isPm === !1 && 12 === a._a[lb] && (a._a[lb] = 0),
            K(a),
            w(a)
        }
        function O(a) {
            return a.replace(/\\(\[)|\\(\])|\[([^\]\[]*)\]|\\(.)/g, function(a, b, c, d, e) {
                return b || c || d || e
            })
        }
        function P(a) {
            return a.replace(/[-\/\\^$*+?.()|[\]{}]/g, "\\$&")
        }
        function Q(a) {
            var c, d, e, f, g;
            if (0 === a._f.length)
                return a._pf.invalidFormat = !0,
                a._d = new Date(0 / 0),
                void 0;
            for (f = 0; f < a._f.length; f++)
                g = 0,
                c = h({}, a),
                c._pf = b(),
                c._f = a._f[f],
                N(c),
                x(c) && (g += c._pf.charsLeftOver,
                g += 10 * c._pf.unusedTokens.length,
                c._pf.score = g,
                (null == e || e > g) && (e = g,
                d = c));
            h(a, d || c)
        }
        function R(a) {
            var b, c, d = a._i, e = Mb.exec(d);
            if (e) {
                for (a._pf.iso = !0,
                b = 0,
                c = Ob.length; c > b; b++)
                    if (Ob[b][1].exec(d)) {
                        a._f = Ob[b][0] + (e[6] || " ");
                        break
                    }
                for (b = 0,
                c = Pb.length; c > b; b++)
                    if (Pb[b][1].exec(d)) {
                        a._f += Pb[b][0];
                        break
                    }
                d.match(Db) && (a._f += "Z"),
                N(a)
            } else
                a._d = new Date(d)
        }
        function S(b) {
            var c = b._i
              , d = sb.exec(c);
            c === a ? b._d = new Date : d ? b._d = new Date(+d[1]) : "string" == typeof c ? R(b) : m(c) ? (b._a = c.slice(0),
            K(b)) : n(c) ? b._d = new Date(+c) : "object" == typeof c ? L(b) : b._d = new Date(c)
        }
        function T(a, b, c, d, e, f, g) {
            var h = new Date(a,b,c,d,e,f,g);
            return 1970 > a && h.setFullYear(a),
            h
        }
        function U(a) {
            var b = new Date(Date.UTC.apply(null, arguments));
            return 1970 > a && b.setUTCFullYear(a),
            b
        }
        function V(a, b) {
            if ("string" == typeof a)
                if (isNaN(a)) {
                    if (a = b.weekdaysParse(a),
                    "number" != typeof a)
                        return null
                } else
                    a = parseInt(a, 10);
            return a
        }
        function W(a, b, c, d, e) {
            return e.relativeTime(b || 1, !!c, a, d)
        }
        function X(a, b, c) {
            var d = hb(Math.abs(a) / 1e3)
              , e = hb(d / 60)
              , f = hb(e / 60)
              , g = hb(f / 24)
              , h = hb(g / 365)
              , i = 45 > d && ["s", d] || 1 === e && ["m"] || 45 > e && ["mm", e] || 1 === f && ["h"] || 22 > f && ["hh", f] || 1 === g && ["d"] || 25 >= g && ["dd", g] || 45 >= g && ["M"] || 345 > g && ["MM", hb(g / 30)] || 1 === h && ["y"] || ["yy", h];
            return i[2] = b,
            i[3] = a > 0,
            i[4] = c,
            W.apply({}, i)
        }
        function Y(a, b, c) {
            var d, e = c - b, f = c - a.day();
            return f > e && (f -= 7),
            e - 7 > f && (f += 7),
            d = db(a).add("d", f),
            {
                week: Math.ceil(d.dayOfYear() / 7),
                year: d.year()
            }
        }
        function Z(a, b, c, d, e) {
            var f, g, h = U(a, 0, 1).getUTCDay();
            return c = null != c ? c : e,
            f = e - h + (h > d ? 7 : 0) - (e > h ? 7 : 0),
            g = 7 * (b - 1) + (c - e) + f + 1,
            {
                year: g > 0 ? a : a - 1,
                dayOfYear: g > 0 ? g : u(a - 1) + g
            }
        }
        function $(a) {
            var b = a._i
              , c = a._f;
            return null === b ? db.invalid({
                nullInput: !0
            }) : ("string" == typeof b && (a._i = b = C().preparse(b)),
            db.isMoment(b) ? (a = i(b),
            a._d = new Date(+b._d)) : c ? m(c) ? Q(a) : N(a) : S(a),
            new f(a))
        }
        function _(a, b) {
            db.fn[a] = db.fn[a + "s"] = function(a) {
                var c = this._isUTC ? "UTC" : "";
                return null != a ? (this._d["set" + c + b](a),
                db.updateOffset(this),
                this) : this._d["get" + c + b]()
            }
        }
        function ab(a) {
            db.duration.fn[a] = function() {
                return this._data[a]
            }
        }
        function bb(a, b) {
            db.duration.fn["as" + a] = function() {
                return +this / b
            }
        }
        function cb(a) {
            var b = !1
              , c = db;
            "undefined" == typeof ender && (a ? (gb.moment = function() {
                return !b && console && console.warn && (b = !0,
                console.warn("Accessing Moment through the global scope is deprecated, and will be removed in an upcoming release.")),
                c.apply(null, arguments)
            }
            ,
            h(gb.moment, c)) : gb.moment = db)
        }
        for (var db, eb, fb = "2.5.1", gb = this, hb = Math.round, ib = 0, jb = 1, kb = 2, lb = 3, mb = 4, nb = 5, ob = 6, pb = {}, qb = {
            _isAMomentObject: null,
            _i: null,
            _f: null,
            _l: null,
            _strict: null,
            _isUTC: null,
            _offset: null,
            _pf: null,
            _lang: null
        }, rb = "undefined" != typeof module && module.exports && "undefined" != typeof require, sb = /^\/?Date\((\-?\d+)/i, tb = /(\-)?(?:(\d*)\.)?(\d+)\:(\d+)(?:\:(\d+)\.?(\d{3})?)?/, ub = /^(-)?P(?:(?:([0-9,.]*)Y)?(?:([0-9,.]*)M)?(?:([0-9,.]*)D)?(?:T(?:([0-9,.]*)H)?(?:([0-9,.]*)M)?(?:([0-9,.]*)S)?)?|([0-9,.]*)W)$/, vb = /(\[[^\[]*\])|(\\)?(Mo|MM?M?M?|Do|DDDo|DD?D?D?|ddd?d?|do?|w[o|w]?|W[o|W]?|YYYYYY|YYYYY|YYYY|YY|gg(ggg?)?|GG(GGG?)?|e|E|a|A|hh?|HH?|mm?|ss?|S{1,4}|X|zz?|ZZ?|.)/g, wb = /(\[[^\[]*\])|(\\)?(LT|LL?L?L?|l{1,4})/g, xb = /\d\d?/, yb = /\d{1,3}/, zb = /\d{1,4}/, Ab = /[+\-]?\d{1,6}/, Bb = /\d+/, Cb = /[0-9]*['a-z\u00A0-\u05FF\u0700-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF]+|[\u0600-\u06FF\/]+(\s*?[\u0600-\u06FF]+){1,2}/i, Db = /Z|[\+\-]\d\d:?\d\d/gi, Eb = /T/i, Fb = /[\+\-]?\d+(\.\d{1,3})?/, Gb = /\d/, Hb = /\d\d/, Ib = /\d{3}/, Jb = /\d{4}/, Kb = /[+-]?\d{6}/, Lb = /[+-]?\d+/, Mb = /^\s*(?:[+-]\d{6}|\d{4})-(?:(\d\d-\d\d)|(W\d\d$)|(W\d\d-\d)|(\d\d\d))((T| )(\d\d(:\d\d(:\d\d(\.\d+)?)?)?)?([\+\-]\d\d(?::?\d\d)?|\s*Z)?)?$/, Nb = "YYYY-MM-DDTHH:mm:ssZ", Ob = [["YYYYYY-MM-DD", /[+-]\d{6}-\d{2}-\d{2}/], ["YYYY-MM-DD", /\d{4}-\d{2}-\d{2}/], ["GGGG-[W]WW-E", /\d{4}-W\d{2}-\d/], ["GGGG-[W]WW", /\d{4}-W\d{2}/], ["YYYY-DDD", /\d{4}-\d{3}/]], Pb = [["HH:mm:ss.SSSS", /(T| )\d\d:\d\d:\d\d\.\d{1,3}/], ["HH:mm:ss", /(T| )\d\d:\d\d:\d\d/], ["HH:mm", /(T| )\d\d:\d\d/], ["HH", /(T| )\d\d/]], Qb = /([\+\-]|\d\d)/gi, Rb = "Date|Hours|Minutes|Seconds|Milliseconds".split("|"), Sb = {
            Milliseconds: 1,
            Seconds: 1e3,
            Minutes: 6e4,
            Hours: 36e5,
            Days: 864e5,
            Months: 2592e6,
            Years: 31536e6
        }, Tb = {
            ms: "millisecond",
            s: "second",
            m: "minute",
            h: "hour",
            d: "day",
            D: "date",
            w: "week",
            W: "isoWeek",
            M: "month",
            y: "year",
            DDD: "dayOfYear",
            e: "weekday",
            E: "isoWeekday",
            gg: "weekYear",
            GG: "isoWeekYear"
        }, Ub = {
            dayofyear: "dayOfYear",
            isoweekday: "isoWeekday",
            isoweek: "isoWeek",
            weekyear: "weekYear",
            isoweekyear: "isoWeekYear"
        }, Vb = {}, Wb = "DDD w W M D d".split(" "), Xb = "M D H h m s w W".split(" "), Yb = {
            M: function() {
                return this.month() + 1
            },
            MMM: function(a) {
                return this.lang().monthsShort(this, a)
            },
            MMMM: function(a) {
                return this.lang().months(this, a)
            },
            D: function() {
                return this.date()
            },
            DDD: function() {
                return this.dayOfYear()
            },
            d: function() {
                return this.day()
            },
            dd: function(a) {
                return this.lang().weekdaysMin(this, a)
            },
            ddd: function(a) {
                return this.lang().weekdaysShort(this, a)
            },
            dddd: function(a) {
                return this.lang().weekdays(this, a)
            },
            w: function() {
                return this.week()
            },
            W: function() {
                return this.isoWeek()
            },
            YY: function() {
                return k(this.year() % 100, 2)
            },
            YYYY: function() {
                return k(this.year(), 4)
            },
            YYYYY: function() {
                return k(this.year(), 5)
            },
            YYYYYY: function() {
                var a = this.year()
                  , b = a >= 0 ? "+" : "-";
                return b + k(Math.abs(a), 6)
            },
            gg: function() {
                return k(this.weekYear() % 100, 2)
            },
            gggg: function() {
                return k(this.weekYear(), 4)
            },
            ggggg: function() {
                return k(this.weekYear(), 5)
            },
            GG: function() {
                return k(this.isoWeekYear() % 100, 2)
            },
            GGGG: function() {
                return k(this.isoWeekYear(), 4)
            },
            GGGGG: function() {
                return k(this.isoWeekYear(), 5)
            },
            e: function() {
                return this.weekday()
            },
            E: function() {
                return this.isoWeekday()
            },
            a: function() {
                return this.lang().meridiem(this.hours(), this.minutes(), !0)
            },
            A: function() {
                return this.lang().meridiem(this.hours(), this.minutes(), !1)
            },
            H: function() {
                return this.hours()
            },
            h: function() {
                return this.hours() % 12 || 12
            },
            m: function() {
                return this.minutes()
            },
            s: function() {
                return this.seconds()
            },
            S: function() {
                return s(this.milliseconds() / 100)
            },
            SS: function() {
                return k(s(this.milliseconds() / 10), 2)
            },
            SSS: function() {
                return k(this.milliseconds(), 3)
            },
            SSSS: function() {
                return k(this.milliseconds(), 3)
            },
            Z: function() {
                var a = -this.zone()
                  , b = "+";
                return 0 > a && (a = -a,
                b = "-"),
                b + k(s(a / 60), 2) + ":" + k(s(a) % 60, 2)
            },
            ZZ: function() {
                var a = -this.zone()
                  , b = "+";
                return 0 > a && (a = -a,
                b = "-"),
                b + k(s(a / 60), 2) + k(s(a) % 60, 2)
            },
            z: function() {
                return this.zoneAbbr()
            },
            zz: function() {
                return this.zoneName()
            },
            X: function() {
                return this.unix()
            },
            Q: function() {
                return this.quarter()
            }
        }, Zb = ["months", "monthsShort", "weekdays", "weekdaysShort", "weekdaysMin"]; Wb.length; )
            eb = Wb.pop(),
            Yb[eb + "o"] = d(Yb[eb], eb);
        for (; Xb.length; )
            eb = Xb.pop(),
            Yb[eb + eb] = c(Yb[eb], 2);
        for (Yb.DDDD = c(Yb.DDD, 3),
        h(e.prototype, {
            set: function(a) {
                var b, c;
                for (c in a)
                    b = a[c],
                    "function" == typeof b ? this[c] = b : this["_" + c] = b
            },
            _months: "January_February_March_April_May_June_July_August_September_October_November_December".split("_"),
            months: function(a) {
                return this._months[a.month()]
            },
            _monthsShort: "Jan_Feb_Mar_Apr_May_Jun_Jul_Aug_Sep_Oct_Nov_Dec".split("_"),
            monthsShort: function(a) {
                return this._monthsShort[a.month()]
            },
            monthsParse: function(a) {
                var b, c, d;
                for (this._monthsParse || (this._monthsParse = []),
                b = 0; 12 > b; b++)
                    if (this._monthsParse[b] || (c = db.utc([2e3, b]),
                    d = "^" + this.months(c, "") + "|^" + this.monthsShort(c, ""),
                    this._monthsParse[b] = new RegExp(d.replace(".", ""),"i")),
                    this._monthsParse[b].test(a))
                        return b
            },
            _weekdays: "Sunday_Monday_Tuesday_Wednesday_Thursday_Friday_Saturday".split("_"),
            weekdays: function(a) {
                return this._weekdays[a.day()]
            },
            _weekdaysShort: "Sun_Mon_Tue_Wed_Thu_Fri_Sat".split("_"),
            weekdaysShort: function(a) {
                return this._weekdaysShort[a.day()]
            },
            _weekdaysMin: "Su_Mo_Tu_We_Th_Fr_Sa".split("_"),
            weekdaysMin: function(a) {
                return this._weekdaysMin[a.day()]
            },
            weekdaysParse: function(a) {
                var b, c, d;
                for (this._weekdaysParse || (this._weekdaysParse = []),
                b = 0; 7 > b; b++)
                    if (this._weekdaysParse[b] || (c = db([2e3, 1]).day(b),
                    d = "^" + this.weekdays(c, "") + "|^" + this.weekdaysShort(c, "") + "|^" + this.weekdaysMin(c, ""),
                    this._weekdaysParse[b] = new RegExp(d.replace(".", ""),"i")),
                    this._weekdaysParse[b].test(a))
                        return b
            },
            _longDateFormat: {
                LT: "h:mm A",
                L: "MM/DD/YYYY",
                LL: "MMMM D YYYY",
                LLL: "MMMM D YYYY LT",
                LLLL: "dddd, MMMM D YYYY LT"
            },
            longDateFormat: function(a) {
                var b = this._longDateFormat[a];
                return !b && this._longDateFormat[a.toUpperCase()] && (b = this._longDateFormat[a.toUpperCase()].replace(/MMMM|MM|DD|dddd/g, function(a) {
                    return a.slice(1)
                }),
                this._longDateFormat[a] = b),
                b
            },
            isPM: function(a) {
                return "p" === (a + "").toLowerCase().charAt(0)
            },
            _meridiemParse: /[ap]\.?m?\.?/i,
            meridiem: function(a, b, c) {
                return a > 11 ? c ? "pm" : "PM" : c ? "am" : "AM"
            },
            _calendar: {
                sameDay: "[Today at] LT",
                nextDay: "[Tomorrow at] LT",
                nextWeek: "dddd [at] LT",
                lastDay: "[Yesterday at] LT",
                lastWeek: "[Last] dddd [at] LT",
                sameElse: "L"
            },
            calendar: function(a, b) {
                var c = this._calendar[a];
                return "function" == typeof c ? c.apply(b) : c
            },
            _relativeTime: {
                future: "in %s",
                past: "%s ago",
                s: "a few seconds",
                m: "a minute",
                mm: "%d minutes",
                h: "an hour",
                hh: "%d hours",
                d: "a day",
                dd: "%d days",
                M: "a month",
                MM: "%d months",
                y: "a year",
                yy: "%d years"
            },
            relativeTime: function(a, b, c, d) {
                var e = this._relativeTime[c];
                return "function" == typeof e ? e(a, b, c, d) : e.replace(/%d/i, a)
            },
            pastFuture: function(a, b) {
                var c = this._relativeTime[a > 0 ? "future" : "past"];
                return "function" == typeof c ? c(b) : c.replace(/%s/i, b)
            },
            ordinal: function(a) {
                return this._ordinal.replace("%d", a)
            },
            _ordinal: "%d",
            preparse: function(a) {
                return a
            },
            postformat: function(a) {
                return a
            },
            week: function(a) {
                return Y(a, this._week.dow, this._week.doy).week
            },
            _week: {
                dow: 0,
                doy: 6
            },
            _invalidDate: "Invalid date",
            invalidDate: function() {
                return this._invalidDate
            }
        }),
        db = function(c, d, e, f) {
            var g;
            return "boolean" == typeof e && (f = e,
            e = a),
            g = {},
            g._isAMomentObject = !0,
            g._i = c,
            g._f = d,
            g._l = e,
            g._strict = f,
            g._isUTC = !1,
            g._pf = b(),
            $(g)
        }
        ,
        db.utc = function(c, d, e, f) {
            var g;
            return "boolean" == typeof e && (f = e,
            e = a),
            g = {},
            g._isAMomentObject = !0,
            g._useUTC = !0,
            g._isUTC = !0,
            g._l = e,
            g._i = c,
            g._f = d,
            g._strict = f,
            g._pf = b(),
            $(g).utc()
        }
        ,
        db.unix = function(a) {
            return db(1e3 * a)
        }
        ,
        db.duration = function(a, b) {
            var c, d, e, f = a, h = null;
            return db.isDuration(a) ? f = {
                ms: a._milliseconds,
                d: a._days,
                M: a._months
            } : "number" == typeof a ? (f = {},
            b ? f[b] = a : f.milliseconds = a) : (h = tb.exec(a)) ? (c = "-" === h[1] ? -1 : 1,
            f = {
                y: 0,
                d: s(h[kb]) * c,
                h: s(h[lb]) * c,
                m: s(h[mb]) * c,
                s: s(h[nb]) * c,
                ms: s(h[ob]) * c
            }) : (h = ub.exec(a)) && (c = "-" === h[1] ? -1 : 1,
            e = function(a) {
                var b = a && parseFloat(a.replace(",", "."));
                return (isNaN(b) ? 0 : b) * c
            }
            ,
            f = {
                y: e(h[2]),
                M: e(h[3]),
                d: e(h[4]),
                h: e(h[5]),
                m: e(h[6]),
                s: e(h[7]),
                w: e(h[8])
            }),
            d = new g(f),
            db.isDuration(a) && a.hasOwnProperty("_lang") && (d._lang = a._lang),
            d
        }
        ,
        db.version = fb,
        db.defaultFormat = Nb,
        db.updateOffset = function() {}
        ,
        db.lang = function(a, b) {
            var c;
            return a ? (b ? A(y(a), b) : null === b ? (B(a),
            a = "en") : pb[a] || C(a),
            c = db.duration.fn._lang = db.fn._lang = C(a),
            c._abbr) : db.fn._lang._abbr
        }
        ,
        db.langData = function(a) {
            return a && a._lang && a._lang._abbr && (a = a._lang._abbr),
            C(a)
        }
        ,
        db.isMoment = function(a) {
            return a instanceof f || null != a && a.hasOwnProperty("_isAMomentObject")
        }
        ,
        db.isDuration = function(a) {
            return a instanceof g
        }
        ,
        eb = Zb.length - 1; eb >= 0; --eb)
            r(Zb[eb]);
        for (db.normalizeUnits = function(a) {
            return p(a)
        }
        ,
        db.invalid = function(a) {
            var b = db.utc(0 / 0);
            return null != a ? h(b._pf, a) : b._pf.userInvalidated = !0,
            b
        }
        ,
        db.parseZone = function(a) {
            return db(a).parseZone()
        }
        ,
        h(db.fn = f.prototype, {
            clone: function() {
                return db(this)
            },
            valueOf: function() {
                return +this._d + 6e4 * (this._offset || 0)
            },
            unix: function() {
                return Math.floor(+this / 1e3)
            },
            toString: function() {
                return this.clone().lang("en").format("ddd MMM DD YYYY HH:mm:ss [GMT]ZZ")
            },
            toDate: function() {
                return this._offset ? new Date(+this) : this._d
            },
            toISOString: function() {
                var a = db(this).utc();
                return 0 < a.year() && a.year() <= 9999 ? F(a, "YYYY-MM-DD[T]HH:mm:ss.SSS[Z]") : F(a, "YYYYYY-MM-DD[T]HH:mm:ss.SSS[Z]")
            },
            toArray: function() {
                var a = this;
                return [a.year(), a.month(), a.date(), a.hours(), a.minutes(), a.seconds(), a.milliseconds()]
            },
            isValid: function() {
                return x(this)
            },
            isDSTShifted: function() {
                return this._a ? this.isValid() && o(this._a, (this._isUTC ? db.utc(this._a) : db(this._a)).toArray()) > 0 : !1
            },
            parsingFlags: function() {
                return h({}, this._pf)
            },
            invalidAt: function() {
                return this._pf.overflow
            },
            utc: function() {
                return this.zone(0)
            },
            local: function() {
                return this.zone(0),
                this._isUTC = !1,
                this
            },
            format: function(a) {
                var b = F(this, a || db.defaultFormat);
                return this.lang().postformat(b)
            },
            add: function(a, b) {
                var c;
                return c = "string" == typeof a ? db.duration(+b, a) : db.duration(a, b),
                l(this, c, 1),
                this
            },
            subtract: function(a, b) {
                var c;
                return c = "string" == typeof a ? db.duration(+b, a) : db.duration(a, b),
                l(this, c, -1),
                this
            },
            diff: function(a, b, c) {
                var d, e, f = z(a, this), g = 6e4 * (this.zone() - f.zone());
                return b = p(b),
                "year" === b || "month" === b ? (d = 432e5 * (this.daysInMonth() + f.daysInMonth()),
                e = 12 * (this.year() - f.year()) + (this.month() - f.month()),
                e += (this - db(this).startOf("month") - (f - db(f).startOf("month"))) / d,
                e -= 6e4 * (this.zone() - db(this).startOf("month").zone() - (f.zone() - db(f).startOf("month").zone())) / d,
                "year" === b && (e /= 12)) : (d = this - f,
                e = "second" === b ? d / 1e3 : "minute" === b ? d / 6e4 : "hour" === b ? d / 36e5 : "day" === b ? (d - g) / 864e5 : "week" === b ? (d - g) / 6048e5 : d),
                c ? e : j(e)
            },
            from: function(a, b) {
                return db.duration(this.diff(a)).lang(this.lang()._abbr).humanize(!b)
            },
            fromNow: function(a) {
                return this.from(db(), a)
            },
            calendar: function() {
                var a = z(db(), this).startOf("day")
                  , b = this.diff(a, "days", !0)
                  , c = -6 > b ? "sameElse" : -1 > b ? "lastWeek" : 0 > b ? "lastDay" : 1 > b ? "sameDay" : 2 > b ? "nextDay" : 7 > b ? "nextWeek" : "sameElse";
                return this.format(this.lang().calendar(c, this))
            },
            isLeapYear: function() {
                return v(this.year())
            },
            isDST: function() {
                return this.zone() < this.clone().month(0).zone() || this.zone() < this.clone().month(5).zone()
            },
            day: function(a) {
                var b = this._isUTC ? this._d.getUTCDay() : this._d.getDay();
                return null != a ? (a = V(a, this.lang()),
                this.add({
                    d: a - b
                })) : b
            },
            month: function(a) {
                var b, c = this._isUTC ? "UTC" : "";
                return null != a ? "string" == typeof a && (a = this.lang().monthsParse(a),
                "number" != typeof a) ? this : (b = this.date(),
                this.date(1),
                this._d["set" + c + "Month"](a),
                this.date(Math.min(b, this.daysInMonth())),
                db.updateOffset(this),
                this) : this._d["get" + c + "Month"]()
            },
            startOf: function(a) {
                switch (a = p(a)) {
                case "year":
                    this.month(0);
                case "month":
                    this.date(1);
                case "week":
                case "isoWeek":
                case "day":
                    this.hours(0);
                case "hour":
                    this.minutes(0);
                case "minute":
                    this.seconds(0);
                case "second":
                    this.milliseconds(0)
                }
                return "week" === a ? this.weekday(0) : "isoWeek" === a && this.isoWeekday(1),
                this
            },
            endOf: function(a) {
                return a = p(a),
                this.startOf(a).add("isoWeek" === a ? "week" : a, 1).subtract("ms", 1)
            },
            isAfter: function(a, b) {
                return b = "undefined" != typeof b ? b : "millisecond",
                +this.clone().startOf(b) > +db(a).startOf(b)
            },
            isBefore: function(a, b) {
                return b = "undefined" != typeof b ? b : "millisecond",
                +this.clone().startOf(b) < +db(a).startOf(b)
            },
            isSame: function(a, b) {
                return b = b || "ms",
                +this.clone().startOf(b) === +z(a, this).startOf(b)
            },
            min: function(a) {
                return a = db.apply(null, arguments),
                this > a ? this : a
            },
            max: function(a) {
                return a = db.apply(null, arguments),
                a > this ? this : a
            },
            zone: function(a) {
                var b = this._offset || 0;
                return null == a ? this._isUTC ? b : this._d.getTimezoneOffset() : ("string" == typeof a && (a = I(a)),
                Math.abs(a) < 16 && (a = 60 * a),
                this._offset = a,
                this._isUTC = !0,
                b !== a && l(this, db.duration(b - a, "m"), 1, !0),
                this)
            },
            zoneAbbr: function() {
                return this._isUTC ? "UTC" : ""
            },
            zoneName: function() {
                return this._isUTC ? "Coordinated Universal Time" : ""
            },
            parseZone: function() {
                return this._tzm ? this.zone(this._tzm) : "string" == typeof this._i && this.zone(this._i),
                this
            },
            hasAlignedHourOffset: function(a) {
                return a = a ? db(a).zone() : 0,
                (this.zone() - a) % 60 === 0
            },
            daysInMonth: function() {
                return t(this.year(), this.month())
            },
            dayOfYear: function(a) {
                var b = hb((db(this).startOf("day") - db(this).startOf("year")) / 864e5) + 1;
                return null == a ? b : this.add("d", a - b)
            },
            quarter: function() {
                return Math.ceil((this.month() + 1) / 3)
            },
            weekYear: function(a) {
                var b = Y(this, this.lang()._week.dow, this.lang()._week.doy).year;
                return null == a ? b : this.add("y", a - b)
            },
            isoWeekYear: function(a) {
                var b = Y(this, 1, 4).year;
                return null == a ? b : this.add("y", a - b)
            },
            week: function(a) {
                var b = this.lang().week(this);
                return null == a ? b : this.add("d", 7 * (a - b))
            },
            isoWeek: function(a) {
                var b = Y(this, 1, 4).week;
                return null == a ? b : this.add("d", 7 * (a - b))
            },
            weekday: function(a) {
                var b = (this.day() + 7 - this.lang()._week.dow) % 7;
                return null == a ? b : this.add("d", a - b)
            },
            isoWeekday: function(a) {
                return null == a ? this.day() || 7 : this.day(this.day() % 7 ? a : a - 7)
            },
            get: function(a) {
                return a = p(a),
                this[a]()
            },
            set: function(a, b) {
                return a = p(a),
                "function" == typeof this[a] && this[a](b),
                this
            },
            lang: function(b) {
                return b === a ? this._lang : (this._lang = C(b),
                this)
            }
        }),
        eb = 0; eb < Rb.length; eb++)
            _(Rb[eb].toLowerCase().replace(/s$/, ""), Rb[eb]);
        _("year", "FullYear"),
        db.fn.days = db.fn.day,
        db.fn.months = db.fn.month,
        db.fn.weeks = db.fn.week,
        db.fn.isoWeeks = db.fn.isoWeek,
        db.fn.toJSON = db.fn.toISOString,
        h(db.duration.fn = g.prototype, {
            _bubble: function() {
                var a, b, c, d, e = this._milliseconds, f = this._days, g = this._months, h = this._data;
                h.milliseconds = e % 1e3,
                a = j(e / 1e3),
                h.seconds = a % 60,
                b = j(a / 60),
                h.minutes = b % 60,
                c = j(b / 60),
                h.hours = c % 24,
                f += j(c / 24),
                h.days = f % 30,
                g += j(f / 30),
                h.months = g % 12,
                d = j(g / 12),
                h.years = d
            },
            weeks: function() {
                return j(this.days() / 7)
            },
            valueOf: function() {
                return this._milliseconds + 864e5 * this._days + this._months % 12 * 2592e6 + 31536e6 * s(this._months / 12)
            },
            humanize: function(a) {
                var b = +this
                  , c = X(b, !a, this.lang());
                return a && (c = this.lang().pastFuture(b, c)),
                this.lang().postformat(c)
            },
            add: function(a, b) {
                var c = db.duration(a, b);
                return this._milliseconds += c._milliseconds,
                this._days += c._days,
                this._months += c._months,
                this._bubble(),
                this
            },
            subtract: function(a, b) {
                var c = db.duration(a, b);
                return this._milliseconds -= c._milliseconds,
                this._days -= c._days,
                this._months -= c._months,
                this._bubble(),
                this
            },
            get: function(a) {
                return a = p(a),
                this[a.toLowerCase() + "s"]()
            },
            as: function(a) {
                return a = p(a),
                this["as" + a.charAt(0).toUpperCase() + a.slice(1) + "s"]()
            },
            lang: db.fn.lang,
            toIsoString: function() {
                var a = Math.abs(this.years())
                  , b = Math.abs(this.months())
                  , c = Math.abs(this.days())
                  , d = Math.abs(this.hours())
                  , e = Math.abs(this.minutes())
                  , f = Math.abs(this.seconds() + this.milliseconds() / 1e3);
                return this.asSeconds() ? (this.asSeconds() < 0 ? "-" : "") + "P" + (a ? a + "Y" : "") + (b ? b + "M" : "") + (c ? c + "D" : "") + (d || e || f ? "T" : "") + (d ? d + "H" : "") + (e ? e + "M" : "") + (f ? f + "S" : "") : "P0D"
            }
        });
        for (eb in Sb)
            Sb.hasOwnProperty(eb) && (bb(eb, Sb[eb]),
            ab(eb.toLowerCase()));
        bb("Weeks", 6048e5),
        db.duration.fn.asMonths = function() {
            return (+this - 31536e6 * this.years()) / 2592e6 + 12 * this.years()
        }
        ,
        db.lang("en", {
            ordinal: function(a) {
                var b = a % 10
                  , c = 1 === s(a % 100 / 10) ? "th" : 1 === b ? "st" : 2 === b ? "nd" : 3 === b ? "rd" : "th";
                return a + c
            }
        }),
        rb ? (module.exports = db,
        cb(!0)) : "function" == typeof define && define.amd ? define("moment", function(b, c, d) {
            return d.config && d.config() && d.config().noGlobal !== !0 && cb(d.config().noGlobal === a),
            db
        }) : cb()
    }
    ).call(this);
    
      </script>
    </head>
    <body>
    
    <div class="content"> 
    
        <h1>Download time calculator</h1>
    	<h3>How long will take to download this?</h3>
    	
    	<form onsubmit="return false">
    	<div id="speed">
    		<h3>How fast is your connection speed?</h3>
    		
    		<p>
    			<label for="internetSpeed">Download Speed</label>
    			<input id="internetSpeed" type="number" min="0" step="0.01" value="10" placeholder="Download speed" autofocus="">
    			
    			<input id="internetSpeed_p" type="button" value="+" onclick="internetSpeed.value = (parseInt(internetSpeed.value)+1).toFixed(2)">
    			<input id="internetSpeed_p" type="button" value="-" onclick="internetSpeed.value = (parseInt(internetSpeed.value)-1).toFixed(2)">
    			
    			<select id="internetSpeedBase">
    				<option value="10^3">Kbps</option>
    				<option value="10^6" selected="">Mbps</option>
    			</select>
    		</p>
    		
    		<p class="idkSpeed"><a id="speedtestLink" href="http://speedtest.net" target="new">I don't know my internet speed</a></p>
    		
    		<div>
    			<label class="collapse" for="_1">▼</label>
    		  	<input id="_1" type="checkbox">
    		  	<div>
    				<p class="overhead-p"><label for="internetOverhead">Overhead</label>
    					<select id="internetOverhead">
    						<option value="1" selected="">None</option>
    						<option value="0.99">1%</option>
    						<option value="0.95">5%</option>
    						<option value="0.9">10% (Tipical TCP overhead)</option>
    						<option value="0.85">15%</option>
    						<option value="0.8">20%</option>
    						<option value="0.75">25%</option>
    						<option value="0.7">30%</option>
    						<option value="0.6">40%</option>
    						<option value="0.5">50%</option>
    						<option value="0.4">60%</option>
    						<option value="0.3">70%</option>
    						<option value="0.2">80%</option>
    						<option value="0.1">90%</option>
    						<option value="0.05">95%</option>
    						<option value="0.01">99%</option>
    					</select>
    					<a href="#" onclick="alert('If you just measured your internet speed, you don\'t need to change this.\n\nBut if enter your contracted speed e.g. 10Mbps, keep in mind this value is a teorical maximum, there will always be overhead.\nFor a conservative value use 10% (tipical TCP overhead) or for more realistic results use 20%.')">Help</a>
    				</p>
    			</div>
    		</div>	
    	</div>
    	
    	<div id="file">
    		<h3>What is the size of what you want to download?</h3>
    		<p> 
    			<label for="fileSize">Size</label>
    			<input type="number" id="fileSize" value="1" step="0.01" min="0">
    			<input id="internetSpeed_p" type="button" value="+" onclick="fileSize.value = (parseInt(fileSize.value)+1).toFixed(2)">
    			<input id="internetSpeed_p" type="button" value="-" onclick="fileSize.value = (parseInt(fileSize.value)-1).toFixed(2)">
    			<select id="fileSizeBase">
    				<option value="2^10">KB (KiloBytes)</option>
    				<option value="2^20" selected="">MB (MegaBytes)</option>
    				<option value="2^30">GB (GigaBytes)</option>
    				<option value="2^40">TB (TeraBytes)</option>
    			</select>
    		</p>
    		
    		<p class="examples-p" style="display:none"> 
    			<label for="fileSizeEx">Examples</label>
    			<select id="fileSizeEx">
    				<option></option>
    				<optgroup label="iTunes Store">
    					<option value="4">4-minute song</option>
    					<option value="30">5-minute video</option>
    					<option value="110">9-hour audiobook</option>
    					<option value="200">45-minute TV show</option>
    					<option value="600">45-minute HDTV show</option>
    					<option value="1.5">2-hour SD movie</option>
    					<option value="4">2-hour HD movie</option>
    					<option value="40">iPod Game</option>
    				</optgroup>
    				<optgroup label="Playstation Network">
    					<option value="9">PS3 Game</option>
    					<option value="24">PS4 Game</option>
    				</optgroup>
    				<option value=""></option>
    				<option value=""></option>
    				<option value=""></option>
    			</select>
    		</p>
    		
    		<p>
    			<button id="calculateButton">Calculate</button>
    		</p>
    	</div>
    	
    	</form>
    	
    	<div id="results" style="visibility: visible;">
    		<div id="results_inner">
    			<p class="time"></p>
    			<p class=""> <span class="size"></span> </p>
    			<p class=""> <span class="speed"></span></p>
    		</div>
    		
    		<hr>
    
    		<div id="downloadSimulatorWindow" style="visibility: visible;">
    			<div class="filename">Simulation</div>
    			<div class="icon"></div>
    			
    			<div class="percent"></div>
    			<div class="progresrbar"><progress max="100" value="0"></progress></div>
    			
    			<div class="details">
    				<span class="downloaded"></span> of <span class="size"></span> (<span class="speed"></span>/sec) <span> - </span> <span class="remaining"></span> remaining
    			</div>
    			<div class="ps">* this is not an actual transfer, this is just a simulation of how much time it would take</div>
    		</div>
    	</div>
    
        <div class="footer">
    		
    		<a href="#">Download-Calculator</a>
    	</div>
    
    </div>
    
    <script>
    var downloadSimulator = null;
    window.onload=function(){
    	calculateButton.onclick = calc;
    	var hasFlash = function() {
    		if(typeof navigator.plugins == "undefined" || navigator.plugins.length == 0){
    			try{
    				return !!(new ActiveXObject("ShockwaveFlash.ShockwaveFlash"));
    			}catch(e){
    				return undefined;
    			}
    		}else{
    			return navigator.plugins["Shockwave Flash"];
    		}
    	};
    	if(!hasFlash()){
    		speedtest.style.display = 'none';
    		speedtestLink.innerHTML = "Test my internet speed";
    		document.querySelector('.idkSpeed').classList.add("mobile");
    	}
    	downloadSimulator = new Downloader(document.getElementById('downloadSimulatorWindow'));
    	if(window.location.hash){
    		var uri = window.location.hash;
    		internetSpeed.value = uri.match(/speed=([\d.]+)x(\d+\^\d+)/)[1];
    		internetSpeedBase.value = uri.match(/speed=([\d.]+)x(\d+\^\d+)/)[2];
    		internetOverhead.value = uri.match(/overhead=([\d.]+)/)[1];
    		fileSize.value = uri.match(/file=([\d.]+)x(\d+\^\d+)/)[1];
    		fileSizeBase.value = uri.match(/file=([\d.]+)x(\d+\^\d+)/)[2];
    		calc();
    	}else if(window.localStorage){
    		if(window.localStorage.getItem('downloadtime.speed')){
    			internetSpeed.value = window.localStorage.getItem('downloadtime.speed');
    			internetSpeedBase.value = window.localStorage.getItem('downloadtime.speedBase');
    			internetOverhead.value = window.localStorage.getItem('downloadtime.overhead');
    			fileSize.value = window.localStorage.getItem('downloadtime.file');
    			fileSizeBase.value = window.localStorage.getItem('downloadtime.fileBase');
    		}else defaults();
    	}else defaults();
    
     document.getElementsByTagName("form")[0].onsubmit = function(e){
    		if (e.stopPropagation) e.stopPropagation();
    	    else e.cancelBubble = true;
    	    if (e.preventDefault) e.preventDefault();
    	    else e.returnValue = false;
    		this.returnValue = false;
    		calc();
    		return false;
    	} 
    };
    function defaults(){
    	internetSpeed.value = "10";
    	internetSpeedBase.value = "10^6";
    	internetOverhead.value = "0.9";
    	fileSize.value = "1";
    	fileSizeBase.value = "2^30";
    }
    
    function calc(){
    	var internet = {
    		speed: internetSpeed.value,
    		factor: internetSpeedBase.value,
    		overhead: internetOverhead.value,
    	}
    	internet.speed = parseFloat(internet.speed);
    	internet.overhead = parseFloat(internet.overhead);
    	internet.factor = {
    		base: internet.factor.match(/(\d+)\^(\d+)/)[1],
    		power: internet.factor.match(/(\d+)\^(\d+)/)[2]
    	}
    	internet.bitsPerSec = internet.speed * Math.pow(internet.factor.base, internet.factor.power);
    	internet.bytesPerSec = internet.bitsPerSec/8;
    
    	var file = {
    		size: fileSize.value,
    		factor:	fileSizeBase.value,
    	}
    	
    	file.size = parseFloat(file.size);
    	file.factor = {
    		base: file.factor.match(/(\d+)\^(\d+)/)[1],
    		power: file.factor.match(/(\d+)\^(\d+)/)[2]
    	}
    	file.bytes = file.size * Math.pow(file.factor.base, file.factor.power);
    	internet.effectiveBytesPerSec = internet.bytesPerSec * internet.overhead;
    	var transferTime_ms = (file.bytes/internet.effectiveBytesPerSec)*1000;
    	document.querySelector("#results .time").innerHTML = moment.preciseDiff(0, transferTime_ms);
    	document.querySelector("#results .size").innerHTML = prefixByteLong(file.bytes);
    	document.querySelector("#results .speed").innerHTML = prefixByte(internet.effectiveBytesPerSec);
    	document.getElementById("results").style.visibility = "visible";
    	document.getElementById("downloadSimulatorWindow").style.visibility = "visible";
    	downloadSimulator.start(file.bytes, internet.effectiveBytesPerSec, "Simulation");
    	if(window.location){
    		var uri=[];
    		uri.push("file="+fileSize.value+"x"+fileSizeBase.value);
    		uri.push("speed="+internetSpeed.value+"x"+internetSpeedBase.value);
    		uri.push("overhead="+internetOverhead.value);
    		window.location.hash = uri.join("&");
    	}
    	
    	if(window.localStorage){		
    		window.localStorage.setItem('downloadtime.speed', internetSpeed.value);
    		window.localStorage.setItem('downloadtime.speedBase', internetSpeedBase.value);
    		window.localStorage.setItem('downloadtime.overhead', internetOverhead.value);
    		window.localStorage.setItem('downloadtime.file', fileSize.value);
    		window.localStorage.setItem('downloadtime.fileBase', fileSizeBase.value);
    	}
    	
    	var t = msToTime(transferTime);
    	console.log(t);
    	str = [];
    	
    	if(t.years >= 1) str.push( t.years + " year" + (t.years>=2?"s":"") );
    	if(t.months >= 1) str.push( t.months + " month" + (t.months>=2?"s":"") );
    	if(t.weeks >= 1) str.push( t.weeks + " week" + (t.weeks>=2?"s":"") );
    	if(t.days >= 1) str.push( t.days + " day" + (t.days>=2?"s":"") );
    	if(t.hours >= 1) str.push( t.hours + " hour" + (t.hours>=2?"s":"") );
    	if(t.minutes >= 1) str.push( t.minutes + " minute" + (t.minutes>=2?"s":"") );
    	if(t.seconds >= 1) str.push( t.seconds + " second" + (t.seconds>=2?"s":"") );
    	if(t.ms >= 1) str.push( t.ms + " ms" );
    	time.innerHTML = str.join(", ")+".";
    	time.innerHTML = moment.duration(transferTime).humanize();
    }
    function msToTime(ms) {
    	debugger;;
    	var t={};
    	t.ms = ms % 1000;
    	ms = (ms - t.ms) / 1000;
    	
    	t.seconds = ms % 60;
    	ms = (ms - t.seconds) / 60;
    	
    	t.minutes = ms % 60;
    	ms = (ms - t.minutes) / 60;
    	
    	t.hours = ms % 60;
    	ms = (ms - t.hours) / 60;
    	
    	t.days = ms % 24;
    	ms = (ms - t.days) / 24;
    	
    	t.weeks = ms % 7;  
    	ms = (ms - t.weeks) / 7;
    	
    	t.months = ms % ((365/12)/7);
    	ms = (ms - t.months) / ((365/12)/7);
    	
    	t.years = ms % (365/12);
    	ms = (ms - t.years) / (365/12);
    	
    	console.log(JSON.stringify(t));
    	
    	return t;
    }
    
    
    
    (function(moment) {
        var STRINGS = {
            nodiff: '',
            year: 'year',
            years: 'years',
            month: 'month',
            months: 'months',
            day: 'day',
            days: 'days',
            hour: 'hour',
            hours: 'hours',
            minute: 'minute',
            minutes: 'minutes',
            second: 'second',
            seconds: 'seconds',
            delimiter: ' '
        };
        moment.fn.preciseDiff = function(d2) {
            return moment.preciseDiff(this, d2);
        };
        moment.preciseDiff = function(d1, d2) {
            var m1 = moment(d1), m2 = moment(d2);
            if (m1.isSame(m2)) {
                return STRINGS.nodiff;
            }
            if (m1.isAfter(m2)) {
                var tmp = m1;
                m1 = m2;
                m2 = tmp;
            }
    
            var yDiff = m2.year() - m1.year();
            var mDiff = m2.month() - m1.month();
            var dDiff = m2.date() - m1.date();
            var hourDiff = m2.hour() - m1.hour();
            var minDiff = m2.minute() - m1.minute();
            var secDiff = m2.second() - m1.second();
    
            if (secDiff < 0) {
                secDiff = 60 + secDiff;
                minDiff--;
            }
            if (minDiff < 0) {
                minDiff = 60 + minDiff;
                hourDiff--;
            }
            if (hourDiff < 0) {
                hourDiff = 24 + hourDiff;
                dDiff--;
            }
            if (dDiff < 0) {
                var daysInLastFullMonth = moment(m2.year() + '-' + (m2.month() + 1), "YYYY-MM").subtract('months', 1).daysInMonth();
                if (daysInLastFullMonth < m1.date()) { // 31/01 -> 2/03
                    dDiff = daysInLastFullMonth + dDiff + (m1.date() - daysInLastFullMonth);
                } else {
                    dDiff = daysInLastFullMonth + dDiff;
                }
                mDiff--;
            }
            if (mDiff < 0) {
                mDiff = 12 + mDiff;
                yDiff--;
            }
    
            function pluralize(num, word) {
                return num + ' ' + STRINGS[word + (num === 1 ? '' : 's')];
            }
            var result = [];
    
            if (yDiff) {
                result.push(pluralize(yDiff, 'year'));
            }
            if (mDiff) {
                result.push(pluralize(mDiff, 'month'));
            }
            if (dDiff) {
                result.push(pluralize(dDiff, 'day'));
            }
            if (hourDiff) {
                result.push(pluralize(hourDiff, 'hour'));
            }
            if (minDiff) {
                result.push(pluralize(minDiff, 'minute'));
            }
            if (secDiff) {
                result.push(pluralize(secDiff, 'second'));
            }
    
            return result.join(STRINGS.delimiter);
        };
    }(moment));
     
    function Downloader(elm){
    	
    	var self = this;
    	
    	this.fileSize;
    	this.speed;
    	
    	this.DOM = {
    		progress: elm.querySelector('progress'),
    		percent: elm.querySelector('.percent'),
    		downloaded: elm.querySelector('.downloaded'),
    		details: elm.querySelector('.details'),
    		size: elm.querySelector('.size'),
    		speed: elm.querySelector('.speed'),
    		remaining: elm.querySelector('.remaining'),
    		
    		filename: elm.querySelector('.filename')
    	}
    	
    	var _transferTime;
    	var _startTime;
    	var _elapsedTime;
    	var _remainingTime;
    	var _downloaded;
    	var _percent;
    	
    	var _timer;
    
    	this.start = function(fileSize, speed, filename){
    		
    		this.DOM.filename.innerHTML = filename;
    		
    		clearInterval(_timer);
    		
    		_startTime = Date.now();
    		_downloaded = 0;
    		_percent = 0;
    		
    		self.fileSize = fileSize;
    		self.speed = speed;
    		
    		_transferTime = (fileSize / speed)*1000;
    		
    		this.DOM.details.style.display = "";
    
    		self.update();
    		_timer = setInterval(function(){self.update()},500);
    	}
    		
    	this.update = function(){
    		var now = Date.now();
    		
    		_elapsedTime = now - _startTime;
    		_remainingTime = _transferTime - _elapsedTime;
    		_percent = (_elapsedTime / _transferTime) * 100;
    		_downloaded = this.fileSize * (_elapsedTime / _transferTime);
    		
    		this.DOM.progress.value = _percent;
    		this.DOM.percent.innerHTML = (_percent<<0) + "%";
    		this.DOM.downloaded.innerHTML = prefixByte(_downloaded);
    		this.DOM.size.innerHTML = prefixByte(this.fileSize);
    		this.DOM.speed.innerHTML = prefixByte(this.speed);
    		this.DOM.remaining.innerHTML = moment.duration(_remainingTime).humanize();
    		
    		if(_elapsedTime>=_transferTime){
    			this.stop();
    		}
    	}
    	
    	this.stop = function(){
    		
    		clearInterval(_timer);
    		
    		_elapsedTime = -1;
    		_remainingTime = 0;
    		_percent = 100;
    		_downloaded = this.fileSize;
    		
    		this.DOM.progress.value = 100;
    		this.DOM.percent.innerHTML = "100%";
    		this.DOM.downloaded.innerHTML = prefixByte(this.fileSize);
    
    		
    		this.DOM.size.innerHTML = prefixByte(this.fileSize);
    		this.DOM.speed.innerHTML = prefixByte(this.speed);
    		this.DOM.remaining.innerHTML = "0";
    		
    
    		this.DOM.details.style.display = "none";
    	}
    
    }
     
    function Prefixer(unit, prefix, format){
    	
    	for(var i=0; i<prefix.length; i++){
    		prefix[i][4] = Math.pow(prefix[i][0], prefix[i][1]);
    	}
    	
    	return function(x){
    		x=parseFloat(x);
    		var r, n=x<0?-1:1;
    		
    		x = x*n;
    		for(var i=0; i<prefix.length; i++){
    			if(x>=prefix[i][4]-1){
    				r = prefix[i];
    			}
    			else break;
    		}
    		x = x*n;
    		x = (x/r[4]);
    		
    		var obj = {
    			value: x,
    			symbol: r[2],
    			prefix: r[3],
    			base: r[0],
    			factor: r[1],
    			plural: x!=1?true:false,
    			s: x!=1?"s":"",
    			unit: unit,
    			units: x!=1?unit+"s":unit
    		};
    		return format?format.apply(obj):obj;
    	}
    }
    
    var prefixByte = new Prefixer("B",[
    		[2,  0, '', ''],
    		[2, 10, 'K', 'Kilo'],
    		[2, 20, 'M', 'Mega'],
    		[2, 30, 'G', 'Giga'],
    		[2, 40, 'T', 'Tera'],
    		[2, 50, 'P', 'Peta'],
    		[2, 60, 'E', 'Exa'],
    		[2, 70, 'Z', 'Zetta'],
    		[2, 80, 'Y', 'Yotta']
    	], function(){
    		return parseFloat(this.value.toFixed(2))+" "+this.symbol+this.unit;
    	}
    );
    
    var prefixByteLong = new Prefixer("byte",[
    		[2,  0, '', ''],
    		[2, 10, 'K', 'Kilo'],
    		[2, 20, 'M', 'Mega'],
    		[2, 30, 'G', 'Giga'],
    		[2, 40, 'T', 'Tera'],
    		[2, 50, 'P', 'Peta'],
    		[2, 60, 'E', 'Exa'],
    		[2, 70, 'Z', 'Zetta'],
    		[2, 80, 'Y', 'Yotta']
    	], function(){
    		return parseFloat(this.value.toFixed(2))+" "+this.prefix+this.units;
    	}
    );
    
    var prefixBit = new Prefixer("bit",[
    		[10,  0, '', ''],
    		[10,  3, 'K', 'Kilo'],
    		[10,  6, 'M', 'Mega'],
    		[10,  9, 'G', 'Giga'],
    		[10, 12, 'T', 'Tera'],
    		[10, 15, 'P', 'Peta'],
    		[10, 18, 'E', 'Exa'],
    		[10, 21, 'Z', 'Zetta'],
    		[10, 24, 'Y', 'Yotta']
    	], function(){
    		return this.value+" "+this.symbol+this.unit;
    	}
    );
    
    var prefixBitLong = new Prefixer("bit",[
    		[10,  0, '', ''],
    		[10,  3, 'K', 'Kilo'],
    		[10,  6, 'M', 'Mega'],
    		[10,  9, 'G', 'Giga'],
    		[10, 12, 'T', 'Tera'],
    		[10, 15, 'P', 'Peta'],
    		[10, 18, 'E', 'Exa'],
    		[10, 21, 'Z', 'Zetta'],
    		[10, 24, 'Y', 'Yotta']
    	], function(){
    		return this.value+" "+this.prefix+this.units;
    	}
    );
    
    
    </script>
      
    
    
    </body></html>