<commit_before>// base-x encoding
// Forked from https://github.com/cryptocoinjs/bs58
// Originally written by Mike Hearn for BitcoinJ
// Copyright (c) 2011 Google Inc
// Ported to JavaScript by Stefan Thomas
// Merged Buffer refactorings from base58-native by Stephen Pair
// Copyright (c) 2013 BitPay Inc

module.exports = function base (ALPHABET) {
  var ALPHABET_MAP = {}
  var BASE = ALPHABET.length
  var LEADER = ALPHABET.charAt(0)

  // pre-compute lookup table
  for (var z = 0; z < ALPHABET.length; z++) {
    var x = ALPHABET.charAt(z)

    if (ALPHABET_MAP[x] !== undefined) throw new TypeError(x + ' is ambiguous')
    ALPHABET_MAP[x] = z
  }

  function encode (source) {
    if (source.length === 0) return ''

    var digits = [0]
    for (var i = 0; i < source.length; ++i) {
      for (var j = 0, carry = source[i]; j < digits.length; ++j) {
        carry += digits[j] << 8
        digits[j] = carry % BASE
        carry = (carry / BASE) | 0
      }

      while (carry > 0) {
        digits.push(carry % BASE)
        carry = (carry / BASE) | 0
      }
    }

    var string = ''

    // deal with leading zeros
    for (var k = 0; source[k] === 0 && k < source.length - 1; ++k) string += ALPHABET[0]
    // convert digits to a string
    for (var q = digits.length - 1; q >= 0; --q) string += ALPHABET[digits[q]]

    return string
  }

  function decodeUnsafe (string) {
    if (string.length === 0) return Buffer.allocUnsafe(0)

    var bytes = [0]
    for (var i = 0; i < string.length; i++) {
      var value = ALPHABET_MAP[string[i]]
      if (value === undefined) return

      for (var j = 0, carry = value; j < bytes.length; ++j) {
        carry += bytes[j] * BASE
        bytes[j] = carry & 0xff
        carry >>= 8
      }

      while (carry > 0) {
        bytes.push(carry & 0xff)
        carry >>= 8
      }
    }

    // deal with leading zeros
    for (var k = 0; string[k] === LEADER && k < string.length - 1; ++k) {
      bytes.push(0)
    }

    return Buffer.from(bytes.reverse())
  }

  function decode (string) {
    var buffer = decodeUnsafe(string)
    if (buffer) return buffer

    throw new Error('Non-base' + BASE + ' character')
  }

  return {
    encode: encode,
    decodeUnsafe: decodeUnsafe,
    decode: decode
  }
}
<commit_msg>Use UInt8Array's in the browser thus eliminating the need for Buffer in browser builds<commit_after>// base-x encoding
// Forked from https://github.com/cryptocoinjs/bs58
// Originally written by Mike Hearn for BitcoinJ
// Copyright (c) 2011 Google Inc
// Ported to JavaScript by Stefan Thomas
// Merged Buffer refactorings from base58-native by Stephen Pair
// Copyright (c) 2013 BitPay Inc

var ByteArray = global && global['Buffer'] ? global['Buffer'] : Uint8Array

module.exports = function base (ALPHABET) {
  var ALPHABET_MAP = {}
  var BASE = ALPHABET.length
  var LEADER = ALPHABET.charAt(0)

  // pre-compute lookup table
  for (var z = 0; z < ALPHABET.length; z++) {
    var x = ALPHABET.charAt(z)

    if (ALPHABET_MAP[x] !== undefined) throw new TypeError(x + ' is ambiguous')
    ALPHABET_MAP[x] = z
  }

  function encode (source) {
    if (source.length === 0) return ''

    var digits = [0]
    for (var i = 0; i < source.length; ++i) {
      for (var j = 0, carry = source[i]; j < digits.length; ++j) {
        carry += digits[j] << 8
        digits[j] = carry % BASE
        carry = (carry / BASE) | 0
      }

      while (carry > 0) {
        digits.push(carry % BASE)
        carry = (carry / BASE) | 0
      }
    }

    var string = ''

    // deal with leading zeros
    for (var k = 0; source[k] === 0 && k < source.length - 1; ++k) string += ALPHABET[0]
    // convert digits to a string
    for (var q = digits.length - 1; q >= 0; --q) string += ALPHABET[digits[q]]

    return string
  }

  function decodeUnsafe (string) {
    if (string.length === 0) return new ByteArray(0)

    var bytes = [0]
    for (var i = 0; i < string.length; i++) {
      var value = ALPHABET_MAP[string[i]]
      if (value === undefined) return

      for (var j = 0, carry = value; j < bytes.length; ++j) {
        carry += bytes[j] * BASE
        bytes[j] = carry & 0xff
        carry >>= 8
      }

      while (carry > 0) {
        bytes.push(carry & 0xff)
        carry >>= 8
      }
    }

    // deal with leading zeros
    for (var k = 0; string[k] === LEADER && k < string.length - 1; ++k) {
      bytes.push(0)
    }

    return ByteArray.from(bytes.reverse())
  }

  function decode (string) {
    var buffer = decodeUnsafe(string)
    if (buffer) return buffer

    throw new Error('Non-base' + BASE + ' character')
  }

  return {
    encode: encode,
    decodeUnsafe: decodeUnsafe,
    decode: decode
  }
}
<|endoftext|>


<commit_before>'use strict';

function draw_logic(){
    // Save the current buffer state.
    canvas_buffer.save();
    canvas_buffer.translate(
      -camera_x,
      0
    );

    canvas_setproperties({
      'properties': {
        'fillStyle': '#003',
      },
    });
    core_group_modify({
      'groups': [
        'pillar',
      ],
      'todo': function(entity){
          canvas_buffer.fillRect(
            core_entities[entity]['x'],
            0,
            100,
            canvas_height
          );
      },
    });

    // Draw stuff relative to center of canvas.
    canvas_buffer.translate(
      0,
      -camera_y
    );

    core_group_modify({
      'groups': [
        'fish',
      ],
      'todo': function(entity){
          canvas_buffer.save();

          // Translate and rotate fish.
          canvas_buffer.translate(
            core_entities[entity]['x'],
            core_entities[entity]['y']
          );
          canvas_buffer.rotate(core_entities[entity]['angle']);

          // Calculate vertex based on movement direction.
          var xoffset = core_entities[entity]['size'] * (core_entities[entity]['dx'] > 0
            ? 1
            : -1);

          // Draw fish.
          canvas_draw_path({
            'properties': {
              'fillStyle': core_entities[entity]['color'],
            },
            'vertices': [
              {
                'type': 'moveTo',
                'y': core_entities[entity]['size'] / 2,
              },
              {
                'x': xoffset,
              },
              {
                'x': xoffset * 3,
                'y': core_entities[entity]['size'],
              },
              {
                'x': xoffset * 3,
              },
              {
                'x': xoffset,
                'y': core_entities[entity]['size'],
              },
            ],
          });

          canvas_buffer.restore();
      },
    });

    // Restore the buffer state.
    canvas_buffer.restore();
}

function logic(){
    if(core_keys[65]['state']){
        camera_x -= core_storage_data['camera-speed'];
    }
    if(core_keys[68]['state']){
        camera_x += core_storage_data['camera-speed'];
    }
    if(core_keys[83]['state']){
        camera_y += core_storage_data['camera-speed'];
    }
    if(core_keys[87]['state']){
        camera_y -= core_storage_data['camera-speed'];
    }

    core_group_modify({
      'groups': [
        'fish',
      ],
      'todo': function(entity){
          // Fish move in the direction they are facing.
          core_entities[entity]['x'] -= core_entities[entity]['dx'];
          core_entities[entity]['y'] -= core_entities[entity]['dy'];

          // If a fish travels past the edge of the screen,
          //   move it to the other side.
          var size = core_entities[entity]['size'] * 4;
          if(core_entities[entity]['x'] > camera_x + canvas_width + size
            || core_entities[entity]['x'] < camera_x - size){
              core_entities[entity]['x'] += core_entities[entity]['dx'] < 0
                ? -canvas_width - size
                : canvas_width + size;
              core_entities[entity]['y'] = camera_y + core_random_integer({
                'max': canvas_height,
              });

              randomize_fish_movement(entity);
          }
      },
    });

    core_ui_update({
      'ids': {
        'fish': core_entity_info['fish']['count'],
        'x': camera_x,
        'y': camera_y,
      },
    });
}

function repo_init(){
    core_repo_init({
      'entities': {
        'fish': {
          'properties': {
            'angle': 0,
            'dx': 0,
            'dy': 0,
          },
        },
        'pillar': {},
      },
      'info': '<input id=restart type=button value=Restart>',
      'info-events': {
        'restart': {
          'todo': function(){
              canvas_setmode({
                'newgame': true,
              });
          },
          'type': 'onclick',
        },
      },
      'keybinds': {
        16: {},
        65: {},
        68: {},
        70: {
          'todo': create_fish,
        },
        72: {
          'todo': function(){
              camera_x = 0;
              camera_y = 0;
          },
        },
        83: {},
        87: {},
      },
      'storage': {
        'camera-speed': 5,
      },
      'storage-menu': '

<input id=camera-speed>Camera Speed
',
      'title': 'Aquarium-2D.htm',
      'ui': ' Fish
x, y',
    });
    canvas_init();
}

var camera_x = 0;
var camera_y = 0;
<commit_msg>removed default type arg<commit_after>'use strict';

function draw_logic(){
    // Save the current buffer state.
    canvas_buffer.save();
    canvas_buffer.translate(
      -camera_x,
      0
    );

    canvas_setproperties({
      'properties': {
        'fillStyle': '#003',
      },
    });
    core_group_modify({
      'groups': [
        'pillar',
      ],
      'todo': function(entity){
          canvas_buffer.fillRect(
            core_entities[entity]['x'],
            0,
            100,
            canvas_height
          );
      },
    });

    // Draw stuff relative to center of canvas.
    canvas_buffer.translate(
      0,
      -camera_y
    );

    core_group_modify({
      'groups': [
        'fish',
      ],
      'todo': function(entity){
          canvas_buffer.save();

          // Translate and rotate fish.
          canvas_buffer.translate(
            core_entities[entity]['x'],
            core_entities[entity]['y']
          );
          canvas_buffer.rotate(core_entities[entity]['angle']);

          // Calculate vertex based on movement direction.
          var xoffset = core_entities[entity]['size'] * (core_entities[entity]['dx'] > 0
            ? 1
            : -1);

          // Draw fish.
          canvas_draw_path({
            'properties': {
              'fillStyle': core_entities[entity]['color'],
            },
            'vertices': [
              {
                'type': 'moveTo',
                'y': core_entities[entity]['size'] / 2,
              },
              {
                'x': xoffset,
              },
              {
                'x': xoffset * 3,
                'y': core_entities[entity]['size'],
              },
              {
                'x': xoffset * 3,
              },
              {
                'x': xoffset,
                'y': core_entities[entity]['size'],
              },
            ],
          });

          canvas_buffer.restore();
      },
    });

    // Restore the buffer state.
    canvas_buffer.restore();
}

