<commit_before>var React = require('react');

var Section = require('grommet/components/Section');
var Table = require('grommet/components/Table');
var Form = require('grommet/components/Form');
var FormField = require('grommet/components/FormField');
var CheckBox = require('grommet/components/CheckBox');

var SG_PROPERTIES = {
  type: "number",
  min: "0",
  step: ".001"
};

// nutrient provides ppm per g/L
var nutrients = {
  fermaid_O: {
    organic: 65,
    inorganic: 0
  },
  dap: {
    organic: 0,
    inorganic: 210
  }
};

var YANCalculator = React.createClass({

  getInitialState: function() {
    return {
      final_gravity: 0.997,
      original_gravity: 1.100,
      gravity_units: 'sg',
      volume: 20,
      volume_units: 'liter',
      target_yan: 250,
      // target_yan_units: PPM
      organic_ratio: 35,

      // TODO convert split to generic
      // TODO make split editable...
      steps: [{
        name: 'At Mix',
        when: 0,
        allow_DAP: false,
        dap_split: 0,
        fermaid_O_split: 40
      },{
        name: 'End of Lag',
        when: 0,
        dap_split: 50,
        fermaid_O_split: 20
      },{
        name: '1/6 Sugar Break',
        when: 1/6,
        dap_split: 40,
        fermaid_O_split: 20
      },{
        name: '1/3 Sugar Break',
        when: 1/3,
        dap_split: 10,
        fermaid_O_split: 20
      },{
        total: true,
        name: 'TOTAL',
        dap_split: null,
        fermaid_O_split: null
      }]
      //TODO other properties to do later
      // types of nutrients
      // organic/inorganic ration
      // how many additions

    };
  },

  _onFormSubmit: function(event) {
    event.preventDefault();
  },

  _onChangeCheckBox:function(event) {
    var change = {};
    change[event.target.id] = event.target.checked;
    this.setState(change);
  },

  _onChange: function(event) {
    var change = {};
    change[event.target.id] = event.target.value;
    this.setState(change);
  },

  renderTable: function() {
    var headers = [Nutrient	];
    var total = {
      fermaid_O_split : 0,
      dap_split : 0
    };
    for (var i = this.state.steps.length - 1; i >= 0; i--) {
      total.fermaid_O_split+=this.state.steps[i].fermaid_O_split;
      total.dap_split+=this.state.steps[i].dap_split;
    };
    var total_gravity_points = this.state.original_gravity - this.state.final_gravity;
    var body = {
      gravity: [At Gravity (sg)	],
      fermaid_O_split: [Fermaid O (%)	],
      fermaid_O: [Fermaid O (g)	],
      fermaid_O_YAN: [Fermaid O YAN (ppm)	],
      blank_row: [	],
      dap_split: [DAP (%)	],
      dap: [DAP (g)	],
      dap_YAN: [DAP YAN (ppm)	]
    };
    var simple=['gravity', 'fermaid_O', 'dap'];
    var total_yan = {
      dap: this.state.target_yan * ((100 - this.state.organic_ratio)/100),
      fermaid_O: this.state.target_yan * (this.state.organic_ratio/100)
    };

    for (var i = 0; i < this.state.steps.length; i++) {
      var step = this.state.steps[i];
      headers.push({step.name}	);

      //percentages
      if (!step.total) {
        //TODO do some abstractions
        body.fermaid_O_split.push({(step.fermaid_O_split/total.fermaid_O_split*100).toFixed(2)+'%'}	);
        body.dap_split.push({(step.dap_split/total.dap_split*100).toFixed(2)+'%'}	);

        var dap_YAN = total_yan.dap*step.dap_split/100;
        var fermaid_YAN = total_yan.fermaid_O*step.fermaid_O_split/100;

        body.dap_YAN.push({(dap_YAN).toFixed(2)}	);
        body.dap.push({(dap_YAN*this.state.volume/nutrients.dap.inorganic).toFixed(2)}	);

        body.fermaid_O_YAN.push({(fermaid_YAN).toFixed(2)}	);
        body.fermaid_O.push({(fermaid_YAN*this.state.volume/nutrients.fermaid_O.organic).toFixed(2)}	);

        //TODO round properly
        body.gravity.push({(this.state.original_gravity - (total_gravity_points * step.when)).toFixed(3)}	);
      } else {
        body.fermaid_O_split.push({'100%'}	);
        body.dap_split.push({'100%'}	);

        body.dap_YAN.push({total_yan.dap}	);
        body.dap.push({(total_yan.dap*this.state.volume/nutrients.dap.inorganic).toFixed(2)}	);

        body.fermaid_O_YAN.push({total_yan.fermaid_O}	);
        body.fermaid_O.push({(total_yan.fermaid_O*this.state.volume/nutrients.fermaid_O.organic).toFixed(2)}	);

        body.gravity.push(N/A	);
      }

      // gravities

    };
    var renderedBody =[];
    for (var part in body) {
      if (simple.indexOf(part) !== -1 || this.state.details) {
        renderedBody.push(
{body[part]}
);
      }
    }
    return (

            {headers}

        {renderedBody}

    );
  },

  renderForm: function() {
    return (
      <Form onSubmit={this._onFormSubmit}>
        <FormField label="Volume (liters)" htmlFor="volume" >
          <input id="volume" type="number" onChange={this._onChange} value={this.state.volume}/>
        </FormField>
        <FormField label="Original Gravity (sg)" htmlFor="original_gravity" >
          <input id="original_gravity" {...SG_PROPERTIES} onChange={this._onChange} value={this.state.original_gravity}/>
        </FormField>
        <FormField label="Final Gravity (sg)" htmlFor="final_gravity" >
          <input id="final_gravity" {...SG_PROPERTIES} onChange={this._onChange} value={this.state.final_gravity}/>
        </FormField>
        <FormField label="YAN (ppm)" htmlFor="target_yan" help="225 is a good minimum for low nutrient yeast, 450 a max for high nutrient yeast">
          <input id="target_yan" type="number" onChange={this._onChange} value={this.state.target_yan}/>
        </FormField>
        <FormField label="Organic Percentage (%)" htmlFor="organic_ratio" help="Organic is more expensive, inorganic can cause more yeast blooms">
          <input id="organic_ratio" min="0" max="100" type="number" onChange={this._onChange} value={this.state.organic_ratio}/>
        </FormField>
        <FormField htmlFor="details" help="To see more details in the output table">
          <CheckBox id="details" toggle={true} name="details" label="Show Details" checked={this.state.details} onChange={this._onChangeCheckBox}/>
        </FormField>
      </Form>
    );
  },

  render: function() {

    return (

Here be Inputs

          {this.renderForm()}

Here be Outputs

          {this.renderTable()}

    );
  }
});

module.exports = YANCalculator;
<commit_msg>indentation.<commit_after>var React = require('react');

var Section = require('grommet/components/Section');
var Table = require('grommet/components/Table');
var Form = require('grommet/components/Form');
var FormField = require('grommet/components/FormField');
var CheckBox = require('grommet/components/CheckBox');

var SG_PROPERTIES = {
  type: "number",
  min: "0",
  step: ".001"
};

// nutrient provides ppm per g/L
var nutrients = {
  fermaid_O: {
    organic: 65,
    inorganic: 0
  },
  dap: {
    organic: 0,
    inorganic: 210
  }
};

var YANCalculator = React.createClass({

  getInitialState: function() {
    return {
      final_gravity: 0.997,
      original_gravity: 1.100,
      gravity_units: 'sg',
      volume: 20,
      volume_units: 'liter',
      target_yan: 250,
      // target_yan_units: PPM
      organic_ratio: 35,

      // TODO convert split to generic
      // TODO make split editable...
      steps: [{
        name: 'At Mix',
        when: 0,
        allow_DAP: false,
        dap_split: 0,
        fermaid_O_split: 40
      },{
        name: 'End of Lag',
        when: 0,
        dap_split: 50,
        fermaid_O_split: 20
      },{
        name: '1/6 Sugar Break',
        when: 1/6,
        dap_split: 40,
        fermaid_O_split: 20
      },{
        name: '1/3 Sugar Break',
        when: 1/3,
        dap_split: 10,
        fermaid_O_split: 20
      },{
        total: true,
        name: 'TOTAL',
        dap_split: null,
        fermaid_O_split: null
      }]
      //TODO other properties to do later
      // types of nutrients
      // organic/inorganic ration
      // how many additions

    };
  },

  _onFormSubmit: function(event) {
    event.preventDefault();
  },

  _onChangeCheckBox:function(event) {
    var change = {};
    change[event.target.id] = event.target.checked;
    this.setState(change);
  },

  _onChange: function(event) {
    var change = {};
    change[event.target.id] = event.target.value;
    this.setState(change);
  },

  renderTable: function() {
    var headers = [Nutrient	];
    var total = {
      fermaid_O_split : 0,
      dap_split : 0
    };
    for (var i = this.state.steps.length - 1; i >= 0; i--) {
      total.fermaid_O_split+=this.state.steps[i].fermaid_O_split;
      total.dap_split+=this.state.steps[i].dap_split;
    };
    var total_gravity_points = this.state.original_gravity - this.state.final_gravity;
    var body = {
      gravity: [At Gravity (sg)	],
      fermaid_O_split: [Fermaid O (%)	],
      fermaid_O: [Fermaid O (g)	],
      fermaid_O_YAN: [Fermaid O YAN (ppm)	],
      blank_row: [	],
      dap_split: [DAP (%)	],
      dap: [DAP (g)	],
      dap_YAN: [DAP YAN (ppm)	]
    };
    var simple=['gravity', 'fermaid_O', 'dap'];
    var total_yan = {
      dap: this.state.target_yan * ((100 - this.state.organic_ratio)/100),
      fermaid_O: this.state.target_yan * (this.state.organic_ratio/100)
    };

    for (var i = 0; i < this.state.steps.length; i++) {
      var step = this.state.steps[i];
      headers.push({step.name}	);

      //percentages
      if (!step.total) {
        //TODO do some abstractions
        body.fermaid_O_split.push({(step.fermaid_O_split/total.fermaid_O_split*100).toFixed(2)+'%'}	);
        body.dap_split.push({(step.dap_split/total.dap_split*100).toFixed(2)+'%'}	);

        var dap_YAN = total_yan.dap*step.dap_split/100;
        var fermaid_YAN = total_yan.fermaid_O*step.fermaid_O_split/100;

        body.dap_YAN.push({(dap_YAN).toFixed(2)}	);
        body.dap.push({(dap_YAN*this.state.volume/nutrients.dap.inorganic).toFixed(2)}	);

        body.fermaid_O_YAN.push({(fermaid_YAN).toFixed(2)}	);
        body.fermaid_O.push({(fermaid_YAN*this.state.volume/nutrients.fermaid_O.organic).toFixed(2)}	);

        //TODO round properly
        body.gravity.push({(this.state.original_gravity - (total_gravity_points * step.when)).toFixed(3)}	);
      } else {
        body.fermaid_O_split.push({'100%'}	);
        body.dap_split.push({'100%'}	);

        body.dap_YAN.push({total_yan.dap}	);
        body.dap.push({(total_yan.dap*this.state.volume/nutrients.dap.inorganic).toFixed(2)}	);

        body.fermaid_O_YAN.push({total_yan.fermaid_O}	);
        body.fermaid_O.push({(total_yan.fermaid_O*this.state.volume/nutrients.fermaid_O.organic).toFixed(2)}	);

        body.gravity.push(N/A	);
      }

      // gravities

    };
    var renderedBody =[];
    for (var part in body) {
      if (simple.indexOf(part) !== -1 || this.state.details) {
        renderedBody.push(
{body[part]}
);
      }
    }
    return (

            {headers}

          {renderedBody}

    );
  },

  renderForm: function() {
    return (
      <Form onSubmit={this._onFormSubmit}>
        <FormField label="Volume (liters)" htmlFor="volume" >
          <input id="volume" type="number" onChange={this._onChange} value={this.state.volume}/>
        </FormField>
        <FormField label="Original Gravity (sg)" htmlFor="original_gravity" >
          <input id="original_gravity" {...SG_PROPERTIES} onChange={this._onChange} value={this.state.original_gravity}/>
        </FormField>
        <FormField label="Final Gravity (sg)" htmlFor="final_gravity" >
          <input id="final_gravity" {...SG_PROPERTIES} onChange={this._onChange} value={this.state.final_gravity}/>
        </FormField>
        <FormField label="YAN (ppm)" htmlFor="target_yan" help="225 is a good minimum for low nutrient yeast, 450 a max for high nutrient yeast">
          <input id="target_yan" type="number" onChange={this._onChange} value={this.state.target_yan}/>
        </FormField>
        <FormField label="Organic Percentage (%)" htmlFor="organic_ratio" help="Organic is more expensive, inorganic can cause more yeast blooms">
          <input id="organic_ratio" min="0" max="100" type="number" onChange={this._onChange} value={this.state.organic_ratio}/>
        </FormField>
        <FormField htmlFor="details" help="To see more details in the output table">
          <CheckBox id="details" toggle={true} name="details" label="Show Details" checked={this.state.details} onChange={this._onChangeCheckBox}/>
        </FormField>
      </Form>
    );
  },

  render: function() {

    return (

Here be Inputs

          {this.renderForm()}

Here be Outputs

          {this.renderTable()}

    );
  }
});

