<commit_before>// @flow
import React, {PureComponent} from 'react';
import styled from 'styled-components';

import example from '../example.json';
import styles from '../utils/styles';
import Editor from './editor';

const links = [
  ['Installation', 'https://github.com/Gregoor/syntactor#usage'],
  ['Reasoning', 'https://medium.com/@grgtwt/code-is-not-just-text-1082981ae27f'],
  ['Comparison', 'https://github.com/Gregoor/syntactor/blob/master/COMPARISON.md'],
  ['Roadmap', 'https://github.com/Gregoor/syntactor/milestones?with_issues=no'],
  ['GitHub', 'https://github.com/gregoor/syntactor'],
  ['Issues', 'https://github.com/Gregoor/syntactor/issues']
];

const Head = styled.h1`
  ${styles.text}
  font-size: 2em;
  text-align: center;
  cursor: pointer;
`;

const Symbol = styled.span`
  color: #B7B7B7;
`;

const Brace = ({charCode}) => <Symbol>{String.fromCharCode(charCode)}</Symbol>;

const Card = styled.div`
  padding: 20px;
  background: white;
  box-shadow: 0 2px 2px 0 rgba(0, 0, 0, .14),
    0 3px 1px -2px rgba(0, 0, 0, .2),
    0 1px 5px 0 rgba(0, 0, 0, .12);
`;

const Nav = styled.div`
  margin: 0 -20px 20px;
  padding: 0 20px 20px;
  border-bottom: 1px solid lightgrey;
  display: flex;
  flex-direction: row;
  justify-content: space-between;
`;

export default class Demo extends PureComponent<{}> {

  editor: Editor;

  constructor(props) {
    super(props);

    let startValue;
    try {
      startValue = JSON.parse(decodeURIComponent(window.location.search.substr(1).split('=')[1]));
    } catch (e) {
      if (!(e instanceof SyntaxError)) {
        throw e;
      }
      startValue = example;
    }

    this.state = {startValue}
  }

  updateQueryString = (json: string) => {
    window.history.pushState({}, '',
      '?json=' + encodeURIComponent(json)
    );
  };

  resetEditor = () => {
    this.setState({startValue: example});
    this.updateQueryString(JSON.stringify(example));
    this.editor.reset();
  };

  render() {
    return (

          <Brace charCode={123}/>Syntactor<Brace charCode={125}/>

        <Card style={{marginBottom: 10, minHeight: '83vh'}}>

            <Symbol>[</Symbol>
            {links.map(([label, link], i) => (

                  {label}
                {i + 1 < links.length && <Symbol>,</Symbol>}

            ))}
            <Symbol>]</Symbol>

          <Editor
            initiallyShowKeymap
            defaultValue={this.state.startValue}
            onChange={this.updateQueryString}
            ref={(el) => this.editor = el}
          />
        </Card>

    );
  }

}<commit_msg>fix type annotations<commit_after>// @flow
import React, {PureComponent} from 'react';
import styled from 'styled-components';

import example from '../example.json';
import styles from '../utils/styles';
import Editor from './editor';

const links = [
  ['Installation', 'https://github.com/Gregoor/syntactor#usage'],
  ['Reasoning', 'https://medium.com/@grgtwt/code-is-not-just-text-1082981ae27f'],
  ['Comparison', 'https://github.com/Gregoor/syntactor/blob/master/COMPARISON.md'],
  ['Roadmap', 'https://github.com/Gregoor/syntactor/milestones?with_issues=no'],
  ['GitHub', 'https://github.com/gregoor/syntactor'],
  ['Issues', 'https://github.com/Gregoor/syntactor/issues']
];

const Head = styled.h1`
  ${styles.text}
  font-size: 2em;
  text-align: center;
  cursor: pointer;
`;

const Symbol = styled.span`
  color: #B7B7B7;
`;

const Brace = ({charCode}) => <Symbol>{String.fromCharCode(charCode)}</Symbol>;

const Card = styled.div`
  padding: 20px;
  background: white;
  box-shadow: 0 2px 2px 0 rgba(0, 0, 0, .14),
    0 3px 1px -2px rgba(0, 0, 0, .2),
    0 1px 5px 0 rgba(0, 0, 0, .12);
`;

const Nav = styled.div`
  margin: 0 -20px 20px;
  padding: 0 20px 20px;
  border-bottom: 1px solid lightgrey;
  display: flex;
  flex-direction: row;
  justify-content: space-between;
`;

interface State {
  startValue: any
}

export default class Demo extends PureComponent<{}, State> {

  editor: Editor | null;

  constructor() {
    super();

    let startValue;
    try {
      startValue = JSON.parse(decodeURIComponent(window.location.search.substr(1).split('=')[1]));
    } catch (e) {
      if (!(e instanceof SyntaxError)) {
        throw e;
      }
      startValue = example;
    }

    this.state = {startValue}
  }

  updateQueryString = (json: string) => {
    window.history.pushState({}, '',
      '?json=' + encodeURIComponent(json)
    );
  };

  resetEditor = () => {
    this.setState({startValue: example});
    this.updateQueryString(JSON.stringify(example));
    this.editor && this.editor.reset();
  };

  render() {
    return (

          <Brace charCode={123}/>Syntactor<Brace charCode={125}/>

        <Card style={{marginBottom: 10, minHeight: '83vh'}}>

            <Symbol>[</Symbol>
            {links.map(([label, link], i) => (

                  {label}
                {i + 1 < links.length && <Symbol>,</Symbol>}

            ))}
            <Symbol>]</Symbol>

          <Editor
            initiallyShowKeymap
            defaultValue={this.state.startValue}
            onChange={this.updateQueryString}
            ref={(el) => this.editor = el}
          />
        </Card>

    );
  }

}<|endoftext|>


<commit_before>import React from 'react';
import ReactDOM from 'react-dom';

import '../index.css';
import Board from './board.js';
import calculateWinner from '../helpers/calculate-winner.js'

export default class Game extends React.Component {
  constructor(){
    super();
    this.state = {
      squares: initialiseChessBoard(),
      player: 1,
      sourceSelection: -1,
      status: 'Next player: 1'
    }
  }

  handleClick(i){
    const squares = this.state.squares.slice();
    console.log(i);

    // if (calculateWinner(squares) || squares[i]) {
    //   return;
    // }
    // squares[i] = this.state.xIsNext? 'X' : 'O';

    if(this.state.sourceSelection === -1){
      if(!squares[i] || squares[i].player !== this.state.player){
        this.setState({status: "Wrong selection. Choose player " + this.state.player + " pieces."})
      }
      else{
        this.setState({
          status: "Choose valid destination for the selected piece",
          sourceSelection: i
        });
      }

    }

    else if(this.state.sourceSelection > -1){
      if(squares[i] && squares[i].player === this.state.player){
        this.setState({
          status: "Wrong selection. Choose valid source and destination again.",
          sourceSelection: -1,
        })
      }
      else{
        const squares = this.state.squares;
        squares[i] = squares[this.state.sourceSelection];
        squares[this.state.sourceSelection] = null;
        let player = this.state.player === 1? 2: 1;
        this.setState({
          status: "",
          sourceSelection: -1,
          squares: squares,
          player: player,
          status: 'Next player: ' + player
        });
      }
    }

  }

  render() {
    const squares = this.state.squares.slice();
    let winner;
    let winningSquares = calculateWinner(squares);
    let status = this.state.status;

    return (

            <Board
            squares = {squares}
            winningSquares = {winningSquares}
            onClick = {(i) => this.handleClick(i)}
            />

{status}

  Chess Icons And Favicon (extracted) By en:User:Cburnett [GFDL, CC-BY-SA-3.0, BSD or GPL], via Wikimedia Commons

      );
  }
}

class Piece {
  constructor(player, iconUrl){
    this.player = player;
    this.style = {backgroundImage: "url('"+iconUrl+"')"};
  }
}

class Rook extends Piece {
  constructor(player){
    super(player, (player === 1? "https://upload.wikimedia.org/wikipedia/commons/7/72/Chess_rlt45.svg" : "https://upload.wikimedia.org/wikipedia/commons/f/ff/Chess_rdt45.svg"));
  }

  isMoveLegal(){
    return true
  }
}

class Knight extends Piece {
  constructor(player){
    super(player, (player === 1? "https://upload.wikimedia.org/wikipedia/commons/7/70/Chess_nlt45.svg" : "https://upload.wikimedia.org/wikipedia/commons/e/ef/Chess_ndt45.svg"));
  }

  isMoveLegal(){
    return true
  }
}

class Bishop extends Piece {
  constructor(player){
    super(player, (player === 1? "https://upload.wikimedia.org/wikipedia/commons/b/b1/Chess_blt45.svg" : "https://upload.wikimedia.org/wikipedia/commons/9/98/Chess_bdt45.svg"));
  }

  isMoveLegal(){
    return true
  }
}

class Queen extends Piece {
  constructor(player){
    super(player, (player === 1? "https://upload.wikimedia.org/wikipedia/commons/1/15/Chess_qlt45.svg" : "https://upload.wikimedia.org/wikipedia/commons/4/47/Chess_qdt45.svg"));
  }

  isMoveLegal(){
    return true
  }
}

class King extends Piece {
  constructor(player){
    super(player, (player === 1? "https://upload.wikimedia.org/wikipedia/commons/4/42/Chess_klt45.svg" : "https://upload.wikimedia.org/wikipedia/commons/f/f0/Chess_kdt45.svg"));
  }

  isMoveLegal(){
    return true
  }
}

class Pawn extends Piece {
  constructor(player){
    super(player, (player === 1?  "https://upload.wikimedia.org/wikipedia/commons/4/45/Chess_plt45.svg" : "https://upload.wikimedia.org/wikipedia/commons/c/c7/Chess_pdt45.svg"));
  }

  isMoveLegal(){
    return true
  }
}

function initialiseChessBoard(){

  const squares = Array(64).fill(null);

  for(let i = 8; i < 16; i++){
    squares[i] = new Pawn(2);
    squares[i+40] = new Pawn(1);
  }
  squares[0] = new Rook(2);
  squares[7] = new Rook(2);
  squares[56] = new Rook(1);
  squares[63] = new Rook(1);

  squares[1] = new Knight(2);
  squares[6] = new Knight(2);
  squares[57] = new Knight(1);
  squares[62] = new Knight(1);

  squares[2] = new Bishop(2);
  squares[5] = new Bishop(2);
  squares[58] = new Bishop(1);
  squares[61] = new Bishop(1);

  squares[3] = new Queen(2);
  squares[4] = new King(2);

  squares[59] = new Queen(1);
  squares[60] = new King(1);

  return squares;
}<commit_msg>change square background color on source piece click<commit_after>import React from 'react';
import ReactDOM from 'react-dom';

import '../index.css';
import Board from './board.js';
import calculateWinner from '../helpers/calculate-winner.js'

export default class Game extends React.Component {
  constructor(){
    super();
    this.state = {
      squares: initialiseChessBoard(),
      player: 1,
      sourceSelection: -1,
      status: 'Next player: 1'
    }
  }

  handleClick(i){
    const squares = this.state.squares.slice();
    console.log(i);

    // if (calculateWinner(squares) || squares[i]) {
    //   return;
    // }
    // squares[i] = this.state.xIsNext? 'X' : 'O';

    if(this.state.sourceSelection === -1){
      if(!squares[i] || squares[i].player !== this.state.player){
        this.setState({status: "Wrong selection. Choose player " + this.state.player + " pieces."});
        squares[i].player? delete squares[i].style.backgroundColor: null;
      }
      else{
        squares[i].style.backgroundColor = "lightblue";
        this.setState({
          status: "Choose valid destination for the selected piece",
          sourceSelection: i
        });
      }
    }

    else if(this.state.sourceSelection > -1){
      delete squares[this.state.sourceSelection].style.backgroundColor;
      if(squares[i] && squares[i].player === this.state.player){
        this.setState({
          status: "Wrong selection. Choose valid source and destination again.",
          sourceSelection: -1,
        })
      }
      else{
        const squares = this.state.squares;
        squares[i] = squares[this.state.sourceSelection];
        squares[this.state.sourceSelection] = null;
        let player = this.state.player === 1? 2: 1;
        this.setState({
          status: "",
          sourceSelection: -1,
          squares: squares,
          player: player,
          status: 'Next player: ' + player
        });
      }
    }

  }

