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

import FlatButton from 'src/FlatButton';
import Widget from 'src/Widget';
import WidgetHeader from 'src/WidgetHeader';
import Theme from 'src/Theme';

import PropTypeDescTable from 'components/PropTypeDescTable';
import FlatButtonDoc from 'assets/propTypes/FlatButton.json';

import 'sass/containers/app/modules/buttons/FlatButtonExamples.scss';

export default class FlatButtonExamples extends Component {

    constructor(props) {
        super(props);
    }

    render() {

        return (

Flat Button

                    Flat Button are used for general functions and reduce the amount of layering on the
                    screen, making it more readable.

Examples

                <Widget>

                    <WidgetHeader className="example-header" title="Basic"/>

Flat Button with default theme, success, warning
                                    , error and disabled props applied.

                                <FlatButton value="Default"/>

                                <FlatButton value="Primary"
                                            theme={Theme.PRIMARY}/>

                                <FlatButton value="Secondary"
                                            theme={Theme.SECONDARY}/>

                                <FlatButton value="Highlight"
                                            theme={Theme.HIGHLIGHT}/>

                                <FlatButton value="Info"
                                            theme={Theme.INFO}/>

                                <FlatButton value="Success"
                                            theme={Theme.SUCCESS}/>

                                <FlatButton value="Warning"
                                            theme={Theme.WARNING}/>

                                <FlatButton value="Error"
                                            theme={Theme.ERROR}/>

                                <FlatButton value="Disabled"
                                            disabled={true}/>

                </Widget>

                <Widget>

                    <WidgetHeader className="example-header" title="With border radius"/>

Set the isRounded property to true for button round corner.

                                <FlatButton value="Default"
                                            isRounded={true}/>

                                <FlatButton value="Primary"
                                            theme={Theme.PRIMARY}
                                            isRounded={true}/>

                                <FlatButton value="Secondary"
                                            theme={Theme.SECONDARY}
                                            isRounded={true}/>

                                <FlatButton value="Highlight"
                                            theme={Theme.HIGHLIGHT}
                                            isRounded={true}/>

                                <FlatButton value="Info"
                                            theme={Theme.INFO}
                                            isRounded={true}/>

                                <FlatButton value="Success"
                                            theme={Theme.SUCCESS}
                                            isRounded={true}/>

                                <FlatButton value="Warning"
                                            theme={Theme.WARNING}
                                            isRounded={true}/>

                                <FlatButton value="Error"
                                            theme={Theme.ERROR}
                                            isRounded={true}/>

                                <FlatButton value="Disabled"
                                            disabled={true}
                                            isRounded={true}/>

                </Widget>

                <Widget>

                    <WidgetHeader className="example-header" title="With icon"/>

Set the iconCls property for button left icon.And set the
                                    rightIconCls property for button right icon.

                                <FlatButton value="Reset"
                                            iconCls="fa fa-undo"/>

                                <FlatButton value="Add"
                                            theme={Theme.SUCCESS}
                                            iconCls="fa fa-plus"/>

                                <FlatButton value="Delete"
                                            theme={Theme.ERROR}
                                            iconCls="fa fa-trash"/>

                                <FlatButton value="Next"
                                            theme={Theme.PRIMARY}
                                            rightIconCls="fa fa-chevron-right"/>

                </Widget>

                <Widget>

                    <WidgetHeader className="example-header" title="Use circle shape"/>

Set the isCircular property to true for circle shape flat button.

                                <FlatButton value="Primary"
                                            isCircular={true}/>

                                <FlatButton value="Success"
                                            theme={Theme.SUCCESS}
                                            isCircular={true}/>

                                <FlatButton value="Error"
                                            theme={Theme.ERROR}
                                            isCircular={true}/>

                                <FlatButton value="Warning"
                                            theme={Theme.WARNING}
                                            isCircular={true}/>

                </Widget>

Properties

                <PropTypeDescTable data={FlatButtonDoc}/>

        );
    }
};<commit_msg>update FlatButton examples<commit_after>import React, {Component} from 'react';

import FlatButton from 'src/FlatButton';
import Widget from 'src/Widget';
import WidgetHeader from 'src/WidgetHeader';
import Theme from 'src/Theme';

import PropTypeDescTable from 'components/PropTypeDescTable';
import FlatButtonDoc from 'assets/propTypes/FlatButton.json';

import 'sass/containers/app/modules/buttons/FlatButtonExamples.scss';

export default class FlatButtonExamples extends Component {

    constructor(props) {
        super(props);
    }

    render() {

        return (

Flat Button

                    Flat Button are used for general functions and reduce the amount of layering on the
                    screen, making it more readable.

Examples

                <Widget>

                    <WidgetHeader className="example-header" title="Basic"/>

                                    Flat Button with default
                                    theme, success, warning
                                    , error and disabled props applied.

                                <FlatButton value="Default"/>

                                <FlatButton value="Primary"
                                            theme={Theme.PRIMARY}/>

                                <FlatButton value="Secondary"
                                            theme={Theme.SECONDARY}/>

                                <FlatButton value="Highlight"
                                            theme={Theme.HIGHLIGHT}/>

                                <FlatButton value="Info"
                                            theme={Theme.INFO}/>

                                <FlatButton value="Success"
                                            theme={Theme.SUCCESS}/>

                                <FlatButton value="Warning"
                                            theme={Theme.WARNING}/>

                                <FlatButton value="Error"
                                            theme={Theme.ERROR}/>

                                <FlatButton value="Disabled"
                                            disabled={true}/>

                </Widget>

                <Widget>

                    <WidgetHeader className="example-header" title="With border radius"/>

Set the isRounded property to true for button round corner.

                                <FlatButton value="Default"
                                            isRounded={true}/>

                                <FlatButton value="Primary"
                                            theme={Theme.PRIMARY}
                                            isRounded={true}/>

                                <FlatButton value="Secondary"
                                            theme={Theme.SECONDARY}
                                            isRounded={true}/>

                                <FlatButton value="Highlight"
                                            theme={Theme.HIGHLIGHT}
                                            isRounded={true}/>

                                <FlatButton value="Info"
                                            theme={Theme.INFO}
                                            isRounded={true}/>

                                <FlatButton value="Success"
                                            theme={Theme.SUCCESS}
                                            isRounded={true}/>

                                <FlatButton value="Warning"
                                            theme={Theme.WARNING}
                                            isRounded={true}/>

                                <FlatButton value="Error"
                                            theme={Theme.ERROR}
                                            isRounded={true}/>

                                <FlatButton value="Disabled"
                                            disabled={true}
                                            isRounded={true}/>

                </Widget>

                <Widget>

                    <WidgetHeader className="example-header" title="With icon"/>

Set the iconCls property for button left icon.And set the
                                    rightIconCls property for button right icon.

                                <FlatButton value="Reset"
                                            iconCls="fa fa-undo"/>

                                <FlatButton value="Add"
                                            theme={Theme.SUCCESS}
                                            iconCls="fa fa-plus"/>

                                <FlatButton value="Delete"
                                            theme={Theme.ERROR}
                                            iconCls="fa fa-trash"/>

                                <FlatButton value="Next"
                                            theme={Theme.PRIMARY}
                                            rightIconCls="fa fa-chevron-right"/>

                </Widget>

                <Widget>

                    <WidgetHeader className="example-header" title="Use circle shape"/>

Set the isCircular property to true for circle shape flat button.

                                <FlatButton value="Primary"
                                            isCircular={true}/>

                                <FlatButton value="Success"
                                            theme={Theme.SUCCESS}
                                            isCircular={true}/>

                                <FlatButton value="Error"
                                            theme={Theme.ERROR}
                                            isCircular={true}/>

                                <FlatButton value="Warning"
                                            theme={Theme.WARNING}
                                            isCircular={true}/>

                </Widget>

Properties

                <PropTypeDescTable data={FlatButtonDoc}/>

        );
    }
};<|endoftext|>


<commit_before>'use strict';

// MODULES //

var isFunction = require( '@stdlib/utils/is-function' );
var isPositiveInteger = require( '@stdlib/utils/is-positive-integer' ).isPrimitive;

// MAIN //

/**
* Transforms a curried function into a function invoked with multiple arguments.
*
* @param {Function} fcn - curried function
* @param {PositiveInteger} [arity] - number of parameters
* @param {*} [thisArg] - evaluation context
* @throws {TypeError} first argument must be a function
* @throws {TypeError} `arity` argument must be a positive integer
* @returns {Function} uncurried function
*
* @example
* function addX( x ) {
*     return function addY( y ) {
*         return x + y;
*     };
* }
*
* var add = uncurry( addX );
*
* var sum = add( 2, 3 );
* // returns 5
*/
function uncurry( fcn, arity, thisArg ) {
	var context;
	var len;
	if ( !isFunction( fcn ) ) {
		throw new TypeError( 'invalid input argument. First argument must be a function. Value: `'+fcn+'`.' );
	}
	if ( arguments.length < 2 ) {
		len = null;
	}
	else if ( arguments.length > 2 ) {
		len = arity;
		context = thisArg;
		if ( !isPositiveInteger( len ) ) {
			throw new TypeError( 'invalid input argument. Arity argument must be a positive integer. Value: `'+len+'`.' );
		}
	}
	else if ( isPositiveInteger( arity ) ) {
		len = arity;
	}
	else {
		len = null;
		context = arity;
	}
	return uncurried;

	/**
	* Uncurried function.
	*
	* @private
	* @param {...*} args - arguments
	* @throws {Error} if arity is set, must provide expected number of input arguments
	* @throws {Error} configured arity must be compatible with curried function
	* @throws {Error} if arity is not set, number of arguments must be compatible with curried function
	* @returns {*} function result
	*/
	function uncurried() {
		var f;
		var i;

		f = fcn;
		if ( len ) {
			if ( len > arguments.length ) {
				throw new Error( 'insufficient input arguments. Expected '+len+' arguments and only received '+arguments.length+' arguments.' );
			}
			for ( i = 0; i < len; i++ ) {
				if ( isFunction( f ) ) {
					f = f.call( context, arguments[ i ] );
				} else {
					throw new Error( 'invalid invocation. The configured arity exceeds the number of possible curried function invocations. Expected: '+len+'. Actual: '+i+'.' );
				}
			}
			return f;
		}
		for ( i = 0; i < arguments.length; i++ ) {
			if ( isFunction( f ) ) {
				f = f.call( context, arguments[ i ] );
			} else {
				throw new Error( 'invalid invocation. Number of arguments exceeds the number of possible curried function invocations. Expected: '+arguments.length+'. Actual: '+i+'.' );
			}
		}
		return f;
	} // end FUNCTION uncurried()
} // end FUNCTION uncurry()

// EXPORTS //

module.exports = uncurry;
<commit_msg>Update error messages<commit_after>'use strict';

// MODULES //

var isFunction = require( '@stdlib/utils/is-function' );
var isPositiveInteger = require( '@stdlib/utils/is-positive-integer' ).isPrimitive;

// MAIN //

