<commit_before>/* @flow */
import React, { PureComponent } from 'react';
import { TextInput } from 'react-native';
import { FormattedMessage } from 'react-intl';

import type { Context, LocalizableText, Style } from '../types';
import { nullFunction } from '../nullObjects';
import { HALF_COLOR, BORDER_COLOR } from '../styles';

type Props = {
  style?: Style,
  placeholder: LocalizableText,
  clearButton: boolean,
  onChangeText: (text: string) => void,
  textInputRef: (component: any) => void,
};

type State = {
  isFocused: boolean,
};

/**
 * A light abstraction over the standard TextInput component
 * that allows us to seamlessly provide internationalization
 * capabilities and also style the component depending on
 * the platform the app is running on.
 *
 * @prop [style] - Style applied to the TextInput component.
 * @prop [placeholder] - Text to be shown when no value is entered.
 * @prop onChangeText - Event called when text is edited.
 * @prop textInputRef - Callback used to pass a reference to the
 *   wrapped TextInput to parent component.
 */
export default class Input extends PureComponent<Props, State> {
  context: Context;
  props: Props;
  state: State;
  textInput: TextInput;

  static contextTypes = {
    styles: () => null,
  };

  static defaultProps = {
    placeholder: {},
  };

  static defaultProps = {
    restProps: [],
    clearButton: false,
    onChangeText: nullFunction,
    textInputRef: nullFunction,
  };

  state = {
    isFocused: false,
  };

  handleClear = () => {
    const { onChangeText } = this.props;
    if (onChangeText) {
      onChangeText('');
    }
    this.textInput.clear();
  };

  handleFocus = () => {
    this.setState({
      isFocused: true,
    });
  };

  handleBlur = () => {
    this.setState({
      isFocused: false,
    });
  };

  render() {
    const { styles } = this.context;
    const { style, placeholder, textInputRef, ...restProps } = this.props;
    const { isFocused } = this.state;
    const placeholderMessage = placeholder.text || placeholder;

    return (
      <FormattedMessage
        id={placeholderMessage}
        defaultMessage={placeholderMessage}
        values={placeholder.values}
      >
        {text => (
          <TextInput
            style={[styles.input, style]}
            placeholder={text}
            placeholderTextColor={HALF_COLOR}
            underlineColorAndroid={isFocused ? BORDER_COLOR : HALF_COLOR}
            onFocus={this.handleFocus}
            onBlur={this.handleBlur}
            ref={(component: any) => {
              this.textInput = component;
              if (textInputRef) {
                textInputRef(component);
              }
            }}
            {...restProps}
          />
        )}
      </FormattedMessage>
    );
  }
}
<commit_msg>cleanup: Remove unused 'clearButton' from `Input`<commit_after>/* @flow */
import React, { PureComponent } from 'react';
import { TextInput } from 'react-native';
import { FormattedMessage } from 'react-intl';

import type { Context, LocalizableText, Style } from '../types';
import { nullFunction } from '../nullObjects';
import { HALF_COLOR, BORDER_COLOR } from '../styles';

type Props = {
  style?: Style,
  placeholder: LocalizableText,
  onChangeText: (text: string) => void,
  textInputRef: (component: any) => void,
};

type State = {
  isFocused: boolean,
};

/**
 * A light abstraction over the standard TextInput component
 * that allows us to seamlessly provide internationalization
 * capabilities and also style the component depending on
 * the platform the app is running on.
 *
 * @prop [style] - Style applied to the TextInput component.
 * @prop [placeholder] - Text to be shown when no value is entered.
 * @prop onChangeText - Event called when text is edited.
 * @prop textInputRef - Callback used to pass a reference to the
 *   wrapped TextInput to parent component.
 */
export default class Input extends PureComponent<Props, State> {
  context: Context;
  props: Props;
  state: State;
  textInput: TextInput;

  static contextTypes = {
    styles: () => null,
  };

  static defaultProps = {
    placeholder: {},
  };

  static defaultProps = {
    restProps: [],
    onChangeText: nullFunction,
    textInputRef: nullFunction,
  };

  state = {
    isFocused: false,
  };

  handleClear = () => {
    const { onChangeText } = this.props;
    if (onChangeText) {
      onChangeText('');
    }
    this.textInput.clear();
  };

  handleFocus = () => {
    this.setState({
      isFocused: true,
    });
  };

  handleBlur = () => {
    this.setState({
      isFocused: false,
    });
  };

  render() {
    const { styles } = this.context;
    const { style, placeholder, textInputRef, ...restProps } = this.props;
    const { isFocused } = this.state;
    const placeholderMessage = placeholder.text || placeholder;

    return (
      <FormattedMessage
        id={placeholderMessage}
        defaultMessage={placeholderMessage}
        values={placeholder.values}
      >
        {text => (
          <TextInput
            style={[styles.input, style]}
            placeholder={text}
            placeholderTextColor={HALF_COLOR}
            underlineColorAndroid={isFocused ? BORDER_COLOR : HALF_COLOR}
            onFocus={this.handleFocus}
            onBlur={this.handleBlur}
            ref={(component: any) => {
              this.textInput = component;
              if (textInputRef) {
                textInputRef(component);
              }
            }}
            {...restProps}
          />
        )}
      </FormattedMessage>
    );
  }
}
<|endoftext|>


<commit_before>/*jshint white: false, strict: false, plusplus: false, onevar: false,
  nomen: false */
/*global define: false, console: false, window: false, setTimeout: false */

define( function( require ) {

    var Graph = function() {

        var _nodes = {};
        var _adjacencies = {};
        var _descendants = {};
        var _roots = {};
        var _visited = {};
        var that = this;

        this.nodes = _nodes;
        this.adjacencies = _adjacencies;
        this.descendants = _descendants;
        this.roots = _roots;

        this.link = function( src, snk ) {

            if( !_nodes[src] ) {
                _nodes[src] = true;
                _descendants[src] = 0;
            }
            if( !_nodes[snk] ) {
                _nodes[snk] = true;
                _descendants[snk] = 0;
                _roots[snk] = true;
            }

            if( !_adjacencies[snk] ) {
                _adjacencies[snk] = {};
            }

            _adjacencies[snk][src] = true;
            ++ _descendants[src];
            if( _roots[src] ) {
                delete _roots[src];
            }
        };

        this.unlink = function( src, snk ) {

            if( _adjacencies[snk] && _adjacencies[snk][src] ) {
                delete _adjacencies[snk][src];
                -- _descendants[src];
                if( !Object.keys( _adjacencies[snk] ).length ) {
                    delete _adjacencies[snk];
                }
                if( !_descendants[src] ) {
                    _roots[src] = true;
                }
            }

        };

        this.insert = function( node ) {

            if( !_nodes[node] ) {
                _nodes[node] = true;
                _descendants[node] = 0;
                _roots[node] = true;
            }

        };

        this.remove = function( node ) {

            var edges = _adjacencies[node] || {};

            for( var src in edges ) {
                that.unlink( src, node );
            }

            if( _nodes[node] ) {
                delete _nodes[node];
                delete _descendants[node];
            }

        };

        this.sort = function() {

            var L = [],
            S = Object.keys( _roots ),
            V = {};

            var visit = function( snk ) {
                if( V[snk] ) {
                    throw 'directed cycle detected';
                }
                V[snk] = true;

                if( !_visited[snk] ) {
                    _visited[snk] = true;
                    var edges = _adjacencies[snk];
                    for( var src in edges ) {
                        if( !_nodes[src] ) {  // This might be a dangling edge
                            delete edges[src];
                        } else {
                            visit( src );
                        }
                    }
                    L.push( snk );
                }
            };

            for( var i = 0, l = S.length; i < l; ++ i ) {
                visit( S[i] );
                V = {};
            }

            _visited = {};

            if( L.length < Object.keys( _nodes ).length ) {
                throw 'directed cycle detected';
            }

            return L;

        };

    };

});<commit_msg>Moved some variables around. Removed some exposed internals. Added a clear() method.<commit_after>/*jshint white: false, strict: false, plusplus: false, onevar: false,
  nomen: false */
/*global define: false, console: false, window: false, setTimeout: false */

define( function( require ) {

    var Graph = function() {

        var _nodes = {};
        var _adjacencies = {};
        var _descendants = {};
        var _roots = {};
        var that = this;

        this.link = function( src, snk ) {

            if( !_nodes[src] ) {
                _nodes[src] = true;
                _descendants[src] = 0;
            }
            if( !_nodes[snk] ) {
                _nodes[snk] = true;
                _descendants[snk] = 0;
                _roots[snk] = true;
            }

            if( !_adjacencies[snk] ) {
                _adjacencies[snk] = {};
            }

            _adjacencies[snk][src] = true;
            ++ _descendants[src];
            if( _roots[src] ) {
                delete _roots[src];
            }
        };

        this.unlink = function( src, snk ) {

            if( _adjacencies[snk] && _adjacencies[snk][src] ) {
                delete _adjacencies[snk][src];
                -- _descendants[src];
                if( !Object.keys( _adjacencies[snk] ).length ) {
                    delete _adjacencies[snk];
                }
                if( !_descendants[src] ) {
                    _roots[src] = true;
                }
            }

        };

        this.insert = function( node ) {

            if( !_nodes[node] ) {
                _nodes[node] = true;
                _descendants[node] = 0;
                _roots[node] = true;
            }

        };

        this.remove = function( node ) {

            var edges = _adjacencies[node] || {};

            for( var src in edges ) {
                that.unlink( src, node );
            }

            if( _nodes[node] ) {
                delete _nodes[node];
                delete _descendants[node];
            }

        };

        this.clear = function() {
            _nodes = {};
            _adjacencies = {};
            _descendants = {};
            _roots = {};
        };

        this.sort = function() {

            var L = [],
            S = Object.keys( _roots ),
            V = {},
            visited = {};

            var visit = function( snk ) {
                if( V[snk] ) {
                    throw 'directed cycle detected';
                }
                V[snk] = true;

                if( !visited[snk] ) {
                    visited[snk] = true;
                    var edges = _adjacencies[snk];
                    for( var src in edges ) {
                        if( !_nodes[src] ) {  // This might be a dangling edge
                            delete edges[src];
                        } else {
                            visit( src );
                        }
                    }
                    L.push( snk );
                }
            };

            for( var i = 0, l = S.length; i < l; ++ i ) {
                visit( S[i] );
                V = {};
            }

            if( L.length < Object.keys( _nodes ).length ) {
                throw 'directed cycle detected';
            }

            return L;

        };

    };

});<|endoftext|>


<commit_before>let moment = require('moment');
let _ = require('underscore');
let im = {
	isImm: (p) => typeof p === 'object' ? Object.isFrozen(p) : true
};

let { pow, floor, log, min, max, abs, LN10 } = Math;

// period = {
//	years : ,
//	months : ,
//	weeks : ,
//	days : ,
//	total: *nb days*
// }
let processPeriod = function(period){

	if(im.isImm(period)){return period;}

	if(typeof period === 'number'){ // ms
		period = makePeriod(moment.duration(period));
	}

	for(let t in {years: true, months: true, weeks: true, days: true}){
		if(period[t] === null || period[t] === undefined){
			period[t] = 0;
		}
	}
	if(period.total === null || period.total === undefined){
		period.total = moment.duration(period).asDays();
	}

	if(period.total > 15 && !period.offset){
		period.offset = true;
	}

	return period;
};

let makePeriod = function(msOrDur){
	let dur = ( !!msOrDur.years ) ? msOrDur : moment.duration(msOrDur);
	return {
		years: dur.years(),
		months: dur.months(),
		weeks: dur.weeks(),
		days: dur.days() - 7 * dur.weeks(),
		total: dur.asDays()
	};
};

