Encapsulate a startable function description
@class StartableModel
432947
function StartableModel(model,instance) {
    if(!model) {
        throw new Error('model is required')
    }
    if(!instance) {
        throw new Error('instance is required')
    }
    if(!(this instanceof StartableModel)) {
        return new StartableModel(model,instance,index)
    }
    this.model = model
    this.key = model.key
    this.instance= instance
    this.fn = instance[model.startable]
    if(!this.fn) {
        throw new Error('The instance of ' +
                        this.key +
                        ' does not have a method ' +
                        model.startable +
                       ' which is required for starting this service.')
    }
    this.inject = (this.fn.inject || [])
    this.hasDeps = (this.inject.length > 0)
}
774769
function modelExport(m) {
  const result = _.mapValues(m.classes, _.head)
  result[m.__name] = m
  return result
}
98866
function init (model) {
    if (model.__ttl) return;

    var distinct_ = model.distinct;
    model.distinct = function distinct (field, cond, cb) {
      applyTTL(cond);
      return distinct_.call(model, field, cond, cb);
    }

    'findOne find count'.split(' ').forEach(function (method) {
      var fn = model[method];

      model[method] = function (cond, fields, opts, cb) {
        if (!cond) {
          cond = {};
        } else if ('function' == typeof cond) {
          cb = cond;
          cond = {};
        }

        applyTTL(cond);
        return fn.call(model, cond, fields, opts, cb);
      }
    });

    'where $where'.split(' ').forEach(function (method) {
      var fn = model[method];
      model[method] = function () {
        var query = fn.apply(this, arguments)
          , cond = {};
        applyTTL(cond);
        return query.find(cond);
      }
    });

    if (reap) {
      model.startTTLReaper();
    }
  }
1134934
function Model(value) {
                var instance = this,
                    commits = [];

                // if the value is undefined, create a empty obj
                value = value || {};

                // build the defaults but only on new instances
                forEach(options.defaults, function(v, k){
                    // only populates when not already defined
                    if(value[k] === undefined){
                        if(typeof v === 'function'){
                            // pass the value so you can combine things
                            // this could be tricky if you have defaults that rely on other defaults ...
                            // like: { name: function(val) { return val.firstName + val.lastName }) }
                            value[k] = copy(v(value));
                        } else {
                            value[k] = copy(v);
                        }
                    }
                });

                // Map all the objects to new names or relationships
                forEach(options.map, function(v, k){
                    if (functionName(v) === functionName(Model) || functionName(v) === functionName(ModelCollection)) {
                        value[k] = new v(value[k]); // jshint ignore:line
                    } else if (typeof v === 'function') {
                        // if its a function, invoke it,
                        // this would be helpful for seralizers
                        // like: map: { date: function(val){ return moment(val) } }
                        value[k] = v(value[k], value);
                    } else {
                        value[k] = value[v];
                        delete value[v];
                    }
                });

                // attach instance actions
                forEach(options.actions, function(v, k){
                    if(k[0] === '$'){
                        instance[k] = function(){
                            return Model.$buildRequest(k, v, instance);
                        };
                    }
                });

                // copy values to the instance
                extend(instance, value);

                // copy instance level helpers to this instance
                extend(instance, copy(options.instance));

                /**
                 * Save the instance to the server.  Posts the instance unless
                 * the instance has the `pk` attribute already then it will do a put.
                 */
                instance.$save = function(){
                     var actionType = instance[options.pk] ? 'update' : 'post',
                         promise = Model[actionType](this);

                    instance.$pending = true;

                    promise.then(function(value){
                        instance.$pending = false;

                        // extend the value from the server to me
                        if (value) {
                            instance.$update(value);
                        }

                        var broadcastName = actionType === 'post' ? 'created' : 'updated';
                        $rootScope.$broadcast(prettyName + '-' + broadcastName, instance);

                        // commit the change for reversion
                        commits.push(angular.toJson(instance));
                    }, function () {
                        // rejected
                        instance.$pending = false;
                    });

                    return promise;
                };

                /**
                 * Delete the instance.  Performs a DELETE on this instance performing
                 * the delete action passing an instance of itself.
                 *
                 * If the item is associated with an array, it will automatically be removed
                 * on successful delete.
                 */
                instance.$destroy = function(){
                    // keep a local pointer since we strip before send

                    var promise = Model.delete(this);
                    instance.$pending = true;

                    promise.then(function(){
                        instance.$pending = false;

                        var arr = instance.$$array;
                        if(arr){
                            arr.splice(arr.indexOf(instance), 1);
                        }

                        $rootScope.$broadcast(prettyName + '-destroyed', instance);
                    }, function(){
                        // rejected
                        instance.$pending = false;
                    });

                    return promise;
                };

                /**
                 * Display the difference between the original data and the
                 * current instance.
                 * https://github.com/flitbit/diff
                 */
                instance.$diff = function(version){
                    var prevCommit = commits[version || commits.length - 1],
                        currCommit = angular.toJson(instance);

                    return DeepDiff.diff(JSON.parse(prevCommit), JSON.parse(currCommit), function(path, key) {
                        return key[0] === '$';
                    });
                };


                /**
                 * Commits the change the commits bucket for rollback later if needed.
                 */
                instance.$commit = function () {
                    // stringify it so you have a clean instance
                    commits.push(angular.toJson(instance));
                    return instance;
                };

                /**
                 * Reverts the current instance back either the latest instance
                 * or you can pass a specific instance on the commits stack.
                 */
                instance.$rollback = function(version) {
                    var prevCommit = commits[version || commits.length - 1];
                    instance.$update(JSON.parse(prevCommit));
                    return instance;
                };

                /**
                 * Extends the properties of the new object onto
                 * the current object without replacing it.  Helpful
                 * when copying and then re-copying new props back
                 */
                instance.$update = function(n){
                    shallowClearAndCopy(n, instance);
                    return instance;
                };


                /**
                 * Creates a copy by taking the raw data values and by
                 * creating a new instance of the model.
                 */
                instance.$copy = function(){
                  // get the raw data of the model
                  var rawData = angular.toJson(this);

                  // ..then wrap it into a new instance to create a clone
                  return new Model(angular.fromJson(rawData));
                };

                // Create a copy of the value last so we get all the goodies,
                // like default values and whatnot.
                instance.$commit();
            }
