<commit_before>#!/usr/bin/env node
'use strict';

var restify   = require('restify');
var extend    = require('deep-extend');
var q         = require('q');
var fs        = require('fs');
var path      = require('path');
var mkdirp    = require('mkdirp');
var md5       = require('md5');
var wkBin = require('wkhtmltopdf-installer');
var pdfFac    = require('../lib');

var ebTestReg = /^\/tmp\/deployment\/application/;
if (ebTestReg.test(wkBin.path)) { // in EB
  wkBin.path = wkBin.path.replace(ebTestReg, __dirname);
}

var pkg = require('../package.json');

// Get untrackable configurations.
try {
  extend(process.env, require('../config.json')); //eslint-disable-line global-require
} catch (err) {
  if (!err.message || err.code !== 'MODULE_NOT_FOUND') {
    throw err;
  }
}

var writeFile   = q.nfbind(fs.writeFile);
var tmpDir      = process.env.TMP_DIR || path.join(__dirname, '..', '.tmp');
var serviceName = process.env.NAME || pkg.name;
var toPdf       = pdfFac({
  command: process.env.CMD_PATH || wkBin.path || 'wkhtmltopdf'
});

var server = restify.createServer({
  name:    serviceName,
  version: '1.0.0'
});

server.use(
  function crossOrigin (req, res, next) {
    res.header("Access-Control-Allow-Origin", "*");
    res.header("Access-Control-Allow-Headers", "X-Requested-With");
    return next();
  }
);

server.use(restify.queryParser());
server.use(restify.gzipResponse());

server.post('/', restify.bodyParser(), function (req, res, next) {
  var html   = req.body && req.body.html;
  var header = req.body && req.body.header;
  var footer = req.footer && req.body.footer;

  if (html) {
    Object.getOwnPropertyNames(req.query).forEach(i => {
      let t = req.query[i].toLowerCase();
      if (t === 'true' || t === 'false') {
        req.query[i] = t === 'true';
      }
    });

    var hfProms = [];
    var time    = Date.now();
    if (header) {
      var headerPath = path.join(tmpDir, md5(header) + '-' + time + '.html');
      hfProms.push(writeFile(headerPath, header).then(function () {
        return headerPath
      }));
      req.query['headerHtml'] = headerPath;
    }
    if (footer) {
      var footerPath = path.join(tmpDir, md5(footer) + '-' + time + '.html');
      hfProms.push(writeFile(footerPath, footer).then(function () {
        return headerPath
      }));
      req.query['footerHtml'] = footerPath;
    }

    q.all(hfProms)
      .done(function (paths) {
        toPdf(html, req.query, (err, out) => {
          if (err) {
            next(err);
          } else {

            res.setHeader('content-type', 'application/pdf');
            res.send(out);
            paths.forEach(function (p) {
              fs.unlink(p);
            });
          }
        });
      })
    ;

  } else {
    next(new Error('No HTML body given.'));
  }
});

mkdirp(tmpDir, function (err) {
  if (err) {
    console.log('Server not started, failed to make temporary directory'); //eslint-disable-line no-console
    throw err;
  }

  server.listen(process.env.PORT || 15000, function () {
    console.log('%s server started at %s', server.name, server.url); //eslint-disable-line no-console
  });

});
<commit_msg>another path fix<commit_after>#!/usr/bin/env node
'use strict';

var restify   = require('restify');
var extend    = require('deep-extend');
var q         = require('q');
var fs        = require('fs');
var path      = require('path');
var mkdirp    = require('mkdirp');
var md5       = require('md5');
var wkBin = require('wkhtmltopdf-installer');
var pdfFac    = require('../lib');

var ebTestReg = /^\/tmp\/deployment\/application/;
if (ebTestReg.test(wkBin.path)) { // in EB
  wkBin.path = wkBin.path.replace(ebTestReg, path.normalize(path.join(__dirname, '..')));
}

var pkg = require('../package.json');

// Get untrackable configurations.
try {
  extend(process.env, require('../config.json')); //eslint-disable-line global-require
} catch (err) {
  if (!err.message || err.code !== 'MODULE_NOT_FOUND') {
    throw err;
  }
}

var writeFile   = q.nfbind(fs.writeFile);
var tmpDir      = process.env.TMP_DIR || path.join(__dirname, '..', '.tmp');
var serviceName = process.env.NAME || pkg.name;
var toPdf       = pdfFac({
  command: process.env.CMD_PATH || wkBin.path || 'wkhtmltopdf'
});

var server = restify.createServer({
  name:    serviceName,
  version: '1.0.0'
});

server.use(
  function crossOrigin (req, res, next) {
    res.header("Access-Control-Allow-Origin", "*");
    res.header("Access-Control-Allow-Headers", "X-Requested-With");
    return next();
  }
);

server.use(restify.queryParser());
server.use(restify.gzipResponse());

server.post('/', restify.bodyParser(), function (req, res, next) {
  var html   = req.body && req.body.html;
  var header = req.body && req.body.header;
  var footer = req.footer && req.body.footer;

  if (html) {
    Object.getOwnPropertyNames(req.query).forEach(i => {
      let t = req.query[i].toLowerCase();
      if (t === 'true' || t === 'false') {
        req.query[i] = t === 'true';
      }
    });

    var hfProms = [];
    var time    = Date.now();
    if (header) {
      var headerPath = path.join(tmpDir, md5(header) + '-' + time + '.html');
      hfProms.push(writeFile(headerPath, header).then(function () {
        return headerPath
      }));
      req.query['headerHtml'] = headerPath;
    }
    if (footer) {
      var footerPath = path.join(tmpDir, md5(footer) + '-' + time + '.html');
      hfProms.push(writeFile(footerPath, footer).then(function () {
        return headerPath
      }));
      req.query['footerHtml'] = footerPath;
    }

    q.all(hfProms)
      .done(function (paths) {
        toPdf(html, req.query, (err, out) => {
          if (err) {
            next(err);
          } else {

            res.setHeader('content-type', 'application/pdf');
            res.send(out);
            paths.forEach(function (p) {
              fs.unlink(p);
            });
          }
        });
      })
    ;

  } else {
    next(new Error('No HTML body given.'));
  }
});

mkdirp(tmpDir, function (err) {
  if (err) {
    console.log('Server not started, failed to make temporary directory'); //eslint-disable-line no-console
    throw err;
  }

  server.listen(process.env.PORT || 15000, function () {
    console.log('%s server started at %s', server.name, server.url); //eslint-disable-line no-console
  });

});
<|endoftext|>


<commit_before>var prefix = "MyItemsHoldr::",
    autoSave = true,
    callbackArgs = ["hello", "world"],
    values = {
        "lives": {
            "valueDefault": 3
        },
        "tries": {
            "value": 0
        }
    },
    displayChanges = {
        "9": "max"
    },
    storage = {},
    ItemsHolder;

describe("constructor", function () {
    it("doesn't throw an error", function () {
        new ItemsHoldr.ItemsHoldr();
    });

    it("correctly sets general settings", function () {
        ItemsHolder = new ItemsHoldr.ItemsHoldr({
            "prefix": prefix,
            "autoSave": autoSave,
            "callbackArgs": callbackArgs,
            "displayChanges": displayChanges,
            "values": values
        });

        chai.expect(ItemsHolder.getPrefix()).to.be.equal(prefix);
        chai.expect(ItemsHolder.getAutoSave()).to.be.equal(autoSave);
        chai.expect(ItemsHolder.getCallbackArgs()).to.be.equal(callbackArgs);
        chai.expect(ItemsHolder.getDisplayChanges()).to.be.equal(displayChanges);
    });
});

describe("storage", function () {
    it("initializes values to a given valueDefault", function () {
        chai.expect(ItemsHolder.getItem("lives")).to.be.equal(3);
    });

    it("initializes values to a given value", function () {
        chai.expect(ItemsHolder.getItem("tries")).to.be.equal(0);
    });

    it("sets values", function () {
        ItemsHolder.setItem("tries", 3);
        chai.expect(ItemsHolder.getItem("tries")).to.be.equal(3);
    });

    it("increases values", function () {
        ItemsHolder.increase("tries");
        chai.expect(ItemsHolder.getItem("tries")).to.be.equal(4);
    });

    it("decreases values", function () {
        ItemsHolder.decrease("tries");
        chai.expect(ItemsHolder.getItem("tries")).to.be.equal(3);
    });

    it("toggles values", function () {
        ItemsHolder.toggle("tries");
        chai.expect(ItemsHolder.getItem("tries")).to.be.equal(0);
        ItemsHolder.toggle("tries");
        chai.expect(ItemsHolder.getItem("tries")).to.be.equal(1);
    });
});

describe("storage", function () {
    var storage = {};

    it("may take in a localStorage", function () {
        ItemsHolder = new ItemsHoldr.ItemsHoldr({
            "prefix": prefix,
            "autoSave": autoSave,
            "callbackArgs": callbackArgs,
            "values": values,
            "localStorage": storage
        });

        chai.expect(ItemsHolder.getLocalStorage()).to.be.equal(storage);
    });

    it("saves values", function () {
        ItemsHolder.saveAll();
        chai.expect(ItemsHolder.getLocalStorage()).to.be.deep.equal({
            "MyItemsHoldr::lives": "3",
            "MyItemsHoldr::tries": "0"
        });
    });

    it("retrieves values", function () {
        ItemsHolder = new ItemsHoldr.ItemsHoldr({
            "prefix": prefix,
            "autoSave": autoSave,
            "callbackArgs": callbackArgs,
            "values": values,
            "localStorage": storage
        });

        chai.expect(ItemsHolder.getItem("lives")).to.be.equal(3);
        chai.expect(ItemsHolder.getItem("tries")).to.be.equal(0);
    });
});

describe("HTML", function () {
    it("creates the container", function () {
        var container;

        values.lives.hasElement = true;
        values.tries.hasElement = true;

        ItemsHolder = new ItemsHoldr.ItemsHoldr({
            "prefix": prefix,
            "autoSave": autoSave,
            "callbackArgs": callbackArgs,
            "values": values,
            "displayChanges": displayChanges,
            "doMakeContainer": true,
            "containersArguments": [
                [
                    "div",
                    {
                        "id": "ContainerOut"
                    }
                ],
                [
                    "span",
                    {
                        "id": "ContainerIn"
                    }
                ]
            ]
        });

        container = ItemsHolder.getContainer();

        chai.expect(container).to.not.be.undefined;
        chai.expect(container.tagName).to.be.equal("DIV");
        chai.expect(container.id).to.be.equal("ContainerOut");
        chai.expect(container.children).to.have.length(1);
        chai.expect(container.children[0].tagName).to.be.equal("SPAN");
        chai.expect(container.children[0].id).to.be.equal("ContainerIn");
    });

    it("creates value elements", function () {
        var children = ItemsHolder.getContainer().children[0].children;

        chai.expect(children[0].className).to.be.equal("MyItemsHoldr::_value lives");
        chai.expect(children[1].className).to.be.equal("MyItemsHoldr::_value tries");

        chai.expect(children[0].children[0].innerText).to.be.equal("lives");
        chai.expect(children[1].children[0].innerText).to.be.equal("tries");

        chai.expect(children[0].children[1].innerText).to.be.equal("3");
        chai.expect(children[1].children[1].innerText).to.be.equal("0");
    });

    it("updates value elements", function () {
        var children = ItemsHolder.getContainer().children[0].children;

        ItemsHolder.setItem("lives", 7);
        ItemsHolder.setItem("tries", 1);

        chai.expect(children[0].children[1].innerText).to.be.equal("7");
        chai.expect(children[1].children[1].innerText).to.be.equal("1");
    });
});<commit_msg>Update tests for toggles<commit_after>var prefix = "MyItemsHoldr::",
    autoSave = true,
    callbackArgs = ["hello", "world"],
    values = {
        "lives": {
            "valueDefault": 3
        },
        "tries": {
            "value": 0
        }
    },
    displayChanges = {
        "9": "max"
    },
    storage = {},
    ItemsHolder;