let fetchFormat = function(p){
	p = processPeriod(p);
	if(p.years !== 0){
		return {
			string: 'YYYY',
			pref: ''
		};
	}else if(p.months >= 6){
		return {
			string: 'S/YY', // ce format n'existe pas, il est géré par la fonction qui appelle
			pref: 'S'
		};
	}else if(p.months >= 3){
		return {
			string: 'Q/YY',
			pref: 'T'
		};
	}else if(p.months !== 0){
		return {
			string: 'MM/YY',
			pref: ''
		};
	}else if(p.weeks !== 0){
		return {
			string: 'DD/MM/YY',
			pref: ''
		};
	}else{
		return {
			string: 'DD/MM/YY',
			pref: ''
		};
	}
};

let roundDownPeriod = function(p){

	let make = (lab,val) => {
		return {
			label: lab,
			val: val
		};
	};

	let out = {};
	if(p.years > 2){
		out = make('years',max(floor(p.years)/10,1));
	}else if(p.total >= moment.duration({months: 6}).asDays()){
		out = make('months', 6);
	}else if(p.total >= moment.duration({months: 3}).asDays()){
		out = make('months', 3);
	}else if(p.total >= moment.duration({months: 1}).asDays()){
		out = make('months', 1);
	}else if(p.total >= moment.duration({weeks: 2}).asDays()){
		out = make('weeks', 2);
	}else if(p.total >= moment.duration({weeks: 1}).asDays()){
		out = make('weeks', 1);
	}else{
		out = make('days', 1);
	}

	return out;
};

let roundUpPeriod = function(p){

	let make = (lab,val) => {
		return {
			label: lab,
			val: val
		};
	};

	let out = {};
	if(p.years !== 0){
		out = make('years',floor(p.years) + 1);
	}else if(p.months >= 6){
		out = make('years', 1);
	}else if(p.months >= 3){
		out = make('months', 6);
	}else if(p.months >= 1){
		out = make('months', 3);
	}else if(p.weeks >= 2){
		out = make('months', 1);
	}else if(p.weeks >= 1){
		out = make('weeks', 2);
	}else if(p.days >= 1){
		out = make('weeks', 1);
	}else{
		out = make('days', 1);
	}

	return out;
};

// round period of sale order of magnitude
// down by default
let roundPeriod = function(per,type){

	let p = {
		years: per.years,
		months: per.months,
		weeks: per.weeks,
		days: per.days,
		total: per.total
	};

	type = type || 'down';

	let types = ['years','months','weeks','days'];

	let makeThis = (type,n) => {
		for(let t = 0; t < types.length; t++){
			if(type === types[t]){
				continue;
			}
			p[types[t]] = 0;
		}
		p[type] = n;
	};

	// 1/10 of years or 1
	// 6, 3 or 1 month(s)
	// 2 or 1 week(s)
	// 1 day
	let round = ( type === 'up' ) ? roundUpPeriod(p) : roundDownPeriod(p);
	makeThis(round.label,round.val);

	p.total = moment.duration(p).asDays();

	return p;
};

let closestUp = function(date,per){
	let out = closestDown(date,per);
	while(out.getTime() <= date.getTime()){
		out = m.add(out,per);
	}

	return out;
};

// beginning of period
let closestDown = function(date,per){
	// day
	if(per.days !== 0){
		return moment(date).subtract(per.days,'days').startOf('day').toDate();
	}
	// start of week: Sunday
	if(per.weeks !== 0){
		 return moment(date).subtract(per.weeks,'weeks').startOf("week").toDate();
	}
	// start of month
	if(per.months !== 0){
		let month = 0;
		while(month < date.getMonth()){
			month += per.months;
		}
		month -= per.months;
		return new Date(date.getFullYear(),month,1);
	}
	// start of year
	if(per.years !== 0){
		return new Date(date.getFullYear(),0,1);
	}
};

let sameDoP = function(dop1,dop2){
	let b1 = dop1 instanceof Date;
	let b2 = dop2 instanceof Date;
	if(b1 !== b2){
		return null;
	}

	return (b1)?'date':'period';
};

let dateGT      = (d1,d2) => d1.getTime() > d2.getTime();

let dateLT      = (d1,d2) => d1.getTime() < d2.getTime();

let dateEQ      = (d1,d2) => d1.getTime() === d2.getTime();

let periodGT    = (p1,p2) => p1.total > p2.total;

let periodLT    = (p1,p2) => p1.total < p2.total;

let periodEQ    = (p1,p2) => p1.total === p2.total;

let greaterThan = (v1,v2,type) => type === 'date' ? dateGT(v1,v2) : periodGT(v1,v2);

let lowerThan   = (v1,v2,type) => type === 'date' ? dateLT(v1,v2) : periodLT(v1,v2);

let equal       = (v1,v2,type) => type === 'date' ? dateEQ(v1,v2) : periodEQ(v1,v2);

let addPer      = (p1,p2) => makePeriod(moment.duration(processPeriod(p1)).add(moment.duration(p2)));

let subPer      = (p1,p2) => makePeriod(moment.duration(processPeriod(p1)).subtract(moment.duration(p2)));

let m = {};

// date / distance methods
m.orderMag = (dop) => floor(log( ( dop instanceof Date ) ? dop.getTime() : moment.duration({days: processPeriod(dop).total}).asMilliseconds() ) / LN10);

m.orderMagValue = function(last,first){
	// start of next year
	let nextfst = new Date(first.getFullYear() + 1,0,1);
	if(m.lowerThan(nextfst,last)){
		return nextfst;
	}

	// start of next semester
	if(first.getMonth() < 7){
		nextfst = new Date(first.getFullYear(),7,1);
		if(m.lowerThan(nextfst,last)){
			return nextfst;
		}
	}

	// start of next trimester
	let mm = first.getMonth() + 3 - first.getMonth() % 3;
	nextfst = new Date(first.getFullYear(),mm,1);
	if(m.lowerThan(nextfst,last)){
		return nextfst;
	}

	// start of next month
	nextfst = new Date(first.getFullYear(),first.getMonth() + 1,1);
	if(m.lowerThan(nextfst,last)){
		return nextfst;
	}

	// start of next half-month
	if(first.getDate() < 15){
		nextfst = new Date(first.getFullYear(),first.getMonth(),15);
		if(m.lowerThan(nextfst,last)){
			return nextfst;
		}
	}

	// start of next quarter-month (as 7 days)
	let dd = first.getDate() + 7 - first.getDate() % 7;
	nextfst = new Date(first.getFullYear(),first.getMonth(),dd);
	if(m.lowerThan(nextfst,last)){
		return nextfst;
	}

	// next day
	return new Date(first.getFullYear(),first.getMonth(),first.getDate() + 1);
};

m.orderMagDist = (r) => makePeriod(pow(10,m.orderMag(r)));

m.roundUp      = (p) => roundPeriod(p,'up');

m.roundDown    = (p) => roundPeriod(p,'down');

m.multiply     = (p,f) => makePeriod(moment.duration({days: processPeriod(p).total * f}));

m.divide       = (p,f) => makePeriod(moment.duration({days: processPeriod(p).total / f}));

m.increase     = (p1,p2) => makePeriod(moment.duration({days: processPeriod(p1).total + processPeriod(p2).total}));

m.offset = function(p){
	p = processPeriod(p);

	let offsetMe = (per) => {
		if(per.years !== 0){
			return makePeriod(moment.duration({months: 6}));
		}else{
			return m.divide(p,2);
		}
	};

	return (p.offset )? offsetMe(p) : makePeriod(0) ;
};

// date methods
m.closestRoundUp   = (ref,per) => closestUp(ref, roundPeriod(per) );

m.closestRoundDown = (ref,per) => closestDown(ref, roundPeriod(per) );

m.closestRound     = (ref,om,type) => (type === 'up')? m.closestRoundUp(ref,om):m.closestRoundDown(ref,om);

m.min              = (dates) => new Date(min.apply(null,_.map(dates, (date) => {return date.getTime();})));

m.max              = (dates) => new Date(max.apply(null,_.map(dates, (date) => {return date.getTime();})));

m.label = function(date,period){
	let format = fetchFormat(period);
	let out = '';
	if(format.pref === 'S'){
		out = (date.getMonth() > 5)? '2/' : '1/';
		out += moment(date).format('YY');
	}else{
		out = moment(date).format(format.string);
	}
	return format.pref + out;
};

// date & period methods
m.add = function(dop,p){
	// preprocess period
	p = processPeriod(p);

	return (dop instanceof Date) ? moment(dop)
		.add(p.years,'years')
		.add(p.months,'months')
		.add(p.weeks,'weeks')
		.add(p.days,'days').toDate():
		addPer(dop,p);
};

m.subtract = function(dop,p){
	// preprocess period
	p = processPeriod(p);

	return (dop instanceof Date) ? moment(dop)
		.subtract(p.years,'years')
		.subtract(p.months,'months')
		.subtract(p.weeks,'weeks')
		.subtract(p.days,'days').toDate():
		subPer(dop,p);
};

m.distance = (d1,d2) => makePeriod(abs(d1.getTime() - d2.getTime()));

m.greaterThan = function(dop1,dop2){
	let sd = sameDoP(dop1,dop2);
	if(sd === null){
		throw 'Error in dateMgr: trying to compare a Date with a Period';
	}
	return greaterThan(dop1,dop2,sd);
};

m.lowerThan = function(dop1,dop2){
	let sd = sameDoP(dop1,dop2);
	if(sd === null){
		throw 'Error in dateMgr: trying to compare a Date with a Period';
	}
	return lowerThan(dop1,dop2,sd);
};

m.equal = function(dop1,dop2){
	let sd = sameDoP(dop1,dop2);
	if(sd === null){
		throw 'Error in dateMgr: trying to compare a Date with a Period';
	}
	return equal(dop1,dop2,sd);
};

// managements
m.getValue = (dop) => (dop instanceof Date) ? dop.getTime() : moment.duration(dop).asMilliseconds();

m.extraTicks = function(step,start,end, already){
	let out = [];
	let startYear = start.getFullYear();
	let lastYear = end.getFullYear();
	// every year, whatever happens
	for(let ye = startYear; ye <= lastYear; ye++){
		let dat = new Date(ye,0,1);
		let idx = _.findIndex(already,(a) => m.equal(a.position,dat));
		if(idx !== -1){
			already[idx].grid = {};
			already[idx].grid.show = true;
			continue;
		}
		if(m.lowerThan(start,dat) && m.lowerThan(dat,end)){
			out.push({
				position: dat,
				offset: {
					along: 0,
					perp: 0
				},
				label: '',
				show: false,
				extra: true,
				grid: {
					show: true,
					color: 'LightGray',
					width: 0.5
				}
			});
		}
	}
	return out;
};

m.smallestStep = () => makePeriod(moment.duration({days: 1}));

m.makePeriod   = (per) => processPeriod(per);

// in years
m.value        = (num) => new Date(num * 1000 * 3600 * 24 * 365);

// in years
m.step         = (num) => makePeriod({years: num});

// no
m.labelize     = () => false;

//
m.defaultSpan  = () => makePeriod(moment.duration({months: 6}));

m.labelF = 0.75;

m.type = 'date';

module.exports = m;
<commit_msg>add/subtract date, last day of month management<commit_after>let moment = require('moment');
let _ = require('underscore');
let im = {
	isImm: (p) => typeof p === 'object' ? Object.isFrozen(p) : true
};

let { pow, floor, log, min, max, abs, LN10 } = Math;

