<commit_before>// OS Monitoring for Node.js

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

var util     = require('util'),
    os       = require('os'),
    events   = require('events'),
    stream   = require('stream'),
    _        = require('underscore'),
    critical = os.cpus().length,
    defaults = {
      delay     : 3000,
      critical1 : critical,
      critical5 : critical,
      critical15: critical,
      freemem   : 0,
      uptime    : 0,
      silent    : false,
      stream    : false
    };

// constructor
var Monitor = function() {
  if(stream.Readable) {
    stream.Readable.call(this, {highWaterMark: 102400});
  } else {
    events.EventEmitter.call(this);
  }

  this._monitorState = {
    running: false,
    streamBuffering: true,
    interval: undefined,
    config: _.clone(defaults)
  };
};

if(stream.Readable) {
  util.inherits(Monitor, stream.Readable);
} else {
  util.inherits(Monitor, events.EventEmitter);
}

Monitor.prototype.version = '0.1.5';

// readable stream implementation requirement
Monitor.prototype._read = function() {
  this._monitorState.streamBuffering = true;
};

Monitor.prototype.sendEvent = function(event, data) {
  // for EventEmitter
  this.emit(event, data);
  // for readable Stream
  if(this._monitorState.config.stream && this._monitorState.streamBuffering) {
    var prettyJSON = os.EOL + JSON.stringify(data, null, 2);
    if( !this.push(new Buffer(prettyJSON)) ) {
      this._monitorState.streamBuffering = false;
    }
  }
};

Monitor.prototype.start = function(options) {

  var self = this;

  self.stop()
      .config(options);

  this._monitorState.interval  = setInterval(function() {
    var info = {
      loadavg  : os.loadavg(),
      uptime   : os.uptime(),
      freemem  : os.freemem(),
      totalmem : os.totalmem()
    },
    config = self._monitorState.config,
    freemem  = (config.freemem < 1) ? config.freemem * info.totalmem : config.freemem;

    if(!config.silent) {
      self.sendEvent('monitor', _.extend({type: 'monitor'}, info));
    }
    if(info.loadavg[0] > config.critical1) {
      self.sendEvent('loadavg1', _.extend({type: 'loadavg1'}, info));
    }
    if(info.loadavg[1] > config.critical5) {
      self.sendEvent('loadavg5', _.extend({type: 'loadavg5'}, info));
    }
    if(info.loadavg[2] > config.critical15) {
      self.sendEvent('loadavg15', _.extend({type: 'loadavg15'}, info));
    }
    if(info.freemem < freemem) {
      self.sendEvent('freemem', _.extend({type: 'freemem'}, info));
    }
    if(Number(config.uptime) && info.uptime > Number(config.uptime)) {
      self.sendEvent('uptime', _.extend({type: 'uptime'}, info));
    }
  }, this._monitorState.config.delay);

  if(!self.isRunning()) {
    this._monitorState.running = true;
    self.sendEvent('start', {type: 'start'});
  }

  return self;
};

Monitor.prototype.stop = function() {

  clearInterval(this._monitorState.interval);

  if(this.isRunning()) {
    this._monitorState.running = false;
    this.sendEvent('stop', {type: 'stop'});
  }

  return this;
};

Monitor.prototype.config = function(options) {

  if(_.isObject(options)) {
    _.extend(this._monitorState.config, options);
    this.sendEvent('config', {type: 'config', options: _.clone(options)});
  }

  return this._monitorState.config;
};

Monitor.prototype.isRunning = function() {
  return !!this._monitorState.running;
};

Monitor.prototype.throttle = function(event, handler, wait) {
  var self     = this,
      _handler = _.wrap(handler, function(fn) {
                   if(self.isRunning()) {
                     fn.apply(this, _.toArray(arguments).slice(1));
                   }
                 });
  return self.on.call(self, event, _.throttle(_handler, wait || this._monitorState.config.throttle));
};

/*
 * convenience methods
 */

Monitor.prototype._sanitizeNumber = function(n) {
  if(!_.isNumber(n)) {
    throw new Error("Number expected");
  }
  if(!n || n < 0) {
    throw new Error("Number must be greater than 0");
  }
  // Math.pow(2, 31);
  if(n >= 2147483648) {
    throw new Error("Number must be smaller than 2147483648");
  }
  return n;
};

Monitor.prototype.seconds = function(n) {
  return this._sanitizeNumber(n * 1000);
};

Monitor.prototype.minutes = function(n) {
  return this._sanitizeNumber(n * this.seconds(60));
};

Monitor.prototype.hours = function(n) {
  return this._sanitizeNumber(n * this.minutes(60));
};

Monitor.prototype.days = function(n) {
  return this._sanitizeNumber(n * this.hours(24));
};

// deprecated stuff
Monitor.prototype.setConfig = util.deprecate(Monitor.prototype.config);

// expose OS module
Monitor.prototype.os = os;

// expose Underscore
Monitor.prototype._ = _;

// create object
var Osm = new Monitor();

// expose main class
Osm.Monitor = Monitor;

module.exports = Osm;

<commit_msg>introduce 'immediate' option<commit_after>// OS Monitoring for Node.js

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

var util     = require('util'),
    os       = require('os'),
    events   = require('events'),
    stream   = require('stream'),
    _        = require('underscore'),
    critical = os.cpus().length,
    defaults = {
      delay     : 3000,
      critical1 : critical,
      critical5 : critical,
      critical15: critical,
      freemem   : 0,
      uptime    : 0,
      silent    : false,
      stream    : false,
      immediate : false
    };

// constructor
var Monitor = function() {
  if(stream.Readable) {
    stream.Readable.call(this, {highWaterMark: 102400});
  } else {
    events.EventEmitter.call(this);
  }

  this._monitorState = {
    running: false,
    streamBuffering: true,
    interval: undefined,
    config: _.clone(defaults)
  };
};

if(stream.Readable) {
  util.inherits(Monitor, stream.Readable);
} else {
  util.inherits(Monitor, events.EventEmitter);
}

Monitor.prototype.version = '0.1.5';

// readable stream implementation requirement
Monitor.prototype._read = function() {
  this._monitorState.streamBuffering = true;
};

Monitor.prototype.sendEvent = function(event, data) {
  // for EventEmitter
  this.emit(event, data);
  // for readable Stream
  if(this._monitorState.config.stream && this._monitorState.streamBuffering) {
    var prettyJSON = os.EOL + JSON.stringify(data, null, 2);
    if( !this.push(new Buffer(prettyJSON)) ) {
      this._monitorState.streamBuffering = false;
    }
  }
};

Monitor.prototype.start = function(options) {

  var self = this;

  self.stop()
      .config(options);

  var cycle = function() {
    var info = {
      loadavg  : os.loadavg(),
      uptime   : os.uptime(),
      freemem  : os.freemem(),
      totalmem : os.totalmem()
    },
    config = self._monitorState.config,
    freemem  = (config.freemem < 1) ? config.freemem * info.totalmem : config.freemem;

    if(!config.silent) {
      self.sendEvent('monitor', _.extend({type: 'monitor'}, info));
    }
    if(info.loadavg[0] > config.critical1) {
      self.sendEvent('loadavg1', _.extend({type: 'loadavg1'}, info));
    }
    if(info.loadavg[1] > config.critical5) {
      self.sendEvent('loadavg5', _.extend({type: 'loadavg5'}, info));
    }
    if(info.loadavg[2] > config.critical15) {
      self.sendEvent('loadavg15', _.extend({type: 'loadavg15'}, info));
    }
    if(info.freemem < freemem) {
      self.sendEvent('freemem', _.extend({type: 'freemem'}, info));
    }
    if(Number(config.uptime) && info.uptime > Number(config.uptime)) {
      self.sendEvent('uptime', _.extend({type: 'uptime'}, info));
    }
  };

  if(self.config().immediate) {
    process.nextTick(cycle);
  }
  this._monitorState.interval  = setInterval(cycle, self.config().delay);

  if(!self.isRunning()) {
    this._monitorState.running = true;
    self.sendEvent('start', {type: 'start'});
  }

  return self;
};

Monitor.prototype.stop = function() {

  clearInterval(this._monitorState.interval);

  if(this.isRunning()) {
    this._monitorState.running = false;
    this.sendEvent('stop', {type: 'stop'});
  }

  return this;
};

Monitor.prototype.config = function(options) {

  if(_.isObject(options)) {
    _.extend(this._monitorState.config, options);
    this.sendEvent('config', {type: 'config', options: _.clone(options)});
  }

  return this._monitorState.config;
};

Monitor.prototype.isRunning = function() {
  return !!this._monitorState.running;
};

Monitor.prototype.throttle = function(event, handler, wait) {
  var self     = this,
      _handler = _.wrap(handler, function(fn) {
                   if(self.isRunning()) {
                     fn.apply(this, _.toArray(arguments).slice(1));
                   }
                 });
  return self.on.call(self, event, _.throttle(_handler, wait || this._monitorState.config.throttle));
};

/*
 * convenience methods
 */

Monitor.prototype._sanitizeNumber = function(n) {
  if(!_.isNumber(n)) {
    throw new Error("Number expected");
  }
  if(!n || n < 0) {
    throw new Error("Number must be greater than 0");
  }
  // Math.pow(2, 31);
  if(n >= 2147483648) {
    throw new Error("Number must be smaller than 2147483648");
  }
  return n;
};

Monitor.prototype.seconds = function(n) {
  return this._sanitizeNumber(n * 1000);
};

Monitor.prototype.minutes = function(n) {
  return this._sanitizeNumber(n * this.seconds(60));
};

Monitor.prototype.hours = function(n) {
  return this._sanitizeNumber(n * this.minutes(60));
};

Monitor.prototype.days = function(n) {
  return this._sanitizeNumber(n * this.hours(24));
};

// deprecated stuff
Monitor.prototype.setConfig = util.deprecate(Monitor.prototype.config);

// expose OS module
Monitor.prototype.os = os;

// expose Underscore
Monitor.prototype._ = _;

// create object
var Osm = new Monitor();

// expose main class
Osm.Monitor = Monitor;

module.exports = Osm;

<|endoftext|>


<commit_before>import { combineReducers } from 'redux'

import {
  OPEN_FOLDER,
  OPEN_FOLDER_SUCCESS,
  OPEN_FOLDER_FAILURE,
  SORT_FOLDER,
  SORT_FOLDER_SUCCESS,
  SORT_FOLDER_FAILURE,
  FETCH_RECENT,
  FETCH_RECENT_SUCCESS,
  FETCH_RECENT_FAILURE,
  FETCH_MORE_FILES_SUCCESS,
  UPLOAD_FILE_SUCCESS,
  TRASH_FILES_SUCCESS,
  CREATE_FOLDER_SUCCESS
} from '../actions'

import {
  EMPTY_TRASH,
  EMPTY_TRASH_SUCCESS,
  EMPTY_TRASH_FAILURE,
  RESTORE_FILES_SUCCESS,
  DESTROY_FILES,
  DESTROY_FILES_SUCCESS,
  DESTROY_FILES_FAILURE
} from '../ducks/trash'
import { RENAME_SUCCESS } from '../ducks/files/rename'
import { isDirectory } from '../ducks/files/files'

import { ROOT_DIR_ID, TRASH_DIR_ID } from '../constants/config.js'

const hasDisplayedSomething = (state = false, action) => {
  switch (action.type) {
    case OPEN_FOLDER_SUCCESS:
    case FETCH_RECENT_SUCCESS:
      return true
    default:
      return state
  }
}

const isOpening = (state = false, action) => {
  switch (action.type) {
    case OPEN_FOLDER:
    case FETCH_RECENT:
      return true
    case OPEN_FOLDER_SUCCESS:
    case FETCH_RECENT_SUCCESS:
      return false
    default:
      return state
  }
}

export const isNavigating = ({ view }) =>
  view.hasDisplayedSomething && view.isOpening

// reducer for the currently displayed folder properties
const displayedFolder = (state = null, action) => {
  switch (action.type) {
    case OPEN_FOLDER_SUCCESS:
      return action.folder
    case FETCH_RECENT_SUCCESS:
      return null
    default:
      return state
  }
}

