Browse Source

Add files via upload

Daniele Bonini (皮夕): WebDev and DevOps by lots of Simplicity bits 4 years ago
parent
commit
83803598ae
4 changed files with 675 additions and 21 deletions
  1. 20 21
      LICENSE
  2. 89 0
      index.html
  3. 268 0
      index.js.original_code.js
  4. 298 0
      serialize-javascript.js

+ 20 - 21
LICENSE

@@ -1,29 +1,28 @@
-BSD 3-Clause License
-
-Copyright (c) 2021, Daniele Bonini (皮夕): WebDev and DevOps by lots of Simplicity bits.
+Copyright 2014 Yahoo! Inc.
+Copyright 2021 5 Mode, requirements, installation and code changes
 All rights reserved.
 All rights reserved.
 
 
 Redistribution and use in source and binary forms, with or without
 Redistribution and use in source and binary forms, with or without
 modification, are permitted provided that the following conditions are met:
 modification, are permitted provided that the following conditions are met:
 
 
-1. Redistributions of source code must retain the above copyright notice, this
-   list of conditions and the following disclaimer.
+    * Redistributions of source code must retain the above copyright
+      notice, this list of conditions and the following disclaimer.
 
 
-2. Redistributions in binary form must reproduce the above copyright notice,
-   this list of conditions and the following disclaimer in the documentation
-   and/or other materials provided with the distribution.
+    * Redistributions in binary form must reproduce the above copyright
+      notice, this list of conditions and the following disclaimer in the
+      documentation and/or other materials provided with the distribution.
 
 
-3. Neither the name of the copyright holder nor the names of its
-   contributors may be used to endorse or promote products derived from
-   this software without specific prior written permission.
+    * Neither the name of the Yahoo! Inc. nor the
+      names of its contributors may be used to endorse or promote products
+      derived from this software without specific prior written permission.
 
 
-THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
-AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
-IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
-DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
-FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
-DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
-SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
-CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
-OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+DISCLAIMED. IN NO EVENT SHALL YAHOO! INC. BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

+ 89 - 0
index.html

@@ -0,0 +1,89 @@
+<!DOCTYPE html>
+<html lang="en-US" xmlns="http://www.w3.org/1999/xhtml">
+<head>
+
+  <meta name="viewport" content="width=device-width, initial-scale=1"/>
+  
+  <title>Serialize-javascript: ver 6.0.0, without npm requirements</title>
+
+  <link rel="shortcut icon" href="./favicon.ico" />
+
+  <meta name="description" content="The complete serialization solution from Yahoo, ver 6.0.0"/>
+  <meta name="keywords" content="5 Mode,object"/>
+  <meta name="robots" content="index,follow"/>
+  <meta name="author" content="5 Mode"/>
+    
+  <script src="./serialize-javascript.js" type="text/javascript"></script>
+    
+  <link href="./css/style.css" type="text/css" rel="stylesheet">  
+  
+  <script type="text/javascript">
+
+    function myObj() {
+      
+      const s = "Hello World!";
+      
+      // Properties
+      this.msg = s;
+      this.start = mystart;
+      
+      // Methods
+      function mystart() {
+	      alert(this.msg);
+      }
+      
+    }  
+
+    function serializeDemo() {
+      thiss = new myObj();
+      alert(serialize(thiss));
+    }  
+
+    function deserializeDemo() {
+      thiss = new myObj();
+      s = serialize(thiss);
+      thatt = deserialize(s);
+      thatt.start();
+    }  
+
+  </script>    
+
+</head>
+
+<body style="margin-top:20px;">
+
+<div style="text-align:center;">
+
+Given the following object:<br><br>
+
+<pre style="width:300px; margin:auto; background: lightgray; text-align:left">
+  
+    function myObj() {
+      
+      const s = "Hello World!";
+      
+      // Properties
+      this.msg = s;
+      this.start = mystart;
+      
+      // Methods
+      function mystart() {
+        alert(this.msg);
+      }
+      
+    }    
+    
+</pre>  
+
+<br>
+
+<input type="button" id="butSerializeDemo" value="Serialize demo" onclick="serializeDemo()">
+
+<br><br>
+
+<input type="button" id="butDeserializeDemo" value="Deserialize demo" onclick="deserializeDemo()">
+
+</div>
+
+</body>
+</html>

