<commit_before>/*
Copyright 2015, 2016 OpenMarket Ltd

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.
*/

'use strict';

import React from 'react';
import PropTypes from 'prop-types';
import { MatrixClient } from 'matrix-js-sdk';

import MFileBody from './MFileBody';
import ImageUtils from '../../../ImageUtils';
import Modal from '../../../Modal';
import sdk from '../../../index';
import dis from '../../../dispatcher';
import { decryptFile, readBlobAsDataUri } from '../../../utils/DecryptFile';
import Promise from 'bluebird';
import { _t } from '../../../languageHandler';
import SettingsStore from "../../../settings/SettingsStore";

export default class extends React.Component {
    displayName: 'MImageBody'

    static propTypes = {
        /* the MatrixEvent to show */
        mxEvent: PropTypes.object.isRequired,

        /* called when the image has loaded */
        onWidgetLoad: PropTypes.func.isRequired,
    }

    static contextTypes = {
        matrixClient: PropTypes.instanceOf(MatrixClient),
    }

    constructor(props) {
        super(props);

        this.onAction = this.onAction.bind(this);
        this.onImageError = this.onImageError.bind(this);
        this.onImageLoad = this.onImageLoad.bind(this);
        this.onImageEnter = this.onImageEnter.bind(this);
        this.onImageLeave = this.onImageLeave.bind(this);
        this.onClientSync = this.onClientSync.bind(this);
        this.onClick = this.onClick.bind(this);
        this.fixupHeight = this.fixupHeight.bind(this);
        this._isGif = this._isGif.bind(this);

        this.state = {
            decryptedUrl: null,
            decryptedThumbnailUrl: null,
            decryptedBlob: null,
            error: null,
            imgError: false,
        };
    }

    componentWillMount() {
        this.unmounted = false;
        this.context.matrixClient.on('sync', this.onClientSync);
    }

    onClientSync(syncState, prevState) {
        if (this.unmounted) return;
        // Consider the client reconnected if there is no error with syncing.
        // This means the state could be RECONNECTING, SYNCING or PREPARED.
        const reconnected = syncState !== "ERROR" && prevState !== syncState;
        if (reconnected && this.state.imgError) {
            // Load the image again
            this.setState({
                imgError: false,
            });
        }
    }

    onClick(ev) {
        if (ev.button == 0 && !ev.metaKey) {
            ev.preventDefault();
            const content = this.props.mxEvent.getContent();
            const httpUrl = this._getContentUrl();
            const ImageView = sdk.getComponent("elements.ImageView");
            const params = {
                src: httpUrl,
                name: content.body && content.body.length > 0 ? content.body : _t('Attachment'),
                mxEvent: this.props.mxEvent,
            };

            if (content.info) {
                params.width = content.info.w;
                params.height = content.info.h;
                params.fileSize = content.info.size;
            }

            Modal.createDialog(ImageView, params, "mx_Dialog_lightbox");
        }
    }

    _isGif() {
        const content = this.props.mxEvent.getContent();
        return (
          content &&
          content.info &&
          content.info.mimetype === "image/gif"
        );
    }

    onImageEnter(e) {
        if (!this._isGif() || SettingsStore.getValue("autoplayGifsAndVideos")) {
            return;
        }
        const imgElement = e.target;
        imgElement.src = this._getContentUrl();
    }

    onImageLeave(e) {
        if (!this._isGif() || SettingsStore.getValue("autoplayGifsAndVideos")) {
            return;
        }
        const imgElement = e.target;
        imgElement.src = this._getThumbUrl();
    }

    onImageError() {
        this.setState({
            imgError: true,
        });
    }

    onImageLoad() {
        this.fixupHeight();
        this.props.onWidgetLoad();
    }

    _getContentUrl() {
        const content = this.props.mxEvent.getContent();
        if (content.file !== undefined) {
            return this.state.decryptedUrl;
        } else {
            return this.context.matrixClient.mxcUrlToHttp(content.url);
        }
    }

    _getThumbUrl() {
        const content = this.props.mxEvent.getContent();
        if (content.file !== undefined) {
            // Don't use the thumbnail for clients wishing to autoplay gifs.
            if (this.state.decryptedThumbnailUrl) {
                return this.state.decryptedThumbnailUrl;
            }
            return this.state.decryptedUrl;
        } else if (content.info.mimetype == "image/svg+xml" && content.info.thumbnail_url) {
            // special case to return client-generated thumbnails for SVGs, if any,
            // given we deliberately don't thumbnail them serverside to prevent
            // billion lol attacks and similar
            return this.context.matrixClient.mxcUrlToHttp(
                content.info.thumbnail_url, 800, 600,
            );
        } else {
            return this.context.matrixClient.mxcUrlToHttp(content.url, 800, 600);
        }
    }

    componentDidMount() {
        this.dispatcherRef = dis.register(this.onAction);
        const content = this.props.mxEvent.getContent();
        if (content.file !== undefined && this.state.decryptedUrl === null) {
            let thumbnailPromise = Promise.resolve(null);
            if (content.info.thumbnail_file) {
                thumbnailPromise = decryptFile(
                    content.info.thumbnail_file,
                ).then(function(blob) {
                    return readBlobAsDataUri(blob);
                });
            }
            let decryptedBlob;
            thumbnailPromise.then((thumbnailUrl) => {
                return decryptFile(content.file).then(function(blob) {
                    decryptedBlob = blob;
                    return readBlobAsDataUri(blob);
                }).then((contentUrl) => {
                    this.setState({
                        decryptedUrl: contentUrl,
                        decryptedThumbnailUrl: thumbnailUrl,
                        decryptedBlob: decryptedBlob,
                    });
                });
            }).catch((err) => {
                console.warn("Unable to decrypt attachment: ", err);
                // Set a placeholder image when we can't decrypt the image.
                this.setState({
                    error: err,
                });
            }).done();
        }
        this._afterComponentDidMount();
    }

    // To be overridden by subclasses (e.g. MStickerBody) for further
    // initialisation after componentDidMount
    _afterComponentDidMount() {
    }

    componentWillUnmount() {
        this.unmounted = true;
        dis.unregister(this.dispatcherRef);
        this.context.matrixClient.removeListener('sync', this.onClientSync);
        this._afterComponentWillUnmount();
    }

    // To be overridden by subclasses (e.g. MStickerBody) for further
    // cleanup after componentWillUnmount
    _afterComponentWillUnmount() {
    }

    onAction(payload) {
        if (payload.action === "timeline_resize") {
            this.fixupHeight();
        }
    }

    fixupHeight() {
        if (!this.refs.image) {
            console.warn(`Refusing to fix up height on ${this.displayName} with no image element`);
            return;
        }

        const content = this.props.mxEvent.getContent();
        const timelineWidth = this.refs.body.offsetWidth;
        const maxHeight = 600; // let images take up as much width as they can so long as the height doesn't exceed 600px.
        // the alternative here would be 600*timelineWidth/800; to scale them down to fit inside a 4:3 bounding box

        // FIXME: this will break on clientside generated thumbnails (as per e2e rooms)
        // which may well be much smaller than the 800x600 bounding box.

        // FIXME: It will also break really badly for images with broken or missing thumbnails

        // console.log("trying to fit image into timelineWidth of " + this.refs.body.offsetWidth + " or " + this.refs.body.clientWidth);
        let thumbHeight = null;
        if (content.info) {
            thumbHeight = ImageUtils.thumbHeight(content.info.w, content.info.h, timelineWidth, maxHeight);
        }
        this.refs.image.style.height = thumbHeight + "px";
        // console.log("Image height now", thumbHeight);
    }

    _messageContent(contentUrl, thumbUrl, content) {
        const thumbnail = (

        );

        return (

                { thumbUrl && !this.state.imgError ? thumbnail : '' }
                <MFileBody {...this.props} decryptedBlob={this.state.decryptedBlob} />

      );
    }

    render() {
        const content = this.props.mxEvent.getContent();

        if (this.state.error !== null) {
            return (

                    { _t("Error decrypting image") }

            );
        }

        if (content.file !== undefined && this.state.decryptedUrl === null) {
            // Need to decrypt the attachment
            // The attachment is decrypted in componentDidMount.
            // For now add an img tag with a spinner.
            return (

            );
        }

        const contentUrl = this._getContentUrl();
        let thumbUrl;
        if (this._isGif() && SettingsStore.getValue("autoplayGifsAndVideos")) {
          thumbUrl = contentUrl;
        } else {
          thumbUrl = this._getThumbUrl();
        }

        return this._messageContent(contentUrl, thumbUrl, content);
    }
}
<commit_msg>final comment<commit_after>/*
Copyright 2015, 2016 OpenMarket Ltd

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.
*/

'use strict';

import React from 'react';
import PropTypes from 'prop-types';
import { MatrixClient } from 'matrix-js-sdk';

import MFileBody from './MFileBody';
import ImageUtils from '../../../ImageUtils';
import Modal from '../../../Modal';
import sdk from '../../../index';
import dis from '../../../dispatcher';
import { decryptFile, readBlobAsDataUri } from '../../../utils/DecryptFile';
import Promise from 'bluebird';
import { _t } from '../../../languageHandler';
import SettingsStore from "../../../settings/SettingsStore";

export default class extends React.Component {
    displayName: 'MImageBody'

    static propTypes = {
        /* the MatrixEvent to show */
        mxEvent: PropTypes.object.isRequired,

        /* called when the image has loaded */
        onWidgetLoad: PropTypes.func.isRequired,
    }

    static contextTypes = {
        matrixClient: PropTypes.instanceOf(MatrixClient),
    }

    constructor(props) {
        super(props);

        this.onAction = this.onAction.bind(this);
        this.onImageError = this.onImageError.bind(this);
        this.onImageLoad = this.onImageLoad.bind(this);
        this.onImageEnter = this.onImageEnter.bind(this);
        this.onImageLeave = this.onImageLeave.bind(this);
        this.onClientSync = this.onClientSync.bind(this);
        this.onClick = this.onClick.bind(this);
        this.fixupHeight = this.fixupHeight.bind(this);
        this._isGif = this._isGif.bind(this);

        this.state = {
            decryptedUrl: null,
            decryptedThumbnailUrl: null,
            decryptedBlob: null,
            error: null,
            imgError: false,
        };
    }