function logic(){
    if(core_keys[65]['state']){
        camera_x -= core_storage_data['camera-speed'];
    }
    if(core_keys[68]['state']){
        camera_x += core_storage_data['camera-speed'];
    }
    if(core_keys[83]['state']){
        camera_y += core_storage_data['camera-speed'];
    }
    if(core_keys[87]['state']){
        camera_y -= core_storage_data['camera-speed'];
    }

    core_group_modify({
      'groups': [
        'fish',
      ],
      'todo': function(entity){
          // Fish move in the direction they are facing.
          core_entities[entity]['x'] -= core_entities[entity]['dx'];
          core_entities[entity]['y'] -= core_entities[entity]['dy'];

          // If a fish travels past the edge of the screen,
          //   move it to the other side.
          var size = core_entities[entity]['size'] * 4;
          if(core_entities[entity]['x'] > camera_x + canvas_width + size
            || core_entities[entity]['x'] < camera_x - size){
              core_entities[entity]['x'] += core_entities[entity]['dx'] < 0
                ? -canvas_width - size
                : canvas_width + size;
              core_entities[entity]['y'] = camera_y + core_random_integer({
                'max': canvas_height,
              });

              randomize_fish_movement(entity);
          }
      },
    });

    core_ui_update({
      'ids': {
        'fish': core_entity_info['fish']['count'],
        'x': camera_x,
        'y': camera_y,
      },
    });
}

function repo_init(){
    core_repo_init({
      'entities': {
        'fish': {
          'properties': {
            'angle': 0,
            'dx': 0,
            'dy': 0,
          },
        },
        'pillar': {},
      },
      'info': '<input id=restart type=button value=Restart>',
      'info-events': {
        'restart': {
          'todo': function(){
              canvas_setmode({
                'newgame': true,
              });
          },
        },
      },
      'keybinds': {
        16: {},
        65: {},
        68: {},
        70: {
          'todo': create_fish,
        },
        72: {
          'todo': function(){
              camera_x = 0;
              camera_y = 0;
          },
        },
        83: {},
        87: {},
      },
      'storage': {
        'camera-speed': 5,
      },
      'storage-menu': '

<input id=camera-speed>Camera Speed
',
      'title': 'Aquarium-2D.htm',
      'ui': ' Fish
x, y',
    });
    canvas_init();
}

var camera_x = 0;
var camera_y = 0;
<|endoftext|>


<commit_before>var fs               = require('fs')
  , util             = require('util')
  , findExec         = require('find-exec')
  , child_process    = require('child_process')
  , players          = [
                        'mplayer',
                        'afplay',
                        'mpg123',
                        'mpg321',
                        'play'
                       ]

function Play(opts){
  var opts           = opts               || {}

  this.players       = opts.players       || players
  this.player        = opts.player        || findExec(this.players)

  var exec           = child_process.exec

  this.play = function(what, next){
    var self = this,
        next = next || function(){}

    if (!what) return next(new Error("No audio file specified"));

    if (!this.player){
      return next(new Error("Couldn't find a suitable audio player"))
    }

    exec(this.player + ' ' + what, function(err, stdout, stderr){
      if (err) return next(err)
      if (stderr) return next(new Error("File doesn't exist: " + what))
      return next();
    })
  }

  this.test = function(next) { this.play('./assets/test.mp3', next) }
}

module.exports = function(opts){
  return new Play(opts)
}
<commit_msg>Improve file existence check<commit_after>var fs               = require('fs')
  , util             = require('util')
  , findExec         = require('find-exec')
  , child_process    = require('child_process')
  , players          = [
                        'mplayer',
                        'afplay',
                        'mpg123',
                        'mpg321',
                        'play'
                       ]

function Play(opts){
  var opts           = opts               || {}

  this.players       = opts.players       || players
  this.player        = opts.player        || findExec(this.players)

  var exec           = child_process.exec

  this.play = function(what, next){
    var self = this,
        next = next || function(){}

    if (!what) return next(new Error("No audio file specified"));

    try {
      if (!fs.statSync(what).isFile()){
        return next(new Error(what + " is not a file"));
      }
    } catch (err){
      return next(new Error("File doesn't exist: " + what));
    }

    if (!this.player){
      return next(new Error("Couldn't find a suitable audio player"))
    }

    exec(this.player + ' ' + what, function(err, stdout, stderr){
      if (err) return next(err)
      return next();
    })
  }

  this.test = function(next) { this.play('./assets/test.mp3', next) }
}

module.exports = function(opts){
  return new Play(opts)
}
<|endoftext|>


<commit_before>import Future from 'fibers/future'
import Fiber from 'fibers'

const SYNC_COMMANDS = ['domain', '_events', '_maxListeners', 'setMaxListeners', 'emit',
    'addListener', 'on', 'once', 'removeListener', 'removeAllListeners', 'listeners',
    'getMaxListeners', 'listenerCount']

let commandIsRunning = false
let forcePromises = false

/**
 * helper method to execute a row of hooks with certain parameters
 * @param  {Function|Function[]} hooks  list of hooks
 * @param  {Object[]} args  list of parameter for hook functions
 * @return {Promise}  promise that gets resolved once all hooks finished running
 */
let executeHooksWithArgs = (hooks = [], args) => {
    /**
     * make sure hooks are an array of functions
     */
    if (typeof hooks === 'function') {
        hooks = [hooks]
    }

    /**
     * make sure args is an array since we are calling apply
     */
    if (!Array.isArray(args)) {
        args = [args]
    }

    hooks = hooks.map((hook) => new Promise((resolve) => {
        let _commandIsRunning = commandIsRunning
        try {
            /**
             * after command hooks require additional Fiber environment
             */
            return Fiber(() => {
                commandIsRunning = true
                resolve(hook.apply(null, args))
                commandIsRunning = _commandIsRunning
            }).run()
        } catch (e) {
            console.error(e.stack)
        }

        resolve()
    }))

    return Promise.all(hooks)
}

/**
 * global function to wrap callbacks into Fiber context
 * @param  {Function} fn  function to wrap around
 * @return {Function}     wrapped around function
 */
global.wdioSync = function (fn, done) {
    return function (...args) {
        return Fiber(() => {
            const result = fn.apply(this, args)

            if (typeof done === 'function') {
                done(result)
            }
        }).run()
    }
}

/**
 * wraps a function into a Fiber ready context to enable sync execution and hooks
 * @param  {Function}   fn             function to be executed
 * @param  {String}     commandName    name of that function
 * @param  {Function[]} beforeCommand  method to be executed before calling the actual function
 * @param  {Function[]} afterCommand   method to be executed after calling the actual function
 * @return {Function}   actual wrapped function
 */
let wrapCommand = function (fn, commandName, beforeCommand, afterCommand) {
    return function (...commandArgs) {
        let future = new Future()
        let futureFailed = false

        if (forcePromises) {
            return fn.apply(this, commandArgs)
        }

        /**
         * don't execute [before/after]Command hook if a command was executed
         * in these hooks
         */
        if (commandIsRunning) {
            let commandPromise = fn.apply(this, commandArgs)

            /**
             * try to execute with Fibers and fall back if can't
             */
            try {
                commandPromise.then(future.return.bind(future), future.throw.bind(future))
                return future.wait()
            } catch (e) {
                if (e.message === "Can't wait without a fiber") {
                    return commandPromise
                }
                throw e
            }
        }

        commandIsRunning = true
        let commandResult, commandError
        new Promise((r) => r(executeHooksWithArgs(beforeCommand, [commandName, commandArgs])))
            .then(() => {
                /**
                 * actual function was already executed in desired catch block
                 */
                if (futureFailed) {
                    return
                }

                return fn.apply(this, commandArgs)
            })
            .then(
                (result) => {
                    commandResult = result
                    return executeHooksWithArgs(afterCommand, [commandName, commandArgs, result])
                },
                (e) => {
                    commandError = e
                    return executeHooksWithArgs(afterCommand, [commandName, commandArgs, null, e])
                }
            )
            .then(() => {
                commandIsRunning = false

                if (commandError) {
                    return future.throw(commandError)
                }
                return future.return(applyPrototype(this, commandResult))
            })

        /**
         * try to execute with Fibers and fall back if can't
         */
        try {
            return future.wait()
        } catch (e) {
            if (e.message === "Can't wait without a fiber") {
                futureFailed = true
                return fn.apply(this, commandArgs)
            }
            throw e
        }
    }
}

/**
 * enhance result with instance prototype to enable command chaining
 * @param  {Ibject} instance WebdriverIO instance
 * @param  {[type]} result   command result
 * @return {[type]}          command result with enhanced prototype
 */
let applyPrototype = function (instance, result) {
    if (!result || typeof result !== 'object') {
        return result
    }

    for (let commandName of Object.keys(Object.getPrototypeOf(instance))) {
        if (result[commandName] || SYNC_COMMANDS.indexOf(commandName) > -1) {
            continue
        }
        result[commandName] = instance[commandName].bind(instance)
    }

    return result
}

/**
 * wraps all WebdriverIO commands
 * @param  {Object}     instance       WebdriverIO client instance (browser)
 * @param  {Function[]} beforeCommand  before command hook
 * @param  {Function[]} afterCommand   after command hook
 */
