<commit_before>import { asImmutable } from '../../../helper/immutableHelper';
import * as actions from './actions';

const initialState = asImmutable({});

export const reducer = (state = initialState, { type, payload }) => {
  switch (type) {
    case actions.FETCH_USER.SUCCEEDED:
      return state.merge(payload.data || {});
    case actions.FETCH_USER_NOTES.SUCCEEDED:
      return state.merge({
        notes: payload.data || []
      });
    case actions.STORE_USER_NOTE.SUCCEEDED:
      return state.mergeIn(['notes'], [payload.data]);
    case actions.FETCH_REPOSITORIES.SUCCEEDED:
      return state.merge({
        repositories: payload.data || []
      });
    default:
      return state;
  }
};

export default reducer;
<commit_msg>Fix problem of note replacement<commit_after>import { asImmutable } from '../../../helper/immutableHelper';
import * as actions from './actions';

const initialState = asImmutable({});

export const reducer = (state = initialState, { type, payload }) => {
  switch (type) {
    case actions.FETCH_USER.SUCCEEDED:
      return state.merge(payload.data || {});
    case actions.FETCH_USER_NOTES.SUCCEEDED:
      return state.merge({
        notes: payload.data || []
      });
    case actions.STORE_USER_NOTE.SUCCEEDED:
      return state.set('notes', state.get('notes').push(asImmutable(payload.data)));
    case actions.FETCH_REPOSITORIES.SUCCEEDED:
      return state.merge({
        repositories: payload.data || []
      });
    default:
      return state;
  }
};

export default reducer;
<|endoftext|>


<commit_before>var spawn = require('child_process').spawn,
    docker = require('../lib/docker')();

var shTask = module.exports = function(name) {
    'use strict';

    var containerManifest = docker.manifest.containers[name];

    if (!containerManifest) {
        throw new Error('Container "' + name + '" not found!');
    }

    return new Promise(function(resolve, reject) {
        var containerName = containerManifest.prefixName + '0';
        var imageName = containerManifest.imageName;

        console.log(this.opts);

        var cmd = spawn('docker', ['run', '-ti', imageName, 'bash'], {stdio:'inherit'});
        cmd.on('exit', function(code) {
            if (code === 0 || code === '0') {
                this.report('message', 'Exit successfully');
                resolve();
            } else {
                reject(new Error('Exit with error code: ' + code));
            }
        }.bind(this));
    }.bind(this));
};<commit_msg>fixed sh task to attach to current working shell or using -s, --single if you dont want to attach<commit_after>var spawn = require('child_process').spawn,
    docker = require('../lib/docker')();

