<commit_before>let loopback = require('../../shims/cassproject.js');
var xapiMePpk = keyFor("xapiAdapter");

var xapiConfig = function () {
    if (this.xapiConfig != null) return this.xapiConfig;
    var xapiConfigFilePath = "etc/adapter.xapi.json";
    if (!fileExists(xapiConfigFilePath))
        fileSave(JSON.stringify({
            xapiEndpoint: "",
            xapiHostname: "",
            xapiAuth: "",
            enabled: false
        }),xapiConfigFilePath);
    this.xapiConfig = JSON.parse(fileToString(fileLoad(xapiConfigFilePath)));
    return this.xapiConfig;
}
var xapiConfigAutoExecute = xapiConfig;

var xapiEndpoint = function (more, since) {
    var endpoint = xapiConfig.call(this).xapiEndpoint + "statements?format=exact&limit=0";
    if (since != null)
        endpoint = xapiConfig.call(this).xapiEndpoint + "statements?format=exact&limit=0&since=" + since;
    if (more != null)
        endpoint = xapiConfig.call(this).xapiEndpoint + more;
    var headers = {};
    headers["Authorization"] = xapiConfig.call(this).xapiAuth;
    headers["X-Experience-API-Version"] = "1.0.1";
    return httpGet(endpoint,false, headers);
}
bindWebService("/xapi/endpoint", xapiEndpoint);

var getMbox = function (agentObject) {
    if (agentObject == null)
        return null;
    if (EcArray.isArray(agentObject))
        agentObject = agentObject[0];
    var email = agentObject.mbox;
    if (email != null)
        return email;
    if (agentObject.account != null)
        return agentObject.account.name;
    return null;
}

var personFromEmail = async function (mbox) {
    if (mbox == null) return null;
    var person = null;
    mbox = mbox.replace("mailto:", "");
    if (mbox.indexOf("@") != -1)
    {
        let people = null;
        people = await loopback.repositorySearch(repo,"@type:Person AND email:\"" + mbox + "\"",{});
        if (people != null) {
            if (people.length == 1)
                person = people[0];
            else if (people.length > 1)
                console.error("Cannot generate xAPI statements for " + mbox + " -- too many people with that email.");
        }
    }
    else
    {
        let people = null;
        people = await loopback.repositorySearch(repo,"@type:Person AND identifier:\"" + mbox + "\"",{});
        if (people != null) {
            if (people.length == 1)
                person = people[0];
            else if (people.length > 1)
                console.error("Cannot generate xAPI statements for " + mbox + " -- too many people with that identifier.");
        }
    }
    return person;
}

var pkFromMbox = async function (xapiPerson) {
    var mbox = getMbox.call(this, xapiPerson);
    if (mbox == null)
        return null;
    var person = await personFromEmail.call(this, mbox);
    if (person == null)
        return null;
    var pk = null;
    for (var i = 0; i < person.owner.length; i++)
        if (EcPk.fromPem(person.owner[i]).fingerprint() == person.getGuid())
            pk = EcPk.fromPem(person.owner[i]);
    return pk;
}

var getAlignedCompetencies = async function (objectId) {
    var results = [];
    let creativeWorks = await loopback.repositorySearch(repo,"@type:CreativeWork AND url:\"" + objectId + "\"",{});
    for (let creativeWork of creativeWorks)
    {
        if (creativeWork.educationalAlignment == null) continue;
        if (!EcArray.isArray(creativeWork.educationalAlignment))
            creativeWork.educationalAlignment = [creativeWork.educationalAlignment];
        for (var i = 0; i < creativeWork.educationalAlignment.length; i++)
            results.push(creativeWork.educationalAlignment[i]);
    }
    return results;
}

var xapiStatement = async function (s) {
    if (s == null) return;
    if (EcArray.isArray(s))
        for (var i = 0;i < s.length;i++)
            await xapiStatement(s[i]);
    if (!EcObject.isObject(s)) return;
    if (s.result == null) return;
    var negative = false;
    if (s.result.score != null) {
        var scaled = s.result.score.scaled;
        if (scaled > 0.7)
            negative = false;
        else
            negative = true;
    } else if (s.result.success != null) {
        var scaled = 1.0;
        if (s.result.success == true)
            negative = false;
        else
            negative = true;
    } else if (s.result.response == "Pass") {
        var scaled = 1.0;
        negative = false;
    } else if (s.result.response == "Fail") {
        var scaled = 1.0;
        negative = true;
    } else
        return;

    var actorPk = await pkFromMbox.call(this, s.actor);
    if (actorPk == null)
    {
        var ppk = await EcPpk.generateKey();
        var person = new schema.Person();
        person.assignId(repo.selectedServer,ppk.toPk().fingerprint());
        person.addOwner(ppk.toPk());
		var mb = getMbox.call(this, s.actor).replace("mailto:","");
		if (mb.indexOf("@") == -1)
			person.identifier = mb;
		else
			person.email = mb;
        person.name = s.actor.name;
        await EcRepository.save(person,console.log,console.error);
        actorPk = ppk.toPk();
    }
    if (actorPk == null) return;
    var authorityPk = await pkFromMbox.call(this, s.authority);
    if (authorityPk == null)
        authorityPk = EcPpk.fromPem(xapiMePpk).toPk();
    if (authorityPk == null) return;

    if (s.object == null) return;

    var alignedCompetencies = await getAlignedCompetencies.call(this, s.object.id);
    var alreadyAligned = {};
    for (var i = 0; i < alignedCompetencies.length; i++) {
        var a = new EcAssertion();
        a.assignId(repo.selectedServer, EcCrypto.md5(s.id+alignedCompetencies[i].targetUrl));
        a.addOwner(EcPpk.fromPem(xapiMePpk).toPk());
        a.addOwner(authorityPk);
        await a.setSubject(actorPk);
        await a.setAgent(authorityPk);
        a.competency = alignedCompetencies[i].targetUrl;
        a.framework = alignedCompetencies[i].educationalFramework;
        if (alreadyAligned[a.competency + a.framework] == true)
            continue;
        alreadyAligned[a.competency + a.framework] = true;
        await a.setEvidence([JSON.stringify(s)]);
        await a.setAssertionDate(new Date(s.timestamp).getTime());
        await a.setNegative(negative);
        a.confidence = scaled;
        EcRepository.save(a, console.log, console.error);
    }
}

var xapiStatementListener = async function () {
    for (let val in this.dataStreams)
        await xapiStatement(this.dataStreams[val]);
    // var data = fileFromDatastream.call(this);
    // if (data == null)
    // {
    // }
    // else
    // {
    //     data = fileToString(data.get(0));
    //     data = JSON.parse(data);
    //     await xapiStatement(data);
    // }
}

var ident = new EcIdentity();
ident.displayName = "xAPI Adapter";
ident.ppk = EcPpk.fromPem(xapiMePpk);
EcIdentityManager.default.addIdentity(ident);
xapiKey = function () {
    return ident.ppk.toPk().toPem();
}
bindWebService("/xapi/pk", xapiKey);
bindWebService("/xapi/statement", xapiStatementListener);

var xapiLoop = async function () {
    var ident = new EcIdentity();
    ident.displayName = "xAPI Adapter";
    ident.ppk = EcPpk.fromPem(xapiMePpk);
    EcIdentityManager.default.addIdentity(ident);
    var sinceFilePath = "etc/adapter.xapi.since.txt";
    var since = null;
    if (fileExists(sinceFilePath)) {
        since = fileLoad(sinceFilePath);
        since = fileToString(since);
    }
    var results = xapiEndpoint.call(this, null, since);
    while (results.statements != null && results.statements.length > 0) {
        for (var i = 0; i < results.statements.length; i++) {
            await xapiStatement.call(this, results.statements[i]);
        }
        fileSave(date(null, "yyyy-MM-dd'T'HH:mm:ssXXX"), sinceFilePath);
        if (results.more != null && results.more != "")
            results = xapiEndpoint.call(this, results.more, null);
        else
            results = {};
    }
}
bindWebService("/xapi/tick", xapiLoop);
<commit_msg>Awaits and dates in xapi adapter<commit_after>let loopback = require('../../shims/cassproject.js');
var xapiMePpk = keyFor("xapiAdapter");

var xapiConfig = function () {
    if (this.xapiConfig != null) return this.xapiConfig;
    var xapiConfigFilePath = "etc/adapter.xapi.json";
    if (!fileExists(xapiConfigFilePath))
        fileSave(JSON.stringify({
            xapiEndpoint: "",
            xapiHostname: "",
            xapiAuth: "",
            enabled: false
        }),xapiConfigFilePath);
    this.xapiConfig = JSON.parse(fileToString(fileLoad(xapiConfigFilePath)));
    return this.xapiConfig;
}
var xapiConfigAutoExecute = xapiConfig;

var xapiEndpoint = async function (more, since) {
    var endpoint = xapiConfig.call(this).xapiEndpoint + "statements?format=exact&limit=0";
    if (since != null)
        endpoint = xapiConfig.call(this).xapiEndpoint + "statements?format=exact&limit=0&since=" + since;
    if (more != null)
        endpoint = xapiConfig.call(this).xapiEndpoint + more;
    var headers = {};
    headers["Authorization"] = xapiConfig.call(this).xapiAuth;
    headers["X-Experience-API-Version"] = "1.0.1";
    return await httpGet(endpoint,false, headers);
}
bindWebService("/xapi/endpoint", xapiEndpoint);

var getMbox = function (agentObject) {
    if (agentObject == null)
        return null;
    if (EcArray.isArray(agentObject))
        agentObject = agentObject[0];
    var email = agentObject.mbox;
    if (email != null)
        return email;
    if (agentObject.account != null)
        return agentObject.account.name;
    return null;
}

var personFromEmail = async function (mbox) {
    if (mbox == null) return null;
    var person = null;
    mbox = mbox.replace("mailto:", "");
    if (mbox.indexOf("@") != -1)
    {
        let people = null;
        people = await loopback.repositorySearch(repo,"@type:Person AND email:\"" + mbox + "\"",{});
        if (people != null) {
            if (people.length == 1)
                person = people[0];
            else if (people.length > 1)
                console.error("Cannot generate xAPI statements for " + mbox + " -- too many people with that email.");
        }
    }
    else
    {
        let people = null;
        people = await loopback.repositorySearch(repo,"@type:Person AND identifier:\"" + mbox + "\"",{});
        if (people != null) {
            if (people.length == 1)
                person = people[0];
            else if (people.length > 1)
                console.error("Cannot generate xAPI statements for " + mbox + " -- too many people with that identifier.");
        }
    }
    return person;
}

var pkFromMbox = async function (xapiPerson) {
    var mbox = getMbox.call(this, xapiPerson);
    if (mbox == null)
        return null;
    var person = await personFromEmail.call(this, mbox);
    if (person == null)
        return null;
    var pk = null;
    for (var i = 0; i < person.owner.length; i++)
        if (EcPk.fromPem(person.owner[i]).fingerprint() == person.getGuid())
            pk = EcPk.fromPem(person.owner[i]);
    return pk;
}