let wrapCommands = function (instance, beforeCommand, afterCommand) {
    Object.keys(Object.getPrototypeOf(instance)).forEach((commandName) => {
        if (SYNC_COMMANDS.indexOf(commandName) > -1) {
            return
        }

        let origFn = instance[commandName]
        instance[commandName] = wrapCommand(origFn, commandName, beforeCommand, afterCommand)
    })

    /**
     * Adding a command within fiber context doesn't require a special routine
     * since everything runs sync. There is no need to promisify the command.
     */
    instance.addCommand = function (fnName, fn, forceOverwrite) {
        let commandGroup = instance
        let commandName = fnName
        let namespace

        if (typeof fn === 'string') {
            namespace = arguments[0]
            fnName = arguments[1]
            fn = arguments[2]
            forceOverwrite = arguments[3]

            switch (typeof commandGroup[namespace]) {
            case 'function':
                throw new Error(`Command namespace "${namespace}" is used internally, and can't be overwritten!`)
            case 'undefined':
                commandGroup[namespace] = {}
                break
            }

            commandName = `${namespace}.${fnName}`
            commandGroup = commandGroup[namespace]
        }

        if (commandGroup[fnName] && !forceOverwrite) {
            throw new Error(`Command ${fnName} is already defined!`)
        }

        /**
         * if method name is async the user specifies that he wants to
         * use bare promises to handle asynchronicity
         */
        if (fn.name === 'async') {
            commandGroup[fnName] = wrapCommand((...args) => {
                forcePromises = true
                let res = fn.apply(instance, args)
                forcePromises = false
                return res
            }, commandName, beforeCommand, afterCommand)
            return
        }

        /**
         * for all other cases we internally return a promise that is
         * finished once the Fiber wrapped custom function has finished
         * #functionalProgrammingWTF!
         */
        commandGroup[fnName] = wrapCommand((...args) => new Promise((r) => {
            wdioSync(fn, r).apply(instance, args)
        }), commandName, beforeCommand, afterCommand)
    }
}

/**
 * [runInFiberContext description]
 * @param  {[type]} testInterfaceFnName  global command that runs specs
 * @param  {[type]} before               before hook hook
 * @param  {[type]} after                after hook hook
 * @param  {[type]} fnName               test interface command to wrap
 */
let runInFiberContext = function (testInterfaceFnName, before, after, fnName) {
    let origFn = global[fnName]

    let runSpec = function (specTitle, specFn) {
        return origFn(specTitle, function (done) {
            Fiber(() => {
                specFn.call(this)
                done()
            }).run()
        })
    }

    let runHook = function (hookFn) {
        return origFn(function (done) {
            executeHooksWithArgs(before)
                .then(() => new Promise((resolve) => {
                    return Fiber(() => {
                        hookFn.call(this)
                        resolve()
                    }).run()
                }))
                .then(() => executeHooksWithArgs(after))
                .then(() => done(), () => done())
        })
    }

    global[fnName] = function (...specArguments) {
        /**
         * Variadic arguments: [title, fn], [title], [fn]
         */
        let specFn = typeof specArguments[0] === 'function' ? specArguments.shift()
            : (typeof specArguments[1] === 'function' ? specArguments.pop() : undefined)
        let specTitle = specArguments[0]

        if (fnName === testInterfaceFnName) {
            if (specFn) return runSpec(specTitle, specFn)

            /**
             * if specFn is undefined we are dealing with a pending function
             */
            return origFn(specTitle)
        }

        return runHook(specFn)
    }

    if (fnName === testInterfaceFnName) {
        global[fnName].skip = origFn.skip
        global[fnName].only = origFn.only
    }
}

export { wrapCommand, wrapCommands, runInFiberContext, executeHooksWithArgs }
<commit_msg>Ensure errors thrown in (e.g. Mocha) hooks are propagated<commit_after>import Future from 'fibers/future'
import Fiber from 'fibers'

const SYNC_COMMANDS = ['domain', '_events', '_maxListeners', 'setMaxListeners', 'emit',
    'addListener', 'on', 'once', 'removeListener', 'removeAllListeners', 'listeners',
    'getMaxListeners', 'listenerCount']

let commandIsRunning = false
let forcePromises = false

/**
 * helper method to execute a row of hooks with certain parameters
 * @param  {Function|Function[]} hooks  list of hooks
 * @param  {Object[]} args  list of parameter for hook functions
 * @return {Promise}  promise that gets resolved once all hooks finished running
 */
let executeHooksWithArgs = (hooks = [], args) => {
    /**
     * make sure hooks are an array of functions
     */
    if (typeof hooks === 'function') {
        hooks = [hooks]
    }

    /**
     * make sure args is an array since we are calling apply
     */
    if (!Array.isArray(args)) {
        args = [args]
    }

    hooks = hooks.map((hook) => new Promise((resolve) => {
        let _commandIsRunning = commandIsRunning
        try {
            /**
             * after command hooks require additional Fiber environment
             */
            return Fiber(() => {
                commandIsRunning = true
                resolve(hook.apply(null, args))
                commandIsRunning = _commandIsRunning
            }).run()
        } catch (e) {
            console.error(e.stack)
        }

        resolve()
    }))

    return Promise.all(hooks)
}

/**
 * global function to wrap callbacks into Fiber context
 * @param  {Function} fn  function to wrap around
 * @return {Function}     wrapped around function
 */
global.wdioSync = function (fn, done) {
    return function (...args) {
        return Fiber(() => {
            const result = fn.apply(this, args)

            if (typeof done === 'function') {
                done(result)
            }
        }).run()
    }
}

/**
 * wraps a function into a Fiber ready context to enable sync execution and hooks
 * @param  {Function}   fn             function to be executed
 * @param  {String}     commandName    name of that function
 * @param  {Function[]} beforeCommand  method to be executed before calling the actual function
 * @param  {Function[]} afterCommand   method to be executed after calling the actual function
 * @return {Function}   actual wrapped function
 */
let wrapCommand = function (fn, commandName, beforeCommand, afterCommand) {
    return function (...commandArgs) {
        let future = new Future()
        let futureFailed = false

        if (forcePromises) {
            return fn.apply(this, commandArgs)
        }

        /**
         * don't execute [before/after]Command hook if a command was executed
         * in these hooks
         */
        if (commandIsRunning) {
            let commandPromise = fn.apply(this, commandArgs)

            /**
             * try to execute with Fibers and fall back if can't
             */
            try {
                commandPromise.then(future.return.bind(future), future.throw.bind(future))
                return future.wait()
            } catch (e) {
                if (e.message === "Can't wait without a fiber") {
                    return commandPromise
                }
                throw e
            }
        }

        commandIsRunning = true
        let commandResult, commandError
        new Promise((r) => r(executeHooksWithArgs(beforeCommand, [commandName, commandArgs])))
            .then(() => {
                /**
                 * actual function was already executed in desired catch block
                 */
                if (futureFailed) {
                    return
                }

                return fn.apply(this, commandArgs)
            })
            .then(
                (result) => {
                    commandResult = result
                    return executeHooksWithArgs(afterCommand, [commandName, commandArgs, result])
                },
                (e) => {
                    commandError = e
                    return executeHooksWithArgs(afterCommand, [commandName, commandArgs, null, e])
                }
            )
            .then(() => {
                commandIsRunning = false

                if (commandError) {
                    return future.throw(commandError)
                }
                return future.return(applyPrototype(this, commandResult))
            })

        /**
         * try to execute with Fibers and fall back if can't
         */
        try {
            return future.wait()
        } catch (e) {
            if (e.message === "Can't wait without a fiber") {
                futureFailed = true
                return fn.apply(this, commandArgs)
            }
            throw e
        }
    }
}

/**
 * enhance result with instance prototype to enable command chaining
 * @param  {Ibject} instance WebdriverIO instance
 * @param  {[type]} result   command result
 * @return {[type]}          command result with enhanced prototype
 */
let applyPrototype = function (instance, result) {
    if (!result || typeof result !== 'object') {
        return result
    }

    for (let commandName of Object.keys(Object.getPrototypeOf(instance))) {
        if (result[commandName] || SYNC_COMMANDS.indexOf(commandName) > -1) {
            continue
        }
        result[commandName] = instance[commandName].bind(instance)
    }

    return result
}

/**
 * wraps all WebdriverIO commands
 * @param  {Object}     instance       WebdriverIO client instance (browser)
 * @param  {Function[]} beforeCommand  before command hook
 * @param  {Function[]} afterCommand   after command hook
 */
let wrapCommands = function (instance, beforeCommand, afterCommand) {
    Object.keys(Object.getPrototypeOf(instance)).forEach((commandName) => {
        if (SYNC_COMMANDS.indexOf(commandName) > -1) {
            return
        }

        let origFn = instance[commandName]
        instance[commandName] = wrapCommand(origFn, commandName, beforeCommand, afterCommand)
    })

    /**
     * Adding a command within fiber context doesn't require a special routine
     * since everything runs sync. There is no need to promisify the command.
     */
    instance.addCommand = function (fnName, fn, forceOverwrite) {
        let commandGroup = instance
        let commandName = fnName
        let namespace

        if (typeof fn === 'string') {
            namespace = arguments[0]
            fnName = arguments[1]
            fn = arguments[2]
            forceOverwrite = arguments[3]

            switch (typeof commandGroup[namespace]) {
            case 'function':
                throw new Error(`Command namespace "${namespace}" is used internally, and can't be overwritten!`)
            case 'undefined':
                commandGroup[namespace] = {}
                break
            }

            commandName = `${namespace}.${fnName}`
            commandGroup = commandGroup[namespace]
        }

        if (commandGroup[fnName] && !forceOverwrite) {
            throw new Error(`Command ${fnName} is already defined!`)
        }

        /**
         * if method name is async the user specifies that he wants to
         * use bare promises to handle asynchronicity
         */
        if (fn.name === 'async') {
            commandGroup[fnName] = wrapCommand((...args) => {
                forcePromises = true
                let res = fn.apply(instance, args)
                forcePromises = false
                return res
            }, commandName, beforeCommand, afterCommand)
            return
        }

        /**
         * for all other cases we internally return a promise that is
         * finished once the Fiber wrapped custom function has finished
         * #functionalProgrammingWTF!
         */
        commandGroup[fnName] = wrapCommand((...args) => new Promise((r) => {
            wdioSync(fn, r).apply(instance, args)
        }), commandName, beforeCommand, afterCommand)
    }
}

/**
 * [runInFiberContext description]
 * @param  {[type]} testInterfaceFnName  global command that runs specs
 * @param  {[type]} before               before hook hook
 * @param  {[type]} after                after hook hook
 * @param  {[type]} fnName               test interface command to wrap
 */