describe("constructor", function () {
    it("doesn't throw an error", function () {
        new ItemsHoldr.ItemsHoldr();
    });

    it("correctly sets general settings", function () {
        ItemsHolder = new ItemsHoldr.ItemsHoldr({
            "prefix": prefix,
            "autoSave": autoSave,
            "callbackArgs": callbackArgs,
            "displayChanges": displayChanges,
            "values": values
        });

        chai.expect(ItemsHolder.getPrefix()).to.be.equal(prefix);
        chai.expect(ItemsHolder.getAutoSave()).to.be.equal(autoSave);
        chai.expect(ItemsHolder.getCallbackArgs()).to.be.equal(callbackArgs);
        chai.expect(ItemsHolder.getDisplayChanges()).to.be.equal(displayChanges);
    });
});

describe("storage", function () {
    it("initializes values to a given valueDefault", function () {
        chai.expect(ItemsHolder.getItem("lives")).to.be.equal(3);
    });

    it("initializes values to a given value", function () {
        chai.expect(ItemsHolder.getItem("tries")).to.be.equal(0);
    });

    it("sets values", function () {
        ItemsHolder.setItem("tries", 3);
        chai.expect(ItemsHolder.getItem("tries")).to.be.equal(3);
    });

    it("increases values", function () {
        ItemsHolder.increase("tries");
        chai.expect(ItemsHolder.getItem("tries")).to.be.equal(4);
    });

    it("decreases values", function () {
        ItemsHolder.decrease("tries");
        chai.expect(ItemsHolder.getItem("tries")).to.be.equal(3);
    });

    it("toggles values", function () {
        ItemsHolder.toggle("tries");
        chai.expect(ItemsHolder.getItem("tries")).to.be.equal(false);
        ItemsHolder.toggle("tries");
        chai.expect(ItemsHolder.getItem("tries")).to.be.equal(true);
    });
});

describe("localStorage", function () {
    var storage = {};

    it("may take in a localStorage", function () {
        ItemsHolder = new ItemsHoldr.ItemsHoldr({
            "prefix": prefix,
            "autoSave": autoSave,
            "callbackArgs": callbackArgs,
            "values": values,
            "localStorage": storage
        });

        chai.expect(ItemsHolder.getLocalStorage()).to.be.equal(storage);
    });

    it("saves values", function () {
        ItemsHolder.saveAll();
        chai.expect(ItemsHolder.getLocalStorage()).to.be.deep.equal({
            "MyItemsHoldr::lives": "3",
            "MyItemsHoldr::tries": "0"
        });
    });

    it("retrieves values", function () {
        ItemsHolder = new ItemsHoldr.ItemsHoldr({
            "prefix": prefix,
            "autoSave": autoSave,
            "callbackArgs": callbackArgs,
            "values": values,
            "localStorage": storage
        });

        chai.expect(ItemsHolder.getItem("lives")).to.be.equal(3);
        chai.expect(ItemsHolder.getItem("tries")).to.be.equal(0);
    });
});

describe("HTML", function () {
    it("creates the container", function () {
        var container;

        values.lives.hasElement = true;
        values.tries.hasElement = true;

        ItemsHolder = new ItemsHoldr.ItemsHoldr({
            "prefix": prefix,
            "autoSave": autoSave,
            "callbackArgs": callbackArgs,
            "values": values,
            "displayChanges": displayChanges,
            "doMakeContainer": true,
            "containersArguments": [
                [
                    "div",
                    {
                        "id": "ContainerOut"
                    }
                ],
                [
                    "span",
                    {
                        "id": "ContainerIn"
                    }
                ]
            ]
        });

        container = ItemsHolder.getContainer();

        chai.expect(container).to.not.be.undefined;
        chai.expect(container.tagName).to.be.equal("DIV");
        chai.expect(container.id).to.be.equal("ContainerOut");
        chai.expect(container.children).to.have.length(1);
        chai.expect(container.children[0].tagName).to.be.equal("SPAN");
        chai.expect(container.children[0].id).to.be.equal("ContainerIn");
    });

    it("creates value elements", function () {
        var children = ItemsHolder.getContainer().children[0].children;

        chai.expect(children[0].className).to.be.equal("MyItemsHoldr::_value lives");
        chai.expect(children[1].className).to.be.equal("MyItemsHoldr::_value tries");

        chai.expect(children[0].children[0].innerText).to.be.equal("lives");
        chai.expect(children[1].children[0].innerText).to.be.equal("tries");

        chai.expect(children[0].children[1].innerText).to.be.equal("3");
        chai.expect(children[1].children[1].innerText).to.be.equal("0");
    });

    it("updates value elements", function () {
        var children = ItemsHolder.getContainer().children[0].children;

        ItemsHolder.setItem("lives", 7);
        ItemsHolder.setItem("tries", 1);

        chai.expect(children[0].children[1].innerText).to.be.equal("7");
        chai.expect(children[1].children[1].innerText).to.be.equal("1");
    });
});<|endoftext|>


<commit_before>

/*
 *   Version 1 (path.js routing)
 *   URL router for maping urls to "views".
 */

function router() {
    // App routes
    /*
    Path.map("#/seq-search").to(function(){
        seq_search_view();
    }).enter(navEvent);
    */

    Path.map("#/workspace-browser").to(function(){
        workspace_view();
    }).enter(navEvent);

    // Data routes
    Path.map("#/genomes")
        .to(function() {
            genome_view();
        })
        .enter(navEvent)
        .exit(removeCards);

    Path.map("#/genomes/cs/:genome_id")
        .to(function(){
            genome_view({'genomeID': this.params['genome_id']});
        })
        .enter(navEvent)
        .exit(removeCards);

    Path.map("#/genomes/:ws_id")
        .to(function() {
            genome_view({'workspaceID': this.params['ws_id']});
        })
        .enter(navEvent)
        .exit(removeCards);

    Path.map("#/genomes/:ws_id/:genome_id")
        .to(function() {
            genome_view(
                {
                    'workspaceID': this.params['ws_id'],
                    'genomeID': this.params['genome_id']
                }
            );
        })
        .enter(navEvent)
        .exit(removeCards);

    Path.map("#/organisms").to(function(){ empty_page() });

    Path.map("#/models").to(function(){
        ws_model_view();
    }).enter(navEvent);

    Path.map("#/models/:ws_id").to(function(){
        ws_model_view(this.params['ws_id']);
    }).enter(navEvent);

    Path.map("#/models/:ws_id/:id").to(function(){
        model_view(this.params['ws_id'], this.params['id']);
    }).enter(navEvent);

    Path.map("#/fbas").to(function(){
        ws_fba_view() ;
    }).enter(navEvent);

    Path.map("#/fbas/:ws_id").to(function(){
        ws_fba_view(this.params['ws_id']) ;
    }).enter(navEvent);

    Path.map("#/fbas/:ws_id/:id").to(function(){
        fba_view(this.params['ws_id'], this.params['id'])
    }).enter(navEvent);

    Path.map("#/rxns").to(function(){
        rxn_view();
    }).enter(navEvent);

    Path.map("#/rxns/:ws_id/:id").to(function(){ empty_page() });

    Path.map("#/cpds").to(function(){
        cpd_view();
    }).enter(navEvent);

    Path.map("#/cpds/:ws_id/:id").to(function(){ empty_page() });

    Path.map("#/media").to(function(){
        ws_media_view();
    }).enter(navEvent);

    Path.map("#/media/:ws_id").to(function(){
        ws_media_view(this.params['ws_id']);
    }).enter(navEvent);

    Path.map("#/media/:ws_id/:id").to(function(){
        media_view(this.params['ws_id'], this.params['id']);
    }).enter(navEvent);

    // analysis Routes
    Path.map("#/run-fba/:ws_id/:id").to(function(){
        run_fba_view(this.params['ws_id'], this.params['id']);
    }).enter(navEvent);

    // help page route
    Path.map("#/data-view-api").to(function(){
        help_view();
    }).enter(navEvent);

    Path.rescue(function(){
        page_not_found();
    })

    Path.root("#/data-view-api");
    Path.listen();
}

// Version 2 (angular routing)

$routeProvider
    .when('/workspace-browser',
        {templateUrl: 'views/ws-browser.html',
         controller: WSBrowser})

    .when('/genomes/CDS/:id',
        {templateUrl: 'views/objects/genome.html',
         controller: GenomeDetail})
    .when('/genomes/:ws',
        {templateUrl: 'views/objects/genome.html',
         controller: GenomeDetail})
    .when('/genomes/:ws/:id',
        {templateUrl: 'views/objects/genome.html',
         controller: GenomeDetail})

    .when('/genes/CDS/:id',
        {templateUrl: 'views/objects/gene.html',
         controller: GeneDetail })
    .when('/genes/:ws/:id',
        {templateUrl: 'views/objects/gene.html',
         controller: GeneDetail })

    .when('/models',
        {templateUrl: 'views/object-list.html',
         controller: WSObjects})
    .when('/models/:ws',
        {templateUrl: 'views/object-list.html',
         controller: WSObjects})
    .when('/models/:ws/:id',
        {templateUrl: 'views/objects/model.html',
         controller: ModelDetail})
    .when('/cards/models/:ws/:id',
        {templateUrl: 'views/objects/modelcards.html',
         controller: ModelDetailCards})

    .when('/media',
        {templateUrl: 'views/object-list.html',
         controller: WSObjects})
    .when('/media/:ws',
        {templateUrl: 'views/object-list.html',
         controller: WSObjects})
    .when('/media/:ws/:id',
        {templateUrl: 'views/objects/media.html',
         controller: MediaDetail})

    .when('/fbas/:ws',
        {templateUrl: 'views/object-list.html',
         controller: WSObjects})
    .when('/fbas/:ws/:id',
        {templateUrl: 'views/objects/fba.html',
         controller: FBADetail})
    .when('/cards/fbas/:ws/:id',
        {templateUrl: 'views/objects/fbacards.html',
         controller: FBADetailCards})

    .when('/rxns',
        {templateUrl: 'views/object-list.html',
         controller: WSObjects})
    .when('/rxns/:ids',
        {templateUrl: 'views/objects/rxn.html',
         controller: RxnDetail})
    .when('/rxns/:ws/:ids',
        {templateUrl: 'views/objects/coming-soon.html',
         controller: RxnDetail})

    .when('/cpds',
        {templateUrl: 'views/object-list.html',
         controller: WSObjects})
    .when('/cpds/:ids',
        {templateUrl: 'views/objects/cpd.html',
         controller: CpdDetail})

    .when('/meme',
        {templateUrl: 'views/meme-list.html',
         controller: WSObjects})
    .when('/meme/:ws',
        {templateUrl: 'views/meme-list.html',
         controller: WSObjects})
    .when('/meme/:ws/:id',
        {templateUrl: 'views/objects/meme.html',
         controller: MemeDetail})

    .when('/spec/:kind/:id',
        {templateUrl: 'views/objects/spec.html',
         controller: SpecDetail})

    .when('/bambi/:ws/:id',
        {templateUrl: 'views/objects/bambi.html',
         controller: BambiDetail})

    .when('/iris',
        {templateUrl: 'views/iris.html',
         controller: IRIS})

    .when('/landing-pages-help',
        {templateUrl: 'views/landing-pages-help.html',
         controller: LPHelp})

    .when('/404',
        {templateUrl: 'views/404.html'})

    .when('/',
        {templateUrl: 'views/landing-pages-help.html',
         controller: LPHelp})

    .otherwise({redirectTo: '/404'})

<commit_msg>removing old file<commit_after><|endoftext|>


<commit_before>import { assign } from '@ember/polyfills';
import { inject as service } from '@ember/service';
import ApplicationSerializer from './application';

