<commit_before>
// requires assertions

if( JSHC.Test === undefined ) JSHC.Test = {};
if( JSHC.Test.Cases === undefined) JSHC.Test.Cases = {};

////////////////////////////////////////////////////////////////////////////////

/*
  can be created with:
  (name, action)
  (name, action, obj) where 'obj' contains extra properties to copy
  (obj) where 'obj' contains properties to copy (including name and action)
*/
JSHC.Test.TestCase = function(p1, p2, p3){
    var k;

    if( typeof p1 === "string" && p2 instanceof Function ){
	this.name = p1;
	this.action = p2;
	for(k in p3){
	    if( k === "name" || k === "action" ){
		throw new Error("invalid parameters");
	    }
	    this[k] = p1[k];
	}
    } else if( p1 !== undefined &&
	       typeof p1.name === "string" &&
	       p1.action instanceof Function ) {
	for(k in p1){
	    this[k] = p1[k];
	}
    } else {
	throw new Error("invalid parameters");
    }
};

JSHC.Test.TestCase.prototype.result = function(ok, info){
    assert.ok( typeof ok === "boolean" && arguments.length <= 2 );
    return new JSHC.Test.TestResult(this, ok, info);
};

////////////////////////////////////////////////////////////////////////////////

JSHC.Test.TestResult = function(id, ok, info){
    assert.ok( typeof ok == "boolean" );
    if( typeof id == "string" ){
        this.name = id;
    } else if( id instanceof JSHC.Test.TestCase ){
        this.tc = id;
    }
    this.ok = ok;
    if( info !== undefined ){
        assert.ok( typeof info == "string", "test result \""+this.getName()+"\" has a non-string as info");
	this.info = info;
    }
};

JSHC.Test.TestResult.prototype.getName = function(){
    return this.name !== undefined ? this.name : this.tc.name;
};

////////////////////////////////////////////////////////////////////////////////

JSHC.Test.Tester = function(){
    this.results = {};
    this.passed = 0;
    this.failed = 0;
    this.interpreter = new JSHC.Interpreter("JSHC.Test.modules");
    this.commandsExecuted = 0;
    this.cmdgroupsExecuted = 0;
};

/*
  Makes a depth-first traversal over the test cases, and runs them.
*/
JSHC.Test.Tester.prototype.run = function(tests){
    var t;

    // run the single test case
    if( tests instanceof JSHC.Test.TestCase ){
	this.runTC(tests);
    } else if( tests instanceof Function ){
        this.runFunction(tests);
    } else {
        // run all test cases in the object
        for(t in tests){
	    this.run(tests[t]);
        }
    }
};

JSHC.Test.Tester.prototype.addResult = function(result){
    assert.ok( result instanceof JSHC.Test.TestResult );
    var name = result.getName();
    if( this.results[name] !== undefined ){
        throw new Error("test names overlap. \""+name+"\" exists more than once.");
    }
    this.results[name] = result;
    if( result.ok ){
        this.passed++;
    } else {
        this.failed++;
    }
};

/*
  Runs a single test case.
*/
JSHC.Test.Tester.prototype.runFunction = function(fun){
    assert.ok( fun instanceof Function );

    //tester = this;
    //var resultHandler = function(result){
    //    tester.addResult(result);
    //};

    fun(this);
};

/*
  Runs a single test case.
*/
JSHC.Test.Tester.prototype.runTC = function(tc){
    assert.ok( tc instanceof JSHC.Test.TestCase );
    this.addResult(tc.action());
};

/*
  Shows test results.
*/
JSHC.Test.Tester.prototype.toString = function(tc){
    var rn,msg = [];
    msg.push("tests passed:" + this.passed + "\n");
    msg.push("executed " + this.commandsExecuted + " commands in " +
             this.cmdgroupsExecuted + " tests\n");
    msg.push("tests failed:" + this.failed + "\n");
    msg.push("\n");
    for(rn in this.results){
	var r = this.results[rn];
	assert.ok( r instanceof JSHC.Test.TestResult );

	// ignore passed tests
	if( r.ok )continue;

	// show failed tests
	msg.push("name: "+r.name+"\n");
	if( r.info === undefined || r.info.length == 0 ){
	    msg.push("(no information)");
	} else {
            msg.push(r.info);
	}
	msg.push("\n\n");
    }
    return msg.join("");
};