// period = {
//	years : ,
//	months : ,
//	weeks : ,
//	days : ,
//	total: *nb days*
// }
let processPeriod = function(period, fac){
	fac = fac || 1;

	// don't touch immutable
	if(im.isImm(period)){
		return period;
	}

	if(typeof period === 'number'){ // ms
		period = makePeriod(moment.duration(period));
	}

	for(let t in {years: true, months: true, weeks: true, days: true}){
		if(period[t] === null || period[t] === undefined){
			period[t] = 0;
		}else{
			period[t] *= fac;
		}
	}
	if(period.total === null || period.total === undefined){
		period.total = moment.duration(period).asDays();
	}

	if(period.total > 15 && !period.offset){
		period.offset = true;
	}

	return period;
};

let makePeriod = function(msOrDur){
	let dur = ( !!msOrDur.years ) ? msOrDur : moment.duration(msOrDur);
	return {
		years: dur.years(),
		months: dur.months(),
		weeks: dur.weeks(),
		days: dur.days() - 7 * dur.weeks(),
		total: dur.asDays()
	};
};

let fetchFormat = function(p){
	p = processPeriod(p);
	if(p.years !== 0){
		return {
			string: 'YYYY',
			pref: ''
		};
	}else if(p.months >= 6){
		return {
			string: 'S/YY', // ce format n'existe pas, il est géré par la fonction qui appelle
			pref: 'S'
		};
	}else if(p.months >= 3){
		return {
			string: 'Q/YY',
			pref: 'T'
		};
	}else if(p.months !== 0){
		return {
			string: 'MM/YY',
			pref: ''
		};
	}else if(p.weeks !== 0){
		return {
			string: 'DD/MM/YY',
			pref: ''
		};
	}else{
		return {
			string: 'DD/MM/YY',
			pref: ''
		};
	}
};

let roundDownPeriod = function(p){

	let make = (lab,val) => {
		return {
			label: lab,
			val: val
		};
	};

	let out = {};
	if(p.years > 2){
		out = make('years',max(floor(p.years)/10,1));
	}else if(p.total >= moment.duration({months: 6}).asDays()){
		out = make('months', 6);
	}else if(p.total >= moment.duration({months: 3}).asDays()){
		out = make('months', 3);
	}else if(p.total >= moment.duration({months: 1}).asDays()){
		out = make('months', 1);
	}else if(p.total >= moment.duration({weeks: 2}).asDays()){
		out = make('weeks', 2);
	}else if(p.total >= moment.duration({weeks: 1}).asDays()){
		out = make('weeks', 1);
	}else{
		out = make('days', 1);
	}

	return out;
};

let roundUpPeriod = function(p){

	let make = (lab,val) => {
		return {
			label: lab,
			val: val
		};
	};

	let out = {};
	if(p.years !== 0){
		out = make('years',floor(p.years) + 1);
	}else if(p.months >= 6){
		out = make('years', 1);
	}else if(p.months >= 3){
		out = make('months', 6);
	}else if(p.months >= 1){
		out = make('months', 3);
	}else if(p.weeks >= 2){
		out = make('months', 1);
	}else if(p.weeks >= 1){
		out = make('weeks', 2);
	}else if(p.days >= 1){
		out = make('weeks', 1);
	}else{
		out = make('days', 1);
	}

	return out;
};

// round period of sale order of magnitude
// down by default
let roundPeriod = function(per,type){

	let p = {
		years: per.years,
		months: per.months,
		weeks: per.weeks,
		days: per.days,
		total: per.total
	};

	type = type || 'down';

	let types = ['years','months','weeks','days'];

	let makeThis = (type,n) => {
		for(let t = 0; t < types.length; t++){
			if(type === types[t]){
				continue;
			}
			p[types[t]] = 0;
		}
		p[type] = n;
	};

	// 1/10 of years or 1
	// 6, 3 or 1 month(s)
	// 2 or 1 week(s)
	// 1 day
	let round = ( type === 'up' ) ? roundUpPeriod(p) : roundDownPeriod(p);
	makeThis(round.label,round.val);

	p.total = moment.duration(p).asDays();

	return p;
};

let closestUp = function(date,per){
	let out = closestDown(date,per);
	while(out.getTime() <= date.getTime()){
		out = m.add(out,per);
	}

	return out;
};

// beginning of period
let closestDown = function(date,per){
	// day
	if(per.days !== 0){
		return moment(date).subtract(per.days,'days').startOf('day').toDate();
	}
	// start of week: Sunday
	if(per.weeks !== 0){
		 return moment(date).subtract(per.weeks,'weeks').startOf("week").toDate();
	}
	// start of month
	if(per.months !== 0){
		let month = 0;
		while(month < date.getMonth()){
			month += per.months;
		}
		month -= per.months;
		return new Date(date.getFullYear(),month,1);
	}
	// start of year
	if(per.years !== 0){
		return new Date(date.getFullYear(),0,1);
	}
};

let sameDoP = function(dop1,dop2){
	let b1 = dop1 instanceof Date;
	let b2 = dop2 instanceof Date;
	if(b1 !== b2){
		return null;
	}

	return (b1)?'date':'period';
};

let dateGT      = (d1,d2) => d1.getTime() > d2.getTime();

let dateLT      = (d1,d2) => d1.getTime() < d2.getTime();

let dateEQ      = (d1,d2) => d1.getTime() === d2.getTime();

let periodGT    = (p1,p2) => p1.total > p2.total;

let periodLT    = (p1,p2) => p1.total < p2.total;

let periodEQ    = (p1,p2) => p1.total === p2.total;

let greaterThan = (v1,v2,type) => type === 'date' ? dateGT(v1,v2) : periodGT(v1,v2);

let lowerThan   = (v1,v2,type) => type === 'date' ? dateLT(v1,v2) : periodLT(v1,v2);

let equal       = (v1,v2,type) => type === 'date' ? dateEQ(v1,v2) : periodEQ(v1,v2);

let addPer      = (p1,p2) => makePeriod(moment.duration(processPeriod(p1)).add(moment.duration(p2)));

let m = {};

// date / distance methods
m.orderMag = (dop) => floor(log( ( dop instanceof Date ) ? dop.getTime() : moment.duration({days: processPeriod(dop).total}).asMilliseconds() ) / LN10);

m.orderMagValue = function(last,first){
	// start of next year
	let nextfst = new Date(first.getFullYear() + 1,0,1);
	if(m.lowerThan(nextfst,last)){
		return nextfst;
	}

	// start of next semester
	if(first.getMonth() < 7){
		nextfst = new Date(first.getFullYear(),7,1);
		if(m.lowerThan(nextfst,last)){
			return nextfst;
		}
	}

	// start of next trimester
	let mm = first.getMonth() + 3 - first.getMonth() % 3;
	nextfst = new Date(first.getFullYear(),mm,1);
	if(m.lowerThan(nextfst,last)){
		return nextfst;
	}

	// start of next month
	nextfst = new Date(first.getFullYear(),first.getMonth() + 1,1);
	if(m.lowerThan(nextfst,last)){
		return nextfst;
	}

	// start of next half-month
	if(first.getDate() < 15){
		nextfst = new Date(first.getFullYear(),first.getMonth(),15);
		if(m.lowerThan(nextfst,last)){
			return nextfst;
		}
	}

	// start of next quarter-month (as 7 days)
	let dd = first.getDate() + 7 - first.getDate() % 7;
	nextfst = new Date(first.getFullYear(),first.getMonth(),dd);
	if(m.lowerThan(nextfst,last)){
		return nextfst;
	}

	// next day
	return new Date(first.getFullYear(),first.getMonth(),first.getDate() + 1);
};

m.orderMagDist = (r) => makePeriod(pow(10,m.orderMag(r)));

m.roundUp      = (p) => roundPeriod(p,'up');

m.roundDown    = (p) => roundPeriod(p,'down');

m.multiply     = (p,f) => makePeriod(moment.duration({days: processPeriod(p).total * f}));

m.divide       = (p,f) => makePeriod(moment.duration({days: processPeriod(p).total / f}));

m.increase     = (p1,p2) => makePeriod(moment.duration({days: processPeriod(p1).total + processPeriod(p2).total}));

m.offset = function(p){
	p = processPeriod(p);

	let offsetMe = (per) => {
		if(per.years !== 0){
			return makePeriod(moment.duration({months: 6}));
		}else{
			return m.divide(p,2);
		}
	};

	return (p.offset )? offsetMe(p) : makePeriod(0) ;
};

// date methods
m.closestRoundUp   = (ref,per) => closestUp(ref, roundPeriod(per) );

m.closestRoundDown = (ref,per) => closestDown(ref, roundPeriod(per) );

m.closestRound     = (ref,om,type) => (type === 'up')? m.closestRoundUp(ref,om):m.closestRoundDown(ref,om);

m.min              = (dates) => new Date(min.apply(null,_.map(dates, (date) => {return date.getTime();})));

m.max              = (dates) => new Date(max.apply(null,_.map(dates, (date) => {return date.getTime();})));

m.label = function(date,period){
	let format = fetchFormat(period);
	let out = '';
	if(format.pref === 'S'){
		out = (date.getMonth() > 5)? '2/' : '1/';
		out += moment(date).format('YY');
	}else{
		out = moment(date).format(format.string);
	}
	return format.pref + out;
};

let addMonth = (d,m) => moment(d).add(1,'days').add(m, 'months').add(-1,'days').toDate();

// deal with periods >= months
// to have last day of month stay last day of month
let addDate = (d,p) => {
	let { years, months } = p;

	return moment(addMonth(d, 12 * years + months))
		.add(p.weeks,'weeks')
		.add(p.days,'days').toDate();
};

// date & period methods
m.add = function(dop,p){
	// preprocess period
	p = processPeriod(p);

	return dop instanceof Date ? addDate(dop,p) : addPer(dop,p);
};

m.subtract = function(dop,p){
	// preprocess period
	p = processPeriod(p, -1);
	return m.add(dop,p);

};

m.distance = (d1,d2) => makePeriod(abs(d1.getTime() - d2.getTime()));

m.greaterThan = function(dop1,dop2){
	let sd = sameDoP(dop1,dop2);
	if(sd === null){
		throw 'Error in dateMgr: trying to compare a Date with a Period';
	}
	return greaterThan(dop1,dop2,sd);
};

m.lowerThan = function(dop1,dop2){
	let sd = sameDoP(dop1,dop2);
	if(sd === null){
		throw 'Error in dateMgr: trying to compare a Date with a Period';
	}
	return lowerThan(dop1,dop2,sd);
};

m.equal = function(dop1,dop2){
	let sd = sameDoP(dop1,dop2);
	if(sd === null){
		throw 'Error in dateMgr: trying to compare a Date with a Period';
	}
	return equal(dop1,dop2,sd);
};

// managements
m.getValue = (dop) => (dop instanceof Date) ? dop.getTime() : moment.duration(dop).asMilliseconds();

m.extraTicks = function(step,start,end, already){
	let out = [];
	let startYear = start.getFullYear();
	let lastYear = end.getFullYear();
	// every year, whatever happens
	for(let ye = startYear; ye <= lastYear; ye++){
		let dat = new Date(ye,0,1);
		let idx = _.findIndex(already,(a) => m.equal(a.position,dat));
		if(idx !== -1){
			already[idx].grid = {};
			already[idx].grid.show = true;
			continue;
		}
		if(m.lowerThan(start,dat) && m.lowerThan(dat,end)){
			out.push({
				position: dat,
				offset: {
					along: 0,
					perp: 0
				},
				label: '',
				show: false,
				extra: true,
				grid: {
					show: true,
					color: 'LightGray',
					width: 0.5
				}
			});
		}
	}
	return out;
};

m.smallestStep = () => makePeriod(moment.duration({days: 1}));

m.makePeriod   = (per) => processPeriod(per);

// in years
m.value        = (num) => new Date(num * 1000 * 3600 * 24 * 365);

