<commit_before>/* eslint-disable react/default-props-match-prop-types */
/* eslint-disable react/forbid-prop-types */
/**
 * mSupply Mobile
 * Sustainable Solutions (NZ) Ltd. 2019
 */

import React from 'react';
import PropTypes from 'prop-types';

import IonIcon from 'react-native-vector-icons/Ionicons';
import FAIcon from 'react-native-vector-icons/FontAwesome';
import FA5Icon from 'react-native-vector-icons/FontAwesome5';
import EvilIcon from 'react-native-vector-icons/EvilIcons';
import EntypoIcon from 'react-native-vector-icons/Entypo';
import MaterialIcon from 'react-native-vector-icons/MaterialCommunityIcons';

import {
  WHITE,
  FINALISE_GREEN,
  SUSSOL_ORANGE,
  FINALISED_RED,
  DARK_GREY,
  dataTableColors,
} from '../globalStyles';

export const SortAscIcon = () => <FAIcon name="sort-asc" size={15} style={{ marginRight: 10 }} />;
export const SortNeutralIcon = () => <FAIcon name="sort" size={15} style={{ marginRight: 10 }} />;
export const SortDescIcon = () => <FAIcon name="sort-desc" size={15} style={{ marginRight: 10 }} />;

export const CheckedIcon = () => (
  <IonIcon name="md-radio-button-on" size={15} color={dataTableColors.checkableCellChecked} />
);

export const UncheckedIcon = () => (
  <IonIcon name="md-radio-button-off" size={15} color={SUSSOL_ORANGE} />
);

export const DisabledCheckedIcon = () => (
  <IonIcon name="md-radio-button-on" size={15} color={dataTableColors.checkableCellDisabled} />
);
export const DisabledUncheckedIcon = () => <MaterialIcon name="cancel" size={15} />;

export const OpenModalIcon = () => (
  <FAIcon name="angle-double-up" size={20} color={SUSSOL_ORANGE} />
);

export const MagnifyingGlassIcon = React.memo(({ size, color }) => (
  <EvilIcon name="search" size={size} color={color} />
));
MagnifyingGlassIcon.propTypes = { size: PropTypes.number, color: PropTypes.string };
MagnifyingGlassIcon.defaultProps = { size: 40, color: SUSSOL_ORANGE };

export const CancelIcon = React.memo(() => (
  <EntypoIcon name="cross" color={FINALISED_RED} size={25} />
));

export const CloseIcon = ({ size, color }) => <IonIcon name="md-close" size={size} color={color} />;
CloseIcon.defaultProps = { color: WHITE, size: 36 };
CloseIcon.propTypes = { color: PropTypes.string, size: PropTypes.number };

export const ExpandIcon = React.memo(() => (
  <FAIcon name="external-link" size={16} color={SUSSOL_ORANGE} />
));

export const ConfirmIcon = React.memo(({ style }) => <FAIcon name="check-circle" style={style} />);
ConfirmIcon.defaultProps = { style: { color: FINALISE_GREEN, fontSize: 40 } };
ConfirmIcon.propTypes = { style: PropTypes.object };

export const LockIcon = React.memo(({ style }) => <FAIcon name="lock" size={28} style={style} />);
LockIcon.defaultProps = { style: { color: FINALISED_RED, marginHorizontal: 8, bottom: 6 } };
LockIcon.propTypes = { style: PropTypes.object };

export const ChevronDownIcon = React.memo(({ color, size }) => (
  <FA5Icon name="chevron-down" color={color} size={size} />
));
ChevronDownIcon.defaultProps = { color: WHITE, size: 20 };
ChevronDownIcon.propTypes = { color: PropTypes.string, size: PropTypes.number };

export const PencilIcon = React.memo(({ color, size }) => (
  <FAIcon name="pencil" color={color} size={size} />
));
PencilIcon.defaultProps = { color: WHITE, size: 20 };
PencilIcon.propTypes = { color: PropTypes.string, size: PropTypes.number };

export const HistoryIcon = ({ color, size }) => (
  <FA5Icon name="history" size={size} color={color} />
);
HistoryIcon.defaultProps = { color: WHITE, size: 20 };
HistoryIcon.propTypes = { color: PropTypes.string, size: PropTypes.number };

export const ChevronRightIcon = () => (
  <FA5Icon name="chevron-right" color={SUSSOL_ORANGE} size={20} />
);

export const FavouriteStarIcon = () => <FAIcon name="star-o" color={SUSSOL_ORANGE} size={20} />;
export const BurgerMenuIcon = () => <EntypoIcon name="menu" color={SUSSOL_ORANGE} size={30} />;
export const AddIcon = ({ size, color }) => <IonIcon name="ios-add" size={size} color={color} />;
AddIcon.defaultProps = { color: WHITE, size: 30 };
AddIcon.propTypes = { color: PropTypes.string, size: PropTypes.number };

export const MinusIcon = ({ size, color }) => (
  <IonIcon name="ios-remove" size={size} color={color} />
);
MinusIcon.defaultProps = { color: WHITE, size: 30 };
MinusIcon.propTypes = { color: PropTypes.string, size: PropTypes.number };

export const CalendarIcon = () => <FAIcon name="calendar" size={20} color={WHITE} />;

export const BackIcon = () => <FAIcon name="chevron-left" size={16} color="black" />;

export const CloudIcon = ({ color, size, style }) => (
  <IonIcon name="md-cloud" size={size} color={color} style={style} />
);
CloudIcon.defaultProps = { color: DARK_GREY, size: 30, style: { top: 6 } };
CloudIcon.propTypes = { color: PropTypes.string, size: PropTypes.number, style: PropTypes.object };

export const ArrowIcon = ({ color, size, style }) => (
  <FAIcon name="exchange" size={size} style={style} color={color} />
);
ArrowIcon.defaultProps = { color: DARK_GREY, size: 16, style: { marginLeft: 10 } };
ArrowIcon.propTypes = { color: PropTypes.string, size: PropTypes.number, style: PropTypes.object };

export const WifiIcon = ({ color, size, style }) => (
  <IonIcon name="logo-rss" size={size} style={style} color={color} />
);
WifiIcon.defaultProps = { color: DARK_GREY, size: 22, style: { marginLeft: 10 } };
WifiIcon.propTypes = { color: PropTypes.string, size: PropTypes.number, style: PropTypes.object };
<commit_msg>Add adjusting of icon styles<commit_after>/* eslint-disable react/default-props-match-prop-types */
/* eslint-disable react/forbid-prop-types */
/**
 * mSupply Mobile
 * Sustainable Solutions (NZ) Ltd. 2019
 */

import React from 'react';
import PropTypes from 'prop-types';

import IonIcon from 'react-native-vector-icons/Ionicons';
import FAIcon from 'react-native-vector-icons/FontAwesome';
import FA5Icon from 'react-native-vector-icons/FontAwesome5';
import EvilIcon from 'react-native-vector-icons/EvilIcons';
import EntypoIcon from 'react-native-vector-icons/Entypo';
import MaterialIcon from 'react-native-vector-icons/MaterialCommunityIcons';

import {
  WHITE,
  FINALISE_GREEN,
  SUSSOL_ORANGE,
  FINALISED_RED,
  DARK_GREY,
  dataTableColors,
} from '../globalStyles';

export const SortAscIcon = () => <FAIcon name="sort-asc" size={15} style={{ marginRight: 10 }} />;
export const SortNeutralIcon = () => <FAIcon name="sort" size={15} style={{ marginRight: 10 }} />;
export const SortDescIcon = () => <FAIcon name="sort-desc" size={15} style={{ marginRight: 10 }} />;

export const CheckedIcon = () => (
  <IonIcon name="md-radio-button-on" size={15} color={dataTableColors.checkableCellChecked} />
);

export const UncheckedIcon = () => (
  <IonIcon name="md-radio-button-off" size={15} color={SUSSOL_ORANGE} />
);

export const DisabledCheckedIcon = () => (
  <IonIcon name="md-radio-button-on" size={15} color={dataTableColors.checkableCellDisabled} />
);
export const DisabledUncheckedIcon = () => <MaterialIcon name="cancel" size={15} />;

export const OpenModalIcon = () => (
  <FAIcon name="angle-double-up" size={20} color={SUSSOL_ORANGE} />
);

export const MagnifyingGlassIcon = React.memo(({ size, color }) => (
  <EvilIcon name="search" size={size} color={color} />
));
MagnifyingGlassIcon.propTypes = { size: PropTypes.number, color: PropTypes.string };
MagnifyingGlassIcon.defaultProps = { size: 40, color: SUSSOL_ORANGE };

export const CancelIcon = React.memo(() => (
  <EntypoIcon name="cross" color={FINALISED_RED} size={25} />
));

