<commit_before>/*
 * This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
 */

/*
 * Copyright (c) 2015, Joyent, Inc.
 */

var assert = require('assert-plus');
var cp = require('child_process');
var execFile = cp.execFile;
var spawn = cp.spawn;

var VMADM_PATH = '/usr/sbin/vmadm';

function vmadm() {}

/*
 * execVmadm options:
 *
 *  args (required)      -- the cmdline args for vmadm [array]
 *  log (required)       -- a bunyan logger
 *  req_id (recommended) -- a req_id to pass to vmadm
 *  vmadmLogger          -- an object with a .write() method that takes a single
 *                          object as its argument. vmadm evt logs go here.
 *
 * Calls callback with
 *
 *   ({code: <code>, signal: <signal>}, stdout [string], stderr [array])
 *
 * on vmadm exit.
 *
 */
function execVmadm(opts, callback) {
    assert.object(opts, 'opts');
    assert.object(opts.log, 'opts.log');
    assert.arrayOfString(opts.args, 'opts.args');

    var args = opts.args;
    var child;
    var execOpts = {env: {}};
    var stderrBuffer = '';
    var stderrLines = [];
    var stdoutBuffer = '';

    if (opts.req_id) {
        opts.log.info('setting req_id to %s', opts.req_id);
        execOpts.env.REQ_ID = opts.req_id;
    }
    execOpts.env.VMADM_DEBUG_LEVEL = 'debug';
    if (process.env.EXPERIMENTAL_VMJS_TRACING) {
        execOpts.env.EXPERIMENTAL_VMJS_TRACING =
            process.env.EXPERIMENTAL_VMJS_TRACING;
    }

    opts.log.info({ args: args, execOpts: execOpts }, 'executing vmadm');

    child = spawn(VMADM_PATH, args, execOpts);

    child.stdout.on('data', function _childStdoutHandler(data) {
        stdoutBuffer += data.toString();
    });

    child.stderr.on('data', function _childStderrHandler(data) {
        var chunk;
        var chunks;
        var logobj;

        stderrBuffer += data.toString();
        chunks = stderrBuffer.split('\n');
        while (chunks.length > 1) {
            chunk = chunks.shift();

            // log the record to the vmadmLogger if it's an evt log.
            logobj = undefined;
            if (opts.vmadmLogger) {
                if (chunk[0] === '{' && chunk.indexOf('"evt"') !== -1) {
                    try {
                        logobj = JSON.parse(chunk);
                    } catch (e) {
                        opts.log.warn({line: chunk, err: e},
                            'failed to JSON.parse line');
                    }
                }
            }
            if (logobj) {
                opts.vmadmLogger.write(logobj);
            }

            stderrLines.push(chunk);
        }
        stderrBuffer = chunks.pop();
    });

    child.on('close', function _childCloseHandler(code, signal) {
        if (stderrBuffer.length > 0) {
            opts.log.info('stderr from vmadm: ' + stderrBuffer);
            stderrLines.push(stderrBuffer);
        }
        opts.log.info('vmadm child closed with (%d, %d)', code, signal);
        callback({code: code, signal: signal}, stdoutBuffer, stderrLines);
    });

    if (opts.stdinData) {
        child.stdin.write(opts.stdinData);
    }
    child.stdin.end();
}

/**
 * Call `vmadm lookup -j UUID`.
 *
 * @param opts {Object} Options
 *      - uuid {String} The VM uuid.
 *      - log {Logger object}
 * @param vmopts {Object} Optional vm options
 *      - fields {Array} Return only the keys give in `fields` array
 * @param callback {Function} `function (err)`
 */

vmadm.load = function vmLoad(opts, vmopts, callback) {
    assert.object(opts, 'opts');
    assert.string(opts.uuid, 'opts.uuid');

    if (!callback) {
        callback = vmopts;
    }

    function addargs(newargs) {
        Array.prototype.push.apply(args, newargs);
    }

    var args = ['lookup', '-1', '-j'];

    if (vmopts && vmopts.fields) {
        addargs(['-o', opts.fields.join(',')]);
    }

    args.push('uuid=' + opts.uuid);

    var execOpts = {
        args: args,
        log: opts.log,
        req_id: opts.req_id
    };

    opts.log.info('spawning vmadm for load');

    execVmadm(execOpts, function (result, stdout, stderr) {
        var err;
        var vm;
        var vms;

        if (result.code !== 0) {
            err = new Error('vmadm exited with code: %d signal: %d',
                result.code, result.signal);
            err.stderr = stderr;
            return callback(err);
        }

        try {
            vms = JSON.parse(stdout);
        } catch (jsonErr) {
            jsonErr.stdout = stdout;
            return callback(jsonErr);
        }

        if (vms.length) {
            vm = vms[0];
        }

        return callback(null, vm);
    });
};

/**
 * Call `vmadm create`.
 *
 * @param opts {Object} Options
 *      - log {Logger object}
 * @param callback {Function} `function (err)`
 */

vmadm.create = function vmCreate(opts, callback) {
    assert.object(opts, 'opts');
    assert.object(opts.log, 'opts.log');

    var execOpts = {};
    var log = opts.log;
    delete opts.log;

    log.info('spawning vmadm for create');

    execOpts.log = log;
    execOpts.args = ['create'];
    execOpts.req_id = opts.req_id;
    delete opts.req_id;

    if (opts.vmadmLogger) {
        execOpts.vmadmLogger = opts.vmadmLogger;
        delete opts.vmadmLogger;
    }

    execOpts.stdinData = JSON.stringify(opts);

    execVmadm(execOpts, function (result, stdout, stderr) {
        if (result.code !== 0) {
            callback(new Error(stderr.join('\n').trim()));
            return;
        }
        callback();
    });
};

/**
 * Call `vmadm delete <uuid>`.
 *
 * @param opts {Object} Options
 *      - uuid {String} UUID of VM to delete
 *      - log {Logger object}
 * @param callback {Function} `function (err)`
 */

vmadm.delete = function vmDelete(opts, callback) {
    assert.object(opts, 'opts');
    assert.string(opts.uuid, 'opts.uuid');
    assert.object(opts.log, 'opts.log');

    var args = ['delete', opts.uuid];

    var execOpts = {
        args: args,
        log: opts.log,
        req_id: opts.req_id
    };

    opts.log.info('spawning vmadm for delete');

    execVmadm(execOpts, function (result, stdout, stderr) {
        var err;

        if (err) {
            err = new Error('vmadm exited with code: %d signal: %d',
                result.code, result.signal);
            err.stderr = stderr;
            return callback(err);
        }
        return callback();
    });
};

/**
 * Call `vmadm update`.
 *
 * @param opts {Object} VMADM update payload
 *      - log {Logger object}
 * @param callback {Function} `function (err)`
 */

vmadm.update = function vmUpdate(opts, callback) {
    assert.object(opts, 'opts');
    assert.string(opts.uuid, 'opts.uuid');
    assert.object(opts.log, 'opts.log');

    var log = opts.log;
    delete opts.log;
    log.info('spawning vmadm for machine update');

    var vmadmproc = spawn(VMADM_PATH, ['update', opts.uuid]);
    var stderr = '';

    vmadmproc.stdin.write(JSON.stringify(opts));
    vmadmproc.stdin.end();

    vmadmproc.on('close', function (code) {
        if (code) {
            callback(new Error(stderr.trim()));
            return;
        }
        callback();
    });

    vmadmproc.stderr.on('data', function (data) {
        stderr += data.toString();
    });
};

/**
 * Call `vmadm reboot <uuid>`.
 *
 * @param opts {Object} Options
 *      - uuid {String} UUID of VM to reboot
 *      - force {Boolean} Whether to force the reboot.
 *      - log {Logger object}
 * @param callback {Function} `function (err)`
 */

vmadm.reboot = function vmReboot(opts, callback) {
    assert.object(opts, 'opts');
    assert.string(opts.uuid, 'opts.uuid');
    assert.object(opts.log, 'opts.log');

    var args = ['reboot', opts.uuid];

    if (opts.force) {
        args.push('-F');
    }

    var execopts = {
        args: args,
        log: opts.log
    };

    execVmadm(execopts, function (err, stdout, stderr) {
        if (err) {
            return callback(err);
        }
        return callback();
    });
};

/**
 * Call `vmadm reprovision`.
 *
 * @param opts {Object} VMADM reprovision payload
 *      - log {Logger object}
 *      - uuid {String} uuid of vm to be reprovisioned
 * @param callback {Function} `function (err)`
 */

vmadm.reprovision = function vmReprovision(opts, callback) {
    assert.object(opts, 'opts');
    assert.string(opts.uuid, 'opts.uuid');
    assert.object(opts.log, 'opts.log');

    var log = opts.log;
    delete opts.log;
    log.info('spawning vmadm for machine update');

    var vmadmproc = spawn(VMADM_PATH, ['reprovision', opts.uuid]);
    var stderr = '';

    vmadmproc.stdin.write(JSON.stringify(opts));
    vmadmproc.stdin.end();

    vmadmproc.on('close', function (code) {
        if (code) {
            callback(new Error(stderr.trim()));
            return;
        }
        callback();
    });

    vmadmproc.stderr.on('data', function (data) {
        stderr += data.toString();
    });
};

module.exports = vmadm;
<commit_msg>fixed breakage caused by merged<commit_after>/*
 * This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
 */

/*
 * Copyright (c) 2015, Joyent, Inc.
 */

var assert = require('assert-plus');
var cp = require('child_process');
var execFile = cp.execFile;
var spawn = cp.spawn;

var VMADM_PATH = '/usr/sbin/vmadm';

function vmadm() {}

/*
 * execVmadm options:
 *
 *  args (required)      -- the cmdline args for vmadm [array]
 *  log (required)       -- a bunyan logger
 *  req_id (recommended) -- a req_id to pass to vmadm
 *  vmadmLogger          -- an object with a .write() method that takes a single
 *                          object as its argument. vmadm evt logs go here.
 *
 * Calls callback with
 *
 *   ({code: <code>, signal: <signal>}, stdout [string], stderr [array])
 *
 * on vmadm exit.
 *
 */
function execVmadm(opts, callback) {
    assert.object(opts, 'opts');
    assert.object(opts.log, 'opts.log');
    assert.arrayOfString(opts.args, 'opts.args');

    var args = opts.args;
    var child;
    var execOpts = {env: {}};
    var stderrBuffer = '';
    var stderrLines = [];
    var stdoutBuffer = '';

    if (opts.req_id) {
        opts.log.info('setting req_id to %s', opts.req_id);
        execOpts.env.REQ_ID = opts.req_id;
    }
    execOpts.env.VMADM_DEBUG_LEVEL = 'debug';
    if (process.env.EXPERIMENTAL_VMJS_TRACING) {
        execOpts.env.EXPERIMENTAL_VMJS_TRACING =
            process.env.EXPERIMENTAL_VMJS_TRACING;
    }

    opts.log.info({ args: args, execOpts: execOpts }, 'executing vmadm');

    child = spawn(VMADM_PATH, args, execOpts);

    child.stdout.on('data', function _childStdoutHandler(data) {
        stdoutBuffer += data.toString();
    });

    child.stderr.on('data', function _childStderrHandler(data) {
        var chunk;
        var chunks;
        var logobj;

        stderrBuffer += data.toString();
        chunks = stderrBuffer.split('\n');
        while (chunks.length > 1) {
            chunk = chunks.shift();

            // log the record to the vmadmLogger if it's an evt log.
            logobj = undefined;
            if (opts.vmadmLogger) {
                if (chunk[0] === '{' && chunk.indexOf('"evt"') !== -1) {
                    try {
                        logobj = JSON.parse(chunk);
                    } catch (e) {
                        opts.log.warn({line: chunk, err: e},
                            'failed to JSON.parse line');
                    }
                }
            }
            if (logobj) {
                opts.vmadmLogger.write(logobj);
            }

            stderrLines.push(chunk);
        }
        stderrBuffer = chunks.pop();
    });

    child.on('close', function _childCloseHandler(code, signal) {
        if (stderrBuffer.length > 0) {
            opts.log.info('stderr from vmadm: ' + stderrBuffer);
            stderrLines.push(stderrBuffer);
        }
        opts.log.info('vmadm child closed with (%d, %d)', code, signal);
        callback({code: code, signal: signal}, stdoutBuffer, stderrLines);
    });

    if (opts.stdinData) {
        child.stdin.write(opts.stdinData);
    }
    child.stdin.end();
}

