<commit_before>/*
 *
 * AddMustPage
 *
 */

import React, { PropTypes } from 'react';
import { connect } from 'react-redux';

import { FormattedMessage } from 'react-intl';
import { Field, reduxForm } from 'redux-form/immutable';
import RaisedButton from 'material-ui/RaisedButton';
import FlatButton from 'material-ui/FlatButton';
import { AutoComplete } from 'redux-form-material-ui';
import { onSubmitActions } from 'redux-form-submit-saga/immutable';
import { fromJS } from 'immutable';
import Page from 'components/Page';
import { Row, Col } from 'react-bem-grid';
import { Card, CardTitle, CardText } from 'material-ui/Card';
import TranslatedAutoComplete from 'components/TranslatedAutoComplete';
import TranslatedDatePicker, { ERRORS as DATE_ERRORS } from 'components/TranslatedDatePicker';
import TranslatedTimePicker from 'components/TranslatedTimePicker';
import TranslatedValidationField, { ERRORS as TEXT_ERRORS } from 'components/TranslatedValidationField';
import { red900 } from 'material-ui/styles/colors';
import { getEarliestDate, ensureTime, combineDateTime } from 'utils/time';

import areIntlLocalesSupported from 'intl-locales-supported';

import { ADD_MUST } from './constants';
import { loadBrands, loadRules } from './actions';
import messages from './messages';
import selectAddMustPage from './selectors';

let DateTimeFormat;

/**
 * Use the native Intl.DateTimeFormat if available, or a polyfill if not.
 */
if (areIntlLocalesSupported(['sv', 'sv-SE'])) {
  DateTimeFormat = global.Intl.DateTimeFormat;
} else {
  const IntlPolyfill = require('intl'); // eslint-disable-line global-require
  DateTimeFormat = IntlPolyfill.DateTimeFormat;
  require('intl/locale-data/jsonp/sv'); // eslint-disable-line global-require
  require('intl/locale-data/jsonp/sv-SE'); // eslint-disable-line global-require
}

function renderError(error) {
  const styles = {
    loginError: {
      color: red900,
    },
  };
  const message = messages[error] || messages[500];
  return (<FormattedMessage {...message} />);
}

export class AddMustPage extends React.Component { // eslint-disable-line react/prefer-stateless-function
  static propTypes = {
    handleSubmit: PropTypes.func,
    pristine: PropTypes.bool,
    submitting: PropTypes.bool,
    reset: PropTypes.func,
    brands: PropTypes.array,
    rules: PropTypes.shape({
      startDate: PropTypes.object,
      endDate: PropTypes.object,
    }),
    error: PropTypes.string,
    defaultDate: PropTypes.object,
    getRules: PropTypes.func.isRequired,
    getBrands: PropTypes.func.isRequired,
  };

  static defaultProps = {
    brands: [],
    rules: {
      startDate: new Date('2016-11-01'),
      endDate: new Date('2016-12-20'),
    },
    defaultDate: new Date(),
  }

  componentDidMount() {
    this.props.getRules();
    this.props.getBrands();
  }

  render() {
    const {
      handleSubmit,
      pristine,
      reset,
      submitting,
      brands,
      rules: {
        startDate,
        endDate,
        minAmount,
        maxAmount,
      },
      error,
      defaultDate,
    } = this.props;
    const maxDate = getEarliestDate(new Date(), endDate);
    return (
      <Page messages={messages}>
        <Row xsCenter>
          <Col md={6} >
            <Card>
              <CardTitle title={<FormattedMessage {...messages.header} />} />
              <CardText>
                <form onSubmit={handleSubmit} noValidate>
                  {error && renderError(error)}

                    <Field
                      name="brand"
                      maxSearchResults={6}
                      filter={AutoComplete.fuzzyFilter}
                      dataSource={brands.map((brand) => (brand.name))}
                      component={TranslatedAutoComplete}
                      hintText="Apotekarnes"
                      floatingLabelText={<FormattedMessage {...messages.brand} />}
                    />

                    <Field
                      name="amount"
                      component={TranslatedValidationField}
                      step={0.1}
                      min={minAmount}
                      max={maxAmount}
                      type="number"
                      hintText="0.33"
                      floatingLabelText={<FormattedMessage {...messages.amount} />}
                    />

                    <Field
                      name="date"
                      disableYearSelection
                      component={TranslatedDatePicker}
                      hintText="Data"
                      autoOk
                      floatingLabelText={<FormattedMessage {...messages.date} />}
                      DateTimeFormat={DateTimeFormat}
                      locale="sv-SE"
                      okLabel={<FormattedMessage {...messages.ok} />}
                      cancelLabel={<FormattedMessage {...messages.cancel} />}
                      minDate={startDate}
                      maxDate={maxDate}
                      defaultDate={defaultDate}
                    />

                    <Field
                      name="time"
                      component={TranslatedTimePicker}
                      hintText="Data"
                      autoOk
                      floatingLabelText={<FormattedMessage {...messages.time} />}
                      okLabel={<FormattedMessage {...messages.ok} />}
                      cancelLabel={<FormattedMessage {...messages.cancel} />}
                      defaultTime={defaultDate}
                    />

                    <FlatButton
                      label={<FormattedMessage {...messages.resetForm} />}
                      secondary
                      onTouchTap={reset}
                    />
                    <RaisedButton type="submit" primary disabled={pristine || submitting} label={<FormattedMessage {...messages.submitForm} />} />

                </form>
              </CardText>
            </Card>
          </Col>
        </Row>
      </Page>
    );
  }
}

function validate(values, props) {
  const { rules } = props;
  const normalValues = values.toJS();
  const errors = {};
  const requiredFields = ['brand', 'amount', 'date', 'time'];
  requiredFields.forEach((field) => {
    if (!normalValues[field]) {
      errors[field] = TEXT_ERRORS.REQUIRED;
    }
  });
  if (Object.keys(rules).length) {
    if (normalValues.amount > rules.maxAmount) {
      errors.amount = TEXT_ERRORS.TOO_MUCH;
    }

    if (normalValues.amount < rules.minAmount) {
      errors.amount = TEXT_ERRORS.TOO_LITTLE;
    }
    const dateError = validateDate(normalValues.date, normalValues.time, rules);
    if (dateError) {
      errors.date = dateError;
      errors.time = dateError;
    }
  }

  return errors;
}

const validateDate = (date, time, rules) => {
  const dateClone = new Date(date);
  const newTime = ensureTime(time);
  const newDate = combineDateTime(dateClone, newTime);

  const maxDate = getEarliestDate(new Date(), rules.endDate);
  if (newDate.getTime() > maxDate.getTime()) {
    return DATE_ERRORS.TOO_LATE;
  }
  if (newDate.getTime() < rules.startDate.getTime()) {
    return DATE_ERRORS.TOO_EARLY;
  }
  return undefined;
};

const mapStateToProps = selectAddMustPage();

function mapDispatchToProps(dispatch) {
  return {
    getBrands: () => dispatch(loadBrands()),
    getRules: () => dispatch(loadRules()),
    dispatch,
  };
}

const AddMustFormPage = reduxForm({
  form: 'add',
  validate,
  onSubmit: onSubmitActions(ADD_MUST),
  initialValues: fromJS({
    date: new Date(),
    time: new Date(),
  }),
})(AddMustPage);

const connectedAddMustPage = connect(mapStateToProps, mapDispatchToProps)(AddMustFormPage);

export default connectedAddMustPage;
<commit_msg>Step size 0.01<commit_after>/*
 *
 * AddMustPage
 *
 */

import React, { PropTypes } from 'react';
import { connect } from 'react-redux';

import { FormattedMessage } from 'react-intl';
import { Field, reduxForm } from 'redux-form/immutable';
import RaisedButton from 'material-ui/RaisedButton';
import FlatButton from 'material-ui/FlatButton';
import { AutoComplete } from 'redux-form-material-ui';
import { onSubmitActions } from 'redux-form-submit-saga/immutable';
import { fromJS } from 'immutable';
import Page from 'components/Page';
import { Row, Col } from 'react-bem-grid';
import { Card, CardTitle, CardText } from 'material-ui/Card';
import TranslatedAutoComplete from 'components/TranslatedAutoComplete';
import TranslatedDatePicker, { ERRORS as DATE_ERRORS } from 'components/TranslatedDatePicker';
import TranslatedTimePicker from 'components/TranslatedTimePicker';
import TranslatedValidationField, { ERRORS as TEXT_ERRORS } from 'components/TranslatedValidationField';
import { red900 } from 'material-ui/styles/colors';
import { getEarliestDate, ensureTime, combineDateTime } from 'utils/time';

import areIntlLocalesSupported from 'intl-locales-supported';

import { ADD_MUST } from './constants';
import { loadBrands, loadRules } from './actions';
import messages from './messages';
import selectAddMustPage from './selectors';

let DateTimeFormat;

/**
 * Use the native Intl.DateTimeFormat if available, or a polyfill if not.
 */
if (areIntlLocalesSupported(['sv', 'sv-SE'])) {
  DateTimeFormat = global.Intl.DateTimeFormat;
} else {
  const IntlPolyfill = require('intl'); // eslint-disable-line global-require
  DateTimeFormat = IntlPolyfill.DateTimeFormat;
  require('intl/locale-data/jsonp/sv'); // eslint-disable-line global-require
  require('intl/locale-data/jsonp/sv-SE'); // eslint-disable-line global-require
}

function renderError(error) {
  const styles = {
    loginError: {
      color: red900,
    },
  };
  const message = messages[error] || messages[500];
  return (<FormattedMessage {...message} />);
}

export class AddMustPage extends React.Component { // eslint-disable-line react/prefer-stateless-function
  static propTypes = {
    handleSubmit: PropTypes.func,
    pristine: PropTypes.bool,
    submitting: PropTypes.bool,
    reset: PropTypes.func,
    brands: PropTypes.array,
    rules: PropTypes.shape({
      startDate: PropTypes.object,
      endDate: PropTypes.object,
    }),
    error: PropTypes.string,
    defaultDate: PropTypes.object,
    getRules: PropTypes.func.isRequired,
    getBrands: PropTypes.func.isRequired,
  };

  static defaultProps = {
    brands: [],
    rules: {
      startDate: new Date('2016-11-01'),
      endDate: new Date('2016-12-20'),
    },
    defaultDate: new Date(),
  }

  componentDidMount() {
    this.props.getRules();
    this.props.getBrands();
  }

