{"version":3,"file":"liquidjs.js","sources":["../../../node_modules/liquidjs/dist/liquid.browser.esm.js"],"sourcesContent":["/*\n * liquidjs@10.9.1, https://github.com/harttle/liquidjs\n * (c) 2016-2023 harttle\n * Released under the MIT License.\n */\nclass Token {\r\n constructor(kind, input, begin, end, file) {\r\n this.kind = kind;\r\n this.input = input;\r\n this.begin = begin;\r\n this.end = end;\r\n this.file = file;\r\n }\r\n getText() {\r\n return this.input.slice(this.begin, this.end);\r\n }\r\n getPosition() {\r\n let [row, col] = [1, 1];\r\n for (let i = 0; i < this.begin; i++) {\r\n if (this.input[i] === '\\n') {\r\n row++;\r\n col = 1;\r\n }\r\n else\r\n col++;\r\n }\r\n return [row, col];\r\n }\r\n size() {\r\n return this.end - this.begin;\r\n }\r\n}\n\nclass Drop {\r\n liquidMethodMissing(key) {\r\n return undefined;\r\n }\r\n}\n\nconst toString$1 = Object.prototype.toString;\r\nconst toLowerCase = String.prototype.toLowerCase;\r\nconst hasOwnProperty = Object.hasOwnProperty;\r\nfunction isString(value) {\r\n return typeof value === 'string';\r\n}\r\n// eslint-disable-next-line @typescript-eslint/ban-types\r\nfunction isFunction(value) {\r\n return typeof value === 'function';\r\n}\r\nfunction isPromise(val) {\r\n return val && isFunction(val.then);\r\n}\r\nfunction isIterator(val) {\r\n return val && isFunction(val.next) && isFunction(val.throw) && isFunction(val.return);\r\n}\r\nfunction escapeRegex(str) {\r\n return str.replace(/[-/\\\\^$*+?.()|[\\]{}]/g, '\\\\$&');\r\n}\r\nfunction stringify(value) {\r\n value = toValue(value);\r\n if (isString(value))\r\n return value;\r\n if (isNil(value))\r\n return '';\r\n if (isArray(value))\r\n return value.map(x => stringify(x)).join('');\r\n return String(value);\r\n}\r\nfunction toValue(value) {\r\n return (value instanceof Drop && isFunction(value.valueOf)) ? value.valueOf() : value;\r\n}\r\nfunction isNumber(value) {\r\n return typeof value === 'number';\r\n}\r\nfunction toLiquid(value) {\r\n if (value && isFunction(value.toLiquid))\r\n return toLiquid(value.toLiquid());\r\n return value;\r\n}\r\nfunction isNil(value) {\r\n return value == null;\r\n}\r\nfunction isUndefined(value) {\r\n return value === undefined;\r\n}\r\nfunction isArray(value) {\r\n // be compatible with IE 8\r\n return toString$1.call(value) === '[object Array]';\r\n}\r\nfunction isIterable(value) {\r\n return isObject(value) && Symbol.iterator in value;\r\n}\r\n/*\r\n * Iterates over own enumerable string keyed properties of an object and invokes iteratee for each property.\r\n * The iteratee is invoked with three arguments: (value, key, object).\r\n * Iteratee functions may exit iteration early by explicitly returning false.\r\n * @param {Object} object The object to iterate over.\r\n * @param {Function} iteratee The function invoked per iteration.\r\n * @return {Object} Returns object.\r\n */\r\nfunction forOwn(obj, iteratee) {\r\n obj = obj || {};\r\n for (const k in obj) {\r\n if (hasOwnProperty.call(obj, k)) {\r\n if (iteratee(obj[k], k, obj) === false)\r\n break;\r\n }\r\n }\r\n return obj;\r\n}\r\nfunction last(arr) {\r\n return arr[arr.length - 1];\r\n}\r\n/*\r\n * Checks if value is the language type of Object.\r\n * (e.g. arrays, functions, objects, regexes, new Number(0), and new String(''))\r\n * @param {any} value The value to check.\r\n * @return {Boolean} Returns true if value is an object, else false.\r\n */\r\nfunction isObject(value) {\r\n const type = typeof value;\r\n return value !== null && (type === 'object' || type === 'function');\r\n}\r\nfunction range(start, stop, step = 1) {\r\n const arr = [];\r\n for (let i = start; i < stop; i += step) {\r\n arr.push(i);\r\n }\r\n return arr;\r\n}\r\nfunction padStart(str, length, ch = ' ') {\r\n return pad(str, length, ch, (str, ch) => ch + str);\r\n}\r\nfunction padEnd(str, length, ch = ' ') {\r\n return pad(str, length, ch, (str, ch) => str + ch);\r\n}\r\nfunction pad(str, length, ch, add) {\r\n str = String(str);\r\n let n = length - str.length;\r\n while (n-- > 0)\r\n str = add(str, ch);\r\n return str;\r\n}\r\nfunction identify(val) {\r\n return val;\r\n}\r\nfunction changeCase(str) {\r\n const hasLowerCase = [...str].some(ch => ch >= 'a' && ch <= 'z');\r\n return hasLowerCase ? str.toUpperCase() : str.toLowerCase();\r\n}\r\nfunction ellipsis(str, N) {\r\n return str.length > N ? str.slice(0, N - 3) + '...' : str;\r\n}\r\n// compare string in case-insensitive way, undefined values to the tail\r\nfunction caseInsensitiveCompare(a, b) {\r\n if (a == null && b == null)\r\n return 0;\r\n if (a == null)\r\n return 1;\r\n if (b == null)\r\n return -1;\r\n a = toLowerCase.call(a);\r\n b = toLowerCase.call(b);\r\n if (a < b)\r\n return -1;\r\n if (a > b)\r\n return 1;\r\n return 0;\r\n}\r\nfunction argumentsToValue(fn) {\r\n return (...args) => fn(...args.map(toValue));\r\n}\r\nfunction escapeRegExp(text) {\r\n return text.replace(/[-[\\]{}()*+?.,\\\\^$|#\\s]/g, '\\\\$&');\r\n}\n\n/**\r\n * targeting ES5, extends Error won't create a proper prototype chain, need a trait to kee track of classes\r\n */\r\nconst TRAIT = '__liquidClass__';\r\nclass LiquidError extends Error {\r\n constructor(err, token) {\r\n /**\r\n * note: for ES5 targeting, `this` will be replaced by return value of Error(),\r\n * thus everything on `this` will be lost, avoid calling `LiquidError` methods here\r\n */\r\n super(typeof err === 'string' ? err : err.message);\r\n this.context = '';\r\n if (typeof err !== 'string')\r\n Object.defineProperty(this, 'originalError', { value: err, enumerable: false });\r\n Object.defineProperty(this, 'token', { value: token, enumerable: false });\r\n Object.defineProperty(this, TRAIT, { value: 'LiquidError', enumerable: false });\r\n }\r\n update() {\r\n Object.defineProperty(this, 'context', { value: mkContext(this.token), enumerable: false });\r\n this.message = mkMessage(this.message, this.token);\r\n this.stack = this.message + '\\n' + this.context +\r\n '\\n' + this.stack;\r\n if (this.originalError)\r\n this.stack += '\\nFrom ' + this.originalError.stack;\r\n }\r\n static is(obj) {\r\n return (obj === null || obj === void 0 ? void 0 : obj[TRAIT]) === 'LiquidError';\r\n }\r\n}\r\nclass TokenizationError extends LiquidError {\r\n constructor(message, token) {\r\n super(message, token);\r\n this.name = 'TokenizationError';\r\n super.update();\r\n }\r\n}\r\nclass ParseError extends LiquidError {\r\n constructor(err, token) {\r\n super(err, token);\r\n this.name = 'ParseError';\r\n this.message = err.message;\r\n super.update();\r\n }\r\n}\r\nclass RenderError extends LiquidError {\r\n constructor(err, tpl) {\r\n super(err, tpl.token);\r\n this.name = 'RenderError';\r\n this.message = err.message;\r\n super.update();\r\n }\r\n static is(obj) {\r\n return obj.name === 'RenderError';\r\n }\r\n}\r\nclass UndefinedVariableError extends LiquidError {\r\n constructor(err, token) {\r\n super(err, token);\r\n this.name = 'UndefinedVariableError';\r\n this.message = err.message;\r\n super.update();\r\n }\r\n}\r\n// only used internally; raised where we don't have token information,\r\n// so it can't be an UndefinedVariableError.\r\nclass InternalUndefinedVariableError extends Error {\r\n constructor(variableName) {\r\n super(`undefined variable: ${variableName}`);\r\n this.name = 'InternalUndefinedVariableError';\r\n this.variableName = variableName;\r\n }\r\n}\r\nclass AssertionError extends Error {\r\n constructor(message) {\r\n super(message);\r\n this.name = 'AssertionError';\r\n this.message = message + '';\r\n }\r\n}\r\nfunction mkContext(token) {\r\n const [line, col] = token.getPosition();\r\n const lines = token.input.split('\\n');\r\n const begin = Math.max(line - 2, 1);\r\n const end = Math.min(line + 3, lines.length);\r\n const context = range(begin, end + 1)\r\n .map(lineNumber => {\r\n const rowIndicator = (lineNumber === line) ? '>> ' : ' ';\r\n const num = padStart(String(lineNumber), String(end).length);\r\n let text = `${rowIndicator}${num}| `;\r\n const colIndicator = lineNumber === line\r\n ? '\\n' + padStart('^', col + text.length)\r\n : '';\r\n text += lines[lineNumber - 1];\r\n text += colIndicator;\r\n return text;\r\n })\r\n .join('\\n');\r\n return context;\r\n}\r\nfunction mkMessage(msg, token) {\r\n if (token.file)\r\n msg += `, file:${token.file}`;\r\n const [line, col] = token.getPosition();\r\n msg += `, line:${line}, col:${col}`;\r\n return msg;\r\n}\n\n// **DO NOT CHANGE THIS FILE**\r\n//\r\n// This file is generated by bin/character-gen.js\r\n// bitmask character types to boost performance\r\nconst 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];\r\nconst IDENTIFIER = 1;\r\nconst BLANK = 4;\r\nconst QUOTE = 8;\r\nconst INLINE_BLANK = 16;\r\nconst NUMBER = 32;\r\nconst SIGN = 64;\r\nTYPES[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;\n\nfunction assert(predicate, message) {\r\n if (!predicate) {\r\n const msg = typeof message === 'function'\r\n ? message()\r\n : (message || `expect ${predicate} to be true`);\r\n throw new AssertionError(msg);\r\n }\r\n}\n\nclass NullDrop extends Drop {\r\n equals(value) {\r\n return isNil(toValue(value));\r\n }\r\n gt() {\r\n return false;\r\n }\r\n geq() {\r\n return false;\r\n }\r\n lt() {\r\n return false;\r\n }\r\n leq() {\r\n return false;\r\n }\r\n valueOf() {\r\n return null;\r\n }\r\n}\n\nclass EmptyDrop extends Drop {\r\n equals(value) {\r\n if (value instanceof EmptyDrop)\r\n return false;\r\n value = toValue(value);\r\n if (isString(value) || isArray(value))\r\n return value.length === 0;\r\n if (isObject(value))\r\n return Object.keys(value).length === 0;\r\n return false;\r\n }\r\n gt() {\r\n return false;\r\n }\r\n geq() {\r\n return false;\r\n }\r\n lt() {\r\n return false;\r\n }\r\n leq() {\r\n return false;\r\n }\r\n valueOf() {\r\n return '';\r\n }\r\n}\n\nclass BlankDrop extends EmptyDrop {\r\n equals(value) {\r\n if (value === false)\r\n return true;\r\n if (isNil(toValue(value)))\r\n return true;\r\n if (isString(value))\r\n return /^\\s*$/.test(value);\r\n return super.equals(value);\r\n }\r\n}\n\nclass ForloopDrop extends Drop {\r\n constructor(length, collection, variable) {\r\n super();\r\n this.i = 0;\r\n this.length = length;\r\n this.name = `${variable}-${collection}`;\r\n }\r\n next() {\r\n this.i++;\r\n }\r\n index0() {\r\n return this.i;\r\n }\r\n index() {\r\n return this.i + 1;\r\n }\r\n first() {\r\n return this.i === 0;\r\n }\r\n last() {\r\n return this.i === this.length - 1;\r\n }\r\n rindex() {\r\n return this.length - this.i;\r\n }\r\n rindex0() {\r\n return this.length - this.i - 1;\r\n }\r\n valueOf() {\r\n return JSON.stringify(this);\r\n }\r\n}\n\nclass BlockDrop extends Drop {\r\n constructor(\r\n // the block render from layout template\r\n superBlockRender = () => '') {\r\n super();\r\n this.superBlockRender = superBlockRender;\r\n }\r\n /**\r\n * Provide parent access in child block by\r\n * {{ block.super }}\r\n */\r\n super() {\r\n return this.superBlockRender();\r\n }\r\n}\n\nfunction isComparable(arg) {\r\n return arg && isFunction(arg.equals);\r\n}\n\nconst nil = new NullDrop();\r\nconst literalValues = {\r\n 'true': true,\r\n 'false': false,\r\n 'nil': nil,\r\n 'null': nil,\r\n 'empty': new EmptyDrop(),\r\n 'blank': new BlankDrop()\r\n};\n\nfunction createTrie(input) {\r\n const trie = {};\r\n for (const [name, data] of Object.entries(input)) {\r\n let node = trie;\r\n for (let i = 0; i < name.length; i++) {\r\n const c = name[i];\r\n node[c] = node[c] || {};\r\n if (i === name.length - 1 && (TYPES[name.charCodeAt(i)] & IDENTIFIER)) {\r\n node[c].needBoundary = true;\r\n }\r\n node = node[c];\r\n }\r\n node.data = data;\r\n node.end = true;\r\n }\r\n return trie;\r\n}\n\n/******************************************************************************\r\nCopyright (c) Microsoft Corporation.\r\n\r\nPermission to use, copy, modify, and/or distribute this software for any\r\npurpose with or without fee is hereby granted.\r\n\r\nTHE SOFTWARE IS PROVIDED \"AS IS\" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH\r\nREGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY\r\nAND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,\r\nINDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM\r\nLOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR\r\nOTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR\r\nPERFORMANCE OF THIS SOFTWARE.\r\n***************************************************************************** */\r\n\r\nvar __assign = function() {\r\n __assign = Object.assign || function __assign(t) {\r\n for (var s, i = 1, n = arguments.length; i < n; i++) {\r\n s = arguments[i];\r\n for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p)) t[p] = s[p];\r\n }\r\n return t;\r\n };\r\n return __assign.apply(this, arguments);\r\n};\r\n\r\nfunction __awaiter(thisArg, _arguments, P, generator) {\r\n function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }\r\n return new (P || (P = Promise))(function (resolve, reject) {\r\n function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }\r\n function rejected(value) { try { step(generator[\"throw\"](value)); } catch (e) { reject(e); } }\r\n function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }\r\n step((generator = generator.apply(thisArg, _arguments || [])).next());\r\n });\r\n}\n\n// convert an async iterator to a Promise\r\nfunction toPromise(val) {\r\n return __awaiter(this, void 0, void 0, function* () {\r\n if (!isIterator(val))\r\n return val;\r\n let value;\r\n let done = false;\r\n let next = 'next';\r\n do {\r\n const state = val[next](value);\r\n done = state.done;\r\n value = state.value;\r\n next = 'next';\r\n try {\r\n if (isIterator(value))\r\n value = toPromise(value);\r\n if (isPromise(value))\r\n value = yield value;\r\n }\r\n catch (err) {\r\n next = 'throw';\r\n value = err;\r\n }\r\n } while (!done);\r\n return value;\r\n });\r\n}\r\n// convert an async iterator to a value in a synchronous manner\r\nfunction toValueSync(val) {\r\n if (!isIterator(val))\r\n return val;\r\n let value;\r\n let done = false;\r\n let next = 'next';\r\n do {\r\n const state = val[next](value);\r\n done = state.done;\r\n value = state.value;\r\n next = 'next';\r\n if (isIterator(value)) {\r\n try {\r\n value = toValueSync(value);\r\n }\r\n catch (err) {\r\n next = 'throw';\r\n value = err;\r\n }\r\n }\r\n } while (!done);\r\n return value;\r\n}\n\nfunction toEnumerable(val) {\r\n val = toValue(val);\r\n if (isArray(val))\r\n return val;\r\n if (isString(val) && val.length > 0)\r\n return [val];\r\n if (isIterable(val))\r\n return Array.from(val);\r\n if (isObject(val))\r\n return Object.keys(val).map((key) => [key, val[key]]);\r\n return [];\r\n}\r\nfunction toArray(val) {\r\n if (isNil(val))\r\n return [];\r\n if (isArray(val))\r\n return val;\r\n return [val];\r\n}\n\nconst rFormat = /%([-_0^#:]+)?(\\d+)?([EO])?(.)/;\r\nconst monthNames = [\r\n 'January', 'February', 'March', 'April', 'May', 'June', 'July', 'August',\r\n 'September', 'October', 'November', 'December'\r\n];\r\nconst dayNames = [\r\n 'Sunday', 'Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday'\r\n];\r\nconst monthNamesShort = monthNames.map(abbr);\r\nconst dayNamesShort = dayNames.map(abbr);\r\nfunction abbr(str) {\r\n return str.slice(0, 3);\r\n}\r\n// prototype extensions\r\nfunction daysInMonth(d) {\r\n const feb = isLeapYear(d) ? 29 : 28;\r\n return [31, feb, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31];\r\n}\r\nfunction getDayOfYear(d) {\r\n let num = 0;\r\n for (let i = 0; i < d.getMonth(); ++i) {\r\n num += daysInMonth(d)[i];\r\n }\r\n return num + d.getDate();\r\n}\r\nfunction getWeekOfYear(d, startDay) {\r\n // Skip to startDay of this week\r\n const now = getDayOfYear(d) + (startDay - d.getDay());\r\n // Find the first startDay of the year\r\n const jan1 = new Date(d.getFullYear(), 0, 1);\r\n const then = (7 - jan1.getDay() + startDay);\r\n return String(Math.floor((now - then) / 7) + 1);\r\n}\r\nfunction isLeapYear(d) {\r\n const year = d.getFullYear();\r\n return !!((year & 3) === 0 && (year % 100 || (year % 400 === 0 && year)));\r\n}\r\nfunction getSuffix(d) {\r\n const date = d.getDate();\r\n let suffix = 'th';\r\n switch (date) {\r\n case 11:\r\n case 12:\r\n case 13:\r\n break;\r\n default:\r\n switch (date % 10) {\r\n case 1:\r\n suffix = 'st';\r\n break;\r\n case 2:\r\n suffix = 'nd';\r\n break;\r\n case 3:\r\n suffix = 'rd';\r\n break;\r\n }\r\n }\r\n return suffix;\r\n}\r\nfunction century(d) {\r\n return parseInt(d.getFullYear().toString().substring(0, 2), 10);\r\n}\r\n// default to 0\r\nconst padWidths = {\r\n d: 2,\r\n e: 2,\r\n H: 2,\r\n I: 2,\r\n j: 3,\r\n k: 2,\r\n l: 2,\r\n L: 3,\r\n m: 2,\r\n M: 2,\r\n S: 2,\r\n U: 2,\r\n W: 2\r\n};\r\n// default to '0'\r\nconst padChars = {\r\n a: ' ',\r\n A: ' ',\r\n b: ' ',\r\n B: ' ',\r\n c: ' ',\r\n e: ' ',\r\n k: ' ',\r\n l: ' ',\r\n p: ' ',\r\n P: ' '\r\n};\r\nconst formatCodes = {\r\n a: (d) => dayNamesShort[d.getDay()],\r\n A: (d) => dayNames[d.getDay()],\r\n b: (d) => monthNamesShort[d.getMonth()],\r\n B: (d) => monthNames[d.getMonth()],\r\n c: (d) => d.toLocaleString(),\r\n C: (d) => century(d),\r\n d: (d) => d.getDate(),\r\n e: (d) => d.getDate(),\r\n H: (d) => d.getHours(),\r\n I: (d) => String(d.getHours() % 12 || 12),\r\n j: (d) => getDayOfYear(d),\r\n k: (d) => d.getHours(),\r\n l: (d) => String(d.getHours() % 12 || 12),\r\n L: (d) => d.getMilliseconds(),\r\n m: (d) => d.getMonth() + 1,\r\n M: (d) => d.getMinutes(),\r\n N: (d, opts) => {\r\n const width = Number(opts.width) || 9;\r\n const str = String(d.getMilliseconds()).slice(0, width);\r\n return padEnd(str, width, '0');\r\n },\r\n p: (d) => (d.getHours() < 12 ? 'AM' : 'PM'),\r\n P: (d) => (d.getHours() < 12 ? 'am' : 'pm'),\r\n q: (d) => getSuffix(d),\r\n s: (d) => Math.round(d.getTime() / 1000),\r\n S: (d) => d.getSeconds(),\r\n u: (d) => d.getDay() || 7,\r\n U: (d) => getWeekOfYear(d, 0),\r\n w: (d) => d.getDay(),\r\n W: (d) => getWeekOfYear(d, 1),\r\n x: (d) => d.toLocaleDateString(),\r\n X: (d) => d.toLocaleTimeString(),\r\n y: (d) => d.getFullYear().toString().slice(2, 4),\r\n Y: (d) => d.getFullYear(),\r\n z: (d, opts) => {\r\n const nOffset = Math.abs(d.getTimezoneOffset());\r\n const h = Math.floor(nOffset / 60);\r\n const m = nOffset % 60;\r\n return (d.getTimezoneOffset() > 0 ? '-' : '+') +\r\n padStart(h, 2, '0') +\r\n (opts.flags[':'] ? ':' : '') +\r\n padStart(m, 2, '0');\r\n },\r\n 't': () => '\\t',\r\n 'n': () => '\\n',\r\n '%': () => '%'\r\n};\r\nformatCodes.h = formatCodes.b;\r\nfunction strftime(d, formatStr) {\r\n let output = '';\r\n let remaining = formatStr;\r\n let match;\r\n while ((match = rFormat.exec(remaining))) {\r\n output += remaining.slice(0, match.index);\r\n remaining = remaining.slice(match.index + match[0].length);\r\n output += format(d, match);\r\n }\r\n return output + remaining;\r\n}\r\nfunction format(d, match) {\r\n const [input, flagStr = '', width, modifier, conversion] = match;\r\n const convert = formatCodes[conversion];\r\n if (!convert)\r\n return input;\r\n const flags = {};\r\n for (const flag of flagStr)\r\n flags[flag] = true;\r\n let ret = String(convert(d, { flags, width, modifier }));\r\n let padChar = padChars[conversion] || '0';\r\n let padWidth = width || padWidths[conversion] || 0;\r\n if (flags['^'])\r\n ret = ret.toUpperCase();\r\n else if (flags['#'])\r\n ret = changeCase(ret);\r\n if (flags['_'])\r\n padChar = ' ';\r\n else if (flags['0'])\r\n padChar = '0';\r\n if (flags['-'])\r\n padWidth = 0;\r\n return padStart(ret, padWidth, padChar);\r\n}\n\n// one minute in milliseconds\r\nconst OneMinute = 60000;\r\nconst ISO8601_TIMEZONE_PATTERN = /([zZ]|([+-])(\\d{2}):(\\d{2}))$/;\r\n/**\r\n * A date implementation with timezone info, just like Ruby date\r\n *\r\n * Implementation:\r\n * - create a Date offset by it's timezone difference, avoiding overriding a bunch of methods\r\n * - rewrite getTimezoneOffset() to trick strftime\r\n */\r\nclass TimezoneDate {\r\n constructor(init, timezoneOffset) {\r\n this.date = init instanceof TimezoneDate\r\n ? init.date\r\n : new Date(init);\r\n this.timezoneOffset = timezoneOffset;\r\n const diff = (this.date.getTimezoneOffset() - this.timezoneOffset) * OneMinute;\r\n const time = this.date.getTime() + diff;\r\n this.displayDate = new Date(time);\r\n }\r\n getTime() {\r\n return this.displayDate.getTime();\r\n }\r\n getMilliseconds() {\r\n return this.displayDate.getMilliseconds();\r\n }\r\n getSeconds() {\r\n return this.displayDate.getSeconds();\r\n }\r\n getMinutes() {\r\n return this.displayDate.getMinutes();\r\n }\r\n getHours() {\r\n return this.displayDate.getHours();\r\n }\r\n getDay() {\r\n return this.displayDate.getDay();\r\n }\r\n getDate() {\r\n return this.displayDate.getDate();\r\n }\r\n getMonth() {\r\n return this.displayDate.getMonth();\r\n }\r\n getFullYear() {\r\n return this.displayDate.getFullYear();\r\n }\r\n toLocaleString(locale, init) {\r\n if (init === null || init === void 0 ? void 0 : init.timeZone) {\r\n return this.date.toLocaleString(locale, init);\r\n }\r\n return this.displayDate.toLocaleString(locale, init);\r\n }\r\n toLocaleTimeString(locale) {\r\n return this.displayDate.toLocaleTimeString(locale);\r\n }\r\n toLocaleDateString(locale) {\r\n return this.displayDate.toLocaleDateString(locale);\r\n }\r\n getTimezoneOffset() {\r\n return this.timezoneOffset;\r\n }\r\n /**\r\n * Create a Date object fixed to it's declared Timezone. Both\r\n * - 2021-08-06T02:29:00.000Z and\r\n * - 2021-08-06T02:29:00.000+08:00\r\n * will always be displayed as\r\n * - 2021-08-06 02:29:00\r\n * regardless timezoneOffset in JavaScript realm\r\n *\r\n * The implementation hack:\r\n * Instead of calling `.getMonth()`/`.getUTCMonth()` respect to `preserveTimezones`,\r\n * we create a different Date to trick strftime, it's both simpler and more performant.\r\n * Given that a template is expected to be parsed fewer times than rendered.\r\n */\r\n static createDateFixedToTimezone(dateString) {\r\n const m = dateString.match(ISO8601_TIMEZONE_PATTERN);\r\n // representing a UTC timestamp\r\n if (m && m[1] === 'Z') {\r\n return new TimezoneDate(+new Date(dateString), 0);\r\n }\r\n // has a timezone specified\r\n if (m && m[2] && m[3] && m[4]) {\r\n const [, , sign, hours, minutes] = m;\r\n const offset = (sign === '+' ? -1 : 1) * (parseInt(hours, 10) * 60 + parseInt(minutes, 10));\r\n return new TimezoneDate(+new Date(dateString), offset);\r\n }\r\n return new Date(dateString);\r\n }\r\n}\n\nclass DelimitedToken extends Token {\r\n constructor(kind, [contentBegin, contentEnd], input, begin, end, trimLeft, trimRight, file) {\r\n super(kind, input, begin, end, file);\r\n this.trimLeft = false;\r\n this.trimRight = false;\r\n const tl = input[contentBegin] === '-';\r\n const tr = input[contentEnd - 1] === '-';\r\n let l = tl ? contentBegin + 1 : contentBegin;\r\n let r = tr ? contentEnd - 1 : contentEnd;\r\n while (l < r && (TYPES[input.charCodeAt(l)] & BLANK))\r\n l++;\r\n while (r > l && (TYPES[input.charCodeAt(r - 1)] & BLANK))\r\n r--;\r\n this.contentRange = [l, r];\r\n this.trimLeft = tl || trimLeft;\r\n this.trimRight = tr || trimRight;\r\n }\r\n get content() {\r\n return this.input.slice(this.contentRange[0], this.contentRange[1]);\r\n }\r\n}\n\nclass TagToken extends DelimitedToken {\r\n constructor(input, begin, end, options, file) {\r\n const { trimTagLeft, trimTagRight, tagDelimiterLeft, tagDelimiterRight } = options;\r\n const [valueBegin, valueEnd] = [begin + tagDelimiterLeft.length, end - tagDelimiterRight.length];\r\n super(TokenKind.Tag, [valueBegin, valueEnd], input, begin, end, trimTagLeft, trimTagRight, file);\r\n this.tokenizer = new Tokenizer(input, options.operators, file, this.contentRange);\r\n this.name = this.tokenizer.readTagName();\r\n this.tokenizer.assert(this.name, `illegal tag syntax, tag name expected`);\r\n this.tokenizer.skipBlank();\r\n }\r\n get args() {\r\n return this.tokenizer.input.slice(this.tokenizer.p, this.contentRange[1]);\r\n }\r\n}\n\nclass OutputToken extends DelimitedToken {\r\n constructor(input, begin, end, options, file) {\r\n const { trimOutputLeft, trimOutputRight, outputDelimiterLeft, outputDelimiterRight } = options;\r\n const valueRange = [begin + outputDelimiterLeft.length, end - outputDelimiterRight.length];\r\n super(TokenKind.Output, valueRange, input, begin, end, trimOutputLeft, trimOutputRight, file);\r\n }\r\n}\n\nclass HTMLToken extends Token {\r\n constructor(input, begin, end, file) {\r\n super(TokenKind.HTML, input, begin, end, file);\r\n this.input = input;\r\n this.begin = begin;\r\n this.end = end;\r\n this.file = file;\r\n this.trimLeft = 0;\r\n this.trimRight = 0;\r\n }\r\n getContent() {\r\n return this.input.slice(this.begin + this.trimLeft, this.end - this.trimRight);\r\n }\r\n}\n\nclass NumberToken extends Token {\r\n constructor(input, begin, end, file) {\r\n super(TokenKind.Number, input, begin, end, file);\r\n this.input = input;\r\n this.begin = begin;\r\n this.end = end;\r\n this.file = file;\r\n this.content = Number(this.getText());\r\n }\r\n}\n\nclass IdentifierToken extends Token {\r\n constructor(input, begin, end, file) {\r\n super(TokenKind.Word, input, begin, end, file);\r\n this.input = input;\r\n this.begin = begin;\r\n this.end = end;\r\n this.file = file;\r\n this.content = this.getText();\r\n }\r\n isNumber(allowSign = false) {\r\n const begin = allowSign && TYPES[this.input.charCodeAt(this.begin)] & SIGN\r\n ? this.begin + 1\r\n : this.begin;\r\n for (let i = begin; i < this.end; i++) {\r\n if (!(TYPES[this.input.charCodeAt(i)] & NUMBER))\r\n return false;\r\n }\r\n return true;\r\n }\r\n}\n\nclass LiteralToken extends Token {\r\n constructor(input, begin, end, file) {\r\n super(TokenKind.Literal, input, begin, end, file);\r\n this.input = input;\r\n this.begin = begin;\r\n this.end = end;\r\n this.file = file;\r\n this.literal = this.getText();\r\n this.content = literalValues[this.literal];\r\n }\r\n}\n\nconst operatorPrecedences = {\r\n '==': 2,\r\n '!=': 2,\r\n '>': 2,\r\n '<': 2,\r\n '>=': 2,\r\n '<=': 2,\r\n 'contains': 2,\r\n 'not': 1,\r\n 'and': 0,\r\n 'or': 0\r\n};\r\nconst operatorTypes = {\r\n '==': 0 /* OperatorType.Binary */,\r\n '!=': 0 /* OperatorType.Binary */,\r\n '>': 0 /* OperatorType.Binary */,\r\n '<': 0 /* OperatorType.Binary */,\r\n '>=': 0 /* OperatorType.Binary */,\r\n '<=': 0 /* OperatorType.Binary */,\r\n 'contains': 0 /* OperatorType.Binary */,\r\n 'not': 1 /* OperatorType.Unary */,\r\n 'and': 0 /* OperatorType.Binary */,\r\n 'or': 0 /* OperatorType.Binary */\r\n};\r\nclass OperatorToken extends Token {\r\n constructor(input, begin, end, file) {\r\n super(TokenKind.Operator, input, begin, end, file);\r\n this.input = input;\r\n this.begin = begin;\r\n this.end = end;\r\n this.file = file;\r\n this.operator = this.getText();\r\n }\r\n getPrecedence() {\r\n const key = this.getText();\r\n return key in operatorPrecedences ? operatorPrecedences[key] : 1;\r\n }\r\n}\n\nclass PropertyAccessToken extends Token {\r\n constructor(variable, props, input, begin, end, file) {\r\n super(TokenKind.PropertyAccess, input, begin, end, file);\r\n this.variable = variable;\r\n this.props = props;\r\n }\r\n}\n\nclass FilterToken extends Token {\r\n constructor(name, args, input, begin, end, file) {\r\n super(TokenKind.Filter, input, begin, end, file);\r\n this.name = name;\r\n this.args = args;\r\n }\r\n}\n\nclass HashToken extends Token {\r\n constructor(input, begin, end, name, value, file) {\r\n super(TokenKind.Hash, input, begin, end, file);\r\n this.input = input;\r\n this.begin = begin;\r\n this.end = end;\r\n this.name = name;\r\n this.value = value;\r\n this.file = file;\r\n }\r\n}\n\nconst rHex = /[\\da-fA-F]/;\r\nconst rOct = /[0-7]/;\r\nconst escapeChar = {\r\n b: '\\b',\r\n f: '\\f',\r\n n: '\\n',\r\n r: '\\r',\r\n t: '\\t',\r\n v: '\\x0B'\r\n};\r\nfunction hexVal(c) {\r\n const code = c.charCodeAt(0);\r\n if (code >= 97)\r\n return code - 87;\r\n if (code >= 65)\r\n return code - 55;\r\n return code - 48;\r\n}\r\nfunction parseStringLiteral(str) {\r\n let ret = '';\r\n for (let i = 1; i < str.length - 1; i++) {\r\n if (str[i] !== '\\\\') {\r\n ret += str[i];\r\n continue;\r\n }\r\n if (escapeChar[str[i + 1]] !== undefined) {\r\n ret += escapeChar[str[++i]];\r\n }\r\n else if (str[i + 1] === 'u') {\r\n let val = 0;\r\n let j = i + 2;\r\n while (j <= i + 5 && rHex.test(str[j])) {\r\n val = val * 16 + hexVal(str[j++]);\r\n }\r\n i = j - 1;\r\n ret += String.fromCharCode(val);\r\n }\r\n else if (!rOct.test(str[i + 1])) {\r\n ret += str[++i];\r\n }\r\n else {\r\n let j = i + 1;\r\n let val = 0;\r\n while (j <= i + 3 && rOct.test(str[j])) {\r\n val = val * 8 + hexVal(str[j++]);\r\n }\r\n i = j - 1;\r\n ret += String.fromCharCode(val);\r\n }\r\n }\r\n return ret;\r\n}\n\nclass QuotedToken extends Token {\r\n constructor(input, begin, end, file) {\r\n super(TokenKind.Quoted, input, begin, end, file);\r\n this.input = input;\r\n this.begin = begin;\r\n this.end = end;\r\n this.file = file;\r\n this.content = parseStringLiteral(this.getText());\r\n }\r\n}\n\nclass RangeToken extends Token {\r\n constructor(input, begin, end, lhs, rhs, file) {\r\n super(TokenKind.Range, input, begin, end, file);\r\n this.input = input;\r\n this.begin = begin;\r\n this.end = end;\r\n this.lhs = lhs;\r\n this.rhs = rhs;\r\n this.file = file;\r\n }\r\n}\n\n/**\r\n * LiquidTagToken is different from TagToken by not having delimiters `{%` or `%}`\r\n */\r\nclass LiquidTagToken extends DelimitedToken {\r\n constructor(input, begin, end, options, file) {\r\n super(TokenKind.Tag, [begin, end], input, begin, end, false, false, file);\r\n this.tokenizer = new Tokenizer(input, options.operators, file, this.contentRange);\r\n this.name = this.tokenizer.readTagName();\r\n this.tokenizer.assert(this.name, 'illegal liquid tag syntax');\r\n this.tokenizer.skipBlank();\r\n this.args = this.tokenizer.remaining();\r\n }\r\n}\n\n/**\r\n * value expression with optional filters\r\n * e.g.\r\n * {% assign foo=\"bar\" | append: \"coo\" %}\r\n */\r\nclass FilteredValueToken extends Token {\r\n constructor(initial, filters, input, begin, end, file) {\r\n super(TokenKind.FilteredValue, input, begin, end, file);\r\n this.initial = initial;\r\n this.filters = filters;\r\n this.input = input;\r\n this.begin = begin;\r\n this.end = end;\r\n this.file = file;\r\n }\r\n}\n\nclass SimpleEmitter {\r\n constructor() {\r\n this.buffer = '';\r\n }\r\n write(html) {\r\n this.buffer += stringify(html);\r\n }\r\n}\n\nclass StreamedEmitter {\r\n constructor() {\r\n this.buffer = '';\r\n this.stream = null;\r\n throw new Error('streaming not supported in browser');\r\n }\r\n}\n\nclass KeepingTypeEmitter {\r\n constructor() {\r\n this.buffer = '';\r\n }\r\n write(html) {\r\n html = toValue(html);\r\n // This will only preserve the type if the value is isolated.\r\n // I.E:\r\n // {{ my-port }} -> 42\r\n // {{ my-host }}:{{ my-port }} -> 'host:42'\r\n if (typeof html !== 'string' && this.buffer === '') {\r\n this.buffer = html;\r\n }\r\n else {\r\n this.buffer = stringify(this.buffer) + stringify(html);\r\n }\r\n }\r\n}\n\nclass Render {\r\n renderTemplatesToNodeStream(templates, ctx) {\r\n const emitter = new StreamedEmitter();\r\n Promise.resolve().then(() => toPromise(this.renderTemplates(templates, ctx, emitter)))\r\n .then(() => emitter.end(), err => emitter.error(err));\r\n return emitter.stream;\r\n }\r\n *renderTemplates(templates, ctx, emitter) {\r\n if (!emitter) {\r\n emitter = ctx.opts.keepOutputType ? new KeepingTypeEmitter() : new SimpleEmitter();\r\n }\r\n for (const tpl of templates) {\r\n try {\r\n // if tpl.render supports emitter, it'll return empty `html`\r\n const html = yield tpl.render(ctx, emitter);\r\n // if not, it'll return an `html`, write to the emitter for it\r\n html && emitter.write(html);\r\n if (emitter['break'] || emitter['continue'])\r\n break;\r\n }\r\n catch (e) {\r\n const err = RenderError.is(e) ? e : new RenderError(e, tpl);\r\n throw err;\r\n }\r\n }\r\n return emitter.buffer;\r\n }\r\n}\n\nclass Expression {\r\n constructor(tokens) {\r\n this.postfix = [...toPostfix(tokens)];\r\n }\r\n *evaluate(ctx, lenient) {\r\n assert(ctx, 'unable to evaluate: context not defined');\r\n const operands = [];\r\n for (const token of this.postfix) {\r\n if (isOperatorToken(token)) {\r\n const r = operands.pop();\r\n let result;\r\n if (operatorTypes[token.operator] === 1 /* OperatorType.Unary */) {\r\n result = yield ctx.opts.operators[token.operator](r, ctx);\r\n }\r\n else {\r\n const l = operands.pop();\r\n result = yield ctx.opts.operators[token.operator](l, r, ctx);\r\n }\r\n operands.push(result);\r\n }\r\n else {\r\n operands.push(yield evalToken(token, ctx, lenient && this.postfix.length === 1));\r\n }\r\n }\r\n return operands[0];\r\n }\r\n valid() {\r\n return !!this.postfix.length;\r\n }\r\n}\r\nfunction* evalToken(token, ctx, lenient = false) {\r\n if (!token)\r\n return;\r\n if ('content' in token)\r\n return token.content;\r\n if (isPropertyAccessToken(token))\r\n return yield evalPropertyAccessToken(token, ctx, lenient);\r\n if (isRangeToken(token))\r\n return yield evalRangeToken(token, ctx);\r\n}\r\nfunction* evalPropertyAccessToken(token, ctx, lenient) {\r\n const props = [];\r\n const variable = yield evalToken(token.variable, ctx, lenient);\r\n for (const prop of token.props) {\r\n props.push((yield evalToken(prop, ctx, false)));\r\n }\r\n try {\r\n if (token.variable) {\r\n return yield ctx._getFromScope(variable, props);\r\n }\r\n else {\r\n return yield ctx._get(props);\r\n }\r\n }\r\n catch (e) {\r\n if (lenient && e.name === 'InternalUndefinedVariableError')\r\n return null;\r\n throw (new UndefinedVariableError(e, token));\r\n }\r\n}\r\nfunction evalQuotedToken(token) {\r\n return token.content;\r\n}\r\nfunction* evalRangeToken(token, ctx) {\r\n const low = yield evalToken(token.lhs, ctx);\r\n const high = yield evalToken(token.rhs, ctx);\r\n return range(+low, +high + 1);\r\n}\r\nfunction* toPostfix(tokens) {\r\n const ops = [];\r\n for (const token of tokens) {\r\n if (isOperatorToken(token)) {\r\n while (ops.length && ops[ops.length - 1].getPrecedence() > token.getPrecedence()) {\r\n yield ops.pop();\r\n }\r\n ops.push(token);\r\n }\r\n else\r\n yield token;\r\n }\r\n while (ops.length) {\r\n yield ops.pop();\r\n }\r\n}\n\nfunction isTruthy(val, ctx) {\r\n return !isFalsy(val, ctx);\r\n}\r\nfunction isFalsy(val, ctx) {\r\n if (ctx.opts.jsTruthy) {\r\n return !val;\r\n }\r\n else {\r\n return val === false || undefined === val || val === null;\r\n }\r\n}\n\nconst defaultOperators = {\r\n '==': equal,\r\n '!=': (l, r) => !equal(l, r),\r\n '>': (l, r) => {\r\n if (isComparable(l))\r\n return l.gt(r);\r\n if (isComparable(r))\r\n return r.lt(l);\r\n return toValue(l) > toValue(r);\r\n },\r\n '<': (l, r) => {\r\n if (isComparable(l))\r\n return l.lt(r);\r\n if (isComparable(r))\r\n return r.gt(l);\r\n return toValue(l) < toValue(r);\r\n },\r\n '>=': (l, r) => {\r\n if (isComparable(l))\r\n return l.geq(r);\r\n if (isComparable(r))\r\n return r.leq(l);\r\n return toValue(l) >= toValue(r);\r\n },\r\n '<=': (l, r) => {\r\n if (isComparable(l))\r\n return l.leq(r);\r\n if (isComparable(r))\r\n return r.geq(l);\r\n return toValue(l) <= toValue(r);\r\n },\r\n 'contains': (l, r) => {\r\n l = toValue(l);\r\n r = toValue(r);\r\n return l && isFunction(l.indexOf) ? l.indexOf(r) > -1 : false;\r\n },\r\n 'not': (v, ctx) => isFalsy(toValue(v), ctx),\r\n 'and': (l, r, ctx) => isTruthy(toValue(l), ctx) && isTruthy(toValue(r), ctx),\r\n 'or': (l, r, ctx) => isTruthy(toValue(l), ctx) || isTruthy(toValue(r), ctx)\r\n};\r\nfunction equal(lhs, rhs) {\r\n if (isComparable(lhs))\r\n return lhs.equals(rhs);\r\n if (isComparable(rhs))\r\n return rhs.equals(lhs);\r\n lhs = toValue(lhs);\r\n rhs = toValue(rhs);\r\n if (isArray(lhs)) {\r\n return isArray(rhs) && arrayEqual(lhs, rhs);\r\n }\r\n return lhs === rhs;\r\n}\r\nfunction arrayEqual(lhs, rhs) {\r\n if (lhs.length !== rhs.length)\r\n return false;\r\n return !lhs.some((value, i) => !equal(value, rhs[i]));\r\n}\n\nclass Node {\r\n constructor(key, value, next, prev) {\r\n this.key = key;\r\n this.value = value;\r\n this.next = next;\r\n this.prev = prev;\r\n }\r\n}\r\nclass LRU {\r\n constructor(limit, size = 0) {\r\n this.limit = limit;\r\n this.size = size;\r\n this.cache = {};\r\n this.head = new Node('HEAD', null, null, null);\r\n this.tail = new Node('TAIL', null, null, null);\r\n this.head.next = this.tail;\r\n this.tail.prev = this.head;\r\n }\r\n write(key, value) {\r\n if (this.cache[key]) {\r\n this.cache[key].value = value;\r\n }\r\n else {\r\n const node = new Node(key, value, this.head.next, this.head);\r\n this.head.next.prev = node;\r\n this.head.next = node;\r\n this.cache[key] = node;\r\n this.size++;\r\n this.ensureLimit();\r\n }\r\n }\r\n read(key) {\r\n if (!this.cache[key])\r\n return;\r\n const { value } = this.cache[key];\r\n this.remove(key);\r\n this.write(key, value);\r\n return value;\r\n }\r\n remove(key) {\r\n const node = this.cache[key];\r\n node.prev.next = node.next;\r\n node.next.prev = node.prev;\r\n delete this.cache[key];\r\n this.size--;\r\n }\r\n clear() {\r\n this.head.next = this.tail;\r\n this.tail.prev = this.head;\r\n this.size = 0;\r\n this.cache = {};\r\n }\r\n ensureLimit() {\r\n if (this.size > this.limit)\r\n this.remove(this.tail.prev.key);\r\n }\r\n}\n\nfunction domResolve(root, path) {\r\n const base = document.createElement('base');\r\n base.href = root;\r\n const head = document.getElementsByTagName('head')[0];\r\n head.insertBefore(base, head.firstChild);\r\n const a = document.createElement('a');\r\n a.href = path;\r\n const resolved = a.href;\r\n head.removeChild(base);\r\n return resolved;\r\n}\r\nfunction resolve(root, filepath, ext) {\r\n if (root.length && last(root) !== '/')\r\n root += '/';\r\n const url = domResolve(root, filepath);\r\n return url.replace(/^(\\w+:\\/\\/[^/]+)(\\/[^?]+)/, (str, origin, path) => {\r\n const last = path.split('/').pop();\r\n if (/\\.\\w+$/.test(last))\r\n return str;\r\n return origin + path + ext;\r\n });\r\n}\r\nfunction readFile(url) {\r\n return __awaiter(this, void 0, void 0, function* () {\r\n return new Promise((resolve, reject) => {\r\n const xhr = new XMLHttpRequest();\r\n xhr.onload = () => {\r\n if (xhr.status >= 200 && xhr.status < 300) {\r\n resolve(xhr.responseText);\r\n }\r\n else {\r\n reject(new Error(xhr.statusText));\r\n }\r\n };\r\n xhr.onerror = () => {\r\n reject(new Error('An error occurred whilst receiving the response.'));\r\n };\r\n xhr.open('GET', url);\r\n xhr.send();\r\n });\r\n });\r\n}\r\nfunction readFileSync(url) {\r\n const xhr = new XMLHttpRequest();\r\n xhr.open('GET', url, false);\r\n xhr.send();\r\n if (xhr.status < 200 || xhr.status >= 300) {\r\n throw new Error(xhr.statusText);\r\n }\r\n return xhr.responseText;\r\n}\r\nfunction exists(filepath) {\r\n return __awaiter(this, void 0, void 0, function* () {\r\n return true;\r\n });\r\n}\r\nfunction existsSync(filepath) {\r\n return true;\r\n}\r\nfunction dirname(filepath) {\r\n return domResolve(filepath, '.');\r\n}\r\nconst sep = '/';\n\nvar fs = /*#__PURE__*/Object.freeze({\n __proto__: null,\n resolve: resolve,\n readFile: readFile,\n readFileSync: readFileSync,\n exists: exists,\n existsSync: existsSync,\n dirname: dirname,\n sep: sep\n});\n\nfunction Default(value, defaultValue, ...args) {\r\n value = toValue(value);\r\n if (isArray(value) || isString(value))\r\n return value.length ? value : defaultValue;\r\n if (value === false && (new Map(args)).get('allow_false'))\r\n return false;\r\n return isFalsy(value, this.context) ? defaultValue : value;\r\n}\r\nfunction json(value, space = 0) {\r\n return JSON.stringify(value, null, space);\r\n}\r\nconst raw = {\r\n raw: true,\r\n handler: identify\r\n};\n\nconst escapeMap = {\r\n '&': '&',\r\n '<': '<',\r\n '>': '>',\r\n '\"': '"',\r\n \"'\": '''\r\n};\r\nconst unescapeMap = {\r\n '&': '&',\r\n '<': '<',\r\n '>': '>',\r\n '"': '\"',\r\n ''': \"'\"\r\n};\r\nfunction escape(str) {\r\n return stringify(str).replace(/&|<|>|\"|'/g, m => escapeMap[m]);\r\n}\r\nfunction unescape(str) {\r\n return stringify(str).replace(/&(amp|lt|gt|#34|#39);/g, m => unescapeMap[m]);\r\n}\r\nfunction escape_once(str) {\r\n return escape(unescape(stringify(str)));\r\n}\r\nfunction newline_to_br(v) {\r\n return stringify(v).replace(/\\r?\\n/gm, '
\\n');\r\n}\r\nfunction strip_html(v) {\r\n return stringify(v).replace(/