<commit_before>import React, { PropTypes } from 'react';
import { Link } from 'react-router';
import { Table, Column, Cell } from 'fixed-data-table';
import { Button, ButtonGroup } from 'react-bootstrap';

import EventTimeline from './EventTimeline';
import TextCell from './TextCell';
import EdmConsts from '../../utils/Consts/EdmConsts';
import styles from './styles.module.css';

const NO_NEIGHBOR = 'NO_NEIGHBOR';

const TABLE_WIDTH = 1000;
const ROW_HEIGHT = 50;
const TABLE_OFFSET = 2;

const NEIGHBOR_VIEW = {
  TABLE: 'TABLE',
  TIMELINE: 'TIMELINE'
};

export default class RowNeighbors extends React.Component {

  static propTypes = {
    neighbors: PropTypes.array.isRequired,
    onClick: PropTypes.func.isRequired,
    formatValueFn: PropTypes.func.isRequired,
    entitySetTitle: PropTypes.string
  }

  constructor(props) {
    super(props);
    this.state = Object.assign(this.organizeNeighbors(props.neighbors), {
      neighborView: NEIGHBOR_VIEW.TABLE
    });
  }

  componentWillReceiveProps(nextProps) {
    if (this.props.neighbors !== nextProps.neighbors) {
      this.setState(this.organizeNeighbors(nextProps.neighbors));
    }
  }

  organizeNeighbors = (neighbors) => {
    const organizedNeighbors = {};
    const dateProps = {};
    neighbors.forEach((neighbor) => {
      const associationEntitySetId = neighbor.associationEntitySet.id;
      const neighborEntitySetId = (neighbor.neighborEntitySet) ? neighbor.neighborEntitySet.id : NO_NEIGHBOR;

      if (!organizedNeighbors[associationEntitySetId]) {
        organizedNeighbors[associationEntitySetId] = {
          [neighborEntitySetId]: [neighbor]
        };
        neighbor.associationPropertyTypes.forEach((propertyType) => {
          if (EdmConsts.EDM_DATE_TYPES.includes(propertyType.datatype)) {
            if (dateProps[associationEntitySetId]) {
              dateProps[associationEntitySetId].push(propertyType.id);
            }
            else {
              dateProps[associationEntitySetId] = [propertyType.id];
            }
          }
        });
      }
      else if (!organizedNeighbors[associationEntitySetId][neighborEntitySetId]) {
        organizedNeighbors[associationEntitySetId][neighborEntitySetId] = [neighbor];

        if (neighbor.neighborPropertyTypes) {
          neighbor.neighborPropertyTypes.forEach((propertyType) => {
            if (EdmConsts.EDM_DATE_TYPES.includes(propertyType.datatype)) {
              if (dateProps[neighborEntitySetId]) {
                dateProps[neighborEntitySetId].push(propertyType.id);
              }
              else {
                dateProps[neighborEntitySetId] = [propertyType.id];
              }
            }
          });
        }
      }
      else {
        organizedNeighbors[associationEntitySetId][neighborEntitySetId].push(neighbor);
      }
    });
    const selectedDateProps = dateProps;
    return { organizedNeighbors, dateProps, selectedDateProps };
  }

  renderColumns = (renderingAssociation, rowValues, neighborGroup, noNeighbor) => {
    const entitySetId = (noNeighbor) ? null : neighborGroup.neighborEntitySet.id;
    let numColumns = neighborGroup.associationPropertyTypes.length;
    if (!noNeighbor) numColumns += neighborGroup.neighborPropertyTypes.length;
    const propertyTypes = (renderingAssociation) ?
      neighborGroup.associationPropertyTypes : neighborGroup.neighborPropertyTypes;

    const columnWidth = (TABLE_WIDTH - 1) / numColumns;
    const allColumns = propertyTypes.map((propertyType) => {
      const field = `${propertyType.type.namespace}.${propertyType.type.name}`;
      const renderImage = (propertyType.type.name === 'mugshot'
        || propertyType.type.name === 'scars'
        || propertyType.type.name === 'tattoos');
      return (
        <Column
            key={`${entitySetId}-${propertyType.id}`}
            header={<Cell>{propertyType.title}</Cell>}
            cell={
              <TextCell
                  results={rowValues}
                  field={field}
                  formatValueFn={this.props.formatValueFn}
                  onClick={this.props.onClick}
                  width={columnWidth}
                  entitySetId={entitySetId}
                  propertyTypes={neighborGroup.neighborPropertyTypes}
                  renderImage={renderImage} />
            }
            width={columnWidth} />
      );
    });
    return allColumns;
  }

  renderNeighborGroupTitle = (neighbor, neighborId) => {
    const entitySetTitle = this.props.entitySetTitle || '';
    const neighborTitle = (neighborId === NO_NEIGHBOR)
      ?
?

      : (<Link to={`/entitysets/${neighborId}`} className={styles.neighborGroupTitle}>
        {neighbor.neighborEntitySet.title}
      </Link>);
    return (neighbor.src)
      ?

        {entitySetTitle} {`${neighbor.associationEntitySet.title}`} {neighborTitle}

    :

      {neighborTitle} {`${neighbor.associationEntitySet.title}`} {entitySetTitle}
;
  }

  renderNeighborGroup = (neighborGroup, neighborId, shouldShowTitle) => {
    const noNeighbor = neighborId === NO_NEIGHBOR;
    const tableHeight = ((neighborGroup.length + 1) * ROW_HEIGHT) + TABLE_OFFSET;

    const rowValues = neighborGroup.map((neighbor) => {
      const row = (noNeighbor) ? neighbor.associationDetails :
        Object.assign({}, neighbor.associationDetails, neighbor.neighborDetails);
      if (!noNeighbor) row.id = neighbor.neighborId;
      return row;
    });
    const associationColumns = this.renderColumns(true, rowValues, neighborGroup[0], noNeighbor);
    const neighborColumns = (noNeighbor) ? null :
      this.renderColumns(false, rowValues, neighborGroup[0], noNeighbor);

    const title = (shouldShowTitle) ? this.renderNeighborGroupTitle(neighborGroup[0], neighborId) : null;
    return (

        {title}

          {associationColumns}
          {neighborColumns}

    );
  }

  renderAssociationGroup = (associationGroup) => {
    const neighborGroups = Object.keys(associationGroup).map((neighborId) => {
      const neighborGroup = associationGroup[neighborId];
      return this.renderNeighborGroup(neighborGroup, neighborId, true);
    });
    const title = Object.values(associationGroup)[0][0].associationEntitySet.title;
    return (

{title}

        {neighborGroups}

    );
  }

  renderNeighbors = () => {
    const neighbors = Object.keys(this.state.organizedNeighbors).map((associationId) => {
      const associationGroup = this.state.organizedNeighbors[associationId];
      return (

          {this.renderAssociationGroup(associationGroup)}

      );
    });
    return neighbors;
  }

  renderTimeline = () => {
    return (
      <EventTimeline
          organizedNeighbors={this.state.organizedNeighbors}
          dateProps={this.state.dateProps}
          renderNeighborGroupFn={this.renderNeighborGroup} />
    );
  }

  renderViewToolbar = () => {
    return (

        <ButtonGroup>
          <Button
              onClick={() => {
                this.setState({ neighborView: NEIGHBOR_VIEW.TABLE });
              }}
              active={this.state.neighborView === NEIGHBOR_VIEW.TABLE}>
            Table</Button>
          <Button
              onClick={() => {
                this.setState({ neighborView: NEIGHBOR_VIEW.TIMELINE });
              }}
              active={this.state.neighborView === NEIGHBOR_VIEW.TIMELINE}>
            Timeline</Button>
        </ButtonGroup>

    );
  }

  render() {
    if (this.props.neighbors.length === 0) return null;
    const content = (this.state.neighborView === NEIGHBOR_VIEW.TABLE)
      ? this.renderNeighbors() : this.renderTimeline();
    return (

        {this.renderViewToolbar()}
        {content}

    );
  }

}
<commit_msg>fix timeline<commit_after>import React, { PropTypes } from 'react';
import { Link } from 'react-router';
import { Table, Column, Cell } from 'fixed-data-table';
import { Button, ButtonGroup } from 'react-bootstrap';

import EventTimeline from './EventTimeline';
import TextCell from './TextCell';
import EdmConsts from '../../utils/Consts/EdmConsts';
import styles from './styles.module.css';

const NO_NEIGHBOR = 'NO_NEIGHBOR';

const TABLE_WIDTH = 1000;
const ROW_HEIGHT = 50;
const TABLE_OFFSET = 2;

const NEIGHBOR_VIEW = {
  TABLE: 'TABLE',
  TIMELINE: 'TIMELINE'
};

export default class RowNeighbors extends React.Component {

  static propTypes = {
    neighbors: PropTypes.array.isRequired,
    onClick: PropTypes.func.isRequired,
    formatValueFn: PropTypes.func.isRequired,
    entitySetTitle: PropTypes.string
  }

  constructor(props) {
    super(props);
    this.state = Object.assign(this.organizeNeighbors(props.neighbors), {
      neighborView: NEIGHBOR_VIEW.TABLE
    });
  }

  componentWillReceiveProps(nextProps) {
    if (this.props.neighbors !== nextProps.neighbors) {
      this.setState(this.organizeNeighbors(nextProps.neighbors));
    }
  }

  organizeNeighbors = (neighbors) => {
    const organizedNeighbors = {};
    const dateProps = {};
    neighbors.forEach((neighbor) => {
      const associationEntitySetId = neighbor.associationEntitySet.id;
      const neighborEntitySetId = (neighbor.neighborEntitySet) ? neighbor.neighborEntitySet.id : NO_NEIGHBOR;

      if (!organizedNeighbors[associationEntitySetId]) {
        organizedNeighbors[associationEntitySetId] = {};
        neighbor.associationPropertyTypes.forEach((propertyType) => {
          if (EdmConsts.EDM_DATE_TYPES.includes(propertyType.datatype)) {
            if (dateProps[associationEntitySetId]) {
              dateProps[associationEntitySetId].push(propertyType.id);
            }
            else {
              dateProps[associationEntitySetId] = [propertyType.id];
            }
          }
        });
      }
      if (!organizedNeighbors[associationEntitySetId][neighborEntitySetId]) {
        organizedNeighbors[associationEntitySetId][neighborEntitySetId] = [neighbor];

        if (neighbor.neighborPropertyTypes) {
          neighbor.neighborPropertyTypes.forEach((propertyType) => {
            if (EdmConsts.EDM_DATE_TYPES.includes(propertyType.datatype)) {
              if (dateProps[neighborEntitySetId]) {
                dateProps[neighborEntitySetId].push(propertyType.id);
              }
              else {
                dateProps[neighborEntitySetId] = [propertyType.id];
              }
            }
          });
        }
      }
      else {
        organizedNeighbors[associationEntitySetId][neighborEntitySetId].push(neighbor);
      }
    });
    const selectedDateProps = dateProps;
    return { organizedNeighbors, dateProps, selectedDateProps };
  }