+ 268 - 0
index.js.original_code.js

@@ -0,0 +1,268 @@
+/*
+Copyright (c) 2014, Yahoo! Inc. All rights reserved.
+Copyrights licensed under the New BSD License.
+See the accompanying LICENSE file for terms.
+*/
+
+'use strict';
+
+var randomBytes = require('randombytes');
+
+// Generate an internal UID to make the regexp pattern harder to guess.
+var UID_LENGTH          = 16;
+var UID                 = generateUID();
+var PLACE_HOLDER_REGEXP = new RegExp('(\\\\)?"@__(F|R|D|M|S|A|U|I|B|L)-' + UID + '-(\\d+)__@"', 'g');
+
+var IS_NATIVE_CODE_REGEXP = /\{\s*\[native code\]\s*\}/g;
+var IS_PURE_FUNCTION = /function.*?\(/;
+var IS_ARROW_FUNCTION = /.*?=>.*?/;
+var UNSAFE_CHARS_REGEXP   = /[<>\/\u2028\u2029]/g;
+
+var RESERVED_SYMBOLS = ['*', 'async'];
+
+// Mapping of unsafe HTML and invalid JavaScript line terminator chars to their
+// Unicode char counterparts which are safe to use in JavaScript strings.
+var ESCAPED_CHARS = {
+    '<'     : '\\u003C',
+    '>'     : '\\u003E',
+    '/'     : '\\u002F',
+    '\u2028': '\\u2028',
+    '\u2029': '\\u2029'
+};
+
+function escapeUnsafeChars(unsafeChar) {
+    return ESCAPED_CHARS[unsafeChar];
+}
+
+function generateUID() {
+    var bytes = randomBytes(UID_LENGTH);
+    var result = '';
+    for(var i=0; i<UID_LENGTH; ++i) {
+        result += bytes[i].toString(16);
+    }
+    return result;
+}
+
+function deleteFunctions(obj){
+    var functionKeys = [];
+    for (var key in obj) {
+        if (typeof obj[key] === "function") {
+            functionKeys.push(key);
+        }
+    }
+    for (var i = 0; i < functionKeys.length; i++) {
+        delete obj[functionKeys[i]];
+    }
+}
+
+module.exports = function serialize(obj, options) {
+    options || (options = {});
+
+    // Backwards-compatibility for `space` as the second argument.
+    if (typeof options === 'number' || typeof options === 'string') {
+        options = {space: options};
+    }
+
+    var functions = [];
+    var regexps   = [];
+    var dates     = [];
+    var maps      = [];
+    var sets      = [];
+    var arrays    = [];
+    var undefs    = [];
+    var infinities= [];
+    var bigInts = [];
+    var urls = [];
+
+    // Returns placeholders for functions and regexps (identified by index)
+    // which are later replaced by their string representation.
+    function replacer(key, value) {
+
+        // For nested function
+        if(options.ignoreFunction){
+            deleteFunctions(value);
+        }
+
+        if (!value && value !== undefined) {
+            return value;
+        }
+
+        // If the value is an object w/ a toJSON method, toJSON is called before
+        // the replacer runs, so we use this[key] to get the non-toJSONed value.
+        var origValue = this[key];
+        var type = typeof origValue;
+
+        if (type === 'object') {
+            if(origValue instanceof RegExp) {
+                return '@__R-' + UID + '-' + (regexps.push(origValue) - 1) + '__@';
+            }
+
+            if(origValue instanceof Date) {
+                return '@__D-' + UID + '-' + (dates.push(origValue) - 1) + '__@';
+            }
+
+            if(origValue instanceof Map) {
+                return '@__M-' + UID + '-' + (maps.push(origValue) - 1) + '__@';
+            }
+
+            if(origValue instanceof Set) {
+                return '@__S-' + UID + '-' + (sets.push(origValue) - 1) + '__@';
+            }
+
+            if(origValue instanceof Array) {
+                var isSparse = origValue.filter(function(){return true}).length !== origValue.length;
+                if (isSparse) {
+                    return '@__A-' + UID + '-' + (arrays.push(origValue) - 1) + '__@';
+                }
+            }
+
+            if(origValue instanceof URL) {
+                return '@__L-' + UID + '-' + (urls.push(origValue) - 1) + '__@';
+            }
+        }
+
+        if (type === 'function') {
+            return '@__F-' + UID + '-' + (functions.push(origValue) - 1) + '__@';
+        }
+
+        if (type === 'undefined') {
+            return '@__U-' + UID + '-' + (undefs.push(origValue) - 1) + '__@';
+        }
+
+        if (type === 'number' && !isNaN(origValue) && !isFinite(origValue)) {
+            return '@__I-' + UID + '-' + (infinities.push(origValue) - 1) + '__@';
+        }
+
+        if (type === 'bigint') {
+            return '@__B-' + UID + '-' + (bigInts.push(origValue) - 1) + '__@';
+        }
+
+        return value;
+    }
+
+    function serializeFunc(fn) {
+      var serializedFn = fn.toString();
+      if (IS_NATIVE_CODE_REGEXP.test(serializedFn)) {
+          throw new TypeError('Serializing native function: ' + fn.name);
+      }
+
+      // pure functions, example: {key: function() {}}
+      if(IS_PURE_FUNCTION.test(serializedFn)) {
+          return serializedFn;
+      }
+
+      // arrow functions, example: arg1 => arg1+5
+      if(IS_ARROW_FUNCTION.test(serializedFn)) {
+          return serializedFn;
+      }
+
+      var argsStartsAt = serializedFn.indexOf('(');
+      var def = serializedFn.substr(0, argsStartsAt)
+        .trim()
+        .split(' ')
+        .filter(function(val) { return val.length > 0 });
+
+      var nonReservedSymbols = def.filter(function(val) {
+        return RESERVED_SYMBOLS.indexOf(val) === -1
+      });
+
+      // enhanced literal objects, example: {key() {}}
+      if(nonReservedSymbols.length > 0) {
+          return (def.indexOf('async') > -1 ? 'async ' : '') + 'function'
+            + (def.join('').indexOf('*') > -1 ? '*' : '')
+            + serializedFn.substr(argsStartsAt);
+      }
+
+      // arrow functions
+      return serializedFn;
+    }
+
+    // Check if the parameter is function
+    if (options.ignoreFunction && typeof obj === "function") {
+        obj = undefined;
+    }
+    // Protects against `JSON.stringify()` returning `undefined`, by serializing
+    // to the literal string: "undefined".
+    if (obj === undefined) {
+        return String(obj);
+    }
+
+    var str;
+
+    // Creates a JSON string representation of the value.
+    // NOTE: Node 0.12 goes into slow mode with extra JSON.stringify() args.
+    if (options.isJSON && !options.space) {
+        str = JSON.stringify(obj);
+    } else {
+        str = JSON.stringify(obj, options.isJSON ? null : replacer, options.space);
+    }
+
+    // Protects against `JSON.stringify()` returning `undefined`, by serializing
+    // to the literal string: "undefined".
+    if (typeof str !== 'string') {
+        return String(str);
+    }
+
+    // Replace unsafe HTML and invalid JavaScript line terminator chars with
+    // their safe Unicode char counterpart. This _must_ happen before the
+    // regexps and functions are serialized and added back to the string.
+    if (options.unsafe !== true) {
+        str = str.replace(UNSAFE_CHARS_REGEXP, escapeUnsafeChars);
+    }
+
+    if (functions.length === 0 && regexps.length === 0 && dates.length === 0 && maps.length === 0 && sets.length === 0 && arrays.length === 0 && undefs.length === 0 && infinities.length === 0 && bigInts.length === 0 && urls.length === 0) {
+        return str;
+    }
+
+    // Replaces all occurrences of function, regexp, date, map and set placeholders in the
+    // JSON string with their string representations. If the original value can
+    // not be found, then `undefined` is used.
+    return str.replace(PLACE_HOLDER_REGEXP, function (match, backSlash, type, valueIndex) {
+        // The placeholder may not be preceded by a backslash. This is to prevent
+        // replacing things like `"a\"@__R-<UID>-0__@"` and thus outputting
+        // invalid JS.
+        if (backSlash) {
+            return match;
+        }
+
+        if (type === 'D') {
+            return "new Date(\"" + dates[valueIndex].toISOString() + "\")";
+        }
+
+        if (type === 'R') {
+            return "new RegExp(" + serialize(regexps[valueIndex].source) + ", \"" + regexps[valueIndex].flags + "\")";
+        }
+
+        if (type === 'M') {
+            return "new Map(" + serialize(Array.from(maps[valueIndex].entries()), options) + ")";
+        }
+
+        if (type === 'S') {
+            return "new Set(" + serialize(Array.from(sets[valueIndex].values()), options) + ")";
+        }
+
+        if (type === 'A') {
+            return "Array.prototype.slice.call(" + serialize(Object.assign({ length: arrays[valueIndex].length }, arrays[valueIndex]), options) + ")";
+        }
+
+        if (type === 'U') {
+            return 'undefined'
+        }
+
+        if (type === 'I') {
+            return infinities[valueIndex];
+        }
+
+        if (type === 'B') {
+            return "BigInt(\"" + bigInts[valueIndex] + "\")";
+        }
+
+        if (type === 'L') {
+            return "new URL(\"" + urls[valueIndex].toString() + "\")"; 
+        }
+
+        var fn = functions[valueIndex];
+
+        return serializeFunc(fn);
+    });
+}

+ 298 - 0
serialize-javascript.js

@@ -0,0 +1,298 @@
+/*
+Copyright (c) 2014, Yahoo! Inc. All rights reserved.
+Copyright (c) 2021, 5 Mode, requirements, installation and code changes.
+Copyrights licensed under the New BSD License.
+See the accompanying LICENSE file for terms.
+ver. 6.0.0
+*/
+
+'use strict';
+
+// upd - 5 Mode
+//var randomBytes = require('randombytes');
+// ---
+
+// Generate an internal UID to make the regexp pattern harder to guess.
+var UID_LENGTH          = 16;
+var UID                 = generateUID();
+var PLACE_HOLDER_REGEXP = new RegExp('(\\\\)?"@__(F|R|D|M|S|A|U|I|B|L)-' + UID + '-(\\d+)__@"', 'g');
+
+var IS_NATIVE_CODE_REGEXP = /\{\s*\[native code\]\s*\}/g;
+var IS_PURE_FUNCTION = /function.*?\(/;
+var IS_ARROW_FUNCTION = /.*?=>.*?/;
+var UNSAFE_CHARS_REGEXP   = /[<>\/\u2028\u2029]/g;
+
+var RESERVED_SYMBOLS = ['*', 'async'];
+
+// Mapping of unsafe HTML and invalid JavaScript line terminator chars to their
+// Unicode char counterparts which are safe to use in JavaScript strings.
+var ESCAPED_CHARS = {
+    '<'     : '\\u003C',
+    '>'     : '\\u003E',
+    '/'     : '\\u002F',
+    '\u2028': '\\u2028',
+    '\u2029': '\\u2029'
+};
+
+function escapeUnsafeChars(unsafeChar) {
+    return ESCAPED_CHARS[unsafeChar];
+}
+
+// upd - 5 Mode
+function rnd(min, max) {
+  var ress = "";
+  var resa = [];
+  min = Math.ceil(min);
+  max = Math.floor(max);
+  //return Math.floor(Math.random() * (max - min +1)) + min;
+  ress = (Math.floor(Math.random() * (max - min +1)) + min) + "";
+  for (var i=0;i<UID_LENGTH;i++) {
+    resa[i] = ress.substr(i,1);
+  }  
+  return resa;
+}
+// ---
+
+function generateUID() {
+    // upd - 5 Mode
+    //var bytes = randomBytes(UID_LENGTH);
+    var bytes = rnd(1000000000000000, 9999999999999999);
+    // ---
+    var result = '';
+    for(var i=0; i<UID_LENGTH; ++i) {
+        result += bytes[i].toString(16);
+    }
+    return result;
+}
+
+function deleteFunctions(obj){
+    var functionKeys = [];
+    for (var key in obj) {
+        if (typeof obj[key] === "function") {
+            functionKeys.push(key);
+        }
+    }
+    for (var i = 0; i < functionKeys.length; i++) {
+        delete obj[functionKeys[i]];
+    }
+}
+
+// upd - 5 Mode
+//module.exports = function serialize(obj, options) {
+// ---  
+function serialize(obj, options) {
+
+    options || (options = {});
+
+    // Backwards-compatibility for `space` as the second argument.
+    if (typeof options === 'number' || typeof options === 'string') {
+        options = {space: options};
+    }
+
+    var functions = [];
+    var regexps   = [];
+    var dates     = [];
+    var maps      = [];
+    var sets      = [];
+    var arrays    = [];
+    var undefs    = [];
+    var infinities= [];
+    var bigInts = [];
+    var urls = [];
+
+    // Returns placeholders for functions and regexps (identified by index)
+    // which are later replaced by their string representation.
+    function replacer(key, value) {
+
+        // For nested function
+        if(options.ignoreFunction){
+            deleteFunctions(value);
+        }
+
+        if (!value && value !== undefined) {
+            return value;
+        }
+
+        // If the value is an object w/ a toJSON method, toJSON is called before
+        // the replacer runs, so we use this[key] to get the non-toJSONed value.
+        var origValue = this[key];
+        var type = typeof origValue;
+
+        if (type === 'object') {
+            if(origValue instanceof RegExp) {
+                return '@__R-' + UID + '-' + (regexps.push(origValue) - 1) + '__@';
+            }
+
+            if(origValue instanceof Date) {
+                return '@__D-' + UID + '-' + (dates.push(origValue) - 1) + '__@';
+            }
+
+            if(origValue instanceof Map) {
+                return '@__M-' + UID + '-' + (maps.push(origValue) - 1) + '__@';
+            }
+
+            if(origValue instanceof Set) {
+                return '@__S-' + UID + '-' + (sets.push(origValue) - 1) + '__@';
+            }
+
+            if(origValue instanceof Array) {
+                var isSparse = origValue.filter(function(){return true}).length !== origValue.length;
+                if (isSparse) {
+                    return '@__A-' + UID + '-' + (arrays.push(origValue) - 1) + '__@';
+                }
+            }
+
+            if(origValue instanceof URL) {
+                return '@__L-' + UID + '-' + (urls.push(origValue) - 1) + '__@';
+            }
+        }
+
+        if (type === 'function') {
+            return '@__F-' + UID + '-' + (functions.push(origValue) - 1) + '__@';
+        }
+
+        if (type === 'undefined') {
+            return '@__U-' + UID + '-' + (undefs.push(origValue) - 1) + '__@';
+        }
+
+        if (type === 'number' && !isNaN(origValue) && !isFinite(origValue)) {
+            return '@__I-' + UID + '-' + (infinities.push(origValue) - 1) + '__@';
+        }
+
+        if (type === 'bigint') {
+            return '@__B-' + UID + '-' + (bigInts.push(origValue) - 1) + '__@';
+        }
+
+        return value;
+    }
+
+    function serializeFunc(fn) {
+      var serializedFn = fn.toString();
+      if (IS_NATIVE_CODE_REGEXP.test(serializedFn)) {
+          throw new TypeError('Serializing native function: ' + fn.name);
+      }
+
+      // pure functions, example: {key: function() {}}
+      if(IS_PURE_FUNCTION.test(serializedFn)) {
+          return serializedFn;
+      }
+
+      // arrow functions, example: arg1 => arg1+5
+      if(IS_ARROW_FUNCTION.test(serializedFn)) {
+          return serializedFn;
+      }
+
+      var argsStartsAt = serializedFn.indexOf('(');
+      var def = serializedFn.substr(0, argsStartsAt)
+        .trim()
+        .split(' ')
+        .filter(function(val) { return val.length > 0 });
+
+      var nonReservedSymbols = def.filter(function(val) {
+        return RESERVED_SYMBOLS.indexOf(val) === -1
+      });
+
+      // enhanced literal objects, example: {key() {}}
+      if(nonReservedSymbols.length > 0) {
+          return (def.indexOf('async') > -1 ? 'async ' : '') + 'function'
+            + (def.join('').indexOf('*') > -1 ? '*' : '')
+            + serializedFn.substr(argsStartsAt);
+      }
+
+      // arrow functions
+      return serializedFn;
+    }
+
+    // Check if the parameter is function
+    if (options.ignoreFunction && typeof obj === "function") {
+        obj = undefined;
+    }
+    // Protects against `JSON.stringify()` returning `undefined`, by serializing
+    // to the literal string: "undefined".
+    if (obj === undefined) {
+        return String(obj);
+    }
+
+    var str;
+
+    // Creates a JSON string representation of the value.
+    // NOTE: Node 0.12 goes into slow mode with extra JSON.stringify() args.
+    if (options.isJSON && !options.space) {
+        str = JSON.stringify(obj);
+    } else {
+        str = JSON.stringify(obj, options.isJSON ? null : replacer, options.space);
+    }
+
+    // Protects against `JSON.stringify()` returning `undefined`, by serializing
+    // to the literal string: "undefined".
+    if (typeof str !== 'string') {
+        return String(str);
+    }
+
+    // Replace unsafe HTML and invalid JavaScript line terminator chars with
+    // their safe Unicode char counterpart. This _must_ happen before the
+    // regexps and functions are serialized and added back to the string.
+    if (options.unsafe !== true) {
+        str = str.replace(UNSAFE_CHARS_REGEXP, escapeUnsafeChars);
+    }
+
+    if (functions.length === 0 && regexps.length === 0 && dates.length === 0 && maps.length === 0 && sets.length === 0 && arrays.length === 0 && undefs.length === 0 && infinities.length === 0 && bigInts.length === 0 && urls.length === 0) {
+        return str;
+    }
+
+    // Replaces all occurrences of function, regexp, date, map and set placeholders in the
+    // JSON string with their string representations. If the original value can
+    // not be found, then `undefined` is used.
+    return str.replace(PLACE_HOLDER_REGEXP, function (match, backSlash, type, valueIndex) {
+        // The placeholder may not be preceded by a backslash. This is to prevent
+        // replacing things like `"a\"@__R-<UID>-0__@"` and thus outputting
+        // invalid JS.
+        if (backSlash) {
+            return match;
+        }
+
+        if (type === 'D') {
+            return "new Date(\"" + dates[valueIndex].toISOString() + "\")";
+        }
+
+        if (type === 'R') {
+            return "new RegExp(" + serialize(regexps[valueIndex].source) + ", \"" + regexps[valueIndex].flags + "\")";
+        }
+
+        if (type === 'M') {
+            return "new Map(" + serialize(Array.from(maps[valueIndex].entries()), options) + ")";
+        }
+
+        if (type === 'S') {
+            return "new Set(" + serialize(Array.from(sets[valueIndex].values()), options) + ")";
+        }
+
+        if (type === 'A') {
+            return "Array.prototype.slice.call(" + serialize(Object.assign({ length: arrays[valueIndex].length }, arrays[valueIndex]), options) + ")";
+        }
+
+        if (type === 'U') {
+            return 'undefined'
+        }
+
+        if (type === 'I') {
+            return infinities[valueIndex];
+        }
+
+        if (type === 'B') {
+            return "BigInt(\"" + bigInts[valueIndex] + "\")";
+        }
+
+        if (type === 'L') {
+            return "new URL(\"" + urls[valueIndex].toString() + "\")"; 
+        }
+
+        var fn = functions[valueIndex];
+
+        return serializeFunc(fn);
+    });
+}
+
+function deserialize(serializedJavascript){
+  return eval('(' + serializedJavascript + ')');
+}