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

import style from './style.css';
import CategoryLabel from './categoryLabel';
import DetailList from './detailList';

const DEFAULT_FIELDS = ['symbol', 'gene_symbol', 'name', 'gene_synonyms', 'synonyms', 'sourceHref', 'gene_id', 'species', 'type'];

class ResultsList extends Component {
  renderHighlightedValues(highlight) {
    let _data = highlight;
    let _fields = Object.keys(_data).filter( d => {
      return (DEFAULT_FIELDS.indexOf(d) < 0);
    });
    return <DetailList data={_data} fields={_fields} />;
  }

  renderHeader(d) {
    return (

        <CategoryLabel category={d.category} />

    );
  }

  renderDetailFromFields(d, fields) {
    return <DetailList data={d} fields={fields} />;
  }

  renderNonGeneEntry(d, i, fields) {
    return (
      <div className={style.resultContainer} key={`sr${i}`}>
        {this.renderHeader(d)}
        {this.renderDetailFromFields(d, fields)}
        {this.renderHighlightedValues(d.highlight)}

    );
  }

  renderHomologs(homologs, label) {
    if (!homologs) return null;
    label = label || 'Homologs';
    if (homologs.length === 0) return null;
    let nodes = homologs.map( (d, i) => {
      let commaNode = (i === homologs.length - 1) ? null : ', ';
      return (

            {d.symbol}

            {d.evidence_name}

          {commaNode}

      );
    });
    return (

        {label}: {nodes}

    );
  }

  renderGeneEntry(d, i) {
    let topFields = ['name', 'synonyms'];
    let bottomFields = ['species', 'gene_type'];
    return (
      <div className={style.resultContainer} key={`sr${i}`}>
        {this.renderHeader(d)}
          {this.renderDetailFromFields(d, topFields)}

            Source:

          {this.renderDetailFromFields(d, bottomFields)}
          {this.renderHomologs(d.homologs)}
          {this.renderHomologs(d.paralogs, 'Paralogs')}
          {this.renderHighlightedValues(d.highlight)}

    );
  }

  renderRows() {
    return this.props.entries.map( (d, i) => {
      if (d.category === 'gene') {
        return this.renderGeneEntry(d, i);
      } else {
        let fieldVals = {
          'disease': ['synonyms', 'omim_id'],
          'go': ['synonyms', 'go_branch'],
        };
        let fields = fieldVals[d.category] || [];
        return this.renderNonGeneEntry(d, i, fields);
      }
    });
  }

  render() {
    return (

        {this.renderRows()}

    );
  }
}

ResultsList.propTypes = {
  entries: React.PropTypes.array
};

export default ResultsList;
<commit_msg>tooltip for more homology info<commit_after>import React, { Component } from 'react';
import { Tooltip, OverlayTrigger } from 'react-bootstrap';

import style from './style.css';
import CategoryLabel from './categoryLabel';
import DetailList from './detailList';

const DEFAULT_FIELDS = ['symbol', 'gene_symbol', 'name', 'gene_synonyms', 'synonyms', 'sourceHref', 'gene_id', 'species', 'type'];

class ResultsList extends Component {
  renderHighlightedValues(highlight) {
    let _data = highlight;
    let _fields = Object.keys(_data).filter( d => {
      return (DEFAULT_FIELDS.indexOf(d) < 0);
    });
    return <DetailList data={_data} fields={_fields} />;
  }

  renderHeader(d) {
    return (

        <CategoryLabel category={d.category} />

    );
  }

  renderDetailFromFields(d, fields) {
    return <DetailList data={d} fields={fields} />;
  }

  renderNonGeneEntry(d, i, fields) {
    return (
      <div className={style.resultContainer} key={`sr${i}`}>
        {this.renderHeader(d)}
        {this.renderDetailFromFields(d, fields)}
        {this.renderHighlightedValues(d.highlight)}

    );
  }

  renderHomologs(homologs, label) {
    if (!homologs) return null;
    label = label || 'Homologs';
    if (homologs.length === 0) return null;
    let nodes = homologs.map( (d, i) => {
      let commaNode = (i === homologs.length - 1) ? null : ', ';
      let tooltipNode = <Tooltip className='in' id='tooltip-top' placement='top'>{d.species} type: {d.relationship_type}</Tooltip>;
      return (

          <OverlayTrigger overlay={tooltipNode} placement='top'>

              {d.symbol}

          </OverlayTrigger>

            {d.evidence_name}

          {commaNode}

      );
    });
    return (

        {label}: {nodes}

    );
  }

  renderGeneEntry(d, i) {
    let topFields = ['name', 'synonyms'];
    let bottomFields = ['species', 'gene_type'];
    return (
      <div className={style.resultContainer} key={`sr${i}`}>
        {this.renderHeader(d)}
          {this.renderDetailFromFields(d, topFields)}

            Source:

          {this.renderDetailFromFields(d, bottomFields)}
          {this.renderHomologs(d.homologs)}
          {this.renderHomologs(d.paralogs, 'Paralogs')}
          {this.renderHighlightedValues(d.highlight)}

    );
  }

  renderRows() {
    return this.props.entries.map( (d, i) => {
      if (d.category === 'gene') {
        return this.renderGeneEntry(d, i);
      } else {
        let fieldVals = {
          'disease': ['synonyms', 'omim_id'],
          'go': ['synonyms', 'go_branch'],
        };
        let fields = fieldVals[d.category] || [];
        return this.renderNonGeneEntry(d, i, fields);
      }
    });
  }

  render() {
    return (

        {this.renderRows()}

    );
  }
}

ResultsList.propTypes = {
  entries: React.PropTypes.array
};

export default ResultsList;
<|endoftext|>


<commit_before>"use strict";

const setupTask = require('utils').setupTask;

module.exports = {
	run : function(creep){
		if(!creep.task){
			var target = {};
			target.pos = new RoomPosition(25,25,creep.memory.targetRoom);
			setupTask(TASK_SCOUT,target);
		}
	}
}
<commit_msg>bugfix<commit_after>"use strict";

const setupTask = require('utils').setupTask;

module.exports = {
	run : function(creep){
		if(!creep.task){
			var target = {};
			target.pos = new RoomPosition(25,25,creep.memory.targetRoom);
			creep.task = setupTask(TASK_SCOUT,target);
		}
	}
}
<|endoftext|>


<commit_before>/*global TWEEN:true*/

// extends src/nodes/time.js which extends src/node-box-native-view.js

$(function(){

  // Average and normalize FFT to 3 values
  var lowMidHigh = function(fft) {
    var low = mid = high = 0;
    var max = 255;
    for (var i=0; i<3; i++) {
      low += fft[i];
    }
    for (i=3; i<6; i++) {
      mid += fft[i];
    }
    for (i=6; i<9; i++) {
      high += fft[i];
    }
    low = low/3/max;
    mid = mid/3/max;
    high = high/3/max;
    return [low, mid, high];
  };

  // var template = '

';

  Iframework.NativeNodes["audio-mic"] = Iframework.NativeNodes["audio"].extend({

    // template: _.template(template),
    info: {
      title: "mic",
      description: "webrtc mic to web audio api"
    },
    initializeModule: function(){
      this.audioOutput = this.audioContext.createGainNode();
      this.analyser = this.audioContext.createAnalyser();
      this.analyser.fftSize = 32;
      this.audioOutput.connect(this.analyser);
      this.fftData = new Uint8Array(this.analyser.frequencyBinCount);
    },
    started: false,
    inputstart: function(){
      var self = this;
      navigator.webkitGetUserMedia(
        {audio: true},
        function(stream) {
          self._stream = stream;
          var microphone = self.audioContext.createMediaStreamSource(stream);
          microphone.connect(self.audioOutput);
          self.started = true;
        },
        function(error){}
      );
    },
    renderAnimationFrame: function (timestamp) {
      if (this.started) {
        this.analyser.getByteFrequencyData(this.fftData);
        var simplified = lowMidHigh(this.fftData);
        this.send("low", simplified[0]);
        this.send("mid", simplified[1]);
        this.send("high", simplified[2]);
      }
    },
    inputstop: function(){
      this._stream.stop();
      self.started = false;
    },
    inputs: {
      start: {
        type: "bang",
        description: "start mic"
      },
      stop: {
        type: "bang",
        description: "stop mic"
      }
    },
    outputs: {
      audio: {
        type: "audio"
      },
      low:{
        type: "number"
      },
      mid:{
        type: "number"
      },
      high:{
        type: "number"
      }
    }

  });

});
<commit_msg>firefox gum<commit_after>/*global TWEEN:true*/

// extends src/nodes/time.js which extends src/node-box-native-view.js

$(function(){

  // Average and normalize FFT to 3 values
  var lowMidHigh = function(fft) {
    var low = 0; var mid = 0; var high = 0;
    var max = 255;
    for (var i=0; i<3; i++) {
      low += fft[i];
    }
    for (i=3; i<6; i++) {
      mid += fft[i];
    }
    for (i=6; i<9; i++) {
      high += fft[i];
    }
    low = low/3/max;
    mid = mid/3/max;
    high = high/3/max;
    return [low, mid, high];
  };

  // var template = '

';

  Iframework.NativeNodes["audio-mic"] = Iframework.NativeNodes["audio"].extend({

    // template: _.template(template),
    info: {
      title: "mic",
      description: "webrtc mic to web audio api"
    },
    initializeModule: function(){
      this.audioOutput = this.audioContext.createGain();
      this.analyser = this.audioContext.createAnalyser();
      this.analyser.fftSize = 32;
      this.audioOutput.connect(this.analyser);
      this.fftData = new Uint8Array(this.analyser.frequencyBinCount);
    },
    started: false,
    inputstart: function(){
      var self = this;
      navigator._meemoo_gum = navigator.getUserMedia || navigator.webkitGetUserMedia || navigator.mozGetUserMedia || null;
      if (!navigator._meemoo_gum) { return; }
      navigator._meemoo_gum(
        {audio: true},
        function(stream) {
          self._stream = stream;
          var microphone = self.audioContext.createMediaStreamSource(stream);
          microphone.connect(self.audioOutput);
          self.started = true;
        },
        function(error){}
      );
    },
    renderAnimationFrame: function (timestamp) {
      if (this.started) {
        this.analyser.getByteFrequencyData(this.fftData);
        var simplified = lowMidHigh(this.fftData);
        this.send("low", simplified[0]);
        this.send("mid", simplified[1]);
        this.send("high", simplified[2]);
      }
    },
    inputstop: function(){
      this._stream.stop();
      self.started = false;
    },
    inputs: {
      start: {
        type: "bang",
        description: "start mic"
      },
      stop: {
        type: "bang",
        description: "stop mic"
      }
    },
    outputs: {
      audio: {
        type: "audio"
      },
      low:{
        type: "number"
      },
      mid:{
        type: "number"
      },
      high:{
        type: "number"
      }
    }

  });

});
<|endoftext|>