export const CloseIcon = ({ size, color }) => <IonIcon name="md-close" size={size} color={color} />;
CloseIcon.defaultProps = { color: WHITE, size: 36 };
CloseIcon.propTypes = { color: PropTypes.string, size: PropTypes.number };

export const ExpandIcon = React.memo(() => (
  <FAIcon name="external-link" size={16} color={SUSSOL_ORANGE} />
));

export const ConfirmIcon = React.memo(({ style }) => <FAIcon name="check-circle" style={style} />);
ConfirmIcon.defaultProps = { style: { color: FINALISE_GREEN, fontSize: 40 } };
ConfirmIcon.propTypes = { style: PropTypes.object };

export const LockIcon = React.memo(({ style }) => <FAIcon name="lock" size={28} style={style} />);
LockIcon.defaultProps = { style: { color: FINALISED_RED, marginHorizontal: 8, bottom: 6 } };
LockIcon.propTypes = { style: PropTypes.object };

export const ChevronDownIcon = React.memo(({ color, size }) => (
  <FA5Icon name="chevron-down" color={color} size={size} />
));
ChevronDownIcon.defaultProps = { color: WHITE, size: 20 };
ChevronDownIcon.propTypes = { color: PropTypes.string, size: PropTypes.number };

export const PencilIcon = React.memo(({ color, size }) => (
  <FAIcon name="pencil" color={color} size={size} />
));
PencilIcon.defaultProps = { color: WHITE, size: 20 };
PencilIcon.propTypes = { color: PropTypes.string, size: PropTypes.number };

export const HistoryIcon = ({ color, size }) => (
  <FA5Icon name="history" size={size} color={color} />
);
HistoryIcon.defaultProps = { color: WHITE, size: 20 };
HistoryIcon.propTypes = { color: PropTypes.string, size: PropTypes.number };

export const ChevronRightIcon = () => (
  <FA5Icon name="chevron-right" color={SUSSOL_ORANGE} size={20} />
);

export const FavouriteStarIcon = () => <FAIcon name="star-o" color={SUSSOL_ORANGE} size={20} />;
export const BurgerMenuIcon = () => <EntypoIcon name="menu" color={SUSSOL_ORANGE} size={30} />;
export const AddIcon = ({ size, color }) => <IonIcon name="ios-add" size={size} color={color} />;
AddIcon.defaultProps = { color: WHITE, size: 30 };
AddIcon.propTypes = { color: PropTypes.string, size: PropTypes.number };

export const MinusIcon = ({ size, color }) => (
  <IonIcon name="ios-remove" size={size} color={color} />
);
MinusIcon.defaultProps = { color: WHITE, size: 30 };
MinusIcon.propTypes = { color: PropTypes.string, size: PropTypes.number };

export const CalendarIcon = () => <FAIcon name="calendar" size={20} color={WHITE} />;

export const BackIcon = () => <FAIcon name="chevron-left" size={16} color="black" />;

export const CloudIcon = ({ color, size, style }) => (
  <IonIcon name="md-cloud" size={size} color={color} style={style} />
);
CloudIcon.defaultProps = { color: DARK_GREY, size: 30, style: {} };
CloudIcon.propTypes = { color: PropTypes.string, size: PropTypes.number, style: PropTypes.object };

export const ArrowIcon = ({ color, size, style }) => (
  <FAIcon name="exchange" size={size} style={style} color={color} />
);
ArrowIcon.defaultProps = { color: DARK_GREY, size: 16, style: { marginLeft: 10 } };
ArrowIcon.propTypes = { color: PropTypes.string, size: PropTypes.number, style: PropTypes.object };

export const WifiIcon = ({ color, size, style }) => (
  <IonIcon name="logo-rss" size={size} style={style} color={color} />
);
WifiIcon.defaultProps = { color: DARK_GREY, size: 22, style: { marginLeft: 10 } };
WifiIcon.propTypes = { color: PropTypes.string, size: PropTypes.number, style: PropTypes.object };
<|endoftext|>


<commit_before>Pebble.addEventListener("showConfiguration", function(_event) {
  var url = (Pebble.getActiveWatchInfo && (Pebble.getActiveWatchInfo().platform == "basalt")) ? "http://sunnygoyal.com/pebble/formface/?" : "http://sunnygoyal.com/pebble/formface/aplite.html?";
  var keys = ["color1", "color2", "color3", "tricolor", "showdate"];
  for (var i = 0; i < keys.length; i++) {
    if (localStorage[keys[i]]) {
      url += encodeURIComponent(keys[i]) + "=" + encodeURIComponent(localStorage[keys[i]]) + "&";
    }
  }
	Pebble.openURL(url);
});

Pebble.addEventListener("webviewclosed", function(e) {
	var configData = JSON.parse(decodeURIComponent(e.response));
  if (configData.showdate === undefined) return;
  if (Pebble.getActiveWatchInfo && (Pebble.getActiveWatchInfo().platform == "basalt")) {
    Pebble.sendAppMessage({
      color1: parseInt(configData.color1, 16),
      color2: parseInt(configData.color2, 16),
      color3: parseInt(configData.color3, 16),
      showdate: configData.showdate
      }, function() {
        console.log('Send successful!');
        localStorage.showdate = configData.showdate;
        localStorage.color1 = configData.color1;
        localStorage.color2 = configData.color2;
        localStorage.color3 = configData.color3;
      }, function() {
        console.log('Send failed!');
      });
  } else {
    Pebble.sendAppMessage({
      showdate: configData.showdate,
      tricolor: configData.tricolor
      }, function() {
        console.log('Send successful!');
        localStorage.showdate = configData.showdate;
        localStorage.tricolor = configData.tricolor;
      }, function() {
        console.log('Send failed!');
      });
  }
});<commit_msg>Changing settings url to github<commit_after>Pebble.addEventListener("showConfiguration", function(_event) {
  var url = (Pebble.getActiveWatchInfo && (Pebble.getActiveWatchInfo().platform == "basalt")) ? "http://sunnygoyal.github.io/FORMWatchFace-pebble/settings/?" : "http://sunnygoyal.github.io/FORMWatchFace-pebble/settings/aplite.html?";
  var keys = ["color1", "color2", "color3", "tricolor", "showdate"];
  for (var i = 0; i < keys.length; i++) {
    if (localStorage[keys[i]]) {
      url += encodeURIComponent(keys[i]) + "=" + encodeURIComponent(localStorage[keys[i]]) + "&";
    }
  }
	Pebble.openURL(url);
});

Pebble.addEventListener("webviewclosed", function(e) {
	var configData = JSON.parse(decodeURIComponent(e.response));
  if (configData.showdate === undefined) return;
  if (Pebble.getActiveWatchInfo && (Pebble.getActiveWatchInfo().platform == "basalt")) {
    Pebble.sendAppMessage({
      color1: parseInt(configData.color1, 16),
      color2: parseInt(configData.color2, 16),
      color3: parseInt(configData.color3, 16),
      showdate: configData.showdate
      }, function() {
        console.log('Send successful!');
        localStorage.showdate = configData.showdate;
        localStorage.color1 = configData.color1;
        localStorage.color2 = configData.color2;
        localStorage.color3 = configData.color3;
      }, function() {
        console.log('Send failed!');
      });
  } else {
    Pebble.sendAppMessage({
      showdate: configData.showdate,
      tricolor: configData.tricolor
      }, function() {
        console.log('Send successful!');
        localStorage.showdate = configData.showdate;
        localStorage.tricolor = configData.tricolor;
      }, function() {
        console.log('Send failed!');
      });
  }
});<|endoftext|>


