<commit_before>import { triggerUpdate } from '../client/update'
import { isUndefined, isFunction } from '../utils/is-type'
import { ensuredPush } from '../utils/ensure'
import { hasMetaInfo } from './meta-helpers'
import { addNavGuards } from './nav-guards'

let appId = 1

export default function createMixin(Vue, options) {
  // for which Vue lifecycle hooks should the metaInfo be refreshed
  const updateOnLifecycleHook = ['activated', 'deactivated', 'beforeMount']

  // watch for client side component updates
  return {
    beforeCreate() {
      Object.defineProperty(this, '_hasMetaInfo', {
        configurable: true,
        get() {
          // Show deprecation warning once when devtools enabled
          if (Vue.config.devtools && !this.$root._vueMeta.hasMetaInfoDeprecationWarningShown) {
            console.warn('VueMeta DeprecationWarning: _hasMetaInfo has been deprecated and will be removed in a future version. Please use hasMetaInfo(vm) instead') // eslint-disable-line no-console
            this.$root._vueMeta.hasMetaInfoDeprecationWarningShown = true
          }
          return hasMetaInfo(this)
        }
      })

      // Add a marker to know if it uses metaInfo
      // _vnode is used to know that it's attached to a real component
      // useful if we use some mixin to add some meta tags (like nuxt-i18n)
      if (!isUndefined(this.$options[options.keyName]) && this.$options[options.keyName] !== null) {
        if (!this.$root._vueMeta) {
          this.$root._vueMeta = { appId }
          appId++
        }

        // to speed up updates we keep track of branches which have a component with vue-meta info defined
        // if _vueMeta = true it has info, if _vueMeta = false a child has info
        if (!this._vueMeta) {
          this._vueMeta = true

          let p = this.$parent
          while (p && p !== this.$root) {
            if (isUndefined(p._vueMeta)) {
              p._vueMeta = false
            }
            p = p.$parent
          }
        }

        // coerce function-style metaInfo to a computed prop so we can observe
        // it on creation
        if (isFunction(this.$options[options.keyName])) {
          if (!this.$options.computed) {
            this.$options.computed = {}
          }
          this.$options.computed.$metaInfo = this.$options[options.keyName]

          if (!this.$isServer) {
            // if computed $metaInfo exists, watch it for updates & trigger a refresh
            // when it changes (i.e. automatically handle async actions that affect metaInfo)
            // credit for this suggestion goes to [Sébastien Chopin](https://github.com/Atinux)
            ensuredPush(this.$options, 'created', () => {
              this.$watch('$metaInfo', function () {
                triggerUpdate(this, 'watcher')
              })
            })
          }
        }

        // force an initial refresh on page load and prevent other lifecycleHooks
        // to triggerUpdate until this initial refresh is finished
        // this is to make sure that when a page is opened in an inactive tab which
        // has throttled rAF/timers we still immediately set the page title
        if (isUndefined(this.$root._vueMeta.initialized)) {
          this.$root._vueMeta.initialized = this.$isServer

          if (!this.$root._vueMeta.initialized) {
            ensuredPush(this.$options, 'beforeMount', () => {
              // if this Vue-app was server rendered, set the appId to 'ssr'
              // only one SSR app per page is supported
              if (this.$root.$el && this.$root.$el.hasAttribute('data-server-rendered')) {
                this.$root._vueMeta.appId = 'ssr'
              }
            })

            // we use the mounted hook here as on page load
            ensuredPush(this.$options, 'mounted', () => {
              if (!this.$root._vueMeta.initialized) {
                // used in triggerUpdate to check if a change was triggered
                // during initialization
                this.$root._vueMeta.initializing = true

                // refresh meta in nextTick so all child components have loaded
                this.$nextTick(function () {
                  const { tags, metaInfo } = this.$root.$meta().refresh()

                  // After ssr hydration (identifier by tags === false) check
                  // if initialized was set to null in triggerUpdate. That'd mean
                  // that during initilazation changes where triggered which need
                  // to be applied OR a metaInfo watcher was triggered before the
                  // current hook was called
                  // (during initialization all changes are blocked)
                  if (tags === false && this.$root._vueMeta.initialized === null) {
                    this.$nextTick(() => triggerUpdate(this, 'initializing'))
                  }

                  this.$root._vueMeta.initialized = true
                  delete this.$root._vueMeta.initializing

                  // add the navigation guards if they havent been added yet
                  // they are needed for the afterNavigation callback
                  if (!options.refreshOnceOnNavigation && metaInfo.afterNavigation) {
                    addNavGuards(this)
                  }
                })
              }
            })

            // add the navigation guards if requested
            if (options.refreshOnceOnNavigation) {
              addNavGuards(this)
            }
          }
        }

        // do not trigger refresh on the server side
        if (!this.$isServer) {
          // no need to add this hooks on server side
          updateOnLifecycleHook.forEach((lifecycleHook) => {
            ensuredPush(this.$options, lifecycleHook, () => triggerUpdate(this, lifecycleHook))
          })

          // re-render meta data when returning from a child component to parent
          ensuredPush(this.$options, 'destroyed', () => {
            // Wait that element is hidden before refreshing meta tags (to support animations)
            const interval = setInterval(() => {
              if (this.$el && this.$el.offsetParent !== null) {
                /* istanbul ignore next line */
                return
              }

              clearInterval(interval)

              if (!this.$parent) {
                /* istanbul ignore next line */
                return
              }

              triggerUpdate(this, 'destroyed')
            }, 50)
          })
        }
      }
    }
  }
}
<commit_msg>fix: ensure hasAttribute exists on $root.$el<commit_after>import { triggerUpdate } from '../client/update'
import { isUndefined, isFunction } from '../utils/is-type'
import { ensuredPush } from '../utils/ensure'
import { hasMetaInfo } from './meta-helpers'
import { addNavGuards } from './nav-guards'

let appId = 1

export default function createMixin(Vue, options) {
  // for which Vue lifecycle hooks should the metaInfo be refreshed
  const updateOnLifecycleHook = ['activated', 'deactivated', 'beforeMount']

  // watch for client side component updates
  return {
    beforeCreate() {
      Object.defineProperty(this, '_hasMetaInfo', {
        configurable: true,
        get() {
          // Show deprecation warning once when devtools enabled
          if (Vue.config.devtools && !this.$root._vueMeta.hasMetaInfoDeprecationWarningShown) {
            console.warn('VueMeta DeprecationWarning: _hasMetaInfo has been deprecated and will be removed in a future version. Please use hasMetaInfo(vm) instead') // eslint-disable-line no-console
            this.$root._vueMeta.hasMetaInfoDeprecationWarningShown = true
          }
          return hasMetaInfo(this)
        }
      })

      // Add a marker to know if it uses metaInfo
      // _vnode is used to know that it's attached to a real component
      // useful if we use some mixin to add some meta tags (like nuxt-i18n)
      if (!isUndefined(this.$options[options.keyName]) && this.$options[options.keyName] !== null) {
        if (!this.$root._vueMeta) {
          this.$root._vueMeta = { appId }
          appId++
        }

        // to speed up updates we keep track of branches which have a component with vue-meta info defined
        // if _vueMeta = true it has info, if _vueMeta = false a child has info
        if (!this._vueMeta) {
          this._vueMeta = true

          let p = this.$parent
          while (p && p !== this.$root) {
            if (isUndefined(p._vueMeta)) {
              p._vueMeta = false
            }
            p = p.$parent
          }
        }

        // coerce function-style metaInfo to a computed prop so we can observe
        // it on creation
        if (isFunction(this.$options[options.keyName])) {
          if (!this.$options.computed) {
            this.$options.computed = {}
          }
          this.$options.computed.$metaInfo = this.$options[options.keyName]

          if (!this.$isServer) {
            // if computed $metaInfo exists, watch it for updates & trigger a refresh
            // when it changes (i.e. automatically handle async actions that affect metaInfo)
            // credit for this suggestion goes to [Sébastien Chopin](https://github.com/Atinux)
            ensuredPush(this.$options, 'created', () => {
              this.$watch('$metaInfo', function () {
                triggerUpdate(this, 'watcher')
              })
            })
          }
        }

        // force an initial refresh on page load and prevent other lifecycleHooks
        // to triggerUpdate until this initial refresh is finished
        // this is to make sure that when a page is opened in an inactive tab which
        // has throttled rAF/timers we still immediately set the page title
        if (isUndefined(this.$root._vueMeta.initialized)) {
          this.$root._vueMeta.initialized = this.$isServer

          if (!this.$root._vueMeta.initialized) {
            ensuredPush(this.$options, 'beforeMount', () => {
              // if this Vue-app was server rendered, set the appId to 'ssr'
              // only one SSR app per page is supported
              if (this.$root.$el && this.$root.$el.hasAttribute && this.$root.$el.hasAttribute('data-server-rendered')) {
                this.$root._vueMeta.appId = 'ssr'
              }
            })

            // we use the mounted hook here as on page load
            ensuredPush(this.$options, 'mounted', () => {
              if (!this.$root._vueMeta.initialized) {
                // used in triggerUpdate to check if a change was triggered
                // during initialization
                this.$root._vueMeta.initializing = true

                // refresh meta in nextTick so all child components have loaded
                this.$nextTick(function () {
                  const { tags, metaInfo } = this.$root.$meta().refresh()

                  // After ssr hydration (identifier by tags === false) check
                  // if initialized was set to null in triggerUpdate. That'd mean
                  // that during initilazation changes where triggered which need
                  // to be applied OR a metaInfo watcher was triggered before the
                  // current hook was called
                  // (during initialization all changes are blocked)
                  if (tags === false && this.$root._vueMeta.initialized === null) {
                    this.$nextTick(() => triggerUpdate(this, 'initializing'))
                  }

                  this.$root._vueMeta.initialized = true
                  delete this.$root._vueMeta.initializing

                  // add the navigation guards if they havent been added yet
                  // they are needed for the afterNavigation callback
                  if (!options.refreshOnceOnNavigation && metaInfo.afterNavigation) {
                    addNavGuards(this)
                  }
                })
              }
            })

            // add the navigation guards if requested
            if (options.refreshOnceOnNavigation) {
              addNavGuards(this)
            }
          }
        }

        // do not trigger refresh on the server side
        if (!this.$isServer) {
          // no need to add this hooks on server side
          updateOnLifecycleHook.forEach((lifecycleHook) => {
            ensuredPush(this.$options, lifecycleHook, () => triggerUpdate(this, lifecycleHook))
          })

          // re-render meta data when returning from a child component to parent
          ensuredPush(this.$options, 'destroyed', () => {
            // Wait that element is hidden before refreshing meta tags (to support animations)
            const interval = setInterval(() => {
              if (this.$el && this.$el.offsetParent !== null) {
                /* istanbul ignore next line */
                return
              }

              clearInterval(interval)

              if (!this.$parent) {
                /* istanbul ignore next line */
                return
              }

              triggerUpdate(this, 'destroyed')
            }, 50)
          })
        }
      }
    }
  }
}
<|endoftext|>


