<commit_before>/*jshint esversion: 6 */
import React, { PropTypes, Component } from 'react';

import Wrapper from './Wrapper.js';
import IdeasList from '../IdeasList';

export default class InputForm extends React.Component {
  constructor(){
    super();
    this.state = {
      titleString: "",
      bodyString: ""
    };
  }

  setIdeaState(key, value) {
    this.setState({
      [key]: value
    });
  }

  createIdea(e) {
    e.preventDefault();
    const ideaObject = {
      title: this.state.titleString,
      body: this.state.bodyString,
      quality: 'swill',
      id: Date.now()
    };
    this.props.addIdea(ideaObject);
  }

  render(){
    return (

        <Wrapper>

ideabox

          <form name="ideaForm">
            <input type="text" id="idea-title"
            placeholder=" title" onChange={ (e) => this.setIdeaState('titleString', e.target.value) } />

            <input type="text" id="idea-body"
            placeholder=" body" onChange={(e) => this.setIdeaState('bodyString', e.target.value)}/>

            <button className="submit-btn"
            onClick={(e) => this.createIdea(e)}>
            Save
            </button>
          </form>
        </Wrapper>
        <IdeasList ideas={ this.props.ideas } removeIdea={ this.props.removeIdea }
        updateIdea={ this.props.updateIdea } />

    );
  }
}

InputForm.PropTypes = {
  addIdea: React.PropTypes.func,
  removeIdea: React.PropTypes.func,
  updateIdea: React.PropTypes.func,
}
<commit_msg>add clearFields to inputForm component<commit_after>/*jshint esversion: 6 */
import React, { PropTypes, Component } from 'react';

import Wrapper from './Wrapper.js';
import IdeasList from '../IdeasList';

export default class InputForm extends React.Component {
  constructor(){
    super();
    this.state = {
      titleString: "",
      bodyString: ""
    };
  }

  setIdeaState(key, value) {
    this.setState({
      [key]: value
    });
  }

  createIdea(e) {
    e.preventDefault();
    const ideaObject = {
      title: this.state.titleString,
      body: this.state.bodyString,
      quality: 'swill',
      id: Date.now()
    };
    this.props.addIdea(ideaObject);
    this.clearFields();
  }

  clearFields(){
    this.setState({titleString: '', bodyString: ''});
  }

  render(){
    return (

        <Wrapper>

ideabox

          <form name="ideaForm">
            <input type="text" id="idea-title"
            value={this.state.titleString}
            placeholder=" title" onChange={ (e) => this.setIdeaState('titleString', e.target.value) } />

            <input type="text" id="idea-body"
            placeholder=" body" value={this.state.bodyString} onChange={(e) => this.setIdeaState('bodyString', e.target.value)}/>

            <button className="submit-btn"
            onClick={(e) => this.createIdea(e)}>
            Save
            </button>
          </form>
        </Wrapper>
        <IdeasList ideas={ this.props.ideas } removeIdea={ this.props.removeIdea }
        updateIdea={ this.props.updateIdea } />

    );
  }
}

InputForm.PropTypes = {
  addIdea: React.PropTypes.func,
  removeIdea: React.PropTypes.func,
  updateIdea: React.PropTypes.func,
}
<|endoftext|>


<commit_before>import React, { Component } from 'react';
import { connect } from 'react-redux';

import { fetchAccounts } from 'actions/Accounts/AccountActions';
import { fetchRecentlyViewed, fileUploaded } from 'actions/App/AppActions';
import AccountList from 'components/Accounts/AccountList/AccountList';
import RecentlyViewedList from 'components/App/RecentlyViewed/RecentlyViewedList';
import Calendar from 'rc-calendar';
import 'rc-calendar/assets/index.css';

import GregorianCalendar from 'gregorian-calendar';
const date = new GregorianCalendar(); // defaults to en-us
date.setTime(+new Date('2015-09-14 13:00:00'));
//console.log(date.getDayOfWeek());

import Dropzone from 'react-dropzone';

export default class HomePage extends Component {
  componentDidMount() {
    const { dispatch } = this.props;
    if (this.props.Account.rows.length === 0) {
      dispatch(fetchAccounts());
    }

    dispatch(fetchRecentlyViewed());
  }

  render() {
    const ReactCSSTransitionGroup = require('react-addons-css-transition-group');

    let filesMarkup;
    if (_.isEmpty(this.props.App.files) === false) {
      filesMarkup = this.props.App.files.map((file, index) =>

      );
    } else {
      filesMarkup = '';
    }

    return (

        <ReactCSSTransitionGroup transitionName="fadeIn" transitionAppearTimeout={300} transitionEnterTimeout={300} transitionLeaveTimeout={300}>

Dashboard

Accounts

          <AccountList rows={this.props.Account.rows}
                       isFetching={this.props.Account.isFetching}/>
          <RecentlyViewedList recentlyViewedRows={this.props.App.recentlyViewed}/>
          <Calendar defaultValue={date} showToday={true} onSelect={this.handleDateSelect}/>
          <Dropzone onDrop={(files) => this.handleFileUpload(files) } multiple={false} style={
							{
								width: '100px',
								height: '100px',
								borderWidth: '2px',
								borderColor: '#666',
								borderStyle: 'dashed',
								borderRadius: '5px'
							}
						}>

Try dropping some a file here, or click to select a file to upload.

          </Dropzone>
          {filesMarkup}
        </ReactCSSTransitionGroup>

    );
  }

  handleDateSelect(gCal) {
    //console.log(new Date(gCal.getTime() ) );
  }

  handleFileUpload(files) {
    const { dispatch } = this.props;
    dispatch(fileUploaded(files));
  }
}

HomePage.propTypes = {};

// Which props do we want to inject, given the global state?
// Note: use https://github.com/faassen/reselect for better performance.
function select(state) {
  return {
    Account: state.Account,
    App: state.App
  };
}

// Wrap the component to inject dispatch and state into it
export default connect(select)(HomePage);
<commit_msg>Delete HomePage_copy.js this file wasn't supposed to be commited to the repo.<commit_after><|endoftext|>


<commit_before>/*
 * micro-markdown.js
 * markdown in under 5kb
 *
 * Copyright 2014, Simon Waldherr - http://simon.waldherr.eu/
 * Released under the MIT Licence
 * http://simon.waldherr.eu/license/mit/
 *
 * Github:  https://github.com/simonwaldherr/micromarkdown.js/
 * Version: 0.3.0
 */

