<commit_before>#!/usr/bin/env node
/* vim: set expandtab tabstop=4 shiftwidth=4 softtabstop=4 fileencoding=utf-8 : */
/*
 *     Copyright 2013 James Burlingame
 *
 *     Licensed under the Apache License, Version 2.0 (the "License");
 *     you may not use this file except in compliance with the License.
 *     You may obtain a copy of the License at
 *
 *         http://www.apache.org/licenses/LICENSE-2.0
 *
 *     Unless required by applicable law or agreed to in writing, software
 *     distributed under the License is distributed on an "AS IS" BASIS,
 *     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 *     See the License for the specific language governing permissions and
 *     limitations under the License.
 *
 */

// enable JavaScript strict mode.
"use strict";

var fs = require("fs");
var http = require("http");
var path = require("path");
var url = require("url");
var util = require("util");
var agentdb = require("./lib/samplx-agentdb.js");
var HashTable = require("./lib/hash.js").HashTable;

// enable debug messages
var debug = false;

/** host to get JSON data. */
var host = 'alscan.info.test';

/** size of the hash table. can use test/tune-hash.js to compute. */
var HASH_TABLE_SIZE = 4339;

/**
 *  Download JSON object from a remote URL.
 *
 *  @param path to request.
 *  @param done callback.
 */
function getJSON(jsonUrl, done) {
    var parsedUrl = url.parse(jsonUrl);

    var options = {
        "host" : parsedUrl.hostname,
        "hostname": parsedUrl.hostname,
        "port" : parsedUrl.port || 80,
        "path" : parsedUrl.pathname,
        "method" : "GET",
        // "agent" : false,
    };

    debug && console.error("prepublish:getJSON('" + jsonUrl + "', done)");
    debug && console.error("options=" + util.inspect(options));
    var req = http.get(options, function (res) {
        debug && console.error("STATUS: " + res.statusCode);
        debug && console.error("HEADERS: " + JSON.stringify(res.headers));
        res.setEncoding('utf8');
        var data = '';
        res.on('data', function (chunk) {
            debug && console.error('getJSON: chunk="' + chunk + '"');
            data += chunk;
        });
        res.on('end', function() {
            debug && console.error('getJSON: end of request.');
            done(JSON.parse(data));
        });
    });

    req.on('error', function(error) {
        console.error("ERROR: " + error.message);
    });
}

/**
 *  Main entry point for prepublish script.
 */
function main() {

    var database = fs.createWriteStream('./lib/database-min.js', { flags: 'w', encoding: 'utf8' });
    var testFile;

    database.write("// Do not edit this file, your changes will be lost.\n");
    database.write("module.exports = { \n");
    getJSON('http://alscan.info.test/agent_groups/groups.json', function (groups) {
        var s = JSON.stringify(groups);
        database.write("groups:" + s + ",\n");
        testFile = fs.createWriteStream('./test/groups.json', { flags: 'w', encoding: 'utf8' });
        testFile.write(s+"\n");
        testFile.end();
        getJSON('http://alscan.info.test/agent_sources/sources.json', function (sources) {
            var s = JSON.stringify(sources);
            database.write("sources:" + s + ",\n");
            testFile = fs.createWriteStream('./test/sources.json', { flags: 'w', encoding: 'utf8' });
            testFile.write(s+"\n");
            testFile.end();
            getJSON('http://alscan.info.test/patterns/patterns.json', function (patterns) {
                database.write("patterns:[\n");
                patterns.forEach(function (pattern) {
                    database.write("{p: new RegExp('" + pattern.pattern + "'), x:" +
                            agentdb.getX(pattern.groupId, pattern.sourceId) + "},");
                });
                database.write("],\n");
                testFile = fs.createWriteStream('./test/patterns.json', { flags: 'w', encoding: 'utf8' });
                testFile.write(JSON.stringify(patterns)+"\n");
                testFile.end();
                getJSON('http://alscan.info.test/agents/agents.json', function (agents) {
                    var hash = new HashTable(HASH_TABLE_SIZE);
                    agents.forEach(function (agent) {
                        if (agent.status < 2) {
                            var obj = { a: agent.agent, x: agentdb.getX(agent.groupId, agent.sourceId) };
                            hash.add('a', obj);
                        }
                    });
                    database.write("table:" + JSON.stringify(hash.table) + ",\n");
                    database.write("HASH_TABLE_SIZE:" + HASH_TABLE_SIZE + ",\n");
                    database.write("hash: undefined\n}\n");
                    testFile = fs.createWriteStream('./test/agents.json', { flags: 'w', encoding: 'utf8' });
                    testFile.write(JSON.stringify(agents)+"\n");
                    testFile.end();
                    if (debug) {
                        var history = hash.getHistory();
                        console.log("Hash table history");
                        for (var n=0; n < history.length; n++) {
                            console.log("  Depth=" + n + ", count=" + history[n] + ", percent=" + (history[n] / HASH_TABLE_SIZE));
                        }
                    }
                });
            });
        });
    });
}

main();

<commit_msg>Use live alscan.info for database source.<commit_after>#!/usr/bin/env node
/* vim: set expandtab tabstop=4 shiftwidth=4 softtabstop=4 fileencoding=utf-8 : */
/*
 *     Copyright 2013 James Burlingame
 *
 *     Licensed under the Apache License, Version 2.0 (the "License");
 *     you may not use this file except in compliance with the License.
 *     You may obtain a copy of the License at
 *
 *         http://www.apache.org/licenses/LICENSE-2.0
 *
 *     Unless required by applicable law or agreed to in writing, software
 *     distributed under the License is distributed on an "AS IS" BASIS,
 *     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 *     See the License for the specific language governing permissions and
 *     limitations under the License.
 *
 */

// enable JavaScript strict mode.
"use strict";

var fs = require("fs");
var http = require("http");
var path = require("path");
var url = require("url");
var util = require("util");
var agentdb = require("./lib/samplx-agentdb.js");
var HashTable = require("./lib/hash.js").HashTable;

// enable debug messages
var debug = false;

/** size of the hash table. can use test/tune-hash.js to compute. */
var HASH_TABLE_SIZE = 4339;

/**
 *  Download JSON object from a remote URL.
 *
 *  @param path to request.
 *  @param done callback.
 */
function getJSON(jsonUrl, done) {
    var parsedUrl = url.parse(jsonUrl);

    var options = {
        "host" : parsedUrl.hostname,
        "hostname": parsedUrl.hostname,
        "port" : parsedUrl.port || 80,
        "path" : parsedUrl.pathname,
        "method" : "GET",
        // "agent" : false,
    };

    debug && console.error("prepublish:getJSON('" + jsonUrl + "', done)");
    debug && console.error("options=" + util.inspect(options));
    var req = http.get(options, function (res) {
        debug && console.error("STATUS: " + res.statusCode);
        debug && console.error("HEADERS: " + JSON.stringify(res.headers));
        res.setEncoding('utf8');
        var data = '';
        res.on('data', function (chunk) {
            debug && console.error('getJSON: chunk="' + chunk + '"');
            data += chunk;
        });
        res.on('end', function() {
            debug && console.error('getJSON: end of request.');
            done(JSON.parse(data));
        });
    });

    req.on('error', function(error) {
        console.error("ERROR: " + error.message);
    });
}

/**
 *  Main entry point for prepublish script.
 */
function main() {

    var database = fs.createWriteStream('./lib/database-min.js', { flags: 'w', encoding: 'utf8' });
    var testFile;

    database.write("// Do not edit this file, your changes will be lost.\n");
    database.write("module.exports = { \n");
    getJSON('http://alscan.info/agent_groups/groups.json', function (groups) {
        var s = JSON.stringify(groups);
        database.write("groups:" + s + ",\n");
        testFile = fs.createWriteStream('./test/groups.json', { flags: 'w', encoding: 'utf8' });
        testFile.write(s+"\n");
        testFile.end();
        getJSON('http://alscan.info/agent_sources/sources.json', function (sources) {
            var s = JSON.stringify(sources);
            database.write("sources:" + s + ",\n");
            testFile = fs.createWriteStream('./test/sources.json', { flags: 'w', encoding: 'utf8' });
            testFile.write(s+"\n");
            testFile.end();
            getJSON('http://alscan.info/patterns/patterns.json', function (patterns) {
                database.write("patterns:[\n");
                patterns.forEach(function (pattern) {
                    database.write("{p: new RegExp('" + pattern.pattern + "'), x:" +
                            agentdb.getX(pattern.groupId, pattern.sourceId) + "},");
                });
                database.write("],\n");
                testFile = fs.createWriteStream('./test/patterns.json', { flags: 'w', encoding: 'utf8' });
                testFile.write(JSON.stringify(patterns)+"\n");
                testFile.end();
                getJSON('http://alscan.info/agents/agents.json', function (agents) {
                    var hash = new HashTable(HASH_TABLE_SIZE);
                    agents.forEach(function (agent) {
                        if (agent.status < 2) {
                            var obj = { a: agent.agent, x: agentdb.getX(agent.groupId, agent.sourceId) };
                            hash.add('a', obj);
                        }
                    });
                    database.write("table:" + JSON.stringify(hash.table) + ",\n");
                    database.write("HASH_TABLE_SIZE:" + HASH_TABLE_SIZE + ",\n");
                    database.write("hash: undefined\n}\n");
                    testFile = fs.createWriteStream('./test/agents.json', { flags: 'w', encoding: 'utf8' });
                    testFile.write(JSON.stringify(agents)+"\n");
                    testFile.end();
                    if (debug) {
                        var history = hash.getHistory();
                        console.log("Hash table history");
                        for (var n=0; n < history.length; n++) {
                            console.log("  Depth=" + n + ", count=" + history[n] + ", percent=" + (history[n] / HASH_TABLE_SIZE));
                        }
                    }
                });
            });
        });
    });
}

main();

<|endoftext|>


<commit_before>/**
 * validations
 *
 */
v = (function (tek) {
    var v = {};
    v.Schema = tek.define({
        init: function (def) {
            var s = this;
            s.validators = [];
            if (def) {
                Object.keys(def).forEach(function (property) {
                    Object.keys(def[property]).forEach(function (key) {
                        var expect = def[property][key];
                        s.addValidator(property, key, expect);
                    });
                });
            }
        },
        properties: {
            addValidator: function (property, key, expect) {
                var s = this;
                var Validator = v.Schema.resolveValidator(key);
                if (Validator) {
                    var validator = new Validator(expect);
                    validator.property = property;
                    s.validators.push(validator);
                } else {
                    console.error('[v.js] unknown schema:', key, expect);
                }
            },
            validate: function (values, callback) {
                var isEmpty = tek.validators.Validator.isEmpty;
                var s = this,
                    validators = s.validators,
                    count = validators.length,
                    errors = [];

                function next() {
                    count--;
                    var finish = count <= 0;
                    if (finish) {
                        callback(errors.length && errors || null);
                    }
                }

                validators.forEach(function (validator) {
                    var property = validator.property,
                        value = values[property];
                    var skip = isEmpty(value) && validator.skipIfEmpty;
                    if (skip) {
                        next();
                        return;
                    }
                    validator.validate(value, function (err) {
                        if (err) {
                            err.property= property;
                            errors.push(err);
                        }
                        next();
                    });
                });
            },
            clone: function () {
                var s = this,
                    clone = new v.Schema;
                clone.validators = s.validators;
                return clone;
            }
        }
    });
    v.Schema.resolveValidator = function (key) {
        var name = key.substr(0, 1).toUpperCase() + key.substr(1) + 'Validator';
        var Validator = tek.validators[name];
        if (Validator) {
            return Validator
        } else {
            if (typeof(value) === 'function') {
                return tek.validators['ConformValidator'];
            } else {
                return null;
            }
        }
    };
    v.Schema.Err = function (data) {
        var s = this;
        tek.copy(data, s);
    };

    /**
     * for serverside validation test
     */
    v.disableAllValidations = function () {
        console.warn('all clientside validation is disabled');
        v.Schema.prototype.validate = function (values, callback) {
            callback(null);
        };
    };
    return  v;
})(tek);
<commit_msg>modify validation<commit_after>/**
 * validations
 *
 */
