<commit_before>var cbus = {};

navigator.getUserMedia = navigator.getUserMedia || navigator.webkitGetUserMedia;
window.AudioContext = window.AudioContext || window.webkitAudioContext;

const request = function(options, callback) {
  var url;
  var headers;

  if (typeof options === "object") {
    url = options.url
    if (options.hasOwnProperty("headers")) { headers = options.headers }
  } else {
    url = options
  }

  console.log(url)
  console.log(headers)

  var req = new XMLHttpRequest();
  req.onload = function(e){
    callback(this.responseText, url, e);
  };

  req.open("get", url, true);

  if (headers) {
    for (key in headers) {
      req.setRequestHeader(key, headers[key])
    }
  }

  req.send();
};

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

const 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;
};

const mergeObjects = function(a, b){
    var result = {};

    for (var key in a) {
        result[key] = a[key];
    }
    for (var key in b) {
        result[key] = b[key];
    }

    return result;
};

const arrayFindByKey = function(arr, pair) {
    let key = Object.keys(pair)[0];
    let val = pair[key];

    let results = [];

    for (let i = 0, l = arr.length; i < l; i++) {
        if (arr[i][key] === val) {
            results.push(arr[i]);
        }
    }

    return results;
};

const decodeHTML = function(html) {
    var elem = document.createElement("div");
    elem.innerHTML = html;
    return elem.textContent;
};

const removeHTMLTags = function(html) {
    return html.replace(/(<([^>]+)>)/ig, ""); // css-tricks.com/snippets/javascript/strip-html-tags-in-javascript
};

const KEYCODES = {
    "0": 48,
    "1": 49,
    "2": 50,
    "3": 51,
    "4": 52,
    "5": 53,
    "6": 54,
    "7": 55,
    "8": 56,
    "9": 57,
    "A": 65,
    "B": 66,
    "C": 67,
    "D": 68,
    "E": 69,
    "F": 70,
    "G": 71,
    "H": 72,
    "I": 73,
    "J": 74,
    "K": 75,
    "L": 76,
    "M": 77,
    "N": 78,
    "O": 79,
    "P": 80,
    "Q": 81,
    "R": 82,
    "S": 83,
    "T": 84,
    "U": 85,
    "V": 86,
    "W": 87,
    "X": 88,
    "Y": 89,
    "Z": 90,
    "a": 97,
    "b": 98,
    "c": 99,
    "d": 100,
    "e": 101,
    "f": 102,
    "g": 103,
    "h": 104,
    "i": 105,
    "j": 106,
    "k": 107,
    "l": 108,
    "m": 109,
    "n": 110,
    "o": 111,
    "p": 112,
    "q": 113,
    "r": 114,
    "s": 115,
    "t": 116,
    "u": 117,
    "v": 118,
    "w": 119,
    "x": 120,
    "y": 121,
    "z": 122,
    "_space": 32
};

const localforageGetMulti = function(keys, callback) {
  let results = {}
  for (let i = 0, l = keys.length; i < l; i++) {
    localforage.getItem(keys[i]).then(function(r) {
      results[keys[i]] = r
      if (Object.keys(results).length === keys.length) {
        callback(results)
      }
    })
  }
}

const existsRecursive = function(root, path) {
  if (typeof root !== "object") {
    throw new TypeError("First argument must be an object")
  }
  var currentObject = root
  for (let i = 0, l = path.length; i < l; i++) {
    if (!currentObject.hasOwnProperty(path[i])) {
      return false
    }
    currentObject = currentObject[path[i]]
  }
  return true
}
<commit_msg>Slightly improve localforageGetMulti performance<commit_after>var cbus = {};

navigator.getUserMedia = navigator.getUserMedia || navigator.webkitGetUserMedia;
window.AudioContext = window.AudioContext || window.webkitAudioContext;

const request = function(options, callback) {
  var url;
  var headers;

  if (typeof options === "object") {
    url = options.url
    if (options.hasOwnProperty("headers")) { headers = options.headers }
  } else {
    url = options
  }

  console.log(url)
  console.log(headers)

  var req = new XMLHttpRequest();
  req.onload = function(e){
    callback(this.responseText, url, e);
  };

  req.open("get", url, true);

  if (headers) {
    for (key in headers) {
      req.setRequestHeader(key, headers[key])
    }
  }

  req.send();
};

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

const 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;
};

const mergeObjects = function(a, b){
    var result = {};

    for (var key in a) {
        result[key] = a[key];
    }
    for (var key in b) {
        result[key] = b[key];
    }

    return result;
};

const arrayFindByKey = function(arr, pair) {
    let key = Object.keys(pair)[0];
    let val = pair[key];

    let results = [];

    for (let i = 0, l = arr.length; i < l; i++) {
        if (arr[i][key] === val) {
            results.push(arr[i]);
        }
    }

    return results;
};

const decodeHTML = function(html) {
    var elem = document.createElement("div");
    elem.innerHTML = html;
    return elem.textContent;
};

const removeHTMLTags = function(html) {
    return html.replace(/(<([^>]+)>)/ig, ""); // css-tricks.com/snippets/javascript/strip-html-tags-in-javascript
};

const KEYCODES = {
    "0": 48,
    "1": 49,
    "2": 50,
    "3": 51,
    "4": 52,
    "5": 53,
    "6": 54,
    "7": 55,
    "8": 56,
    "9": 57,
    "A": 65,
    "B": 66,
    "C": 67,
    "D": 68,
    "E": 69,
    "F": 70,
    "G": 71,
    "H": 72,
    "I": 73,
    "J": 74,
    "K": 75,
    "L": 76,
    "M": 77,
    "N": 78,
    "O": 79,
    "P": 80,
    "Q": 81,
    "R": 82,
    "S": 83,
    "T": 84,
    "U": 85,
    "V": 86,
    "W": 87,
    "X": 88,
    "Y": 89,
    "Z": 90,
    "a": 97,
    "b": 98,
    "c": 99,
    "d": 100,
    "e": 101,
    "f": 102,
    "g": 103,
    "h": 104,
    "i": 105,
    "j": 106,
    "k": 107,
    "l": 108,
    "m": 109,
    "n": 110,
    "o": 111,
    "p": 112,
    "q": 113,
    "r": 114,
    "s": 115,
    "t": 116,
    "u": 117,
    "v": 118,
    "w": 119,
    "x": 120,
    "y": 121,
    "z": 122,
    "_space": 32
};

const localforageGetMulti = function(keys, callback) {
  let results = {};

  var gotCount = 0;
  let keysCount = keys.length;

  for (let i = 0, l = keys.length; i < l; i++) {
    localforage.getItem(keys[i]).then(function(r) {
      results[keys[i]] = r;
      gotCount++;
      if (gotCount === keysCount) {
        callback(results);
      }
    });
  }
};

const existsRecursive = function(root, path) {
  if (typeof root !== "object") {
    throw new TypeError("First argument must be an object")
  }
  var currentObject = root
  for (let i = 0, l = path.length; i < l; i++) {
    if (!currentObject.hasOwnProperty(path[i])) {
      return false
    }
    currentObject = currentObject[path[i]]
  }
  return true
}
<|endoftext|>


<commit_before>// SW_CACHE_VERSION will be replaced while copying this file to the build directory with InterpolateSWPlugin
const reactPWAFromScratchCacheVersion = 'react-pwa-from-scratch-v' + '%SW_CACHE_VERSION%';

// SW_ASSET_FILES will be feed with all the generated assets for pre-cache purposes
//  while copying this file to the build directory with InterpolateSWPlugin
const cacheAll = [%SW_ASSET_FILES%];

/**
 * Pre-cache some assets when service worker is registered
 */
this.addEventListener('install', (event) => {
  event.waitUntil(
    caches.open(reactPWAFromScratchCacheVersion).then((cache) => {
      return cache.addAll(cacheAll);
    })
  );
});

/**
 * Activate gets executed after install in the sw life cycle. So current cache is already created.
 */
this.addEventListener('activate', (event) => {

    // Promises passed here will block other events, we can safely remove old caches or content here
    event.waitUntil(
      // Loop through all created caches
      caches.keys().then((keyList) => {
        return Promise.all(keyList.map((key) => {
          // For now that would do it. Delete all previously created caches but the current one.
          if (reactPWAFromScratchCacheVersion != key) {
            return caches.delete(key);
          }
        }));
      })
    );

  });

/**
 * Intercepts application's requests and serves them first from cache.
 */
this.addEventListener('fetch', (event) => {
  event.respondWith(

    // Request in cache?
    caches.match(event.request).then((cacheResponse) => {

      return cacheResponse || fetch(event.request).then((fetchedResponse) => {

        // Better off cloning the response here. If done inside caches.open reponse could
        // be already read by returning the original response.
        var clonedFetchedResponse = fetchedResponse.clone();

        // Request was not in the cache. We fetched it and now we save it in the cache.
        caches.open(reactPWAFromScratchCacheVersion).then((cache) => {

          // Reponse stream can be read only once so that it must be cloned.
          cache.put(event.request, clonedFetchedResponse);

        });

        // Make sure reposnse is already cloned before returning here.
        return fetchedResponse;
      });

    })
    .catch(() => {

      // Fallback answer if there is no connectivity and request is not in cache.
      return new Response('Fallback answer if there is no connectivity and request is not in cache.');

    })
  );
});

/**
 * Custom messages from the application thread
 */
self.addEventListener('message', function(event) {
  if (event.data.action === 'skipWaiting') {
    self.skipWaiting();
  }
});<commit_msg>Service worker detecting new app version<commit_after>// SW_CACHE_VERSION will be replaced while copying this file to the build directory with InterpolateSWPlugin
const reactPWAFromScratchCacheVersion = 'react-pwa-from-scratch-v' + '%SW_CACHE_VERSION%';