<commit_before>'use strict';

var assign             = require('es5-ext/object/assign')
  , d                  = require('d/d')
  , autoBind           = require('d/auto-bind')
  , toStringTagSymbol  = require('es6-symbol').toStringTag
  , ee                 = require('event-emitter/lib/core')
  , is                 = require('./is-observable-value')
  , isObservableSymbol = require('./symbol-is-observable')

  , defineProperty = Object.defineProperty
  , Observable;

module.exports = Observable = function (value) {
	if (!(this instanceof Observable)) return new Observable(value);
	if (is(value)) {
		defineProperty(this, '__link__', d(value));
		value.on('change', this._mutableListener);
		value = value.value;
	}
	defineProperty(this, '__value__', d('w', value));
};
Object.defineProperties(ee(Observable.prototype), assign({
	value: d.gs(function () { return this.__value__; }, function (nu) {
		var old = this.__value__, isOldObservable = this.hasOwnProperty('__link__');
		if (isOldObservable) {
			if (nu === this.__link__) return;
			this.__link__.off('change', this._mutableListener);
		}
		if (is(nu)) {
			if (isOldObservable) this.__link__ = nu;
			else defineProperty(this, '__link__', d(nu));
			nu.on('change', this._mutableListener);
			this.__value__ = nu = nu.value;
		} else {
			if (isOldObservable) delete this.__link__;
			this.__value__ = nu;
		}
		if (nu !== old) {
			this.emit('change', {
				type: 'change',
				newValue: nu,
				oldValue: old
			});
		}
	}),
	toString: d(function () { return String(this.__value__); })
}, autoBind({
	_mutableListener: d('', function (event) {
		this.__value__ = event.newValue;
		this.emit('change', event);
	})
})));
defineProperty(Observable.prototype, toStringTagSymbol,
	d('c', 'ObservableValue'));
defineProperty(Observable.prototype, isObservableSymbol, d('', true));
<commit_msg>Support events hold<commit_after>'use strict';

var assign             = require('es5-ext/object/assign-multiple')
  , d                  = require('d/d')
  , autoBind           = require('d/auto-bind')
  , lazy               = require('d/lazy')
  , toStringTagSymbol  = require('es6-symbol').toStringTag
  , ee                 = require('event-emitter/lib/core')
  , is                 = require('./is-observable-value')
  , isObservableSymbol = require('./symbol-is-observable')

  , defineProperty = Object.defineProperty
  , Observable;

module.exports = Observable = function (value) {
	if (!(this instanceof Observable)) return new Observable(value);
	if (is(value)) {
		defineProperty(this, '__link__', d(value));
		value.on('change', this._mutableListener);
		value = value.value;
	}
	defineProperty(this, '__value__', d('w', value));
};
Object.defineProperties(ee(Observable.prototype), assign({
	value: d.gs(function () { return this.__value__; }, function (nu) {
		var old = this.__value__, isOldObservable = this.hasOwnProperty('__link__');
		if (isOldObservable) {
			if (nu === this.__link__) return;
			this.__link__.off('change', this._mutableListener);
		}
		if (is(nu)) {
			if (isOldObservable) this.__link__ = nu;
			else defineProperty(this, '__link__', d(nu));
			nu.on('change', this._mutableListener);
			this.__value__ = nu = nu.value;
		} else {
			if (isOldObservable) delete this.__link__;
			this.__value__ = nu;
		}
		if (nu !== old) {
			if (this.__hold__) {
				if (this.__event__) this.__event__.newValue = nu;
				else this.__event__ = { newValue: nu, oldValue: old };
				return;
			}
			this.emit('change', { type: 'change', newValue: nu, oldValue: old });
		}
	}),
	toString: d(function () { return String(this.__value__); }),
	_hold_: d.gs(function () { return this.__hold__; }, function (value) {
		var event;
		this.__hold__ = value;
		if (value) return;
		event = this.__event__;
		if (!event) return;
		this.__event__ = null;
		event.type = 'change';
		this.emit('change', event);
	})
}, autoBind({
	_mutableListener: d('', function (event) {
		this.__value__ = event.newValue;
		this.emit('change', event);
	})
}), lazy({
	__hold__: d('w', 0),
	__event__: d('w', null)
})));
defineProperty(Observable.prototype, toStringTagSymbol,
	d('c', 'ObservableValue'));
defineProperty(Observable.prototype, isObservableSymbol, d('', true));
<|endoftext|>


<commit_before>/**
 * The roiMap is an array of the size of the original image data that contains
 * positive and negative numbers. When the number is common, it corresponds
 * to one region of interest (ROI)
 *
 * @class RoiMap
 */

export default class RoiMap {
    constructor(parent, data) {
        this.parent = parent;
        this.width = parent.width;
        this.height = parent.height;
        this.data = data;
        this.negative = 0;
        this.positive = 0;
    }

    get total() {
        return this.negative + this.positive;
    }
}
<commit_msg>Update RoiMap.js<commit_after>/**
 * The roiMap is an array of the size of the original image data that contains
 * positive and negative numbers. When the number is common, it corresponds
 * to one region of interest (ROI)
 *
 * @class RoiMap
 * @private
 */

export default class RoiMap {
    constructor(parent, data) {
        this.parent = parent;
        this.width = parent.width;
        this.height = parent.height;
        this.data = data;
        this.negative = 0;
        this.positive = 0;
    }

    get total() {
        return this.negative + this.positive;
    }
}
<|endoftext|>


<commit_before><commit_msg>refactor: reset platform config to {} during initRepo<commit_after><|endoftext|>


<commit_before>function GeolocationService ($http, $log, $q, ConfigService, ErrorHandler) {

    var GeolocationService = {};

    GeolocationService.asyncGetCurrentPosition = function () {
        var deferred = $q.defer();
        if (navigator.geolocation) {
            navigator.geolocation.getCurrentPosition(function (position) {
                deferred.resolve(position);
            }, function () {
                ErrorHandler.handleNoGeolocation(true);
                deferred.reject();
            });
        }
        else {
            ErrorHandler.handleNoGeolocation(false);
            deferred.reject();
        }
        return deferred.promise;
    };

    GeolocationService.asyncGetUserPositions = function (options) {
        var deferred = $q.defer();
        GeolocationService.asyncGetCurrentPosition().then(function (position) {
            var data = {
                latitude: position.coords.latitude,
                longitude: position.coords.longitude,
                options: options
            };
            $http.post(ConfigService.SERVER_URL + '/getUsers', data).
                success(function (data, status, headers, config) {
                    deferred.resolve(data);
                }).
                error(function (data, status, headers, config) {
                    deferred.reject(new HttpError(status, 'get users request failed'));
                });
        }, function () {
            deferred.reject();
        });
        return deferred.promise;
    };

    return GeolocationService;
}

angular.module('spacebox').factory('GeolocationService',
    ['$http', '$log', '$q', 'ConfigService', 'ErrorHandler', GeolocationService]);
<commit_msg>GeolocationService code refactoring.<commit_after>function GeolocationService ($http, $log, $q, ConfigService, ErrorHandler) {

    var GeolocationService = {};

    GeolocationService.asyncGetCurrentPosition = function () {
        var deferred = $q.defer();
        if (navigator.geolocation) {
            navigator.geolocation.getCurrentPosition(function (position) {
                deferred.resolve(position);
            }, function () {
                ErrorHandler.handleNoGeolocation(true);
                deferred.reject();
            });
        }
        else {
            ErrorHandler.handleNoGeolocation(false);
            deferred.reject();
        }
        return deferred.promise;
    };

    GeolocationService.asyncGetUserPositions = function (options) {
        return GeolocationService.asyncGetCurrentPosition().then(function (position) {
            var params = {
                latitude: position.coords.latitude,
                longitude: position.coords.longitude,
                options: options
            };
            return $http.post(ConfigService.SERVER_URL + '/getUsers', params).then(
                function __success (response) {
                    $log.debug('Get near users ', response.data);
                    return response.data;
                },
                function __error (response) {
                    return $q.reject(new HttpError(response.status, 'get users request failed'));
                });
        });
    };

    return GeolocationService;
}

angular.module('spacebox').factory('GeolocationService',
    ['$http', '$log', '$q', 'ConfigService', 'ErrorHandler', GeolocationService]);
<|endoftext|>


<commit_before>"use strict";

angular.module("firebase", []).value("Firebase", Firebase);

// Implicit syncing. angularFire binds a model to $scope and keeps the data
// synchronized with a Firebase location both ways.
// TODO: Optimize to use child events instead of whole "value".
angular.module("firebase").factory("angularFire", ["$q", "$parse", "$timeout",
  function($q, $parse, $timeout) {
    return function(ref, scope, name, ret) {
      var af = new AngularFire($q, $parse, $timeout, ref);
      return af.associate(scope, name, ret);
    };
  }
]);