    componentWillMount() {
        this.unmounted = false;
        this.context.matrixClient.on('sync', this.onClientSync);
    }

    onClientSync(syncState, prevState) {
        if (this.unmounted) return;
        // Consider the client reconnected if there is no error with syncing.
        // This means the state could be RECONNECTING, SYNCING or PREPARED.
        const reconnected = syncState !== "ERROR" && prevState !== syncState;
        if (reconnected && this.state.imgError) {
            // Load the image again
            this.setState({
                imgError: false,
            });
        }
    }

    onClick(ev) {
        if (ev.button == 0 && !ev.metaKey) {
            ev.preventDefault();
            const content = this.props.mxEvent.getContent();
            const httpUrl = this._getContentUrl();
            const ImageView = sdk.getComponent("elements.ImageView");
            const params = {
                src: httpUrl,
                name: content.body && content.body.length > 0 ? content.body : _t('Attachment'),
                mxEvent: this.props.mxEvent,
            };

            if (content.info) {
                params.width = content.info.w;
                params.height = content.info.h;
                params.fileSize = content.info.size;
            }

            Modal.createDialog(ImageView, params, "mx_Dialog_lightbox");
        }
    }

    _isGif() {
        const content = this.props.mxEvent.getContent();
        return (
          content &&
          content.info &&
          content.info.mimetype === "image/gif"
        );
    }

    onImageEnter(e) {
        if (!this._isGif() || SettingsStore.getValue("autoplayGifsAndVideos")) {
            return;
        }
        const imgElement = e.target;
        imgElement.src = this._getContentUrl();
    }

    onImageLeave(e) {
        if (!this._isGif() || SettingsStore.getValue("autoplayGifsAndVideos")) {
            return;
        }
        const imgElement = e.target;
        imgElement.src = this._getThumbUrl();
    }

    onImageError() {
        this.setState({
            imgError: true,
        });
    }

    onImageLoad() {
        this.fixupHeight();
        this.props.onWidgetLoad();
    }

    _getContentUrl() {
        const content = this.props.mxEvent.getContent();
        if (content.file !== undefined) {
            return this.state.decryptedUrl;
        } else {
            return this.context.matrixClient.mxcUrlToHttp(content.url);
        }
    }

    _getThumbUrl() {
        const content = this.props.mxEvent.getContent();
        if (content.file !== undefined) {
            // Don't use the thumbnail for clients wishing to autoplay gifs.
            if (this.state.decryptedThumbnailUrl) {
                return this.state.decryptedThumbnailUrl;
            }
            return this.state.decryptedUrl;
        } else if (content.info.mimetype == "image/svg+xml" && content.info.thumbnail_url) {
            // special case to return client-generated thumbnails for SVGs, if any,
            // given we deliberately don't thumbnail them serverside to prevent
            // billion lol attacks and similar
            return this.context.matrixClient.mxcUrlToHttp(
                content.info.thumbnail_url, 800, 600,
            );
        } else {
            return this.context.matrixClient.mxcUrlToHttp(content.url, 800, 600);
        }
    }

    componentDidMount() {
        this.dispatcherRef = dis.register(this.onAction);
        const content = this.props.mxEvent.getContent();
        if (content.file !== undefined && this.state.decryptedUrl === null) {
            let thumbnailPromise = Promise.resolve(null);
            if (content.info.thumbnail_file) {
                thumbnailPromise = decryptFile(
                    content.info.thumbnail_file,
                ).then(function(blob) {
                    return readBlobAsDataUri(blob);
                });
            }
            let decryptedBlob;
            thumbnailPromise.then((thumbnailUrl) => {
                return decryptFile(content.file).then(function(blob) {
                    decryptedBlob = blob;
                    return readBlobAsDataUri(blob);
                }).then((contentUrl) => {
                    this.setState({
                        decryptedUrl: contentUrl,
                        decryptedThumbnailUrl: thumbnailUrl,
                        decryptedBlob: decryptedBlob,
                    });
                });
            }).catch((err) => {
                console.warn("Unable to decrypt attachment: ", err);
                // Set a placeholder image when we can't decrypt the image.
                this.setState({
                    error: err,
                });
            }).done();
        }
        this._afterComponentDidMount();
    }

    // To be overridden by subclasses (e.g. MStickerBody) for further
    // initialisation after componentDidMount
    _afterComponentDidMount() {
    }

    componentWillUnmount() {
        this.unmounted = true;
        dis.unregister(this.dispatcherRef);
        this.context.matrixClient.removeListener('sync', this.onClientSync);
        this._afterComponentWillUnmount();
    }

    // To be overridden by subclasses (e.g. MStickerBody) for further
    // cleanup after componentWillUnmount
    _afterComponentWillUnmount() {
    }

    onAction(payload) {
        if (payload.action === "timeline_resize") {
            this.fixupHeight();
        }
    }

    fixupHeight() {
        if (!this.refs.image) {
            console.warn(`Refusing to fix up height on ${this.displayName} with no image element`);
            return;
        }

        const content = this.props.mxEvent.getContent();
        const timelineWidth = this.refs.body.offsetWidth;
        const maxHeight = 600; // let images take up as much width as they can so long as the height doesn't exceed 600px.
        // the alternative here would be 600*timelineWidth/800; to scale them down to fit inside a 4:3 bounding box

        // FIXME: this will break on clientside generated thumbnails (as per e2e rooms)
        // which may well be much smaller than the 800x600 bounding box.

        // FIXME: It will also break really badly for images with broken or missing thumbnails

        // FIXME: Because we don't know what size of thumbnail the server's actually going to send
        // us, we can't even really layout the page nicely for it.  Instead we have to assume
        // it'll target 800x600 and we'll downsize if needed to make things fit.

        // console.log("trying to fit image into timelineWidth of " + this.refs.body.offsetWidth + " or " + this.refs.body.clientWidth);
        let thumbHeight = null;
        if (content.info) {
            thumbHeight = ImageUtils.thumbHeight(content.info.w, content.info.h, timelineWidth, maxHeight);
        }
        this.refs.image.style.height = thumbHeight + "px";
        // console.log("Image height now", thumbHeight);
    }

    _messageContent(contentUrl, thumbUrl, content) {
        const thumbnail = (

        );

        return (

                { thumbUrl && !this.state.imgError ? thumbnail : '' }
                <MFileBody {...this.props} decryptedBlob={this.state.decryptedBlob} />

      );
    }

    render() {
        const content = this.props.mxEvent.getContent();

        if (this.state.error !== null) {
            return (

                    { _t("Error decrypting image") }

            );
        }

        if (content.file !== undefined && this.state.decryptedUrl === null) {
            // Need to decrypt the attachment
            // The attachment is decrypted in componentDidMount.
            // For now add an img tag with a spinner.
            return (

            );
        }

        const contentUrl = this._getContentUrl();
        let thumbUrl;
        if (this._isGif() && SettingsStore.getValue("autoplayGifsAndVideos")) {
          thumbUrl = contentUrl;
        } else {
          thumbUrl = this._getThumbUrl();
        }

        return this._messageContent(contentUrl, thumbUrl, content);
    }
}
<|endoftext|>


<commit_before>import React from 'react';
import cx from 'classnames';
import { props, skinnable, t } from '../utils';
import omit from 'lodash/omit';
import InputChildren from 'react-input-children';
import { linkState } from '../link-state';
import FlexView from '../flex/FlexView';
import Icon from '../Icon/Icon';

@skinnable()
@props({
  initialValue: t.maybe(t.String),
  onChange: t.maybe(t.Function),
  onConfirm: t.maybe(t.Function),
  onClear: t.maybe(t.Function),
  placeholder: t.maybe(t.String),
  disabled: t.maybe(t.Boolean),
  text: t.struct({
    clear: t.maybe(t.String),
    toConfirm: t.maybe(t.String)
  }),
  icon: t.struct({
    clear: t.maybe(t.String),
    toConfirm: t.maybe(t.String)
  }),
  className: t.maybe(t.String),
  id: t.maybe(t.String),
  style: t.maybe(t.Object)
}, { strict: false })
export default class ConfirmationInput extends React.Component {

  static defaultProps = {
    onChange: () => {},
    onConfirm: () => {},
    onClear: () => {}
  };

  constructor(props) {
    super(props);
    this.state = {
      focused: false,
      hoveringConfirm: false,
      value: props.initialValue
    };
  }

  componentWillReceiveProps({ initialValue }) {
    if (initialValue !== this.props.initialValue) {
      this.setState({
        value: initialValue
      });
    }
  }

  onEnter = (e) => {
    if (e.which === 13 || e.keyCode === 13) { // if Enter key
      this._onConfirm();
      document.activeElement.blur(); // remove focus
    }
  };

  onBlur = () => {
    const { hoveringConfirm } = this.state;
    if (!hoveringConfirm) {
      this._onConfirm();
    }
    this.setState({ focused: false });
  };

  onFocus = () => {
    this.setState({ focused: true });
  };

  onMouseEnter = () => this.setState({ hoveringConfirm: true });

  onMouseLeave = () => this.setState({ hoveringConfirm: false });

  _onConfirm = () => {
    const {
      props: { initialValue, onConfirm, onChange },
      state: { value },
      onMouseLeave
    } = this;
    const confirmed = (value === initialValue) || (!value && !initialValue);
    if (!confirmed) {
      onConfirm(value);
      onChange(value);
      if (!value) {
        onMouseLeave(); // on confirm, if value is empty, `templateConfirm` disappears -> onMouseLeave never called
      }
    }
  };

  _onClear = () => {
    this.props.onClear();
    this.props.onChange(''); // props.onChange should always receive a string
    this.onMouseLeave(); // on clear `templateConfirm` disappears -> onMouseLeave never called
  };