/*
  Shows test results.
*/
JSHC.Test.Tester.prototype.toHTML = function(tc){
    var rn,msg = [];
    msg.push("
tests passed:" + this.passed + "
");
    msg.push("executed " + this.commandsExecuted + " commands in " +
             this.cmdgroupsExecuted + " tests
");
    msg.push("tests failed:" + this.failed + "
");
    msg.push("

");
    for(rn in this.results){
	var r = this.results[rn];
	assert.ok( r instanceof JSHC.Test.TestResult );

	// ignore passed tests
	if( r.ok )continue;

	// show failed tests
	msg.push("name: "+r.getName()+"
");
	if( r.info === undefined || r.info.length == 0 ){
	    msg.push("(no information)");
	} else {
            // TODO: should somehow convert to HTML ?
            msg.push(r.info.replace(/\n/g,"
"));
	}
	msg.push("
");
    }
    return msg.join("");
};

////////////////////////////////////////////////////////////////////////////////

/*
  Runs the given tests and returns a string describing the results.
*/
JSHC.Test.runtests = function(tests, showHTML){
    var tester = new JSHC.Test.Tester();
    tester.run(tests);
    return showHTML ? tester.toHTML() : tester.toString();
};

////////////////////////////////////////////////////////////////////////////////

/*
  run test tests using test data
*/
JSHC.Test.runData = function(tester,td){
    assert.ok( td.fileSystem !== undefined );

    tester.interpreter.resetStatus();

    // set file system
    tester.interpreter.compiler.setFileSystem(td.fileSystem);

    // set targets
    if( td.targets === undefined ){
       var targets = [];
       for(var modname in td.fileSystem){
          targets.push(modname);
       }
    } else {
       targets = td.targets;
    }
    tester.interpreter.compiler.setTargets(targets);

    // compile
    tester.interpreter.compiler.recompile();

    var errorAmount;
    if( td.errors === undefined ){
        errorAmount = 0;
    } else {
        errorAmount = td.errors;
    }

    var info = [];
    if( tester.interpreter.errors !== errorAmount ){
        for(var i=0 ; i<tester.interpreter.errorList.length ; i++){
            var err = tester.interpreter.errorList[i];
            if( typeof err !== "string" ){
                err = JSHC.showError(err);
            }
            info.push(err);
        }
    }

    var success = tester.interpreter.errors === errorAmount;

    var commands = td.commands;
    var has_commands = false;
    for(var command in commands){
        tester.commandsExecuted++;
        has_commands = true;
        tester.interpreter.execCommand(command);

        if( commands[command] === null ){
            // supposed to result in an error
            if( tester.interpreter.errors === 0 ){
                success = false;
                info.push(tester.interpreter.errorList.join("\n"));
                info.push(tester.interpreter.warningList.join("\n"));
                continue;
            } else {
                // success: got an error
                continue;
            }
        } else {
            if( tester.interpreter.errors > 0 ){
                success = false;
                info.push(tester.interpreter.errorList.join("\n"));
                info.push(tester.interpreter.warningList.join("\n"));
                continue;
            }
            if ( tester.interpreter.messageList.length === 0 ) {
                success = false;
                info.push("got no result when executing\""+command+"\"");
                info.push(tester.interpreter.messageList.join("\n"));
                continue;
            }
            if( tester.interpreter.messageList.length !== 1 ){
                success = false;
                info.push("got more than one result when executing \""+command+"\":");
                info.push(tester.interpreter.messageList.join("\n"));
                continue;
            }
            if( tester.interpreter.messageList[0] !== commands[command] ){
                success = false;
                info.push("got result \""+tester.interpreter.messageList[0]+"\""+
                          " instead of \""+commands[command]+"\" when executing "+
                          "\""+command+"\"");
                continue;
            }
        }
    }
    if( has_commands ){
        tester.cmdgroupsExecuted++;
    }

    tester.addResult(new JSHC.Test.TestResult(
        td.name,
        success,
        info.length==0 ? undefined : info.join("\n")));
};

////////////////////////////////////////////////////////////////////////////////
<commit_msg>testing: print command when exception occurs<commit_after>
// requires assertions

if( JSHC.Test === undefined ) JSHC.Test = {};
if( JSHC.Test.Cases === undefined) JSHC.Test.Cases = {};

////////////////////////////////////////////////////////////////////////////////

/*
  can be created with:
  (name, action)
  (name, action, obj) where 'obj' contains extra properties to copy
  (obj) where 'obj' contains properties to copy (including name and action)
*/
JSHC.Test.TestCase = function(p1, p2, p3){
    var k;

    if( typeof p1 === "string" && p2 instanceof Function ){
	this.name = p1;
	this.action = p2;
	for(k in p3){
	    if( k === "name" || k === "action" ){
		throw new Error("invalid parameters");
	    }
	    this[k] = p1[k];
	}
    } else if( p1 !== undefined &&
	       typeof p1.name === "string" &&
	       p1.action instanceof Function ) {
	for(k in p1){
	    this[k] = p1[k];
	}
    } else {
	throw new Error("invalid parameters");
    }
};

JSHC.Test.TestCase.prototype.result = function(ok, info){
    assert.ok( typeof ok === "boolean" && arguments.length <= 2 );
    return new JSHC.Test.TestResult(this, ok, info);
};

////////////////////////////////////////////////////////////////////////////////

JSHC.Test.TestResult = function(id, ok, info){
    assert.ok( typeof ok == "boolean" );
    if( typeof id == "string" ){
        this.name = id;
    } else if( id instanceof JSHC.Test.TestCase ){
        this.tc = id;
    }
    this.ok = ok;
    if( info !== undefined ){
        assert.ok( typeof info == "string", "test result \""+this.getName()+"\" has a non-string as info");
	this.info = info;
    }
};

JSHC.Test.TestResult.prototype.getName = function(){
    return this.name !== undefined ? this.name : this.tc.name;
};

////////////////////////////////////////////////////////////////////////////////

JSHC.Test.Tester = function(){
    this.results = {};
    this.passed = 0;
    this.failed = 0;
    this.interpreter = new JSHC.Interpreter("JSHC.Test.modules");
    this.commandsExecuted = 0;
    this.cmdgroupsExecuted = 0;
};

/*
  Makes a depth-first traversal over the test cases, and runs them.
*/
JSHC.Test.Tester.prototype.run = function(tests){
    var t;

    // run the single test case
    if( tests instanceof JSHC.Test.TestCase ){
	this.runTC(tests);
    } else if( tests instanceof Function ){
        this.runFunction(tests);
    } else {
        // run all test cases in the object
        for(t in tests){
	    this.run(tests[t]);
        }
    }
};

JSHC.Test.Tester.prototype.addResult = function(result){
    assert.ok( result instanceof JSHC.Test.TestResult );
    var name = result.getName();
    if( this.results[name] !== undefined ){
        throw new Error("test names overlap. \""+name+"\" exists more than once.");
    }
    this.results[name] = result;
    if( result.ok ){
        this.passed++;
    } else {
        this.failed++;
    }
};

/*
  Runs a single test case.
*/
JSHC.Test.Tester.prototype.runFunction = function(fun){
    assert.ok( fun instanceof Function );

    //tester = this;
    //var resultHandler = function(result){
    //    tester.addResult(result);
    //};

    fun(this);
};

/*
  Runs a single test case.
*/
JSHC.Test.Tester.prototype.runTC = function(tc){
    assert.ok( tc instanceof JSHC.Test.TestCase );
    this.addResult(tc.action());
};

/*
  Shows test results.
*/
JSHC.Test.Tester.prototype.toString = function(tc){
    var rn,msg = [];
    msg.push("tests passed:" + this.passed + "\n");
    msg.push("executed " + this.commandsExecuted + " commands in " +
             this.cmdgroupsExecuted + " tests\n");
    msg.push("tests failed:" + this.failed + "\n");
    msg.push("\n");
    for(rn in this.results){
	var r = this.results[rn];
	assert.ok( r instanceof JSHC.Test.TestResult );

	// ignore passed tests
	if( r.ok )continue;

	// show failed tests
	msg.push("name: "+r.name+"\n");
	if( r.info === undefined || r.info.length == 0 ){
	    msg.push("(no information)");
	} else {
            msg.push(r.info);
	}
	msg.push("\n\n");
    }
    return msg.join("");
};

/*
  Shows test results.
*/
JSHC.Test.Tester.prototype.toHTML = function(tc){
    var rn,msg = [];
    msg.push("
tests passed:" + this.passed + "
");
    msg.push("executed " + this.commandsExecuted + " commands in " +
             this.cmdgroupsExecuted + " tests
");
    msg.push("tests failed:" + this.failed + "
");
    msg.push("

");
    for(rn in this.results){
	var r = this.results[rn];
	assert.ok( r instanceof JSHC.Test.TestResult );

	// ignore passed tests
	if( r.ok )continue;

	// show failed tests
	msg.push("name: "+r.getName()+"
");
	if( r.info === undefined || r.info.length == 0 ){
	    msg.push("(no information)");
	} else {
            // TODO: should somehow convert to HTML ?
            msg.push(r.info.replace(/\n/g,"
"));
	}
	msg.push("
");
    }
    return msg.join("");
};

////////////////////////////////////////////////////////////////////////////////

/*
  Runs the given tests and returns a string describing the results.
*/
JSHC.Test.runtests = function(tests, showHTML){
    var tester = new JSHC.Test.Tester();
    tester.run(tests);
    return showHTML ? tester.toHTML() : tester.toString();
};

////////////////////////////////////////////////////////////////////////////////

/*
  run test tests using test data
*/
JSHC.Test.runData = function(tester,td){
    assert.ok( td.fileSystem !== undefined );

    tester.interpreter.resetStatus();

    // set file system
    tester.interpreter.compiler.setFileSystem(td.fileSystem);

    // set targets
    if( td.targets === undefined ){
       var targets = [];
       for(var modname in td.fileSystem){
          targets.push(modname);
       }
    } else {
       targets = td.targets;
    }
    tester.interpreter.compiler.setTargets(targets);

    // compile
    tester.interpreter.compiler.recompile();

    var errorAmount;
    if( td.errors === undefined ){
        errorAmount = 0;
    } else {
        errorAmount = td.errors;
    }

    var info = [];
    if( tester.interpreter.errors !== errorAmount ){
        for(var i=0 ; i<tester.interpreter.errorList.length ; i++){
            var err = tester.interpreter.errorList[i];
            if( typeof err !== "string" ){
                err = JSHC.showError(err);
            }
            info.push(err);
        }
    }

    var success = tester.interpreter.errors === errorAmount;

    var commands = td.commands;
    var has_commands = false;
    for(var command in commands){
        tester.commandsExecuted++;
        has_commands = true;
        tester.interpreter.execCommand(command);

        if( commands[command] === null ){
            // supposed to result in an error
            if( tester.interpreter.errors === 0 ){
                success = false;
                info.push(tester.interpreter.errorList.join("\n"));
                info.push(tester.interpreter.warningList.join("\n"));
                continue;
            } else {
                // success: got an error
                continue;
            }
        } else {
            if( tester.interpreter.errors > 0 ){
                success = false;
                info.push("got:");
                info.push(tester.interpreter.errorList.join("\n"));
                info.push(tester.interpreter.warningList.join("\n"));
                info.push("when executing\""+command+"\"");
                continue;
            }
            if ( tester.interpreter.messageList.length === 0 ) {
                success = false;
                info.push("got no result when executing\""+command+"\"");
                info.push(tester.interpreter.messageList.join("\n"));
                continue;
            }
            if( tester.interpreter.messageList.length !== 1 ){
                success = false;
                info.push("got more than one result when executing \""+command+"\":");
                info.push(tester.interpreter.messageList.join("\n"));
                continue;
            }
            if( tester.interpreter.messageList[0] !== commands[command] ){
                success = false;
                info.push("got result \""+tester.interpreter.messageList[0]+"\""+
                          " instead of \""+commands[command]+"\" when executing "+
                          "\""+command+"\"");
                continue;
            }
        }
    }
    if( has_commands ){
        tester.cmdgroupsExecuted++;
    }

    tester.addResult(new JSHC.Test.TestResult(
        td.name,
        success,
        info.length==0 ? undefined : info.join("\n")));
};

////////////////////////////////////////////////////////////////////////////////
<|endoftext|>


<commit_before>/**
 * Chiffon
 *
 * @description  A very small ECMAScript parser, tokenizer and minify written in JavaScript
 * @fileoverview JavaScript parser, tokenizer and minify library
 * @version      1.3.2
 * @date         2015-10-17
 * @link         https://github.com/polygonplanet/Chiffon
 * @copyright    Copyright (c) 2015 polygon planet <polygon.planet.aqua@gmail.com>
 * @license      Licensed under the MIT license.
 */

/*jshint bitwise:false, eqnull:true */
(function(name, context, factory) {

  // Supports AMD, Node.js, CommonJS and browser context.
  if (typeof exports !== 'undefined') {
    if (typeof module !== 'undefined' && module.exports) {
      module.exports = factory();
    } else {
      exports[name] = factory();
    }
  } else if (typeof define === 'function' && define.amd) {
    define(factory);
  } else {
    context[name] = factory();
  }

}('Chiffon', this, function() {
  'use strict';

  var Chiffon = {};

  var DEFAULT_MAXLINELEN = 32000;

  var _Comment = 'Comment',
      _LineTerminator = 'LineTerminator',
      _Template = 'Template',
      _String = 'String',
      _Punctuator = 'Punctuator',
      _RegularExpression = 'RegularExpression',
      _Numeric = 'Numeric',
      _UnicodeEscapeSequence = 'UnicodeEscapeSequence',
      _Identifier = 'Identifier',
      _Null = 'Null',
      _Boolean = 'Boolean',
      _Keyword = 'Keyword';

  var capturedToken = [
    '',
    _Comment,
    _Comment,
    _LineTerminator,
    _Comment,
    _Template,
    _String,
    _RegularExpression,
    _Numeric,
    _Punctuator,
    _UnicodeEscapeSequence,
    _LineTerminator,
    _Identifier
  ];
  var capturedTokenLen = capturedToken.length;

  // ECMA-262 11.3 Line Terminators
  var lineTerminator = '\\r\\n\\u2028\\u2029';
  var lineTerminatorSequence = '(?:\\r\\n|[' + lineTerminator + '])';
  var whiteSpace = '(?:(?![' + lineTerminator + '])\\s)+';

  var literalSuffix = '(?=' +
    '\\s*' +
    '(?:' + '(?!\\s*[/\\\\<>*+%`^"\'\\w$-])' +
            '[^/\\\\<>*+%`^\'"({[\\w$-]' +
      '|' + '[!=]==?' +
      '|' + '[|][|]' +
      '|' + '&&' +
      '|' + '/[*/]' +
      '|' + '[,.;:!?)}\\]' + lineTerminator + ']' +
      '|' + '$' +
    ')' +
  ')';

  // ECMA-262 11.7 Punctuators
  var punctuators = '(?:' +
          '>>>=?|[.]{3}|<<=|===|!==|>>=' +
    '|' + '[+][+](?=[+])|--(?=-)' +
    '|' + '[=!<>*%+/&|^-]=' +
    '|' + '&&|[|][|]|[+][+]|--|<<|>>|=>' +
    '|' + '[-+*/%<>=&|^~!?:;,.()[\\]{}]' +
  ')';

  var regexpLiteral = '(?:' +
    '/(?![*])(?:\\\\.|[^/' + lineTerminator + '\\\\])+/' +
    '(?:[gimuy]{0,5}|\\b)' +
  ')';

  var identToken = '[^\\s+/%*=&|^~<>!?:;,.()[\\]{}\'"`-]';

  // Valid keywords for Regular Expression Literal. e.g. `typeof /a/`
  var regexPreWords = 'typeof|in|void|case|instanceof|yield|throw|delete';
  // Valid keywords when previous token of the regex literal is a paren.
  // e.g. `if (1) /a/`
  var regexParenWords = 'if|while|for|with';

  var keywordsRe = new RegExp('^(?:' +
    // ECMA-262 11.6.2.1 Keywords
    regexParenWords + '|' + regexPreWords + '|' +
    'var|else|function|this|return|new|break|do|' +
    'catch|finally|try|default|continue|switch|' +
    'const|export|import|class|extends|debugger|super|' +
    // Reserved keywords
    'let|static|' +
    // ECMA-262 11.6.2.2 Future Reserved Words
    'enum|await|' +
    'implements|package|protected|interface|private|public' +
  ')$');

  var identRe = new RegExp(identToken);
  var signRe = /[+-]/;

  var regexPrefixRe = new RegExp('(?:' +
          '(?:^(?:' + regexPreWords + ')$)' +
    '|' + '(?:' + '(?![.\\]])' + punctuators + '$)' +
  ')');
  var regexParenWordsRe = new RegExp('^(?:' + regexParenWords + ')$');

  var tokenizeRe = getPattern();
  var tokenizeAllRe = getPattern(true);

  function getPattern(all) {
    return new RegExp(
      '(?:' +
            // (1) multiline comment
            '(' + '/[*][\\s\\S]*?[*]/' + ')' +
            // (2) single line comment
      '|' + '(' + '//[^' + lineTerminator + ']*' +
            '|' + '<!--[^' + lineTerminator + ']*' +
            ')' +
            // (3) line terminators
      '|' + '(?:^|(' + lineTerminatorSequence + '))' +
            '(?:' + whiteSpace + '|)' +
            // (4) single line comment
            '(' + '-->[^' + lineTerminator + ']*' +
            ')' +
            // (5) template literal
      '|' + '(' + '`(?:\\\\[\\s\\S]|[^`\\\\])*`' +
            ')' + literalSuffix +
            // (6) string literal
      '|' + '(' + '"(?:\\\\[\\s\\S]|[^"' + lineTerminator + '\\\\])*"' +
            '|' + "'(?:\\\\[\\s\\S]|[^'" + lineTerminator + "\\\\])*'" +
            ')' +
            // (7) regular expression literal
      '|' + '(' + (all ? regexpLiteral : whiteSpace) +
            ')' + literalSuffix +
            // (8) numeric literal
      '|' + '(' + '0(?:' + '[xX][0-9a-fA-F]+' +
                     '|' + '[oO][0-7]+' +
                     '|' + '[bB][01]+' +
                     ')' +
            '|' + '(?:\\d+(?:[.]\\d*)?|[.]\\d+)(?:[eE][+-]?\\d+)?' +
            '|' + '[1-9]\\d*' +
            '|' + '0[0-7]+' +
            ')' +
            // (9) operators
      '|' + '(' + punctuators +
            ')' +
            // (10) unicode character
      '|' + '(' + '\\\\u[0-9a-fA-F]{4}' +
            ')' +
      '|' + whiteSpace +
            // (11) line terminators
      '|' + '(' + lineTerminatorSequence + ')' +
            // (12) identifier
      '|' + '(' + identToken + '+' +
            ')' +
      ')',
      'g'
    );
  }

  var _regexParsing;
  var _options;

  function parseMatches(match, tokens) {
    for (var i = 1; i < capturedTokenLen; i++) {
      var value = match[i];
      if (!value) {
        continue;
      }

      var regex;
      var type = capturedToken[i];
      if (type === _Comment) {
        if (!_options.comment) {
          break;
        }
      } else if (type === _LineTerminator) {
        if (!_options.lineTerminator) {
          continue;
        }
      } else if (type === _Identifier) {
        if (value === 'null') {
          type = _Null;
        } else if (value === 'true' || value === 'false') {
          type = _Boolean;
        } else if (keywordsRe.test(value)) {
          type = _Keyword;
        }
      } else if (type === _RegularExpression) {
        if (_regexParsing) {
          break;
        }
        regex = parseRegExpFlags(value);
      }

      var token = {
        type: type,
        value: value
      };

      if (regex) {
        token.regex = regex;
      }

      if (_options.range) {
        var lastIndex = _regexParsing ? tokenizeRe.lastIndex : tokenizeAllRe.lastIndex;
        token.range = [
          lastIndex - value.length,
          lastIndex
        ];
      }

      tokens[tokens.length] = token;

      if (value === match[0]) {
        break;
      }
    }
  }

  // Fix Regular Expression missing matches e.g. `var g=1,a=2/3/g;`
  function fixRegExpTokens(tokens) {
    for (var i = 0; i < tokens.length; i++) {
      if (tokens[i].type !== _RegularExpression) {
        continue;
      }

      var index = i;
      var regexToken = tokens[i];

      while (--index >= 0) {
        var token = tokens[index];
        var type = token.type;

        if (type === _Comment || type === _LineTerminator) {
          continue;
        }

        var value = token.value;
        if (type === _Punctuator) {
          if (value === ')') {
            if (isValidRegExpPrefix(tokens, index + 1)) {
              break;
            }
          } else if (regexPrefixRe.test(value)) {
            break;
          }
        } else if (type === _Keyword && regexPrefixRe.test(value)) {
          break;
        }

        var parts = parseRegExp(regexToken);
        Array.prototype.splice.apply(tokens, [i, 1].concat(parts));
        break;
      }
    }
  }

  function isValidRegExpPrefix(tokens, i) {
    var level = 0;

    while (--i >= 0) {
      var token = tokens[i];
      var type = token.type;
      if (type !== _Punctuator) {
        continue;
      }

      var value = token.value;
      if (value === '(') {
        if (--level === 0) {
          var prevToken = tokens[i - 1];
          if (prevToken && prevToken.type === _Keyword &&
              regexParenWordsRe.test(prevToken.value)) {
            return true;
          }
          return false;
        }
      } else if (value === ')') {
        level++;
      }
    }

    return false;
  }

  function parseRegExpFlags(value) {
    var index = value.lastIndexOf('/');
    var flags = value.substring(index + 1);
    var pattern = value.substr(1, index - 1);

    return {
      pattern: pattern,
      flags: flags
    };
  }

  function parseRegExp(regexToken) {
    var value = regexToken.value;
    var tokens = [];
    var m;

    _regexParsing = true;
    tokenizeRe.lastIndex = 0;
    while ((m = tokenizeRe.exec(value)) != null) {
      parseMatches(m, tokens);
    }

    if (_options.range) {
      var index = regexToken.range[0];
      for (var i = 0, len = tokens.length; i < len; i++) {
        var range = tokens[i].range;
        range[0] += index;
        range[1] += index;
      }
    }

    _regexParsing = false;
    return tokens;
  }

  function tokenize(code, options) {
    _options = options || {};

    var tokens = [];
    var m;

    _regexParsing = false;
    tokenizeAllRe.lastIndex = 0;
    while ((m = tokenizeAllRe.exec(code)) != null) {
      parseMatches(m, tokens);
    }

    fixRegExpTokens(tokens);
    _options = null;
    return tokens;
  }

  /**
   * Tokenize a string code.
   *
   * @param {string} code Target code.
   * @param {Object} [options] Tokenize options.
   *   - comment: {boolean} (default=false)
   *     Keep comment tokens.
   *   - lineTerminator: {boolean} (default=false)
   *     Keep line feed tokens.
   *   - range: {boolean} (default=false)
   *     Includes an index-based location range (array)
   * @return {string} Return an array of the parsed tokens.
   */
  Chiffon.tokenize = tokenize;

  function untokenize(tokens, options) {
    options = options || {};

    var results = [];
    var maxLineLen = options.maxLineLen || DEFAULT_MAXLINELEN;
    var lineLen = 0;
    var prev;

    for (var i = 0, len = tokens.length; i < len; prev = tokens[i++]) {
      var token = tokens[i];
      var next = tokens[i + 1];

      if (!prev) {
        if (token.type !== _LineTerminator) {
          results[results.length] = token.value;
        }
        continue;
      }

      var ws = '';
      if (token.type === _LineTerminator) {
        if (prev.type === _LineTerminator) {
          continue;
        }
        if (prev.type === _Punctuator || (next && next.type === _Punctuator)) {
          token.value = '';
        } else {
          lineLen = 0;
        }
      } else {
        if ((signRe.test(token.value.slice(-1)) && signRe.test(prev.value.charAt(0))) ||
            (identRe.test(prev.value.slice(-1)) && identRe.test(token.value.charAt(0)))) {
          ws = ' ';
        }

        if (token.type === _Punctuator && lineLen > maxLineLen) {
          token.value += '\n';
          lineLen = 0;
        }
      }

      var value = ws + token.value;
      lineLen += value.length;
      results[results.length] = value;
    }

    return results.join('');
  }

  /**
   * Concatenate to string from the parsed tokens.
   *
   * @param {Array} tokens An array of the parsed tokens.
   * @return {string} Return a concatenated string.
   */
  Chiffon.untokenize = untokenize;

  function minify(code, options) {
    return untokenize(tokenize(code, { lineTerminator: true }), options);
  }

  /**
   * Minify JavaScript code.
   *
   * @param {string} code Target code.
   * @param {Object} [options] minify options.
   *   - maxLineLen: {number} (default=32000)
   *     Limit the line length in symbols.
   * @return {string} Return a minified code.
   */
  Chiffon.minify = minify;

  return Chiffon;
}));
<commit_msg>Improve regex and variables<commit_after>/**
 * Chiffon
 *
 * @description  A very small ECMAScript parser, tokenizer and minify written in JavaScript
 * @fileoverview JavaScript parser, tokenizer and minify library
 * @version      1.3.2
 * @date         2015-10-17
 * @link         https://github.com/polygonplanet/Chiffon
 * @copyright    Copyright (c) 2015 polygon planet <polygon.planet.aqua@gmail.com>
 * @license      Licensed under the MIT license.
 */

/*jshint bitwise:false, eqnull:true */
(function(name, context, factory) {

  // Supports AMD, Node.js, CommonJS and browser context.
  if (typeof exports !== 'undefined') {
    if (typeof module !== 'undefined' && module.exports) {
      module.exports = factory();
    } else {
      exports[name] = factory();
    }
  } else if (typeof define === 'function' && define.amd) {
    define(factory);
  } else {
    context[name] = factory();
  }

}('Chiffon', this, function() {
  'use strict';

  var Chiffon = {};

  var DEFAULT_MAXLINELEN = 32000;

  var _Comment = 'Comment',
      _LineTerminator = 'LineTerminator',
      _Template = 'Template',
      _String = 'String',
      _Punctuator = 'Punctuator',
      _RegularExpression = 'RegularExpression',
      _Numeric = 'Numeric',
      _UnicodeEscapeSequence = 'UnicodeEscapeSequence',
      _Identifier = 'Identifier',
      _Null = 'Null',
      _Boolean = 'Boolean',
      _Keyword = 'Keyword';

  var capturedToken = [
    '',
    _Comment,
    _Comment,
    _LineTerminator,
    _Comment,
    _Template,
    _String,
    _RegularExpression,
    _Numeric,
    _Punctuator,
    _UnicodeEscapeSequence,
    _LineTerminator,
    _Identifier
  ];
  var capturedTokenLen = capturedToken.length;

  // ECMA-262 11.3 Line Terminators
  var lineTerminator = '\\r\\n\\u2028\\u2029';
  var lineTerminatorSequence = '(?:\\r\\n|[' + lineTerminator + '])';
  var whiteSpace = '(?:(?![' + lineTerminator + '])\\s)+';

  var literalSuffix = '(?=' +
    '\\s*' +
    '(?:' + '(?!\\s*[/\\\\<>*+%`^"\'\\w$-])' +
            '[^/\\\\<>*+%`^\'"({[\\w$-]' +
      '|' + '[!=]==?' +
      '|' + '[|][|]' +
      '|' + '&&' +
      '|' + '/[*/]' +
      '|' + '[,.;:!?)}\\]' + lineTerminator + ']' +
      '|' + '$' +
    ')' +
  ')';

  // ECMA-262 11.7 Punctuators
  var punctuators = '(?:' +
          '>>>=?|[.]{3}|<<=|===|!==|>>=' +
    '|' + '[+][+](?=[+])|--(?=-)' +
    '|' + '[=!<>*%+/&|^-]=' +
    '|' + '&&|[|][|]|[+][+]|--|<<|>>|=>' +
    '|' + '[-+*/%<>=&|^~!?:;,.()[\\]{}]' +
  ')';

  var regexpLiteral = '(?:' +
    '/(?![*])(?:\\\\.|[^/' + lineTerminator + '\\\\])+/' +
    '(?:[gimuy]{0,5}|\\b)' +
  ')';

  var identToken = '[^\\s+/%*=&|^~<>!?:;,.()[\\]{}\'"`-]';

  // Valid keywords for Regular Expression Literal. e.g. `typeof /a/`
  var regexPreWords = 'typeof|in|void|case|instanceof|yield|throw|delete';
  // Valid keywords when previous token of the regex literal is a paren.
  // e.g. `if (1) /a/`
  var regexParenWords = 'if|while|for|with';

  var keywordsRe = new RegExp('^(?:' +
    // ECMA-262 11.6.2.1 Keywords
    regexParenWords + '|' + regexPreWords + '|' +
    'var|else|function|this|return|new|break|do|' +
    'catch|finally|try|default|continue|switch|' +
    'const|export|import|class|extends|debugger|super|' +
    // Reserved keywords
    'let|static|' +
    // ECMA-262 11.6.2.2 Future Reserved Words
    'enum|await|' +
    'implements|package|protected|interface|private|public' +
  ')$');

  var identLeftRe = new RegExp('^' + identToken);
  var identRightRe = new RegExp(identToken + '$');
  var signLeftRe = /^[+-]/;
  var signRightRe = /[+-]$/;

  var regexPrefixRe = new RegExp('(?:' +
          '(?:^(?:' + regexPreWords + ')$)' +
    '|' + '(?:' + '(?![.\\]])' + punctuators + '$)' +
  ')');
  var regexParenWordsRe = new RegExp('^(?:' + regexParenWords + ')$');

  var tokenizeRe = getPattern();
  var tokenizeAllRe = getPattern(true);

  function getPattern(all) {
    return new RegExp(
      '(?:' +
            // (1) multiline comment
            '(' + '/[*][\\s\\S]*?[*]/' + ')' +
            // (2) single line comment
      '|' + '(' + '//[^' + lineTerminator + ']*' +
            '|' + '<!--[^' + lineTerminator + ']*' +
            ')' +
            // (3) line terminators
      '|' + '(?:^|(' + lineTerminatorSequence + '))' +
            '(?:' + whiteSpace + '|)' +
            // (4) single line comment
            '(' + '-->[^' + lineTerminator + ']*' +
            ')' +
            // (5) template literal
      '|' + '(' + '`(?:\\\\[\\s\\S]|[^`\\\\])*`' +
            ')' + literalSuffix +
            // (6) string literal
      '|' + '(' + '"(?:\\\\[\\s\\S]|[^"' + lineTerminator + '\\\\])*"' +
            '|' + "'(?:\\\\[\\s\\S]|[^'" + lineTerminator + "\\\\])*'" +
            ')' +
            // (7) regular expression literal
      '|' + '(' + (all ? regexpLiteral : whiteSpace) +
            ')' + literalSuffix +
            // (8) numeric literal
      '|' + '(' + '0(?:' + '[xX][0-9a-fA-F]+' +
                     '|' + '[oO][0-7]+' +
                     '|' + '[bB][01]+' +
                     ')' +
            '|' + '(?:\\d+(?:[.]\\d*)?|[.]\\d+)(?:[eE][+-]?\\d+)?' +
            '|' + '[1-9]\\d*' +
            '|' + '0[0-7]+' +
            ')' +
            // (9) operators
      '|' + '(' + punctuators +
            ')' +
            // (10) unicode character
      '|' + '(' + '\\\\u[0-9a-fA-F]{4}' +
            ')' +
      '|' + whiteSpace +
            // (11) line terminators
      '|' + '(' + lineTerminatorSequence + ')' +
            // (12) identifier
      '|' + '(' + identToken + '+' +
            ')' +
      ')',
      'g'
    );
  }

  var _regexParsing;
  var _options;

  function parseMatches(match, tokens) {
    for (var i = 1; i < capturedTokenLen; i++) {
      var value = match[i];
      if (!value) {
        continue;
      }

      var regex;
      var type = capturedToken[i];
      if (type === _Comment) {
        if (!_options.comment) {
          break;
        }
      } else if (type === _LineTerminator) {
        if (!_options.lineTerminator) {
          continue;
        }
      } else if (type === _Identifier) {
        if (value === 'null') {
          type = _Null;
        } else if (value === 'true' || value === 'false') {
          type = _Boolean;
        } else if (keywordsRe.test(value)) {
          type = _Keyword;
        }
      } else if (type === _RegularExpression) {
        if (_regexParsing) {
          break;
        }
        regex = parseRegExpFlags(value);
      }

      var token = {
        type: type,
        value: value
      };

      if (regex) {
        token.regex = regex;
      }

      if (_options.range) {
        var lastIndex = _regexParsing ? tokenizeRe.lastIndex : tokenizeAllRe.lastIndex;
        token.range = [
          lastIndex - value.length,
          lastIndex
        ];
      }

      tokens[tokens.length] = token;

      if (value === match[0]) {
        break;
      }
    }
  }

  // Fix Regular Expression missing matches e.g. `var g=1,a=2/3/g;`
  function fixRegExpTokens(tokens) {
    for (var i = 0; i < tokens.length; i++) {
      if (tokens[i].type !== _RegularExpression) {
        continue;
      }

      var index = i;
      var regexToken = tokens[i];

      while (--index >= 0) {
        var token = tokens[index];
        var type = token.type;

        if (type === _Comment || type === _LineTerminator) {
          continue;
        }

        var value = token.value;
        if (type === _Punctuator) {
          if (value === ')') {
            if (isValidRegExpPrefix(tokens, index + 1)) {
              break;
            }
          } else if (regexPrefixRe.test(value)) {
            break;
          }
        } else if (type === _Keyword && regexPrefixRe.test(value)) {
          break;
        }

        var parts = parseRegExp(regexToken);
        Array.prototype.splice.apply(tokens, [i, 1].concat(parts));
        break;
      }
    }
  }

  function isValidRegExpPrefix(tokens, i) {
    var level = 0;

    while (--i >= 0) {
      var token = tokens[i];
      var type = token.type;
      if (type !== _Punctuator) {
        continue;
      }

      var value = token.value;
      if (value === '(') {
        if (--level === 0) {
          var prevToken = tokens[i - 1];
          if (prevToken && prevToken.type === _Keyword &&
              regexParenWordsRe.test(prevToken.value)) {
            return true;
          }
          return false;
        }
      } else if (value === ')') {
        level++;
      }
    }

    return false;
  }

  function parseRegExpFlags(value) {
    var index = value.lastIndexOf('/');
    var flags = value.substring(index + 1);
    var pattern = value.substr(1, index - 1);

    return {
      pattern: pattern,
      flags: flags
    };
  }

  function parseRegExp(regexToken) {
    var value = regexToken.value;
    var tokens = [];
    var m;

    _regexParsing = true;
    tokenizeRe.lastIndex = 0;
    while ((m = tokenizeRe.exec(value)) != null) {
      parseMatches(m, tokens);
    }

    if (_options.range) {
      var index = regexToken.range[0];
      for (var i = 0, len = tokens.length; i < len; i++) {
        var range = tokens[i].range;
        range[0] += index;
        range[1] += index;
      }
    }

    _regexParsing = false;
    return tokens;
  }

  function tokenize(code, options) {
    _options = options || {};

    var tokens = [];
    var m;

    _regexParsing = false;
    tokenizeAllRe.lastIndex = 0;
    while ((m = tokenizeAllRe.exec(code)) != null) {
      parseMatches(m, tokens);
    }

    fixRegExpTokens(tokens);
    _options = null;
    return tokens;
  }

  /**
   * Tokenize a string code.
   *
   * @param {string} code Target code.
   * @param {Object} [options] Tokenize options.
   *   - comment: {boolean} (default=false)
   *     Keep comment tokens.
   *   - lineTerminator: {boolean} (default=false)
   *     Keep line feed tokens.
   *   - range: {boolean} (default=false)
   *     Includes an index-based location range (array)
   * @return {string} Return an array of the parsed tokens.
   */
  Chiffon.tokenize = tokenize;

  function untokenize(tokens, options) {
    options = options || {};

    var results = [];
    var maxLineLen = options.maxLineLen || DEFAULT_MAXLINELEN;
    var lineLen = 0;
    var prev;

    for (var i = 0, len = tokens.length; i < len; prev = tokens[i++]) {
      var token = tokens[i];
      var tokenType = token.type;
      var tokenValue = token.value;
      var next = tokens[i + 1];

      if (!prev) {
        if (tokenType !== _LineTerminator) {
          results[results.length] = tokenValue;
        }
        continue;
      }

      var ws = '';
      var prevType = prev.type;
      var prevValue = prev.value;

      if (tokenType === _LineTerminator) {
        if (prevType === _LineTerminator) {
          continue;
        }
        if (prevType === _Punctuator || (next && next.type === _Punctuator)) {
          tokenValue = '';
        } else {
          lineLen = 0;
        }
      } else {
        if ((signLeftRe.test(tokenValue) && signRightRe.test(prevValue)) ||
            (identLeftRe.test(tokenValue) && identRightRe.test(prevValue))) {
          ws = ' ';
        }

        if (tokenType === _Punctuator && lineLen > maxLineLen) {
          tokenValue += '\n';
          lineLen = 0;
        }
      }

      var value = ws + tokenValue;
      lineLen += value.length;
      results[results.length] = value;
    }

    return results.join('');
  }

  /**
   * Concatenate to string from the parsed tokens.
   *
   * @param {Array} tokens An array of the parsed tokens.
   * @return {string} Return a concatenated string.
   */
  Chiffon.untokenize = untokenize;

  function minify(code, options) {
    return untokenize(tokenize(code, { lineTerminator: true }), options);
  }

  /**
   * Minify JavaScript code.
   *
   * @param {string} code Target code.
   * @param {Object} [options] minify options.
   *   - maxLineLen: {number} (default=32000)
   *     Limit the line length in symbols.
   * @return {string} Return a minified code.
   */
  Chiffon.minify = minify;

  return Chiffon;
}));
<|endoftext|>


<commit_before>const path = require('path');
const vscode = require('vscode');

function showRelatedFiles() {
    const separator = path.sep;
    const { levelsToPreserve } = vscode.workspace.getConfiguration('quickPickRelatedFiles');

    const { fileName } = vscode.window.activeTextEditor.document;
    const fileNameParts = fileName.split(separator);
    const prefilledText = fileNameParts.slice(fileNameParts.length - 1 - levelsToPreserve).join(separator);

    vscode.commands.executeCommand('workbench.action.quickOpen', prefilledText);
}

function activate(context) {
    context.subscriptions.push(vscode.commands.registerCommand('quickPickRelatedFiles.show', showRelatedFiles));
}

module.exports.activate = activate;
<commit_msg>Create buildPrefix function<commit_after>const path = require('path');
const vscode = require('vscode');

function buildPrefix(currentFilename, separator, config) {
    const { levelsToPreserve } = config;

    const fileNameParts = currentFilename.split(separator);
    return fileNameParts.slice(fileNameParts.length - 1 - levelsToPreserve).join(separator);
}

function showRelatedFiles() {
    const currentFilename = vscode.window.activeTextEditor.document.fileName;
    const separator = path.sep;
    const config = vscode.workspace.getConfiguration('quickPickRelatedFiles');

    const prefix = buildPrefix(currentFilename, separator, config);
    vscode.commands.executeCommand('workbench.action.quickOpen', prefix);
}

function activate(context) {
    context.subscriptions.push(vscode.commands.registerCommand('quickPickRelatedFiles.show', showRelatedFiles));
}

module.exports.buildPrefix = buildPrefix;
module.exports.activate = activate;
<|endoftext|>


<commit_before>if (typeof define !== 'function') {
	var define = require('amdefine')(module);
}

define(["require","../deep", "../lib/unit"], function (require, deep, Unit) {

	//_______________________________________________________________ GENERIC STORE TEST CASES

	var unit = {
		title:"deep/units/ocm",
		tests : {
			base:function(){
				var myManager = deep.ocm({
					mode1:{
						test:1
					},
					mode2:{
						test:2,
						title:"hello world"
					},
					mode3:{
						backgrounds:["this::../mode2"],
						description:"mode 3 description"
					}
				});
				myManager.flatten(); // seek and apply backgrounds
				return deep.when([myManager("mode1"),myManager("mode2"), myManager("mode3")]).equal(
					[
						{ test:1 },
						{ test:2, title:"hello world"},
						{ test:2, title:"hello world", description:"mode 3 description"}
					]
				);
		   },
		   currentMode:function(){
				var myManager = deep.ocm({
					mode1:{
						title:"should not see this"
					},
					mode2:{
						title:"hello world"
					}
				});
				myManager.mode("mode2");
				return deep.when(myManager())
				.equal({ title:"hello world" });
			},
			modeCollection:function(){
				var myManager = deep.ocm({
					mode1:{
						test:1
					},
					mode2:{
						title:"hello world"
					}
				});
				return deep.when([myManager("mode1", "mode2"), myManager("mode2", "mode1")])
				.equal([ { test:1, title:"hello world"}, { title:"hello world", test:1 }]);
			},
			setGroup:function()
			{
				var myManager = deep.ocm({
					mode1:{
						test:1
					},
					mode2:{
						title:"hello world"
					}
				});

				myManager.group("myGroup");

				deep.setModes({ "myGroup":["mode2", "mode1"]}); // set modes in current deep.context

				return deep.modes({ "myGroup":"mode1" }) // start a chain with provided modes
				.delay(5)
				.done(function(success){
					return myManager();
				})
				.equal({test:1})
				.modes({ "myGroup":"mode2"} )
				.delay(5)
				.done(function(success){
					return myManager();
				})
				.equal({ title:"hello world"});
			},
			groupCollection:function(){
				return deep.modes({
					group1:"mode1"
				})
				.done(function(success){
					return deep.modes({ group2:"mode2" })
					.delay(5)
					.done(function(success){
						return deep.context.modes;
					})
					.equal({ group1:"mode1", group2:"mode2" });
				})
				.delay(5)
				.done(function(success){
					return deep.context.modes;
				})
				.equal({ group1:"mode1" });
			},
			shared:function(){
				var obj = deep.ocm({
					mode1:{
						myShared:deep.Shared([1,2,3]),
						myShared2:deep.Shared({ a:1 })
					},
					mode2:{
						backgrounds:["this::../mode1"],
						myShared:[4,5],
						myShared2:{ b:2 }
					}
				});

				return obj.flatten().done(function(obj){
					obj("mode1").myShared.push(6);
					obj("mode1").myShared2.c = 3;
					return [obj("mode1"), obj("mode2")];
				})
				.equal([
					{ myShared:[1,2,3,4,5,6], myShared2:{ a:1, _deep_shared_:true, b:2,  c:3}},
					{ myShared:[1,2,3,4,5,6], myShared2:{ a:1,  _deep_shared_:true, b:2, c:3}}
				]);
			},
			cross_inheritance:function(){
				var a = {
					b:deep.ocm({
						backgrounds:["this::../brol"],
						role:true
					}),
					brol:{
						role2:false
					}
				};
				deep.flatten(a);
				return deep([a.b("role2"),a.b("role")]).equal([false,true]);
			}
		}
	};

	return unit;
});
<commit_msg>remove deep.setModes<commit_after>if (typeof define !== 'function') {
	var define = require('amdefine')(module);
}

define(["require","../deep", "../lib/unit"], function (require, deep, Unit) {

	//_______________________________________________________________ GENERIC STORE TEST CASES

	var unit = {
		title:"deep/units/ocm",
		tests : {
			base:function(){
				var myManager = deep.ocm({
					mode1:{
						test:1
					},
					mode2:{
						test:2,
						title:"hello world"
					},
					mode3:{
						backgrounds:["this::../mode2"],
						description:"mode 3 description"
					}
				});
				myManager.flatten(); // seek and apply backgrounds
				return deep.when([myManager("mode1"),myManager("mode2"), myManager("mode3")]).equal(
					[
						{ test:1 },
						{ test:2, title:"hello world"},
						{ test:2, title:"hello world", description:"mode 3 description"}
					]
				);
		   },
		   currentMode:function(){
				var myManager = deep.ocm({
					mode1:{
						title:"should not see this"
					},
					mode2:{
						title:"hello world"
					}
				});
				myManager.mode("mode2");
				return deep.when(myManager())
				.equal({ title:"hello world" });
			},
			modeCollection:function(){
				var myManager = deep.ocm({
					mode1:{
						test:1
					},
					mode2:{
						title:"hello world"
					}
				});
				return deep.when([myManager("mode1", "mode2"), myManager("mode2", "mode1")])
				.equal([ { test:1, title:"hello world"}, { title:"hello world", test:1 }]);
			},
			setGroup:function()
			{
				var myManager = deep.ocm({
					mode1:{
						test:1
					},
					mode2:{
						title:"hello world"
					}
				});
				myManager.group("myGroup");
				return deep.modes({ "myGroup":"mode1" }) // start a chain with provided modes
				.delay(5)
				.done(function(success){
					return myManager();
				})
				.equal({test:1})
				.modes({ "myGroup":"mode2"} )
				.delay(5)
				.done(function(success){
					return myManager();
				})
				.equal({ title:"hello world"});
			},
			groupCollection:function(){
				return deep.modes({
					group1:"mode1"
				})
				.done(function(success){
					return deep.modes({ group2:"mode2" })
					.delay(5)
					.done(function(success){
						return deep.context.modes;
					})
					.equal({ group1:"mode1", group2:"mode2" });
				})
				.delay(5)
				.done(function(success){
					return deep.context.modes;
				})
				.equal({ group1:"mode1" });
			},
			shared:function(){
				var obj = deep.ocm({
					mode1:{
						myShared:deep.Shared([1,2,3]),
						myShared2:deep.Shared({ a:1 })
					},
					mode2:{
						backgrounds:["this::../mode1"],
						myShared:[4,5],
						myShared2:{ b:2 }
					}
				});

				return obj.flatten().done(function(obj){
					obj("mode1").myShared.push(6);
					obj("mode1").myShared2.c = 3;
					return [obj("mode1"), obj("mode2")];
				})
				.equal([
					{ myShared:[1,2,3,4,5,6], myShared2:{ a:1, _deep_shared_:true, b:2,  c:3}},
					{ myShared:[1,2,3,4,5,6], myShared2:{ a:1,  _deep_shared_:true, b:2, c:3}}
				]);
			},
			cross_inheritance:function(){
				var a = {
					b:deep.ocm({
						backgrounds:["this::../brol"],
						role:true
					}),
					brol:{
						role2:false
					}
				};
				deep.flatten(a);
				return deep([a.b("role2"),a.b("role")]).equal([false,true]);
			}
		}
	};

	return unit;
});
<|endoftext|>


<commit_before>import { GraphQLString, GraphQLNonNull } from 'graphql';

import { assertUser } from 'util/user';
import client from 'util/client';
import { uploadToGCS } from 'util/gcs';
import { getMediaFileHash } from 'graphql/util';

import { ArticleReferenceInput } from 'graphql/models/ArticleReference';
import MutationResult from 'graphql/models/MutationResult';
import { createOrUpdateReplyRequest } from './CreateOrUpdateReplyRequest';
import ArticleTypeEnum from 'graphql/models/ArticleTypeEnum';
import fetch from 'node-fetch';

/**
 * @param {NodeJS.ReadableStream} fileStream
 * @param {sring} name File name
 * @param {ArticleTypeEnum} type The article type
 * @returns {string} url
 */
export async function uploadFile(fileStream, name, type) {
  // final file name that combined with folder name.
  let fileName;
  let mimeType = '*/*';

  if (type === 'IMAGE') {
    if (process.env.GCS_IMAGE_FOLDER) {
      fileName = `${process.env.GCS_IMAGE_FOLDER}/${name}.jpeg`;
    } else {
      fileName = `${name}.jpeg`;
    }

    mimeType = 'image/jpeg';
  }
  return await uploadToGCS(fileStream, fileName, mimeType);
}

/**
 * Creates a new article in ElasticSearch,
 * or return an article which attachment.hash is similar to mediaUrl
 *
 * @param {object} param
 * @param {string} param.mediaUrl
 * @param {ArticleTypeEnum} param.articleType
 * @param {ArticleReferenceInput} param.reference
 * @param {string} param.userId
 * @param {string} param.appId
 * @returns {Promise<string>} the new article's ID
 */
async function createNewMediaArticle({
  mediaUrl,
  articleType,
  reference: originalReference,
  userId,
  appId,
}) {
  if (articleType !== 'IMAGE') {
    throw new Error(`Type ${articleType} is not yet supported.`);
  }

  const file = await fetch(mediaUrl);
  const attachmentHash = await getMediaFileHash(
    await file.clone().buffer(),
    articleType
  );
  const text = '';
  const now = new Date().toISOString();
  const reference = {
    ...originalReference,
    createdAt: now,
    userId: userId,
    appId: appId,
  };

  const { body: matchedArticle } = await client.search({
    index: 'articles',
    type: 'doc',
    body: {
      query: {
        term: {
          attachmentHash,
        },
      },
    },
  });

  if (!matchedArticle.hits.total) {
    const attachmentUrl = await uploadFile(
      file.body,
      attachmentHash,
      articleType
    );

    // use elasticsearch created id
    const {
      body: { _id: articleId },
    } = await client.index({
      index: 'articles',
      type: 'doc',
      body: {
        text,
        createdAt: now,
        updatedAt: now,
        userId,
        appId,
        references: [reference],
        articleReplies: [],
        articleCategories: [],
        normalArticleReplyCount: 0,
        normalArticleCategoryCount: 0,
        replyRequestCount: 0,
        tags: [],
        hyperlinks: [],
        articleType,
        attachmentUrl,
        attachmentHash,
      },
    });

    return articleId;
  }
  return matchedArticle.hits.hits[0]._id;
}

export default {
  type: MutationResult,
  description: 'Create a media article and/or a replyRequest',
  args: {
    mediaUrl: { type: new GraphQLNonNull(GraphQLString) },
    articleType: { type: new GraphQLNonNull(ArticleTypeEnum) },
    reference: { type: new GraphQLNonNull(ArticleReferenceInput) },
    reason: {
      // FIXME: Change to required field after LINE bot is implemented
      // type: new GraphQLNonNull(GraphQLString),
      type: GraphQLString,
      description:
        'The reason why the user want to submit this article. Mandatory for 1st sender',
    },
  },
  resolve(rootValue, { mediaUrl, articleType, reference, reason }, { user }) {
    assertUser(user);
    const newArticlePromise = createNewMediaArticle({
      mediaUrl,
      articleType,
      reference,
      userId: user.id,
      appId: user.appId,
    });

    // Dependencies
    //
    // newArticlePromise* --> replyRequestPromise* --> done
    //
    // *: Updates article. Will trigger version_conflict_engine_exception if run in parallel.
    //

    const replyRequestPromise = newArticlePromise.then(articleId =>
      createOrUpdateReplyRequest({ articleId, user, reason })
    );

    // Wait for all promises
    return Promise.all([
      newArticlePromise, // for fetching articleId
      replyRequestPromise,
    ]).then(([id]) => ({ id }));
  },
};
<commit_msg>[CreateMediaArticle] Make logic clean<commit_after>import { GraphQLString, GraphQLNonNull } from 'graphql';

import { assertUser } from 'util/user';
import client from 'util/client';
import { uploadToGCS } from 'util/gcs';
import { getMediaFileHash } from 'graphql/util';

import { ArticleReferenceInput } from 'graphql/models/ArticleReference';
import MutationResult from 'graphql/models/MutationResult';
import { createOrUpdateReplyRequest } from './CreateOrUpdateReplyRequest';
import ArticleTypeEnum from 'graphql/models/ArticleTypeEnum';
import fetch from 'node-fetch';

/**
 * @param {NodeJS.ReadableStream} fileStream
 * @param {sring} name File name
 * @param {ArticleTypeEnum} type The article type
 * @returns {string} url
 */
export async function uploadFile(fileStream, name, type) {
  // final file name that combined with folder name.
  let fileName;
  let mimeType = '*/*';

  if (type === 'IMAGE') {
    if (process.env.GCS_IMAGE_FOLDER) {
      fileName = `${process.env.GCS_IMAGE_FOLDER}/${name}.jpeg`;
    } else {
      fileName = `${name}.jpeg`;
    }

    mimeType = 'image/jpeg';
  }
  return await uploadToGCS(fileStream, fileName, mimeType);
}

/**
 * Creates a new article in ElasticSearch,
 * or return an article which attachment.hash is similar to mediaUrl
 *
 * @param {object} param
 * @param {string} param.mediaUrl
 * @param {ArticleTypeEnum} param.articleType
 * @param {ArticleReferenceInput} param.reference
 * @param {string} param.userId
 * @param {string} param.appId
 * @returns {Promise<string>} the new article's ID
 */
async function createNewMediaArticle({
  mediaUrl,
  articleType,
  reference: originalReference,
  userId,
  appId,
}) {
  if (articleType !== 'IMAGE') {
    throw new Error(`Type ${articleType} is not yet supported.`);
  }

  const file = await fetch(mediaUrl);
  const attachmentHash = await getMediaFileHash(
    await file.clone().buffer(),
    articleType
  );
  const text = '';
  const now = new Date().toISOString();
  const reference = {
    ...originalReference,
    createdAt: now,
    userId: userId,
    appId: appId,
  };

  const { body: matchedArticle } = await client.search({
    index: 'articles',
    type: 'doc',
    body: {
      query: {
        term: {
          attachmentHash,
        },
      },
    },
  });

  if (matchedArticle.hits.total) {
    return matchedArticle.hits.hits[0]._id;
  }

  const attachmentUrl = await uploadFile(
    file.body,
    attachmentHash,
    articleType
  );

  // use elasticsearch created id
  const {
    body: { _id: articleId },
  } = await client.index({
    index: 'articles',
    type: 'doc',
    body: {
      text,
      createdAt: now,
      updatedAt: now,
      userId,
      appId,
      references: [reference],
      articleReplies: [],
      articleCategories: [],
      normalArticleReplyCount: 0,
      normalArticleCategoryCount: 0,
      replyRequestCount: 0,
      tags: [],
      hyperlinks: [],
      articleType,
      attachmentUrl,
      attachmentHash,
    },
  });

  return articleId;
}

export default {
  type: MutationResult,
  description: 'Create a media article and/or a replyRequest',
  args: {
    mediaUrl: { type: new GraphQLNonNull(GraphQLString) },
    articleType: { type: new GraphQLNonNull(ArticleTypeEnum) },
    reference: { type: new GraphQLNonNull(ArticleReferenceInput) },
    reason: {
      // FIXME: Change to required field after LINE bot is implemented
      // type: new GraphQLNonNull(GraphQLString),
      type: GraphQLString,
      description:
        'The reason why the user want to submit this article. Mandatory for 1st sender',
    },
  },
  async resolve(
    rootValue,
    { mediaUrl, articleType, reference, reason },
    { user }
  ) {
    assertUser(user);
    const articleId = await createNewMediaArticle({
      mediaUrl,
      articleType,
      reference,
      userId: user.id,
      appId: user.appId,
    });

    await createOrUpdateReplyRequest({
      articleId,
      user,
      reason,
    });

    return { id: articleId };
  },
};
<|endoftext|>


<commit_before>

 var duration_longue = true;
  var  duration_courte = false;
  var  enfant = false;
   var adult = true;
   var duree = "longue";

  $(document).ready(function(){
  //on initialise les variables avec les valeurs par défaut

    var pub = "adu";
    var nbDePersonnes = 16;
    var sce = 1;
  //localStorage.numGroupe = nbDePersonnes;

  //  localStorage.duree = 'longue_adult';

  //on appuie les boutons en conséquence
    $("#dur_lon").addClass("active");
    $("#pub_adu").addClass("active");
    $("#sce_1").addClass("active");
    //$("#car").load('carousel_long.html');

    //On remplit le champ du bouton +/- avec la valeur par défaut
    $("#inputnb").val(nbDePersonnes);

   //localStorage.duree = 'longue_adult';
    //var carousel_c = $.get("carousel_court.html");
    //var carousel_l = $.get("carousel_long.html");
  //On change la valeur des variables en fonction des actions utilisateurs
   $("#inputnb").change(function(e){
     var numpers = $("#inputnb").val();
     localStorage.numGroupe = numpers;
   });

  //Pour la durée :
    $("#dur_cou").click(function(e){

  //    localStorage.duree = 'courte';

      duree = "courte";
      duration_courte = true;
      duration_longue = false;
      $("#dur_lon").removeClass("active");
      $("#dur_cou").addClass("active");
      //var code = load("carousel_court.html");
      //$("#myCarousel").replaceWith("
 This text is strong
  This text is italic
");
      //alert(carousel_c);
      //$("#car").empty();
      $("#car").load('carousel_court.html');
      $("#p1").show();
//       alert("Chargement terminé \n Guide pour atelier court !");
      $("#rest").hide();
      $("#plusbtn, #minubtn").click(function(){$("#rest").show();});

      if (duree == "longue" && enfant) localStorage.duree = "longue_enfant";
      else if (duree == "courte" && adult) localStorage.duree = "courte_adult";
      else if (duree == "courte" && enfant) localStorage.duree = "courte_enfant";
      else  localStorage.duree = "longue_adult";

    });
    $("#dur_lon").click(function(e){

    //  localStorage.duree = 'longue';

      duree = "longue";
      duration_longue = true;
      duration_courte = false;
      $("#dur_cou").removeClass("active");
      $("#dur_lon").addClass("active");
      //$("#myCarousel").replaceWith(carousel_l);
      //$("#car").empty();
      $("#car").load('carousel_long.html');
      $("#p1").show();
//       alert("Chargement terminé \n Guide pour atelier long !");
      $("#rest").hide();
      $("#plusbtn, #minubtn").click(function(){$("#rest").show();})

      if (duree == "longue" && enfant) localStorage.duree = "longue_enfant";
      else if (duree == "courte" && adult) localStorage.duree = "courte_adult";
      else if (duree == "courte" && enfant) localStorage.duree = "courte_enfant";
      else  localStorage.duree = "longue_adult";
    });
  //Pour le public :
    $("#pub_enf").click(function(e){

      localStorage.type = 'enfant';

      pub = "enf";
      adult = false;
      enfant = true;
      $("#pub_adu").removeClass("active");
      $("#pub_enf").addClass("active");

      if (duree == "longue" && enfant) localStorage.duree = "longue_enfant";
      else if (duree == "courte" && adult) localStorage.duree = "courte_adult";
      else if (duree == "courte" && enfant) localStorage.duree = "courte_enfant";
      else  localStorage.duree = "longue_adult";
    });
    $("#pub_adu").click(function(e){

      localStorage.type = 'adult';

      pub = "adu";
      adult = true;
      enfant = false;
      $("#pub_enf").removeClass("active");
      $("#pub_adu").addClass("active");

      if (duree == "longue" && enfant) localStorage.duree = "longue_enfant";
      else if (duree == "courte" && adult) localStorage.duree = "courte_adult";
      else if (duree == "courte" && enfant) localStorage.duree = "courte_enfant";
      else  localStorage.duree = "longue_adult";
    });
  //Pour le scénario :
    $("#sce_2").click(function(e){
      sce = 2;
     localStorage.dataset = "deux";
      $("#sce_1").removeClass("active");
      $("#sce_2").addClass("active");
    });
    $("#sce_1").click(function(e){
      sce = 1;
      localStorage.dataset = "un";
      $("#sce_2").removeClass("active");
      $("#sce_1").addClass("active");
    });

    $("#pointLien").click(function(e){
      if(pub == "enf"){
        $("#pointLien").attr('href','graphiques_enfants.html');
      }else{
        $("#pointLien").attr('href','graphiques_adultes.html');
      }
    });

  });

function demoFromHTML() {

     var pdf = new jsPDF('p', 'pt', 'a4', false);

  //   alert(localStorage.duree);

    var logo = new Image();

    var numPErs =  (parseInt(localStorage.numGroupe));

    alert(numPErs);

          if(localStorage.duree == "longue_adult"){
            if(localStorage.dataset == "un"){
              var cont = 1;
              for (groupe = 1; groupe < 5; groupe++) {
                 var logo = new Image();
                 logo.src = "https://vizkit.github.io/pdf_images/long/Long_adults/long_adults_dataset1_"+groupe+".PNG";
                 pdf.addImage(logo, 'PNG', 2, 2, 590,850);
                 if(groupe < numPErs){
                   pdf.addPage();
                 }
              }
            }else{
              for (groupe = 1; groupe < 5; groupe++) {
                 var logo = new Image();
                 logo.src = "https://vizkit.github.io/pdf_images/long/Long_adults/long_adults_dataset2_"+groupe+".PNG";
                 pdf.addImage(logo, 'PNG', 2, 2, 590,850);
                 if(groupe < numPErs){
                   pdf.addPage();
                 }
              }
            }
          }
          else if(localStorage.duree == "longue_enfant"){
            if(localStorage.dataset == "un"){
              for (groupe = 1; groupe < 5; groupe++) {
                 var logo = new Image();
                 logo.src = "https://vizkit.github.io/pdf_images/long/Long_enfants/long_enfants_dataset1_"+groupe+".PNG";
                 pdf.addImage(logo, 'PNG', 2, 2, 590,850);
                 if(groupe < numPErs){
                   pdf.addPage();
                 }
              }
            }else{
              for (groupe = 1; groupe < 5; groupe++) {
                 var logo = new Image();
                 logo.src = "https://vizkit.github.io/pdf_images/long/Long_enfants/long_enfants_dataset2_"+groupe+".PNG";
                 pdf.addImage(logo, 'PNG', 2, 2, 590,850);
                 if(groupe < numPErs){
                   pdf.addPage();
                 }
              }
            }

      }
      else if(localStorage.duree == "courte_enfant"){
            if(localStorage.dataset == "un"){
              for (groupe = 1; groupe < 5; groupe++) {
                 var logo = new Image();
                 logo.src = "https://vizkit.github.io/pdf_images/court/Court_enfants/court_enfants_dataset1_"+groupe+".PNG";
                 pdf.addImage(logo, 'PNG', 2, 2, 590,850);
                 if(groupe < numPErs){
                   pdf.addPage();
                 }
              }
            }else{
              for (groupe = 1; groupe < 5; groupe++) {
                var logo = new Image();
                logo.src = "https://vizkit.github.io/pdf_images/court/Court_enfants/court_enfants_dataset2_"+groupe+".PNG";
                pdf.addImage(logo, 'PNG', 2, 2, 590,850);
                if(groupe < numPErs){
                   pdf.addPage();
                }
              }
            }

          }
          else {
            if(localStorage.dataset == "un"){
             for (groupe = 1; groupe < 5; groupe++) {
                var logo = new Image();
                logo.src = "https://vizkit.github.io/pdf_images/court/Court_adults/court_adults_dataset1_"+groupe+".PNG";
                pdf.addImage(logo, 'PNG', 2, 2, 590,850);
                if(groupe < numPErs){
                   pdf.addPage();
                 }

             }
            }else{
             for (groupe = 1; groupe < 5; groupe++) {
                var logo = new Image();
                logo.src = "https://vizkit.github.io/pdf_images/court/Court_adults/court_adults_dataset2_"+groupe+".PNG";
                pdf.addImage(logo, 'PNG', 2, 2, 590,850);
                if(groupe < numPErs){
                   pdf.addPage();
                 }
             }
            }
          // var uno= 1;
          }

        pdf.output("dataurlnewwindow");

}
<commit_msg>Update dynamic_carousel.js<commit_after>

 var duration_longue = true;
  var  duration_courte = false;
  var  enfant = false;
   var adult = true;
   var duree = "longue";

  $(document).ready(function(){
  //on initialise les variables avec les valeurs par défaut

    var pub = "adu";
    var nbDePersonnes = 16;
    var sce = 1;
  //localStorage.numGroupe = nbDePersonnes;

  //  localStorage.duree = 'longue_adult';

  //on appuie les boutons en conséquence
    $("#dur_lon").addClass("active");
    $("#pub_adu").addClass("active");
    $("#sce_1").addClass("active");
    //$("#car").load('carousel_long.html');

    //On remplit le champ du bouton +/- avec la valeur par défaut
    $("#inputnb").val(nbDePersonnes);

   //localStorage.duree = 'longue_adult';
    //var carousel_c = $.get("carousel_court.html");
    //var carousel_l = $.get("carousel_long.html");
  //On change la valeur des variables en fonction des actions utilisateurs
   $("#inputnb").change(function(e){
     var numpers = $("#inputnb").val();
     localStorage.numGroupe = numpers;
   });

  //Pour la durée :
    $("#dur_cou").click(function(e){

  //    localStorage.duree = 'courte';

      duree = "courte";
      duration_courte = true;
      duration_longue = false;
      $("#dur_lon").removeClass("active");
      $("#dur_cou").addClass("active");
      //var code = load("carousel_court.html");
      //$("#myCarousel").replaceWith("
 This text is strong
  This text is italic
");
      //alert(carousel_c);
      //$("#car").empty();
      $("#car").load('carousel_court.html');
      $("#p1").show();
//       alert("Chargement terminé \n Guide pour atelier court !");
      $("#rest").hide();
      $("#plusbtn, #minubtn").click(function(){$("#rest").show();});

      if (duree == "longue" && enfant) localStorage.duree = "longue_enfant";
      else if (duree == "courte" && adult) localStorage.duree = "courte_adult";
      else if (duree == "courte" && enfant) localStorage.duree = "courte_enfant";
      else  localStorage.duree = "longue_adult";

    });
    $("#dur_lon").click(function(e){

    //  localStorage.duree = 'longue';

      duree = "longue";
      duration_longue = true;
      duration_courte = false;
      $("#dur_cou").removeClass("active");
      $("#dur_lon").addClass("active");
      //$("#myCarousel").replaceWith(carousel_l);
      //$("#car").empty();
      $("#car").load('carousel_long.html');
      $("#p1").show();
//       alert("Chargement terminé \n Guide pour atelier long !");
      $("#rest").hide();
      $("#plusbtn, #minubtn").click(function(){$("#rest").show();})

      if (duree == "longue" && enfant) localStorage.duree = "longue_enfant";
      else if (duree == "courte" && adult) localStorage.duree = "courte_adult";
      else if (duree == "courte" && enfant) localStorage.duree = "courte_enfant";
      else  localStorage.duree = "longue_adult";
    });
  //Pour le public :
    $("#pub_enf").click(function(e){

      localStorage.type = 'enfant';

      pub = "enf";
      adult = false;
      enfant = true;
      $("#pub_adu").removeClass("active");
      $("#pub_enf").addClass("active");

      if (duree == "longue" && enfant) localStorage.duree = "longue_enfant";
      else if (duree == "courte" && adult) localStorage.duree = "courte_adult";
      else if (duree == "courte" && enfant) localStorage.duree = "courte_enfant";
      else  localStorage.duree = "longue_adult";
    });
    $("#pub_adu").click(function(e){

      localStorage.type = 'adult';

      pub = "adu";
      adult = true;
      enfant = false;
      $("#pub_enf").removeClass("active");
      $("#pub_adu").addClass("active");

      if (duree == "longue" && enfant) localStorage.duree = "longue_enfant";
      else if (duree == "courte" && adult) localStorage.duree = "courte_adult";
      else if (duree == "courte" && enfant) localStorage.duree = "courte_enfant";
      else  localStorage.duree = "longue_adult";
    });
  //Pour le scénario :
    $("#sce_2").click(function(e){
      sce = 2;
     localStorage.dataset = "deux";
      $("#sce_1").removeClass("active");
      $("#sce_2").addClass("active");
    });
    $("#sce_1").click(function(e){
      sce = 1;
      localStorage.dataset = "un";
      $("#sce_2").removeClass("active");
      $("#sce_1").addClass("active");
    });

    $("#pointLien").click(function(e){
      if(pub == "enf"){
        $("#pointLien").attr('href','graphiques_enfants.html');
      }else{
        $("#pointLien").attr('href','graphiques_adultes.html');
      }
    });

  });

function demoFromHTML() {

     var pdf = new jsPDF('p', 'pt', 'a4', false);

  //   alert(localStorage.duree);

    var logo = new Image();

    var numPErs =  (parseInt(localStorage.numGroupe));

          if(localStorage.duree == "longue_adult"){
            if(localStorage.dataset == "un"){
              var cont = 1;
              for (groupe = 1; groupe < 5; groupe++) {
                 var logo = new Image();
                 logo.src = "https://vizkit.github.io/pdf_images/long/Long_adults/long_adults_dataset1_"+groupe+".PNG";
                 pdf.addImage(logo, 'PNG', 2, 2, 590,850);
                 if(groupe < numPErs){
                   pdf.addPage();
                 }
              }
            }else{
              for (groupe = 1; groupe < 5; groupe++) {
                 var logo = new Image();
                 logo.src = "https://vizkit.github.io/pdf_images/long/Long_adults/long_adults_dataset2_"+groupe+".PNG";
                 pdf.addImage(logo, 'PNG', 2, 2, 590,850);
                 if(groupe < numPErs){
                   pdf.addPage();
                 }
              }
            }
          }
          else if(localStorage.duree == "longue_enfant"){
            if(localStorage.dataset == "un"){
              for (groupe = 1; groupe < 5; groupe++) {
                 var logo = new Image();
                 logo.src = "https://vizkit.github.io/pdf_images/long/Long_enfants/long_enfants_dataset1_"+groupe+".PNG";
                 pdf.addImage(logo, 'PNG', 2, 2, 590,850);
                 if(groupe < numPErs){
                   pdf.addPage();
                 }
              }
            }else{
              for (groupe = 1; groupe < 5; groupe++) {
                 var logo = new Image();
                 logo.src = "https://vizkit.github.io/pdf_images/long/Long_enfants/long_enfants_dataset2_"+groupe+".PNG";
                 pdf.addImage(logo, 'PNG', 2, 2, 590,850);
                 if(groupe < numPErs){
                   pdf.addPage();
                 }
              }
            }

      }
      else if(localStorage.duree == "courte_enfant"){
            if(localStorage.dataset == "un"){
              for (groupe = 1; groupe < 5; groupe++) {
                 var logo = new Image();
                 logo.src = "https://vizkit.github.io/pdf_images/court/Court_enfants/court_enfants_dataset1_"+groupe+".PNG";
                 pdf.addImage(logo, 'PNG', 2, 2, 590,850);
                 if(groupe < numPErs){
                   pdf.addPage();
                 }
              }
            }else{
              for (groupe = 1; groupe < 5; groupe++) {
                var logo = new Image();
                logo.src = "https://vizkit.github.io/pdf_images/court/Court_enfants/court_enfants_dataset2_"+groupe+".PNG";
                pdf.addImage(logo, 'PNG', 2, 2, 590,850);
                if(groupe < numPErs){
                   pdf.addPage();
                }
              }
            }

          }
          else {
            if(localStorage.dataset == "un"){
             for (groupe = 1; groupe < 5; groupe++) {
                var logo = new Image();
                logo.src = "https://vizkit.github.io/pdf_images/court/Court_adults/court_adults_dataset1_"+groupe+".PNG";
                pdf.addImage(logo, 'PNG', 2, 2, 590,850);
                if(groupe < numPErs){
                   pdf.addPage();
                 }

             }
            }else{
             for (groupe = 1; groupe < 5; groupe++) {
                var logo = new Image();
                logo.src = "https://vizkit.github.io/pdf_images/court/Court_adults/court_adults_dataset2_"+groupe+".PNG";
                pdf.addImage(logo, 'PNG', 2, 2, 590,850);
                if(groupe < numPErs){
                   pdf.addPage();
                 }
             }
            }
          // var uno= 1;
          }

        pdf.output("dataurlnewwindow");

}
<|endoftext|>


<commit_before>// // Moment.js takes 161 KB of space (minified) which is too much
// import moment from 'moment'

// // `date-fns` would be a better alternative to moment
// // but it doesn't support templated date parsing
// // until version `2.0.0` of it is released.
// // https://github.com/date-fns/date-fns/issues/347
// import parse_date_date_fns from 'date-fns/parse'
// import format_date_date_fns from 'date-fns/format'

// Parses a text value into a `Date` provided a `format`.
// The date returned is in the user's time zone and the time is `12:00`.
export function parseDate(text_value, format, noon, utc)
{
	if (!text_value) {
		return
	}

	// Custom
	return parseDateCustom(text_value, format, noon, utc)

	// // Using `date-fns`
	// const date = parse_date_date_fns(text_value)

	// if (isNaN(date.getTime()))
	// {
	// 	return
	// }

	// return date

	// // Using `Moment.js`
	// const moment_day = moment(text_value, format, true)

	// if (!moment_day.isValid())
	// {
	// 	return
	// }

	// return moment_day.toDate()
}

// (Moment.js)
// Formats a `Date` into a text value provided a `format`
export function formatDate(date, format)
{
	// Custom
	return formatDateCustom(date, format)

	// // Using `date-fns`
	// return format_date_date_fns(date, format)

	// // Using `Moment.js`
	// return moment(date).format(format)
}

// Parses a text value into a `Date` provided a `format`.
// The date returned is in the user's time zone and the time is `00:00`.
// (only `DD`, `MM`, `YY` and `YYYY` literals are supported).
export function parseDateCustom(string, format, noon, utc)
{
	if (!string) {
		return
	}

	let year = extract(string, format, 'YYYY')

	if (year === undefined)
	{
		year = extract(string, format, 'YY')

		if (year !== undefined)
		{
			// Current year in the user's time zone.
			const current_year = new Date().getFullYear()
			const current_year_century = current_year - current_year % 100
			year += current_year_century
		}
	}

	const month = extract(string, format, 'MM')
	const day   = extract(string, format, 'DD')

	if (year === undefined || month === undefined || day === undefined) {
		return
	}

	// The date created is in the user's time zone and the time is `00:00`.
	let date = new Date
	(
		year,
		month - 1,
		day,
		noon ? 12 : 0
	)

	if (utc)
	{
		// Converts timezone to UTC while preserving the same time
		date = convertToUtcTimezone(date)
	}

	// If `new Date()` returns "Invalid Date"
	// (sometimes it does)
	if (isNaN(date.getTime())) {
		return
	}

	return date
}

function extract(string, template, piece)
{
	const starts_at = template.indexOf(piece)

	if (starts_at < 0) {
		return
	}

	// Check overall sanity
	if (!correspondsToTemplate(string, template)) {
		return
	}

	const number = parseInt(string.slice(starts_at, starts_at + piece.length))

	if (!isNaN(number)) {
		return number
	}
}

export function correspondsToTemplate(string, template)
{
	if (string.length !== template.length) {
		return false
	}

	let i = 0
	while (i < string.length)
	{
		const is_a_digit = string[i] >= '0' && string[i] <= '9'

		if (!is_a_digit)
		{
			if (string[i] !== template[i])
			{
				return false
			}
		}
		else
		{
			if (template[i] !== 'D' && template[i] !== 'M' && template[i] !== 'Y')
			{
				return false
			}
		}

		i++
	}

	return true
}

export function formatDateCustom(date, format)
{
	// Someone may accidentally pass a timestamp, or a string.
	// Or `date` could be `undefined`.
	if (!(date instanceof Date)) {
		return ''
	}

	// Check if `date` is "Invalid Date".
	if (isNaN(date.getTime())) {
		return ''
	}

	const day   = date.getDate()
	const month = date.getMonth() + 1
	const year  = date.getFullYear()

	let text = format
		.replace('DD', padWithZeroes(String(day),   2))
		.replace('MM', padWithZeroes(String(month), 2))

	if (text.indexOf('YYYY') >= 0) {
		return text.replace('YYYY', padWithZeroes(String(year), 4))
	}

	if (text.indexOf('YY') >= 0) {
		return text.replace('YY', padWithZeroes(String(year % 100), 2))
	}
}

function padWithZeroes(string, target_length)
{
	while (string.length < target_length) {
		string = '0' + string
	}

	return string
}

// // Intl date formatting
//
// const dateFormatters = {}
//
// function format_dateIntl(date, locale) {
//   if (typeof Intl === 'undefined') {
//     return date.toISOString()
//   }
//
//   const key = typeof locale === 'string' ? locale : locale.join(',')
//
//   if (!dateFormatters[key]) {
//     dateFormatters[key] = new Intl.DateTimeFormat(locale, {
//       day: '2-digit',
//       month: '2-digit',
//       year: 'numeric'
//     })
//   }
//
//   return dateFormatters[key]
// }

// Converts `null` to `undefined`
// (specially for `knex.js`)
export function normalizeDate(value)
{
	if (value === null) {
		return
	}

	// Check if `value` is "Invalid Date".
	if (value instanceof Date && isNaN(value.getTime())) {
		return
	}

	return value
}

export function trimInvalidPart(value, format)
{
	let i = 0
	while (i < value.length && i < format.length)
	{
		if (format[i] === 'D' || format[i] === 'M' || format[i] === 'Y')
		{
			if (!(value[i] >= '0' && value[i] <= '9'))
			{
				break
			}
		}
		else if (format[i] !== value[i])
		{
			break
		}
		i++
	}

	return value.slice(0, i)
}

// Converts timezone to UTC while preserving the same time
function convertToUtcTimezone(date)
{
	// Doesn't account for leap seconds but I guess that's ok
	// given that javascript's own `Date()` does not either.
	// https://www.timeanddate.com/time/leap-seconds-background.html
	//
	// https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Date/getTimezoneOffset
	//
	return new Date(date.getTime() - date.getTimezoneOffset() * 60 * 1000)
}
<commit_msg>YY parsing tweak<commit_after>// // Moment.js takes 161 KB of space (minified) which is too much
// import moment from 'moment'

// // `date-fns` would be a better alternative to moment
// // but it doesn't support templated date parsing
// // until version `2.0.0` of it is released.
// // https://github.com/date-fns/date-fns/issues/347
// import parse_date_date_fns from 'date-fns/parse'
// import format_date_date_fns from 'date-fns/format'

// Parses a text value into a `Date` provided a `format`.
// The date returned is in the user's time zone and the time is `12:00`.
export function parseDate(text_value, format, noon, utc)
{
	if (!text_value) {
		return
	}

	// Custom
	return parseDateCustom(text_value, format, noon, utc)

	// // Using `date-fns`
	// const date = parse_date_date_fns(text_value)

	// if (isNaN(date.getTime()))
	// {
	// 	return
	// }

	// return date

	// // Using `Moment.js`
	// const moment_day = moment(text_value, format, true)

	// if (!moment_day.isValid())
	// {
	// 	return
	// }

	// return moment_day.toDate()
}

// (Moment.js)
// Formats a `Date` into a text value provided a `format`
export function formatDate(date, format)
{
	// Custom
	return formatDateCustom(date, format)

	// // Using `date-fns`
	// return format_date_date_fns(date, format)

	// // Using `Moment.js`
	// return moment(date).format(format)
}

// Parses a text value into a `Date` provided a `format`.
// The date returned is in the user's time zone and the time is `00:00`.
// (only `DD`, `MM`, `YY` and `YYYY` literals are supported).
export function parseDateCustom(string, format, noon, utc)
{
	if (!string) {
		return
	}

	let year = extract(string, format, 'YYYY')

	if (year === undefined)
	{
		year = extract(string, format, 'YY')

		if (year !== undefined)
		{
			// Current year in the user's time zone.
			const current_year_and_century = new Date().getFullYear()
			const current_year = current_year_and_century % 100
			let century = (current_year_and_century - current_year) / 100

			if (year >= current_year)
			{
				if (year - current_year > 100 * 1/5)
				{
					century--
				}
			}
			else
			{
				if (current_year - year > 100 * 4/5)
				{
					century++
				}
			}

			year += century * 100
		}
	}

	const month = extract(string, format, 'MM')
	const day   = extract(string, format, 'DD')

	if (year === undefined || month === undefined || day === undefined) {
		return
	}

	// The date created is in the user's time zone and the time is `00:00`.
	let date = new Date
	(
		year,
		month - 1,
		day,
		noon ? 12 : 0
	)

	if (utc)
	{
		// Converts timezone to UTC while preserving the same time
		date = convertToUtcTimezone(date)
	}

	// If `new Date()` returns "Invalid Date"
	// (sometimes it does)
	if (isNaN(date.getTime())) {
		return
	}

	return date
}

function extract(string, template, piece)
{
	const starts_at = template.indexOf(piece)

	if (starts_at < 0) {
		return
	}

	// Check overall sanity
	if (!correspondsToTemplate(string, template)) {
		return
	}

	const number = parseInt(string.slice(starts_at, starts_at + piece.length))

	if (!isNaN(number)) {
		return number
	}
}

export function correspondsToTemplate(string, template)
{
	if (string.length !== template.length) {
		return false
	}

	let i = 0
	while (i < string.length)
	{
		const is_a_digit = string[i] >= '0' && string[i] <= '9'

		if (!is_a_digit)
		{
			if (string[i] !== template[i])
			{
				return false
			}
		}
		else
		{
			if (template[i] !== 'D' && template[i] !== 'M' && template[i] !== 'Y')
			{
				return false
			}
		}

		i++
	}

	return true
}

export function formatDateCustom(date, format)
{
	// Someone may accidentally pass a timestamp, or a string.
	// Or `date` could be `undefined`.
	if (!(date instanceof Date)) {
		return ''
	}

	// Check if `date` is "Invalid Date".
	if (isNaN(date.getTime())) {
		return ''
	}

	const day   = date.getDate()
	const month = date.getMonth() + 1
	const year  = date.getFullYear()

	let text = format
		.replace('DD', padWithZeroes(String(day),   2))
		.replace('MM', padWithZeroes(String(month), 2))

	if (text.indexOf('YYYY') >= 0) {
		return text.replace('YYYY', padWithZeroes(String(year), 4))
	}

	if (text.indexOf('YY') >= 0) {
		return text.replace('YY', padWithZeroes(String(year % 100), 2))
	}
}

function padWithZeroes(string, target_length)
{
	while (string.length < target_length) {
		string = '0' + string
	}

	return string
}

// // Intl date formatting
//
// const dateFormatters = {}
//
// function format_dateIntl(date, locale) {
//   if (typeof Intl === 'undefined') {
//     return date.toISOString()
//   }
//
//   const key = typeof locale === 'string' ? locale : locale.join(',')
//
//   if (!dateFormatters[key]) {
//     dateFormatters[key] = new Intl.DateTimeFormat(locale, {
//       day: '2-digit',
//       month: '2-digit',
//       year: 'numeric'
//     })
//   }
//
//   return dateFormatters[key]
// }

// Converts `null` to `undefined`
// (specially for `knex.js`)
export function normalizeDate(value)
{
	if (value === null) {
		return
	}

	// Check if `value` is "Invalid Date".
	if (value instanceof Date && isNaN(value.getTime())) {
		return
	}

	return value
}

export function trimInvalidPart(value, format)
{
	let i = 0
	while (i < value.length && i < format.length)
	{
		if (format[i] === 'D' || format[i] === 'M' || format[i] === 'Y')
		{
			if (!(value[i] >= '0' && value[i] <= '9'))
			{
				break
			}
		}
		else if (format[i] !== value[i])
		{
			break
		}
		i++
	}

	return value.slice(0, i)
}

// Converts timezone to UTC while preserving the same time
function convertToUtcTimezone(date)
{
	// Doesn't account for leap seconds but I guess that's ok
	// given that javascript's own `Date()` does not either.
	// https://www.timeanddate.com/time/leap-seconds-background.html
	//
	// https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Date/getTimezoneOffset
	//
	return new Date(date.getTime() - date.getTimezoneOffset() * 60 * 1000)
}
<|endoftext|>


<commit_before>/*
 * Copyright (C) 2015 Jonny Lamb <jonnylamb@jonnylamb.com>
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
 */

const Main = imports.ui.main;
const Meta = imports.gi.Meta;
const Lang = imports.lang;

const Shell = imports.gi.Shell;

// Import the convenience.js (Used for loading settings schemas)
const Self = imports.misc.extensionUtils.getCurrentExtension();
const Convenience = Self.imports.convenience;

// Import config
const config = Self.imports.config;

let notify_id = 0;
let visible = 1;

function init() {
    this.settings = Convenience.getSettings();
    // Catch use shortcut toggle config change
    this.settings.connect('changed::' +
        config.SETTINGS_USE_TOGGLE_SHORTCUT, Lang.bind(this, refreshBindings));
}

function enable() {
    if (settings.get_boolean(config.SETTINGS_USE_TOGGLE_SHORTCUT))
        addKeybindings(config.SETTINGS_TOGGLE_SHORTCUT, toggleTray);
    hideTray();
}

function disable() {
    removeKeybindings(config.SETTINGS_TOGGLE_SHORTCUT);
    showTray();
}

function showTray() {
    visible = 1;
    if (notify_id > 0)
        Main.legacyTray.actor.disconnect(notify_id);
    notify_id = 0;

    Main.legacyTray.actor.show();
}

function hideTray() {
    visible = 0;
    Main.legacyTray.actor.hide();

    /* so elegant */

    notify_id = Main.legacyTray.actor.connect("notify::visible", function() {
        if (Main.legacyTray.actor.visible)
            Main.legacyTray.actor.hide();
    });
}

function toggleTray() {
    if (visible == 1)
        hideTray();
    else
        showTray();
}

function addKeybindings(name, handler) {
    if (Main.wm.addKeybinding) {
        var ModeType = Shell.hasOwnProperty('ActionMode') ?
            Shell.ActionMode : Shell.KeyBindingMode;
        Main.wm.addKeybinding(name, this.settings, Meta.KeyBindingFlags.NONE,
             ModeType.NORMAL | ModeType.OVERVIEW, handler);
    } else {
        global.display.add_keybinding(name, this.settings,
             Meta.KeyBindingFlags.NONE, handler);
    }
}

function removeKeybindings(name) {
    if (Main.wm.removeKeybinding) {
        Main.wm.removeKeybinding(name);
    }
    else {
        global.display.remove_keybinding(name);
    }
}

function refreshBindings() {
    disable();
    enable();
}
<commit_msg>extension: turn visible into a bool<commit_after>/*
 * Copyright (C) 2015 Jonny Lamb <jonnylamb@jonnylamb.com>
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
 */

const Main = imports.ui.main;
const Meta = imports.gi.Meta;
const Lang = imports.lang;

const Shell = imports.gi.Shell;

// Import the convenience.js (Used for loading settings schemas)
const Self = imports.misc.extensionUtils.getCurrentExtension();
const Convenience = Self.imports.convenience;

// Import config
const config = Self.imports.config;

let notify_id = 0;
let visible = true;

function init() {
    this.settings = Convenience.getSettings();
    // Catch use shortcut toggle config change
    this.settings.connect('changed::' +
        config.SETTINGS_USE_TOGGLE_SHORTCUT, Lang.bind(this, refreshBindings));
}

function enable() {
    if (settings.get_boolean(config.SETTINGS_USE_TOGGLE_SHORTCUT))
        addKeybindings(config.SETTINGS_TOGGLE_SHORTCUT, toggleTray);
    hideTray();
}

function disable() {
    removeKeybindings(config.SETTINGS_TOGGLE_SHORTCUT);
    showTray();
}

function showTray() {
    visible = true;
    if (notify_id > 0)
        Main.legacyTray.actor.disconnect(notify_id);
    notify_id = 0;

    Main.legacyTray.actor.show();
}

function hideTray() {
    visible = false;
    Main.legacyTray.actor.hide();

    /* so elegant */

    notify_id = Main.legacyTray.actor.connect("notify::visible", function() {
        if (Main.legacyTray.actor.visible)
            Main.legacyTray.actor.hide();
    });
}

function toggleTray() {
    if (visible)
        hideTray();
    else
        showTray();
}

function addKeybindings(name, handler) {
    if (Main.wm.addKeybinding) {
        var ModeType = Shell.hasOwnProperty('ActionMode') ?
            Shell.ActionMode : Shell.KeyBindingMode;
        Main.wm.addKeybinding(name, this.settings, Meta.KeyBindingFlags.NONE,
             ModeType.NORMAL | ModeType.OVERVIEW, handler);
    } else {
        global.display.add_keybinding(name, this.settings,
             Meta.KeyBindingFlags.NONE, handler);
    }
}

function removeKeybindings(name) {
    if (Main.wm.removeKeybinding) {
        Main.wm.removeKeybinding(name);
    }
    else {
        global.display.remove_keybinding(name);
    }
}

function refreshBindings() {
    disable();
    enable();
}
<|endoftext|>