  renderColumns = (renderingAssociation, rowValues, neighborGroup, noNeighbor) => {
    const entitySetId = (noNeighbor) ? null : neighborGroup.neighborEntitySet.id;
    let numColumns = neighborGroup.associationPropertyTypes.length;
    if (!noNeighbor) numColumns += neighborGroup.neighborPropertyTypes.length;
    const propertyTypes = (renderingAssociation) ?
      neighborGroup.associationPropertyTypes : neighborGroup.neighborPropertyTypes;

    const columnWidth = (TABLE_WIDTH - 1) / numColumns;
    const allColumns = propertyTypes.map((propertyType) => {
      const field = `${propertyType.type.namespace}.${propertyType.type.name}`;
      const renderImage = (propertyType.type.name === 'mugshot'
        || propertyType.type.name === 'scars'
        || propertyType.type.name === 'tattoos');
      return (
        <Column
            key={`${entitySetId}-${propertyType.id}`}
            header={<Cell>{propertyType.title}</Cell>}
            cell={
              <TextCell
                  results={rowValues}
                  field={field}
                  formatValueFn={this.props.formatValueFn}
                  onClick={this.props.onClick}
                  width={columnWidth}
                  entitySetId={entitySetId}
                  propertyTypes={neighborGroup.neighborPropertyTypes}
                  renderImage={renderImage} />
            }
            width={columnWidth} />
      );
    });
    return allColumns;
  }

  renderNeighborGroupTitle = (neighbor, neighborId) => {
    const entitySetTitle = this.props.entitySetTitle || '';
    const neighborTitle = (neighborId === NO_NEIGHBOR)
      ?
?

      : (<Link to={`/entitysets/${neighborId}`} className={styles.neighborGroupTitle}>
        {neighbor.neighborEntitySet.title}
      </Link>);
    return (neighbor.src)
      ?

        {entitySetTitle} {`${neighbor.associationEntitySet.title}`} {neighborTitle}

    :

      {neighborTitle} {`${neighbor.associationEntitySet.title}`} {entitySetTitle}
;
  }

  renderNeighborGroup = (neighborGroup, neighborId, shouldShowTitle) => {
    const noNeighbor = neighborId === NO_NEIGHBOR;
    const tableHeight = ((neighborGroup.length + 1) * ROW_HEIGHT) + TABLE_OFFSET;

    const rowValues = neighborGroup.map((neighbor) => {
      const row = (noNeighbor) ? neighbor.associationDetails :
        Object.assign({}, neighbor.associationDetails, neighbor.neighborDetails);
      if (!noNeighbor) row.id = neighbor.neighborId;
      return row;
    });
    const associationColumns = this.renderColumns(true, rowValues, neighborGroup[0], noNeighbor);
    const neighborColumns = (noNeighbor) ? null :
      this.renderColumns(false, rowValues, neighborGroup[0], noNeighbor);

    const title = (shouldShowTitle) ? this.renderNeighborGroupTitle(neighborGroup[0], neighborId) : null;
    return (

        {title}

          {associationColumns}
          {neighborColumns}

    );
  }

  renderAssociationGroup = (associationGroup) => {
    const neighborGroups = Object.keys(associationGroup).map((neighborId) => {
      const neighborGroup = associationGroup[neighborId];
      return this.renderNeighborGroup(neighborGroup, neighborId, true);
    });
    const title = Object.values(associationGroup)[0][0].associationEntitySet.title;
    return (

{title}

        {neighborGroups}

    );
  }

  renderNeighbors = () => {
    const neighbors = Object.keys(this.state.organizedNeighbors).map((associationId) => {
      const associationGroup = this.state.organizedNeighbors[associationId];
      return (

          {this.renderAssociationGroup(associationGroup)}

      );
    });
    return neighbors;
  }

  renderTimeline = () => {
    return (
      <EventTimeline
          organizedNeighbors={this.state.organizedNeighbors}
          dateProps={this.state.dateProps}
          renderNeighborGroupFn={this.renderNeighborGroup} />
    );
  }

  renderViewToolbar = () => {
    return (

        <ButtonGroup>
          <Button
              onClick={() => {
                this.setState({ neighborView: NEIGHBOR_VIEW.TABLE });
              }}
              active={this.state.neighborView === NEIGHBOR_VIEW.TABLE}>
            Table</Button>
          <Button
              onClick={() => {
                this.setState({ neighborView: NEIGHBOR_VIEW.TIMELINE });
              }}
              active={this.state.neighborView === NEIGHBOR_VIEW.TIMELINE}>
            Timeline</Button>
        </ButtonGroup>

    );
  }

  render() {
    if (this.props.neighbors.length === 0) return null;
    const content = (this.state.neighborView === NEIGHBOR_VIEW.TABLE)
      ? this.renderNeighbors() : this.renderTimeline();
    return (

        {this.renderViewToolbar()}
        {content}

    );
  }

}
<|endoftext|>


<commit_before>import Buildfire, { components } from 'buildfire';
import React from 'react';
import cloneDeep from 'lodash/cloneDeep';
import ReactQuill from 'react-quill';
import ImageResize from 'quill-image-resize-module';

ReactQuill.Quill.register('modules/imageResize', ImageResize);

class LocationForm extends React.Component {
  constructor(props) {
    super(props);
    this.state = {};
  }

  componentWillMount() {
    let model = {
      title: '',
      subtitle: '',
      description: '',
      address: {},
      image: '',
      actionItems: [],
      categories: [],
      carousel: []
    };
    let state = Object.assign(model, cloneDeep(this.props.location) || {});
    this.setState(state);
  }

  componentWillUnmount() {
    window.google.maps.event.clearInstanceListeners(this.autocomplete);
    delete this.autocomplete;
  }

  /**
   * Handles mounting of dom dependant components
   * - Google Maps
   * - Carousel
   */
  componentDidMount() {
    // Mount google map autocomplete
    const { maps } = window.google;
    this.autocomplete = new maps.places.Autocomplete(this.addressInput);
    this.autocomplete.addListener('place_changed', () => this.onPlaceChanged());
    setTimeout(() => {
      let container = document.querySelector('.pac-container');
      this.addressInput.parentNode.appendChild(container);
      container.style.top = '10px';
      container.style.left = '10px';
    }, 400);

    // Mount carousel
    this.editor = new components.carousel.editor('#carousel');
    this.editor.loadItems(this.state.carousel);
    this.editor.onAddItems = (items) => this.updateCarouselState();
    this.editor.onDeleteItem = (items, index) => this.updateCarouselState();
    this.editor.onItemChange = (item) => this.updateCarouselState();
    this.editor.onOrderChange = (item, prevIndex, newIndex) => this.updateCarouselState();

    // Action items
    let selector = '#actionItems';
    let items = this.state.actionItems;
    this.actions = new components.actionItems.sortableList(selector, items);
    this.actions.onAddItems = () => this.updateActions();
    this.actions.onDeleteItem = () => this.updateActions();
    this.actions.onItemChange = () => this.updateActions();
    this.actions.onOrderChange = () => this.updateActions();

    document.querySelector('#actionItems .labels').innerHTML = 'Contact Information';
    document.querySelector('#actionItems a').innerHTML = 'Add Contact Information';

    // Set initial map height
    this.map.style.height = 0;

    // Mount map if address exists
    if (this.state.address.lat && this.state.address.lng) {
      this.mountMap(this.state.address);
    }
  }

  mountMap(address) {
    const { maps } = window.google;
    let defaultLocation = new maps.LatLng(address.lat, address.lng);
    let mapOptions = {
      zoom: 16,
      center: defaultLocation
    };
    this.map.style.height = '230px';
    this.mapInstance = new maps.Map(this.map, mapOptions);

    // Place a draggable marker on the map
    this.markerInstance = new maps.Marker({
      position: defaultLocation,
      map: this.mapInstance,
      draggable: true,
      title: 'Drag to choose a location'
    });

    // Handle makre drag
    maps.event.addListener(this.markerInstance, 'dragend', e => {
      let address = this.state.address;
      address.lat = e.latLng.lat();
      address.lng = e.latLng.lng();
      this.setState({ address });
    });
  }

  componentWillUpdate(nextProps, nextState) {
    const { address } = nextState;

    if (address.lat && address.lng && !this.mapInstance) {
      this.mountMap(address);
    }
  }

  updateActions() {
    this.setState({ actionItems: this.actions.items });
  }

  onInputChange(e) {
    const changes = {};
    changes[e.target.name] = e.target.value;
    this.setState(changes);
  }

  onDescriptionChange(description) {
    this.setState({ description });
  }

  onCategoryChange(e) {
    let { name, checked } = e.target;

    // Category was selected
    if (checked) {
      let { categories } = this.state;
      categories.push(name);
      this.setState({ categories });

    // Category was unselected
    } else {
      let index = this.state.categories.indexOf(name);
      let { categories } = this.state;
      categories.splice(index, 1);
      this.setState({ categories });
    }
  }

  /**
   * Handles updating the carousel state data
   */
  updateCarouselState() {
    const { items } = this.editor;
    this.setState({ carousel: items });
  }

  /**
   * Handle showing the image dialog
   */
  showImageDialog() {
    const dialogOptions = {
      showIcons: false,
      multiSelection: false
    };

    // Request user to select image
    Buildfire.imageLib.showDialog(dialogOptions, (err, result) => {
      if (err) return console.error(err);

      // Stop if we don't have any images
      if (!result || !result.selectedFiles || !result.selectedFiles.length) {
        return;
      }

      this.setState({ image: result.selectedFiles[0] });
    });
  }

  /**
   * Handle the google maps autocomplete place change
   */
  onPlaceChanged() {
    const place = this.autocomplete.getPlace();
    if (!place.geometry) {
      return this.setState({ address: {} });
    }

    const address = {
      name: this.addressInput.value,
      lat: place.geometry.location.lat(),
      lng: place.geometry.location.lng()
    };

    if (this.mapInstance && this.markerInstance) {
      const { maps } = window.google;
      const point = new maps.LatLng(address.lat, address.lng);
      this.mapInstance.panTo(point);
      this.markerInstance.setPosition(point);
    }

    this.setState({ address });
  }

  onAddressChange(e) {
    if (e.target.value === '') {
      this.setState({ address: {} });
    }
  }

