<commit_before>/* ***** BEGIN LICENSE BLOCK *****
 * Distributed under the BSD license:
 *
 * Copyright (c) 2010, Ajax.org B.V.
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are met:
 *     * Redistributions of source code must retain the above copyright
 *       notice, this list of conditions and the following disclaimer.
 *     * Redistributions in binary form must reproduce the above copyright
 *       notice, this list of conditions and the following disclaimer in the
 *       documentation and/or other materials provided with the distribution.
 *     * Neither the name of Ajax.org B.V. nor the
 *       names of its contributors may be used to endorse or promote products
 *       derived from this software without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
 * DISCLAIMED. IN NO EVENT SHALL AJAX.ORG B.V. BE LIABLE FOR ANY
 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 *
 * ***** END LICENSE BLOCK ***** */

define(function(require, exports, module) {
"use strict";

var oop = require("../lib/oop");
var DocCommentHighlightRules = require("./doc_comment_highlight_rules").DocCommentHighlightRules;
var TextHighlightRules = require("./text_highlight_rules").TextHighlightRules;

var leanHighlightRules = function() {

    var keywordControls = (
        [ "alias", "as", "assert", "assume", "at", "attribute", "axioms",
          "begin", "by", "calc", "check", "noncomputable",
          "classes", "coercions", "conjecture", "context",
          "corollary", "else", "end", "environment", "eval", "example",
          "exists", "exit", "export", "exposing", "extends", "fields", "find_decl",
          "forall", "from", "fun", "have", "help", "hiding", "if",
          "import", "in", "include", "infix", "infixl", "infixr", "instances",
          "let", "local", "match", "migrate", "namespace", "notation", "obtain",
          "omit", "opaque", "open", "options", "parameter", "parameters", "postfix",
          "precedence", "prefix", "prelude", "premise", "premises", "print", "private", "proof",
          "protected", "qed", "raw", "renaming", "replacing", "reserve", "reveal", "section", "set_option",
          "show", "suffices", "to", "suppose", "tactic_infix", "tactic_infixl", "tactic_infixr", "tactic_hint",
          "tactic_notation", "tactic_postfix", "tactic_prefix",
          "take", "then", "this", "universe",
          "universes", "using", "variable", "variables", "with"].join("|")
    );

    var nameProviders = (
        ["inductive\\b", "structure\\b", "record\\b", "theorem\\b", "axiom\\b", "corollary\\b",
         "conjecture\\b", "abbreviation\\b", "lemma\\b", "hypothesis\\b", "definition\\b",
         "constant\\b", "premise\\b"].join("|")
    );

    var storageType = (
        ["Prop", "Type", "Type'", "Type₊", "Type₁", "Type₂", "Type₃"].join("|")
    );

    var storageModifiers = (
        "\\[(" +
            ["abbreviations", "begin-end-hints", "class", "classes", "coercion", "unfold", "unfold-full",
             "coercions", "declarations", "decls", "instance", "irreducible", "recursor",
             "multiple-instances", "notation", "notations", "parsing-only", "persistent",
             "reduce-hints", "reducible", "tactic-hints", "visible", "wf", "whnf", "simp", "congr",
             "symm", "trans", "refl", "trans-instance"
            ].join("|") +
            ")\\]"
    );

    var keywordOperators = (
        [].join("|")
    );

    var keywordMapper = this.$keywords = this.createKeywordMapper({
        "keyword.control" : keywordControls,
        "storage.type" : storageType,
        "keyword.operator" : keywordOperators,
        "variable.language": "sorry"
    }, "identifier");

    var identifierRe = "[A-Za-z_\u03b1-\u03ba\u03bc-\u03fb\u1f00-\u1ffe\u2100-\u214f][A-Za-z0-9_'\u03b1-\u03ba\u03bc-\u03fb\u1f00-\u1ffe\u2070-\u2079\u207f-\u2089\u2090-\u209c\u2100-\u214f.]*";
    var operatorRe = new RegExp(["#", "@", "->", "∼", "↔", "/", "==", "=", ":=", "<->",
                                 "/\\", "\\/", "∧", "∨", "≠", "<", ">", "≤", "≥", "¬",
                                 "<=", ">=", "⁻¹", "⬝", "▸", "\\+", "\\*", "-", "/",
                                 "λ", "→", "∃", "∀", ":="].join("|"));
    // regexp must not have capturing parentheses. Use (?:) instead.
    // regexps are ordered -> the first match is used

    this.$rules = {
        "start" : [
            {
                token : "comment", // single line comment "--"
                regex : "--.*$"
            },
            DocCommentHighlightRules.getStartRule("doc-start"),
            {
                token : "comment", // multi line comment "/-"
                regex : "\\/-",
                next : "comment"
            }, {
                stateName: "qqstring",
                token : "string.start", regex : '"', next : [
                    {token : "string.end", regex : '"', next : "start"},
                    {token : "constant.language.escape", regex : /\\[n"\\]/},
                    {defaultToken: "string"}
                ]
            }, {
                token : "keyword.control", regex : 'constants\\b', next : [
                    {token : "variable.language", regex : identifierRe + '[^:]*', next : "start"} ]
            }, {
                token : "keyword.control", regex : nameProviders, next : [
                    {token : "variable.language", regex : identifierRe, next : "start"} ]
            }, {
                token : "constant.numeric", // hex
                regex : "0[xX][0-9a-fA-F]+(L|l|UL|ul|u|U|F|f|ll|LL|ull|ULL)?\\b"
            }, {
                token : "constant.numeric", // float
                regex : "[+-]?\\d+(?:(?:\\.\\d*)?(?:[eE][+-]?\\d+)?)?(L|l|UL|ul|u|U|F|f|ll|LL|ull|ULL)?\\b"
            }, {
                token : "storage.modifier",
                regex : storageModifiers
            }, {
                token : keywordMapper,
                regex : identifierRe
            }, {
                token : "operator",
                regex : operatorRe
            }, {
              token : "punctuation.operator",
              regex : "\\?|\\:|\\,|\\;|\\."
            }, {
                token : "paren.lparen",
                regex : "[[({]"
            }, {
                token : "paren.rparen",
                regex : "[\\])}]"
            }, {
                token : "text",
                regex : "\\s+"
            }
        ],
        "comment" : [ {token: "comment", regex: "-/", next: "start"},
                      {defaultToken: "comment"} ]
    };

    this.embedRules(DocCommentHighlightRules, "doc-",
        [ DocCommentHighlightRules.getEndRule("start") ]);
    this.normalizeRules();
};

oop.inherits(leanHighlightRules, TextHighlightRules);

exports.leanHighlightRules = leanHighlightRules;
});
<commit_msg>remove "to" from keyword list<commit_after>/* ***** BEGIN LICENSE BLOCK *****
 * Distributed under the BSD license:
 *
 * Copyright (c) 2010, Ajax.org B.V.
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are met:
 *     * Redistributions of source code must retain the above copyright
 *       notice, this list of conditions and the following disclaimer.
 *     * Redistributions in binary form must reproduce the above copyright
 *       notice, this list of conditions and the following disclaimer in the
 *       documentation and/or other materials provided with the distribution.
 *     * Neither the name of Ajax.org B.V. nor the
 *       names of its contributors may be used to endorse or promote products
 *       derived from this software without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
 * DISCLAIMED. IN NO EVENT SHALL AJAX.ORG B.V. BE LIABLE FOR ANY
 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 *
 * ***** END LICENSE BLOCK ***** */

define(function(require, exports, module) {
"use strict";

var oop = require("../lib/oop");
var DocCommentHighlightRules = require("./doc_comment_highlight_rules").DocCommentHighlightRules;
var TextHighlightRules = require("./text_highlight_rules").TextHighlightRules;

var leanHighlightRules = function() {

    var keywordControls = (
        [ "alias", "as", "assert", "assume", "at", "attribute", "axioms",
          "begin", "by", "calc", "check", "noncomputable",
          "classes", "coercions", "conjecture", "context",
          "corollary", "else", "end", "environment", "eval", "example",
          "exists", "exit", "export", "exposing", "extends", "fields", "find_decl",
          "forall", "from", "fun", "have", "help", "hiding", "if",
          "import", "in", "include", "infix", "infixl", "infixr", "instances",
          "let", "local", "match", "migrate", "namespace", "notation", "obtain",
          "omit", "opaque", "open", "options", "parameter", "parameters", "postfix",
          "precedence", "prefix", "prelude", "premise", "premises", "print", "private", "proof",
          "protected", "qed", "raw", "renaming", "replacing", "reserve", "reveal", "section", "set_option",
          "show", "suffices", "suppose", "tactic_infix", "tactic_infixl", "tactic_infixr", "tactic_hint",
          "tactic_notation", "tactic_postfix", "tactic_prefix",
          "take", "then", "this", "universe",
          "universes", "using", "variable", "variables", "with"].join("|")
    );

    var nameProviders = (
        ["inductive\\b", "structure\\b", "record\\b", "theorem\\b", "axiom\\b", "corollary\\b",
         "conjecture\\b", "abbreviation\\b", "lemma\\b", "hypothesis\\b", "definition\\b",
         "constant\\b", "premise\\b"].join("|")
    );

    var storageType = (
        ["Prop", "Type", "Type'", "Type₊", "Type₁", "Type₂", "Type₃"].join("|")
    );

    var storageModifiers = (
        "\\[(" +
            ["abbreviations", "begin-end-hints", "class", "classes", "coercion", "unfold", "unfold-full",
             "coercions", "declarations", "decls", "instance", "irreducible", "recursor",
             "multiple-instances", "notation", "notations", "parsing-only", "persistent",
             "reduce-hints", "reducible", "tactic-hints", "visible", "wf", "whnf", "simp", "congr",
             "symm", "trans", "refl", "trans-instance"
            ].join("|") +
            ")\\]"
    );

    var keywordOperators = (
        [].join("|")
    );

    var keywordMapper = this.$keywords = this.createKeywordMapper({
        "keyword.control" : keywordControls,
        "storage.type" : storageType,
        "keyword.operator" : keywordOperators,
        "variable.language": "sorry"
    }, "identifier");

    var identifierRe = "[A-Za-z_\u03b1-\u03ba\u03bc-\u03fb\u1f00-\u1ffe\u2100-\u214f][A-Za-z0-9_'\u03b1-\u03ba\u03bc-\u03fb\u1f00-\u1ffe\u2070-\u2079\u207f-\u2089\u2090-\u209c\u2100-\u214f.]*";
    var operatorRe = new RegExp(["#", "@", "->", "∼", "↔", "/", "==", "=", ":=", "<->",
                                 "/\\", "\\/", "∧", "∨", "≠", "<", ">", "≤", "≥", "¬",
                                 "<=", ">=", "⁻¹", "⬝", "▸", "\\+", "\\*", "-", "/",
                                 "λ", "→", "∃", "∀", ":="].join("|"));
    // regexp must not have capturing parentheses. Use (?:) instead.
    // regexps are ordered -> the first match is used

    this.$rules = {
        "start" : [
            {
                token : "comment", // single line comment "--"
                regex : "--.*$"
            },
            DocCommentHighlightRules.getStartRule("doc-start"),
            {
                token : "comment", // multi line comment "/-"
                regex : "\\/-",
                next : "comment"
            }, {
                stateName: "qqstring",
                token : "string.start", regex : '"', next : [
                    {token : "string.end", regex : '"', next : "start"},
                    {token : "constant.language.escape", regex : /\\[n"\\]/},
                    {defaultToken: "string"}
                ]
            }, {
                token : "keyword.control", regex : 'constants\\b', next : [
                    {token : "variable.language", regex : identifierRe + '[^:]*', next : "start"} ]
            }, {
                token : "keyword.control", regex : nameProviders, next : [
                    {token : "variable.language", regex : identifierRe, next : "start"} ]
            }, {
                token : "constant.numeric", // hex
                regex : "0[xX][0-9a-fA-F]+(L|l|UL|ul|u|U|F|f|ll|LL|ull|ULL)?\\b"
            }, {
                token : "constant.numeric", // float
                regex : "[+-]?\\d+(?:(?:\\.\\d*)?(?:[eE][+-]?\\d+)?)?(L|l|UL|ul|u|U|F|f|ll|LL|ull|ULL)?\\b"
            }, {
                token : "storage.modifier",
                regex : storageModifiers
            }, {
                token : keywordMapper,
                regex : identifierRe
            }, {
                token : "operator",
                regex : operatorRe
            }, {
              token : "punctuation.operator",
              regex : "\\?|\\:|\\,|\\;|\\."
            }, {
                token : "paren.lparen",
                regex : "[[({]"
            }, {
                token : "paren.rparen",
                regex : "[\\])}]"
            }, {
                token : "text",
                regex : "\\s+"
            }
        ],
        "comment" : [ {token: "comment", regex: "-/", next: "start"},
                      {defaultToken: "comment"} ]
    };

    this.embedRules(DocCommentHighlightRules, "doc-",
        [ DocCommentHighlightRules.getEndRule("start") ]);
    this.normalizeRules();
};

oop.inherits(leanHighlightRules, TextHighlightRules);

exports.leanHighlightRules = leanHighlightRules;
});
<|endoftext|>


<commit_before>var Web3 = require('web3');
var web3 = new Web3();
web3.setProvider(new web3.providers.HttpProvider('http://localhost:8545'));
var blobstoreAbi = require('./blobstore.abi.json');
var blobstoreContract = web3.eth.contract(blobstoreAbi);
var blobstoreAddress = '0x8f3fae469b08e48d8e2a692e0b9805c38509231b';
var blobstore = blobstoreContract.at(blobstoreAddress);

// solc version: 0.2.0-0/Release-Linux/g++/int linked to libethereum-1.1.0-0/Release-Linux/g++/int

var getBlobHash = function(blob) {
  return '0x' + web3.sha3(blob.toString('hex'), {encoding: 'hex'});
}

var getBlobBlock = function(hash) {
  // Determine the block that includes the transaction for this blob.
  return blobstore.getBlobBlock(hash, {}, 'latest').toNumber();
}

var storeBlob = function(blob) {
  // Determine hash of blob.
  var hash = getBlobHash(blob);
  // Check if this blob is in a block yet.
  if (getBlobBlock(hash) == 0) {
    // Calculate maximum transaction gas.
    var gas = 44800 + 78 * blob.length;
    // Broadcast the transaction. If this blob is already in a pending
    // transaction, or has just been mined, this will be handled by the
    // contract.
    blobstore.storeBlob('0x' + blob.toString('hex'), {gas: gas});
  }
  return hash;
}

var getBlob = function(hash, callback) {
  var blobBlock = getBlobBlock(hash);
  if (blobBlock == 0) {
    // The blob isn't in a block yet. See if it is in a pending transaction.
    var txids = web3.eth.getBlock('pending').transactions;
    for (var i in txids) {
      var tx = web3.eth.getTransaction(txids[i]);
      if (tx.to != blobstoreAddress) {
        continue;
      }
      // Extract the blob from the transaction.
      var length = parseInt(tx.input.substr(74, 64), 16);
      var blob = new Buffer(tx.input.substr(138, length * 2), 'hex');
      // Does it have the correct hash?
      if (getBlobHash(blob) == hash) {
        callback(null, blob);
        return;
      }
    }
    // We didn't find the blob. Check in the blocks one more time in case it
    // just got mined and we missed it.
    blobBlock = getBlobBlock(hash);
    if (blobBlock == 0) {
      // We didn't find it. Report the Error.
      callback('error');
      return;
    }
  }
  // If the blob is in a block that occured within the past hour, search from an
  // hour ago until the latest block in case there has been a re-arragement
  // since we got the block number (very conservative).
  var fromBlock, toBlock;
  if (blobBlock > web3.eth.blockNumber - 200) {
    fromBlock = web3.eth.blockNumber - 200;
    toBlock = 'latest';
  }
  else {
    fromBlock = toBlock = blobBlock;
  }
  var filter = web3.eth.filter({fromBlock: fromBlock, toBlock: toBlock, address: blobstoreAddress, topics: [hash]});
  filter.get(function(error, result) {
    if (result.length != 0) {
      var length = parseInt(result[0].data.substr(66, 64), 16);
      callback(null, new Buffer(result[0].data.substr(130, length * 2), 'hex'));
    }
    else {
      // There has just been a re-arrangement and the trasaction is now back to
      // pending. Let's try again from the start.
      getBlob(hash, callback);
    }
  });
}

module.exports = {
  getBlobHash: getBlobHash,
  getBlobBlock: getBlobBlock,
  storeBlob: storeBlob,
  getBlob: getBlob
};
<commit_msg>Add a comment about only being able to retrive blobs from pending transactions if the blob was stored directly by a transaction.<commit_after>var Web3 = require('web3');
var web3 = new Web3();
web3.setProvider(new web3.providers.HttpProvider('http://localhost:8545'));
var blobstoreAbi = require('./blobstore.abi.json');
var blobstoreContract = web3.eth.contract(blobstoreAbi);
var blobstoreAddress = '0x8f3fae469b08e48d8e2a692e0b9805c38509231b';
var blobstore = blobstoreContract.at(blobstoreAddress);

// solc version: 0.2.0-0/Release-Linux/g++/int linked to libethereum-1.1.0-0/Release-Linux/g++/int

var getBlobHash = function(blob) {
  return '0x' + web3.sha3(blob.toString('hex'), {encoding: 'hex'});
}

var getBlobBlock = function(hash) {
  // Determine the block that includes the transaction for this blob.
  return blobstore.getBlobBlock(hash, {}, 'latest').toNumber();
}

var storeBlob = function(blob) {
  // Determine hash of blob.
  var hash = getBlobHash(blob);
  // Check if this blob is in a block yet.
  if (getBlobBlock(hash) == 0) {
    // Calculate maximum transaction gas.
    var gas = 44800 + 78 * blob.length;
    // Broadcast the transaction. If this blob is already in a pending
    // transaction, or has just been mined, this will be handled by the
    // contract.
    blobstore.storeBlob('0x' + blob.toString('hex'), {gas: gas});
  }
  return hash;
}

var getBlob = function(hash, callback) {
  var blobBlock = getBlobBlock(hash);
  if (blobBlock == 0) {
    // The blob isn't in a block yet. See if it is in a pending transaction.
    // This will only work if the blob was stored directly by a transaction.
    var txids = web3.eth.getBlock('pending').transactions;
    for (var i in txids) {
      var tx = web3.eth.getTransaction(txids[i]);
      if (tx.to != blobstoreAddress) {
        continue;
      }
      // Extract the blob from the transaction.
      var length = parseInt(tx.input.substr(74, 64), 16);
      var blob = new Buffer(tx.input.substr(138, length * 2), 'hex');
      // Does it have the correct hash?
      if (getBlobHash(blob) == hash) {
        callback(null, blob);
        return;
      }
    }
    // We didn't find the blob. Check in the blocks one more time in case it
    // just got mined and we missed it.
    blobBlock = getBlobBlock(hash);
    if (blobBlock == 0) {
      // We didn't find it. Report the Error.
      callback('error');
      return;
    }
  }
  // If the blob is in a block that occured within the past hour, search from an
  // hour ago until the latest block in case there has been a re-arragement
  // since we got the block number (very conservative).
  var fromBlock, toBlock;
  if (blobBlock > web3.eth.blockNumber - 200) {
    fromBlock = web3.eth.blockNumber - 200;
    toBlock = 'latest';
  }
  else {
    fromBlock = toBlock = blobBlock;
  }
  var filter = web3.eth.filter({fromBlock: fromBlock, toBlock: toBlock, address: blobstoreAddress, topics: [hash]});
  filter.get(function(error, result) {
    if (result.length != 0) {
      var length = parseInt(result[0].data.substr(66, 64), 16);
      callback(null, new Buffer(result[0].data.substr(130, length * 2), 'hex'));
    }
    else {
      // There has just been a re-arrangement and the trasaction is now back to
      // pending. Let's try again from the start.
      getBlob(hash, callback);
    }
  });
}

module.exports = {
  getBlobHash: getBlobHash,
  getBlobBlock: getBlobBlock,
  storeBlob: storeBlob,
  getBlob: getBlob
};
<|endoftext|>


<commit_before>/* ***** BEGIN LICENSE BLOCK *****
 * Distributed under the BSD license:
 *
 * Copyright (c) 2010, Ajax.org B.V.
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are met:
 *     * Redistributions of source code must retain the above copyright
 *       notice, this list of conditions and the following disclaimer.
 *     * Redistributions in binary form must reproduce the above copyright
 *       notice, this list of conditions and the following disclaimer in the
 *       documentation and/or other materials provided with the distribution.
 *     * Neither the name of Ajax.org B.V. nor the
 *       names of its contributors may be used to endorse or promote products
 *       derived from this software without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
 * DISCLAIMED. IN NO EVENT SHALL AJAX.ORG B.V. BE LIABLE FOR ANY
 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 *
 * ***** END LICENSE BLOCK ***** */

define(function(require, exports, module) {
"use strict";

var oop = require("../lib/oop");
var TextHighlightRules = require("./text_highlight_rules").TextHighlightRules;

var YamlHighlightRules = function() {

    // regexp must not have capturing parentheses. Use (?:) instead.
    // regexps are ordered -> the first match is used
    this.$rules = {
        "start" : [
            {
                token : "comment",
                regex : "#.*$"
            }, {
                token : "list.markup",
                regex : /^(?:-{3}|\.{3})\s*(?=#|$)/
            },  {
                token : "list.markup",
                regex : /^\s*[\-?](?:$|\s)/
            }, {
                token: "constant",
                regex: "!![\\w//]+"
            }, {
                token: "constant.language",
                regex: "[&\\*][a-zA-Z0-9-_]+"
            }, {
                token: ["meta.tag", "keyword"],
                regex: /^(\s*\w.*?)(\:(?:\s+|$))/
            },{
                token: ["meta.tag", "keyword"],
                regex: /(\w+?)(\s*\:(?:\s+|$))/
            }, {
                token : "keyword.operator",
                regex : "<<\\w*:\\w*"
            }, {
                token : "keyword.operator",
                regex : "-\\s*(?=[{])"
            }, {
                token : "string", // single line
                regex : '["](?:(?:\\\\.)|(?:[^"\\\\]))*?["]'
            }, {
                token : "string", // multi line string start
                regex : '[\\|>]\\w*',
                next : "qqstring"
            }, {
                token : "string", // single quoted string
                regex : "['](?:(?:\\\\.)|(?:[^'\\\\]))*?[']"
            }, {
                token : "constant.numeric", // float
                regex : /[+\-]?[\d_]+(?:(?:\.[\d_]*)?(?:[eE][+\-]?[\d_]+)?)?\b/
            }, {
                token : "constant.numeric", // other number
                regex : /[+\-]?\.inf\b|NaN\b|0x[\dA-Fa-f_]+|0b[10_]+/
            }, {
                token : "constant.language.boolean",
                regex : "(?:true|false|TRUE|FALSE|True|False|yes|no)\\b"
            }, {
                token : "invalid.illegal", // comments are not allowed
                regex : "\\/\\/.*$"
            }, {
                token : "paren.lparen",
                regex : "[[({]"
            }, {
                token : "paren.rparen",
                regex : "[\\])}]"
            }
        ],
        "qqstring" : [
            {
                token : "string",
                regex : '(?=(?:(?:\\\\.)|(?:[^:]))*?:)',
                next : "start"
            }, {
                token : "string",
                regex : '.+'
            }
        ]};

};

oop.inherits(YamlHighlightRules, TextHighlightRules);

exports.YamlHighlightRules = YamlHighlightRules;
});
<commit_msg>fix #1598 Pipe '|' symbol breaks YAML Syntax highlighting<commit_after>/* ***** BEGIN LICENSE BLOCK *****
 * Distributed under the BSD license:
 *
 * Copyright (c) 2010, Ajax.org B.V.
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are met:
 *     * Redistributions of source code must retain the above copyright
 *       notice, this list of conditions and the following disclaimer.
 *     * Redistributions in binary form must reproduce the above copyright
 *       notice, this list of conditions and the following disclaimer in the
 *       documentation and/or other materials provided with the distribution.
 *     * Neither the name of Ajax.org B.V. nor the
 *       names of its contributors may be used to endorse or promote products
 *       derived from this software without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
 * DISCLAIMED. IN NO EVENT SHALL AJAX.ORG B.V. BE LIABLE FOR ANY
 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 *
 * ***** END LICENSE BLOCK ***** */

define(function(require, exports, module) {
"use strict";

var oop = require("../lib/oop");
var TextHighlightRules = require("./text_highlight_rules").TextHighlightRules;

var YamlHighlightRules = function() {

    // regexp must not have capturing parentheses. Use (?:) instead.
    // regexps are ordered -> the first match is used
    this.$rules = {
        "start" : [
            {
                token : "comment",
                regex : "#.*$"
            }, {
                token : "list.markup",
                regex : /^(?:-{3}|\.{3})\s*(?=#|$)/
            },  {
                token : "list.markup",
                regex : /^\s*[\-?](?:$|\s)/
            }, {
                token: "constant",
                regex: "!![\\w//]+"
            }, {
                token: "constant.language",
                regex: "[&\\*][a-zA-Z0-9-_]+"
            }, {
                token: ["meta.tag", "keyword"],
                regex: /^(\s*\w.*?)(\:(?:\s+|$))/
            },{
                token: ["meta.tag", "keyword"],
                regex: /(\w+?)(\s*\:(?:\s+|$))/
            }, {
                token : "keyword.operator",
                regex : "<<\\w*:\\w*"
            }, {
                token : "keyword.operator",
                regex : "-\\s*(?=[{])"
            }, {
                token : "string", // single line
                regex : '["](?:(?:\\\\.)|(?:[^"\\\\]))*?["]'
            }, {
                token : "string", // multi line string start
                regex : '[|>][-+\\d\\s]*$',
                next : "qqstring"
            }, {
                token : "string", // single quoted string
                regex : "['](?:(?:\\\\.)|(?:[^'\\\\]))*?[']"
            }, {
                token : "constant.numeric", // float
                regex : /[+\-]?[\d_]+(?:(?:\.[\d_]*)?(?:[eE][+\-]?[\d_]+)?)?\b/
            }, {
                token : "constant.numeric", // other number
                regex : /[+\-]?\.inf\b|NaN\b|0x[\dA-Fa-f_]+|0b[10_]+/
            }, {
                token : "constant.language.boolean",
                regex : "(?:true|false|TRUE|FALSE|True|False|yes|no)\\b"
            }, {
                token : "invalid.illegal", // comments are not allowed
                regex : "\\/\\/.*$"
            }, {
                token : "paren.lparen",
                regex : "[[({]"
            }, {
                token : "paren.rparen",
                regex : "[\\])}]"
            }
        ],
        "qqstring" : [
            {
                token : "string",
                regex : '(?=(?:(?:\\\\.)|(?:[^:]))*?:)',
                next : "start"
            }, {
                token : "string",
                regex : '.+'
            }
        ]};

};

oop.inherits(YamlHighlightRules, TextHighlightRules);

exports.YamlHighlightRules = YamlHighlightRules;
});
<|endoftext|>


<commit_before>'use strict';

const CHC = require('..');

const validate = require('har-validator');

const assert = require('assert');
const url = require('url');
const zlib = require('zlib');

function checkedRun({done, urls, options = {}, expected, check}) {
    let nLoad = 0;
    let nDone = 0;
    let nFail = 0;
    let nPreHook = 0;
    let nPostHook = 0;
    const events = [];
    options.content = true;
    options.preHook = async (url, client, index, _urls) => {
        // ignore certificate errors (requires Chrome 59) because
        // --ignore-certificate-errors doesn't work in headless mode
        const {Security} = client;
        await Security.enable();
        await Security.setOverrideCertificateErrors({override: true});
        Security.certificateError(({eventId}) => {
            Security.handleCertificateError({eventId, action: 'continue'});
        });

        nPreHook++;
        events.push('preHook');
        try {
            assert.strictEqual(typeof url, 'string');
            assert.strictEqual(typeof client.close, 'function');
            assert.strictEqual(urls[index], url);
            assert.deepStrictEqual(_urls, urls);
        } catch (err) {
            done(err);
        }
    };
    options.postHook = (url, client, index, _urls) => {
        nPostHook++;
        events.push('postHook');
        try {
            assert.strictEqual(typeof url, 'string');
            assert.strictEqual(typeof client.close, 'function');
            assert.strictEqual(_urls[index], url);
            assert.deepStrictEqual(_urls, urls);
        } catch (err) {
            done(err);
        }
    };
    CHC.run(
        urls,
        options
    ).on('load', (url, index, _urls) => {
        nLoad++;
        try {
            assert.strictEqual(typeof url, 'string');
            assert.strictEqual(_urls[index], url);
            assert.deepStrictEqual(_urls, urls);
        } catch (err) {
            done(err);
        }
    }).on('done', (url, index, _urls) => {
        nDone++;
        try {
            assert.strictEqual(typeof url, 'string');
            assert.strictEqual(_urls[index], url);
            assert.deepStrictEqual(_urls, urls);
        } catch (err) {
            done(err);
        }
    }).on('fail', (url, err, index, _urls) => {
        nFail++;
        try {
            assert.strictEqual(typeof url, 'string');
            assert(err instanceof Error);
            assert.strictEqual(_urls[index], url);
            assert.deepStrictEqual(_urls, urls);
        } catch (err) {
            done(err);
        }
    }).on('har', async (har) => {
        try {
            // check HAR syntax
            await validate.har(har);
            // custom expected counts
            if (expected) {
                assert.strictEqual(nLoad, expected.nLoad, 'load');
                assert.strictEqual(nDone, expected.nDone, 'done');
                assert.strictEqual(nFail, expected.nFail, 'fail');
                assert.strictEqual(nPreHook, expected.nPreHook, 'preHook');
                assert.strictEqual(nPostHook, expected.nPostHook, 'postHook');
                assert.strictEqual(har.log.pages.length, expected.nPages, 'pages');
                assert.strictEqual(har.log.entries.length, expected.nEntries, 'entries');
            }
            // custom check function
            if (check) {
                await check(events, har);
            }
            // finally done
            done();
        } catch (err) {
            if (err.name === 'HARError') {
                console.error(JSON.stringify(har, null, 4));
                console.error(JSON.stringify(err.errors, null, 4));
            }
            done(err);
        }
    });
}

function data(size) {
    return Buffer.alloc(size, 'x');
}

function testServerHandler(request, response) {
    const urlObject = url.parse(request.url, true);
    switch (urlObject.pathname) {
    case '/get':
        {
            response.end();
        }
        break;
    case '/generate_post':
        {
            const type = urlObject.query.type;
            response.setHeader('content-type', 'text/html');
            response.end(`<form id="form" method="POST" action="/post" enctype="${type}"><input name="name" value="value"/></form><script>form.submit();</script>`);
        }
        break;
    case '/post':
        {
            response.end();
        }
        break;
    case '/generate_204':
        {
            response.setHeader('content-type', 'text/html');
            response.end('');
        }
        break;
    case '/204':
        {
            response.writeHead(204);
            response.end();
        }
        break;
    case '/generate_404':
        {
            response.setHeader('content-type', 'text/html');
            response.end(`
                          <link rel="stylesheet" href="/404.css">`);
        }
        break;
    case '/data':
        {
            const size = Number(urlObject.query.size);
            const chunks = Number(urlObject.query.chunks);
            const gzip = !!(urlObject.query.gzip);
            const send = (chunk, end) => {
                if (end) {
                    response.end(chunk);
                } else {
                    response.write(chunk);
                }
            };
            // enable compression
            if (gzip) {
                response.setHeader('content-encoding', 'gzip');
                const gzipStream = zlib.createGzip();
                gzipStream.pipe(response);
                response = gzipStream;
            }
            // trasfer-encoding: chunked
            if (chunks) {
                for (let i = 0; i < chunks; i++) {
                    const chunk = data(size);
                    send(chunk, false);
                }
                response.end();
            }
            // set content-length
            else {
                const chunk = data(size);
                send(chunk, true);
            }
        }
        break;
    case '/redirect':
        {
            const n = Number(urlObject.query.n);
            const size = Number(urlObject.query.size);
            if (n) {
                response.writeHead(302, {
                    location: `/redirect?n=${n - 1}&size=${size}`
                });
                response.end();
            } else {
                const chunk = data(size);
                response.end(chunk);
            }
        }
        break;
    default:
        {
            response.writeHead(404);
            response.end();
        }
    }
}

module.exports = {checkedRun, testServerHandler};
<commit_msg>Do not swallow unexpected errors in tests<commit_after>'use strict';

const CHC = require('..');

const validate = require('har-validator');

const assert = require('assert');
const url = require('url');
const zlib = require('zlib');

function checkedRun({done, urls, options = {}, expected, check}) {
    let nLoad = 0;
    let nDone = 0;
    let nFail = 0;
    let nPreHook = 0;
    let nPostHook = 0;
    const events = [];
    options.content = true;
    options.preHook = async (url, client, index, _urls) => {
        // ignore certificate errors (requires Chrome 59) because
        // --ignore-certificate-errors doesn't work in headless mode
        const {Security} = client;
        await Security.enable();
        await Security.setOverrideCertificateErrors({override: true});
        Security.certificateError(({eventId}) => {
            Security.handleCertificateError({eventId, action: 'continue'});
        });

        nPreHook++;
        events.push('preHook');
        try {
            assert.strictEqual(typeof url, 'string');
            assert.strictEqual(typeof client.close, 'function');
            assert.strictEqual(urls[index], url);
            assert.deepStrictEqual(_urls, urls);
        } catch (err) {
            done(err);
        }
    };
    options.postHook = (url, client, index, _urls) => {
        nPostHook++;
        events.push('postHook');
        try {
            assert.strictEqual(typeof url, 'string');
            assert.strictEqual(typeof client.close, 'function');
            assert.strictEqual(_urls[index], url);
            assert.deepStrictEqual(_urls, urls);
        } catch (err) {
            done(err);
        }
    };
    CHC.run(
        urls,
        options
    ).on('load', (url, index, _urls) => {
        nLoad++;
        try {
            assert.strictEqual(typeof url, 'string');
            assert.strictEqual(_urls[index], url);
            assert.deepStrictEqual(_urls, urls);
        } catch (err) {
            done(err);
        }
    }).on('done', (url, index, _urls) => {
        nDone++;
        try {
            assert.strictEqual(typeof url, 'string');
            assert.strictEqual(_urls[index], url);
            assert.deepStrictEqual(_urls, urls);
        } catch (err) {
            done(err);
        }
    }).on('fail', (url, err, index, _urls) => {
        // do not swallow unexpected errors
        if (!expected) {
            console.log(err);
        }

        nFail++;
        try {
            assert.strictEqual(typeof url, 'string');
            assert(err instanceof Error);
            assert.strictEqual(_urls[index], url);
            assert.deepStrictEqual(_urls, urls);
        } catch (err) {
            done(err);
        }
    }).on('har', async (har) => {
        try {
            // check HAR syntax
            await validate.har(har);
            // custom expected counts
            if (expected) {
                assert.strictEqual(nLoad, expected.nLoad, 'load');
                assert.strictEqual(nDone, expected.nDone, 'done');
                assert.strictEqual(nFail, expected.nFail, 'fail');
                assert.strictEqual(nPreHook, expected.nPreHook, 'preHook');
                assert.strictEqual(nPostHook, expected.nPostHook, 'postHook');
                assert.strictEqual(har.log.pages.length, expected.nPages, 'pages');
                assert.strictEqual(har.log.entries.length, expected.nEntries, 'entries');
            }
            // custom check function
            if (check) {
                await check(events, har);
            }
            // finally done
            done();
        } catch (err) {
            if (err.name === 'HARError') {
                console.error(JSON.stringify(har, null, 4));
                console.error(JSON.stringify(err.errors, null, 4));
            }
            done(err);
        }
    });
}

function data(size) {
    return Buffer.alloc(size, 'x');
}

function testServerHandler(request, response) {
    const urlObject = url.parse(request.url, true);
    switch (urlObject.pathname) {
    case '/get':
        {
            response.end();
        }
        break;
    case '/generate_post':
        {
            const type = urlObject.query.type;
            response.setHeader('content-type', 'text/html');
            response.end(`<form id="form" method="POST" action="/post" enctype="${type}"><input name="name" value="value"/></form><script>form.submit();</script>`);
        }
        break;
    case '/post':
        {
            response.end();
        }
        break;
    case '/generate_204':
        {
            response.setHeader('content-type', 'text/html');
            response.end('');
        }
        break;
    case '/204':
        {
            response.writeHead(204);
            response.end();
        }
        break;
    case '/generate_404':
        {
            response.setHeader('content-type', 'text/html');
            response.end(`
                          <link rel="stylesheet" href="/404.css">`);
        }
        break;
    case '/data':
        {
            const size = Number(urlObject.query.size);
            const chunks = Number(urlObject.query.chunks);
            const gzip = !!(urlObject.query.gzip);
            const send = (chunk, end) => {
                if (end) {
                    response.end(chunk);
                } else {
                    response.write(chunk);
                }
            };
            // enable compression
            if (gzip) {
                response.setHeader('content-encoding', 'gzip');
                const gzipStream = zlib.createGzip();
                gzipStream.pipe(response);
                response = gzipStream;
            }
            // trasfer-encoding: chunked
            if (chunks) {
                for (let i = 0; i < chunks; i++) {
                    const chunk = data(size);
                    send(chunk, false);
                }
                response.end();
            }
            // set content-length
            else {
                const chunk = data(size);
                send(chunk, true);
            }
        }
        break;
    case '/redirect':
        {
            const n = Number(urlObject.query.n);
            const size = Number(urlObject.query.size);
            if (n) {
                response.writeHead(302, {
                    location: `/redirect?n=${n - 1}&size=${size}`
                });
                response.end();
            } else {
                const chunk = data(size);
                response.end(chunk);
            }
        }
        break;
    default:
        {
            response.writeHead(404);
            response.end();
        }
    }
}

module.exports = {checkedRun, testServerHandler};
<|endoftext|>


<commit_before>(function() {

  // When testing alternative View implementations, change this varaible.
  var View = Backbone.View;

  var view;

  module("Backbone.View", {

    setup: function() {
      view = new View({
        id        : 'test-view',
        className : 'test-view',
        other     : 'non-special-option'
      });
    }

  });

  test("constructor", 3, function() {
    equal(view.el.id, 'test-view');
    equal(view.el.className, 'test-view');
    equal(view.el.other, void 0);
  });

  test("$", 2, function() {
    var view = new View;
    view.setElement('
test
');
    var result = view.$('a b');

    strictEqual(result[0].innerHTML, 'test');
    ok(result.length === +result.length);
  });

  test("_setEl", 2, function() {
    view._setEl('
', {id: 'test-div'});

    equal(view.el.tagName.toLowerCase(), 'div');
    equal(view.el.id, 'test-div');
  });

  test("initialize", 1, function() {
    var Test = View.extend({
      initialize: function() {
        this.one = 1;
      }
    });

    strictEqual(new Test().one, 1);
  });

  test("delegateEvents", 6, function() {
    var counter1 = 0, counter2 = 0;

    view = new View({el: '#testElement'});
    view.increment = function(){ counter1++; };
    addEventListener.call(view.el, 'click', function(){ counter2++; });

    var events = {'click h1': 'increment'};

    view.delegateEvents(events);
    click(view.$('h1')[0]);
    equal(counter1, 1);
    equal(counter2, 1);

    click(view.$('h1')[0]);
    equal(counter1, 2);
    equal(counter2, 2);

    view.delegateEvents(events);
    click(view.$('h1')[0]);
    equal(counter1, 3);
    equal(counter2, 3);
  });

  test("delegate", 2, function() {
    var counter1 = 0, counter2 = 0;

    view = new View({el: '#testElement'});
    view.increment = function(){ counter1++; };
    view.delegate('click', function(){ counter2++; });

    view.delegate('click', 'h1', view.increment);
    view.delegate('click', view.increment);

    click(view.$('h1')[0]);
    equal(counter1, 2);
    equal(counter2, 1);
  });

  test("delegateEvents allows functions for callbacks", 3, function() {
    view = new View({el: '

'});
    view.counter = 0;

    var events = {
      click: function() {
        this.counter++;
      }
    };

    document.body.appendChild(view.el);

    view.delegateEvents(events);
    click(view.el);
    equal(view.counter, 1);

    click(view.el);
    equal(view.counter, 2);

    view.delegateEvents(events);
    click(view.el);
    equal(view.counter, 3);

    document.body.removeChild(view.el);
  });

  test("delegateEvents ignore undefined methods", 0, function() {
    view = new View({el: '

'});

    document.body.appendChild(view.el);

    view.delegateEvents({'click': 'undefinedMethod'});
    click(view.el);

    document.body.removeChild(view.el);
  });

  test("undelegateEvents", 6, function() {
    var counter1 = 0, counter2 = 0;

    view = new View({el: '#testElement'});
    view.increment = function(){ counter1++; };
    addEventListener.call(view.el, 'click', function(){ counter2++; });

    var events = {'click h1': 'increment'};

    view.delegateEvents(events);
    click(view.$('h1')[0]);
    equal(counter1, 1);
    equal(counter2, 1);

    view.undelegateEvents();
    click(view.$('h1')[0]);
    equal(counter1, 1);
    equal(counter2, 2);

    view.delegateEvents(events);
    click(view.$('h1')[0]);
    equal(counter1, 2);
    equal(counter2, 3);
  });

  test("_ensureElement with DOM node el", 1, function() {
    var Test = View.extend({
      el: document.body
    });

    equal(new Test().el, document.body);
  });

  test("_ensureElement with string el", 3, function() {
    var Test = View.extend({
      el: "body"
    });
    strictEqual(new Test().el, document.body);

    Test = View.extend({
      el: "#testElement > h1"
    });
    var h1 = _.filter(document.getElementById('testElement').childNodes, function(node) {
      return node.nodeType == 1;
    })[0];
    strictEqual(new Test().el, h1);

    Test = View.extend({
      el: "#nonexistent"
    });
    ok(!new Test().el);
  });

  test("with className and id functions", 2, function() {
    var Test = View.extend({
      className: function() {
        return 'className';
      },
      id: function() {
        return 'id';
      }
    });

    strictEqual(new Test().el.className, 'className');
    strictEqual(new Test().el.id, 'id');
  });

  test("with attributes", 2, function() {
    var Test = View.extend({
      attributes: {
        id: 'id',
        'class': 'class'
      }
    });

    strictEqual(new Test().el.className, 'class');
    strictEqual(new Test().el.id, 'id');
  });

  test("with attributes as a function", 1, function() {
    var Test = View.extend({
      attributes: function() {
        return {'class': 'dynamic'};
      }
    });

    strictEqual(new Test().el.className, 'dynamic');
  });

  test("multiple views per element", 3, function() {
    var count = 0;
    var el = document.createElement('p');

    var Test = View.extend({
      el: el,
      events: {
        click: function() {
          count++;
        }
      }
    });

    document.body.appendChild(el);

    var view1 = new Test;
    click(el);
    equal(1, count);

    var view2 = new Test;
    click(el);
    equal(3, count);

    view1.delegateEvents();
    click(el);
    equal(5, count);

    document.body.removeChild(el);
  });

  if (typeof Backbone.$ != 'undefined') {
    test("custom events, with namespaces", 2, function() {
      var count = 0;

      var Test = View.extend({
        el: $('body'),
        events: function() {
          return {"fake$event.namespaced": "run"};
        },
        run: function() {
          count++;
        }
      });

      var view = new Test;
      $('body').trigger('fake$event').trigger('fake$event');
      equal(count, 2);

      $('body').off('.namespaced');
      $('body').trigger('fake$event');
      equal(count, 2);

    });
  }

  test("#1048 - setElement uses provided object.", 2, function() {
    var el = document.body;

    view = new View({el: el});
    ok(view.el === el);

    view.setElement(el = document.body);
    ok(view.el === el);
  });

  test("#986 - Undelegate before changing element.", 1, function() {
    var button1 = document.createElement('button');
    var button2 = document.createElement('button');

    document.body.appendChild(button1);
    document.body.appendChild(button2);

    var Test = View.extend({
      events: {
        click: function(e) {
          ok(view.el === e.target || e.srcElement);
        }
      }
    });

    var view = new Test({el: button1});
    view.setElement(button2);

    click(button1);
    click(button2);

    document.body.removeChild(button1);
    document.body.removeChild(button2);
  });

  test("#1172 - Clone attributes object", 2, function() {
    var Test = View.extend({
      attributes: {foo: 'bar'}
    });

    var view1 = new Test({id: 'foo'});
    strictEqual(view1.el.id, 'foo');

    var view2 = new Test();
    ok(!view2.el.id);
  });

  test("#1228 - tagName can be provided as a function", 1, function() {
    var Test = View.extend({
      tagName: function() {
        return 'p';
      }
    });

    ok(new Test().el.tagName.toLowerCase() == 'p');
  });

  test("views stopListening", 0, function() {
    var Test = View.extend({
      initialize: function() {
        this.listenTo(this.model, 'all x', function(){ ok(false); });
        this.listenTo(this.collection, 'all x', function(){ ok(false); });
      }
    });

    var view = new Test({
      model: new Backbone.Model,
      collection: new Backbone.Collection
    });

    view.stopListening();
    view.model.trigger('x');
    view.collection.trigger('x');
  });

  test("Provide function for el.", 2, function() {
    var Test = View.extend({
      el: function() {
        return "

";
      }
    });

    var view = new Test;
    ok(view.el.tagName.toLowerCase() == 'p');
    ok(view.$('a').length != 0);
  });

  test("events passed in options", 1, function() {
    var counter = 0;

    var Test = View.extend({
      el: '#testElement',
      increment: function() {
        counter++;
      }
    });

    var view = new Test({
      events: {
        'click h1': 'increment'
      }
    });

    click(view.$('h1')[0]);
    click(view.$('h1')[0]);
    equal(counter, 2);
  });

  test("remove", 2, function() {
    document.body.appendChild(view.el);

    addEventListener.call(view.el, 'click', function() { ok(true); });
    view.delegate('click', function() { ok(false); });
    view.listenTo(view, 'all x', function() { ok(false); });

    view.remove();

    notEqual(view.el.parentNode, document.body);

    click(view.el);
    view.trigger('x');
  });

  test('_removeElement', 2, function() {
    var el = view.el;
    document.body.appendChild(view.el);
    view._removeElement();
    strictEqual(view.el, el);
    ok(!document.body.contains(view.el));
  });

  // Cross-browser helpers
  var addEventListener =
    typeof Element != 'undefined' && Element.prototype.addEventListener || function(eventName, listener) {
      return this.attachEvent('on' + eventName, listener);
    };

  function click(element) {
    var event;
    if (document.createEvent) {
      event = document.createEvent('MouseEvent');
      var args = [
        'click', true, true,
        // IE 10+ and Firefox require these
        event.view, event.detail, event.screenX, event.screenY, event.clientX,
        event.clientY, event.ctrlKey, event.altKey, event.shiftKey,
        event.metaKey, event.button, event.relatedTarget
      ];
      (event.initMouseEvent || event.initEvent).apply(event, args);
    } else {
      event = document.createEventObject();
      event.type = 'click';
      event.bubbles = true;
      event.cancelable = true;
    }

    if (element.dispatchEvent) {
      return element.dispatchEvent(event);
    }
    element.fireEvent('onclick', event);
  }

})();
<commit_msg>Revert "View conformance tests"<commit_after>(function() {

  var view;

  module("Backbone.View", {

    setup: function() {
      view = new Backbone.View({
        id        : 'test-view',
        className : 'test-view',
        other     : 'non-special-option'
      });
    }

  });

  test("constructor", 3, function() {
    equal(view.el.id, 'test-view');
    equal(view.el.className, 'test-view');
    equal(view.el.other, void 0);
  });

  test("$", 2, function() {
    var view = new Backbone.View;
    view.setElement('
test
');
    var result = view.$('a b');

    strictEqual(result[0].innerHTML, 'test');
    ok(result.length === +result.length);
  });

  test("jQuery", function() {
    var view = new Backbone.View;
    view.setElement('
test
');

    if (Backbone.$) {
      ok(view.$el instanceof Backbone.$);
      equal(view.$el[0], view.el);
    }
  });

  test("initialize", 1, function() {
    var View = Backbone.View.extend({
      initialize: function() {
        this.one = 1;
      }
    });

    strictEqual(new View().one, 1);
  });

  test("delegateEvents", 6, function() {
    var counter1 = 0, counter2 = 0;

    var view = new Backbone.View({el: '#testElement'});
    view.increment = function(){ counter1++; };
    view.$el.on('click', function(){ counter2++; });

    var events = {'click h1': 'increment'};

    view.delegateEvents(events);
    view.$('h1').trigger('click');
    equal(counter1, 1);
    equal(counter2, 1);

    view.$('h1').trigger('click');
    equal(counter1, 2);
    equal(counter2, 2);

    view.delegateEvents(events);
    view.$('h1').trigger('click');
    equal(counter1, 3);
    equal(counter2, 3);
  });

  test("delegate", 2, function() {
    var counter1 = 0, counter2 = 0;

    var view = new Backbone.View({el: '#testElement'});
    view.increment = function(){ counter1++; };
    view.$el.on('click', function(){ counter2++; });

    view.delegate('click', 'h1', view.increment);
    view.delegate('click', view.increment);

    view.$('h1').trigger('click');
    equal(counter1, 2);
    equal(counter2, 1);
  });

  test("delegateEvents allows functions for callbacks", 3, function() {
    var view = new Backbone.View({el: '

'});
    view.counter = 0;

    var events = {
      click: function() {
        this.counter++;
      }
    };

    view.delegateEvents(events);
    view.$el.trigger('click');
    equal(view.counter, 1);

    view.$el.trigger('click');
    equal(view.counter, 2);

    view.delegateEvents(events);
    view.$el.trigger('click');
    equal(view.counter, 3);
  });

  test("delegateEvents ignore undefined methods", 0, function() {
    var view = new Backbone.View({el: '

'});
    view.delegateEvents({'click': 'undefinedMethod'});
    view.$el.trigger('click');
  });

  test("undelegateEvents", 6, function() {
    var counter1 = 0, counter2 = 0;

    var view = new Backbone.View({el: '#testElement'});
    view.increment = function(){ counter1++; };
    view.$el.on('click', function(){ counter2++; });

    var events = {'click h1': 'increment'};

    view.delegateEvents(events);
    view.$('h1').trigger('click');
    equal(counter1, 1);
    equal(counter2, 1);

    view.undelegateEvents();
    view.$('h1').trigger('click');
    equal(counter1, 1);
    equal(counter2, 2);

    view.delegateEvents(events);
    view.$('h1').trigger('click');
    equal(counter1, 2);
    equal(counter2, 3);
  });

  test("_ensureElement with DOM node el", 1, function() {
    var View = Backbone.View.extend({
      el: document.body
    });

    equal(new View().el, document.body);
  });

  test("_ensureElement with string el", 3, function() {
    var View = Backbone.View.extend({
      el: "body"
    });
    strictEqual(new View().el, document.body);

    View = Backbone.View.extend({
      el: "#testElement > h1"
    });
    strictEqual(new View().el, $("#testElement > h1").get(0));

    View = Backbone.View.extend({
      el: "#nonexistent"
    });
    ok(!new View().el);
  });

  test("with className and id functions", 2, function() {
    var View = Backbone.View.extend({
      className: function() {
        return 'className';
      },
      id: function() {
        return 'id';
      }
    });

    strictEqual(new View().el.className, 'className');
    strictEqual(new View().el.id, 'id');
  });

  test("with attributes", 2, function() {
    var View = Backbone.View.extend({
      attributes: {
        id: 'id',
        'class': 'class'
      }
    });

    strictEqual(new View().el.className, 'class');
    strictEqual(new View().el.id, 'id');
  });

  test("with attributes as a function", 1, function() {
    var View = Backbone.View.extend({
      attributes: function() {
        return {'class': 'dynamic'};
      }
    });

    strictEqual(new View().el.className, 'dynamic');
  });

  test("multiple views per element", 3, function() {
    var count = 0;
    var $el = $('

');

    var View = Backbone.View.extend({
      el: $el,
      events: {
        click: function() {
          count++;
        }
      }
    });

    var view1 = new View;
    $el.trigger("click");
    equal(1, count);

    var view2 = new View;
    $el.trigger("click");
    equal(3, count);

    view1.delegateEvents();
    $el.trigger("click");
    equal(5, count);
  });

  test("custom events, with namespaces", 2, function() {
    var count = 0;

    var View = Backbone.View.extend({
      el: $('body'),
      events: function() {
        return {"fake$event.namespaced": "run"};
      },
      run: function() {
        count++;
      }
    });

    var view = new View;
    $('body').trigger('fake$event').trigger('fake$event');
    equal(count, 2);

    $('body').off('.namespaced');
    $('body').trigger('fake$event');
    equal(count, 2);
  });

  test("#1048 - setElement uses provided object.", 2, function() {
    var $el = $('body');

    var view = new Backbone.View({el: $el});
    ok(view.$el === $el);

    view.setElement($el = $($el));
    ok(view.$el === $el);
  });

  test("#986 - Undelegate before changing element.", 1, function() {
    var button1 = $('<button></button>');
    var button2 = $('<button></button>');

    var View = Backbone.View.extend({
      events: {
        click: function(e) {
          ok(view.el === e.target);
        }
      }
    });

    var view = new View({el: button1});
    view.setElement(button2);

    button1.trigger('click');
    button2.trigger('click');
  });

  test("#1172 - Clone attributes object", 2, function() {
    var View = Backbone.View.extend({
      attributes: {foo: 'bar'}
    });

    var view1 = new View({id: 'foo'});
    strictEqual(view1.el.id, 'foo');

    var view2 = new View();
    ok(!view2.el.id);
  });

  test("#1228 - tagName can be provided as a function", 1, function() {
    var View = Backbone.View.extend({
      tagName: function() {
        return 'p';
      }
    });

    ok(new View().el.tagName.toLowerCase() == 'p');
  });

  test("views stopListening", 0, function() {
    var View = Backbone.View.extend({
      initialize: function() {
        this.listenTo(this.model, 'all x', function(){ ok(false); });
        this.listenTo(this.collection, 'all x', function(){ ok(false); });
      }
    });

    var view = new View({
      model: new Backbone.Model,
      collection: new Backbone.Collection
    });

    view.stopListening();
    view.model.trigger('x');
    view.collection.trigger('x');
  });

  test("Provide function for el.", 2, function() {
    var View = Backbone.View.extend({
      el: function() {
        return "

";
      }
    });

    var view = new View;
    ok(view.el.tagName.toLowerCase() == 'p');
    ok(view.$('a').length != 0);
  });

  test("events passed in options", 1, function() {
    var counter = 0;

    var View = Backbone.View.extend({
      el: '#testElement',
      increment: function() {
        counter++;
      }
    });

    var view = new View({
      events: {
        'click h1': 'increment'
      }
    });

    view.$('h1').trigger('click').trigger('click');
    equal(counter, 2);
  });

  test("remove", 0, function() {
    document.body.appendChild(view.el);

    view.delegate('click', function() { ok(false); });
    view.listenTo(view, 'all x', function() { ok(false); });

    view.remove();

    view.$el.trigger('x');
    view.trigger('x');
  });

  test('_removeElement', 2, function() {
    var el = view.el;
    document.body.appendChild(view.el);
    view._removeElement();
    strictEqual(view.el, el);
    ok(!document.body.contains(view.el));
  });

})();
<|endoftext|>


<commit_before>var server = require("./server");
var tjbot = require('tjbot');
var constants = require('./config');
var AudioContext = require('web-audio-api').AudioContext
context = new AudioContext
var request = require("request");
var fs = require('fs');
var fileDir = process.cwd() + "/public/img/snaps"
var curImage = "";

// obtain our credentials from config.js
var credentials = constants.credentials;

// obtain user-specific config
var VOICE = constants.config.voice;
var WORKSPACEID = constants.config.conversationWorkspaceId;

// these are the hardware capabilities that TJ needs for this recipe
var hardware = ['microphone', 'speaker', 'led', 'servo'];

// Set up configuration paramters
var config = {
    verboseLogging: true, //enable console debugging
    servoPin: 7, // set servo pin
    cameraParams: {
        height: 720,
        width: 960,
        vflip: false,
        hflip: false
    } // setup my camera capture parameters
};

var listening = true;
var detectface = true;

// obtain our configs from config.js and merge with custom configs
config = Object.assign(constants.config, config);

// instantiate our TJBot!
var tj = new tjbot(hardware, config, credentials);

server.wss.on('connection', function connection(ws) {
    ws.on('message', function incoming(message) {
        message = JSON.parse(message)
        console.log("beee", (message));
        switch (message.event) {
            case 'wave':
                var prompt = "Waving my arm. Just for you. ";
                logSpeak("TJBot", prompt);
                wave(prompt)
                break;
            case 'dance':
                var prompt = "Sure. I'll play some music and dance.";
                logSpeak("TJBot", prompt);
                predance(prompt)
                break;
            case 'see':
                var prompt = "A moment. Let me look around.";
                logSpeak("TJBot", prompt);
                see(prompt)
                break;
            case 'seetext':
                var prompt = "Sure. Scanning for text in the image.";
                logSpeak("TJBot", prompt);
                seeText(prompt)
                break;
            case 'led':
                console.log("shinning led ", message.color)
                tj.shine(message.color);
                break;
            case 'speak':
                console.log("speaking ", message.value);
                logSpeak("you", message.value);
                converse(message.value);
                break;
            case 'listening':
                console.log("toggle listening", message.value);
                listening = message.value;
                break;
            case 'detectface':
                console.log("toggle detectface", message.value)
                detectface = message.value;
                break;
        }
    });

});

startListening();

function startListening() {
    tj.listen(function(msg) {
        if (listening) {
            logSpeak("you", msg);
            // send to the conversation service
            converse(msg);
        }
    });

}

function converse(msg) {
    tj.converse(WORKSPACEID, msg, function(response, responseText) {
        // speak the result
        response = response.object;
        if (response.output.text.length > 0) {
            //console.log(response)
            conversation_response = response.output.text[0];
            if (conversation_response != undefined) {
                var matchedIntent = response.intents[0].intent; // intent with the highest confidence
                var intentconfidence = response.intents[0].confidence;
                console.log("> intents : ", response.intents);

                if (intentconfidence > 0.5) {
                    tj.shine("green");
                    if (matchedIntent == "dance") {
                        predance("Sure, will play some music");
                        //dance();
                    } else if (matchedIntent == "wave") {
                        wave(conversation_response);
                    } else if (matchedIntent == "see") {
                        see(conversation_response);
                    } else if (matchedIntent == "off_topic") {
                        // do nothing
                    } else if (matchedIntent == "weather") {
                        getCordinates("Las vegas", "city", "US", "NV");
                    } else {
                        tj.speak(conversation_response).then(function() {
                            tj.shine("white");
                        });
                    }
                    if (matchedIntent != "off_topic") {
                        logSpeak("TJBot", conversation_response, matchedIntent + " (" + intentconfidence.toFixed(2) * 100 + "%)");
                    }

                } else {
                    tj.shine("red");
                    setTimeout(function() {
                        tj.shine("white");
                    }, 800);
                }

            } else {
                tj.shine("red");
                console.log("The response (output) text from your conversation is empty. Please check your conversation flow \n" + JSON.stringify(response))
            }
        } else {
            console.error("The conversation service did not return any response text.");
        }
        //console.log("conversation response", response)
    });
}

function setLED(color) {
    tj.shine(color)
}

function predance(conversation_response, intent) {
    //logSpeak("TJBot", conversation_response, intent);
    tj.speak(conversation_response).then(function() {
        dance("club.wav")
    });
}

function wave(conversation_response) {
    //logSpeak("TJBot", conversation_response);
    tj.speak(conversation_response).then(function() {
        // wave
        tj.wave();
        tj.wave();
        tj.shine("white");
    })
}

function seeText(prompt) {
    //logSpeak("TJBot", prompt);
    tj.speak(prompt).then(function() {
        curImage = Date.now() + ".jpg";
        filePath = fileDir + "/" + curImage;
        tj.captureImage(filePath).then(function(filePath) {
            var response = {};
            response.imageurl = curImage;
            response.transcript = "Scanning for text."
            logVision("tjbot", response)
            tj.callVisualRecognition("text", filePath).then(function(response) {
                console.log(" ... response .. ", response.description)
                response.description = (response.description == "" || response.description == null) ? "No text recognized in the image." : "The words I see are : " + response.description;
                logSpeak("TJBot", response.description);
                tj.speak(response.description).then(function() {
                    tj.shine("white");
                })

            });
        })

    });
}

function see(conversation_response) {
    //logSpeak("TJBot", conversation_response);
    tj.speak(conversation_response).then(function() {
        curImage = Date.now() + ".jpg";
        filePath = fileDir + "/" + curImage;
        tj.captureImage(filePath).then(function(filePath) {
            console.log(" ==== face ===", detectface);
            if (detectface) {
                detectFaces(filePath, curImage);
            } else {
                var response = {};
                response.imageurl = curImage;
                response.transcript = "";
                logVision("tjbot", response);
            }

            tj.callVisualRecognition("classify", filePath).then(function(response) {
                console.log(" ... response .. ", response.description)
                if (response.description != null) {
                    logSpeak("TJBot", response.description);
                    tj.speak(response.description).then(function() {
                        tj.shine("white");
                    })
                }
            });
        })

    });
}

/**
 * [dance play a soundFile and dance to its beats]
 * @param  {[type]} soundFile [soundfile to be decoded and danced to]
 * @return {[type]}           [description]
 */
function dance(soundFile) {
    // Decode the sound file to get its digital signal data
    var audioContext = new AudioContext
    fs.readFile(soundFile, function(err, buf) {
        if (err) throw err
        audioContext.decodeAudioData(buf, function(audioBuffer) {
            console.log("> finished decoding sound file ", soundFile);
            findPeaks(audioBuffer.getChannelData(0), audioBuffer.sampleRate, soundFile);
        }, function(err) {
            throw err
        })
    })

}

/**
 * [_findPeaks find peaks or high energy positions in audioBuffer data and move arm based on that to simulate dance.]
 * @param  {[type]} audioBuffer [decoded audio data]
 * @param  {[type]} sampleRate  [audio sample rate]
 * @return {[type]}             [description]
 */
function findPeaks(audioBuffer, sampleRate, soundFile) {
    var interval = 0.05 * 1000;
    var index = 0;
    var step = Math.round(sampleRate * (interval / 1000));
    var max = 0;
    var prevmax = 0;
    var prevdiffthreshold = 0.3;

    var sampleSound = setInterval(function() {
        if (index >= audioBuffer.length) {
            clearInterval(sampleSound);
            tj.shine("white");
            return;
        }
        for (var i = index; i < index + step; i++) {
            max = audioBuffer[i] > max ? audioBuffer[i].toFixed(1) : max;
        }
        // Spot a significant increase or peak? Wave Arm
        if (max - prevmax >= prevdiffthreshold) {
            // do some funky waving.
            var delay = 300;
            tj.raiseArm();
            setTimeout(function() {
                tj.lowerArm();
            }, delay);
        }
        prevmax = max;
        max = 0;
        index += step;
    }, interval);
    tj.playSound(soundFile);
}

function logVision(sender, response) {
    var message = {
        type: "vision",
        title: "What TJBot Sees",
        sender: sender,
        transcript: response.transcript,
        description: "",
        imageurl: "/img/snaps/" + response.imageurl,
        timestamp: Date.now(),
        tags: [{
            title: "visual recognition",
            url: "#"
        }, {
            title: "camera",
            url: "#"
        }],
        visiontags: [{
            title: "visual recognition",
            url: "#"
        }, {
            title: "camera",
            url: "#"
        }],
        confidence: 1
    }
    //console.log(message)
    server.sendEvent(message)
}

function logSpeak(sender, transcript, intent) {

    var message = {
        type: "speech",
        sender: sender,
        title: sender == "you" ? "What TJBot thinks you said" : "What TJBot says",
        transcript: transcript,
        intent: intent,
        description: "",
        timestamp: Date.now(),
        tags: [{
            title: "speech to text",
            url: "#"
        }, {
            title: "text to speech",
            url: "#"
        }, {
            title: "microphone",
            url: "#"
        }, {
            title: "speaker",
            url: "#"
        }],
        confidence: 1
    }
    //console.log(message)
    server.sendEvent(message)
}

var cv = require('opencv');

function detectFaces(imgsource, curImage) {
    var starttime = Date.now();
    var endtime;
    var COLOR = [0, 255, 255]; // default red
    var thickness = 1; // default 1

    cv.readImage(imgsource, function(err, im) {
        if (err) throw err;
        if (im.width() < 1 || im.height() < 1) throw new Error('Image has no size');
        im.detectObject("haar/face.xml", {}, function(err, faces) {
            if (err) throw err;
            for (var i = 0; i < faces.length; i++) {
                var face = faces[i];
                im.rectangle([face.x, face.y], [face.width, face.height], COLOR, 2);
            }
            endtime = Date.now()
            console.log("faces found: ", faces.length, "timetaken: ", (endtime - starttime) / 1000)
            im.save(imgsource);
            var response = {};
            response.imageurl = curImage;
            response.transcript = faces.length + " faces detected.";
            logVision("tjbot", response)
            console.log('Image saved to ', imgsource);
        });
    });
}

function getCordinates(query, locationtype, countrycode, admindistrictcode) {
    query = query.replace(/ /g, "+")
    var url = "https://" + credentials.weather.username + ":" + credentials.weather.password + "@" + credentials.weather.host + ":" + credentials.weather.port + "/api/weather/v3/location/search?query=" + query + "&locationType=" + locationtype + "&countryCode=" + countrycode + "&adminDistrictCode=" + admindistrictcode + "&language=en-US";
    var options = {
        method: 'GET',
        url: url
    }
    request(options, function(error, response, body) {

        if (!error && response.statusCode == 200) {
            var result = JSON.parse(body)
            //console.log(result)
            var longitude = result.location.longitude[0];
            var latitude = result.location.latitude[0];
            //console.log(longitude, latitude);
            getWeather(longitude, latitude)
        } else {
            console.log("Error getting cordinates")
        }
    });

}

function getWeather(long, lat) {
    var url = "https://" + credentials.weather.username + ":" + credentials.weather.password + "@" + credentials.weather.host + ":" + credentials.weather.port + "/api/weather/v1/geocode/" + lat + "/" + long + "/observations.json?units=m&language=en-US";
    var options = {
        method: 'GET',
        url: url
    }
    request(options, function(error, response, body) {
        if (!error && response.statusCode == 200) {
            var result = JSON.parse(body)
            var ob = result.observation
            var location = ob.obs_name;
            var temp = ob.temp;
            var desc = ob.wx_phrase;
            var feelslike = ob.feels_like;
            var windspeed = ob.wspd + " km/h";
            var uv = ob.uv_desc;
            var alldesc = "The weather in " + location + " today is " + desc + " with a temperature of " + temp + " that feels more like " +
                feelslike + ". Wind speed is " + windspeed + " and UV is " + uv;
            console.log(alldesc);
            logSpeak("TJBot", alldesc);
            tj.speak(alldesc);
        } else {
            console.log("weather error")
        }
    });
}
<commit_msg>add face detection<commit_after>var server = require("./server");
var tjbot = require('tjbot');
var constants = require('./config');
var AudioContext = require('web-audio-api').AudioContext
context = new AudioContext
var request = require("request");
var fs = require('fs');
var fileDir = process.cwd() + "/public/img/snaps"
var curImage = "";

// obtain our credentials from config.js
var credentials = constants.credentials;

// obtain user-specific config
var VOICE = constants.config.voice;
var WORKSPACEID = constants.config.conversationWorkspaceId;

// these are the hardware capabilities that TJ needs for this recipe
var hardware = ['microphone', 'speaker', 'led', 'servo'];

// Set up configuration paramters
var config = {
    verboseLogging: true, //enable console debugging
    servoPin: 7, // set servo pin
    cameraParams: {
        height: 720,
        width: 960,
        vflip: false,
        hflip: false
    } // setup my camera capture parameters
};

var listening = true;
var detectface = false;

// obtain our configs from config.js and merge with custom configs
config = Object.assign(constants.config, config);

// instantiate our TJBot!
var tj = new tjbot(hardware, config, credentials);

server.wss.on('connection', function connection(ws) {
    ws.on('message', function incoming(message) {
        message = JSON.parse(message)
        console.log("beee", (message));
        switch (message.event) {
            case 'wave':
                var prompt = "Waving my arm. Just for you. ";
                logSpeak("TJBot", prompt);
                wave(prompt)
                break;
            case 'dance':
                var prompt = "Sure. I'll play some music and dance.";
                logSpeak("TJBot", prompt);
                predance(prompt)
                break;
            case 'see':
                var prompt = "A moment. Let me look around.";
                logSpeak("TJBot", prompt);
                see(prompt)
                break;
            case 'seetext':
                var prompt = "Sure. Scanning for text in the image.";
                logSpeak("TJBot", prompt);
                seeText(prompt)
                break;
            case 'led':
                console.log("shinning led ", message.color)
                tj.shine(message.color);
                break;
            case 'speak':
                console.log("speaking ", message.value);
                logSpeak("you", message.value);
                converse(message.value);
                break;
            case 'listening':
                console.log("toggle listening", message.value);
                listening = message.value;
                break;
            case 'detectface':
                console.log("toggle detectface", message.value)
                detectface = message.value;
                break;
        }
    });

});

startListening();

function startListening() {
    tj.listen(function(msg) {
        if (listening) {
            logSpeak("you", msg);
            // send to the conversation service
            converse(msg);
        }
    });

}

function converse(msg) {
    tj.converse(WORKSPACEID, msg, function(response, responseText) {
        // speak the result
        response = response.object;
        if (response.output.text.length > 0) {
            //console.log(response)
            conversation_response = response.output.text[0];
            if (conversation_response != undefined) {
                var matchedIntent = response.intents[0].intent; // intent with the highest confidence
                var intentconfidence = response.intents[0].confidence;
                console.log("> intents : ", response.intents);

                if (intentconfidence > 0.5) {
                    tj.shine("green");
                    if (matchedIntent == "dance") {
                        predance("Sure, will play some music");
                        //dance();
                    } else if (matchedIntent == "wave") {
                        wave(conversation_response);
                    } else if (matchedIntent == "see") {
                        see(conversation_response);
                    } else if (matchedIntent == "off_topic") {
                        // do nothing
                    } else if (matchedIntent == "weather") {
                        getCordinates("Las vegas", "city", "US", "NV");
                    } else {
                        tj.speak(conversation_response).then(function() {
                            tj.shine("white");
                        });
                    }
                    if (matchedIntent != "off_topic") {
                        logSpeak("TJBot", conversation_response, matchedIntent + " (" + intentconfidence.toFixed(2) * 100 + "%)");
                    }

                } else {
                    tj.shine("red");
                    setTimeout(function() {
                        tj.shine("white");
                    }, 800);
                }

            } else {
                tj.shine("red");
                console.log("The response (output) text from your conversation is empty. Please check your conversation flow \n" + JSON.stringify(response))
            }
        } else {
            console.error("The conversation service did not return any response text.");
        }
        //console.log("conversation response", response)
    });
}

function setLED(color) {
    tj.shine(color)
}

function predance(conversation_response, intent) {
    //logSpeak("TJBot", conversation_response, intent);
    tj.speak(conversation_response).then(function() {
        dance("club.wav")
    });
}

function wave(conversation_response) {
    //logSpeak("TJBot", conversation_response);
    tj.speak(conversation_response).then(function() {
        // wave
        tj.wave();
        tj.wave();
        tj.shine("white");
    })
}

function seeText(prompt) {
    //logSpeak("TJBot", prompt);
    tj.speak(prompt).then(function() {
        curImage = Date.now() + ".jpg";
        filePath = fileDir + "/" + curImage;
        tj.captureImage(filePath).then(function(filePath) {
            var response = {};
            response.imageurl = curImage;
            response.transcript = "Scanning for text."
            logVision("tjbot", response)
            tj.callVisualRecognition("text", filePath).then(function(response) {
                console.log(" ... response .. ", response.description)
                response.description = (response.description == "" || response.description == null) ? "No text recognized in the image." : "The words I see are : " + response.description;
                logSpeak("TJBot", response.description);
                tj.speak(response.description).then(function() {
                    tj.shine("white");
                })

            });
        })

    });
}

function see(conversation_response) {
    //logSpeak("TJBot", conversation_response);
    tj.speak(conversation_response).then(function() {
        curImage = Date.now() + ".jpg";
        filePath = fileDir + "/" + curImage;
        tj.captureImage(filePath).then(function(filePath) {
            console.log(" ==== face ===", detectface);
            if (detectface) {
                detectFaces(filePath, curImage);
            } else {
                var response = {};
                response.imageurl = curImage;
                response.transcript = "";
                logVision("tjbot", response);
            }

            tj.callVisualRecognition("classify", filePath).then(function(response) {
                console.log(" ... response .. ", response.description)
                if (response.description != null) {
                    logSpeak("TJBot", response.description);
                    tj.speak(response.description).then(function() {
                        tj.shine("white");
                    })
                }
            });
        })

    });
}

/**
 * [dance play a soundFile and dance to its beats]
 * @param  {[type]} soundFile [soundfile to be decoded and danced to]
 * @return {[type]}           [description]
 */
function dance(soundFile) {
    // Decode the sound file to get its digital signal data
    var audioContext = new AudioContext
    fs.readFile(soundFile, function(err, buf) {
        if (err) throw err
        audioContext.decodeAudioData(buf, function(audioBuffer) {
            console.log("> finished decoding sound file ", soundFile);
            findPeaks(audioBuffer.getChannelData(0), audioBuffer.sampleRate, soundFile);
        }, function(err) {
            throw err
        })
    })

}

/**
 * [_findPeaks find peaks or high energy positions in audioBuffer data and move arm based on that to simulate dance.]
 * @param  {[type]} audioBuffer [decoded audio data]
 * @param  {[type]} sampleRate  [audio sample rate]
 * @return {[type]}             [description]
 */
function findPeaks(audioBuffer, sampleRate, soundFile) {
    var interval = 0.05 * 1000;
    var index = 0;
    var step = Math.round(sampleRate * (interval / 1000));
    var max = 0;
    var prevmax = 0;
    var prevdiffthreshold = 0.3;

    var sampleSound = setInterval(function() {
        if (index >= audioBuffer.length) {
            clearInterval(sampleSound);
            tj.shine("white");
            return;
        }
        for (var i = index; i < index + step; i++) {
            max = audioBuffer[i] > max ? audioBuffer[i].toFixed(1) : max;
        }
        // Spot a significant increase or peak? Wave Arm
        if (max - prevmax >= prevdiffthreshold) {
            // do some funky waving.
            var delay = 300;
            tj.raiseArm();
            setTimeout(function() {
                tj.lowerArm();
            }, delay);
        }
        prevmax = max;
        max = 0;
        index += step;
    }, interval);
    tj.playSound(soundFile);
}

function logVision(sender, response) {
    var message = {
        type: "vision",
        title: "What TJBot Sees",
        sender: sender,
        transcript: response.transcript,
        description: "",
        imageurl: "/img/snaps/" + response.imageurl,
        timestamp: Date.now(),
        tags: [{
            title: "visual recognition",
            url: "#"
        }, {
            title: "camera",
            url: "#"
        }],
        visiontags: [{
            title: "visual recognition",
            url: "#"
        }, {
            title: "camera",
            url: "#"
        }],
        confidence: 1
    }
    //console.log(message)
    server.sendEvent(message)
}

function logSpeak(sender, transcript, intent) {

    var message = {
        type: "speech",
        sender: sender,
        title: sender == "you" ? "What TJBot thinks you said" : "What TJBot says",
        transcript: transcript,
        intent: intent,
        description: "",
        timestamp: Date.now(),
        tags: [{
            title: "speech to text",
            url: "#"
        }, {
            title: "text to speech",
            url: "#"
        }, {
            title: "microphone",
            url: "#"
        }, {
            title: "speaker",
            url: "#"
        }],
        confidence: 1
    }
    //console.log(message)
    server.sendEvent(message)
}

var cv = require('opencv');

function detectFaces(imgsource, curImage) {
    var starttime = Date.now();
    var endtime;
    var COLOR = [0, 255, 255]; // default red
    var thickness = 1; // default 1

    cv.readImage(imgsource, function(err, im) {
        if (err) throw err;
        if (im.width() < 1 || im.height() < 1) throw new Error('Image has no size');
        im.detectObject("haar/face.xml", {}, function(err, faces) {
            if (err) throw err;
            for (var i = 0; i < faces.length; i++) {
                var face = faces[i];
                im.rectangle([face.x, face.y], [face.width, face.height], COLOR, 2);
            }
            endtime = Date.now()
            console.log("faces found: ", faces.length, "timetaken: ", (endtime - starttime) / 1000)
            im.save(imgsource);
            var response = {};
            response.imageurl = curImage;
            response.transcript = faces.length + " faces detected.";
            logVision("tjbot", response)
            console.log('Image saved to ', imgsource);
        });
    });
}

function getCordinates(query, locationtype, countrycode, admindistrictcode) {
    query = query.replace(/ /g, "+")
    var url = "https://" + credentials.weather.username + ":" + credentials.weather.password + "@" + credentials.weather.host + ":" + credentials.weather.port + "/api/weather/v3/location/search?query=" + query + "&locationType=" + locationtype + "&countryCode=" + countrycode + "&adminDistrictCode=" + admindistrictcode + "&language=en-US";
    var options = {
        method: 'GET',
        url: url
    }
    request(options, function(error, response, body) {

        if (!error && response.statusCode == 200) {
            var result = JSON.parse(body)
            //console.log(result)
            var longitude = result.location.longitude[0];
            var latitude = result.location.latitude[0];
            //console.log(longitude, latitude);
            getWeather(longitude, latitude)
        } else {
            console.log("Error getting cordinates")
        }
    });

}

function getWeather(long, lat) {
    var url = "https://" + credentials.weather.username + ":" + credentials.weather.password + "@" + credentials.weather.host + ":" + credentials.weather.port + "/api/weather/v1/geocode/" + lat + "/" + long + "/observations.json?units=m&language=en-US";
    var options = {
        method: 'GET',
        url: url
    }
    request(options, function(error, response, body) {
        if (!error && response.statusCode == 200) {
            var result = JSON.parse(body)
            var ob = result.observation
            var location = ob.obs_name;
            var temp = ob.temp;
            var desc = ob.wx_phrase;
            var feelslike = ob.feels_like;
            var windspeed = ob.wspd + " km/h";
            var uv = ob.uv_desc;
            var alldesc = "The weather in " + location + " today is " + desc + " with a temperature of " + temp + " that feels more like " +
                feelslike + ". Wind speed is " + windspeed + " and UV is " + uv;
            console.log(alldesc);
            logSpeak("TJBot", alldesc);
            tj.speak(alldesc);
        } else {
            console.log("weather error")
        }
    });
}
<|endoftext|>