module.exports = YANCalculator;
<|endoftext|>


<commit_before>import React from 'react'
import ReactHighcharts from 'react-highcharts'
import BaseWidget from './Base'

class GraphWidget extends BaseWidget {
	constructor () {
		super()
		this.state = {
			isLoading: true,
		}
	}

	componentWillMount () {
		this.setState({ isLoading: false })
	}

	getConfig () {
		return {
			title: {
				text: '',
				align: 'left',
				style: {
					fontSize: '26px',
					fontFamily: 'Asap, Trebuchet MS',
				},
			},
			tooltip: {
				shared: true,
				valueSuffix: '',
				dateTimeLabelFormats: {
					millisecond: '%H:%M %d-%m-%Y',
					second: '%H:%M %d-%m-%Y',
					minute: '%H:%M %d-%m-%Y',
					hour: '%H:%M %d-%m-%Y',
					day: '%H:%M %d-%m-%Y',
					week: '%H:%M %d-%m-%Y',
					month: '%H:%M %d-%m-%Y',
					year: '%H:%M %d-%m-%Y',
				},
			},
			legend: {
				align: 'center',
				verticalAlign: 'bottom',
				layout: 'horizontal',
			},
			chart: {
				style: {
					fontFamily: 'Trebuchet MS',
				},
				zoomType: 'x',
			},
			plotOptions: {
				series: {
					cropTreshhold: 5000,
					states: {
						hover: {
							enabled: false,
						},
					},
				},
				line: {
					turboThreshold: 5000,
					lineWidth: 1,
				},
			},
			credits: {
				enabled: false,
			},
			xAxis: {
				type: 'datetime',
				labels: {
					rotation: -45,
					align: 'right',
				},
				title: {
					text: 'Timestamp',
				},
				crosshair: true,
				alternateGridColor: '#f7f7f7',
				dateTimeLabelFormats: {
					millisecond: '%H:%M:%S.%L',
					second: '%H:%M:%S',
					minute: '%H:%M',
					hour: '%H:%M',
					day: '%d-%m-%Y',
					week: 'week %U',
					month: '%m-%Y',
					year: '%Y',
				},
			},
			yAxis: {
				title: {
					text: this.getYAxisLabel(),
				}
			},
			series: this.getSeries(),
		}
	}
	getYAxisTitle () {
		return ''
	}
	getSeries () {
		return this.props.series
	}

	render () {
		var height = 400
		if (this.state.isLoading) {
			return (
Loading…
)
		}

		var config = this.getConfig()

		if (config.series.length === 0) {
			return (
No measurements.
)
		}

		return (<ReactHighcharts style={{ height }} config={config} />)
	}
}

GraphWidget.propTypes = {
	series: React.PropTypes.array.isRequired,
}

export default GraphWidget
<commit_msg>Remove markers from graph widget.<commit_after>import React from 'react'
import ReactHighcharts from 'react-highcharts'
import BaseWidget from './Base'

class GraphWidget extends BaseWidget {
	constructor () {
		super()
		this.state = {
			isLoading: true,
		}
	}

	componentWillMount () {
		this.setState({ isLoading: false })
	}

	getConfig () {
		return {
			title: {
				text: '',
				align: 'left',
				style: {
					fontSize: '26px',
					fontFamily: 'Asap, Trebuchet MS',
				},
			},
			tooltip: {
				shared: true,
				valueSuffix: '',
				dateTimeLabelFormats: {
					millisecond: '%H:%M %d-%m-%Y',
					second: '%H:%M %d-%m-%Y',
					minute: '%H:%M %d-%m-%Y',
					hour: '%H:%M %d-%m-%Y',
					day: '%H:%M %d-%m-%Y',
					week: '%H:%M %d-%m-%Y',
					month: '%H:%M %d-%m-%Y',
					year: '%H:%M %d-%m-%Y',
				},
			},
			legend: {
				align: 'center',
				verticalAlign: 'bottom',
				layout: 'horizontal',
			},
			chart: {
				style: {
					fontFamily: 'Trebuchet MS',
				},
				zoomType: 'x',
			},
			plotOptions: {
				series: {
					cropTreshhold: 5000,
					states: {
						hover: {
							enabled: false,
						},
					},
				},
				line: {
					turboThreshold: 5000,
					lineWidth: 1,
					marker: {
						enabled: false,
					},
				},
			},
			credits: {
				enabled: false,
			},
			xAxis: {
				type: 'datetime',
				labels: {
					rotation: -45,
					align: 'right',
				},
				title: {
					text: 'Timestamp',
				},
				crosshair: true,
				alternateGridColor: '#f7f7f7',
				dateTimeLabelFormats: {
					millisecond: '%H:%M:%S.%L',
					second: '%H:%M:%S',
					minute: '%H:%M',
					hour: '%H:%M',
					day: '%d-%m-%Y',
					week: 'week %U',
					month: '%m-%Y',
					year: '%Y',
				},
			},
			yAxis: {
				title: {
					text: this.getYAxisLabel(),
				}
			},
			series: this.getSeries(),
		}
	}
	getYAxisTitle () {
		return ''
	}
	getSeries () {
		return this.props.series
	}

	render () {
		var height = 400
		if (this.state.isLoading) {
			return (
Loading…
)
		}

		var config = this.getConfig()

		if (config.series.length === 0) {
			return (
No measurements.
)
		}

		return (<ReactHighcharts style={{ height }} config={config} />)
	}
}

GraphWidget.propTypes = {
	series: React.PropTypes.array.isRequired,
}

export default GraphWidget
<|endoftext|>


<commit_before>var L = require('leaflet');
var EsriGeocoder = require('esri-leaflet-geocoder');
var humane = require('humane-js');
require('leaflet-sidebar-v2');
require('../mapview/MapView');

L.App = L.App || {};

L.App.AppController = L.Class.extend({

  statics: {},

  options: {},

  initialize: function(options) {
    console.log('app.controller.AppController::initialize', arguments);
    L.setOptions(this, options);

    this.mapView = new L.App.MapView();

    this.zoomControl = new L.control.zoom({
      position: 'topright'
    }).addTo(this.mapView._map);

    this.searchControl = new EsriGeocoder.Geosearch({
      providers: [
        new EsriGeocoder.FeatureLayerProvider({
          label: 'Water System',
          url: 'http://sjcgis.org/arcgis/rest/services/HCS/Water_Systems/MapServer/0',
          searchFields: ['Sys_Name', 'Sys_ID'],
          //proxy: 'http://sjcgis.org/proxy/proxy.ashx',
          bufferRadius: 200,
          formatSuggestion: function(feature) {
            return feature.properties.Sys_Name;
          }
        }),
        new EsriGeocoder.GeocodeServiceProvider({
          url: 'http://sjcgis.org/arcgis/rest/services/Tools/Polaris_Geolocator/GeocodeServer',
          label: 'Polaris Geocoder',
          //proxy: 'http://sjcgis.org/proxy/proxy.ashx'
        })
      ],
      useArcgisWorldGeocoder: false,
      position: 'topright',
      useMapBounds: false
    }).addTo(this.mapView._map);

    this.sidebar = L.control.sidebar('sidebar').addTo(this.mapView._map);

    this.sidebar.open('home');

    this.results = new L.FeatureGroup().addTo(this.mapView._map);

    this.setupConnections();
  },

  setupConnections: function(options) {
    console.log('app.controller.AppController::setupConnections', arguments);

    var that = this;

    this.searchControl.on('results', function(data) {
      that.results.clearLayers();
      if(data.results.length === 0){
        humane.log('No results from search');
      } else {
        for(var i = data.results.length - 1; i >= 0; i--) {
          var marker = L.marker(data.results[i].latlng, {
            title: data.results[i].text,
            clickable: true
          });
          that.results.addLayer(marker);
          marker.bindPopup(data.results[i].text).openPopup();
        }
      }
    });

    this.results.on('contextmenu', function(evt) {
      that.results.clearLayers();
    });
  }
});
<commit_msg>Fix Geocode service url<commit_after>var L = require('leaflet');
var EsriGeocoder = require('esri-leaflet-geocoder');
var humane = require('humane-js');
require('leaflet-sidebar-v2');
require('../mapview/MapView');