/**
 * Call `vmadm lookup -j UUID`.
 *
 * @param opts {Object} Options
 *      - uuid {String} The VM uuid.
 *      - log {Logger object}
 * @param vmopts {Object} Optional vm options
 *      - fields {Array} Return only the keys give in `fields` array
 * @param callback {Function} `function (err)`
 */

vmadm.load = function vmLoad(opts, vmopts, callback) {
    assert.object(opts, 'opts');
    assert.string(opts.uuid, 'opts.uuid');

    if (!callback) {
        callback = vmopts;
    }

    function addargs(newargs) {
        Array.prototype.push.apply(args, newargs);
    }

    var args = ['lookup', '-1', '-j'];

    if (vmopts && vmopts.fields) {
        addargs(['-o', opts.fields.join(',')]);
    }

    args.push('uuid=' + opts.uuid);

    var execOpts = {
        args: args,
        log: opts.log,
        req_id: opts.req_id
    };

    opts.log.info('spawning vmadm for load');

    execVmadm(execOpts, function (result, stdout, stderr) {
        var err;
        var vm;
        var vms;

        if (result.code !== 0) {
            err = new Error('vmadm exited with code: %d signal: %d',
                result.code, result.signal);
            err.stderr = stderr;
            return callback(err);
        }

        try {
            vms = JSON.parse(stdout);
        } catch (jsonErr) {
            jsonErr.stdout = stdout;
            return callback(jsonErr);
        }

        if (vms.length) {
            vm = vms[0];
        }

        return callback(null, vm);
    });
};

/**
 * Call `vmadm create`.
 *
 * @param opts {Object} Options
 *      - log {Logger object}
 * @param callback {Function} `function (err)`
 */

vmadm.create = function vmCreate(opts, callback) {
    assert.object(opts, 'opts');
    assert.object(opts.log, 'opts.log');

    var execOpts = {};
    var log = opts.log;
    delete opts.log;

    log.info('spawning vmadm for create');

    execOpts.log = log;
    execOpts.args = ['create'];
    execOpts.req_id = opts.req_id;
    delete opts.req_id;

    if (opts.vmadmLogger) {
        execOpts.vmadmLogger = opts.vmadmLogger;
        delete opts.vmadmLogger;
    }

    execOpts.stdinData = JSON.stringify(opts);

    execVmadm(execOpts, function (result, stdout, stderr) {
        if (result.code !== 0) {
            callback(new Error(stderr.join('\n').trim()));
            return;
        }
        callback();
    });
};

/**
 * Call `vmadm delete <uuid>`.
 *
 * @param opts {Object} Options
 *      - uuid {String} UUID of VM to delete
 *      - log {Logger object}
 * @param callback {Function} `function (err)`
 */

vmadm.delete = function vmDelete(opts, callback) {
    assert.object(opts, 'opts');
    assert.string(opts.uuid, 'opts.uuid');
    assert.object(opts.log, 'opts.log');

    var args = ['delete', opts.uuid];

    var execOpts = {
        args: args,
        log: opts.log,
        req_id: opts.req_id
    };

    opts.log.info('spawning vmadm for delete');

    execVmadm(execOpts, function (result, stdout, stderr) {
        var err;

        if (result.code !== 0) {
            err = new Error('vmadm exited with code: %d signal: %d',
                result.code, result.signal);
            err.stderr = stderr;
            return callback(err);
        }
        return callback();
    });
};

/**
 * Call `vmadm update`.
 *
 * @param opts {Object} VMADM update payload
 *      - log {Logger object}
 * @param callback {Function} `function (err)`
 */

vmadm.update = function vmUpdate(opts, callback) {
    assert.object(opts, 'opts');
    assert.string(opts.uuid, 'opts.uuid');
    assert.object(opts.log, 'opts.log');

    var log = opts.log;
    delete opts.log;
    log.info('spawning vmadm for machine update');

    var vmadmproc = spawn(VMADM_PATH, ['update', opts.uuid]);
    var stderr = '';

    vmadmproc.stdin.write(JSON.stringify(opts));
    vmadmproc.stdin.end();

    vmadmproc.on('close', function (code) {
        if (code) {
            callback(new Error(stderr.trim()));
            return;
        }
        callback();
    });

    vmadmproc.stderr.on('data', function (data) {
        stderr += data.toString();
    });
};

/**
 * Call `vmadm reboot <uuid>`.
 *
 * @param opts {Object} Options
 *      - uuid {String} UUID of VM to reboot
 *      - force {Boolean} Whether to force the reboot.
 *      - log {Logger object}
 * @param callback {Function} `function (err)`
 */

vmadm.reboot = function vmReboot(opts, callback) {
    assert.object(opts, 'opts');
    assert.string(opts.uuid, 'opts.uuid');
    assert.object(opts.log, 'opts.log');

    var args = ['reboot', opts.uuid];

    if (opts.force) {
        args.push('-F');
    }

    var execopts = {
        args: args,
        log: opts.log
    };

    execVmadm(execopts, function (result, stdout, stderr) {
        var err;

        if (result.code !== 0) {
            err = new Error('vmadm exited with code: %d signal: %d',
                result.code, result.signal);
            err.stderr = stderr;
            return callback(err);
        }
        return callback();
    });
};

/**
 * Call `vmadm reprovision`.
 *
 * @param opts {Object} VMADM reprovision payload
 *      - log {Logger object}
 *      - uuid {String} uuid of vm to be reprovisioned
 * @param callback {Function} `function (err)`
 */

vmadm.reprovision = function vmReprovision(opts, callback) {
    assert.object(opts, 'opts');
    assert.string(opts.uuid, 'opts.uuid');
    assert.object(opts.log, 'opts.log');

    var log = opts.log;
    delete opts.log;
    log.info('spawning vmadm for machine update');

    var vmadmproc = spawn(VMADM_PATH, ['reprovision', opts.uuid]);
    var stderr = '';

    vmadmproc.stdin.write(JSON.stringify(opts));
    vmadmproc.stdin.end();

    vmadmproc.on('close', function (code) {
        if (code) {
            callback(new Error(stderr.trim()));
            return;
        }
        callback();
    });

    vmadmproc.stderr.on('data', function (data) {
        stderr += data.toString();
    });
};

module.exports = vmadm;
<|endoftext|>


<commit_before>// test utils
import { mount, shallow, render } from 'enzyme';
// Components
import connectPaginate from '../paginate';

describe('The Pagninate connector ', () => {
  describe('The connector with a list which uses the selected props', ()=>{
    const propsSpy = sinon.spy();
    const List = props => {
      return
{props.data.map((d,i) =>
{JSON.stringify(d)}
)}

    }
    const ConnectedPaginateList = connectPaginate()(props => <List data={[1,2,3]} />);
    const wrapper = mount(<ConnectedPaginateList onClickNext={propsSpy} />);
    it('should add four differents div', () => {
        expect(wrapper.find('[data-focus="pagination"]')).to.have.length(1)
        expect(wrapper.find('[data-focus="pagination-indicators"]')).to.have.length(1);
        expect(wrapper.find('[data-focus="pagination__actions"]')).to.have.length(1);
        expect(wrapper.find('[data-focus="list-with-pagination"]')).to.have.length(1)
    });
    it("should call the onClickNext function on the button next's click", () => {
      expect(wrapper.find("[data-focus='pagination__actions']").find('button')).to.have.length(1);
      wrapper.find("[data-focus='pagination__actions']").find('button').simulate('click');
      wrapper.find("[data-focus='pagination__actions']").find('button').simulate('click');
      expect(propsSpy).to.have.callCount(2);
      expect(propsSpy).to.have.been.calledWith(20, 0)
      expect(propsSpy).to.have.been.calledWith(30, 0)
    });

    it("should call the otherAction function on the button other action 's click and props isOtherAction", () => {
      const otherAction=sinon.spy()
      const wrapperOther = mount(<ConnectedPaginateList onClickNext={()=>{}} otherAction={otherAction} isOtherAction={true} />);
      expect(wrapperOther.find("[data-focus='pagination__actions']").find('button')).to.have.length(1);
      wrapperOther.find("[data-focus='pagination__actions']").find('button').simulate('click');
      expect(otherAction).to.have.callCount(1);
    });
  });

});
<commit_msg>fix pagination test<commit_after>// test utils
import { mount, shallow, render } from 'enzyme';
// Components
import connectPaginate from '../paginate';

describe('The Pagninate connector ', () => {
    describe('The connector with a list which uses the selected props', ()=>{
        const propsSpy = sinon.spy();
        const List = props => {
            return
{props.data.map((d,i) =>
{JSON.stringify(d)}
)}

        }
        const ConnectedPaginateList = connectPaginate()(props => <List data={[1,2,3]} />);
        const wrapper = mount(<ConnectedPaginateList onClickNext={propsSpy} />);
        it('should add four differents div', () => {
            expect(wrapper.find('[data-focus="pagination"]')).to.have.length(1)
            expect(wrapper.find('[data-focus="pagination-indicators"]')).to.have.length(1);
            expect(wrapper.find('[data-focus="pagination__actions"]')).to.have.length(1);
            expect(wrapper.find('[data-focus="list-with-pagination"]')).to.have.length(1)
        });
        it("should call the onClickNext function on the button next's click", () => {
            expect(wrapper.find("[data-focus='pagination__actions']").find('button')).to.have.length(1);
            wrapper.find("[data-focus='pagination__actions']").find('button').simulate('click');
            wrapper.find("[data-focus='pagination__actions']").find('button').simulate('click');
            expect(propsSpy).to.have.callCount(2);
            expect(propsSpy).to.have.been.calledWith(20, 0)
            expect(propsSpy).to.have.been.calledWith(30, 0)
        });

        it("should call the otherAction function on the button other action 's click and props isOtherAction", () => {
            const otherAction=sinon.spy()
            const wrapperOther = mount(<ConnectedPaginateList onClickNext={()=>{}} otherAction={otherAction} isOtherAction={true} />);
            expect(wrapperOther.find("[data-focus='pagination__actions']").find('button')).to.have.length(1);
            wrapperOther.find("[data-focus='pagination__actions']").find('button').simulate('click');
            expect(otherAction).to.have.callCount(1);
        });
    });
});
<|endoftext|>


<commit_before>const wasm = require('../src/main.rs')

/**
 * Usage:
 *
 * Available functions:
 *  - parseInput - Parses TTML input
 *  -
 */