var shTask = module.exports = function(name) {
    'use strict';

    var containerManifest = docker.manifest.containers[name];

    if (!containerManifest) {
        throw new Error('Container "' + name + '" not found!');
    }

    return new Promise(function(resolve, reject) {
        var containerName = containerManifest.prefixName + '0';
        var imageName = containerManifest.imageName;
        var cmd;

        if (this.opts.s || this.opts.single) {
            cmd = spawn('docker', ['run', '-ti', imageName, 'bash'], {stdio:'inherit'});
            cmd.on('exit', function(code) {
                if (code === 0 || code === '0') {
                    this.report('message', 'Exit successfully');
                    resolve();
                } else {
                    reject(new Error('Exit with error code: ' + code));
                }
            }.bind(this));
        } else {
            cmd = spawn('docker', ['exec', '-ti', containerName, 'bash'], {stdio:'inherit'});
            cmd.on('exit', function(code) {
                if (code === 0 || code === '0') {
                    this.report('message', 'Exit successfully');
                    resolve();
                } else {
                    reject(new Error('Exit with error code: ' + code));
                }
            }.bind(this));
        }

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


<commit_before>(function($) {

  $.yifansays = function(options) {

    var settings = $.extend({
        source: 'https://rawgit.com/shamenchens/yifanslideshow/gh-pages/src/yifansays.json',
        image: [
          'https://raw.githubusercontent.com/shamenchens/yifanslideshow/gh-pages/img/yifan.png'
        ],
        height: 450, // image height
        width: 466, // image width
        effect: 'jump', // options: default, fast, slow, veryslow, jump, sneaky
        popup_effect: 'fade', // options: default, fade, slide, zoom
        popup_radius: '8px', // popup radius
        popup_color: 'black', // popup font color
        popup_bgcolor: 'beige', // popup background color
        readmore_color: 'brown', // popup font color
        comein_position: 80, // show kp after scroll more than percent of page height
        default_text: '一帆表示', // the words show in popup before loading done
        enter_from: 'left', // options: left, right
        enter_distance: -50 // the distance to window side

        //left: -130, // remove this option after ver2.0
    }, options);

    createYifan(settings);

    var container = $('#yifan_container'),
        yifan_image = $('#yifan_container img'),
        popup = $('#yifan_popup'),
        close = $('#yifan_close_popup');

    $(window).scroll(function(){
      var scroll = $(window).scrollTop(),
          window_h = $(window).height(),
          page_h = $(document).height(),
          come_in = {},come_out = {};
      come_in[settings.enter_from] = settings.enter_distance+'px';
      come_out[settings.enter_from] = '-'+(settings.width)+'px';

      if((scroll+window_h) > (page_h*(settings.comein_position/100))) {
        if(container.css(settings.enter_from) == '-'+settings.width+'px') {
          switch(settings.effect) {
            case 'fast':
              container.animate(come_in, 100, function() {
                popupIn(settings.popup_effect);
              });
              break;

            case 'slow':
              container.animate(come_in, 1000, function() {
                popupIn(settings.popup_effect);
              });
              break;

            case 'veryslow':
              container.animate(come_in, 10000, function() {
                popupIn(settings.popup_effect);
              });
              break;

            case 'jump':
              container
                .css('bottom','-'+settings.height+'px')
                .css(settings.enter_from,settings.enter_distance);
              container
                .animate({bottom: 0}, 300)
                .animate({bottom: '-10px'}, 50)
                .animate({bottom: 0}, 50)
                .animate({bottom: '-10px'}, 50)
                .animate({
                  bottom: 0
                }, 300, function() {
                  popupIn(settings.popup_effect);
                });
              break;

            case 'sneaky':
              var sneaky_pos1 = {},
                  sneaky_pos2 = {},
                  sneaky_pos3 = {};
              sneaky_pos1[settings.enter_from] = '-'+(settings.width*0.54)+'px';
              sneaky_pos2[settings.enter_from] = '-'+(settings.width*0.6)+'px';
              sneaky_pos3[settings.enter_from] = '-'+(settings.width*0.7)+'px';

              container
                .animate(sneaky_pos1, 2000).delay(2000)
                .animate(sneaky_pos2, 1000).delay(1000)
                .animate(sneaky_pos1, 1000).delay(2000)
                .animate(sneaky_pos3, 2000).delay(1000)
                .animate(come_in, 3000, function() {
                  popupIn(settings.popup_effect);
                });
              break;

            default:
              container.animate(
                come_in, 500, function() {
                  popupIn(settings.popup_effect);
              });
              break;
          }
        }
      }
      else {
        if(container.css(settings.enter_from) == settings.enter_distance+'px') {
          popup.hide();
          container.animate(come_out, 100);
          loadData(settings);
        }
      }
    });
    yifan_image.click(function(){
      var come_out_forever = {};
      come_out_forever[settings.enter_from] = '-'+(settings.width+10)+'px';
      popup.remove();
      container.animate(come_out_forever, 100);
    });
    close.click(function(){
      popup.hide();
      loadData(settings);
    });
  };

  function createYifan(settings){
    var img_src,arrow_pos;
    if($.isArray(settings.image)==true)
      img_src = settings.image[Math.floor(Math.random()*(settings.image.length))];
    else
      img_src = settings.image;
    if(settings.enter_from == 'left')
      arrow_pos = 'right';
    else
      arrow_pos = 'left';
    var object = '

'+settings.default_text+'了解更多Yifan

X

';
    $('body').append(object);
    loadData(settings);
  }

  function loadData(settings){
    var says, talk;
    $.getJSON(settings.source, function(data) {
      talk = data.talks[Math.floor(Math.random()*(data.talks.length))];
      says = '
'+settings.default_text+'
'+talk+'
';
    }).always(function() {
      $('#yifan_says').scrollTop(0).html(says).promise().done(function(){
        $('p').removeAttr("style"); $('span').removeAttr("style");
      });
    });
  }

  function popupIn(effect) {
    switch(effect) {

      case 'fade':
        $('#yifan_popup').fadeIn('slow');
        break;

      case 'slide':
        $('.yifan_readmore').hide(function(){
          $('#yifan_popup').slideDown('fast',function(){
            $('.yifan_readmore').fadeIn();
          });
        });
        break;

      case 'zoom':
        $('#yifan_says').hide(function(){
          $('#yifan_popup').show('slow',function(){
            $('#yifan_says').fadeIn();
          });
        });
        break;

      default:
        $('#yifan_popup').show();
        break;
    }
  }

}(jQuery));
<commit_msg>Move talks to google spreadsheet<commit_after>(function($) {

  $.yifansays = function(options) {

    var settings = $.extend({
        source: 'https://spreadsheets.google.com/feeds/cells/149wA5vH2cOQWTjRthjutL5YmS_E6AZ6YcqwPihpSMsU/o6wgwqc/public/values?alt=json',
        image: [
          'https://raw.githubusercontent.com/shamenchens/yifanslideshow/gh-pages/img/yifan.png'
        ],
        height: 450, // image height
        width: 466, // image width
        effect: 'jump', // options: default, fast, slow, veryslow, jump, sneaky
        popup_effect: 'fade', // options: default, fade, slide, zoom
        popup_radius: '8px', // popup radius
        popup_color: 'black', // popup font color
        popup_bgcolor: 'beige', // popup background color
        readmore_color: 'brown', // popup font color
        comein_position: 80, // show kp after scroll more than percent of page height
        default_text: '一帆表示', // the words show in popup before loading done
        enter_from: 'left', // options: left, right
        enter_distance: -50 // the distance to window side

        //left: -130, // remove this option after ver2.0
    }, options);

    createYifan(settings);

    var container = $('#yifan_container'),
        yifan_image = $('#yifan_container img'),
        popup = $('#yifan_popup'),
        close = $('#yifan_close_popup');

    $(window).scroll(function(){
      var scroll = $(window).scrollTop(),
          window_h = $(window).height(),
          page_h = $(document).height(),
          come_in = {},come_out = {};
      come_in[settings.enter_from] = settings.enter_distance+'px';
      come_out[settings.enter_from] = '-'+(settings.width)+'px';

      if((scroll+window_h) > (page_h*(settings.comein_position/100))) {
        if(container.css(settings.enter_from) == '-'+settings.width+'px') {
          switch(settings.effect) {
            case 'fast':
              container.animate(come_in, 100, function() {
                popupIn(settings.popup_effect);
              });
              break;

            case 'slow':
              container.animate(come_in, 1000, function() {
                popupIn(settings.popup_effect);
              });
              break;

            case 'veryslow':
              container.animate(come_in, 10000, function() {
                popupIn(settings.popup_effect);
              });
              break;

            case 'jump':
              container
                .css('bottom','-'+settings.height+'px')
                .css(settings.enter_from,settings.enter_distance);
              container
                .animate({bottom: 0}, 300)
                .animate({bottom: '-10px'}, 50)
                .animate({bottom: 0}, 50)
                .animate({bottom: '-10px'}, 50)
                .animate({
                  bottom: 0
                }, 300, function() {
                  popupIn(settings.popup_effect);
                });
              break;

            case 'sneaky':
              var sneaky_pos1 = {},
                  sneaky_pos2 = {},
                  sneaky_pos3 = {};
              sneaky_pos1[settings.enter_from] = '-'+(settings.width*0.54)+'px';
              sneaky_pos2[settings.enter_from] = '-'+(settings.width*0.6)+'px';
              sneaky_pos3[settings.enter_from] = '-'+(settings.width*0.7)+'px';

              container
                .animate(sneaky_pos1, 2000).delay(2000)
                .animate(sneaky_pos2, 1000).delay(1000)
                .animate(sneaky_pos1, 1000).delay(2000)
                .animate(sneaky_pos3, 2000).delay(1000)
                .animate(come_in, 3000, function() {
                  popupIn(settings.popup_effect);
                });
              break;

            default:
              container.animate(
                come_in, 500, function() {
                  popupIn(settings.popup_effect);
              });
              break;
          }
        }
      }
      else {
        if(container.css(settings.enter_from) == settings.enter_distance+'px') {
          popup.hide();
          container.animate(come_out, 100);
          loadData(settings);
        }
      }
    });
    yifan_image.click(function(){
      var come_out_forever = {};
      come_out_forever[settings.enter_from] = '-'+(settings.width+10)+'px';
      popup.remove();
      container.animate(come_out_forever, 100);
    });
    close.click(function(){
      popup.hide();
      loadData(settings);
    });
  };

  function createYifan(settings){
    var img_src,arrow_pos;
    if($.isArray(settings.image)==true)
      img_src = settings.image[Math.floor(Math.random()*(settings.image.length))];
    else
      img_src = settings.image;
    if(settings.enter_from == 'left')
      arrow_pos = 'right';
    else
      arrow_pos = 'left';
    var object = '

'+settings.default_text+'了解更多Yifan

X

';
    $('body').append(object);
    loadData(settings);
  }

  function loadData(settings){
    var says, talk, entry;
    $.getJSON(settings.source, function(data) {
      // Retrieve talks from google spreadsheet: http://goo.gl/6fLH21
      // We only need column B starting from row 2, so we can remove the first two cells,
      // which are the two cells in row 1, and filter out first cell in each row.
      entry = data.feed.entry.splice(2).filter(function(element, index) {
        return index % 2 === 1;
      });
      talk = entry[Math.floor(Math.random()*(entry.length))].content['$t'];
      says = '
'+settings.default_text+'
'+talk+'
';
    }).always(function() {
      $('#yifan_says').scrollTop(0).html(says).promise().done(function(){
        $('p').removeAttr("style"); $('span').removeAttr("style");
      });
    });
  }

  function popupIn(effect) {
    switch(effect) {

      case 'fade':
        $('#yifan_popup').fadeIn('slow');
        break;

      case 'slide':
        $('.yifan_readmore').hide(function(){
          $('#yifan_popup').slideDown('fast',function(){
            $('.yifan_readmore').fadeIn();
          });
        });
        break;

      case 'zoom':
        $('#yifan_says').hide(function(){
          $('#yifan_popup').show('slow',function(){
            $('#yifan_says').fadeIn();
          });
        });
        break;

      default:
        $('#yifan_popup').show();
        break;
    }
  }

}(jQuery));
<|endoftext|>


<commit_before>(function() {
    var app = angular.module("app");

    app.factory("ApiService", ['$http', function($http) {
        var api = { };
        api.url = '/api/students/';

        api.error = function(data, status, headers, config, statusText) {
            console.error('%s %s %s', config.method, config.url, status);
        }

        api.getAll = function(success) {
            var promise = $http.get(api.url);
            promise.success(success);
            promise.error(api.error);
        }

        api.getOne = function(id, success) {
            var promise = $http.get(api.url + id);
            promise.success(success);
            promise.error(api.error);
        }

        api.delete = function(id, success) {
            $http({
                url: api.url + id,
                method: "DELETE",
            }).success(success).error(api.error);
        }

        api.save = function(model, success) {
            $http({
                url: api.url,
                method: "POST",
                data: model,
            }).success(success).error(api.error);
        }

        api.update = function(model, success) {
            $http({
                url: api.url,
                method: "PUT",
                data: model,
            }).success(success).error(api.error);
        }

        return api;

    }]);

})();<commit_msg>moved into class<commit_after>(function() {
    var app = angular.module("app");

    app.factory("ApiService", ['$http', function($http) {

        var Api = function (url){
            this.url = url;
        }

        Api.prototype.error = function(data, status, headers, config, statusText) {
            console.error('%s %s %s', config.method, config.url, status);
        }

        Api.prototype.getAll = function(success) {
            var api = this;
            var promise = $http.get(api.url);
            promise.success(success);
            promise.error(api.error);
        }

        Api.prototype.getOne = function(id, success) {
            var api = this;
            var promise = $http.get(api.url + id);
            promise.success(success);
            promise.error(api.error);
        }

        Api.prototype.delete = function(id, success) {
            var api = this;
            $http({
                url: api.url + id,
                method: "DELETE",
            }).success(success).error(api.error);
        }

        Api.prototype.save = function(model, success) {
            var api = this;
            $http({
                url: api.url,
                method: "POST",
                data: model,
            }).success(success).error(api.error);
        }

        Api.prototype.update = function(model, success) {
            var api = this;
            $http({
                url: api.url,
                method: "PUT",
                data: model,
            }).success(success).error(api.error);
        }

        return new Api('/api/students/');

    }]);

})();<|endoftext|>


<commit_before>/*
Copyright 2017 Vector Creations Ltd

Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at

    http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/

import q from "q";
import {MatrixInMemoryStore} from "./memory";
import utils from "../utils";
import LocalIndexedDBStoreBackend from "./indexeddb-local-backend.js";

/**
 * This is an internal module. See {@link IndexedDBStore} for the public class.
 * @module store/indexeddb
 */

// If this value is too small we'll be writing very often which will cause
// noticable stop-the-world pauses. If this value is too big we'll be writing
// so infrequently that the /sync size gets bigger on reload. Writing more
// often does not affect the length of the pause since the entire /sync
// response is persisted each time.
const WRITE_DELAY_MS = 1000 * 60 * 5; // once every 5 minutes

/**
 * Construct a new Indexed Database store, which extends MatrixInMemoryStore.
 *
 * This store functions like a MatrixInMemoryStore except it periodically persists
 * the contents of the store to an IndexedDB backend.
 *
 * All data is still kept in-memory but can be loaded from disk by calling
 * startup(). This can make startup times quicker as a complete
 * sync from the server is not required. This does not reduce memory usage as all
 * the data is eagerly fetched when startup() is called.
 *

 * let opts = { localStorage: window.localStorage };
 * let store = new IndexedDBStore();
 * await store.startup(); // load from indexed db
 * let client = sdk.createClient({
 *     store: store,
 * });
 * client.startClient();
 * client.on("sync", function(state, prevState, data) {
 *     if (state === "PREPARED") {
 *         console.log("Started up, now with go faster stripes!");
 *     }
 * });
 *

 *
 * @constructor
 * @extends MatrixInMemoryStore
 * @param {Object} opts Options object.
 * @param {Object} opts.indexedDB The Indexed DB interface e.g.
 * window.indexedDB
 * @param {string=} opts.dbName Optional database name. The same name must be used
 * to open the same database.
 * @prop {IndexedDBStoreBackend} backend The backend instance. Call through to
 * this API if you need to perform specific indexeddb actions like deleting the
 * database.
 */
const IndexedDBStore = function IndexedDBStore(opts) {
    MatrixInMemoryStore.call(this, opts);

    if (!opts.indexedDB) {
        throw new Error('Missing required option: indexedDB');
    }

    this.backend = new LocalIndexedDBStoreBackend(opts.indexedDB, opts.dbName);
    this.startedUp = false;
    this._syncTs = Date.now(); // updated when writes to the database are performed
};
utils.inherits(IndexedDBStore, MatrixInMemoryStore);

/**
 * @return {Promise} Resolved when loaded from indexed db.
  */
IndexedDBStore.prototype.startup = function() {
    if (this.startedUp) {
        return q();
    }
    return this.backend.connect().then(() => {
        return q.all([
            this.backend.loadUsers(),
            this.backend.loadAccountData(),
            this.backend.loadSyncData(),
        ]);
    }).then((values) => {
        const [users, accountData, syncData] = values;
        console.log(
            "Loaded data from database: sync from ", syncData.nextBatch,
            " -- Reticulating splines...",
        );
        users.forEach((u) => {
            this.storeUser(u);
        });
        this._syncTs = Date.now(); // pretend we've written so we don't rewrite
        this.setSyncToken(syncData.nextBatch);
        this.setSyncData({
            next_batch: syncData.nextBatch,
            rooms: syncData.roomsData,
            account_data: {
                events: accountData,
            },
        });
    });
};

/**
 * @return {Promise} Resolves with a sync response to restore the
 * client state to where it was at the last save, or null if there
 * is no saved sync data.
 */
IndexedDBStore.prototype.getSavedSync = function() {
    return this.backend.getSavedSync();
};

/**
 * Delete all data from this store.
 * @return {Promise} Resolves if the data was deleted from the database.
 */
IndexedDBStore.prototype.deleteAllData = function() {
    MatrixInMemoryStore.prototype.deleteAllData.call(this);
    return this.backend.clearDatabase().then(() => {
        console.log("Deleted indexeddb data.");
    }, (err) => {
        console.error("Failed to delete indexeddb data: ", err);
        throw err;
    });
};

/**
 * Possibly write data to the database.
 * @return {Promise} Promise resolves after the write completes.
 */
IndexedDBStore.prototype.save = function() {
    const now = Date.now();
    if (now - this._syncTs > WRITE_DELAY_MS) {
        this._syncTs = Date.now(); // set now to guard against multi-writes
        return this.backend.syncToDatabase(this.getUsers()).catch((err) => {console.error("sync fail:", err);});
    }
    return q();
};

IndexedDBStore.prototype.setSyncData = function(syncData) {
    this.backend.setSyncData(syncData);
};

module.exports.IndexedDBStore = IndexedDBStore;
<commit_msg>long line<commit_after>/*
Copyright 2017 Vector Creations Ltd

Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at

    http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/

import q from "q";
import {MatrixInMemoryStore} from "./memory";
import utils from "../utils";
import LocalIndexedDBStoreBackend from "./indexeddb-local-backend.js";

/**
 * This is an internal module. See {@link IndexedDBStore} for the public class.
 * @module store/indexeddb
 */

// If this value is too small we'll be writing very often which will cause
// noticable stop-the-world pauses. If this value is too big we'll be writing
// so infrequently that the /sync size gets bigger on reload. Writing more
// often does not affect the length of the pause since the entire /sync
// response is persisted each time.
const WRITE_DELAY_MS = 1000 * 60 * 5; // once every 5 minutes

/**
 * Construct a new Indexed Database store, which extends MatrixInMemoryStore.
 *
 * This store functions like a MatrixInMemoryStore except it periodically persists
 * the contents of the store to an IndexedDB backend.
 *
 * All data is still kept in-memory but can be loaded from disk by calling
 * startup(). This can make startup times quicker as a complete
 * sync from the server is not required. This does not reduce memory usage as all
 * the data is eagerly fetched when startup() is called.
 *

 * let opts = { localStorage: window.localStorage };
 * let store = new IndexedDBStore();
 * await store.startup(); // load from indexed db
 * let client = sdk.createClient({
 *     store: store,
 * });
 * client.startClient();
 * client.on("sync", function(state, prevState, data) {
 *     if (state === "PREPARED") {
 *         console.log("Started up, now with go faster stripes!");
 *     }
 * });
 *

 *
 * @constructor
 * @extends MatrixInMemoryStore
 * @param {Object} opts Options object.
 * @param {Object} opts.indexedDB The Indexed DB interface e.g.
 * window.indexedDB
 * @param {string=} opts.dbName Optional database name. The same name must be used
 * to open the same database.
 * @prop {IndexedDBStoreBackend} backend The backend instance. Call through to
 * this API if you need to perform specific indexeddb actions like deleting the
 * database.
 */
const IndexedDBStore = function IndexedDBStore(opts) {
    MatrixInMemoryStore.call(this, opts);

    if (!opts.indexedDB) {
        throw new Error('Missing required option: indexedDB');
    }

    this.backend = new LocalIndexedDBStoreBackend(opts.indexedDB, opts.dbName);
    this.startedUp = false;
    this._syncTs = Date.now(); // updated when writes to the database are performed
};
utils.inherits(IndexedDBStore, MatrixInMemoryStore);

/**
 * @return {Promise} Resolved when loaded from indexed db.
  */
IndexedDBStore.prototype.startup = function() {
    if (this.startedUp) {
        return q();
    }
    return this.backend.connect().then(() => {
        return q.all([
            this.backend.loadUsers(),
            this.backend.loadAccountData(),
            this.backend.loadSyncData(),
        ]);
    }).then((values) => {
        const [users, accountData, syncData] = values;
        console.log(
            "Loaded data from database: sync from ", syncData.nextBatch,
            " -- Reticulating splines...",
        );
        users.forEach((u) => {
            this.storeUser(u);
        });
        this._syncTs = Date.now(); // pretend we've written so we don't rewrite
        this.setSyncToken(syncData.nextBatch);
        this.setSyncData({
            next_batch: syncData.nextBatch,
            rooms: syncData.roomsData,
            account_data: {
                events: accountData,
            },
        });
    });
};

/**
 * @return {Promise} Resolves with a sync response to restore the
 * client state to where it was at the last save, or null if there
 * is no saved sync data.
 */
IndexedDBStore.prototype.getSavedSync = function() {
    return this.backend.getSavedSync();
};

/**
 * Delete all data from this store.
 * @return {Promise} Resolves if the data was deleted from the database.
 */
IndexedDBStore.prototype.deleteAllData = function() {
    MatrixInMemoryStore.prototype.deleteAllData.call(this);
    return this.backend.clearDatabase().then(() => {
        console.log("Deleted indexeddb data.");
    }, (err) => {
        console.error("Failed to delete indexeddb data: ", err);
        throw err;
    });
};

/**
 * Possibly write data to the database.
 * @return {Promise} Promise resolves after the write completes.
 */
IndexedDBStore.prototype.save = function() {
    const now = Date.now();
    if (now - this._syncTs > WRITE_DELAY_MS) {
        this._syncTs = Date.now(); // set now to guard against multi-writes
        return this.backend.syncToDatabase(this.getUsers()).catch((err) => {
            console.error("sync fail:", err);
        });
    }
    return q();
};

IndexedDBStore.prototype.setSyncData = function(syncData) {
    this.backend.setSyncData(syncData);
};

module.exports.IndexedDBStore = IndexedDBStore;
<|endoftext|>


<commit_before>import config from 'core/config'
import { warn, cached } from 'core/util/index'
import { query } from 'web/util/index'
import Vue from './web-runtime'
import { compile } from './web-compiler'

const idToTemplate = cached(id => query(id).innerHTML)

const cache1 = Object.create(null)
const cache2 = Object.create(null)

function createRenderFns (template) {
  const preserveWhitespace = config.preserveWhitespace
  const cache = preserveWhitespace ? cache1 : cache2
  if (cache[template]) {
    return cache[template]
  }
  const res = {}
  const compiled = compile(template, { preserveWhitespace })
  res.render = new Function(compiled.render)
  const l = compiled.staticRenderFns.length
  if (l) {
    res.staticRenderFns = new Array(l)
    for (let i = 0; i < l; i++) {
      res.staticRenderFns[i] = new Function(compiled.staticRenderFns[i])
    }
  }
  return (cache[template] = res)
}

const mount = Vue.prototype.$mount

Vue.prototype.$mount = function (el) {
  el = el && query(el)
  const options = this.$options
  // resolve template/el and convert to render function
  if (!options.render) {
    let template = options.template
    if (template) {
      if (typeof template === 'string') {
        if (template.charAt(0) === '#') {
          template = idToTemplate(template)
        }
      } else if (template.nodeType) {
        template = template.innerHTML
      } else {
        warn('invalid template option:' + template, this)
      }
    } else if (el) {
      template = getOuterHTML(el)
    }
    if (template) {
      const { render, staticRenderFns } = createRenderFns(template)
      options.render = render
      options.staticRenderFns = staticRenderFns
    }
  }
  mount.call(this, el)
}

/**
 * Get outerHTML of elements, taking care
 * of SVG elements in IE as well.
 *
 * @param {Element} el
 * @return {String}
 */

function getOuterHTML (el) {
  if (el.outerHTML) {
    return el.outerHTML
  } else {
    var container = document.createElement('div')
    container.appendChild(el.cloneNode(true))
    return container.innerHTML
  }
}

Vue.compile = compile

export default Vue
<commit_msg>exposed compile function should be cached version<commit_after>import config from 'core/config'
import { warn, cached } from 'core/util/index'
import { query } from 'web/util/index'
import Vue from './web-runtime'
import { compile } from './web-compiler'

const idToTemplate = cached(id => query(id).innerHTML)

const cache1 = Object.create(null)
const cache2 = Object.create(null)

function createRenderFns (template) {
  const preserveWhitespace = config.preserveWhitespace
  const cache = preserveWhitespace ? cache1 : cache2
  if (cache[template]) {
    return cache[template]
  }
  const res = {}
  const compiled = compile(template, { preserveWhitespace })
  res.render = new Function(compiled.render)
  const l = compiled.staticRenderFns.length
  if (l) {
    res.staticRenderFns = new Array(l)
    for (let i = 0; i < l; i++) {
      res.staticRenderFns[i] = new Function(compiled.staticRenderFns[i])
    }
  }
  return (cache[template] = res)
}

const mount = Vue.prototype.$mount

Vue.prototype.$mount = function (el) {
  el = el && query(el)
  const options = this.$options
  // resolve template/el and convert to render function
  if (!options.render) {
    let template = options.template
    if (template) {
      if (typeof template === 'string') {
        if (template.charAt(0) === '#') {
          template = idToTemplate(template)
        }
      } else if (template.nodeType) {
        template = template.innerHTML
      } else {
        warn('invalid template option:' + template, this)
      }
    } else if (el) {
      template = getOuterHTML(el)
    }
    if (template) {
      const { render, staticRenderFns } = createRenderFns(template)
      options.render = render
      options.staticRenderFns = staticRenderFns
    }
  }
  mount.call(this, el)
}

/**
 * Get outerHTML of elements, taking care
 * of SVG elements in IE as well.
 *
 * @param {Element} el
 * @return {String}
 */

function getOuterHTML (el) {
  if (el.outerHTML) {
    return el.outerHTML
  } else {
    var container = document.createElement('div')
    container.appendChild(el.cloneNode(true))
    return container.innerHTML
  }
}

Vue.compile = createRenderFns

export default Vue
<|endoftext|>


<commit_before>/* Adapted from VoteItUp */
/* A script for updating the contents of the vote widget on the fly */
/*
USAGE:
vote (object to update with vote count, object to update with after vote text, post id, user id, base url)
*/

/* Note: This script is meant for the bar theme of the plugin */

var xmlHttp
var currentobj
var voteobj
var aftervotetext

//Useful for compatibility
function function_exists( function_name ) {
    if (typeof function_name == 'string'){
        return (typeof window[function_name] == 'function');
    } else{
        return (function_name instanceof Function);
    }
}

//Javascript Function for JavaScript to communicate with Server-side scripts
function lg_AJAXrequest(scriptURL) {
	xmlHttp=zGetXmlHttpObject()
if (xmlHttp==null)
  {
  alert ("Your browser does not support AJAX!");
  return;
  }
	xmlHttp.onreadystatechange=zvoteChanged;
	xmlHttp.open("GET",scriptURL,true);
	xmlHttp.send(null);
}

function zGetXmlHttpObject()
{
var xmlHttp=null;
try
  {
  // Firefox, Opera 8.0+, Safari
  xmlHttp=new XMLHttpRequest();
  }
catch (e)
  {
  // Internet Explorer
  try
    {
    xmlHttp=new ActiveXObject("Msxml2.XMLHTTP");
    }
  catch (e)
    {
    xmlHttp=new ActiveXObject("Microsoft.XMLHTTP");
    }
  }
return xmlHttp;
}

function zvoteChanged()
{
if (xmlHttp.readyState==4)
{
	var votedisp = document.getElementById('voteid' + currentobj);
	var votenodisp = document.getElementById('votes' + currentobj);
	var voteno = xmlHttp.responseText;

	currentobj_obj = document.getElementById(currentobj);

	currentobj_obj.style.width = voteno;

        if ( voteobj !== null )  {
	    voteobj_obj = document.getElementById(voteobj);
	    voteobj_obj.innerHTML = aftervotetext;
        }

}

}

function vote(obj, votelinkobj, aftervote, postID ,userID, baseURL) {
	currentobj = obj;
	voteobj = votelinkobj;
	aftervotetext = aftervote;
	var scripturl = baseURL+"/voteinterface.php?type=vote&uid="+userID+"&pid="+postID+"&auth="+Math.random();
	lg_AJAXrequest(scripturl);
}

function sink(obj, votelinkobj, aftervote, postID ,userID, baseURL) {
	currentobj = obj;
	voteobj = votelinkobj;
	aftervotetext = aftervote;
	var scripturl = baseURL+"/voteinterface.php?type=sink&uid="+userID+"&pid="+postID+"&auth="+Math.random();
	lg_AJAXrequest(scripturl);
}

// Arghhh!!! missing vote_ticker function
// I am just copying and posting vote and sink functions to create vote_ticker and sink_ticker
// dont have nerves to create my own function in this mess. sorry
function vote_ticker(obj, postID ,userID, baseURL) {
	currentobj = obj;
	voteobj = null; // ahh!!! global javascript vars
	aftervotetext = null; // ahh!!! global javascript vars
	var scripturl = baseURL+"/voteinterface.php?type=vote&uid="+userID+"&pid="+postID+"&auth="+Math.random();
	lg_AJAXrequest(scripturl);
}

function sink_ticker(obj,  postID ,userID, baseURL) {
	currentobj = obj;
	voteobj = null; // ahh!! global javascript vars
	aftervotetext = null; // ahh!! global javascript vars
	var scripturl = baseURL+"/voteinterface.php?type=sink&uid="+userID+"&pid="+postID+"&auth="+Math.random();
	lg_AJAXrequest(scripturl);
}
<commit_msg>fixed: vote count update<commit_after>/* Adapted from VoteItUp */
/* A script for updating the contents of the vote widget on the fly */
/*
USAGE:
vote (object to update with vote count, object to update with after vote text, post id, user id, base url)
*/

/* Note: This script is meant for the bar theme of the plugin */

var xmlHttp
var currentobj
var voteobj
var aftervotetext

//Useful for compatibility
function function_exists( function_name ) {
    if (typeof function_name == 'string'){
        return (typeof window[function_name] == 'function');
    } else{
        return (function_name instanceof Function);
    }
}

//Javascript Function for JavaScript to communicate with Server-side scripts
function lg_AJAXrequest(scriptURL) {
	xmlHttp=zGetXmlHttpObject()
if (xmlHttp==null)
  {
  alert ("Your browser does not support AJAX!");
  return;
  }
	xmlHttp.onreadystatechange=zvoteChanged;
	xmlHttp.open("GET",scriptURL,true);
	xmlHttp.send(null);
}

function zGetXmlHttpObject()
{
var xmlHttp=null;
try
  {
  // Firefox, Opera 8.0+, Safari
  xmlHttp=new XMLHttpRequest();
  }
catch (e)
  {
  // Internet Explorer
  try
    {
    xmlHttp=new ActiveXObject("Msxml2.XMLHTTP");
    }
  catch (e)
    {
    xmlHttp=new ActiveXObject("Microsoft.XMLHTTP");
    }
  }
return xmlHttp;
}

function zvoteChanged()
{
if (xmlHttp.readyState==4)
{
	var votedisp = document.getElementById('voteid' + currentobj);
	var votenodisp = document.getElementById('votes' + currentobj);
	var voteno = xmlHttp.responseText;

	currentobj_obj = document.getElementById(currentobj);

	currentobj_obj.innerHTML = voteno;

        if ( voteobj !== null )  {
	    voteobj_obj = document.getElementById(voteobj);
	    voteobj_obj.innerHTML = aftervotetext;
        }

}

}

function vote(obj, votelinkobj, aftervote, postID ,userID, baseURL) {
	currentobj = obj;
	voteobj = votelinkobj;
	aftervotetext = aftervote;
	var scripturl = baseURL+"/voteinterface.php?type=vote&tid=total&uid="+userID+"&pid="+postID+"&auth="+Math.random();
	lg_AJAXrequest(scripturl);
}

function sink(obj, votelinkobj, aftervote, postID ,userID, baseURL) {
	currentobj = obj;
	voteobj = votelinkobj;
	aftervotetext = aftervote;
	var scripturl = baseURL+"/voteinterface.php?type=sink&tid=total&uid="+userID+"&pid="+postID+"&auth="+Math.random();
	lg_AJAXrequest(scripturl);
}

// Arghhh!!! missing vote_ticker function
// I am just copying and posting vote and sink functions to create vote_ticker and sink_ticker
// dont have nerves to create my own function in this mess. sorry
function vote_ticker(obj, postID ,userID, baseURL) {
	currentobj = obj;
	voteobj = null; // ahh!!! global javascript vars
	aftervotetext = null; // ahh!!! global javascript vars
	var scripturl = baseURL+"/voteinterface.php?type=vote&tid=total&uid="+userID+"&pid="+postID+"&auth="+Math.random();
	lg_AJAXrequest(scripturl);
}

function sink_ticker(obj,  postID ,userID, baseURL) {
	currentobj = obj;
	voteobj = null; // ahh!! global javascript vars
	aftervotetext = null; // ahh!! global javascript vars
	var scripturl = baseURL+"/voteinterface.php?type=sink&tid=total&uid="+userID+"&pid="+postID+"&auth="+Math.random();
	lg_AJAXrequest(scripturl);
}
<|endoftext|>


<commit_before>module.exports = {
  mode: 'jit',
  purge: [
    './src/server/template/ejs/**/*'
  ],
  darkMode: false, // or 'media' or 'class'
  theme: {
    extend: {},
  },
  variants: {
    extend: {},
  },
  plugins: [],
}
<commit_msg>add tailwindcss/forms<commit_after>module.exports = {
  mode: 'jit',
  purge: [
    './src/server/template/ejs/**/*'
  ],
  darkMode: false, // or 'media' or 'class'
  theme: {
    extend: {},
  },
  variants: {
    extend: {},
  },
  plugins: [
    require('@tailwindcss/forms'),
  ],
}
<|endoftext|>


<commit_before>"use strict";
const utils = require("./utils");
const financials = require("./financials");

const OUTPUT_FOLDER = "data/output/";
// utils.list_files(OUTPUT_FOLDER)
//     .then(console.log);

const constructFilePath = (date) => {
    return Promise.resolve(OUTPUT_FOLDER + date + ".csv");
};

const computeChangesEtf = (resultList) => {
    const CRITERIA = "forecastPe";
    let cheaperList = [];
    let moreExpensiveList = [];
    let ticketList = resultList[0].reduce( (total, elt) => {
        total.push(elt.name);
        return total;
    }, []);
    for (const ticket of ticketList) {
        const CRITERIA = "pe";
        let old = resultList[0].find(x => x.name === ticket);
        let n = resultList[1].find(x => x.name === ticket);
        if (old !== undefined && n !== undefined) {
            // let earningsUpdate = financials.haveEarningsChanged(old.price, old.pe, n.price, n.pe);
            // console.log(ticket + " " + priceVariation);
            if (!financials.areFloatEqual(old[CRITERIA], n[CRITERIA])) {
                let change = n[CRITERIA] / old[CRITERIA];
                if (old[CRITERIA] > n[CRITERIA]) {
                    cheaperList.push({
                        old: old,
                        n: n,
                        change: change
                    });
                }
                else {
                    moreExpensiveList.push({
                        old: old,
                        n: n,
                        change: change
                    });
                }
            }
        }
    }
    cheaperList.sort(function (a, b) {
        return a.change - b.change;
    });
    moreExpensiveList.sort(function (a, b) {
        return b.change - a.change;
    });
    return {
        cheaperList: cheaperList,
        moreExpensiveList: moreExpensiveList,
        criteria: CRITERIA
    };
};

const displaySubList = (subList, criteria) => {
    let old, n, change;
    for (let e of subList) {
        ({ old, n, change } = e);
        let priceVariation = (n.price / old.price).toFixed(2);
        console.log(n.name + " " + priceVariation);
        console.log(old[criteria] + " => " + n[criteria]);
        if (change < 1) {
            console.log("↘ " + change.toFixed(2));
        }
        else {
            console.log("↗ " + change.toFixed(2));
        }
    }
};

const displayResults = (res) => {
    let cheaperList, moreExpensiveList, criteria;
    ({ cheaperList, moreExpensiveList, criteria } = res);

    console.log("Based on " + criteria);
    console.log("============================");
    console.log("Cheaper");
    displaySubList(cheaperList, criteria);
    console.log("============================");
    console.log("More expensive");
    displaySubList(moreExpensiveList, criteria);
};

let path = ["test-2017-10-29", "test-2017-10-30"];
path = ["2017-09-24", "2017-11-4"];
Promise.all(path
    .map((x) => constructFilePath(x)
        .then(utils.readFromCsv)))
    .then(computeChangesEtf)
    .then(displayResults)
    .catch(console.err);<commit_msg>Data folder as a constant<commit_after>"use strict";
const utils = require("./utils");
const financials = require("./financials");
const constants = require("./constants");

const OUTPUT_FOLDER = "data/output/";
// utils.list_files(OUTPUT_FOLDER)
//     .then(console.log);

const constructFilePath = (date) => {
    return Promise.resolve(constants.EXPORT_FOLDER + date + ".csv");
};

const computeChangesEtf = (resultList) => {
    const CRITERIA = "forecastPe";
    let cheaperList = [];
    let moreExpensiveList = [];
    let ticketList = resultList[0].reduce( (total, elt) => {
        total.push(elt.name);
        return total;
    }, []);
    for (const ticket of ticketList) {
        const CRITERIA = "pe";
        let old = resultList[0].find(x => x.name === ticket);
        let n = resultList[1].find(x => x.name === ticket);
        if (old !== undefined && n !== undefined) {
            // let earningsUpdate = financials.haveEarningsChanged(old.price, old.pe, n.price, n.pe);
            // console.log(ticket + " " + priceVariation);
            if (!financials.areFloatEqual(old[CRITERIA], n[CRITERIA])) {
                let change = n[CRITERIA] / old[CRITERIA];
                if (old[CRITERIA] > n[CRITERIA]) {
                    cheaperList.push({
                        old: old,
                        n: n,
                        change: change
                    });
                }
                else {
                    moreExpensiveList.push({
                        old: old,
                        n: n,
                        change: change
                    });
                }
            }
        }
    }
    cheaperList.sort(function (a, b) {
        return a.change - b.change;
    });
    moreExpensiveList.sort(function (a, b) {
        return b.change - a.change;
    });
    return {
        cheaperList: cheaperList,
        moreExpensiveList: moreExpensiveList,
        criteria: CRITERIA
    };
};

const displaySubList = (subList, criteria) => {
    let old, n, change;
    for (let e of subList) {
        ({ old, n, change } = e);
        let priceVariation = (n.price / old.price).toFixed(2);
        console.log(n.name + " " + priceVariation);
        console.log(old[criteria] + " => " + n[criteria]);
        if (change < 1) {
            console.log("↘ " + change.toFixed(2));
        }
        else {
            console.log("↗ " + change.toFixed(2));
        }
    }
};

const displayResults = (res) => {
    let cheaperList, moreExpensiveList, criteria;
    ({ cheaperList, moreExpensiveList, criteria } = res);

    console.log("Based on " + criteria);
    console.log("============================");
    console.log("Cheaper");
    displaySubList(cheaperList, criteria);
    console.log("============================");
    console.log("More expensive");
    displaySubList(moreExpensiveList, criteria);
};

let path = ["test-2017-10-29", "test-2017-10-30"];
path = ["2017-09-24", "2017-11-4"];
Promise.all(path
    .map((x) => constructFilePath(x)
        .then(utils.readFromCsv)))
    .then(computeChangesEtf)
    .then(displayResults)
    .catch(console.err);<|endoftext|>


<commit_before>// Variables
var expand_documentation = false;

// Function: Anchor links creations
function anchorizejekyll()
{
  'use strict';

  var headingNodes = [];
  var results;
  var link;
  var tags = ['h2', 'h3', 'h4', 'h5', 'h6'];

  tags.forEach(function(tag){
    results = document.getElementsByTagName(tag);
    Array.prototype.push.apply(headingNodes, results);
  });

  headingNodes.forEach(function(node){
    link = document.createElement('a');
    link.innerHTML = ' ∞';
    link.href = '#' + node.getAttribute('id');
    link.style.visibility = "hidden";
    node.className = 'anchor-item';
    node.appendChild(link);
  });

}

// Function: Toggle all documentation details
function toggle_documentation(button)
{
  var details = document.querySelectorAll('details');
  expand_documentation = !expand_documentation;

  Array.from(details).forEach(function(obj, idx) {
    obj.open = expand_documentation;
  });
}

// Page loaded event
window.onload = function()
{
  // Start anchor links creations
  anchorizejekyll();
}
<commit_msg>docs: Automatically expand details section for anchors<commit_after>// Variables
var expand_documentation = false;

// Function: Anchor links creations
function anchorizejekyll()
{
  'use strict';

  var headingNodes = [];
  var results;
  var link;
  var tags = ['h2', 'h3', 'h4', 'h5', 'h6'];

  tags.forEach(function(tag){
    results = document.getElementsByTagName(tag);
    Array.prototype.push.apply(headingNodes, results);
  });

  headingNodes.forEach(function(node){
    link = document.createElement('a');
    link.innerHTML = ' ∞';
    link.href = '#' + node.getAttribute('id');
    link.style.visibility = "hidden";
    node.className = 'anchor-item';
    node.appendChild(link);
  });

}

// Function: Toggle all documentation details
function toggle_documentation(button)
{
  var details = document.querySelectorAll('details');
  expand_documentation = !expand_documentation;

  Array.from(details).forEach(function(obj, idx) {
    obj.open = expand_documentation;
  });
}

// Function: Expands details wrapping an anchor
function anchor_expands(id)
{
  // Find element by tag
  var title = document.getElementById(id);
  if (title) {

    // Find related details
    var details = title.closest("details");
    if (details) {

      // Expand related details
      details.open = true;
    }
  }
}

// Page loaded event
window.onload = function()
{
  // Start anchor links creations
  anchorizejekyll();

  // Acquire anchor tag
  var anchor_tag = window.location.hash.substr(1);

  // Apply anchor expands
  if (anchor_tag && anchor_tag.length !== 0) {
    anchor_expands(anchor_tag);
  }
}
<|endoftext|>


<commit_before>//main.js
/*var flights = [[{dest: "Poland", price: "242", carrier: "Ryan Air"},
                    {dest: "Poland", price: "60", carrier: "British Airways"},
                    {dest: "Poland", price: "260", carrier: "Joe's Hardware"}],
            [ {dest: "Bristol", price: "160", carrier: "British Airways"},
                    {dest: "Bristol", price: "20", carrier: "Joe's Hardware"}]];
*/
var flights;
var ready = false;
//get flight data
$.get( "/top_flights", function( data ) {
    flights = JSON.parse(data);
    populate_data();
});
$(document).ready( function () {

    $('#chooser a').click(function (e) {
	e.preventDefault();
	$(this).tab('show');
    if(!$("#tab-main").hasClass("active")){ $("#tab-main").removeClass("hide");}
        else { $("#tab-main").addClass("hide"); }
    if(!$("#tab-friends").hasClass("active")){ $("#tab-friends").removeClass("hide");}
        else { $("#tab-friends").addClass("hide"); }
    });

    $(".btn-modal").on("click", function () {
        //set modal to loading!
        if(ready) {
            reset_modal();
            $('#myModal').modal('toggle');
            //populate the modal here!!!
            populate_modal($(this).attr("location"));
        }
    });

    $(".friendlist tr").on("click", function() {
        //open up a modal with that locations prices
        if(ready) {
            reset_modal();
            $("#myModal").modal('toggle');
            flights.forEach(function(f) {
                if (f.name.indexOf($(this).children("span:last").text().split(",")[0])) {
                    //this is to find the appropriate flight data
                    console.log("city found");
                }
            });
        }
    });
    $('#search').on("keyup", function () {
        var q = $('#search').val();
        $(".friend-name").each(function () {
            if ($(this).text().toLowerCase().indexOf(q.toLowerCase()) != -1) {
                $(this).parent().parent().show();
            }
            else {
                $(this).parent().parent().hide();
            }
        });
    });
});
function reset_modal() {
    //resets the modal to a loading screen
    $("#modalTitle").text("Loading...");
    $("#flight-data tr").remove();
    $("#flight-data").html("
Date	Airline	Fly Now!
");
}
function populate_modal(city_id) {
    //this gets all relevant data for the modal
    var data = flights[city_id];
    $("#modalTitle").text(data.name[0]+", "+data.name[1]+", "+data.name[2]);
    $("#skyscanner-url").attr('href', flights[city_id]['url']);
    $("#flight-data tr:last").after(prepare_flight(data.cheapest_quote));
    data.quotes.forEach(function (entry) {
        $("#flight-data tr:last").after(prepare_flight(entry));
    });
    $(".date-tooltip").tooltip();
}
function populate_data() {
    ready = true;
    $("#Loading-Content").addClass("hidden");
    $("#first-location h1").html(flights[0].name[1] + "
£"+flights[0].cheapest_quote.MinPrice);
    $("#first-location p").html("Go and see "+flights[0].friends[0].name+", "+flights[0].friends[1].name+" and "+(flights[0].friends.length - 2)+" others in "+flights[0].name[1]+", "+flights[0].name[2]);
    $("#first-location button").attr("location", 0);
    $("#first-location").removeClass("hidden");
    $("#second-location h1").html(flights[1].name[1] + "
£"+flights[1].cheapest_quote.MinPrice);
    $("#second-location p").html("You have "+flights[1].friends.length+" friends near "+flights[1].name[1]+", including "+flights[1].friends[0].name+"");
    $("#second-location button").attr("location", 1);
    $("#second-location").removeClass("hidden");
    $("#third-location h1").html(flights[2].name[1] + "
£"+flights[2].cheapest_quote.MinPrice);
    $("#third-location p").html("Flights available to go and see "+flights[2].friends[0].name+" and "+(flights[2].friends.length -1)+" others in "+flights[2].name[1]);
    $("#third-location button").attr("location", 2);
    $("#third-location").removeClass("hidden");
}
function prepare_flight(dest) {
    var date = moment(dest.OutboundLeg.DepartureDate).format('ll');
    var ret_date = moment(dest.InboundLeg.DepartureDate).format('ll');
    var rel_date = moment(dest.OutboundLeg.DepartureDate).fromNow();
    var ss_date = moment(dest.OutboundLeg.DepartureDate).formay('YYYY-MM-DD');
    //add a 'time until' event using .fromNow() as a tooltip
    var r = "
";
    r += "

"+date+" to "+ret_date+"	";
    r += ""+dest.InboundLeg.Carrier+"	";
    r += "£"+dest.MinPrice+"	";
    r += "
";
    return r;
}
<commit_msg>Fixed typo duh<commit_after>//main.js
/*var flights = [[{dest: "Poland", price: "242", carrier: "Ryan Air"},
                    {dest: "Poland", price: "60", carrier: "British Airways"},
                    {dest: "Poland", price: "260", carrier: "Joe's Hardware"}],
            [ {dest: "Bristol", price: "160", carrier: "British Airways"},
                    {dest: "Bristol", price: "20", carrier: "Joe's Hardware"}]];
*/
var flights;
var ready = false;
//get flight data
$.get( "/top_flights", function( data ) {
    flights = JSON.parse(data);
    populate_data();
});
$(document).ready( function () {

    $('#chooser a').click(function (e) {
	e.preventDefault();
	$(this).tab('show');
    if(!$("#tab-main").hasClass("active")){ $("#tab-main").removeClass("hide");}
        else { $("#tab-main").addClass("hide"); }
    if(!$("#tab-friends").hasClass("active")){ $("#tab-friends").removeClass("hide");}
        else { $("#tab-friends").addClass("hide"); }
    });

    $(".btn-modal").on("click", function () {
        //set modal to loading!
        if(ready) {
            reset_modal();
            $('#myModal').modal('toggle');
            //populate the modal here!!!
            populate_modal($(this).attr("location"));
        }
    });

    $(".friendlist tr").on("click", function() {
        //open up a modal with that locations prices
        if(ready) {
            reset_modal();
            $("#myModal").modal('toggle');
            flights.forEach(function(f) {
                if (f.name.indexOf($(this).children("span:last").text().split(",")[0])) {
                    //this is to find the appropriate flight data
                    console.log("city found");
                }
            });
        }
    });
    $('#search').on("keyup", function () {
        var q = $('#search').val();
        $(".friend-name").each(function () {
            if ($(this).text().toLowerCase().indexOf(q.toLowerCase()) != -1) {
                $(this).parent().parent().show();
            }
            else {
                $(this).parent().parent().hide();
            }
        });
    });
});
function reset_modal() {
    //resets the modal to a loading screen
    $("#modalTitle").text("Loading...");
    $("#flight-data tr").remove();
    $("#flight-data").html("
Date	Airline	Fly Now!
");
}
function populate_modal(city_id) {
    //this gets all relevant data for the modal
    var data = flights[city_id];
    $("#modalTitle").text(data.name[0]+", "+data.name[1]+", "+data.name[2]);
    $("#skyscanner-url").attr('href', flights[city_id]['url']);
    $("#flight-data tr:last").after(prepare_flight(data.cheapest_quote));
    data.quotes.forEach(function (entry) {
        $("#flight-data tr:last").after(prepare_flight(entry));
    });
    $(".date-tooltip").tooltip();
}
function populate_data() {
    ready = true;
    $("#Loading-Content").addClass("hidden");
    $("#first-location h1").html(flights[0].name[1] + "
£"+flights[0].cheapest_quote.MinPrice);
    $("#first-location p").html("Go and see "+flights[0].friends[0].name+", "+flights[0].friends[1].name+" and "+(flights[0].friends.length - 2)+" others in "+flights[0].name[1]+", "+flights[0].name[2]);
    $("#first-location button").attr("location", 0);
    $("#first-location").removeClass("hidden");
    $("#second-location h1").html(flights[1].name[1] + "
£"+flights[1].cheapest_quote.MinPrice);
    $("#second-location p").html("You have "+flights[1].friends.length+" friends near "+flights[1].name[1]+", including "+flights[1].friends[0].name+"");
    $("#second-location button").attr("location", 1);
    $("#second-location").removeClass("hidden");
    $("#third-location h1").html(flights[2].name[1] + "
£"+flights[2].cheapest_quote.MinPrice);
    $("#third-location p").html("Flights available to go and see "+flights[2].friends[0].name+" and "+(flights[2].friends.length -1)+" others in "+flights[2].name[1]);
    $("#third-location button").attr("location", 2);
    $("#third-location").removeClass("hidden");
}
function prepare_flight(dest) {
    var date = moment(dest.OutboundLeg.DepartureDate).format('ll');
    var ret_date = moment(dest.InboundLeg.DepartureDate).format('ll');
    var rel_date = moment(dest.OutboundLeg.DepartureDate).fromNow();
    var ss_date = moment(dest.OutboundLeg.DepartureDate).format('YYYY-MM-DD');
    //add a 'time until' event using .fromNow() as a tooltip
    var r = "
";
    r += "

"+date+" to "+ret_date+"	";
    r += ""+dest.InboundLeg.Carrier+"	";
    r += "£"+dest.MinPrice+"	";
    r += "
";
    return r;
}
<|endoftext|>


<commit_before>/**
 *
 * Created by bryan.barnard on 9/26/15.
 */
(function simpleRequest() {
    var request = require('request');
    var request = request.defaults({jar:true});  //default all requests to use global jar object and be sessio naware
    require('request-debug')(request);

    var options = {
        uri: 'https://demonightlyus.service-now.com/api/now/table/cmdb_ci?sysparm_limit=1',
        method: 'GET',
        time:true, //causes each request to be timed
        auth: {
            'user': 'admin',
            'pass': 'snow2004',
            'sendImmediately': true
        },
        headers : {
            'accept': 'application/json',
            'connection': 'close'
        }
    };

    var callback = function (error, response, body) {
        if (!error && response.statusCode == 200) {
            console.log('elapsed_time: ' + response.elapsedTime);
        }
    };

    //make the request, note that subsequent requests will send cookies if cookies were received in first response
    request(options, callback);
})();<commit_msg>commit these change<commit_after>/**
 *
 * Created by bryan.barnard on 9/26/15.
 */
(function simpleRequest() {
    var request = require('request');
    var request = request.defaults({jar:true});  //default all requests to use global jar object and be sessio naware
    require('request-debug')(request);

    var options = {
        uri: 'https://demonightlyus.service-now.com/api/now/table/cmdb_ci?sysparm_limit=1',
        method: 'GET',
        time:true, //causes each request to be timed
        auth: {
            'user': 'admin',
            'pass': 'snow2004',
            'sendImmediately': true
        },
        headers : {
            'accept': 'application/json',
            'connection': 'close'
        }
    };

    var callback = function (error, response, body) {
        if (!error && response.statusCode == 200) {
            console.log('elapsed_time: ' + response.elapsedTime);
        }
    };

    //make the request, note that subsequent requests will send cookies if cookies were received in first response
    request(options, callback);
})();

//blah
<|endoftext|>


<commit_before>/**
 * Runtime.js
 *
 * Copyright 2013, Moxiecode Systems AB
 * Released under GPL License.
 *
 * License: http://www.plupload.com/license
 * Contributing: http://www.plupload.com/contributing
 */

define('moxie/runtime/Runtime', [
	"moxie/core/utils/Basic",
	"moxie/core/utils/Dom",
	"moxie/core/EventTarget"
], function(Basic, Dom, EventTarget) {
	var runtimeConstructors = {}, runtimes = {};

	/**
	Common set of methods and properties for every runtime instance

	@class Runtime

	@param {Object} options
	@param {String} type Sanitized name of the runtime
	@param {Object} [caps] Set of capabilities that differentiate specified runtime
	@param {Object} [clientCaps] Set of capabilities that implicitly switch the runtime to 'client' mode
	@param {String} [defaultMode='browser'] Default operational mode to choose if no required capabilities were requested
	*/
	function Runtime(options, type, caps, clientCaps, defaultMode) {
		/**
		Dispatched when runtime is initialized and ready.
		Results in RuntimeInit on a connected component.

		@event Init
		*/

		/**
		Dispatched when runtime fails to initialize.
		Results in RuntimeError on a connected component.

		@event Error
		*/

		var self = this
		, _shim
		, _uid = Basic.guid(type + '_')
		, _mode = null
		;

		/**
		Runtime (not native one) may operate in browser or client mode.

		@method _setMode
		@private
		@param {Object} [clientCaps] Set of capabilities that require client mode
		@param {Object} [defaultMode] The mode to switch to if clientCaps or requiredCaps are empty
		*/
		function _setMode(clientCaps, defaultMode) {
			var self = this
			, rc = options && options.required_caps
			;

			// mode can be effectively set only once
			if (_mode !== null) {
				return _mode;
			}

			if (rc && !Basic.isEmptyObj(clientCaps)) {
				// loop over required caps and check if they do require the same mode
				Basic.each(rc, function(value, cap) {
					if (clientCaps.hasOwnProperty(cap)) {
						var capMode = self.can(cap, value, clientCaps) ? 'client' : 'browser';
						// if cap requires conflicting mode - runtime cannot fulfill required caps
						if (_mode && _mode !== capMode) {
							return (_mode = false);
						} else {
							_mode = capMode;
						}
					}
				});
			}

			// if mode still not defined
			if (_mode === null) {
				_mode = defaultMode || 'browser';
			}

			// once we got the mode, test against all caps
			if (_mode && rc && !this.can(rc)) {
				_mode = false;
			}
		}

		// register runtime in private hash
		runtimes[_uid] = this;

		/**
		Default set of capabilities, which can be redifined later by specific runtime

		@private
		@property caps
		@type Object
		*/
		caps = Basic.extend({
			// Runtime can provide access to raw binary data of the file
			access_binary: false,
			// ... provide access to raw binary data of the image (image extension is optional)
			access_image_binary: false,
			// ... display binary data as thumbs for example
			display_media: false,
			// ... make cross-domain requests
			do_cors: false,
			// ... accept files dragged and dropped from the desktop
			drag_and_drop: false,
			// ... resize image (and manipulate it raw data of any file in general)
			resize_image: false,
			// ... periodically report how many bytes of total in the file were uploaded (loaded)
			report_upload_progress: false,
			// ... provide access to the headers of http response
			return_response_headers: false,
			// ... support response of specific type, which should be passed as an argument
			// e.g. runtime.can('return_response_type', 'blob')
			return_response_type: false,
			// ... return http status code of the response
			return_status_code: true,
			// ... send custom http header with the request
			send_custom_headers: false,
			// ... select whole folder in file browse dialog
			select_folder: false,
			// ... select multiple files at once in file browse dialog
			select_multiple: true,
			// ... send raw binary data, that is generated after image resizing or manipulation of other kind
			send_binary_string: false,
			// ... send cookies with http request and therefore retain session
			send_browser_cookies: true,
			// ... send data formatted as multipart/form-data
			send_multipart: true,
			// ... slice the file or blob to smaller parts
			slice_blob: false,
			// ... upload file without preloading it to memory, stream it out directly from disk
			stream_upload: false,
			// ... programmatically trigger file browse dialog
			summon_file_dialog: false,
			// ... upload file of specific size, size should be passed as argument
			// e.g. runtime.can('upload_filesize', '500mb')
			upload_filesize: true,
			// ... initiate http request with specific http method, method should be passed as argument
			// e.g. runtime.can('use_http_method', 'put')
			use_http_method: true
		}, caps);

		// small extension factory here (is meant to be extended with actual extensions constructors)
		_shim = (function() {
			var objpool = {};

			return {
				exec: function(uid, comp, fn, args) {
					if (_shim[comp]) {
						if (!objpool[uid]) {
							objpool[uid] = {
								context: this,
								instance: new _shim[comp]()
							};
						}

						if (objpool[uid].instance[fn]) {
							return objpool[uid].instance[fn].apply(this, args);
						}
					}
				},

				removeInstance: function(uid) {
					delete objpool[uid];
				},

				removeAllInstances: function() {
					var self = this;

					Basic.each(objpool, function(obj, uid) {
						if (Basic.typeOf(obj.instance.destroy) === 'function') {
							obj.instance.destroy.call(obj.context);
						}
						self.removeInstance(uid);
					});
				}
			};
		}());

		// public methods
		Basic.extend(this, {
			/**
			Specifies whether runtime instance was initialized or not

			@property initialized
			@type {Boolean}
			@default false
			*/
			initialized: false, // shims require this flag to stop initialization retries

			/**
			Unique ID of the runtime

			@property uid
			@type {String}
			*/
			uid: _uid,

			/**
			Runtime type (e.g. flash, html5, etc)

			@property type
			@type {String}
			*/
			type: type,

			/**
			id of the DOM container for the runtime (if available)

			@property shimid
			@type {String}
			*/
			shimid: _uid + '_container',

			/**
			Number of connected clients. If equal to zero, runtime can be destroyed

			@property clients
			@type {Number}
			*/
			clients: 0,

			/**
			Runtime initialization options

			@property options
			@type {Object}
			*/
			options: options,

			/**
			Checks if the runtime has specific capability

			@method can
			@param {String} cap Name of capability to check
			@param {Mixed} [value] If passed, capability should somehow correlate to the value
			@param {Object} [refCaps] Set of capabilities to check the specified cap against (defaults to internal set)
			@return {Boolean} true if runtime has such capability and false, if - not
			*/
			can: function(cap, value) {
				var refCaps = arguments[2] || caps;

				// if cap var is a comma-separated list of caps, convert it to object (key/value)
				if (Basic.typeOf(cap) === 'string' && Basic.typeOf(value) === 'undefined') {
					cap = (function(arr) {
						var obj = {};

						Basic.each(arr, function(key) {
							obj[key] = true; // since no value supplied, we assume user meant it to be - true
						});

						return obj;
					}(cap.split(',')));
				}

				if (Basic.typeOf(cap) === 'object') {
					for (var key in cap) {
						if (!this.can(key, cap[key], refCaps)) {
							return false;
						}
					}
					return true;
				}

				// check the individual cap
				var result;
				if (Basic.typeOf(refCaps[cap]) === 'function') {
					return refCaps[cap].call(this, value);
				} else {
					return (value === refCaps[cap]);
				}
			},

			/**
			Runtime (not native one) may operate in browser or client mode.

			@method getMode
			@return {String|Boolean} current mode or false, if none possible
			*/
			getMode: function() {
				return _mode || false;
			},

			/**
			Returns container for the runtime as DOM element

			@method getShimContainer
			@return {DOMElement}
			*/
			getShimContainer: function() {
				var container, shimContainer = Dom.get(this.shimid);

				// if no container for shim, create one
				if (!shimContainer) {
					container = this.options.container ? Dom.get(this.options.container) : document.body;

					// create shim container and insert it at an absolute position into the outer container
					shimContainer = document.createElement('div');
					shimContainer.id = this.shimid;
					shimContainer.className = 'moxie-shim moxie-shim-' + this.type;

					Basic.extend(shimContainer.style, {
						position: 'absolute',
						top: '0px',
						left: '0px',
						width: '1px',
						height: '1px',
						overflow: 'hidden'
					});

					container.appendChild(shimContainer);
					container = null;
				}

				return shimContainer;
			},

			/**
			Returns runtime as DOM element (if appropriate)

			@method getShim
			@return {DOMElement}
			*/
			getShim: function() {
				return _shim;
			},

			/**
			Invokes a method within the runtime itself (might differ across the runtimes)

			@method shimExec
			@param {Mixed} []
			@protected
			@return {Mixed} Depends on the action and component
			*/
			shimExec: function(component, action) {
				var args = [].slice.call(arguments, 2);
				return self.getShim().exec.call(this, this.uid, component, action, args);
			},

			/**
			Operaional interface that is used by components to invoke specific actions on the runtime
			(is invoked in the scope of component)

			@method exec
			@param {Mixed} []*
			@protected
			@return {Mixed} Depends on the action and component
			*/
			exec: function(component, action) { // this is called in the context of component, not runtime
				var args = [].slice.call(arguments, 2);

				if (self[component] && self[component][action]) {
					return self[component][action].apply(this, args);
				}
				return self.shimExec.apply(this, arguments);
			},

			/**
			Destroys the runtime (removes all events and deletes DOM structures)

			@method destroy
			*/
			destroy: function() {
				var shimContainer = Dom.get(this.shimid);
				if (shimContainer) {
					shimContainer.parentNode.removeChild(shimContainer);
				}

				if (_shim) {
					_shim.removeAllInstances();
				}

				this.unbindAll();
				delete runtimes[this.uid];
				_uid = self = _shim = _mode = shimContainer = null;
			}
		});

		_setMode.call(this, clientCaps, defaultMode);
	}

	/**
	Default order to try different runtime types

	@property order
	@type String
	@static
	*/
	Runtime.order = 'html5,flash,silverlight,html4';

	/**
	Retrieves runtime from private hash by it's uid

	@method getRuntime
	@private
	@static
	@param {String} uid Unique identifier of the runtime
	@return {Runtime|Boolean} Returns runtime, if it exists and false, if - not
	*/
	Runtime.getRuntime = function(uid) {
		return runtimes[uid] ? runtimes[uid] : false;
	};

	/**
	Register constructor for the Runtime of new (or perhaps modified) type

	@method addConstructor
	@static
	@param {String} type Runtime type (e.g. flash, html5, etc)
	@param {Function} construct Constructor for the Runtime type
	*/
	Runtime.addConstructor = function(type, constructor) {
		constructor.prototype = EventTarget.instance;
		runtimeConstructors[type] = constructor;
	};

	/**
	Get the constructor for the specified type.

	method getConstructor
	@static
	@param {String} type Runtime type (e.g. flash, html5, etc)
	@return {Function} Constructor for the Runtime type
	*/
	Runtime.getConstructor = function(type) {
		return runtimeConstructors[type] || null;
	};

	/**
	Get info about the runtime (uid, type, capabilities)

	@method getInfo
	@static
	@param {String} uid Unique identifier of the runtime
	@return {Mixed} Info object or null if runtime doesn't exist
	*/
	Runtime.getInfo = function(uid) {
		var runtime = Runtime.getRuntime(uid);

		if (runtime) {
			return {
				uid: runtime.uid,
				type: runtime.type,
				can: runtime.can
			};
		}

		return null;
	};

	/**
	Capability check that always returns true

	@private
	@static
	@return {True}
	*/
	Runtime.capTrue = function() {
		return true;
	};

	/**
	Capability check that always returns false

	@private
	@static
	@return {False}
	*/
	Runtime.capFalse = function() {
		return false;
	};

	return Runtime;
});
<commit_msg>Runtime: Remove extra variable definition.<commit_after>/**
 * Runtime.js
 *
 * Copyright 2013, Moxiecode Systems AB
 * Released under GPL License.
 *
 * License: http://www.plupload.com/license
 * Contributing: http://www.plupload.com/contributing
 */

define('moxie/runtime/Runtime', [
	"moxie/core/utils/Basic",
	"moxie/core/utils/Dom",
	"moxie/core/EventTarget"
], function(Basic, Dom, EventTarget) {
	var runtimeConstructors = {}, runtimes = {};

	/**
	Common set of methods and properties for every runtime instance

	@class Runtime

	@param {Object} options
	@param {String} type Sanitized name of the runtime
	@param {Object} [caps] Set of capabilities that differentiate specified runtime
	@param {Object} [clientCaps] Set of capabilities that implicitly switch the runtime to 'client' mode
	@param {String} [defaultMode='browser'] Default operational mode to choose if no required capabilities were requested
	*/
	function Runtime(options, type, caps, clientCaps, defaultMode) {
		/**
		Dispatched when runtime is initialized and ready.
		Results in RuntimeInit on a connected component.

		@event Init
		*/

		/**
		Dispatched when runtime fails to initialize.
		Results in RuntimeError on a connected component.

		@event Error
		*/

		var self = this
		, _shim
		, _uid = Basic.guid(type + '_')
		, _mode = null
		;

		/**
		Runtime (not native one) may operate in browser or client mode.

		@method _setMode
		@private
		@param {Object} [clientCaps] Set of capabilities that require client mode
		@param {Object} [defaultMode] The mode to switch to if clientCaps or requiredCaps are empty
		*/
		function _setMode(clientCaps, defaultMode) {
			var self = this
			, rc = options && options.required_caps
			;

			// mode can be effectively set only once
			if (_mode !== null) {
				return _mode;
			}

			if (rc && !Basic.isEmptyObj(clientCaps)) {
				// loop over required caps and check if they do require the same mode
				Basic.each(rc, function(value, cap) {
					if (clientCaps.hasOwnProperty(cap)) {
						var capMode = self.can(cap, value, clientCaps) ? 'client' : 'browser';
						// if cap requires conflicting mode - runtime cannot fulfill required caps
						if (_mode && _mode !== capMode) {
							return (_mode = false);
						} else {
							_mode = capMode;
						}
					}
				});
			}

			// if mode still not defined
			if (_mode === null) {
				_mode = defaultMode || 'browser';
			}

			// once we got the mode, test against all caps
			if (_mode && rc && !this.can(rc)) {
				_mode = false;
			}
		}

		// register runtime in private hash
		runtimes[_uid] = this;

		/**
		Default set of capabilities, which can be redifined later by specific runtime

		@private
		@property caps
		@type Object
		*/
		caps = Basic.extend({
			// Runtime can provide access to raw binary data of the file
			access_binary: false,
			// ... provide access to raw binary data of the image (image extension is optional)
			access_image_binary: false,
			// ... display binary data as thumbs for example
			display_media: false,
			// ... make cross-domain requests
			do_cors: false,
			// ... accept files dragged and dropped from the desktop
			drag_and_drop: false,
			// ... resize image (and manipulate it raw data of any file in general)
			resize_image: false,
			// ... periodically report how many bytes of total in the file were uploaded (loaded)
			report_upload_progress: false,
			// ... provide access to the headers of http response
			return_response_headers: false,
			// ... support response of specific type, which should be passed as an argument
			// e.g. runtime.can('return_response_type', 'blob')
			return_response_type: false,
			// ... return http status code of the response
			return_status_code: true,
			// ... send custom http header with the request
			send_custom_headers: false,
			// ... select whole folder in file browse dialog
			select_folder: false,
			// ... select multiple files at once in file browse dialog
			select_multiple: true,
			// ... send raw binary data, that is generated after image resizing or manipulation of other kind
			send_binary_string: false,
			// ... send cookies with http request and therefore retain session
			send_browser_cookies: true,
			// ... send data formatted as multipart/form-data
			send_multipart: true,
			// ... slice the file or blob to smaller parts
			slice_blob: false,
			// ... upload file without preloading it to memory, stream it out directly from disk
			stream_upload: false,
			// ... programmatically trigger file browse dialog
			summon_file_dialog: false,
			// ... upload file of specific size, size should be passed as argument
			// e.g. runtime.can('upload_filesize', '500mb')
			upload_filesize: true,
			// ... initiate http request with specific http method, method should be passed as argument
			// e.g. runtime.can('use_http_method', 'put')
			use_http_method: true
		}, caps);

		// small extension factory here (is meant to be extended with actual extensions constructors)
		_shim = (function() {
			var objpool = {};

			return {
				exec: function(uid, comp, fn, args) {
					if (_shim[comp]) {
						if (!objpool[uid]) {
							objpool[uid] = {
								context: this,
								instance: new _shim[comp]()
							};
						}

						if (objpool[uid].instance[fn]) {
							return objpool[uid].instance[fn].apply(this, args);
						}
					}
				},

				removeInstance: function(uid) {
					delete objpool[uid];
				},

				removeAllInstances: function() {
					var self = this;

					Basic.each(objpool, function(obj, uid) {
						if (Basic.typeOf(obj.instance.destroy) === 'function') {
							obj.instance.destroy.call(obj.context);
						}
						self.removeInstance(uid);
					});
				}
			};
		}());

		// public methods
		Basic.extend(this, {
			/**
			Specifies whether runtime instance was initialized or not

			@property initialized
			@type {Boolean}
			@default false
			*/
			initialized: false, // shims require this flag to stop initialization retries

			/**
			Unique ID of the runtime

			@property uid
			@type {String}
			*/
			uid: _uid,

			/**
			Runtime type (e.g. flash, html5, etc)

			@property type
			@type {String}
			*/
			type: type,

			/**
			id of the DOM container for the runtime (if available)

			@property shimid
			@type {String}
			*/
			shimid: _uid + '_container',

			/**
			Number of connected clients. If equal to zero, runtime can be destroyed

			@property clients
			@type {Number}
			*/
			clients: 0,

			/**
			Runtime initialization options

			@property options
			@type {Object}
			*/
			options: options,

			/**
			Checks if the runtime has specific capability

			@method can
			@param {String} cap Name of capability to check
			@param {Mixed} [value] If passed, capability should somehow correlate to the value
			@param {Object} [refCaps] Set of capabilities to check the specified cap against (defaults to internal set)
			@return {Boolean} true if runtime has such capability and false, if - not
			*/
			can: function(cap, value) {
				var refCaps = arguments[2] || caps;

				// if cap var is a comma-separated list of caps, convert it to object (key/value)
				if (Basic.typeOf(cap) === 'string' && Basic.typeOf(value) === 'undefined') {
					cap = (function(arr) {
						var obj = {};

						Basic.each(arr, function(key) {
							obj[key] = true; // since no value supplied, we assume user meant it to be - true
						});

						return obj;
					}(cap.split(',')));
				}

				if (Basic.typeOf(cap) === 'object') {
					for (var key in cap) {
						if (!this.can(key, cap[key], refCaps)) {
							return false;
						}
					}
					return true;
				}

				// check the individual cap
				if (Basic.typeOf(refCaps[cap]) === 'function') {
					return refCaps[cap].call(this, value);
				} else {
					return (value === refCaps[cap]);
				}
			},

			/**
			Runtime (not native one) may operate in browser or client mode.

			@method getMode
			@return {String|Boolean} current mode or false, if none possible
			*/
			getMode: function() {
				return _mode || false;
			},

			/**
			Returns container for the runtime as DOM element

			@method getShimContainer
			@return {DOMElement}
			*/
			getShimContainer: function() {
				var container, shimContainer = Dom.get(this.shimid);

				// if no container for shim, create one
				if (!shimContainer) {
					container = this.options.container ? Dom.get(this.options.container) : document.body;

					// create shim container and insert it at an absolute position into the outer container
					shimContainer = document.createElement('div');
					shimContainer.id = this.shimid;
					shimContainer.className = 'moxie-shim moxie-shim-' + this.type;

					Basic.extend(shimContainer.style, {
						position: 'absolute',
						top: '0px',
						left: '0px',
						width: '1px',
						height: '1px',
						overflow: 'hidden'
					});

					container.appendChild(shimContainer);
					container = null;
				}

				return shimContainer;
			},

			/**
			Returns runtime as DOM element (if appropriate)

			@method getShim
			@return {DOMElement}
			*/
			getShim: function() {
				return _shim;
			},

			/**
			Invokes a method within the runtime itself (might differ across the runtimes)

			@method shimExec
			@param {Mixed} []
			@protected
			@return {Mixed} Depends on the action and component
			*/
			shimExec: function(component, action) {
				var args = [].slice.call(arguments, 2);
				return self.getShim().exec.call(this, this.uid, component, action, args);
			},

			/**
			Operaional interface that is used by components to invoke specific actions on the runtime
			(is invoked in the scope of component)

			@method exec
			@param {Mixed} []*
			@protected
			@return {Mixed} Depends on the action and component
			*/
			exec: function(component, action) { // this is called in the context of component, not runtime
				var args = [].slice.call(arguments, 2);

				if (self[component] && self[component][action]) {
					return self[component][action].apply(this, args);
				}
				return self.shimExec.apply(this, arguments);
			},

			/**
			Destroys the runtime (removes all events and deletes DOM structures)

			@method destroy
			*/
			destroy: function() {
				var shimContainer = Dom.get(this.shimid);
				if (shimContainer) {
					shimContainer.parentNode.removeChild(shimContainer);
				}

				if (_shim) {
					_shim.removeAllInstances();
				}

				this.unbindAll();
				delete runtimes[this.uid];
				_uid = self = _shim = _mode = shimContainer = null;
			}
		});

		_setMode.call(this, clientCaps, defaultMode);
	}

	/**
	Default order to try different runtime types

	@property order
	@type String
	@static
	*/
	Runtime.order = 'html5,flash,silverlight,html4';

	/**
	Retrieves runtime from private hash by it's uid

	@method getRuntime
	@private
	@static
	@param {String} uid Unique identifier of the runtime
	@return {Runtime|Boolean} Returns runtime, if it exists and false, if - not
	*/
	Runtime.getRuntime = function(uid) {
		return runtimes[uid] ? runtimes[uid] : false;
	};

	/**
	Register constructor for the Runtime of new (or perhaps modified) type

	@method addConstructor
	@static
	@param {String} type Runtime type (e.g. flash, html5, etc)
	@param {Function} construct Constructor for the Runtime type
	*/
	Runtime.addConstructor = function(type, constructor) {
		constructor.prototype = EventTarget.instance;
		runtimeConstructors[type] = constructor;
	};

	/**
	Get the constructor for the specified type.

	method getConstructor
	@static
	@param {String} type Runtime type (e.g. flash, html5, etc)
	@return {Function} Constructor for the Runtime type
	*/
	Runtime.getConstructor = function(type) {
		return runtimeConstructors[type] || null;
	};

	/**
	Get info about the runtime (uid, type, capabilities)

	@method getInfo
	@static
	@param {String} uid Unique identifier of the runtime
	@return {Mixed} Info object or null if runtime doesn't exist
	*/
	Runtime.getInfo = function(uid) {
		var runtime = Runtime.getRuntime(uid);

		if (runtime) {
			return {
				uid: runtime.uid,
				type: runtime.type,
				can: runtime.can
			};
		}

		return null;
	};

	/**
	Capability check that always returns true

	@private
	@static
	@return {True}
	*/
	Runtime.capTrue = function() {
		return true;
	};

	/**
	Capability check that always returns false

	@private
	@static
	@return {False}
	*/
	Runtime.capFalse = function() {
		return false;
	};

	return Runtime;
});
<|endoftext|>