<commit_before>define([], function(){
    function PermalinkHub(opts){
        this.collectionHandlers = {};
        this.hasPermalinkModal = false;
        this.bus = opts.bus || window;

        var msgEvent = this.bus.addEventListener ? 'message' : 'onmessage';
        var addEvent = this.bus.addEventListener || this.bus.attachEvent;

        var self = this;
        addEvent(msgEvent, function(event){
            self.onPostMessage.call(self, event);
        }, false);
    }

    PermalinkHub.prototype.onPostMessage = function(event){
        var msg = null;
        if(typeof event.data === 'object')
            msg = event.data
        else {
            try{
                msg = JSON.parse(event.data)
            } catch(e){
                return;
            }
        }

        if(msg.to !== 'permalink' || !msg.data || !msg.action)
            return;

        if(msg.action === 'post'){
            if(msg.from === 'permalink-modal')
                this.receiveModalRegistration(msg.data);
            else
                this.receiveAppRegistration(msg.data);
        }

        if(msg.action === 'put'){
            if(msg.from === 'permalink-modal')
                this.messageAppToPermalink(msg.data);
        }
    };

    PermalinkHub.prototype.receiveModalHaveAppPermalink = function(data){
        var apps = this.collectionHandlers[data.collectionId] || []
        console.log('collectionHandlers ', this.collectionHandlers, data.collectionId)
        for(var i = 0; i < apps.length; i++)
            this.messageAppToPermalink(apps[i], data);
    };

    //This isn't as important as before now that we broadcast to all apps
    //listening to the model collection. We could remoe this entirely and
    //send the Model a message to show or not show its button.
    PermalinkHub.prototype.receiveModalRegistration = function(data){
        if(this.hasPermalinkModal) return;

        this.hasPermalinkModal = true;
        for(key in this.collectionHandlers)
            for(var i = 0; i < this.collectionHandlers[key].length; i++)
                this.messageModalAppInfo(this.collectionHandlers[key][i]);
    };

    PermalinkHub.prototype.receiveAppRegistration = function(data){
        this.collectionHandlers[data.collectionId] = this.collectionHandlers[data.collectionId] || []
        this.collectionHandlers[data.collectionId].push(data);
        if(this.hasPermalinkModal)
            this.messageModalAppInfo(data);
    };

    PermalinkHub.prototype.messageAppToPermalink = function(app, data){
        var msg = {
            from: 'permalink',
            to: app,
            action: 'put',
            data: data
        }
        this.bus.postMessage(JSON.stringify(msg),'*');
    };

    PermalinkHub.prototype.messageModalAppInfo = function(data){
        var msg = {
            from: 'permalink',
            to: 'permalink-modal',
            action: 'post',
            data: data
        }
        this.bus.postMessage(JSON.stringify(msg),'*');
    };

    return PermalinkHub;
});<commit_msg>Actually call the appropriate function instead of just forwarding a the modal message to permalink<commit_after>define([], function(){
    function PermalinkHub(opts){
        this.collectionHandlers = {};
        this.hasPermalinkModal = false;
        this.bus = opts.bus || window;

        var msgEvent = this.bus.addEventListener ? 'message' : 'onmessage';
        var addEvent = this.bus.addEventListener || this.bus.attachEvent;

        var self = this;
        addEvent(msgEvent, function(event){
            self.onPostMessage.call(self, event);
        }, false);
    }

    PermalinkHub.prototype.onPostMessage = function(event){
        var msg = null;
        if(typeof event.data === 'object')
            msg = event.data
        else {
            try{
                msg = JSON.parse(event.data)
            } catch(e){
                return;
            }
        }

        if(msg.to !== 'permalink' || !msg.data || !msg.action)
            return;

        if(msg.action === 'post'){
            if(msg.from === 'permalink-modal')
                this.receiveModalRegistration(msg.data);
            else
                this.receiveAppRegistration(msg.data);
        }

        if(msg.action === 'put'){
            if(msg.from === 'permalink-modal')
                this.receiveModalHaveAppPermalink(msg.data);
        }
    };

    PermalinkHub.prototype.receiveModalHaveAppPermalink = function(data){
        var apps = this.collectionHandlers[data.collectionId] || []
        console.log('collectionHandlers ', this.collectionHandlers, data.collectionId)
        for(var i = 0; i < apps.length; i++)
            this.messageAppToPermalink(apps[i], data);
    };

    //This isn't as important as before now that we broadcast to all apps
    //listening to the model collection. We could remoe this entirely and
    //send the Model a message to show or not show its button.
    PermalinkHub.prototype.receiveModalRegistration = function(data){
        if(this.hasPermalinkModal) return;

        this.hasPermalinkModal = true;
        for(key in this.collectionHandlers)
            for(var i = 0; i < this.collectionHandlers[key].length; i++)
                this.messageModalAppInfo(this.collectionHandlers[key][i]);
    };

    PermalinkHub.prototype.receiveAppRegistration = function(data){
        this.collectionHandlers[data.collectionId] = this.collectionHandlers[data.collectionId] || []
        this.collectionHandlers[data.collectionId].push(data);
        if(this.hasPermalinkModal)
            this.messageModalAppInfo(data);
    };

    PermalinkHub.prototype.messageAppToPermalink = function(app, data){
        var msg = {
            from: 'permalink',
            to: app,
            action: 'put',
            data: data
        }
        this.bus.postMessage(JSON.stringify(msg),'*');
    };

    PermalinkHub.prototype.messageModalAppInfo = function(data){
        var msg = {
            from: 'permalink',
            to: 'permalink-modal',
            action: 'post',
            data: data
        }
        this.bus.postMessage(JSON.stringify(msg),'*');
    };

    return PermalinkHub;
});<|endoftext|>


<commit_before>define(["pex/core/Vbo", "pex/core/Vec3", "pex/core/Vec4"], function(Vbo, Vec3, Vec4) {

  //options = {
  //  primitiveType : eg.: gl.POINTS
  //}
  function Mesh(gl, geometry, material, options) {
    this.options = options || {};
    this.gl = gl;
    this.material = material;
    this.geometry = geometry;
    this.vbo = Vbo.fromGeometry(gl, geometry, this.options.primitiveType);
    this.position = new Vec3(0,0,0);
    this.rotation = new Vec4(0, 1, 0, 0);
    this.scale = new Vec3(1, 1, 1);
  }

  Mesh.prototype.draw = function(camera) {

    if (camera) {
      this.material.uniforms.projectionMatrix = camera.getProjectionMatrix();
      this.material.uniforms.viewMatrix = camera.getViewMatrix();
      this.material.uniforms.modelViewMatrix = camera.calcModelViewMatrix(this.position, this.rotation, this.scale);
  	  this.material.uniforms.normalMatrix = this.material.uniforms.modelViewMatrix.dup().invert().transpose();
    }

    this.material.use();

    this.vbo.draw(this.material.program);
  }

  return Mesh;
});<commit_msg>Support for VBO in Mesh constructor<commit_after>define(["pex/core/Vbo", "pex/core/Vec3", "pex/core/Vec4"], function(Vbo, Vec3, Vec4) {

  //  Parameters:
  //    gl - gl context
  //    meshData - vbo or geometry
  //    material - mesh material
  //    options = {
  //      primitiveType : eg.: gl.POINTS
  //  }
  function Mesh(gl, meshData, material, options) {
    this.options = options || {};
    this.gl = gl;
    this.material = material;

    if (meshData instanceof Vbo) {
      this.vbo = meshData;
    }
    else {
      this.geometry = meshData;
      this.vbo = Vbo.fromGeometry(gl, meshData, this.options.primitiveType);
    }

    this.position = new Vec3(0,0,0);
    this.rotation = new Vec4(0, 1, 0, 0);
    this.scale = new Vec3(1, 1, 1);
  }

  Mesh.prototype.draw = function(camera) {

    if (camera) {
      this.material.uniforms.projectionMatrix = camera.getProjectionMatrix();
      this.material.uniforms.viewMatrix = camera.getViewMatrix();
      this.material.uniforms.modelViewMatrix = camera.calcModelViewMatrix(this.position, this.rotation, this.scale);
  	  this.material.uniforms.normalMatrix = this.material.uniforms.modelViewMatrix.dup().invert().transpose();
    }

    this.material.use();

    this.vbo.draw(this.material.program);
  }

  return Mesh;
});<|endoftext|>


<commit_before>import React, { Component, PropTypes } from 'react';
import { withState, withSidebar, withToolbar, withAutoMarkdown, withUniqueId, useBlocks } from './editor-decorators';
import { Button } from 'antd';
import { Editor, Html } from 'slate';
import withBlockTypes from './decorators';
import './style.less';

const options = {
  defaultNode: 'paragraph',
  toolbarMarks: [
    { type: 'bold', icon: 'bold' },
    { type: 'italic', icon: 'italic' },
    { type: 'underlined', icon: 'underline' },
    { type: 'code', icon: 'code' },
  ],
  toolbarTypes: [
    { type: 'heading-one', icon: 'header' },
    { type: 'heading-two', icon: 'header' },
    { type: 'block-quote', icon: 'quote-left' },
    { type: 'numbered-list', icon: 'list-ol' },
    { type: 'bulleted-list', icon: 'list-ul' },
  ],
  toolbarActions: [
    { type: 'link', icon: 'link', onClick: ({ value, onChange }, isActive) => {
      if (isActive) {
        value = value
          .transform()
          .unwrapInline('link')
          .apply();
      } else {
        let href = window.prompt('URL');
        if (href.indexOf('http') !== 0 && href.indexOf('.') !== -1) href = `http://${href}`;
        value = value
          .transform()
          .wrapInline({
            type: 'link',
            data: { href, target: '_blank' },
          })
          .collapseToEnd()
          .apply();
      }
      onChange(value);
    }, isActive: ({ value }) => {
      return value.inlines.some(inline => inline.type === 'link');
    } },
  ],
  sidebarTypes: [],
  nodes: {
    paragraph: ({ children, attributes }) =>
{children}
,
    link: ({ node, attributes, children }) => {children},
    'block-quote': ({ children, attributes }) =>
{children}
,
    'bulleted-list': ({ children, attributes }) =>
{children}
,
    'numbered-list': ({ children, attributes }) =>
{children}
,
    'heading-one': ({ children, attributes }) =>
{children}
,
    'heading-two': ({ children, attributes }) =>
{children}
,
    'heading-three': ({ children, attributes }) =>
{children}
,
    'heading-four': ({ children, attributes }) =>
{children}
,
    'heading-five': ({ children, attributes }) =>
{children}
,
    'heading-six': ({ children, attributes }) =>
{children}
,
    'bulleted-list-item': ({ children, attributes }) =>
{children}
,
    'numbered-list-item': ({ children, attributes }) =>
{children}
,
  },
  marks: {
    bold: ({ children, attributes }) => {children},
    code: ({ children, attributes }) => {children},
    italic: ({ children, attributes }) => {children},
    underlined: ({ children, attributes }) => {children},
  },
  getMarkdownType: (chars) => {
    switch (chars) {
      case '*':
      case '-':
      case '+': return 'bulleted-list-item';
      case '>': return 'block-quote';
      case '#': return 'heading-one';
      case '##': return 'heading-two';
      case '###': return 'heading-three';
      case '####': return 'heading-four';
      case '#####': return 'heading-five';
      case '######': return 'heading-six';
      case '1.': return 'numbered-list-item';
      default: return null;
    }
  },
};

