<commit_before>let getRowInfo = (key, value, level) => {
  let type = typeof value;

  let info = {
    keyValue: key,
    value: value,
    formattedValue: typeof value,
    notPrunedString: false,
    level: level,
    isPruned: false,
    hasChildren: false,
    valueClass: type,
    copyValue: false,
    isId: false
  };
  if (resemblesId(value)) {
    info['formattedValue'] = value;
    info['valueClass'] = 'id';
    info['copyValue'] = value;
    info['isId'] = true;
  } else if (_.isNumber(value)) {
    info['formattedValue'] = value;
    info['valueClass'] = 'number';
    info['copyValue'] = value;
  } else if (_.isString(value)) {
    info['formattedValue'] = s(value).prune(35).value();
    info['isPruned'] = value.length > 35;
    info['copyValue'] = value;
    info['notPrunedString'] = value;
  } else if (_.isNull(value)) {
    info['formattedValue'] = 'null';
    info['valueClass'] = 'null';
  } else if (_.isBoolean(value)) {
    info['formattedValue'] = value ? 'true' : 'false';
  } else if (_.isDate(value)) {
    info['formattedValue'] = value;
    info['valueClass'] = 'date';
    info['copyValue'] = moment(value).format(Settings.dateFormat);
  } else if (_.isArray(value)) {
    info['formattedValue'] = '[ ' + value.length + ' items ]';
    info['valueClass'] = 'array';
    info['hasChildren'] = true;
    info['copyValue'] = JSON.stringify(value);
  } else if (_.isObject(value)) {
    info['formattedValue'] = '{ ' + Object.keys(value).length + ' fields }';
    info['valueClass'] = 'object';
    info['hasChildren'] = true;
    info['copyValue'] = JSON.stringify(value);
  }

  info.valueClass = 'value-' + info.valueClass;

  if (level == 0) {
    let pinnedColumns = [];
    if (CurrentSession.collection.pinnedColumns && CurrentSession.collection.pinnedColumns.length > 0) {
      _.each(CurrentSession.collection.pinnedColumns, (column) => {
        try {
          let t = eval('(value.' + column + ')');
          if (t) pinnedColumns.push('
'+t+'
');
        }
        catch (error) {
          // do nothing
        }

      })
    } else {
      if (value.name) {
        pinnedColumns.push('
'+value.name+'
');
      } else if (value.title) {
        pinnedColumns.push('
' + value.title + '
');
      }
    }
    if (pinnedColumns.length) {
      info.keyValue += ' ' + info.formattedValue + '';
      info.formattedValue = pinnedColumns.join('');
    }
  }

  if (info.hasChildren) {
    let fields = [];
    let id = null;
    _.each(value, (v, k) => {
      if (k == '_id') {
        id = v;
        return;
      }

      fields.push({
        key: k,
        value: v
      })
    });

    fields = _.sortBy(fields, 'key');
    if (id) fields.unshift({key: '_id', value: id});

    info.children = [];
    _.each(fields, (v) => {
      info.children.push(getRowInfo(v.key, v.value, level + 1));
    });
  }

  return info;
};

let deleteHintTimeout = null;
let showDeleteHint = (show = true) => {
  // first stop previous timeout if exists
  if(deleteHintTimeout) Meteor.clearTimeout(deleteHintTimeout);

  if(show) {
    deleteHintTimeout = Meteor.setTimeout(() => {
      sAlert.info('Psst!! Hey you! Try double click...');
    }, 300);
  }
};

Template.TreeDocument.onCreated(function () {
  let key = this.data._id;
  let value = this.data;
  let info = getRowInfo(typeof key == 'string' ? key : key._str, value, 0);
  //log('> info', info);

  this.info = info;
});

Template.TreeDocument.helpers({
  info() {
    return Template.instance().info;
  }
});

Template.TreeDocument.events({
  'click .copy-value'(event, templateInstance) {
    event.preventDefault();
    event.stopImmediatePropagation();
    copyText($(event.currentTarget).attr('data-clipboard-text'));
  },
  'click .edit-document'(event, templateInstance) {
    event.preventDefault();
    event.stopImmediatePropagation();

    Session.set('DocumentEditorModal', {
      connectionId: CurrentSession.connection._id,
      databaseId: CurrentSession.database._id,
      collectionId: CurrentSession.collection._id,
      documentId: this.value._id,
      document: this.value
    });
    $('#DocumentEditorModal').modal('show');
  },
  'click .duplicate-document'(event, templateInstance) {
    event.preventDefault();
    event.stopImmediatePropagation();
    Meteor.call('duplicateDocument', CurrentSession.collection._id, this.value._id, function (error, result) {
      if (!error) {
        sAlert.success('Document duplicated with new _ID: ' + result)
      }
    });
  },
  'dblclick .delete-document'(event, templateInstance) {
    event.preventDefault();
    event.stopImmediatePropagation();
    showDeleteHint(false);
    Meteor.call('removeDocument', CurrentSession.collection._id, this.value._id)
  },
  'click .delete-document'(event, templateInstance) {
    event.preventDefault();
    event.stopImmediatePropagation();
    showDeleteHint();
  },
  'click .view-value'(event, templateInstance) {
    event.preventDefault();
    event.stopImmediatePropagation();

    Session.set('ViewValueModal', {
      title: this.keyValue,
      value: this.notPrunedString
    });
    $('#ViewValueModal').modal('show');
  },
  'click .find-id'(event, templateInstance) {
    event.preventDefault();
    event.stopImmediatePropagation();
    Meteor.call('findCollectionForDocumentId', CurrentSession.database._id, this.value, (error, result) => {
      let c = Collections.findOne({database_id: CurrentSession.database._id, name: result});
      if (c) {
        CurrentSession.documentsSelector = this.value;
        CurrentSession.documentsOptions = {};
        const data = {
          collection: c.name,
          database: c.database().name,
          connection: c.database().connection().slug
        };

        goTo(FlowRouter.path('Documents', data));
      }
    });
  }

});
<commit_msg>Document ID shown incorrectly [close: #31]<commit_after>let getRowInfo = (key, value, level) => {
  let type = typeof value;

  let info = {
    keyValue: key,
    value: value,
    formattedValue: typeof value,
    notPrunedString: false,
    level: level,
    isPruned: false,
    hasChildren: false,
    valueClass: type,
    copyValue: false,
    isId: false,
    idValue: null
  };
  if (resemblesId(value) || key == '_id') {
    info['formattedValue'] = value;
    info['valueClass'] = 'id';
    info['copyValue'] = value;
    info['isId'] = true;
    info['idValue'] = value;
  } else if (_.isNumber(value)) {
    info['formattedValue'] = value;
    info['valueClass'] = 'number';
    info['copyValue'] = value;
  } else if (_.isString(value)) {
    info['formattedValue'] = s(value).prune(35).value();
    info['isPruned'] = value.length > 35;
    info['copyValue'] = value;
    info['notPrunedString'] = value;
  } else if (_.isNull(value)) {
    info['formattedValue'] = 'null';
    info['valueClass'] = 'null';
  } else if (_.isBoolean(value)) {
    info['formattedValue'] = value ? 'true' : 'false';
  } else if (_.isDate(value)) {
    info['formattedValue'] = value;
    info['valueClass'] = 'date';
    info['copyValue'] = moment(value).format(Settings.dateFormat);
  } else if (_.isArray(value)) {
    info['formattedValue'] = '[ ' + value.length + ' items ]';
    info['valueClass'] = 'array';
    info['hasChildren'] = true;
    info['copyValue'] = JSON.stringify(value);
  } else if (_.isObject(value)) {
    info['formattedValue'] = '{ ' + Object.keys(value).length + ' fields }';
    info['valueClass'] = 'object';
    info['hasChildren'] = true;
    info['copyValue'] = JSON.stringify(value);
  }

  info.valueClass = 'value-' + info.valueClass;

  if (level == 0) {
    let pinnedColumns = [];
    if (CurrentSession.collection.pinnedColumns && CurrentSession.collection.pinnedColumns.length > 0) {
      _.each(CurrentSession.collection.pinnedColumns, (column) => {
        try {
          let t = eval('(value.' + column + ')');
          if (t) pinnedColumns.push('
'+t+'
');
        }
        catch (error) {
          // do nothing
        }

      })
    } else {
      if (value.name) {
        pinnedColumns.push('
'+value.name+'
');
      } else if (value.title) {
        pinnedColumns.push('
' + value.title + '
');
      }
    }
    if (pinnedColumns.length) {
      info.keyValue += ' ' + info.formattedValue + '';
      info.formattedValue = pinnedColumns.join('');
    }
  }

  if (info.hasChildren) {
    let fields = [];
    let id = null;
    _.each(value, (v, k) => {
      if (k == '_id') {
        id = v;
        return;
      }

      fields.push({
        key: k,
        value: v
      })
    });

    fields = _.sortBy(fields, 'key');
    if (id) fields.unshift({key: '_id', value: id});

    info.children = [];
    _.each(fields, (v) => {
      info.children.push(getRowInfo(v.key, v.value, level + 1));
    });
  }

  return info;
};

let deleteHintTimeout = null;
let showDeleteHint = (show = true) => {
  // first stop previous timeout if exists
  if(deleteHintTimeout) Meteor.clearTimeout(deleteHintTimeout);

  if(show) {
    deleteHintTimeout = Meteor.setTimeout(() => {
      sAlert.info('Psst!! Hey you! Try double click...');
    }, 300);
  }
};

Template.TreeDocument.onCreated(function () {
  let key = this.data._id;
  let value = this.data;
  let info = getRowInfo(typeof key == 'string' ? key : key._str, value, 0);
  //log('> info', info);

  this.info = info;
});

Template.TreeDocument.helpers({
  info() {
    return Template.instance().info;
  }
});

Template.TreeDocument.events({
  'click .copy-value'(event, templateInstance) {
    event.preventDefault();
    event.stopImmediatePropagation();
    copyText($(event.currentTarget).attr('data-clipboard-text'));
  },
  'click .edit-document'(event, templateInstance) {
    event.preventDefault();
    event.stopImmediatePropagation();

    Session.set('DocumentEditorModal', {
      connectionId: CurrentSession.connection._id,
      databaseId: CurrentSession.database._id,
      collectionId: CurrentSession.collection._id,
      documentId: this.value._id,
      document: this.value
    });
    $('#DocumentEditorModal').modal('show');
  },
  'click .duplicate-document'(event, templateInstance) {
    event.preventDefault();
    event.stopImmediatePropagation();
    Meteor.call('duplicateDocument', CurrentSession.collection._id, this.value._id, function (error, result) {
      if (!error) {
        sAlert.success('Document duplicated with new _ID: ' + result)
      }
    });
  },
  'dblclick .delete-document'(event, templateInstance) {
    event.preventDefault();
    event.stopImmediatePropagation();
    showDeleteHint(false);
    Meteor.call('removeDocument', CurrentSession.collection._id, this.value._id)
  },
  'click .delete-document'(event, templateInstance) {
    event.preventDefault();
    event.stopImmediatePropagation();
    showDeleteHint();
  },
  'click .view-value'(event, templateInstance) {
    event.preventDefault();
    event.stopImmediatePropagation();

    Session.set('ViewValueModal', {
      title: this.keyValue,
      value: this.notPrunedString
    });
    $('#ViewValueModal').modal('show');
  },
  'click .find-id'(event, templateInstance) {
    event.preventDefault();
    event.stopImmediatePropagation();

    Meteor.call('findCollectionForDocumentId', CurrentSession.database._id, this.idValue, (error, result) => {
      let c = Collections.findOne({database_id: CurrentSession.database._id, name: result});
      if (c) {
        CurrentSession.documentsSelector = this.idValue;
        CurrentSession.documentsOptions = {};
        const data = {
          collection: c.name,
          database: c.database().name,
          connection: c.database().connection().slug
        };

        goTo(FlowRouter.path('Documents', data));
      }
    });
  }

});
<|endoftext|>


<commit_before>define(function(require) {

	'use strict';

	var _    = require('underscore');
	var PIXI = require('pixi');

	var Particle              = require('models/particle');
	var HeatmapView           = require('views/heatmap');
	var SpeakerOscillatorView = require('views/oscillator/speaker');

	/**
	 * Constants
	 */
	var PARTICLE_CELL_RATIO = 3;

	/*
	 * "Local" variables for functions to share and recycle
	 */
	var sprite,
	    particle,
	    particles,
	    sprites,
	    texture,
	    texture2,
	    xSpacing,
	    ySpacing,
	    width,
	    height,
	    i,
	    j,
	    scale;

	/**
	 * SoundHeatmapView is the sound simulation version of the HeatmapView
	 *   that uses different sub-views where necessary.
	 */
	var SoundHeatmapView = HeatmapView.extend({

		initialize: function(options) {
			// Default values
			options = _.extend({
				title: 'Pressure (Heatmap) – XY Plane',
				color: '#000'
			}, options);

			HeatmapView.prototype.initialize.apply(this, [ options ]);

			this.accumulator = 0;
		},

		/**
		 * Overrides HeatmapView.renderOscillatorView so it can use the
		 *   SpeakerOscillatorView instead of the plain OscillatorView.
		 */
		renderOscillatorView: function(oscillator) {
			// Create a new view and render it
			var oscillatorView = new SpeakerOscillatorView({
				heatmapView: this,
				oscillator: oscillator
			});
			oscillatorView.render();

			this.addOscillatorView(oscillatorView);
		},

		/**
		 * A helper function to iterate through all the pressure particles
		 *   because they aren't a 1:1 ratio with the lattice cells.
		 */
		eachPressureParticle: function(callback) {
			width  = this.waveSimulation.lattice.width;
			height = this.waveSimulation.lattice.height;

			for (i = 0; i < width; i++) {
				for (j = 0; j < height; j++) {
					if (i % PARTICLE_CELL_RATIO === 0 && j % PARTICLE_CELL_RATIO === 0) {
						callback.apply(this, [ i, j ]);
					}
				}
			}
		},

		/**
		 * Need to have xSpacing and ySpacing defined before this will work
		 */
		initPressureParticles: function() {
			this.pressureParticles = [];
			this.pressureParticleSprites = [];

			this.pressureParticleSpriteBatch = new PIXI.SpriteBatch();
			this.stage.addChild(this.pressureParticleSpriteBatch);

			this.disablePressureParticles();

			texture  = PIXI.Texture.fromImage('../img/phet/particle-blue.gif');
			texture2 = PIXI.Texture.fromImage('../img/phet/particle-blue-marked.png');

			this.eachPressureParticle(function(i, j) {
				if (!this.pressureParticles[i]) {
					this.pressureParticles[i]       = [];
					this.pressureParticleSprites[i] = [];
				}

				if (Math.random() < 0.05)
					sprite = new PIXI.Sprite(texture2);
				else
					sprite = new PIXI.Sprite(texture);
				sprite.anchor.x = sprite.anchor.y = 0.5;

				particle = new Particle({
					i: i,
					j: j,
					spacingBetweenCells: 1,
					lattice: this.waveSimulation.lattice
				});

				this.pressureParticles[i][j] = particle;
				this.pressureParticleSprites[i][j] = sprite;

				this.pressureParticleSpriteBatch.addChild(sprite);
			});

			this.resizePressureParticles();
		},

		/**
		 *
		 */
		resizePressureParticles: function() {
			height = this.waveSimulation.lattice.height;

			xSpacing = this.xSpacing;

			particles = this.pressureParticles;
			sprites   = this.pressureParticleSprites;

			scale = (2.5 * xSpacing) / 36;

			this.eachPressureParticle(function(i, j) {
				particles[i][j].resize(xSpacing);

				sprite = sprites[i][j];
				sprite.scale.x = scale;
				sprite.scale.y = scale;
				// TODO: change the scale?
			});
		},

		/**
		 *
		 */
		enablePressureParticles: function() {
			this.pressureParticleSpriteBatch.visible = true;
			this.spriteBatch.visible = false;

			this.$('.heatmap-title').html('Pressure (Particles) – XY Plane');
		},

		/**
		 *
		 */
		disablePressureParticles: function() {
			this.spriteBatch.visible = true;
			this.pressureParticleSpriteBatch.visible = false;

			this.$('.heatmap-title').html(this.graphInfo.title);
		},

		/**
		 * Updates all the pressure particles.
		 */
		updatePressureParticles: function() {
			this.eachPressureParticle(this._updatePressureParticlesCallback);
		},

		/**
		 * This needs to be saved and reused instead of just
		 *   being an anonymous function because it gets run
		 *   every frame.
		 */
		_updatePressureParticlesCallback: function(i, j) {
			this.pressureParticles[i][j].update();

			this.pressureParticleSprites[i][j].position.x = this.pressureParticles[i][j].x;
			this.pressureParticleSprites[i][j].position.y = this.height - this.pressureParticles[i][j].y;
		},

		resizeGraphics: function() {
			if (this.pressureParticles)
				this.resizePressureParticles();

			HeatmapView.prototype.resizeGraphics.apply(this);
		},

		update: function(time, delta) {
			if (!this.waveSimulation.paused) {
				if (!this.pressureParticles) {
					this.initPressureParticles();
				}

				this.accumulator += delta;

				while (this.accumulator >= this.waveSimulation.timestep) {
					this.updatePressureParticles();

					this.accumulator -= this.waveSimulation.timestep;
				}
			}

			HeatmapView.prototype.update.apply(this, [time, delta]);
		}

	});

	return SoundHeatmapView;
});
<commit_msg>Maybe fixed some img paths<commit_after>define(function(require) {

	'use strict';

	var _    = require('underscore');
	var PIXI = require('pixi');

	var Particle              = require('models/particle');
	var HeatmapView           = require('views/heatmap');
	var SpeakerOscillatorView = require('views/oscillator/speaker');

	/**
	 * Constants
	 */
	var PARTICLE_CELL_RATIO = 3;

	/*
	 * "Local" variables for functions to share and recycle
	 */
	var sprite,
	    particle,
	    particles,
	    sprites,
	    texture,
	    texture2,
	    xSpacing,
	    ySpacing,
	    width,
	    height,
	    i,
	    j,
	    scale;

	/**
	 * SoundHeatmapView is the sound simulation version of the HeatmapView
	 *   that uses different sub-views where necessary.
	 */
	var SoundHeatmapView = HeatmapView.extend({

		initialize: function(options) {
			// Default values
			options = _.extend({
				title: 'Pressure (Heatmap) – XY Plane',
				color: '#000'
			}, options);

			HeatmapView.prototype.initialize.apply(this, [ options ]);

			this.accumulator = 0;
		},

		/**
		 * Overrides HeatmapView.renderOscillatorView so it can use the
		 *   SpeakerOscillatorView instead of the plain OscillatorView.
		 */
		renderOscillatorView: function(oscillator) {
			// Create a new view and render it
			var oscillatorView = new SpeakerOscillatorView({
				heatmapView: this,
				oscillator: oscillator
			});
			oscillatorView.render();

			this.addOscillatorView(oscillatorView);
		},

		/**
		 * A helper function to iterate through all the pressure particles
		 *   because they aren't a 1:1 ratio with the lattice cells.
		 */
		eachPressureParticle: function(callback) {
			width  = this.waveSimulation.lattice.width;
			height = this.waveSimulation.lattice.height;

			for (i = 0; i < width; i++) {
				for (j = 0; j < height; j++) {
					if (i % PARTICLE_CELL_RATIO === 0 && j % PARTICLE_CELL_RATIO === 0) {
						callback.apply(this, [ i, j ]);
					}
				}
			}
		},

		/**
		 * Need to have xSpacing and ySpacing defined before this will work
		 */
		initPressureParticles: function() {
			this.pressureParticles = [];
			this.pressureParticleSprites = [];

			this.pressureParticleSpriteBatch = new PIXI.SpriteBatch();
			this.stage.addChild(this.pressureParticleSpriteBatch);

			this.disablePressureParticles();

			texture  = PIXI.Texture.fromImage('img/phet/particle-blue.gif');
			texture2 = PIXI.Texture.fromImage('img/phet/particle-blue-marked.png');

			this.eachPressureParticle(function(i, j) {
				if (!this.pressureParticles[i]) {
					this.pressureParticles[i]       = [];
					this.pressureParticleSprites[i] = [];
				}

				if (Math.random() < 0.05)
					sprite = new PIXI.Sprite(texture2);
				else
					sprite = new PIXI.Sprite(texture);
				sprite.anchor.x = sprite.anchor.y = 0.5;

				particle = new Particle({
					i: i,
					j: j,
					spacingBetweenCells: 1,
					lattice: this.waveSimulation.lattice
				});

				this.pressureParticles[i][j] = particle;
				this.pressureParticleSprites[i][j] = sprite;

				this.pressureParticleSpriteBatch.addChild(sprite);
			});

			this.resizePressureParticles();
		},

		/**
		 *
		 */
		resizePressureParticles: function() {
			height = this.waveSimulation.lattice.height;

			xSpacing = this.xSpacing;

			particles = this.pressureParticles;
			sprites   = this.pressureParticleSprites;

			scale = (2.5 * xSpacing) / 36;

			this.eachPressureParticle(function(i, j) {
				particles[i][j].resize(xSpacing);

				sprite = sprites[i][j];
				sprite.scale.x = scale;
				sprite.scale.y = scale;
				// TODO: change the scale?
			});
		},

		/**
		 *
		 */
		enablePressureParticles: function() {
			this.pressureParticleSpriteBatch.visible = true;
			this.spriteBatch.visible = false;

			this.$('.heatmap-title').html('Pressure (Particles) – XY Plane');
		},

		/**
		 *
		 */
		disablePressureParticles: function() {
			this.spriteBatch.visible = true;
			this.pressureParticleSpriteBatch.visible = false;

			this.$('.heatmap-title').html(this.graphInfo.title);
		},

		/**
		 * Updates all the pressure particles.
		 */
		updatePressureParticles: function() {
			this.eachPressureParticle(this._updatePressureParticlesCallback);
		},

		/**
		 * This needs to be saved and reused instead of just
		 *   being an anonymous function because it gets run
		 *   every frame.
		 */
		_updatePressureParticlesCallback: function(i, j) {
			this.pressureParticles[i][j].update();

			this.pressureParticleSprites[i][j].position.x = this.pressureParticles[i][j].x;
			this.pressureParticleSprites[i][j].position.y = this.height - this.pressureParticles[i][j].y;
		},

		resizeGraphics: function() {
			if (this.pressureParticles)
				this.resizePressureParticles();

			HeatmapView.prototype.resizeGraphics.apply(this);
		},

		update: function(time, delta) {
			if (!this.waveSimulation.paused) {
				if (!this.pressureParticles) {
					this.initPressureParticles();
				}

				this.accumulator += delta;

				while (this.accumulator >= this.waveSimulation.timestep) {
					this.updatePressureParticles();

					this.accumulator -= this.waveSimulation.timestep;
				}
			}

			HeatmapView.prototype.update.apply(this, [time, delta]);
		}

	});

	return SoundHeatmapView;
});
<|endoftext|>


<commit_before>'use strict';

describe('Directive: mansharCover', function () {

  var scope, element, elementWithoutUrl;
  beforeEach(module('webClientApp'));

  beforeEach(inject(function ($compile, $rootScope) {
    scope = $rootScope;
    element = angular.element(
        '

');

    elementWithoutUrl = angular.element(
        '

');
    $compile(element)(scope);
    $compile(elementWithoutUrl)(scope);
  }));

  it('should add background css properties to the element', function () {
    expect(elementWithoutUrl.css('background-image')).toBe('');
    expect(elementWithoutUrl.css('background-size')).toBe('cover');
    expect(elementWithoutUrl.css('background-repeat')).toBe('no-repeat');
    expect(elementWithoutUrl.css('background-position')).toBe('50% 50%');

    scope.$apply(function() {
      scope.url = 'mybackgroundimage.png';
    });
    expect(element.css('background-image')).toContain('mybackgroundimage.png');
    expect(element.css('background-size')).toBe('cover');
    expect(element.css('background-repeat')).toBe('no-repeat');
    expect(element.css('background-position')).toBe('50% 50%');
  });

});
<commit_msg>Fixed the test for profile cover image<commit_after>'use strict';

describe('Directive: mansharCover', function () {

  var scope, element, elementWithoutUrl;
  beforeEach(module('webClientApp'));

  beforeEach(inject(function ($compile, $rootScope) {
    scope = $rootScope;
    element = angular.element(
        '

');

    elementWithoutUrl = angular.element(
        '

');
    $compile(element)(scope);
    $compile(elementWithoutUrl)(scope);
  }));

  it('should add background css properties to the element', function () {
    expect(elementWithoutUrl.css('background-image')).toBe('');
    expect(elementWithoutUrl.css('background-size')).toBe('cover');
    expect(elementWithoutUrl.css('background-repeat')).toBe('no-repeat');
    expect(elementWithoutUrl.css('background-position')).toBe('50% 0%');

    scope.$apply(function() {
      scope.url = 'mybackgroundimage.png';
    });
    expect(element.css('background-image')).toContain('mybackgroundimage.png');
    expect(element.css('background-size')).toBe('cover');
    expect(element.css('background-repeat')).toBe('no-repeat');
    expect(element.css('background-position')).toBe('50% 0%');
  });

});
<|endoftext|>


<commit_before>'use strict';

app.controller('PrescriptionCtrl', ['$rootScope', '$scope', '$stateParams', '$state', 'Patients', 'Medicines', 'Doctors', 'MedicalRecords', function ($rootScope, $scope, $stateParams, $state, Patients, Medicines, Doctors, MedicalRecords) {
	// For nav redirections
	$scope.$state = $state;
	$scope.$stateParams = $stateParams;

	$scope.prescription = {};
	$scope.treatment = {};
	$scope.medicines = [];
	$scope.doctors = [];

	$scope.listDoctors = function () {
		Doctors.getAll().then(function (doctors) {
			$scope.doctors = doctors;
		}, function (error) {
			alert('A problem occcured when loading the list  doctors :\n' + error.message);
		});
	};

	$scope.searchMedication = function (keyword) {
		if (keyword) {
			Medicines.search(keyword).then(function (medicines) {
				$scope.medicines = medicines;
			}, function (error) {
				console.error(error);
			});
		}
	};

	$scope.submit = function () {
		$scope.prescription.date = new Date();
		Patients.getPatient($stateParams.id).then(function (patient) {
			var medicalFile = patient.medical_file;
			$scope.prescription.medicalFile = medicalFile;
			MedicalRecords.addPrescription(medicalFile.id, $scope.prescription).success(function (data, status, headers, config) {
				$scope.treatment.prescription = data;
				$scope.treatment.medicalFile = data.medicalFile;
				MedicalRecords.addTreatment(medicalFile.id, $scope.treatment).success(function (dataTreatTreatment, statusTreatment, headersTreatment, configTreatment) {
					alert('Prescrition and treatment saved!');
				}).error(function (dataTreatment, statusTreatment, headersTreatment, configTreatment) {
					alert('Oops! Couldn\'t save the treatment');
				});
			}).error(function (data, status, headers, config) {
				alert('Oops! Couldn\'t save the prescription');
			});
		}, function (error) {
			alert(error);
		});
		$('#prescriptionDoctorsModal').modal('hide');
	};

	$scope.listDoctors();
}]);<commit_msg>Redirection on successful prescription save<commit_after>'use strict';

app.controller('PrescriptionCtrl', ['$rootScope', '$scope', '$stateParams', '$state', 'Patients', 'Medicines', 'Doctors', 'MedicalRecords', '$location', function ($rootScope, $scope, $stateParams, $state, Patients, Medicines, Doctors, MedicalRecords, $location) {
	// For nav redirections
	$scope.$state = $state;
	$scope.$stateParams = $stateParams;

	$scope.prescription = {};
	$scope.treatment = {};
	$scope.medicines = [];
	$scope.doctors = [];

	$scope.listDoctors = function () {
		Doctors.getAll().then(function (doctors) {
			$scope.doctors = doctors;
		}, function (error) {
			alert('A problem occcured when loading the list  doctors :\n' + error.message);
		});
	};

	$scope.searchMedication = function (keyword) {
		if (keyword) {
			Medicines.search(keyword).then(function (medicines) {
				$scope.medicines = medicines;
			}, function (error) {
				console.error(error);
			});
		}
	};

	$scope.submit = function () {
		$scope.prescription.date = new Date();
		Patients.getPatient($stateParams.id).then(function (patient) {
			var medicalFile = patient.medical_file;
			$scope.prescription.medicalFile = medicalFile;
			MedicalRecords.addPrescription(medicalFile.id, $scope.prescription).success(function (data, status, headers, config) {
				$scope.treatment.prescription = data;
				$scope.treatment.medicalFile = data.medicalFile;
				MedicalRecords.addTreatment(medicalFile.id, $scope.treatment).success(function (dataTreatTreatment, statusTreatment, headersTreatment, configTreatment) {
					$location.path('/patients/' + $stateParams.id + '/medicalRecord');
				}).error(function (dataTreatment, statusTreatment, headersTreatment, configTreatment) {
					alert('Oops! Couldn\'t save the treatment');
				});
			}).error(function (data, status, headers, config) {
				alert('Oops! Couldn\'t save the prescription');
			});
		}, function (error) {
			alert(error);
		});
		$('#prescriptionDoctorsModal').modal('hide');
	};

	$scope.listDoctors();
}]);<|endoftext|>


<commit_before>
/* Dasca, an idle game by @CylonicRaider (github.com/CylonicRaider/dasca)
 * Abstract engine for JS-based idle games */

'use strict';

/* *** Clock ***
 * An object allowing to sample "time" (as defined by an external source)
 * with a linear transform in place. */

/* Construct a new clock
 * source is a function that, when called, returns the current time; scale
 * and offset modify source's output in a linear fashion: the reading of
 * source is multiplied by scale and offset is added to that to obtain the
 * current time. If scale is undefined or null, it defaults to 1; if offset
 * is null, it is computed such that the clock starts counting from zero. */
function Clock(source, scale, offset) {
  if (scale == null) scale = 1.0;
  if (offset == null) offset = -source() * scale;
  this.source = source;
  this.scale = scale;
  this.offset = offset;
}

Clock.prototype = {
  /* Sample the current time */
  now: function() {
    return this.source() * this.scale + this.offset;
  },

  /* Construct a new clock from this one, applying the given transformation
   * The new clock derives its time from the same (!) source as this one,
   * but its scale and offset are modified to simulate a clock constructed
   * like
   *     new Clock(this, scale, offset);
   */
  derive: function(scale, offset) {
    if (scale == null) scale = 1.0;
    if (offset != null) offset = this.offset * scale + offset;
    var ret = new Clock(this.source, this.scale * scale, offset);
    if (this._realTime) ret._realTime = true;
    return ret;
  },

  /* Serialization boilerplate */
  constructor: Clock
};

/* Construct a clock that returns (optionally scaled) real time
 * The clock counts from zero */
Clock.realTime = function(scale, start) {
  if (scale == null) scale = 1.0;
  scale *= 1e-3;
  var offset = (start == null) ? null : start - performance.now() * scale;
  var ret = new Clock(performance.now.bind(performance), scale, offset);
  ret._realTime = true;
  return ret;
};

/* Seralize a Clock */
Clock.__save__ = function(clock) {
  if (! clock._realTime) throw new Error("Clock not serializable!");
  return {scale: clock.scale * 1e3, time: clock.now()};
};

/* Deserialize a Clock */
Clock.__restore__ = function(data) {
  return Clock.realTime(data.scale, data.time);
};

/* *** Scheduler ***
 * Schedules call-backs to happen at certain times as defined by a Clock
 * instance. */

/* Construct a new scheduler
 * requeue is a funtion that somehow ("magically") ensures the function
 * to it is asynchronously called again some short time later; tasks is an
 * ordered array of objects whose "time" property is used to determine when
 * they are to run; clock is a Clock instance determining the time this
 * instance works with. The "running" property is set to true; it can be used
 * to stop the Scheduler.
 * To start it, ensure the "running" property is true and call the run()
 * method. */
function Scheduler(requeue, tasks, clock) {
  if (tasks == null) tasks = [];
  if (clock == null) clock = Clock.realTime();
  this.requeue = requeue;
  this.tasks = tasks;
  this.clock = clock;
  this.running = true;
}

Scheduler.prototype = {
  /* Queue the next run of the scheduler, and perform any tasks whose time
   * has come
   * After obtaining a timestamp from the clock, all tasks whose time
   * property is not less than the timestamp are removed from the queue and
   * run using runTask(); after that, if the "running" property is true,
   * requeue is called with a bound version of this.run as only argument to
   * trigger another execution. */
  run: function() {
    /* Abort if not running */
    if (! this.running) return;
    /* Obtain current timestamp */
    var now = this.clock.now();
    /* For each task that is (over)due */
    while (this.tasks[0] && this.tasks[0].time <= now) {
      /* Run it */
      this.runTask(this.tasks.shift(), now);
    }
    /* Schedule next iteration */
    this.requeue(this.run.bind(this));
  },

  /* Run a singular task, providing the given timestamp
   * The default implementation calls the task's "cb" (which is assumed to be
   * a function) with the value of now and the Scheduler instance as
   * arguments, and consumes exceptions by logging them to the console. */
  runTask: function(task, now) {
    try {
      task.cb(now, this);
    } catch (e) {
      console.error(e);
    }
  },

  /* Schedule a task to be run
   * If time is not null, it is inserted into task as the "time" property;
   * after that, the task is inserted at an appropriate position. */
  addTask: function(task, time) {
    if (time != null) task.time = time;
    time = task.time;
    var i;
    for (i = 0; i < this.tasks.length; i++) {
      if (this.tasks[i].time > time) break;
    }
    this.tasks.splice(0, i, task);
  },

  /* Cancel all tasks */
  clear: function() {
    this.tasks.splice(0, this.tasks.length);
  },

  /* OOP boilerplate */
  constructor: Scheduler
};

/* Create a Scheduler for animations */
Scheduler.makeAnimated = function(clock) {
  var ret = new Scheduler(requestAnimationFrame, null, clock);
  ret._type = "animated";
  return ret;
};

/* Create a Scheduler that polls tasks at regular intervals */
Scheduler.makeStrobe = function(fps, clock) {
  var delay = 1000.0 / fps;
  var ret = new Scheduler(function(cb) {
    setTimeout(cb, delay);
  }, null, clock);
  ret._type = "strobe";
  ret._fps = fps;
  return ret;
};

/* Prepare for serializing a Scheduler */
Scheduler.__save__ = function(sched) {
  var ret = {type: sched._type, tasks: sched.tasks, clock: sched.clock,
             running: sched.running};
  if (sched._type == "strobe") {
    ret.fps = sched._fps;
  } else if (sched._type != "animated") {
    throw new Error("Scheduler not serializable!");
  }
  return ret;
};

/* Deserialize a Scheduler */
Scheduler.__restore__ = function(data) {
  var ret;
  if (data.type == "animated") {
    ret = Scheduler.makeAnimated(data.clock);
  } else if (data.type == "strobe") {
    ret = Scheduler.makeStrobe(data.fps, data.clock);
  }
  ret.tasks = data.tasks;
  ret.running = data.running;
  return ret;
};

/* *** Serialization ***
 * Serializes object trees (!) into JSON strings, allowing reified objects to
 * be of the correct type, to hook their (de)serialization process.
 * Input containing enumerable function properties is rejected (since those
 * are silently swallowed by JSON); use hooks to meaningfully handle them. */

/* Serialize an object tree to JSON, storing type information */
function serialize(obj) {
  return JSON.stringify(obj, function(name, value) {
    /* Fail verbosely */
    if (typeof value == "function")
      throw new Error("Cannot serialize function");
    /* Only transform object values */
    if (typeof value != "object" || Array.isArray(value)) return value;
    /* Get a meaningful constructor name */
    var cons = value.constructor.__sername__;
    if (! cons) cons = value.constructor.name;
    if (! cons) cons = Object.prototype.toString(value).slice(8, -1);
    if (cons == "Object") cons = undefined;
    /* Copy properties into new object, or let object serialize itself */
    var ret;
    if (value.constructor.__save__) {
      ret = value.constructor.__save__(value);
    } else {
      ret = {};
      for (var prop in value) ret[prop] = value[prop];
    }
    /* Add __type__ */
    ret.__type__ = cons;
    /* Done */
    return ret;
  });
}

/* Deserialize a JSON string into an object structure */
function deserialize(obj) {
  return JSON.parse(obj, function(name, value) {
    /* Ignore non-objects */
    if (typeof value != "object" || Array.isArray(value)) return value;
    /* Check for a __type__ */
    if (value.__type__) {
      /* Obtain type object */
      var type = window[value.__type__];
      if (type && type.__restore__) {
        /* Use restorer function */
        value = type.__restore__(value);
      } else if (type) {
        /* Assume an object is deserializable as-is */
        var newVal = Object.create(type.prototype);
        for (var k in value) if (! /^__.+__$/.test(k)) newVal[k] = value[k];
        value = newVal;
      } else {
        /* Nope */
        throw new Error("Object not deserializable (cannot find type): " +
                        JSON.stringify(value));
      }
    }
    return value;
  });
}
<commit_msg>Allow specifying a custom deserialization environment<commit_after>
/* Dasca, an idle game by @CylonicRaider (github.com/CylonicRaider/dasca)
 * Abstract engine for JS-based idle games */

'use strict';

/* *** Clock ***
 * An object allowing to sample "time" (as defined by an external source)
 * with a linear transform in place. */

/* Construct a new clock
 * source is a function that, when called, returns the current time; scale
 * and offset modify source's output in a linear fashion: the reading of
 * source is multiplied by scale and offset is added to that to obtain the
 * current time. If scale is undefined or null, it defaults to 1; if offset
 * is null, it is computed such that the clock starts counting from zero. */
function Clock(source, scale, offset) {
  if (scale == null) scale = 1.0;
  if (offset == null) offset = -source() * scale;
  this.source = source;
  this.scale = scale;
  this.offset = offset;
}

Clock.prototype = {
  /* Sample the current time */
  now: function() {
    return this.source() * this.scale + this.offset;
  },

  /* Construct a new clock from this one, applying the given transformation
   * The new clock derives its time from the same (!) source as this one,
   * but its scale and offset are modified to simulate a clock constructed
   * like
   *     new Clock(this, scale, offset);
   */
  derive: function(scale, offset) {
    if (scale == null) scale = 1.0;
    if (offset != null) offset = this.offset * scale + offset;
    var ret = new Clock(this.source, this.scale * scale, offset);
    if (this._realTime) ret._realTime = true;
    return ret;
  },

  /* Serialization boilerplate */
  constructor: Clock
};

/* Construct a clock that returns (optionally scaled) real time
 * The clock counts from zero */
Clock.realTime = function(scale, start) {
  if (scale == null) scale = 1.0;
  scale *= 1e-3;
  var offset = (start == null) ? null : start - performance.now() * scale;
  var ret = new Clock(performance.now.bind(performance), scale, offset);
  ret._realTime = true;
  return ret;
};

/* Seralize a Clock */
Clock.__save__ = function(clock) {
  if (! clock._realTime) throw new Error("Clock not serializable!");
  return {scale: clock.scale * 1e3, time: clock.now()};
};

/* Deserialize a Clock */
Clock.__restore__ = function(data) {
  return Clock.realTime(data.scale, data.time);
};

/* *** Scheduler ***
 * Schedules call-backs to happen at certain times as defined by a Clock
 * instance. */

/* Construct a new scheduler
 * requeue is a funtion that somehow ("magically") ensures the function
 * to it is asynchronously called again some short time later; tasks is an
 * ordered array of objects whose "time" property is used to determine when
 * they are to run; clock is a Clock instance determining the time this
 * instance works with. The "running" property is set to true; it can be used
 * to stop the Scheduler.
 * To start it, ensure the "running" property is true and call the run()
 * method. */
function Scheduler(requeue, tasks, clock) {
  if (tasks == null) tasks = [];
  if (clock == null) clock = Clock.realTime();
  this.requeue = requeue;
  this.tasks = tasks;
  this.clock = clock;
  this.running = true;
}

Scheduler.prototype = {
  /* Queue the next run of the scheduler, and perform any tasks whose time
   * has come
   * After obtaining a timestamp from the clock, all tasks whose time
   * property is not less than the timestamp are removed from the queue and
   * run using runTask(); after that, if the "running" property is true,
   * requeue is called with a bound version of this.run as only argument to
   * trigger another execution. */
  run: function() {
    /* Abort if not running */
    if (! this.running) return;
    /* Obtain current timestamp */
    var now = this.clock.now();
    /* For each task that is (over)due */
    while (this.tasks[0] && this.tasks[0].time <= now) {
      /* Run it */
      this.runTask(this.tasks.shift(), now);
    }
    /* Schedule next iteration */
    this.requeue(this.run.bind(this));
  },

  /* Run a singular task, providing the given timestamp
   * The default implementation calls the task's "cb" (which is assumed to be
   * a function) with the value of now and the Scheduler instance as
   * arguments, and consumes exceptions by logging them to the console. */
  runTask: function(task, now) {
    try {
      task.cb(now, this);
    } catch (e) {
      console.error(e);
    }
  },

  /* Schedule a task to be run
   * If time is not null, it is inserted into task as the "time" property;
   * after that, the task is inserted at an appropriate position. */
  addTask: function(task, time) {
    if (time != null) task.time = time;
    time = task.time;
    var i;
    for (i = 0; i < this.tasks.length; i++) {
      if (this.tasks[i].time > time) break;
    }
    this.tasks.splice(0, i, task);
  },

  /* Cancel all tasks */
  clear: function() {
    this.tasks.splice(0, this.tasks.length);
  },

  /* OOP boilerplate */
  constructor: Scheduler
};

/* Create a Scheduler for animations */
Scheduler.makeAnimated = function(clock) {
  var ret = new Scheduler(requestAnimationFrame, null, clock);
  ret._type = "animated";
  return ret;
};

/* Create a Scheduler that polls tasks at regular intervals */
Scheduler.makeStrobe = function(fps, clock) {
  var delay = 1000.0 / fps;
  var ret = new Scheduler(function(cb) {
    setTimeout(cb, delay);
  }, null, clock);
  ret._type = "strobe";
  ret._fps = fps;
  return ret;
};

/* Prepare for serializing a Scheduler */
Scheduler.__save__ = function(sched) {
  var ret = {type: sched._type, tasks: sched.tasks, clock: sched.clock,
             running: sched.running};
  if (sched._type == "strobe") {
    ret.fps = sched._fps;
  } else if (sched._type != "animated") {
    throw new Error("Scheduler not serializable!");
  }
  return ret;
};

/* Deserialize a Scheduler */
Scheduler.__restore__ = function(data) {
  var ret;
  if (data.type == "animated") {
    ret = Scheduler.makeAnimated(data.clock);
  } else if (data.type == "strobe") {
    ret = Scheduler.makeStrobe(data.fps, data.clock);
  }
  ret.tasks = data.tasks;
  ret.running = data.running;
  return ret;
};

/* *** Serialization ***
 * Serializes object trees (!) into JSON strings, allowing reified objects to
 * be of the correct type, to hook their (de)serialization process.
 * Input containing enumerable function properties is rejected (since those
 * are silently swallowed by JSON); use hooks to meaningfully handle them. */

/* Serialize an object tree to JSON, storing type information */
function serialize(obj) {
  return JSON.stringify(obj, function(name, value) {
    /* Fail verbosely */
    if (typeof value == "function")
      throw new Error("Cannot serialize function");
    /* Only transform object values */
    if (typeof value != "object" || Array.isArray(value)) return value;
    /* Get a meaningful constructor name */
    var cons = value.constructor.__sername__;
    if (! cons) cons = value.constructor.name;
    if (! cons) cons = Object.prototype.toString(value).slice(8, -1);
    if (cons == "Object") cons = undefined;
    /* Copy properties into new object, or let object serialize itself */
    var ret;
    if (value.constructor.__save__) {
      ret = value.constructor.__save__(value);
    } else {
      ret = {};
      for (var prop in value) ret[prop] = value[prop];
    }
    /* Add __type__ */
    ret.__type__ = cons;
    /* Done */
    return ret;
  });
}

/* Deserialize a JSON string into an object structure */
function deserialize(obj, env) {
  if (env == null) env = window;
  return JSON.parse(obj, function(name, value) {
    /* Ignore non-objects */
    if (typeof value != "object" || Array.isArray(value)) return value;
    /* Check for a __type__ */
    if (value.__type__) {
      /* Obtain type object */
      var type = env[value.__type__];
      if (type && type.__restore__) {
        /* Use restorer function */
        value = type.__restore__(value);
      } else if (type) {
        /* Assume an object is deserializable as-is */
        var newVal = Object.create(type.prototype);
        for (var k in value) if (! /^__.+__$/.test(k)) newVal[k] = value[k];
        value = newVal;
      } else {
        /* Nope */
        throw new Error("Object not deserializable (cannot find type): " +
                        JSON.stringify(value));
      }
    }
    return value;
  });
}
<|endoftext|>


<commit_before>var responsiveCal;
(function() {
   if (typeof(responsiveCal)!=='undefined') return;
   var heredoc = function (f) {
      return f.toString().match(/\/\*\s*([\s\S]*?)\s*\*\//m)[1];
   };
   var lut = []; for (var il=0; il<256; il++) { lut[il] = (il<16?'0':'')+(il).toString(16); }
   var uuid = function() {
      var d0 = Math.random()*0xffffffff|0;
      var d1 = Math.random()*0xffffffff|0;
      var d2 = Math.random()*0xffffffff|0;
      var d3 = Math.random()*0xffffffff|0;
      return lut[d0&0xff]+lut[d0>>8&0xff]+lut[d0>>16&0xff]+lut[d0>>24&0xff]+'-'+
        lut[d1&0xff]+lut[d1>>8&0xff]+'-'+lut[d1>>16&0x0f|0x40]+lut[d1>>24&0xff]+'-'+
        lut[d2&0x3f|0x80]+lut[d2>>8&0xff]+'-'+lut[d2>>16&0xff]+lut[d2>>24&0xff]+
        lut[d3&0xff]+lut[d3>>8&0xff]+lut[d3>>16&0xff]+lut[d3>>24&0xff];
    };

   var calTmplHtml = heredoc(function(){/*

*/});

   responsiveCal = function(config) {
      var param = {
            reqMoment : moment(),
            wrapTarget : '.mcal-wrap',
            monthWrapTarget : '.mcal-wrap .mcal',
            calTmplId : 'rescal-tmpl-'+uuid(),
      };

      if (typeof(config)==='object') {
         for (var p in param) {
            if (typeof(config[p])!=='undefined') {
               param[p]=config[p];
            }
         }
         delete p;
      }
      var calTmplTarget = '#'+param.calTmplId;

      if (!$(calTmplTarget).length) {
         $('body').append(calTmplHtml.replace(/{calTmplId}/g,param.calTmplId));
      }

      var genMonth = function() {
         $(param.monthWrapTarget).empty();

         var startDOW=1;
         var endDOW=0;
         var selDay=param.reqMoment.dayOfYear();

         var reqMonth=param.reqMoment.format('M');

         var calStartMom = moment(reqMonth,'M');

         // Clone the value before .endOf()
         var calEndMom = moment(calStartMom).endOf('month').add(-1,'day');

         var curMoment=calStartMom;

         for(;;) {
            if (curMoment.format('e')==startDOW) {
               break;
            }
            curMoment.add(-1,'day');
         }

         for(;;) {
            if (calEndMom.format('e')==endDOW) {
               break;
            }
            calEndMom.add(1,'day');
         }

         var curW;
         var weekUI;

         for(;;) {
            /*
             * do stuff...
             */
            if (curMoment.format('e')==startDOW) {
               curW = curMoment.format('W');
               if (weekUI) {
                  $(param.monthWrapTarget).append(weekUI);
               }
               weekUI = $(calTmplTarget+' [data-tmpl="week"]').clone().attr('data-weekno',curW);
            }
            var dayUI = $(calTmplTarget+' [data-tmpl="day"]').clone();

            dayUI.attr('data-dayofmonth',curMoment.format('D'));
            dayUI.attr('data-year',curMoment.format('Y'));
            dayUI.attr('data-month',curMoment.format('M'));

            //data-formatdate="DD"
            dayUI.find('[data-formatdate]').each(function() {
               var f=$(this).data('formatdate');
               $(this).text(curMoment.format(f));
            });

            if (curMoment.format('M')!=reqMonth) {
               dayUI.addClass(dayUI.data('othermonthclass'));
               //console.log('not req month: '+curMoment.toISOString());
            }
            if (curMoment.dayOfYear()==selDay) {
               dayUI.find('[data-seldayclass]').each(function() {
                  $(this).addClass($(this).data('seldayclass'));
               });
               if (dayUI.data('seldayclass')) {
                  dayUI.addClass(dayUI.data('seldayclass'));
               }
            }

            dayUI.appendTo(weekUI);
            /*
             * advance and check if end of calendar
             */

            if (curMoment.format('YYYYMMDD')==calEndMom.format('YYYYMMDD')) {
               //console.log('found end: '+curMoment.toISOString());
               $(param.monthWrapTarget).append(weekUI);
               break;
            }
            curMoment.add(1,'day');
         }/*end for(;;) loop to generate 'mcal' for specified month*/
         $(param.wrapTarget).find('[data-month-formatdate]').each(function() {
            //console.log($(this).data('monthFormatdate'));

            $(this).text(param.reqMoment.format($(this).data('monthFormatdate')));
         });
      };/*end genMonth()*/

      return {
         'generate' : function(config) {
            if (typeof config === 'string' || config instanceof String) {
               if (config=='month') {
                  return genMonth();
               }
            }
         },
      };
   };
})();<commit_msg>fix bug when generating for other than present year<commit_after>var responsiveCal;
(function() {
   if (typeof(responsiveCal)!=='undefined') return;
   var heredoc = function (f) {
      return f.toString().match(/\/\*\s*([\s\S]*?)\s*\*\//m)[1];
   };
   var lut = []; for (var il=0; il<256; il++) { lut[il] = (il<16?'0':'')+(il).toString(16); }
   var uuid = function() {
      var d0 = Math.random()*0xffffffff|0;
      var d1 = Math.random()*0xffffffff|0;
      var d2 = Math.random()*0xffffffff|0;
      var d3 = Math.random()*0xffffffff|0;
      return lut[d0&0xff]+lut[d0>>8&0xff]+lut[d0>>16&0xff]+lut[d0>>24&0xff]+'-'+
        lut[d1&0xff]+lut[d1>>8&0xff]+'-'+lut[d1>>16&0x0f|0x40]+lut[d1>>24&0xff]+'-'+
        lut[d2&0x3f|0x80]+lut[d2>>8&0xff]+'-'+lut[d2>>16&0xff]+lut[d2>>24&0xff]+
        lut[d3&0xff]+lut[d3>>8&0xff]+lut[d3>>16&0xff]+lut[d3>>24&0xff];
    };

   var calTmplHtml = heredoc(function(){/*

*/});

   responsiveCal = function(config) {
      var param = {
            reqMoment : moment(),
            wrapTarget : '.mcal-wrap',
            monthWrapTarget : '.mcal-wrap .mcal',
            calTmplId : 'rescal-tmpl-'+uuid(),
      };

      if (typeof(config)==='object') {
         for (var p in param) {
            if (typeof(config[p])!=='undefined') {
               param[p]=config[p];
            }
         }
         delete p;
      }
      var calTmplTarget = '#'+param.calTmplId;

      if (!$(calTmplTarget).length) {
         $('body').append(calTmplHtml.replace(/{calTmplId}/g,param.calTmplId));
      }

      var genMonth = function() {
         $(param.monthWrapTarget).empty();

         var startDOW=1;
         var endDOW=0;
         var selDay=param.reqMoment.dayOfYear();

         var reqMonth=param.reqMoment.format('M');

         var calStartMom = moment(param.reqMoment.format('YYYY-M'),'YYYY-M');

         // Clone the value before .endOf()
         var calEndMom = moment(calStartMom).endOf('month').add(-1,'day');

         var curMoment=calStartMom;

         for(;;) {
            if (curMoment.format('e')==startDOW) {
               break;
            }
            curMoment.add(-1,'day');
         }

         for(;;) {
            if (calEndMom.format('e')==endDOW) {
               break;
            }
            calEndMom.add(1,'day');
         }

         var curW;
         var weekUI;

         for(;;) {
            /*
             * do stuff...
             */
            if (curMoment.format('e')==startDOW) {
               curW = curMoment.format('W');
               if (weekUI) {
                  $(param.monthWrapTarget).append(weekUI);
               }
               weekUI = $(calTmplTarget+' [data-tmpl="week"]').clone().attr('data-weekno',curW);
            }
            var dayUI = $(calTmplTarget+' [data-tmpl="day"]').clone();

            dayUI.attr('data-dayofmonth',curMoment.format('D'));
            dayUI.attr('data-year',curMoment.format('Y'));
            dayUI.attr('data-month',curMoment.format('M'));

            //data-formatdate="DD"
            dayUI.find('[data-formatdate]').each(function() {
               var f=$(this).data('formatdate');
               $(this).text(curMoment.format(f));
            });

            if (curMoment.format('M')!=reqMonth) {
               dayUI.addClass(dayUI.data('othermonthclass'));
               //console.log('not req month: '+curMoment.toISOString());
            }
            if (curMoment.dayOfYear()==selDay) {
               dayUI.find('[data-seldayclass]').each(function() {
                  $(this).addClass($(this).data('seldayclass'));
               });
               if (dayUI.data('seldayclass')) {
                  dayUI.addClass(dayUI.data('seldayclass'));
               }
            }

            dayUI.appendTo(weekUI);
            /*
             * advance and check if end of calendar
             */

            if (curMoment.format('YYYYMMDD')==calEndMom.format('YYYYMMDD')) {
               //console.log('found end: '+curMoment.toISOString());
               $(param.monthWrapTarget).append(weekUI);
               break;
            }
            curMoment.add(1,'day');
         }/*end for(;;) loop to generate 'mcal' for specified month*/
         $(param.wrapTarget).find('[data-month-formatdate]').each(function() {
            //console.log($(this).data('monthFormatdate'));

            $(this).text(param.reqMoment.format($(this).data('monthFormatdate')));
         });
      };/*end genMonth()*/

      return {
         'generate' : function(config) {
            if (typeof config === 'string' || config instanceof String) {
               if (config=='month') {
                  return genMonth();
               }
            }
         },
      };
   };
})();<|endoftext|>


<commit_before>/**
 * iframify is a script that replaces a node with a dynamically generated iframe
 * verson of itself, including all its necessary styles to perform correctly.
 *
 * It can be useful when working with a styleguide displaying components, in
 * order to replicate element queries on a component level.
 *
 * For instance:
 *
 * var componentContainers = document.querySelectorAll('.styleguide-component-container')
 * Array.prototype.forEach.call(componentContainers, iframify)
 *
 * Demo:
 *
 * http://codepen.io/HugoGiraudel/pen/vGWpyr
 */

(function (global) {
  function assign (target, source) {
    if (Object.assign) {
      return Object.assign.apply(null, arguments)
    }

    var from;
    var to = Object(target);
    var symbols;

    for (var s = 1; s < arguments.length; s++) {
      from = Object(arguments[s]);

      for (var key in from) {
        if (hasOwnProperty.call(from, key)) to[key] = from[key];
      }
    }

    return to;
  }

  function matches(node, selector) {
    var fn = (node.matches || node.msMatchesSelector);
    return fn.call(node, selector)
  }

  /**
   * Check whether a CSS rule matters in regard to a node.
   *
   * @param {Node} node
   * @param {CSSStyleDeclaration} cssRule
   * @return {Boolean}
   */
  function shouldAddRule (node, cssRule) {
    if (cssRule.cssRules) { // @media rule
      for (var k = 0; k < cssRule.cssRules.length; k += 1) {
        if (matches(node, cssRule.cssRules[k].selectorText)) {
          return true;
        }
      }

      return false;
    }

    return node.matches(cssRule.selectorText);
  }

  /**
   * Get all the rules impacting a node as an object where the keys are the
   * rules, and the values are always `true`. Storing in an object instead of
   * a string or an array makes it possible to prevent duplicated rules without
   * having too much of a performance hit.
   *
   * @param  {Node} node
   * @return {Object} - Keys are rules, values are `true`
   */
  function getRulesImpactingNode (node) {
    var stylesheets = document.styleSheets;
    var object = {};

    for (var i = 0; i < stylesheets.length; i += 1) {
      var cssRules = stylesheets[i].cssRules || stylesheets[i].rules;
      if (!cssRules) continue;

      for (var j = 0; j < cssRules.length; j += 1) {
        if (shouldAddRule(node, cssRules[j])) {
          object[cssRules[j].cssText] = true;
        }
      }
    }

    return object;
  }

  /**
   * Get string representation of all the styles relevant to a root node and all
   * its children.
   *
   *
   * @param  {Node} rootNode
   * @return {String}
   */
  function getStylesForTree (rootNode) {
    var children = rootNode.querySelectorAll('*');
    var rules = Array.prototype.reduce.call(children, function (tree, child) {
      return assign({}, tree, getRulesImpactingNode(child));
    }, getRulesImpactingNode(rootNode));

    return Object.keys(rules).join('');
  }

  /**
   * Get the content for the iframified version of a node.
   * @param  {Node} node
   * @return {String}
   */
  function getIframeContentForNode (node, extraCSS) {
    return '<!doctype html>'
      + ''
      + ''
      + ''
      + (extraCSS ? '' : '')
      + ''
      + '' + node.innerHTML + ''
      + '';
  }

  /**
   * Get document height (stackoverflow.com/questions/1145850/)
   * @param  {Document} doc
   * @return {Number}
   */
  function getDocumentHeight (doc) {
    doc = doc || document;
    var body = doc.body;
    var html = doc.documentElement;

    return Math.max(
      body.scrollHeight, body.offsetHeight,
      html.clientHeight, html.scrollHeight, html.offsetHeight
    );
  }

  /**
   * Transform a collection of nodes into an iframe version of themselves
   * including all the styles they need to perform correctly.
   *
   * @param  {NodeList} nodes
   * @return undefined
   */
  function iframify (node, extraCSS) {
    var iframe = document.createElement('iframe');
    var html = getIframeContentForNode(node, extraCSS);
    iframe.srcdoc = html;
    iframe.src = 'data:text/html;charset=utf-8,' + encodeURI(html);
    node.parentNode.replaceChild(iframe, node);

    // If `srcdoc` is supported, there is no CORS issue therefore we can
    // dynamically resize iframe height. The setTimeout is there to make sure
    // that any asynchronously loaded content inside the component has been
    // safely loaded before computing the height.
    if ('srcdoc' in iframe) {
      setTimeout(function () {
        var iframeDocument = iframe.contentDocument || iframe.contentWindow.document;
        iframe.height = getDocumentHeight(iframeDocument);
      }, 500);
    }
  }

  global.iframify = iframify;

}(window))
<commit_msg>Made the code semistandard compliant<commit_after>/**
 * iframify is a script that replaces a node with a dynamically generated iframe
 * verson of itself, including all its necessary styles to perform correctly.
 *
 * It can be useful when working with a styleguide displaying components, in
 * order to replicate element queries on a component level.
 *
 * For instance:
 *
 * var componentContainers = document.querySelectorAll('.styleguide-component-container')
 * Array.prototype.forEach.call(componentContainers, iframify)
 *
 * Demo:
 *
 * http://codepen.io/HugoGiraudel/pen/vGWpyr
 */

(function (global) {
  function assign (target, source) {
    if (Object.assign) {
      return Object.assign.apply(null, arguments);
    }

    var from;
    var to = Object(target);

    for (var s = 1; s < arguments.length; s++) {
      from = Object(arguments[s]);

      for (var key in from) {
        if (hasOwnProperty.call(from, key)) to[key] = from[key];
      }
    }

    return to;
  }

  function matches (node, selector) {
    var fn = (node.matches || node.msMatchesSelector);
    return fn.call(node, selector);
  }

  /**
   * Check whether a CSS rule matters in regard to a node.
   *
   * @param {Node} node
   * @param {CSSStyleDeclaration} cssRule
   * @return {Boolean}
   */
  function shouldAddRule (node, cssRule) {
    if (cssRule.cssRules) { // @media rule
      for (var k = 0; k < cssRule.cssRules.length; k += 1) {
        if (matches(node, cssRule.cssRules[k].selectorText)) {
          return true;
        }
      }

      return false;
    }

    return node.matches(cssRule.selectorText);
  }

  /**
   * Get all the rules impacting a node as an object where the keys are the
   * rules, and the values are always `true`. Storing in an object instead of
   * a string or an array makes it possible to prevent duplicated rules without
   * having too much of a performance hit.
   *
   * @param  {Node} node
   * @return {Object} - Keys are rules, values are `true`
   */
  function getRulesImpactingNode (node) {
    var stylesheets = document.styleSheets;
    var object = {};

    for (var i = 0; i < stylesheets.length; i += 1) {
      var cssRules = stylesheets[i].cssRules || stylesheets[i].rules;
      if (!cssRules) continue;

      for (var j = 0; j < cssRules.length; j += 1) {
        if (shouldAddRule(node, cssRules[j])) {
          object[cssRules[j].cssText] = true;
        }
      }
    }

    return object;
  }

  /**
   * Get string representation of all the styles relevant to a root node and all
   * its children.
   *
   * @param  {Node} rootNode
   * @return {String}
   */
  function getStylesForTree (rootNode) {
    var children = rootNode.querySelectorAll('*');
    var rules = Array.prototype.reduce.call(children, function (tree, child) {
      return assign({}, tree, getRulesImpactingNode(child));
    }, getRulesImpactingNode(rootNode));

    return Object.keys(rules).join('');
  }

  /**
   * Get the content for the iframified version of a node.
   *
   * @param  {Node} node
   * @return {String}
   */
  function getIframeContentForNode (node, extraCSS) {
    return '<!doctype html>' +
      '' +
      '' +
      '' +
      (extraCSS ? '' : '') +
      '' +
      '' + node.innerHTML + '' +
      '';
  }

  /**
   * Get document height (stackoverflow.com/questions/1145850/)
   *
   * @param  {Document} doc
   * @return {Number}
   */
  function getDocumentHeight (doc) {
    doc = doc || document;
    var body = doc.body;
    var html = doc.documentElement;

    return Math.max(
      body.scrollHeight, body.offsetHeight,
      html.clientHeight, html.scrollHeight, html.offsetHeight
    );
  }

  /**
   * Transform a collection of nodes into an iframe version of themselves
   * including all the styles they need to perform correctly.
   *
   * @param  {NodeList} nodes
   * @return undefined
   */
  function iframify (node, extraCSS) {
    var iframe = document.createElement('iframe');
    var html = getIframeContentForNode(node, extraCSS);
    iframe.srcdoc = html;
    iframe.src = 'data:text/html;charset=utf-8,' + encodeURI(html);
    node.parentNode.replaceChild(iframe, node);

    // If `srcdoc` is supported, there is no CORS issue therefore we can
    // dynamically resize iframe height. The setTimeout is there to make sure
    // that any asynchronously loaded content inside the component has been
    // safely loaded before computing the height.
    if ('srcdoc' in iframe) {
      setTimeout(function () {
        var iframeDocument = iframe.contentDocument || iframe.contentWindow.document;
        iframe.height = getDocumentHeight(iframeDocument);
      }, 500);
    }
  }

  global.iframify = iframify;
}(window));
<|endoftext|>


<commit_before>// Chris Samuel
// ksamuel.chris@gmail.com
/*
JavaSCript uses lexical scoping which  means thats function are executed using
the variable scope that is in effect when they are invoked. All JavaScript functions
are closures:

they are objects and they have a scope chain associated with them.

Github: alayode

*/

var ARMORY = (function(){
  var weaponList =  [ 'Excalibur','Ice Brand','Ragnarok','Save the Queen' ];
  var armorList  =  [ 'Rainbow Cloak','Doublet','Lizard Jerkin','Chain Mail' ];

  var removeWeapon = function(){
    //revmove weapon from the armory
  };
  var replaceWeapon = function(){
    //add a weapon to the weaponList
  };
  var removeArmor = function(){
    //remove a weapons from the armorList
  };
  var replaceArmor = function(){
    //add armor to the armorList
  };

  return{
    makeWeaponRequest: function(){
    //create a object that would be accessible to the global scope.
    };
    makeArmorRequest: function(){
      // create a object that also be available to the global scope once the function is called.
    };
  };
})();
<commit_msg>test makeWeaponRequest request function with console log<commit_after>// Chris Samuel
// ksamuel.chris@gmail.com
/*
JavaSCript uses lexical scoping which  means thats function are executed using
the variable scope that is in effect when they are invoked. All JavaScript functions
are closures:

they are objects and they have a scope chain associated with them.

Github: alayode

*/

var ARMORY = (function(){
  var weaponList =  [ 'Excalibur','Ice Brand','Ragnarok','Save the Queen' ];
  var armorList  =  [ 'Rainbow Cloak','Doublet','Lizard Jerkin','Chain Mail' ];

  var removeWeapon = function(){
    //revmove weapon from the armory
  };
  var replaceWeapon = function(){
    //add a weapon to the weaponList
  };
  var removeArmor = function(){
    //remove a weapons from the armorList
  };
  var replaceArmor = function(){
    //add armor to the armorList
  };

  return{
    makeWeaponRequest: function(){
    //create a object that would be accessible to the global scope.
    console.log('Weapon Request Acknowledge!');
  },
    makeArmorRequest: function(){
      // create a object that also be available to the global scope once the function is called.
    }
  };
})();
<|endoftext|>


<commit_before><commit_msg>fix path to unbreak build<commit_after><|endoftext|>


<commit_before>/**
 * Grid of metabolites.
 * @author Stefan Verhoeven
 */
Ext.define('Esc.magmaweb.view.metabolite.List', {
  extend: 'Ext.grid.Panel',
  alias: 'widget.metabolitelist',
  requires: [
    'Ext.ux.grid.FiltersFeature', 'Esc.chemdoodle.Column',
    'Ext.toolbar.Paging', 'Ext.grid.column.Boolean',
    'Ext.grid.column.Action', 'Ext.selection.CheckboxModel'
  ],
  store: 'Metabolites',
  viewConfig: {
    emptyText: 'No structures available: Add structures or relax filters'
  },
  selType: 'checkboxmodel',
  selModel: {
    allowDeselect: true,
    mode: 'SINGLE',
    showHeaderCheckbox: false
  },
  dockedItems: [{
    xtype: 'pagingtoolbar',
    store: 'Metabolites',   // same store GridPanel is using
    dock: 'bottom',
    displayInfo: true,
    items: [{
      xtype: 'combo',
      width: 170,
      store: [
        [10, '10 molecules per page'],
        [25, '25 molecules per page'],
        [50, '50 molecules per page'],
        [100, '100 molecules per page'],
        [250, '250 molecules per page'],
        [500, '500 molecules per page'],
        [1000, '1000 molecules per page']
      ],
      forceSelection: true,
      triggerAction: 'all',
      action: 'pagesize'
    }]
  }],
  initComponent: function() {
    console.log('Init met grid');
    var me = this;
    var molcol = Ext.create('Esc.chemdoodle.Column', {
      text: 'Molecule', dataIndex: 'mol',
      width: 162,
      initCanvas: function(id, width, height, value, record) {
        var c = new ChemDoodle.ViewerCanvas(id, width, height);
        c.loadMolecule(ChemDoodle.readMOL(value));
        var tip = Ext.create('Ext.tip.ToolTip', {
          target: id,
          html: '<canvas id="'+id+'-tp"></canvas>',
          listeners: {
            render: function(tip) {
              var c = new ChemDoodle.ViewerCanvas(id+'-tp', 300, 300);
              c.loadMolecule(ChemDoodle.readMOL(value));
            }
          }
        });
      }
    });

    var mfilters = Ext.create('Ext.ux.grid.FiltersFeature',{
      id: 'mfilter',
      encode: true
    });

    this.addEvents([
        /**
         * @event metabolize
         * Fired after metabolize column action is clicked
         * @param {Ext.data.Model} record The record to metabolize
         */
        'metabolize'
    ]);

    Ext.apply(this, {
      columns: [
        {text: 'ID', dataIndex: 'metid', hidden: true},
        molcol,
        {text: 'Level', dataIndex: 'level', filter: { type: 'list',  options: ['0','1','2','3'] }, hidden:true},
        {text: 'Probability', dataIndex: 'probability', filter: { type: 'numeric' }},
        {text: 'Name', dataIndex: 'origin', flex:1, filter: { type: 'string' }},
        {text: 'Reaction sequence', dataIndex: 'reactionsequence', flex:1, filter: { type: 'string' }, renderer: function(v) {
          return '

'+v.replace("\n","

")+'

';
        }},
        {text: 'Scans', dataIndex: 'nhits', filter: {
            type: 'numeric', value:{gt:0}, active: true
        }},
        {text: 'Smiles', dataIndex: 'smiles', hidden:true},
        {text: 'Formula', dataIndex: 'molformula', filter: { type: 'string' }},
        {text: 'Monoisotopic mass', dataIndex: 'mim', filter: { type: 'numeric' }, hidden: false},
        {text: 'Query', dataIndex: 'isquery', xtype:'booleancolumn', hidden: true, trueText:'Yes', falseText:'No', filter: { type: 'boolean' }},
        {text: 'Candidate score', dataIndex: 'score', hidden: true, filter: { type: 'numeric' }},
        {text: 'ΔMass (ppm)', dataIndex: 'deltappm', hidden: true, filter: { type: 'numeric' }},
        {text: 'Assigned', dataIndex: 'assigned', hidden: false, xtype:'booleancolumn', trueText:'Yes', falseText:'No', filter: { type: 'boolean' }},
        {text: 'LogP', dataIndex: 'logp', filter: { type: 'numeric' }, hidden: true},
        {text: 'Reference', dataIndex: 'reference', filter: { type: 'string' }, sortable: false },
        {xtype: 'actioncolumn', width:30, text:'Commands',
            items: [{
                tooltip: 'Metabolize',
                iconCls: 'metabolize-col',
                handler: function(grid, rowIndex) {
                    me.fireEvent('metabolize', me.getStore().getAt(rowIndex));
                }
            }]
        }
      ],
      plugins: [molcol],
      features: [mfilters]
    });
    this.callParent(arguments);
  },
  /**
   * Clears all filters applied to metabolites
   */
  clearFilters: function() {
    this.getView().getFeature('mfilter').clearFilters();
  },
  /**
   * Get column with scores.
   *
   * Column should only be shown when a scan has been selected.
   *
   * @return {Ext.grid.column.Column}
   */
  getFragmentScoreColumn: function() {
      return this.columns.filter(function(c) { return (c.dataIndex == "score");})[0];
  },
  /**
   * Get column with deltappm.
   *
   * Column should only be shown when a scan has been selected.
   *
   * @return {Ext.grid.column.Column}
   */
  getFragmentDeltaPpmColumn: function() {
      return this.columns.filter(function(c) { return (c.dataIndex == "deltappm");})[0];
  },
  /**
   * Get column with commands.
   *
   * @return {Ext.grid.column.Action}
   */
  getCommandsColumn: function() {
      return this.columns.filter(function(c) { return (c.text == "Commands");})[0];
  },
  /**
   * Hides column with scores/deltappm and removes sort in header column.
   */
  hideFragmentScoreColumn: function() {
    var sortCls = [
        Ext.baseCSSPrefix + 'column-header-sort-ASC',
        Ext.baseCSSPrefix + 'column-header-sort-DESC'
    ];
    var score = this.getFragmentScoreColumn();
    score.hide();
    score.removeCls(sortCls);
    var deltappm = this.getFragmentDeltaPpmColumn()
    deltappm.hide();
    deltappm.removeCls(sortCls);
  },
  /**
   * Shows column with scores/deltappm.
   */
  showFragmentScoreColumn: function() {
    this.getFragmentScoreColumn().show();
    this.getFragmentDeltaPpmColumn().show();
  }
});
<commit_msg>The molecule canvas of the popup has an id. The popup is hidden when mouse is moved out or a delay passes. When the grid is changed and you mouse over a molecule the chemdoodle class gets the id of the canvas. There are now 2 canvases with the same id. So if you dont see a molecule in the popup it's been drawn in a hidden popup.<commit_after>/**
 * Grid of metabolites.
 * @author Stefan Verhoeven
 */
Ext.define('Esc.magmaweb.view.metabolite.List', {
  extend: 'Ext.grid.Panel',
  alias: 'widget.metabolitelist',
  requires: [
    'Ext.ux.grid.FiltersFeature', 'Esc.chemdoodle.Column',
    'Ext.toolbar.Paging', 'Ext.grid.column.Boolean',
    'Ext.grid.column.Action', 'Ext.selection.CheckboxModel'
  ],
  store: 'Metabolites',
  viewConfig: {
    emptyText: 'No structures available: Add structures or relax filters'
  },
  selType: 'checkboxmodel',
  selModel: {
    allowDeselect: true,
    mode: 'SINGLE',
    showHeaderCheckbox: false
  },
  dockedItems: [{
    xtype: 'pagingtoolbar',
    store: 'Metabolites',   // same store GridPanel is using
    dock: 'bottom',
    displayInfo: true,
    items: [{
      xtype: 'combo',
      width: 170,
      store: [
        [10, '10 molecules per page'],
        [25, '25 molecules per page'],
        [50, '50 molecules per page'],
        [100, '100 molecules per page'],
        [250, '250 molecules per page'],
        [500, '500 molecules per page'],
        [1000, '1000 molecules per page']
      ],
      forceSelection: true,
      triggerAction: 'all',
      action: 'pagesize'
    }]
  }],
  initComponent: function() {
    console.log('Init met grid');
    var me = this;
    var molcol = Ext.create('Esc.chemdoodle.Column', {
      text: 'Molecule', dataIndex: 'mol',
      width: 162,
      initCanvas: function(id, width, height, value, record) {
        var c = new ChemDoodle.ViewerCanvas(id, width, height);
        c.loadMolecule(ChemDoodle.readMOL(value));
        var tip = Ext.create('Ext.tip.ToolTip', {
          target: id,
          html: null,
          listeners: {
            render: function(tip) {
              var c = new ChemDoodle.ViewerCanvas(id+'-'+tip.id, 300, 300);
              c.loadMolecule(ChemDoodle.readMOL(value));
            }
          }
        });
        tip.update('<canvas id="'+id+'-'+tip.id+'"></canvas>');
      }
    });

    var mfilters = Ext.create('Ext.ux.grid.FiltersFeature',{
      id: 'mfilter',
      encode: true
    });

    this.addEvents([
        /**
         * @event metabolize
         * Fired after metabolize column action is clicked
         * @param {Ext.data.Model} record The record to metabolize
         */
        'metabolize'
    ]);

    Ext.apply(this, {
      columns: [
        {text: 'ID', dataIndex: 'metid', hidden: true},
        molcol,
        {text: 'Level', dataIndex: 'level', filter: { type: 'list',  options: ['0','1','2','3'] }, hidden:true},
        {text: 'Probability', dataIndex: 'probability', filter: { type: 'numeric' }},
        {text: 'Name', dataIndex: 'origin', flex:1, filter: { type: 'string' }},
        {text: 'Reaction sequence', dataIndex: 'reactionsequence', flex:1, filter: { type: 'string' }, renderer: function(v) {
          return '

'+v.replace("\n","

")+'

';
        }},
        {text: 'Scans', dataIndex: 'nhits', filter: {
            type: 'numeric', value:{gt:0}, active: true
        }},
        {text: 'Smiles', dataIndex: 'smiles', hidden:true},
        {text: 'Formula', dataIndex: 'molformula', filter: { type: 'string' }},
        {text: 'Monoisotopic mass', dataIndex: 'mim', filter: { type: 'numeric' }, hidden: false},
        {text: 'Query', dataIndex: 'isquery', xtype:'booleancolumn', hidden: true, trueText:'Yes', falseText:'No', filter: { type: 'boolean' }},
        {text: 'Candidate score', dataIndex: 'score', hidden: true, filter: { type: 'numeric' }},
        {text: 'ΔMass (ppm)', dataIndex: 'deltappm', hidden: true, filter: { type: 'numeric' }},
        {text: 'Assigned', dataIndex: 'assigned', hidden: false, xtype:'booleancolumn', trueText:'Yes', falseText:'No', filter: { type: 'boolean' }},
        {text: 'LogP', dataIndex: 'logp', filter: { type: 'numeric' }, hidden: true},
        {text: 'Reference', dataIndex: 'reference', filter: { type: 'string' }, sortable: false },
        {xtype: 'actioncolumn', width:30, text:'Commands',
            items: [{
                tooltip: 'Metabolize',
                iconCls: 'metabolize-col',
                handler: function(grid, rowIndex) {
                    me.fireEvent('metabolize', me.getStore().getAt(rowIndex));
                }
            }]
        }
      ],
      plugins: [molcol],
      features: [mfilters]
    });
    this.callParent(arguments);
  },
  /**
   * Clears all filters applied to metabolites
   */
  clearFilters: function() {
    this.getView().getFeature('mfilter').clearFilters();
  },
  /**
   * Get column with scores.
   *
   * Column should only be shown when a scan has been selected.
   *
   * @return {Ext.grid.column.Column}
   */
  getFragmentScoreColumn: function() {
      return this.columns.filter(function(c) { return (c.dataIndex == "score");})[0];
  },
  /**
   * Get column with deltappm.
   *
   * Column should only be shown when a scan has been selected.
   *
   * @return {Ext.grid.column.Column}
   */
  getFragmentDeltaPpmColumn: function() {
      return this.columns.filter(function(c) { return (c.dataIndex == "deltappm");})[0];
  },
  /**
   * Get column with commands.
   *
   * @return {Ext.grid.column.Action}
   */
  getCommandsColumn: function() {
      return this.columns.filter(function(c) { return (c.text == "Commands");})[0];
  },
  /**
   * Hides column with scores/deltappm and removes sort in header column.
   */
  hideFragmentScoreColumn: function() {
    var sortCls = [
        Ext.baseCSSPrefix + 'column-header-sort-ASC',
        Ext.baseCSSPrefix + 'column-header-sort-DESC'
    ];
    var score = this.getFragmentScoreColumn();
    score.hide();
    score.removeCls(sortCls);
    var deltappm = this.getFragmentDeltaPpmColumn()
    deltappm.hide();
    deltappm.removeCls(sortCls);
  },
  /**
   * Shows column with scores/deltappm.
   */
  showFragmentScoreColumn: function() {
    this.getFragmentScoreColumn().show();
    this.getFragmentDeltaPpmColumn().show();
  }
});
<|endoftext|>


<commit_before>goog.provide('ol.control.FullScreen');

goog.require('goog.asserts');
goog.require('goog.dom');
goog.require('goog.dom.TagName');
goog.require('goog.dom.classes');
goog.require('goog.dom.fullscreen');
goog.require('goog.dom.fullscreen.EventType');
goog.require('goog.events');
goog.require('goog.events.EventType');
goog.require('ol.control.Control');
goog.require('ol.css');

/**
 * Provides a button that when clicked fills up the full screen with the map.
 * When in full screen mode, a close button is shown to exit full screen mode.
 * The [Fullscreen API](http://www.w3.org/TR/fullscreen/) is used to
 * toggle the map in full screen mode.
 *
 *
 * @constructor
 * @extends {ol.control.Control}
 * @param {olx.control.FullScreenOptions=} opt_options Options.
 * @todo stability experimental
 */
ol.control.FullScreen = function(opt_options) {

  var options = goog.isDef(opt_options) ? opt_options : {};

  /**
   * @private
   * @type {string}
   */
  this.cssClassName_ = goog.isDef(options.className) ?
      options.className : 'ol-full-screen';

  var aElement = goog.dom.createDom(goog.dom.TagName.A, {
    'href': '#fullScreen',
    'class': this.cssClassName_ + '-' + goog.dom.fullscreen.isFullScreen()
  });
  goog.events.listen(aElement, [
    goog.events.EventType.CLICK,
    goog.events.EventType.TOUCHEND
  ], this.handleClick_, false, this);

  goog.events.listen(goog.global.document, goog.dom.fullscreen.EventType.CHANGE,
      this.handleFullScreenChange_, false, this);

  var element = goog.dom.createDom(goog.dom.TagName.DIV, {
    'class': this.cssClassName_ + ' ' + ol.css.CLASS_UNSELECTABLE + ' ' +
        (!goog.dom.fullscreen.isSupported() ? ol.css.CLASS_UNSUPPORTED : '')
  }, aElement);

  goog.base(this, {
    element: element,
    target: options.target
  });

  /**
   * @private
   * @type {boolean}
   */
  this.keys_ = goog.isDef(options.keys) ? options.keys : false;

};
goog.inherits(ol.control.FullScreen, ol.control.Control);

/**
 * @param {goog.events.BrowserEvent} browserEvent Browser event.
 * @private
 */
ol.control.FullScreen.prototype.handleClick_ = function(browserEvent) {
  if (!goog.dom.fullscreen.isSupported()) {
    return;
  }
  browserEvent.preventDefault();
  var map = this.getMap();
  if (goog.isNull(map)) {
    return;
  }
  if (goog.dom.fullscreen.isFullScreen()) {
    goog.dom.fullscreen.exitFullScreen();
  } else {
    var target = map.getTarget();
    goog.asserts.assert(goog.isDefAndNotNull(target));
    var element = goog.dom.getElement(target);
    goog.asserts.assert(goog.isDefAndNotNull(element));
    if (this.keys_) {
      goog.dom.fullscreen.requestFullScreenWithKeys(element);
    } else {
      goog.dom.fullscreen.requestFullScreen(element);
    }
  }
};

/**
 * @private
 */
ol.control.FullScreen.prototype.handleFullScreenChange_ = function() {
  var opened = this.cssClassName_ + '-true';
  var closed = this.cssClassName_ + '-false';
  var anchor = goog.dom.getFirstElementChild(this.element);
  if (goog.dom.fullscreen.isFullScreen()) {
    goog.dom.classes.swap(anchor, closed, opened);
  } else {
    goog.dom.classes.swap(anchor, opened, closed);
  }
};
<commit_msg>Prevent OSX Safari to display distorded map<commit_after>goog.provide('ol.control.FullScreen');

goog.require('goog.asserts');
goog.require('goog.dom');
goog.require('goog.dom.TagName');
goog.require('goog.dom.classes');
goog.require('goog.dom.fullscreen');
goog.require('goog.dom.fullscreen.EventType');
goog.require('goog.events');
goog.require('goog.events.EventType');
goog.require('ol.control.Control');
goog.require('ol.css');

/**
 * Provides a button that when clicked fills up the full screen with the map.
 * When in full screen mode, a close button is shown to exit full screen mode.
 * The [Fullscreen API](http://www.w3.org/TR/fullscreen/) is used to
 * toggle the map in full screen mode.
 *
 *
 * @constructor
 * @extends {ol.control.Control}
 * @param {olx.control.FullScreenOptions=} opt_options Options.
 * @todo stability experimental
 */
ol.control.FullScreen = function(opt_options) {

  var options = goog.isDef(opt_options) ? opt_options : {};

  /**
   * @private
   * @type {string}
   */
  this.cssClassName_ = goog.isDef(options.className) ?
      options.className : 'ol-full-screen';

  var aElement = goog.dom.createDom(goog.dom.TagName.A, {
    'href': '#fullScreen',
    'class': this.cssClassName_ + '-' + goog.dom.fullscreen.isFullScreen()
  });
  goog.events.listen(aElement, [
    goog.events.EventType.CLICK,
    goog.events.EventType.TOUCHEND
  ], this.handleClick_, false, this);

  goog.events.listen(goog.global.document, goog.dom.fullscreen.EventType.CHANGE,
      this.handleFullScreenChange_, false, this);

  var element = goog.dom.createDom(goog.dom.TagName.DIV, {
    'class': this.cssClassName_ + ' ' + ol.css.CLASS_UNSELECTABLE + ' ' +
        (!goog.dom.fullscreen.isSupported() ? ol.css.CLASS_UNSUPPORTED : '')
  }, aElement);

  goog.base(this, {
    element: element,
    target: options.target
  });

  /**
   * @private
   * @type {boolean}
   */
  this.keys_ = goog.isDef(options.keys) ? options.keys : false;

};
goog.inherits(ol.control.FullScreen, ol.control.Control);

/**
 * @param {goog.events.BrowserEvent} browserEvent Browser event.
 * @private
 */
ol.control.FullScreen.prototype.handleClick_ = function(browserEvent) {
  if (!goog.dom.fullscreen.isSupported()) {
    return;
  }
  browserEvent.preventDefault();
  var map = this.getMap();
  if (goog.isNull(map)) {
    return;
  }
  if (goog.dom.fullscreen.isFullScreen()) {
    goog.dom.fullscreen.exitFullScreen();
  } else {
    var target = map.getTarget();
    goog.asserts.assert(goog.isDefAndNotNull(target));
    var element = goog.dom.getElement(target);
    goog.asserts.assert(goog.isDefAndNotNull(element));
    if (this.keys_) {
      goog.dom.fullscreen.requestFullScreenWithKeys(element);
    } else {
      goog.dom.fullscreen.requestFullScreen(element);
    }
  }
};

/**
 * @private
 */
ol.control.FullScreen.prototype.handleFullScreenChange_ = function() {
  var opened = this.cssClassName_ + '-true';
  var closed = this.cssClassName_ + '-false';
  var anchor = goog.dom.getFirstElementChild(this.element);
  var map = this.getMap();
  if (goog.dom.fullscreen.isFullScreen()) {
    goog.dom.classes.swap(anchor, closed, opened);
  } else {
    goog.dom.classes.swap(anchor, opened, closed);
  }
  if (!goog.isNull(map)) {
    map.updateSize();
  }
};
<|endoftext|>