  render() {
    const squares = this.state.squares.slice();
    let winner;
    let winningSquares = calculateWinner(squares);
    let status = this.state.status;

    return (

            <Board
            squares = {squares}
            winningSquares = {winningSquares}
            onClick = {(i) => this.handleClick(i)}
            />

{status}

  Chess Icons And Favicon (extracted) By en:User:Cburnett [GFDL, CC-BY-SA-3.0, BSD or GPL], via Wikimedia Commons

      );
  }
}

class Piece {
  constructor(player, iconUrl){
    this.player = player;
    this.style = {backgroundImage: "url('"+iconUrl+"')"};
  }
}

class Rook extends Piece {
  constructor(player){
    super(player, (player === 1? "https://upload.wikimedia.org/wikipedia/commons/7/72/Chess_rlt45.svg" : "https://upload.wikimedia.org/wikipedia/commons/f/ff/Chess_rdt45.svg"));
  }

  isMoveLegal(){
    return true
  }
}

class Knight extends Piece {
  constructor(player){
    super(player, (player === 1? "https://upload.wikimedia.org/wikipedia/commons/7/70/Chess_nlt45.svg" : "https://upload.wikimedia.org/wikipedia/commons/e/ef/Chess_ndt45.svg"));
  }

  isMoveLegal(){
    return true
  }
}

class Bishop extends Piece {
  constructor(player){
    super(player, (player === 1? "https://upload.wikimedia.org/wikipedia/commons/b/b1/Chess_blt45.svg" : "https://upload.wikimedia.org/wikipedia/commons/9/98/Chess_bdt45.svg"));
  }

  isMoveLegal(){
    return true
  }
}

class Queen extends Piece {
  constructor(player){
    super(player, (player === 1? "https://upload.wikimedia.org/wikipedia/commons/1/15/Chess_qlt45.svg" : "https://upload.wikimedia.org/wikipedia/commons/4/47/Chess_qdt45.svg"));
  }

  isMoveLegal(){
    return true
  }
}

class King extends Piece {
  constructor(player){
    super(player, (player === 1? "https://upload.wikimedia.org/wikipedia/commons/4/42/Chess_klt45.svg" : "https://upload.wikimedia.org/wikipedia/commons/f/f0/Chess_kdt45.svg"));
  }

  isMoveLegal(){
    return true
  }
}

class Pawn extends Piece {
  constructor(player){
    super(player, (player === 1?  "https://upload.wikimedia.org/wikipedia/commons/4/45/Chess_plt45.svg" : "https://upload.wikimedia.org/wikipedia/commons/c/c7/Chess_pdt45.svg"));
  }

  isMoveLegal(){
    return true
  }
}

function initialiseChessBoard(){

  const squares = Array(64).fill(null);

  for(let i = 8; i < 16; i++){
    squares[i] = new Pawn(2);
    squares[i+40] = new Pawn(1);
  }
  squares[0] = new Rook(2);
  squares[7] = new Rook(2);
  squares[56] = new Rook(1);
  squares[63] = new Rook(1);

  squares[1] = new Knight(2);
  squares[6] = new Knight(2);
  squares[57] = new Knight(1);
  squares[62] = new Knight(1);

  squares[2] = new Bishop(2);
  squares[5] = new Bishop(2);
  squares[58] = new Bishop(1);
  squares[61] = new Bishop(1);

  squares[3] = new Queen(2);
  squares[4] = new King(2);

  squares[59] = new Queen(1);
  squares[60] = new King(1);

  return squares;
}<|endoftext|>


<commit_before>import React from 'react';

export default ({posts}) => {
  return (

Hello World! This is the homepage.

      {posts.map(post => ({post.title}))}

  );
};
<commit_msg>Corrected the link<commit_after>import React from 'react';

export default ({posts}) => {
  return (

Hello World! This is the homepage.

      {posts.map(post => ({post.title}))}

  );
};
<|endoftext|>


<commit_before>import React from 'react';
import Sandbox from 'sandboxjs';

import Alert from '../components/alert';

export default class A0Logs extends React.Component {
    constructor(props) {
        super(props);

        this.state = {
            error: null,
            logs: []
        };
    }

    componentDidMount() {
        const logStream = this.props.profile.createLogStream();

        logStream.on('error', (e) => {
            console.error(e);

            this.setState({
                error: new Error(e.message),
            });
        });

        logStream.on('data', (msg) => {
            const logs = this.state.logs.slice();

            if (msg.name === 'sandbox-logs') {
                logs.push(msg);
                logs.sort((a, b) => new Date(b) - new Date(a));

                this.setState({ logs });
            }
        });
    }

    componentDidUpdate() {
        if(this.refs['log-view']) {
            let logs = this.refs['log-view'].getDOMNode();

            logs.scrollTop = logs.scrollHeight;
        }
    }

    render() {
        const error = this.state.error ?
                     'Error: ' + this.state.error.message :
                     null;

        const logs = this.state.logs.length ?

                {
                    this.state.logs.map(line => line.msg + '\n')
                }

 :
            <Alert bsStyle="info">
                Nothing to report
            </Alert>

        return (

                <Alert bsStyle={this.state.error ? 'danger' : 'success'}>
                  {error || 'Connected to ' + this.props.profile.container}
                </Alert>

                {this.state.error ? null : logs}

        );
    }
}

A0Logs.title = 'View webtask logs';

A0Logs.propTypes = {
    profile: React.PropTypes.instanceOf(Sandbox).isRequired
};
<commit_msg>Destroy logstream on unmount. Style changes<commit_after>import React from 'react';
import Sandbox from 'sandboxjs';

import Alert from '../components/alert';

export default class A0Logs extends React.Component {
    constructor(props) {
        super(props);

        this.logStream = null;
        this.state = {
            error: null,
            logs: []
        };
    }

    componentDidMount() {
        this.logStream = this.props.profile.createLogStream();

        this.logStream.on('error', (e) => {
            console.error(e);

            this.setState({
                error: new Error(e.message),
            });
        });

        this.logStream.on('data', (msg) => {
            const logs = this.state.logs.slice();

            if (msg.name === 'sandbox-logs') {
                logs.push(msg);
                logs.sort((a, b) => new Date(b) - new Date(a));

                this.setState({ logs });
            }
        });
    }

    componentDidUpdate() {
        if(this.refs['log-view']) {
            let logs = this.refs['log-view'].getDOMNode();

            logs.scrollTop = logs.scrollHeight;
        }
    }

    componentWillUnmount() {
        this.logStream.destroy();
        this.logStream = null;
    }

    render() {
        const error = this.state.error
            ? 'Error: ' + this.state.error.message
            : null;

        const logs = this.state.logs.length
        ?   (

                    {
                        this.state.logs.map(line => line.msg + '\n')
                    }

            )
        :   (
                <Alert bsStyle="info">
                    Nothing to report
                </Alert>
            );

        return (

                <Alert bsStyle={this.state.error ? 'danger' : 'success'}>
                  {error || 'Connected to ' + this.props.profile.container}
                </Alert>

                { this.state.error
                ?   null
                :   logs
                }

        );
    }
}

A0Logs.title = 'View webtask logs';

A0Logs.propTypes = {
    profile: React.PropTypes.instanceOf(Sandbox).isRequired
};
<|endoftext|>


<commit_before>import React from 'react';
import NavigationBar from '../components/navigation-bar.js';
import KeyboardShortcutOverlay from '../components/keyboard-shortcut-overlay.js';
import KatasNavigation from '../components/katas-navigation.js';

export default class Main extends React.Component {

  render() {
    const {metaKeySymbol, onSave, onResetCode, editorId, runnerId, shortcuts} = this.props;
    return (

        <NavigationBar
          metaKeySymbol={metaKeySymbol}
          onSave={onSave}
          onResetCode={onResetCode}
        />

        <KatasNavigation />

        <KeyboardShortcutOverlay
          metaKeySymbol={metaKeySymbol}
          shortcuts={shortcuts}
        />

    );
  }

}
<commit_msg>Add GA dynamically.<commit_after>/* global process */
import React from 'react';
import NavigationBar from '../components/navigation-bar.js';
import KeyboardShortcutOverlay from '../components/keyboard-shortcut-overlay.js';
import KatasNavigation from '../components/katas-navigation.js';

export default class Main extends React.Component {

  render() {
    const {metaKeySymbol, onSave, onResetCode, editorId, runnerId, shortcuts} = this.props;
    return (

        <NavigationBar
          metaKeySymbol={metaKeySymbol}
          onSave={onSave}
          onResetCode={onResetCode}
        />

        <KatasNavigation />

        <KeyboardShortcutOverlay
          metaKeySymbol={metaKeySymbol}
          shortcuts={shortcuts}
        />

        <Analytics />

    );
  }
}

class Analytics extends React.Component {
  render() {
    const trackingId = process.env.GA_TRACKING_ID;
    const trackingDomain = process.env.GA_TRACKING_DOMAIN;
    if (!trackingId || !trackingDomain) {
      return null;
    }
    const jsCode = `(function(i,s,o,g,r,a,m){i['GoogleAnalyticsObject']=r;i[r]=i[r]||function(){
      (i[r].q=i[r].q||[]).push(arguments)},i[r].l=1*new Date();a=s.createElement(o),
      m=s.getElementsByTagName(o)[0];a.async=1;a.src=g;m.parentNode.insertBefore(a,m)
      })(window,document,'script','//www.google-analytics.com/analytics.js','ga');
      ga('create', '${trackingId}', '${trackingDomain}');
      ga('send', 'pageview');
    `;
    return
  }
}
<|endoftext|>


<commit_before>/*
 * DOM and jQuery utilities
 * @author		Neil Rackett
 */

/**
 * Initialize Applications in the DOM using the specified namespace
 *
 * By default, Conbo scans the entire DOM, but you can limit the
 * scope by specifying a root element
 *
 * @memberof	conbo
 */
conbo.initDom = function(namespace, rootEl)
{
	var $rootEl = $(rootEl || 'html');

	if (conbo.isString(namespace))
	{
		namespace = conbo(namespace);
	}

	if (!conbo.isObject(namespace))
	{
		conbo.warn('Unable to initialize namespace:', namespace);
		return this;
	}

	$(function()
	{
		$rootEl.find('[cb-app]').not('.cb-app').each(function(index, el)
       	{
			var $el = $(el)
       		  , appName = $el.attr('cb-app')
       		  , appClass = namespace[appName]
       		  ;

       		if (appClass)
       		{
       			new appClass({el:el})
       		}
       	});
	});

	return this;
};

/**
 * @private
 */
var __observers = [];

/**
 * @private
 */
var __getObserverIndex = function(namespace, rootEl)
{
	var length = __observers.length;

	for (var i=0; i<length; i++)
	{
		var observer = __observers[i];

		if (observer[0] == namespace && observer[1] == rootEl)
		{
			return i;
		}
	}

	return -1;
};

/**
 * Watch the DOM for new Applications using the specified namespace
 *
 * By default, Conbo watches the entire DOM, but you can limit the
 * scope by specifying a root element
 *
 * @memberof	conbo
 */
conbo.observeDom = function(namespace, rootEl)
{
	if (conbo.isString(namespace))
	{
		namespace = conbo(namespace);
	}

	if (__getObserverIndex(namespace, rootEl) != -1)
	{
		return;
	}

	var mo;
	var $rootEl = $(rootEl || 'html');

	mo = new conbo.MutationObserver();
	mo.observe($rootEl[0]);

	mo.addEventListener(conbo.ConboEvent.ADD, function(event)
	{
		event.nodes.forEach(function(node)
		{
			var $node = $(node);
			var appName = $node.cbAttrs().app;

			if (namespace[appName] && !$node.hasClass('cb-app'))
			{
				new namespace[appName]({el:node});
			}
		});
	});

	__observers.push([namespace, rootEl, mo]);

	return this;
};

/**
 * Stop watching the DOM for new Applications
 *
 * @memberof	conbo
 */
conbo.unobserveDom = function(namespace, rootEl)
{
	if (conbo.isString(namespace))
	{
		namespace = conbo(namespace);
	}

	var i = __getObserverIndex(namespace, rootEl);

	if (i != -1)
	{
		var observer = __observers[i];

		observer[2].removeEventListener();
		__observers.slice(i,1);
	}

	return this;
};