/**
* Transforms a curried function into a function invoked with multiple arguments.
*
* @param {Function} fcn - curried function
* @param {PositiveInteger} [arity] - number of parameters
* @param {*} [thisArg] - evaluation context
* @throws {TypeError} first argument must be a function
* @throws {TypeError} `arity` argument must be a positive integer
* @returns {Function} uncurried function
*
* @example
* function addX( x ) {
*     return function addY( y ) {
*         return x + y;
*     };
* }
*
* var add = uncurry( addX );
*
* var sum = add( 2, 3 );
* // returns 5
*/
function uncurry( fcn, arity, thisArg ) {
	var context;
	var len;
	if ( !isFunction( fcn ) ) {
		throw new TypeError( 'invalid input argument. First argument must be a function. Value: `'+fcn+'`.' );
	}
	if ( arguments.length < 2 ) {
		len = null;
	}
	else if ( arguments.length > 2 ) {
		len = arity;
		context = thisArg;
		if ( !isPositiveInteger( len ) ) {
			throw new TypeError( 'invalid input argument. Arity argument must be a positive integer. Value: `'+len+'`.' );
		}
	}
	else if ( isPositiveInteger( arity ) ) {
		len = arity;
	}
	else {
		len = null;
		context = arity;
	}
	return uncurried;

	/**
	* Uncurried function.
	*
	* @private
	* @param {...*} args - arguments
	* @throws {Error} if arity is set, must provide expected number of input arguments
	* @throws {Error} configured arity must be compatible with curried function
	* @throws {Error} if arity is not set, number of arguments must be compatible with curried function
	* @returns {*} function result
	*/
	function uncurried() {
		var f;
		var i;

		f = fcn;
		if ( len ) {
			if ( len > arguments.length ) {
				throw new Error( 'insufficient input arguments. Expected '+len+' argument(s) and only received '+arguments.length+' argument(s).' );
			}
			for ( i = 0; i < len; i++ ) {
				if ( isFunction( f ) ) {
					f = f.call( context, arguments[ i ] );
				} else {
					throw new Error( 'invalid invocation. The configured arity exceeds the number of possible curried function invocations. Expected: '+len+'. Actual: '+i+'.' );
				}
			}
			return f;
		}
		for ( i = 0; i < arguments.length; i++ ) {
			if ( isFunction( f ) ) {
				f = f.call( context, arguments[ i ] );
			} else {
				throw new Error( 'invalid invocation. Number of arguments exceeds the number of possible curried function invocations. Expected: '+arguments.length+'. Actual: '+i+'.' );
			}
		}
		return f;
	} // end FUNCTION uncurried()
} // end FUNCTION uncurry()

// EXPORTS //

module.exports = uncurry;
<|endoftext|>


<commit_before>describe("PGN Game Set 1", function() {
  jasmine.getFixtures().fixturesPath = 'base/src/tests/fixtures/';

  it("works with the PGN set", function() {
    loadFixtures("testPgns.html");
    var i = 1;
    var printInterval = 1000;
    $j("div[id^=testGame]").each(function (idx, el) {
      var pgn = new Pgn(el.innerHTML);
      var conv = new Converter(pgn);
      try {
        conv.convert();
      }
      catch(e) {
        expect("No errors!").toBe(e + ". For game "+el.id);
        return false;
      }
      if (i++ % printInterval == 0) {
        console.log((i-1)+" games processed");
      }
    });
    console.log("Ran tests for "+i+" games");
  });

  it("works with the ChessPastebin PGN set", function() {
    loadFixtures("chesspastebin.html");
    var i = 1;
    var printInterval = 1000;
    $j("div[id^=testGame]").each(function (idx, el) {
      var pgn = new ChessGame(el.innerHTML);
      var conv = new Converter(pgn.format);
      try {
        conv.convert();
      }
      catch(e) {
        expect("No errors!").toBe(e + ". For game "+el.id);
        return false;
      }
      if (i++ % printInterval == 0) {
        console.log((i-1)+" games processed");
      }
    });
    console.log("Ran tests for "+i+" games");
  });

  it("works with the custom PGN set", function() {
    loadFixtures("testPgnsCustom.html");
    $j("div[id^=testGame]").each(function (idx, el) {
      var pgn = new Pgn(el.innerHTML);
      var conv = new Converter(pgn);
      try {
        conv.convert();
      }
      catch(e) {
        expect("No errors!").toBe(e + ". For game "+el.id);
        return false;
      }
    });
    console.log("Ran tests for "+i+" games");
  });
});
<commit_msg>Fixed bug in tests<commit_after>describe("PGN Game Set 1", function() {
  jasmine.getFixtures().fixturesPath = 'base/src/tests/fixtures/';

  it("works with the PGN set", function() {
    loadFixtures("testPgns.html");
    var i = 1;
    var printInterval = 1000;
    $j("div[id^=testGame]").each(function (idx, el) {
      var pgn = new Pgn(el.innerHTML);
      var conv = new Converter(pgn);
      try {
        conv.convert();
      }
      catch(e) {
        expect("No errors!").toBe(e + ". For game "+el.id);
        return false;
      }
      if (i++ % printInterval == 0) {
        console.log((i-1)+" games processed");
      }
    });
    console.log("Ran tests for "+i+" games");
  });

  it("works with the ChessPastebin PGN set", function() {
    loadFixtures("chesspastebin.html");
    var i = 1;
    var printInterval = 1000;
    $j("div[id^=testGame]").each(function (idx, el) {
      var pgn = new ChessGame(el.innerHTML);
      var conv = new Converter(pgn.format);
      try {
        conv.convert();
      }
      catch(e) {
        expect("No errors!").toBe(e + ". For game "+el.id);
        return false;
      }
      if (i++ % printInterval == 0) {
        console.log((i-1)+" games processed");
      }
    });
    console.log("Ran tests for "+i+" games");
  });

  it("works with the custom PGN set", function() {
    loadFixtures("testPgnsCustom.html");
    var i = 1;
    $j("div[id^=testGame]").each(function (idx, el) {
      var pgn = new Pgn(el.innerHTML);
      var conv = new Converter(pgn);
      try {
        conv.convert();
      }
      catch(e) {
        expect("No errors!").toBe(e + ". For game "+el.id);
        return false;
      }
      i++;
    });
    console.log("Ran tests for "+i+" games");
  });
});
<|endoftext|>


<commit_before>'use strict';

var vscode = require('vscode');
var j = require('jfp');

function buildTextEdit (coords, text) {
    var start = new vscode.Position(coords.start[0], coords.start[1]),
        end = new vscode.Position(coords.end[0], coords.end[1]),
        range = new vscode.Range(start, end);

    return new vscode.TextEdit(range, text);
}

function buildWorkspaceEdit () {
    return new vscode.WorkspaceEdit();
}

// Builds a "set" type edit object to update the view
function buildSetEdit (uri, coords, text) {
    var edit = buildWorkspaceEdit();
    edit.set(uri, [buildTextEdit(coords, text)]);

    return edit;
}

// Builds a "replace" type edit object to update the view
function buildReplaceEdit (uri, coords, text) {
    var edit = buildWorkspaceEdit();
    edit.replace(uri, [buildTextEdit(coords, text)]);

    return edit
}

function buildMultipleSetEdits (uri, edits){
    var textEdits = edits.reduce(function (list, edit) { return j.conj(buildTextEdit(edit.coords, edit.value), list); }, []);
    var edit = buildWorkspaceEdit();

    edit.set(uri, textEdits);

    return edit;
}

module.exports = {
    buildMultipleSetEdits: buildMultipleSetEdits,
    buildTextEdit: buildTextEdit,
    buildWorkspaceEdit: buildWorkspaceEdit,
    buildSetEdit: buildSetEdit,
    buildReplaceEdit: buildReplaceEdit
};<commit_msg>Refactored edit-factory module.<commit_after>'use strict';

var vscode = require('vscode');
var j = require('jfp');

function positionFactory (line, column){
    return new vscode.Position(line, column);
}

// This will be important as coordinate object is converted to new format
function positionFactoryFacade (location) {
    return positionFactory(location[0], location[1]);
}

function rangeFactory (start, end){
    var startPosition = positionFactoryFacade(start);
    var endPosition = positionFactoryFacade(end);

    return new vscode.Range(startPosition, endPosition);
}

function textEditFactory (coords, content){
    var range = rangeFactory(coords.start, coords.end);
    return new vscode.TextEdit(range, content);
}

function workspaceEditFactory () {
    return new vscode.WorkspaceEdit();
}

function setEditFactory (uri, edits){
    var edit = workspaceEditFactory();

    edit.set(uri, edits);

    return edit;
}

function replaceEditFactory (uri, edits){
    var edit = workspaceEditFactory();

    edit.replace(uri, edits);

    return edit;
}

// Composite construction functions

// Builds a "set" type edit object to update the view
function buildSetEdit (uri, coords, text) {
    var textEdit = textEditFactory(coords, text);
    return setEditFactory(uri, [textEdit]);
}

// Builds a "replace" type edit object to update the view
function buildReplaceEdit (uri, coords, text) {
    var textEdit = textEditFactory(coords, text);
    return replaceEditFactory(uri, [textEdit]);
}

function buildMultipleSetEdits (uri, edits){
    var textEdits = edits.map(function (edit) { return textEditFactory(edit.coords, edit.value); });
    return setEditFactory(uri, textEdits);
}

function buildMultipleReplaceEdits (uri, edits){
    var textEdits = edits.map(function (edit) { return textEditFactory(edit.coords, edit.value); });
    return replaceEditFactory(uri, textEdits);
}

module.exports = {
    buildMultipleSetEdits: buildMultipleSetEdits,
    buildSetEdit: buildSetEdit,
    buildMultipleReplaceEdits: buildMultipleSetEdits,
    buildReplaceEdit: buildSetEdit
};<|endoftext|>


<commit_before>// Generated by CoffeeScript 1.6.3
jQuery(function() {
  $.each($("[data-time]"), function(index, ele) {
    return $(ele).html(prettyDate(new Date($(this).data("time"))));
  });

  $('#main-content').smoothState();
});
<commit_msg>scroll top after render<commit_after>// Generated by CoffeeScript 1.6.3
jQuery(function() {
  $.each($("[data-time]"), function(index, ele) {
    return $(ele).html(prettyDate(new Date($(this).data("time"))));
  });

  var $body = $("html, body");
  $('#main-content').smoothState({
      onEnd: {
          render: function(url, $container, $content) {
              $body.css('cursor', 'auto');
              $body.find('a').css('cursor', 'auto');
              $container.html($content);
              setTimeout(function() {
                  $body.animate({scrollTop: 0}, 500);
              }, 0);
          }
      }
  });
});
<|endoftext|>


<commit_before>const path = require('path');
const ls = require('ls');
const webpack = require('webpack');
const HtmlWebpackPlugin = require('html-webpack-plugin');
const CopyWebpackPlugin = require('copy-webpack-plugin');

const INTERFACE_THEME = {"desktop":"desktop","desktop_alt":"desktop","mobile":"mobile","mobile_alt":"mobile","oeview":"desktop","oeedit":"desktop"};

const buildPath = path.resolve(__dirname, 'geoportailv3_geoportal/static-ngeo/build/');
const entry = {};

// The dev mode will be used for builds on local machine outside docker
const nodeEnv = process.env['NODE_ENV'] || 'development';
const dev = nodeEnv == 'development'
process.traceDeprecation = true;

// FIXME: this looks strange: INTERFACE_THEME does not contain "main"
const name = 'main';
process.env.THEME = INTERFACE_THEME[name];

entry[name] = 'geoportailv3/apps/MainController.js';
const plugins = [
  new HtmlWebpackPlugin({
    inject: false,
    template: path.resolve(__dirname, 'geoportailv3_geoportal/static-ngeo/js/apps/' + name + '.html.ejs'),
    chunksSortMode: 'manual',
    filename: name + '.html',
    chunks: [name],
    vars: {
      entry_point: '${VISIBLE_ENTRY_POINT}',
    },
  }),
  new CopyWebpackPlugin({
    patterns: [
      {
        from: path.resolve(__dirname, 'geoportailv3_geoportal/static-ngeo/images/*'),
        to: buildPath + '/geoportailv3_geoportal/static-ngeo/images/',
        toType: 'dir',
        flatten: false,
      },
    ],
  }),
];

const babelPresetEnv = ['@babel/preset-env', {
  targets: {
    browsers: ['> 0.5% in CH', '> 0.5% in FR', 'Firefox ESR', 'ie 11'],
  },
  modules: false,
  loose: true
}];

// Transform code to ES2015 and annotate injectable functions with an $inject array.
const projectRule = {
  test: /geoportailv3_geoportal\/static-ngeo\/js\/.*\.js$/,
  use: {
    loader: 'babel-loader',
    options: {
      presets: [babelPresetEnv],
      plugins: ['@camptocamp/babel-plugin-angularjs-annotate'],
    }
  },
};

const rules = [
  projectRule,
];

const noDevServer = process.env['NO_DEV_SERVER'] == 'TRUE';
const devServer = dev && !noDevServer;

console.log("Use dev mode: " + dev)
console.log("Use dev server mode: " + devServer)

rules.push({
  test: /\.js$/,
  use: ["source-map-loader"],
  enforce: "pre"
});

