<commit_before>//= require ./utils
//= require ./codec

Data.attrMeta = function (type, options) {
  return {
    type: type,
    isAttribute: true,
    options: options || {},
    codec: {
      key: function (key) {
        return key.decamelize();
      },

      decode: function (value) {
        var
          parts = type.split(':'),
          basicType = parts[0],
          qualifier = parts[1];

        return Data.codec[basicType].decode(value, qualifier);
      },

      encode: function (instance, attribute) {
        var
          parts = type.split(':'),
          basicType = parts[0],
          qualifier = parts[1],
          value = attribute ? instance.get(attribute) : instance;

        return Data.codec[basicType].encode(value, qualifier);
      }
    }
  };
};

Data.attr = function (type, options) {
  options = options || {};
  var meta = Data.attrMeta(type, options);

  return Ember.computed(function(key, value, oldValue) {
    if (arguments.length > 1) {
      var encodedValue = meta.codec.encode(value);
      this._changeAttribute(key, oldValue, encodedValue);
      this.set('_data.' + meta.codec.key(key), encodedValue);
    } else {
      value = this.get('_data.' + meta.codec.key(key));

      if (Ember.isNone(value)) {
        value = options.defaultValue;
      }
      value = meta.codec.decode(value);
    }
    return value;
  }).property('_data').meta(meta);
};

Data.embedded = function (type, options) {
  options = options || {};

  var meta = {
    type: type,
    isAttribute: true,
    options: options,
    codec: {
      key: function (key) {
        return key.decamelize();
      },

      encode: function (instance, attribute) {
        return instance.get(attribute).toJSON();
      }
    }
  };

  return Ember.computed(function(key, value, oldValue) {
    if (arguments.length > 1) {
      this._changeAttribute(key, oldValue, value);
      this.set('_data.' + meta.codec.key(key), value);
    } else {
      value = this.get('_data.' + meta.codec.key(key));

      if (value === undefined) {
        value = options.defaultValue;
      }
      value = Data.getType(type).load(value, {
        _embeddedContainer: this,
        _embeddedAttribute: key
      });
    }
    return value;
  }).property('_data').meta(meta);
};

Data.dynamicAttributable = Ember.Mixin.create({

  defineAttribute: function (key, definition) {
    Ember.defineProperty(this, key, Ember.computed(function (key, newValue/*, oldValue*/) {
      var result = newValue;
      if (arguments.length > 1) {
        Ember.set(this._data, key, result);
      } else {
        var decoder = definition.decoder || 'raw';
        result = Ember.get(this._data, key);
        switch (decoder) {
        case 'array':
          if (Ember.typeOf(result) === 'object') { // fix JQuery serialization or object arrays...
            var array = [];
            Ember.keys(result).forEach(function (index) {
              array[index] = result[index];
            });
            result = array;
          }
          break;
        default:
          // nope
        }
      }
      return result;
    }).property('_data', '_data.%@'.fmt(key)).cacheable(false));

    if (Ember.isNone(Ember.get(this._data, key))) {
      Ember.set(this._data, key, definition.defaultValue);
    }
  },

  defineAttributes: function (object) {
    Ember.keys(object).forEach(function (key) {
      this.defineAttribute(key, object[key]);
    }, this);
  },

  resetAttributes: function (object) {
    this.set('_data', {});
    if (object) {
      this.defineAttributes(object);
    }
  },

  unknownProperty: function (propertyName) {
    if (this._data.hasOwnProperty(propertyName)) {
      return this._data[propertyName];
    }
  }
});

/**
  Declares a "to one" relation.
    - type: the "one" relation side's entity fully qualified class name
    - options: an optional object defining some extra relation behaviour settings (cf. below)

  Supported options:
    - nested: defaults to false. if true, this entity's parent will be the related entity
    - embedded: defaults to false. if true, the related entity's data is expected to be inlined inside holder's payload
    - sideLoad: an extra side-loaded entities associated to this relation (exclusive with `sideLoads`)
    - sideLoads: a list of extra side-loaded entities associated to this relation
    - cascadeSaving: defaults to true. if true, the relation is also saved if needed when the holder is saved
 */
Data.belongsTo = function (type, options) {
  options = options || {};
  options.cascadeSaving = !!options.cascadeSaving;

  var meta = {
    type: type,
    isRelation: true,
    options: options,
    codec: {
      key: function (key) {
        if (options.embedded) {
          return key;
        }
        return Data.belongsToKey(key);
      },

      encode: function (instance, attribute) {
        return instance.get('_data.' + this.key(attribute));
      }
    }
  };

  return Ember.computed(function(key, value, oldValue) {
    if (arguments.length > 1) {
      this.set('_data.' + meta.codec.key(key), value ? value.get('id') : value);
      this.get('_relationsCache')[key] = value;
      Ember.run.next(this, function () {
        this._replaceRelation(key, oldValue, value);
        this.expireCaches();
      });
    } else {
      var type = Data.getType(meta.type),
          id = this.get('_data.' + meta.codec.key(key)),
          parent = meta.options.nested ? this : null,
          relationsCache = this.get('_relationsCache') || {},
          relation = relationsCache[key];

      if (relation) {
        return relation;
      }
      if (id) {
        if (options.embedded) {
          relation = type.load(id);
        } else {
          relation = type.find(id, parent, { sync: true });
        }
        relation.set('_owner', this);
        relationsCache[key] = relation;
      } else {
        relation = null;
      }
      return relation;
    }
  }).property('_data', '_relationsCache', '_cacheTimestamp').meta(meta);
};

/**
  Declares a "to many" relation.
    - type: the "many" relation side's entity fully qualified class name
    - options: an optional object defining some extra relation behaviour settings (cf. below)

  Supported options:
    - nested: defaults to false. if true, this entity's parent will be the related entity
    - nestingParam: TODO
    - serialize: defaults to true, if false, this relation will not be seralized to API, and dirtyness will not be
      propagated to the parent
    - sideLoad: an extra side-loaded entities associated to this relation (exclusive with `sideLoads`)
    - sideLoads: a list of extra side-loaded entities associated to this relation
    - cascadeSaving: defaults to true. if true, the relation is also saved if needed when the holder is saved
 */
Data.hasMany = function (type, options) {
  options = options || {};
  options.cascadeSaving = !!options.cascadeSaving;

  var meta = {
    type: type,
    isRelation: true,
    options: options,
    codec: {
      key: function (key) {
        return '%@_ids'.fmt(key.decamelize().singularize());
      },

      encode: function (instance, attribute) {
        var cache = instance.get('_relationsCache.%@'.fmt(attribute));

        if (cache) {
          return cache.getEach('id');
        }
        return instance.get('_data.' + this.key(attribute));
      }
    }
  };

  /* jshint maxcomplexity:11 */
  return Ember.computed(function(key/*, value, oldValue*/) {
    if (arguments.length > 1) {
      Ember.assert('SHOULD NOT DO THAT, BRO', false);
    } else {
      var meta = this.constructor.metaForProperty(key),
          type = Data.getType(meta.type),
          ids = this.get('_data.' + meta.codec.key(key)),
          parent = meta.options.nested ? this : null,
          params,
          relationsCache = this.get('_relationsCache') || {},
          relation = relationsCache[key],
          content;

      if (relation) {
        // Ember.Logger.debug('hasMany(%@.%@): use cache'.fmt(type, key));
        return relation;
      }

      if (this.get('meta.isNew')) {
        content = [];
        // Ember.Logger.debug('hasMany(%@.%@): empty set (new)'.fmt(type, key));
      } else {
        if (Ember.isEmpty(ids)) {
          content = [];
          // Ember.Logger.debug('hasMany(%@.%@): empty set'.fmt(type, key));
        } else {
          if (meta.options.nestingParam) {
            var parts = meta.options.nestingParam.split(':'),
              param = parts[1] || parts[0],
              valuePath = parts[1] ? parts[0] : 'id';

            params = {};
            params[param] = this.get(valuePath);
          }

          content = type.find(ids, parent, { sync: true, params: params });
          // Ember.Logger.debug('hasMany(%@.%@): retrieve %@'.fmt(type, key, ids));
        }
      }

      relation = Data.ModelArray.create({
        _type: meta.type,
        _owner: this,
        _field: key,
        _affectOwner: meta.options.serialize || false,
        content: content
      });
      content.forEach(function (record) {
        record.set('_container', relation);
      });
      relationsCache[key] = relation;
      return relation;
    }
  }).property('_data', '_relationsCache', '_cacheTimestamp').meta(meta);
};
<commit_msg>Add explanatory log & error case management in relation population<commit_after>//= require ./utils
//= require ./codec

Data.attrMeta = function (type, options) {
  return {
    type: type,
    isAttribute: true,
    options: options || {},
    codec: {
      key: function (key) {
        return key.decamelize();
      },

      decode: function (value) {
        var
          parts = type.split(':'),
          basicType = parts[0],
          qualifier = parts[1];

        return Data.codec[basicType].decode(value, qualifier);
      },

      encode: function (instance, attribute) {
        var
          parts = type.split(':'),
          basicType = parts[0],
          qualifier = parts[1],
          value = attribute ? instance.get(attribute) : instance;

        return Data.codec[basicType].encode(value, qualifier);
      }
    }
  };
};

Data.attr = function (type, options) {
  options = options || {};
  var meta = Data.attrMeta(type, options);

  return Ember.computed(function(key, value, oldValue) {
    if (arguments.length > 1) {
      var encodedValue = meta.codec.encode(value);
      this._changeAttribute(key, oldValue, encodedValue);
      this.set('_data.' + meta.codec.key(key), encodedValue);
    } else {
      value = this.get('_data.' + meta.codec.key(key));

      if (Ember.isNone(value)) {
        value = options.defaultValue;
      }
      value = meta.codec.decode(value);
    }
    return value;
  }).property('_data').meta(meta);
};

Data.embedded = function (type, options) {
  options = options || {};

  var meta = {
    type: type,
    isAttribute: true,
    options: options,
    codec: {
      key: function (key) {
        return key.decamelize();
      },

      encode: function (instance, attribute) {
        return instance.get(attribute).toJSON();
      }
    }
  };

  return Ember.computed(function(key, value, oldValue) {
    if (arguments.length > 1) {
      this._changeAttribute(key, oldValue, value);
      this.set('_data.' + meta.codec.key(key), value);
    } else {
      value = this.get('_data.' + meta.codec.key(key));

      if (value === undefined) {
        value = options.defaultValue;
      }
      value = Data.getType(type).load(value, {
        _embeddedContainer: this,
        _embeddedAttribute: key
      });
    }
    return value;
  }).property('_data').meta(meta);
};