v = (function (tek) {
    var v = {};
    v.Schema = tek.define({
        init: function (def) {
            var s = this;
            s.validators = [];
            if (def) {
                Object.keys(def).forEach(function (property) {
                    Object.keys(def[property]).forEach(function (key) {
                        var expect = def[property][key];
                        s.addValidator(property, key, expect);
                    });
                });
            }
        },
        properties: {
            addValidator: function (property, key, expect) {
                var s = this;
                var Validator = v.Schema.resolveValidator(key);
                if (Validator) {
                    var validator = new Validator(expect);
                    validator.property = property;
                    s.validators.push(validator);
                } else {
                    console.error('[v.js] unknown schema:', key, expect);
                }
            },
            validate: function (valueObj, callback) {
                var isEmpty = tek.validators.Validator.isEmpty;
                var s = this,
                    validators = s.validators,
                    count = validators.length,
                    errors = [];

                function next() {
                    count--;
                    var finish = count <= 0;
                    if (finish) {
                        callback(errors.length && errors || null);
                    }
                }

                validators.forEach(function (validator) {
                    var property = validator.property,
                        values = property.split(',').map(function (property) {
                            return valueObj[property];
                        });
                    if (validator.skipIfEmpty) {
                        var skip = values.filter(function (value) {
                            return !isEmpty(value);
                        }).length == 0;
                        if (skip) {
                            next();
                            return;
                        }
                    }
                    var validateArgs = values.concat(function (err) {
                        if (err) {
                            err.property = property;
                            errors.push(err);
                        }
                        next();
                    });
                    validator.validate.apply(validator, validateArgs);
                });
            },
            clone: function () {
                var s = this,
                    clone = new v.Schema;
                clone.validators = s.validators;
                return clone;
            }
        }
    });
    v.Schema.resolveValidator = function (key) {
        var name = key.substr(0, 1).toUpperCase() + key.substr(1) + 'Validator';
        var Validator = tek.validators[name];
        if (Validator) {
            return Validator
        } else {
            if (typeof(value) === 'function') {
                return tek.validators['ConformValidator'];
            } else {
                return null;
            }
        }
    };
    v.Schema.Err = function (data) {
        var s = this;
        tek.copy(data, s);
    };

    /**
     * for serverside validation test
     */
    v.disableAllValidations = function () {
        console.warn('all clientside validation is disabled');
        v.Schema.prototype.validate = function (values, callback) {
            callback(null);
        };
    };
    return  v;
})(tek);
<|endoftext|>


<commit_before>$('.UserSearch-search').on('keyup', ({ target }) => {
  if (target.value.length > 2) {
    fetch(`/users/search?q=${target.value}`, {
      headers: {
        'Accept': 'application/json',
        'Content-Type': 'application/json'
      },
      credentials: 'same-origin',
      method: 'get'
    })
    .then(results => results.json())
    .then(users => {
      appendUsersToSearch(users);
    })
    .catch(err => console.error(err));
  } else {
    $('.UserSearch-results').html('');
  }
});

const appendUsersToSearch = users => {
  const ul = document.createElement('ul'), cName = 'UserSearch-search-result list-group-item';

  ul.className = 'list-group';
  const list = $(ul);

  users.forEach(({ name, nameNumber, eligible, spotId, spotOpen }) => {
    const spot = `Spot (${spotId}) ${spotOpen ? 'open' : 'not open'}`;
    const canChallenge = eligible ? 'Can challenge' : 'Can\'t challenge';
    const ineligibleButton = eligible ?
      `<button class="UserSearch-search-result-ineligibleButton ${nameNumber}">Make Ineligible</button>` :
      '';
    const openSpotButton = !spotOpen && parseInt(spotId.substring(1), 10) < 13 ?
      `<button class="UserSearch-search-result-openSpotbutton ${spotId}">Open Spot</button>` :
      '';

    list.append(
      $(`<li class="${cName}">${name} | ${canChallenge} | ${spot} ${ineligibleButton} ${openSpotButton}</li>`)
    );
  });

  $('.UserSearch-results').html(list);

  $('.UserSearch-search-result-ineligibleButton').click(({ target }) => {
    fetch('/users/makeineligible', {
      headers: {
        'Accept': 'application/json',
        'Content-Type': 'application/json'
      },
      credentials: 'same-origin',
      method: 'post',
      body: JSON.stringify({ nameNumber: target.classList[1] })
    })
    .then(res => res.json())
    .then(() => {
      banner('User is now ineligible for next challenge');
      $(document.getElementsByClassName(target.classList.value)).remove();
    })
    .catch(() => banner('Sorry! We can\'t fufill that request right now'));
  });

  $('.UserSearch-search-result-openSpotbutton').click(({ target }) => {
    fetch('/spots/open', {
      headers: {
        'Accept': 'application/json',
        'Content-Type': 'application/json'
      },
      credentials: 'same-origin',
      method: 'post',
      body: JSON.stringify({ spotId: target.classList[1] })
    })
    .then(res => res.json())
    .then(() => {
      banner('User is now ineligible for next challenge');
      $(document.getElementsByClassName(target.classList.value)).remove();
    })
    .catch(() => banner('Sorry! We can\'t fufill that request right now'));
  });
};

const banner = (message) => {
  $('.bannerMessage').remove();
  $('.navbar').after(`<h3 class="bannerMessage">${message}</h3>`);
};
<commit_msg>Remove open spot text in list element after spot open action and change banner message<commit_after>$('.UserSearch-search').on('keyup', ({ target }) => {
  if (target.value.length > 2) {
    fetch(`/users/search?q=${target.value}`, {
      headers: {
        'Accept': 'application/json',
        'Content-Type': 'application/json'
      },
      credentials: 'same-origin',
      method: 'get'
    })
    .then(results => results.json())
    .then(users => {
      appendUsersToSearch(users);
    })
    .catch(err => console.error(err));
  } else {
    $('.UserSearch-results').html('');
  }
});

const appendUsersToSearch = users => {
  const ul = document.createElement('ul'), cName = 'UserSearch-search-result list-group-item';

  ul.className = 'list-group';
  const list = $(ul);

  users.forEach(({ name, nameNumber, eligible, spotId, spotOpen }) => {
    const spot = `Spot (${spotId}) ${spotOpen ? 'open' : 'not open'}`;
    const canChallenge = eligible ? 'Can challenge' : 'Can\'t challenge';
    const ineligibleButton = eligible ?
      `<button class="UserSearch-search-result-ineligibleButton ${nameNumber}">Make Ineligible</button>` :
      '';
    const openSpotButton = !spotOpen && parseInt(spotId.substring(1), 10) < 13 ?
      `<button class="UserSearch-search-result-openSpotbutton ${spotId}">Open Spot</button>` :
      '';

    list.append(
      $(`<li class="${cName}">${name} | ${canChallenge} | ${spot} ${ineligibleButton} ${openSpotButton}</li>`)
    );
  });

  $('.UserSearch-results').html(list);

  $('.UserSearch-search-result-ineligibleButton').click(({ target }) => {
    fetch('/users/makeineligible', {
      headers: {
        'Accept': 'application/json',
        'Content-Type': 'application/json'
      },
      credentials: 'same-origin',
      method: 'post',
      body: JSON.stringify({ nameNumber: target.classList[1] })
    })
    .then(res => res.json())
    .then(() => {
      banner('User is now ineligible for next challenge');
      $(document.getElementsByClassName(target.classList.value)).remove();
    })
    .catch(() => banner('Sorry! We can\'t fufill that request right now'));
  });

  $('.UserSearch-search-result-openSpotbutton').click(({ target }) => {
    fetch('/spots/open', {
      headers: {
        'Accept': 'application/json',
        'Content-Type': 'application/json'
      },
      credentials: 'same-origin',
      method: 'post',
      body: JSON.stringify({ spotId: target.classList[1] })
    })
    .then(res => res.json())
    .then(() => {
      const buttonParent = $(target.parentElement);

      banner(`Spot ${target.classList[1]} is now open!`);
      $(document.getElementsByClassName(target.classList.value)).remove();
      buttonParent.text(buttonParent[0].innerText.replace('not ', ''));
    })
    .catch(() => banner('Sorry! We can\'t fufill that request right now'));
  });
};

const banner = (message) => {
  $('.bannerMessage').remove();
  $('.navbar').after(`<h3 class="bannerMessage">${message}</h3>`);
};
<|endoftext|>


<commit_before>var Backbone = require('backbone');

var Template = require('../tpl/networks-detail.hbs');

var Addresses = require('../models/addresses');

var AddressesTableRowTemplate = require('../tpl/networks-detail-address-row.hbs');
var AddressesTableRow = Backbone.Marionette.ItemView.extend({
    tagName: "tr",
    template: AddressesTableRowTemplate,
    templateHelpers: {
        belongs_to_url: function() {
            var uuid = this.belongs_to_uuid;
            var type = this.belongs_to_type;
            var prefix;
            if (type === 'server') {
                prefix = 'servers';
            } else if (type === 'zone') {
                prefix = 'vms';
            } else {
                return null;
            }
            return _.str.sprintf('/%s/%s', prefix, uuid);
        }
    }
});

var AddressesTable = Backbone.Marionette.CollectionView.extend({
    itemView: AddressesTableRow
});

var NotesView = require('./notes');

var NetworkDetailView = Backbone.Marionette.ItemView.extend({
    template: Template,
    sidebar: "networks",
    initialize: function() {
        this.modelBinder = new Backbone.ModelBinder();
    },
    url: function() {
        return _.str.sprintf('networks/%s', this.model.get('uuid'));
    },
    onRender: function() {
        var addresses = new Addresses({uuid: this.model.get('uuid') });
        var addressesTable = new AddressesTable({
            el: this.$(".addresses tbody"),
            collection: addresses
        });
        addresses.fetch();
        this.modelBinder.bind(this.model, this.el);

        this.notesView = new NotesView({itemUuid: this.model.get('uuid'), el: this.$('.notes')});
        this.notesView.render();
    }
});

module.exports = NetworkDetailView;
<commit_msg>ADMINUI-943: should navigate to belongs to ip address's owner without page refresh<commit_after>var Backbone = require('backbone');
var _ = require('underscore');

var adminui = require('adminui');

var Template = require('../tpl/networks-detail.hbs');

var Addresses = require('../models/addresses');

var AddressesTableRowTemplate = require('../tpl/networks-detail-address-row.hbs');
var AddressesTableRow = Backbone.Marionette.ItemView.extend({
    tagName: "tr",
    template: AddressesTableRowTemplate,
    events: {
        'click .belongs-to a': 'navigateToItem'
    },
    navigateToItem: function(e) {
        if (e) {
            e.preventDefault();
        }

        var uuid = this.model.get('belongs_to_uuid');
        var type = this.model.get('belongs_to_type');
        if (type === 'server') {
            adminui.vent.trigger('showview', 'server', {uuid: uuid });
        }
        if (type === 'zone') {
            adminui.vent.trigger('showview', 'vm', {uuid: uuid });
        }
    },
    templateHelpers: {
        belongs_to_url: function() {
            var uuid = this.belongs_to_uuid;
            var type = this.belongs_to_type;
            var prefix;
            if (type === 'server') {
                prefix = 'servers';
            } else if (type === 'zone') {
                prefix = 'vms';
            } else {
                return null;
            }
            return _.str.sprintf('/%s/%s', prefix, uuid);
        }
    }
});

var AddressesTable = Backbone.Marionette.CollectionView.extend({
    itemView: AddressesTableRow
});

var NotesView = require('./notes');

var NetworkDetailView = Backbone.Marionette.ItemView.extend({
    template: Template,
    sidebar: "networks",
    initialize: function() {
        this.modelBinder = new Backbone.ModelBinder();
    },
    url: function() {
        return _.str.sprintf('networks/%s', this.model.get('uuid'));
    },
    onRender: function() {
        var addresses = new Addresses({uuid: this.model.get('uuid') });
        var addressesTable = new AddressesTable({
            el: this.$(".addresses tbody"),
            collection: addresses
        });
        addresses.fetch();
        this.modelBinder.bind(this.model, this.el);

        this.notesView = new NotesView({itemUuid: this.model.get('uuid'), el: this.$('.notes')});
        this.notesView.render();
    }
});