var getAlignedCompetencies = async function (objectId) {
    var results = [];
    let creativeWorks = await loopback.repositorySearch(repo,"@type:CreativeWork AND url:\"" + objectId + "\"",{});
    for (let creativeWork of creativeWorks)
    {
        if (creativeWork.educationalAlignment == null) continue;
        if (!EcArray.isArray(creativeWork.educationalAlignment))
            creativeWork.educationalAlignment = [creativeWork.educationalAlignment];
        for (var i = 0; i < creativeWork.educationalAlignment.length; i++)
            results.push(creativeWork.educationalAlignment[i]);
    }
    return results;
}

var xapiStatement = async function (s) {
    if (s == null) return;
    if (EcArray.isArray(s))
        for (var i = 0;i < s.length;i++)
            await xapiStatement(s[i]);
    if (!EcObject.isObject(s)) return;
    if (s.result == null) return;
    var negative = false;
    if (s.result.score != null) {
        var scaled = s.result.score.scaled;
        if (scaled > 0.7)
            negative = false;
        else
            negative = true;
    } else if (s.result.success != null) {
        var scaled = 1.0;
        if (s.result.success == true)
            negative = false;
        else
            negative = true;
    } else if (s.result.response == "Pass") {
        var scaled = 1.0;
        negative = false;
    } else if (s.result.response == "Fail") {
        var scaled = 1.0;
        negative = true;
    } else
        return;

    var actorPk = await pkFromMbox.call(this, s.actor);
    if (actorPk == null)
    {
        var ppk = await EcPpk.generateKey();
        var person = new schema.Person();
        person.assignId(repo.selectedServer,ppk.toPk().fingerprint());
        person.addOwner(ppk.toPk());
		var mb = getMbox.call(this, s.actor).replace("mailto:","");
		if (mb.indexOf("@") == -1)
			person.identifier = mb;
		else
			person.email = mb;
        person.name = s.actor.name;
        await EcRepository.save(person,console.log,console.error);
        actorPk = ppk.toPk();
    }
    if (actorPk == null) return;
    var authorityPk = await pkFromMbox.call(this, s.authority);
    if (authorityPk == null)
        authorityPk = EcPpk.fromPem(xapiMePpk).toPk();
    if (authorityPk == null) return;

    if (s.object == null) return;

    var alignedCompetencies = await getAlignedCompetencies.call(this, s.object.id);
    var alreadyAligned = {};
    for (var i = 0; i < alignedCompetencies.length; i++) {
        var a = new EcAssertion();
        a.assignId(repo.selectedServer, EcCrypto.md5(s.id+alignedCompetencies[i].targetUrl));
        a.addOwner(EcPpk.fromPem(xapiMePpk).toPk());
        a.addOwner(authorityPk);
        await a.setSubject(actorPk);
        await a.setAgent(authorityPk);
        a.competency = alignedCompetencies[i].targetUrl;
        a.framework = alignedCompetencies[i].educationalFramework;
        if (alreadyAligned[a.competency + a.framework] == true)
            continue;
        alreadyAligned[a.competency + a.framework] = true;
        await a.setEvidence([JSON.stringify(s)]);
        await a.setAssertionDate(new Date(s.timestamp).getTime());
        await a.setNegative(negative);
        a.confidence = scaled;
        EcRepository.save(a, console.log, console.error);
    }
}

var xapiStatementListener = async function () {
    for (let val in this.dataStreams)
        await xapiStatement(this.dataStreams[val]);
    // var data = fileFromDatastream.call(this);
    // if (data == null)
    // {
    // }
    // else
    // {
    //     data = fileToString(data.get(0));
    //     data = JSON.parse(data);
    //     await xapiStatement(data);
    // }
}

var ident = new EcIdentity();
ident.displayName = "xAPI Adapter";
ident.ppk = EcPpk.fromPem(xapiMePpk);
EcIdentityManager.default.addIdentity(ident);
xapiKey = function () {
    return ident.ppk.toPk().toPem();
}
bindWebService("/xapi/pk", xapiKey);
bindWebService("/xapi/statement", xapiStatementListener);

var xapiLoop = async function () {
    var ident = new EcIdentity();
    ident.displayName = "xAPI Adapter";
    ident.ppk = EcPpk.fromPem(xapiMePpk);
    EcIdentityManager.default.addIdentity(ident);
    var sinceFilePath = "etc/adapter.xapi.since.txt";
    var since = null;
    if (fileExists(sinceFilePath)) {
        since = fileLoad(sinceFilePath);
        since = fileToString(since);
    }
    var results = await xapiEndpoint.call(this, null, since);
    while (results.statements != null && results.statements.length > 0) {
        for (var i = 0; i < results.statements.length; i++) {
            await xapiStatement.call(this, results.statements[i]);
        }
        fileSave(new Date().toISOString(), sinceFilePath);
        if (results.more != null && results.more != "")
            results = await xapiEndpoint.call(this, results.more, null);
        else
            results = {};
    }
}
bindWebService("/xapi/tick", xapiLoop);
<|endoftext|>


<commit_before>#!/usr/bin/env node

var exec = require('child_process').exec;
var spawn = require('child_process').spawn;

// MDM NOTE that node v0.12 or higher is required for this.
var execSync = require('child_process').execSync;
var spawnSync = require('child_process').spawnSync;

var spawnargs = require('spawn-args');

//=========== run_command_sync_to_console: run one command and let output immediately flow to console ============
var run_command_sync_to_console = function (cmd) {
    execSync(cmd, {stdio:[0,1,2]}, function(error, stdout, stderr) {
        if (error) {
            console.log('======= RUN ERROR =======');
            throw error;
        }
    });
}

//=========== run_command_async_to_console: async run one command and dump output to console when complete ============
var run_command_async_to_console = function (cmd) {
    exec(cmd, function(error, stdout, stderr) {
        if (stdout.length > 0 ) console.log(stdout);
        if (stderr.length > 0 ) console.log(stderr);
    });
}

//=========== run_command_quietly: runs without output unless error ============
var run_command_quietly = function (cmd) {
    execSync(cmd, function(error, stdout, stderr) {
        if (error) {
            console.log('======= RUN ERROR =======');
            throw error;
        }
    });
}

// =========== run_command: run one command and get output ============
// Run a command asynchronously and get the output when it finishes in a callback.
// Usage:
// run_command( "ls -l", function(err,text) { console.log (text) });
var run_command = function (cmd, callBack ) {

    var fullargs = spawnargs(cmd);
    cmd = fullargs[0];
    var args = fullargs.slice(1);

    // DEBUG this works!
    // var args = ["status"];
    // cmd = "git";

    // DEBUG this works!
    // cmd = "git";
    // var args = ["commit","-a","-m",'"synctrouble"'];

    // DEBUG:
    // console.log('cmd args: ' + cmd + ' ----- ' + args);

    var spawn = require('child_process').spawn;

    var child = spawn(cmd, args);
    // var child = spawn(cmd, args, {stdio: "inherit"});

    var resp = "";
    var errr = "";
    child.stdout.on('data', function (buffer) { resp += buffer.toString() });
    child.stderr.on('data', function (buffer) { errr += buffer.toString() });

    child.stdout.on('end', function() { callBack (errr, resp) });
}

// =========== run_command_sync: run one command and get output ============
// Run a command synchronously and get the output when it finishes.
// Usage:
// var lsout = run_command_sync("ls -l");
var run_command_sync = function (cmd) {

    var fullargs = spawnargs(cmd);
    cmd = fullargs[0];
    var args = fullargs.slice(1);

    var spawnSync = require('child_process').spawnSync;
    var outp = spawnSync(cmd, args, { encoding : 'utf8' });

    // Return all output.  Put any error output last.
    var result = outp.stdout;
    if (outp.stderr.length > 0) { result += "\n" + outp.stderr; }
    return result;
}

// =========== runsteps: run a specific set of commands in specific directories ============
// Given: steps, an array of {name,folder,cmd} objects, eg:
//
//      var my_steps =
//      [
//          { name: 'update Project'        , folder: '.'       , cmd: 'git pull'       },
//          { name: 'build Project'         , folder: '.'       , cmd: 'make'           },
//      ];
//
// This function runs the requested steps.
// Verbosity can be:
//		"quiet"		no output
//		undefined	normal output - the command output is logged to console
//		"verbose"	more output - step name, folder, command output
// Define async to get asynchronous execution.
var runsteps = function (steps,verbosity,async) {

    var path = require('path');

    steps.forEach(function(step,i) {

        try {

            process.chdir(path.normalize(step.folder));

            if (async) {

                run_command(step.cmd, function(text) {
                    if (verbosity == "verbose") {
                        console.log ('------------------------------');
                        console.log('step: ' + step.name);
                        console.log ('------------------------------');
                        console.log(step.folder + '> ' + step.cmd);
                    }
                    console.log (text)
                });

                // Workaround during testing
                // run_command_async_to_console(steps[i].cmd);

            } else if (verbosity != "quiet") {

                if (verbosity == "verbose") {
                    console.log ('------------------------------');
                    console.log('step: ' + step.name);
                    console.log ('------------------------------');
                    console.log(step.folder + '> ' + step.cmd);
                }
        		run_command_sync_to_console(step.cmd);

            } else {
        		run_command_quietly(step.cmd);
        	}
        }
        catch (err) {
            if (verbosity == "verbose") {
            	console.log(err);
            }
        }
    });
}

var combine_params = function(params) {
    var result = "";
    if (params.length > 0)
    {
        params.forEach(function(val,index,array){
            if (index != 0) { result += " "; }
            result += val;
        });
    }
    return result;
}

module.exports.run_command_sync = run_command_sync;
module.exports.run_command_sync_to_console = run_command_sync_to_console;
module.exports.run_command_async_to_console = run_command_async_to_console;
module.exports.run_command_quietly = run_command_quietly;
module.exports.run_command = run_command;
module.exports.runsteps = runsteps;
module.exports.combine_params = combine_params;
<commit_msg>comment<commit_after>#!/usr/bin/env node

var exec = require('child_process').exec;
var spawn = require('child_process').spawn;

// MDM NOTE that node v0.12 or higher is required for this.
var execSync = require('child_process').execSync;
var spawnSync = require('child_process').spawnSync;

var spawnargs = require('spawn-args');

//=========== run_command_sync_to_console: run one command and let output immediately flow to console ============
var run_command_sync_to_console = function (cmd) {
    execSync(cmd, {stdio:[0,1,2]}, function(error, stdout, stderr) {
        if (error) {
            console.log('======= RUN ERROR =======');
            throw error;
        }
    });
}

//=========== run_command_async_to_console: async run one command and dump output to console when complete ============
var run_command_async_to_console = function (cmd) {
    exec(cmd, function(error, stdout, stderr) {
        if (stdout.length > 0 ) console.log(stdout);
        if (stderr.length > 0 ) console.log(stderr);
    });
}

//=========== run_command_quietly: runs without output unless error ============
var run_command_quietly = function (cmd) {
    execSync(cmd, function(error, stdout, stderr) {
        if (error) {
            console.log('======= RUN ERROR =======');
            throw error;
        }
    });
}