if (!!$)
{
	/**
	 * Return a list of cb-* attributes on the DOM element
	 */
	$.fn.cbAttrs = function(camelCase)
	{
		var data = {},
			attrs = conbo.toArray(this.get()[0].attributes),
			count = 0,
			propertyName;

		for (var i=0; i<attrs.length; ++i)
		{
			if (attrs[i].name.indexOf('cb-') != 0) continue;

			propertyName = attrs[i].name.substr(3);

			if (camelCase !== false)
			{
				propertyName = conbo.toCamelCase(propertyName);
			}

			data[propertyName] = attrs[i].value;
		}

		return data;
	}

	/**
	 * Find elements based on their cb-attribute
	 */
	$.expr[':'].cbAttr = function(el, index, meta, stack)
	{
		var $el = $(el),
			args = (meta[3] || '').split(','),
			cb = $el.cbAttrs();

		if (!cb) return false;
		if (!!cb && !args.length) return true;
		if (!!args[0] && !args[1]) return args[0] in cb;
		if (!!args[0] && !!args[1]) return cb[args[0]] == args[1];
		return false;
	};

}<commit_msg>Added cbClass jQuery method<commit_after>/*
 * DOM and jQuery utilities
 * @author		Neil Rackett
 */

/**
 * Initialize Applications in the DOM using the specified namespace
 *
 * By default, Conbo scans the entire DOM, but you can limit the
 * scope by specifying a root element
 *
 * @memberof	conbo
 */
conbo.initDom = function(namespace, rootEl)
{
	var $rootEl = $(rootEl || 'html');

	if (conbo.isString(namespace))
	{
		namespace = conbo(namespace);
	}

	if (!conbo.isObject(namespace))
	{
		conbo.warn('Unable to initialize namespace:', namespace);
		return this;
	}

	$(function()
	{
		$rootEl.find('[cb-app]').not('.cb-app').each(function(index, el)
       	{
			var $el = $(el)
       		  , appName = $el.attr('cb-app')
       		  , appClass = namespace[appName]
       		  ;

       		if (appClass)
       		{
       			new appClass({el:el})
       		}
       	});
	});

	return this;
};

/**
 * @private
 */
var __observers = [];

/**
 * @private
 */
var __getObserverIndex = function(namespace, rootEl)
{
	var length = __observers.length;

	for (var i=0; i<length; i++)
	{
		var observer = __observers[i];

		if (observer[0] == namespace && observer[1] == rootEl)
		{
			return i;
		}
	}

	return -1;
};

/**
 * Watch the DOM for new Applications using the specified namespace
 *
 * By default, Conbo watches the entire DOM, but you can limit the
 * scope by specifying a root element
 *
 * @memberof	conbo
 */
conbo.observeDom = function(namespace, rootEl)
{
	if (conbo.isString(namespace))
	{
		namespace = conbo(namespace);
	}

	if (__getObserverIndex(namespace, rootEl) != -1)
	{
		return;
	}

	var mo;
	var $rootEl = $(rootEl || 'html');

	mo = new conbo.MutationObserver();
	mo.observe($rootEl[0]);

	mo.addEventListener(conbo.ConboEvent.ADD, function(event)
	{
		event.nodes.forEach(function(node)
		{
			var $node = $(node);
			var appName = $node.cbAttrs().app;

			if (namespace[appName] && !$node.hasClass('cb-app'))
			{
				new namespace[appName]({el:node});
			}
		});
	});

	__observers.push([namespace, rootEl, mo]);

	return this;
};

/**
 * Stop watching the DOM for new Applications
 *
 * @memberof	conbo
 */
conbo.unobserveDom = function(namespace, rootEl)
{
	if (conbo.isString(namespace))
	{
		namespace = conbo(namespace);
	}

	var i = __getObserverIndex(namespace, rootEl);

	if (i != -1)
	{
		var observer = __observers[i];

		observer[2].removeEventListener();
		__observers.slice(i,1);
	}

	return this;
};

if (!!$)
{
	/**
	 * Return a list of cb-* attributes on the DOM element
	 */
	$.fn.cbAttrs = function(camelCase)
	{
		var data = {},
			attrs = conbo.toArray(this.get()[0].attributes),
			count = 0,
			propertyName;

		for (var i=0; i<attrs.length; ++i)
		{
			if (attrs[i].name.indexOf('cb-') != 0) continue;

			propertyName = attrs[i].name.substr(3);

			if (camelCase !== false)
			{
				propertyName = conbo.toCamelCase(propertyName);
			}

			data[propertyName] = attrs[i].value;
		}

		return data;
	};

	/**
	 * Select child elements that are instances of the specified class
	 */
	$.fn.cbClass = function(viewClass)
	{
		return this.find('.cb-view .cb-glimpse').filter(function()
		{
			return conbo.instanceOf(this.cbView || this.cbGlimpse, viewClass);
		});
	};

	/**
	 * Find elements based on their cb-attribute
	 */
	$.expr[':'].cbAttr = function(el, index, meta, stack)
	{
		var $el = $(el),
			args = (meta[3] || '').split(','),
			cb = $el.cbAttrs();

		if (!cb) return false;
		if (!!cb && !args.length) return true;
		if (!!args[0] && !args[1]) return args[0] in cb;
		if (!!args[0] && !!args[1]) return cb[args[0]] == args[1];
		return false;
	};

}<|endoftext|>


<commit_before>/* global angular, bootbox */

angular.module('chatCtrl', ['SocketFactory'])

.controller('chatController', function($scope, Socket) {
    Socket.connect();
    $scope.users = [];
    $scope.messages = [];
    // $scope.msg = '';

    var promptUsername = function(message) {
        bootbox.prompt(message, function(name) {
            name = name || 'Guest' + new Date().getTime();
            if (name != null && (name = name.trim()).length > 0) {
                Socket.emit('add-user', {
                    username: name
                });
            }
            else {
                promptUsername('You must enter a username.');
            }
        });
    };

    $scope.sendMessage = function(msg) {
        if (msg != null && (msg = msg.trim()).length > 0) {
            Socket.emit('message', {
                message: msg
            });
        }
        $scope.msg = '';
    };
    Socket.on('users', function(data) {
        $scope.users = data.users;
    });

    Socket.on('message', function(data) {
        $scope.messages.push(data);
    });

    Socket.on('add-user', function(data) {
        $scope.users.push(data.username);
        $scope.messages.push({
            username: data.username,
            message: 'has entered the channel.'
        });
    });

    Socket.on('remove-user', function(data) {
        if ($scope.users.indexOf(data.username) >= 0)
            $scope.users.splice($scope.users.indexOf(data.username), 1);

        $scope.messages.push({
            username: data.username,
            message: 'has left the chat'
        });
    });

    Socket.on('prompt-username', function(data) {
        promptUsername(data.message);
    });

    $scope.$on('$locationChangeStart', function(event) {
        Socket.disconnect(true);
    });

    Socket.emit('request-users', {}, function() {
        alert('{}');
        promptUsername('What is your name?');
    });
});<commit_msg>Removed 'request-users' acknowledgemnt<commit_after>/* global angular, bootbox */

angular.module('chatCtrl', ['SocketFactory'])

.controller('chatController', function($scope, Socket) {
    Socket.connect();
    $scope.users = [];
    $scope.messages = [];
    // $scope.msg = '';

    var promptUsername = function(message) {
        bootbox.prompt(message, function(name) {
            name = name || 'Guest' + new Date().getTime();
            if (name != null && (name = name.trim()).length > 0) {
                Socket.emit('add-user', {
                    username: name
                });
            }
            else {
                promptUsername('You must enter a username.');
            }
        });
    };

    $scope.sendMessage = function(msg) {
        if (msg != null && (msg = msg.trim()).length > 0) {
            Socket.emit('message', {
                message: msg
            });
        }
        $scope.msg = '';
    };
    Socket.on('users', function(data) {
        $scope.users = data.users;
    });

    Socket.on('message', function(data) {
        $scope.messages.push(data);
    });

    Socket.on('add-user', function(data) {
        $scope.users.push(data.username);
        $scope.messages.push({
            username: data.username,
            message: 'has entered the channel.'
        });
    });

    Socket.on('remove-user', function(data) {
        if ($scope.users.indexOf(data.username) >= 0)
            $scope.users.splice($scope.users.indexOf(data.username), 1);

        $scope.messages.push({
            username: data.username,
            message: 'has left the chat'
        });
    });

    Socket.on('prompt-username', function(data) {
        promptUsername(data.message);
    });

    $scope.$on('$locationChangeStart', function(event) {
        Socket.disconnect(true);
    });

    Socket.emit('request-users');

    promptUsername('What is your name?');
});<|endoftext|>


<commit_before>// @flow

import React, { Component, Fragment, type Element, type Node } from 'react';
import styled from 'react-emotion';
import { Link } from 'react-router-dom';
import NodeResolver from 'react-node-resolver';

import { borderRadius, colors, gridSize } from '../../theme';

const ItemElement = props => {
  if (props.to) return <Link {...props} />;
  if (props.href) return <a {...props} />;
  return <button type="button" {...props} />;
};

const Item = styled(ItemElement)({
  appearance: 'none',
  background: 'none',
  border: '1px solid transparent',
  color: colors.text,
  cursor: 'pointer',
  display: 'block',
  fontSize: 14,
  lineHeight: '17px',
  margin: 0,
  padding: `${gridSize}px ${gridSize * 1.5}px`,
  textAlign: 'left',
  transition: 'box-shadow 100ms linear',
  verticalAlign: 'middle',
  whiteSpace: 'nowrap',
  width: '100%',

  '&:hover, &:focus': {
    backgroundColor: colors.B.L90,
    color: colors.primary,
    outline: 0,
    textDecoration: 'none',
  },
});
const Menu = styled.div({
  backgroundColor: 'white',
  borderRadius: borderRadius,
  boxShadow: '0 0 0 1px rgba(0, 0, 0, 0.175), 0 3px 8px rgba(0, 0, 0, 0.175)',
  marginTop: gridSize,
  maxHeight: '100%',
  minWidth: 160,
  position: 'absolute',
});

type ItemType = {
  to?: string,
  content: Node,
  href?: string,
  onClick?: (*) => void,
};
type ClickArgs = { onClick?: MouseEvent => void };
type Props = {
  children: Element<*>,
  defaultIsOpen: boolean,
  items: Array<ItemType>,
  selectClosesMenu: boolean,
};
type State = { isOpen: boolean };

function focus(el) {
  if (el && typeof el.focus === 'function') {
    el.focus();
  }
}

export default class Dropdown extends Component<Props, State> {
  lastHover: HTMLElement;
  menu: HTMLElement;
  target: HTMLElement;
  state = { isOpen: this.props.defaultIsOpen };
  static defaultProps = {
    selectClosesMenu: true,
  };

  componentDidMount() {
    document.addEventListener('click', this.handleClick);
    document.addEventListener('keydown', this.handleKeyDown, false);
  }
  componentWillUnmount() {
    document.removeEventListener('click', this.handleClick);
    document.removeEventListener('keydown', this.handleKeyDown, false);
  }

  open = () => {
    this.setState({ isOpen: true });
    focus(this.menu.firstChild);
  };
  close = ({ returnFocus }: { returnFocus: boolean }) => {
    this.setState({ isOpen: false });
    if (returnFocus) this.target.focus();
  };

  handleClick = ({ target }: MouseEvent) => {
    const { isOpen } = this.state;

    // appease flow
    if (!(target instanceof HTMLElement)) return;

    // close on outside click
    if (isOpen && !this.menu.contains(target)) {
      this.close({ returnFocus: false });
    }

    // open on target click
    if (!isOpen && this.target.contains(target)) {
      this.open();
    }
  };
  handleItemClick = ({ onClick }: ClickArgs) => (event: MouseEvent) => {
    const { selectClosesMenu } = this.props;
    if (selectClosesMenu) this.close({ returnFocus: true });
    if (onClick) onClick(event);
  };
  handleKeyDown = (event: KeyboardEvent) => {
    const { key, target } = event;
    const { isOpen } = this.state;

    if (!isOpen || !(target instanceof HTMLElement)) return;

    if (key === 'Escape') {
      this.close({ returnFocus: true });
      return;
    }

    const isArrowUp = key === 'ArrowUp';
    const isArrowDown = key === 'ArrowDown';
    const isPageUp = key === 'PageUp';
    const isPageDown = key === 'PageDown';

    const firstItem = this.menu.firstChild;
    const lastItem = this.menu.lastChild;
    const preventScroll = isArrowUp || isArrowDown || isPageUp || isPageDown;

    if (preventScroll) event.preventDefault();

    if (isArrowUp) focus(target.previousSibling);
    else if (isArrowDown) focus(target.nextSibling);
    else if (isPageUp) focus(firstItem);
    else if (isPageDown) focus(lastItem);
  };
  handleMouseOver = ({ target }: MouseEvent) => {
    if (target instanceof HTMLElement) {
      this.lastHover = target;
    }

    if (document.activeElement) {
      document.activeElement.blur();
    }
  };
  handleMenuLeave = () => {
    this.lastHover.focus();
  };