export default ApplicationSerializer.extend({
  config: service(),

  attrs: {
    isDraining: 'Drain',
    httpAddr: 'HTTPAddr',
  },

  normalize(modelClass, hash) {
    // Transform map-based objects into an array-based fragment lists
    const drivers = hash.Drivers || {};
    hash.Drivers = Object.keys(drivers).map(key => {
      return assign({}, drivers[key], { Name: key });
    });

    const hostVolumes = hash.HostVolumes || {};
    hash.HostVolumes = Object.keys(hostVolumes).map(key => hostVolumes[key]);

    return this._super(modelClass, hash);
  },

  extractRelationships(modelClass, hash) {
    const { modelName } = modelClass;
    const nodeURL = this.store
      .adapterFor(modelName)
      .buildURL(modelName, this.extractId(modelClass, hash), hash, 'findRecord');

    return {
      allocations: {
        links: {
          related: `${nodeURL}/allocations`,
        },
      },
    };
  },
});
<commit_msg>Fix a bug where the NodeListStub API response would override existing HostVolumes in the store<commit_after>import { assign } from '@ember/polyfills';
import { inject as service } from '@ember/service';
import ApplicationSerializer from './application';

export default ApplicationSerializer.extend({
  config: service(),

  attrs: {
    isDraining: 'Drain',
    httpAddr: 'HTTPAddr',
  },

  normalize(modelClass, hash) {
    // Transform map-based objects into an array-based fragment lists
    const drivers = hash.Drivers || {};
    hash.Drivers = Object.keys(drivers).map(key => {
      return assign({}, drivers[key], { Name: key });
    });

    if (hash.HostVolumes) {
      const hostVolumes = hash.HostVolumes;
      hash.HostVolumes = Object.keys(hostVolumes).map(key => hostVolumes[key]);
    }

    return this._super(modelClass, hash);
  },

  extractRelationships(modelClass, hash) {
    const { modelName } = modelClass;
    const nodeURL = this.store
      .adapterFor(modelName)
      .buildURL(modelName, this.extractId(modelClass, hash), hash, 'findRecord');

    return {
      allocations: {
        links: {
          related: `${nodeURL}/allocations`,
        },
      },
    };
  },
});
<|endoftext|>


<commit_before>'use strict';
/**
 * This code represents the Attribute Pool Object of the original Etherpad.
 * 90% of the code is still like in the original Etherpad
 * Look at https://github.com/ether/pad/blob/master/infrastructure/ace/www/easysync2.js
 * You can find a explanation what a attribute pool is here:
 * https://github.com/ether/etherpad-lite/blob/master/doc/easysync/easysync-notes.txt
 */

/*
 * Copyright 2009 Google Inc., 2011 Peter 'Pita' Martischka (Primary Technology Ltd)
 *
 * 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.
 */

/*
  An AttributePool maintains a mapping from [key,value] Pairs called
  Attributes to Numbers (unsigened integers) and vice versa. These numbers are
  used to reference Attributes in Changesets.
*/

const AttributePool = function () {
  this.numToAttrib = {}; // e.g. {0: ['foo','bar']}
  this.attribToNum = {}; // e.g. {'foo,bar': 0}
  this.nextNum = 0;
};

AttributePool.prototype.putAttrib = function (attrib, dontAddIfAbsent) {
  const str = String(attrib);
  if (str in this.attribToNum) {
    return this.attribToNum[str];
  }
  if (dontAddIfAbsent) {
    return -1;
  }
  const num = this.nextNum++;
  this.attribToNum[str] = num;
  this.numToAttrib[num] = [String(attrib[0] || ''), String(attrib[1] || '')];
  return num;
};

AttributePool.prototype.getAttrib = function (num) {
  const pair = this.numToAttrib[num];
  if (!pair) {
    return pair;
  }
  return [pair[0], pair[1]]; // return a mutable copy
};

AttributePool.prototype.getAttribKey = function (num) {
  const pair = this.numToAttrib[num];
  if (!pair) return '';
  return pair[0];
};

AttributePool.prototype.getAttribValue = function (num) {
  const pair = this.numToAttrib[num];
  if (!pair) return '';
  return pair[1];
};

AttributePool.prototype.eachAttrib = function (func) {
  for (const n of this.numToAttrib) {
    const pair = this.numToAttrib[n];
    func(pair[0], pair[1]);
  }
};

AttributePool.prototype.toJsonable = function () {
  return {
    numToAttrib: this.numToAttrib,
    nextNum: this.nextNum,
  };
};

AttributePool.prototype.fromJsonable = function (obj) {
  this.numToAttrib = obj.numToAttrib;
  this.nextNum = obj.nextNum;
  this.attribToNum = {};
  for (const n of this.numToAttrib) {
    this.attribToNum[String(this.numToAttrib[n])] = Number(n);
  }
  return this;
};

module.exports = AttributePool;
<commit_msg>lint: attributepool fix incorrect commit<commit_after>'use strict';
/**
 * This code represents the Attribute Pool Object of the original Etherpad.
 * 90% of the code is still like in the original Etherpad
 * Look at https://github.com/ether/pad/blob/master/infrastructure/ace/www/easysync2.js
 * You can find a explanation what a attribute pool is here:
 * https://github.com/ether/etherpad-lite/blob/master/doc/easysync/easysync-notes.txt
 */

/*
 * Copyright 2009 Google Inc., 2011 Peter 'Pita' Martischka (Primary Technology Ltd)
 *
 * 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.
 */

/*
  An AttributePool maintains a mapping from [key,value] Pairs called
  Attributes to Numbers (unsigened integers) and vice versa. These numbers are
  used to reference Attributes in Changesets.
*/

const AttributePool = function () {
  this.numToAttrib = {}; // e.g. {0: ['foo','bar']}
  this.attribToNum = {}; // e.g. {'foo,bar': 0}
  this.nextNum = 0;
};

AttributePool.prototype.putAttrib = function (attrib, dontAddIfAbsent) {
  const str = String(attrib);
  if (str in this.attribToNum) {
    return this.attribToNum[str];
  }
  if (dontAddIfAbsent) {
    return -1;
  }
  const num = this.nextNum++;
  this.attribToNum[str] = num;
  this.numToAttrib[num] = [String(attrib[0] || ''), String(attrib[1] || '')];
  return num;
};

AttributePool.prototype.getAttrib = function (num) {
  const pair = this.numToAttrib[num];
  if (!pair) {
    return pair;
  }
  return [pair[0], pair[1]]; // return a mutable copy
};

AttributePool.prototype.getAttribKey = function (num) {
  const pair = this.numToAttrib[num];
  if (!pair) return '';
  return pair[0];
};

AttributePool.prototype.getAttribValue = function (num) {
  const pair = this.numToAttrib[num];
  if (!pair) return '';
  return pair[1];
};

AttributePool.prototype.eachAttrib = function (func) {
  for (const n of Object.keys(this.numToAttrib)) {
    const pair = this.numToAttrib[n];
    func(pair[0], pair[1]);
  }
};

AttributePool.prototype.toJsonable = function () {
  return {
    numToAttrib: this.numToAttrib,
    nextNum: this.nextNum,
  };
};

AttributePool.prototype.fromJsonable = function (obj) {
  this.numToAttrib = obj.numToAttrib;
  this.nextNum = obj.nextNum;
  this.attribToNum = {};
  for (const n of Object.keys(this.numToAttrib)) {
    this.attribToNum[String(this.numToAttrib[n])] = Number(n);
  }
  return this;
};

module.exports = AttributePool;
<|endoftext|>


<commit_before>function ConcourseClient(base_url) {
    var self = this;

    /**
     * Client-supplied callback. Called when there is a likely authentication failure.
     *
     * @param reason an HTML string describing the auth failure.
     */
    this.onAuthError = null;

    function xhrGet(url, onSuccess) {
        xhrGetWithHeaders(url, {}, onSuccess);
    }

    function xhrGetWithHeaders(url, headers, onSuccess) {
        var xhr = new XMLHttpRequest();

        xhr.addEventListener("load", function(evt) {
            if (this.status == 401) {
                self.onAuthError("Authorization Error")
            }
            var responseJson = JSON.parse(this.responseText);
            onSuccess(responseJson);
        });
        xhr.addEventListener("error", function(evt) { console.log("Error in XHR", evt) });
        xhr.addEventListener("abort", function(evt) { console.log("XHR aborted", evt) });

        if (url.startsWith("/")) {
            url = base_url + url;
        }

        xhr.open("GET", url);

        for (var header in headers) {
            if (headers.hasOwnProperty(header)) {
                xhr.setRequestHeader(header, headers[header]);
            }
        }

        xhr.send();
    }

    this.auth = function(username, password, onSuccess) {
        var token = "Basic " + btoa(username + ":" + password);
        xhrGetWithHeaders("/api/v1/teams/main/auth/token", {"Authorization": token}, function(responseJson) {
            if (onSuccess != undefined) {
                onSuccess(responseJson);
            }
        });
    }

    this.getPipelines = function(onSuccess) {
        xhrGet("/api/v1/pipelines", function(pipelines) {
            if (pipelines.length == 0) {
                self.onAuthError("No pipelines found.")
                return;
            }

            pipelines = pipelines.filter(function(p) { return !p.paused; });

            var result = [];
            function appendResult(pipelineResult) {
                result.push(pipelineResult);
                if (result.length === pipelines.length) {
                    onSuccess(result);
                }
            }

            for (var i = 0; i < pipelines.length; i++) {
                let p = pipelines[i];
                if (p.paused) { continue; }

                xhrGet("/api/v1/teams/main/pipelines/" + encodeURIComponent(p.name) + "/jobs", function(jobs) {
                    var newestFailureTime = 0;
                    var newestRunningTime = 0;
                    var newestSuccessTime = 0;
                    for (var i = 0; i < jobs.length; i++) {
                        var job = jobs[i];

                        var finishedBuild = job["finished_build"];
                        if (finishedBuild != null) {
                            if (finishedBuild.status === "failed" || finishedBuild.status === "errored") {
                                newestFailureTime = Math.max(newestFailureTime, finishedBuild["end_time"]);
                            } else if (finishedBuild.status === "succeeded") {
                                newestSuccessTime = Math.max(newestSuccessTime, finishedBuild["end_time"]);
                            }
                        }

                        var nextBuild = job["next_build"];
                        if (nextBuild != null) {
                            newestRunningTime = Math.max(newestRunningTime, nextBuild["start_time"]);
                        }
                    }
                    appendResult({
                        "name": p.name,
                        "jobs": jobs,
                        "newestFailureTime": newestFailureTime,
                        "newestRunningTime": newestRunningTime,
                        "newestSuccessTime": newestSuccessTime
                    });
                });
            }
        });
    }
}
<commit_msg>Order stages according to dependencies; put singles on right<commit_after>function ConcourseClient(base_url) {
    var self = this;

    /**
     * Client-supplied callback. Called when there is a likely authentication failure.
     *
     * @param reason an HTML string describing the auth failure.
     */
    this.onAuthError = null;

    function xhrGet(url, onSuccess) {
        xhrGetWithHeaders(url, {}, onSuccess);
    }

    function xhrGetWithHeaders(url, headers, onSuccess) {
        var xhr = new XMLHttpRequest();

        xhr.addEventListener("load", function(evt) {
            if (this.status == 401) {
                self.onAuthError("Authorization Error")
            }
            var responseJson = JSON.parse(this.responseText);
            onSuccess(responseJson);
        });
        xhr.addEventListener("error", function(evt) { console.log("Error in XHR", evt) });
        xhr.addEventListener("abort", function(evt) { console.log("XHR aborted", evt) });

        if (url.startsWith("/")) {
            url = base_url + url;
        }

        xhr.open("GET", url);

        for (var header in headers) {
            if (headers.hasOwnProperty(header)) {
                xhr.setRequestHeader(header, headers[header]);
            }
        }

        xhr.send();
    }

    this.auth = function(username, password, onSuccess) {
        var token = "Basic " + btoa(username + ":" + password);
        xhrGetWithHeaders("/api/v1/teams/main/auth/token", {"Authorization": token}, function(responseJson) {
            if (onSuccess != undefined) {
                onSuccess(responseJson);
            }
        });
    }

    this.getPipelines = function(onSuccess) {
        xhrGet("/api/v1/pipelines", function(pipelines) {
            if (pipelines.length == 0) {
                self.onAuthError("No pipelines found.")
                return;
            }

            pipelines = pipelines.filter(function(p) { return !p.paused; });

            var result = [];
            function appendResult(pipelineResult) {
                result.push(pipelineResult);
                if (result.length === pipelines.length) {
                    onSuccess(result);
                }
            }

            for (var i = 0; i < pipelines.length; i++) {
                let p = pipelines[i];
                if (p.paused) { continue; }

                xhrGet("/api/v1/teams/main/pipelines/" + encodeURIComponent(p.name) + "/jobs", function(jobs) {
                    var newestFailureTime = 0;
                    var newestRunningTime = 0;
                    var newestSuccessTime = 0;
                    for (var i = 0; i < jobs.length; i++) {
                        var job = jobs[i];

                        var finishedBuild = job["finished_build"];
                        if (finishedBuild != null) {
                            if (finishedBuild.status === "failed" || finishedBuild.status === "errored") {
                                newestFailureTime = Math.max(newestFailureTime, finishedBuild["end_time"]);
                            } else if (finishedBuild.status === "succeeded") {
                                newestSuccessTime = Math.max(newestSuccessTime, finishedBuild["end_time"]);
                            }
                        }

                        var nextBuild = job["next_build"];
                        if (nextBuild != null) {
                            newestRunningTime = Math.max(newestRunningTime, nextBuild["start_time"]);
                        }
                    }

                    appendResult({
                        "name": p.name,
                        "jobs": self.orderedJobs(jobs),
                        "newestFailureTime": newestFailureTime,
                        "newestRunningTime": newestRunningTime,
                        "newestSuccessTime": newestSuccessTime
                    });
                });
            }
        });
    }

    this.orderedJobs = function(jobs) {
        var nameDepths = {};
        var parentNames = {};
        var toPlace = jobs;
        for (var level = 0; toPlace.length > 0; level++) {
            var keys = Object.keys(nameDepths);
            var placeNext = [];
            toPlace.forEach(function(job) {
                var passedNames = [];
                job["inputs"].forEach(function(input) {
                    if ("passed" in input) {
                        passedNames = passedNames.concat(input["passed"]);
                        input["passed"].forEach(function(name) {
                            parentNames[name] = 1;
                        });
                    }
                });

                var diff = passedNames.filter(function(passedName) { return keys.indexOf(passedName) < 0 });
                if (diff.length == 0) {
                    nameDepths[job["name"]] = level;
                } else {
                    placeNext.push(job);
                }
            });
            toPlace = placeNext;
        }

        var jobsByName = {};
        jobs.forEach(function(job) {
            jobsByName[job["name"]] = job;
        });

        var ordered = [];
        var noChildren = [];
        for (level = 0; Object.keys(nameDepths).length > 0; level++) {
            Object.keys(nameDepths).forEach(function(key) {
                if (nameDepths[key] == level) {
                    var job = jobsByName[key];
                    if (job["name"] in parentNames || level > 0) {
                        ordered.push(job);
                    } else {
                        noChildren.push(job);
                    }
                    delete nameDepths[key];
                }
            });
        }
        return ordered.concat(noChildren);
    }
}
<|endoftext|>