L.App = L.App || {};

L.App.AppController = L.Class.extend({

  statics: {},

  options: {},

  initialize: function(options) {
    console.log('app.controller.AppController::initialize', arguments);
    L.setOptions(this, options);

    this.mapView = new L.App.MapView();

    this.zoomControl = new L.control.zoom({
      position: 'topright'
    }).addTo(this.mapView._map);

    this.searchControl = new EsriGeocoder.Geosearch({
      providers: [
        new EsriGeocoder.FeatureLayerProvider({
          label: 'Water System',
          url: 'http://sjcgis.org/arcgis/rest/services/HCS/Water_Systems/MapServer/0',
          searchFields: ['Sys_Name', 'Sys_ID'],
          //proxy: 'http://sjcgis.org/proxy/proxy.ashx',
          bufferRadius: 200,
          formatSuggestion: function(feature) {
            return feature.properties.Sys_Name;
          }
        }),
        new EsriGeocoder.GeocodeServiceProvider({
          url: 'http://sjcgis.org/arcgis/rest/services/Tools/SJC_Locator/GeocodeServer',
          label: 'San Juan County Geocoder',
          //proxy: 'http://sjcgis.org/proxy/proxy.ashx'
        })
      ],
      useArcgisWorldGeocoder: false,
      position: 'topright',
      useMapBounds: false
    }).addTo(this.mapView._map);

    this.sidebar = L.control.sidebar('sidebar').addTo(this.mapView._map);

    this.sidebar.open('home');

    this.results = new L.FeatureGroup().addTo(this.mapView._map);

    this.setupConnections();
  },

  setupConnections: function(options) {
    console.log('app.controller.AppController::setupConnections', arguments);

    var that = this;

    this.searchControl.on('results', function(data) {
      that.results.clearLayers();
      if(data.results.length === 0){
        humane.log('No results from search');
      } else {
        for(var i = data.results.length - 1; i >= 0; i--) {
          var marker = L.marker(data.results[i].latlng, {
            title: data.results[i].text,
            clickable: true
          });
          that.results.addLayer(marker);
          marker.bindPopup(data.results[i].text).openPopup();
        }
      }
    });

    this.results.on('contextmenu', function(evt) {
      that.results.clearLayers();
    });
  }
});
<|endoftext|>


<commit_before>/* ========================================================================
 * jQueryStickyNote: abstractDbController.js v1.0.0
 *
 * ========================================================================
 * Copyright 2016
 * Licensed under MIT (https://github.com/keshikashvili-gio/jQueryStickyNote/master/LICENSE)
 * ======================================================================== */

+function ($) {
    'use strict';

    note.DbLocalStorageController = function (options) {
        this.options = options;
    };

    note.DbLocalStorageController.prototype = Object.create(note.DbController.prototype);

    note.DbLocalStorageController.prototype.constructor = note.DbLocalStorageController;

    note.DbLocalStorageController.prototype.save = function (data) {
         this._saveToLocalStorage(data)
    };

    note.DbLocalStorageController.prototype.delete = function (id) {
         var data = this._getAllFromLocalStorage();
             for(var i = 0; i < data.length; i++){
                 if(data[i].id == id){
                     data.splice(data[i], 1);
                 }
             }
             this._saveToLocalStorage(data);
    };

    note.DbLocalStorageController.prototype.deleteAll = function () {

    };

    note.DbLocalStorageController.prototype.update = function () {

    };

    note.DbLocalStorageController.prototype.updateAll = function () {

    };

    note.DbLocalStorageController.prototype.getData = function () {
        return this._getAllFromLocalStorage();
    };

    note.DbLocalStorageController.prototype._addToLocalStorage = function (obj) {
        var data = this._getAllFromLocalStorage();
            data.push(obj);
            this._saveToLocalStorage(data);
    };

    note.DbLocalStorageController.prototype._getAllFromLocalStorage = function () {
        var storage = localStorage.getItem(this.options.localStorageKey);
        return storage ? JSON.parse(storage) : [];
    };

    note.DbLocalStorageController.prototype._saveToLocalStorage = function (data) {
        localStorage.setItem(this.options.localStorageKey, JSON.stringify(data));
    };

    note.DbLocalStorageController.prototype._getItemFromLocalStorage = function (key) {
        return this._getAllFromLocalStorage()[key];
    };

}(jQuery);

<commit_msg>implement delete function is DbLocalStorageService<commit_after>/* ========================================================================
 * jQueryStickyNote: abstractDbController.js v1.0.0
 *
 * ========================================================================
 * Copyright 2016
 * Licensed under MIT (https://github.com/keshikashvili-gio/jQueryStickyNote/master/LICENSE)
 * ======================================================================== */

+function ($) {
    'use strict';

    note.DbLocalStorageController = function (options) {
        this.options = options;
    };

    /**
     * extend Base D
     * @type {note.DbService}
     */
    note.DbLocalStorageController.prototype = Object.create(note.DbController.prototype);

    note.DbLocalStorageController.prototype.constructor = note.DbLocalStorageController;

    /**
     * add new note to localStorage
     * @param newData
     */
    note.DbLocalStorageController.prototype.save = function (newData) {
        var data = this._getAllFromLocalStorage();
        data.push(newData);
        this._saveToLocalStorage(data);
    };

    /**
     * delete note from localStorage
     * @param id
     */
    note.DbLocalStorageController.prototype.delete = function (id) {
        var data = this._getAllFromLocalStorage();
        for (var i = 0; i < data.length; i++) {
            if (data[i].id == id) {
                data.splice(data[i], 1);
            }
        }
        this._saveToLocalStorage(data);
    };

    note.DbLocalStorageController.prototype.deleteAll = function () {

    };

    /**
     *
     * @param updatedData
     */
    note.DbLocalStorageController.prototype.update = function (updatedData) {
        var data = this._getAllFromLocalStorage();
        for (var i = 0; i < data.length; i++) {
            if (data[i].id == updatedData.id) {
                data[i] = updatedData;
            }
        }
        this._saveToLocalStorage(data);
    };

    note.DbLocalStorageController.prototype.updateAll = function () {

    };

    /**
     *
     * @returns {Array|Object}
     */
    note.DbLocalStorageController.prototype.getData = function () {
        return this._getAllFromLocalStorage();
    };

    /**
     *
     * @returns {Array|object}
     * @private
     */
    note.DbLocalStorageController.prototype._getAllFromLocalStorage = function () {
        var storage = localStorage.getItem(this.options.localStorageKey);
        return storage ? JSON.parse(storage) : [];
    };

    /**
     *
     * @param data
     * @private
     */
    note.DbLocalStorageController.prototype._saveToLocalStorage = function (data) {
        localStorage.setItem(this.options.localStorageKey, JSON.stringify(data));
    };

    /**
     *
     * @param key
     * @returns {*}
     * @private
     */
    note.DbLocalStorageController.prototype._getItemFromLocalStorage = function (key) {
        return this._getAllFromLocalStorage()[key];
    };

}(jQuery);

<|endoftext|>