// =========== run_command: run one command and get output ============
// Run a command asynchronously and get the output when it finishes in a callback.
// Usage:
// run_command( "ls -l", function(err,text) { console.log (text) });
var run_command = function (cmd, callBack ) {

    var fullargs = spawnargs(cmd);
    cmd = fullargs[0];
    var args = fullargs.slice(1);

    // DEBUG this works!
    // var args = ["status"];
    // cmd = "git";

    // DEBUG this works!
    // cmd = "git";
    // var args = ["commit","-a","-m",'"synctrouble"'];

    // DEBUG:
    // console.log('cmd args: ' + cmd + ' ----- ' + args);

    var spawn = require('child_process').spawn;

    var child = spawn(cmd, args);
    // var child = spawn(cmd, args, {stdio: "inherit"});

    var resp = "";
    var errr = "";
    child.stdout.on('data', function (buffer) { resp += buffer.toString() });
    child.stderr.on('data', function (buffer) { errr += buffer.toString() });

    child.stdout.on('end', function() { callBack (errr, resp) });
}

// =========== run_command_sync: run one command and get output ============
// Run a command synchronously and get the output when it finishes.
// Usage:
// var lsout = run_command_sync("ls -l");
var run_command_sync = function (cmd) {

    var fullargs = spawnargs(cmd);
    cmd = fullargs[0];
    var args = fullargs.slice(1);

    var spawnSync = require('child_process').spawnSync;
    var outp = spawnSync(cmd, args, { encoding : 'utf8' });

    // Return all output.  Put any error output last.
    var result = outp.stdout;
    if (outp.stderr && outp.stderr.length > 0) { result += "\n" + outp.stderr; }
    return result;
}

// =========== runsteps: run a specific set of commands in specific directories ============
// Given: steps, an array of {name,folder,cmd} objects, eg:
//
//      var my_steps =
//      [
//          { name: 'update Project'        , folder: '.'       , cmd: 'git pull'       },
//          { name: 'build Project'         , folder: '.'       , cmd: 'make'           },
//      ];
//
// This function runs the requested steps.
// Verbosity can be:
//		"quiet"		no output
//		undefined	normal output - the command output is logged to console
//		"verbose"	more output - step name, folder, command output
// Define async to get asynchronous execution.
var runsteps = function (steps,verbosity,async) {

    var path = require('path');

    steps.forEach(function(step,i) {

        try {

            process.chdir(path.normalize(step.folder));

            if (async) {

                run_command(step.cmd, function(text) {
                    if (verbosity == "verbose") {
                        console.log ('------------------------------');
                        console.log('step: ' + step.name);
                        console.log ('------------------------------');
                        console.log(step.folder + '> ' + step.cmd);
                    }
                    console.log (text)
                });

                // Workaround during testing
                // run_command_async_to_console(steps[i].cmd);

            } else if (verbosity != "quiet") {

                if (verbosity == "verbose") {
                    console.log ('------------------------------');
                    console.log('step: ' + step.name);
                    console.log ('------------------------------');
                    console.log(step.folder + '> ' + step.cmd);
                }
        		run_command_sync_to_console(step.cmd);

            } else {
        		run_command_quietly(step.cmd);
        	}
        }
        catch (err) {
            if (verbosity == "verbose") {
            	console.log(err);
            }
        }
    });
}

var combine_params = function(params) {
    var result = "";
    if (params.length > 0)
    {
        params.forEach(function(val,index,array){
            if (index != 0) { result += " "; }
            result += val;
        });
    }
    return result;
}

module.exports.run_command_sync = run_command_sync;
module.exports.run_command_sync_to_console = run_command_sync_to_console;
module.exports.run_command_async_to_console = run_command_async_to_console;
module.exports.run_command_quietly = run_command_quietly;
module.exports.run_command = run_command;
module.exports.runsteps = runsteps;
module.exports.combine_params = combine_params;
<|endoftext|>


<commit_before>/**
* GIBS Web Examples
*
* Copyright 2013 - 2015 United States Government as represented by the
* Administrator of the National Aeronautics and Space Administration.
* 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.
*/

var gibs = gibs || {};

gibs.Viewer = function(config) {

    // Earliest date of Corrected Reflectance in archive: May 8, 2012
    var startTime = Cesium.JulianDate.fromDate(
            new Date(Date.UTC(2012, 4, 8)));

    var endTime = Cesium.JulianDate.now();

    // If slightly after midnight, show the previous day's data while
    // the near-real time imagery is processing.
    var show = new Date();
    if ( show.getUTCHours() < 3 ) {
        show.setUTCDate(now.getUTCDate() - 1);
    }
    var initialTime = Cesium.JulianDate.fromDate(show);

    // Keep track of the previous day. Only update the layer on a tick if the
    // day has actually changed.
    var previousTime = null;
    var selectedSet = null;

    var clock = new Cesium.Clock({
        currentTime: initialTime,
        multiplier: 0, // Don't start animation by default
        startTime: startTime,
        endTime: endTime,
        clockRange: Cesium.ClockRange.CLAMPED
    });

    // GIBS needs the day as a string parameter in the form of YYYY-MM-DD.
    // Date.toISOString returns YYYY-MM-DDTHH:MM:SSZ. Split at the "T" and
    // take the date which is the first part.
    var isoDate = function(isoDateTime) {
        return isoDateTime.split("T")[0];
    };

    // Create the layer for the current day
    var createProvider = function(layer_id) {
        var layer = config.layers[layer_id];
        var time = "";

        if ( layer.startDate ) {
            var isoDateTime = clock.currentTime.toString();
            time = "?TIME=" + isoDate(isoDateTime);
        }

        var provider;
        if ( !layer.wms ) {
            var resolution = config.resolutions[layer.resolution];
            var options = {
                url: "//map1.vis.earthdata.nasa.gov/wmts-geo/wmts.cgi" + time,
                layer: layer.id,
                style: "",
                format: layer.format,
                tileMatrixSetID: resolution.tileMatrixSetID,
                minimumLevel: 0,
                maximumLevel: resolution.maximumLevel,
                tileWidth: 512,
                tileHeight: 512,
                tilingScheme: gibs.GeographicTilingScheme()
            };
            if ( layer.credit ) {
                options.credit = layer.credit;
            }
            provider = new Cesium.WebMapTileServiceImageryProvider(options);
        } else {
            var options = {
                url: "//map2.vis.earthdata.nasa.gov/wms/wms.php" + time,
                layers: layer.id,
                parameters: {
                    transparent: true,
                    format: "image/png"
                }
            };
            if ( layer.credit ) {
                options.credit = layer.credit;
            }
            provider = new Cesium.WebMapServiceImageryProvider(options);
        }
        return provider;
    };

    // Invoked when the current day changes, but do not call this too often
    // if the user is sweeping through days.
    var updateLayers = _.throttle(function() {
        var isoDateTime = clock.currentTime.toString();
        var time = isoDate(isoDateTime);
        var layers = viewer.scene.imageryLayers;
        layers.removeAll();
        _.each(selectedSet.layers, function(layer_id) {
            layers.addImageryProvider(createProvider(layer_id));
        });

        var legend = selectedSet.legend;
        if ( !legend ) {
            $("#legend").hide();
        } else if ( legend.type === "scale" ) {
            $(".legend-title").html(legend.title);
            $(".legend-colorbar").attr("src", legend.colorbar);
            $(".legend-max").html(legend.max);
            $(".legend-min").html(legend.min);
            $("#legend .single").hide();
            $("#legend .scale").show();
            $("#legend").show();
        } else {
            $(".legend-title").html(legend.title);
            $(".legend-color").css("background-color", legend.color);
            $("#legend .scale").hide();
            $("#legend .single").show();
            $("#legend").show();
        }
    }, 250, {leading: true, trailing: true});;

    // When the clock changes, check to see if the day has changed and
    // replace the current layers/
    var onClockUpdate = function() {
        var isoDateTime = clock.currentTime.toString();
        var time = isoDate(isoDateTime);
        if ( time !== previousTime ) {
            previousTime = time;
            updateLayers();
        }
    };

    var models = [];
    _.each(config.sets, function(set) {
        var model = new Cesium.ProviderViewModel({
            name: set.name,
            tooltip: "Hello",
            iconUrl: set.icon,
            creationFunction: function() {
                // Return an empty set and update the layers in the same
                // way done when the clock changes.
                selectedSet = set;
                _.defer(updateLayers);
                return [];
            }
        });
        models.push(model);
    });

    var viewer = new Cesium.Viewer("map", {
        clock: clock,
        imageryProviderViewModels: models,
        terrainProviderViewModels: []
    });

    viewer.timeline.zoomTo(startTime, endTime);
    viewer.clock.onTick.addEventListener(onClockUpdate);
    onClockUpdate();
    viewer.scene.globe.baseColor = Cesium.Color.BLACK;

    var getLeadingPoint = function() {
        // Set default extent according to time of day:
        //   at 00:00 UTC, start at far eastern edge of map: "20.6015625,-46.546875,179.9296875,53.015625"
        //   at 23:00 UTC, start at far western edge of map: "-179.9296875,-46.546875,-20.6015625,53.015625"
        var curHour = new Date().getUTCHours();

        // For earlier hours when data is still being filled in, force a far eastern perspective
        if (curHour < 3) {
            curHour = 23;
        }

        // Compute east/west bounds
        var minLon = 20.6015625 + curHour * (-200.53125/23.0) + 20;
        var maxLon = minLon + 159.328125;

        var minLat = -46.546875;
        var maxLat = 53.015625;

        return new Cesium.Rectangle(
            Cesium.Math.toRadians(minLon),
            Cesium.Math.toRadians(minLat),
            Cesium.Math.toRadians(maxLon),
            Cesium.Math.toRadians(maxLat)
        );
    };

    viewer.camera.viewRectangle(getLeadingPoint());

    return viewer;
};

<commit_msg>Adjust starting point due to globe view<commit_after>/**
* GIBS Web Examples
*
* Copyright 2013 - 2015 United States Government as represented by the
* Administrator of the National Aeronautics and Space Administration.
* 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.
*/

var gibs = gibs || {};

