f71a8576 by David LaPalomento

Convert m3u8 tests to use deepEquals against a known "good" parse

Take all the remaining test cases and conver them into pairs of m3u8 and json files. Removed handlebars since it's no longer in use.
1 parent 6a7f0679
Showing 56 changed files with 1470 additions and 3455 deletions
1 /*!
2
3 handlebars v1.1.2
4
5 Copyright (C) 2011 by Yehuda Katz
6
7 Permission is hereby granted, free of charge, to any person obtaining a copy
8 of this software and associated documentation files (the "Software"), to deal
9 in the Software without restriction, including without limitation the rights
10 to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
11 copies of the Software, and to permit persons to whom the Software is
12 furnished to do so, subject to the following conditions:
13
14 The above copyright notice and this permission notice shall be included in
15 all copies or substantial portions of the Software.
16
17 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
18 IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
19 FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
20 AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
21 LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
22 OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
23 THE SOFTWARE.
24
25 @license
26 */
27 var Handlebars = (function() {
28 // handlebars/safe-string.js
29 var __module4__ = (function() {
30 "use strict";
31 var __exports__;
32 // Build out our basic SafeString type
33 function SafeString(string) {
34 this.string = string;
35 }
36
37 SafeString.prototype.toString = function() {
38 return "" + this.string;
39 };
40
41 __exports__ = SafeString;
42 return __exports__;
43 })();
44
45 // handlebars/utils.js
46 var __module3__ = (function(__dependency1__) {
47 "use strict";
48 var __exports__ = {};
49 var SafeString = __dependency1__;
50
51 var escape = {
52 "&": "&",
53 "<": "&lt;",
54 ">": "&gt;",
55 '"': "&quot;",
56 "'": "&#x27;",
57 "`": "&#x60;"
58 };
59
60 var badChars = /[&<>"'`]/g;
61 var possible = /[&<>"'`]/;
62
63 function escapeChar(chr) {
64 return escape[chr] || "&amp;";
65 }
66
67 function extend(obj, value) {
68 for(var key in value) {
69 if(value.hasOwnProperty(key)) {
70 obj[key] = value[key];
71 }
72 }
73 }
74
75 __exports__.extend = extend;var toString = Object.prototype.toString;
76 __exports__.toString = toString;
77 // Sourced from lodash
78 // https://github.com/bestiejs/lodash/blob/master/LICENSE.txt
79 var isFunction = function(value) {
80 return typeof value === 'function';
81 };
82 // fallback for older versions of Chrome and Safari
83 if (isFunction(/x/)) {
84 isFunction = function(value) {
85 return typeof value === 'function' && toString.call(value) === '[object Function]';
86 };
87 }
88 var isFunction;
89 __exports__.isFunction = isFunction;
90 var isArray = Array.isArray || function(value) {
91 return (value && typeof value === 'object') ? toString.call(value) === '[object Array]' : false;
92 };
93 __exports__.isArray = isArray;
94
95 function escapeExpression(string) {
96 // don't escape SafeStrings, since they're already safe
97 if (string instanceof SafeString) {
98 return string.toString();
99 } else if (!string && string !== 0) {
100 return "";
101 }
102
103 // Force a string conversion as this will be done by the append regardless and
104 // the regex test will do this transparently behind the scenes, causing issues if
105 // an object's to string has escaped characters in it.
106 string = "" + string;
107
108 if(!possible.test(string)) { return string; }
109 return string.replace(badChars, escapeChar);
110 }
111
112 __exports__.escapeExpression = escapeExpression;function isEmpty(value) {
113 if (!value && value !== 0) {
114 return true;
115 } else if (isArray(value) && value.length === 0) {
116 return true;
117 } else {
118 return false;
119 }
120 }
121
122 __exports__.isEmpty = isEmpty;
123 return __exports__;
124 })(__module4__);
125
126 // handlebars/exception.js
127 var __module5__ = (function() {
128 "use strict";
129 var __exports__;
130
131 var errorProps = ['description', 'fileName', 'lineNumber', 'message', 'name', 'number', 'stack'];
132
133 function Exception(/* message */) {
134 var tmp = Error.prototype.constructor.apply(this, arguments);
135
136 // Unfortunately errors are not enumerable in Chrome (at least), so `for prop in tmp` doesn't work.
137 for (var idx = 0; idx < errorProps.length; idx++) {
138 this[errorProps[idx]] = tmp[errorProps[idx]];
139 }
140 }
141
142 Exception.prototype = new Error();
143
144 __exports__ = Exception;
145 return __exports__;
146 })();
147
148 // handlebars/base.js
149 var __module2__ = (function(__dependency1__, __dependency2__) {
150 "use strict";
151 var __exports__ = {};
152 /*globals Exception, Utils */
153 var Utils = __dependency1__;
154 var Exception = __dependency2__;
155
156 var VERSION = "1.1.2";
157 __exports__.VERSION = VERSION;var COMPILER_REVISION = 4;
158 __exports__.COMPILER_REVISION = COMPILER_REVISION;
159 var REVISION_CHANGES = {
160 1: '<= 1.0.rc.2', // 1.0.rc.2 is actually rev2 but doesn't report it
161 2: '== 1.0.0-rc.3',
162 3: '== 1.0.0-rc.4',
163 4: '>= 1.0.0'
164 };
165 __exports__.REVISION_CHANGES = REVISION_CHANGES;
166 var isArray = Utils.isArray,
167 isFunction = Utils.isFunction,
168 toString = Utils.toString,
169 objectType = '[object Object]';
170
171 function HandlebarsEnvironment(helpers, partials) {
172 this.helpers = helpers || {};
173 this.partials = partials || {};
174
175 registerDefaultHelpers(this);
176 }
177
178 __exports__.HandlebarsEnvironment = HandlebarsEnvironment;HandlebarsEnvironment.prototype = {
179 constructor: HandlebarsEnvironment,
180
181 logger: logger,
182 log: log,
183
184 registerHelper: function(name, fn, inverse) {
185 if (toString.call(name) === objectType) {
186 if (inverse || fn) { throw new Exception('Arg not supported with multiple helpers'); }
187 Utils.extend(this.helpers, name);
188 } else {
189 if (inverse) { fn.not = inverse; }
190 this.helpers[name] = fn;
191 }
192 },
193
194 registerPartial: function(name, str) {
195 if (toString.call(name) === objectType) {
196 Utils.extend(this.partials, name);
197 } else {
198 this.partials[name] = str;
199 }
200 }
201 };
202
203 function registerDefaultHelpers(instance) {
204 instance.registerHelper('helperMissing', function(arg) {
205 if(arguments.length === 2) {
206 return undefined;
207 } else {
208 throw new Error("Missing helper: '" + arg + "'");
209 }
210 });
211
212 instance.registerHelper('blockHelperMissing', function(context, options) {
213 var inverse = options.inverse || function() {}, fn = options.fn;
214
215 if (isFunction(context)) { context = context.call(this); }
216
217 if(context === true) {
218 return fn(this);
219 } else if(context === false || context == null) {
220 return inverse(this);
221 } else if (isArray(context)) {
222 if(context.length > 0) {
223 return instance.helpers.each(context, options);
224 } else {
225 return inverse(this);
226 }
227 } else {
228 return fn(context);
229 }
230 });
231
232 instance.registerHelper('each', function(context, options) {
233 var fn = options.fn, inverse = options.inverse;
234 var i = 0, ret = "", data;
235
236 if (isFunction(context)) { context = context.call(this); }
237
238 if (options.data) {
239 data = createFrame(options.data);
240 }
241
242 if(context && typeof context === 'object') {
243 if (isArray(context)) {
244 for(var j = context.length; i<j; i++) {
245 if (data) {
246 data.index = i;
247 data.first = (i === 0)
248 data.last = (i === (context.length-1));
249 }
250 ret = ret + fn(context[i], { data: data });
251 }
252 } else {
253 for(var key in context) {
254 if(context.hasOwnProperty(key)) {
255 if(data) { data.key = key; }
256 ret = ret + fn(context[key], {data: data});
257 i++;
258 }
259 }
260 }
261 }
262
263 if(i === 0){
264 ret = inverse(this);
265 }
266
267 return ret;
268 });
269
270 instance.registerHelper('if', function(conditional, options) {
271 if (isFunction(conditional)) { conditional = conditional.call(this); }
272
273 // Default behavior is to render the positive path if the value is truthy and not empty.
274 // The `includeZero` option may be set to treat the condtional as purely not empty based on the
275 // behavior of isEmpty. Effectively this determines if 0 is handled by the positive path or negative.
276 if ((!options.hash.includeZero && !conditional) || Utils.isEmpty(conditional)) {
277 return options.inverse(this);
278 } else {
279 return options.fn(this);
280 }
281 });
282
283 instance.registerHelper('unless', function(conditional, options) {
284 return instance.helpers['if'].call(this, conditional, {fn: options.inverse, inverse: options.fn, hash: options.hash});
285 });
286
287 instance.registerHelper('with', function(context, options) {
288 if (isFunction(context)) { context = context.call(this); }
289
290 if (!Utils.isEmpty(context)) return options.fn(context);
291 });
292
293 instance.registerHelper('log', function(context, options) {
294 var level = options.data && options.data.level != null ? parseInt(options.data.level, 10) : 1;
295 instance.log(level, context);
296 });
297 }
298
299 var logger = {
300 methodMap: { 0: 'debug', 1: 'info', 2: 'warn', 3: 'error' },
301
302 // State enum
303 DEBUG: 0,
304 INFO: 1,
305 WARN: 2,
306 ERROR: 3,
307 level: 3,
308
309 // can be overridden in the host environment
310 log: function(level, obj) {
311 if (logger.level <= level) {
312 var method = logger.methodMap[level];
313 if (typeof console !== 'undefined' && console[method]) {
314 console[method].call(console, obj);
315 }
316 }
317 }
318 };
319 __exports__.logger = logger;
320 function log(level, obj) { logger.log(level, obj); }
321
322 __exports__.log = log;var createFrame = function(object) {
323 var obj = {};
324 Utils.extend(obj, object);
325 return obj;
326 };
327 __exports__.createFrame = createFrame;
328 return __exports__;
329 })(__module3__, __module5__);
330
331 // handlebars/runtime.js
332 var __module6__ = (function(__dependency1__, __dependency2__, __dependency3__) {
333 "use strict";
334 var __exports__ = {};
335 /*global Utils */
336 var Utils = __dependency1__;
337 var Exception = __dependency2__;
338 var COMPILER_REVISION = __dependency3__.COMPILER_REVISION;
339 var REVISION_CHANGES = __dependency3__.REVISION_CHANGES;
340
341 function checkRevision(compilerInfo) {
342 var compilerRevision = compilerInfo && compilerInfo[0] || 1,
343 currentRevision = COMPILER_REVISION;
344
345 if (compilerRevision !== currentRevision) {
346 if (compilerRevision < currentRevision) {
347 var runtimeVersions = REVISION_CHANGES[currentRevision],
348 compilerVersions = REVISION_CHANGES[compilerRevision];
349 throw new Error("Template was precompiled with an older version of Handlebars than the current runtime. "+
350 "Please update your precompiler to a newer version ("+runtimeVersions+") or downgrade your runtime to an older version ("+compilerVersions+").");
351 } else {
352 // Use the embedded version info since the runtime doesn't know about this revision yet
353 throw new Error("Template was precompiled with a newer version of Handlebars than the current runtime. "+
354 "Please update your runtime to a newer version ("+compilerInfo[1]+").");
355 }
356 }
357 }
358
359 // TODO: Remove this line and break up compilePartial
360
361 function template(templateSpec, env) {
362 if (!env) {
363 throw new Error("No environment passed to template");
364 }
365
366 var invokePartialWrapper;
367 if (env.compile) {
368 invokePartialWrapper = function(partial, name, context, helpers, partials, data) {
369 // TODO : Check this for all inputs and the options handling (partial flag, etc). This feels
370 // like there should be a common exec path
371 var result = invokePartial.apply(this, arguments);
372 if (result) { return result; }
373
374 var options = { helpers: helpers, partials: partials, data: data };
375 partials[name] = env.compile(partial, { data: data !== undefined }, env);
376 return partials[name](context, options);
377 };
378 } else {
379 invokePartialWrapper = function(partial, name /* , context, helpers, partials, data */) {
380 var result = invokePartial.apply(this, arguments);
381 if (result) { return result; }
382 throw new Exception("The partial " + name + " could not be compiled when running in runtime-only mode");
383 };
384 }
385
386 // Just add water
387 var container = {
388 escapeExpression: Utils.escapeExpression,
389 invokePartial: invokePartialWrapper,
390 programs: [],
391 program: function(i, fn, data) {
392 var programWrapper = this.programs[i];
393 if(data) {
394 programWrapper = program(i, fn, data);
395 } else if (!programWrapper) {
396 programWrapper = this.programs[i] = program(i, fn);
397 }
398 return programWrapper;
399 },
400 merge: function(param, common) {
401 var ret = param || common;
402
403 if (param && common && (param !== common)) {
404 ret = {};
405 Utils.extend(ret, common);
406 Utils.extend(ret, param);
407 }
408 return ret;
409 },
410 programWithDepth: programWithDepth,
411 noop: noop,
412 compilerInfo: null
413 };
414
415 return function(context, options) {
416 options = options || {};
417 var namespace = options.partial ? options : env,
418 helpers,
419 partials;
420
421 if (!options.partial) {
422 helpers = options.helpers;
423 partials = options.partials;
424 }
425 var result = templateSpec.call(
426 container,
427 namespace, context,
428 helpers,
429 partials,
430 options.data);
431
432 if (!options.partial) {
433 checkRevision(container.compilerInfo);
434 }
435
436 return result;
437 };
438 }
439
440 __exports__.template = template;function programWithDepth(i, fn, data /*, $depth */) {
441 var args = Array.prototype.slice.call(arguments, 3);
442
443 var prog = function(context, options) {
444 options = options || {};
445
446 return fn.apply(this, [context, options.data || data].concat(args));
447 };
448 prog.program = i;
449 prog.depth = args.length;
450 return prog;
451 }
452
453 __exports__.programWithDepth = programWithDepth;function program(i, fn, data) {
454 var prog = function(context, options) {
455 options = options || {};
456
457 return fn(context, options.data || data);
458 };
459 prog.program = i;
460 prog.depth = 0;
461 return prog;
462 }
463
464 __exports__.program = program;function invokePartial(partial, name, context, helpers, partials, data) {
465 var options = { partial: true, helpers: helpers, partials: partials, data: data };
466
467 if(partial === undefined) {
468 throw new Exception("The partial " + name + " could not be found");
469 } else if(partial instanceof Function) {
470 return partial(context, options);
471 }
472 }
473
474 __exports__.invokePartial = invokePartial;function noop() { return ""; }
475
476 __exports__.noop = noop;
477 return __exports__;
478 })(__module3__, __module5__, __module2__);
479
480 // handlebars.runtime.js
481 var __module1__ = (function(__dependency1__, __dependency2__, __dependency3__, __dependency4__, __dependency5__) {
482 "use strict";
483 var __exports__;
484 var base = __dependency1__;
485
486 // Each of these augment the Handlebars object. No need to setup here.
487 // (This is done to easily share code between commonjs and browse envs)
488 var SafeString = __dependency2__;
489 var Exception = __dependency3__;
490 var Utils = __dependency4__;
491 var runtime = __dependency5__;
492
493 // For compatibility and usage outside of module systems, make the Handlebars object a namespace
494 var create = function() {
495 var hb = new base.HandlebarsEnvironment();
496
497 Utils.extend(hb, base);
498 hb.SafeString = SafeString;
499 hb.Exception = Exception;
500 hb.Utils = Utils;
501
502 hb.VM = runtime;
503 hb.template = function(spec) {
504 return runtime.template(spec, hb);
505 };
506
507 return hb;
508 };
509
510 var Handlebars = create();
511 Handlebars.create = create;
512
513 __exports__ = Handlebars;
514 return __exports__;
515 })(__module2__, __module4__, __module5__, __module3__, __module6__);
516
517 // handlebars/compiler/ast.js
518 var __module7__ = (function(__dependency1__) {
519 "use strict";
520 var __exports__ = {};
521 var Exception = __dependency1__;
522
523 function ProgramNode(statements, inverseStrip, inverse) {
524 this.type = "program";
525 this.statements = statements;
526 this.strip = {};
527
528 if(inverse) {
529 this.inverse = new ProgramNode(inverse, inverseStrip);
530 this.strip.right = inverseStrip.left;
531 } else if (inverseStrip) {
532 this.strip.left = inverseStrip.right;
533 }
534 }
535
536 __exports__.ProgramNode = ProgramNode;function MustacheNode(rawParams, hash, open, strip) {
537 this.type = "mustache";
538 this.hash = hash;
539 this.strip = strip;
540
541 var escapeFlag = open[3] || open[2];
542 this.escaped = escapeFlag !== '{' && escapeFlag !== '&';
543
544 var id = this.id = rawParams[0];
545 var params = this.params = rawParams.slice(1);
546
547 // a mustache is an eligible helper if:
548 // * its id is simple (a single part, not `this` or `..`)
549 var eligibleHelper = this.eligibleHelper = id.isSimple;
550
551 // a mustache is definitely a helper if:
552 // * it is an eligible helper, and
553 // * it has at least one parameter or hash segment
554 this.isHelper = eligibleHelper && (params.length || hash);
555
556 // if a mustache is an eligible helper but not a definite
557 // helper, it is ambiguous, and will be resolved in a later
558 // pass or at runtime.
559 }
560
561 __exports__.MustacheNode = MustacheNode;function PartialNode(partialName, context, strip) {
562 this.type = "partial";
563 this.partialName = partialName;
564 this.context = context;
565 this.strip = strip;
566 }
567
568 __exports__.PartialNode = PartialNode;function BlockNode(mustache, program, inverse, close) {
569 if(mustache.id.original !== close.path.original) {
570 throw new Exception(mustache.id.original + " doesn't match " + close.path.original);
571 }
572
573 this.type = "block";
574 this.mustache = mustache;
575 this.program = program;
576 this.inverse = inverse;
577
578 this.strip = {
579 left: mustache.strip.left,
580 right: close.strip.right
581 };
582
583 (program || inverse).strip.left = mustache.strip.right;
584 (inverse || program).strip.right = close.strip.left;
585
586 if (inverse && !program) {
587 this.isInverse = true;
588 }
589 }
590
591 __exports__.BlockNode = BlockNode;function ContentNode(string) {
592 this.type = "content";
593 this.string = string;
594 }
595
596 __exports__.ContentNode = ContentNode;function HashNode(pairs) {
597 this.type = "hash";
598 this.pairs = pairs;
599 }
600
601 __exports__.HashNode = HashNode;function IdNode(parts) {
602 this.type = "ID";
603
604 var original = "",
605 dig = [],
606 depth = 0;
607
608 for(var i=0,l=parts.length; i<l; i++) {
609 var part = parts[i].part;
610 original += (parts[i].separator || '') + part;
611
612 if (part === ".." || part === "." || part === "this") {
613 if (dig.length > 0) { throw new Exception("Invalid path: " + original); }
614 else if (part === "..") { depth++; }
615 else { this.isScoped = true; }
616 }
617 else { dig.push(part); }
618 }
619
620 this.original = original;
621 this.parts = dig;
622 this.string = dig.join('.');
623 this.depth = depth;
624
625 // an ID is simple if it only has one part, and that part is not
626 // `..` or `this`.
627 this.isSimple = parts.length === 1 && !this.isScoped && depth === 0;
628
629 this.stringModeValue = this.string;
630 }
631
632 __exports__.IdNode = IdNode;function PartialNameNode(name) {
633 this.type = "PARTIAL_NAME";
634 this.name = name.original;
635 }
636
637 __exports__.PartialNameNode = PartialNameNode;function DataNode(id) {
638 this.type = "DATA";
639 this.id = id;
640 }
641
642 __exports__.DataNode = DataNode;function StringNode(string) {
643 this.type = "STRING";
644 this.original =
645 this.string =
646 this.stringModeValue = string;
647 }
648
649 __exports__.StringNode = StringNode;function IntegerNode(integer) {
650 this.type = "INTEGER";
651 this.original =
652 this.integer = integer;
653 this.stringModeValue = Number(integer);
654 }
655
656 __exports__.IntegerNode = IntegerNode;function BooleanNode(bool) {
657 this.type = "BOOLEAN";
658 this.bool = bool;
659 this.stringModeValue = bool === "true";
660 }
661
662 __exports__.BooleanNode = BooleanNode;function CommentNode(comment) {
663 this.type = "comment";
664 this.comment = comment;
665 }
666
667 __exports__.CommentNode = CommentNode;
668 return __exports__;
669 })(__module5__);
670
671 // handlebars/compiler/parser.js
672 var __module9__ = (function() {
673 "use strict";
674 var __exports__;
675 /* Jison generated parser */
676 var handlebars = (function(){
677 var parser = {trace: function trace() { },
678 yy: {},
679 symbols_: {"error":2,"root":3,"statements":4,"EOF":5,"program":6,"simpleInverse":7,"statement":8,"openInverse":9,"closeBlock":10,"openBlock":11,"mustache":12,"partial":13,"CONTENT":14,"COMMENT":15,"OPEN_BLOCK":16,"inMustache":17,"CLOSE":18,"OPEN_INVERSE":19,"OPEN_ENDBLOCK":20,"path":21,"OPEN":22,"OPEN_UNESCAPED":23,"CLOSE_UNESCAPED":24,"OPEN_PARTIAL":25,"partialName":26,"partial_option0":27,"inMustache_repetition0":28,"inMustache_option0":29,"dataName":30,"param":31,"STRING":32,"INTEGER":33,"BOOLEAN":34,"hash":35,"hash_repetition_plus0":36,"hashSegment":37,"ID":38,"EQUALS":39,"DATA":40,"pathSegments":41,"SEP":42,"$accept":0,"$end":1},
680 terminals_: {2:"error",5:"EOF",14:"CONTENT",15:"COMMENT",16:"OPEN_BLOCK",18:"CLOSE",19:"OPEN_INVERSE",20:"OPEN_ENDBLOCK",22:"OPEN",23:"OPEN_UNESCAPED",24:"CLOSE_UNESCAPED",25:"OPEN_PARTIAL",32:"STRING",33:"INTEGER",34:"BOOLEAN",38:"ID",39:"EQUALS",40:"DATA",42:"SEP"},
681 productions_: [0,[3,2],[3,1],[6,2],[6,3],[6,2],[6,1],[6,1],[6,0],[4,1],[4,2],[8,3],[8,3],[8,1],[8,1],[8,1],[8,1],[11,3],[9,3],[10,3],[12,3],[12,3],[13,4],[7,2],[17,3],[17,1],[31,1],[31,1],[31,1],[31,1],[31,1],[35,1],[37,3],[26,1],[26,1],[26,1],[30,2],[21,1],[41,3],[41,1],[27,0],[27,1],[28,0],[28,2],[29,0],[29,1],[36,1],[36,2]],
682 performAction: function anonymous(yytext,yyleng,yylineno,yy,yystate,$$,_$) {
683
684 var $0 = $$.length - 1;
685 switch (yystate) {
686 case 1: return new yy.ProgramNode($$[$0-1]);
687 break;
688 case 2: return new yy.ProgramNode([]);
689 break;
690 case 3:this.$ = new yy.ProgramNode([], $$[$0-1], $$[$0]);
691 break;
692 case 4:this.$ = new yy.ProgramNode($$[$0-2], $$[$0-1], $$[$0]);
693 break;
694 case 5:this.$ = new yy.ProgramNode($$[$0-1], $$[$0], []);
695 break;
696 case 6:this.$ = new yy.ProgramNode($$[$0]);
697 break;
698 case 7:this.$ = new yy.ProgramNode([]);
699 break;
700 case 8:this.$ = new yy.ProgramNode([]);
701 break;
702 case 9:this.$ = [$$[$0]];
703 break;
704 case 10: $$[$0-1].push($$[$0]); this.$ = $$[$0-1];
705 break;
706 case 11:this.$ = new yy.BlockNode($$[$0-2], $$[$0-1].inverse, $$[$0-1], $$[$0]);
707 break;
708 case 12:this.$ = new yy.BlockNode($$[$0-2], $$[$0-1], $$[$0-1].inverse, $$[$0]);
709 break;
710 case 13:this.$ = $$[$0];
711 break;
712 case 14:this.$ = $$[$0];
713 break;
714 case 15:this.$ = new yy.ContentNode($$[$0]);
715 break;
716 case 16:this.$ = new yy.CommentNode($$[$0]);
717 break;
718 case 17:this.$ = new yy.MustacheNode($$[$0-1][0], $$[$0-1][1], $$[$0-2], stripFlags($$[$0-2], $$[$0]));
719 break;
720 case 18:this.$ = new yy.MustacheNode($$[$0-1][0], $$[$0-1][1], $$[$0-2], stripFlags($$[$0-2], $$[$0]));
721 break;
722 case 19:this.$ = {path: $$[$0-1], strip: stripFlags($$[$0-2], $$[$0])};
723 break;
724 case 20:this.$ = new yy.MustacheNode($$[$0-1][0], $$[$0-1][1], $$[$0-2], stripFlags($$[$0-2], $$[$0]));
725 break;
726 case 21:this.$ = new yy.MustacheNode($$[$0-1][0], $$[$0-1][1], $$[$0-2], stripFlags($$[$0-2], $$[$0]));
727 break;
728 case 22:this.$ = new yy.PartialNode($$[$0-2], $$[$0-1], stripFlags($$[$0-3], $$[$0]));
729 break;
730 case 23:this.$ = stripFlags($$[$0-1], $$[$0]);
731 break;
732 case 24:this.$ = [[$$[$0-2]].concat($$[$0-1]), $$[$0]];
733 break;
734 case 25:this.$ = [[$$[$0]], null];
735 break;
736 case 26:this.$ = $$[$0];
737 break;
738 case 27:this.$ = new yy.StringNode($$[$0]);
739 break;
740 case 28:this.$ = new yy.IntegerNode($$[$0]);
741 break;
742 case 29:this.$ = new yy.BooleanNode($$[$0]);
743 break;
744 case 30:this.$ = $$[$0];
745 break;
746 case 31:this.$ = new yy.HashNode($$[$0]);
747 break;
748 case 32:this.$ = [$$[$0-2], $$[$0]];
749 break;
750 case 33:this.$ = new yy.PartialNameNode($$[$0]);
751 break;
752 case 34:this.$ = new yy.PartialNameNode(new yy.StringNode($$[$0]));
753 break;
754 case 35:this.$ = new yy.PartialNameNode(new yy.IntegerNode($$[$0]));
755 break;
756 case 36:this.$ = new yy.DataNode($$[$0]);
757 break;
758 case 37:this.$ = new yy.IdNode($$[$0]);
759 break;
760 case 38: $$[$0-2].push({part: $$[$0], separator: $$[$0-1]}); this.$ = $$[$0-2];
761 break;
762 case 39:this.$ = [{part: $$[$0]}];
763 break;
764 case 42:this.$ = [];
765 break;
766 case 43:$$[$0-1].push($$[$0]);
767 break;
768 case 46:this.$ = [$$[$0]];
769 break;
770 case 47:$$[$0-1].push($$[$0]);
771 break;
772 }
773 },
774 table: [{3:1,4:2,5:[1,3],8:4,9:5,11:6,12:7,13:8,14:[1,9],15:[1,10],16:[1,12],19:[1,11],22:[1,13],23:[1,14],25:[1,15]},{1:[3]},{5:[1,16],8:17,9:5,11:6,12:7,13:8,14:[1,9],15:[1,10],16:[1,12],19:[1,11],22:[1,13],23:[1,14],25:[1,15]},{1:[2,2]},{5:[2,9],14:[2,9],15:[2,9],16:[2,9],19:[2,9],20:[2,9],22:[2,9],23:[2,9],25:[2,9]},{4:20,6:18,7:19,8:4,9:5,11:6,12:7,13:8,14:[1,9],15:[1,10],16:[1,12],19:[1,21],20:[2,8],22:[1,13],23:[1,14],25:[1,15]},{4:20,6:22,7:19,8:4,9:5,11:6,12:7,13:8,14:[1,9],15:[1,10],16:[1,12],19:[1,21],20:[2,8],22:[1,13],23:[1,14],25:[1,15]},{5:[2,13],14:[2,13],15:[2,13],16:[2,13],19:[2,13],20:[2,13],22:[2,13],23:[2,13],25:[2,13]},{5:[2,14],14:[2,14],15:[2,14],16:[2,14],19:[2,14],20:[2,14],22:[2,14],23:[2,14],25:[2,14]},{5:[2,15],14:[2,15],15:[2,15],16:[2,15],19:[2,15],20:[2,15],22:[2,15],23:[2,15],25:[2,15]},{5:[2,16],14:[2,16],15:[2,16],16:[2,16],19:[2,16],20:[2,16],22:[2,16],23:[2,16],25:[2,16]},{17:23,21:24,30:25,38:[1,28],40:[1,27],41:26},{17:29,21:24,30:25,38:[1,28],40:[1,27],41:26},{17:30,21:24,30:25,38:[1,28],40:[1,27],41:26},{17:31,21:24,30:25,38:[1,28],40:[1,27],41:26},{21:33,26:32,32:[1,34],33:[1,35],38:[1,28],41:26},{1:[2,1]},{5:[2,10],14:[2,10],15:[2,10],16:[2,10],19:[2,10],20:[2,10],22:[2,10],23:[2,10],25:[2,10]},{10:36,20:[1,37]},{4:38,8:4,9:5,11:6,12:7,13:8,14:[1,9],15:[1,10],16:[1,12],19:[1,11],20:[2,7],22:[1,13],23:[1,14],25:[1,15]},{7:39,8:17,9:5,11:6,12:7,13:8,14:[1,9],15:[1,10],16:[1,12],19:[1,21],20:[2,6],22:[1,13],23:[1,14],25:[1,15]},{17:23,18:[1,40],21:24,30:25,38:[1,28],40:[1,27],41:26},{10:41,20:[1,37]},{18:[1,42]},{18:[2,42],24:[2,42],28:43,32:[2,42],33:[2,42],34:[2,42],38:[2,42],40:[2,42]},{18:[2,25],24:[2,25]},{18:[2,37],24:[2,37],32:[2,37],33:[2,37],34:[2,37],38:[2,37],40:[2,37],42:[1,44]},{21:45,38:[1,28],41:26},{18:[2,39],24:[2,39],32:[2,39],33:[2,39],34:[2,39],38:[2,39],40:[2,39],42:[2,39]},{18:[1,46]},{18:[1,47]},{24:[1,48]},{18:[2,40],21:50,27:49,38:[1,28],41:26},{18:[2,33],38:[2,33]},{18:[2,34],38:[2,34]},{18:[2,35],38:[2,35]},{5:[2,11],14:[2,11],15:[2,11],16:[2,11],19:[2,11],20:[2,11],22:[2,11],23:[2,11],25:[2,11]},{21:51,38:[1,28],41:26},{8:17,9:5,11:6,12:7,13:8,14:[1,9],15:[1,10],16:[1,12],19:[1,11],20:[2,3],22:[1,13],23:[1,14],25:[1,15]},{4:52,8:4,9:5,11:6,12:7,13:8,14:[1,9],15:[1,10],16:[1,12],19:[1,11],20:[2,5],22:[1,13],23:[1,14],25:[1,15]},{14:[2,23],15:[2,23],16:[2,23],19:[2,23],20:[2,23],22:[2,23],23:[2,23],25:[2,23]},{5:[2,12],14:[2,12],15:[2,12],16:[2,12],19:[2,12],20:[2,12],22:[2,12],23:[2,12],25:[2,12]},{14:[2,18],15:[2,18],16:[2,18],19:[2,18],20:[2,18],22:[2,18],23:[2,18],25:[2,18]},{18:[2,44],21:56,24:[2,44],29:53,30:60,31:54,32:[1,57],33:[1,58],34:[1,59],35:55,36:61,37:62,38:[1,63],40:[1,27],41:26},{38:[1,64]},{18:[2,36],24:[2,36],32:[2,36],33:[2,36],34:[2,36],38:[2,36],40:[2,36]},{14:[2,17],15:[2,17],16:[2,17],19:[2,17],20:[2,17],22:[2,17],23:[2,17],25:[2,17]},{5:[2,20],14:[2,20],15:[2,20],16:[2,20],19:[2,20],20:[2,20],22:[2,20],23:[2,20],25:[2,20]},{5:[2,21],14:[2,21],15:[2,21],16:[2,21],19:[2,21],20:[2,21],22:[2,21],23:[2,21],25:[2,21]},{18:[1,65]},{18:[2,41]},{18:[1,66]},{8:17,9:5,11:6,12:7,13:8,14:[1,9],15:[1,10],16:[1,12],19:[1,11],20:[2,4],22:[1,13],23:[1,14],25:[1,15]},{18:[2,24],24:[2,24]},{18:[2,43],24:[2,43],32:[2,43],33:[2,43],34:[2,43],38:[2,43],40:[2,43]},{18:[2,45],24:[2,45]},{18:[2,26],24:[2,26],32:[2,26],33:[2,26],34:[2,26],38:[2,26],40:[2,26]},{18:[2,27],24:[2,27],32:[2,27],33:[2,27],34:[2,27],38:[2,27],40:[2,27]},{18:[2,28],24:[2,28],32:[2,28],33:[2,28],34:[2,28],38:[2,28],40:[2,28]},{18:[2,29],24:[2,29],32:[2,29],33:[2,29],34:[2,29],38:[2,29],40:[2,29]},{18:[2,30],24:[2,30],32:[2,30],33:[2,30],34:[2,30],38:[2,30],40:[2,30]},{18:[2,31],24:[2,31],37:67,38:[1,68]},{18:[2,46],24:[2,46],38:[2,46]},{18:[2,39],24:[2,39],32:[2,39],33:[2,39],34:[2,39],38:[2,39],39:[1,69],40:[2,39],42:[2,39]},{18:[2,38],24:[2,38],32:[2,38],33:[2,38],34:[2,38],38:[2,38],40:[2,38],42:[2,38]},{5:[2,22],14:[2,22],15:[2,22],16:[2,22],19:[2,22],20:[2,22],22:[2,22],23:[2,22],25:[2,22]},{5:[2,19],14:[2,19],15:[2,19],16:[2,19],19:[2,19],20:[2,19],22:[2,19],23:[2,19],25:[2,19]},{18:[2,47],24:[2,47],38:[2,47]},{39:[1,69]},{21:56,30:60,31:70,32:[1,57],33:[1,58],34:[1,59],38:[1,28],40:[1,27],41:26},{18:[2,32],24:[2,32],38:[2,32]}],
775 defaultActions: {3:[2,2],16:[2,1],50:[2,41]},
776 parseError: function parseError(str, hash) {
777 throw new Error(str);
778 },
779 parse: function parse(input) {
780 var self = this, stack = [0], vstack = [null], lstack = [], table = this.table, yytext = "", yylineno = 0, yyleng = 0, recovering = 0, TERROR = 2, EOF = 1;
781 this.lexer.setInput(input);
782 this.lexer.yy = this.yy;
783 this.yy.lexer = this.lexer;
784 this.yy.parser = this;
785 if (typeof this.lexer.yylloc == "undefined")
786 this.lexer.yylloc = {};
787 var yyloc = this.lexer.yylloc;
788 lstack.push(yyloc);
789 var ranges = this.lexer.options && this.lexer.options.ranges;
790 if (typeof this.yy.parseError === "function")
791 this.parseError = this.yy.parseError;
792 function popStack(n) {
793 stack.length = stack.length - 2 * n;
794 vstack.length = vstack.length - n;
795 lstack.length = lstack.length - n;
796 }
797 function lex() {
798 var token;
799 token = self.lexer.lex() || 1;
800 if (typeof token !== "number") {
801 token = self.symbols_[token] || token;
802 }
803 return token;
804 }
805 var symbol, preErrorSymbol, state, action, a, r, yyval = {}, p, len, newState, expected;
806 while (true) {
807 state = stack[stack.length - 1];
808 if (this.defaultActions[state]) {
809 action = this.defaultActions[state];
810 } else {
811 if (symbol === null || typeof symbol == "undefined") {
812 symbol = lex();
813 }
814 action = table[state] && table[state][symbol];
815 }
816 if (typeof action === "undefined" || !action.length || !action[0]) {
817 var errStr = "";
818 if (!recovering) {
819 expected = [];
820 for (p in table[state])
821 if (this.terminals_[p] && p > 2) {
822 expected.push("'" + this.terminals_[p] + "'");
823 }
824 if (this.lexer.showPosition) {
825 errStr = "Parse error on line " + (yylineno + 1) + ":\n" + this.lexer.showPosition() + "\nExpecting " + expected.join(", ") + ", got '" + (this.terminals_[symbol] || symbol) + "'";
826 } else {
827 errStr = "Parse error on line " + (yylineno + 1) + ": Unexpected " + (symbol == 1?"end of input":"'" + (this.terminals_[symbol] || symbol) + "'");
828 }
829 this.parseError(errStr, {text: this.lexer.match, token: this.terminals_[symbol] || symbol, line: this.lexer.yylineno, loc: yyloc, expected: expected});
830 }
831 }
832 if (action[0] instanceof Array && action.length > 1) {
833 throw new Error("Parse Error: multiple actions possible at state: " + state + ", token: " + symbol);
834 }
835 switch (action[0]) {
836 case 1:
837 stack.push(symbol);
838 vstack.push(this.lexer.yytext);
839 lstack.push(this.lexer.yylloc);
840 stack.push(action[1]);
841 symbol = null;
842 if (!preErrorSymbol) {
843 yyleng = this.lexer.yyleng;
844 yytext = this.lexer.yytext;
845 yylineno = this.lexer.yylineno;
846 yyloc = this.lexer.yylloc;
847 if (recovering > 0)
848 recovering--;
849 } else {
850 symbol = preErrorSymbol;
851 preErrorSymbol = null;
852 }
853 break;
854 case 2:
855 len = this.productions_[action[1]][1];
856 yyval.$ = vstack[vstack.length - len];
857 yyval._$ = {first_line: lstack[lstack.length - (len || 1)].first_line, last_line: lstack[lstack.length - 1].last_line, first_column: lstack[lstack.length - (len || 1)].first_column, last_column: lstack[lstack.length - 1].last_column};
858 if (ranges) {
859 yyval._$.range = [lstack[lstack.length - (len || 1)].range[0], lstack[lstack.length - 1].range[1]];
860 }
861 r = this.performAction.call(yyval, yytext, yyleng, yylineno, this.yy, action[1], vstack, lstack);
862 if (typeof r !== "undefined") {
863 return r;
864 }
865 if (len) {
866 stack = stack.slice(0, -1 * len * 2);
867 vstack = vstack.slice(0, -1 * len);
868 lstack = lstack.slice(0, -1 * len);
869 }
870 stack.push(this.productions_[action[1]][0]);
871 vstack.push(yyval.$);
872 lstack.push(yyval._$);
873 newState = table[stack[stack.length - 2]][stack[stack.length - 1]];
874 stack.push(newState);
875 break;
876 case 3:
877 return true;
878 }
879 }
880 return true;
881 }
882 };
883
884
885 function stripFlags(open, close) {
886 return {
887 left: open[2] === '~',
888 right: close[0] === '~' || close[1] === '~'
889 };
890 }
891
892 /* Jison generated lexer */
893 var lexer = (function(){
894 var lexer = ({EOF:1,
895 parseError:function parseError(str, hash) {
896 if (this.yy.parser) {
897 this.yy.parser.parseError(str, hash);
898 } else {
899 throw new Error(str);
900 }
901 },
902 setInput:function (input) {
903 this._input = input;
904 this._more = this._less = this.done = false;
905 this.yylineno = this.yyleng = 0;
906 this.yytext = this.matched = this.match = '';
907 this.conditionStack = ['INITIAL'];
908 this.yylloc = {first_line:1,first_column:0,last_line:1,last_column:0};
909 if (this.options.ranges) this.yylloc.range = [0,0];
910 this.offset = 0;
911 return this;
912 },
913 input:function () {
914 var ch = this._input[0];
915 this.yytext += ch;
916 this.yyleng++;
917 this.offset++;
918 this.match += ch;
919 this.matched += ch;
920 var lines = ch.match(/(?:\r\n?|\n).*/g);
921 if (lines) {
922 this.yylineno++;
923 this.yylloc.last_line++;
924 } else {
925 this.yylloc.last_column++;
926 }
927 if (this.options.ranges) this.yylloc.range[1]++;
928
929 this._input = this._input.slice(1);
930 return ch;
931 },
932 unput:function (ch) {
933 var len = ch.length;
934 var lines = ch.split(/(?:\r\n?|\n)/g);
935
936 this._input = ch + this._input;
937 this.yytext = this.yytext.substr(0, this.yytext.length-len-1);
938 //this.yyleng -= len;
939 this.offset -= len;
940 var oldLines = this.match.split(/(?:\r\n?|\n)/g);
941 this.match = this.match.substr(0, this.match.length-1);
942 this.matched = this.matched.substr(0, this.matched.length-1);
943
944 if (lines.length-1) this.yylineno -= lines.length-1;
945 var r = this.yylloc.range;
946
947 this.yylloc = {first_line: this.yylloc.first_line,
948 last_line: this.yylineno+1,
949 first_column: this.yylloc.first_column,
950 last_column: lines ?
951 (lines.length === oldLines.length ? this.yylloc.first_column : 0) + oldLines[oldLines.length - lines.length].length - lines[0].length:
952 this.yylloc.first_column - len
953 };
954
955 if (this.options.ranges) {
956 this.yylloc.range = [r[0], r[0] + this.yyleng - len];
957 }
958 return this;
959 },
960 more:function () {
961 this._more = true;
962 return this;
963 },
964 less:function (n) {
965 this.unput(this.match.slice(n));
966 },
967 pastInput:function () {
968 var past = this.matched.substr(0, this.matched.length - this.match.length);
969 return (past.length > 20 ? '...':'') + past.substr(-20).replace(/\n/g, "");
970 },
971 upcomingInput:function () {
972 var next = this.match;
973 if (next.length < 20) {
974 next += this._input.substr(0, 20-next.length);
975 }
976 return (next.substr(0,20)+(next.length > 20 ? '...':'')).replace(/\n/g, "");
977 },
978 showPosition:function () {
979 var pre = this.pastInput();
980 var c = new Array(pre.length + 1).join("-");
981 return pre + this.upcomingInput() + "\n" + c+"^";
982 },
983 next:function () {
984 if (this.done) {
985 return this.EOF;
986 }
987 if (!this._input) this.done = true;
988
989 var token,
990 match,
991 tempMatch,
992 index,
993 col,
994 lines;
995 if (!this._more) {
996 this.yytext = '';
997 this.match = '';
998 }
999 var rules = this._currentRules();
1000 for (var i=0;i < rules.length; i++) {
1001 tempMatch = this._input.match(this.rules[rules[i]]);
1002 if (tempMatch && (!match || tempMatch[0].length > match[0].length)) {
1003 match = tempMatch;
1004 index = i;
1005 if (!this.options.flex) break;
1006 }
1007 }
1008 if (match) {
1009 lines = match[0].match(/(?:\r\n?|\n).*/g);
1010 if (lines) this.yylineno += lines.length;
1011 this.yylloc = {first_line: this.yylloc.last_line,
1012 last_line: this.yylineno+1,
1013 first_column: this.yylloc.last_column,
1014 last_column: lines ? lines[lines.length-1].length-lines[lines.length-1].match(/\r?\n?/)[0].length : this.yylloc.last_column + match[0].length};
1015 this.yytext += match[0];
1016 this.match += match[0];
1017 this.matches = match;
1018 this.yyleng = this.yytext.length;
1019 if (this.options.ranges) {
1020 this.yylloc.range = [this.offset, this.offset += this.yyleng];
1021 }
1022 this._more = false;
1023 this._input = this._input.slice(match[0].length);
1024 this.matched += match[0];
1025 token = this.performAction.call(this, this.yy, this, rules[index],this.conditionStack[this.conditionStack.length-1]);
1026 if (this.done && this._input) this.done = false;
1027 if (token) return token;
1028 else return;
1029 }
1030 if (this._input === "") {
1031 return this.EOF;
1032 } else {
1033 return this.parseError('Lexical error on line '+(this.yylineno+1)+'. Unrecognized text.\n'+this.showPosition(),
1034 {text: "", token: null, line: this.yylineno});
1035 }
1036 },
1037 lex:function lex() {
1038 var r = this.next();
1039 if (typeof r !== 'undefined') {
1040 return r;
1041 } else {
1042 return this.lex();
1043 }
1044 },
1045 begin:function begin(condition) {
1046 this.conditionStack.push(condition);
1047 },
1048 popState:function popState() {
1049 return this.conditionStack.pop();
1050 },
1051 _currentRules:function _currentRules() {
1052 return this.conditions[this.conditionStack[this.conditionStack.length-1]].rules;
1053 },
1054 topState:function () {
1055 return this.conditionStack[this.conditionStack.length-2];
1056 },
1057 pushState:function begin(condition) {
1058 this.begin(condition);
1059 }});
1060 lexer.options = {};
1061 lexer.performAction = function anonymous(yy,yy_,$avoiding_name_collisions,YY_START) {
1062
1063
1064 function strip(start, end) {
1065 return yy_.yytext = yy_.yytext.substr(start, yy_.yyleng-end);
1066 }
1067
1068
1069 var YYSTATE=YY_START
1070 switch($avoiding_name_collisions) {
1071 case 0:
1072 if(yy_.yytext.slice(-2) === "\\\\") {
1073 strip(0,1);
1074 this.begin("mu");
1075 } else if(yy_.yytext.slice(-1) === "\\") {
1076 strip(0,1);
1077 this.begin("emu");
1078 } else {
1079 this.begin("mu");
1080 }
1081 if(yy_.yytext) return 14;
1082
1083 break;
1084 case 1:return 14;
1085 break;
1086 case 2:
1087 if(yy_.yytext.slice(-1) !== "\\") this.popState();
1088 if(yy_.yytext.slice(-1) === "\\") strip(0,1);
1089 return 14;
1090
1091 break;
1092 case 3:strip(0,4); this.popState(); return 15;
1093 break;
1094 case 4:return 25;
1095 break;
1096 case 5:return 16;
1097 break;
1098 case 6:return 20;
1099 break;
1100 case 7:return 19;
1101 break;
1102 case 8:return 19;
1103 break;
1104 case 9:return 23;
1105 break;
1106 case 10:return 22;
1107 break;
1108 case 11:this.popState(); this.begin('com');
1109 break;
1110 case 12:strip(3,5); this.popState(); return 15;
1111 break;
1112 case 13:return 22;
1113 break;
1114 case 14:return 39;
1115 break;
1116 case 15:return 38;
1117 break;
1118 case 16:return 38;
1119 break;
1120 case 17:return 42;
1121 break;
1122 case 18:/*ignore whitespace*/
1123 break;
1124 case 19:this.popState(); return 24;
1125 break;
1126 case 20:this.popState(); return 18;
1127 break;
1128 case 21:yy_.yytext = strip(1,2).replace(/\\"/g,'"'); return 32;
1129 break;
1130 case 22:yy_.yytext = strip(1,2).replace(/\\'/g,"'"); return 32;
1131 break;
1132 case 23:return 40;
1133 break;
1134 case 24:return 34;
1135 break;
1136 case 25:return 34;
1137 break;
1138 case 26:return 33;
1139 break;
1140 case 27:return 38;
1141 break;
1142 case 28:yy_.yytext = strip(1,2); return 38;
1143 break;
1144 case 29:return 'INVALID';
1145 break;
1146 case 30:return 5;
1147 break;
1148 }
1149 };
1150 lexer.rules = [/^(?:[^\x00]*?(?=(\{\{)))/,/^(?:[^\x00]+)/,/^(?:[^\x00]{2,}?(?=(\{\{|$)))/,/^(?:[\s\S]*?--\}\})/,/^(?:\{\{(~)?>)/,/^(?:\{\{(~)?#)/,/^(?:\{\{(~)?\/)/,/^(?:\{\{(~)?\^)/,/^(?:\{\{(~)?\s*else\b)/,/^(?:\{\{(~)?\{)/,/^(?:\{\{(~)?&)/,/^(?:\{\{!--)/,/^(?:\{\{![\s\S]*?\}\})/,/^(?:\{\{(~)?)/,/^(?:=)/,/^(?:\.\.)/,/^(?:\.(?=([=~}\s\/.])))/,/^(?:[\/.])/,/^(?:\s+)/,/^(?:\}(~)?\}\})/,/^(?:(~)?\}\})/,/^(?:"(\\["]|[^"])*")/,/^(?:'(\\[']|[^'])*')/,/^(?:@)/,/^(?:true(?=([~}\s])))/,/^(?:false(?=([~}\s])))/,/^(?:-?[0-9]+(?=([~}\s])))/,/^(?:([^\s!"#%-,\.\/;->@\[-\^`\{-~]+(?=([=~}\s\/.]))))/,/^(?:\[[^\]]*\])/,/^(?:.)/,/^(?:$)/];
1151 lexer.conditions = {"mu":{"rules":[4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30],"inclusive":false},"emu":{"rules":[2],"inclusive":false},"com":{"rules":[3],"inclusive":false},"INITIAL":{"rules":[0,1,30],"inclusive":true}};
1152 return lexer;})()
1153 parser.lexer = lexer;
1154 function Parser () { this.yy = {}; }Parser.prototype = parser;parser.Parser = Parser;
1155 return new Parser;
1156 })();__exports__ = handlebars;
1157 return __exports__;
1158 })();
1159
1160 // handlebars/compiler/base.js
1161 var __module8__ = (function(__dependency1__, __dependency2__) {
1162 "use strict";
1163 var __exports__ = {};
1164 var parser = __dependency1__;
1165 var AST = __dependency2__;
1166
1167 __exports__.parser = parser;
1168
1169 function parse(input) {
1170 // Just return if an already-compile AST was passed in.
1171 if(input.constructor === AST.ProgramNode) { return input; }
1172
1173 parser.yy = AST;
1174 return parser.parse(input);
1175 }
1176
1177 __exports__.parse = parse;
1178 return __exports__;
1179 })(__module9__, __module7__);
1180
1181 // handlebars/compiler/javascript-compiler.js
1182 var __module11__ = (function(__dependency1__) {
1183 "use strict";
1184 var __exports__;
1185 var COMPILER_REVISION = __dependency1__.COMPILER_REVISION;
1186 var REVISION_CHANGES = __dependency1__.REVISION_CHANGES;
1187 var log = __dependency1__.log;
1188
1189 function Literal(value) {
1190 this.value = value;
1191 }
1192
1193 function JavaScriptCompiler() {}
1194
1195 JavaScriptCompiler.prototype = {
1196 // PUBLIC API: You can override these methods in a subclass to provide
1197 // alternative compiled forms for name lookup and buffering semantics
1198 nameLookup: function(parent, name /* , type*/) {
1199 var wrap,
1200 ret;
1201 if (parent.indexOf('depth') === 0) {
1202 wrap = true;
1203 }
1204
1205 if (/^[0-9]+$/.test(name)) {
1206 ret = parent + "[" + name + "]";
1207 } else if (JavaScriptCompiler.isValidJavaScriptVariableName(name)) {
1208 ret = parent + "." + name;
1209 }
1210 else {
1211 ret = parent + "['" + name + "']";
1212 }
1213
1214 if (wrap) {
1215 return '(' + parent + ' && ' + ret + ')';
1216 } else {
1217 return ret;
1218 }
1219 },
1220
1221 appendToBuffer: function(string) {
1222 if (this.environment.isSimple) {
1223 return "return " + string + ";";
1224 } else {
1225 return {
1226 appendToBuffer: true,
1227 content: string,
1228 toString: function() { return "buffer += " + string + ";"; }
1229 };
1230 }
1231 },
1232
1233 initializeBuffer: function() {
1234 return this.quotedString("");
1235 },
1236
1237 namespace: "Handlebars",
1238 // END PUBLIC API
1239
1240 compile: function(environment, options, context, asObject) {
1241 this.environment = environment;
1242 this.options = options || {};
1243
1244 log('debug', this.environment.disassemble() + "\n\n");
1245
1246 this.name = this.environment.name;
1247 this.isChild = !!context;
1248 this.context = context || {
1249 programs: [],
1250 environments: [],
1251 aliases: { }
1252 };
1253
1254 this.preamble();
1255
1256 this.stackSlot = 0;
1257 this.stackVars = [];
1258 this.registers = { list: [] };
1259 this.compileStack = [];
1260 this.inlineStack = [];
1261
1262 this.compileChildren(environment, options);
1263
1264 var opcodes = environment.opcodes, opcode;
1265
1266 this.i = 0;
1267
1268 for(var l=opcodes.length; this.i<l; this.i++) {
1269 opcode = opcodes[this.i];
1270
1271 if(opcode.opcode === 'DECLARE') {
1272 this[opcode.name] = opcode.value;
1273 } else {
1274 this[opcode.opcode].apply(this, opcode.args);
1275 }
1276
1277 // Reset the stripNext flag if it was not set by this operation.
1278 if (opcode.opcode !== this.stripNext) {
1279 this.stripNext = false;
1280 }
1281 }
1282
1283 // Flush any trailing content that might be pending.
1284 this.pushSource('');
1285
1286 return this.createFunctionContext(asObject);
1287 },
1288
1289 preamble: function() {
1290 var out = [];
1291
1292 if (!this.isChild) {
1293 var namespace = this.namespace;
1294
1295 var copies = "helpers = this.merge(helpers, " + namespace + ".helpers);";
1296 if (this.environment.usePartial) { copies = copies + " partials = this.merge(partials, " + namespace + ".partials);"; }
1297 if (this.options.data) { copies = copies + " data = data || {};"; }
1298 out.push(copies);
1299 } else {
1300 out.push('');
1301 }
1302
1303 if (!this.environment.isSimple) {
1304 out.push(", buffer = " + this.initializeBuffer());
1305 } else {
1306 out.push("");
1307 }
1308
1309 // track the last context pushed into place to allow skipping the
1310 // getContext opcode when it would be a noop
1311 this.lastContext = 0;
1312 this.source = out;
1313 },
1314
1315 createFunctionContext: function(asObject) {
1316 var locals = this.stackVars.concat(this.registers.list);
1317
1318 if(locals.length > 0) {
1319 this.source[1] = this.source[1] + ", " + locals.join(", ");
1320 }
1321
1322 // Generate minimizer alias mappings
1323 if (!this.isChild) {
1324 for (var alias in this.context.aliases) {
1325 if (this.context.aliases.hasOwnProperty(alias)) {
1326 this.source[1] = this.source[1] + ', ' + alias + '=' + this.context.aliases[alias];
1327 }
1328 }
1329 }
1330
1331 if (this.source[1]) {
1332 this.source[1] = "var " + this.source[1].substring(2) + ";";
1333 }
1334
1335 // Merge children
1336 if (!this.isChild) {
1337 this.source[1] += '\n' + this.context.programs.join('\n') + '\n';
1338 }
1339
1340 if (!this.environment.isSimple) {
1341 this.pushSource("return buffer;");
1342 }
1343
1344 var params = this.isChild ? ["depth0", "data"] : ["Handlebars", "depth0", "helpers", "partials", "data"];
1345
1346 for(var i=0, l=this.environment.depths.list.length; i<l; i++) {
1347 params.push("depth" + this.environment.depths.list[i]);
1348 }
1349
1350 // Perform a second pass over the output to merge content when possible
1351 var source = this.mergeSource();
1352
1353 if (!this.isChild) {
1354 var revision = COMPILER_REVISION,
1355 versions = REVISION_CHANGES[revision];
1356 source = "this.compilerInfo = ["+revision+",'"+versions+"'];\n"+source;
1357 }
1358
1359 if (asObject) {
1360 params.push(source);
1361
1362 return Function.apply(this, params);
1363 } else {
1364 var functionSource = 'function ' + (this.name || '') + '(' + params.join(',') + ') {\n ' + source + '}';
1365 log('debug', functionSource + "\n\n");
1366 return functionSource;
1367 }
1368 },
1369 mergeSource: function() {
1370 // WARN: We are not handling the case where buffer is still populated as the source should
1371 // not have buffer append operations as their final action.
1372 var source = '',
1373 buffer;
1374 for (var i = 0, len = this.source.length; i < len; i++) {
1375 var line = this.source[i];
1376 if (line.appendToBuffer) {
1377 if (buffer) {
1378 buffer = buffer + '\n + ' + line.content;
1379 } else {
1380 buffer = line.content;
1381 }
1382 } else {
1383 if (buffer) {
1384 source += 'buffer += ' + buffer + ';\n ';
1385 buffer = undefined;
1386 }
1387 source += line + '\n ';
1388 }
1389 }
1390 return source;
1391 },
1392
1393 // [blockValue]
1394 //
1395 // On stack, before: hash, inverse, program, value
1396 // On stack, after: return value of blockHelperMissing
1397 //
1398 // The purpose of this opcode is to take a block of the form
1399 // `{{#foo}}...{{/foo}}`, resolve the value of `foo`, and
1400 // replace it on the stack with the result of properly
1401 // invoking blockHelperMissing.
1402 blockValue: function() {
1403 this.context.aliases.blockHelperMissing = 'helpers.blockHelperMissing';
1404
1405 var params = ["depth0"];
1406 this.setupParams(0, params);
1407
1408 this.replaceStack(function(current) {
1409 params.splice(1, 0, current);
1410 return "blockHelperMissing.call(" + params.join(", ") + ")";
1411 });
1412 },
1413
1414 // [ambiguousBlockValue]
1415 //
1416 // On stack, before: hash, inverse, program, value
1417 // Compiler value, before: lastHelper=value of last found helper, if any
1418 // On stack, after, if no lastHelper: same as [blockValue]
1419 // On stack, after, if lastHelper: value
1420 ambiguousBlockValue: function() {
1421 this.context.aliases.blockHelperMissing = 'helpers.blockHelperMissing';
1422
1423 var params = ["depth0"];
1424 this.setupParams(0, params);
1425
1426 var current = this.topStack();
1427 params.splice(1, 0, current);
1428
1429 // Use the options value generated from the invocation
1430 params[params.length-1] = 'options';
1431
1432 this.pushSource("if (!" + this.lastHelper + ") { " + current + " = blockHelperMissing.call(" + params.join(", ") + "); }");
1433 },
1434
1435 // [appendContent]
1436 //
1437 // On stack, before: ...
1438 // On stack, after: ...
1439 //
1440 // Appends the string value of `content` to the current buffer
1441 appendContent: function(content) {
1442 if (this.pendingContent) {
1443 content = this.pendingContent + content;
1444 }
1445 if (this.stripNext) {
1446 content = content.replace(/^\s+/, '');
1447 }
1448
1449 this.pendingContent = content;
1450 },
1451
1452 // [strip]
1453 //
1454 // On stack, before: ...
1455 // On stack, after: ...
1456 //
1457 // Removes any trailing whitespace from the prior content node and flags
1458 // the next operation for stripping if it is a content node.
1459 strip: function() {
1460 if (this.pendingContent) {
1461 this.pendingContent = this.pendingContent.replace(/\s+$/, '');
1462 }
1463 this.stripNext = 'strip';
1464 },
1465
1466 // [append]
1467 //
1468 // On stack, before: value, ...
1469 // On stack, after: ...
1470 //
1471 // Coerces `value` to a String and appends it to the current buffer.
1472 //
1473 // If `value` is truthy, or 0, it is coerced into a string and appended
1474 // Otherwise, the empty string is appended
1475 append: function() {
1476 // Force anything that is inlined onto the stack so we don't have duplication
1477 // when we examine local
1478 this.flushInline();
1479 var local = this.popStack();
1480 this.pushSource("if(" + local + " || " + local + " === 0) { " + this.appendToBuffer(local) + " }");
1481 if (this.environment.isSimple) {
1482 this.pushSource("else { " + this.appendToBuffer("''") + " }");
1483 }
1484 },
1485
1486 // [appendEscaped]
1487 //
1488 // On stack, before: value, ...
1489 // On stack, after: ...
1490 //
1491 // Escape `value` and append it to the buffer
1492 appendEscaped: function() {
1493 this.context.aliases.escapeExpression = 'this.escapeExpression';
1494
1495 this.pushSource(this.appendToBuffer("escapeExpression(" + this.popStack() + ")"));
1496 },
1497
1498 // [getContext]
1499 //
1500 // On stack, before: ...
1501 // On stack, after: ...
1502 // Compiler value, after: lastContext=depth
1503 //
1504 // Set the value of the `lastContext` compiler value to the depth
1505 getContext: function(depth) {
1506 if(this.lastContext !== depth) {
1507 this.lastContext = depth;
1508 }
1509 },
1510
1511 // [lookupOnContext]
1512 //
1513 // On stack, before: ...
1514 // On stack, after: currentContext[name], ...
1515 //
1516 // Looks up the value of `name` on the current context and pushes
1517 // it onto the stack.
1518 lookupOnContext: function(name) {
1519 this.push(this.nameLookup('depth' + this.lastContext, name, 'context'));
1520 },
1521
1522 // [pushContext]
1523 //
1524 // On stack, before: ...
1525 // On stack, after: currentContext, ...
1526 //
1527 // Pushes the value of the current context onto the stack.
1528 pushContext: function() {
1529 this.pushStackLiteral('depth' + this.lastContext);
1530 },
1531
1532 // [resolvePossibleLambda]
1533 //
1534 // On stack, before: value, ...
1535 // On stack, after: resolved value, ...
1536 //
1537 // If the `value` is a lambda, replace it on the stack by
1538 // the return value of the lambda
1539 resolvePossibleLambda: function() {
1540 this.context.aliases.functionType = '"function"';
1541
1542 this.replaceStack(function(current) {
1543 return "typeof " + current + " === functionType ? " + current + ".apply(depth0) : " + current;
1544 });
1545 },
1546
1547 // [lookup]
1548 //
1549 // On stack, before: value, ...
1550 // On stack, after: value[name], ...
1551 //
1552 // Replace the value on the stack with the result of looking
1553 // up `name` on `value`
1554 lookup: function(name) {
1555 this.replaceStack(function(current) {
1556 return current + " == null || " + current + " === false ? " + current + " : " + this.nameLookup(current, name, 'context');
1557 });
1558 },
1559
1560 // [lookupData]
1561 //
1562 // On stack, before: ...
1563 // On stack, after: data, ...
1564 //
1565 // Push the data lookup operator
1566 lookupData: function() {
1567 this.push('data');
1568 },
1569
1570 // [pushStringParam]
1571 //
1572 // On stack, before: ...
1573 // On stack, after: string, currentContext, ...
1574 //
1575 // This opcode is designed for use in string mode, which
1576 // provides the string value of a parameter along with its
1577 // depth rather than resolving it immediately.
1578 pushStringParam: function(string, type) {
1579 this.pushStackLiteral('depth' + this.lastContext);
1580
1581 this.pushString(type);
1582
1583 if (typeof string === 'string') {
1584 this.pushString(string);
1585 } else {
1586 this.pushStackLiteral(string);
1587 }
1588 },
1589
1590 emptyHash: function() {
1591 this.pushStackLiteral('{}');
1592
1593 if (this.options.stringParams) {
1594 this.register('hashTypes', '{}');
1595 this.register('hashContexts', '{}');
1596 }
1597 },
1598 pushHash: function() {
1599 this.hash = {values: [], types: [], contexts: []};
1600 },
1601 popHash: function() {
1602 var hash = this.hash;
1603 this.hash = undefined;
1604
1605 if (this.options.stringParams) {
1606 this.register('hashContexts', '{' + hash.contexts.join(',') + '}');
1607 this.register('hashTypes', '{' + hash.types.join(',') + '}');
1608 }
1609 this.push('{\n ' + hash.values.join(',\n ') + '\n }');
1610 },
1611
1612 // [pushString]
1613 //
1614 // On stack, before: ...
1615 // On stack, after: quotedString(string), ...
1616 //
1617 // Push a quoted version of `string` onto the stack
1618 pushString: function(string) {
1619 this.pushStackLiteral(this.quotedString(string));
1620 },
1621
1622 // [push]
1623 //
1624 // On stack, before: ...
1625 // On stack, after: expr, ...
1626 //
1627 // Push an expression onto the stack
1628 push: function(expr) {
1629 this.inlineStack.push(expr);
1630 return expr;
1631 },
1632
1633 // [pushLiteral]
1634 //
1635 // On stack, before: ...
1636 // On stack, after: value, ...
1637 //
1638 // Pushes a value onto the stack. This operation prevents
1639 // the compiler from creating a temporary variable to hold
1640 // it.
1641 pushLiteral: function(value) {
1642 this.pushStackLiteral(value);
1643 },
1644
1645 // [pushProgram]
1646 //
1647 // On stack, before: ...
1648 // On stack, after: program(guid), ...
1649 //
1650 // Push a program expression onto the stack. This takes
1651 // a compile-time guid and converts it into a runtime-accessible
1652 // expression.
1653 pushProgram: function(guid) {
1654 if (guid != null) {
1655 this.pushStackLiteral(this.programExpression(guid));
1656 } else {
1657 this.pushStackLiteral(null);
1658 }
1659 },
1660
1661 // [invokeHelper]
1662 //
1663 // On stack, before: hash, inverse, program, params..., ...
1664 // On stack, after: result of helper invocation
1665 //
1666 // Pops off the helper's parameters, invokes the helper,
1667 // and pushes the helper's return value onto the stack.
1668 //
1669 // If the helper is not found, `helperMissing` is called.
1670 invokeHelper: function(paramSize, name) {
1671 this.context.aliases.helperMissing = 'helpers.helperMissing';
1672
1673 var helper = this.lastHelper = this.setupHelper(paramSize, name, true);
1674 var nonHelper = this.nameLookup('depth' + this.lastContext, name, 'context');
1675
1676 this.push(helper.name + ' || ' + nonHelper);
1677 this.replaceStack(function(name) {
1678 return name + ' ? ' + name + '.call(' +
1679 helper.callParams + ") " + ": helperMissing.call(" +
1680 helper.helperMissingParams + ")";
1681 });
1682 },
1683
1684 // [invokeKnownHelper]
1685 //
1686 // On stack, before: hash, inverse, program, params..., ...
1687 // On stack, after: result of helper invocation
1688 //
1689 // This operation is used when the helper is known to exist,
1690 // so a `helperMissing` fallback is not required.
1691 invokeKnownHelper: function(paramSize, name) {
1692 var helper = this.setupHelper(paramSize, name);
1693 this.push(helper.name + ".call(" + helper.callParams + ")");
1694 },
1695
1696 // [invokeAmbiguous]
1697 //
1698 // On stack, before: hash, inverse, program, params..., ...
1699 // On stack, after: result of disambiguation
1700 //
1701 // This operation is used when an expression like `{{foo}}`
1702 // is provided, but we don't know at compile-time whether it
1703 // is a helper or a path.
1704 //
1705 // This operation emits more code than the other options,
1706 // and can be avoided by passing the `knownHelpers` and
1707 // `knownHelpersOnly` flags at compile-time.
1708 invokeAmbiguous: function(name, helperCall) {
1709 this.context.aliases.functionType = '"function"';
1710
1711 this.pushStackLiteral('{}'); // Hash value
1712 var helper = this.setupHelper(0, name, helperCall);
1713
1714 var helperName = this.lastHelper = this.nameLookup('helpers', name, 'helper');
1715
1716 var nonHelper = this.nameLookup('depth' + this.lastContext, name, 'context');
1717 var nextStack = this.nextStack();
1718
1719 this.pushSource('if (' + nextStack + ' = ' + helperName + ') { ' + nextStack + ' = ' + nextStack + '.call(' + helper.callParams + '); }');
1720 this.pushSource('else { ' + nextStack + ' = ' + nonHelper + '; ' + nextStack + ' = typeof ' + nextStack + ' === functionType ? ' + nextStack + '.call(' + helper.callParams + ') : ' + nextStack + '; }');
1721 },
1722
1723 // [invokePartial]
1724 //
1725 // On stack, before: context, ...
1726 // On stack after: result of partial invocation
1727 //
1728 // This operation pops off a context, invokes a partial with that context,
1729 // and pushes the result of the invocation back.
1730 invokePartial: function(name) {
1731 var params = [this.nameLookup('partials', name, 'partial'), "'" + name + "'", this.popStack(), "helpers", "partials"];
1732
1733 if (this.options.data) {
1734 params.push("data");
1735 }
1736
1737 this.context.aliases.self = "this";
1738 this.push("self.invokePartial(" + params.join(", ") + ")");
1739 },
1740
1741 // [assignToHash]
1742 //
1743 // On stack, before: value, hash, ...
1744 // On stack, after: hash, ...
1745 //
1746 // Pops a value and hash off the stack, assigns `hash[key] = value`
1747 // and pushes the hash back onto the stack.
1748 assignToHash: function(key) {
1749 var value = this.popStack(),
1750 context,
1751 type;
1752
1753 if (this.options.stringParams) {
1754 type = this.popStack();
1755 context = this.popStack();
1756 }
1757
1758 var hash = this.hash;
1759 if (context) {
1760 hash.contexts.push("'" + key + "': " + context);
1761 }
1762 if (type) {
1763 hash.types.push("'" + key + "': " + type);
1764 }
1765 hash.values.push("'" + key + "': (" + value + ")");
1766 },
1767
1768 // HELPERS
1769
1770 compiler: JavaScriptCompiler,
1771
1772 compileChildren: function(environment, options) {
1773 var children = environment.children, child, compiler;
1774
1775 for(var i=0, l=children.length; i<l; i++) {
1776 child = children[i];
1777 compiler = new this.compiler();
1778
1779 var index = this.matchExistingProgram(child);
1780
1781 if (index == null) {
1782 this.context.programs.push(''); // Placeholder to prevent name conflicts for nested children
1783 index = this.context.programs.length;
1784 child.index = index;
1785 child.name = 'program' + index;
1786 this.context.programs[index] = compiler.compile(child, options, this.context);
1787 this.context.environments[index] = child;
1788 } else {
1789 child.index = index;
1790 child.name = 'program' + index;
1791 }
1792 }
1793 },
1794 matchExistingProgram: function(child) {
1795 for (var i = 0, len = this.context.environments.length; i < len; i++) {
1796 var environment = this.context.environments[i];
1797 if (environment && environment.equals(child)) {
1798 return i;
1799 }
1800 }
1801 },
1802
1803 programExpression: function(guid) {
1804 this.context.aliases.self = "this";
1805
1806 if(guid == null) {
1807 return "self.noop";
1808 }
1809
1810 var child = this.environment.children[guid],
1811 depths = child.depths.list, depth;
1812
1813 var programParams = [child.index, child.name, "data"];
1814
1815 for(var i=0, l = depths.length; i<l; i++) {
1816 depth = depths[i];
1817
1818 if(depth === 1) { programParams.push("depth0"); }
1819 else { programParams.push("depth" + (depth - 1)); }
1820 }
1821
1822 return (depths.length === 0 ? "self.program(" : "self.programWithDepth(") + programParams.join(", ") + ")";
1823 },
1824
1825 register: function(name, val) {
1826 this.useRegister(name);
1827 this.pushSource(name + " = " + val + ";");
1828 },
1829
1830 useRegister: function(name) {
1831 if(!this.registers[name]) {
1832 this.registers[name] = true;
1833 this.registers.list.push(name);
1834 }
1835 },
1836
1837 pushStackLiteral: function(item) {
1838 return this.push(new Literal(item));
1839 },
1840
1841 pushSource: function(source) {
1842 if (this.pendingContent) {
1843 this.source.push(this.appendToBuffer(this.quotedString(this.pendingContent)));
1844 this.pendingContent = undefined;
1845 }
1846
1847 if (source) {
1848 this.source.push(source);
1849 }
1850 },
1851
1852 pushStack: function(item) {
1853 this.flushInline();
1854
1855 var stack = this.incrStack();
1856 if (item) {
1857 this.pushSource(stack + " = " + item + ";");
1858 }
1859 this.compileStack.push(stack);
1860 return stack;
1861 },
1862
1863 replaceStack: function(callback) {
1864 var prefix = '',
1865 inline = this.isInline(),
1866 stack;
1867
1868 // If we are currently inline then we want to merge the inline statement into the
1869 // replacement statement via ','
1870 if (inline) {
1871 var top = this.popStack(true);
1872
1873 if (top instanceof Literal) {
1874 // Literals do not need to be inlined
1875 stack = top.value;
1876 } else {
1877 // Get or create the current stack name for use by the inline
1878 var name = this.stackSlot ? this.topStackName() : this.incrStack();
1879
1880 prefix = '(' + this.push(name) + ' = ' + top + '),';
1881 stack = this.topStack();
1882 }
1883 } else {
1884 stack = this.topStack();
1885 }
1886
1887 var item = callback.call(this, stack);
1888
1889 if (inline) {
1890 if (this.inlineStack.length || this.compileStack.length) {
1891 this.popStack();
1892 }
1893 this.push('(' + prefix + item + ')');
1894 } else {
1895 // Prevent modification of the context depth variable. Through replaceStack
1896 if (!/^stack/.test(stack)) {
1897 stack = this.nextStack();
1898 }
1899
1900 this.pushSource(stack + " = (" + prefix + item + ");");
1901 }
1902 return stack;
1903 },
1904
1905 nextStack: function() {
1906 return this.pushStack();
1907 },
1908
1909 incrStack: function() {
1910 this.stackSlot++;
1911 if(this.stackSlot > this.stackVars.length) { this.stackVars.push("stack" + this.stackSlot); }
1912 return this.topStackName();
1913 },
1914 topStackName: function() {
1915 return "stack" + this.stackSlot;
1916 },
1917 flushInline: function() {
1918 var inlineStack = this.inlineStack;
1919 if (inlineStack.length) {
1920 this.inlineStack = [];
1921 for (var i = 0, len = inlineStack.length; i < len; i++) {
1922 var entry = inlineStack[i];
1923 if (entry instanceof Literal) {
1924 this.compileStack.push(entry);
1925 } else {
1926 this.pushStack(entry);
1927 }
1928 }
1929 }
1930 },
1931 isInline: function() {
1932 return this.inlineStack.length;
1933 },
1934
1935 popStack: function(wrapped) {
1936 var inline = this.isInline(),
1937 item = (inline ? this.inlineStack : this.compileStack).pop();
1938
1939 if (!wrapped && (item instanceof Literal)) {
1940 return item.value;
1941 } else {
1942 if (!inline) {
1943 this.stackSlot--;
1944 }
1945 return item;
1946 }
1947 },
1948
1949 topStack: function(wrapped) {
1950 var stack = (this.isInline() ? this.inlineStack : this.compileStack),
1951 item = stack[stack.length - 1];
1952
1953 if (!wrapped && (item instanceof Literal)) {
1954 return item.value;
1955 } else {
1956 return item;
1957 }
1958 },
1959
1960 quotedString: function(str) {
1961 return '"' + str
1962 .replace(/\\/g, '\\\\')
1963 .replace(/"/g, '\\"')
1964 .replace(/\n/g, '\\n')
1965 .replace(/\r/g, '\\r')
1966 .replace(/\u2028/g, '\\u2028') // Per Ecma-262 7.3 + 7.8.4
1967 .replace(/\u2029/g, '\\u2029') + '"';
1968 },
1969
1970 setupHelper: function(paramSize, name, missingParams) {
1971 var params = [];
1972 this.setupParams(paramSize, params, missingParams);
1973 var foundHelper = this.nameLookup('helpers', name, 'helper');
1974
1975 return {
1976 params: params,
1977 name: foundHelper,
1978 callParams: ["depth0"].concat(params).join(", "),
1979 helperMissingParams: missingParams && ["depth0", this.quotedString(name)].concat(params).join(", ")
1980 };
1981 },
1982
1983 // the params and contexts arguments are passed in arrays
1984 // to fill in
1985 setupParams: function(paramSize, params, useRegister) {
1986 var options = [], contexts = [], types = [], param, inverse, program;
1987
1988 options.push("hash:" + this.popStack());
1989
1990 inverse = this.popStack();
1991 program = this.popStack();
1992
1993 // Avoid setting fn and inverse if neither are set. This allows
1994 // helpers to do a check for `if (options.fn)`
1995 if (program || inverse) {
1996 if (!program) {
1997 this.context.aliases.self = "this";
1998 program = "self.noop";
1999 }
2000
2001 if (!inverse) {
2002 this.context.aliases.self = "this";
2003 inverse = "self.noop";
2004 }
2005
2006 options.push("inverse:" + inverse);
2007 options.push("fn:" + program);
2008 }
2009
2010 for(var i=0; i<paramSize; i++) {
2011 param = this.popStack();
2012 params.push(param);
2013
2014 if(this.options.stringParams) {
2015 types.push(this.popStack());
2016 contexts.push(this.popStack());
2017 }
2018 }
2019
2020 if (this.options.stringParams) {
2021 options.push("contexts:[" + contexts.join(",") + "]");
2022 options.push("types:[" + types.join(",") + "]");
2023 options.push("hashContexts:hashContexts");
2024 options.push("hashTypes:hashTypes");
2025 }
2026
2027 if(this.options.data) {
2028 options.push("data:data");
2029 }
2030
2031 options = "{" + options.join(",") + "}";
2032 if (useRegister) {
2033 this.register('options', options);
2034 params.push('options');
2035 } else {
2036 params.push(options);
2037 }
2038 return params.join(", ");
2039 }
2040 };
2041
2042 var reservedWords = (
2043 "break else new var" +
2044 " case finally return void" +
2045 " catch for switch while" +
2046 " continue function this with" +
2047 " default if throw" +
2048 " delete in try" +
2049 " do instanceof typeof" +
2050 " abstract enum int short" +
2051 " boolean export interface static" +
2052 " byte extends long super" +
2053 " char final native synchronized" +
2054 " class float package throws" +
2055 " const goto private transient" +
2056 " debugger implements protected volatile" +
2057 " double import public let yield"
2058 ).split(" ");
2059
2060 var compilerWords = JavaScriptCompiler.RESERVED_WORDS = {};
2061
2062 for(var i=0, l=reservedWords.length; i<l; i++) {
2063 compilerWords[reservedWords[i]] = true;
2064 }
2065
2066 JavaScriptCompiler.isValidJavaScriptVariableName = function(name) {
2067 if(!JavaScriptCompiler.RESERVED_WORDS[name] && /^[a-zA-Z_$][0-9a-zA-Z_$]+$/.test(name)) {
2068 return true;
2069 }
2070 return false;
2071 };
2072
2073 __exports__ = JavaScriptCompiler;
2074 return __exports__;
2075 })(__module2__);
2076
2077 // handlebars/compiler/compiler.js
2078 var __module10__ = (function(__dependency1__, __dependency2__, __dependency3__, __dependency4__) {
2079 "use strict";
2080 var __exports__ = {};
2081 var Exception = __dependency1__;
2082 var parse = __dependency2__.parse;
2083 var JavaScriptCompiler = __dependency3__;
2084 var AST = __dependency4__;
2085
2086 function Compiler() {}
2087
2088 __exports__.Compiler = Compiler;// the foundHelper register will disambiguate helper lookup from finding a
2089 // function in a context. This is necessary for mustache compatibility, which
2090 // requires that context functions in blocks are evaluated by blockHelperMissing,
2091 // and then proceed as if the resulting value was provided to blockHelperMissing.
2092
2093 Compiler.prototype = {
2094 compiler: Compiler,
2095
2096 disassemble: function() {
2097 var opcodes = this.opcodes, opcode, out = [], params, param;
2098
2099 for (var i=0, l=opcodes.length; i<l; i++) {
2100 opcode = opcodes[i];
2101
2102 if (opcode.opcode === 'DECLARE') {
2103 out.push("DECLARE " + opcode.name + "=" + opcode.value);
2104 } else {
2105 params = [];
2106 for (var j=0; j<opcode.args.length; j++) {
2107 param = opcode.args[j];
2108 if (typeof param === "string") {
2109 param = "\"" + param.replace("\n", "\\n") + "\"";
2110 }
2111 params.push(param);
2112 }
2113 out.push(opcode.opcode + " " + params.join(" "));
2114 }
2115 }
2116
2117 return out.join("\n");
2118 },
2119
2120 equals: function(other) {
2121 var len = this.opcodes.length;
2122 if (other.opcodes.length !== len) {
2123 return false;
2124 }
2125
2126 for (var i = 0; i < len; i++) {
2127 var opcode = this.opcodes[i],
2128 otherOpcode = other.opcodes[i];
2129 if (opcode.opcode !== otherOpcode.opcode || opcode.args.length !== otherOpcode.args.length) {
2130 return false;
2131 }
2132 for (var j = 0; j < opcode.args.length; j++) {
2133 if (opcode.args[j] !== otherOpcode.args[j]) {
2134 return false;
2135 }
2136 }
2137 }
2138
2139 len = this.children.length;
2140 if (other.children.length !== len) {
2141 return false;
2142 }
2143 for (i = 0; i < len; i++) {
2144 if (!this.children[i].equals(other.children[i])) {
2145 return false;
2146 }
2147 }
2148
2149 return true;
2150 },
2151
2152 guid: 0,
2153
2154 compile: function(program, options) {
2155 this.opcodes = [];
2156 this.children = [];
2157 this.depths = {list: []};
2158 this.options = options;
2159
2160 // These changes will propagate to the other compiler components
2161 var knownHelpers = this.options.knownHelpers;
2162 this.options.knownHelpers = {
2163 'helperMissing': true,
2164 'blockHelperMissing': true,
2165 'each': true,
2166 'if': true,
2167 'unless': true,
2168 'with': true,
2169 'log': true
2170 };
2171 if (knownHelpers) {
2172 for (var name in knownHelpers) {
2173 this.options.knownHelpers[name] = knownHelpers[name];
2174 }
2175 }
2176
2177 return this.accept(program);
2178 },
2179
2180 accept: function(node) {
2181 var strip = node.strip || {},
2182 ret;
2183 if (strip.left) {
2184 this.opcode('strip');
2185 }
2186
2187 ret = this[node.type](node);
2188
2189 if (strip.right) {
2190 this.opcode('strip');
2191 }
2192
2193 return ret;
2194 },
2195
2196 program: function(program) {
2197 var statements = program.statements;
2198
2199 for(var i=0, l=statements.length; i<l; i++) {
2200 this.accept(statements[i]);
2201 }
2202 this.isSimple = l === 1;
2203
2204 this.depths.list = this.depths.list.sort(function(a, b) {
2205 return a - b;
2206 });
2207
2208 return this;
2209 },
2210
2211 compileProgram: function(program) {
2212 var result = new this.compiler().compile(program, this.options);
2213 var guid = this.guid++, depth;
2214
2215 this.usePartial = this.usePartial || result.usePartial;
2216
2217 this.children[guid] = result;
2218
2219 for(var i=0, l=result.depths.list.length; i<l; i++) {
2220 depth = result.depths.list[i];
2221
2222 if(depth < 2) { continue; }
2223 else { this.addDepth(depth - 1); }
2224 }
2225
2226 return guid;
2227 },
2228
2229 block: function(block) {
2230 var mustache = block.mustache,
2231 program = block.program,
2232 inverse = block.inverse;
2233
2234 if (program) {
2235 program = this.compileProgram(program);
2236 }
2237
2238 if (inverse) {
2239 inverse = this.compileProgram(inverse);
2240 }
2241
2242 var type = this.classifyMustache(mustache);
2243
2244 if (type === "helper") {
2245 this.helperMustache(mustache, program, inverse);
2246 } else if (type === "simple") {
2247 this.simpleMustache(mustache);
2248
2249 // now that the simple mustache is resolved, we need to
2250 // evaluate it by executing `blockHelperMissing`
2251 this.opcode('pushProgram', program);
2252 this.opcode('pushProgram', inverse);
2253 this.opcode('emptyHash');
2254 this.opcode('blockValue');
2255 } else {
2256 this.ambiguousMustache(mustache, program, inverse);
2257
2258 // now that the simple mustache is resolved, we need to
2259 // evaluate it by executing `blockHelperMissing`
2260 this.opcode('pushProgram', program);
2261 this.opcode('pushProgram', inverse);
2262 this.opcode('emptyHash');
2263 this.opcode('ambiguousBlockValue');
2264 }
2265
2266 this.opcode('append');
2267 },
2268
2269 hash: function(hash) {
2270 var pairs = hash.pairs, pair, val;
2271
2272 this.opcode('pushHash');
2273
2274 for(var i=0, l=pairs.length; i<l; i++) {
2275 pair = pairs[i];
2276 val = pair[1];
2277
2278 if (this.options.stringParams) {
2279 if(val.depth) {
2280 this.addDepth(val.depth);
2281 }
2282 this.opcode('getContext', val.depth || 0);
2283 this.opcode('pushStringParam', val.stringModeValue, val.type);
2284 } else {
2285 this.accept(val);
2286 }
2287
2288 this.opcode('assignToHash', pair[0]);
2289 }
2290 this.opcode('popHash');
2291 },
2292
2293 partial: function(partial) {
2294 var partialName = partial.partialName;
2295 this.usePartial = true;
2296
2297 if(partial.context) {
2298 this.ID(partial.context);
2299 } else {
2300 this.opcode('push', 'depth0');
2301 }
2302
2303 this.opcode('invokePartial', partialName.name);
2304 this.opcode('append');
2305 },
2306
2307 content: function(content) {
2308 this.opcode('appendContent', content.string);
2309 },
2310
2311 mustache: function(mustache) {
2312 var options = this.options;
2313 var type = this.classifyMustache(mustache);
2314
2315 if (type === "simple") {
2316 this.simpleMustache(mustache);
2317 } else if (type === "helper") {
2318 this.helperMustache(mustache);
2319 } else {
2320 this.ambiguousMustache(mustache);
2321 }
2322
2323 if(mustache.escaped && !options.noEscape) {
2324 this.opcode('appendEscaped');
2325 } else {
2326 this.opcode('append');
2327 }
2328 },
2329
2330 ambiguousMustache: function(mustache, program, inverse) {
2331 var id = mustache.id,
2332 name = id.parts[0],
2333 isBlock = program != null || inverse != null;
2334
2335 this.opcode('getContext', id.depth);
2336
2337 this.opcode('pushProgram', program);
2338 this.opcode('pushProgram', inverse);
2339
2340 this.opcode('invokeAmbiguous', name, isBlock);
2341 },
2342
2343 simpleMustache: function(mustache) {
2344 var id = mustache.id;
2345
2346 if (id.type === 'DATA') {
2347 this.DATA(id);
2348 } else if (id.parts.length) {
2349 this.ID(id);
2350 } else {
2351 // Simplified ID for `this`
2352 this.addDepth(id.depth);
2353 this.opcode('getContext', id.depth);
2354 this.opcode('pushContext');
2355 }
2356
2357 this.opcode('resolvePossibleLambda');
2358 },
2359
2360 helperMustache: function(mustache, program, inverse) {
2361 var params = this.setupFullMustacheParams(mustache, program, inverse),
2362 name = mustache.id.parts[0];
2363
2364 if (this.options.knownHelpers[name]) {
2365 this.opcode('invokeKnownHelper', params.length, name);
2366 } else if (this.options.knownHelpersOnly) {
2367 throw new Error("You specified knownHelpersOnly, but used the unknown helper " + name);
2368 } else {
2369 this.opcode('invokeHelper', params.length, name);
2370 }
2371 },
2372
2373 ID: function(id) {
2374 this.addDepth(id.depth);
2375 this.opcode('getContext', id.depth);
2376
2377 var name = id.parts[0];
2378 if (!name) {
2379 this.opcode('pushContext');
2380 } else {
2381 this.opcode('lookupOnContext', id.parts[0]);
2382 }
2383
2384 for(var i=1, l=id.parts.length; i<l; i++) {
2385 this.opcode('lookup', id.parts[i]);
2386 }
2387 },
2388
2389 DATA: function(data) {
2390 this.options.data = true;
2391 if (data.id.isScoped || data.id.depth) {
2392 throw new Exception('Scoped data references are not supported: ' + data.original);
2393 }
2394
2395 this.opcode('lookupData');
2396 var parts = data.id.parts;
2397 for(var i=0, l=parts.length; i<l; i++) {
2398 this.opcode('lookup', parts[i]);
2399 }
2400 },
2401
2402 STRING: function(string) {
2403 this.opcode('pushString', string.string);
2404 },
2405
2406 INTEGER: function(integer) {
2407 this.opcode('pushLiteral', integer.integer);
2408 },
2409
2410 BOOLEAN: function(bool) {
2411 this.opcode('pushLiteral', bool.bool);
2412 },
2413
2414 comment: function() {},
2415
2416 // HELPERS
2417 opcode: function(name) {
2418 this.opcodes.push({ opcode: name, args: [].slice.call(arguments, 1) });
2419 },
2420
2421 declare: function(name, value) {
2422 this.opcodes.push({ opcode: 'DECLARE', name: name, value: value });
2423 },
2424
2425 addDepth: function(depth) {
2426 if(isNaN(depth)) { throw new Error("EWOT"); }
2427 if(depth === 0) { return; }
2428
2429 if(!this.depths[depth]) {
2430 this.depths[depth] = true;
2431 this.depths.list.push(depth);
2432 }
2433 },
2434
2435 classifyMustache: function(mustache) {
2436 var isHelper = mustache.isHelper;
2437 var isEligible = mustache.eligibleHelper;
2438 var options = this.options;
2439
2440 // if ambiguous, we can possibly resolve the ambiguity now
2441 if (isEligible && !isHelper) {
2442 var name = mustache.id.parts[0];
2443
2444 if (options.knownHelpers[name]) {
2445 isHelper = true;
2446 } else if (options.knownHelpersOnly) {
2447 isEligible = false;
2448 }
2449 }
2450
2451 if (isHelper) { return "helper"; }
2452 else if (isEligible) { return "ambiguous"; }
2453 else { return "simple"; }
2454 },
2455
2456 pushParams: function(params) {
2457 var i = params.length, param;
2458
2459 while(i--) {
2460 param = params[i];
2461
2462 if(this.options.stringParams) {
2463 if(param.depth) {
2464 this.addDepth(param.depth);
2465 }
2466
2467 this.opcode('getContext', param.depth || 0);
2468 this.opcode('pushStringParam', param.stringModeValue, param.type);
2469 } else {
2470 this[param.type](param);
2471 }
2472 }
2473 },
2474
2475 setupMustacheParams: function(mustache) {
2476 var params = mustache.params;
2477 this.pushParams(params);
2478
2479 if(mustache.hash) {
2480 this.hash(mustache.hash);
2481 } else {
2482 this.opcode('emptyHash');
2483 }
2484
2485 return params;
2486 },
2487
2488 // this will replace setupMustacheParams when we're done
2489 setupFullMustacheParams: function(mustache, program, inverse) {
2490 var params = mustache.params;
2491 this.pushParams(params);
2492
2493 this.opcode('pushProgram', program);
2494 this.opcode('pushProgram', inverse);
2495
2496 if(mustache.hash) {
2497 this.hash(mustache.hash);
2498 } else {
2499 this.opcode('emptyHash');
2500 }
2501
2502 return params;
2503 }
2504 };
2505
2506 function precompile(input, options) {
2507 if (input == null || (typeof input !== 'string' && input.constructor !== AST.ProgramNode)) {
2508 throw new Exception("You must pass a string or Handlebars AST to Handlebars.precompile. You passed " + input);
2509 }
2510
2511 options = options || {};
2512 if (!('data' in options)) {
2513 options.data = true;
2514 }
2515
2516 var ast = parse(input);
2517 var environment = new Compiler().compile(ast, options);
2518 return new JavaScriptCompiler().compile(environment, options);
2519 }
2520
2521 __exports__.precompile = precompile;function compile(input, options, env) {
2522 if (input == null || (typeof input !== 'string' && input.constructor !== AST.ProgramNode)) {
2523 throw new Exception("You must pass a string or Handlebars AST to Handlebars.compile. You passed " + input);
2524 }
2525
2526 options = options || {};
2527
2528 if (!('data' in options)) {
2529 options.data = true;
2530 }
2531
2532 var compiled;
2533
2534 function compileInput() {
2535 var ast = parse(input);
2536 var environment = new Compiler().compile(ast, options);
2537 var templateSpec = new JavaScriptCompiler().compile(environment, options, undefined, true);
2538 return env.template(templateSpec);
2539 }
2540
2541 // Template is only compiled on first use and cached after that point.
2542 return function(context, options) {
2543 if (!compiled) {
2544 compiled = compileInput();
2545 }
2546 return compiled.call(this, context, options);
2547 };
2548 }
2549
2550 __exports__.compile = compile;
2551 return __exports__;
2552 })(__module5__, __module8__, __module11__, __module7__);
2553
2554 // handlebars.js
2555 var __module0__ = (function(__dependency1__, __dependency2__, __dependency3__, __dependency4__, __dependency5__) {
2556 "use strict";
2557 var __exports__;
2558 var Handlebars = __dependency1__;
2559
2560 // Compiler imports
2561 var AST = __dependency2__;
2562 var Parser = __dependency3__.parser;
2563 var parse = __dependency3__.parse;
2564 var Compiler = __dependency4__.Compiler;
2565 var compile = __dependency4__.compile;
2566 var precompile = __dependency4__.precompile;
2567 var JavaScriptCompiler = __dependency5__;
2568
2569 var _create = Handlebars.create;
2570 var create = function() {
2571 var hb = _create();
2572
2573 hb.compile = function(input, options) {
2574 return compile(input, options, hb);
2575 };
2576 hb.precompile = precompile;
2577
2578 hb.AST = AST;
2579 hb.Compiler = Compiler;
2580 hb.JavaScriptCompiler = JavaScriptCompiler;
2581 hb.Parser = Parser;
2582 hb.parse = parse;
2583
2584 return hb;
2585 };
2586
2587 Handlebars = create();
2588 Handlebars.create = create;
2589
2590 __exports__ = Handlebars;
2591 return __exports__;
2592 })(__module1__, __module7__, __module8__, __module10__, __module11__);
2593
2594 return __module0__;
2595 })();
1 (function(window, undefined) { 1 (function(window, undefined) {
2 var 2 var
3 Handlebars = this.Handlebars,
4 //manifestController = this.manifestController, 3 //manifestController = this.manifestController,
5 ParseStream = window.videojs.m3u8.ParseStream, 4 ParseStream = window.videojs.m3u8.ParseStream,
6 parseStream, 5 parseStream,
...@@ -566,566 +565,6 @@ ...@@ -566,566 +565,6 @@
566 notStrictEqual(parser, undefined, 'parser is defined'); 565 notStrictEqual(parser, undefined, 'parser is defined');
567 }); 566 });
568 567
569 test('should successfully parse manifest data', function() {
570 parser.push(window.playlistM3U8data);
571 ok(parser.manifest);
572 });
573
574 test('valid manifest should populate the manifest data object', function() {
575 parser.push(window.playlistM3U8data);
576
577 ok(parser.manifest, 'the manifest is parsed');
578 strictEqual(parser.manifest.targetDuration, 10, 'the manifest has correct TARGET DURATION');
579 strictEqual(parser.manifest.allowCache, true, 'allow-cache is defaulted to true');
580 strictEqual(parser.manifest.playlistType, 'VOD', 'playlist type is VOD');
581 strictEqual(parser.manifest.segments.length, 17, 'there are 17 segments in the manifest');
582 strictEqual(parser.manifest.mediaSequence, 0, 'MEDIA SEQUENCE is correct');
583 ok(!('duration' in parser.manifest), "no total duration is specified");
584 });
585
586 /*3.4.7. EXT-X-PLAYLIST-TYPE
587
588 The EXT-X-PLAYLIST-TYPE tag provides mutability information about the
589 Playlist file. It applies to the entire Playlist file. It is
590 OPTIONAL. Its format is:
591
592 #EXT-X-PLAYLIST-TYPE:<EVENT|VOD>
593
594 Section 6.2.1 defines the implications of the EXT-X-PLAYLIST-TYPE
595 tag.
596
597 The EXT-X-PLAYLIST-TYPE tag MUST NOT appear in a Master Playlist.
598 */
599
600 test('should have parsed VOD playlist type', function() {
601 var
602 playlistTemplate = Handlebars.compile(window.playlist_type_template),
603 testData = { playlistType: 'VOD' };
604 parser.push(playlistTemplate(testData));
605
606 notStrictEqual(parser.manifest, null, 'manifest is parsed');
607 //strictEqual(data.invalidReasons.length, 0, 'Errors object should not be empty.');
608 strictEqual(parser.manifest.playlistType, 'VOD', 'playlist type is vod');
609 });
610
611 test('should have parsed EVENT playlist type', function() {
612 var
613 playlistTemplate = Handlebars.compile(window.playlist_type_template),
614 testData = { playlistType: 'EVENT' };
615 parser.push(playlistTemplate(testData));
616
617 notStrictEqual(parser.manifest, null, 'manifest is parsed');
618 //strictEqual(data.invalidReasons.length, 0, 'Errors object should not be empty.');
619 strictEqual(parser.manifest.playlistType, 'EVENT', 'playlist type is event');
620 });
621
622 test('handles a missing playlist type', function() {
623 var
624 playlistTemplate = Handlebars.compile(window.playlist_type_template),
625 testData = {};
626 parser.push(playlistTemplate(testData));
627
628 //strictEqual(data.invalidReasons.length, 0, 'Errors object should not be empty.');
629 //strictEqual(data.warnings, 'EXT-X-PLAYLIST-TYPE was empty or missing. Assuming VOD');
630 strictEqual(parser.manifest.playlistType, 'VOD', 'playlist type defaults to vod');
631 });
632
633 test('should default invalid playlist types to vod', function() {
634 var
635 playlistTemplate = Handlebars.compile(window.playlist_type_template),
636 testData = { playlistType: 'baklsdhfajsdf' };
637 parser.push(playlistTemplate(testData));
638
639 strictEqual(parser.manifest.playlistType, 'VOD', 'invalid playlist types default to vod');
640 //strictEqual(data.invalidReasons.length, 1, 'data has 1 invalid reasons');
641 //strictEqual(data.invalidReasons[0], 'Invalid Playlist Type Value: \'baklsdhfajsdf\'');
642 });
643
644 test('handles an empty playlist type', function() {
645 var
646 playlistTemplate = Handlebars.compile(window.playlist_type_template),
647 testData = { playlistType: '' };
648 parser.push(playlistTemplate(testData));
649
650 //strictEqual(data.invalidReasons.length, 0, 'Errors object should not be empty.');
651 //strictEqual(data.warnings, 'EXT-X-PLAYLIST-TYPE was empty or missing. Assuming VOD');
652 strictEqual(parser.manifest.playlistType, 'VOD', 'playlist type defaults to vod');
653 });
654
655 /*3.4.2. EXT-X-TARGETDURATION
656
657 The EXT-X-TARGETDURATION tag specifies the maximum media segment
658 duration. The EXTINF duration of each media segment in the Playlist
659 file, when rounded to the nearest integer, MUST be less than or equal
660 to the target duration. This tag MUST appear once in a Media
661 Playlist file. It applies to the entire Playlist file. Its format
662 is:
663
664 #EXT-X-TARGETDURATION:<s>
665
666 where s is a decimal-integer indicating the target duration in
667 seconds.
668
669 The EXT-X-TARGETDURATION tag MUST NOT appear in a Master Playlist.
670 */
671
672 test('valid target duration', function() {
673 var
674 playlistTemplate = Handlebars.compile(window.playlist_target_duration_template),
675 testData = { targetDuration: '10' };
676 parser.push(playlistTemplate(testData));
677
678 strictEqual(parser.manifest.targetDuration, 10, 'manifest has correct TARGET DURATION');
679 //strictEqual(data.invalidReasons.length, 0, 'data has 1 invalid reasons');
680 });
681
682 test('NaN target duration', function() {
683 var
684 playlistTemplate = Handlebars.compile(window.playlist_target_duration_template),
685 testData = { targetDuration: 'string' };
686 parser.push(playlistTemplate(testData));
687
688 ok(!('targetDuration' in parser.manifest), 'target duration is not defined');
689 // notStrictEqual(data.invalidReasons, null, 'invalidReasons is not NULL');
690 // strictEqual(data.invalidReasons.length, 1, 'data has 0 invalid reasons');
691 // strictEqual(data.invalidReasons[0], 'Invalid Target Duration Value: \'NaN\'');
692 });
693
694 test('empty target duration', function() {
695 var
696 playlistTemplate = Handlebars.compile(window.playlist_target_duration_template),
697 testData = { targetDuration: '\'\'' };
698 parser.push(playlistTemplate(testData));
699
700 ok(!('targetDuration' in parser.manifest), 'target duration is not defined');
701 // notStrictEqual(data.invalidReasons, null, 'invalidReasons is not NULL');
702 // strictEqual(data.invalidReasons.length, 1, 'data has 1 invalid reasons');
703 // strictEqual(data.invalidReasons[0], 'Invalid Target Duration Value: \'NaN\'');
704 });
705
706 test('empty target duration', function() {
707 var
708 playlistTemplate = Handlebars.compile(window.playlist_target_duration_template);
709 parser.push(playlistTemplate({}));
710
711 ok(!('targetDuration' in parser.manifest), 'target duration is not defined');
712 // notStrictEqual(data.invalidReasons, null, 'invalidReasons is not NULL');
713 // strictEqual(data.invalidReasons.length, 1, 'data has 1 invalid reasons');
714 // strictEqual(data.invalidReasons[0], 'Invalid Target Duration Value: \'what\'');
715 });
716
717 /*3.4.3. EXT-X-MEDIA-SEQUENCE
718
719 Each media segment in a Playlist has a unique integer sequence
720 number. The sequence number of a segment is equal to the sequence
721 number of the segment that preceded it plus one. The EXT-X-MEDIA-
722 SEQUENCE tag indicates the sequence number of the first segment that
723 appears in a Playlist file. Its format is:
724
725 #EXT-X-MEDIA-SEQUENCE:<number>
726
727 where number is a decimal-integer. The sequence number MUST NOT
728 decrease.
729
730 A Media Playlist file MUST NOT contain more than one EXT-X-MEDIA-
731 SEQUENCE tag. If the Media Playlist file does not contain an EXT-X-
732 MEDIA-SEQUENCE tag then the sequence number of the first segment in
733 the playlist SHALL be considered to be 0. A client MUST NOT assume
734 that segments with the same sequence number in different Media
735 Playlists contain matching content.
736
737 A media URI is not required to contain its sequence number.
738 */
739
740 test('media sequence is valid in the playlist', function() {
741 var
742 playlistTemplate = Handlebars.compile(window.playlist_media_sequence_template),
743 testData = { mediaSequence: '0' };
744 parser.push(playlistTemplate(testData));
745
746 // notStrictEqual(data.invalidReasons, null, 'invalidReasons is not NULL');
747 // strictEqual(data.invalidReasons.length, 0, 'Errors object should not be empty.');
748 strictEqual(parser.manifest.mediaSequence, 0, 'MEDIA SEQUENCE is zero');
749 });
750
751 test('media sequence is encountered twice in the playlist', function() {
752 var
753 playlistTemplate = Handlebars.compile(window.playlist_media_sequence_template),
754 testData = {
755 mediaSequence: '0',
756 mediaSequence1: '1'
757 };
758 parser.push(playlistTemplate(testData));
759
760 // notStrictEqual(data.invalidReasons, null, 'invalidReasons is not NULL');
761 // strictEqual(data.invalidReasons.length, 0, 'Errors object should not be empty.');
762 strictEqual(parser.manifest.mediaSequence,
763 1,
764 'the most recently encountered media sequence is stored');
765 });
766
767 test('media sequence is zero if not present in media playlists', function() {
768 var playlistTemplate = Handlebars.compile(window.playlist_media_sequence_template);
769 parser.push(playlistTemplate({}));
770
771 // notStrictEqual(data.invalidReasons, null, 'invalidReasons is not NULL');
772 // strictEqual(data.invalidReasons.length, 0, 'Errors object should not be empty.');
773 strictEqual(parser.manifest.mediaSequence, 0, 'mediaSequence is defaulted to zero');
774 });
775
776 test('empty media sequence numbers is ignored in media playlists', function() {
777 var
778 playlistTemplate = Handlebars.compile(window.playlist_media_sequence_template),
779 testData = { mediaSequence: '' };
780 parser.push(playlistTemplate(testData));
781
782 // notStrictEqual(data.invalidReasons, null, 'invalidReasons is not NULL');
783 // strictEqual(data.invalidReasons.length, 1, 'data has 1 invalid reasons');
784 strictEqual(parser.manifest.mediaSequence,
785 0,
786 'empty media sequences are defaulted');
787 });
788
789 test('handles invalid media sequence numbers in the playlist', function() {
790 var
791 playlistTemplate = Handlebars.compile(window.playlist_media_sequence_template),
792 testData = { mediaSequence: '-1' };
793 parser.push(playlistTemplate(testData));
794
795 // notStrictEqual(data.invalidReasons, null, 'invalidReasons is not NULL');
796 // strictEqual(data.invalidReasons.length, 1, 'data has 1 invalid reasons');
797 // strictEqual(data.invalidReasons[0], 'Invalid Media Sequence Value: \'-1\'');
798 strictEqual(parser.manifest.mediaSequence,
799 -1,
800 'negative media sequence numbers are parsed');
801 });
802
803 test('invalid media sequences are defaulted', function() {
804 var
805 playlistTemplate = Handlebars.compile(window.playlist_media_sequence_template),
806 testData = {
807 mediaSequence: 'asdfkasdkfl'
808 };
809 parser.push(playlistTemplate(testData));
810
811 strictEqual(parser.manifest.mediaSequence, 0, 'invalid media sequences default to zero');
812 // notStrictEqual(data.invalidReasons, null, 'invalidReasons is not NULL');
813 // strictEqual(data.invalidReasons.length, 1, 'data has 1 invalid reasons');
814 // strictEqual(data.invalidReasons[0], 'Invalid Media Sequence Value: \'asdfkasdkfl\'');
815 });
816
817 module('Representative Playlist', {
818 setup: function() {
819 parser = new Parser();
820 },
821 teardown: function() {
822 parser = null;
823 }
824 });
825
826 test('should parse real manifest data', function() {
827 parser.push(window.brightcove_playlist_data);
828 parser.end();
829
830 ok(parser.manifest, 'a manifest is parsed');
831 ok(!('segments' in parser.manifest), 'no segments should be parsed');
832 strictEqual(parser.manifest.playlists.length, 4, 'has correct playlist count');
833 strictEqual(parser.manifest.playlists[0].attributes.BANDWIDTH, 240000, 'first rendition index bandwidth is correct');
834 strictEqual(parser.manifest.playlists[0].attributes['PROGRAM-ID'], 1, 'first rendition index program-id is correct');
835 strictEqual(parser.manifest.playlists[0].attributes.RESOLUTION.width,
836 396,
837 'first rendition index resolution width is correct');
838 strictEqual(parser.manifest.playlists[0].attributes.RESOLUTION.height,
839 224,
840 'first rendition index resolution height is correct');
841
842 });
843
844 /*3.3.2. EXTINF
845
846 The EXTINF tag specifies the duration of a media segment. It applies
847 only to the media segment that follows it, and MUST be followed by a
848 media segment URI. Each media segment MUST be preceded by an EXTINF
849 tag. Its format is:
850
851 #EXTINF:<duration>,<title>
852
853 where duration is an decimal-integer or decimal-floating-point number
854 that specifies the duration of the media segment in seconds.
855 Durations that are reported as integers SHOULD be rounded to the
856 nearest integer. Durations MUST be integers if the protocol version
857 of the Playlist file is less than 3. Durations SHOULD be floating-
858 point if the version is equal to or greater than 3. The remainder of
859 the line following the comma is an optional human-readable
860 informative title of the media segment.
861
862 The EXTINF duration of each media segment in the Playlist
863 file, when rounded to the nearest integer, MUST be less than or equal
864 to the target duration.
865 */
866
867 test('test valid extinf values in playlist', function() {
868 var
869 playlistTemplate = Handlebars.compile(window.playlist_extinf_template),
870 testData = {
871 version: 4,
872 extInf: '10',
873 extInf1: '10',
874 extInf2: '10',
875 segment: 'hls_450k_video.ts'
876 };
877 parser.push(playlistTemplate(testData));
878
879 strictEqual(parser.manifest.segments.length, 17, 'the number of playlists is inferred');
880 strictEqual(parser.manifest.segments[0].duration,
881 10,
882 'the first playlist duration is parsed');
883 strictEqual(parser.manifest.segments[1].duration,
884 10,
885 'the second playlist duration is parsed');
886 strictEqual(parser.manifest.segments[2].duration,
887 10,
888 'the third playlist duration is parsed');
889 strictEqual(parser.manifest.segments[3].duration,
890 10,
891 'the fourth playlist duration is parsed');
892 // notStrictEqual(data.invalidReasons, null, 'invalidReasons is not NULL');
893 // strictEqual(data.invalidReasons.length, 0, 'Errors object should not be empty.');
894 });
895
896 test('the last encountered extinf tag before a segment takes precedance', function() {
897 var
898 playlistTemplate = Handlebars.compile(window.playlist_extinf_template),
899 testData = {
900 version: 4,
901 extInf: '1',
902 extInf1: '2',
903 extInf2: '3'
904 };
905 parser.push(playlistTemplate(testData));
906
907 strictEqual(parser.manifest.segments[0].duration,
908 2,
909 'the most recent duration is stored');
910 });
911
912 //
913 test('ignore invalid extinf values', function() {
914 var
915 playlistTemplate = Handlebars.compile(window.playlist_extinf_template),
916 testData = {
917 version: 4,
918 extInf: 'asdf',
919 extInf1: '10',
920 extInf2: '10',
921 segment: 'hls_450k_video.ts'
922 };
923 parser.push(playlistTemplate(testData));
924
925 ok(!('duration' in parser.manifest.segments[0]), 'invalid durations are ignored');
926 // notStrictEqual(data.invalidReasons, null, 'invalidReasons is not NULL');
927 // strictEqual(data.invalidReasons.length, 1, 'data has 1 invalid reasons');
928 });
929
930 //its best practice that every extinf have the same value, but its not required
931 test('test inconsistent extinf values in playlist below target duration', function() {
932 var
933 playlistTemplate = Handlebars.compile(window.playlist_extinf_template),
934 testData = {
935 version: 4,
936 extInf: '10',
937 extInf1: '7',
938 extInf2: '10',
939 segment: 'hls_450k_video.ts'
940 };
941 parser.push(playlistTemplate(testData));
942
943 strictEqual(parser.manifest.segments[0].duration,
944 10,
945 'the first duration is parsed');
946 strictEqual(parser.manifest.segments[1].duration,
947 7,
948 'the second duration is parsed');
949 strictEqual(parser.manifest.segments[2].duration,
950 10,
951 'the third duration is parsed');
952 // notStrictEqual(data.invalidReasons, null, 'invalidReasons is not NULL');
953 // strictEqual(data.invalidReasons.length, 0, 'Errors object should not be empty.');
954 });
955
956 //extinf values must be below the target duration
957 test('test floating-point values are accepted with version 3', function() {
958 var
959 playlistTemplate = Handlebars.compile(window.playlist_extinf_template),
960 testData = {
961 version: 3,
962 extInf: '10.5',
963 extInf1: '10.5',
964 extInf2: '10.5',
965 segment: 'hls_450k_video.ts'
966 };
967 parser.push(playlistTemplate(testData));
968
969 strictEqual(parser.manifest.segments[0].duration, 10.5, 'fractional durations are parsed');
970 // notStrictEqual(data.invalidReasons, null, 'invalidReasons is not NULL');
971 // strictEqual(data.invalidReasons.length, 1, 'data has 1 invalid reasons');
972 // strictEqual(data.invalidReasons[0], 'Invalid Segment Data: \'#EXTINF value not an integer\'');
973 });
974
975 //extinf values must be below the target duration
976 test('test empty EXTINF values', function() {
977 var
978 playlistTemplate = Handlebars.compile(window.playlist_extinf_template),
979 testData = {
980 version: 4,
981 extInf: '',
982 extInf1: '10.5',
983 extInf2: '10.5',
984 segment: 'hls_450k_video.ts'
985 };
986 parser.push(playlistTemplate(testData));
987
988 ok(!('duration' in parser.manifest.segments[0]), 'empty durations are ignored');
989 // notStrictEqual(data.invalidReasons, null, 'invalidReasons is not NULL');
990 // strictEqual(data.invalidReasons.length, 1, 'data has 1 invalid reasons');
991 // strictEqual(data.invalidReasons[0], 'Invalid Segment Data: \'#EXTINF value empty\'');
992 });
993
994 /*
995 3.3.6. EXT-X-ALLOW-CACHE
996
997 The EXT-X-ALLOW-CACHE tag indicates whether the client MAY or MUST
998 NOT cache downloaded media segments for later replay. It MAY occur
999 anywhere in the Playlist file; it MUST NOT occur more than once. The
1000 EXT-X-ALLOW-CACHE tag applies to all segments in the playlist. Its
1001 format is:
1002
1003 #EXT-X-ALLOW-CACHE:<YES|NO>
1004 */
1005
1006 test('test EXT-X-ALLOW-CACHE YES', function() {
1007 var
1008 playlistTemplate = Handlebars.compile(window.playlist_allow_cache),
1009 testData = { version: 4, allowCache: 'YES' };
1010 parser.push(playlistTemplate(testData));
1011
1012 // notStrictEqual(data.invalidReasons, null, 'invalidReasons is not NULL');
1013 // strictEqual(data.invalidReasons.length, 0, 'Errors object should not be empty.');
1014 strictEqual(parser.manifest.allowCache, true, 'allowCache is true');
1015 });
1016
1017 test('test EXT-X-ALLOW-CACHE NO', function() {
1018 var
1019 playlistTemplate = Handlebars.compile(window.playlist_allow_cache),
1020 testData = {
1021 version: 4,
1022 allowCache: 'NO'
1023 };
1024 parser.push(playlistTemplate(testData));
1025
1026 // notStrictEqual(data.invalidReasons, null, 'invalidReasons is not NULL');
1027 // strictEqual(data.invalidReasons.length, 0, 'Errors object should not be empty.');
1028 strictEqual(parser.manifest.allowCache, false, 'allowCache is false');
1029 });
1030
1031 test('test EXT-X-ALLOW-CACHE invalid, default to YES', function() {
1032 var
1033 playlistTemplate = Handlebars.compile(window.playlist_allow_cache),
1034 testData = {
1035 version: 4,
1036 allowCache: 'YESTERDAYNO'
1037 };
1038 parser.push(playlistTemplate(testData));
1039
1040 // notStrictEqual(data.invalidReasons, null, 'invalidReasons is not NULL');
1041 // strictEqual(data.invalidReasons.length, 1, 'data has 1 invalid reasons');
1042 // strictEqual(data.invalidReasons[0], 'Invalid EXT-X-ALLOW-CACHE value: \'YESTERDAYNO\'');
1043 strictEqual(parser.manifest.allowCache, true, 'allowCache defaults to true');
1044 });
1045
1046 test('empty EXT-X-ALLOW-CACHE defaults to YES', function() {
1047 var
1048 playlistTemplate = Handlebars.compile(window.playlist_allow_cache),
1049 testData = {
1050 version: 4,
1051 allowCache: ''
1052 };
1053 parser.push(playlistTemplate(testData));
1054
1055 // notStrictEqual(data.invalidReasons, null, 'invalidReasons is not NULL');
1056 // strictEqual(data.invalidReasons.length, 1, 'data has 1 invalid reasons');
1057 // strictEqual(data.invalidReasons[0], 'Invalid EXT-X-ALLOW-CACHE value: \'\'');
1058 strictEqual(parser.manifest.allowCache, true, 'allowCache should default to YES.');
1059 });
1060
1061 test('missing EXT-X-ALLOW-CACHE defaults to YES', function() {
1062 var
1063 playlistTemplate = Handlebars.compile(window.playlist_allow_cache),
1064 testData = {version: 4};
1065 parser.push(playlistTemplate(testData));
1066
1067 // notStrictEqual(data.invalidReasons, null, 'invalidReasons is not NULL');
1068 // strictEqual(data.invalidReasons.length, 1, 'No EXT-X-ALLOW-CACHE specified. Default: YES.');
1069 strictEqual(parser.manifest.allowCache, true, 'allowCache should default to YES');
1070 });
1071
1072 test('valid byteranges are parsed', function() {
1073 var
1074 playlistTemplate = Handlebars.compile(window.playlist_byte_range),
1075 testData = {
1076 version: 4,
1077 byteRange: '522828@0',
1078 byteRange1: '587500@522828',
1079 byteRange2: '44556@8353216'
1080 };
1081 parser.push(playlistTemplate(testData));
1082
1083 //notStrictEqual(data.invalidReasons, null, 'invalidReasons is not NULL');
1084 //strictEqual(data.invalidReasons.length, 0, 'Errors object should be empty.');
1085 //TODO: Validate the byteRange info
1086 strictEqual(parser.manifest.segments.length,
1087 17,
1088 '17 segments should have been parsed.');
1089 strictEqual(parser.manifest.segments[0].byterange.length,
1090 522828,
1091 'byteRange length incorrect');
1092 strictEqual(parser.manifest.segments[0].byterange.offset,
1093 0,
1094 'byteRange offset incorrect');
1095 strictEqual(parser.manifest.segments[1].byterange.length,
1096 587500,
1097 'byteRange length incorrect');
1098 strictEqual(parser.manifest.segments[1].byterange.offset,
1099 522828,
1100 'byteRange offset incorrect');
1101 });
1102
1103 test('EXT-X-BYTERANGE used but version is < 4', function() {
1104 var
1105 playlistTemplate = Handlebars.compile(window.playlist_byte_range),
1106 testData = {
1107 version: 3,
1108 // incorrect syntax, '@' is the offset separator
1109 byteRange: '522828,0',
1110 byteRange1: '587500,522828',
1111 byteRange2: '44556,8353216'
1112 };
1113 parser.push(playlistTemplate(testData));
1114
1115 strictEqual(parser.manifest.segments.length,
1116 17,
1117 '17 segments should have been parsed.');
1118 strictEqual(parser.manifest.segments[0].byterange.length,
1119 522828,
1120 'the byterange length was parsed');
1121 strictEqual(parser.manifest.segments[0].byterange.offset,
1122 0,
1123 'the byterange offset was parsed');
1124 strictEqual(parser.manifest.segments[1].byterange.offset,
1125 0,
1126 'the byterange offset was defaulted');
1127 });
1128
1129 module('m3u8s'); 568 module('m3u8s');
1130 569
1131 test('parses the example manifests as expected', function() { 570 test('parses the example manifests as expected', function() {
......
1 {
2 "targetDuration": 10,
3 "allowCache": true,
4 "mediaSequence": 0,
5 "playlistType": "VOD",
6 "segments": [{
7 "duration": 10,
8 "byterange": {
9 "length": 522828,
10 "offset": 0
11 },
12 "uri": "hls_450k_video.ts"
13 }, {
14 "duration": 10,
15 "byterange": {
16 "length": 587500,
17 "offset": 522828
18 },
19 "uri": "hls_450k_video.ts"
20 }, {
21 "duration": 10,
22 "byterange": {
23 "length": 713084,
24 "offset": 1110328
25 },
26 "uri": "hls_450k_video.ts"
27 }, {
28 "duration": 10,
29 "byterange": {
30 "length": 476580,
31 "offset": 1823412
32 },
33 "uri": "hls_450k_video.ts"
34 }, {
35 "duration": 10,
36 "byterange": {
37 "length": 535612,
38 "offset": 2299992
39 },
40 "uri": "hls_450k_video.ts"
41 }, {
42 "duration": 10,
43 "byterange": {
44 "length": 207176,
45 "offset": 2835604
46 },
47 "uri": "hls_450k_video.ts"
48 }, {
49 "duration": 10,
50 "byterange": {
51 "length": 455900,
52 "offset": 3042780
53 },
54 "uri": "hls_450k_video.ts"
55 }, {
56 "duration": 10,
57 "byterange": {
58 "length": 657248,
59 "offset": 3498680
60 },
61 "uri": "hls_450k_video.ts"
62 }, {
63 "duration": 10,
64 "byterange": {
65 "length": 571708,
66 "offset": 4155928
67 },
68 "uri": "hls_450k_video.ts"
69 }, {
70 "duration": 10,
71 "byterange": {
72 "length": 485040,
73 "offset": 4727636
74 },
75 "uri": "hls_450k_video.ts"
76 }, {
77 "duration": 10,
78 "byterange": {
79 "length": 709136,
80 "offset": 5212676
81 },
82 "uri": "hls_450k_video.ts"
83 }, {
84 "duration": 10,
85 "byterange": {
86 "length": 730004,
87 "offset": 5921812
88 },
89 "uri": "hls_450k_video.ts"
90 }, {
91 "duration": 10,
92 "byterange": {
93 "length": 456276,
94 "offset": 6651816
95 },
96 "uri": "hls_450k_video.ts"
97 }, {
98 "duration": 10,
99 "byterange": {
100 "length": 468684,
101 "offset": 7108092
102 },
103 "uri": "hls_450k_video.ts"
104 }, {
105 "duration": 10,
106 "byterange": {
107 "length": 444996,
108 "offset": 7576776
109 },
110 "uri": "hls_450k_video.ts"
111 }, {
112 "duration": 10,
113 "byterange": {
114 "length": 331444,
115 "offset": 8021772
116 },
117 "uri": "hls_450k_video.ts"
118 }, {
119 "duration": 1.4167,
120 "byterange": {
121 "length": 44556,
122 "offset": 8353216
123 },
124 "uri": "hls_450k_video.ts"
125 }]
126 }
1 #EXTM3U
2 #EXT-X-TARGETDURATION:10
3 #EXT-X-VERSION:4
4 #EXT-X-ALLOW-CACHE:YES
5 #EXT-X-MEDIA-SEQUENCE:0
6 #EXT-X-PLAYLIST-TYPE:VOD
7 #EXTINF:10,
8 #EXT-X-BYTERANGE:522828@0
9 hls_450k_video.ts
10 #EXTINF:10,
11 #EXT-X-BYTERANGE:587500@522828
12 hls_450k_video.ts
13 #EXTINF:10,
14 #EXT-X-BYTERANGE:713084@1110328
15 hls_450k_video.ts
16 #EXTINF:10,
17 #EXT-X-BYTERANGE:476580@1823412
18 hls_450k_video.ts
19 #EXTINF:10,
20 #EXT-X-BYTERANGE:535612@2299992
21 hls_450k_video.ts
22 #EXTINF:10,
23 #EXT-X-BYTERANGE:207176@2835604
24 hls_450k_video.ts
25 #EXTINF:10,
26 #EXT-X-BYTERANGE:455900@3042780
27 hls_450k_video.ts
28 #EXTINF:10,
29 #EXT-X-BYTERANGE:657248@3498680
30 hls_450k_video.ts
31 #EXTINF:10,
32 #EXT-X-BYTERANGE:571708@4155928
33 hls_450k_video.ts
34 #EXTINF:10,
35 #EXT-X-BYTERANGE:485040@4727636
36 hls_450k_video.ts
37 #EXTINF:10,
38 #EXT-X-BYTERANGE:709136@5212676
39 hls_450k_video.ts
40 #EXTINF:10,
41 #EXT-X-BYTERANGE:730004@5921812
42 hls_450k_video.ts
43 #EXTINF:10,
44 #EXT-X-BYTERANGE:456276@6651816
45 hls_450k_video.ts
46 #EXTINF:10,
47 #EXT-X-BYTERANGE:468684@7108092
48 hls_450k_video.ts
49 #EXTINF:10,
50 #EXT-X-BYTERANGE:444996@7576776
51 hls_450k_video.ts
52 #EXTINF:10,
53 #EXT-X-BYTERANGE:331444@8021772
54 hls_450k_video.ts
55 #EXTINF:1.4167,
56 #EXT-X-BYTERANGE:44556@8353216
57 hls_450k_video.ts
58 #EXT-X-ENDLIST
...\ No newline at end of file ...\ No newline at end of file
1 window.brightcove_playlist_data = '#EXTM3U\n'+
2 '#EXT-X-STREAM-INF:PROGRAM-ID=1,BANDWIDTH=240000,RESOLUTION=396x224\n'+
3 'http://c.brightcove.com/services/mobile/streaming/index/rendition.m3u8?assetId=1824686811001&videoId=1824650741001\n'+
4 '#EXT-X-STREAM-INF:PROGRAM-ID=1,BANDWIDTH=40000\n'+
5 'http://c.brightcove.com/services/mobile/streaming/index/rendition.m3u8?assetId=1824683759001&videoId=1824650741001\n'+
6 '#EXT-X-STREAM-INF:PROGRAM-ID=1,BANDWIDTH=440000,RESOLUTION=396x224\n'+
7 'http://c.brightcove.com/services/mobile/streaming/index/rendition.m3u8?assetId=1824686593001&videoId=1824650741001\n'+
8 '#EXT-X-STREAM-INF:PROGRAM-ID=1,BANDWIDTH=1928000,RESOLUTION=960x540\n'+
9 'http://c.brightcove.com/services/mobile/streaming/index/rendition.m3u8?assetId=1824687660001&videoId=1824650741001';
1 {
2 "allowCache": true,
3 "targetDuration": 10,
4 "mediaSequence": 0,
5 "playlistType": "VOD",
6 "segments": [{
7 "duration": 10,
8 "uri": "hls_450k_video.ts"
9 }, {
10 "duration": 10,
11 "byterange": {
12 "length": 587500,
13 "offset": 522828
14 },
15 "uri": "hls_450k_video.ts"
16 }, {
17 "duration": 10,
18 "byterange": {
19 "length": 713084,
20 "offset": 0
21 },
22 "uri": "hls_450k_video2.ts"
23 }, {
24 "duration": 10,
25 "byterange": {
26 "length": 476580,
27 "offset": 1823412
28 },
29 "uri": "hls_450k_video.ts"
30 }, {
31 "duration": 10,
32 "byterange": {
33 "length": 535612,
34 "offset": 2299992
35 },
36 "uri": "hls_450k_video.ts"
37 }, {
38 "duration": 10,
39 "byterange": {
40 "length": 207176,
41 "offset": 2835604
42 },
43 "uri": "hls_450k_video.ts"
44 }, {
45 "duration": 10,
46 "byterange": {
47 "length": 455900,
48 "offset": 3042780
49 },
50 "uri": "hls_450k_video.ts"
51 }, {
52 "duration": 10,
53 "byterange": {
54 "length": 657248,
55 "offset": 3498680
56 },
57 "uri": "hls_450k_video.ts"
58 }, {
59 "duration": 10,
60 "byterange": {
61 "length": 571708,
62 "offset": 4155928
63 },
64 "uri": "hls_450k_video.ts"
65 }, {
66 "duration": 10,
67 "byterange": {
68 "length": 485040,
69 "offset": 4727636
70 },
71 "uri": "hls_450k_video.ts"
72 }, {
73 "duration": 10,
74 "byterange": {
75 "length": 709136,
76 "offset": 5212676
77 },
78 "uri": "hls_450k_video.ts"
79 }, {
80 "duration": 10,
81 "byterange": {
82 "length": 730004,
83 "offset": 5921812
84 },
85 "uri": "hls_450k_video.ts"
86 }, {
87 "duration": 10,
88 "byterange": {
89 "length": 456276,
90 "offset": 6651816
91 },
92 "uri": "hls_450k_video.ts"
93 }, {
94 "duration": 10,
95 "byterange": {
96 "length": 468684,
97 "offset": 7108092
98 },
99 "uri": "hls_450k_video.ts"
100 }, {
101 "duration": 10,
102 "byterange": {
103 "length": 444996,
104 "offset": 7576776
105 },
106 "uri": "hls_450k_video.ts"
107 }, {
108 "duration": 10,
109 "byterange": {
110 "length": 331444,
111 "offset": 8021772
112 },
113 "uri": "hls_450k_video.ts"
114 }, {
115 "duration": 1.4167,
116 "byterange": {
117 "length": 44556,
118 "offset": 8353216
119 },
120 "uri": "hls_450k_video.ts"
121 }]
122 }
1 #EXTM3U
2 #EXT-X-TARGETDURATION:10
3 #EXT-X-VERSION:3
4 #EXT-X-MEDIA-SEQUENCE:0
5 #EXT-X-PLAYLIST-TYPE:VOD
6 #EXTINF:10,
7 hls_450k_video.ts
8 #EXTINF:10,
9 #EXT-X-BYTERANGE:587500@522828
10 hls_450k_video.ts
11 #EXTINF:10,
12 #EXT-X-BYTERANGE:713084
13 hls_450k_video2.ts
14 #EXTINF:10,
15 #EXT-X-BYTERANGE:476580@1823412
16 hls_450k_video.ts
17 #EXTINF:10,
18 #EXT-X-BYTERANGE:535612@2299992
19 hls_450k_video.ts
20 #EXTINF:10,
21 #EXT-X-BYTERANGE:207176@2835604
22 hls_450k_video.ts
23 #EXTINF:10,
24 #EXT-X-BYTERANGE:455900@3042780
25 hls_450k_video.ts
26 #EXTINF:10,
27 #EXT-X-BYTERANGE:657248@3498680
28 hls_450k_video.ts
29 #EXTINF:10,
30 #EXT-X-BYTERANGE:571708@4155928
31 hls_450k_video.ts
32 #EXTINF:10,
33 #EXT-X-BYTERANGE:485040@4727636
34 hls_450k_video.ts
35 #EXTINF:10,
36 #EXT-X-BYTERANGE:709136@5212676
37 hls_450k_video.ts
38 #EXTINF:10,
39 #EXT-X-BYTERANGE:730004@5921812
40 hls_450k_video.ts
41 #EXTINF:10,
42 #EXT-X-BYTERANGE:456276@6651816
43 hls_450k_video.ts
44 #EXTINF:10,
45 #EXT-X-BYTERANGE:468684@7108092
46 hls_450k_video.ts
47 #EXTINF:10,
48 #EXT-X-BYTERANGE:444996@7576776
49 hls_450k_video.ts
50 #EXTINF:10,
51 #EXT-X-BYTERANGE:331444@8021772
52 hls_450k_video.ts
53 #EXTINF:1.4167,
54 #EXT-X-BYTERANGE:44556@8353216
55 hls_450k_video.ts
56 #EXT-X-ENDLIST
...\ No newline at end of file ...\ No newline at end of file
1 {
2 "targetDuration": 10,
3 "allowCache": false,
4 "mediaSequence": 0,
5 "playlistType": "VOD",
6 "segments": [{
7 "duration": 10,
8 "byterange": {
9 "length": 522828,
10 "offset": 0
11 },
12 "uri": "hls_450k_video.ts"
13 }]
14 }
1 #EXTM3U
2 #EXT-X-TARGETDURATION:10
3 #EXT-X-VERSION:4
4 #EXT-X-ALLOW-CACHE:NO
5 #EXT-X-MEDIA-SEQUENCE:0
6 #EXT-X-PLAYLIST-TYPE:VOD
7 #EXTINF:10,
8 #EXT-X-BYTERANGE:522828@0
9 hls_450k_video.ts
10 #EXT-X-ENDLIST
...\ No newline at end of file ...\ No newline at end of file
1 {
2 "targetDuration": 10,
3 "allowCache": true,
4 "mediaSequence": 0,
5 "playlistType": "VOD",
6 "segments": [{
7 "duration": 10,
8 "byterange": {
9 "length": 522828,
10 "offset": 0
11 },
12 "uri": "hls_450k_video.ts"
13 }]
14 }
1 #EXTM3U
2 #EXT-X-TARGETDURATION:10
3 #EXT-X-VERSION:4
4 #EXT-X-ALLOW-CACHE:
5 #EXT-X-MEDIA-SEQUENCE:0
6 #EXT-X-PLAYLIST-TYPE:VOD
7 #EXTINF:10,
8 #EXT-X-BYTERANGE:522828@0
9 hls_450k_video.ts
10 #EXT-X-ENDLIST
...\ No newline at end of file ...\ No newline at end of file
1 {
2 "allowCache": true,
3 "mediaSequence": 0,
4 "playlistType": "VOD",
5 "targetDuration": 8,
6 "segments": [{
7 "duration": 6.64,
8 "uri": "/test/ts-files/tvy7/8a5e2822668b5370f4eb1438b2564fb7ab12ffe1-hi720.ts"
9 }, {
10 "duration": 6.08,
11 "uri": "/test/ts-files/tvy7/56be1cef869a1c0cc8e38864ad1add17d187f051-hi720.ts"
12 }, {
13 "duration": 6.6,
14 "uri": "/test/ts-files/tvy7/549c8c77f55f049741a06596e5c1e01dacaa46d0-hi720.ts"
15 }, {
16 "duration": 5,
17 "uri": "/test/ts-files/tvy7/6cfa378684ffeb1c455a64dae6c103290a1f53d4-hi720.ts"
18 }]
19 }
1 #EXTM3U
2 #EXT-X-PLAYLIST-TYPE:VOD
3 #EXT-X-MEDIA-SEQUENCE:
4 #EXT-X-ALLOW-CACHE:YES
5 #EXT-X-TARGETDURATION:8
6 #EXTINF:6.640,{}
7 /test/ts-files/tvy7/8a5e2822668b5370f4eb1438b2564fb7ab12ffe1-hi720.ts
8 #EXTINF:6.080,{}
9 /test/ts-files/tvy7/56be1cef869a1c0cc8e38864ad1add17d187f051-hi720.ts
10 #EXTINF:6.600,{}
11 /test/ts-files/tvy7/549c8c77f55f049741a06596e5c1e01dacaa46d0-hi720.ts
12 #EXTINF:5.000,{}
13 /test/ts-files/tvy7/6cfa378684ffeb1c455a64dae6c103290a1f53d4-hi720.ts
14 #EXT-X-ENDLIST
1 {
2 "allowCache": true,
3 "targetDuration": 10,
4 "mediaSequence": 0,
5 "playlistType": "VOD",
6 "segments": [{
7 "duration": 10,
8 "uri": "/test/ts-files/zencoder/haze/Haze_Mantel_President_encoded_1200-00001.ts"
9 }, {
10 "duration": 10,
11 "uri": "/test/ts-files/zencoder/haze/Haze_Mantel_President_encoded_1200-00002.ts"
12 }, {
13 "duration": 10,
14 "uri": "/test/ts-files/zencoder/haze/Haze_Mantel_President_encoded_1200-00003.ts"
15 }, {
16 "duration": 10,
17 "uri": "/test/ts-files/zencoder/haze/Haze_Mantel_President_encoded_1200-00004.ts"
18 }, {
19 "duration": 10,
20 "uri": "/test/ts-files/zencoder/haze/Haze_Mantel_President_encoded_1200-00005.ts"
21 }, {
22 "duration": 8,
23 "uri": "/test/ts-files/zencoder/haze/Haze_Mantel_President_encoded_1200-00006.ts"
24 }]
25 }
1 #EXTM3U
2 #EXT-X-PLAYLIST-TYPE:
3 #EXT-X-TARGETDURATION:10
4 #EXTINF:10,
5 /test/ts-files/zencoder/haze/Haze_Mantel_President_encoded_1200-00001.ts
6 #EXTINF:10,
7 /test/ts-files/zencoder/haze/Haze_Mantel_President_encoded_1200-00002.ts
8 #EXTINF:10,
9 /test/ts-files/zencoder/haze/Haze_Mantel_President_encoded_1200-00003.ts
10 #EXTINF:10,
11 /test/ts-files/zencoder/haze/Haze_Mantel_President_encoded_1200-00004.ts
12 #EXTINF:10,
13 /test/ts-files/zencoder/haze/Haze_Mantel_President_encoded_1200-00005.ts
14 #EXTINF:8,
15 /test/ts-files/zencoder/haze/Haze_Mantel_President_encoded_1200-00006.ts
16 #ZEN-TOTAL-DURATION:57.9911
17 #EXT-X-ENDLIST
1 {
2 "allowCache": true,
3 "playlists": [{
4 "attributes": {
5 "PROGRAM-ID": 1,
6 "BANDWIDTH": 240000,
7 "RESOLUTION": {
8 "width": 396,
9 "height": 224
10 }
11 },
12 "uri": "http://c.brightcove.com/services/mobile/streaming/index/rendition.m3u8?assetId=1824686811001&videoId=1824650741001"
13 }, {
14 "attributes": {
15 "PROGRAM-ID": 1,
16 "BANDWIDTH": 40000
17 },
18 "uri": "http://c.brightcove.com/services/mobile/streaming/index/rendition.m3u8?assetId=1824683759001&videoId=1824650741001"
19 }, {
20 "attributes": {
21 "PROGRAM-ID": 1,
22 "BANDWIDTH": 440000,
23 "RESOLUTION": {
24 "width": 396,
25 "height": 224
26 }
27 },
28 "uri": "http://c.brightcove.com/services/mobile/streaming/index/rendition.m3u8?assetId=1824686593001&videoId=1824650741001"
29 }, {
30 "attributes": {
31 "PROGRAM-ID": 1,
32 "BANDWIDTH": 1928000,
33 "RESOLUTION": {
34 "width": 960,
35 "height": 540
36 }
37 },
38 "uri": "http://c.brightcove.com/services/mobile/streaming/index/rendition.m3u8?assetId=1824687660001&videoId=1824650741001"
39 }]
40 }
1 #EXTM3U
2 #EXT-X-TARGETDURATION:
3 #EXT-X-STREAM-INF:PROGRAM-ID=1,BANDWIDTH=240000,RESOLUTION=396x224
4 http://c.brightcove.com/services/mobile/streaming/index/rendition.m3u8?assetId=1824686811001&videoId=1824650741001
5 #EXT-X-STREAM-INF:PROGRAM-ID=1,BANDWIDTH=40000
6 http://c.brightcove.com/services/mobile/streaming/index/rendition.m3u8?assetId=1824683759001&videoId=1824650741001
7 #EXT-X-STREAM-INF:PROGRAM-ID=1,BANDWIDTH=440000,RESOLUTION=396x224
8 http://c.brightcove.com/services/mobile/streaming/index/rendition.m3u8?assetId=1824686593001&videoId=1824650741001
9 #EXT-X-STREAM-INF:PROGRAM-ID=1,BANDWIDTH=1928000,RESOLUTION=960x540
10 http://c.brightcove.com/services/mobile/streaming/index/rendition.m3u8?assetId=1824687660001&videoId=1824650741001
1 {
2 "allowCache": true,
3 "targetDuration": 10,
4 "mediaSequence": 0,
5 "playlistType": "EVENT",
6 "segments": [{
7 "duration": 10,
8 "uri": "/test/ts-files/zencoder/haze/Haze_Mantel_President_encoded_1200-00001.ts"
9 }, {
10 "duration": 10,
11 "uri": "/test/ts-files/zencoder/haze/Haze_Mantel_President_encoded_1200-00002.ts"
12 }, {
13 "duration": 10,
14 "uri": "/test/ts-files/zencoder/haze/Haze_Mantel_President_encoded_1200-00003.ts"
15 }, {
16 "duration": 10,
17 "uri": "/test/ts-files/zencoder/haze/Haze_Mantel_President_encoded_1200-00004.ts"
18 }, {
19 "duration": 10,
20 "uri": "/test/ts-files/zencoder/haze/Haze_Mantel_President_encoded_1200-00005.ts"
21 }, {
22 "duration": 8,
23 "uri": "/test/ts-files/zencoder/haze/Haze_Mantel_President_encoded_1200-00006.ts"
24 }]
25 }
1 #EXTM3U
2 #EXT-X-PLAYLIST-TYPE:EVENT
3 #EXT-X-TARGETDURATION:10
4 #EXTINF:10,
5 /test/ts-files/zencoder/haze/Haze_Mantel_President_encoded_1200-00001.ts
6 #EXTINF:10,
7 /test/ts-files/zencoder/haze/Haze_Mantel_President_encoded_1200-00002.ts
8 #EXTINF:10,
9 /test/ts-files/zencoder/haze/Haze_Mantel_President_encoded_1200-00003.ts
10 #EXTINF:10,
11 /test/ts-files/zencoder/haze/Haze_Mantel_President_encoded_1200-00004.ts
12 #EXTINF:10,
13 /test/ts-files/zencoder/haze/Haze_Mantel_President_encoded_1200-00005.ts
14 #EXTINF:8,
15 /test/ts-files/zencoder/haze/Haze_Mantel_President_encoded_1200-00006.ts
16 #ZEN-TOTAL-DURATION:57.9911
17 #EXT-X-ENDLIST
1 {
2 "allowCache": true,
3 "targetDuration": 10,
4 "mediaSequence": 0,
5 "playlistType": "VOD",
6 "segments": [{
7 "duration": 10,
8 "byterange": {
9 "length": 522828,
10 "offset": 0
11 },
12 "uri": "hls_450k_video.ts"
13 }, {
14 "byterange": {
15 "length": 587500,
16 "offset": 522828
17 },
18 "uri": "hls_450k_video.ts"
19 }, {
20 "duration": 5,
21 "byterange": {
22 "length": 713084,
23 "offset": 1110328
24 },
25 "uri": "hls_450k_video.ts"
26 }, {
27 "duration": 9.7,
28 "byterange": {
29 "length": 476580,
30 "offset": 1823412
31 },
32 "uri": "hls_450k_video.ts"
33 }, {
34 "duration": 10,
35 "byterange": {
36 "length": 535612,
37 "offset": 2299992
38 },
39 "uri": "hls_450k_video.ts"
40 }, {
41 "duration": 10,
42 "byterange": {
43 "length": 207176,
44 "offset": 2835604
45 },
46 "uri": "hls_450k_video.ts"
47 }, {
48 "duration": 10,
49 "byterange": {
50 "length": 455900,
51 "offset": 3042780
52 },
53 "uri": "hls_450k_video.ts"
54 }, {
55 "duration": 10,
56 "byterange": {
57 "length": 657248,
58 "offset": 3498680
59 },
60 "uri": "hls_450k_video.ts"
61 }, {
62 "duration": 10,
63 "byterange": {
64 "length": 571708,
65 "offset": 4155928
66 },
67 "uri": "hls_450k_video.ts"
68 }, {
69 "duration": 10,
70 "byterange": {
71 "length": 485040,
72 "offset": 4727636
73 },
74 "uri": "hls_450k_video.ts"
75 }, {
76 "duration": 10,
77 "byterange": {
78 "length": 709136,
79 "offset": 5212676
80 },
81 "uri": "hls_450k_video.ts"
82 }, {
83 "duration": 10,
84 "byterange": {
85 "length": 730004,
86 "offset": 5921812
87 },
88 "uri": "hls_450k_video.ts"
89 }, {
90 "duration": 10,
91 "byterange": {
92 "length": 456276,
93 "offset": 6651816
94 },
95 "uri": "hls_450k_video.ts"
96 }, {
97 "duration": 10,
98 "byterange": {
99 "length": 468684,
100 "offset": 7108092
101 },
102 "uri": "hls_450k_video.ts"
103 }, {
104 "duration": 10,
105 "byterange": {
106 "length": 444996,
107 "offset": 7576776
108 },
109 "uri": "hls_450k_video.ts"
110 }, {
111 "duration": 10,
112 "byterange": {
113 "length": 331444,
114 "offset": 8021772
115 },
116 "uri": "hls_450k_video.ts"
117 }, {
118 "byterange": {
119 "length": 44556,
120 "offset": 8353216
121 },
122 "uri": "hls_450k_video.ts"
123 }]
124 }
1 #EXTM3U
2 #EXT-X-TARGETDURATION:10
3 #EXT-X-VERSION:3
4 #EXT-X-MEDIA-SEQUENCE:0
5 #EXT-X-PLAYLIST-TYPE:VOD
6 #EXTINF:10
7 #EXT-X-BYTERANGE:522828@0
8 hls_450k_video.ts
9 #EXTINF:;asljasdfii11)))00,
10 #EXT-X-BYTERANGE:587500@522828
11 hls_450k_video.ts
12 #EXTINF:5,
13 #EXT-X-BYTERANGE:713084@1110328
14 hls_450k_video.ts
15 #EXTINF:9.7,
16 #EXT-X-BYTERANGE:476580@1823412
17 hls_450k_video.ts
18 #EXTINF:10,
19 #EXT-X-BYTERANGE:535612@2299992
20 hls_450k_video.ts
21 #EXTINF:10,
22 #EXT-X-BYTERANGE:207176@2835604
23 hls_450k_video.ts
24 #EXTINF:10,
25 #EXT-X-BYTERANGE:455900@3042780
26 hls_450k_video.ts
27 #EXTINF:10,
28 #EXT-X-BYTERANGE:657248@3498680
29 hls_450k_video.ts
30 #EXTINF:10,
31 #EXT-X-BYTERANGE:571708@4155928
32 hls_450k_video.ts
33 #EXTINF:10,
34 #EXT-X-BYTERANGE:485040@4727636
35 hls_450k_video.ts
36 #EXTINF:10,
37 #EXT-X-BYTERANGE:709136@5212676
38 hls_450k_video.ts
39 #EXTINF:10,
40 #EXT-X-BYTERANGE:730004@5921812
41 hls_450k_video.ts
42 #EXTINF:10,
43 #EXT-X-BYTERANGE:456276@6651816
44 hls_450k_video.ts
45 #EXTINF:10,
46 #EXT-X-BYTERANGE:468684@7108092
47 hls_450k_video.ts
48 #EXTINF:10,
49 #EXT-X-BYTERANGE:444996@7576776
50 hls_450k_video.ts
51 #EXTINF:22,
52 #EXTINF:10,
53 #EXT-X-BYTERANGE:331444@8021772
54 hls_450k_video.ts
55 #EXT-X-BYTERANGE:44556@8353216
56 hls_450k_video.ts
57 #EXT-X-ENDLIST
1 {
2 "targetDuration": 10,
3 "allowCache": true,
4 "mediaSequence": 0,
5 "playlistType": "VOD",
6 "segments": [{
7 "duration": 10,
8 "byterange": {
9 "length": 522828,
10 "offset": 0
11 },
12 "uri": "hls_450k_video.ts"
13 }]
14 }
1 #EXTM3U
2 #EXT-X-TARGETDURATION:10
3 #EXT-X-VERSION:4
4 #EXT-X-ALLOW-CACHE:MAYBE
5 #EXT-X-MEDIA-SEQUENCE:0
6 #EXT-X-PLAYLIST-TYPE:VOD
7 #EXTINF:10,
8 #EXT-X-BYTERANGE:522828@0
9 hls_450k_video.ts
10 #EXT-X-ENDLIST
...\ No newline at end of file ...\ No newline at end of file
1 {
2 "allowCache": true,
3 "mediaSequence": 0,
4 "playlistType": "VOD",
5 "targetDuration": 8,
6 "segments": [{
7 "duration": 6.64,
8 "uri": "/test/ts-files/tvy7/8a5e2822668b5370f4eb1438b2564fb7ab12ffe1-hi720.ts"
9 }, {
10 "duration": 6.08,
11 "uri": "/test/ts-files/tvy7/56be1cef869a1c0cc8e38864ad1add17d187f051-hi720.ts"
12 }, {
13 "duration": 6.6,
14 "uri": "/test/ts-files/tvy7/549c8c77f55f049741a06596e5c1e01dacaa46d0-hi720.ts"
15 }, {
16 "duration": 5,
17 "uri": "/test/ts-files/tvy7/6cfa378684ffeb1c455a64dae6c103290a1f53d4-hi720.ts"
18 }]
19 }
1 #EXTM3U
2 #EXT-X-PLAYLIST-TYPE:VOD
3 #EXT-X-MEDIA-SEQUENCE:gobblegobble
4 #EXT-X-ALLOW-CACHE:YES
5 #EXT-X-TARGETDURATION:8
6 #EXTINF:6.640,{}
7 /test/ts-files/tvy7/8a5e2822668b5370f4eb1438b2564fb7ab12ffe1-hi720.ts
8 #EXTINF:6.080,{}
9 /test/ts-files/tvy7/56be1cef869a1c0cc8e38864ad1add17d187f051-hi720.ts
10 #EXTINF:6.600,{}
11 /test/ts-files/tvy7/549c8c77f55f049741a06596e5c1e01dacaa46d0-hi720.ts
12 #EXTINF:5.000,{}
13 /test/ts-files/tvy7/6cfa378684ffeb1c455a64dae6c103290a1f53d4-hi720.ts
14 #EXT-X-ENDLIST
1 {
2 "allowCache": true,
3 "targetDuration": 10,
4 "mediaSequence": 0,
5 "playlistType": "VOD",
6 "segments": [{
7 "duration": 10,
8 "uri": "/test/ts-files/zencoder/haze/Haze_Mantel_President_encoded_1200-00001.ts"
9 }, {
10 "duration": 10,
11 "uri": "/test/ts-files/zencoder/haze/Haze_Mantel_President_encoded_1200-00002.ts"
12 }, {
13 "duration": 10,
14 "uri": "/test/ts-files/zencoder/haze/Haze_Mantel_President_encoded_1200-00003.ts"
15 }, {
16 "duration": 10,
17 "uri": "/test/ts-files/zencoder/haze/Haze_Mantel_President_encoded_1200-00004.ts"
18 }, {
19 "duration": 10,
20 "uri": "/test/ts-files/zencoder/haze/Haze_Mantel_President_encoded_1200-00005.ts"
21 }, {
22 "duration": 8,
23 "uri": "/test/ts-files/zencoder/haze/Haze_Mantel_President_encoded_1200-00006.ts"
24 }]
25 }
1 #EXTM3U
2 #EXT-X-PLAYLIST-TYPE:asdRASDfasdR
3 #EXT-X-TARGETDURATION:10
4 #EXTINF:10,
5 /test/ts-files/zencoder/haze/Haze_Mantel_President_encoded_1200-00001.ts
6 #EXTINF:10,
7 /test/ts-files/zencoder/haze/Haze_Mantel_President_encoded_1200-00002.ts
8 #EXTINF:10,
9 /test/ts-files/zencoder/haze/Haze_Mantel_President_encoded_1200-00003.ts
10 #EXTINF:10,
11 /test/ts-files/zencoder/haze/Haze_Mantel_President_encoded_1200-00004.ts
12 #EXTINF:10,
13 /test/ts-files/zencoder/haze/Haze_Mantel_President_encoded_1200-00005.ts
14 #EXTINF:8,
15 /test/ts-files/zencoder/haze/Haze_Mantel_President_encoded_1200-00006.ts
16 #ZEN-TOTAL-DURATION:57.9911
17 #EXT-X-ENDLIST
1 {
2 "allowCache": true,
3 "mediaSequence": 0,
4 "playlistType": "VOD",
5 "segments": [{
6 "duration": 10,
7 "byterange": {
8 "length": 522828,
9 "offset": 0
10 },
11 "uri": "hls_450k_video.ts"
12 }, {
13 "duration": 10,
14 "byterange": {
15 "length": 587500,
16 "offset": 522828
17 },
18 "uri": "hls_450k_video.ts"
19 }, {
20 "duration": 10,
21 "byterange": {
22 "length": 713084,
23 "offset": 1110328
24 },
25 "uri": "hls_450k_video.ts"
26 }, {
27 "duration": 10,
28 "byterange": {
29 "length": 476580,
30 "offset": 1823412
31 },
32 "uri": "hls_450k_video.ts"
33 }, {
34 "duration": 10,
35 "byterange": {
36 "length": 535612,
37 "offset": 2299992
38 },
39 "uri": "hls_450k_video.ts"
40 }, {
41 "duration": 10,
42 "byterange": {
43 "length": 207176,
44 "offset": 2835604
45 },
46 "uri": "hls_450k_video.ts"
47 }, {
48 "duration": 10,
49 "byterange": {
50 "length": 455900,
51 "offset": 3042780
52 },
53 "uri": "hls_450k_video.ts"
54 }, {
55 "duration": 10,
56 "byterange": {
57 "length": 657248,
58 "offset": 3498680
59 },
60 "uri": "hls_450k_video.ts"
61 }, {
62 "duration": 10,
63 "byterange": {
64 "length": 571708,
65 "offset": 4155928
66 },
67 "uri": "hls_450k_video.ts"
68 }, {
69 "duration": 10,
70 "byterange": {
71 "length": 485040,
72 "offset": 4727636
73 },
74 "uri": "hls_450k_video.ts"
75 }, {
76 "duration": 10,
77 "byterange": {
78 "length": 709136,
79 "offset": 5212676
80 },
81 "uri": "hls_450k_video.ts"
82 }, {
83 "duration": 10,
84 "byterange": {
85 "length": 730004,
86 "offset": 5921812
87 },
88 "uri": "hls_450k_video.ts"
89 }, {
90 "duration": 10,
91 "byterange": {
92 "length": 456276,
93 "offset": 6651816
94 },
95 "uri": "hls_450k_video.ts"
96 }, {
97 "duration": 10,
98 "byterange": {
99 "length": 468684,
100 "offset": 7108092
101 },
102 "uri": "hls_450k_video.ts"
103 }, {
104 "duration": 10,
105 "byterange": {
106 "length": 444996,
107 "offset": 7576776
108 },
109 "uri": "hls_450k_video.ts"
110 }, {
111 "duration": 10,
112 "byterange": {
113 "length": 331444,
114 "offset": 8021772
115 },
116 "uri": "hls_450k_video.ts"
117 }, {
118 "duration": 1.4167,
119 "byterange": {
120 "length": 44556,
121 "offset": 8353216
122 },
123 "uri": "hls_450k_video.ts"
124 }]
125 }
126
1 #EXTM3U
2 #EXT-X-TARGETDURATION:NaN
3 #EXT-X-VERSION:4
4 #EXT-X-MEDIA-SEQUENCE:0
5 #EXT-X-PLAYLIST-TYPE:VOD
6 #EXTINF:10,
7 #EXT-X-BYTERANGE:522828@0
8 hls_450k_video.ts
9 #EXTINF:10,
10 #EXT-X-BYTERANGE:587500@522828
11 hls_450k_video.ts
12 #EXTINF:10,
13 #EXT-X-BYTERANGE:713084@1110328
14 hls_450k_video.ts
15 #EXTINF:10,
16 #EXT-X-BYTERANGE:476580@1823412
17 hls_450k_video.ts
18 #EXTINF:10,
19 #EXT-X-BYTERANGE:535612@2299992
20 hls_450k_video.ts
21 #EXTINF:10,
22 #EXT-X-BYTERANGE:207176@2835604
23 hls_450k_video.ts
24 #EXTINF:10,
25 #EXT-X-BYTERANGE:455900@3042780
26 hls_450k_video.ts
27 #EXTINF:10,
28 #EXT-X-BYTERANGE:657248@3498680
29 hls_450k_video.ts
30 #EXTINF:10,
31 #EXT-X-BYTERANGE:571708@4155928
32 hls_450k_video.ts
33 #EXTINF:10,
34 #EXT-X-BYTERANGE:485040@4727636
35 hls_450k_video.ts
36 #EXTINF:10,
37 #EXT-X-BYTERANGE:709136@5212676
38 hls_450k_video.ts
39 #EXTINF:10,
40 #EXT-X-BYTERANGE:730004@5921812
41 hls_450k_video.ts
42 #EXTINF:10,
43 #EXT-X-BYTERANGE:456276@6651816
44 hls_450k_video.ts
45 #EXTINF:10,
46 #EXT-X-BYTERANGE:468684@7108092
47 hls_450k_video.ts
48 #EXTINF:10,
49 #EXT-X-BYTERANGE:444996@7576776
50 hls_450k_video.ts
51 #EXTINF:10,
52 #EXT-X-BYTERANGE:331444@8021772
53 hls_450k_video.ts
54 #EXTINF:1.4167,
55 #EXT-X-BYTERANGE:44556@8353216
56 hls_450k_video.ts
57 #EXT-X-ENDLIST
1 {
2 "allowCache": true,
3 "playlists": [{
4 "attributes": {
5 "PROGRAM-ID": 1,
6 "BANDWIDTH": 240000,
7 "RESOLUTION": {
8 "width": 396,
9 "height": 224
10 }
11 },
12 "uri": "http://c.brightcove.com/services/mobile/streaming/index/rendition.m3u8?assetId=1824686811001&videoId=1824650741001"
13 }, {
14 "attributes": {
15 "PROGRAM-ID": 1,
16 "BANDWIDTH": 40000
17 },
18 "uri": "http://c.brightcove.com/services/mobile/streaming/index/rendition.m3u8?assetId=1824683759001&videoId=1824650741001"
19 }, {
20 "attributes": {
21 "PROGRAM-ID": 1,
22 "BANDWIDTH": 440000,
23 "RESOLUTION": {
24 "width": 396,
25 "height": 224
26 }
27 },
28 "uri": "http://c.brightcove.com/services/mobile/streaming/index/rendition.m3u8?assetId=1824686593001&videoId=1824650741001"
29 }, {
30 "attributes": {
31 "PROGRAM-ID": 1,
32 "BANDWIDTH": 1928000,
33 "RESOLUTION": {
34 "width": 960,
35 "height": 540
36 }
37 },
38 "uri": "http://c.brightcove.com/services/mobile/streaming/index/rendition.m3u8?assetId=1824687660001&videoId=1824650741001"
39 }]
40 }
1 #EXTM3U
2 #EXT-X-STREAM-INF:PROGRAM-ID=1,BANDWIDTH=240000,RESOLUTION=396x224
3 http://c.brightcove.com/services/mobile/streaming/index/rendition.m3u8?assetId=1824686811001&videoId=1824650741001
4 #EXT-X-STREAM-INF:PROGRAM-ID=1,BANDWIDTH=40000
5 http://c.brightcove.com/services/mobile/streaming/index/rendition.m3u8?assetId=1824683759001&videoId=1824650741001
6 #EXT-X-STREAM-INF:PROGRAM-ID=1,BANDWIDTH=440000,RESOLUTION=396x224
7 http://c.brightcove.com/services/mobile/streaming/index/rendition.m3u8?assetId=1824686593001&videoId=1824650741001
8 #EXT-X-STREAM-INF:PROGRAM-ID=1,BANDWIDTH=1928000,RESOLUTION=960x540
9 http://c.brightcove.com/services/mobile/streaming/index/rendition.m3u8?assetId=1824687660001&videoId=1824650741001
1 {
2 "allowCache": true,
3 "mediaSequence": 0,
4 "playlistType": "VOD",
5 "targetDuration": 8,
6 "segments": [{
7 "duration": 6.64,
8 "uri": "/test/ts-files/tvy7/8a5e2822668b5370f4eb1438b2564fb7ab12ffe1-hi720.ts"
9 }, {
10 "duration": 6.08,
11 "uri": "/test/ts-files/tvy7/56be1cef869a1c0cc8e38864ad1add17d187f051-hi720.ts"
12 }, {
13 "duration": 6.6,
14 "uri": "/test/ts-files/tvy7/549c8c77f55f049741a06596e5c1e01dacaa46d0-hi720.ts"
15 }, {
16 "duration": 5,
17 "uri": "/test/ts-files/tvy7/6cfa378684ffeb1c455a64dae6c103290a1f53d4-hi720.ts"
18 }]
19 }
1 #EXTM3U
2 #EXT-X-PLAYLIST-TYPE:VOD
3 #EXT-X-MEDIA-SEQUENCE:0
4 #EXT-X-ALLOW-CACHE:YES
5 #EXT-X-TARGETDURATION:8
6 #EXTINF:6.640,{}
7 /test/ts-files/tvy7/8a5e2822668b5370f4eb1438b2564fb7ab12ffe1-hi720.ts
8 #EXTINF:6.080,{}
9 /test/ts-files/tvy7/56be1cef869a1c0cc8e38864ad1add17d187f051-hi720.ts
10 #EXTINF:6.600,{}
11 /test/ts-files/tvy7/549c8c77f55f049741a06596e5c1e01dacaa46d0-hi720.ts
12 #EXTINF:5.000,{}
13 /test/ts-files/tvy7/6cfa378684ffeb1c455a64dae6c103290a1f53d4-hi720.ts
14 #EXT-X-ENDLIST
1 {
2 "allowCache": true,
3 "mediaSequence": 0,
4 "playlistType": "VOD",
5 "targetDuration": 8,
6 "segments": [{
7 "duration": 6.64,
8 "uri": "/test/ts-files/tvy7/8a5e2822668b5370f4eb1438b2564fb7ab12ffe1-hi720.ts"
9 }, {
10 "duration": 6.08,
11 "uri": "/test/ts-files/tvy7/56be1cef869a1c0cc8e38864ad1add17d187f051-hi720.ts"
12 }, {
13 "duration": 6.6,
14 "uri": "/test/ts-files/tvy7/549c8c77f55f049741a06596e5c1e01dacaa46d0-hi720.ts"
15 }, {
16 "duration": 5,
17 "uri": "/test/ts-files/tvy7/6cfa378684ffeb1c455a64dae6c103290a1f53d4-hi720.ts"
18 }]
19 }
1 #EXTM3U
2 #EXT-X-PLAYLIST-TYPE:VOD
3 #EXT-X-ALLOW-CACHE:YES
4 #EXT-X-TARGETDURATION:8
5 #EXTINF:6.640,{}
6 /test/ts-files/tvy7/8a5e2822668b5370f4eb1438b2564fb7ab12ffe1-hi720.ts
7 #EXTINF:6.080,{}
8 /test/ts-files/tvy7/56be1cef869a1c0cc8e38864ad1add17d187f051-hi720.ts
9 #EXTINF:6.600,{}
10 /test/ts-files/tvy7/549c8c77f55f049741a06596e5c1e01dacaa46d0-hi720.ts
11 #EXTINF:5.000,{}
12 /test/ts-files/tvy7/6cfa378684ffeb1c455a64dae6c103290a1f53d4-hi720.ts
13 #EXT-X-ENDLIST
1 {
2 "allowCache": true,
3 "mediaSequence": 0,
4 "playlistType": "VOD",
5 "targetDuration": 8,
6 "segments": [{
7 "duration": 6.64,
8 "uri": "/test/ts-files/tvy7/8a5e2822668b5370f4eb1438b2564fb7ab12ffe1-hi720.ts"
9 }, {
10 "uri": "/test/ts-files/tvy7/56be1cef869a1c0cc8e38864ad1add17d187f051-hi720.ts"
11 }, {
12 "uri": "/test/ts-files/tvy7/549c8c77f55f049741a06596e5c1e01dacaa46d0-hi720.ts"
13 }, {
14 "uri": "/test/ts-files/tvy7/6cfa378684ffeb1c455a64dae6c103290a1f53d4-hi720.ts"
15 }]
16 }
1 #EXTM3U
2 #EXT-X-PLAYLIST-TYPE:VOD
3 #EXT-X-MEDIA-SEQUENCE:0
4 #EXT-X-ALLOW-CACHE:YES
5 #EXT-X-TARGETDURATION:8
6 #EXTINF:6.640,{}
7 /test/ts-files/tvy7/8a5e2822668b5370f4eb1438b2564fb7ab12ffe1-hi720.ts
8 /test/ts-files/tvy7/56be1cef869a1c0cc8e38864ad1add17d187f051-hi720.ts
9 /test/ts-files/tvy7/549c8c77f55f049741a06596e5c1e01dacaa46d0-hi720.ts
10 /test/ts-files/tvy7/6cfa378684ffeb1c455a64dae6c103290a1f53d4-hi720.ts
11 #EXT-X-ENDLIST
1 {
2 "allowCache": true,
3 "mediaSequence": -11,
4 "playlistType": "VOD",
5 "targetDuration": 8,
6 "segments": [{
7 "duration": 6.64,
8 "uri": "/test/ts-files/tvy7/8a5e2822668b5370f4eb1438b2564fb7ab12ffe1-hi720.ts"
9 }, {
10 "duration": 6.08,
11 "uri": "/test/ts-files/tvy7/56be1cef869a1c0cc8e38864ad1add17d187f051-hi720.ts"
12 }, {
13 "duration": 6.6,
14 "uri": "/test/ts-files/tvy7/549c8c77f55f049741a06596e5c1e01dacaa46d0-hi720.ts"
15 }, {
16 "duration": 5,
17 "uri": "/test/ts-files/tvy7/6cfa378684ffeb1c455a64dae6c103290a1f53d4-hi720.ts"
18 }]
19 }
1 #EXTM3U
2 #EXT-X-PLAYLIST-TYPE:VOD
3 #EXT-X-MEDIA-SEQUENCE:-11
4 #EXT-X-ALLOW-CACHE:YES
5 #EXT-X-TARGETDURATION:8
6 #EXTINF:6.640,{}
7 /test/ts-files/tvy7/8a5e2822668b5370f4eb1438b2564fb7ab12ffe1-hi720.ts
8 #EXTINF:6.080,{}
9 /test/ts-files/tvy7/56be1cef869a1c0cc8e38864ad1add17d187f051-hi720.ts
10 #EXTINF:6.600,{}
11 /test/ts-files/tvy7/549c8c77f55f049741a06596e5c1e01dacaa46d0-hi720.ts
12 #EXTINF:5.000,{}
13 /test/ts-files/tvy7/6cfa378684ffeb1c455a64dae6c103290a1f53d4-hi720.ts
14 #EXT-X-ENDLIST
...@@ -124,3 +124,4 @@ ...@@ -124,3 +124,4 @@
124 "uri": "hls_450k_video.ts" 124 "uri": "hls_450k_video.ts"
125 }] 125 }]
126 } 126 }
127
......
1 window.playlistM3U8data = '#EXTM3U\n'+
2 '#EXT-X-TARGETDURATION:10\n' +
3 '#EXT-X-VERSION:4\n' +
4 '#EXT-X-MEDIA-SEQUENCE:0\n' +
5 '#EXT-X-PLAYLIST-TYPE:VOD\n' +
6 '#EXTINF:10,\n' +
7 '#EXT-X-BYTERANGE:522828@0\n' +
8 'hls_450k_video.ts\n' +
9 '#EXTINF:10,\n' +
10 '#EXT-X-BYTERANGE:587500@522828\n' +
11 'hls_450k_video.ts\n' +
12 '#EXTINF:10,\n' +
13 '#EXT-X-BYTERANGE:713084@1110328\n' +
14 'hls_450k_video.ts\n' +
15 '#EXTINF:10,\n' +
16 '#EXT-X-BYTERANGE:476580@1823412\n' +
17 'hls_450k_video.ts\n' +
18 '#EXTINF:10,\n' +
19 '#EXT-X-BYTERANGE:535612@2299992\n' +
20 'hls_450k_video.ts\n' +
21 '#EXTINF:10,\n' +
22 '#EXT-X-BYTERANGE:207176@2835604\n' +
23 'hls_450k_video.ts\n' +
24 '#EXTINF:10,\n' +
25 '#EXT-X-BYTERANGE:455900@3042780\n' +
26 'hls_450k_video.ts\n' +
27 '#EXTINF:10,\n' +
28 '#EXT-X-BYTERANGE:657248@3498680\n' +
29 'hls_450k_video.ts\n' +
30 '#EXTINF:10,\n' +
31 '#EXT-X-BYTERANGE:571708@4155928\n' +
32 'hls_450k_video.ts\n' +
33 '#EXTINF:10,\n' +
34 '#EXT-X-BYTERANGE:485040@4727636\n' +
35 'hls_450k_video.ts\n' +
36 '#EXTINF:10,\n' +
37 '#EXT-X-BYTERANGE:709136@5212676\n' +
38 'hls_450k_video.ts\n' +
39 '#EXTINF:10,\n' +
40 '#EXT-X-BYTERANGE:730004@5921812\n' +
41 'hls_450k_video.ts\n' +
42 '#EXTINF:10,\n' +
43 '#EXT-X-BYTERANGE:456276@6651816\n' +
44 'hls_450k_video.ts\n' +
45 '#EXTINF:10,\n' +
46 '#EXT-X-BYTERANGE:468684@7108092\n' +
47 'hls_450k_video.ts\n' +
48 '#EXTINF:10,\n' +
49 '#EXT-X-BYTERANGE:444996@7576776\n' +
50 'hls_450k_video.ts\n' +
51 '#EXTINF:10,\n' +
52 '#EXT-X-BYTERANGE:331444@8021772\n' +
53 'hls_450k_video.ts\n' +
54 '#EXTINF:1.4167,\n' +
55 '#EXT-X-BYTERANGE:44556@8353216\n' +
56 'hls_450k_video.ts\n' +
57 '#EXT-X-ENDLIST';
1 window.playlist_allow_cache = '#EXTM3U\n'+
2 '#EXT-X-TARGETDURATION:10\n' +
3 '#EXT-X-VERSION:{{{version}}}\n' +
4 '{{#if allowCache}}#EXT-X-ALLOW-CACHE:{{{allowCache}}}{{/if}}\n' +
5 '#EXT-X-MEDIA-SEQUENCE:0\n' +
6 '#EXT-X-PLAYLIST-TYPE:VOD\n' +
7 '#EXTINF:10,\n' +
8 '#EXT-X-BYTERANGE:522828@0\n' +
9 'hls_450k_video.ts\n' +
10 '#EXTINF:10,\n' +
11 '#EXT-X-BYTERANGE:587500@522828\n' +
12 'hls_450k_video.ts\n' +
13 '#EXTINF:10,\n' +
14 '#EXT-X-BYTERANGE:713084@1110328\n' +
15 'hls_450k_video.ts\n' +
16 '#EXTINF:10,\n' +
17 '#EXT-X-BYTERANGE:476580@1823412\n' +
18 'hls_450k_video.ts\n' +
19 '#EXTINF:10,\n' +
20 '#EXT-X-BYTERANGE:535612@2299992\n' +
21 'hls_450k_video.ts\n' +
22 '#EXTINF:10,\n' +
23 '#EXT-X-BYTERANGE:207176@2835604\n' +
24 'hls_450k_video.ts\n' +
25 '#EXTINF:10,\n' +
26 '#EXT-X-BYTERANGE:455900@3042780\n' +
27 'hls_450k_video.ts\n' +
28 '#EXTINF:10,\n' +
29 '#EXT-X-BYTERANGE:657248@3498680\n' +
30 'hls_450k_video.ts\n' +
31 '#EXTINF:10,\n' +
32 '#EXT-X-BYTERANGE:571708@4155928\n' +
33 'hls_450k_video.ts\n' +
34 '#EXTINF:10,\n' +
35 '#EXT-X-BYTERANGE:485040@4727636\n' +
36 'hls_450k_video.ts\n' +
37 '#EXTINF:10,\n' +
38 '#EXT-X-BYTERANGE:709136@5212676\n' +
39 'hls_450k_video.ts\n' +
40 '#EXTINF:10,\n' +
41 '#EXT-X-BYTERANGE:730004@5921812\n' +
42 'hls_450k_video.ts\n' +
43 '#EXTINF:10,\n' +
44 '#EXT-X-BYTERANGE:456276@6651816\n' +
45 'hls_450k_video.ts\n' +
46 '#EXTINF:10,\n' +
47 '#EXT-X-BYTERANGE:468684@7108092\n' +
48 'hls_450k_video.ts' +
49 '#EXTINF:10,\n' +
50 '#EXT-X-BYTERANGE:444996@7576776\n' +
51 'hls_450k_video.ts\n' +
52 '#EXTINF:10,\n' +
53 '#EXT-X-BYTERANGE:331444@8021772\n' +
54 'hls_450k_video.ts\n' +
55 '#EXTINF:1.4167,\n' +
56 '#EXT-X-BYTERANGE:44556@8353216\n' +
57 'hls_450k_video.ts\n' +
58 '#EXT-X-ENDLIST';
1 #EXTM3U
2 #EXT-X-TARGETDURATION:10
3 #EXT-X-VERSION:{{{version}}}
4 {{#if allowCache}}#EXT-X-ALLOW-CACHE:{{{allowCache}}}{{/if}}
5 #EXT-X-MEDIA-SEQUENCE:0
6 #EXT-X-PLAYLIST-TYPE:VOD
7 #EXTINF:10,
8 #EXT-X-BYTERANGE:522828@0
9 hls_450k_video.ts
10 #EXTINF:10,
11 #EXT-X-BYTERANGE:587500@522828
12 hls_450k_video.ts
13 #EXTINF:10,
14 #EXT-X-BYTERANGE:713084@1110328
15 hls_450k_video.ts
16 #EXTINF:10,
17 #EXT-X-BYTERANGE:476580@1823412
18 hls_450k_video.ts
19 #EXTINF:10,
20 #EXT-X-BYTERANGE:535612@2299992
21 hls_450k_video.ts
22 #EXTINF:10,
23 #EXT-X-BYTERANGE:207176@2835604
24 hls_450k_video.ts
25 #EXTINF:10,
26 #EXT-X-BYTERANGE:455900@3042780
27 hls_450k_video.ts
28 #EXTINF:10,
29 #EXT-X-BYTERANGE:657248@3498680
30 hls_450k_video.ts
31 #EXTINF:10,
32 #EXT-X-BYTERANGE:571708@4155928
33 hls_450k_video.ts
34 #EXTINF:10,
35 #EXT-X-BYTERANGE:485040@4727636
36 hls_450k_video.ts
37 #EXTINF:10,
38 #EXT-X-BYTERANGE:709136@5212676
39 hls_450k_video.ts
40 #EXTINF:10,
41 #EXT-X-BYTERANGE:730004@5921812
42 hls_450k_video.ts
43 #EXTINF:10,
44 #EXT-X-BYTERANGE:456276@6651816
45 hls_450k_video.ts
46 #EXTINF:10,
47 #EXT-X-BYTERANGE:468684@7108092
48 hls_450k_video.ts
49 #EXTINF:10,
50 #EXT-X-BYTERANGE:444996@7576776
51 hls_450k_video.ts
52 #EXTINF:10,
53 #EXT-X-BYTERANGE:331444@8021772
54 hls_450k_video.ts
55 #EXTINF:1.4167,
56 #EXT-X-BYTERANGE:44556@8353216
57 hls_450k_video.ts
58 #EXT-X-ENDLIST
...\ No newline at end of file ...\ No newline at end of file
1 window.playlist_byte_range = '#EXTM3U\n'+
2 '#EXT-X-TARGETDURATION:10\n' +
3 '#EXT-X-VERSION:{{{version}}}\n' +
4 '#EXT-X-MEDIA-SEQUENCE:0\n' +
5 '#EXT-X-PLAYLIST-TYPE:VOD\n' +
6 '#EXTINF:10,\n' +
7 '{{#if byteRange}}#EXT-X-BYTERANGE:{{{byteRange}}}{{/if}}\n' +
8 //'#EXT-X-BYTERANGE:522828@0\n' +
9 'hls_450k_video.ts\n' +
10 '#EXTINF:10,\n' +
11 '{{#if byteRange1}}#EXT-X-BYTERANGE:{{{byteRange1}}}{{/if}}\n' +
12 //'#EXT-X-BYTERANGE:587500@522828\n' +
13 'hls_450k_video.ts\n' +
14 '#EXTINF:10,\n' +
15 '#EXT-X-BYTERANGE:713084@1110328\n' +
16 'hls_450k_video.ts\n' +
17 '#EXTINF:10,\n' +
18 '#EXT-X-BYTERANGE:476580@1823412\n' +
19 'hls_450k_video.ts\n' +
20 '#EXTINF:10,\n' +
21 '#EXT-X-BYTERANGE:535612@2299992\n' +
22 'hls_450k_video.ts\n' +
23 '#EXTINF:10,\n' +
24 '#EXT-X-BYTERANGE:207176@2835604\n' +
25 'hls_450k_video.ts\n' +
26 '#EXTINF:10,\n' +
27 '#EXT-X-BYTERANGE:455900@3042780\n' +
28 'hls_450k_video.ts\n' +
29 '#EXTINF:10,\n' +
30 '#EXT-X-BYTERANGE:657248@3498680\n' +
31 'hls_450k_video.ts\n' +
32 '#EXTINF:10,\n' +
33 '#EXT-X-BYTERANGE:571708@4155928\n' +
34 'hls_450k_video.ts\n' +
35 '#EXTINF:10,\n' +
36 '#EXT-X-BYTERANGE:485040@4727636\n' +
37 'hls_450k_video.ts\n' +
38 '#EXTINF:10,\n' +
39 '#EXT-X-BYTERANGE:709136@5212676\n' +
40 'hls_450k_video.ts\n' +
41 '#EXTINF:10,\n' +
42 '#EXT-X-BYTERANGE:730004@5921812\n' +
43 'hls_450k_video.ts\n' +
44 '#EXTINF:10,\n' +
45 '#EXT-X-BYTERANGE:456276@6651816\n' +
46 'hls_450k_video.ts\n' +
47 '#EXTINF:10,\n' +
48 '#EXT-X-BYTERANGE:468684@7108092\n' +
49 'hls_450k_video.ts\n' +
50 '#EXTINF:10,\n' +
51 '#EXT-X-BYTERANGE:444996@7576776\n' +
52 'hls_450k_video.ts\n' +
53 '#EXTINF:10,\n' +
54 '#EXT-X-BYTERANGE:331444@8021772\n' +
55 'hls_450k_video.ts\n' +
56 '#EXTINF:1.4167,\n' +
57 '{{#if byteRange2}}#EXT-X-BYTERANGE:{{{byteRange2}}}{{/if}}\n' +
58 //'#EXT-X-BYTERANGE:44556@8353216\n' +
59 'hls_450k_video.ts\n' +
60 '#EXT-X-ENDLIST';
1 #EXTM3U
2 #EXT-X-TARGETDURATION:10
3 #EXT-X-VERSION:{{{version}}}
4 #EXT-X-MEDIA-SEQUENCE:0
5 #EXT-X-PLAYLIST-TYPE:VOD
6 #EXTINF:10,
7 {{#if byteRange}}#EXT-X-BYTERANGE:{{{byteRange}}}{{/if}}
8 //#EXT-X-BYTERANGE:522828@0
9 hls_450k_video.ts
10 #EXTINF:10,
11 {{#if byteRange1}}#EXT-X-BYTERANGE:{{{byteRange1}}}{{/if}}
12 //#EXT-X-BYTERANGE:587500@522828
13 hls_450k_video.ts
14 #EXTINF:10,
15 #EXT-X-BYTERANGE:713084@1110328
16 hls_450k_video.ts
17 #EXTINF:10,
18 #EXT-X-BYTERANGE:476580@1823412
19 hls_450k_video.ts
20 #EXTINF:10,
21 #EXT-X-BYTERANGE:535612@2299992
22 hls_450k_video.ts
23 #EXTINF:10,
24 #EXT-X-BYTERANGE:207176@2835604
25 hls_450k_video.ts
26 #EXTINF:10,
27 #EXT-X-BYTERANGE:455900@3042780
28 hls_450k_video.ts
29 #EXTINF:10,
30 #EXT-X-BYTERANGE:657248@3498680
31 hls_450k_video.ts
32 #EXTINF:10,
33 #EXT-X-BYTERANGE:571708@4155928
34 hls_450k_video.ts
35 #EXTINF:10,
36 #EXT-X-BYTERANGE:485040@4727636
37 hls_450k_video.ts
38 #EXTINF:10,
39 #EXT-X-BYTERANGE:709136@5212676
40 hls_450k_video.ts
41 #EXTINF:10,
42 #EXT-X-BYTERANGE:730004@5921812
43 hls_450k_video.ts
44 #EXTINF:10,
45 #EXT-X-BYTERANGE:456276@6651816
46 hls_450k_video.ts
47 #EXTINF:10,
48 #EXT-X-BYTERANGE:468684@7108092
49 hls_450k_video.ts
50 #EXTINF:10,
51 #EXT-X-BYTERANGE:444996@7576776
52 hls_450k_video.ts
53 #EXTINF:10,
54 #EXT-X-BYTERANGE:331444@8021772
55 hls_450k_video.ts
56 #EXTINF:1.4167,
57 {{#if byteRange2}}#EXT-X-BYTERANGE:{{{byteRange2}}}{{/if}}
58 //#EXT-X-BYTERANGE:44556@8353216
59 hls_450k_video.ts
60 #EXT-X-ENDLIST
...\ No newline at end of file ...\ No newline at end of file
1 window.playlist_extinf_template = '#EXTM3U\n'+
2 '#EXT-X-TARGETDURATION:10\n' +
3 '#EXT-X-VERSION:{{{version}}}\n' +
4 '#EXT-X-MEDIA-SEQUENCE:0\n' +
5 '#EXT-X-PLAYLIST-TYPE:VOD\n' +
6 '{{#if extInf}}#EXTINF:{{{extInf}}}{{/if}}\n' +
7 '#EXT-X-BYTERANGE:522828@0\n' +
8 '{{#if segment}}{{{segment}}}\n{{/if}}' +
9 '{{#if extInf1}}#EXTINF:{{{extInf1}}}{{/if}}\n' +
10 '#EXT-X-BYTERANGE:587500@522828\n' +
11 'hls_450k_video.ts\n' +
12 '#EXTINF:10,\n' +
13 '#EXT-X-BYTERANGE:713084@1110328\n' +
14 'hls_450k_video.ts\n' +
15 '#EXTINF:10,\n' +
16 '#EXT-X-BYTERANGE:476580@1823412\n' +
17 'hls_450k_video.ts\n' +
18 '#EXTINF:10,\n' +
19 '#EXT-X-BYTERANGE:535612@2299992\n' +
20 'hls_450k_video.ts\n' +
21 '#EXTINF:10,\n' +
22 '#EXT-X-BYTERANGE:207176@2835604\n' +
23 'hls_450k_video.ts\n' +
24 '#EXTINF:10,\n' +
25 '#EXT-X-BYTERANGE:455900@3042780\n' +
26 'hls_450k_video.ts\n' +
27 '#EXTINF:10,\n' +
28 '#EXT-X-BYTERANGE:657248@3498680\n' +
29 'hls_450k_video.ts\n' +
30 '#EXTINF:10,\n' +
31 '#EXT-X-BYTERANGE:571708@4155928\n' +
32 'hls_450k_video.ts\n' +
33 '#EXTINF:10,\n' +
34 '#EXT-X-BYTERANGE:485040@4727636\n' +
35 'hls_450k_video.ts\n' +
36 '#EXTINF:10,\n' +
37 '#EXT-X-BYTERANGE:709136@5212676\n' +
38 'hls_450k_video.ts\n' +
39 '#EXTINF:10,\n' +
40 '#EXT-X-BYTERANGE:730004@5921812\n' +
41 'hls_450k_video.ts\n' +
42 '#EXTINF:10,\n' +
43 '#EXT-X-BYTERANGE:456276@6651816\n' +
44 'hls_450k_video.ts\n' +
45 '#EXTINF:10,\n' +
46 '#EXT-X-BYTERANGE:468684@7108092\n' +
47 'hls_450k_video.ts' +
48 '#EXTINF:10,\n' +
49 '#EXT-X-BYTERANGE:444996@7576776\n' +
50 'hls_450k_video.ts\n' +
51 '#EXTINF:10,\n' +
52 '#EXT-X-BYTERANGE:331444@8021772\n' +
53 'hls_450k_video.ts\n' +
54 '{{#if extInf2}}#EXTINF:{{{extInf2}}}{{/if}}\n' +
55 '#EXT-X-BYTERANGE:44556@8353216\n' +
56 'hls_450k_video.ts\n' +
57 '#EXT-X-ENDLIST';
1 #EXTM3U
2 #EXT-X-TARGETDURATION:10
3 #EXT-X-VERSION:{{{version}}}
4 #EXT-X-MEDIA-SEQUENCE:0
5 #EXT-X-PLAYLIST-TYPE:VOD
6 {{#if extInf}}#EXTINF:{{{extInf}}}{{/if}}
7 #EXT-X-BYTERANGE:522828@0
8 {{#if segment}}{{{segment}}}\n{{/if}}
9 {{#if extInf1}}#EXTINF:{{{extInf1}}}{{/if}}
10 #EXT-X-BYTERANGE:587500@522828
11 hls_450k_video.ts
12 #EXTINF:10,
13 #EXT-X-BYTERANGE:713084@1110328
14 hls_450k_video.ts
15 #EXTINF:10,
16 #EXT-X-BYTERANGE:476580@1823412
17 hls_450k_video.ts
18 #EXTINF:10,
19 #EXT-X-BYTERANGE:535612@2299992
20 hls_450k_video.ts
21 #EXTINF:10,
22 #EXT-X-BYTERANGE:207176@2835604
23 hls_450k_video.ts
24 #EXTINF:10,
25 #EXT-X-BYTERANGE:455900@3042780
26 hls_450k_video.ts
27 #EXTINF:10,
28 #EXT-X-BYTERANGE:657248@3498680
29 hls_450k_video.ts
30 #EXTINF:10,
31 #EXT-X-BYTERANGE:571708@4155928
32 hls_450k_video.ts
33 #EXTINF:10,
34 #EXT-X-BYTERANGE:485040@4727636
35 hls_450k_video.ts
36 #EXTINF:10,
37 #EXT-X-BYTERANGE:709136@5212676
38 hls_450k_video.ts
39 #EXTINF:10,
40 #EXT-X-BYTERANGE:730004@5921812
41 hls_450k_video.ts
42 #EXTINF:10,
43 #EXT-X-BYTERANGE:456276@6651816
44 hls_450k_video.ts
45 #EXTINF:10,
46 #EXT-X-BYTERANGE:468684@7108092
47 hls_450k_video.ts
48 #EXTINF:10,
49 #EXT-X-BYTERANGE:444996@7576776
50 hls_450k_video.ts
51 #EXTINF:10,
52 #EXT-X-BYTERANGE:331444@8021772
53 hls_450k_video.ts
54 {{#if extInf2}}#EXTINF:{{{extInf2}}}{{/if}}
55 #EXT-X-BYTERANGE:44556@8353216
56 hls_450k_video.ts
57 #EXT-X-ENDLIST
1 window.playlist_media_sequence_template = '#EXTM3U\n'+
2 '#EXT-X-PLAYLIST-TYPE:VOD\n'+
3 '{{#if mediaSequence}}#EXT-X-MEDIA-SEQUENCE:{{{mediaSequence}}}{{/if}}\n'+
4 '{{#if mediaSequence1}}#EXT-X-MEDIA-SEQUENCE:{{{mediaSequence1}}}{{/if}}\n'+
5 '#EXT-X-ALLOW-CACHE:YES\n'+
6 '#EXT-X-TARGETDURATION:8\n'+
7 '#EXTINF:6.640,{}\n'+
8 '/test/ts-files/tvy7/8a5e2822668b5370f4eb1438b2564fb7ab12ffe1-hi720.ts\n'+
9 '#EXTINF:6.080,{}\n'+
10 '/test/ts-files/tvy7/56be1cef869a1c0cc8e38864ad1add17d187f051-hi720.ts\n'+
11 '#EXTINF:6.600,{}\n'+
12 '/test/ts-files/tvy7/549c8c77f55f049741a06596e5c1e01dacaa46d0-hi720.ts\n'+
13 '#EXTINF:5.000,{}\n'+
14 '/test/ts-files/tvy7/6cfa378684ffeb1c455a64dae6c103290a1f53d4-hi720.ts\n'+
15 '#EXT-X-ENDLIST'
1 #EXTM3U
2 #EXT-X-PLAYLIST-TYPE:VOD
3 {{#if mediaSequence}}#EXT-X-MEDIA-SEQUENCE:{{{mediaSequence}}}{{/if}}
4 {{#if mediaSequence1}}#EXT-X-MEDIA-SEQUENCE:{{{mediaSequence2}}}{{/if}}
5 #EXT-X-ALLOW-CACHE:YES
6 #EXT-X-TARGETDURATION:8
7 #EXTINF:6.640,{}
8 /test/ts-files/tvy7/8a5e2822668b5370f4eb1438b2564fb7ab12ffe1-hi720.ts
9 #EXTINF:6.080,{}
10 /test/ts-files/tvy7/56be1cef869a1c0cc8e38864ad1add17d187f051-hi720.ts
11 #EXTINF:6.600,{}
12 /test/ts-files/tvy7/549c8c77f55f049741a06596e5c1e01dacaa46d0-hi720.ts
13 #EXTINF:5.000,{}
14 /test/ts-files/tvy7/6cfa378684ffeb1c455a64dae6c103290a1f53d4-hi720.ts
15 #EXT-X-ENDLIST
1 window.playlist_target_duration_template = '#EXTM3U\n'+
2 '#EXT-X-PLAYLIST-TYPE:VOD\n'+
3 '#EXT-X-MEDIA-SEQUENCE:0\n'+
4 '#EXT-X-ALLOW-CACHE:YES\n'+
5 '{{#if targetDuration}}#EXT-X-TARGETDURATION:{{{targetDuration}}}{{/if}}\n'+
6 '#EXTINF:6.640,{}\n'+
7 '/test/ts-files/tvy7/8a5e2822668b5370f4eb1438b2564fb7ab12ffe1-hi720.ts\n'+
8 '#EXTINF:6.080,{}\n'+
9 '/test/ts-files/tvy7/56be1cef869a1c0cc8e38864ad1add17d187f051-hi720.ts\n'+
10 '#EXTINF:6.600,{}\n'+
11 '/test/ts-files/tvy7/549c8c77f55f049741a06596e5c1e01dacaa46d0-hi720.ts\n'+
12 '#EXTINF:5.000,{}\n'+
13 '/test/ts-files/tvy7/6cfa378684ffeb1c455a64dae6c103290a1f53d4-hi720.ts\n'+
14 '#EXT-X-ENDLIST'
1 #EXTM3U
2 #EXT-X-PLAYLIST-TYPE:VOD
3 #EXT-X-MEDIA-SEQUENCE:0
4 #EXT-X-ALLOW-CACHE:YES
5 {{#if targetDuration}}#EXT-X-TARGETDURATION:{{{targetDuration}}}{{/if}}
6 #EXTINF:6.640,{}
7 /test/ts-files/tvy7/8a5e2822668b5370f4eb1438b2564fb7ab12ffe1-hi720.ts
8 #EXTINF:6.080,{}
9 /test/ts-files/tvy7/56be1cef869a1c0cc8e38864ad1add17d187f051-hi720.ts
10 #EXTINF:6.600,{}
11 /test/ts-files/tvy7/549c8c77f55f049741a06596e5c1e01dacaa46d0-hi720.ts
12 #EXTINF:5.000,{}
13 /test/ts-files/tvy7/6cfa378684ffeb1c455a64dae6c103290a1f53d4-hi720.ts
14 #EXT-X-ENDLIST
1 window.playlist_type_template = '#EXTM3U\n' +
2 '{{#if playlistType}}#EXT-X-PLAYLIST-TYPE:{{{playlistType}}}{{/if}}\n' +
3 '#EXT-X-TARGETDURATION:10\n' +
4 '#EXTINF:10,\n' +
5 '/test/ts-files/zencoder/haze/Haze_Mantel_President_encoded_1200-00001.ts\n' +
6 '#EXTINF:10,\n' +
7 '/test/ts-files/zencoder/haze/Haze_Mantel_President_encoded_1200-00002.ts\n' +
8 '#EXTINF:10,\n' +
9 '/test/ts-files/zencoder/haze/Haze_Mantel_President_encoded_1200-00003.ts\n' +
10 '#EXTINF:10,\n' +
11 '/test/ts-files/zencoder/haze/Haze_Mantel_President_encoded_1200-00004.ts\n' +
12 '#EXTINF:10,\n' +
13 '/test/ts-files/zencoder/haze/Haze_Mantel_President_encoded_1200-00005.ts\n' +
14 '#EXTINF:8,\n' +
15 '/test/ts-files/zencoder/haze/Haze_Mantel_President_encoded_1200-00006.ts\n' +
16 '#ZEN-TOTAL-DURATION:57.9911\n' +
17 '#EXT-X-ENDLIST';
1 #EXTM3U
2 {{#if playlistType}}#EXT-X-PLAYLIST-TYPE:{{{playlistType}}}{{/if}}
3 #EXT-X-TARGETDURATION:10
4 #EXTINF:10,
5 /test/ts-files/zencoder/haze/Haze_Mantel_President_encoded_1200-00001.ts
6 #EXTINF:10,
7 /test/ts-files/zencoder/haze/Haze_Mantel_President_encoded_1200-00002.ts
8 #EXTINF:10,
9 /test/ts-files/zencoder/haze/Haze_Mantel_President_encoded_1200-00003.ts
10 #EXTINF:10,
11 /test/ts-files/zencoder/haze/Haze_Mantel_President_encoded_1200-00004.ts
12 #EXTINF:10,
13 /test/ts-files/zencoder/haze/Haze_Mantel_President_encoded_1200-00005.ts
14 #EXTINF:8,
15 /test/ts-files/zencoder/haze/Haze_Mantel_President_encoded_1200-00006.ts
16 #ZEN-TOTAL-DURATION:57.9911
17 #EXT-X-ENDLIST
1 {
2 "allowCache": true,
3 "mediaSequence": 11,
4 "playlistType": "VOD",
5 "targetDuration": 8,
6 "segments": [{
7 "duration": 6.64,
8 "uri": "/test/ts-files/tvy7/8a5e2822668b5370f4eb1438b2564fb7ab12ffe1-hi720.ts"
9 }, {
10 "duration": 6.08,
11 "uri": "/test/ts-files/tvy7/56be1cef869a1c0cc8e38864ad1add17d187f051-hi720.ts"
12 }, {
13 "duration": 6.6,
14 "uri": "/test/ts-files/tvy7/549c8c77f55f049741a06596e5c1e01dacaa46d0-hi720.ts"
15 }, {
16 "duration": 5,
17 "uri": "/test/ts-files/tvy7/6cfa378684ffeb1c455a64dae6c103290a1f53d4-hi720.ts"
18 }]
19 }
1 #EXTM3U
2 #EXT-X-PLAYLIST-TYPE:VOD
3 #EXT-X-MEDIA-SEQUENCE:0
4 #EXT-X-MEDIA-SEQUENCE:11
5 #EXT-X-ALLOW-CACHE:YES
6 #EXT-X-TARGETDURATION:8
7 #EXTINF:6.640,{}
8 /test/ts-files/tvy7/8a5e2822668b5370f4eb1438b2564fb7ab12ffe1-hi720.ts
9 #EXTINF:6.080,{}
10 /test/ts-files/tvy7/56be1cef869a1c0cc8e38864ad1add17d187f051-hi720.ts
11 #EXTINF:6.600,{}
12 /test/ts-files/tvy7/549c8c77f55f049741a06596e5c1e01dacaa46d0-hi720.ts
13 #EXTINF:5.000,{}
14 /test/ts-files/tvy7/6cfa378684ffeb1c455a64dae6c103290a1f53d4-hi720.ts
15 #EXT-X-ENDLIST
...@@ -7,9 +7,6 @@ ...@@ -7,9 +7,6 @@
7 <link rel="stylesheet" href="../libs/qunit/qunit.css" media="screen"> 7 <link rel="stylesheet" href="../libs/qunit/qunit.css" media="screen">
8 <script src="../libs/qunit/qunit.js"></script> 8 <script src="../libs/qunit/qunit.js"></script>
9 9
10 <!-- handlebars.js -->
11 <script src="../libs/handlebars/handlebars-v1.1.2.js"></script>
12
13 <!-- video.js --> 10 <!-- video.js -->
14 <script src="../node_modules/video.js/dist/video-js/video.js"></script> 11 <script src="../node_modules/video.js/dist/video-js/video.js"></script>
15 12
...@@ -25,15 +22,6 @@ ...@@ -25,15 +22,6 @@
25 <script src="../src/m3u8/m3u8-parser.js"></script> 22 <script src="../src/m3u8/m3u8-parser.js"></script>
26 <script src="../src/manifest-controller.js"></script> 23 <script src="../src/manifest-controller.js"></script>
27 <!-- M3U8 TEST DATA --> 24 <!-- M3U8 TEST DATA -->
28 <script src="manifest/playlistM3U8data.js"></script>
29 <script src="manifest/brightcove_playlist_m3u8.js"></script>
30 <script src="manifest/playlist_type_template.js"></script>
31 <script src="manifest/playlist_media_sequence_template.js"></script>
32 <script src="manifest/playlist_target_duration_template.js"></script>
33 <script src="manifest/playlist_extinf_template.js"></script>
34 <script src="manifest/playlist_allow_cache_template.js"></script>
35 <script src="manifest/playlist_byte_range_template.js"></script>
36
37 <script src="../tmp/manifests.js"></script> 25 <script src="../tmp/manifests.js"></script>
38 <script src="../tmp/expected.js"></script> 26 <script src="../tmp/expected.js"></script>
39 27
......