<commit_before>define([
  'jquery',
  '../utils',
  '../keys'
], function ($, Utils, KEYS) {
  function Search (decorated, $element, options) {
    decorated.call(this, $element, options);
  }

  Search.prototype.render = function (decorated) {
    var $search = $(
      '
' +
        '<input class="select2-search__field" type="search" tabindex="-1"' +
        ' autocomplete="off" autocorrect="off" autocapitalize="none"' +
        ' spellcheck="false" role="searchbox" aria-autocomplete="list" />' +
      '
'
    );

    this.$searchContainer = $search;
    this.$search = $search.find('input');

    var $rendered = decorated.call(this);

    this._transferTabIndex();

    return $rendered;
  };

  Search.prototype.bind = function (decorated, container, $container) {
    var self = this;

    var resultsId = container.id + '-results';

    decorated.call(this, container, $container);

    container.on('open', function () {
      self.$search.attr('aria-controls', resultsId);
      self.$search.trigger('focus');
    });

    container.on('close', function () {
      self.$search.val('');
      self.$search.removeAttr('aria-controls');
      self.$search.removeAttr('aria-activedescendant');
      self.$search.trigger('focus');
    });

    container.on('enable', function () {
      self.$search.prop('disabled', false);

      self._transferTabIndex();
    });

    container.on('disable', function () {
      self.$search.prop('disabled', true);
    });

    container.on('focus', function (evt) {
      self.$search.trigger('focus');
    });

    container.on('results:focus', function (params) {
      if (params.data._resultId) {
        self.$search.attr('aria-activedescendant', params.data._resultId);
      } else {
        self.$search.removeAttr('aria-activedescendant');
      }
    });

    this.$selection.on('focusin', '.select2-search--inline', function (evt) {
      self.trigger('focus', evt);
    });

    this.$selection.on('focusout', '.select2-search--inline', function (evt) {
      self._handleBlur(evt);
    });

    this.$selection.on('keydown', '.select2-search--inline', function (evt) {
      evt.stopPropagation();

      self.trigger('keypress', evt);

      self._keyUpPrevented = evt.isDefaultPrevented();

      var key = evt.which;

      if (key === KEYS.BACKSPACE && self.$search.val() === '') {
        var $previousChoice = self.$searchContainer
          .prev('.select2-selection__choice');

        if ($previousChoice.length > 0) {
          var item = Utils.GetData($previousChoice[0], 'data');

          self.searchRemoveChoice(item);

          evt.preventDefault();
        }
      }
    });

    this.$selection.on('click', '.select2-search--inline', function (evt) {
      if (self.$search.val()) {
        evt.stopPropagation();
      }
    });

    // Try to detect the IE version should the `documentMode` property that
    // is stored on the document. This is only implemented in IE and is
    // slightly cleaner than doing a user agent check.
    // This property is not available in Edge, but Edge also doesn't have
    // this bug.
    var msie = document.documentMode;
    var disableInputEvents = msie && msie <= 11;

    // Workaround for browsers which do not support the `input` event
    // This will prevent double-triggering of events for browsers which support
    // both the `keyup` and `input` events.
    this.$selection.on(
      'input.searchcheck',
      '.select2-search--inline',
      function (evt) {
        // IE will trigger the `input` event when a placeholder is used on a
        // search box. To get around this issue, we are forced to ignore all
        // `input` events in IE and keep using `keyup`.
        if (disableInputEvents) {
          self.$selection.off('input.search input.searchcheck');
          return;
        }

        // Unbind the duplicated `keyup` event
        self.$selection.off('keyup.search');
      }
    );

    this.$selection.on(
      'keyup.search input.search',
      '.select2-search--inline',
      function (evt) {
        // IE will trigger the `input` event when a placeholder is used on a
        // search box. To get around this issue, we are forced to ignore all
        // `input` events in IE and keep using `keyup`.
        if (disableInputEvents && evt.type === 'input') {
          self.$selection.off('input.search input.searchcheck');
          return;
        }

        var key = evt.which;

        // We can freely ignore events from modifier keys
        if (key == KEYS.SHIFT || key == KEYS.CTRL || key == KEYS.ALT) {
          return;
        }

        // Tabbing will be handled during the `keydown` phase
        if (key == KEYS.TAB) {
          return;
        }

        self.handleSearch(evt);
      }
    );
  };

  /**
   * This method will transfer the tabindex attribute from the rendered
   * selection to the search box. This allows for the search box to be used as
   * the primary focus instead of the selection container.
   *
   * @private
   */
  Search.prototype._transferTabIndex = function (decorated) {
    this.$search.attr('tabindex', this.$selection.attr('tabindex'));
    this.$selection.attr('tabindex', '-1');
  };

  Search.prototype.createPlaceholder = function (decorated, placeholder) {
    this.$search.attr('placeholder', placeholder.text);
  };

  Search.prototype.update = function (decorated, data) {
    var searchHadFocus = this.$search[0] == document.activeElement;

    this.$search.attr('placeholder', '');

    decorated.call(this, data);

    this.$selection.find('.select2-selection__rendered')
                   .append(this.$searchContainer);

    this.resizeSearch();
    if (searchHadFocus) {
      this.$search.trigger('focus');
    }
  };

  Search.prototype.handleSearch = function () {
    this.resizeSearch();

    if (!this._keyUpPrevented) {
      var input = this.$search.val();

      this.trigger('query', {
        term: input
      });
    }

    this._keyUpPrevented = false;
  };

  Search.prototype.searchRemoveChoice = function (decorated, item) {
    this.trigger('unselect', {
      data: item
    });

    this.$search.val(item.text);
    this.handleSearch();
  };

  Search.prototype.resizeSearch = function () {
    this.$search.css('width', '25px');

    var width = '';

    if (this.$search.attr('placeholder') !== '') {
      width = this.$selection.find('.select2-selection__rendered').width();
    } else {
      var minimumWidth = this.$search.val().length + 1;

      width = (minimumWidth * 0.75) + 'em';
    }

    this.$search.css('width', width);
  };

  return Search;
});
<commit_msg>Fix selection search resizeSearch on close (#5766)<commit_after>define([
  'jquery',
  '../utils',
  '../keys'
], function ($, Utils, KEYS) {
  function Search (decorated, $element, options) {
    decorated.call(this, $element, options);
  }

  Search.prototype.render = function (decorated) {
    var $search = $(
      '
' +
        '<input class="select2-search__field" type="search" tabindex="-1"' +
        ' autocomplete="off" autocorrect="off" autocapitalize="none"' +
        ' spellcheck="false" role="searchbox" aria-autocomplete="list" />' +
      '
'
    );

    this.$searchContainer = $search;
    this.$search = $search.find('input');

    var $rendered = decorated.call(this);

    this._transferTabIndex();

    return $rendered;
  };

  Search.prototype.bind = function (decorated, container, $container) {
    var self = this;

    var resultsId = container.id + '-results';

    decorated.call(this, container, $container);

    container.on('open', function () {
      self.$search.attr('aria-controls', resultsId);
      self.$search.trigger('focus');
    });

    container.on('close', function () {
      self.$search.val('');
      self.resizeSearch();
      self.$search.removeAttr('aria-controls');
      self.$search.removeAttr('aria-activedescendant');
      self.$search.trigger('focus');
    });

    container.on('enable', function () {
      self.$search.prop('disabled', false);

      self._transferTabIndex();
    });

    container.on('disable', function () {
      self.$search.prop('disabled', true);
    });

    container.on('focus', function (evt) {
      self.$search.trigger('focus');
    });

    container.on('results:focus', function (params) {
      if (params.data._resultId) {
        self.$search.attr('aria-activedescendant', params.data._resultId);
      } else {
        self.$search.removeAttr('aria-activedescendant');
      }
    });

    this.$selection.on('focusin', '.select2-search--inline', function (evt) {
      self.trigger('focus', evt);
    });

    this.$selection.on('focusout', '.select2-search--inline', function (evt) {
      self._handleBlur(evt);
    });

    this.$selection.on('keydown', '.select2-search--inline', function (evt) {
      evt.stopPropagation();

      self.trigger('keypress', evt);

      self._keyUpPrevented = evt.isDefaultPrevented();

      var key = evt.which;

      if (key === KEYS.BACKSPACE && self.$search.val() === '') {
        var $previousChoice = self.$searchContainer
          .prev('.select2-selection__choice');

        if ($previousChoice.length > 0) {
          var item = Utils.GetData($previousChoice[0], 'data');

          self.searchRemoveChoice(item);

          evt.preventDefault();
        }
      }
    });

    this.$selection.on('click', '.select2-search--inline', function (evt) {
      if (self.$search.val()) {
        evt.stopPropagation();
      }
    });

    // Try to detect the IE version should the `documentMode` property that
    // is stored on the document. This is only implemented in IE and is
    // slightly cleaner than doing a user agent check.
    // This property is not available in Edge, but Edge also doesn't have
    // this bug.
    var msie = document.documentMode;
    var disableInputEvents = msie && msie <= 11;

    // Workaround for browsers which do not support the `input` event
    // This will prevent double-triggering of events for browsers which support
    // both the `keyup` and `input` events.
    this.$selection.on(
      'input.searchcheck',
      '.select2-search--inline',
      function (evt) {
        // IE will trigger the `input` event when a placeholder is used on a
        // search box. To get around this issue, we are forced to ignore all
        // `input` events in IE and keep using `keyup`.
        if (disableInputEvents) {
          self.$selection.off('input.search input.searchcheck');
          return;
        }

        // Unbind the duplicated `keyup` event
        self.$selection.off('keyup.search');
      }
    );

    this.$selection.on(
      'keyup.search input.search',
      '.select2-search--inline',
      function (evt) {
        // IE will trigger the `input` event when a placeholder is used on a
        // search box. To get around this issue, we are forced to ignore all
        // `input` events in IE and keep using `keyup`.
        if (disableInputEvents && evt.type === 'input') {
          self.$selection.off('input.search input.searchcheck');
          return;
        }

        var key = evt.which;

        // We can freely ignore events from modifier keys
        if (key == KEYS.SHIFT || key == KEYS.CTRL || key == KEYS.ALT) {
          return;
        }

        // Tabbing will be handled during the `keydown` phase
        if (key == KEYS.TAB) {
          return;
        }

        self.handleSearch(evt);
      }
    );
  };

  /**
   * This method will transfer the tabindex attribute from the rendered
   * selection to the search box. This allows for the search box to be used as
   * the primary focus instead of the selection container.
   *
   * @private
   */
  Search.prototype._transferTabIndex = function (decorated) {
    this.$search.attr('tabindex', this.$selection.attr('tabindex'));
    this.$selection.attr('tabindex', '-1');
  };

  Search.prototype.createPlaceholder = function (decorated, placeholder) {
    this.$search.attr('placeholder', placeholder.text);
  };

  Search.prototype.update = function (decorated, data) {
    var searchHadFocus = this.$search[0] == document.activeElement;

    this.$search.attr('placeholder', '');

    decorated.call(this, data);

    this.$selection.find('.select2-selection__rendered')
                   .append(this.$searchContainer);

    this.resizeSearch();
    if (searchHadFocus) {
      this.$search.trigger('focus');
    }
  };

  Search.prototype.handleSearch = function () {
    this.resizeSearch();

    if (!this._keyUpPrevented) {
      var input = this.$search.val();

      this.trigger('query', {
        term: input
      });
    }

    this._keyUpPrevented = false;
  };

  Search.prototype.searchRemoveChoice = function (decorated, item) {
    this.trigger('unselect', {
      data: item
    });

    this.$search.val(item.text);
    this.handleSearch();
  };

  Search.prototype.resizeSearch = function () {
    this.$search.css('width', '25px');

    var width = '';

    if (this.$search.attr('placeholder') !== '') {
      width = this.$selection.find('.select2-selection__rendered').width();
    } else {
      var minimumWidth = this.$search.val().length + 1;

      width = (minimumWidth * 0.75) + 'em';
    }

    this.$search.css('width', width);
  };

  return Search;
});
<|endoftext|>


<commit_before>/*
 * Copyright (c) 2014 Adobe Systems Incorporated. All rights reserved.
 *
 * Permission is hereby granted, free of charge, to any person obtaining a
 * copy of this software and associated documentation files (the "Software"),
 * to deal in the Software without restriction, including without limitation
 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
 * and/or sell copies of the Software, and to permit persons to whom the
 * Software is furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included in
 * all copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
 * DEALINGS IN THE SOFTWARE.
 *
 */