module.exports = NetworkDetailView;
<|endoftext|>


<commit_before>(function () {
    'use strict';

    mare.views.SuccessStories = Backbone.View.extend({
        el: 'body',

        events: {
            'click .card__button'	: 'loadSuccessStory'
        },

        loadSuccessStory: function(event) {
        	window.location.href = $(event.target).data('url');
        }

    });
}());<commit_msg>#208 | clean up success story backbone view to make navigation easier to understand<commit_after>(function () {
    'use strict';

    mare.views.SuccessStories = Backbone.View.extend({
        el: 'body',

        events: {
            'click .success-story__button'	: 'navigate'
        },

        navigate: function navigate( event ) {
        	window.location.href = $( event.target ).data( 'url' );
        }
    });
}());<|endoftext|>


<commit_before>TDP.data.overlays = {

  special_attack: "\u{1F525}",  // 🔥
  player_attack: "\u{1F4A5}",   // 💥
  player_miss: "\u{1F4AB}",     // 💫
  player_kill: "\u{2620}",      // ☠
  monster_attack: "\u{1F4A2}",  // 💢
  monster_miss: "\u{1F4AB}",    // 💫
  monster_kill: "\u{2620}",     // ☠
  monument_find: "\u{2728}"     // ✨

};

<commit_msg>Updated overlays emoji declarations<commit_after>TDP.data.overlays = {

  special_attack: "\uD83D\uDD25",  // 🔥
  player_attack: "\uD83D\uDCA5",   // 💥
  player_miss: "\uD83D\uDCAB",     // 💫
  player_kill: "\u2620",      // ☠
  monster_attack: "\uD83D\uDCA2",  // 💢
  monster_miss: "\uD83D\uDCAB",    // 💫
  monster_kill: "\u2620",     // ☠
  monument_find: "\u2728"     // ✨

};

<|endoftext|>


<commit_before>;(function() {
  var interval = 16;

  function Updater() {
    this.updatees = [];
    this.tick = interval;
    this.prev = new Date().getTime();

    var self = this;
    var update = function() {
      var now = new Date().getTime();
      self.tick = now - self.prev;
      self.prev = now;
      game.update(); // make sure game updated before everything else
      for (var i = 0; i < self.updatees.length; i++) {
        self.updatees[i].update();
      }

      window.requestAnimationFrame(update);
    };

    window.requestAnimationFrame(update);
  };

  Updater.prototype = {
    add: function(updatee) {
      this.updatees.push(updatee);
    },

    remove: function(updatee) {
      for(var i = 0; i < this.updatees.length; i++) {
        if(this.updatees[i] === updatee) {
          this.updatees.splice(i, 1);
          break;
        }
      }
    }
  };

  this.Updater = Updater;
}).call(this);
<commit_msg>Check for prefixed versions of requestAnimationFrame<commit_after>;(function() {
  var interval = 16;

  function Updater() {
    this.updatees = [];
    this.tick = interval;
    this.prev = new Date().getTime();

    var self = this;
    var requestAnimationFrame = window.requestAnimationFrame
        || window.mozRequestAnimationFrame
        || window.webkitRequestAnimationFrame;
    var update = function() {
      var now = new Date().getTime();
      self.tick = now - self.prev;
      self.prev = now;
      game.update(); // make sure game updated before everything else
      for (var i = 0; i < self.updatees.length; i++) {
        self.updatees[i].update();
      }

      requestAnimationFrame(update);
    };

    requestAnimationFrame(update);
  };

  Updater.prototype = {
    add: function(updatee) {
      this.updatees.push(updatee);
    },

    remove: function(updatee) {
      for(var i = 0; i < this.updatees.length; i++) {
        if(this.updatees[i] === updatee) {
          this.updatees.splice(i, 1);
          break;
        }
      }
    }
  };

  this.Updater = Updater;
}).call(this);
<|endoftext|>


<commit_before>// Initial state
export const initialState = {
    jobs: [],
    job: null,
    jobLabel: '',
    jobFilePath: '',
    jobError: false,
    jobLoading: false,

    proteinInfo: {},
    toggleProteinInfoModal: false,
};

// Enum for job actions
export const JOB_ACTIONS = {
    INITIAL_STATE: 'JOB_INITIAL_STATE',

    UPDATE_JOB_LABEL: 'UPDATE_JOB_LABEL',
    UPDATE_JOB_FILEPATH: 'UPDATE_JOB_FILEPATH',

    LOADING_JOBS: 'LOADING_JOBS',
    JOBS_LOADED: 'JOBS_LOADED',
    JOBS_ERROR: 'JOBS_ERROR',

    LOADING_JOB: 'LOADING_JOB',
    JOB_LOADED: 'JOB_LOADED',
    JOB_ERROR: 'JOB_ERROR',

    START_JOB: 'START_JOB',

    PROTEIN_INFO: 'PROTEIN_INFO',
    CLOSE_PROTEIN_MODAL: 'CLOSE_PROTEIN_MODAL',
};

const jobsReducer = (state = initialState, action) => {
    switch (action.type) {
        case JOB_ACTIONS.INITIAL_STATE:
            return initialState;

        case JOB_ACTIONS.UPDATE_JOB_LABEL:
            return {...state, jobLabel: action.value};
        case JOB_ACTIONS.UPDATE_JOB_FILEPATH:
            return {...state, jobFilePath: action.value};

        case JOB_ACTIONS.LOADING_JOBS:
            return {...state, jobError: false, jobs: []};
        case JOB_ACTIONS.JOBS_LOADED:
            return {...state, jobs: action.value, jobError: false};

        case JOB_ACTIONS.LOADING_JOB:
            return {...state, jobError: false, job: null, jobLoading: true};
        case JOB_ACTIONS.JOB_LOADED:
            return {...state, job: action.value, jobError: false, jobLoading: false};

        case JOB_ACTIONS.PROTEIN_INFO:
            return {...state, proteinInfo: action.value, toggleProteinInfoModal: true};
        case JOB_ACTIONS.CLOSE_PROTEIN_MODAL:
            return {...state, proteinInfo: {}, toggleProteinInfoModal: false};

        case JOB_ACTIONS.JOB_ERROR:
        case JOB_ACTIONS.JOBS_ERROR:
            return {...state, jobError: true};

        default:
            return state;
    }
};

export default jobsReducer;<commit_msg>bug fix<commit_after>// Initial state
export const initialState = {
    jobs: [],
    job: null,
    jobLabel: '',
    jobFilePath: '',
    jobError: false,
    jobLoading: false,

    proteinInfo: {},
    toggleProteinInfoModal: false,
};

// Enum for job actions
export const JOB_ACTIONS = {
    INITIAL_STATE: 'JOB_INITIAL_STATE',

    UPDATE_JOB_LABEL: 'UPDATE_JOB_LABEL',
    UPDATE_JOB_FILEPATH: 'UPDATE_JOB_FILEPATH',

    LOADING_JOBS: 'LOADING_JOBS',
    JOBS_LOADED: 'JOBS_LOADED',
    JOBS_ERROR: 'JOBS_ERROR',

    LOADING_JOB: 'LOADING_JOB',
    JOB_LOADED: 'JOB_LOADED',
    JOB_ERROR: 'JOB_ERROR',

    START_JOB: 'START_JOB',

    PROTEIN_INFO: 'PROTEIN_INFO',
    CLOSE_PROTEIN_MODAL: 'CLOSE_PROTEIN_MODAL',
};

const jobsReducer = (state = initialState, action) => {
    switch (action.type) {
        case JOB_ACTIONS.INITIAL_STATE:
            return initialState;

        case JOB_ACTIONS.UPDATE_JOB_LABEL:
            return {...state, jobLabel: action.value};
        case JOB_ACTIONS.UPDATE_JOB_FILEPATH:
            return {...state, jobFilePath: action.value};

        case JOB_ACTIONS.LOADING_JOBS:
            return {...state, jobError: false, jobs: []};
        case JOB_ACTIONS.JOBS_LOADED:
            return {...state, jobs: action.value, jobError: false};

        case JOB_ACTIONS.LOADING_JOB:
            return {...state, jobError: false, job: null, jobLoading: true};
        case JOB_ACTIONS.JOB_LOADED:
            return {...state, job: action.value, jobError: false, jobLoading: false};

        case JOB_ACTIONS.PROTEIN_INFO:
            return {...state, proteinInfo: (action.value ? action.value : {}), toggleProteinInfoModal: true};
        case JOB_ACTIONS.CLOSE_PROTEIN_MODAL:
            return {...state, proteinInfo: {}, toggleProteinInfoModal: false};

        case JOB_ACTIONS.JOB_ERROR:
        case JOB_ACTIONS.JOBS_ERROR:
            return {...state, jobError: true};

        default:
            return state;
    }
};

export default jobsReducer;<|endoftext|>