1199470
function Models(ml, base_url) {
  this.ml = ml;
  this.base_url = base_url;

  if (includes(base_url, 'classifiers')) {
    this.run_action = 'classify';
  } else if (includes(base_url, 'extractors')) {
    this.run_action = 'extract';
  } else {
    this.run_action = undefined;
  }
}
970016
function initModels(seqObj, modelFiles, models, tablePrefix) {
    modelFiles.forEach((item) => {
      var modelFn;
      try {
        modelFn = require(item.fullPath);
      } catch (e) {
        console.error('Thorin.sql: could not require model: ' + item.fullPath + '\n', e.stack);
        return;
      }
      if (modelFn == null) return;  // we skip it
      if (typeof modelFn !== 'function') {
        console.error(thorin.error('SQL.INVALID_MODEL', 'SQL Model: ' + item.fullPath + ' must export a function(modelObj){}'));
        return;
      }
      if (modelFn.name === 'extend') {
        if (typeof extendModels[item.code] === 'undefined') extendModels[item.code] = [];
        extendModels[item.code].push(modelFn);
        return;
      }
      let modelObj = loader.buildModel(seqObj, modelFn, item, tablePrefix);
      if (modelObj) {
        if (typeof models[modelObj.code] !== 'undefined') {
          console.error(thorin.error('SQL.ADD_MODEL', 'SQL Store: model ' + modelObj.code + ' was already declared.'));
          return;
        }
        models[modelObj.code] = modelObj;
      }
    });
  }