const init = () => wasm.initialize({
  noExitRuntime: true,
}).then((module) => {
  // parse ttml using rust
  const run = module.cwrap('run_macro', 'string', [ 'string', 'string' ])

  class TTML {
    /**
     * Initialize the class
     */
    constructor () {
      // memoize any macros we receive to reference in other macros
      this.macros = {}

      // reserved token names, referenced by id
      this.tokens = {
        // me: undefined,
        // selected: undefined,
      }
    }

    /**
     * Add a token to be used in the macros (cannot be referenced unless given a name
     * @param {string} ref; The reference name to the token (e.g. "me" for @me)
     * @param {object} token; The token in Object notation
     * @return void
     */
    setStaticToken (ref, token = {}) {
      // Make sure our token is ready to be ingested by the parser
      const attrs = Object.keys(token).map((attr) => ({
        attribute: attr,
        value: token[attr],
      }))
      this.tokens[ref] = attrs
    }

    /**
     * Run the macro
     * @param {string} input
     * @return Promise<JSON|Error>
     */
    runMacro (input) {
      try {
        const rawOutput = run(input, JSON.stringify(this.tokens))
        const output = JSON.parse(rawOutput)
        if (output.error) {
          // @todo throw specialized errors
          throw new Error(output.error.message)
        }
        return output
      } catch (e) {
        throw e // bubble the error
      }
    }
  }

  return new TTML()
})

module.exports.init = init
global.window.ttml = {
  init,
}
<commit_msg>shutdown wasm, prevents memory alloc errors?<commit_after>const wasm = require('../src/main.rs')

/**
 * Usage:
 *
 * Available functions:
 *  - parseInput - Parses TTML input
 *  -
 */
const init = () => wasm.initialize({
  // noExitRuntime: true,
}).then((module) => {
  // parse ttml using rust
  const run = module.cwrap('run_macro', 'string', [ 'string', 'string' ])

  class TTML {
    /**
     * Initialize the class
     */
    constructor () {
      // memoize any macros we receive to reference in other macros
      this.macros = {}

      // reserved token names, referenced by id
      this.tokens = {
        // me: undefined,
        // selected: undefined,
      }
    }

    /**
     * Add a token to be used in the macros (cannot be referenced unless given a name
     * @param {string} ref; The reference name to the token (e.g. "me" for @me)
     * @param {object} token; The token in Object notation
     * @return void
     */
    setStaticToken (ref, token = {}) {
      // Make sure our token is ready to be ingested by the parser
      const attrs = Object.keys(token).map((attr) => ({
        attribute: attr,
        value: token[attr],
      }))
      this.tokens[ref] = attrs
    }

    /**
     * Run the macro
     * @param {string} input
     * @return Promise<JSON|Error>
     */
    runMacro (input) {
      try {
        const rawOutput = run(input, JSON.stringify(this.tokens))
        const output = JSON.parse(rawOutput)
        if (output.error) {
          // @todo throw specialized errors
          throw new Error(output.error.message)
        }
        return output
      } catch (e) {
        throw e // bubble the error
      }
    }
  }

  return new TTML()
})

module.exports.init = init
global.window.ttml = {
  init,
}
<|endoftext|>


<commit_before>//
// HL7 Parser
//
// Author:    Evan Lucas
// Filename:  index.js
// Created:   2/6/14
// Copyright: Evan Lucas 2014
//

/**
 * Module dependencies
 */
var Transform = require('stream').Transform
  , util = require('util')
  , segment = require('./segment')()

module.exports = Parser

/**
 * Constructor
 */
function Parser() {
  var opts = { objectMode: true }
  if (!(this instanceof Parser))
    return new Parser(opts)

  var self = this
  Transform.call(this, opts)

  this._messages = []
  this._current = []
}

util.inherits(Parser, Transform)

/**
 * Transform for parser
 *
 * **NOTE: The stream should have been pipe through `split()` already**
 *
 * @param {Buffer} data The segment as a buffer
 * @param {String} encoding The encoding of the buffer
 * @param {Function} cb function(err, res)
 * @api private
 */
Parser.prototype._transform = function(data, encoding, done) {
  var self = this
  var res
  try {
    res = segment.parse(data)
  }
  catch (e) {
    self.emit('error', e)
    res = null
  }
  if (res) {
    if (segment.isHeader(res)) {
      this.emit('message', this.current)
      this._messages.push(this.current)
      this.current = [res]
    } else {
      this.current.push(res)
    }
    this.push(res)
  }
  done()
}

Parser.prototype._flush = function(done) {
  var self = this
  this.emit('messages', this._messages)
}
<commit_msg>Create a new Message object for each message we parse<commit_after>//
// HL7 Parser
//
// Author:    Evan Lucas
// Filename:  index.js
// Created:   2/6/14
// Copyright: Evan Lucas 2014
//

/**
 * Module dependencies
 */
var Transform = require('stream').Transform
  , util = require('util')
  , segment = require('./segment')()
  , Message = require('./message')

module.exports = Parser

/**
 * Constructor
 */
function Parser() {
  var opts = { objectMode: true }
  if (!(this instanceof Parser))
    return new Parser(opts)

  var self = this
  Transform.call(this, opts)

  this._messages = []
  this.current = []
}

util.inherits(Parser, Transform)

/**
 * Transform for parser
 *
 * **NOTE: The stream should have been pipe through `split()` already**
 *
 * @param {Buffer} data The segment as a buffer
 * @param {String} encoding The encoding of the buffer
 * @param {Function} cb function(err, res)
 * @api private
 */
Parser.prototype._transform = function(data, encoding, done) {
  var self = this
  var res
  try {
    res = segment.parse(data)
  }
  catch (e) {
    self.emit('error', e)
    res = null
  }
  if (res) {
    if (segment.isHeader(res) && this.current.length) {
      var message = new Message(this.current)
      this.emit('message', message)
      this._messages.push(message)
      this.current = [res]
    } else {
      this.current.push(res)
    }
    this.push(res)
  }
  done()
}

Parser.prototype._flush = function(done) {
  var self = this
  if (this.current.length) {
    var message = new Message(this.current)
    this.emit('message', message)
    this._messages.push(message)
    this.current = []
  }
  this.emit('messages', this._messages)
}
<|endoftext|>


<commit_before>const fs = require('fs');
const path = require('path');
const express = require('express');
const bodyparser = require('body-parser');

const app = express();
app.use(bodyparser.urlencoded({ extende:true }));
app.use(bodyparser.json());

app.use("*", function (req, res, next) {
  res.header('Access-Control-Allow-Origin', '*');
  res.header("Access-Control-Allow-Headers", "Content-Type,Content-Length, Authorization, Accept,X-Requested-With");
  res.header("Access-Control-Allow-Methods","PUT,POST,GET,DELETE,OPTIONS");
  if (req.method === 'OPTIONS') {
    res.send(200)
  } else {
    next()
  }
});

app.get('/', (req, res) => {
  res.send(fs.readFileSync(path.resolve(__dirname, 'index.html'), 'utf-8'));
});

app.get('/dict.json', (req, res) => {
  res.send(fs.readFileSync(path.resolve(__dirname, '../dict.json'), 'utf-8'));
});

app.get('/backup', (req, res) => {
  const text = fs.readFileSync(path.resolve(__dirname, '../dict.json'), 'utf-8');
  fs.writeFileSync(path.resolve(__dirname, `../dict-${new Date().getTime()}.json`), text, 'utf-8');
  res.send({
    code: 0,
    data: 'ok',
  });
});

app.post('/', (req, res) => {
  try {
    fs.writeFileSync(path.resolve(__dirname, '../dict.json'), req.body.json, 'utf-8');
    res.send({
      code: 0,
      data: 'ok',
    });
  } catch (err) {
    res.send({
      code: 1000,
      error: err,
    });
  }
});

app.listen(2019);<commit_msg>add minserver<commit_after>const fs = require('fs');
const path = require('path');
const express = require('express');
const bodyparser = require('body-parser');

const app = express();
app.use(bodyparser.urlencoded({ extende:true }));
app.use(bodyparser.json());

// app.use("*", function (req, res, next) {
//   res.header('Access-Control-Allow-Origin', '*');
//   res.header("Access-Control-Allow-Headers", "Content-Type,Content-Length, Authorization, Accept,X-Requested-With");
//   res.header("Access-Control-Allow-Methods","PUT,POST,GET,DELETE,OPTIONS");
//   if (req.method === 'OPTIONS') {
//     res.send(200)
//   } else {
//     next()
//   }
// });

app.get('/dictadmin/', (req, res) => {
  res.send(fs.readFileSync(path.resolve(__dirname, 'index.html'), 'utf-8'));
});

app.get('/dictadmin/dict.json', (req, res) => {
  res.send(fs.readFileSync(path.resolve(__dirname, '../dict.json'), 'utf-8'));
});

app.get('/dictadmin/backup', (req, res) => {
  const text = fs.readFileSync(path.resolve(__dirname, '../dict.json'), 'utf-8');
  fs.writeFileSync(path.resolve(__dirname, `../dict-${new Date().getTime()}.json`), text, 'utf-8');
  res.send({
    code: 0,
    data: 'ok',
  });
});

app.post('/dictadmin', (req, res) => {
  try {
    fs.writeFileSync(path.resolve(__dirname, '../dict.json'), req.body.json, 'utf-8');
    res.send({
      code: 0,
      data: 'ok',
    });
  } catch (err) {
    res.send({
      code: 1000,
      error: err,
    });
  }
});

app.listen(2019);<|endoftext|>


<commit_before>var async = require('async');
var _ = require('underscore');
var path = require('path');

var config = {
    cookie:{
        secret:'ninja_face'
    },
    callback:{
        uri:'/callbacks'
    },
    settings:{
        uri:'/settings'
    },
    app_dir:path.join(__dirname, '..', '..'),
    port:3000
};
var njax_util = require('njax-util');
var njax_app = function(options){

    options = _.extend(config, options)

    var app = njax_util.app(options);
    app.njax.config.njax_dir = path.join(__dirname, '..');

    app.njax.config.njax_tpl_dir = path.join(app.njax.config.njax_dir, 'public', 'templates');
    app.locals.partials = {
        /*_header:app.njax.config.njax_tpl_dir + '/_header',
        _footer:app.njax.config.njax_tpl_dir + '/_footer'*/
    };
    require('./modules')(app);

    require('./routes')(app);

    return app;

}

module.exports = njax_app;<commit_msg>Code flying from the fingertips<commit_after>var async = require('async');
var _ = require('underscore');
var path = require('path');

var config = {
    cookie:{
        secret:'ninja_face'
    },
    callback:{
        uri:'/callbacks'
    },
    settings:{
        uri:'/settings'
    },
    app_dir:path.join(__dirname, '..', '..'),
    port:3000
};
var njax_util = require('njax-util');
var njax_app = function(options){

    options = _.extend(config, options)

    var app = njax_util.app(options);
    app.njax.config.njax_dir = path.join(__dirname, '..');

    app.njax.config.njax_tpl_dir = path.join(app.njax.config.njax_dir, 'public', 'templates');
    app.locals.partials = {};
    app.locals.partials._header = app.njax.config.njax_util_tpl_dir + '/_header';
    app.locals.partials._footer = app.njax.config.njax_util_tpl_dir + '/_footer';
    require('./modules')(app);

    require('./routes')(app);

    return app;

}

module.exports = njax_app;<|endoftext|>