// in years
m.step         = (num) => makePeriod({years: num});

// no
m.labelize     = () => false;

//
m.defaultSpan  = () => makePeriod(moment.duration({months: 6}));

m.labelF = 0.75;

m.type = 'date';

module.exports = m;
<|endoftext|>


<commit_before>import { createStore, applyMiddleware, compose, combineReducers } from 'redux'
import thunk from 'redux-thunk'

export function combine (states) {
  const middleware = applyMiddleware(thunk)
  const enhancers = [middleware]

  if (process.env.NODE_ENV === 'development') {
    const devTools = require('./devtools')
    const devToolsExtension = devTools.default.instrument()
    enhancers.push(devToolsExtension)
  }

  const enhancer = compose(...enhancers)
  const rootReducer = combineReducers(states)
  const store = createStore(rootReducer, enhancer)

  getStore = () => store

  for (const i in states) {
    states[i].dispatch = (type, payload) => store.dispatch({ type, payload })
    states[i].getState = (stateName) => {
      if (stateName === true) return store.getState()
      else if (typeof stateName === 'string') return store.getState()[stateName]

      return store.getState()[states[i]._name]
    }
  }

  // if (module.onReload) {
  //   module.onReload(() => {
  //     // store.replaceReducer(rootReducer)
  //     return true
  //   })
  // }

  return store
}

export function getStore(){}

export function getDevToolsState () {}

export function setDevToolsState () {}
<commit_msg>Use react-router-redux middleware required for action-based navigation<commit_after>import { createStore, applyMiddleware, compose, combineReducers } from 'redux'
import { routerMiddleware } from 'react-router-redux'
import { browserHistory } from 'react-router'
import thunk from 'redux-thunk'

export function combine (states) {
  const middleware = applyMiddleware(thunk, routerMiddleware(browserHistory))
  const enhancers = [middleware]

  if (process.env.NODE_ENV === 'development') {
    const devTools = require('./devtools')
    const devToolsExtension = devTools.default.instrument()
    enhancers.push(devToolsExtension)
  }

  const enhancer = compose(...enhancers)
  const rootReducer = combineReducers(states)
  const store = createStore(rootReducer, enhancer)

  getStore = () => store

  for (const i in states) {
    states[i].dispatch = (type, payload) => store.dispatch({ type, payload })
    states[i].getState = (stateName) => {
      if (stateName === true) return store.getState()
      else if (typeof stateName === 'string') return store.getState()[stateName]

      return store.getState()[states[i]._name]
    }
  }

  return store
}

export function getStore(){}

export function getDevToolsState () {}

export function setDevToolsState () {}
<|endoftext|>


<commit_before>'use strict';

import 'core-js/fn/object/entries';

import createStream from 'cyclejs-stream';
import mapValues from 'map-values';
import mergeObjects from 'merge-object';
import getParametersNames from 'get-parameter-names';

function _makeInjectFn(streamWithDependencies) {
    return function inject(...inputObjects) {
        let combinedInputObject = inputObjects.length === 1 ?
            inputObjects[0] :
            inputObjects.reduce(mergeObjects, {});

        for(let [ , { dependencies, stream } ] of Object.entries(streamWithDependencies)) {
            let streamDependencies = dependencies.map((dependencyName) => {
                if(!combinedInputObject.hasOwnProperty(dependencyName)) {
                    throw new Error(`Dependency "${dependencyName}" is not available!`);
                }

                // shareReplay is here for circural dependent streams
                // otherwise there will be endless loop of subscribing
                return combinedInputObject[dependencyName].shareReplay(1);
            });

            stream.inject(...streamDependencies);
        }

        if (inputObjects.length === 1) {
            return inputObjects[0];
        } else if (inputObjects.length > 1) {
            return inputObjects;
        } else {
            return null;
        }
    };
}

function _makeDisposeFn(group) {
    return function dispose() {
        for (let [ , stream ] of Object.entries(group)) {
            stream.dispose();
        }
    };
}

export default function createGroup(definition) {
    let streamsDefs = ('function' === typeof definition) ?
        definition() :
        definition;

    if(('object' !== typeof streamsDefs) ||
        (streamsDefs === null) ||
        Array.isArray(streamsDefs)
    ) {
        throw new TypeError('Cycle Streams Group must be an object.');
    }

    if (this instanceof createGroup) { // jshint ignore:line
        throw new Error('Cannot use `new` operator on `createStreamsGroup()`, it is not a constructor.');
    }

    let streamsWithDeps = mapValues(streamsDefs, (streamFn) => ({
        dependencies: getParametersNames(streamFn),
        stream: createStream(streamFn)
    }));

    let group = mapValues(streamsWithDeps, ({ stream }) => stream);

    // add `inject` and `dispose` as not enumerable properties to make them
    // not visible for `each` function
    Object.defineProperty(group, 'inject', {
        enumerable: false,
        value: _makeInjectFn(streamsWithDeps)
    });

    Object.defineProperty(group, 'dispose', {
        enumerable: false,
        value: _makeDisposeFn(group)
    });

    Object.freeze(group);

    return group;
}

<commit_msg>remove underscores from beginning and end of function parameters names<commit_after>'use strict';

import 'core-js/fn/object/entries';

import createStream from 'cyclejs-stream';
import mapValues from 'map-values';
import mergeObjects from 'merge-object';
import getParametersNames from 'get-parameter-names';

function _removeUnderscores(string) {
    let result = /^_*(.*[^_])_*$/.exec(string);

    return result ? result[1] : string;
}

function _makeInjectFn(streamWithDependencies) {
    return function inject(...inputObjects) {
        let combinedInputObject = inputObjects.length === 1 ?
            inputObjects[0] :
            inputObjects.reduce(mergeObjects, {});

        for(let [ , { dependencies, stream } ] of Object.entries(streamWithDependencies)) {
            let streamDependencies = dependencies.map((dependencyName) => {
                if(!combinedInputObject.hasOwnProperty(dependencyName)) {
                    throw new Error(`Dependency "${dependencyName}" is not available!`);
                }

                // shareReplay is here for circural dependent streams
                // otherwise there will be endless loop of subscribing
                return combinedInputObject[dependencyName].shareReplay(1);
            });

            stream.inject(...streamDependencies);
        }

        if (inputObjects.length === 1) {
            return inputObjects[0];
        } else if (inputObjects.length > 1) {
            return inputObjects;
        } else {
            return null;
        }
    };
}

function _makeDisposeFn(group) {
    return function dispose() {
        for (let [ , stream ] of Object.entries(group)) {
            stream.dispose();
        }
    };
}

export default function createGroup(definition) {
    let streamsDefs = ('function' === typeof definition) ?
        definition() :
        definition;

    if(('object' !== typeof streamsDefs) ||
        (streamsDefs === null) ||
        Array.isArray(streamsDefs)
    ) {
        throw new TypeError('Cycle Streams Group must be an object.');
    }

    if (this instanceof createGroup) { // jshint ignore:line
        throw new Error('Cannot use `new` operator on `createStreamsGroup()`, it is not a constructor.');
    }

    let streamsWithDeps = mapValues(streamsDefs, (streamFn) => ({
        dependencies: getParametersNames(streamFn)
            .map(_removeUnderscores),
        stream: createStream(streamFn)
    }));

    let group = mapValues(streamsWithDeps, ({ stream }) => stream);

    // add `inject` and `dispose` as not enumerable properties to make them
    // not visible for `each` function
    Object.defineProperty(group, 'inject', {
        enumerable: false,
        value: _makeInjectFn(streamsWithDeps)
    });

    Object.defineProperty(group, 'dispose', {
        enumerable: false,
        value: _makeDisposeFn(group)
    });

    Object.freeze(group);

    return group;
}

<|endoftext|>


<commit_before>// ==UserScript==
// @name         arxiv.ninja
// @description  reorder papers on arXiv new pages
// @version      0.1.2
// @include      https://arxiv.org/list/*/new*
// @include      https://arxiv.org/list/*/recent*
// @include      https://arxiv.org/list/*/pastweek*
// @grant        none
// ==/UserScript==

// Original script: Iain Murray, August 2018
// Updates to include preferences: Dan Foreman-Mackey, January 2019

(function(){

  // Save the current state of the preferences dictionary
  var executed = false;
  var counter = {};
  var storage = chrome.storage.local;

  // Storage for the word vectors
  var word_vectors = {};

  // Request the current preferences dictionary
  //storage.remove(['ninja'], function(result) {
  //  var error = chrome.runtime.lastError;
  //  if (error) {
  //      console.error(error);
  //  }
  //});
  storage.get(['ninja'], function(result) {
    console.log('Value currently is: ')
    console.log(result.ninja);
    if (result.ninja) {
      counter = result.ninja;
    } else {
      counter = {};
    }
    executed = true;

    // Compute the distance between the user preferences and these papers
    var scores = [];
    for (var key in word_vectors) {
      var vec = word_vectors[key];
      var score = 0;
      for (var stem in vec) {
        var orig = counter[stem];
        if (orig) score += vec[stem] * orig;
      }
      scores[key] = score;
    }

    // Re-order the ninja divs based on the score
    reorder_divs(scores);
  });

  // This function intercepts clicks and if that click is on an abstract
  // listing, update the user preferences and save it to local storage
  document.onclick = function (e) {
    e = e ||  window.event;
    var element = e.target || e.srcElement;

    if (element.nodeName == 'A') {
      // Check to make sure that the request to local storage executed
      if (!executed) {
        console.log("something went wrong!");
        return true;
      }

      // Find the parent ninja block
      var url = element.href;
      element = element.parentElement;
      while (element && element.getAttribute('class') != 'ninja') {
        element = element.parentElement;
      }

      // If it wasn't found, this was a different link. Proceed
      if (!element || element.getAttribute('class') != 'ninja') {
        return true;
      }

      var arxiv_id = element.id;
      var vec = word_vectors[arxiv_id];
      for (var stem in vec) {
        if (counter[stem]) counter[stem] += vec[stem];
        else counter[stem] = vec[stem]
      }

      // Save the updated results to local storage
      storage.set({ninja: counter}, function() {
        window.location = url;
      });

      return false;
    }
  };

  // Loop over all the visible abstract blocks and tokenize the title and
  // (if available) the abstract into a vector of stemmed word counts
  var compute_word_vectors = function () {
    var blocks = document.getElementsByTagName('dl');
    var I = blocks.length;
    for (i = 0; i < I; ++i) {
      // Extract parts of this block
      var titles = blocks[i].getElementsByTagName('dt');
      var bits = blocks[i].getElementsByTagName('dd');

      // Wrap all the papers in a common block div
      var N = titles.length;
      for (var j = 0; j < N; ++j) {
        var div = document.createElement('div');
        div.appendChild(titles[j]);
        div.appendChild(bits[j]);

        // Work out the arXiv ID
        var arxiv_id = null;
        var links = div.getElementsByTagName('a');
        for (var k = 0; k < links.length; ++k) {
          var link = links[k];
          if (link.title == 'Abstract') {
            arxiv_id = link.innerText;
            break;
          }
        }

        // Add the div back into the list
        div.setAttribute('class', 'ninja');
        div.setAttribute('id', arxiv_id);
        blocks[i].insertBefore(div, titles[j]);

        // Parse the div text for word stems
        var this_counter = {};
        var pars = div.getElementsByClassName('mathjax');
        var L = pars.length;
        for (var l = 0; l < L; ++l) {
          var words = pars[l].innerText.toLowerCase()
                            .replace(/[^\w\s]|_/g, "") // only alphanumeric
                            .replace(/[0-9]/g, "")     // no numbers
                            .split(/\s+/);             // split by whitespace
          var K = words.length;
          for (var k = 0; k < K; ++k) {
            if (!window.stopwords.includes(words[k])) {
              var stem = stemmer(words[k]);
              if (stem.length) {
                if (this_counter[stem]) this_counter[stem] += 1;
                else this_counter[stem] = 1;
              }
            }
          }
        }

        // Update the local list of word vectors
        word_vectors[arxiv_id] = this_counter;
      }
    }
  };

  // Based on the word vectors computed in 'compute_word_vectors', compute
  // the normalized tf-idf representation of each block
  var compute_tf_idf_vectors = function () {
    // Compute idf
    var nd = 0;
    var df = {};
    for (var key in word_vectors) {
      nd += 1;
      for (var stem in word_vectors[key]) {
        if (df[stem]) df[stem] += 1;
        else df[stem] = 1;
      }
    }

    // Compute the tf-idf scores
    for (var key in word_vectors) {
      var vec = word_vectors[key];
      var total = 0;
      for (var stem in word_vectors[key]) {
        var tf_idf = vec[stem] * Math.log(nd / df[stem]);
        vec[stem] = tf_idf;
        total += tf_idf * tf_idf;
      }
      total = Math.sqrt(total);

      // Normalize the vectors
      for (var stem in word_vectors[key]) {
        vec[stem] /= total;
      }
    }
  };

  // Reorder the ninja divs based the preference scores
  var reorder_divs = function (scores) {
    var links = document.getElementsByTagName('a');
    var links_length = links.length;
    var blocks = document.getElementsByTagName('dl');
    var blocks_length = blocks.length
    for (var block_id = 0; block_id < blocks_length; ++block_id) {
      var block = blocks[block_id];
      var divs = block.getElementsByClassName('ninja');
      var old_first_name = divs[0].childNodes[0].childNodes[0].getAttribute('name');
      console.log(old_first_name);
      var divs_length = divs.length;
      var sortable = [];
      for (var div_id = 0; div_id < divs_length; ++div_id) {
        var div = divs[div_id];
        sortable.push([scores[div.id], div]);
      }
      sortable = sortable.sort(function(a, b) { return b[0] - a[0]; });

      // Make sure that the top links are right
      for (var l = 0; l < links_length; ++l) {
        if (links[l].getAttribute('href') == '#' + old_first_name) {
          links[l].setAttribute('href', '#' + sortable[0][1].id);
        }
      }

      // Update the blocks
      for (var div_id = 0; div_id < divs_length; ++div_id) {
        block.appendChild(sortable[div_id][1]);
      }
    }
  };

  compute_word_vectors();
  compute_tf_idf_vectors();

})();
<commit_msg>badge<commit_after>// ==UserScript==
// @name         arxiv.ninja
// @description  reorder papers on arXiv new pages
// @version      0.1.2
// @include      https://arxiv.org/list/*/new*
// @include      https://arxiv.org/list/*/recent*
// @include      https://arxiv.org/list/*/pastweek*
// @grant        none
// ==/UserScript==