gibs.Viewer = function(config) {

    // Earliest date of Corrected Reflectance in archive: May 8, 2012
    var startTime = Cesium.JulianDate.fromDate(
            new Date(Date.UTC(2012, 4, 8)));

    var endTime = Cesium.JulianDate.now();

    // If slightly after midnight, show the previous day's data while
    // the near-real time imagery is processing.
    var show = new Date();
    if ( show.getUTCHours() < 3 ) {
        show.setUTCDate(show.getUTCDate() - 1);
    }
    var initialTime = Cesium.JulianDate.fromDate(show);

    // Keep track of the previous day. Only update the layer on a tick if the
    // day has actually changed.
    var previousTime = null;
    var selectedSet = null;

    var clock = new Cesium.Clock({
        currentTime: initialTime,
        multiplier: 0, // Don't start animation by default
        startTime: startTime,
        endTime: endTime,
        clockRange: Cesium.ClockRange.CLAMPED
    });

    // GIBS needs the day as a string parameter in the form of YYYY-MM-DD.
    // Date.toISOString returns YYYY-MM-DDTHH:MM:SSZ. Split at the "T" and
    // take the date which is the first part.
    var isoDate = function(isoDateTime) {
        return isoDateTime.split("T")[0];
    };

    // Create the layer for the current day
    var createProvider = function(layer_id) {
        var layer = config.layers[layer_id];
        var time = "";

        if ( layer.startDate ) {
            var isoDateTime = clock.currentTime.toString();
            time = "?TIME=" + isoDate(isoDateTime);
        }

        var provider;
        if ( !layer.wms ) {
            var resolution = config.resolutions[layer.resolution];
            var options = {
                url: "//map1.vis.earthdata.nasa.gov/wmts-geo/wmts.cgi" + time,
                layer: layer.id,
                style: "",
                format: layer.format,
                tileMatrixSetID: resolution.tileMatrixSetID,
                minimumLevel: 0,
                maximumLevel: resolution.maximumLevel,
                tileWidth: 512,
                tileHeight: 512,
                tilingScheme: gibs.GeographicTilingScheme()
            };
            if ( layer.credit ) {
                options.credit = layer.credit;
            }
            provider = new Cesium.WebMapTileServiceImageryProvider(options);
        } else {
            var options = {
                url: "//map2.vis.earthdata.nasa.gov/wms/wms.php" + time,
                layers: layer.id,
                parameters: {
                    transparent: true,
                    format: "image/png"
                }
            };
            if ( layer.credit ) {
                options.credit = layer.credit;
            }
            provider = new Cesium.WebMapServiceImageryProvider(options);
        }
        return provider;
    };

    // Invoked when the current day changes, but do not call this too often
    // if the user is sweeping through days.
    var updateLayers = _.throttle(function() {
        var isoDateTime = clock.currentTime.toString();
        var time = isoDate(isoDateTime);
        var layers = viewer.scene.imageryLayers;
        layers.removeAll();
        _.each(selectedSet.layers, function(layer_id) {
            layers.addImageryProvider(createProvider(layer_id));
        });

        var legend = selectedSet.legend;
        if ( !legend ) {
            $("#legend").hide();
        } else if ( legend.type === "scale" ) {
            $(".legend-title").html(legend.title);
            $(".legend-colorbar").attr("src", legend.colorbar);
            $(".legend-max").html(legend.max);
            $(".legend-min").html(legend.min);
            $("#legend .single").hide();
            $("#legend .scale").show();
            $("#legend").show();
        } else {
            $(".legend-title").html(legend.title);
            $(".legend-color").css("background-color", legend.color);
            $("#legend .scale").hide();
            $("#legend .single").show();
            $("#legend").show();
        }
    }, 250, {leading: true, trailing: true});;

    // When the clock changes, check to see if the day has changed and
    // replace the current layers/
    var onClockUpdate = function() {
        var isoDateTime = clock.currentTime.toString();
        var time = isoDate(isoDateTime);
        if ( time !== previousTime ) {
            previousTime = time;
            updateLayers();
        }
    };

    var models = [];
    _.each(config.sets, function(set) {
        var model = new Cesium.ProviderViewModel({
            name: set.name,
            tooltip: "Hello",
            iconUrl: set.icon,
            creationFunction: function() {
                // Return an empty set and update the layers in the same
                // way done when the clock changes.
                selectedSet = set;
                _.defer(updateLayers);
                return [];
            }
        });
        models.push(model);
    });

    var viewer = new Cesium.Viewer("map", {
        clock: clock,
        imageryProviderViewModels: models,
        terrainProviderViewModels: []
    });

    viewer.timeline.zoomTo(startTime, endTime);
    viewer.clock.onTick.addEventListener(onClockUpdate);
    onClockUpdate();
    viewer.scene.globe.baseColor = Cesium.Color.BLACK;

    var getLeadingPoint = function() {
        // Set default extent according to time of day:
        //   at 00:00 UTC, start at far eastern edge of map: "20.6015625,-46.546875,179.9296875,53.015625"
        //   at 23:00 UTC, start at far western edge of map: "-179.9296875,-46.546875,-20.6015625,53.015625"
        var curHour = new Date().getUTCHours();

        // For earlier hours when data is still being filled in, force a far eastern perspective
        if (curHour < 3) {
            curHour = 23;
        }

        // Adjust for globe view
        curHour -= 5;

        // Compute east/west bounds
        var minLon = 20.6015625 + curHour * (-200.53125/23.0);
        var maxLon = minLon + 159.328125;

        var minLat = -46.546875;
        var maxLat = 53.015625;

        return new Cesium.Rectangle(
            Cesium.Math.toRadians(minLon),
            Cesium.Math.toRadians(minLat),
            Cesium.Math.toRadians(maxLon),
            Cesium.Math.toRadians(maxLat)
        );
    };

    viewer.camera.viewRectangle(getLeadingPoint());

    return viewer;
};

<|endoftext|>


<commit_before>var TwilioApp = function(document, options){
  var self = this;

  this.TWILIO_NUMBER = '+13608136586';
  this.TARGET_NUMBER = '+12068198408';
  this.TOKEN_URL = 'http://localhost:8001/';

  this.ariaLiveDiv = document.querySelector('[aria-live]');

  this.fetchAuthToken();

  // Register an event handler to be called a connection is attempted:
  Twilio.Device.incoming(function(connection) {
    console.log(connection);
    self.updateLiveRegion('Call in progress...');
  });

  // Register an event handler for when a call ends for any reason
  Twilio.Device.disconnect(function(connection) {
    self.updateLiveRegion('Disconnected');
  });
};
TwilioApp.prototype = {
  fetchAuthToken: function(){
    var self = this;
    var r = new XMLHttpRequest();
    r.overrideMimeType("application/json");
    r.open("GET", this.TOKEN_URL, true);
    r.onreadystatechange = function () {
      if (r.readyState != 4 || r.status != 200) return;
      self.setUpDevice(JSON.parse(r.responseText));
    };
    r.send(null);
  },
  setUpDevice: function(response){
    var self = this;

    Twilio.Device.setup(response.token);

    Twilio.Device.ready(function() {
      console.log('ready');

      self.updateLiveRegion('Ready for tacos!');
    });
  },
  makeCall: function() {
    console.log(this);
    Twilio.Device.connect({
      CallerId: this.TWILIO_NUMBER,
      PhoneNumber: this.TARGET_NUMBER
    });
  },
  hangUp: function(){
    Twilio.Device.disconnectAll();
  },
  updateLiveRegion: function(message) {
    var messageEl = '
'+message+'
';
    this.ariaLiveDiv.innerHTML = messageEl;
  }
};

<commit_msg>testing url<commit_after>var TwilioApp = function(document, options){
  var self = this;

  this.TWILIO_NUMBER = '+13608136586';
  this.TARGET_NUMBER = '+12068198408';
  this.TOKEN_URL = 'http://10.0.0.81:8001/';

  this.ariaLiveDiv = document.querySelector('[aria-live]');

  this.fetchAuthToken();

  // Register an event handler to be called a connection is attempted:
  Twilio.Device.incoming(function(connection) {
    console.log(connection);
    self.updateLiveRegion('Call in progress...');
  });

  // Register an event handler for when a call ends for any reason
  Twilio.Device.disconnect(function(connection) {
    self.updateLiveRegion('Disconnected');
  });
};
TwilioApp.prototype = {
  fetchAuthToken: function(){
    var self = this;
    var r = new XMLHttpRequest();
    r.overrideMimeType("application/json");
    r.open("GET", this.TOKEN_URL, true);
    r.onreadystatechange = function () {
      if (r.readyState != 4 || r.status != 200) return;
      self.setUpDevice(JSON.parse(r.responseText));
    };
    r.send(null);
  },
  setUpDevice: function(response){
    var self = this;

    Twilio.Device.setup(response.token);

    Twilio.Device.ready(function() {
      console.log('ready');

      self.updateLiveRegion('Ready for tacos!');
    });
  },
  makeCall: function() {
    console.log(this);
    Twilio.Device.connect({
      CallerId: this.TWILIO_NUMBER,
      PhoneNumber: this.TARGET_NUMBER
    });
  },
  hangUp: function(){
    Twilio.Device.disconnectAll();
  },
  updateLiveRegion: function(message) {
    var messageEl = '
'+message+'
';
    this.ariaLiveDiv.innerHTML = messageEl;
  }
};

<|endoftext|>


<commit_before>var ps;
var zoomed = 0;
var rot = 0;

function zoom(amt){
  zoomed += amt * 2;
}

function render() {

  // transform point cloud
  ps.translate(0,0,zoomed);
  ps.rotateY(rot+=0.01);

  // redraw
  ps.clear();
  ps.render();

  window.status = Math.floor(ps.frameRate);
}

function start(){
  ps = new PointStream();

  ps.setup(document.getElementById('canvas'), render);
  ps.background([.2,.5,.7,1]);

  ps.onMouseScroll = zoom;

  ps.loadFile({path:"mickey.asc", autoCenter: true});
}
<commit_msg>updaed mickey demo with mouse button controls<commit_after>var ps;

var buttonDown = false;
var zoomed = 0;

var rot =[0,0];
var curCoords = [0,0];

var size = 500;

function zoom(amt){
  zoomed += amt * 2;
  size += amt * 10;

  if(ps.mouseX < 25 && ps.mouseY < 25){
    ps.resize(size, size);
    ps.background([0,0,0,1]);
  }
}

function mousePressed(){
  curCoords[0] = ps.mouseX;
  curCoords[1] = ps.mouseY;
  buttonDown = true;
}

function mouseReleased(){
  buttonDown = false;
}

function render() {

  var deltaX = ps.mouseX - curCoords[0];
  var deltaY = ps.mouseY - curCoords[1];

  if(buttonDown){
    rot[0] += deltaX / 250;
    rot[1] += deltaY / 250;
    curCoords[0] = ps.mouseX;
    curCoords[1] = ps.mouseY;
  }

  // transform point cloud
  ps.translate(0,0,zoomed);

  ps.rotateY(rot[0]);
  ps.rotateX(rot[1]);

  // redraw
  ps.clear();
  ps.render();
}

function start(){
  ps = new PointStream();

  ps.setup(document.getElementById('canvas'), render);
  ps.background([0.3,0.5,0.7,1]);

  ps.onMouseScroll = zoom;
  ps.onMousePressed = mousePressed;
  ps.onMouseReleased = mouseReleased;

  ps.loadFile({path:"mickey.asc", autoCenter: true});
}
<|endoftext|>


<commit_before>var B = require('sanctuary').B

exports.today = env =>
  env === 'heroku-test' ? "'2017-08-15'" : "curdate()"

exports.due_dates = start => end => compare => {
  var wrap =
    month_and_day(start) < month_and_day(end) ? x => x : x => `not(${x})`

  return wrap(`${set_2000(compare)}
    between ${set_2000(`'${new Date(start).toISOString()}'`)}
    and ${set_2000(`'${new Date(end).toISOString()}'`)}`)
}

var set_year = year => date => `date_format(${date}, '${year}-%m-%d')`

var set_2000 = set_year('2000')

var current_year = env =>
  process.env.NODE_ENV === 'heroku-test'
  ? '2017'
  : JSON.stringify((new Date).getFullYear())

exports.set_current = B(set_year, current_year)

var month_and_day = date_string => date_string.split('-').slice(1).join()

<commit_msg>Fix subscription due query.<commit_after>var B = require('sanctuary').B

exports.today = env =>
  env === 'heroku-test' ? "'2017-08-15'" : "curdate()"

exports.due_dates = start => end => compare => {
  var wrap =
    month_and_day(start) < month_and_day(end) ? x => x : x => `not(${x})`

  return wrap(`${set_2000(compare)}
    between ${set_2000(`'${start}'`)}
    and ${set_2000(`'${end}'`)}`)
}

var set_year = year => date => `date_format(${date}, '${year}-%m-%d')`

var set_2000 = set_year('2000')

var current_year = env =>
  env === 'heroku-test'
  ? '2017'
  : JSON.stringify((new Date()).getFullYear())