function AngularFire($q, $parse, $timeout, ref) {
  this._q = $q;
  this._parse = $parse;
  this._timeout = $timeout;

  this._initial = true;
  this._remoteValue = false;

  if (typeof ref == "string") {
    this._fRef = new Firebase(ref);
  } else {
    this._fRef = ref;
  }
}
AngularFire.prototype = {
  disassociate: function() {
    var self = this;
    if (self._unregister) {
      self._unregister();
    }
    this._fRef.off("value");
  },
  associate: function($scope, name, ret) {
    var self = this;
    if (ret == undefined) {
      ret = [];
    }
    var deferred = this._q.defer();
    var promise = deferred.promise;
    this._fRef.on("value", function(snap) {
      var resolve = false;
      if (deferred) {
        resolve = deferred;
        deferred = false;
      }
      self._remoteValue = ret;
      if (snap && snap.val() != undefined) {
        var val = snap.val();
        if (typeof val != typeof ret) {
          self._log("Error: type mismatch");
          return;
        }
        // Also distinguish between objects and arrays.
        var check = Object.prototype.toString;
        if (check.call(ret) != check.call(val)) {
          self._log("Error: type mismatch");
          return;
        }
        self._remoteValue = angular.copy(val);
        if (angular.equals(val, self._parse(name)($scope))) {
          return;
        }
      }
      self._timeout(function() {
        self._resolve($scope, name, resolve, self._remoteValue)
      });
    });
    return promise;
  },
  _log: function(msg) {
    if (console && console.log) {
      console.log(msg);
    }
  },
  _resolve: function($scope, name, deferred, val) {
    var self = this;
    this._parse(name).assign($scope, angular.copy(val));
    this._remoteValue = angular.copy(val);
    if (deferred) {
      deferred.resolve(function() {
        self.disassociate();
      });
      this._watch($scope, name);
    }
  },
  _watch: function($scope, name) {
    // Watch for local changes.
    var self = this;
    self._unregister = $scope.$watch(name, function() {
      if (self._initial) {
        self._initial = false;
        return;
      }
      var val = JSON.parse(angular.toJson(self._parse(name)($scope)));
      if (angular.equals(val, self._remoteValue)) {
        return;
      }
      self._fRef.ref().set(val);
    }, true);
  }
};

// Explicit syncing. Provides a collection object you can modify.
// Original code by @petebacondarwin, from:
// https://github.com/petebacondarwin/angular-firebase/blob/master/ng-firebase-collection.js
angular.module("firebase").factory("angularFireCollection", ["$timeout", function($timeout) {
  function angularFireItem(ref, index) {
    this.$ref = ref.ref();
    this.$id = ref.name();
    this.$index = index;
      angular.extend(this, {priority:ref.getPriority()}, ref.val());
  }

  return function(collectionUrlOrRef, initialCb) {
    var collection = [];
    var indexes = {};

    var collectionRef;
    if (typeof collectionUrlOrRef == "string") {
      collectionRef = new Firebase(collectionUrlOrRef);
    } else {
      collectionRef = collectionUrlOrRef;
    }

    function getIndex(prevId) {
      return prevId ? indexes[prevId] + 1 : 0;
    }

    function addChild(index, item) {
      indexes[item.$id] = index;
      collection.splice(index, 0, item);
    }

    function removeChild(id) {
      var index = indexes[id];
      // Remove the item from the collection.
      collection.splice(index, 1);
      indexes[id] = undefined;
    }

    function updateChild (index, item) {
      collection[index] = item;
    }

    function moveChild (from, to, item) {
      collection.splice(from, 1);
      collection.splice(to, 0, item);
      updateIndexes(from, to);
    }

    function updateIndexes(from, to) {
      var length = collection.length;
      to = to || length;
      if (to > length) {
        to = length;
      }
      for (var index = from; index < to; index++) {
        var item = collection[index];
        item.$index = indexes[item.$id] = index;
      }
    }

    if (initialCb && typeof initialCb == "function") {
      collectionRef.once("value", initialCb);
    }

    collectionRef.on("child_added", function(data, prevId) {
      $timeout(function() {
        var index = getIndex(prevId);
        addChild(index, new angularFireItem(data, index));
        updateIndexes(index);
      });
    });

    collectionRef.on("child_removed", function(data) {
      $timeout(function() {
        var id = data.name();
        var pos = indexes[id];
        removeChild(id);
        updateIndexes(pos);
      });
    });

    collectionRef.on("child_changed", function(data, prevId) {
      $timeout(function() {
        var index = indexes[data.name()];
        var newIndex = getIndex(prevId);
        var item = new angularFireItem(data, index);

        updateChild(index, item);
        if (newIndex !== index) {
          moveChild(index, newIndex, item);
        }
      });
    });

    collectionRef.on("child_moved", function(ref, prevId) {
      $timeout(function() {
        var oldIndex = indexes[ref.name()];
        var newIndex = getIndex(prevId);
        var item = collection[oldIndex];
        moveChild(oldIndex, newIndex, item);
      });
    });

    collection.add = function(item, cb) {
      var ref;
      if (!cb) {
        ref = collectionRef.ref().push(item);
      } else {
        ref = collectionRef.ref().push(item, cb);
      }
      return ref;
    };
    collection.remove = function(itemOrId) {
      var item = angular.isString(itemOrId) ? collection[indexes[itemOrId]] : itemOrId;
      item.$ref.remove();
    };

    collection.update = function(itemOrId) {
      var item = angular.isString(itemOrId) ? collection[indexes[itemOrId]] : itemOrId;
      var copy = {};
      angular.forEach(item, function(value, key) {
        if (key.indexOf("$") !== 0) {
          copy[key] = value;
        }
      });
      item.$ref.set(copy);
    };

    return collection;
  };
}]);

// Authentication support for AngularFire.
angular.module("firebase").factory("angularFireAuth", [
  "$rootScope", "$parse", "$timeout", "$location", "$route",
  function($rootScope, $parse, $timeout, $location, $route) {

    function deconstructJWT(token) {
      var segments = token.split(".");
      if (!segments instanceof Array || segments.length !== 3) {
        throw new Error("Invalid JWT");
      }
      var claims = segments[1];
      return JSON.parse(decodeURIComponent(escape(window.atob(claims))));
    }

    function updateExpression(scope, name, val, cb) {
      if (name) {
        $timeout(function() {
          $parse(name).assign(scope, val);
          cb();
        });
      }
    }

    function authRequiredRedirect(route, path, self) {
      if (route.authRequired && !self._authenticated){
        if (route.pathTo === undefined) {
          self._redirectTo = $location.path();
        } else {
          self._redirectTo = route.pathTo === path ? "/" : route.pathTo;
        }
        $location.replace();
        $location.path(path);
      }
    }

    return {
      initialize: function(url, options) {
        var self = this;

        options = options || {};
        this._scope = $rootScope;
        if (options.scope) {
          this._scope = options.scope;
        }
        if (options.name) {
          this._name = options.name;
        }
        this._cb = function(){};
        if (options.callback && typeof options.callback === "function") {
          this._cb = options.callback;
        }

        this._redirectTo = null;
        this._authenticated = false;
        if (options.path) {
          authRequiredRedirect($route.current, options.path, self);
          $rootScope.$on("$routeChangeStart", function(e, next) {
            authRequiredRedirect(next, options.path, self);
          });
        }

        this._ref = new Firebase(url);
        if (options.simple && options.simple === false) {
          updateExpression(this._scope, this._name, null);
          return;
        }

        // Simple Login.
        if (!window.FirebaseSimpleLogin) {
          var err = new Error("FirebaseSimpleLogin undefined, " +
            "did you include firebase-simple-login.js?");
          $rootScope.$broadcast("angularFireAuth:error", err);
          return;
        }
        var client = new FirebaseSimpleLogin(this._ref, function(err, user) {
          self._cb(err, user);
          if (err) {
            $rootScope.$broadcast("angularFireAuth:error", err);
          } else if (user) {
            self._loggedIn(user)
          } else {
            self._loggedOut();
          }
        });
        this._authClient = client;
      },
      login: function(tokenOrProvider, options) {
        switch (tokenOrProvider) {
        case "github":
        case "persona":
        case "twitter":
        case "facebook":
        case "password":
          if (!this._authClient) {
            var err = new Error("Simple Login not initialized");
            $rootScope.$broadcast("angularFireAuth:error", err);
          } else {
            this._authClient.login(tokenOrProvider, options);
          }
          break;
        default:
          // Custom Login.
          var claims, self = this;
          try {
            claims = deconstructJWT(tokenOrProvider);
            this._ref.auth(tokenOrProvider, function(err) {
              if (err) {
                $rootScope.$broadcast("angularFireAuth:error", err);
              } else {
                self._loggedIn();
              }
            });
          } catch(e) {
            $rootScope.$broadcast("angularFireAuth:error", e)
          }
        }
      },
      logout: function() {
        if (this._authClient) {
          this._authClient.logout();
        } else {
          this._ref.unauth();
          this._loggedOut();
        }
      },
      _loggedIn: function(user) {
        var self = this;
        this._authenticated = true;
        updateExpression(this._scope, this._name, user, function() {
          $rootScope.$broadcast("angularFireAuth:login", user);
          if (self._redirectTo) {
            $location.replace();
            $location.path(self._redirectTo);
            self._redirectTo = null;
          }
        });
      },
      _loggedOut: function() {
        this._authenticated = false;
        updateExpression(this._scope, this._name, null, function() {
          $rootScope.$broadcast("angularFireAuth:logout");
        });
      }
    }
  }
]);
<commit_msg>Add createUser - issue #57<commit_after>"use strict";

angular.module("firebase", []).value("Firebase", Firebase);

// Implicit syncing. angularFire binds a model to $scope and keeps the data
// synchronized with a Firebase location both ways.
// TODO: Optimize to use child events instead of whole "value".
angular.module("firebase").factory("angularFire", ["$q", "$parse", "$timeout",
  function($q, $parse, $timeout) {
    return function(ref, scope, name, ret) {
      var af = new AngularFire($q, $parse, $timeout, ref);
      return af.associate(scope, name, ret);
    };
  }
]);

function AngularFire($q, $parse, $timeout, ref) {
  this._q = $q;
  this._parse = $parse;
  this._timeout = $timeout;

  this._initial = true;
  this._remoteValue = false;

  if (typeof ref == "string") {
    this._fRef = new Firebase(ref);
  } else {
    this._fRef = ref;
  }
}
AngularFire.prototype = {
  disassociate: function() {
    var self = this;
    if (self._unregister) {
      self._unregister();
    }
    this._fRef.off("value");
  },
  associate: function($scope, name, ret) {
    var self = this;
    if (ret == undefined) {
      ret = [];
    }
    var deferred = this._q.defer();
    var promise = deferred.promise;
    this._fRef.on("value", function(snap) {
      var resolve = false;
      if (deferred) {
        resolve = deferred;
        deferred = false;
      }
      self._remoteValue = ret;
      if (snap && snap.val() != undefined) {
        var val = snap.val();
        if (typeof val != typeof ret) {
          self._log("Error: type mismatch");
          return;
        }
        // Also distinguish between objects and arrays.
        var check = Object.prototype.toString;
        if (check.call(ret) != check.call(val)) {
          self._log("Error: type mismatch");
          return;
        }
        self._remoteValue = angular.copy(val);
        if (angular.equals(val, self._parse(name)($scope))) {
          return;
        }
      }
      self._timeout(function() {
        self._resolve($scope, name, resolve, self._remoteValue)
      });
    });
    return promise;
  },
  _log: function(msg) {
    if (console && console.log) {
      console.log(msg);
    }
  },
  _resolve: function($scope, name, deferred, val) {
    var self = this;
    this._parse(name).assign($scope, angular.copy(val));
    this._remoteValue = angular.copy(val);
    if (deferred) {
      deferred.resolve(function() {
        self.disassociate();
      });
      this._watch($scope, name);
    }
  },
  _watch: function($scope, name) {
    // Watch for local changes.
    var self = this;
    self._unregister = $scope.$watch(name, function() {
      if (self._initial) {
        self._initial = false;
        return;
      }
      var val = JSON.parse(angular.toJson(self._parse(name)($scope)));
      if (angular.equals(val, self._remoteValue)) {
        return;
      }
      self._fRef.ref().set(val);
    }, true);
  }
};