  render() {
    const {
      handleSubmit,
      pristine,
      reset,
      submitting,
      brands,
      rules: {
        startDate,
        endDate,
        minAmount,
        maxAmount,
      },
      error,
      defaultDate,
    } = this.props;
    const maxDate = getEarliestDate(new Date(), endDate);
    return (
      <Page messages={messages}>
        <Row xsCenter>
          <Col md={6} >
            <Card>
              <CardTitle title={<FormattedMessage {...messages.header} />} />
              <CardText>
                <form onSubmit={handleSubmit} noValidate>
                  {error && renderError(error)}

                    <Field
                      name="brand"
                      maxSearchResults={6}
                      filter={AutoComplete.fuzzyFilter}
                      dataSource={brands.map((brand) => (brand.name))}
                      component={TranslatedAutoComplete}
                      hintText="Apotekarnes"
                      floatingLabelText={<FormattedMessage {...messages.brand} />}
                    />

                    <Field
                      name="amount"
                      component={TranslatedValidationField}
                      step={0.01}
                      min={minAmount}
                      max={maxAmount}
                      type="number"
                      hintText="0.33"
                      floatingLabelText={<FormattedMessage {...messages.amount} />}
                    />

                    <Field
                      name="date"
                      disableYearSelection
                      component={TranslatedDatePicker}
                      hintText="Data"
                      autoOk
                      floatingLabelText={<FormattedMessage {...messages.date} />}
                      DateTimeFormat={DateTimeFormat}
                      locale="sv-SE"
                      okLabel={<FormattedMessage {...messages.ok} />}
                      cancelLabel={<FormattedMessage {...messages.cancel} />}
                      minDate={startDate}
                      maxDate={maxDate}
                      defaultDate={defaultDate}
                    />

                    <Field
                      name="time"
                      component={TranslatedTimePicker}
                      hintText="Data"
                      autoOk
                      floatingLabelText={<FormattedMessage {...messages.time} />}
                      okLabel={<FormattedMessage {...messages.ok} />}
                      cancelLabel={<FormattedMessage {...messages.cancel} />}
                      defaultTime={defaultDate}
                    />

                    <FlatButton
                      label={<FormattedMessage {...messages.resetForm} />}
                      secondary
                      onTouchTap={reset}
                    />
                    <RaisedButton type="submit" primary disabled={pristine || submitting} label={<FormattedMessage {...messages.submitForm} />} />

                </form>
              </CardText>
            </Card>
          </Col>
        </Row>
      </Page>
    );
  }
}

function validate(values, props) {
  const { rules } = props;
  const normalValues = values.toJS();
  const errors = {};
  const requiredFields = ['brand', 'amount', 'date', 'time'];
  requiredFields.forEach((field) => {
    if (!normalValues[field]) {
      errors[field] = TEXT_ERRORS.REQUIRED;
    }
  });
  if (Object.keys(rules).length) {
    if (normalValues.amount > rules.maxAmount) {
      errors.amount = TEXT_ERRORS.TOO_MUCH;
    }

    if (normalValues.amount < rules.minAmount) {
      errors.amount = TEXT_ERRORS.TOO_LITTLE;
    }
    const dateError = validateDate(normalValues.date, normalValues.time, rules);
    if (dateError) {
      errors.date = dateError;
      errors.time = dateError;
    }
  }

  return errors;
}

const validateDate = (date, time, rules) => {
  const dateClone = new Date(date);
  const newTime = ensureTime(time);
  const newDate = combineDateTime(dateClone, newTime);

  const maxDate = getEarliestDate(new Date(), rules.endDate);
  if (newDate.getTime() > maxDate.getTime()) {
    return DATE_ERRORS.TOO_LATE;
  }
  if (newDate.getTime() < rules.startDate.getTime()) {
    return DATE_ERRORS.TOO_EARLY;
  }
  return undefined;
};

const mapStateToProps = selectAddMustPage();

function mapDispatchToProps(dispatch) {
  return {
    getBrands: () => dispatch(loadBrands()),
    getRules: () => dispatch(loadRules()),
    dispatch,
  };
}

const AddMustFormPage = reduxForm({
  form: 'add',
  validate,
  onSubmit: onSubmitActions(ADD_MUST),
  initialValues: fromJS({
    date: new Date(),
    time: new Date(),
  }),
})(AddMustPage);

const connectedAddMustPage = connect(mapStateToProps, mapDispatchToProps)(AddMustFormPage);

export default connectedAddMustPage;
<|endoftext|>


<commit_before>import { take, call, put, fork, cancel } from 'redux-saga/effects';
import { takeLatest } from 'redux-saga';
import { LOCATION_CHANGE } from 'react-router-redux';
import { getBrands, getRules, sendDrink } from './add';
import {
  ADD_MUST_SUBMIT,
  GET_RULES,
  GET_BRANDS,
} from './constants';

import {
  mustAdded,
  mustAddedError,
  rulesLoaded,
  rulesLoadingError,
  brandsLoaded,
  brandsLoadingError,
} from './actions';

function* addMustSaga(action) {
  try {
    const payload = yield call(sendDrink, action.payload);
    yield put(mustAdded(payload));
  } catch (error) {
    yield put(mustAddedError(error));
  }
}

export function* watchAddMustSaga() {
  yield* takeLatest(ADD_MUST_SUBMIT, addMustSaga);
}

function* getRulesSaga() {
  try {
    const payload = yield call(getRules);
    yield put(rulesLoaded(payload));
  } catch (error) {
    yield* put(rulesLoadingError(error));
  }
}

export function* watchGetRulesSaga() {
  yield* takeLatest(GET_RULES, getRulesSaga);
}

function* getBrandsSaga() {
  try {
    const payload = yield call(getBrands);
    yield put(brandsLoaded(payload));
  } catch (error) {
    yield* put(brandsLoadingError(error));
  }
}

export function* watchGetBrandsSaga() {
  yield* takeLatest(GET_BRANDS, getBrandsSaga);
}

export function* root() {
  const watcherAdd = yield fork(watchAddMustSaga);
  const watcherBrands = yield fork(watchGetBrandsSaga);
  const watcherRules = yield fork(watchGetRulesSaga);
  yield take(LOCATION_CHANGE);
  yield cancel(watcherAdd);
  yield cancel(watcherBrands);
  yield cancel(watcherRules);
}

export default [
  root,
];
<commit_msg>Navigating away on add must success<commit_after>import { take, call, put, fork, cancel } from 'redux-saga/effects';
import { takeLatest } from 'redux-saga';
import { LOCATION_CHANGE } from 'react-router-redux';
import { browserHistory } from 'react-router';
import { getBrands, getRules, sendDrink } from './add';
import {
  ADD_MUST_SUBMIT,
  ADD_MUST_SUCCESS,
  GET_RULES,
  GET_BRANDS,
} from './constants';

import {
  mustAdded,
  mustAddedError,
  rulesLoaded,
  rulesLoadingError,
  brandsLoaded,
  brandsLoadingError,
} from './actions';

function* addMustSaga(action) {
  try {
    const payload = yield call(sendDrink, action.payload);
    yield put(mustAdded(payload));
  } catch (error) {
    yield put(mustAddedError(error));
  }
}

export function* watchAddMustSaga() {
  yield* takeLatest(ADD_MUST_SUBMIT, addMustSaga);
}

export function* watchMustAddedSaga() {
  yield* takeLatest(ADD_MUST_SUCCESS, () => forwardTo('/'));
}

function* getRulesSaga() {
  try {
    const payload = yield call(getRules);
    yield put(rulesLoaded(payload));
  } catch (error) {
    yield* put(rulesLoadingError(error));
  }
}

export function* watchGetRulesSaga() {
  yield* takeLatest(GET_RULES, getRulesSaga);
}

function* getBrandsSaga() {
  try {
    const payload = yield call(getBrands);
    yield put(brandsLoaded(payload));
  } catch (error) {
    yield* put(brandsLoadingError(error));
  }
}

export function* watchGetBrandsSaga() {
  yield* takeLatest(GET_BRANDS, getBrandsSaga);
}

export function* root() {
  const watcherAdd = yield fork(watchAddMustSaga);
  const watcherBrands = yield fork(watchGetBrandsSaga);
  const watcherRules = yield fork(watchGetRulesSaga);
  const watcherMustAdded = yield fork(watchMustAddedSaga);
  yield take(LOCATION_CHANGE);
  yield cancel(watcherAdd);
  yield cancel(watcherBrands);
  yield cancel(watcherRules);
  yield cancel(watcherMustAdded);
}

function forwardTo(location) {
  browserHistory.push(location);
}

export default [
  root,
];
<|endoftext|>


<commit_before>/*
---

script: Styles.js

description: Set, get and render different kind of styles on widget

license: Public domain (http://unlicense.org).

authors: Yaroslaff Fedin

requires:
  - LSD.Module
  - Core/Element.Style
  - Ext/FastArray
  - Sheet/SheetParser.Styles

provides:
  - LSD.Module.Styles

...
*/

!function() {

var CSS = SheetParser.Styles, Paint = LSD.Styles;
var setStyle = function(element, property, value, type) {
  delete this.style.expressed[property];
  delete this.style.calculated[property];
  if (value === false) {
    if (element && this.element) delete this.element.style[property];
    delete this.style[element ? 'element' : 'paint'][property], delete this.style.current[property];
    if (type) delete this.style[type][property];
  } else {
    if (element && this.element) this.element.style[property] = (typeof value == 'number') ? value + 'px' : value;
    this.style[element ? 'element' : 'paint'][property] = this.style.current[property] = value;
    if (type) this.style[type][property] = value;
  }
}

LSD.Module.Styles = new Class({
  initializers: {
    style: function() {
      this.rules = [];
      this.style = {
        current: {},    //styles that widget currently has
        found: {},      //styles that were found in stylesheets
        given: {},      //styles that were manually assigned

        changed: {},    //styles that came from stylesheet since last render
        calculated: {}, //styles that are calculated in runtime
        computed: {},   //styles that are already getStyled
        expressed: {},  //styles that are expressed through function
        implied: {},    //styles that are assigned by environment

        element: {},    //styles that are currently assigned to element
        paint: {}       //styles that are currently used to paint
      };
      return {
        events: {
          update: function() {
            this.style.calculated = {};
            this.style.computed = {};
          }
        }
      }
    }
  },

  setStyle: function(property, value) {
    var paint, css;
    if (!(paint = Paint[property]) && !(css = CSS[property])) return false;
    var length = arguments.length;
    if (length > 2) {
      if (arguments[length - 1] in this.style) var type = arguments[--length];
      if (length > 2) value = Array.prototype.splice.call(arguments, 1, length);
    }
    if (value.call) {
      var expression = value;
      value = value.call(this, property);
    }
    var result = (css || paint)[value.push ? 'apply' : 'call'](this, value);
    if (result === true || result === false) setStyle.call(this, css, property, value, type);
    else for (var prop in result) setStyle.call(this, css, prop, result[prop], type);
    if (expression) {
      this.style.expressed[property] = expression
      this.style.computed[property] = value
    }
    return result;
  },

  setStyles: function(style, type) {
    for (var key in style) this.setStyle(key, style[key], type)
  },

  getStyle: function(property) {
    if (this.style.computed[property]) return this.style.computed[property];
    var value;
    var definition = Paint[property] || CSS[property];
    if (!definition) return;
    if (definition.properties) return definition.properties.map(this.getStyle.bind(this));
    var expression = this.style.expressed[property];
    if (expression) {
      value = this.style.current[property] = this.calculateStyle(property, expression);
    } else {
      value = this.style.current[property];
      if (property == 'height') {
        if (typeof value !== 'number') value = this.getClientHeight();
      } else if (property == 'width') {
        if (typeof value !== 'number') value = this.getClientWidth();
      } else {
        if (value == "inherit") value = this.inheritStyle(property);
        if (value == "auto") value = this.calculateStyle(property);
      }
    }
    this.style.computed[property] = value;
    return value;
  },

  getStyles: function(properties) {
    var result = {};
    for (var i = 0, property, args = arguments; property = args[i++];) result[property] = this.getStyle(property);
    return result;
  },

  renderStyles: function(styles) {
    var style = this.style,
        current = style.current,
        paint = style.paint,
        element = style.element,
        found = style.found,
        implied = style.implied,
        calculated = style.calculated,
        given = Object.append(style.given, styles),
        changed = style.changed;
    this.setStyles(given, 'given')
    for (var property in found) if ((property in changed) && !(property in given)) this.setStyle(property, found[property]);
    Object.append(style.current, style.implied);
    for (var property in element)  {
      if (!(property in given) && !(property in found) && !(property in calculated) && !(property in implied)) {
        this.element.style[property] = '';
        delete element[property]
      }
    }
    for (var property in current)  {
      if (!(property in given) && !(property in found) && !(property in calculated) && !(property in implied)) {
        delete current[property];
        delete paint[property];
      }
    }
  },

  combineRules: function(rule) {
    var rules = this.rules, style = this.style, found = style.found = {}, implied = style.implied = {}, changed = style.changed;
    for (var j = rules.length, other; other = rules[--j];) {
      var setting = other.style, implying = other.implied, self = (rule == other);
      if (setting) for (var property in setting) if (!(property in found)) {
        if (self) changed[property] = setting[property];
        found[property] = setting[property];
      }
      if (implying) for (var property in implying) if (!(property in implied)) implied[property] = implying[property];
    }
  },

  addRule: function(rule) {
    var rules = this.rules;
    if (rules.indexOf(rule) > -1) return
    for (var i = 0, other;  other = rules[i++];) {
      if ((other.specificity > rule.specificity) || ((other.specificity == rule.specificity) && (other.index > rule.index))) break;
    }
    rules.splice(--i, 0, rule);
    this.combineRules(rule);
  },

  removeRule: function(rule) {
    var rules = this.rules, index = rules.indexOf(rule)
    if (index == -1) return
    rules.splice(index, 1);
    this.combineRules();
    var style = this.style, found = style.found, changed = style.changed, setting = rule.style;
    if (setting) for (var property in setting) if (!Object.equals(found[property], setting[property])) changed[property] = found[property];
 },

  inheritStyle: function(property) {
    var node = this;
    var style = node.style.current[property];
    while ((style == 'inherit' || !style) && (node = node.parentNode)) style = node.style.current[property];
    return style;
  },

  calculateStyle: function(property, expression) {
    if (this.style.calculated[property]) return this.style.calculated[property];
    var value;
    if (expression) {
      value = expression.call(this, property);
    } else {
      switch (property) {
        case "height":
          value = this.getClientHeight();
        case "width":
          value = this.inheritStyle(property);
          if (value == "auto") value = this.getClientWidth();
        case "height": case "width":
          //if dimension size is zero, then the widget is not in DOM yet
          //so we wait until the root widget is injected, and then try to repeat
          if (value == 0 && (this.redraws == 0)) this.halt();
      }
    }
    this.style.calculated[property] = value;
    return value;
  },

  render: function(style) {
    this.renderStyles(style);
    this.parent.apply(this, arguments);
  }
});

LSD.Options.styles = {
  add: 'setStyles',
  remove: 'unsetStyles'
};
}();<commit_msg>Minor doc format<commit_after>/*
---

script: Styles.js

description: Set, get and render different kind of styles on widget

license: Public domain (http://unlicense.org).

authors: Yaroslaff Fedin

requires:
  - LSD.Module
  - Core/Element.Style
  - Ext/FastArray
  - Sheet/SheetParser.Styles

provides:
  - LSD.Module.Styles

...
*/