define(function (require, exports, module) {
    "use strict";

    var Promise = require("bluebird");

    var util = require("adapter/util"),
        PS = require("adapter/ps"),
        OS = require("adapter/os"),
        UI = require("adapter/ps/ui"),
        descriptor = require("adapter/ps/descriptor"),
        toolLib = require("adapter/lib/tool");

    var Tool = require("js/models/tool"),
        shortcuts = require("js/actions/shortcuts"),
        EventPolicy = require("js/models/eventpolicy"),
        KeyboardEventPolicy = EventPolicy.KeyboardEventPolicy;

    var _TOGGLE_TARGET_PATH = 3502,
        _CLEAR_PATH = 106;

    /**
     * Updates current document because we may have changed bounds in Photoshop
     * @private
     */
    var _deselectHandler = function () {
        var currentDocument = this.flux.store("application").getCurrentDocument();

        var targetPathsPromise = UI.setSuppressTargetPaths(true),
            backspacePromise = this.transfer(shortcuts.removeShortcut, "vectorBackspace"),
            deletePromise = this.transfer(shortcuts.removeShortcut, "vectorDelete");

        return Promise.join(targetPathsPromise, backspacePromise, deletePromise)
            .bind(this)
            .then(function () {
                if (currentDocument) {
                    this.flux.actions.layers.resetLayers(currentDocument, currentDocument.layers.selected);
                }
            });
    };

    /**
     * Sets the selection mode to only active layers for direct select tool
     * @private
     */
    var _selectHandler = function () {
        var deleteFn = function (event) {
            event.stopPropagation();

            return PS.performMenuCommand(_CLEAR_PATH)
                .catch(function () {
                    // Silence the errors here
                });
        };

        var optionsPromise = descriptor.playObject(toolLib.setDirectSelectOptionForAllLayers(false)),
            suppressionPromise = UI.setSuppressTargetPaths(false),
            backspacePromise = this.transfer(shortcuts.addShortcut,
                OS.eventKeyCode.BACKSPACE, {}, deleteFn, "vectorBackspace", true),
            deletePromise = this.transfer(shortcuts.addShortcut,
                OS.eventKeyCode.DELETE, {}, deleteFn, "vectorDelete", true),
            getPathVisiblePromise = descriptor.getProperty("document", "targetPathVisibility");

        return Promise.join(getPathVisiblePromise,
            optionsPromise,
            suppressionPromise,
            backspacePromise,
            deletePromise,
            function (visible) {
                if (!visible) {
                    return PS.performMenuCommand(_TOGGLE_TARGET_PATH);
                }
            });
    };

    /**
     * @implements {Tool}
     * @constructor
     */
    var SuperSelectVectorTool = function () {
        Tool.call(this, "superselectVector", "Superselect - Direct Select", "directSelectTool");
        this.icon = "directSelect";
        this.isMainTool = false;

        var escapeKeyPolicy = new KeyboardEventPolicy(UI.policyAction.NEVER_PROPAGATE,
                OS.eventKind.KEY_DOWN, null, OS.eventKeyCode.ESCAPE),
            enterKeyPolicy = new KeyboardEventPolicy(UI.policyAction.NEVER_PROPAGATE,
                OS.eventKind.KEY_DOWN, null, OS.eventKeyCode.ENTER),
            backspaceKeyPolicy = new KeyboardEventPolicy(UI.policyAction.NEVER_PROPAGATE,
                OS.eventKind.KEY_DOWN, null, OS.eventKeyCode.BACKSPACE),
            deleteKeyPolicy = new KeyboardEventPolicy(UI.policyAction.NEVER_PROPAGATE,
                OS.eventKind.KEY_DOWN, null, OS.eventKeyCode.DELETE),
            arrowLeftPolicy = new KeyboardEventPolicy(UI.policyAction.ALWAYS_PROPAGATE,
                OS.eventKind.KEY_DOWN, null, OS.eventKeyCode.ARROW_LEFT),
            arrowUpPolicy = new KeyboardEventPolicy(UI.policyAction.ALWAYS_PROPAGATE,
                OS.eventKind.KEY_DOWN, null, OS.eventKeyCode.ARROW_UP),
            arrowRightPolicy = new KeyboardEventPolicy(UI.policyAction.ALWAYS_PROPAGATE,
                OS.eventKind.KEY_DOWN, null, OS.eventKeyCode.ARROW_RIGHT),
            arrowDownPolicy = new KeyboardEventPolicy(UI.policyAction.ALWAYS_PROPAGATE,
                OS.eventKind.KEY_DOWN, null, OS.eventKeyCode.ARROW_DOWN);

        this.keyboardPolicyList = [
            escapeKeyPolicy, // Switch back to newSelect
            enterKeyPolicy, // Switch back to newSelect
            backspaceKeyPolicy, // Delete selected vertices
            deleteKeyPolicy, // Delete selected vertices
            arrowLeftPolicy, // We want all arrow keys to go into Photoshop in vector edit mode
            arrowDownPolicy,
            arrowRightPolicy,
            arrowUpPolicy
        ];

        this.selectHandler = _selectHandler;
        this.deselectHandler = _deselectHandler;
    };
    util.inherits(SuperSelectVectorTool, Tool);

    /**
     * Handler for key down events
     * Enter and escape switches back to super select tool
     *
     * @param  {KeyboardEvent} event
     */
    SuperSelectVectorTool.prototype.onKeyDown = function (event) {
        var flux = this.getFlux(),
            toolStore = flux.store("tool");

        var detail = event.detail;
        if (detail.keyCode === 27) { // Escape
            flux.actions.tools.select(toolStore.getToolByID("newSelect"));
        } else if (detail.keyCode === 13) { // Enter
            flux.actions.tools.select(toolStore.getToolByID("newSelect"));
        }
    };

    module.exports = SuperSelectVectorTool;
});
<commit_msg>Listen to pathComponentSelectionChanged events in vector tool and reset tool<commit_after>/*
 * Copyright (c) 2014 Adobe Systems Incorporated. All rights reserved.
 *
 * Permission is hereby granted, free of charge, to any person obtaining a
 * copy of this software and associated documentation files (the "Software"),
 * to deal in the Software without restriction, including without limitation
 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
 * and/or sell copies of the Software, and to permit persons to whom the
 * Software is furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included in
 * all copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
 * DEALINGS IN THE SOFTWARE.
 *
 */

define(function (require, exports, module) {
    "use strict";

    var Promise = require("bluebird");

    var util = require("adapter/util"),
        PS = require("adapter/ps"),
        OS = require("adapter/os"),
        UI = require("adapter/ps/ui"),
        descriptor = require("adapter/ps/descriptor"),
        toolLib = require("adapter/lib/tool");

    var Tool = require("js/models/tool"),
        shortcuts = require("js/actions/shortcuts"),
        EventPolicy = require("js/models/eventpolicy"),
        KeyboardEventPolicy = EventPolicy.KeyboardEventPolicy;

    var _TOGGLE_TARGET_PATH = 3502,
        _CLEAR_PATH = 106;

    /**
     * Handler for pathComponentSelectionChanged events
     */
    var _pathSelectionhandler;

    /**
     * Updates current document because we may have changed bounds in Photoshop
     * @private
     */
    var _deselectHandler = function () {
        var currentDocument = this.flux.store("application").getCurrentDocument();

        var targetPathsPromise = UI.setSuppressTargetPaths(true),
            backspacePromise = this.transfer(shortcuts.removeShortcut, "vectorBackspace"),
            deletePromise = this.transfer(shortcuts.removeShortcut, "vectorDelete");

        descriptor.removeListener("pathComponentSelectionChanged", _pathSelectionhandler);
        _pathSelectionhandler = null;

        return Promise.join(targetPathsPromise, backspacePromise, deletePromise)
            .bind(this)
            .then(function () {
                if (currentDocument) {
                    this.flux.actions.layers.resetLayers(currentDocument, currentDocument.layers.selected);
                }
            });
    };

    /**
     * Sets the selection mode to only active layers for direct select tool
     * @private
     */
    var _selectHandler = function () {
        var deleteFn = function (event) {
            event.stopPropagation();

            return PS.performMenuCommand(_CLEAR_PATH)
                .catch(function () {
                    // Silence the errors here
                });
        };

        _pathSelectionhandler = function (event) {
            if (event.pathID && event.pathID.length === 0) {
                var toolStore = this.flux.store("tool");

                this.flux.actions.tools.select(toolStore.getToolByID("newSelect"));
            }
        }.bind(this);
        descriptor.addListener("pathComponentSelectionChanged", _pathSelectionhandler);

        var optionsPromise = descriptor.playObject(toolLib.setDirectSelectOptionForAllLayers(false)),
            suppressionPromise = UI.setSuppressTargetPaths(false),
            backspacePromise = this.transfer(shortcuts.addShortcut,
                OS.eventKeyCode.BACKSPACE, {}, deleteFn, "vectorBackspace", true),
            deletePromise = this.transfer(shortcuts.addShortcut,
                OS.eventKeyCode.DELETE, {}, deleteFn, "vectorDelete", true),
            getPathVisiblePromise = descriptor.getProperty("document", "targetPathVisibility");

        return Promise.join(getPathVisiblePromise,
            optionsPromise,
            suppressionPromise,
            backspacePromise,
            deletePromise,
            function (visible) {
                if (!visible) {
                    return PS.performMenuCommand(_TOGGLE_TARGET_PATH);
                }
            });
    };

    /**
     * @implements {Tool}
     * @constructor
     */
    var SuperSelectVectorTool = function () {
        Tool.call(this, "superselectVector", "Superselect - Direct Select", "directSelectTool");
        this.icon = "directSelect";
        this.isMainTool = false;

        var escapeKeyPolicy = new KeyboardEventPolicy(UI.policyAction.NEVER_PROPAGATE,
                OS.eventKind.KEY_DOWN, null, OS.eventKeyCode.ESCAPE),
            enterKeyPolicy = new KeyboardEventPolicy(UI.policyAction.NEVER_PROPAGATE,
                OS.eventKind.KEY_DOWN, null, OS.eventKeyCode.ENTER),
            backspaceKeyPolicy = new KeyboardEventPolicy(UI.policyAction.NEVER_PROPAGATE,
                OS.eventKind.KEY_DOWN, null, OS.eventKeyCode.BACKSPACE),
            deleteKeyPolicy = new KeyboardEventPolicy(UI.policyAction.NEVER_PROPAGATE,
                OS.eventKind.KEY_DOWN, null, OS.eventKeyCode.DELETE),
            arrowLeftPolicy = new KeyboardEventPolicy(UI.policyAction.ALWAYS_PROPAGATE,
                OS.eventKind.KEY_DOWN, null, OS.eventKeyCode.ARROW_LEFT),
            arrowUpPolicy = new KeyboardEventPolicy(UI.policyAction.ALWAYS_PROPAGATE,
                OS.eventKind.KEY_DOWN, null, OS.eventKeyCode.ARROW_UP),
            arrowRightPolicy = new KeyboardEventPolicy(UI.policyAction.ALWAYS_PROPAGATE,
                OS.eventKind.KEY_DOWN, null, OS.eventKeyCode.ARROW_RIGHT),
            arrowDownPolicy = new KeyboardEventPolicy(UI.policyAction.ALWAYS_PROPAGATE,
                OS.eventKind.KEY_DOWN, null, OS.eventKeyCode.ARROW_DOWN);

        this.keyboardPolicyList = [
            escapeKeyPolicy, // Switch back to newSelect
            enterKeyPolicy, // Switch back to newSelect
            backspaceKeyPolicy, // Delete selected vertices
            deleteKeyPolicy, // Delete selected vertices
            arrowLeftPolicy, // We want all arrow keys to go into Photoshop in vector edit mode
            arrowDownPolicy,
            arrowRightPolicy,
            arrowUpPolicy
        ];

        this.selectHandler = _selectHandler;
        this.deselectHandler = _deselectHandler;
    };
    util.inherits(SuperSelectVectorTool, Tool);

    /**
     * Handler for key down events
     * Enter and escape switches back to super select tool
     *
     * @param  {KeyboardEvent} event
     */
    SuperSelectVectorTool.prototype.onKeyDown = function (event) {
        var flux = this.getFlux(),
            toolStore = flux.store("tool");

        var detail = event.detail;
        if (detail.keyCode === 27) { // Escape
            flux.actions.tools.select(toolStore.getToolByID("newSelect"));
        } else if (detail.keyCode === 13) { // Enter
            flux.actions.tools.select(toolStore.getToolByID("newSelect"));
        }
    };

    module.exports = SuperSelectVectorTool;
});
<|endoftext|>