// Explicit syncing. Provides a collection object you can modify.
// Original code by @petebacondarwin, from:
// https://github.com/petebacondarwin/angular-firebase/blob/master/ng-firebase-collection.js
angular.module("firebase").factory("angularFireCollection", ["$timeout", function($timeout) {
  function angularFireItem(ref, index) {
    this.$ref = ref.ref();
    this.$id = ref.name();
    this.$index = index;
      angular.extend(this, {priority:ref.getPriority()}, ref.val());
  }

  return function(collectionUrlOrRef, initialCb) {
    var collection = [];
    var indexes = {};

    var collectionRef;
    if (typeof collectionUrlOrRef == "string") {
      collectionRef = new Firebase(collectionUrlOrRef);
    } else {
      collectionRef = collectionUrlOrRef;
    }

    function getIndex(prevId) {
      return prevId ? indexes[prevId] + 1 : 0;
    }

    function addChild(index, item) {
      indexes[item.$id] = index;
      collection.splice(index, 0, item);
    }

    function removeChild(id) {
      var index = indexes[id];
      // Remove the item from the collection.
      collection.splice(index, 1);
      indexes[id] = undefined;
    }

    function updateChild (index, item) {
      collection[index] = item;
    }

    function moveChild (from, to, item) {
      collection.splice(from, 1);
      collection.splice(to, 0, item);
      updateIndexes(from, to);
    }

    function updateIndexes(from, to) {
      var length = collection.length;
      to = to || length;
      if (to > length) {
        to = length;
      }
      for (var index = from; index < to; index++) {
        var item = collection[index];
        item.$index = indexes[item.$id] = index;
      }
    }

    if (initialCb && typeof initialCb == "function") {
      collectionRef.once("value", initialCb);
    }

    collectionRef.on("child_added", function(data, prevId) {
      $timeout(function() {
        var index = getIndex(prevId);
        addChild(index, new angularFireItem(data, index));
        updateIndexes(index);
      });
    });

    collectionRef.on("child_removed", function(data) {
      $timeout(function() {
        var id = data.name();
        var pos = indexes[id];
        removeChild(id);
        updateIndexes(pos);
      });
    });

    collectionRef.on("child_changed", function(data, prevId) {
      $timeout(function() {
        var index = indexes[data.name()];
        var newIndex = getIndex(prevId);
        var item = new angularFireItem(data, index);

        updateChild(index, item);
        if (newIndex !== index) {
          moveChild(index, newIndex, item);
        }
      });
    });

    collectionRef.on("child_moved", function(ref, prevId) {
      $timeout(function() {
        var oldIndex = indexes[ref.name()];
        var newIndex = getIndex(prevId);
        var item = collection[oldIndex];
        moveChild(oldIndex, newIndex, item);
      });
    });

    collection.add = function(item, cb) {
      var ref;
      if (!cb) {
        ref = collectionRef.ref().push(item);
      } else {
        ref = collectionRef.ref().push(item, cb);
      }
      return ref;
    };
    collection.remove = function(itemOrId) {
      var item = angular.isString(itemOrId) ? collection[indexes[itemOrId]] : itemOrId;
      item.$ref.remove();
    };

    collection.update = function(itemOrId) {
      var item = angular.isString(itemOrId) ? collection[indexes[itemOrId]] : itemOrId;
      var copy = {};
      angular.forEach(item, function(value, key) {
        if (key.indexOf("$") !== 0) {
          copy[key] = value;
        }
      });
      item.$ref.set(copy);
    };

    return collection;
  };
}]);

// Authentication support for AngularFire.
angular.module("firebase").factory("angularFireAuth", [
  "$rootScope", "$parse", "$timeout", "$location", "$route",
  function($rootScope, $parse, $timeout, $location, $route) {

    function deconstructJWT(token) {
      var segments = token.split(".");
      if (!segments instanceof Array || segments.length !== 3) {
        throw new Error("Invalid JWT");
      }
      var claims = segments[1];
      return JSON.parse(decodeURIComponent(escape(window.atob(claims))));
    }

    function updateExpression(scope, name, val, cb) {
      if (name) {
        $timeout(function() {
          $parse(name).assign(scope, val);
          cb();
        });
      }
    }

    function authRequiredRedirect(route, path, self) {
      if (route.authRequired && !self._authenticated){
        if (route.pathTo === undefined) {
          self._redirectTo = $location.path();
        } else {
          self._redirectTo = route.pathTo === path ? "/" : route.pathTo;
        }
        $location.replace();
        $location.path(path);
      }
    }

    return {
      initialize: function(url, options) {
        var self = this;

        options = options || {};
        this._scope = $rootScope;
        if (options.scope) {
          this._scope = options.scope;
        }
        if (options.name) {
          this._name = options.name;
        }
        this._cb = function(){};
        if (options.callback && typeof options.callback === "function") {
          this._cb = options.callback;
        }

        this._redirectTo = null;
        this._authenticated = false;
        if (options.path) {
          authRequiredRedirect($route.current, options.path, self);
          $rootScope.$on("$routeChangeStart", function(e, next) {
            authRequiredRedirect(next, options.path, self);
          });
        }

        this._ref = new Firebase(url);
        if (options.simple && options.simple === false) {
          updateExpression(this._scope, this._name, null);
          return;
        }

        // Simple Login.
        if (!window.FirebaseSimpleLogin) {
          var err = new Error("FirebaseSimpleLogin undefined, " +
            "did you include firebase-simple-login.js?");
          $rootScope.$broadcast("angularFireAuth:error", err);
          return;
        }
        var client = new FirebaseSimpleLogin(this._ref, function(err, user) {
          self._cb(err, user);
          if (err) {
            $rootScope.$broadcast("angularFireAuth:error", err);
          } else if (user) {
            self._loggedIn(user)
          } else {
            self._loggedOut();
          }
        });
        this._authClient = client;
      },
      login: function(tokenOrProvider, options) {
        switch (tokenOrProvider) {
        case "github":
        case "persona":
        case "twitter":
        case "facebook":
        case "password":
          if (!this._authClient) {
            var err = new Error("Simple Login not initialized");
            $rootScope.$broadcast("angularFireAuth:error", err);
          } else {
            this._authClient.login(tokenOrProvider, options);
          }
          break;
        default:
          // Custom Login.
          var claims, self = this;
          try {
            claims = deconstructJWT(tokenOrProvider);
            this._ref.auth(tokenOrProvider, function(err) {
              if (err) {
                $rootScope.$broadcast("angularFireAuth:error", err);
              } else {
                self._loggedIn();
              }
            });
          } catch(e) {
            $rootScope.$broadcast("angularFireAuth:error", e)
          }
        }
      },
      //fn cb receives a Simple Login user object
      createUser: function(email, password, cb){
        var self = this;
        this._authClient.createUser(email, password, function(err, user){
          try{
            if(err){
              $rootScope.$broadcast("angularFireAuth:error", err);
            } else {
              self._loggedIn(user);
            }
          } catch(e) {
            $rootScope.$broadcast("angularFireAuth:error", e);
          }
          $timeout(function(){
           cb(user);
          });
        });
      },
      logout: function() {
        if (this._authClient) {
          this._authClient.logout();
        } else {
          this._ref.unauth();
          this._loggedOut();
        }
      },
      _loggedIn: function(user) {
        var self = this;
        this._authenticated = true;
        updateExpression(this._scope, this._name, user, function() {
          $rootScope.$broadcast("angularFireAuth:login", user);
          if (self._redirectTo) {
            $location.replace();
            $location.path(self._redirectTo);
            self._redirectTo = null;
          }
        });
      },
      _loggedOut: function() {
        this._authenticated = false;
        updateExpression(this._scope, this._name, null, function() {
          $rootScope.$broadcast("angularFireAuth:logout");
        });
      }
    }
  }
]);
<|endoftext|>


<commit_before>const rx = require('rx');

module.exports = class SlackApiRx {
  // Public: Retrieves DM channels for all of the given users, opening any that
  // do not already exist.
  //
  // slackApi - An instance of the Slack client
  // users - The users to fetch DM channels for
  //
  // Returns an {Observable} that signals completion
  static openDms(slackApi, users) {
    let ret = rx.Observable.fromArray(users)
      .flatMap(user => SlackApiRx.getOrOpenDm(slackApi, user))
      .reduce((acc, x) => {
        acc[x.id] = x.dm;
        return acc;
      }, {})
      .publishLast();

    ret.connect();
    return ret;
  }

  // Private: Checks for the existence of an open DM channel for the user, and
  // opens one if necessary.
  //
  // slackApi - An instance of the Slack client
  // user - The user we are trying to DM with
  //
  // Returns an {Observable} of the opened DM channel
  static getOrOpenDm(slackApi, user) {
    let readySubj = new rx.AsyncSubject();
    let dm = slackApi.getDMByName(user.name);
    console.log(`Opening DM channel for ${user.name}`);

    if (!dm || !dm.is_open) {
      slackApi.openDM(user.id, (result) => {
        if (result.ok) {
          dm = slackApi.getDMByName(user.name);
          readySubj.onNext({id: user.id, dm: dm});
          readySubj.onCompleted();
        } else {
          console.log(`Unable to open DM for ${user.name}: ${result.error}`);
          readySubj.onCompleted();
        }
      });
    } else {
      readySubj.onNext({id: user.id, dm: dm});
      readySubj.onCompleted();
    }
    return readySubj;
  }
};
<commit_msg>Rework openDms to wait for the im_open event to be emitted, then wait a little bit more.<commit_after>const rx = require('rx');