exports.set_current = B(set_year, current_year)

var month_and_day = date_string => date_string.split('-').slice(1).join()
<|endoftext|>


<commit_before>'use strict';

const unirest = require("unirest")
const ApiHealthCheckService = require('../services/ApiHealthCheckService')
const JWT = require("./Token");
const Utils = require('../helpers/utils');
const ProxyHooks = require('../services/KongProxyHooks');
const _ = require('lodash');

function getParameterByName(name, url) {
  if (!url) url = window.location.href;
  name = name.replace(/[\[\]]/g, '\\$&');
  var regex = new RegExp('[?&]' + name + '(=([^&#]*)|&|#|$)'),
    results = regex.exec(url);
  if (!results) return null;
  if (!results[2]) return '';
  return decodeURIComponent(results[2].replace(/\+/g, ' '));
}

var KongService = {

  headers: function (node, isJSON) {

    // Monkey-patch backwards compatibility with request obj
    var connection = node.connection || node;
    var headers = {};

    if (isJSON) {
      headers = {'Content-Type': 'application/json'}
    }

    // Set required headers according to connection type
    switch (connection.type) {
      case "key_auth":
        headers.apikey = connection.kong_api_key;
        break;
      case "jwt":
        var token = JWT.issueKongConnectionToken(connection);
        headers.Authorization = "Bearer " + token;
        break;
    }

    return headers;
  },

  create: function (req, res) {

    unirest.post(Utils.withoutTrailingSlash(req.connection.kong_admin_url) + req.url.replace('/kong', ''))
      .headers(KongService.headers(req, true))
      .send(req.body)
      .end(function (response) {
        if (response.error) return res.kongError(response);
        return res.json(response.body);
      });
  },

  createCb: function (req, res, cb) {

    unirest.post(Utils.withoutTrailingSlash(req.connection.kong_admin_url) + req.url.replace('/kong', ''))
      .headers(KongService.headers(req, true))
      .send(req.body)
      .end(function (response) {
        if (response.error) return cb(response);
        return cb(null, response.body);
      });
  },

  createFromEndpointCb: function (endpoint, data, req, cb) {

    unirest.post(Utils.withoutTrailingSlash(req.connection.kong_admin_url) + endpoint)
      .headers(KongService.headers(req, true))
      .send(data)
      .end(function (response) {
        if (response.error) return cb(response)
        return cb(null, response.body)
      });
  },

  deleteFromEndpointCb: function (endpoint, req, cb) {
    sails.log('Deleting ' + Utils.withoutTrailingSlash(req.connection.kong_admin_url) + endpoint);
    unirest.delete(Utils.withoutTrailingSlash(req.connection.kong_admin_url) + endpoint)
      .headers(KongService.headers(req, true))
      .end(function (response) {
        if (response.error) return cb(response)
        return cb(null, response.body)
      });
  },

  retrieve: function (req, res) {
    unirest.get(Utils.withoutTrailingSlash(req.connection.kong_admin_url) + req.url.replace('/kong', ''))
      .headers(KongService.headers(req, true))
      .end(function (response) {
        if (response.error) return res.kongError(response);
        return res.json(response.body);
      });
  },

  get: function (req, endpoint) {
    var self = this;
    return new Promise((resolve, reject) => {
      self.listAllCb(req, endpoint, (err, data) => {
        if (err) return reject(err);
        resolve(data);
      })
    });
  },

  fetch: (endpoint,req) => {
    return new Promise((resolve, reject) => {
      KongService.listAllCb(req, endpoint, (err, data) => {
        if(err) {
          return reject(err)
        }
        return resolve(data)
      })
    })
  },

  nodeStatus: function (node, cb) {

    unirest.get(Utils.withoutTrailingSlash(node.kong_admin_url) + "/status")
      .headers(KongService.headers(node, true))
      .end(function (response) {
        if (response.error) return cb(response);
        return cb(null, response.body);
      });
  },

  nodeInfo: function (node, cb) {
    unirest.get(Utils.withoutTrailingSlash(node.kong_admin_url))
      .headers(KongService.headers(node, true))
      .end(function (response) {
        if (response.error) return cb(response);
        return cb(null, response.body);
      });
  },

  info: function (connection) {
    return new Promise((resolve, reject) => {
      unirest.get(Utils.withoutTrailingSlash(connection.kong_admin_url))
        .headers(KongService.headers(connection, true))
        .end(function (response) {
          if (response.error) return reject(response);
          return resolve(response.body);
        });
    });
  },

  listAllCb: function (req, endpoint, cb) {
    var url = (Utils.withoutTrailingSlash(req.kong_admin_url) || Utils.withoutTrailingSlash(req.connection.kong_admin_url)) + endpoint;

    // Always add size=1000 the url just to be sure
    // no more than the needed amount of requests are performed
    const sizeParam = getParameterByName('size', url);
    if(!sizeParam)  url += url.indexOf('?') > -1 ? `&size=1000` : `?size=1000`;

    sails.log.debug('KongService: listAllCb', url);
    var getData = function (previousData, url) {
      unirest.get(url)
        .headers(KongService.headers(req, true))
        .end(function (response) {
          if (response.error) return cb(response)
          var data = previousData.concat(response.body.data);
          if (response.body.next) {
            getData(data, (Utils.withoutTrailingSlash(req.kong_admin_url) || Utils.withoutTrailingSlash(req.connection.kong_admin_url)) + response.body.next);
          }
          else {
            response.body.data = data;
            ProxyHooks.afterEntityList(endpoint.replace('/', '').split('?')[0], req, response.body, (err, finalData) => {
              if (err) return cb(err);
              return cb(null, finalData)
            })
          }
        });
    };
    getData([], `${url}`);
  },

  list: function (req, res) {
    var getData = function (previousData, url) {
      unirest.get(url)
        .headers(KongService.headers(req, true))
        .end(function (response) {
          if (response.error) return res.kongError(response)
          var apis = previousData.concat(response.body.data);
          if (response.body.next) {
            getData(apis, response.body.next);
          }
          else {
            response.body.data = apis;
            return res.json(response.body);
          }
        });
    };
    getData([], (Utils.withoutTrailingSlash(req.kong_admin_url) || Utils.withoutTrailingSlash(req.connection.kong_admin_url)) + req.url.replace('/kong', ''));
  },

  update: function (req, res) {
    unirest.patch(Utils.withoutTrailingSlash(req.connection.kong_admin_url) + req.url.replace('/kong', ''))
      .headers(KongService.headers(req, true))
      .send(req.body)
      .end(function (response) {
        if (response.error) return res.kongError(response);

        if (req.url.indexOf("/kong/apis") > -1) {
          // If api was updated, update its health checks as well
          ApiHealthCheckService.updateCb({
            api_id: response.body.id
          }, {api: response.body}, function (err, updated) {
          });
        }

        return res.json(response.body);
      });
  },

  updateCb: function (req, res, cb) {
    unirest.patch(Utils.withoutTrailingSlash(req.connection.kong_admin_url) + req.url.replace('/kong', ''))
      .headers(KongService.headers(req, true))
      .send(req.body)
      .end(function (response) {
        if (response.error) return cb(response);

        if (req.url.indexOf("/kong/apis") > -1) {
          // If api was updated, update its health checks as well
          // If api was updated, update its health checks as well
          ApiHealthCheckService.updateCb({
            api_id: response.body.id
          }, {api: response.body}, function (err, updated) {
          });
        }

        return cb(null, response.body);
      });
  },

  updateOrCreate: function (req, res) {
    unirest.put(Utils.withoutTrailingSlash(req.connection.kong_admin_url) + req.url.replace('/kong', ''))
      .headers(KongService.headers(req, true))
      .send(req.body)
      .end(function (response) {
        if (response.error) return res.kongError(response);
        return res.json(response.body);
      });
  },

  delete: function (req, res) {
    unirest.delete(Utils.withoutTrailingSlash(req.connection.kong_admin_url) + req.url.replace('/kong', ''))
      .headers(KongService.headers(req, true))
      .end(function (response) {
        if (response.error) return res.kongError(response);

        if (req.url.indexOf("/kong/apis") > -1) {
          // If api was deleted, delete its health checks as well
          var id = req.url.substr(req.url.lastIndexOf('/') + 1)

          // If api was updated, update its health checks as well
          ApiHealthCheckService.deleteCb({
            api_id: id
          }, function (err, updated) {
          });
        }

        return res.json(response.body);
      })
  },

  deleteCb: function (req, res, cb) {
    unirest.delete(Utils.withoutTrailingSlash(req.connection.kong_admin_url) + req.url.replace('/kong', ''))
      .headers(KongService.headers(req, true))
      .end(function (response) {
        if (response.error) return cb(response);

        if (req.url.indexOf("/kong/apis") > -1) {
          // If api was deleted, delete its health checks as well
          var id = req.url.pop() || req.url.pop();  // handle potential trailing slash

          ApiHealthCheckService.deleteCb({
            api_id: id
          }, function (err, updated) {
          });
        }

        return cb(null, response.body);
      });
  },

  put: function (url, connection, data) {
    // sails.log("KongService.put called() =>", url, connection, data);
    return new Promise((resolve, reject) => {
      unirest.put(Utils.withoutTrailingSlash(connection.kong_admin_url) +url.replace('/kong', ''))
        .headers(KongService.headers(connection, true))
        .send(data)
        .end(function (response) {
          if (response.error) return reject(response);
          return resolve(response.body);
        });
    })
  },

  post: function (url, connection, data) {
    // sails.log("KongService.put called() =>", url, connection, data);
    return new Promise((resolve, reject) => {
      unirest.post(Utils.withoutTrailingSlash(connection.kong_admin_url) +url.replace('/kong', ''))
        .headers(KongService.headers(connection, true))
        .send(data)
        .end(function (response) {
          if (response.error) return reject(response);
          return resolve(response.body);
        });
    })
  },

  fetchConsumerRoutes: async (req, consumerId, consumerAuths, consumerGroups, allPlugins) => {

    // Fetch all routes
    const routesRecords = await KongService.fetch(`/routes`, req)
    let routes = routesRecords.data;

    routes.forEach(route => {
      // Assign the consumer_id to the route.
      // We need this @ the frontend
      route.consumer_id = consumerId;

      // Assign plugins to the service
      route.plugins = _.filter(allPlugins, plugin => route.id === _.get(plugin, 'route.id'));

      // Separate acl plugins in an acl property
      // We will need this to better handle things @ the frontend
      let acl = _.find(route.plugins,item => item.name === 'acl');
      if(acl) route.acl = acl;

      let authenticationPlugins = _.filter(route.plugins, item => ['jwt','basic-auth','key-auth','hmac-auth','oauth2'].indexOf(item.name) > -1);
      authenticationPlugins = _.map(authenticationPlugins, item => item.name);
      sails.log("authenticationPlugins",authenticationPlugins);
      route.auths = authenticationPlugins;
    })

    // Gather routes with no access control restrictions whatsoever
    let open =  _.filter(routes,function (route) {
      return !route.acl && !route.auths.length;
    })

    // Gather routes with auths matching at least on consumer credential
    let matchingAuths = _.filter(routes,function (route) {
      return _.intersection(route.auths, consumerAuths).length > 0;
    });

    // Gather routes with access control restrictions whitelisting at least one of the consumer's groups.
    let whitelisted = _.filter(routes,function (route) {
      return route.acl && _.intersection(route.acl.config.whitelist,consumerGroups).length > 0;
    });

    // Gather routes  with no authentication plugins
    // & access control restrictions whitelisting at least one of the consumer's groups.
    let whitelistedNoAuth = _.filter(routes,function (route) {
      return route.acl
        && _.intersection(route.acl.config.whitelist,consumerGroups).length > 0
        && (!route.auths || !route.auths.length);
    });

    // Gather routes with no access control restrictions whatsoever
    let eligible = matchingAuths.length && whitelisted.length ? _.intersection(matchingAuths, whitelisted) : matchingAuths.concat(whitelisted);
    eligible = eligible.concat(whitelistedNoAuth);

    return {
      total : open.length + eligible.length,
      data  : open.concat(eligible)
    }

  }

}