<commit_before>'use strict';

var assert = require("assert");
var sinon = require("sinon");
var expect = require('chai').expect;

require("../Morphine");

// Создаем пустой объект, слушаем, добавляем структуру, проверяем
// Создаем объект по path, слушаем, добавляем структуру
// Создаем объект из plain-объекта

// Создаем коллекции, слушаем изменения коллекции
// Проверяем события add, change, remove и всплывающие
// Проверяем события на текущем объекте и всплывающие

// Проверяем реакцию на все всплывающие события при подписке на all.
// Проверяем реакцию на все события текущего объекта при подписке на all.

describe('Listeners tests', function () {

    describe('Событие add', function () {

        describe('set path в пустой объект', function () {

            it('Состояние event-объекта', function (cb) {
                var morph = new Morphine();

                morph.on('add', function (e) {
                    // Event {type: "add", path: "Application", fieldName: "Application"}
                    expect(e.type).to.equal('add');
                    expect(e.path).to.equal('Application');
                    expect(e.fieldName).to.equal('Application');
                    cb();
                });

                morph.set('Application');
            });

            it('Количество вызовов event-listener метода', function () {
                var addHandler = sinon.spy();
                var morph = new Morphine();

                morph.on('add', addHandler);
                morph.set('Application');

                assert.equal(addHandler.calledOnce, true, 'Обработчик события add вызван один раз');
            });

        });

    });

});<commit_msg>Тест события add при создании вложеной структуры через set<commit_after>'use strict';

var assert = require("assert");
var sinon = require("sinon");
var expect = require('chai').expect;

require("../Morphine");

// Создаем пустой объект, слушаем, добавляем структуру, проверяем
// Создаем объект по path, слушаем, добавляем структуру
// Создаем объект из plain-объекта

// Создаем коллекции, слушаем изменения коллекции
// Проверяем события add, change, remove и всплывающие
// Проверяем события на текущем объекте и всплывающие

// Проверяем реакцию на все всплывающие события при подписке на all.
// Проверяем реакцию на все события текущего объекта при подписке на all.

describe('Listeners tests', function () {

    describe('Событие add', function () {

        describe('set path в пустой объект', function () {

            it('Состояние event-объекта', function (cb) {
                var morph = new Morphine();

                morph.on('add', function (e) {
                    // Event {type: "add", path: "Application", fieldName: "Application"}
                    expect(e.type).to.equal('add');
                    expect(e.path).to.equal('Application');
                    expect(e.fieldName).to.equal('Application');
                    cb();
                });

                morph.set('Application');
            });

            it('Количество вызовов event-listener метода', function () {
                var addHandler = sinon.spy();
                var morph = new Morphine();

                morph.on('add', addHandler);
                morph.set('Application');

                assert.equal(addHandler.calledOnce, true, 'Обработчик события add вызван один раз');
            });

            it('Создание нескольких вложенных объектов', function () {
                var addHandler = sinon.spy();
                var morph = new Morphine();

                morph.on('add', addHandler);
                morph.set('Application.Collections.Users.$');

                assert.equal(addHandler.callCount, 3, 'Обработчик события add вызван 3 раза');
            });

        });

    });

});<|endoftext|>


<commit_before>var express = require('express');
var router = express.Router();
var LocationModel = require('../models/location');

/* GET GeoJS page */
router.get('/',function(req,res,next){
	res.render('geojs', { city:'city'});
});

/* GET _id */
router.get('/city/:name',function(res,req,next){
	var city = req.params.name;
	res.send(city);
});

router.get('/geojs/:version',function(res,req){
	res.send(req.params.version)
});
/* POST GeoJs page */
router.post('/',function(req,res,next){
	LocationModel.create(req.body.city);
	res.send('City of '+ req.body.city);
});
console.log(LocationModel);

module.exports = router;

<commit_msg>router find<commit_after>var express = require('express');
var router = express.Router();
var LocationModel = require('../models/location');

/* GET GeoJS page */
router.get('/',function(req,res,next){
	res.render('geojs', { city:'city'});
});

/* GET _id */
router.get('/city/:name',function(req,res,next){
	var city = req.params.name;
	res.send(city);
});

router.get('/geojs/:version',function(req,res){
	res.send(req.params.version)
});
/* POST GeoJs page */
router.post('/',function(req,res,next){
	LocationModel.create(req.body.city);
	res.send('City of '+ req.body.city);
});
console.log(LocationModel);

module.exports = router;

<|endoftext|>


<commit_before>/**
 * @license
 * Visual Blocks Editor
 *
 * Copyright 2017 Google Inc.
 * https://developers.google.com/blockly/
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *   http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

 /**
 * @fileoverview Test utilities.
 * @author marisaleung@google.com (Marisa Leung)
 */
'use strict';

goog.require('goog.testing');

/**
 * The normal blockly event fire function.  We sometimes override this.  This
 * handle lets us reset after an override.
 */
var savedFireFunc = Blockly.Events.fire;

/**
 * A helper function to replace Blockly.Events.fire in tests.
 */
function temporary_fireEvent(event) {
  if (!Blockly.Events.isEnabled()) {
    return;
  }
  Blockly.Events.FIRE_QUEUE_.push(event);
  Blockly.Events.fireNow_();
}

/**
 * Check that two arrays have the same content.
 * @param {!Array.<string>} array1 The first array.
 * @param {!Array.<string>} array2 The second array.
 */
function isEqualArrays(array1, array2) {
  assertEquals(array1.length, array2.length);
  for (var i = 0; i < array1.length; i++) {
    assertEquals(array1[i], array2[i]);
  }
}

/**
 * Creates a controlled MethodMock. Sets the expected return values and
 *     the parameters if any exist. Sets the method to replay.
 * @param {!goog.testing.MockControl} mockControl Object that holds a set
 *    of mocks for this test.
 * @param {!Object} scope The scope of the method to be mocked out.
 * @param {!string} funcName The name of the function we're going to mock.
 * @param {Array<Object>} parameters The parameters to call the mock with.
 * @param {Array<!Object>} return_values The values to return when called.
 * @return {!goog.testing.MockInterface} The mocked method.
 */
function setUpMockMethod(mockControl, scope, funcName, parameters,
	return_values) {
  var mockMethod = mockControl.createMethodMock(scope, funcName);
  if (return_values) {
    for (var i = 0, return_value; return_value = return_values[i]; i++) {
      if (parameters && i < parameters.length) {
        mockMethod(parameters[i]).$returns(return_value);
      }
      else {
        mockMethod().$returns(return_value);
      }
    }
  }
  // If there are no return values but there are parameters, we are only
  // recording specific method calls.
  else if (parameters) {
    for (var i = 0; i < parameters.length; i++) {
      mockMethod(parameters[i]);
    }
  }
  mockMethod.$replay();
  return mockMethod;
}

/**
 * Check if a variable with the given values exists.
 * @param {Blockly.Workspace|Blockly.VariableMap} container The workspace  or
 *     variableMap the checked variable belongs to.
 * @param {!string} name The expected name of the variable.
 * @param {!string} type The expected type of the variable.
 * @param {!string} id The expected id of the variable.
 */
function checkVariableValues(container, name, type, id) {
  var variable = container.getVariableById(id);
  assertNotUndefined(variable);
  assertEquals(name, variable.name);
  assertEquals(type, variable.type);
  assertEquals(id, variable.getId());
}

/**
 * Create a test get_var_block.
 * Will fail if get_var_block isn't defined.
 * @param {!Blockly.Workspace} workspace The workspace on which to create the
 *     block.
 * @param {!string} variable_id The id of the variable to reference.
 * @return {!Blockly.Block} The created block.
 */
function createMockVarBlock(workspace, variable_id) {
  if (!Blockly.Blocks['get_var_block']) {
    fail();
  }
  // Turn off events to avoid testing XML at the same time.
  Blockly.Events.disable();
  var block = new Blockly.Block(workspace, 'get_var_block');
  block.inputList[0].fieldRow[0].setValue(variable_id);
  Blockly.Events.enable();
  return block;
}

function createTwoVariablesAndBlocks(workspace) {
  // Create two variables of different types.
  workspace.createVariable('name1', 'type1', 'id1');
  workspace.createVariable('name2', 'type2', 'id2');
  // Create blocks to refer to both of them.
  createMockVarBlock(workspace, 'id1');
  createMockVarBlock(workspace, 'id2');
}

function createVariableAndBlock(workspace) {
  workspace.createVariable('name1', 'type1', 'id1');
  createMockVarBlock(workspace, 'id1');
}

function defineGetVarBlock() {
  Blockly.defineBlocksWithJsonArray([{
    "type": "get_var_block",
    "message0": "%1",
    "args0": [
      {
        "type": "field_variable",
        "name": "VAR",
        "variableTypes": ["", "type1", "type2"]
      }
    ]
  }]);
}

function undefineGetVarBlock() {
  delete Blockly.Blocks['get_var_block'];
}

/**
 * Capture the strings sent to console.warn() when calling a function.
 * @param {function} innerFunc The function where warnings may called.
 * @return {string[]} The warning messages (only the first arguments).
 */