module.exports = class SlackApiRx {
  // Public: Retrieves DM channels for all of the given users, opening any that
  // do not already exist.
  //
  // slackApi - An instance of the Slack client
  // users - The users to fetch DM channels for
  //
  // Returns an {Observable} that signals completion
  static openDms(slackApi, users) {
    let ret = rx.Observable.fromArray(users)
      .flatMap((user) => SlackApiRx.getOrOpenDm(slackApi, user))
      .reduce((acc, x) => {
        acc[x.id] = x.dm;
        return acc;
      }, {})
      .publishLast();

    ret.connect();
    return ret;
  }

  // Private: Checks for the existence of an open DM channel for the user,
  // opens one if necessary, then waits for the `im_open` event and retrieves
  // the DM channel.
  //
  // slackApi - An instance of the Slack client
  // user - The user we are trying to DM with
  //
  // Returns an {Observable} representing the opened channel. This will be an
  // object with two keys: `id` and `dm`. DM will be null if the API call
  // failed for some reason (e.g., an invalid user).
  static getOrOpenDm(slackApi, user) {
    console.log(`Getting DM channel for ${user.name}`);
    let dm = slackApi.getDMByName(user.name);

    // Bot players don't need DM channels; we only talk to humans
    if ((dm && dm.is_open) || user.isBot) {
      return rx.Observable.return({id: user.id, dm: dm});
    }

    console.log(`No open channel found, opening one using ${user.id}`);

    return SlackApiRx.openDm(slackApi, user)
      .flatMap(() => SlackApiRx.waitForDmToOpen(slackApi, user))
      .flatMap((dm) => rx.Observable.return({id: user.id, dm: dm}))
      .catch(rx.Observable.return({id: user.id, dm: null}));
  }

  // Private: Maps the `im.open` API call into an {Observable}.
  //
  // Returns an {Observable} that signals completion, or an error if the API
  // call fails
  static openDm(slackApi, user) {
    let calledOpen = new rx.AsyncSubject();

    slackApi.openDM(user.id, (result) => {
      if (result.ok) {
        calledOpen.onNext(user.name);
        calledOpen.onCompleted();
      } else {
        console.log(`Unable to open DM for ${user.name}: ${result.error}`);
        calledOpen.onError(new Error(result.error));
      }
    })

    return calledOpen;
  }

  // Private: The `im.open` callback is still not late enough; we need to wait
  // for the client's underlying list of DM's to be updated. When that occurs
  // we can retrieve the DM.
  //
  // Returns a replayable {Observable} containing the opened DM channel
  static waitForDmToOpen(slackApi, user) {
    let ret = rx.DOM.fromEvent(slackApi, 'raw_message')
      .where((m) => m.type === 'im_open' && m.user === user.id)
      .take(1)
      .flatMap(() => rx.Observable.timer(100).map(() =>
        slackApi.getDMByName(user.name)))
      .publishLast();

    ret.connect();
    return ret;
  }
};
<|endoftext|>


<commit_before>/*
simpleBC- a wrapper around BCSocket

usage:

app.use(simpleBC ({base: "/foobar"}, function(data) {
  this.broadcast(data); //sends the data back to all clients.
});

Your function gets called every time a piece of data comes in through the
browserchannel with the data that gets sent. Broadcast sends the message to all
connected clients.

TODO: maybe set up some sort of subscription groups for the different pads?

*/
var browserChannel = require('browserchannel').server;
module.exports = function(opts, onMessage) {
  this.sessions = {};
  this.broadcast = function(message) {
    for (var id in sessions) {
      if (sessions.hasOwnProperty(id)) {
        sessions[id].send(message);
      }
    }
  }
  return browserChannel(opts, function(session) {
    sessions[session.id] = session;
    session.on('message', function(data) {
      onMessage(data);
    });

    session.on('close', function(reason) {
      delete sessions[session.id];
    });
  });
}
<commit_msg>Remove simpleBC.js. It doesn' t work<commit_after><|endoftext|>


<commit_before>const Discord = require("discord.js");

const impliedPermissions = new Discord.Permissions([
  "READ_MESSAGES",
  "SEND_MESSAGES",
  "SEND_TTS_MESSAGES",
  "EMBED_LINKS",
  "ATTACH_FILES",
  "READ_MESSAGE_HISTORY",
  "MENTION_EVERYONE",
  "EXTERNAL_EMOJIS",
  "ADD_REACTIONS",
]);

exports.conf = {
  enabled: true,
  spamProtection: false,
  priority: 7,
};