  getLocals() {
    const {
      props: {
        className,
        initialValue,
        text,
        icon,
        ...props
      },
      state: { value, focused },
      _onClear: onClear,
      _onConfirm: onConfirm,
      onMouseEnter, onMouseLeave
    } = this;
    const confirmed = (value === initialValue) || (!value && !initialValue);
    const showToConfirm = !confirmed;
    const showClear = (value && confirmed && !focused);

    return {
      confirmProps: (showToConfirm || showClear) && {
        text: text[confirmed ? 'clear' : 'toConfirm'],
        icon: icon[confirmed ? 'clear' : 'toConfirm'],
        onMouseDown: showClear ? onClear : onConfirm,
        onMouseEnter,
        onMouseLeave
      },
      inputProps: {
        ...omit(props, 'onChange'),
        valueLink: linkState(this, 'value'),
        onKeyUp: this.onEnter,
        onBlur: this.onBlur,
        onFocus: this.onFocus,
        wrapper: {
          className: cx('confirmation-input', { focused }, className)
        }
      }
    };
  }

  templateConfirm({ text, icon, ...confirmProps }) {
    const props = {
      style: { cursor: 'pointer' },
      className: 'confirmation',
      vAlignContent: 'center',
      ...confirmProps
    };
    return (
      <FlexView {...props}>
        {icon && <Icon icon={icon} />}
        {text}
      </FlexView>
    );
  }

  template({ inputProps, confirmProps }) {
    return (
      <InputChildren {...inputProps}>
        {confirmProps && this.templateConfirm(confirmProps)}
      </InputChildren>
    );
  }

}
<commit_msg>add comments to ConfirmationInput<commit_after>import React from 'react';
import cx from 'classnames';
import { props, skinnable, t } from '../utils';
import omit from 'lodash/omit';
import InputChildren from 'react-input-children';
import { linkState } from '../link-state';
import FlexView from '../flex/FlexView';
import Icon from '../Icon/Icon';

/** An input field that allows to confirm its content
 * @param initialValue - initial value
 * @param onChange - called when input box content is changed
 * @param onConfirm - called when confirming input content
 * @param onClear - called when clearing confirmed content
 * @param placeholder - input placeholder
 * @param disabled - true if disabled
 * @param text - labels for 'clear' and 'toConfirm' buttons
 * @param icon - icons for 'clear' and 'toConfirm' buttons
 */
@skinnable()
@props({
  initialValue: t.maybe(t.String),
  onChange: t.maybe(t.Function),
  onConfirm: t.maybe(t.Function),
  onClear: t.maybe(t.Function),
  placeholder: t.maybe(t.String),
  disabled: t.maybe(t.Boolean),
  text: t.struct({
    clear: t.maybe(t.String),
    toConfirm: t.maybe(t.String)
  }),
  icon: t.struct({
    clear: t.maybe(t.String),
    toConfirm: t.maybe(t.String)
  }),
  className: t.maybe(t.String),
  id: t.maybe(t.String),
  style: t.maybe(t.Object)
}, { strict: false })
export default class ConfirmationInput extends React.Component {

  static defaultProps = {
    onChange: () => {},
    onConfirm: () => {},
    onClear: () => {}
  };

  constructor(props) {
    super(props);
    this.state = {
      focused: false,
      hoveringConfirm: false,
      value: props.initialValue
    };
  }

  componentWillReceiveProps({ initialValue }) {
    if (initialValue !== this.props.initialValue) {
      this.setState({
        value: initialValue
      });
    }
  }

  onEnter = (e) => {
    if (e.which === 13 || e.keyCode === 13) { // if Enter key
      this._onConfirm();
      document.activeElement.blur(); // remove focus
    }
  };

  onBlur = () => {
    const { hoveringConfirm } = this.state;
    if (!hoveringConfirm) {
      this._onConfirm();
    }
    this.setState({ focused: false });
  };

  onFocus = () => {
    this.setState({ focused: true });
  };

  onMouseEnter = () => this.setState({ hoveringConfirm: true });

  onMouseLeave = () => this.setState({ hoveringConfirm: false });

  _onConfirm = () => {
    const {
      props: { initialValue, onConfirm, onChange },
      state: { value },
      onMouseLeave
    } = this;
    const confirmed = (value === initialValue) || (!value && !initialValue);
    if (!confirmed) {
      onConfirm(value);
      onChange(value);
      if (!value) {
        onMouseLeave(); // on confirm, if value is empty, `templateConfirm` disappears -> onMouseLeave never called
      }
    }
  };

  _onClear = () => {
    this.props.onClear();
    this.props.onChange(''); // props.onChange should always receive a string
    this.onMouseLeave(); // on clear `templateConfirm` disappears -> onMouseLeave never called
  };

  getLocals() {
    const {
      props: {
        className,
        initialValue,
        text,
        icon,
        ...props
      },
      state: { value, focused },
      _onClear: onClear,
      _onConfirm: onConfirm,
      onMouseEnter, onMouseLeave
    } = this;
    const confirmed = (value === initialValue) || (!value && !initialValue);
    const showToConfirm = !confirmed;
    const showClear = (value && confirmed && !focused);

    return {
      confirmProps: (showToConfirm || showClear) && {
        text: text[confirmed ? 'clear' : 'toConfirm'],
        icon: icon[confirmed ? 'clear' : 'toConfirm'],
        onMouseDown: showClear ? onClear : onConfirm,
        onMouseEnter,
        onMouseLeave
      },
      inputProps: {
        ...omit(props, 'onChange'),
        valueLink: linkState(this, 'value'),
        onKeyUp: this.onEnter,
        onBlur: this.onBlur,
        onFocus: this.onFocus,
        wrapper: {
          className: cx('confirmation-input', { focused }, className)
        }
      }
    };
  }

  templateConfirm({ text, icon, ...confirmProps }) {
    const props = {
      style: { cursor: 'pointer' },
      className: 'confirmation',
      vAlignContent: 'center',
      ...confirmProps
    };
    return (
      <FlexView {...props}>
        {icon && <Icon icon={icon} />}
        {text}
      </FlexView>
    );
  }

  template({ inputProps, confirmProps }) {
    return (
      <InputChildren {...inputProps}>
        {confirmProps && this.templateConfirm(confirmProps)}
      </InputChildren>
    );
  }

}
<|endoftext|>


<commit_before>import config from 'config';
import { getAllModels, patchItemDueDate, searchStudent } from '../../lib/api-client';
import { Dispatcher } from 'consus-core/flux';
import moment from 'moment-timezone';
import StudentStore from '../../store/student-store';

export default class StudentPanelController {

    static getModels() {
        return getAllModels().then(models => {
            Dispatcher.handleAction("MODELS_RECEIVED", models);
        });
    }
    static changeItemDueDate(date, item){
        if(this.isValidDueDate(date)){
            return patchItemDueDate(date, item.address, StudentStore.getStudent().id).then(() => {
                return searchStudent(StudentStore.getStudent().id);
            }).then(student => {
                Dispatcher.handleAction("STUDENT_FOUND", student);
            }).catch(e => {
                Dispatcher.handleAction('ERROR', { error: e.message });
            });
        }
    }

    static isValidDueDate(dueDate){
        let today = moment();
        let dueDateMoment = moment.tz(dueDate, config.get('timezone'));
        if(dueDateMoment.isBefore(today)){
            Dispatcher.handleAction('ERROR', {
                error: 'Due date cannot be set to today or past.'
            });
            return false;
        }
        return true;
    }
    static countDuplicateModels(models) {
        let modelCounts = [];
        models.forEach(model => {
            let exists = false;
            modelCounts.forEach(mc => {
                if(model.address === mc.address && !exists){
                    mc.quantity++;
                    exists = true;
                }
            });
            if(!exists){
                modelCounts.push({address: model.address, name: model.name, quantity: 1});
            }
        });
        return modelCounts;
    }

    static throwNotANumberError() {
        Dispatcher.handleAction("ERROR", {
            error: "Input was not a number"
        });
    }

}
<commit_msg><commit_after>import config from 'config';
import { getAllModels, patchItemDueDate, searchStudent } from '../../lib/api-client';
import { Dispatcher } from 'consus-core/flux';
import moment from 'moment-timezone';
import StudentStore from '../../store/student-store';

export default class StudentPanelController {

    static getModels() {
        return getAllModels().then(models => {
            Dispatcher.handleAction("MODELS_RECEIVED", models);
        });
    }
    static changeItemDueDate(date, item){
        if(this.isValidDueDate(date)){
            return patchItemDueDate(date, item.address, StudentStore.getStudent().id).then(() => {
                return searchStudent(StudentStore.getStudent().id);
            }).then(student => {
                Dispatcher.handleAction("STUDENT_FOUND", student);
            }).catch(e => {
                Dispatcher.handleAction('ERROR', { error: e.message });
            });
        }
    }

    static isValidDueDate(dueDate){
        let today = moment();
        let dueDateMoment = moment.tz(dueDate, config.get('timezone'));
        today.hour(0).minute(0).second(0);
        dueDateMoment.hour(1);
        if(!dueDateMoment.isSameOrAfter(today)){
            Dispatcher.handleAction('ERROR', {
                error: 'Due date cannot be set to today or past.'
            });
            return false;
        }
        return true;
    }
    static countDuplicateModels(models) {
        let modelCounts = [];
        models.forEach(model => {
            let exists = false;
            modelCounts.forEach(mc => {
                if(model.address === mc.address && !exists){
                    mc.quantity++;
                    exists = true;
                }
            });
            if(!exists){
                modelCounts.push({address: model.address, name: model.name, quantity: 1});
            }
        });
        return modelCounts;
    }

    static throwNotANumberError() {
        Dispatcher.handleAction("ERROR", {
            error: "Input was not a number"
        });
    }

}
<|endoftext|>


<commit_before>import { Range } from '../../infrastructure/range';
import { SelectorMark } from './selector.mark';
import { modelFactory } from '../../test/model.factory';
import { ColumnModel } from '../../column-type/column.model';