!function() {

var CSS = SheetParser.Styles, Paint = LSD.Styles;
var setStyle = function(element, property, value, type) {
  delete this.style.expressed[property];
  delete this.style.calculated[property];
  if (value === false) {
    if (element && this.element) delete this.element.style[property];
    delete this.style[element ? 'element' : 'paint'][property], delete this.style.current[property];
    if (type) delete this.style[type][property];
  } else {
    if (element && this.element) this.element.style[property] = (typeof value == 'number') ? value + 'px' : value;
    this.style[element ? 'element' : 'paint'][property] = this.style.current[property] = value;
    if (type) this.style[type][property] = value;
  }
}

LSD.Module.Styles = new Class({
  initializers: {
    style: function() {
      this.rules = [];
      this.style = {    // Styles that...
        current: {},    // ... widget currently has
        found: {},      // ... were found in stylesheets
        given: {},      // ... were manually assigned

        changed: {},    // ... came from stylesheet since last render
        calculated: {}, // ... are calculated in runtime
        computed: {},   // ... are already getStyled
        expressed: {},  // ... are expressed through function
        implied: {},    // ... are assigned by environment

        element: {},    // ... are currently assigned to element
        paint: {}       // ... are currently used to paint
      };
      return {
        events: {
          update: function() {
            this.style.calculated = {};
            this.style.computed = {};
          }
        }
      }
    }
  },

  setStyle: function(property, value) {
    var paint, css;
    if (!(paint = Paint[property]) && !(css = CSS[property])) return false;
    var length = arguments.length;
    if (length > 2) {
      if (arguments[length - 1] in this.style) var type = arguments[--length];
      if (length > 2) value = Array.prototype.splice.call(arguments, 1, length);
    }
    if (value.call) {
      var expression = value;
      value = value.call(this, property);
    }
    var result = (css || paint)[value.push ? 'apply' : 'call'](this, value);
    if (result === true || result === false) setStyle.call(this, css, property, value, type);
    else for (var prop in result) setStyle.call(this, css, prop, result[prop], type);
    if (expression) {
      this.style.expressed[property] = expression
      this.style.computed[property] = value
    }
    return result;
  },

  setStyles: function(style, type) {
    for (var key in style) this.setStyle(key, style[key], type)
  },

  getStyle: function(property) {
    if (this.style.computed[property]) return this.style.computed[property];
    var value;
    var definition = Paint[property] || CSS[property];
    if (!definition) return;
    if (definition.properties) return definition.properties.map(this.getStyle.bind(this));
    var expression = this.style.expressed[property];
    if (expression) {
      value = this.style.current[property] = this.calculateStyle(property, expression);
    } else {
      value = this.style.current[property];
      if (property == 'height') {
        if (typeof value !== 'number') value = this.getClientHeight();
      } else if (property == 'width') {
        if (typeof value !== 'number') value = this.getClientWidth();
      } else {
        if (value == "inherit") value = this.inheritStyle(property);
        if (value == "auto") value = this.calculateStyle(property);
      }
    }
    this.style.computed[property] = value;
    return value;
  },

  getStyles: function(properties) {
    var result = {};
    for (var i = 0, property, args = arguments; property = args[i++];) result[property] = this.getStyle(property);
    return result;
  },

  renderStyles: function(styles) {
    var style = this.style,
        current = style.current,
        paint = style.paint,
        element = style.element,
        found = style.found,
        implied = style.implied,
        calculated = style.calculated,
        given = Object.append(style.given, styles),
        changed = style.changed;
    this.setStyles(given, 'given')
    for (var property in found) if ((property in changed) && !(property in given)) this.setStyle(property, found[property]);
    Object.append(style.current, style.implied);
    for (var property in element)  {
      if (!(property in given) && !(property in found) && !(property in calculated) && !(property in implied)) {
        this.element.style[property] = '';
        delete element[property]
      }
    }
    for (var property in current)  {
      if (!(property in given) && !(property in found) && !(property in calculated) && !(property in implied)) {
        delete current[property];
        delete paint[property];
      }
    }
  },

  combineRules: function(rule) {
    var rules = this.rules, style = this.style, found = style.found = {}, implied = style.implied = {}, changed = style.changed;
    for (var j = rules.length, other; other = rules[--j];) {
      var setting = other.style, implying = other.implied, self = (rule == other);
      if (setting) for (var property in setting) if (!(property in found)) {
        if (self) changed[property] = setting[property];
        found[property] = setting[property];
      }
      if (implying) for (var property in implying) if (!(property in implied)) implied[property] = implying[property];
    }
  },

  addRule: function(rule) {
    var rules = this.rules;
    if (rules.indexOf(rule) > -1) return
    for (var i = 0, other;  other = rules[i++];) {
      if ((other.specificity > rule.specificity) || (other.specificity == rule.specificity))
        if (other.index > rule.index) break;
    }
    rules.splice(--i, 0, rule);
    this.combineRules(rule);
  },

  removeRule: function(rule) {
    var rules = this.rules, index = rules.indexOf(rule)
    if (index == -1) return
    rules.splice(index, 1);
    this.combineRules();
    var style = this.style, found = style.found, changed = style.changed, setting = rule.style;
    for (var property in setting) if (!Object.equals(found[property], setting[property])) changed[property] = found[property];
 },

  inheritStyle: function(property) {
    var node = this;
    var style = node.style.current[property];
    while ((style == 'inherit' || !style) && (node = node.parentNode)) style = node.style.current[property];
    return style;
  },

  calculateStyle: function(property, expression) {
    if (this.style.calculated[property]) return this.style.calculated[property];
    var value;
    if (expression) {
      value = expression.call(this, property);
    } else {
      switch (property) {
        case "height":
          value = this.getClientHeight();
        case "width":
          value = this.inheritStyle(property);
          if (value == "auto") value = this.getClientWidth();
        case "height": case "width":
          //if dimension size is zero, then the widget is not in DOM yet
          //so we wait until the root widget is injected, and then try to repeat
          if (value == 0 && (this.redraws == 0)) this.halt();
      }
    }
    this.style.calculated[property] = value;
    return value;
  },

  render: function(style) {
    this.renderStyles(style);
    this.parent.apply(this, arguments);
  }
});

LSD.Options.styles = {
  add: 'setStyles',
  remove: 'unsetStyles'
};
}();<|endoftext|>


<commit_before>const TEMPLATE = 'export';

var elasticsearch = require('elasticsearch'),
    exp = require('../services/ExportService'),
    mapServ = require('../services/MappingService'),
    md5 = require('md5'),
    config = require('../config');

function getFileName(query, format) {
    var dateTime = Date.now();
    return 'report-' + md5(JSON.stringify(query)) + '-' + dateTime + '.' + format;
}

function exportData(model, expSvc) {
    // scroll thru documents, save to format
    var client = new elasticsearch.Client({
        host: config.elastic.host + ':' + config.elastic.port,
        log: config.elastic.log
    });

    mapServ.getMapping(model.indexName, model.typeName)
        .then(function (fieldMap) {
            expSvc.createWriteStream(
                config.outputDirectory + model.filename,
                fieldMap
            );
            client.search({
                index: model.indexName,
                scroll: config.elastic.scrollTime,
                search_type: 'scan',
                body: model.query
            }, function getMoreUntilDone(error, response) {
                response.hits.hits.forEach(function (hit) {
                    expSvc.write(hit._source ? hit._source : hit.fields);
                });
                if (response.hits.total > expSvc.getTotal()) {
                    client.scroll({
                        scrollId: response._scroll_id,
                        scroll: config.elastic.scrollTime
                    }, getMoreUntilDone);
                } else {
                    console.log('exportData completed', expSvc.getTotal());
                    expSvc.end();
                }
            });
        }).catch(function (err) {
            console.log('exportData catch', err, model);
        });
}

function dispatchRequest(req, res) {
    var rawQuery = req.body.rawQuery,
        format = req.body.format,
        exportService = exp[format] ? exp[format]() : null,
        query = JSON.parse(rawQuery),
        model;

    model = {
        filename: getFileName(rawQuery, format),
        rawQuery: rawQuery,
        indexName: req.body.indexName,
        typeName: req.body.typeName,
        query: query
    };

    if (!exportService) {
        model.error = {message: 'Support for the export format ' + format + ' was not found.'};
    } else {
        exportData(model, exportService);
    }
    res.render(TEMPLATE, model);
}

module.exports = {
    dispatch: dispatchRequest
};<commit_msg>update output<commit_after>const TEMPLATE = 'export';