// SW_ASSET_FILES will be feed with all the generated assets for pre-cache purposes
//  while copying this file to the build directory with InterpolateSWPlugin
const cacheAll = [%SW_ASSET_FILES%];

/**
 * Pre-cache some assets when service worker is registered
 */
this.addEventListener('install', (event) => {
  event.waitUntil(
    caches.open(reactPWAFromScratchCacheVersion).then((cache) => {
      return cache.addAll(cacheAll);
    })
  );
});

/**
 * Activate gets executed after install in the sw life cycle. So current cache is already created.
 */
this.addEventListener('activate', (event) => {

    // Promises passed here will block other events, we can safely remove old caches or content here
    event.waitUntil(
      // Loop through all created caches
      caches.keys().then((keyList) => {
        return Promise.all(keyList.map((key) => {
          // For now that would do it. Delete all previously created caches but the current one.
          if (reactPWAFromScratchCacheVersion != key) {
            return caches.delete(key);
          }
        }));
      })
    );

  });

/**
 * Intercepts application's requests and serves them first from cache.
 */
this.addEventListener('fetch', (event) => {
  event.respondWith(

    // Request in cache?
    caches.match(event.request).then((cacheResponse) => {

      return cacheResponse || fetch(event.request).then((fetchedResponse) => {

        // Better off cloning the response here. If done inside caches.open reponse could
        // be already read by returning the original response.
        var clonedFetchedResponse = fetchedResponse.clone();

        // Request was not in the cache. We fetched it and now we save it in the cache.
        caches.open(reactPWAFromScratchCacheVersion).then((cache) => {

          // Reponse stream can be read only once so that it must be cloned.
          cache.put(event.request, clonedFetchedResponse);

        });

        // Make sure reposnse is already cloned before returning here.
        return fetchedResponse;
      });

    })
    .catch(() => {

      // Fallback answer if there is no connectivity and request is not in cache.
      return new Response('Fallback answer if there is no connectivity and request is not in cache.');

    })
  );
});

/**
 * Custom messages from the application thread
 */
self.addEventListener('message', function(event) {
  // Activate the new service worker
  if (event.data.action === 'skipWaiting') {
    self.skipWaiting();
  }
});<|endoftext|>


<commit_before>define(["./account.js"], function (account) {

  function OnStartup (bezl) {
      bezl.vars.filterString = "";

      // Load the object for the selected customer from local storage into
      // a variable we can work with
      if (typeof(Storage) !== "undefined" && localStorage.getItem("selectedAccount")) {
          bezl.vars.selectedAccount = JSON.parse(localStorage.getItem("selectedAccount"));

          // Perform additional processing on the returned data
          for (var i = 0; i < bezl.vars.selectedAccount.CRMCalls.length; i++) {
            bezl.vars.selectedAccount.CRMCalls[i].show = true;
          }
      }

      // Refresh all call data at regular interval
      account.runQuery(bezl, "AllCRMCalls");

      // Also pull in the list of defined CRM call types.  This is expecting a plugin instance
      // to be defined in BRDB named sales-rep-calltypes which points to a data source for call
      // types
      bezl.dataService.add('CallTypes','brdb','sales-rep-queries','ExecuteQuery', { "QueryName": "GetCallTypes" },0);

      $(".panel").on("selectAccount", function(event, param1) {
        bezl.vars.selectedAccount = param1;
        bezl.vars.loadedMore = false;

        // If there are no CRM calls present with what was passed over, go
        // ahead and run the full query now
        if (!bezl.vars.selectedAccount.CRMCalls) {
          account.runQuery(bezl, "CRMCalls");
        } else {
          // Perform additional processing on the returned data
          for (var i = 0; i < bezl.vars.selectedAccount.CRMCalls.length; i++) {
            bezl.vars.selectedAccount.CRMCalls[i].show = true;
          }
        }

        $(bezl.container.nativeElement).find('#filterString')[0].value = ""; // Clear out the search filter box

      });

      // Prepopulate the CRM new interaction form for click to call/email/navigate
      // Should pass data in param1 in the form of:
      // {
      //   "type": <enum: "phone", "email", "navigate">,
      //   "shortSummary": <string>,
      //   "details": <string>
      // }
      $(".panel").on("CRMNewInteraction", function(event, param1) {
        // TODO: look up an appropriate type from the CallTypes list
        // This should eventually be a config option to select the local
        // CallType to be used for phone/email/navigate. For now we will use
        // some much less useful default strings.
        switch (param1.type) {
            case "phone":
                bezl.vars.type = "Sales";
                break;
            case "email":
                bezl.vars.type = "Email";
                break;
            case "navigate":
                bezl.vars.type = "Customer Visit";
                break;
        }

        bezl.vars.shortSummary = param1.shortSummary;
        bezl.vars.details = param1.details;
      });
  }

  return {
    onStartup: OnStartup
  }
});
<commit_msg>Handle switching between selected accounts.<commit_after>define(["./account.js"], function (account) {

  function OnStartup (bezl) {
      bezl.vars.filterString = "";

      // Load the object for the selected customer from local storage into
      // a variable we can work with
      if (typeof(Storage) !== "undefined" && localStorage.getItem("selectedAccount")) {
          bezl.vars.selectedAccount = JSON.parse(localStorage.getItem("selectedAccount"));

          // Perform additional processing on the returned data
          for (var i = 0; i < bezl.vars.selectedAccount.CRMCalls.length; i++) {
            bezl.vars.selectedAccount.CRMCalls[i].show = true;
          }
      }

      // Refresh all call data at regular interval
      account.runQuery(bezl, "AllCRMCalls");

      // Also pull in the list of defined CRM call types.  This is expecting a plugin instance
      // to be defined in BRDB named sales-rep-calltypes which points to a data source for call
      // types
      bezl.dataService.add('CallTypes','brdb','sales-rep-queries','ExecuteQuery', { "QueryName": "GetCallTypes" },0);

      $(".panel").on("selectAccount", function(event, param1) {
        bezl.vars.selectedAccount = param1;
        bezl.vars.loadedMore = false;

        // Load up the CRM calls for this newly selected account
        if (bezl.data.AllCRMCalls) {
            bezl.vars.selectedAccount.CRMCalls = [];
            for (var i = 0; i < bezl.data.AllCRMCalls.length; i++) {
                if (bezl.data.AllCRMCalls[i].ID == bezl.vars.selectedAccount.ID) {
                    bezl.vars.selectedAccount.CRMCalls.push(bezl.data.AllCRMCalls[i])
                }
            }
        }

        // If there are no CRM calls present with what was passed over, go
        // ahead and run the full query now
        if (!bezl.vars.selectedAccount.CRMCalls) {
          account.runQuery(bezl, "CRMCalls");
        } else {
          // Perform additional processing on the returned data
          for (var i = 0; i < bezl.vars.selectedAccount.CRMCalls.length; i++) {
            bezl.vars.selectedAccount.CRMCalls[i].show = true;
          }
        }

        $(bezl.container.nativeElement).find('#filterString')[0].value = ""; // Clear out the search filter box

      });

      // Prepopulate the CRM new interaction form for click to call/email/navigate
      // Should pass data in param1 in the form of:
      // {
      //   "type": <enum: "phone", "email", "navigate">,
      //   "shortSummary": <string>,
      //   "details": <string>
      // }
      $(".panel").on("CRMNewInteraction", function(event, param1) {
        // TODO: look up an appropriate type from the CallTypes list
        // This should eventually be a config option to select the local
        // CallType to be used for phone/email/navigate. For now we will use
        // some much less useful default strings.
        switch (param1.type) {
            case "phone":
                bezl.vars.type = "Sales";
                break;
            case "email":
                bezl.vars.type = "Email";
                break;
            case "navigate":
                bezl.vars.type = "Customer Visit";
                break;
        }

        bezl.vars.shortSummary = param1.shortSummary;
        bezl.vars.details = param1.details;
      });
  }

  return {
    onStartup: OnStartup
  }
});
<|endoftext|>


<commit_before>// Copyright (c) 2017 Markus Laire
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
// SOFTWARE.

'use strict';

const OUTPUT_SNIPPET_LIMIT = 12;
const TRIM_LIMIT_UA        = 500;