module.exports = {
  output: {
    path: buildPath,
    publicPath: devServer ? '${VISIBLE_ENTRY_POINT}dev/' : '${VISIBLE_ENTRY_POINT}static-ngeo/UNUSED_CACHE_VERSION/build/'
  },
  entry: entry,
  module: {
    rules
  },
  plugins: plugins,
  resolve: {
    alias: {
      geoportailv3: path.resolve(__dirname, 'geoportailv3_geoportal/static-ngeo/js'),
    }
  },
};
<commit_msg>Fix again the background images<commit_after>const path = require('path');
const ls = require('ls');
const webpack = require('webpack');
const HtmlWebpackPlugin = require('html-webpack-plugin');
const CopyWebpackPlugin = require('copy-webpack-plugin');

const INTERFACE_THEME = {"desktop":"desktop","desktop_alt":"desktop","mobile":"mobile","mobile_alt":"mobile","oeview":"desktop","oeedit":"desktop"};

const buildPath = path.resolve(__dirname, 'geoportailv3_geoportal/static-ngeo/build/');
const entry = {};

// The dev mode will be used for builds on local machine outside docker
const nodeEnv = process.env['NODE_ENV'] || 'development';
const dev = nodeEnv == 'development'
process.traceDeprecation = true;

// FIXME: this looks strange: INTERFACE_THEME does not contain "main"
const name = 'main';
process.env.THEME = INTERFACE_THEME[name];

entry[name] = 'geoportailv3/apps/MainController.js';
const plugins = [
  new HtmlWebpackPlugin({
    inject: false,
    template: path.resolve(__dirname, 'geoportailv3_geoportal/static-ngeo/js/apps/' + name + '.html.ejs'),
    chunksSortMode: 'manual',
    filename: name + '.html',
    chunks: [name],
    vars: {
      entry_point: '${VISIBLE_ENTRY_POINT}',
    },
  }),
  new CopyWebpackPlugin({
    patterns: [
      {
        from: path.resolve(__dirname, 'geoportailv3_geoportal/static-ngeo/images'),
        to: buildPath + '/geoportailv3_geoportal/static-ngeo/images/',
        flatten: false,
      },
    ],
  }),
];

const babelPresetEnv = ['@babel/preset-env', {
  targets: {
    browsers: ['> 0.5% in CH', '> 0.5% in FR', 'Firefox ESR', 'ie 11'],
  },
  modules: false,
  loose: true
}];

// Transform code to ES2015 and annotate injectable functions with an $inject array.
const projectRule = {
  test: /geoportailv3_geoportal\/static-ngeo\/js\/.*\.js$/,
  use: {
    loader: 'babel-loader',
    options: {
      presets: [babelPresetEnv],
      plugins: ['@camptocamp/babel-plugin-angularjs-annotate'],
    }
  },
};

const rules = [
  projectRule,
];

const noDevServer = process.env['NO_DEV_SERVER'] == 'TRUE';
const devServer = dev && !noDevServer;

console.log("Use dev mode: " + dev)
console.log("Use dev server mode: " + devServer)

rules.push({
  test: /\.js$/,
  use: ["source-map-loader"],
  enforce: "pre"
});

module.exports = {
  output: {
    path: buildPath,
    publicPath: devServer ? '${VISIBLE_ENTRY_POINT}dev/' : '${VISIBLE_ENTRY_POINT}static-ngeo/UNUSED_CACHE_VERSION/build/'
  },
  entry: entry,
  module: {
    rules
  },
  plugins: plugins,
  resolve: {
    alias: {
      geoportailv3: path.resolve(__dirname, 'geoportailv3_geoportal/static-ngeo/js'),
    }
  },
};
<|endoftext|>


<commit_before>// Global tokenizer
//  tokenizes expressions and all that great stuff

import CheddarLexer from './tok/lex';
import CheddarEXPLICIT from './patterns/EXPLICIT';

import * as CheddarError from './consts/err';
import CheddarErrorMessage from './consts/err_msg';
import HelperLoc from '../helpers/loc';

import S1_ASSIGN from './states/assign';
import S2_IF from './states/if';
import S2_FOR from './states/for';
import S3_EXPR from './states/expr';

var CLOSES = '\n;';

const VALID_END = chr =>
    (CLOSES.indexOf(chr) > -1) || !chr;

const FORMAT_ERROR = (TOK, LEXER) => TOK
    .replace(/\$LOC/, HelperLoc(LEXER.Code, LEXER.Index).slice(0, 2).join(":"))
    .replace(/\$1/, LEXER.Code[LEXER.Index]);

const SINGLELINE_WHITESPACE = /[\t\f ]/;
const NEWLINE = /[\r\n]/;

export default class CheddarTokenize extends CheddarLexer {
    exec(ENDS = "") {

        let MATCH = this.attempt(
            S1_ASSIGN,
            S2_IF,
            S2_FOR,
            S3_EXPR
        );

        if (MATCH instanceof CheddarLexer && MATCH.Errored !== true) {

            this.Tokens = MATCH;
            this.Index = MATCH.Index;

            // Whether or not it backtracked for a newline
            let backtracked = false;

            while (SINGLELINE_WHITESPACE.test(this.Code[this.Index])) {
                backtracked = true;
                this.Index--;
            } /* then { */
            if (backtracked) {
                if (NEWLINE.test(this.Code[this.Index - 1])) {
                    this.Index--;
                }
            }

            while (this.Code[this.Index] && SINGLELINE_WHITESPACE.test(this.Code[this.Index]) || this._jumpComment()) {
                this.Index++;
            }

            if (ENDS.indexOf(this.Code[this.Index]) > -1) {
                return this.close();
            }

            if (!(MATCH instanceof CheddarEXPLICIT) && !(VALID_END(this.Code[this.Index]))) {
                return this.error(
                    FORMAT_ERROR(
                        CheddarErrorMessage.get(
                            CheddarError.UNEXPECTED_TOKEN
                        )
                    , this)
                );
            }

            this.Index++;

            this.jumpWhite();

            if (this.Code[this.Index]) {
                let M2 = new CheddarTokenize(this.Code, this.Index);
                let response = M2.exec(...arguments);

                if (response instanceof CheddarLexer) {
                    this._Tokens.push(...M2._Tokens);
                    this.Index = M2.Index;
                }
                else {
                    if (response !== CheddarError.EXIT_NOTFOUND)
                        return this.error(response);
                }

            }

            return this.close();
        }
        else {
            if (MATCH instanceof CheddarLexer) {
                return this.error(
                    FORMAT_ERROR(
                        CheddarErrorMessage.get(
                            CheddarError.UNEXPECTED_TOKEN
                        )
                    , this)
                );
            } else {
                return this.error(
                    FORMAT_ERROR(
                        typeof MATCH === 'symbol'
                        ? CheddarErrorMessage.get( MATCH )
                        : MATCH.toString()
                    , this)
                );
            }
        }
    }

}<commit_msg>fix [tok]: Fixed backtracking with expressions<commit_after>// Global tokenizer
//  tokenizes expressions and all that great stuff

import CheddarLexer from './tok/lex';
import CheddarEXPLICIT from './patterns/EXPLICIT';

import * as CheddarError from './consts/err';
import CheddarErrorMessage from './consts/err_msg';
import HelperLoc from '../helpers/loc';

import S1_ASSIGN from './states/assign';
import S2_IF from './states/if';
import S2_FOR from './states/for';
import S3_EXPR from './states/expr';

var CLOSES = '\n;';

const VALID_END = chr =>
    (CLOSES.indexOf(chr) > -1) || !chr;

const FORMAT_ERROR = (TOK, LEXER) => TOK
    .replace(/\$LOC/, HelperLoc(LEXER.Code, LEXER.Index).slice(0, 2).join(":"))
    .replace(/\$1/, LEXER.Code[LEXER.Index]);

const SINGLELINE_WHITESPACE = /[\t\f ]/;
const WHITESPACE = /\s/;
const NEWLINE = /[\r\n]/;

export default class CheddarTokenize extends CheddarLexer {
    exec(ENDS = "") {

        let MATCH = this.attempt(
            S1_ASSIGN,
            S2_IF,
            S2_FOR,
            S3_EXPR
        );

        if (MATCH instanceof CheddarLexer && MATCH.Errored !== true) {

            this.Tokens = MATCH;
            this.Index = MATCH.Index;

            // Whether or not it backtracked for a newline
            let backtracked = false;

            while (SINGLELINE_WHITESPACE.test(this.Code[this.Index])) {
                backtracked = true;
                this.Index--;
            }

            if (backtracked) {
                if (NEWLINE.test(this.Code[this.Index - 1])) {
                    this.Index--;
                }
            }

            while (this.Code[this.Index] && SINGLELINE_WHITESPACE.test(this.Code[this.Index]) || this._jumpComment()) {
                this.Index++;
            }

            if (ENDS.indexOf(this.Code[this.Index]) > -1) {
                return this.close();
            }

            if (!(MATCH instanceof CheddarEXPLICIT) && !(VALID_END(this.Code[this.Index]))) {
                return this.error(
                    FORMAT_ERROR(
                        CheddarErrorMessage.get(
                            CheddarError.UNEXPECTED_TOKEN
                        )
                    , this)
                );
            }

            this.Index++;

            this.jumpWhite();

            if (this.Code[this.Index]) {
                let M2 = new CheddarTokenize(this.Code, this.Index);
                let response = M2.exec(...arguments);

                if (response instanceof CheddarLexer) {
                    this._Tokens.push(...M2._Tokens);
                    this.Index = M2.Index;
                }
                else {
                    if (response !== CheddarError.EXIT_NOTFOUND)
                        return this.error(response);
                }

            }

            return this.close();
        }
        else {
            if (MATCH instanceof CheddarLexer) {
                return this.error(
                    FORMAT_ERROR(
                        CheddarErrorMessage.get(
                            CheddarError.UNEXPECTED_TOKEN
                        )
                    , this)
                );
            } else {
                return this.error(
                    FORMAT_ERROR(
                        typeof MATCH === 'symbol'
                        ? CheddarErrorMessage.get( MATCH )
                        : MATCH.toString()
                    , this)
                );
            }
        }
    }

}<|endoftext|>


<commit_before>	var M = {};
	M.loader = $('#ajax_wrap, #ajax_loader');
	M.loadCount = 0;
	M.loadCheck = function(){
		if ( this.loadCount > 0 ){
			this.loader.show();
		}
		else
		{
			this.loader.hide();
		}
	}

	M.init = function(){
		M.etsy.init();
		$('#etsy .more').tappable(function(){
			M.etsy.more();
		});

		M.write.get();
		$('#write .more').tappable(function(){
			M.write.get();
		});

		$('.home').tappable(function(){
			M.nav.home();
		});

		if ( $('.mobNav').css('display') == 'block' ){
			router.navigate('/etsy');
		}

		$('[show]:not(.prep)').addClass('prep').tappable(function(){
			var show = $(this).attr('show');
			router.navigate('/'+show);
			$('[show].act').removeClass('act');
			$('[show='+show+']').addClass('act');
		});
		router.checkRoutes(History.getState());
	}

	M.etsy = {};
	M.etsy.items = {};
	M.etsy.page = 0;
	M.etsy.limit = 15;
	M.etsy.isMore = true;
	M.etsy.get = function(){
		if ( M.etsy.isMore ){
			limit = M.etsy.limit;
			var offset = M.etsy.page*limit;
			var url = 'http://openapi.etsy.com/v2/shops/catandglove/listings/active.js?callback=getData&api_key=3lrt6kdjs0ppzxvxj1ypo0m4&includes=Images&limit='+limit+'&order=date_desc&offset='+offset;
			M.loadCount++;
			M.loadCheck();
			$.ajax({
			url:url,
			dataType: 'jsonp'
			}).done(function(data){
				M.loadCount--;
				M.loadCheck();
				if (data.ok){
				M.etsy.page++;
				var count = 0;
					for (x in data.results)
					{
						count++;
						var result = data.results[x];
						M.etsy.items[result.listing_id] = result;
					}
					if ( count < limit ) { M.etsy.isMore = false;}
					M.etsy.render();
				}
				else
				{

				}
			})
			.fail(function(){
			M.loadCount--;
			M.loadCheck();
			});
		}
	}

	M.etsy.hideMoreButton = function (){
		$('#etsy .more').hide();
	}

	M.etsy.showMoreButton = function (){
		$('#etsy .more').show();
	}

	M.etsy.render = function(){
		var itemTemp = '

{{{title}}}

';
		var etsyHTML = [];

		for (x in M.etsy.items){
			var result = M.etsy.items[x];
			if (result.rendered == undefined){
				result.image = result.Images[0]['url_570xN'];
				etsyHTML.push(Mustache.render(itemTemp, result));
				M.etsy.items[x]['rendered'] = true;
			}
		}

		var loadHTML = function(){
			if (etsyHTML.length > 0)
			{
				var $item = $(etsyHTML.pop());
				$('#etsy .items').append($item);
				$item.hide().fadeIn(1000);
				setTimeout(loadHTML, 100);
			}
			else
			{
				$('.etsyItem:not(prepped)').addClass('prepped').tappable(function(){
					var eid = $(this).attr('eid');
					router.navigate('/etsy/'+eid);
				});
				if ( M.etsy.isMore ){
					M.etsy.showMoreButton();
				}
				else
				{
					M.etsy.hideMoreButton();
				}
			}
		}
		loadHTML();
	}