182002
function ImmutableCoreModel (args) {
    // store copy of original args
    this.args = _.cloneDeep(args)
    // initialize global data
    this.initGlobal(args)
    // create module and set options
    this.initModule(args)
    // initialize column spec for model
    this.initColumns(args)
    // initialize multi-column indexes
    this.initIndexes(args)
    // create and validate JSON schema
    this.initJsonSchema(args)
    // add create method to module
    this.initCreate(args)
    // add query method to module
    this.initQuery(args)
    // add associated actions
    this.initActions(args)
    // initialize any model views
    this.initViews(args)
    // initialize related models
    this.initRelations(args)
    // initialize access control
    this.initAccessControl(args)
    // create columnsId
    this.initIds()
}
615355
function Model(defaults){

    // Make sure "new" is always used,
    // so we can use "instanceof" to check if something is a Model.
    if (!(this instanceof Model)) {
      return new Model(defaults);
    }

    // `model` is the public API object returned from invoking `new Model()`.
    var model = this,

        // The internal stored values for tracked properties. { property -> value }
        values = {},

        // The callback functions for each tracked property. { property -> [callback] }
        listeners = {},

        // The set of tracked properties. { property -> true }
        trackedProperties = {};

    // The functional reactive "when" operator.
    //
    //  * `properties` An array of property names (can also be a single property string).
    //  * `callback` A callback function that is called:
    //    * with property values as arguments, ordered corresponding to the properties array,
    //    * only if all specified properties have values,
    //    * once for initialization,
    //    * whenever one or more specified properties change,
    //    * on the next tick of the JavaScript event loop after properties change,
    //    * only once as a result of one or more synchronous changes to dependency properties.
    function when(properties, callback, thisArg){
      
      // Make sure the default `this` becomes 
      // the object you called `.on` on.
      thisArg = thisArg || this;

      // Handle either an array or a single string.
      properties = (properties instanceof Array) ? properties : [properties];

      // This function will trigger the callback to be invoked.
      var listener = debounce(function (){
        var args = properties.map(function(property){
          return values[property];
        });
        if(allAreDefined(args)){
          callback.apply(thisArg, args);
        }
      });

      // Trigger the callback once for initialization.
      listener();
      
      // Trigger the callback whenever specified properties change.
      properties.forEach(function(property){
        on(property, listener);
      });

      // Return this function so it can be removed later with `model.cancel(listener)`.
      return listener;
    }

    // Adds a change listener for a given property with Backbone-like behavior.
    // Similar to http://backbonejs.org/#Events-on
    function on(property, callback, thisArg){
      thisArg = thisArg || this;
      getListeners(property).push(callback);
      track(property, thisArg);
    }
    
    // Gets or creates the array of listener functions for a given property.
    function getListeners(property){
      return listeners[property] || (listeners[property] = []);
    }

    // Tracks a property if it is not already tracked.
    function track(property, thisArg){
      if(!(property in trackedProperties)){
        trackedProperties[property] = true;
        values[property] = model[property];
        Object.defineProperty(model, property, {
          get: function () { return values[property]; },
          set: function(newValue) {
            var oldValue = values[property];
            values[property] = newValue;
            getListeners(property).forEach(function(callback){
              callback.call(thisArg, newValue, oldValue);
            });
          }
        });
      }
    }

    // Cancels a listener returned by a call to `model.when(...)`.
    function cancel(listener){
      for(var property in listeners){
        off(property, listener);
      }
    }

    // Removes a change listener added using `on`.
    function off(property, callback){
      listeners[property] = listeners[property].filter(function (listener) {
        return listener !== callback;
      });
    }

    // Sets all of the given values on the model.
    // `newValues` is an object { property -> value }.
    function set(newValues){
      for(var property in newValues){
        model[property] = newValues[property];
      }
    }

    // Transfer defaults passed into the constructor to the model.
    set(defaults);

    // Public API.
    model.when = when;
    model.cancel = cancel;
    model.on = on;
    model.off = off;
    model.set = set;
  }
797224
function(api, modelDefinition) {
		this.parentAPI = api;
		this.childModels = [];

		this.initialized = false;

		this.model = modelDefinition.model;
		this.path = this.model.tableName.toLowerCase();
		this.modelRouter = Express.Router();
		this.primaryKey = Helpers.getPrimaryKey(this.model);

		/**
		 * Array of valid columns in the class minus the primary key
		 * However the primary key is only 'not valid' to be set if it is
		 * marked as auto-generated.
		 */
		this.validColumns = _.keys(this.model.rawAttributes);

		if(this.model.rawAttributes[this.primaryKey]._autoGenerated)
			this.validColumns.splice(this.validColumns.indexOf(this.primaryKey), 1);

		this._initializeOptions(modelDefinition);
		this._initializeAssociationOptions(modelDefinition);
		this._initializeRoutes(modelDefinition);

		this.filter = Helpers.mergeTriplicate({
			// If this is filled out, don't allow these parameters to be used.
			blacklist: [],

			// If this is filled out, ONLY allow these parameters to be used.
			whitelist: [],

			// Include these fields in output
			include: [],

			// Exclude these fields from output
			exclude: []
		}, this.model.filter || {}, modelDefinition.filter || {});
	}