module.exports = KongService
<commit_msg>Handle unexpected response<commit_after>'use strict';

const unirest = require("unirest")
const ApiHealthCheckService = require('../services/ApiHealthCheckService')
const JWT = require("./Token");
const Utils = require('../helpers/utils');
const ProxyHooks = require('../services/KongProxyHooks');
const _ = require('lodash');

function getParameterByName(name, url) {
  if (!url) url = window.location.href;
  name = name.replace(/[\[\]]/g, '\\$&');
  var regex = new RegExp('[?&]' + name + '(=([^&#]*)|&|#|$)'),
    results = regex.exec(url);
  if (!results) return null;
  if (!results[2]) return '';
  return decodeURIComponent(results[2].replace(/\+/g, ' '));
}

var KongService = {

  headers: function (node, isJSON) {

    // Monkey-patch backwards compatibility with request obj
    var connection = node.connection || node;
    var headers = {};

    if (isJSON) {
      headers = {'Content-Type': 'application/json'}
    }

    // Set required headers according to connection type
    switch (connection.type) {
      case "key_auth":
        headers.apikey = connection.kong_api_key;
        break;
      case "jwt":
        var token = JWT.issueKongConnectionToken(connection);
        headers.Authorization = "Bearer " + token;
        break;
    }

    return headers;
  },

  create: function (req, res) {

    unirest.post(Utils.withoutTrailingSlash(req.connection.kong_admin_url) + req.url.replace('/kong', ''))
      .headers(KongService.headers(req, true))
      .send(req.body)
      .end(function (response) {
        if (response.error) return res.kongError(response);
        return res.json(response.body);
      });
  },

  createCb: function (req, res, cb) {

    unirest.post(Utils.withoutTrailingSlash(req.connection.kong_admin_url) + req.url.replace('/kong', ''))
      .headers(KongService.headers(req, true))
      .send(req.body)
      .end(function (response) {
        if (response.error) return cb(response);
        return cb(null, response.body);
      });
  },

  createFromEndpointCb: function (endpoint, data, req, cb) {

    unirest.post(Utils.withoutTrailingSlash(req.connection.kong_admin_url) + endpoint)
      .headers(KongService.headers(req, true))
      .send(data)
      .end(function (response) {
        if (response.error) return cb(response)
        return cb(null, response.body)
      });
  },

  deleteFromEndpointCb: function (endpoint, req, cb) {
    sails.log('Deleting ' + Utils.withoutTrailingSlash(req.connection.kong_admin_url) + endpoint);
    unirest.delete(Utils.withoutTrailingSlash(req.connection.kong_admin_url) + endpoint)
      .headers(KongService.headers(req, true))
      .end(function (response) {
        if (response.error) return cb(response)
        return cb(null, response.body)
      });
  },

  retrieve: function (req, res) {
    unirest.get(Utils.withoutTrailingSlash(req.connection.kong_admin_url) + req.url.replace('/kong', ''))
      .headers(KongService.headers(req, true))
      .end(function (response) {
        if (response.error) return res.kongError(response);
        return res.json(response.body);
      });
  },

  get: function (req, endpoint) {
    var self = this;
    return new Promise((resolve, reject) => {
      self.listAllCb(req, endpoint, (err, data) => {
        if (err) return reject(err);
        resolve(data);
      })
    });
  },

  fetch: (endpoint,req) => {
    return new Promise((resolve, reject) => {
      KongService.listAllCb(req, endpoint, (err, data) => {
        if(err) {
          return reject(err)
        }
        return resolve(data)
      })
    })
  },

  nodeStatus: function (node, cb) {

    unirest.get(Utils.withoutTrailingSlash(node.kong_admin_url) + "/status")
      .headers(KongService.headers(node, true))
      .end(function (response) {
        if (response.error) return cb(response);
        return cb(null, response.body);
      });
  },

  nodeInfo: function (node, cb) {
    unirest.get(Utils.withoutTrailingSlash(node.kong_admin_url))
      .headers(KongService.headers(node, true))
      .end(function (response) {
        if (response.error) return cb(response);
        return cb(null, response.body);
      });
  },

  info: function (connection) {
    return new Promise((resolve, reject) => {
      unirest.get(Utils.withoutTrailingSlash(connection.kong_admin_url))
        .headers(KongService.headers(connection, true))
        .end(function (response) {
          if (response.error) return reject(response);
          return resolve(response.body);
        });
    });
  },

  listAllCb: function (req, endpoint, cb) {
    var url = (Utils.withoutTrailingSlash(req.kong_admin_url) || Utils.withoutTrailingSlash(req.connection.kong_admin_url)) + endpoint;

    // Always add size=1000 the url just to be sure
    // no more than the needed amount of requests are performed
    const sizeParam = getParameterByName('size', url);
    if(!sizeParam)  url += url.indexOf('?') > -1 ? `&size=1000` : `?size=1000`;

    sails.log.debug('KongService: listAllCb', url);
    var getData = function (previousData, url) {
      unirest.get(url)
        .headers(KongService.headers(req, true))
        .end(function (response) {
          if (response.error) return cb(response)
          var data = previousData.concat(response.body.data);
          if (response.body.next) {
            getData(data, (Utils.withoutTrailingSlash(req.kong_admin_url) || Utils.withoutTrailingSlash(req.connection.kong_admin_url)) + response.body.next);
          }
          else {
            try {
              response.body.data = data;
              ProxyHooks.afterEntityList(endpoint.replace('/', '').split('?')[0], req, response.body, (err, finalData) => {
                if (err) return cb(err);
                return cb(null, finalData)
              })
            }catch(err) {
              return cb(null, {
                data: []
              })
            }

          }
        });
    };
    getData([], `${url}`);
  },

  list: function (req, res) {
    var getData = function (previousData, url) {
      unirest.get(url)
        .headers(KongService.headers(req, true))
        .end(function (response) {
          if (response.error) return res.kongError(response)
          var apis = previousData.concat(response.body.data);
          if (response.body.next) {
            getData(apis, response.body.next);
          }
          else {
            response.body.data = apis;
            return res.json(response.body);
          }
        });
    };
    getData([], (Utils.withoutTrailingSlash(req.kong_admin_url) || Utils.withoutTrailingSlash(req.connection.kong_admin_url)) + req.url.replace('/kong', ''));
  },

  update: function (req, res) {
    unirest.patch(Utils.withoutTrailingSlash(req.connection.kong_admin_url) + req.url.replace('/kong', ''))
      .headers(KongService.headers(req, true))
      .send(req.body)
      .end(function (response) {
        if (response.error) return res.kongError(response);

        if (req.url.indexOf("/kong/apis") > -1) {
          // If api was updated, update its health checks as well
          ApiHealthCheckService.updateCb({
            api_id: response.body.id
          }, {api: response.body}, function (err, updated) {
          });
        }

        return res.json(response.body);
      });
  },

  updateCb: function (req, res, cb) {
    unirest.patch(Utils.withoutTrailingSlash(req.connection.kong_admin_url) + req.url.replace('/kong', ''))
      .headers(KongService.headers(req, true))
      .send(req.body)
      .end(function (response) {
        if (response.error) return cb(response);

        if (req.url.indexOf("/kong/apis") > -1) {
          // If api was updated, update its health checks as well
          // If api was updated, update its health checks as well
          ApiHealthCheckService.updateCb({
            api_id: response.body.id
          }, {api: response.body}, function (err, updated) {
          });
        }

        return cb(null, response.body);
      });
  },

  updateOrCreate: function (req, res) {
    unirest.put(Utils.withoutTrailingSlash(req.connection.kong_admin_url) + req.url.replace('/kong', ''))
      .headers(KongService.headers(req, true))
      .send(req.body)
      .end(function (response) {
        if (response.error) return res.kongError(response);
        return res.json(response.body);
      });
  },

  delete: function (req, res) {
    unirest.delete(Utils.withoutTrailingSlash(req.connection.kong_admin_url) + req.url.replace('/kong', ''))
      .headers(KongService.headers(req, true))
      .end(function (response) {
        if (response.error) return res.kongError(response);

        if (req.url.indexOf("/kong/apis") > -1) {
          // If api was deleted, delete its health checks as well
          var id = req.url.substr(req.url.lastIndexOf('/') + 1)

          // If api was updated, update its health checks as well
          ApiHealthCheckService.deleteCb({
            api_id: id
          }, function (err, updated) {
          });
        }

        return res.json(response.body);
      })
  },

  deleteCb: function (req, res, cb) {
    unirest.delete(Utils.withoutTrailingSlash(req.connection.kong_admin_url) + req.url.replace('/kong', ''))
      .headers(KongService.headers(req, true))
      .end(function (response) {
        if (response.error) return cb(response);

        if (req.url.indexOf("/kong/apis") > -1) {
          // If api was deleted, delete its health checks as well
          var id = req.url.pop() || req.url.pop();  // handle potential trailing slash

          ApiHealthCheckService.deleteCb({
            api_id: id
          }, function (err, updated) {
          });
        }

        return cb(null, response.body);
      });
  },

  put: function (url, connection, data) {
    // sails.log("KongService.put called() =>", url, connection, data);
    return new Promise((resolve, reject) => {
      unirest.put(Utils.withoutTrailingSlash(connection.kong_admin_url) +url.replace('/kong', ''))
        .headers(KongService.headers(connection, true))
        .send(data)
        .end(function (response) {
          if (response.error) return reject(response);
          return resolve(response.body);
        });
    })
  },

  post: function (url, connection, data) {
    // sails.log("KongService.put called() =>", url, connection, data);
    return new Promise((resolve, reject) => {
      unirest.post(Utils.withoutTrailingSlash(connection.kong_admin_url) +url.replace('/kong', ''))
        .headers(KongService.headers(connection, true))
        .send(data)
        .end(function (response) {
          if (response.error) return reject(response);
          return resolve(response.body);
        });
    })
  },

  fetchConsumerRoutes: async (req, consumerId, consumerAuths, consumerGroups, allPlugins) => {

    // Fetch all routes
    const routesRecords = await KongService.fetch(`/routes`, req)
    let routes = routesRecords.data;

    routes.forEach(route => {
      // Assign the consumer_id to the route.
      // We need this @ the frontend
      route.consumer_id = consumerId;

      // Assign plugins to the service
      route.plugins = _.filter(allPlugins, plugin => route.id === _.get(plugin, 'route.id'));

      // Separate acl plugins in an acl property
      // We will need this to better handle things @ the frontend
      let acl = _.find(route.plugins,item => item.name === 'acl');
      if(acl) route.acl = acl;

      let authenticationPlugins = _.filter(route.plugins, item => ['jwt','basic-auth','key-auth','hmac-auth','oauth2'].indexOf(item.name) > -1);
      authenticationPlugins = _.map(authenticationPlugins, item => item.name);
      sails.log("authenticationPlugins",authenticationPlugins);
      route.auths = authenticationPlugins;
    })

    // Gather routes with no access control restrictions whatsoever
    let open =  _.filter(routes,function (route) {
      return !route.acl && !route.auths.length;
    })

    // Gather routes with auths matching at least on consumer credential
    let matchingAuths = _.filter(routes,function (route) {
      return _.intersection(route.auths, consumerAuths).length > 0;
    });

    // Gather routes with access control restrictions whitelisting at least one of the consumer's groups.
    let whitelisted = _.filter(routes,function (route) {
      return route.acl && _.intersection(route.acl.config.whitelist,consumerGroups).length > 0;
    });

    // Gather routes  with no authentication plugins
    // & access control restrictions whitelisting at least one of the consumer's groups.
    let whitelistedNoAuth = _.filter(routes,function (route) {
      return route.acl
        && _.intersection(route.acl.config.whitelist,consumerGroups).length > 0
        && (!route.auths || !route.auths.length);
    });

    // Gather routes with no access control restrictions whatsoever
    let eligible = matchingAuths.length && whitelisted.length ? _.intersection(matchingAuths, whitelisted) : matchingAuths.concat(whitelisted);
    eligible = eligible.concat(whitelistedNoAuth);

    return {
      total : open.length + eligible.length,
      data  : open.concat(eligible)
    }

  }

}

