UNPKG

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