<commit_before>export default (reporterName = 'verbose', tapReporter) => (input) => {
    return function ava(/* log */) {
        const API = require('ava/api');
        const Reporter = require('ava/lib/reporters/' + reporterName);

        // tap with custom reporter
        if (reporterName === 'tap' && typeof tapReporter === 'function') {
            return new Promise((resolve, reject) => {
                const api = new API(input);
                const reporter = Reporter();
                const stream = tapReporter();

                reporter.api = api;

                stream.pipe(process.stdout);

                api
                    .on('test', test => {
                        stream.write(reporter.test(test));
                    })
                    .on('error', error => {
                        console.error(reporter.unhandledError(error));
                    })
                    .run()
                    .then(() => {
                        stream.write(reporter.finish());
                        stream.end();

                        if (api.failCount > 0) {
                            return reject();
                        }

                        resolve(input);
                    })
                    .catch(error => {
                        reject(error.message);
                    });
            });
        }

        // simple
        return new Promise((resolve, reject) => {
            const api = new API(input);
            const reporter = Reporter();

            reporter.api = api;

            api
                .on('test', test => {
                    console.log(reporter.test(test));
                })
                .on('error', error => {
                    console.error(reporter.unhandledError(error));
                })
                .run()
                .then(() => {
                    console.log(reporter.finish());

                    if (api.failCount > 0) {
                        return reject();
                    }

                    resolve(input);
                })
                .catch(error => {
                    reject(error.message);
                });
        });
    };
};
<commit_msg>:heavy_check_mark: the reported need the results from run (#2)<commit_after>export default (reporterName = 'verbose', tapReporter) => (input) => {
    return function ava(/* log */) {
        const API = require('ava/api');
        const Reporter = require('ava/lib/reporters/' + reporterName);

        // tap with custom reporter
        if (reporterName === 'tap' && typeof tapReporter === 'function') {
            return new Promise((resolve, reject) => {
                const api = new API(input);
                const reporter = Reporter();
                const stream = tapReporter();

                reporter.api = api;

                stream.pipe(process.stdout);

                api
                    .on('test', test => {
                        stream.write(reporter.test(test));
                    })
                    .on('error', error => {
                        console.error(reporter.unhandledError(error));
                    })
                    .run()
                    .then((test) => {
                        stream.write(reporter.finish(test));
                        stream.end();

                        if (api.failCount > 0) {
                            return reject();
                        }

                        resolve(input);
                    })
                    .catch(error => {
                        reject(error.message);
                    });
            });
        }

        // simple
        return new Promise((resolve, reject) => {
            const api = new API(input);
            const reporter = Reporter();

            reporter.api = api;

            api
                .on('test', test => {
                    console.log(reporter.test(test));
                })
                .on('error', error => {
                    console.error(reporter.unhandledError(error));
                })
                .run()
                .then((test) => {
                    console.log(reporter.finish(test));

                    if (api.failCount > 0) {
                        return reject();
                    }

                    resolve(input);
                })
                .catch(error => {
                    reject(error.message);
                });
        });
    };
};
<|endoftext|>


<commit_before>'use strict';

let pkg = require('../package.json');
let Boom = require('boom');

function digs(server, opts, done) {
  server.route({
    method: '*',
    path: '/{p*}',
    handler: function(req, reply) {
      reply(Boom.notFound());
    }
  });

  server.select('coap').route({
    method: 'POST',
    path: '/log/{tags*}',
    handler: function(req, reply) {
      server.log(req.params.tags.split('/'), req.payload);
      reply({success: true});
    }
  });

  server.log('digs', 'Digs plugin registered successfully');

  done();
}

digs.attributes = {
  pkg: pkg,
  dependencies: [
    'good',
    'blipp'
  ]
};

digs.createServer = require('./server');

module.exports = digs;
<commit_msg>slight tweaks to plugin<commit_after>'use strict';

let pkg = require('../package.json');
let Boom = require('boom');

function digsPlugin(digs, opts, done) {
  digs.route({
    method: '*',
    path: '/{p*}',
    handler: function notFound(req, reply) {
      reply(Boom.notFound());
    }
  });

  digs.route({
    method: 'POST',
    path: '/log/{tags*}',
    handler: function log(req, reply) {
      digs.log(req.params.tags.split('/'), req.payload);
      reply({success: true});
    },
    config: {
      tags: ['digs', 'log']
    }
  });

  digs.log('digs', 'Digs plugin registered successfully');

  done();
}

digsPlugin.attributes = {
  pkg: pkg,
  dependencies: [
    'good',
    'blipp'
  ]
};

digsPlugin.createServer = require('./server');

module.exports = digsPlugin;
<|endoftext|>


<commit_before>'use strict'

var uuid = require('node-uuid')

var OrSet = module.exports = function(pairs) {
  Object.defineProperties(this, {
    _elements: { value: [] },
    _utags:    { value: Object.create(null) }
  })

  if (pairs) this.reset(pairs)
}

OrSet.prototype = Object.create({

  get size() {
    return this._elements.length
  },

  has: function(e) {
    return this._elements.indexOf(e) > -1
  },

  get: function(u) {
    if (!(u in this._utags)) {
      return undefined
    }

    return this._elements[this._utags[u]]
  },

  add: function(e, u) {
    var utag, index

    var transformed = this._transform(e)

    // downstream
    if (u) {
      utag  = u
      index = this._elements.indexOf(e)
      if (index === -1) {
        index = this._elements.push(transformed) - 1
      }
    }
    // local
    else {
      if (this.has(e)) return
      utag = uuid.v4()
      index = this._elements.push(transformed) - 1
    }

    this._utags[utag] = index

    if (typeof Object.getNotifier === 'function') {
      Object.getNotifier(this).notify({
        type: 'add', name: utag, value: transformed
      })
    }
  },

  remove: function(e, u) {
    var index, utag

    // downstream
    if (u) {
      if (!(u in this._utags)) return
      index = this._utags[u]
      delete this._utags[u]

      if (typeof Object.getNotifier === 'function') {
        Object.getNotifier(this).notify({
          type: 'delete', name: u, oldValue: this._elements[index]
        })
      }

      for (utag in this._utags) {
        if (this._utags[utag] === index) {
          return
        }
      }
    }
    // local
    else {
      // var remove = []
      for (utag in this._utags) {
        var idx = this._utags[utag]
        if (this._elements[idx] === e) {
          // remove.push({
          //   e: this._elements[index],
          //   u: utag
          // })
          delete this._utags[utag]
          index = idx

          if (typeof Object.getNotifier === 'function') {
            Object.getNotifier(this).notify({
              type: 'delete', name: utag, oldValue: e
            })
          }
        }
      }
    }

    if (index >= 0) {
      this._elements.splice(index, 1)
      for (utag in this._utags) {
        if (this._utags[utag] > index) {
          this._utags[utag]--
        }
      }
    }
  },

  reset: function(pairs) {
    // empty
    this._elements.length = 0
    for (var u in this._utags) {
      delete this._utags[u]
    }

    // add pairs, represented as follows:
    // [[e, u], [e, u], ...]
    //   e: ..., // element
    //   u: ...  // unique tag
    pairs.forEach(function(pair) {
      if (Array.isArray(pair) && pair.length === 2) {
        var length = this._elements.push(this._transform(pair[0]))
        this._utags[pair[1]] = length - 1
      } else {
        this.add(pair)
      }
    }, this)
  },

  entries: function() {
    var utags = Object.keys(this._utags)
    var self = this
    return {
      next: function() {
        var utag = utags.shift()
        return utag
          ? { value: [utag, self._elements[self._utags[utag]]], done: false }
          : { done: true }
      }
    }
  },

  values: function() {
    var utags = Object.keys(this._utags)
    var self = this
    return {
      next: function() {
        var utag = utags.shift()
        return utag
          ? { value: self._elements[self._utags[utag]], done: false }
          : { done: true }
      }
    }
  },

  _transform: function(el) {
    return el
  }

}, { constructor: { value: OrSet } })

var arrayMethods = ['forEach', 'filter', 'map', 'reduce']
arrayMethods.forEach(function(method) {
  OrSet.prototype[method] = function() {
    return Array.prototype[method].apply(this._elements, arguments)
  }
})

OrSet.typed = function(T) {
  var TypedOrSet = function(pairs) {
    OrSet.call(this, pairs)
  }

  TypedOrSet.prototype = Object.create(OrSet.prototype, {
    constructor: { value: OrSet }
  })

  TypedOrSet.prototype._transform = function(el) {
    if (el && el instanceof T) {
      return el
    } else {
      return new T(el)
    }
  }

  return TypedOrSet
}
<commit_msg>add size change notifications<commit_after>'use strict'

var uuid = require('node-uuid')

var OrSet = module.exports = function(pairs) {
  Object.defineProperties(this, {
    _elements: { value: [] },
    _utags:    { value: Object.create(null) }
  })

  if (pairs) this.reset(pairs)
}

OrSet.prototype = Object.create({

  get size() {
    return this._elements.length
  },

  has: function(e) {
    return this._elements.indexOf(e) > -1
  },

  get: function(u) {
    if (!(u in this._utags)) {
      return undefined
    }

    return this._elements[this._utags[u]]
  },

  add: function(e, u) {
    var utag, index

    var transformed = this._transform(e)

    // downstream
    if (u) {
      utag  = u
      index = this._elements.indexOf(e)
      if (index === -1) {
        index = this._elements.push(transformed) - 1
      }
    }
    // local
    else {
      if (this.has(e)) return
      utag = uuid.v4()
      index = this._elements.push(transformed) - 1
    }

    this._utags[utag] = index

    if (typeof Object.getNotifier === 'function') {
      Object.getNotifier(this).notify({
        type: 'add', name: utag, value: transformed
      })

      Object.getNotifier(this).notify({
        type: 'update', name: 'size', oldValue: this.size - 1
      })
    }
  },

  remove: function(e, u) {
    var index, utag

    // downstream
    if (u) {
      if (!(u in this._utags)) return
      index = this._utags[u]
      delete this._utags[u]

      if (typeof Object.getNotifier === 'function') {
        Object.getNotifier(this).notify({
          type: 'delete', name: u, oldValue: this._elements[index]
        })

        Object.getNotifier(this).notify({
          type: 'update', name: 'size', oldValue: this.size + 1
        })
      }

      for (utag in this._utags) {
        if (this._utags[utag] === index) {
          return
        }
      }
    }
    // local
    else {
      // var remove = []
      for (utag in this._utags) {
        var idx = this._utags[utag]
        if (this._elements[idx] === e) {
          // remove.push({
          //   e: this._elements[index],
          //   u: utag
          // })
          delete this._utags[utag]
          index = idx

          if (typeof Object.getNotifier === 'function') {
            Object.getNotifier(this).notify({
              type: 'delete', name: utag, oldValue: e
            })

            Object.getNotifier(this).notify({
              type: 'update', name: 'size', oldValue: this.size + 1
            })
          }
        }
      }
    }

    if (index >= 0) {
      this._elements.splice(index, 1)
      for (utag in this._utags) {
        if (this._utags[utag] > index) {
          this._utags[utag]--
        }
      }
    }
  },

  reset: function(pairs) {
    // empty
    this._elements.length = 0
    for (var u in this._utags) {
      delete this._utags[u]
    }

    // add pairs, represented as follows:
    // [[e, u], [e, u], ...]
    //   e: ..., // element
    //   u: ...  // unique tag
    pairs.forEach(function(pair) {
      if (Array.isArray(pair) && pair.length === 2) {
        var length = this._elements.push(this._transform(pair[0]))
        this._utags[pair[1]] = length - 1
      } else {
        this.add(pair)
      }
    }, this)
  },

  entries: function() {
    var utags = Object.keys(this._utags)
    var self = this
    return {
      next: function() {
        var utag = utags.shift()
        return utag
          ? { value: [utag, self._elements[self._utags[utag]]], done: false }
          : { done: true }
      }
    }
  },

  values: function() {
    var utags = Object.keys(this._utags)
    var self = this
    return {
      next: function() {
        var utag = utags.shift()
        return utag
          ? { value: self._elements[self._utags[utag]], done: false }
          : { done: true }
      }
    }
  },

  _transform: function(el) {
    return el
  }

}, { constructor: { value: OrSet } })