<commit_before>/* tests */

/*
 * Connection configurations
 */
var settings = JSON.parse(require('fs').readFileSync('./tests/db_conf.json','utf8'));

/*
 * Create an Informix database nodejs object
 */
var bindings = require("../nodejs-db-informix");

/*
 * Create a new Informix database bindings. Setup event callbacks. Connect to
 * the database.
 * c - connection
 */
var c = new bindings.Informix(settings);
c.on('error', function(error) {
    console.log("Error: ");
    console.log(error);
}).on('ready', function(server) {
    console.log("Connection ready to ");
    console.log(server);
}).connect(function(err) {
    if (err) {
        throw new Error('Could not connect to DB');
    }
    console.log('Connected to db with ');
    console.log(settings);
    console.log("isConnected() == " + c.isConnected());

    var rs;

    rs = this
        .query(
              ""
            , []
            , function () {
                console.log('CALLBACK:');
                console.log(arguments);
            }
            , {
                start: function(q) {
                    console.log('START:');
                    console.log(q);
                }
                , finish: function(f) {
                    console.log('Finish:');
                    console.log(f);
                }
                , async: false
                , cast: true
            }
        )
        .select("name,partnum,owner,created")
        .from("sysdatabases", false)
        .orderby("name")
        .execute();

    rs = this
        .query(
              ""
            , []
            , function () {
                console.log('CALLBACK:');
                console.log(arguments);
            }
            , {
                start: function(q) {
                    console.log('START:');
                    console.log(q);
                }
                , finish: function(f) {
                    console.log('Finish:');
                    console.log(f);
                }
                , async: false
                , cast: true
            }
        )
        .select(["procid", "procname", "owner", "mode", "retsize", "symsize", "datasize", "codesize", "numargs", "isproc"])
        .skip(15)
        .limit(15,10)
        .first(3)
        .from("sysprocedures", false)
        .where("owner='informix'")
        .orderby("procname")
        .execute();

});
<commit_msg>use async<commit_after>/* tests */

/*
 * Connection configurations
 */
var settings = JSON.parse(require('fs').readFileSync('./tests/db_conf.json','utf8'));

/*
 * Create an Informix database nodejs object
 */
var bindings = require("../nodejs-db-informix");

/*
 * Create a new Informix database bindings. Setup event callbacks. Connect to
 * the database.
 * c - connection
 */
var c = new bindings.Informix(settings);
c.on('error', function(error) {
    console.log("Error: ");
    console.log(error);
}).on('ready', function(server) {
    console.log("Connection ready to ");
    console.log(server);
}).connect(function(err) {
    if (err) {
        throw new Error('Could not connect to DB');
    }
    console.log('Connected to db with ');
    console.log(settings);
    console.log("isConnected() == " + c.isConnected());

    var rs;

    rs = this
        .query(
              ""
            , []
            , function () {
                console.log('CALLBACK:');
                console.log(arguments);
            }
            , {
                start: function(q) {
                    console.log('START:');
                    console.log(q);
                }
                , finish: function(f) {
                    console.log('Finish:');
                    console.log(f);
                }
                , async: true
                , cast: true
            }
        )
        .select("name,partnum,owner,created")
        .from("sysdatabases", false)
        .orderby("name")
        .execute();

    rs = this
        .query(
              ""
            , []
            , function () {
                console.log('CALLBACK:');
                console.log(arguments);
            }
            , {
                start: function(q) {
                    console.log('START:');
                    console.log(q);
                }
                , finish: function(f) {
                    console.log('Finish:');
                    console.log(f);
                }
                , async: true
                , cast: true
            }
        )
        .select(["procid", "procname", "owner", "mode", "retsize", "symsize", "datasize", "codesize", "numargs", "isproc"])
        .skip(15)
        .limit(15,10)
        .first(3)
        .from("sysprocedures", false)
        .where("owner='informix'")
        .orderby("procname")
        .execute();

});
<|endoftext|>


<commit_before>//I hear you like to run node in your node, so I'm testing node using node
var spawn = require('child_process').spawn,
    testProcess = spawn('cat ./src/index.js | echo'),
    assert = require('assert');
console.log("Modules required and process spawned");

testProcess.stdout.on('data', function (data) {
  assert.equal(data, 'This is only a test');
  console.log("Received expected output on stdout");
});

testProcess.stderr.on('data', function (data) {
  assert.fail(data, "nothing", "Did not expect any stderr", ":")
});

testProcess.on('close', function (code) {
  assert.equal(code, 0, "The spawned process did not exit cleanly");

});
<commit_msg>Trying to get tests to work on TravisCI<commit_after>//I hear you like to run node in your node, so I'm testing node using node
var spawn = require('child_process').spawn,
    testProcess = spawn('ls'),
    assert = require('assert');
console.log(process.env.PATH);

testProcess.stdout.on('data', function (data) {
  assert.equal(data, 'This is only a test');
  console.log("Received expected output on stdout");
});

testProcess.stderr.on('data', function (data) {
  assert.fail(data, "nothing", "Did not expect any stderr", ":")
});

testProcess.on('close', function (code) {
  assert.equal(code, 0, "The spawned process did not exit cleanly");

});
<|endoftext|>


<commit_before>/* eslint-disable no-undef */
const assert = require('assert');
const fs = require('fs-extra');
const os = require('os');
const path = require('path');
const pathExists = require('path-exists');
const rename = require('../rename');
const yargs = require('yargs');
const yargsOptions = require('../lib/yargsOptions');

// remove test directory
fs.removeSync('./test');
// create test files/directories
fs.ensureDirSync('test');
fs.ensureDirSync('test/another-dir');
for (let i = 1; i < 31; i++) {
  let num = inWords(i);
  fs.writeFileSync((i < 20 ? 'test/' : 'test/another-dir/') + num.trim().replace(' ', '-') + '.txt', 'file ' + num.trim(), 'utf8');
}
let undoFile = os.homedir() + '/.rename/undo.json';
if (!pathExists.sync(undoFile)) fs.writeJSONSync(undoFile, []);

// run tests
runCommand('rename test/one.txt test/one-renamed.txt');
let oldFile = fs.existsSync('test/one.txt');
let newFile = fs.existsSync('test/one-renamed.txt');
describe('Rename a single file', function () {
  it('rename test/one.txt test/one-renamed.txt', function () {
    assert.equal(oldFile, false);
    assert.equal(newFile, true);
  });
});

runCommand('rename test/f*.txt test/multiple');
oldFile = ['test/four.txt', 'test/five.txt', 'test/fourteen.txt', 'test/fifteen.txt'].some(f => fs.existsSync(f));
newFile = ['test/multiple1.txt', 'test/multiple2.txt', 'test/multiple3.txt', 'test/multiple4.txt'].every(f => fs.existsSync(f));
describe('Rename multiple files the same thing with appended index', function () {
  it('rename test/f*.txt test/multiple', function () {
    assert.equal(oldFile, false);
    assert.equal(newFile, true);
  });
});

// HELPER FUNCTIONS

function runCommand(command) {
  let argv = yargs.options(yargsOptions).parse(command.replace(/^rename /, '') + ' --noundo');
  let newFileName = path.parse(argv._.pop());
  let files = rename.getFileArray(argv._);
  let options = rename.argvToOptions(argv);
  let operations = rename.getOperations(files, newFileName, options);
  rename.run(operations, false);
}

function inWords (num) {
  let a = ['','one ','two ','three ','four ', 'five ','six ','seven ','eight ','nine ','ten ','eleven ','twelve ','thirteen ','fourteen ','fifteen ','sixteen ','seventeen ','eighteen ','nineteen '];
  let b = ['', '', 'twenty','thirty','forty','fifty', 'sixty','seventy','eighty','ninety'];
  if ((num = num.toString()).length > 9) return 'overflow';
  let n = ('000000000' + num).substr(-9).match(/^(\d{2})(\d{2})(\d{2})(\d{1})(\d{2})$/);
  if (!n) return;
  let str = '';
  str += (n[1] != 0) ? (a[Number(n[1])] || b[n[1][0]] + ' ' + a[n[1][1]]) + 'crore ' : '';
  str += (n[2] != 0) ? (a[Number(n[2])] || b[n[2][0]] + ' ' + a[n[2][1]]) + 'lakh ' : '';
  str += (n[3] != 0) ? (a[Number(n[3])] || b[n[3][0]] + ' ' + a[n[3][1]]) + 'thousand ' : '';
  str += (n[4] != 0) ? (a[Number(n[4])] || b[n[4][0]] + ' ' + a[n[4][1]]) + 'hundred ' : '';
  str += (n[5] != 0) ? ((str != '') ? 'and ' : '') + (a[Number(n[5])] || b[n[5][0]] + ' ' + a[n[5][1]]) : '';
  return str;
}
<commit_msg>catch write error<commit_after>/* eslint-disable no-undef */
const assert = require('assert');
const fs = require('fs-extra');
const os = require('os');
const path = require('path');
const pathExists = require('path-exists');
const rename = require('../rename');
const yargs = require('yargs');
const yargsOptions = require('../lib/yargsOptions');

// remove test directory
fs.removeSync('./test');
// create test files/directories
fs.ensureDirSync('test');
fs.ensureDirSync('test/another-dir');
for (let i = 1; i < 31; i++) {
  let num = inWords(i);
  fs.writeFileSync((i < 20 ? 'test/' : 'test/another-dir/') + num.trim().replace(' ', '-') + '.txt', 'file ' + num.trim(), 'utf8');
}
let undoFile = os.homedir() + '/.rename/undo.json';
if (!pathExists.sync(undoFile)) {
  try {
    fs.writeJSONSync(undoFile, []);
  } catch(e) {
    console.dir(e);
  }
}

// run tests
runCommand('rename test/one.txt test/one-renamed.txt');
let oldFile = fs.existsSync('test/one.txt');
let newFile = fs.existsSync('test/one-renamed.txt');
describe('Rename a single file', function () {
  it('rename test/one.txt test/one-renamed.txt', function () {
    assert.equal(oldFile, false);
    assert.equal(newFile, true);
  });
});

runCommand('rename test/f*.txt test/multiple');
oldFile = ['test/four.txt', 'test/five.txt', 'test/fourteen.txt', 'test/fifteen.txt'].some(f => fs.existsSync(f));
newFile = ['test/multiple1.txt', 'test/multiple2.txt', 'test/multiple3.txt', 'test/multiple4.txt'].every(f => fs.existsSync(f));
describe('Rename multiple files the same thing with appended index', function () {
  it('rename test/f*.txt test/multiple', function () {
    assert.equal(oldFile, false);
    assert.equal(newFile, true);
  });
});