const openedFolderId = (state = null, action) => {
  switch (action.type) {
    case OPEN_FOLDER:
      return action.folderId
    case FETCH_RECENT:
      return null
    default:
      return state
  }
}

const fileCount = (state = null, action) => {
  switch (action.type) {
    case OPEN_FOLDER_SUCCESS:
    case FETCH_RECENT_SUCCESS:
      return action.fileCount
    case UPLOAD_FILE_SUCCESS:
    case CREATE_FOLDER_SUCCESS:
      return state + 1
    case TRASH_FILES_SUCCESS:
    case DESTROY_FILES_SUCCESS:
      return state - action.ids.length
    case RESTORE_FILES_SUCCESS:
      return state + action.ids.length
    default:
      return state
  }
}

const sort = (state = null, action) => {
  switch (action.type) {
    case SORT_FOLDER:
      return {
        attribute: action.sortAttribute,
        order: action.sortOrder
      }
    case OPEN_FOLDER_SUCCESS:
    case FETCH_RECENT_SUCCESS:
      return null
    default:
      return state
  }
}

const updateItem = (file, files) => {
  const withoutFile = files.filter(f => f.id !== file.id)
  return insertItem(file, withoutFile)
}

const insertItem = (file, array, currentItemCount) => {
  const index = indexFor(file, array, (a, b) => {
    if (a.type !== b.type) {
      return isDirectory(a) ? -1 : 1
    }
    return a.name.localeCompare(b.name)
  })
  // if we only have partially fetched the file list and the new item
  // position is in the unfetched part of the list, we don't add the item
  // to the list
  if (index === array.length - 1 && array.length < currentItemCount) {
    return array
  }
  return [...array.slice(0, index + 1), file, ...array.slice(index + 1)]
}

const indexFor = (file, array, compareFn, start = 0, end = array.length) => {
  if (array.length === 0) return -1
  const pivot = parseInt(start + (end - start) / 2, 10)
  const c = compareFn(file, array[pivot])
  if (end - start <= 1) return c === -1 ? pivot - 1 : pivot
  switch (c) {
    case -1:
      return indexFor(file, array, compareFn, start, pivot)
    case 0:
      return pivot
    case 1:
      return indexFor(file, array, compareFn, pivot, end)
  }
}

// reducer for the full file list of the currently displayed folder
const files = (state = [], action) => {
  switch (action.type) {
    case OPEN_FOLDER_SUCCESS:
    case FETCH_RECENT_SUCCESS:
    case SORT_FOLDER_SUCCESS:
      return action.files
    case FETCH_MORE_FILES_SUCCESS:
      const clone = state.slice(0)
      action.files.forEach((f, i) => {
        clone[action.skip + i] = f
      })
      return clone
    case RENAME_SUCCESS:
      return updateItem(action.file, state)
    case UPLOAD_FILE_SUCCESS:
      return insertItem(action.file, state)
    case CREATE_FOLDER_SUCCESS:
      return insertItem(action.folder, state, action.currentFileCount)
    case TRASH_FILES_SUCCESS:
    case RESTORE_FILES_SUCCESS:
    case DESTROY_FILES_SUCCESS:
      return state.filter(f => action.ids.indexOf(f.id) === -1)
    case EMPTY_TRASH_SUCCESS:
      return []
    default:
      return state
  }
}

const fetchStatus = (state = 'pending', action) => {
  switch (action.type) {
    // there's a trick here : we set the fetchStatus to 'pending'
    // on initial state so that the loading spinner is only showed
    // when the app is launched or when the user use the back button
    case EMPTY_TRASH: // we temporarily display the spinner when working in the trashed
    case DESTROY_FILES: // TODO: display a spinner in the confirm modal instead
      return 'pending'
    case OPEN_FOLDER_SUCCESS:
    case FETCH_RECENT_SUCCESS:
    case EMPTY_TRASH_SUCCESS:
    case EMPTY_TRASH_FAILURE:
    case DESTROY_FILES_SUCCESS:
    case DESTROY_FILES_FAILURE:
      return 'loaded'
    case OPEN_FOLDER_FAILURE:
    case SORT_FOLDER_FAILURE:
    case FETCH_RECENT_FAILURE:
      return 'failed'
    default:
      return state
  }
}

const lastFetch = (state = null, action) => {
  switch (action.type) {
    case OPEN_FOLDER_SUCCESS:
    case OPEN_FOLDER_FAILURE:
    case SORT_FOLDER_SUCCESS:
    case SORT_FOLDER_FAILURE:
    case FETCH_RECENT_SUCCESS:
    case FETCH_RECENT_FAILURE:
      return Date.now()
    default:
      return state
  }
}

export default combineReducers({
  hasDisplayedSomething,
  isOpening,
  displayedFolder,
  openedFolderId,
  fileCount,
  sort,
  files,
  fetchStatus,
  lastFetch
})

// TODO: temp
export const getFilesWithLinks = ({ view }, folderId) =>
  view.filesWithLinks[folderId]

export const getVisibleFiles = ({ view }) => view.files

export const getSort = ({ view }) => view.sort

export const getFileById = ({ view }, id) => {
  const file = view.files.find(f => f && f.id && f.id === id)
  if (!file) return null
  // we need the path for some actions, like selection download
  // but the stack only provides the path for folders...
  return Object.assign({}, file, { path: getFilePath({ view }, file) })
}

const isRootFolder = folder => folder.id === ROOT_DIR_ID

export const getFilePath = ({ view }, file) => {
  const { displayedFolder } = view
  return isDirectory(file)
    ? file.path
    : displayedFolder && !isRootFolder(displayedFolder)
      ? `${displayedFolder.path}/${file.name}`
      : `/${file.name}`
}

export const getFolderIdFromRoute = (location, params) => {
  if (params.folderId) return params.folderId
  if (location.pathname.match(/^\/folder/)) return ROOT_DIR_ID
  if (location.pathname.match(/^\/trash/)) return TRASH_DIR_ID
}

export const getFolderUrl = (folderId, location) => {
  if (folderId === undefined) return '/folder'
  if (folderId === ROOT_DIR_ID) return '/folder'
  if (folderId === TRASH_DIR_ID) return '/trash'
  const url = location.pathname.match(/^\/folder/) ? '/folder/' : '/trash/'
  return url + folderId
}

// reconstruct the whole path to the current folder (first element is the root, the last is the current folder)
export const getFolderPath = ({ view }, location, isPublic) => {
  const { displayedFolder } = view
  const path = []
  const isBrowsingTrash = /^\/trash/.test(location.pathname)
  const isBrowsingRecentFiles = /^\/recent/.test(location.pathname)
  // dring the first fetch, displayedFolder is null, and we don't want to display anything
  if (displayedFolder) {
    path.push(displayedFolder)
    // does the folder have parents to display? The trash folder has the root folder as parent, but we don't want to show that.
    const parent = displayedFolder.parent
    if (
      parent &&
      parent.id &&
      !(isBrowsingTrash && parent.id === ROOT_DIR_ID)
    ) {
      path.unshift(parent)
      // has the parent a parent too?
      if (
        parent.dir_id &&
        !(isBrowsingTrash && parent.dir_id === ROOT_DIR_ID) &&
        !isPublic
      ) {
        // since we don't *actually* have any information about the parent's parent, we have to fake it
        path.unshift({ id: parent.dir_id })
      }
    }
  }
  if (isPublic) {
    return path
  }
  // finally, we need to make sure we have the root level folder, which can be either the root, or the trash folder.
  if (!isBrowsingRecentFiles) {
    const hasRootFolder =
      path[0] && (path[0].id === ROOT_DIR_ID || path[0].id === TRASH_DIR_ID)
    if (!hasRootFolder) {
      // if we don't have one, we add it manually
      path.unshift({
        id: isBrowsingTrash ? TRASH_DIR_ID : ROOT_DIR_ID
      })
    }
  }
  return path
}
<commit_msg>feat: Show loading state when sorting files<commit_after>import { combineReducers } from 'redux'

import {
  OPEN_FOLDER,
  OPEN_FOLDER_SUCCESS,
  OPEN_FOLDER_FAILURE,
  SORT_FOLDER,
  SORT_FOLDER_SUCCESS,
  SORT_FOLDER_FAILURE,
  FETCH_RECENT,
  FETCH_RECENT_SUCCESS,
  FETCH_RECENT_FAILURE,
  FETCH_MORE_FILES_SUCCESS,
  UPLOAD_FILE_SUCCESS,
  TRASH_FILES_SUCCESS,
  CREATE_FOLDER_SUCCESS
} from '../actions'

import {
  EMPTY_TRASH,
  EMPTY_TRASH_SUCCESS,
  EMPTY_TRASH_FAILURE,
  RESTORE_FILES_SUCCESS,
  DESTROY_FILES,
  DESTROY_FILES_SUCCESS,
  DESTROY_FILES_FAILURE
} from '../ducks/trash'
import { RENAME_SUCCESS } from '../ducks/files/rename'
import { isDirectory } from '../ducks/files/files'

import { ROOT_DIR_ID, TRASH_DIR_ID } from '../constants/config.js'

const hasDisplayedSomething = (state = false, action) => {
  switch (action.type) {
    case OPEN_FOLDER_SUCCESS:
    case FETCH_RECENT_SUCCESS:
      return true
    default:
      return state
  }
}

const isOpening = (state = false, action) => {
  switch (action.type) {
    case OPEN_FOLDER:
    case FETCH_RECENT:
      return true
    case OPEN_FOLDER_SUCCESS:
    case FETCH_RECENT_SUCCESS:
      return false
    default:
      return state
  }
}

export const isNavigating = ({ view }) =>
  view.hasDisplayedSomething && view.isOpening

// reducer for the currently displayed folder properties
const displayedFolder = (state = null, action) => {
  switch (action.type) {
    case OPEN_FOLDER_SUCCESS:
      return action.folder
    case FETCH_RECENT_SUCCESS:
      return null
    default:
      return state
  }
}

const openedFolderId = (state = null, action) => {
  switch (action.type) {
    case OPEN_FOLDER:
      return action.folderId
    case FETCH_RECENT:
      return null
    default:
      return state
  }
}

const fileCount = (state = null, action) => {
  switch (action.type) {
    case OPEN_FOLDER_SUCCESS:
    case FETCH_RECENT_SUCCESS:
      return action.fileCount
    case UPLOAD_FILE_SUCCESS:
    case CREATE_FOLDER_SUCCESS:
      return state + 1
    case TRASH_FILES_SUCCESS:
    case DESTROY_FILES_SUCCESS:
      return state - action.ids.length
    case RESTORE_FILES_SUCCESS:
      return state + action.ids.length
    default:
      return state
  }
}

const sort = (state = null, action) => {
  switch (action.type) {
    case SORT_FOLDER:
      return {
        attribute: action.sortAttribute,
        order: action.sortOrder
      }
    case OPEN_FOLDER_SUCCESS:
    case FETCH_RECENT_SUCCESS:
      return null
    default:
      return state
  }
}

const updateItem = (file, files) => {
  const withoutFile = files.filter(f => f.id !== file.id)
  return insertItem(file, withoutFile)
}

const insertItem = (file, array, currentItemCount) => {
  const index = indexFor(file, array, (a, b) => {
    if (a.type !== b.type) {
      return isDirectory(a) ? -1 : 1
    }
    return a.name.localeCompare(b.name)
  })
  // if we only have partially fetched the file list and the new item
  // position is in the unfetched part of the list, we don't add the item
  // to the list
  if (index === array.length - 1 && array.length < currentItemCount) {
    return array
  }
  return [...array.slice(0, index + 1), file, ...array.slice(index + 1)]
}

const indexFor = (file, array, compareFn, start = 0, end = array.length) => {
  if (array.length === 0) return -1
  const pivot = parseInt(start + (end - start) / 2, 10)
  const c = compareFn(file, array[pivot])
  if (end - start <= 1) return c === -1 ? pivot - 1 : pivot
  switch (c) {
    case -1:
      return indexFor(file, array, compareFn, start, pivot)
    case 0:
      return pivot
    case 1:
      return indexFor(file, array, compareFn, pivot, end)
  }
}