<commit_before>var currentCommentID;

function show_comment_list()
{
	$('comment-list').show();
	$('add-comment').hide();
	$('show-comment-link').addClassName("active");
	$('add-comment-link').removeClassName("active");
	$('all-comments-link').removeClassName("active");
	show_comments_in_list(currentCommentID);
}

function show_all_comments()
{
	$('comment-list').show();
	$('add-comment').hide();
	$('show-comment-link').removeClassName("active");
	$('add-comment-link').removeClassName("active");
	$('all-comments-link').addClassName("active");
	show_comments_in_list();
}

function show_add_comment()
{
	$('comment-list').hide();
	$('add-comment').show();
	$('show-comment-link').removeClassName("active");
	$('add-comment-link').addClassName("active");
	$('all-comments-link').removeClassName("active");
}

function hide_add_comment()
{
	$('user-comments').hide();
	$('modal-background').hide();
	$(content_textare_id).value = '';
	$(currentCommentID).style.zIndex = 0;
}

function show_comments_in_list(id)
{
	var list = $('comment-list');
	var count=0;
	for(var i=0, k=list.childNodes.length; i < k; i++)
	{
		var node = list.childNodes[i];
		if(node.nodeType == 1) //an element node
		{
			if(typeof(id) == "undefined" || node.className.indexOf(id) >= 0)
			{
				node.style.display="block"
				count++;
			}
			else
				node.style.display="none";
		}
	}
	return count;
}

function show_comments(block)
{
	var id = block.id
	currentCommentID = id;
	$(hidden_block_id).value = id;
	var commentBlock = $('user-comments');
	var pos = Position.cumulativeOffset(block);
	var top = pos[1] + block.offsetHeight;
	commentBlock.style.top = top+"px";
	commentBlock.style.width = (block.offsetWidth-22)+"px";

	commentBlock.show();

	var count = show_comments_in_list(id);

	$('comment-list').show();
	if(count > 0)
		show_comment_list();
	else
		show_add_comment();

	var background = $('modal-background');
	background.style.top="0px";
	background.style.left="0px";
	background.style.opacity="0.5";
	background.style.width = document.body.offsetWidth+"px";
	background.style.height = document.body.offsetHeight+"px";
	background.show();
	block.style.zIndex = 100;
	block.style.paddingRight="9px";
	block.style.marginRight="-9px";

}

function show_block(block)
{
	while(block && block.className && block.className.indexOf("block-content") < 0)
		block = block.parentNode;
	if(block && block.className && block.className.indexOf("block-content") >= 0)
	{
		block.addClassName('block-hover');
		var tag = $('tag-'+block.id);
//		if(tag.className.indexOf("tag-shown")<=0)
			tag.firstChild.style.visibility="visible"
	}
}

function hide_block(block)
{
	while(block && block.className && block.className.indexOf("block-hover") < 0)
		block = block.parentNode;
	if(block && block.className && block.className.indexOf("block-hover") >= 0)
	{
		block.removeClassName('block-hover');
		var tag = $('tag-'+block.id);
		if(tag.className.indexOf("tag-shown")<=0)
			tag.firstChild.style.visibility="hidden"
	}
}

function add_comment_tag(el)
{
	var dim = Element.getDimensions(el);
	var comments = get_comment_count(el.id);
	var style = "height:"+(dim.height > 35 ? dim.height : 35)+"px;";
	var cssClass = dim.height ? "block-comment-tag" : "block-comment-tag-ie";
	var title = "View "+comments+" comments"
	var innerStyle="";
	if(comments <= 0)
	{
		innerStyle = " visibility:hidden;";
		comments = "add";
		title = "Add new comment";
	}
	else
		cssClass += " tag-shown";
	var id = "tag-"+el.id;
	var tag = "

"+comments+"

";
	new Insertion.Before(el, tag);
	var tag_div = $(id);
	Event.observe(tag_div, "mouseover", function(e){ if(typeof(show_block)!="undefined") show_block(el); });
	Event.observe(tag_div, "mouseout", function(e){ if(typeof(hide_block) !="undefined") hide_block(el); });
	Event.observe(tag_div, "click", function(e) { if(typeof(show_comments) !="undefined") show_comments(el); Event.stop(e); });
}

function increment_count_tag(id)
{
	var tag = $('tag-'+id);
	if(tag && tag.firstChild)
	{
		if(tag.className.indexOf("tag-shown") >= 0)
		{
			var count = Number(tag.firstChild.innerHTML);
			tag.firstChild.innerHTML = (++count)+"";
			tag.firstChild.style.visibility="visible";
		}
		else
		{
			tag.firstChild.innerHTML = "1";
			tag.addClassName("tag-shown");
			tag.firstChild.style.visibility="visible";
		}
	}
}

function get_comment_count(id)
{
	return comment_count[id] ? comment_count[id] : 0;
}

//initialize the comment js

if(!Prado.Browser.ie) //not IE 4,5,6
{
	(function()
	{
		var userComments = $('user-comments');
		userComments.style.position="absolute";
		userComments.style.marginRight="80px";
		var commentList = $('comment-list');
		commentList.style.height="320px";
		$('add-comment').style.height="320px";
		commentList.style.overflow="auto";
		$('show-comment-link').style.display="";
		$('to-top').hide();
		$('close-comments').show();
		$('all-comments-link').show();
		userComments.hide();
		$('comments-header').hide();

		$$('#comment-list .source-link').each(function(el){ el.hide(); });

		$$('#content .block-content').each(function(el)
		{
			Event.observe(el, 'mouseover', function(e){ if(typeof(show_block)!="undefined") show_block(Event.element(e)); });
			Event.observe(el, 'mouseout', function(e){ if(typeof(hide_block)!="undefined") hide_block(Event.element(e)); });
			add_comment_tag(el);
		});

		Event.observe($('show-comment-link'), "click", function(e) { show_comment_list(); Event.stop(e); });
		Event.observe($('add-comment-link'), "click", function(e) { show_add_comment();	Event.stop(e); });
		Event.observe($('all-comments-link'), "click", function(e) { show_all_comments();	Event.stop(e); });
		Event.observe($('close-comments'), "click", function(e) { hide_add_comment(); Event.stop(e); });

	})();
}<commit_msg>fix #564, take 2<commit_after>var currentCommentID;

function show_comment_list()
{
	$('comment-list').show();
	$('add-comment').hide();
	$('show-comment-link').addClassName("active");
	$('add-comment-link').removeClassName("active");
	$('all-comments-link').removeClassName("active");
	show_comments_in_list(currentCommentID);
}

function show_all_comments()
{
	$('comment-list').show();
	$('add-comment').hide();
	$('show-comment-link').removeClassName("active");
	$('add-comment-link').removeClassName("active");
	$('all-comments-link').addClassName("active");
	show_comments_in_list();
}

function show_add_comment()
{
	$('comment-list').hide();
	$('add-comment').show();
	$('show-comment-link').removeClassName("active");
	$('add-comment-link').addClassName("active");
	$('all-comments-link').removeClassName("active");
}

function hide_add_comment()
{
	$('user-comments').hide();
	$('modal-background').hide();
	$(content_textare_id).value = '';
	$(currentCommentID).style.zIndex = 0;
}

function show_comments_in_list(id)
{
	var list = $('comment-list');
	var count=0;
	for(var i=0, k=list.childNodes.length; i < k; i++)
	{
		var node = list.childNodes[i];
		if(node.nodeType == 1) //an element node
		{
			if(typeof(id) == "undefined" || node.className.indexOf(id) >= 0)
			{
				node.style.display="block"
				count++;
			}
			else
				node.style.display="none";
		}
	}
	return count;
}

function show_comments(block)
{
	var id = block.id
	currentCommentID = id;
	$(hidden_block_id).value = id;
	var commentBlock = $('user-comments');
	var pos = Position.cumulativeOffset(block);
	var top = pos[1] + block.offsetHeight;
	commentBlock.style.top = top+"px";
	commentBlock.style.width = (block.offsetWidth-22)+"px";

	commentBlock.show();

	var count = show_comments_in_list(id);

	$('comment-list').show();
	if(count > 0)
		show_comment_list();
	else
		show_add_comment();

	var background = $('modal-background');
	background.style.top="0px";
	background.style.left="0px";
	background.style.opacity="0.5";
	background.style.width = document.body.offsetWidth+"px";
	background.style.height = document.body.offsetHeight+"px";
	background.show();
	block.style.zIndex = 100;
	block.style.paddingRight="9px";
	block.style.marginRight="-9px";

}

function show_block(block)
{
	while(block && block.className.indexOf("block-content") < 0)
		block = block.parentNode;
	if(block && block.className.indexOf("block-content") >= 0)
	{
		block.addClassName('block-hover');
		var tag = $('tag-'+block.id);
//		if(tag.className.indexOf("tag-shown")<=0)
			tag.firstChild.style.visibility="visible"
	}
}

function hide_block(block)
{
	while(block && block.className.indexOf("block-hover") < 0)
		block = block.parentNode;
	if(block && block.className.indexOf("block-hover") >= 0)
	{
		block.removeClassName('block-hover');
		var tag = $('tag-'+block.id);
		if(tag.className.indexOf("tag-shown")<=0)
			tag.firstChild.style.visibility="hidden"
	}
}