const serializer = new Html({
  rules: [{
    deserialize(el, next) {
      const types = {
        p: 'paragraph',
        li: 'list-item',
        ul: 'bulleted-list',
        ol: 'numbered-list',
        blockquote: 'quote',
        pre: 'code',
        h1: 'heading-one',
        h2: 'heading-two',
        h3: 'heading-three',
        h4: 'heading-four',
        h5: 'heading-five',
        h6: 'heading-six',
      };
      const block = types[el.tagName];
      if (!block) return undefined;
      return {
        kind: 'block',
        type: block,
        nodes: next(el.children),
      };
    },
  }, {
    deserialize(el, next) {
      const marks = {
        strong: 'bold',
        em: 'italic',
        u: 'underline',
        s: 'strikethrough',
        code: 'code',
      };
      const mark = marks[el.tagName];
      if (!mark) return undefined;
      return {
        kind: 'mark',
        type: mark,
        nodes: next(el.children),
      };
    },
  }, {
    // Special case for code blocks, which need to grab the nested children.
    deserialize(el, next) {
      if (el.tagName !== 'pre') return undefined;
      const code = el.children[0];
      const children = code && code.tagName === 'code'
        ? code.children
        : el.children;

      return {
        kind: 'block',
        type: 'code',
        nodes: next(children),
      };
    },
  }, {
    // Special case for links, to grab their href.
    deserialize(el, next) {
      if (el.tagName !== 'a') return undefined;
      return {
        kind: 'inline',
        type: 'link',
        nodes: next(el.children),
        data: {
          href: el.attribs.href,
        },
      };
    },
  }],
});

@withBlockTypes
@withUniqueId()
@withState({ terse: true })
@useBlocks(options)
@withAutoMarkdown(options)
@withToolbar(options)
@withSidebar(options)
export default class SlateEditor extends Component {
  state = {};
  static propTypes = {
    readOnly: PropTypes.bool,
    showUndo: PropTypes.bool,
    children: PropTypes.node,
    value: PropTypes.object,
    onChange: PropTypes.func,
    marks: PropTypes.object,
    nodes: PropTypes.object,
    autoMarkDownKeyDown: PropTypes.func,
    plugins: PropTypes.array,
    className: PropTypes.string,
  }
  static defaultProps = {
    readOnly: false,
  }

  onPaste = (e, data, state) => {
    if (data.type !== 'html') return;
    const { document } = serializer.deserialize(data.html);

    console.log(data.html, document);

    return state
      .transform()
      .insertFragment(document)
      .apply();
  }

  onKeyDown = (e, data, state) => {
    if (e.shiftKey && data.key === 'enter') {
      // shift + enter
      return state
        .transform()
        .insertText('\n')
        .apply();
    } else if (e.metaKey || e.ctrlKey) {
      // cmd/ctrl + ???
      switch (data.key) {
        case 'b':
          return state
            .transform()
            .toggleMark('bold')
            .apply();

        case 'u':
          return state
            .transform()
            .toggleMark('underlined')
            .apply();

        case 'i':
          return state
            .transform()
            .toggleMark('italic')
            .apply();

        default:
          return;
      }
    }

    return;
  }

  render = () => {
    const { children, showUndo, value, onChange, readOnly, marks, nodes, plugins, className, spellcheck, ...rest } = this.props;

    return (

        {value && showUndo && value.hasUndos && (
          <Button type="default" shape="circle" onClick={() => onChange(value.transform().undo().apply())} style={{ position: 'fixed', bottom: 30, right: 30, zIndex: 1 }}>

          </Button>
        )}
        {children}
        {this.state.mode ? <Editor
          {...rest}
          spellcheck={spellcheck || false}
          readOnly={!!readOnly}
          state={this.state.mode}
          onChange={mode => this.setState({ mode })}
          onPaste={this.onPaste}
          onKeyDown={this.onKeyDown}
        /> : <Editor
          {...rest}
          spellcheck={spellcheck || false}
          readOnly={!!readOnly}
          plugins={plugins}
          schema={{ marks, nodes }}
          state={value}
          onChange={onChange}
          onPaste={this.onPaste}
          onKeyDown={this.onKeyDown}
        />}

    );
  }
}
<commit_msg>logs raus<commit_after>import React, { Component, PropTypes } from 'react';
import { withState, withSidebar, withToolbar, withAutoMarkdown, withUniqueId, useBlocks } from './editor-decorators';
import { Button } from 'antd';
import { Editor, Html } from 'slate';
import withBlockTypes from './decorators';
import './style.less';

const options = {
  defaultNode: 'paragraph',
  toolbarMarks: [
    { type: 'bold', icon: 'bold' },
    { type: 'italic', icon: 'italic' },
    { type: 'underlined', icon: 'underline' },
    { type: 'code', icon: 'code' },
  ],
  toolbarTypes: [
    { type: 'heading-one', icon: 'header' },
    { type: 'heading-two', icon: 'header' },
    { type: 'block-quote', icon: 'quote-left' },
    { type: 'numbered-list', icon: 'list-ol' },
    { type: 'bulleted-list', icon: 'list-ul' },
  ],
  toolbarActions: [
    { type: 'link', icon: 'link', onClick: ({ value, onChange }, isActive) => {
      if (isActive) {
        value = value
          .transform()
          .unwrapInline('link')
          .apply();
      } else {
        let href = window.prompt('URL');
        if (href.indexOf('http') !== 0 && href.indexOf('.') !== -1) href = `http://${href}`;
        value = value
          .transform()
          .wrapInline({
            type: 'link',
            data: { href, target: '_blank' },
          })
          .collapseToEnd()
          .apply();
      }
      onChange(value);
    }, isActive: ({ value }) => {
      return value.inlines.some(inline => inline.type === 'link');
    } },
  ],
  sidebarTypes: [],
  nodes: {
    paragraph: ({ children, attributes }) =>
{children}
,
    link: ({ node, attributes, children }) => {children},
    'block-quote': ({ children, attributes }) =>
{children}
,
    'bulleted-list': ({ children, attributes }) =>
{children}
,
    'numbered-list': ({ children, attributes }) =>
{children}
,
    'heading-one': ({ children, attributes }) =>
{children}
,
    'heading-two': ({ children, attributes }) =>
{children}
,
    'heading-three': ({ children, attributes }) =>
{children}
,
    'heading-four': ({ children, attributes }) =>
{children}
,
    'heading-five': ({ children, attributes }) =>
{children}
,
    'heading-six': ({ children, attributes }) =>
{children}
,
    'bulleted-list-item': ({ children, attributes }) =>
{children}
,
    'numbered-list-item': ({ children, attributes }) =>
{children}
,
  },
  marks: {
    bold: ({ children, attributes }) => {children},
    code: ({ children, attributes }) => {children},
    italic: ({ children, attributes }) => {children},
    underlined: ({ children, attributes }) => {children},
  },
  getMarkdownType: (chars) => {
    switch (chars) {
      case '*':
      case '-':
      case '+': return 'bulleted-list-item';
      case '>': return 'block-quote';
      case '#': return 'heading-one';
      case '##': return 'heading-two';
      case '###': return 'heading-three';
      case '####': return 'heading-four';
      case '#####': return 'heading-five';
      case '######': return 'heading-six';
      case '1.': return 'numbered-list-item';
      default: return null;
    }
  },
};