describe('SelectorFactory', () => {
	const column1 = new ColumnModel();
	column1.pin = 'grid';
	const column2 = new ColumnModel();
	column2.pin = 'left';
	const column3 = new ColumnModel();
	column3.pin = 'grid';
	const column4 = new ColumnModel();
	column4.pin = 'right';
	const column5 = new ColumnModel();
	column5.pin = null;

	const model = modelFactory();
	model
		.view({
			rows: ['row1', 'row2', 'row3'],
		})
		.scene({
			column: {
				rows: [],
				line: [],
				area: {
					left: [column2],
					null: [column5],
					right: [column4],
					grid: [column1, column3]
				}
			}
		});
	const name = 'q';
	const markup = {
		'q': 'q',
		'q-grid': 'q-grid',
		'q-left': 'q-left',
		'q-right': 'q-right'
	};
	const cell = {
		element: 'cell',
		columnRange: new Range(1, 4),
		rowRange: new Range(0, 3)
	};

	const selectorMark = new SelectorMark(model, markup, name);

	describe('addFactory', () => {
		it('should add new cell to the existing array of cells', () => {
			const test = {
				element: 'q-grid',
				columnRange: new Range(4, 6),
				rowRange: new Range(0, 3)
			};
			const result = [cell];
			const factory = selectorMark.addFactory(result);
			const cells = factory('grid');
			expect(cells).to.be.an.instanceOf(Array).and.to.have.lengthOf(2);
			expect(JSON.stringify(cells[0])).to.equal(JSON.stringify(cell));
			expect(JSON.stringify(cells[1])).to.equal(JSON.stringify(test));
		});
		it('if markup element was not found, than returns initial array of cells', () => {
			const result = [cell];
			const factory = selectorMark.addFactory(result);
			const cells = factory('notExistingElement');
			expect(cells).to.be.an.instanceOf(Array).and.to.have.lengthOf(1);
			expect(JSON.stringify(cells[0])).to.equal(JSON.stringify(cell));
		});
	});

	describe('select', () => {
		it('should return array of cells', () => {
			const leftCell = {
				element: 'q-left',
				columnRange: new Range(0, 1),
				rowRange: new Range(0, 3)
			};
			const rightCell = {
				element: 'q-right',
				columnRange: new Range(2, 3),
				rowRange: new Range(0, 3)
			};
			const optional = {
				element: 'q',
				columnRange: new Range(1, 2),
				rowRange: new Range(0, 3)
			};
			const cells = selectorMark.select();
			expect(cells).to.be.an.instanceOf(Array).and.to.have.lengthOf(3);
			expect(JSON.stringify(cells[0])).to.equal(JSON.stringify(leftCell));
			expect(JSON.stringify(cells[1])).to.equal(JSON.stringify(optional));
			expect(JSON.stringify(cells[2])).to.equal(JSON.stringify(rightCell));
		});
	});
});
<commit_msg>Fix selector mark test<commit_after>import { Range } from '../../infrastructure/range';
import { SelectorMark } from './selector.mark';
import { modelFactory } from '../../test/model.factory';
import { ColumnModel } from '../../column-type/column.model';

describe('SelectorFactory', () => {
	const column1 = new ColumnModel();
	column1.pin = 'grid';
	const column2 = new ColumnModel();
	column2.pin = 'left';
	const column3 = new ColumnModel();
	column3.pin = 'grid';
	const column4 = new ColumnModel();
	column4.pin = 'right';
	const column5 = new ColumnModel();
	column5.pin = null;

	const model = modelFactory();
	model
		.scene({
			rows: ['row1', 'row2', 'row3'],
			column: {
				rows: [],
				line: [],
				area: {
					left: [column2],
					null: [column5],
					right: [column4],
					grid: [column1, column3]
				}
			}
		});
	const name = 'q';
	const markup = {
		'q': 'q',
		'q-grid': 'q-grid',
		'q-left': 'q-left',
		'q-right': 'q-right'
	};
	const cell = {
		element: 'cell',
		columnRange: new Range(1, 4),
		rowRange: new Range(0, 3)
	};

	const selectorMark = new SelectorMark(model, markup, name);

	describe('addFactory', () => {
		it('should add new cell to the existing array of cells', () => {
			const test = {
				element: 'q-grid',
				columnRange: new Range(4, 6),
				rowRange: new Range(0, 3)
			};
			const result = [cell];
			const factory = selectorMark.addFactory(result);
			const cells = factory('grid');
			expect(cells).to.be.an.instanceOf(Array).and.to.have.lengthOf(2);
			expect(JSON.stringify(cells[0])).to.equal(JSON.stringify(cell));
			expect(JSON.stringify(cells[1])).to.equal(JSON.stringify(test));
		});
		it('if markup element was not found, than returns initial array of cells', () => {
			const result = [cell];
			const factory = selectorMark.addFactory(result);
			const cells = factory('notExistingElement');
			expect(cells).to.be.an.instanceOf(Array).and.to.have.lengthOf(1);
			expect(JSON.stringify(cells[0])).to.equal(JSON.stringify(cell));
		});
	});

	describe('select', () => {
		it('should return array of cells', () => {
			const leftCell = {
				element: 'q-left',
				columnRange: new Range(0, 1),
				rowRange: new Range(0, 3)
			};
			const rightCell = {
				element: 'q-right',
				columnRange: new Range(2, 3),
				rowRange: new Range(0, 3)
			};
			const optional = {
				element: 'q',
				columnRange: new Range(1, 2),
				rowRange: new Range(0, 3)
			};
			const cells = selectorMark.select();
			expect(cells).to.be.an.instanceOf(Array).and.to.have.lengthOf(3);
			expect(JSON.stringify(cells[0])).to.equal(JSON.stringify(leftCell));
			expect(JSON.stringify(cells[1])).to.equal(JSON.stringify(optional));
			expect(JSON.stringify(cells[2])).to.equal(JSON.stringify(rightCell));
		});
	});
});
<|endoftext|>


<commit_before>Package.describe({
  name: 'bojicas:bootstrap-alerts',
  summary: 'Display application alerts',
  version: '1.0.0',
  git: 'https://github.com/bojicas/bootstrap-alerts'
});

Package.onUse(function(api) {
  api.versionsFrom('1.0.2.1');
  api.use('mongo');
  api.use([
    'twbs:bootstrap',
    'templating'
  ], 'client');
  api.addFiles([
    'bojicas:bootstrap-alerts.css',
    'bojicas:bootstrap-alerts.html',
    'bojicas:bootstrap-alerts.js'
  ], 'client');
  if (api.export) {
    api.export('Alerts');
  }
});

Package.onTest(function(api) {
  api.use('tinytest');
  api.use('bojicas:bootstrap-alerts');
  api.addFiles('bojicas:bootstrap-alerts-tests.js');
});
<commit_msg>Cleanup package file<commit_after>Package.describe({
  name: 'bojicas:bootstrap-alerts',
  summary: 'Display application alerts',
  version: '1.0.0',
  git: 'https://github.com/bojicas/bootstrap-alerts'
});

Package.onUse(function(api) {
  api.versionsFrom('1.0.2.1');

  api.use('mongo');
  api.use([
    'twbs:bootstrap',
    'templating'
  ], 'client');

  api.addFiles([
    'bojicas:bootstrap-alerts.css',
    'bojicas:bootstrap-alerts.html',
    'bojicas:bootstrap-alerts.js'
  ], 'client');

  if (api.export) {
    api.export('Alerts');
  }
});

Package.onTest(function(api) {
  api.use('tinytest');
  api.use('bojicas:bootstrap-alerts');
  api.addFiles('bojicas:bootstrap-alerts-tests.js');
});
<|endoftext|>


<commit_before>/**
  @module ember-data
*/

/**
  `DS.Serializer` is an abstract base class that you should override in your
  application to customize it for your backend. The minimum set of methods
  that you should implement is:

    * `extract()`
    * `serialize()`

  And you can optionally override the following methods:

    * `normalize()`

  For an example implementation, see
  [DS.JSONSerializer](DS.JSONSerializer.html), the included JSON serializer.

  @class Serializer
  @namespace DS
  @extends Ember.Object
*/

export default Ember.Object.extend({

  /**
    The `store` property is the application's `store` that contains all records.
    It's injected as a service.
    It can be used to push records from a non flat data structure server
    response.

    @property store
    @type {DS.Store}
    @public
  */

  /*
    The `normalizeResponse` method is used to normalize a payload from the
    server to a JSON-API Document.

    http://jsonapi.org/format/#document-structure

    @method normalizeResponse
    @param {DS.Store} store
    @param {DS.Model} primaryModelClass
    @param {Object} payload
    @param {String|Number} id
    @param {String} requestType
    @return {Object} JSON-API Document
  */
  normalizeResponse: null,

  /**
    The `serialize` method is used when a record is saved in order to convert
    the record into the form that your external data source expects.

    `serialize` takes an optional `options` hash with a single option:

    - `includeId`: If this is `true`, `serialize` should include the ID
      in the serialized object it builds.

    @method serialize
    @param {DS.Model} record
    @param {Object} [options]
    @return {Object}
  */
  serialize: null,

  /**
    The `normalize` method is used to convert a payload received from your
    external data source into the normalized form `store.push()` expects. You
    should override this method, munge the hash and return the normalized
    payload.

    @method normalize
    @param {DS.Model} typeClass
    @param {Object} hash
    @return {Object}
  */
  normalize: function(typeClass, hash) {
    return hash;
  }

});
<commit_msg>[DOC release] make normalizeResponse show up in the API docs<commit_after>/**
  @module ember-data
*/

/**
  `DS.Serializer` is an abstract base class that you should override in your
  application to customize it for your backend. The minimum set of methods
  that you should implement is:

    * `extract()`
    * `serialize()`

  And you can optionally override the following methods:

    * `normalize()`

  For an example implementation, see
  [DS.JSONSerializer](DS.JSONSerializer.html), the included JSON serializer.

  @class Serializer
  @namespace DS
  @extends Ember.Object
*/