Data.dynamicAttributable = Ember.Mixin.create({

  defineAttribute: function (key, definition) {
    Ember.defineProperty(this, key, Ember.computed(function (key, newValue/*, oldValue*/) {
      var result = newValue;
      if (arguments.length > 1) {
        Ember.set(this._data, key, result);
      } else {
        var decoder = definition.decoder || 'raw';
        result = Ember.get(this._data, key);
        switch (decoder) {
        case 'array':
          if (Ember.typeOf(result) === 'object') { // fix JQuery serialization or object arrays...
            var array = [];
            Ember.keys(result).forEach(function (index) {
              array[index] = result[index];
            });
            result = array;
          }
          break;
        default:
          // nope
        }
      }
      return result;
    }).property('_data', '_data.%@'.fmt(key)).cacheable(false));

    if (Ember.isNone(Ember.get(this._data, key))) {
      Ember.set(this._data, key, definition.defaultValue);
    }
  },

  defineAttributes: function (object) {
    Ember.keys(object).forEach(function (key) {
      this.defineAttribute(key, object[key]);
    }, this);
  },

  resetAttributes: function (object) {
    this.set('_data', {});
    if (object) {
      this.defineAttributes(object);
    }
  },

  unknownProperty: function (propertyName) {
    if (this._data.hasOwnProperty(propertyName)) {
      return this._data[propertyName];
    }
  }
});

/**
  Declares a "to one" relation.
    - type: the "one" relation side's entity fully qualified class name
    - options: an optional object defining some extra relation behaviour settings (cf. below)

  Supported options:
    - nested: defaults to false. if true, this entity's parent will be the related entity
    - embedded: defaults to false. if true, the related entity's data is expected to be inlined inside holder's payload
    - sideLoad: an extra side-loaded entities associated to this relation (exclusive with `sideLoads`)
    - sideLoads: a list of extra side-loaded entities associated to this relation
    - cascadeSaving: defaults to true. if true, the relation is also saved if needed when the holder is saved
 */
Data.belongsTo = function (type, options) {
  options = options || {};
  options.cascadeSaving = !!options.cascadeSaving;

  var meta = {
    type: type,
    isRelation: true,
    options: options,
    codec: {
      key: function (key) {
        if (options.embedded) {
          return key;
        }
        return Data.belongsToKey(key);
      },

      encode: function (instance, attribute) {
        return instance.get('_data.' + this.key(attribute));
      }
    }
  };

  return Ember.computed(function(key, value, oldValue) {
    if (arguments.length > 1) {
      this.set('_data.' + meta.codec.key(key), value ? value.get('id') : value);
      this.get('_relationsCache')[key] = value;
      Ember.run.next(this, function () {
        this._replaceRelation(key, oldValue, value);
        this.expireCaches();
      });
    } else {
      var type = Data.getType(meta.type),
          id = this.get('_data.' + meta.codec.key(key)),
          parent = meta.options.nested ? this : null,
          relationsCache = this.get('_relationsCache') || {},
          relation = relationsCache[key];

      if (relation) {
        return relation;
      }
      if (id) {
        if (options.embedded) {
          relation = type.load(id);
        } else {
          relation = type.find(id, parent, { sync: true });
        }
        if (relation) {
          relation.set('_owner', this);
          relationsCache[key] = relation;
        } else {
          Ember.Logger.warn('An error occured at relation fetching... %@[%@].%@[%@] is not populated'.fmt(
            this.constructor, this.get('id'), key, id
          ));
        }
      } else {
        relation = null;
      }
      return relation;
    }
  }).property('_data', '_relationsCache', '_cacheTimestamp').meta(meta);
};

/**
  Declares a "to many" relation.
    - type: the "many" relation side's entity fully qualified class name
    - options: an optional object defining some extra relation behaviour settings (cf. below)

  Supported options:
    - nested: defaults to false. if true, this entity's parent will be the related entity
    - nestingParam: TODO
    - serialize: defaults to true, if false, this relation will not be seralized to API, and dirtyness will not be
      propagated to the parent
    - sideLoad: an extra side-loaded entities associated to this relation (exclusive with `sideLoads`)
    - sideLoads: a list of extra side-loaded entities associated to this relation
    - cascadeSaving: defaults to true. if true, the relation is also saved if needed when the holder is saved
 */
Data.hasMany = function (type, options) {
  options = options || {};
  options.cascadeSaving = !!options.cascadeSaving;

  var meta = {
    type: type,
    isRelation: true,
    options: options,
    codec: {
      key: function (key) {
        return '%@_ids'.fmt(key.decamelize().singularize());
      },

      encode: function (instance, attribute) {
        var cache = instance.get('_relationsCache.%@'.fmt(attribute));

        if (cache) {
          return cache.getEach('id');
        }
        return instance.get('_data.' + this.key(attribute));
      }
    }
  };

  /* jshint maxcomplexity:11 */
  return Ember.computed(function(key/*, value, oldValue*/) {
    if (arguments.length > 1) {
      Ember.assert('SHOULD NOT DO THAT, BRO', false);
    } else {
      var meta = this.constructor.metaForProperty(key),
          type = Data.getType(meta.type),
          ids = this.get('_data.' + meta.codec.key(key)),
          parent = meta.options.nested ? this : null,
          params,
          relationsCache = this.get('_relationsCache') || {},
          relation = relationsCache[key],
          content;

      if (relation) {
        // Ember.Logger.debug('hasMany(%@.%@): use cache'.fmt(type, key));
        return relation;
      }

      if (this.get('meta.isNew')) {
        content = [];
        // Ember.Logger.debug('hasMany(%@.%@): empty set (new)'.fmt(type, key));
      } else {
        if (Ember.isEmpty(ids)) {
          content = [];
          // Ember.Logger.debug('hasMany(%@.%@): empty set'.fmt(type, key));
        } else {
          if (meta.options.nestingParam) {
            var parts = meta.options.nestingParam.split(':'),
              param = parts[1] || parts[0],
              valuePath = parts[1] ? parts[0] : 'id';

            params = {};
            params[param] = this.get(valuePath);
          }

          content = type.find(ids, parent, { sync: true, params: params });
          // Ember.Logger.debug('hasMany(%@.%@): retrieve %@'.fmt(type, key, ids));
        }
      }

      relation = Data.ModelArray.create({
        _type: meta.type,
        _owner: this,
        _field: key,
        _affectOwner: meta.options.serialize || false,
        content: content
      });
      content.forEach(function (record) {
        record.set('_container', relation);
      });
      relationsCache[key] = relation;
      return relation;
    }
  }).property('_data', '_relationsCache', '_cacheTimestamp').meta(meta);
};
<|endoftext|>