  getTarget = (ref: HTMLElement) => {
    this.target = ref;
  };
  getMenu = (ref: HTMLElement) => {
    this.menu = ref;
  };

  render() {
    const { children, items } = this.props;
    const { isOpen } = this.state;

    return (
      <Fragment>
        <NodeResolver innerRef={this.getTarget}>{children}</NodeResolver>
        {isOpen ? (
          <Menu innerRef={this.getMenu} onMouseLeave={this.handleMenuLeave}>
            {items.map(({ content, ...rest }, idx) => (
              <Item
                {...rest}
                onClick={this.handleItemClick(rest)}
                onMouseOver={this.handleMouseOver}
                key={idx}
              >
                {content}
              </Item>
            ))}
          </Menu>
        ) : null}
      </Fragment>
    );
  }
}
<commit_msg>support tab looping in dropdown menu<commit_after>// @flow

import React, { Component, Fragment, type Element, type Node } from 'react';
import styled from 'react-emotion';
import { Link } from 'react-router-dom';
import NodeResolver from 'react-node-resolver';

import { borderRadius, colors, gridSize } from '../../theme';

const ItemElement = props => {
  if (props.to) return <Link {...props} />;
  if (props.href) return <a {...props} />;
  return <button type="button" {...props} />;
};

const Item = styled(ItemElement)({
  appearance: 'none',
  background: 'none',
  border: '1px solid transparent',
  color: colors.text,
  cursor: 'pointer',
  display: 'block',
  fontSize: 14,
  lineHeight: '17px',
  margin: 0,
  padding: `${gridSize}px ${gridSize * 1.5}px`,
  textAlign: 'left',
  transition: 'box-shadow 100ms linear',
  verticalAlign: 'middle',
  whiteSpace: 'nowrap',
  width: '100%',

  '&:hover, &:focus': {
    backgroundColor: colors.B.L90,
    color: colors.primary,
    outline: 0,
    textDecoration: 'none',
  },
});
const Menu = styled.div({
  backgroundColor: 'white',
  borderRadius: borderRadius,
  boxShadow: '0 0 0 1px rgba(0, 0, 0, 0.175), 0 3px 8px rgba(0, 0, 0, 0.175)',
  marginTop: gridSize,
  maxHeight: '100%',
  minWidth: 160,
  position: 'absolute',
});

type ItemType = {
  to?: string,
  content: Node,
  href?: string,
  onClick?: (*) => void,
};
type ClickArgs = { onClick?: MouseEvent => void };
type Props = {
  children: Element<*>,
  defaultIsOpen: boolean,
  items: Array<ItemType>,
  selectClosesMenu: boolean,
};
type State = { isOpen: boolean };

function focus(el) {
  if (el && typeof el.focus === 'function') {
    el.focus();
  }
}

export default class Dropdown extends Component<Props, State> {
  lastHover: HTMLElement;
  menu: HTMLElement;
  target: HTMLElement;
  state = { isOpen: this.props.defaultIsOpen };
  static defaultProps = {
    selectClosesMenu: true,
  };

  componentDidMount() {
    document.addEventListener('click', this.handleClick);
    document.addEventListener('keydown', this.handleKeyDown, false);
  }
  componentWillUnmount() {
    document.removeEventListener('click', this.handleClick);
    document.removeEventListener('keydown', this.handleKeyDown, false);
  }

  open = () => {
    this.setState({ isOpen: true });
    focus(this.menu.firstChild);
  };
  close = ({ returnFocus }: { returnFocus: boolean }) => {
    this.setState({ isOpen: false });
    if (returnFocus) this.target.focus();
  };

  handleClick = ({ target }: MouseEvent) => {
    const { isOpen } = this.state;

    // appease flow
    if (!(target instanceof HTMLElement)) return;

    // close on outside click
    if (isOpen && !this.menu.contains(target)) {
      this.close({ returnFocus: false });
    }

    // open on target click
    if (!isOpen && this.target.contains(target)) {
      this.open();
    }
  };
  handleItemClick = ({ onClick }: ClickArgs) => (event: MouseEvent) => {
    const { selectClosesMenu } = this.props;
    if (selectClosesMenu) this.close({ returnFocus: true });
    if (onClick) onClick(event);
  };
  handleKeyDown = (event: KeyboardEvent) => {
    const { key, target } = event;
    const { isOpen } = this.state;

    if (!isOpen || !(target instanceof HTMLElement)) return;

    if (key === 'Escape') {
      this.close({ returnFocus: true });
      return;
    }

    const isArrowUp = key === 'ArrowUp';
    const isArrowDown = key === 'ArrowDown';
    const isPageUp = key === 'PageUp';
    const isPageDown = key === 'PageDown';

    const firstItem = this.menu.firstChild;
    const lastItem = this.menu.lastChild;
    const preventScroll = isArrowUp || isArrowDown || isPageUp || isPageDown;

    if (preventScroll) event.preventDefault();

    // typical item traversal
    if (isArrowUp) focus(target.previousSibling);
    if (isArrowDown) focus(target.nextSibling);
    if (isPageUp) focus(firstItem);
    if (isPageDown) focus(lastItem);

    // support looping
    if (target === firstItem && isArrowUp) focus(lastItem);
    if (target === lastItem && isArrowDown) focus(firstItem);
  };
  handleMouseOver = ({ target }: MouseEvent) => {
    if (target instanceof HTMLElement) {
      this.lastHover = target;
    }

    if (document.activeElement) {
      document.activeElement.blur();
    }
  };
  handleMenuLeave = () => {
    this.lastHover.focus();
  };

  getTarget = (ref: HTMLElement) => {
    this.target = ref;
  };
  getMenu = (ref: HTMLElement) => {
    this.menu = ref;
  };

  render() {
    const { children, items } = this.props;
    const { isOpen } = this.state;

    return (
      <Fragment>
        <NodeResolver innerRef={this.getTarget}>{children}</NodeResolver>
        {isOpen ? (
          <Menu innerRef={this.getMenu} onMouseLeave={this.handleMenuLeave}>
            {items.map(({ content, ...rest }, idx) => (
              <Item
                {...rest}
                onClick={this.handleItemClick(rest)}
                onMouseOver={this.handleMouseOver}
                key={idx}
              >
                {content}
              </Item>
            ))}
          </Menu>
        ) : null}
      </Fragment>
    );
  }
}
<|endoftext|>


<commit_before>(function(jQuery, $) {
	jQuery.fn.login = function(options) {
		options = jQuery.extend({}, jQuery.fn.login.options, options);
		var user;

		user = localStorage.getItem(options.lsUserKey);
		if (user !== null) {
			user = JSON.parse(user);
			$.ajax({
				url: '/login',
				method: 'POST',
				data: user,
				success: function(data) {
					jQuery.fn.login.postLogin(user, options);
				}
			});
		}

		// Klickhandler registrieren
		$(this).each(function(key, item) {
			var eventData;

			eventData = {
				options: options,
				form: item
			};

			$(item).on('submit', eventData, jQuery.fn.login.loginUser);
		});
	};

	jQuery.fn.login.loginUser = function(event) {
		var options;

		// Prevent default and disable login button
		event.preventDefault();
		$(event.data.form).find('.poker-login-submit').attr('disabled', 'disabled');

		options = event.data.options;

		$.ajax({
			url: '/login',
			method: 'POST',
			data: $(event.data.form).serialize(),
			success: function(data) {
				localStorage.setItem(options.lsUserKey, JSON.stringify(data));
				jQuery.fn.login.postLogin(data, options);
			},
			fail: function(data) {
				$(event.data.form).find('.poker-login-submit').removeAttr('disabled');
			}
		});
	};

	jQuery.fn.login.postLogin = function(user, options) {
		jQuery.fn.login.preparePageForRole(user.role, options);
		jQuery.fn.login.updateUserInfo(user, options);
		jQuery.fn.login.openWebSocket(options);
		$(options.overlay).hide(400);
	};

	jQuery.fn.login.preparePageForRole = function(role, options) {
		for (var i in options.roleSettings[role].hide) {
			$(options.roleSettings[role][i]).hide();
		}

		for (var i in options.roleSettings[role].show) {
			$(options.roleSettings[role][i]).show();
		}
	};

	jQuery.fn.login.updateUserInfo = function(user, options) {
		console.log(user);
		$(options.nameClass).html(user.name);
		$(options.roleClass).html(options.availableRoles[user.role]);
		$(options.userInfoClass).show();
	};

	jQuery.fn.login.openWebSocket = function(options) {
		window.managedSocket.open();
	}

	jQuery.fn.login.options = {
		availableRoles: {
			developer: 'Entwickler',
			productOwner: 'Product Owner',
			scrumMaster: 'Scrum Master'
		},
		roleSettings: {
			developer: {
				show: [],
				hide: []
			},
			scrumMaster: {
				show: [],
				hide: []
			},
			productOwner: {
				show: [],
				hide: []
			}
		},
		overlay: null,
		lsUserKey: 'user',
		nameClass: null,
		roleClass: null
	};
})(jQuery, jQuery);<commit_msg>Page preparation for different roles<commit_after>(function(jQuery, $) {
	jQuery.fn.login = function(options) {
		options = jQuery.extend({}, jQuery.fn.login.options, options);
		var user;

		user = localStorage.getItem(options.lsUserKey);
		if (user !== null) {
			user = JSON.parse(user);
			$.ajax({
				url: '/login',
				method: 'POST',
				data: user,
				success: function(data) {
					jQuery.fn.login.postLogin(user, options);
				}
			});
		}

		// Klickhandler registrieren
		$(this).each(function(key, item) {
			var eventData;

			eventData = {
				options: options,
				form: item
			};

			$(item).on('submit', eventData, jQuery.fn.login.loginUser);
		});
	};

	jQuery.fn.login.loginUser = function(event) {
		var options;

		// Prevent default and disable login button
		event.preventDefault();
		$(event.data.form).find('.poker-login-submit').attr('disabled', 'disabled');

		options = event.data.options;

		$.ajax({
			url: '/login',
			method: 'POST',
			data: $(event.data.form).serialize(),
			success: function(data) {
				localStorage.setItem(options.lsUserKey, JSON.stringify(data));
				jQuery.fn.login.postLogin(data, options);
			},
			fail: function(data) {
				$(event.data.form).find('.poker-login-submit').removeAttr('disabled');
			}
		});
	};

	jQuery.fn.login.postLogin = function(user, options) {
		jQuery.fn.login.preparePageForRole(user.role, options);
		jQuery.fn.login.updateUserInfo(user, options);
		jQuery.fn.login.openWebSocket(options);
		$(options.overlay).hide(400);
	};

	jQuery.fn.login.preparePageForRole = function(role, options) {
		for (var i in options.roleSettings[role].hide) {
			$(options.roleSettings[role].hide[i]).hide();
		}

		for (var i in options.roleSettings[role].show) {
			$(options.roleSettings[role].show[i]).show();
		}
	};

	jQuery.fn.login.updateUserInfo = function(user, options) {
		$(options.nameClass).html(user.name);
		$(options.roleClass).html(options.availableRoles[user.role]);
		$(options.userInfoClass).show();
	};

	jQuery.fn.login.openWebSocket = function(options) {
		window.managedSocket.open();
	}

	jQuery.fn.login.options = {
		availableRoles: {
			developer: 'Entwickler',
			productOwner: 'Product Owner',
			scrumMaster: 'Scrum Master'
		},
		roleSettings: {
			developer: {
				show: [],
				hide: []
			},
			scrumMaster: {
				show: [],
				hide: []
			},
			productOwner: {
				show: [],
				hide: []
			}
		},
		overlay: null,
		lsUserKey: 'user',
		nameClass: null,
		roleClass: null
	};
})(jQuery, jQuery);<|endoftext|>