export default Ember.Object.extend({

  /**
    The `store` property is the application's `store` that contains all records.
    It's injected as a service.
    It can be used to push records from a non flat data structure server
    response.

    @property store
    @type {DS.Store}
    @public
  */

  /**
    The `normalizeResponse` method is used to normalize a payload from the
    server to a JSON-API Document.

    http://jsonapi.org/format/#document-structure

    @method normalizeResponse
    @param {DS.Store} store
    @param {DS.Model} primaryModelClass
    @param {Object} payload
    @param {String|Number} id
    @param {String} requestType
    @return {Object} JSON-API Document
  */
  normalizeResponse: null,

  /**
    The `serialize` method is used when a record is saved in order to convert
    the record into the form that your external data source expects.

    `serialize` takes an optional `options` hash with a single option:

    - `includeId`: If this is `true`, `serialize` should include the ID
      in the serialized object it builds.

    @method serialize
    @param {DS.Model} record
    @param {Object} [options]
    @return {Object}
  */
  serialize: null,

  /**
    The `normalize` method is used to convert a payload received from your
    external data source into the normalized form `store.push()` expects. You
    should override this method, munge the hash and return the normalized
    payload.

    @method normalize
    @param {DS.Model} typeClass
    @param {Object} hash
    @return {Object}
  */
  normalize: function(typeClass, hash) {
    return hash;
  }

});
<|endoftext|>


<commit_before>define([
    "dojo/_base/declare",
    "dojo/_base/lang",
    "dijit/_WidgetBase",
    "dijit/_TemplatedMixin",
    "dijit/_WidgetsInTemplateMixin",
    "dojo/query",
    "dojo/on",
    "dojo/topic",
    "dojo/keys",
    "dojo/NodeList-dom",
    "dojo/dom-class",
    "dojo/dom-attr",
    "dojo/dom-style",
    "../../../User",
    "../../../model/meta/Model",
    "../../../locale/Dictionary",
    "dojo/text!./template/NavigationWidget.html",
    "dojo/domReady!"
], function (
    declare,
    lang,
    _WidgetBase,
    _TemplatedMixin,
    _WidgetsInTemplateMixin,
    query,
    on,
    topic,
    keys,
    nodeListDom,
    domClass,
    domAttr,
    domStyle,
    User,
    Model,
    Dict,
    template
) {
    return declare([_WidgetBase, _TemplatedMixin, _WidgetsInTemplateMixin], {

        titleOnly: false,
        templateString: lang.replace(template, Dict.tplTranslate),
        selected: null,

        constructor: function (params) {
            this.titleOnly = params.titleOnly;

            // template variables
            this.title = appConfig.title;
            this.userName = User.getLogin();
            this.firstRootType = Model.getSimpleTypeName(appConfig.rootTypes[0]);
            this.userType = Model.getSimpleTypeName(appConfig.userType);
        },

        postCreate: function() {
            // search field
            this.own(
                on(this.searchField, "keydown", lang.hitch(this, function(e) {
                    if (e.keyCode === keys.ENTER) {
                        e.preventDefault();
                        topic.publish('navigate', 'search', null, {q: domAttr.get(this.searchField, "value")});
                    }
                })),
                on(this.searchBtn, "click", lang.hitch(this, function(e) {
                    e.preventDefault();
                    topic.publish('navigate', 'search', null, {q: domAttr.get(this.searchField, "value")});
                })),
                on(this.collapseToggleBtn, "click", lang.hitch(this, function(e) {
                    var height = domStyle.get(this.menuCollapse, "height");
                    domStyle.set(this.menuCollapse, "height", height == 0 ? "auto" : 0);
                }))
            );
        },

        startup: function() {
            this.inherited(arguments);

            // initialize dropdowns
            query(".dropdown-toggle").on("click", lang.hitch(this, function(e) {
                e.preventDefault();
                var menu = query(e.target).closest(".main-menu.dropdown")[0];
                if (menu) {
                    if (domClass.contains(menu, "open")) {
                        domClass.remove(menu, "open");
                    }
                    else {
                        domClass.add(menu, "open");
                    }
                }
            }));

            // hide buttons, if titleOnly
            if (this.titleOnly) {
                query(".main-menu").style("display", "none");
            }
            else {
                // set selected menu
                query(".main-menu").removeClass("active");
                if (this.selected) {
                    query("#"+this.selected).addClass("active");
                }
            }
        },

        setContentRoute: function(type, id) {
            var contentNavNode = query("#navContent");
            contentNavNode.attr("data-wcmf-route", id !== undefined ? "entity" : "entityList");
            var routeParamStr = "type: '"+type+"'";
            if (id !== undefined) {
              routeParamStr += ", id: '"+id+"'";
            }
            contentNavNode.attr("data-wcmf-pathparams", routeParamStr);
        }
    });
});<commit_msg>added missing class<commit_after>define([
    "dojo/_base/declare",
    "dojo/_base/lang",
    "dijit/_WidgetBase",
    "dijit/_TemplatedMixin",
    "dijit/_WidgetsInTemplateMixin",
    "dojo/query",
    "dojo/on",
    "dojo/topic",
    "dojo/keys",
    "dojo/NodeList-dom",
    "dojo/NodeList-traverse",
    "dojo/dom-class",
    "dojo/dom-attr",
    "dojo/dom-style",
    "../../../User",
    "../../../model/meta/Model",
    "../../../locale/Dictionary",
    "dojo/text!./template/NavigationWidget.html",
    "dojo/domReady!"
], function (
    declare,
    lang,
    _WidgetBase,
    _TemplatedMixin,
    _WidgetsInTemplateMixin,
    query,
    on,
    topic,
    keys,
    nodeListDom,
    nodeListTraverse,
    domClass,
    domAttr,
    domStyle,
    User,
    Model,
    Dict,
    template
) {
    return declare([_WidgetBase, _TemplatedMixin, _WidgetsInTemplateMixin], {

        titleOnly: false,
        templateString: lang.replace(template, Dict.tplTranslate),
        selected: null,

        constructor: function (params) {
            this.titleOnly = params.titleOnly;

            // template variables
            this.title = appConfig.title;
            this.userName = User.getLogin();
            this.firstRootType = Model.getSimpleTypeName(appConfig.rootTypes[0]);
            this.userType = Model.getSimpleTypeName(appConfig.userType);
        },

        postCreate: function() {
            // search field
            this.own(
                on(this.searchField, "keydown", lang.hitch(this, function(e) {
                    if (e.keyCode === keys.ENTER) {
                        e.preventDefault();
                        topic.publish('navigate', 'search', null, {q: domAttr.get(this.searchField, "value")});
                    }
                })),
                on(this.searchBtn, "click", lang.hitch(this, function(e) {
                    e.preventDefault();
                    topic.publish('navigate', 'search', null, {q: domAttr.get(this.searchField, "value")});
                })),
                on(this.collapseToggleBtn, "click", lang.hitch(this, function(e) {
                    var height = domStyle.get(this.menuCollapse, "height");
                    domStyle.set(this.menuCollapse, "height", height == 0 ? "auto" : 0);
                }))
            );
        },

        startup: function() {
            this.inherited(arguments);

            // initialize dropdowns
            query(".dropdown-toggle").on("click", lang.hitch(this, function(e) {
                e.preventDefault();
                var menu = query(e.target).closest(".main-menu.dropdown")[0];
                if (menu) {
                    if (domClass.contains(menu, "open")) {
                        domClass.remove(menu, "open");
                    }
                    else {
                        domClass.add(menu, "open");
                    }
                }
            }));

            // hide buttons, if titleOnly
            if (this.titleOnly) {
                query(".main-menu").style("display", "none");
            }
            else {
                // set selected menu
                query(".main-menu").removeClass("active");
                if (this.selected) {
                    query("#"+this.selected).addClass("active");
                }
            }
        },

        setContentRoute: function(type, id) {
            var contentNavNode = query("#navContent");
            contentNavNode.attr("data-wcmf-route", id !== undefined ? "entity" : "entityList");
            var routeParamStr = "type: '"+type+"'";
            if (id !== undefined) {
              routeParamStr += ", id: '"+id+"'";
            }
            contentNavNode.attr("data-wcmf-pathparams", routeParamStr);
        }
    });
});<|endoftext|>


<commit_before>/**
 * Created by vincent on 11.04.16.
 */
'use strict';

angular.module('myApp.procedural', ['ngRoute'])
  .config(['$routeProvider', function($routeProvider) {
    $routeProvider.when('/procedural', {
      templateUrl: 'modules/procedural/partial/procedural.html',
      controller: 'proceduralCtrl'
    });
  }])
  .controller('proceduralCtrl', ['$scope', ($scope) => {
    const boardSize = 10;
    const boardResolution = 20;
    const canvasSize = boardSize * boardResolution;
    const canvas = document.getElementById('tutorial');
    const ctx = canvas.getContext('2d');
    let board = createMap(boardSize,boardSize);
    checkBoard();

    ctx.canvas.width = canvasSize;
    ctx.canvas.height = canvasSize;

    $scope.$on('$viewContentLoaded', function(){
      drawGrid(canvasSize,boardResolution);
      drawMap(board);
    });

    function createMap (rows,cols) {
      let arr = [];
      for ( let i=0; i < rows; i++ ) {
        arr.push([]);
        arr[i].push( new Array(cols) );
        for ( let j=0; j < cols; j++ ) {
          arr[i][j] = randomIntFromInterval(0,1);
        }
      }
      return arr;
    };

    function checkBoard () {
      for ( let i = 0; i < boardSize; i++ ) {
        for ( let j = 0; j < boardSize; j++ ) {
          checkVicinity(i,j);
        }
      }
    }

    function checkVicinity (x,y) {
      console.log(x + " " + y);
      let counter = 0;
      for (let i = x - 1; i <= x + 1; i++) {
        for (let j = y - 1; j <= y + 1; j++) {
          if (i >= 0 && i < boardSize && j >= 0 && j < boardSize) {
            if (board[i][j] === 1) {
              counter++;
            }
          }
        }
      }
      console.log("punkt: " + x + "," + y + " ma " + counter + " sąsiadów");
    }

    function drawGrid (size,resolution) {
      for (let i=0; i <= size; i = i + resolution){
        ctx.moveTo(i,0);
        ctx.lineTo(i,size);
        ctx.moveTo(0,i);
        ctx.lineTo(size,i);
      }
      ctx.stroke();
    };

    function drawArea(x, y) {
      ctx.fillStyle = "rgba(0, 0, 200, 0.5)";
      ctx.fillRect (x, y, boardResolution, boardResolution);
    }

    function drawMap(mapArray) {
      for (let i in mapArray) {
        for(let j in mapArray[i]) {
          if (mapArray[i][j] === 1) {
            drawArea(i * 20, j * 20);
          };
        }
      }
    }

    function randomIntFromInterval(min,max) {
      return Math.floor(Math.random()*(max-min+1)+min);
    }
  }]);<commit_msg>wip on searchForSeparatedFields<commit_after>'use strict';

