UNPKG

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