<commit_before>const {
  info,
  openBrowser,
  IpcMessenger
} = require('@vue/cli-shared-utils')

const defaults = {
  host: '0.0.0.0',
  port: 8080,
  https: false
}

module.exports = (api, options) => {
  api.registerCommand('uni-serve', {
    description: 'start development server',
    usage: 'vue-cli-service uni-serve [options] [entry]',
    options: {
      '--open': `open browser on server start`,
      '--copy': `copy url to clipboard on server start`,
      '--mode': `specify env mode (default: development)`,
      '--host': `specify host (default: ${defaults.host})`,
      '--port': `specify port (default: ${defaults.port})`,
      '--https': `use https (default: ${defaults.https})`,
      '--public': `specify the public network URL for the HMR client`
    }
  }, async function serve (args) {
    info('Starting development server...')

    // although this is primarily a dev server, it is possible that we
    // are running it in a mode with a production env, e.g. in E2E tests.
    const isInContainer = checkInContainer()
    const isProduction = process.env.NODE_ENV === 'production'

    const url = require('url')
    const path = require('path')
    const chalk = require('chalk')
    const webpack = require('webpack')
    const WebpackDevServer = require('webpack-dev-server')
    const portfinder = require('portfinder')
    const prepareURLs = require('@vue/cli-service/lib/util/prepareURLs')
    const prepareProxy = require('@vue/cli-service/lib/util/prepareProxy')
    const launchEditorMiddleware = require('launch-editor-middleware')
    const validateWebpackConfig = require('@vue/cli-service/lib/util/validateWebpackConfig')
    const isAbsoluteUrl = require('@vue/cli-service/lib/util/isAbsoluteUrl')

    // resolve webpack config
    const webpackConfig = api.resolveWebpackConfig()

    // check for common config errors
    validateWebpackConfig(webpackConfig, api, options)

    // load user devServer options with higher priority than devServer
    // in webpck config
    const projectDevServerOptions = Object.assign(
      webpackConfig.devServer || {},
      options.devServer
    )

    // expose advanced stats
    if (args.dashboard) {
      const DashboardPlugin = require('@vue/cli-service/lib/webpack/DashboardPlugin');
      (webpackConfig.plugins = webpackConfig.plugins || []).push(new DashboardPlugin({
        type: 'serve'
      }))
    }

    // entry arg
    const entry = args._[0]
    if (entry) {
      webpackConfig.entry = {
        app: api.resolve(entry)
      }
    }

    // resolve server options
    const useHttps = args.https || projectDevServerOptions.https || defaults.https
    const protocol = useHttps ? 'https' : 'http'
    const host = args.host || process.env.HOST || projectDevServerOptions.host || defaults.host
    portfinder.basePort = args.port || process.env.PORT || projectDevServerOptions.port || defaults
      .port
    const port = await portfinder.getPortPromise()
    const rawPublicUrl = args.public || projectDevServerOptions.public
    const publicUrl = rawPublicUrl
      ? /^[a-zA-Z]+:\/\//.test(rawPublicUrl)
        ? rawPublicUrl
        : `${protocol}://${rawPublicUrl}`
      : null

    const urls = prepareURLs(
      protocol,
      host,
      port,
      isAbsoluteUrl(options.publicPath) ? '/' : options.publicPath
    )

    const proxySettings = prepareProxy(
      projectDevServerOptions.proxy,
      api.resolve('public')
    )

    // inject dev & hot-reload middleware entries
    if (!isProduction) {
      const sockjsUrl = publicUrl
      // explicitly configured via devServer.public
        ? `?${publicUrl}/sockjs-node`
        : isInContainer
        // can't infer public netowrk url if inside a container...
        // use client-side inference (note this would break with non-root publicPath)
          ? ``
        // otherwise infer the url
          : `?` + url.format({
            protocol,
            port,
            hostname: urls.lanUrlForConfig || 'localhost',
            pathname: '/sockjs-node'
          })
      const devClients = [
        // dev server client
        require.resolve(`webpack-dev-server/client`) + sockjsUrl,
        // hmr client
        require.resolve(projectDevServerOptions.hotOnly
          ? 'webpack/hot/only-dev-server'
          : 'webpack/hot/dev-server')
        // TODO custom overlay client
        // `@vue/cli-overlay/dist/client`
      ]
      if (process.env.APPVEYOR) {
        devClients.push(`webpack/hot/poll?500`)
      }
      // inject dev/hot client
      addDevClientToEntry(webpackConfig, devClients)
    }

    // create compiler
    const compiler = webpack(webpackConfig)

    // create server
    const server = new WebpackDevServer(compiler, Object.assign({
      clientLogLevel: 'none',
      historyApiFallback: {
        disableDotRule: true,
        rewrites: [{
          from: /./,
          to: path.posix.join(options.publicPath, 'index.html')
        }]
      },
      contentBase: api.resolve('public'),
      watchContentBase: !isProduction,
      hot: !isProduction,
      quiet: true,
      compress: isProduction,
      publicPath: options.publicPath,
      overlay: isProduction // TODO disable this
        ? false : {
          warnings: false,
          errors: true
        }
    }, projectDevServerOptions, {
      https: useHttps,
      proxy: proxySettings,
      before (app, server) {
        // launch editor support.
        // this works with vue-devtools & @vue/cli-overlay
        app.use('/__open-in-editor', launchEditorMiddleware(() => console.log(
          `To specify an editor, sepcify the EDITOR env variable or ` +
                    `add "editor" field to your Vue project config.\n`
        )))
        // allow other plugins to register middlewares, e.g. PWA
        api.service.devServerConfigFns.forEach(fn => fn(app, server))
        // apply in project middlewares
        projectDevServerOptions.before && projectDevServerOptions.before(app,
          server)
      }
    }))

        ;
    ['SIGINT', 'SIGTERM'].forEach(signal => {
      process.on(signal, () => {
        server.close(() => {
          process.exit(0)
        })
      })
    })

    // on appveyor, killing the process with SIGTERM causes execa to
    // throw error
    if (process.env.VUE_CLI_TEST) {
      process.stdin.on('data', data => {
        if (data.toString() === 'close') {
          console.log('got close signal!')
          server.close(() => {
            process.exit(0)
          })
        }
      })
    }

    return new Promise((resolve, reject) => {
      // log instructions & open browser on first compilation complete
      let isFirstCompile = true
      compiler.hooks.done.tap('vue-cli-service uni-serve', stats => {
        if (stats.hasErrors()) {
          return
        }

        let copied = ''
        if (isFirstCompile && args.copy) {
          require('clipboardy').write(urls.localUrlForBrowser)
          copied = chalk.dim('(copied to clipboard)')
        }

        const networkUrl = publicUrl
          ? publicUrl.replace(/([^/])$/, '$1/')
          : urls.lanUrlForTerminal

        console.log()
        console.log(`  App running at:`)
        console.log(
          `  - Local:   ${chalk.cyan(urls.localUrlForTerminal)} ${copied}`
        )
        if (!isInContainer) {
          console.log(`  - Network: ${chalk.cyan(networkUrl)}`)
        } else {
          console.log()
          console.log(chalk.yellow(
            `  It seems you are running Vue CLI inside a container.`
          ))
          if (!publicUrl && options.publicPath && options.publicPath !== '/') {
            console.log()
            console.log(chalk.yellow(
              `  Since you are using a non-root publicPath, the hot-reload socket`
            ))
            console.log(chalk.yellow(
              `  will not be able to infer the correct URL to connect. You should`
            ))
            console.log(chalk.yellow(
              `  explicitly specify the URL via ${chalk.blue(`devServer.public`)}.`
            ))
            console.log()
          }
          console.log(chalk.yellow(
            `  Access the dev server via ${chalk.cyan(
              `${protocol}://localhost:<your container's external mapped port>${options.publicPath}`
            )}`
          ))
        }
        console.log()

        if (isFirstCompile) {
          isFirstCompile = false

          if (!isProduction) {
            if (process.UNI_CLOUD) {
              console.warn(`当前项目使用了uniCloud，为避免云函数调用跨域问题，建议在HBuilderX内置浏览器里调试，如使用外部浏览器需安装跨域插件，详见：https://ask.dcloud.net.cn/article/35267`)
            }
            // const buildCommand = hasProjectYarn(api.getCwd()) ? `yarn build` : `npm run build`
            // console.log(`  Note that the development build is not optimized.`)
            // console.log(`  To create a production build, run ${chalk.cyan(buildCommand)}.`)
          } else {
            console.log(`  App is served in production mode.`)
            console.log(`  Note this is for preview or E2E testing only.`)
          }
          console.log()

          if (args.open || projectDevServerOptions.open) {
            const pageUri = (projectDevServerOptions.openPage && typeof projectDevServerOptions
              .openPage === 'string')
              ? projectDevServerOptions.openPage
              : ''
            openBrowser(urls.localUrlForBrowser + pageUri)
          }

          // Send final app URL
          if (args.dashboard) {
            const ipc = new IpcMessenger()
            ipc.send({
              vueServe: {
                url: urls.localUrlForBrowser
              }
            })
          }

          // resolve returned Promise
          // so other commands can do api.service.run('serve').then(...)
          resolve({
            server,
            url: urls.localUrlForBrowser
          })
        } else if (process.env.VUE_CLI_TEST) {
          // signal for test to check HMR
          console.log('App updated')
        }
      })

      server.listen(port, host, err => {
        if (err) {
          reject(err)
        }
      })
    })
  })
}

function addDevClientToEntry (config, devClient) {
  const {
    entry
  } = config
  if (typeof entry === 'object' && !Array.isArray(entry)) {
    Object.keys(entry).forEach((key) => {
      entry[key] = devClient.concat(entry[key])
    })
  } else if (typeof entry === 'function') {
    config.entry = entry(devClient)
  } else {
    config.entry = devClient.concat(entry)
  }
}

// https://stackoverflow.com/a/20012536
function checkInContainer () {
  const fs = require('fs')
  if (fs.existsSync(`/proc/1/cgroup`)) {
    const content = fs.readFileSync(`/proc/1/cgroup`, 'utf-8')
    return /:\/(lxc|docker|kubepods)\//.test(content)
  }
}

module.exports.defaultModes = {
  serve: 'development'
}
<commit_msg>Update serve.js<commit_after>const {
  info,
  openBrowser,
  IpcMessenger
} = require('@vue/cli-shared-utils')

const defaults = {
  host: '0.0.0.0',
  port: 8080,
  https: false
}