let runInFiberContext = function (testInterfaceFnName, before, after, fnName) {
    let origFn = global[fnName]

    let runSpec = function (specTitle, specFn) {
        return origFn(specTitle, function (done) {
            Fiber(() => {
                specFn.call(this)
                done()
            }).run()
        })
    }

    let runHook = function (hookFn) {
        return origFn(function (done) {
            executeHooksWithArgs(before)
                .then(() => new Promise((resolve, reject) => {
                    return Fiber(() => {
                        try {
                            hookFn.call(this)
                        } catch (e) {
                            reject(e)
                        }
                        resolve()
                    }).run()
                }))
                .then(() => executeHooksWithArgs(after))
                .then(done, done)
        })
    }

    global[fnName] = function (...specArguments) {
        /**
         * Variadic arguments: [title, fn], [title], [fn]
         */
        let specFn = typeof specArguments[0] === 'function' ? specArguments.shift()
            : (typeof specArguments[1] === 'function' ? specArguments.pop() : undefined)
        let specTitle = specArguments[0]

        if (fnName === testInterfaceFnName) {
            if (specFn) return runSpec(specTitle, specFn)

            /**
             * if specFn is undefined we are dealing with a pending function
             */
            return origFn(specTitle)
        }

        return runHook(specFn)
    }

    if (fnName === testInterfaceFnName) {
        global[fnName].skip = origFn.skip
        global[fnName].only = origFn.only
    }
}

export { wrapCommand, wrapCommands, runInFiberContext, executeHooksWithArgs }
<|endoftext|>


<commit_before>var _ = require('lodash');
var defaultValidations = require('./defaultValidations');

module.exports = Validator;

/**
 * Creates a validator object and initiates it
 * @param {Model} model - A scoped model to the location on where to put the validator's data
 * @param {Model|string} [origin] - Either a scoped model to the location where the original data is stored. Or, a path (as string) to the location where to find the original data. If not passed, the fields parameter is mandatory.
 * @param {Collection.<string, Object>} [fields] - A collection of fields to use. If not passed, the origin parameter is mandatory. The key for each object is the field name, and the value is the field object (specified below).
   * @param {*} [fields.<fieldName>.default] - A default value for this specific field.
   * @param {Object[]} [fields.<fieldName>.validations] - A list of validations to apply.
     * @param {String|Function|RegEx} [fields.<fieldName>.validations.<index>.rule] - The rule to use when validating this rule. Either, this can be a string matching the name of a default rule (specified in default checks or passed in as an option), OR a function which will get run with the value to be validated as input, which should return true|false reflecting the validity, OR a RegEx, which will get run similar to if you pass in a function.
     * @param {String} [fields.<fieldName>.validations.<index>.message] - The error message to show if validation fails
 * @param {Object} [options] - An options object
   * @param {Collection.<string, Function|RegEx>} [options.rules] - A collection of default rules to add to this instance. Each key is the name of the rule. The value is the rule, either a function or regular expression similar to field specific functions/regular expressions passed in the fields parameter
 * @returns {Validator} - Instance of Validator
 */
function Validator(model, origin, fields, options) {
  // Parse out arguments

  var args = Array.prototype.slice.call(arguments);

  if(!args.length) throw new Error('You must specify a model!');
  if(!args.length == 1) throw new Error('You must either specify an origin or a fields object');

  this.model = args.shift();
  var arg = args.shift();

  if(typeof (arg || {}).path === 'function') {
    this.origin = arg;

    arg = args.shift();
  } else if(typeof arg === 'string') {
    this.origin = this.model.scope(arg);

    arg = args.shift();
  }

  if(arg) this.fields = arg;

  this.options = _.assign({
    rules: {},
    messages: {}
  }, args.shift());

  // Setup
  this._setup();
};

Validator.prototype.getValues = function () {
  var values = {};
  _.each(this.model.get(), function (field, fieldName) {
    values[fieldName] = field.value;
  });
  return values;
}

Validator.prototype.validateField = function (fieldname) {
  this._validateField(fieldname);
};

Validator.prototype.validateAll = function() {
  var self = this;
  _.each(this.model.get(), function (n, key) {
    self._validateField(key);
  });
};

Validator.prototype.checkForInvalidFields = function() {
  return _.find(this.model.get(), function (field) {
    if(field.isInvalid) return field;
  });
};

Validator.prototype.setInvalid = function (fieldName, message) {
  this._setInvalid(fieldName);
  this.model.push(fieldName + '.messages', message || defaultValidations['default'].message);
};

/*
 * @public
 * Reset values to origin.
 */
Validator.prototype.resetForm = function () {
  this._setup();
};

/*
 * @public
 * Commit values to model. Call after client- and serverside validation.
 */
Validator.prototype.commit = function () {
  if(!this.origin) return;

  var self = this;

  _.each(this.origin.get(), function (n, key) {
    self.origin.set(key, self.model.get(key + '.value'));
  });
};

Validator.prototype._setup = function () {
  var self = this;

  if (this.fields) {
    _.each(this.fields, function (n, key) {
      self._addFieldProperties(key, n);
    });
  };

  if(this.origin) {
    _.each(this.origin.get(), function (value, fieldName) {
      self.model.set(fieldName + '.value', value);
    });
  };
};

Validator.prototype._addFieldProperties = function (fieldName, field) {
  var self = this;

  this.model.setEach(fieldName, {
    value: field.default,
    validations: this._assignValidations(field.validations),
    isValid: false,
    isInvalid: false,
    validate: function () {
      self._validateField(fieldName);
    }
  });
};

Validator.prototype._validateField = function (fieldName) {
  this.model.del(fieldName + '.messages');

  var field = this.model.get(fieldName);
  var valid = true;

  for (var i = 0; i < field.validations.length; i++) {
    var validation = field.validations[i];

    if (!this._check(field, validation.rule)) {
      valid = false;

      this.model.push(fieldName + '.messages', validation.message);
    }
  };

  if (valid) {
    this._setValid(fieldName);
  } else {
    this._setInvalid(fieldName);
  }
};

Validator.prototype._assignValidations = function (validations) {
  for (var i = 0; i < validations.length; i++) {
    var validation = validations[i];

    if (!validation.message) validation.message = this._getMessage(validation.rule);

    if (typeof validation.rule === 'string') validation.rule = this._getRule(validation.rule);

    if (typeof validation.rule !== 'function' && !_.isRegExp(validation.rule)) throw new Error('This rule is not (or does not point to) a RegEx or a function.');
  }

  return validations;
};

Validator.prototype._getRule = function (ruleName) {
  if(this.options.rules[ruleName]) return this.options.rules[ruleName];

  if(defaultValidations.hasOwnProperty(ruleName)) return defaultValidations[ruleName].rule;

  throw new Error('Rule: "' + ruleName + '" is not available. You need to add it as an option.');
};

Validator.prototype._getMessage = function (ruleName) {
  return this.options.messages[ruleName] || ((defaultValidations.hasOwnProperty(ruleName)) ? defaultValidations[ruleName].message : defaultValidations['default'].message);
};

Validator.prototype._check = function (field, rule) {
  if(_.isRegExp(rule)) return rule.test(field.value);

  if(typeof rule === 'function') return rule(field.value);
};

Validator.prototype._setInvalid = function (fieldName) {
  this.model.setEach(fieldName, { isValid: false, isInvalid: true });
};

Validator.prototype._setValid = function (fieldName) {
  this.model.setEach(fieldName, { isValid: true, isInvalid: false });
};
<commit_msg>Changed name of method validateField to validate<commit_after>var _ = require('lodash');
var defaultValidations = require('./defaultValidations');

module.exports = Validator;

/**
 * Creates a validator object and initiates it
 * @param {Model} model - A scoped model to the location on where to put the validator's data
 * @param {Model|string} [origin] - Either a scoped model to the location where the original data is stored. Or, a path (as string) to the location where to find the original data. If not passed, the fields parameter is mandatory.
 * @param {Collection.<string, Object>} [fields] - A collection of fields to use. If not passed, the origin parameter is mandatory. The key for each object is the field name, and the value is the field object (specified below).
   * @param {*} [fields.<fieldName>.default] - A default value for this specific field.
   * @param {Object[]} [fields.<fieldName>.validations] - A list of validations to apply.
     * @param {String|Function|RegEx} [fields.<fieldName>.validations.<index>.rule] - The rule to use when validating this rule. Either, this can be a string matching the name of a default rule (specified in default checks or passed in as an option), OR a function which will get run with the value to be validated as input, which should return true|false reflecting the validity, OR a RegEx, which will get run similar to if you pass in a function.
     * @param {String} [fields.<fieldName>.validations.<index>.message] - The error message to show if validation fails
 * @param {Object} [options] - An options object
   * @param {Collection.<string, Function|RegEx>} [options.rules] - A collection of default rules to add to this instance. Each key is the name of the rule. The value is the rule, either a function or regular expression similar to field specific functions/regular expressions passed in the fields parameter
 * @returns {Validator} - Instance of Validator
 */
function Validator(model, origin, fields, options) {
  // Parse out arguments

  var args = Array.prototype.slice.call(arguments);

  if(!args.length) throw new Error('You must specify a model!');
  if(!args.length == 1) throw new Error('You must either specify an origin or a fields object');

  this.model = args.shift();
  var arg = args.shift();

  if(typeof (arg || {}).path === 'function') {
    this.origin = arg;

    arg = args.shift();
  } else if(typeof arg === 'string') {
    this.origin = this.model.scope(arg);

    arg = args.shift();
  }

  if(arg) this.fields = arg;

  this.options = _.assign({
    rules: {},
    messages: {}
  }, args.shift());

  // Setup
  this._setup();
};

Validator.prototype.getValues = function () {
  var values = {};
  _.each(this.model.get(), function (field, fieldName) {
    values[fieldName] = field.value;
  });
  return values;
}

Validator.prototype.validate = function (fieldname) {
  this._validateField(fieldname);
};

Validator.prototype.validateAll = function() {
  var self = this;
  _.each(this.model.get(), function (n, key) {
    self._validate(key);
  });
};

Validator.prototype.checkForInvalidFields = function() {
  return _.find(this.model.get(), function (field) {
    if(field.isInvalid) return field;
  });
};

Validator.prototype.setInvalid = function (fieldName, message) {
  this._setInvalid(fieldName);
  this.model.push(fieldName + '.messages', message || defaultValidations['default'].message);
};

/*
 * @public
 * Reset values to origin.
 */
Validator.prototype.resetForm = function () {
  this._setup();
};

/*
 * @public
 * Commit values to model. Call after client- and serverside validation.
 */