function captureWarnings(innerFunc) {
  var msgs = [];
  var nativeConsoleWarn = console.warn;
  try {
    console.warn = function(msg) {
      msgs.push(msg);
      nativeConsoleWarn.apply(console, arguments);
    };
    innerFunc();
  } finally {
    console.warn = nativeConsoleWarn;
  }
  return msgs;
}
<commit_msg>Failing unit tests no longer show useful info.<commit_after>/**
 * @license
 * Visual Blocks Editor
 *
 * Copyright 2017 Google Inc.
 * https://developers.google.com/blockly/
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *   http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

 /**
 * @fileoverview Test utilities.
 * @author marisaleung@google.com (Marisa Leung)
 */
'use strict';

goog.require('goog.testing');

/**
 * The normal blockly event fire function.  We sometimes override this.  This
 * handle lets us reset after an override.
 */
var savedFireFunc = Blockly.Events.fire;

// Asserts must be disabled or else errors can't be shown when running on
// file:// URLs.
goog.asserts.ENABLE_ASSERTS = false;

/**
 * A helper function to replace Blockly.Events.fire in tests.
 */
function temporary_fireEvent(event) {
  if (!Blockly.Events.isEnabled()) {
    return;
  }
  Blockly.Events.FIRE_QUEUE_.push(event);
  Blockly.Events.fireNow_();
}

/**
 * Check that two arrays have the same content.
 * @param {!Array.<string>} array1 The first array.
 * @param {!Array.<string>} array2 The second array.
 */
function isEqualArrays(array1, array2) {
  assertEquals(array1.length, array2.length);
  for (var i = 0; i < array1.length; i++) {
    assertEquals(array1[i], array2[i]);
  }
}

/**
 * Creates a controlled MethodMock. Sets the expected return values and
 *     the parameters if any exist. Sets the method to replay.
 * @param {!goog.testing.MockControl} mockControl Object that holds a set
 *    of mocks for this test.
 * @param {!Object} scope The scope of the method to be mocked out.
 * @param {!string} funcName The name of the function we're going to mock.
 * @param {Array<Object>} parameters The parameters to call the mock with.
 * @param {Array<!Object>} return_values The values to return when called.
 * @return {!goog.testing.MockInterface} The mocked method.
 */
function setUpMockMethod(mockControl, scope, funcName, parameters,
	return_values) {
  var mockMethod = mockControl.createMethodMock(scope, funcName);
  if (return_values) {
    for (var i = 0, return_value; return_value = return_values[i]; i++) {
      if (parameters && i < parameters.length) {
        mockMethod(parameters[i]).$returns(return_value);
      }
      else {
        mockMethod().$returns(return_value);
      }
    }
  }
  // If there are no return values but there are parameters, we are only
  // recording specific method calls.
  else if (parameters) {
    for (var i = 0; i < parameters.length; i++) {
      mockMethod(parameters[i]);
    }
  }
  mockMethod.$replay();
  return mockMethod;
}

/**
 * Check if a variable with the given values exists.
 * @param {Blockly.Workspace|Blockly.VariableMap} container The workspace  or
 *     variableMap the checked variable belongs to.
 * @param {!string} name The expected name of the variable.
 * @param {!string} type The expected type of the variable.
 * @param {!string} id The expected id of the variable.
 */
function checkVariableValues(container, name, type, id) {
  var variable = container.getVariableById(id);
  assertNotUndefined(variable);
  assertEquals(name, variable.name);
  assertEquals(type, variable.type);
  assertEquals(id, variable.getId());
}

/**
 * Create a test get_var_block.
 * Will fail if get_var_block isn't defined.
 * @param {!Blockly.Workspace} workspace The workspace on which to create the
 *     block.
 * @param {!string} variable_id The id of the variable to reference.
 * @return {!Blockly.Block} The created block.
 */
function createMockVarBlock(workspace, variable_id) {
  if (!Blockly.Blocks['get_var_block']) {
    fail();
  }
  // Turn off events to avoid testing XML at the same time.
  Blockly.Events.disable();
  var block = new Blockly.Block(workspace, 'get_var_block');
  block.inputList[0].fieldRow[0].setValue(variable_id);
  Blockly.Events.enable();
  return block;
}

function createTwoVariablesAndBlocks(workspace) {
  // Create two variables of different types.
  workspace.createVariable('name1', 'type1', 'id1');
  workspace.createVariable('name2', 'type2', 'id2');
  // Create blocks to refer to both of them.
  createMockVarBlock(workspace, 'id1');
  createMockVarBlock(workspace, 'id2');
}

function createVariableAndBlock(workspace) {
  workspace.createVariable('name1', 'type1', 'id1');
  createMockVarBlock(workspace, 'id1');
}

function defineGetVarBlock() {
  Blockly.defineBlocksWithJsonArray([{
    "type": "get_var_block",
    "message0": "%1",
    "args0": [
      {
        "type": "field_variable",
        "name": "VAR",
        "variableTypes": ["", "type1", "type2"]
      }
    ]
  }]);
}

function undefineGetVarBlock() {
  delete Blockly.Blocks['get_var_block'];
}

/**
 * Capture the strings sent to console.warn() when calling a function.
 * @param {function} innerFunc The function where warnings may called.
 * @return {string[]} The warning messages (only the first arguments).
 */
function captureWarnings(innerFunc) {
  var msgs = [];
  var nativeConsoleWarn = console.warn;
  try {
    console.warn = function(msg) {
      msgs.push(msg);
      nativeConsoleWarn.apply(console, arguments);
    };
    innerFunc();
  } finally {
    console.warn = nativeConsoleWarn;
  }
  return msgs;
}
<|endoftext|>


<commit_before>var util = require('util');
var nukiConstants = require('./nuki-constants');
var _ = require('underscore');
var crc = require('crc');
var sodium = require('sodium');
var HSalsa20 = require('./hsalsa20');
var crypto = require('crypto');

var bleno = require('bleno');
var BlenoCharacteristic = bleno.Characteristic;
var BlenoDescriptor = bleno.Descriptor;

function PairingGeneralDataInputOutputCharacteristic(keys) {
    this.state = this.PAIRING_IDLE;
    this.keys = keys;
    this.dataStillToSend = new Buffer(0);

    PairingGeneralDataInputOutputCharacteristic.super_.call(this, {
        // uuid: 'a92ee101-5501-11e4-916c-0800200c9a66',
        uuid: 'a92ee101550111e4916c0800200c9a66',
        properties: ['write', 'indicate'],
        descriptors: [
            new BlenoDescriptor({
                uuid: '2902',   // client characterstic configuration
                value: 'Pairing commands'
            })
        ]
    });
}

util.inherits(PairingGeneralDataInputOutputCharacteristic, BlenoCharacteristic);

PairingGeneralDataInputOutputCharacteristic.prototype.PAIRING_IDLE = 0;
PairingGeneralDataInputOutputCharacteristic.prototype.PAIRING_SL_SEND_PUBKEY = 1;
PairingGeneralDataInputOutputCharacteristic.prototype.PAIRING_CL_SEND_PUBKEY = 2;
PairingGeneralDataInputOutputCharacteristic.prototype.PAIRING_SL_SEND_CHALLENGE = 3;
PairingGeneralDataInputOutputCharacteristic.prototype.PAIRING_CL_SEND_AUTHENTICATOR = 4;

PairingGeneralDataInputOutputCharacteristic.prototype.getNextChunk = function (data) {
    var block0;
    if (data.length > 20) {
        block0 = data.slice(0, 20);
        this.dataStillToSend = data.slice(20);
    } else {
        block0 = data;
        this.dataStillToSend = new Buffer(0);
    }
    return block0;
};

PairingGeneralDataInputOutputCharacteristic.prototype.prepareDataToSend = function (cmd, data) {
    var cmdBuffer = new Buffer(2);
    cmdBuffer.writeUInt16LE(cmd);
    var responseData = Buffer.concat([cmdBuffer, data]);
    var checksum = crc.crc16ccitt(responseData);
    var checksumBuffer = new Buffer(2);
    checksumBuffer.writeUInt16LE(checksum);
    this.dataStillToSend = Buffer.concat([responseData, checksumBuffer]);
    console.log("prepared to send:", this.dataStillToSend);
};