const serializer = new Html({
  rules: [{
    deserialize(el, next) {
      const types = {
        p: 'paragraph',
        li: 'list-item',
        ul: 'bulleted-list',
        ol: 'numbered-list',
        blockquote: 'quote',
        pre: 'code',
        h1: 'heading-one',
        h2: 'heading-two',
        h3: 'heading-three',
        h4: 'heading-four',
        h5: 'heading-five',
        h6: 'heading-six',
      };
      const block = types[el.tagName];
      if (!block) return undefined;
      return {
        kind: 'block',
        type: block,
        nodes: next(el.children),
      };
    },
  }, {
    deserialize(el, next) {
      const marks = {
        strong: 'bold',
        em: 'italic',
        u: 'underline',
        s: 'strikethrough',
        code: 'code',
      };
      const mark = marks[el.tagName];
      if (!mark) return undefined;
      return {
        kind: 'mark',
        type: mark,
        nodes: next(el.children),
      };
    },
  }, {
    // Special case for code blocks, which need to grab the nested children.
    deserialize(el, next) {
      if (el.tagName !== 'pre') return undefined;
      const code = el.children[0];
      const children = code && code.tagName === 'code'
        ? code.children
        : el.children;

      return {
        kind: 'block',
        type: 'code',
        nodes: next(children),
      };
    },
  }, {
    // Special case for links, to grab their href.
    deserialize(el, next) {
      if (el.tagName !== 'a') return undefined;
      return {
        kind: 'inline',
        type: 'link',
        nodes: next(el.children),
        data: {
          href: el.attribs.href,
        },
      };
    },
  }],
});

@withBlockTypes
@withUniqueId()
@withState({ terse: true })
@useBlocks(options)
@withAutoMarkdown(options)
@withToolbar(options)
@withSidebar(options)
export default class SlateEditor extends Component {
  state = {};
  static propTypes = {
    readOnly: PropTypes.bool,
    showUndo: PropTypes.bool,
    children: PropTypes.node,
    value: PropTypes.object,
    onChange: PropTypes.func,
    marks: PropTypes.object,
    nodes: PropTypes.object,
    autoMarkDownKeyDown: PropTypes.func,
    plugins: PropTypes.array,
    className: PropTypes.string,
  }
  static defaultProps = {
    readOnly: false,
  }

  onPaste = (e, data, state) => {
    if (data.type !== 'html') return undefined;
    const { document } = serializer.deserialize(data.html);
    return state
      .transform()
      .insertFragment(document)
      .apply();
  }

  onKeyDown = (e, data, state) => {
    if (e.shiftKey && data.key === 'enter') {
      // shift + enter
      return state
        .transform()
        .insertText('\n')
        .apply();
    } else if (e.metaKey || e.ctrlKey) {
      // cmd/ctrl + ???
      switch (data.key) {
        case 'b':
          return state
            .transform()
            .toggleMark('bold')
            .apply();

        case 'u':
          return state
            .transform()
            .toggleMark('underlined')
            .apply();

        case 'i':
          return state
            .transform()
            .toggleMark('italic')
            .apply();

        default:
          return;
      }
    }

    return;
  }

  render = () => {
    const { children, showUndo, value, onChange, readOnly, marks, nodes, plugins, className, spellcheck, ...rest } = this.props;

    return (

        {value && showUndo && value.hasUndos && (
          <Button type="default" shape="circle" onClick={() => onChange(value.transform().undo().apply())} style={{ position: 'fixed', bottom: 30, right: 30, zIndex: 1 }}>

          </Button>
        )}
        {children}
        {this.state.mode ? <Editor
          {...rest}
          spellcheck={spellcheck || false}
          readOnly={!!readOnly}
          state={this.state.mode}
          onChange={mode => this.setState({ mode })}
          onPaste={this.onPaste}
          onKeyDown={this.onKeyDown}
        /> : <Editor
          {...rest}
          spellcheck={spellcheck || false}
          readOnly={!!readOnly}
          plugins={plugins}
          schema={{ marks, nodes }}
          state={value}
          onChange={onChange}
          onPaste={this.onPaste}
          onKeyDown={this.onKeyDown}
        />}

    );
  }
}
<|endoftext|>


<commit_before><commit_msg>better  documentation<commit_after><|endoftext|>


<commit_before>/* ---------------------------------------------------- +/

## Location ##

Code related to the location template

/+ ---------------------------------------------------- */

//Template.location.created = function () {
//};

//Template.location.helpers({
    //myHelper: function () {
    //}
//});

Template.location.rendered = function () {
    // Fade in the main location wrapper
    $('.location').addClass('animated fadeIn92');

    /**
     * Setup image area
     */
    var width = 1800,
        height = 1080 - 100,
        svg = d3.select(".images").append("svg")
            .attr("class", 'svg-canvas')
            .attr("width", width)
            .attr("height", height);

    /**
     * Setup timeline area
     */
    var time = d3.select(".time").append("svg")
        .attr("class", 'time-canvas')
        .attr("width", width - 30)
        .attr("height", 300);

    /**
     * We have to do our D3 stuff in here because of Meteor's client server
     * stuff. I don't exactly understand...
     *
     * TODO: Research
     */
    Deps.autorun(function () {
        /**
         * Wait for a half-second to let the collections load.
         *
         * TODO: figure out why we need to do this. Before I was doing this,
         * the image counts would get set three times with successively
         * increasing numbers.
         */
        window.setTimeout(function() {
            renderLocation();
        }, 500);

        function renderLocation() {
            /**
             * Render each image
             */
            var imagesCursor = Images.find();
            var imagesCount = imagesCursor.count();
            var images = imagesCursor.fetch();
            images = _.sortBy(images, function(image) {
                return image.date;
            });
            var timelineMargin = 60;
            widthInterval = parseInt((width - timelineMargin) / imagesCount);
            var firstImageWidth = images[0].thumbWidth;
            var lastImageWidth = images[parseInt(imagesCount - 1)].thumbWidth;
            _.each(images, function(image, i) {
                drawImage(svg, image, i, imagesCount, firstImageWidth, lastImageWidth, timelineMargin, widthInterval);
            });

            /**
             * Print the start and end years of the timeline
             */
            // Start
            time.append('svg:text')
                .attr("x", 10)
                .attr("y", 35)
                .attr("class", 'time-label-start')
                .text('1800');

            // End
            time.append('svg:text')
                .attr("x", 1675)
                .attr("y", 35)
                .attr("class", 'time-label-end')
                .text('2000');

            /**
             * Render the timeline handle
             */
            time.append('rect')
                .attr("width", "50")
                .attr("height", "50")
                .attr('class', 'time-handle-rect')
                .attr("x", 0)
                .attr("y", 0);

        };
    });

    /**
     * Render each image
     */
    function drawImage(svg, image, i, imagesCount, firstImageWidth, lastImageWidth, timelineMargin, widthInterval) {
        /**
         * Image properties
         */
        var imageBorder = 5;
        var delay = 2; // Milliseconds to delay the animation per image
        var dur = 500; // Milliseconds for the image animation

        /**
         * Image positioning
         */
        // The x calue for the first image at the left edge of the timeline
        var leftEdge = (timelineMargin / 2) - imageBorder;
        var centerX;
        if (i === 0) {
            centerX = leftEdge;
        }

        // The x value for the last image at the right edge of the timeline
        //
        // The last values account for the shadow offset in the group
        var rightEdge = (timelineMargin / 2) + 1760 - lastImageWidth - (imageBorder * 2) - 5;
        if (i == (imagesCount - 1)){
            centerX = rightEdge;
        }

        // Find the proper interval between images, for the rest of the images
        var rightEdgeCenter = rightEdge + (firstImageWidth / 2);
        var centerInterval = (rightEdgeCenter - leftEdge) / (imagesCount - 2);

        if ((i !== 0) && (i != (imagesCount - 1))) {
            // 15 for white border and shadow
            centerX = leftEdge + (centerInterval * i) - ((image.thumbWidth + 15) / 2);
        }

        // Put the images at the top of the timeline
        var bottomY = (835 - image.thumbHeight);
        var translate = 'translate(' + centerX + ',' + bottomY + ')';

        /**
         * Picture group parent
         */
        var pictureGroup = svg.append("g")
            .attr('class', 'picture-group ' + 'picture-' + i)
            .attr('data-index', i)
            .attr('data-date', image.date)
            .attr("transform", function (){
                return translate;
            });

            /**
            * Picture drop shadow
            */
            var filter = pictureGroup.append("defs")
                .append("filter")
                .attr("id", "blur")
                .append("feGaussianBlur")
                .attr("stdDeviation", 5);
            pictureGroup.append('rect')
                .attr("x", 0)
                .attr("y", 0)
                .style('fill', '#000')
                .attr("width", image.thumbWidth + (imageBorder * 2))
                .attr("height", image.thumbHeight + (imageBorder * 2))
                .attr('class', 'child')
                .attr("filter", "url(#blur)");

            /**
            * Picture white border
            */
            pictureGroup.append('rect')
                // Positions are relative to the group
                .attr("x", (0 - imageBorder))
                .attr("y", (0 - imageBorder))
                .attr("width", image.thumbWidth + (imageBorder * 2))
                .attr("height", image.thumbHeight + (imageBorder * 2))
                .attr('class', 'child location-matte');

            // Image
            pictureGroup.append('image')
                .attr("xlink:href", "/images/thumbnails/" + image._id + ".jpg")
                .attr("data-id", image._id)
                .attr("data-location", image.generalLocationDs)
                //// Simulate scaling form the center of the image
                .attr("width", image.thumbWidth)
                .attr("height", image.thumbHeight)
                .attr('location', image.generalLocationDs)
                .attr('class', 'child');

        /**
         * Picture starting state
         *
         * Scale at 0
         * All child elements with an opacity of 0
         */
        pictureGroup
            .attr("transform", function (){
                transform = translate + ',scale(0)';
                return transform;
            });
        pictureGroup.selectAll('.child')
            .attr("opacity", "0");

        /**
         * Picture - Animate in.
         *
         * Scale and opacity at 1
         */
        pictureGroup
            .transition()
            .delay(i * delay) // Stagger the markers animating in
            .attr("transform", function (){
                transform = translate + ',scale(1)';
                return transform;
            })
            .duration(dur);
        pictureGroup.selectAll('.child')
            .transition()
            .delay(i * delay) // Stagger the markers animating in
            .attr("opacity", "1")
            .duration(dur);

    }
};