<commit_before>(function($) {

  var filters;

  $.filters = filters = {
    append: function(options) {
      options = options || {};
      var field_label = options['label'];
      var field_name  = options['name'];
      var field_type  = options['type'];
      var field_value = options['value'];
      var field_operator = options['operator'];
      var select_options = options['select_options'];
      var index = options['index'];
      var required = options['required'];
      var required_label = required ? 'required' : '';
      var value_name    = 'f[' +  field_name + '][' + index + '][v]';
      var operator_name = 'f[' +  field_name + '][' + index + '][o]';
      var control = null;
      var additional_control = null;
      var delete_button = null;
      var field_label_lower = field_label.toLowerCase();

      switch(field_type) {
        case 'boolean':
          var control = '<select class="input-sm form-control" name="' + value_name + '">' +
            '<option value="_discard">...</option>' +
            '<option value="true"' + (field_value == "true" ? 'selected="selected"' : '') + '>' + RailsAdmin.I18n.t("true") + '</option>' +
            '<option value="false"' + (field_value == "false" ? 'selected="selected"' : '') + '>' + RailsAdmin.I18n.t("false") + '</option>' +
            '<option disabled="disabled">---------</option>' +
            '<option ' + (field_value == "_present" ? 'selected="selected"' : '') + ' value="_present">' + RailsAdmin.I18n.t("is_present") + '</option>' +
            '<option ' + (field_value == "_blank"   ? 'selected="selected"' : '') + ' value="_blank"  >' + RailsAdmin.I18n.t("is_blank") + '</option>' +
          '</select>';
          break;
        case 'date':
          additional_control =
          '<input size="20" class="date additional-fieldset default input-sm form-control ' + required_label + ' ' + field_label_lower + '-filter-field" style="display:' + ((!field_operator || field_operator == "default") ? 'inline-block' : 'none') + ';" type="text" name="' + value_name + '[]" value="' + (field_value[0] || '') + '" /> ' +
          '<input size="20" placeholder="-∞" class="date additional-fieldset between input-sm form-control ' + required_label + ' ' + field_label_lower + '-filter-field" style="display:' + ((field_operator == "between") ? 'inline-block' : 'none') + ';" type="text" name="' + value_name + '[]" value="' + (field_value[1] || '') + '" /> ' +
          '<input size="20" placeholder="∞" class="date additional-fieldset between input-sm form-control ' + required_label + ' ' + field_label_lower + '-filter-field" style="display:' + ((field_operator == "between") ? 'inline-block' : 'none') + ';" type="text" name="' + value_name + '[]" value="' + (field_value[2] || '') + '" />';
        case 'datetime':
        case 'timestamp':
          control = control || '<select class="switch-additionnal-fieldsets input-sm form-control" name="' + operator_name + '">' +
            '<option ' + (field_operator == "default"   ? 'selected="selected"' : '') + ' data-additional-fieldset="default" value="default">' + RailsAdmin.I18n.t("date") + '</option>' +
            '<option ' + (field_operator == "between"   ? 'selected="selected"' : '') + ' data-additional-fieldset="between" value="between">' + RailsAdmin.I18n.t("between_and_") + '</option>' +
            '<option ' + (field_operator == "today"   ? 'selected="selected"' : '') + ' value="today">' + RailsAdmin.I18n.t("today") + '</option>' +
            '<option ' + (field_operator == "yesterday"   ? 'selected="selected"' : '') + ' value="yesterday">' + RailsAdmin.I18n.t("yesterday") + '</option>' +
            '<option ' + (field_operator == "this_week"   ? 'selected="selected"' : '') + ' value="this_week">' + RailsAdmin.I18n.t("this_week") + '</option>' +
            '<option ' + (field_operator == "last_week"   ? 'selected="selected"' : '') + ' value="last_week">' + RailsAdmin.I18n.t("last_week") + '</option>' +
            '<option disabled="disabled">---------</option>' +
            '<option ' + (field_operator == "_not_null" ? 'selected="selected"' : '') + ' value="_not_null">' + RailsAdmin.I18n.t("is_present") + '</option>' +
            '<option ' + (field_operator == "_null"     ? 'selected="selected"' : '') + ' value="_null" >' + RailsAdmin.I18n.t("is_blank") + '</option>' +
          '</select>'
          additional_control = additional_control ||
          '<input size="25" class="datetime additional-fieldset default input-sm form-control ' + required_label + ' ' + field_label_lower + '-filter-field" style="display:' + ((!field_operator || field_operator == "default") ? 'inline-block' : 'none') + ';" type="text" name="' + value_name + '[]" value="' + (field_value[0] || '') + '" /> ' +
          '<input size="25" placeholder="-∞" class="datetime additional-fieldset between input-sm form-control ' + required_label + ' ' + field_label_lower + '-filter-field" style="display:' + ((field_operator == "between") ? 'inline-block' : 'none') + ';" type="text" name="' + value_name + '[]" value="' + (field_value[1] || '') + '" /> ' +
          '<input size="25" placeholder="∞" class="datetime additional-fieldset between input-sm form-control ' + required_label + ' ' + field_label_lower + '-filter-field" style="display:' + ((field_operator == "between") ? 'inline-block' : 'none') + ';" type="text" name="' + value_name + '[]" value="' + (field_value[2] || '') + '" />';
          break;
        case 'enum':
          var multiple_values = ((field_value instanceof Array) ? true : false)
          control = '<select style="display:' + (multiple_values ? 'none' : 'inline-block') + '" ' + (multiple_values ? '' : 'name="' + value_name + '"') + ' data-name="' + value_name + '" class="select-single input-sm form-control">' +
              '<option value="_discard">...</option>' +
              '<option ' + (field_value == "_present" ? 'selected="selected"' : '') + ' value="_present">' + RailsAdmin.I18n.t("is_present") + '</option>' +
              '<option ' + (field_value == "_blank"   ? 'selected="selected"' : '') + ' value="_blank">' + RailsAdmin.I18n.t("is_blank") + '</option>' +
              '<option disabled="disabled">---------</option>' +
              select_options +
            '</select>' +
            '<select multiple="multiple" style="display:' + (multiple_values ? 'inline-block' : 'none') + '" ' + (multiple_values ? 'name="' + value_name + '[]"' : '') + ' data-name="' + value_name + '[]" class="select-multiple input-sm form-control">' +
              select_options +
            '</select> ' +
            '';
        break;
        case 'string':
        case 'text':
        case 'belongs_to_association':
          control = '<select class="switch-additionnal-fieldsets input-sm form-control" value="' + field_operator + '" name="' + operator_name + '">' +
            '<option data-additional-fieldset="additional-fieldset"'  + (field_operator == "is"          ? 'selected="selected"' : '') + ' value="is">' + RailsAdmin.I18n.t("is_exactly") + '</option>' +
            '<option disabled="disabled">---------</option>' +
            '<option ' + (field_operator == "_not_null"    ? 'selected="selected"' : '') + ' value="_not_null">' + RailsAdmin.I18n.t("is_present") + '</option>' +
            '<option ' + (field_operator == "_null"      ? 'selected="selected"' : '') + ' value="_null">' + RailsAdmin.I18n.t("is_blank") + '</option>' +
          '</select>'
          additional_control = '<input class="additional-fieldset input-sm form-control ' + required_label + ' ' + field_label_lower + '-filter-field" style="display:' + (field_operator == "_blank" || field_operator == "_present" ? 'none' : 'inline-block') + ';" type="text" name="' + value_name + '" value="' + field_value + '" /> ';
          break;
        case 'integer':
        case 'decimal':
        case 'float':
          control = '<select class="switch-additionnal-fieldsets input-sm form-control" name="' + operator_name + '">' +
            '<option ' + (field_operator == "default"   ? 'selected="selected"' : '') + ' data-additional-fieldset="default" value="default">' + RailsAdmin.I18n.t("number") + '</option>' +
            '<option ' + (field_operator == "between"   ? 'selected="selected"' : '') + ' data-additional-fieldset="between" value="between">' + RailsAdmin.I18n.t("between_and_") + '</option>' +
            '<option disabled="disabled">---------</option>' +
            '<option ' + (field_operator == "_not_null" ? 'selected="selected"' : '') + ' value="_not_null">' + RailsAdmin.I18n.t("is_present") +'</option>' +
            '<option ' + (field_operator == "_null"     ? 'selected="selected"' : '') + ' value="_null" >' + RailsAdmin.I18n.t("is_blank") + '</option>' +
          '</select>'
          additional_control =
          '<input class="additional-fieldset default input-sm form-control ' + required_label + ' ' + field_label_lower + '-filter-field" style="display:' + ((!field_operator || field_operator == "default") ? 'inline-block' : 'none') + ';" type="' + field_type + '" name="' + value_name + '[]" value="' + (field_value[0] || '') + '" /> ' +
          '<input placeholder="-∞" class="additional-fieldset between input-sm form-control ' + required_label + ' ' + field_label_lower + '-filter-field" style="display:' + ((field_operator == "between") ? 'inline-block' : 'none') + ';" type="' + field_type + '" name="' + value_name + '[]" value="' + (field_value[1] || '') + '" /> ' +
          '<input placeholder="∞" class="additional-fieldset between input-sm form-control ' + required_label + ' ' + field_label_lower + '-filter-field" style="display:' + ((field_operator == "between") ? 'inline-block' : 'none') + ';" type="' + field_type + '" name="' + value_name + '[]" value="' + (field_value[2] || '') + '" />';
          break;
        default:
          control = '<input type="text" class="input-sm form-control ' + required_label + ' ' + field_label_lower + '-filter-field" name="' + value_name + '" value="' + field_value + '"/> ';
          break;
      }

      if (required && $('.' + field_label_lower + '-filter-button.required').length == 0)
        delete_button = '' + field_label + '';
      else
        delete_button = '' + field_label + '';
      var $content = $('
')
        .addClass('filter form-search')
        .append(delete_button)
        .append(' ' + control + ' ' + (additional_control || ''));

      $('#filters_box').append($content);

      $content.find('.date, .datetime').datetimepicker({
        locale: RailsAdmin.I18n.locale,
        showTodayButton: true,
        format: options['datetimepicker_format']
      });

      $("hr.filters_box:hidden").show('slow');
    }
  }

  $(document).on('click', "#filters a", function(e) {
    e.preventDefault();
    $.filters.append({
      label: $(this).data('field-label'),
      name:  $(this).data('field-name'),
      type:  $(this).data('field-type'),
      value: $(this).data('field-value'),
      operator: $(this).data('field-operator'),
      select_options: $(this).data('field-options'),
      index: $.now().toString().slice(6,11),
      datetimepicker_format: $(this).data('field-datetimepicker-format')
    });
  });

  $(document).on('click', "#filters_box .delete", function(e) {
    e.preventDefault();
    form = $(this).parents('form');
    $(this).parents('.filter').remove();
    !$("#filters_box").children().length && $("hr.filters_box:visible").hide('slow');
  });

  function isFilterUsed(filter) {
    appliedFilters = $("." + filter + "-filter-field:visible");
    hiddenFilters = $("." + filter + "-filter-field:hidden");
    if (appliedFilters.length == 0 || hiddenFilters.length > 0) return true;

    filterUsed = $.map(appliedFilters, function (field) {
      return field.value !== "";
    }).find (function (val) {
      return val;
    });

    return !!filterUsed;
  }

  function display_filter_alert() {
    var filtersUsed = [];
    for (var i=0; i<required_filters.length; i++) {
      if (!isFilterUsed(required_filters[i])) {
        $("#filter-alert-text").text(required_filters[i] + " filter required");
        $("#filter-alert").show();
        return true;
      }
    }

    $("#filter-alert").hide();
    return false;
  };

  $(document).on('click', "#submit-filter", function(e) {
    if (display_filter_alert()) {
      e.preventDefault();
      return
    }
  });

  $(document).on('click', "#filters_box .switch-select", function(e) {
    e.preventDefault();
    var selected_select = $(this).siblings('select:visible');
    var not_selected_select = $(this).siblings('select:hidden');
    not_selected_select.attr('name', not_selected_select.data('name')).show('slow');
    selected_select.attr('name', null).hide('slow');
    $(this).find('i').toggleClass("icon-plus icon-minus")
  });

  $(document).on('change', "#filters_box .switch-additionnal-fieldsets", function(e) {
    var selected_option = $(this).find('option:selected');
    if(klass = $(selected_option).data('additional-fieldset')) {
      $(this).siblings('.additional-fieldset:not(.' + klass + ')').hide('slow');
      $(this).siblings('.' + klass).show('slow');
    } else {
      $(this).siblings('.additional-fieldset').hide('slow');
    }
  });
})( jQuery );
<commit_msg>GW-3348 #comment add contains to filter<commit_after>(function($) {

  var filters;

  $.filters = filters = {
    append: function(options) {
      options = options || {};
      var field_label = options['label'];
      var field_name  = options['name'];
      var field_type  = options['type'];
      var field_value = options['value'];
      var field_operator = options['operator'];
      var select_options = options['select_options'];
      var index = options['index'];
      var required = options['required'];
      var required_label = required ? 'required' : '';
      var value_name    = 'f[' +  field_name + '][' + index + '][v]';
      var operator_name = 'f[' +  field_name + '][' + index + '][o]';
      var control = null;
      var additional_control = null;
      var delete_button = null;
      var field_label_lower = field_label.toLowerCase();

      switch(field_type) {
        case 'boolean':
          var control = '<select class="input-sm form-control" name="' + value_name + '">' +
            '<option value="_discard">...</option>' +
            '<option value="true"' + (field_value == "true" ? 'selected="selected"' : '') + '>' + RailsAdmin.I18n.t("true") + '</option>' +
            '<option value="false"' + (field_value == "false" ? 'selected="selected"' : '') + '>' + RailsAdmin.I18n.t("false") + '</option>' +
            '<option disabled="disabled">---------</option>' +
            '<option ' + (field_value == "_present" ? 'selected="selected"' : '') + ' value="_present">' + RailsAdmin.I18n.t("is_present") + '</option>' +
            '<option ' + (field_value == "_blank"   ? 'selected="selected"' : '') + ' value="_blank"  >' + RailsAdmin.I18n.t("is_blank") + '</option>' +
          '</select>';
          break;
        case 'date':
          additional_control =
          '<input size="20" class="date additional-fieldset default input-sm form-control ' + required_label + ' ' + field_label_lower + '-filter-field" style="display:' + ((!field_operator || field_operator == "default") ? 'inline-block' : 'none') + ';" type="text" name="' + value_name + '[]" value="' + (field_value[0] || '') + '" /> ' +
          '<input size="20" placeholder="-∞" class="date additional-fieldset between input-sm form-control ' + required_label + ' ' + field_label_lower + '-filter-field" style="display:' + ((field_operator == "between") ? 'inline-block' : 'none') + ';" type="text" name="' + value_name + '[]" value="' + (field_value[1] || '') + '" /> ' +
          '<input size="20" placeholder="∞" class="date additional-fieldset between input-sm form-control ' + required_label + ' ' + field_label_lower + '-filter-field" style="display:' + ((field_operator == "between") ? 'inline-block' : 'none') + ';" type="text" name="' + value_name + '[]" value="' + (field_value[2] || '') + '" />';
        case 'datetime':
        case 'timestamp':
          control = control || '<select class="switch-additionnal-fieldsets input-sm form-control" name="' + operator_name + '">' +
            '<option ' + (field_operator == "default"   ? 'selected="selected"' : '') + ' data-additional-fieldset="default" value="default">' + RailsAdmin.I18n.t("date") + '</option>' +
            '<option ' + (field_operator == "between"   ? 'selected="selected"' : '') + ' data-additional-fieldset="between" value="between">' + RailsAdmin.I18n.t("between_and_") + '</option>' +
            '<option ' + (field_operator == "today"   ? 'selected="selected"' : '') + ' value="today">' + RailsAdmin.I18n.t("today") + '</option>' +
            '<option ' + (field_operator == "yesterday"   ? 'selected="selected"' : '') + ' value="yesterday">' + RailsAdmin.I18n.t("yesterday") + '</option>' +
            '<option ' + (field_operator == "this_week"   ? 'selected="selected"' : '') + ' value="this_week">' + RailsAdmin.I18n.t("this_week") + '</option>' +
            '<option ' + (field_operator == "last_week"   ? 'selected="selected"' : '') + ' value="last_week">' + RailsAdmin.I18n.t("last_week") + '</option>' +
            '<option disabled="disabled">---------</option>' +
            '<option ' + (field_operator == "_not_null" ? 'selected="selected"' : '') + ' value="_not_null">' + RailsAdmin.I18n.t("is_present") + '</option>' +
            '<option ' + (field_operator == "_null"     ? 'selected="selected"' : '') + ' value="_null" >' + RailsAdmin.I18n.t("is_blank") + '</option>' +
          '</select>'
          additional_control = additional_control ||
          '<input size="25" class="datetime additional-fieldset default input-sm form-control ' + required_label + ' ' + field_label_lower + '-filter-field" style="display:' + ((!field_operator || field_operator == "default") ? 'inline-block' : 'none') + ';" type="text" name="' + value_name + '[]" value="' + (field_value[0] || '') + '" /> ' +
          '<input size="25" placeholder="-∞" class="datetime additional-fieldset between input-sm form-control ' + required_label + ' ' + field_label_lower + '-filter-field" style="display:' + ((field_operator == "between") ? 'inline-block' : 'none') + ';" type="text" name="' + value_name + '[]" value="' + (field_value[1] || '') + '" /> ' +
          '<input size="25" placeholder="∞" class="datetime additional-fieldset between input-sm form-control ' + required_label + ' ' + field_label_lower + '-filter-field" style="display:' + ((field_operator == "between") ? 'inline-block' : 'none') + ';" type="text" name="' + value_name + '[]" value="' + (field_value[2] || '') + '" />';
          break;
        case 'enum':
          var multiple_values = ((field_value instanceof Array) ? true : false)
          control = '<select style="display:' + (multiple_values ? 'none' : 'inline-block') + '" ' + (multiple_values ? '' : 'name="' + value_name + '"') + ' data-name="' + value_name + '" class="select-single input-sm form-control">' +
              '<option value="_discard">...</option>' +
              '<option ' + (field_value == "_present" ? 'selected="selected"' : '') + ' value="_present">' + RailsAdmin.I18n.t("is_present") + '</option>' +
              '<option ' + (field_value == "_blank"   ? 'selected="selected"' : '') + ' value="_blank">' + RailsAdmin.I18n.t("is_blank") + '</option>' +
              '<option disabled="disabled">---------</option>' +
              select_options +
            '</select>' +
            '<select multiple="multiple" style="display:' + (multiple_values ? 'inline-block' : 'none') + '" ' + (multiple_values ? 'name="' + value_name + '[]"' : '') + ' data-name="' + value_name + '[]" class="select-multiple input-sm form-control">' +
              select_options +
            '</select> ' +
            '';
        break;
        case 'string':
        case 'text':
        case 'belongs_to_association':
          control = '<select class="switch-additionnal-fieldsets input-sm form-control" value="' + field_operator + '" name="' + operator_name + '">' +
            '<option data-additional-fieldset="additional-fieldset"'  + (field_operator == "like"        ? 'selected="selected"' : '') + ' value="like">' + RailsAdmin.I18n.t("contains") + '</option>' +
            '<option data-additional-fieldset="additional-fieldset"'  + (field_operator == "is"          ? 'selected="selected"' : '') + ' value="is">' + RailsAdmin.I18n.t("is_exactly") + '</option>' +
            '<option disabled="disabled">---------</option>' +
            '<option ' + (field_operator == "_not_null"    ? 'selected="selected"' : '') + ' value="_not_null">' + RailsAdmin.I18n.t("is_present") + '</option>' +
            '<option ' + (field_operator == "_null"      ? 'selected="selected"' : '') + ' value="_null">' + RailsAdmin.I18n.t("is_blank") + '</option>' +
          '</select>'
          additional_control = '<input class="additional-fieldset input-sm form-control ' + required_label + ' ' + field_label_lower + '-filter-field" style="display:' + (field_operator == "_blank" || field_operator == "_present" ? 'none' : 'inline-block') + ';" type="text" name="' + value_name + '" value="' + field_value + '" /> ';
          break;
        case 'integer':
        case 'decimal':
        case 'float':
          control = '<select class="switch-additionnal-fieldsets input-sm form-control" name="' + operator_name + '">' +
            '<option ' + (field_operator == "default"   ? 'selected="selected"' : '') + ' data-additional-fieldset="default" value="default">' + RailsAdmin.I18n.t("number") + '</option>' +
            '<option ' + (field_operator == "between"   ? 'selected="selected"' : '') + ' data-additional-fieldset="between" value="between">' + RailsAdmin.I18n.t("between_and_") + '</option>' +
            '<option disabled="disabled">---------</option>' +
            '<option ' + (field_operator == "_not_null" ? 'selected="selected"' : '') + ' value="_not_null">' + RailsAdmin.I18n.t("is_present") +'</option>' +
            '<option ' + (field_operator == "_null"     ? 'selected="selected"' : '') + ' value="_null" >' + RailsAdmin.I18n.t("is_blank") + '</option>' +
          '</select>'
          additional_control =
          '<input class="additional-fieldset default input-sm form-control ' + required_label + ' ' + field_label_lower + '-filter-field" style="display:' + ((!field_operator || field_operator == "default") ? 'inline-block' : 'none') + ';" type="' + field_type + '" name="' + value_name + '[]" value="' + (field_value[0] || '') + '" /> ' +
          '<input placeholder="-∞" class="additional-fieldset between input-sm form-control ' + required_label + ' ' + field_label_lower + '-filter-field" style="display:' + ((field_operator == "between") ? 'inline-block' : 'none') + ';" type="' + field_type + '" name="' + value_name + '[]" value="' + (field_value[1] || '') + '" /> ' +
          '<input placeholder="∞" class="additional-fieldset between input-sm form-control ' + required_label + ' ' + field_label_lower + '-filter-field" style="display:' + ((field_operator == "between") ? 'inline-block' : 'none') + ';" type="' + field_type + '" name="' + value_name + '[]" value="' + (field_value[2] || '') + '" />';
          break;
        default:
          control = '<input type="text" class="input-sm form-control ' + required_label + ' ' + field_label_lower + '-filter-field" name="' + value_name + '" value="' + field_value + '"/> ';
          break;
      }

      if (required && $('.' + field_label_lower + '-filter-button.required').length == 0)
        delete_button = '' + field_label + '';
      else
        delete_button = '' + field_label + '';
      var $content = $('
')
        .addClass('filter form-search')
        .append(delete_button)
        .append(' ' + control + ' ' + (additional_control || ''));

      $('#filters_box').append($content);

      $content.find('.date, .datetime').datetimepicker({
        locale: RailsAdmin.I18n.locale,
        showTodayButton: true,
        format: options['datetimepicker_format']
      });

      $("hr.filters_box:hidden").show('slow');
    }
  }

  $(document).on('click', "#filters a", function(e) {
    e.preventDefault();
    $.filters.append({
      label: $(this).data('field-label'),
      name:  $(this).data('field-name'),
      type:  $(this).data('field-type'),
      value: $(this).data('field-value'),
      operator: $(this).data('field-operator'),
      select_options: $(this).data('field-options'),
      index: $.now().toString().slice(6,11),
      datetimepicker_format: $(this).data('field-datetimepicker-format')
    });
  });

  $(document).on('click', "#filters_box .delete", function(e) {
    e.preventDefault();
    form = $(this).parents('form');
    $(this).parents('.filter').remove();
    !$("#filters_box").children().length && $("hr.filters_box:visible").hide('slow');
  });

  function isFilterUsed(filter) {
    appliedFilters = $("." + filter + "-filter-field:visible");
    hiddenFilters = $("." + filter + "-filter-field:hidden");
    if (appliedFilters.length == 0 || hiddenFilters.length > 0) return true;

    filterUsed = $.map(appliedFilters, function (field) {
      return field.value !== "";
    }).find (function (val) {
      return val;
    });

    return !!filterUsed;
  }

  function display_filter_alert() {
    var filtersUsed = [];
    for (var i=0; i<required_filters.length; i++) {
      if (!isFilterUsed(required_filters[i])) {
        $("#filter-alert-text").text(required_filters[i] + " filter required");
        $("#filter-alert").show();
        return true;
      }
    }

    $("#filter-alert").hide();
    return false;
  };

  $(document).on('click', "#submit-filter", function(e) {
    if (display_filter_alert()) {
      e.preventDefault();
      return
    }
  });

  $(document).on('click', "#filters_box .switch-select", function(e) {
    e.preventDefault();
    var selected_select = $(this).siblings('select:visible');
    var not_selected_select = $(this).siblings('select:hidden');
    not_selected_select.attr('name', not_selected_select.data('name')).show('slow');
    selected_select.attr('name', null).hide('slow');
    $(this).find('i').toggleClass("icon-plus icon-minus")
  });

  $(document).on('change', "#filters_box .switch-additionnal-fieldsets", function(e) {
    var selected_option = $(this).find('option:selected');
    if(klass = $(selected_option).data('additional-fieldset')) {
      $(this).siblings('.additional-fieldset:not(.' + klass + ')').hide('slow');
      $(this).siblings('.' + klass).show('slow');
    } else {
      $(this).siblings('.additional-fieldset').hide('slow');
    }
  });
})( jQuery );
<|endoftext|>


