UNPKG

180 kBJavaScriptView Raw
1/*
2 * liquidjs@9.33.1, https://github.com/harttle/liquidjs
3 * (c) 2016-2022 harttle
4 * Released under the MIT License.
5 */
6(function (global, factory) {
7 typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports) :
8 typeof define === 'function' && define.amd ? define(['exports'], factory) :
9 (global = typeof globalThis !== 'undefined' ? globalThis : global || self, factory(global.liquidjs = {}));
10})(this, (function (exports) { 'use strict';
11
12 /*! *****************************************************************************
13 Copyright (c) Microsoft Corporation.
14
15 Permission to use, copy, modify, and/or distribute this software for any
16 purpose with or without fee is hereby granted.
17
18 THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH
19 REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
20 AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,
21 INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
22 LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
23 OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
24 PERFORMANCE OF THIS SOFTWARE.
25 ***************************************************************************** */
26 /* global Reflect, Promise */
27
28 var extendStatics = function(d, b) {
29 extendStatics = Object.setPrototypeOf ||
30 ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||
31 function (d, b) { for (var p in b) if (Object.prototype.hasOwnProperty.call(b, p)) d[p] = b[p]; };
32 return extendStatics(d, b);
33 };
34
35 function __extends(d, b) {
36 if (typeof b !== "function" && b !== null)
37 throw new TypeError("Class extends value " + String(b) + " is not a constructor or null");
38 extendStatics(d, b);
39 function __() { this.constructor = d; }
40 d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
41 }
42
43 var __assign = function() {
44 __assign = Object.assign || function __assign(t) {
45 for (var s, i = 1, n = arguments.length; i < n; i++) {
46 s = arguments[i];
47 for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p)) t[p] = s[p];
48 }
49 return t;
50 };
51 return __assign.apply(this, arguments);
52 };
53
54 function __awaiter(thisArg, _arguments, P, generator) {
55 function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
56 return new (P || (P = Promise))(function (resolve, reject) {
57 function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
58 function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
59 function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
60 step((generator = generator.apply(thisArg, _arguments || [])).next());
61 });
62 }
63
64 function __generator(thisArg, body) {
65 var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g;
66 return g = { next: verb(0), "throw": verb(1), "return": verb(2) }, typeof Symbol === "function" && (g[Symbol.iterator] = function() { return this; }), g;
67 function verb(n) { return function (v) { return step([n, v]); }; }
68 function step(op) {
69 if (f) throw new TypeError("Generator is already executing.");
70 while (_) try {
71 if (f = 1, y && (t = op[0] & 2 ? y["return"] : op[0] ? y["throw"] || ((t = y["return"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t;
72 if (y = 0, t) op = [op[0] & 2, t.value];
73 switch (op[0]) {
74 case 0: case 1: t = op; break;
75 case 4: _.label++; return { value: op[1], done: false };
76 case 5: _.label++; y = op[1]; op = [0]; continue;
77 case 7: op = _.ops.pop(); _.trys.pop(); continue;
78 default:
79 if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; }
80 if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; }
81 if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; }
82 if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; }
83 if (t[2]) _.ops.pop();
84 _.trys.pop(); continue;
85 }
86 op = body.call(thisArg, _);
87 } catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; }
88 if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true };
89 }
90 }
91
92 function __values(o) {
93 var s = typeof Symbol === "function" && Symbol.iterator, m = s && o[s], i = 0;
94 if (m) return m.call(o);
95 if (o && typeof o.length === "number") return {
96 next: function () {
97 if (o && i >= o.length) o = void 0;
98 return { value: o && o[i++], done: !o };
99 }
100 };
101 throw new TypeError(s ? "Object is not iterable." : "Symbol.iterator is not defined.");
102 }
103
104 function __read(o, n) {
105 var m = typeof Symbol === "function" && o[Symbol.iterator];
106 if (!m) return o;
107 var i = m.call(o), r, ar = [], e;
108 try {
109 while ((n === void 0 || n-- > 0) && !(r = i.next()).done) ar.push(r.value);
110 }
111 catch (error) { e = { error: error }; }
112 finally {
113 try {
114 if (r && !r.done && (m = i["return"])) m.call(i);
115 }
116 finally { if (e) throw e.error; }
117 }
118 return ar;
119 }
120
121 function __spreadArray(to, from, pack) {
122 if (pack || arguments.length === 2) for (var i = 0, l = from.length, ar; i < l; i++) {
123 if (ar || !(i in from)) {
124 if (!ar) ar = Array.prototype.slice.call(from, 0, i);
125 ar[i] = from[i];
126 }
127 }
128 return to.concat(ar || Array.prototype.slice.call(from));
129 }
130
131 var Drop = /** @class */ (function () {
132 function Drop() {
133 }
134 Drop.prototype.valueOf = function () {
135 return undefined;
136 };
137 Drop.prototype.liquidMethodMissing = function (key) {
138 return undefined;
139 };
140 return Drop;
141 }());
142
143 var toStr = Object.prototype.toString;
144 var toLowerCase = String.prototype.toLowerCase;
145 function isString(value) {
146 return typeof value === 'string';
147 }
148 // eslint-disable-next-line @typescript-eslint/ban-types
149 function isFunction(value) {
150 return typeof value === 'function';
151 }
152 function escapeRegex(str) {
153 return str.replace(/[-/\\^$*+?.()|[\]{}]/g, '\\$&');
154 }
155 function stringify(value) {
156 value = toValue$1(value);
157 if (isString(value))
158 return value;
159 if (isNil(value))
160 return '';
161 return String(value);
162 }
163 function toValue$1(value) {
164 return value instanceof Drop ? value.valueOf() : value;
165 }
166 function isNumber(value) {
167 return typeof value === 'number';
168 }
169 function toLiquid(value) {
170 if (value && isFunction(value.toLiquid))
171 return toLiquid(value.toLiquid());
172 return value;
173 }
174 function isNil(value) {
175 return value == null;
176 }
177 function isArray(value) {
178 // be compatible with IE 8
179 return toStr.call(value) === '[object Array]';
180 }
181 /*
182 * Iterates over own enumerable string keyed properties of an object and invokes iteratee for each property.
183 * The iteratee is invoked with three arguments: (value, key, object).
184 * Iteratee functions may exit iteration early by explicitly returning false.
185 * @param {Object} object The object to iterate over.
186 * @param {Function} iteratee The function invoked per iteration.
187 * @return {Object} Returns object.
188 */
189 function forOwn(obj, iteratee) {
190 obj = obj || {};
191 for (var k in obj) {
192 if (Object.hasOwnProperty.call(obj, k)) {
193 if (iteratee(obj[k], k, obj) === false)
194 break;
195 }
196 }
197 return obj;
198 }
199 function last$1(arr) {
200 return arr[arr.length - 1];
201 }
202 /*
203 * Checks if value is the language type of Object.
204 * (e.g. arrays, functions, objects, regexes, new Number(0), and new String(''))
205 * @param {any} value The value to check.
206 * @return {Boolean} Returns true if value is an object, else false.
207 */
208 function isObject(value) {
209 var type = typeof value;
210 return value !== null && (type === 'object' || type === 'function');
211 }
212 function range(start, stop, step) {
213 if (step === void 0) { step = 1; }
214 var arr = [];
215 for (var i = start; i < stop; i += step) {
216 arr.push(i);
217 }
218 return arr;
219 }
220 function padStart(str, length, ch) {
221 if (ch === void 0) { ch = ' '; }
222 return pad(str, length, ch, function (str, ch) { return ch + str; });
223 }
224 function padEnd(str, length, ch) {
225 if (ch === void 0) { ch = ' '; }
226 return pad(str, length, ch, function (str, ch) { return str + ch; });
227 }
228 function pad(str, length, ch, add) {
229 str = String(str);
230 var n = length - str.length;
231 while (n-- > 0)
232 str = add(str, ch);
233 return str;
234 }
235 function identify(val) {
236 return val;
237 }
238 function snakeCase(str) {
239 return str.replace(/(\w?)([A-Z])/g, function (_, a, b) { return (a ? a + '_' : '') + b.toLowerCase(); });
240 }
241 function changeCase(str) {
242 var hasLowerCase = __spreadArray([], __read(str), false).some(function (ch) { return ch >= 'a' && ch <= 'z'; });
243 return hasLowerCase ? str.toUpperCase() : str.toLowerCase();
244 }
245 function ellipsis(str, N) {
246 return str.length > N ? str.substr(0, N - 3) + '...' : str;
247 }
248 // compare string in case-insensitive way, undefined values to the tail
249 function caseInsensitiveCompare(a, b) {
250 if (a == null && b == null)
251 return 0;
252 if (a == null)
253 return 1;
254 if (b == null)
255 return -1;
256 a = toLowerCase.call(a);
257 b = toLowerCase.call(b);
258 if (a < b)
259 return -1;
260 if (a > b)
261 return 1;
262 return 0;
263 }
264
265 var Node = /** @class */ (function () {
266 function Node(key, value, next, prev) {
267 this.key = key;
268 this.value = value;
269 this.next = next;
270 this.prev = prev;
271 }
272 return Node;
273 }());
274 var LRU = /** @class */ (function () {
275 function LRU(limit, size) {
276 if (size === void 0) { size = 0; }
277 this.limit = limit;
278 this.size = size;
279 this.cache = {};
280 this.head = new Node('HEAD', null, null, null);
281 this.tail = new Node('TAIL', null, null, null);
282 this.head.next = this.tail;
283 this.tail.prev = this.head;
284 }
285 LRU.prototype.write = function (key, value) {
286 if (this.cache[key]) {
287 this.cache[key].value = value;
288 }
289 else {
290 var node = new Node(key, value, this.head.next, this.head);
291 this.head.next.prev = node;
292 this.head.next = node;
293 this.cache[key] = node;
294 this.size++;
295 this.ensureLimit();
296 }
297 };
298 LRU.prototype.read = function (key) {
299 if (!this.cache[key])
300 return;
301 var value = this.cache[key].value;
302 this.remove(key);
303 this.write(key, value);
304 return value;
305 };
306 LRU.prototype.remove = function (key) {
307 var node = this.cache[key];
308 node.prev.next = node.next;
309 node.next.prev = node.prev;
310 delete this.cache[key];
311 this.size--;
312 };
313 LRU.prototype.clear = function () {
314 this.head.next = this.tail;
315 this.tail.prev = this.head;
316 this.size = 0;
317 this.cache = {};
318 };
319 LRU.prototype.ensureLimit = function () {
320 if (this.size > this.limit)
321 this.remove(this.tail.prev.key);
322 };
323 return LRU;
324 }());
325
326 function domResolve(root, path) {
327 var base = document.createElement('base');
328 base.href = root;
329 var head = document.getElementsByTagName('head')[0];
330 head.insertBefore(base, head.firstChild);
331 var a = document.createElement('a');
332 a.href = path;
333 var resolved = a.href;
334 head.removeChild(base);
335 return resolved;
336 }
337 function resolve(root, filepath, ext) {
338 if (root.length && last$1(root) !== '/')
339 root += '/';
340 var url = domResolve(root, filepath);
341 return url.replace(/^(\w+:\/\/[^/]+)(\/[^?]+)/, function (str, origin, path) {
342 var last = path.split('/').pop();
343 if (/\.\w+$/.test(last))
344 return str;
345 return origin + path + ext;
346 });
347 }
348 function readFile(url) {
349 return __awaiter(this, void 0, void 0, function () {
350 return __generator(this, function (_a) {
351 return [2 /*return*/, new Promise(function (resolve, reject) {
352 var xhr = new XMLHttpRequest();
353 xhr.onload = function () {
354 if (xhr.status >= 200 && xhr.status < 300) {
355 resolve(xhr.responseText);
356 }
357 else {
358 reject(new Error(xhr.statusText));
359 }
360 };
361 xhr.onerror = function () {
362 reject(new Error('An error occurred whilst receiving the response.'));
363 };
364 xhr.open('GET', url);
365 xhr.send();
366 })];
367 });
368 });
369 }
370 function readFileSync(url) {
371 var xhr = new XMLHttpRequest();
372 xhr.open('GET', url, false);
373 xhr.send();
374 if (xhr.status < 200 || xhr.status >= 300) {
375 throw new Error(xhr.statusText);
376 }
377 return xhr.responseText;
378 }
379 function exists(filepath) {
380 return __awaiter(this, void 0, void 0, function () {
381 return __generator(this, function (_a) {
382 return [2 /*return*/, true];
383 });
384 });
385 }
386 function existsSync(filepath) {
387 return true;
388 }
389 function dirname(filepath) {
390 return domResolve(filepath, '.');
391 }
392 var sep = '/';
393
394 var fs = /*#__PURE__*/Object.freeze({
395 __proto__: null,
396 resolve: resolve,
397 readFile: readFile,
398 readFileSync: readFileSync,
399 exists: exists,
400 existsSync: existsSync,
401 dirname: dirname,
402 sep: sep
403 });
404
405 function isComparable(arg) {
406 return arg && isFunction(arg.equals);
407 }
408
409 function isTruthy(val, ctx) {
410 return !isFalsy(val, ctx);
411 }
412 function isFalsy(val, ctx) {
413 if (ctx.opts.jsTruthy) {
414 return !val;
415 }
416 else {
417 return val === false || undefined === val || val === null;
418 }
419 }
420
421 var defaultOperators = {
422 '==': function (l, r) {
423 if (isComparable(l))
424 return l.equals(r);
425 if (isComparable(r))
426 return r.equals(l);
427 return l === r;
428 },
429 '!=': function (l, r) {
430 if (isComparable(l))
431 return !l.equals(r);
432 if (isComparable(r))
433 return !r.equals(l);
434 return l !== r;
435 },
436 '>': function (l, r) {
437 if (isComparable(l))
438 return l.gt(r);
439 if (isComparable(r))
440 return r.lt(l);
441 return l > r;
442 },
443 '<': function (l, r) {
444 if (isComparable(l))
445 return l.lt(r);
446 if (isComparable(r))
447 return r.gt(l);
448 return l < r;
449 },
450 '>=': function (l, r) {
451 if (isComparable(l))
452 return l.geq(r);
453 if (isComparable(r))
454 return r.leq(l);
455 return l >= r;
456 },
457 '<=': function (l, r) {
458 if (isComparable(l))
459 return l.leq(r);
460 if (isComparable(r))
461 return r.geq(l);
462 return l <= r;
463 },
464 'contains': function (l, r) {
465 return l && isFunction(l.indexOf) ? l.indexOf(r) > -1 : false;
466 },
467 'and': function (l, r, ctx) { return isTruthy(l, ctx) && isTruthy(r, ctx); },
468 'or': function (l, r, ctx) { return isTruthy(l, ctx) || isTruthy(r, ctx); }
469 };
470
471 // **DO NOT CHANGE THIS FILE**
472 //
473 // This file is generated by bin/character-gen.js
474 // bitmask character types to boost performance
475 var TYPES = [0, 0, 0, 0, 0, 0, 0, 0, 0, 20, 4, 4, 4, 20, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 20, 2, 8, 0, 0, 0, 0, 8, 0, 0, 0, 64, 0, 65, 0, 0, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 0, 0, 2, 2, 2, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0];
476 var IDENTIFIER = 1;
477 var BLANK = 4;
478 var QUOTE = 8;
479 var INLINE_BLANK = 16;
480 var NUMBER = 32;
481 var SIGN = 64;
482 TYPES[160] = TYPES[5760] = TYPES[6158] = TYPES[8192] = TYPES[8193] = TYPES[8194] = TYPES[8195] = TYPES[8196] = TYPES[8197] = TYPES[8198] = TYPES[8199] = TYPES[8200] = TYPES[8201] = TYPES[8202] = TYPES[8232] = TYPES[8233] = TYPES[8239] = TYPES[8287] = TYPES[12288] = BLANK;
483
484 function createTrie(operators) {
485 var e_1, _a;
486 var trie = {};
487 try {
488 for (var _b = __values(Object.entries(operators)), _c = _b.next(); !_c.done; _c = _b.next()) {
489 var _d = __read(_c.value, 2), name_1 = _d[0], handler = _d[1];
490 var node = trie;
491 for (var i = 0; i < name_1.length; i++) {
492 var c = name_1[i];
493 node[c] = node[c] || {};
494 if (i === name_1.length - 1 && (TYPES[name_1.charCodeAt(i)] & IDENTIFIER)) {
495 node[c].needBoundary = true;
496 }
497 node = node[c];
498 }
499 node.handler = handler;
500 node.end = true;
501 }
502 }
503 catch (e_1_1) { e_1 = { error: e_1_1 }; }
504 finally {
505 try {
506 if (_c && !_c.done && (_a = _b.return)) _a.call(_b);
507 }
508 finally { if (e_1) throw e_1.error; }
509 }
510 return trie;
511 }
512
513 var defaultOptions = {
514 root: ['.'],
515 layouts: ['.'],
516 partials: ['.'],
517 relativeReference: true,
518 jekyllInclude: false,
519 cache: undefined,
520 extname: '',
521 fs: fs,
522 dynamicPartials: true,
523 jsTruthy: false,
524 trimTagRight: false,
525 trimTagLeft: false,
526 trimOutputRight: false,
527 trimOutputLeft: false,
528 greedy: true,
529 tagDelimiterLeft: '{%',
530 tagDelimiterRight: '%}',
531 outputDelimiterLeft: '{{',
532 outputDelimiterRight: '}}',
533 preserveTimezones: false,
534 strictFilters: false,
535 strictVariables: false,
536 lenientIf: false,
537 globals: {},
538 keepOutputType: false,
539 operators: defaultOperators,
540 operatorsTrie: createTrie(defaultOperators)
541 };
542 function normalize(options) {
543 if (options.hasOwnProperty('operators')) {
544 options.operatorsTrie = createTrie(options.operators);
545 }
546 if (options.hasOwnProperty('root')) {
547 if (!options.hasOwnProperty('partials'))
548 options.partials = options.root;
549 if (!options.hasOwnProperty('layouts'))
550 options.layouts = options.root;
551 }
552 if (options.hasOwnProperty('cache')) {
553 var cache = void 0;
554 if (typeof options.cache === 'number')
555 cache = options.cache > 0 ? new LRU(options.cache) : undefined;
556 else if (typeof options.cache === 'object')
557 cache = options.cache;
558 else
559 cache = options.cache ? new LRU(1024) : undefined;
560 options.cache = cache;
561 }
562 options = __assign(__assign(__assign({}, defaultOptions), (options.jekyllInclude ? { dynamicPartials: false } : {})), options);
563 if (!options.fs.dirname && options.relativeReference) {
564 console.warn('[LiquidJS] `fs.dirname` is required for relativeReference, set relativeReference to `false` to suppress this warning, or provide implementation for `fs.dirname`');
565 options.relativeReference = false;
566 }
567 options.root = normalizeDirectoryList(options.root);
568 options.partials = normalizeDirectoryList(options.partials);
569 options.layouts = normalizeDirectoryList(options.layouts);
570 return options;
571 }
572 function normalizeDirectoryList(value) {
573 var list = [];
574 if (isArray(value))
575 list = value;
576 if (isString(value))
577 list = [value];
578 return list;
579 }
580
581 var LiquidError = /** @class */ (function (_super) {
582 __extends(LiquidError, _super);
583 function LiquidError(err, token) {
584 var _this = _super.call(this, err.message) || this;
585 _this.originalError = err;
586 _this.token = token;
587 _this.context = '';
588 return _this;
589 }
590 LiquidError.prototype.update = function () {
591 var err = this.originalError;
592 this.context = mkContext(this.token);
593 this.message = mkMessage(err.message, this.token);
594 this.stack = this.message + '\n' + this.context +
595 '\n' + this.stack + '\nFrom ' + err.stack;
596 };
597 return LiquidError;
598 }(Error));
599 var TokenizationError = /** @class */ (function (_super) {
600 __extends(TokenizationError, _super);
601 function TokenizationError(message, token) {
602 var _this = _super.call(this, new Error(message), token) || this;
603 _this.name = 'TokenizationError';
604 _super.prototype.update.call(_this);
605 return _this;
606 }
607 return TokenizationError;
608 }(LiquidError));
609 var ParseError = /** @class */ (function (_super) {
610 __extends(ParseError, _super);
611 function ParseError(err, token) {
612 var _this = _super.call(this, err, token) || this;
613 _this.name = 'ParseError';
614 _this.message = err.message;
615 _super.prototype.update.call(_this);
616 return _this;
617 }
618 return ParseError;
619 }(LiquidError));
620 var RenderError = /** @class */ (function (_super) {
621 __extends(RenderError, _super);
622 function RenderError(err, tpl) {
623 var _this = _super.call(this, err, tpl.token) || this;
624 _this.name = 'RenderError';
625 _this.message = err.message;
626 _super.prototype.update.call(_this);
627 return _this;
628 }
629 RenderError.is = function (obj) {
630 return obj.name === 'RenderError';
631 };
632 return RenderError;
633 }(LiquidError));
634 var UndefinedVariableError = /** @class */ (function (_super) {
635 __extends(UndefinedVariableError, _super);
636 function UndefinedVariableError(err, token) {
637 var _this = _super.call(this, err, token) || this;
638 _this.name = 'UndefinedVariableError';
639 _this.message = err.message;
640 _super.prototype.update.call(_this);
641 return _this;
642 }
643 return UndefinedVariableError;
644 }(LiquidError));
645 // only used internally; raised where we don't have token information,
646 // so it can't be an UndefinedVariableError.
647 var InternalUndefinedVariableError = /** @class */ (function (_super) {
648 __extends(InternalUndefinedVariableError, _super);
649 function InternalUndefinedVariableError(variableName) {
650 var _this = _super.call(this, "undefined variable: ".concat(variableName)) || this;
651 _this.name = 'InternalUndefinedVariableError';
652 _this.variableName = variableName;
653 return _this;
654 }
655 return InternalUndefinedVariableError;
656 }(Error));
657 var AssertionError = /** @class */ (function (_super) {
658 __extends(AssertionError, _super);
659 function AssertionError(message) {
660 var _this = _super.call(this, message) || this;
661 _this.name = 'AssertionError';
662 _this.message = message + '';
663 return _this;
664 }
665 return AssertionError;
666 }(Error));
667 function mkContext(token) {
668 var _a = __read(token.getPosition(), 1), line = _a[0];
669 var lines = token.input.split('\n');
670 var begin = Math.max(line - 2, 1);
671 var end = Math.min(line + 3, lines.length);
672 var context = range(begin, end + 1)
673 .map(function (lineNumber) {
674 var indicator = (lineNumber === line) ? '>> ' : ' ';
675 var num = padStart(String(lineNumber), String(end).length);
676 var text = lines[lineNumber - 1];
677 return "".concat(indicator).concat(num, "| ").concat(text);
678 })
679 .join('\n');
680 return context;
681 }
682 function mkMessage(msg, token) {
683 if (token.file)
684 msg += ", file:".concat(token.file);
685 var _a = __read(token.getPosition(), 2), line = _a[0], col = _a[1];
686 msg += ", line:".concat(line, ", col:").concat(col);
687 return msg;
688 }
689
690 var Context = /** @class */ (function () {
691 function Context(env, opts, renderOptions) {
692 if (env === void 0) { env = {}; }
693 if (opts === void 0) { opts = defaultOptions; }
694 if (renderOptions === void 0) { renderOptions = {}; }
695 var _a, _b;
696 /**
697 * insert a Context-level empty scope,
698 * for tags like {% capture %} {% assign %} to operate
699 */
700 this.scopes = [{}];
701 this.registers = {};
702 this.sync = !!renderOptions.sync;
703 this.opts = opts;
704 this.globals = (_a = renderOptions.globals) !== null && _a !== void 0 ? _a : opts.globals;
705 this.environments = env;
706 this.strictVariables = (_b = renderOptions.strictVariables) !== null && _b !== void 0 ? _b : this.opts.strictVariables;
707 }
708 Context.prototype.getRegister = function (key) {
709 return (this.registers[key] = this.registers[key] || {});
710 };
711 Context.prototype.setRegister = function (key, value) {
712 return (this.registers[key] = value);
713 };
714 Context.prototype.saveRegister = function () {
715 var _this = this;
716 var keys = [];
717 for (var _i = 0; _i < arguments.length; _i++) {
718 keys[_i] = arguments[_i];
719 }
720 return keys.map(function (key) { return [key, _this.getRegister(key)]; });
721 };
722 Context.prototype.restoreRegister = function (keyValues) {
723 var _this = this;
724 return keyValues.forEach(function (_a) {
725 var _b = __read(_a, 2), key = _b[0], value = _b[1];
726 return _this.setRegister(key, value);
727 });
728 };
729 Context.prototype.getAll = function () {
730 return __spreadArray([this.globals, this.environments], __read(this.scopes), false).reduce(function (ctx, val) { return __assign(ctx, val); }, {});
731 };
732 Context.prototype.get = function (paths) {
733 var scope = this.findScope(paths[0]);
734 return this.getFromScope(scope, paths);
735 };
736 Context.prototype.getFromScope = function (scope, paths) {
737 var _this = this;
738 if (typeof paths === 'string')
739 paths = paths.split('.');
740 return paths.reduce(function (scope, path) {
741 scope = readProperty(scope, path);
742 if (isNil(scope) && _this.strictVariables) {
743 throw new InternalUndefinedVariableError(path);
744 }
745 return scope;
746 }, scope);
747 };
748 Context.prototype.push = function (ctx) {
749 return this.scopes.push(ctx);
750 };
751 Context.prototype.pop = function () {
752 return this.scopes.pop();
753 };
754 Context.prototype.bottom = function () {
755 return this.scopes[0];
756 };
757 Context.prototype.findScope = function (key) {
758 for (var i = this.scopes.length - 1; i >= 0; i--) {
759 var candidate = this.scopes[i];
760 if (key in candidate)
761 return candidate;
762 }
763 if (key in this.environments)
764 return this.environments;
765 return this.globals;
766 };
767 return Context;
768 }());
769 function readProperty(obj, key) {
770 if (isNil(obj))
771 return obj;
772 obj = toLiquid(obj);
773 if (isFunction(obj[key]))
774 return obj[key]();
775 if (obj instanceof Drop) {
776 if (obj.hasOwnProperty(key))
777 return obj[key];
778 return obj.liquidMethodMissing(key);
779 }
780 if (key === 'size')
781 return readSize(obj);
782 if (key === 'first')
783 return readFirst(obj);
784 if (key === 'last')
785 return readLast(obj);
786 return obj[key];
787 }
788 function readFirst(obj) {
789 if (isArray(obj))
790 return obj[0];
791 return obj['first'];
792 }
793 function readLast(obj) {
794 if (isArray(obj))
795 return obj[obj.length - 1];
796 return obj['last'];
797 }
798 function readSize(obj) {
799 if (obj.hasOwnProperty('size') || obj['size'] !== undefined)
800 return obj['size'];
801 if (isArray(obj) || isString(obj))
802 return obj.length;
803 if (typeof obj === 'object')
804 return Object.keys(obj).length;
805 }
806
807 function assert(predicate, message) {
808 if (!predicate) {
809 var msg = typeof message === 'function'
810 ? message()
811 : (message || "expect ".concat(predicate, " to be true"));
812 throw new AssertionError(msg);
813 }
814 }
815
816 var LookupType;
817 (function (LookupType) {
818 LookupType["Partials"] = "partials";
819 LookupType["Layouts"] = "layouts";
820 LookupType["Root"] = "root";
821 })(LookupType || (LookupType = {}));
822 var Loader = /** @class */ (function () {
823 function Loader(options) {
824 this.options = options;
825 if (options.relativeReference) {
826 var sep = options.fs.sep;
827 assert(sep, '`fs.sep` is required for relative reference');
828 var rRelativePath_1 = new RegExp(['.' + sep, '..' + sep, './', '../'].map(function (prefix) { return escapeRegex(prefix); }).join('|'));
829 this.shouldLoadRelative = function (referencedFile) { return rRelativePath_1.test(referencedFile); };
830 }
831 else {
832 this.shouldLoadRelative = function (referencedFile) { return false; };
833 }
834 this.contains = this.options.fs.contains || (function () { return true; });
835 }
836 Loader.prototype.lookup = function (file, type, sync, currentFile) {
837 var fs, dirs, _a, _b, filepath, _c, e_1_1;
838 var e_1, _d;
839 return __generator(this, function (_e) {
840 switch (_e.label) {
841 case 0:
842 fs = this.options.fs;
843 dirs = this.options[type];
844 _e.label = 1;
845 case 1:
846 _e.trys.push([1, 8, 9, 10]);
847 _a = __values(this.candidates(file, dirs, currentFile, type !== LookupType.Root)), _b = _a.next();
848 _e.label = 2;
849 case 2:
850 if (!!_b.done) return [3 /*break*/, 7];
851 filepath = _b.value;
852 if (!sync) return [3 /*break*/, 3];
853 _c = fs.existsSync(filepath);
854 return [3 /*break*/, 5];
855 case 3: return [4 /*yield*/, fs.exists(filepath)];
856 case 4:
857 _c = _e.sent();
858 _e.label = 5;
859 case 5:
860 if (_c)
861 return [2 /*return*/, filepath];
862 _e.label = 6;
863 case 6:
864 _b = _a.next();
865 return [3 /*break*/, 2];
866 case 7: return [3 /*break*/, 10];
867 case 8:
868 e_1_1 = _e.sent();
869 e_1 = { error: e_1_1 };
870 return [3 /*break*/, 10];
871 case 9:
872 try {
873 if (_b && !_b.done && (_d = _a.return)) _d.call(_a);
874 }
875 finally { if (e_1) throw e_1.error; }
876 return [7 /*endfinally*/];
877 case 10: throw this.lookupError(file, dirs);
878 }
879 });
880 };
881 Loader.prototype.candidates = function (file, dirs, currentFile, enforceRoot) {
882 var _a, fs, extname, referenced, dirs_1, dirs_1_1, dir, e_2_1, dirs_2, dirs_2_1, dir, referenced, e_3_1, filepath;
883 var e_2, _b, e_3, _c;
884 return __generator(this, function (_d) {
885 switch (_d.label) {
886 case 0:
887 _a = this.options, fs = _a.fs, extname = _a.extname;
888 if (!(this.shouldLoadRelative(file) && currentFile)) return [3 /*break*/, 8];
889 referenced = fs.resolve(this.dirname(currentFile), file, extname);
890 _d.label = 1;
891 case 1:
892 _d.trys.push([1, 6, 7, 8]);
893 dirs_1 = __values(dirs), dirs_1_1 = dirs_1.next();
894 _d.label = 2;
895 case 2:
896 if (!!dirs_1_1.done) return [3 /*break*/, 5];
897 dir = dirs_1_1.value;
898 if (!(!enforceRoot || this.contains(dir, referenced))) return [3 /*break*/, 4];
899 // the relatively referenced file is within one of root dirs
900 return [4 /*yield*/, referenced];
901 case 3:
902 // the relatively referenced file is within one of root dirs
903 _d.sent();
904 return [3 /*break*/, 5];
905 case 4:
906 dirs_1_1 = dirs_1.next();
907 return [3 /*break*/, 2];
908 case 5: return [3 /*break*/, 8];
909 case 6:
910 e_2_1 = _d.sent();
911 e_2 = { error: e_2_1 };
912 return [3 /*break*/, 8];
913 case 7:
914 try {
915 if (dirs_1_1 && !dirs_1_1.done && (_b = dirs_1.return)) _b.call(dirs_1);
916 }
917 finally { if (e_2) throw e_2.error; }
918 return [7 /*endfinally*/];
919 case 8:
920 _d.trys.push([8, 13, 14, 15]);
921 dirs_2 = __values(dirs), dirs_2_1 = dirs_2.next();
922 _d.label = 9;
923 case 9:
924 if (!!dirs_2_1.done) return [3 /*break*/, 12];
925 dir = dirs_2_1.value;
926 referenced = fs.resolve(dir, file, extname);
927 if (!(!enforceRoot || this.contains(dir, referenced))) return [3 /*break*/, 11];
928 return [4 /*yield*/, referenced];
929 case 10:
930 _d.sent();
931 _d.label = 11;
932 case 11:
933 dirs_2_1 = dirs_2.next();
934 return [3 /*break*/, 9];
935 case 12: return [3 /*break*/, 15];
936 case 13:
937 e_3_1 = _d.sent();
938 e_3 = { error: e_3_1 };
939 return [3 /*break*/, 15];
940 case 14:
941 try {
942 if (dirs_2_1 && !dirs_2_1.done && (_c = dirs_2.return)) _c.call(dirs_2);
943 }
944 finally { if (e_3) throw e_3.error; }
945 return [7 /*endfinally*/];
946 case 15:
947 if (!(fs.fallback !== undefined)) return [3 /*break*/, 17];
948 filepath = fs.fallback(file);
949 if (!(filepath !== undefined)) return [3 /*break*/, 17];
950 return [4 /*yield*/, filepath];
951 case 16:
952 _d.sent();
953 _d.label = 17;
954 case 17: return [2 /*return*/];
955 }
956 });
957 };
958 Loader.prototype.dirname = function (path) {
959 var fs = this.options.fs;
960 assert(fs.dirname, '`fs.dirname` is required for relative reference');
961 return fs.dirname(path);
962 };
963 Loader.prototype.lookupError = function (file, roots) {
964 var err = new Error('ENOENT');
965 err.message = "ENOENT: Failed to lookup \"".concat(file, "\" in \"").concat(roots, "\"");
966 err.code = 'ENOENT';
967 return err;
968 };
969 return Loader;
970 }());
971
972 var SimpleEmitter = /** @class */ (function () {
973 function SimpleEmitter() {
974 this.buffer = '';
975 }
976 SimpleEmitter.prototype.write = function (html) {
977 this.buffer += stringify(html);
978 };
979 return SimpleEmitter;
980 }());
981
982 var StreamedEmitter = /** @class */ (function () {
983 function StreamedEmitter() {
984 this.buffer = '';
985 this.stream = null;
986 throw new Error('streaming not supported in browser');
987 }
988 return StreamedEmitter;
989 }());
990
991 function createResolvedThenable(value) {
992 var ret = {
993 then: function (resolve) { return resolve(value); },
994 catch: function () { return ret; }
995 };
996 return ret;
997 }
998 function createRejectedThenable(err) {
999 var ret = {
1000 then: function (resolve, reject) {
1001 if (reject)
1002 return reject(err);
1003 return ret;
1004 },
1005 catch: function (reject) { return reject(err); }
1006 };
1007 return ret;
1008 }
1009 function isThenable(val) {
1010 return val && isFunction(val.then);
1011 }
1012 function isAsyncIterator(val) {
1013 return val && isFunction(val.next) && isFunction(val.throw) && isFunction(val.return);
1014 }
1015 // convert an async iterator to a thenable (Promise compatible)
1016 function toThenable(val) {
1017 if (isThenable(val))
1018 return val;
1019 if (isAsyncIterator(val))
1020 return reduce();
1021 return createResolvedThenable(val);
1022 function reduce(prev) {
1023 var state;
1024 try {
1025 state = val.next(prev);
1026 }
1027 catch (err) {
1028 return createRejectedThenable(err);
1029 }
1030 if (state.done)
1031 return createResolvedThenable(state.value);
1032 return toThenable(state.value).then(reduce, function (err) {
1033 var state;
1034 try {
1035 state = val.throw(err);
1036 }
1037 catch (e) {
1038 return createRejectedThenable(e);
1039 }
1040 if (state.done)
1041 return createResolvedThenable(state.value);
1042 return reduce(state.value);
1043 });
1044 }
1045 }
1046 function toPromise(val) {
1047 return Promise.resolve(toThenable(val));
1048 }
1049 // get the value of async iterator in synchronous manner
1050 function toValue(val) {
1051 var ret;
1052 toThenable(val)
1053 .then(function (x) {
1054 ret = x;
1055 return createResolvedThenable(ret);
1056 })
1057 .catch(function (err) {
1058 throw err;
1059 });
1060 return ret;
1061 }
1062
1063 var KeepingTypeEmitter = /** @class */ (function () {
1064 function KeepingTypeEmitter() {
1065 this.buffer = '';
1066 }
1067 KeepingTypeEmitter.prototype.write = function (html) {
1068 html = toValue$1(html);
1069 // This will only preserve the type if the value is isolated.
1070 // I.E:
1071 // {{ my-port }} -> 42
1072 // {{ my-host }}:{{ my-port }} -> 'host:42'
1073 if (typeof html !== 'string' && this.buffer === '') {
1074 this.buffer = html;
1075 }
1076 else {
1077 this.buffer = stringify(this.buffer) + stringify(html);
1078 }
1079 };
1080 return KeepingTypeEmitter;
1081 }());
1082
1083 var Render = /** @class */ (function () {
1084 function Render() {
1085 }
1086 Render.prototype.renderTemplatesToNodeStream = function (templates, ctx) {
1087 var _this = this;
1088 var emitter = new StreamedEmitter();
1089 Promise.resolve().then(function () { return toThenable(_this.renderTemplates(templates, ctx, emitter)); })
1090 .then(function () { return emitter.end(); }, function (err) { return emitter.error(err); });
1091 return emitter.stream;
1092 };
1093 Render.prototype.renderTemplates = function (templates, ctx, emitter) {
1094 var templates_1, templates_1_1, tpl, html, e_1, err, e_2_1;
1095 var e_2, _a;
1096 return __generator(this, function (_b) {
1097 switch (_b.label) {
1098 case 0:
1099 if (!emitter) {
1100 emitter = ctx.opts.keepOutputType ? new KeepingTypeEmitter() : new SimpleEmitter();
1101 }
1102 _b.label = 1;
1103 case 1:
1104 _b.trys.push([1, 8, 9, 10]);
1105 templates_1 = __values(templates), templates_1_1 = templates_1.next();
1106 _b.label = 2;
1107 case 2:
1108 if (!!templates_1_1.done) return [3 /*break*/, 7];
1109 tpl = templates_1_1.value;
1110 _b.label = 3;
1111 case 3:
1112 _b.trys.push([3, 5, , 6]);
1113 return [4 /*yield*/, tpl.render(ctx, emitter)
1114 // if not, it'll return an `html`, write to the emitter for it
1115 ];
1116 case 4:
1117 html = _b.sent();
1118 // if not, it'll return an `html`, write to the emitter for it
1119 html && emitter.write(html);
1120 if (emitter['break'] || emitter['continue'])
1121 return [3 /*break*/, 7];
1122 return [3 /*break*/, 6];
1123 case 5:
1124 e_1 = _b.sent();
1125 err = RenderError.is(e_1) ? e_1 : new RenderError(e_1, tpl);
1126 throw err;
1127 case 6:
1128 templates_1_1 = templates_1.next();
1129 return [3 /*break*/, 2];
1130 case 7: return [3 /*break*/, 10];
1131 case 8:
1132 e_2_1 = _b.sent();
1133 e_2 = { error: e_2_1 };
1134 return [3 /*break*/, 10];
1135 case 9:
1136 try {
1137 if (templates_1_1 && !templates_1_1.done && (_a = templates_1.return)) _a.call(templates_1);
1138 }
1139 finally { if (e_2) throw e_2.error; }
1140 return [7 /*endfinally*/];
1141 case 10: return [2 /*return*/, emitter.buffer];
1142 }
1143 });
1144 };
1145 return Render;
1146 }());
1147
1148 exports.TokenKind = void 0;
1149 (function (TokenKind) {
1150 TokenKind[TokenKind["Number"] = 1] = "Number";
1151 TokenKind[TokenKind["Literal"] = 2] = "Literal";
1152 TokenKind[TokenKind["Tag"] = 4] = "Tag";
1153 TokenKind[TokenKind["Output"] = 8] = "Output";
1154 TokenKind[TokenKind["HTML"] = 16] = "HTML";
1155 TokenKind[TokenKind["Filter"] = 32] = "Filter";
1156 TokenKind[TokenKind["Hash"] = 64] = "Hash";
1157 TokenKind[TokenKind["PropertyAccess"] = 128] = "PropertyAccess";
1158 TokenKind[TokenKind["Word"] = 256] = "Word";
1159 TokenKind[TokenKind["Range"] = 512] = "Range";
1160 TokenKind[TokenKind["Quoted"] = 1024] = "Quoted";
1161 TokenKind[TokenKind["Operator"] = 2048] = "Operator";
1162 TokenKind[TokenKind["Delimited"] = 12] = "Delimited";
1163 })(exports.TokenKind || (exports.TokenKind = {}));
1164
1165 function isDelimitedToken(val) {
1166 return !!(getKind(val) & exports.TokenKind.Delimited);
1167 }
1168 function isOperatorToken(val) {
1169 return getKind(val) === exports.TokenKind.Operator;
1170 }
1171 function isHTMLToken(val) {
1172 return getKind(val) === exports.TokenKind.HTML;
1173 }
1174 function isOutputToken(val) {
1175 return getKind(val) === exports.TokenKind.Output;
1176 }
1177 function isTagToken(val) {
1178 return getKind(val) === exports.TokenKind.Tag;
1179 }
1180 function isQuotedToken(val) {
1181 return getKind(val) === exports.TokenKind.Quoted;
1182 }
1183 function isLiteralToken(val) {
1184 return getKind(val) === exports.TokenKind.Literal;
1185 }
1186 function isNumberToken(val) {
1187 return getKind(val) === exports.TokenKind.Number;
1188 }
1189 function isPropertyAccessToken(val) {
1190 return getKind(val) === exports.TokenKind.PropertyAccess;
1191 }
1192 function isWordToken(val) {
1193 return getKind(val) === exports.TokenKind.Word;
1194 }
1195 function isRangeToken(val) {
1196 return getKind(val) === exports.TokenKind.Range;
1197 }
1198 function getKind(val) {
1199 return val ? val.kind : -1;
1200 }
1201
1202 var typeGuards = /*#__PURE__*/Object.freeze({
1203 __proto__: null,
1204 isDelimitedToken: isDelimitedToken,
1205 isOperatorToken: isOperatorToken,
1206 isHTMLToken: isHTMLToken,
1207 isOutputToken: isOutputToken,
1208 isTagToken: isTagToken,
1209 isQuotedToken: isQuotedToken,
1210 isLiteralToken: isLiteralToken,
1211 isNumberToken: isNumberToken,
1212 isPropertyAccessToken: isPropertyAccessToken,
1213 isWordToken: isWordToken,
1214 isRangeToken: isRangeToken
1215 });
1216
1217 var ParseStream = /** @class */ (function () {
1218 function ParseStream(tokens, parseToken) {
1219 this.handlers = {};
1220 this.stopRequested = false;
1221 this.tokens = tokens;
1222 this.parseToken = parseToken;
1223 }
1224 ParseStream.prototype.on = function (name, cb) {
1225 this.handlers[name] = cb;
1226 return this;
1227 };
1228 ParseStream.prototype.trigger = function (event, arg) {
1229 var h = this.handlers[event];
1230 return h ? (h.call(this, arg), true) : false;
1231 };
1232 ParseStream.prototype.start = function () {
1233 this.trigger('start');
1234 var token;
1235 while (!this.stopRequested && (token = this.tokens.shift())) {
1236 if (this.trigger('token', token))
1237 continue;
1238 if (isTagToken(token) && this.trigger("tag:".concat(token.name), token)) {
1239 continue;
1240 }
1241 var template = this.parseToken(token, this.tokens);
1242 this.trigger('template', template);
1243 }
1244 if (!this.stopRequested)
1245 this.trigger('end');
1246 return this;
1247 };
1248 ParseStream.prototype.stop = function () {
1249 this.stopRequested = true;
1250 return this;
1251 };
1252 return ParseStream;
1253 }());
1254
1255 var TemplateImpl = /** @class */ (function () {
1256 function TemplateImpl(token) {
1257 this.token = token;
1258 }
1259 return TemplateImpl;
1260 }());
1261
1262 var NullDrop = /** @class */ (function (_super) {
1263 __extends(NullDrop, _super);
1264 function NullDrop() {
1265 return _super !== null && _super.apply(this, arguments) || this;
1266 }
1267 NullDrop.prototype.equals = function (value) {
1268 return isNil(toValue$1(value));
1269 };
1270 NullDrop.prototype.gt = function () {
1271 return false;
1272 };
1273 NullDrop.prototype.geq = function () {
1274 return false;
1275 };
1276 NullDrop.prototype.lt = function () {
1277 return false;
1278 };
1279 NullDrop.prototype.leq = function () {
1280 return false;
1281 };
1282 NullDrop.prototype.valueOf = function () {
1283 return null;
1284 };
1285 return NullDrop;
1286 }(Drop));
1287
1288 var EmptyDrop = /** @class */ (function (_super) {
1289 __extends(EmptyDrop, _super);
1290 function EmptyDrop() {
1291 return _super !== null && _super.apply(this, arguments) || this;
1292 }
1293 EmptyDrop.prototype.equals = function (value) {
1294 if (value instanceof EmptyDrop)
1295 return false;
1296 value = toValue$1(value);
1297 if (isString(value) || isArray(value))
1298 return value.length === 0;
1299 if (isObject(value))
1300 return Object.keys(value).length === 0;
1301 return false;
1302 };
1303 EmptyDrop.prototype.gt = function () {
1304 return false;
1305 };
1306 EmptyDrop.prototype.geq = function () {
1307 return false;
1308 };
1309 EmptyDrop.prototype.lt = function () {
1310 return false;
1311 };
1312 EmptyDrop.prototype.leq = function () {
1313 return false;
1314 };
1315 EmptyDrop.prototype.valueOf = function () {
1316 return '';
1317 };
1318 return EmptyDrop;
1319 }(Drop));
1320
1321 var BlankDrop = /** @class */ (function (_super) {
1322 __extends(BlankDrop, _super);
1323 function BlankDrop() {
1324 return _super !== null && _super.apply(this, arguments) || this;
1325 }
1326 BlankDrop.prototype.equals = function (value) {
1327 if (value === false)
1328 return true;
1329 if (isNil(toValue$1(value)))
1330 return true;
1331 if (isString(value))
1332 return /^\s*$/.test(value);
1333 return _super.prototype.equals.call(this, value);
1334 };
1335 return BlankDrop;
1336 }(EmptyDrop));
1337
1338 var nil = new NullDrop();
1339 var literalValues = {
1340 'true': true,
1341 'false': false,
1342 'nil': nil,
1343 'null': nil,
1344 'empty': new EmptyDrop(),
1345 'blank': new BlankDrop()
1346 };
1347
1348 var rHex = /[\da-fA-F]/;
1349 var rOct = /[0-7]/;
1350 var escapeChar = {
1351 b: '\b',
1352 f: '\f',
1353 n: '\n',
1354 r: '\r',
1355 t: '\t',
1356 v: '\x0B'
1357 };
1358 function hexVal(c) {
1359 var code = c.charCodeAt(0);
1360 if (code >= 97)
1361 return code - 87;
1362 if (code >= 65)
1363 return code - 55;
1364 return code - 48;
1365 }
1366 function parseStringLiteral(str) {
1367 var ret = '';
1368 for (var i = 1; i < str.length - 1; i++) {
1369 if (str[i] !== '\\') {
1370 ret += str[i];
1371 continue;
1372 }
1373 if (escapeChar[str[i + 1]] !== undefined) {
1374 ret += escapeChar[str[++i]];
1375 }
1376 else if (str[i + 1] === 'u') {
1377 var val = 0;
1378 var j = i + 2;
1379 while (j <= i + 5 && rHex.test(str[j])) {
1380 val = val * 16 + hexVal(str[j++]);
1381 }
1382 i = j - 1;
1383 ret += String.fromCharCode(val);
1384 }
1385 else if (!rOct.test(str[i + 1])) {
1386 ret += str[++i];
1387 }
1388 else {
1389 var j = i + 1;
1390 var val = 0;
1391 while (j <= i + 3 && rOct.test(str[j])) {
1392 val = val * 8 + hexVal(str[j++]);
1393 }
1394 i = j - 1;
1395 ret += String.fromCharCode(val);
1396 }
1397 }
1398 return ret;
1399 }
1400
1401 var Expression = /** @class */ (function () {
1402 function Expression(tokens) {
1403 this.postfix = __spreadArray([], __read(toPostfix(tokens)), false);
1404 }
1405 Expression.prototype.evaluate = function (ctx, lenient) {
1406 var operands, _a, _b, token, r, l, result, _c, _d, e_1_1;
1407 var e_1, _e;
1408 return __generator(this, function (_f) {
1409 switch (_f.label) {
1410 case 0:
1411 assert(ctx, 'unable to evaluate: context not defined');
1412 operands = [];
1413 _f.label = 1;
1414 case 1:
1415 _f.trys.push([1, 9, 10, 11]);
1416 _a = __values(this.postfix), _b = _a.next();
1417 _f.label = 2;
1418 case 2:
1419 if (!!_b.done) return [3 /*break*/, 8];
1420 token = _b.value;
1421 if (!isOperatorToken(token)) return [3 /*break*/, 5];
1422 return [4 /*yield*/, operands.pop()];
1423 case 3:
1424 r = _f.sent();
1425 return [4 /*yield*/, operands.pop()];
1426 case 4:
1427 l = _f.sent();
1428 result = evalOperatorToken(ctx.opts.operators, token, l, r, ctx);
1429 operands.push(result);
1430 return [3 /*break*/, 7];
1431 case 5:
1432 _d = (_c = operands).push;
1433 return [4 /*yield*/, evalToken(token, ctx, lenient && this.postfix.length === 1)];
1434 case 6:
1435 _d.apply(_c, [_f.sent()]);
1436 _f.label = 7;
1437 case 7:
1438 _b = _a.next();
1439 return [3 /*break*/, 2];
1440 case 8: return [3 /*break*/, 11];
1441 case 9:
1442 e_1_1 = _f.sent();
1443 e_1 = { error: e_1_1 };
1444 return [3 /*break*/, 11];
1445 case 10:
1446 try {
1447 if (_b && !_b.done && (_e = _a.return)) _e.call(_a);
1448 }
1449 finally { if (e_1) throw e_1.error; }
1450 return [7 /*endfinally*/];
1451 case 11: return [2 /*return*/, operands[0]];
1452 }
1453 });
1454 };
1455 return Expression;
1456 }());
1457 function evalToken(token, ctx, lenient) {
1458 if (lenient === void 0) { lenient = false; }
1459 if (isPropertyAccessToken(token))
1460 return evalPropertyAccessToken(token, ctx, lenient);
1461 if (isRangeToken(token))
1462 return evalRangeToken(token, ctx);
1463 if (isLiteralToken(token))
1464 return evalLiteralToken(token);
1465 if (isNumberToken(token))
1466 return evalNumberToken(token);
1467 if (isWordToken(token))
1468 return token.getText();
1469 if (isQuotedToken(token))
1470 return evalQuotedToken(token);
1471 }
1472 function evalPropertyAccessToken(token, ctx, lenient) {
1473 var props = token.props.map(function (prop) { return evalToken(prop, ctx, false); });
1474 try {
1475 return ctx.get(__spreadArray([token.propertyName], __read(props), false));
1476 }
1477 catch (e) {
1478 if (lenient && e.name === 'InternalUndefinedVariableError')
1479 return null;
1480 throw (new UndefinedVariableError(e, token));
1481 }
1482 }
1483 function evalNumberToken(token) {
1484 var str = token.whole.content + '.' + (token.decimal ? token.decimal.content : '');
1485 return Number(str);
1486 }
1487 function evalQuotedToken(token) {
1488 return parseStringLiteral(token.getText());
1489 }
1490 function evalOperatorToken(operators, token, lhs, rhs, ctx) {
1491 var impl = operators[token.operator];
1492 return impl(lhs, rhs, ctx);
1493 }
1494 function evalLiteralToken(token) {
1495 return literalValues[token.literal];
1496 }
1497 function evalRangeToken(token, ctx) {
1498 var low = evalToken(token.lhs, ctx);
1499 var high = evalToken(token.rhs, ctx);
1500 return range(+low, +high + 1);
1501 }
1502 function toPostfix(tokens) {
1503 var ops, tokens_1, tokens_1_1, token, e_2_1;
1504 var e_2, _a;
1505 return __generator(this, function (_b) {
1506 switch (_b.label) {
1507 case 0:
1508 ops = [];
1509 _b.label = 1;
1510 case 1:
1511 _b.trys.push([1, 10, 11, 12]);
1512 tokens_1 = __values(tokens), tokens_1_1 = tokens_1.next();
1513 _b.label = 2;
1514 case 2:
1515 if (!!tokens_1_1.done) return [3 /*break*/, 9];
1516 token = tokens_1_1.value;
1517 if (!isOperatorToken(token)) return [3 /*break*/, 6];
1518 _b.label = 3;
1519 case 3:
1520 if (!(ops.length && ops[ops.length - 1].getPrecedence() > token.getPrecedence())) return [3 /*break*/, 5];
1521 return [4 /*yield*/, ops.pop()];
1522 case 4:
1523 _b.sent();
1524 return [3 /*break*/, 3];
1525 case 5:
1526 ops.push(token);
1527 return [3 /*break*/, 8];
1528 case 6: return [4 /*yield*/, token];
1529 case 7:
1530 _b.sent();
1531 _b.label = 8;
1532 case 8:
1533 tokens_1_1 = tokens_1.next();
1534 return [3 /*break*/, 2];
1535 case 9: return [3 /*break*/, 12];
1536 case 10:
1537 e_2_1 = _b.sent();
1538 e_2 = { error: e_2_1 };
1539 return [3 /*break*/, 12];
1540 case 11:
1541 try {
1542 if (tokens_1_1 && !tokens_1_1.done && (_a = tokens_1.return)) _a.call(tokens_1);
1543 }
1544 finally { if (e_2) throw e_2.error; }
1545 return [7 /*endfinally*/];
1546 case 12:
1547 if (!ops.length) return [3 /*break*/, 14];
1548 return [4 /*yield*/, ops.pop()];
1549 case 13:
1550 _b.sent();
1551 return [3 /*break*/, 12];
1552 case 14: return [2 /*return*/];
1553 }
1554 });
1555 }
1556
1557 var Token = /** @class */ (function () {
1558 function Token(kind, input, begin, end, file) {
1559 this.kind = kind;
1560 this.input = input;
1561 this.begin = begin;
1562 this.end = end;
1563 this.file = file;
1564 }
1565 Token.prototype.getText = function () {
1566 return this.input.slice(this.begin, this.end);
1567 };
1568 Token.prototype.getPosition = function () {
1569 var _a = __read([1, 1], 2), row = _a[0], col = _a[1];
1570 for (var i = 0; i < this.begin; i++) {
1571 if (this.input[i] === '\n') {
1572 row++;
1573 col = 1;
1574 }
1575 else
1576 col++;
1577 }
1578 return [row, col];
1579 };
1580 Token.prototype.size = function () {
1581 return this.end - this.begin;
1582 };
1583 return Token;
1584 }());
1585
1586 var DelimitedToken = /** @class */ (function (_super) {
1587 __extends(DelimitedToken, _super);
1588 function DelimitedToken(kind, content, input, begin, end, trimLeft, trimRight, file) {
1589 var _this = _super.call(this, kind, input, begin, end, file) || this;
1590 _this.trimLeft = false;
1591 _this.trimRight = false;
1592 _this.content = _this.getText();
1593 var tl = content[0] === '-';
1594 var tr = last$1(content) === '-';
1595 _this.content = content
1596 .slice(tl ? 1 : 0, tr ? -1 : content.length)
1597 .trim();
1598 _this.trimLeft = tl || trimLeft;
1599 _this.trimRight = tr || trimRight;
1600 return _this;
1601 }
1602 return DelimitedToken;
1603 }(Token));
1604
1605 function whiteSpaceCtrl(tokens, options) {
1606 var inRaw = false;
1607 for (var i = 0; i < tokens.length; i++) {
1608 var token = tokens[i];
1609 if (!isDelimitedToken(token))
1610 continue;
1611 if (!inRaw && token.trimLeft) {
1612 trimLeft(tokens[i - 1], options.greedy);
1613 }
1614 if (isTagToken(token)) {
1615 if (token.name === 'raw')
1616 inRaw = true;
1617 else if (token.name === 'endraw')
1618 inRaw = false;
1619 }
1620 if (!inRaw && token.trimRight) {
1621 trimRight(tokens[i + 1], options.greedy);
1622 }
1623 }
1624 }
1625 function trimLeft(token, greedy) {
1626 if (!token || !isHTMLToken(token))
1627 return;
1628 var mask = greedy ? BLANK : INLINE_BLANK;
1629 while (TYPES[token.input.charCodeAt(token.end - 1 - token.trimRight)] & mask)
1630 token.trimRight++;
1631 }
1632 function trimRight(token, greedy) {
1633 if (!token || !isHTMLToken(token))
1634 return;
1635 var mask = greedy ? BLANK : INLINE_BLANK;
1636 while (TYPES[token.input.charCodeAt(token.begin + token.trimLeft)] & mask)
1637 token.trimLeft++;
1638 if (token.input.charAt(token.begin + token.trimLeft) === '\n')
1639 token.trimLeft++;
1640 }
1641
1642 var NumberToken = /** @class */ (function (_super) {
1643 __extends(NumberToken, _super);
1644 function NumberToken(whole, decimal) {
1645 var _this = _super.call(this, exports.TokenKind.Number, whole.input, whole.begin, decimal ? decimal.end : whole.end, whole.file) || this;
1646 _this.whole = whole;
1647 _this.decimal = decimal;
1648 return _this;
1649 }
1650 return NumberToken;
1651 }(Token));
1652
1653 var IdentifierToken = /** @class */ (function (_super) {
1654 __extends(IdentifierToken, _super);
1655 function IdentifierToken(input, begin, end, file) {
1656 var _this = _super.call(this, exports.TokenKind.Word, input, begin, end, file) || this;
1657 _this.input = input;
1658 _this.begin = begin;
1659 _this.end = end;
1660 _this.file = file;
1661 _this.content = _this.getText();
1662 return _this;
1663 }
1664 IdentifierToken.prototype.isNumber = function (allowSign) {
1665 if (allowSign === void 0) { allowSign = false; }
1666 var begin = allowSign && TYPES[this.input.charCodeAt(this.begin)] & SIGN
1667 ? this.begin + 1
1668 : this.begin;
1669 for (var i = begin; i < this.end; i++) {
1670 if (!(TYPES[this.input.charCodeAt(i)] & NUMBER))
1671 return false;
1672 }
1673 return true;
1674 };
1675 return IdentifierToken;
1676 }(Token));
1677
1678 var LiteralToken = /** @class */ (function (_super) {
1679 __extends(LiteralToken, _super);
1680 function LiteralToken(input, begin, end, file) {
1681 var _this = _super.call(this, exports.TokenKind.Literal, input, begin, end, file) || this;
1682 _this.input = input;
1683 _this.begin = begin;
1684 _this.end = end;
1685 _this.file = file;
1686 _this.literal = _this.getText();
1687 return _this;
1688 }
1689 return LiteralToken;
1690 }(Token));
1691
1692 var precedence = {
1693 '==': 1,
1694 '!=': 1,
1695 '>': 1,
1696 '<': 1,
1697 '>=': 1,
1698 '<=': 1,
1699 'contains': 1,
1700 'and': 0,
1701 'or': 0
1702 };
1703 var OperatorToken = /** @class */ (function (_super) {
1704 __extends(OperatorToken, _super);
1705 function OperatorToken(input, begin, end, file) {
1706 var _this = _super.call(this, exports.TokenKind.Operator, input, begin, end, file) || this;
1707 _this.input = input;
1708 _this.begin = begin;
1709 _this.end = end;
1710 _this.file = file;
1711 _this.operator = _this.getText();
1712 return _this;
1713 }
1714 OperatorToken.prototype.getPrecedence = function () {
1715 var key = this.getText();
1716 return key in precedence ? precedence[key] : 1;
1717 };
1718 return OperatorToken;
1719 }(Token));
1720
1721 var PropertyAccessToken = /** @class */ (function (_super) {
1722 __extends(PropertyAccessToken, _super);
1723 function PropertyAccessToken(variable, props, end) {
1724 var _this = _super.call(this, exports.TokenKind.PropertyAccess, variable.input, variable.begin, end, variable.file) || this;
1725 _this.variable = variable;
1726 _this.props = props;
1727 _this.propertyName = _this.variable instanceof IdentifierToken
1728 ? _this.variable.getText()
1729 : parseStringLiteral(_this.variable.getText());
1730 return _this;
1731 }
1732 return PropertyAccessToken;
1733 }(Token));
1734
1735 var FilterToken = /** @class */ (function (_super) {
1736 __extends(FilterToken, _super);
1737 function FilterToken(name, args, input, begin, end, file) {
1738 var _this = _super.call(this, exports.TokenKind.Filter, input, begin, end, file) || this;
1739 _this.name = name;
1740 _this.args = args;
1741 return _this;
1742 }
1743 return FilterToken;
1744 }(Token));
1745
1746 var HashToken = /** @class */ (function (_super) {
1747 __extends(HashToken, _super);
1748 function HashToken(input, begin, end, name, value, file) {
1749 var _this = _super.call(this, exports.TokenKind.Hash, input, begin, end, file) || this;
1750 _this.input = input;
1751 _this.begin = begin;
1752 _this.end = end;
1753 _this.name = name;
1754 _this.value = value;
1755 _this.file = file;
1756 return _this;
1757 }
1758 return HashToken;
1759 }(Token));
1760
1761 var QuotedToken = /** @class */ (function (_super) {
1762 __extends(QuotedToken, _super);
1763 function QuotedToken(input, begin, end, file) {
1764 var _this = _super.call(this, exports.TokenKind.Quoted, input, begin, end, file) || this;
1765 _this.input = input;
1766 _this.begin = begin;
1767 _this.end = end;
1768 _this.file = file;
1769 return _this;
1770 }
1771 return QuotedToken;
1772 }(Token));
1773
1774 var HTMLToken = /** @class */ (function (_super) {
1775 __extends(HTMLToken, _super);
1776 function HTMLToken(input, begin, end, file) {
1777 var _this = _super.call(this, exports.TokenKind.HTML, input, begin, end, file) || this;
1778 _this.input = input;
1779 _this.begin = begin;
1780 _this.end = end;
1781 _this.file = file;
1782 _this.trimLeft = 0;
1783 _this.trimRight = 0;
1784 return _this;
1785 }
1786 HTMLToken.prototype.getContent = function () {
1787 return this.input.slice(this.begin + this.trimLeft, this.end - this.trimRight);
1788 };
1789 return HTMLToken;
1790 }(Token));
1791
1792 var RangeToken = /** @class */ (function (_super) {
1793 __extends(RangeToken, _super);
1794 function RangeToken(input, begin, end, lhs, rhs, file) {
1795 var _this = _super.call(this, exports.TokenKind.Range, input, begin, end, file) || this;
1796 _this.input = input;
1797 _this.begin = begin;
1798 _this.end = end;
1799 _this.lhs = lhs;
1800 _this.rhs = rhs;
1801 _this.file = file;
1802 return _this;
1803 }
1804 return RangeToken;
1805 }(Token));
1806
1807 var OutputToken = /** @class */ (function (_super) {
1808 __extends(OutputToken, _super);
1809 function OutputToken(input, begin, end, options, file) {
1810 var _this = this;
1811 var trimOutputLeft = options.trimOutputLeft, trimOutputRight = options.trimOutputRight, outputDelimiterLeft = options.outputDelimiterLeft, outputDelimiterRight = options.outputDelimiterRight;
1812 var value = input.slice(begin + outputDelimiterLeft.length, end - outputDelimiterRight.length);
1813 _this = _super.call(this, exports.TokenKind.Output, value, input, begin, end, trimOutputLeft, trimOutputRight, file) || this;
1814 return _this;
1815 }
1816 return OutputToken;
1817 }(DelimitedToken));
1818
1819 function matchOperator(str, begin, trie, end) {
1820 if (end === void 0) { end = str.length; }
1821 var node = trie;
1822 var i = begin;
1823 var info;
1824 while (node[str[i]] && i < end) {
1825 node = node[str[i++]];
1826 if (node['end'])
1827 info = node;
1828 }
1829 if (!info)
1830 return -1;
1831 if (info['needBoundary'] && (TYPES[str.charCodeAt(i)] & IDENTIFIER))
1832 return -1;
1833 return i;
1834 }
1835
1836 var LiquidTagToken = /** @class */ (function (_super) {
1837 __extends(LiquidTagToken, _super);
1838 function LiquidTagToken(input, begin, end, options, file) {
1839 var _this = this;
1840 var value = input.slice(begin, end);
1841 _this = _super.call(this, exports.TokenKind.Tag, value, input, begin, end, false, false, file) || this;
1842 if (!/\S/.test(value)) {
1843 // A line that contains only whitespace.
1844 _this.name = '';
1845 _this.args = '';
1846 }
1847 else {
1848 var tokenizer = new Tokenizer(_this.content, options.operatorsTrie);
1849 _this.name = tokenizer.readIdentifier().getText();
1850 if (!_this.name)
1851 throw new TokenizationError("illegal liquid tag syntax", _this);
1852 tokenizer.skipBlank();
1853 _this.args = tokenizer.remaining();
1854 }
1855 return _this;
1856 }
1857 return LiquidTagToken;
1858 }(DelimitedToken));
1859
1860 var Tokenizer = /** @class */ (function () {
1861 function Tokenizer(input, trie, file) {
1862 if (file === void 0) { file = ''; }
1863 this.input = input;
1864 this.trie = trie;
1865 this.file = file;
1866 this.p = 0;
1867 this.rawBeginAt = -1;
1868 this.N = input.length;
1869 }
1870 Tokenizer.prototype.readExpression = function () {
1871 return new Expression(this.readExpressionTokens());
1872 };
1873 Tokenizer.prototype.readExpressionTokens = function () {
1874 var operand, operator, operand_1;
1875 return __generator(this, function (_a) {
1876 switch (_a.label) {
1877 case 0:
1878 operand = this.readValue();
1879 if (!operand)
1880 return [2 /*return*/];
1881 return [4 /*yield*/, operand];
1882 case 1:
1883 _a.sent();
1884 _a.label = 2;
1885 case 2:
1886 if (!(this.p < this.N)) return [3 /*break*/, 5];
1887 operator = this.readOperator();
1888 if (!operator)
1889 return [2 /*return*/];
1890 operand_1 = this.readValue();
1891 if (!operand_1)
1892 return [2 /*return*/];
1893 return [4 /*yield*/, operator];
1894 case 3:
1895 _a.sent();
1896 return [4 /*yield*/, operand_1];
1897 case 4:
1898 _a.sent();
1899 return [3 /*break*/, 2];
1900 case 5: return [2 /*return*/];
1901 }
1902 });
1903 };
1904 Tokenizer.prototype.readOperator = function () {
1905 this.skipBlank();
1906 var end = matchOperator(this.input, this.p, this.trie);
1907 if (end === -1)
1908 return;
1909 return new OperatorToken(this.input, this.p, (this.p = end), this.file);
1910 };
1911 Tokenizer.prototype.readFilters = function () {
1912 var filters = [];
1913 while (true) {
1914 var filter = this.readFilter();
1915 if (!filter)
1916 return filters;
1917 filters.push(filter);
1918 }
1919 };
1920 Tokenizer.prototype.readFilter = function () {
1921 var _this = this;
1922 this.skipBlank();
1923 if (this.end())
1924 return null;
1925 assert(this.peek() === '|', function () { return "unexpected token at ".concat(_this.snapshot()); });
1926 this.p++;
1927 var begin = this.p;
1928 var name = this.readIdentifier();
1929 if (!name.size())
1930 return null;
1931 var args = [];
1932 this.skipBlank();
1933 if (this.peek() === ':') {
1934 do {
1935 ++this.p;
1936 var arg = this.readFilterArg();
1937 arg && args.push(arg);
1938 while (this.p < this.N && this.peek() !== ',' && this.peek() !== '|')
1939 ++this.p;
1940 } while (this.peek() === ',');
1941 }
1942 return new FilterToken(name.getText(), args, this.input, begin, this.p, this.file);
1943 };
1944 Tokenizer.prototype.readFilterArg = function () {
1945 var key = this.readValue();
1946 if (!key)
1947 return;
1948 this.skipBlank();
1949 if (this.peek() !== ':')
1950 return key;
1951 ++this.p;
1952 var value = this.readValue();
1953 return [key.getText(), value];
1954 };
1955 Tokenizer.prototype.readTopLevelTokens = function (options) {
1956 if (options === void 0) { options = defaultOptions; }
1957 var tokens = [];
1958 while (this.p < this.N) {
1959 var token = this.readTopLevelToken(options);
1960 tokens.push(token);
1961 }
1962 whiteSpaceCtrl(tokens, options);
1963 return tokens;
1964 };
1965 Tokenizer.prototype.readTopLevelToken = function (options) {
1966 var tagDelimiterLeft = options.tagDelimiterLeft, outputDelimiterLeft = options.outputDelimiterLeft;
1967 if (this.rawBeginAt > -1)
1968 return this.readEndrawOrRawContent(options);
1969 if (this.match(tagDelimiterLeft))
1970 return this.readTagToken(options);
1971 if (this.match(outputDelimiterLeft))
1972 return this.readOutputToken(options);
1973 return this.readHTMLToken([tagDelimiterLeft, outputDelimiterLeft]);
1974 };
1975 Tokenizer.prototype.readHTMLToken = function (stopStrings) {
1976 var _this = this;
1977 var begin = this.p;
1978 while (this.p < this.N) {
1979 if (stopStrings.some(function (str) { return _this.match(str); }))
1980 break;
1981 ++this.p;
1982 }
1983 return new HTMLToken(this.input, begin, this.p, this.file);
1984 };
1985 Tokenizer.prototype.readTagToken = function (options) {
1986 if (options === void 0) { options = defaultOptions; }
1987 var _a = this, file = _a.file, input = _a.input;
1988 var begin = this.p;
1989 if (this.readToDelimiter(options.tagDelimiterRight) === -1) {
1990 throw this.mkError("tag ".concat(this.snapshot(begin), " not closed"), begin);
1991 }
1992 var token = new TagToken(input, begin, this.p, options, file);
1993 if (token.name === 'raw')
1994 this.rawBeginAt = begin;
1995 return token;
1996 };
1997 Tokenizer.prototype.readToDelimiter = function (delimiter) {
1998 while (this.p < this.N) {
1999 if ((this.peekType() & QUOTE)) {
2000 this.readQuoted();
2001 continue;
2002 }
2003 ++this.p;
2004 if (this.rmatch(delimiter))
2005 return this.p;
2006 }
2007 return -1;
2008 };
2009 Tokenizer.prototype.readOutputToken = function (options) {
2010 if (options === void 0) { options = defaultOptions; }
2011 var _a = this, file = _a.file, input = _a.input;
2012 var outputDelimiterRight = options.outputDelimiterRight;
2013 var begin = this.p;
2014 if (this.readToDelimiter(outputDelimiterRight) === -1) {
2015 throw this.mkError("output ".concat(this.snapshot(begin), " not closed"), begin);
2016 }
2017 return new OutputToken(input, begin, this.p, options, file);
2018 };
2019 Tokenizer.prototype.readEndrawOrRawContent = function (options) {
2020 var tagDelimiterLeft = options.tagDelimiterLeft, tagDelimiterRight = options.tagDelimiterRight;
2021 var begin = this.p;
2022 var leftPos = this.readTo(tagDelimiterLeft) - tagDelimiterLeft.length;
2023 while (this.p < this.N) {
2024 if (this.readIdentifier().getText() !== 'endraw') {
2025 leftPos = this.readTo(tagDelimiterLeft) - tagDelimiterLeft.length;
2026 continue;
2027 }
2028 while (this.p <= this.N) {
2029 if (this.rmatch(tagDelimiterRight)) {
2030 var end = this.p;
2031 if (begin === leftPos) {
2032 this.rawBeginAt = -1;
2033 return new TagToken(this.input, begin, end, options, this.file);
2034 }
2035 else {
2036 this.p = leftPos;
2037 return new HTMLToken(this.input, begin, leftPos, this.file);
2038 }
2039 }
2040 if (this.rmatch(tagDelimiterLeft))
2041 break;
2042 this.p++;
2043 }
2044 }
2045 throw this.mkError("raw ".concat(this.snapshot(this.rawBeginAt), " not closed"), begin);
2046 };
2047 Tokenizer.prototype.readLiquidTagTokens = function (options) {
2048 if (options === void 0) { options = defaultOptions; }
2049 var tokens = [];
2050 while (this.p < this.N) {
2051 var token = this.readLiquidTagToken(options);
2052 if (token.name)
2053 tokens.push(token);
2054 }
2055 return tokens;
2056 };
2057 Tokenizer.prototype.readLiquidTagToken = function (options) {
2058 var _a = this, file = _a.file, input = _a.input;
2059 var begin = this.p;
2060 var end = this.N;
2061 if (this.readToDelimiter('\n') !== -1)
2062 end = this.p;
2063 var token = new LiquidTagToken(input, begin, end, options, file);
2064 return token;
2065 };
2066 Tokenizer.prototype.mkError = function (msg, begin) {
2067 return new TokenizationError(msg, new IdentifierToken(this.input, begin, this.N, this.file));
2068 };
2069 Tokenizer.prototype.snapshot = function (begin) {
2070 if (begin === void 0) { begin = this.p; }
2071 return JSON.stringify(ellipsis(this.input.slice(begin), 16));
2072 };
2073 /**
2074 * @deprecated
2075 */
2076 Tokenizer.prototype.readWord = function () {
2077 console.warn('Tokenizer#readWord() will be removed, use #readIdentifier instead');
2078 return this.readIdentifier();
2079 };
2080 Tokenizer.prototype.readIdentifier = function () {
2081 this.skipBlank();
2082 var begin = this.p;
2083 while (this.peekType() & IDENTIFIER)
2084 ++this.p;
2085 return new IdentifierToken(this.input, begin, this.p, this.file);
2086 };
2087 Tokenizer.prototype.readHashes = function (jekyllStyle) {
2088 var hashes = [];
2089 while (true) {
2090 var hash = this.readHash(jekyllStyle);
2091 if (!hash)
2092 return hashes;
2093 hashes.push(hash);
2094 }
2095 };
2096 Tokenizer.prototype.readHash = function (jekyllStyle) {
2097 this.skipBlank();
2098 if (this.peek() === ',')
2099 ++this.p;
2100 var begin = this.p;
2101 var name = this.readIdentifier();
2102 if (!name.size())
2103 return;
2104 var value;
2105 this.skipBlank();
2106 var sep = jekyllStyle ? '=' : ':';
2107 if (this.peek() === sep) {
2108 ++this.p;
2109 value = this.readValue();
2110 }
2111 return new HashToken(this.input, begin, this.p, name, value, this.file);
2112 };
2113 Tokenizer.prototype.remaining = function () {
2114 return this.input.slice(this.p);
2115 };
2116 Tokenizer.prototype.advance = function (i) {
2117 if (i === void 0) { i = 1; }
2118 this.p += i;
2119 };
2120 Tokenizer.prototype.end = function () {
2121 return this.p >= this.N;
2122 };
2123 Tokenizer.prototype.readTo = function (end) {
2124 while (this.p < this.N) {
2125 ++this.p;
2126 if (this.rmatch(end))
2127 return this.p;
2128 }
2129 return -1;
2130 };
2131 Tokenizer.prototype.readValue = function () {
2132 var value = this.readQuoted() || this.readRange();
2133 if (value)
2134 return value;
2135 if (this.peek() === '[') {
2136 this.p++;
2137 var prop = this.readQuoted();
2138 if (!prop)
2139 return;
2140 if (this.peek() !== ']')
2141 return;
2142 this.p++;
2143 return new PropertyAccessToken(prop, [], this.p);
2144 }
2145 var variable = this.readIdentifier();
2146 if (!variable.size())
2147 return;
2148 var isNumber = variable.isNumber(true);
2149 var props = [];
2150 while (true) {
2151 if (this.peek() === '[') {
2152 isNumber = false;
2153 this.p++;
2154 var prop = this.readValue() || new IdentifierToken(this.input, this.p, this.p, this.file);
2155 this.readTo(']');
2156 props.push(prop);
2157 }
2158 else if (this.peek() === '.' && this.peek(1) !== '.') { // skip range syntax
2159 this.p++;
2160 var prop = this.readIdentifier();
2161 if (!prop.size())
2162 break;
2163 if (!prop.isNumber())
2164 isNumber = false;
2165 props.push(prop);
2166 }
2167 else
2168 break;
2169 }
2170 if (!props.length && literalValues.hasOwnProperty(variable.content)) {
2171 return new LiteralToken(this.input, variable.begin, variable.end, this.file);
2172 }
2173 if (isNumber)
2174 return new NumberToken(variable, props[0]);
2175 return new PropertyAccessToken(variable, props, this.p);
2176 };
2177 Tokenizer.prototype.readRange = function () {
2178 this.skipBlank();
2179 var begin = this.p;
2180 if (this.peek() !== '(')
2181 return;
2182 ++this.p;
2183 var lhs = this.readValueOrThrow();
2184 this.p += 2;
2185 var rhs = this.readValueOrThrow();
2186 ++this.p;
2187 return new RangeToken(this.input, begin, this.p, lhs, rhs, this.file);
2188 };
2189 Tokenizer.prototype.readValueOrThrow = function () {
2190 var _this = this;
2191 var value = this.readValue();
2192 assert(value, function () { return "unexpected token ".concat(_this.snapshot(), ", value expected"); });
2193 return value;
2194 };
2195 Tokenizer.prototype.readQuoted = function () {
2196 this.skipBlank();
2197 var begin = this.p;
2198 if (!(this.peekType() & QUOTE))
2199 return;
2200 ++this.p;
2201 var escaped = false;
2202 while (this.p < this.N) {
2203 ++this.p;
2204 if (this.input[this.p - 1] === this.input[begin] && !escaped)
2205 break;
2206 if (escaped)
2207 escaped = false;
2208 else if (this.input[this.p - 1] === '\\')
2209 escaped = true;
2210 }
2211 return new QuotedToken(this.input, begin, this.p, this.file);
2212 };
2213 Tokenizer.prototype.readFileNameTemplate = function (options) {
2214 var outputDelimiterLeft, htmlStopStrings, htmlStopStringSet;
2215 return __generator(this, function (_a) {
2216 switch (_a.label) {
2217 case 0:
2218 outputDelimiterLeft = options.outputDelimiterLeft;
2219 htmlStopStrings = [',', ' ', outputDelimiterLeft];
2220 htmlStopStringSet = new Set(htmlStopStrings);
2221 _a.label = 1;
2222 case 1:
2223 if (!(this.p < this.N && !htmlStopStringSet.has(this.peek()))) return [3 /*break*/, 3];
2224 return [4 /*yield*/, this.match(outputDelimiterLeft)
2225 ? this.readOutputToken(options)
2226 : this.readHTMLToken(htmlStopStrings)];
2227 case 2:
2228 _a.sent();
2229 return [3 /*break*/, 1];
2230 case 3: return [2 /*return*/];
2231 }
2232 });
2233 };
2234 Tokenizer.prototype.match = function (word) {
2235 for (var i = 0; i < word.length; i++) {
2236 if (word[i] !== this.input[this.p + i])
2237 return false;
2238 }
2239 return true;
2240 };
2241 Tokenizer.prototype.rmatch = function (pattern) {
2242 for (var i = 0; i < pattern.length; i++) {
2243 if (pattern[pattern.length - 1 - i] !== this.input[this.p - 1 - i])
2244 return false;
2245 }
2246 return true;
2247 };
2248 Tokenizer.prototype.peekType = function (n) {
2249 if (n === void 0) { n = 0; }
2250 return TYPES[this.input.charCodeAt(this.p + n)];
2251 };
2252 Tokenizer.prototype.peek = function (n) {
2253 if (n === void 0) { n = 0; }
2254 return this.input[this.p + n];
2255 };
2256 Tokenizer.prototype.skipBlank = function () {
2257 while (this.peekType() & BLANK)
2258 ++this.p;
2259 };
2260 return Tokenizer;
2261 }());
2262
2263 var TagToken = /** @class */ (function (_super) {
2264 __extends(TagToken, _super);
2265 function TagToken(input, begin, end, options, file) {
2266 var _this = this;
2267 var trimTagLeft = options.trimTagLeft, trimTagRight = options.trimTagRight, tagDelimiterLeft = options.tagDelimiterLeft, tagDelimiterRight = options.tagDelimiterRight;
2268 var value = input.slice(begin + tagDelimiterLeft.length, end - tagDelimiterRight.length);
2269 _this = _super.call(this, exports.TokenKind.Tag, value, input, begin, end, trimTagLeft, trimTagRight, file) || this;
2270 var tokenizer = new Tokenizer(_this.content, options.operatorsTrie);
2271 _this.name = tokenizer.readIdentifier().getText();
2272 if (!_this.name)
2273 throw new TokenizationError("illegal tag syntax", _this);
2274 tokenizer.skipBlank();
2275 _this.args = tokenizer.remaining();
2276 return _this;
2277 }
2278 return TagToken;
2279 }(DelimitedToken));
2280
2281 /**
2282 * Key-Value Pairs Representing Tag Arguments
2283 * Example:
2284 * For the markup `, foo:'bar', coo:2 reversed %}`,
2285 * hash['foo'] === 'bar'
2286 * hash['coo'] === 2
2287 * hash['reversed'] === undefined
2288 */
2289 var Hash = /** @class */ (function () {
2290 function Hash(markup, jekyllStyle) {
2291 var e_1, _a;
2292 this.hash = {};
2293 var tokenizer = new Tokenizer(markup, {});
2294 try {
2295 for (var _b = __values(tokenizer.readHashes(jekyllStyle)), _c = _b.next(); !_c.done; _c = _b.next()) {
2296 var hash = _c.value;
2297 this.hash[hash.name.content] = hash.value;
2298 }
2299 }
2300 catch (e_1_1) { e_1 = { error: e_1_1 }; }
2301 finally {
2302 try {
2303 if (_c && !_c.done && (_a = _b.return)) _a.call(_b);
2304 }
2305 finally { if (e_1) throw e_1.error; }
2306 }
2307 }
2308 Hash.prototype.render = function (ctx) {
2309 var hash, _a, _b, key, _c, _d, _e, e_2_1;
2310 var e_2, _f;
2311 return __generator(this, function (_g) {
2312 switch (_g.label) {
2313 case 0:
2314 hash = {};
2315 _g.label = 1;
2316 case 1:
2317 _g.trys.push([1, 8, 9, 10]);
2318 _a = __values(Object.keys(this.hash)), _b = _a.next();
2319 _g.label = 2;
2320 case 2:
2321 if (!!_b.done) return [3 /*break*/, 7];
2322 key = _b.value;
2323 _c = hash;
2324 _d = key;
2325 if (!(this.hash[key] === undefined)) return [3 /*break*/, 3];
2326 _e = true;
2327 return [3 /*break*/, 5];
2328 case 3: return [4 /*yield*/, evalToken(this.hash[key], ctx)];
2329 case 4:
2330 _e = _g.sent();
2331 _g.label = 5;
2332 case 5:
2333 _c[_d] = _e;
2334 _g.label = 6;
2335 case 6:
2336 _b = _a.next();
2337 return [3 /*break*/, 2];
2338 case 7: return [3 /*break*/, 10];
2339 case 8:
2340 e_2_1 = _g.sent();
2341 e_2 = { error: e_2_1 };
2342 return [3 /*break*/, 10];
2343 case 9:
2344 try {
2345 if (_b && !_b.done && (_f = _a.return)) _f.call(_a);
2346 }
2347 finally { if (e_2) throw e_2.error; }
2348 return [7 /*endfinally*/];
2349 case 10: return [2 /*return*/, hash];
2350 }
2351 });
2352 };
2353 return Hash;
2354 }());
2355
2356 function isKeyValuePair(arr) {
2357 return isArray(arr);
2358 }
2359
2360 var Filter = /** @class */ (function () {
2361 function Filter(name, impl, args, liquid) {
2362 this.name = name;
2363 this.impl = impl || identify;
2364 this.args = args;
2365 this.liquid = liquid;
2366 }
2367 Filter.prototype.render = function (value, context) {
2368 var e_1, _a;
2369 var argv = [];
2370 try {
2371 for (var _b = __values(this.args), _c = _b.next(); !_c.done; _c = _b.next()) {
2372 var arg = _c.value;
2373 if (isKeyValuePair(arg))
2374 argv.push([arg[0], evalToken(arg[1], context)]);
2375 else
2376 argv.push(evalToken(arg, context));
2377 }
2378 }
2379 catch (e_1_1) { e_1 = { error: e_1_1 }; }
2380 finally {
2381 try {
2382 if (_c && !_c.done && (_a = _b.return)) _a.call(_b);
2383 }
2384 finally { if (e_1) throw e_1.error; }
2385 }
2386 return this.impl.apply({ context: context, liquid: this.liquid }, __spreadArray([value], __read(argv), false));
2387 };
2388 return Filter;
2389 }());
2390
2391 var Value = /** @class */ (function () {
2392 /**
2393 * @param str the value to be valuated, eg.: "foobar" | truncate: 3
2394 */
2395 function Value(str, liquid) {
2396 this.filters = [];
2397 var tokenizer = new Tokenizer(str, liquid.options.operatorsTrie);
2398 this.initial = tokenizer.readExpression();
2399 this.filters = tokenizer.readFilters().map(function (_a) {
2400 var name = _a.name, args = _a.args;
2401 return new Filter(name, liquid.filters.get(name), args, liquid);
2402 });
2403 }
2404 Value.prototype.value = function (ctx, lenient) {
2405 var val, _a, _b, filter, e_1_1;
2406 var e_1, _c;
2407 return __generator(this, function (_d) {
2408 switch (_d.label) {
2409 case 0:
2410 lenient = lenient || (ctx.opts.lenientIf && this.filters.length > 0 && this.filters[0].name === 'default');
2411 return [4 /*yield*/, this.initial.evaluate(ctx, lenient)];
2412 case 1:
2413 val = _d.sent();
2414 _d.label = 2;
2415 case 2:
2416 _d.trys.push([2, 7, 8, 9]);
2417 _a = __values(this.filters), _b = _a.next();
2418 _d.label = 3;
2419 case 3:
2420 if (!!_b.done) return [3 /*break*/, 6];
2421 filter = _b.value;
2422 return [4 /*yield*/, filter.render(val, ctx)];
2423 case 4:
2424 val = _d.sent();
2425 _d.label = 5;
2426 case 5:
2427 _b = _a.next();
2428 return [3 /*break*/, 3];
2429 case 6: return [3 /*break*/, 9];
2430 case 7:
2431 e_1_1 = _d.sent();
2432 e_1 = { error: e_1_1 };
2433 return [3 /*break*/, 9];
2434 case 8:
2435 try {
2436 if (_b && !_b.done && (_c = _a.return)) _c.call(_a);
2437 }
2438 finally { if (e_1) throw e_1.error; }
2439 return [7 /*endfinally*/];
2440 case 9: return [2 /*return*/, val];
2441 }
2442 });
2443 };
2444 return Value;
2445 }());
2446
2447 var Tag = /** @class */ (function (_super) {
2448 __extends(Tag, _super);
2449 function Tag(token, tokens, liquid) {
2450 var _this = _super.call(this, token) || this;
2451 _this.name = token.name;
2452 var impl = liquid.tags.get(token.name);
2453 _this.impl = Object.create(impl);
2454 _this.impl.liquid = liquid;
2455 if (_this.impl.parse) {
2456 _this.impl.parse(token, tokens);
2457 }
2458 return _this;
2459 }
2460 Tag.prototype.render = function (ctx, emitter) {
2461 var hash, impl;
2462 return __generator(this, function (_a) {
2463 switch (_a.label) {
2464 case 0: return [4 /*yield*/, new Hash(this.token.args).render(ctx)];
2465 case 1:
2466 hash = (_a.sent());
2467 impl = this.impl;
2468 if (!isFunction(impl.render)) return [3 /*break*/, 3];
2469 return [4 /*yield*/, impl.render(ctx, emitter, hash)];
2470 case 2: return [2 /*return*/, _a.sent()];
2471 case 3: return [2 /*return*/];
2472 }
2473 });
2474 };
2475 return Tag;
2476 }(TemplateImpl));
2477
2478 var Output = /** @class */ (function (_super) {
2479 __extends(Output, _super);
2480 function Output(token, liquid) {
2481 var _this = _super.call(this, token) || this;
2482 _this.value = new Value(token.content, liquid);
2483 return _this;
2484 }
2485 Output.prototype.render = function (ctx, emitter) {
2486 var val;
2487 return __generator(this, function (_a) {
2488 switch (_a.label) {
2489 case 0: return [4 /*yield*/, this.value.value(ctx, false)];
2490 case 1:
2491 val = _a.sent();
2492 emitter.write(val);
2493 return [2 /*return*/];
2494 }
2495 });
2496 };
2497 return Output;
2498 }(TemplateImpl));
2499
2500 var HTML = /** @class */ (function (_super) {
2501 __extends(HTML, _super);
2502 function HTML(token) {
2503 var _this = _super.call(this, token) || this;
2504 _this.str = token.getContent();
2505 return _this;
2506 }
2507 HTML.prototype.render = function (ctx, emitter) {
2508 return __generator(this, function (_a) {
2509 emitter.write(this.str);
2510 return [2 /*return*/];
2511 });
2512 };
2513 return HTML;
2514 }(TemplateImpl));
2515
2516 var Parser = /** @class */ (function () {
2517 function Parser(liquid) {
2518 this.liquid = liquid;
2519 this.cache = this.liquid.options.cache;
2520 this.fs = this.liquid.options.fs;
2521 this.parseFile = this.cache ? this._parseFileCached : this._parseFile;
2522 this.loader = new Loader(this.liquid.options);
2523 }
2524 Parser.prototype.parse = function (html, filepath) {
2525 var tokenizer = new Tokenizer(html, this.liquid.options.operatorsTrie, filepath);
2526 var tokens = tokenizer.readTopLevelTokens(this.liquid.options);
2527 return this.parseTokens(tokens);
2528 };
2529 Parser.prototype.parseTokens = function (tokens) {
2530 var token;
2531 var templates = [];
2532 while ((token = tokens.shift())) {
2533 templates.push(this.parseToken(token, tokens));
2534 }
2535 return templates;
2536 };
2537 Parser.prototype.parseToken = function (token, remainTokens) {
2538 try {
2539 if (isTagToken(token)) {
2540 return new Tag(token, remainTokens, this.liquid);
2541 }
2542 if (isOutputToken(token)) {
2543 return new Output(token, this.liquid);
2544 }
2545 return new HTML(token);
2546 }
2547 catch (e) {
2548 throw new ParseError(e, token);
2549 }
2550 };
2551 Parser.prototype.parseStream = function (tokens) {
2552 var _this = this;
2553 return new ParseStream(tokens, function (token, tokens) { return _this.parseToken(token, tokens); });
2554 };
2555 Parser.prototype._parseFileCached = function (file, sync, type, currentFile) {
2556 var key, tpls, task;
2557 if (type === void 0) { type = LookupType.Root; }
2558 return __generator(this, function (_a) {
2559 switch (_a.label) {
2560 case 0:
2561 key = this.loader.shouldLoadRelative(file)
2562 ? currentFile + ',' + file
2563 : type + ':' + file;
2564 return [4 /*yield*/, this.cache.read(key)];
2565 case 1:
2566 tpls = _a.sent();
2567 if (tpls)
2568 return [2 /*return*/, tpls];
2569 task = toThenable(this._parseFile(file, sync, type, currentFile));
2570 this.cache.write(key, task);
2571 _a.label = 2;
2572 case 2:
2573 _a.trys.push([2, 4, , 5]);
2574 return [4 /*yield*/, task];
2575 case 3: return [2 /*return*/, _a.sent()];
2576 case 4:
2577 _a.sent();
2578 // remove cached task if failed
2579 this.cache.remove(key);
2580 return [3 /*break*/, 5];
2581 case 5: return [2 /*return*/, []];
2582 }
2583 });
2584 };
2585 Parser.prototype._parseFile = function (file, sync, type, currentFile) {
2586 var filepath, _a, _b, _c;
2587 if (type === void 0) { type = LookupType.Root; }
2588 return __generator(this, function (_d) {
2589 switch (_d.label) {
2590 case 0: return [4 /*yield*/, this.loader.lookup(file, type, sync, currentFile)];
2591 case 1:
2592 filepath = _d.sent();
2593 _b = (_a = this.liquid).parse;
2594 if (!sync) return [3 /*break*/, 2];
2595 _c = this.fs.readFileSync(filepath);
2596 return [3 /*break*/, 4];
2597 case 2: return [4 /*yield*/, this.fs.readFile(filepath)];
2598 case 3:
2599 _c = _d.sent();
2600 _d.label = 4;
2601 case 4: return [2 /*return*/, _b.apply(_a, [_c, filepath])];
2602 }
2603 });
2604 };
2605 return Parser;
2606 }());
2607
2608 var assign = {
2609 parse: function (token) {
2610 var tokenizer = new Tokenizer(token.args, this.liquid.options.operatorsTrie);
2611 this.key = tokenizer.readIdentifier().content;
2612 tokenizer.skipBlank();
2613 assert(tokenizer.peek() === '=', function () { return "illegal token ".concat(token.getText()); });
2614 tokenizer.advance();
2615 this.value = tokenizer.remaining();
2616 },
2617 render: function (ctx) {
2618 var _a, _b;
2619 return __generator(this, function (_c) {
2620 switch (_c.label) {
2621 case 0:
2622 _a = ctx.bottom();
2623 _b = this.key;
2624 return [4 /*yield*/, this.liquid._evalValue(this.value, ctx)];
2625 case 1:
2626 _a[_b] = _c.sent();
2627 return [2 /*return*/];
2628 }
2629 });
2630 }
2631 };
2632
2633 function toEnumerable(val) {
2634 if (isArray(val))
2635 return val;
2636 if (isString(val) && val.length > 0)
2637 return [val];
2638 if (isObject(val))
2639 return Object.keys(val).map(function (key) { return [key, val[key]]; });
2640 return [];
2641 }
2642 function toArray(val) {
2643 if (isArray(val))
2644 return val;
2645 return [val];
2646 }
2647
2648 var ForloopDrop = /** @class */ (function (_super) {
2649 __extends(ForloopDrop, _super);
2650 function ForloopDrop(length, collection, variable) {
2651 var _this = _super.call(this) || this;
2652 _this.i = 0;
2653 _this.length = length;
2654 _this.name = "".concat(variable, "-").concat(collection);
2655 return _this;
2656 }
2657 ForloopDrop.prototype.next = function () {
2658 this.i++;
2659 };
2660 ForloopDrop.prototype.index0 = function () {
2661 return this.i;
2662 };
2663 ForloopDrop.prototype.index = function () {
2664 return this.i + 1;
2665 };
2666 ForloopDrop.prototype.first = function () {
2667 return this.i === 0;
2668 };
2669 ForloopDrop.prototype.last = function () {
2670 return this.i === this.length - 1;
2671 };
2672 ForloopDrop.prototype.rindex = function () {
2673 return this.length - this.i;
2674 };
2675 ForloopDrop.prototype.rindex0 = function () {
2676 return this.length - this.i - 1;
2677 };
2678 ForloopDrop.prototype.valueOf = function () {
2679 return JSON.stringify(this);
2680 };
2681 return ForloopDrop;
2682 }(Drop));
2683
2684 var MODIFIERS = ['offset', 'limit', 'reversed'];
2685 var For = {
2686 type: 'block',
2687 parse: function (token, remainTokens) {
2688 var _this = this;
2689 var tokenizer = new Tokenizer(token.args, this.liquid.options.operatorsTrie);
2690 var variable = tokenizer.readIdentifier();
2691 var inStr = tokenizer.readIdentifier();
2692 var collection = tokenizer.readValue();
2693 assert(variable.size() && inStr.content === 'in' && collection, function () { return "illegal tag: ".concat(token.getText()); });
2694 this.variable = variable.content;
2695 this.collection = collection;
2696 this.hash = new Hash(tokenizer.remaining());
2697 this.templates = [];
2698 this.elseTemplates = [];
2699 var p;
2700 var stream = this.liquid.parser.parseStream(remainTokens)
2701 .on('start', function () { return (p = _this.templates); })
2702 .on('tag:else', function () { return (p = _this.elseTemplates); })
2703 .on('tag:endfor', function () { return stream.stop(); })
2704 .on('template', function (tpl) { return p.push(tpl); })
2705 .on('end', function () {
2706 throw new Error("tag ".concat(token.getText(), " not closed"));
2707 });
2708 stream.start();
2709 },
2710 render: function (ctx, emitter) {
2711 var r, collection, _a, continueKey, hash, modifiers, scope, collection_1, collection_1_1, item, e_1_1;
2712 var e_1, _b;
2713 return __generator(this, function (_c) {
2714 switch (_c.label) {
2715 case 0:
2716 r = this.liquid.renderer;
2717 _a = toEnumerable;
2718 return [4 /*yield*/, evalToken(this.collection, ctx)];
2719 case 1:
2720 collection = _a.apply(void 0, [_c.sent()]);
2721 if (!!collection.length) return [3 /*break*/, 3];
2722 return [4 /*yield*/, r.renderTemplates(this.elseTemplates, ctx, emitter)];
2723 case 2:
2724 _c.sent();
2725 return [2 /*return*/];
2726 case 3:
2727 continueKey = 'continue-' + this.variable + '-' + this.collection.getText();
2728 ctx.push({ continue: ctx.getRegister(continueKey) });
2729 return [4 /*yield*/, this.hash.render(ctx)];
2730 case 4:
2731 hash = _c.sent();
2732 ctx.pop();
2733 modifiers = this.liquid.options.orderedFilterParameters
2734 ? Object.keys(hash).filter(function (x) { return MODIFIERS.includes(x); })
2735 : MODIFIERS.filter(function (x) { return hash[x] !== undefined; });
2736 collection = modifiers.reduce(function (collection, modifier) {
2737 if (modifier === 'offset')
2738 return offset(collection, hash['offset']);
2739 if (modifier === 'limit')
2740 return limit(collection, hash['limit']);
2741 return reversed(collection);
2742 }, collection);
2743 ctx.setRegister(continueKey, (hash['offset'] || 0) + collection.length);
2744 scope = { forloop: new ForloopDrop(collection.length, this.collection.getText(), this.variable) };
2745 ctx.push(scope);
2746 _c.label = 5;
2747 case 5:
2748 _c.trys.push([5, 10, 11, 12]);
2749 collection_1 = __values(collection), collection_1_1 = collection_1.next();
2750 _c.label = 6;
2751 case 6:
2752 if (!!collection_1_1.done) return [3 /*break*/, 9];
2753 item = collection_1_1.value;
2754 scope[this.variable] = item;
2755 return [4 /*yield*/, r.renderTemplates(this.templates, ctx, emitter)];
2756 case 7:
2757 _c.sent();
2758 if (emitter['break']) {
2759 emitter['break'] = false;
2760 return [3 /*break*/, 9];
2761 }
2762 emitter['continue'] = false;
2763 scope.forloop.next();
2764 _c.label = 8;
2765 case 8:
2766 collection_1_1 = collection_1.next();
2767 return [3 /*break*/, 6];
2768 case 9: return [3 /*break*/, 12];
2769 case 10:
2770 e_1_1 = _c.sent();
2771 e_1 = { error: e_1_1 };
2772 return [3 /*break*/, 12];
2773 case 11:
2774 try {
2775 if (collection_1_1 && !collection_1_1.done && (_b = collection_1.return)) _b.call(collection_1);
2776 }
2777 finally { if (e_1) throw e_1.error; }
2778 return [7 /*endfinally*/];
2779 case 12:
2780 ctx.pop();
2781 return [2 /*return*/];
2782 }
2783 });
2784 }
2785 };
2786 function reversed(arr) {
2787 return __spreadArray([], __read(arr), false).reverse();
2788 }
2789 function offset(arr, count) {
2790 return arr.slice(count);
2791 }
2792 function limit(arr, count) {
2793 return arr.slice(0, count);
2794 }
2795
2796 var capture = {
2797 parse: function (tagToken, remainTokens) {
2798 var _this = this;
2799 var tokenizer = new Tokenizer(tagToken.args, this.liquid.options.operatorsTrie);
2800 this.variable = readVariableName(tokenizer);
2801 assert(this.variable, function () { return "".concat(tagToken.args, " not valid identifier"); });
2802 this.templates = [];
2803 var stream = this.liquid.parser.parseStream(remainTokens);
2804 stream.on('tag:endcapture', function () { return stream.stop(); })
2805 .on('template', function (tpl) { return _this.templates.push(tpl); })
2806 .on('end', function () {
2807 throw new Error("tag ".concat(tagToken.getText(), " not closed"));
2808 });
2809 stream.start();
2810 },
2811 render: function (ctx) {
2812 var r, html;
2813 return __generator(this, function (_a) {
2814 switch (_a.label) {
2815 case 0:
2816 r = this.liquid.renderer;
2817 return [4 /*yield*/, r.renderTemplates(this.templates, ctx)];
2818 case 1:
2819 html = _a.sent();
2820 ctx.bottom()[this.variable] = html;
2821 return [2 /*return*/];
2822 }
2823 });
2824 }
2825 };
2826 function readVariableName(tokenizer) {
2827 var word = tokenizer.readIdentifier().content;
2828 if (word)
2829 return word;
2830 var quoted = tokenizer.readQuoted();
2831 if (quoted)
2832 return evalQuotedToken(quoted);
2833 }
2834
2835 var Case = {
2836 parse: function (tagToken, remainTokens) {
2837 var _this = this;
2838 this.cond = new Value(tagToken.args, this.liquid);
2839 this.cases = [];
2840 this.elseTemplates = [];
2841 var p = [];
2842 var stream = this.liquid.parser.parseStream(remainTokens)
2843 .on('tag:when', function (token) {
2844 p = [];
2845 var tokenizer = new Tokenizer(token.args, _this.liquid.options.operatorsTrie);
2846 while (!tokenizer.end()) {
2847 var value = tokenizer.readValue();
2848 _this.cases.push({
2849 val: value,
2850 templates: p
2851 });
2852 tokenizer.readTo(',');
2853 }
2854 })
2855 .on('tag:else', function () { return (p = _this.elseTemplates); })
2856 .on('tag:endcase', function () { return stream.stop(); })
2857 .on('template', function (tpl) { return p.push(tpl); })
2858 .on('end', function () {
2859 throw new Error("tag ".concat(tagToken.getText(), " not closed"));
2860 });
2861 stream.start();
2862 },
2863 render: function (ctx, emitter) {
2864 var r, cond, _a, _b, _c, branch, val, e_1_1;
2865 var e_1, _d;
2866 return __generator(this, function (_e) {
2867 switch (_e.label) {
2868 case 0:
2869 r = this.liquid.renderer;
2870 _a = toValue$1;
2871 return [4 /*yield*/, this.cond.value(ctx, ctx.opts.lenientIf)];
2872 case 1:
2873 cond = _a.apply(void 0, [_e.sent()]);
2874 _e.label = 2;
2875 case 2:
2876 _e.trys.push([2, 7, 8, 9]);
2877 _b = __values(this.cases), _c = _b.next();
2878 _e.label = 3;
2879 case 3:
2880 if (!!_c.done) return [3 /*break*/, 6];
2881 branch = _c.value;
2882 val = evalToken(branch.val, ctx, ctx.opts.lenientIf);
2883 if (!(val === cond)) return [3 /*break*/, 5];
2884 return [4 /*yield*/, r.renderTemplates(branch.templates, ctx, emitter)];
2885 case 4:
2886 _e.sent();
2887 return [2 /*return*/];
2888 case 5:
2889 _c = _b.next();
2890 return [3 /*break*/, 3];
2891 case 6: return [3 /*break*/, 9];
2892 case 7:
2893 e_1_1 = _e.sent();
2894 e_1 = { error: e_1_1 };
2895 return [3 /*break*/, 9];
2896 case 8:
2897 try {
2898 if (_c && !_c.done && (_d = _b.return)) _d.call(_b);
2899 }
2900 finally { if (e_1) throw e_1.error; }
2901 return [7 /*endfinally*/];
2902 case 9: return [4 /*yield*/, r.renderTemplates(this.elseTemplates, ctx, emitter)];
2903 case 10:
2904 _e.sent();
2905 return [2 /*return*/];
2906 }
2907 });
2908 }
2909 };
2910
2911 var comment = {
2912 parse: function (tagToken, remainTokens) {
2913 var stream = this.liquid.parser.parseStream(remainTokens);
2914 stream
2915 .on('token', function (token) {
2916 if (token.name === 'endcomment')
2917 stream.stop();
2918 })
2919 .on('end', function () {
2920 throw new Error("tag ".concat(tagToken.getText(), " not closed"));
2921 });
2922 stream.start();
2923 }
2924 };
2925
2926 var BlockMode;
2927 (function (BlockMode) {
2928 /* store rendered html into blocks */
2929 BlockMode[BlockMode["OUTPUT"] = 0] = "OUTPUT";
2930 /* output rendered html directly */
2931 BlockMode[BlockMode["STORE"] = 1] = "STORE";
2932 })(BlockMode || (BlockMode = {}));
2933 var BlockMode$1 = BlockMode;
2934
2935 var render = {
2936 parseFilePath: parseFilePath,
2937 renderFilePath: renderFilePath,
2938 parse: function (token) {
2939 var args = token.args;
2940 var tokenizer = new Tokenizer(args, this.liquid.options.operatorsTrie);
2941 this['file'] = this.parseFilePath(tokenizer, this.liquid);
2942 this['currentFile'] = token.file;
2943 while (!tokenizer.end()) {
2944 tokenizer.skipBlank();
2945 var begin = tokenizer.p;
2946 var keyword = tokenizer.readIdentifier();
2947 if (keyword.content === 'with' || keyword.content === 'for') {
2948 tokenizer.skipBlank();
2949 // can be normal key/value pair, like "with: true"
2950 if (tokenizer.peek() !== ':') {
2951 var value = tokenizer.readValue();
2952 // can be normal key, like "with,"
2953 if (value) {
2954 var beforeAs = tokenizer.p;
2955 var asStr = tokenizer.readIdentifier();
2956 var alias = void 0;
2957 if (asStr.content === 'as')
2958 alias = tokenizer.readIdentifier();
2959 else
2960 tokenizer.p = beforeAs;
2961 this[keyword.content] = { value: value, alias: alias && alias.content };
2962 tokenizer.skipBlank();
2963 if (tokenizer.peek() === ',')
2964 tokenizer.advance();
2965 // matched!
2966 continue;
2967 }
2968 }
2969 }
2970 /**
2971 * restore cursor if with/for not matched
2972 */
2973 tokenizer.p = begin;
2974 break;
2975 }
2976 this.hash = new Hash(tokenizer.remaining());
2977 },
2978 render: function (ctx, emitter) {
2979 var _a, liquid, hash, filepath, childCtx, scope, _b, _c, _d, value, alias, _e, value, alias, collection, collection_1, collection_1_1, item, templates, e_1_1, templates;
2980 var e_1, _f;
2981 return __generator(this, function (_g) {
2982 switch (_g.label) {
2983 case 0:
2984 _a = this, liquid = _a.liquid, hash = _a.hash;
2985 return [4 /*yield*/, this.renderFilePath(this['file'], ctx, liquid)];
2986 case 1:
2987 filepath = _g.sent();
2988 assert(filepath, function () { return "illegal filename \"".concat(filepath, "\""); });
2989 childCtx = new Context({}, ctx.opts, { sync: ctx.sync, globals: ctx.globals, strictVariables: ctx.strictVariables });
2990 scope = childCtx.bottom();
2991 _b = __assign;
2992 _c = [scope];
2993 return [4 /*yield*/, hash.render(ctx)];
2994 case 2:
2995 _b.apply(void 0, _c.concat([_g.sent()]));
2996 if (this['with']) {
2997 _d = this['with'], value = _d.value, alias = _d.alias;
2998 scope[alias || filepath] = evalToken(value, ctx);
2999 }
3000 if (!this['for']) return [3 /*break*/, 12];
3001 _e = this['for'], value = _e.value, alias = _e.alias;
3002 collection = evalToken(value, ctx);
3003 collection = toEnumerable(collection);
3004 scope['forloop'] = new ForloopDrop(collection.length, value.getText(), alias);
3005 _g.label = 3;
3006 case 3:
3007 _g.trys.push([3, 9, 10, 11]);
3008 collection_1 = __values(collection), collection_1_1 = collection_1.next();
3009 _g.label = 4;
3010 case 4:
3011 if (!!collection_1_1.done) return [3 /*break*/, 8];
3012 item = collection_1_1.value;
3013 scope[alias] = item;
3014 return [4 /*yield*/, liquid._parsePartialFile(filepath, childCtx.sync, this['currentFile'])];
3015 case 5:
3016 templates = _g.sent();
3017 return [4 /*yield*/, liquid.renderer.renderTemplates(templates, childCtx, emitter)];
3018 case 6:
3019 _g.sent();
3020 scope['forloop'].next();
3021 _g.label = 7;
3022 case 7:
3023 collection_1_1 = collection_1.next();
3024 return [3 /*break*/, 4];
3025 case 8: return [3 /*break*/, 11];
3026 case 9:
3027 e_1_1 = _g.sent();
3028 e_1 = { error: e_1_1 };
3029 return [3 /*break*/, 11];
3030 case 10:
3031 try {
3032 if (collection_1_1 && !collection_1_1.done && (_f = collection_1.return)) _f.call(collection_1);
3033 }
3034 finally { if (e_1) throw e_1.error; }
3035 return [7 /*endfinally*/];
3036 case 11: return [3 /*break*/, 15];
3037 case 12: return [4 /*yield*/, liquid._parsePartialFile(filepath, childCtx.sync, this['currentFile'])];
3038 case 13:
3039 templates = _g.sent();
3040 return [4 /*yield*/, liquid.renderer.renderTemplates(templates, childCtx, emitter)];
3041 case 14:
3042 _g.sent();
3043 _g.label = 15;
3044 case 15: return [2 /*return*/];
3045 }
3046 });
3047 }
3048 };
3049 /**
3050 * @return null for "none",
3051 * @return Template[] for quoted with tags and/or filters
3052 * @return Token for expression (not quoted)
3053 * @throws TypeError if cannot read next token
3054 */
3055 function parseFilePath(tokenizer, liquid) {
3056 if (liquid.options.dynamicPartials) {
3057 var file = tokenizer.readValue();
3058 if (file === undefined)
3059 throw new TypeError("illegal argument \"".concat(tokenizer.input, "\""));
3060 if (file.getText() === 'none')
3061 return null;
3062 if (isQuotedToken(file)) {
3063 // for filenames like "files/{{file}}", eval as liquid template
3064 var templates_1 = liquid.parse(evalQuotedToken(file));
3065 return optimize(templates_1);
3066 }
3067 return file;
3068 }
3069 var tokens = __spreadArray([], __read(tokenizer.readFileNameTemplate(liquid.options)), false);
3070 var templates = optimize(liquid.parser.parseTokens(tokens));
3071 return templates === 'none' ? null : templates;
3072 }
3073 function optimize(templates) {
3074 // for filenames like "files/file.liquid", extract the string directly
3075 if (templates.length === 1 && isHTMLToken(templates[0].token))
3076 return templates[0].token.getContent();
3077 return templates;
3078 }
3079 function renderFilePath(file, ctx, liquid) {
3080 if (typeof file === 'string')
3081 return file;
3082 if (Array.isArray(file))
3083 return liquid.renderer.renderTemplates(file, ctx);
3084 return evalToken(file, ctx);
3085 }
3086
3087 var include = {
3088 parseFilePath: parseFilePath,
3089 renderFilePath: renderFilePath,
3090 parse: function (token) {
3091 var args = token.args;
3092 var tokenizer = new Tokenizer(args, this.liquid.options.operatorsTrie);
3093 this['file'] = this.parseFilePath(tokenizer, this.liquid);
3094 this['currentFile'] = token.file;
3095 var begin = tokenizer.p;
3096 var withStr = tokenizer.readIdentifier();
3097 if (withStr.content === 'with') {
3098 tokenizer.skipBlank();
3099 if (tokenizer.peek() !== ':') {
3100 this.withVar = tokenizer.readValue();
3101 }
3102 else
3103 tokenizer.p = begin;
3104 }
3105 else
3106 tokenizer.p = begin;
3107 this.hash = new Hash(tokenizer.remaining(), this.liquid.options.jekyllInclude);
3108 },
3109 render: function (ctx, emitter) {
3110 var _a, liquid, hash, withVar, renderer, filepath, saved, scope, templates;
3111 return __generator(this, function (_b) {
3112 switch (_b.label) {
3113 case 0:
3114 _a = this, liquid = _a.liquid, hash = _a.hash, withVar = _a.withVar;
3115 renderer = liquid.renderer;
3116 return [4 /*yield*/, this.renderFilePath(this['file'], ctx, liquid)];
3117 case 1:
3118 filepath = _b.sent();
3119 assert(filepath, function () { return "illegal filename \"".concat(filepath, "\""); });
3120 saved = ctx.saveRegister('blocks', 'blockMode');
3121 ctx.setRegister('blocks', {});
3122 ctx.setRegister('blockMode', BlockMode$1.OUTPUT);
3123 return [4 /*yield*/, hash.render(ctx)];
3124 case 2:
3125 scope = _b.sent();
3126 if (withVar)
3127 scope[filepath] = evalToken(withVar, ctx);
3128 return [4 /*yield*/, liquid._parsePartialFile(filepath, ctx.sync, this['currentFile'])];
3129 case 3:
3130 templates = _b.sent();
3131 ctx.push(ctx.opts.jekyllInclude ? { include: scope } : scope);
3132 return [4 /*yield*/, renderer.renderTemplates(templates, ctx, emitter)];
3133 case 4:
3134 _b.sent();
3135 ctx.pop();
3136 ctx.restoreRegister(saved);
3137 return [2 /*return*/];
3138 }
3139 });
3140 }
3141 };
3142
3143 var decrement = {
3144 parse: function (token) {
3145 var tokenizer = new Tokenizer(token.args, this.liquid.options.operatorsTrie);
3146 this.variable = tokenizer.readIdentifier().content;
3147 },
3148 render: function (context, emitter) {
3149 var scope = context.environments;
3150 if (!isNumber(scope[this.variable])) {
3151 scope[this.variable] = 0;
3152 }
3153 emitter.write(stringify(--scope[this.variable]));
3154 }
3155 };
3156
3157 var cycle = {
3158 parse: function (tagToken) {
3159 var tokenizer = new Tokenizer(tagToken.args, this.liquid.options.operatorsTrie);
3160 var group = tokenizer.readValue();
3161 tokenizer.skipBlank();
3162 this.candidates = [];
3163 if (group) {
3164 if (tokenizer.peek() === ':') {
3165 this.group = group;
3166 tokenizer.advance();
3167 }
3168 else
3169 this.candidates.push(group);
3170 }
3171 while (!tokenizer.end()) {
3172 var value = tokenizer.readValue();
3173 if (value)
3174 this.candidates.push(value);
3175 tokenizer.readTo(',');
3176 }
3177 assert(this.candidates.length, function () { return "empty candidates: ".concat(tagToken.getText()); });
3178 },
3179 render: function (ctx, emitter) {
3180 var group = evalToken(this.group, ctx);
3181 var fingerprint = "cycle:".concat(group, ":") + this.candidates.join(',');
3182 var groups = ctx.getRegister('cycle');
3183 var idx = groups[fingerprint];
3184 if (idx === undefined) {
3185 idx = groups[fingerprint] = 0;
3186 }
3187 var candidate = this.candidates[idx];
3188 idx = (idx + 1) % this.candidates.length;
3189 groups[fingerprint] = idx;
3190 var html = evalToken(candidate, ctx);
3191 emitter.write(html);
3192 }
3193 };
3194
3195 var If = {
3196 parse: function (tagToken, remainTokens) {
3197 var _this = this;
3198 this.branches = [];
3199 this.elseTemplates = [];
3200 var p;
3201 this.liquid.parser.parseStream(remainTokens)
3202 .on('start', function () { return _this.branches.push({
3203 predicate: new Value(tagToken.args, _this.liquid),
3204 templates: (p = [])
3205 }); })
3206 .on('tag:elsif', function (token) { return _this.branches.push({
3207 predicate: new Value(token.args, _this.liquid),
3208 templates: (p = [])
3209 }); })
3210 .on('tag:else', function () { return (p = _this.elseTemplates); })
3211 .on('tag:endif', function () { this.stop(); })
3212 .on('template', function (tpl) { return p.push(tpl); })
3213 .on('end', function () { throw new Error("tag ".concat(tagToken.getText(), " not closed")); })
3214 .start();
3215 },
3216 render: function (ctx, emitter) {
3217 var r, _a, _b, _c, predicate, templates, value, e_1_1;
3218 var e_1, _d;
3219 return __generator(this, function (_e) {
3220 switch (_e.label) {
3221 case 0:
3222 r = this.liquid.renderer;
3223 _e.label = 1;
3224 case 1:
3225 _e.trys.push([1, 7, 8, 9]);
3226 _a = __values(this.branches), _b = _a.next();
3227 _e.label = 2;
3228 case 2:
3229 if (!!_b.done) return [3 /*break*/, 6];
3230 _c = _b.value, predicate = _c.predicate, templates = _c.templates;
3231 return [4 /*yield*/, predicate.value(ctx, ctx.opts.lenientIf)];
3232 case 3:
3233 value = _e.sent();
3234 if (!isTruthy(value, ctx)) return [3 /*break*/, 5];
3235 return [4 /*yield*/, r.renderTemplates(templates, ctx, emitter)];
3236 case 4:
3237 _e.sent();
3238 return [2 /*return*/];
3239 case 5:
3240 _b = _a.next();
3241 return [3 /*break*/, 2];
3242 case 6: return [3 /*break*/, 9];
3243 case 7:
3244 e_1_1 = _e.sent();
3245 e_1 = { error: e_1_1 };
3246 return [3 /*break*/, 9];
3247 case 8:
3248 try {
3249 if (_b && !_b.done && (_d = _a.return)) _d.call(_a);
3250 }
3251 finally { if (e_1) throw e_1.error; }
3252 return [7 /*endfinally*/];
3253 case 9: return [4 /*yield*/, r.renderTemplates(this.elseTemplates, ctx, emitter)];
3254 case 10:
3255 _e.sent();
3256 return [2 /*return*/];
3257 }
3258 });
3259 }
3260 };
3261
3262 var increment = {
3263 parse: function (token) {
3264 var tokenizer = new Tokenizer(token.args, this.liquid.options.operatorsTrie);
3265 this.variable = tokenizer.readIdentifier().content;
3266 },
3267 render: function (context, emitter) {
3268 var scope = context.environments;
3269 if (!isNumber(scope[this.variable])) {
3270 scope[this.variable] = 0;
3271 }
3272 var val = scope[this.variable];
3273 scope[this.variable]++;
3274 emitter.write(stringify(val));
3275 }
3276 };
3277
3278 var layout = {
3279 parseFilePath: parseFilePath,
3280 renderFilePath: renderFilePath,
3281 parse: function (token, remainTokens) {
3282 var tokenizer = new Tokenizer(token.args, this.liquid.options.operatorsTrie);
3283 this['file'] = this.parseFilePath(tokenizer, this.liquid);
3284 this['currentFile'] = token.file;
3285 this.hash = new Hash(tokenizer.remaining());
3286 this.tpls = this.liquid.parser.parseTokens(remainTokens);
3287 },
3288 render: function (ctx, emitter) {
3289 var _a, liquid, hash, file, renderer, filepath, templates, html, blocks, _b, _c;
3290 return __generator(this, function (_d) {
3291 switch (_d.label) {
3292 case 0:
3293 _a = this, liquid = _a.liquid, hash = _a.hash, file = _a.file;
3294 renderer = liquid.renderer;
3295 if (!(file === null)) return [3 /*break*/, 2];
3296 ctx.setRegister('blockMode', BlockMode$1.OUTPUT);
3297 return [4 /*yield*/, renderer.renderTemplates(this.tpls, ctx, emitter)];
3298 case 1:
3299 _d.sent();
3300 return [2 /*return*/];
3301 case 2: return [4 /*yield*/, this.renderFilePath(this['file'], ctx, liquid)];
3302 case 3:
3303 filepath = _d.sent();
3304 assert(filepath, function () { return "illegal filename \"".concat(filepath, "\""); });
3305 return [4 /*yield*/, liquid._parseLayoutFile(filepath, ctx.sync, this['currentFile'])
3306 // render remaining contents and store rendered results
3307 ];
3308 case 4:
3309 templates = _d.sent();
3310 // render remaining contents and store rendered results
3311 ctx.setRegister('blockMode', BlockMode$1.STORE);
3312 return [4 /*yield*/, renderer.renderTemplates(this.tpls, ctx)];
3313 case 5:
3314 html = _d.sent();
3315 blocks = ctx.getRegister('blocks');
3316 // set whole content to anonymous block if anonymous doesn't specified
3317 if (blocks[''] === undefined)
3318 blocks[''] = function (parent, emitter) { return emitter.write(html); };
3319 ctx.setRegister('blockMode', BlockMode$1.OUTPUT);
3320 // render the layout file use stored blocks
3321 _c = (_b = ctx).push;
3322 return [4 /*yield*/, hash.render(ctx)];
3323 case 6:
3324 // render the layout file use stored blocks
3325 _c.apply(_b, [_d.sent()]);
3326 return [4 /*yield*/, renderer.renderTemplates(templates, ctx, emitter)];
3327 case 7:
3328 _d.sent();
3329 ctx.pop();
3330 return [2 /*return*/];
3331 }
3332 });
3333 }
3334 };
3335
3336 var BlockDrop = /** @class */ (function (_super) {
3337 __extends(BlockDrop, _super);
3338 function BlockDrop(
3339 // the block render from layout template
3340 superBlockRender) {
3341 if (superBlockRender === void 0) { superBlockRender = function () { return ''; }; }
3342 var _this = _super.call(this) || this;
3343 _this.superBlockRender = superBlockRender;
3344 return _this;
3345 }
3346 /**
3347 * Provide parent access in child block by
3348 * {{ block.super }}
3349 */
3350 BlockDrop.prototype.super = function () {
3351 return this.superBlockRender();
3352 };
3353 return BlockDrop;
3354 }(Drop));
3355
3356 var block = {
3357 parse: function (token, remainTokens) {
3358 var _this = this;
3359 var match = /\w+/.exec(token.args);
3360 this.block = match ? match[0] : '';
3361 this.tpls = [];
3362 this.liquid.parser.parseStream(remainTokens)
3363 .on('tag:endblock', function () { this.stop(); })
3364 .on('template', function (tpl) { return _this.tpls.push(tpl); })
3365 .on('end', function () { throw new Error("tag ".concat(token.getText(), " not closed")); })
3366 .start();
3367 },
3368 render: function (ctx, emitter) {
3369 var blockRender;
3370 return __generator(this, function (_a) {
3371 switch (_a.label) {
3372 case 0:
3373 blockRender = this.getBlockRender(ctx);
3374 if (!(ctx.getRegister('blockMode') === BlockMode$1.STORE)) return [3 /*break*/, 1];
3375 ctx.getRegister('blocks')[this.block] = blockRender;
3376 return [3 /*break*/, 3];
3377 case 1: return [4 /*yield*/, blockRender(new BlockDrop(), emitter)];
3378 case 2:
3379 _a.sent();
3380 _a.label = 3;
3381 case 3: return [2 /*return*/];
3382 }
3383 });
3384 },
3385 getBlockRender: function (ctx) {
3386 var _a = this, liquid = _a.liquid, tpls = _a.tpls;
3387 var renderChild = ctx.getRegister('blocks')[this.block];
3388 var renderCurrent = function (superBlock, emitter) {
3389 return __generator(this, function (_a) {
3390 switch (_a.label) {
3391 case 0:
3392 // add {{ block.super }} support when rendering
3393 ctx.push({ block: superBlock });
3394 return [4 /*yield*/, liquid.renderer.renderTemplates(tpls, ctx, emitter)];
3395 case 1:
3396 _a.sent();
3397 ctx.pop();
3398 return [2 /*return*/];
3399 }
3400 });
3401 };
3402 return renderChild
3403 ? function (superBlock, emitter) { return renderChild(new BlockDrop(function () { return renderCurrent(superBlock, emitter); }), emitter); }
3404 : renderCurrent;
3405 }
3406 };
3407
3408 var raw = {
3409 parse: function (tagToken, remainTokens) {
3410 var _this = this;
3411 this.tokens = [];
3412 var stream = this.liquid.parser.parseStream(remainTokens);
3413 stream
3414 .on('token', function (token) {
3415 if (token.name === 'endraw')
3416 stream.stop();
3417 else
3418 _this.tokens.push(token);
3419 })
3420 .on('end', function () {
3421 throw new Error("tag ".concat(tagToken.getText(), " not closed"));
3422 });
3423 stream.start();
3424 },
3425 render: function () {
3426 return this.tokens.map(function (token) { return token.getText(); }).join('');
3427 }
3428 };
3429
3430 var TablerowloopDrop = /** @class */ (function (_super) {
3431 __extends(TablerowloopDrop, _super);
3432 function TablerowloopDrop(length, cols, collection, variable) {
3433 var _this = _super.call(this, length, collection, variable) || this;
3434 _this.length = length;
3435 _this.cols = cols;
3436 return _this;
3437 }
3438 TablerowloopDrop.prototype.row = function () {
3439 return Math.floor(this.i / this.cols) + 1;
3440 };
3441 TablerowloopDrop.prototype.col0 = function () {
3442 return (this.i % this.cols);
3443 };
3444 TablerowloopDrop.prototype.col = function () {
3445 return this.col0() + 1;
3446 };
3447 TablerowloopDrop.prototype.col_first = function () {
3448 return this.col0() === 0;
3449 };
3450 TablerowloopDrop.prototype.col_last = function () {
3451 return this.col() === this.cols;
3452 };
3453 return TablerowloopDrop;
3454 }(ForloopDrop));
3455
3456 var tablerow = {
3457 parse: function (tagToken, remainTokens) {
3458 var _this = this;
3459 var tokenizer = new Tokenizer(tagToken.args, this.liquid.options.operatorsTrie);
3460 var variable = tokenizer.readIdentifier();
3461 tokenizer.skipBlank();
3462 var tmp = tokenizer.readIdentifier();
3463 assert(tmp && tmp.content === 'in', function () { return "illegal tag: ".concat(tagToken.getText()); });
3464 this.variable = variable.content;
3465 this.collection = tokenizer.readValue();
3466 this.hash = new Hash(tokenizer.remaining());
3467 this.templates = [];
3468 var p;
3469 var stream = this.liquid.parser.parseStream(remainTokens)
3470 .on('start', function () { return (p = _this.templates); })
3471 .on('tag:endtablerow', function () { return stream.stop(); })
3472 .on('template', function (tpl) { return p.push(tpl); })
3473 .on('end', function () {
3474 throw new Error("tag ".concat(tagToken.getText(), " not closed"));
3475 });
3476 stream.start();
3477 },
3478 render: function (ctx, emitter) {
3479 var collection, _a, hash, offset, limit, cols, r, tablerowloop, scope, idx;
3480 return __generator(this, function (_b) {
3481 switch (_b.label) {
3482 case 0:
3483 _a = toEnumerable;
3484 return [4 /*yield*/, evalToken(this.collection, ctx)];
3485 case 1:
3486 collection = _a.apply(void 0, [_b.sent()]);
3487 return [4 /*yield*/, this.hash.render(ctx)];
3488 case 2:
3489 hash = _b.sent();
3490 offset = hash.offset || 0;
3491 limit = (hash.limit === undefined) ? collection.length : hash.limit;
3492 collection = collection.slice(offset, offset + limit);
3493 cols = hash.cols || collection.length;
3494 r = this.liquid.renderer;
3495 tablerowloop = new TablerowloopDrop(collection.length, cols, this.collection.getText(), this.variable);
3496 scope = { tablerowloop: tablerowloop };
3497 ctx.push(scope);
3498 idx = 0;
3499 _b.label = 3;
3500 case 3:
3501 if (!(idx < collection.length)) return [3 /*break*/, 6];
3502 scope[this.variable] = collection[idx];
3503 if (tablerowloop.col0() === 0) {
3504 if (tablerowloop.row() !== 1)
3505 emitter.write('</tr>');
3506 emitter.write("<tr class=\"row".concat(tablerowloop.row(), "\">"));
3507 }
3508 emitter.write("<td class=\"col".concat(tablerowloop.col(), "\">"));
3509 return [4 /*yield*/, r.renderTemplates(this.templates, ctx, emitter)];
3510 case 4:
3511 _b.sent();
3512 emitter.write('</td>');
3513 _b.label = 5;
3514 case 5:
3515 idx++, tablerowloop.next();
3516 return [3 /*break*/, 3];
3517 case 6:
3518 if (collection.length)
3519 emitter.write('</tr>');
3520 ctx.pop();
3521 return [2 /*return*/];
3522 }
3523 });
3524 }
3525 };
3526
3527 var unless = {
3528 parse: function (tagToken, remainTokens) {
3529 var _this = this;
3530 this.branches = [];
3531 this.elseTemplates = [];
3532 var p;
3533 this.liquid.parser.parseStream(remainTokens)
3534 .on('start', function () { return _this.branches.push({
3535 predicate: new Value(tagToken.args, _this.liquid),
3536 test: isFalsy,
3537 templates: (p = [])
3538 }); })
3539 .on('tag:elsif', function (token) { return _this.branches.push({
3540 predicate: new Value(token.args, _this.liquid),
3541 test: isTruthy,
3542 templates: (p = [])
3543 }); })
3544 .on('tag:else', function () { return (p = _this.elseTemplates); })
3545 .on('tag:endunless', function () { this.stop(); })
3546 .on('template', function (tpl) { return p.push(tpl); })
3547 .on('end', function () { throw new Error("tag ".concat(tagToken.getText(), " not closed")); })
3548 .start();
3549 },
3550 render: function (ctx, emitter) {
3551 var r, _a, _b, _c, predicate, test_1, templates, value, e_1_1;
3552 var e_1, _d;
3553 return __generator(this, function (_e) {
3554 switch (_e.label) {
3555 case 0:
3556 r = this.liquid.renderer;
3557 _e.label = 1;
3558 case 1:
3559 _e.trys.push([1, 7, 8, 9]);
3560 _a = __values(this.branches), _b = _a.next();
3561 _e.label = 2;
3562 case 2:
3563 if (!!_b.done) return [3 /*break*/, 6];
3564 _c = _b.value, predicate = _c.predicate, test_1 = _c.test, templates = _c.templates;
3565 return [4 /*yield*/, predicate.value(ctx, ctx.opts.lenientIf)];
3566 case 3:
3567 value = _e.sent();
3568 if (!test_1(value, ctx)) return [3 /*break*/, 5];
3569 return [4 /*yield*/, r.renderTemplates(templates, ctx, emitter)];
3570 case 4:
3571 _e.sent();
3572 return [2 /*return*/];
3573 case 5:
3574 _b = _a.next();
3575 return [3 /*break*/, 2];
3576 case 6: return [3 /*break*/, 9];
3577 case 7:
3578 e_1_1 = _e.sent();
3579 e_1 = { error: e_1_1 };
3580 return [3 /*break*/, 9];
3581 case 8:
3582 try {
3583 if (_b && !_b.done && (_d = _a.return)) _d.call(_a);
3584 }
3585 finally { if (e_1) throw e_1.error; }
3586 return [7 /*endfinally*/];
3587 case 9: return [4 /*yield*/, r.renderTemplates(this.elseTemplates, ctx, emitter)];
3588 case 10:
3589 _e.sent();
3590 return [2 /*return*/];
3591 }
3592 });
3593 }
3594 };
3595
3596 var Break = {
3597 render: function (ctx, emitter) {
3598 emitter['break'] = true;
3599 }
3600 };
3601
3602 var Continue = {
3603 render: function (ctx, emitter) {
3604 emitter['continue'] = true;
3605 }
3606 };
3607
3608 var echo = {
3609 parse: function (token) {
3610 this.value = new Value(token.args, this.liquid);
3611 },
3612 render: function (ctx, emitter) {
3613 var val;
3614 return __generator(this, function (_a) {
3615 switch (_a.label) {
3616 case 0: return [4 /*yield*/, this.value.value(ctx, false)];
3617 case 1:
3618 val = _a.sent();
3619 emitter.write(val);
3620 return [2 /*return*/];
3621 }
3622 });
3623 }
3624 };
3625
3626 var liquid = {
3627 parse: function (token) {
3628 var tokenizer = new Tokenizer(token.args, this.liquid.options.operatorsTrie);
3629 var tokens = tokenizer.readLiquidTagTokens(this.liquid.options);
3630 this.tpls = this.liquid.parser.parseTokens(tokens);
3631 },
3632 render: function (ctx, emitter) {
3633 return __generator(this, function (_a) {
3634 switch (_a.label) {
3635 case 0: return [4 /*yield*/, this.liquid.renderer.renderTemplates(this.tpls, ctx, emitter)];
3636 case 1:
3637 _a.sent();
3638 return [2 /*return*/];
3639 }
3640 });
3641 }
3642 };
3643
3644 var tags = {
3645 assign: assign,
3646 'for': For,
3647 capture: capture,
3648 'case': Case,
3649 comment: comment,
3650 include: include,
3651 render: render,
3652 decrement: decrement,
3653 increment: increment,
3654 cycle: cycle,
3655 'if': If,
3656 layout: layout,
3657 block: block,
3658 raw: raw,
3659 tablerow: tablerow,
3660 unless: unless,
3661 'break': Break, 'continue': Continue,
3662 echo: echo,
3663 liquid: liquid
3664 };
3665
3666 var escapeMap = {
3667 '&': '&amp;',
3668 '<': '&lt;',
3669 '>': '&gt;',
3670 '"': '&#34;',
3671 "'": '&#39;'
3672 };
3673 var unescapeMap = {
3674 '&amp;': '&',
3675 '&lt;': '<',
3676 '&gt;': '>',
3677 '&#34;': '"',
3678 '&#39;': "'"
3679 };
3680 function escape(str) {
3681 return stringify(str).replace(/&|<|>|"|'/g, function (m) { return escapeMap[m]; });
3682 }
3683 function unescape(str) {
3684 return String(str).replace(/&(amp|lt|gt|#34|#39);/g, function (m) { return unescapeMap[m]; });
3685 }
3686 function escapeOnce(str) {
3687 return escape(unescape(str));
3688 }
3689 function newlineToBr(v) {
3690 return v.replace(/\n/g, '<br />\n');
3691 }
3692 function stripHtml(v) {
3693 return v.replace(/<script.*?<\/script>|<!--.*?-->|<style.*?<\/style>|<.*?>/g, '');
3694 }
3695
3696 var abs = Math.abs;
3697 var atLeast = Math.max;
3698 var atMost = Math.min;
3699 var ceil = Math.ceil;
3700 var dividedBy = function (v, arg) { return v / arg; };
3701 var floor = Math.floor;
3702 var minus = function (v, arg) { return v - arg; };
3703 var modulo = function (v, arg) { return v % arg; };
3704 var times = function (v, arg) { return v * arg; };
3705 function round(v, arg) {
3706 if (arg === void 0) { arg = 0; }
3707 var amp = Math.pow(10, arg);
3708 return Math.round(v * amp) / amp;
3709 }
3710 function plus(v, arg) {
3711 return Number(v) + Number(arg);
3712 }
3713 function sortNatural(input, property) {
3714 if (!input || !input.sort)
3715 return [];
3716 if (property !== undefined) {
3717 return __spreadArray([], __read(input), false).sort(function (lhs, rhs) { return caseInsensitiveCompare(lhs[property], rhs[property]); });
3718 }
3719 return __spreadArray([], __read(input), false).sort(caseInsensitiveCompare);
3720 }
3721
3722 var urlDecode = function (x) { return x.split('+').map(decodeURIComponent).join(' '); };
3723 var urlEncode = function (x) { return x.split(' ').map(encodeURIComponent).join('+'); };
3724
3725 var join = function (v, arg) { return v.join(arg === undefined ? ' ' : arg); };
3726 var last = function (v) { return isArray(v) ? last$1(v) : ''; };
3727 var first = function (v) { return isArray(v) ? v[0] : ''; };
3728 var reverse = function (v) { return __spreadArray([], __read(v), false).reverse(); };
3729 function sort(arr, property) {
3730 var _this = this;
3731 var getValue = function (obj) { return property ? _this.context.getFromScope(obj, property.split('.')) : obj; };
3732 return toArray(arr).sort(function (lhs, rhs) {
3733 lhs = getValue(lhs);
3734 rhs = getValue(rhs);
3735 return lhs < rhs ? -1 : (lhs > rhs ? 1 : 0);
3736 });
3737 }
3738 var size = function (v) { return (v && v.length) || 0; };
3739 function map(arr, property) {
3740 var _this = this;
3741 return toArray(arr).map(function (obj) { return _this.context.getFromScope(obj, property.split('.')); });
3742 }
3743 function compact(arr) {
3744 return toArray(arr).filter(function (x) { return !isNil(x); });
3745 }
3746 function concat(v, arg) {
3747 return toArray(v).concat(arg);
3748 }
3749 function slice(v, begin, length) {
3750 if (length === void 0) { length = 1; }
3751 begin = begin < 0 ? v.length + begin : begin;
3752 return v.slice(begin, begin + length);
3753 }
3754 function where(arr, property, expected) {
3755 var _this = this;
3756 return toArray(arr).filter(function (obj) {
3757 var value = _this.context.getFromScope(obj, String(property).split('.'));
3758 return expected === undefined ? isTruthy(value, _this.context) : value === expected;
3759 });
3760 }
3761 function uniq(arr) {
3762 var u = {};
3763 return (arr || []).filter(function (val) {
3764 if (u.hasOwnProperty(String(val)))
3765 return false;
3766 u[String(val)] = true;
3767 return true;
3768 });
3769 }
3770
3771 var rFormat = /%([-_0^#:]+)?(\d+)?([EO])?(.)/;
3772 var monthNames = [
3773 'January', 'February', 'March', 'April', 'May', 'June', 'July', 'August',
3774 'September', 'October', 'November', 'December'
3775 ];
3776 var dayNames = [
3777 'Sunday', 'Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday'
3778 ];
3779 var monthNamesShort = monthNames.map(abbr);
3780 var dayNamesShort = dayNames.map(abbr);
3781 var suffixes = {
3782 1: 'st',
3783 2: 'nd',
3784 3: 'rd',
3785 'default': 'th'
3786 };
3787 function abbr(str) {
3788 return str.slice(0, 3);
3789 }
3790 // prototype extensions
3791 function daysInMonth(d) {
3792 var feb = isLeapYear(d) ? 29 : 28;
3793 return [31, feb, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31];
3794 }
3795 function getDayOfYear(d) {
3796 var num = 0;
3797 for (var i = 0; i < d.getMonth(); ++i) {
3798 num += daysInMonth(d)[i];
3799 }
3800 return num + d.getDate();
3801 }
3802 function getWeekOfYear(d, startDay) {
3803 // Skip to startDay of this week
3804 var now = getDayOfYear(d) + (startDay - d.getDay());
3805 // Find the first startDay of the year
3806 var jan1 = new Date(d.getFullYear(), 0, 1);
3807 var then = (7 - jan1.getDay() + startDay);
3808 return String(Math.floor((now - then) / 7) + 1);
3809 }
3810 function isLeapYear(d) {
3811 var year = d.getFullYear();
3812 return !!((year & 3) === 0 && (year % 100 || (year % 400 === 0 && year)));
3813 }
3814 function getSuffix(d) {
3815 var str = d.getDate().toString();
3816 var index = parseInt(str.slice(-1));
3817 return suffixes[index] || suffixes['default'];
3818 }
3819 function century(d) {
3820 return parseInt(d.getFullYear().toString().substring(0, 2), 10);
3821 }
3822 // default to 0
3823 var padWidths = {
3824 d: 2,
3825 e: 2,
3826 H: 2,
3827 I: 2,
3828 j: 3,
3829 k: 2,
3830 l: 2,
3831 L: 3,
3832 m: 2,
3833 M: 2,
3834 S: 2,
3835 U: 2,
3836 W: 2
3837 };
3838 // default to '0'
3839 var padChars = {
3840 a: ' ',
3841 A: ' ',
3842 b: ' ',
3843 B: ' ',
3844 c: ' ',
3845 e: ' ',
3846 k: ' ',
3847 l: ' ',
3848 p: ' ',
3849 P: ' '
3850 };
3851 var formatCodes = {
3852 a: function (d) { return dayNamesShort[d.getDay()]; },
3853 A: function (d) { return dayNames[d.getDay()]; },
3854 b: function (d) { return monthNamesShort[d.getMonth()]; },
3855 B: function (d) { return monthNames[d.getMonth()]; },
3856 c: function (d) { return d.toLocaleString(); },
3857 C: function (d) { return century(d); },
3858 d: function (d) { return d.getDate(); },
3859 e: function (d) { return d.getDate(); },
3860 H: function (d) { return d.getHours(); },
3861 I: function (d) { return String(d.getHours() % 12 || 12); },
3862 j: function (d) { return getDayOfYear(d); },
3863 k: function (d) { return d.getHours(); },
3864 l: function (d) { return String(d.getHours() % 12 || 12); },
3865 L: function (d) { return d.getMilliseconds(); },
3866 m: function (d) { return d.getMonth() + 1; },
3867 M: function (d) { return d.getMinutes(); },
3868 N: function (d, opts) {
3869 var width = Number(opts.width) || 9;
3870 var str = String(d.getMilliseconds()).substr(0, width);
3871 return padEnd(str, width, '0');
3872 },
3873 p: function (d) { return (d.getHours() < 12 ? 'AM' : 'PM'); },
3874 P: function (d) { return (d.getHours() < 12 ? 'am' : 'pm'); },
3875 q: function (d) { return getSuffix(d); },
3876 s: function (d) { return Math.round(d.getTime() / 1000); },
3877 S: function (d) { return d.getSeconds(); },
3878 u: function (d) { return d.getDay() || 7; },
3879 U: function (d) { return getWeekOfYear(d, 0); },
3880 w: function (d) { return d.getDay(); },
3881 W: function (d) { return getWeekOfYear(d, 1); },
3882 x: function (d) { return d.toLocaleDateString(); },
3883 X: function (d) { return d.toLocaleTimeString(); },
3884 y: function (d) { return d.getFullYear().toString().substring(2, 4); },
3885 Y: function (d) { return d.getFullYear(); },
3886 z: function (d, opts) {
3887 var nOffset = Math.abs(d.getTimezoneOffset());
3888 var h = Math.floor(nOffset / 60);
3889 var m = nOffset % 60;
3890 return (d.getTimezoneOffset() > 0 ? '-' : '+') +
3891 padStart(h, 2, '0') +
3892 (opts.flags[':'] ? ':' : '') +
3893 padStart(m, 2, '0');
3894 },
3895 't': function () { return '\t'; },
3896 'n': function () { return '\n'; },
3897 '%': function () { return '%'; }
3898 };
3899 formatCodes.h = formatCodes.b;
3900 function strftime (d, formatStr) {
3901 var output = '';
3902 var remaining = formatStr;
3903 var match;
3904 while ((match = rFormat.exec(remaining))) {
3905 output += remaining.slice(0, match.index);
3906 remaining = remaining.slice(match.index + match[0].length);
3907 output += format(d, match);
3908 }
3909 return output + remaining;
3910 }
3911 function format(d, match) {
3912 var e_1, _a;
3913 var _b = __read(match, 5), input = _b[0], _c = _b[1], flagStr = _c === void 0 ? '' : _c, width = _b[2], modifier = _b[3], conversion = _b[4];
3914 var convert = formatCodes[conversion];
3915 if (!convert)
3916 return input;
3917 var flags = {};
3918 try {
3919 for (var flagStr_1 = __values(flagStr), flagStr_1_1 = flagStr_1.next(); !flagStr_1_1.done; flagStr_1_1 = flagStr_1.next()) {
3920 var flag = flagStr_1_1.value;
3921 flags[flag] = true;
3922 }
3923 }
3924 catch (e_1_1) { e_1 = { error: e_1_1 }; }
3925 finally {
3926 try {
3927 if (flagStr_1_1 && !flagStr_1_1.done && (_a = flagStr_1.return)) _a.call(flagStr_1);
3928 }
3929 finally { if (e_1) throw e_1.error; }
3930 }
3931 var ret = String(convert(d, { flags: flags, width: width, modifier: modifier }));
3932 var padChar = padChars[conversion] || '0';
3933 var padWidth = width || padWidths[conversion] || 0;
3934 if (flags['^'])
3935 ret = ret.toUpperCase();
3936 else if (flags['#'])
3937 ret = changeCase(ret);
3938 if (flags['_'])
3939 padChar = ' ';
3940 else if (flags['0'])
3941 padChar = '0';
3942 if (flags['-'])
3943 padWidth = 0;
3944 return padStart(ret, padWidth, padChar);
3945 }
3946
3947 // one minute in milliseconds
3948 var OneMinute = 60000;
3949 var hostTimezoneOffset = new Date().getTimezoneOffset();
3950 var ISO8601_TIMEZONE_PATTERN = /([zZ]|([+-])(\d{2}):(\d{2}))$/;
3951 /**
3952 * A date implementation with timezone info, just like Ruby date
3953 *
3954 * Implementation:
3955 * - create a Date offset by it's timezone difference, avoiding overriding a bunch of methods
3956 * - rewrite getTimezoneOffset() to trick strftime
3957 */
3958 var TimezoneDate = /** @class */ (function () {
3959 function TimezoneDate(init, timezoneOffset) {
3960 if (init instanceof TimezoneDate) {
3961 this.date = init.date;
3962 timezoneOffset = init.timezoneOffset;
3963 }
3964 else {
3965 var diff = (hostTimezoneOffset - timezoneOffset) * OneMinute;
3966 var time = new Date(init).getTime() + diff;
3967 this.date = new Date(time);
3968 }
3969 this.timezoneOffset = timezoneOffset;
3970 }
3971 TimezoneDate.prototype.getTime = function () {
3972 return this.date.getTime();
3973 };
3974 TimezoneDate.prototype.getMilliseconds = function () {
3975 return this.date.getMilliseconds();
3976 };
3977 TimezoneDate.prototype.getSeconds = function () {
3978 return this.date.getSeconds();
3979 };
3980 TimezoneDate.prototype.getMinutes = function () {
3981 return this.date.getMinutes();
3982 };
3983 TimezoneDate.prototype.getHours = function () {
3984 return this.date.getHours();
3985 };
3986 TimezoneDate.prototype.getDay = function () {
3987 return this.date.getDay();
3988 };
3989 TimezoneDate.prototype.getDate = function () {
3990 return this.date.getDate();
3991 };
3992 TimezoneDate.prototype.getMonth = function () {
3993 return this.date.getMonth();
3994 };
3995 TimezoneDate.prototype.getFullYear = function () {
3996 return this.date.getFullYear();
3997 };
3998 TimezoneDate.prototype.toLocaleTimeString = function (locale) {
3999 return this.date.toLocaleTimeString(locale);
4000 };
4001 TimezoneDate.prototype.toLocaleDateString = function (locale) {
4002 return this.date.toLocaleDateString(locale);
4003 };
4004 TimezoneDate.prototype.getTimezoneOffset = function () {
4005 return this.timezoneOffset;
4006 };
4007 /**
4008 * Create a Date object fixed to it's declared Timezone. Both
4009 * - 2021-08-06T02:29:00.000Z and
4010 * - 2021-08-06T02:29:00.000+08:00
4011 * will always be displayed as
4012 * - 2021-08-06 02:29:00
4013 * regardless timezoneOffset in JavaScript realm
4014 *
4015 * The implementation hack:
4016 * Instead of calling `.getMonth()`/`.getUTCMonth()` respect to `preserveTimezones`,
4017 * we create a different Date to trick strftime, it's both simpler and more performant.
4018 * Given that a template is expected to be parsed fewer times than rendered.
4019 */
4020 TimezoneDate.createDateFixedToTimezone = function (dateString) {
4021 var m = dateString.match(ISO8601_TIMEZONE_PATTERN);
4022 // representing a UTC timestamp
4023 if (m && m[1] === 'Z') {
4024 return new TimezoneDate(+new Date(dateString), 0);
4025 }
4026 // has a timezone specified
4027 if (m && m[2] && m[3] && m[4]) {
4028 var _a = __read(m, 5), sign = _a[2], hours = _a[3], minutes = _a[4];
4029 var delta = (sign === '+' ? -1 : 1) * (parseInt(hours, 10) * 60 + parseInt(minutes, 10));
4030 return new TimezoneDate(+new Date(dateString), delta);
4031 }
4032 return new Date(dateString);
4033 };
4034 return TimezoneDate;
4035 }());
4036
4037 function date(v, arg) {
4038 var opts = this.context.opts;
4039 var date;
4040 if (v === 'now' || v === 'today') {
4041 date = new Date();
4042 }
4043 else if (isNumber(v)) {
4044 date = new Date(v * 1000);
4045 }
4046 else if (isString(v)) {
4047 if (/^\d+$/.test(v)) {
4048 date = new Date(+v * 1000);
4049 }
4050 else if (opts.preserveTimezones) {
4051 date = TimezoneDate.createDateFixedToTimezone(v);
4052 }
4053 else {
4054 date = new Date(v);
4055 }
4056 }
4057 else {
4058 date = v;
4059 }
4060 if (!isValidDate(date))
4061 return v;
4062 if (opts.hasOwnProperty('timezoneOffset')) {
4063 date = new TimezoneDate(date, opts.timezoneOffset);
4064 }
4065 return strftime(date, arg);
4066 }
4067 function isValidDate(date) {
4068 return (date instanceof Date || date instanceof TimezoneDate) && !isNaN(date.getTime());
4069 }
4070
4071 function Default(value, defaultValue) {
4072 var args = [];
4073 for (var _i = 2; _i < arguments.length; _i++) {
4074 args[_i - 2] = arguments[_i];
4075 }
4076 if (isArray(value) || isString(value))
4077 return value.length ? value : defaultValue;
4078 value = toValue$1(value);
4079 if (value === false && (new Map(args)).get('allow_false'))
4080 return false;
4081 return isFalsy(value, this.context) ? defaultValue : value;
4082 }
4083 function json(value) {
4084 return JSON.stringify(value);
4085 }
4086
4087 /**
4088 * String related filters
4089 *
4090 * * prefer stringify() to String() since `undefined`, `null` should eval ''
4091 */
4092 function append(v, arg) {
4093 assert(arguments.length === 2, 'append expect 2 arguments');
4094 return stringify(v) + stringify(arg);
4095 }
4096 function prepend(v, arg) {
4097 assert(arguments.length === 2, 'prepend expect 2 arguments');
4098 return stringify(arg) + stringify(v);
4099 }
4100 function lstrip(v) {
4101 return stringify(v).replace(/^\s+/, '');
4102 }
4103 function downcase(v) {
4104 return stringify(v).toLowerCase();
4105 }
4106 function upcase(str) {
4107 return stringify(str).toUpperCase();
4108 }
4109 function remove(v, arg) {
4110 return stringify(v).split(String(arg)).join('');
4111 }
4112 function removeFirst(v, l) {
4113 return stringify(v).replace(String(l), '');
4114 }
4115 function rstrip(str) {
4116 return stringify(str).replace(/\s+$/, '');
4117 }
4118 function split(v, arg) {
4119 return stringify(v).split(String(arg));
4120 }
4121 function strip(v) {
4122 return stringify(v).trim();
4123 }
4124 function stripNewlines(v) {
4125 return stringify(v).replace(/\n/g, '');
4126 }
4127 function capitalize(str) {
4128 str = stringify(str);
4129 return str.charAt(0).toUpperCase() + str.slice(1).toLowerCase();
4130 }
4131 function replace(v, pattern, replacement) {
4132 return stringify(v).split(String(pattern)).join(replacement);
4133 }
4134 function replaceFirst(v, arg1, arg2) {
4135 return stringify(v).replace(String(arg1), arg2);
4136 }
4137 function truncate(v, l, o) {
4138 if (l === void 0) { l = 50; }
4139 if (o === void 0) { o = '...'; }
4140 v = stringify(v);
4141 if (v.length <= l)
4142 return v;
4143 return v.substr(0, l - o.length) + o;
4144 }
4145 function truncatewords(v, l, o) {
4146 if (l === void 0) { l = 15; }
4147 if (o === void 0) { o = '...'; }
4148 var arr = v.split(/\s+/);
4149 var ret = arr.slice(0, l).join(' ');
4150 if (arr.length >= l)
4151 ret += o;
4152 return ret;
4153 }
4154
4155 var builtinFilters = /*#__PURE__*/Object.freeze({
4156 __proto__: null,
4157 escape: escape,
4158 escapeOnce: escapeOnce,
4159 newlineToBr: newlineToBr,
4160 stripHtml: stripHtml,
4161 abs: abs,
4162 atLeast: atLeast,
4163 atMost: atMost,
4164 ceil: ceil,
4165 dividedBy: dividedBy,
4166 floor: floor,
4167 minus: minus,
4168 modulo: modulo,
4169 times: times,
4170 round: round,
4171 plus: plus,
4172 sortNatural: sortNatural,
4173 urlDecode: urlDecode,
4174 urlEncode: urlEncode,
4175 join: join,
4176 last: last,
4177 first: first,
4178 reverse: reverse,
4179 sort: sort,
4180 size: size,
4181 map: map,
4182 compact: compact,
4183 concat: concat,
4184 slice: slice,
4185 where: where,
4186 uniq: uniq,
4187 date: date,
4188 Default: Default,
4189 json: json,
4190 append: append,
4191 prepend: prepend,
4192 lstrip: lstrip,
4193 downcase: downcase,
4194 upcase: upcase,
4195 remove: remove,
4196 removeFirst: removeFirst,
4197 rstrip: rstrip,
4198 split: split,
4199 strip: strip,
4200 stripNewlines: stripNewlines,
4201 capitalize: capitalize,
4202 replace: replace,
4203 replaceFirst: replaceFirst,
4204 truncate: truncate,
4205 truncatewords: truncatewords
4206 });
4207
4208 var TagMap = /** @class */ (function () {
4209 function TagMap() {
4210 this.impls = {};
4211 }
4212 TagMap.prototype.get = function (name) {
4213 var impl = this.impls[name];
4214 assert(impl, function () { return "tag \"".concat(name, "\" not found"); });
4215 return impl;
4216 };
4217 TagMap.prototype.set = function (name, impl) {
4218 this.impls[name] = impl;
4219 };
4220 return TagMap;
4221 }());
4222
4223 var FilterMap = /** @class */ (function () {
4224 function FilterMap(strictFilters, liquid) {
4225 this.strictFilters = strictFilters;
4226 this.liquid = liquid;
4227 this.impls = {};
4228 }
4229 FilterMap.prototype.get = function (name) {
4230 var impl = this.impls[name];
4231 assert(impl || !this.strictFilters, function () { return "undefined filter: ".concat(name); });
4232 return impl;
4233 };
4234 FilterMap.prototype.set = function (name, impl) {
4235 this.impls[name] = impl;
4236 };
4237 FilterMap.prototype.create = function (name, args) {
4238 return new Filter(name, this.get(name), args, this.liquid);
4239 };
4240 return FilterMap;
4241 }());
4242
4243 var version = '9.33.1';
4244 var Liquid = /** @class */ (function () {
4245 function Liquid(opts) {
4246 var _this = this;
4247 if (opts === void 0) { opts = {}; }
4248 this.options = normalize(opts);
4249 this.parser = new Parser(this);
4250 this.renderer = new Render();
4251 this.filters = new FilterMap(this.options.strictFilters, this);
4252 this.tags = new TagMap();
4253 forOwn(tags, function (conf, name) { return _this.registerTag(snakeCase(name), conf); });
4254 forOwn(builtinFilters, function (handler, name) { return _this.registerFilter(snakeCase(name), handler); });
4255 }
4256 Liquid.prototype.parse = function (html, filepath) {
4257 return this.parser.parse(html, filepath);
4258 };
4259 Liquid.prototype._render = function (tpl, scope, renderOptions) {
4260 var ctx = new Context(scope, this.options, renderOptions);
4261 return this.renderer.renderTemplates(tpl, ctx);
4262 };
4263 Liquid.prototype.render = function (tpl, scope, renderOptions) {
4264 return __awaiter(this, void 0, void 0, function () {
4265 return __generator(this, function (_a) {
4266 return [2 /*return*/, toPromise(this._render(tpl, scope, __assign(__assign({}, renderOptions), { sync: false })))];
4267 });
4268 });
4269 };
4270 Liquid.prototype.renderSync = function (tpl, scope, renderOptions) {
4271 return toValue(this._render(tpl, scope, __assign(__assign({}, renderOptions), { sync: true })));
4272 };
4273 Liquid.prototype.renderToNodeStream = function (tpl, scope, renderOptions) {
4274 if (renderOptions === void 0) { renderOptions = {}; }
4275 var ctx = new Context(scope, this.options, renderOptions);
4276 return this.renderer.renderTemplatesToNodeStream(tpl, ctx);
4277 };
4278 Liquid.prototype._parseAndRender = function (html, scope, renderOptions) {
4279 var tpl = this.parse(html);
4280 return this._render(tpl, scope, renderOptions);
4281 };
4282 Liquid.prototype.parseAndRender = function (html, scope, renderOptions) {
4283 return __awaiter(this, void 0, void 0, function () {
4284 return __generator(this, function (_a) {
4285 return [2 /*return*/, toPromise(this._parseAndRender(html, scope, __assign(__assign({}, renderOptions), { sync: false })))];
4286 });
4287 });
4288 };
4289 Liquid.prototype.parseAndRenderSync = function (html, scope, renderOptions) {
4290 return toValue(this._parseAndRender(html, scope, __assign(__assign({}, renderOptions), { sync: true })));
4291 };
4292 Liquid.prototype._parsePartialFile = function (file, sync, currentFile) {
4293 return this.parser.parseFile(file, sync, LookupType.Partials, currentFile);
4294 };
4295 Liquid.prototype._parseLayoutFile = function (file, sync, currentFile) {
4296 return this.parser.parseFile(file, sync, LookupType.Layouts, currentFile);
4297 };
4298 Liquid.prototype.parseFile = function (file) {
4299 return __awaiter(this, void 0, void 0, function () {
4300 return __generator(this, function (_a) {
4301 return [2 /*return*/, toPromise(this.parser.parseFile(file, false))];
4302 });
4303 });
4304 };
4305 Liquid.prototype.parseFileSync = function (file) {
4306 return toValue(this.parser.parseFile(file, true));
4307 };
4308 Liquid.prototype.renderFile = function (file, ctx, renderOptions) {
4309 return __awaiter(this, void 0, void 0, function () {
4310 var templates;
4311 return __generator(this, function (_a) {
4312 switch (_a.label) {
4313 case 0: return [4 /*yield*/, this.parseFile(file)];
4314 case 1:
4315 templates = _a.sent();
4316 return [2 /*return*/, this.render(templates, ctx, renderOptions)];
4317 }
4318 });
4319 });
4320 };
4321 Liquid.prototype.renderFileSync = function (file, ctx, renderOptions) {
4322 var templates = this.parseFileSync(file);
4323 return this.renderSync(templates, ctx, renderOptions);
4324 };
4325 Liquid.prototype.renderFileToNodeStream = function (file, scope, renderOptions) {
4326 return __awaiter(this, void 0, void 0, function () {
4327 var templates;
4328 return __generator(this, function (_a) {
4329 switch (_a.label) {
4330 case 0: return [4 /*yield*/, this.parseFile(file)];
4331 case 1:
4332 templates = _a.sent();
4333 return [2 /*return*/, this.renderToNodeStream(templates, scope, renderOptions)];
4334 }
4335 });
4336 });
4337 };
4338 Liquid.prototype._evalValue = function (str, ctx) {
4339 var value = new Value(str, this);
4340 return value.value(ctx, false);
4341 };
4342 Liquid.prototype.evalValue = function (str, ctx) {
4343 return __awaiter(this, void 0, void 0, function () {
4344 return __generator(this, function (_a) {
4345 return [2 /*return*/, toPromise(this._evalValue(str, ctx))];
4346 });
4347 });
4348 };
4349 Liquid.prototype.evalValueSync = function (str, ctx) {
4350 return toValue(this._evalValue(str, ctx));
4351 };
4352 Liquid.prototype.registerFilter = function (name, filter) {
4353 this.filters.set(name, filter);
4354 };
4355 Liquid.prototype.registerTag = function (name, tag) {
4356 this.tags.set(name, tag);
4357 };
4358 Liquid.prototype.plugin = function (plugin) {
4359 return plugin.call(this, Liquid);
4360 };
4361 Liquid.prototype.express = function () {
4362 var self = this; // eslint-disable-line
4363 var firstCall = true;
4364 return function (filePath, ctx, callback) {
4365 var _a, _b, _c;
4366 if (firstCall) {
4367 firstCall = false;
4368 var dirs = normalizeDirectoryList(this.root);
4369 (_a = self.options.root).unshift.apply(_a, __spreadArray([], __read(dirs), false));
4370 (_b = self.options.layouts).unshift.apply(_b, __spreadArray([], __read(dirs), false));
4371 (_c = self.options.partials).unshift.apply(_c, __spreadArray([], __read(dirs), false));
4372 }
4373 self.renderFile(filePath, ctx).then(function (html) { return callback(null, html); }, callback);
4374 };
4375 };
4376 return Liquid;
4377 }());
4378
4379 exports.AssertionError = AssertionError;
4380 exports.Context = Context;
4381 exports.Drop = Drop;
4382 exports.Expression = Expression;
4383 exports.Hash = Hash;
4384 exports.InternalUndefinedVariableError = InternalUndefinedVariableError;
4385 exports.Liquid = Liquid;
4386 exports.LiquidError = LiquidError;
4387 exports.ParseError = ParseError;
4388 exports.ParseStream = ParseStream;
4389 exports.RenderError = RenderError;
4390 exports.TagToken = TagToken;
4391 exports.Token = Token;
4392 exports.TokenizationError = TokenizationError;
4393 exports.Tokenizer = Tokenizer;
4394 exports.TypeGuards = typeGuards;
4395 exports.UndefinedVariableError = UndefinedVariableError;
4396 exports.Value = Value;
4397 exports.assert = assert;
4398 exports.createTrie = createTrie;
4399 exports.defaultOperators = defaultOperators;
4400 exports.evalQuotedToken = evalQuotedToken;
4401 exports.evalToken = evalToken;
4402 exports.isFalsy = isFalsy;
4403 exports.isTruthy = isTruthy;
4404 exports.toPromise = toPromise;
4405 exports.toThenable = toThenable;
4406 exports.toValue = toValue$1;
4407 exports.version = version;
4408
4409 Object.defineProperty(exports, '__esModule', { value: true });
4410
4411}));
4412//# sourceMappingURL=liquid.browser.umd.js.map