function add_comment_tag(el)
{
	var dim = Element.getDimensions(el);
	var comments = get_comment_count(el.id);
	var style = "height:"+(dim.height > 35 ? dim.height : 35)+"px;";
	var cssClass = dim.height ? "block-comment-tag" : "block-comment-tag-ie";
	var title = "View "+comments+" comments"
	var innerStyle="";
	if(comments <= 0)
	{
		innerStyle = " visibility:hidden;";
		comments = "add";
		title = "Add new comment";
	}
	else
		cssClass += " tag-shown";
	var id = "tag-"+el.id;
	var tag = "

"+comments+"

";
	new Insertion.Before(el, tag);
	var tag_div = $(id);
	Event.observe(tag_div, "mouseover", function(e){ if(typeof(show_block)!="undefined") show_block(el); });
	Event.observe(tag_div, "mouseout", function(e){ if(typeof(hide_block) !="undefined") hide_block(el); });
	Event.observe(tag_div, "click", function(e) { if(typeof(show_comments) !="undefined") show_comments(el); Event.stop(e); });
}

function increment_count_tag(id)
{
	var tag = $('tag-'+id);
	if(tag && tag.firstChild)
	{
		if(tag.className.indexOf("tag-shown") >= 0)
		{
			var count = Number(tag.firstChild.innerHTML);
			tag.firstChild.innerHTML = (++count)+"";
			tag.firstChild.style.visibility="visible";
		}
		else
		{
			tag.firstChild.innerHTML = "1";
			tag.addClassName("tag-shown");
			tag.firstChild.style.visibility="visible";
		}
	}
}

function get_comment_count(id)
{
	return comment_count[id] ? comment_count[id] : 0;
}

//initialize the comment js

if(!Prado.Browser.ie) //not IE 4,5,6
{
	Event.OnLoad(function()
	{
		var userComments = $('user-comments');
		userComments.style.position="absolute";
		userComments.style.marginRight="80px";
		var commentList = $('comment-list');
		commentList.style.height="320px";
		$('add-comment').style.height="320px";
		commentList.style.overflow="auto";
		$('show-comment-link').style.display="";
		$('to-top').hide();
		$('close-comments').show();
		$('all-comments-link').show();
		userComments.hide();
		$('comments-header').hide();

		$$('#comment-list .source-link').each(function(el){ el.hide(); });

		$$('#content .block-content').each(function(el)
		{
			Event.observe(el, 'mouseover', function(e){ if(typeof(show_block)!="undefined") show_block(Event.element(e)); });
			Event.observe(el, 'mouseout', function(e){ if(typeof(hide_block)!="undefined") hide_block(Event.element(e)); });
			add_comment_tag(el);
		});

		Event.observe($('show-comment-link'), "click", function(e) { show_comment_list(); Event.stop(e); });
		Event.observe($('add-comment-link'), "click", function(e) { show_add_comment();	Event.stop(e); });
		Event.observe($('all-comments-link'), "click", function(e) { show_all_comments();	Event.stop(e); });
		Event.observe($('close-comments'), "click", function(e) { hide_add_comment(); Event.stop(e); });

	});
}<|endoftext|>


<commit_before>var fs = require('fs-extra'),
    path = require('path'),
    util = require('util'),
    fm = require('front-matter'),
    gutil = require('gulp-util'),
    through = require('through2'),
    swig = require('./swig.js'),
    time = require('microtime'),
    htmlmin = require('html-minifier').minify,
    _s = require('underscore.string');

var base = process.cwd() + '/tmp';

//////////////////////////////
// Get a list of directories
//////////////////////////////
var inspect = function (object) {
  console.log(util.inspect(object, false, null));
}

var makeTitle = function makeTitle (string) {
  return _s.titleize(_s.humanize(string)).replace('Ui ', 'UI ').replace('Input ', 'Input - ').replace(/^([0-9]+\s)/g, '');
}

var processDirs = function processDirs (files, base) {
  var results = {
    'dirs': {},
    'index': false,
    'base': base
  };

  if (files.indexOf('index.md') >= 0 || files.indexOf('index.html') >= 0) {
    results.index = true;
  }

  files.forEach(function (file) {
    var dir = path.resolve(base, file),
        name = makeTitle(file);
    dir = fs.statSync(dir);
    if (dir.isDirectory()) {
      results.dirs[file] = {
        'title': name
      };
    }
  });

  return results;
}

var getdirs = function getDirs (base, cb) {
  fs.readdir(base, function (err, files) {
    var results;

    if (err) {
      throw err;
    }

    results = processDirs(files, base);

    cb(err, results);
  });
};

var getdirsSync = function (base) {
  var files = fs.readdirSync(base),
      reults;

  return processDirs(files, base);
}

var writeRedirectIndex = function writeRedirectIndex(redirect, title) {
  var refreshIndex = '<!DOCTYPE html><meta http-equiv="refresh" content="0; url={{redirect}}" /><meta charset="UTF-8" /><title>Redirect</title>
The first available page for <strong`>{{title}}</strong`> is {{redirect}}
';

  var url = redirect.split('/'),
      redirPrts = [],
      urlPrts = [];

  if (url.length > 1) {
    url.pop();
    if (url[0] === '') {
      url.shift();
    }
  }

  url.forEach(function (urlp) {
    urlPrts.push(urlp.replace(/^([0-9]+\-)/g, ''));
  });

  redirect.split('/').forEach(function (redirp) {
    redirPrts.push(redirp.replace(/^([0-9]+\-)/g, ''));
  });

  url = urlPrts.join('/');
  redirect = redirPrts.join('/');

  refreshIndex = refreshIndex.replace(/\{\{redirect\}\}/g, redirect);
  refreshIndex = refreshIndex.replace(/\{\{title\}\}/g, title);

  fs.outputFile(process.cwd() + '/www/' + url + '/index.html', refreshIndex, function (err) {
    if (err) throw err;
    // gutil.log('Wrote ' + gutil.colors.magenta(url) + ' to redirect ' + gutil.colors.cyan(title));
  });
}

module.exports = function (options, cb) {
  options = options || {};

  var fin = {},
    mainNav = {},
    menu,
    absoluteMenu = {},
    start = time.now(),
    end;

  // fin['index'] = {
  //   'index': process.cwd() + '/tmp/index.html'
  // };

  fs.readFile(process.cwd() + '/tmp/index.html', 'utf-8', function (err, content) {
    if (err) throw err;

    fs.outputFile(process.cwd() + '/www/index.html', contentBuild(content), function (err) {
      if (err) throw err;
    });
  });

  getdirs(process.cwd() + '/tmp', function (err, dirs) {
    var key,
        mainNavBuild = [],
        index = false,
        section;

    menu = dirs.dirs;

    Object.keys(menu).forEach(function (dir) {
      fin[dir] = {};

      dir.split('/').forEach(function (dirPrt) {
        mainNavBuild.push(dirPrt.replace(/^([0-9]+\-)/g, ''));
      });

      mainNav[dir] = {
        'title': menu[dir].title,
        'url': mainNavBuild.join('/')
      }

      mainNavBuild = [];
    });

    Object.keys(menu).forEach(function (dir) {

      getdirs(base + '/' + dir, function (err, sections) {
        key = sections.base.split('/');
        key = key[key.length - 1];

        menu[key].sections = sections.dirs;

        if (sections.index === false) {
          writeRedirectIndex('/' + key + '/' + Object.keys(menu[key].sections)[0], menu[key].title);
        }

        Object.keys(sections.dirs).forEach(function (section) {
          var subsections = getdirsSync(base + '/' + key + '/' + section),
              render = 0,
              subnav = [],
              i,
              subnav;

          Object.keys(subsections.dirs).forEach(function (subsection) {
            var menuItem = {};

            menuItem.title = subsections.dirs[subsection].title;
            menuItem.url = '/' + key + '/' + section + '/' + subsection;

            subnav.push(menuItem);
          });

          if (subnav.length) {
            menu[key].sections[section].subnav = subnav;

            if (subsections.index === false) {
              writeRedirectIndex(menu[key].sections[section].subnav[0].url, menu[key].sections[section].title);
            }

            // Get Subsections
            subnav.forEach(function (navSection) {
              var navSectionItems = getdirsSync(base + navSection.url);

              if (navSectionItems.index) {
                fin[key][navSection.url] = navSectionItems.base + '/index.html';
              }
              else {
                Object.keys(navSectionItems.dirs).forEach(function (subNavSection) {
                  fin[key][navSection.url + '/' + subNavSection] = navSectionItems.base + '/' + subNavSection + '/index.html';
                });
              }
            });
          }
          else {
            if (subsections.index) {
              menu[key].sections[section].url = '/' + key + '/' + section;

              fin[key]['/' + key + '/' + section] = subsections.base + '/index.html';
            }
          }
        });

        Object.keys(fin[key]).forEach(function (renderKey) {
          outputFile(key, renderKey);
        });
      });
    });
  });

  var contentBuild = function contentBuild (content, key, outputKey) {
    var templatePath = 'library/templates/',
        title = ' | ',
        pageTemplate,
        subNav,
        title,
        render;

    content = fm(content);
    pageTemplate = content.attributes.pageTemplate ? content.attributes.pageTemplate : templatePath + '_layout.html';

    if (key) {
      title += menu[key].title + ' - '

      if (content.attributes.name) {
        title += content.attributes.name;
      }
      else if (content.attributes.title) {
        title += content.attributes.title;
      }
      else {
        title = '';
      }
    }
    else {
      title = '';
    }

    if (menu[key] && menu[key].sections) {
      subNav = menu[key].sections;
    }

    if (subNav) {
      Object.keys(subNav).forEach(function (subnavItem, j) {
        var miholder = [];
        if (subNav[subnavItem].url) {
          subNav[subnavItem].url.split('/').forEach(function (mi) {
            miholder.push(mi.replace(/^([0-9]+\-)/g, ''));
          });
          if (j === 0) {
            absoluteMenu[key.replace(/^([0-9]+\-)/g, '')] = miholder.join('/');
          }
          subNav[subnavItem].url = miholder.join('/');
          miholder = [];
        }
        else if (subNav[subnavItem].subnav) {
          subNav[subnavItem].subnav.forEach(function (sna, k) {
            sna.url.split('/').forEach(function (mi) {
              miholder.push(mi.replace(/^([0-9]+\-)/g, ''));
            });
            if (j === 0 && k === 0) {
              absoluteMenu[key.replace(/^([0-9]+\-)/g, '')] = miholder.join('/');
            }
            sna.url = miholder.join('/');
            subNav[subnavItem].subnav[k] = sna;
            miholder = [];
          });
        }
      });
    }

    render = swig.compileFile(pageTemplate)({
      'layout': {
        'title': title,
        'content': content.body,
      },
      'navigation': {
        'main': mainNav,
        'sub': subNav,
        'active': {
          'main': key ? key.replace(/^([0-9]+\-)/g, '') : '',
          'sub': outputKey ? outputKey : ''
        }
      }
    });

    return htmlmin(render, {
      'removeComments': true,
      'collapseWhitespace': true,
      'collapseBooleanAttributes': true,
      'removeRedundantAttributes': true,
      'removeEmptyAttributes': true,
      'removeEmptyElements': true,
      'minifyJS': true,
      'minifyCSS': true,
      'minifyURLs': true
    });
  };

  var outputFile = function outputFile (key, renderKey) {
    var outputKey = [];

    fs.readFile(fin[key][renderKey], 'utf-8', function (err, content) {
      if (err) throw err;

      renderKey.split('/').forEach(function (rk) {
        outputKey.push(rk.replace(/^([0-9]+\-)/g, ''));
      });

      outputKey = outputKey.join('/');

      fs.outputFile(process.cwd() + '/www' + outputKey + '/index.html', contentBuild(content, key, outputKey), function (err) {
        if (err) throw err;

        // gutil.log('Wrote ' + gutil.colors.magenta(renderKey.substring(1)) + ' with title ' + gutil.colors.cyan(layout.title.substring(3)));

        delete fin[key][renderKey];

        if (Object.keys(fin[key]).length === 0) {
          delete fin[key];

          if (Object.keys(fin).length === 0) {
            end = time.now();

            // console.log(absoluteMenu);
            gutil.log('Guide rebuilt after ' + gutil.colors.magenta(Math.round((end - start) / 1000) + 'ms'));
            cb();
            // console.timeEnd('render');
          }
        }
      });
    });
  }
}
<commit_msg>Add absolute menu generation<commit_after>var fs = require('fs-extra'),
    path = require('path'),
    util = require('util'),
    fm = require('front-matter'),
    gutil = require('gulp-util'),
    through = require('through2'),
    swig = require('./swig.js'),
    time = require('microtime'),
    glob = require('glob'),
    htmlmin = require('html-minifier').minify,
    _s = require('underscore.string');