// reducer for the full file list of the currently displayed folder
const files = (state = [], action) => {
  switch (action.type) {
    case OPEN_FOLDER_SUCCESS:
    case FETCH_RECENT_SUCCESS:
    case SORT_FOLDER_SUCCESS:
      return action.files
    case FETCH_MORE_FILES_SUCCESS:
      const clone = state.slice(0)
      action.files.forEach((f, i) => {
        clone[action.skip + i] = f
      })
      return clone
    case RENAME_SUCCESS:
      return updateItem(action.file, state)
    case UPLOAD_FILE_SUCCESS:
      return insertItem(action.file, state)
    case CREATE_FOLDER_SUCCESS:
      return insertItem(action.folder, state, action.currentFileCount)
    case TRASH_FILES_SUCCESS:
    case RESTORE_FILES_SUCCESS:
    case DESTROY_FILES_SUCCESS:
      return state.filter(f => action.ids.indexOf(f.id) === -1)
    case EMPTY_TRASH_SUCCESS:
      return []
    default:
      return state
  }
}

const fetchStatus = (state = 'pending', action) => {
  switch (action.type) {
    // there's a trick here : we set the fetchStatus to 'pending'
    // on initial state so that the loading spinner is only showed
    // when the app is launched or when the user use the back button
    case EMPTY_TRASH: // we temporarily display the spinner when working in the trashed
    case DESTROY_FILES: // TODO: display a spinner in the confirm modal instead
    case SORT_FOLDER:
      return 'pending'
    case OPEN_FOLDER_SUCCESS:
    case SORT_FOLDER_SUCCESS:
    case FETCH_RECENT_SUCCESS:
    case EMPTY_TRASH_SUCCESS:
    case EMPTY_TRASH_FAILURE:
    case DESTROY_FILES_SUCCESS:
    case DESTROY_FILES_FAILURE:
      return 'loaded'
    case OPEN_FOLDER_FAILURE:
    case SORT_FOLDER_FAILURE:
    case FETCH_RECENT_FAILURE:
      return 'failed'
    default:
      return state
  }
}

const lastFetch = (state = null, action) => {
  switch (action.type) {
    case OPEN_FOLDER_SUCCESS:
    case OPEN_FOLDER_FAILURE:
    case SORT_FOLDER_SUCCESS:
    case SORT_FOLDER_FAILURE:
    case FETCH_RECENT_SUCCESS:
    case FETCH_RECENT_FAILURE:
      return Date.now()
    default:
      return state
  }
}

export default combineReducers({
  hasDisplayedSomething,
  isOpening,
  displayedFolder,
  openedFolderId,
  fileCount,
  sort,
  files,
  fetchStatus,
  lastFetch
})

// TODO: temp
export const getFilesWithLinks = ({ view }, folderId) =>
  view.filesWithLinks[folderId]

export const getVisibleFiles = ({ view }) => view.files

export const getSort = ({ view }) => view.sort

export const getFileById = ({ view }, id) => {
  const file = view.files.find(f => f && f.id && f.id === id)
  if (!file) return null
  // we need the path for some actions, like selection download
  // but the stack only provides the path for folders...
  return Object.assign({}, file, { path: getFilePath({ view }, file) })
}

const isRootFolder = folder => folder.id === ROOT_DIR_ID

export const getFilePath = ({ view }, file) => {
  const { displayedFolder } = view
  return isDirectory(file)
    ? file.path
    : displayedFolder && !isRootFolder(displayedFolder)
      ? `${displayedFolder.path}/${file.name}`
      : `/${file.name}`
}

export const getFolderIdFromRoute = (location, params) => {
  if (params.folderId) return params.folderId
  if (location.pathname.match(/^\/folder/)) return ROOT_DIR_ID
  if (location.pathname.match(/^\/trash/)) return TRASH_DIR_ID
}

export const getFolderUrl = (folderId, location) => {
  if (folderId === undefined) return '/folder'
  if (folderId === ROOT_DIR_ID) return '/folder'
  if (folderId === TRASH_DIR_ID) return '/trash'
  const url = location.pathname.match(/^\/folder/) ? '/folder/' : '/trash/'
  return url + folderId
}

// reconstruct the whole path to the current folder (first element is the root, the last is the current folder)
export const getFolderPath = ({ view }, location, isPublic) => {
  const { displayedFolder } = view
  const path = []
  const isBrowsingTrash = /^\/trash/.test(location.pathname)
  const isBrowsingRecentFiles = /^\/recent/.test(location.pathname)
  // dring the first fetch, displayedFolder is null, and we don't want to display anything
  if (displayedFolder) {
    path.push(displayedFolder)
    // does the folder have parents to display? The trash folder has the root folder as parent, but we don't want to show that.
    const parent = displayedFolder.parent
    if (
      parent &&
      parent.id &&
      !(isBrowsingTrash && parent.id === ROOT_DIR_ID)
    ) {
      path.unshift(parent)
      // has the parent a parent too?
      if (
        parent.dir_id &&
        !(isBrowsingTrash && parent.dir_id === ROOT_DIR_ID) &&
        !isPublic
      ) {
        // since we don't *actually* have any information about the parent's parent, we have to fake it
        path.unshift({ id: parent.dir_id })
      }
    }
  }
  if (isPublic) {
    return path
  }
  // finally, we need to make sure we have the root level folder, which can be either the root, or the trash folder.
  if (!isBrowsingRecentFiles) {
    const hasRootFolder =
      path[0] && (path[0].id === ROOT_DIR_ID || path[0].id === TRASH_DIR_ID)
    if (!hasRootFolder) {
      // if we don't have one, we add it manually
      path.unshift({
        id: isBrowsingTrash ? TRASH_DIR_ID : ROOT_DIR_ID
      })
    }
  }
  return path
}
<|endoftext|>


<commit_before>var logger = require("../models/Logger");
var url = require('url');

var RestPushConnector = function(dispatcher, prefix, authenticator) {
    logger.info("Init REST push connector server");
    this.dispatcher = dispatcher;
    this.prefix = prefix;
    this.authenticator = authenticator;

    //take parameters from request, create a dispatch and send it to dispatcher
};

RestPushConnector.prototype.cors = function(req, res) {
    var origin = req.headers.origin || "*";
    res.setHeader('Access-Control-Allow-Origin', origin);
    res.setHeader('Access-Control-Request-Method', '*');
    res.setHeader('Access-Control-Allow-Methods', 'OPTIONS, POST');
    res.setHeader('Access-Control-Allow-Headers', 'content-type');
};