<commit_before>import { get, set, observer, computed } from '@ember/object';
import { next } from '@ember/runloop';
import Component from '@ember/component';
import { alias } from '@ember/object/computed';
import { parseSi } from 'shared/utils/parse-unit';
import { convertToMillis } from 'shared/utils/util';
import layout from './template';

const GPU_KEY = 'nvidia.com/gpu';

export default Component.extend({
  layout,

  classNames: ['accordion-wrapper'],

  // Inputs
  instance:   null,
  service:    null,
  editing:    true,
  isSidekick: null,

  // ----------------------------------
  capabilityChoices:    null,
  // ----------------------------------
  memoryMode:           'unlimited',
  // unlimited, set
  memoryMb:             null,
  // Memory
  memoryReservationMb:  null,
  // ----------------------------------
  cpuMode:              'unlimited',
  // unlimited, set
  cpuMillis:            null,
  // CPU
  cpuReservationMillis: null,
  // ----------------------------------
  gpuReservation:       null,
  limits:               alias('instance.resources.limits'),
  requests:             alias('instance.resources.requests'),

  init() {
    this._super(...arguments);

    if ( !get(this, 'instance.resources') ) {
      set(this, 'instance.resources', {
        requests: {},
        limits:   {}
      });
    }

    if ( !get(this, 'instance.resources.requests') ) {
      set(this, 'instance.resources.requests', {});
    }

    if ( !get(this, 'instance.resources.limits') ) {
      set(this, 'instance.resources.limits', {});
    }

    this.initCapability();
    this.initMemory();
    this.initGpu();
    this.initCpu();
  },

  actions: {
    modifyCapabilities(type, select) {
      let options = Array.prototype.slice.call(select.target.options, 0);
      let selectedOptions = [];

      options.filterBy('selected', true).forEach((cap) => selectedOptions.push(cap.value));

      set(this, `instance.${ type }`, selectedOptions);
    },
  },

  // ----------------------------------
  privilegedChanged: observer('instance.privileged', 'instance.capAdd.[]', function() {
    if (get(this, 'instance.privileged') || (get(this, 'instance.capAdd') && get(this, 'instance.capAdd').indexOf('SYS_ADMIN') > -1)) {
      set(this, 'instance.allowPrivilegeEscalation', true);
    }
  }),

  memoryDidChange: observer('memoryMb', 'memoryMode', function() {
    next(this, 'updateMemory');
  }),

  memoryReservationChanged: observer('memoryReservationMb', function() {
    var mem = get(this, 'memoryReservationMb');

    if (isNaN(mem) || mem <= 0) {
      const requests = get(this, 'instance.resources.requests');

      delete requests['memory'];
    } else {
      set(this, 'instance.resources.requests.memory', `${ mem }Mi`);
    }
  }),

  cpuDidChange: observer('cpuMillis', 'cpuMode', function() {
    next(this, 'updateCpu');
  }),

  cpuReservationChanged: observer('cpuReservationMillis', function() {
    var cpu = get(this, 'cpuReservationMillis');

    if (isNaN(cpu) || cpu <= 0) {
      const requests = get(this, 'instance.resources.requests');

      delete requests['cpu']
    } else {
      set(this, 'instance.resources.requests.cpu', `${ cpu }m`);
    }
  }),

  updateGpu: observer('gpuReservation', function() {
    var gpu = get(this, 'gpuReservation');

    const requests = get(this, 'instance.resources.requests');
    const limits = get(this, 'instance.resources.limits');

    if (isNaN(gpu) || gpu <= 0) {
      delete requests[GPU_KEY];
      delete limits[GPU_KEY];
    } else {
      requests[GPU_KEY] = `${ gpu }`;
      limits[GPU_KEY] = `${ gpu }`;
    }
  }),

  // 2) has CAP_SYS_ADMIN
  allowPrivilegeEscalationDisabled: computed('instance.privileged', 'instance.capAdd.[]', function() {
    return get(this, 'instance.privileged') || (get(this, 'instance.capAdd') && get(this, 'instance.capAdd').indexOf('SYS_ADMIN') > -1);
  }),

  // ----------------------------------
  // Capability
  initCapability() {
    set(this, 'instance.capAdd', get(this, 'instance.capAdd') || []);
    set(this, 'instance.capDrop', get(this, 'instance.capDrop') || []);
    var choices = get(this, 'store').getById('schema', 'container')
      .optionsFor('capAdd')
      .sort();

    set(this, 'capabilityChoices', choices);
  },

  // ----------------------------------
  // AllowPrivilegeEscalation
  // It is true always when the container is:
  // 1) run as Privileged
  // ----------------------------------
  initMemory() {
    var mem = get(this, 'instance.resources.limits.memory');
    var memReservation = get(this, 'instance.resources.requests.memory');

    if (memReservation) {
      set(this, 'memoryReservationMb', parseSi(memReservation, 1024) / 1048576);
    } else {
      set(this, 'memoryReservationMb', '');
    }

    if (mem) {
      set(this, 'memoryMb', parseSi(mem, 1024) / 1048576);
      set(this, 'memoryMode', 'set');
    } else {
      set(this, 'memoryMb', 128);
      set(this, 'memoryMode', 'unlimited');
    }
    this.updateMemory();
  },

  updateMemory() {
    let mem = parseInt(get(this, 'memoryMb'), 10);
    let memoryMode = get(this, 'memoryMode');

    // Memory
    if (memoryMode === 'unlimited' || isNaN(mem) || mem <= 0) {
      const limits = get(this, 'instance.resources.limits');

      delete limits['memory'];

      return;
    }

    set(this, 'instance.resources.limits.memory', `${ mem }Mi`);
  },

  // ----------------------------------
  initCpu() {
    var cpu = get(this, 'instance.resources.limits.cpu');
    var cpuReservation = get(this, 'instance.resources.requests.cpu');

    set(this, 'cpuReservationMillis', convertToMillis(cpuReservation));

    if (cpu) {
      set(this, 'cpuMillis', convertToMillis(cpu));
      set(this, 'cpuMode', 'set');
    } else {
      set(this, 'cpuMillis', 1000);
      set(this, 'cpuMode', 'unlimited');
    }
    this.updateCpu();
  },

  updateCpu() {
    let cpu = parseInt(get(this, 'cpuMillis'), 10);
    let cpuMode = get(this, 'cpuMode');

    if (cpuMode === 'unlimited' || isNaN(cpu) || cpu <= 0) {
      const limits = get(this, 'instance.resources.limits');

      delete limits['cpu'];

      return;
    }

    set(this, 'instance.resources.limits.cpu', `${ cpu }m`);
  },

  // ----------------------------------
  // GPU
  initGpu() {
    var gpu = (get(this, 'instance.resources.limits') || {})[GPU_KEY];

    set(this, 'gpuReservation', gpu);
    this.updateGpu();
  },
});
<commit_msg>Units for CPU/Memory resource limits not consistent https://github.com/rancher/rancher/issues/17267<commit_after>import { get, set, observer, computed } from '@ember/object';
import { next } from '@ember/runloop';
import Component from '@ember/component';
import { alias } from '@ember/object/computed';
import { parseSi } from 'shared/utils/parse-unit';
import { convertToMillis } from 'shared/utils/util';
import layout from './template';