// ------=========---------------
function GetOutput(data, limit) {
// ------=========---------------
  var data_start_time = data[0][0];

  var text = '';

  var sum_count = 0;

  var ms_first;
  var uA_min, uA_max, uA_sum, uA_avg;
  var mV_min, mV_max, mV_sum, mV_avg;
  var nW_min, nW_max, nW_sum, nW_avg;

  var uA_div      = Number($('input[name=current-divisor]:checked').val());
  var mV_div      = Number($('input[name=voltage-divisor]:checked').val());
  var nW_div      = Number($('input[name=power-divisor]:checked').val());
  var avg_count   = parseInt($('input[name=group-size]:checked').val());
  var time_format = $('#time-format').val();

  var include_time        = (time_format !== '');

  var include_current     = ! isNaN(uA_div) && (avg_count == 1);
  var include_voltage     = ! isNaN(mV_div) && (avg_count == 1);
  var include_power       = ! isNaN(nW_div) && (avg_count == 1);

  var include_current_min = ! isNaN(uA_div) && (avg_count > 1) && $('#current-min').prop('checked');
  var include_current_avg = ! isNaN(uA_div) && (avg_count > 1) && $('#current-avg').prop('checked');
  var include_current_max = ! isNaN(uA_div) && (avg_count > 1) && $('#current-max').prop('checked');

  var include_voltage_min = ! isNaN(mV_div) && (avg_count > 1) && $('#voltage-min').prop('checked');
  var include_voltage_avg = ! isNaN(mV_div) && (avg_count > 1) && $('#voltage-avg').prop('checked');
  var include_voltage_max = ! isNaN(mV_div) && (avg_count > 1) && $('#voltage-max').prop('checked');

  var include_power_min   = ! isNaN(nW_div) && (avg_count > 1) && $('#power-min').prop('checked');
  var include_power_avg   = ! isNaN(nW_div) && (avg_count > 1) && $('#power-avg').prop('checked');
  var include_power_max   = ! isNaN(nW_div) && (avg_count > 1) && $('#power-max').prop('checked');

  var current_unit = $('input[name=current-divisor]:checked').attr('data-unit');
  var voltage_unit = $('input[name=voltage-divisor]:checked').attr('data-unit');
  var power_unit   = $('input[name=power-divisor]:checked').attr('data-unit');

  var output_lines = 0;

  if ($('#column-labels').prop('checked')) {
    var row = [];

    if (include_time       ) row.push('time');

    if (include_current    ) row.push(current_unit);
    if (include_current_min) row.push(current_unit + ' min');
    if (include_current_avg) row.push(current_unit + ' avg');
    if (include_current_max) row.push(current_unit + ' max');

    if (include_voltage    ) row.push(voltage_unit);
    if (include_voltage_min) row.push(voltage_unit + ' min');
    if (include_voltage_avg) row.push(voltage_unit + ' avg');
    if (include_voltage_max) row.push(voltage_unit + ' max');

    if (include_power      ) row.push(power_unit);
    if (include_power_min  ) row.push(power_unit   + ' min');
    if (include_power_avg  ) row.push(power_unit   + ' avg');
    if (include_power_max  ) row.push(power_unit   + ' max');

    text += row.join(',') + "\n";
  }

  var skipped_some = false;
  data.forEach(function (values, index) {
    if (output_lines >= limit) {
      skipped_some = true;
      return;
    }

    var ms = values[0];
    var uA = values[1];
    var mV = values[2];
    var nW = uA * mV;

    if (avg_count > 1) {
      if (sum_count == 0) {
        ms_first = ms;
        uA_min   = 1e15;
        uA_max   = -1e15;
        uA_sum   = 0;
        mV_min   = 1e15;
        mV_max   = -1e15;
        mV_sum   = 0
        nW_min   = 1e15;
        nW_max   = -1e15;
        nW_sum   = 0
      }

      sum_count++;
      uA_sum += uA;
      mV_sum += mV;
      nW_sum += nW;

      if (uA < uA_min) uA_min = uA;
      if (uA > uA_max) uA_max = uA;
      if (mV < mV_min) mV_min = mV;
      if (mV > mV_max) mV_max = mV;
      if (nW < nW_min) nW_min = nW;
      if (nW > nW_max) nW_max = nW;

      if (sum_count < avg_count &&
          ! (index + 1 == data.length &&
             $('#include-last-partial').prop('checked'))) return;

      ms = ms_first;
      uA_avg = uA_sum / sum_count;
      mV_avg = mV_sum / sum_count;
      nW_avg = nW_sum / sum_count;

      sum_count = 0;
    }

    output_lines++;

    var time
    if ($('#time-from-zero').prop('checked')) {
      ms = ms - data_start_time;
      time = (new moment.utc(ms, 'x')).format(time_format);
    } else {
      time = (new moment(ms, 'x')).format(time_format);
    }

    var row = [];

    if (include_time       ) row.push(time);

    if (include_current    ) row.push(uA     / uA_div);
    if (include_current_min) row.push(uA_min / uA_div);
    if (include_current_avg) row.push(uA_avg / uA_div);
    if (include_current_max) row.push(uA_max / uA_div);

    if (include_voltage    ) row.push(mV     / mV_div);
    if (include_voltage_min) row.push(mV_min / mV_div);
    if (include_voltage_avg) row.push(mV_avg / mV_div);
    if (include_voltage_max) row.push(mV_max / mV_div);

    if (include_power      ) row.push(nW     / nW_div);
    if (include_power_min  ) row.push(nW_min / nW_div);
    if (include_power_avg  ) row.push(nW_avg / nW_div);
    if (include_power_max  ) row.push(nW_max / nW_div);

    text += row.join(',') + "\n";
  });

  if (skipped_some) text += "...\n";

  return text;
}

// ------==========----
function ParseInput() {
// ------==========----
  var data = [];

  var trimming_beginning = $('#trim-begin').prop('checked');

  var lines = $('#input').val().replace(' ', '').split(/\r\n|\r|\n/g);
  lines.forEach(function (line) {
    if (line === '') return;

    var values = line.split(',');
    var ms = parseInt(values[0]);
    var uA = parseInt(values[1]);
    var mV = parseInt(values[2]);

    if (trimming_beginning) {
      if (uA <= TRIM_LIMIT_UA) return;
      trimming_beginning = false;
    }

    data.push([ ms, uA, mV ]);
  });

  return data;
}

// ------==============----
function ShowFullOutput() {
// ------==============----
  var data = ParseInput();
  var text = GetOutput(data);
  $('#output-snippet').val(text);
}

// ------===================----
function UpdateOutputSnippet() {
// ------===================----
  var data = ParseInput();
  var text = GetOutput(data, OUTPUT_SNIPPET_LIMIT);
  $('#output-snippet').val(text);
}
<commit_msg>refactoring: separate data grouping from output generation<commit_after>// Copyright (c) 2017 Markus Laire
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
// SOFTWARE.

'use strict';

const OUTPUT_SNIPPET_LIMIT = 12;
const TRIM_LIMIT_UA        = 500;

// ------=========----------------
function GetOutput(data_grouped) {
// ------=========----------------
  var data_start_time = (data_grouped.length == 0) ? NaN : data_grouped[0].ms_min;

  var text = '';

  var uA_div      = Number($('input[name=current-divisor]:checked').val());
  var mV_div      = Number($('input[name=voltage-divisor]:checked').val());
  var nW_div      = Number($('input[name=power-divisor]:checked').val());
  var is_grouped  = (parseInt($('input[name=group-size]:checked').val()) > 1);
  var time_format = $('#time-format').val();

  // CONVENTION: when not grouped, output 'minimum' value if any

  var include_time        = (time_format !== '');

  var include_current_min = ! isNaN(uA_div) && (! is_grouped || $('#current-min').prop('checked'));
  var include_current_avg = ! isNaN(uA_div) &&    is_grouped && $('#current-avg').prop('checked');
  var include_current_max = ! isNaN(uA_div) &&    is_grouped && $('#current-max').prop('checked');

  var include_voltage_min = ! isNaN(mV_div) && (! is_grouped || $('#voltage-min').prop('checked'));
  var include_voltage_avg = ! isNaN(mV_div) &&    is_grouped && $('#voltage-avg').prop('checked');
  var include_voltage_max = ! isNaN(mV_div) &&    is_grouped && $('#voltage-max').prop('checked');

  var include_power_min   = ! isNaN(nW_div) && (! is_grouped || $('#power-min').prop('checked'));
  var include_power_avg   = ! isNaN(nW_div) &&    is_grouped && $('#power-avg').prop('checked');
  var include_power_max   = ! isNaN(nW_div) &&    is_grouped && $('#power-max').prop('checked');

  var current_unit = $('input[name=current-divisor]:checked').attr('data-unit');
  var voltage_unit = $('input[name=voltage-divisor]:checked').attr('data-unit');
  var power_unit   = $('input[name=power-divisor]:checked').attr('data-unit');

  if ($('#column-labels').prop('checked')) {
    var row = [];

    if (include_time       ) row.push('time');

    if (include_current_min) row.push(current_unit + (is_grouped ? ' min' : ''));
    if (include_current_avg) row.push(current_unit + ' avg');
    if (include_current_max) row.push(current_unit + ' max');

    if (include_voltage_min) row.push(voltage_unit + (is_grouped ? ' min' : ''));
    if (include_voltage_avg) row.push(voltage_unit + ' avg');
    if (include_voltage_max) row.push(voltage_unit + ' max');

    if (include_power_min  ) row.push(power_unit   + (is_grouped ? ' min' : ''));
    if (include_power_avg  ) row.push(power_unit   + ' avg');
    if (include_power_max  ) row.push(power_unit   + ' max');

    text += row.join(',') + "\n";
  }

  data_grouped.forEach(function (input) {
    var {count, ms_min,
         uA_min, uA_max, uA_sum,
         mV_min, mV_max, mV_sum,
         nW_min, nW_max, nW_sum} = input;

    var time;
    if ($('#time-from-zero').prop('checked')) {
      ms_min -= data_start_time;
      time = (new moment.utc(ms_min, 'x')).format(time_format);
    } else {
      time = (new moment(ms_min, 'x')).format(time_format);
    }

    var row = [];

    if (include_time       ) row.push(time);

    if (include_current_min) row.push(uA_min / uA_div);
    if (include_current_avg) row.push(uA_sum / count / uA_div);
    if (include_current_max) row.push(uA_max / uA_div);

    if (include_voltage_min) row.push(mV_min / mV_div);
    if (include_voltage_avg) row.push(mV_sum / count / mV_div);
    if (include_voltage_max) row.push(mV_max / mV_div);

    if (include_power_min  ) row.push(nW_min / nW_div);
    if (include_power_avg  ) row.push(nW_sum / count / nW_div);
    if (include_power_max  ) row.push(nW_max / nW_div);

    text += row.join(',') + "\n";
  });

  return text;
}