PairingGeneralDataInputOutputCharacteristic.prototype.onWriteRequest = function (data, offset, withoutResponse, callback) {
    var cmdId, slPk;
    console.log("PairingGeneralDataInputOutputCharacteristic", data);
    var dataForCrc = data.slice(0, data.length - 2);
    var crcSumCalc = crc.crc16ccitt(dataForCrc);
    var crcSumRetrieved = data.readUInt16LE(data.length - 2);

    if (crcSumCalc === crcSumRetrieved) {
        console.log("checksum is ok");
        if (offset) {
            callback(this.RESULT_ATTR_NOT_LONG);
        } else if (data.length > 200) {
            callback(this.RESULT_INVALID_ATTRIBUTE_LENGTH);
        } else {
            switch (this.state) {
                case PairingGeneralDataInputOutputCharacteristic.prototype.PAIRING_IDLE:
                    var rCmd = data.readUInt16LE(0);
                    cmdId = data.readUInt16LE(2);
                    if (rCmd === nukiConstants.CMD_reqUEST_DATA && cmdId === nukiConstants.CMD_ID_PUBLIC_KEY) {
                        slPk = new Buffer(0);
                        if (Buffer.isBuffer(this.keys.slPk)) {
                            slPk = this.keys.slPk;
                        } else {
                            if (_.isString(this.keys.slPk)) {
                                slPk = new Buffer(this.keys.slPk, 'hex');
                            } else {
                                if (_.isArray(this.keys.slPk)) {
                                    slPk = new Buffer(this.keys.slPk);
                                }
                            }
                        }

                        if (slPk.length > 0) {
                            this.prepareDataToSend(nukiConstants.CMD_ID_PUBLIC_KEY, slPk);
                            this.state = PairingGeneralDataInputOutputCharacteristic.prototype.PAIRING_SL_SEND_PUBKEY;

                            callback(this.RESULT_SUCCESS);
                        } else {
                            console.log("ERROR missing SL public key");
                            this.state = this.PAIRING_IDLE;
                            callback(this.RESULT_UNLIKELY_ERROR);
                        }
                    }
                    else {
                        console.log("command or command identifier wrong");
                        this.state = this.PAIRING_IDLE;
                        callback(this.RESULT_UNLIKELY_ERROR);
                    }
                    break;
                case PairingGeneralDataInputOutputCharacteristic.prototype.PAIRING_CL_SEND_PUBKEY:
                    cmdId = data.readUInt16LE(0);
                    if (cmdId === nukiConstants.CMD_ID_PUBLIC_KEY) {
                        this.keys.clPk = data.slice(2, data.length - 2);
                        console.log("CL PUBKEY:", this.keys.clPk);

                        slPk = new Buffer(0);
                        if (Buffer.isBuffer(this.keys.slPk)) {
                            slPk = this.keys.slPk;
                        } else {
                            if (_.isString(this.keys.slPk)) {
                                slPk = new Buffer(this.keys.slPk, 'hex');
                            } else {
                                if (_.isArray(this.keys.slPk)) {
                                    slPk = new Buffer(this.keys.slPk);
                                }
                            }
                        }
                        var slSk = new Buffer(0);
                        if (Buffer.isBuffer(this.keys.slSk)) {
                            slSk = this.keys.slSk;
                        } else {
                            if (_.isString(this.keys.slSk)) {
                                slSk = new Buffer(this.keys.slSk, 'hex');
                            } else {
                                if (_.isArray(this.keys.slSk)) {
                                    slSk = new Buffer(this.keys.slSk);
                                }
                            }
                        }

                        console.log("slPK", slPk);
                        console.log("slSK", slSk);
                        console.log("clPK", this.keys.clPk);

                        // Create Diffie-Hellman key from nuki secret key and clients public key
                        // crypto_scalarmult_curve25519(k,secretKey,pk)
                        var k = sodium.api.crypto_scalarmult(slSk, this.keys.clPk);
                        console.log("SL DH Key from SL SK and CL PK: ", k);

                        // derive a longterm shared secret key s from k using function kdf1
                        // static const unsigned char _0[16];
                        // static const unsigned char sigma[16] = "expand 32-byte k";
                        // crypto_core_hsalsa20(firstKey,_0,sharedKey,sigma)
                        var hsalsa20 = new HSalsa20();
                        var sharedSecret = new Buffer(32);
                        var inv = new Buffer(16);
                        inv.fill(0);
                        var c = new Buffer("expand 32-byte k");
                        hsalsa20.crypto_core(sharedSecret, inv, k, c);
                        console.log("derived shared key: ", sharedSecret);

                        console.log("Creating one time challenge...");
                        var nonce = new Buffer(nukiConstants.NUKI_NONCEBYTES);
                        sodium.api.randombytes_buf(nonce);
                        // todo remove hardcoded challenge
                        nonce = new Buffer("6CD4163D159050C798553EAA57E278A579AFFCBC56F09FC57FE879E51C42DF17", 'hex');
                        if (nonce.length != nukiConstants.NUKI_NONCEBYTES) {
                            console.log("Nonce length (" + nonce.length + ") is not " + nukiConstants.NUKI_NONCEBYTES);
                            this.state = this.PAIRING_IDLE;
                            callback(this.RESULT_UNLIKELY_ERROR);
                            return;
                        }

                        this.state = PairingGeneralDataInputOutputCharacteristic.prototype.PAIRING_SL_SEND_CHALLENGE;
                        this.prepareDataToSend(nukiConstants.CMD_CHALLENGE, nonce);
                        var value = this.getNextChunk(this.dataStillToSend);
                        if (this._updateValueCallback && value.length > 0) {
                            console.log("sending challenge: " + value.length + " bytes");
                            this._updateValueCallback(value);
                        }

                        var r = Buffer.concat([this.keys.clPk, slPk, nonce]);
                        // use HMAC-SHA256 to create the authenticator
                        var a = crypto.createHmac('SHA256', sharedSecret).update(r);
                        console.log("Authorization authenticator from SL", a);

                        callback(this.RESULT_SUCCESS);
                    }
                    else {
                        console.log("command or command identifier wrong");
                        this.state = this.PAIRING_IDLE;
                        callback(this.RESULT_UNLIKELY_ERROR);
                    }

                    break;
                case PairingGeneralDataInputOutputCharacteristic.prototype.PAIRING_CL_SEND_AUTHENTICATOR:
                    cmdId = data.readUInt16LE(0);
                    if (cmdId === nukiConstants.CMD_AUTHORIZATION_AUTHENTICATOR) {
                        var clAuthenticator = data.slice(2, data.length - 2);
                        console.log("CL sent authorization authenticator", clAuthenticator);

                        // todo verify authenticator
                    }
                    else {
                        console.log("command or command identifier wrong");
                        this.state = this.PAIRING_IDLE;
                        callback(this.RESULT_UNLIKELY_ERROR);
                    }
                    break;
                default:
                    console.log("ERROR unexpected pairing state");
                    this.state = this.PAIRING_IDLE;
                    callback(this.RESULT_UNLIKELY_ERROR);
            }
        }
    } else {
        console.log("checksum is NOT ok");
        this.state = this.PAIRING_IDLE;
        callback(this.RESULT_UNLIKELY_ERROR);
    }
};

PairingGeneralDataInputOutputCharacteristic.prototype.onSubscribe = function (maxValueSize, updateValueCallback) {
    console.log('PairingGeneralDataInputOutputCharacteristic - onSubscribe');

    this._updateValueCallback = updateValueCallback;

    if (this.dataStillToSend.length > 0) {
        switch (this.state) {
            case PairingGeneralDataInputOutputCharacteristic.prototype.PAIRING_SL_SEND_PUBKEY:

                var value = this.getNextChunk(this.dataStillToSend);
                if (value.length > 0) {
                    console.log("sending " + value.length + " bytes from onSubscribe");
                    updateValueCallback(value);
                }

                if (this.dataStillToSend.length === 0) {
                    this.state = PairingGeneralDataInputOutputCharacteristic.prototype.PAIRING_CL_SEND_PUBKEY;
                }

                break;
            default:
                console.log("ERROR unexpected pairing state");
                this.state = this.PAIRING_IDLE;
        }
    } else {
        console.log("don't have more data to notify");
    }
};

PairingGeneralDataInputOutputCharacteristic.prototype.onUnsubscribe = function () {
    console.log('PairingGeneralDataInputOutputCharacteristic - onUnsubscribe');

    this._updateValueCallback = null;
};

PairingGeneralDataInputOutputCharacteristic.prototype.onIndicate = function () {
    console.log("PairingGeneralDataInputOutputCharacteristic indicate");
    if (this.dataStillToSend.length > 0) {
        if (this._updateValueCallback) {
            var value;
            switch (this.state) {
                case PairingGeneralDataInputOutputCharacteristic.prototype.PAIRING_SL_SEND_PUBKEY:
                    value = this.getNextChunk(this.dataStillToSend);
                    if (value.length > 0) {
                        console.log("sending " + value.length + " bytes as indication");
                        this._updateValueCallback(value);
                    }
                    if (this.dataStillToSend.length === 0) {
                        this.state = PairingGeneralDataInputOutputCharacteristic.prototype.PAIRING_CL_SEND_PUBKEY;
                    }

                    break;
                case PairingGeneralDataInputOutputCharacteristic.prototype.PAIRING_SL_SEND_CHALLENGE:
                    value = this.getNextChunk(this.dataStillToSend);
                    if (value.length > 0) {
                        console.log("sending " + value.length + " bytes as indication");
                        this._updateValueCallback(value);
                    }
                    if (this.dataStillToSend.length === 0) {
                        this.state = PairingGeneralDataInputOutputCharacteristic.prototype.PAIRING_CL_SEND_AUTHENTICATOR;
                    }
                    break;
                default:
                    console.log("ERROR unexpected pairing state");
                    this.state = this.PAIRING_IDLE;
            }
        } else {
            console.log("don't have updateValueCallback on indicate");
            this.state = this.PAIRING_IDLE;
        }
    } else {
        console.log("don't have more data to indicate");
    }
};

module.exports = PairingGeneralDataInputOutputCharacteristic;
<commit_msg>call digest to get hmac<commit_after>var util = require('util');
var nukiConstants = require('./nuki-constants');
var _ = require('underscore');
var crc = require('crc');
var sodium = require('sodium');
var HSalsa20 = require('./hsalsa20');
var crypto = require('crypto');

var bleno = require('bleno');
var BlenoCharacteristic = bleno.Characteristic;
var BlenoDescriptor = bleno.Descriptor;

function PairingGeneralDataInputOutputCharacteristic(keys) {
    this.state = this.PAIRING_IDLE;
    this.keys = keys;
    this.dataStillToSend = new Buffer(0);

    PairingGeneralDataInputOutputCharacteristic.super_.call(this, {
        // uuid: 'a92ee101-5501-11e4-916c-0800200c9a66',
        uuid: 'a92ee101550111e4916c0800200c9a66',
        properties: ['write', 'indicate'],
        descriptors: [
            new BlenoDescriptor({
                uuid: '2902',   // client characterstic configuration
                value: 'Pairing commands'
            })
        ]
    });
}

util.inherits(PairingGeneralDataInputOutputCharacteristic, BlenoCharacteristic);

PairingGeneralDataInputOutputCharacteristic.prototype.PAIRING_IDLE = 0;
PairingGeneralDataInputOutputCharacteristic.prototype.PAIRING_SL_SEND_PUBKEY = 1;
PairingGeneralDataInputOutputCharacteristic.prototype.PAIRING_CL_SEND_PUBKEY = 2;
PairingGeneralDataInputOutputCharacteristic.prototype.PAIRING_SL_SEND_CHALLENGE = 3;
PairingGeneralDataInputOutputCharacteristic.prototype.PAIRING_CL_SEND_AUTHENTICATOR = 4;