<commit_before>(function () {
"use strict";

var apis = window.apis || {};
window.apis = apis;

var Socket = function (onConnectFunc, onMessageFunc, onCloseFunc) {
	this.onConnectFunc = onConnectFunc;
	this.onMessageFunc = onMessageFunc;
	this.onCloseFunc = onCloseFunc;

	this.base = null;
	this.conn = null;
	this.socketPrefix = '/socket';
	this.headerSeparator = '\n\n';
	this.requestId = 0;
};

Socket.prototype.ensureConnected = function(base, cb) {
	if (this.conn == null || this.base != base) {
		this.connect(base, function (conn) {
			cb(conn);
		});
	}
	else {
		cb(this.conn);
	}
};

Socket.prototype.connect = function(base, opt_cb) {
	this.close();

	this.base = base || '';
	this.conn = new SockJS(this.base + this.socketPrefix);
	var self = this;

	this.conn.onopen = function() {
		self.onConnectFunc(self.conn);
		if (opt_cb) {
			opt_cb(self.conn);
		}
	};

	this.conn.onmessage = function(e) {
		var data = self.decode(e.data);
		self.onMessageFunc(e, data);
	};

	this.conn.onclose = function(e) {
		self.onCloseFunc(e);
	};
};

Socket.prototype.close = function () {
	if (this.conn != null) {
		this.conn.close();
		this.conn = null;
	}
};

Socket.prototype.send = function(headers, body) {
	headers = headers || {};
	headers.requestId = (headers.requestId == null ? ++this.requestId : headers.requestId);

	if (body === undefined) {
		body = '';
	}
	else {
		body = JSON.stringify(body);
	}

	var msg = [
		JSON.stringify(headers),
		body
	].join(this.headerSeparator);
	//console.log('sending:', msg);
	this.conn.send(msg);
};

Socket.prototype.decode = function(message) {
	//console.log('got:', message);
	var sepPos = message.indexOf(this.headerSeparator);
	var headersStr = message.substring(0, sepPos);
	var body = message.substring(sepPos + this.headerSeparator.length);

	var headers = JSON.parse(headersStr);

	return {
		headers: headers,
		body: body
	};
};

var Http = function (onResponseFunc) {
	this.onResponseFunc = onResponseFunc;
};

Http.prototype.setHeaders = function (req, headers) {
	if (headers) {
		for (var k in headers) {
			req.setRequestHeader(k, headers[k]);
		}
	}
};

Http.prototype.send = function (base, path, method, headers, body, xdomain, callback) {
	if (body === undefined) {
		body = '';
	}
	else {
		body = JSON.stringify(body);
	}

	var httpRequest = new XMLHttpRequest();
	var url = base + path;

	var self = this;
	httpRequest.onreadystatechange = function() {
		if(httpRequest.readyState == 4) {
			self.onResponseFunc(httpRequest);
		}
	};

	if (method == 'get' || xdomain) {
		var parts = [];
		if (callback) {
			if (method != 'get') {
				headers = headers || {};
				headers.method = method;
			}
			if (headers) {
				parts.push('headers=' + encodeURIComponent(JSON.stringify(headers)));
			}
		}
		if (body) {
			parts.push('body=' + encodeURIComponent(body));
		}
		if (xdomain) {
			parts.push('xdomain=' + encodeURIComponent(xdomain));
		}
		if (callback) {
			parts.push('callback=' + encodeURIComponent(callback));
		}
		var realUrl = url;
		if (parts.length > 0) {
			realUrl += '?' + parts.join('&');
		}
		httpRequest.open('GET', realUrl);
		if (!callback) {
			this.setHeaders(httpRequest, headers);
		}
		httpRequest.send();
	}
	else {
		httpRequest.open('POST', url);
		httpRequest.setRequestHeader('Content-type', 'application/json');
		if (method != 'create') {
			httpRequest.setRequestHeader('X-Method', method);
		}
		this.setHeaders(httpRequest, headers);
		httpRequest.send(body);
	}
};

var TestPage = function () {
	this.socket = this.createSocket();
	this.http = this.createHttp();
};

TestPage.prototype.initUi = function () {
	this.requestBaseField = this.byId('request-base');
	this.requestPathField = this.byId('request-path');
	this.requestPathFieldGroup = this.byId('request-path-group');
	this.requestMethodField = this.byId('request-method');
	this.requestHeadersField = this.byId('request-headers');
	this.requestHeadersFieldGroup = this.byId('request-headers-group');
	this.requestBodyField = this.byId('request-body');
	this.requestBodyFieldGroup = this.byId('request-body-group');
	this.requestXdomainField = this.byId('request-xdomain');

	this.requestSmartHeadersField = this.byId('request-smart-headers');
	this.requestRawBodyField = this.byId('request-raw-body');

	this.socketConnectButton = this.byId('socket-connect');
	this.socketSendButton = this.byId('socket-send');
	this.httpSendButton = this.byId('http-send');

	this.responseHeadersField = this.byId('response-headers');
	this.responseBodyField = this.byId('response-body');

	this.clearErrOnChange(this.requestPathField, this.requestPathFieldGroup);
	this.clearErrOnChange(this.requestHeadersField, this.requestHeadersFieldGroup);
	this.clearErrOnChange(this.requestBodyField, this.requestBodyFieldGroup);

	this.fixTabs(this.requestHeadersField);
	this.fixTabs(this.requestBodyField);
	this.fixTabs(this.responseHeadersField);
	this.fixTabs(this.responseBodyField);

	this.initButtons();
	this.initKeyHandler();
};

TestPage.prototype.byId = function (id) {
	return document.getElementById(id);
};

TestPage.prototype.fixTabs = function (el) {
	el.addEventListener('keydown', function (e) {
		if(e.keyCode == 9 && !e.altKey && !e.ctrlKey && !e.shiftKey) {
			var start = this.selectionStart;
			var end = this.selectionEnd;

			var value = this.value;
			this.value = [
				value.substring(0, start),
				'\t',
				value.substring(end)
			].join('');

			this.selectionStart = this.selectionEnd = start + 1;
			e.preventDefault();
		}
	});
};

TestPage.prototype.setErr = function (el, errEl, msg) {
	el.title = msg;
	errEl.classList.add('error');
	el.focus();
};

TestPage.prototype.clearErr = function (el, errEl) {
	el.title = null;
	errEl.classList.remove('error');
};

TestPage.prototype.clearErrOnChange = function (el, errEl) {
	var self = this;
	var clearFunc = function () {
		self.clearErr(el, errEl);
	};
	el.addEventListener('change', clearFunc);
	el.addEventListener('keydown', clearFunc);
	el.addEventListener('mousedown', clearFunc);
	el.addEventListener('blur', clearFunc);
};

TestPage.prototype.setPathRequiredErr = function () {
	this.setErr(this.requestPathField, this.requestPathFieldGroup, 'path is required');
};

TestPage.prototype.jsonval = function (el, errEl) {
	var v = el.value;
	var result;
	if (v) {
		var str = '"use strict";\nreturn ' + v;
		try {
			result = (new Function(str))();
		}
		catch (err) {
			this.setErr(el, errEl, err.message);
			throw err;
		}
	}
	return result;
};

TestPage.prototype.createSocket = function () {
	var self = this;
	var result = new Socket(
		function (conn) {
			self.onSocketConnect(conn);
		},
		function (e, data) {
			self.onSocketMessage(e, data);
		},
		function (e) {
			self.onSocketClose(e);
		}
	);
	return result;
};

TestPage.prototype.socketConnect = function () {
	if (this.socket.conn != null) {
		this.socket.close();
	}
	else {
		this.socket.connect();
	}
};

TestPage.prototype.onSocketConnect = function (conn) {
	this.socketConnectButton.innerText = 'disconnect';
};

TestPage.prototype.onSocketClose = function (e) {
	this.socketConnectButton.innerText = 'connect';
};

TestPage.prototype.onSocketMessage = function (e, data) {
	this.showResult(
		data.headers.status,
		data.headers,
		data.body
	);
};

TestPage.prototype.socketSend = function () {
	this.clearResult();
	var fields = this.collectFields();

	var headers = fields.headers || {};
	headers.path = headers.path || fields.path;
	headers.method = headers.method || fields.method;

	if (!headers.path) {
		this.setPathRequiredErr();
	}
	else {
		var socket = this.socket;
		socket.ensureConnected(fields.base, function () {
			socket.send(headers, fields.body);
		});
	}
};

TestPage.prototype.createHttp = function () {
	var self = this;
	return new Http(function (httpRequest) {
		self.onHttpResponse(httpRequest);
	});
};

TestPage.prototype.onHttpResponse = function (httpRequest) {
	this.showResult(
		httpRequest.status,
		httpRequest.getAllResponseHeaders(),
		httpRequest.responseText
	);
};

TestPage.prototype.applyHttpSmartHeaders = function (fields) {
	var headers = fields.headers;
	if (headers.auth) {
		headers['X-Auth'] = headers.auth;
		delete headers.auth;
	}
	if (headers.authExpected) {
		headers['X-AuthExpected'] = headers.authExpected;
		delete headers.authExpected;
	}
	if (headers.method) {
		fields.method = headers.method;
		delete headers.method;
	}
	if (headers.path) {
		fields.path = headers.path;
		delete headers.path;
	}
};

TestPage.prototype.httpSend = function () {
	this.clearResult();

	var fields = this.collectFields();
	if (fields.headers && this.requestSmartHeadersField.checked && !fields.xdomain) {
		this.applyHttpSmartHeaders(fields);
	}

	if (!fields.path) {
		this.setPathRequiredErr();
	}
	else {
		var callback = (fields.xdomain == 'jsonp' ? 'callback' : null);
		this.http.send(
			fields.base,
			fields.path,
			fields.method,
			fields.headers,
			fields.body,
			fields.xdomain,
			callback
		);
	}
};

TestPage.prototype.collectFields = function (cb) {
	return {
		base: this.requestBaseField.value,
		path: this.requestPathField.value,
		method: this.requestMethodField.value,
		headers: this.jsonval(this.requestHeadersField, this.requestHeadersFieldGroup),
		body: this.requestRawBodyField.checked ? this.requestBodyField.value : this.jsonval(this.requestBodyField, this.requestBodyFieldGroup),
		xdomain: this.requestXdomainField.value == 'none' ? null : this.requestXdomainField.value
	};
};

TestPage.prototype.clearResult = function (headers, body) {
	this.responseHeadersField.value = '';
	this.responseBodyField.value = '';
};

TestPage.prototype.showResult = function (status, headers, body) {
	if (headers.constructor !== String) {
		headers = JSON.stringify(headers, null, '\t');
	}
	try {
		body = JSON.stringify(JSON.parse(body), null, '\t');
	}
	catch (err) { // to be ready to non-json responses
	}

	this.responseHeadersField.value = headers;
	this.responseBodyField.value = ['Response code is ', status, '\n', body].join('');
};

TestPage.prototype.initButtons = function (headers, body) {
	var self = this;

	this.socketConnectButton.addEventListener('click', function () {
		self.socketConnect();
	});

	this.socketSendButton.addEventListener('click', function () {
		self.socketSend();
	});

	this.httpSendButton.addEventListener('click', function () {
		self.httpSend();
	});
};

TestPage.prototype.initKeyHandler = function () {
	var self = this;
	window.addEventListener('keypress', function (e) {
		if (e.keyCode == 13) {
			var tag = e.srcElement.tagName;
			if (tag != 'BUTTON') {
				var ok = true;
				if (tag == 'TEXTAREA') {
					if (e.ctrlKey) {
						e.preventDefault();
					}
					else {
						ok = false;
					}
				}
				if (ok) {
					if (e.altKey) {
						self.socketSendButton.click();
					}
					else {
						self.httpSendButton.click();
					}
				}
			}
		}
	});
};

apis.testPage = {
	Socket: Socket,
	Http: Http,
	TestPage: TestPage
};

})();
<commit_msg>fixed disconnetion problem on test page<commit_after>(function () {
"use strict";

var apis = window.apis || {};
window.apis = apis;

var Socket = function (onConnectFunc, onMessageFunc, onCloseFunc) {
	this.onConnectFunc = onConnectFunc;
	this.onMessageFunc = onMessageFunc;
	this.onCloseFunc = onCloseFunc;

	this.base = null;
	this.conn = null;
	this.socketPrefix = '/socket';
	this.headerSeparator = '\n\n';
	this.requestId = 0;
};

Socket.prototype.ensureConnected = function(base, cb) {
	if (this.conn == null || this.base != base) {
		this.connect(base, function (conn) {
			cb(conn);
		});
	}
	else {
		cb(this.conn);
	}
};

Socket.prototype.connect = function(base, opt_cb) {
	this.close();

	this.base = base || '';
	this.conn = new SockJS(this.base + this.socketPrefix);
	var self = this;

	this.conn.onopen = function() {
		self.onConnectFunc(self.conn);
		if (opt_cb) {
			opt_cb(self.conn);
		}
	};

	this.conn.onmessage = function(e) {
		var data = self.decode(e.data);
		self.onMessageFunc(e, data);
	};

	this.conn.onclose = function(e) {
		self.onCloseFunc(e);
		self.conn = null;
	};
};

Socket.prototype.close = function () {
	if (this.conn != null) {
		this.conn.close();
		this.conn = null;
	}
};

Socket.prototype.send = function(headers, body) {
	headers = headers || {};
	headers.requestId = (headers.requestId == null ? ++this.requestId : headers.requestId);

	if (body === undefined) {
		body = '';
	}
	else {
		body = JSON.stringify(body);
	}

	var msg = [
		JSON.stringify(headers),
		body
	].join(this.headerSeparator);
	//console.log('sending:', msg);
	this.conn.send(msg);
};

Socket.prototype.decode = function(message) {
	//console.log('got:', message);
	var sepPos = message.indexOf(this.headerSeparator);
	var headersStr = message.substring(0, sepPos);
	var body = message.substring(sepPos + this.headerSeparator.length);

	var headers = JSON.parse(headersStr);

	return {
		headers: headers,
		body: body
	};
};

var Http = function (onResponseFunc) {
	this.onResponseFunc = onResponseFunc;
};

Http.prototype.setHeaders = function (req, headers) {
	if (headers) {
		for (var k in headers) {
			req.setRequestHeader(k, headers[k]);
		}
	}
};

Http.prototype.send = function (base, path, method, headers, body, xdomain, callback) {
	if (body === undefined) {
		body = '';
	}
	else {
		body = JSON.stringify(body);
	}

	var httpRequest = new XMLHttpRequest();
	var url = base + path;

	var self = this;
	httpRequest.onreadystatechange = function() {
		if(httpRequest.readyState == 4) {
			self.onResponseFunc(httpRequest);
		}
	};

	if (method == 'get' || xdomain) {
		var parts = [];
		if (callback) {
			if (method != 'get') {
				headers = headers || {};
				headers.method = method;
			}
			if (headers) {
				parts.push('headers=' + encodeURIComponent(JSON.stringify(headers)));
			}
		}
		if (body) {
			parts.push('body=' + encodeURIComponent(body));
		}
		if (xdomain) {
			parts.push('xdomain=' + encodeURIComponent(xdomain));
		}
		if (callback) {
			parts.push('callback=' + encodeURIComponent(callback));
		}
		var realUrl = url;
		if (parts.length > 0) {
			realUrl += '?' + parts.join('&');
		}
		httpRequest.open('GET', realUrl);
		if (!callback) {
			this.setHeaders(httpRequest, headers);
		}
		httpRequest.send();
	}
	else {
		httpRequest.open('POST', url);
		httpRequest.setRequestHeader('Content-type', 'application/json');
		if (method != 'create') {
			httpRequest.setRequestHeader('X-Method', method);
		}
		this.setHeaders(httpRequest, headers);
		httpRequest.send(body);
	}
};

var TestPage = function () {
	this.socket = this.createSocket();
	this.http = this.createHttp();
};

TestPage.prototype.initUi = function () {
	this.requestBaseField = this.byId('request-base');
	this.requestPathField = this.byId('request-path');
	this.requestPathFieldGroup = this.byId('request-path-group');
	this.requestMethodField = this.byId('request-method');
	this.requestHeadersField = this.byId('request-headers');
	this.requestHeadersFieldGroup = this.byId('request-headers-group');
	this.requestBodyField = this.byId('request-body');
	this.requestBodyFieldGroup = this.byId('request-body-group');
	this.requestXdomainField = this.byId('request-xdomain');

	this.requestSmartHeadersField = this.byId('request-smart-headers');
	this.requestRawBodyField = this.byId('request-raw-body');

	this.socketConnectButton = this.byId('socket-connect');
	this.socketSendButton = this.byId('socket-send');
	this.httpSendButton = this.byId('http-send');

	this.responseHeadersField = this.byId('response-headers');
	this.responseBodyField = this.byId('response-body');

	this.clearErrOnChange(this.requestPathField, this.requestPathFieldGroup);
	this.clearErrOnChange(this.requestHeadersField, this.requestHeadersFieldGroup);
	this.clearErrOnChange(this.requestBodyField, this.requestBodyFieldGroup);

	this.fixTabs(this.requestHeadersField);
	this.fixTabs(this.requestBodyField);
	this.fixTabs(this.responseHeadersField);
	this.fixTabs(this.responseBodyField);

	this.initButtons();
	this.initKeyHandler();
};

TestPage.prototype.byId = function (id) {
	return document.getElementById(id);
};

TestPage.prototype.fixTabs = function (el) {
	el.addEventListener('keydown', function (e) {
		if(e.keyCode == 9 && !e.altKey && !e.ctrlKey && !e.shiftKey) {
			var start = this.selectionStart;
			var end = this.selectionEnd;

			var value = this.value;
			this.value = [
				value.substring(0, start),
				'\t',
				value.substring(end)
			].join('');

			this.selectionStart = this.selectionEnd = start + 1;
			e.preventDefault();
		}
	});
};

TestPage.prototype.setErr = function (el, errEl, msg) {
	el.title = msg;
	errEl.classList.add('error');
	el.focus();
};

TestPage.prototype.clearErr = function (el, errEl) {
	el.title = null;
	errEl.classList.remove('error');
};

TestPage.prototype.clearErrOnChange = function (el, errEl) {
	var self = this;
	var clearFunc = function () {
		self.clearErr(el, errEl);
	};
	el.addEventListener('change', clearFunc);
	el.addEventListener('keydown', clearFunc);
	el.addEventListener('mousedown', clearFunc);
	el.addEventListener('blur', clearFunc);
};

TestPage.prototype.setPathRequiredErr = function () {
	this.setErr(this.requestPathField, this.requestPathFieldGroup, 'path is required');
};

TestPage.prototype.jsonval = function (el, errEl) {
	var v = el.value;
	var result;
	if (v) {
		var str = '"use strict";\nreturn ' + v;
		try {
			result = (new Function(str))();
		}
		catch (err) {
			this.setErr(el, errEl, err.message);
			throw err;
		}
	}
	return result;
};

TestPage.prototype.createSocket = function () {
	var self = this;
	var result = new Socket(
		function (conn) {
			self.onSocketConnect(conn);
		},
		function (e, data) {
			self.onSocketMessage(e, data);
		},
		function (e) {
			self.onSocketClose(e);
		}
	);
	return result;
};

TestPage.prototype.socketConnect = function () {
	if (this.socket.conn != null) {
		this.socket.close();
	}
	else {
		this.socket.connect();
	}
};

TestPage.prototype.onSocketConnect = function (conn) {
	this.socketConnectButton.innerText = 'disconnect';
};

TestPage.prototype.onSocketClose = function (e) {
	this.socketConnectButton.innerText = 'connect';
};

TestPage.prototype.onSocketMessage = function (e, data) {
	this.showResult(
		data.headers.status,
		data.headers,
		data.body
	);
};

TestPage.prototype.socketSend = function () {
	this.clearResult();
	var fields = this.collectFields();

	var headers = fields.headers || {};
	headers.path = headers.path || fields.path;
	headers.method = headers.method || fields.method;

	if (!headers.path) {
		this.setPathRequiredErr();
	}
	else {
		var socket = this.socket;
		socket.ensureConnected(fields.base, function () {
			socket.send(headers, fields.body);
		});
	}
};

TestPage.prototype.createHttp = function () {
	var self = this;
	return new Http(function (httpRequest) {
		self.onHttpResponse(httpRequest);
	});
};

TestPage.prototype.onHttpResponse = function (httpRequest) {
	this.showResult(
		httpRequest.status,
		httpRequest.getAllResponseHeaders(),
		httpRequest.responseText
	);
};

TestPage.prototype.applyHttpSmartHeaders = function (fields) {
	var headers = fields.headers;
	if (headers.auth) {
		headers['X-Auth'] = headers.auth;
		delete headers.auth;
	}
	if (headers.authExpected) {
		headers['X-AuthExpected'] = headers.authExpected;
		delete headers.authExpected;
	}
	if (headers.method) {
		fields.method = headers.method;
		delete headers.method;
	}
	if (headers.path) {
		fields.path = headers.path;
		delete headers.path;
	}
};

TestPage.prototype.httpSend = function () {
	this.clearResult();

	var fields = this.collectFields();
	if (fields.headers && this.requestSmartHeadersField.checked && !fields.xdomain) {
		this.applyHttpSmartHeaders(fields);
	}

	if (!fields.path) {
		this.setPathRequiredErr();
	}
	else {
		var callback = (fields.xdomain == 'jsonp' ? 'callback' : null);
		this.http.send(
			fields.base,
			fields.path,
			fields.method,
			fields.headers,
			fields.body,
			fields.xdomain,
			callback
		);
	}
};

TestPage.prototype.collectFields = function (cb) {
	return {
		base: this.requestBaseField.value,
		path: this.requestPathField.value,
		method: this.requestMethodField.value,
		headers: this.jsonval(this.requestHeadersField, this.requestHeadersFieldGroup),
		body: this.requestRawBodyField.checked ? this.requestBodyField.value : this.jsonval(this.requestBodyField, this.requestBodyFieldGroup),
		xdomain: this.requestXdomainField.value == 'none' ? null : this.requestXdomainField.value
	};
};

TestPage.prototype.clearResult = function (headers, body) {
	this.responseHeadersField.value = '';
	this.responseBodyField.value = '';
};

TestPage.prototype.showResult = function (status, headers, body) {
	if (headers.constructor !== String) {
		headers = JSON.stringify(headers, null, '\t');
	}
	try {
		body = JSON.stringify(JSON.parse(body), null, '\t');
	}
	catch (err) { // to be ready to non-json responses
	}

	this.responseHeadersField.value = headers;
	this.responseBodyField.value = ['Response code is ', status, '\n', body].join('');
};

TestPage.prototype.initButtons = function (headers, body) {
	var self = this;

	this.socketConnectButton.addEventListener('click', function () {
		self.socketConnect();
	});

	this.socketSendButton.addEventListener('click', function () {
		self.socketSend();
	});

	this.httpSendButton.addEventListener('click', function () {
		self.httpSend();
	});
};

TestPage.prototype.initKeyHandler = function () {
	var self = this;
	window.addEventListener('keypress', function (e) {
		if (e.keyCode == 13) {
			var tag = e.srcElement.tagName;
			if (tag != 'BUTTON') {
				var ok = true;
				if (tag == 'TEXTAREA') {
					if (e.ctrlKey) {
						e.preventDefault();
					}
					else {
						ok = false;
					}
				}
				if (ok) {
					if (e.altKey) {
						self.socketSendButton.click();
					}
					else {
						self.httpSendButton.click();
					}
				}
			}
		}
	});
};

apis.testPage = {
	Socket: Socket,
	Http: Http,
	TestPage: TestPage
};

})();
<|endoftext|>