var micromarkdown = {
	regexobject: {
		headline: /^(\#{1,6})([^\#\n]+)$/m,
		code: /\s\`\`\`\n?([^`]+)\`\`\`/g,
		hr: /^(?:([\*\-_] ?)+)\1\1$/gm,
		lists: /^((\s*((\*|\-)|\d(\.|\))) [^\n]+)\n)+/gm,
		bolditalic: /(?:([\*_~]{1,3}))([^\*_~\n]+[^\*_~\s])\1/g,
		links: /!?\[([^\]<>]+)\]\(([^ \)<>]+)( "[^\(\)\"]+")?\)/g,
		reflinks: /\[([^\]]+)\]\[([^\]]+)\]/g,
		smlinks: /\@([a-z0-9]{3,})\@(t|gh|fb|gp|adn)/gi,
		mail: /<(([a-z0-9_\-\.])+\@([a-z0-9_\-\.])+\.([a-z]{2,7}))>/gmi,
		tables: /\n(([^|\n]+ *\| *)+([^|\n]+\n))((:?\-+:?\|)+(:?\-+:?)*\n)((([^|\n]+ *\| *)+([^|\n]+)\n)+)/g,
		include: /[\[<]include (\S+) from (https?:\/\/[a-z0-9\.\-]+\.[a-z]{2,9}[a-z0-9\.\-\?\&\/]+)[\]>]/gi,
		url: /<([a-zA-Z0-9@:%_\+.~#?&\/\/=]{2,256}\.[a-z]{2,4}\b(\/[\-a-zA-Z0-9@:%_\+.~#?&\/\/=]*)?)>/g
	},

	codeHandler: function (stra, str) {
		return str.replace(stra[0], '\n' + micromarkdown.htmlEncode(stra[1]).replace(/\n/gm, '
').replace(/\ /gm, ' ') + '\n');
	},

	headlinesHandler: function (stra, str) {
		var count = stra[1].length;
		return str.replace(stra[0], '<h' + count + '>' + stra[2] + '</h' + count + '>' + '\n');
	},

	linksHandler: function (stra, str, strict) {
		if (stra[0].substr(0, 1) === '!') {
			str = str.replace(stra[0], '\n');
		} else {
			str = str.replace(stra[0], '' + stra[1] + '\n');
		}
		return str;
	},
	mailHandler: function (stra, str) {
		return str.replace(stra[0], '' + stra[1] + '');
	},
	horizontalLineHandler: function (stra, str) {
		return str.replace(stra[0], '\n
\n');
	},
	urlHandler: function (stra, str, strict) {
		var repString = stra[1];
		if (repString.indexOf('://') === -1) {
			repString = 'http://' + repString;
		}
		return str.replace(stra[0], '' + repString.replace(/(https:\/\/|http:\/\/|mailto:|ftp:\/\/)/gmi, '') + '');
	},
	refLinksHandler: function (str, stra, helper, strict) {
		return str.replace(stra[0], '' + stra[1] + '');
	},
	specialLinks: function (stra, str, strict) {
		var repstr = "";
		switch (stra[2]) {
			case 't':
				repstr = 'https://twitter.com/' + stra[1];
				break;
			case 'gh':
				repstr = 'https://github.com/' + stra[1];
				break;
			case 'fb':
				repstr = 'https://www.facebook.com/' + stra[1];
				break;
			case 'gp':
				repstr = 'https://plus.google.com/+' + stra[1];
				break;
		}
		return str.replace(stra[0], '' + stra[1] + '');
	},
	boldItalicHandler: function (stra, str) {
		var repstr = [];
		if (stra[1] === '~~') {
			str = str.replace(stra[0], '' + stra[2] + '');
		} else {
			switch (stra[1].length) {
				case 1:
					repstr = ['', ''];
					break;
				case 2:
					repstr = ['', ''];
					break;
				case 3:
					repstr = ['', ''];
					break;
			}
			str = str.replace(stra[0], repstr[0] + stra[2] + repstr[1]);
		}
		return str;
	},
	tableHandlerHelper: function (helper, calign, strict) {
		var i;
		for (i = 0; i < helper.length; i++) {
			if (calign.length <= i) {
				calign.push(0);
			} else if ((calign[i].trimRight().slice(-1) === ':') && (strict !== true)) {
				if (calign[i][0] === ':') {
					calign[i] = 3;
				} else {
					calign[i] = 2;
				}
			} else if (strict !== true) {
				if (calign[i][0] === ':') {
					calign[i] = 1;
				} else {
					calign[i] = 0;
				}
			} else {
				calign[i] = 0;
			}
		}
	},
	tablesHandler: function (stra, str, strict) {
		var repstr, cel, helper, calign, helper1, helper2, i, j;

		repstr = '

';
		helper = stra[1].split('|');
		calign = stra[4].split('|');
		this.tableHandlerHelper(helper, calign, strict);
		cel = ['', '', '', ''];
		for (i = 0; i < helper.length; i++) {
			repstr += cel[calign[i]] + helper[i].trim() + '	';
		}
		repstr += '
';
		cel = ['', '', '', ''];
		helper1 = stra[7].split('\n');
		for (i = 0; i < helper1.length; i++) {
			helper2 = helper1[i].split('|');
			if (helper2[0].length !== 0) {
				while (calign.length < helper2.length) {
					calign.push(0);
				}
				repstr += '
';
				for (j = 0; j < helper2.length; j++) {
					repstr += cel[calign[j]] + helper2[j].trim() + '	';
				}
				repstr += '
' + '\n';
			}
		}
		repstr += '
';
		return str.replace(stra[0], repstr);
	},

	listHanderStart: function (stra, repstr) {
		if ((stra[0].trim().substr(0, 1) === '*') || (stra[0].trim().substr(0, 1) === '-')) {
			repstr = '
';
		} else {
			repstr = '
';
		}
		return repstr;
	},

	listHandler: function (stra, str) {
		var helper, helper1, status, indent, line, nstatus, repstr, i, casca = 0;
		repstr = this.listHanderStart(stra, repstr);
		helper = stra[0].split('\n');
		helper1 = [];
		status = 0;
		indent = false;
		for (i = 0; i < helper.length; i++) {
			if ((line = /^((\s*)((\*|\-)|\d(\.|\))) ([^\n]+))/.exec(helper[i])) !== null) {
				if ((line[2] === undefined) || (line[2].length === 0)) {
					nstatus = 0;
				} else {
					if (indent === false) {
						indent = line[2].replace(/\t/, '    ').length;
					}
					nstatus = Math.round(line[2].replace(/\t/, '    ').length / indent);
				}
				while (status > nstatus) {
					repstr += helper1.pop();
					status--;
					casca--;
				}
				while (status < nstatus) {
					if ((line[0].trim().substr(0, 1) === '*') || (line[0].trim().substr(0, 1) === '-')) {
						repstr += '
';
						helper1.push('
');
					} else {
						repstr += '
';
						helper1.push('
');
					}
					status++;
					casca++;
				}
				repstr += '
' + line[6] + '
' + '\n';
			}
		}
		while (casca > 0) {
			repstr += '
';
			casca--;
		}
		if ((stra[0].trim().substr(0, 1) === '*') || (stra[0].trim().substr(0, 1) === '-')) {
			repstr += '
';
		} else {
			repstr += '
';
		}
		return str.replace(stra[0], repstr + '\n');
	},

	parse: function (str, strict) {
		var helper, helper1, stra, trashgc = [], i;
		str = '\n' + str + '\n';

		var regexobject = micromarkdown.regexobject;
		if (strict !== true) {
			regexobject.lists = /^((\s*(\*|\d\.) [^\n]+)\n)+/gm;
		}

		while ((stra = regexobject.code.exec(str)) !== null) {
			str = this.codeHandler(stra, str);
		}

		while ((stra = regexobject.headline.exec(str)) !== null) {
			str = this.headlinesHandler(stra, str);
		}

		while ((stra = regexobject.lists.exec(str)) !== null) {
			str = this.listHandler(stra, str);
		}

		while ((stra = regexobject.tables.exec(str)) !== null) {
			str = this.tablesHandler(stra, str, strict);
		}

		for (i = 0; i < 3; i++) {
			while ((stra = regexobject.bolditalic.exec(str)) !== null) {
				str = this.boldItalicHandler(stra, str);
			}
		}

		while ((stra = regexobject.links.exec(str)) !== null) {
			str = this.linksHandler(stra, str, strict);
		}

		while ((stra = regexobject.mail.exec(str)) !== null) {
			str = this.mailHandler(stra, str);
		}

		while ((stra = regexobject.url.exec(str)) !== null) {
			str = this.urlHandler(stra, str, strict);
		}

		while ((stra = regexobject.reflinks.exec(str)) !== null) {
			helper1 = new RegExp('\\[' + stra[2] + '\\]: ?([^ \n]+)', "gi");
			if ((helper = helper1.exec(str)) !== null) {
				str = this.refLinksHandler(str, stra, helper, strict);
				trashgc.push(helper[0]);
			}
		}

		for (i = 0; i < trashgc.length; i++) {
			str = str.replace(trashgc[i], '');
		}
		while ((stra = regexobject.smlinks.exec(str)) !== null) {
			str = this.specialLinks(stra, str, strict);
		}

		while ((stra = regexobject.hr.exec(str)) !== null) {
			str = this.horizontalLineHandler(stra, str);
		}

		return str.replace(/ {2,}[\n]{1,}/gmi, '

');
	},

	htmlEncode: function (str) {
		var div = document.createElement('div');
		div.appendChild(document.createTextNode(str));
		return div.innerHTML;
	},

	mmdCSSclass: function (str, strict) {
		var urlTemp;
		if ((str.indexOf('/') !== -1) && (strict !== true)) {
			urlTemp = str.split('/');
			if (urlTemp[1].length === 0) {
				urlTemp = urlTemp[2].split('.');
			} else {
				urlTemp = urlTemp[0].split('.');
			}
			return 'class="mmd_' + urlTemp[urlTemp.length - 2].replace(/[^\w\d]/g, '') + urlTemp[urlTemp.length - 1] + '" ';
		}
		return '';
	}
};

EchoesWorks.md = micromarkdown;<commit_msg>extract list handler end<commit_after>/*
 * micro-markdown.js
 * markdown in under 5kb
 *
 * Copyright 2014, Simon Waldherr - http://simon.waldherr.eu/
 * Released under the MIT Licence
 * http://simon.waldherr.eu/license/mit/
 *
 * Github:  https://github.com/simonwaldherr/micromarkdown.js/
 * Version: 0.3.0
 */

var micromarkdown = {
	regexobject: {
		headline: /^(\#{1,6})([^\#\n]+)$/m,
		code: /\s\`\`\`\n?([^`]+)\`\`\`/g,
		hr: /^(?:([\*\-_] ?)+)\1\1$/gm,
		lists: /^((\s*((\*|\-)|\d(\.|\))) [^\n]+)\n)+/gm,
		bolditalic: /(?:([\*_~]{1,3}))([^\*_~\n]+[^\*_~\s])\1/g,
		links: /!?\[([^\]<>]+)\]\(([^ \)<>]+)( "[^\(\)\"]+")?\)/g,
		reflinks: /\[([^\]]+)\]\[([^\]]+)\]/g,
		smlinks: /\@([a-z0-9]{3,})\@(t|gh|fb|gp|adn)/gi,
		mail: /<(([a-z0-9_\-\.])+\@([a-z0-9_\-\.])+\.([a-z]{2,7}))>/gmi,
		tables: /\n(([^|\n]+ *\| *)+([^|\n]+\n))((:?\-+:?\|)+(:?\-+:?)*\n)((([^|\n]+ *\| *)+([^|\n]+)\n)+)/g,
		include: /[\[<]include (\S+) from (https?:\/\/[a-z0-9\.\-]+\.[a-z]{2,9}[a-z0-9\.\-\?\&\/]+)[\]>]/gi,
		url: /<([a-zA-Z0-9@:%_\+.~#?&\/\/=]{2,256}\.[a-z]{2,4}\b(\/[\-a-zA-Z0-9@:%_\+.~#?&\/\/=]*)?)>/g
	},

	codeHandler: function (stra, str) {
		return str.replace(stra[0], '\n' + micromarkdown.htmlEncode(stra[1]).replace(/\n/gm, '
').replace(/\ /gm, ' ') + '\n');
	},

	headlinesHandler: function (stra, str) {
		var count = stra[1].length;
		return str.replace(stra[0], '<h' + count + '>' + stra[2] + '</h' + count + '>' + '\n');
	},

	linksHandler: function (stra, str, strict) {
		if (stra[0].substr(0, 1) === '!') {
			str = str.replace(stra[0], '\n');
		} else {
			str = str.replace(stra[0], '' + stra[1] + '\n');
		}
		return str;
	},
	mailHandler: function (stra, str) {
		return str.replace(stra[0], '' + stra[1] + '');
	},
	horizontalLineHandler: function (stra, str) {
		return str.replace(stra[0], '\n
\n');
	},
	urlHandler: function (stra, str, strict) {
		var repString = stra[1];
		if (repString.indexOf('://') === -1) {
			repString = 'http://' + repString;
		}
		return str.replace(stra[0], '' + repString.replace(/(https:\/\/|http:\/\/|mailto:|ftp:\/\/)/gmi, '') + '');
	},
	refLinksHandler: function (str, stra, helper, strict) {
		return str.replace(stra[0], '' + stra[1] + '');
	},
	specialLinks: function (stra, str, strict) {
		var repstr = "";
		switch (stra[2]) {
			case 't':
				repstr = 'https://twitter.com/' + stra[1];
				break;
			case 'gh':
				repstr = 'https://github.com/' + stra[1];
				break;
			case 'fb':
				repstr = 'https://www.facebook.com/' + stra[1];
				break;
			case 'gp':
				repstr = 'https://plus.google.com/+' + stra[1];
				break;
		}
		return str.replace(stra[0], '' + stra[1] + '');
	},
	boldItalicHandler: function (stra, str) {
		var repstr = [];
		if (stra[1] === '~~') {
			str = str.replace(stra[0], '' + stra[2] + '');
		} else {
			switch (stra[1].length) {
				case 1:
					repstr = ['', ''];
					break;
				case 2:
					repstr = ['', ''];
					break;
				case 3:
					repstr = ['', ''];
					break;
			}
			str = str.replace(stra[0], repstr[0] + stra[2] + repstr[1]);
		}
		return str;
	},
	tableHandlerHelper: function (helper, calign, strict) {
		var i;
		for (i = 0; i < helper.length; i++) {
			if (calign.length <= i) {
				calign.push(0);
			} else if ((calign[i].trimRight().slice(-1) === ':') && (strict !== true)) {
				if (calign[i][0] === ':') {
					calign[i] = 3;
				} else {
					calign[i] = 2;
				}
			} else if (strict !== true) {
				if (calign[i][0] === ':') {
					calign[i] = 1;
				} else {
					calign[i] = 0;
				}
			} else {
				calign[i] = 0;
			}
		}
	},
	tablesHandler: function (stra, str, strict) {
		var repstr, cel, helper, calign, helper1, helper2, i, j;

		repstr = '

';
		helper = stra[1].split('|');
		calign = stra[4].split('|');
		this.tableHandlerHelper(helper, calign, strict);
		cel = ['', '', '', ''];
		for (i = 0; i < helper.length; i++) {
			repstr += cel[calign[i]] + helper[i].trim() + '	';
		}
		repstr += '
';
		cel = ['', '', '', ''];
		helper1 = stra[7].split('\n');
		for (i = 0; i < helper1.length; i++) {
			helper2 = helper1[i].split('|');
			if (helper2[0].length !== 0) {
				while (calign.length < helper2.length) {
					calign.push(0);
				}
				repstr += '
';
				for (j = 0; j < helper2.length; j++) {
					repstr += cel[calign[j]] + helper2[j].trim() + '	';
				}
				repstr += '
' + '\n';
			}
		}
		repstr += '
';
		return str.replace(stra[0], repstr);
	},

	listHanderStart: function (stra, repstr) {
		if ((stra[0].trim().substr(0, 1) === '*') || (stra[0].trim().substr(0, 1) === '-')) {
			repstr = '
';
		} else {
			repstr = '
';
		}
		return repstr;
	},

	listsHandlerEnd: function (stra, repstr) {
		if ((stra[0].trim().substr(0, 1) === '*') || (stra[0].trim().substr(0, 1) === '-')) {
			repstr += '
';
		} else {
			repstr += '
';
		}
		return repstr;
	}, listHandler: function (stra, str) {
		var helper, helper1, status, indent, line, nstatus, repstr, i, casca = 0;
		repstr = this.listHanderStart(stra, repstr);
		helper = stra[0].split('\n');
		helper1 = [];
		status = 0;
		indent = false;
		for (i = 0; i < helper.length; i++) {
			if ((line = /^((\s*)((\*|\-)|\d(\.|\))) ([^\n]+))/.exec(helper[i])) !== null) {
				if ((line[2] === undefined) || (line[2].length === 0)) {
					nstatus = 0;
				} else {
					if (indent === false) {
						indent = line[2].replace(/\t/, '    ').length;
					}
					nstatus = Math.round(line[2].replace(/\t/, '    ').length / indent);
				}
				while (status > nstatus) {
					repstr += helper1.pop();
					status--;
					casca--;
				}
				while (status < nstatus) {
					if ((line[0].trim().substr(0, 1) === '*') || (line[0].trim().substr(0, 1) === '-')) {
						repstr += '
';
						helper1.push('
');
					} else {
						repstr += '
';
						helper1.push('
');
					}
					status++;
					casca++;
				}
				repstr += '
' + line[6] + '
' + '\n';
			}
		}
		while (casca > 0) {
			repstr += '
';
			casca--;
		}
		repstr = this.listsHandlerEnd(stra, repstr);
		return str.replace(stra[0], repstr + '\n');
	},

	parse: function (str, strict) {
		var helper, helper1, stra, trashgc = [], i;
		str = '\n' + str + '\n';

		var regexobject = micromarkdown.regexobject;
		if (strict !== true) {
			regexobject.lists = /^((\s*(\*|\d\.) [^\n]+)\n)+/gm;
		}

		while ((stra = regexobject.code.exec(str)) !== null) {
			str = this.codeHandler(stra, str);
		}

		while ((stra = regexobject.headline.exec(str)) !== null) {
			str = this.headlinesHandler(stra, str);
		}

		while ((stra = regexobject.lists.exec(str)) !== null) {
			str = this.listHandler(stra, str);
		}

		while ((stra = regexobject.tables.exec(str)) !== null) {
			str = this.tablesHandler(stra, str, strict);
		}

		for (i = 0; i < 3; i++) {
			while ((stra = regexobject.bolditalic.exec(str)) !== null) {
				str = this.boldItalicHandler(stra, str);
			}
		}

		while ((stra = regexobject.links.exec(str)) !== null) {
			str = this.linksHandler(stra, str, strict);
		}

		while ((stra = regexobject.mail.exec(str)) !== null) {
			str = this.mailHandler(stra, str);
		}

		while ((stra = regexobject.url.exec(str)) !== null) {
			str = this.urlHandler(stra, str, strict);
		}

		while ((stra = regexobject.reflinks.exec(str)) !== null) {
			helper1 = new RegExp('\\[' + stra[2] + '\\]: ?([^ \n]+)', "gi");
			if ((helper = helper1.exec(str)) !== null) {
				str = this.refLinksHandler(str, stra, helper, strict);
				trashgc.push(helper[0]);
			}
		}

		for (i = 0; i < trashgc.length; i++) {
			str = str.replace(trashgc[i], '');
		}
		while ((stra = regexobject.smlinks.exec(str)) !== null) {
			str = this.specialLinks(stra, str, strict);
		}

		while ((stra = regexobject.hr.exec(str)) !== null) {
			str = this.horizontalLineHandler(stra, str);
		}

		return str.replace(/ {2,}[\n]{1,}/gmi, '

');
	},

	htmlEncode: function (str) {
		var div = document.createElement('div');
		div.appendChild(document.createTextNode(str));
		return div.innerHTML;
	},

	mmdCSSclass: function (str, strict) {
		var urlTemp;
		if ((str.indexOf('/') !== -1) && (strict !== true)) {
			urlTemp = str.split('/');
			if (urlTemp[1].length === 0) {
				urlTemp = urlTemp[2].split('.');
			} else {
				urlTemp = urlTemp[0].split('.');
			}
			return 'class="mmd_' + urlTemp[urlTemp.length - 2].replace(/[^\w\d]/g, '') + urlTemp[urlTemp.length - 1] + '" ';
		}
		return '';
	}
};

EchoesWorks.md = micromarkdown;<|endoftext|>


<commit_before>var DAY_SUFFIXES = { 1: "st", 2: "nd", 3: "rd" };
var DATATABLES_COLUMNS = { PROTO: 0, DST_PORT: 1, DST_IP: 2, SRC_IP: 3, FIRST_SEEN: 4, LAST_SEEN: 5, COUNT: 6 }
var IP_COUNTRY = {};
var POINT_SIZE = 4;
var LINE_WIDTH = 1.5;
var DEFAULT_OPACITY = 0.7;
var TRENDLINE_TIMEOUT = null;
var RESIZE_TIMEOUT = null;
var REFRESH_PAGE_PERIOD = 5 * 60 * 1000;  // 5 mins

window.setTimeout(function(){ document.location.reload(true); }, REFRESH_PAGE_PERIOD);

jQuery.extend(jQuery.fn.dataTableExt.oSort, {
    // Reference: http://cdn.datatables.net/plug-ins/3cfcc339e89/sorting/date-euro.js
    "date-custom-pre": function ( a ) {
        var x = Infinity;
        var match = a.match(/time=["']([^"']+)/);
        if (match !== null) {
            var frDatea = match[1].split(' ');
            var frTimea = frDatea[1].split('.')[0].split(':');
            var frDatea2 = frDatea[0].split('-');

            x = (frDatea2[0] + frDatea2[1] + frDatea2[2] + frTimea[0] + frTimea[1] + frTimea[2]) * 1;
        }
        return x;
    },
    "date-custom-asc": function ( a, b ) {
        return a - b;
    },
    "date-custom-desc": function ( a, b ) {
        return b - a;
    }
});

jQuery.extend(jQuery.fn.dataTableExt.oSort, {
    // Reference: https://cdn.datatables.net/plug-ins/3cfcc339e89/sorting/ip-address.js
    "ip-address-pre": function (a) {
        return _ipSortingValue(a);
    },

    "ip-address-asc": function ( a, b ) {
        return ((a  b) ? 1 : 0));
    },

    "ip-address-desc": function ( a, b ) {
        return ((a  b) ? -1 : 0));
    }
});

jQuery.extend(jQuery.fn.dataTableExt.oSort, {
    "port-custom-pre": function ( a ) {
        var x = 0;
        var match = a.match(/(\d+).*/);
        if (match !== null) {
            x = match[1] * 1;
        }
        return x;
    },
    "port-custom-asc": function ( a, b ) {
        return a - b;
    },
    "port-custom-desc": function ( a, b ) {
        return b - a;
    }
});

function formatDate(value) {
    return value.getFullYear() + "-" + pad(value.getMonth() + 1, 2) + "-" + pad(value.getDate(), 2);
};

function pad(n, width, z) {
    z = z || '0';
    n = n + '';

    return n.length >= width ? n : new Array(width - n.length + 1).join(z) + n;
}

String.prototype.hashCode = function() {
    return murmurhash3_32_gc(this, 13);
};

function getHashColor(value) {
    return pad(value.hashCode().toString(16), 6).substring(0, 6);
}

// Reference: http://en.wikipedia.org/wiki/Private_network
function isLocalAddress(ip) {
    if (ip.startsWith("10.") || ip.startsWith("192.168.") || ip.startsWith("127."))
        return true;
    else if (ip.startsWith("172.")) {
        var _ = parseInt(ip.split(".")[1]);
        return ((_ >= 16) && (_ <= 31))
    }
    else
        return false;
};

function _ipSortingValue(a) {
    var x = "";

    match = a.match(/\d+\.\d+\.\d+\.\d+/);
    if (match !== null) {
        var m = match[0].split(".");

        for (var i = 0; i < m.length; i++) {
            var item = m[i];

            if(item.length === 1) {
                x += "00" + item;
            } else if(item.length === 2) {
                x += "0" + item;
            } else {
                x += item;
            }
        }
    }

    return x;
}

google.load("visualization", "1", {packages:["corechart"]});

function drawTrendlines() {
    var data = google.visualization.arrayToDataTable([
//<!TRENDLINE_DATA!>
]);

    var options = {
        title: '',
        colors: [],
        hAxis: {title: 'Date', format: 'yyyy-MM-dd', textStyle: {fontSize: 12}, titleTextStyle: {italic: false, fontSize: 13}},
        vAxis: {title: 'Intruders', textStyle: {fontSize: 12}, titleTextStyle: {italic: false, fontSize: 13}, logScale: true, minValue: 0},
        trendlines: { },
        legend: {position: 'right', textStyle: {fontSize: 13}},
        fontName: 'monospace',
        chartArea: {left: 70, top: 20, width: "80%", height: "80%"},
    };

    for (var i = 1; i < data.getNumberOfColumns(); i++) {
        var color = getHashColor(data.getColumnLabel(i));
        options.trendlines[i - 1] = {type: 'polynomial', degree: 3, opacity: 1, lineWidth: 1, tooltip: false, color: color};
        options.colors.push(color);
    }

    if (data.getNumberOfRows() > 0) {
        document.title = "tsusen (" + formatDate(data.getValue(0, 0)) + " - " + formatDate(data.getValue(data.getNumberOfRows() - 1,0)) + ")";
    }

    var chart = new google.visualization.ScatterChart(document.getElementById('chart'));

    chart.draw(data, options);

    // Reference: http://stackoverflow.com/a/20384135
    $(window).resize(function() {
        if(RESIZE_TIMEOUT)
            clearTimeout(RESIZE_TIMEOUT);
        RESIZE_TIMEOUT = setTimeout(function() {
            $(this).trigger('resized');
        }, 300);
    });

    $(window).on('resized', function() {
        drawTrendlines(chart.draw(data, options));
    });

    google.visualization.events.addListener(chart, 'onmouseover', function(e){
        var circles = $('svg g g g circle');
        if (circles.length) {
            var fill = circles[circles.length - 1].attributes["fill"].value;
            clearTimeout(TRENDLINE_TIMEOUT);
            $("circle[fill='" + fill + "']").attr("r", POINT_SIZE * 1.2).attr("fill-opacity", 1);
            $("path[stroke='" + fill + "']").attr("stroke-width", LINE_WIDTH * 2).attr("stroke-opacity", 1);
            $("circle[fill!='" + fill + "']").attr("fill-opacity", 0.1);
            $("path[stroke!='" + fill + "']").attr("stroke-opacity", 0.1);
        }
    });

    google.visualization.events.addListener(chart, 'onmouseout', function(e){
        TRENDLINE_TIMEOUT = setTimeout(function(){
            $("circle").attr("r", POINT_SIZE).attr("fill-opacity", DEFAULT_OPACITY);
            $("path").attr("stroke-width", LINE_WIDTH).attr("stroke-opacity", DEFAULT_OPACITY);
        }, 500);
    });

    google.visualization.events.addListener(chart, 'ready', function(e){
        google.visualization.events.trigger(chart, 'onmouseout', e);
    });
}

var dataset = [
//<!DATASET!>
];

$(document).ready(function() {
    drawTrendlines();

    $('#details').DataTable( {
        data: dataset,
        columns: [
            { title: "proto" },
            { title: "dst_port", type: "port-custom" },
            { title: "dst_ip", type: "ip-address" },
            { title: "src_ip", type: "ip-address" },
            { title: "first_seen", type: "date-custom" },
            { title: "last_seen", type: "date-custom" },
            { title: "count" },
        ],
        columnDefs: [
            {
                orderSequence: [ "desc", "asc" ],
                targets: [ DATATABLES_COLUMNS.FIRST_SEEN, DATATABLES_COLUMNS.LAST_SEEN, DATATABLES_COLUMNS.COUNT ]
            },
            {
                render: function (data, type, row) {
                    var parts = data.split(' ');
                    var day = parts[0].split('-')[2];
                    var dayint = parseInt(day);
                    var suffix = (dayint > 10 && dayint < 20) ? "th" : DAY_SUFFIXES[dayint % 10] || "th";
                    return "
" + day + "" + suffix + " " + parts[1].split('.')[0] + "
";
                },
                targets: [ DATATABLES_COLUMNS.FIRST_SEEN, DATATABLES_COLUMNS.LAST_SEEN ],
            },
        ],
        iDisplayLength: 25,
        aaSorting: [ [DATATABLES_COLUMNS.LAST_SEEN, 'desc'] ],
        fnRowCallback: function(nRow, aData, iDisplayIndex, iDisplayIndexFull) {
            function nslookup(event, ui) {
                var elem = $(this);
                var html = elem.parent().html();
                var match = html.match(/\d+\.\d+\.\d+\.\d+/);

                if (match !== null) {
                    var ip = match[0];

                    $.ajax("https://stat.ripe.net/data/dns-chain/data.json?resource=" + ip, { dataType:"jsonp", ip: ip})
                    .success(function(json) {
                        var _ = json.data.reverse_nodes[this.ip];
                        if ((_.length === 0)||(_ === "localhost")) {
                            _ = "-";
                        }
                        var msg = "
" + _ + "
";
                        ui.tooltip.find(".ui-tooltip-content").html(msg + "
" + "please wait...");

                        $.ajax("https://stat.ripe.net/data/whois/data.json?resource=" + ip, { dataType:"jsonp", ip: ip, msg: msg })
                        .success(function(json) {
                            // Reference: http://bugs.jqueryui.com/ticket/8740#comment:21
                            var found = null;
                            var msg = "";

                            for (var i = json.data.records.length - 1; i >= 0 ; i--) {
                                if ((json.data.records[i][0].key.toLowerCase().indexOf("inetnum") != -1) || (json.data.records[i][0].key.toLowerCase().indexOf("netrange") != -1)){
                                    found = i;
                                    break;
                                }
                            }

                            if (found !== null) {
                                for (var j = 0; j < json.data.records[found].length; j++) {
                                    msg += json.data.records[found][j].key + ": " + json.data.records[found][j].value;
                                    msg += "
";
                                }
                                msg = msg.replace(/(\-\+)+/g, "--").replace(/(\-\+)+/g, "--");
                            }

                            ui.tooltip.find(".ui-tooltip-content").html(this.msg + "
" + msg);
                        });
                    });
                }
            }

            $('[title]', nRow).tooltip();

            $.each([DATATABLES_COLUMNS.SRC_IP, DATATABLES_COLUMNS.DST_IP], function(index, value) {
                var cell = $('td:eq(' + value + ')', nRow);

                if (cell === null)
                    return false;

                var html = cell.html();

                if (html === null)
                    return false;

                if ((html.indexOf('flag') > -1) || (html.indexOf('lan') > -1) || (html.indexOf(',') > -1))
                    return false;

                var match = html.match(/\d+\.\d+\.\d+\.\d+/);
                if (match === null)
                    return false;

                var interval = null;
                var img = "";
                var ip = match[0];
                var options = { content: "please wait...", open: nslookup, position: { my: "left center", at: "right+10 top-50" } };

                if (!isLocalAddress(ip)) {
                    if (!(ip in IP_COUNTRY)) {
                        IP_COUNTRY[ip] = null;
                        //$.ajax("https://stat.ripe.net/data/geoloc/data.json?resource=" + ip, { dataType:"jsonp", ip: ip, cell: cell })
                        $.ajax("/geoip.json?ip=" + ip, { dataType:"jsonp", ip: ip, cell: cell })
                        .success(function(json) {
                            var span_ip = $("").html(this.ip + " ");

                            if ((json.country) && (json.country !== "ANO")) {
                                IP_COUNTRY[this.ip] = json.country.toLowerCase().split('-')[0];
                                img = '';  // title="' + IP_COUNTRY[this.ip].toUpperCase() + '"
                                span_ip.tooltip(options);
                            }
                            else {
                                IP_COUNTRY[this.ip] = "unknown";
                                img = '';
                            }

                            this.cell.html("").append(span_ip).append($(img).tooltip());
                        });
                    }
                    else if (IP_COUNTRY[ip] !== null) {
                        img = ' '

                        var span_ip = $("").html(ip + " ");
                        span_ip.tooltip(options);

                        cell.html("").append(span_ip).append($(img).tooltip());
                    }
                    else {
                        interval = setInterval(function(ip, cell){
                            html = cell.html();
                            if ((IP_COUNTRY[ip] !== null) && (html.indexOf("flag-") === -1)) {
                                img = ' '

                                var span_ip = $("").html(ip + " ");
                                span_ip.tooltip(options);

                                cell.html("").append(span_ip).append($(img).tooltip());
                                clearInterval(interval);
                            }
                        }, 200, ip, cell);
                    }
                }
                else {
                    img = '';
                    cell.html(html + " ").append($(img).tooltip());
                }
            });
        },

    } );
} );
<commit_msg>Minor style update<commit_after>var DAY_SUFFIXES = { 1: "st", 2: "nd", 3: "rd" };
var DATATABLES_COLUMNS = { PROTO: 0, DST_PORT: 1, DST_IP: 2, SRC_IP: 3, FIRST_SEEN: 4, LAST_SEEN: 5, COUNT: 6 }
var IP_COUNTRY = {};
var POINT_SIZE = 4;
var LINE_WIDTH = 1.5;
var DEFAULT_OPACITY = 0.7;
var TRENDLINE_TIMEOUT = null;
var RESIZE_TIMEOUT = null;
var REFRESH_PAGE_PERIOD = 5 * 60 * 1000;  // 5 mins

window.setTimeout(function(){ document.location.reload(true); }, REFRESH_PAGE_PERIOD);

jQuery.extend(jQuery.fn.dataTableExt.oSort, {
    // Reference: http://cdn.datatables.net/plug-ins/3cfcc339e89/sorting/date-euro.js
    "date-custom-pre": function ( a ) {
        var x = Infinity;
        var match = a.match(/time=["']([^"']+)/);
        if (match !== null) {
            var frDatea = match[1].split(' ');
            var frTimea = frDatea[1].split('.')[0].split(':');
            var frDatea2 = frDatea[0].split('-');

            x = (frDatea2[0] + frDatea2[1] + frDatea2[2] + frTimea[0] + frTimea[1] + frTimea[2]) * 1;
        }
        return x;
    },
    "date-custom-asc": function ( a, b ) {
        return a - b;
    },
    "date-custom-desc": function ( a, b ) {
        return b - a;
    }
});

jQuery.extend(jQuery.fn.dataTableExt.oSort, {
    // Reference: https://cdn.datatables.net/plug-ins/3cfcc339e89/sorting/ip-address.js
    "ip-address-pre": function (a) {
        return _ipSortingValue(a);
    },

    "ip-address-asc": function ( a, b ) {
        return ((a  b) ? 1 : 0));
    },

    "ip-address-desc": function ( a, b ) {
        return ((a  b) ? -1 : 0));
    }
});

jQuery.extend(jQuery.fn.dataTableExt.oSort, {
    "port-custom-pre": function ( a ) {
        var x = 0;
        var match = a.match(/(\d+).*/);
        if (match !== null) {
            x = match[1] * 1;
        }
        return x;
    },
    "port-custom-asc": function ( a, b ) {
        return a - b;
    },
    "port-custom-desc": function ( a, b ) {
        return b - a;
    }
});

function formatDate(value) {
    return value.getFullYear() + "-" + pad(value.getMonth() + 1, 2) + "-" + pad(value.getDate(), 2);
};

function pad(n, width, z) {
    z = z || '0';
    n = n + '';

    return n.length >= width ? n : new Array(width - n.length + 1).join(z) + n;
}

String.prototype.hashCode = function() {
    return murmurhash3_32_gc(this, 13);
};

function getHashColor(value) {
    return pad(value.hashCode().toString(16), 6).substring(0, 6);
}

// Reference: http://en.wikipedia.org/wiki/Private_network
function isLocalAddress(ip) {
    if (ip.startsWith("10.") || ip.startsWith("192.168.") || ip.startsWith("127."))
        return true;
    else if (ip.startsWith("172.")) {
        var _ = parseInt(ip.split(".")[1]);
        return ((_ >= 16) && (_ <= 31))
    }
    else
        return false;
};

function _ipSortingValue(a) {
    var x = "";

    match = a.match(/\d+\.\d+\.\d+\.\d+/);
    if (match !== null) {
        var m = match[0].split(".");

        for (var i = 0; i < m.length; i++) {
            var item = m[i];

            if(item.length === 1) {
                x += "00" + item;
            } else if(item.length === 2) {
                x += "0" + item;
            } else {
                x += item;
            }
        }
    }

    return x;
}

google.load("visualization", "1", {packages:["corechart"]});

function drawTrendlines() {
    var data = google.visualization.arrayToDataTable([
//<!TRENDLINE_DATA!>
]);

    var options = {
        title: '',
        colors: [],
        hAxis: {title: 'Date', format: 'yyyy-MM-dd', textStyle: {fontSize: 12}, titleTextStyle: {italic: false, fontSize: 13}},
        vAxis: {title: 'Intruders', textStyle: {fontSize: 12}, titleTextStyle: {italic: false, fontSize: 13}, logScale: true, minValue: 0},
        trendlines: { },
        legend: {position: 'right', textStyle: {fontSize: 13}},
        fontName: 'monospace',
        chartArea: {left: 70, top: 20, width: "80%", height: "80%"},
    };

    for (var i = 1; i < data.getNumberOfColumns(); i++) {
        var color = getHashColor(data.getColumnLabel(i));
        options.trendlines[i - 1] = {type: 'polynomial', degree: 3, opacity: 1, lineWidth: 1, tooltip: false, color: color};
        options.colors.push(color);
    }

    if (data.getNumberOfRows() > 0) {
        document.title = "tsusen (" + formatDate(data.getValue(0, 0)) + " - " + formatDate(data.getValue(data.getNumberOfRows() - 1,0)) + ")";
    }

    var chart = new google.visualization.ScatterChart(document.getElementById('chart'));

    chart.draw(data, options);

    // Reference: http://stackoverflow.com/a/20384135
    $(window).resize(function() {
        if(RESIZE_TIMEOUT)
            clearTimeout(RESIZE_TIMEOUT);
        RESIZE_TIMEOUT = setTimeout(function() {
            $(this).trigger('resized');
        }, 300);
    });

    $(window).on('resized', function() {
        drawTrendlines(chart.draw(data, options));
    });

    google.visualization.events.addListener(chart, 'onmouseover', function(e){
        var circles = $('svg g g g circle');
        if (circles.length) {
            var fill = circles[circles.length - 1].attributes["fill"].value;
            clearTimeout(TRENDLINE_TIMEOUT);
            $("circle[fill='" + fill + "']").attr("r", POINT_SIZE * 1.2).attr("fill-opacity", 1);
            $("path[stroke='" + fill + "']").attr("stroke-width", LINE_WIDTH * 2).attr("stroke-opacity", 1);
            $("circle[fill!='" + fill + "']").attr("fill-opacity", 0.1);
            $("path[stroke!='" + fill + "']").attr("stroke-opacity", 0.1);
        }
    });

    google.visualization.events.addListener(chart, 'onmouseout', function(e){
        TRENDLINE_TIMEOUT = setTimeout(function(){
            $("circle").attr("r", POINT_SIZE).attr("fill-opacity", DEFAULT_OPACITY);
            $("path").attr("stroke-width", LINE_WIDTH).attr("stroke-opacity", DEFAULT_OPACITY);
        }, 500);
    });

    google.visualization.events.addListener(chart, 'ready', function(e){
        google.visualization.events.trigger(chart, 'onmouseout', e);
    });
}

var dataset = [
//<!DATASET!>
];

$(document).ready(function() {
    drawTrendlines();

    $('#details').DataTable( {
        data: dataset,
        columns: [
            { title: "proto" },
            { title: "dst_port", type: "port-custom" },
            { title: "dst_ip", type: "ip-address" },
            { title: "src_ip", type: "ip-address" },
            { title: "first_seen", type: "date-custom" },
            { title: "last_seen", type: "date-custom" },
            { title: "count" },
        ],
        columnDefs: [
            {
                orderSequence: [ "desc", "asc" ],
                targets: [ DATATABLES_COLUMNS.FIRST_SEEN, DATATABLES_COLUMNS.LAST_SEEN, DATATABLES_COLUMNS.COUNT ]
            },
            {
                render: function (data, type, row) {
                    var parts = data.split(' ');
                    var day = parts[0].split('-')[2];
                    var dayint = parseInt(day);
                    var suffix = (dayint > 10 && dayint < 20) ? "th" : DAY_SUFFIXES[dayint % 10] || "th";
                    return "
" + day + "" + suffix + " " + parts[1].split('.')[0] + "
";
                },
                targets: [ DATATABLES_COLUMNS.FIRST_SEEN, DATATABLES_COLUMNS.LAST_SEEN ],
            },
        ],
        iDisplayLength: 25,
        aaSorting: [ [DATATABLES_COLUMNS.LAST_SEEN, 'desc'] ],
        fnRowCallback: function(nRow, aData, iDisplayIndex, iDisplayIndexFull) {
            function nslookup(event, ui) {
                var elem = $(this);
                var html = elem.parent().html();
                var match = html.match(/\d+\.\d+\.\d+\.\d+/);

                if (match !== null) {
                    var ip = match[0];

                    $.ajax("https://stat.ripe.net/data/dns-chain/data.json?resource=" + ip, { dataType:"jsonp", ip: ip})
                    .success(function(json) {
                        var _ = json.data.reverse_nodes[this.ip];
                        if ((_.length === 0)||(_ === "localhost")) {
                            _ = "-";
                        }
                        var msg = "
" + _ + "
";
                        ui.tooltip.find(".ui-tooltip-content").html(msg + "please wait...");

                        $.ajax("https://stat.ripe.net/data/whois/data.json?resource=" + ip, { dataType:"jsonp", ip: ip, msg: msg })
                        .success(function(json) {
                            // Reference: http://bugs.jqueryui.com/ticket/8740#comment:21
                            var found = null;
                            var msg = "";

                            for (var i = json.data.records.length - 1; i >= 0 ; i--) {
                                if ((json.data.records[i][0].key.toLowerCase().indexOf("inetnum") != -1) || (json.data.records[i][0].key.toLowerCase().indexOf("netrange") != -1)){
                                    found = i;
                                    break;
                                }
                            }

                            if (found !== null) {
                                for (var j = 0; j < json.data.records[found].length; j++) {
                                    msg += json.data.records[found][j].key + ": " + json.data.records[found][j].value;
                                    msg += "
";
                                }
                                msg = msg.replace(/(\-\+)+/g, "--").replace(/(\-\+)+/g, "--");
                            }

                            ui.tooltip.find(".ui-tooltip-content").html(this.msg + msg);
                        });
                    });
                }
            }

            $('[title]', nRow).tooltip();

            $.each([DATATABLES_COLUMNS.SRC_IP, DATATABLES_COLUMNS.DST_IP], function(index, value) {
                var cell = $('td:eq(' + value + ')', nRow);

                if (cell === null)
                    return false;

                var html = cell.html();

                if (html === null)
                    return false;

                if ((html.indexOf('flag') > -1) || (html.indexOf('lan') > -1) || (html.indexOf(',') > -1))
                    return false;

                var match = html.match(/\d+\.\d+\.\d+\.\d+/);
                if (match === null)
                    return false;

                var interval = null;
                var img = "";
                var ip = match[0];
                var options = { content: "please wait...", open: nslookup, position: { my: "left center", at: "right+10 top-50" } };

                if (!isLocalAddress(ip)) {
                    if (!(ip in IP_COUNTRY)) {
                        IP_COUNTRY[ip] = null;
                        //$.ajax("https://stat.ripe.net/data/geoloc/data.json?resource=" + ip, { dataType:"jsonp", ip: ip, cell: cell })
                        $.ajax("/geoip.json?ip=" + ip, { dataType:"jsonp", ip: ip, cell: cell })
                        .success(function(json) {
                            var span_ip = $("").html(this.ip + " ");

                            if ((json.country) && (json.country !== "ANO")) {
                                IP_COUNTRY[this.ip] = json.country.toLowerCase().split('-')[0];
                                img = '';  // title="' + IP_COUNTRY[this.ip].toUpperCase() + '"
                                span_ip.tooltip(options);
                            }
                            else {
                                IP_COUNTRY[this.ip] = "unknown";
                                img = '';
                            }

                            this.cell.html("").append(span_ip).append($(img).tooltip());
                        });
                    }
                    else if (IP_COUNTRY[ip] !== null) {
                        img = ' '

                        var span_ip = $("").html(ip + " ");
                        span_ip.tooltip(options);

                        cell.html("").append(span_ip).append($(img).tooltip());
                    }
                    else {
                        interval = setInterval(function(ip, cell){
                            html = cell.html();
                            if ((IP_COUNTRY[ip] !== null) && (html.indexOf("flag-") === -1)) {
                                img = ' '

                                var span_ip = $("").html(ip + " ");
                                span_ip.tooltip(options);

                                cell.html("").append(span_ip).append($(img).tooltip());
                                clearInterval(interval);
                            }
                        }, 200, ip, cell);
                    }
                }
                else {
                    img = '';
                    cell.html(html + " ").append($(img).tooltip());
                }
            });
        },

    } );
} );
<|endoftext|>


<commit_before>(function($){
  var _instance, addTagSearch;

  addTagSearch = function() {
    var $el = $('.editable-container .tags-inline-input')
    new op.data.view.TagSearch({el: $el});
  };

  var DetailView = op.data.view.Editable.extend({
    initialize: function(){
      this.boundFunctions = {};
    },
    _bound : function(name){
      if( !this.boundFunctions[name] ){
        if( typeof this[name] !== 'function' ) return null;
        this.boundFunctions[name] = _.bind(this[name], this);
      }
      return this.boundFunctions[name];
    },
    template: _.template($('#op-lightbox-details').html()),
    editable: {
      '.title.edit' : {
        name: 'title',
        title: 'Edit Photo Title',
        placement: 'top',
      },
      '.description.edit' : {
        name: 'description',
        type: 'textarea',
        title: 'Edit Photo Description',
        placement: 'top',
        emptytext: 'Click to add a description'
      },
      '.tags.edit' : {
        name: 'tags',
        title: 'Edit Tags',
        placement: 'top',
        emptytext: '',
        inputclass: 'tags-inline-input tags',
        shown: addTagSearch
      }
    },
    setModel: function(model){
      if( this.model ){
        // stop listening
        this.model.off('change', this._bound('render'));
      }
      this.model = model;
      this.model.on('change', this._bound('render'));
      this.render();
    },
    events : {
      'click .permission.edit': 'permission',
      'click .rotate': 'rotate',
      'click .share': 'share'
    },
    permission: function(ev) {
      ev.preventDefault();
      var el = $(ev.currentTarget), id = el.attr('data-id'), model = this.model;
      model.set('permission', model.get('permission') == 0 ? 1 : 0, {silent:false});
      model.save();
    },
    rotate: function(ev) {
      ev.preventDefault();
      var $el = $(ev.currentTarget), model = this.model, id = model.get('id'), size = 'Base', value='90';
      OP.Util.makeRequest('/photo/'+id+'/transform.json', {crumb: TBX.crumb(),rotate:value,generate:'true'}, TBX.callbacks.rotate.bind({model: model, id: id, size: size}), 'json', 'post');
    },
    share: function(ev) {
      ev.preventDefault();
      var $el = $(ev.currentTarget), id = $el.attr('data-id'), router = op.data.store.Router;
      OP.Util.makeRequest('/share/photo/'+id+'/view.json', {crumb: TBX.crumb()}, function(response) {
        router.navigate(op.Lightbox.prototype._path, {trigger: true});
        TBX.callbacks.share(response);
      }, 'json', 'get');
    }
  });

  var Lightbox = function(){

    // we are going to use the global photo store.
    this.boundFunctions = {};
    this.cache = {};
    this.store = op.data.store.Photos;
    this.template = _.template($('#op-lightbox').html());
    this._initialized = false;
  };

  _.extend( Lightbox.prototype, Backbone.Events, {

    imagePathKey : 'pathBase',

    _initialize : function(){
      if( this._initialized ) return;
      this._initView();
      this._initEvents();
      this._initialized = true;
    },

    keys : {
      // we may want to rethink some of these key codes...
      // i think down and up may be good to toggle details / thumbs
      next      	  :[34, 39, 40, 74], // up, down, j
      prev      	  :[33, 37, 38, 75], // left, up, k
      title         :[84],  // t
      tags          :[71],  // g
      description   :[68],  // d
      privacy    	  :[80],  // p
      hide      	  :[27],  // escape
      togglePlay	  :[32]  // spacebar
      //toggleDetails :[68]   // d
    },

    _path: location.pathname,
    _filter: location.pathname.replace('/p/', '/').replace('/photos/', '/').replace('/list', ''),
    _visible: false,

    _indexOf : function(model){
      return _.indexOf(this.store.models, model);
    },

    _bound : function(name){
      if( !this.boundFunctions[name] ){
        if( typeof this[name] !== 'function' ) return null;
        this.boundFunctions[name] = _.bind(this[name], this);
      }
      return this.boundFunctions[name];
    },

    _initView : function(){

      this.$el = $( this.template() )
        .appendTo($(document.body))
        .hide()
        .fadeIn('fast')

      this.detailView = new DetailView({el: this.$el.find('.details .container')} );
    },

    _initEvents : function(){
      this.$el.click( this._bound('onContainerClick') );
      this.$el.find('.photo').click( this._bound('nextIfImage'));
      this.$el.find('.photo .nav .prev').click( this._bound('prev'));
      this.$el.find('.photo .nav .next').click( this._bound('next'));
      this.$el.find('.details .toggle').click( this._bound('toggleDetails'));
      this.$el.find('.detail-link').click( this._bound('viewDetailPage'));
    },

    _captureDocumentEvents : function(){
      $(document).on({
        'keyup.oplightbox'	:this._bound('keyup')
      });
      $(window).on({
        'resize.oplightbox'		:this._bound('adjustSize')
      });
    },

    _releaseDocumentEvents : function(){
      $(document).off('.oplightbox');
      $(window).off('.oplightbox');
    },

    onContainerClick : function(e){
      if( e.target === this.$el[0] ) this.hide();
      if( $(e.target).parent()[0] == this.$el[0] ) this.hide();
    },

    keyup : function(e){
      var code = e.which || e.keyCode
        , target = e.target || e.srcElement
        , self = this

      // Ignore key combinations and key events within form elements
      if (!e.ctrlKey && !e.altKey && !e.shiftKey && !e.metaKey && !(target && (target.type || $(target).is('[contenteditable]')))) {
        $.each(self.keys, function(fn, codes){
          if( ~_.indexOf(codes, code) ){
            self[fn]();
            return false;
          }
          return true;
        });
      }
    },

    adjustSize : function(){
      var $photo = this.$el.find('.photo');

      // check for the image
      if( (c =this.cache[this.model.get('id')]) && c._loaded ){
        /*
         * iw = image width, ih = image height, ir = image ratio
         * cw = chrome width, ch = chrome height, cr = chrome ratio
         */
        var iw = c.width
          , ih = c.height
          , ir = iw / ih
          , cw = $(window).width()
          , ch = $(window).height() - this.$el.find('.bd').position().top
          , cr = cw / ch;

        // if the image is narrower and the height is shorter than the chrome
        //  then set the div's width to the images dimensions
        // else
        //  if the chrome ratio (width) is greater than the image
        //    set the width to the image width * chrome height / image height
        //    set the height to the chrome height
        //  else
        //    set the height to the image height * chrome width / image width
        //    set the width to the chrome width
        if( iw < cw && ih < ch ){
          $photo.width(iw);
          $photo.height(ih);
        } else {
          $photo.css( cr > ir ? {width: iw * ch/ih, height: ch} : {width: cw, height: ih * cw/iw} );
        }
      } else {
        $photo.css({'height': ( $(window).height() - this.$el.find('.bd').position().top )+'px'} );
      }
    },

    isOpen: function() {
      if(this.$el)
        return true;
      return false;
    },

    show : function(item){
      this._initialize();
      this._visible = true;
      this._captureDocumentEvents();
      this.$el.fadeIn('fast');
      this.adjustSize();
      return this;
    },

    hide : function(){
      var router = op.data.store.Router;
      this._releaseDocumentEvents();
      this._visible = false;
      this.$el.fadeOut('fast');
      router.navigate(this._path, {silent:true});
      return this;
    },

    update : function(model){
      this._initialize();
      this.$el.addClass('loading');
      this.setModel( model );
      this.$el.find('.photo').find('img').remove();
      this.loadImage();
      return this;
    },

    setModel : function(model){
      this.model = model;
      this.trigger('updatemodel', model);
      this.detailView.setModel( model );
      this.loadImage();
      //this.$el.find('.header .detail-link').attr('href', model.get('url'));
      this._preloadNextPrevious(model);
    },

    _imageLoaded : function(id){
      var c = this.cache[id];
      c._loaded = true;
      if( this.model.get('id') != id ) return;
      this.$el.removeClass('loading');
      this.$el.find('.photo img').remove();
      $('<img />').attr('class', 'photo-img-'+id).attr('src', $(c).attr('src')).hide().appendTo(this.$el.find('.photo')).fadeIn('fast');
      this.adjustSize();
    },

    _preloadNextPrevious : function(model) {
      var next, previous, photos = [];
      previous = this.store.at(this.store.indexOf(model) - 1);
      next = this.store.at(this.store.indexOf(model) + 1);

      if(typeof(previous) !== 'undefined') {
        photos.push(previous.get(this.imagePathKey));
      }
      if(typeof(next) !== 'undefined') {
        photos.push(next.get(this.imagePathKey));
      }

      if(photos.length > 0) {
        OP.Util.fire('preload:photos', photos);
      }
    },

    loadImage : function(){
      var c;
      this.$el.find('.photo img').remove();
      this.$el.addClass('loading');
      this.$el.find('.photo')
        .width($(window).width())
        .height(($(window).height() - this.$el.find('.bd').position().top )+'px');

      if( !(c = this.cache[this.model.get('id')]) ){
        var c = this.cache[this.model.get('id')] = new Image();
        c.onload = _.bind(this._imageLoaded, this, this.model.get('id'));
        c.src = this.model.get(this.imagePathKey);
        c._loaded = true;
      }
      else if( c._loaded ){
        this._imageLoaded(this.model.get('id'));
      }
    },

    prev : function(ev){
      if(ev !== undefined && ev.preventDefault) ev.preventDefault();
      var i = _.indexOf( this.store.models, this.model ) - 1, router = op.data.store.Router, id;
      if( i < 0 ) i = this.store.models.length-1;
      id = this.store.models[i].get('id');
      if( !$('body').hasClass('photo-details') ){
        router.navigate('/p/'+id+this._filter, {trigger: false});
      }
      this.go(i);
    },

    next : function(ev){
      if(ev !== undefined && ev.preventDefault) ev.preventDefault();
      var i = _.indexOf( this.store.models, this.model ) + 1, router = op.data.store.Router, id;
      // at the end, load some more synchronously
      if( i > this.store.models.length-1 ) {
        TBX.init.pages.photos.load(false);
      }

      // we check the length again since we append above
      // once we reach the end the appending stops so this works
      if( i < this.store.models.length ) {
        if( !$('body').hasClass('photo-details') ){
          id = this.store.models[i].get('id');
          router.navigate('/p/'+id+this._filter, {trigger: false});
        }
        this.go(i);
      }
    },

    nextIfImage : function(ev) {
      var el = ev.target;
      console.log(el.tagName);
      if(el.tagName === 'IMG') {
        ev.stopPropagation();
        this.next(ev);
      }
    },

    viewDetailPage : function(ev) {
      ev.preventDefault();
      var id = this.model.get('id');
      location.href = '/p/'+id+this._filter;
    },

    tags: function(ev) {
      var $tagsEl = $('a.tags.editable-click', this.$el);
      $tagsEl.on('render', function() { console.log('yaya'); });
      $tagsEl.trigger('click');
      //new op.data.view.TagSearch({el: $inputEl});
    },

    description: function(ev) {
      $('a.description.editable-click', this.$el).trigger('click');
    },

    title: function(ev) {
      $('a.title.editable-click', this.$el).trigger('click');
    },

    privacy: function(ev) {
      $('.permission', this.$el).trigger('click');
    },

    go : function( index ){
      this.setModel( this.store.models[index] );
    },

    togglePlay : function(){
      // TODO - implement slideshow playing state.
      return this;
    },

    toggleDetails : function(){
      this.$el.toggleClass('details-hidden');
    },

    open: function(arg) {
      var id, model;
      if(typeof(arg) === 'event') {
        arg.preventDefault();
        id = $(arg.currentTarget).attr('data-id');
      } else {
        id = arg;
      }

      // get the item from the store
      model = op.data.store.Photos.get(id);

      if( !model ) return $.error('No image in store with id '+id);

      return this.update(model).show();
    }
  });

  Lightbox.getInstance = function(){
    if( _instance === undefined ){
      _instance = new Lightbox();
    }
    return _instance;
  }

  op.Lightbox = Lightbox;
})(jQuery);
<commit_msg>Removing console.log calls in JS. #1416<commit_after>(function($){
  var _instance, addTagSearch;

  addTagSearch = function() {
    var $el = $('.editable-container .tags-inline-input')
    new op.data.view.TagSearch({el: $el});
  };

  var DetailView = op.data.view.Editable.extend({
    initialize: function(){
      this.boundFunctions = {};
    },
    _bound : function(name){
      if( !this.boundFunctions[name] ){
        if( typeof this[name] !== 'function' ) return null;
        this.boundFunctions[name] = _.bind(this[name], this);
      }
      return this.boundFunctions[name];
    },
    template: _.template($('#op-lightbox-details').html()),
    editable: {
      '.title.edit' : {
        name: 'title',
        title: 'Edit Photo Title',
        placement: 'top',
      },
      '.description.edit' : {
        name: 'description',
        type: 'textarea',
        title: 'Edit Photo Description',
        placement: 'top',
        emptytext: 'Click to add a description'
      },
      '.tags.edit' : {
        name: 'tags',
        title: 'Edit Tags',
        placement: 'top',
        emptytext: '',
        inputclass: 'tags-inline-input tags',
        shown: addTagSearch
      }
    },
    setModel: function(model){
      if( this.model ){
        // stop listening
        this.model.off('change', this._bound('render'));
      }
      this.model = model;
      this.model.on('change', this._bound('render'));
      this.render();
    },
    events : {
      'click .permission.edit': 'permission',
      'click .rotate': 'rotate',
      'click .share': 'share'
    },
    permission: function(ev) {
      ev.preventDefault();
      var el = $(ev.currentTarget), id = el.attr('data-id'), model = this.model;
      model.set('permission', model.get('permission') == 0 ? 1 : 0, {silent:false});
      model.save();
    },
    rotate: function(ev) {
      ev.preventDefault();
      var $el = $(ev.currentTarget), model = this.model, id = model.get('id'), size = 'Base', value='90';
      OP.Util.makeRequest('/photo/'+id+'/transform.json', {crumb: TBX.crumb(),rotate:value,generate:'true'}, TBX.callbacks.rotate.bind({model: model, id: id, size: size}), 'json', 'post');
    },
    share: function(ev) {
      ev.preventDefault();
      var $el = $(ev.currentTarget), id = $el.attr('data-id'), router = op.data.store.Router;
      OP.Util.makeRequest('/share/photo/'+id+'/view.json', {crumb: TBX.crumb()}, function(response) {
        router.navigate(op.Lightbox.prototype._path, {trigger: true});
        TBX.callbacks.share(response);
      }, 'json', 'get');
    }
  });

  var Lightbox = function(){

    // we are going to use the global photo store.
    this.boundFunctions = {};
    this.cache = {};
    this.store = op.data.store.Photos;
    this.template = _.template($('#op-lightbox').html());
    this._initialized = false;
  };

  _.extend( Lightbox.prototype, Backbone.Events, {

    imagePathKey : 'pathBase',

    _initialize : function(){
      if( this._initialized ) return;
      this._initView();
      this._initEvents();
      this._initialized = true;
    },

    keys : {
      // we may want to rethink some of these key codes...
      // i think down and up may be good to toggle details / thumbs
      next      	  :[34, 39, 40, 74], // up, down, j
      prev      	  :[33, 37, 38, 75], // left, up, k
      title         :[84],  // t
      tags          :[71],  // g
      description   :[68],  // d
      privacy    	  :[80],  // p
      hide      	  :[27],  // escape
      togglePlay	  :[32]  // spacebar
      //toggleDetails :[68]   // d
    },

    _path: location.pathname,
    _filter: location.pathname.replace('/p/', '/').replace('/photos/', '/').replace('/list', ''),
    _visible: false,

    _indexOf : function(model){
      return _.indexOf(this.store.models, model);
    },

    _bound : function(name){
      if( !this.boundFunctions[name] ){
        if( typeof this[name] !== 'function' ) return null;
        this.boundFunctions[name] = _.bind(this[name], this);
      }
      return this.boundFunctions[name];
    },

    _initView : function(){

      this.$el = $( this.template() )
        .appendTo($(document.body))
        .hide()
        .fadeIn('fast')

      this.detailView = new DetailView({el: this.$el.find('.details .container')} );
    },

    _initEvents : function(){
      this.$el.click( this._bound('onContainerClick') );
      this.$el.find('.photo').click( this._bound('nextIfImage'));
      this.$el.find('.photo .nav .prev').click( this._bound('prev'));
      this.$el.find('.photo .nav .next').click( this._bound('next'));
      this.$el.find('.details .toggle').click( this._bound('toggleDetails'));
      this.$el.find('.detail-link').click( this._bound('viewDetailPage'));
    },

    _captureDocumentEvents : function(){
      $(document).on({
        'keyup.oplightbox'	:this._bound('keyup')
      });
      $(window).on({
        'resize.oplightbox'		:this._bound('adjustSize')
      });
    },

    _releaseDocumentEvents : function(){
      $(document).off('.oplightbox');
      $(window).off('.oplightbox');
    },

    onContainerClick : function(e){
      if( e.target === this.$el[0] ) this.hide();
      if( $(e.target).parent()[0] == this.$el[0] ) this.hide();
    },

    keyup : function(e){
      var code = e.which || e.keyCode
        , target = e.target || e.srcElement
        , self = this

      // Ignore key combinations and key events within form elements
      if (!e.ctrlKey && !e.altKey && !e.shiftKey && !e.metaKey && !(target && (target.type || $(target).is('[contenteditable]')))) {
        $.each(self.keys, function(fn, codes){
          if( ~_.indexOf(codes, code) ){
            self[fn]();
            return false;
          }
          return true;
        });
      }
    },

    adjustSize : function(){
      var $photo = this.$el.find('.photo');

      // check for the image
      if( (c =this.cache[this.model.get('id')]) && c._loaded ){
        /*
         * iw = image width, ih = image height, ir = image ratio
         * cw = chrome width, ch = chrome height, cr = chrome ratio
         */
        var iw = c.width
          , ih = c.height
          , ir = iw / ih
          , cw = $(window).width()
          , ch = $(window).height() - this.$el.find('.bd').position().top
          , cr = cw / ch;

        // if the image is narrower and the height is shorter than the chrome
        //  then set the div's width to the images dimensions
        // else
        //  if the chrome ratio (width) is greater than the image
        //    set the width to the image width * chrome height / image height
        //    set the height to the chrome height
        //  else
        //    set the height to the image height * chrome width / image width
        //    set the width to the chrome width
        if( iw < cw && ih < ch ){
          $photo.width(iw);
          $photo.height(ih);
        } else {
          $photo.css( cr > ir ? {width: iw * ch/ih, height: ch} : {width: cw, height: ih * cw/iw} );
        }
      } else {
        $photo.css({'height': ( $(window).height() - this.$el.find('.bd').position().top )+'px'} );
      }
    },

    isOpen: function() {
      if(this.$el)
        return true;
      return false;
    },

    show : function(item){
      this._initialize();
      this._visible = true;
      this._captureDocumentEvents();
      this.$el.fadeIn('fast');
      this.adjustSize();
      return this;
    },

    hide : function(){
      var router = op.data.store.Router;
      this._releaseDocumentEvents();
      this._visible = false;
      this.$el.fadeOut('fast');
      router.navigate(this._path, {silent:true});
      return this;
    },

    update : function(model){
      this._initialize();
      this.$el.addClass('loading');
      this.setModel( model );
      this.$el.find('.photo').find('img').remove();
      this.loadImage();
      return this;
    },

    setModel : function(model){
      this.model = model;
      this.trigger('updatemodel', model);
      this.detailView.setModel( model );
      this.loadImage();
      //this.$el.find('.header .detail-link').attr('href', model.get('url'));
      this._preloadNextPrevious(model);
    },

    _imageLoaded : function(id){
      var c = this.cache[id];
      c._loaded = true;
      if( this.model.get('id') != id ) return;
      this.$el.removeClass('loading');
      this.$el.find('.photo img').remove();
      $('<img />').attr('class', 'photo-img-'+id).attr('src', $(c).attr('src')).hide().appendTo(this.$el.find('.photo')).fadeIn('fast');
      this.adjustSize();
    },

    _preloadNextPrevious : function(model) {
      var next, previous, photos = [];
      previous = this.store.at(this.store.indexOf(model) - 1);
      next = this.store.at(this.store.indexOf(model) + 1);

      if(typeof(previous) !== 'undefined') {
        photos.push(previous.get(this.imagePathKey));
      }
      if(typeof(next) !== 'undefined') {
        photos.push(next.get(this.imagePathKey));
      }

      if(photos.length > 0) {
        OP.Util.fire('preload:photos', photos);
      }
    },

    loadImage : function(){
      var c;
      this.$el.find('.photo img').remove();
      this.$el.addClass('loading');
      this.$el.find('.photo')
        .width($(window).width())
        .height(($(window).height() - this.$el.find('.bd').position().top )+'px');

      if( !(c = this.cache[this.model.get('id')]) ){
        var c = this.cache[this.model.get('id')] = new Image();
        c.onload = _.bind(this._imageLoaded, this, this.model.get('id'));
        c.src = this.model.get(this.imagePathKey);
        c._loaded = true;
      }
      else if( c._loaded ){
        this._imageLoaded(this.model.get('id'));
      }
    },

    prev : function(ev){
      if(ev !== undefined && ev.preventDefault) ev.preventDefault();
      var i = _.indexOf( this.store.models, this.model ) - 1, router = op.data.store.Router, id;
      if( i < 0 ) i = this.store.models.length-1;
      id = this.store.models[i].get('id');
      if( !$('body').hasClass('photo-details') ){
        router.navigate('/p/'+id+this._filter, {trigger: false});
      }
      this.go(i);
    },

    next : function(ev){
      if(ev !== undefined && ev.preventDefault) ev.preventDefault();
      var i = _.indexOf( this.store.models, this.model ) + 1, router = op.data.store.Router, id;
      // at the end, load some more synchronously
      if( i > this.store.models.length-1 ) {
        TBX.init.pages.photos.load(false);
      }

      // we check the length again since we append above
      // once we reach the end the appending stops so this works
      if( i < this.store.models.length ) {
        if( !$('body').hasClass('photo-details') ){
          id = this.store.models[i].get('id');
          router.navigate('/p/'+id+this._filter, {trigger: false});
        }
        this.go(i);
      }
    },

    nextIfImage : function(ev) {
      var el = ev.target;
      if(el.tagName === 'IMG') {
        ev.stopPropagation();
        this.next(ev);
      }
    },

    viewDetailPage : function(ev) {
      ev.preventDefault();
      var id = this.model.get('id');
      location.href = '/p/'+id+this._filter;
    },

    tags: function(ev) {
      var $tagsEl = $('a.tags.editable-click', this.$el);
      $tagsEl.trigger('click');
      //new op.data.view.TagSearch({el: $inputEl});
    },

    description: function(ev) {
      $('a.description.editable-click', this.$el).trigger('click');
    },

    title: function(ev) {
      $('a.title.editable-click', this.$el).trigger('click');
    },

    privacy: function(ev) {
      $('.permission', this.$el).trigger('click');
    },

    go : function( index ){
      this.setModel( this.store.models[index] );
    },

    togglePlay : function(){
      // TODO - implement slideshow playing state.
      return this;
    },

    toggleDetails : function(){
      this.$el.toggleClass('details-hidden');
    },

    open: function(arg) {
      var id, model;
      if(typeof(arg) === 'event') {
        arg.preventDefault();
        id = $(arg.currentTarget).attr('data-id');
      } else {
        id = arg;
      }

      // get the item from the store
      model = op.data.store.Photos.get(id);

      if( !model ) return $.error('No image in store with id '+id);

      return this.update(model).show();
    }
  });

  Lightbox.getInstance = function(){
    if( _instance === undefined ){
      _instance = new Lightbox();
    }
    return _instance;
  }

  op.Lightbox = Lightbox;
})(jQuery);
<|endoftext|>


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

var MapWrapper = require('./MapWrapper');
var ProjectMapWrapper = require('./ProjectMapWrapper');
var MapLayerToggleWrapper = require('./MapLayerToggleWrapper');
var SearchMapWrapper = require('./SearchMapWrapper');

var PropTypes = React.PropTypes;

function MapRowComponent (props) {
  return(

        <MapWrapper HandleMapZoomEnd={props.HandleMapZoomEnd} handleMapMoveEnd={props.handleMapMoveEnd} zoom={props.zoom} latitude={props.latitude} longitude={props.longitude} handleMapClick={props.handleMapClick} rowPadding={props.rowPadding} mapHeight={props.mapHeight} />

                <MapLayerToggleWrapper    />

                <ProjectMapWrapper />

  )
}

MapRowComponent.PropTypes = {
  latitude: PropTypes.number.isRequired,
  longitude: PropTypes.number.isRequired,
  zoom: PropTypes.number.isRequired,
  handleCenter: PropTypes.func.isRequired,
  handleMapClick: PropTypes.func.isRequired,
  handleMapMoveEnd: PropTypes.func.isRequired,
  mapHeight: PropTypes.number,
  rowPadding: PropTypes.number
}

module.exports = MapRowComponent;
<commit_msg>missed this on combine map row.<commit_after>var React = require('react');

var MapWrapper = require('./MapWrapper');
var ProjectMapWrapper = require('./ProjectMapWrapper');
var MapLayerToggleWrapper = require('./MapLayerToggleWrapper');
var SearchMapWrapper = require('./SearchMapWrapper');

var PropTypes = React.PropTypes;

var MapRowComponent = React.createClass({
  componentDidMount: function() {
    //do something
  },
  propTypes: {
    latitude: PropTypes.number.isRequired,
    longitude: PropTypes.number.isRequired,
    zoom: PropTypes.number.isRequired,
    handleCenter: PropTypes.func.isRequired,
    handleMapClick: PropTypes.func.isRequired,
    handleMapMoveEnd: PropTypes.func.isRequired,
    mapHeight: PropTypes.number.isRequired,
    rowPadding: PropTypes.number.isRequired
  },
  getDefaultProps: function() {
    return {
      mapHeight: 300,
      rowPadding: 1
    };
  },

  getInitialState: function () {
    return {
      latitude: this.props.latitude,
      longitude: this.props.longitude,
      rowPadding: this.props.rowPadding,
      zoom: this.props.zoom
    }
  },
  render: function() {
    return (

          <MapWrapper HandleMapZoomEnd={this.props.HandleMapZoomEnd} handleMapMoveEnd={this.props.handleMapMoveEnd} zoom={this.props.zoom} latitude={this.props.latitude} longitude={this.props.longitude} handleMapClick={this.props.handleMapClick} rowPadding={this.props.rowPadding} mapHeight={this.props.mapHeight} />

                  <MapLayerToggleWrapper    />

                  <ProjectMapWrapper />

    );
  }

});

module.exports = MapRowComponent;
<|endoftext|>


<commit_before>'use babel'
'use strict'

const request = require('request')
const WebSocketClient = require('websocket').client
const WsBridge = require('./wsBridge')
const configurationManager = require('./configurationManager')

const THERA_CONFIG_URL = 'http://127.0.0.1:PORT/theraConfig'
const MOCK_CONFIG_URL = 'http://localhost:PORT/mockConfig'
const wsAddress = 'http://127.0.0.1:PORT'
const pageQRCode = 'http://127.0.0.1:PORT/ipAddressPort'

const WS_SEND_MSG = 'weex-run:ws-send-msg'
const HTTP_SEND_MSG = 'weex-run:http-send-msg'
const WS_CONNECTED = 'weex-run:ws-connected'

const SERVER_STATUS_STARTING = "starting"
const SERVER_STATUS_RUNNING = "running"
const SERVER_STATUS_SHUTDOWN = "shutdown"

const fsp = require('fs-promise')
const path = require('path')
const fs = require('fs')

module.exports = class PreviewClient {
  constructor () {
    atom.commands.add(atom.commands.rootNode, WS_SEND_MSG, (content) => this.wsSend(content))
    atom.commands.add(atom.commands.rootNode, HTTP_SEND_MSG, (content) => this.httpSend(content.detail))

    let projectPath = atom.project.getDirectories()[0].path
    this.mockConfigPath = path.join(projectPath, 'mock', 'config.json')
    this.launchConfigPath = path.join(projectPath, '.thera', 'launch.json')
  }

  start (fileToRun, protocol) {
    return new Promise((resolve, reject) => {
      // let curEditor = atom.workspace.getActiveTextEditor()
      // let filePath = fileToRun || curEditor.getPath()

      this.sendLaunchConfig()
      this.sendMockConfig()
    })
  }

  requestQRCode () {
    return new Promise((resolve, reject) => {
      const imgURL = pageQRCode.replace('PORT', atom.config.get('weex-run.dumplingPort'))
      request(imgURL, (err, response, body) => {
        if (err || response.statusCode !== 200) {
          console.error(`request qr image ${imgURL} error`, err)
          resolve(undefined)
        } else {
          resolve(body)
        }
      })
    })
  }

  httpSend (content) {
    let {url, method, headers, body} = content
    let payload = {
      url: url,
      method: method,
      headers: headers,
      body: JSON.stringify(body)
    }

    console.log(`send request ${url}`)
    if (payload.method === 'POST') console.log(`send request body ${JSON.stringify(body)}`)
    request(payload, (err, response, body) => {
      if (err || response.statusCode !== 200) {
        if (err) console.error(err)
      } else {
        console.log(body)
      }
    })
  }

  wsSend (content) {
    this.wsClient = this.wsClient || new WebSocketClient()
    if (this.wsClient.connection) {
      console.log(`ws send msg ${JSON.stringify(content.detail)}`)
      this.wsClient.connection.sendUTF(JSON.stringify(content.detail))
    } else {
      console.error('not connected yet')
    }
  }

  wsConnect () {
    var self = this
    return new Promise((resolve, reject) => {
      // If connection is valid, needn't do any thing.
      if (this.wsClient && this.wsClient.connection && this.wsClient.connection.state === 'open') {
        console.log('Thera connection to dumpling is alive. Needn\'t reconnection.');
        resolve();
        return;
      }
      // Clear current connection state.
      if (this.wsClient && this.wsClient.connection) {
        this.wsClient.connection.close('Normally closed.')
        this.wsClient = null
      }
      this.wsClient = this.wsClient || new WebSocketClient()
      this.wsClient.on('connectFailed', (error) => {
        reject(error)
        console.log(`Connect error: ${error.toString()}`)
      })
      this.wsClient.on('connect', (connection) => {
        console.log('websocket connected')
        self.wsClient.connection = connection

        connection.on('error', (error) => {
          console.log(`Connection error: ${error.toString()}`)

          // reconnect after delay
          setTimeout(() => {
            console.log('reconnecting websocket after 3 seconds')

            self.wsClient.connect(
              wsAddress.replace('PORT', atom.config.get('weex-run.dumplingPort')),
              undefined,
              undefined,
              {'from': 'thera'}
            )
          }, 1000 * 3)
        })

        connection.on('close', (error) => {
          console.log('Connection closed: ' + error.toString())
          notifyServerStatus.apply(self, [SERVER_STATUS_SHUTDOWN])
        })

        // dispatch message
        connection.on('message', onRecvCallback.bind(self))
        atom.commands.dispatch(atom.views.getView(atom.workspace), WS_CONNECTED)
        this.watchLaunchConfig()
        this.watchMockConfig()
        resolve()
      })

      function onRecvCallback (message) {
        // console.log(message)
        this.wsBridge.dispatch(message)
      }

      function onSendCallback (message) {
        // console.log(message)
        this.wsClient.connection.sendUTF(message)
      }

      function notifyServerStatus(status) {
        console.log('Server status: ' + status)
        atom.commands.dispatch(atom.views.getView(atom.workspace), 'thera-live-server:shutdown')
      }

      if (this.wsBridge) {
        this.wsBridge.dispose()
        this.wsBridge = null
      }
      this.wsBridge = new WsBridge(onSendCallback.bind(this))

      // connect with header from:thera
      this.wsClient.connect(
        wsAddress.replace('PORT', atom.config.get('weex-run.dumplingPort')),
        undefined,
        undefined,
        {'from': 'thera'}
      )
    })
  }

  watchLaunchConfig() {
    let projectPath = atom.project.getDirectories()[0].path
    var launchConfigPath = path.join(projectPath, '.thera', 'launch.json')
    fs.watchFile(launchConfigPath, (curr, prev) => {
      this.sendLaunchConfig()
    })
  }

  sendLaunchConfig() {
    fsp.readJson(this.launchConfigPath)
        .then((configObject) => {
          let options = {
            url: THERA_CONFIG_URL.replace('PORT', atom.config.get('weex-run.dumplingPort')),
            method: 'POST',
            headers: {
              'Content-Type': 'application/json'
            },
            body: JSON.stringify({
              'message': 'theraConfig',
              'data': configObject
            })
          }

          request(options, (err, response, body) => {
            if (err) reject(err)
            else {
              console.log('start monitor file...')
              console.log(body)
            }
          })
        })
  }

  watchMockConfig(){
      // watch config changes
      fs.watchFile(this.mockConfigPath, (curr, prev) => {
        this.sendMockConfig()
      })
  }

  sendMockConfig(){
    fsp.readJson(this.mockConfigPath)
        .then((mockJSON) => {
          let msg = this.parseMockConfig(mockJSON)
          this.httpSend(msg)
        })
  }

  parseMockConfig (config) {
    let projectPath = atom.project.getDirectories()[0].path
    var body
    if (config) {
      body = {
        'message': 'mock',
        'data': {
          'mockData': [],
          'mockModules': []
        }
      }
      if(config.hasOwnProperty('mockData')){
        config.mockData.forEach((data) => {
          let mockUnit = {}
          for (var key in data) {
            if (data.hasOwnProperty(key)) {
              mockUnit[key] = data[key].replace('${workspaceRoot}', projectPath)
            }
          }
          body.data.mockData.push(mockUnit)
        })
      }
      if(config.hasOwnProperty('mockModules')) {
        config.mockModules.forEach((module) => {
          body.data.mockModules.push(module)
        })
      }
    }

    let payload = {
      url: MOCK_CONFIG_URL.replace('PORT', atom.config.get('weex-run.dumplingPort')),
      method: 'POST',
      headers: {'Content-Type': 'application/json'},
      body: body
    }

    return payload
  }

}
<commit_msg>change launch config to son<commit_after>'use babel'
'use strict'

const request = require('request')
const WebSocketClient = require('websocket').client
const WsBridge = require('./wsBridge')
const configurationManager = require('./configurationManager')

const THERA_CONFIG_URL = 'http://127.0.0.1:PORT/theraConfig'
const MOCK_CONFIG_URL = 'http://localhost:PORT/mockConfig'
const wsAddress = 'http://127.0.0.1:PORT'
const pageQRCode = 'http://127.0.0.1:PORT/ipAddressPort'

const WS_SEND_MSG = 'weex-run:ws-send-msg'
const HTTP_SEND_MSG = 'weex-run:http-send-msg'
const WS_CONNECTED = 'weex-run:ws-connected'

const SERVER_STATUS_STARTING = "starting"
const SERVER_STATUS_RUNNING = "running"
const SERVER_STATUS_SHUTDOWN = "shutdown"

const fsp = require('fs-promise')
const path = require('path')
const fs = require('fs')

module.exports = class PreviewClient {
  constructor () {
    atom.commands.add(atom.commands.rootNode, WS_SEND_MSG, (content) => this.wsSend(content))
    atom.commands.add(atom.commands.rootNode, HTTP_SEND_MSG, (content) => this.httpSend(content.detail))

    let projectPath = atom.project.getDirectories()[0].path
    this.mockConfigPath = path.join(projectPath, 'mock', 'config.json')
    this.launchConfigPath = path.join(projectPath, '.thera', 'launch.json')
  }

  start (fileToRun, protocol) {
    return new Promise((resolve, reject) => {
      // let curEditor = atom.workspace.getActiveTextEditor()
      // let filePath = fileToRun || curEditor.getPath()

      this.sendLaunchConfig()
      this.sendMockConfig()
    })
  }

  requestQRCode () {
    return new Promise((resolve, reject) => {
      const imgURL = pageQRCode.replace('PORT', atom.config.get('weex-run.dumplingPort'))
      request(imgURL, (err, response, body) => {
        if (err || response.statusCode !== 200) {
          console.error(`request qr image ${imgURL} error`, err)
          resolve(undefined)
        } else {
          resolve(body)
        }
      })
    })
  }

  httpSend (content) {
    let {url, method, headers, body} = content
    let payload = {
      url: url,
      method: method,
      headers: headers,
      body: JSON.stringify(body)
    }

    console.log(`send request ${url}`)
    if (payload.method === 'POST') console.log(`send request body ${JSON.stringify(body)}`)
    request(payload, (err, response, body) => {
      if (err || response.statusCode !== 200) {
        if (err) console.error(err)
      } else {
        console.log(body)
      }
    })
  }

  wsSend (content) {
    this.wsClient = this.wsClient || new WebSocketClient()
    if (this.wsClient.connection) {
      console.log(`ws send msg ${JSON.stringify(content.detail)}`)
      this.wsClient.connection.sendUTF(JSON.stringify(content.detail))
    } else {
      console.error('not connected yet')
    }
  }

  wsConnect () {
    var self = this
    return new Promise((resolve, reject) => {
      // If connection is valid, needn't do any thing.
      if (this.wsClient && this.wsClient.connection && this.wsClient.connection.state === 'open') {
        console.log('Thera connection to dumpling is alive. Needn\'t reconnection.');
        resolve();
        return;
      }
      // Clear current connection state.
      if (this.wsClient && this.wsClient.connection) {
        this.wsClient.connection.close('Normally closed.')
        this.wsClient = null
      }
      this.wsClient = this.wsClient || new WebSocketClient()
      this.wsClient.on('connectFailed', (error) => {
        reject(error)
        console.log(`Connect error: ${error.toString()}`)
      })
      this.wsClient.on('connect', (connection) => {
        console.log('websocket connected')
        self.wsClient.connection = connection

        connection.on('error', (error) => {
          console.log(`Connection error: ${error.toString()}`)

          // reconnect after delay
          setTimeout(() => {
            console.log('reconnecting websocket after 3 seconds')

            self.wsClient.connect(
              wsAddress.replace('PORT', atom.config.get('weex-run.dumplingPort')),
              undefined,
              undefined,
              {'from': 'thera'}
            )
          }, 1000 * 3)
        })

        connection.on('close', (error) => {
          console.log('Connection closed: ' + error.toString())
          notifyServerStatus.apply(self, [SERVER_STATUS_SHUTDOWN])
        })

        // dispatch message
        connection.on('message', onRecvCallback.bind(self))
        atom.commands.dispatch(atom.views.getView(atom.workspace), WS_CONNECTED)
        this.watchLaunchConfig()
        this.watchMockConfig()
        resolve()
      })

      function onRecvCallback (message) {
        // console.log(message)
        this.wsBridge.dispatch(message)
      }

      function onSendCallback (message) {
        // console.log(message)
        this.wsClient.connection.sendUTF(message)
      }

      function notifyServerStatus(status) {
        console.log('Server status: ' + status)
        atom.commands.dispatch(atom.views.getView(atom.workspace), 'thera-live-server:shutdown')
      }

      if (this.wsBridge) {
        this.wsBridge.dispose()
        this.wsBridge = null
      }
      this.wsBridge = new WsBridge(onSendCallback.bind(this))

      // connect with header from:thera
      this.wsClient.connect(
        wsAddress.replace('PORT', atom.config.get('weex-run.dumplingPort')),
        undefined,
        undefined,
        {'from': 'thera'}
      )
    })
  }

  watchLaunchConfig() {
    let projectPath = atom.project.getDirectories()[0].path
    var launchConfigPath = path.join(projectPath, '.thera', 'launch.json')
    fs.watchFile(launchConfigPath, (curr, prev) => {
      this.sendLaunchConfig()
    })
  }

  sendLaunchConfig() {
    configurationManager.getConfig()
        .then((configObject) => {
          let options = {
            url: THERA_CONFIG_URL.replace('PORT', atom.config.get('weex-run.dumplingPort')),
            method: 'POST',
            headers: {
              'Content-Type': 'application/json'
            },
            body: JSON.stringify({
              'message': 'theraConfig',
              'data': configObject
            })
          }

          request(options, (err, response, body) => {
            if (err) reject(err)
            else {
              console.log('start monitor file...')
              console.log(body)
            }
          })
        })
  }

  watchMockConfig(){
      // watch config changes
      fs.watchFile(this.mockConfigPath, (curr, prev) => {
        this.sendMockConfig()
      })
  }

  sendMockConfig(){
    fsp.readJson(this.mockConfigPath)
        .then((mockJSON) => {
          let msg = this.parseMockConfig(mockJSON)
          this.httpSend(msg)
        })
  }

  parseMockConfig (config) {
    let projectPath = atom.project.getDirectories()[0].path
    var body
    if (config) {
      body = {
        'message': 'mock',
        'data': {
          'mockData': [],
          'mockModules': []
        }
      }
      if(config.hasOwnProperty('mockData')){
        config.mockData.forEach((data) => {
          let mockUnit = {}
          for (var key in data) {
            if (data.hasOwnProperty(key)) {
              mockUnit[key] = data[key].replace('${workspaceRoot}', projectPath)
            }
          }
          body.data.mockData.push(mockUnit)
        })
      }
      if(config.hasOwnProperty('mockModules')) {
        config.mockModules.forEach((module) => {
          body.data.mockModules.push(module)
        })
      }
    }

    let payload = {
      url: MOCK_CONFIG_URL.replace('PORT', atom.config.get('weex-run.dumplingPort')),
      method: 'POST',
      headers: {'Content-Type': 'application/json'},
      body: body
    }

    return payload
  }

}
<|endoftext|>


<commit_before>/**
 * TagSpaces - universal file and folder organizer
 * Copyright (C) 2017-present TagSpaces UG (haftungsbeschraenkt)
 *
 * This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU Affero General Public License (version 3) as
 * published by the Free Software Foundation.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU Affero General Public License for more details.
 *
 * You should have received a copy of the GNU Affero General Public License
 * along with this program.  If not, see <https://www.gnu.org/licenses/>.
 *
 * @flow
 */

import React from 'react';
import { DragSource } from 'react-dnd';
import DragItemTypes from './DragItemTypes';
import TagContainer from './TagContainer';
import { type TagGroup, type Tag } from '../reducers/taglibrary';

type Props = {
  tag: Tag,
  key: string,
  defaultTextColor: string,
  defaultBackgroundColor: string,
  tagGroup: TagGroup,
  handleTagMenu: (event: Object, tag: Tag, tagGroup: TagGroup) => void, // TODO refactor
  handleTagMenu: (event: Object, tag: Tag, entryPath: string) => void,
  handleRemoveTag: (event: Object, tag: Tag) => void,
  isDragging: boolean,
  tagMode?: 'default' | 'display' | 'remove',
  entryPath?: string,
  connectDragSource: (param: Object) => void,
  deleteIcon: Object
};

const boxSource = {
  beginDrag(props) {
    // console.log('beginDrag', props);
    return {
      tagId: props.tag.id,
      tag: props.tag,
      sourceTagGroupId: props.tagGroup.uuid
    };
  },

  endDrag(props, monitor) {
    const item = monitor.getItem();
    const dropResult = monitor.getDropResult();

    // console.log('DropRESULT: ', dropResult);
    // console.log('item: ', item);
    if (dropResult && dropResult.tagGroupId && dropResult.tagGroupId !== item.sourceTagGroupId) {
      // console.log(`Dropped ${item.tagId} from ${item.sourceTagGroupId} into ${dropResult.tagGroupId}!`);
      props.moveTag(item.tagId, item.sourceTagGroupId, dropResult.tagGroupId);
    } else if (dropResult && dropResult.entryPath) {
      // console.log(`Dropped item: ${item.tag.title} onto file: ${dropResult.entryPath}!`);
      props.addTags([dropResult.entryPath], [item.tag]);
    }
  }
};

class TagContainerDnd extends React.Component<Props> {
  render() {
    const {
      key,
      tag,
      defaultTextColor,
      defaultBackgroundColor,
      tagGroup,
      entryPath,
      handleTagMenu,
      deleteIcon
    } = this.props;
    const { isDragging, connectDragSource, tagMode } = this.props;

    return connectDragSource(

        <TagContainer
          key={key}
          defaultTextColor={defaultTextColor}
          defaultBackgroundColor={defaultBackgroundColor}
          tag={tag}
          tagGroup={tagGroup}
          handleTagMenu={handleTagMenu}
          deleteIcon={deleteIcon}
          tagMode={tagMode}
          entryPath={entryPath}
          isDragging={isDragging}
        />

    );
  }
}

export default DragSource(DragItemTypes.TAG, boxSource, (connect, monitor) => ({
  connectDragSource: connect.dragSource(),
  isDragging: monitor.isDragging()
}))(TagContainerDnd);
<commit_msg>fix drag preview (#774)<commit_after>/**
 * TagSpaces - universal file and folder organizer
 * Copyright (C) 2017-present TagSpaces UG (haftungsbeschraenkt)
 *
 * This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU Affero General Public License (version 3) as
 * published by the Free Software Foundation.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU Affero General Public License for more details.
 *
 * You should have received a copy of the GNU Affero General Public License
 * along with this program.  If not, see <https://www.gnu.org/licenses/>.
 *
 * @flow
 */

import React from 'react';
import { DragSource } from 'react-dnd';
import type { ConnectDragPreview, ConnectDragSource } from 'react-dnd';
// import { getEmptyImage } from 'react-dnd-html5-backend';
import DragItemTypes from './DragItemTypes';
import TagContainer from './TagContainer';
import { type TagGroup, type Tag } from '../reducers/taglibrary';

type Props = {
  tag: Tag,
  key: string,
  defaultTextColor: string,
  defaultBackgroundColor: string,
  tagGroup: TagGroup,
  handleTagMenu: (event: Object, tag: Tag, tagGroup: TagGroup) => void, // TODO refactor
  handleTagMenu: (event: Object, tag: Tag, entryPath: string) => void,
  handleRemoveTag: (event: Object, tag: Tag) => void,
  isDragging: boolean,
  tagMode?: 'default' | 'display' | 'remove',
  entryPath?: string,
  connectDragSource: ConnectDragSource,
  connectDragPreview: ConnectDragPreview,
  deleteIcon: Object
};

const boxSource = {
  beginDrag(props) {
    // console.log('beginDrag', props);
    return {
      tagId: props.tag.id,
      tag: props.tag,
      sourceTagGroupId: props.tagGroup.uuid
    };
  },

  endDrag(props, monitor) {
    const item = monitor.getItem();
    const dropResult = monitor.getDropResult();

    // console.log('DropRESULT: ', dropResult);
    // console.log('item: ', item);
    if (dropResult && dropResult.tagGroupId && dropResult.tagGroupId !== item.sourceTagGroupId) {
      // console.log(`Dropped ${item.tagId} from ${item.sourceTagGroupId} into ${dropResult.tagGroupId}!`);
      props.moveTag(item.tagId, item.sourceTagGroupId, dropResult.tagGroupId);
    } else if (dropResult && dropResult.entryPath) {
      // console.log(`Dropped item: ${item.tag.title} onto file: ${dropResult.entryPath}!`);
      props.addTags([dropResult.entryPath], [item.tag]);
    }
  }
};

class TagContainerDnd extends React.Component<Props> {
  componentDidMount() {
    const xml = '<svg version="1.1" height="25" width="100" xmlns="http://www.w3.org/2000/svg">' +
      '<g>' +
      '<rect x="0" y="0" rx="5" ry="5" width="100%" height="100%" style="fill:' + this.props.tag.color + ';opacity:0.5" />' +
      '<text x="50%" y="55%" dominant-baseline="middle" text-anchor="middle" fill="' + this.props.tag.textcolor + '">' + this.props.tag.title + '</text>' +
      '</g>' +
      '</svg>';
    const img = new Image();
    img.src = `data:image/svg+xml;charset=utf-8,${xml.replace(/(\r\n|\n|\r)/gm, '')}`;
    img.onload = () => this.props.connectDragPreview(img, { anchorX: 1, anchorY: 0 });
    // this.props.connectDragPreview(getEmptyImage(), { captureDraggingState: true });
  }

  render() {
    const {
      key,
      tag,
      defaultTextColor,
      defaultBackgroundColor,
      tagGroup,
      entryPath,
      handleTagMenu,
      deleteIcon
    } = this.props;
    const { isDragging, connectDragSource, tagMode } = this.props;

    // return connectDragPreview({
    return connectDragSource(

        <TagContainer
          key={key}
          defaultTextColor={defaultTextColor}
          defaultBackgroundColor={defaultBackgroundColor}
          tag={tag}
          tagGroup={tagGroup}
          handleTagMenu={handleTagMenu}
          deleteIcon={deleteIcon}
          tagMode={tagMode}
          entryPath={entryPath}
          isDragging={isDragging}
        />
      );
    // , { dropEffect: 'copy' });
    // }, { anchorX: 0, anchorY: 0 });
  }
}

export default DragSource(DragItemTypes.TAG, boxSource, (connect, monitor) => ({
  connectDragSource: connect.dragSource(),
  connectDragPreview: connect.dragPreview(),
  isDragging: monitor.isDragging()
}))(TagContainerDnd);
<|endoftext|>