{"version":3,"sources":["jsdelivr-header.js","/npm/stjs@0.0.5/st.js"],"names":[],"mappings":"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","file":"/npm/stjs@0.0.5/st.js","sourceRoot":"","sourcesContent":["/**\n * Minified by jsDelivr using Terser v5.39.0.\n * Original file: /npm/stjs@0.0.5/st.js\n *\n * Do NOT use SRI with dynamically generated files! More information: https://www.jsdelivr.com/using-sri-with-dynamic-files\n */\n","(function() {\n  var $context = this;\n  var root; // root context\n  var Helper = {\n    is_template: function(str) {\n      var re = /\\{\\{(.+)\\}\\}/g;\n      return re.test(str);\n    },\n    is_array: function(item) {\n      return (\n        Array.isArray(item) ||\n        (!!item &&\n          typeof item === 'object' && typeof item.length === 'number' &&\n          (item.length === 0 || (item.length > 0 && (item.length - 1) in item))\n        )\n      );\n    },\n    resolve: function(o, path, new_val) {\n      // 1. Takes any object\n      // 2. Finds subtree based on path\n      // 3. Sets the value to new_val\n      // 4. Returns the object;\n      if (path && path.length > 0) {\n        var func = Function('new_val', 'with(this) {this' + path + '=new_val; return this;}').bind(o);\n        return func(new_val);\n      } else {\n        o = new_val;\n        return o;\n      }\n    },\n  };\n  var Conditional = {\n    run: function(template, data) {\n      // expecting template as an array of objects,\n      // each of which contains '#if', '#elseif', 'else' as key\n\n      // item should be in the format of:\n      // {'#if item': 'blahblah'}\n\n      // Step 1. get all the conditional keys of the template first.\n      // Step 2. then try evaluating one by one until something returns true\n      // Step 3. if it reaches the end, the last item shall be returned\n      for (var i = 0; i < template.length; i++) {\n        var item = template[i];\n        var keys = Object.keys(item);\n        // assuming that there's only a single kv pair for each item\n        var key = keys[0];\n        var func = TRANSFORM.tokenize(key);\n        if (func.name === '#if' || func.name === '#elseif') {\n          var expression = func.expression;\n          var res = TRANSFORM.fillout(data, '{{' + expression + '}}');\n          if (res === ('{{' + expression + '}}')) {\n            // if there was at least one item that was not evaluatable,\n            // we halt parsing and return the template;\n            return template;\n          } else {\n            if (res) {\n              // run the current one and return\n              return TRANSFORM.run(item[key], data);\n            } else {\n              // res was falsy. Ignore this branch and go on to the next item\n            }\n          }\n        } else {\n          // #else\n          // if you reached this point, it means:\n          //  1. there were no non-evaluatable expressions\n          //  2. Yet all preceding expressions evaluated to falsy value\n          //  Therefore we run this branch\n          return TRANSFORM.run(item[key], data);\n        }\n      }\n      // if you've reached this point, it means nothing matched.\n      // so return null\n      return null;\n    },\n    is: function(template) {\n      // TRUE ONLY IF it's in a correct format.\n      // Otherwise return the original template\n      // Condition 0. Must be an array\n      // Condition 1. Must have at least one item\n      // Condition 2. Each item in the array should be an object of a single key/value pair\n      // Condition 3. starts with #if\n      // Condition 4. in case there's more than two items, everything between the first and the last item should be #elseif\n      // Condition 5. in case there's more than two items, the last one should be either '#else' or '#elseif'\n      if (!Helper.is_array(template)) {\n        // Condition 0, it needs to be an array to be a conditional\n        return false;\n      }\n      // Condition 1.\n      // Must have at least one item\n      if (template.length === 0) {\n        return false;\n      }\n      // Condition 2.\n      // Each item in the array should be an object\n      // , and  of a single key/value pair\n      var containsValidObjects = true;\n      for (var i = 0; i < template.length; i++) {\n        var item = template[0];\n        if (typeof item !== 'object') {\n          containsValidObjects = false;\n          break;\n        }\n        if (Object.keys(item).length !== 1) {\n          // first item in the array has multiple key value pairs, so invalid.\n          containsValidObjects = false;\n          break;\n        }\n      }\n      if (!containsValidObjects) {\n        return false;\n      }\n      // Condition 3.\n      // the first item should have #if as its key\n      // the first item should also contain an expression\n      var first = template[0];\n      var func;\n      for (var key in first) {\n        func = TRANSFORM.tokenize(key);\n        if (!func) {\n          return false;\n        }\n        if (!func.name) {\n          return false;\n        }\n        // '{{#if }}'\n        if (!func.expression || func.expression.length === 0) {\n          return false;\n        }\n        if (func.name.toLowerCase() !== '#if') {\n          return false;\n        }\n      }\n      if (template.length === 1) {\n        // If we got this far and the template has only one item, it means\n        // template had one item which was '#if' so it's valid\n        return true;\n      }\n      // Condition 4.\n      // in case there's more than two items, everything between the first and the last item should be #elseif\n      var they_are_all_elseifs = true;\n      for (var template_index = 1; template_index < template.length-1; template_index++) {\n        var template_item = template[template_index];\n        for (var template_key in template_item) {\n          func = TRANSFORM.tokenize(template_key);\n          if (func.name.toLowerCase() !== '#elseif') {\n            they_are_all_elseifs = false;\n            break;\n          }\n        }\n      }\n      if (!they_are_all_elseifs) {\n        // There was at least one item that wasn't an elseif\n        // therefore invalid\n        return false;\n      }\n      // If you've reached this point, it means we have multiple items and everything between the first and the last item\n      // are elseifs\n      // Now we need to check the validity of the last item\n      // Condition 5.\n      // in case there's more than one item, it should end with #else or #elseif\n      var last = template[template.length-1];\n      for (var last_key in last) {\n        func = TRANSFORM.tokenize(last_key);\n        if (['#else', '#elseif'].indexOf(func.name.toLowerCase()) === -1) {\n          return false;\n        }\n      }\n      // Congrats, if you've reached this point, it's valid\n      return true;\n    },\n  };\n  var TRANSFORM = {\n    transform: function(template, data, injection, serialized) {\n      var selector = null;\n      if (/#include/.test(JSON.stringify(template))) {\n        selector = function(key, value) { return /#include/.test(key) || /#include/.test(value); };\n      }\n      var res;\n      if (injection) {\n        // resolve template with selector\n        var resolved_template = SELECT.select(template, selector, serialized)\n          .transform(data, serialized)\n          .root();\n        // apply the resolved template on data\n        res = SELECT.select(data, null, serialized)\n          .inject(injection, serialized)\n          .transformWith(resolved_template, serialized)\n          .root();\n      } else {\n        // no need for separate template resolution step\n        // select the template with selector and transform data\n        res = SELECT.select(template, selector, serialized)\n          .transform(data, serialized)\n          .root();\n      }\n      if (serialized) {\n        // needs to return stringified version\n        return JSON.stringify(res);\n      } else {\n        return res;\n      }\n    },\n    tokenize: function(str) {\n      // INPUT : string\n      // OUTPUT : {name: FUNCTION_NAME:STRING, args: ARGUMENT:ARRAY}\n      var re = /\\{\\{(.+)\\}\\}/g;\n      str = str.replace(re, '$1');\n      // str : '#each $jason.items'\n\n      var tokens = str.trim().split(' ');\n      // => tokens: ['#each', '$jason.items']\n\n      var func;\n      if (tokens.length > 0) {\n        if (tokens[0][0] === '#') {\n          func = tokens.shift();\n          // => func: '#each' or '#if'\n          // => tokens: ['$jason.items', '&&', '$jason.items.length', '>', '0']\n\n          var expression = tokens.join(' ');\n          // => expression: '$jason.items && $jason.items.length > 0'\n\n          return { name: func, expression: expression };\n        }\n      }\n      return null;\n    },\n    run: function(template, data) {\n      var result;\n      var fun;\n      if (typeof template === 'string') {\n        // Leaf node, so call TRANSFORM.fillout()\n        if (Helper.is_template(template)) {\n          var include_string_re = /\\{\\{([ ]*#include)[ ]*([^ ]*)\\}\\}/g;\n          if (include_string_re.test(template)) {\n            fun = TRANSFORM.tokenize(template);\n            if (fun.expression) {\n              // if #include has arguments, evaluate it before attaching\n              result = TRANSFORM.fillout(data, '{{' + fun.expression + '}}', true);\n            } else {\n              // shouldn't happen =>\n              // {'wrapper': '{{#include}}'}\n              result = template;\n            }\n          } else {\n            // non-#include\n            result = TRANSFORM.fillout(data, template);\n          }\n        } else {\n          result = template;\n        }\n      } else if (Helper.is_array(template)) {\n        if (Conditional.is(template)) {\n          result = Conditional.run(template, data);\n        } else {\n          result = [];\n          for (var i = 0; i < template.length; i++) {\n            var item = TRANSFORM.run(template[i], data);\n            if (item) {\n              // only push when the result is not null\n              // null could mean #if clauses where nothing matched => In this case instead of rendering 'null', should just skip it completely\n              // Todo : Distinguish between #if arrays and ordinary arrays, and return null for ordinary arrays\n              result.push(item);\n            }\n          }\n        }\n      } else if (Object.prototype.toString.call(template) === '[object Object]') {\n        // template is an object\n        result = {};\n\n        // ## Handling #include\n        // This needs to precede everything else since it's meant to be overwritten\n        // in case of collision\n        var include_object_re = /\\{\\{([ ]*#include)[ ]*(.*)\\}\\}/;\n        var include_keys = Object.keys(template).filter(function(key) { return include_object_re.test(key); });\n        if (include_keys.length > 0) {\n        // find the first key with #include\n          fun = TRANSFORM.tokenize(include_keys[0]);\n          if (fun.expression) {\n            // if #include has arguments, evaluate it before attaching\n            result = TRANSFORM.fillout(template[include_keys[0]], '{{' + fun.expression + '}}', true);\n          } else {\n            // no argument, simply attach the child\n            result = template[include_keys[0]];\n          }\n        }\n\n        for (var key in template) {\n          // Checking to see if the key contains template..\n          // Currently the only case for this are '#each' and '#include'\n          if (Helper.is_template(key)) {\n            fun = TRANSFORM.tokenize(key);\n            if (fun) {\n              if (fun.name === '#include') {\n                // this was handled above (before the for loop) so just ignore\n              } else if (fun.name === '#concat') {\n                if (Helper.is_array(template[key])) {\n                  result = [];\n                  template[key].forEach(function(concat_item) {\n                    var res = TRANSFORM.run(concat_item, data);\n                    result = result.concat(res);\n                  });\n\n                  if (/\\{\\{(.*?)\\}\\}/.test(JSON.stringify(result))) {\n                    // concat should only trigger if all of its children\n                    // have successfully parsed.\n                    // so check for any template expression in the end result\n                    // and if there is one, revert to the original template\n                    result = template;\n                  }\n                }\n              } else if (fun.name === '#merge') {\n                if (Helper.is_array(template[key])) {\n                  result = {};\n                  template[key].forEach(function(merge_item) {\n                    var res = TRANSFORM.run(merge_item, data);\n                    for (var key in res) {\n                      result[key] = res[key];\n                    }\n                  });\n                  // clean up $index from the result\n                  // necessary because #merge merges multiple objects into one,\n                  // and one of them may be 'this', in which case the $index attribute\n                  // will have snuck into the final result\n                  if(typeof data === 'object') {\n                    delete result[\"$index\"];\n                  } else {\n                    delete String.prototype.$index;\n                    delete Number.prototype.$index;\n                    delete Function.prototype.$index;\n                    delete Array.prototype.$index;\n                    delete Boolean.prototype.$index;\n                  }\n                }\n              } else if (fun.name === '#each') {\n                // newData will be filled with parsed results\n                var newData = TRANSFORM.fillout(data, '{{' + fun.expression + '}}', true);\n\n                // Ideally newData should be an array since it was prefixed by #each\n                if (newData && Helper.is_array(newData)) {\n                  result = [];\n                  for (var index = 0; index < newData.length; index++) {\n                    // temporarily set $index\n                    if(typeof newData[index] === 'object') {\n                      newData[index][\"$index\"] = index;\n                    } else {\n                      String.prototype.$index = index;\n                      Number.prototype.$index = index;\n                      Function.prototype.$index = index;\n                      Array.prototype.$index = index;\n                      Boolean.prototype.$index = index;\n                    }\n\n                    // run\n                    var loop_item = TRANSFORM.run(template[key], newData[index]);\n\n                    // clean up $index\n                    if(typeof newData[index] === 'object') {\n                      delete newData[index][\"$index\"];\n                    } else {\n                      delete String.prototype.$index;\n                      delete Number.prototype.$index;\n                      delete Function.prototype.$index;\n                      delete Array.prototype.$index;\n                      delete Boolean.prototype.$index;\n                    }\n\n                    if (loop_item) {\n                      // only push when the result is not null\n                      // null could mean #if clauses where nothing matched => In this case instead of rendering 'null', should just skip it completely\n                      result.push(loop_item);\n                    }\n                  }\n                } else {\n                  // In case it's not an array, it's an exception, since it was prefixed by #each.\n                  // This probably means this #each is not for the current variable\n                  // For example {{#each items}} may not be an array, but just leave it be, so\n                  // But don't get rid of it,\n                  // Instead, just leave it as template\n                  // So some other parse run could fill it in later.\n                  result = template;\n                }\n              } // end of #each\n            } else { // end of if (fun)\n              // If the key is a template expression but aren't either #include or #each,\n              // it needs to be parsed\n              var k = TRANSFORM.fillout(data, key);\n              var v = TRANSFORM.fillout(data, template[key]);\n              if (k !== undefined && v !== undefined) {\n                result[k] = v;\n              }\n            }\n          } else {\n            // Helper.is_template(key) was false, which means the key was not a template (hardcoded string)\n            if (typeof template[key] === 'string') {\n              fun = TRANSFORM.tokenize(template[key]);\n              if (fun && fun.name === '#?') {\n                // If the key is a template expression but aren't either #include or #each,\n                // it needs to be parsed\n                var filled = TRANSFORM.fillout(data, '{{' + fun.expression + '}}');\n                if (filled === '{{' + fun.expression + '}}' || !filled) {\n                  // case 1.\n                  // not parsed, which means the evaluation failed.\n\n                  // case 2.\n                  // returns fasly value\n\n                  // both cases mean this key should be excluded\n                } else {\n                  // only include if the evaluation is truthy\n                  result[key] = filled;\n                }\n              } else {\n                var item = TRANSFORM.run(template[key], data);\n                if (item !== undefined) {\n                  result[key] = item;\n                }\n              }\n            } else {\n              var item = TRANSFORM.run(template[key], data);\n              if (item !== undefined) {\n                result[key] = item;\n              }\n            }\n          }\n        }\n      } else {\n        return template;\n      }\n      return result;\n    },\n    fillout: function(data, template, raw) {\n      // 1. fill out if possible\n      // 2. otherwise return the original\n      var replaced = template;\n      // Run fillout() only if it's a template. Otherwise just return the original string\n      if (Helper.is_template(template)) {\n        var re = /\\{\\{(.*?)\\}\\}/g;\n\n        // variables are all instances of {{ }} in the current expression\n        // for example '{{this.item}} is {{this.user}}'s' has two variables: ['this.item', 'this.user']\n        var variables = template.match(re);\n\n        if (variables) {\n          if (raw) {\n            // 'raw' is true only for when this is called from #each\n            // Because #each is expecting an array, it shouldn't be stringified.\n            // Therefore we pass template:null,\n            // which will result in returning the original result instead of trying to\n            // replace it into the template with a stringified version\n            replaced = TRANSFORM._fillout({\n              variable: variables[0],\n              data: data,\n              template: null,\n            });\n          } else {\n            // Fill out the template for each variable\n            for (var i = 0; i < variables.length; i++) {\n              var variable = variables[i];\n              replaced = TRANSFORM._fillout({\n                variable: variable,\n                data: data,\n                template: replaced,\n              });\n            }\n          }\n        } else {\n          return replaced;\n        }\n      }\n      return replaced;\n    },\n    _fillout: function(options) {\n      // Given a template and fill it out with passed slot and its corresponding data\n      var re = /\\{\\{(.*?)\\}\\}/g;\n      var full_re = /^\\{\\{((?!\\}\\}).)*\\}\\}$/;\n      var variable = options.variable;\n      var data = options.data;\n      var template = options.template;\n      try {\n        // 1. Evaluate the variable\n        var slot = variable.replace(re, '$1');\n\n        // data must exist. Otherwise replace with blank\n        if (data) {\n          var func;\n          // Attach $root to each node so that we can reference it from anywhere\n          var data_type = typeof data;\n          if (['number', 'string', 'array', 'boolean', 'function'].indexOf(data_type === -1)) {\n            data.$root = root;\n          }\n          // If the pattern ends with a return statement, but is NOT wrapped inside another function ([^}]*$), it's a function expression\n          var match = /function\\([ ]*\\)[ ]*\\{(.*)\\}[ ]*$/g.exec(slot);\n          if (match) {\n            func = Function('with(this) {' + match[1] + '}').bind(data);\n          } else if (/\\breturn [^;]+;?[ ]*$/.test(slot) && /return[^}]*$/.test(slot)) {\n            // Function expression with explicit 'return' expression\n            func = Function('with(this) {' + slot + '}').bind(data);\n          } else {\n            // Function expression with explicit 'return' expression\n            // Ordinary simple expression that\n            func = Function('with(this) {return (' + slot + ')}').bind(data);\n          }\n          var evaluated = func();\n          delete data.$root;  // remove $root now that the parsing is over\n          if (evaluated) {\n            // In case of primitive types such as String, need to call valueOf() to get the actual value instead of the promoted object\n            evaluated = evaluated.valueOf();\n          }\n          if (typeof evaluated === 'undefined') {\n            // it tried to evaluate since the variable existed, but ended up evaluating to undefined\n            // (example: var a = [1,2,3,4]; var b = a[5];)\n            return template;\n          } else {\n            // 2. Fill out the template with the evaluated value\n            // Be forgiving and print any type, even functions, so it's easier to debug\n            if (evaluated) {\n              // IDEAL CASE : Return the replaced template\n              if (template) {\n                // if the template is a pure template with no additional static text,\n                // And if the evaluated value is an object or an array, we return the object itself instead of\n                // replacing it into template via string replace, since that will turn it into a string.\n                if (full_re.test(template)) {\n                  return evaluated;\n                } else {\n                  return template.replace(variable, evaluated);\n                }\n              } else {\n                return evaluated;\n              }\n            } else {\n              // Treat false or null as blanks (so that #if can handle it)\n              if (template) {\n                // if the template is a pure template with no additional static text,\n                // And if the evaluated value is an object or an array, we return the object itself instead of\n                // replacing it into template via string replace, since that will turn it into a string.\n                if (full_re.test(template)) {\n                  return evaluated;\n                } else {\n                  return template.replace(variable, '');\n                }\n              } else {\n                return '';\n              }\n            }\n          }\n        }\n        // REST OF THE CASES\n        // if evaluated is null or undefined,\n        // it probably means one of the following:\n        //  1. The current data being parsed is not for the current template\n        //  2. It's an error\n        //\n        //  In either case we need to return the original template unparsed.\n        //    1. for case1, we need to leave the template alone so that the template can be parsed\n        //      by another data set\n        //    2. for case2, it's better to just return the template so it's easier to debug\n        return template;\n      } catch (err) {\n        return template;\n      }\n    },\n  };\n  var SELECT = {\n    // current: currently accessed object\n    // path: the path leading to this item\n    // filter: The filter function to decide whether to select or not\n    $val: null,\n    $selected: [],\n    $injected: [],\n    $progress: null,\n    exec: function(current, path, filter) {\n      // if current matches the pattern, put it in the selected array\n      if (typeof current === 'string') {\n        // leaf node should be ignored\n        // we're lookin for keys only\n      } else if (Helper.is_array(current)) {\n        for (var i=0; i<current.length; i++) {\n          SELECT.exec(current[i], path+'['+i+']', filter);\n        }\n      } else {\n        // object\n        for (var key in current) {\n          // '$root' is a special key that links to the root node\n          // so shouldn't be used to iterate\n          if (key !== '$root') {\n            if (filter(key, current[key])) {\n              var index = SELECT.$selected.length;\n              SELECT.$selected.push({\n                index: index,\n                key: key,\n                path: path,\n                object: current,\n                value: current[key],\n              });\n            }\n            SELECT.exec(current[key], path+'[\"'+key+'\"]', filter);\n          }\n        }\n      }\n    },\n    inject: function(obj, serialized) {\n      SELECT.$injected = obj;\n      try {\n        if (serialized) SELECT.$injected = JSON.parse(obj);\n      } catch (error) { }\n\n      if (Object.keys(SELECT.$injected).length > 0) {\n        SELECT.select(SELECT.$injected);\n      }\n      return SELECT;\n    },\n    // returns the object itself\n    select: function(obj, filter, serialized) {\n      // iterate '$selected'\n      //\n      /*\n      SELECT.$selected = [{\n        value {\n          '{{#include}}': {\n            '{{#each items}}': {\n              'type': 'label',\n              'text': '{{name}}'\n            }\n          }\n        },\n        path: '$jason.head.actions.$load'\n        ...\n      }]\n      */\n      var json = obj;\n      try {\n        if (serialized) json = JSON.parse(obj);\n      } catch (error) { }\n\n      if (filter) {\n        SELECT.$selected = [];\n        SELECT.exec(json, '', filter);\n      } else {\n        SELECT.$selected = null;\n      }\n\n      if (json && (Helper.is_array(json) || typeof json === 'object')) {\n        if (!SELECT.$progress) {\n          // initialize\n          if (Helper.is_array(json)) {\n            SELECT.$val = [];\n            SELECT.$selected_root = [];\n          } else {\n            SELECT.$val = {};\n            SELECT.$selected_root = {};\n          }\n        }\n        Object.keys(json).forEach(function(key) {\n        //for (var key in json) {\n          SELECT.$val[key] = json[key];\n          SELECT.$selected_root[key] = json[key];\n        });\n      } else {\n        SELECT.$val = json;\n        SELECT.$selected_root = json;\n      }\n      SELECT.$progress = true; // set the 'in progress' flag\n\n      return SELECT;\n    },\n    transformWith: function(obj, serialized) {\n      SELECT.$parsed = [];\n      SELECT.$progress = null;\n      /*\n      *  'selected' is an array that contains items that looks like this:\n      *  {\n      *    key: The selected key,\n      *    path: The path leading down to the selected key,\n      *    object: The entire object that contains the currently selected key/val pair\n      *    value: The selected value\n      *  }\n      */\n      var template = obj;\n      try {\n        if (serialized) template = JSON.parse(obj);\n      } catch (error) { }\n\n      // Setting $root\n      SELECT.$template_root = template;\n      String.prototype.$root = SELECT.$selected_root;\n      Number.prototype.$root = SELECT.$selected_root;\n      Function.prototype.$root = SELECT.$selected_root;\n      Array.prototype.$root = SELECT.$selected_root;\n      Boolean.prototype.$root = SELECT.$selected_root;\n      root = SELECT.$selected_root;\n      // generate new $selected_root\n      if (SELECT.$selected && SELECT.$selected.length > 0) {\n        SELECT.$selected.sort(function(a, b) {\n          // sort by path length, so that deeper level items will be replaced first\n          // TODO: may need to look into edge cases\n          return b.path.length - a.path.length;\n        }).forEach(function(selection) {\n        //SELECT.$selected.forEach(function(selection) {\n          // parse selected\n          var parsed_object = TRANSFORM.run(template, selection.object);\n\n          // apply the result to root\n          SELECT.$selected_root = Helper.resolve(SELECT.$selected_root, selection.path, parsed_object);\n\n          // update selected object with the parsed result\n          selection.object = parsed_object;\n        });\n        SELECT.$selected.sort(function(a, b) {\n          return a.index - b.index;\n        });\n      } else {\n        var parsed_object = TRANSFORM.run(template, SELECT.$selected_root);\n        // apply the result to root\n        SELECT.$selected_root = Helper.resolve(SELECT.$selected_root, '', parsed_object);\n      }\n      delete String.prototype.$root;\n      delete Number.prototype.$root;\n      delete Function.prototype.$root;\n      delete Array.prototype.$root;\n      delete Boolean.prototype.$root;\n      return SELECT;\n    },\n    transform: function(obj, serialized) {\n      SELECT.$parsed = [];\n      SELECT.$progress = null;\n      /*\n      'selected' is an array that contains items that looks like this:\n\n      {\n        key: The selected key,\n        path: The path leading down to the selected key,\n        object: The entire object that contains the currently selected key/val pair\n        value: The selected value\n      }\n      */\n      var data = obj;\n      try {\n        if (serialized) data = JSON.parse(obj);\n      } catch (error) { }\n\n      // since we're assuming that the template has been already selected, the $template_root is $selected_root\n      SELECT.$template_root = SELECT.$selected_root;\n\n      String.prototype.$root = data;\n      Number.prototype.$root = data;\n      Function.prototype.$root = data;\n      Array.prototype.$root = data;\n      Boolean.prototype.$root = data;\n      root = data;\n\n      if (SELECT.$selected && SELECT.$selected.length > 0) {\n        SELECT.$selected.sort(function(a, b) {\n          // sort by path length, so that deeper level items will be replaced first\n          // TODO: may need to look into edge cases\n          return b.path.length - a.path.length;\n        }).forEach(function(selection) {\n          // parse selected\n          var parsed_object = TRANSFORM.run(selection.object, data);\n          // apply the result to root\n          SELECT.$template_root = Helper.resolve(SELECT.$template_root, selection.path, parsed_object);\n          SELECT.$selected_root = SELECT.$template_root;\n\n          // update selected object with the parsed result\n          selection.object = parsed_object;\n        });\n        SELECT.$selected.sort(function(a, b) {\n          return a.index - b.index;\n        });\n      } else {\n        var parsed_object = TRANSFORM.run(SELECT.$selected_root, data);\n        // apply the result to root\n        SELECT.$template_root = Helper.resolve(SELECT.$template_root, '', parsed_object);\n        SELECT.$selected_root = SELECT.$template_root;\n      }\n      delete String.prototype.$root;\n      delete Number.prototype.$root;\n      delete Function.prototype.$root;\n      delete Array.prototype.$root;\n      delete Boolean.prototype.$root;\n      return SELECT;\n    },\n\n    // Terminal methods\n    objects: function() {\n      SELECT.$progress = null;\n      if (SELECT.$selected) {\n        return SELECT.$selected.map(function(item) { return item.object; });\n      } else {\n        return [SELECT.$selected_root];\n      }\n    },\n    keys: function() {\n      SELECT.$progress = null;\n      if (SELECT.$selected) {\n        return SELECT.$selected.map(function(item) { return item.key; });\n      } else {\n        if (Array.isArray(SELECT.$selected_root)) {\n          return Object.keys(SELECT.$selected_root).map(function(key) { return parseInt(key); });\n        } else {\n          return Object.keys(SELECT.$selected_root);\n        }\n      }\n    },\n    paths: function() {\n      SELECT.$progress = null;\n      if (SELECT.$selected) {\n        return SELECT.$selected.map(function(item) { return item.path; });\n      } else {\n        if (Array.isArray(SELECT.$selected_root)) {\n          return Object.keys(SELECT.$selected_root).map(function(item) {\n            // key is integer\n            return '[' + item + ']';\n          });\n        } else {\n          return Object.keys(SELECT.$selected_root).map(function(item) {\n            // key is string\n            return '[\"' + item + '\"]';\n          });\n        }\n      }\n    },\n    values: function() {\n      SELECT.$progress = null;\n      if (SELECT.$selected) {\n        return SELECT.$selected.map(function(item) { return item.value; });\n      } else {\n        return Object.values(SELECT.$selected_root);\n      }\n    },\n    root: function() {\n      SELECT.$progress = null;\n      return SELECT.$selected_root;\n    },\n  };\n\n  // Native JSON object override\n  var _stringify = JSON.stringify;\n  JSON.stringify = function(val, replacer, spaces) {\n    var t = typeof val;\n    if (['number', 'string', 'boolean'].indexOf(t) !== -1) {\n      return _stringify(val, replacer, spaces);\n    }\n    if (!replacer) {\n      return _stringify(val, function(key, val) {\n        if (SELECT.$injected && SELECT.$injected.length > 0 && SELECT.$injected.indexOf(key) !== -1) { return undefined; }\n        if (key === '$root' || key === '$index') {\n          return undefined;\n        }\n        if (typeof val === 'function') {\n          return '(' + val.toString() + ')';\n        } else {\n          return val;\n        }\n      }, spaces);\n    } else {\n      return _stringify(val, replacer, spaces);\n    }\n  };\n\n  // Export\n  if (typeof exports !== 'undefined') {\n    var x = {\n      TRANSFORM: TRANSFORM,\n      transform: TRANSFORM,\n      SELECT: SELECT,\n      Conditional: Conditional,\n      Helper: Helper,\n      inject: SELECT.inject,\n      select: SELECT.select,\n      transform: TRANSFORM.transform,\n    };\n    if (typeof module !== 'undefined' && module.exports) { exports = module.exports = x; }\n    exports = x;\n  } else {\n    $context.ST = {\n      select: SELECT.select,\n      inject: SELECT.inject,\n      transform: TRANSFORM.transform,\n    };\n  }\n}());\n"]}