Validator.prototype.commit = function () {
  if(!this.origin) return;

  var self = this;

  _.each(this.origin.get(), function (n, key) {
    self.origin.set(key, self.model.get(key + '.value'));
  });
};

Validator.prototype._setup = function () {
  var self = this;

  if (this.fields) {
    _.each(this.fields, function (n, key) {
      self._addFieldProperties(key, n);
    });
  };

  if(this.origin) {
    _.each(this.origin.get(), function (value, fieldName) {
      self.model.set(fieldName + '.value', value);
    });
  };
};

Validator.prototype._addFieldProperties = function (fieldName, field) {
  var self = this;

  this.model.setEach(fieldName, {
    value: field.default,
    validations: this._assignValidations(field.validations),
    isValid: false,
    isInvalid: false,
    validate: function () {
      self._validate(fieldName);
    }
  });
};

Validator.prototype._validate = function (fieldName) {
  this.model.del(fieldName + '.messages');

  var field = this.model.get(fieldName);
  var valid = true;

  for (var i = 0; i < field.validations.length; i++) {
    var validation = field.validations[i];

    if (!this._check(field, validation.rule)) {
      valid = false;

      this.model.push(fieldName + '.messages', validation.message);
    }
  };

  if (valid) {
    this._setValid(fieldName);
  } else {
    this._setInvalid(fieldName);
  }
};

Validator.prototype._assignValidations = function (validations) {
  for (var i = 0; i < validations.length; i++) {
    var validation = validations[i];

    if (!validation.message) validation.message = this._getMessage(validation.rule);

    if (typeof validation.rule === 'string') validation.rule = this._getRule(validation.rule);

    if (typeof validation.rule !== 'function' && !_.isRegExp(validation.rule)) throw new Error('This rule is not (or does not point to) a RegEx or a function.');
  }

  return validations;
};

Validator.prototype._getRule = function (ruleName) {
  if(this.options.rules[ruleName]) return this.options.rules[ruleName];

  if(defaultValidations.hasOwnProperty(ruleName)) return defaultValidations[ruleName].rule;

  throw new Error('Rule: "' + ruleName + '" is not available. You need to add it as an option.');
};

Validator.prototype._getMessage = function (ruleName) {
  return this.options.messages[ruleName] || ((defaultValidations.hasOwnProperty(ruleName)) ? defaultValidations[ruleName].message : defaultValidations['default'].message);
};

Validator.prototype._check = function (field, rule) {
  if(_.isRegExp(rule)) return rule.test(field.value);

  if(typeof rule === 'function') return rule(field.value);
};

Validator.prototype._setInvalid = function (fieldName) {
  this.model.setEach(fieldName, { isValid: false, isInvalid: true });
};

Validator.prototype._setValid = function (fieldName) {
  this.model.setEach(fieldName, { isValid: true, isInvalid: false });
};
<|endoftext|>