var arrayMethods = ['forEach', 'filter', 'map', 'reduce']
arrayMethods.forEach(function(method) {
  OrSet.prototype[method] = function() {
    return Array.prototype[method].apply(this._elements, arguments)
  }
})

OrSet.typed = function(T) {
  var TypedOrSet = function(pairs) {
    OrSet.call(this, pairs)
  }

  TypedOrSet.prototype = Object.create(OrSet.prototype, {
    constructor: { value: OrSet }
  })

  TypedOrSet.prototype._transform = function(el) {
    if (el && el instanceof T) {
      return el
    } else {
      return new T(el)
    }
  }

  return TypedOrSet
}
<|endoftext|>


<commit_before>/*eslint no-fallthrough: "off"*/
const callbackEvents = [ 'hide', 'show' ];

/**
 * Tablist constructor
 * @constructor
 * @param {Node} el - DOM node
 */
class Tablist{

  constructor( el ){
    if ( !el || !el.nodeName ) {
      throw new Error( 'No DOM node provided. Abort.' );
    }

    this.el = el;

    this._tablist = {};

    this._callbacks = {};

    this._handleDisplay = this._handleDisplay.bind( this );
    this._handleFocus = this._handleFocus.bind( this );
    this._handleTab = this._handleTab.bind( this );
    this._handlePanelFocus = this._handlePanelFocus.bind( this );
    this._handlePanel = this._handlePanel.bind( this );
  }

  /**
   * Retrieve first activable tab (that does not have `disabled` attribute)
   */
  _firstActiveTab() {
    let activeTab;

    for( let i = 0; i < this._tablist.tabs.length; i++ ) {
      if( !this._tablist.tabs[ i ].disabled ){
        activeTab = i;
        break;
      }
    }

    return activeTab;
  }

  /**
   * Toggle display of the tabPanel (show/hide)
   * @param {DOMEvent} e - Can be a `MouseEvent` or a `KeyboardEvent` object
   */
  _handleDisplay( e ){
    e.preventDefault();

    const tab = e.currentTarget;

    if( tab.disabled ){
      return;
    }

    // ensure the tab has the focus when a click occurs
    if( tab !== document.activeElement ){
      tab.focus();
    }

    this._toggleDisplay( this._tablist.tabs.indexOf( tab ));
  }

  /**
   * Update the current tab index before selecting the current tab
   * @param {DOMEvent} e - A `FocusEvent` object
   */
  _handleFocus( e ){
    const tab = e.currentTarget;

    if( tab.disabled ){
      return;
    }

    this._tablist.currentTabIndex = this._tablist.tabs.indexOf( tab );

    this._select( this._tablist.tabs[ this._tablist.currentTabIndex ]);
  }

  /**
   * Handle keystroke on [role=tabpanel]
   * @param {DOMEvent} e - A `KeyboardEvent` object
   */
  _handlePanel( e ){

    if ( this._tablist.currentTabIndex === undefined ) {
      this._handlePanelFocus( e );
    }

    switch( e.keyCode ){
      // ctrl + page up
      case 33:
        if( e.ctrlKey ){
          e.preventDefault();
          // focus the previous tab
          this._switchTab( this._tablist.currentTabIndex - 1 );
        }
        break;
      // ctrl + page down
      case 34:
        if( e.ctrlKey ){
          e.preventDefault();
          // focus the next tab
          this._switchTab( this._tablist.currentTabIndex + 1 );
        }
        break;

      // focus back to tab
      // ctrl + up
      case 38:
        if( e.ctrlKey ){
          e.preventDefault();
          // focus linked tab
          this._switchTab( this._tablist.currentTabIndex );
        }
        break;
    }
  }

  /**
   * Ensure that the current tab index is the one matching the tabPanel
   * @param {DOMEvent} e - A `FocusEvent` or `KeyboardEvent` object
   */
  _handlePanelFocus( e ){

    if( e.target.doubleFocus ){
      e.preventDefault();
      delete e.target.doubleFocus;

      return;
    }

    const tabPanel = e.currentTarget;

    this._tablist.currentTabIndex = this._tablist.tabPanels.indexOf( tabPanel );

    // prevent double focus event when the inputs are focused
    if([ 'radio', 'checkbox' ].indexOf( e.target.type ) >= 0 ){
      e.target.doubleFocus = true;
    }
  }

  /**
   * Handle keystroke on [role=tab]
   * @param {DOMEvent} e - A `KeyboardEvent` object
   */
  _handleTab( e ){

    if ( this._tablist.currentTabIndex === undefined ) {
      this._handleFocus( e );
    }

    switch( e.keyCode ){
      // space
      case 32:
      // return
      case 13:
        // toggle the display of the linked tabpanel
        this._handleDisplay( e );
        break;

        // end
      case 35:
        e.preventDefault();
        // focus the last tab
        this._switchTab( this._tablist.tabs.length - 1 );
        break;

        // home
      case 36:
        e.preventDefault();
        // focus the first active tab
        this._switchTab( this._firstActiveTab());
        break;

        // left
      case 37:
      // up
      case 38:
        e.preventDefault();
        // focus the previous tab
        this._switchTab( this._tablist.currentTabIndex - 1 );
        break;

        // right
      case 39:
      // down
      case 40:
        e.preventDefault();
        // focus the next tab
        this._switchTab( this._tablist.currentTabIndex + 1 );
        break;
    }
  }

  /**
   * Dummy function
   */
  _noop(){}

  /**
   * Update tab selected attributes (`aria-selected`, `tabindex`)
   * based on the `tabToSelect` attribute
   * @param {DOMElement} tabToSelect - Tab element to select
   */
  _select( tabToSelect ){
    // loop on each tab
    this._tablist.tabs.forEach(( tab, index ) => {
      const shouldSelect = tabToSelect === tab;

      tab.setAttribute( 'aria-selected', shouldSelect );
      tab.setAttribute( 'tabindex', shouldSelect ? 0 : -1 );

      // only for tab to be selected
      if ( shouldSelect ) {
        this._toggleDisplay( index );
      }
    });
  }

  /**
   * Move the focus to the tab based on the index
   * @param {number} index - Index of the element to focus
   */
  _switchTab( index ){

    // handle disabled tab
    if( this._tablist.tabs[ index ] && this._tablist.tabs[ index ].disabled ){

      // cycling forward? Then go one item farther
      const newIndex = index > this._tablist.currentTabIndex ? index + 1 : index - 1;

      this._switchTab( newIndex );

      return;
    }

    this._tablist.currentTabIndex = index;

    if( this._tablist.currentTabIndex < this._firstActiveTab()){
      this._tablist.currentTabIndex = this._tablist.tabsLength - 1;
    }
    else if( this._tablist.currentTabIndex >= this._tablist.tabsLength ){
      this._tablist.currentTabIndex = this._firstActiveTab();
    }

    this._tablist.tabs[ this._tablist.currentTabIndex ].focus();
  }

  /**
   * Toggle the `aria-hidden` attribute on the tabpanel based on the passed tab
   * @param {integer} index - index of the tab
   * @param {boolean} show - whether or not display the panel
   */
  _toggleDisplay( index, show = true ){
    if( show && index === this._tablist.openedIndex ){
      return;
    }

    const tab = this._tablist.tabs[ index ];
    const tabPanel = this._tablist.tabPanels[ index ];

    // close the previous tab
    if( show && this._tablist.openedIndex !== undefined ){
      this._toggleDisplay( this._tablist.openedIndex, false );
    }

    tabPanel.setAttribute( 'aria-hidden', !show );

    if( show ){
      this._tablist.openedIndex = index;

      if( this._tablist.openedIndex !== undefined ){
        this._trigger( 'show', [ tab, tabPanel ]);
      }
    }
    else if( this._tablist.openedIndex !== undefined ){
      this._trigger( 'hide', [ tab, tabPanel ]);
    }
  }

  _trigger( eventName, params ){
    if( !this._callbacks[ eventName ]){
      return;
    }

    this._callbacks[ eventName ].forEach( callback => {
      callback.apply( this, params );
    });
  }

  /**
   * Parse tablist element to setup the tab and tabpanel elements
   */
  mount(){
    let firstTabIndex;
    let openedTab = false;

    // create reference arrays
    this._tablist.tabs = [];
    this._tablist.tabPanels = [];

    // loop on each tab elements to find tabpanel elements and update their attributes
    Array.from( this.el.querySelectorAll( '[role=tab]' )).forEach(( tab, index ) => {
      const controls = tab.getAttribute( 'aria-controls' );
      let tabPanel;

      // get the tabpanel linked to the tab element
      if( controls ){
        tabPanel = document.getElementById( controls );
      }
      else if( tab.nextElementSibling && tab.nextElementSibling.getAttribute( 'aria-labelledby' ) === tab.id ){
        tabPanel = tab.nextElementSibling;
      }

      if( !tabPanel ){
        throw new Error( `Could not find associated tabpanel for tab ${tab.id}. Use [aria-controls="tabpanelId"] on the [role="tab"] element to link them together` );
      }

      // store the tab and the tabpanel on their respective arrays on the tablist
      this._tablist.tabs.push( tab );
      this._tablist.tabPanels.push( tabPanel );

      tab.disabled = tab.hasAttribute( 'disabled' ) || tab.getAttribute( 'aria-disabled' ) === 'true';

      // if there's no opened tab yet
      if( tab.getAttribute( 'data-open' ) === 'true' && !tab.disabled ){
        if( this._tablist.openedIndex === undefined ){
          this._toggleDisplay( index, true );

          openedTab = true;
        }
      }

      // remove setup data attributes
      tab.removeAttribute( 'data-open' );

      // get first non-disabled tab
      if( firstTabIndex === undefined && !tab.disabled ){
        firstTabIndex = index;
      }

      // set the attributes according the the openedTab status
      tab.setAttribute( 'tabindex', -1 );
      tabPanel.setAttribute( 'aria-hidden', !openedTab );

      // subscribe internal events for tab and tap panel
      tab.addEventListener( 'click', this._handleDisplay );
      tab.addEventListener( 'focus', this._handleFocus );
      tab.addEventListener( 'keydown', this._handleTab );
      tabPanel.addEventListener( 'focus', this._handlePanelFocus );
      tabPanel.addEventListener( 'keydown', this._handlePanel );
    });

    // store constants
    this._tablist.tabsLength = this._tablist.tabs.length;
    this._tablist.tabPanelsLength = this._tablist.tabPanels.length;

    // set the tabindex so the first opened tab or the first non-disabled tab can be focused on tab navigation
    if( this._tablist.openedIndex !== undefined ){
      this._tablist.tabs[ this._tablist.openedIndex ].setAttribute( 'tabindex', 0 );
    }
    // if there's no opened tab and it's not an accordion open the first tab
    else{
      this._toggleDisplay( firstTabIndex, true );

      this._tablist.tabs[ firstTabIndex ].setAttribute( 'tabindex', 0 );
    }
  }

  off( event, callback ){
    if( !this._callbacks[ event ]){
      return;
    }

    const callbackIndex = this._callbacks[ event ].indexOf( callback );

    if( callbackIndex < 0 ){
      return;
    }

    this._callbacks[ event ].splice( callbackIndex, 1 );
  }