Template.location.events({
    // Desired functionality, but disabled for testing
    //'mousemove .container': function (e) {
    'click .container': function (e) {

        /**
         * Setup basic objects and widths
         */
        var timeline = $('.time-canvas');

        // Count elements in our SVG element to get number of images
        var imagesCount = d3.selectAll('.picture-group')[0].length;

        // Pixel interval between images
        var intervalWidth = (timeline.width() / imagesCount);

        // Mouse position relative to the timeline
        var posX = e.pageX - timeline.parent().offset().left;
        var posInterval = Math.floor(posX / intervalWidth);

        /**
         * Position the handle relative to our pointer event
         */
        var handle = d3.select('.time-handle-rect');
        var handleWidth = handle.attr('width');
        var handleWidthHalf = (handleWidth / 2);

        // Prevent the handle from going off the edge of the timeline
        if (posX < handleWidthHalf) {
            posX = (handleWidthHalf);
            posInterval = 1;
        }
        if (posX > 1760 - handleWidthHalf) {
            posX = (1760 - handleWidthHalf);
            posInterval = imagesCount;
        }

        // Set the middle of the handle to the mouse position
        handle.attr('x', (posX - handleWidthHalf));

        /**
         * Scale the images based on mouse position
         *
         * Make the images nearest the cursor the biggest
         */
        d3.selectAll('.picture-group').each( function(d, i){

            /**
             * Determine a scale value based on mouse position
             */
            i = Number(d3.select(this).attr("data-index"));
            console.log('i', i);
            console.log('posInterval');
            var distance = posInterval - i;
            //var distanceScale;
            if (distance === 0) {
                distanceScale = 1;
            }
            else {
                distanceScale = (2 * (1 / Math.abs(posInterval - i)));
            }

            /**
             * Transform the picture group
             */
            var pictureGroup = d3.select(this);
            var imageInGroup = pictureGroup.select('image');
            var imageHeight = imageInGroup
                .attr('height');
            console.log('imageHeight', imageHeight);
            // Get the current transform object
            var t = d3.transform(pictureGroup.attr('transform'));
            // Set the scale value, without changing other attributes
            // This allows the image to stay at its current X,Y position
            // while scaling.
            console.log('image select');
            console.log(imageInGroup);
            t.scale = [distanceScale, distanceScale];
            t.translate = [
                t.translate[0], // Keep the X axis in place
                (835 - (imageHeight * distanceScale))
            ];
            //console.log('t translate Y', t.translate[1]);
            // Turn the transform back into a string for SVG
            transformString = t.toString();
            pictureGroup
                .transition()
                .duration(50)
                .attr("transform", transformString);
        });

        /**
         * Dev mouse position data
         */
        $('.dev-mouse').html(
            'Rel pointer X = ' + posX + '
' +
            'Interval width = ' + intervalWidth + '
' +
            'Pos interval = ' + posInterval + '
'
        );

    },

    'click .back': function(e, instance){
        console.clear();
    },

    'click .delete': function(e, instance){
        var location = this;
        e.preventDefault();
        Meteor.call('removeLocation', location, function(error, result){
            alert('Location deleted.');
            Router.go('/locations');
        });
    }

});
<commit_msg>Better animation of image scaling<commit_after>/* ---------------------------------------------------- +/

## Location ##

Code related to the location template

/+ ---------------------------------------------------- */

//Template.location.created = function () {
//};

//Template.location.helpers({
    //myHelper: function () {
    //}
//});

Template.location.rendered = function () {
    // Fade in the main location wrapper
    $('.location').addClass('animated fadeIn92');

    /**
     * Setup image area
     */
    var width = 1800,
        height = 1080 - 100,
        svg = d3.select(".images").append("svg")
            .attr("class", 'svg-canvas')
            .attr("width", width)
            .attr("height", height);

    /**
     * Setup timeline area
     */
    var time = d3.select(".time").append("svg")
        .attr("class", 'time-canvas')
        .attr("width", width - 30)
        .attr("height", 300);

    /**
     * We have to do our D3 stuff in here because of Meteor's client server
     * stuff. I don't exactly understand...
     *
     * TODO: Research
     */
    Deps.autorun(function () {
        /**
         * Wait for a half-second to let the collections load.
         *
         * TODO: figure out why we need to do this. Before I was doing this,
         * the image counts would get set three times with successively
         * increasing numbers.
         */
        window.setTimeout(function() {
            renderLocation();
        }, 500);

        function renderLocation() {
            /**
             * Render each image
             */
            var imagesCursor = Images.find();
            var imagesCount = imagesCursor.count();
            var images = imagesCursor.fetch();
            images = _.sortBy(images, function(image) {
                return image.date;
            });
            var timelineMargin = 60;
            widthInterval = parseInt((width - timelineMargin) / imagesCount);
            var firstImageWidth = images[0].thumbWidth;
            var lastImageWidth = images[parseInt(imagesCount - 1)].thumbWidth;
            _.each(images, function(image, i) {
                drawImage(svg, image, i, imagesCount, firstImageWidth, lastImageWidth, timelineMargin, widthInterval);
            });

            /**
             * Print the start and end years of the timeline
             */
            // Start
            time.append('svg:text')
                .attr("x", 10)
                .attr("y", 35)
                .attr("class", 'time-label-start')
                .text('1800');

            // End
            time.append('svg:text')
                .attr("x", 1675)
                .attr("y", 35)
                .attr("class", 'time-label-end')
                .text('2000');

            /**
             * Render the timeline handle
             */
            time.append('rect')
                .attr("width", "50")
                .attr("height", "50")
                .attr('class', 'time-handle-rect')
                .attr("x", 0)
                .attr("y", 0);

        };
    });

    /**
     * Render each image
     */
    function drawImage(svg, image, i, imagesCount, firstImageWidth, lastImageWidth, timelineMargin, widthInterval) {
        /**
         * Image properties
         */
        var imageBorder = 5;
        var delay = 2; // Milliseconds to delay the animation per image
        var dur = 500; // Milliseconds for the image animation

        /**
         * Image positioning
         */
        // The x calue for the first image at the left edge of the timeline
        var leftEdge = (timelineMargin / 2) - imageBorder;
        var centerX;
        if (i === 0) {
            centerX = leftEdge;
        }

        // The x value for the last image at the right edge of the timeline
        //
        // The last values account for the shadow offset in the group
        var rightEdge = (timelineMargin / 2) + 1760 - lastImageWidth - (imageBorder * 2) - 5;
        if (i == (imagesCount - 1)){
            centerX = rightEdge;
        }

        // Find the proper interval between images, for the rest of the images
        var rightEdgeCenter = rightEdge + (firstImageWidth / 2);
        var centerInterval = (rightEdgeCenter - leftEdge) / (imagesCount - 2);

        if ((i !== 0) && (i != (imagesCount - 1))) {
            // 15 for white border and shadow
            centerX = leftEdge + (centerInterval * i) - ((image.thumbWidth + 15) / 2);
        }

        // Put the images at the top of the timeline
        var bottomY = (835 - image.thumbHeight);
        var translate = 'translate(' + centerX + ',' + bottomY + ')';

        /**
         * Picture group parent
         */
        var pictureGroup = svg.append("g")
            .attr('class', 'picture-group ' + 'picture-' + i)
            .attr('data-index', i)
            .attr('data-date', image.date)
            .attr("transform", function (){
                return translate;
            });

            /**
            * Picture drop shadow
            */
            var filter = pictureGroup.append("defs")
                .append("filter")
                .attr("id", "blur")
                .append("feGaussianBlur")
                .attr("stdDeviation", 5);
            pictureGroup.append('rect')
                .attr("x", 0)
                .attr("y", 0)
                .style('fill', '#000')
                .attr("width", image.thumbWidth + (imageBorder * 2))
                .attr("height", image.thumbHeight + (imageBorder * 2))
                .attr('class', 'child')
                .attr("filter", "url(#blur)");

            /**
            * Picture white border
            */
            pictureGroup.append('rect')
                // Positions are relative to the group
                .attr("x", (0 - imageBorder))
                .attr("y", (0 - imageBorder))
                .attr("width", image.thumbWidth + (imageBorder * 2))
                .attr("height", image.thumbHeight + (imageBorder * 2))
                .attr('class', 'child location-matte');

            // Image
            pictureGroup.append('image')
                .attr("xlink:href", "/images/thumbnails/" + image._id + ".jpg")
                .attr("data-id", image._id)
                .attr("data-location", image.generalLocationDs)
                //// Simulate scaling form the center of the image
                .attr("width", image.thumbWidth)
                .attr("height", image.thumbHeight)
                .attr('location', image.generalLocationDs)
                .attr('class', 'child');

        /**
         * Picture starting state
         *
         * Scale at 0
         * All child elements with an opacity of 0
         */
        pictureGroup
            .attr("transform", function (){
                transform = translate + ',scale(0)';
                return transform;
            });
        pictureGroup.selectAll('.child')
            .attr("opacity", "0");

        /**
         * Picture - Animate in.
         *
         * Scale and opacity at 1
         */
        pictureGroup
            .transition()
            .delay(i * delay) // Stagger the markers animating in
            .attr("transform", function (){
                transform = translate + ',scale(1)';
                return transform;
            })
            .duration(dur);
        pictureGroup.selectAll('.child')
            .transition()
            .delay(i * delay) // Stagger the markers animating in
            .attr("opacity", "1")
            .duration(dur);

    }
};