// HELPER FUNCTIONS

function runCommand(command) {
  let argv = yargs.options(yargsOptions).parse(command.replace(/^rename /, '') + ' --noundo');
  let newFileName = path.parse(argv._.pop());
  let files = rename.getFileArray(argv._);
  let options = rename.argvToOptions(argv);
  let operations = rename.getOperations(files, newFileName, options);
  rename.run(operations, false);
}

function inWords (num) {
  let a = ['','one ','two ','three ','four ', 'five ','six ','seven ','eight ','nine ','ten ','eleven ','twelve ','thirteen ','fourteen ','fifteen ','sixteen ','seventeen ','eighteen ','nineteen '];
  let b = ['', '', 'twenty','thirty','forty','fifty', 'sixty','seventy','eighty','ninety'];
  if ((num = num.toString()).length > 9) return 'overflow';
  let n = ('000000000' + num).substr(-9).match(/^(\d{2})(\d{2})(\d{2})(\d{1})(\d{2})$/);
  if (!n) return;
  let str = '';
  str += (n[1] != 0) ? (a[Number(n[1])] || b[n[1][0]] + ' ' + a[n[1][1]]) + 'crore ' : '';
  str += (n[2] != 0) ? (a[Number(n[2])] || b[n[2][0]] + ' ' + a[n[2][1]]) + 'lakh ' : '';
  str += (n[3] != 0) ? (a[Number(n[3])] || b[n[3][0]] + ' ' + a[n[3][1]]) + 'thousand ' : '';
  str += (n[4] != 0) ? (a[Number(n[4])] || b[n[4][0]] + ' ' + a[n[4][1]]) + 'hundred ' : '';
  str += (n[5] != 0) ? ((str != '') ? 'and ' : '') + (a[Number(n[5])] || b[n[5][0]] + ' ' + a[n[5][1]]) : '';
  return str;
}
<|endoftext|>


<commit_before>module.exports = function(server) {

  // Create an API namespace, so that the root does not
  // have to be repeated for each end point.
	server.namespace('/api', function() {

		// Return fixture data for '/api/profile/:id'
		server.get('/profiles/:id', function(req, res) {
			var profile = {
				"profile": {
					"id": 			1,
					"name": 		"Jim Hall",
					"skills": 		["1", "2"],
					"jobs": 	["1", "2"]
				},

				"skills": [{
					"id": "1",
					"title": "Javascript",
					"duration": 3
				},{
					"id": "2",
					"title": "Design Patterns",
					"duration": 3
				},{
					"id": "3",
					"title": "Handlebars",
					"duration": 2.5
				},{
					"id": "4",
					"title": "Ember JS",
					"duration": 1
				},{
					"id": "5",
					"title": "Ember Data",
					"duration": 1
				},{
					"id": "6",
					"title": "Node JS",
					"duration": 1
				},{
					"id": "7",
					"title": "Express JS",
					"duration": 1
				},{
					"id": "10",
					"title": "Sails JS",
					"duration": 0.5
				},{
					"id": "9",
					"title": "Require JS",
					"duration": 1
				},{
					"id": "8",
					"title": "Grunt",
					"duration": 1
				}],

				"jobs": [{
					"id": "1",
					"position": "Javascript Developer",
					"company": "Qualified (part of Kaplan)",
					"startDate": "August, 2013",
					"endDate": "March, 2014",
					"description": "This group inside of Kaplan was building an application using Ember JS with Ember Data on top of a Node top tier server.  I used these technologies and more to build a powerful application.  We practiced the Scrum methodology and I served as our team's Scrum Master.  ",
					"skills": ["1", "2", "3", "4", "5", "6", "7", "8", "9"]

				},{
					"id": "2",
					"position": "Front End Developer",
					"company": "Tribune Inc.",
					"startDate": "January, 2013",
					"endDate": "August, 2013",
					"description": "This is a job description",

				},{
					"id": "3",
					"position": "Front End Developer",
					"company": "Sears Holdings",
					"startDate": "August, 2012",
					"endDate": "January, 2013",
					"description": "This is a job description",

				},{
					"id": "4",
					"position": "Web Developer",
					"company": "C|Change Inc.",
					"startDate": "July, 2011",
					"endDate": "August, 2012",
					"description": "This is a job description",

				},{
					"id": "5",
					"position": "Graphic Designer",
					"company": "AlphaMetrix LLC",
					"startDate": "December, 2009",
					"endDate": "July, 2011",
					"description": "This is a job description",

				}]
			}

			res.send(profile);
		});

		server.get('/sections/', function(req, res) {
			var sections = {
				"sections": [{
					"id": "1",
					"title": "Javascript",
					"description": "
My focus this last year has been Ember application development.  This MVVM framework is arguably the best for team based application development.

I've also worked with Node, Express, Grunt, and Ember App Kit.  These powerful serverside tools are baked into my preferred build processes.
",
					"skills": ["1", "2", "3", "4", "5", "6", "7", "8", "9"],
					"jobs": ["1", "2"]

				},{
					"id": "2",
					"title": "UI",
					"description": "
My focus this last year has been Ember application development.  This MVVM framework is arguably the best for team based application development.

I've also worked with Node, Express, Grunt, and Ember App Kit.  These powerful serverside tools are baked into my preferred build processes.
",
					"skills": ["1", "2", "3", "4", "5", "6", "7", "8", "9"],
					"jobs": ["1", "2"]

				}]
			}

			res.send(sections);
		});

	});

};<commit_msg>skill added<commit_after>module.exports = function(server) {

  // Create an API namespace, so that the root does not
  // have to be repeated for each end point.
	server.namespace('/api', function() {

		// Return fixture data for '/api/profile/:id'
		server.get('/profiles/:id', function(req, res) {
			var profile = {
				"profile": {
					"id": 			1,
					"name": 		"Jim Hall",
					"skills": 		["1", "2"],
					"jobs": 	["1", "2"]
				},

				"skills": [{
					"id": "1",
					"title": "Javascript",
					"duration": 3
				},{
					"id": "2",
					"title": "Design Patterns",
					"duration": 3
				},{
					"id": "3",
					"title": "Handlebars",
					"duration": 2.5
				},{
					"id": "4",
					"title": "Ember JS",
					"duration": 1
				},{
					"id": "5",
					"title": "Ember Data",
					"duration": 1
				},{
					"id": "6",
					"title": "Node JS",
					"duration": 1
				},{
					"id": "7",
					"title": "Express JS",
					"duration": 1
				},{
					"id": "10",
					"title": "Sails JS",
					"duration": 0.5
				},{
					"id": "9",
					"title": "Require JS",
					"duration": 1
				},{
					"id": "8",
					"title": "Grunt",
					"duration": 1
				},{
					"id": "9",
					"title": "Git",
					"duration": 2
				}],

				"jobs": [{
					"id": "1",
					"position": "Javascript Developer",
					"company": "Qualified (part of Kaplan)",
					"startDate": "August, 2013",
					"endDate": "March, 2014",
					"description": "This group inside of Kaplan was building an application using Ember JS with Ember Data on top of a Node top tier server.  I used these technologies and more to build a powerful application.  We practiced the Scrum methodology and I served as our team's Scrum Master.  ",
					"skills": ["1", "2", "3", "4", "5", "6", "7", "8", "9"]

				},{
					"id": "2",
					"position": "Front End Developer",
					"company": "Tribune Inc.",
					"startDate": "January, 2013",
					"endDate": "August, 2013",
					"description": "This is a job description",

				},{
					"id": "3",
					"position": "Front End Developer",
					"company": "Sears Holdings",
					"startDate": "August, 2012",
					"endDate": "January, 2013",
					"description": "This is a job description",

				},{
					"id": "4",
					"position": "Web Developer",
					"company": "C|Change Inc.",
					"startDate": "July, 2011",
					"endDate": "August, 2012",
					"description": "This is a job description",

				},{
					"id": "5",
					"position": "Graphic Designer",
					"company": "AlphaMetrix LLC",
					"startDate": "December, 2009",
					"endDate": "July, 2011",
					"description": "This is a job description",

				}]
			}

			res.send(profile);
		});

		server.get('/sections/', function(req, res) {
			var sections = {
				"sections": [{
					"id": "1",
					"title": "Javascript",
					"description": "
My focus this last year has been Ember application development.  This MVVM framework is arguably the best for team based application development.

I've also worked with Node, Express, Grunt, and Ember App Kit.  These powerful serverside tools are baked into my preferred build processes.
",
					"skills": ["1", "2", "3", "4", "5", "6", "7", "8", "9"],
					"jobs": ["1", "2"]

				},{
					"id": "2",
					"title": "UI",
					"description": "
My focus this last year has been Ember application development.  This MVVM framework is arguably the best for team based application development.

I've also worked with Node, Express, Grunt, and Ember App Kit.  These powerful serverside tools are baked into my preferred build processes.
",
					"skills": ["1", "2", "3", "4", "5", "6", "7", "8", "9"],
					"jobs": ["1", "2"]

				}]
			}

			res.send(sections);
		});

	});

};<|endoftext|>


<commit_before>var util = require('util');
var DocsParser = require("../docsparser");
var xregexp = require('../xregexp').XRegExp;

function JsParser(settings) {
    // this.setup_settings();
    // call parent constructor
    DocsParser.call(this, settings);
}

JsParser.prototype = Object.create(DocsParser.prototype);

JsParser.prototype.setup_settings = function() {
    var identifier = '[a-zA-Z_$][a-zA-Z_$0-9]*';
    this.settings = {
        // curly brackets around the type information
        'curlyTypes': true,
        'typeInfo': true,
        'typeTag': 'type',
        // technically, they can contain all sorts of unicode, but w/e
        'varIdentifier': identifier,
        'fnIdentifier':  identifier,
        'fnOpener': 'function(?:\\s+' + identifier + ')?\\s*\\(',
        'commentCloser': ' */',
        'bool': 'Boolean',
        'function': 'Function'
    };
};