exports.run = (client, msg, cmd) => {
  const missing = msg.channel.type === "text" ? msg.channel.permissionsFor(client.user).missing(cmd.conf.botPerms) : impliedPermissions.missing(cmd.conf.botPerms);
  if (missing.length > 0) return `Insufficient permissions, missing: **${client.funcs.toTitleCase(missing.join(", ").split("_").join(" "))}**`;
  return false;
};
<commit_msg>Fix deprecated Permision (#227)<commit_after>const { Permissions } = require("discord.js");

const impliedPermissions = new Permissions([
  "READ_MESSAGES",
  "SEND_MESSAGES",
  "SEND_TTS_MESSAGES",
  "EMBED_LINKS",
  "ATTACH_FILES",
  "READ_MESSAGE_HISTORY",
  "MENTION_EVERYONE",
  "USE_EXTERNAL_EMOJIS",
  "ADD_REACTIONS",
]);

exports.conf = {
  enabled: true,
  spamProtection: false,
  priority: 7,
};

exports.run = (client, msg, cmd) => {
  const missing = msg.channel.type === "text" ? msg.channel.permissionsFor(client.user).missing(cmd.conf.botPerms) : impliedPermissions.missing(cmd.conf.botPerms);
  if (missing.length > 0) return `Insufficient permissions, missing: **${client.funcs.toTitleCase(missing.join(", ").split("_").join(" "))}**`;
  return false;
};
<|endoftext|>


<commit_before>var InlineGenerator = (function(){
  function InlineGenerator(style, stream, outline_context){
    LayoutGenerator.call(this, style, stream);
    this.outlineContext = outline_context || null;
  }
  Class.extend(InlineGenerator, LayoutGenerator);

  InlineGenerator.prototype._yield = function(context){
    if(!context.isInlineSpaceLeft()){
      return null;
    }
    while(this.hasNext()){
      var element = this._getNext(context);
      if(element === null){
	break;
      }
      var measure = this._getMeasure(element);
      if(measure === 0){
	break;
      }
      if(!context.hasInlineSpaceFor(measure)){
	this.pushCache(element);
	break;
      }
      this._addElement(context, element, measure);
      if(!context.isInlineSpaceLeft()){
	break;
      }
    }
    // no br, no element
    if(context.isInlineEmpty()){
      return null;
    }
    // justify if this line is generated by overflow(not line-break).
    if(!context.hasBr()){
      this._justifyLine(context);
    }
    return this._createOutput(context);
  };

  InlineGenerator.prototype._createChildContext = function(context){
    return new LayoutContext(
      context.block, // inline generator inherits block context as it is.
      new InlineContext(context.getInlineRestMeasure())
    );
  };

  InlineGenerator.prototype._createOutput = function(context){
    var line = this.style.createLine({
      br:context.hasBr(), // is line broken by br?
      measure:context.getInlineCurMeasure(), // actual measure
      elements:context.getInlineElements(), // all inline-child, not only text, but recursive child box.
      texts:context.getInlineTexts(), // elements but text element only.
      charCount:context.getInlineCharCount()
    });

    // call _onCreate callback for 'each' output
    this._onCreate(line);

    // call _onComplete callback for 'final' output
    if(!this.hasNext()){
      this._onComplete(line);
    }
    return line;
  };

  InlineGenerator.prototype._justifyLine = function(context){
    // by stream.getToken(), stream pos has been moved to next pos already, so cur pos is the next head.
    var next_head = this.peekLastCache() || this.stream.peek();
    var new_tail = context.justify(next_head); // if justify is occured, new_tail token is gained.
    if(new_tail){
      this.stream.setPos(new_tail.pos + 1); // new stream pos is next pos of new tail.
      this.clearCache(); // stream position changed, so disable cache.
    }
  };

  InlineGenerator.prototype._getNext = function(context){
    if(this.hasCache()){
      return this.popCache(context);
    }

    if(this.hasChildLayout()){
      return this.yieldChildLayout();
    }

    // read next token
    var token = this.stream.get();
    if(token === null){
      return null;
    }

    // inline text
    if(Token.isText(token)){
      // if tcy, wrap all content and return Tcy object and force generator terminate.
      if(this.style.getTextCombine() === "horizontal"){
	this.setTerminate(true);
	var tcy = new Tcy(this.style.getMarkupContent());
	return this._getText(context, tcy);
      }
      return this._getText(context, token);
    }

    // if tag token, inherit style
    var child_style = this.style;
    if(token instanceof Tag){
      child_style = new StyleContext(token, this.style, {context:context});
    }

    // if inline -> block, force terminate inline
    if(child_style.isBlock()){
      this.stream.prev();
      this.setTerminate(true);

      // add line-break to avoid empty-line.
      // because empty-line is returned as null to parent block generator,
      // and it causes page-break of parent block generator.
      context.setLineBreak(true);
      return null;
    }

    var child_stream = this._createStream(child_style, token);

    // if inline-block, yield immediately, and return as inline element.
    if(child_style.isInlineBlock()){
      return (new BlockGenerator(child_style, child_stream, this.outlineContext)).yield(context);
    }

    // inline child
    switch(child_style.getMarkupName()){
    case "img":
      return child_style.createImage();

    case "br":
      context.setLineBreak(true);
      return null;

    case "script":
    case "style":
    case "noscript":
      return this._getNext(context); // just skip

    case "a":
      this.setChildLayout(new LinkGenerator(child_style, child_stream, this.outlineContext));
      return this.yieldChildLayout(context);

    default:
      this.setChildLayout(new InlineGenerator(child_style, child_stream, this.outlineContext));
      return this.yieldChildLayout(context);
    }
  };

  InlineGenerator.prototype._getText = function(context, token){
    // new-line
    if(Token.isNewLine(token)){
      if(this.style.isPre()){
	return null; // break line at new-line char.
      }
      // if not pre, skip continuous new-line
      this.stream.skipUntil(Token.isNewLine);
      return this._getNext(context);
    }
    if(!token.hasMetrics()){
      // if charactor token, set kerning before setting metrics.
      // because some additional space is added to it in some case.
      if(token instanceof Char){
	this._setCharKerning(context, token);
      }
      token.setMetrics(this.style.flow, this.style.font);
    }
    if(token instanceof Ruby){
      return token;
    }
    switch(token._type){
    case "char":
    case "tcy":
      return token;
      case "word":
      return this._getWord(context, token);
    }
  };

  InlineGenerator.prototype._setCharKerning = function(context, char_token){
    var next_token = this.stream.peek();
    var prev_text = context.getInlineLastText();
    var next_text = next_token && Token.isText(next_token)? next_token : null;
    Kerning.set(char_token, prev_text, next_text);
  };

  InlineGenerator.prototype._getWord = function(context, token){
    var rest_measure = context.getInlineRestMeasure();
    var advance = token.getAdvance(this.style.flow, this.style.letterSpacing || 0);

    // if advance of this word is less than max-measure, just return.
    if(advance <= rest_measure){
      token.setDevided(false);
      return token;
    }
    // if advance is lager than max_measure,
    // we must cut this word into some parts.
    var part = token.cutMeasure(this.style.getFontSize(), rest_measure); // get sliced word
    part.setMetrics(this.style.flow, this.style.font); // metrics for first half
    token.setMetrics(this.style.flow, this.style.font); // metrics for second half
    this.stream.prev(); // re-parse this token because rest part is still exists.
    part.bodySize = Math.min(rest_measure, part.bodySize);
    return part;
  };

  InlineGenerator.prototype._getMeasure = function(element){
    if(element instanceof Box){
      return element.getLayoutMeasure(this.style.flow);
    }
    if(element.getAdvance){
      return element.getAdvance(this.style.flow, this.style.letterSpacing || 0);
    }
    return 0; // TODO
  };

  InlineGenerator.prototype._addElement = function(context, element, measure){
    context.addInlineElement(element, measure);

    // call _onAddElement callback for each 'element' of output.
    this._onAddElement(element);
  };

  return InlineGenerator;
})();

<commit_msg>add comment<commit_after>var InlineGenerator = (function(){
  function InlineGenerator(style, stream, outline_context){
    LayoutGenerator.call(this, style, stream);
    this.outlineContext = outline_context || null;
  }
  Class.extend(InlineGenerator, LayoutGenerator);

  InlineGenerator.prototype._yield = function(context){
    if(!context.isInlineSpaceLeft()){
      return null;
    }
    while(this.hasNext()){
      var element = this._getNext(context);
      if(element === null){
	break;
      }
      var measure = this._getMeasure(element);
      if(measure === 0){
	break;
      }
      if(!context.hasInlineSpaceFor(measure)){
	this.pushCache(element);
	break;
      }
      this._addElement(context, element, measure);
      if(!context.isInlineSpaceLeft()){
	break;
      }
    }
    // no br, no element
    if(context.isInlineEmpty()){
      return null;
    }
    // justify if this line is generated by overflow(not line-break).
    if(!context.hasBr()){
      this._justifyLine(context);
    }
    return this._createOutput(context);
  };

  InlineGenerator.prototype._createChildContext = function(context){
    return new LayoutContext(
      context.block, // inline generator inherits block context as it is.
      new InlineContext(context.getInlineRestMeasure())
    );
  };

  InlineGenerator.prototype._createOutput = function(context){
    var line = this.style.createLine({
      br:context.hasBr(), // is line broken by br?
      measure:context.getInlineCurMeasure(), // actual measure
      elements:context.getInlineElements(), // all inline-child, not only text, but recursive child box.
      texts:context.getInlineTexts(), // elements but text element only.
      charCount:context.getInlineCharCount()
    });

    // call _onCreate callback for 'each' output
    this._onCreate(line);

    // call _onComplete callback for 'final' output
    if(!this.hasNext()){
      this._onComplete(line);
    }
    return line;
  };

  InlineGenerator.prototype._justifyLine = function(context){
    // by stream.getToken(), stream pos has been moved to next pos already, so cur pos is the next head.
    var next_head = this.peekLastCache() || this.stream.peek();
    var new_tail = context.justify(next_head); // if justify is occured, new_tail token is gained.
    if(new_tail){
      this.stream.setPos(new_tail.pos + 1); // new stream pos is next pos of new tail.
      this.clearCache(); // stream position changed, so disable cache.
    }
  };

  InlineGenerator.prototype._getNext = function(context){
    if(this.hasCache()){
      return this.popCache(context);
    }

    if(this.hasChildLayout()){
      return this.yieldChildLayout();
    }

    // read next token
    var token = this.stream.get();
    if(token === null){
      return null;
    }

    // inline text
    if(Token.isText(token)){
      // if tcy, wrap all content and return Tcy object and force generator terminate.
      if(this.style.getTextCombine() === "horizontal"){
	this.setTerminate(true);
	var tcy = new Tcy(this.style.getMarkupContent());
	return this._getText(context, tcy);
      }
      return this._getText(context, token);
    }

    // if tag token, inherit style
    var child_style = this.style;
    if(token instanceof Tag){
      child_style = new StyleContext(token, this.style, {context:context});
    }

    // if inline -> block, force terminate inline
    if(child_style.isBlock()){
      this.stream.prev();
      this.setTerminate(true);

      // add line-break to avoid empty-line.
      // because empty-line is returned as null to parent block generator,
      // and it causes page-break of parent block generator.
      context.setLineBreak(true);
      return null;
    }

    var child_stream = this._createStream(child_style, token);

    // if inline-block, yield immediately, and return as inline element.
    if(child_style.isInlineBlock()){
      return (new BlockGenerator(child_style, child_stream, this.outlineContext)).yield(context);
    }

    // inline child
    switch(child_style.getMarkupName()){
    case "img":
      return child_style.createImage();

    case "br":
      context.setLineBreak(true);
      return null;

    case "script":
    case "style":
    case "noscript":
      return this._getNext(context); // just skip

    case "a":
      this.setChildLayout(new LinkGenerator(child_style, child_stream, this.outlineContext));
      return this.yieldChildLayout(context);

    default:
      this.setChildLayout(new InlineGenerator(child_style, child_stream, this.outlineContext));
      return this.yieldChildLayout(context);
    }
  };

  InlineGenerator.prototype._getText = function(context, token){
    // new-line
    if(Token.isNewLine(token)){
      if(this.style.isPre()){
	return null; // break line at new-line char.
      }
      // if not pre, skip continuous new-line
      this.stream.skipUntil(Token.isNewLine);
      return this._getNext(context);
    }
    if(!token.hasMetrics()){
      // if charactor token, set kerning before setting metrics.
      // because some additional space is added to it in some case.
      if(token instanceof Char){
	this._setCharKerning(context, token);
      }
      token.setMetrics(this.style.flow, this.style.font);
    }
    if(token instanceof Ruby){
      return token;
    }
    switch(token._type){
    case "char":
    case "tcy":
      return token;
      case "word":
      return this._getWord(context, token);
    }
  };

  InlineGenerator.prototype._setCharKerning = function(context, char_token){
    var next_token = this.stream.peek();
    var prev_text = context.getInlineLastText();
    var next_text = next_token && Token.isText(next_token)? next_token : null;
    Kerning.set(char_token, prev_text, next_text);
  };

  InlineGenerator.prototype._getWord = function(context, token){
    var rest_measure = context.getInlineRestMeasure();
    var advance = token.getAdvance(this.style.flow, this.style.letterSpacing || 0);

    // if advance of this word is less than max-measure, just return.
    if(advance <= rest_measure){
      token.setDevided(false);
      return token;
    }
    // if advance is lager than max_measure,
    // we must cut this word into some parts.
    var part = token.cutMeasure(this.style.getFontSize(), rest_measure); // get sliced word
    part.setMetrics(this.style.flow, this.style.font); // metrics for first half
    token.setMetrics(this.style.flow, this.style.font); // metrics for second half
    this.stream.prev(); // re-parse this token because rest part is still exists.
    part.bodySize = Math.min(rest_measure, part.bodySize); // sometimes overflows. more accurate logic is required in the future.
    return part;
  };

  InlineGenerator.prototype._getMeasure = function(element){
    if(element instanceof Box){
      return element.getLayoutMeasure(this.style.flow);
    }
    if(element.getAdvance){
      return element.getAdvance(this.style.flow, this.style.letterSpacing || 0);
    }
    return 0; // TODO
  };

  InlineGenerator.prototype._addElement = function(context, element, measure){
    context.addInlineElement(element, measure);

    // call _onAddElement callback for each 'element' of output.
    this._onAddElement(element);
  };

  return InlineGenerator;
})();

<|endoftext|>


<commit_before>/* global toggleMobileMenu:false */
/* global setSession:true */
window.onload = function() {
    initForm();
    getClientCountry();

    window.onresize = checkWidth;

    // Store gclid
    const gclid = getParamValue(document.referrer, 'gclid');
    if (gclid) {
        localStorage.setItem('gclid', gclid);
    }

    commonOnload();
};

function initForm() {
    const signup_forms = document.querySelectorAll('.signup-form');
    let ws = wsConnect();

    function sendVerifyEmail(val) {
        if (!checkCountry(val)) {
            return;
        }
        const trimmed_email = trimEmail(val);
        wsSend(ws, {
            verify_email: trimmed_email,
            type        : 'account_opening',
        });
    }

    function verifySubmit(msg) {
        const response = JSON.parse(msg.data);
        setValidationStyle(el_email, response.error);
        if (!response.error) {
            signup_forms.forEach((el) => {
                el.querySelector('.signup-form-input').classList.add('invisible');
                el.querySelector('.signup-form-success').classList.remove('invisible');
            });
        }
    }

    function trimEmail(str) {
        return str.replace(/\s/g, '');
    }

    function checkCountry(val) {
        const clients_country = sessionStorage.getItem('clients_country');
        if ((clients_country !== 'my') || /@binary\.com$/.test(val)) {
            return true;
        }
        signup_forms.forEach((el) => {
            el.querySelector('.signup-form-input').classList.add('invisible');
            el.querySelector('.signup-form-error').classList.remove('invisible');
        });
        return false;
    }

    function connect() {
        ws = wsConnect();
        ws.onmessage = verifySubmit;
        ws.onclose = connect;
    }

    let validation_set = false; // To prevent validating before submit

    signup_forms.forEach((form) => {
        form.addEventListener('submit', handleSubmit);
    });

    let el_email;
    function handleSubmit(e) {
        e.preventDefault();

        const el_form  = this;
        el_email = el_form.querySelector('input[type="email"]');
        if (!validateEmail(el_email.value)) {
            if (!validation_set) {
                ['input', 'change'].forEach((evt) => {
                    el_email.addEventListener(evt, () => {
                        setValidationStyle(!validateEmail(el_email.value));
                    });
                });
                setValidationStyle(!validateEmail(el_email.value));
                validation_set = true;
            }

            const to = this.offsetTop - 50;
            scrollTo(to, 500); // Scroll to nearest form
            return;
        }

        if (ws.readyState === 1) {
            sendVerifyEmail(el_email.value);
        } else {
            ws = wsConnect();
            ws.onopen = sendVerifyEmail(el_email.value);
        }
    }

    ws.onmessage = verifySubmit;
    ws.onclose = connect;
}

function validateEmail(email) {
    return /^[a-zA-Z0-9_.+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,63}$/.test(email);
}

function setValidationStyle(has_error) {
    document.querySelectorAll('input[type="email"]').forEach((el) => {
        el.classList[has_error ? 'add' : 'remove']('error-field');
    });
    document.querySelectorAll('.error-msg').forEach((el) => {
        el.classList[has_error ? 'remove' : 'add']('invisible');
    });
}

function getClientCountry() {
    let clients_country = sessionStorage.getItem('clients_country');

    // Try to get residence from client's info if logged-in
    if (!clients_country) {
        const accounts = JSON.parse(localStorage.getItem('client.accounts') || null);
        if (accounts) {
            Object.keys(accounts).some((loginid) => {
                if (accounts[loginid].residence) {
                    clients_country = accounts[loginid].residence;
                    setSession('clients_country', clients_country);
                    return true;
                }
                return false;
            });
        }
    }

    // Get required info from WebSocket
    const ws = wsConnect();

    function sendRequests() {
        if (!clients_country) wsSend(ws, { website_status: 1 });
        wsSend(ws, { time: 1 });
    }

    if (ws.readyState === 1) {
        sendRequests();
    } else {
        ws.onopen = sendRequests;
    }

    ws.onmessage = function (msg) {
        const response = JSON.parse(msg.data);
        if (response.website_status) {
            clients_country = response.website_status.clients_country;
            setSession('clients_country', clients_country);
        }
    };

    return clients_country;
}
<commit_msg>return if email is sent<commit_after>/* global toggleMobileMenu:false */
/* global setSession:true */
window.onload = function() {
    initForm();
    getClientCountry();

    window.onresize = checkWidth;

    // Store gclid
    const gclid = getParamValue(document.referrer, 'gclid');
    if (gclid) {
        localStorage.setItem('gclid', gclid);
    }

    commonOnload();
};

function initForm() {
    const signup_forms = document.querySelectorAll('.signup-form');
    let ws = wsConnect();
    let email_sent = false;

    function sendVerifyEmail(val) {
        if (!checkCountry(val)) {
            return;
        }
        const trimmed_email = trimEmail(val);
        wsSend(ws, {
            verify_email: trimmed_email,
            type        : 'account_opening',
        });
    }

    function verifySubmit(msg) {
        const response = JSON.parse(msg.data);
        setValidationStyle(el_email, response.error);
        if (!response.error) {
            signup_forms.forEach((el) => {
                el.querySelector('.signup-form-input').classList.add('invisible');
                el.querySelector('.signup-form-success').classList.remove('invisible');
                email_sent = true;
            });
        }
    }

    function trimEmail(str) {
        return str.replace(/\s/g, '');
    }

    function checkCountry(val) {
        const clients_country = sessionStorage.getItem('clients_country');
        if ((clients_country !== 'my') || /@binary\.com$/.test(val)) {
            return true;
        }
        signup_forms.forEach((el) => {
            el.querySelector('.signup-form-input').classList.add('invisible');
            el.querySelector('.signup-form-error').classList.remove('invisible');
        });
        return false;
    }

    function connect() {
        if (email_sent) return;
        ws = wsConnect();
        ws.onmessage = verifySubmit;
        ws.onclose = connect;
    }

    let validation_set = false; // To prevent validating before submit

    signup_forms.forEach((form) => {
        form.addEventListener('submit', handleSubmit);
    });

    let el_email;
    function handleSubmit(e) {
        e.preventDefault();

        const el_form  = this;
        el_email = el_form.querySelector('input[type="email"]');
        if (!validateEmail(el_email.value)) {
            if (!validation_set) {
                ['input', 'change'].forEach((evt) => {
                    el_email.addEventListener(evt, () => {
                        setValidationStyle(!validateEmail(el_email.value));
                    });
                });
                setValidationStyle(!validateEmail(el_email.value));
                validation_set = true;
            }

            const to = this.offsetTop - 50;
            scrollTo(to, 500); // Scroll to nearest form
            return;
        }

        if (ws.readyState === 1) {
            sendVerifyEmail(el_email.value);
        } else {
            ws.onopen = sendVerifyEmail(el_email.value);
        }
    }

    ws.onmessage = verifySubmit;
    ws.onclose = connect;
}

function validateEmail(email) {
    return /^[a-zA-Z0-9_.+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,63}$/.test(email);
}

function setValidationStyle(has_error) {
    document.querySelectorAll('input[type="email"]').forEach((el) => {
        el.classList[has_error ? 'add' : 'remove']('error-field');
    });
    document.querySelectorAll('.error-msg').forEach((el) => {
        el.classList[has_error ? 'remove' : 'add']('invisible');
    });
}

function getClientCountry() {
    let clients_country = sessionStorage.getItem('clients_country');

    // Try to get residence from client's info if logged-in
    if (!clients_country) {
        const accounts = JSON.parse(localStorage.getItem('client.accounts') || null);
        if (accounts) {
            Object.keys(accounts).some((loginid) => {
                if (accounts[loginid].residence) {
                    clients_country = accounts[loginid].residence;
                    setSession('clients_country', clients_country);
                    return true;
                }
                return false;
            });
        }
    }

    // Get required info from WebSocket
    const ws = wsConnect();

    function sendRequests() {
        if (!clients_country) wsSend(ws, { website_status: 1 });
        wsSend(ws, { time: 1 });
    }

    if (ws.readyState === 1) {
        sendRequests();
    } else {
        ws.onopen = sendRequests;
    }

    ws.onmessage = function (msg) {
        const response = JSON.parse(msg.data);
        if (response.website_status) {
            clients_country = response.website_status.clients_country;
            setSession('clients_country', clients_country);
        }
    };

    return clients_country;
}
<|endoftext|>


<commit_before>/**
 * Aperture Slider
 *
 * JavaScript object that can be used to create sliding multi-part forms.
 *
 * @category  ApertureSlider
 * @package   ApertureSlider
 * @author    Rod Mcnew <rmcnew@relivinc.com>
 * @license   License.txt New BSD License
 * @version   Release: 1.0
 * @link      http://ci.reliv.com/confluence
 */

/**
 * Aperture Slider Constructor
 *
 * @param {Object} apertureDiv jQuery object for the aperture div
 * @param {Object} [configOverride] defaults are below
 * @constructor
 */
var ApertureSlider = function (apertureDiv, configOverride) {

    /**
     * Default config options
     * @type {Object}
     */
    var config = {
        frameWidth:800,
        minHeight:400,
        framesPerView:1, //Values > 1 not compatible with hideOffScreenFrames
        animationDelay:400,
        frameSeparation:100, //Must be 0 if framesPerView > 1
        hideOffScreenFrames:true, //Prevents focus in off-screen forms.
        backButtonSupport:false, //Requires jQuery bbq library
        bbqStateId:'s'
    };

    /**
     * Always refers to me object unlike the 'me' JS variable;
     *
     * @type {ApertureSlider}
     */
    var me = this;

    var filmDiv, frameDivs, currentFrame, frameCount, totalFrameWidth,
        filmWidth, apertureWidth, maxFrameIndex, minFrameIndex;

    //Allow overriding of config vars
    if (typeof(configOverride) == 'object') {
        $.extend(config, configOverride);
    }

    /**
     * Runs immediately after this class is instantiated
     */
    me.init = function () {

        //Get all the divs we need to work with
        filmDiv = apertureDiv.children();
        frameDivs = filmDiv.children();

        //Init
        currentFrame = 1;
        minFrameIndex = 1;

        //Calculate widths and counts
        frameCount = filmDiv.children().length;
        totalFrameWidth = config.frameWidth + config.frameSeparation;
        filmWidth = (frameCount * totalFrameWidth * 2); // * 2 for good measure
        apertureWidth = config.framesPerView * totalFrameWidth;
        maxFrameIndex = frameCount - config.framesPerView;

        //Hide optional "Loading..." div
        apertureDiv.parent().find('.apertureLoading').hide();

        //Add css
        frameDivs.css('float', 'left');
        frameDivs.css('width', config.frameWidth + 'px');
        frameDivs.css('min-height', config.minHeight + 'px');
        frameDivs.css('margin-right', config.frameSeparation + 'px');
        filmDiv.css('width', filmWidth + 'px');
        filmDiv.css('margin-left: 0');
        apertureDiv.css('width', apertureWidth + 'px');
        apertureDiv.css('overflow', 'hidden');

        //Hide off-screen frame contents
        if (config.hideOffScreenFrames) {
            frameDivs.children().hide();
            me.getCurrentFrameDiv().children().show();
        }

        //Focus on first input if this is a form
        me.focusOnFirstInput();

        if (config.backButtonSupport) {
            //Support browser's refresh button
            me.handleHashChange();

            //Support browser's back button
            $(window).bind('hashchange', me.handleHashChange);
        }
    };

    /**
     * Sets the current frame. This is the meat of this class.
     *
     * @param {Integer} newFrame the frame that we want to switch to
     * @param {Function} [callback] is called when sliding is complete
     * @param {Boolean} [skipPushState] used internally only
     */
    me.goToFrame = function (newFrame, callback, skipPushState) {

        if (newFrame < minFrameIndex) {
            newFrame = minFrameIndex;
        }

        if (newFrame > maxFrameIndex) {
            newFrame = maxFrameIndex;
        }

        if (currentFrame == 0 || !newFrame) {
            /**
             * don't allow more sliding if we are already in the middle of a
             * slide or if the new frame is invalid
             */
            return false;
        } else if (currentFrame == newFrame) {
            //If we are already here, there is no reason to move
            if (typeof(callback) == 'function') {
                callback(currentFrame);
            }
            return true;
        } else {
            //Save the last frame that we were on so we can hide it after the
            //transition
            var lastFrame = currentFrame;

            //mark that we are currently sliding
            currentFrame = 0;

            //Show the next frame's contents
            if (config.hideOffScreenFrames) {
                me.getFrameDiv(newFrame).children().show();
            }

            //Mess with the url if browser button support is on
            if (!skipPushState) {
                me.pushStateToHistory(newFrame);
            }

            filmDiv.animate(
                {
                    'margin-left':-(newFrame - 1) * totalFrameWidth
                },
                config.animationDelay,
                function () {
                    //hide the previous frame's contents
                    if (config.hideOffScreenFrames) {
                        me.getFrameDiv(lastFrame).children().hide();
                    }

                    //mark that we are done sliding
                    currentFrame = newFrame;

                    me.focusOnFirstInput();

                    //call the passed-in callback if it is set
                    if (typeof(callback) == 'function') {
                        callback(currentFrame);
                    }

                    apertureDiv.trigger('apertureFrameChanged');

                }
            );

            return true;
        }

    };

    me.focusOnFirstInput = function () {
        var input = me.getCurrentFrameDiv().find('input').first();
        if (input) {
            input.focus();
        }
    };

    me.getCurrentFrameDiv = function () {
        return me.getFrameDiv(currentFrame);
    };

    me.getFrameDiv = function (frameNumber) {
        return $(frameDivs.get(frameNumber - 1));
    };

    /**
     * Returns which frame we are currently on
     *
     * @return {Number}
     */
    me.getCurrentFrame = function () {
        return currentFrame;
    };

    /**
     *
     * @param {Integer} frameDelta amount to change frame index by
     * @param {Function} [callback] is called when sliding is complete
     */
    me.go = function (frameDelta, callback) {
        me.goToFrame(currentFrame + frameDelta, callback);
    };

    /**
     * slide to next frame
     *
     * @param {Function} [callback] is called when sliding is complete
     */
    me.goForward = function (callback) {
        me.go(1, callback);
    };

    /**
     * Slide to last frame
     *
     * @param {Function} [callback] is called when sliding is complete
     */
    me.goBack = function (callback) {
        me.go(-1, callback);
    };

    /**
     * Go forward a whole page
     *
     * @param {Function} [callback] is called when sliding is complete
     */
    me.pageForward = function (callback) {
        me.go(config.framesPerView - 1, callback)
    };

    /**
     * Go backward a whole page
     *
     * @param {Function} [callback] is called when sliding is complete
     */
    me.pageBack = function (callback) {
        me.go(0 - config.framesPerView + 1, callback)
    };

    /**
     * Gets the number of frames
     *
     * @return {Number}
     */
    me.getFrameCount = function () {
        return frameCount;
    };

    /**
     * Handle browser back, forward, and refreash buttons
     */
    me.handleHashChange = function () {
        if (config.backButtonSupport) {
            var frame = $.bbq.getState(config.bbqStateId, true) || 1;
            me.goToFrame(
                parseFloat(frame), null, true
            );
        }
    };

    /**
     * Pushes the current state (which frame we are on) to the html5 history
     * object. This is used for browser button support.
     *
     * @param frame
     */
    me.pushStateToHistory = function (frame) {
        if (config.backButtonSupport) {
            var state = {};
            state[config.bbqStateId] = frame;
            $.bbq.pushState(state);
        }
    };

    me.init();
};<commit_msg>fix online apps to work with new slider<commit_after>/**
 * Aperture Slider
 *
 * JavaScript object that can be used to create sliding multi-part forms.
 *
 * @category  ApertureSlider
 * @package   ApertureSlider
 * @author    Rod Mcnew <rmcnew@relivinc.com>
 * @license   License.txt New BSD License
 * @version   Release: 1.0
 * @link      http://ci.reliv.com/confluence
 */

/**
 * Aperture Slider Constructor
 *
 * @param {Object} apertureDiv jQuery object for the aperture div
 * @param {Object} [configOverride] defaults are below
 * @constructor
 */
var ApertureSlider = function (apertureDiv, configOverride) {

    /**
     * Default config options
     * @type {Object}
     */
    var config = {
        frameWidth:800,
        minHeight:400,
        framesPerView:1, //Values > 1 not compatible with hideOffScreenFrames
        animationDelay:400,
        frameSeparation:100, //Must be 0 if framesPerView > 1
        hideOffScreenFrames:true, //Prevents focus in off-screen forms.
        backButtonSupport:false, //Requires jQuery bbq library
        bbqStateId:'s'
    };

    /**
     * Always refers to me object unlike the 'me' JS variable;
     *
     * @type {ApertureSlider}
     */
    var me = this;

    var filmDiv, frameDivs, currentFrame, frameCount, totalFrameWidth,
        filmWidth, apertureWidth, maxFrameIndex, minFrameIndex;

    //Allow overriding of config vars
    if (typeof(configOverride) == 'object') {
        $.extend(config, configOverride);
    }

    /**
     * Runs immediately after this class is instantiated
     */
    me.init = function () {

        //Get all the divs we need to work with
        filmDiv = apertureDiv.children();
        frameDivs = filmDiv.children();

        //Init
        currentFrame = 1;
        minFrameIndex = 1;

        //Calculate widths and counts
        frameCount = filmDiv.children().length;
        totalFrameWidth = config.frameWidth + config.frameSeparation;
        filmWidth = (frameCount * totalFrameWidth * 2); // * 2 for good measure
        apertureWidth = config.framesPerView * config.frameWidth;
        maxFrameIndex = frameCount - config.framesPerView;

        //Hide optional "Loading..." div
        apertureDiv.parent().find('.apertureLoading').hide();

        //Add css
        frameDivs.css('float', 'left');
        frameDivs.css('width', config.frameWidth + 'px');
        frameDivs.css('min-height', config.minHeight + 'px');
        frameDivs.css('margin-right', config.frameSeparation + 'px');
        filmDiv.css('width', filmWidth + 'px');
        filmDiv.css('margin-left: 0');
        apertureDiv.css('width', apertureWidth + 'px');
        apertureDiv.css('overflow', 'hidden');

        //Hide off-screen frame contents
        if (config.hideOffScreenFrames) {
            frameDivs.children().hide();
            me.getCurrentFrameDiv().children().show();
        }

        //Focus on first input if this is a form
        me.focusOnFirstInput();

        if (config.backButtonSupport) {
            //Support browser's refresh button
            me.handleHashChange();

            //Support browser's back button
            $(window).bind('hashchange', me.handleHashChange);
        }
    };

    /**
     * Sets the current frame. This is the meat of this class.
     *
     * @param {Integer} newFrame the frame that we want to switch to
     * @param {Function} [callback] is called when sliding is complete
     * @param {Boolean} [skipPushState] used internally only
     */
    me.goToFrame = function (newFrame, callback, skipPushState) {

        if (newFrame < minFrameIndex) {
            newFrame = minFrameIndex;
        }

        if (newFrame > maxFrameIndex) {
            newFrame = maxFrameIndex;
        }

        if (currentFrame == 0 || !newFrame) {
            /**
             * don't allow more sliding if we are already in the middle of a
             * slide or if the new frame is invalid
             */
            return false;
        } else if (currentFrame == newFrame) {
            //If we are already here, there is no reason to move
            if (typeof(callback) == 'function') {
                callback(currentFrame);
            }
            return true;
        } else {
            //Save the last frame that we were on so we can hide it after the
            //transition
            var lastFrame = currentFrame;

            //mark that we are currently sliding
            currentFrame = 0;

            //Show the next frame's contents
            if (config.hideOffScreenFrames) {
                me.getFrameDiv(newFrame).children().show();
            }

            //Mess with the url if browser button support is on
            if (!skipPushState) {
                me.pushStateToHistory(newFrame);
            }

            filmDiv.animate(
                {
                    'margin-left':-(newFrame - 1) * totalFrameWidth
                },
                config.animationDelay,
                function () {
                    //hide the previous frame's contents
                    if (config.hideOffScreenFrames) {
                        me.getFrameDiv(lastFrame).children().hide();
                    }

                    //mark that we are done sliding
                    currentFrame = newFrame;

                    me.focusOnFirstInput();

                    //call the passed-in callback if it is set
                    if (typeof(callback) == 'function') {
                        callback(currentFrame);
                    }

                    apertureDiv.trigger('apertureFrameChanged');

                }
            );

            return true;
        }

    };

    me.focusOnFirstInput = function () {
        var input = me.getCurrentFrameDiv().find('input').first();
        if (input) {
            input.focus();
        }
    };

    me.getCurrentFrameDiv = function () {
        return me.getFrameDiv(currentFrame);
    };

    me.getFrameDiv = function (frameNumber) {
        return $(frameDivs.get(frameNumber - 1));
    };

    /**
     * Returns which frame we are currently on
     *
     * @return {Number}
     */
    me.getCurrentFrame = function () {
        return currentFrame;
    };

    /**
     *
     * @param {Integer} frameDelta amount to change frame index by
     * @param {Function} [callback] is called when sliding is complete
     */
    me.go = function (frameDelta, callback) {
        me.goToFrame(currentFrame + frameDelta, callback);
    };

    /**
     * slide to next frame
     *
     * @param {Function} [callback] is called when sliding is complete
     */
    me.goForward = function (callback) {
        me.go(1, callback);
    };

    /**
     * Slide to last frame
     *
     * @param {Function} [callback] is called when sliding is complete
     */
    me.goBack = function (callback) {
        me.go(-1, callback);
    };

    /**
     * Go forward a whole page
     *
     * @param {Function} [callback] is called when sliding is complete
     */
    me.pageForward = function (callback) {
        me.go(config.framesPerView - 1, callback)
    };

    /**
     * Go backward a whole page
     *
     * @param {Function} [callback] is called when sliding is complete
     */
    me.pageBack = function (callback) {
        me.go(0 - config.framesPerView + 1, callback)
    };

    /**
     * Gets the number of frames
     *
     * @return {Number}
     */
    me.getFrameCount = function () {
        return frameCount;
    };

    /**
     * Handle browser back, forward, and refreash buttons
     */
    me.handleHashChange = function () {
        if (config.backButtonSupport) {
            var frame = $.bbq.getState(config.bbqStateId, true) || 1;
            me.goToFrame(
                parseFloat(frame), null, true
            );
        }
    };

    /**
     * Pushes the current state (which frame we are on) to the html5 history
     * object. This is used for browser button support.
     *
     * @param frame
     */
    me.pushStateToHistory = function (frame) {
        if (config.backButtonSupport) {
            var state = {};
            state[config.bbqStateId] = frame;
            $.bbq.pushState(state);
        }
    };

    me.init();
};<|endoftext|>