const GPU_KEY = 'nvidia.com/gpu';

export default Component.extend({
  layout,

  classNames: ['accordion-wrapper'],

  // Inputs
  instance:   null,
  service:    null,
  editing:    true,
  isSidekick: null,

  // ----------------------------------
  capabilityChoices:    null,
  // ----------------------------------
  memoryMode:           'unlimited',
  // unlimited, set
  memoryMb:             null,
  // Memory
  memoryReservationMb:  null,
  // ----------------------------------
  cpuMode:              'unlimited',
  // unlimited, set
  cpuMillis:            null,
  // CPU
  cpuReservationMillis: null,
  // ----------------------------------
  gpuReservation:       null,
  limits:               alias('instance.resources.limits'),
  requests:             alias('instance.resources.requests'),

  init() {
    this._super(...arguments);

    if ( !get(this, 'instance.resources') ) {
      set(this, 'instance.resources', {
        requests: {},
        limits:   {}
      });
    }

    if ( !get(this, 'instance.resources.requests') ) {
      set(this, 'instance.resources.requests', {});
    }

    if ( !get(this, 'instance.resources.limits') ) {
      set(this, 'instance.resources.limits', {});
    }

    this.initCapability();
    this.initMemory();
    this.initGpu();
    this.initCpu();
  },

  actions: {
    modifyCapabilities(type, select) {
      let options = Array.prototype.slice.call(select.target.options, 0);
      let selectedOptions = [];

      options.filterBy('selected', true).forEach((cap) => selectedOptions.push(cap.value));

      set(this, `instance.${ type }`, selectedOptions);
    },
  },

  // ----------------------------------
  privilegedChanged: observer('instance.privileged', 'instance.capAdd.[]', function() {
    if (get(this, 'instance.privileged') || (get(this, 'instance.capAdd') && get(this, 'instance.capAdd').indexOf('SYS_ADMIN') > -1)) {
      set(this, 'instance.allowPrivilegeEscalation', true);
    }
  }),

  memoryDidChange: observer('memoryMb', 'memoryMode', function() {
    next(this, 'updateMemory');
  }),

  memoryReservationChanged: observer('memoryReservationMb', function() {
    var mem = get(this, 'memoryReservationMb');

    if (isNaN(mem) || mem <= 0) {
      const requests = get(this, 'instance.resources.requests');

      delete requests['memory'];
    } else {
      set(this, 'instance.resources.requests.memory', `${ mem }Mi`);
    }
  }),

  cpuDidChange: observer('cpuMillis', 'cpuMode', function() {
    next(this, 'updateCpu');
  }),

  cpuReservationChanged: observer('cpuReservationMillis', function() {
    var cpu = get(this, 'cpuReservationMillis');

    if (isNaN(cpu) || cpu <= 0) {
      const requests = get(this, 'instance.resources.requests');

      delete requests['cpu']
    } else {
      set(this, 'instance.resources.requests.cpu', `${ cpu }m`);
    }
  }),

  updateGpu: observer('gpuReservation', function() {
    var gpu = get(this, 'gpuReservation');

    const requests = get(this, 'instance.resources.requests');
    const limits = get(this, 'instance.resources.limits');

    if (isNaN(gpu) || gpu <= 0) {
      delete requests[GPU_KEY];
      delete limits[GPU_KEY];
    } else {
      requests[GPU_KEY] = `${ gpu }`;
      limits[GPU_KEY] = `${ gpu }`;
    }
  }),

  // 2) has CAP_SYS_ADMIN
  allowPrivilegeEscalationDisabled: computed('instance.privileged', 'instance.capAdd.[]', function() {
    return get(this, 'instance.privileged') || (get(this, 'instance.capAdd') && get(this, 'instance.capAdd').indexOf('SYS_ADMIN') > -1);
  }),

  // ----------------------------------
  // Capability
  initCapability() {
    set(this, 'instance.capAdd', get(this, 'instance.capAdd') || []);
    set(this, 'instance.capDrop', get(this, 'instance.capDrop') || []);
    var choices = get(this, 'store').getById('schema', 'container')
      .optionsFor('capAdd')
      .sort();

    set(this, 'capabilityChoices', choices);
  },

  // ----------------------------------
  // AllowPrivilegeEscalation
  // It is true always when the container is:
  // 1) run as Privileged
  // ----------------------------------
  initMemory() {
    var mem = get(this, 'instance.resources.limits.memory');
    var memReservation = get(this, 'instance.resources.requests.memory');

    if (memReservation) {
      set(this, 'memoryReservationMb', parseSi(memReservation, 1024) / 1048576);
    } else {
      set(this, 'memoryReservationMb', '');
    }

    if (mem) {
      set(this, 'memoryMb', parseSi(mem, 1024) / 1048576);
      set(this, 'memoryMode', 'set');
    } else {
      set(this, 'memoryMb', 128);
      set(this, 'memoryMode', 'unlimited');
    }
    this.updateMemory();
    this.memoryReservationChanged();
  },

  updateMemory() {
    let mem = parseInt(get(this, 'memoryMb'), 10);
    let memoryMode = get(this, 'memoryMode');

    // Memory
    if (memoryMode === 'unlimited' || isNaN(mem) || mem <= 0) {
      const limits = get(this, 'instance.resources.limits');

      delete limits['memory'];

      return;
    }

    set(this, 'instance.resources.limits.memory', `${ mem }Mi`);
  },

  // ----------------------------------
  initCpu() {
    var cpu = get(this, 'instance.resources.limits.cpu');
    var cpuReservation = get(this, 'instance.resources.requests.cpu');

    set(this, 'cpuReservationMillis', convertToMillis(cpuReservation));

    if (cpu) {
      set(this, 'cpuMillis', convertToMillis(cpu));
      set(this, 'cpuMode', 'set');
    } else {
      set(this, 'cpuMillis', 1000);
      set(this, 'cpuMode', 'unlimited');
    }
    this.updateCpu();
    this.cpuReservationChanged();
  },

  updateCpu() {
    let cpu = parseInt(get(this, 'cpuMillis'), 10);
    let cpuMode = get(this, 'cpuMode');

    if (cpuMode === 'unlimited' || isNaN(cpu) || cpu <= 0) {
      const limits = get(this, 'instance.resources.limits');

      delete limits['cpu'];

      return;
    }

    set(this, 'instance.resources.limits.cpu', `${ cpu }m`);
  },

  // ----------------------------------
  // GPU
  initGpu() {
    var gpu = (get(this, 'instance.resources.limits') || {})[GPU_KEY];

    set(this, 'gpuReservation', gpu);
    this.updateGpu();
  },
});
<|endoftext|>