PairingGeneralDataInputOutputCharacteristic.prototype.getNextChunk = function (data) {
    var block0;
    if (data.length > 20) {
        block0 = data.slice(0, 20);
        this.dataStillToSend = data.slice(20);
    } else {
        block0 = data;
        this.dataStillToSend = new Buffer(0);
    }
    return block0;
};

PairingGeneralDataInputOutputCharacteristic.prototype.prepareDataToSend = function (cmd, data) {
    var cmdBuffer = new Buffer(2);
    cmdBuffer.writeUInt16LE(cmd);
    var responseData = Buffer.concat([cmdBuffer, data]);
    var checksum = crc.crc16ccitt(responseData);
    var checksumBuffer = new Buffer(2);
    checksumBuffer.writeUInt16LE(checksum);
    this.dataStillToSend = Buffer.concat([responseData, checksumBuffer]);
    console.log("prepared to send:", this.dataStillToSend);
};

PairingGeneralDataInputOutputCharacteristic.prototype.onWriteRequest = function (data, offset, withoutResponse, callback) {
    var cmdId, slPk;
    console.log("PairingGeneralDataInputOutputCharacteristic", data);
    var dataForCrc = data.slice(0, data.length - 2);
    var crcSumCalc = crc.crc16ccitt(dataForCrc);
    var crcSumRetrieved = data.readUInt16LE(data.length - 2);

    if (crcSumCalc === crcSumRetrieved) {
        console.log("checksum is ok");
        if (offset) {
            callback(this.RESULT_ATTR_NOT_LONG);
        } else if (data.length > 200) {
            callback(this.RESULT_INVALID_ATTRIBUTE_LENGTH);
        } else {
            switch (this.state) {
                case PairingGeneralDataInputOutputCharacteristic.prototype.PAIRING_IDLE:
                    var rCmd = data.readUInt16LE(0);
                    cmdId = data.readUInt16LE(2);
                    if (rCmd === nukiConstants.CMD_reqUEST_DATA && cmdId === nukiConstants.CMD_ID_PUBLIC_KEY) {
                        slPk = new Buffer(0);
                        if (Buffer.isBuffer(this.keys.slPk)) {
                            slPk = this.keys.slPk;
                        } else {
                            if (_.isString(this.keys.slPk)) {
                                slPk = new Buffer(this.keys.slPk, 'hex');
                            } else {
                                if (_.isArray(this.keys.slPk)) {
                                    slPk = new Buffer(this.keys.slPk);
                                }
                            }
                        }

                        if (slPk.length > 0) {
                            this.prepareDataToSend(nukiConstants.CMD_ID_PUBLIC_KEY, slPk);
                            this.state = PairingGeneralDataInputOutputCharacteristic.prototype.PAIRING_SL_SEND_PUBKEY;

                            callback(this.RESULT_SUCCESS);
                        } else {
                            console.log("ERROR missing SL public key");
                            this.state = this.PAIRING_IDLE;
                            callback(this.RESULT_UNLIKELY_ERROR);
                        }
                    }
                    else {
                        console.log("command or command identifier wrong");
                        this.state = this.PAIRING_IDLE;
                        callback(this.RESULT_UNLIKELY_ERROR);
                    }
                    break;
                case PairingGeneralDataInputOutputCharacteristic.prototype.PAIRING_CL_SEND_PUBKEY:
                    cmdId = data.readUInt16LE(0);
                    if (cmdId === nukiConstants.CMD_ID_PUBLIC_KEY) {
                        this.keys.clPk = data.slice(2, data.length - 2);
                        console.log("CL PUBKEY:", this.keys.clPk);

                        slPk = new Buffer(0);
                        if (Buffer.isBuffer(this.keys.slPk)) {
                            slPk = this.keys.slPk;
                        } else {
                            if (_.isString(this.keys.slPk)) {
                                slPk = new Buffer(this.keys.slPk, 'hex');
                            } else {
                                if (_.isArray(this.keys.slPk)) {
                                    slPk = new Buffer(this.keys.slPk);
                                }
                            }
                        }
                        var slSk = new Buffer(0);
                        if (Buffer.isBuffer(this.keys.slSk)) {
                            slSk = this.keys.slSk;
                        } else {
                            if (_.isString(this.keys.slSk)) {
                                slSk = new Buffer(this.keys.slSk, 'hex');
                            } else {
                                if (_.isArray(this.keys.slSk)) {
                                    slSk = new Buffer(this.keys.slSk);
                                }
                            }
                        }

                        console.log("slPK", slPk);
                        console.log("slSK", slSk);
                        console.log("clPK", this.keys.clPk);

                        // Create Diffie-Hellman key from nuki secret key and clients public key
                        // crypto_scalarmult_curve25519(k,secretKey,pk)
                        var k = sodium.api.crypto_scalarmult(slSk, this.keys.clPk);
                        console.log("SL DH Key from SL SK and CL PK: ", k);

                        // derive a longterm shared secret key s from k using function kdf1
                        // static const unsigned char _0[16];
                        // static const unsigned char sigma[16] = "expand 32-byte k";
                        // crypto_core_hsalsa20(firstKey,_0,sharedKey,sigma)
                        var hsalsa20 = new HSalsa20();
                        var sharedSecret = new Buffer(32);
                        var inv = new Buffer(16);
                        inv.fill(0);
                        var c = new Buffer("expand 32-byte k");
                        hsalsa20.crypto_core(sharedSecret, inv, k, c);
                        console.log("derived shared key: ", sharedSecret);

                        console.log("Creating one time challenge...");
                        var nonce = new Buffer(nukiConstants.NUKI_NONCEBYTES);
                        sodium.api.randombytes_buf(nonce);
                        // todo remove hardcoded challenge
                        nonce = new Buffer("6CD4163D159050C798553EAA57E278A579AFFCBC56F09FC57FE879E51C42DF17", 'hex');
                        if (nonce.length != nukiConstants.NUKI_NONCEBYTES) {
                            console.log("Nonce length (" + nonce.length + ") is not " + nukiConstants.NUKI_NONCEBYTES);
                            this.state = this.PAIRING_IDLE;
                            callback(this.RESULT_UNLIKELY_ERROR);
                            return;
                        }

                        this.state = PairingGeneralDataInputOutputCharacteristic.prototype.PAIRING_SL_SEND_CHALLENGE;
                        this.prepareDataToSend(nukiConstants.CMD_CHALLENGE, nonce);
                        var value = this.getNextChunk(this.dataStillToSend);
                        if (this._updateValueCallback && value.length > 0) {
                            console.log("sending challenge: " + value.length + " bytes");
                            this._updateValueCallback(value);
                        }

                        var r = Buffer.concat([this.keys.clPk, slPk, nonce]);
                        // use HMAC-SHA256 to create the authenticator
                        var a = crypto.createHmac('SHA256', sharedSecret).update(r).digest();
                        console.log("Authorization authenticator from SL", a);

                        callback(this.RESULT_SUCCESS);
                    }
                    else {
                        console.log("command or command identifier wrong");
                        this.state = this.PAIRING_IDLE;
                        callback(this.RESULT_UNLIKELY_ERROR);
                    }

                    break;
                case PairingGeneralDataInputOutputCharacteristic.prototype.PAIRING_CL_SEND_AUTHENTICATOR:
                    cmdId = data.readUInt16LE(0);
                    if (cmdId === nukiConstants.CMD_AUTHORIZATION_AUTHENTICATOR) {
                        var clAuthenticator = data.slice(2, data.length - 2);
                        console.log("CL sent authorization authenticator", clAuthenticator);

                        // todo verify authenticator
                    }
                    else {
                        console.log("command or command identifier wrong");
                        this.state = this.PAIRING_IDLE;
                        callback(this.RESULT_UNLIKELY_ERROR);
                    }
                    break;
                default:
                    console.log("ERROR unexpected pairing state");
                    this.state = this.PAIRING_IDLE;
                    callback(this.RESULT_UNLIKELY_ERROR);
            }
        }
    } else {
        console.log("checksum is NOT ok");
        this.state = this.PAIRING_IDLE;
        callback(this.RESULT_UNLIKELY_ERROR);
    }
};

PairingGeneralDataInputOutputCharacteristic.prototype.onSubscribe = function (maxValueSize, updateValueCallback) {
    console.log('PairingGeneralDataInputOutputCharacteristic - onSubscribe');

    this._updateValueCallback = updateValueCallback;

    if (this.dataStillToSend.length > 0) {
        switch (this.state) {
            case PairingGeneralDataInputOutputCharacteristic.prototype.PAIRING_SL_SEND_PUBKEY:

                var value = this.getNextChunk(this.dataStillToSend);
                if (value.length > 0) {
                    console.log("sending " + value.length + " bytes from onSubscribe");
                    updateValueCallback(value);
                }

                if (this.dataStillToSend.length === 0) {
                    this.state = PairingGeneralDataInputOutputCharacteristic.prototype.PAIRING_CL_SEND_PUBKEY;
                }

                break;
            default:
                console.log("ERROR unexpected pairing state");
                this.state = this.PAIRING_IDLE;
        }
    } else {
        console.log("don't have more data to notify");
    }
};

PairingGeneralDataInputOutputCharacteristic.prototype.onUnsubscribe = function () {
    console.log('PairingGeneralDataInputOutputCharacteristic - onUnsubscribe');

    this._updateValueCallback = null;
};