// ------=========---------------------------
function GroupData(data_parsed, limit = -1) {
// ------=========---------------------------
  var data_grouped = [];
  var group_size = parseInt($('input[name=group-size]:checked').val());

  var count = 0;
  var ms_min;
  var uA_min, uA_max, uA_sum;
  var mV_min, mV_max, mV_sum;
  var nW_min, nW_max, nW_sum;

  for (var index = 0; index < data_parsed.length; index++) {
    var [ms, uA, mV] = data_parsed[index];
    var nW = uA * mV;

    if (count == 0) {
      ms_min = ms;
      uA_min = uA_max = uA_sum = uA;
      mV_min = mV_max = mV_sum = mV;
      nW_min = nW_max = nW_sum = nW;
    } else {
      uA_sum += uA;
      mV_sum += mV;
      nW_sum += nW;

      if (uA < uA_min) uA_min = uA;
      if (uA > uA_max) uA_max = uA;
      if (mV < mV_min) mV_min = mV;
      if (mV > mV_max) mV_max = mV;
      if (nW < nW_min) nW_min = nW;
      if (nW > nW_max) nW_max = nW;
    }
    count++;

    if (count == group_size) {
      data_grouped.push({
        'count' : count,
        'ms_min': ms_min,
        'uA_min': uA_min, 'uA_max': uA_max, 'uA_sum': uA_sum,
        'mV_min': mV_min, 'mV_max': mV_max, 'mV_sum': mV_sum,
        'nW_min': nW_min, 'nW_max': nW_max, 'nW_sum': nW_sum,
      });
      count = 0;
      if (data_grouped.length == limit) break;
    }
  };

  if (count > 0) {
    data_grouped.push({
      'count' : count,
      'ms_min': ms_min,
      'uA_min': uA_min, 'uA_max': uA_max, 'uA_sum': uA_sum,
      'mV_min': mV_min, 'mV_max': mV_max, 'mV_sum': mV_sum,
      'nW_min': nW_min, 'nW_max': nW_max, 'nW_sum': nW_sum,
    });
  }

  // possibly exclude last
  if (! $('#include-last-partial').prop('checked')
      && data_grouped.slice(-1)[0].count < group_size) {
    data_grouped.pop();
  }

  return data_grouped;
}

// ------==========----
function ParseInput() {
// ------==========----
  var data_parsed = [];

  var trimming_beginning = $('#trim-begin').prop('checked');

  var lines = $('#input').val().replace(' ', '').split(/\r\n|\r|\n/g);
  lines.forEach(function (line) {
    if (line === '') return;

    var values = line.split(',');
    var ms = parseInt(values[0]);
    var uA = parseInt(values[1]);
    var mV = parseInt(values[2]);

    if (trimming_beginning) {
      if (uA <= TRIM_LIMIT_UA) return;
      trimming_beginning = false;
    }

    data_parsed.push([ ms, uA, mV ]);
  });

  return data_parsed;
}

// ------==============----
function ShowFullOutput() {
// ------==============----
  var data_grouped = GroupData(ParseInput());
  $('#output-snippet').val(GetOutput(data_grouped));
}

// ------===================----
function UpdateOutputSnippet() {
// ------===================----
  var data_grouped = GroupData(ParseInput(), OUTPUT_SNIPPET_LIMIT);
  $('#output-snippet').val(GetOutput(data_grouped) + "...\n");
}
<|endoftext|>


<commit_before>// @flow

import Store from './Store';

export const ElementTypeClassOrFunction = 1;
export const ElementTypeContext = 2;
export const ElementTypeForwardRef = 3;
export const ElementTypeMemo = 4;
export const ElementTypeOtherOrUnknown = 5;
export const ElementTypeProfiler = 6;
export const ElementTypeRoot = 7;
export const ElementTypeSuspense = 8;

export type ElementType = 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8;

// TODO: Add profiling node

export type Element = {|
  children: Array<number>,
  depth: number,
  displayName: string | null,
  id: number,
  key: number | string | null,
  parentID: number,
  type: ElementType,
  weight: number,
|};

export type InspectedElement = {|
  id: number,
  context: Object | null,
  hooks: Object | null,
  props: Object | null,
  state: Object | null,
  canEditProps: boolean,
  source: Object,
|};

export type TreeMetadataType = {|
  size: number,
  store: Store,
|};
<commit_msg>Added inline comments for types<commit_after>// @flow

import Store from './Store';

export const ElementTypeClassOrFunction = 1;
export const ElementTypeContext = 2;
export const ElementTypeForwardRef = 3;
export const ElementTypeMemo = 4;
export const ElementTypeOtherOrUnknown = 5;
export const ElementTypeProfiler = 6;
export const ElementTypeRoot = 7;
export const ElementTypeSuspense = 8;

// Different types of elements displayed in the Elements tree.
// These types may be used to visually distinguish types,
// or to enable/disable certain functionality.
export type ElementType = 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8;

// Each element on the frontend corresponds to a Fiber on the backend.
// Some of its information (e.g. id, type, displayName) come from the backend.
// Other bits (e.g. weight and depth) are computed on the frontend for windowing and display purposes.
// Elements are udpated on a push basis– meaning the backend pushes updates to the frontend when needed.
export type Element = {|
  id: number,
  parentID: number,
  children: Array<number>,
  type: ElementType,
  displayName: string | null,
  key: number | string | null,

  // How many levels deep within the tree is this element?
  // This determines how much indentation (left padding) should be used in the Elements tree.
  depth: number,

  // How many nodes (including itself) are below this Element within the tree.
  // This property is used to quickly determine the total number of Elements,
  // and the Element at any given index (for windowing purposes).
  weight: number,
|};

export type InspectedElement = {|
  id: number,

  // Does the current renderer support editable props/state/hooks?
  canEditValues: boolean,

  // Inspectable properties.
  context: Object | null,
  hooks: Object | null,
  props: Object | null,
  state: Object | null,

  // List of owners
  owners: Array<number>,

  // Location of component in source coude.
  source: Object,
|};

// TODO: Add profiling type

// The frontend Store is mutable.
// This wrapper object is recreated whenever the store's tree is mutated.
// It is used to trigger a re-render of the virtualized Elements tree.
export type TreeMetadataType = {|
  size: number,
  store: Store,
|};
<|endoftext|>


<commit_before>/**
 * Unit-On v0.2.2
 * @author Dark Heart aka PretorDH
 * @site uniton.deparadox.com
 * MIT license
 */

(function(o){
(Unit = function (o) {
	this.U = o;
	this.unitLoad = function (h,c) {
		var Su=Unit.U[h];
		if (Su.loaded) return;
		if (Su.loaded===false && typeof c=='function') {
			var a=Su.onload;
			return Su.onload = function (){a && a();c && c()};
		};
		Su.onload = c;
		if (Su.css) Unit.cssLoad(Su,(Su.jss)?null:Su.onload);
		if (Su.jss) Unit.jssLoad(Su);
		Su.loaded = false;
	};
	this.cssLoad = function (Su,c) {
		var a,f=document.createElement("link");
		(a=f.setAttribute)("rel", "stylesheet");
		a("type", "text/css");
		a("onload", function(){Su.onload && Su.onload()});
		a("href", Su['css']);
		(typeof f != "undefined") && document.getElementsByTagName("head")[0].appendChild(f) && console.log('Load:'+h['css']);
	};
	this.jssLoad = function (Su) {
		var callback = function(e){if (Su.loaded) return; console.log('Load: '+Su['jss']); Su.onload && Su.onload(); Su.onload=Su.onreadystatechange=null; Su.loaded=true};
/*		$.getScript(Su['jss'],callback); */
		var script = document.createElement('script');
		script.setAttribute('src', Su['jss']);
		script.onreadystatechange = script.onload = callback;
		document.getElementsByTagName('head')[0].appendChild(script);
	}

	for(var h in this.U) {
		var nfn = this.U[h].fn;
		if (nfn == 'NOW') this.unitLoad(h,this.U[h].onload);
		if (nfn == 'ONLOAD')
			(function(h){
				$(function(){Unit.unitLoad(h,Unit.U[h].onload);});
			})(h);
		if (typeof nfn == 'string')
			(function(nfn,h){
				window[nfn] = function(){
					var self=this, ar=arguments;
					Unit.unitLoad(h,function(){window[nfn].apply(self,ar) });
				};
			})(nfn,h);
	};
	return o;
}).call(Unit,o);
})

({  'dragon':{jss:'http://dragon.deparadox.com/drag-on.js', fn:'NOW'},
    'baron':{jss:'http://dragon.deparadox.com/bar-on.js', fn:'ONLOAD'}      });
<commit_msg>Unit-on: new version 0.2.4<commit_after>/**
 * Unit-On v0.2.3
 * @author Dark Heart aka PretorDH
 * @site uniton.deparadox.com
 * MIT license
 */

(function(o){
(Unit = function (o) {
	this.U = o;
	this.unitLoad = function (h,c) {
		var Su=Unit.U[h];
		if (Su.loaded || !!document.getElementById(h)) return console.log('Unit.Bypass '+h);
		if (Su.loaded===false && typeof c=='function') {
			var a=Su.onload;
			return Su.onload = function (){a && a();c && c()};
		};
		Su.onload = c;
		if (Su.css) Unit.cssLoad(Su,(Su.jss)?null:Su.onload);
		if (Su.jss) Unit.jssLoad(Su);
		Su.loaded = false;
	};
	this.cssLoad = function (Su,c) {
		var a,f=document.createElement("link");
		(a=f.setAttribute)("rel", "stylesheet");
		a("type", "text/css");
		a("onload", function(){Su.onload && Su.onload()});
		a("href", Su['css']);
		(typeof f != "undefined") && document.getElementsByTagName("head")[0].appendChild(f) && console.log('Load:'+h['css']);
	};
	this.jssLoad = function (Su) {
		var callback = function(e){if (Su.loaded) return; console.log('Load: '+Su['jss']); Su.onload && Su.onload(); Su.onload=Su.onreadystatechange=null; Su.loaded=true};
		var script = document.createElement('script');
		script.setAttribute('src', Su['jss']);
		script.onreadystatechange = script.onload = callback;
		document.getElementsByTagName('head')[0].appendChild(script);
	}

	for(var h in this.U) {
		var nfn = this.U[h].fn;
		if (nfn == 'NOW') this.unitLoad(h,this.U[h].onload);
		else if (nfn == 'ONLOAD')
			(function(h){
				$(function(){Unit.unitLoad(h,Unit.U[h].onload);});
			})(h);
		else if (typeof nfn == 'string')
			(function(nfn,h){
				window[nfn] = function(){
					var self=this, ar=arguments;
					Unit.unitLoad(h,function(){window[nfn].apply(self,ar) });
				};
			})(nfn,h);
	};
	return o;
}).call(Unit,o);
})