  on( event, callback ){
    if( callbackEvents.indexOf( event ) < 0 ){
      return;
    }

    if( !this._callbacks[ event ]){
      this._callbacks[ event ] = [];
    }

    this._callbacks[ event ].push( callback );
  }

  /**
   * Returns the opened tab or array of opened tabs
   */
  get current(){
    const tab = this._tablist.tabs[ this._tablist.openedIndex ];
    const tabPanel = this._tablist.tabPanels[ this._tablist.openedIndex ];

    return {
      tab,
      tabPanel
    };
  }

  /**
   * unbind tablist
   */
  unmount(){
    this._tablist.tabs.forEach(( tab, index ) => {
      const tabPanel = this._tablist.tabPanels[ index ];

      // unsubscribe internal events for tab and tap panel
      tab.removeEventListener( 'click', this._handleDisplay );
      tab.removeEventListener( 'focus', this._handleFocus );
      tab.removeEventListener( 'keydown', this._handleTab );

      tab.removeAttribute( 'tabindex' );
      tab.removeAttribute( 'aria-selected' );

      tabPanel.removeEventListener( 'focus', this._handlePanelFocus );
      tabPanel.removeEventListener( 'keydown', this._handlePanel );
      tabPanel.setAttribute( 'aria-hidden', 'false' );
    });

    this._tablist = {};
  }
}

export default Tablist;
<commit_msg>fix focus event not firing from inside a panel<commit_after>/*eslint no-fallthrough: "off"*/
const callbackEvents = [ 'hide', 'show' ];

/**
 * Tablist constructor
 * @constructor
 * @param {Node} el - DOM node
 */
class Tablist{

  constructor( el ){
    if ( !el || !el.nodeName ) {
      throw new Error( 'No DOM node provided. Abort.' );
    }

    this.el = el;

    this._tablist = {};

    this._callbacks = {};

    this._handleDisplay = this._handleDisplay.bind( this );
    this._handleFocus = this._handleFocus.bind( this );
    this._handleTab = this._handleTab.bind( this );
    this._handlePanelFocus = this._handlePanelFocus.bind( this );
    this._handlePanel = this._handlePanel.bind( this );
  }

  /**
   * Retrieve first activable tab (that does not have `disabled` attribute)
   */
  _firstActiveTab() {
    let activeTab;

    for( let i = 0; i < this._tablist.tabs.length; i++ ) {
      if( !this._tablist.tabs[ i ].disabled ){
        activeTab = i;
        break;
      }
    }

    return activeTab;
  }

  /**
   * Toggle display of the tabPanel (show/hide)
   * @param {DOMEvent} e - Can be a `MouseEvent` or a `KeyboardEvent` object
   */
  _handleDisplay( e ){
    e.preventDefault();

    const tab = e.currentTarget;

    if( tab.disabled ){
      return;
    }

    // ensure the tab has the focus when a click occurs
    if( tab !== document.activeElement ){
      tab.focus();
    }

    this._toggleDisplay( this._tablist.tabs.indexOf( tab ));
  }

  /**
   * Update the current tab index before selecting the current tab
   * @param {DOMEvent} e - A `FocusEvent` object
   */
  _handleFocus( e ){
    const tab = e.currentTarget;

    if( tab.disabled ){
      return;
    }

    this._tablist.currentTabIndex = this._tablist.tabs.indexOf( tab );

    this._select( this._tablist.tabs[ this._tablist.currentTabIndex ]);
  }

  /**
   * Handle keystroke on [role=tabpanel]
   * @param {DOMEvent} e - A `KeyboardEvent` object
   */
  _handlePanel( e ){

    if ( this._tablist.currentTabIndex === undefined ) {
      this._handlePanelFocus( e );
    }

    switch( e.keyCode ){
      // ctrl + page up
      case 33:
        if( e.ctrlKey ){
          e.preventDefault();
          // focus the previous tab
          this._switchTab( this._tablist.currentTabIndex - 1 );
        }
        break;
      // ctrl + page down
      case 34:
        if( e.ctrlKey ){
          e.preventDefault();
          // focus the next tab
          this._switchTab( this._tablist.currentTabIndex + 1 );
        }
        break;

      // focus back to tab
      // ctrl + up
      case 38:
        if( e.ctrlKey ){
          e.preventDefault();
          // focus linked tab
          this._switchTab( this._tablist.currentTabIndex );
        }
        break;
    }
  }

  /**
   * Ensure that the current tab index is the one matching the tabPanel
   * @param {DOMEvent} e - A `FocusEvent` or `KeyboardEvent` object
   */
  _handlePanelFocus( e ){

    if( e.target.doubleFocus ){
      e.preventDefault();
      delete e.target.doubleFocus;

      return;
    }

    const tabPanel = e.currentTarget;

    this._tablist.currentTabIndex = this._tablist.tabPanels.indexOf( tabPanel );

    // prevent double focus event when the inputs are focused
    if([ 'radio', 'checkbox' ].indexOf( e.target.type ) >= 0 ){
      e.target.doubleFocus = true;
    }
  }

  /**
   * Handle keystroke on [role=tab]
   * @param {DOMEvent} e - A `KeyboardEvent` object
   */
  _handleTab( e ){

    if ( this._tablist.currentTabIndex === undefined ) {
      this._handleFocus( e );
    }

    switch( e.keyCode ){
      // space
      case 32:
      // return
      case 13:
        // toggle the display of the linked tabpanel
        this._handleDisplay( e );
        break;

        // end
      case 35:
        e.preventDefault();
        // focus the last tab
        this._switchTab( this._tablist.tabs.length - 1 );
        break;

        // home
      case 36:
        e.preventDefault();
        // focus the first active tab
        this._switchTab( this._firstActiveTab());
        break;

        // left
      case 37:
      // up
      case 38:
        e.preventDefault();
        // focus the previous tab
        this._switchTab( this._tablist.currentTabIndex - 1 );
        break;

        // right
      case 39:
      // down
      case 40:
        e.preventDefault();
        // focus the next tab
        this._switchTab( this._tablist.currentTabIndex + 1 );
        break;
    }
  }

  /**
   * Dummy function
   */
  _noop(){}

  /**
   * Update tab selected attributes (`aria-selected`, `tabindex`)
   * based on the `tabToSelect` attribute
   * @param {DOMElement} tabToSelect - Tab element to select
   */
  _select( tabToSelect ){
    // loop on each tab
    this._tablist.tabs.forEach(( tab, index ) => {
      const shouldSelect = tabToSelect === tab;

      tab.setAttribute( 'aria-selected', shouldSelect );
      tab.setAttribute( 'tabindex', shouldSelect ? 0 : -1 );

      // only for tab to be selected
      if ( shouldSelect ) {
        this._toggleDisplay( index );
      }
    });
  }

  /**
   * Move the focus to the tab based on the index
   * @param {number} index - Index of the element to focus
   */
  _switchTab( index ){

    // handle disabled tab
    if( this._tablist.tabs[ index ] && this._tablist.tabs[ index ].disabled ){

      // cycling forward? Then go one item farther
      const newIndex = index > this._tablist.currentTabIndex ? index + 1 : index - 1;

      this._switchTab( newIndex );

      return;
    }

    this._tablist.currentTabIndex = index;

    if( this._tablist.currentTabIndex < this._firstActiveTab()){
      this._tablist.currentTabIndex = this._tablist.tabsLength - 1;
    }
    else if( this._tablist.currentTabIndex >= this._tablist.tabsLength ){
      this._tablist.currentTabIndex = this._firstActiveTab();
    }

    this._tablist.tabs[ this._tablist.currentTabIndex ].focus();
  }

  /**
   * Toggle the `aria-hidden` attribute on the tabpanel based on the passed tab
   * @param {integer} index - index of the tab
   * @param {boolean} show - whether or not display the panel
   */
  _toggleDisplay( index, show = true ){
    if( show && index === this._tablist.openedIndex ){
      return;
    }

    const tab = this._tablist.tabs[ index ];
    const tabPanel = this._tablist.tabPanels[ index ];

    // close the previous tab
    if( show && this._tablist.openedIndex !== undefined ){
      this._toggleDisplay( this._tablist.openedIndex, false );
    }

    tabPanel.setAttribute( 'aria-hidden', !show );

    if( show ){
      this._tablist.openedIndex = index;

      if( this._tablist.openedIndex !== undefined ){
        this._trigger( 'show', [ tab, tabPanel ]);
      }
    }
    else if( this._tablist.openedIndex !== undefined ){
      this._trigger( 'hide', [ tab, tabPanel ]);
    }
  }

  _trigger( eventName, params ){
    if( !this._callbacks[ eventName ]){
      return;
    }

    this._callbacks[ eventName ].forEach( callback => {
      callback.apply( this, params );
    });
  }

  /**
   * Parse tablist element to setup the tab and tabpanel elements
   */
  mount(){
    let firstTabIndex;
    let openedTab = false;

    // create reference arrays
    this._tablist.tabs = [];
    this._tablist.tabPanels = [];

    // loop on each tab elements to find tabpanel elements and update their attributes
    Array.from( this.el.querySelectorAll( '[role=tab]' )).forEach(( tab, index ) => {
      const controls = tab.getAttribute( 'aria-controls' );
      let tabPanel;

      // get the tabpanel linked to the tab element
      if( controls ){
        tabPanel = document.getElementById( controls );
      }
      else if( tab.nextElementSibling && tab.nextElementSibling.getAttribute( 'aria-labelledby' ) === tab.id ){
        tabPanel = tab.nextElementSibling;
      }

      if( !tabPanel ){
        throw new Error( `Could not find associated tabpanel for tab ${tab.id}. Use [aria-controls="tabpanelId"] on the [role="tab"] element to link them together` );
      }

      // store the tab and the tabpanel on their respective arrays on the tablist
      this._tablist.tabs.push( tab );
      this._tablist.tabPanels.push( tabPanel );

      tab.disabled = tab.hasAttribute( 'disabled' ) || tab.getAttribute( 'aria-disabled' ) === 'true';

      // if there's no opened tab yet
      if( tab.getAttribute( 'data-open' ) === 'true' && !tab.disabled ){
        if( this._tablist.openedIndex === undefined ){
          this._toggleDisplay( index, true );

          openedTab = true;
        }
      }

      // remove setup data attributes
      tab.removeAttribute( 'data-open' );

      // get first non-disabled tab
      if( firstTabIndex === undefined && !tab.disabled ){
        firstTabIndex = index;
      }

      // set the attributes according the the openedTab status
      tab.setAttribute( 'tabindex', -1 );
      tabPanel.setAttribute( 'aria-hidden', !openedTab );

      // subscribe internal events for tab and tap panel
      tab.addEventListener( 'click', this._handleDisplay );
      tab.addEventListener( 'focus', this._handleFocus );
      tab.addEventListener( 'keydown', this._handleTab );
      tabPanel.addEventListener( 'focus', this._handlePanelFocus, true );
      tabPanel.addEventListener( 'keydown', this._handlePanel );
    });

    // store constants
    this._tablist.tabsLength = this._tablist.tabs.length;
    this._tablist.tabPanelsLength = this._tablist.tabPanels.length;

    // set the tabindex so the first opened tab or the first non-disabled tab can be focused on tab navigation
    if( this._tablist.openedIndex !== undefined ){
      this._tablist.tabs[ this._tablist.openedIndex ].setAttribute( 'tabindex', 0 );
    }
    // if there's no opened tab and it's not an accordion open the first tab
    else{
      this._toggleDisplay( firstTabIndex, true );

      this._tablist.tabs[ firstTabIndex ].setAttribute( 'tabindex', 0 );
    }
  }