angular.module('myApp.procedural', ['ngRoute'])
  .config(['$routeProvider', function($routeProvider) {
    $routeProvider.when('/procedural', {
      templateUrl: 'modules/procedural/partial/procedural.html',
      controller: 'proceduralCtrl'
    });
  }])
  .controller('proceduralCtrl', ['$scope', ($scope) => {
    const boardSize = 10;
    const boardResolution = 20;
    const canvasSize = boardSize * boardResolution;
    const canvas = document.getElementById('tutorial');
    const ctx = canvas.getContext('2d');
    let board = createMap(boardSize,boardSize);
    checkBoard();

    ctx.canvas.width = canvasSize;
    ctx.canvas.height = canvasSize;

    $scope.$on('$viewContentLoaded', function(){
      drawGrid(canvasSize,boardResolution);
      drawMap(board);
    });

    // board functions

    function createMap (rows,cols) {
      let arr = [];
      for ( let i=0; i < rows; i++ ) {
        arr.push([]);
        arr[i].push( new Array(cols) );
        for ( let j=0; j < cols; j++ ) {
          arr[i][j] = randomIntFromInterval(0,1);
        }
      }
      return arr;
    };

    function checkBoard () {
      for ( let i = 0; i < boardSize; i++ ) {
        for ( let j = 0; j < boardSize; j++ ) {
          checkVicinity(i,j);
        }
      }
    }

    function checkVicinity (x,y) {
      let counter = 0;
      for (let i = x - 1; i <= x + 1; i++) {
        for (let j = y - 1; j <= y + 1; j++) {
          if (i >= 0 && i < boardSize && j >= 0 && j < boardSize) {
            if (board[i][j] === 1) {
              counter++;
            }
            searchForSeparatedFields(x,y);
          }
        }
      }
      // console.log("punkt: " + x + "," + y + " ma " + counter + " sąsiadów");
    }

    // procedural fill functions:

    function searchForSeparatedFields (x,y) {
      console.log(x + " " + y);
      console.log(typeof(board[x][y-1]));
      if (board[x][y-1] === 0 && board[x-1][y] === 0 && board[x+1][y] === 0 && board[x][y+1] &&) {
        console.log(x + " " + y);
        switch (randomIntFromInterval(0,3)) {
          case 0:
            board[x][y-1] = 1;
            break;
          case 1:
            board[x-1][y] = 1;
            break;
          case 2:
            board[x+1][y] = 1;
            break;
          case 3:
            board[x][y+1] = 1;
            break;
          default:
            board[x][y] = 1;
            break;
        }
      }
    }

    // draw functions:

    function drawGrid (size,resolution) {
      for (let i=0; i <= size; i = i + resolution){
        ctx.moveTo(i,0);
        ctx.lineTo(i,size);
        ctx.moveTo(0,i);
        ctx.lineTo(size,i);
      }
      ctx.stroke();
    };

    function drawArea(x, y) {
      ctx.fillStyle = "rgba(0, 0, 200, 0.5)";
      ctx.fillRect (x, y, boardResolution, boardResolution);
    }

    function drawMap(mapArray) {
      for (let i in mapArray) {
        for(let j in mapArray[i]) {
          if (mapArray[i][j] === 1) {
            drawArea(i * 20, j * 20);
          };
        }
      }
    }

    //math functions:

    function randomIntFromInterval(min,max) {
      return Math.floor(Math.random()*(max-min+1)+min);
    }
  }]);<|endoftext|>


<commit_before>/**
 * [created by isabolic sabolic.ivan@gmail.com]
 */
(function($, x) {
    var options = {
        mapRegionContainer : null,
        mapRegionId        : null,
        mapName            : null,
        width              : "100%",
        height             : 300,
        initalView         : {
            x                  : null,
            y                  : null,
            zoomLevel          : null
        }
    };

    /**
     * [xDebug - PRIVATE function for debug]
     * @param  string   functionName  caller function
     * @param  array    params        caller arguments
     */
    var xDebug = function(functionName, params){
        x.debug(this.jsName || " - " || functionName, params, this);
    };

    /**
     * [triggerEvent     - PRIVATE handler fn - trigger apex events]
     * @param String evt - apex event name to trigger
     */
    var triggerEvent = function(evt, evtData) {
        xDebug.call(this, arguments.callee.name, arguments);
        this.container.trigger(evt, [evtData]);
        $(this).trigger(evt + "." + this.apexname, [evtData]);
    };

    /**
     * [resizeMap        - PRIVATE event handler fn -  when map bbox change]
     * @param String evt - apex event name to trigger
     */
    var bboxChangeEvt = function(evt) {
        var bbox     = this.map.getBounds(),
            bboxJson = {
                "west"   : bbox.getWest(),
                "south"  : bbox.getSouth(),
                "east"   : bbox.getEast(),
                "north"  : bbox.getNorth(),
                "string" : "BBOX(" + this.map.getBounds().toBBoxString() + ")"
            };

        triggerEvent.apply(this, [evt, bboxJson]);
    };

    /**
     * [zoomLlvChangeEvt - PRIVATE event handler fn - when map zoom level change]
     * @param String evt - apex event name to trigger
     */
    var zoomLlvChangeEvt = function(evt) {
        var lvl = {
            "zoomLevel": this.map.getZoom()
        }
        triggerEvent.apply(this, [evt, lvl]);
    };

    /**
     * [resizeMap        - PRIVATE event handler fn]
     * @param String evt - apex event name to trigger
     */
    var resizeMap = function (evt){
        var o = {
            w : this.region.width(),
            h : this.region.height(),
        },
        timer,
        bounds = this.map.getBounds();

        // wait until html renders
        timer = setTimeout(function(){
            if(o.w === this.region.width() &&
               o.h === this.region.height()){

                if(this.container.hasClass("max-width") === false){
                    this.container.addClass("max-width");
                }else{
                    this.container.removeClass("max-width");
                }

                this.map.invalidateSize();
                this.map.fitBounds(bounds);

                triggerEvent.apply(this, [evt]);

            }
        }.bind(this), 100);
    };

    apex.plugins.mapbox.mapBoxMap = function(opts) {
        this.map = null;
        this.options = {};
        this.container = null;
        this.region = null;
        this.events = ["mapboxmap-change-bbox",
                       "mapboxmap-change-zoomlevel",
                       "mapboxmap-maximize-region"];
        this.jsName = "apex.plugins.mapBoxMap";
        this.apexname = "MAPBOXREGION";
        this.init = function() {

            if ($.isPlainObject(options)) {
                this.options = $.extend(true, {}, this.options, options, opts);
            } else {
                throw this.jsName || ": Invalid options passed.";
            }

            if (this.options.mapRegionContainer === null) {
                throw this.jsName || ": mapRegionContainer is required.";
            }

            this.container = $("#" + this.options.mapRegionContainer);

            if (this.container.length !== 1) {
                throw this.jsName || ": Invalid region selector.";
            }

            if (this.options.mapRegionId === null) {
                throw this.jsName || ": mapRegionContainer is required.";
            }

            this.region = $("#" + this.options.mapRegionId);

            if (this.region.length !== 1) {
                throw this.jsName || ": Invalid region selector.";
            }

            this.container.addClass("mapbox-map");

            this.map = L.mapbox.map(this.container.get(0),
                                    'mapbox.streets',
                                    {
                                        trackResize: true,
                                        detectRetina: true
                                    });

            this.container.height(this.options.height);
            this.container.width(this.options.width);

            if (this.options.initalView.x &&
                this.options.initalView.y &&
                this.options.initalView.zoomLevel) {

                this.setView(
                    this.options.initalView.x,
                    this.options.initalView.y,
                    this.options.initalView.zoomLevel
                )
            }

            this.map.on("move"   , bboxChangeEvt.bind(   this, this.events[0]));
            this.map.on("zoomend", zoomLlvChangeEvt.bind(this, this.events[1]));
            this.region
                .on("click", 'span.js-maximizeButtonContainer',
                    resizeMap.bind(this, this.events[2]));

            this.region.data("mapboxRegion", this);

            x.debug("apex.plugins.mapBoxMap : ", this);

            return this;
        }

        return this.init();
    }
    apex.plugins.mapbox.mapBoxMap.prototype = {

        /**
         * [setView -  API method, zoom to spec. position]
         * @param   Number  x          x cord.
         * @param   Number  y          y cord.
         * @param   Number  zoomLevel zoomLevel
         */
        setView: function setView(x, y, zoomLevel) {
            xDebug.call(this, arguments.callee.name, arguments);
            return this.map
                       .setView([x, y], zoomLevel);
        },

        /**
         * [zoomTo set/get zoomLevel]
         * @param   Number  zoomLevel
         * @return  Number  zoomLevel
         */
        zoomTo: function zoomTo(zoomLevel){
            xDebug.call(this, arguments.callee.name, arguments);
            if(zoomLevel){
                this.map.setZoom(zoomLevel);
            }

            return this.map.getZoom();
        },

        /**
         * [setBounds - zoom to spec. bounds]
         * @param L.bounds bbox     L.bounds - object
         * @param Number zoomLevel  zoomLevel - number
         */
        setBounds: function setBounds(bbox, zoomLevel) {
            xDebug.call(this, arguments.callee.name, arguments);
            this.map.fitBounds(bbox);
            if(this.map.zoomTo){
                this.map.zoomTo(zoomLevel);
            }
            return this;
        },

        /**
         * [setGeoJSON - load geojson object on map]
         * @param Object  geoJson geoJson object
         * @param Boolean zoomTo  true/false to zoom on geometry bounds
         */
        setGeoJSON:function setGeoJSON(geoJson, zoomTo) {
            xDebug.call(this, arguments.callee.name, arguments);
            this.map.featureLayer.setGeoJSON(geoJson);
            if(zoomTo === true){
                this.setBounds(this.map.featureLayer.getBounds());
            }
            return this;
        }

    };

})(apex.jQuery, apex);
<commit_msg>code form.<commit_after>/**
 * [created by isabolic sabolic.ivan@gmail.com]
 */