var elasticsearch = require('elasticsearch'),
    exp = require('../services/ExportService'),
    mapServ = require('../services/MappingService'),
    md5 = require('md5'),
    config = require('../config');

function getFileName(query, format) {
    var dateTime = Date.now();
    return 'report-' + md5(JSON.stringify(query)) + '-' + dateTime + '.' + format;
}

function exportData(model, expSvc) {
    // scroll thru documents, save to format
    var client = new elasticsearch.Client({
        host: config.elastic.host + ':' + config.elastic.port,
        log: config.elastic.log
    });

    mapServ.getMapping(model.indexName, model.typeName)
        .then(function (fieldMap) {
            expSvc.createWriteStream(
                config.outputDirectory + model.filename,
                fieldMap
            );
            client.search({
                index: model.indexName,
                scroll: config.elastic.scrollTime,
                search_type: 'scan',
                body: model.query
            }, function getMoreUntilDone(error, response) {
                response.hits.hits.forEach(function (hit) {
                    expSvc.write(hit._source ? hit._source : hit.fields);
                });
                if (response.hits.total > expSvc.getTotal()) {
                    client.scroll({
                        scrollId: response._scroll_id,
                        scroll: config.elastic.scrollTime
                    }, getMoreUntilDone);
                } else {
                    console.log('exportData completed: ' + expSvc.getTotal() + ' items.');
                    expSvc.end();
                }
            });
        }).catch(function (err) {
            console.log('exportData catch', err, model);
        });
}

function dispatchRequest(req, res) {
    var rawQuery = req.body.rawQuery,
        format = req.body.format,
        exportService = exp[format] ? exp[format]() : null,
        query = JSON.parse(rawQuery),
        model;

    model = {
        filename: getFileName(rawQuery, format),
        rawQuery: rawQuery,
        indexName: req.body.indexName,
        typeName: req.body.typeName,
        query: query
    };

    if (!exportService) {
        model.error = {message: 'Support for the export format ' + format + ' was not found.'};
    } else {
        exportData(model, exportService);
    }
    res.render(TEMPLATE, model);
}

module.exports = {
    dispatch: dispatchRequest
};<|endoftext|>


<commit_before>/*
---
script: ShapeHover.js

description: Add rollover effect on an image map

license: MIT-style license.

authors: Yannick Croissant

inspiration:
	Inspired by [jQuery Maphilight](http://davidlynch.org/js/maphilight/docs/) Copyright (c) 2008 [David Lynch](http://davidlynch.org), [MIT License](http://opensource.org/licenses/mit-license.php)

requires:
	core/1.2.3: '*'
	more/1.2.3.1: [Assets]

provides: [ShapeHover]

...
*/
var ShapeHover=new Class({Implements:[Options,Events],options:{fill:{type:"color",content:"#000",opacity:0.5},stroke:{color:"#F00",opacity:1,width:1},fade:true,alwaysOn:false,onReady:$empty,onMouseOver:$empty,onMouseOut:$empty,onClick:$empty},initialize:function(c,a){this.element=document.id(c);this.map=document.getElement('map[name="'+this.element.get("usemap").split("#")[1]+'"]');this.setOptions(a);this.type=document.createElement("canvas")&&document.createElement("canvas").getContext?"canvas":(document.namespaces?"vml":false);if(!this.type||!this.map){return false}if(this.type=="vml"){document.createStyleSheet().addRule("v\\:shape","display:inline-block");document.namespaces.add("v","urn:schemas-microsoft-com:vml","#default#VML")}if(this.options.fill.type!="image"){return this.ready()}if(this.type=="canvas"){this.fillContent=new Asset.image(this.options.fill.content,{onload:this.ready.bind(this)})}else{var b=new Element("div",{styles:{position:"absolute",left:"-9999em"}});b.inject(this.element,"after");b.innerHTML='<v:rect><v:fill type="tile" src="'+this.options.fill.content+'" /></v:rect>';this.ready()}},ready:function(){this.wrap=new Element("div",{styles:{background:"url("+this.element.get("src")+")",height:this.element.getSize().y,position:"relative",width:this.element.getSize().x}}).inject(this.element,"before");this.element.style.opacity=0;if(Browser.Engine.trident){this.element.style.filter="Alpha(opacity=0)"}this.element.setStyles({position:"absolute",left:0,top:0,padding:0,border:0});this.wrap.adopt(this.element);this.canvas=this.createCanvas().set({styles:{border:0,left:0,padding:0,position:"absolute",top:0},width:this.element.getSize().x,height:this.element.getSize().y});if(this.options.alwaysOn){this.map.getElements("area[coords]").forEach(function(b){var a=this.shapeFromArea(b);this.addShapeTo(a[0],a[1])}.bind(this))}else{this.map.getElements("area[coords]").addEvent("mouseover",function(b){var a=this.shapeFromArea(b.target);this.addShapeTo(a[0],a[1]);this.fireEvent("onMouseOver",b)}.bind(this)).addEvent("mouseout",function(a){this.clearCanvas();this.fireEvent("onMouseOut",a)}.bind(this)).addEvent("click",function(a){this.fireEvent("onClick",a)}.bind(this))}this.canvas.inject(this.element,"before");this.fireEvent("onReady")},createCanvas:function(){if(this.type=="canvas"){var a=new Element("canvas",{styles:{width:this.element.getSize().x+"px",height:this.element.getSize().y+"px"}});a.getContext("2d").clearRect(0,0,a.width,a.height);if(this.options.fade){a.set({tween:{duration:"short"}})}return a}return new Element("var",{styles:{display:"block",height:this.element.getSize().y+"px",overflow:"hidden",width:this.element.getSize().x+"px",zoom:1}})},addShapeTo:function(g,k){if(this.type=="canvas"){if(this.options.fade){this.canvas.set("opacity",0)}var a=this.canvas.getContext("2d");a.beginPath();if(g=="rect"){a.rect(k[0],k[1],k[2]-k[0],k[3]-k[1])}else{if(g=="circ"){a.arc(k[0],k[1],k[2],0,Math.PI*2,false)}else{if(g=="poly"){a.moveTo(k[0],k[1]);for(var c=2,m=k.length;c<m;c+=2){a.lineTo(k[c],k[c+1])}}}}a.closePath();if(this.options.fill){if(this.options.fill.type=="image"){var h=a.createPattern(this.fillContent,"repeat");a.fillStyle=h}else{a.fillStyle="rgba("+this.options.fill.content.hexToRgb(true).join(",")+","+this.options.fill.opacity+")"}a.fill()}if(this.options.stroke){a.strokeStyle="rgba("+this.options.stroke.color.hexToRgb(true).join(",")+","+this.options.stroke.opacity+")";a.lineWidth=this.options.stroke.width;a.stroke()}if(this.options.fade){this.canvas.tween("opacity",1)}}else{var l=[],j=[];k.filter(function(i,e){if(e%2){j.push(i)}else{l.push(i)}}.bind(this));l=-1*l.min()/(l.max()-l.min());j=-1*j.min()/(j.max()-j.min());if(this.options.fill&&this.options.fill.type=="image"){var o='<v:fill type="tile" position="'+l+","+j+'" src="'+this.options.fill.content+'" />'}else{var o='<v:fill opacity="'+(this.options.fill?this.options.fill.opacity:0)+'" />'}var n=this.options.stroke?'strokeweight="'+this.options.stroke.width+'px" stroked="t" strokecolor="'+this.options.stroke.color+'"':'stroked="f"';var d='<v:stroke opacity="'+(this.options.stroke?this.options.stroke.opacity:0)+'"/>';if(g=="rect"){var f='<v:rect filled="t" '+n+' style="zoom:1;margin:0;padding:0;display:block;position:absolute;left:'+k[0]+"px;top:"+k[1]+"px;width:"+(k[2]-k[0])+"px;height:"+(k[3]-k[1])+'px;">'+o+d+"</v:rect>"}else{if(g=="circ"){var f='<v:oval filled="t" '+n+' style="zoom:1;margin:0;padding:0;display:block;position:absolute;left:'+(k[0]-k[2])+"px;top:"+(k[1]-k[2])+"px;width:"+(k[2]*2)+"px;height:"+(k[2]*2)+'px;">'+o+d+"</v:oval>"}else{if(g=="poly"){var f='<v:shape coordorigin="0,0" filled="t" '+n+' fillcolor="'+(this.options.fill?this.options.fill.content:"")+'" coordsize="'+this.canvas.width+","+this.canvas.height+'" path="m '+k[0]+","+k[1]+" l "+k.join(",")+' x e" style="zoom:1;margin:0;padding:0;display:block;position:absolute;top:0px;left:0px;width:'+this.canvas.width+"px;height:"+this.canvas.height+'px;">'+o+d+"</v:shape>"}}}var b=document.createElement("div");b.style.display="none";document.body.appendChild(b);b.innerHTML=f;f=b.childNodes[0];document.id(f).inject(this.canvas);document.id(b).destroy()}},clearCanvas:function(){if(this.type=="canvas"){this.canvas.getContext("2d").clearRect(0,0,this.canvas.width,this.canvas.height)}else{this.canvas.empty()}},shapeFromArea:function(a){return[a.get("shape").toLowerCase().substr(0,4),a.get("coords").split(",").map(function(b){return parseFloat(b)})]}});<commit_msg>- Comments update<commit_after>/*
---
script: ShapeHover-yui-compressed.js

description: Add rollover effect on an image map

license: MIT-style license.

authors: Yannick Croissant

inspiration:
	Inspired by [jQuery Maphilight](http://davidlynch.org/js/maphilight/docs/) Copyright (c) 2008 [David Lynch](http://davidlynch.org), [MIT License](http://opensource.org/licenses/mit-license.php)

requires:
	core/1.2.3: '*'
	more/1.2.3.1: [Assets]

provides: [ShapeHover]

...
*/
var ShapeHover=new Class({Implements:[Options,Events],options:{fill:{type:"color",content:"#000",opacity:0.5},stroke:{color:"#F00",opacity:1,width:1},fade:true,alwaysOn:false,onReady:$empty,onMouseOver:$empty,onMouseOut:$empty,onClick:$empty},initialize:function(c,a){this.element=document.id(c);this.map=document.getElement('map[name="'+this.element.get("usemap").split("#")[1]+'"]');this.setOptions(a);this.type=document.createElement("canvas")&&document.createElement("canvas").getContext?"canvas":(document.namespaces?"vml":false);if(!this.type||!this.map){return false}if(this.type=="vml"){document.createStyleSheet().addRule("v\\:shape","display:inline-block");document.namespaces.add("v","urn:schemas-microsoft-com:vml","#default#VML")}if(this.options.fill.type!="image"){return this.ready()}if(this.type=="canvas"){this.fillContent=new Asset.image(this.options.fill.content,{onload:this.ready.bind(this)})}else{var b=new Element("div",{styles:{position:"absolute",left:"-9999em"}});b.inject(this.element,"after");b.innerHTML='<v:rect><v:fill type="tile" src="'+this.options.fill.content+'" /></v:rect>';this.ready()}},ready:function(){this.wrap=new Element("div",{styles:{background:"url("+this.element.get("src")+")",height:this.element.getSize().y,position:"relative",width:this.element.getSize().x}}).inject(this.element,"before");this.element.style.opacity=0;if(Browser.Engine.trident){this.element.style.filter="Alpha(opacity=0)"}this.element.setStyles({position:"absolute",left:0,top:0,padding:0,border:0});this.wrap.adopt(this.element);this.canvas=this.createCanvas().set({styles:{border:0,left:0,padding:0,position:"absolute",top:0},width:this.element.getSize().x,height:this.element.getSize().y});if(this.options.alwaysOn){this.map.getElements("area[coords]").forEach(function(b){var a=this.shapeFromArea(b);this.addShapeTo(a[0],a[1])}.bind(this))}else{this.map.getElements("area[coords]").addEvent("mouseover",function(b){var a=this.shapeFromArea(b.target);this.addShapeTo(a[0],a[1]);this.fireEvent("onMouseOver",b)}.bind(this)).addEvent("mouseout",function(a){this.clearCanvas();this.fireEvent("onMouseOut",a)}.bind(this)).addEvent("click",function(a){this.fireEvent("onClick",a)}.bind(this))}this.canvas.inject(this.element,"before");this.fireEvent("onReady")},createCanvas:function(){if(this.type=="canvas"){var a=new Element("canvas",{styles:{width:this.element.getSize().x+"px",height:this.element.getSize().y+"px"}});a.getContext("2d").clearRect(0,0,a.width,a.height);if(this.options.fade){a.set({tween:{duration:"short"}})}return a}return new Element("var",{styles:{display:"block",height:this.element.getSize().y+"px",overflow:"hidden",width:this.element.getSize().x+"px",zoom:1}})},addShapeTo:function(g,k){if(this.type=="canvas"){if(this.options.fade){this.canvas.set("opacity",0)}var a=this.canvas.getContext("2d");a.beginPath();if(g=="rect"){a.rect(k[0],k[1],k[2]-k[0],k[3]-k[1])}else{if(g=="circ"){a.arc(k[0],k[1],k[2],0,Math.PI*2,false)}else{if(g=="poly"){a.moveTo(k[0],k[1]);for(var c=2,m=k.length;c<m;c+=2){a.lineTo(k[c],k[c+1])}}}}a.closePath();if(this.options.fill){if(this.options.fill.type=="image"){var h=a.createPattern(this.fillContent,"repeat");a.fillStyle=h}else{a.fillStyle="rgba("+this.options.fill.content.hexToRgb(true).join(",")+","+this.options.fill.opacity+")"}a.fill()}if(this.options.stroke){a.strokeStyle="rgba("+this.options.stroke.color.hexToRgb(true).join(",")+","+this.options.stroke.opacity+")";a.lineWidth=this.options.stroke.width;a.stroke()}if(this.options.fade){this.canvas.tween("opacity",1)}}else{var l=[],j=[];k.filter(function(i,e){if(e%2){j.push(i)}else{l.push(i)}}.bind(this));l=-1*l.min()/(l.max()-l.min());j=-1*j.min()/(j.max()-j.min());if(this.options.fill&&this.options.fill.type=="image"){var o='<v:fill type="tile" position="'+l+","+j+'" src="'+this.options.fill.content+'" />'}else{var o='<v:fill opacity="'+(this.options.fill?this.options.fill.opacity:0)+'" />'}var n=this.options.stroke?'strokeweight="'+this.options.stroke.width+'px" stroked="t" strokecolor="'+this.options.stroke.color+'"':'stroked="f"';var d='<v:stroke opacity="'+(this.options.stroke?this.options.stroke.opacity:0)+'"/>';if(g=="rect"){var f='<v:rect filled="t" '+n+' style="zoom:1;margin:0;padding:0;display:block;position:absolute;left:'+k[0]+"px;top:"+k[1]+"px;width:"+(k[2]-k[0])+"px;height:"+(k[3]-k[1])+'px;">'+o+d+"</v:rect>"}else{if(g=="circ"){var f='<v:oval filled="t" '+n+' style="zoom:1;margin:0;padding:0;display:block;position:absolute;left:'+(k[0]-k[2])+"px;top:"+(k[1]-k[2])+"px;width:"+(k[2]*2)+"px;height:"+(k[2]*2)+'px;">'+o+d+"</v:oval>"}else{if(g=="poly"){var f='<v:shape coordorigin="0,0" filled="t" '+n+' fillcolor="'+(this.options.fill?this.options.fill.content:"")+'" coordsize="'+this.canvas.width+","+this.canvas.height+'" path="m '+k[0]+","+k[1]+" l "+k.join(",")+' x e" style="zoom:1;margin:0;padding:0;display:block;position:absolute;top:0px;left:0px;width:'+this.canvas.width+"px;height:"+this.canvas.height+'px;">'+o+d+"</v:shape>"}}}var b=document.createElement("div");b.style.display="none";document.body.appendChild(b);b.innerHTML=f;f=b.childNodes[0];document.id(f).inject(this.canvas);document.id(b).destroy()}},clearCanvas:function(){if(this.type=="canvas"){this.canvas.getContext("2d").clearRect(0,0,this.canvas.width,this.canvas.height)}else{this.canvas.empty()}},shapeFromArea:function(a){return[a.get("shape").toLowerCase().substr(0,4),a.get("coords").split(",").map(function(b){return parseFloat(b)})]}});<|endoftext|>