var base = process.cwd() + '/tmp';

//////////////////////////////
// Get a list of directories
//////////////////////////////
var inspect = function (object) {
  console.log(util.inspect(object, false, null));
}

var makeTitle = function makeTitle (string) {
  return _s.titleize(_s.humanize(string)).replace('Ui ', 'UI ').replace('Input ', 'Input - ').replace(/^([0-9]+\s)/g, '');
}

var processDirs = function processDirs (files, base) {
  var results = {
    'dirs': {},
    'index': false,
    'base': base
  };

  if (files.indexOf('index.md') >= 0 || files.indexOf('index.html') >= 0) {
    results.index = true;
  }

  files.forEach(function (file) {
    var dir = path.resolve(base, file),
        name = makeTitle(file);
    dir = fs.statSync(dir);
    if (dir.isDirectory()) {
      results.dirs[file] = {
        'title': name
      };
    }
  });

  return results;
}

var getdirs = function getDirs (base, cb) {
  fs.readdir(base, function (err, files) {
    var results;

    if (err) {
      throw err;
    }

    results = processDirs(files, base);

    cb(err, results);
  });
};

var getdirsSync = function (base) {
  var files = fs.readdirSync(base),
      reults;

  return processDirs(files, base);
}

var writeRedirectIndex = function writeRedirectIndex(redirect, title) {
  var refreshIndex = '<!DOCTYPE html><meta http-equiv="refresh" content="0; url={{redirect}}" /><meta charset="UTF-8" /><title>Redirect</title>
The first available page for <strong`>{{title}}</strong`> is {{redirect}}
';

  var url = redirect.split('/'),
      redirPrts = [],
      urlPrts = [];

  if (url.length > 1) {
    url.pop();
    if (url[0] === '') {
      url.shift();
    }
  }

  url.forEach(function (urlp) {
    urlPrts.push(urlp.replace(/^([0-9]+\-)/g, ''));
  });

  redirect.split('/').forEach(function (redirp) {
    redirPrts.push(redirp.replace(/^([0-9]+\-)/g, ''));
  });

  url = urlPrts.join('/');
  redirect = redirPrts.join('/');

  refreshIndex = refreshIndex.replace(/\{\{redirect\}\}/g, redirect);
  refreshIndex = refreshIndex.replace(/\{\{title\}\}/g, title);

  fs.outputFile(process.cwd() + '/www/' + url + '/index.html', refreshIndex, function (err) {
    if (err) throw err;
    // gutil.log('Wrote ' + gutil.colors.magenta(url) + ' to redirect ' + gutil.colors.cyan(title));
  });
}

module.exports = function (options, cb) {
  options = options || {};

  var fin = {},
    mainNav = {},
    menu,
    absoluteMenu = {},
    start = time.now(),
    end;

  // fin['index'] = {
  //   'index': process.cwd() + '/tmp/index.html'
  // };

  fs.readFile(process.cwd() + '/tmp/index.html', 'utf-8', function (err, content) {
    if (err) throw err;

    fs.outputFile(process.cwd() + '/www/index.html', contentBuild(content), function (err) {
      if (err) throw err;
    });
  });

  getdirs(process.cwd() + '/tmp', function (err, dirs) {
    var key,
        mainNavBuild = [],
        index = false,
        section;

    menu = dirs.dirs;

    Object.keys(menu).forEach(function (dir) {
      fin[dir] = {};

      dir.split('/').forEach(function (dirPrt) {
        mainNavBuild.push(dirPrt.replace(/^([0-9]+\-)/g, ''));
      });

      mainNav[dir] = {
        'title': menu[dir].title,
        'url': mainNavBuild.join('/')
      }

      mainNavBuild = [];
    });

    Object.keys(menu).forEach(function (dir) {

      getdirs(base + '/' + dir, function (err, sections) {
        key = sections.base.split('/');
        key = key[key.length - 1];

        menu[key].sections = sections.dirs;

        if (sections.index === false) {
          writeRedirectIndex('/' + key + '/' + Object.keys(menu[key].sections)[0], menu[key].title);
        }

        Object.keys(sections.dirs).forEach(function (section) {
          var subsections = getdirsSync(base + '/' + key + '/' + section),
              render = 0,
              subnav = [],
              i,
              subnav;

          Object.keys(subsections.dirs).forEach(function (subsection) {
            var menuItem = {};

            menuItem.title = subsections.dirs[subsection].title;
            menuItem.url = '/' + key + '/' + section + '/' + subsection;

            subnav.push(menuItem);
          });

          if (subnav.length) {
            menu[key].sections[section].subnav = subnav;

            if (subsections.index === false) {
              writeRedirectIndex(menu[key].sections[section].subnav[0].url, menu[key].sections[section].title);
            }

            // Get Subsections
            subnav.forEach(function (navSection) {
              var navSectionItems = getdirsSync(base + navSection.url);

              if (navSectionItems.index) {
                fin[key][navSection.url] = navSectionItems.base + '/index.html';
              }
              else {
                Object.keys(navSectionItems.dirs).forEach(function (subNavSection) {
                  fin[key][navSection.url + '/' + subNavSection] = navSectionItems.base + '/' + subNavSection + '/index.html';
                });
              }
            });
          }
          else {
            if (subsections.index) {
              menu[key].sections[section].url = '/' + key + '/' + section;

              fin[key]['/' + key + '/' + section] = subsections.base + '/index.html';
            }
          }
        });

        Object.keys(fin[key]).forEach(function (renderKey) {
          outputFile(key, renderKey);
        });
      });
    });
  });

  var contentBuild = function contentBuild (content, key, outputKey) {
    var templatePath = 'library/templates/',
        title = ' | ',
        pageTemplate,
        subNav,
        title,
        render;

    content = fm(content);
    pageTemplate = content.attributes.pageTemplate ? content.attributes.pageTemplate : templatePath + '_layout.html';

    if (key) {
      title += menu[key].title + ' - '

      if (content.attributes.name) {
        title += content.attributes.name;
      }
      else if (content.attributes.title) {
        title += content.attributes.title;
      }
      else {
        title = '';
      }
    }
    else {
      title = '';
    }

    if (menu[key] && menu[key].sections) {
      subNav = menu[key].sections;
    }

    if (subNav) {
      Object.keys(subNav).forEach(function (subnavItem, j) {
        var miholder = [];
        if (subNav[subnavItem].url) {
          subNav[subnavItem].url.split('/').forEach(function (mi) {
            miholder.push(mi.replace(/^([0-9]+\-)/g, ''));
          });
          if (j === 0) {
            absoluteMenu[key.replace(/^([0-9]+\-)/g, '')] = miholder.join('/');
          }
          subNav[subnavItem].url = miholder.join('/');
          miholder = [];
        }
        else if (subNav[subnavItem].subnav) {
          subNav[subnavItem].subnav.forEach(function (sna, k) {
            sna.url.split('/').forEach(function (mi) {
              miholder.push(mi.replace(/^([0-9]+\-)/g, ''));
            });
            if (j === 0 && k === 0) {
              absoluteMenu[key.replace(/^([0-9]+\-)/g, '')] = miholder.join('/');
            }
            sna.url = miholder.join('/');
            subNav[subnavItem].subnav[k] = sna;
            miholder = [];
          });
        }
      });
    }

    render = swig.compileFile(pageTemplate)({
      'layout': {
        'title': title,
        'content': content.body,
      },
      'navigation': {
        'main': mainNav,
        'sub': subNav,
        'active': {
          'main': key ? key.replace(/^([0-9]+\-)/g, '') : '',
          'sub': outputKey ? outputKey : ''
        }
      }
    });

    return htmlmin(render, {
      'removeComments': true,
      'collapseWhitespace': true,
      'collapseBooleanAttributes': true,
      'removeRedundantAttributes': true,
      'removeEmptyAttributes': true,
      'removeEmptyElements': true,
      'minifyJS': true,
      'minifyCSS': true,
      'minifyURLs': true
    });
  };

  var outputFile = function outputFile (key, renderKey) {
    var outputKey = [];

    fs.readFile(fin[key][renderKey], 'utf-8', function (err, content) {
      if (err) throw err;

      renderKey.split('/').forEach(function (rk) {
        outputKey.push(rk.replace(/^([0-9]+\-)/g, ''));
      });

      outputKey = outputKey.join('/');

      fs.outputFile(process.cwd() + '/www' + outputKey + '/index.html', contentBuild(content, key, outputKey), function (err) {
        if (err) throw err;

        // gutil.log('Wrote ' + gutil.colors.magenta(renderKey.substring(1)) + ' with title ' + gutil.colors.cyan(layout.title.substring(3)));

        delete fin[key][renderKey];

        if (Object.keys(fin[key]).length === 0) {
          delete fin[key];

          if (Object.keys(fin).length === 0) {
            glob(process.cwd() + '/www/**/*.html', function (err, files) {
              var fileCount = files.length,
                  fi;
              files.forEach(function (file) {
                var f = fs.readFileSync(file, 'utf-8');

                Object.keys(absoluteMenu).forEach(function (pth) {
                  var find = 'href="/' + pth + '"',
                      re = new RegExp(find, 'g');

                  f = f.replace(re, 'href="' + absoluteMenu[pth] + '"');
                });

                fs.outputFile(file, f, function (e) {
                  fileCount--;
                  if (fileCount === 0) {
                    end = time.now();

                    gutil.log('Guide rebuilt after ' + gutil.colors.magenta(Math.round((end - start) / 1000) + 'ms'));
                    cb();
                  }
                });
              });
            });
          }
        }
      });
    });
  };
}
<|endoftext|>


<commit_before>/*jshint forin:true, noarg:true, noempty:true, eqeqeq:true, bitwise:false, strict:true, undef:true, unused:true, curly:true, node:true, indent:4, maxerr:50, globalstrict:true */

"use strict";

var fishback = require("../lib/fishback");
var http = require("http");

var PORT = 8080;
var BACKEND_HOST = "www.bbc.co.uk";
var BACKEND_PORT = "80";

var client = new fishback.Client(BACKEND_HOST, BACKEND_PORT);
client.on('newRequest', function (req) {
    console.info("CLIENT.newRequest " + req.method + " " + req.url);
});
client.on('newResponse', function (res) {
    console.info("CLIENT.newResponse " + res.method + " " + res.url);
});

var proxy = fishback.createProxy(client);
proxy.on('newRequest', function (req) {
    console.info("PROXY.newRequest " + req.method + " " + req.url);
});
proxy.on('newResponse', function (res) {
    console.info("PROXY.newResponse " + res.method + " " + res.url);
});

var server = new http.Server();
server.on('request', proxy.request.bind(proxy));
server.listen(PORT, function () {
    console.info("Listening on port " + PORT);
    console.info();
    console.info("Try:");
    console.info();
    console.info("  $ curl -s -i http://localhost:" + PORT + "/");
});
<commit_msg>Compensate for url -> localUrl changes<commit_after>/*jshint forin:true, noarg:true, noempty:true, eqeqeq:true, bitwise:false, strict:true, undef:true, unused:true, curly:true, node:true, indent:4, maxerr:50, globalstrict:true */

"use strict";

var fishback = require("../lib/fishback");
var http = require("http");

var PORT = 8080;
var BACKEND_HOST = "www.bbc.co.uk";
var BACKEND_PORT = "80";

var client = new fishback.Client(BACKEND_HOST, BACKEND_PORT);
client.on('newRequest', function (req) {
    console.info("CLIENT.newRequest " + req.method + " " + req.url);
});
client.on('newResponse', function (res) {
    console.info("CLIENT.newResponse " + res.method + " " + res.localUrl);
});

