UNPKG

music21j-port

Version:

A toolkit for computer-aided musicology, Javascript version

914 lines (847 loc) 29.7 kB
/** * jsonpickle.js 1.0.0 built on * 2016-09-02. * Copyright (c) 2013-2016 Michael Scott Cuthbert and cuthbertLab * * http://github.com/cuthbertLab/jsonpickleJS */ (function (global, factory) { typeof exports === 'object' && typeof module !== 'undefined' ? module.exports = factory() : typeof define === 'function' && define.amd ? define(factory) : (global.jsonpickle = factory()); }(this, (function () { 'use strict'; var tags = { ID: 'py/id', OBJECT: 'py/object', TYPE: 'py/type', REPR: 'py/repr', REF: 'py/ref', TUPLE: 'py/tuple', SET: 'py/set', SEQ: 'py/seq', STATE: 'py/state', JSON_KEY: 'json://' }; tags.RESERVED = [tags.ID, tags.OBJECT, tags.TYPE, tags.REPR, tags.REF, tags.TUPLE, tags.SET, tags.SEQ, tags.STATE, tags.JSON_KEY]; tags.PY_CLASS = '_py_class'; var _typeof = typeof Symbol === "function" && typeof Symbol.iterator === "symbol" ? function (obj) { return typeof obj; } : function (obj) { return obj && typeof Symbol === "function" && obj.constructor === Symbol ? "symbol" : typeof obj; }; var classCallCheck = function (instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }; var createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }(); var util = {}; util.merge = function merge(destination, source) { if (source === undefined) { return destination; } for (var prop in source) { if (!{}.hasOwnProperty.call(source, prop)) { continue; } destination[prop] = source[prop]; } return destination; }; util.PRIMITIVES = ['string', 'number', 'boolean']; /* from jsonpickle.util */ // to_do... util.is_type = function (obj) { return false; }; // same as dictionary in JS... util.is_object = function (obj) { return util.is_dictionary(obj); }; util.is_primitive = function (obj) { if (obj === undefined || obj == null) { return true; } if (util.PRIMITIVES.indexOf(typeof obj === 'undefined' ? 'undefined' : _typeof(obj)) !== -1) { return true; } return false; }; util.is_dictionary = function (obj) { return (typeof obj === 'undefined' ? 'undefined' : _typeof(obj)) === 'object' && obj !== null; }; util.is_sequence = function (obj) { return util.is_list(obj) || util.is_set(obj) || util.is_tuple(obj); }; util.is_list = function (obj) { return obj instanceof Array; }; // to_do... util.is_set = function (obj) { return false; }; util.is_tuple = function (obj) { return false; }; util.is_dictionary_subclass = function (obj) { return false; }; util.is_sequence_subclass = function (obj) { return false; }; util.is_noncomplex = function (obj) { return false; }; util.is_function = function (obj) { return typeof obj === 'function'; }; util.is_module = function (obj) { return false; }; util.is_picklable = function (name, value) { if (tags.RESERVED.indexOf(name) !== -1) { return false; } if (util.is_function(value)) { return false; } else { return true; } }; util.is_installed = function (module) { return true; }; // ??? util.is_list_like = function (obj) { return util.is_list(obj); }; var handlers = { 'fractions.Fraction': { restore: function restore(obj) { return obj._numerator / obj._denominator; } } }; /** * jsonPickle/javascript/unpickler -- Conversion from music21p jsonpickle streams * * Copyright (c) 2013-14, Michael Scott Cuthbert and cuthbertLab * Based on music21 (=music21p), Copyright (c) 2006–14, Michael Scott Cuthbert and cuthbertLab * * usage: * * js_obj = unpickler.decode(json_string); * */ var unpickler = {}; unpickler.decode = function decode(string, user_handlers, options) { var params = { keys: false, safe: false, reset: true, backend: JSON }; util.merge(params, options); var use_handlers = {}; util.merge(use_handlers, handlers); // don't screw up default handlers... util.merge(use_handlers, user_handlers); var context = void 0; // backend does not do anything -- it is there for // compat with py-JSON-Pickle if (params.context === undefined) { var unpickler_options = { keys: params.keys, backend: params.backend, safe: params.safe }; context = new unpickler.Unpickler(unpickler_options, use_handlers); } else { context = params.context; } var jsonObj = params.backend.parse(string); return context.restore(jsonObj, params.reset); }; var Unpickler = function () { function Unpickler(options, handlers) { classCallCheck(this, Unpickler); var params = { keys: false, safe: false }; util.merge(params, options); this.keys = params.keys; this.safe = params.safe; this.handlers = handlers; // obsolete... // this._namedict = {}; // The namestack grows whenever we recurse into a child object this._namestack = []; // Maps objects to their index in the _objs list this._obj_to_idx = {}; this._objs = []; } createClass(Unpickler, [{ key: 'reset', value: function reset() { // this._namedict = {}; this._namestack = []; this._obj_to_idx = {}; this._objs = []; } /** * Restores a flattened object to a JavaScript representation * as close to the original python object as possible. * */ }, { key: 'restore', value: function restore(obj, reset) { if (reset) { this.reset(); } return this._restore(obj); } }, { key: '_restore', value: function _restore(obj) { var has_tag = unpickler.has_tag; var restoreMeth = function restoreMeth(obj) { return obj; }; if (has_tag(obj, tags.ID)) { restoreMeth = this._restore_id.bind(this); } else if (has_tag(obj, tags.REF)) { // backwards compat. not supported } else if (has_tag(obj, tags.TYPE)) { restoreMeth = this._restore_type.bind(this); } else if (has_tag(obj, tags.REPR)) { // backwards compat. not supported } else if (has_tag(obj, tags.OBJECT)) { restoreMeth = this._restore_object.bind(this); } else if (has_tag(obj, tags.TUPLE)) { restoreMeth = this._restore_tuple.bind(this); } else if (has_tag(obj, tags.SET)) { restoreMeth = this._restore_set.bind(this); } else if (util.is_list(obj)) { restoreMeth = this._restore_list.bind(this); } else if (util.is_dictionary(obj)) { restoreMeth = this._restore_dict.bind(this); } else { // map to self } return restoreMeth(obj); } }, { key: '_restore_id', value: function _restore_id(obj) { return this._objs[obj[tags.ID]]; } }, { key: '_restore_type', value: function _restore_type(obj) { var typeref = unpickler.loadclass(obj[tags.TYPE]); if (typeref === undefined) { return obj; } else { return typeref; } } }, { key: '_restore_object', value: function _restore_object(obj) { var class_name = obj[tags.OBJECT]; var handler = this.handlers[class_name]; if (handler !== undefined && handler.restore !== undefined) { var instance = handler.restore(obj); instance[tags.PY_CLASS] = class_name; return this._mkref(instance); } else { var cls = unpickler.loadclass(class_name); if (cls === undefined) { obj[tags.PY_CLASS] = class_name; return this._mkref(obj); } var _instance = this._restore_object_instance(obj, cls); _instance[tags.PY_CLASS] = class_name; if (handler !== undefined && handler.post_restore !== undefined) { return handler.post_restore(_instance); } else { return _instance; } } } }, { key: '_loadfactory', value: function _loadfactory(obj) { var default_factory = obj.default_factory; if (default_factory === undefined) { return undefined; } else { obj.default_factory = undefined; return this._restore(default_factory); } } }, { key: '_restore_object_instance', value: function _restore_object_instance(obj, cls) { // var factory = this._loadfactory(obj); var args = unpickler.getargs(obj); if (args.length > 0) { args = this._restore(args); } // not using factory... does not seem to apply to JS var instance = unpickler.construct(cls, args); this._mkref(instance); return this._restore_object_instance_variables(obj, instance); } }, { key: '_restore_object_instance_variables', value: function _restore_object_instance_variables(obj, instance) { var has_tag = unpickler.has_tag; var restore_key = this._restore_key_fn(); var keys = []; for (var k in obj) { if ({}.hasOwnProperty.call(obj, k)) { keys.push(k); } } keys.sort(); for (var i = 0; i < keys.length; i++) { var _k = keys[i]; if (tags.RESERVED.indexOf(_k) !== -1) { continue; } var v = obj[_k]; this._namestack.push(_k); _k = restore_key(_k); var value = void 0; if (v !== undefined && v !== null) { value = this._restore(v); } // no setattr checks... instance[_k] = value; this._namestack.pop(); } if (has_tag(obj, tags.SEQ)) { if (instance.push !== undefined) { for (var _v in obj[tags.SEQ]) { if (!{}.hasOwnProperty.call(obj[tags.SEQ], _v)) { continue; } instance.push(this._restore(_v)); } } // no .add ... } if (has_tag(obj, tags.STATE)) { instance = this._restore_state(obj, instance); } return instance; } }, { key: '_restore_state', value: function _restore_state(obj, instance) { // only if the JS object implements __setstate__ if (instance.__setstate__ !== undefined) { var state = this._restore(obj[tags.STATE]); instance.__setstate__(state); } else { instance = this._restore_object_instance_variables(obj[tags.STATE], instance); } return instance; } }, { key: '_restore_list', value: function _restore_list(obj) { var parent = []; this._mkref(parent); var children = []; for (var i = 0; i < obj.length; i++) { var v = obj[i]; var rest = this._restore(v); children.push(rest); } parent.push.apply(parent, children); return parent; } }, { key: '_restore_tuple', value: function _restore_tuple(obj) { // JS having no difference between list, tuple, set -- returns Array var children = []; var tupleContents = obj[tags.TUPLE]; for (var i = 0; i < tupleContents.length; i++) { children.push(this._restore(tupleContents[i])); } return children; } }, { key: '_restore_set', value: function _restore_set(obj) { // JS having no difference between list, tuple, set -- returns Array // TODO: ES5 Sets! var children = []; var setContents = obj[tags.SET]; for (var i = 0; i < setContents.length; i++) { children.push(this._restore(setContents[i])); } return children; } }, { key: '_restore_dict', value: function _restore_dict(obj) { var data = {}; // var restore_key = this._restore_key_fn(); var keys = []; for (var k in obj) { if ({}.hasOwnProperty.call(obj, k)) { keys.push(k); } } keys.sort(); for (var i = 0; i < keys.length; i++) { var _k2 = keys[i]; var v = obj[_k2]; this._namestack.push(_k2); data[_k2] = this._restore(v); // no setattr checks... this._namestack.pop(); } return data; } }, { key: '_restore_key_fn', value: function _restore_key_fn() { var _this = this; if (this.keys) { return function (key) { if (key.indexOf(tags.JSON_KEY) === 0) { key = unpickler.decode(key.slice(tags.JSON_KEY.length), _this.handlers, { context: _this, keys: _this.keys, reset: false }); return key; } else { return key; } }; } else { return function (key) { return key; }; } } // _refname not needed... }, { key: '_mkref', value: function _mkref(obj) { // does not use id(obj) in javascript this._objs.push(obj); return obj; } }]); return Unpickler; }(); unpickler.Unpickler = Unpickler; unpickler.getargs = function getargs(obj) { var seq_list = obj[tags.SEQ]; var obj_dict = obj[tags.OBJECT]; if (seq_list === undefined || obj_dict === undefined) { return []; } var typeref = unpickler.loadclass(obj_dict); if (typeref === undefined) { return []; } if (typeref._fields !== undefined) { if (typeref._fields.length === seq_list.length) { return seq_list; } } return []; }; unpickler.loadclass = function loadclass(module_and_name) { var main_check = '__main__.'; if (module_and_name.indexOf(main_check) === 0) { module_and_name = module_and_name.slice(main_check.length); } var parent = window; var module_class_split = module_and_name.split('.'); for (var i = 0; i < module_class_split.length; i++) { var this_module_or_class = module_class_split[i]; parent = parent[this_module_or_class]; if (parent === undefined) { return parent; } } return parent; }; unpickler.has_tag = function has_tag(obj, tag) { if ((typeof obj === 'undefined' ? 'undefined' : _typeof(obj)) === 'object' && obj !== null && obj[tag] !== undefined) { return true; } else { return false; } }; // http://stackoverflow.com/questions/1606797/use-of-apply-with-new-operator-is-this-possible unpickler.construct = function construct(constructor, args) { function F() { return constructor.apply(this, args); } F.prototype = constructor.prototype; return new F(); }; var pickler = {}; pickler.encode = function encode(value, options) { var params = { unpicklable: false, make_refs: true, keys: false, max_depth: undefined, reset: true, backend: undefined, // does nothing; python compat context: undefined }; util.merge(params, options); if (params.context === undefined) { var outparams = { unpicklable: params.unpicklable, make_refs: params.make_refs, keys: params.keys, backend: params.backend, max_depth: params.max_depth }; params.context = new pickler.Pickler(outparams); var fixed_obj = params.context.flatten(value, params.reset); return JSON.stringify(fixed_obj); } else { return undefined; } }; var Pickler = function () { function Pickler(options) { classCallCheck(this, Pickler); var params = { unpicklable: true, make_refs: true, max_depth: undefined, backend: undefined, keys: false }; util.merge(params, options); this.unpicklable = params.unpicklable; this.make_refs = params.make_refs; this.backend = params.backend; this.keys = params.keys; this._depth = -1; this._max_depth = params.max_depth; this._objs = []; this._seen = []; } createClass(Pickler, [{ key: 'reset', value: function reset() { this._objs = []; this._depth = -1; this._seen = []; } }, { key: '_push', value: function _push() { this._depth += 1; } }, { key: '_pop', value: function _pop(value) { this._depth -= 1; if (this._depth === -1) { this.reset(); } return value; } }, { key: '_mkref', value: function _mkref(obj) { var found_id = this._get_id_in_objs(obj); // console.log(found_id); if (found_id !== -1) { return false; // if (this.unpicklable == false || this.make_refs == false) { // return true; // } else { // return false; // } } this._objs.push(obj); return true; } }, { key: '_get_id_in_objs', value: function _get_id_in_objs(obj) { var objLength = this._objs.length; // console.log('sought obj', obj); // console.log('stored objs: ', this._objs); for (var i = 0; i < objLength; i++) { if (obj === this._objs[i]) { return i; } } return -1; } }, { key: '_getref', value: function _getref(obj) { var wrap_obj = {}; wrap_obj[tags.ID] = this._get_id_in_objs(obj); return wrap_obj; } }, { key: 'flatten', value: function flatten(obj, reset) { if (reset === undefined) { reset = true; } if (reset) { this.reset(); } var flatOut = this._flatten(obj); console.log(this._objs); return flatOut; } }, { key: '_flatten', value: function _flatten(obj) { this._push(); return this._pop(this._flatten_obj(obj)); } }, { key: '_flatten_obj', value: function _flatten_obj(obj) { this._seen.push(obj); var max_reached = this._depth === this._max_depth; if (max_reached || this.make_refs === false && this._get_id_in_objs(obj) !== -1) { // no repr equivalent, use str; return toString(obj); } else { var flattener = this._get_flattener(obj); // console.log(flattener); return flattener.call(this, obj); } } }, { key: '_list_recurse', value: function _list_recurse(obj) { var l = []; for (var i = 0; i < obj.length; i++) { l.push(this._flatten(obj[i])); } return l; } }, { key: '_get_flattener', value: function _get_flattener(obj) { var _this = this; if (util.is_primitive(obj)) { return function (obj) { return obj; }; } if (util.is_list(obj)) { if (this._mkref(obj)) { return this._list_recurse; } else { this._push(); return this._getref; } } if (util.is_tuple(obj)) { if (!this.unpicklable) { return this._list_recurse; } else { return function (obj) { var obj_wrap = {}; obj_wrap[tags.TUPLE] = _this._list_recurse(obj); }; } } if (util.is_set(obj)) { if (!this.unpicklable) { return this._list_recurse; } else { return function (obj) { var obj_wrap = {}; obj_wrap[tags.SET] = _this._list_recurse(obj); }; } } // better -- translate as object... // if (util.is_dictionary(obj)) { // return this._flatten_dict_obj; // } // if (util.is_type(obj)) { // return _mktyperef; // } if (util.is_object(obj)) { return this._ref_obj_instance; } console.log('no flattener for ', obj, ' of type ', typeof obj === 'undefined' ? 'undefined' : _typeof(obj)); return undefined; } }, { key: '_ref_obj_instance', value: function _ref_obj_instance(obj) { if (this._mkref(obj)) { return this._flatten_obj_instance(obj); } return this._getref(obj); } }, { key: '_flatten_obj_instance', value: function _flatten_obj_instance(obj) { var data = {}; var has_class = obj[tags.PY_CLASS] !== undefined; // ? or ... var has_dict = true; // const has_slots = false; var has_getstate = obj.__getstate__ !== undefined; if (has_class && util.is_module(obj) === false) { var fullModuleName = pickler._getclassdetail(obj); if (this.unpicklable) { data[tags.OBJECT] = fullModuleName; console.log(data); } var handler = handlers[fullModuleName]; if (handler !== undefined) { handler.flatten(obj, data); } } if (util.is_module(obj)) { // todo if possible to have this happen... } if (util.is_dictionary_subclass(obj)) { // todo if possible to have this happen... } if (has_dict) { // where every object currently ends up if (util.is_sequence_subclass(obj)) { // todo if possible to be... } if (has_getstate) { return this._getstate(obj, data); } return this._flatten_dict_obj(obj, data); } return undefined; // todo: is_sequence_subclass // todo: is_noncomplex // todo: has_slots... } }, { key: '_flatten_dict_obj', value: function _flatten_dict_obj(obj, data) { if (data === undefined) { data = new obj.prototype.constructor(); } var key_index = []; for (var key in obj) { if ({}.hasOwnProperty.call(obj, key)) { key_index.push(key); } } for (var i = 0; i < key_index.length; i++) { var _key = key_index[i]; var value = obj[_key]; if (_key === tags.PY_CLASS) { continue; } this._flatten_key_value_pair(_key, value, data); } // default_factory... return data; } // _flatten_newstyle_with_slots }, { key: '_flatten_key_value_pair', value: function _flatten_key_value_pair(k, v, data) { if (util.is_picklable(k, v) === false) { return data; } // assume all keys are strings -- Javascript; data[k] = this._flatten(v); return data; } // pickler.Pickler.prototype._flatten_sequence_obj = function () {}; }, { key: '_getstate', value: function _getstate(obj, data) { var state = this._flatten_obj(obj.__getstate__()); if (this.unpicklable) { data[tags.STATE] = state; } else { data = state; } return data; } // pickler._mktyperef = function (obj) {}; }, { key: '_getclassdetail', value: function _getclassdetail(obj) { // just returns the Python class name return obj[tags.PY_CLASS]; } }]); return Pickler; }(); pickler.Pickler = Pickler; /** * jsonpickleJS -- interpretation of python jsonpickle in Javascript * main.js -- main loader -- this should be the only file that most users care about. * * Copyright (c) 2014-16 Michael Scott Cuthbert and cuthbertLab */ var jsonpickle = {}; jsonpickle.pickler = pickler; jsonpickle.unpickler = unpickler; jsonpickle.util = util; jsonpickle.tags = tags; jsonpickle.handlers = handlers; jsonpickle.encode = function jsonpickle_encode(value, unpicklable, make_refs, keys, max_depth, backend) { if (unpicklable === undefined) { unpicklable = true; } if (make_refs === undefined) { make_refs = true; } if (keys === undefined) { keys = false; } var options = { unpicklable: unpicklable, make_refs: make_refs, keys: keys, max_depth: max_depth, backend: backend }; return pickler.encode(value, options); }; jsonpickle.decode = function jsonpickle_decode(string, backend, keys) { if (keys === undefined) { keys = false; } return unpickler.decode(string, backend, keys); }; window.jsonpickle = {}; return jsonpickle; }))); //# sourceMappingURL=jsonpickle.debug.js.map