module.exports = (api, options) => {
  api.registerCommand('uni-serve', {
    description: 'start development server',
    usage: 'vue-cli-service uni-serve [options] [entry]',
    options: {
      '--open': `open browser on server start`,
      '--copy': `copy url to clipboard on server start`,
      '--mode': `specify env mode (default: development)`,
      '--host': `specify host (default: ${defaults.host})`,
      '--port': `specify port (default: ${defaults.port})`,
      '--https': `use https (default: ${defaults.https})`,
      '--public': `specify the public network URL for the HMR client`
    }
  }, async function serve (args) {
    info('Starting development server...')

    // although this is primarily a dev server, it is possible that we
    // are running it in a mode with a production env, e.g. in E2E tests.
    const isInContainer = checkInContainer()
    const isProduction = process.env.NODE_ENV === 'production'

    const url = require('url')
    const path = require('path')
    const chalk = require('chalk')
    const webpack = require('webpack')
    const WebpackDevServer = require('webpack-dev-server')
    const portfinder = require('portfinder')
    const prepareURLs = require('@vue/cli-service/lib/util/prepareURLs')
    const prepareProxy = require('@vue/cli-service/lib/util/prepareProxy')
    const launchEditorMiddleware = require('launch-editor-middleware')
    const validateWebpackConfig = require('@vue/cli-service/lib/util/validateWebpackConfig')
    const isAbsoluteUrl = require('@vue/cli-service/lib/util/isAbsoluteUrl')

    // resolve webpack config
    const webpackConfig = api.resolveWebpackConfig()

    // check for common config errors
    validateWebpackConfig(webpackConfig, api, options)

    // load user devServer options with higher priority than devServer
    // in webpck config
    const projectDevServerOptions = Object.assign(
      webpackConfig.devServer || {},
      options.devServer
    )

    // expose advanced stats
    if (args.dashboard) {
      const DashboardPlugin = require('@vue/cli-service/lib/webpack/DashboardPlugin');
      (webpackConfig.plugins = webpackConfig.plugins || []).push(new DashboardPlugin({
        type: 'serve'
      }))
    }

    // entry arg
    const entry = args._[0]
    if (entry) {
      webpackConfig.entry = {
        app: api.resolve(entry)
      }
    }

    // resolve server options
    const useHttps = args.https || projectDevServerOptions.https || defaults.https
    const protocol = useHttps ? 'https' : 'http'
    const host = args.host || process.env.HOST || projectDevServerOptions.host || defaults.host
    portfinder.basePort = args.port || process.env.PORT || projectDevServerOptions.port || defaults
      .port
    const port = await portfinder.getPortPromise()
    const rawPublicUrl = args.public || projectDevServerOptions.public
    const publicUrl = rawPublicUrl
      ? /^[a-zA-Z]+:\/\//.test(rawPublicUrl)
        ? rawPublicUrl
        : `${protocol}://${rawPublicUrl}`
      : null

    const urls = prepareURLs(
      protocol,
      host,
      port,
      isAbsoluteUrl(options.publicPath) ? '/' : options.publicPath
    )

    const proxySettings = prepareProxy(
      projectDevServerOptions.proxy,
      api.resolve('public')
    )

    // inject dev & hot-reload middleware entries
    if (!isProduction) {
      const sockjsUrl = publicUrl
      // explicitly configured via devServer.public
        ? `?${publicUrl}/sockjs-node`
        : isInContainer
        // can't infer public netowrk url if inside a container...
        // use client-side inference (note this would break with non-root publicPath)
          ? ``
        // otherwise infer the url
          : `?` + url.format({
            protocol,
            port,
            hostname: urls.lanUrlForConfig || 'localhost',
            pathname: '/sockjs-node'
          })
      const devClients = [
        // dev server client
        require.resolve(`webpack-dev-server/client`) + sockjsUrl,
        // hmr client
        require.resolve(projectDevServerOptions.hotOnly
          ? 'webpack/hot/only-dev-server'
          : 'webpack/hot/dev-server')
        // TODO custom overlay client
        // `@vue/cli-overlay/dist/client`
      ]
      if (process.env.APPVEYOR) {
        devClients.push(`webpack/hot/poll?500`)
      }
      // inject dev/hot client
      addDevClientToEntry(webpackConfig, devClients)
    }

    // create compiler
    const compiler = webpack(webpackConfig)

    // create server
    const server = new WebpackDevServer(compiler, Object.assign({
      clientLogLevel: 'none',
      historyApiFallback: {
        disableDotRule: true,
        rewrites: [{
          from: /./,
          to: path.posix.join(options.publicPath, 'index.html')
        }]
      },
      contentBase: api.resolve('public'),
      watchContentBase: !isProduction,
      hot: !isProduction,
      quiet: true,
      compress: isProduction,
      publicPath: options.publicPath,
      overlay: isProduction // TODO disable this
        ? false : {
          warnings: false,
          errors: true
        }
    }, projectDevServerOptions, {
      https: useHttps,
      proxy: proxySettings,
      before (app, server) {
        // launch editor support.
        // this works with vue-devtools & @vue/cli-overlay
        app.use('/__open-in-editor', launchEditorMiddleware(() => console.log(
          `To specify an editor, sepcify the EDITOR env variable or ` +
                    `add "editor" field to your Vue project config.\n`
        )))
        // allow other plugins to register middlewares, e.g. PWA
        api.service.devServerConfigFns.forEach(fn => fn(app, server))
        // apply in project middlewares
        projectDevServerOptions.before && projectDevServerOptions.before(app,
          server)
      }
    }))

        ;
    ['SIGINT', 'SIGTERM'].forEach(signal => {
      process.on(signal, () => {
        server.close(() => {
          process.exit(0)
        })
      })
    })

    // on appveyor, killing the process with SIGTERM causes execa to
    // throw error
    if (process.env.VUE_CLI_TEST) {
      process.stdin.on('data', data => {
        if (data.toString() === 'close') {
          console.log('got close signal!')
          server.close(() => {
            process.exit(0)
          })
        }
      })
    }

    return new Promise((resolve, reject) => {
      // log instructions & open browser on first compilation complete
      let isFirstCompile = true
      compiler.hooks.done.tap('vue-cli-service uni-serve', stats => {
        if (stats.hasErrors()) {
          return
        }

        let copied = ''
        if (isFirstCompile && args.copy) {
          require('clipboardy').write(urls.localUrlForBrowser)
          copied = chalk.dim('(copied to clipboard)')
        }

        const networkUrl = publicUrl
          ? publicUrl.replace(/([^/])$/, '$1/')
          : urls.lanUrlForTerminal

        console.log()
        console.log(`  App running at:`)
        console.log(
          `  - Local:   ${chalk.cyan(urls.localUrlForTerminal)} ${copied}`
        )
        if (!isInContainer) {
          console.log(`  - Network: ${chalk.cyan(networkUrl)}`)
        } else {
          console.log()
          console.log(chalk.yellow(
            `  It seems you are running Vue CLI inside a container.`
          ))
          if (!publicUrl && options.publicPath && options.publicPath !== '/') {
            console.log()
            console.log(chalk.yellow(
              `  Since you are using a non-root publicPath, the hot-reload socket`
            ))
            console.log(chalk.yellow(
              `  will not be able to infer the correct URL to connect. You should`
            ))
            console.log(chalk.yellow(
              `  explicitly specify the URL via ${chalk.blue(`devServer.public`)}.`
            ))
            console.log()
          }
          console.log(chalk.yellow(
            `  Access the dev server via ${chalk.cyan(
              `${protocol}://localhost:<your container's external mapped port>${options.publicPath}`
            )}`
          ))
        }
        console.log()

        if (isFirstCompile) {
          isFirstCompile = false

          if (!isProduction) {
            if (process.UNI_CLOUD) {
              console.warn(`当前项目使用了uniCloud，为避免云函数调用跨域问题，建议在HBuilderX内置浏览器(win版)里调试，如使用外部浏览器需安装跨域插件，详见：https://ask.dcloud.net.cn/article/35267`)
            }
            // const buildCommand = hasProjectYarn(api.getCwd()) ? `yarn build` : `npm run build`
            // console.log(`  Note that the development build is not optimized.`)
            // console.log(`  To create a production build, run ${chalk.cyan(buildCommand)}.`)
          } else {
            console.log(`  App is served in production mode.`)
            console.log(`  Note this is for preview or E2E testing only.`)
          }
          console.log()

          if (args.open || projectDevServerOptions.open) {
            const pageUri = (projectDevServerOptions.openPage && typeof projectDevServerOptions
              .openPage === 'string')
              ? projectDevServerOptions.openPage
              : ''
            openBrowser(urls.localUrlForBrowser + pageUri)
          }

          // Send final app URL
          if (args.dashboard) {
            const ipc = new IpcMessenger()
            ipc.send({
              vueServe: {
                url: urls.localUrlForBrowser
              }
            })
          }

          // resolve returned Promise
          // so other commands can do api.service.run('serve').then(...)
          resolve({
            server,
            url: urls.localUrlForBrowser
          })
        } else if (process.env.VUE_CLI_TEST) {
          // signal for test to check HMR
          console.log('App updated')
        }
      })

      server.listen(port, host, err => {
        if (err) {
          reject(err)
        }
      })
    })
  })
}

function addDevClientToEntry (config, devClient) {
  const {
    entry
  } = config
  if (typeof entry === 'object' && !Array.isArray(entry)) {
    Object.keys(entry).forEach((key) => {
      entry[key] = devClient.concat(entry[key])
    })
  } else if (typeof entry === 'function') {
    config.entry = entry(devClient)
  } else {
    config.entry = devClient.concat(entry)
  }
}

// https://stackoverflow.com/a/20012536
function checkInContainer () {
  const fs = require('fs')
  if (fs.existsSync(`/proc/1/cgroup`)) {
    const content = fs.readFileSync(`/proc/1/cgroup`, 'utf-8')
    return /:\/(lxc|docker|kubepods)\//.test(content)
  }
}

module.exports.defaultModes = {
  serve: 'development'
}
<|endoftext|>


<commit_before>$(document).ready(function () {
	var $form = $('form');
	var $img_add_btn = $form.find('#img_plus');
	var $model = $form.find('#thumbnail_model');
	var s3_url = $model.data('s3-url');
	var $input_image_files = $form.find('input[name="image_files"]');
	var $sortable_div = $form.find('div.sortable');

	function rewrite_image_files_input(){
		var image_files = [];
		$sortable_div.children('[data-file]').each(function(){
			image_files.push($(this).data('file'));
		});
		$input_image_files.val(JSON.stringify(image_files));
	}

	Sortable.create($sortable_div.get(0), {
		onEnd: function(evt){
			rewrite_image_files_input();
		}
	});

	$form.find('span.img-delete').click(function() {
		$(this).closest('div.thumbnail-col').remove();
		rewrite_image_files_input();
	});

    $('#fileupload').bind('fileuploadprocessfail', function (e, data) {
		var error = (data.files[data.index].error == 'File type not allowed') ? 'Fout bestandstype' : data.files[data.index].error;
		alert(error);
		$img_add_btn.removeClass('fa-spin fa-spinner').addClass('fa-plus');
	}).fileupload({

		disableImageResize: /Android(?!.*Chrome)|Opera/
			.test(window.navigator.userAgent),
		imageMaxWidth: 400,
		imageMaxHeight: 400,
		imageOrientation: true

	}).on('fileuploadadd', function (e, data) {
		$img_add_btn.removeClass('fa-plus').addClass('fa-spinner fa-spin');
	}).on('fileuploaddone', function (e, data) {

		$img_add_btn.removeClass('fa-spin fa-spinner').addClass('fa-plus');

        $.each(data.result, function (index, file) {

            if (file) {
				var $thumbnail = $model.clone();
				$thumbnail.removeAttr('id');
				$thumbnail.attr('data-file', file);
				var $img = $thumbnail.find('img');
				$img.attr('src', s3_url + file);

				$thumbnail.find('span.img-delete').click(function(){
					$(this).closest('div.thumbnail-col').remove();
					$thumbnail.remove();
				});

				$thumbnail.removeClass('hidden');
				$model.parent().append($thumbnail);
				rewrite_image_files_input();
            } else {
				alert('Fout bij het opladen van de afbeelding.');
			}
        });

     }).prop('disabled', !$.support.fileInput)
        .parent().addClass($.support.fileInput ? undefined : 'disabled');
});
<commit_msg>fix image delete<commit_after>$(document).ready(function () {
	var $form = $('form');
	var $img_add_btn = $form.find('#img_plus');
	var $model = $form.find('#thumbnail_model');
	var s3_url = $model.data('s3-url');
	var $input_image_files = $form.find('input[name="image_files"]');
	var $sortable_div = $form.find('div.sortable');

	function rewrite_image_files_input(){
		var image_files = [];
		$sortable_div.children('[data-file]:visible').each(function(){
			image_files.push($(this).data('file'));
		});
		$input_image_files.val(JSON.stringify(image_files));
	}

	Sortable.create($sortable_div.get(0), {
		onEnd: function(evt){
			rewrite_image_files_input();
		}
	});

	$form.find('span.img-delete').click(function() {
		$(this).closest('div.thumbnail-col').remove();
		rewrite_image_files_input();
	});

    $('#fileupload').bind('fileuploadprocessfail', function (e, data) {
		var error = (data.files[data.index].error == 'File type not allowed') ? 'Fout bestandstype' : data.files[data.index].error;
		alert(error);
		$img_add_btn.removeClass('fa-spin fa-spinner').addClass('fa-plus');
	}).fileupload({

		disableImageResize: /Android(?!.*Chrome)|Opera/
			.test(window.navigator.userAgent),
		imageMaxWidth: 400,
		imageMaxHeight: 400,
		imageOrientation: true

	}).on('fileuploadadd', function (e, data) {
		$img_add_btn.removeClass('fa-plus').addClass('fa-spinner fa-spin');
	}).on('fileuploaddone', function (e, data) {

		$img_add_btn.removeClass('fa-spin fa-spinner').addClass('fa-plus');

        $.each(data.result, function (index, file) {

            if (file) {
				var $thumbnail = $model.clone();
				$thumbnail.removeAttr('id');
				$thumbnail.attr('data-file', file);
				var $img = $thumbnail.find('img');
				$img.attr('src', s3_url + file);

				$thumbnail.find('span.img-delete').click(function(){
					$thumbnail.remove();
					rewrite_image_files_input();
				});

				$thumbnail.removeClass('hidden');
				$model.parent().append($thumbnail);
				rewrite_image_files_input();
            } else {
				alert('Fout bij het opladen van de afbeelding.');
			}
        });

     }).prop('disabled', !$.support.fileInput)
        .parent().addClass($.support.fileInput ? undefined : 'disabled');
});
<|endoftext|>