66477
function bindModel(proc, model) {
  const actualModel = model || {};
  proc.model = actualModel;
  proc.logic.model = actualModel;

  if (!actualModel.__proc) {
    Object.defineProperty(actualModel, '__proc', {
      value: proc,
      enumerable: false,
      configurable: true
    });
  }
}
677992
def function_begin(self):
        """"""
        self.newline_label(self.shared.function_name, False, True)
        self.push("%14")
        self.move("%15", "%14")
597096
function Model(collectionName, attributes, values) {
    this.collectionName = collectionName;
    this.idAttribute = Model.getId(attributes);
    this.attributes = attributeValidator.validate(attributes);
    this.values = { };
    this.virtuals = { };

    // initially add the null value from all attributes
    for (var key in this.attributes) {
        this.values[key] = undefined;
    }

    // prevents from modifying values and adding properties
    Object.freeze(this.attributes);

    // prevents from adding new properties
    Object.seal(this.values);

    // sets the initial values
    this.set(values);
}
285990
def decorate_method(wrapped):
    
    def wrapper(self):
        lines = Lines()
        if hasattr(self.model, wrapped.__name__):
            print('            . %s' % wrapped.__name__)
            lines.add(1, method_header(wrapped.__name__, nogil=True))
            for line in wrapped(self):
                lines.add(2, line)
        return lines
    functools.update_wrapper(wrapper, wrapped)
    wrapper.__doc__ = 'Lines of model method %s.' % wrapped.__name__
    return property(wrapper)
508212
function GlobalMemoryDump(model, start) {
    tr.model.ContainerMemoryDump.call(this, start);
    this.model = model;
    this.processMemoryDumps = {};
  }
637372
function(context, descriptor, args) {
		var xpr = args[0],
			index = args[1],
			templ = args[2],
			val = xpr.__interpolable__ ? xpr.output(context) : xpr,
			rest = new Template(templ._queue.slice(index));
		if (val)
			rest.toHTMLString(context, descriptor);
	}