({  'dragon':{jss:'http://dragon.deparadox.com/drag-on.js', fn:'NOW'},
    'baron':{jss:'http://dragon.deparadox.com/bar-on.js', fn:'ONLOAD'}      });
<|endoftext|>


<commit_before>'use strict';

module.exports = {
  prop: function (property) {
    var negate;
    if (/^!/.test(property)) {
      negate = true;
      property = property.slice(1);
    }
    return function ($el, value, previousValue) {
      $el = $($el);

      $el.prop(property, negate && !value || !negate && !!value);
    };
  },

  booleanClass: function (setClass, unsetClass) {
    return function ($el, value, previousValue) {
      $el = $($el);

      $el.toggleClass(setClass, !!value).toggleClass(unsetClass, !value);
    };
  },

  html: function ($el, value, previousValue) {
    $el = $($el);

    $el.html(value);

    $el.trigger('change', { internal: true });
  },

  text: function ($el, value, previousValue) {
    $el = $($el);

    $el.text(value);

    $el.trigger('change', { internal: true });
  },

  value: function ($el, value, previousValue) {
    $el = $($el);

    if ($el[0].type === 'radio' || $el[0].type === 'checkbox') {
      if ($el.length === 1) {
        $el.prop('checked', !!value);
      } else {
        $el.prop('checked', false);

        if (value)
          $el.filter((_.isArray(value) ? value : [ value ]).map(function (value) {
            return '[value="' + value + '"]';
          }).join(',')).prop('checked', true);
      }
    } else {
      if (value != null) value = value.toString();

      $el.val(value);
    }

    $el.trigger('change', { internal: true });
  },

  published: function ($el, value) {
    $el = $($el);

    $el = $el.closest('[data-published]');

    $el.attr('data-published', (!!value).toString());
  },

  parts: function ($el, value) {
    $el = $($el);

    if (!_.isDate(value)) value = new Date(value);

    var ref = value.toLocaleString('se-SV').split(' ');

    $el.find('[data-part]').toArray().forEach(function (part, index) {
      $(part).val(ref[index]);
    });
  },

  src: function ($el, value) {
    $el = $($el);

    $el.attr('src', value);
  },

  selectMultiple: function ($el, value) {
    $el = $($el);

    if (!value) $el.val(null);

    else
      value.forEach(function (value) {
        $el.find('[value="' + value + '"]').prop('selected', true);
      });
  }
};
<commit_msg>Smarter value setter.<commit_after>'use strict';

module.exports = {
  prop: function (property) {
    var negate;
    if (/^!/.test(property)) {
      negate = true;
      property = property.slice(1);
    }
    return function ($el, value, previousValue) {
      $el = $($el);

      $el.prop(property, negate && !value || !negate && !!value);
    };
  },

  booleanClass: function (setClass, unsetClass) {
    return function ($el, value, previousValue) {
      $el = $($el);

      $el.toggleClass(setClass, !!value).toggleClass(unsetClass, !value);
    };
  },

  html: function ($el, value, previousValue) {
    $el = $($el);

    $el.html(value);

    $el.trigger('change', { internal: true });
  },

  text: function ($el, value, previousValue) {
    $el = $($el);

    $el.text(value);

    $el.trigger('change', { internal: true });
  },

  value: function (el, value, previousValue) {
    if (el.type === 'radio' || el.type === 'checkbox') {
      if (el.name && el.form)
        el = el.form[el.name];

      if ('length' in el) {
        $(el).prop('checked', false);

        if (value != null)
          _.each(el, function (el) {
            if (_.isArray(value) && value.indexOf(el.value) > -1 || el.value === value)
              el.checked = true;
          });
      } else {
        el.checked = !!value;
      }
    } else {
      if (value != null) value = value.toString();

      $(el).val(value);
    }

    $(el).trigger('change', { internal: true });
  },

  published: function ($el, value) {
    $el = $($el);

    $el = $el.closest('[data-published]');

    $el.attr('data-published', (!!value).toString());
  },

  parts: function ($el, value) {
    $el = $($el);

    if (!_.isDate(value)) value = new Date(value);

    var ref = value.toLocaleString('se-SV').split(' ');

    $el.find('[data-part]').toArray().forEach(function (part, index) {
      $(part).val(ref[index]);
    });
  },

  src: function ($el, value) {
    $el = $($el);

    $el.attr('src', value);
  },

  selectMultiple: function ($el, value) {
    $el = $($el);

    if (!value) $el.val(null);

    else
      value.forEach(function (value) {
        $el.find('[value="' + value + '"]').prop('selected', true);
      });
  }
};
<|endoftext|>


<commit_before>//     Amethyst.js 1.0
//     http://amethyst.io
//     (c) 2014 Jonathan James, Writebot
//     Amethyst may be freely distributed under the MIT license.

(function () {

  // Setup
  // -----
  // Establish the root object, `window` in the browser, or `exports` on the server.
  var root = this;

  // Create the A object for use below.
  var A = {};

  // Export the A object correctly for client and server use.
  // If Node.js -- export with backwards-compatibility for the old `require()` API.
  // If other (browser, etc.), add `A` to root as a global object.
  if (typeof exports !== 'undefined') {
    if (typeof module !== 'undefined' && module.exports) {
      exports = module.exports = A;
    }
    exports.A = A;
  } else {
    root.A = A;
  }

  // Utility functions for library.
  // ------------------------------
  var isObject = function (x) {
    return Object.prototype.toString.call(x) === '[object Object]';
  };

  var isArray = function (x) {
    return Object.prototype.toString.call(x) === '[object Array]';
  };

  var isFunction = function (x) {
    return typeof x === 'function';
  };

  var canUseConsoleLog = function () {
    return typeof console !== 'undefined' && console.log;
  };

  // Subjects Module
  // ---------------
  // Amethyst components are comprised of subjects.
  // They are abstractions of commonly used functionality -- specialized constructors that
  // load functionality into a component or decorate existing functionality.
  var subjects = (function () {

    // Scalars.
    // --------
    // All subjects are stored in _store so we can load them into components later.
    var _store = {};

    // Save and load hooks allow us to use reflection easily.
    var saveHooks = { before: [], after: [] }
    , loadHooks = { before: [], after: [] };

    // Utility functions for subjects.
    // -------------------------------
    var subjectHasName = function (x) {
      return x.name !== null;
    };

    var isInStore = function (name) {
      return typeof _store[name] !== "undefined";
    };

    var thereAreBeforeSaveHooks = function () {
      return !!saveHooks.before.length;
    };

    var thereAreAfterSaveHooks = function () {
      return !!saveHooks.after.length;
    };

    var saveSubject = function (name, options) {
      _store[name] = options;
    };

    // The method to save subjects in _store.
    // --------------------------------------
    var save = function (/* list of subject objects with name and options */) {

      // Iterate through a list of subjects passed as arguments.
      // If they validate, add them to _store.
      for (var i = arguments.length - 1; i >= 0; i--) {
        var name, options = {};

        // Validate and assign name.
        if (arguments[i].name == null) throw new Error("Subject " + i + " has no name.");
        name = arguments[i].name;

        // Validate and assign options.
        if (!isObject(arguments[i].options))
          throw new Error("Subject " + i + " options must be an object.");
        options = arguments[i].options;

        // Check for existing subjects by the same name.
        if (isInStore(name)) throw new Error("A subject named " +
          name + " already exists. Please give your subjects unique names.");

        // Run before hooks for save.
        if (thereAreBeforeSaveHooks()) {
          for (var i = saveHooks.before.length - 1; i >= 0; i--) {
            saveHooks.before[i](name, options);
          };
        }

        // Save the subject.
        saveSubject(name, options);

        // Run after hooks for save.
        if (thereAreAfterSaveHooks()) {
          for (var i = saveHooks.after.length - 1; i >= 0; i--) {
            saveHooks.after[i](name, options);
          };
        }

      };
    };

    // The method to load subjects into a parent using an explicit "subjects" property.
    // --------------------------------------------------------------------------------
    var _loadDeps = function (context, subjects) {
      if (!isObject(subjects))
        throw new Error("Subjects " + subjects +
          " to be loaded into a parent must be an object!");

      // Call _load recursively for each subject.
      var args;
      for (key in subjects) {
        if (!subjects.hasOwnProperty(key)) continue;

        if (isArray(subjects[key])) {
          args = [key, subjects[key]];
        } else {
          args = [key, [subjects[key]]];
        }

        // Name and value.
        _load.apply(context, [args]);

      };
    }

    // The method to load subjects into a component.
    // ---------------------------------------------
    var _load = function (/* list of subjects in string or array form */) {
      var subject = {}
      , name = ''
      , argsArray = []
      , loadedResults = []
      , error = function (name) {
          throw new Error("Subject " + name + " not found.");
      };

      // console.log("LOADING SUBJECT", arguments);

      // Loop through all given subjects and load them into the component.
      for (var i = arguments.length - 1; i >= 0; i--) {

        // console.log("LOADING ARGUMENT", i, arguments[i]);

        // Arguments can either be an array or string.
        // An array with two items will have [subjectName, [subjectConstructorArguments]].
        if (isArray(arguments[i])) {
          name = arguments[i][0];

          // Get this subject from `_store` if it exists.
          if (!isInStore(name)) error(name);
          subject = _store[name];

          // Check if we're loading other subjects into this subject. Load them first.
          if (subject.subjects) {
            _loadDeps(this, subject.subjects);
          }

          // Apply argsArray to `loaded` method.
          if (arguments[i].length > 1) argsArray = arguments[i][1];
          if (subject.loaded && isFunction(subject.loaded)) {
            loadedResults.push( subject.loaded.apply(this, argsArray) );
          }

        // Do as above, but for string subject name (without an args array).
        } else if (typeof arguments[i] === 'string') {
          name = arguments[i];
          if (!isInStore(name)) error(name);
          subject = _store[name];
          if (subject.subjects) {
            _loadDeps(this, subject.subjects);
          }
          if (subject.loaded && isFunction(subject.loaded)) {
            loadedResults.push( subject.loaded.call(this) );
          }
        }

        // Add the subject's API to the component. APIs are optional but safe.
        if (subject.api) {
          if (isFunction(subject.api)) {

            this[name] = subject.api.bind(this); // If subjects.api is a function.

          } else {

            var val
            , boundAPI = {};

            for (key in subject.api) { // TODO: make recursive?
              if (!subject.api.hasOwnProperty(key)) continue;
              val = subject.api[key];
              boundAPI[key] = isFunction(val) ? val.bind(this) : val;
            }
            this[name] = boundAPI; // APIs are namespaced by subject when loaded.
          };
        }
      } // End for arguments.

      return loadedResults;

    };

    var load = function (/* context, subject names...*/) {
      var s = Array.prototype.slice.call(arguments, 1);
      _load.apply(arguments[0], s);
    };

    // Run a subject's unloaded() function in a given context
    var unload = function (/* context, subject name */) {
      var s = Array.prototype.slice.call(arguments, 1);
      if (!isInStore(s)) throw new Error("Subject " + s + " not found.");
      if (_store[s].unloaded && isFunction(_store[s].unloaded))
        _store[s].unloaded.call(arguments[0]);
    };

    var view = function () {
      if (canUseConsoleLog()) console.log(_store);
    };

    // Subjects API
    // ------------
    return {
      before: {
        save: function (func) {
          if (!isFunction(func)) throw new Error("Hooks must be functions!");
          saveHooks.before.push(func);
        }
      },
      after: {
        save: function (func) {
          if (!isFunction(func)) throw new Error("Hooks must be functions!");
          saveHooks.after.push(func);
        }
      },
      save: save,
      load: load,
      unload: unload,
      view: view
    };

  }());

  // Add subjects module to A!
  A.subjects = subjects;

}).call(this);
<commit_msg>Clean up<commit_after>//     Amethyst.js 1.0
//     http://amethyst.io
//     (c) 2014 Jonathan James
//     Amethyst may be freely distributed under the MIT license.

