(function (global, factory) {
    typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports) :
    typeof define === 'function' && define.amd ? define(['exports'], factory) :
    (global = typeof globalThis !== 'undefined' ? globalThis : global || self, factory(global.JsonCanonicalize = {}));
}(this, (function (exports) { 'use strict';

    function canonicalize(obj) {
        var buffer = '';
        serialize(obj);
        return buffer;
        function serialize(object) {
            if (object === null ||
                typeof object !== 'object' ||
                object.toJSON != null) {
                /////////////////////////////////////////////////
                // Primitive data type - Use ES6/JSON          //
                /////////////////////////////////////////////////
                buffer += JSON.stringify(object);
                // } else if (object instanceof Date) {
                //   buffer += JSON.stringify(object);
            }
            else if (Array.isArray(object)) {
                /////////////////////////////////////////////////
                // Array - Maintain element order              //
                /////////////////////////////////////////////////
                buffer += '[';
                var next_1 = false;
                object.forEach(function (element) {
                    if (next_1) {
                        buffer += ',';
                    }
                    next_1 = true;
                    if (element === undefined) {
                        element = null;
                    }
                    /////////////////////////////////////////
                    // Array element - Recursive expansion //
                    /////////////////////////////////////////
                    serialize(element);
                });
                buffer += ']';
            }
            else {
                /////////////////////////////////////////////////
                // Object - Sort properties before serializing //
                /////////////////////////////////////////////////
                buffer += '{';
                var vKeys = Object.keys(object).filter(function (k) { return object[k] !== undefined; }).sort();
                vKeys.forEach(function (property, index) { return addProp(object, property, index); });
                buffer += '}';
            }
        }
        function addProp(object, property, index) {
            if (index > 0) {
                buffer += ',';
            }
            ///////////////////////////////////////////////
            // Property names are strings - Use ES6/JSON //
            ///////////////////////////////////////////////
            buffer += JSON.stringify(property);
            buffer += ':';
            //////////////////////////////////////////
            // Property value - Recursive expansion //
            //////////////////////////////////////////
            serialize(object[property]);
        }
    }

    function canonicalizeEx(obj, options) {
        var buffer = '';
        var vInclude = options && options.include;
        var vExclude = options && options.exclude;
        if (vExclude) {
            if (typeof vExclude === 'string')
                vExclude = [vExclude];
        }
        if (vInclude)
            vInclude.sort();
        serialize(obj);
        return buffer;
        function serialize(object, parent) {
            if (object === null ||
                typeof object !== 'object' ||
                object.toJSON != null) {
                /////////////////////////////////////////////////
                // Primitive data type - Use ES6/JSON          //
                /////////////////////////////////////////////////
                buffer += JSON.stringify(object);
                // } else if (object instanceof Date) {
                //   buffer += JSON.stringify(object);
            }
            else if (Array.isArray(object)) {
                /////////////////////////////////////////////////
                // Array - Maintain element order              //
                /////////////////////////////////////////////////
                buffer += '[';
                var next_1 = false;
                object.forEach(function (element) {
                    if (next_1) {
                        buffer += ',';
                    }
                    next_1 = true;
                    /////////////////////////////////////////
                    // Array element - Recursive expansion //
                    /////////////////////////////////////////
                    serialize(element, object);
                });
                buffer += ']';
            }
            else {
                /////////////////////////////////////////////////
                // Object - Sort properties before serializing //
                /////////////////////////////////////////////////
                buffer += '{';
                if (!parent && vInclude) {
                    vInclude.forEach(function (property, index) {
                        if (!object.hasOwnProperty(property))
                            return;
                        addProp(object, property, index);
                    });
                }
                else {
                    var vKeys = Object.keys(object).sort();
                    vKeys.forEach(function (property, index) { return addProp(object, property, index); });
                }
                buffer += '}';
            }
        }
        function addProp(object, property, index) {
            if (vExclude && vExclude.length) {
                for (var _i = 0, vExclude_1 = vExclude; _i < vExclude_1.length; _i++) {
                    var v = vExclude_1[_i];
                    if (v === property)
                        return;
                }
            }
            if (index > 0) {
                buffer += ',';
            }
            ///////////////////////////////////////////////
            // Property names are strings - Use ES6/JSON //
            ///////////////////////////////////////////////
            buffer += JSON.stringify(property);
            buffer += ':';
            //////////////////////////////////////////
            // Property value - Recursive expansion //
            //////////////////////////////////////////
            serialize(object[property], object);
        }
    }

    exports.canonicalize = canonicalize;
    exports.canonicalizeEx = canonicalizeEx;

    Object.defineProperty(exports, '__esModule', { value: true });

})));
//# sourceMappingURL=index.umd.js.map