<commit_before>define([
	"dojo/_base/declare", "dojo/on", "dojo/dom-construct",
	"dojo/_base/lang", "dojo/mouse",
	"dojo/topic", "dojo/query", "dijit/layout/ContentPane",
	"dijit/Dialog", "dijit/popup", "dijit/TooltipDialog",
	"./AdvancedDownload", "dojo/dom-class", "dojo/when"
], function(declare, on, domConstruct,
			lang, Mouse,
			Topic, query, ContentPane,
			Dialog, popup, TooltipDialog,
			AdvancedDownload, domClass, when){

	return declare([TooltipDialog], {
		containerType: "",
		selection: null,
		grid: null,
		conf: null,

		_setSelectionAttr: function(val){
			//console.log("CopyTooltipDialog._setSelectionAttr: ", val);
			this.selection = val;
		},
		timeout: function(val){
			var _self = this;
			this._timer = setTimeout(function(){
				popup.close(_self);
			}, val || 2500);
		},

		onMouseEnter: function(){
			if(this._timer){
				clearTimeout(this._timer);
			}

			this.inherited(arguments);
		},
		onMouseLeave: function(){
			popup.close(this);
		},

		// convert the selection into TSV format, skipping headers and columns as specified
		_totsv: function(selection, includeHeader, selectedOnly, shownCols){

			var out = [];
			var keys = Object.keys(selection[0]);

			// construct the header
			var header = [];
			keys.forEach(function(key){
				if (!selectedOnly || (selectedOnly && shownCols.includes(key))){
					header.push(key);
				}
			});

			// if we want the header, push it to the array
			if (includeHeader){
				out.push(header.join("\t"));
			}

			// for each selected item, push its data to the result array
			// Note: did for loops because its a bit faster than forEach (and a bit easier to follow syntactically)
			for (var i=0; i<selection.length; i++) {
				var io = [];
				var obj = selection[i];

				for (var j=0; j<keys.length; j++) {
					var key = keys[j];

					console.log('[2]key:',key) // gotta check if the key exists in the columns first: if (typeof this.grid.columns[key] != 'undefined')
					// is this masking really the best way to do this?  getting ugly

					// decide if we should include this column
					if (!selectedOnly || (selectedOnly && shownCols.includes(key))){
						// push it to the array
						if (obj[key] instanceof Array){
							io.push(obj[key].join(";"));
						} else {
							io.push(obj[key]);
						}
					}
				}
				out.push(io.join("\t"));
  		}
			return out.join("\n");

		},

		// XXX known issue: seleted items not accessible after changing pages (NPE)
		copySelection: function(type, selection){
			console.log("CopyTooltipDialog.copySelection(", type,",", selection,")");
			//console.log('CopyTooltipDialog.grid', this.grid)
			console.log('CopyTooltipDialog.grid.columns:', this.grid.columns)

			// format the text
			var includeHeader;
			var selectedOnly;
			var pkOnly;
			switch(type){
				case "full_w_header":
					includeHeader = true;
					selectedOnly = false;
					break;
				case "full_wo_header":
					includeHeader = false;
					selectedOnly = false;
					break;
				case "selected_w_header":
					includeHeader = true;
					selectedOnly = true;
					break;
				case "selected_wo_header":
					includeHeader = false;
					selectedOnly = true;
					break;
				default:
					includeHeader = true;
					selectedOnly = false;
					break;
			}

			// build a list of which columns are visible to the user
			var shownCols = [];
			if (selectedOnly) {
				var col_keys = Object.keys(this.grid.columns);
				for (var i=0; i<col_keys.length; i++) {
					var key = col_keys[i];

					// if the key is not hidden, put it in the list of shown columns
					if ( (typeof this.grid.columns[key].hidden != 'undefined') || !this.grid.columns[key].hidden) {
						shownCols.push(key);
					}
				}
			}

			console.log('CopyTooltipDialog.shownCols:', shownCols);

			// convert to tsv
			var copy_text = this._totsv(selection, includeHeader, selectedOnly, shownCols);

			// put it on the clipboard (https://www.npmjs.com/package/clipboard-js)
			clipboard.copy(copy_text);
		},

		startup: function(){
			if(this._started){
				return;
			}
			on(this.domNode, Mouse.enter, lang.hitch(this, "onMouseEnter"));
			on(this.domNode, Mouse.leave, lang.hitch(this, "onMouseLeave"));
			var _self = this;
			on(this.domNode, ".wsActionTooltip:click", function(evt){
				// console.log("evt.target: ", evt.target, evt.target.attributes);
				var rel = evt.target.attributes.rel.value;
				_self.copySelection(rel, _self.selection)
			});

			var dstContent = domConstruct.create("div", {});
			this.labelNode = domConstruct.create("div", {style: "background:#09456f;color:#fff;margin:0px;margin-bottom:4px;padding:4px;text-align:center;"}, dstContent);
			this.selectedCount = domConstruct.create("div", {}, dstContent);
			var table = domConstruct.create("table", {}, dstContent);

			var tr = domConstruct.create("tr", {}, table);
			var tData = this.tableCopyNode = domConstruct.create("td", {style: "vertical-align:top;"}, tr);
			//spacer
			domConstruct.create("td", {style: "width:10px;"}, tr);
			var oData = this.otherCopyNode = domConstruct.create("td", {style: "vertical-align:top;"}, tr);

			domConstruct.create("div", {"class": "wsActionTooltip", rel: "full_w_header", innerHTML: "Full Table (with headers)"}, tData);
			domConstruct.create("div", {"class": "wsActionTooltip", rel: "full_wo_header", innerHTML: "Full Table (without headers)"}, tData);
			domConstruct.create("div", {"class": "wsActionTooltip", rel: "selected_w_header", innerHTML: "Selected Columns (with headers)"}, tData);
			domConstruct.create("div", {"class": "wsActionTooltip", rel: "selected_wo_header", innerHTML: "Selected Columns (without headers)"}, tData);

			tr = domConstruct.create("tr", {}, table);
			var td = domConstruct.create("td", {"colspan": 3, "style": "text-align:right"}, tr);

			this.set("content", dstContent);

			this._started = true;
			this.set("label", this.label);
			this.set("selection", this.selection);

		},

		_setLabelAttr: function(val){
			console.log("CopyTooltipDialog._setLabelAttr: ", val);
			this.label = val;
			if(this._started){
				this.labelNode.innerHTML = "Copy selected " + this.label + " (" + (this.selection ? this.selection.length : "0") + ") as...";
			}
		},

		"copyableConfig": {
			"genome_data": {
				"label": "Genomes",
				"dataType": "genome",
				pk: "genome_id",
				tableData: true,
				advanced: true
			},
			"sequence_data": {
				"label": "Sequences",
				"dataType": "genome_sequence",
				pk: "sequence_id",
				tableData: true,
				otherData: ["dna+fasta"]
			},
			"feature_data": {
				"label": "Features",
				"dataType": "genome_feature",
				pk: "feature_id",
				tableData: true,
				otherData: ["dna+fasta", "protein+fasta"]
			},
			"spgene_data": {
				dataType: "sp_gene",
				field: "feature_id",
				pk: "id",
				"label": "Specialty Genes",
				tableData: true
			},
			"spgene_ref_data": {
				dataType: "sp_gene_ref",
				pk: "id",
				"label": "Specialty VF Genes",
				tableData: true
			},
			"pathway_data": {
				pk: "pathway_id",
				dataType: "pathway",
				"label": "Pathways",
				tableData: true
			},
			"gene_expression_data": {
				dataType: "transcriptomics_gene",
				pk: "id",
				"label": "Gene Expression",
				tableData: true
			},
			"transcriptomics_gene_data": {
				dataType: "genome_feature",
				pk: "feature_id",
				"label": "Features",
				tableData: true
			},
			"transcriptomics_experiment_data": {
				dataType: "transcriptomics_experiment",
				pk: "eid",
				"label": "Experiments",
				tableData: true
			},
			"transcriptomics_sample_data": {
				dataType: "transcriptomics_sample",
				pk: "pid",
				"label": "Comparisons",
				tableData: true
			},
			"interaction_data": {
				dataType: "ppi",
				pk: "id",
				"label": "Interactions",
				tableData: true
			},
			"genome_amr_data": {
				dataType: "genome_amr",
				pk: "id",
				"label": "AMR Phenotypes",
				tableData: true
			},
			"default": {
				"label": "Items",
				pk: "id",
				tableData: true
			}
		},

		_setContainerTypeAttr: function(val){
			console.log("CopyTooltipDialog.setContainerType: ", val);

			this.containerType = val;
			this.conf = this.copyableConfig[val] || this.copyableConfig["default"];
			this.set("label", this.conf.label);

			if(!this._started){
				return;
			}

			domConstruct.empty(this.otherCopyNode);

			if(this.conf.otherData){
				this.conf.otherData.forEach(function(type){
					domConstruct.create("div", {
						"class": "wsActionTooltip",
						rel: type,
						innerHTML: null
					}, this.otherCopyNode);
				}, this);
			}

		}
	});

});
<commit_msg>cleaned up code a bit<commit_after>define([
	"dojo/_base/declare", "dojo/on", "dojo/dom-construct",
	"dojo/_base/lang", "dojo/mouse",
	"dojo/topic", "dojo/query", "dijit/layout/ContentPane",
	"dijit/Dialog", "dijit/popup", "dijit/TooltipDialog",
	"./AdvancedDownload", "dojo/dom-class", "dojo/when"
], function(declare, on, domConstruct,
			lang, Mouse,
			Topic, query, ContentPane,
			Dialog, popup, TooltipDialog,
			AdvancedDownload, domClass, when){

	return declare([TooltipDialog], {
		containerType: "",
		selection: null,
		grid: null,
		conf: null,

		_setSelectionAttr: function(val){
			//console.log("CopyTooltipDialog._setSelectionAttr: ", val);
			this.selection = val;
		},
		timeout: function(val){
			var _self = this;
			this._timer = setTimeout(function(){
				popup.close(_self);
			}, val || 2500);
		},

		onMouseEnter: function(){
			if(this._timer){
				clearTimeout(this._timer);
			}

			this.inherited(arguments);
		},
		onMouseLeave: function(){
			popup.close(this);
		},

		// convert the selection into TSV format, skipping headers and columns as specified
		_totsv: function(selection, includeHeader, selectedOnly, shownCols){
			var out = [];
			var keys = Object.keys(selection[0]);

			// construct the header
			var header = [];
			keys.forEach(function(key){
				if (!selectedOnly || (selectedOnly && shownCols.includes(key))){
					header.push(key);
				}
			});

			// if we want the header, push it to the array
			if (includeHeader){
				out.push(header.join("\t"));
			}

			// for each selected item, push its data to the result array
			selection.forEach(function(obj){
				var io = [];

				keys.forEach(function(key){
					// decide if we should include this column
					if (!selectedOnly || (selectedOnly && shownCols.includes(key))){
						// push it to the array
						if (obj[key] instanceof Array){
							io.push(obj[key].join(";"));
						} else {
							io.push(obj[key]);
						}
					}
				});
				out.push(io.join("\t"));
  		});
			return out.join("\n");

		},

		// XXX known issue: seleted items not accessible after changing pages (NPE)
		copySelection: function(type, selection){
			//console.log("CopyTooltipDialog.copySelection(", type,",", selection,")");

			// format the text
			var includeHeader;
			var selectedOnly;
			var pkOnly;
			switch(type){
				case "full_w_header":
					includeHeader = true;
					selectedOnly = false;
					break;
				case "full_wo_header":
					includeHeader = false;
					selectedOnly = false;
					break;
				case "selected_w_header":
					includeHeader = true;
					selectedOnly = true;
					break;
				case "selected_wo_header":
					includeHeader = false;
					selectedOnly = true;
					break;
				default:
					includeHeader = true;
					selectedOnly = false;
					break;
			}

			// build a list of which columns are visible to the user
			var shownCols = [];
			if (selectedOnly) {
				var col_keys = Object.keys(this.grid.columns);
				for (var i=0; i<col_keys.length; i++) {
					var key = col_keys[i];

					// if the column is not hidden, put it in the list of shown columns
					if ((typeof this.grid.columns[key].hidden == 'undefined') || !this.grid.columns[key].hidden) {
						shownCols.push(key);
					}
				}
			}

			// convert to tsv
			var copy_text = this._totsv(selection, includeHeader, selectedOnly, shownCols);

			// put it on the clipboard (https://www.npmjs.com/package/clipboard-js)
			clipboard.copy(copy_text);
		},

		startup: function(){
			if(this._started){
				return;
			}
			on(this.domNode, Mouse.enter, lang.hitch(this, "onMouseEnter"));
			on(this.domNode, Mouse.leave, lang.hitch(this, "onMouseLeave"));
			var _self = this;
			on(this.domNode, ".wsActionTooltip:click", function(evt){
				// console.log("evt.target: ", evt.target, evt.target.attributes);
				var rel = evt.target.attributes.rel.value;
				_self.copySelection(rel, _self.selection)
			});

			var dstContent = domConstruct.create("div", {});
			this.labelNode = domConstruct.create("div", {style: "background:#09456f;color:#fff;margin:0px;margin-bottom:4px;padding:4px;text-align:center;"}, dstContent);
			this.selectedCount = domConstruct.create("div", {}, dstContent);
			var table = domConstruct.create("table", {}, dstContent);

			var tr = domConstruct.create("tr", {}, table);
			var tData = this.tableCopyNode = domConstruct.create("td", {style: "vertical-align:top;"}, tr);
			//spacer
			domConstruct.create("td", {style: "width:10px;"}, tr);
			var oData = this.otherCopyNode = domConstruct.create("td", {style: "vertical-align:top;"}, tr);

			domConstruct.create("div", {"class": "wsActionTooltip", rel: "full_w_header", innerHTML: "Full Table (with headers)"}, tData);
			domConstruct.create("div", {"class": "wsActionTooltip", rel: "full_wo_header", innerHTML: "Full Table (without headers)"}, tData);
			domConstruct.create("div", {"class": "wsActionTooltip", rel: "selected_w_header", innerHTML: "Selected Columns (with headers)"}, tData);
			domConstruct.create("div", {"class": "wsActionTooltip", rel: "selected_wo_header", innerHTML: "Selected Columns (without headers)"}, tData);

			tr = domConstruct.create("tr", {}, table);
			var td = domConstruct.create("td", {"colspan": 3, "style": "text-align:right"}, tr);

			this.set("content", dstContent);

			this._started = true;
			this.set("label", this.label);
			this.set("selection", this.selection);

		},

		_setLabelAttr: function(val){
			//console.log("CopyTooltipDialog._setLabelAttr: ", val);
			this.label = val;
			if(this._started){
				this.labelNode.innerHTML = "Copy selected " + this.label + " (" + (this.selection ? this.selection.length : "0") + ") as...";
			}
		},

		"copyableConfig": {
			"genome_data": {
				"label": "Genomes",
				"dataType": "genome",
				pk: "genome_id",
				tableData: true,
				advanced: true
			},
			"sequence_data": {
				"label": "Sequences",
				"dataType": "genome_sequence",
				pk: "sequence_id",
				tableData: true,
				otherData: ["dna+fasta"]
			},
			"feature_data": {
				"label": "Features",
				"dataType": "genome_feature",
				pk: "feature_id",
				tableData: true,
				otherData: ["dna+fasta", "protein+fasta"]
			},
			"spgene_data": {
				dataType: "sp_gene",
				field: "feature_id",
				pk: "id",
				"label": "Specialty Genes",
				tableData: true
			},
			"spgene_ref_data": {
				dataType: "sp_gene_ref",
				pk: "id",
				"label": "Specialty VF Genes",
				tableData: true
			},
			"pathway_data": {
				pk: "pathway_id",
				dataType: "pathway",
				"label": "Pathways",
				tableData: true
			},
			"gene_expression_data": {
				dataType: "transcriptomics_gene",
				pk: "id",
				"label": "Gene Expression",
				tableData: true
			},
			"transcriptomics_gene_data": {
				dataType: "genome_feature",
				pk: "feature_id",
				"label": "Features",
				tableData: true
			},
			"transcriptomics_experiment_data": {
				dataType: "transcriptomics_experiment",
				pk: "eid",
				"label": "Experiments",
				tableData: true
			},
			"transcriptomics_sample_data": {
				dataType: "transcriptomics_sample",
				pk: "pid",
				"label": "Comparisons",
				tableData: true
			},
			"interaction_data": {
				dataType: "ppi",
				pk: "id",
				"label": "Interactions",
				tableData: true
			},
			"genome_amr_data": {
				dataType: "genome_amr",
				pk: "id",
				"label": "AMR Phenotypes",
				tableData: true
			},
			"default": {
				"label": "Items",
				pk: "id",
				tableData: true
			}
		},

		_setContainerTypeAttr: function(val){
			//console.log("CopyTooltipDialog.setContainerType: ", val);

			this.containerType = val;
			this.conf = this.copyableConfig[val] || this.copyableConfig["default"];
			this.set("label", this.conf.label);

			if(!this._started){
				return;
			}

			domConstruct.empty(this.otherCopyNode);

			if(this.conf.otherData){
				this.conf.otherData.forEach(function(type){
					domConstruct.create("div", {
						"class": "wsActionTooltip",
						rel: type,
						innerHTML: null
					}, this.otherCopyNode);
				}, this);
			}

		}
	});

});
<|endoftext|>


