<commit_before>/* global analytics */
/* eslint no-console:0, no-unused-vars:0, no-extra-parens:0 */

'use strict';

var integration = require('analytics.js-integration');
var request = require('visionmedia/superagent');
var prefix = require('johntron/superagent-prefix');
var async = require('caolan/async');
var uuid = require('uuid');
window._astq = window._astq || [];

/**
 * Expose `Astronomer` integration.
 */
var Astronomer = module.exports = exports = integration('astronomer')
  .global('_astq')
  .option('appId', null)
  .option('credentialServer', 'https://app.astronomer.io:443')
  .option('credentialsExpiration', 900)
  .option('trackAllPages', false)
  .option('trackNamedPages', true)
  .option('trackCategorizedPages', true)
  .tag('aws', '<script src="https://sdk.amazonaws.com/js/aws-sdk-2.1.33.min.js">');

/**
 * Initialize astronomer.
 * @param {Facade} page The page object
 */
Astronomer.prototype.initialize = function() {
  var self = this;
  // Hold user data
  self.props = {};
  // The kinesis service object
  self.kinesis = null;
  // Need concurrency 1 here to prevent multiple auth requests simultaneously
  self.queue = async.queue(self.putRecord.bind(self), 1);
  // Load aws sdk, then signal ready
  self.load('aws', function() {
    self.ready();
    self.replay();
  });
};

/**
 * Authenticate with our server
 * @param {Function} callback Callback
 */
Astronomer.prototype.ensureKinesisConfig = function(callback) {
  var self = this;

  if (!self.expired()) {
    callback(null, { config: self.config, kinesis: self.kinesis });
    return;
  }

  // Request fresh config (token)
  self.requestConfig(function(err, response) {
    if (err) { return callback(err); }

    // Update global config object
    self.config = response.body;

    var params = {
      region: self.config.region,
      credentials: new window.AWS.WebIdentityCredentials({
        RoleArn: self.config.roleArn,
        WebIdentityToken: self.config.credentials.Token,
        DurationSeconds: self.options.credentialsExpiration
      })
    };

    // Assign kinesis service object to new one with fresh config
    self.kinesis = new window.AWS.Kinesis(params);

    callback(null, { config: self.config, kinesis: self.kinesis });
  });
};

/**
 * Check credentials on kinesis service object
 * @return {Boolean} If expired
 */
Astronomer.prototype.expired = function() {
  var expireTime = (((this.kinesis || {}).config || {}).credentials || {}).expireTime;
  return !expireTime || expireTime.getTime() <= Date.now();
};

/**
 * Worker handler function
 * @param {Object} record Record to put to kinesis
 * @param {Function} callback Function to callback to queue
 */
Astronomer.prototype.putRecord = function(record, callback) {
  var self = this;
  self.ensureKinesisConfig(function(err, config) {
    if (err) {
      console.error("Error retrieving config.");
      return callback();
    }

    var params = {
      Data: record,
      StreamName: config.config.streamName,
      PartitionKey: self.options.appId
    };

    config.kinesis.putRecord(params, function(err, data) {
      if (err) {
        console.log(err);
      }
      callback();
    });
  });
};

/**
 * Request new configuration from server, including fresh token
 * @param {Function} callback Callback passing in response
 */
Astronomer.prototype.requestConfig = function(callback) {
  request.get('/api/v1/applications/credentials/' + this.options.appId)
    .use(prefix(this.options.credentialServer))
    .end(callback);
};

/**
 * Replay the events that have been queued prior to initialization
 */
Astronomer.prototype.replay = function() {
  while (window._astq.length > 0) {
    var item = window._astq.shift();
    var method = item.shift();
    if (analytics[method]) analytics[method].apply(analytics, item);
  }
};

/**
 * Has the astronomer library been loaded yet?
 * @return {Boolean}
 */
Astronomer.prototype.loaded = function() {
  return !!((((window.AWS) || {}).config || {}).credentials || {}).accessKeyId;
};

/**
 * Trigger a page view.
 * @param {Facade} page A page object
 */
Astronomer.prototype.page = function(page) {
  var category = page.category();
  var props = page.properties();
  var name = page.fullName();
  var opts = this.options;

  // all pages
  if (opts.trackAllPages) {
    this.track(page.track());
  }

  // named pages
  if (name && opts.trackNamedPages) {
    this.track(page.track(name));
  }

  // categorized pages
  // if (category && opts.trackCategorizedPages) {
  //   this.track(page.track(category));
  // }
};

/**
 * Identify a user.
 * @param {Facade} identify An identify object
 */
Astronomer.prototype.identify = function(identify) {
  this.push(identify.json());
  // var id = identify.userId();
  // var traits = identify.traits();
  // this.props.userId = id;
  // this.props.userProperties = traits;
};

/**
 * Associate the current user with a group of users.
 * @param {Facade} group A group object
 */
// Astronomer.prototype.group = function(group) {
//   var id = group.groupId();
//   var traits = group.traits();
//   this.props.groupId = id;
//   this.props.groupProperties = traits;
// };

/**
 * Track an event.
 * @param {Facade} track A track object
 */
Astronomer.prototype.track = function(track) {
  this.push(track.json());
};

/**
 * Push a message to the outgoing queue.
 * @param {Object} msg
 */
Astronomer.prototype.push = function(msg) {
  // var record = JSON.stringify({
  //   event: track.event(),
  //   properties: track.properties(),
  //   anonymousId: analytics.user().anonymousId(),
  //   userId: this.props.userId,
  //   traits: this.props.userProperties
  // });
  msg = this.normalize(msg);
  console.log(msg);
  // this.queue.push(msg);
};

/**
 * Normalize a given msg.
 * @param {Object} msg
 */
Astronomer.prototype.normalize = function(msg) {
  var user = this.analytics.user();
  msg.userId = msg.userId || user.id();
  msg.anonymousId = user.anonymousId();
  msg.messageId = uuid();
  msg.sentAt = new Date();
  return msg;
};<commit_msg>SAVEPOINT<commit_after>/* global analytics */
/* eslint no-console:0, no-unused-vars:0, no-extra-parens:0 */

'use strict';

var integration = require('analytics.js-integration');
var request = require('visionmedia/superagent');
var prefix = require('johntron/superagent-prefix');
var async = require('caolan/async');
var uuid = require('uuid');
window._astq = window._astq || [];

/**
 * Expose `Astronomer` integration.
 */
var Astronomer = module.exports = exports = integration('astronomer')
  .global('_astq')
  .option('appId', null)
  .option('credentialServer', 'https://app.astronomer.io:443')
  .option('credentialsExpiration', 900)
  .option('trackAllPages', false)
  .option('trackNamedPages', true)
  .option('trackCategorizedPages', true)
  .tag('aws', '<script src="https://sdk.amazonaws.com/js/aws-sdk-2.1.33.min.js">');

/**
 * Initialize astronomer.
 * @param {Facade} page The page object
 */
Astronomer.prototype.initialize = function() {
  var self = this;
  // Hold user data
  self.props = {};
  // The kinesis service object
  self.kinesis = null;
  // Need concurrency 1 here to prevent multiple auth requests simultaneously
  self.queue = async.queue(self.putRecord.bind(self), 1);
  // Load aws sdk, then signal ready
  self.load('aws', function() {
    self.ready();
    self.replay();
  });
};

/**
 * Authenticate with our server
 * @param {Function} callback Callback
 */
Astronomer.prototype.ensureKinesisConfig = function(callback) {
  var self = this;

  if (!self.expired()) {
    callback(null, { config: self.config, kinesis: self.kinesis });
    return;
  }

  // Request fresh config (token)
  self.requestConfig(function(err, response) {
    if (err) { return callback(err); }

    // Update global config object
    self.config = response.body;

    var params = {
      region: self.config.region,
      credentials: new window.AWS.WebIdentityCredentials({
        RoleArn: self.config.roleArn,
        WebIdentityToken: self.config.credentials.Token,
        DurationSeconds: self.options.credentialsExpiration
      })
    };

    // Assign kinesis service object to new one with fresh config
    self.kinesis = new window.AWS.Kinesis(params);

    callback(null, { config: self.config, kinesis: self.kinesis });
  });
};

/**
 * Check credentials on kinesis service object
 * @return {Boolean} If expired
 */
Astronomer.prototype.expired = function() {
  var expireTime = (((this.kinesis || {}).config || {}).credentials || {}).expireTime;
  return !expireTime || expireTime.getTime() <= Date.now();
};

/**
 * Worker handler function
 * @param {Object} record Record to put to kinesis
 * @param {Function} callback Function to callback to queue
 */
Astronomer.prototype.putRecord = function(record, callback) {
  var self = this;
  self.ensureKinesisConfig(function(err, config) {
    if (err) {
      console.error("Error retrieving config.");
      return callback();
    }

    var params = {
      Data: record,
      StreamName: config.config.streamName,
      PartitionKey: self.options.appId
    };

    config.kinesis.putRecord(params, function(err, data) {
      if (err) {
        console.log(err);
      }
      callback();
    });
  });
};

/**
 * Request new configuration from server, including fresh token
 * @param {Function} callback Callback passing in response
 */
Astronomer.prototype.requestConfig = function(callback) {
  request.get('/api/v1/applications/credentials/' + this.options.appId)
    .use(prefix(this.options.credentialServer))
    .end(callback);
};

/**
 * Replay the events that have been queued prior to initialization
 */
Astronomer.prototype.replay = function() {
  while (window._astq.length > 0) {
    var item = window._astq.shift();
    var method = item.shift();
    if (analytics[method]) analytics[method].apply(analytics, item);
  }
};

/**
 * Has the astronomer library been loaded yet?
 * @return {Boolean}
 */
Astronomer.prototype.loaded = function() {
  return !!((((window.AWS) || {}).config || {}).credentials || {}).accessKeyId;
};

/**
 * Trigger a page view.
 * @param {Facade} page A page object
 */
Astronomer.prototype.page = function(page) {
  console.log("PAGE", page.json());
  var category = page.category();
  var props = page.properties();
  var name = page.fullName();
  var opts = this.options;

  // all pages
  if (opts.trackAllPages) {
    this.track(page.track());
  }

  // named pages
  if (name && opts.trackNamedPages) {
    this.track(page.track(name));
  }

  // categorized pages
  // if (category && opts.trackCategorizedPages) {
  //   this.track(page.track(category));
  // }
};

/**
 * Identify a user.
 * @param {Facade} identify An identify object
 */
Astronomer.prototype.identify = function(identify) {
  this.push(identify.json());
  // var id = identify.userId();
  // var traits = identify.traits();
  // this.props.userId = id;
  // this.props.userProperties = traits;
};

/**
 * Associate the current user with a group of users.
 * @param {Facade} group A group object
 */
// Astronomer.prototype.group = function(group) {
//   var id = group.groupId();
//   var traits = group.traits();
//   this.props.groupId = id;
//   this.props.groupProperties = traits;
// };

