aboutsummaryrefslogtreecommitdiffstats
path: root/src/lib/liquid.js
diff options
context:
space:
mode:
Diffstat (limited to 'src/lib/liquid.js')
-rw-r--r--src/lib/liquid.js3651
1 files changed, 3651 insertions, 0 deletions
diff --git a/src/lib/liquid.js b/src/lib/liquid.js
new file mode 100644
index 0000000..118b044
--- /dev/null
+++ b/src/lib/liquid.js
@@ -0,0 +1,3651 @@
+/*
+ * liquidjs@9.11.10, https://github.com/harttle/liquidjs
+ * (c) 2016-2020 harttle
+ * Released under the MIT License.
+ */
+(function (global, factory) {
+ typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports) :
+ typeof define === 'function' && define.amd ? define(['exports'], factory) :
+ (global = global || self, factory(global.liquidjs = {}));
+}(this, function (exports) { 'use strict';
+
+ /*! *****************************************************************************
+ Copyright (c) Microsoft Corporation. All rights reserved.
+ Licensed under the Apache License, Version 2.0 (the "License"); you may not use
+ this file except in compliance with the License. You may obtain a copy of the
+ License at http://www.apache.org/licenses/LICENSE-2.0
+
+ THIS CODE IS PROVIDED ON AN *AS IS* BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ KIND, EITHER EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION ANY IMPLIED
+ WARRANTIES OR CONDITIONS OF TITLE, FITNESS FOR A PARTICULAR PURPOSE,
+ MERCHANTABLITY OR NON-INFRINGEMENT.
+
+ See the Apache Version 2.0 License for specific language governing permissions
+ and limitations under the License.
+ ***************************************************************************** */
+ /* global Reflect, Promise */
+
+ var extendStatics = function(d, b) {
+ extendStatics = Object.setPrototypeOf ||
+ ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||
+ function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; };
+ return extendStatics(d, b);
+ };
+
+ function __extends(d, b) {
+ extendStatics(d, b);
+ function __() { this.constructor = d; }
+ d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
+ }
+
+ var __assign = function() {
+ __assign = Object.assign || function __assign(t) {
+ for (var s, i = 1, n = arguments.length; i < n; i++) {
+ s = arguments[i];
+ for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p)) t[p] = s[p];
+ }
+ return t;
+ };
+ return __assign.apply(this, arguments);
+ };
+
+ function __awaiter(thisArg, _arguments, P, generator) {
+ return new (P || (P = Promise))(function (resolve, reject) {
+ function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
+ function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
+ function step(result) { result.done ? resolve(result.value) : new P(function (resolve) { resolve(result.value); }).then(fulfilled, rejected); }
+ step((generator = generator.apply(thisArg, _arguments || [])).next());
+ });
+ }
+
+ function __generator(thisArg, body) {
+ var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g;
+ return g = { next: verb(0), "throw": verb(1), "return": verb(2) }, typeof Symbol === "function" && (g[Symbol.iterator] = function() { return this; }), g;
+ function verb(n) { return function (v) { return step([n, v]); }; }
+ function step(op) {
+ if (f) throw new TypeError("Generator is already executing.");
+ while (_) try {
+ 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;
+ if (y = 0, t) op = [op[0] & 2, t.value];
+ switch (op[0]) {
+ case 0: case 1: t = op; break;
+ case 4: _.label++; return { value: op[1], done: false };
+ case 5: _.label++; y = op[1]; op = [0]; continue;
+ case 7: op = _.ops.pop(); _.trys.pop(); continue;
+ default:
+ if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; }
+ if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; }
+ if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; }
+ if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; }
+ if (t[2]) _.ops.pop();
+ _.trys.pop(); continue;
+ }
+ op = body.call(thisArg, _);
+ } catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; }
+ if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true };
+ }
+ }
+
+ function __values(o) {
+ var m = typeof Symbol === "function" && o[Symbol.iterator], i = 0;
+ if (m) return m.call(o);
+ return {
+ next: function () {
+ if (o && i >= o.length) o = void 0;
+ return { value: o && o[i++], done: !o };
+ }
+ };
+ }
+
+ function __read(o, n) {
+ var m = typeof Symbol === "function" && o[Symbol.iterator];
+ if (!m) return o;
+ var i = m.call(o), r, ar = [], e;
+ try {
+ while ((n === void 0 || n-- > 0) && !(r = i.next()).done) ar.push(r.value);
+ }
+ catch (error) { e = { error: error }; }
+ finally {
+ try {
+ if (r && !r.done && (m = i["return"])) m.call(i);
+ }
+ finally { if (e) throw e.error; }
+ }
+ return ar;
+ }
+
+ function __spread() {
+ for (var ar = [], i = 0; i < arguments.length; i++)
+ ar = ar.concat(__read(arguments[i]));
+ return ar;
+ }
+
+ var Drop = /** @class */ (function () {
+ function Drop() {
+ }
+ Drop.prototype.valueOf = function () {
+ return undefined;
+ };
+ Drop.prototype.liquidMethodMissing = function (key) {
+ return undefined;
+ };
+ return Drop;
+ }());
+
+ var toStr = Object.prototype.toString;
+ var toLowerCase = String.prototype.toLowerCase;
+ /*
+ * Checks if value is classified as a String primitive or object.
+ * @param {any} value The value to check.
+ * @return {Boolean} Returns true if value is a string, else false.
+ */
+ function isString(value) {
+ return toStr.call(value) === '[object String]';
+ }
+ function isFunction(value) {
+ return typeof value === 'function';
+ }
+ function stringify(value) {
+ value = toValue(value);
+ return isNil(value) ? '' : String(value);
+ }
+ function toValue(value) {
+ return value instanceof Drop ? value.valueOf() : value;
+ }
+ function isNumber(value) {
+ return typeof value === 'number';
+ }
+ function toLiquid(value) {
+ if (value && isFunction(value.toLiquid))
+ return toLiquid(value.toLiquid());
+ return value;
+ }
+ function isNil(value) {
+ return value === null || value === undefined;
+ }
+ function isArray(value) {
+ // be compatible with IE 8
+ return toStr.call(value) === '[object Array]';
+ }
+ /*
+ * Iterates over own enumerable string keyed properties of an object and invokes iteratee for each property.
+ * The iteratee is invoked with three arguments: (value, key, object).
+ * Iteratee functions may exit iteration early by explicitly returning false.
+ * @param {Object} object The object to iterate over.
+ * @param {Function} iteratee The function invoked per iteration.
+ * @return {Object} Returns object.
+ */
+ function forOwn(object, iteratee) {
+ object = object || {};
+ for (var k in object) {
+ if (object.hasOwnProperty(k)) {
+ if (iteratee(object[k], k, object) === false)
+ break;
+ }
+ }
+ return object;
+ }
+ function last(arr) {
+ return arr[arr.length - 1];
+ }
+ /*
+ * Checks if value is the language type of Object.
+ * (e.g. arrays, functions, objects, regexes, new Number(0), and new String(''))
+ * @param {any} value The value to check.
+ * @return {Boolean} Returns true if value is an object, else false.
+ */
+ function isObject(value) {
+ var type = typeof value;
+ return value !== null && (type === 'object' || type === 'function');
+ }
+ function range(start, stop, step) {
+ if (step === void 0) { step = 1; }
+ var arr = [];
+ for (var i = start; i < stop; i += step) {
+ arr.push(i);
+ }
+ return arr;
+ }
+ function padStart(str, length, ch) {
+ if (ch === void 0) { ch = ' '; }
+ return pad(str, length, ch, function (str, ch) { return ch + str; });
+ }
+ function padEnd(str, length, ch) {
+ if (ch === void 0) { ch = ' '; }
+ return pad(str, length, ch, function (str, ch) { return str + ch; });
+ }
+ function pad(str, length, ch, add) {
+ str = String(str);
+ var n = length - str.length;
+ while (n-- > 0)
+ str = add(str, ch);
+ return str;
+ }
+ function identify(val) {
+ return val;
+ }
+ function snakeCase(str) {
+ return str.replace(/(\w?)([A-Z])/g, function (_, a, b) { return (a ? a + '_' : '') + b.toLowerCase(); });
+ }
+ function changeCase(str) {
+ var hasLowerCase = __spread(str).some(function (ch) { return ch >= 'a' && ch <= 'z'; });
+ return hasLowerCase ? str.toUpperCase() : str.toLowerCase();
+ }
+ function ellipsis(str, N) {
+ return str.length > N ? str.substr(0, N - 3) + '...' : str;
+ }
+ // compare string in case-insensitive way, undefined values to the tail
+ function caseInsensitiveCompare(a, b) {
+ if (a == null && b == null)
+ return 0;
+ if (a == null)
+ return 1;
+ if (b == null)
+ return -1;
+ a = toLowerCase.call(a);
+ b = toLowerCase.call(b);
+ if (a < b)
+ return -1;
+ if (a > b)
+ return 1;
+ return 0;
+ }
+
+ var Node = /** @class */ (function () {
+ function Node(key, value, next, prev) {
+ this.key = key;
+ this.value = value;
+ this.next = next;
+ this.prev = prev;
+ }
+ return Node;
+ }());
+ var LRU = /** @class */ (function () {
+ function LRU(limit, size) {
+ if (size === void 0) { size = 0; }
+ this.limit = limit;
+ this.size = size;
+ this.cache = {};
+ this.head = new Node('HEAD', null, null, null);
+ this.tail = new Node('TAIL', null, null, null);
+ this.head.next = this.tail;
+ this.tail.prev = this.head;
+ }
+ LRU.prototype.write = function (key, value) {
+ if (this.cache[key]) {
+ this.cache[key].value = value;
+ }
+ else {
+ var node = new Node(key, value, this.head.next, this.head);
+ this.head.next.prev = node;
+ this.head.next = node;
+ this.cache[key] = node;
+ this.size++;
+ this.ensureLimit();
+ }
+ };
+ LRU.prototype.read = function (key) {
+ if (!this.cache[key])
+ return;
+ var value = this.cache[key].value;
+ this.remove(key);
+ this.write(key, value);
+ return value;
+ };
+ LRU.prototype.remove = function (key) {
+ var node = this.cache[key];
+ node.prev.next = node.next;
+ node.next.prev = node.prev;
+ delete this.cache[key];
+ this.size--;
+ };
+ LRU.prototype.clear = function () {
+ this.head.next = this.tail;
+ this.tail.prev = this.head;
+ this.size = 0;
+ this.cache = {};
+ };
+ LRU.prototype.ensureLimit = function () {
+ if (this.size > this.limit)
+ this.remove(this.tail.prev.key);
+ };
+ return LRU;
+ }());
+
+ var defaultOptions = {
+ root: ['.'],
+ cache: undefined,
+ extname: '',
+ dynamicPartials: true,
+ trimTagRight: false,
+ trimTagLeft: false,
+ trimOutputRight: false,
+ trimOutputLeft: false,
+ greedy: true,
+ tagDelimiterLeft: '{%',
+ tagDelimiterRight: '%}',
+ outputDelimiterLeft: '{{',
+ outputDelimiterRight: '}}',
+ strictFilters: false,
+ strictVariables: false,
+ globals: {}
+ };
+ function normalize(options) {
+ options = options || {};
+ if (options.hasOwnProperty('root')) {
+ options.root = normalizeStringArray(options.root);
+ }
+ if (options.hasOwnProperty('cache')) {
+ var cache = void 0;
+ if (typeof options.cache === 'number')
+ cache = options.cache > 0 ? new LRU(options.cache) : undefined;
+ else if (typeof options.cache === 'object')
+ cache = options.cache;
+ else
+ cache = options.cache ? new LRU(1024) : undefined;
+ options.cache = cache;
+ }
+ return options;
+ }
+ function applyDefault(options) {
+ return __assign({}, defaultOptions, options);
+ }
+ function normalizeStringArray(value) {
+ if (isArray(value))
+ return value;
+ if (isString(value))
+ return [value];
+ return [];
+ }
+
+ var Context = /** @class */ (function () {
+ function Context(env, opts, sync) {
+ if (env === void 0) { env = {}; }
+ if (opts === void 0) { opts = defaultOptions; }
+ if (sync === void 0) { sync = false; }
+ this.scopes = [{}];
+ this.registers = {};
+ this.sync = sync;
+ this.opts = opts;
+ this.globals = opts.globals;
+ this.environments = env;
+ }
+ Context.prototype.getRegister = function (key, defaultValue) {
+ if (defaultValue === void 0) { defaultValue = {}; }
+ return (this.registers[key] = this.registers[key] || defaultValue);
+ };
+ Context.prototype.setRegister = function (key, value) {
+ return (this.registers[key] = value);
+ };
+ Context.prototype.saveRegister = function () {
+ var _this = this;
+ var keys = [];
+ for (var _i = 0; _i < arguments.length; _i++) {
+ keys[_i] = arguments[_i];
+ }
+ return keys.map(function (key) { return [key, _this.getRegister(key)]; });
+ };
+ Context.prototype.restoreRegister = function (keyValues) {
+ var _this = this;
+ return keyValues.forEach(function (_a) {
+ var _b = __read(_a, 2), key = _b[0], value = _b[1];
+ return _this.setRegister(key, value);
+ });
+ };
+ Context.prototype.getAll = function () {
+ return __spread([this.globals, this.environments], this.scopes).reduce(function (ctx, val) { return __assign(ctx, val); }, {});
+ };
+ Context.prototype.get = function (paths) {
+ var scope = this.findScope(paths[0]);
+ return this.getFromScope(scope, paths);
+ };
+ Context.prototype.getFromScope = function (scope, paths) {
+ var _this = this;
+ if (typeof paths === 'string')
+ paths = paths.split('.');
+ return paths.reduce(function (scope, path) {
+ scope = readProperty(scope, path);
+ if (isNil(scope) && _this.opts.strictVariables) {
+ throw new TypeError("undefined variable: " + path);
+ }
+ return scope;
+ }, scope);
+ };
+ Context.prototype.push = function (ctx) {
+ return this.scopes.push(ctx);
+ };
+ Context.prototype.pop = function () {
+ return this.scopes.pop();
+ };
+ Context.prototype.bottom = function () {
+ return this.scopes[0];
+ };
+ Context.prototype.findScope = function (key) {
+ for (var i = this.scopes.length - 1; i >= 0; i--) {
+ var candidate = this.scopes[i];
+ if (key in candidate)
+ return candidate;
+ }
+ if (key in this.environments)
+ return this.environments;
+ return this.globals;
+ };
+ return Context;
+ }());
+ function readProperty(obj, key) {
+ if (isNil(obj))
+ return obj;
+ obj = toLiquid(obj);
+ if (obj instanceof Drop) {
+ if (isFunction(obj[key]))
+ return obj[key]();
+ if (obj.hasOwnProperty(key))
+ return obj[key];
+ return obj.liquidMethodMissing(key);
+ }
+ if (key === 'size')
+ return readSize(obj);
+ if (key === 'first')
+ return readFirst(obj);
+ if (key === 'last')
+ return readLast(obj);
+ return obj[key];
+ }
+ function readFirst(obj) {
+ if (isArray(obj))
+ return obj[0];
+ return obj['first'];
+ }
+ function readLast(obj) {
+ if (isArray(obj))
+ return obj[obj.length - 1];
+ return obj['last'];
+ }
+ function readSize(obj) {
+ if (isArray(obj) || isString(obj))
+ return obj.length;
+ return obj['size'];
+ }
+
+ function domResolve(root, path) {
+ var base = document.createElement('base');
+ base.href = root;
+ var head = document.getElementsByTagName('head')[0];
+ head.insertBefore(base, head.firstChild);
+ var a = document.createElement('a');
+ a.href = path;
+ var resolved = a.href;
+ head.removeChild(base);
+ return resolved;
+ }
+ function resolve(root, filepath, ext) {
+ if (root.length && last(root) !== '/')
+ root += '/';
+ var url = domResolve(root, filepath);
+ return url.replace(/^(\w+:\/\/[^/]+)(\/[^?]+)/, function (str, origin, path) {
+ var last = path.split('/').pop();
+ if (/\.\w+$/.test(last))
+ return str;
+ return origin + path + ext;
+ });
+ }
+ function readFile(url) {
+ return __awaiter(this, void 0, void 0, function () {
+ return __generator(this, function (_a) {
+ return [2 /*return*/, new Promise(function (resolve, reject) {
+ var xhr = new XMLHttpRequest();
+ xhr.onload = function () {
+ if (xhr.status >= 200 && xhr.status < 300) {
+ resolve(xhr.responseText);
+ }
+ else {
+ reject(new Error(xhr.statusText));
+ }
+ };
+ xhr.onerror = function () {
+ reject(new Error('An error occurred whilst receiving the response.'));
+ };
+ xhr.open('GET', url);
+ xhr.send();
+ })];
+ });
+ });
+ }
+ function readFileSync(url) {
+ var xhr = new XMLHttpRequest();
+ xhr.open('GET', url, false);
+ xhr.send();
+ if (xhr.status < 200 || xhr.status >= 300) {
+ throw new Error(xhr.statusText);
+ }
+ return xhr.responseText;
+ }
+ function exists(filepath) {
+ return __awaiter(this, void 0, void 0, function () {
+ return __generator(this, function (_a) {
+ return [2 /*return*/, true];
+ });
+ });
+ }
+ function existsSync(filepath) {
+ return true;
+ }
+
+ var fs = /*#__PURE__*/Object.freeze({
+ resolve: resolve,
+ readFile: readFile,
+ readFileSync: readFileSync,
+ exists: exists,
+ existsSync: existsSync
+ });
+
+ var TokenKind;
+ (function (TokenKind) {
+ TokenKind[TokenKind["Number"] = 1] = "Number";
+ TokenKind[TokenKind["Literal"] = 2] = "Literal";
+ TokenKind[TokenKind["Tag"] = 4] = "Tag";
+ TokenKind[TokenKind["Output"] = 8] = "Output";
+ TokenKind[TokenKind["HTML"] = 16] = "HTML";
+ TokenKind[TokenKind["Filter"] = 32] = "Filter";
+ TokenKind[TokenKind["Hash"] = 64] = "Hash";
+ TokenKind[TokenKind["PropertyAccess"] = 128] = "PropertyAccess";
+ TokenKind[TokenKind["Word"] = 256] = "Word";
+ TokenKind[TokenKind["Range"] = 512] = "Range";
+ TokenKind[TokenKind["Quoted"] = 1024] = "Quoted";
+ TokenKind[TokenKind["Operator"] = 2048] = "Operator";
+ TokenKind[TokenKind["Delimited"] = 12] = "Delimited";
+ })(TokenKind || (TokenKind = {}));
+
+ function isDelimitedToken(val) {
+ return !!(getKind(val) & TokenKind.Delimited);
+ }
+ function isOperatorToken(val) {
+ return getKind(val) === TokenKind.Operator;
+ }
+ function isHTMLToken(val) {
+ return getKind(val) === TokenKind.HTML;
+ }
+ function isOutputToken(val) {
+ return getKind(val) === TokenKind.Output;
+ }
+ function isTagToken(val) {
+ return getKind(val) === TokenKind.Tag;
+ }
+ function isQuotedToken(val) {
+ return getKind(val) === TokenKind.Quoted;
+ }
+ function isLiteralToken(val) {
+ return getKind(val) === TokenKind.Literal;
+ }
+ function isNumberToken(val) {
+ return getKind(val) === TokenKind.Number;
+ }
+ function isPropertyAccessToken(val) {
+ return getKind(val) === TokenKind.PropertyAccess;
+ }
+ function isWordToken(val) {
+ return getKind(val) === TokenKind.Word;
+ }
+ function isRangeToken(val) {
+ return getKind(val) === TokenKind.Range;
+ }
+ function getKind(val) {
+ return val ? val.kind : -1;
+ }
+
+ var typeGuards = /*#__PURE__*/Object.freeze({
+ isDelimitedToken: isDelimitedToken,
+ isOperatorToken: isOperatorToken,
+ isHTMLToken: isHTMLToken,
+ isOutputToken: isOutputToken,
+ isTagToken: isTagToken,
+ isQuotedToken: isQuotedToken,
+ isLiteralToken: isLiteralToken,
+ isNumberToken: isNumberToken,
+ isPropertyAccessToken: isPropertyAccessToken,
+ isWordToken: isWordToken,
+ isRangeToken: isRangeToken
+ });
+
+ // **DO NOT CHANGE THIS FILE**
+ //
+ // This file is generated by bin/character-gen.js
+ // bitmask character types to boost performance
+ var TYPES = [0, 0, 0, 0, 0, 0, 0, 0, 0, 20, 4, 4, 4, 20, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 20, 2, 8, 0, 0, 0, 0, 8, 0, 0, 0, 64, 0, 65, 0, 0, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 0, 0, 2, 2, 2, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0];
+ var VARIABLE = 1;
+ var BLANK = 4;
+ var QUOTE = 8;
+ var INLINE_BLANK = 16;
+ var NUMBER = 32;
+ var SIGN = 64;
+ TYPES[160] = TYPES[5760] = TYPES[6158] = TYPES[8192] = TYPES[8193] = TYPES[8194] = TYPES[8195] = TYPES[8196] = TYPES[8197] = TYPES[8198] = TYPES[8199] = TYPES[8200] = TYPES[8201] = TYPES[8202] = TYPES[8232] = TYPES[8233] = TYPES[8239] = TYPES[8287] = TYPES[12288] = BLANK;
+
+ function whiteSpaceCtrl(tokens, options) {
+ options = __assign({ greedy: true }, options);
+ var inRaw = false;
+ for (var i = 0; i < tokens.length; i++) {
+ var token = tokens[i];
+ if (!isDelimitedToken(token))
+ continue;
+ if (!inRaw && token.trimLeft) {
+ trimLeft(tokens[i - 1], options.greedy);
+ }
+ if (isTagToken(token)) {
+ if (token.name === 'raw')
+ inRaw = true;
+ else if (token.name === 'endraw')
+ inRaw = false;
+ }
+ if (!inRaw && token.trimRight) {
+ trimRight(tokens[i + 1], options.greedy);
+ }
+ }
+ }
+ function trimLeft(token, greedy) {
+ if (!token || !isHTMLToken(token))
+ return;
+ var mask = greedy ? BLANK : INLINE_BLANK;
+ while (TYPES[token.input.charCodeAt(token.end - 1 - token.trimRight)] & mask)
+ token.trimRight++;
+ }
+ function trimRight(token, greedy) {
+ if (!token || !isHTMLToken(token))
+ return;
+ var mask = greedy ? BLANK : INLINE_BLANK;
+ while (TYPES[token.input.charCodeAt(token.begin + token.trimLeft)] & mask)
+ token.trimLeft++;
+ if (token.input.charAt(token.begin + token.trimLeft) === '\n')
+ token.trimLeft++;
+ }
+
+ var Token = /** @class */ (function () {
+ function Token(kind, input, begin, end, file) {
+ this.kind = kind;
+ this.input = input;
+ this.begin = begin;
+ this.end = end;
+ this.file = file;
+ }
+ Token.prototype.getText = function () {
+ return this.input.slice(this.begin, this.end);
+ };
+ Token.prototype.getPosition = function () {
+ var _a = __read([1, 1], 2), row = _a[0], col = _a[1];
+ for (var i = 0; i < this.begin; i++) {
+ if (this.input[i] === '\n') {
+ row++;
+ col = 1;
+ }
+ else
+ col++;
+ }
+ return [row, col];
+ };
+ Token.prototype.size = function () {
+ return this.end - this.begin;
+ };
+ return Token;
+ }());
+
+ var NumberToken = /** @class */ (function (_super) {
+ __extends(NumberToken, _super);
+ function NumberToken(whole, decimal) {
+ var _this = _super.call(this, TokenKind.Number, whole.input, whole.begin, decimal ? decimal.end : whole.end, whole.file) || this;
+ _this.whole = whole;
+ _this.decimal = decimal;
+ return _this;
+ }
+ return NumberToken;
+ }(Token));
+
+ // a word can be an identifier, a number, a keyword or a single-word-literal
+ var WordToken = /** @class */ (function (_super) {
+ __extends(WordToken, _super);
+ function WordToken(input, begin, end, file) {
+ var _this = _super.call(this, TokenKind.Word, input, begin, end, file) || this;
+ _this.input = input;
+ _this.begin = begin;
+ _this.end = end;
+ _this.file = file;
+ _this.content = _this.getText();
+ return _this;
+ }
+ WordToken.prototype.isNumber = function (allowSign) {
+ if (allowSign === void 0) { allowSign = false; }
+ var begin = allowSign && TYPES[this.input.charCodeAt(this.begin)] & SIGN
+ ? this.begin + 1
+ : this.begin;
+ for (var i = begin; i < this.end; i++) {
+ if (!(TYPES[this.input.charCodeAt(i)] & NUMBER))
+ return false;
+ }
+ return true;
+ };
+ return WordToken;
+ }(Token));
+
+ var EmptyDrop = /** @class */ (function (_super) {
+ __extends(EmptyDrop, _super);
+ function EmptyDrop() {
+ return _super !== null && _super.apply(this, arguments) || this;
+ }
+ EmptyDrop.prototype.equals = function (value) {
+ if (isString(value) || isArray(value))
+ return value.length === 0;
+ if (isObject(value))
+ return Object.keys(value).length === 0;
+ return false;
+ };
+ EmptyDrop.prototype.gt = function () {
+ return false;
+ };
+ EmptyDrop.prototype.geq = function () {
+ return false;
+ };
+ EmptyDrop.prototype.lt = function () {
+ return false;
+ };
+ EmptyDrop.prototype.leq = function () {
+ return false;
+ };
+ EmptyDrop.prototype.valueOf = function () {
+ return '';
+ };
+ return EmptyDrop;
+ }(Drop));
+
+ var BlankDrop = /** @class */ (function (_super) {
+ __extends(BlankDrop, _super);
+ function BlankDrop() {
+ return _super !== null && _super.apply(this, arguments) || this;
+ }
+ BlankDrop.prototype.equals = function (value) {
+ if (value === false)
+ return true;
+ if (isNil(toValue(value)))
+ return true;
+ if (isString(value))
+ return /^\s*$/.test(value);
+ return _super.prototype.equals.call(this, value);
+ };
+ return BlankDrop;
+ }(EmptyDrop));
+
+ var NullDrop = /** @class */ (function (_super) {
+ __extends(NullDrop, _super);
+ function NullDrop() {
+ return _super !== null && _super.apply(this, arguments) || this;
+ }
+ NullDrop.prototype.equals = function (value) {
+ return isNil(toValue(value)) || value instanceof BlankDrop;
+ };
+ NullDrop.prototype.gt = function () {
+ return false;
+ };
+ NullDrop.prototype.geq = function () {
+ return false;
+ };
+ NullDrop.prototype.lt = function () {
+ return false;
+ };
+ NullDrop.prototype.leq = function () {
+ return false;
+ };
+ NullDrop.prototype.valueOf = function () {
+ return null;
+ };
+ return NullDrop;
+ }(Drop));
+
+ var literalValues = {
+ 'true': true,
+ 'false': false,
+ 'nil': new NullDrop(),
+ 'null': new NullDrop(),
+ 'empty': new EmptyDrop(),
+ 'blank': new BlankDrop()
+ };
+
+ var LiteralToken = /** @class */ (function (_super) {
+ __extends(LiteralToken, _super);
+ function LiteralToken(input, begin, end, file) {
+ var _this = _super.call(this, TokenKind.Literal, input, begin, end, file) || this;
+ _this.input = input;
+ _this.begin = begin;
+ _this.end = end;
+ _this.file = file;
+ _this.literal = _this.getText();
+ return _this;
+ }
+ return LiteralToken;
+ }(Token));
+
+ var precedence = {
+ '==': 1,
+ '!=': 1,
+ '>': 1,
+ '<': 1,
+ '>=': 1,
+ '<=': 1,
+ 'contains': 1,
+ 'and': 0,
+ 'or': 0
+ };
+ var OperatorToken = /** @class */ (function (_super) {
+ __extends(OperatorToken, _super);
+ function OperatorToken(input, begin, end, file) {
+ var _this = _super.call(this, TokenKind.Operator, input, begin, end, file) || this;
+ _this.input = input;
+ _this.begin = begin;
+ _this.end = end;
+ _this.file = file;
+ _this.operator = _this.getText();
+ return _this;
+ }
+ OperatorToken.prototype.getPrecedence = function () {
+ return precedence[this.getText()];
+ };
+ return OperatorToken;
+ }(Token));
+
+ var PropertyAccessToken = /** @class */ (function (_super) {
+ __extends(PropertyAccessToken, _super);
+ function PropertyAccessToken(variable, props, end) {
+ var _this = _super.call(this, TokenKind.PropertyAccess, variable.input, variable.begin, end, variable.file) || this;
+ _this.variable = variable;
+ _this.props = props;
+ return _this;
+ }
+ return PropertyAccessToken;
+ }(Token));
+
+ var LiquidError = /** @class */ (function (_super) {
+ __extends(LiquidError, _super);
+ function LiquidError(err, token) {
+ var _this = _super.call(this, err.message) || this;
+ _this.originalError = err;
+ _this.token = token;
+ return _this;
+ }
+ LiquidError.prototype.update = function () {
+ var err = this.originalError;
+ var context = mkContext(this.token);
+ this.message = mkMessage(err.message, this.token);
+ this.stack = this.message + '\n' + context +
+ '\n' + this.stack + '\nFrom ' + err.stack;
+ };
+ return LiquidError;
+ }(Error));
+ var TokenizationError = /** @class */ (function (_super) {
+ __extends(TokenizationError, _super);
+ function TokenizationError(message, token) {
+ var _this = _super.call(this, new Error(message), token) || this;
+ _this.name = 'TokenizationError';
+ _super.prototype.update.call(_this);
+ return _this;
+ }
+ return TokenizationError;
+ }(LiquidError));
+ var ParseError = /** @class */ (function (_super) {
+ __extends(ParseError, _super);
+ function ParseError(err, token) {
+ var _this = _super.call(this, err, token) || this;
+ _this.name = 'ParseError';
+ _this.message = err.message;
+ _super.prototype.update.call(_this);
+ return _this;
+ }
+ return ParseError;
+ }(LiquidError));
+ var RenderError = /** @class */ (function (_super) {
+ __extends(RenderError, _super);
+ function RenderError(err, tpl) {
+ var _this = _super.call(this, err, tpl.token) || this;
+ _this.name = 'RenderError';
+ _this.message = err.message;
+ _super.prototype.update.call(_this);
+ return _this;
+ }
+ RenderError.is = function (obj) {
+ return obj instanceof RenderError;
+ };
+ return RenderError;
+ }(LiquidError));
+ var AssertionError = /** @class */ (function (_super) {
+ __extends(AssertionError, _super);
+ function AssertionError(message) {
+ var _this = _super.call(this, message) || this;
+ _this.name = 'AssertionError';
+ _this.message = message + '';
+ return _this;
+ }
+ return AssertionError;
+ }(Error));
+ function mkContext(token) {
+ var _a = __read(token.getPosition(), 1), line = _a[0];
+ var lines = token.input.split('\n');
+ var begin = Math.max(line - 2, 1);
+ var end = Math.min(line + 3, lines.length);
+ var context = range(begin, end + 1)
+ .map(function (lineNumber) {
+ var indicator = (lineNumber === line) ? '>> ' : ' ';
+ var num = padStart(String(lineNumber), String(end).length);
+ var text = lines[lineNumber - 1];
+ return "" + indicator + num + "| " + text;
+ })
+ .join('\n');
+ return context;
+ }
+ function mkMessage(msg, token) {
+ if (token.file)
+ msg += ", file:" + token.file;
+ var _a = __read(token.getPosition(), 2), line = _a[0], col = _a[1];
+ msg += ", line:" + line + ", col:" + col;
+ return msg;
+ }
+
+ function assert(predicate, message) {
+ if (!predicate) {
+ var msg = message ? message() : "expect " + predicate + " to be true";
+ throw new AssertionError(msg);
+ }
+ }
+
+ var FilterToken = /** @class */ (function (_super) {
+ __extends(FilterToken, _super);
+ function FilterToken(name, args, input, begin, end, file) {
+ var _this = _super.call(this, TokenKind.Filter, input, begin, end, file) || this;
+ _this.name = name;
+ _this.args = args;
+ return _this;
+ }
+ return FilterToken;
+ }(Token));
+
+ var HashToken = /** @class */ (function (_super) {
+ __extends(HashToken, _super);
+ function HashToken(input, begin, end, name, value, file) {
+ var _this = _super.call(this, TokenKind.Hash, input, begin, end, file) || this;
+ _this.input = input;
+ _this.begin = begin;
+ _this.end = end;
+ _this.name = name;
+ _this.value = value;
+ _this.file = file;
+ return _this;
+ }
+ return HashToken;
+ }(Token));
+
+ var QuotedToken = /** @class */ (function (_super) {
+ __extends(QuotedToken, _super);
+ function QuotedToken(input, begin, end, file) {
+ var _this = _super.call(this, TokenKind.Quoted, input, begin, end, file) || this;
+ _this.input = input;
+ _this.begin = begin;
+ _this.end = end;
+ _this.file = file;
+ return _this;
+ }
+ return QuotedToken;
+ }(Token));
+
+ var HTMLToken = /** @class */ (function (_super) {
+ __extends(HTMLToken, _super);
+ function HTMLToken(input, begin, end, file) {
+ var _this = _super.call(this, TokenKind.HTML, input, begin, end, file) || this;
+ _this.input = input;
+ _this.begin = begin;
+ _this.end = end;
+ _this.file = file;
+ _this.trimLeft = 0;
+ _this.trimRight = 0;
+ return _this;
+ }
+ HTMLToken.prototype.getContent = function () {
+ return this.input.slice(this.begin + this.trimLeft, this.end - this.trimRight);
+ };
+ return HTMLToken;
+ }(Token));
+
+ var DelimitedToken = /** @class */ (function (_super) {
+ __extends(DelimitedToken, _super);
+ function DelimitedToken(kind, content, input, begin, end, trimLeft, trimRight, file) {
+ var _this = _super.call(this, kind, input, begin, end, file) || this;
+ _this.trimLeft = false;
+ _this.trimRight = false;
+ _this.content = _this.getText();
+ var tl = content[0] === '-';
+ var tr = last(content) === '-';
+ _this.content = content
+ .slice(tl ? 1 : 0, tr ? -1 : content.length)
+ .trim();
+ _this.trimLeft = tl || trimLeft;
+ _this.trimRight = tr || trimRight;
+ return _this;
+ }
+ return DelimitedToken;
+ }(Token));
+
+ var TagToken = /** @class */ (function (_super) {
+ __extends(TagToken, _super);
+ function TagToken(input, begin, end, options, file) {
+ var _this = this;
+ var trimTagLeft = options.trimTagLeft, trimTagRight = options.trimTagRight, tagDelimiterLeft = options.tagDelimiterLeft, tagDelimiterRight = options.tagDelimiterRight;
+ var value = input.slice(begin + tagDelimiterLeft.length, end - tagDelimiterRight.length);
+ _this = _super.call(this, TokenKind.Tag, value, input, begin, end, trimTagLeft, trimTagRight, file) || this;
+ var nameEnd = 0;
+ while (TYPES[_this.content.charCodeAt(nameEnd)] & VARIABLE)
+ nameEnd++;
+ _this.name = _this.content.slice(0, nameEnd);
+ if (!_this.name)
+ throw new TokenizationError("illegal tag syntax", _this);
+ var argsBegin = nameEnd;
+ while (TYPES[_this.content.charCodeAt(argsBegin)] & BLANK)
+ argsBegin++;
+ _this.args = _this.content.slice(argsBegin);
+ return _this;
+ }
+ return TagToken;
+ }(DelimitedToken));
+
+ var RangeToken = /** @class */ (function (_super) {
+ __extends(RangeToken, _super);
+ function RangeToken(input, begin, end, lhs, rhs, file) {
+ var _this = _super.call(this, TokenKind.Range, input, begin, end, file) || this;
+ _this.input = input;
+ _this.begin = begin;
+ _this.end = end;
+ _this.lhs = lhs;
+ _this.rhs = rhs;
+ _this.file = file;
+ return _this;
+ }
+ return RangeToken;
+ }(Token));
+
+ var OutputToken = /** @class */ (function (_super) {
+ __extends(OutputToken, _super);
+ function OutputToken(input, begin, end, options, file) {
+ var _this = this;
+ var trimOutputLeft = options.trimOutputLeft, trimOutputRight = options.trimOutputRight, outputDelimiterLeft = options.outputDelimiterLeft, outputDelimiterRight = options.outputDelimiterRight;
+ var value = input.slice(begin + outputDelimiterLeft.length, end - outputDelimiterRight.length);
+ _this = _super.call(this, TokenKind.Output, value, input, begin, end, trimOutputLeft, trimOutputRight, file) || this;
+ return _this;
+ }
+ return OutputToken;
+ }(DelimitedToken));
+
+ var trie = {
+ a: { n: { d: { end: true, needBoundary: true } } },
+ o: { r: { end: true, needBoundary: true } },
+ c: { o: { n: { t: { a: { i: { n: { s: { end: true, needBoundary: true } } } } } } } },
+ '=': { '=': { end: true } },
+ '!': { '=': { end: true } },
+ '>': { end: true, '=': { end: true } },
+ '<': { end: true, '=': { end: true } }
+ };
+ function matchOperator(str, begin, end) {
+ if (end === void 0) { end = str.length; }
+ var node = trie;
+ var i = begin;
+ var info;
+ while (node[str[i]] && i < end) {
+ node = node[str[i++]];
+ if (node['end'])
+ info = node;
+ }
+ if (!info)
+ return -1;
+ if (info['needBoundary'] && str.charCodeAt(i) & VARIABLE)
+ return -1;
+ return i;
+ }
+
+ var Tokenizer = /** @class */ (function () {
+ function Tokenizer(input, file) {
+ if (file === void 0) { file = ''; }
+ this.input = input;
+ this.file = file;
+ this.p = 0;
+ this.N = input.length;
+ }
+ Tokenizer.prototype.readExpression = function () {
+ var operand, operator, operand_1;
+ return __generator(this, function (_a) {
+ switch (_a.label) {
+ case 0:
+ operand = this.readValue();
+ if (!operand)
+ return [2 /*return*/];
+ return [4 /*yield*/, operand];
+ case 1:
+ _a.sent();
+ _a.label = 2;
+ case 2:
+ if (!(this.p < this.N)) return [3 /*break*/, 5];
+ operator = this.readOperator();
+ if (!operator)
+ return [2 /*return*/];
+ operand_1 = this.readValue();
+ if (!operand_1)
+ return [2 /*return*/];
+ return [4 /*yield*/, operator];
+ case 3:
+ _a.sent();
+ return [4 /*yield*/, operand_1];
+ case 4:
+ _a.sent();
+ return [3 /*break*/, 2];
+ case 5: return [2 /*return*/];
+ }
+ });
+ };
+ Tokenizer.prototype.readOperator = function () {
+ this.skipBlank();
+ var end = matchOperator(this.input, this.p, this.p + 8);
+ if (end === -1)
+ return;
+ return new OperatorToken(this.input, this.p, (this.p = end), this.file);
+ };
+ Tokenizer.prototype.readFilters = function () {
+ var filters = [];
+ while (true) {
+ var filter = this.readFilter();
+ if (!filter)
+ return filters;
+ filters.push(filter);
+ }
+ };
+ Tokenizer.prototype.readFilter = function () {
+ var _this = this;
+ this.skipBlank();
+ if (this.end())
+ return null;
+ assert(this.peek() === '|', function () { return "unexpected token at " + _this.snapshot(); });
+ this.p++;
+ var begin = this.p;
+ var name = this.readWord();
+ if (!name.size())
+ return null;
+ var args = [];
+ this.skipBlank();
+ if (this.peek() === ':') {
+ do {
+ ++this.p;
+ var arg = this.readFilterArg();
+ arg && args.push(arg);
+ while (this.p < this.N && this.peek() !== ',' && this.peek() !== '|')
+ ++this.p;
+ } while (this.peek() === ',');
+ }
+ return new FilterToken(name.getText(), args, this.input, begin, this.p, this.file);
+ };
+ Tokenizer.prototype.readFilterArg = function () {
+ var key = this.readValue();
+ if (!key)
+ return;
+ this.skipBlank();
+ if (this.peek() !== ':')
+ return key;
+ ++this.p;
+ var value = this.readValue();
+ return [key.getText(), value];
+ };
+ Tokenizer.prototype.readTopLevelTokens = function (options) {
+ if (options === void 0) { options = defaultOptions; }
+ var tokens = [];
+ while (this.p < this.N) {
+ var token = this.readTopLevelToken(options);
+ tokens.push(token);
+ }
+ whiteSpaceCtrl(tokens, options);
+ return tokens;
+ };
+ Tokenizer.prototype.readTopLevelToken = function (options) {
+ var tagDelimiterLeft = options.tagDelimiterLeft, outputDelimiterLeft = options.outputDelimiterLeft;
+ if (this.matchWord(tagDelimiterLeft))
+ return this.readTagToken(options);
+ if (this.matchWord(outputDelimiterLeft))
+ return this.readOutputToken(options);
+ return this.readHTMLToken(options);
+ };
+ Tokenizer.prototype.readHTMLToken = function (options) {
+ var begin = this.p;
+ while (this.p < this.N) {
+ var tagDelimiterLeft = options.tagDelimiterLeft, outputDelimiterLeft = options.outputDelimiterLeft;
+ if (this.matchWord(tagDelimiterLeft))
+ break;
+ if (this.matchWord(outputDelimiterLeft))
+ break;
+ ++this.p;
+ }
+ return new HTMLToken(this.input, begin, this.p, this.file);
+ };
+ Tokenizer.prototype.readTagToken = function (options) {
+ var _a = this, file = _a.file, input = _a.input;
+ var tagDelimiterRight = options.tagDelimiterRight;
+ var begin = this.p;
+ if (this.readTo(tagDelimiterRight) === -1) {
+ this.mkError("tag " + this.snapshot(begin) + " not closed", begin);
+ }
+ return new TagToken(input, begin, this.p, options, file);
+ };
+ Tokenizer.prototype.readOutputToken = function (options) {
+ var _a = this, file = _a.file, input = _a.input;
+ var outputDelimiterRight = options.outputDelimiterRight;
+ var begin = this.p;
+ if (this.readTo(outputDelimiterRight) === -1) {
+ this.mkError("output " + this.snapshot(begin) + " not closed", begin);
+ }
+ return new OutputToken(input, begin, this.p, options, file);
+ };
+ Tokenizer.prototype.mkError = function (msg, begin) {
+ throw new TokenizationError(msg, new WordToken(this.input, begin, this.N, this.file));
+ };
+ Tokenizer.prototype.snapshot = function (begin) {
+ if (begin === void 0) { begin = this.p; }
+ return JSON.stringify(ellipsis(this.input.slice(begin), 16));
+ };
+ Tokenizer.prototype.readWord = function () {
+ this.skipBlank();
+ var begin = this.p;
+ while (this.peekType() & VARIABLE)
+ ++this.p;
+ return new WordToken(this.input, begin, this.p, this.file);
+ };
+ Tokenizer.prototype.readHashes = function () {
+ var hashes = [];
+ while (true) {
+ var hash = this.readHash();
+ if (!hash)
+ return hashes;
+ hashes.push(hash);
+ }
+ };
+ Tokenizer.prototype.readHash = function () {
+ this.skipBlank();
+ if (this.peek() === ',')
+ ++this.p;
+ var begin = this.p;
+ var name = this.readWord();
+ if (!name.size())
+ return;
+ var value;
+ this.skipBlank();
+ if (this.peek() === ':') {
+ ++this.p;
+ value = this.readValue();
+ }
+ return new HashToken(this.input, begin, this.p, name, value, this.file);
+ };
+ Tokenizer.prototype.remaining = function () {
+ return this.input.slice(this.p);
+ };
+ Tokenizer.prototype.advance = function (i) {
+ if (i === void 0) { i = 1; }
+ this.p += i;
+ };
+ Tokenizer.prototype.end = function () {
+ return this.p >= this.N;
+ };
+ Tokenizer.prototype.readTo = function (end) {
+ while (this.p < this.N) {
+ ++this.p;
+ if (this.reverseMatchWord(end))
+ return this.p;
+ }
+ return -1;
+ };
+ Tokenizer.prototype.readValue = function () {
+ var value = this.readQuoted() || this.readRange();
+ if (value)
+ return value;
+ var variable = this.readWord();
+ if (!variable.size())
+ return;
+ var isNumber = variable.isNumber(true);
+ var props = [];
+ while (true) {
+ if (this.peek() === '[') {
+ isNumber = false;
+ this.p++;
+ var prop = this.readValue() || new WordToken(this.input, this.p, this.p, this.file);
+ this.readTo(']');
+ props.push(prop);
+ }
+ else if (this.peek() === '.' && this.peek(1) !== '.') { // skip range syntax
+ this.p++;
+ var prop = this.readWord();
+ if (!prop.size())
+ break;
+ if (!prop.isNumber())
+ isNumber = false;
+ props.push(prop);
+ }
+ else
+ break;
+ }
+ if (!props.length && literalValues.hasOwnProperty(variable.content)) {
+ return new LiteralToken(this.input, variable.begin, variable.end, this.file);
+ }
+ if (isNumber)
+ return new NumberToken(variable, props[0]);
+ return new PropertyAccessToken(variable, props, this.p);
+ };
+ Tokenizer.prototype.readRange = function () {
+ this.skipBlank();
+ var begin = this.p;
+ if (this.peek() !== '(')
+ return;
+ ++this.p;
+ var lhs = this.readValueOrThrow();
+ this.p += 2;
+ var rhs = this.readValueOrThrow();
+ ++this.p;
+ return new RangeToken(this.input, begin, this.p, lhs, rhs, this.file);
+ };
+ Tokenizer.prototype.readValueOrThrow = function () {
+ var _this = this;
+ var value = this.readValue();
+ assert(value, function () { return "unexpected token " + _this.snapshot() + ", value expected"; });
+ return value;
+ };
+ Tokenizer.prototype.readQuoted = function () {
+ this.skipBlank();
+ var begin = this.p;
+ if (!(this.peekType() & QUOTE))
+ return;
+ ++this.p;
+ var escaped = false;
+ while (this.p < this.N) {
+ ++this.p;
+ if (this.input[this.p - 1] === this.input[begin] && !escaped)
+ break;
+ if (escaped)
+ escaped = false;
+ else if (this.input[this.p - 1] === '\\')
+ escaped = true;
+ }
+ return new QuotedToken(this.input, begin, this.p, this.file);
+ };
+ Tokenizer.prototype.readFileName = function () {
+ var begin = this.p;
+ while (!(this.peekType() & BLANK) && this.peek() !== ',' && this.p < this.N)
+ this.p++;
+ return new WordToken(this.input, begin, this.p, this.file);
+ };
+ Tokenizer.prototype.matchWord = function (word) {
+ for (var i = 0; i < word.length; i++) {
+ if (word[i] !== this.input[this.p + i])
+ return false;
+ }
+ return true;
+ };
+ Tokenizer.prototype.reverseMatchWord = function (word) {
+ for (var i = 0; i < word.length; i++) {
+ if (word[word.length - 1 - i] !== this.input[this.p - 1 - i])
+ return false;
+ }
+ return true;
+ };
+ Tokenizer.prototype.peekType = function (n) {
+ if (n === void 0) { n = 0; }
+ return TYPES[this.input.charCodeAt(this.p + n)];
+ };
+ Tokenizer.prototype.peek = function (n) {
+ if (n === void 0) { n = 0; }
+ return this.input[this.p + n];
+ };
+ Tokenizer.prototype.skipBlank = function () {
+ while (this.peekType() & BLANK)
+ ++this.p;
+ };
+ return Tokenizer;
+ }());
+
+ var Emitter = /** @class */ (function () {
+ function Emitter() {
+ this.html = '';
+ this.break = false;
+ this.continue = false;
+ }
+ Emitter.prototype.write = function (html) {
+ this.html += html;
+ };
+ return Emitter;
+ }());
+
+ var Render = /** @class */ (function () {
+ function Render() {
+ }
+ Render.prototype.renderTemplates = function (templates, ctx, emitter) {
+ var templates_1, templates_1_1, tpl, html, e_1, err, e_2_1;
+ var e_2, _a;
+ if (emitter === void 0) { emitter = new Emitter(); }
+ return __generator(this, function (_b) {
+ switch (_b.label) {
+ case 0:
+ _b.trys.push([0, 7, 8, 9]);
+ templates_1 = __values(templates), templates_1_1 = templates_1.next();
+ _b.label = 1;
+ case 1:
+ if (!!templates_1_1.done) return [3 /*break*/, 6];
+ tpl = templates_1_1.value;
+ _b.label = 2;
+ case 2:
+ _b.trys.push([2, 4, , 5]);
+ return [4 /*yield*/, tpl.render(ctx, emitter)];
+ case 3:
+ html = _b.sent();
+ html && emitter.write(html);
+ if (emitter.break || emitter.continue)
+ return [3 /*break*/, 6];
+ return [3 /*break*/, 5];
+ case 4:
+ e_1 = _b.sent();
+ err = RenderError.is(e_1) ? e_1 : new RenderError(e_1, tpl);
+ throw err;
+ case 5:
+ templates_1_1 = templates_1.next();
+ return [3 /*break*/, 1];
+ case 6: return [3 /*break*/, 9];
+ case 7:
+ e_2_1 = _b.sent();
+ e_2 = { error: e_2_1 };
+ return [3 /*break*/, 9];
+ case 8:
+ try {
+ if (templates_1_1 && !templates_1_1.done && (_a = templates_1.return)) _a.call(templates_1);
+ }
+ finally { if (e_2) throw e_2.error; }
+ return [7 /*endfinally*/];
+ case 9: return [2 /*return*/, emitter.html];
+ }
+ });
+ };
+ return Render;
+ }());
+
+ var ParseStream = /** @class */ (function () {
+ function ParseStream(tokens, parseToken) {
+ this.handlers = {};
+ this.stopRequested = false;
+ this.tokens = tokens;
+ this.parseToken = parseToken;
+ }
+ ParseStream.prototype.on = function (name, cb) {
+ this.handlers[name] = cb;
+ return this;
+ };
+ ParseStream.prototype.trigger = function (event, arg) {
+ var h = this.handlers[event];
+ return h ? (h(arg), true) : false;
+ };
+ ParseStream.prototype.start = function () {
+ this.trigger('start');
+ var token;
+ while (!this.stopRequested && (token = this.tokens.shift())) {
+ if (this.trigger('token', token))
+ continue;
+ if (isTagToken(token) && this.trigger("tag:" + token.name, token)) {
+ continue;
+ }
+ var template = this.parseToken(token, this.tokens);
+ this.trigger('template', template);
+ }
+ if (!this.stopRequested)
+ this.trigger('end');
+ return this;
+ };
+ ParseStream.prototype.stop = function () {
+ this.stopRequested = true;
+ return this;
+ };
+ return ParseStream;
+ }());
+
+ var TemplateImpl = /** @class */ (function () {
+ function TemplateImpl(token) {
+ this.token = token;
+ }
+ return TemplateImpl;
+ }());
+
+ var rHex = /[\da-fA-F]/;
+ var rOct = /[0-7]/;
+ var escapeChar = {
+ b: '\b',
+ f: '\f',
+ n: '\n',
+ r: '\r',
+ t: '\t',
+ v: '\x0B'
+ };
+ function hexVal(c) {
+ var code = c.charCodeAt(0);
+ if (code >= 97)
+ return code - 87;
+ if (code >= 65)
+ return code - 55;
+ return code - 48;
+ }
+ function parseStringLiteral(str) {
+ var ret = '';
+ for (var i = 1; i < str.length - 1; i++) {
+ if (str[i] !== '\\') {
+ ret += str[i];
+ continue;
+ }
+ if (escapeChar[str[i + 1]] !== undefined) {
+ ret += escapeChar[str[++i]];
+ }
+ else if (str[i + 1] === 'u') {
+ var val = 0;
+ var j = i + 2;
+ while (j <= i + 5 && rHex.test(str[j])) {
+ val = val * 16 + hexVal(str[j++]);
+ }
+ i = j - 1;
+ ret += String.fromCharCode(val);
+ }
+ else if (!rOct.test(str[i + 1])) {
+ ret += str[++i];
+ }
+ else {
+ var j = i + 1;
+ var val = 0;
+ while (j <= i + 3 && rOct.test(str[j])) {
+ val = val * 8 + hexVal(str[j++]);
+ }
+ i = j - 1;
+ ret += String.fromCharCode(val);
+ }
+ }
+ return ret;
+ }
+
+ function isComparable(arg) {
+ return arg && isFunction(arg.equals);
+ }
+
+ function isTruthy(val) {
+ return !isFalsy(val);
+ }
+ function isFalsy(val) {
+ return val === false || undefined === val || val === null;
+ }
+
+ var operatorImpls = {
+ '==': function (l, r) {
+ if (isComparable(l))
+ return l.equals(r);
+ if (isComparable(r))
+ return r.equals(l);
+ return l === r;
+ },
+ '!=': function (l, r) {
+ if (isComparable(l))
+ return !l.equals(r);
+ if (isComparable(r))
+ return !r.equals(l);
+ return l !== r;
+ },
+ '>': function (l, r) {
+ if (isComparable(l))
+ return l.gt(r);
+ if (isComparable(r))
+ return r.lt(l);
+ return l > r;
+ },
+ '<': function (l, r) {
+ if (isComparable(l))
+ return l.lt(r);
+ if (isComparable(r))
+ return r.gt(l);
+ return l < r;
+ },
+ '>=': function (l, r) {
+ if (isComparable(l))
+ return l.geq(r);
+ if (isComparable(r))
+ return r.leq(l);
+ return l >= r;
+ },
+ '<=': function (l, r) {
+ if (isComparable(l))
+ return l.leq(r);
+ if (isComparable(r))
+ return r.geq(l);
+ return l <= r;
+ },
+ 'contains': function (l, r) {
+ return l && isFunction(l.indexOf) ? l.indexOf(r) > -1 : false;
+ },
+ 'and': function (l, r) { return isTruthy(l) && isTruthy(r); },
+ 'or': function (l, r) { return isTruthy(l) || isTruthy(r); }
+ };
+
+ var Expression = /** @class */ (function () {
+ function Expression(str) {
+ this.operands = [];
+ var tokenizer = new Tokenizer(str);
+ this.postfix = toPostfix(tokenizer.readExpression());
+ }
+ Expression.prototype.evaluate = function (ctx) {
+ var e_1, _a;
+ try {
+ for (var _b = __values(this.postfix), _c = _b.next(); !_c.done; _c = _b.next()) {
+ var token = _c.value;
+ if (isOperatorToken(token)) {
+ var r = this.operands.pop();
+ var l = this.operands.pop();
+ var result = evalOperatorToken(token, l, r);
+ this.operands.push(result);
+ }
+ else {
+ this.operands.push(evalToken(token, ctx));
+ }
+ }
+ }
+ catch (e_1_1) { e_1 = { error: e_1_1 }; }
+ finally {
+ try {
+ if (_c && !_c.done && (_a = _b.return)) _a.call(_b);
+ }
+ finally { if (e_1) throw e_1.error; }
+ }
+ return this.operands[0];
+ };
+ Expression.prototype.value = function (ctx) {
+ return __generator(this, function (_a) {
+ return [2 /*return*/, toValue(this.evaluate(ctx))];
+ });
+ };
+ return Expression;
+ }());
+ function evalToken(token, ctx) {
+ assert(ctx, function () { return 'unable to evaluate: context not defined'; });
+ if (isPropertyAccessToken(token)) {
+ var variable = token.variable.getText();
+ var props = token.props.map(function (prop) { return evalToken(prop, ctx); });
+ return ctx.get(__spread([variable], props));
+ }
+ if (isRangeToken(token))
+ return evalRangeToken(token, ctx);
+ if (isLiteralToken(token))
+ return evalLiteralToken(token);
+ if (isNumberToken(token))
+ return evalNumberToken(token);
+ if (isWordToken(token))
+ return token.getText();
+ if (isQuotedToken(token))
+ return evalQuotedToken(token);
+ }
+ function evalNumberToken(token) {
+ var str = token.whole.content + '.' + (token.decimal ? token.decimal.content : '');
+ return Number(str);
+ }
+ function evalQuotedToken(token) {
+ return parseStringLiteral(token.getText());
+ }
+ function evalOperatorToken(token, lhs, rhs) {
+ var impl = operatorImpls[token.operator];
+ return impl(lhs, rhs);
+ }
+ function evalLiteralToken(token) {
+ return literalValues[token.literal];
+ }
+ function evalRangeToken(token, ctx) {
+ var low = evalToken(token.lhs, ctx);
+ var high = evalToken(token.rhs, ctx);
+ return range(+low, +high + 1);
+ }
+ function toPostfix(tokens) {
+ var ops, tokens_1, tokens_1_1, token, e_2_1;
+ var e_2, _a;
+ return __generator(this, function (_b) {
+ switch (_b.label) {
+ case 0:
+ ops = [];
+ _b.label = 1;
+ case 1:
+ _b.trys.push([1, 10, 11, 12]);
+ tokens_1 = __values(tokens), tokens_1_1 = tokens_1.next();
+ _b.label = 2;
+ case 2:
+ if (!!tokens_1_1.done) return [3 /*break*/, 9];
+ token = tokens_1_1.value;
+ if (!isOperatorToken(token)) return [3 /*break*/, 6];
+ _b.label = 3;
+ case 3:
+ if (!(ops.length && ops[ops.length - 1].getPrecedence() > token.getPrecedence())) return [3 /*break*/, 5];
+ return [4 /*yield*/, ops.pop()];
+ case 4:
+ _b.sent();
+ return [3 /*break*/, 3];
+ case 5:
+ ops.push(token);
+ return [3 /*break*/, 8];
+ case 6: return [4 /*yield*/, token];
+ case 7:
+ _b.sent();
+ _b.label = 8;
+ case 8:
+ tokens_1_1 = tokens_1.next();
+ return [3 /*break*/, 2];
+ case 9: return [3 /*break*/, 12];
+ case 10:
+ e_2_1 = _b.sent();
+ e_2 = { error: e_2_1 };
+ return [3 /*break*/, 12];
+ case 11:
+ try {
+ if (tokens_1_1 && !tokens_1_1.done && (_a = tokens_1.return)) _a.call(tokens_1);
+ }
+ finally { if (e_2) throw e_2.error; }
+ return [7 /*endfinally*/];
+ case 12:
+ if (!ops.length) return [3 /*break*/, 14];
+ return [4 /*yield*/, ops.pop()];
+ case 13:
+ _b.sent();
+ return [3 /*break*/, 12];
+ case 14: return [2 /*return*/];
+ }
+ });
+ }
+
+ /**
+ * Key-Value Pairs Representing Tag Arguments
+ * Example:
+ * For the markup `, foo:'bar', coo:2 reversed %}`,
+ * hash['foo'] === 'bar'
+ * hash['coo'] === 2
+ * hash['reversed'] === undefined
+ */
+ var Hash = /** @class */ (function () {
+ function Hash(markup) {
+ var e_1, _a;
+ this.hash = {};
+ var tokenizer = new Tokenizer(markup);
+ try {
+ for (var _b = __values(tokenizer.readHashes()), _c = _b.next(); !_c.done; _c = _b.next()) {
+ var hash = _c.value;
+ this.hash[hash.name.content] = hash.value;
+ }
+ }
+ catch (e_1_1) { e_1 = { error: e_1_1 }; }
+ finally {
+ try {
+ if (_c && !_c.done && (_a = _b.return)) _a.call(_b);
+ }
+ finally { if (e_1) throw e_1.error; }
+ }
+ }
+ Hash.prototype.render = function (ctx) {
+ var hash, _a, _b, key;
+ var e_2, _c;
+ return __generator(this, function (_d) {
+ hash = {};
+ try {
+ for (_a = __values(Object.keys(this.hash)), _b = _a.next(); !_b.done; _b = _a.next()) {
+ key = _b.value;
+ hash[key] = evalToken(this.hash[key], ctx);
+ }
+ }
+ catch (e_2_1) { e_2 = { error: e_2_1 }; }
+ finally {
+ try {
+ if (_b && !_b.done && (_c = _a.return)) _c.call(_a);
+ }
+ finally { if (e_2) throw e_2.error; }
+ }
+ return [2 /*return*/, hash];
+ });
+ };
+ return Hash;
+ }());
+
+ var Tag = /** @class */ (function (_super) {
+ __extends(Tag, _super);
+ function Tag(token, tokens, liquid) {
+ var _this = _super.call(this, token) || this;
+ _this.name = token.name;
+ var impl = liquid.tags.get(token.name);
+ _this.impl = Object.create(impl);
+ _this.impl.liquid = liquid;
+ if (_this.impl.parse) {
+ _this.impl.parse(token, tokens);
+ }
+ return _this;
+ }
+ Tag.prototype.render = function (ctx, emitter) {
+ var hash, impl;
+ return __generator(this, function (_a) {
+ switch (_a.label) {
+ case 0: return [4 /*yield*/, new Hash(this.token.args).render(ctx)];
+ case 1:
+ hash = _a.sent();
+ impl = this.impl;
+ if (!isFunction(impl.render)) return [3 /*break*/, 3];
+ return [4 /*yield*/, impl.render(ctx, emitter, hash)];
+ case 2: return [2 /*return*/, _a.sent()];
+ case 3: return [2 /*return*/];
+ }
+ });
+ };
+ Tag.impls = {};
+ return Tag;
+ }(TemplateImpl));
+
+ function isKeyValuePair(arr) {
+ return isArray(arr);
+ }
+
+ var Filter = /** @class */ (function () {
+ function Filter(name, impl, args) {
+ this.name = name;
+ this.impl = impl || identify;
+ this.args = args;
+ }
+ Filter.prototype.render = function (value, context) {
+ var argv, _a, _b, arg, _c, _d, _e, _f, _g, e_1_1;
+ var e_1, _h;
+ return __generator(this, function (_j) {
+ switch (_j.label) {
+ case 0:
+ argv = [];
+ _j.label = 1;
+ case 1:
+ _j.trys.push([1, 8, 9, 10]);
+ _a = __values(this.args), _b = _a.next();
+ _j.label = 2;
+ case 2:
+ if (!!_b.done) return [3 /*break*/, 7];
+ arg = _b.value;
+ if (!isKeyValuePair(arg)) return [3 /*break*/, 4];
+ _d = (_c = argv).push;
+ _e = [arg[0]];
+ return [4 /*yield*/, evalToken(arg[1], context)];
+ case 3:
+ _d.apply(_c, [_e.concat([_j.sent()])]);
+ return [3 /*break*/, 6];
+ case 4:
+ _g = (_f = argv).push;
+ return [4 /*yield*/, evalToken(arg, context)];
+ case 5:
+ _g.apply(_f, [_j.sent()]);
+ _j.label = 6;
+ case 6:
+ _b = _a.next();
+ return [3 /*break*/, 2];
+ case 7: return [3 /*break*/, 10];
+ case 8:
+ e_1_1 = _j.sent();
+ e_1 = { error: e_1_1 };
+ return [3 /*break*/, 10];
+ case 9:
+ try {
+ if (_b && !_b.done && (_h = _a.return)) _h.call(_a);
+ }
+ finally { if (e_1) throw e_1.error; }
+ return [7 /*endfinally*/];
+ case 10: return [2 /*return*/, this.impl.apply({ context: context }, __spread([value], argv))];
+ }
+ });
+ };
+ return Filter;
+ }());
+
+ var Value = /** @class */ (function () {
+ /**
+ * @param str the value to be valuated, eg.: "foobar" | truncate: 3
+ */
+ function Value(str, filterMap) {
+ var _this = this;
+ this.filterMap = filterMap;
+ this.filters = [];
+ var tokenizer = new Tokenizer(str);
+ this.initial = tokenizer.readValue();
+ this.filters = tokenizer.readFilters().map(function (_a) {
+ var name = _a.name, args = _a.args;
+ return new Filter(name, _this.filterMap.get(name), args);
+ });
+ }
+ Value.prototype.value = function (ctx) {
+ var val, _a, _b, filter, e_1_1;
+ var e_1, _c;
+ return __generator(this, function (_d) {
+ switch (_d.label) {
+ case 0: return [4 /*yield*/, evalToken(this.initial, ctx)];
+ case 1:
+ val = _d.sent();
+ _d.label = 2;
+ case 2:
+ _d.trys.push([2, 7, 8, 9]);
+ _a = __values(this.filters), _b = _a.next();
+ _d.label = 3;
+ case 3:
+ if (!!_b.done) return [3 /*break*/, 6];
+ filter = _b.value;
+ return [4 /*yield*/, filter.render(val, ctx)];
+ case 4:
+ val = _d.sent();
+ _d.label = 5;
+ case 5:
+ _b = _a.next();
+ return [3 /*break*/, 3];
+ case 6: return [3 /*break*/, 9];
+ case 7:
+ e_1_1 = _d.sent();
+ e_1 = { error: e_1_1 };
+ return [3 /*break*/, 9];
+ case 8:
+ try {
+ if (_b && !_b.done && (_c = _a.return)) _c.call(_a);
+ }
+ finally { if (e_1) throw e_1.error; }
+ return [7 /*endfinally*/];
+ case 9: return [2 /*return*/, val];
+ }
+ });
+ };
+ return Value;
+ }());
+
+ var Output = /** @class */ (function (_super) {
+ __extends(Output, _super);
+ function Output(token, filters) {
+ var _this = _super.call(this, token) || this;
+ _this.value = new Value(token.content, filters);
+ return _this;
+ }
+ Output.prototype.render = function (ctx, emitter) {
+ var val;
+ return __generator(this, function (_a) {
+ switch (_a.label) {
+ case 0: return [4 /*yield*/, this.value.value(ctx)];
+ case 1:
+ val = _a.sent();
+ emitter.write(stringify(toValue(val)));
+ return [2 /*return*/];
+ }
+ });
+ };
+ return Output;
+ }(TemplateImpl));
+
+ var HTML = /** @class */ (function (_super) {
+ __extends(HTML, _super);
+ function HTML(token) {
+ var _this = _super.call(this, token) || this;
+ _this.str = token.getContent();
+ return _this;
+ }
+ HTML.prototype.render = function (ctx, emitter) {
+ return __generator(this, function (_a) {
+ emitter.write(this.str);
+ return [2 /*return*/];
+ });
+ };
+ return HTML;
+ }(TemplateImpl));
+
+ var Parser = /** @class */ (function () {
+ function Parser(liquid) {
+ this.liquid = liquid;
+ }
+ Parser.prototype.parse = function (tokens) {
+ var token;
+ var templates = [];
+ while ((token = tokens.shift())) {
+ templates.push(this.parseToken(token, tokens));
+ }
+ return templates;
+ };
+ Parser.prototype.parseToken = function (token, remainTokens) {
+ try {
+ if (isTagToken(token)) {
+ return new Tag(token, remainTokens, this.liquid);
+ }
+ if (isOutputToken(token)) {
+ return new Output(token, this.liquid.filters);
+ }
+ return new HTML(token);
+ }
+ catch (e) {
+ throw new ParseError(e, token);
+ }
+ };
+ Parser.prototype.parseStream = function (tokens) {
+ var _this = this;
+ return new ParseStream(tokens, function (token, tokens) { return _this.parseToken(token, tokens); });
+ };
+ return Parser;
+ }());
+
+ var assign = {
+ parse: function (token) {
+ var tokenizer = new Tokenizer(token.args);
+ this.key = tokenizer.readWord().content;
+ tokenizer.skipBlank();
+ assert(tokenizer.peek() === '=', function () { return "illegal token " + token.getText(); });
+ tokenizer.advance();
+ this.value = tokenizer.remaining();
+ },
+ render: function (ctx) {
+ var _a, _b;
+ return __generator(this, function (_c) {
+ switch (_c.label) {
+ case 0:
+ _a = ctx.bottom();
+ _b = this.key;
+ return [4 /*yield*/, this.liquid._evalValue(this.value, ctx)];
+ case 1:
+ _a[_b] = _c.sent();
+ return [2 /*return*/];
+ }
+ });
+ }
+ };
+
+ function toEnumerable(val) {
+ if (isArray(val))
+ return val;
+ if (isString(val) && val.length > 0)
+ return [val];
+ if (isObject(val))
+ return Object.keys(val).map(function (key) { return [key, val[key]]; });
+ return [];
+ }
+ function toArray(val) {
+ if (isArray(val))
+ return val;
+ return [val];
+ }
+
+ var ForloopDrop = /** @class */ (function (_super) {
+ __extends(ForloopDrop, _super);
+ function ForloopDrop(length) {
+ var _this = _super.call(this) || this;
+ _this.i = 0;
+ _this.length = length;
+ return _this;
+ }
+ ForloopDrop.prototype.next = function () {
+ this.i++;
+ };
+ ForloopDrop.prototype.index0 = function () {
+ return this.i;
+ };
+ ForloopDrop.prototype.index = function () {
+ return this.i + 1;
+ };
+ ForloopDrop.prototype.first = function () {
+ return this.i === 0;
+ };
+ ForloopDrop.prototype.last = function () {
+ return this.i === this.length - 1;
+ };
+ ForloopDrop.prototype.rindex = function () {
+ return this.length - this.i;
+ };
+ ForloopDrop.prototype.rindex0 = function () {
+ return this.length - this.i - 1;
+ };
+ ForloopDrop.prototype.valueOf = function () {
+ return JSON.stringify(this);
+ };
+ return ForloopDrop;
+ }(Drop));
+
+ var For = {
+ type: 'block',
+ parse: function (token, remainTokens) {
+ var _this = this;
+ var toknenizer = new Tokenizer(token.args);
+ var variable = toknenizer.readWord();
+ var inStr = toknenizer.readWord();
+ var collection = toknenizer.readValue();
+ assert(variable.size() && inStr.content === 'in' && collection, function () { return "illegal tag: " + token.getText(); });
+ this.variable = variable.content;
+ this.collection = collection;
+ this.hash = new Hash(toknenizer.remaining());
+ this.templates = [];
+ this.elseTemplates = [];
+ var p;
+ var stream = this.liquid.parser.parseStream(remainTokens)
+ .on('start', function () { return (p = _this.templates); })
+ .on('tag:else', function () { return (p = _this.elseTemplates); })
+ .on('tag:endfor', function () { return stream.stop(); })
+ .on('template', function (tpl) { return p.push(tpl); })
+ .on('end', function () {
+ throw new Error("tag " + token.getText() + " not closed");
+ });
+ stream.start();
+ },
+ render: function (ctx, emitter) {
+ var r, collection, hash, offset, limit, scope, collection_1, collection_1_1, item, e_1_1;
+ var e_1, _a;
+ return __generator(this, function (_b) {
+ switch (_b.label) {
+ case 0:
+ r = this.liquid.renderer;
+ collection = toEnumerable(evalToken(this.collection, ctx));
+ if (!!collection.length) return [3 /*break*/, 2];
+ return [4 /*yield*/, r.renderTemplates(this.elseTemplates, ctx, emitter)];
+ case 1:
+ _b.sent();
+ return [2 /*return*/];
+ case 2: return [4 /*yield*/, this.hash.render(ctx)];
+ case 3:
+ hash = _b.sent();
+ offset = hash.offset || 0;
+ limit = (hash.limit === undefined) ? collection.length : hash.limit;
+ collection = collection.slice(offset, offset + limit);
+ if ('reversed' in hash)
+ collection.reverse();
+ scope = { forloop: new ForloopDrop(collection.length) };
+ ctx.push(scope);
+ _b.label = 4;
+ case 4:
+ _b.trys.push([4, 9, 10, 11]);
+ collection_1 = __values(collection), collection_1_1 = collection_1.next();
+ _b.label = 5;
+ case 5:
+ if (!!collection_1_1.done) return [3 /*break*/, 8];
+ item = collection_1_1.value;
+ scope[this.variable] = item;
+ return [4 /*yield*/, r.renderTemplates(this.templates, ctx, emitter)];
+ case 6:
+ _b.sent();
+ if (emitter.break) {
+ emitter.break = false;
+ return [3 /*break*/, 8];
+ }
+ emitter.continue = false;
+ scope.forloop.next();
+ _b.label = 7;
+ case 7:
+ collection_1_1 = collection_1.next();
+ return [3 /*break*/, 5];
+ case 8: return [3 /*break*/, 11];
+ case 9:
+ e_1_1 = _b.sent();
+ e_1 = { error: e_1_1 };
+ return [3 /*break*/, 11];
+ case 10:
+ try {
+ if (collection_1_1 && !collection_1_1.done && (_a = collection_1.return)) _a.call(collection_1);
+ }
+ finally { if (e_1) throw e_1.error; }
+ return [7 /*endfinally*/];
+ case 11:
+ ctx.pop();
+ return [2 /*return*/];
+ }
+ });
+ }
+ };
+
+ var capture = {
+ parse: function (tagToken, remainTokens) {
+ var _this = this;
+ var tokenizer = new Tokenizer(tagToken.args);
+ this.variable = tokenizer.readWord().content;
+ assert(this.variable, function () { return tagToken.args + " not valid identifier"; });
+ this.templates = [];
+ var stream = this.liquid.parser.parseStream(remainTokens);
+ stream.on('tag:endcapture', function () { return stream.stop(); })
+ .on('template', function (tpl) { return _this.templates.push(tpl); })
+ .on('end', function () {
+ throw new Error("tag " + tagToken.getText() + " not closed");
+ });
+ stream.start();
+ },
+ render: function (ctx) {
+ var r, html;
+ return __generator(this, function (_a) {
+ switch (_a.label) {
+ case 0:
+ r = this.liquid.renderer;
+ return [4 /*yield*/, r.renderTemplates(this.templates, ctx)];
+ case 1:
+ html = _a.sent();
+ ctx.bottom()[this.variable] = html;
+ return [2 /*return*/];
+ }
+ });
+ }
+ };
+
+ var Case = {
+ parse: function (tagToken, remainTokens) {
+ var _this = this;
+ this.cond = tagToken.args;
+ this.cases = [];
+ this.elseTemplates = [];
+ var p = [];
+ var stream = this.liquid.parser.parseStream(remainTokens)
+ .on('tag:when', function (token) {
+ _this.cases.push({
+ val: token.args,
+ templates: p = []
+ });
+ })
+ .on('tag:else', function () { return (p = _this.elseTemplates); })
+ .on('tag:endcase', function () { return stream.stop(); })
+ .on('template', function (tpl) { return p.push(tpl); })
+ .on('end', function () {
+ throw new Error("tag " + tagToken.getText() + " not closed");
+ });
+ stream.start();
+ },
+ render: function (ctx, emitter) {
+ var r, cond, i, branch, val;
+ return __generator(this, function (_a) {
+ switch (_a.label) {
+ case 0:
+ r = this.liquid.renderer;
+ return [4 /*yield*/, new Expression(this.cond).value(ctx)];
+ case 1:
+ cond = _a.sent();
+ i = 0;
+ _a.label = 2;
+ case 2:
+ if (!(i < this.cases.length)) return [3 /*break*/, 6];
+ branch = this.cases[i];
+ return [4 /*yield*/, new Expression(branch.val).value(ctx)];
+ case 3:
+ val = _a.sent();
+ if (!(val === cond)) return [3 /*break*/, 5];
+ return [4 /*yield*/, r.renderTemplates(branch.templates, ctx, emitter)];
+ case 4:
+ _a.sent();
+ return [2 /*return*/];
+ case 5:
+ i++;
+ return [3 /*break*/, 2];
+ case 6: return [4 /*yield*/, r.renderTemplates(this.elseTemplates, ctx, emitter)];
+ case 7:
+ _a.sent();
+ return [2 /*return*/];
+ }
+ });
+ }
+ };
+
+ var comment = {
+ parse: function (tagToken, remainTokens) {
+ var stream = this.liquid.parser.parseStream(remainTokens);
+ stream
+ .on('token', function (token) {
+ if (token.name === 'endcomment')
+ stream.stop();
+ })
+ .on('end', function () {
+ throw new Error("tag " + tagToken.getText() + " not closed");
+ });
+ stream.start();
+ }
+ };
+
+ var BlockMode;
+ (function (BlockMode) {
+ /* store rendered html into blocks */
+ BlockMode[BlockMode["OUTPUT"] = 0] = "OUTPUT";
+ /* output rendered html directly */
+ BlockMode[BlockMode["STORE"] = 1] = "STORE";
+ })(BlockMode || (BlockMode = {}));
+ var BlockMode$1 = BlockMode;
+
+ var include = {
+ parse: function (token) {
+ var args = token.args;
+ var tokenizer = new Tokenizer(args);
+ this.file = this.liquid.options.dynamicPartials
+ ? tokenizer.readValue()
+ : tokenizer.readFileName();
+ assert(this.file, function () { return "illegal argument \"" + token.args + "\""; });
+ var begin = tokenizer.p;
+ var withStr = tokenizer.readWord();
+ if (withStr.content === 'with') {
+ tokenizer.skipBlank();
+ if (tokenizer.peek() !== ':') {
+ this.withVar = tokenizer.readValue();
+ }
+ else
+ tokenizer.p = begin;
+ }
+ else
+ tokenizer.p = begin;
+ this.hash = new Hash(tokenizer.remaining());
+ },
+ render: function (ctx, emitter) {
+ var _a, liquid, hash, withVar, file, renderer, filepath, _b, _c, saved, scope, templates;
+ return __generator(this, function (_d) {
+ switch (_d.label) {
+ case 0:
+ _a = this, liquid = _a.liquid, hash = _a.hash, withVar = _a.withVar, file = _a.file;
+ renderer = liquid.renderer;
+ if (!ctx.opts.dynamicPartials) return [3 /*break*/, 5];
+ if (!isQuotedToken(file)) return [3 /*break*/, 2];
+ return [4 /*yield*/, renderer.renderTemplates(liquid.parse(evalQuotedToken(file)), ctx)];
+ case 1:
+ _c = _d.sent();
+ return [3 /*break*/, 4];
+ case 2: return [4 /*yield*/, evalToken(file, ctx)];
+ case 3:
+ _c = _d.sent();
+ _d.label = 4;
+ case 4:
+ _b = (_c);
+ return [3 /*break*/, 6];
+ case 5:
+ _b = file.getText();
+ _d.label = 6;
+ case 6:
+ filepath = _b;
+ assert(filepath, function () { return "illegal filename \"" + file.getText() + "\":\"" + filepath + "\""; });
+ saved = ctx.saveRegister('blocks', 'blockMode');
+ ctx.setRegister('blocks', {});
+ ctx.setRegister('blockMode', BlockMode$1.OUTPUT);
+ return [4 /*yield*/, hash.render(ctx)];
+ case 7:
+ scope = _d.sent();
+ if (withVar)
+ scope[filepath] = evalToken(withVar, ctx);
+ return [4 /*yield*/, liquid._parseFile(filepath, ctx.opts, ctx.sync)];
+ case 8:
+ templates = _d.sent();
+ ctx.push(scope);
+ return [4 /*yield*/, renderer.renderTemplates(templates, ctx, emitter)];
+ case 9:
+ _d.sent();
+ ctx.pop();
+ ctx.restoreRegister(saved);
+ return [2 /*return*/];
+ }
+ });
+ }
+ };
+
+ var render = {
+ parse: function (token) {
+ var args = token.args;
+ var tokenizer = new Tokenizer(args);
+ this.file = this.liquid.options.dynamicPartials
+ ? tokenizer.readValue()
+ : tokenizer.readFileName();
+ assert(this.file, function () { return "illegal argument \"" + token.args + "\""; });
+ while (!tokenizer.end()) {
+ tokenizer.skipBlank();
+ var begin = tokenizer.p;
+ var keyword = tokenizer.readWord();
+ if (keyword.content === 'with' || keyword.content === 'for') {
+ tokenizer.skipBlank();
+ if (tokenizer.peek() !== ':') {
+ var value = tokenizer.readValue();
+ if (value) {
+ var beforeAs = tokenizer.p;
+ var asStr = tokenizer.readWord();
+ var alias = void 0;
+ if (asStr.content === 'as')
+ alias = tokenizer.readWord();
+ else
+ tokenizer.p = beforeAs;
+ this[keyword.content] = { value: value, alias: alias && alias.content };
+ tokenizer.skipBlank();
+ if (tokenizer.peek() === ',')
+ tokenizer.advance();
+ continue;
+ }
+ }
+ }
+ tokenizer.p = begin;
+ break;
+ }
+ this.hash = new Hash(tokenizer.remaining());
+ },
+ render: function (ctx, emitter) {
+ var _a, liquid, file, hash, renderer, filepath, _b, _c, childCtx, scope, _d, value, alias, _e, value, alias, collection, collection_1, collection_1_1, item, templates, e_1_1, templates;
+ var e_1, _f;
+ return __generator(this, function (_g) {
+ switch (_g.label) {
+ case 0:
+ _a = this, liquid = _a.liquid, file = _a.file, hash = _a.hash;
+ renderer = liquid.renderer;
+ if (!ctx.opts.dynamicPartials) return [3 /*break*/, 4];
+ if (!isQuotedToken(file)) return [3 /*break*/, 2];
+ return [4 /*yield*/, renderer.renderTemplates(liquid.parse(evalQuotedToken(file)), ctx)];
+ case 1:
+ _c = _g.sent();
+ return [3 /*break*/, 3];
+ case 2:
+ _c = evalToken(file, ctx);
+ _g.label = 3;
+ case 3:
+ _b = (_c);
+ return [3 /*break*/, 5];
+ case 4:
+ _b = file.getText();
+ _g.label = 5;
+ case 5:
+ filepath = _b;
+ assert(filepath, function () { return "illegal filename \"" + file.getText() + "\":\"" + filepath + "\""; });
+ childCtx = new Context({}, ctx.opts, ctx.sync);
+ return [4 /*yield*/, hash.render(ctx)];
+ case 6:
+ scope = _g.sent();
+ if (this['with']) {
+ _d = this['with'], value = _d.value, alias = _d.alias;
+ scope[alias || filepath] = evalToken(value, ctx);
+ }
+ childCtx.push(scope);
+ if (!this['for']) return [3 /*break*/, 16];
+ _e = this['for'], value = _e.value, alias = _e.alias;
+ collection = evalToken(value, ctx);
+ collection = toEnumerable(collection);
+ scope['forloop'] = new ForloopDrop(collection.length);
+ _g.label = 7;
+ case 7:
+ _g.trys.push([7, 13, 14, 15]);
+ collection_1 = __values(collection), collection_1_1 = collection_1.next();
+ _g.label = 8;
+ case 8:
+ if (!!collection_1_1.done) return [3 /*break*/, 12];
+ item = collection_1_1.value;
+ scope[alias] = item;
+ return [4 /*yield*/, liquid._parseFile(filepath, childCtx.opts, childCtx.sync)];
+ case 9:
+ templates = _g.sent();
+ return [4 /*yield*/, renderer.renderTemplates(templates, childCtx, emitter)];
+ case 10:
+ _g.sent();
+ scope.forloop.next();
+ _g.label = 11;
+ case 11:
+ collection_1_1 = collection_1.next();
+ return [3 /*break*/, 8];
+ case 12: return [3 /*break*/, 15];
+ case 13:
+ e_1_1 = _g.sent();
+ e_1 = { error: e_1_1 };
+ return [3 /*break*/, 15];
+ case 14:
+ try {
+ if (collection_1_1 && !collection_1_1.done && (_f = collection_1.return)) _f.call(collection_1);
+ }
+ finally { if (e_1) throw e_1.error; }
+ return [7 /*endfinally*/];
+ case 15: return [3 /*break*/, 19];
+ case 16: return [4 /*yield*/, liquid._parseFile(filepath, childCtx.opts, childCtx.sync)];
+ case 17:
+ templates = _g.sent();
+ return [4 /*yield*/, renderer.renderTemplates(templates, childCtx, emitter)];
+ case 18:
+ _g.sent();
+ _g.label = 19;
+ case 19: return [2 /*return*/];
+ }
+ });
+ }
+ };
+
+ var decrement = {
+ parse: function (token) {
+ var tokenizer = new Tokenizer(token.args);
+ this.variable = tokenizer.readWord().content;
+ },
+ render: function (context, emitter) {
+ var scope = context.environments;
+ if (!isNumber(scope[this.variable])) {
+ scope[this.variable] = 0;
+ }
+ emitter.write(stringify(--scope[this.variable]));
+ }
+ };
+
+ var cycle = {
+ parse: function (tagToken) {
+ var tokenizer = new Tokenizer(tagToken.args);
+ var group = tokenizer.readValue();
+ tokenizer.skipBlank();
+ this.candidates = [];
+ if (group) {
+ if (tokenizer.peek() === ':') {
+ this.group = group;
+ tokenizer.advance();
+ }
+ else
+ this.candidates.push(group);
+ }
+ while (!tokenizer.end()) {
+ var value = tokenizer.readValue();
+ if (value)
+ this.candidates.push(value);
+ tokenizer.readTo(',');
+ }
+ assert(this.candidates.length, function () { return "empty candidates: " + tagToken.getText(); });
+ },
+ render: function (ctx, emitter) {
+ var group = evalToken(this.group, ctx);
+ var fingerprint = "cycle:" + group + ":" + this.candidates.join(',');
+ var groups = ctx.getRegister('cycle');
+ var idx = groups[fingerprint];
+ if (idx === undefined) {
+ idx = groups[fingerprint] = 0;
+ }
+ var candidate = this.candidates[idx];
+ idx = (idx + 1) % this.candidates.length;
+ groups[fingerprint] = idx;
+ var html = evalToken(candidate, ctx);
+ emitter.write(html);
+ }
+ };
+
+ var If = {
+ parse: function (tagToken, remainTokens) {
+ var _this = this;
+ this.branches = [];
+ this.elseTemplates = [];
+ var p;
+ var stream = this.liquid.parser.parseStream(remainTokens)
+ .on('start', function () { return _this.branches.push({
+ cond: tagToken.args,
+ templates: (p = [])
+ }); })
+ .on('tag:elsif', function (token) {
+ _this.branches.push({
+ cond: token.args,
+ templates: p = []
+ });
+ })
+ .on('tag:else', function () { return (p = _this.elseTemplates); })
+ .on('tag:endif', function () { return stream.stop(); })
+ .on('template', function (tpl) { return p.push(tpl); })
+ .on('end', function () {
+ throw new Error("tag " + tagToken.getText() + " not closed");
+ });
+ stream.start();
+ },
+ render: function (ctx, emitter) {
+ var r, _a, _b, branch, cond, e_1_1;
+ var e_1, _c;
+ return __generator(this, function (_d) {
+ switch (_d.label) {
+ case 0:
+ r = this.liquid.renderer;
+ _d.label = 1;
+ case 1:
+ _d.trys.push([1, 7, 8, 9]);
+ _a = __values(this.branches), _b = _a.next();
+ _d.label = 2;
+ case 2:
+ if (!!_b.done) return [3 /*break*/, 6];
+ branch = _b.value;
+ return [4 /*yield*/, new Expression(branch.cond).value(ctx)];
+ case 3:
+ cond = _d.sent();
+ if (!isTruthy(cond)) return [3 /*break*/, 5];
+ return [4 /*yield*/, r.renderTemplates(branch.templates, ctx, emitter)];
+ case 4:
+ _d.sent();
+ return [2 /*return*/];
+ case 5:
+ _b = _a.next();
+ return [3 /*break*/, 2];
+ case 6: return [3 /*break*/, 9];
+ case 7:
+ e_1_1 = _d.sent();
+ e_1 = { error: e_1_1 };
+ return [3 /*break*/, 9];
+ case 8:
+ try {
+ if (_b && !_b.done && (_c = _a.return)) _c.call(_a);
+ }
+ finally { if (e_1) throw e_1.error; }
+ return [7 /*endfinally*/];
+ case 9: return [4 /*yield*/, r.renderTemplates(this.elseTemplates, ctx, emitter)];
+ case 10:
+ _d.sent();
+ return [2 /*return*/];
+ }
+ });
+ }
+ };
+
+ var increment = {
+ parse: function (token) {
+ var tokenizer = new Tokenizer(token.args);
+ this.variable = tokenizer.readWord().content;
+ },
+ render: function (context, emitter) {
+ var scope = context.environments;
+ if (!isNumber(scope[this.variable])) {
+ scope[this.variable] = 0;
+ }
+ var val = scope[this.variable];
+ scope[this.variable]++;
+ emitter.write(stringify(val));
+ }
+ };
+
+ var layout = {
+ parse: function (token, remainTokens) {
+ var tokenizer = new Tokenizer(token.args);
+ var file = this.liquid.options.dynamicPartials ? tokenizer.readValue() : tokenizer.readFileName();
+ assert(file, function () { return "illegal argument \"" + token.args + "\""; });
+ this.file = file;
+ this.hash = new Hash(tokenizer.remaining());
+ this.tpls = this.liquid.parser.parse(remainTokens);
+ },
+ render: function (ctx, emitter) {
+ var _a, liquid, hash, file, renderer, filepath, _b, _c, blocks, html, templates, _d, _e, partial;
+ return __generator(this, function (_f) {
+ switch (_f.label) {
+ case 0:
+ _a = this, liquid = _a.liquid, hash = _a.hash, file = _a.file;
+ renderer = liquid.renderer;
+ if (!ctx.opts.dynamicPartials) return [3 /*break*/, 4];
+ if (!isQuotedToken(file)) return [3 /*break*/, 2];
+ return [4 /*yield*/, renderer.renderTemplates(liquid.parse(evalQuotedToken(file)), ctx)];
+ case 1:
+ _c = _f.sent();
+ return [3 /*break*/, 3];
+ case 2:
+ _c = evalToken(this.file, ctx);
+ _f.label = 3;
+ case 3:
+ _b = (_c);
+ return [3 /*break*/, 5];
+ case 4:
+ _b = file.getText();
+ _f.label = 5;
+ case 5:
+ filepath = _b;
+ assert(filepath, function () { return "illegal filename \"" + file.getText() + "\":\"" + filepath + "\""; });
+ // render the remaining tokens immediately
+ ctx.setRegister('blockMode', BlockMode$1.STORE);
+ blocks = ctx.getRegister('blocks');
+ return [4 /*yield*/, renderer.renderTemplates(this.tpls, ctx)];
+ case 6:
+ html = _f.sent();
+ if (blocks[''] === undefined)
+ blocks[''] = html;
+ return [4 /*yield*/, liquid._parseFile(filepath, ctx.opts, ctx.sync)];
+ case 7:
+ templates = _f.sent();
+ _e = (_d = ctx).push;
+ return [4 /*yield*/, hash.render(ctx)];
+ case 8:
+ _e.apply(_d, [_f.sent()]);
+ ctx.setRegister('blockMode', BlockMode$1.OUTPUT);
+ return [4 /*yield*/, renderer.renderTemplates(templates, ctx)];
+ case 9:
+ partial = _f.sent();
+ ctx.pop();
+ emitter.write(partial);
+ return [2 /*return*/];
+ }
+ });
+ }
+ };
+
+ var block = {
+ parse: function (token, remainTokens) {
+ var _this = this;
+ var match = /\w+/.exec(token.args);
+ this.block = match ? match[0] : '';
+ this.tpls = [];
+ var stream = this.liquid.parser.parseStream(remainTokens)
+ .on('tag:endblock', function () { return stream.stop(); })
+ .on('template', function (tpl) { return _this.tpls.push(tpl); })
+ .on('end', function () {
+ throw new Error("tag " + token.getText() + " not closed");
+ });
+ stream.start();
+ },
+ render: function (ctx, emitter) {
+ var blocks, childDefined, r, html, _a;
+ return __generator(this, function (_b) {
+ switch (_b.label) {
+ case 0:
+ blocks = ctx.getRegister('blocks');
+ childDefined = blocks[this.block];
+ r = this.liquid.renderer;
+ if (!(childDefined !== undefined)) return [3 /*break*/, 1];
+ _a = childDefined;
+ return [3 /*break*/, 3];
+ case 1: return [4 /*yield*/, r.renderTemplates(this.tpls, ctx)];
+ case 2:
+ _a = _b.sent();
+ _b.label = 3;
+ case 3:
+ html = _a;
+ if (ctx.getRegister('blockMode', BlockMode$1.OUTPUT) === BlockMode$1.STORE) {
+ blocks[this.block] = html;
+ return [2 /*return*/];
+ }
+ emitter.write(html);
+ return [2 /*return*/];
+ }
+ });
+ }
+ };
+
+ var raw = {
+ parse: function (tagToken, remainTokens) {
+ var _this = this;
+ this.tokens = [];
+ var stream = this.liquid.parser.parseStream(remainTokens);
+ stream
+ .on('token', function (token) {
+ if (token.name === 'endraw')
+ stream.stop();
+ else
+ _this.tokens.push(token);
+ })
+ .on('end', function () {
+ throw new Error("tag " + tagToken.getText() + " not closed");
+ });
+ stream.start();
+ },
+ render: function () {
+ return this.tokens.map(function (token) { return token.getText(); }).join('');
+ }
+ };
+
+ var TablerowloopDrop = /** @class */ (function (_super) {
+ __extends(TablerowloopDrop, _super);
+ function TablerowloopDrop(length, cols) {
+ var _this = _super.call(this, length) || this;
+ _this.length = length;
+ _this.cols = cols;
+ return _this;
+ }
+ TablerowloopDrop.prototype.row = function () {
+ return Math.floor(this.i / this.cols) + 1;
+ };
+ TablerowloopDrop.prototype.col0 = function () {
+ return (this.i % this.cols);
+ };
+ TablerowloopDrop.prototype.col = function () {
+ return this.col0() + 1;
+ };
+ TablerowloopDrop.prototype.col_first = function () {
+ return this.col0() === 0;
+ };
+ TablerowloopDrop.prototype.col_last = function () {
+ return this.col() === this.cols;
+ };
+ return TablerowloopDrop;
+ }(ForloopDrop));
+
+ var tablerow = {
+ parse: function (tagToken, remainTokens) {
+ var _this = this;
+ var tokenizer = new Tokenizer(tagToken.args);
+ this.variable = tokenizer.readWord();
+ tokenizer.skipBlank();
+ var tmp = tokenizer.readWord();
+ assert(tmp && tmp.content === 'in', function () { return "illegal tag: " + tagToken.getText(); });
+ this.collection = tokenizer.readValue();
+ this.hash = new Hash(tokenizer.remaining());
+ this.templates = [];
+ var p;
+ var stream = this.liquid.parser.parseStream(remainTokens)
+ .on('start', function () { return (p = _this.templates); })
+ .on('tag:endtablerow', function () { return stream.stop(); })
+ .on('template', function (tpl) { return p.push(tpl); })
+ .on('end', function () {
+ throw new Error("tag " + tagToken.getText() + " not closed");
+ });
+ stream.start();
+ },
+ render: function (ctx, emitter) {
+ var collection, hash, offset, limit, cols, r, tablerowloop, scope, idx;
+ return __generator(this, function (_a) {
+ switch (_a.label) {
+ case 0:
+ collection = toEnumerable(evalToken(this.collection, ctx));
+ return [4 /*yield*/, this.hash.render(ctx)];
+ case 1:
+ hash = _a.sent();
+ offset = hash.offset || 0;
+ limit = (hash.limit === undefined) ? collection.length : hash.limit;
+ collection = collection.slice(offset, offset + limit);
+ cols = hash.cols || collection.length;
+ r = this.liquid.renderer;
+ tablerowloop = new TablerowloopDrop(collection.length, cols);
+ scope = { tablerowloop: tablerowloop };
+ ctx.push(scope);
+ idx = 0;
+ _a.label = 2;
+ case 2:
+ if (!(idx < collection.length)) return [3 /*break*/, 5];
+ scope[this.variable.content] = collection[idx];
+ if (tablerowloop.col0() === 0) {
+ if (tablerowloop.row() !== 1)
+ emitter.write('</tr>');
+ emitter.write("<tr class=\"row" + tablerowloop.row() + "\">");
+ }
+ emitter.write("<td class=\"col" + tablerowloop.col() + "\">");
+ return [4 /*yield*/, r.renderTemplates(this.templates, ctx, emitter)];
+ case 3:
+ _a.sent();
+ emitter.write('</td>');
+ _a.label = 4;
+ case 4:
+ idx++, tablerowloop.next();
+ return [3 /*break*/, 2];
+ case 5:
+ if (collection.length)
+ emitter.write('</tr>');
+ ctx.pop();
+ return [2 /*return*/];
+ }
+ });
+ }
+ };
+
+ var unless = {
+ parse: function (tagToken, remainTokens) {
+ var _this = this;
+ this.templates = [];
+ this.elseTemplates = [];
+ var p;
+ var stream = this.liquid.parser.parseStream(remainTokens)
+ .on('start', function () {
+ p = _this.templates;
+ _this.cond = tagToken.args;
+ })
+ .on('tag:else', function () { return (p = _this.elseTemplates); })
+ .on('tag:endunless', function () { return stream.stop(); })
+ .on('template', function (tpl) { return p.push(tpl); })
+ .on('end', function () {
+ throw new Error("tag " + tagToken.getText() + " not closed");
+ });
+ stream.start();
+ },
+ render: function (ctx, emitter) {
+ var r, cond;
+ return __generator(this, function (_a) {
+ switch (_a.label) {
+ case 0:
+ r = this.liquid.renderer;
+ return [4 /*yield*/, new Expression(this.cond).value(ctx)];
+ case 1:
+ cond = _a.sent();
+ return [4 /*yield*/, (isFalsy(cond)
+ ? r.renderTemplates(this.templates, ctx, emitter)
+ : r.renderTemplates(this.elseTemplates, ctx, emitter))];
+ case 2:
+ _a.sent();
+ return [2 /*return*/];
+ }
+ });
+ }
+ };
+
+ var Break = {
+ render: function (ctx, emitter) {
+ emitter.break = true;
+ }
+ };
+
+ var Continue = {
+ render: function (ctx, emitter) {
+ emitter.continue = true;
+ }
+ };
+
+ var tags = {
+ assign: assign, 'for': For, capture: capture, 'case': Case, comment: comment, include: include, render: render, decrement: decrement, increment: increment, cycle: cycle, 'if': If, layout: layout, block: block, raw: raw, tablerow: tablerow, unless: unless, 'break': Break, 'continue': Continue
+ };
+
+ var escapeMap = {
+ '&': '&amp;',
+ '<': '&lt;',
+ '>': '&gt;',
+ '"': '&#34;',
+ "'": '&#39;'
+ };
+ var unescapeMap = {
+ '&amp;': '&',
+ '&lt;': '<',
+ '&gt;': '>',
+ '&#34;': '"',
+ '&#39;': "'"
+ };
+ function escape(str) {
+ return stringify(str).replace(/&|<|>|"|'/g, function (m) { return escapeMap[m]; });
+ }
+ function unescape(str) {
+ return String(str).replace(/&(amp|lt|gt|#34|#39);/g, function (m) { return unescapeMap[m]; });
+ }
+ function escapeOnce(str) {
+ return escape(unescape(str));
+ }
+ function newlineToBr(v) {
+ return v.replace(/\n/g, '<br/>');
+ }
+ function stripHtml(v) {
+ return v.replace(/<script.*?<\/script>|<!--.*?-->|<style.*?<\/style>|<.*?>/g, '');
+ }
+
+ var abs = Math.abs;
+ var atLeast = Math.max;
+ var atMost = Math.min;
+ var ceil = Math.ceil;
+ var dividedBy = function (v, arg) { return v / arg; };
+ var floor = Math.floor;
+ var minus = function (v, arg) { return v - arg; };
+ var modulo = function (v, arg) { return v % arg; };
+ var times = function (v, arg) { return v * arg; };
+ function round(v, arg) {
+ if (arg === void 0) { arg = 0; }
+ var amp = Math.pow(10, arg);
+ return Math.round(v * amp) / amp;
+ }
+ function plus(v, arg) {
+ return Number(v) + Number(arg);
+ }
+ function sortNatural(input, property) {
+ if (!input || !input.sort)
+ return [];
+ if (property !== undefined) {
+ return __spread(input).sort(function (lhs, rhs) { return caseInsensitiveCompare(lhs[property], rhs[property]); });
+ }
+ return __spread(input).sort(caseInsensitiveCompare);
+ }
+
+ var urlDecode = function (x) { return x.split('+').map(decodeURIComponent).join(' '); };
+ var urlEncode = function (x) { return x.split(' ').map(encodeURIComponent).join('+'); };
+
+ var join = function (v, arg) { return v.join(arg === undefined ? ' ' : arg); };
+ var last$1 = function (v) { return isArray(v) ? last(v) : ''; };
+ var first = function (v) { return isArray(v) ? v[0] : ''; };
+ var reverse = function (v) { return __spread(v).reverse(); };
+ var sort = function (v, arg) { return v.sort(arg); };
+ var size = function (v) { return (v && v.length) || 0; };
+ function map(arr, arg) {
+ return toArray(arr).map(function (v) { return v[arg]; });
+ }
+ function concat(v, arg) {
+ return toArray(v).concat(arg);
+ }
+ function slice(v, begin, length) {
+ if (length === void 0) { length = 1; }
+ begin = begin < 0 ? v.length + begin : begin;
+ return v.slice(begin, begin + length);
+ }
+ function where(arr, property, expected) {
+ var _this = this;
+ return toArray(arr).filter(function (obj) {
+ var value = _this.context.getFromScope(obj, String(property).split('.'));
+ return expected === undefined ? isTruthy(value) : value === expected;
+ });
+ }
+ function uniq(arr) {
+ var u = {};
+ return (arr || []).filter(function (val) {
+ if (u.hasOwnProperty(String(val)))
+ return false;
+ u[String(val)] = true;
+ return true;
+ });
+ }
+
+ var rFormat = /%([-_0^#:]+)?(\d+)?([EO])?(.)/;
+ var monthNames = [
+ 'January', 'February', 'March', 'April', 'May', 'June', 'July', 'August',
+ 'September', 'October', 'November', 'December'
+ ];
+ var dayNames = [
+ 'Sunday', 'Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday'
+ ];
+ var monthNamesShort = monthNames.map(abbr);
+ var dayNamesShort = dayNames.map(abbr);
+ var suffixes = {
+ 1: 'st',
+ 2: 'nd',
+ 3: 'rd',
+ 'default': 'th'
+ };
+ function abbr(str) {
+ return str.slice(0, 3);
+ }
+ // prototype extensions
+ function daysInMonth(d) {
+ var feb = isLeapYear(d) ? 29 : 28;
+ return [31, feb, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31];
+ }
+ function getDayOfYear(d) {
+ var num = 0;
+ for (var i = 0; i < d.getMonth(); ++i) {
+ num += daysInMonth(d)[i];
+ }
+ return num + d.getDate();
+ }
+ function getWeekOfYear(d, startDay) {
+ // Skip to startDay of this week
+ var now = getDayOfYear(d) + (startDay - d.getDay());
+ // Find the first startDay of the year
+ var jan1 = new Date(d.getFullYear(), 0, 1);
+ var then = (7 - jan1.getDay() + startDay);
+ return String(Math.floor((now - then) / 7) + 1);
+ }
+ function isLeapYear(d) {
+ var year = d.getFullYear();
+ return !!((year & 3) === 0 && (year % 100 || (year % 400 === 0 && year)));
+ }
+ function getSuffix(d) {
+ var str = d.getDate().toString();
+ var index = parseInt(str.slice(-1));
+ return suffixes[index] || suffixes['default'];
+ }
+ function century(d) {
+ return parseInt(d.getFullYear().toString().substring(0, 2), 10);
+ }
+ // default to 0
+ var padWidths = {
+ d: 2,
+ e: 2,
+ H: 2,
+ I: 2,
+ j: 3,
+ k: 2,
+ l: 2,
+ L: 3,
+ m: 2,
+ M: 2,
+ S: 2,
+ U: 2,
+ W: 2
+ };
+ // default to '0'
+ var padChars = {
+ a: ' ',
+ A: ' ',
+ b: ' ',
+ B: ' ',
+ c: ' ',
+ e: ' ',
+ k: ' ',
+ l: ' ',
+ p: ' ',
+ P: ' '
+ };
+ var formatCodes = {
+ a: function (d) { return dayNamesShort[d.getDay()]; },
+ A: function (d) { return dayNames[d.getDay()]; },
+ b: function (d) { return monthNamesShort[d.getMonth()]; },
+ B: function (d) { return monthNames[d.getMonth()]; },
+ c: function (d) { return d.toLocaleString(); },
+ C: function (d) { return century(d); },
+ d: function (d) { return d.getDate(); },
+ e: function (d) { return d.getDate(); },
+ H: function (d) { return d.getHours(); },
+ I: function (d) { return String(d.getHours() % 12 || 12); },
+ j: function (d) { return getDayOfYear(d); },
+ k: function (d) { return d.getHours(); },
+ l: function (d) { return String(d.getHours() % 12 || 12); },
+ L: function (d) { return d.getMilliseconds(); },
+ m: function (d) { return d.getMonth() + 1; },
+ M: function (d) { return d.getMinutes(); },
+ N: function (d, opts) {
+ var width = Number(opts.width) || 9;
+ var str = String(d.getMilliseconds()).substr(0, width);
+ return padEnd(str, width, '0');
+ },
+ p: function (d) { return (d.getHours() < 12 ? 'AM' : 'PM'); },
+ P: function (d) { return (d.getHours() < 12 ? 'am' : 'pm'); },
+ q: function (d) { return getSuffix(d); },
+ s: function (d) { return Math.round(d.valueOf() / 1000); },
+ S: function (d) { return d.getSeconds(); },
+ u: function (d) { return d.getDay() || 7; },
+ U: function (d) { return getWeekOfYear(d, 0); },
+ w: function (d) { return d.getDay(); },
+ W: function (d) { return getWeekOfYear(d, 1); },
+ x: function (d) { return d.toLocaleDateString(); },
+ X: function (d) { return d.toLocaleTimeString(); },
+ y: function (d) { return d.getFullYear().toString().substring(2, 4); },
+ Y: function (d) { return d.getFullYear(); },
+ z: function (d, opts) {
+ var offset = d.getTimezoneOffset();
+ var nOffset = Math.abs(offset);
+ var h = Math.floor(nOffset / 60);
+ var m = nOffset % 60;
+ return (offset > 0 ? '-' : '+') +
+ padStart(h, 2, '0') +
+ (opts.flags[':'] ? ':' : '') +
+ padStart(m, 2, '0');
+ },
+ 't': function () { return '\t'; },
+ 'n': function () { return '\n'; },
+ '%': function () { return '%'; }
+ };
+ formatCodes.h = formatCodes.b;
+ function strftime (d, formatStr) {
+ var output = '';
+ var remaining = formatStr;
+ var match;
+ while ((match = rFormat.exec(remaining))) {
+ output += remaining.slice(0, match.index);
+ remaining = remaining.slice(match.index + match[0].length);
+ output += format(d, match);
+ }
+ return output + remaining;
+ }
+ function format(d, match) {
+ var e_1, _a;
+ 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];
+ var convert = formatCodes[conversion];
+ if (!convert)
+ return input;
+ var flags = {};
+ try {
+ for (var flagStr_1 = __values(flagStr), flagStr_1_1 = flagStr_1.next(); !flagStr_1_1.done; flagStr_1_1 = flagStr_1.next()) {
+ var flag = flagStr_1_1.value;
+ flags[flag] = true;
+ }
+ }
+ catch (e_1_1) { e_1 = { error: e_1_1 }; }
+ finally {
+ try {
+ if (flagStr_1_1 && !flagStr_1_1.done && (_a = flagStr_1.return)) _a.call(flagStr_1);
+ }
+ finally { if (e_1) throw e_1.error; }
+ }
+ var ret = String(convert(d, { flags: flags, width: width, modifier: modifier }));
+ var padChar = padChars[conversion] || '0';
+ var padWidth = width || padWidths[conversion] || 0;
+ if (flags['^'])
+ ret = ret.toUpperCase();
+ else if (flags['#'])
+ ret = changeCase(ret);
+ if (flags['_'])
+ padChar = ' ';
+ else if (flags['0'])
+ padChar = '0';
+ if (flags['-'])
+ padWidth = 0;
+ return padStart(ret, padWidth, padChar);
+ }
+
+ function date(v, arg) {
+ var date = v;
+ if (v === 'now' || v === 'today') {
+ date = new Date();
+ }
+ else if (isNumber(v)) {
+ date = new Date(v * 1000);
+ }
+ else if (isString(v)) {
+ date = /^\d+$/.test(v) ? new Date(+v * 1000) : new Date(v);
+ }
+ return isValidDate(date) ? strftime(date, arg) : v;
+ }
+ function isValidDate(date) {
+ return date instanceof Date && !isNaN(date.getTime());
+ }
+
+ function Default(v, arg) {
+ if (isArray(v) || isString(v))
+ return v.length ? v : arg;
+ return isFalsy(toValue(v)) ? arg : v;
+ }
+ function json(v) {
+ return JSON.stringify(v);
+ }
+
+ /**
+ * String related filters
+ *
+ * * prefer stringify() to String() since `undefined`, `null` should eval ''
+ */
+ function append(v, arg) {
+ assert(arg !== undefined, function () { return 'append expect 2 arguments'; });
+ return stringify(v) + stringify(arg);
+ }
+ function prepend(v, arg) {
+ assert(arg !== undefined, function () { return 'prepend expect 2 arguments'; });
+ return stringify(arg) + stringify(v);
+ }
+ function lstrip(v) {
+ return stringify(v).replace(/^\s+/, '');
+ }
+ function downcase(v) {
+ return stringify(v).toLowerCase();
+ }
+ function upcase(str) {
+ return stringify(str).toUpperCase();
+ }
+ function remove(v, arg) {
+ return stringify(v).split(arg).join('');
+ }
+ function removeFirst(v, l) {
+ return stringify(v).replace(l, '');
+ }
+ function rstrip(str) {
+ return stringify(str).replace(/\s+$/, '');
+ }
+ function split(v, arg) {
+ return stringify(v).split(arg);
+ }
+ function strip(v) {
+ return stringify(v).trim();
+ }
+ function stripNewlines(v) {
+ return stringify(v).replace(/\n/g, '');
+ }
+ function capitalize(str) {
+ str = stringify(str);
+ return str.charAt(0).toUpperCase() + str.slice(1);
+ }
+ function replace(v, pattern, replacement) {
+ return stringify(v).split(pattern).join(replacement);
+ }
+ function replaceFirst(v, arg1, arg2) {
+ return stringify(v).replace(arg1, arg2);
+ }
+ function truncate(v, l, o) {
+ if (l === void 0) { l = 50; }
+ if (o === void 0) { o = '...'; }
+ v = stringify(v);
+ if (v.length <= l)
+ return v;
+ return v.substr(0, l - o.length) + o;
+ }
+ function truncatewords(v, l, o) {
+ if (l === void 0) { l = 15; }
+ if (o === void 0) { o = '...'; }
+ var arr = v.split(/\s+/);
+ var ret = arr.slice(0, l).join(' ');
+ if (arr.length >= l)
+ ret += o;
+ return ret;
+ }
+
+
+
+ var builtinFilters = /*#__PURE__*/Object.freeze({
+ escape: escape,
+ escapeOnce: escapeOnce,
+ newlineToBr: newlineToBr,
+ stripHtml: stripHtml,
+ abs: abs,
+ atLeast: atLeast,
+ atMost: atMost,
+ ceil: ceil,
+ dividedBy: dividedBy,
+ floor: floor,
+ minus: minus,
+ modulo: modulo,
+ times: times,
+ round: round,
+ plus: plus,
+ sortNatural: sortNatural,
+ urlDecode: urlDecode,
+ urlEncode: urlEncode,
+ join: join,
+ last: last$1,
+ first: first,
+ reverse: reverse,
+ sort: sort,
+ size: size,
+ map: map,
+ concat: concat,
+ slice: slice,
+ where: where,
+ uniq: uniq,
+ date: date,
+ Default: Default,
+ json: json,
+ append: append,
+ prepend: prepend,
+ lstrip: lstrip,
+ downcase: downcase,
+ upcase: upcase,
+ remove: remove,
+ removeFirst: removeFirst,
+ rstrip: rstrip,
+ split: split,
+ strip: strip,
+ stripNewlines: stripNewlines,
+ capitalize: capitalize,
+ replace: replace,
+ replaceFirst: replaceFirst,
+ truncate: truncate,
+ truncatewords: truncatewords
+ });
+
+ var TagMap = /** @class */ (function () {
+ function TagMap() {
+ this.impls = {};
+ }
+ TagMap.prototype.get = function (name) {
+ var impl = this.impls[name];
+ assert(impl, function () { return "tag \"" + name + "\" not found"; });
+ return impl;
+ };
+ TagMap.prototype.set = function (name, impl) {
+ this.impls[name] = impl;
+ };
+ return TagMap;
+ }());
+
+ var FilterMap = /** @class */ (function () {
+ function FilterMap(strictFilters) {
+ this.strictFilters = strictFilters;
+ this.impls = {};
+ }
+ FilterMap.prototype.get = function (name) {
+ var impl = this.impls[name];
+ assert(impl || !this.strictFilters, function () { return "undefined filter: " + name; });
+ return impl;
+ };
+ FilterMap.prototype.set = function (name, impl) {
+ this.impls[name] = impl;
+ };
+ FilterMap.prototype.create = function (name, args) {
+ return new Filter(name, this.get(name), args);
+ };
+ return FilterMap;
+ }());
+
+ function mkResolve(value) {
+ var ret = {
+ then: function (resolve) { return resolve(value); },
+ catch: function () { return ret; }
+ };
+ return ret;
+ }
+ function mkReject(err) {
+ var ret = {
+ then: function (resolve, reject) {
+ if (reject)
+ return reject(err);
+ return ret;
+ },
+ catch: function (reject) { return reject(err); }
+ };
+ return ret;
+ }
+ function isThenable(val) {
+ return val && isFunction(val.then);
+ }
+ function isCustomIterable(val) {
+ return val && isFunction(val.next) && isFunction(val.throw) && isFunction(val.return);
+ }
+ function toThenable(val) {
+ if (isThenable(val))
+ return val;
+ if (isCustomIterable(val))
+ return reduce();
+ return mkResolve(val);
+ function reduce(prev) {
+ var state;
+ try {
+ state = val.next(prev);
+ }
+ catch (err) {
+ return mkReject(err);
+ }
+ if (state.done)
+ return mkResolve(state.value);
+ return toThenable(state.value).then(reduce, function (err) {
+ var state;
+ try {
+ state = val.throw(err);
+ }
+ catch (e) {
+ return mkReject(e);
+ }
+ if (state.done)
+ return mkResolve(state.value);
+ return reduce(state.value);
+ });
+ }
+ }
+ function toValue$1(val) {
+ var ret;
+ toThenable(val)
+ .then(function (x) {
+ ret = x;
+ return mkResolve(ret);
+ })
+ .catch(function (err) {
+ throw err;
+ });
+ return ret;
+ }
+
+ var Liquid = /** @class */ (function () {
+ function Liquid(opts) {
+ var _this = this;
+ if (opts === void 0) { opts = {}; }
+ this.options = applyDefault(normalize(opts));
+ this.parser = new Parser(this);
+ this.renderer = new Render();
+ this.fs = opts.fs || fs;
+ this.filters = new FilterMap(this.options.strictFilters);
+ this.tags = new TagMap();
+ forOwn(tags, function (conf, name) { return _this.registerTag(snakeCase(name), conf); });
+ forOwn(builtinFilters, function (handler, name) { return _this.registerFilter(snakeCase(name), handler); });
+ }
+ Liquid.prototype.parse = function (html, filepath) {
+ var tokenizer = new Tokenizer(html, filepath);
+ var tokens = tokenizer.readTopLevelTokens(this.options);
+ return this.parser.parse(tokens);
+ };
+ Liquid.prototype._render = function (tpl, scope, opts, sync) {
+ var options = __assign({}, this.options, normalize(opts));
+ var ctx = new Context(scope, options, sync);
+ return this.renderer.renderTemplates(tpl, ctx);
+ };
+ Liquid.prototype.render = function (tpl, scope, opts) {
+ return __awaiter(this, void 0, void 0, function () {
+ return __generator(this, function (_a) {
+ return [2 /*return*/, toThenable(this._render(tpl, scope, opts, false))];
+ });
+ });
+ };
+ Liquid.prototype.renderSync = function (tpl, scope, opts) {
+ return toValue$1(this._render(tpl, scope, opts, true));
+ };
+ Liquid.prototype._parseAndRender = function (html, scope, opts, sync) {
+ var tpl = this.parse(html);
+ return this._render(tpl, scope, opts, sync);
+ };
+ Liquid.prototype.parseAndRender = function (html, scope, opts) {
+ return __awaiter(this, void 0, void 0, function () {
+ return __generator(this, function (_a) {
+ return [2 /*return*/, toThenable(this._parseAndRender(html, scope, opts, false))];
+ });
+ });
+ };
+ Liquid.prototype.parseAndRenderSync = function (html, scope, opts) {
+ return toValue$1(this._parseAndRender(html, scope, opts, true));
+ };
+ Liquid.prototype._parseFile = function (file, opts, sync) {
+ var options, paths, filepath, paths_1, paths_1_1, filepath, cache, tpls, _a, tpl, _b, _c, e_1_1;
+ var e_1, _d;
+ var _this = this;
+ return __generator(this, function (_e) {
+ switch (_e.label) {
+ case 0:
+ options = __assign({}, this.options, normalize(opts));
+ paths = options.root.map(function (root) { return _this.fs.resolve(root, file, options.extname); });
+ if (this.fs.fallback !== undefined) {
+ filepath = this.fs.fallback(file);
+ if (filepath !== undefined)
+ paths.push(filepath);
+ }
+ _e.label = 1;
+ case 1:
+ _e.trys.push([1, 13, 14, 15]);
+ paths_1 = __values(paths), paths_1_1 = paths_1.next();
+ _e.label = 2;
+ case 2:
+ if (!!paths_1_1.done) return [3 /*break*/, 12];
+ filepath = paths_1_1.value;
+ cache = options.cache;
+ if (!cache) return [3 /*break*/, 4];
+ return [4 /*yield*/, cache.read(filepath)];
+ case 3:
+ tpls = _e.sent();
+ if (tpls)
+ return [2 /*return*/, tpls];
+ _e.label = 4;
+ case 4:
+ if (!sync) return [3 /*break*/, 5];
+ _a = this.fs.existsSync(filepath);
+ return [3 /*break*/, 7];
+ case 5: return [4 /*yield*/, this.fs.exists(filepath)];
+ case 6:
+ _a = _e.sent();
+ _e.label = 7;
+ case 7:
+ if (!(_a))
+ return [3 /*break*/, 11];
+ _b = this.parse;
+ if (!sync) return [3 /*break*/, 8];
+ _c = this.fs.readFileSync(filepath);
+ return [3 /*break*/, 10];
+ case 8: return [4 /*yield*/, this.fs.readFile(filepath)];
+ case 9:
+ _c = _e.sent();
+ _e.label = 10;
+ case 10:
+ tpl = _b.apply(this, [_c, filepath]);
+ if (cache)
+ cache.write(filepath, tpl);
+ return [2 /*return*/, tpl];
+ case 11:
+ paths_1_1 = paths_1.next();
+ return [3 /*break*/, 2];
+ case 12: return [3 /*break*/, 15];
+ case 13:
+ e_1_1 = _e.sent();
+ e_1 = { error: e_1_1 };
+ return [3 /*break*/, 15];
+ case 14:
+ try {
+ if (paths_1_1 && !paths_1_1.done && (_d = paths_1.return)) _d.call(paths_1);
+ }
+ finally { if (e_1) throw e_1.error; }
+ return [7 /*endfinally*/];
+ case 15: throw this.lookupError(file, options.root);
+ }
+ });
+ };
+ Liquid.prototype.parseFile = function (file, opts) {
+ return __awaiter(this, void 0, void 0, function () {
+ return __generator(this, function (_a) {
+ return [2 /*return*/, toThenable(this._parseFile(file, opts, false))];
+ });
+ });
+ };
+ Liquid.prototype.parseFileSync = function (file, opts) {
+ return toValue$1(this._parseFile(file, opts, true));
+ };
+ Liquid.prototype.renderFile = function (file, ctx, opts) {
+ return __awaiter(this, void 0, void 0, function () {
+ var templates;
+ return __generator(this, function (_a) {
+ switch (_a.label) {
+ case 0: return [4 /*yield*/, this.parseFile(file, opts)];
+ case 1:
+ templates = _a.sent();
+ return [2 /*return*/, this.render(templates, ctx, opts)];
+ }
+ });
+ });
+ };
+ Liquid.prototype.renderFileSync = function (file, ctx, opts) {
+ var options = normalize(opts);
+ var templates = this.parseFileSync(file, options);
+ return this.renderSync(templates, ctx, opts);
+ };
+ Liquid.prototype._evalValue = function (str, ctx) {
+ var value = new Value(str, this.filters);
+ return value.value(ctx);
+ };
+ Liquid.prototype.evalValue = function (str, ctx) {
+ return __awaiter(this, void 0, void 0, function () {
+ return __generator(this, function (_a) {
+ return [2 /*return*/, toThenable(this._evalValue(str, ctx))];
+ });
+ });
+ };
+ Liquid.prototype.evalValueSync = function (str, ctx) {
+ return toValue$1(this._evalValue(str, ctx));
+ };
+ Liquid.prototype.registerFilter = function (name, filter) {
+ this.filters.set(name, filter);
+ };
+ Liquid.prototype.registerTag = function (name, tag) {
+ this.tags.set(name, tag);
+ };
+ Liquid.prototype.plugin = function (plugin) {
+ return plugin.call(this, Liquid);
+ };
+ Liquid.prototype.express = function () {
+ var self = this; // eslint-disable-line
+ return function (filePath, ctx, callback) {
+ var opts = { root: __spread(normalizeStringArray(this.root), self.options.root) };
+ self.renderFile(filePath, ctx, opts).then(function (html) { return callback(null, html); }, callback);
+ };
+ };
+ Liquid.prototype.lookupError = function (file, roots) {
+ var err = new Error('ENOENT');
+ err.message = "ENOENT: Failed to lookup \"" + file + "\" in \"" + roots + "\"";
+ err.code = 'ENOENT';
+ return err;
+ };
+ /**
+ * @deprecated use parseFile instead
+ */
+ Liquid.prototype.getTemplate = function (file, opts) {
+ return __awaiter(this, void 0, void 0, function () {
+ return __generator(this, function (_a) {
+ return [2 /*return*/, this.parseFile(file, opts)];
+ });
+ });
+ };
+ /**
+ * @deprecated use parseFileSync instead
+ */
+ Liquid.prototype.getTemplateSync = function (file, opts) {
+ return this.parseFileSync(file, opts);
+ };
+ return Liquid;
+ }());
+
+ exports.AssertionError = AssertionError;
+ exports.Context = Context;
+ exports.Drop = Drop;
+ exports.Emitter = Emitter;
+ exports.Expression = Expression;
+ exports.Hash = Hash;
+ exports.Liquid = Liquid;
+ exports.ParseError = ParseError;
+ exports.ParseStream = ParseStream;
+ exports.TagToken = TagToken;
+ exports.Token = Token;
+ exports.TokenizationError = TokenizationError;
+ exports.Tokenizer = Tokenizer;
+ exports.TypeGuards = typeGuards;
+ exports.assert = assert;
+ exports.evalQuotedToken = evalQuotedToken;
+ exports.evalToken = evalToken;
+ exports.isFalsy = isFalsy;
+ exports.isTruthy = isTruthy;
+
+ Object.defineProperty(exports, '__esModule', { value: true });
+
+}));
+//# sourceMappingURL=liquid.js.map