  off( event, callback ){
    if( !this._callbacks[ event ]){
      return;
    }

    const callbackIndex = this._callbacks[ event ].indexOf( callback );

    if( callbackIndex < 0 ){
      return;
    }

    this._callbacks[ event ].splice( callbackIndex, 1 );
  }

  on( event, callback ){
    if( callbackEvents.indexOf( event ) < 0 ){
      return;
    }

    if( !this._callbacks[ event ]){
      this._callbacks[ event ] = [];
    }

    this._callbacks[ event ].push( callback );
  }

  /**
   * Returns the opened tab or array of opened tabs
   */
  get current(){
    const tab = this._tablist.tabs[ this._tablist.openedIndex ];
    const tabPanel = this._tablist.tabPanels[ this._tablist.openedIndex ];

    return {
      tab,
      tabPanel
    };
  }

  /**
   * unbind tablist
   */
  unmount(){
    this._tablist.tabs.forEach(( tab, index ) => {
      const tabPanel = this._tablist.tabPanels[ index ];

      // unsubscribe internal events for tab and tap panel
      tab.removeEventListener( 'click', this._handleDisplay );
      tab.removeEventListener( 'focus', this._handleFocus );
      tab.removeEventListener( 'keydown', this._handleTab );

      tab.removeAttribute( 'tabindex' );
      tab.removeAttribute( 'aria-selected' );

      tabPanel.removeEventListener( 'focus', this._handlePanelFocus, true );
      tabPanel.removeEventListener( 'keydown', this._handlePanel );
      tabPanel.setAttribute( 'aria-hidden', 'false' );
    });

    this._tablist = {};
  }
}

export default Tablist;
<|endoftext|>


<commit_before>var  _ 		= require('underscore')
	,https 	= require('https');
exports = module.exports = LSQ;

	function LSQ(host,token,options){
		this.host  = host;
		this.token  = token;
		this.options = _.isObject(options) ? options : {};
		this.options = _.defaults(this.options,{"apiVersion":"v1"});
		return this;
	}

	LSQ.prototype.create = function(collection,data,options,callback){
		if(_.isFunction(options)){
		callback = options;
		}
		else if(!_.isObject(options)){
			options = {};
		}
		if(_.isFunction(data)){
			callback = data;
			data = {};
		}

		if(!_.isString(collection) && collection.length < 1){
			callback("error no collection",{})
			return;
		}
		data = {model:data};
		data.key = collection;

		this.apiCall("create",data,options,callback)

	}

	LSQ.prototype.read = function(collection,data,options,callback){

		if(_.isFunction(options)){
		callback = options;
		}
		else if(!_.isObject(options)){
			options = {};
		}
		if(_.isFunction(data)){
			callback = data;
			data = {};
		}
		if(_.isString(data)){
			data = {id:data}
		}else{
			data = {query:data}
		}

		if(!_.isString(collection) && collection.length < 1){
			callback("error no collection",{})
			return;
		}
		data.key = collection;
		this.apiCall("read",data,callback)

	}
	LSQ.prototype.update = function(collection,data,model,options,callback){

		if(_.isFunction(options)){
		callback = options;
		}
		else if(!_.isObject(options)){
			options = {};
		}

		if(_.isFunction(model) || _.isString(model)){
			callback("error no data",{})
			return;
		}

		if(!_.isString(collection) && collection.length < 1){
			callback("error no collection",{})
			return;
		}
		if(_.isString(data)){
			data = {id:data}
		}else{
			data = {query:data}
		}
		data.model = model;
		data.key = collection;
		this.apiCall("update",data,callback)

	}
	LSQ.prototype.delete = function(collection,data,options,callback){

		if(_.isFunction(options)){
		callback = options;
		}
		else if(!_.isObject(options)){
			options = {};
		}
		if(_.isFunction(data)){
			callback = data;
			data = {};
		}

		if(_.isString(data)){
			data = {id:data}
		}else{
			data = {query:data}
		}

		if(!_.isString(collection) && collection.length < 1){
			callback("error no collection",{})
			return;
		}
		data.key = collection;
		this.apiCall("delete",data,callback)

	}

	LSQ.prototype.apiCall = function(method,data,options,callback){
	var self = this;
	var  op 		= {}
		,result 	= ""
		,error 		= null
		,body 		= {token:this.token}
		,key
		,req;

	if(_.isFunction(options)){
		callback = options;
	}
	else if(!_.isObject(options)){
		options = {};
	}
	if(_.isFunction(data)){
		callback = data;
		data = {};
	}

	if(!_.isFunction(callback))
		callback = function(){};

		op.host 		= this.host;
		op.port 		= 443;
		op.method 		= "POST";
		op.path 		= "/api/"+self.apiVersion+"/"+data.key;
		body.model 		= _.isObject(data.model) ? data.model : {};
		body.query 		= _.isObject(data.query) ? data.query : {};
		if(_.isString(data.id))
			body.id = data.id;

		if(_.has(this.options,"user")&&_.has(this.options,"pass"))
			op.auth = this.options.user +":"+this.options.pass;

	switch(method){
		case "create":
			body.request= "create";

			if(_.isEmpty(body.model)){
				callback("model is empty",{});
				return;
			}
		break;
		case "update":
			body.request= "update";

		break;
		case "delete":
			body.request= "delete";

		break;
		default:
			body.request= "read";

		break;
	}

	var d = new Buffer(JSON.stringify({data:body}));
	op.headers ={'Content-Length': d.length,'Content-Type': 'application/json'};

	req = https.request(op, function(res) {
		res.setEncoding('utf8');
		res.on('data', function (chunk) {
			result +=chunk;
		});
  		res.on("end",function(){
  			callback(error,result);
		})
	});
	req.on('error', function(e) {
		callback(e.message,e,result);
	});
	for(var i = 0; i < d.length; i+=500){
		var end = i+500 > d.length ? d.length: i+500 ;
		req.write(d.slice(i,end).toString(),'utf8')
	}
	req.end();

}
<commit_msg>Add apivision correctly<commit_after>var  _ 		= require('underscore')
	,https 	= require('https');
exports = module.exports = LSQ;

	function LSQ(host,token,options){
		this.host  = host;
		this.token  = token;
		this.options = _.isObject(options) ? options : {};
		this.options = _.defaults(this.options,{"apiVersion":"v1"});
		return this;
	}

	LSQ.prototype.create = function(collection,data,options,callback){
		if(_.isFunction(options)){
		callback = options;
		}
		else if(!_.isObject(options)){
			options = {};
		}
		if(_.isFunction(data)){
			callback = data;
			data = {};
		}

		if(!_.isString(collection) && collection.length < 1){
			callback("error no collection",{})
			return;
		}
		data = {model:data};
		data.key = collection;

		this.apiCall("create",data,options,callback)

	}

	LSQ.prototype.read = function(collection,data,options,callback){

		if(_.isFunction(options)){
		callback = options;
		}
		else if(!_.isObject(options)){
			options = {};
		}
		if(_.isFunction(data)){
			callback = data;
			data = {};
		}
		if(_.isString(data)){
			data = {id:data}
		}else{
			data = {query:data}
		}

		if(!_.isString(collection) && collection.length < 1){
			callback("error no collection",{})
			return;
		}
		data.key = collection;
		this.apiCall("read",data,callback)

	}
	LSQ.prototype.update = function(collection,data,model,options,callback){

		if(_.isFunction(options)){
		callback = options;
		}
		else if(!_.isObject(options)){
			options = {};
		}

		if(_.isFunction(model) || _.isString(model)){
			callback("error no data",{})
			return;
		}

		if(!_.isString(collection) && collection.length < 1){
			callback("error no collection",{})
			return;
		}
		if(_.isString(data)){
			data = {id:data}
		}else{
			data = {query:data}
		}
		data.model = model;
		data.key = collection;
		this.apiCall("update",data,callback)

	}
	LSQ.prototype.delete = function(collection,data,options,callback){

		if(_.isFunction(options)){
		callback = options;
		}
		else if(!_.isObject(options)){
			options = {};
		}
		if(_.isFunction(data)){
			callback = data;
			data = {};
		}

		if(_.isString(data)){
			data = {id:data}
		}else{
			data = {query:data}
		}

		if(!_.isString(collection) && collection.length < 1){
			callback("error no collection",{})
			return;
		}
		data.key = collection;
		this.apiCall("delete",data,callback)

	}

	LSQ.prototype.apiCall = function(method,data,options,callback){
	var self = this;
	var  op 		= {}
		,result 	= ""
		,error 		= null
		,body 		= {token:this.token}
		,key
		,req;

	if(_.isFunction(options)){
		callback = options;
	}
	else if(!_.isObject(options)){
		options = {};
	}
	if(_.isFunction(data)){
		callback = data;
		data = {};
	}

	if(!_.isFunction(callback))
		callback = function(){};

		op.host 		= this.host;
		op.port 		= 443;
		op.method 		= "POST";
		op.path 		= "/api/"+self.options.apiVersion+"/"+data.key;
		body.model 		= _.isObject(data.model) ? data.model : {};
		body.query 		= _.isObject(data.query) ? data.query : {};
		if(_.isString(data.id))
			body.id = data.id;

		if(_.has(this.options,"user")&&_.has(this.options,"pass"))
			op.auth = this.options.user +":"+this.options.pass;

	switch(method){
		case "create":
			body.request= "create";

			if(_.isEmpty(body.model)){
				callback("model is empty",{});
				return;
			}
		break;
		case "update":
			body.request= "update";

		break;
		case "delete":
			body.request= "delete";

		break;
		default:
			body.request= "read";

		break;
	}

	var d = new Buffer(JSON.stringify({data:body}));
	op.headers ={'Content-Length': d.length,'Content-Type': 'application/json'};

	req = https.request(op, function(res) {
		res.setEncoding('utf8');
		res.on('data', function (chunk) {
			result +=chunk;
		});
  		res.on("end",function(){
  			callback(error,result);
		})
	});
	req.on('error', function(e) {
		callback(e.message,e,result);
	});
	for(var i = 0; i < d.length; i+=500){
		var end = i+500 > d.length ? d.length: i+500 ;
		req.write(d.slice(i,end).toString(),'utf8')
	}
	req.end();

}
<|endoftext|>


<commit_before>var ipc = require('node-ipc');
var router = require('../../../lib/router.js');
var runner = require('../../../lib/jobs-runner.js');
var expect = require('chai').expect;
var spawn = require('child_process').spawn;
var fs = require('fs');
var path = require('path');
var zipper = require('zip-local');
var rmrf = require('rimraf');

// FAKE: ipc socket server
ipc.config.silent = true;
ipc.config.id = 'FAKE';
ipc.config.retry = 1500;