<commit_before>// ========================================================================
// Copyright (c) 2008-2009, Metaweb Technologies, Inc.
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions
// are met:
//     * Redistributions of source code must retain the above copyright
//       notice, this list of conditions and the following disclaimer.
//     * Redistributions in binary form must reproduce the above
//       copyright notice, this list of conditions and the following
//       disclaimer in the documentation and/or other materials provided
//       with the distribution.
//
// THIS SOFTWARE IS PROVIDED BY METAWEB TECHNOLOGIES AND CONTRIBUTORS
// ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL METAWEB
// TECHNOLOGIES OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
// INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
// BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
// OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
// ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR
// TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
// USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
// DAMAGE.
// ========================================================================

/*
**  Misc utility functions
*/

//perform a shallow copy of a JS object
function clone(obj) {
    var copy = {};
    for (var i in obj)
        copy[i] = obj[i];
    return copy;
}

/**constructs a DOM node
  * @param {!string} kind The tag of the created node
  */
function node(kind, var_args) {
    var node = $(document.createElement(arguments[0]));
    var options = arguments[arguments.length-1]
    var len = arguments.length - 1;
    if (typeof options == "object" && options.insertAfter == undefined){
        if (options["onclick"] != undefined) {
            node.click(options["onclick"]);
            delete options["onclick"];
        }
        node.attr(options);
    }
    else
        len = arguments.length;

    for (var i = 1; i < len; i++)
        node.append(arguments[i]);
    return node;
}

/** Maps MQL ids to valid CSS class names
  * @param {!string} idName the MQL id
 */