(function($, x) {
    var options = {
        mapRegionContainer : null,
        mapRegionId        : null,
        mapName            : null,
        width              : "100%",
        height             : 300,
        initalView         : {
            x                  : null,
            y                  : null,
            zoomLevel          : null
        }
    };

    /**
     * [xDebug - PRIVATE function for debug]
     * @param  string   functionName  caller function
     * @param  array    params        caller arguments
     */
    var xDebug = function(functionName, params){
        x.debug(this.jsName || " - " || functionName, params, this);
    };

    /**
     * [triggerEvent     - PRIVATE handler fn - trigger apex events]
     * @param String evt - apex event name to trigger
     */
    var triggerEvent = function(evt, evtData) {
        xDebug.call(this, arguments.callee.name, arguments);
        this.container.trigger(evt, [evtData]);
        $(this).trigger(evt + "." + this.apexname, [evtData]);
    };

    /**
     * [resizeMap        - PRIVATE event handler fn -  when map bbox change]
     * @param String evt - apex event name to trigger
     */
    var bboxChangeEvt = function(evt) {
        var bbox     = this.map.getBounds(),
            bboxJson = {
                "west"   : bbox.getWest(),
                "south"  : bbox.getSouth(),
                "east"   : bbox.getEast(),
                "north"  : bbox.getNorth(),
                "string" : "BBOX(" + this.map.getBounds().toBBoxString() + ")"
            };

        triggerEvent.apply(this, [evt, bboxJson]);
    };

    /**
     * [zoomLlvChangeEvt - PRIVATE event handler fn - when map zoom level change]
     * @param String evt - apex event name to trigger
     */
    var zoomLlvChangeEvt = function(evt) {
        var lvl = {
            "zoomLevel": this.map.getZoom()
        }
        triggerEvent.apply(this, [evt, lvl]);
    };

    /**
     * [resizeMap        - PRIVATE event handler fn]
     * @param String evt - apex event name to trigger
     */
    var resizeMap = function (evt){
        var o = {
            w : this.region.width(),
            h : this.region.height(),
        },
        timer,
        bounds = this.map.getBounds();

        // wait until html renders
        timer = setTimeout(function(){
            if(o.w === this.region.width() &&
               o.h === this.region.height()){

                if(this.container.hasClass("max-width") === false){
                    this.container.addClass("max-width");
                }else{
                    this.container.removeClass("max-width");
                }

                this.map.invalidateSize();
                this.map.fitBounds(bounds);

                triggerEvent.apply(this, [evt]);

            }
        }.bind(this), 100);
    };

    apex.plugins.mapbox.mapBoxMap = function(opts) {
        this.map = null;
        this.options = {};
        this.container = null;
        this.region = null;
        this.events = ["mapboxmap-change-bbox",
                       "mapboxmap-change-zoomlevel",
                       "mapboxmap-maximize-region"];
        this.jsName = "apex.plugins.mapBoxMap";
        this.apexname = "MAPBOXREGION";
        this.init = function() {

            if ($.isPlainObject(options)) {
                this.options = $.extend(true, {}, this.options, options, opts);
            } else {
                throw this.jsName || ": Invalid options passed.";
            }

            if (this.options.mapRegionContainer === null) {
                throw this.jsName || ": mapRegionContainer is required.";
            }

            this.container = $("#" + this.options.mapRegionContainer);

            if (this.container.length !== 1) {
                throw this.jsName || ": Invalid region selector.";
            }

            if (this.options.mapRegionId === null) {
                throw this.jsName || ": mapRegionContainer is required.";
            }

            this.region = $("#" + this.options.mapRegionId);

            if (this.region.length !== 1) {
                throw this.jsName || ": Invalid region selector.";
            }

            this.container.addClass("mapbox-map");

            this.map = L.mapbox.map(this.container.get(0),
                                    'mapbox.streets',
                                    {
                                        trackResize: true,
                                        detectRetina: true
                                    });

            this.container.height(this.options.height);
            this.container.width(this.options.width);

            if (this.options.initalView.x &&
                this.options.initalView.y &&
                this.options.initalView.zoomLevel) {

                this.setView(
                    this.options.initalView.x,
                    this.options.initalView.y,
                    this.options.initalView.zoomLevel
                )
            }

            this.map.on("move"   , bboxChangeEvt.bind(   this, this.events[0]));
            this.map.on("zoomend", zoomLlvChangeEvt.bind(this, this.events[1]));
            this.region
                .on("click", 'span.js-maximizeButtonContainer',
                    resizeMap.bind(this, this.events[2]));

            this.region.data("mapboxRegion", this);

            x.debug("apex.plugins.mapBoxMap : ", this);

            return this;
        }

        return this.init();
    }
    apex.plugins.mapbox.mapBoxMap.prototype = {

        /**
         * [setView -  API method, zoom to spec. position]
         * @param   Number  x          x cord.
         * @param   Number  y          y cord.
         * @param   Number  zoomLevel zoomLevel
         */
        setView: function setView(x, y, zoomLevel) {
            xDebug.call(this, arguments.callee.name, arguments);
            return this.map
                       .setView([x, y], zoomLevel);
        },

        /**
         * [zoomTo set/get zoomLevel]
         * @param   Number  zoomLevel
         * @return  Number  zoomLevel
         */
        zoomTo: function zoomTo(zoomLevel){
            xDebug.call(this, arguments.callee.name, arguments);
            if(zoomLevel){
                this.map.setZoom(zoomLevel);
            }

            return this.map.getZoom();
        },

        /**
         * [setBounds - zoom to spec. bounds]
         * @param L.bounds bbox     L.bounds - object
         * @param Number zoomLevel  zoomLevel - number
         */
        setBounds: function setBounds(bbox, zoomLevel) {
            xDebug.call(this, arguments.callee.name, arguments);
            this.map.fitBounds(bbox);
            if(this.map.zoomTo){
                this.map.zoomTo(zoomLevel);
            }
            return this;
        },

        /**
         * [setGeoJSON - load geojson object on map]
         * @param Object  geoJson geoJson object
         * @param Boolean zoomTo  true/false to zoom on geometry bounds
         */
        setGeoJSON:function setGeoJSON(geoJson, zoomTo) {
            xDebug.call(this, arguments.callee.name, arguments);
            this.map.featureLayer.setGeoJSON(geoJson);
            if(zoomTo === true){
                this.setBounds(this.map.featureLayer.getBounds());
            }
            return this;
        }

    };

})(apex.jQuery, apex);
<|endoftext|>


<commit_before>import { lazy } from "./utils";