// Original script: Iain Murray, August 2018
// Updates to include preferences: Dan Foreman-Mackey, January 2019

(function(){

  // Save the current state of the preferences dictionary
  var executed = false;
  var counter = {};
  var storage = chrome.storage.local;

  // Storage for the word vectors
  var word_vectors = {};

  // Request the current preferences dictionary
  //storage.remove(['ninja'], function(result) {
  //  var error = chrome.runtime.lastError;
  //  if (error) {
  //      console.error(error);
  //  }
  //});
  storage.get(['ninja'], function(result) {
    console.log('Value ninja preferences are: ')
    console.log(result.ninja);
    if (result.ninja) {
      counter = result.ninja;
    } else {
      counter = {};
    }
    executed = true;

    // Compute the distance between the user preferences and these papers
    var scores = [];
    for (var key in word_vectors) {
      var vec = word_vectors[key];
      var score = 0;
      for (var stem in vec) {
        var orig = counter[stem];
        if (orig) score += vec[stem] * orig;
      }
      scores[key] = score;
    }

    // Re-order the ninja divs based on the score
    reorder_divs(scores);
  });

  // This function intercepts clicks and if that click is on an abstract
  // listing, update the user preferences and save it to local storage
  document.onclick = function (e) {
    e = e ||  window.event;
    var element = e.target || e.srcElement;

    if (element.nodeName == 'A') {
      // Check to make sure that the request to local storage executed
      if (!executed) {
        console.log("something went wrong!");
        return true;
      }

      // Find the parent ninja block
      var url = element.href;
      element = element.parentElement;
      while (element && element.getAttribute('class') != 'ninja') {
        element = element.parentElement;
      }

      // If it wasn't found, this was a different link. Proceed
      if (!element || element.getAttribute('class') != 'ninja') {
        return true;
      }

      var arxiv_id = element.id;
      var vec = word_vectors[arxiv_id];
      for (var stem in vec) {
        if (counter[stem]) counter[stem] += vec[stem];
        else counter[stem] = vec[stem]
      }

      // Save the updated results to local storage
      storage.set({ninja: counter}, function() {
        window.location = url;
      });

      return false;
    }
  };

  // Loop over all the visible abstract blocks and tokenize the title and
  // (if available) the abstract into a vector of stemmed word counts
  var compute_word_vectors = function () {
    var blocks = document.getElementsByTagName('dl');
    var I = blocks.length;
    for (i = 0; i < I; ++i) {
      // Extract parts of this block
      var titles = blocks[i].getElementsByTagName('dt');
      var bits = blocks[i].getElementsByTagName('dd');

      // Wrap all the papers in a common block div
      var N = titles.length;
      for (var j = 0; j < N; ++j) {
        var div = document.createElement('div');
        div.appendChild(titles[j]);
        div.appendChild(bits[j]);

        // Work out the arXiv ID
        var arxiv_id = null;
        var links = div.getElementsByTagName('a');
        for (var k = 0; k < links.length; ++k) {
          var link = links[k];
          if (link.title == 'Abstract') {
            arxiv_id = link.innerText;
            break;
          }
        }

        // Add the div back into the list
        div.setAttribute('class', 'ninja');
        div.setAttribute('id', arxiv_id);
        blocks[i].insertBefore(div, titles[j]);

        // Parse the div text for word stems
        var this_counter = {};
        var pars = div.getElementsByClassName('mathjax');
        var L = pars.length;
        for (var l = 0; l < L; ++l) {
          var words = pars[l].innerText.toLowerCase()
                            .replace(/[^\w\s]|_/g, "") // only alphanumeric
                            .replace(/[0-9]/g, "")     // no numbers
                            .split(/\s+/);             // split by whitespace
          var K = words.length;
          for (var k = 0; k < K; ++k) {
            if (!window.stopwords.includes(words[k])) {
              var stem = stemmer(words[k]);
              if (stem.length) {
                if (this_counter[stem]) this_counter[stem] += 1;
                else this_counter[stem] = 1;
              }
            }
          }
        }

        // Update the local list of word vectors
        word_vectors[arxiv_id] = this_counter;
      }
    }
  };

  // Based on the word vectors computed in 'compute_word_vectors', compute
  // the normalized tf-idf representation of each block
  var compute_tf_idf_vectors = function () {
    // Compute idf
    var nd = 0;
    var df = {};
    for (var key in word_vectors) {
      nd += 1;
      for (var stem in word_vectors[key]) {
        if (df[stem]) df[stem] += 1;
        else df[stem] = 1;
      }
    }

    // Compute the tf-idf scores
    for (var key in word_vectors) {
      var vec = word_vectors[key];
      var total = 0;
      for (var stem in word_vectors[key]) {
        var tf_idf = vec[stem] * Math.log(nd / df[stem]);
        vec[stem] = tf_idf;
        total += tf_idf * tf_idf;
      }
      total = Math.sqrt(total);

      // Normalize the vectors
      for (var stem in word_vectors[key]) {
        vec[stem] /= total;
      }
    }
  };

  // Reorder the ninja divs based the preference scores
  var reorder_divs = function (scores) {
    var links = document.getElementsByTagName('a');
    var links_length = links.length;
    var blocks = document.getElementsByTagName('dl');
    var blocks_length = blocks.length
    for (var block_id = 0; block_id < blocks_length; ++block_id) {
      var block = blocks[block_id];
      var divs = block.getElementsByClassName('ninja');
      var old_first_name = divs[0].childNodes[0].childNodes[0].getAttribute('name');
      var divs_length = divs.length;
      var sortable = [];
      for (var div_id = 0; div_id < divs_length; ++div_id) {
        var div = divs[div_id];
        sortable.push([scores[div.id], div]);
      }
      sortable = sortable.sort(function(a, b) { return b[0] - a[0]; });

      // Make sure that the top links are right
      for (var l = 0; l < links_length; ++l) {
        if (links[l].getAttribute('href') == '#' + old_first_name) {
          links[l].setAttribute('href', '#' + sortable[0][1].id);
        }
      }

      // Update the blocks
      var header = document.createElement('div');
      header.innerHTML = '<i>sorted by arXiv.ninja</i>';
      header.setAttribute('style', 'padding: 0 0 1em');
      block.appendChild(header);
      for (var div_id = 0; div_id < divs_length; ++div_id) {
        block.appendChild(sortable[div_id][1]);
      }
    }
  };

  compute_word_vectors();
  compute_tf_idf_vectors();

})();
<|endoftext|>


<commit_before>// CodeMirror, copyright (c) by Marijn Haverbeke and others
// Distributed under an MIT license: http://codemirror.net/LICENSE