M.etsy.renderItem = function (data) {
	M.nav.makeActive($('#etsy'));
	var tmpl = '

{{{description}}}
<button class="button">View on etsy</button>

Price - {{price}} {{currency_code}}

Style - {{style_string}}

{{{image_list}}}

';
	data.style_string = '';
	var eid = data.listing_id;
	for (x in data.style)
	{
		data.style_string += data.style[x] +', ';
	}
	if (data.style_string.length > 0)
	{
		data.style_string= data.style_string.substr(0, data.style_string.length-2);
	}
	data.description = data.description.replace(/\n/g,"
");

	data.image_list = '';
	var a = 0;
	for (x in data.Images ){
		if (a == 0){
		data.image_list+='

';
		a++;
		} else
		{
			data.image_list+='

';
		}
	}

	var res = Mustache.render(tmpl, data);
	$('[eid='+eid+']').after(res);
	scrollTo(0, $('[eid='+eid+']').offset().top);
}

M.restoreItems = function (){
	 $('.itemDetails').remove();
	 $('.activeItem').removeClass('activeItem');
}
	M.etsy.init = M.etsy.get;
	M.etsy.more = M.etsy.get;

	M.wp = {};
M.wp.category = '';
M.wp.items = {};
M.wp.page = 1;
M.wp.limit = 15;
M.wp.isMore = true;

M.wp.get = function(){
	if ( this.isMore ){
		var wp = this;
		url = '/press?json=get_category_posts&category_slug='+this.category+'&count='+this.limit+'&page='+this.page;
		M.loadCount++;
		M.loadCheck();
		$.get(url).
		done( function( data ){
			M.loadCount--;
			M.loadCheck();
			if ( data.status == 'ok' ){
				wp.page++;
				var count = 0;
				for ( x in data.posts ){
					count++;
					var result = data.posts[x];
					wp.items[result['slug']] = result;
				}
				if ( count < wp.limit ) { wp.isMore = false;}
			}
			wp.render();
		})
		.fail(function(){
		M.loadCount--;
		M.loadCheck();
		});
	}
}

M.write = M.wp;
M.write.category = 'write';
M.write.showMoreButton = function(){
	$('#write .more').show();
};
M.write.hideMoreButton = function(){
	$('#write .more').hide();
};
M.write.render = function(){
	var itemTemp = '

{{{title}}}
{{{content}}}

';
	var writeHTML = [];

	for (x in this.items){
		var result = this.items[x];
		if (result.rendered == undefined){
			//result.image = result.Images[0]['url_570xN'];
			writeHTML.push(Mustache.render(itemTemp, result));
			this.items[x]['rendered'] = true;
		}
	}

	var loadHTML = function(){
		if (writeHTML.length > 0)
		{
			var $item = $(writeHTML.pop());
			$('#write .items').append($item);
			$item.hide().fadeIn(1000);
			setTimeout(loadHTML, 100);
		}
		else
		{
			if ( M.write.isMore ){
				M.write.showMoreButton();
			}
			else
			{
				M.write.hideMoreButton();
			}
		}
	}
	loadHTML();
}

M.nav = {};

M.nav.home = function () {
	router.navigate('/');
}

M.nav.makeActive = function ($id){
	if ( !$id.hasClass('twelve') ){
		var id = $id.attr('id');
		$('[show]').removeClass('act');
		$('[show='+id+']').addClass('act');
		$('.content>.twelve').removeClass('twelve').addClass('four');
		$('.hidden').removeClass('hidden');
		$('#etsy, #write, #art').addClass('hidden');
		$id.removeClass('hidden').removeClass('four').addClass('twelve');
	}
}

M.nav.removeActive = function($id){
$('#etsy, #write, #art').removeClass('hidden');
$('.content>.twelve').removeClass('twelve').addClass('four');
}

M.nav.pageByID = function(type, id){

	if ( M[type]['items'][id] != undefined )
	{
		$('[eid='+id+']').addClass('activeItem');
		var data = M[type]['items'][id];
		M[type]['renderItem']( data );
		scrollTo(0, $('.activeItem').offset().top);
	}
	else
	{
		M[type]['getSingle'](id);
	}
}

var router = new Router();

router.route('/', function(){
	M.restoreItems();
	M.nav.removeActive();
});

router.route('/etsy', function(){
	M.restoreItems();
	M.nav.makeActive($('#etsy'));
});

router.route('/etsy/:id', function(id){
	M.restoreItems();
	M.nav.pageByID('etsy', id);
});

router.route('/write', function(){
	M.restoreItems();
	M.nav.makeActive($('#write'));
});

router.route('/write/:id', function(id){
	M.restoreItems();
	M.nav.pageByID('write', id);
});

router.route('/art', function(){
	M.restoreItems();
	M.nav.makeActive($('#art'));
});

router.route('/art/:id', function(id){
	M.restoreItems();
	M.nav.pageByID('art', id);
});

<commit_msg>added swipe to gallery<commit_after>	var M = {};
	M.loader = $('#ajax_wrap, #ajax_loader');
	M.loadCount = 0;
	M.loadCheck = function(){
		if ( this.loadCount > 0 ){
			this.loader.show();
		}
		else
		{
			this.loader.hide();
		}
	}

	M.init = function(){
		M.etsy.init();
		$('#etsy .more').tappable(function(){
			M.etsy.more();
		});

		M.write.get();
		$('#write .more').tappable(function(){
			M.write.get();
		});

		$('.home').tappable(function(){
			M.nav.home();
		});

		if ( $('.mobNav').css('display') == 'block' ){
			router.navigate('/etsy');
		}

		$('[show]:not(.prep)').addClass('prep').tappable(function(){
			var show = $(this).attr('show');
			router.navigate('/'+show);
			$('[show].act').removeClass('act');
			$('[show='+show+']').addClass('act');
		});
		router.checkRoutes(History.getState());
	}

	M.etsy = {};
	M.etsy.items = {};
	M.etsy.page = 0;
	M.etsy.limit = 15;
	M.etsy.isMore = true;
	M.etsy.get = function(){
		if ( M.etsy.isMore ){
			limit = M.etsy.limit;
			var offset = M.etsy.page*limit;
			var url = 'http://openapi.etsy.com/v2/shops/catandglove/listings/active.js?callback=getData&api_key=3lrt6kdjs0ppzxvxj1ypo0m4&includes=Images&limit='+limit+'&order=date_desc&offset='+offset;
			M.loadCount++;
			M.loadCheck();
			$.ajax({
			url:url,
			dataType: 'jsonp'
			}).done(function(data){
				M.loadCount--;
				M.loadCheck();
				if (data.ok){
				M.etsy.page++;
				var count = 0;
					for (x in data.results)
					{
						count++;
						var result = data.results[x];
						M.etsy.items[result.listing_id] = result;
					}
					if ( count < limit ) { M.etsy.isMore = false;}
					M.etsy.render();
				}
				else
				{

				}
			})
			.fail(function(){
			M.loadCount--;
			M.loadCheck();
			});
		}
	}

	M.etsy.hideMoreButton = function (){
		$('#etsy .more').hide();
	}

	M.etsy.showMoreButton = function (){
		$('#etsy .more').show();
	}

	M.etsy.render = function(){
		var itemTemp = '

{{{title}}}

';
		var etsyHTML = [];

		for (x in M.etsy.items){
			var result = M.etsy.items[x];
			if (result.rendered == undefined){
				result.image = result.Images[0]['url_570xN'];
				etsyHTML.push(Mustache.render(itemTemp, result));
				M.etsy.items[x]['rendered'] = true;
			}
		}

		var loadHTML = function(){
			if (etsyHTML.length > 0)
			{
				var $item = $(etsyHTML.pop());
				$('#etsy .items').append($item);
				$item.hide().fadeIn(1000);
				setTimeout(loadHTML, 100);
			}
			else
			{
				$('.etsyItem:not(prepped)').addClass('prepped').tappable(function(){
					var eid = $(this).attr('eid');
					router.navigate('/etsy/'+eid);
				});
				if ( M.etsy.isMore ){
					M.etsy.showMoreButton();
				}
				else
				{
					M.etsy.hideMoreButton();
				}
			}
		}
		loadHTML();
	}

M.etsy.renderItem = function (data) {
	M.nav.makeActive($('#etsy'));
	var tmpl = '

{{{description}}}
<button class="button">View on etsy</button>

Price - {{price}} {{currency_code}}

Style - {{style_string}}

{{{image_list}}}

';
	data.style_string = '';
	var eid = data.listing_id;
	for (x in data.style)
	{
		data.style_string += data.style[x] +', ';
	}
	if (data.style_string.length > 0)
	{
		data.style_string= data.style_string.substr(0, data.style_string.length-2);
	}
	data.description = data.description.replace(/\n/g,"
");

	data.image_list = '';
	var a = 0;
	for (x in data.Images ){
		if (a == 0){
		data.image_list+='

';
		a++;
		} else
		{
			data.image_list+='

';
		}
	}

	var res = Mustache.render(tmpl, data);
	$('[eid='+eid+']').after(res);
	scrollTo(0, $('[eid='+eid+']').offset().top);
	window.s = new Swipe($('.gal')[0]);
}

M.restoreItems = function (){
	 $('.itemDetails').remove();
	 $('.activeItem').removeClass('activeItem');
}
	M.etsy.init = M.etsy.get;
	M.etsy.more = M.etsy.get;

	M.wp = {};
M.wp.category = '';
M.wp.items = {};
M.wp.page = 1;
M.wp.limit = 15;
M.wp.isMore = true;

M.wp.get = function(){
	if ( this.isMore ){
		var wp = this;
		url = '/press?json=get_category_posts&category_slug='+this.category+'&count='+this.limit+'&page='+this.page;
		M.loadCount++;
		M.loadCheck();
		$.get(url).
		done( function( data ){
			M.loadCount--;
			M.loadCheck();
			if ( data.status == 'ok' ){
				wp.page++;
				var count = 0;
				for ( x in data.posts ){
					count++;
					var result = data.posts[x];
					wp.items[result['slug']] = result;
				}
				if ( count < wp.limit ) { wp.isMore = false;}
			}
			wp.render();
		})
		.fail(function(){
		M.loadCount--;
		M.loadCheck();
		});
	}
}

M.write = M.wp;
M.write.category = 'write';
M.write.showMoreButton = function(){
	$('#write .more').show();
};
M.write.hideMoreButton = function(){
	$('#write .more').hide();
};
M.write.render = function(){
	var itemTemp = '

{{{title}}}
{{{content}}}

';
	var writeHTML = [];

	for (x in this.items){
		var result = this.items[x];
		if (result.rendered == undefined){
			//result.image = result.Images[0]['url_570xN'];
			writeHTML.push(Mustache.render(itemTemp, result));
			this.items[x]['rendered'] = true;
		}
	}

	var loadHTML = function(){
		if (writeHTML.length > 0)
		{
			var $item = $(writeHTML.pop());
			$('#write .items').append($item);
			$item.hide().fadeIn(1000);
			setTimeout(loadHTML, 100);
		}
		else
		{
			if ( M.write.isMore ){
				M.write.showMoreButton();
			}
			else
			{
				M.write.hideMoreButton();
			}
		}
	}
	loadHTML();
}

M.nav = {};

M.nav.home = function () {
	router.navigate('/');
}

M.nav.makeActive = function ($id){
	if ( !$id.hasClass('twelve') ){
		var id = $id.attr('id');
		$('[show]').removeClass('act');
		$('[show='+id+']').addClass('act');
		$('.content>.twelve').removeClass('twelve').addClass('four');
		$('.hidden').removeClass('hidden');
		$('#etsy, #write, #art').addClass('hidden');
		$id.removeClass('hidden').removeClass('four').addClass('twelve');
	}
}

M.nav.removeActive = function($id){
$('#etsy, #write, #art').removeClass('hidden');
$('.content>.twelve').removeClass('twelve').addClass('four');
}

M.nav.pageByID = function(type, id){

	if ( M[type]['items'][id] != undefined )
	{
		$('[eid='+id+']').addClass('activeItem');
		var data = M[type]['items'][id];
		M[type]['renderItem']( data );
		scrollTo(0, $('.activeItem').offset().top);
	}
	else
	{
		M[type]['getSingle'](id);
	}
}

var router = new Router();

router.route('/', function(){
	M.restoreItems();
	M.nav.removeActive();
});

router.route('/etsy', function(){
	M.restoreItems();
	M.nav.makeActive($('#etsy'));
});

router.route('/etsy/:id', function(id){
	M.restoreItems();
	M.nav.pageByID('etsy', id);
});

router.route('/write', function(){
	M.restoreItems();
	M.nav.makeActive($('#write'));
});

router.route('/write/:id', function(id){
	M.restoreItems();
	M.nav.pageByID('write', id);
});

router.route('/art', function(){
	M.restoreItems();
	M.nav.makeActive($('#art'));
});

router.route('/art/:id', function(id){
	M.restoreItems();
	M.nav.pageByID('art', id);
});

<|endoftext|>


<commit_before>(function(w){

        var events = [
            {
                titulo : "The Developers Conference - Florianópolis",
                data : "13 a 16 de maio",
                local : "Oceania Convention Center",
                endereco : "Rua do Marisco, 550 - Ingleses - Florianópolis",
                embed_link : "https://www.google.com/maps/embed?pb=!1m14!1m8!1m3!1d3541.1684351171016!2d-48.399936!3d-27.432861!3m2!1i1024!2i768!4f13.1!3m3!1m2!1s0x9527420773711be1%3A0xdd51edbd5dfb6a15!2sOceania+Convention+Center!5e0!3m2!1spt-BR!2sbr!4v1428577375490",
                link : "http://www.thedevelopersconference.com.br/"
            },
            {
                titulo : "Python Nordeste 2015",
                data : "14 a 16 de Maio",
                local : "Natal - Rio Grande do Norte",
                endereco : "Hotel Imirá Plaza - Via Costeira",
                embed_link : "https://www.google.com/maps/embed?pb=!1m18!1m12!1m3!1d3969.1976254172037!2d-35.182604000000005!3d-5.827737!2m3!1f0!2f0!3f0!3m2!1i1024!2i768!4f13.1!3m3!1m2!1s0x7b2ffb83562ed77%3A0xea0923125a199def!2sImir%C3%A1+Plaza+Hotel+%26+Convention!5e0!3m2!1spt-BR!2sbr!4v1429061393672",
                link : "http://2015.pythonnordeste.org/"
            },
            {
                titulo : "RuPy Campinas",
                data : "20 de junho",
                local : "Faculdade de Engenharia Elétrica e de Computação (FEEC) - Unicamp",
                endereco : "Avenida Albert Einstein, 400 - Cidade Universitária - Campinas",
                embed_link : "https://www.google.com/maps/embed?pb=!1m14!1m8!1m3!1d7355.074395894319!2d-47.064721568999175!3d-22.819606489990303!3m2!1i1024!2i768!4f13.1!3m3!1m2!1s0x94c8c6add6b9f5d3%3A0x82e3f5267d13e82c!2sAv.+Albert+Einstein%2C+400+-+Cidade+Universit%C3%A1ria%2C+Faculdade+de+Engenharia+El%C3%A9trica+e+Computa%C3%A7%C3%A3o+(FEEC)%2C+Universidade+Estadual+de+Campinas+-+Campinas+-+SP%2C+13083-852!5e0!3m2!1sen!2sbr!4v1424211246725",
                link : "http://campinas.rupy.com.br/"
            }
        ];

        w.Events = {
                getAll : function(){
                    return events;
                }
        };
})(window);
<commit_msg>Adiciona evento TDC 2015 São Paulo<commit_after>(function(w){

        var events = [
            {
                titulo : "The Developers Conference - Florianópolis",
                data : "13 a 16 de maio",
                local : "Oceania Convention Center",
                endereco : "Rua do Marisco, 550 - Ingleses - Florianópolis",
                embed_link : "https://www.google.com/maps/embed?pb=!1m14!1m8!1m3!1d3541.1684351171016!2d-48.399936!3d-27.432861!3m2!1i1024!2i768!4f13.1!3m3!1m2!1s0x9527420773711be1%3A0xdd51edbd5dfb6a15!2sOceania+Convention+Center!5e0!3m2!1spt-BR!2sbr!4v1428577375490",
                link : "http://www.thedevelopersconference.com.br/"
            },
            {
                titulo : "Python Nordeste 2015",
                data : "14 a 16 de Maio",
                local : "Natal - Rio Grande do Norte",
                endereco : "Hotel Imirá Plaza - Via Costeira",
                embed_link : "https://www.google.com/maps/embed?pb=!1m18!1m12!1m3!1d3969.1976254172037!2d-35.182604000000005!3d-5.827737!2m3!1f0!2f0!3f0!3m2!1i1024!2i768!4f13.1!3m3!1m2!1s0x7b2ffb83562ed77%3A0xea0923125a199def!2sImir%C3%A1+Plaza+Hotel+%26+Convention!5e0!3m2!1spt-BR!2sbr!4v1429061393672",
                link : "http://2015.pythonnordeste.org/"
            },
            {
                titulo : "RuPy Campinas",
                data : "20 de junho",
                local : "Faculdade de Engenharia Elétrica e de Computação (FEEC) - Unicamp",
                endereco : "Avenida Albert Einstein, 400 - Cidade Universitária - Campinas",
                embed_link : "https://www.google.com/maps/embed?pb=!1m14!1m8!1m3!1d7355.074395894319!2d-47.064721568999175!3d-22.819606489990303!3m2!1i1024!2i768!4f13.1!3m3!1m2!1s0x94c8c6add6b9f5d3%3A0x82e3f5267d13e82c!2sAv.+Albert+Einstein%2C+400+-+Cidade+Universit%C3%A1ria%2C+Faculdade+de+Engenharia+El%C3%A9trica+e+Computa%C3%A7%C3%A3o+(FEEC)%2C+Universidade+Estadual+de+Campinas+-+Campinas+-+SP%2C+13083-852!5e0!3m2!1sen!2sbr!4v1424211246725",
                link : "http://campinas.rupy.com.br/"
            },
            {
                titulo : "The Developers Conference - São Paulo",
                data : "21 a 25 de julho",
                local : "Universidade Anhembi Morumbi",
                endereco : "Rua Casa do Ator, 275 - Vila Olímpia - São Paulo - SP",
                embed_link : "https://www.google.com/maps/embed?pb=!1m18!1m12!1m3!1d3656.1174053028217!2d-46.677008!3d-23.600122!2m3!1f0!2f0!3f0!3m2!1i1024!2i768!4f13.1!3m3!1m2!1s0x94ce57536602d7f7%3A0xe8034f1be9c3a8b8!2sUniversidade+Anhembi+Morumbi!5e0!3m2!1spt-BR!2sbr!4v1431381035864",
                link : "http://www.thedevelopersconference.com.br/"
            }
        ];

        w.Events = {
                getAll : function(){
                    return events;
                }
        };
})(window);
<|endoftext|>


<commit_before>/* Meathod : Constructor
 * Arguments : sizes (Array) - sequence in which the type of boxes required to be filled.
 *                             each element in the array is object with keys type and qty
 *                              [{type : 'A', qty : 10},{type : 'B', qty : 20}]
 * description : Creates an instance of Locker
*/
var Locker = function (sizes) {
  // Model data for locker boxes state true for occupied and false for empty
  this._lokerBoxes = {};
  // size and qty of that size boxes
  this._sizes = sizes || [{type :'small'  , qty : 1000 },
                          {type: 'medium' , qty : 1000 },
                          {type: 'large' , qty :1000} ];
  // init all boxes to empty
  for(var size =0; this._sizes.length; size++) {
    for(var i = 1; i <= this._sizes[size].qty; i++) {
      this._lokerBoxes[this._sizes[size].type][i] = false;
    }
  }

};
/* Meathod : addBags
 * Arguments : bagSize 0 - small , 1 - med , 2 -large
 * description : adds bag to the locker and generates a ticket no based on the locker no.
 * return : (string) ticket no. or message Lockers are full
*/
Locker.prototype.addBags = function(bagSize) {
  // Check validity of the bag size
  if(bagSize < 0 || bagSize >= this._sizes.length) {
    console.warn("invalid bag size");
    return "invalid bag size";
  }
  // Locate the next empty box in the lockers of bagSize
  for (var i = 1; i <= this._sizes[bagSize].qty; i++) {
    if(!this._lokerBoxes[this._sizes[bagSize].type][i]) {
      return bagSize+':'+i;
    }
  };
  // if all the boxes of bagSize are occupied then add the bag in the next size
  if(bagSize < this._sizes.length -1 ){
    this.addBags(bagSize+1);
  } else {
    // All lockes are full
    return "Lockers are full";
  }

};

/* Meathod : returnBags
 * Arguments : ticketNo (string) '0:23' represemted as typeOrder:BoxNo
 * description : locates the box checks if it occupied and marks it as returned
 * return : (string) ticket no. or message Lockers are full
*/
Locker.prototype.returnBag = function(ticketNo) {
  var ticket = ticketNo.split(':');

};
<commit_msg>add returnBag method<commit_after>/* Meathod : Constructor
 * Arguments : sizes (Array) - sequence in which the type of boxes required to be filled.
 *                             each element in the array is object with keys type and qty
 *                              [{type : 'A', qty : 10},{type : 'B', qty : 20}]
 * description : Creates an instance of Locker
*/
var Locker = function (sizes) {
  // Model data for locker boxes state true for occupied and false for empty
  this._lokerBoxes = {};
  // size and qty of that size boxes
  this._sizes = sizes || [{type :'small'  , qty : 1000 },
                          {type: 'medium' , qty : 1000 },
                          {type: 'large' , qty :1000} ];
  // init all boxes to empty
  for(var size =0; this._sizes.length; size++) {
    for(var i = 1; i <= this._sizes[size].qty; i++) {
      this._lokerBoxes[this._sizes[size].type][i] = false;
    }
  }

};
/* Meathod : addBags
 * Arguments : bagSize 0 - small , 1 - med , 2 -large
 * description : adds bag to the locker and generates a ticket no based on the locker no.
 * return : (string) ticket no. or message Lockers are full
*/
Locker.prototype.addBags = function(bagSize) {
  // Check validity of the bag size
  if(bagSize < 0 || bagSize >= this._sizes.length) {
    console.warn("invalid bag size");
    return "invalid bag size";
  }
  // Locate the next empty box in the lockers of bagSize
  for (var i = 1; i <= this._sizes[bagSize].qty; i++) {
    if(!this._lokerBoxes[this._sizes[bagSize].type][i]) {
      return bagSize+':'+i;
    }
  };
  // if all the boxes of bagSize are occupied then add the bag in the next size
  if(bagSize < this._sizes.length -1 ){
    this.addBags(bagSize+1);
  } else {
    // All lockes are full
    return "Lockers are full";
  }

};

/* Meathod : returnBags
 * Arguments : ticketNo (string) '0:23' represemted as typeOrder:BoxNo
 * description : locates the box checks if it occupied and marks it as returned
 * return : (string) Box size and box no.
*/
Locker.prototype.returnBag = function(ticketNo) {
  var ticket = ticketNo.split(':');
  var boxType = parseInt(ticket[0]);
  var boxNo = parseInt(ticket[1]);

  if(boxType <0 || boxType >= this._sizes.length ||
    boxNo <1 || boxNo > this._sizes[boxType].qty ||
    !this._lokerBoxes[this._sizes[boxType].type][boxNo]){

    return "Invalid ticket no."
  }
  this._lokerBoxes[this._sizes[boxType].type][boxNo] = false;
  return 'Size : '+ this._sizes[boxType].type + 'Box No. : ' + boxNo;
};
<|endoftext|>


<commit_before>import React from 'react';
import { mount } from 'enzyme';

const RestrictFocusToChildren = require('../RestrictFocusToChildren');

const eventMap = {};

window.addEventListener = jest.genMockFn().mockImplementation((event, cb) => {
  eventMap[event] = cb;
});

class TestComponent extends React.Component {
  state = {
    showContent: false
  }

  render () {
    return (

        <button
          id='open-button'
          onClick={e => {
            //Enzyme simulate click was not focusing the button
            e.target.focus();
            this.setState({ showContent: true });
          }}
        >
          Open Content
        </button>

Focusable Div

        {this.state.showContent ? (
          <RestrictFocusToChildren>

              <button id='close-button' onClick={() => this.setState({ showContent: false })}>
                Close Content
              </button>

          </RestrictFocusToChildren>
        ) : null}

    );
  }
}

describe('RestrictFocusToChildren', () => {
  let openButton;
  let wrapper;

  beforeEach(() => {
    wrapper = mount(<TestComponent />, { attachTo: window.document });
    openButton = wrapper.find('#open-button').first();

    openButton.simulate('click');
  });

  afterEach(() => {
    wrapper.unmount();
  });

  it('should remember the last focused node', () => {
    expect(wrapper.find(RestrictFocusToChildren).first().instance().previousFocusedNode)
      .toEqual(openButton.instance());
  });

  it('should return focus to the last focused node on unmount', () => {
    const closeButton = wrapper.find('#close-button').first();

    closeButton.simulate('click');

    expect(window.document.activeElement).toEqual(openButton.instance());
  });

  it('should hide content in parent that is focusable when child is rendered', () => {
    const buttonHTML = openButton.html();

    expect(buttonHTML).toContain('tabindex="-1"');
    expect(buttonHTML).toContain('aria-hidden="true"');
  });

  it('should unhide content in parent that is focusable when child is removed', () => {
    const closeButton = wrapper.find('#close-button').first();

    closeButton.simulate('click');

    const openButtonHTML = openButton.html();

    expect(openButtonHTML).not.toContain('tabindex');
    expect(openButtonHTML).not.toContain('aria-hidden');
  });

  it('should preserve tabindex on unmount', () => {
    const focusableDiv = wrapper.find('#focusable-div').first();
    const closeButton = wrapper.find('#close-button').first();

    expect(focusableDiv.html()).toContain('tabindex="-1"');
    closeButton.simulate('click');
    expect(focusableDiv.html()).toContain('tabindex="2"');
  });
});<commit_msg>Tests focusin functionality<commit_after>import React from 'react';
import { mount } from 'enzyme';

const RestrictFocusToChildren = require('../RestrictFocusToChildren');

const eventMap = {};

window.addEventListener = jest.genMockFn().mockImplementation((event, cb) => {
  eventMap[event] = cb;
});

class TestComponent extends React.Component {
  state = {
    showContent: false,
    showNewContent: false
  }

  render () {
    return (

        <button
          id='open-button'
          onClick={e => {
            //Enzyme simulate click was not focusing the button
            e.target.focus();
            this.setState({ showContent: true });
          }}
        >
          Open Content
        </button>

Focusable Div

        {this.state.showNewContent ? (<button id='new-button'>New focusable Button</button>) : null}
        {this.state.showContent ? (
          <RestrictFocusToChildren>

              <button id='close-button' onClick={() => this.setState({ showContent: false })}>
                Close Content
              </button>
              <button
                id='add-new-node'
                onClick={e => {
                  //Enzyme simulate click was not focusing the button
                  e.target.focus();
                  this.setState({ showNewContent: true });
                }}
              >
                Add New Node
              </button>

          </RestrictFocusToChildren>
        ) : null}

    );
  }
}

describe('RestrictFocusToChildren', () => {
  let openButton;
  let wrapper;

  beforeEach(() => {
    wrapper = mount(<TestComponent />, { attachTo: window.document });
    openButton = wrapper.find('#open-button').first();

    openButton.simulate('click');
  });

  afterEach(() => {
    wrapper.unmount();
  });

  it('should remember the last focused node', () => {
    expect(wrapper.find(RestrictFocusToChildren).first().instance().previousFocusedNode)
      .toEqual(openButton.instance());
  });

  it('should return focus to the last focused node on unmount', () => {
    const closeButton = wrapper.find('#close-button').first();

    closeButton.simulate('click');

    expect(window.document.activeElement).toEqual(openButton.instance());
  });

  it('should hide content in parent that is focusable when child is rendered', () => {
    const buttonHTML = openButton.html();

    expect(buttonHTML).toContain('tabindex="-1"');
    expect(buttonHTML).toContain('aria-hidden="true"');
  });

  it('should unhide content in parent that is focusable when child is removed', () => {
    const closeButton = wrapper.find('#close-button').first();

    closeButton.simulate('click');

    const openButtonHTML = openButton.html();

    expect(openButtonHTML).not.toContain('tabindex');
    expect(openButtonHTML).not.toContain('aria-hidden');
  });

  it('should preserve tabindex on unmount', () => {
    const focusableDiv = wrapper.find('#focusable-div').first();
    const closeButton = wrapper.find('#close-button').first();

    expect(focusableDiv.html()).toContain('tabindex="-1"');
    closeButton.simulate('click');
    expect(focusableDiv.html()).toContain('tabindex="2"');
  });

  it('should redirect focus on focusin event if node is not in focusable nodes array', () => {
    const closeButton = wrapper.find('#close-button').first();
    const addNewNodeButton = wrapper.find('#add-new-node').first();

    addNewNodeButton.simulate('click');

    const newButton = wrapper.find('#new-button').first().instance();

    eventMap.focusin({ target: newButton });

    expect(window.document.activeElement).toEqual(closeButton.instance());
  });
});<|endoftext|>


<commit_before>'use strict';

var expect = require('chai').expect;

describe('ScatterChart', function() {
  it('renders scatterchart', function() {
    var React = require('react/addons');
    var ScatterChart = require('../src/scatterchart').ScatterChart;
    var generate = require('../utils/datagen').generateArrayOfPoints;
    var TestUtils = React.addons.TestUtils;
    var points = 5;
    var pointRadius = 5;

    // Render a scatterchart using array data
    var data = {
      series1: generate(points),
      series2: generate(points)
    };
    var scatterchart = TestUtils.renderIntoDocument(
      <ScatterChart data={data} width={400} height={200} pointRadius={pointRadius} />
    );

    var circles = TestUtils.scryRenderedDOMComponentsWithTag(
      scatterchart, 'circle');
    expect(circles).to.have.length(2 * points);

    var circleOne = circles[0];
    expect(circleOne.getDOMNode().r.baseVal.value).to.equal(pointRadius);
    TestUtils.Simulate.mouseOver(circleOne);
    expect(circleOne.getDOMNode().r.baseVal.value).to.be.above(pointRadius);
    TestUtils.Simulate.mouseOut(circleOne);
    expect(circleOne.getDOMNode().r.baseVal.value).to.equal(pointRadius);
  });
});
<commit_msg>Make sure scatter chart's circle are animating when hovered<commit_after>'use strict';

var expect = require('chai').expect;

describe('ScatterChart', function() {
  it('renders scatterchart', function() {
    var React = require('react/addons');
    var ScatterChart = require('../src/scatterchart').ScatterChart;
    var generate = require('../utils/datagen').generateArrayOfPoints;
    var TestUtils = React.addons.TestUtils;
    var points = 5;
    var pointRadius = 5;

    // Render a scatterchart using array data
    var data = {
      series1: generate(points),
      series2: generate(points)
    };
    var scatterchart = TestUtils.renderIntoDocument(
      <ScatterChart data={data} width={400} height={200} pointRadius={pointRadius} />
    );

    var circles = TestUtils.scryRenderedDOMComponentsWithTag(
      scatterchart, 'circle');
    expect(circles).to.have.length(2 * points);

    var circleOne = circles[0];
    var circleOneColor = circleOne.props.fill;

    expect(circleOne.props.r).to.equal(pointRadius);

    TestUtils.Simulate.mouseOver(circleOne);
    expect(circleOne.props.r).to.be.above(pointRadius);
    expect(circleOne.props.fill).to.not.equal(circleOneColor);

    TestUtils.Simulate.mouseOut(circleOne);
    expect(circleOne.props.r).to.equal(pointRadius);
    expect(circleOne.props.fill).to.equal(circleOneColor);
  });
});
<|endoftext|>


<commit_before>{% load i18n %}

<script src="//www.gstatic.com/charts/loader.js"></script>
<script src="//ajax.googleapis.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<script type="text/javascript">
  google.charts.load('current', {'packages':['corechart']});
  google.charts.setOnLoadCallback(drawCharts);

  function drawCharts() {
    var valuesChart = new google.visualization.Histogram(document.getElementById('values-histogram'));
    var scoresChart = new google.visualization.Histogram(document.getElementById('scores-histogram'));

    $.get('{{ url_values }}', function (data) {
      valuesChart.draw(
        new google.visualization.DataTable(data),
        {
          colors: ['#bd2222'],
          height: 300,
          legend: { position: 'none' },
          title: '{% trans "Values" %}',
        }
      );
    });

    $.get('{{ url_scores }}', function (data) {
      scoresChart.draw(
        new google.visualization.DataTable(data),
        {
          height: 300,
          legend: { position: 'none' },
          title: '{% trans "Quality scores" %}',
        }
      );
    });
  }
</script>
<commit_msg>Handle error when chart does not load<commit_after>{% load i18n %}

<script src="//www.gstatic.com/charts/loader.js"></script>
<script src="//ajax.googleapis.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<script type="text/javascript">
  google.charts.load('current', {'packages':['corechart']});
  google.charts.setOnLoadCallback(drawCharts);

  function drawCharts() {
    var valuesChart = new google.visualization.Histogram(document.getElementById('values-histogram'));
    var scoresChart = new google.visualization.Histogram(document.getElementById('scores-histogram'));

    $.get('{{ url_values }}', function (data) {
      valuesChart.draw(
        new google.visualization.DataTable(data),
        {
          colors: ['#bd2222'],
          height: 300,
          legend: { position: 'none' },
          title: '{% trans "Values" %}',
        }
      );
    }).fail(function () {
      document.getElementById('values-histogram').textContent = '{% trans "An error occured while loading this chart." %}';
    });

    $.get('{{ url_scores }}', function (data) {
      scoresChart.draw(
        new google.visualization.DataTable(data),
        {
          height: 300,
          legend: { position: 'none' },
          title: '{% trans "Quality scores" %}',
        }
      );
    }).fail(function () {
      document.getElementById('scores-histogram').textContent = '{% trans "An error occured while loading this chart." %}';
    });
  }
</script>
<|endoftext|>


<commit_before>/*
 * Copyright 2018 balena
 *
 * @license Apache-2.0
 */

"use strict";

const Bluebird = require("bluebird");
const fse = require("fs-extra");
const { join } = require("path");
const { homedir } = require("os");
const util = require('util');
const exec = util.promisify(require('child_process').exec);

// required for unwrapping images
const imagefs = require('balena-image-fs');
const stream = require('stream');
const pipeline = util.promisify(stream.pipeline);

// copied from the SV
// https://github.com/balena-os/balena-supervisor/blob/master/src/config/backends/config-txt.ts
// TODO: retrieve this from the SDK (requires v16.2.0) or future versions of device contracts
// https://www.balena.io/docs/reference/sdk/node-sdk/#balena.models.config.getConfigVarSchema
const supportsBootConfig = (deviceType) => {
	return (
		[
			'fincm3',
			'rt-rpi-300',
			'243390-rpi3',
			'nebra-hnt',
			'revpi-connect',
			'revpi-core-3',
		].includes(deviceType) || deviceType.startsWith('raspberry')
	);
};

const enableSerialConsole = async (imagePath) => {
	const bootConfig = await imagefs.interact(imagePath, 1, async (_fs) => {
		return require('bluebird')
			.promisify(_fs.readFile)('/config.txt')
			.catch((err) => {
				return undefined;
			});
	});

	if (bootConfig) {
		await imagefs.interact(imagePath, 1, async (_fs) => {
			const regex = /^enable_uart=.*$/m;
			const value = 'enable_uart=1';

			console.log(`Setting ${value} in config.txt...`);

			// delete any existing instances before appending to the file
			const newConfig = bootConfig.toString().replace(regex, '');
			await require('bluebird').promisify(_fs.writeFile)(
				'/config.txt',
				newConfig.concat(`\n\n${value}\n\n`),
			);
		});
	}
};

module.exports = {
  title: "Managed BalenaOS release suite",
  run: async function () {
    const Worker = this.require("common/worker");
    const BalenaOS = this.require("components/os/balenaos");
    const Balena = this.require("components/balena/sdk");
    // used for `preload`
    const CLI = this.require("components/balena/cli");

    await fse.ensureDir(this.suite.options.tmpdir);

    // add objects to the context, so that they can be used across all the tests in this suite
    this.suite.context.set({
      cloud: new Balena(this.suite.options.balena.apiUrl, this.getLogger()),
      balena: {
        name: this.suite.options.id,
        application: `${this.suite.options.balena.organization}/${this.suite.options.id}`,
        organization: this.suite.options.balena.organization,
        sshKey: { label: this.suite.options.id },
      },
      cli: new CLI(this.suite.options.balena.apiUrl, this.getLogger()),
      sshKeyPath: join(homedir(), "id"),
      utils: this.require("common/utils"),
      worker: new Worker(this.suite.deviceType.slug, this.getLogger()),
    });

    // Network definitions - these are given to the testbot via the config sent via the config.js
    if (this.suite.options.balenaOS.network.wired === true) {
      this.suite.options.balenaOS.network.wired = {
        nat: true,
      };
    } else {
      delete this.suite.options.balenaOS.network.wired;
    }
    if (this.suite.options.balenaOS.network.wireless === true) {
      this.suite.options.balenaOS.network.wireless = {
        ssid: this.suite.options.id,
        psk: `${this.suite.options.id}_psk`,
        nat: true,
      };
    } else {
      delete this.suite.options.balenaOS.network.wireless;
    }

    // Authenticating balenaSDK
    this.log("Logging into balena with balenaSDK");
    await this.context
      .get()
      .cloud.balena.auth.loginWithToken(this.suite.options.balena.apiKey);

    // create a balena application
    this.log("Creating application in cloud...");
    await this.context.get().cloud.balena.models.application.create({
      name: this.suite.options.id,
      deviceType: this.suite.deviceType.slug,
      organization: this.context.get().balena.organization,
    });

    // remove application when tests are done
    this.suite.teardown.register(() => {
      this.log("Removing application");
      try {
        return this.context
        .get()
        .cloud.balena.models.application.remove(
          this.context.get().balena.application
        );
      } catch(e){
        this.log(`Error while removing application...`)
      }
    });

    // Push a single container application
    this.log(`Cloning getting started repo...`);
    this.suite.context.set({
      appPath: `${__dirname}/app`
    })
    await exec(
      `git clone https://github.com/balena-io-examples/balena-node-hello-world.git ${this.context.get().appPath}`
    );
    this.log(`Pushing release to app...`);
    const initialCommit = await this.context.get().cloud.pushReleaseToApp(this.context.get().balena.application, `${__dirname}/app`)
    this.suite.context.set({
      balena: {
        initialCommit: initialCommit
      }
    })

    // create an ssh key, so we can ssh into DUT later
    await this.context
      .get()
      .cloud.balena.models.key.create(
        this.context.get().balena.sshKey.label,
        await this.context
          .get()
          .utils.createSSHKey(this.context.get().sshKeyPath)
      );
    this.suite.teardown.register(() => {
      return Bluebird.resolve(
        this.context
          .get()
          .cloud.removeSSHKey(this.context.get().balena.sshKey.label)
      );
    });

    // generate a uuid
    this.suite.context.set({
      balena: {
        uuid: this.context.get().cloud.balena.models.device.generateUniqueKey(),
      },
    });

    this.suite.context.set({
      os: new BalenaOS(
        {
          deviceType: this.suite.deviceType.slug,
          network: this.suite.options.balenaOS.network,
        },
        this.getLogger()
      ),
    });

    // unpack OS
    await this.context.get().os.fetch();

    // If this is a flasher image, and we are using qemu, unwrap
		if (
			this.suite.deviceType.data.storage.internal &&
			process.env.WORKER_TYPE === `qemu`
		) {
			const RAW_IMAGE_PATH = `/opt/balena-image-${this.suite.deviceType.slug}.balenaos-img`;
			const OUTPUT_IMG_PATH = '/data/downloads/unwrapped.img';
			console.log(`Unwrapping file ${this.context.get().os.image.path}`);
			console.log(`Looking for ${RAW_IMAGE_PATH}`);
			try {
				await imagefs.interact(
					this.context.get().os.image.path,
					2,
					async (fsImg) => {
						await pipeline(
							fsImg.createReadStream(RAW_IMAGE_PATH),
							fse.createWriteStream(OUTPUT_IMG_PATH),
						);
					},
				);

				this.context.get().os.image.path = OUTPUT_IMG_PATH;
				console.log(`Unwrapped flasher image!`);
			} catch (e) {
				// If the outer image doesn't contain an image for installation, ignore the error
				if (e.code === 'ENOENT') {
					console.log('Not a flasher image, skipping unwrap');
				} else {
					throw e;
				}
			}
		}

    await this.context.get().os.readOsRelease();

    // get config.json for application
    let config = await this.context
      .get()
      .cloud.balena.models.os.getConfig(this.context.get().balena.application, {
        version: this.context.get().os.contract.version,
      });

    config.uuid = this.context.get().balena.uuid;

    //register the device with the application, add the api key to the config.json
    let deviceApiKey = await this.context
      .get()
      .cloud.balena.models.device.register(
        this.context.get().balena.application,
        this.context.get().balena.uuid
      );
    config.deviceApiKey = deviceApiKey.api_key;

    // get newly registered device id, add to config.json
    await Bluebird.delay(1000 * 10);
    let devId = await this.context
      .get()
      .cloud.balena.models.device.get(this.context.get().balena.uuid);
    config.deviceId = devId.id;
    config.persistentLogging = true;
    config.developmentMode= true;

    // get ready to populate DUT image config.json with the attributes we just generated
    this.context.get().os.addCloudConfig(config);

    // Teardown the worker when the tests end
    this.suite.teardown.register(() => {
      this.log("Worker teardown");
      return this.context.get().worker.teardown();
    });

    console.log('--config.json--')
    console.log(this.context.get().os.configJson);
    // preload image with the single container application
    this.log(`Device uuid should be ${this.context.get().balena.uuid}`)
    await this.context.get().os.configure();
    await this.context.get().cli.preload(this.context.get().os.image.path, {
      app: this.context.get().balena.application,
      commit: initialCommit,
      pin: true,
    });

    this.log("Setting up worker");
    await this.context
      .get()
      .worker.network(this.suite.options.balenaOS.network);

    if (supportsBootConfig(this.suite.deviceType.slug)) {
      await enableSerialConsole(this.context.get().os.image.path);
    }

    await this.context.get().worker.off();
    await this.context.get().worker.flash(this.context.get().os.image.path);
    await this.context.get().worker.on();

    this.log("Waiting for device to be reachable");
    await this.context.get().utils.waitUntil(async() => {
      console.log(`checking device is online in the dashboard....`)

      let isOnline =  await this.context
        .get()
        .cloud.balena.models.device.isOnline(this.context.get().balena.uuid);

      console.log(isOnline);
      return isOnline === true
    });

    this.log("Device is online and provisioned successfully");
    await this.context.get().utils.waitUntil(async () => {
      this.log("Trying to ssh into device");
      let hostname = await this.context
      .get()
      .cloud.executeCommandInHostOS(
        "cat /etc/hostname",
        this.context.get().balena.uuid
      )
      return hostname === this.context.get().balena.uuid.slice(0, 7)
    }, false);

    this.log("Unpinning");
    await this.context.get().utils.waitUntil(async () => {
      this.log(`Unpinning device from release`)
      await this.context
      .get()
      .cloud.balena.models.device.trackApplicationRelease(
        this.context.get().balena.uuid
      );

      let unpinned = await this.context
      .get()
      .cloud.balena.models.device.isTrackingApplicationRelease(this.context.get().balena.uuid)

      return unpinned
    }, false);

    this.suite.teardown.register(async () => {
      await this.context.get().worker.archiveLogs(this.id,  `${this.context.get().balena.uuid.slice(0, 7)}.local`,);
    });

    // wait until the service is running before continuing
    await this.context.get().cloud.waitUntilServicesRunning(
      this.context.get().balena.uuid,
      [`main`],
      this.context.get().balena.initialCommit
    )
  },
  tests: [
    "./tests/preload",
    "./tests/supervisor",
    "./tests/multicontainer",
  ],
};
<commit_msg>tests/cloud: register teardown before  online<commit_after>/*
 * Copyright 2018 balena
 *
 * @license Apache-2.0
 */

"use strict";

const Bluebird = require("bluebird");
const fse = require("fs-extra");
const { join } = require("path");
const { homedir } = require("os");
const util = require('util');
const exec = util.promisify(require('child_process').exec);

// required for unwrapping images
const imagefs = require('balena-image-fs');
const stream = require('stream');
const pipeline = util.promisify(stream.pipeline);

// copied from the SV
// https://github.com/balena-os/balena-supervisor/blob/master/src/config/backends/config-txt.ts
// TODO: retrieve this from the SDK (requires v16.2.0) or future versions of device contracts
// https://www.balena.io/docs/reference/sdk/node-sdk/#balena.models.config.getConfigVarSchema
const supportsBootConfig = (deviceType) => {
	return (
		[
			'fincm3',
			'rt-rpi-300',
			'243390-rpi3',
			'nebra-hnt',
			'revpi-connect',
			'revpi-core-3',
		].includes(deviceType) || deviceType.startsWith('raspberry')
	);
};

const enableSerialConsole = async (imagePath) => {
	const bootConfig = await imagefs.interact(imagePath, 1, async (_fs) => {
		return require('bluebird')
			.promisify(_fs.readFile)('/config.txt')
			.catch((err) => {
				return undefined;
			});
	});

	if (bootConfig) {
		await imagefs.interact(imagePath, 1, async (_fs) => {
			const regex = /^enable_uart=.*$/m;
			const value = 'enable_uart=1';

			console.log(`Setting ${value} in config.txt...`);

			// delete any existing instances before appending to the file
			const newConfig = bootConfig.toString().replace(regex, '');
			await require('bluebird').promisify(_fs.writeFile)(
				'/config.txt',
				newConfig.concat(`\n\n${value}\n\n`),
			);
		});
	}
};

module.exports = {
  title: "Managed BalenaOS release suite",
  run: async function () {
    const Worker = this.require("common/worker");
    const BalenaOS = this.require("components/os/balenaos");
    const Balena = this.require("components/balena/sdk");
    // used for `preload`
    const CLI = this.require("components/balena/cli");

    await fse.ensureDir(this.suite.options.tmpdir);

    // add objects to the context, so that they can be used across all the tests in this suite
    this.suite.context.set({
      cloud: new Balena(this.suite.options.balena.apiUrl, this.getLogger()),
      balena: {
        name: this.suite.options.id,
        application: `${this.suite.options.balena.organization}/${this.suite.options.id}`,
        organization: this.suite.options.balena.organization,
        sshKey: { label: this.suite.options.id },
      },
      cli: new CLI(this.suite.options.balena.apiUrl, this.getLogger()),
      sshKeyPath: join(homedir(), "id"),
      utils: this.require("common/utils"),
      worker: new Worker(this.suite.deviceType.slug, this.getLogger()),
    });

    // Network definitions - these are given to the testbot via the config sent via the config.js
    if (this.suite.options.balenaOS.network.wired === true) {
      this.suite.options.balenaOS.network.wired = {
        nat: true,
      };
    } else {
      delete this.suite.options.balenaOS.network.wired;
    }
    if (this.suite.options.balenaOS.network.wireless === true) {
      this.suite.options.balenaOS.network.wireless = {
        ssid: this.suite.options.id,
        psk: `${this.suite.options.id}_psk`,
        nat: true,
      };
    } else {
      delete this.suite.options.balenaOS.network.wireless;
    }

    // Authenticating balenaSDK
    this.log("Logging into balena with balenaSDK");
    await this.context
      .get()
      .cloud.balena.auth.loginWithToken(this.suite.options.balena.apiKey);

    // create a balena application
    this.log("Creating application in cloud...");
    await this.context.get().cloud.balena.models.application.create({
      name: this.suite.options.id,
      deviceType: this.suite.deviceType.slug,
      organization: this.context.get().balena.organization,
    });

    // remove application when tests are done
    this.suite.teardown.register(() => {
      this.log("Removing application");
      try {
        return this.context
        .get()
        .cloud.balena.models.application.remove(
          this.context.get().balena.application
        );
      } catch(e){
        this.log(`Error while removing application...`)
      }
    });

    // Push a single container application
    this.log(`Cloning getting started repo...`);
    this.suite.context.set({
      appPath: `${__dirname}/app`
    })
    await exec(
      `git clone https://github.com/balena-io-examples/balena-node-hello-world.git ${this.context.get().appPath}`
    );
    this.log(`Pushing release to app...`);
    const initialCommit = await this.context.get().cloud.pushReleaseToApp(this.context.get().balena.application, `${__dirname}/app`)
    this.suite.context.set({
      balena: {
        initialCommit: initialCommit
      }
    })

    // create an ssh key, so we can ssh into DUT later
    await this.context
      .get()
      .cloud.balena.models.key.create(
        this.context.get().balena.sshKey.label,
        await this.context
          .get()
          .utils.createSSHKey(this.context.get().sshKeyPath)
      );
    this.suite.teardown.register(() => {
      return Bluebird.resolve(
        this.context
          .get()
          .cloud.removeSSHKey(this.context.get().balena.sshKey.label)
      );
    });

    // generate a uuid
    this.suite.context.set({
      balena: {
        uuid: this.context.get().cloud.balena.models.device.generateUniqueKey(),
      },
    });

    this.suite.context.set({
      os: new BalenaOS(
        {
          deviceType: this.suite.deviceType.slug,
          network: this.suite.options.balenaOS.network,
        },
        this.getLogger()
      ),
    });

    // unpack OS
    await this.context.get().os.fetch();

    // If this is a flasher image, and we are using qemu, unwrap
		if (
			this.suite.deviceType.data.storage.internal &&
			process.env.WORKER_TYPE === `qemu`
		) {
			const RAW_IMAGE_PATH = `/opt/balena-image-${this.suite.deviceType.slug}.balenaos-img`;
			const OUTPUT_IMG_PATH = '/data/downloads/unwrapped.img';
			console.log(`Unwrapping file ${this.context.get().os.image.path}`);
			console.log(`Looking for ${RAW_IMAGE_PATH}`);
			try {
				await imagefs.interact(
					this.context.get().os.image.path,
					2,
					async (fsImg) => {
						await pipeline(
							fsImg.createReadStream(RAW_IMAGE_PATH),
							fse.createWriteStream(OUTPUT_IMG_PATH),
						);
					},
				);

				this.context.get().os.image.path = OUTPUT_IMG_PATH;
				console.log(`Unwrapped flasher image!`);
			} catch (e) {
				// If the outer image doesn't contain an image for installation, ignore the error
				if (e.code === 'ENOENT') {
					console.log('Not a flasher image, skipping unwrap');
				} else {
					throw e;
				}
			}
		}

    await this.context.get().os.readOsRelease();

    // get config.json for application
    let config = await this.context
      .get()
      .cloud.balena.models.os.getConfig(this.context.get().balena.application, {
        version: this.context.get().os.contract.version,
      });

    config.uuid = this.context.get().balena.uuid;

    //register the device with the application, add the api key to the config.json
    let deviceApiKey = await this.context
      .get()
      .cloud.balena.models.device.register(
        this.context.get().balena.application,
        this.context.get().balena.uuid
      );
    config.deviceApiKey = deviceApiKey.api_key;

    // get newly registered device id, add to config.json
    await Bluebird.delay(1000 * 10);
    let devId = await this.context
      .get()
      .cloud.balena.models.device.get(this.context.get().balena.uuid);
    config.deviceId = devId.id;
    config.persistentLogging = true;
    config.developmentMode= true;

    // get ready to populate DUT image config.json with the attributes we just generated
    this.context.get().os.addCloudConfig(config);

    // Teardown the worker when the tests end
    this.suite.teardown.register(() => {
      this.log("Worker teardown");
      return this.context.get().worker.teardown();
    });

    console.log('--config.json--')
    console.log(this.context.get().os.configJson);
    // preload image with the single container application
    this.log(`Device uuid should be ${this.context.get().balena.uuid}`)
    await this.context.get().os.configure();
    await this.context.get().cli.preload(this.context.get().os.image.path, {
      app: this.context.get().balena.application,
      commit: initialCommit,
      pin: true,
    });

    this.log("Setting up worker");
    await this.context
      .get()
      .worker.network(this.suite.options.balenaOS.network);

    if (supportsBootConfig(this.suite.deviceType.slug)) {
      await enableSerialConsole(this.context.get().os.image.path);
    }

    await this.context.get().worker.off();
    await this.context.get().worker.flash(this.context.get().os.image.path);
    await this.context.get().worker.on();

    this.suite.teardown.register(async () => {
      await this.context.get().worker.archiveLogs(this.id, `${this.context.get().balena.uuid.slice(0, 7)}.local`,);
    });

    this.log("Waiting for device to be reachable");
    await this.context.get().utils.waitUntil(async() => {
      console.log(`checking device is online in the dashboard....`)

      let isOnline =  await this.context
        .get()
        .cloud.balena.models.device.isOnline(this.context.get().balena.uuid);

      console.log(isOnline);
      return isOnline === true
    });

    this.log("Device is online and provisioned successfully");
    await this.context.get().utils.waitUntil(async () => {
      this.log("Trying to ssh into device");
      let hostname = await this.context
      .get()
      .cloud.executeCommandInHostOS(
        "cat /etc/hostname",
        this.context.get().balena.uuid
      )
      return hostname === this.context.get().balena.uuid.slice(0, 7)
    }, false);

    this.log("Unpinning");
    await this.context.get().utils.waitUntil(async () => {
      this.log(`Unpinning device from release`)
      await this.context
      .get()
      .cloud.balena.models.device.trackApplicationRelease(
        this.context.get().balena.uuid
      );

      let unpinned = await this.context
      .get()
      .cloud.balena.models.device.isTrackingApplicationRelease(this.context.get().balena.uuid)

      return unpinned
    }, false);

    // wait until the service is running before continuing
    await this.context.get().cloud.waitUntilServicesRunning(
      this.context.get().balena.uuid,
      [`main`],
      this.context.get().balena.initialCommit
    )
  },
  tests: [
    "./tests/preload",
    "./tests/supervisor",
    "./tests/multicontainer",
  ],
};
<|endoftext|>


<commit_before>var debug = require("debug")("litesocket");

exports = module.exports = function(req, res, next){
	debug("connection opened");
	res.writeHead(200, exports.headers(req));
	["sendRetry","sendComment","sendData"].forEach(function(name){
		var fn = exports[name];
		res[name] = function(val){
			fn(res, val);
		};
	});
	res.send = function(data, options){
		exports.send(res, data, options);
	};

	//send something or the browser gets mad!
	res.sendComment(exports.welcome);

	//very important to remove it from the pool and kill off the default 2 minute timeout
	req.socket.setTimeout(0);
	req.socket.emit("agentRemove");
	req.on('close', function(){
		debug("connection closed");
	});

	next();
};

exports.welcome = "You are connected";
exports.headers = function(res){
	return {
		"Access-Control-Allow-Origin": "*",
		"Content-Type":"text/event-stream",
		"Cache-Control":"no-cache",
		"Connection":"keep-alive"
	};
}
exports.sendId = function(stream, id){
	debug("id: ", id);
	stream.write("id:");
	stream.write(String(id));
	stream.write('\n');
};
exports.sendEvent = function(stream, name){
	debug("event:", name);
	stream.write("event:");
	stream.write(String(name));
	stream.write('\n');
};
exports.sendRetry = function(stream, ms){
	debug("retry:", ms);
	stream.write("retry:");
	stream.write(String(ms));
	stream.write('\n');
};
exports.sendComment = function(stream, comment){
	debug(":", comment);
	stream.write(":");
	stream.write(String(comment).replace(/\n(?=.)/g, '\n:'));
	stream.write('\n');
};
exports.sendData = function(stream, data){
	data = String(data).replace(/\n(?=.)/g, '\ndata: ');
	stream.write("data:");
	debug(data);
	stream.write(data);
	if(/\n\r?\n\r?$/.test(data))//the data already has the terminating \n\n at the end
		return;
	stream.write(/\n\r?$/.test(data)? '\n':'\n\n');
};
exports.send = function(stream, data, options){
	if(options){
		if(options.comment){
			exports.sendComment(stream, options.comment);
		}
		if(options.retry){
			exports.sendRetry(stream, options.retry);
		}
		if(options.id){
			exports.sendId(stream, options.id);
		}
		if(options.event){
			exports.sendEvent(stream, options.event);
		}
	}
	if(data)
		exports.sendData(stream, data);
};
exports.handler = function sseHandler(url, callback){
	this.get(url, exports, callback);
};
<commit_msg>rename exports<commit_after>var debug = require("debug")("litesocket");

litesocket = module.exports = function(req, res, next){
	debug("connection opened");
	res.writeHead(200, litesocket.headers(req));
	["sendRetry","sendComment","sendData"].forEach(function(name){
		var fn = litesocket[name];
		res[name] = function(val){
			fn(res, val);
		};
	});
	res.send = function(data, options){
		litesocket.send(res, data, options);
	};

	//send something or the browser gets mad!
	res.sendComment(litesocket.welcome);

	//very important to remove it from the pool and kill off the default 2 minute timeout
	req.socket.setTimeout(0);
	req.socket.emit("agentRemove");
	req.on('close', function(){
		debug("connection closed");
	});

	next();
};
litesocket.handler = function(url, callback){
	this.get(url, litesocket, callback);
};

litesocket.welcome = "You are connected";
litesocket.headers = function(res){
	return {
		"Access-Control-Allow-Origin": "*",
		"Content-Type":"text/event-stream",
		"Cache-Control":"no-cache",
		"Connection":"keep-alive"
	};
}
litesocket.sendId = function(stream, id){
	debug("id: ", id);
	stream.write("id:");
	stream.write(String(id));
	stream.write('\n');
};
litesocket.sendEvent = function(stream, name){
	debug("event:", name);
	stream.write("event:");
	stream.write(String(name));
	stream.write('\n');
};
litesocket.sendRetry = function(stream, ms){
	debug("retry:", ms);
	stream.write("retry:");
	stream.write(String(ms));
	stream.write('\n');
};
litesocket.sendComment = function(stream, comment){
	debug(":", comment);
	stream.write(":");
	stream.write(String(comment).replace(/\n(?=.)/g, '\n:'));
	stream.write('\n');
};
litesocket.sendData = function(stream, data){
	data = String(data).replace(/\n(?=.)/g, '\ndata: ');
	stream.write("data:");
	debug(data);
	stream.write(data);
	if(/\n\r?\n\r?$/.test(data))//the data already has the terminating \n\n at the end
		return;
	stream.write(/\n\r?$/.test(data)? '\n':'\n\n');
};
litesocket.send = function(stream, data, options){
	if(options){
		if(options.comment){
			litesocket.sendComment(stream, options.comment);
		}
		if(options.retry){
			litesocket.sendRetry(stream, options.retry);
		}
		if(options.id){
			litesocket.sendId(stream, options.id);
		}
		if(options.event){
			litesocket.sendEvent(stream, options.event);
		}
	}
	if(data)
		litesocket.sendData(stream, data);
};
<|endoftext|>