(function () {

  // Setup
  // -----
  // Establish the root object, `window` in the browser, or `exports` on the server.
  var root = this;

  // Create the A object for use below.
  var A = {};

  // Export the A object correctly for client and server use.
  // If Node.js -- export with backwards-compatibility for the old `require()` API.
  // If other (browser, etc.), add `A` to root as a global object.
  if (typeof exports !== 'undefined') {
    if (typeof module !== 'undefined' && module.exports) {
      exports = module.exports = A;
    }
    exports.A = A;
  } else {
    root.A = A;
  }

  // Utility functions for library.
  // ------------------------------
  var isObject = function (x) {
    return Object.prototype.toString.call(x) === '[object Object]';
  };

  var isArray = function (x) {
    return Object.prototype.toString.call(x) === '[object Array]';
  };

  var isFunction = function (x) {
    return typeof x === 'function';
  };

  var canUseConsoleLog = function () {
    return typeof console !== 'undefined' && console.log;
  };

  // Subjects Module
  // ---------------
  // Amethyst components are comprised of subjects.
  // They are abstractions of commonly used functionality -- specialized constructors that
  // load functionality into a component or decorate existing functionality.
  var subjects = (function () {

    // Scalars.
    // --------
    // All subjects are stored in _store so we can load them into components later.
    var _store = {};

    // Save and load hooks allow us to use reflection easily.
    var saveHooks = { before: [], after: [] }
    , loadHooks = { before: [], after: [] };

    // Utility functions for subjects.
    // -------------------------------
    var subjectHasName = function (x) {
      return x.name !== null;
    };

    var isInStore = function (name) {
      return typeof _store[name] !== "undefined";
    };

    var thereAreBeforeSaveHooks = function () {
      return !!saveHooks.before.length;
    };

    var thereAreAfterSaveHooks = function () {
      return !!saveHooks.after.length;
    };

    var saveSubject = function (name, options) {
      _store[name] = options;
    };

    // The method to save subjects in _store.
    // --------------------------------------
    var save = function (/* list of subject objects with name and options */) {

      // Iterate through a list of subjects passed as arguments.
      // If they validate, add them to _store.
      for (var i = arguments.length - 1; i >= 0; i--) {
        var name, options = {};

        // Validate and assign name.
        if (arguments[i].name == null) throw new Error("Subject " + i + " has no name.");
        name = arguments[i].name;

        // Validate and assign options.
        if (!isObject(arguments[i].options))
          throw new Error("Subject " + i + " options must be an object.");
        options = arguments[i].options;

        // Check for existing subjects by the same name.
        if (isInStore(name)) throw new Error("A subject named " +
          name + " already exists. Please give your subjects unique names.");

        // Run before hooks for save.
        if (thereAreBeforeSaveHooks()) {
          for (var i = saveHooks.before.length - 1; i >= 0; i--) {
            saveHooks.before[i](name, options);
          };
        }

        // Save the subject.
        saveSubject(name, options);

        // Run after hooks for save.
        if (thereAreAfterSaveHooks()) {
          for (var i = saveHooks.after.length - 1; i >= 0; i--) {
            saveHooks.after[i](name, options);
          };
        }

      };
    };

    // The method to load subjects into a parent using an explicit "subjects" property.
    // --------------------------------------------------------------------------------
    var _loadDeps = function (context, subjects) {
      if (!isObject(subjects))
        throw new Error("Subjects " + subjects +
          " to be loaded into a parent must be an object!");

      // Call _load recursively for each subject.
      var args;
      for (key in subjects) {
        if (!subjects.hasOwnProperty(key)) continue;

        if (isArray(subjects[key])) {
          args = [key, subjects[key]];
        } else {
          args = [key, [subjects[key]]];
        }

        // Name and value.
        _load.apply(context, [args]);

      };
    }

    // The method to load subjects into a component.
    // ---------------------------------------------
    var _load = function (/* list of subjects in string or array form */) {
      var subject = {}
      , name = ''
      , argsArray = []
      , loadedResults = []
      , error = function (name) {
          throw new Error("Subject " + name + " not found.");
      };

      // console.log("LOADING SUBJECT", arguments);

      // Loop through all given subjects and load them into the component.
      for (var i = arguments.length - 1; i >= 0; i--) {

        // console.log("LOADING ARGUMENT", i, arguments[i]);

        // Arguments can either be an array or string.
        // An array with two items will have [subjectName, [subjectConstructorArguments]].
        if (isArray(arguments[i])) {
          name = arguments[i][0];

          // Get this subject from `_store` if it exists.
          if (!isInStore(name)) error(name);
          subject = _store[name];

          // Check if we're loading other subjects into this subject. Load them first.
          if (subject.subjects) {
            _loadDeps(this, subject.subjects);
          }

          // Apply argsArray to `loaded` method.
          if (arguments[i].length > 1) argsArray = arguments[i][1];
          if (subject.loaded && isFunction(subject.loaded)) {
            loadedResults.push( subject.loaded.apply(this, argsArray) );
          }

        // Do as above, but for string subject name (without an args array).
        } else if (typeof arguments[i] === 'string') {
          name = arguments[i];
          if (!isInStore(name)) error(name);
          subject = _store[name];
          if (subject.subjects) {
            _loadDeps(this, subject.subjects);
          }
          if (subject.loaded && isFunction(subject.loaded)) {
            loadedResults.push( subject.loaded.call(this) );
          }
        }

        // Add the subject's API to the component. APIs are optional but safe.
        if (subject.api) {
          if (isFunction(subject.api)) {

            this[name] = subject.api.bind(this); // If subjects.api is a function.

          } else {

            var val
            , boundAPI = {};

            for (key in subject.api) { // TODO: make recursive?
              if (!subject.api.hasOwnProperty(key)) continue;
              val = subject.api[key];
              boundAPI[key] = isFunction(val) ? val.bind(this) : val;
            }
            this[name] = boundAPI; // APIs are namespaced by subject when loaded.
          };
        }
      } // End for arguments.

      return loadedResults;

    };

    var load = function (/* context, subject names...*/) {
      var s = Array.prototype.slice.call(arguments, 1);
      _load.apply(arguments[0], s);
    };

    // Run a subject's unloaded() function in a given context
    var unload = function (/* context, subject name */) {
      var s = Array.prototype.slice.call(arguments, 1);
      if (!isInStore(s)) throw new Error("Subject " + s + " not found.");
      if (_store[s].unloaded && isFunction(_store[s].unloaded))
        _store[s].unloaded.call(arguments[0]);
    };

    var view = function () {
      if (canUseConsoleLog()) console.log(_store);
    };

    // Subjects API
    // ------------
    return {
      before: {
        save: function (func) {
          if (!isFunction(func)) throw new Error("Hooks must be functions!");
          saveHooks.before.push(func);
        }
      },
      after: {
        save: function (func) {
          if (!isFunction(func)) throw new Error("Hooks must be functions!");
          saveHooks.after.push(func);
        }
      },
      save: save,
      load: load,
      unload: unload,
      view: view
    };

  }());

  // Add subjects module to A!
  A.subjects = subjects;

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


<commit_before>'use strict';

// derivative-model.js - A just a generic object literal model
const validator = require('validator');

const derivativeModel = {
    name: {
        type: String,
        required: true,
        prop: data => data.name,
        validator: [
            {
                validate: data => !validator.isNull(data.name),
                message: "Name cannot be empty."
            }
        ]
    },
    age: {
        type: Number,
        required: false,
        min: 0,
        prop: data => data.age,
        validator: [
            {
                validate: data => Number.isSafeInteger(data.age),
                message: "Age must be a valid integer."
            },
            {
                validate: data => data.age >= derivativeModel.age.min,
                message: "Age must not be negative."
            }
        ]
    }
};

module.exports = derivativeModel;
<commit_msg>Added icon & full to derivative model.<commit_after>'use strict';

// derivative-model.js - A just a generic object literal model
const validator = require('validator');

const Picture = require('../picture/picture-model');

const derivativeModel = {
    name: {
        type: String,
        required: true,
        prop: data => data.name,
        validator: [
            {
                validate: data => !validator.isNull(data.name),
                message: "Name cannot be empty."
            }
        ]
    },
    icon: {
        type: Picture,
        required: false,
        prop: data => data.icon
    },
    full: {
        type: Picture,
        required: false,
        prop: data => data.full
    },
    age: {
        type: Number,
        required: false,
        min: 0,
        prop: data => data.age,
        validator: [
            {
                validate: data => Number.isSafeInteger(data.age),
                message: "Age must be a valid integer."
            },
            {
                validate: data => data.age >= derivativeModel.age.min,
                message: "Age must not be negative."
            }
        ]
    }
};

module.exports = derivativeModel;
<|endoftext|>


<commit_before>import moment from 'moment'
import {sortBy} from 'lodash'
import {isPast} from '<utils>/utils'

const sponsors = {
  premierSponsors: [
    {
      imgSrc: '/sponsors/eggheadio.png',
      name: 'Egghead.io',
      link: 'http://jsair.io/eggheadio',
      tagline: 'Bite-sized web development video training',
      startDate: '2015-12-08',
    },
  ],
  goldSponsors: [
    {
      imgSrc: '/sponsors/frontendmasters.png',
      name: 'Frontend Masters',
      link: 'http://jsair.io/frontendmasters',
      tagline: 'Expert front-end training',
      startDate: '2015-12-08',
    },
    {
      imgSrc: '/sponsors/trackjs.png',
      name: '{Track:js}',
      link: 'http://jsair.io/trackjs',
      tagline: 'JavaScript Error Monitoring',
      startDate: '2015-12-08',
    },
    {
      imgSrc: '/sponsors/wallabyjs.png',
      name: 'Wallaby.js',
      link: 'http://jsair.io/wallabyjs',
      tagline: 'Realtime code coverage',
      startDate: '2016-01-15',
      endDate: '2016-04-18',
    },
    {
      imgSrc: '/sponsors/codecov.png',
      name: 'Codecov.io',
      link: 'http://jsair.io/codecov',
      tagline: 'Code coverage done right',
      startDate: '2016-01-15',
      endDate: '2016-04-19',
    },
    {
      imgSrc: '/sponsors/sparkpost.png',
      name: 'SparkPost',
      link: 'http://jsair.io/sparkpost',
      tagline: `Email. We've Got It Down.`,
      startDate: '2016-04-19',
    },
    {
      imgSrc: '/sponsors/webstorm.png',
      name: 'WebStorm',
      link: 'http://jsair.io/webstorm',
      tagline: 'Smart JavaScript IDE',
      startDate: '2016-04-20',
    },
  ],
  silverSponsors: [
    {
      imgSrc: '/sponsors/fluent.png',
      name: 'Fluent',
      link: 'http://jsair.io/fluent',
      tagline: 'Web development training',
      startDate: '2016-02-02',
    },
    {
      imgSrc: '/sponsors/auth0.png',
      name: 'Auth0',
      link: 'http://jsair.io/auth0',
      tagline: 'Authentication Made Simple',
      startDate: '2016-02-17',
    },
    {
      imgSrc: '/sponsors/trading-tech.png',
      name: 'Trading Technologies',
      link: 'http://jsair.io/trading-technologies',
      tagline: `Building For What's Next`,
      startDate: '2016-03-22',
    },
    {
      imgSrc: '/sponsors/sparkpost.png',
      name: 'SparkPost',
      link: 'http://jsair.io/sparkpost',
      tagline: `Email. We've Got It Down.`,
      startDate: '2016-04-05',
      endDate: '2016-04-19',
    },
  ],
  appreciationSponsors: [
    {
      twitter: '_jwngr',
      name: 'Jacob Wenger',
      startDate: '2016-03-11',
    },
    {
      twitter: 'nyrosmith',
      name: 'Martin Schmid',
      startDate: '2016-03-11',
    },
  ].map(s => {
    return {
      imgSrc: `/sponsors/appreciation/${s.twitter}.png`,
      link: `https://twitter.com/${s.twitter}`,
      squareImage: false,
      ...s,
    }
  }),
}

function getSponsorsForDate(date) {
  const filterSponsor = getSponsorFilter(date)
  const sponsorsForDate = Object.keys(sponsors).reduce((current, key) => {
    const sponsorGroup = sponsors[key]
    const filteredSponsors = sponsorGroup.filter(filterSponsor)
    const sortedSponsors = sortBy(filteredSponsors, 'date')
    if (key === 'premierSponsors') {
      current.premierSponsor = sortedSponsors[0]
    } else {
      current[key] = sortedSponsors
    }
    return current
  }, {})
  return sponsorsForDate
}

function getSponsorFilter(date) {
  const momentDate = moment(date)
  return function filter(sponsor) {
    const {startDate, endDate} = sponsor
    const sponsorshipHasBegun = isPast(startDate, momentDate)
    const sponsorshipHasEnded = endDate && isPast(endDate, momentDate)
    return sponsorshipHasBegun && !sponsorshipHasEnded
  }
}

const currentSponsors = getSponsorsForDate(new Date())

export default sponsors

export {currentSponsors, getSponsorsForDate}
<commit_msg>update sponsors<commit_after>import moment from 'moment'
import {sortBy} from 'lodash'
import {isPast} from '<utils>/utils'

const sponsors = {
  premierSponsors: [
    {
      imgSrc: '/sponsors/eggheadio.png',
      name: 'Egghead.io',
      link: 'http://jsair.io/eggheadio',
      tagline: 'Bite-sized web development video training',
      startDate: '2015-12-08',
    },
  ],
  goldSponsors: [
    {
      imgSrc: '/sponsors/frontendmasters.png',
      name: 'Frontend Masters',
      link: 'http://jsair.io/frontendmasters',
      tagline: 'Expert front-end training',
      startDate: '2015-12-08',
    },
    {
      imgSrc: '/sponsors/trackjs.png',
      name: '{Track:js}',
      link: 'http://jsair.io/trackjs',
      tagline: 'JavaScript Error Monitoring',
      startDate: '2015-12-08',
    },
    {
      imgSrc: '/sponsors/wallabyjs.png',
      name: 'Wallaby.js',
      link: 'http://jsair.io/wallabyjs',
      tagline: 'Realtime code coverage',
      startDate: '2016-01-15',
      endDate: '2016-04-18',
    },
    {
      imgSrc: '/sponsors/codecov.png',
      name: 'Codecov.io',
      link: 'http://jsair.io/codecov',
      tagline: 'Code coverage done right',
      startDate: '2016-01-15',
      endDate: '2016-04-19',
    },
    {
      imgSrc: '/sponsors/sparkpost.png',
      name: 'SparkPost',
      link: 'http://jsair.io/sparkpost',
      tagline: `Email. We've Got It Down.`,
      startDate: '2016-04-19',
    },
    {
      imgSrc: '/sponsors/webstorm.png',
      name: 'WebStorm',
      link: 'http://jsair.io/webstorm',
      tagline: 'Smart JavaScript IDE',
      startDate: '2016-04-20',
    },
  ],
  silverSponsors: [
    {
      imgSrc: '/sponsors/fluent.png',
      name: 'Fluent',
      link: 'http://jsair.io/fluent',
      tagline: 'Web development training',
      startDate: '2016-02-02',
      endDate: '2016-05-02',
    },
    {
      imgSrc: '/sponsors/auth0.png',
      name: 'Auth0',
      link: 'http://jsair.io/auth0',
      tagline: 'Authentication Made Simple',
      startDate: '2016-02-17',
    },
    {
      imgSrc: '/sponsors/trading-tech.png',
      name: 'Trading Technologies',
      link: 'http://jsair.io/trading-technologies',
      tagline: `Building For What's Next`,
      startDate: '2016-03-22',
    },
    {
      imgSrc: '/sponsors/sparkpost.png',
      name: 'SparkPost',
      link: 'http://jsair.io/sparkpost',
      tagline: `Email. We've Got It Down.`,
      startDate: '2016-04-05',
      endDate: '2016-04-19',
    },
  ],
  appreciationSponsors: [
    {
      twitter: '_jwngr',
      name: 'Jacob Wenger',
      startDate: '2016-03-11',
    },
    {
      twitter: 'nyrosmith',
      name: 'Martin Schmid',
      startDate: '2016-03-11',
    },
  ].map(s => {
    return {
      imgSrc: `/sponsors/appreciation/${s.twitter}.png`,
      link: `https://twitter.com/${s.twitter}`,
      squareImage: false,
      ...s,
    }
  }),
}

function getSponsorsForDate(date) {
  const filterSponsor = getSponsorFilter(date)
  const sponsorsForDate = Object.keys(sponsors).reduce((current, key) => {
    const sponsorGroup = sponsors[key]
    const filteredSponsors = sponsorGroup.filter(filterSponsor)
    const sortedSponsors = sortBy(filteredSponsors, 'date')
    if (key === 'premierSponsors') {
      current.premierSponsor = sortedSponsors[0]
    } else {
      current[key] = sortedSponsors
    }
    return current
  }, {})
  return sponsorsForDate
}

function getSponsorFilter(date) {
  const momentDate = moment(date)
  return function filter(sponsor) {
    const {startDate, endDate} = sponsor
    const sponsorshipHasBegun = isPast(startDate, momentDate)
    const sponsorshipHasEnded = endDate && isPast(endDate, momentDate)
    return sponsorshipHasBegun && !sponsorshipHasEnded
  }
}

const currentSponsors = getSponsorsForDate(new Date())

export default sponsors

export {currentSponsors, getSponsorsForDate}
<|endoftext|>


<commit_before>/*
 * Copyright (c) 2017 Bruce Schubert.
 * The MIT License
 * http://www.opensource.org/licenses/mit-license
 */

/* global define, WorldWind */

/**
 * The EnhancedWmsLayer provides vendor parameters to the GeoServer WMS GetMap
 * requests.
 *
 * @exports EnhancedWmsLayer
 * @author Bruce Schubert
 */
define(['worldwind'],
    function () {
        "use strict";

        var EnhancedWmsLayer = function (config, timeString) {
            WorldWind.WmsLayer.call(this, config, timeString);

            // Extract the bbox out of the WMS layer configuration
            this.bbox = config.sector;

            // Override the default WmsLayer 36x36 level set with one that
            // matches the GeoServer EPSG:4326 Gridset
            this.levels = new WorldWind.LevelSet(WorldWind.Sector.FULL_SPHERE,
                new WorldWind.Location(180, 180),
                config.numLevels || 22,
                256,
                256);

            // "tiled=true" is a hint for the GeoServer WMS to use the GeoWebCache
            this.vendorParms = '&tiled=true&tilesorigin=-180,-90';

            // The WW tileCache is too small to accomodate large screen
            // full of tiles at an oblique view from the surface.
            // Increase the size to prevent trashing of the tileCache.
            this.tileCache = new WorldWind.MemoryCache(4.2e6, 3.2e6);

        };

        // Inherit the WmsLayer methods
        EnhancedWmsLayer.prototype = Object.create(WorldWind.WmsLayer.prototype);

        /**
         * Returns the URL string for the resource. Overrides the TiledImageLayer
         * resourceUrlForTile method by appending the vendor paramerters to the URL.
         * @param {ImageTile} tile The tile whose image is returned
         * @param {String} imageFormat The mime type of the image format desired.
         * @returns {String} The URL string, or null if the string can not be formed.
         */
        EnhancedWmsLayer.prototype.resourceUrlForTile = function (tile, imageFormat) {
            var url = WorldWind.TiledImageLayer.prototype.resourceUrlForTile.call(this, tile, imageFormat);
            if (url) {
                url = url + this.vendorParms;
            }
            return url;
        };

        return EnhancedWmsLayer;
    }
);<commit_msg>Small tweak to tile cache size in  EnhancedWmsLayer. - Removed a debug value.<commit_after>/*
 * Copyright (c) 2017 Bruce Schubert.
 * The MIT License
 * http://www.opensource.org/licenses/mit-license
 */

/* global define, WorldWind */

/**
 * The EnhancedWmsLayer provides vendor parameters to the GeoServer WMS GetMap
 * requests.
 *
 * @exports EnhancedWmsLayer
 * @author Bruce Schubert
 */
define(['worldwind'],
    function () {
        "use strict";

        var EnhancedWmsLayer = function (config, timeString) {
            WorldWind.WmsLayer.call(this, config, timeString);

            // Extract the bbox out of the WMS layer configuration
            this.bbox = config.sector;

            // Override the default WmsLayer 36x36 level set with one that
            // matches the GeoServer EPSG:4326 Gridset
            this.levels = new WorldWind.LevelSet(WorldWind.Sector.FULL_SPHERE,
                new WorldWind.Location(180, 180),
                config.numLevels || 22,
                256,
                256);

            // "tiled=true" is a hint for the GeoServer WMS to use the GeoWebCache
            this.vendorParms = '&tiled=true&tilesorigin=-180,-90';

            // The WW tileCache is too small to accomodate large screen
            // full of tiles at an oblique view from the surface.
            // Increase the size to prevent trashing of the tileCache.
            this.tileCache = new WorldWind.MemoryCache(4.0e6, 3.2e6);

        };

        // Inherit the WmsLayer methods
        EnhancedWmsLayer.prototype = Object.create(WorldWind.WmsLayer.prototype);

        /**
         * Returns the URL string for the resource. Overrides the TiledImageLayer
         * resourceUrlForTile method by appending the vendor paramerters to the URL.
         * @param {ImageTile} tile The tile whose image is returned
         * @param {String} imageFormat The mime type of the image format desired.
         * @returns {String} The URL string, or null if the string can not be formed.
         */
        EnhancedWmsLayer.prototype.resourceUrlForTile = function (tile, imageFormat) {
            var url = WorldWind.TiledImageLayer.prototype.resourceUrlForTile.call(this, tile, imageFormat);
            if (url) {
                url = url + this.vendorParms;
            }
            return url;
        };

        return EnhancedWmsLayer;
    }
);<|endoftext|>


<commit_before>function User(userID, login, fullName, firstName, lastName, color)
{
	if (userID !== undefined && login === undefined && fullName === undefined && firstName === undefined &&
		lastName === undefined && color === undefined)
	{
		// Just look up an existing user
		return User.prototype.users[userID];
	}
	else
	{
		// Create a new instance.
		this.id = userID;
		this.login = login;
		this.fullName = fullName;
		this.firstName = firstName;
		this.lastName = lastName;
		this.color = color;

		// Cache the instance for later lookups.
 		User.prototype.users[userID] = this;
	}

	return this;
};

User.prototype.users = {};

User.all = function()
{
	return User.prototype.users;
};

/**
 * Gets the user object belonging the passed ID and calls the passed function
 * with this as parameter. If the user object is not available, an update of
 * the user cache is scheduled before.
 */
User.auto_update_call = function(user_id, fn)
{
  if (user_id in User.prototype.users) {
    fn(User.prototype.users[user_id]);
  } else {
    User.getUsers(function() {
      // Expect it to be there after the update
      fn(User.prototype.users[user_id]);
    });
  }
};

User.getUsers = function(completionCallback)
{
	// Asynchronously request the list of users from the server.
	requestQueue.register(django_url + 'user-list',
							'GET',
							undefined,
							function (status, text, xml) {
								User.prototype.handleGetUsers(status, text, xml);
								if (completionCallback !== undefined) {
									completionCallback();
								}
							});
};

User.prototype.handleGetUsers = function(status, text, xml)
{
	if (status == 200 && text)
	{
		var jsonData = $.parseJSON(text);
		for (var i = 0; i < jsonData.length; i++)
		{
			var userData = jsonData[i];
			new User(userData.id, userData.login, userData.full_name, userData.first_name, userData.last_name,
			         new THREE.Color().setRGB(userData.color[0], userData.color[1], userData.color[2]));
		}
	}
	else
	{
		alert("The list of users could not be retrieved:\n\n\t" + text + "\n\n(" + status + ")");
	}
};
<commit_msg>Use new error dialog in user retrieval in front-end<commit_after>function User(userID, login, fullName, firstName, lastName, color)
{
	if (userID !== undefined && login === undefined && fullName === undefined && firstName === undefined &&
		lastName === undefined && color === undefined)
	{
		// Just look up an existing user
		return User.prototype.users[userID];
	}
	else
	{
		// Create a new instance.
		this.id = userID;
		this.login = login;
		this.fullName = fullName;
		this.firstName = firstName;
		this.lastName = lastName;
		this.color = color;

		// Cache the instance for later lookups.
 		User.prototype.users[userID] = this;
	}

	return this;
};

User.prototype.users = {};

User.all = function()
{
	return User.prototype.users;
};

/**
 * Gets the user object belonging the passed ID and calls the passed function
 * with this as parameter. If the user object is not available, an update of
 * the user cache is scheduled before.
 */
User.auto_update_call = function(user_id, fn)
{
  if (user_id in User.prototype.users) {
    fn(User.prototype.users[user_id]);
  } else {
    User.getUsers(function() {
      // Expect it to be there after the update
      fn(User.prototype.users[user_id]);
    });
  }
};

User.getUsers = function(completionCallback)
{
	// Asynchronously request the list of users from the server.
	requestQueue.register(django_url + 'user-list',
							'GET',
							undefined,
							function (status, text, xml) {
								User.prototype.handleGetUsers(status, text, xml);
								if (completionCallback !== undefined) {
									completionCallback();
								}
							});
};

User.prototype.handleGetUsers = function(status, text, xml)
{
	if (status == 200 && text)
	{
		var jsonData = $.parseJSON(text);
		for (var i = 0; i < jsonData.length; i++)
		{
			var userData = jsonData[i];
			new User(userData.id, userData.login, userData.full_name, userData.first_name, userData.last_name,
			         new THREE.Color().setRGB(userData.color[0], userData.color[1], userData.color[2]));
		}
	}
	else
	{
		new ErrorDialog("The list of users could not be retrieved.",
			text + "\n\n(Status: " + status + ")").show();
	}
};
<|endoftext|>