<commit_before>/*jshint node:true, laxcomma:true */
"use strict";

var httpProxy = require('http-proxy');
var instances = require('../helpers/instances');
var util = require('utile');

module.exports = function(options, core, data) {

  var proxy = httpProxy.createProxyServer({})
    , domainEnv = core.config.get('publicDomain')
    ,publicIP = core.config.get('publiciP');;

  return function(req, res, next) {

    instances.getInstances(function(err,data){
    var reqServer = req.headers['x-forwarded-server']
      , reqHost = req.headers['x-forwarded-host']
      , reqSubdomain = reqHost ? reqHost.split('.') : null
      ;

    console.log('reverseproxy#1',reqSubdomain,' && (', reqServer, ' === ', domainEnv, ")");

    console.log("");
    console.log("########## DEBUG ##########");
    console.log("DATA : " + data);
    console.log("REQHOST : " + reqHost);
    console.log("REQSUBDOMAIN : " + reqSubdomain);
    console.log("REQSERVER : " + reqServer);
    console.log("DOMAINENV : " + domainEnv);
    console.log("########## FIN DEBUG ##########");
    console.log("");

    if(reqSubdomain && (reqServer === domainEnv) && data !== undefined) {

      console.log('reverseproxy#1.1');

      var search = reqSubdomain[0].split('-');

      var found = Object.keys(data)
      .map(function(z) {
        data[z].current = data[z].technicalName.split('-');
        data[z].current[2] = data[z].current[2] === undefined ? 0 : Number(data[z].current[2]);
        if (Number.isNaN(data[z].current[2])) {
          data[z].current[2] = 0;
        }
        return z;
      })
      .sort(function(a, b) {
        return data[a].current[2] < data[b].current[2];
      })
      .filter(function(x) {
        return data[x].current[0] === search[0] && data[x].current[1] === search[1];
      })
      .reduce(function(prev, w) {
        if (prev !== undefined) {
          return prev;
        }
        if (search[2] === undefined) {
          return w;
        }
        if (data[w].current[0] === search[0] && data[w].current[1] === search[1] && data[w].current[2] === Number(search[2])) {
          return w;
        }
        return;
      }, undefined);

      console.log("########## FOUND : " + found + " ##########");

      if (found !== undefined) {
        var url = 'http://'+publicIP+':' + data[found].port;
        console.log('reverseproxy#1.1.1', url);
        proxy.web(req, res, { target: url });
        proxy.on('error', function(e) {
          console.error("reverseproxy#1.1.2", e);
          next(new Error('Bad gateway'))
        } );
        return;
      }
      else {
        console.log('reverseproxy#1.2');
        res.render('404', { title: 'No any app found :( !', path: '/', userName: req.user });
      }
    }
    else {
      console.log('reverseproxy#1.0');
      next();
    }
    })
  }

}<commit_msg>correction of publicIP<commit_after>/*jshint node:true, laxcomma:true */
"use strict";

var httpProxy = require('http-proxy');
var instances = require('../helpers/instances');
var util = require('utile');

module.exports = function(options, core, data) {

  var proxy = httpProxy.createProxyServer({})
    , domainEnv = core.config.get('publicDomain')
    ,publicIP = core.config.get('publicIP');;

  return function(req, res, next) {

    instances.getInstances(function(err,data){
    var reqServer = req.headers['x-forwarded-server']
      , reqHost = req.headers['x-forwarded-host']
      , reqSubdomain = reqHost ? reqHost.split('.') : null
      ;

    console.log('reverseproxy#1',reqSubdomain,' && (', reqServer, ' === ', domainEnv, ")");

    console.log("");
    console.log("########## DEBUG ##########");
    console.log("DATA : " + data);
    console.log("REQHOST : " + reqHost);
    console.log("REQSUBDOMAIN : " + reqSubdomain);
    console.log("REQSERVER : " + reqServer);
    console.log("DOMAINENV : " + domainEnv);
    console.log("########## FIN DEBUG ##########");
    console.log("");

    if(reqSubdomain && (reqServer === domainEnv) && data !== undefined) {

      console.log('reverseproxy#1.1');

      var search = reqSubdomain[0].split('-');

      var found = Object.keys(data)
      .map(function(z) {
        data[z].current = data[z].technicalName.split('-');
        data[z].current[2] = data[z].current[2] === undefined ? 0 : Number(data[z].current[2]);
        if (Number.isNaN(data[z].current[2])) {
          data[z].current[2] = 0;
        }
        return z;
      })
      .sort(function(a, b) {
        return data[a].current[2] < data[b].current[2];
      })
      .filter(function(x) {
        return data[x].current[0] === search[0] && data[x].current[1] === search[1];
      })
      .reduce(function(prev, w) {
        if (prev !== undefined) {
          return prev;
        }
        if (search[2] === undefined) {
          return w;
        }
        if (data[w].current[0] === search[0] && data[w].current[1] === search[1] && data[w].current[2] === Number(search[2])) {
          return w;
        }
        return;
      }, undefined);

      console.log("########## FOUND : " + found + " ##########");

      if (found !== undefined) {
        var url = 'http://'+publicIP+':' + data[found].port;
        console.log('reverseproxy#1.1.1', url);
        proxy.web(req, res, { target: url });
        proxy.on('error', function(e) {
          console.error("reverseproxy#1.1.2", e);
          next(new Error('Bad gateway'))
        } );
        return;
      }
      else {
        console.log('reverseproxy#1.2');
        res.render('404', { title: 'No any app found :( !', path: '/', userName: req.user });
      }
    }
    else {
      console.log('reverseproxy#1.0');
      next();
    }
    })
  }

}<|endoftext|>


<commit_before>import Ember from 'ember';

var SettingsGeneralController = Ember.ObjectController.extend({
  needs: ['settings'],
  site: Ember.computed.alias('controllers.settings.model'),
  isSaving: false,

  // @todo Get that list from the server
  allThemes: [ 'willy' ],

  actions: {
    removeLogo: function() {
      this.get('model').set('logo', null);
    },

    removeCover: function() {
      this.get('model').set('cover', null);
    },

    // called by 'select-image' modal controller
    imageSelected: function(field, image) {
      var model = this.get('model');
      model.set(field, image);
    },

    // called by 'tinymce-editor' component
    descriptionChanged: function(newValue) {
      this.get('model').set('description', newValue);
    },

    // called by 'tinymce-editor' component
    moreDescChanged: function(newValue) {
      this.get('model').set('moreDesc', newValue);
    },

    // called by 'tinymce-editor' component
    joinTextChanged: function(newValue) {
      this.get('model').set('joinText', newValue);
    },

    save: function () {
      var self = this;

      this.set('isSaving', true);

      return this.get('model').save().then(function (model) {
        self.get('flashes').success('Settings saved.');

        return model;
      }).catch(function (/* errors */) {
        self.get('flashes').danger('Failed to save settings.');
      }).finally(function(){
        self.set('isSaving', false);
      });
    }
  }
});