module.exports = KongService
<|endoftext|>


<commit_before>import L from 'leaflet'
import 'leaflet-rotatedmarker'
import "leaflet/dist/leaflet.css";

// https://github.com/Leaflet/Leaflet/issues/4968
/*
import icon from 'leaflet/dist/images/marker-icon.png';
import iconShadow from 'leaflet/dist/images/marker-shadow.png';

let DefaultIcon = L.icon({
    iconUrl: icon,
    shadowUrl: iconShadow
});

L.Marker.prototype.options.icon = DefaultIcon;
*/

delete L.Icon.Default.prototype._getIconUrl;

L.Icon.Default.mergeOptions({
  iconRetinaUrl: '/static/leaflet/dist/images/marker-icon-2x.png',
  iconUrl: '/static/leaflet/dist/images/marker-icon.png',
  shadowUrl: '/static/leaflet/dist/images/marker-shadow.png',
});

// LeafletWidget

export class LeafletWidget {

    constructor(options) {

        this.options = {
            url: 'https://api.tiles.mapbox.com/v4/{id}/{z}/{x}/{y}.png?access_token=',
            options: {
                attribution: 'Map data © OpenStreetMap contributors, CC-BY-SA, Imagery © Mapbox',
                maxZoom: 18,
                id: 'mapbox.streets'
            },

            lat: 32.53530431898372,
            lng: -116.9165934003241,
            zoom: 15,
            location_icon_url: '/static/icons/pin/blue.svg',
            location_icon_size: [32, 32],
            add_marker_control: false,
        };

        // Altering using user-provided options
        for (const property in options) {
            if (options.hasOwnProperty(property)) {
                this.options[property] = options[property];
            }
        }

        // create map
        this.map = L.map(this.options.map_id).setView(L.latLng(this.options.lat,
            this.options.lng),
            this.options.zoom);
        // add reference to parent object
        this.map.parent = this;

        // create title layer
        L.tileLayer(this.options.url + this.options.access_token,
            this.options.options).addTo(this.map);

        // add location controls
        const locateControl = L.Control.extend({

            options: {
                position: 'topleft'
            },

            onAdd: function (map) {

                const container = L.DomUtil.create('div',
                    'leaflet-bar leaflet-control leaflet-control-custom');

                container.style.width = '32px';
                container.style.height = '32px';
                container.style.backgroundImage = "url('/static/icons/mouse-pointer.svg')";
                container.style.backgroundPosition = 'center';
                container.style.backgroundSize = '20px 20px';
                container.style.backgroundColor = 'white';
                container.style.backgroundRepeat = 'no-repeat';

                /* tooltip */
                container.title = 'Go to your location';

                L.DomEvent
                    .addListener(container, 'click', L.DomEvent.stopPropagation)
                    .addListener(container, 'click', L.DomEvent.preventDefault)
                    .addListener(container, 'click', function () {
                        map.locate({setView: true, maxZoom: 14});
                    });

                return container;
            },

        });

        this.map.addControl(new locateControl());

        this.map.on('locationerror', function (e) {
            alert('Could not find location
 ' + e.message);
        });

        // location marker
        const location_icon = L.icon({
            iconUrl: this.options.location_icon_url,
            iconSize: this.options.location_icon_size,
        });

        // locate
        this.map.on('locationfound', function (e) {
            const parent = e.target.parent;
            if (typeof parent.current_location === 'undefined') {
                // create marker
                parent.current_location =
                    L.marker(parent.map.getCenter(),
                        {icon: location_icon}).addTo(parent.map);
            } else {
                // move marker
                parent.current_location.setLatLng(e.latlng);
            }
        });
    }

    fitBounds(bounds) {

        // Get bounds if not given
        bounds = bounds || this.map.getBounds();
        console.log('bounds = ' + bounds);

        // Fit map to bounds
        this.map.fitBounds(bounds);

    }

    center(position, zoom) {

        // Get zoom from map if not given
        zoom = zoom || this.map.getZoom();

        // center map
        this.map.setView([position.latitude, position.longitude], zoom);

    }

}

// LeafletMultiPointWidget

export class LeafletMultiPointWidget extends LeafletWidget {

    constructor(options) {

        // Call parent
        super(options)

        // store all marker id's
        this.markerIdMap = {};
        this.pointIdMap = {};

        // create layer
        this.markers = L.layerGroup();

        this.options.add_marker_control = true;
        if (this.options.add_marker_control) {

            this.clickToAddPoint = false;

            // add add marker control
            const addMarkerControl = L.Control.extend({

                options: {
                    position: 'topleft'
                },

                onAdd: function (map) {
                    const container = L.DomUtil.create('div',
                        'leaflet-bar leaflet-control leaflet-control-custom leaflet-add-marker leaflet-tooltip');

                    const tooltip = L.DomUtil.create('span',
                        'leaflet-tooltiptext',
                        container);
                    tooltip.textContent = 'Add AED';

                    map.parent.addControlCheckbox =
                        L.DomUtil.create('input',
                            'leaflet-add-marker-input',
                            container);
                    map.parent.addControlCheckbox.type = 'checkbox';
                    map.parent.addControlCheckbox.id = 'leaflet-add-marker-id';
                    map.parent.addControlCheckbox.map = this;

                    const label = L.DomUtil.create('label',
                        '',
                        container);
                    label.htmlFor = 'leaflet-add-marker-id';

                    L.DomEvent
                        .addListener(map.parent.addControlCheckbox,
                            'click', L.DomEvent.stopPropagation)
                        .addListener(map.parent.addControlCheckbox,
                            'click',
                            function (e) {
                                if (e.target.checked) {
                                    // enable click to add point
                                    e.target.map._map.parent.clickToAddPoint = true;
                                } else {
                                    // disable click to add point
                                    e.target.map._map.parent.clickToAddPoint = false;
                                }
                            });

                    return container;
                },

            });

            this.map.addControl(new addMarkerControl());

            // listen to click
            this.map.on('click', function (e) {
                const map = e.target.parent;
                if (map.clickToAddPoint) {
                    // add marker?
                    map.addPoint(e.latlng.lat, e.latlng.lng, -1, map.options.newPointFunction);
                    // disable add marker mode
                    map.addControlCheckbox.click();
                }

            });
        }
    }

    // MEMBER FUNCTIONS

    // add point
    addPoint(lat, lng, id, fun) {

        // add marker
        const marker = L.marker([lat, lng])
            .addTo(this.map);

        if (fun) {
            marker.on('click', fun);
        }

        L.stamp(marker);
        this.markers.addLayer(marker);

        if (id >= 0) {
            this.markerIdMap[marker._leaflet_id] = id;
            this.pointIdMap[id] = marker._leaflet_id;
        }

        // TODO: Disable add marker mode

        return marker;
    }

}

// LeafletPointWidget

export class LeafletPointWidget extends LeafletWidget {

    constructor(options) {

        // Call parent
        super(options);

        if (!this.options.point) {
            this.options.point = [options.lat, options.lng];
        }

        // add marker
        this.point = L.marker(L.latLng(this.options.point[0], this.options.point[1]),
            {draggable: true});
        this.point.addTo(this.map);

        // add reference to parent object
        this.point.parent = this;

        // call set point to update fields
        this.setPoint(L.latLng(this.options.point[0], this.options.point[1]));

        // set coordinates when dragged
        this.point.on('dragend', function (e) {
            e.target.parent.setPoint(e.target.getLatLng());
        });

        // set coordinates when map is click
        this.map.on('click',
            function (e) {
                e.target.parent.setPoint(e.latlng);
            });

    }

    // MEMBER FUNCTIONS

    // update point
    setPoint(p) {

        // set point coordinates
        this.point.setLatLng(p);

        // update fields
        if (this.options.id) {
            document.getElementById(this.options.id).value =
                'POINT(' + p.lng + ' ' + p.lat + ')';
        }
        if (this.options.id_lat) {
            document.getElementById(this.options.id_lat).value = p.lat;
        }
        if (this.options.id_lng) {
            document.getElementById(this.options.id_lng).value = p.lng;
        }
    }

}

// Polyline Widget

export class LeafletPolylineWidget extends LeafletWidget {

    constructor(options) {

        // Call parent
        super(options);

        // store all markers and lines id's
        this.polylineIdMap = {}
        this.markerIdMap = {};
        this.pointIdMap = {};

        // create layers
        this.layers = {};

        // create default layer
        this.createLayer('default');

        //this.map.createPane('defaultLeafletPolylineWidgetPane');
        //this.layers['default'] = {
        //        'markers': L.layerGroup({'pane': 'defaultLeafletPolylineWidget'}),
        //        'lines': L.layerGroup({'pane': 'defaultLeafletPolylineWidget'})
        //    };

    }

    createLayer(layer) {

        var layerName = layer + 'LeafletPolylineWidgetPane';
        this.map.createPane(layerName);
        this.layers[layer] = {
            'markers': L.layerGroup({'pane': layerName}),
            'lines': L.layerGroup({'pane': layerName})
        };

    }

    getLayerPane(layer) {

        var layerName = layer + 'LeafletPolylineWidgetPane';
        return this.map.getPane(layerName);

    }

    addLine(points, id, color, fun, layer) {

        fun = fun || null;
        layer = layer || 'default';

        // Create polyline
        var layerName = layer + 'LeafletPolylineWidgetPane';
        var polyline = L.polyline(points, {color: color, pane: layerName})
            .addTo(this.map);

        // Add click callback
        if (fun) {
            polyline.on('click', fun);
        }

        // Add marker
        L.stamp(polyline);
        this.layers[layer]['lines'].addLayer(polyline);

        // Track ids
        if (id >= 0) {
            this.polylineIdMap[polyline._leaflet_id] = id;
        }

        return polyline;
    }