JsParser.prototype.parse_function = function(line) {
    // single quotes indicate what will be matched in each line
    var preFunction = '^' +
        // '  'var foo = function bar (baz, quaz) {}
        '\\s*' +
        '(?:export\\s+)?(?:default\\s+)?' +
        //   'var 'foo = function bar (baz, quaz) {}
        '(?:(?:var|let|const)\\s+)?' +
        '(?:' +
            //   var 'bar.prototype.'foo = function bar (baz, quaz) {}
            '(?:[a-zA-Z_$][a-zA-Z_$0-9.]*\\.)?' +
            //   var 'foo = 'function bar (baz, quaz) {}
            '(?P<name1>' + this.settings.varIdentifier + ')\\s*[:=]\\s*' +
        ')?';

    var functionRegex = xregexp(
        preFunction +
        // modifiers: static, async
        '(?:static\\s+)?(?P<promise>async\\s+)?' +
        //   var foo = 'function 'bar (baz, quaz) {}
        '(?:function(:?\\s*\\*)?|get|set)\\s*' +
        //   var foo = function 'bar '(baz, quaz) {}
        '(?:\\s+(?P<name2>' + this.settings.fnIdentifier + '))?\\s*' +
        //   var foo = function bar '(baz, quaz)' {}
        '\\(\\s*(?P<args>.*?)\\)'
    );

    var arrowFunctionRegex = xregexp(
        preFunction +
        '(?P<promise>async\\s+)?' +
        '(?:'+
            //   var foo = 'bar' => {}
            '(?P<arg>' + this.settings.varIdentifier + ')' +
            '|' +
            //   var foo = '(bar, baz)' => {}
            '\\(\\s*(?P<args>.*?)\\)' +
        ')\\s*' +
        //   var foo = bar '=>' {}
        '=>\\s*'
    );

    var functionMatches = xregexp.exec(line, functionRegex);
    var arrowFunctionMatches = xregexp.exec(line, arrowFunctionRegex);
    var matches = functionMatches || arrowFunctionMatches;

    if(matches === null) {
        return null;
    }
    // grab the name out of "name1 = function name2(foo)" preferring name1
    var name = matches.name1 || matches.name2 || '';
    var args = matches.args || matches.arg || null;

    // check for async method to set retval to promise
    var retval = matches.promise !== undefined ? 'Promise' : null;
    return [name, args, retval];
};

JsParser.prototype.parse_var = function(line) {
        //   var foo = blah,
        //       foo = blah;
        //   baz.foo = blah;
        //   baz = {
        //        foo : blah
        //   }
    var regex = xregexp('(?P<name>' + this.settings.varIdentifier + ')\\s*[=:]\\s*(?P<val>.*?)(?:[;,]|$)');
    var matches = xregexp.exec(line, regex);
    if(matches === null) {
        return null;
    }
    // variable name, variable value
    return [matches.name, matches.val.trim()];
};

JsParser.prototype.parse_arg = function(arg) {

    var regex = xregexp(
        '(?P<name>' + this.settings.varIdentifier + ')(\\s*=\\s*(?P<value>.*))?'
    );

    return xregexp.exec(arg, regex);
};

JsParser.prototype.get_arg_type = function(arg) {

    var matches = this.parse_arg(arg);

    if(matches && matches.value) {
        return this.guess_type_from_value(matches.value);
    }

    return null;
};

JsParser.prototype.get_arg_name = function(arg) {

    var matches = this.parse_arg(arg);

    if (matches.value) {
      return util.format('[%s=%s]', matches.name, matches.value);
    }

    return matches.name;
};

JsParser.prototype.guess_type_from_value = function(val) {
    var lower_primitives = this.editor_settings.lower_case_primitives || false;
    var short_primitives = this.editor_settings.short_primitives || false;
    var var_type;
    var capitalize = function(str) {
        return str.charAt(0).toUpperCase() + str.slice(1);
    };
    if(this.is_numeric(val)) {
        var_type = 'number';
        return (lower_primitives ? var_type : capitalize(var_type));
    }
    if((val[0] === '\'') || (val[0] === '"')) {
        var_type = 'string';
        return (lower_primitives ? var_type : capitalize(var_type));
    }
    if(val[0] === '[') {
        return 'Array';
    }
    if(val[0] === '{') {
        return 'Object';
    }
    if((val === 'true') || (val === 'false')) {
        var ret_val = (short_primitives ? 'Bool' : 'Boolean');
        return (lower_primitives ? ret_val : capitalize(ret_val));
    }
    var regex = new RegExp('^RegExp|^\\/[^/*].*\\/$');
    if(regex.test(val)) {
        return 'RegExp';
    }
    if(val.slice(0, 4) === 'new ') {
        regex = new RegExp('new (' + this.settings.fnIdentifier + ')');
        var matches = regex.exec(val);
        return (matches[0] && matches[1]) || null;
    }
    return null;
};

JsParser.prototype.get_function_return_type = function(name, retval) {
    if(retval) {
      return retval;
    }
    return DocsParser.prototype.get_function_return_type.call(this, name, retval);
};

module.exports = JsParser;
<commit_msg>Add support for immediately returned JS closures<commit_after>var util = require('util');
var DocsParser = require("../docsparser");
var xregexp = require('../xregexp').XRegExp;

function JsParser(settings) {
    // this.setup_settings();
    // call parent constructor
    DocsParser.call(this, settings);
}

JsParser.prototype = Object.create(DocsParser.prototype);

JsParser.prototype.setup_settings = function() {
    var identifier = '[a-zA-Z_$][a-zA-Z_$0-9]*';
    this.settings = {
        // curly brackets around the type information
        'curlyTypes': true,
        'typeInfo': true,
        'typeTag': 'type',
        // technically, they can contain all sorts of unicode, but w/e
        'varIdentifier': identifier,
        'fnIdentifier':  identifier,
        'fnOpener': 'function(?:\\s+' + identifier + ')?\\s*\\(',
        'commentCloser': ' */',
        'bool': 'Boolean',
        'function': 'Function'
    };
};

JsParser.prototype.parse_function = function(line) {
    // single quotes indicate what will be matched in each line
    var preFunction = '^' +
        // '  'var foo = function bar (baz, quaz) {}
        '\\s*' +
        '(?:' +
            // 'return' foo = function bar (baz, quaz) {}
            'return\\s+' +
            '|' +
            // 'export default 'var foo = function bar (baz, quaz) {}
            '(?:export\\s+(?:default\\s+)?)?' +
            //  export default 'var 'foo = function bar (baz, quaz) {}
            '(?:(?:var|let|const)\\s+)?' +
        ')?' +
        '(?:' +
            //   var 'bar.prototype.'foo = function bar (baz, quaz) {}
            '(?:[a-zA-Z_$][a-zA-Z_$0-9.]*\\.)?' +
            //   var 'foo = 'function bar (baz, quaz) {}
            '(?P<name1>' + this.settings.varIdentifier + ')\\s*[:=]\\s*' +
        ')?';

    var functionRegex = xregexp(
        preFunction +
        // modifiers: static, async
        '(?:static\\s+)?(?P<promise>async\\s+)?' +
        //   var foo = 'function 'bar (baz, quaz) {}
        '(?:function(:?\\s*\\*)?|get|set)\\s*' +
        //   var foo = function 'bar '(baz, quaz) {}
        '(?:\\s+(?P<name2>' + this.settings.fnIdentifier + '))?\\s*' +
        //   var foo = function bar '(baz, quaz)' {}
        '\\(\\s*(?P<args>.*?)\\)'
    );

    var arrowFunctionRegex = xregexp(
        preFunction +
        '(?P<promise>async\\s+)?' +
        '(?:'+
            //   var foo = 'bar' => {}
            '(?P<arg>' + this.settings.varIdentifier + ')' +
            '|' +
            //   var foo = '(bar, baz)' => {}
            '\\(\\s*(?P<args>.*?)\\)' +
        ')\\s*' +
        //   var foo = bar '=>' {}
        '=>\\s*'
    );

    var functionMatches = xregexp.exec(line, functionRegex);
    var arrowFunctionMatches = xregexp.exec(line, arrowFunctionRegex);
    var matches = functionMatches || arrowFunctionMatches;

    if(matches === null) {
        return null;
    }
    // grab the name out of "name1 = function name2(foo)" preferring name1
    var name = matches.name1 || matches.name2 || '';
    var args = matches.args || matches.arg || null;

    // check for async method to set retval to promise
    var retval = matches.promise !== undefined ? 'Promise' : null;
    return [name, args, retval];
};

JsParser.prototype.parse_var = function(line) {
        //   var foo = blah,
        //       foo = blah;
        //   baz.foo = blah;
        //   baz = {
        //        foo : blah
        //   }
    var regex = xregexp('(?P<name>' + this.settings.varIdentifier + ')\\s*[=:]\\s*(?P<val>.*?)(?:[;,]|$)');
    var matches = xregexp.exec(line, regex);
    if(matches === null) {
        return null;
    }
    // variable name, variable value
    return [matches.name, matches.val.trim()];
};

JsParser.prototype.parse_arg = function(arg) {

    var regex = xregexp(
        '(?P<name>' + this.settings.varIdentifier + ')(\\s*=\\s*(?P<value>.*))?'
    );

    return xregexp.exec(arg, regex);
};

JsParser.prototype.get_arg_type = function(arg) {

    var matches = this.parse_arg(arg);

    if(matches && matches.value) {
        return this.guess_type_from_value(matches.value);
    }

    return null;
};

JsParser.prototype.get_arg_name = function(arg) {

    var matches = this.parse_arg(arg);

    if (matches.value) {
      return util.format('[%s=%s]', matches.name, matches.value);
    }

    return matches.name;
};

JsParser.prototype.guess_type_from_value = function(val) {
    var lower_primitives = this.editor_settings.lower_case_primitives || false;
    var short_primitives = this.editor_settings.short_primitives || false;
    var var_type;
    var capitalize = function(str) {
        return str.charAt(0).toUpperCase() + str.slice(1);
    };
    if(this.is_numeric(val)) {
        var_type = 'number';
        return (lower_primitives ? var_type : capitalize(var_type));
    }
    if((val[0] === '\'') || (val[0] === '"')) {
        var_type = 'string';
        return (lower_primitives ? var_type : capitalize(var_type));
    }
    if(val[0] === '[') {
        return 'Array';
    }
    if(val[0] === '{') {
        return 'Object';
    }
    if((val === 'true') || (val === 'false')) {
        var ret_val = (short_primitives ? 'Bool' : 'Boolean');
        return (lower_primitives ? ret_val : capitalize(ret_val));
    }
    var regex = new RegExp('^RegExp|^\\/[^/*].*\\/$');
    if(regex.test(val)) {
        return 'RegExp';
    }
    if(val.slice(0, 4) === 'new ') {
        regex = new RegExp('new (' + this.settings.fnIdentifier + ')');
        var matches = regex.exec(val);
        return (matches[0] && matches[1]) || null;
    }
    return null;
};

JsParser.prototype.get_function_return_type = function(name, retval) {
    if(retval) {
      return retval;
    }
    return DocsParser.prototype.get_function_return_type.call(this, name, retval);
};

module.exports = JsParser;
<|endoftext|>