/**
 * Track an event.
 * @param {Facade} track A track object
 */
Astronomer.prototype.track = function(track) {
  this.push(track.json());
};

/**
 * Push a message to the outgoing queue.
 * @param {Object} msg
 */
Astronomer.prototype.push = function(msg) {
  msg = this.normalize(msg);
  this.queue.push(msg);
};

/**
 * Normalize a given msg.
 * @param {Object} msg
 */
Astronomer.prototype.normalize = function(msg) {
  var user = this.analytics.user();
  msg.userId = msg.userId || user.id();
  msg.anonymousId = user.anonymousId();
  msg.messageId = uuid();
  msg.sentAt = new Date();
  return msg;
};<|endoftext|>


<commit_before>var xhr = function(url, callback) {
    var oReq = new XMLHttpRequest();
    oReq.onload = function(e){
        callback(this.responseText, e);
    };
    oReq.open("get", url, true);
    oReq.send();
};

var colonSeparateDuration = function(num) { // in seconds
    if (typeof num == "number" && !(Number.isNaN || isNaN)(num)) {
        var minutes = Math.floor(num / 60);
        var seconds = Math.floor(num % 60);
        return "" + minutes + ":" + zpad(seconds, 2);
    } else {
        return "--:--";
    }
};

var zpad = function pad(n, width, z) { // by user Pointy on SO: stackoverflow.com/a/10073788
    z = z || "0";
    n = n + "";
    return n.length >= width ? n : new Array(width - n.length + 1).join(z) + n;
};

window.AudioContext = window.AudioContext || window.webkitAudioContext;

var cbus = {};

cbus.audio = {
    DEFAULT_JUMP_AMOUNT_BACKWARD: -10,
    DEFAULT_JUMP_AMOUNT_FORWARD: 30,

    element: null,

    setElement: function(elem) {
        if (cbus.audio.element) {
            cbus.audio.pause();
            cbus.audio.element.onseeked = null;
            cbus.audio.element.onloadedmetadata = null;
            cbus.audio.element.onended = null;
        }

        if (cbus.audio.queue.indexOf(elem) !== -1) {
            cbus.audio.queue.splice(cbus.audio.queue.indexOf(elem), 1);
        }

        cbus.audio.element = elem;
        cbus.audio.element.currentTime = 0;

        cbus.audio.element.onseeked = function() {
            cbus.audio.updatePlayerTime();
        };
        cbus.audio.element.onloadedmetadata = function() {
            cbus.audio.updatePlayerTime(true);
        };
        cbus.audio.element.onended = cbus.audio.playNextInQueue;

        var episodeElem = elem.parentElement.parentElement.parentElement.parentElement;

        var episodeTitle = episodeElem.querySelector(".episode_title").textContent;
        var episodeFeedTitle = episodeElem.querySelector(".episode_feed-title").textContent;
        var episodeImage = episodeElem.querySelector(".episode_background").style.backgroundImage;

        $(".player_time--total").text(colonSeparateDuration(cbus.audio.element.duration));

        document.querySelector("cbus-queue-item").title = episodeTitle;
        document.querySelector("cbus-queue-item").feedTitle = episodeFeedTitle;
        document.querySelector("cbus-queue-item").image = episodeImage;
    },

    updatePlayerTime: function(updateTotalLength) {
        if (cbus.audio.element && !cbus.audio.element.paused) {
            var currentTime = cbus.audio.element.currentTime;
            /* slider */
            var percentage = currentTime / cbus.audio.element.duration;
            $(".player_slider").val(Math.round(1000 * percentage) || 0);

            /* time indicator */
            $(".player_time--now").text(colonSeparateDuration(currentTime));
            if (updateTotalLength === true) {
                $(".player_time--total").text(colonSeparateDuration(cbus.audio.element.duration));
            }
        }
    },
    sliderUpdateInterval: null,

    playNextInQueue: function() {
        if (cbus.audio.queue.length > 0) {
            cbus.audio.setElement(cbus.audio.queue[0]);
            cbus.audio.updatePlayerTime(true);
            cbus.audio.play();
        }
    },

    play: function() {
        cbus.audio.element.play();
        $(".player_button--play").html("pause");
        $(".player_time--total")
    },
    pause: function() {
        cbus.audio.element.pause();
        $(".player_button--play").html("play_arrow");
    },
    stop: function() {
        cbus.audio.element.pause();
        cbus.audio.element.currentTime = 0;
    },
    jump: function(amount) {
        cbus.audio.element.currentTime += amount;
    },

    queue: [],

    enqueue: function(elem) {
        cbus.audio.queue.push(elem);
    }
};

cbus.audio.sliderUpdateInterval = setInterval(cbus.audio.updatePlayerTime, 500);