  /**
   * Pass submissions to parent component
   *
   * @param   {Event} e Form submission event
   */
  onSubmit(e) {
    e.preventDefault();
    if (typeof this.state.address !== 'object') return;
    this.props.onSubmit(this.state);
  }

  onAutoKeyUp(e) {
    let keyCode = e.keyCode || e.which;
    if (keyCode === 13) {
      e.stopPropagation();
      e.preventDefault();
    }
  }

  imageHandler(image, callback) {
    const range = this.quillRef.getEditor().getSelection();
    Buildfire.notifications.prompt({
      message: 'What is the image URL'
    }, (value) => {
      if (value) {
        value = `https://czi3m2qn.cloudimg.io/cdn/n/n/${value}`;
        this.quillRef.getEditor().insertEmbed(range.index, 'image', value, 'user');
      }
    });
  }

  removeImage(e) {
    this.setState({ image: '' });
    e.preventDefault();
    return false;
  }

  modules = {
    imageResize: {},
    toolbar: {
      container: [
        [{ header: [1, 2, 3, false] }],
        [{ color: [] }, { background: [] }],
        ['bold', 'italic', 'underline', 'strike', 'blockquote'],
        [{'list': 'ordered'}, {'list': 'bullet'}],
        [{ align: [] }],
        [{'indent': '-1'}, {'indent': '+1'}],
        [{ color: [] }, { background: [] }],
        ['link', 'image', 'video']
      ],
      handlers: {
        // commenting this out fixed image upload in description
        // image: this.imageHandler.bind(this)
      },
    },
  }

  render() {
    const { title, address, description, image, categories, subtitle } = this.state;

    return (
      <form onSubmit={ e => this.onSubmit(e) } onKeyPress={ e => this.onAutoKeyUp(e) }>

          Title*
          <input
            maxLength={ 60 }
            onChange={ e => this.onInputChange(e) }
            value={ title }
            name='title'
            type='text'
            className='form-control' />

          Subtitle
          <input
            maxLength={ 90 }
            onChange={ e => this.onInputChange(e) }
            value={ subtitle }
            name='subtitle'
            className='form-control'
            placeholder='Optional'
            type='text'/>

          Categories

            { this.props.categories ? this.props.categories.map((category, index) => (

                <input
                  onChange={ e => this.onCategoryChange(e) }
                  type='checkbox'
                  name={ category.id }
                  checked={ categories.indexOf(category.id) > -1 } />

                { category.name }

            )) : null }

          Address*
          <input
            key='address-input'
            onChange={ e => this.onAddressChange(e) }
            ref={ n => this.addressInput = n }
            value={ address.name
              ? address.name
              : address.lat && address.lng
                ? `${address.lat}, ${address.lng}`
                : address.name }
            type='text'
            className='form-control' />

 this.map = n} />

          Description*

            <ReactQuill
              ref={ n => this.quillRef = n }
              modules={ this.modules }
              onChange={ value => this.onDescriptionChange(value) }
              defaultValue={ description } />

          List Image

            <div
              style={{ backgroundImage: image ? `url(${image})` : '' }}
              className='image-dialog'
              onClick={ () => this.showImageDialog() }>
              { this.state.image ? null : Add Image + }

             this.removeImage(e) }
              src='assets/img/cross.png' />

          <button
            disabled={ !title.length || !description.length || !address || !address.lat || !address.lng }
            type='submit'
            className='btn btn-primary'>
            { this.props.location ? 'Save Location' : 'Save Location' }
          </button>

      </form>
    );
  }
}

export default LocationForm;
<commit_msg>add imagelib to wysiwyg<commit_after>import Buildfire, { components } from 'buildfire';
import React from 'react';
import cloneDeep from 'lodash/cloneDeep';
import ReactQuill from 'react-quill';
import ImageResize from 'quill-image-resize-module';

ReactQuill.Quill.register('modules/imageResize', ImageResize);

class LocationForm extends React.Component {
  constructor(props) {
    super(props);
    this.state = {};
  }

  componentWillMount() {
    let model = {
      title: '',
      subtitle: '',
      description: '',
      address: {},
      image: '',
      actionItems: [],
      categories: [],
      carousel: []
    };
    let state = Object.assign(model, cloneDeep(this.props.location) || {});
    this.setState(state);
  }

  componentWillUnmount() {
    window.google.maps.event.clearInstanceListeners(this.autocomplete);
    delete this.autocomplete;
  }

  /**
   * Handles mounting of dom dependant components
   * - Google Maps
   * - Carousel
   */
  componentDidMount() {
    // Mount google map autocomplete
    const { maps } = window.google;
    this.autocomplete = new maps.places.Autocomplete(this.addressInput);
    this.autocomplete.addListener('place_changed', () => this.onPlaceChanged());
    setTimeout(() => {
      let container = document.querySelector('.pac-container');
      this.addressInput.parentNode.appendChild(container);
      container.style.top = '10px';
      container.style.left = '10px';
    }, 400);

    // Mount carousel
    this.editor = new components.carousel.editor('#carousel');
    this.editor.loadItems(this.state.carousel);
    this.editor.onAddItems = (items) => this.updateCarouselState();
    this.editor.onDeleteItem = (items, index) => this.updateCarouselState();
    this.editor.onItemChange = (item) => this.updateCarouselState();
    this.editor.onOrderChange = (item, prevIndex, newIndex) => this.updateCarouselState();

    // Action items
    let selector = '#actionItems';
    let items = this.state.actionItems;
    this.actions = new components.actionItems.sortableList(selector, items);
    this.actions.onAddItems = () => this.updateActions();
    this.actions.onDeleteItem = () => this.updateActions();
    this.actions.onItemChange = () => this.updateActions();
    this.actions.onOrderChange = () => this.updateActions();

    document.querySelector('#actionItems .labels').innerHTML = 'Contact Information';
    document.querySelector('#actionItems a').innerHTML = 'Add Contact Information';

    // Set initial map height
    this.map.style.height = 0;

    // Mount map if address exists
    if (this.state.address.lat && this.state.address.lng) {
      this.mountMap(this.state.address);
    }
  }

  mountMap(address) {
    const { maps } = window.google;
    let defaultLocation = new maps.LatLng(address.lat, address.lng);
    let mapOptions = {
      zoom: 16,
      center: defaultLocation
    };
    this.map.style.height = '230px';
    this.mapInstance = new maps.Map(this.map, mapOptions);

    // Place a draggable marker on the map
    this.markerInstance = new maps.Marker({
      position: defaultLocation,
      map: this.mapInstance,
      draggable: true,
      title: 'Drag to choose a location'
    });

    // Handle makre drag
    maps.event.addListener(this.markerInstance, 'dragend', e => {
      let address = this.state.address;
      address.lat = e.latLng.lat();
      address.lng = e.latLng.lng();
      this.setState({ address });
    });
  }

  componentWillUpdate(nextProps, nextState) {
    const { address } = nextState;

    if (address.lat && address.lng && !this.mapInstance) {
      this.mountMap(address);
    }
  }

  updateActions() {
    this.setState({ actionItems: this.actions.items });
  }

  onInputChange(e) {
    const changes = {};
    changes[e.target.name] = e.target.value;
    this.setState(changes);
  }

  onDescriptionChange(description) {
    this.setState({ description });
  }

  onCategoryChange(e) {
    let { name, checked } = e.target;

    // Category was selected
    if (checked) {
      let { categories } = this.state;
      categories.push(name);
      this.setState({ categories });

    // Category was unselected
    } else {
      let index = this.state.categories.indexOf(name);
      let { categories } = this.state;
      categories.splice(index, 1);
      this.setState({ categories });
    }
  }

  /**
   * Handles updating the carousel state data
   */
  updateCarouselState() {
    const { items } = this.editor;
    this.setState({ carousel: items });
  }

  /**
   * Handle showing the image dialog
   */
  showImageDialog() {
    const dialogOptions = {
      showIcons: false,
      multiSelection: false
    };

    // Request user to select image
    Buildfire.imageLib.showDialog(dialogOptions, (err, result) => {
      if (err) return console.error(err);

      // Stop if we don't have any images
      if (!result || !result.selectedFiles || !result.selectedFiles.length) {
        return;
      }

      this.setState({ image: result.selectedFiles[0] });
    });
  }

  /**
   * Handle the google maps autocomplete place change
   */
  onPlaceChanged() {
    const place = this.autocomplete.getPlace();
    if (!place.geometry) {
      return this.setState({ address: {} });
    }

    const address = {
      name: this.addressInput.value,
      lat: place.geometry.location.lat(),
      lng: place.geometry.location.lng()
    };

    if (this.mapInstance && this.markerInstance) {
      const { maps } = window.google;
      const point = new maps.LatLng(address.lat, address.lng);
      this.mapInstance.panTo(point);
      this.markerInstance.setPosition(point);
    }

    this.setState({ address });
  }

  onAddressChange(e) {
    if (e.target.value === '') {
      this.setState({ address: {} });
    }
  }

  /**
   * Pass submissions to parent component
   *
   * @param   {Event} e Form submission event
   */
  onSubmit(e) {
    e.preventDefault();
    if (typeof this.state.address !== 'object') return;
    this.props.onSubmit(this.state);
  }

  onAutoKeyUp(e) {
    let keyCode = e.keyCode || e.which;
    if (keyCode === 13) {
      e.stopPropagation();
      e.preventDefault();
    }
  }

  imageHandler = () => {
    const range = this.quillRef.getEditor().getSelection();
    buildfire.imageLib.showDialog({ showIcons: false, multiSelection: false }, (err, result) => {
      if (err) throw err;
      if (result.selectedFiles.length > 0) {
        const value = `https://czi3m2qn.cloudimg.io/cdn/n/n/${result.selectedFiles[0]}`;
        this.quillRef.getEditor().insertEmbed(range.index, 'image', value, 'user');
      }
    })
  }

  removeImage(e) {
    this.setState({ image: '' });
    e.preventDefault();
    return false;
  }

  modules = {
    imageResize: {},
    toolbar: {
      container: [
        [{ header: [1, 2, 3, false] }],
        [{ color: [] }, { background: [] }],
        ['bold', 'italic', 'underline', 'strike', 'blockquote'],
        [{'list': 'ordered'}, {'list': 'bullet'}],
        [{ align: [] }],
        [{'indent': '-1'}, {'indent': '+1'}],
        [{ color: [] }, { background: [] }],
        ['link', 'image', 'video']
      ],
      handlers: {
        // commenting this out fixed issue with image upload in description
        image: () => this.imageHandler()
      },
    },
  }