const Routes = {
  HomePage: lazy(() =>
    import(/* webpackChunkName: "r-homepage" */ "@agir/front/app/Homepage/Home")
  ),
  AgendaPage: lazy(() =>
    import(
      /* webpackChunkName: "r-agendapage" */ "@agir/events/agendaPage/Agenda"
    )
  ),
  EventMap: lazy(() =>
    import(
      /* webpackChunkName: "r-eventmap" */ "@agir/carte/page__eventMap/EventMap"
    )
  ),
  EventPage: lazy(() =>
    import(
      /* webpackChunkName: "r-eventpage" */ "@agir/events/eventPage/EventPage"
    )
  ),
  CreateEvent: lazy(() =>
    import(
      /* webpackChunkName: "r-createevent" */ "@agir/events/createEventPage/CreateEvent"
    )
  ),
  MissingDocumentsPage: lazy(() =>
    import(
      /* webpackChunkName: "r-missingdocumentspage" */ "@agir/events/eventRequiredDocuments/MissingDocuments/MissingDocumentsPage"
    )
  ),
  EventRequiredDocuments: lazy(() =>
    import(
      /* webpackChunkName: "r-eventrequireddocuments" */ "@agir/events/eventRequiredDocuments/EventRequiredDocumentsPage"
    )
  ),
  GroupsPage: lazy(() =>
    import(
      /* webpackChunkName: "r-groupspage" */ "@agir/groups/groupsPage/GroupsPage"
    )
  ),
  FullGroupPage: lazy(() =>
    import(
      /* webpackChunkName: "r-fullgrouppage" */ "@agir/groups/fullGroupPage/FullGroupPage"
    )
  ),
  GroupPage: lazy(() =>
    import(
      /* webpackChunkName: "r-grouppage" */ "@agir/groups/groupPage/GroupPage"
    )
  ),
  GroupMessagePage: lazy(() =>
    import(
      /* webpackChunkName: "r-groupmessagepage" */ "@agir/groups/groupPage/GroupMessagePage"
    )
  ),
  GroupMap: lazy(() =>
    import(
      /* webpackChunkName: "r-groupmap" */ "@agir/carte/page__groupMap/GroupMap"
    )
  ),
  ActivityPage: lazy(() =>
    import(
      /* webpackChunkName: "r-activitypage" */ "@agir/activity/ActivityPage/ActivityPage"
    )
  ),
  NavigationPage: lazy(() =>
    import(
      /* webpackChunkName: "r-navigationpage" */ "@agir/front/navigationPage/NavigationPage"
    )
  ),
  SignupPage: lazy(() =>
    import(
      /* webpackChunkName: "r-signuppage" */ "@agir/front/authentication/Connexion/SignupPage"
    )
  ),
  LoginPage: lazy(() =>
    import(
      /* webpackChunkName: "r-loginpage" */ "@agir/front/authentication/Connexion/LoginPage"
    )
  ),
  CodeLoginPage: lazy(() =>
    import(
      /* webpackChunkName: "r-codeloginpage" */ "@agir/front/authentication/Connexion/Code/CodeLogin"
    )
  ),
  CodeSignupPage: lazy(() =>
    import(
      /* webpackChunkName: "r-codesignuppage" */ "@agir/front/authentication/Connexion/Code/CodeSignup"
    )
  ),
  TellMorePage: lazy(() =>
    import(
      /* webpackChunkName: "r-tellmorepage" */ "@agir/front/authentication/Connexion/TellMore/TellMorePage"
    )
  ),
  LogoutPage: lazy(() =>
    import(
      /* webpackChunkName: "r-logoutpage" */ "@agir/front/authentication/Connexion/Logout"
    )
  ),
  MessagePage: lazy(() =>
    import(
      /* webpackChunkName: "r-messagepage" */ "@agir/msgs/MessagePage/MessagePage"
    )
  ),
  CreateContactPage: lazy(() =>
    import(
      /* webpackChunkName: "r-createcontactpage" */ "@agir/people/contacts/CreateContactPage"
    )
  ),
  DonationPage: lazy(() =>
    import(
      /* webpackChunkName: "r-donationpage" */ "@agir/donations/donationPage/DonationPage"
    )
  ),
  DonationInformationsPage: lazy(() =>
    import(
      /* webpackChunkName: "r-donationinformationspage" */ "@agir/donations/donationPage/InformationsPage"
    )
  ),
  ActionToolsPage: lazy(() =>
    import(
      /* webpackChunkName: "r-actiontoolspage" */ "@agir/front/ActionToolsPage/ActionToolsPage"
    )
  ),
  SearchPage: lazy(() =>
    import(
      /* webpackChunkName: "r-searchpage" */ "@agir/front/SearchPage/SearchPage"
    )
  ),
  SearchGroupPage: lazy(() =>
    import(
      /* webpackChunkName: "r-searchgrouppage" */ "@agir/front/SearchPage/SearchGroupPage"
    )
  ),
  SearchEventPage: lazy(() =>
    import(
      /* webpackChunkName: "r-searcheventpage" */ "@agir/front/SearchPage/SearchEventPage"
    )
  ),
  NewVotingProxyRequest: lazy(() =>
    import(
      /* webpackChunkName: "r-newvotingproxyrequest" */ "@agir/voting_proxies/VotingProxyRequest/NewVotingProxyRequest"
    )
  ),
  NewVotingProxy: lazy(() =>
    import(
      /* webpackChunkName: "r-newvotingproxy" */ "@agir/voting_proxies/VotingProxy/NewVotingProxy"
    )
  ),
  ReplyToVotingProxyRequests: lazy(() =>
    import(
      /* webpackChunkName: "r-replytovotingproxyrequests" */ "@agir/voting_proxies/VotingProxy/ReplyToVotingProxyRequests"
    )
  ),
  VotingProxyRequestDetails: lazy(() =>
    import(
      /* webpackChunkName: "r-votingproxyrequestdetails" */ "@agir/voting_proxies/VotingProxyRequest/VotingProxyRequestDetails"
    )
  ),
  TestErrorPage: lazy(() =>
    import(
      /* webpackChunkName: "r-testerrorpage" */ "@agir/front/errorPage/TestErrorPage"
    )
  ),
  TokTokPreview: lazy(() =>
    import(
      /* webpackChunkName: "r-testtoktokpreview" */ "@agir/events/TokTok/TokTokPreview"
    )
  ),
};

export default Routes;
<commit_msg>fix webpack chunkname toktok while merging<commit_after>import { lazy } from "./utils";

const Routes = {
  HomePage: lazy(() =>
    import(/* webpackChunkName: "r-homepage" */ "@agir/front/app/Homepage/Home")
  ),
  AgendaPage: lazy(() =>
    import(
      /* webpackChunkName: "r-agendapage" */ "@agir/events/agendaPage/Agenda"
    )
  ),
  EventMap: lazy(() =>
    import(
      /* webpackChunkName: "r-eventmap" */ "@agir/carte/page__eventMap/EventMap"
    )
  ),
  EventPage: lazy(() =>
    import(
      /* webpackChunkName: "r-eventpage" */ "@agir/events/eventPage/EventPage"
    )
  ),
  CreateEvent: lazy(() =>
    import(
      /* webpackChunkName: "r-createevent" */ "@agir/events/createEventPage/CreateEvent"
    )
  ),
  MissingDocumentsPage: lazy(() =>
    import(
      /* webpackChunkName: "r-missingdocumentspage" */ "@agir/events/eventRequiredDocuments/MissingDocuments/MissingDocumentsPage"
    )
  ),
  EventRequiredDocuments: lazy(() =>
    import(
      /* webpackChunkName: "r-eventrequireddocuments" */ "@agir/events/eventRequiredDocuments/EventRequiredDocumentsPage"
    )
  ),
  GroupsPage: lazy(() =>
    import(
      /* webpackChunkName: "r-groupspage" */ "@agir/groups/groupsPage/GroupsPage"
    )
  ),
  FullGroupPage: lazy(() =>
    import(
      /* webpackChunkName: "r-fullgrouppage" */ "@agir/groups/fullGroupPage/FullGroupPage"
    )
  ),
  GroupPage: lazy(() =>
    import(
      /* webpackChunkName: "r-grouppage" */ "@agir/groups/groupPage/GroupPage"
    )
  ),
  GroupMessagePage: lazy(() =>
    import(
      /* webpackChunkName: "r-groupmessagepage" */ "@agir/groups/groupPage/GroupMessagePage"
    )
  ),
  GroupMap: lazy(() =>
    import(
      /* webpackChunkName: "r-groupmap" */ "@agir/carte/page__groupMap/GroupMap"
    )
  ),
  ActivityPage: lazy(() =>
    import(
      /* webpackChunkName: "r-activitypage" */ "@agir/activity/ActivityPage/ActivityPage"
    )
  ),
  NavigationPage: lazy(() =>
    import(
      /* webpackChunkName: "r-navigationpage" */ "@agir/front/navigationPage/NavigationPage"
    )
  ),
  SignupPage: lazy(() =>
    import(
      /* webpackChunkName: "r-signuppage" */ "@agir/front/authentication/Connexion/SignupPage"
    )
  ),
  LoginPage: lazy(() =>
    import(
      /* webpackChunkName: "r-loginpage" */ "@agir/front/authentication/Connexion/LoginPage"
    )
  ),
  CodeLoginPage: lazy(() =>
    import(
      /* webpackChunkName: "r-codeloginpage" */ "@agir/front/authentication/Connexion/Code/CodeLogin"
    )
  ),
  CodeSignupPage: lazy(() =>
    import(
      /* webpackChunkName: "r-codesignuppage" */ "@agir/front/authentication/Connexion/Code/CodeSignup"
    )
  ),
  TellMorePage: lazy(() =>
    import(
      /* webpackChunkName: "r-tellmorepage" */ "@agir/front/authentication/Connexion/TellMore/TellMorePage"
    )
  ),
  LogoutPage: lazy(() =>
    import(
      /* webpackChunkName: "r-logoutpage" */ "@agir/front/authentication/Connexion/Logout"
    )
  ),
  MessagePage: lazy(() =>
    import(
      /* webpackChunkName: "r-messagepage" */ "@agir/msgs/MessagePage/MessagePage"
    )
  ),
  CreateContactPage: lazy(() =>
    import(
      /* webpackChunkName: "r-createcontactpage" */ "@agir/people/contacts/CreateContactPage"
    )
  ),
  DonationPage: lazy(() =>
    import(
      /* webpackChunkName: "r-donationpage" */ "@agir/donations/donationPage/DonationPage"
    )
  ),
  DonationInformationsPage: lazy(() =>
    import(
      /* webpackChunkName: "r-donationinformationspage" */ "@agir/donations/donationPage/InformationsPage"
    )
  ),
  ActionToolsPage: lazy(() =>
    import(
      /* webpackChunkName: "r-actiontoolspage" */ "@agir/front/ActionToolsPage/ActionToolsPage"
    )
  ),
  SearchPage: lazy(() =>
    import(
      /* webpackChunkName: "r-searchpage" */ "@agir/front/SearchPage/SearchPage"
    )
  ),
  SearchGroupPage: lazy(() =>
    import(
      /* webpackChunkName: "r-searchgrouppage" */ "@agir/front/SearchPage/SearchGroupPage"
    )
  ),
  SearchEventPage: lazy(() =>
    import(
      /* webpackChunkName: "r-searcheventpage" */ "@agir/front/SearchPage/SearchEventPage"
    )
  ),
  NewVotingProxyRequest: lazy(() =>
    import(
      /* webpackChunkName: "r-newvotingproxyrequest" */ "@agir/voting_proxies/VotingProxyRequest/NewVotingProxyRequest"
    )
  ),
  NewVotingProxy: lazy(() =>
    import(
      /* webpackChunkName: "r-newvotingproxy" */ "@agir/voting_proxies/VotingProxy/NewVotingProxy"
    )
  ),
  ReplyToVotingProxyRequests: lazy(() =>
    import(
      /* webpackChunkName: "r-replytovotingproxyrequests" */ "@agir/voting_proxies/VotingProxy/ReplyToVotingProxyRequests"
    )
  ),
  VotingProxyRequestDetails: lazy(() =>
    import(
      /* webpackChunkName: "r-votingproxyrequestdetails" */ "@agir/voting_proxies/VotingProxyRequest/VotingProxyRequestDetails"
    )
  ),
  TestErrorPage: lazy(() =>
    import(
      /* webpackChunkName: "r-testerrorpage" */ "@agir/front/errorPage/TestErrorPage"
    )
  ),
  TokTokPreview: lazy(() =>
    import(
      /* webpackChunkName: "r-toktokpreview" */ "@agir/events/TokTok/TokTokPreview"
    )
  ),
};

export default Routes;
<|endoftext|>