export default SettingsGeneralController;
<commit_msg>WIP on ailes theme<commit_after>import Ember from 'ember';

var SettingsGeneralController = Ember.ObjectController.extend({
  needs: ['settings'],
  site: Ember.computed.alias('controllers.settings.model'),
  isSaving: false,

  // @todo Get that list from the server
  allThemes: [ 'ailes', 'willy' ],

  actions: {
    removeLogo: function() {
      this.get('model').set('logo', null);
    },

    removeCover: function() {
      this.get('model').set('cover', null);
    },

    // called by 'select-image' modal controller
    imageSelected: function(field, image) {
      var model = this.get('model');
      model.set(field, image);
    },

    // called by 'tinymce-editor' component
    descriptionChanged: function(newValue) {
      this.get('model').set('description', newValue);
    },

    // called by 'tinymce-editor' component
    moreDescChanged: function(newValue) {
      this.get('model').set('moreDesc', newValue);
    },

    // called by 'tinymce-editor' component
    joinTextChanged: function(newValue) {
      this.get('model').set('joinText', newValue);
    },

    save: function () {
      var self = this;

      this.set('isSaving', true);

      return this.get('model').save().then(function (model) {
        self.get('flashes').success('Settings saved.');

        return model;
      }).catch(function (/* errors */) {
        self.get('flashes').danger('Failed to save settings.');
      }).finally(function(){
        self.set('isSaving', false);
      });
    }
  }
});

export default SettingsGeneralController;
<|endoftext|>


<commit_before>var WelcomeManager = {

    // Initialization function.
    init: function() {
        $(document).on("change", ".content .field input", function() {
            WelcomeManager.setUnsaved();
        });

        $(document).on("submit", ".content #welcomepage", WelcomeManager.submit);
    },

    // Sets the SAVE button to saved (green).
    setSaved: function() {
        $(".tablemenu input[type=submit]")
            .removeClass('unsaved')
            .addClass('saved');
    },

    // Sets the SAVE button to unsaved (yellow).
    setUnsaved: function() {
        $(".tablemenu input[type=submit]")
            .removeClass('saved')
            .addClass('unsaved');
    },

    submit: function() {
        // Integer-Only Check
        $.validator.addMethod("IntegersOnly", function(value, element){
            if (this.optional(element)) {
                return /^$/i.test(value) || /^[0-9]+$/i.test(value);
            } else {
                return /^[0-9]+$/i.test(value);
            }
        }, "Please enter a positive number.");

        // Zip Code Check
        // Allow 0-9, space, dash
        $.validator.addMethod("zip", function(value, element) {
            if (this.optional(element)) {
                return /^$/i.test(value) || /^[0-9\s\-]+$/i.test(value);
            } else {
                return /^[0-9\s\-]+$/i.test(value);
            }
        }, "Zip codes may only contain numbers, spaces, and dashes.");

        // U.S. Phone Number Check
        $.validator.addMethod("phoneNum", function(value, element){
            if (this.optional(element)) {
                return /^$/i.test(value) || /^\(?([0-9]{3})\)?\s([0-9]{3})-([0-9]{4})(\sx[0-9]{1,5})?$/i.test(value);
            }
            else {
                return /^\(?([0-9]{3})\)?\s([0-9]{3})-([0-9]{4})(\sx[0-9]{1,5})?$/i.test(value);
            }
        }, "Please enter a valid phone number.");

        // International Phone Number
        $.validator.addMethod("intPhone", function(value, element) {
            if (this.optional(element)) {
                return /^$/i.test(value) || /^[0-9\-x\s\+\(\)]+$/i.test(value);
            } else {
                return /^[0-9\-x\s\+\(\)]+$/i.test(value);
            }
        }, "Please enter a valid phone number.");

        $("#welcomepage").validate();

        if ($(this).valid()) {
            var uri = $("#welcomepage").attr("action");
            $.ajax({
                type: 'POST',
                url: uri,
                data: $(this).serializeArray(),
                success: function(name) {
                    WelcomeManager.setSaved();
                    if ($("#header span.advisorfirstname").text() != $("input[name=firstname]").val()) {
                        $("span.advisorfirstname").each(function() {
                            $(this).fadeOut(200, function() {
                                var exclamation = ($(this).closest("li").length > 0) ? "" : "!";
                                $(this).text($("input[name=firstname]").val() + exclamation);
                                $(this).fadeIn(200);
                            });
                        });
                    }

                    if($("#header span.advisorlastname").text() != $("input[name=lastname]").val()){
                        $("span.advisorlastname").fadeOut(200, function() {
                            $(this).text($("input[name=lastname]").val());
                            $(this).fadeIn(200);
                        });
                    }

                    if($("span.schoolname").text() != $("input[name=schoolname]").val()){
                        $("span.schoolname").fadeOut(200, function() {
                            $(this).text($("input[name=schoolname]").val());
                            $(this).fadeIn(200);
                        });
                    }
                },
            });
        }
        return false;
    },

    toString: function(){
        return "WelcomeManager";
    }
}

$(function() {
    WelcomeManager.init()

    // TODO: MOVE TO UI ----------------------------------------
    function setGreen(id) {
        $(id).removeClass('negative').addClass('good');
    }

    function setRed(id) {
        $(id).removeClass('good').addClass('negative');
    }
});<commit_msg>Missing semicolon. I'm a clown.<commit_after>var WelcomeManager = {

    // Initialization function.
    init: function() {
        $(document).on("change", ".content .field input", function() {
            WelcomeManager.setUnsaved();
        });

        $(document).on("submit", ".content #welcomepage", WelcomeManager.submit);
    },

    // Sets the SAVE button to saved (green).
    setSaved: function() {
        $(".tablemenu input[type=submit]")
            .removeClass('unsaved')
            .addClass('saved');
    },

    // Sets the SAVE button to unsaved (yellow).
    setUnsaved: function() {
        $(".tablemenu input[type=submit]")
            .removeClass('saved')
            .addClass('unsaved');
    },

    submit: function() {
        // Integer-Only Check
        $.validator.addMethod("IntegersOnly", function(value, element){
            if (this.optional(element)) {
                return /^$/i.test(value) || /^[0-9]+$/i.test(value);
            } else {
                return /^[0-9]+$/i.test(value);
            }
        }, "Please enter a positive number.");

        // Zip Code Check
        // Allow 0-9, space, dash
        $.validator.addMethod("zip", function(value, element) {
            if (this.optional(element)) {
                return /^$/i.test(value) || /^[0-9\s\-]+$/i.test(value);
            } else {
                return /^[0-9\s\-]+$/i.test(value);
            }
        }, "Zip codes may only contain numbers, spaces, and dashes.");

        // U.S. Phone Number Check
        $.validator.addMethod("phoneNum", function(value, element){
            if (this.optional(element)) {
                return /^$/i.test(value) || /^\(?([0-9]{3})\)?\s([0-9]{3})-([0-9]{4})(\sx[0-9]{1,5})?$/i.test(value);
            }
            else {
                return /^\(?([0-9]{3})\)?\s([0-9]{3})-([0-9]{4})(\sx[0-9]{1,5})?$/i.test(value);
            }
        }, "Please enter a valid phone number.");

        // International Phone Number
        $.validator.addMethod("intPhone", function(value, element) {
            if (this.optional(element)) {
                return /^$/i.test(value) || /^[0-9\-x\s\+\(\)]+$/i.test(value);
            } else {
                return /^[0-9\-x\s\+\(\)]+$/i.test(value);
            }
        }, "Please enter a valid phone number.");

        $("#welcomepage").validate();

        if ($(this).valid()) {
            var uri = $("#welcomepage").attr("action");
            $.ajax({
                type: 'POST',
                url: uri,
                data: $(this).serializeArray(),
                success: function(name) {
                    WelcomeManager.setSaved();
                    if ($("#header span.advisorfirstname").text() != $("input[name=firstname]").val()) {
                        $("span.advisorfirstname").each(function() {
                            $(this).fadeOut(200, function() {
                                var exclamation = ($(this).closest("li").length > 0) ? "" : "!";
                                $(this).text($("input[name=firstname]").val() + exclamation);
                                $(this).fadeIn(200);
                            });
                        });
                    }

                    if($("#header span.advisorlastname").text() != $("input[name=lastname]").val()){
                        $("span.advisorlastname").fadeOut(200, function() {
                            $(this).text($("input[name=lastname]").val());
                            $(this).fadeIn(200);
                        });
                    }

                    if($("span.schoolname").text() != $("input[name=schoolname]").val()){
                        $("span.schoolname").fadeOut(200, function() {
                            $(this).text($("input[name=schoolname]").val());
                            $(this).fadeIn(200);
                        });
                    }
                },
            });
        }
        return false;
    },

    toString: function(){
        return "WelcomeManager";
    }
}

$(function() {
    WelcomeManager.init();

    // TODO: MOVE TO UI ----------------------------------------
    function setGreen(id) {
        $(id).removeClass('negative').addClass('good');
    }

    function setRed(id) {
        $(id).removeClass('good').addClass('negative');
    }
});<|endoftext|>


<commit_before>var ContentManager = {

    // Initializer function.
    init: function() {
        History.Adapter.bind(window, 'statechange', function(){
            var state = History.getState();
            var handler = $("#app").is(":hidden")
                ? ContentManager.loadInitContent
                : ContentManager.loadNewContent;
            handler(state.url);
        });

        $(document).on("click", "a.js-nav", function() {
            History.pushState({}, $(this).text(), $(this).attr("href"));
            return false;
        });

        $(document).on("click", "#appnavbar a.js-nav", function() {
            $("#appnavbar a.nav.currentpage").removeClass('currentpage');
            $(this).addClass('currentpage');
        });

        ContentManager.onPageLoad();
    },

    // Fades the initial content into view.
    onPageLoad: function() {
        if(window.location.pathname == '/') {
            History.pushState({}, "", $("html").data("default-path"));
        } else if (!document.getElementById('content-placeholder')) {
            $('#app').fadeIn(500);
        } else {
            $(window).trigger('statechange');
        }
    },

    // Loads initial content into the application content container.
    loadInitContent: function(path, data) {
        if ($("#splash").is(":visible")) {
            $.ajax({
                url: path,
                success: function(response) {
                    // Replace the title and content.
                    $("title").html(response.match(/<title>(.*?)<\/title>/)[1]);
                    $("#capsule").replaceWith($("#capsule", $(response)));
                    $("#appnavbar a[href='" + window.location.pathname + "']")
                      .addClass('currentpage');
                    // Fade in.
                    $("#splash").delay(250).fadeOut(250, function() {
                        $("#app").delay(250).fadeIn(500, function() {
                            $("#headerwrapper").slideDown(350, function() {
                                $("#header").slideDown(350);
                            });
                        });
                    });
                },
                error: Error.show
            });
        } else {
            $.ajax({
                url: path,
                success: function(response) {
                  // Replace the title and content.
                  $("title").html(response.match(/<title>(.*?)<\/title>/)[1]);
                  $("#capsule").replaceWith($("#capsule", $(response)));
                  // Fade in.
                  $("#app").delay(250).fadeIn(500);
                },
                error: Error.show
            });
        }
    },

    // Loads new content into the application content container.
    loadNewContent: function(path, data) {
        $(".content").css('height', $(".content").height() + "px");
        $(".content #contentwrapper").fadeOut(150, function() {
            $(".content").addClass("loading");
            var method = data ? "POST" : "GET";
            $.ajax({
                type: method,
                url: path,
                data: data,
                success: function(data) {
                    // Replace the title and content.
                    $("title").html(data.match(/<title>(.*?)<\/title>/)[1]);
                    $("#capsule").replaceWith($("#capsule", $(data)));
                    // Animate and fade in.
                    $("#contentwrapper").css({
                        'visibility':'hidden',
                        'display': 'block'
                    });
                    var height = $("#contentwrapper").height();
                    $("#contentwrapper").css({
                        'visibility':'',
                        'display': 'none'
                    });
                    $(".content").animate({height: height}, 500, function() {
                        $(".content").removeClass("loading");
                        $("#contentwrapper").fadeIn(150, function() {
                            $(".content").css('height','');
                        });
                    });
                },
                error: Error.show
            });
        });
    },

    // Prepares the UI upon login/logout.
    onLoginLogout: function(redirect, fadetime) {
        $("#container").fadeOut(150, function() {
            $("#container").load(redirect + " #appcontainer", null, function() {
                $("#container").fadeIn(fadetime, function() {
                    History.pushState({}, "", redirect);
                });
            });
        });
    }
};