  render() {
    const { title, address, description, image, categories, subtitle } = this.state;

    return (
      <form onSubmit={ e => this.onSubmit(e) } onKeyPress={ e => this.onAutoKeyUp(e) }>

          Title*
          <input
            maxLength={ 60 }
            onChange={ e => this.onInputChange(e) }
            value={ title }
            name='title'
            type='text'
            className='form-control' />

          Subtitle
          <input
            maxLength={ 90 }
            onChange={ e => this.onInputChange(e) }
            value={ subtitle }
            name='subtitle'
            className='form-control'
            placeholder='Optional'
            type='text'/>

          Categories

            { this.props.categories ? this.props.categories.map((category, index) => (

                <input
                  onChange={ e => this.onCategoryChange(e) }
                  type='checkbox'
                  name={ category.id }
                  checked={ categories.indexOf(category.id) > -1 } />

                { category.name }

            )) : null }

          Address*
          <input
            key='address-input'
            onChange={ e => this.onAddressChange(e) }
            ref={ n => this.addressInput = n }
            value={ address.name
              ? address.name
              : address.lat && address.lng
                ? `${address.lat}, ${address.lng}`
                : address.name }
            type='text'
            className='form-control' />

 this.map = n} />

          Description*

            <ReactQuill
              ref={ n => this.quillRef = n }
              modules={ this.modules }
              onChange={ value => this.onDescriptionChange(value) }
              defaultValue={ description } />

          List Image

            <div
              style={{ backgroundImage: image ? `url(${image})` : '' }}
              className='image-dialog'
              onClick={ () => this.showImageDialog() }>
              { this.state.image ? null : Add Image + }

             this.removeImage(e) }
              src='assets/img/cross.png' />

          <button
            disabled={ !title.length || !description.length || !address || !address.lat || !address.lng }
            type='submit'
            className='btn btn-primary'>
            { this.props.location ? 'Save Location' : 'Save Location' }
          </button>

      </form>
    );
  }
}

export default LocationForm;
<|endoftext|>


<commit_before>var $ = require('jQuery');
var onReady = require('kwf/on-ready');
var gmapLoader = require('kwf/google-map/loader');
var gmapMap = require('kwf/google-map/map');

var renderedMaps = [];

var renderMap = function(map) {
    if ($.inArray(map, renderedMaps) != -1) return;
    renderedMaps.push(map);

    var cfg = map.find(".options", true);
    if (!cfg) return;
    cfg = $.parseJSON(cfg.val());

    var text = map.find("div.text");
    cfg.mapContainer = map;
    if (!cfg.markers) {
        cfg.markers = {
            longitude : cfg.longitude,
            latitude  : cfg.latitude,
            autoOpenInfoWindow: cfg.autoOpenInfoWindow
        };
        if (text.length) cfg.markers.infoHtml = text.html();
    }

    var cls = eval(cfg.mapClass) || gmapMap;
    var myMap = new cls(cfg);
    map.map = myMap;

    gmapLoader(function() {
        this.show();
    }, myMap);

    return myMap;
};

onReady.onRender('.kwcClass', function(map) {
    if (!map.get('gmapObject') && !map.is(':hidden')) {
        map.data('gmapObject', renderMap(map));
    }
}, { checkVisibility: true });

onReady.onRender('.kwcClass', function (el) {
    var mobileOverlayOpen = el.find('.mobileOverlayOpen');
    var mobileOverlayClose = el.find('.mobileOverlayClose');

    mobileOverlayOpen.click(function (ev) {
        if ($(this).is(':visible')) {
            var newEl = $(this).parent();
            newEl.addClass('navigate');
            $('html, body').animate({
                scrollTop: newEl.offset().top
            }, 400, function() {
                google.maps.event.trigger(newEl.get(0).map.gmap, 'resize');
            });
        }
    });

    mobileOverlayClose.on('touchstart click', function (ev) {
        if ($(this).is(':visible')) {
            var newEl = $(this).parent();
            newEl.removeClass('navigate');
            $('html, body').animate({
                scrollTop: newEl.offset().top - (($(window).innerHeight() - newEl.height()) / 2)
            });
        }
    });
});
<commit_msg>Fix GoogleMapView mobile enlarge resize<commit_after>var $ = require('jQuery');
var onReady = require('kwf/on-ready');
var gmapLoader = require('kwf/google-map/loader');
var gmapMap = require('kwf/google-map/map');

var renderedMaps = [];

var renderMap = function(map) {
    if ($.inArray(map, renderedMaps) != -1) return;
    renderedMaps.push(map);

    var cfg = map.find(".options", true);
    if (!cfg) return;
    cfg = $.parseJSON(cfg.val());

    var text = map.find("div.text");
    cfg.mapContainer = map;
    if (!cfg.markers) {
        cfg.markers = {
            longitude : cfg.longitude,
            latitude  : cfg.latitude,
            autoOpenInfoWindow: cfg.autoOpenInfoWindow
        };
        if (text.length) cfg.markers.infoHtml = text.html();
    }

    var cls = eval(cfg.mapClass) || gmapMap;
    var myMap = new cls(cfg);
    map.map = myMap;

    gmapLoader(function() {
        this.show();
    }, myMap);

    return myMap;
};

onReady.onRender('.kwcClass', function(map) {
    if (!map.get('gmapObject') && !map.is(':hidden')) {
        map.data('gmapObject', renderMap(map));
    }
}, { checkVisibility: true });

onReady.onRender('.kwcClass', function (el) {
    var mobileOverlayOpen = el.find('.mobileOverlayOpen');
    var mobileOverlayClose = el.find('.mobileOverlayClose');

    mobileOverlayOpen.click(function (ev) {
        if ($(this).is(':visible')) {
            var newEl = $(this).parent();
            newEl.addClass('navigate');
            $('html, body').animate({
                scrollTop: newEl.offset().top
            }, 400, function() {
                google.maps.event.trigger(newEl.data('gmapObject').gmap, 'resize');
            });
        }
    });

    mobileOverlayClose.on('touchstart click', function (ev) {
        if ($(this).is(':visible')) {
            var newEl = $(this).parent();
            newEl.removeClass('navigate');
            $('html, body').animate({
                scrollTop: newEl.offset().top - (($(window).innerHeight() - newEl.height()) / 2)
            });
        }
    });
});
<|endoftext|>


<commit_before>
/*
Copyright Â© 2001-2004 World Wide Web Consortium,
(Massachusetts Institute of Technology, European Research Consortium
for Informatics and Mathematics, Keio University). All
Rights Reserved. This work is distributed under the W3CÂ® Software License [1] in the
hope that it will be useful, but WITHOUT ANY WARRANTY; without even
the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.

[1] http://www.w3.org/Consortium/Legal/2002/copyright-software-20021231
*/

   /**
    *  Gets URI that identifies the test.
    *  @return uri identifier of test
    */
function getTargetURI() {
      return "http://www.w3.org/2001/DOM-Test-Suite/level2/html/button03";
   }

var docsLoaded = -1000000;
var builder = null;

//
//   This function is called by the testing framework before
//      running the test suite.
//
//   If there are no configuration exceptions, asynchronous
//        document loading is started.  Otherwise, the status
//        is set to complete and the exception is immediately
//        raised when entering the body of the test.
//
function setUpPage() {
   setUpPageStatus = 'running';
   try {
     //
     //   creates test document builder, may throw exception
     //
     builder = createConfiguredBuilder();

      docsLoaded = 0;

      var docRef = null;
      if (typeof(this.doc) != 'undefined') {
        docRef = this.doc;
      }
      docsLoaded += preload(docRef, "doc", "button");

       if (docsLoaded == 1) {
          setUpPageStatus = 'complete';
       }
    } catch(ex) {
    	catchInitializationError(builder, ex);
        setUpPageStatus = 'complete';
    }
}

//
//   This method is called on the completion of
//      each asychronous load started in setUpTests.
//
//   When every synchronous loaded document has completed,
//      the page status is changed which allows the
//      body of the test to be executed.
function loadComplete() {
    if (++docsLoaded == 1) {
        setUpPageStatus = 'complete';
    }
}

/**
*
The value of attribute action of the form element which contains this button is read and checked against the expected value

* @author Netscape
* @author Sivakiran Tummala
* @see http://www.w3.org/TR/1998/REC-DOM-Level-1-19981001/level-one-html#ID-71254493
* @see http://www.w3.org/TR/1998/REC-DOM-Level-1-19981001/level-one-html#ID-74049184
*/
function button03() {
   var success;
    if(checkInitialization(builder, "button03") != null) return;
    var nodeList;
      var testNode;
      var formNode;
      var vfaction;
      var doc;

      var docRef = null;
      if (typeof(this.doc) != 'undefined') {
        docRef = this.doc;
      }
      doc = load(docRef, "doc", "button");
      nodeList = doc.getElementsByTagName("button");
      assertSize("Asize",2,nodeList);
testNode = nodeList.item(0);
      formNode = testNode.form;

      vfaction = formNode.action;

      assertEquals("formLink","...",vfaction);

}

function runTest() {
   button03();
}
<commit_msg>Checked in a file missed when I landed just now.<commit_after>
/*
Copyright Â© 2001-2004 World Wide Web Consortium,
(Massachusetts Institute of Technology, European Research Consortium
for Informatics and Mathematics, Keio University). All
Rights Reserved. This work is distributed under the W3CÂ® Software License [1] in the
hope that it will be useful, but WITHOUT ANY WARRANTY; without even
the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.

[1] http://www.w3.org/Consortium/Legal/2002/copyright-software-20021231
*/

   /**
    *  Gets URI that identifies the test.
    *  @return uri identifier of test
    */
function getTargetURI() {
      return "http://www.w3.org/2001/DOM-Test-Suite/level2/html/button03";
   }

var docsLoaded = -1000000;
var builder = null;

//
//   This function is called by the testing framework before
//      running the test suite.
//
//   If there are no configuration exceptions, asynchronous
//        document loading is started.  Otherwise, the status
//        is set to complete and the exception is immediately
//        raised when entering the body of the test.
//
function setUpPage() {
   setUpPageStatus = 'running';
   try {
     //
     //   creates test document builder, may throw exception
     //
     builder = createConfiguredBuilder();

      docsLoaded = 0;

      var docRef = null;
      if (typeof(this.doc) != 'undefined') {
        docRef = this.doc;
      }
      docsLoaded += preload(docRef, "doc", "button");

       if (docsLoaded == 1) {
          setUpPageStatus = 'complete';
       }
    } catch(ex) {
    	catchInitializationError(builder, ex);
        setUpPageStatus = 'complete';
    }
}

//
//   This method is called on the completion of
//      each asychronous load started in setUpTests.
//
//   When every synchronous loaded document has completed,
//      the page status is changed which allows the
//      body of the test to be executed.
function loadComplete() {
    if (++docsLoaded == 1) {
        setUpPageStatus = 'complete';
    }
}

