// Begin----------------------------------------------------------------

/* function cloneObject-------------------------------------------------
 *
 * Clones complex objects
 *
 * Original code from Rajesh Mohana
 * https://stackblitz.com/edit/typescript-vudfgn
 * with modifications and additions from Stefan Schnell
 */
function cloneObject(obj) {

  var clone = {};

  if (
    (typeof obj === "object" && obj === null) ||
     typeof obj === "undefined" ||
     typeof obj === "number" ||
     typeof obj === "string" ||
     typeof obj === "boolean"
  ) {
    // If primitive datatype--------------------------------------------
    clone = obj;
  } else if (typeof obj === "object" && Array.isArray(obj)) {
    // If array---------------------------------------------------------
    clone = obj.slice();
  } else {
    for (var i in obj) {
      if ((obj[i] !== null) && (typeof obj[i] === "object")) {
        if (obj[i] instanceof Date) {
          // If date----------------------------------------------------
          clone[i] = new Date(obj[i]);
        } else if (!Array.isArray(obj[i])) {
          // If non-array-----------------------------------------------
          clone[i] = cloneObject(obj[i]);
        } else if (Array.isArray(obj[i])) {
          // If array---------------------------------------------------
          clone[i] = obj[i].map( function(arrayObj) {
            return cloneObject(arrayObj);
          });
        }
      } else {
        clone[i] = obj[i];
      }
    }
  }

  return clone;

}

// Main-----------------------------------------------------------------
var obj = {
  a : 1,
  b : {
    ba : 2,
  },
  c : [1, 2, 3],
  d : [
    {
      da : ['da1', 'da2', 'da3'],
    },
    {
      db : ['db1', 'db2', 'db3'],
    },
    {
      dc : [
        {
          dca : ['dca1', 'dca2', null],
        },
      ],
    },
    null,
    undefined,
    NaN,
    0,
    '',
    ['a', 'b', ['c', 'd'], ['e', 'f']],
    [
      {
        dda : 1,
      },
      {
        ddb : 1,
      },
    ],
  ],
  e : [true, false],
  f : [[1, 2]],
  g : function() {
    return "Hello World";
  },
  h : new Date(),
  z : "End"
};

var newObj = cloneObject(obj);

// End------------------------------------------------------------------