(function() {
  var mode = CodeMirror.getMode({indentUnit: 2}, "javascript");
  function MT(name) { test.mode(name, mode, Array.prototype.slice.call(arguments, 1)); }

  MT("locals",
     "[keyword function] [def foo]([def a], [def b]) { [keyword var] [def c] [operator =] [number 10]; [keyword return] [variable-2 a] [operator +] [variable-2 c] [operator +] [variable d]; }");

  MT("comma-and-binop",
     "[keyword function](){ [keyword var] [def x] [operator =] [number 1] [operator +] [number 2], [def y]; }");

  MT("destructuring",
     "([keyword function]([def a], [[[def b], [def c] ]]) {",
     "  [keyword let] {[def d], [property foo]: [def c][operator =][number 10], [def x]} [operator =] [variable foo]([variable-2 a]);",
     "  [[[variable-2 c], [variable y] ]] [operator =] [variable-2 c];",
     "})();");

  MT("destructure_trailing_comma",
    "[keyword let] {[def a], [def b],} [operator =] [variable foo];",
    "[keyword let] [def c];"); // Parser still in good state?

  MT("class_body",
     "[keyword class] [def Foo] {",
     "  [property constructor]() {}",
     "  [property sayName]() {",
     "    [keyword return] [string-2 `foo${][variable foo][string-2 }oo`];",
     "  }",
     "}");

  MT("class",
     "[keyword class] [def Point] [keyword extends] [variable SuperThing] {",
     "  [keyword get] [property prop]() { [keyword return] [number 24]; }",
     "  [property constructor]([def x], [def y]) {",
     "    [keyword super]([string 'something']);",
     "    [keyword this].[property x] [operator =] [variable-2 x];",
     "  }",
     "}");

  MT("anonymous_class_expression",
     "[keyword const] [def Adder] [operator =] [keyword class] [keyword extends] [variable Arithmetic] {",
     "  [property add]([def a], [def b]) {}",
     "};");

  MT("named_class_expression",
     "[keyword const] [def Subber] [operator =] [keyword class] [def Subtract] {",
     "  [property sub]([def a], [def b]) {}",
     "};");

  MT("class_async_method",
     "[keyword class] [def Foo] {",
     "  [property sayName1]() {}",
     "  [keyword async] [property sayName2]() {}",
     "}");

  MT("import",
     "[keyword function] [def foo]() {",
     "  [keyword import] [def $] [keyword from] [string 'jquery'];",
     "  [keyword import] { [def encrypt], [def decrypt] } [keyword from] [string 'crypto'];",
     "}");

  MT("import_trailing_comma",
     "[keyword import] {[def foo], [def bar],} [keyword from] [string 'baz']")

  MT("const",
     "[keyword function] [def f]() {",
     "  [keyword const] [[ [def a], [def b] ]] [operator =] [[ [number 1], [number 2] ]];",
     "}");

  MT("for/of",
     "[keyword for]([keyword let] [def of] [keyword of] [variable something]) {}");

  MT("generator",
     "[keyword function*] [def repeat]([def n]) {",
     "  [keyword for]([keyword var] [def i] [operator =] [number 0]; [variable-2 i] [operator <] [variable-2 n]; [operator ++][variable-2 i])",
     "    [keyword yield] [variable-2 i];",
     "}");

  MT("quotedStringAddition",
     "[keyword let] [def f] [operator =] [variable a] [operator +] [string 'fatarrow'] [operator +] [variable c];");

  MT("quotedFatArrow",
     "[keyword let] [def f] [operator =] [variable a] [operator +] [string '=>'] [operator +] [variable c];");

  MT("fatArrow",
     "[variable array].[property filter]([def a] [operator =>] [variable-2 a] [operator +] [number 1]);",
     "[variable a];", // No longer in scope
     "[keyword let] [def f] [operator =] ([[ [def a], [def b] ]], [def c]) [operator =>] [variable-2 a] [operator +] [variable-2 c];",
     "[variable c];");

  MT("spread",
     "[keyword function] [def f]([def a], [meta ...][def b]) {",
     "  [variable something]([variable-2 a], [meta ...][variable-2 b]);",
     "}");

  MT("quasi",
     "[variable re][string-2 `fofdlakj${][variable x] [operator +] ([variable re][string-2 `foo`]) [operator +] [number 1][string-2 }fdsa`] [operator +] [number 2]");

  MT("quasi_no_function",
     "[variable x] [operator =] [string-2 `fofdlakj${][variable x] [operator +] [string-2 `foo`] [operator +] [number 1][string-2 }fdsa`] [operator +] [number 2]");

  MT("indent_statement",
     "[keyword var] [def x] [operator =] [number 10]",
     "[variable x] [operator +=] [variable y] [operator +]",
     "  [atom Infinity]",
     "[keyword debugger];");

  MT("indent_if",
     "[keyword if] ([number 1])",
     "  [keyword break];",
     "[keyword else] [keyword if] ([number 2])",
     "  [keyword continue];",
     "[keyword else]",
     "  [number 10];",
     "[keyword if] ([number 1]) {",
     "  [keyword break];",
     "} [keyword else] [keyword if] ([number 2]) {",
     "  [keyword continue];",
     "} [keyword else] {",
     "  [number 10];",
     "}");

  MT("indent_for",
     "[keyword for] ([keyword var] [def i] [operator =] [number 0];",
     "     [variable i] [operator <] [number 100];",
     "     [variable i][operator ++])",
     "  [variable doSomething]([variable i]);",
     "[keyword debugger];");

  MT("indent_c_style",
     "[keyword function] [def foo]()",
     "{",
     "  [keyword debugger];",
     "}");

  MT("indent_else",
     "[keyword for] (;;)",
     "  [keyword if] ([variable foo])",
     "    [keyword if] ([variable bar])",
     "      [number 1];",
     "    [keyword else]",
     "      [number 2];",
     "  [keyword else]",
     "    [number 3];");

  MT("indent_funarg",
     "[variable foo]([number 10000],",
     "    [keyword function]([def a]) {",
     "  [keyword debugger];",
     "};");

  MT("indent_below_if",
     "[keyword for] (;;)",
     "  [keyword if] ([variable foo])",
     "    [number 1];",
     "[number 2];");

  MT("indent_semicolonless_if",
     "[keyword function] [def foo]() {",
     "  [keyword if] ([variable x])",
     "    [variable foo]()",
     "}")

  MT("indent_semicolonless_if_with_statement",
     "[keyword function] [def foo]() {",
     "  [keyword if] ([variable x])",
     "    [variable foo]()",
     "  [variable bar]()",
     "}")

  MT("multilinestring",
     "[keyword var] [def x] [operator =] [string 'foo\\]",
     "[string bar'];");

  MT("scary_regexp",
     "[string-2 /foo[[/]]bar/];");

  MT("indent_strange_array",
     "[keyword var] [def x] [operator =] [[",
     "  [number 1],,",
     "  [number 2],",
     "]];",
     "[number 10];");

  MT("param_default",
     "[keyword function] [def foo]([def x] [operator =] [string-2 `foo${][number 10][string-2 }bar`]) {",
     "  [keyword return] [variable-2 x];",
     "}");

  MT("new_target",
     "[keyword function] [def F]([def target]) {",
     "  [keyword if] ([variable-2 target] [operator &&] [keyword new].[keyword target].[property name]) {",
     "    [keyword return] [keyword new]",
     "      .[keyword target];",
     "  }",
     "}");

  MT("async",
     "[keyword async] [keyword function] [def foo]([def args]) { [keyword return] [atom true]; }");

  MT("async_assignment",
     "[keyword const] [def foo] [operator =] [keyword async] [keyword function] ([def args]) { [keyword return] [atom true]; };");

  MT("async_object",
     "[keyword let] [def obj] [operator =] { [property async]: [atom false] };");

  // async be highlighet as keyword and foo as def, but it requires potentially expensive look-ahead. See #4173
  MT("async_object_function",
     "[keyword let] [def obj] [operator =] { [property async] [property foo]([def args]) { [keyword return] [atom true]; } };");

  MT("async_object_properties",
     "[keyword let] [def obj] [operator =] {",
     "  [property prop1]: [keyword async] [keyword function] ([def args]) { [keyword return] [atom true]; },",
     "  [property prop2]: [keyword async] [keyword function] ([def args]) { [keyword return] [atom true]; },",
     "  [property prop3]: [keyword async] [keyword function] [def prop3]([def args]) { [keyword return] [atom true]; },",
     "};");

  MT("async_arrow",
     "[keyword const] [def foo] [operator =] [keyword async] ([def args]) [operator =>] { [keyword return] [atom true]; };");

  MT("async_jquery",
     "[variable $].[property ajax]({",
     "  [property url]: [variable url],",
     "  [property async]: [atom true],",
     "  [property method]: [string 'GET']",
     "});");

  var ts_mode = CodeMirror.getMode({indentUnit: 2}, "application/typescript")
  function TS(name) {
    test.mode(name, ts_mode, Array.prototype.slice.call(arguments, 1))
  }

  TS("extend_type",
     "[keyword class] [def Foo] [keyword extends] [variable-3 Some][operator <][variable-3 Type][operator >] {}")

  TS("arrow_type",
     "[keyword let] [def x]: ([variable arg]: [variable-3 Type]) [operator =>] [variable-3 ReturnType]")

  TS("typescript_class",
     "[keyword class] [def Foo] {",
     "  [keyword public] [keyword static] [property main]() {}",
     "  [keyword private] [property _foo]: [variable-3 string];",
     "}")

  TS("typescript_literal_types",
     "[keyword import] [keyword *] [keyword as] [def Sequelize] [keyword from] [string 'sequelize'];",
     "[keyword interface] [def MyAttributes] {",
     "  [property truthy]: [string 'true'] [operator |] [number 1] [operator |] [atom true];",
     "  [property falsy]: [string 'false'] [operator |] [number 0] [operator |] [atom false];",
     "}",
     "[keyword interface] [def MyInstance] [keyword extends] [variable-3 Sequelize].[variable-3 Instance] [operator <] [variable-3 MyAttributes] [operator >] {",
     "  [property rawAttributes]: [variable-3 MyAttributes];",
     "  [property truthy]: [string 'true'] [operator |] [number 1] [operator |] [atom true];",
     "  [property falsy]: [string 'false'] [operator |] [number 0] [operator |] [atom false];",
     "}")

  TS("typescript_extend_operators",
     "[keyword export] [keyword interface] [def UserModel] [keyword extends]",
     "  [variable-3 Sequelize].[variable-3 Model] [operator <] [variable-3 UserInstance], [variable-3 UserAttributes] [operator >] {",
     "    [property findById]: (",
     "    [variable userId]: [variable-3 number]",
     "    ) [operator =>] [variable-3 Promise] [operator <] [variable-3 Array] [operator <] { [property id], [property name] } [operator >>];",
     "    [property updateById]: (",
     "    [variable userId]: [variable-3 number],",
     "    [variable isActive]: [variable-3 boolean]",
     "    ) [operator =>] [variable-3 Promise] [operator <] [variable-3 AccountHolderNotificationPreferenceInstance] [operator >];",
     "  }")

  TS("typescript_interface_with_const",
     "[keyword const] [def hello]: {",
     "  [property prop1][operator ?]: [variable-3 string];",
     "  [property prop2][operator ?]: [variable-3 string];",
     "} [operator =] {};")

  TS("typescript_double_extend",
     "[keyword export] [keyword interface] [def UserAttributes] {",
     "  [property id][operator ?]: [variable-3 number];",
     "  [property createdAt][operator ?]: [variable-3 Date];",
     "}",
     "[keyword export] [keyword interface] [def UserInstance] [keyword extends] [variable-3 Sequelize].[variable-3 Instance][operator <][variable-3 UserAttributes][operator >], [variable-3 UserAttributes] {",
     "  [property id]: [variable-3 number];",
     "  [property createdAt]: [variable-3 Date];",
     "}");

  var jsonld_mode = CodeMirror.getMode(
    {indentUnit: 2},
    {name: "javascript", jsonld: true}
  );
  function LD(name) {
    test.mode(name, jsonld_mode, Array.prototype.slice.call(arguments, 1));
  }

  LD("json_ld_keywords",
    '{',
    '  [meta "@context"]: {',
    '    [meta "@base"]: [string "http://example.com"],',
    '    [meta "@vocab"]: [string "http://xmlns.com/foaf/0.1/"],',
    '    [property "likesFlavor"]: {',
    '      [meta "@container"]: [meta "@list"]',
    '      [meta "@reverse"]: [string "@beFavoriteOf"]',
    '    },',
    '    [property "nick"]: { [meta "@container"]: [meta "@set"] },',
    '    [property "nick"]: { [meta "@container"]: [meta "@index"] }',
    '  },',
    '  [meta "@graph"]: [[ {',
    '    [meta "@id"]: [string "http://dbpedia.org/resource/John_Lennon"],',
    '    [property "name"]: [string "John Lennon"],',
    '    [property "modified"]: {',
    '      [meta "@value"]: [string "2010-05-29T14:17:39+02:00"],',
    '      [meta "@type"]: [string "http://www.w3.org/2001/XMLSchema#dateTime"]',
    '    }',
    '  } ]]',
    '}');

  LD("json_ld_fake",
    '{',
    '  [property "@fake"]: [string "@fake"],',
    '  [property "@contextual"]: [string "@identifier"],',
    '  [property "user@domain.com"]: [string "@graphical"],',
    '  [property "@ID"]: [string "@@ID"]',
    '}');
})();
<commit_msg>test for typescript index signature<commit_after>// CodeMirror, copyright (c) by Marijn Haverbeke and others
// Distributed under an MIT license: http://codemirror.net/LICENSE