describe('Beacon\'s Jobs Runner', function() {

    before(function(done) {
        ipc.serve(function(){
            ipc.server.on('message', function(msg) {});
        });
        ipc.server.start();

        rmrf('.unpacks', function(err) {
            done();
        });
    });

    after(function() {
        ipc.server.stop();
    });

    it('runs a job locally and mediates communication between processes', function(done) {
        var fake_parent = spawn('node', ['./tests/fixtures/beacon/router-ipc-client.js']);
        var fake_parent_stdout = "";
        fake_parent.stdout.on('data', function(chunck) { fake_parent_stdout += chunck.toString().trim(); });
        var fake_parent_exit = new Promise(function(resolve, reject) {
            fake_parent.on('exit', function(){resolve();});
        });

        // wait for a message from the fake client announcing its ipc socket
        ipc.server.on('SOCKET:PUB', function(data, socket) {
            // set the meta table and monitor_socket
            router.setMetaTable(router.buildPureLocalTable(2));
            router.setMonitorSocket(socket);

            var fake_instance = spawn('node', ['./tests/fixtures/beacon/router-local-process.js'], {stdio: [null, null, null, 'ipc']});
            var fake_instance_stdout = "";
            fake_instance.stdout.on('data', function(chunck) { fake_instance_stdout += chunck.toString().trim(); });
            var fake_instance_exit = new Promise(function(resolve, reject) {
                fake_instance.on('exit', function(){resolve();});
            });
            router.setLocalChannel(0, fake_instance);

            var job = {size: 2, startId: 1, app: './tests/fixtures/beacon/runner-fake-job.js'};

            runner.runLocally(job);

            Promise.all([fake_parent_exit, fake_instance_exit]).then(function() {
                expect(fake_parent_stdout).to.equal("Hello from Fake");
                expect(fake_instance_stdout).to.equal("Fake Hello");
                done();
            });
        });
    });

    it('packs an app correctly', function() {
        var descriptor = runner.pack({app: './tests/fixtures/beacon/fake_app/main.js'});

        expect(descriptor.entry).to.equal('main.js');

        var packg = zipper.sync.unzip(new Buffer(descriptor.data, "base64")).memory();
        var packg_contents = packg.contents();

        expect(packg_contents.length).to.equal(3);
        expect(packg_contents).to.include('main.js');
        expect(packg.read('main.js', 'text').trim()).to.equal("var klyng = require('klyng');");
        expect(packg_contents).to.include('_modules/_fiber.js');
        expect(packg.read('_modules/_fiber.js', 'text').trim()).to.equal('Fiber!');
        expect(packg_contents).to.include('_modules/_klyng.js');
        expect(packg.read('_modules/_klyng.js', 'text').trim()).to.equal('Klyng!');
    });

    it('unpacks an app correctly', function(done) {
        runner.unpack({
            entry: "main.js",
            data: fs.readFileSync("./tests/fixtures/beacon/fake_app.zip", {encoding: "base64"})
        })
        .then(function(app) {
            var parsed = path.parse(app);
            expect(parsed.base).to.equal("main.js");
            expect(fs.readFileSync(app, {encoding: "utf8"}).trim()).to.equal("var klyng = require('klyng');");
            expect(fs.readFileSync(parsed.dir + "/_modules/_fiber.js", {encoding: "utf8"}).trim()).to.equal('Fiber!');
            expect(fs.readFileSync(parsed.dir + "/_modules/_klyng.js", {encoding: "utf8"}).trim()).to.equal('Klyng!');
            done();
        })
        .catch(done);
    });

    it('divides a job over given hosts correctly (perfect dist, no infinity host)', function() {
        // perfect dist means that job.size <= sum of hosts max processes
        var fake_job = {
            hosts: {
                "local": 2,
                "192.168.0.100@2222:": 5,
                "192.168.0.58@2222:": 4
            },
            size: 11
        };

        var plan = runner.divide(fake_job);
        expect(plan.local).to.exist;
        expect(plan.local.count).to.equal(2);
        expect(plan.local.start).to.equal(0);
        expect(plan["192.168.0.100@2222"]).to.exist;
        expect(plan["192.168.0.100@2222"].start).to.equal(2);
        expect(plan["192.168.0.100@2222"].count).to.equal(5);
        expect(plan["192.168.0.58@2222"]).to.exist;
        expect(plan["192.168.0.58@2222"].start).to.equal(7);
        expect(plan["192.168.0.58@2222"].count).to.equal(4);
    });

    it('divides a job over given hosts correctly (perfect dist, infinity host)', function() {
        var fake_job = {
            hosts: {
                "local": 2,
                "192.168.0.100@2222:": 1,
                "192.168.0.58@2222:": Infinity
            },
            size: 11
        };

        var plan = runner.divide(fake_job);
        expect(plan.local.count).to.equal(2);
        expect(plan["192.168.0.100@2222"].count).to.equal(1);
        expect(plan["192.168.0.58@2222"].count).to.equal(8);
    });

    it('divides a job over given hosts correctly (overallocation)', function() {
        var fake_job = {
            hosts: {
                "local": 2,
                "192.168.0.100@2222:": 1,
                "192.168.0.58@2222:": 3
            },
            size: 9
        };

        var plan = runner.divide(fake_job);
        expect(plan.local.count).to.equal(3);
        expect(plan["192.168.0.100@2222"].count).to.equal(2);
        expect(plan["192.168.0.58@2222"].count).to.equal(4);
    });

});
<commit_msg>updated tests to reflect changes in 3bad8cb<commit_after>var ipc = require('node-ipc');
var router = require('../../../lib/router.js');
var runner = require('../../../lib/jobs-runner.js');
var expect = require('chai').expect;
var spawn = require('child_process').spawn;
var fs = require('fs');
var path = require('path');
var zipper = require('zip-local');
var rmrf = require('rimraf');

// FAKE: ipc socket server
ipc.config.silent = true;
ipc.config.id = 'FAKE';
ipc.config.retry = 1500;

describe('Beacon\'s Jobs Runner', function() {

    before(function(done) {
        ipc.serve(function(){
            ipc.server.on('message', function(msg) {});
        });
        ipc.server.start();

        rmrf('.unpacks', function(err) {
            done();
        });
    });

    after(function() {
        ipc.server.stop();
    });

    it('runs a job locally and mediates communication between processes', function(done) {
        var fake_parent = spawn('node', ['./tests/fixtures/beacon/router-ipc-client.js']);
        var fake_parent_stdout = "";
        fake_parent.stdout.on('data', function(chunck) { fake_parent_stdout += chunck.toString().trim(); });
        var fake_parent_exit = new Promise(function(resolve, reject) {
            fake_parent.on('exit', function(){resolve();});
        });

        // wait for a message from the fake client announcing its ipc socket
        ipc.server.on('SOCKET:PUB', function(data, socket) {
            // set the meta table and monitor_socket
            router.setMetaTable(router.buildPureLocalTable(2));
            router.setMonitorSocket(socket);

            var fake_instance = spawn('node', ['./tests/fixtures/beacon/router-local-process.js'], {stdio: [null, null, null, 'ipc']});
            var fake_instance_stdout = "";
            fake_instance.stdout.on('data', function(chunck) { fake_instance_stdout += chunck.toString().trim(); });
            var fake_instance_exit = new Promise(function(resolve, reject) {
                fake_instance.on('exit', function(){resolve();});
            });
            router.setLocalChannel(0, fake_instance);

            var job = {size: 2, startId: 1, app: './tests/fixtures/beacon/runner-fake-job.js'};

            runner.runLocally(job);

            Promise.all([fake_parent_exit, fake_instance_exit]).then(function() {
                expect(fake_parent_stdout).to.equal("Hello from Fake");
                expect(fake_instance_stdout).to.equal("Fake Hello");
                done();
            });
        });
    });

    it('packs an app correctly', function() {
        var descriptor = runner.pack({app: './tests/fixtures/beacon/fake_app/main.js'});

        expect(descriptor.entry).to.equal('main.js');

        var packg = zipper.sync.unzip(new Buffer(descriptor.data, "base64")).memory();
        var packg_contents = packg.contents();

        expect(packg_contents.length).to.equal(3);
        expect(packg_contents).to.include('main.js');
        expect(packg.read('main.js', 'text').trim()).to.equal("var klyng = require('klyng');");
        expect(packg_contents).to.include('_modules/_fiber.js');
        expect(packg.read('_modules/_fiber.js', 'text').trim()).to.equal('Fiber!');
        expect(packg_contents).to.include('_modules/_klyng.js');
        expect(packg.read('_modules/_klyng.js', 'text').trim()).to.equal('Klyng!');
    });

    it('unpacks an app correctly', function(done) {
        runner.unpack({
            entry: "main.js",
            data: fs.readFileSync("./tests/fixtures/beacon/fake_app.zip", {encoding: "base64"})
        })
        .then(function(app) {
            var parsed = path.parse(app);
            expect(parsed.base).to.equal("main.js");
            expect(fs.readFileSync(app, {encoding: "utf8"}).trim()).to.equal("var klyng = require('klyng');");
            expect(fs.readFileSync(parsed.dir + "/_modules/_fiber.js", {encoding: "utf8"}).trim()).to.equal('Fiber!');
            expect(fs.readFileSync(parsed.dir + "/_modules/_klyng.js", {encoding: "utf8"}).trim()).to.equal('Klyng!');
            done();
        })
        .catch(done);
    });

    it('divides a job over given hosts correctly (perfect dist, no infinity host)', function() {
        // perfect dist means that job.size <= sum of hosts max processes
        var fake_job = {
            hosts: {
                "local": {max_procs: 2},
                "192.168.0.100:2222": {max_procs: 5, password: ""},
                "192.168.0.58:2222": {max_procs: 4, password: ""}
            },
            size: 11
        };

        var plan = runner.divide(fake_job);
        expect(plan.local).to.exist;
        expect(plan.local.count).to.equal(2);
        expect(plan.local.start).to.equal(0);
        expect(plan["192.168.0.100:2222"]).to.exist;
        expect(plan["192.168.0.100:2222"].start).to.equal(2);
        expect(plan["192.168.0.100:2222"].count).to.equal(5);
        expect(plan["192.168.0.58:2222"]).to.exist;
        expect(plan["192.168.0.58:2222"].start).to.equal(7);
        expect(plan["192.168.0.58:2222"].count).to.equal(4);
    });

    it('divides a job over given hosts correctly (perfect dist, infinity host)', function() {
        var fake_job = {
            hosts: {
                "local": {max_procs: 2},
                "192.168.0.100:2222": {max_procs: 1, password: ""},
                "192.168.0.58:2222": {max_procs: Infinity, password: ""}
            },
            size: 11
        };

        var plan = runner.divide(fake_job);
        expect(plan.local.count).to.equal(2);
        expect(plan["192.168.0.100:2222"].count).to.equal(1);
        expect(plan["192.168.0.58:2222"].count).to.equal(8);
    });

    it('divides a job over given hosts correctly (overallocation)', function() {
        var fake_job = {
            hosts: {
                "local": {max_procs: 2},
                "192.168.0.100:2222": {max_procs: 1, password: ""},
                "192.168.0.58:2222": {max_procs: 3, password: ""}
            },
            size: 9
        };

        var plan = runner.divide(fake_job);
        expect(plan.local.count).to.equal(3);
        expect(plan["192.168.0.100:2222"].count).to.equal(2);
        expect(plan["192.168.0.58:2222"].count).to.equal(4);
    });

});
<|endoftext|>


<commit_before>require.config({
    baseUrl: "../",
    paths: {
        'chai': '../../../../node_modules/chai/chai',
        'domReady': '../../../../vendor/requirejs-domready/domReady',
        'text': '../../../../vendor/requirejs-text/text',
        'jquery': '../../../../vendor/jquery/dist/jquery',
        'underscore': '../../../../vendor/underscore/underscore',
        'backbone': '../../../../vendor/backbone/backbone',
        'modernizr': '../../../../vendor/modernizr/modernizr',
        'detectizr': '../../../../vendor/detectizr/dist/detectizr',
        'spin': '../../../../vendor/spin.js/spin',
    }
});

require([
    'test/app'
], function() {
    if (typeof mochaPhantomJS !== "undefined") { mochaPhantomJS.run(); }
    else { mocha.run(); }
});<commit_msg>Add js test<commit_after><|endoftext|>