PairingGeneralDataInputOutputCharacteristic.prototype.onIndicate = function () {
    console.log("PairingGeneralDataInputOutputCharacteristic indicate");
    if (this.dataStillToSend.length > 0) {
        if (this._updateValueCallback) {
            var value;
            switch (this.state) {
                case PairingGeneralDataInputOutputCharacteristic.prototype.PAIRING_SL_SEND_PUBKEY:
                    value = this.getNextChunk(this.dataStillToSend);
                    if (value.length > 0) {
                        console.log("sending " + value.length + " bytes as indication");
                        this._updateValueCallback(value);
                    }
                    if (this.dataStillToSend.length === 0) {
                        this.state = PairingGeneralDataInputOutputCharacteristic.prototype.PAIRING_CL_SEND_PUBKEY;
                    }

                    break;
                case PairingGeneralDataInputOutputCharacteristic.prototype.PAIRING_SL_SEND_CHALLENGE:
                    value = this.getNextChunk(this.dataStillToSend);
                    if (value.length > 0) {
                        console.log("sending " + value.length + " bytes as indication");
                        this._updateValueCallback(value);
                    }
                    if (this.dataStillToSend.length === 0) {
                        this.state = PairingGeneralDataInputOutputCharacteristic.prototype.PAIRING_CL_SEND_AUTHENTICATOR;
                    }
                    break;
                default:
                    console.log("ERROR unexpected pairing state");
                    this.state = this.PAIRING_IDLE;
            }
        } else {
            console.log("don't have updateValueCallback on indicate");
            this.state = this.PAIRING_IDLE;
        }
    } else {
        console.log("don't have more data to indicate");
    }
};

module.exports = PairingGeneralDataInputOutputCharacteristic;
<|endoftext|>


<commit_before>'use strict';

var I = require('immutable');

var BASE_LENGTH = I.Range(1)
  .filter(function(n) {
    if (n % 2)
      return false;
    var b = Math.pow(10, n);
    return 2 * b - 2 == 2 * b - 1 || -2 * b + 2 == -2 * b + 1;
  }).first() - 1;

var BASE = Math.pow(10, BASE_LENGTH);
var HALFBASE = Math.sqrt(BASE);

var LongInt = function LongInt() {};

var make = function make(sign, digits) {
  return {
    type  : LongInt,
    sign  : digits ? sign : 0,
    digits: digits
  };
};

var promote = function promote(n) {
  var sign = (n > 0) - (n < 0);
  n = Math.abs(n);

  var digits = I.List().withMutations(function(list) {
    while (n > 0) {
      list.push(n % BASE);
      n = Math.floor(n / BASE);
    }
  });

  return make(sign, digits);
};

var parse = function parse(literal) {
  if (!literal.match(/^[+-]?\d+$/))
    throw new Error("expected an integer literal, got "+literal);

  var sign = literal[0] == '-' ? -1 : 1;

  var digits = I.List().withMutations(function(list) {
    var n = literal.length;
    while (n > 0) {
      var m = Math.max(n - BASE_LENGTH, 0);
      var start = (m == 0 && literal.match(/^[+-]/)) ? 1 : m;
      list.push(parseInt(literal.slice(start, n)));
      n = m;
    }

    while (list.size > 0 && list.last() == 0)
      list.pop();
  });

  if (digits.size == 0)
    sign = 0;

  return make(sign, digits);
};

var negative = function negative(n) {
  return make(-n.sign, n.digits);
};

var abs = function abs(n) {
  return make(1, n.digits);
};

var sgn = function sgn(n) {
};

module.exports = {
  type    : LongInt,
  promote : promote,
  parse   : parse,
  negative: negative,
  abs     : abs,
  sgn     : sgn
};
<commit_msg>clean up make()<commit_after>'use strict';

var I = require('immutable');

var BASE_LENGTH = I.Range(1)
  .filter(function(n) {
    if (n % 2)
      return false;
    var b = Math.pow(10, n);
    return 2 * b - 2 == 2 * b - 1 || -2 * b + 2 == -2 * b + 1;
  }).first() - 1;

var BASE = Math.pow(10, BASE_LENGTH);
var HALFBASE = Math.sqrt(BASE);

var LongInt = function LongInt() {};

var make = function make(sign, digits) {
  return {
    type  : LongInt,
    sign  : sign,
    digits: digits
  };
};

var promote = function promote(n) {
  var sign = (n > 0) - (n < 0);
  n = Math.abs(n);

  var digits = I.List().withMutations(function(list) {
    while (n > 0) {
      list.push(n % BASE);
      n = Math.floor(n / BASE);
    }
  });

  return make(sign, digits);
};

var parse = function parse(literal) {
  if (!literal.match(/^[+-]?\d+$/))
    throw new Error("expected an integer literal, got "+literal);

  var sign = literal[0] == '-' ? -1 : 1;

  var digits = I.List().withMutations(function(list) {
    var n = literal.length;
    while (n > 0) {
      var m = Math.max(n - BASE_LENGTH, 0);
      var start = (m == 0 && literal.match(/^[+-]/)) ? 1 : m;
      list.push(parseInt(literal.slice(start, n)));
      n = m;
    }

    while (list.size > 0 && list.last() == 0)
      list.pop();
  });

  if (digits.size == 0)
    sign = 0;

  return make(sign, digits);
};

var negative = function negative(n) {
  return make(-n.sign, n.digits);
};

var abs = function abs(n) {
  return make(1, n.digits);
};

var sgn = function sgn(n) {
};

module.exports = {
  type    : LongInt,
  promote : promote,
  parse   : parse,
  negative: negative,
  abs     : abs,
  sgn     : sgn
};
<|endoftext|>


<commit_before>'use strict';
var React = require('react');
var jsonScriptEscape = require('../libs/jsonScriptEscape');
var globals = require('./globals');
var mixins = require('./mixins');
var HomePage = require('./home');
var ErrorPage = require('./error');
var Navigation = require('./navigation');
var HelpPage = require('./help');
var AboutPage = require('./about');
var Footer = require('./footer');
var url = require('url');
var _ = require('underscore');
var store = require('../store');
var browse = require('./browse');

//sid is to allow addition of supplementary ids to navbar link headings

var portal = {
    portal_title: '4DN Data Portal',
    global_sections: [
        {id: 'browse', sid:'sBrowse', title: 'Browse', url: '/browse/?type=ExperimentSet&experimentset_type=biological+replicates'},
        {id: 'help', sid:'sHelp', title: 'Help', children: [
            {id: 'gettingstarted', title: 'Getting started', url: '/help'},
            {id: 'metadatastructure', title: 'Metadata structure', url: '/help#metadata-structure'},
            {id: 'datasubmission', title: 'Data submission', url: '/help#data-submission'},
            {id: 'restapi', title: 'REST API', url: '/help#rest-api'},
            {id: 'about', title: 'About', url: '/about/'}
        ]}
    ],
    user_section: [
            {id: 'login', title: 'Log in', url: '/'},
            {id: 'accountactions', title: 'Register', url: '/help/'}
            // Remove context actions for now{id: 'contextactions', title: 'Actions', url: '/'}
    ]
};

// See https://github.com/facebook/react/issues/2323
var Title = React.createClass({
    render: function() {
        return <title {...this.props}>{this.props.children}</title>;
    },
    componentDidMount: function() {
        var node = document.querySelector('title');
        if (node && !node.getAttribute('data-reactid')) {
            node.setAttribute('data-reactid', this._rootNodeID);
        }
    }
});