cbus.display = function(thing) {
    switch (thing) {
        case "feeds":
            $(".filters_feeds").html("");
            cbus.feeds.forEach(function(feed) {
                $(".filters_feeds").append("
\
");
            });
            break;
        case "episodes":
            $(".list--episodes").html("");

            for (var i = 0; i < Math.min(50, cbus.episodes.length); i++) {
                var episode = cbus.episodes[i];

                var episodeElem = document.createElement("cbus-episode");

                episodeElem.title = episode.title;
                episodeElem.image = episode.feed.image;
                episodeElem.feedTitle = episode.feed.title;
                episodeElem.url = episode.url;
                episodeElem.description = episode.description;
                episodeElem.dataset.id = episode.id;

                $(".list--episodes").append(episodeElem);
            };

            break;
    }
};

cbus.update = function() {
    $(".list--episodes").html("");
    xhr("update?feeds=" + encodeURIComponent(JSON.stringify(cbus.feeds)), function(r) {
        var feedContents = JSON.parse(r);
        var episodes = [];

        console.log(feedContents);

        Object.keys(feedContents).forEach(function(feedUrl) {
            feedContents[feedUrl].items.forEach(function(episode) {
                var feed = cbus.feeds.filter(function(feed) {
                    return feed.url === feedUrl;
                })[0];

                episodes.push({
                    id: episode.id,
                    url: episode.url,
                    title: episode.title,
                    description: episode.description,
                    date: (new Date(episode.date).getTime() ? new Date(episode.date) : null), // check if date is valid
                    feed: feed
                });
            });
        });

        cbus.episodes = episodes.sort(function(a, b) {
            if (a.date > b.date) return -1;
            if (a.date < b.date) return 1;
            return 0;
        });
        cbus.display("episodes");
    });
};

cbus.feeds = (localStorage.getItem("cbus_feeds") ?
    JSON.parse(localStorage.getItem("cbus_feeds")).sort(function(a, b) {
        var aTitle = a.title.toLowerCase();
        var bTitle = b.title.toLowerCase();

        if (aTitle < bTitle) return -1;
        if (aTitle > bTitle) return 1;
        return 0;
    })
    : []);

cbus.display("feeds");

$(".filters_control--add-feed").click(function() {
    Ply.dialog("prompt", {
        title: "Add feed",
        form: { title: "Some Random Podcast" }
    }).always(function (ui) {
        if (ui.state) {
            console.log(ui.widget);
            var feedTitle = ui.data.title;
            xhr("feedinfo?term=" + feedTitle, function(res) {
                var json = JSON.parse(res);
                console.log(json);

                var feedInfo = json[0];

                var feedTitle = feedInfo.title;
                var feedImage = feedInfo.image;
                var feedUrl = feedInfo.url;

                var feedAlreadyAdded = false;
                for (var i = 0; i < cbus.feeds.length; i++) {
                    var lfeed = cbus.feeds[i];
                    var lfeedUrl = lfeed.url;
                    if (lfeedUrl === feedUrl) {
                        feedAlreadyAdded = true;
                        break;
                    }
                }

                if (feedAlreadyAdded) {
                    Ply.dialog("alert", "You already have that feed.");
                } else {
                    cbus.feeds.push({
                        url: feedUrl,
                        title: feedTitle,
                        image: feedImage
                    });
                    localStorage.setItem("cbus_feeds", JSON.stringify(cbus.feeds));
                    Ply.dialog("alert", "Added feed.");
                }
            });
        }
    });
});

$(".list--episodes").on("click", function(e) {
    var classList = e.target.classList;
    var audioElem = e.target.parentElement.parentElement.querySelector(".episode_audio_player");
    if (classList.contains("episode_audio_button--play")) {
        cbus.audio.setElement(audioElem);
        cbus.audio.play();
    } else if (classList.contains("episode_audio_button--enqueue")) {
        cbus.audio.enqueue(audioElem);
    }
});

$(".player").on("click", function(e) {
    var classList = e.target.classList;
    if (classList.contains("player_button")) {
        if (classList.contains("player_button--backward")) {
            cbus.audio.jump(cbus.audio.DEFAULT_JUMP_AMOUNT_BACKWARD);
        } else if (classList.contains("player_button--forward")) {
            cbus.audio.jump(cbus.audio.DEFAULT_JUMP_AMOUNT_FORWARD);
        } else if (classList.contains("player_button--play")) {
            if (!cbus.audio.element) {
                if (cbus.audio.queue.length > 0) {
                    cbus.audio.setElement(cbus.audio.queue[0]);
                } else {
                    cbus.audio.setElement($(".episode_audio_player")[0]);
                }
                cbus.audio.play();
            } else if (cbus.audio.element.paused) {
                cbus.audio.play();
            } else {
                cbus.audio.pause();
            }
        } else if (classList.contains("player_button--next")) {
            cbus.audio.playNextInQueue();
        }
    }
});

$(".player_button--next").on("mouseenter click", function(e) {
    var nextEpisodeString = "Nothing in queue.";

    if (cbus.audio.queue.length !== 0) {
        nextEpisodeString = $("" + cbus.audio.queue[0].parentElement.parentElement.querySelector(".episode_title").textContent + "
" +  cbus.audio.queue[0].parentElement.parentElement.querySelector(".episode_feed-title").textContent + "");
    }

    $(this).tooltipster("content", nextEpisodeString);
});

$(".player_slider").on("input", function() {
    var proportion = this.value / this.max;
    cbus.audio.element.currentTime = cbus.audio.element.duration * proportion;
});

$(".filter--time").on("change", function() {
    var timeCategory = this.value;
    $(".episode").each(function(i, elem) {
        var matchableTimes = elem.dataset.time.split(",");
        if (matchableTimes.indexOf(timeCategory) !== -1) {
            elem.classList.remove("hidden");
        } else {
            elem.classList.add("hidden");
        }
    });
});

/* header actions */

$(".header_actions").on("click", function(e) {
    var classList = e.target.classList;
    if (classList.contains("header_action")) {
        if (classList.contains("header_action--show-filters")) {
            $(".content-container")[0].classList.toggle("filters-visible");
            e.target.classList.toggle("md-inactive");
        }
        if (classList.contains("header_action--refresh-episodes")) {
            cbus.update();
        }
    }
});

/* do the thing */

cbus.update();

/* initialize tooltipster */

$(".tooltip").tooltipster({
    theme: "tooltipster-cbus",
    animation: "fadeup",
    speed: 300
});
<commit_msg>Add getEpisodeData and getEpisodeElem functions<commit_after>var xhr = function(url, callback) {
    var oReq = new XMLHttpRequest();
    oReq.onload = function(e){
        callback(this.responseText, e);
    };
    oReq.open("get", url, true);
    oReq.send();
};

var colonSeparateDuration = function(num) { // in seconds
    if (typeof num == "number" && !(Number.isNaN || isNaN)(num)) {
        var minutes = Math.floor(num / 60);
        var seconds = Math.floor(num % 60);
        return "" + minutes + ":" + zpad(seconds, 2);
    } else {
        return "--:--";
    }
};

var zpad = function pad(n, width, z) { // by user Pointy on SO: stackoverflow.com/a/10073788
    z = z || "0";
    n = n + "";
    return n.length >= width ? n : new Array(width - n.length + 1).join(z) + n;
};

window.AudioContext = window.AudioContext || window.webkitAudioContext;

var cbus = {};

cbus.audio = {
    DEFAULT_JUMP_AMOUNT_BACKWARD: -10,
    DEFAULT_JUMP_AMOUNT_FORWARD: 30,

    element: null,

    setElement: function(elem) {
        if (cbus.audio.element) {
            cbus.audio.pause();
            cbus.audio.element.onseeked = null;
            cbus.audio.element.onloadedmetadata = null;
            cbus.audio.element.onended = null;
        }

        if (cbus.audio.queue.indexOf(elem) !== -1) {
            cbus.audio.queue.splice(cbus.audio.queue.indexOf(elem), 1);
        }

        cbus.audio.element = elem;
        cbus.audio.element.currentTime = 0;

        cbus.audio.element.onseeked = function() {
            cbus.audio.updatePlayerTime();
        };
        cbus.audio.element.onloadedmetadata = function() {
            cbus.audio.updatePlayerTime(true);
        };
        cbus.audio.element.onended = cbus.audio.playNextInQueue;

        var episodeElem = elem.parentElement.parentElement.parentElement.parentElement;

        var episodeTitle = episodeElem.querySelector(".episode_title").textContent;
        var episodeFeedTitle = episodeElem.querySelector(".episode_feed-title").textContent;
        var episodeImage = episodeElem.querySelector(".episode_background").style.backgroundImage;

        $(".player_time--total").text(colonSeparateDuration(cbus.audio.element.duration));

        document.querySelector("cbus-queue-item").title = episodeTitle;
        document.querySelector("cbus-queue-item").feedTitle = episodeFeedTitle;
        document.querySelector("cbus-queue-item").image = episodeImage;
    },

    updatePlayerTime: function(updateTotalLength) {
        if (cbus.audio.element && !cbus.audio.element.paused) {
            var currentTime = cbus.audio.element.currentTime;
            /* slider */
            var percentage = currentTime / cbus.audio.element.duration;
            $(".player_slider").val(Math.round(1000 * percentage) || 0);

            /* time indicator */
            $(".player_time--now").text(colonSeparateDuration(currentTime));
            if (updateTotalLength === true) {
                $(".player_time--total").text(colonSeparateDuration(cbus.audio.element.duration));
            }
        }
    },
    sliderUpdateInterval: null,

    playNextInQueue: function() {
        if (cbus.audio.queue.length > 0) {
            cbus.audio.setElement(cbus.audio.queue[0]);
            cbus.audio.updatePlayerTime(true);
            cbus.audio.play();
        }
    },

    play: function() {
        cbus.audio.element.play();
        $(".player_button--play").html("pause");
        $(".player_time--total")
    },
    pause: function() {
        cbus.audio.element.pause();
        $(".player_button--play").html("play_arrow");
    },
    stop: function() {
        cbus.audio.element.pause();
        cbus.audio.element.currentTime = 0;
    },
    jump: function(amount) {
        cbus.audio.element.currentTime += amount;
    },

    queue: [],

    enqueue: function(elem) {
        cbus.audio.queue.push(elem);
    }
};

cbus.audio.sliderUpdateInterval = setInterval(cbus.audio.updatePlayerTime, 500);

cbus.display = function(thing) {
    switch (thing) {
        case "feeds":
            $(".filters_feeds").html("");
            cbus.feeds.forEach(function(feed) {
                $(".filters_feeds").append("
\
");
            });
            break;
        case "episodes":
            $(".list--episodes").html("");

            for (var i = 0; i < Math.min(50, cbus.episodes.length); i++) {
                var episode = cbus.episodes[i];

                var episodeElem = document.createElement("cbus-episode");

                episodeElem.title = episode.title;
                episodeElem.image = episode.feed.image;
                episodeElem.feedTitle = episode.feed.title;
                episodeElem.url = episode.url;
                episodeElem.description = episode.description;
                episodeElem.dataset.id = episode.id;

                $(".list--episodes").append(episodeElem);
            };

            break;
    }
};

cbus.update = function() {
    $(".list--episodes").html("");
    xhr("update?feeds=" + encodeURIComponent(JSON.stringify(cbus.feeds)), function(r) {
        var feedContents = JSON.parse(r);
        var episodes = [];

        console.log(feedContents);

        Object.keys(feedContents).forEach(function(feedUrl) {
            feedContents[feedUrl].items.forEach(function(episode) {
                var feed = cbus.feeds.filter(function(feed) {
                    return feed.url === feedUrl;
                })[0];

                episodes.push({
                    id: episode.id,
                    url: episode.url,
                    title: episode.title,
                    description: episode.description,
                    date: (new Date(episode.date).getTime() ? new Date(episode.date) : null), // check if date is valid
                    feed: feed
                });
            });
        });

        cbus.episodes = episodes.sort(function(a, b) {
            if (a.date > b.date) return -1;
            if (a.date < b.date) return 1;
            return 0;
        });
        cbus.display("episodes");
    });
};

cbus.getEpisodeElem = function(options) {
    if (options.id || (typeof options.index !== "undefined" && options.index !== null)) {
        var elem = null;

        if (options.id) {
            elem = document.querySelector("cbus-episode[data-id='" + options.id + "']");
        } else { // options.index
            elem = document.querySelectorAll("cbus-episode")[Number(options.index)];
        }

        return elem;
    }
    return false;
};

cbus.getEpisodeData = function(options) {
    if (options.id || (typeof options.index !== "undefined" && options.index !== null) || options.audioElement) {
        var result = null;

        if (options.id) {
            var filteredList = cbus.episodes.filter(function(episode) {
                return episode.id === options.id;
            });

            if (filteredList.length !== 0) {
                result = filteredList[0];
            }
        } else if (options.audioElement) {
            result = cbus.getEpisodeData({
                id: options.audioElement.parentElement.parentElement.parentElement.parentElement.dataset.id
            });
        } else { // options.index
            result = cbus.episodes[Number(options.index)];
        }

        return result;
    }
    return false;
};

cbus.feeds = (localStorage.getItem("cbus_feeds") ?
    JSON.parse(localStorage.getItem("cbus_feeds")).sort(function(a, b) {
        var aTitle = a.title.toLowerCase();
        var bTitle = b.title.toLowerCase();

        if (aTitle < bTitle) return -1;
        if (aTitle > bTitle) return 1;
        return 0;
    })
    : []);

cbus.display("feeds");

$(".filters_control--add-feed").click(function() {
    Ply.dialog("prompt", {
        title: "Add feed",
        form: { title: "Some Random Podcast" }
    }).always(function (ui) {
        if (ui.state) {
            console.log(ui.widget);
            var feedTitle = ui.data.title;
            xhr("feedinfo?term=" + feedTitle, function(res) {
                var json = JSON.parse(res);
                console.log(json);

                var feedInfo = json[0];

                var feedTitle = feedInfo.title;
                var feedImage = feedInfo.image;
                var feedUrl = feedInfo.url;

                var feedAlreadyAdded = false;
                for (var i = 0; i < cbus.feeds.length; i++) {
                    var lfeed = cbus.feeds[i];
                    var lfeedUrl = lfeed.url;
                    if (lfeedUrl === feedUrl) {
                        feedAlreadyAdded = true;
                        break;
                    }
                }

                if (feedAlreadyAdded) {
                    Ply.dialog("alert", "You already have that feed.");
                } else {
                    cbus.feeds.push({
                        url: feedUrl,
                        title: feedTitle,
                        image: feedImage
                    });
                    localStorage.setItem("cbus_feeds", JSON.stringify(cbus.feeds));
                    Ply.dialog("alert", "Added feed.");
                }
            });
        }
    });
});

$(".list--episodes").on("click", function(e) {
    var classList = e.target.classList;
    var audioElem = e.target.parentElement.parentElement.querySelector(".episode_audio_player");
    if (classList.contains("episode_audio_button--play")) {
        cbus.audio.setElement(audioElem);
        cbus.audio.play();
    } else if (classList.contains("episode_audio_button--enqueue")) {
        cbus.audio.enqueue(audioElem);
    }
});

$(".player").on("click", function(e) {
    var classList = e.target.classList;
    if (classList.contains("player_button")) {
        if (classList.contains("player_button--backward")) {
            cbus.audio.jump(cbus.audio.DEFAULT_JUMP_AMOUNT_BACKWARD);
        } else if (classList.contains("player_button--forward")) {
            cbus.audio.jump(cbus.audio.DEFAULT_JUMP_AMOUNT_FORWARD);
        } else if (classList.contains("player_button--play")) {
            if (!cbus.audio.element) {
                if (cbus.audio.queue.length > 0) {
                    cbus.audio.setElement(cbus.audio.queue[0]);
                } else {
                    cbus.audio.setElement($(".episode_audio_player")[0]);
                }
                cbus.audio.play();
            } else if (cbus.audio.element.paused) {
                cbus.audio.play();
            } else {
                cbus.audio.pause();
            }
        } else if (classList.contains("player_button--next")) {
            cbus.audio.playNextInQueue();
        }
    }
});

$(".player_button--next").on("mouseenter click", function(e) {
    var episodeData = cbus.getEpisodeData({
        audioElement: cbus.audio.queue[0]
    });

    var nextEpisodeString = "Nothing in queue.";
    if (cbus.audio.queue.length !== 0) {
        nextEpisodeString = $("" + episodeData.title + "
" + episodeData.feed.title + "");
    }

    $(this).tooltipster("content", nextEpisodeString);
});

$(".player_slider").on("input", function() {
    var proportion = this.value / this.max;
    cbus.audio.element.currentTime = cbus.audio.element.duration * proportion;
});

$(".filter--time").on("change", function() {
    var timeCategory = this.value;
    $(".episode").each(function(i, elem) {
        var matchableTimes = elem.dataset.time.split(",");
        if (matchableTimes.indexOf(timeCategory) !== -1) {
            elem.classList.remove("hidden");
        } else {
            elem.classList.add("hidden");
        }
    });
});

/* header actions */

$(".header_actions").on("click", function(e) {
    var classList = e.target.classList;
    if (classList.contains("header_action")) {
        if (classList.contains("header_action--show-filters")) {
            $(".content-container")[0].classList.toggle("filters-visible");
            e.target.classList.toggle("md-inactive");
        }
        if (classList.contains("header_action--refresh-episodes")) {
            cbus.update();
        }
    }
});

/* do the thing */

cbus.update();

/* initialize tooltipster */

$(".tooltip").tooltipster({
    theme: "tooltipster-cbus",
    animation: "fadeup",
    speed: 300
});
<|endoftext|>


<commit_before>/*
 * Copyright (c) 2011 Vinay Pulim <vinay@milewise.com>
 * MIT Licensed
 */

"use strict";

function findKey(obj, val) {
  for (var n in obj)
    if (obj[n] === val)
      return n;
}

var http = require('./http'),
  assert = require('assert'),
  url = require('url');

var Client = function(wsdl, endpoint, options) {
  options = options || {};
  this.wsdl = wsdl;
  this._initializeOptions(options);
  this._initializeServices(endpoint);
};

Client.prototype.addSoapHeader = function(soapHeader, name, namespace, xmlns) {
  if (!this.soapHeaders) {
    this.soapHeaders = [];
  }
  if (typeof soapHeader === 'object') {
    soapHeader = this.wsdl.objectToXML(soapHeader, name, namespace, xmlns, true);
  }
  this.soapHeaders.push(soapHeader);
};

Client.prototype.getSoapHeaders = function() {
  return this.soapHeaders;
};

Client.prototype.clearSoapHeaders = function() {
  this.soapHeaders = null;
};

Client.prototype.setEndpoint = function(endpoint) {
  this.endpoint = endpoint;
  this._initializeServices(endpoint);
};

Client.prototype.describe = function() {
  var types = this.wsdl.definitions.types;
  return this.wsdl.describeServices();
};

Client.prototype.setSecurity = function(security) {
  this.security = security;
};

Client.prototype.setSOAPAction = function(SOAPAction) {
  this.SOAPAction = SOAPAction;
};

Client.prototype._initializeServices = function(endpoint) {
  var definitions = this.wsdl.definitions,
    services = definitions.services;
  for (var name in services) {
    this[name] = this._defineService(services[name], endpoint);
  }
};

Client.prototype._initializeOptions = function(options) {
  this.wsdl.options.attributesKey = options.attributesKey || 'attributes';
};

Client.prototype._defineService = function(service, endpoint) {
  var ports = service.ports,
    def = {};
  for (var name in ports) {
    def[name] = this._definePort(ports[name], endpoint ? endpoint : ports[name].location);
  }
  return def;
};

Client.prototype._definePort = function(port, endpoint) {
  var location = endpoint,
    binding = port.binding,
    methods = binding.methods,
    def = {};
  for (var name in methods) {
    def[name] = this._defineMethod(methods[name], location);
    this[name] = def[name];
  }
  return def;
};

Client.prototype._defineMethod = function(method, location) {
  var self = this;
  return function(args, callback, options, extraHeaders) {
    if (typeof args === 'function') {
      callback = args;
      args = {};
    }
    self._invoke(method, args, location, function(error, result, raw) {
      callback(error, result, raw);
    }, options, extraHeaders);
  };
};

Client.prototype._invoke = function(method, args, location, callback, options, extraHeaders) {
  var self = this,
    name = method.$name,
    input = method.input,
    output = method.output,
    style = method.style,
    defs = this.wsdl.definitions,
    ns = defs.$targetNamespace,
    encoding = '',
    message = '',
    xml = null,
    req = null,
    soapAction = this.SOAPAction ? this.SOAPAction(ns, name) : (method.soapAction || (((ns.lastIndexOf("/") !== ns.length - 1) ? ns + "/" : ns) + name)),
    headers = {
      SOAPAction: '"' + soapAction + '"',
      'Content-Type': "text/xml; charset=utf-8"
    },
    alias = findKey(defs.xmlns, ns);

  options = options || {};

  //Add extra headers
  for (var attr in extraHeaders) { headers[attr] = extraHeaders[attr]; }

  // Allow the security object to add headers
  if (self.security && self.security.addHeaders)
    self.security.addHeaders(headers);
  if (self.security && self.security.addOptions)
    self.security.addOptions(options);

  if (input.parts) {
    assert.ok(!style || style === 'rpc', 'invalid message definition for document style binding');
    message = self.wsdl.objectToRpcXML(name, args, alias, ns);
    (method.inputSoap === 'encoded') && (encoding = 'soap:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/" ');
  } else if (typeof (args) === 'string') {
    message = args;
  } else if (args === null) {
    message = "<" + name + " />";
  } else {
    assert.ok(!style || style === 'document', 'invalid message definition for rpc style binding');
    // pass `input.$lookupType` if `input.$type` could not be found
    message = self.wsdl.objectToDocumentXML(input.$name, args, input.targetNSAlias, input.targetNamespace, (input.$type || input.$lookupType));
  }
  xml = "<soap:Envelope " +
    "xmlns:soap=\"http://schemas.xmlsoap.org/soap/envelope/\" " +
    "xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" " +
    encoding +
    this.wsdl.xmlnsInEnvelope + '>' +
    ((self.soapHeaders || self.security) ?
      (
        "<soap:Header>" +
        (self.soapHeaders ? self.soapHeaders.join("\n") : "") +
        (self.security ? self.security.toXML() : "") +
        "</soap:Header>"
      )
      :
        ''
      ) +
    "<soap:Body>" +
    message +
    "</soap:Body>" +
    "</soap:Envelope>";

  self.lastMessage = message;
  self.lastRequest = xml;

  req = http.request(location, xml, function(err, response, body) {
    var result;
    var obj;
    self.lastResponse = body;
    self.lastResponseHeaders = response && response.headers;

    if (err) {
      callback(err);
    } else if (response.statusCode !== 200) {
      callback(new Error('Invalid response: ' + response.statusCode + '\nBody: ' + body));
    } else {
      try {
        obj = self.wsdl.xmlToObject(body);
      } catch (error) {
        error.response = response;
        error.body = body;
        return callback(error, response, body);
      }

      result = obj.Body[output.$name];
      // RPC/literal response body may contain elements with added suffixes I.E.
      // 'Response', or 'Output', or 'Out'
      // This doesn't necessarily equal the ouput message name. See WSDL 1.1 Section 2.4.5
      if(!result){
        result = obj.Body[output.$name.replace(/(?:Out(?:put)?|Response)$/, '')];
      }
      if (!result) {
        ['Response', 'Out', 'Output'].forEach(function (term) {
          if (obj.Body.hasOwnProperty(name + term)) {
            return result = obj.Body[name + term];
          }
        });
      }

      callback(null, result, body);
    }
  }, headers, options);

  // Added mostly for testability, but possibly useful for debugging
  self.lastRequestHeaders = req.headers;
};

exports.Client = Client;
<commit_msg>Re-added check for presence of security<commit_after>/*
 * Copyright (c) 2011 Vinay Pulim <vinay@milewise.com>
 * MIT Licensed
 */

"use strict";

function findKey(obj, val) {
  for (var n in obj)
    if (obj[n] === val)
      return n;
}

var http = require('./http'),
  assert = require('assert'),
  url = require('url');

var Client = function(wsdl, endpoint, options) {
  options = options || {};
  this.wsdl = wsdl;
  this._initializeOptions(options);
  this._initializeServices(endpoint);
};

Client.prototype.addSoapHeader = function(soapHeader, name, namespace, xmlns) {
  if (!this.soapHeaders) {
    this.soapHeaders = [];
  }
  if (typeof soapHeader === 'object') {
    soapHeader = this.wsdl.objectToXML(soapHeader, name, namespace, xmlns, true);
  }
  this.soapHeaders.push(soapHeader);
};

Client.prototype.getSoapHeaders = function() {
  return this.soapHeaders;
};

Client.prototype.clearSoapHeaders = function() {
  this.soapHeaders = null;
};

Client.prototype.setEndpoint = function(endpoint) {
  this.endpoint = endpoint;
  this._initializeServices(endpoint);
};

Client.prototype.describe = function() {
  var types = this.wsdl.definitions.types;
  return this.wsdl.describeServices();
};

Client.prototype.setSecurity = function(security) {
  this.security = security;
};

Client.prototype.setSOAPAction = function(SOAPAction) {
  this.SOAPAction = SOAPAction;
};

Client.prototype._initializeServices = function(endpoint) {
  var definitions = this.wsdl.definitions,
    services = definitions.services;
  for (var name in services) {
    this[name] = this._defineService(services[name], endpoint);
  }
};

Client.prototype._initializeOptions = function(options) {
  this.wsdl.options.attributesKey = options.attributesKey || 'attributes';
};

Client.prototype._defineService = function(service, endpoint) {
  var ports = service.ports,
    def = {};
  for (var name in ports) {
    def[name] = this._definePort(ports[name], endpoint ? endpoint : ports[name].location);
  }
  return def;
};

Client.prototype._definePort = function(port, endpoint) {
  var location = endpoint,
    binding = port.binding,
    methods = binding.methods,
    def = {};
  for (var name in methods) {
    def[name] = this._defineMethod(methods[name], location);
    this[name] = def[name];
  }
  return def;
};

Client.prototype._defineMethod = function(method, location) {
  var self = this;
  return function(args, callback, options, extraHeaders) {
    if (typeof args === 'function') {
      callback = args;
      args = {};
    }
    self._invoke(method, args, location, function(error, result, raw) {
      callback(error, result, raw);
    }, options, extraHeaders);
  };
};

Client.prototype._invoke = function(method, args, location, callback, options, extraHeaders) {
  var self = this,
    name = method.$name,
    input = method.input,
    output = method.output,
    style = method.style,
    defs = this.wsdl.definitions,
    ns = defs.$targetNamespace,
    encoding = '',
    message = '',
    xml = null,
    req = null,
    soapAction = this.SOAPAction ? this.SOAPAction(ns, name) : (method.soapAction || (((ns.lastIndexOf("/") !== ns.length - 1) ? ns + "/" : ns) + name)),
    headers = {
      SOAPAction: '"' + soapAction + '"',
      'Content-Type': "text/xml; charset=utf-8"
    },
    alias = findKey(defs.xmlns, ns);

  options = options || {};

  //Add extra headers
  for (var attr in extraHeaders) { headers[attr] = extraHeaders[attr]; }

  // Allow the security object to add headers
  if (self.security && self.security.addHeaders)
    self.security.addHeaders(headers);
  if (self.security && self.security.addOptions)
    self.security.addOptions(options);

  if (input.parts) {
    assert.ok(!style || style === 'rpc', 'invalid message definition for document style binding');
    message = self.wsdl.objectToRpcXML(name, args, alias, ns);
    (method.inputSoap === 'encoded') && (encoding = 'soap:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/" ');
  } else if (typeof (args) === 'string') {
    message = args;
  } else if (args === null) {
    message = "<" + name + " />";
  } else {
    assert.ok(!style || style === 'document', 'invalid message definition for rpc style binding');
    // pass `input.$lookupType` if `input.$type` could not be found
    message = self.wsdl.objectToDocumentXML(input.$name, args, input.targetNSAlias, input.targetNamespace, (input.$type || input.$lookupType));
  }
  xml = "<soap:Envelope " +
    "xmlns:soap=\"http://schemas.xmlsoap.org/soap/envelope/\" " +
    "xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" " +
    encoding +
    this.wsdl.xmlnsInEnvelope + '>' +
    ((self.soapHeaders || (self.security && self.security.toXML())) ?
      (
        "<soap:Header>" +
        (self.soapHeaders ? self.soapHeaders.join("\n") : "") +
        (self.security ? self.security.toXML() : "") +
        "</soap:Header>"
      )
      :
        ''
      ) +
    "<soap:Body>" +
    message +
    "</soap:Body>" +
    "</soap:Envelope>";

  self.lastMessage = message;
  self.lastRequest = xml;

  req = http.request(location, xml, function(err, response, body) {
    var result;
    var obj;
    self.lastResponse = body;
    self.lastResponseHeaders = response && response.headers;

    if (err) {
      callback(err);
    } else if (response.statusCode !== 200) {
      callback(new Error('Invalid response: ' + response.statusCode + '\nBody: ' + body));
    } else {
      try {
        obj = self.wsdl.xmlToObject(body);
      } catch (error) {
        error.response = response;
        error.body = body;
        return callback(error, response, body);
      }

      result = obj.Body[output.$name];
      // RPC/literal response body may contain elements with added suffixes I.E.
      // 'Response', or 'Output', or 'Out'
      // This doesn't necessarily equal the ouput message name. See WSDL 1.1 Section 2.4.5
      if(!result){
        result = obj.Body[output.$name.replace(/(?:Out(?:put)?|Response)$/, '')];
      }
      if (!result) {
        ['Response', 'Out', 'Output'].forEach(function (term) {
          if (obj.Body.hasOwnProperty(name + term)) {
            return result = obj.Body[name + term];
          }
        });
      }

      callback(null, result, body);
    }
  }, headers, options);

  // Added mostly for testability, but possibly useful for debugging
  self.lastRequestHeaders = req.headers;
};

exports.Client = Client;
<|endoftext|>


<commit_before>/*global define */
/*
 | Copyright 2014 Esri
 |
 | 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.
 */
define(
     ({
        map: {
            error: "Kan ikke opprette kart" // Shown when error occurs while creation of map
        },
        main: {
            noGroup: "Ingen gruppe er konfigurert" // Appears when no group is configured
        },
        webMapList: {
            owner: "Eier", // Appears in web-map list description panel when it is set to true
            created: "Opprettingsdato", // Appears in web-map list description panel when it is set to true
            modified: "Oppdatert dato", // Appears in web-map list description panel when it is set to true
            description: "Beskrivelse", // Appears in web-map list description panel when it is set to true
            snippet: "Sammendrag", // Appears in web-map list description panel when it is set to true
            licenseInfo: "Begrensning av tilgang og bruk", // Appears in web-map list description panel when it is set to true
            accessInformation: "Krediteringer", // Appears in web-map list description panel when it is set to true
            tags: "Merker", // Appears in web-map list description panel when it is set to true
            numViews: "Antall visninger", // Appears in web-map list description panel when it is set to true
            avgRating: "Vurdering", // Appears in web-map list description panel when it is set to true
            noWebMapInGroup: "Konfigurert gruppe er ugyldig, eller ingen elementer er blitt delt med denne gruppen ennå", // Appears when invalid group in configured or no web-map is available in that group
            infoBtnToolTip: "Kartinformasjon" // Display tool-tip on command button to display description of web-map
        },
        applicationHeader: {
            signOutOption: "Logg ut", // Command button to sign-out from the application
            pleaseSignInText: "Du må logge på", // Appears when user needs to sign-in into the application
            showSelectedOption: "Vis valgte", // Command button to show selected records in data-viewer
            showAllOption: "Vis alle", // Command button to show all the records in data-viewer
            clearSelectionOption: "Fjern utvalg", // Command button to clear selected records in data-viewer
            zoomToSelectedOption: "Zoom til valgt", // Command button to zoom map to selected records
            gridViewOption: "Listevisning", // Command button to display list view
            mapViewOption: "Kartvisning", // Command button to display map view
            gridMapViewOption: "Delt visning", // Command button to display split view
            settingsBtnToolTip: "Alternativer for utvalg", // Display tool-tip on command button to open a list of settings options
            viewModeBtnToolTip: "Visningsalternativer", // Display tool-tip on command button to open a list of view options
            searchModeBtnToolTip: "Søk i dette laget", // Display tool-tip on command button to open a dialog box for finding a feature
            manualRefreshBtnToolTip: "Oppdater", // Display tool-tip on command button to manually refresh the selected operational layer
            confirmManualRefeshText: "Alle utvalg og endringer som ikke er lagret, forkastes", // Appears when user wants to do manual refresh
            signInOption: "Logg på" // Appears when user has not signed in
        },
        dataviewer: {
            noIssuesReported: "Ingen tilgjengelige rapporter", // Appears when no issues are available in current extent
            photoAttachmentHeader: "Vedlegg", // Appears when attachments are available for display in details tab
            invalidSmallNumber: "Angi et heltall ", // Shown when invalid integer value is entered while editing in data-viewer (valid integer value between -32768 and 32767)
            invalidNumber: "Angi et heltall", // Shown when invalid integer value is entered while editing in data-viewer (valid integer value between -2147483648 and 2147483647)
            invalidFloat: "Angi et tall", // Shown when invalid floating value is entered while editing in data-viewer (floating point value between -3.4E38 and 1.2E38)
            invalidDouble: "Angi et tall", // Shown when invalid double value is entered while editing in data-viewer (double value between -2.2E308 and 1.8E308)
            invalidString: "Angi en verdi", // Shown when user enters invalid string value
            invalidDate: "Angi en gyldig dato", // Shown when user enters invalid date value
            invalidNumericRange: "Angi en verdi mellom ${minValue} og ${maxValue}", // Shown when user enters value which is out of range
            moreInfolink: "Kobling", // Shown when value in field contains only URL.
            commentsText: "Kommentarer", // Appears when comments are available for display in details tab
            noCommentsAvailable: "Ingen tilgjengelige kommentarer", // Appears when no comments are available
            noFeatureGeometry: "Kan ikke vise geoobjekt" // Appears when user selects/activates a feature and geometry is available for that
        },
        config: {
            configNotDefined: "Ingen konfigurasjon er definert" // Shown when there is an issue with config file
        },
        searchPanel: {
            noResultsFound: "Fant ingen resultater" // Appears when user search for features and no feature is found
        },
        mapViewer: {
            detailsBtnToolTip: "Vis flere detaljer om det aktive geoobjektet", // Display tool-tip on command button to view details of selected feature
            locationBtnToolTip: "Vis kart", // Display tool-tip on command button to view map panel
            zoomInToolTip: "Zoom inn", // Display tool-tip on command button to zoom in map
            zoomOutToolTip: "Zoom ut" // Display tool-tip on command button to zoom out map
        },
        signOutPage: {
            signOutMessage: "Du er logget av", // Appears when user is successfully signed-out from application
            reSignInMessage: "Klikk her for å logge på" // Appears when user is signed-out from application and wants to sign-in again
        },
        preview: {
            section1: "Crowdsource Manager, en tilleggsgruppemal til Crowdsource Reporter, er en responsiv gruppeappmal (datamaskiner og nettbrett) som gir brukerne i en organisasjon mulighet til å gå gjennom problemer og observasjoner som er sendt inn via Manager-appen.", // Appears when preview page is loaded
            section2: "Appen presenterer ett eller flere kart for brukerne der de kan gå gjennom et problem eller en observasjon. Brukerne kan se etter mønstre og klynger, gå gjennom problemdetaljer, oppdatere status og tildele ansvar.", // Appears when preview page is loaded
            section3: "Programmets kildekode kan lastes ned og tilpasses ytterligere. Tilleggskonfigurasjonen av programmet kan brukes på et konfigurerbart webprogramelement fra ArcGIS Online eller hostes på din egen webserver.
 Hvis du vil ha mer informasjon om hvordan du konfigurerer denne appen, kan du se dokumentasjonen for Crowdsource Manager." // Appears when preview page is loaded
        }
    })
);<commit_msg>Updated language<commit_after>/*global define */
/*
 | Copyright 2014 Esri
 |
 | 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.
 */
define(
     ({
        map: {
            error: "Kan ikke opprette kart" // Shown when error occurs while creation of map
        },
        main: {
            noGroup: "Ingen gruppe er konfigurert" // Appears when no group is configured
        },
        webMapList: {
            owner: "Eier", // Appears in web-map list description panel when it is set to true
            created: "Opprettingsdato", // Appears in web-map list description panel when it is set to true
            modified: "Oppdatert dato", // Appears in web-map list description panel when it is set to true
            description: "Beskrivelse", // Appears in web-map list description panel when it is set to true
            snippet: "Sammendrag", // Appears in web-map list description panel when it is set to true
            licenseInfo: "Begrensning av tilgang og bruk", // Appears in web-map list description panel when it is set to true
            accessInformation: "Krediteringer", // Appears in web-map list description panel when it is set to true
            tags: "Merker", // Appears in web-map list description panel when it is set to true
            numViews: "Antall visninger", // Appears in web-map list description panel when it is set to true
            avgRating: "Vurdering", // Appears in web-map list description panel when it is set to true
            noWebMapInGroup: "Konfigurert gruppe er ugyldig, eller ingen elementer er blitt delt med denne gruppen ennå", // Appears when invalid group in configured or no web-map is available in that group
            infoBtnToolTip: "Kartinformasjon" // Display tool-tip on command button to display description of web-map
        },
        applicationHeader: {
            signOutOption: "Logg ut", // Command button to sign-out from the application
            pleaseSignInText: "Du må logge på", // Appears when user needs to sign-in into the application
            showSelectedOption: "Vis valgte", // Command button to show selected records in data-viewer
            showAllOption: "Vis alle", // Command button to show all the records in data-viewer
            clearSelectionOption: "Fjern utvalg", // Command button to clear selected records in data-viewer
            zoomToSelectedOption: "Zoom til valgt", // Command button to zoom map to selected records
            gridViewOption: "Listevisning", // Command button to display list view
            mapViewOption: "Kartvisning", // Command button to display map view
            gridMapViewOption: "Delt visning", // Command button to display split view
            settingsBtnToolTip: "Alternativer for utvalg", // Display tool-tip on command button to open a list of settings options
            viewModeBtnToolTip: "Visningsalternativer", // Display tool-tip on command button to open a list of view options
            searchModeBtnToolTip: "Søk i dette laget", // Display tool-tip on command button to open a dialog box for finding a feature
            manualRefreshBtnToolTip: "Oppdater", // Display tool-tip on command button to manually refresh the selected operational layer
            confirmManualRefeshText: "Alle utvalg og endringer som ikke er lagret, forkastes", // Appears when user wants to do manual refresh
            signInOption: "Logg på" // Appears when user has not signed in
        },
        dataviewer: {
            noIssuesReported: "Ingen tilgjengelige rapporter", // Appears when no issues are available in current extent
            photoAttachmentHeader: "Vedlegg", // Appears when attachments are available for display in details tab
            invalidSmallNumber: "Angi et heltall ", // Shown when invalid integer value is entered while editing in data-viewer (valid integer value between -32768 and 32767)
            invalidNumber: "Angi et heltall", // Shown when invalid integer value is entered while editing in data-viewer (valid integer value between -2147483648 and 2147483647)
            invalidFloat: "Angi et tall", // Shown when invalid floating value is entered while editing in data-viewer (floating point value between -3.4E38 and 1.2E38)
            invalidDouble: "Angi et tall", // Shown when invalid double value is entered while editing in data-viewer (double value between -2.2E308 and 1.8E308)
            invalidString: "Angi en verdi", // Shown when user enters invalid string value
            invalidDate: "Angi en gyldig dato", // Shown when user enters invalid date value
            invalidNumericRange: "Angi en verdi mellom ${minValue} og ${maxValue}", // Shown when user enters value which is out of range
            moreInfolink: "Kobling", // Shown when value in field contains only URL.
            commentsText: "Kommentarer", // Appears when comments are available for display in details tab
            noCommentsAvailable: "Ingen tilgjengelige kommentarer", // Appears when no comments are available
            noFeatureGeometry: "Kan ikke vise geoobjekt" // Appears when user selects/activates a feature and geometry is available for that
        },
        config: {
            configNotDefined: "Ingen konfigurasjon er definert" // Shown when there is an issue with config file
        },
        searchPanel: {
            noResultsFound: "Fant ingen resultater" // Appears when user search for features and no feature is found
        },
        mapViewer: {
            detailsBtnToolTip: "Vis flere detaljer om det aktive geoobjektet", // Display tool-tip on command button to view details of selected feature
            locationBtnToolTip: "Vis kart", // Display tool-tip on command button to view map panel
            zoomInToolTip: "Zoom inn", // Display tool-tip on command button to zoom in map
            zoomOutToolTip: "Zoom ut" // Display tool-tip on command button to zoom out map
        },
        signOutPage: {
            signOutMessage: "Du er logget av", // Appears when user is successfully signed-out from application
            reSignInMessage: "Klikk her for å logge på" // Appears when user is signed-out from application and wants to sign-in again
        },
        preview: {
            section1: "Crowdsource Manager, en tilleggsgruppemal til Crowdsource Reporter, er en responsiv gruppeappmal (datamaskiner og nettbrett) som gir brukerne i en organisasjon mulighet til å gå gjennom problemer og observasjoner som er sendt inn via Manager-appen.", // Appears when preview page is loaded
            section2: "Appen presenterer ett eller flere kart for brukerne der de kan gå gjennom et problem eller en observasjon. Brukerne kan se etter mønstre og klynger, gå gjennom problemdetaljer, oppdatere status og tildele ansvar.", // Appears when preview page is loaded
            section3: "Programmets kildekode kan lastes ned og tilpasses ytterligere. Tilleggskonfigurasjonen av programmet kan brukes på et konfigurerbart webprogramelement fra ArcGIS Online eller administreres på din egen webserver.
 Hvis du vil ha mer informasjon om hvordan du konfigurerer denne appen, kan du se dokumentasjonen for Crowdsource Manager." // Appears when preview page is loaded
        }
    })
);<|endoftext|>


<commit_before>const coverageVariable = '__start_coverage__';

export function instrument(istanbul = require('istanbul'), options) {
    return function(input) {
        return function coverageInstrument(log) {
            const path = require('path');

            return new Promise((resolve, reject) => {
                const instrumenter = new istanbul.Instrumenter({
                    embedSource: true,
                    noAutoWrap: true,
                    ...options,
                    coverageVariable
                });
                const files = input.map(file => path.resolve(file));

                istanbul.hook.hookRequire(
                    // hook requires which matches input files
                    function(file) {
                        return files.indexOf(file) !== -1;
                    },
                    // and instrument that sources
                    function(source, file) {
                        const result = instrumenter.instrumentSync(source, file);
                        const relativeFile = path.relative(process.cwd(), file);

                        log(relativeFile);

                        return result;
                    }
                );

                resolve(input);
            });
        };
    };
}

export function report(reporters = [ 'lcovonly', 'text-summary' ], dir = 'coverage/') {
    return function(input) {
        return function coverageReport(/* log */) {
            const istanbul = require('istanbul');

            istanbul.hook.unhookRequire();

            return new Promise((resolve, reject) => {
                const collector = new istanbul.Collector();
                const reporter = new istanbul.Reporter(null, dir);

                collector.add(global[coverageVariable]);
                reporter.addAll(reporters);
                reporter.write(collector, false /* async */, () => {
                    resolve(input);
                });
            });
        };
    };
}

export function thresholds(options = {}) {
    return function(input) {
        return function coverageoptions(/* log */) {
            const istanbul = require('istanbul');

            return new Promise((resolve, reject) => {
                const coverage = istanbul.utils.summarizeCoverage(global[coverageVariable]);
                const result = Object.keys(options).reduce((errors, key) => {
                    const threshold = options[key];
                    const summary = coverage[key];

                    // check percentage threshold
                    if (threshold > 0) {
                        if (summary.pct < threshold) {
                            return errors.concat(
                                `${key} percentage: ${summary.pct}% < ${threshold}%`
                            );
                        }
                    }

                    // check gap threshold
                    if (threshold < 0) {
                        if (summary.covered - summary.total < threshold) {
                            return errors.concat(
                                `${key} gap: ${summary.covered} - ${summary.total} < ${threshold}`
                            );
                        }
                    }

                    return errors;
                }, []);

                if (result.length > 0) {
                    return reject(result);
                }

                resolve(input);
            });
        };
    };
}
<commit_msg>:wrench: assume that files paths are absolute from `files` task by default<commit_after>const coverageVariable = '__start_coverage__';

export function instrument(istanbul = require('istanbul'), options) {
    return function(input) {
        return function coverageInstrument(log) {
            const path = require('path');

            return new Promise((resolve, reject) => {
                const instrumenter = new istanbul.Instrumenter({
                    embedSource: true,
                    noAutoWrap: true,
                    ...options,
                    coverageVariable
                });
                istanbul.hook.hookRequire(
                    // hook requires which matches input files
                    function(file) {
                        return input.indexOf(file) !== -1;
                    },
                    // and instrument that sources
                    function(source, file) {
                        const result = instrumenter.instrumentSync(source, file);

                        log(file);

                        return result;
                    }
                );

                resolve(input);
            });
        };
    };
}

export function report(reporters = [ 'lcovonly', 'text-summary' ], dir = 'coverage/') {
    return function(input) {
        return function coverageReport(/* log */) {
            const istanbul = require('istanbul');

            istanbul.hook.unhookRequire();

            return new Promise((resolve, reject) => {
                const collector = new istanbul.Collector();
                const reporter = new istanbul.Reporter(null, dir);

                collector.add(global[coverageVariable]);
                reporter.addAll(reporters);
                reporter.write(collector, false /* async */, () => {
                    resolve(input);
                });
            });
        };
    };
}

export function thresholds(options = {}) {
    return function(input) {
        return function coverageoptions(/* log */) {
            const istanbul = require('istanbul');

            return new Promise((resolve, reject) => {
                const coverage = istanbul.utils.summarizeCoverage(global[coverageVariable]);
                const result = Object.keys(options).reduce((errors, key) => {
                    const threshold = options[key];
                    const summary = coverage[key];

                    // check percentage threshold
                    if (threshold > 0) {
                        if (summary.pct < threshold) {
                            return errors.concat(
                                `${key} percentage: ${summary.pct}% < ${threshold}%`
                            );
                        }
                    }

                    // check gap threshold
                    if (threshold < 0) {
                        if (summary.covered - summary.total < threshold) {
                            return errors.concat(
                                `${key} gap: ${summary.covered} - ${summary.total} < ${threshold}`
                            );
                        }
                    }

                    return errors;
                }, []);

                if (result.length > 0) {
                    return reject(result);
                }

                resolve(input);
            });
        };
    };
}
<|endoftext|>


<commit_before>// Filter function for
//
// Copyright 2011, 2012 StatusNet Inc.
//
// 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 databank = require('databank'),
    Databank = databank.Databank,
    NoSuchThingError = databank.NoSuchThingError,
    Step = require('step');

var RELEVANCE_CUTOFF = 20;
var MINIMUM_OCCURENCES = 3;
var MINPROB = 0.0001;
var MAXPROB = 0.9999;
var DEFAULT_PROB = 0.4; // default probability for unseen values
var SPAM_PROB = 0.90; // cutoff for saying is or isn't

var SpamFilter = {

    db: null,

    opposite: function(cat) {
        if (cat === 'ham') {
            return 'spam';
        } else if (cat === 'spam') {
            return 'ham';
        } else {
            throw new Error('Unknown category: ' + cat);
        }
    },

    updateCounts: function(cat, tokens, onSuccess) {

        var filter = this,
            opp = this.opposite(cat),
            catTotalKey = cat + 'total',
            oppTotalKey = opp + 'total',
            catTotal, oppTotal;

        Step(
            function() {
                filter.db.incr(catTotalKey, 1, this);
            },
            function(err, result) {
                if (err) throw err;
                catTotal = result;
                filter.db.read(oppTotalKey, 1, this);
            },
            function(err, result) {
                var i, group = this.group();
                if (err) {
                    if (err instanceof NoSuchThingError) {
                        oppTotal = 0;
                    } else {
                        throw err;
                    }
                } else {
                    oppTotal = result;
                }
                for (i in tokens) { // Not sure I love this
                    filter.updateTokenCount(cat, tokens[i], catTotal, oppTotal, group());
                }
            },
            function(err, results) {
                if (err) {
                    onSuccess(err, null);
                } else {
                    onSuccess(null, results);
                }
            }
        );
    },

    updateTokenCount: function(cat, token, catTotal, oppTotal, onSuccess) {
        var opp = this.opposite(cat),
            filter = this,
            catCount, oppCount;

        Step(
            function() {
                filter.db.incr(cat, token, this);
            },
            function(err, result) {
                if (err) throw err;
                catCount = result;
                filter.db.read(opp, token, this);
            },
            function(err, result) {
                if (err instanceof NoSuchThingError) {
                    oppCount = 0;
                } else if (err) {
                    onSuccess(err, null);
                } else {
                    oppCount = result;
                }

                if (cat === 'spam') {
                    filter.updateTokenProb(token, catCount, oppCount, catTotal, oppTotal, onSuccess);
                } else {
                    filter.updateTokenProb(token, oppCount, catCount, oppTotal, catTotal, onSuccess);
                }
            }
        );
    },

    updateTokenProb: function(token, spamCount, hamCount, spamTotal, hamTotal, onSuccess) {
        var g = 2 * hamCount,
            b = spamCount;

        if (g + b > 5) {
            var p = Math.max(MINPROB,
                             Math.min(MAXPROB,
                                      Math.min(1, b/spamTotal)/
                                      (Math.min(1, g/hamTotal) + Math.min(1, b/spamTotal))));
            this.db.save('prob', token, p, onSuccess);
        }
    },

    getProbabilities: function(tokens, onSuccess) {
        this.db.readAll('prob', tokens, function(err, probs) {
            var i, probabilities = [], token;
            for (i = 0; i < tokens.length; i++) {
                token = tokens[i];
                // There's probably a nicer data structure for this
                if (probs[token] === null) {
                    probabilities.push([token, DEFAULT_PROB]);
                } else {
                    probabilities.push([token, probs[token]]);
                }
            }
            onSuccess(probabilities);
        });
    },

    bestProbabilities: function(probs) {
        probs.sort(function (a, b) {
            var adist = Math.abs(a[1] - 0.5);
            var bdist = Math.abs(b[1] - 0.5);

            if (adist > bdist) {
                return -1;
            } else if (bdist > adist) {
                return 1;
            } else {
                return 0;
            }
        });

        // Get the most relevant
        return probs.slice(0, Math.min(probs.length, RELEVANCE_CUTOFF));
    },

    combineProbabilities: function(probs) {
        var prod = probs.reduce(function(coll, cur, index, array) {
            return coll * cur[1];
        }, 1.0);

        var invprod = probs.reduce(function(coll, cur, index, array) {
            return coll * (1 - cur[1]);
        }, 1.0);

        //bounded values
        return Math.min(MAXPROB, Math.max(MINPROB, (prod)/(prod + invprod))); // really?
    },

    schema: {'spam': {pkey: 'token'},
              'ham': {pkey: 'token'},
              'prob': {pkey: 'token'},
              'spamtotal': {pkey: 'service'},
              'hamtotal': {pkey: 'service'}}
};

exports.SpamFilter = SpamFilter;
<commit_msg>always return<commit_after>// Filter function for
//
// Copyright 2011, 2012 StatusNet Inc.
//
// 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 databank = require('databank'),
    Databank = databank.Databank,
    NoSuchThingError = databank.NoSuchThingError,
    Step = require('step');

var RELEVANCE_CUTOFF = 20;
var MINIMUM_OCCURENCES = 3;
var MINPROB = 0.0001;
var MAXPROB = 0.9999;
var DEFAULT_PROB = 0.4; // default probability for unseen values
var SPAM_PROB = 0.90; // cutoff for saying is or isn't

var SpamFilter = {

    db: null,

    opposite: function(cat) {
        if (cat === 'ham') {
            return 'spam';
        } else if (cat === 'spam') {
            return 'ham';
        } else {
            throw new Error('Unknown category: ' + cat);
        }
    },

    updateCounts: function(cat, tokens, onSuccess) {

        var filter = this,
            opp = this.opposite(cat),
            catTotalKey = cat + 'total',
            oppTotalKey = opp + 'total',
            catTotal, oppTotal;

        Step(
            function() {
                filter.db.incr(catTotalKey, 1, this);
            },
            function(err, result) {
                if (err) throw err;
                catTotal = result;
                filter.db.read(oppTotalKey, 1, this);
            },
            function(err, result) {
                var i, group = this.group();
                if (err) {
                    if (err instanceof NoSuchThingError) {
                        oppTotal = 0;
                    } else {
                        throw err;
                    }
                } else {
                    oppTotal = result;
                }
                for (i in tokens) { // Not sure I love this
                    filter.updateTokenCount(cat, tokens[i], catTotal, oppTotal, group());
                }
            },
            function(err, results) {
                if (err) {
                    onSuccess(err, null);
                } else {
                    onSuccess(null, results);
                }
            }
        );
    },

    updateTokenCount: function(cat, token, catTotal, oppTotal, onSuccess) {
        var opp = this.opposite(cat),
            filter = this,
            catCount, oppCount;

        Step(
            function() {
                filter.db.incr(cat, token, this);
            },
            function(err, result) {
                if (err) throw err;
                catCount = result;
                filter.db.read(opp, token, this);
            },
            function(err, result) {
                if (err instanceof NoSuchThingError) {
                    oppCount = 0;
                } else if (err) {
                    onSuccess(err, null);
                } else {
                    oppCount = result;
                }

                if (cat === 'spam') {
                    filter.updateTokenProb(token, catCount, oppCount, catTotal, oppTotal, onSuccess);
                } else {
                    filter.updateTokenProb(token, oppCount, catCount, oppTotal, catTotal, onSuccess);
                }
            }
        );
    },

    updateTokenProb: function(token, spamCount, hamCount, spamTotal, hamTotal, onSuccess) {
        var g = 2 * hamCount,
            b = spamCount;

        if (g + b > 5) {
            var p = Math.max(MINPROB,
                             Math.min(MAXPROB,
                                      Math.min(1, b/spamTotal)/
                                      (Math.min(1, g/hamTotal) + Math.min(1, b/spamTotal))));
            this.db.save('prob', token, p, onSuccess);
        } else {
            onSuccess(null, null);
        }
    },

    getProbabilities: function(tokens, onSuccess) {
        this.db.readAll('prob', tokens, function(err, probs) {
            var i, probabilities = [], token;
            for (i = 0; i < tokens.length; i++) {
                token = tokens[i];
                // There's probably a nicer data structure for this
                if (probs[token] === null) {
                    probabilities.push([token, DEFAULT_PROB]);
                } else {
                    probabilities.push([token, probs[token]]);
                }
            }
            onSuccess(probabilities);
        });
    },

    bestProbabilities: function(probs) {
        probs.sort(function (a, b) {
            var adist = Math.abs(a[1] - 0.5);
            var bdist = Math.abs(b[1] - 0.5);

            if (adist > bdist) {
                return -1;
            } else if (bdist > adist) {
                return 1;
            } else {
                return 0;
            }
        });

        // Get the most relevant
        return probs.slice(0, Math.min(probs.length, RELEVANCE_CUTOFF));
    },

    combineProbabilities: function(probs) {
        var prod = probs.reduce(function(coll, cur, index, array) {
            return coll * cur[1];
        }, 1.0);

        var invprod = probs.reduce(function(coll, cur, index, array) {
            return coll * (1 - cur[1]);
        }, 1.0);

        //bounded values
        return Math.min(MAXPROB, Math.max(MINPROB, (prod)/(prod + invprod))); // really?
    },

    schema: {'spam': {pkey: 'token'},
              'ham': {pkey: 'token'},
              'prob': {pkey: 'token'},
              'spamtotal': {pkey: 'service'},
              'hamtotal': {pkey: 'service'}}
};

exports.SpamFilter = SpamFilter;
<|endoftext|>


<commit_before>var Sunset;

Sunset = require('../lib/sunset');

describe("Sunset", function() {
  var activationPromise, ref, workspaceElement;
  ref = [], workspaceElement = ref[0], activationPromise = ref[1];
  beforeEach(function() {
    workspaceElement = atom.views.getView(atom.workspace);
    return activationPromise = atom.packages.activatePackage('sunset');
  });
  return describe("when the sunset:toggle event is triggered", function() {
    it("hides and shows the modal panel", function() {
      expect(workspaceElement.querySelector('.sunset')).not.toExist();
      atom.commands.dispatch(workspaceElement, 'sunset:toggle');
      waitsForPromise(function() {
        return activationPromise;
      });
      return runs(function() {
        var sunsetElement, sunsetPanel;
        expect(workspaceElement.querySelector('.sunset')).toExist();
        sunsetElement = workspaceElement.querySelector('.sunset');
        expect(sunsetElement).toExist();
        sunsetPanel = atom.workspace.panelForItem(sunsetElement);
        expect(sunsetPanel.isVisible()).toBe(true);
        atom.commands.dispatch(workspaceElement, 'sunset:toggle');
        return expect(sunsetPanel.isVisible()).toBe(false);
      });
    });
    return it("hides and shows the view", function() {
      jasmine.attachToDOM(workspaceElement);
      expect(workspaceElement.querySelector('.sunset')).not.toExist();
      atom.commands.dispatch(workspaceElement, 'sunset:toggle');
      waitsForPromise(function() {
        return activationPromise;
      });
      return runs(function() {
        var sunsetElement;
        sunsetElement = workspaceElement.querySelector('.sunset');
        expect(sunsetElement).toBeVisible();
        atom.commands.dispatch(workspaceElement, 'sunset:toggle');
        return expect(sunsetElement).not.toBeVisible();
      });
    });
  });
});
<commit_msg>these don't look relevant anymore<commit_after><|endoftext|>


<commit_before>define ([
    'kbwidget',
    'bootstrap',
    'jquery',
    'kbase-client-api',
    'widgets/dynamicTable',
    'kbaseAuthenticatedWidget',
    'kbaseTabs',
    'kbase-generic-client-api',
    'narrativeConfig',
    'bluebird'
], function(
	KBWidget,
	bootstrap,
	$,
    kbase_client_api,
    DynamicTable,
	kbaseAuthenticatedWidget,
    kbaseTabs,
    GenericClient,
    Config,
    Promise
) {
    'use strict';

    return KBWidget({
        name: 'kbaseGenomeAnnotationAssembly',
        parent: kbaseAuthenticatedWidget,
        version: '1.0.0',
        options: {
            pageLimit: 10

        },

        init: function init(options) {
            this._super(options);

            var self = this;
            self.obj_ref = self.options.wsNameOrId + '/' + self.options.objNameOrId;
            self.link_ref = self.obj_ref;

            if(options._obj_info) {
                self.assembly_info = options._obj_info;
                self.obj_ref = self.assembly_info['ws_id'] + '/' + self.assembly_info['id'] + '/' + self.assembly_info['version'];
                self.link_ref = self.assembly_info['ws_id'] + '/' + self.assembly_info['name'] + '/' + self.assembly_info['version'];
            }

            self.client = new GenericClient(Config.url('service_wizard'), {token: self.authToken()});
            self.ws = new Workspace(Config.url('workspace'),{'token':self.authToken()});

            self.$elem.append($('
').attr('align', 'center').append($('')));

            // 1) get stats, and show the panel
            var basicInfoCalls = [];
            basicInfoCalls.push(
                Promise.resolve(self.client.sync_call('AssemblyAPI.get_stats', [this.obj_ref], null, null, 'dev'))
                    .then(function(stats) {
                        self.assembly_stats = stats[0];
                    }));
            basicInfoCalls.push(
                Promise.resolve(self.ws.get_object_info_new({objects: [{'ref':this.obj_ref}], includeMetadata:1}))
                    .then(function(info) {
                        self.assembly_obj_info = info[0];
                        self.link_ref = info[0][6] + '/' + info[0][1] + '/' + info[0][4];
                    }));
            Promise.all(basicInfoCalls)
                .then(function() {
                    self.renderBasicTable();
                })
                .catch(function(err) {
                    console.error('an error occurred! ' + err);
                    self.$elem.empty();
                    self.$elem.append('Error' + JSON.stringify(err));
                });

            return this;
        },

        processContigData: function() {
            var self = this;

            var contig_table = [];
            for (var id in self.contig_lengths) {
                if (self.contig_lengths.hasOwnProperty(id)) {
                    var gc='unknown';
                    if(self.contig_lengths.hasOwnProperty(id)) {
                        gc = String((self.contig_gc[id]*100).toFixed(2)) + '%';
                    }
                    var contig = {
                        id: id,
                        len: '' + String(self.numberWithCommas(self.contig_lengths[id]))+' bp',
                        gc:  gc
                    };
                    contig_table.push(contig);
                }
            }
            self.contig_table = contig_table;
            //console.log(contig_table);
        },

        renderBasicTable: function() {
            var self = this;
            var $container = this.$elem;
            $container.empty();

            var $tabPane = $('
');
            $container.append($tabPane);

            // Build the overview table
            var $overviewTable = $('
');

            function get_table_row(key, value) {
                return $('
').append($('').append(key)).append($('').append(value));
            }

            $overviewTable.append(get_table_row('KBase Object Name',
                '' + self.assembly_obj_info[1] +'' ));
                // leave out version for now, because that is not passed into data widgets
                //'' + self.assembly_obj_info[1] + ' (v'+self.assembly_obj_info[4]+')'+'' ));
            $overviewTable.append(get_table_row('Number of Contigs', self.assembly_stats['num_contigs'] ));
            $overviewTable.append(get_table_row('Total GC Content',  String((self.assembly_stats['gc_content']*100).toFixed(2)) + '%' ));
            $overviewTable.append(get_table_row('Total Length',      String(self.numberWithCommas(self.assembly_stats['dna_size']))+' bp'  )  );

            // Build the tabs
            var $tabs = new kbaseTabs($tabPane, {
                tabPosition : 'top',
                canDelete : true, //whether or not the tab can be removed.
                tabs : [
                    {
                        tab : 'Assembly Summary',   //name of the tab
                        content : $('
').css('margin-top','15px').append($overviewTable),  //jquery object to stuff into the content
                        canDelete : false, //override the canDelete param on a per tab basis
                        show : true,
                    }, {
                        tab : 'Contigs',
                        canDelete : false,
                        showContentCallback: function() {
                            return self.addContigList();
                        }
                    },
                ],
            });
        },

        addContigList: function() {
            var self = this;
            var $content = $('
');
            new DynamicTable($content, {
                headers: [{
                    id: 'contig_id',
                    text: 'Contig Id',
                    isSortable: true
                }, {
                    id: 'length',
                    text: 'Length (bp)',
                    isSortable: true
                }, {
                    id: 'gc',
                    text: 'GC Content (%)',
                    isSortable: true
                }],
                searchPlaceholder: 'Search contigs',
                updateFunction: function(pageNum, query, sortColId, sortColDir) {
                    var sortBy = [];
                    if (sortColId && sortColDir !== 0) {
                        sortBy.push([sortColId, sortColDir < 0 ? 0 : 1]);
                    }
                    return Promise.resolve(self.client.sync_call('AssemblyAPI.search_contigs', [{
                        ref: self.obj_ref,
                        query: query,
                        sort_by: sortBy,
                        start: pageNum * self.options.pageLimit
                    }], null, null, 'dev'))
                    .then(function(results) {
                        results = results[0];
                        var rows = [];
                        results.contigs.forEach(function(contig) {
                            rows.push([contig.contig_id, contig.length, contig.gc]);
                        });
                        return {
                            rows: rows,
                            start: results.start,
                            query: results.query,
                            total: results.num_found,
                        };
                    });
                },
                style: {'margin-top': '5px'}
            });
            return $content;
        },

        numberWithCommas: function(x) {
            return x.toString().replace(/\B(?=(\d{3})+(?!\d))/g, ',');
        }
    });

});
<commit_msg>remove dependency on dev for assembly viewer<commit_after>define ([
    'kbwidget',
    'bootstrap',
    'jquery',
    'kbase-client-api',
    'widgets/dynamicTable',
    'kbaseAuthenticatedWidget',
    'kbaseTabs',
    'kbase-generic-client-api',
    'narrativeConfig',
    'bluebird'
], function(
	KBWidget,
	bootstrap,
	$,
    kbase_client_api,
    DynamicTable,
	kbaseAuthenticatedWidget,
    kbaseTabs,
    GenericClient,
    Config,
    Promise
) {
    'use strict';

    return KBWidget({
        name: 'kbaseGenomeAnnotationAssembly',
        parent: kbaseAuthenticatedWidget,
        version: '1.0.0',
        options: {
            pageLimit: 10

        },

        init: function init(options) {
            this._super(options);

            var self = this;
            self.obj_ref = self.options.wsNameOrId + '/' + self.options.objNameOrId;
            self.link_ref = self.obj_ref;

            if(options._obj_info) {
                self.assembly_info = options._obj_info;
                self.obj_ref = self.assembly_info['ws_id'] + '/' + self.assembly_info['id'] + '/' + self.assembly_info['version'];
                self.link_ref = self.assembly_info['ws_id'] + '/' + self.assembly_info['name'] + '/' + self.assembly_info['version'];
            }

            self.client = new GenericClient(Config.url('service_wizard'), {token: self.authToken()});
            self.ws = new Workspace(Config.url('workspace'),{'token':self.authToken()});

            self.$elem.append($('
').attr('align', 'center').append($('')));

            // 1) get stats, and show the panel
            var basicInfoCalls = [];
            basicInfoCalls.push(
                Promise.resolve(self.client.sync_call('AssemblyAPI.get_stats', [this.obj_ref]))
                    .then(function(stats) {
                        self.assembly_stats = stats[0];
                    }));
            basicInfoCalls.push(
                Promise.resolve(self.ws.get_object_info_new({objects: [{'ref':this.obj_ref}], includeMetadata:1}))
                    .then(function(info) {
                        self.assembly_obj_info = info[0];
                        self.link_ref = info[0][6] + '/' + info[0][1] + '/' + info[0][4];
                    }));
            Promise.all(basicInfoCalls)
                .then(function() {
                    self.renderBasicTable();
                })
                .catch(function(err) {
                    console.error('an error occurred! ' + err);
                    self.$elem.empty();
                    self.$elem.append('Error' + JSON.stringify(err));
                });

            return this;
        },

        processContigData: function() {
            var self = this;

            var contig_table = [];
            for (var id in self.contig_lengths) {
                if (self.contig_lengths.hasOwnProperty(id)) {
                    var gc='unknown';
                    if(self.contig_lengths.hasOwnProperty(id)) {
                        gc = String((self.contig_gc[id]*100).toFixed(2)) + '%';
                    }
                    var contig = {
                        id: id,
                        len: '' + String(self.numberWithCommas(self.contig_lengths[id]))+' bp',
                        gc:  gc
                    };
                    contig_table.push(contig);
                }
            }
            self.contig_table = contig_table;
            //console.log(contig_table);
        },

        renderBasicTable: function() {
            var self = this;
            var $container = this.$elem;
            $container.empty();

            var $tabPane = $('
');
            $container.append($tabPane);

            // Build the overview table
            var $overviewTable = $('
');

            function get_table_row(key, value) {
                return $('
').append($('').append(key)).append($('').append(value));
            }

            $overviewTable.append(get_table_row('KBase Object Name',
                '' + self.assembly_obj_info[1] +'' ));
                // leave out version for now, because that is not passed into data widgets
                //'' + self.assembly_obj_info[1] + ' (v'+self.assembly_obj_info[4]+')'+'' ));
            $overviewTable.append(get_table_row('Number of Contigs', self.assembly_stats['num_contigs'] ));
            $overviewTable.append(get_table_row('Total GC Content',  String((self.assembly_stats['gc_content']*100).toFixed(2)) + '%' ));
            $overviewTable.append(get_table_row('Total Length',      String(self.numberWithCommas(self.assembly_stats['dna_size']))+' bp'  )  );

            // Build the tabs
            var $tabs = new kbaseTabs($tabPane, {
                tabPosition : 'top',
                canDelete : true, //whether or not the tab can be removed.
                tabs : [
                    {
                        tab : 'Assembly Summary',   //name of the tab
                        content : $('
').css('margin-top','15px').append($overviewTable),  //jquery object to stuff into the content
                        canDelete : false, //override the canDelete param on a per tab basis
                        show : true,
                    }, {
                        tab : 'Contigs',
                        canDelete : false,
                        showContentCallback: function() {
                            return self.addContigList();
                        }
                    },
                ],
            });
        },

        addContigList: function() {
            var self = this;
            var $content = $('
');
            new DynamicTable($content, {
                headers: [{
                    id: 'contig_id',
                    text: 'Contig Id',
                    isSortable: true
                }, {
                    id: 'length',
                    text: 'Length (bp)',
                    isSortable: true
                }, {
                    id: 'gc',
                    text: 'GC Content (%)',
                    isSortable: true
                }],
                searchPlaceholder: 'Search contigs',
                updateFunction: function(pageNum, query, sortColId, sortColDir) {
                    var sortBy = [];
                    if (sortColId && sortColDir !== 0) {
                        sortBy.push([sortColId, sortColDir < 0 ? 0 : 1]);
                    }
                    return Promise.resolve(self.client.sync_call('AssemblyAPI.search_contigs', [{
                        ref: self.obj_ref,
                        query: query,
                        sort_by: sortBy,
                        start: pageNum * self.options.pageLimit
                    }]))
                    .then(function(results) {
                        results = results[0];
                        var rows = [];
                        results.contigs.forEach(function(contig) {
                            rows.push([contig.contig_id, contig.length, contig.gc]);
                        });
                        return {
                            rows: rows,
                            start: results.start,
                            query: results.query,
                            total: results.num_found,
                        };
                    });
                },
                style: {'margin-top': '5px'}
            });
            return $content;
        },

        numberWithCommas: function(x) {
            return x.toString().replace(/\B(?=(\d{3})+(?!\d))/g, ',');
        }
    });

});
<|endoftext|>


<commit_before><commit_msg>remove duplicate flipcounter<commit_after><|endoftext|>