<commit_before>(function (root, factory) {
    if (typeof define === 'function' && define.amd) {
        // AMD. Register as an anonymous module.
        define(['backbone', 'swipeview', 'underscore'], factory);
    } else if (typeof exports === 'object') {
        // Node. Does not work with strict CommonJS, but
        // only CommonJS-like environments that support module.exports,
        // like Node.
        module.exports = factory(require('backbone'), require('swipeview'), require('underscore'));
    } else {
        // Browser globals (root is window)
        root.returnExports = factory(root.Backbone, root.SwipeView, root._);
    }
}(this, function (Backbone, SwipeView, _) {
    /* A mixin which loads the SwipeView class and keeps 3 subviews in memory. */

    'use strict';
    /* XXX: This also adds the 'restore' and 'destroy' methods to the SwipeView
     * "class". While the intend was to create a new "class" with the old
     * Swipeview methods plus the new methods below.
     *
     * An example of how to do this can be found in the Backbone extend()
     * function. Not to be confused with the underscore extend function.
     */
    var RestorableSwipeView = (function () {
        var hasTouch = 'ontouchstart' in window,
            resizeEvent = 'onorientationchange' in window ? 'orientationchange' : 'resize',
            startEvent = hasTouch ? 'touchstart' : 'mousedown',
            moveEvent = hasTouch ? 'touchmove' : 'mousemove',
            endEvent = hasTouch ? 'touchend' : 'mouseup';

        SwipeView.prototype.restore = function () {
                var i, l;
                for (i=0, l=this.customEvents.length; i<l; i++) {
                    this.wrapper.addEventListener('swipeview-' + this.customEvents[i][0], this.customEvents[i][1], false);
                }

                window.addEventListener(resizeEvent, this, false);
                this.wrapper.addEventListener(startEvent, this, false);
                this.wrapper.addEventListener(moveEvent, this, false);
                this.wrapper.addEventListener(endEvent, this, false);
                this.slider.addEventListener('webkitTransitionEnd', this, false);

                console.log('Swipeview is active');
        };

        SwipeView.prototype.destroy = function () {
                var i, l;
                for (i=0, l=this.customEvents.length; i<l; i++) {
                    this.wrapper.removeEventListener('swipeview-' + this.customEvents[i][0], this.customEvents[i][1], false);
                }

                // Remove the event listeners
                window.removeEventListener(resizeEvent, this, false);
                this.wrapper.removeEventListener(startEvent, this, false);
                this.wrapper.removeEventListener(moveEvent, this, false);
                this.wrapper.removeEventListener(endEvent, this, false);
                this.slider.removeEventListener('webkitTransitionEnd', this, false);

                console.log('Swipeview is disabled');
        };

        return SwipeView;
    })();

    return Backbone.View.extend({
        swipeview_options: {},

        current_subview: function() {
            // Return currently active subview
            return this.subViews[this.gallery.currentMasterPage];
        },

        goTo: function(model) {
            // Navigate to a particular model

            var index = this.collection.indexOf(model);
            if (index >= 0) {
                this.gallery.goToPage(index);

                // Update the view's model
                this.model = model;

                // Trigger page_changed
                this.trigger('page_changed', index);
            }
        },

        nextPage: function() {
            // Navigate to next page
            this.gallery.next();
        },

        previousPage: function() {
            // Navigate to previous page
            this.gallery.prev();
        },

        pageCount: function() {
            // Return number of pages
            return this.collection.size();
        },

        render: function(options) {
            // Render SwipeView
            // options are passed to the subview

            console.log('Rendering SwipeView');
            console.assert(this.el);
            console.assert(this.collection);

            // Get swipeview options but make sure number of pages is set
            var swipeview_options = _.extend({}, this.swipeview_options, {
                numberOfPages: this.pageCount()
            });

            this.gallery = new RestorableSwipeView(this.el, swipeview_options);

            // A list of all the views which are initialized and loaded
            // into the Swipeview.
            this.subViews = [null, null, null];

            // Load initial data
            for (var i=0; i<3; i++) {
                var page = i===0 ? this.pageCount()-1 : i-1;
                var master_page = Backbone.$(this.gallery.masterPages[i]);

                var view = this.render_subview(page, options);
                master_page.append(view.el);

                this.subViews[i] = view;
            }

            // Log events for debug purposes
            // Nice hook to handle some UX
            this.on('page_changed', function (pageindex) {
                // console.log('Page change to: '+pageindex);

                // Trigger 'first_page' and 'last_page' signals on,
                // respectively, the first and the last page.
                if (pageindex === 0) {
                    this.trigger('first_page');
                }

                if (pageindex === this.pageCount()-1) {
                    this.trigger('last_page');
                }
            }, this);

            // Callback for page changes
            this.gallery.onFlip(Backbone.$.proxy(function () {
                var i;
                for (i=0; i<3; i++) {
                    var master_page = this.gallery.masterPages[i];
                    var upcoming_idx = master_page.dataset.upcomingPageIndex;

                    // Determine whether we should actually render a new page
                    if (upcoming_idx != "undefined" && upcoming_idx !== master_page.dataset.pageIndex) {
                        // Remove the old view.
                        var old_view = this.subViews[i];
                        // console.log('Deleting old view for: '+old_view.model.id);
                        old_view.remove();
                        old_view = null;

                        var view = this.render_subview(upcoming_idx, options);
                        Backbone.$(master_page).append(view.el);

                        // Store subview for later reference
                        this.subViews[i] = view;

                    }
                }

                // Trigger page changed event on main view
                var current_subview = this.current_subview();
                if (current_subview) {
                    current_subview.trigger('activated');
                }

                Backbone.$(this.gallery.slider).one('transitionend',
                    Backbone.$.proxy(function () {
                        this.trigger('page_changed', this.gallery.pageIndex);
                    }, this)
                );

            }, this));

            this.gallery.bind();

            // If model specified, navigate to specified page
            if (this.model) {
                this.go_to(this.model);
            }

            return this;
        },

        remove: function () {
            // Remove self and all subviews
            _.each(this.subViews, function (view) {
                view.remove();
            });
            this.subViews = [null, null, null];

            Backbone.View.prototype.remove.call(this);
        },

        render_subview: function(page_index) {
            // Instantiate a new subview for this page.
            // console.log('Rendering SwipeView page: ', page_index);

            // Request the model using the page_index from the collection.
            var obj = this.collection.at(page_index);

            // Instantiate the subview using the newly acquired model.
            var subview_instance = new this.subview({
                model: obj
            });

            // Render the fucker.
            subview_instance.render();

            return subview_instance;
        },
    });
}));
<commit_msg>Fixed issue with wrong `page_changed`.<commit_after>(function (root, factory) {
    if (typeof define === 'function' && define.amd) {
        // AMD. Register as an anonymous module.
        define(['backbone', 'swipeview', 'underscore'], factory);
    } else if (typeof exports === 'object') {
        // Node. Does not work with strict CommonJS, but
        // only CommonJS-like environments that support module.exports,
        // like Node.
        module.exports = factory(require('backbone'), require('swipeview'), require('underscore'));
    } else {
        // Browser globals (root is window)
        root.returnExports = factory(root.Backbone, root.SwipeView, root._);
    }
}(this, function (Backbone, SwipeView, _) {
    /* A mixin which loads the SwipeView class and keeps 3 subviews in memory. */

    'use strict';
    /* XXX: This also adds the 'restore' and 'destroy' methods to the SwipeView
     * "class". While the intend was to create a new "class" with the old
     * Swipeview methods plus the new methods below.
     *
     * An example of how to do this can be found in the Backbone extend()
     * function. Not to be confused with the underscore extend function.
     */
    var RestorableSwipeView = (function () {
        var hasTouch = 'ontouchstart' in window,
            resizeEvent = 'onorientationchange' in window ? 'orientationchange' : 'resize',
            startEvent = hasTouch ? 'touchstart' : 'mousedown',
            moveEvent = hasTouch ? 'touchmove' : 'mousemove',
            endEvent = hasTouch ? 'touchend' : 'mouseup';

        SwipeView.prototype.restore = function () {
                var i, l;
                for (i=0, l=this.customEvents.length; i<l; i++) {
                    this.wrapper.addEventListener('swipeview-' + this.customEvents[i][0], this.customEvents[i][1], false);
                }

                window.addEventListener(resizeEvent, this, false);
                this.wrapper.addEventListener(startEvent, this, false);
                this.wrapper.addEventListener(moveEvent, this, false);
                this.wrapper.addEventListener(endEvent, this, false);
                this.slider.addEventListener('webkitTransitionEnd', this, false);

                console.log('Swipeview is active');
        };

        SwipeView.prototype.destroy = function () {
                var i, l;
                for (i=0, l=this.customEvents.length; i<l; i++) {
                    this.wrapper.removeEventListener('swipeview-' + this.customEvents[i][0], this.customEvents[i][1], false);
                }

                // Remove the event listeners
                window.removeEventListener(resizeEvent, this, false);
                this.wrapper.removeEventListener(startEvent, this, false);
                this.wrapper.removeEventListener(moveEvent, this, false);
                this.wrapper.removeEventListener(endEvent, this, false);
                this.slider.removeEventListener('webkitTransitionEnd', this, false);

                console.log('Swipeview is disabled');
        };

        return SwipeView;
    })();

    return Backbone.View.extend({
        swipeview_options: {},

        current_subview: function() {
            // Return currently active subview
            return this.subViews[this.gallery.currentMasterPage];
        },

        goTo: function(model) {
            // Navigate to a particular model

            var index = this.collection.indexOf(model);
            if (index >= 0) {
                this.gallery.goToPage(index);

                // Update the view's model
                this.model = model;

                // Trigger page_changed
                this.trigger('page_changed', index);
            }
        },

        nextPage: function() {
            // Navigate to next page
            this.gallery.next();
        },

        previousPage: function() {
            // Navigate to previous page
            this.gallery.prev();
        },

        pageCount: function() {
            // Return number of pages
            return this.collection.size();
        },

        render: function(options) {
            // Render SwipeView
            // options are passed to the subview

            console.log('Rendering SwipeView');
            console.assert(this.el);
            console.assert(this.collection);

            // Get swipeview options but make sure number of pages is set
            var swipeview_options = _.extend({}, this.swipeview_options, {
                numberOfPages: this.pageCount()
            });

            this.gallery = new RestorableSwipeView(this.el, swipeview_options);

            // A list of all the views which are initialized and loaded
            // into the Swipeview.
            this.subViews = [null, null, null];

            // Load initial data
            for (var i=0; i<3; i++) {
                var page = i===0 ? this.pageCount()-1 : i-1;
                var master_page = Backbone.$(this.gallery.masterPages[i]);

                var view = this.render_subview(page, options);
                master_page.append(view.el);

                this.subViews[i] = view;
            }

            // Log events for debug purposes
            // Nice hook to handle some UX
            this.on('page_changed', function (pageindex) {
                // console.log('Page change to: '+pageindex);

                // Trigger 'first_page' and 'last_page' signals on,
                // respectively, the first and the last page.
                if (pageindex === 0) {
                    this.trigger('first_page');
                }

                if (pageindex === this.pageCount()-1) {
                    this.trigger('last_page');
                }
            }, this);

            // Callback for page changes
            this.gallery.onFlip(Backbone.$.proxy(function () {
                var i;
                for (i=0; i<3; i++) {
                    var master_page = this.gallery.masterPages[i];
                    var upcoming_idx = master_page.dataset.upcomingPageIndex;

                    // Determine whether we should actually render a new page
                    if (upcoming_idx != "undefined" && upcoming_idx !== master_page.dataset.pageIndex) {
                        // Remove the old view.
                        var old_view = this.subViews[i];
                        // console.log('Deleting old view for: '+old_view.model.id);
                        old_view.remove();
                        old_view = null;

                        var view = this.render_subview(upcoming_idx, options);
                        Backbone.$(master_page).append(view.el);

                        // Store subview for later reference
                        this.subViews[i] = view;

                    }
                }

                // Trigger page changed event on main view
                var current_subview = this.current_subview();
                console.assert(current_subview);

                current_subview.trigger('activated');

                // It turns out the pageIndex on the gallery is not reliable
                // here, hence we use the index on the current_subview.
                var index  = this.collection.indexOf(current_subview.model);

                Backbone.$(this.gallery.slider).one('transitionend',
                    Backbone.$.proxy(function () {
                        this.trigger('page_changed', index);
                    }, this)
                );
            }, this));

            this.gallery.bind();

            // If model specified, navigate to specified page
            if (this.model) {
                this.go_to(this.model);
            }

            return this;
        },

        remove: function () {
            // Remove self and all subviews
            _.each(this.subViews, function (view) {
                view.remove();
            });
            this.subViews = [null, null, null];

            Backbone.View.prototype.remove.call(this);
        },

        render_subview: function(page_index) {
            // Instantiate a new subview for this page.
            // console.log('Rendering SwipeView page: ', page_index);

            // Request the model using the page_index from the collection.
            var obj = this.collection.at(page_index);

            // Instantiate the subview using the newly acquired model.
            var subview_instance = new this.subview({
                model: obj
            });

            // Render the fucker.
            subview_instance.render();

            return subview_instance;
        },
    });
}));
<|endoftext|>