var proxy = fishback.createProxy(client);
proxy.on('newRequest', function (req) {
    console.info("PROXY.newRequest " + req.method + " " + req.url);
});
proxy.on('newResponse', function (res) {
    console.info("PROXY.newResponse " + res.method + " " + res.url);
});

var server = new http.Server();
server.on('request', proxy.request.bind(proxy));
server.listen(PORT, function () {
    console.info("Listening on port " + PORT);
    console.info();
    console.info("Try:");
    console.info();
    console.info("  $ curl -s -i http://localhost:" + PORT + "/");
});
<|endoftext|>


<commit_before>/**
 * The function to run the error modal.
 * @param htmlMsg {string}: the message to display.
 */
function runModal (htmlMsg) {
  $('#error-modal-message').html(htmlMsg)
  $('#error-modal').modal()
}

/**
 * At least one document is required to run the stats.
 * @returns {string | null}: the errors that is checked by JS, if no error the result will be null.
 */
function submissionError () {
  if ($('#num_active_files').val() < 1) { return 'You must have at least 1 active documents to proceed!' } else { return null }
}

/**
 * The function to convert the form into json
 * @returns {{string: string}}: the form converted to json
 */
function jsonifyForm () {
  const form = {}
  $.each($('form').serializeArray(), function (i, field) {
    form[field.name] = field.value || ''
  })
  return form
}

/**
 * Send the ajax request.
 * @param url {string}: the url to post.
 * @param form {{string: string}}: the form data packed into an object.
 * @returns {jQuery.Ajax}: an jQuery Ajax object.
 */
function sendAjaxRequest (url, form) {
  return $.ajax({
    type: 'POST',
    url: url,
    contentType: 'application/json; charset=utf-8',
    data: JSON.stringify(form)
  })
}

/**
 * Format the ajax call response to HTML format string.
 * @param response {json}: a json format string.
 * @return {string}: formatted file report.
 */
function formatFileReportResponse (response) {
  // Extract constant result from response.
  const token_name = response['token_name']
  const mean = `<p>Average document size is ${response['mean']} ${token_name}</p>`
  const std_deviation = `<p>Standard deviation of documents is ${response['std_deviation']} ${token_name}</p>`
  const inter_quartile_range = `<p>Inter quartile range of documents is ${response['inter_quartile_range']} ${token_name}</p>`
  // Extract standard deviation anomaly information.
  let anomaly_se
  if (response['anomaly_se'].every(function (element) { return element === null})) {
    anomaly_se = `<p><b>No</b> anomaly detected by standard deviation test.</p>`
  } else {
    anomaly_se = `<p>Anomaly <b>detected</b> by standard error test.</p>`
    response['anomaly_se'].forEach(function (element) {
      if (element !== null) { anomaly_se += `<p style="padding-left: 20px">${element.slice(0, 5).bold()}${element.slice(5, element.length)}</p>` }
    })
  }

  // Extract inter quartile range anomaly information.
  let anomaly_iqr
  if (response['anomaly_iqr'].every(function (element) { return element === null})) {
    anomaly_iqr = `<p><b>No</b> anomaly detected by inter quartile range test.</p>`
  } else {
    anomaly_iqr = `<p>Anomaly <b>detected</b> by inter quartile range test.</p>`
    response['anomaly_iqr'].forEach(function (element) {
      if (element !== null) { anomaly_iqr += `<p style="padding-left: 20px">${element.slice(0, 5).bold()}${element.slice(5, element.length)}</p>` }
    })
  }

  // Return the retracted information.
  return `${mean}${std_deviation}${inter_quartile_range}${anomaly_se}${anomaly_iqr}`
}

/**
 * Display the result of the corpus statistics report on web.
 */
function generateStatsFileReport () {
  $('#status-analyze').css({'visibility': 'visible'})
  // convert form into an object map string to string
  const form = jsonifyForm()

  // send the ajax request
  sendAjaxRequest('/fileReport', form)
    .done(
      function (response) {
        $('#file-report').html(formatFileReportResponse(response))
      })
    .fail(
      function (jqXHR, textStatus, errorThrown) {
        // If fail hide the loading icon.
        $('#status-analyze').css({'visibility': 'hidden'})
        console.log('textStatus: ' + textStatus)
        console.log('errorThrown: ' + errorThrown)
        runModal('Error encountered while generating the corpus statistics.')
      })
}

/**
 * Display the result of the box plot on web page
 */
function generateStatsBoxPlot () {
  $('#status-analyze').css({'visibility': 'visible'})
  // convert form into an object map string to string
  const form = jsonifyForm()

  // send the ajax request
  sendAjaxRequest('/boxPlot', form)
    .done(
      function (response) {
        $('#box-plot').html(response)
      })
    .fail(
      function (jqXHR, textStatus, errorThrown) {
        console.log('textStatus: ' + textStatus)
        console.log('errorThrown: ' + errorThrown)
        runModal('Error encountered while generating the box plot.')
      })
}

/**
 * Display the result of the file statistics on web.
 */
function generateStatsFileTable () {
  $('#status-analyze').css({'visibility': 'visible'})
  // convert form into an object map string to string
  const form = jsonifyForm()

  // the configuration for creating data table
  const dataTableConfig = {
    // Set the initial page length.
    pageLength: 10,

    // Replace entries to documents.
    language: {
      'lengthMenu': 'Display _MENU_ documents',
      'info': 'Showing _START_ to _END_ of _TOTAL_ documents'
    },

    // Specify where the button is.
    dom: '<\'row\'<\'col-sm-2\'l><\'col-sm-3 pull-right\'B>>' +
    '<\'row\'<\'col-sm-12\'tr>>' + '<\'row\'<\'col-sm-5\'i><\'col-sm-7\'p>>',

    // Specify all the download buttons that are displayed on the page.
    buttons: ['copyHtml5', 'excelHtml5', 'csvHtml5', 'pdfHtml5']
  }

  // send the ajax request
  sendAjaxRequest('/fileTable', form)
    .done(
      function (response) {
        const outerTableDivSelector = $('#file-table')
        // put the response onto the web page
        outerTableDivSelector.html(response)
        // initialize the data table
        outerTableDivSelector.children().DataTable(dataTableConfig)
        // display the corpus statistics result
        $('#stats-result').css({'display': 'block'})
      })
    .fail(
      function (jqXHR, textStatus, errorThrown) {
        // If fail hide the loading icon.
        $('#status-analyze').css({'visibility': 'hidden'})
        console.log('textStatus: ' + textStatus)
        console.log('errorThrown: ' + errorThrown)
        runModal('Error encountered while generating the file statistics.')
      })
    .always(
      function () {
        // Always hide the loading icon.
        $('#status-analyze').css({'visibility': 'hidden'})
      }
    )
}

$(function () {
  // Hide the stats result div.
  $('#stats-result').css({'display': 'none'})
  // Hide the normalize options and set it to raw count.
  $('#normalizeTypeRaw').attr('checked', true)
  $('#normalize-options').css({'visibility': 'hidden'})

  // Toggle file selection & reset the maximum number of documents when 'Toggle All' is clicked
  $('#allCheckBoxSelector').on('click', function () {
    if (this.checked) {
      $('.file-selector:not(:checked)').trigger('click')
      $('#cullnumber').attr('max', $('.file-selector:checked').length)
    } else {
      $('.file-selector:checked').trigger('click')
      $('#cullnumber').attr('max', '0')
    }
  })

  /**
   * The event handler for generate statistics clicked. Before generate
   * stats result, get number of active files and id of active files.
   */
  $('#get-stats').click(function () {
    // Get all the checked files.
    const checked_files = $('.eachFileCheck :checked')
    // Set a variable to store checked file ids.
    let active_file_ids = ''
    // Store checked file ids to the variable.
    checked_files.each(function () {
      active_file_ids += `${$(this).val()} `
    })
    // Store the variable to input field.
    $('#active_file_ids').val(active_file_ids)
    // Store the number of active files.
    $('#num_active_files').val(checked_files.length)

    // Get the possible error during the submission.
    const error = submissionError()

    if (error === null) {
      // Only get corpus info when there are more than one file.
      if (checked_files.length > 1) {
        // Get the corpus result.
        generateStatsFileReport()
        // Get the box plot.
        generateStatsBoxPlot()
      }
      // Get the file stats table.
      generateStatsFileTable()
    } else {
      runModal(error)
    }
  })
})
<commit_msg>Use template literal for dom settings<commit_after>/**
 * The function to run the error modal.
 * @param htmlMsg {string}: the message to display.
 */
function runModal (htmlMsg) {
  $('#error-modal-message').html(htmlMsg)
  $('#error-modal').modal()
}

/**
 * At least one document is required to run the stats.
 * @returns {string | null}: the errors that is checked by JS, if no error the result will be null.
 */
function submissionError () {
  if ($('#num_active_files').val() < 1) { return 'You must have at least 1 active documents to proceed!' } else { return null }
}

/**
 * The function to convert the form into json
 * @returns {{string: string}}: the form converted to json
 */
function jsonifyForm () {
  const form = {}
  $.each($('form').serializeArray(), function (i, field) {
    form[field.name] = field.value || ''
  })
  return form
}

/**
 * Send the ajax request.
 * @param url {string}: the url to post.
 * @param form {{string: string}}: the form data packed into an object.
 * @returns {jQuery.Ajax}: an jQuery Ajax object.
 */
function sendAjaxRequest (url, form) {
  return $.ajax({
    type: 'POST',
    url: url,
    contentType: 'application/json; charset=utf-8',
    data: JSON.stringify(form)
  })
}

/**
 * Format the ajax call response to HTML format string.
 * @param response {json}: a json format string.
 * @return {string}: formatted file report.
 */
function formatFileReportResponse (response) {
  // Extract constant result from response.
  const token_name = response['token_name']
  const mean = `<p>Average document size is ${response['mean']} ${token_name}</p>`
  const std_deviation = `<p>Standard deviation of documents is ${response['std_deviation']} ${token_name}</p>`
  const inter_quartile_range = `<p>Inter quartile range of documents is ${response['inter_quartile_range']} ${token_name}</p>`
  // Extract standard deviation anomaly information.
  let anomaly_se
  if (response['anomaly_se'].every(function (element) { return element === null})) {
    anomaly_se = `<p><b>No</b> anomaly detected by standard deviation test.</p>`
  } else {
    anomaly_se = `<p>Anomaly <b>detected</b> by standard error test.</p>`
    response['anomaly_se'].forEach(function (element) {
      if (element !== null) { anomaly_se += `<p style="padding-left: 20px">${element.slice(0, 5).bold()}${element.slice(5, element.length)}</p>` }
    })
  }

  // Extract inter quartile range anomaly information.
  let anomaly_iqr
  if (response['anomaly_iqr'].every(function (element) { return element === null})) {
    anomaly_iqr = `<p><b>No</b> anomaly detected by inter quartile range test.</p>`
  } else {
    anomaly_iqr = `<p>Anomaly <b>detected</b> by inter quartile range test.</p>`
    response['anomaly_iqr'].forEach(function (element) {
      if (element !== null) { anomaly_iqr += `<p style="padding-left: 20px">${element.slice(0, 5).bold()}${element.slice(5, element.length)}</p>` }
    })
  }

  // Return the retracted information.
  return `${mean}${std_deviation}${inter_quartile_range}${anomaly_se}${anomaly_iqr}`
}

/**
 * Display the result of the corpus statistics report on web.
 */
function generateStatsFileReport () {
  $('#status-analyze').css({'visibility': 'visible'})
  // convert form into an object map string to string
  const form = jsonifyForm()

  // send the ajax request
  sendAjaxRequest('/fileReport', form)
    .done(
      function (response) {
        $('#file-report').html(formatFileReportResponse(response))
      })
    .fail(
      function (jqXHR, textStatus, errorThrown) {
        // If fail hide the loading icon.
        $('#status-analyze').css({'visibility': 'hidden'})
        console.log('textStatus: ' + textStatus)
        console.log('errorThrown: ' + errorThrown)
        runModal('Error encountered while generating the corpus statistics.')
      })
}