<commit_before>(function($){

    var gen_from = 'passphrase';
    var gen_compressed = false;
    var gen_eckey = null;
    var gen_pt = null;
    var gen_ps_reset = false;
    var gen_timeout = 600;
    var timeout = null;

    function parseBase58Check(address) {
        var bytes = Bitcoin.Base58.decode(address);
        var end = bytes.length - 4;
        var hash = bytes.slice(0, end);
        var checksum = Crypto.SHA256(Crypto.SHA256(hash, {asBytes: true}), {asBytes: true});
        if (checksum[0] != bytes[end] ||
            checksum[1] != bytes[end+1] ||
            checksum[2] != bytes[end+2] ||
            checksum[3] != bytes[end+3]) {
          return [-1, []];
        }
        var version = hash.shift();
        return [version, hash];
    }

    encode_length = function(len) {
        if (len < 0x80) {
            return [len];
        } else if (len < 255) {
            return [0x80|1, len];
        } else {
            return [0x80|2, len >> 8, len & 0xff];
        }
    }

    encode_id = function(id, s) {
        var len = encode_length(s.length);
        return [id].concat(len).concat(s);
    }

    encode_integer = function(s) {
        if (typeof s == 'number') {
            s = [s];
        }
        return encode_id(0x02, s);
    }

    encode_octet_string = function(s)  {
        return encode_id(0x04, s);
    }

    encode_constructed = function(tag, s) {
        return encode_id(0xa0 + tag, s);
    }

    encode_bitstring = function(s) {
        return encode_id(0x03, s);
    }

    encode_sequence = function() {
        sequence = [];
        for (var i = 0; i < arguments.length; i++) {
            sequence = sequence.concat(arguments[i]);
        }
        return encode_id(0x30, sequence);
    }

    function getEncoded(pt, compressed) {
       var x = pt.getX().toBigInteger();
       var y = pt.getY().toBigInteger();
       var enc = integerToBytes(x, 32);
       if (compressed) {
         if (y.isEven()) {
           enc.unshift(0x02);
         } else {
           enc.unshift(0x03);
         }
       } else {
         enc.unshift(0x04);
         enc = enc.concat(integerToBytes(y, 32));
       }
       return enc;
    }

    function getDER(eckey, compressed) {
        var ecparams = getSECCurveByName("secp256k1");
        var _p = ecparams.getCurve().getQ().toByteArrayUnsigned();
        var _r = ecparams.getN().toByteArrayUnsigned();
        var encoded_oid = [0x06, 0x07, 0x2A, 0x86, 0x48, 0xCE, 0x3D, 0x01, 0x01];

        var secret = integerToBytes(eckey.priv, 32);
        var encoded_gxgy = getEncoded(ecparams.getG(), compressed);
        var encoded_pub = getEncoded(gen_pt, compressed);

        return encode_sequence(
            encode_integer(1),
            encode_octet_string(secret),
            encode_constructed(0,
                encode_sequence(
                    encode_integer(1),
                    encode_sequence(
                        encoded_oid, //encode_oid(*(1, 2, 840, 10045, 1, 1)), //TODO
                        encode_integer([0].concat(_p))
                    ),
                    encode_sequence(
                        encode_octet_string([0]),
                        encode_octet_string([7])
                    ),
                    encode_octet_string(encoded_gxgy),
                    encode_integer([0].concat(_r)),
                    encode_integer(1)
                )
            ),
            encode_constructed(1,
                encode_bitstring([0].concat(encoded_pub))
            )
        );
    }

    function pad(str, len, ch) {
        padding = '';
        for (var i = 0; i < len - str.length; i++) {
            padding += ch;
        }
        return padding + str;
    }

    function setErrorState(field, err, msg) {

        //group = field.parent().parent();

        group = field.closest('.control-group');

        if (err) {
            group.addClass('error');
        } else {
            group.removeClass('error');
        }

        var e = group.find('.errormsg');
        if (e) {
            e.text(msg||'');
        }
    }

    function get_radiobtn_id(obj, def) {
        res = def;
        obj.children().each(function(i) {
            if ($(this).hasClass('active'))
                res = $(this).attr('id');
        });
        return res;
    }

    function gen_random() {
        $('#pass').val('');
        $('#hash').focus();
        gen_from = 'secret';
        $('#secret').button('toggle');
        update_gen();
        var bytes = Crypto.util.randomBytes(32);
        $('#hash').val(Crypto.util.bytesToHex(bytes));
        clearTimeout(timeout);
        timeout = setTimeout(generate, gen_timeout);
    }

    function update_gen() {
        $('#pass').attr('readonly', gen_from != 'passphrase');
        $('#hash').attr('readonly', gen_from != 'secret');
        $('#sec').attr('readonly', gen_from != 'privkey');
        $('#sec').parent().parent().removeClass('error');
    }

    function update_gen_from() {
        gen_from = $(this).attr('id');
        update_gen();

        setErrorState($('#hash'), false);
        setErrorState($('#sec'), false);

        if (gen_from == 'passphrase') {

            if (gen_ps_reset) {
                gen_ps_reset = false;
                onChangePass();
            }
            $('#pass').focus();
        }

        if (gen_from == 'secret') {
            $('#hash').focus();
        }

        if (gen_from == 'privkey') {
            $('#sec').focus();
        }
    }

    function generate() {

        var hash_str = pad($('#hash').val(), 64, '0');
        var hash = Crypto.util.hexToBytes(hash_str);

        eckey = new Bitcoin.ECKey(hash);

        gen_eckey = eckey;

        try {
            var ecparams = getSECCurveByName("secp256k1");
            gen_pt = ecparams.getG().multiply(eckey.priv);
            gen_eckey.pub = getEncoded(gen_pt, gen_compressed);
            gen_eckey.pubKeyHash = Bitcoin.Util.sha256ripe160(gen_eckey.pub);
            var addr = eckey.getBitcoinAddress();
            setErrorState($('#hash'), false);
        } catch (err) {
            console.info(err);
            setErrorState($('#hash'), true, 'Invalid secret exponent (must be non-zero value)');
            return;
        }

        gen_update();
    }

    function update_gen_compressed() {
        setErrorState($('#hash'), false);
        setErrorState($('#sec'), false);
        gen_compressed = $(this).attr('id') == 'compressed';
        gen_eckey.pub = getEncoded(gen_pt, gen_compressed);
        gen_eckey.pubKeyHash = Bitcoin.Util.sha256ripe160(gen_eckey.pub);
        gen_update();
    }

    function gen_update() {

        var eckey = gen_eckey;
        var compressed = gen_compressed;

        var hash_str = pad($('#hash').val(), 64, '0');
        var hash = Crypto.util.hexToBytes(hash_str);

        var hash160 = eckey.getPubKeyHash();

        var addr = eckey.getBitcoinAddress();
        $('#addr').val(addr);

        var h160 = Crypto.util.bytesToHex(hash160);
        $('#h160').val(h160);

        var payload = hash;

        if (compressed)
            payload.push(0x01);

        var sec = new Bitcoin.Address(payload); sec.version = 128;
        $('#sec').val(sec);

        var pub = Crypto.util.bytesToHex(getEncoded(gen_pt, compressed));
        $('#pub').val(pub);

        var der = Crypto.util.bytesToHex(getDER(eckey, compressed));
        $('#der').val(der);

        var img = '';

        if (true) {
            var qr = qrcode(3, 'M');
            var text = $('#addr').val();
            text = text.replace(/^[\s\u3000]+|[\s\u3000]+$/g, '');
            qr.addData(text);
            qr.make();
            img = qr.createImgTag(5);
        }

        var url = 'http://blockchain.info/address/'+addr;
        $('#qr').html(''+img+'');
        $('#qr_addr').text($('#addr').val());
    }

    function calc_hash() {
        var hash = Crypto.SHA256($('#pass').val(), { asBytes: true });
        $('#hash').val(Crypto.util.bytesToHex(hash));
    }

    function onChangePass() {
        calc_hash();
        clearTimeout(timeout);
        timeout = setTimeout(generate, gen_timeout);
    }

    function onChangeHash() {
        $('#pass').val('');
        gen_ps_reset = true;

        clearTimeout(timeout);

        if (/[^0123456789abcdef]+/i.test($('#hash').val())) {
            setErrorState($('#hash'), true, 'Erroneous characters (must be 0..9-a..f)');
            return;
        } else {
            setErrorState($('#hash'), false);
        }

        timeout = setTimeout(generate, gen_timeout);
    }

    function onChangePrivKey() {

        clearTimeout(timeout);

        $('#pass').val('');
        gen_ps_reset = true;

        var sec = $('#sec').val();

        var res = parseBase58Check(sec);
        var version = res[0];
        var hash = res[1];

        var error = (version != 128 || hash.length != 32);

        if (version == -1) {
            setErrorState($('#sec'), true, 'Invalid private key checksum');
            return;
        } else if (version != 128) {
            setErrorState($('#sec'), true, 'Invalid private key version (must be 128)');
            return;
        } else if (hash.length < 32) {
            setErrorState($('#sec'), true, 'Invalid payload (must be 32 or 33 bytes)');
            return;
        }

        setErrorState($('#sec'), false);

        if (hash.length > 32) {
            hash.pop();

            gen_compressed = true;
            $('#compressed').button('toggle');
        } else {

            gen_compressed = false;
            $('#uncompressed').button('toggle');
        }

        $('#hash').val(Crypto.util.bytesToHex(hash));

        timeout = setTimeout(generate, gen_timeout);
    }

    var from = 'base58';
    var to = 'hex';

    function get_radiobtn_id(obj, def) {
        res = def;
        obj.children().each(function(i) {
            if ($(this).hasClass('active'))
                res = $(this).attr('id');
        });
        return res;
    }

    function update_direction(from, to) {
        $('#direction').html(from + ' > ' + to);
    }

    function update_enc_from() {
        from = $(this).attr('id').substring(5);
        update_direction(from, to);
        translate();
    }

    function update_enc_to() {
        to = $(this).attr('id').substring(3);
        update_direction(from, to);
        translate();
    }

    function strToBytes(str) {
        var bytes = [];
        for (var i = 0; i < str.length; ++i)
           bytes.push(str.charCodeAt(i));
        return bytes;
    }

    function bytesToString(bytes) {
        var str = '';
        for (var i = 0; i < bytes.length; ++i)
            str += String.fromCharCode(bytes[i]);
        return str;
    }

    function translate() {

        var str = $('#from').val();

        text = str;

        bytes = strToBytes(str);

        if (bytes.length > 0) {

            if (from == 'base58') {
                bytes = Bitcoin.Base58.decode(str);
            } else if (from == 'hex') {
                bytes = Crypto.util.hexToBytes(str);
            } else if (from == 'rfc1751') {
                bytes = rfc1751_to_key(str, false);
            } else if (from == 'base64') {
                bytes = Crypto.util.base64ToBytes(str);
            }

            if (to == 'base58') {
                text = Bitcoin.Base58.encode(bytes);
            } else if (to == 'hex') {
                text = Crypto.util.bytesToHex(bytes);
            } else if (to == 'text') {
                text = bytesToString(bytes);
            } else if (to == 'rfc1751') {
                text = key_to_rfc1751(bytes, false);
            } else if (to == 'base64') {
                text = Crypto.util.bytesToBase64(bytes);
            }

            var bstr = bytes.length + ' ' + (bytes.length == 1 ? 'byte' : 'bytes');

            $('#direction').html(from + '  > ' + bstr + ' > ' + to);

        }

        $('#to').val(text);

    }

    function onChangeFrom() {
        clearTimeout(timeout);
        timeout = setTimeout(translate, gen_timeout);
    }

    function onInput(id, func) {

        $(id).bind("input keyup keydown keypress change blur", function() {
            if ($(this).val() != jQuery.data(this, "lastvalue")) {
                func();
            }
            jQuery.data(this, "lastvalue", $(this).val());
        });

        $(id).bind("focus", function() {
           jQuery.data(this, "lastvalue", $(this).val());
        });
    }

    $(document).ready(
        function() {

            onInput('#pass', onChangePass);
            onInput('#hash', onChangeHash);
            onInput('#sec', onChangePrivKey);

            $('#passphrase').click(update_gen_from);
            $('#secret').click(update_gen_from);
            $('#privkey').click(update_gen_from);
            $('#random').click(gen_random);

            $('#uncompressed').click(update_gen_compressed);
            $('#compressed').click(update_gen_compressed);

            $('#pass').val('correct horse battery staple');
            calc_hash();
            generate();
            $('#pass').focus();

            onInput('#from', onChangeFrom);

            $("body").on("click", "#enc_from .btn", update_enc_from);
            $("body").on("click", "#enc_to .btn", update_enc_to);

            update_direction(from, to);
        }
    );
})(jQuery);
<commit_msg>Removed random gen timeout<commit_after>(function($){

    var gen_from = 'passphrase';
    var gen_compressed = false;
    var gen_eckey = null;
    var gen_pt = null;
    var gen_ps_reset = false;
    var gen_timeout = 600;
    var timeout = null;

    function parseBase58Check(address) {
        var bytes = Bitcoin.Base58.decode(address);
        var end = bytes.length - 4;
        var hash = bytes.slice(0, end);
        var checksum = Crypto.SHA256(Crypto.SHA256(hash, {asBytes: true}), {asBytes: true});
        if (checksum[0] != bytes[end] ||
            checksum[1] != bytes[end+1] ||
            checksum[2] != bytes[end+2] ||
            checksum[3] != bytes[end+3]) {
          return [-1, []];
        }
        var version = hash.shift();
        return [version, hash];
    }

    encode_length = function(len) {
        if (len < 0x80) {
            return [len];
        } else if (len < 255) {
            return [0x80|1, len];
        } else {
            return [0x80|2, len >> 8, len & 0xff];
        }
    }

    encode_id = function(id, s) {
        var len = encode_length(s.length);
        return [id].concat(len).concat(s);
    }

    encode_integer = function(s) {
        if (typeof s == 'number') {
            s = [s];
        }
        return encode_id(0x02, s);
    }

    encode_octet_string = function(s)  {
        return encode_id(0x04, s);
    }

    encode_constructed = function(tag, s) {
        return encode_id(0xa0 + tag, s);
    }

    encode_bitstring = function(s) {
        return encode_id(0x03, s);
    }

    encode_sequence = function() {
        sequence = [];
        for (var i = 0; i < arguments.length; i++) {
            sequence = sequence.concat(arguments[i]);
        }
        return encode_id(0x30, sequence);
    }

    function getEncoded(pt, compressed) {
       var x = pt.getX().toBigInteger();
       var y = pt.getY().toBigInteger();
       var enc = integerToBytes(x, 32);
       if (compressed) {
         if (y.isEven()) {
           enc.unshift(0x02);
         } else {
           enc.unshift(0x03);
         }
       } else {
         enc.unshift(0x04);
         enc = enc.concat(integerToBytes(y, 32));
       }
       return enc;
    }

    function getDER(eckey, compressed) {
        var ecparams = getSECCurveByName("secp256k1");
        var _p = ecparams.getCurve().getQ().toByteArrayUnsigned();
        var _r = ecparams.getN().toByteArrayUnsigned();
        var encoded_oid = [0x06, 0x07, 0x2A, 0x86, 0x48, 0xCE, 0x3D, 0x01, 0x01];

        var secret = integerToBytes(eckey.priv, 32);
        var encoded_gxgy = getEncoded(ecparams.getG(), compressed);
        var encoded_pub = getEncoded(gen_pt, compressed);

        return encode_sequence(
            encode_integer(1),
            encode_octet_string(secret),
            encode_constructed(0,
                encode_sequence(
                    encode_integer(1),
                    encode_sequence(
                        encoded_oid, //encode_oid(*(1, 2, 840, 10045, 1, 1)), //TODO
                        encode_integer([0].concat(_p))
                    ),
                    encode_sequence(
                        encode_octet_string([0]),
                        encode_octet_string([7])
                    ),
                    encode_octet_string(encoded_gxgy),
                    encode_integer([0].concat(_r)),
                    encode_integer(1)
                )
            ),
            encode_constructed(1,
                encode_bitstring([0].concat(encoded_pub))
            )
        );
    }

    function pad(str, len, ch) {
        padding = '';
        for (var i = 0; i < len - str.length; i++) {
            padding += ch;
        }
        return padding + str;
    }

    function setErrorState(field, err, msg) {

        //group = field.parent().parent();

        group = field.closest('.control-group');

        if (err) {
            group.addClass('error');
        } else {
            group.removeClass('error');
        }

        var e = group.find('.errormsg');
        if (e) {
            e.text(msg||'');
        }
    }

    function get_radiobtn_id(obj, def) {
        res = def;
        obj.children().each(function(i) {
            if ($(this).hasClass('active'))
                res = $(this).attr('id');
        });
        return res;
    }

    function gen_random() {
        $('#pass').val('');
        $('#hash').focus();
        gen_from = 'secret';
        $('#secret').button('toggle');
        update_gen();
        var bytes = Crypto.util.randomBytes(32);
        $('#hash').val(Crypto.util.bytesToHex(bytes));
        generate();
    }

    function update_gen() {
        $('#pass').attr('readonly', gen_from != 'passphrase');
        $('#hash').attr('readonly', gen_from != 'secret');
        $('#sec').attr('readonly', gen_from != 'privkey');
        $('#sec').parent().parent().removeClass('error');
    }

    function update_gen_from() {
        gen_from = $(this).attr('id');
        update_gen();

        setErrorState($('#hash'), false);
        setErrorState($('#sec'), false);

        if (gen_from == 'passphrase') {

            if (gen_ps_reset) {
                gen_ps_reset = false;
                onChangePass();
            }
            $('#pass').focus();
        }

        if (gen_from == 'secret') {
            $('#hash').focus();
        }

        if (gen_from == 'privkey') {
            $('#sec').focus();
        }
    }

    function generate() {

        var hash_str = pad($('#hash').val(), 64, '0');
        var hash = Crypto.util.hexToBytes(hash_str);

        eckey = new Bitcoin.ECKey(hash);

        gen_eckey = eckey;

        try {
            var ecparams = getSECCurveByName("secp256k1");
            gen_pt = ecparams.getG().multiply(eckey.priv);
            gen_eckey.pub = getEncoded(gen_pt, gen_compressed);
            gen_eckey.pubKeyHash = Bitcoin.Util.sha256ripe160(gen_eckey.pub);
            var addr = eckey.getBitcoinAddress();
            setErrorState($('#hash'), false);
        } catch (err) {
            console.info(err);
            setErrorState($('#hash'), true, 'Invalid secret exponent (must be non-zero value)');
            return;
        }

        gen_update();
    }

    function update_gen_compressed() {
        setErrorState($('#hash'), false);
        setErrorState($('#sec'), false);
        gen_compressed = $(this).attr('id') == 'compressed';
        gen_eckey.pub = getEncoded(gen_pt, gen_compressed);
        gen_eckey.pubKeyHash = Bitcoin.Util.sha256ripe160(gen_eckey.pub);
        gen_update();
    }

    function gen_update() {

        var eckey = gen_eckey;
        var compressed = gen_compressed;

        var hash_str = pad($('#hash').val(), 64, '0');
        var hash = Crypto.util.hexToBytes(hash_str);

        var hash160 = eckey.getPubKeyHash();

        var addr = eckey.getBitcoinAddress();
        $('#addr').val(addr);

        var h160 = Crypto.util.bytesToHex(hash160);
        $('#h160').val(h160);

        var payload = hash;

        if (compressed)
            payload.push(0x01);

        var sec = new Bitcoin.Address(payload); sec.version = 128;
        $('#sec').val(sec);

        var pub = Crypto.util.bytesToHex(getEncoded(gen_pt, compressed));
        $('#pub').val(pub);

        var der = Crypto.util.bytesToHex(getDER(eckey, compressed));
        $('#der').val(der);

        var img = '';

        if (true) {
            var qr = qrcode(3, 'M');
            var text = $('#addr').val();
            text = text.replace(/^[\s\u3000]+|[\s\u3000]+$/g, '');
            qr.addData(text);
            qr.make();
            img = qr.createImgTag(5);
        }

        var url = 'http://blockchain.info/address/'+addr;
        $('#qr').html(''+img+'');
        $('#qr_addr').text($('#addr').val());
    }

    function calc_hash() {
        var hash = Crypto.SHA256($('#pass').val(), { asBytes: true });
        $('#hash').val(Crypto.util.bytesToHex(hash));
    }

    function onChangePass() {
        calc_hash();
        clearTimeout(timeout);
        timeout = setTimeout(generate, gen_timeout);
    }

    function onChangeHash() {
        $('#pass').val('');
        gen_ps_reset = true;

        clearTimeout(timeout);

        if (/[^0123456789abcdef]+/i.test($('#hash').val())) {
            setErrorState($('#hash'), true, 'Erroneous characters (must be 0..9-a..f)');
            return;
        } else {
            setErrorState($('#hash'), false);
        }

        timeout = setTimeout(generate, gen_timeout);
    }

    function onChangePrivKey() {

        clearTimeout(timeout);

        $('#pass').val('');
        gen_ps_reset = true;

        var sec = $('#sec').val();

        var res = parseBase58Check(sec);
        var version = res[0];
        var hash = res[1];

        var error = (version != 128 || hash.length != 32);

        if (version == -1) {
            setErrorState($('#sec'), true, 'Invalid private key checksum');
            return;
        } else if (version != 128) {
            setErrorState($('#sec'), true, 'Invalid private key version (must be 128)');
            return;
        } else if (hash.length < 32) {
            setErrorState($('#sec'), true, 'Invalid payload (must be 32 or 33 bytes)');
            return;
        }

        setErrorState($('#sec'), false);

        if (hash.length > 32) {
            hash.pop();

            gen_compressed = true;
            $('#compressed').button('toggle');
        } else {

            gen_compressed = false;
            $('#uncompressed').button('toggle');
        }

        $('#hash').val(Crypto.util.bytesToHex(hash));

        timeout = setTimeout(generate, gen_timeout);
    }

    var from = 'base58';
    var to = 'hex';

    function get_radiobtn_id(obj, def) {
        res = def;
        obj.children().each(function(i) {
            if ($(this).hasClass('active'))
                res = $(this).attr('id');
        });
        return res;
    }

    function update_direction(from, to) {
        $('#direction').html(from + ' > ' + to);
    }

    function update_enc_from() {
        from = $(this).attr('id').substring(5);
        update_direction(from, to);
        translate();
    }

    function update_enc_to() {
        to = $(this).attr('id').substring(3);
        update_direction(from, to);
        translate();
    }

    function strToBytes(str) {
        var bytes = [];
        for (var i = 0; i < str.length; ++i)
           bytes.push(str.charCodeAt(i));
        return bytes;
    }

    function bytesToString(bytes) {
        var str = '';
        for (var i = 0; i < bytes.length; ++i)
            str += String.fromCharCode(bytes[i]);
        return str;
    }

    function translate() {

        var str = $('#from').val();

        text = str;

        bytes = strToBytes(str);

        if (bytes.length > 0) {

            if (from == 'base58') {
                bytes = Bitcoin.Base58.decode(str);
            } else if (from == 'hex') {
                bytes = Crypto.util.hexToBytes(str);
            } else if (from == 'rfc1751') {
                bytes = rfc1751_to_key(str, false);
            } else if (from == 'base64') {
                bytes = Crypto.util.base64ToBytes(str);
            }

            if (to == 'base58') {
                text = Bitcoin.Base58.encode(bytes);
            } else if (to == 'hex') {
                text = Crypto.util.bytesToHex(bytes);
            } else if (to == 'text') {
                text = bytesToString(bytes);
            } else if (to == 'rfc1751') {
                text = key_to_rfc1751(bytes, false);
            } else if (to == 'base64') {
                text = Crypto.util.bytesToBase64(bytes);
            }

            var bstr = bytes.length + ' ' + (bytes.length == 1 ? 'byte' : 'bytes');

            $('#direction').html(from + '  > ' + bstr + ' > ' + to);

        }

        $('#to').val(text);

    }

    function onChangeFrom() {
        clearTimeout(timeout);
        timeout = setTimeout(translate, gen_timeout);
    }

    function onInput(id, func) {

        $(id).bind("input keyup keydown keypress change blur", function() {
            if ($(this).val() != jQuery.data(this, "lastvalue")) {
                func();
            }
            jQuery.data(this, "lastvalue", $(this).val());
        });

        $(id).bind("focus", function() {
           jQuery.data(this, "lastvalue", $(this).val());
        });
    }

    $(document).ready(
        function() {

            onInput('#pass', onChangePass);
            onInput('#hash', onChangeHash);
            onInput('#sec', onChangePrivKey);

            $('#passphrase').click(update_gen_from);
            $('#secret').click(update_gen_from);
            $('#privkey').click(update_gen_from);
            $('#random').click(gen_random);

            $('#uncompressed').click(update_gen_compressed);
            $('#compressed').click(update_gen_compressed);

            $('#pass').val('correct horse battery staple');
            calc_hash();
            generate();
            $('#pass').focus();

            onInput('#from', onChangeFrom);

            $("body").on("click", "#enc_from .btn", update_enc_from);
            $("body").on("click", "#enc_to .btn", update_enc_to);

            update_direction(from, to);
        }
    );
})(jQuery);
<|endoftext|>