Template.location.events({
    // Desired functionality, but disabled for testing
    'mousemove .container': function (e) {
    //'click .container': function (e) {

        /**
         * Setup basic objects and widths
         */
        var timeline = $('.time-canvas');

        // Count elements in our SVG element to get number of images
        var imagesCount = d3.selectAll('.picture-group')[0].length;

        // Pixel interval between images
        var intervalWidth = (timeline.width() / imagesCount);

        // Mouse position relative to the timeline
        var posX = e.pageX - timeline.parent().offset().left;
        var posInterval = Math.floor(posX / intervalWidth);

        /**
         * Position the handle relative to our pointer event
         */
        var handle = d3.select('.time-handle-rect');
        var handleWidth = handle.attr('width');
        var handleWidthHalf = (handleWidth / 2);

        // Prevent the handle from going off the edge of the timeline
        if (posX < handleWidthHalf) {
            posX = (handleWidthHalf);
            posInterval = 1;
        }
        if (posX > 1760 - handleWidthHalf) {
            posX = (1760 - handleWidthHalf);
            posInterval = imagesCount;
        }

        // Set the middle of the handle to the mouse position
        handle.attr('x', (posX - handleWidthHalf));

        /**
         * Scale the images based on mouse position
         *
         * Make the images nearest the cursor the biggest
         */
        d3.selectAll('.picture-group').each( function(d, i){

            /**
             * Determine a scale value based on mouse position
             */
            i = Number(d3.select(this).attr("data-index"));
            var distance = posInterval - i;
            //var distanceScale;
            if (distance === 0) {
                distanceScale = 1;
            }
            else {
                var minVal = 0.3;
                var maxVal = 0.7;
                distanceScale = ( minVal + (maxVal - minVal) * (1 / (Math.abs(posInterval - i))));
            }

            /**
             * Transform the picture group
             */
            var pictureGroup = d3.select(this);
            var imageInGroup = pictureGroup.select('image');
            var imageHeight = imageInGroup
                .attr('height');
            // Get the current transform object
            var t = d3.transform(pictureGroup.attr('transform'));
            // Set the scale value, without changing other attributes
            // This allows the image to stay at its current X,Y position
            // while scaling.
            t.scale = [distanceScale, distanceScale];
            var translateY;
            if (posInterval == i) {
                translateY = (835 - (imageHeight * distanceScale)) - 50;
            }
            else {
                translateY = (835 - (imageHeight * distanceScale));
            }
            t.translate = [
                t.translate[0], // Keep the X axis in placename
                translateY
            ];
            //console.log('t translate Y', t.translate[1]);
            // Turn the transform back into a string for SVG
            transformString = t.toString();
            pictureGroup
                .transition()
                .duration(100)
                .ease('circle-out')
                .attr("transform", transformString);
        });
        /**
         * Dev mouse position data
         */
        $('.dev-mouse').html(
            'Rel pointer X = ' + posX + '
' +
            'Interval width = ' + intervalWidth + '
' +
            'Pos interval = ' + posInterval + '
'
        );

    },

    'click .back': function(e, instance){
        console.clear();
    },

    'click .delete': function(e, instance){
        var location = this;
        e.preventDefault();
        Meteor.call('removeLocation', location, function(error, result){
            alert('Location deleted.');
            Router.go('/locations');
        });
    }

});
<|endoftext|>


<commit_before>require('mongoose');
// eslint-disable-next-line no-unused-vars
const { info, error } = require('../src/logger');

const { connect, close } = require('../src/utils/database');

require('../src/services/homework/model');

module.exports = {
	up: async function up() {
		await connect();
		// ////////////////////////////////////////////////////
		// Make changes to the database here.
		// Hint: Access models via this('modelName'), not an imported model to have
		// access to the correct database connection. Otherwise Mongoose calls never return.
		info('update homework indexes...');
		this('homework').syncIndexes();
		info('updated homework indexes successfully');

		info('update submission indexes...');
		this('submission').syncIndexes();
		info('updated submission indexes successfully');

		info('update courses indexes...');
		this('courses').syncIndexes();
		info('updated courses indexes successfully');
		// ////////////////////////////////////////////////////
		await close();
	},
};
<commit_msg>fix migration<commit_after>require('mongoose');
// eslint-disable-next-line no-unused-vars
const { info, error } = require('../src/logger');

const { connect, close } = require('../src/utils/database');

require('../src/services/homework/model');
const { courseModel } = require('../src/services/user-group/model');

module.exports = {
	up: async function up() {
		await connect();
		// ////////////////////////////////////////////////////
		// Make changes to the database here.
		// Hint: Access models via this('modelName'), not an imported model to have
		// access to the correct database connection. Otherwise Mongoose calls never return.
		info('update homework indexes...');
		await this('homework').syncIndexes();
		info('updated homework indexes successfully');

		info('update submission indexes...');
		await this('submission').syncIndexes();
		info('updated submission indexes successfully');

		info('update courses indexes...');
		await courseModel.syncIndexes();
		info('updated courses indexes successfully');
		// ////////////////////////////////////////////////////
		await close();
	},
};
<|endoftext|>


<commit_before>angular.module("mirmindr")
.controller("tasksCtrl",function($scope,$mdToast,$mdDialog,$firebaseArray){
  var ref = new Firebase("https://mirmindr.firebaseio.com");
  var authData = ref.getAuth();
  function setUserRef(uid){
    $scope.userRef = ref.child("users").child(uid);
    $scope.authenticated = true;
    $scope.tasks = $firebaseArray($scope.userRef.child("tasks"));
    $scope.subjects = $firebaseArray($scope.userRef.child("subjects"));
  };
  if (authData) {
    console.log("Authenticated");
    setUserRef(authData.uid);
  }
  $scope.user = {
    email: "",
    password: ""
  };

  $scope.toggleSubjects = function() {
    // If editingSubjects is true, make it false. Or vice versa
  };

  $scope.toggleAddingTask = function() {
    // If addingTask is true, make it false. Or vice versa
  };

  $scope.deleteTask = function(task) {
    // Remove task from $scope.tasks
  };

  $scope.toggleDone = function(task) {
    // Mark task as done
    // Alert with a toast
    // Save the tasks array
  };

  $scope.isOverdue = function(task) {
    // Return true if the task's dueDate is older than now.
  }

  $scope.newTask = {};
  chrome.identity.getProfileUserInfo(function(data){
    if(data.email) {
      console.log("Email found");
      $scope.user.email = data.email;
      $scope.$apply();
    }
  });

  $scope.showActionToast = function(msg) {
    var toast = $mdToast.simple()
          .textContent(msg)
          .action('OK')
          .highlightAction(false)
          .position("top");
    $mdToast.show(toast);
  };

  $scope.login = function(form) {
    if (form.$valid) {
      ref.authWithPassword({
        email: $scope.user.email,
        password: $scope.user.password
      }, function(error, authData) {
        if(error) {
          $scope.showActionToast(error.toString());
        } else {
          setUserRef(authData.uid);
          $scope.$apply();
        }
      });
    }
  }

  $scope.addTask = function(form) {
    if(form.$valid) {
      console.log($scope.newTask);
      $scope.newTask.dueDate = $scope.newTask.dueDate.getTime();
      $scope.newTask.done = false;
      $scope.tasks.$add($scope.newTask);
      setTasksBySubject();
      $scope.newTask = {};
    } else {
      $scope.showActionToast("Missing something?")
    }
  }
});<commit_msg>Erased app.js<commit_after><|endoftext|>