$(function() {
    ContentManager.init();
});
<commit_msg>#86: Rewrote ContentManager.loadNewContent to fetch and fadeout in parellel.<commit_after>var ContentManager = {

    // Initializer function.
    init: function() {
        History.Adapter.bind(window, 'statechange', function(){
            var state = History.getState();
            var handler = $('#app').is(':hidden')
                ? ContentManager.loadInitContent
                : ContentManager.loadNewContent;
            handler(state.url);
        });

        $(document).on('click', 'a.js-nav', function() {
            History.pushState({}, $(this).text(), $(this).attr('href'));
            return false;
        });

        $(document).on('click', '#appnavbar a.js-nav', function() {
            $('#appnavbar a.js-nav.currentpage').removeClass('currentpage');
            $(this).addClass('currentpage');
        });

        ContentManager.onPageLoad();
    },

    // Fades the initial content into view.
    onPageLoad: function() {
        if(window.location.pathname == '/') {
            History.pushState({}, '', $('html').data('default-path'));
        } else if (!document.getElementById('content-placeholder')) {
            $('#app').fadeIn(500);
        } else {
            $(window).trigger('statechange');
        }
    },

    // Loads initial content into the application content container.
    loadInitContent: function(path, data) {
        if ($('#splash').is(':visible')) {
            $.ajax({
                url: path,
                success: function(response) {
                    // Replace the title and content.
                    $('title').html(response.match(/<title>(.*?)<\/title>/)[1]);
                    $('#capsule').replaceWith($('#capsule', $(response)));
                    $('#appnavbar a[href="' + window.location.pathname + '"]')
                      .addClass('currentpage');
                    // Fade in.
                    $('#splash').delay(250).fadeOut(250, function() {
                        $('#app').delay(250).fadeIn(500, function() {
                            $('#headerwrapper').slideDown(350, function() {
                                $('#header').slideDown(350);
                            });
                        });
                    });
                },
                error: Error.show
            });
        } else {
            $.ajax({
                url: path,
                success: function(response) {
                  // Replace the title and content.
                  $('title').html(response.match(/<title>(.*?)<\/title>/)[1]);
                  $('#capsule').replaceWith($('#capsule', $(response)));
                  // Fade in.
                  $('#app').delay(250).fadeIn(500);
                },
                error: Error.show
            });
        }
    },

    // Loads new content into the application content container.
    loadNewContent: function(path, data) {
        var $content = $('.content');
        var $contentwrapper = $('#contentwrapper');

        var fadeout = $.Deferred(function(deferred) {
            $content.css('height', $content.height() + 'px');
            $contentwrapper.fadeOut(150, function() {
                $content.addClass('loading');
                deferred.resolve();
            });
        });

        var method = data ? 'POST' : 'GET';
        var ajaxCall = $.ajax({type: method, url: path, data: data});

        $.when(ajaxCall, fadeout)
            .done(function(ajaxData) {
                var data = ajaxData[0];
                $('title').html(data.match(/<title>(.*?)<\/title>/)[1]);
                $('#capsule').replaceWith($('#capsule', $(data)));

                $contentwrapper.css({
                    'visibility':'hidden',
                    'display': 'block'
                });
                var height = $contentwrapper.height();
                $contentwrapper.css({
                    'visibility':'',
                    'display': 'none'
                });

                $content.animate({height: height}, 500, function() {
                    $content.removeClass('loading');
                    $contentwrapper.fadeIn(150, function() {
                        $content.css('height','');
                    });
                });
            })
            .fail(Error.show);
    },

    // Prepares the UI upon login/logout.
    onLoginLogout: function(redirect, fadetime) {
        $('#container').fadeOut(150, function() {
            $('#container').load(redirect + ' #appcontainer', null, function() {
                $('#container').fadeIn(fadetime, function() {
                    History.pushState({}, '', redirect);
                });
            });
        });
    }
};

$(function() {
    ContentManager.init();
});
<|endoftext|>


<commit_before>

var bar_color = '#045a8d';
var margin = {top: 60, right: 80, bottom: 20, left: 100};

var cell_width = 60;
var cell_height = 50;
var cell_rows = 104;
var cell_columns = 10;
var cell_vertical_buffer = 0;
var cell_horizontal_buffer = 0;

var width = cell_columns*cell_width - margin.left - margin.right;
var height = cell_rows*cell_height - margin.top - margin.bottom;

var cell_yscale = d3.scale.linear()
        .range([cell_height, 0])
        .domain([0,0.5])
    ;

var cell_xscale = d3.scale.ordinal()
    .rangeRoundBands([0, cell_width], 0.1)
    .domain(_.range(1, 9+1));

var cell_xaxis = d3.svg.axis()
    .orient("bottom")
    .scale(cell_xscale);

var cell_yaxis = d3.svg.axis()
    .orient("left")
    .scale(cell_yscale);

var svg = d3.select("body").append("svg")
        .attr("width", width + margin.left + margin.right + 100)
        .attr("height", height + margin.top + margin.bottom + 100)
        .append("g")
        .attr("transform", "translate(" + margin.left + "," + margin.top + ")")
    ;

var position_string = {
    1: 'P',
    2: 'C',
    3: '1B',
    4: '2B',
    5: '3B',
    6: 'SS',
    7: 'LF',
    8: 'CF',
    9: 'RF',
    10: 'DH'
};

var MIN_YEAR = 1913;
d3.json('lineups.json', function(data) {

    console.log('data', data);

    _.forOwn(data, function(v, k) {
        if (k !== 'all' && parseInt(k)<MIN_YEAR) {
            MIN_YEAR = parseInt(k);
        }
    });

    var era_list = ['all', '1913-1919',
        '1920-1940', '1946-1967',
        '1973-1992', '1993-2002', '2006-2014']

    function make_cell(obj) {
        var data = obj.data;
        var year = obj.year;
        var idx_x = obj.position_idx-1;

        var idx_y;
        idx_y = era_list.indexOf(year);
        if (idx_y === -1) {
            idx_y = obj.year - MIN_YEAR + 7;
        }

        var child_svg = svg.append('g')
            .attr('transform', function() {

                var dx = (cell_width + cell_horizontal_buffer)*idx_x;
                var dy = (cell_height + cell_vertical_buffer)*idx_y;

                //var tmp = dx;
                //dx = dy;
                //dy = tmp;

                var s = 'translate (';
                s += dx.toString();
                s += ',';
                s += dy.toString();
                s += ')';
                return s;
            });

        var k = 'rect-' + obj.year.toString() + '-' + obj.position_idx.toString();

        var e = child_svg.selectAll('.' + k)
            .data(data)
            .enter();

        var rect_width = cell_xscale(2) - cell_xscale(1);
        e.append('rect')
            .attr('class', k)
            .attr('width', rect_width)
            .attr('height', function(d) {
                //console.log(d, cell_yscale(d.value));
                var v = cell_yscale(d.value);
                // scale goes to 0.5, but a few values are >0.5.
                // clamp these at 0.5
                if (v<0) {
                    v = 0;
                }
                return cell_height - v;
            })
            .attr('x', function(d) {
                return cell_xscale(d.lineup_idx);
            })
            .attr('y', function(d) {
                var v = cell_yscale(d.value);
                // scale goes to 0.5, but a few values are >0.5.
                // clamp these at 0.5
                if (v<0) {
                    v = 0;
                }
                return v;
            })
            .attr('fill', bar_color)
            .style('opacity', 0.5)
            .attr('stroke-width', 1)
            .attr('stroke', 'black')
            .attr('cursor', 'pointer')
            .on('mouseover', function() {
                //set_game_text(d);
            });

        child_svg.append('rect')
            .attr('width', cell_width)
            .attr('height', cell_height)
            .style('fill', 'none')
            .style('stroke', '#332222')
        ;

        if (obj.position_idx === 1) {
            child_svg.append('text')
                .text(obj.year)
                .style('font-size', 10)
                .attr('text-anchor', 'middle')
                .attr('transform', function () {
                    var dx = -10;
                    var dy = parseInt(0.5 * cell_height);
                    var s = 'translate(' + dx + ',' + dy + ')';
                    s += ' rotate(-90, -10, ' + dy + ')' ;

                    return 'rotate(-90, -5, ' + dy + ')';
                })
                .attr('x', -5)
                .attr('y', parseInt(.5*cell_height))
            ;
        }

        if (obj.year === 'all') {
            child_svg.append('text')
                .attr('x', parseInt(0.5* cell_width))
                .attr('y', -4)
                .attr('text-anchor', 'middle')
                .text(position_string[obj.position_idx])
                .style('font-size', 10)
        }
    }

    function update_cell() {
        ;
    }

    var this_data = {};
    era_list.forEach(function(yr) {
        this_data = {};

        _.forEach(_.range(1, 10+1), function(position_idx) {
            this_data[position_idx] = [];
        });

        _.forEach(data[yr], function(d) {
            var position_idx = d.position_idx;
            this_data[position_idx].push(d);
        });

        _.forEach(_.range(1, 10+1), function(position_idx) {
            //console.log(yr, position_idx, this_data[position_idx]);
            var obj = {year: yr, data: this_data[position_idx], position_idx: position_idx};
            make_cell(obj);
        });

    });

    var yr1 = 1913;
    var yr2 = 2015;
    _.forEach(_.range(yr1, yr2), function(yr) {
        this_data = {};
        _.forEach(_.range(1, 10+1), function(position_idx) {
            this_data[position_idx] = [];
        });

        _.forEach(data[yr], function(d) {
            var position_idx = d.position_idx;
            this_data[position_idx].push(d);
        });

        _.forEach(_.range(1, 10+1), function(position_idx) {
          //  console.log(yr, position_idx, this_data[position_idx]);
            var obj = {year: yr, data: this_data[position_idx], position_idx: position_idx};
            make_cell(obj);
        })
    });

});<commit_msg>height<commit_after>

var bar_color = '#045a8d';
var margin = {top: 60, right: 80, bottom: 20, left: 100};

var cell_width = 60;
var cell_height = 50;
var cell_rows = 112;
var cell_columns = 10;
var cell_vertical_buffer = 0;
var cell_horizontal_buffer = 0;

var width = cell_columns*cell_width - margin.left - margin.right;
var height = cell_rows*cell_height - margin.top - margin.bottom;