    // add point
    addPoint(lat, lng, id, fun, layer) {

        fun = fun || null;
        layer = layer || 'default';

        // Create marker without a shaddow
        var icon = new L.Icon.Default();
        icon.options.shadowSize = [0, 0];
        var layerName = layer + 'LeafletPolylineWidgetPane';
        var marker = L.marker([lat, lng], {icon: icon, pane: layerName})
            .addTo(this.map);

        // Add click callback
        if (fun) {
            marker.on('click', fun);
        }

        // Add marker
        L.stamp(marker);
        this.layers[layer]['markers'].addLayer(marker);

        // Track ids
        if (id >= 0) {
            this.markerIdMap[marker._leaflet_id] = id;
            this.pointIdMap[id] = marker._leaflet_id;
        }

        return marker;
    }

}

<commit_msg>Bundling ambulance detail frontend.<commit_after>import L from 'leaflet'
import 'leaflet-rotatedmarker'
import "leaflet/dist/leaflet.css";

// https://github.com/Leaflet/Leaflet/issues/4968
import iconUrl from 'leaflet/dist/images/marker-icon.png';
import icon2xUrl from 'leaflet/dist/images/marker-icon-2x.png';
import iconShadowUrl from 'leaflet/dist/images/marker-shadow.png';

/*
let DefaultIcon = L.icon({
    iconUrl: icon,
    shadowUrl: iconShadow
});

L.Marker.prototype.options.icon = DefaultIcon;
*/

delete L.Icon.Default.prototype._getIconUrl;

L.Icon.Default.mergeOptions({
  iconRetinaUrl: icon2xUrl,
  iconUrl: iconUrl,
  shadowUrl: iconShadowUrl,
});

// LeafletWidget

export class LeafletWidget {

    constructor(options) {

        this.options = {
            url: 'https://api.tiles.mapbox.com/v4/{id}/{z}/{x}/{y}.png?access_token=',
            options: {
                attribution: 'Map data © OpenStreetMap contributors, CC-BY-SA, Imagery © Mapbox',
                maxZoom: 18,
                id: 'mapbox.streets'
            },

            lat: 32.53530431898372,
            lng: -116.9165934003241,
            zoom: 15,
            location_icon_url: '/static/icons/pin/blue.svg',
            location_icon_size: [32, 32],
            add_marker_control: false,
        };

        // Altering using user-provided options
        for (const property in options) {
            if (options.hasOwnProperty(property)) {
                this.options[property] = options[property];
            }
        }

        // create map
        this.map = L.map(this.options.map_id).setView(L.latLng(this.options.lat,
            this.options.lng),
            this.options.zoom);
        // add reference to parent object
        this.map.parent = this;

        // create title layer
        L.tileLayer(this.options.url + this.options.access_token,
            this.options.options).addTo(this.map);

        // add location controls
        const locateControl = L.Control.extend({

            options: {
                position: 'topleft'
            },

            onAdd: function (map) {

                const container = L.DomUtil.create('div',
                    'leaflet-bar leaflet-control leaflet-control-custom');

                container.style.width = '32px';
                container.style.height = '32px';
                container.style.backgroundImage = "url('/static/icons/mouse-pointer.svg')";
                container.style.backgroundPosition = 'center';
                container.style.backgroundSize = '20px 20px';
                container.style.backgroundColor = 'white';
                container.style.backgroundRepeat = 'no-repeat';

                /* tooltip */
                container.title = 'Go to your location';

                L.DomEvent
                    .addListener(container, 'click', L.DomEvent.stopPropagation)
                    .addListener(container, 'click', L.DomEvent.preventDefault)
                    .addListener(container, 'click', function () {
                        map.locate({setView: true, maxZoom: 14});
                    });

                return container;
            },

        });

        this.map.addControl(new locateControl());

        this.map.on('locationerror', function (e) {
            alert('Could not find location
 ' + e.message);
        });

        // location marker
        const location_icon = L.icon({
            iconUrl: this.options.location_icon_url,
            iconSize: this.options.location_icon_size,
        });

        // locate
        this.map.on('locationfound', function (e) {
            const parent = e.target.parent;
            if (typeof parent.current_location === 'undefined') {
                // create marker
                parent.current_location =
                    L.marker(parent.map.getCenter(),
                        {icon: location_icon}).addTo(parent.map);
            } else {
                // move marker
                parent.current_location.setLatLng(e.latlng);
            }
        });
    }

    fitBounds(bounds) {

        // Get bounds if not given
        bounds = bounds || this.map.getBounds();
        console.log('bounds = ' + bounds);

        // Fit map to bounds
        this.map.fitBounds(bounds);

    }

    center(position, zoom) {

        // Get zoom from map if not given
        zoom = zoom || this.map.getZoom();

        // center map
        this.map.setView([position.latitude, position.longitude], zoom);

    }

}

// LeafletMultiPointWidget

export class LeafletMultiPointWidget extends LeafletWidget {

    constructor(options) {

        // Call parent
        super(options)

        // store all marker id's
        this.markerIdMap = {};
        this.pointIdMap = {};

        // create layer
        this.markers = L.layerGroup();

        this.options.add_marker_control = true;
        if (this.options.add_marker_control) {

            this.clickToAddPoint = false;

            // add add marker control
            const addMarkerControl = L.Control.extend({

                options: {
                    position: 'topleft'
                },

                onAdd: function (map) {
                    const container = L.DomUtil.create('div',
                        'leaflet-bar leaflet-control leaflet-control-custom leaflet-add-marker leaflet-tooltip');

                    const tooltip = L.DomUtil.create('span',
                        'leaflet-tooltiptext',
                        container);
                    tooltip.textContent = 'Add AED';

                    map.parent.addControlCheckbox =
                        L.DomUtil.create('input',
                            'leaflet-add-marker-input',
                            container);
                    map.parent.addControlCheckbox.type = 'checkbox';
                    map.parent.addControlCheckbox.id = 'leaflet-add-marker-id';
                    map.parent.addControlCheckbox.map = this;

                    const label = L.DomUtil.create('label',
                        '',
                        container);
                    label.htmlFor = 'leaflet-add-marker-id';

                    L.DomEvent
                        .addListener(map.parent.addControlCheckbox,
                            'click', L.DomEvent.stopPropagation)
                        .addListener(map.parent.addControlCheckbox,
                            'click',
                            function (e) {
                                if (e.target.checked) {
                                    // enable click to add point
                                    e.target.map._map.parent.clickToAddPoint = true;
                                } else {
                                    // disable click to add point
                                    e.target.map._map.parent.clickToAddPoint = false;
                                }
                            });

                    return container;
                },

            });

            this.map.addControl(new addMarkerControl());

            // listen to click
            this.map.on('click', function (e) {
                const map = e.target.parent;
                if (map.clickToAddPoint) {
                    // add marker?
                    map.addPoint(e.latlng.lat, e.latlng.lng, -1, map.options.newPointFunction);
                    // disable add marker mode
                    map.addControlCheckbox.click();
                }

            });
        }
    }

    // MEMBER FUNCTIONS

    // add point
    addPoint(lat, lng, id, fun) {

        // add marker
        const marker = L.marker([lat, lng])
            .addTo(this.map);

        if (fun) {
            marker.on('click', fun);
        }

        L.stamp(marker);
        this.markers.addLayer(marker);

        if (id >= 0) {
            this.markerIdMap[marker._leaflet_id] = id;
            this.pointIdMap[id] = marker._leaflet_id;
        }

        // TODO: Disable add marker mode

        return marker;
    }

}

// LeafletPointWidget

export class LeafletPointWidget extends LeafletWidget {

    constructor(options) {

        // Call parent
        super(options);

        if (!this.options.point) {
            this.options.point = [options.lat, options.lng];
        }

        // add marker
        this.point = L.marker(L.latLng(this.options.point[0], this.options.point[1]),
            {draggable: true});
        this.point.addTo(this.map);

        // add reference to parent object
        this.point.parent = this;

        // call set point to update fields
        this.setPoint(L.latLng(this.options.point[0], this.options.point[1]));

        // set coordinates when dragged
        this.point.on('dragend', function (e) {
            e.target.parent.setPoint(e.target.getLatLng());
        });

        // set coordinates when map is click
        this.map.on('click',
            function (e) {
                e.target.parent.setPoint(e.latlng);
            });

    }

    // MEMBER FUNCTIONS

    // update point
    setPoint(p) {

        // set point coordinates
        this.point.setLatLng(p);

        // update fields
        if (this.options.id) {
            document.getElementById(this.options.id).value =
                'POINT(' + p.lng + ' ' + p.lat + ')';
        }
        if (this.options.id_lat) {
            document.getElementById(this.options.id_lat).value = p.lat;
        }
        if (this.options.id_lng) {
            document.getElementById(this.options.id_lng).value = p.lng;
        }
    }

}

// Polyline Widget

export class LeafletPolylineWidget extends LeafletWidget {

    constructor(options) {

        // Call parent
        super(options);

        // store all markers and lines id's
        this.polylineIdMap = {}
        this.markerIdMap = {};
        this.pointIdMap = {};

        // create layers
        this.layers = {};

        // create default layer
        this.createLayer('default');

        //this.map.createPane('defaultLeafletPolylineWidgetPane');
        //this.layers['default'] = {
        //        'markers': L.layerGroup({'pane': 'defaultLeafletPolylineWidget'}),
        //        'lines': L.layerGroup({'pane': 'defaultLeafletPolylineWidget'})
        //    };

    }

    createLayer(layer) {

        var layerName = layer + 'LeafletPolylineWidgetPane';
        this.map.createPane(layerName);
        this.layers[layer] = {
            'markers': L.layerGroup({'pane': layerName}),
            'lines': L.layerGroup({'pane': layerName})
        };

    }

    getLayerPane(layer) {

        var layerName = layer + 'LeafletPolylineWidgetPane';
        return this.map.getPane(layerName);

    }

    addLine(points, id, color, fun, layer) {

        fun = fun || null;
        layer = layer || 'default';

        // Create polyline
        var layerName = layer + 'LeafletPolylineWidgetPane';
        var polyline = L.polyline(points, {color: color, pane: layerName})
            .addTo(this.map);

        // Add click callback
        if (fun) {
            polyline.on('click', fun);
        }

        // Add marker
        L.stamp(polyline);
        this.layers[layer]['lines'].addLayer(polyline);

        // Track ids
        if (id >= 0) {
            this.polylineIdMap[polyline._leaflet_id] = id;
        }

        return polyline;
    }

    // add point
    addPoint(lat, lng, id, fun, layer) {

        fun = fun || null;
        layer = layer || 'default';

        // Create marker without a shaddow
        var icon = new L.Icon.Default();
        icon.options.shadowSize = [0, 0];
        var layerName = layer + 'LeafletPolylineWidgetPane';
        var marker = L.marker([lat, lng], {icon: icon, pane: layerName})
            .addTo(this.map);

        // Add click callback
        if (fun) {
            marker.on('click', fun);
        }

        // Add marker
        L.stamp(marker);
        this.layers[layer]['markers'].addLayer(marker);

        // Track ids
        if (id >= 0) {
            this.markerIdMap[marker._leaflet_id] = id;
            this.pointIdMap[id] = marker._leaflet_id;
        }

        return marker;
    }

}

<|endoftext|>