// App is the root component, mounted on document.body.
// It lives for the entire duration the page is loaded.
// App maintains state for the
var App = React.createClass({
    mixins: [mixins.Auth0, mixins.HistoryAndTriggers],
    triggers: {
        login: 'triggerLogin',
        profile: 'triggerProfile',
        logout: 'triggerLogout'
    },

    getInitialState: function() {
        return {
            errors: [],
            dropdownComponent: undefined,
            content: undefined
        };
    },

    // Dropdown context using React context mechanism.
    childContextTypes: {
        dropdownComponent: React.PropTypes.string,
        listActionsFor: React.PropTypes.func,
        currentResource: React.PropTypes.func,
        location_href: React.PropTypes.string,
        onDropdownChange: React.PropTypes.func,
        portal: React.PropTypes.object,
        hidePublicAudits: React.PropTypes.bool
    },

    // Retrieve current React context
    getChildContext: function() {
        return {
            dropdownComponent: this.state.dropdownComponent, // ID of component with visible dropdown
            listActionsFor: this.listActionsFor,
            currentResource: this.currentResource,
            location_href: this.props.href,
            onDropdownChange: this.handleDropdownChange, // Function to process dropdown state change
            portal: portal,
            hidePublicAudits: true // True if audits should be hidden on the UI while logged out
        };
    },

    listActionsFor: function(category) {
        if (category === 'context') {
            var context = this.currentResource();
            var name = this.currentAction();
            var context_actions = [];
            Array.prototype.push.apply(context_actions, context.actions || []);

            if (!name && context.default_page) {
                context = context.default_page;
                var actions = context.actions || [];
                for (var i = 0; i < actions.length; i++) {
                    var action = actions[i];
                    if (action.href[0] == '#') {
                        action.href = context['@id'] + action.href;
                    }
                    context_actions.push(action);
                }
            }
            return context_actions;
        }
        if (category === 'user_section') {
            return portal.user_section;
        }
        if (category === 'user') {
            return this.state.session_properties.user_actions || [];
        }
        if (category === 'global_sections') {
            return portal.global_sections;
        }
    },

    currentResource: function() {
        return this.props.context;
    },

    currentAction: function() {
        var href_url = url.parse(this.props.href);
        var hash = href_url.hash || '';
        var name;
        if (hash.slice(0, 2) === '#!') {
            name = hash.slice(2);
        }
        return name;
    },

    // When current dropdown changes; componentID is _rootNodeID of newly dropped-down component
    handleDropdownChange: function(componentID) {
        // Use React _rootNodeID to uniquely identify a dropdown menu;
        // It's passed in as componentID
        this.setState({dropdownComponent: componentID});
    },

    handleAutocompleteChosenChange: function(chosen) {
        this.setState({autocompleteTermChosen: chosen});
    },

    handleAutocompleteFocusChange: function(focused) {
        this.setState({autocompleteFocused: focused});
    },

    handleAutocompleteHiddenChange: function(hidden) {
        this.setState({autocompleteHidden: hidden});
    },

    // Handle a click outside a dropdown menu by clearing currently dropped down menu
    handleLayoutClick: function(e) {
        if (this.state.dropdownComponent !== undefined) {
            this.setState({dropdownComponent: undefined});
        }
    },

    // If ESC pressed while drop-down menu open, close the menu
    handleKey: function(e) {
        if (e.which === 27) {
            if (this.state.dropdownComponent !== undefined) {
                e.preventDefault();
                this.handleDropdownChange(undefined);
            } else if (!this.state.autocompleteHidden) {
                e.preventDefault();
                this.handleAutocompleteHiddenChange(true);
            }
        } else if (e.which === 13 && this.state.autocompleteFocused && !this.state.autocompleteTermChosen) {
            e.preventDefault();
        }
    },

    // Once the app component is mounted, bind keydowns to handleKey function
    componentDidMount: function() {
        globals.bindEvent(window, 'keydown', this.handleKey);
    },

    render: function() {
        console.log('render app');
        var context = this.props.context;
        var content;
        var href_url = url.parse(this.props.href);
        // Switching between collections may leave component in place
        var key = context && context['@id'] && context['@id'].split('?')[0];
        var current_action = this.currentAction();

        if (!current_action && context.default_page) {
            context = context.default_page;
        }

        var errors = this.state.errors.map(function (error) {
            return

;
        });

        var appClass = 'done';
        if (this.props.slow) {
            appClass = 'communicating';
        }

        var canonical = this.props.href;
        if (context.canonical_uri) {
            if (href_url.host) {
                canonical = (href_url.protocol || '') + '//' + href_url.host + context.canonical_uri;
            } else {
                canonical = context.canonical_uri;
            }
        }

        // add static page routing
        var title;
        var routeList = canonical.split("/");
        var lowerList = [];
        var scrollList = [];
        routeList.map(function(value) {
            if (value.includes('#') && value.charAt(0) !== "#"){
                var navSplit = value.split("#");
                lowerList.push(navSplit[0].toLowerCase());
                scrollList.push(navSplit[1].toLowerCase());
            }else if(value.charAt(0) !== "!" && value.length > 0){
                lowerList.push(value.toLowerCase());
            }
        });
        var currRoute = lowerList.slice(1); // eliminate http
        // first case is fallback
        if (canonical === "about:blank"){
            title = portal.portal_title;
            content = null;
        }else if (currRoute[currRoute.length-1] === 'home' || (currRoute[currRoute.length-1] === href_url.host)){
            content = <HomePage />;
            title = portal.portal_title;
        }else if (currRoute[currRoute.length-1] === 'help'){
            content = <HelpPage />;
            title = 'Help - ' + portal.portal_title;
        }else if (currRoute[currRoute.length-1] === 'about'){
            content = <AboutPage />;
            title = 'About - ' + portal.portal_title;
        }else if (context) {
            var ContentView = globals.content_views.lookup(context, current_action);
            if (ContentView){
                content = <ContentView context={context} expSetFilters={this.props.expSetFilters}/>;
                title = context.title || context.name || context.accession || context['@id'];
                if (title && title != 'Home') {
                    title = title + ' – ' + portal.portal_title;
                } else {
                    title = portal.portal_title;
                }
            }else{
                // Handle the case where context is not loaded correctly
                content = <ErrorPage />;
                title="Not Found";
            }
        }
        // Google does not update the content of 301 redirected pages
        var base;
        if (({'http://data.4dnucleome.org/': 1})[canonical]) {
            base = canonical = 'http://data.4dnucleome.org/';
            this.historyEnabled = false;

        }
        return (

                    <meta charSet="utf-8" />
                    <meta httpEquiv="X-UA-Compatible" content="IE=edge" />
                    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
                    <Title>{title}</Title>
                    {base ? <base href={base}/> : null}
                    <link rel="canonical" href={canonical} />

                    <link href="https://fonts.googleapis.com/css?family=Work+Sans" rel="stylesheet" />
                    <link href="https://fonts.googleapis.com/css?family=Yrsa" rel="stylesheet" />

                    <link rel="stylesheet" href="/static/css/style.css" />

                                <Navigation />

                                    {content}

                                {errors}

        );
    },

    statics: {
        getRenderedProps: function (document) {
            // Ensure the initial render is exactly the same
            store.dispatch({
                type: {'href':document.querySelector('link[rel="canonical"]').getAttribute('href')}
            });
            var script_props = document.querySelectorAll('script[data-prop-name]');
            var props_dict = {};
            for (var i = 0; i < script_props.length; i++) {
                var elem = script_props[i];
                var elem_value = elem.text;
                var elem_type = elem.getAttribute('type') || '';
                if (elem_type == 'application/json' || elem_type.slice(-5) == '+json') {
                    elem_value = JSON.parse(elem_value);
                }
                props_dict[ elem.getAttribute('data-prop-name')] = elem_value;
            }
            store.dispatch({
                type: props_dict
            });
        }
    }
});

module.exports = App;
<commit_msg>FF-230 #comment updating app.js.<commit_after>'use strict';
var React = require('react');
var jsonScriptEscape = require('../libs/jsonScriptEscape');
var globals = require('./globals');
var mixins = require('./mixins');
var HomePage = require('./home');
var ErrorPage = require('./error');
var Navigation = require('./navigation');
var HelpPage = require('./help');
var AboutPage = require('./about');
var Footer = require('./footer');
var url = require('url');
var _ = require('underscore');
var store = require('../store');
var browse = require('./browse');

//sid is to allow addition of supplementary ids to navbar link headings

var portal = {
    portal_title: '4DN Data Portal',
    global_sections: [
        {id: 'browse', sid:'sBrowse', title: 'Browse', url: '/browse/?type=ExperimentSet&experimentset_type=biological+replicates&limit=all'},
        {id: 'help', sid:'sHelp', title: 'Help', children: [
            {id: 'gettingstarted', title: 'Getting started', url: '/help'},
            {id: 'metadatastructure', title: 'Metadata structure', url: '/help#metadata-structure'},
            {id: 'datasubmission', title: 'Data submission', url: '/help#data-submission'},
            {id: 'restapi', title: 'REST API', url: '/help#rest-api'},
            {id: 'about', title: 'About', url: '/about/'}
        ]}
    ],
    user_section: [
            {id: 'login', title: 'Log in', url: '/'},
            {id: 'accountactions', title: 'Register', url: '/help/'}
            // Remove context actions for now{id: 'contextactions', title: 'Actions', url: '/'}
    ]
};

// See https://github.com/facebook/react/issues/2323
var Title = React.createClass({
    render: function() {
        return <title {...this.props}>{this.props.children}</title>;
    },
    componentDidMount: function() {
        var node = document.querySelector('title');
        if (node && !node.getAttribute('data-reactid')) {
            node.setAttribute('data-reactid', this._rootNodeID);
        }
    }
});