<commit_before>import Morph from "./Morph.js"

import { Graph } from 'src/client/triples/triples.js';
import lively from 'src/client/lively.js';

export default class AddTriple extends Morph {
  async initialize() {
    this.windowTitle = "Add Triple";

    let title = this.get("#title");
    title.addEventListener('keyup',  event => {
      if (event.keyCode == 13) { // ENTER
        this.save();
      }
    });

    let input = this.get("#inputSubject");
    let list = this.get("#subject");
    input.addEventListener('keyup',  event => {
      if (event.keyCode == 13) { // ENTER
        // https://derickbailey.com/2016/03/23/get-a-data-attribute-value-from-the-selected-datalist-option/
        var value = input.value;
        lively.notify('input value: ' + value);
        // TODO: value could be a literal or a url
        var option = this.get("#subject [value='" + value + "']");
        // value could also be an external url
        if(!option) return;
        lively.notify(option.innerHTML)
        window.myOption = option;
        let id = option.dataset.url;
        lively.notify('url: ' + id);
      }
    });

    let button = this.get('#save');
    button.addEventListener('click', event => this.save());

    this.prepareOptions('#subject2');
    this.prepareOptions('#predicate2');
    this.prepareOptions('#object2');

    this.selectors.forEach(({ list }) => this.prepareDatalist(list));
  }

  get selectors() {
    return [{
      input: '#inputSubject',
      list: '#subject'
    }, {
      input: '#inputPredicate',
      list: '#predicate'
    }, {
      input: '#inputObject',
      list: '#object'
    }]
  }

  setupSaveEventListeners() {

  }

  async prepareOptions(listSelector) {
    let graph = Graph.getInstance();
    await graph.loadFromDir('https://lively4/dropbox/');

    let selection = this.get(listSelector);
    graph.getKnots().forEach(knot => {
      let option = document.createElement('option');
      option.value = knot.url;
      option.text = knot.label();

      selection.appendChild(option);
    });
  }

  async prepareDatalist(listSelector) {
    let graph = Graph.getInstance();
    await graph.loadFromDir('https://lively4/dropbox/');

    let selection = this.get(listSelector);
    graph.getKnots().forEach(knot => {
      let option = document.createElement('option');

      option.innerHTML = knot.label();
      option.value = knot.url;
      option.dataset.url = knot.url;

      selection.appendChild(option);
    });
  }

  getURLFor(inputSelector, listSelector) {

  }

  async save() {
    let graph = Graph.getInstance();

    let directory = this.get('#directory').value;
    let title = this.get('#title').value;
    let fileEnding = this.get('#file-ending').value;

    graph.createTriple(
      this.getURLFor('#inputSubject', '#subject'),
      this.getURLFor('#inputPredicate', '#predicate'),
      this.getURLFor('#inputObject', '#object')
    );
  }
}
<commit_msg>AUTO-COMMIT templates/add-triple.js<commit_after>import Morph from "./Morph.js"