900049
function prepareModel(modelObj) {
    /* BEFORE save */
    function onSave(iObj, opt, fn) {
      /* Check if crypto is disabled */
      if (typeof opt === 'object' && opt && opt.crypto === false) return fn();
      /* for each field, check if we have to encrypt*/
      let encrypted = modelObj.getEncrypted();
      for (let i = 0, len = encrypted.length; i < len; i++) {
        let fieldName = encrypted[i],
          fieldValue = iObj.getDataValue(fieldName);
        if (typeof fieldValue === 'undefined') {  // check default value;
          let _default = modelObj.fields[fieldName]._default;
          if (typeof _default !== 'undefined' && _default != null) {
            fieldValue = (typeof _default === 'function' ? _default() : _default);
          }
        }
        if (typeof fieldValue === 'undefined' || fieldValue === null) continue;
        // we now place it encrypted.
        if (crypto.isEncrypted(fieldValue)) continue;
        let enc = crypto.encrypt(fieldValue, opt.key);
        if (enc === null) continue;
        if (!iObj._changed[fieldName]) continue;
        iObj.setDataValue(fieldName, enc);
        if (typeof iObj.__original_encrypted === 'undefined') {
          iObj.__original_encrypted = {};
        }
        iObj.__original_encrypted[fieldName] = fieldValue;
      }
      if (typeof fn === 'function') {
        fn();
      }
    }

    function onSaved(iObj) {
      if (typeof iObj.__original_encrypted === 'undefined') return;
      let fields = Object.keys(iObj.__original_encrypted);
      for (let i = 0, len = fields.length; i < len; i++) {
        let fieldName = fields[i],
          fieldValue = iObj.__original_encrypted[fieldName];
        iObj.setDataValue(fieldName, fieldValue);
      }
      delete iObj.__original_encrypted;
    }

    /*
     * Changes the WHERE statement.
     * */
    function prepareWhere(opt, _modelObj) {
      if (!_modelObj) _modelObj = modelObj;
      if (!_modelObj) return;
      if (typeof _modelObj.isEncrypted !== 'function') {
        _modelObj = storeObj.model(storeObj.camelize(_modelObj.name), true);
      }
      /* Check if crypto is disabled */
      if (opt.crypto === false) return;
      if (typeof opt.where !== 'object' || !opt.where) return;
      let fields = Object.keys(opt.where);
      for (let i = 0, len = fields.length; i < len; i++) {
        let fieldName = fields[i];
        // Check for inner $and operator
        if (fieldName === '$and') {
          let tmp = {
            where: opt.where[fieldName],
            key: opt.key
          };
          prepareWhere(tmp, _modelObj);
          continue;
        }
        // Check for inner $or operator
        if (fieldName === '$or' && opt.where[fieldName] instanceof Array) {
          for (let j = 0, jlen = opt.where[fieldName].length; j < jlen; j++) {
            let tmp = {
              where: opt.where[fieldName][j],
              key: opt.key
            };
            prepareWhere(tmp, _modelObj);
          }
          continue;
        }
        if (!_modelObj.isEncrypted(fieldName)) continue;
        let fieldValue = opt.where[fieldName];
        let fieldValueType = typeof fieldValue;
        if (fieldValueType === 'undefined' || fieldValue === null) continue;
        if (fieldValue instanceof Array) {
          let tmp = [];
          for (let i = 0, len = fieldValue.length; i < len; i++) {
            let val = fieldValue[i],
              type = typeof val;
            if (type === 'number' || type === 'boolean') {
              val = val.toString();
              type = 'string';
            }
            if (type !== 'string') {
              tmp.push(val);
              continue;
            }
            if (crypto.isEncrypted(val)) {
              tmp.push(val);
              continue;
            }
            let enc = crypto.encrypt(val, opt.key);
            if (enc === null) continue;
            tmp.push(enc);
          }
          opt.where[fieldName] = tmp;
        } else if (fieldValueType === 'object') {
          // this is some kind of operator/aggregator
          let $ops = Object.keys(fieldValue);
          for (let j = 0, llen = $ops.length; j < llen; j++) {
            let opName = $ops[j],
              opValue = fieldValue[opName];
            // Special op: %
            if (opName === '$like') {
              if (!crypto.isEncrypted(opValue)) {
                if (opValue.charAt(0) === '%') opValue = opValue.substr(1);
                if (opValue.charAt(opValue.length - 1) === '%') opValue = opValue.substr(0, opValue.length - 1);
                opValue = crypto.encrypt(opValue, opt.key);
                fieldValue[opName] = opValue;
              }
            } else if (INNER_OPERATORS.indexOf(opName) !== -1) {
              if (opValue instanceof Array) {
                for (let k = 0, klen = opValue.length; k < klen; k++) {
                  if (!crypto.isEncrypted(opValue[k])) {
                    let enc = crypto.encrypt(opValue[k], opt.key);
                    if (enc != null) {
                      opValue[k] = enc;
                    }
                  }
                }
              } else if (!crypto.isEncrypted(opValue)) {
                let enc = crypto.encrypt(opValue, opt.key);
                if (enc === null) continue;
                fieldValue[opName] = enc;
              }
            }
          }
        } else {
          if (crypto.isEncrypted(fieldValue)) continue;
          let enc = crypto.encrypt(fieldValue, opt.key);
          if (enc === null) continue;
          opt.where[fieldName] = enc;
        }
      }
    }

    /*
     * Looks for JOINS in the include field
     * */
    function prepareInclude(opt) {
      if (opt.crypto === false) return;
      if (typeof opt.include === 'undefined') return;
      if (opt.include instanceof Array) {
        for (let i = 0, len = opt.include.length; i < len; i++) {
          singleInclude(opt.include[i]);
        }
      } else if (typeof opt.include === 'object' && opt.include) {
        singleInclude(opt.include);
      }
    }

    function singleInclude(obj) {
      if (typeof obj !== 'object' || !obj) return;
      if (typeof obj.where === 'object' && obj.where) {
        prepareWhere(obj, obj.model);
      }
      if (typeof obj.include !== 'undefined') {
        prepareInclude(obj);
      }
    }

    function bulkChanges(opt, fn) {
      if (opt.crypto === false) return fn();
      // first check for encrypted where's
      if (typeof opt.where === 'object' && opt.where) {
        prepareWhere(opt);
      }
      if (typeof opt.attributes === 'object' && opt.attributes) {
        let fields = Object.keys(opt.attributes);
        for (let i = 0, len = fields.length; i < len; i++) {
          let fieldName = fields[i];
          if (!modelObj.isEncrypted(fieldName)) continue;
          let fieldValue = opt.attributes[fieldName];
          if (typeof fieldValue === 'undefined' || fieldValue === null) continue;
          if (crypto.isEncrypted(fieldValue)) continue;
          let enc = crypto.encrypt(fieldValue, opt.key);
          if (enc === null) continue;
          opt.attributes[fieldName] = enc;
        }
      }
      fn();
    }

    /*
     * Hook inside the findAll()
     * */
    function alterMultiFind(opt, fn) {
      if (typeof opt !== 'object' || !opt) return fn(opt);
      if (opt.crypto === false) return fn(opt);
      prepareWhere(opt);
      prepareInclude(opt);
      if (opt.raw !== true) {
        return fn(opt);
      }
      return fn(opt).then((items) => {
        if (items.length === 0) return items;
        for (let i = 0, len = items.length; i < len; i++) {
          let item = items[i],
            fields = Object.keys(item);
          for (let j = 0, llen = fields.length; j < llen; j++) {
            let fieldValue = item[fields[j]];
            if (crypto.isEncrypted(fieldValue)) {
              let encr = crypto.decrypt(fieldValue, opt.key);
              if (encr) {
                item[fields[j]] = encr;
              }
            }
          }
        }
        return items;
      });
    }

    function alterSingleFind(opt, fn) {
      if (typeof opt !== 'object' || !opt) return fn(opt);
      if (opt.crypto === false) return fn(opt);
      prepareWhere(opt);
      prepareInclude(opt);
      if (opt.raw !== true) return fn(opt);
      return fn(opt).then((item) => {
        if (typeof item !== 'object' || !item) return item;
        let fields = Object.keys(item);
        for (let j = 0, llen = fields.length; j < llen; j++) {
          let fieldValue = item[fields[j]];
          if (crypto.isEncrypted(fieldValue)) {
            let encr = crypto.decrypt(fieldValue, opt.key);
            if (encr) {
              item[fields[j]] = encr;
            }
          }
        }
        return item;
      });
    }

    function alterOrFind(opt, instance, fn) {
      if (typeof opt !== 'object' || !opt) return fn(opt);
      if (opt.crypto === false) return fn(opt);
      prepareWhere(opt);
      prepareInclude(opt);
      return fn(opt, instance);
    }

    function alterCount(opt, fn, _hasRows) {
      if (typeof opt !== 'object' || !opt) return fn(opt);
      if (opt.crypto === false) return fn(opt);
      prepareWhere(opt);
      prepareInclude(opt);
      if (opt.raw !== true || _hasRows !== true) return fn(opt);
      return fn(opt).then((res) => {
        if (typeof res !== 'object' || !res) return res;
        if (!(res.rows instanceof Array)) return res;
        for (let i = 0, len = res.rows.length; i < len; i++) {
          let item = res.rows[i],
            fields = Object.keys(item);
          for (let j = 0, llen = fields.length; j < llen; j++) {
            let fieldValue = item[fields[j]];
            if (crypto.isEncrypted(fieldValue)) {
              let encr = crypto.decrypt(fieldValue, opt.key);
              if (encr) {
                item[fields[j]] = encr;
              }
            }
          }
        }
        return res;
      });
    }

    /*
     * Recursively decrypt entity data
     * */
    function decryptEntity(data, modelObj) {
      if (typeof data !== 'object' || !data) return;
      let encrypted = modelObj.getEncrypted();
      for (let i = 0, len = encrypted.length; i < len; i++) {
        let fieldName = encrypted[i],
          fieldValue = data[fieldName];
        if (typeof fieldValue !== 'string') continue;
        if (!crypto.isEncrypted(fieldValue)) continue;
        let decrypted = crypto.decrypt(fieldValue, opt.key);
        if (decrypted === null) {
          logger.warn(`Could not decrypt field ${fieldName} of entity`);
          logger.debug(data);
          continue;
        }
        data[fieldName] = decrypted;
      }
      /* now check foreign relations */
      if (!modelObj.hasRelationFields()) return;
      let relations = modelObj.getRelationFields();
      for (let i = 0, len = relations.length; i < len; i++) {
        let relation = relations[i];
        if (typeof data[relation.field] === 'undefined') continue;
        let relationModel = storeObj.model(relation.model, true);
        if (!relationModel.hasEncryptedFields()) continue;
        if (data[relation.field] instanceof Array) {
          for (let j = 0; j < data[relation.field].length; j++) {
            decryptEntity(data[relation.field][j], relationModel);
          }
        } else if (typeof data[relation.field] === 'object' && data[relation.field]) {
          decryptEntity(data[relation.field], relationModel);
        }
      }
    }

    function bindToStore(storeObj) {
      let Instance = modelObj.getInstance();
      const names = [
        'findAll', 'findById', 'findOne', 'find', 'findAndCount',
        'count', 'sum', 'max', 'min'
      ];
      names.forEach((name) => {
        let baseFn = Instance[name].bind(Instance);
        switch (name) {
          case 'findAll':
            Instance[name] = function EncryptedFindWrapper(opt) {
              return alterMultiFind(opt, baseFn);
            };
            break;
          case 'find':
          case 'findById':
          case 'findOne':
            Instance[name] = function EncryptedReadWrapper(opt) {
              return alterSingleFind(opt, baseFn);
            };
            break;
          case 'findAndCount':
            Instance[name] = function EncryptedCountWrapper(opt) {
              return alterCount(opt, baseFn, true);
            };
            break;
          case 'findOrCreate':
          case 'findOrInitialize':
            Instance[name] = function EncryptedFindWrapper(opt, instance) {
              return alterOrFind(opt, instance, baseFn);
            };
            break;
          case 'count':
            Instance[name] = function EncryptedCountWrapper(opt) {
              if (typeof opt !== 'object' || !opt) return baseFn(opt);
              if (opt.crypto === false) return baseFn(opt);
              prepareWhere(opt);
              prepareInclude(opt);
              return baseFn(opt);
            };
            break;
          case 'sum':
          case 'min':
          case 'max':
            Instance[name] = function EncryptedFuncWrapper(field, opt) {
              if (typeof opt !== 'object' || !opt) return baseFn(field, opt);
              if (opt.crypto === false) return baseFn(field, opt);
              prepareWhere(opt);
              prepareInclude(opt);
              return baseFn(field, opt);
            };
            break;
        }
      });

      /* Override the default Build() function */
      let _build = Instance.build.bind(Instance);
      Instance.build = function (values, opt) {
        decryptEntity(values, modelObj);
        return _build(values, opt);
      };
    }

    bindToStore(storeObj);

    modelObj
      .hook('beforeBulkCreate', (instances, opt, fn) => {
        for (let i = 0, len = instances.length; i < len; i++) {
          onSave(instances[i], opt);
        }
        fn();
      })
      .hook('afterBulkCreate', (instances) => {
        for (let i = 0, len = instances.length; i < len; i++) {
          onSaved(instances[i]);
        }
      })
      .hook('beforeBulkUpdate', bulkChanges)
      .hook('beforeBulkDestroy', bulkChanges);

    modelObj
      .hook('beforeCreate', onSave)
      .hook('afterCreate', onSaved)
      .hook('beforeUpdate', onSave)
      .hook('afterUpdate', onSaved);
  }
938016
function(object, map) {
      Object.keys(map).forEach(function(name) {
        var method = map[name];
        if (name in object) return;
        if (supportsDescriptors) {
          Object.defineProperty(object, name, {
            configurable: true,
            enumerable: false,
            writable: true,
            value: method
          });
        } else {
          object[name] = method;
        }
      });
    }