<commit_before>#!/usr/bin/env node

/* global -Promise */
'use strict';

var Promise = require('bluebird');
var engine = require('../engine');
var fs = require('fs');

var runSynValThen = function(year) {
    return engine.runSyntactical(year)
    .then(function() {
        return engine.runValidity(year);
    });
};

var runSynValAll = function(year) {
    return Promise.all([engine.runSyntactical(year), engine.runValidity(year)]);
};

var runQualMacroThen = function(year) {
    return engine.runQuality(year)
    .then(function() {
        return engine.runMacro(year);
    });
};

var runQualMacroAll = function(year) {
    return Promise.all([engine.runQuality(year), engine.runMacro(year)]);
};

var runAll = function(year) {
    return runSynValAll(year)
    .then(function() {
        return runQualMacroAll(year);
    })
    .then(function() {
        return engine.runSpecial(year);
    });
};

var runThen = function(year) {
    return runSynValThen(year)
    .then(function() {
        return runQualMacroThen(year);
    })
    .then(function() {
        return engine.runSpecial(year);
    });
};

var runHarness = function(fn, year, apiurl, uselocaldb, debug, asthen) {
    var promise = runAll;
    engine.setAPIURL(apiurl);
    if (uselocaldb !== undefined && uselocaldb === 'y') {
        engine.setUseLocalDB(true);
    }
    if (debug !== undefined) {
        engine.setDebug(debug);
    }
    if (asthen !== undefined && asthen === 'y') {
        promise = runThen;
    }

    console.time('total time');
    console.time('time to process hmda json');
    fs.readFile(fn, function(err, data) {
        if (err) {
            console.error('File does not exist');
            process.exit(1);
        }
        engine.fileToJson(data, year, function(fileErr) {
            if (fileErr) {
                console.log(fileErr);
            } else {
                console.log('lars in \'' + fn + '\' = ' + engine.getHmdaJson().hmdaFile.loanApplicationRegisters.length);
                console.timeEnd('time to process hmda json');
                console.time('time to run all rules');
                promise(year)
                .then(function() {
                    console.timeEnd('time to run all rules');
                    console.timeEnd('total time');
                    //console.log(JSON.stringify(engine.getErrors(), null, 2));
                    console.log(engine.getErrors());
                })
                .catch(function(err) {
                    console.log(err.message);
                });
            }
        });
    });
};

var run = function() {
    if (process.argv.length < 5) {
        console.error('');
        console.error('Usage: ./run FILENAME YEAR APIURL [USE LOCALDB] [ENGINE DEBUG LEVEL] [RUN AS THEN, NOT ALL]');
        console.error('');
        console.error('EX: ./run ./testdata/bank.dat 2013 http://localhost:9000 1 y');
        console.error('');
        process.exit(1);
    }

    var fn = process.argv[2];
    var year = process.argv[3];
    var apiurl = process.argv[4];
    var uselocaldb = process.argv[5];
    var debug = process.argv[6];
    var asthen = process.argv[7];
    runHarness(fn, year, apiurl, uselocaldb, debug, asthen);
};

module.exports = runHarness;
if (process.argv.length && process.argv[1] === __dirname +'/harness.js') {
    run();
}
<commit_msg>Add IRS report timings to harness<commit_after>#!/usr/bin/env node

/* global -Promise */
'use strict';

var Promise = require('bluebird');
var engine = require('../engine');
var fs = require('fs');

var runSynValThen = function(year) {
    return engine.runSyntactical(year)
    .then(function() {
        return engine.runValidity(year);
    });
};

var runSynValAll = function(year) {
    return Promise.all([engine.runSyntactical(year), engine.runValidity(year)]);
};

var runQualMacroThen = function(year) {
    return engine.runQuality(year)
    .then(function() {
        return engine.runMacro(year);
    });
};

var runQualMacroAll = function(year) {
    return Promise.all([engine.runQuality(year), engine.runMacro(year)]);
};

var runAll = function(year) {
    return runSynValAll(year)
    .then(function() {
        return runQualMacroAll(year);
    })
    .then(function() {
        return engine.runSpecial(year);
    })
    .then(function() {
        console.time('time to run IRS report');
        return engine.getTotalsByMSA(engine.getHmdaJson().hmdaFile.loanApplicationRegisters)
        .then(function() {
            console.timeEnd('time to run IRS report');
        });
    });
};

var runThen = function(year) {
    return runSynValThen(year)
    .then(function() {
        return runQualMacroThen(year);
    })
    .then(function() {
        return engine.runSpecial(year);
    })
    .then(function() {
        console.time('time to run IRS report');
        return engine.getTotalsByMSA(engine.getHmdaJson().hmdaFile.loanApplicationRegisters)
        .then(function() {
            console.timeEnd('time to run IRS report');
        });
    });
};

var runHarness = function(fn, year, apiurl, uselocaldb, debug, asthen) {
    var promise = runAll;
    engine.setAPIURL(apiurl);
    if (uselocaldb !== undefined && uselocaldb === 'y') {
        engine.setUseLocalDB(true);
    }
    if (debug !== undefined) {
        engine.setDebug(debug);
    }
    if (asthen !== undefined && asthen === 'y') {
        promise = runThen;
    }

    console.time('total time');
    console.time('time to process hmda json');
    fs.readFile(fn, function(err, data) {
        if (err) {
            console.error('File does not exist');
            process.exit(1);
        }
        engine.fileToJson(data, year, function(fileErr) {
            if (fileErr) {
                console.log(fileErr);
            } else {
                console.log('lars in \'' + fn + '\' = ' + engine.getHmdaJson().hmdaFile.loanApplicationRegisters.length);
                console.timeEnd('time to process hmda json');
                console.time('time to run all rules');
                promise(year)
                .then(function() {
                    console.timeEnd('time to run all rules');
                    console.timeEnd('total time');
                    //console.log(JSON.stringify(engine.getErrors(), null, 2));
                    //console.log(engine.getErrors());
                })
                .catch(function(err) {
                    console.log(err.message);
                });
            }
        });
    });
};

var run = function() {
    if (process.argv.length < 5) {
        console.error('');
        console.error('Usage: ./run FILENAME YEAR APIURL [USE LOCALDB] [ENGINE DEBUG LEVEL] [RUN AS THEN, NOT ALL]');
        console.error('');
        console.error('EX: ./run ./testdata/bank.dat 2013 http://localhost:9000 1 y');
        console.error('');
        process.exit(1);
    }

    var fn = process.argv[2];
    var year = process.argv[3];
    var apiurl = process.argv[4];
    var uselocaldb = process.argv[5];
    var debug = process.argv[6];
    var asthen = process.argv[7];
    runHarness(fn, year, apiurl, uselocaldb, debug, asthen);
};

module.exports = runHarness;
if (process.argv.length && process.argv[1] === __dirname +'/harness.js') {
    run();
}
<|endoftext|>