RestPushConnector.prototype.push = function(req, res) {
    var pushUrl = req.url.replace(this.prefix, '');

    //preflight request
    if (req.method == "OPTIONS") {
        this.cors(req, res);
        res.end();
        return;
    }

    //here comes the push data
    var chunks = [];
    if (req.method == 'POST') {

        //allow CORS
        this.cors(req, res);

        var me = this;
        req.on('data', function(chunk) {
            chunks.push(chunk);
        });
        req.on('end', function(chunk) {
            //console.log("Received body data:");
            var rawdata = Buffer.concat(chunks);
            //console.log(rawdata);

            try {
                var pushData = JSON.parse(rawdata);
            } catch (e) {
                logger.info(rawdata, "is not json");
                return me.fail(req, res, 400, "Data was not json");
            }

            var cmd = pushData.cmd || "";
            var authData = pushData.auth || {};

            if (!("data" in pushData)) {
                logger.debug("data parameter missing in pushdata");
                return me.fail(req, res, 401, "data missing");
            }

            var event = pushData.data.event || "";
            var user = pushData.data.user || "";
            var users = pushData.data.users || [];
            var channel = pushData.data.channel || "";
            var channels = pushData.data.channels || [];
            var payload = pushData.data.payload || {};

            //check auth here
            //only if an authenticator is defined
            if (me.authenticator) {
                if (!(me.authenticator.verify(authData))) {
                    logger.debug("Authenticator denied PUSH");
                    return me.fail(req, res, 401, "Wrong auth data");
                }
            }

            if (user) {
                if (typeof user === "string") {
                    users.push(user);
                    logger.debug("User " + user);
                }
            }

            if (channel) {
                if (typeof channel === "string") {
                    channels.push(channel);
                }
            }

            //create dispatch
            var targets = {};
            if (channels.length > 0) targets["channels"] = channels;
            if (users.length > 0) targets["users"] = users;
            if (cmd === "notifyAll") {
                targets = {
                    broadcast: true
                };
            }
            //console.log(payload);
            //console.log(targets);
            logger.info("User " + user + " event " + event);
            me.dispatcher.dispatchEventDataTarget(event, payload, targets);
            me.success(req, res, 200, "OK");
            return pushData;
        });
    } else {
        logger.info("[405] " + req.method + " to " + req.url);
        res.writeHead(405, "Method not supported", {'Content-Type': 'text/html'});
        res.end('<title>405 - Method not supported</title>
Method not supported.
');
        return false;
    }
};

RestPushConnector.prototype.success = function(req, res, code, message) {
    res.statusCode = code;
    res.end(message);
    return true;
};

RestPushConnector.prototype.fail = function(req, res, code, message) {
    res.statusCode = code;
    res.end(message);
    return false;
};

module.exports = RestPushConnector;
<commit_msg>TODO rework to enable pushConnector to send pushData back<commit_after>var logger = require("../models/Logger");
var url = require('url');

var RestPushConnector = function(dispatcher, prefix, authenticator) {
    logger.info("Init REST push connector server");
    this.dispatcher = dispatcher;
    this.prefix = prefix;
    this.authenticator = authenticator;

    //take parameters from request, create a dispatch and send it to dispatcher
};

RestPushConnector.prototype.cors = function(req, res) {
    var origin = req.headers.origin || "*";
    res.setHeader('Access-Control-Allow-Origin', origin);
    res.setHeader('Access-Control-Request-Method', '*');
    res.setHeader('Access-Control-Allow-Methods', 'OPTIONS, POST');
    res.setHeader('Access-Control-Allow-Headers', 'content-type');
};

RestPushConnector.prototype.push = function(req, res) {
    var pushUrl = req.url.replace(this.prefix, '');

    //preflight request
    if (req.method == "OPTIONS") {
        this.cors(req, res);
        res.end();
        return;
    }

    //here comes the push data
    var chunks = [];
    if (req.method == 'POST') {

        //allow CORS
        this.cors(req, res);

        var me = this;
        req.on('data', function(chunk) {
            chunks.push(chunk);
        });
        req.on('end', function(chunk) {
            //console.log("Received body data:");
            var rawdata = Buffer.concat(chunks);
            //console.log(rawdata);

            try {
                var pushData = JSON.parse(rawdata);
            } catch (e) {
                logger.info(rawdata, "is not json");
                return me.fail(req, res, 400, "Data was not json");
            }

            var cmd = pushData.cmd || "";
            var authData = pushData.auth || {};

            if (!("data" in pushData)) {
                logger.debug("data parameter missing in pushdata");
                return me.fail(req, res, 401, "data missing");
            }

            var event = pushData.data.event || "";
            var user = pushData.data.user || "";
            var users = pushData.data.users || [];
            var channel = pushData.data.channel || "";
            var channels = pushData.data.channels || [];
            var payload = pushData.data.payload || {};

            //check auth here
            //only if an authenticator is defined
            if (me.authenticator) {
                if (!(me.authenticator.verify(authData))) {
                    logger.debug("Authenticator denied PUSH");
                    return me.fail(req, res, 401, "Wrong auth data");
                }
            }

            if (user) {
                if (typeof user === "string") {
                    users.push(user);
                    logger.debug("User " + user);
                }
            }

            if (channel) {
                if (typeof channel === "string") {
                    channels.push(channel);
                }
            }

            //create dispatch
            var targets = {};
            if (channels.length > 0) targets["channels"] = channels;
            if (users.length > 0) targets["users"] = users;
            if (cmd === "notifyAll") {
                targets = {
                    broadcast: true
                };
            }
            //console.log(payload);
            //console.log(targets);
            logger.info("User " + user + " event " + event);
            me.dispatcher.dispatchEventDataTarget(event, payload, targets);
            me.success(req, res, 200, "OK");
            // @TODO
            // of course this won't work as we need a callback/Promise to send data back after the request is done
            return pushData;
        });
    } else {
        logger.info("[405] " + req.method + " to " + req.url);
        res.writeHead(405, "Method not supported", {'Content-Type': 'text/html'});
        res.end('<title>405 - Method not supported</title>
Method not supported.
');
        return false;
    }
};

RestPushConnector.prototype.success = function(req, res, code, message) {
    res.statusCode = code;
    res.end(message);
    return true;
};

RestPushConnector.prototype.fail = function(req, res, code, message) {
    res.statusCode = code;
    res.end(message);
    return false;
};

module.exports = RestPushConnector;
<|endoftext|>


<commit_before>import React from 'react';
import {Helmet} from 'react-helmet';
import {connect} from 'react-redux';
import {Link, Route, Switch} from 'react-router-dom';
import {css} from 'emotion';
import i18n from 'i18n';
import {MEDIA, SHADES} from 'styles/consts';
import {ToastContainer} from 'react-toastify';
import Loadable from 'react-loadable';
import {Col, Container, Input, Row} from 'reactstrap';
import {auth, database} from 'services/firebase';
import {setLanguageAction, setTranslations, setUserIdAction} from 'actions/root';
import {setCustomLocations, setSelectedLocations} from 'actions/config';
import {TRANSLATIONS} from 'consts';
import Discord from 'images/discord.png';

import SpinnerModal from 'components/SpinnerModal/SpinnerModal';
import SpyIcon from 'components/SpyIcon/SpyIcon';

const LoadableSettings = Loadable({loader: () => import('../Settings/Settings'), loading: SpinnerModal});
const LoadableGame = Loadable({loader: () => import('../Game/Game'), loading: SpinnerModal});
const LoadableJoinRoom = Loadable({loader: () => import('../JoinRoom/JoinRoom'), loading: SpinnerModal});

export class App extends React.Component{
  componentDidMount() {
    const { setUserId } = this.props;
    auth.signInAnonymously().then((authUser) => {
      setUserId(authUser.user.uid);
      this.importTranslations();
    });
  }

  importTranslations = async () => {
    // imported less than 24 hours ago
    if(this.props.translationsImportTime && Date.now() - this.props.translationsImportTime < 24 * 60 * 60 * 1000) return null;

    const translationsSnapshot = await database.ref('translations').once('value');
    this.props.setTranslations(translationsSnapshot.val() || {});
  };

  setLanguage = (language) => {
    const { setLanguage } = this.props;
    i18n.changeLanguage(language);
    setLanguage(language);
  };

  render() {
    const { language, translations = {} } = this.props;

    return (
      <Container className={styles.container}>
        <Helmet
          defaultTitle="Spyfall"
        >
          <meta name="description" content="Ensemble React Web Template" />
        </Helmet>
        <Row className="justify-content-center">
          <Col xs={12} md={8} lg={6}>
            <Row className="align-items-center justify-content-center">
              <Col xs="12" sm="4" className="text-center">
                <Link to="/">
                  <SpyIcon />
                  Spyfall
                </Link>
              </Col>
              <Col xs="12" sm="8" className={`${styles.languageSelector} text-center`}>
                <Input type="select" name="languages" id="languages" value={language} onChange={(evt) => this.setLanguage(evt.target.value)}>
                  {TRANSLATIONS.map((translation) =>
                    <option key={translation.id} value={translation.id}>{translation.name} - {translations[translation.id] || 0}%</option>
                  )}
                </Input>
              </Col>
            </Row>
            <Switch>
              <Route exact path="/settings" component={LoadableSettings} />
              <Route exact path="/join" component={LoadableJoinRoom} />
              <Route exact path="/" component={LoadableGame} />
            </Switch>
            <Row className={styles.localizationContainer}>
              <Col className="text-center">

                Help us with translations!
              </Col>
            </Row>
            <Row className={styles.localizationContainer}>
              <Col className="text-center">

                  Join Spyfall Discord server

              </Col>
            </Row>
            <Row className={styles.footer}>
              <Col className="text-center">
                <Row>
                  <Col>
                    Spyfall is designed by Alexandr Ushan and published by Hobby World
                  </Col>
                </Row>
                <Row>
                  <Col>
                    Spy icon created by Dan Hetteix (TheNounProject)
                  </Col>
                </Row>
                <Row>
                  <Col>
                    https://github.com/adrianocola/spyfall
                  </Col>
                </Row>
              </Col>
            </Row>
          </Col>
        </Row>
        <ToastContainer />
      </Container>
    );
  }
}

const styles = {
  container: css({
    paddingTop: 50,
  }),
  languageSelector: css({
    [MEDIA.xsOnly]: {
      marginTop: 10,
    },
  }),
  localizationContainer: css({
    marginTop: 40,
    fontSize: '0.8rem',
  }),
  localizationLink: css({
    marginLeft: 10,
  }),
  discordImage: css({
    height: 32,
  }),
  discordLink: css({
    marginLeft: 10,
  }),
  footer: css({
    marginTop: 20,
    marginBottom: 30,
    fontSize: '0.8rem',
    color: SHADES.light,
  }),
};

const mapStateToProps = (state) => ({
  language: state.root.language,
  translations: state.root.translations,
  translationsImportTime: state.root.translationsImportTime,
});

const mapDispatchToProps = (dispatch) => ({
  setUserId: (userId) => dispatch(setUserIdAction(userId)),
  setLanguage: (language) => dispatch(setLanguageAction(language)),
  setSelectedLocations: (selectedLocations) => dispatch(setSelectedLocations(selectedLocations)),
  setCustomLocations: (customLocations) => dispatch(setCustomLocations(customLocations)),
  setTranslations: (translations) => dispatch(setTranslations(translations)),
});

export default connect(mapStateToProps, mapDispatchToProps)(App);
<commit_msg>Make language select show current language on startup<commit_after>import React from 'react';
import {Helmet} from 'react-helmet';
import {connect} from 'react-redux';
import {Link, Route, Switch} from 'react-router-dom';
import {css} from 'emotion';
import i18n from 'i18n';
import {MEDIA, SHADES} from 'styles/consts';
import {ToastContainer} from 'react-toastify';
import Loadable from 'react-loadable';
import {Col, Container, Input, Row} from 'reactstrap';
import {auth, database} from 'services/firebase';
import {setLanguageAction, setTranslations, setUserIdAction} from 'actions/root';
import {setCustomLocations, setSelectedLocations} from 'actions/config';
import {TRANSLATIONS} from 'consts';
import Discord from 'images/discord.png';

import SpinnerModal from 'components/SpinnerModal/SpinnerModal';
import SpyIcon from 'components/SpyIcon/SpyIcon';

const LoadableSettings = Loadable({loader: () => import('../Settings/Settings'), loading: SpinnerModal});
const LoadableGame = Loadable({loader: () => import('../Game/Game'), loading: SpinnerModal});
const LoadableJoinRoom = Loadable({loader: () => import('../JoinRoom/JoinRoom'), loading: SpinnerModal});

export class App extends React.Component{
  componentDidMount() {
    const { setUserId } = this.props;
    auth.signInAnonymously().then((authUser) => {
      setUserId(authUser.user.uid);
      this.importTranslations();
    });
  }

  importTranslations = async () => {
    // imported less than 24 hours ago
    if(this.props.translationsImportTime && Date.now() - this.props.translationsImportTime < 24 * 60 * 60 * 1000) return null;

    const translationsSnapshot = await database.ref('translations').once('value');
    this.props.setTranslations(translationsSnapshot.val() || {});
  };

  setLanguage = (language) => {
    const { setLanguage } = this.props;
    i18n.changeLanguage(language);
    setLanguage(language);
  };

  render() {
    const { language, translations = {} } = this.props;

    return (
      <Container className={styles.container}>
        <Helmet
          defaultTitle="Spyfall"
        >
          <meta name="description" content="Ensemble React Web Template" />
        </Helmet>
        <Row className="justify-content-center">
          <Col xs={12} md={8} lg={6}>
            <Row className="align-items-center justify-content-center">
              <Col xs="12" sm="4" className="text-center">
                <Link to="/">
                  <SpyIcon />
                  Spyfall
                </Link>
              </Col>
              <Col xs="12" sm="8" className={`${styles.languageSelector} text-center`}>
                <Input type="select" name="languages" id="languages" value={i18n.language} onChange={(evt) => this.setLanguage(evt.target.value)}>
                  {TRANSLATIONS.map((translation) =>
                    <option key={translation.id} value={translation.id}>{translation.name} - {translations[translation.id] || 0}%</option>
                  )}
                </Input>
              </Col>
            </Row>
            <Switch>
              <Route exact path="/settings" component={LoadableSettings} />
              <Route exact path="/join" component={LoadableJoinRoom} />
              <Route exact path="/" component={LoadableGame} />
            </Switch>
            <Row className={styles.localizationContainer}>
              <Col className="text-center">

                Help us with translations!
              </Col>
            </Row>
            <Row className={styles.localizationContainer}>
              <Col className="text-center">

                  Join Spyfall Discord server

              </Col>
            </Row>
            <Row className={styles.footer}>
              <Col className="text-center">
                <Row>
                  <Col>
                    Spyfall is designed by Alexandr Ushan and published by Hobby World
                  </Col>
                </Row>
                <Row>
                  <Col>
                    Spy icon created by Dan Hetteix (TheNounProject)
                  </Col>
                </Row>
                <Row>
                  <Col>
                    https://github.com/adrianocola/spyfall
                  </Col>
                </Row>
              </Col>
            </Row>
          </Col>
        </Row>
        <ToastContainer />
      </Container>
    );
  }
}

const styles = {
  container: css({
    paddingTop: 50,
  }),
  languageSelector: css({
    [MEDIA.xsOnly]: {
      marginTop: 10,
    },
  }),
  localizationContainer: css({
    marginTop: 40,
    fontSize: '0.8rem',
  }),
  localizationLink: css({
    marginLeft: 10,
  }),
  discordImage: css({
    height: 32,
  }),
  discordLink: css({
    marginLeft: 10,
  }),
  footer: css({
    marginTop: 20,
    marginBottom: 30,
    fontSize: '0.8rem',
    color: SHADES.light,
  }),
};

const mapStateToProps = (state) => ({
  language: state.root.language,
  translations: state.root.translations,
  translationsImportTime: state.root.translationsImportTime,
});

const mapDispatchToProps = (dispatch) => ({
  setUserId: (userId) => dispatch(setUserIdAction(userId)),
  setLanguage: (language) => dispatch(setLanguageAction(language)),
  setSelectedLocations: (selectedLocations) => dispatch(setSelectedLocations(selectedLocations)),
  setCustomLocations: (customLocations) => dispatch(setCustomLocations(customLocations)),
  setTranslations: (translations) => dispatch(setTranslations(translations)),
});

export default connect(mapStateToProps, mapDispatchToProps)(App);
<|endoftext|>


<commit_before>function cloudifyWidgetInitialization(){
    function cloudifyWidgetOnLoadHandler(){
        var element = document.getElementById("cloudify-widget");
        var api_key = element.getAttribute("data-api-key");
        var host = element.getAttribute("data-host") || "launch.cloudifysource.org";  // backward compatibility

        var iframe = document.createElement("iframe");
        element.parentNode.insertBefore(iframe, element.nextSibling);

        // todo : make protocol insensitive once we support HTTPS.
        // http://localhost:9000/public/angularApps/index.html#/widgets/4a7c12a1-3e1b-412d-b674-8329480f93fd/view?since=1406540993919
        iframe.setAttribute("src", "http://" + host + "/public/angularApps/index.html#/widgets/" + api_key + '/view?since=' + new Date().getTime());
        iframe.setAttribute("width", "600px");
        iframe.setAttribute("height", "463px");
        iframe.setAttribute("scrolling", "no");
        iframe.setAttribute("frameborder", "no");
    }
    window.addEventListener("load", cloudifyWidgetOnLoadHandler, false);
}
cloudifyWidgetInitialization();<commit_msg>adding get_widget for backward compatibility<commit_after>function cloudifyWidgetInitialization(){
    function cloudifyWidgetOnLoadHandler(){
        var element = document.getElementById("cloudify-widget");
        var api_key = element.getAttribute("data-api-key");
        var host = element.getAttribute("data-host") || "launch.cloudifysource.org";  // backward compatibility

        var iframe = document.createElement("iframe");
        element.parentNode.insertBefore(iframe, element.nextSibling);

        // todo : make protocol insensitive once we support HTTPS.
        // http://localhost:9000/public/angularApps/index.html#/widgets/4a7c12a1-3e1b-412d-b674-8329480f93fd/view?since=1406540993919
        iframe.setAttribute("src", "http://" + host + "/public-folder/angularApps/index.html#/widgets/" + api_key + '/view?since=' + new Date().getTime());
        iframe.setAttribute("width", "600px");
        iframe.setAttribute("height", "463px");
        iframe.setAttribute("scrolling", "no");
        iframe.setAttribute("frameborder", "no");
    }
    window.addEventListener("load", cloudifyWidgetOnLoadHandler, false);
}
cloudifyWidgetInitialization();<|endoftext|>


<commit_before>var helper = require("../../../helper");
var Manager = require("../../../../src/etl/sales/fact-weaving-sales-contract-etl-manager");
var instanceManager = null;
var should = require("should");
var sqlHelper = require("../../../sql-helper");

before("#00. connect db", function (done) {
    Promise.all([helper, sqlHelper])
        .then((result) => {
            var db = result[0];
            var sql = result[1];
            db.getDb().then((db) => {
                instanceManager = new Manager(db, {
                    username: "unit-test"
                }, sql);
                done();
            })
                .catch((e) => {
                    done(e);
                })
        });
});

it("#01. should success when create etl fact-weaving-sales-contract", function (done) {
    instanceManager.run()
        .then((a) => {
            console.log(a);
            done();
        })
        .catch((e) => {
            console.log(e);
            done(e);
        });
});

it("#02. should success when transforming data", function (done) {
    var data = [
        {
            uom: {
                unit: "yds"
            },
            orderQuantity: 1,
            material: {
                name: ""
            },
            materialConstruction: {
                name: ""
            },
            yarnMaterial: {
                name: ""
            },
            materialWidth: 0
        },
        {
            uom: {
                unit: "mtr"
            },
            orderQuantity: 1
        }
    ];
    instanceManager.transform(data)
        .then(() => {
            done();
        })
        .catch((e) => {
            done(e);
        });
});

// it("#03. should error when load empty data", function (done) {
//     instanceManager.load({})
//         .then(id => {
//             done("should error when create with empty data");
//         })
//         .catch(e => {
//             try {
//                 done();
//             }
//             catch (ex) {
//                 done(ex);
//             }
//         });
// });

it("#04. should error when insert empty data", function (done) {
    instanceManager.insertQuery(this.sql, "")
        .then((id) => {
            done("should error when create with empty data");
        })
        .catch((e) => {
            try {
                done();
            }
            catch (ex) {
                done(ex);
            }
        });
});<commit_msg>update weaving sc<commit_after>var helper = require("../../../helper");
var Manager = require("../../../../src/etl/sales/fact-weaving-sales-contract-etl-manager");
var instanceManager = null;
var should = require("should");
var sqlHelper = require("../../../sql-helper");

before("#00. connect db", function (done) {
    Promise.all([helper, sqlHelper])
        .then((result) => {
            var db = result[0];
            var sql = result[1];
            db.getDb().then((db) => {
                instanceManager = new Manager(db, {
                    username: "unit-test"
                }, sql);
                done();
            })
                .catch((e) => {
                    done(e);
                })
        });
});

it("#01. should success when create etl fact-weaving-sales-contract", function (done) {
    instanceManager.run()
        .then((a) => {
            console.log(a);
            done();
        })
        .catch((e) => {
            console.log(e);
            done(e);
        });
});

it("#02. should success when transforming data", function (done) {
    var data = [
        {
            uom: {
                unit: "yds"
            },
            orderQuantity: 1,
            material: {
                name: ""
            },
            materialConstruction: {
                name: ""
            },
            yarnMaterial: {
                name: ""
            },
            materialWidth: 0
        },
        {
            uom: {
                unit: "mtr"
            },
            orderQuantity: 1
        }
    ];
    instanceManager.transform(data)
        .then(() => {
            done();
        })
        .catch((e) => {
            done(e);
        });
});

it("#03. should success when convert quantity data", function (done) {
    instanceManager.orderQuantiyConvertion("test", 2)
        .then(() => {
            done();
        })
        .catch((e) => {
            done(e);
        });
});

it("#04. should success when join string data", function (done) {
    instanceManager.joinConstructionString("test", "tests", "test", "test")
        .then(() => {
            done();
        })
        .catch((e) => {
            done(e);
        });
});

// it("#03. should error when load empty data", function (done) {
//     instanceManager.load({})
//         .then(id => {
//             done("should error when create with empty data");
//         })
//         .catch(e => {
//             try {
//                 done();
//             }
//             catch (ex) {
//                 done(ex);
//             }
//         });
// });

it("#05. should error when insert empty data", function (done) {
    instanceManager.insertQuery(this.sql, "")
        .then((id) => {
            done("should error when create with empty data");
        })
        .catch((e) => {
            try {
                done();
            }
            catch (ex) {
                done(ex);
            }
        });
});<|endoftext|>


<commit_before>const fs = require('fs');
const childProcess = require('child_process');

const ENVIRONMENT_VARIABLES_TO_PRESERVE = new Set([
  'NODE_ENV',
  'NODE_PATH',
  'ATOM_HOME',
  'ATOM_DISABLE_SHELLING_OUT_FOR_ENVIRONMENT'
]);

const PLATFORMS_KNOWN_TO_WORK = new Set(['darwin', 'linux']);

// Shell command that returns env var=value lines separated by \0s so that
// newlines are handled properly. Note: need to use %c to inject the \0s
// to work with some non GNU awks.
const ENV_COMMAND =
  'command awk \'BEGIN{for(v in ENVIRON) printf("%s=%s%c", v, ENVIRON[v], 0)}\'';

async function updateProcessEnv(launchEnv) {
  let envToAssign;
  if (launchEnv) {
    if (shouldGetEnvFromShell(launchEnv)) {
      envToAssign = await getEnvFromShell(launchEnv);
    } else if (launchEnv.PWD || launchEnv.PROMPT || launchEnv.PSModulePath) {
      envToAssign = launchEnv;
    }
  }

  if (envToAssign) {
    for (let key in process.env) {
      if (!ENVIRONMENT_VARIABLES_TO_PRESERVE.has(key)) {
        delete process.env[key];
      }
    }

    for (let key in envToAssign) {
      if (
        !ENVIRONMENT_VARIABLES_TO_PRESERVE.has(key) ||
        (!process.env[key] && envToAssign[key])
      ) {
        process.env[key] = envToAssign[key];
      }
    }

    if (envToAssign.ATOM_HOME && fs.existsSync(envToAssign.ATOM_HOME)) {
      process.env.ATOM_HOME = envToAssign.ATOM_HOME;
    }
  }
}

function shouldGetEnvFromShell(env) {
  if (!PLATFORMS_KNOWN_TO_WORK.has(process.platform)) {
    return false;
  }

  if (!env || !env.SHELL || env.SHELL.trim() === '') {
    return false;
  }

  const disableSellingOut =
    env.ATOM_DISABLE_SHELLING_OUT_FOR_ENVIRONMENT ||
    process.env.ATOM_DISABLE_SHELLING_OUT_FOR_ENVIRONMENT;

  if (disableSellingOut === 'true') {
    return false;
  }

  return true;
}

async function getEnvFromShell(env) {
  let { stdout, error } = await new Promise(resolve => {
    let child;
    let error;
    let stdout = '';
    let done = false;
    const cleanup = () => {
      if (!done && child) {
        child.kill();
        done = true;
      }
    };
    process.once('exit', cleanup);
    setTimeout(() => {
      cleanup();
    }, 5000);
    child = childProcess.spawn(env.SHELL, ['-ilc', ENV_COMMAND], {
      encoding: 'utf8',
      detached: true,
      stdio: ['ignore', 'pipe', process.stderr]
    });
    const buffers = [];
    child.on('error', e => {
      done = true;
      error = e;
    });
    child.stdout.on('data', data => {
      buffers.push(data);
    });
    child.on('close', (code, signal) => {
      done = true;
      process.removeListener('exit', cleanup);
      if (buffers.length) {
        stdout = Buffer.concat(buffers).toString('utf8');
      }

      resolve({ stdout, error });
    });
  });

  if (error) {
    if (error.handle) {
      error.handle();
    }
    console.log(
      'warning: ' +
        env.SHELL +
        ' -ilc "' +
        ENV_COMMAND +
        '" failed with signal (' +
        error.signal +
        ')'
    );
    console.log(error);
  }

  if (!stdout || stdout.trim() === '') {
    return null;
  }

  let result = {}
  for (let line of stdout.split('\0')) {
    if (line.includes('=')) {
      let components = line.split('=')
      let key = components.shift()
      let value = components.join('=')
      result[key] = value
    }
  }
  return result;
}

module.exports = { updateProcessEnv, shouldGetEnvFromShell };
<commit_msg>Fix lint errors.<commit_after>const fs = require('fs');
const childProcess = require('child_process');

const ENVIRONMENT_VARIABLES_TO_PRESERVE = new Set([
  'NODE_ENV',
  'NODE_PATH',
  'ATOM_HOME',
  'ATOM_DISABLE_SHELLING_OUT_FOR_ENVIRONMENT'
]);

const PLATFORMS_KNOWN_TO_WORK = new Set(['darwin', 'linux']);

// Shell command that returns env var=value lines separated by \0s so that
// newlines are handled properly. Note: need to use %c to inject the \0s
// to work with some non GNU awks.
const ENV_COMMAND =
  'command awk \'BEGIN{for(v in ENVIRON) printf("%s=%s%c", v, ENVIRON[v], 0)}\'';

async function updateProcessEnv(launchEnv) {
  let envToAssign;
  if (launchEnv) {
    if (shouldGetEnvFromShell(launchEnv)) {
      envToAssign = await getEnvFromShell(launchEnv);
    } else if (launchEnv.PWD || launchEnv.PROMPT || launchEnv.PSModulePath) {
      envToAssign = launchEnv;
    }
  }

  if (envToAssign) {
    for (let key in process.env) {
      if (!ENVIRONMENT_VARIABLES_TO_PRESERVE.has(key)) {
        delete process.env[key];
      }
    }

    for (let key in envToAssign) {
      if (
        !ENVIRONMENT_VARIABLES_TO_PRESERVE.has(key) ||
        (!process.env[key] && envToAssign[key])
      ) {
        process.env[key] = envToAssign[key];
      }
    }

    if (envToAssign.ATOM_HOME && fs.existsSync(envToAssign.ATOM_HOME)) {
      process.env.ATOM_HOME = envToAssign.ATOM_HOME;
    }
  }
}

function shouldGetEnvFromShell(env) {
  if (!PLATFORMS_KNOWN_TO_WORK.has(process.platform)) {
    return false;
  }

  if (!env || !env.SHELL || env.SHELL.trim() === '') {
    return false;
  }

  const disableSellingOut =
    env.ATOM_DISABLE_SHELLING_OUT_FOR_ENVIRONMENT ||
    process.env.ATOM_DISABLE_SHELLING_OUT_FOR_ENVIRONMENT;

  if (disableSellingOut === 'true') {
    return false;
  }

  return true;
}

async function getEnvFromShell(env) {
  let { stdout, error } = await new Promise(resolve => {
    let child;
    let error;
    let stdout = '';
    let done = false;
    const cleanup = () => {
      if (!done && child) {
        child.kill();
        done = true;
      }
    };
    process.once('exit', cleanup);
    setTimeout(() => {
      cleanup();
    }, 5000);
    child = childProcess.spawn(env.SHELL, ['-ilc', ENV_COMMAND], {
      encoding: 'utf8',
      detached: true,
      stdio: ['ignore', 'pipe', process.stderr]
    });
    const buffers = [];
    child.on('error', e => {
      done = true;
      error = e;
    });
    child.stdout.on('data', data => {
      buffers.push(data);
    });
    child.on('close', (code, signal) => {
      done = true;
      process.removeListener('exit', cleanup);
      if (buffers.length) {
        stdout = Buffer.concat(buffers).toString('utf8');
      }

      resolve({ stdout, error });
    });
  });

  if (error) {
    if (error.handle) {
      error.handle();
    }
    console.log(
      'warning: ' +
        env.SHELL +
        ' -ilc "' +
        ENV_COMMAND +
        '" failed with signal (' +
        error.signal +
        ')'
    );
    console.log(error);
  }

  if (!stdout || stdout.trim() === '') {
    return null;
  }

  let result = {};
  for (let line of stdout.split('\0')) {
    if (line.includes('=')) {
      let components = line.split('=');
      let key = components.shift();
      let value = components.join('=');
      result[key] = value;
    }
  }
  return result;
}

module.exports = { updateProcessEnv, shouldGetEnvFromShell };
<|endoftext|>


<commit_before>/*
// http://developer.appcelerator.com/question/93681/how-do-i-set-a-back-button-background-image-and-onclick-background-image#answer-168801
var btnBack = new Ti.UI.createButton({
    backgroundImage:'back.png',
    backgroundSelectedImage:'back.png',
    width:80,height:25
});
var win = new Ti.UI.createWindow({
    url:'index.js',
    leftNavButton:btnBack
});
btnBack.addEventListener('click', function(){
    win.close();
});
*/

$.submit.addEventListener("touchstart",  function(){$.submit.backgroundColor = "#9CC075";});
//$.submit.addEventListener("touchend",    function(){$.submit.backgroundColor = "#7C9A5B";});
$.submit.addEventListener("touchcancel", function(){$.submit.backgroundColor = "#7C9A5B";});

$.submit.addEventListener("touchend", function(e){
	Ti.API.info("Pressed button: Invite.");
	$.submit.backgroundColor = "#7C9A5B";
	Ti.App.fireEvent('app:createGame', {friends: $.friends.value.split(',')});
});

// (?): https://developer.appcelerator.com/question/27291/button-inside-a-view---inside-a-tableviewrow
// (?): http://developer.appcelerator.com/question/124202/how-to-add-a-text-and-a-checkbox-on-a-tableviewrow
// My Data-array for Table-view
var checkboxArray = [
  { hasCheck: false, title: "Derek Schultz", leftImage: "https://fbcdn-profile-a.akamaihd.net/hprofile-ak-ash2/t1/c40.0.160.160/p160x160/1394375_10202509459080754_1157139205_n.jpg" },
  { hasCheck: false, title: "Dan Bulger",    leftImage: "https://fbcdn-profile-a.akamaihd.net/hprofile-ak-ash2/t1/c40.0.160.160/p160x160/1394375_10202509459080754_1157139205_n.jpg" },
];

// Make a UI searchbar that filters the contents of a UI tableview.
var searchBar = Ti.UI.createSearchBar({
    showCancel: false,				// button on far right
    hintText: 'Invite friends...',  // placeholder text
    //prompt: "to: ",				// centered text above field
    top: 60,						// absolute position
    //bottom: 50,
    minHeight: 35,
    barColor: 'white',
    color: '#444',
    //backgroundColor: "#fff",
    //tintColor: "black",
    //borderColor: "#444",
    //borderRadius: 0,
    //borderWidth: 1
});
var tableView = Ti.UI.createTableView({
    width: "100%",
    height: "100%",
    data: checkboxArray,
    search: searchBar,
    filterAttribute: 'title',     // http://docs.appcelerator.com/titanium/latest/#!/api/Titanium.UI.TableView-property-filterAttribute
    filterCaseInsensitive: true,  // Determines whether the search is case insensitive.
    color: "#444",
    font: {
		fontFamily: "Omnes-Regular",
		fontSize: 20
	},
    //searchHidden: true,		  // Set to true to hide the search field.
    //separatorStyle: Ti.UI.iPhone.TableViewSeparatorStyle.NONE,
    //separatorColor: "#fff"
});
$.main.add(tableView);

// (?): http://stackoverflow.com/questions/16062363/titanium-alloy-accessing-ui-from-different-controllers
/*
for(var i = 0; i < 25; i++) {
	var row = Ti.UI.createTableViewRow({
	  // Do not specify 'title' if using Views as children of the Row.
  	  title: i
	});
	tableView.appendRow(row);
}*/

// Track checked items
// Hack: record hasCheck of all rows.
/*
// var rows = this.data[0].rows;
// for (var i = 0; i < rows.length; ++i)
    // rows[i].hasCheck = false;*/

var lastRowClicked;
tableView.addEventListener('click', function(e){
	var row = e.row;
     row.hasCheck = !row.hasCheck;
});

// Handle touch events on the "Start Game" button.
function submitGame(){
	Ti.API.info("Pressed button: Invite.");
	$.submit.backgroundColor = "#7C9A5B";
	Ti.App.fireEvent('app:createGame', {friends: searchBar.value.split(',')});
};
$.submit.addEventListener("touchstart",  function(e){$.submit.backgroundColor = "#9CC075";});
$.submit.addEventListener("touchcancel", function(e){$.submit.backgroundColor = "#7C9A5B";});
$.submit.addEventListener("touchend",    function(e){submitGame();});
searchBar.addEventListener("return",     function(e){submitGame();});

// Now that it's set up, focus on the search bar.
searchBar.focus();
<commit_msg>Broken progress interrupted by pull<commit_after>/*
// http://developer.appcelerator.com/question/93681/how-do-i-set-a-back-button-background-image-and-onclick-background-image#answer-168801
var btnBack = new Ti.UI.createButton({
    backgroundImage:'back.png',
    backgroundSelectedImage:'back.png',
    width:80,height:25
});
var win = new Ti.UI.createWindow({
    url:'index.js',
    leftNavButton:btnBack
});
btnBack.addEventListener('click', function(){
    win.close();
});
*/

$.submit.addEventListener("touchstart",  function(){$.submit.backgroundColor = "#9CC075";});
//$.submit.addEventListener("touchend",    function(){$.submit.backgroundColor = "#7C9A5B";});
$.submit.addEventListener("touchcancel", function(){$.submit.backgroundColor = "#7C9A5B";});

$.submit.addEventListener("touchend", function(e){
	Ti.API.info("Pressed button: Invite.");
	$.submit.backgroundColor = "#7C9A5B";
	Ti.App.fireEvent('app:createGame', {friends: $.friends.value.split(',')});
});

// (?): https://developer.appcelerator.com/question/27291/button-inside-a-view---inside-a-tableviewrow
// (?): http://developer.appcelerator.com/question/124202/how-to-add-a-text-and-a-checkbox-on-a-tableviewrow
// My Data-array for Table-view
var checkboxArray = [];

Ti.App.fireEvent('app:requestFriendList');

Ti.App.addEventListener('app:friendListAcquired', function (message) {
	for (var key in friends) {
		checkboxArray.push({ hasCheck: false, title: friends[key].name, leftImage: friends[key].picture });
	}
});

// Make a UI searchbar that filters the contents of a UI tableview.
var searchBar = Ti.UI.createSearchBar({
    showCancel: false,				// button on far right
    hintText: 'Invite friends...',  // placeholder text
    //prompt: "to: ",				// centered text above field
    top: 60,						// absolute position
    //bottom: 50,
    minHeight: 35,
    barColor: 'white',
    color: '#444',
    //backgroundColor: "#fff",
    //tintColor: "black",
    //borderColor: "#444",
    //borderRadius: 0,
    //borderWidth: 1
});
var tableView = Ti.UI.createTableView({
    width: "100%",
    height: "100%",
    data: checkboxArray,
    search: searchBar,
    filterAttribute: 'title',     // http://docs.appcelerator.com/titanium/latest/#!/api/Titanium.UI.TableView-property-filterAttribute
    filterCaseInsensitive: true,  // Determines whether the search is case insensitive.
    color: "#444",
    font: {
		fontFamily: "Omnes-Regular",
		fontSize: 20
	},
    //searchHidden: true,		  // Set to true to hide the search field.
    //separatorStyle: Ti.UI.iPhone.TableViewSeparatorStyle.NONE,
    //separatorColor: "#fff"
});
$.main.add(tableView);

// (?): http://stackoverflow.com/questions/16062363/titanium-alloy-accessing-ui-from-different-controllers
/*
for(var i = 0; i < 25; i++) {
	var row = Ti.UI.createTableViewRow({
	  // Do not specify 'title' if using Views as children of the Row.
  	  title: i
	});
	tableView.appendRow(row);
}*/

// Track checked items
// Hack: record hasCheck of all rows.
/*
// var rows = this.data[0].rows;
// for (var i = 0; i < rows.length; ++i)
    // rows[i].hasCheck = false;*/

var lastRowClicked;
tableView.addEventListener('click', function(e){
	var row = e.row;
     row.hasCheck = !row.hasCheck;
});

// Handle touch events on the "Start Game" button.
function submitGame(){
	Ti.API.info("Pressed button: Invite.");
	$.submit.backgroundColor = "#7C9A5B";
	Ti.App.fireEvent('app:createGame', {friends: searchBar.value.split(',')});
};
$.submit.addEventListener("touchstart",  function(e){$.submit.backgroundColor = "#9CC075";});
$.submit.addEventListener("touchcancel", function(e){$.submit.backgroundColor = "#7C9A5B";});
$.submit.addEventListener("touchend",    function(e){submitGame();});
searchBar.addEventListener("return",     function(e){submitGame();});

// Now that it's set up, focus on the search bar.
searchBar.focus();
<|endoftext|>


<commit_before>module.exports = function(models, io, logger) {

};
<commit_msg>went to a clean slate for event.js until we have a better definition of what it is to be<commit_after>/**
	*  new node file
**/<|endoftext|>


<commit_before>(function(){
	app.controller('MainController', function($scope, $http, API_CONFIG) {
		// Start on the login page
		$scope.selected = 'login';
		$scope.config = API_CONFIG;

        $scope.dc = {};
        $scope.filters = {};

        $scope.getFilters = function(){
            return $scope.filters;
        }

        $scope.setDataCenter = function(dataCenter){
            $scope.dc = dataCenter;
            $scope.prefixes = buildList(dataCenter.prefixes);
            $scope.filters = {
                dataCenter : dataCenter.value,
                filterBy : $scope.config.filters[0],
                prefix: $scope.prefixes[0],
                filter : ''
            };
        }

        $scope.resetFilters = function(){
            if($scope.dc)
                $scope.setDataCenter( $scope.dc );
            else
                $scope.setDataCenter( $scope.config.dataCenters[0] );
            API_HELPER.loadCodes($scope.populateCodes, $scope.getFilters());
        }

        $scope.resetFilters();

		$scope.populateCodes = function( codes ){
            trimKeys(codes);
        	$scope.launchCodes = codes;
            if( !$scope.isSelected('list') )
                $scope.selectTab('list');
        	$scope.$apply();
        }

        $scope.populateAudits = function( audits ){
            console.log(audits);
            $scope.auditList = audits;
            $scope.$apply();
        }

        $scope.isSelected = function(val) {
            return $scope.selected === val;
        }

        $scope.selectTab = function(val) {
            var oldElem = $("#" + $scope.selected);
            var newElem = $("#" + val);
            oldElem.slideUp(400, function(){
                newElem.slideDown(400, function() {
                    $scope.selected = val;
                    if(val != "login"){
                        $("#wrapper").removeClass("toggled");
                    }
                    $scope.$apply();
                });
            });

        }

        $scope.login = function(user, pw) {
            API_HELPER.login(user, pw, function(token){
                API_HELPER.saveToken(token);
                API_HELPER.loadCodes($scope.populateCodes, $scope.getFilters());
            });
        }
        $scope.logout = function(){
            API_HELPER.deleteToken();
            location.reload(true);
        }

        API_HELPER.loadCodes($scope.populateCodes, $scope.getFilters());

        function buildList(object, branch){
            var array = [];
            for(key in object){
                if(!branch){
                    array.push(key)
                    if(!$.isEmptyObject(object[key]))
                        array = array.concat(buildList(object[key], key));
                }else{
                    array.push(branch + "/" + key);
                    if(!$.isEmptyObject(object[key]))
                        array = array.concat(buildList(object[key], branch + "/" + key));
                }

            }
            return array;
        }

        function trimKeys( codes ){
            console.log($scope.filters.prefix);
            for (var i = 0; i < codes.length; i++) {
                codes[i].key = codes[i].key.replace($scope.filters.prefix + "/", "");
            };
        }
	});

})();<commit_msg>more bug fixes<commit_after>(function(){
	app.controller('MainController', function($scope, $http, API_CONFIG) {
		// Start on the login page
		$scope.selected = 'login';
		$scope.config = API_CONFIG;

        $scope.dc = {};
        $scope.filters = {};

        $scope.getFilters = function(){
            return $scope.filters;
        }

        $scope.setDataCenter = function(dataCenter){
            $scope.dc = dataCenter;
            $scope.prefixes = buildList(dataCenter.prefixes);
            $scope.filters = {
                dataCenter : dataCenter.value,
                filterBy : $scope.config.filters[0],
                prefix: $scope.prefixes[0],
                filter : ''
            };
        }

        $scope.populateCodes = function( codes ){
            trimKeys(codes);
            $scope.launchCodes = codes;
            if( !$scope.isSelected('list') )
                $scope.selectTab('list');
            $scope.$apply();
        }

        $scope.resetFilters = function(){
            if($scope.dc)
                $scope.setDataCenter( $scope.dc );
            else
                $scope.setDataCenter( $scope.config.dataCenters[0] );
            API_HELPER.loadCodes($scope.populateCodes, $scope.getFilters());
        }

        $scope.resetFilters();

        $scope.populateAudits = function( audits ){
            console.log(audits);
            $scope.auditList = audits;
            $scope.$apply();
        }

        $scope.isSelected = function(val) {
            return $scope.selected === val;
        }

        $scope.selectTab = function(val) {
            var oldElem = $("#" + $scope.selected);
            var newElem = $("#" + val);
            oldElem.slideUp(400, function(){
                newElem.slideDown(400, function() {
                    $scope.selected = val;
                    if(val != "login"){
                        $("#wrapper").removeClass("toggled");
                    }
                    $scope.$apply();
                });
            });

        }

        $scope.login = function(user, pw) {
            API_HELPER.login(user, pw, function(token){
                API_HELPER.saveToken(token);
                API_HELPER.loadCodes($scope.populateCodes, $scope.getFilters());
            });
        }
        $scope.logout = function(){
            API_HELPER.deleteToken();
            location.reload(true);
        }

        API_HELPER.loadCodes($scope.populateCodes, $scope.getFilters());

        function buildList(object, branch){
            var array = [];
            for(key in object){
                if(!branch){
                    array.push(key)
                    if(!$.isEmptyObject(object[key]))
                        array = array.concat(buildList(object[key], key));
                }else{
                    array.push(branch + "/" + key);
                    if(!$.isEmptyObject(object[key]))
                        array = array.concat(buildList(object[key], branch + "/" + key));
                }

            }
            return array;
        }

        function trimKeys( codes ){
            console.log($scope.filters.prefix);
            for (var i = 0; i < codes.length; i++) {
                codes[i].key = codes[i].key.replace($scope.filters.prefix + "/", "");
            };
        }
	});

})();<|endoftext|>


<commit_before>/* eslint no-magic-numbers: "off" */
'use strict';

module.exports = {
  rules: {
    'array-bracket-spacing': ['error', 'never'],
    'block-spacing': ['error', 'always'],
    'brace-style': ['error', 'stroustrup', {allowSingleLine: false}],
    'camelcase': ['error', {properties: 'always'}],
    'comma-spacing': ['error', {before: false, after: true}],
    'comma-style': ['error', 'last'],
    'computed-property-spacing': ['error', 'never'],
    'consistent-this': ['error', 'self'],
    'eol-last': 'error',
    'func-names': 'off',
    'func-style': 'off',
    'id-blacklist': ['error', 'data', 'obj'],
    'id-length': ['error', {
      min: 2,
      max: 35,
      properties: 'always',
      exceptions: ['_', 'i']
    }],
    'id-match': 'off',
    'indent': ['error', 2, {SwitchCase: 1}],
    'jsx-quotes': ['error', 'prefer-double'],
    'key-spacing': ['error', {beforeColon: false, afterColon: true}],
    'keyword-spacing': 'error',
    'linebreak-style': ['error', 'unix'],
    'lines-around-comment': ['error', {
      beforeBlockComment: true,
      afterBlockComment: false,
      beforeLineComment: true,
      afterLineComment: false,
      allowBlockStart: true,
      allowBlockEnd: false,
      allowObjectStart: true,
      allowObjectEnd: false,
      allowArrayStart: true,
      allowArrayEnd: false
    }],
    'max-depth': ['error', 3],
    'max-len': ['error', {code: 80, tabWidth: 4, ignoreUrls: true}],
    'max-nested-callbacks': ['error', 3],
    'max-params': ['error', 4],
    'max-statements': ['error', 15],
    'new-cap': ['error', {newIsCap: true, capIsNew: true}],
    'new-parens': 'error',
    'newline-after-var': 'off',
    'newline-before-return': 'off',
    'newline-per-chained-call': 'error',
    'no-array-constructor': 'error',
    'no-bitwise': 'error',
    'no-continue': 'error',
    'no-inline-comments': 'off',
    'no-lonely-if': 'error',
    'no-mixed-spaces-and-tabs': 'error',
    'no-multiple-empty-lines': ['error', {max: 1, maxEOF: 1}],
    'no-negated-condition': 'error',
    'no-nested-ternary': 'error',
    'no-new-object': 'error',
    'no-plusplus': ['error', {allowForLoopAfterthoughts: true}],
    'no-restricted-syntax': ['error', 'WithStatement'],
    'no-spaced-func': 'error',
    'no-ternary': 'off',
    'no-trailing-spaces': 'error',
    'no-underscore-dangle': 'error',
    'no-unneeded-ternary': 'error',
    'no-whitespace-before-property': 'error',
    'object-curly-spacing': ['error', 'never'],
    'one-var': ['error', 'never'],
    'one-var-declaration-per-line': 'off',
    'operator-assignment': ['error', 'always'],
    'operator-linebreak': ['error', 'after'],
    'padded-blocks': ['error', 'never'],
    'quote-props': ['error', 'consistent-as-needed', {keywords: true}],
    'quotes': ['error', 'single', 'avoid-escape'],
    'require-jsdoc': 'off',
    'semi': ['error', 'always'],
    'semi-spacing': ['error', {before: false, after: true}],
    'sort-imports': ['error', {ignoreCase: false}],
    'sort-vars': ['error', {ignoreCase: false}],
    'space-before-blocks': 'error',
    'space-before-function-paren': ['error', 'never'],
    'space-in-parens': ['error', 'never'],
    'space-infix-ops': ['error', {int32Hint: false}],
    'space-unary-ops': ['error', {words: true, nonwords: false}],
    'spaced-comment': ['error', 'always', {exceptions: ['+', '-', '=']}],
    'wrap-regex': 'error'
  }
};
<commit_msg>Allow "P" as single character variable name<commit_after>/* eslint no-magic-numbers: "off" */
'use strict';

module.exports = {
  rules: {
    'array-bracket-spacing': ['error', 'never'],
    'block-spacing': ['error', 'always'],
    'brace-style': ['error', 'stroustrup', {allowSingleLine: false}],
    'camelcase': ['error', {properties: 'always'}],
    'comma-spacing': ['error', {before: false, after: true}],
    'comma-style': ['error', 'last'],
    'computed-property-spacing': ['error', 'never'],
    'consistent-this': ['error', 'self'],
    'eol-last': 'error',
    'func-names': 'off',
    'func-style': 'off',
    'id-blacklist': ['error', 'data', 'obj'],
    'id-length': ['error', {
      min: 2,
      max: 35,
      properties: 'always',
      exceptions: ['_', 'i', 'P']
    }],
    'id-match': 'off',
    'indent': ['error', 2, {SwitchCase: 1}],
    'jsx-quotes': ['error', 'prefer-double'],
    'key-spacing': ['error', {beforeColon: false, afterColon: true}],
    'keyword-spacing': 'error',
    'linebreak-style': ['error', 'unix'],
    'lines-around-comment': ['error', {
      beforeBlockComment: true,
      afterBlockComment: false,
      beforeLineComment: true,
      afterLineComment: false,
      allowBlockStart: true,
      allowBlockEnd: false,
      allowObjectStart: true,
      allowObjectEnd: false,
      allowArrayStart: true,
      allowArrayEnd: false
    }],
    'max-depth': ['error', 3],
    'max-len': ['error', {code: 80, tabWidth: 4, ignoreUrls: true}],
    'max-nested-callbacks': ['error', 3],
    'max-params': ['error', 4],
    'max-statements': ['error', 15],
    'new-cap': ['error', {newIsCap: true, capIsNew: true}],
    'new-parens': 'error',
    'newline-after-var': 'off',
    'newline-before-return': 'off',
    'newline-per-chained-call': 'error',
    'no-array-constructor': 'error',
    'no-bitwise': 'error',
    'no-continue': 'error',
    'no-inline-comments': 'off',
    'no-lonely-if': 'error',
    'no-mixed-spaces-and-tabs': 'error',
    'no-multiple-empty-lines': ['error', {max: 1, maxEOF: 1}],
    'no-negated-condition': 'error',
    'no-nested-ternary': 'error',
    'no-new-object': 'error',
    'no-plusplus': ['error', {allowForLoopAfterthoughts: true}],
    'no-restricted-syntax': ['error', 'WithStatement'],
    'no-spaced-func': 'error',
    'no-ternary': 'off',
    'no-trailing-spaces': 'error',
    'no-underscore-dangle': 'error',
    'no-unneeded-ternary': 'error',
    'no-whitespace-before-property': 'error',
    'object-curly-spacing': ['error', 'never'],
    'one-var': ['error', 'never'],
    'one-var-declaration-per-line': 'off',
    'operator-assignment': ['error', 'always'],
    'operator-linebreak': ['error', 'after'],
    'padded-blocks': ['error', 'never'],
    'quote-props': ['error', 'consistent-as-needed', {keywords: true}],
    'quotes': ['error', 'single', 'avoid-escape'],
    'require-jsdoc': 'off',
    'semi': ['error', 'always'],
    'semi-spacing': ['error', {before: false, after: true}],
    'sort-imports': ['error', {ignoreCase: false}],
    'sort-vars': ['error', {ignoreCase: false}],
    'space-before-blocks': 'error',
    'space-before-function-paren': ['error', 'never'],
    'space-in-parens': ['error', 'never'],
    'space-infix-ops': ['error', {int32Hint: false}],
    'space-unary-ops': ['error', {words: true, nonwords: false}],
    'spaced-comment': ['error', 'always', {exceptions: ['+', '-', '=']}],
    'wrap-regex': 'error'
  }
};
<|endoftext|>


<commit_before>import { expect, renderComponent } from '../../test_helper';
import SurveyShow from '../../../../webpack/components/surveys/SurveyShow';
import InfoModal from '../../components/InfoModal';

describe('SurveyShow', () => {
  let component;

  beforeEach(() => {
    const props = {
      currentUser:{},
      publishSurvey: ()=> {},
      setBreadcrumbPath: () => {},
      router: {},
      survey: {
        id: 1,
        name: "Robot Questionaire",
        surveySections: [1,2,3]
      },
      sections: [
        {id:1,name:"Bleep",createdBy:{email:"test_author@gmail.com"},createdAt:"2016-12-27T23:40:54.505Z",updatedAt:"2016-12-28T23:40:54.505Z",versionIndependentId:"SECT-1",version:1,controlNumber:"","questions":[]},
        {id:2,name:"Bloop",createdBy:{email:"test_author@gmail.com"},createdAt:"2016-12-28T23:40:54.505Z",updatedAt:"2016-12-29T23:40:54.505Z",versionIndependentId:"SECT-1",version:1,controlNumber:"","questions":[]},
        {id:3,name:"I am a robot",createdBy:{email:"test_author@gmail.com"},createdAt:"2016-12-29T23:40:54.505Z",updatedAt:"2016-12-30T23:40:54.505Z",versionIndependentId:"SECT-1",version:1,controlNumber:"","questions":[]}
      ],
      deleteSurvey: ()=> {}
    };
    const startState = {};
    component = renderComponent(SurveyShow, props, startState);
  });

  it('should create a list of sections', () => {
    // Drop out of JQuery and just use draw javascript selectors
    expect(component.find("a[class='panel-toggle']")).to.contain('Linked Sections' + <Button bsStyle='link' style={{ padding: 3 }} onClick={() => this.setState({showInfoLinkedSections: true})}><text className="sr-only">Click for info about this item (Linked Sections)</text></Button> + ': 3');
  });

  it('should render an empty list of sections', () => {
    let emptyComponent = renderComponent(SurveyShow, {survey: {id: 1, name: "Test"}, setBreadcrumbPath: () => {}, name: 'test'}, {});
    expect(emptyComponent[0].querySelectorAll('.survey-section').length).to.equal(0);
  });

});
<commit_msg>updated import path<commit_after>import { expect, renderComponent } from '../../test_helper';
import SurveyShow from '../../../../webpack/components/surveys/SurveyShow';
import {Button} from 'react-bootstrap';
import InfoModal from '../../../../webpack/components/InfoModal';

describe('SurveyShow', () => {
  let component;

  beforeEach(() => {
    const props = {
      currentUser:{},
      publishSurvey: ()=> {},
      setBreadcrumbPath: () => {},
      router: {},
      survey: {
        id: 1,
        name: "Robot Questionaire",
        surveySections: [1,2,3]
      },
      sections: [
        {id:1,name:"Bleep",createdBy:{email:"test_author@gmail.com"},createdAt:"2016-12-27T23:40:54.505Z",updatedAt:"2016-12-28T23:40:54.505Z",versionIndependentId:"SECT-1",version:1,controlNumber:"","questions":[]},
        {id:2,name:"Bloop",createdBy:{email:"test_author@gmail.com"},createdAt:"2016-12-28T23:40:54.505Z",updatedAt:"2016-12-29T23:40:54.505Z",versionIndependentId:"SECT-1",version:1,controlNumber:"","questions":[]},
        {id:3,name:"I am a robot",createdBy:{email:"test_author@gmail.com"},createdAt:"2016-12-29T23:40:54.505Z",updatedAt:"2016-12-30T23:40:54.505Z",versionIndependentId:"SECT-1",version:1,controlNumber:"","questions":[]}
      ],
      deleteSurvey: ()=> {}
    };
    const startState = {};
    component = renderComponent(SurveyShow, props, startState);
  });

  it('should create a list of sections', () => {
    // Drop out of JQuery and just use draw javascript selectors
    expect(component.find("a[class='panel-toggle']")).to.contain('Linked Sections' + <Button bsStyle='link' style={{ padding: 3 }} onClick={() => this.setState({showInfoLinkedSections: true})}><text className="sr-only">Click for info about this item (Linked Sections)</text></Button> + ': 3');
  });

  it('should render an empty list of sections', () => {
    let emptyComponent = renderComponent(SurveyShow, {survey: {id: 1, name: "Test"}, setBreadcrumbPath: () => {}, name: 'test'}, {});
    expect(emptyComponent[0].querySelectorAll('.survey-section').length).to.equal(0);
  });

});
<|endoftext|>


<commit_before>//= require jquery/jquery.js
//= require jquery-ui/ui/jquery-ui.js
//= require lodash/dist/lodash.js
//= require vendor/bootstrap.js
//= require select2/select2.js
//= require pines-notify/jquery.pnotify.js

//= require angular/angular.js
//= require angular-resource/angular-resource.js
//= require angular-cookies/angular-cookies.js
//= require angular-sanitize/angular-sanitize.js
//= require angular-socket-io/socket.js
//= require angular-ui-router/release/angular-ui-router.js
//= require angular-bootstrap/ui-bootstrap-tpls.js
//= require angular-ui-utils/modules/utils.js
//= require angular-ui-select2/src/select2.js
//= require angular-grid/ng-grid-2.0.7.debug.js
//= require fullcalendar/fullcalendar.js
//= require angular-ui-calendar/src/calendar.js
//= require restangular/dist/restangular.js
//= require angular-pines-notify/src/pnotify.js

//= require states/states.js
//= require auth/main.js
//= require user/main.js
//= require group/main.js
//= require search/main.js
//= require ./admin.js

//= require_self

//= require kabam/controllers/index.js

'use strict';

var dependencies = [
  'ui.router',
  'ui.bootstrap',
  'ui.notify',
  'btford.socket-io',
  'restangular',
  'kabam.auth',
  'kabam.user',
  'kabam.group',
  'kabam.search',
  'kabam.states'
];

if (window.moduleDependencies && Array.isArray(window.moduleDependencies)) {
  dependencies = dependencies.concat(window.moduleDependencies);
}

angular.module('kabam', dependencies)
  .config([
    '$stateProvider', '$urlRouterProvider', '$locationProvider', 'RestangularProvider', 'kabamStatesProvider',
    function ($stateProvider, $urlRouterProvider, $locationProvider, RestangularProvider, kabamStatesProvider) {
      // add all states that were registered in other modules
      for(var s in kabamStatesProvider.states){
        $stateProvider.state(kabamStatesProvider.states[s]);
      }

      $urlRouterProvider.otherwise('/');
      // $locationProvider.html5Mode(true)

      // setup Restangular
      RestangularProvider.setBaseUrl('/api/rest');
      RestangularProvider.setResponseExtractor(function(response) {
        var newResponse = response;
        if (angular.isArray(response)) {
          angular.forEach(newResponse, function(value, key) {
            newResponse[key].originalElement = angular.copy(value);
          });
        } else {
          newResponse.originalElement = angular.copy(response);
        }

        return newResponse;
      });
      RestangularProvider.setRestangularFields({
        id: '_id'
      });
    }
  ])
  .run([
    'guard', 'authService', '$rootScope', '$state', '$stateParams', '$log', 'socket', 'notificationService',
    function(guard, authService, $rootScope, $state, $stateParams, $log, socket, notificationService) {
      $rootScope.authService = authService;
      $rootScope.$state = $state;
      $rootScope.$stateParams = $stateParams;
      guard.watch();

      socket.on('broadcast', function(data) {
        $log.log('broadcast', data);
        $rootScope.$broadcast('broadcast', data);
      });

      socket.on('notify', function(data) {
        $log.log('notify', data);
        if (data.type && _.contains([ 'info', 'error', 'notice', 'success' ], data.type)) {
          notificationService.notify({
            type: data.type,
            text: data.message
          });
        } else {
          $rootScope.$broadcast('notify', data);
        }
      });

      $rootScope.$on('backend', function(event, args) {
        if (args.action) {
          args.sender = authService.user;
          socket.emit('backend', args);
          $log.log('event sent to backend:', args);
        } else {
          $log.error('invalid backend event: no action:', args);
        }
      });

      socket.on('update', function(data) {
        $rootScope.$broadcast('update', data);
      });

      socket.on('delete', function(data) {
        $rootScope.$broadcast('delete', data);
      });

      socket.on('create', function(data) {
        $rootScope.$broadcast('create', data);
      });

    }
  ]);
<commit_msg>chore(app): chat-xmpp dependency<commit_after>//= require jquery/jquery.js
//= require jquery-ui/ui/jquery-ui.js
//= require lodash/dist/lodash.js
//= require vendor/bootstrap.js
//= require select2/select2.js
//= require pines-notify/jquery.pnotify.js

//= require angular/angular.js
//= require angular-resource/angular-resource.js
//= require angular-cookies/angular-cookies.js
//= require angular-sanitize/angular-sanitize.js
//= require angular-socket-io/socket.js
//= require angular-ui-router/release/angular-ui-router.js
//= require angular-bootstrap/ui-bootstrap-tpls.js
//= require angular-ui-utils/modules/utils.js
//= require angular-ui-select2/src/select2.js
//= require angular-grid/ng-grid-2.0.7.debug.js
//= require fullcalendar/fullcalendar.js
//= require angular-ui-calendar/src/calendar.js
//= require restangular/dist/restangular.js
//= require angular-pines-notify/src/pnotify.js

//= require states/states.js
//= require auth/main.js
//= require user/main.js
//= require group/main.js
//= require search/main.js
//= require chat-xmpp/main.js
//= require ./admin.js

//= require_self

//= require kabam/controllers/index.js

'use strict';

var dependencies = [
  'ui.router',
  'ui.bootstrap',
  'ui.notify',
  'btford.socket-io',
  'restangular',
  'kabam.auth',
  'kabam.user',
  'kabam.group',
  'kabam.search',
  'kabam.states',
  'ChatXmpp'
];

if (window.moduleDependencies && Array.isArray(window.moduleDependencies)) {
  dependencies = dependencies.concat(window.moduleDependencies);
}

angular.module('kabam', dependencies)
  .config([
    '$stateProvider', '$urlRouterProvider', '$locationProvider', 'RestangularProvider', 'kabamStatesProvider',
    function ($stateProvider, $urlRouterProvider, $locationProvider, RestangularProvider, kabamStatesProvider) {
      // add all states that were registered in other modules
      for(var s in kabamStatesProvider.states){
        $stateProvider.state(kabamStatesProvider.states[s]);
      }

      $urlRouterProvider.otherwise('/');
      // $locationProvider.html5Mode(true)

      // setup Restangular
      RestangularProvider.setBaseUrl('/api/rest');
      RestangularProvider.setResponseExtractor(function(response) {
        var newResponse = response;
        if (angular.isArray(response)) {
          angular.forEach(newResponse, function(value, key) {
            newResponse[key].originalElement = angular.copy(value);
          });
        } else {
          newResponse.originalElement = angular.copy(response);
        }

        return newResponse;
      });
      RestangularProvider.setRestangularFields({
        id: '_id'
      });
    }
  ])
  .run([
    'guard', 'authService', '$rootScope', '$state', '$stateParams', '$log', 'socket', 'notificationService',
    function(guard, authService, $rootScope, $state, $stateParams, $log, socket, notificationService) {
      $rootScope.authService = authService;
      $rootScope.$state = $state;
      $rootScope.$stateParams = $stateParams;
      guard.watch();

      socket.on('broadcast', function(data) {
        $log.log('broadcast', data);
        $rootScope.$broadcast('broadcast', data);
      });

      socket.on('notify', function(data) {
        $log.log('notify', data);
        if (data.type && _.contains([ 'info', 'error', 'notice', 'success' ], data.type)) {
          notificationService.notify({
            type: data.type,
            text: data.message
          });
        } else {
          $rootScope.$broadcast('notify', data);
        }
      });

      $rootScope.$on('backend', function(event, args) {
        if (args.action) {
          args.sender = authService.user;
          socket.emit('backend', args);
          $log.log('event sent to backend:', args);
        } else {
          $log.error('invalid backend event: no action:', args);
        }
      });

      socket.on('update', function(data) {
        $rootScope.$broadcast('update', data);
      });

      socket.on('delete', function(data) {
        $rootScope.$broadcast('delete', data);
      });

      socket.on('create', function(data) {
        $rootScope.$broadcast('create', data);
      });

    }
  ]);
<|endoftext|>


<commit_before>// = Server config =============================================================

export const port = 3000

export const enableGraphiQL = true;

export const logFile = 'store.log'

// = App config ================================================================
<commit_msg>Add ability to define port as environment variable<commit_after>// = Server config =============================================================

export const port = process.env.PORT || 3000

export const enableGraphiQL = true;

export const logFile = 'store.log'

// = App config ================================================================
<|endoftext|>


<commit_before>/**
 * @class Denkmal_Component_EventList
 * @extends Denkmal_Component_Abstract
 */
var Denkmal_Component_EventList = Denkmal_Component_Abstract.extend({

  /** @type String */
  _class: 'Denkmal_Component_EventList',

  events: {
    'click .showEventDetails': function(event) {
      var href = $(event.currentTarget).data('href');
      cm.router.route(href);
    }
  }
});
<commit_msg>Defer opening floatbox to give time for the click-feedback animation to trigger<commit_after>/**
 * @class Denkmal_Component_EventList
 * @extends Denkmal_Component_Abstract
 */
var Denkmal_Component_EventList = Denkmal_Component_Abstract.extend({

  /** @type String */
  _class: 'Denkmal_Component_EventList',

  events: {
    'click .showEventDetails': function(event) {
      var href = $(event.currentTarget).data('href');
      _.defer(function() {
        // Defer is required for the click-feedback animation to trigger on Chrome/Androi
        cm.router.route(href);
      });
    }
  }
});
<|endoftext|>