(function() {
  var mode = CodeMirror.getMode({indentUnit: 2}, "javascript");
  function MT(name) { test.mode(name, mode, Array.prototype.slice.call(arguments, 1)); }

  MT("locals",
     "[keyword function] [def foo]([def a], [def b]) { [keyword var] [def c] [operator =] [number 10]; [keyword return] [variable-2 a] [operator +] [variable-2 c] [operator +] [variable d]; }");

  MT("comma-and-binop",
     "[keyword function](){ [keyword var] [def x] [operator =] [number 1] [operator +] [number 2], [def y]; }");

  MT("destructuring",
     "([keyword function]([def a], [[[def b], [def c] ]]) {",
     "  [keyword let] {[def d], [property foo]: [def c][operator =][number 10], [def x]} [operator =] [variable foo]([variable-2 a]);",
     "  [[[variable-2 c], [variable y] ]] [operator =] [variable-2 c];",
     "})();");

  MT("destructure_trailing_comma",
    "[keyword let] {[def a], [def b],} [operator =] [variable foo];",
    "[keyword let] [def c];"); // Parser still in good state?

  MT("class_body",
     "[keyword class] [def Foo] {",
     "  [property constructor]() {}",
     "  [property sayName]() {",
     "    [keyword return] [string-2 `foo${][variable foo][string-2 }oo`];",
     "  }",
     "}");

  MT("class",
     "[keyword class] [def Point] [keyword extends] [variable SuperThing] {",
     "  [keyword get] [property prop]() { [keyword return] [number 24]; }",
     "  [property constructor]([def x], [def y]) {",
     "    [keyword super]([string 'something']);",
     "    [keyword this].[property x] [operator =] [variable-2 x];",
     "  }",
     "}");

  MT("anonymous_class_expression",
     "[keyword const] [def Adder] [operator =] [keyword class] [keyword extends] [variable Arithmetic] {",
     "  [property add]([def a], [def b]) {}",
     "};");

  MT("named_class_expression",
     "[keyword const] [def Subber] [operator =] [keyword class] [def Subtract] {",
     "  [property sub]([def a], [def b]) {}",
     "};");

  MT("class_async_method",
     "[keyword class] [def Foo] {",
     "  [property sayName1]() {}",
     "  [keyword async] [property sayName2]() {}",
     "}");

  MT("import",
     "[keyword function] [def foo]() {",
     "  [keyword import] [def $] [keyword from] [string 'jquery'];",
     "  [keyword import] { [def encrypt], [def decrypt] } [keyword from] [string 'crypto'];",
     "}");

  MT("import_trailing_comma",
     "[keyword import] {[def foo], [def bar],} [keyword from] [string 'baz']")

  MT("const",
     "[keyword function] [def f]() {",
     "  [keyword const] [[ [def a], [def b] ]] [operator =] [[ [number 1], [number 2] ]];",
     "}");

  MT("for/of",
     "[keyword for]([keyword let] [def of] [keyword of] [variable something]) {}");

  MT("generator",
     "[keyword function*] [def repeat]([def n]) {",
     "  [keyword for]([keyword var] [def i] [operator =] [number 0]; [variable-2 i] [operator <] [variable-2 n]; [operator ++][variable-2 i])",
     "    [keyword yield] [variable-2 i];",
     "}");

  MT("quotedStringAddition",
     "[keyword let] [def f] [operator =] [variable a] [operator +] [string 'fatarrow'] [operator +] [variable c];");

  MT("quotedFatArrow",
     "[keyword let] [def f] [operator =] [variable a] [operator +] [string '=>'] [operator +] [variable c];");

  MT("fatArrow",
     "[variable array].[property filter]([def a] [operator =>] [variable-2 a] [operator +] [number 1]);",
     "[variable a];", // No longer in scope
     "[keyword let] [def f] [operator =] ([[ [def a], [def b] ]], [def c]) [operator =>] [variable-2 a] [operator +] [variable-2 c];",
     "[variable c];");

  MT("spread",
     "[keyword function] [def f]([def a], [meta ...][def b]) {",
     "  [variable something]([variable-2 a], [meta ...][variable-2 b]);",
     "}");

  MT("quasi",
     "[variable re][string-2 `fofdlakj${][variable x] [operator +] ([variable re][string-2 `foo`]) [operator +] [number 1][string-2 }fdsa`] [operator +] [number 2]");

  MT("quasi_no_function",
     "[variable x] [operator =] [string-2 `fofdlakj${][variable x] [operator +] [string-2 `foo`] [operator +] [number 1][string-2 }fdsa`] [operator +] [number 2]");

  MT("indent_statement",
     "[keyword var] [def x] [operator =] [number 10]",
     "[variable x] [operator +=] [variable y] [operator +]",
     "  [atom Infinity]",
     "[keyword debugger];");

  MT("indent_if",
     "[keyword if] ([number 1])",
     "  [keyword break];",
     "[keyword else] [keyword if] ([number 2])",
     "  [keyword continue];",
     "[keyword else]",
     "  [number 10];",
     "[keyword if] ([number 1]) {",
     "  [keyword break];",
     "} [keyword else] [keyword if] ([number 2]) {",
     "  [keyword continue];",
     "} [keyword else] {",
     "  [number 10];",
     "}");

  MT("indent_for",
     "[keyword for] ([keyword var] [def i] [operator =] [number 0];",
     "     [variable i] [operator <] [number 100];",
     "     [variable i][operator ++])",
     "  [variable doSomething]([variable i]);",
     "[keyword debugger];");

  MT("indent_c_style",
     "[keyword function] [def foo]()",
     "{",
     "  [keyword debugger];",
     "}");

  MT("indent_else",
     "[keyword for] (;;)",
     "  [keyword if] ([variable foo])",
     "    [keyword if] ([variable bar])",
     "      [number 1];",
     "    [keyword else]",
     "      [number 2];",
     "  [keyword else]",
     "    [number 3];");

  MT("indent_funarg",
     "[variable foo]([number 10000],",
     "    [keyword function]([def a]) {",
     "  [keyword debugger];",
     "};");

  MT("indent_below_if",
     "[keyword for] (;;)",
     "  [keyword if] ([variable foo])",
     "    [number 1];",
     "[number 2];");

  MT("indent_semicolonless_if",
     "[keyword function] [def foo]() {",
     "  [keyword if] ([variable x])",
     "    [variable foo]()",
     "}")

  MT("indent_semicolonless_if_with_statement",
     "[keyword function] [def foo]() {",
     "  [keyword if] ([variable x])",
     "    [variable foo]()",
     "  [variable bar]()",
     "}")

  MT("multilinestring",
     "[keyword var] [def x] [operator =] [string 'foo\\]",
     "[string bar'];");

  MT("scary_regexp",
     "[string-2 /foo[[/]]bar/];");

  MT("indent_strange_array",
     "[keyword var] [def x] [operator =] [[",
     "  [number 1],,",
     "  [number 2],",
     "]];",
     "[number 10];");

  MT("param_default",
     "[keyword function] [def foo]([def x] [operator =] [string-2 `foo${][number 10][string-2 }bar`]) {",
     "  [keyword return] [variable-2 x];",
     "}");

  MT("new_target",
     "[keyword function] [def F]([def target]) {",
     "  [keyword if] ([variable-2 target] [operator &&] [keyword new].[keyword target].[property name]) {",
     "    [keyword return] [keyword new]",
     "      .[keyword target];",
     "  }",
     "}");

  MT("async",
     "[keyword async] [keyword function] [def foo]([def args]) { [keyword return] [atom true]; }");

  MT("async_assignment",
     "[keyword const] [def foo] [operator =] [keyword async] [keyword function] ([def args]) { [keyword return] [atom true]; };");

  MT("async_object",
     "[keyword let] [def obj] [operator =] { [property async]: [atom false] };");

  // async be highlighet as keyword and foo as def, but it requires potentially expensive look-ahead. See #4173
  MT("async_object_function",
     "[keyword let] [def obj] [operator =] { [property async] [property foo]([def args]) { [keyword return] [atom true]; } };");

  MT("async_object_properties",
     "[keyword let] [def obj] [operator =] {",
     "  [property prop1]: [keyword async] [keyword function] ([def args]) { [keyword return] [atom true]; },",
     "  [property prop2]: [keyword async] [keyword function] ([def args]) { [keyword return] [atom true]; },",
     "  [property prop3]: [keyword async] [keyword function] [def prop3]([def args]) { [keyword return] [atom true]; },",
     "};");

  MT("async_arrow",
     "[keyword const] [def foo] [operator =] [keyword async] ([def args]) [operator =>] { [keyword return] [atom true]; };");

  MT("async_jquery",
     "[variable $].[property ajax]({",
     "  [property url]: [variable url],",
     "  [property async]: [atom true],",
     "  [property method]: [string 'GET']",
     "});");

  var ts_mode = CodeMirror.getMode({indentUnit: 2}, "application/typescript")
  function TS(name) {
    test.mode(name, ts_mode, Array.prototype.slice.call(arguments, 1))
  }

  TS("extend_type",
     "[keyword class] [def Foo] [keyword extends] [variable-3 Some][operator <][variable-3 Type][operator >] {}")

  TS("arrow_type",
     "[keyword let] [def x]: ([variable arg]: [variable-3 Type]) [operator =>] [variable-3 ReturnType]")

  TS("typescript_class",
     "[keyword class] [def Foo] {",
     "  [keyword public] [keyword static] [property main]() {}",
     "  [keyword private] [property _foo]: [variable-3 string];",
     "}")

  TS("typescript_literal_types",
     "[keyword import] [keyword *] [keyword as] [def Sequelize] [keyword from] [string 'sequelize'];",
     "[keyword interface] [def MyAttributes] {",
     "  [property truthy]: [string 'true'] [operator |] [number 1] [operator |] [atom true];",
     "  [property falsy]: [string 'false'] [operator |] [number 0] [operator |] [atom false];",
     "}",
     "[keyword interface] [def MyInstance] [keyword extends] [variable-3 Sequelize].[variable-3 Instance] [operator <] [variable-3 MyAttributes] [operator >] {",
     "  [property rawAttributes]: [variable-3 MyAttributes];",
     "  [property truthy]: [string 'true'] [operator |] [number 1] [operator |] [atom true];",
     "  [property falsy]: [string 'false'] [operator |] [number 0] [operator |] [atom false];",
     "}")

  TS("typescript_extend_operators",
     "[keyword export] [keyword interface] [def UserModel] [keyword extends]",
     "  [variable-3 Sequelize].[variable-3 Model] [operator <] [variable-3 UserInstance], [variable-3 UserAttributes] [operator >] {",
     "    [property findById]: (",
     "    [variable userId]: [variable-3 number]",
     "    ) [operator =>] [variable-3 Promise] [operator <] [variable-3 Array] [operator <] { [property id], [property name] } [operator >>];",
     "    [property updateById]: (",
     "    [variable userId]: [variable-3 number],",
     "    [variable isActive]: [variable-3 boolean]",
     "    ) [operator =>] [variable-3 Promise] [operator <] [variable-3 AccountHolderNotificationPreferenceInstance] [operator >];",
     "  }")

  TS("typescript_interface_with_const",
     "[keyword const] [def hello]: {",
     "  [property prop1][operator ?]: [variable-3 string];",
     "  [property prop2][operator ?]: [variable-3 string];",
     "} [operator =] {};")

  TS("typescript_double_extend",
     "[keyword export] [keyword interface] [def UserAttributes] {",
     "  [property id][operator ?]: [variable-3 number];",
     "  [property createdAt][operator ?]: [variable-3 Date];",
     "}",
     "[keyword export] [keyword interface] [def UserInstance] [keyword extends] [variable-3 Sequelize].[variable-3 Instance][operator <][variable-3 UserAttributes][operator >], [variable-3 UserAttributes] {",
     "  [property id]: [variable-3 number];",
     "  [property createdAt]: [variable-3 Date];",
     "}");

  TS("typescript_index_signature",
     "[keyword interface] [def A] {",
     "  [[[property prop]: [variable-3 string]]]: [variable-3 any];",
     "  [property prop1]: [variable-3 any];",
     "}");

  var jsonld_mode = CodeMirror.getMode(
    {indentUnit: 2},
    {name: "javascript", jsonld: true}
  );
  function LD(name) {
    test.mode(name, jsonld_mode, Array.prototype.slice.call(arguments, 1));
  }

  LD("json_ld_keywords",
    '{',
    '  [meta "@context"]: {',
    '    [meta "@base"]: [string "http://example.com"],',
    '    [meta "@vocab"]: [string "http://xmlns.com/foaf/0.1/"],',
    '    [property "likesFlavor"]: {',
    '      [meta "@container"]: [meta "@list"]',
    '      [meta "@reverse"]: [string "@beFavoriteOf"]',
    '    },',
    '    [property "nick"]: { [meta "@container"]: [meta "@set"] },',
    '    [property "nick"]: { [meta "@container"]: [meta "@index"] }',
    '  },',
    '  [meta "@graph"]: [[ {',
    '    [meta "@id"]: [string "http://dbpedia.org/resource/John_Lennon"],',
    '    [property "name"]: [string "John Lennon"],',
    '    [property "modified"]: {',
    '      [meta "@value"]: [string "2010-05-29T14:17:39+02:00"],',
    '      [meta "@type"]: [string "http://www.w3.org/2001/XMLSchema#dateTime"]',
    '    }',
    '  } ]]',
    '}');

  LD("json_ld_fake",
    '{',
    '  [property "@fake"]: [string "@fake"],',
    '  [property "@contextual"]: [string "@identifier"],',
    '  [property "user@domain.com"]: [string "@graphical"],',
    '  [property "@ID"]: [string "@@ID"]',
    '}');
})();
<|endoftext|>