function idToClass(idName) {
    return idName.replace(/\//g,"_").replace(":","___");
}

function startsWith(needle, haystack) {
    if (needle.substr(0,haystack.length) == haystack)
        return true;
    return false;
}

function charIn(string, chr) {
    return string.indexOf(chr) !== -1;
}

function isValueProperty(propName) {
    if (freebase.getPropMetadata(propName))
        return isValueType(freebase.getPropMetadata(propName).expected_type);
    return undefined;
}

function isValueType(type) {
    return Arr.contains(type['extends'], "/type/value");
}

function isCVTProperty(propName) {
    var prop = freebase.getPropMetadata(propName);
    if (freebase.getPropMetadata(propName))
        return isCVTType(prop.expected_type);
    return undefined;
}

function isCVTType(type) {
    return type["/freebase/type_hints/mediator"]
        && type["/freebase/type_hints/mediator"].value;
}

//I can't believe I can't find a better way of doing these
/* Functions for treating an object kinda like a list */
function getFirstValue(obj) {
    for (var key in obj)
        return obj[key];
    return undefined;
}

function getSecondValue(obj) {
    var i = 1;
    for (var key in obj){
        if (i > 1)
            return obj[key];
        i++;
    }
    return undefined;
}

function isObjectEmpty(obj) {
    for (var key in obj)
        return false;
    return true;
}

function numProperties(obj) {
    var i = 0;
    for (var key in obj)
        i++;
    return i;
}

function identity(value) {return value;}

function getChainedProperty(entity, prop) {
    var slots = [entity];
    $.each(prop.split(":"), function(_,part) {
        var newSlots = [];
        $.each(slots, function(_,slot) {
            newSlots = newSlots.concat($.grep($.makeArray(slot[part]),identity))
        })
        slots = newSlots;
    });
    if (slots === []) return undefined;
    return slots;
}

var isMqlProp = (function(){
    var invalidList = ["/type/object/name","/type/object/type","/type/object/id",/(^|:)id$/];
    return function(prop) {
        for (var i = 0; i<invalidList.length; i++){
            if (prop.match(invalidList[i]))
                return false;
        }
        return true;
    }
})();

function getMqlProperties(headers) {
    return Arr.filter(getProperties(headers), isMqlProp);
}

function getProperties(headers) {
    return Arr.filter(headers, function(header) {
        return header.charAt(0) == "/"
    })
}

/** @constructor */
function OrderedMap() {
    var properties = [];
    var map = {};
    this.set = function(key, value) {
        if (key in map)
            map[key] = value;
        else
            this.add(key,value);
    }
    this.setIfAbsent = function(key,value) {
        if (!(key in map))
            this.set(key,value);
        return this.get(key);
    }
    this.add = function(key, value) {
        properties.push(key);
        map[key] = value;
    }
    this.get = function(key, defaultValue) {
        return map[key] || defaultValue;
    }
    this.getProperties = function() {
        return properties;
    }
    //assumes OrderedMap<String,OrderedMap>
    this.getComplexProperties = function() {
        var self = this;
        return Arr.concatMap(properties, function(prop) {
            var innerProps = self.get(prop).getComplexProperties();
            return [prop].concat($.map(innerProps,function(innerProp){return prop + ":" + innerProp}));
        });
    }
}

/** @constructor */
var Set = function(var_args) {
    var set = {};
    this.add = function(val) {set[val] = true;};
    this.addAll = function(array) {
        for(var i = 0; i < array.length; i++)
            this.add(array[i]);
    }
    this.contains = function(val) {return val in set;};
    //getAll only valid for
    this.getAll = function() {var all = []; for (var val in set) all.push(val); return all;};
    this.addAll(arguments);
}

/**

  @return {string}
*/
function getType(v) {
    if (typeof v !== "object") return typeof v;
    if ($.isArray(v)) return "array";
    if (v === null) return "null";
    if (v === undefined) return "undefined";
    if (v instanceof Date) return "date";
    if (v instanceof RegExp) return "regexp";
    if (v instanceof String) return "string";
    return "object";
}

//This set implementation preserves order, but just in case
var OrderedSet = Set;

/**
 * @param {string} url
 * @param {Object} params
 * @param {function(Object)} onSuccess
 * @param {function()} onTimeout
 * @param {number=} millis milliseconds until query times out
 */
function getJSON(url, params, onSuccess, onTimeout, millis) {
    millis = millis || 120000; //default of 2 minute timeout
    var timedOut = false;
    var responded = false;
    function timeout() {
        if (responded) return;
        warn("timed out");
        timedOut = true;
        if (onTimeout) onTimeout();
    }
    var timer = setTimeout(timeout, millis);
    function responseHandler(response) {
        if (timedOut) {
            warn("got response after timeout")
            return;
        }
        responded = true;
        clearTimeout(timer);
        onSuccess(response);
    }

    if (location.host === "data.labs.freebase.com")
        $.post(url, params, responseHandler, "jsonp")
    else
        $.getJSON(url, params, responseHandler);
}

/*
** create debugging tools if they're not available
*/
function logger(log_level) {
    if (console[log_level])
        return function(message) {
          try {
            return console[log_level](message);
          }
          catch(e) {
            return console[log_level](JsObjDump.annotate(message));
          }
        };
    return function(message){/*node("div",JSON.stringify(message)).appendTo("#" + log_level + "Log");*/ return message;}
}

//These messages don't go anywhere at the moment, but it'd be very easy to create the
// places where they'd go
if (!window.console)
    var console = {};
var error  = logger("error");
var warn   = logger("warn" );
var log    = logger("log"  );
var info   = logger("info" );
var assert = function() {
    if (console.assert)
        return function(bool, message) {return console.assert(bool,message);};
    return function(bool,message){if (!bool) error(message)};
}()<commit_msg>Added debug() utility function<commit_after>// ========================================================================
// Copyright (c) 2008-2009, Metaweb Technologies, Inc.
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions
// are met:
//     * Redistributions of source code must retain the above copyright
//       notice, this list of conditions and the following disclaimer.
//     * Redistributions in binary form must reproduce the above
//       copyright notice, this list of conditions and the following
//       disclaimer in the documentation and/or other materials provided
//       with the distribution.
//
// THIS SOFTWARE IS PROVIDED BY METAWEB TECHNOLOGIES AND CONTRIBUTORS
// ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL METAWEB
// TECHNOLOGIES OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
// INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
// BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
// OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
// ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR
// TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
// USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
// DAMAGE.
// ========================================================================

/*
**  Misc utility functions
*/

//perform a shallow copy of a JS object
function clone(obj) {
    var copy = {};
    for (var i in obj)
        copy[i] = obj[i];
    return copy;
}

/**constructs a DOM node
  * @param {!string} kind The tag of the created node
  */
function node(kind, var_args) {
    var node = $(document.createElement(arguments[0]));
    var options = arguments[arguments.length-1]
    var len = arguments.length - 1;
    if (typeof options == "object" && options.insertAfter == undefined){
        if (options["onclick"] != undefined) {
            node.click(options["onclick"]);
            delete options["onclick"];
        }
        node.attr(options);
    }
    else
        len = arguments.length;

    for (var i = 1; i < len; i++)
        node.append(arguments[i]);
    return node;
}

/** Maps MQL ids to valid CSS class names
  * @param {!string} idName the MQL id
 */
function idToClass(idName) {
    return idName.replace(/\//g,"_").replace(":","___");
}

function startsWith(needle, haystack) {
    if (needle.substr(0,haystack.length) == haystack)
        return true;
    return false;
}

function charIn(string, chr) {
    return string.indexOf(chr) !== -1;
}

function isValueProperty(propName) {
    if (freebase.getPropMetadata(propName))
        return isValueType(freebase.getPropMetadata(propName).expected_type);
    return undefined;
}

function isValueType(type) {
    return Arr.contains(type['extends'], "/type/value");
}

function isCVTProperty(propName) {
    var prop = freebase.getPropMetadata(propName);
    if (freebase.getPropMetadata(propName))
        return isCVTType(prop.expected_type);
    return undefined;
}

function isCVTType(type) {
    return type["/freebase/type_hints/mediator"]
        && type["/freebase/type_hints/mediator"].value;
}

//I can't believe I can't find a better way of doing these
/* Functions for treating an object kinda like a list */
function getFirstValue(obj) {
    for (var key in obj)
        return obj[key];
    return undefined;
}

function getSecondValue(obj) {
    var i = 1;
    for (var key in obj){
        if (i > 1)
            return obj[key];
        i++;
    }
    return undefined;
}

function isObjectEmpty(obj) {
    for (var key in obj)
        return false;
    return true;
}

function numProperties(obj) {
    var i = 0;
    for (var key in obj)
        i++;
    return i;
}

function identity(value) {return value;}

function getChainedProperty(entity, prop) {
    var slots = [entity];
    $.each(prop.split(":"), function(_,part) {
        var newSlots = [];
        $.each(slots, function(_,slot) {
            newSlots = newSlots.concat($.grep($.makeArray(slot[part]),identity))
        })
        slots = newSlots;
    });
    if (slots === []) return undefined;
    return slots;
}

var isMqlProp = (function(){
    var invalidList = ["/type/object/name","/type/object/type","/type/object/id",/(^|:)id$/];
    return function(prop) {
        for (var i = 0; i<invalidList.length; i++){
            if (prop.match(invalidList[i]))
                return false;
        }
        return true;
    }
})();

function getMqlProperties(headers) {
    return Arr.filter(getProperties(headers), isMqlProp);
}

function getProperties(headers) {
    return Arr.filter(headers, function(header) {
        return header.charAt(0) == "/"
    })
}

/** @constructor */
function OrderedMap() {
    var properties = [];
    var map = {};
    this.set = function(key, value) {
        if (key in map)
            map[key] = value;
        else
            this.add(key,value);
    }
    this.setIfAbsent = function(key,value) {
        if (!(key in map))
            this.set(key,value);
        return this.get(key);
    }
    this.add = function(key, value) {
        properties.push(key);
        map[key] = value;
    }
    this.get = function(key, defaultValue) {
        return map[key] || defaultValue;
    }
    this.getProperties = function() {
        return properties;
    }
    //assumes OrderedMap<String,OrderedMap>
    this.getComplexProperties = function() {
        var self = this;
        return Arr.concatMap(properties, function(prop) {
            var innerProps = self.get(prop).getComplexProperties();
            return [prop].concat($.map(innerProps,function(innerProp){return prop + ":" + innerProp}));
        });
    }
}

/** @constructor */
var Set = function(var_args) {
    var set = {};
    this.add = function(val) {set[val] = true;};
    this.addAll = function(array) {
        for(var i = 0; i < array.length; i++)
            this.add(array[i]);
    }
    this.contains = function(val) {return val in set;};
    //getAll only valid for
    this.getAll = function() {var all = []; for (var val in set) all.push(val); return all;};
    this.addAll(arguments);
}

/**

  @return {string}
*/
function getType(v) {
    if (typeof v !== "object") return typeof v;
    if ($.isArray(v)) return "array";
    if (v === null) return "null";
    if (v === undefined) return "undefined";
    if (v instanceof Date) return "date";
    if (v instanceof RegExp) return "regexp";
    if (v instanceof String) return "string";
    return "object";
}

//This set implementation preserves order, but just in case
var OrderedSet = Set;

/**
 * @param {string} url
 * @param {Object} params
 * @param {function(Object)} onSuccess
 * @param {function()} onTimeout
 * @param {number=} millis milliseconds until query times out
 */
function getJSON(url, params, onSuccess, onTimeout, millis) {
    millis = millis || 120000; //default of 2 minute timeout
    var timedOut = false;
    var responded = false;
    function timeout() {
        if (responded) return;
        warn("timed out");
        timedOut = true;
        if (onTimeout) onTimeout();
    }
    var timer = setTimeout(timeout, millis);
    function responseHandler(response) {
        if (timedOut) {
            warn("got response after timeout")
            return;
        }
        responded = true;
        clearTimeout(timer);
        onSuccess(response);
    }

    if (location.host === "data.labs.freebase.com")
        $.post(url, params, responseHandler, "jsonp")
    else
        $.getJSON(url, params, responseHandler);
}

/*
** create debugging tools if they're not available
*/
function logger(log_level) {
    if (console[log_level])
        return function(message) {
          try {
            return console[log_level](message);
          }
          catch(e) {
            return console[log_level](JsObjDump.annotate(message));
          }
        };
    return function(message){/*node("div",JSON.stringify(message)).appendTo("#" + log_level + "Log");*/ return message;}
}

//These messages don't go anywhere at the moment, but it'd be very easy to create the
// places where they'd go
if (!window.console)
    var console = {};
var error  = logger("error");
var warn   = logger("warn" );
var log    = logger("log"  );
var info   = logger("info" );
var assert = function() {
    if (console.assert)
        return function(bool, message) {return console.assert(bool,message);};
    return function(bool,message){if (!bool) error(message)};
}()

var debug = function(val) {
    log(JSON.stringify(JsObjDump.annotate(val), null, 2))
}
<|endoftext|>


<commit_before>{
	"translatorID":"24d9f058-3eb3-4d70-b78f-1ba1aef2128d",
	"translatorType":5,
	"label":"CTX",
	"creator":"Avram Lyon and Simon Kornblith",
	"target":"^http://freecite.library.brown.edu",
	"minVersion":"2.0",
	"maxVersion":"",
	"priority":100,
	"inRepository":false,
	"lastUpdated":"2010-10-09 07:21:37"
}

/*
 * This translator imports OpenURL ContextObjects encapsulated in XML
 * documents, as described at:
 *  http://alcme.oclc.org/openurl/servlet/OAIHandler?verb=GetRecord&metadataPrefix=oai_dc&identifier=info:ofi/fmt:xml:xsd:ctx
 * The schema for such XML documents is at:
 *  http://www.openurl.info/registry/docs/xsd/info:ofi/fmt:xml:xsd:ctx
 *
 * This format is used in several places online, including Brown University's FreeCite
 * Citation parser (http://freecite.library.brown.edu/welcome) and Oslo University's
 * X-Port (http://www.ub.uio.no/portal/gs.htm or http://x-port.uio.no/).

 * Our input looks like this:
<ctx:context-objects xmlns:xsi='http://www.w3.org/2001/XMLSchema-instance' xsi:schemaLocation='info:ofi/fmt:xml:xsd:ctx http://www.openurl.info/registry/docs/info:ofi/fmt:xml:xsd:ctx' xmlns:ctx='info:ofi/fmt:xml:xsd:ctx'>
<ctx:context-object timestamp='2010-01-02T16:55:48-05:00' encoding='info:ofi/enc:UTF-8' version='Z39.88-2004' identifier=''>
 <ctx:referent>
  <ctx:metadata-by-val>
   <ctx:format>info:ofi/fmt:xml:xsd:journal</ctx:format>
   <ctx:metadata>
    <journal xmlns:rft='info:ofi/fmt:xml:xsd:journal' xsi:schemaLocation='info:ofi/fmt:xml:xsd:journal http://www.openurl.info/registry/docs/info:ofi/fmt:xml:xsd:journal'>
     <rft:atitle>Acute Myocardial Infarction in the Medicare population: process of care and clinical outcomes</rft:atitle>
     <rft:spage>2530</rft:spage>
     <rft:date>1992</rft:date>
     <rft:stitle>Journal of the American Medical Association</rft:stitle>
     <rft:genre>article</rft:genre>
     <rft:volume>18</rft:volume>
     <rft:epage>2536</rft:epage>
     <rft:au>I S Udvarhelyi</rft:au>
     <rft:au>C A Gatsonis</rft:au>
     <rft:au>A M Epstein</rft:au>
     <rft:au>C L Pashos</rft:au>
     <rft:au>J P Newhouse</rft:au>
     <rft:au>B J McNeil</rft:au>
    </journal>
   </ctx:metadata>
  </ctx:metadata-by-val>
 </ctx:referent>
</ctx:context-object>
</ctx:context-objects>
 *
 * The approach we will take is to convert this into COinS, so that we can
 * piggy-back off of the perhaps more robust support in the core Zotero code.
 */

Zotero.configure("dataMode", "line");

function detectWeb(doc, url) {
	var texts = [], text = "";
	var codes = doc.getElementsByTagName("code");
	for(var i = 0; i < codes.length; i++) {
		text = codes[i].textContent;
		text.replace(/</g,"<").replace(/>/g,">");
		texts.push(text);
	}
	return detectInString(texts);
};

function doWeb(doc, url) {
	var texts = [], text = "";
	var codes = doc.getElementsByTagName("code");
	for(var i = 0; i < codes.length; i++) {
		text = codes[i].textContent;
		text.replace(/</g,"<").replace(/>/g,">");
		texts.push(text);
	}
	doImportFromText(texts, true);
};

function doImport() {
	var text = "";
	var line;
	while(line = Zotero.read()) {
		text += line;
	}
	return doImportFromText(text, false);
}

function detectImport() {
	var text = "";
	var line;
	while(line = Zotero.read()) {
		text += line;
	}
	return detectInString(text) != false;
}

function detectInString(text) {
    var detectedType = false;

	var spans = [];

	// This is because we want to be able to read multiple such CTX elements in a single page
	if (typeof text != "string" && text.length >= 1) {
		spans = text.map(contextObjectXMLToCOinS).reduce(function(a,b){return a.concat(b);});
	} else {
		spans = contextObjectXMLToCOinS(text);
	}

	for (var i = 0 ; i < spans.length ; i++) {
		var item = new Zotero.Item;
		var success = Zotero.Utilities.parseContextObject(spans[i], item);
		if(item.itemType) {
			Zotero.debug("Found " + item.itemType);
			if (detectedType) {
			    return "multiple";
			}
			detectedType = item.itemType;
		} else {
			Zotero.debug("Type not found");
		}
	}
	return detectedType;
};

/* Takes the string of the ContextObject XML format
 * and returns an array of COinS titles of the same, per the COinS
 * specification.
 */
function contextObjectXMLToCOinS (text) {
	try {
		var doc = new XML(text);
	}
	catch (e) {
		return [];
	}

	/* Here and elsewhere, we are using the E4X syntax for XML */
	var objects = doc..*::["context-object"];

	/* Bail out if no object */
	if (objects.length() == 0) {
		Zotero.debug("No context object");
		return [];
	}

	var titles = [];

	for (var i = 0; i < objects.length(); i++) {
		Zotero.debug("Processing object: " + objects[i].text());
		var pieces = [];

		var version = objects[i].@version;
		pieces.push("ctx_ver="+encodeURIComponent(version));

		var format = objects[i]..*::format;
		// Now convert this to the corresponding Key/Encoded-Value format; see note below.
		// Check if this is unknown; if it is, skip
		if (format.text() == "info:ofi/fmt:xml:xsd:unknown") {
			Zotero.debug("Skipping object of type 'unknown'");
			continue;
		}
		format = mapXMLtoKEV[format.text()];

		pieces.push("rft_val_fmt=" + encodeURIComponent(format));

		// Here we disregard the namespaces
		var fields = objects[i]..*::metadata.children()[0].*::*;
		var field;

		for each (field in fields) {
		    var name = field.localName();
		    // We can hardcode the 'rft' namespace to keep COinS valid
		    name = "rft."+name;
		    var value = encodeURIComponent(field.text());
		    pieces.push(name + "=" + value);
		}

		var title = pieces.join("&");
		var span = "\n";
		Zotero.debug("Made span: " + span);
		titles.push(title);
	}
	return titles;
};

function doImportFromText(text, showPrompt) {
	var spans = [], items = [], zoteroItems = [];

	// This is because we want to be able to read multiple such CTX elements in a single page
	if (typeof text != "string" && text.length >= 1) {
		spans = text.map(contextObjectXMLToCOinS).reduce(function(a,b){return a.concat(b);});
	} else {
		spans = contextObjectXMLToCOinS(text);
	}

	for (var i = 0 ; i < spans.length ; i++) {
		Zotero.debug("Processing span: "+spans[i]);
		var item = new Zotero.Item;
		Zotero.Utilities.parseContextObject(spans[i], item);
		if(item.itemType) {
			Zotero.debug("Found " + item.itemType);
			items.push(item.title);
			zoteroItems.push(item);
			// Set publicationTitle to the short title if only the latter is specified
			if (item.journalAbbreviation && !item.publicationTitle) {
				item.publicationTitle = item.journalAbbreviation;
			}
			// If we're in non-prompting mode, save right away
			if (showPrompt === false) {
				item.complete();
			}
		} else {
			Zotero.debug("Type not found");
		}
	}
	// Since we want to prompt, we have to parse twice.
	if(showPrompt === true) {
		if(items.length == 1) {
			item.complete();
		} else {
			items = Zotero.selectItems(items);
			if(!items) return true;
			for(var i in items) {
				zoteroItems[i].complete();
			}
		}
	}
};

/* These two arrays are needed because COinS uses Key/Escaped-Value, which has a different
 * set of format codes. Codes from "Registry for the OpenURL Framework - ANSI/NISO Z39.88-2004":
 * http://alcme.oclc.org/openurl/servlet/OAIHandler?verb=ListRecords&metadataPrefix=oai_dc&set=Core:Metadata+Formats
 */
var mapKEVtoXML = {
	'info:ofi/fmt:kev:mtx:book'	:	'info:ofi/fmt:xml:xsd:book',	 	// Books
	'info:ofi/fmt:kev:mtx:dc'	:	'info:ofi/fmt:xml:xsd:oai_dc',		// Dublin Core
	'info:ofi/fmt:kev:mtx:dissertation' :	'info:ofi/fmt:xml:xsd:dissertation',	// Dissertations
	'info:ofi/fmt:kev:mtx:journal'	:	'info:ofi/fmt:xml:xsd:journal',		// Journals
	'info:ofi/fmt:kev:mtx:patent'	:	'info:ofi/fmt:xml:xsd:patent',		// Patents
	'info:ofi/fmt:kev:mtx:sch_svc'	:	'info:ofi/fmt:xml:xsd:sch_svc'		// Scholarly ServiceTypes
};

var mapXMLtoKEV = {
	'info:ofi/fmt:xml:xsd:book'	:	'info:ofi/fmt:kev:mtx:book',	 	// Books
	'info:ofi/fmt:xml:xsd:oai_dc'	:	'info:ofi/fmt:kev:mtx:dc',		// Dublin Core
	'info:ofi/fmt:xml:xsd:dissertation' :	'info:ofi/fmt:kev:mtx:dissertation',	// Dissertations
	'info:ofi/fmt:xml:xsd:journal'	:	'info:ofi/fmt:kev:mtx:journal',		// Journals
	'info:ofi/fmt:xml:xsd:patent'	:	'info:ofi/fmt:kev:mtx:patent',		// Patents
	'info:ofi/fmt:xml:xsd:sch_svc'	:	'info:ofi/fmt:kev:mtx:sch_svc'		// Scholarly ServiceTypes
};
<commit_msg>Trans: Adding GPL declaration to CTX code<commit_after>{
	"translatorID":"24d9f058-3eb3-4d70-b78f-1ba1aef2128d",
	"translatorType":5,
	"label":"CTX",
	"creator":"Avram Lyon and Simon Kornblith",
	"target":"^http://freecite.library.brown.edu",
	"minVersion":"2.0",
	"maxVersion":"",
	"priority":100,
	"inRepository":false,
	"lastUpdated":"2010-10-09 07:21:37"
}

/*
   Radio Liberty Translator
   Copyright (C) 2010 Avram Lyon, ajlyon@gmail.com

   This program is free software: you can redistribute it and/or modify
   it under the terms of the GNU General Public License as published by
   the Free Software Foundation, either version 3 of the License, or
   (at your option) any later version.

   This program is distributed in the hope that it will be useful,
   but WITHOUT ANY WARRANTY; without even the implied warranty of
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   GNU General Public License for more details.

   You should have received a copy of the GNU General Public License
   along with this program.  If not, see <http://www.gnu.org/licenses/>.
 */
 /*This translator imports OpenURL ContextObjects encapsulated in XML
 * documents, as described at:
 *  http://alcme.oclc.org/openurl/servlet/OAIHandler?verb=GetRecord&metadataPrefix=oai_dc&identifier=info:ofi/fmt:xml:xsd:ctx
 * The schema for such XML documents is at:
 *  http://www.openurl.info/registry/docs/xsd/info:ofi/fmt:xml:xsd:ctx
 *
 * This format is used in several places online, including Brown University's FreeCite
 * Citation parser (http://freecite.library.brown.edu/welcome) and Oslo University's
 * X-Port (http://www.ub.uio.no/portal/gs.htm or http://x-port.uio.no/).

 * Our input looks like this:
<ctx:context-objects xmlns:xsi='http://www.w3.org/2001/XMLSchema-instance' xsi:schemaLocation='info:ofi/fmt:xml:xsd:ctx http://www.openurl.info/registry/docs/info:ofi/fmt:xml:xsd:ctx' xmlns:ctx='info:ofi/fmt:xml:xsd:ctx'>
<ctx:context-object timestamp='2010-01-02T16:55:48-05:00' encoding='info:ofi/enc:UTF-8' version='Z39.88-2004' identifier=''>
 <ctx:referent>
  <ctx:metadata-by-val>
   <ctx:format>info:ofi/fmt:xml:xsd:journal</ctx:format>
   <ctx:metadata>
    <journal xmlns:rft='info:ofi/fmt:xml:xsd:journal' xsi:schemaLocation='info:ofi/fmt:xml:xsd:journal http://www.openurl.info/registry/docs/info:ofi/fmt:xml:xsd:journal'>
     <rft:atitle>Acute Myocardial Infarction in the Medicare population: process of care and clinical outcomes</rft:atitle>
     <rft:spage>2530</rft:spage>
     <rft:date>1992</rft:date>
     <rft:stitle>Journal of the American Medical Association</rft:stitle>
     <rft:genre>article</rft:genre>
     <rft:volume>18</rft:volume>
     <rft:epage>2536</rft:epage>
     <rft:au>I S Udvarhelyi</rft:au>
     <rft:au>C A Gatsonis</rft:au>
     <rft:au>A M Epstein</rft:au>
     <rft:au>C L Pashos</rft:au>
     <rft:au>J P Newhouse</rft:au>
     <rft:au>B J McNeil</rft:au>
    </journal>
   </ctx:metadata>
  </ctx:metadata-by-val>
 </ctx:referent>
</ctx:context-object>
</ctx:context-objects>
 *
 * The approach we will take is to convert this into COinS, so that we can
 * piggy-back off of the perhaps more robust support in the core Zotero code.
 */

Zotero.configure("dataMode", "line");

function detectWeb(doc, url) {
	var texts = [], text = "";
	var codes = doc.getElementsByTagName("code");
	for(var i = 0; i < codes.length; i++) {
		text = codes[i].textContent;
		text.replace(/</g,"<").replace(/>/g,">");
		texts.push(text);
	}
	return detectInString(texts);
};

function doWeb(doc, url) {
	var texts = [], text = "";
	var codes = doc.getElementsByTagName("code");
	for(var i = 0; i < codes.length; i++) {
		text = codes[i].textContent;
		text.replace(/</g,"<").replace(/>/g,">");
		texts.push(text);
	}
	doImportFromText(texts, true);
};

function doImport() {
	var text = "";
	var line;
	while(line = Zotero.read()) {
		text += line;
	}
	return doImportFromText(text, false);
}

function detectImport() {
	var text = "";
	var line;
	while(line = Zotero.read()) {
		text += line;
	}
	return detectInString(text) != false;
}

function detectInString(text) {
    var detectedType = false;

	var spans = [];

	// This is because we want to be able to read multiple such CTX elements in a single page
	if (typeof text != "string" && text.length >= 1) {
		spans = text.map(contextObjectXMLToCOinS).reduce(function(a,b){return a.concat(b);});
	} else {
		spans = contextObjectXMLToCOinS(text);
	}

	for (var i = 0 ; i < spans.length ; i++) {
		var item = new Zotero.Item;
		var success = Zotero.Utilities.parseContextObject(spans[i], item);
		if(item.itemType) {
			Zotero.debug("Found " + item.itemType);
			if (detectedType) {
			    return "multiple";
			}
			detectedType = item.itemType;
		} else {
			Zotero.debug("Type not found");
		}
	}
	return detectedType;
};

/* Takes the string of the ContextObject XML format
 * and returns an array of COinS titles of the same, per the COinS
 * specification.
 */
function contextObjectXMLToCOinS (text) {
	try {
		var doc = new XML(text);
	}
	catch (e) {
		return [];
	}

	/* Here and elsewhere, we are using the E4X syntax for XML */
	var objects = doc..*::["context-object"];

	/* Bail out if no object */
	if (objects.length() == 0) {
		Zotero.debug("No context object");
		return [];
	}

	var titles = [];

	for (var i = 0; i < objects.length(); i++) {
		Zotero.debug("Processing object: " + objects[i].text());
		var pieces = [];

		var version = objects[i].@version;
		pieces.push("ctx_ver="+encodeURIComponent(version));

		var format = objects[i]..*::format;
		// Now convert this to the corresponding Key/Encoded-Value format; see note below.
		// Check if this is unknown; if it is, skip
		if (format.text() == "info:ofi/fmt:xml:xsd:unknown") {
			Zotero.debug("Skipping object of type 'unknown'");
			continue;
		}
		format = mapXMLtoKEV[format.text()];

		pieces.push("rft_val_fmt=" + encodeURIComponent(format));

		// Here we disregard the namespaces
		var fields = objects[i]..*::metadata.children()[0].*::*;
		var field;

		for each (field in fields) {
		    var name = field.localName();
		    // We can hardcode the 'rft' namespace to keep COinS valid
		    name = "rft."+name;
		    var value = encodeURIComponent(field.text());
		    pieces.push(name + "=" + value);
		}

		var title = pieces.join("&");
		var span = "\n";
		Zotero.debug("Made span: " + span);
		titles.push(title);
	}
	return titles;
};

function doImportFromText(text, showPrompt) {
	var spans = [], items = [], zoteroItems = [];

	// This is because we want to be able to read multiple such CTX elements in a single page
	if (typeof text != "string" && text.length >= 1) {
		spans = text.map(contextObjectXMLToCOinS).reduce(function(a,b){return a.concat(b);});
	} else {
		spans = contextObjectXMLToCOinS(text);
	}

	for (var i = 0 ; i < spans.length ; i++) {
		Zotero.debug("Processing span: "+spans[i]);
		var item = new Zotero.Item;
		Zotero.Utilities.parseContextObject(spans[i], item);
		if(item.itemType) {
			Zotero.debug("Found " + item.itemType);
			items.push(item.title);
			zoteroItems.push(item);
			// Set publicationTitle to the short title if only the latter is specified
			if (item.journalAbbreviation && !item.publicationTitle) {
				item.publicationTitle = item.journalAbbreviation;
			}
			// If we're in non-prompting mode, save right away
			if (showPrompt === false) {
				item.complete();
			}
		} else {
			Zotero.debug("Type not found");
		}
	}
	// Since we want to prompt, we have to parse twice.
	if(showPrompt === true) {
		if(items.length == 1) {
			item.complete();
		} else {
			items = Zotero.selectItems(items);
			if(!items) return true;
			for(var i in items) {
				zoteroItems[i].complete();
			}
		}
	}
};

/* These two arrays are needed because COinS uses Key/Escaped-Value, which has a different
 * set of format codes. Codes from "Registry for the OpenURL Framework - ANSI/NISO Z39.88-2004":
 * http://alcme.oclc.org/openurl/servlet/OAIHandler?verb=ListRecords&metadataPrefix=oai_dc&set=Core:Metadata+Formats
 */
var mapKEVtoXML = {
	'info:ofi/fmt:kev:mtx:book'	:	'info:ofi/fmt:xml:xsd:book',	 	// Books
	'info:ofi/fmt:kev:mtx:dc'	:	'info:ofi/fmt:xml:xsd:oai_dc',		// Dublin Core
	'info:ofi/fmt:kev:mtx:dissertation' :	'info:ofi/fmt:xml:xsd:dissertation',	// Dissertations
	'info:ofi/fmt:kev:mtx:journal'	:	'info:ofi/fmt:xml:xsd:journal',		// Journals
	'info:ofi/fmt:kev:mtx:patent'	:	'info:ofi/fmt:xml:xsd:patent',		// Patents
	'info:ofi/fmt:kev:mtx:sch_svc'	:	'info:ofi/fmt:xml:xsd:sch_svc'		// Scholarly ServiceTypes
};

var mapXMLtoKEV = {
	'info:ofi/fmt:xml:xsd:book'	:	'info:ofi/fmt:kev:mtx:book',	 	// Books
	'info:ofi/fmt:xml:xsd:oai_dc'	:	'info:ofi/fmt:kev:mtx:dc',		// Dublin Core
	'info:ofi/fmt:xml:xsd:dissertation' :	'info:ofi/fmt:kev:mtx:dissertation',	// Dissertations
	'info:ofi/fmt:xml:xsd:journal'	:	'info:ofi/fmt:kev:mtx:journal',		// Journals
	'info:ofi/fmt:xml:xsd:patent'	:	'info:ofi/fmt:kev:mtx:patent',		// Patents
	'info:ofi/fmt:xml:xsd:sch_svc'	:	'info:ofi/fmt:kev:mtx:sch_svc'		// Scholarly ServiceTypes
};
<|endoftext|>


<commit_before>import { createElement as h } from 'react'
import PropTypes from 'prop-types'
import classNames from 'classnames'

// Round upward to the next group of ten
const round = (num) => Math.ceil(num / 10) * 10

const max = (items) => round(Math.max.apply(Math, items))
const mid = (items) => max(items) / 2
const min = () => 0

const percentage = (amount, max) => (amount / max) * 100

const Row = (props) => {

	return (
		h('div', {
			className: classNames({
				'barChart__row': true,
				'barChart__row--top': props.position === 'top',
				'barChart__row--middle': props.position === 'middle',
				'barChart__row--bottom': props.position === 'bottom',
				'color-light': true
			})
		}, props.children)
	)

}

const Column = (props) => {

	return (
		h('div', {
			className: classNames({
				barChart__column: true,
				active: props.active
			}),
			onMouseEnter: props.onEnter,
			onMouseLeave: props.onLeave
		},
			h('div', {
				'className': 'barChart__bar color-black',
				'style': { '--size': props.size },
				'data-label': props.label
			})
		)
	)

}

const PresentationBarChart = (props) => {

	return (
		h('div', { className: 'barChart' },
			h('div', { className: 'barChart__axis' },
				h(Row, { position: 'top' }, props.items.length === 0 ? '' : max(props.items)),
				h(Row, { position: 'middle' }, props.items.length === 0 ? '' : mid(props.items)),
				h(Row, { position: 'bottom' }, props.items.length === 0 ? '' : min())
			),
			props.items.map((item, index) => (
				h(Column, {
					key: index,
					active: props.active === index,
					size: `${ percentage(item, max(props.items)) }%`,
					onEnter: () => props.onEnter(index),
					onLeave: () => props.onLeave(index),
					label: item
				})
			))
		)
	)

}

PresentationBarChart.propTypes = {
	items: PropTypes.arrayOf(PropTypes.number).isRequired,
	onEnter: PropTypes.func.isRequired,
	onLeave: PropTypes.func.isRequired
}

export default PresentationBarChart<commit_msg>Use variable to check if it has items<commit_after>import { createElement as h } from 'react'
import PropTypes from 'prop-types'
import classNames from 'classnames'

// Round upward to the next group of ten
const round = (num) => Math.ceil(num / 10) * 10

const max = (items) => round(Math.max.apply(Math, items))
const mid = (items) => max(items) / 2
const min = () => 0

const percentage = (amount, max) => (amount / max) * 100

const Row = (props) => {

	return (
		h('div', {
			className: classNames({
				'barChart__row': true,
				'barChart__row--top': props.position === 'top',
				'barChart__row--middle': props.position === 'middle',
				'barChart__row--bottom': props.position === 'bottom',
				'color-light': true
			})
		}, props.children)
	)

}

const Column = (props) => {

	return (
		h('div', {
			className: classNames({
				barChart__column: true,
				active: props.active
			}),
			onMouseEnter: props.onEnter,
			onMouseLeave: props.onLeave
		},
			h('div', {
				'className': 'barChart__bar color-black',
				'style': { '--size': props.size },
				'data-label': props.label
			})
		)
	)

}

const PresentationBarChart = (props) => {

	const hasItems = props.items.length > 0

	return (
		h('div', { className: 'barChart' },
			h('div', { className: 'barChart__axis' },
				h(Row, { position: 'top' }, hasItems === true ? max(props.items) : ''),
				h(Row, { position: 'middle' }, hasItems === true ? mid(props.items) : ''),
				h(Row, { position: 'bottom' }, hasItems === true ? min() : '')
			),
			props.items.map((item, index) => (
				h(Column, {
					key: index,
					active: props.active === index,
					size: `${ percentage(item, max(props.items)) }%`,
					onEnter: () => props.onEnter(index),
					onLeave: () => props.onLeave(index),
					label: item
				})
			))
		)
	)

}

PresentationBarChart.propTypes = {
	items: PropTypes.arrayOf(PropTypes.number).isRequired,
	onEnter: PropTypes.func.isRequired,
	onLeave: PropTypes.func.isRequired
}

export default PresentationBarChart<|endoftext|>


<commit_before><commit_msg>update map<commit_after><|endoftext|>