/**
 * Display the result of the box plot on web page
 */
function generateStatsBoxPlot () {
  $('#status-analyze').css({'visibility': 'visible'})
  // convert form into an object map string to string
  const form = jsonifyForm()

  // send the ajax request
  sendAjaxRequest('/boxPlot', form)
    .done(
      function (response) {
        $('#box-plot').html(response)
      })
    .fail(
      function (jqXHR, textStatus, errorThrown) {
        console.log('textStatus: ' + textStatus)
        console.log('errorThrown: ' + errorThrown)
        runModal('Error encountered while generating the box plot.')
      })
}

/**
 * Display the result of the file statistics on web.
 */
function generateStatsFileTable () {
  $('#status-analyze').css({'visibility': 'visible'})
  // convert form into an object map string to string
  const form = jsonifyForm()

  // the configuration for creating data table
  const dataTableConfig = {
    // Set the initial page length.
    pageLength: 10,

    // Replace entries to documents.
    language: {
      'lengthMenu': 'Display _MENU_ documents',
      'info': 'Showing _START_ to _END_ of _TOTAL_ documents'
    },

    // Specify where the button is.
    dom: `<'row'<'col-sm-6'l><'col-sm-6 text-right'B>>
          <'row'<'col-sm-12'tr>><'row'<'col-sm-6'i><'col-sm-6'p>>`,

    // Specify all the download buttons that are displayed on the page.
    buttons: ['copyHtml5', 'excelHtml5', 'csvHtml5', 'pdfHtml5']
  }

  // send the ajax request
  sendAjaxRequest('/fileTable', form)
    .done(
      function (response) {
        const outerTableDivSelector = $('#file-table')
        // put the response onto the web page
        outerTableDivSelector.html(response)
        // initialize the data table
        outerTableDivSelector.children().DataTable(dataTableConfig)
        // display the corpus statistics result
        $('#stats-result').css({'display': 'block'})
      })
    .fail(
      function (jqXHR, textStatus, errorThrown) {
        // If fail hide the loading icon.
        $('#status-analyze').css({'visibility': 'hidden'})
        console.log('textStatus: ' + textStatus)
        console.log('errorThrown: ' + errorThrown)
        runModal('Error encountered while generating the file statistics.')
      })
    .always(
      function () {
        // Always hide the loading icon.
        $('#status-analyze').css({'visibility': 'hidden'})
      }
    )
}

$(function () {
  // Hide the stats result div.
  $('#stats-result').css({'display': 'none'})
  // Hide the normalize options and set it to raw count.
  $('#normalizeTypeRaw').attr('checked', true)
  $('#normalize-options').css({'visibility': 'hidden'})

  // Toggle file selection & reset the maximum number of documents when 'Toggle All' is clicked
  $('#allCheckBoxSelector').on('click', function () {
    if (this.checked) {
      $('.file-selector:not(:checked)').trigger('click')
      $('#cullnumber').attr('max', $('.file-selector:checked').length)
    } else {
      $('.file-selector:checked').trigger('click')
      $('#cullnumber').attr('max', '0')
    }
  })

  /**
   * The event handler for generate statistics clicked. Before generate
   * stats result, get number of active files and id of active files.
   */
  $('#get-stats').click(function () {
    // Get all the checked files.
    const checked_files = $('.eachFileCheck :checked')
    // Set a variable to store checked file ids.
    let active_file_ids = ''
    // Store checked file ids to the variable.
    checked_files.each(function () {
      active_file_ids += `${$(this).val()} `
    })
    // Store the variable to input field.
    $('#active_file_ids').val(active_file_ids)
    // Store the number of active files.
    $('#num_active_files').val(checked_files.length)

    // Get the possible error during the submission.
    const error = submissionError()

    if (error === null) {
      // Only get corpus info when there are more than one file.
      if (checked_files.length > 1) {
        // Get the corpus result.
        generateStatsFileReport()
        // Get the box plot.
        generateStatsBoxPlot()
      }
      // Get the file stats table.
      generateStatsFileTable()
    } else {
      runModal(error)
    }
  })
})
<|endoftext|>


<commit_before>/**
 * Copyright 2017 Google Inc. All Rights Reserved.
 *
 * 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.
 */

// Event: pull_request
// https://developer.github.com/v3/activity/events/types/#pullrequestevent
// Keys
//  * number - the pull request number.
//  * changes - the changes to the comment if the action was 'edited'
//  * pull_request - the pull request itself.
const PR_ASSIGNED = 'assigned';
const PR_UNASSIGNED = 'unassigned';
const PR_REVIEW_REQUESTED = 'review_requested';
const PR_REVIEW_REQUEST_REMOVED = 'review_request_removed';
const PR_LABELED = 'labeled';
const PR_UNLABLED = 'unlabeled';
const PR_OPENED = 'opened';
const PR_EDITED = 'edited';
const PR_CLOSED = 'closed';
const PR_REOPENED = 'reopened';

// Label for issues that confuse the bot
const LABEL_NEEDS_TRIAGE = 'needs-triage';

/**
 * Create a new handler for github pull requests.
 * @param {GithubClient} gh_client client for interacting with Github.
 */
function PullRequestHandler(gh_client, email_client, config) {
  // Client for interacting with github
  this.gh_client = gh_client;

  // Client for sending emails
  this.email_client = email_client;

  // Configuration
  this.config = config;
}

/**
 * Handle an issue associated with a Github pull request.
 */
PullRequestHandler.prototype.handlePullRequestEvent = function(
  event,
  action,
  pr,
  repo,
  sender
) {
  switch (action) {
    case PR_OPENED:
      return this.onNewPullRequest(repo, pr);
    case PR_LABELED:
      return this.onPullRequestLabeled(repo, pr);
    case PR_ASSIGNED:
    /* falls through */
    case PR_UNASSIGNED:
    /* falls through */
    case PR_REVIEW_REQUESTED:
    /* falls through */
    case PR_REVIEW_REQUEST_REMOVED:
    /* falls through */
    case PR_UNLABLED:
    /* falls through */
    case PR_EDITED:
    /* falls through */
    case PR_CLOSED:
    /* falls through */
    case PR_REOPENED:
    /* falls through */
    default:
      console.log('Unsupported pull request action: ' + action);
      console.log('Pull Request: ' + pr.title);
      break;
  }

  return Promise.resolve();
};

/**
 * Handle a newly opened pull request.
 */
PullRequestHandler.prototype.onNewPullRequest = function(repo, pr) {
  // Get basic issue information
  var org = repo.owner.login;
  var name = repo.name;
  var number = pr.number;

  var promises = [];

  // Check for skip
  if (this.hasSkipTag(repo, pr)) {
    return Promise.resolve();
  }

  // Check to see if the pull request has an issue associated
  if (!this.hasIssueLink(repo, pr)) {
    msg =
      "I couldn't find a link to an issue in your pull request. Please make sure this PR addresses an open issue.";
    var addCommentPromise = this.gh_client.addComment(org, name, number, msg);
    promises.push(addCommentPromise);
  }

  // Add a needs triage label
  var addLabelPromise = this.gh_client.addLabel(
    org,
    name,
    number,
    LABEL_NEEDS_TRIAGE
  );
  promises.push(addLabelPromise);

  return Promise.resolve(promises);
};

PullRequestHandler.prototype.onPullRequestLabeled = function(repo, pr) {
  // TODO(samstern): Send a an email to the right peopl
  return Promise.resolve();
};

/**
 * Determine if a PR has the [triage-skip] tag.
 */
PullRequestHandler.prototype.hasSkipTag = function(repo, pr) {
  return pr.title.indexOf('[triage-skip]') >= 0;
};

/**
 * Determine if the pull request links to a github issue (fuzzy).
 */
PullRequestHandler.prototype.hasIssueLink = function(repo, pr) {
  // Match either /issues/NUM or #NUM
  var issueRegex = new RegExp('(\/issues\/|#)[0-9]+');

  return issueRegex.test(pr.body);
};

// Exports
exports.PullRequestHandler = PullRequestHandler;
<commit_msg>Disable checking for issue links in PRs (for now)<commit_after>/**
 * Copyright 2017 Google Inc. All Rights Reserved.
 *
 * 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.
 */

// Event: pull_request
// https://developer.github.com/v3/activity/events/types/#pullrequestevent
// Keys
//  * number - the pull request number.
//  * changes - the changes to the comment if the action was 'edited'
//  * pull_request - the pull request itself.
const PR_ASSIGNED = 'assigned';
const PR_UNASSIGNED = 'unassigned';
const PR_REVIEW_REQUESTED = 'review_requested';
const PR_REVIEW_REQUEST_REMOVED = 'review_request_removed';
const PR_LABELED = 'labeled';
const PR_UNLABLED = 'unlabeled';
const PR_OPENED = 'opened';
const PR_EDITED = 'edited';
const PR_CLOSED = 'closed';
const PR_REOPENED = 'reopened';

// Label for issues that confuse the bot
const LABEL_NEEDS_TRIAGE = 'needs-triage';

/**
 * Create a new handler for github pull requests.
 * @param {GithubClient} gh_client client for interacting with Github.
 */
function PullRequestHandler(gh_client, email_client, config) {
  // Client for interacting with github
  this.gh_client = gh_client;

  // Client for sending emails
  this.email_client = email_client;

  // Configuration
  this.config = config;
}

/**
 * Handle an issue associated with a Github pull request.
 */
PullRequestHandler.prototype.handlePullRequestEvent = function(
  event,
  action,
  pr,
  repo,
  sender
) {
  switch (action) {
    case PR_OPENED:
      return this.onNewPullRequest(repo, pr);
    case PR_LABELED:
      return this.onPullRequestLabeled(repo, pr);
    case PR_ASSIGNED:
    /* falls through */
    case PR_UNASSIGNED:
    /* falls through */
    case PR_REVIEW_REQUESTED:
    /* falls through */
    case PR_REVIEW_REQUEST_REMOVED:
    /* falls through */
    case PR_UNLABLED:
    /* falls through */
    case PR_EDITED:
    /* falls through */
    case PR_CLOSED:
    /* falls through */
    case PR_REOPENED:
    /* falls through */
    default:
      console.log('Unsupported pull request action: ' + action);
      console.log('Pull Request: ' + pr.title);
      break;
  }

  return Promise.resolve();
};

/**
 * Handle a newly opened pull request.
 */
PullRequestHandler.prototype.onNewPullRequest = function(repo, pr) {
  // Get basic issue information
  var org = repo.owner.login;
  var name = repo.name;
  var number = pr.number;

  var promises = [];

  // Check for skip
  if (this.hasSkipTag(repo, pr)) {
    return Promise.resolve();
  }

  // Check to see if the pull request has an issue associated
  // TODO(samstern): Decide if we should re-enable checking for an issue link
  // if (!this.hasIssueLink(repo, pr)) {
  //   msg =
  //     "I couldn't find a link to an issue in your pull request. Please make sure this PR addresses an open issue.";
  //   var addCommentPromise = this.gh_client.addComment(org, name, number, msg);
  //   promises.push(addCommentPromise);
  // }

  // Add a needs triage label
  var addLabelPromise = this.gh_client.addLabel(
    org,
    name,
    number,
    LABEL_NEEDS_TRIAGE
  );
  promises.push(addLabelPromise);

  return Promise.resolve(promises);
};

PullRequestHandler.prototype.onPullRequestLabeled = function(repo, pr) {
  // TODO(samstern): Send a an email to the right peopl
  return Promise.resolve();
};

/**
 * Determine if a PR has the [triage-skip] tag.
 */
PullRequestHandler.prototype.hasSkipTag = function(repo, pr) {
  return pr.title.indexOf('[triage-skip]') >= 0;
};

/**
 * Determine if the pull request links to a github issue (fuzzy).
 */
PullRequestHandler.prototype.hasIssueLink = function(repo, pr) {
  // Match either /issues/NUM or #NUM
  var issueRegex = new RegExp('(\/issues\/|#)[0-9]+');

  return issueRegex.test(pr.body);
};

// Exports
exports.PullRequestHandler = PullRequestHandler;
<|endoftext|>