<commit_before>'use strict';

var glob = require('glob').sync;

var paths = glob('tests/*').filter(function(path) {
  return !/fixtures/.test(path);
});

paths = paths.concat([
  'lib',
  'bin',
  'blueprints'
]);

require('mocha-eslint')(paths);
<commit_msg>tests/lint: Increase "timeout" and "slow" properties<commit_after>'use strict';

var glob = require('glob').sync;

var paths = glob('tests/*').filter(function(path) {
  return !/fixtures/.test(path);
});

paths = paths.concat([
  'lib',
  'bin',
  'blueprints'
]);

require('mocha-eslint')(paths, {
  timeout: 5000,
  slow: 1000,
});
<|endoftext|>


<commit_before>/*
Coded by Orzo with special thanks to Birdy (for the idea + word list contributions)
Also thanks to w3schools, Mozilla Firefox, Stack Overflow, the Internet... and of course, Calliope Town <3
otherwise, this would not have been possible!
*/

var items = [];
var charries = [];
var states = [];
var char1;
var char2;
var char3;

$.get('https://rawgit.com/orzoxcv/calliope-roulette/master/items.txt', function(data) {
    items = data.split("\n");
});

$.get('https://rawgit.com/orzoxcv/calliope-roulette/master/states.txt', function(data) {
    states = data.split("\n");
});

// $.get('https://rawgit.com/orzoxcv/calliope-roulette/master/characters.txt', function(data) {
//     charries = data.split("\n");
// });

function randomValueFromArray(array){
  var random = Math.floor(Math.random()*(array.length-1))
  return array[random];
}

function initializeCharries(){
	var x = document.getElementById("myText").value;
	charries = x.split("\n");
	char1 = Math.floor(Math.random() * (charries.length-1));
	char2 = char1;
	while(char2 == char1){
		char2 = Math.floor(Math.random() * (charries.length-1));
	}
	if (charries.length>2){
		char3 = char2;
		while(char3 == char2 || char3 == char1){
			char3 = Math.floor(Math.random() * (charries.length-1));
		}
	}
}