var cell_yscale = d3.scale.linear()
        .range([cell_height, 0])
        .domain([0,0.5])
    ;

var cell_xscale = d3.scale.ordinal()
    .rangeRoundBands([0, cell_width], 0.1)
    .domain(_.range(1, 9+1));

var cell_xaxis = d3.svg.axis()
    .orient("bottom")
    .scale(cell_xscale);

var cell_yaxis = d3.svg.axis()
    .orient("left")
    .scale(cell_yscale);

var svg = d3.select("body").append("svg")
        .attr("width", width + margin.left + margin.right + 100)
        .attr("height", height + margin.top + margin.bottom + 100)
        .append("g")
        .attr("transform", "translate(" + margin.left + "," + margin.top + ")")
    ;

var position_string = {
    1: 'P',
    2: 'C',
    3: '1B',
    4: '2B',
    5: '3B',
    6: 'SS',
    7: 'LF',
    8: 'CF',
    9: 'RF',
    10: 'DH'
};

var MIN_YEAR = 1913;
d3.json('lineups.json', function(data) {

    console.log('data', data);

    _.forOwn(data, function(v, k) {
        if (k !== 'all' && parseInt(k)<MIN_YEAR) {
            MIN_YEAR = parseInt(k);
        }
    });

    var era_list = ['all', '1913-1919',
        '1920-1940', '1946-1967',
        '1973-1992', '1993-2002', '2006-2014']

    function make_cell(obj) {
        var data = obj.data;
        var year = obj.year;
        var idx_x = obj.position_idx-1;

        var idx_y;
        idx_y = era_list.indexOf(year);
        if (idx_y === -1) {
            idx_y = obj.year - MIN_YEAR + 7;
        }

        var child_svg = svg.append('g')
            .attr('transform', function() {

                var dx = (cell_width + cell_horizontal_buffer)*idx_x;
                var dy = (cell_height + cell_vertical_buffer)*idx_y;

                //var tmp = dx;
                //dx = dy;
                //dy = tmp;

                var s = 'translate (';
                s += dx.toString();
                s += ',';
                s += dy.toString();
                s += ')';
                return s;
            });

        var k = 'rect-' + obj.year.toString() + '-' + obj.position_idx.toString();

        var e = child_svg.selectAll('.' + k)
            .data(data)
            .enter();

        var rect_width = cell_xscale(2) - cell_xscale(1);
        e.append('rect')
            .attr('class', k)
            .attr('width', rect_width)
            .attr('height', function(d) {
                //console.log(d, cell_yscale(d.value));
                var v = cell_yscale(d.value);
                // scale goes to 0.5, but a few values are >0.5.
                // clamp these at 0.5
                if (v<0) {
                    v = 0;
                }
                return cell_height - v;
            })
            .attr('x', function(d) {
                return cell_xscale(d.lineup_idx);
            })
            .attr('y', function(d) {
                var v = cell_yscale(d.value);
                // scale goes to 0.5, but a few values are >0.5.
                // clamp these at 0.5
                if (v<0) {
                    v = 0;
                }
                return v;
            })
            .attr('fill', bar_color)
            .style('opacity', 0.5)
            .attr('stroke-width', 1)
            .attr('stroke', 'black')
            .attr('cursor', 'pointer')
            .on('mouseover', function() {
                //set_game_text(d);
            });

        child_svg.append('rect')
            .attr('width', cell_width)
            .attr('height', cell_height)
            .style('fill', 'none')
            .style('stroke', '#332222')
        ;

        if (obj.position_idx === 1) {
            child_svg.append('text')
                .text(obj.year)
                .style('font-size', 10)
                .attr('text-anchor', 'middle')
                .attr('transform', function () {
                    var dx = -10;
                    var dy = parseInt(0.5 * cell_height);
                    var s = 'translate(' + dx + ',' + dy + ')';
                    s += ' rotate(-90, -10, ' + dy + ')' ;

                    return 'rotate(-90, -5, ' + dy + ')';
                })
                .attr('x', -5)
                .attr('y', parseInt(.5*cell_height))
            ;
        }

        if (obj.year === 'all') {
            child_svg.append('text')
                .attr('x', parseInt(0.5* cell_width))
                .attr('y', -4)
                .attr('text-anchor', 'middle')
                .text(position_string[obj.position_idx])
                .style('font-size', 10)
        }
    }

    function update_cell() {
        ;
    }

    var this_data = {};
    era_list.forEach(function(yr) {
        this_data = {};

        _.forEach(_.range(1, 10+1), function(position_idx) {
            this_data[position_idx] = [];
        });

        _.forEach(data[yr], function(d) {
            var position_idx = d.position_idx;
            this_data[position_idx].push(d);
        });

        _.forEach(_.range(1, 10+1), function(position_idx) {
            //console.log(yr, position_idx, this_data[position_idx]);
            var obj = {year: yr, data: this_data[position_idx], position_idx: position_idx};
            make_cell(obj);
        });

    });

    var yr1 = 1913;
    var yr2 = 2015;
    _.forEach(_.range(yr1, yr2), function(yr) {
        this_data = {};
        _.forEach(_.range(1, 10+1), function(position_idx) {
            this_data[position_idx] = [];
        });

        _.forEach(data[yr], function(d) {
            var position_idx = d.position_idx;
            this_data[position_idx].push(d);
        });

        _.forEach(_.range(1, 10+1), function(position_idx) {
          //  console.log(yr, position_idx, this_data[position_idx]);
            var obj = {year: yr, data: this_data[position_idx], position_idx: position_idx};
            make_cell(obj);
        })
    });

});<|endoftext|>


<commit_before>var keystone = require('keystone'),
	Types = keystone.Field.Types;

// Create model
var SocialWorker = new keystone.List('Social Worker', {
	track: true,
	map: { name: 'name.full' },
	defaultSort: 'name.full'
});

// Create fields
SocialWorker.add('Permissions', {

	permissions: {
		isVerified: { type: Boolean, label: 'has a verified email address', default: false, noedit: true },
		isActive: { type: Boolean, label: 'is active', default: true, noedit: true }
	}

}, 'General Information', {

	name: {
		first: { type: Types.Text, label: 'first name', required: true, index: true, initial: true },
		last: { type: Types.Text, label: 'last name', required: true, index: true, initial: true },
		full: { type: Types.Text, label: 'name', hidden: true, noedit: true, initial: false }
	},

	password: { type: Types.Password, label: 'password', required: true, initial: true },
	// avatar: { type: Types.CloudinaryImage, label: 'avatar', folder: 'users/social workers', select: true, selectPrefix: 'users/social workers', autoCleanup: true }
	avatar: { type: Types.CloudinaryImage, label: 'avatar', folder: 'users/social workers', autoCleanup: true }

}, 'Contact Information', {

	email: { type: Types.Email, label: 'email address', unique: true, required: true, index: true, initial: true },

	phone: {
		work: { type: Types.Text, label: 'work phone number', initial: true },
		home: { type: Types.Text, label: 'home phone number', initial: true },
		cell: { type: Types.Text, label: 'cell phone number', initial: true },
		preferred: { type: Types.Select, label: 'preferred phone', options: 'work, home, cell', initial: true }
	},

	address: {
	    street1: { type: Types.Text, label: 'address line 1', initial: true },
		street2: { type: Types.Text, label: 'address line 2', initial: true },
		city: { type: Types.Text, label: 'city', initial: true },
		state: { type: Types.Relationship, label: 'state', ref: 'State', index: true, initial: true },
		zipCode: { type: Types.Text, label: 'zip code', index: true, initial: true }
	}

}, 'Social Worker Information', {

	// position: { type: Types.Relationship, label: 'Position', ref: 'Social Worker Position', initial: true },
	position: { type: Types.Select, options: 'adoption worker, recruitment worker, supervisor, administrator, family worker, other', label: 'Position', initial: true },
	agency: { type: Types.Relationship, label: 'agency', ref: 'Agency', initial: true },
	title: { type: Types.Text, label: 'title', index: true, initial: true }

});

SocialWorker.relationship({ path: 'children', ref: 'Child', refPath: 'adoptionWorker' });

// Pre Save
SocialWorker.schema.pre('save', function(next) {
	'use strict';

	// Populate the full name string for better identification when linking through Relationship field types
	this.name.full = this.name.first + ' ' + this.name.last;

	next();
});

// Define default columns in the admin interface and register the model
SocialWorker.defaultColumns = 'name.full, phone.work, phone.home, phone.cell, phone.preferred, email';
SocialWorker.register();<commit_msg>Add notes to Social Worker and remove the home phone field.<commit_after>var keystone = require('keystone'),
	Types = keystone.Field.Types;

// Create model
var SocialWorker = new keystone.List('Social Worker', {
	track: true,
	map: { name: 'name.full' },
	defaultSort: 'name.full'
});

// Create fields
SocialWorker.add('Permissions', {

	permissions: {
		isVerified: { type: Boolean, label: 'has a verified email address', default: false, noedit: true },
		isActive: { type: Boolean, label: 'is active', default: true, noedit: true }
	}

}, 'General Information', {

	name: {
		first: { type: Types.Text, label: 'first name', required: true, index: true, initial: true },
		last: { type: Types.Text, label: 'last name', required: true, index: true, initial: true },
		full: { type: Types.Text, label: 'name', hidden: true, noedit: true, initial: false }
	},

	password: { type: Types.Password, label: 'password', required: true, initial: true },
	// avatar: { type: Types.CloudinaryImage, label: 'avatar', folder: 'users/social workers', select: true, selectPrefix: 'users/social workers', autoCleanup: true }
	avatar: { type: Types.CloudinaryImage, label: 'avatar', folder: 'users/social workers', autoCleanup: true }

}, 'Contact Information', {

	email: { type: Types.Email, label: 'email address', unique: true, required: true, index: true, initial: true },

	phone: {
		work: { type: Types.Text, label: 'work phone number', initial: true },
		cell: { type: Types.Text, label: 'cell phone number', initial: true },
		preferred: { type: Types.Select, label: 'preferred phone', options: 'work, cell', initial: true }
	},

	address: {
	    street1: { type: Types.Text, label: 'address line 1', initial: true },
		street2: { type: Types.Text, label: 'address line 2', initial: true },
		city: { type: Types.Text, label: 'city', initial: true },
		state: { type: Types.Relationship, label: 'state', ref: 'State', index: true, initial: true },
		zipCode: { type: Types.Text, label: 'zip code', index: true, initial: true }
	}

}, 'Social Worker Information', {

	// position: { type: Types.Relationship, label: 'Position', ref: 'Social Worker Position', initial: true },
	position: { type: Types.Select, options: 'adoption worker, recruitment worker, supervisor, administrator, family worker, other', label: 'Position', initial: true },
	agency: { type: Types.Relationship, label: 'agency', ref: 'Agency', initial: true },
	title: { type: Types.Text, label: 'title', index: true, initial: true },
	notes: { type: Types.Textarea, label: 'notes', initial: true }

});

SocialWorker.relationship({ path: 'children', ref: 'Child', refPath: 'adoptionWorker' });

// Pre Save
SocialWorker.schema.pre('save', function(next) {
	'use strict';

	// Populate the full name string for better identification when linking through Relationship field types
	this.name.full = this.name.first + ' ' + this.name.last;

	next();
});

// Define default columns in the admin interface and register the model
SocialWorker.defaultColumns = 'name.full, phone.work, phone.home, phone.cell, phone.preferred, email';
SocialWorker.register();<|endoftext|>