/**
*
The value of attribute action of the form element which contains this button is read and checked against the expected value

* @author Netscape
* @author Sivakiran Tummala
* @see http://www.w3.org/TR/1998/REC-DOM-Level-1-19981001/level-one-html#ID-71254493
* @see http://www.w3.org/TR/1998/REC-DOM-Level-1-19981001/level-one-html#ID-74049184
*/
function button03() {
   var success;
    if(checkInitialization(builder, "button03") != null) return;
    var nodeList;
      var testNode;
      var formNode;
      var vfaction;
      var doc;

      var docRef = null;
      if (typeof(this.doc) != 'undefined') {
        docRef = this.doc;
      }
      doc = load(docRef, "doc", "button");
      nodeList = doc.getElementsByTagName("button");
      assertSize("Asize",2,nodeList);
testNode = nodeList.item(0);
      formNode = testNode.form;

      vfaction = formNode.action;

//  WebKit modification: 26-August-2010
      var expectedAction = document.URL.replace(/[^/]*$/, "") + "...";
//  End WebKit modification

      assertEquals("formLink",expectedAction,vfaction);

}

function runTest() {
   button03();
}
<|endoftext|>


<commit_before>(function() {
    'use strict';
    function AddResetButtonToInput() {
        return {
            restrict: 'A',
            require: 'ngModel',
            link: function (scope, iElement, iAttrs, ngModel) {
                var margin = 5;
                var wrapper = angular.element('

');

                iElement.wrap(wrapper);

                var clearButton = angular.element('

');
                var loupeIcone = angular.element('

');

                clearButton.css('top','2px');
                clearButton.css('left',iElement.width()-margin);
                clearButton.css('display','none');

                loupeIcone.css('top','2px');
                loupeIcone.css('left',iElement.width()-margin);
                loupeIcone.css('display','block');

                iElement.parent().append(clearButton);
                iElement.parent().append(loupeIcone);

                scope.$watch(function(){
                        return ngModel.$modelValue;
                    }, function (value) {
                    if(value) {
                        clearButton.css('display','block');
                        loupeIcone.css('display','none');
                    } else {
                        loupeIcone.css('display','block');
                        clearButton.css('display','none');
                    }
                });

                clearButton.on('click',function(){
                    scope.$apply(function(){
                        ngModel.$setViewValue('');
                        ngModel.$render();
                    });

                });
            }
        };
    }

    angular.module('talend.widget')
        .directive('addResetButtonToInput', AddResetButtonToInput);
})();
<commit_msg>TDP-551: use new magnifier icon in js<commit_after>(function() {
    'use strict';
    function AddResetButtonToInput() {
        return {
            restrict: 'A',
            require: 'ngModel',
            link: function (scope, iElement, iAttrs, ngModel) {
                var margin = 5;
                var wrapper = angular.element('

');

                iElement.wrap(wrapper);

                var clearButton = angular.element('

');
                var loupeIcone = angular.element('

');

                clearButton.css('top','2px');
                clearButton.css('left',iElement.width()-margin);
                clearButton.css('display','none');

                loupeIcone.css('top','2px');
                loupeIcone.css('left',iElement.width()-margin);
                loupeIcone.css('display','block');

                iElement.parent().append(clearButton);
                iElement.parent().append(loupeIcone);

                scope.$watch(function(){
                        return ngModel.$modelValue;
                    }, function (value) {
                    if(value) {
                        clearButton.css('display','block');
                        loupeIcone.css('display','none');
                    } else {
                        loupeIcone.css('display','block');
                        clearButton.css('display','none');
                    }
                });

                clearButton.on('click',function(){
                    scope.$apply(function(){
                        ngModel.$setViewValue('');
                        ngModel.$render();
                    });

                });
            }
        };
    }

    angular.module('talend.widget')
        .directive('addResetButtonToInput', AddResetButtonToInput);
})();
<|endoftext|>


<commit_before>/**
 * @license
 * Copyright 2019 The FOAM Authors. All Rights Reserved.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

foam.CLASS({
  package: 'foam.nanos.auth',
  name: 'UserAndGroupAuthService',
  flags: ['java'],

  implements: [
    'foam.nanos.auth.AuthService',
    'foam.nanos.NanoService'
  ],

  imports: [
    'DAO localGroupDAO',
    'DAO localSessionDAO',
    'DAO localUserDAO'
  ],

  javaImports: [
    'foam.core.X',
    'foam.dao.DAO',
    'foam.nanos.auth.LifecycleState',
    'foam.nanos.auth.Subject',
    'foam.nanos.auth.User',
    'foam.nanos.logger.Logger',
    'foam.nanos.notification.Notification',
    'foam.nanos.session.Session',
    'foam.util.Email',
    'foam.util.Password',
    'foam.util.SafetyUtil',

    'java.security.Permission',
    'java.util.Calendar',
    'javax.security.auth.AuthPermission',

    'static foam.mlang.MLang.AND',
    'static foam.mlang.MLang.CLASS_OF',
    'static foam.mlang.MLang.EQ',
    'static foam.mlang.MLang.OR'
  ],

  constants: [
    {
      name: 'CHECK_USER_PERMISSION',
      type: 'String',
      value: 'service.auth.checkUser'
    }
  ],

  methods: [
    {
      name: 'start',
      javaCode: '// nothing here'
    },
    {
      name: 'getCurrentSubject',
      javaCode: `
        Session session = x.get(Session.class);
        // fetch context and check if not null or user id is 0
        if ( session == null || session.getUserId() == 0 ) {
          throw new AuthenticationException("Not logged in");
        }
        // get user from session id
        User user = (User) ((DAO) getLocalUserDAO()).find(session.getUserId());
        user.validateAuth(x);
        // check if group enabled
        Group group = getCurrentGroup(x);
        if ( group != null && ! group.getEnabled() ) {
          throw new AuthenticationException("Group disabled");
        }
        Subject subject = (Subject) x.get("subject");
        return subject;
      `
    },
    {
      name: 'loginHelper',
      documentation: `Helper function to reduce duplicated code.`,
      type: 'User',
      args: [
        {
          name: 'x',
          type: 'Context'
        },
        {
          name: 'user',
          type: 'User'
        },
        {
          name: 'password',
          type: 'String'
        }
      ],
      javaThrows: ['foam.nanos.auth.AuthenticationException'],
      javaCode: `
      try {
        if ( user == null ) {
          throw new AuthenticationException("User not found");
        }

        // check that the user is active
        assertUserIsActive(user);

        // check if user enabled
        if ( ! user.getEnabled() ) {
          throw new AuthenticationException("User disabled");
        }

        // check if user login enabled
        if ( ! user.getLoginEnabled() ) {
          throw new AuthenticationException("Login disabled");
        }

        // check if group enabled
        X userX = x.put("subject", new Subject.Builder(x).setUser(user).build());
        Group group = user.findGroup(userX);
        if ( group != null && ! group.getEnabled() ) {
          throw new AuthenticationException("Group disabled");
        }

        if ( ! Password.verify(password, user.getPassword()) ) {
          throw new AuthenticationException("Invalid Password");
        }

        // Freeze user
        user = (User) user.fclone();
        user.freeze();

        Session session = x.get(Session.class);
        session.setUserId(user.getId());

        if ( Group.ADMIN_GROUP.equalsIgnoreCase(user.getGroup()) ||
             check(x.put("user", user), "*") ) {
          session.setClusterable(false);
          String msg = "Admin login for " + user.getId() + " succeeded on " + System.getProperty("hostname", "localhost");
          ((foam.nanos.logger.Logger) x.get("logger")).warning(msg);
          Notification notification = new Notification.Builder(x)
            .setTemplate("NOC");
            .setToastMessage(msg);
            .setBody(msg)
            .build();
          ((DAO) x.get("localNotificationDAO")).put(notification);
        }

        ((DAO) getLocalSessionDAO()).inX(x).put(session);
        session.setContext(session.applyTo(session.getContext()));
        return user;
      } catch ( AuthenticationException e ) {
        if ( user != null &&
             ( Group.ADMIN_GROUP.equalsIgnoreCase(user.getGroup()) ||
               check(x.put("user", user), "*") ) ) {
          String msg = "Admin login for " + user.getId() + " failed on " + System.getProperty("hostname", "localhost");
          ((foam.nanos.logger.Logger) x.get("logger")).warning(msg);
          Notification notification = new Notification.Builder(x)
            .setTemplate("NOC");
            .setToastMessage(msg);
            .setBody(msg)
            .build();
          ((DAO) x.get("localNotificationDAO")).put(notification);
        }
        throw e;
      }
      `
    },
    {
      name: 'login',
      documentation: `Login a user by their identifier (email or username) provided, validate the password and
        return the user in the context`,
      javaCode: `
        User user = (User) ((DAO) getLocalUserDAO())
          .inX(x)
          .find(
            AND(
              OR(
                EQ(User.EMAIL, identifier.toLowerCase()),
                EQ(User.USER_NAME, identifier)
              ),
              CLASS_OF(User.class)
            )
          );

        if ( user == null ) {
          throw new AuthenticationException("User not found");
        }
        return loginHelper(x, user, password);
      `
    },
    {
      name: 'checkUser',
      documentation: `Checks if the user passed into the method has the passed
        in permission attributed to it by checking their group. No check on User
        and group enabled flags.`,
      javaCode: `
        // check whether user has permission to check user permissions
        if ( ! check(x, CHECK_USER_PERMISSION) ) throw new AuthorizationException();

        if ( user == null || permission == null ) return false;

        try {
          String groupId = (String) user.getGroup();

          while ( ! SafetyUtil.isEmpty(groupId) ) {
            Group group = (Group) ((DAO) getLocalGroupDAO()).find(groupId);

            // if group is null break
            if ( group == null ) break;

            // check permission
            if ( group.implies(x, new AuthPermission(permission)) ) return true;

            // check parent group
            groupId = group.getParent();
          }
        } catch (Throwable t) {
        }

        return false;
      `
    },
    {
      name: 'check',
      documentation: `Check if the user in the context supplied has the right
        permission.`,
      javaCode: `
        if ( x == null || permission == null ) return false;

        Permission p = new AuthPermission(permission);

        try {
          Group group = getCurrentGroup(x);

          while ( group != null ) {

            // check permission
            if ( group.implies(x, p) ) return true;

            // check parent group
            group = (Group) ((DAO) getLocalGroupDAO()).find(group.getParent());
          }
        } catch (IllegalArgumentException e) {
          Logger logger = (Logger) x.get("logger");
          logger.error("check", p, e);
        } catch (Throwable t) {
        }

        return false;
      `
    },
    {
      name: 'validatePassword',
      javaCode: `
        // Password policy to validate against
        PasswordPolicy passwordPolicy = null;

        // Retrieve the logger
        Logger logger = (Logger) x.get("logger");

        // Retrieve the password policy from the user and group when available
        if ( user != null ) {
          Group ancestor = (Group) x.get("group");
          if ( ancestor != null ) {
            // Check password policy
            passwordPolicy = ancestor.getPasswordPolicy();
            while ( passwordPolicy == null || ! passwordPolicy.getEnabled() ) {
              ancestor = ancestor.getAncestor(x, ancestor);
              if ( ancestor == null ) break;
              passwordPolicy = ancestor.getPasswordPolicy();
            }
          }
        }

        // Use the default password policy if nothing is found
        if ( passwordPolicy == null || ! passwordPolicy.getEnabled() ) {
          passwordPolicy = new PasswordPolicy();
          passwordPolicy.setEnabled(true);
        }

        // Validate the password against the password policy
        passwordPolicy.validate(user, potentialPassword);
      `
    },
    {
      name: 'assertUserIsActive',
      documentation: `Given a user, we check whether the user is ACTIVE.`,
      args: [
        {
          name: 'user',
          type: 'foam.nanos.auth.User'
        }
      ],
      javaCode: `
      // check that the user is active
      if ( user instanceof LifecycleAware && ((LifecycleAware)user).getLifecycleState() != LifecycleState.ACTIVE ) {
        throw new AuthenticationException("User is not active");
      }
      `
    },
    {
      name: 'updatePassword',
      documentation: `Given a context with a user, validate the password to be
        updated and return a context with the updated user information.`,
      javaCode: `
        if ( x == null || SafetyUtil.isEmpty(oldPassword) || SafetyUtil.isEmpty(newPassword) ) {
          throw new RuntimeException("Password fields cannot be blank");
        }

        Session session = x.get(Session.class);
        if ( session == null || session.getUserId() == 0 ) {
          throw new AuthenticationException("User not found");
        }

        User user = (User) ((DAO) getLocalUserDAO()).find(session.getUserId());
        if ( user == null ) {
          throw new AuthenticationException("User not found");
        }

        // check that the user is active
        assertUserIsActive(user);

        // check if user enabled
        if ( ! user.getEnabled() ) {
          throw new AuthenticationException("User disabled");
        }

        // check if user login enabled
        if ( ! user.getLoginEnabled() ) {
          throw new AuthenticationException("Login disabled");
        }

        // check if group enabled
        Group group = user.findGroup(x);
        if ( group != null && ! group.getEnabled() ) {
          throw new AuthenticationException("Group disabled");
        }

        // check if password is valid per validatePassword method
        validatePassword(x, user, newPassword);

        // old password does not match
        if ( ! Password.verify(oldPassword, user.getPassword()) ) {
          throw new RuntimeException("Old password is incorrect");
        }

        // new password is the same
        if ( Password.verify(newPassword, user.getPassword()) ) {
          throw new RuntimeException("New password must be different");
        }

        // store new password in DAO and put in context
        user = (User) user.fclone();
        user.setPasswordLastModified(Calendar.getInstance().getTime());
        user.setPreviousPassword(user.getPassword());
        user.setPassword(Password.hash(newPassword));
        // TODO: modify line to allow actual setting of password expiry in cases where users are required to periodically update their passwords
        user.setPasswordExpiry(null);
        user = (User) ((DAO) getLocalUserDAO()).put(user);
        Subject subject = new Subject.Builder(x).setUser(user).build();
        session.setContext(session.getContext().put("subject", subject).put("group", group));
        return user;
      `
    },
    {
      name: 'validateUser',
      documentation: `Used to validate properties of a user. This will be called
        on registration of users. Will mainly be used as a veto method. Users
        should have id, email, first name, last name, password for registration`,
      javaCode: `
        if ( user == null ) {
          throw new AuthenticationException("Invalid User");
        }

        if ( SafetyUtil.isEmpty(user.getEmail()) ) {
          throw new AuthenticationException("Email is required for creating a user");
        }

        if ( ! Email.isValid(user.getEmail()) ) {
          throw new AuthenticationException("Email format is invalid");
        }

        if ( SafetyUtil.isEmpty(user.getFirstName()) ) {
          throw new AuthenticationException("First Name is required for creating a user");
        }

        if ( SafetyUtil.isEmpty(user.getLastName()) ) {
          throw new AuthenticationException("Last Name is required for creating a user");
        }

        if ( SafetyUtil.isEmpty(user.getPassword()) ) {
          throw new AuthenticationException("Password is required for creating a user");
        }

        validatePassword(x, user, user.getPassword());
      `
    },
    {
      name: 'logout',
      documentation: `Just return a null user for now. Not sure how to handle
        the cleanup of the current context.`,
      javaCode: `
        Session session = x.get(Session.class);
        if ( session != null && session.getUserId() != 0 ) {
          ((DAO) getLocalSessionDAO()).remove(session);
        }
      `
    },
    {
      name: 'getCurrentGroup',
      documentation: `Gets the effective group from a context.`,
      javaCode: `
        // Highest precedence: Just return the group from the context if it's already
        // been set.
        Group group = (Group) x.get("group");

        if ( group != null ) return group;

        Subject subject = (Subject) x.get("subject");
        User user = subject.getUser();
        User agent = subject.getRealUser();

        // Second highest precedence: If one user is acting as another, return the
        // group on the junction between them.
        if ( user != null ) {
          if ( agent != null && agent != user ) {
            DAO agentJunctionDAO = (DAO) x.get("agentJunctionDAO");
            UserUserJunction junction = (UserUserJunction) agentJunctionDAO.find(
              AND(
                EQ(UserUserJunction.SOURCE_ID, agent.getId()),
                EQ(UserUserJunction.TARGET_ID, user.getId())
              )
            );

            if ( junction == null ) {
              ((foam.nanos.logger.Logger) x.get("logger")).warning("There was a user and an agent in the context, but a junction between them was not found.", "user", user.getId(), "agent", agent.getId());
              throw new RuntimeException("There was a user and an agent in the context, but a junction between them was not found.");
            }

            return (Group) ((DAO) getLocalGroupDAO()).inX(x).find(junction.getGroup());
          }

          // Third highest precedence: If a user is logged in but not acting as
          // another user, return their group.
          return (Group) ((DAO) getLocalGroupDAO()).inX(x).find(user.getGroup());
        }

        // If none of the cases above match, return null.
        // TODO: Should this throw an error instead?
        return null;
      `
    }
  ]
});

<commit_msg>compile before commit<commit_after>/**
 * @license
 * Copyright 2019 The FOAM Authors. All Rights Reserved.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

foam.CLASS({
  package: 'foam.nanos.auth',
  name: 'UserAndGroupAuthService',
  flags: ['java'],

  implements: [
    'foam.nanos.auth.AuthService',
    'foam.nanos.NanoService'
  ],

  imports: [
    'DAO localGroupDAO',
    'DAO localSessionDAO',
    'DAO localUserDAO'
  ],

  javaImports: [
    'foam.core.X',
    'foam.dao.DAO',
    'foam.nanos.auth.LifecycleState',
    'foam.nanos.auth.Subject',
    'foam.nanos.auth.User',
    'foam.nanos.logger.Logger',
    'foam.nanos.notification.Notification',
    'foam.nanos.session.Session',
    'foam.util.Email',
    'foam.util.Password',
    'foam.util.SafetyUtil',

    'java.security.Permission',
    'java.util.Calendar',
    'javax.security.auth.AuthPermission',

    'static foam.mlang.MLang.AND',
    'static foam.mlang.MLang.CLASS_OF',
    'static foam.mlang.MLang.EQ',
    'static foam.mlang.MLang.OR'
  ],

  constants: [
    {
      name: 'CHECK_USER_PERMISSION',
      type: 'String',
      value: 'service.auth.checkUser'
    }
  ],

  methods: [
    {
      name: 'start',
      javaCode: '// nothing here'
    },
    {
      name: 'getCurrentSubject',
      javaCode: `
        Session session = x.get(Session.class);
        // fetch context and check if not null or user id is 0
        if ( session == null || session.getUserId() == 0 ) {
          throw new AuthenticationException("Not logged in");
        }
        // get user from session id
        User user = (User) ((DAO) getLocalUserDAO()).find(session.getUserId());
        user.validateAuth(x);
        // check if group enabled
        Group group = getCurrentGroup(x);
        if ( group != null && ! group.getEnabled() ) {
          throw new AuthenticationException("Group disabled");
        }
        Subject subject = (Subject) x.get("subject");
        return subject;
      `
    },
    {
      name: 'loginHelper',
      documentation: `Helper function to reduce duplicated code.`,
      type: 'User',
      args: [
        {
          name: 'x',
          type: 'Context'
        },
        {
          name: 'user',
          type: 'User'
        },
        {
          name: 'password',
          type: 'String'
        }
      ],
      javaThrows: ['foam.nanos.auth.AuthenticationException'],
      javaCode: `
      try {
        if ( user == null ) {
          throw new AuthenticationException("User not found");
        }

        // check that the user is active
        assertUserIsActive(user);

        // check if user enabled
        if ( ! user.getEnabled() ) {
          throw new AuthenticationException("User disabled");
        }

        // check if user login enabled
        if ( ! user.getLoginEnabled() ) {
          throw new AuthenticationException("Login disabled");
        }

        // check if group enabled
        X userX = x.put("subject", new Subject.Builder(x).setUser(user).build());
        Group group = user.findGroup(userX);
        if ( group != null && ! group.getEnabled() ) {
          throw new AuthenticationException("Group disabled");
        }

        if ( ! Password.verify(password, user.getPassword()) ) {
          throw new AuthenticationException("Invalid Password");
        }

        // Freeze user
        user = (User) user.fclone();
        user.freeze();

        Session session = x.get(Session.class);
        session.setUserId(user.getId());

        if ( Group.ADMIN_GROUP.equalsIgnoreCase(user.getGroup()) ||
             check(x.put("user", user), "*") ) {
          session.setClusterable(false);
          String msg = "Admin login for " + user.getId() + " succeeded on " + System.getProperty("hostname", "localhost");
          ((foam.nanos.logger.Logger) x.get("logger")).warning(msg);
          Notification notification = new Notification.Builder(x)
            .setTemplate("NOC")
            .setToastMessage(msg)
            .setBody(msg)
            .build();
          ((DAO) x.get("localNotificationDAO")).put(notification);
        }

        ((DAO) getLocalSessionDAO()).inX(x).put(session);
        session.setContext(session.applyTo(session.getContext()));
        return user;
      } catch ( AuthenticationException e ) {
        if ( user != null &&
             ( Group.ADMIN_GROUP.equalsIgnoreCase(user.getGroup()) ||
               check(x.put("user", user), "*") ) ) {
          String msg = "Admin login for " + user.getId() + " failed on " + System.getProperty("hostname", "localhost");
          ((foam.nanos.logger.Logger) x.get("logger")).warning(msg);
          Notification notification = new Notification.Builder(x)
            .setTemplate("NOC")
            .setToastMessage(msg)
            .setBody(msg)
            .build();
          ((DAO) x.get("localNotificationDAO")).put(notification);
        }
        throw e;
      }
      `
    },
    {
      name: 'login',
      documentation: `Login a user by their identifier (email or username) provided, validate the password and
        return the user in the context`,
      javaCode: `
        User user = (User) ((DAO) getLocalUserDAO())
          .inX(x)
          .find(
            AND(
              OR(
                EQ(User.EMAIL, identifier.toLowerCase()),
                EQ(User.USER_NAME, identifier)
              ),
              CLASS_OF(User.class)
            )
          );

        if ( user == null ) {
          throw new AuthenticationException("User not found");
        }
        return loginHelper(x, user, password);
      `
    },
    {
      name: 'checkUser',
      documentation: `Checks if the user passed into the method has the passed
        in permission attributed to it by checking their group. No check on User
        and group enabled flags.`,
      javaCode: `
        // check whether user has permission to check user permissions
        if ( ! check(x, CHECK_USER_PERMISSION) ) throw new AuthorizationException();

        if ( user == null || permission == null ) return false;

        try {
          String groupId = (String) user.getGroup();

          while ( ! SafetyUtil.isEmpty(groupId) ) {
            Group group = (Group) ((DAO) getLocalGroupDAO()).find(groupId);

            // if group is null break
            if ( group == null ) break;

            // check permission
            if ( group.implies(x, new AuthPermission(permission)) ) return true;

            // check parent group
            groupId = group.getParent();
          }
        } catch (Throwable t) {
        }

        return false;
      `
    },
    {
      name: 'check',
      documentation: `Check if the user in the context supplied has the right
        permission.`,
      javaCode: `
        if ( x == null || permission == null ) return false;

        Permission p = new AuthPermission(permission);

        try {
          Group group = getCurrentGroup(x);

          while ( group != null ) {

            // check permission
            if ( group.implies(x, p) ) return true;

            // check parent group
            group = (Group) ((DAO) getLocalGroupDAO()).find(group.getParent());
          }
        } catch (IllegalArgumentException e) {
          Logger logger = (Logger) x.get("logger");
          logger.error("check", p, e);
        } catch (Throwable t) {
        }

        return false;
      `
    },
    {
      name: 'validatePassword',
      javaCode: `
        // Password policy to validate against
        PasswordPolicy passwordPolicy = null;

        // Retrieve the logger
        Logger logger = (Logger) x.get("logger");

        // Retrieve the password policy from the user and group when available
        if ( user != null ) {
          Group ancestor = (Group) x.get("group");
          if ( ancestor != null ) {
            // Check password policy
            passwordPolicy = ancestor.getPasswordPolicy();
            while ( passwordPolicy == null || ! passwordPolicy.getEnabled() ) {
              ancestor = ancestor.getAncestor(x, ancestor);
              if ( ancestor == null ) break;
              passwordPolicy = ancestor.getPasswordPolicy();
            }
          }
        }

        // Use the default password policy if nothing is found
        if ( passwordPolicy == null || ! passwordPolicy.getEnabled() ) {
          passwordPolicy = new PasswordPolicy();
          passwordPolicy.setEnabled(true);
        }

        // Validate the password against the password policy
        passwordPolicy.validate(user, potentialPassword);
      `
    },
    {
      name: 'assertUserIsActive',
      documentation: `Given a user, we check whether the user is ACTIVE.`,
      args: [
        {
          name: 'user',
          type: 'foam.nanos.auth.User'
        }
      ],
      javaCode: `
      // check that the user is active
      if ( user instanceof LifecycleAware && ((LifecycleAware)user).getLifecycleState() != LifecycleState.ACTIVE ) {
        throw new AuthenticationException("User is not active");
      }
      `
    },
    {
      name: 'updatePassword',
      documentation: `Given a context with a user, validate the password to be
        updated and return a context with the updated user information.`,
      javaCode: `
        if ( x == null || SafetyUtil.isEmpty(oldPassword) || SafetyUtil.isEmpty(newPassword) ) {
          throw new RuntimeException("Password fields cannot be blank");
        }

        Session session = x.get(Session.class);
        if ( session == null || session.getUserId() == 0 ) {
          throw new AuthenticationException("User not found");
        }

        User user = (User) ((DAO) getLocalUserDAO()).find(session.getUserId());
        if ( user == null ) {
          throw new AuthenticationException("User not found");
        }

        // check that the user is active
        assertUserIsActive(user);

        // check if user enabled
        if ( ! user.getEnabled() ) {
          throw new AuthenticationException("User disabled");
        }

        // check if user login enabled
        if ( ! user.getLoginEnabled() ) {
          throw new AuthenticationException("Login disabled");
        }

        // check if group enabled
        Group group = user.findGroup(x);
        if ( group != null && ! group.getEnabled() ) {
          throw new AuthenticationException("Group disabled");
        }

        // check if password is valid per validatePassword method
        validatePassword(x, user, newPassword);

        // old password does not match
        if ( ! Password.verify(oldPassword, user.getPassword()) ) {
          throw new RuntimeException("Old password is incorrect");
        }

        // new password is the same
        if ( Password.verify(newPassword, user.getPassword()) ) {
          throw new RuntimeException("New password must be different");
        }

        // store new password in DAO and put in context
        user = (User) user.fclone();
        user.setPasswordLastModified(Calendar.getInstance().getTime());
        user.setPreviousPassword(user.getPassword());
        user.setPassword(Password.hash(newPassword));
        // TODO: modify line to allow actual setting of password expiry in cases where users are required to periodically update their passwords
        user.setPasswordExpiry(null);
        user = (User) ((DAO) getLocalUserDAO()).put(user);
        Subject subject = new Subject.Builder(x).setUser(user).build();
        session.setContext(session.getContext().put("subject", subject).put("group", group));
        return user;
      `
    },
    {
      name: 'validateUser',
      documentation: `Used to validate properties of a user. This will be called
        on registration of users. Will mainly be used as a veto method. Users
        should have id, email, first name, last name, password for registration`,
      javaCode: `
        if ( user == null ) {
          throw new AuthenticationException("Invalid User");
        }

        if ( SafetyUtil.isEmpty(user.getEmail()) ) {
          throw new AuthenticationException("Email is required for creating a user");
        }

        if ( ! Email.isValid(user.getEmail()) ) {
          throw new AuthenticationException("Email format is invalid");
        }

        if ( SafetyUtil.isEmpty(user.getFirstName()) ) {
          throw new AuthenticationException("First Name is required for creating a user");
        }

        if ( SafetyUtil.isEmpty(user.getLastName()) ) {
          throw new AuthenticationException("Last Name is required for creating a user");
        }

        if ( SafetyUtil.isEmpty(user.getPassword()) ) {
          throw new AuthenticationException("Password is required for creating a user");
        }

        validatePassword(x, user, user.getPassword());
      `
    },
    {
      name: 'logout',
      documentation: `Just return a null user for now. Not sure how to handle
        the cleanup of the current context.`,
      javaCode: `
        Session session = x.get(Session.class);
        if ( session != null && session.getUserId() != 0 ) {
          ((DAO) getLocalSessionDAO()).remove(session);
        }
      `
    },
    {
      name: 'getCurrentGroup',
      documentation: `Gets the effective group from a context.`,
      javaCode: `
        // Highest precedence: Just return the group from the context if it's already
        // been set.
        Group group = (Group) x.get("group");

        if ( group != null ) return group;

        Subject subject = (Subject) x.get("subject");
        User user = subject.getUser();
        User agent = subject.getRealUser();

        // Second highest precedence: If one user is acting as another, return the
        // group on the junction between them.
        if ( user != null ) {
          if ( agent != null && agent != user ) {
            DAO agentJunctionDAO = (DAO) x.get("agentJunctionDAO");
            UserUserJunction junction = (UserUserJunction) agentJunctionDAO.find(
              AND(
                EQ(UserUserJunction.SOURCE_ID, agent.getId()),
                EQ(UserUserJunction.TARGET_ID, user.getId())
              )
            );

            if ( junction == null ) {
              ((foam.nanos.logger.Logger) x.get("logger")).warning("There was a user and an agent in the context, but a junction between them was not found.", "user", user.getId(), "agent", agent.getId());
              throw new RuntimeException("There was a user and an agent in the context, but a junction between them was not found.");
            }

            return (Group) ((DAO) getLocalGroupDAO()).inX(x).find(junction.getGroup());
          }

          // Third highest precedence: If a user is logged in but not acting as
          // another user, return their group.
          return (Group) ((DAO) getLocalGroupDAO()).inX(x).find(user.getGroup());
        }

        // If none of the cases above match, return null.
        // TODO: Should this throw an error instead?
        return null;
      `
    }
  ]
});

<|endoftext|>


<commit_before>/*=============================================================================
 * Orange - Time System Variables
 * By Hudell - www.hudell.com
 * OrangeTimeSystemVariables.js
 * Version: 1.3
 * Free for commercial and non commercial use.
 *=============================================================================*/
/*:
 * @plugindesc Exports Orange Time System data to variables
 *
 * @author Hudell
 *
 * @param secondVariable
 * @desc The number of the variable where you want to store the seconds
 * @default 0
 *
 * @param minuteVariable
 * @desc The number of the variable where you want to store the minutes
 * @default 0
 *
 * @param hourVariable
 * @desc The number of the variable where you want to store the hours
 * @default 0
 *
 * @param dayVariable
 * @desc The number of the variable where you want to store the days
 * @default 0
 *
 * @param monthVariable
 * @desc The number of the variable where you want to store the months
 * @default 0
 *
 * @param yearVariable
 * @desc The number of the variable where you want to store the years
 * @default 0
 *
 * @param weekDayVariable
 * @desc The number of the variable where you want to store the week day
 * @default 0
 *
 * @param dayPeriodVariable
 * @desc The number of the variable where you want to store the day period
 * @default 0
 *
 * @param monthNameVariable
 * @desc The number of the variable where you want to store the name of the month
 * @default 0
 *
 * @param monthShortNameVariable
 * @desc The number of the variable where you want to store the short name of the month
 * @default 0
 *
 * @param dayNameVariable
 * @desc The number of the variable where you want to store the name of the day
 * @default 0
 *
 * @param dayShortNameVariable
 * @desc The number of the variable where you want to store the short name of the day
 * @default 0
 *
 * @help
 * ============================================================================
 * Latest Version
 * ============================================================================
 *
 * Get the latest version of this script on
 * http://link.hudell.com/time-system-variables
 *
 *=============================================================================*/

var Imported = Imported || {};
var OrangeTimeSystemVariables = OrangeTimeSystemVariables || {};

if (Imported["OrangeTimeSystem"] === undefined) {
  console.log('Download MVCommons: http://link.hudell.com/time-system');
  throw new Error("This library requires the OrangeTimeSystem!");
}

(function($) {
  "use strict";

  $.Parameters = PluginManager.parameters('OrangeTimeSystemVariables');
  $.Param = $.Param || {};

  $.Param.secondVariable = Number($.Parameters['secondVariable'] || 0);
  $.Param.minuteVariable = Number($.Parameters['minuteVariable'] || 0);
  $.Param.hourVariable = Number($.Parameters['hourVariable'] || 0);
  $.Param.dayVariable = Number($.Parameters['dayVariable'] || 0);
  $.Param.monthVariable = Number($.Parameters['monthVariable'] || 0);
  $.Param.yearVariable = Number($.Parameters['yearVariable'] || 0);
  $.Param.weekDayVariable = Number($.Parameters['weekDayVariable'] || 0);
  $.Param.dayPeriodVariable = Number($.Parameters['dayPeriodVariable'] || 0);
  $.Param.monthNameVariable = Number($.Parameters['monthNameVariable'] || 0);
  $.Param.monthShortNameVariable = Number($.Parameters['monthShortNameVariable'] || 0);
  $.Param.dayNameVariable = Number($.Parameters['dayNameVariable'] || 0);
  $.Param.dayShortNameVariable = Number($.Parameters['dayShortNameVariable'] || 0);

  $.configureVariables = function() {
    if ($gameVariables === undefined || $gameVariables === null) return;

    if ($.Param.secondVariable !== undefined && $.Param.secondVariable > 0) {
      $gameVariables.setValue($.Param.secondVariable, OrangeTimeSystem.seconds);
    }
    if ($.Param.minuteVariable !== undefined && $.Param.secondVariable > 0) {
      $gameVariables.setValue($.Param.minuteVariable, OrangeTimeSystem.minute);
    }
    if ($.Param.hourVariable !== undefined && $.Param.secondVariable > 0) {
      $gameVariables.setValue($.Param.hourVariable, OrangeTimeSystem.hour);
    }
    if ($.Param.dayVariable !== undefined && $.Param.secondVariable > 0) {
      $gameVariables.setValue($.Param.dayVariable, OrangeTimeSystem.day);
    }
    if ($.Param.monthVariable !== undefined && $.Param.secondVariable > 0) {
      $gameVariables.setValue($.Param.monthVariable, OrangeTimeSystem.month);
    }
    if ($.Param.yearVariable !== undefined && $.Param.secondVariable > 0) {
      $gameVariables.setValue($.Param.yearVariable, OrangeTimeSystem.year);
    }
    if ($.Param.weekDayVariable !== undefined && $.Param.secondVariable > 0) {
      $gameVariables.setValue($.Param.weekDayVariable, OrangeTimeSystem.weekDay);
    }
    if ($.Param.dayPeriodVariable !== undefined && $.Param.secondVariable > 0) {
      $gameVariables.setValue($.Param.dayPeriodVariable, OrangeTimeSystem.dayPeriod);
    }
    if ($.Param.monthNameVariable !== undefined && $.Param.monthNameVariable > 0) {
      $gameVariables.setValue($.Param.monthNameVariable, OrangeTimeSystem.monthName);
    }
    if ($.Param.monthShortNameVariable !== undefined && $.Param.monthShortNameVariable > 0) {
      $gameVariables.setValue($.Param.monthShortNameVariable, OrangeTimeSystem.monthShortName);
    }
    if ($.Param.dayNameVariable !== undefined && $.Param.dayNameVariable > 0) {
      $gameVariables.setValue($.Param.dayNameVariable, OrangeTimeSystem.dayName);
    }
    if ($.Param.dayShortNameVariable !== undefined && $.Param.dayShortNameVariable > 0) {
      $gameVariables.setValue($.Param.dayShortNameVariable, OrangeTimeSystem.dayShortName);
    }
  };

  // Updates the variables every in-game second
  OrangeTimeSystem.on('changeTime', $.configureVariables);
})(OrangeTimeSystemVariables);

Imported.OrangeTimeSystemVariables = 1.3;<commit_msg>Update OrangeTimeSystemVariables.js<commit_after>/*=============================================================================
 * Orange - Time System Variables
 * By Hudell - www.hudell.com
 * OrangeTimeSystemVariables.js
 * Version: 1.3
 * Free for commercial and non commercial use.
 *=============================================================================*/
/*:
 * @plugindesc Exports Orange Time System data to variables
 *
 * @author Hudell
 *
 * @param secondVariable
 * @desc The number of the variable where you want to store the seconds
 * @default 0
 *
 * @param minuteVariable
 * @desc The number of the variable where you want to store the minutes
 * @default 0
 *
 * @param hourVariable
 * @desc The number of the variable where you want to store the hours
 * @default 0
 *
 * @param dayVariable
 * @desc The number of the variable where you want to store the days
 * @default 0
 *
 * @param monthVariable
 * @desc The number of the variable where you want to store the months
 * @default 0
 *
 * @param yearVariable
 * @desc The number of the variable where you want to store the years
 * @default 0
 *
 * @param weekDayVariable
 * @desc The number of the variable where you want to store the week day
 * @default 0
 *
 * @param dayPeriodVariable
 * @desc The number of the variable where you want to store the day period
 * @default 0
 *
 * @param monthNameVariable
 * @desc The number of the variable where you want to store the name of the month
 * @default 0
 *
 * @param monthShortNameVariable
 * @desc The number of the variable where you want to store the short name of the month
 * @default 0
 *
 * @param dayNameVariable
 * @desc The number of the variable where you want to store the name of the day
 * @default 0
 *
 * @param dayShortNameVariable
 * @desc The number of the variable where you want to store the short name of the day
 * @default 0
 *
 * @help
 * ============================================================================
 * Latest Version
 * ============================================================================
 *
 * Get the latest version of this script on
 * http://link.hudell.com/time-system-variables
 *
 *=============================================================================*/

var Imported = Imported || {};
var OrangeTimeSystemVariables = OrangeTimeSystemVariables || {};

if (Imported["OrangeTimeSystem"] === undefined) {
  console.log('Download MVCommons: http://link.hudell.com/time-system');
  throw new Error("This library requires the OrangeTimeSystem!");
}

(function($) {
  "use strict";

  $.Parameters = PluginManager.parameters('OrangeTimeSystemVariables');
  $.Param = $.Param || {};

  $.Param.secondVariable = Number($.Parameters['secondVariable'] || 0);
  $.Param.minuteVariable = Number($.Parameters['minuteVariable'] || 0);
  $.Param.hourVariable = Number($.Parameters['hourVariable'] || 0);
  $.Param.dayVariable = Number($.Parameters['dayVariable'] || 0);
  $.Param.monthVariable = Number($.Parameters['monthVariable'] || 0);
  $.Param.yearVariable = Number($.Parameters['yearVariable'] || 0);
  $.Param.weekDayVariable = Number($.Parameters['weekDayVariable'] || 0);
  $.Param.dayPeriodVariable = Number($.Parameters['dayPeriodVariable'] || 0);
  $.Param.monthNameVariable = Number($.Parameters['monthNameVariable'] || 0);
  $.Param.monthShortNameVariable = Number($.Parameters['monthShortNameVariable'] || 0);
  $.Param.dayNameVariable = Number($.Parameters['dayNameVariable'] || 0);
  $.Param.dayShortNameVariable = Number($.Parameters['dayShortNameVariable'] || 0);

  $.configureVariables = function() {
    if ($gameVariables === undefined || $gameVariables === null) return;

    if ($.Param.secondVariable !== undefined && $.Param.secondVariable > 0) {
      $gameVariables.setValue($.Param.secondVariable, OrangeTimeSystem.seconds);
    }
    if ($.Param.minuteVariable !== undefined && $.Param.minuteVariable > 0) {
      $gameVariables.setValue($.Param.minuteVariable, OrangeTimeSystem.minute);
    }
    if ($.Param.hourVariable !== undefined && $.Param.hourVariable > 0) {
      $gameVariables.setValue($.Param.hourVariable, OrangeTimeSystem.hour);
    }
    if ($.Param.dayVariable !== undefined && $.Param.dayVariable > 0) {
      $gameVariables.setValue($.Param.dayVariable, OrangeTimeSystem.day);
    }
    if ($.Param.monthVariable !== undefined && $.Param.monthVariable > 0) {
      $gameVariables.setValue($.Param.monthVariable, OrangeTimeSystem.month);
    }
    if ($.Param.yearVariable !== undefined && $.Param.yearVariable > 0) {
      $gameVariables.setValue($.Param.yearVariable, OrangeTimeSystem.year);
    }
    if ($.Param.weekDayVariable !== undefined && $.Param.weekDayVariable > 0) {
      $gameVariables.setValue($.Param.weekDayVariable, OrangeTimeSystem.weekDay);
    }
    if ($.Param.dayPeriodVariable !== undefined && $.Param.dayPeriodVariable > 0) {
      $gameVariables.setValue($.Param.dayPeriodVariable, OrangeTimeSystem.dayPeriod);
    }
    if ($.Param.monthNameVariable !== undefined && $.Param.monthNameVariable > 0) {
      $gameVariables.setValue($.Param.monthNameVariable, OrangeTimeSystem.monthName);
    }
    if ($.Param.monthShortNameVariable !== undefined && $.Param.monthShortNameVariable > 0) {
      $gameVariables.setValue($.Param.monthShortNameVariable, OrangeTimeSystem.monthShortName);
    }
    if ($.Param.dayNameVariable !== undefined && $.Param.dayNameVariable > 0) {
      $gameVariables.setValue($.Param.dayNameVariable, OrangeTimeSystem.dayName);
    }
    if ($.Param.dayShortNameVariable !== undefined && $.Param.dayShortNameVariable > 0) {
      $gameVariables.setValue($.Param.dayShortNameVariable, OrangeTimeSystem.dayShortName);
    }
  };

  // Updates the variables every in-game second
  OrangeTimeSystem.on('changeTime', $.configureVariables);
})(OrangeTimeSystemVariables);

Imported.OrangeTimeSystemVariables = 1.3;
<|endoftext|>