// App is the root component, mounted on document.body.
// It lives for the entire duration the page is loaded.
// App maintains state for the
var App = React.createClass({
    mixins: [mixins.Auth0, mixins.HistoryAndTriggers],
    triggers: {
        login: 'triggerLogin',
        profile: 'triggerProfile',
        logout: 'triggerLogout'
    },

    getInitialState: function() {
        return {
            errors: [],
            dropdownComponent: undefined,
            content: undefined
        };
    },

    // Dropdown context using React context mechanism.
    childContextTypes: {
        dropdownComponent: React.PropTypes.string,
        listActionsFor: React.PropTypes.func,
        currentResource: React.PropTypes.func,
        location_href: React.PropTypes.string,
        onDropdownChange: React.PropTypes.func,
        portal: React.PropTypes.object,
        hidePublicAudits: React.PropTypes.bool
    },

    // Retrieve current React context
    getChildContext: function() {
        return {
            dropdownComponent: this.state.dropdownComponent, // ID of component with visible dropdown
            listActionsFor: this.listActionsFor,
            currentResource: this.currentResource,
            location_href: this.props.href,
            onDropdownChange: this.handleDropdownChange, // Function to process dropdown state change
            portal: portal,
            hidePublicAudits: true // True if audits should be hidden on the UI while logged out
        };
    },

    listActionsFor: function(category) {
        if (category === 'context') {
            var context = this.currentResource();
            var name = this.currentAction();
            var context_actions = [];
            Array.prototype.push.apply(context_actions, context.actions || []);

            if (!name && context.default_page) {
                context = context.default_page;
                var actions = context.actions || [];
                for (var i = 0; i < actions.length; i++) {
                    var action = actions[i];
                    if (action.href[0] == '#') {
                        action.href = context['@id'] + action.href;
                    }
                    context_actions.push(action);
                }
            }
            return context_actions;
        }
        if (category === 'user_section') {
            return portal.user_section;
        }
        if (category === 'user') {
            return this.state.session_properties.user_actions || [];
        }
        if (category === 'global_sections') {
            return portal.global_sections;
        }
    },

    currentResource: function() {
        return this.props.context;
    },

    currentAction: function() {
        var href_url = url.parse(this.props.href);
        var hash = href_url.hash || '';
        var name;
        if (hash.slice(0, 2) === '#!') {
            name = hash.slice(2);
        }
        return name;
    },

    // When current dropdown changes; componentID is _rootNodeID of newly dropped-down component
    handleDropdownChange: function(componentID) {
        // Use React _rootNodeID to uniquely identify a dropdown menu;
        // It's passed in as componentID
        this.setState({dropdownComponent: componentID});
    },

    handleAutocompleteChosenChange: function(chosen) {
        this.setState({autocompleteTermChosen: chosen});
    },

    handleAutocompleteFocusChange: function(focused) {
        this.setState({autocompleteFocused: focused});
    },

    handleAutocompleteHiddenChange: function(hidden) {
        this.setState({autocompleteHidden: hidden});
    },

    // Handle a click outside a dropdown menu by clearing currently dropped down menu
    handleLayoutClick: function(e) {
        if (this.state.dropdownComponent !== undefined) {
            this.setState({dropdownComponent: undefined});
        }
    },

    // If ESC pressed while drop-down menu open, close the menu
    handleKey: function(e) {
        if (e.which === 27) {
            if (this.state.dropdownComponent !== undefined) {
                e.preventDefault();
                this.handleDropdownChange(undefined);
            } else if (!this.state.autocompleteHidden) {
                e.preventDefault();
                this.handleAutocompleteHiddenChange(true);
            }
        } else if (e.which === 13 && this.state.autocompleteFocused && !this.state.autocompleteTermChosen) {
            e.preventDefault();
        }
    },

    // Once the app component is mounted, bind keydowns to handleKey function
    componentDidMount: function() {
        globals.bindEvent(window, 'keydown', this.handleKey);
    },

    render: function() {
        console.log('render app');
        var context = this.props.context;
        var content;
        var href_url = url.parse(this.props.href);
        // Switching between collections may leave component in place
        var key = context && context['@id'] && context['@id'].split('?')[0];
        var current_action = this.currentAction();

        if (!current_action && context.default_page) {
            context = context.default_page;
        }

        var errors = this.state.errors.map(function (error) {
            return

;
        });

        var appClass = 'done';
        if (this.props.slow) {
            appClass = 'communicating';
        }

        var canonical = this.props.href;
        if (context.canonical_uri) {
            if (href_url.host) {
                canonical = (href_url.protocol || '') + '//' + href_url.host + context.canonical_uri;
            } else {
                canonical = context.canonical_uri;
            }
        }

        // add static page routing
        var title;
        var routeList = canonical.split("/");
        var lowerList = [];
        var scrollList = [];
        routeList.map(function(value) {
            if (value.includes('#') && value.charAt(0) !== "#"){
                var navSplit = value.split("#");
                lowerList.push(navSplit[0].toLowerCase());
                scrollList.push(navSplit[1].toLowerCase());
            }else if(value.charAt(0) !== "!" && value.length > 0){
                lowerList.push(value.toLowerCase());
            }
        });
        var currRoute = lowerList.slice(1); // eliminate http
        // first case is fallback
        if (canonical === "about:blank"){
            title = portal.portal_title;
            content = null;
        }else if (currRoute[currRoute.length-1] === 'home' || (currRoute[currRoute.length-1] === href_url.host)){
            content = <HomePage />;
            title = portal.portal_title;
        }else if (currRoute[currRoute.length-1] === 'help'){
            content = <HelpPage />;
            title = 'Help - ' + portal.portal_title;
        }else if (currRoute[currRoute.length-1] === 'about'){
            content = <AboutPage />;
            title = 'About - ' + portal.portal_title;
        }else if (context) {
            var ContentView = globals.content_views.lookup(context, current_action);
            if (ContentView){
                content = <ContentView context={context} expSetFilters={this.props.expSetFilters}/>;
                title = context.title || context.name || context.accession || context['@id'];
                if (title && title != 'Home') {
                    title = title + ' – ' + portal.portal_title;
                } else {
                    title = portal.portal_title;
                }
            }else{
                // Handle the case where context is not loaded correctly
                content = <ErrorPage />;
                title="Not Found";
            }
        }
        // Google does not update the content of 301 redirected pages
        var base;
        if (({'http://data.4dnucleome.org/': 1})[canonical]) {
            base = canonical = 'http://data.4dnucleome.org/';
            this.historyEnabled = false;

        }
        return (

                    <meta charSet="utf-8" />
                    <meta httpEquiv="X-UA-Compatible" content="IE=edge" />
                    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
                    <Title>{title}</Title>
                    {base ? <base href={base}/> : null}
                    <link rel="canonical" href={canonical} />

                    <link href="https://fonts.googleapis.com/css?family=Work+Sans:200,300,400,500,600,700" rel="stylesheet" />
                    <link href="https://fonts.googleapis.com/css?family=Yrsa" rel="stylesheet" />

                    <link rel="stylesheet" href="/static/css/style.css" />
                    <link href="/static/font/ss-gizmo.css" rel="stylesheet" />
                    <link href="/static/font/ss-black-tie-regular.css" rel="stylesheet" />

                                <Navigation />

                                    {content}

                                {errors}

        );
    },

    statics: {
        getRenderedProps: function (document) {
            // Ensure the initial render is exactly the same
            store.dispatch({
                type: {'href':document.querySelector('link[rel="canonical"]').getAttribute('href')}
            });
            var script_props = document.querySelectorAll('script[data-prop-name]');
            var props_dict = {};
            for (var i = 0; i < script_props.length; i++) {
                var elem = script_props[i];
                var elem_value = elem.text;
                var elem_type = elem.getAttribute('type') || '';
                if (elem_type == 'application/json' || elem_type.slice(-5) == '+json') {
                    elem_value = JSON.parse(elem_value);
                }
                props_dict[ elem.getAttribute('data-prop-name')] = elem_value;
            }
            store.dispatch({
                type: props_dict
            });
        }
    }
});

module.exports = App;
<|endoftext|>


<commit_before>/** @jsx React.DOM */
define(['react', 'jsonScriptEscape', './globals', './mixins', './navbar', './footer'],
function (React, jsonScriptEscape, globals, mixins, NavBar, Footer) {
    /*jshint devel: true*/
    'use strict';

    var portal = {
        portal_title: 'ENCODE',
        global_sections: [
            {id: 'antibodies', title: 'Antibodies', url: '/antibodies/'},
            {id: 'biosamples', title: 'Biosamples', url: '/biosamples/'},
            {id: 'experiments', title: 'Experiments', url: '/experiments/'},
            {id: 'targets', title: 'Targets', url: '/targets/'}
        ]
    };

    var user_actions = [
        {id: 'signout', title: 'Sign out', trigger: 'logout'}
    ];

    // App is the root component, mounted on document.body.
    // It lives for the entire duration the page is loaded.
    // App maintains state for the
    var App = React.createClass({
        mixins: [mixins.Persona, mixins.HistoryAndTriggers],
        triggers: {
            login: 'triggerLogin',
            logout: 'triggerLogout'
        },

        getInitialState: function() {
            return {
                errors: [],
                portal: portal,
                session: null,
                user_actions: user_actions
            };
        },

        render: function() {
            console.log('render app');
            var content;
            var context = this.props.context;
            if (context) {
                var ContentView = globals.content_views.lookup(context);
                content = this.transferPropsTo(ContentView({
                    key: context['@id'],  // Switching between collections may leave component in place
                    personaReady: this.state.personaReady,
                    session: this.state.session
                }));
            }
            var errors = this.state.errors.map(function (error) {
                return

;
            });

            var appClass;
            if (this.state.communicating) {
                appClass = 'communicating';
            } else {
                appClass = 'done';
            }

            var title = globals.listing_titles.lookup(context)({context: context});
            if (title && title != 'Home') {
                title = title + ' – ' + portal.portal_title;
            } else {
                title = portal.portal_title;
            }

            return (

                        <meta charset="utf-8" />
                        <meta http-equiv="content-language" content="en" />
                        <meta http-equiv="X-UA-Compatible" content="IE=edge" />
                        <meta name="viewport" content="width=device-width, initial-scale=1.0" />
                        <title>{title}</title>
                        <link rel="canonical" href={this.props.href} />
                        <link rel="stylesheet" href="/static/css/style.css" />
                        <link rel="stylesheet" href="/static/css/responsive.css" />

                                    <NavBar href={this.props.href} portal={this.state.portal}
                                            user_actions={this.state.user_actions} session={this.state.session}
                                            personaReady={this.state.personaReady} />

                                        {content}

                                    {errors}

            );
        }

    });

    return App;

});
<commit_msg>Add linebreaks around embedded json to make generated source easier to read.<commit_after>/** @jsx React.DOM */
define(['react', 'jsonScriptEscape', './globals', './mixins', './navbar', './footer'],
function (React, jsonScriptEscape, globals, mixins, NavBar, Footer) {
    /*jshint devel: true*/
    'use strict';

    var portal = {
        portal_title: 'ENCODE',
        global_sections: [
            {id: 'antibodies', title: 'Antibodies', url: '/antibodies/'},
            {id: 'biosamples', title: 'Biosamples', url: '/biosamples/'},
            {id: 'experiments', title: 'Experiments', url: '/experiments/'},
            {id: 'targets', title: 'Targets', url: '/targets/'}
        ]
    };

    var user_actions = [
        {id: 'signout', title: 'Sign out', trigger: 'logout'}
    ];

    // App is the root component, mounted on document.body.
    // It lives for the entire duration the page is loaded.
    // App maintains state for the
    var App = React.createClass({
        mixins: [mixins.Persona, mixins.HistoryAndTriggers],
        triggers: {
            login: 'triggerLogin',
            logout: 'triggerLogout'
        },

        getInitialState: function() {
            return {
                errors: [],
                portal: portal,
                session: null,
                user_actions: user_actions
            };
        },

        render: function() {
            console.log('render app');
            var content;
            var context = this.props.context;
            if (context) {
                var ContentView = globals.content_views.lookup(context);
                content = this.transferPropsTo(ContentView({
                    key: context['@id'],  // Switching between collections may leave component in place
                    personaReady: this.state.personaReady,
                    session: this.state.session
                }));
            }
            var errors = this.state.errors.map(function (error) {
                return

;
            });

            var appClass;
            if (this.state.communicating) {
                appClass = 'communicating';
            } else {
                appClass = 'done';
            }

            var title = globals.listing_titles.lookup(context)({context: context});
            if (title && title != 'Home') {
                title = title + ' – ' + portal.portal_title;
            } else {
                title = portal.portal_title;
            }

            return (

                        <meta charset="utf-8" />
                        <meta http-equiv="content-language" content="en" />
                        <meta http-equiv="X-UA-Compatible" content="IE=edge" />
                        <meta name="viewport" content="width=device-width, initial-scale=1.0" />
                        <title>{title}</title>
                        <link rel="canonical" href={this.props.href} />
                        <link rel="stylesheet" href="/static/css/style.css" />
                        <link rel="stylesheet" href="/static/css/responsive.css" />

                                    <NavBar href={this.props.href} portal={this.state.portal}
                                            user_actions={this.state.user_actions} session={this.state.session}
                                            personaReady={this.state.personaReady} />

                                        {content}

                                    {errors}

            );
        }

    });

    return App;

});
<|endoftext|>