import { Graph } from 'src/client/triples/triples.js';
import lively from 'src/client/lively.js';

export default class AddTriple extends Morph {
  async initialize() {
    this.windowTitle = "Add Triple";

    let title = this.get("#title");
    title.addEventListener('keyup',  event => {
      if (event.keyCode == 13) { // ENTER
        this.save();
      }
    });

    let input = this.get("#inputSubject");
    let list = this.get("#subject");
    input.addEventListener('keyup',  event => {
      if (event.keyCode == 13) { // ENTER
        // https://derickbailey.com/2016/03/23/get-a-data-attribute-value-from-the-selected-datalist-option/
        var value = input.value;
        lively.notify('input value: ' + value);
        // TODO: value could be a literal or a url
        var option = this.get("#subject [value='" + value + "']");
        // value could also be an external url
        if(!option) return;
        lively.notify(option.innerHTML)
        window.myOption = option;
        let id = option.dataset.url;
        lively.notify('url: ' + id);
      }
    });

    let button = this.get('#save');
    button.addEventListener('click', event => this.save());

    this.prepareOptions('#subject2');
    this.prepareOptions('#predicate2');
    this.prepareOptions('#object2');

    this.selectors.forEach(({ list }) => this.prepareDatalist(list));
  }

  get selectors() {
    return [{
      input: '#inputSubject',
      list: '#subject'
    }, {
      input: '#inputPredicate',
      list: '#predicate'
    }, {
      input: '#inputObject',
      list: '#object'
    }]
  }

  setupSaveEventListeners() {

  }

  async prepareOptions(listSelector) {
    let graph = Graph.getInstance();
    await graph.loadFromDir('https://lively4/dropbox/');

    let selection = this.get(listSelector);
    graph.getKnots().forEach(knot => {
      let option = document.createElement('option');
      option.value = knot.url;
      option.text = knot.label();

      selection.appendChild(option);
    });
  }

  async prepareDatalist(listSelector) {
    let graph = Graph.getInstance();
    await graph.loadFromDir('https://lively4/dropbox/');

    let selection = this.get(listSelector);
    graph.getKnots().forEach(knot => {
      let option = document.createElement('option');

      option.innerHTML = knot.label();
      option.value = knot.url;
      option.dataset.url = knot.url;

      selection.appendChild(option);
    });
  }

  getURLFor(inputSelector, listSelector) {
    let input = this.get(inputSelector);
    let list = this.get(listSelector);
    // https://derickbailey.com/2016/03/23/get-a-data-attribute-value-from-the-selected-datalist-option/
    var value = input.value;
    lively.notify('input value: ' + value);
    // TODO: value could be a literal or a url
    var option = this.get("#subject [value='" + value + "']");
    // value could also be an external url
    if(!option) return;
    lively.notify(option.innerHTML)
    window.myOption = option;
    let id = option.dataset.url;
    lively.notify('url: ' + id);
    return id;
  }

  async save() {
    let graph = Graph.getInstance();

    let directory = this.get('#directory').value;
    let title = this.get('#title').value;
    let fileEnding = this.get('#file-ending').value;

    graph.createTriple(
      this.getURLFor('#inputSubject', '#subject'),
      this.getURLFor('#inputPredicate', '#predicate'),
      this.getURLFor('#inputObject', '#object')
    );
  }
}
<|endoftext|>


<commit_before>'use strict';

// @ngInject
function LoginController(CardshifterServerAPI, $scope, $location, $rootScope, $timeout) {
    var SUCCESS = 200;
    var UPDATE_DELAY = 10000;
    var REFRESH_DELAY = 3000;

    $scope.refreshing = false;

    $scope.servers = [
        new ServerInfo("Local Host", "ws://127.0.0.1:4243"),
        new ServerInfo("Dwarf Towers", "ws://dwarftowers.com:4243"),
        new ServerInfo("Zomis.net", "ws://stats.zomis.net:4243"),
        new ServerInfo("Other...", "other")
    ];

    $scope.login = function() {
        $scope.loggedIn = true;
        var finalServer = ($scope.server === "other" ? $scope.other_server : $scope.server);

        CardshifterServerAPI.init(finalServer, $scope.is_secure, function() {
            var login = new CardshifterServerAPI.messageTypes.LoginMessage($scope.username);

            try {
                CardshifterServerAPI.setMessageListener(function(welcome) {
                    if(welcome.status === SUCCESS && welcome.message === "OK") {
                        // taking the easy way out
                        window.currentUser = {
                            username: $scope.username,
                            id: welcome.userId,
                            game: {
                                id: null,
                                mod: null
                            }
                        };

                        $rootScope.$apply(function() {
                            $location.path("/lobby");
                        });
                    } else {
                        console.log("server messsage: " + welcome.message);
                        $scope.loggedIn = false;
                        $scope.$apply();
                    }
                }, ["loginresponse"]);
                CardshifterServerAPI.sendMessage(login);

            } catch(e) {
                // notify the user that there was an issue logging in (loginmessage issue)
                console.log("LoginMessage error(error 2): " + e);
                $scope.loggedIn = false;
                $scope.$apply();
            }
        }, function() {
            // notify the user that there was an issue logging in (websocket issue)
            console.log("Websocket error(error 1)");
            $scope.loggedIn = false;
            $scope.$apply();
        });
    }

    $scope.refreshServers = function() {
        $scope.refreshing = true;
        $timeout(function() {
            $scope.refreshing = false;
        }, REFRESH_DELAY);

        /**
        */
        var i = 0;
        (function getServerInfo() {
            var thisServer = $scope.servers[i];

            if(thisServer.name === "Other...") {
                return;
            }

            var now = Date.now();

            CardshifterServerAPI.init(thisServer.address, false, function() {
                thisServer.latency = Date.now() - now;
                thisServer.isOnline = true;

                CardshifterServerAPI.socket.close();
                CardshifterServerAPI.socket = null;

                i++;
                if($scope.servers[i]) {
                    getServerInfo();
                }
            }, function() {
                thisServer.latency = 0;
                thisServer.isOnline = false;
                thisServer.userCount = 0;

                i++;
                if($scope.servers[i]) {
                    getServerInfo();
                }
            })
        })();
    };

    /**
    * The ServerInfo class.
    * @constructor
    *
    * @param name:string -- The name of the server
    * @param address:string -- The address of the server
    *
    * This class is used for displaying the various
    * available servers at the top of the screen
    * in the server status table.
    */
    function ServerInfo(name, address) {
        this.name = name;
        this.address = address;
        this.isOnline = false;
        this.userCount = 0;
        this.latency = 0;
    }
};

module.exports = LoginController;
<commit_msg>added documentation<commit_after>'use strict';

// @ngInject
function LoginController(CardshifterServerAPI, $scope, $location, $rootScope, $timeout) {
    var SUCCESS = 200;
    var UPDATE_DELAY = 10000;
    var REFRESH_DELAY = 3000;

    $scope.refreshing = false;

    $scope.servers = [
        new ServerInfo("Local Host", "ws://127.0.0.1:4243"),
        new ServerInfo("Dwarf Towers", "ws://dwarftowers.com:4243"),
        new ServerInfo("Zomis.net", "ws://stats.zomis.net:4243"),
        new ServerInfo("Other...", "other")
    ];

    $scope.login = function() {
        $scope.loggedIn = true;
        var finalServer = ($scope.server === "other" ? $scope.other_server : $scope.server);

        CardshifterServerAPI.init(finalServer, $scope.is_secure, function() {
            var login = new CardshifterServerAPI.messageTypes.LoginMessage($scope.username);

            try {
                CardshifterServerAPI.setMessageListener(function(welcome) {
                    if(welcome.status === SUCCESS && welcome.message === "OK") {
                        // taking the easy way out
                        window.currentUser = {
                            username: $scope.username,
                            id: welcome.userId,
                            game: {
                                id: null,
                                mod: null
                            }
                        };

                        $rootScope.$apply(function() {
                            $location.path("/lobby");
                        });
                    } else {
                        console.log("server messsage: " + welcome.message);
                        $scope.loggedIn = false;
                        $scope.$apply();
                    }
                }, ["loginresponse"]);
                CardshifterServerAPI.sendMessage(login);

            } catch(e) {
                // notify the user that there was an issue logging in (loginmessage issue)
                console.log("LoginMessage error(error 2): " + e);
                $scope.loggedIn = false;
                $scope.$apply();
            }
        }, function() {
            // notify the user that there was an issue logging in (websocket issue)
            console.log("Websocket error(error 1)");
            $scope.loggedIn = false;
            $scope.$apply();
        });
    }

    $scope.refreshServers = function() {
        $scope.refreshing = true;
        $timeout(function() {
            $scope.refreshing = false;
        }, REFRESH_DELAY);

        /**
        * This is a recursive function that is called
        * once the Websocket has successfully connected
        * with the server. Once it is connected, the
        * Websocket is obliterated.
        *
        * This is used in place of the loop because
        * API.init is a mostly async method, so the
        * loop would rapidly terminate, and the sockets
        * will be destroyed at the incorrect points in
        * order for the "blank users"(#92) to be prevented.
        */
        var i = 0;
        (function getServerInfo() {
            var thisServer = $scope.servers[i];

            if(thisServer.name === "Other...") {
                return;
            }

            var now = Date.now();

            CardshifterServerAPI.init(thisServer.address, false, function() {
                thisServer.latency = Date.now() - now;
                thisServer.isOnline = true;

                CardshifterServerAPI.socket.close();
                CardshifterServerAPI.socket = null;

                i++;
                if($scope.servers[i]) {
                    getServerInfo();
                }
            }, function() {
                thisServer.latency = 0;
                thisServer.isOnline = false;
                thisServer.userCount = 0;

                i++;
                if($scope.servers[i]) {
                    getServerInfo();
                }
            })
        })();
    };

    /**
    * The ServerInfo class.
    * @constructor
    *
    * @param name:string -- The name of the server
    * @param address:string -- The address of the server
    *
    * This class is used for displaying the various
    * available servers at the top of the screen
    * in the server status table.
    */
    function ServerInfo(name, address) {
        this.name = name;
        this.address = address;
        this.isOnline = false;
        this.userCount = 0;
        this.latency = 0;
    }
};

module.exports = LoginController;
<|endoftext|>