function genScenario(){
	var text = document.getElementById("outputScenario");
	initializeCharries();

	//***GENERATE A SCENARIO***//

	var x = Math.floor((Math.random() * 6) + 0);

	var scenario = "For some reason, ";

	if (x==0){
		scenario += ":P1: owes :P2: :a(n): :xitem:."
	}
	else if (x==1){
		scenario += ":P1: gives :P2: :a(n): :xitem:.";
	}
	else if (x==2){
		scenario += ":P1: sees :P2: walking around with :a(n): :xitem:"

		var w = Math.floor(Math.random() * 2)+1;
		if (w == 1){
			scenario += " while :xstate:.";
		} else {
			scenario += ".";
		}

		var y = Math.floor(Math.random() * 2)+1;
		if (charries.length>2){
			if (y == 1){
				scenario += " Plot-twist: It's :P3:'s.";
			}
		}
	}
	else if (x==3){
		scenario += ":P1: steals :P2:'s :xitem:."
	}
	else if (x==4){
		scenario += ":P1: needs to borrow :P2:'s :xitem:."
	}
	else if (x==5){
		scenario += ":P1: and :P2: are arguing over who gets the last :xitem:.";
	}
	else {
		scenario += ":P1: has :P2:'s :xitem:."
		var y = Math.floor(Math.random() * 2)+1;
		if (y == 1){
			scenario += " But :P2: doesn't know that. Yet.";
		}
	}

	//***MAD LIBS REPLACEAROO***//
	var item = randomValueFromArray(items);
	var item = randomValueFromArray(states);

	scenario = scenario.replace(":P1:", charries[char1]);
	scenario = scenario.replace(":P2:", charries[char2]);
	scenario = scenario.replace(":xitem:", item);
	scenario = scenario.replace(":xstate:", state);
	if (charries.length>2){
		scenario = scenario.replace(":P3:", charries[char3]);
	}

	//***GRAMMAR STUFF***//
	var firstletteritem = item.substring(0,1);

	if (firstletteritem.localeCompare("a") == 0 ||
		firstletteritem.localeCompare("e") == 0 ||
		firstletteritem.localeCompare("i") == 0 ||
		firstletteritem.localeCompare("o") == 0 ||
		firstletteritem.localeCompare("u") == 0) {

		scenario = scenario.replace(":a(n):", "an");

	} else {
		scenario = scenario.replace(":a(n):", "a");
	}

	//***OUTPUT***//
	text.innerHTML = scenario;
}
<commit_msg>Update calliope-roulette.js<commit_after>/*
Coded by Orzo with special thanks to Birdy (for the idea + word list contributions)
Also thanks to w3schools, Mozilla Firefox, Stack Overflow, the Internet... and of course, Calliope Town <3
otherwise, this would not have been possible!
*/

var items = [];
var charries = [];
var states = [];
var char1;
var char2;
var char3;

$.get('https://rawgit.com/orzoxcv/calliope-roulette/master/items.txt', function(data) {
    items = data.split("\n");
});

$.get('https://rawgit.com/orzoxcv/calliope-roulette/master/states.txt', function(data) {
    states = data.split("\n");
});

// $.get('https://rawgit.com/orzoxcv/calliope-roulette/master/characters.txt', function(data) {
//     charries = data.split("\n");
// });

function randomValueFromArray(array){
  var random = Math.floor(Math.random()*(array.length-1))
  return array[random];
}

function initializeCharries(){
	var x = document.getElementById("myText").value;
	charries = x.split("\n");
	char1 = Math.floor(Math.random() * (charries.length-1));
	char2 = char1;
	while(char2 == char1){
		char2 = Math.floor(Math.random() * (charries.length-1));
	}
	if (charries.length>2){
		char3 = char2;
		while(char3 == char2 || char3 == char1){
			char3 = Math.floor(Math.random() * (charries.length-1));
		}
	}
}

function genScenario(){
	var text = document.getElementById("outputScenario");
	initializeCharries();

	//***GENERATE A SCENARIO***//

	var x = Math.floor((Math.random() * 6) + 0);

	var scenario = "For some reason, ";

	if (x==0){
		scenario += ":P1: owes :P2: :a(n): :xitem:."
	}
	else if (x==1){
		scenario += ":P1: gives :P2: :a(n): :xitem:.";
	}
	else if (x==2){
		scenario += ":P1: sees :P2: walking around with :a(n): :xitem:";

		var w = Math.floor(Math.random() * 2)+1;
		if (w == 1){
			scenario += " while :xstate:.";
		} else {
			scenario += ".";
		}

		var y = Math.floor(Math.random() * 2)+1;
		if (charries.length>2){
			if (y == 1){
				scenario += " Plot-twist: It's :P3:'s.";
			}
		}
	}
	else if (x==3){
		scenario += ":P1: steals :P2:'s :xitem:."
	}
	else if (x==4){
		scenario += ":P1: needs to borrow :P2:'s :xitem:."
	}
	else if (x==5){
		scenario += ":P1: and :P2: are arguing over who gets the last :xitem:.";
	}
	else {
		scenario += ":P1: has :P2:'s :xitem:."
		var y = Math.floor(Math.random() * 2)+1;
		if (y == 1){
			scenario += " But :P2: doesn't know that. Yet.";
		}
	}

	//***MAD LIBS REPLACEAROO***//
	var item = randomValueFromArray(items);
	var item = randomValueFromArray(states);

	scenario = scenario.replace(":P1:", charries[char1]);
	scenario = scenario.replace(":P2:", charries[char2]);
	scenario = scenario.replace(":xitem:", item);
	scenario = scenario.replace(":xstate:", state);
	if (charries.length>2){
		scenario = scenario.replace(":P3:", charries[char3]);
	}

	//***GRAMMAR STUFF***//
	var firstletteritem = item.substring(0,1);

	if (firstletteritem.localeCompare("a") == 0 ||
		firstletteritem.localeCompare("e") == 0 ||
		firstletteritem.localeCompare("i") == 0 ||
		firstletteritem.localeCompare("o") == 0 ||
		firstletteritem.localeCompare("u") == 0) {

		scenario = scenario.replace(":a(n):", "an");

	} else {
		scenario = scenario.replace(":a(n):", "a");
	}

	//***OUTPUT***//
	text.innerHTML = scenario;
}
<|endoftext|>


<commit_before>/******************************************************************************
 *
 * Copyright (c) 2017, the Perspective Authors.
 *
 * This file is part of the Perspective library, distributed under the terms of
 * the Apache License 2.0.  The full license can be found in the LICENSE file.
 *
 */

import { registerPlugin } from "@finos/perspective-viewer/dist/esm/utils.js";
import L from "leaflet"

/*const VIEWER_MAP = new Map();*/
const geomColumn = "geometry"
const idMap = "map"

function get_or_create_map(element, div) {
  if (document.getElementById(idMap)) {
    document.getElementById(idMap).remove()
  }
  // Attach the container div to the DOM
  const mapElement = document.createElement("div");
  mapElement.id = idMap
  div.innerHTML = ""
  div.appendChild(document.createElement("slot"))
  element.appendChild(mapElement);

  // Initialize Leaflet
  const map = L.map(idMap);
  L.tileLayer('https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png', {
    attribution: '© OpenStreetMap contributors'
  }).addTo(map);

  // if (!VIEWER_MAP.has(idMap)) {

  //   // Save the map to fetch it later
  //   VIEWER_MAP.set(idMap, map);
  // } else {
  //   // Fetch the map form the store
  //   map = VIEWER_MAP.get(idMap);

  //   // Attach the container div to the DOM
  //   const mapElement = document.createElement("div");
  //   mapElement.id = idMap
  //   div.innerHTML = ""
  //   div.appendChild(document.createElement("slot"))
  //   element.appendChild(mapElement);
  // }

  return map;
}

export class MapPlugin {
  static async update() { }

  static async create(div, view) {
    try {
      const columns = JSON.parse(this.getAttribute("columns"))
      if (!columns.includes(geomColumn)) {
        columns.push(geomColumn)
        this.setAttribute('columns', JSON.stringify(columns))
      }

      const map = get_or_create_map(this, div);
      map.eachLayer(layer => {
        // Delete all GeoJSON layers
        layer instanceof L.FeatureGroup ? map.removeLayer(layer) : null
      })

      const dataMap = await view.to_json() || []
      if (dataMap.some(x => !!x[geomColumn])) {
        const geojson = L.featureGroup(dataMap.map(({ [geomColumn]: geometry = "{}", ...properties }) => {
          return L.geoJSON({ type: "Feature", geometry: JSON.parse(geometry), properties })
        })).addTo(map)

        map.fitBounds(geojson.getBounds());
      }
    } catch (e) {
      if (e.message !== "View is not initialized") {
        throw e;
      }
    }
  }

  static async resize() {
    // if (this.view && VIEWER_MAP.has(this._datavis)) {
    //   const datagrid = VIEWER_MAP.get(this._datavis);
    //   try {
    //     await datagrid.draw();
    //   } catch (e) {
    //     if (e.message !== "View is not initialized") {
    //       throw e;
    //     }
    //   }
    // }
  }

  static delete() {
    console.log("map delete");
  }

  static save() {}

  static restore() {
    console.log("map restore");
  }
}

registerPlugin("map", MapPlugin);
<commit_msg>plugin verbose<commit_after>import { registerPlugin } from "@finos/perspective-viewer/dist/esm/utils.js";
import L from "leaflet"

// default geoJSON column name
const geomColumn = "geometry"
// default HTML id
const idMap = "map"

function createMapNode(element, div) {
  if (document.getElementById(idMap)) {
    document.getElementById(idMap).remove()
  }
  // Attach the container div to the DOM
  const mapElement = document.createElement("div");
  mapElement.id = idMap
  div.innerHTML = ""
  div.appendChild(document.createElement("slot"))
  element.appendChild(mapElement);

  // Initialize Leaflet
  const map = L.map(idMap);
  L.tileLayer('https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png', {
    attribution: '© OpenStreetMap contributors'
  }).addTo(map);

  return map;
}

export class MapPlugin {
  static async update() { }

  static async create(div, view) {
    try {
      const columns = JSON.parse(this.getAttribute("columns"))

      // Enforces to have a geometry column
      if (!columns.includes(geomColumn)) {
        columns.push(geomColumn)
        this.setAttribute("columns", JSON.stringify(columns))
      }

      const map = createMapNode(this, div);
      map.eachLayer(layer => {
        // Delete all previous GeoJSON layers
        layer instanceof L.FeatureGroup ? map.removeLayer(layer) : null
      })

      // fetch the current displayed data
      const dataMap = await view.to_json() || []
      if (dataMap.some(({ [geomColumn]: geometry }) => !!geometry)) {
        const geojson = L.featureGroup(
          dataMap.map(({ [geomColumn]: geometry = "{}", ...properties }) =>
            L.geoJSON({
              type: "Feature",
              geometry: JSON.parse(geometry),
              properties
            })
          )
        ).addTo(map);

        map.fitBounds(geojson.getBounds());
      }
    } catch (e) {
      if (e.message !== "View is not initialized") {
        throw e;
      }
    }
  }

  static async resize() {
    // if (this.view && VIEWER_MAP.has(this._datavis)) {
    //   const datagrid = VIEWER_MAP.get(this._datavis);
    //   try {
    //     await datagrid.draw();
    //   } catch (e) {
    //     if (e.message !== "View is not initialized") {
    //       throw e;
    //     }
    //   }
    // }
  }

  static delete() {}

  static save() {}

  static restore() {}
}

registerPlugin("map", MapPlugin);
<|endoftext|>