<commit_before>window.addEventListener("load", () => {
  const SUPPORTED_TYPES = ["Files", "application/x-moz-file"];

  let body = document.getElementsByTagName("body")[0];

  body.addEventListener("dragover", (ev) => {
    if(SUPPORTED_TYPES.find(el => ev.dataTransfer.types.includes(el)))
      ev.preventDefault();
  });

  body.addEventListener("drop", (ev) => {
    if(SUPPORTED_TYPES.find(el => ev.dataTransfer.types.includes(el))) {
      ev.preventDefault();

      for(let i = ev.dataTransfer.files.length - 1; i >= 0; --i) {
        let file = ev.dataTransfer.files[i];
        let request = new XMLHttpRequest();
        request.open('PUT', document.URL + file.name);
        request.send(file);
      }
    }
  });
});
<commit_msg>Fix Drag&Drop uploading w/o forward slash at end of URL<commit_after>window.addEventListener("load", () => {
  const SUPPORTED_TYPES = ["Files", "application/x-moz-file"];

  let body = document.getElementsByTagName("body")[0];

  body.addEventListener("dragover", (ev) => {
    if(SUPPORTED_TYPES.find(el => ev.dataTransfer.types.contains(el)))
      ev.preventDefault();
  });

  body.addEventListener("drop", (ev) => {
    if(SUPPORTED_TYPES.find(el => ev.dataTransfer.types.contains(el))) {
      ev.preventDefault();

      let url = document.URL;
      if(url[url.length - 1] != "/")
        url += "/";

      for(let i = ev.dataTransfer.files.length - 1; i >= 0; --i) {
        let file = ev.dataTransfer.files[i];
        let request = new XMLHttpRequest();
        request.open('PUT', url + file.name);
        request.send(file);
      }
    }
  });
});
<|endoftext|>


<commit_before>import warning from 'warning'
import { createLocation } from './LocationUtils'
import { addEventListener, removeEventListener } from './DOMUtils'
import { saveState, readState } from './DOMStateStorage'
import {
  addQueryStringValueToPath,
  stripQueryStringValueFromPath,
  getQueryStringValueFromPath,
  parsePath,
  createPath
} from './PathUtils'

const HashChangeEvent = 'hashchange'

const getHashPath = () => {
  // We can't use window.location.hash here because it's not
  // consistent across browsers - Firefox will pre-decode it!
  const href = window.location.href
  const hashIndex = href.indexOf('#')
  return hashIndex === -1 ? '' : href.substring(hashIndex + 1)
}

const pushHashPath = (path) =>
  window.location.hash = path

const replaceHashPath = (path) => {
  const hashIndex = window.location.href.indexOf('#')

  window.location.replace(
    window.location.href.slice(0, hashIndex >= 0 ? hashIndex : 0) + '#' + path
  )
}

export { getUserConfirmation, go } from './BrowserProtocol'

export const getCurrentLocation = (pathCoder, queryKey) => {
  let path = pathCoder.decodePath(getHashPath())
  const key = getQueryStringValueFromPath(path, queryKey)

  let state
  if (key) {
    path = stripQueryStringValueFromPath(path, queryKey)
    state = readState(key)
  }

  const init = parsePath(path)
  init.state = state

  return createLocation(init, undefined, key)
}

let prevLocation

export const startListener = (listener, pathCoder, queryKey) => {
  const handleHashChange = () => {
    const path = getHashPath()
    const encodedPath = pathCoder.encodePath(path)

    if (path !== encodedPath) {
      replaceHashPath(encodedPath)
    } else {
      const currentLocation = getCurrentLocation(pathCoder, queryKey)

      if (prevLocation && currentLocation.key && prevLocation.key === currentLocation.key)
        return // Ignore extraneous hashchange events

      prevLocation = currentLocation

      listener(currentLocation)
    }
  }

  const path = getHashPath()
  const encodedPath = pathCoder.encodePath(path)

  if (path !== encodedPath)
    replaceHashPath(encodedPath)

  addEventListener(window, HashChangeEvent, handleHashChange)

  return () =>
    removeEventListener(window, HashChangeEvent, handleHashChange)
}

const updateLocation = (location, pathCoder, queryKey, updateHash) => {
  const { state, key } = location

  let path = pathCoder.encodePath(createPath(location))

  if (state !== undefined) {
    path = addQueryStringValueToPath(path, queryKey, key)
    saveState(key, state)
  }

  prevLocation = location

  updateHash(path)
}

export const pushLocation = (location, pathCoder, queryKey) =>
  updateLocation(location, pathCoder, queryKey, (path) => {
    if (getHashPath() !== path) {
      pushHashPath(path)
    } else {
      warning(false, 'You cannot PUSH the same path using hash history')
    }
  })

export const replaceLocation = (location, pathCoder, queryKey) =>
  updateLocation(location, pathCoder, queryKey, (path) => {
    if (getHashPath() !== path)
      replaceHashPath(path)
  })
<commit_msg>Add explanatory comments<commit_after>import warning from 'warning'
import { createLocation } from './LocationUtils'
import { addEventListener, removeEventListener } from './DOMUtils'
import { saveState, readState } from './DOMStateStorage'
import {
  addQueryStringValueToPath,
  stripQueryStringValueFromPath,
  getQueryStringValueFromPath,
  parsePath,
  createPath
} from './PathUtils'

const HashChangeEvent = 'hashchange'

const getHashPath = () => {
  // We can't use window.location.hash here because it's not
  // consistent across browsers - Firefox will pre-decode it!
  const href = window.location.href
  const hashIndex = href.indexOf('#')
  return hashIndex === -1 ? '' : href.substring(hashIndex + 1)
}

const pushHashPath = (path) =>
  window.location.hash = path

const replaceHashPath = (path) => {
  const hashIndex = window.location.href.indexOf('#')

  window.location.replace(
    window.location.href.slice(0, hashIndex >= 0 ? hashIndex : 0) + '#' + path
  )
}

export { getUserConfirmation, go } from './BrowserProtocol'

export const getCurrentLocation = (pathCoder, queryKey) => {
  let path = pathCoder.decodePath(getHashPath())
  const key = getQueryStringValueFromPath(path, queryKey)

  let state
  if (key) {
    path = stripQueryStringValueFromPath(path, queryKey)
    state = readState(key)
  }

  const init = parsePath(path)
  init.state = state

  return createLocation(init, undefined, key)
}

let prevLocation

export const startListener = (listener, pathCoder, queryKey) => {
  const handleHashChange = () => {
    const path = getHashPath()
    const encodedPath = pathCoder.encodePath(path)

    if (path !== encodedPath) {
      // Always be sure we have a properly-encoded hash.
      replaceHashPath(encodedPath)
    } else {
      const currentLocation = getCurrentLocation(pathCoder, queryKey)

      if (prevLocation && currentLocation.key && prevLocation.key === currentLocation.key)
        return // Ignore extraneous hashchange events

      prevLocation = currentLocation

      listener(currentLocation)
    }
  }

  // Ensure the hash is encoded properly.
  const path = getHashPath()
  const encodedPath = pathCoder.encodePath(path)

  if (path !== encodedPath)
    replaceHashPath(encodedPath)

  addEventListener(window, HashChangeEvent, handleHashChange)

  return () =>
    removeEventListener(window, HashChangeEvent, handleHashChange)
}

const updateLocation = (location, pathCoder, queryKey, updateHash) => {
  const { state, key } = location

  let path = pathCoder.encodePath(createPath(location))

  if (state !== undefined) {
    path = addQueryStringValueToPath(path, queryKey, key)
    saveState(key, state)
  }

  prevLocation = location

  updateHash(path)
}

export const pushLocation = (location, pathCoder, queryKey) =>
  updateLocation(location, pathCoder, queryKey, (path) => {
    if (getHashPath() !== path) {
      pushHashPath(path)
    } else {
      warning(false, 'You cannot PUSH the same path using hash history')
    }
  })

export const replaceLocation = (location, pathCoder, queryKey) =>
  updateLocation(location, pathCoder, queryKey, (path) => {
    if (getHashPath() !== path)
      replaceHashPath(path)
  })
<|endoftext|>


<commit_before>console.assert(add(0, 0), /* FILL ME IN */);
console.assert(add(0, 1), /* FILL ME IN */);
console.assert(add(0, 2), /* FILL ME IN */);

/**
 * @param {Number} A to add to B
 * @param {Number} B to add to A
 * @return {Number} sum of A and B
 */
function add(A, B){
} // END add
<commit_msg>filled out<commit_after>
function add(A, B){
  return A + B;
};
console.assert(add(0, 0), === 0);
console.assert(add(0, 1), === 1);
console.assert(add(0, 2), === 2);
console.assert(add(0, 3), === 3);
console.assert(add(0, 4), === 4);
console.assert(add(0, 5), === 5);
console.assert(add(0, 6), === 6);
console.assert(add(0, 7), === 7);
console.assert(add(0, 8), === 8);
console.assert(add(0, 9), === 9);

/**
 * @param {Number} A to add to B
 * @param {Number} B to add to A
 * @return {Number} sum of A and B
 */

 function minus(A, B){
   return A - B;
};
 console.assert(minus(0,0), === 0);
 console.assert(minus(0,1), === -1);
 console.assert(minus(0,3), === -3);
 console.assert(minus(0,4), === -4);
 console.assert(minus(0,5), === -5);
 console.assert(minus(0,6), === -6);
 console.assert(minus(0,7), === -7);
 console.assert(minus(0,8), === -8);
 console.assert(minus(0,9), === -9);

 function times(A, B){
   return A * B;
};
 console.assert(times(0,0), === 0);
 console.assert(times(0,1), === 0);
 console.assert(times(0,3), === 0);
 console.assert(times(0,4), === 0);
 console.assert(times(0,5), === 0);
 console.assert(times(0,6), === 0);
 console.assert(times(0,7), === 0);
 console.assert(times(0,8), === 0);
 console.assert(times(0,9), === 0);
<|endoftext|>