<commit_before>function AllNedTools() {
   NedTool("Calculator", "nedhome.ml/tools/calculator", "www.free-icons-download.net/images/calculator-logo-73002.png");

   NedTool("Calander", "nedhome.ml/tools/calendar", "goo.gl/hGkTvi")

   NedTool("Clock", "nedhome.ml/tools/clock", "goo.gl/V4Zwrh");

   NedTool("$ Converter", "nedhome.ml/tools/moneyconverter", "goo.gl/g0vTnM");

   NedGames();
}
function AllOutherSites() {
   OutherSite("SUSEStudio", "susestudio.com", "goo.gl/64ozgA");

   OutherSite("Weebly", "weebly.com", "upload.wikimedia.org/wikipedia/commons/4/43/Weebly_logo_2013.png");

   OutherSite("Youtube", "youtube.com", "t2.gstatic.com/images?q=tbn:ANd9GcQDfL7X2SHlu_A9qhVi4HhJFMFqkX4VBAZL9LS81bJm_RatOoM71KJX9nv3");

   OutherSite("Linux", "linux.com", "upload.wikimedia.org/wikipedia/commons/thumb/3/35/Tux.svg/1000px-Tux.svg.png");

   OutherSite("CCleaner", "ccleaner.com", "upload.wikimedia.org/wikipedia/en/4/4a/CCleaner_logo_2013.png");
}
function AllSocialMedia() {
   SocialMedia("Facebook", "facebook.com", "upload.wikimedia.org/wikipedia/commons/thumb/c/c2/F_icon.svg/2000px-F_icon.svg.png");

   SocialMedia("Twitter", "twitter.com", "upload.wikimedia.org/wikipedia/en/thumb/9/9f/Twitter_bird_logo_2012.svg/220px-Twitter_bird_logo_2012.svg.png");
}
function AllSites() {
   AllNedTools();

   NewLine("br");

   AllOutherSites();

   NewLine("br");

   AllSocialMedia();
}
<commit_msg>Update AllSites.js<commit_after>function AllNedTools() {
   NedTool("Calculator", "nedhome.ml/tools/calculator", "www.free-icons-download.net/images/calculator-logo-73002.png");

   NedTool("Calander", "nedhome.ml/tools/calendar", "goo.gl/hGkTvi")

   NedTool("Clock", "nedhome.ml/tools/clock", "goo.gl/V4Zwrh");

   NedTool("$ Converter", "nedhome.ml/tools/moneyconverter", "goo.gl/g0vTnM");

   NedGames();
}
function AllOutherSites() {
   OutherSite("SUSEStudio", "susestudio.com", "goo.gl/64ozgA");

   OutherSite("Weebly", "weebly.com", "upload.wikimedia.org/wikipedia/commons/4/43/Weebly_logo_2013.png");

   OutherSite("Youtube", "youtube.com", "t2.gstatic.com/images?q=tbn:ANd9GcQDfL7X2SHlu_A9qhVi4HhJFMFqkX4VBAZL9LS81bJm_RatOoM71KJX9nv3");

   OutherSite("Linux", "linux.com", "upload.wikimedia.org/wikipedia/commons/thumb/3/35/Tux.svg/1000px-Tux.svg.png");

   OutherSite("CCleaner", "ccleaner.com", "upload.wikimedia.org/wikipedia/en/4/4a/CCleaner_logo_2013.png");

   OutherSite("Microsoft", "microsoft.com", "img05.deviantart.net/e1f7/i/2011/251/e/4/microsoft_windows_logo_3000px_by_davidm147-d3hax3m.png");
}
function AllSocialMedia() {
   SocialMedia("Facebook", "facebook.com", "upload.wikimedia.org/wikipedia/commons/thumb/c/c2/F_icon.svg/2000px-F_icon.svg.png");

   SocialMedia("Twitter", "twitter.com", "upload.wikimedia.org/wikipedia/en/thumb/9/9f/Twitter_bird_logo_2012.svg/220px-Twitter_bird_logo_2012.svg.png");
}
function AllSites() {
   AllNedTools();

   NewLine("br");

   AllOutherSites();

   NewLine("br");

   AllSocialMedia();
}
<|endoftext|>


<commit_before>var path = require('path')
var express = require('express')
var webpack = require('webpack')
var config = require('../config')
var proxyMiddleware = require('http-proxy-middleware')
var webpackConfig = process.env.NODE_ENV === 'testing'
  ? require('./webpack.prod.conf')
  : require('./webpack.dev.conf')

// default port where dev server listens for incoming traffic
var port = process.env.PORT || config.dev.port
// Define HTTP proxies to your custom API backend
// https://github.com/chimurai/http-proxy-middleware
var proxyTable = config.dev.proxyTable

var app = express()
var compiler = webpack(webpackConfig)

var devMiddleware = require('webpack-dev-middleware')(compiler, {
  publicPath: webpackConfig.output.publicPath,
  stats: {
    colors: true,
    chunks: false
  }
})

var hotMiddleware = require('webpack-hot-middleware')(compiler)
// force page reload when html-webpack-plugin template changes
compiler.plugin('compilation', function (compilation) {
  compilation.plugin('html-webpack-plugin-after-emit', function (data, cb) {
    hotMiddleware.publish({ action: 'reload' })
    cb()
  })
})

// proxy api requests
Object.keys(proxyTable).forEach(function (context) {
  var options = proxyTable[context]
  if (typeof options === 'string') {
    options = {
      target: options,
      ws: true
    }
  }
  app.use(proxyMiddleware(context, options))
})

// handle fallback for HTML5 history API
app.use(require('connect-history-api-fallback')())

// serve webpack bundle output
app.use(devMiddleware)

// enable hot-reload and state-preserving
// compilation error display
app.use(hotMiddleware)

// serve pure static assets
var staticPath = path.posix.join(config.build.assetsPublicPath, config.build.assetsSubDirectory)
app.use(staticPath, express.static('./static'))

module.exports = app.listen(port, function (err) {
  if (err) {
    console.log(err)
    return
  }
  console.log('Listening at http://localhost:' + port + '\n')
})
<commit_msg>修复静态目录服务路径错误的问题<commit_after>var path = require('path')
var express = require('express')
var webpack = require('webpack')
var config = require('../config')
var proxyMiddleware = require('http-proxy-middleware')
var webpackConfig = process.env.NODE_ENV === 'testing'
  ? require('./webpack.prod.conf')
  : require('./webpack.dev.conf')

// default port where dev server listens for incoming traffic
var port = process.env.PORT || config.dev.port
// Define HTTP proxies to your custom API backend
// https://github.com/chimurai/http-proxy-middleware
var proxyTable = config.dev.proxyTable

var app = express()
var compiler = webpack(webpackConfig)

var devMiddleware = require('webpack-dev-middleware')(compiler, {
  publicPath: webpackConfig.output.publicPath,
  stats: {
    colors: true,
    chunks: false
  }
})

var hotMiddleware = require('webpack-hot-middleware')(compiler)
// force page reload when html-webpack-plugin template changes
compiler.plugin('compilation', function (compilation) {
  compilation.plugin('html-webpack-plugin-after-emit', function (data, cb) {
    hotMiddleware.publish({ action: 'reload' })
    cb()
  })
})

// proxy api requests
Object.keys(proxyTable).forEach(function (context) {
  var options = proxyTable[context]
  if (typeof options === 'string') {
    options = {
      target: options,
      ws: true
    }
  }
  app.use(proxyMiddleware(context, options))
})

// handle fallback for HTML5 history API
app.use(require('connect-history-api-fallback')())

// serve webpack bundle output
app.use(devMiddleware)

// enable hot-reload and state-preserving
// compilation error display
app.use(hotMiddleware)

// serve pure static assets
var staticPath = path.posix.join(config.build.assetsPublicPath, config.build.assetsSubDirectory)
app.use(staticPath, express.static(path.join(__dirname, '..', 'wwwroot', 'static')))

module.exports = app.listen(port, function (err) {
  if (err) {
    console.log(err)
    return
  }
  console.log('Listening at http://localhost:' + port + '\n')
})
<|endoftext|>