<commit_before>'use strict';

var fs             = require('fs'),
    Path           = require('path'),
    url            = require('url'),
    format         = require('util').format,
    _drop          = require('lodash/array/drop'),
    _noop          = require('lodash/utility/noop'),
    _keys          = require('lodash/object/keys'),
    _isFunction    = require('lodash/lang/isFunction'),
    _isArray       = require('lodash/lang/isArray'),
    _isPlainObject = require('lodash/lang/isPlainObject');

var util = module.exports = {
    /**
     * Writes messages to stdout.
     * Log messages are suppressed by default, but can be enabled by setting the DEBUG variable.
     * @type {function}
     */
    debug: require('debug')('swagger:parser'),

    /**
     * Asynchronously invokes the given callback function with the given parameters.
     *
     * NOTE: This unwinds the call stack, which avoids stack overflows that can occur when crawling very complex Swagger APIs
     *
     * @param {function} callback
     * @param {*}     [err]
     * @param {...*}  [params]
     */
    doCallback: function(callback, err, params) {
        var args = _drop(arguments);
        process.nextTick(function() {
            callback.apply(null, args);
        });
    },

    /**
     * Recursively crawls an object, and calls the given function for each nested object.
     * This function can be used synchronously or asynchronously.
     *
     * @param   {object|*[]}    obj
     * The object (or array) to be crawled
     *
     * @param   {string}        [path]
     * The starting path of the object (e.g. "/definitions/pet")
     *
     * @param   {function}      [callback]
     * Called when the entire object tree is done being crawled, or when an error occurs.
     * The signature is `function(err, obj)`.
     *
     * @param   {function}      forEach
     * Called for each nested object in the tree. The signature is `function(parents, propName, propPath, continue)`,
     * where `parents` is an array of parent objects, `propName` is the name of the nested object property,
     * `propPath` is a full path of nested object (e.g. "/paths//get/responses/200/schema"),
     * and `continue` is a function to call to resume crawling the object.
     */
    crawlObject: function(obj, path, callback, forEach) {
        // Shift args if needed
        if (_isFunction(path)) {
            forEach = callback;
            callback = path;
            path = '';
        }
        if (!_isFunction(forEach)) {
            forEach = callback;
            callback = _noop;
        }

        // Do nothing if it's not an object or array
        if (!_isPlainObject(obj) && !_isArray(obj)) {
            callback(null, obj);
            return;
        }

        // Keep a stack of parent objects
        var parents = forEach.__parents = forEach.__parents || [];
        parents.push(obj);

        // Loop through each item in the object/array
        var properties = _keys(obj);
        crawlNextProperty();

        function crawlNextProperty(err) {
            if (err) {
                // An error occurred, so stop crawling and bubble it up
                forEach.__parents.pop();
                callback(err);
                return;
            }
            else if (properties.length === 0) {
                // We've crawled all of this object's properties, so we're done.
                forEach.__parents.pop();
                util.doCallback(callback, null, obj);
                return;
            }

            var propName = properties.pop();
            var propValue = obj[propName];
            var propPath = path + '/' + propName;

            if (_isPlainObject(propValue)) {
                // Found an object property, so call the callback
                forEach(parents, propName, propPath, function(err) {
                    if (err) {
                        // An error occurred, so bubble it up
                        crawlNextProperty(err);
                    }
                    else {
                        // Crawl the nested object (re-fetch it from the parent obj, in case it has changed)
                        util.crawlObject(obj[propName], propPath, crawlNextProperty, forEach);
                    }
                });
            }
            else if (_isArray(propValue)) {
                // This is an array property, so crawl its items
                util.crawlObject(propValue, propPath, crawlNextProperty, forEach);
            }
            else {
                // This isn't an object property, so skip it
                util.doCallback(crawlNextProperty);
            }
        }
    },

    /**
     * Creates an Error with a formatted string message.
     *
     * @param     {Error}     [err]       The original error, if any
     * @param     {string}    [message]   A user-friendly message about the source of the error
     * @param     {...*}      [params]    One or more {@link util#format} params
     * @returns   {Error}
     */
    newError: function(err, message, params) {
        if (err && err instanceof Error) {
            return new Error(errorDump.apply(null, arguments));
        }
        else {
            return new Error(format.apply(null, arguments));
        }
    },

    /**
     * Creates a SyntaxError with a formatted string message.
     *
     * @param     {Error}     [err]       The original error, if any
     * @param     {string}    [message]   A user-friendly message about the source of the error
     * @param     {...*}      [params]    One or more {@link util#format} params
     * @returns   {SyntaxError}
     */
    newSyntaxError: function(err, message, params) {
        if (err && err instanceof Error) {
            return new SyntaxError(errorDump.apply(null, arguments));
        }
        else {
            return new SyntaxError(format.apply(null, arguments));
        }
    },

    /**
     * Determines if we're running in a browser.
     * @returns {boolean}
     */
    isBrowser: function() {
        return fs.readFile === undefined;
    },

    /**
     * Determines whether the given path is a local filesystem path (as opposed to a remote path or URL).
     * NOTE: This does NOT verify that the path exists or is valid.
     *
     * @param   {string|Url}    path    A path or URL (e.g. "/path/to/file", "c:\path\to\file", "http://company.com/path/to/file")
     * @returns {boolean}
     */
    isLocalPath: function(path) {
        /* istanbul ignore if: code-coverage doesn't run in the browser */
        if (util.isBrowser()) {
            // Local paths are not allowed in browsers
            return false;
        }

        // NOTE: The following are all considered local files: "file://path/to/file", "/path/to/file", "c:\path\to\file"
        path = url.parse(path);
        return path.protocol !== 'http:' && path.protocol !== 'https:';
    },

    /**
     * Normalizes a path or URL across all environments (Linux, Mac, Windows, browsers).
     *
     * @param   {string}    path       A path or URL (e.g. "/path/to/file", "c:\path\to\file", "http://company.com/path/to/file")
     * @param   {boolean}   [isLocal]  Set to true to treat `path` as a local path
     * @returns {Url}
     */
    normalizePath: function(path, isLocal) {
        isLocal = isLocal === undefined ? util.isLocalPath(path) : isLocal;

        if (isLocal) {
            path = path.split(Path.sep).join('/');  // Windows
            path = encodeURI(path);
            path = url.format({pathname: path});
            return url.parse(path);
        }
        else {
            return url.parse(path);
        }
    },

    /**
     * De-normalizes a path or URL to a string that is properly formatted.
     *
     * @param   {string}    path       A path or URL (e.g. "/path/to/file", "c:\path\to\file", "http://company.com/path/to/file")
     * @param   {boolean}   [isLocal]  Set to true to treat `path` as a local path
     * @returns {string}
     */
    denormalizePath: function(path, isLocal) {
        isLocal = isLocal === undefined ? util.isLocalPath(path) : isLocal;

        if (isLocal) {
            path = decodeURIComponent(path);
            return Path.normalize(path);
        }
        else {
            return path;
        }
    },

    /**
     * Resolves the given paths to an absolute path.
     * NOTE: This does NOT verify that the path exists or is valid.
     *
     * @param   {string}    basePath
     * The base path, which must be absolute (e.g. "/base/path", "c:\base\path", "http://company.com/base/path")
     *
     * @param   {string}    path
     * The path to be resolved, which may be relative or absolute. (e.g. "path/to/file", "path\to\file")
     *
     * @returns {string}
     * The resolved, absolute path. (e.g. "/full/path/to/file", "c:\full\path\to\file", "http://company.com/full/path/to/file")
     */
    resolvePath: function(basePath, path) {
        util.debug('Resolving path "%s", relative to "%s"', path, basePath);

        // Normalize the paths
        var baseIsLocal = util.isLocalPath(basePath);
        var pathIsLocal = util.isLocalPath(path);
        basePath = util.normalizePath(basePath, baseIsLocal);
        path = util.normalizePath(path, pathIsLocal && baseIsLocal);

        // url.resolve() works across all environments (Linux, Mac, Windows, browsers),
        // even if basePath and path are different types (e.g. one is a URL, the other is a local path)
        var resolvedUrl = url.resolve(basePath, path);
        resolvedUrl = util.denormalizePath(resolvedUrl);

        util.debug('    Resolved to %s', resolvedUrl);
        return resolvedUrl;
    },

    /**
     * Returns the current working directory across environments (Linux, Mac, Windows, browsers).
     * The returned path always include a trailing slash to ensure that it behaves properly with {@link url#resolve}.
     *
     * @returns {string}
     */
    cwd: function() {
        /* istanbul ignore next: code-coverage doesn't run in the browser */
        var cwd = util.isBrowser() ? window.location.href : process.cwd() + '/';
        cwd = util.normalizePath(cwd);

        // Remove the file name (if any) from the pathname
        var lastSlash = cwd.pathname.lastIndexOf('/') + 1;
        cwd.pathname = cwd.pathname.substr(0, lastSlash);

        // Remove everything after the pathname
        cwd.path = null;
        cwd.search = null;
        cwd.query = null;
        cwd.hash = null;

        // Format and denormalize only the remaining parts of the URL
        cwd = url.format(cwd);
        cwd = util.denormalizePath(cwd);

        return cwd;
    }
};

/**
 * Returns detailed error information that can be written to a log, stderror, etc.
 *
 * @param   {Error}     err         The Error object
 * @param   {string}    [message]   Optional message about where and why the error occurred.
 * @param   {...*}      [params]    One or more params to be passed to {@link util#format}
 */
function errorDump(err, message, params) {
    // Format the message string
    message = format.apply(null, _drop(arguments)) + ': \n';

    // Gather detailed error information
    message += (err.name || 'Error') + ': ';

    var stack = err.stack;

    /* istanbul ignore else: Only IE doesn't have an Error.stack property */
    if (stack) {
        /* istanbul ignore if: Only Safari doesn't include Error.message in Error.stack */
        if (stack.indexOf(err.message) === -1) {
            message += err.message + ' \n';
        }

        return message + stack;
    }
    else {
        return message + err.message;
    }
}
<commit_msg>Switched to `setImmediate` instead of `process.nextTick()` when running in Node<commit_after>'use strict';

var fs             = require('fs'),
    Path           = require('path'),
    url            = require('url'),
    format         = require('util').format,
    _drop          = require('lodash/array/drop'),
    _noop          = require('lodash/utility/noop'),
    _keys          = require('lodash/object/keys'),
    _isFunction    = require('lodash/lang/isFunction'),
    _isArray       = require('lodash/lang/isArray'),
    _isPlainObject = require('lodash/lang/isPlainObject');

var util = module.exports = {
    /**
     * Writes messages to stdout.
     * Log messages are suppressed by default, but can be enabled by setting the DEBUG variable.
     * @type {function}
     */
    debug: require('debug')('swagger:parser'),

    /**
     * Asynchronously invokes the given callback function with the given parameters.
     *
     * NOTE: This unwinds the call stack, which avoids stack overflows that can occur when crawling very complex Swagger APIs
     *
     * @param {function} callback
     * @param {*}     [err]
     * @param {...*}  [params]
     */
    doCallback: function(callback, err, params) {
        var args = _drop(arguments);

        /* istanbul ignore if: code-coverage doesn't run in the browser */
        if (util.isBrowser()) {
            process.nextTick(invokeCallback);
        }
        else {
            setImmediate(invokeCallback);
        }

        function invokeCallback() {
            callback.apply(null, args);
        }
    },

    /**
     * Recursively crawls an object, and calls the given function for each nested object.
     * This function can be used synchronously or asynchronously.
     *
     * @param   {object|*[]}    obj
     * The object (or array) to be crawled
     *
     * @param   {string}        [path]
     * The starting path of the object (e.g. "/definitions/pet")
     *
     * @param   {function}      [callback]
     * Called when the entire object tree is done being crawled, or when an error occurs.
     * The signature is `function(err, obj)`.
     *
     * @param   {function}      forEach
     * Called for each nested object in the tree. The signature is `function(parents, propName, propPath, continue)`,
     * where `parents` is an array of parent objects, `propName` is the name of the nested object property,
     * `propPath` is a full path of nested object (e.g. "/paths//get/responses/200/schema"),
     * and `continue` is a function to call to resume crawling the object.
     */
    crawlObject: function(obj, path, callback, forEach) {
        // Shift args if needed
        if (_isFunction(path)) {
            forEach = callback;
            callback = path;
            path = '';
        }
        if (!_isFunction(forEach)) {
            forEach = callback;
            callback = _noop;
        }

        // Do nothing if it's not an object or array
        if (!_isPlainObject(obj) && !_isArray(obj)) {
            callback(null, obj);
            return;
        }

        // Keep a stack of parent objects
        var parents = forEach.__parents = forEach.__parents || [];
        parents.push(obj);

        // Loop through each item in the object/array
        var properties = _keys(obj);
        crawlNextProperty();

        function crawlNextProperty(err) {
            if (err) {
                // An error occurred, so stop crawling and bubble it up
                forEach.__parents.pop();
                callback(err);
                return;
            }
            else if (properties.length === 0) {
                // We've crawled all of this object's properties, so we're done.
                forEach.__parents.pop();
                util.doCallback(callback, null, obj);
                return;
            }

            var propName = properties.pop();
            var propValue = obj[propName];
            var propPath = path + '/' + propName;

            if (_isPlainObject(propValue)) {
                // Found an object property, so call the callback
                forEach(parents, propName, propPath, function(err) {
                    if (err) {
                        // An error occurred, so bubble it up
                        crawlNextProperty(err);
                    }
                    else {
                        // Crawl the nested object (re-fetch it from the parent obj, in case it has changed)
                        util.crawlObject(obj[propName], propPath, crawlNextProperty, forEach);
                    }
                });
            }
            else if (_isArray(propValue)) {
                // This is an array property, so crawl its items
                util.crawlObject(propValue, propPath, crawlNextProperty, forEach);
            }
            else {
                // This isn't an object property, so skip it
                util.doCallback(crawlNextProperty);
            }
        }
    },

    /**
     * Creates an Error with a formatted string message.
     *
     * @param     {Error}     [err]       The original error, if any
     * @param     {string}    [message]   A user-friendly message about the source of the error
     * @param     {...*}      [params]    One or more {@link util#format} params
     * @returns   {Error}
     */
    newError: function(err, message, params) {
        if (err && err instanceof Error) {
            return new Error(errorDump.apply(null, arguments));
        }
        else {
            return new Error(format.apply(null, arguments));
        }
    },

    /**
     * Creates a SyntaxError with a formatted string message.
     *
     * @param     {Error}     [err]       The original error, if any
     * @param     {string}    [message]   A user-friendly message about the source of the error
     * @param     {...*}      [params]    One or more {@link util#format} params
     * @returns   {SyntaxError}
     */
    newSyntaxError: function(err, message, params) {
        if (err && err instanceof Error) {
            return new SyntaxError(errorDump.apply(null, arguments));
        }
        else {
            return new SyntaxError(format.apply(null, arguments));
        }
    },

    /**
     * Determines if we're running in a browser.
     * @returns {boolean}
     */
    isBrowser: function() {
        return fs.readFile === undefined;
    },

    /**
     * Determines whether the given path is a local filesystem path (as opposed to a remote path or URL).
     * NOTE: This does NOT verify that the path exists or is valid.
     *
     * @param   {string|Url}    path    A path or URL (e.g. "/path/to/file", "c:\path\to\file", "http://company.com/path/to/file")
     * @returns {boolean}
     */
    isLocalPath: function(path) {
        /* istanbul ignore if: code-coverage doesn't run in the browser */
        if (util.isBrowser()) {
            // Local paths are not allowed in browsers
            return false;
        }

        // NOTE: The following are all considered local files: "file://path/to/file", "/path/to/file", "c:\path\to\file"
        path = url.parse(path);
        return path.protocol !== 'http:' && path.protocol !== 'https:';
    },

    /**
     * Normalizes a path or URL across all environments (Linux, Mac, Windows, browsers).
     *
     * @param   {string}    path       A path or URL (e.g. "/path/to/file", "c:\path\to\file", "http://company.com/path/to/file")
     * @param   {boolean}   [isLocal]  Set to true to treat `path` as a local path
     * @returns {Url}
     */
    normalizePath: function(path, isLocal) {
        isLocal = isLocal === undefined ? util.isLocalPath(path) : isLocal;

        if (isLocal) {
            path = path.split(Path.sep).join('/');  // Windows
            path = encodeURI(path);
            path = url.format({pathname: path});
            return url.parse(path);
        }
        else {
            return url.parse(path);
        }
    },

    /**
     * De-normalizes a path or URL to a string that is properly formatted.
     *
     * @param   {string}    path       A path or URL (e.g. "/path/to/file", "c:\path\to\file", "http://company.com/path/to/file")
     * @param   {boolean}   [isLocal]  Set to true to treat `path` as a local path
     * @returns {string}
     */
    denormalizePath: function(path, isLocal) {
        isLocal = isLocal === undefined ? util.isLocalPath(path) : isLocal;

        if (isLocal) {
            path = decodeURIComponent(path);
            return Path.normalize(path);
        }
        else {
            return path;
        }
    },

    /**
     * Resolves the given paths to an absolute path.
     * NOTE: This does NOT verify that the path exists or is valid.
     *
     * @param   {string}    basePath
     * The base path, which must be absolute (e.g. "/base/path", "c:\base\path", "http://company.com/base/path")
     *
     * @param   {string}    path
     * The path to be resolved, which may be relative or absolute. (e.g. "path/to/file", "path\to\file")
     *
     * @returns {string}
     * The resolved, absolute path. (e.g. "/full/path/to/file", "c:\full\path\to\file", "http://company.com/full/path/to/file")
     */
    resolvePath: function(basePath, path) {
        util.debug('Resolving path "%s", relative to "%s"', path, basePath);

        // Normalize the paths
        var baseIsLocal = util.isLocalPath(basePath);
        var pathIsLocal = util.isLocalPath(path);
        basePath = util.normalizePath(basePath, baseIsLocal);
        path = util.normalizePath(path, pathIsLocal && baseIsLocal);

        // url.resolve() works across all environments (Linux, Mac, Windows, browsers),
        // even if basePath and path are different types (e.g. one is a URL, the other is a local path)
        var resolvedUrl = url.resolve(basePath, path);
        resolvedUrl = util.denormalizePath(resolvedUrl);

        util.debug('    Resolved to %s', resolvedUrl);
        return resolvedUrl;
    },

    /**
     * Returns the current working directory across environments (Linux, Mac, Windows, browsers).
     * The returned path always include a trailing slash to ensure that it behaves properly with {@link url#resolve}.
     *
     * @returns {string}
     */
    cwd: function() {
        /* istanbul ignore next: code-coverage doesn't run in the browser */
        var cwd = util.isBrowser() ? window.location.href : process.cwd() + '/';
        cwd = util.normalizePath(cwd);

        // Remove the file name (if any) from the pathname
        var lastSlash = cwd.pathname.lastIndexOf('/') + 1;
        cwd.pathname = cwd.pathname.substr(0, lastSlash);

        // Remove everything after the pathname
        cwd.path = null;
        cwd.search = null;
        cwd.query = null;
        cwd.hash = null;

        // Format and denormalize only the remaining parts of the URL
        cwd = url.format(cwd);
        cwd = util.denormalizePath(cwd);

        return cwd;
    }
};

/**
 * Returns detailed error information that can be written to a log, stderror, etc.
 *
 * @param   {Error}     err         The Error object
 * @param   {string}    [message]   Optional message about where and why the error occurred.
 * @param   {...*}      [params]    One or more params to be passed to {@link util#format}
 */
function errorDump(err, message, params) {
    // Format the message string
    message = format.apply(null, _drop(arguments)) + ': \n';

    // Gather detailed error information
    message += (err.name || 'Error') + ': ';

    var stack = err.stack;

    /* istanbul ignore else: Only IE doesn't have an Error.stack property */
    if (stack) {
        /* istanbul ignore if: Only Safari doesn't include Error.message in Error.stack */
        if (stack.indexOf(err.message) === -1) {
            message += err.message + ' \n';
        }

        return message + stack;
    }
    else {
        return message + err.message;
    }
}
<|endoftext|>


<commit_before>
const MAX_SIZE = 1024;
// const MAX_WIDTH = 1024;
// const MAX_HEIGHT = 768;
const isTouchEnabled = 'createTouch' in window.document;

const screenUtils = {

  isTouch: isTouchEnabled,

  getDimensions: () => {
    return {
      width: Math.min( window.document.body.clientWidth, MAX_SIZE ),
      height: Math.min( window.document.body.clientHeight, MAX_SIZE )
    }
  }

};

export default screenUtils;
<commit_msg>Add screenUtils - wip<commit_after>
const MAX_SIZE = 1024;
const PIXEL_RATIO = window.devicePixelRatio || 1;
// const MAX_WIDTH = 1024;
// const MAX_HEIGHT = 768;
const isTouchEnabled = 'createTouch' in window.document;

const getWidth = () => {
	return window.document.body.clientWidth;
	return Math.min( window.screen.width * PIXEL_RATIO, MAX_SIZE );
}

const getHeight = () => {
	return window.document.body.clientHeight;
	return Math.min( window.screen.height * PIXEL_RATIO, MAX_SIZE );
}

const screenUtils = {

  isTouch: isTouchEnabled,

  getDimensions: () => {
    return {
      // width: screen.width,
      // height: screen.height
      width: getWidth(),
      height: getHeight()
    }
  }

};

export default screenUtils;
<|endoftext|>


<commit_before>/* eslint-disable */
import fs from 'fs';
import _ from 'underscore';
import { readFileMap, storeFileMap } from './file';
import getSize from 'get-folder-size';
import {
  fileMapPath,
  activityPatternPath,
  statePath,
  storageDirPath,
  powerStorageSlider,
  maxStorageSlider
} from './ENV_variables';

// to be CHANGED don't real all fileMapEntries
function readFilesInfo() {
  const fileMap = JSON.parse(fs.readFileSync(fileMapPath));
  const filesInfo = [];
  for(var key in fileMap) {
    if(fileMap.hasOwnProperty(key)) {
        filesInfo.push({
          id: key,
          shreds: fileMap[key].shreds,
          name: fileMap[key].name,
          status: 1,
          uploadTime: fileMap[key].uploadTime,
          size: fileMap[key].size/1024,
        });
    }
  }
  return filesInfo;
}

function loadActivityPattern(type) { // asynchronouslly loads the Activity Pattern
  const hourlyPatterns = [];
  const averagePatterns = [];
  const hourlyLabels = [];
  const activityPatternObject = JSON.parse(fs.readFileSync(activityPath));
  const patterns =
        (activityPatternObject.hasOwnProperty("Pattern"))
        ?
        activityPatternObject["Pattern"]
        :
        [];
  let sum = 0;
  for (var i=0; i<patterns.length; i++){
    sum +=parseInt(patterns[i]);
    if(i%6==0){
      hourlyPatterns.push(sum);
      sum = 0;
    }
  }
  if (type=='data'){
    return hourlyPatterns;
  } else if (type=='labels'){
    for (var i=0; i<hourlyPatterns.length; i++){
      hourlyLabels.push('');
    }
    return hourlyLabels;
  } else if (type=='average'){
    for (var i=0; i<hourlyPatterns.length; i++){
      averagePatterns.push(3);
    }
    return averagePatterns;
  }
}

function getStorageSpace(){
  const state = JSON.parse(fs.readFileSync(statePath));
  if(state.hasOwnProperty('storage')) {
    return state.storage;
  } else {
    console.error('Error reading storage field in ' + statePath);
  }
}

function getUsedSpace(){
  let usedSpace = 0;
  fs.readdirSync(storageDirPath).map((fileName)=>{
    if(fs.statSync(storageDirPath+'/'+fileName)){
      usedSpace+=fs.statSync(storageDirPath+'/'+fileName).size;
    }
  })
  return usedSpace/1024/1024;
}

function getStorageInfo(){

  const empty = getStorageSpace() - getUsedSpace();
  const used = getUsedSpace();

  return [empty,used]
}

function transform(value) {
  return Math.round((Math.exp(powerStorageSlider * value / maxStorageSlider) - 1) / (Math.exp(powerStorageSlider) - 1) * maxStorageSlider);
}

function reverse(value) {
  return (1 / powerStorageSlider) * Math.log(((Math.exp(powerStorageSlider) - 1) * value / maxStorageSlider) + 1) * maxStorageSlider;
}

function editStorage(newStorage){
  const state = JSON.parse(fs.readFileSync(statePath));
  state.storage = newStorage;
  fs.writeFileSync(statePath, JSON.stringify(state));
}

export {
  editStorage,
  reverse,
  transform,
  getStorageInfo,
  getUsedSpace,
  getStorageSpace,
  loadActivityPattern,
  readFilesInfo,
};
<commit_msg>fix typo activityPath<commit_after>/* eslint-disable */
import fs from 'fs';
import _ from 'underscore';
import { readFileMap, storeFileMap } from './file';
import getSize from 'get-folder-size';
import {
  fileMapPath,
  activityPatternPath,
  statePath,
  storageDirPath,
  powerStorageSlider,
  maxStorageSlider
} from './ENV_variables';

// to be CHANGED don't real all fileMapEntries
function readFilesInfo() {
  const fileMap = JSON.parse(fs.readFileSync(fileMapPath));
  const filesInfo = [];
  for(var key in fileMap) {
    if(fileMap.hasOwnProperty(key)) {
        filesInfo.push({
          id: key,
          shreds: fileMap[key].shreds,
          name: fileMap[key].name,
          status: 1,
          uploadTime: fileMap[key].uploadTime,
          size: fileMap[key].size/1024,
        });
    }
  }
  return filesInfo;
}

function loadActivityPattern(type) { // asynchronouslly loads the Activity Pattern
  const hourlyPatterns = [];
  const averagePatterns = [];
  const hourlyLabels = [];
  const activityPatternObject = JSON.parse(fs.readFileSync(activityPatternPath));
  const patterns =
        (activityPatternObject.hasOwnProperty("Pattern"))
        ?
        activityPatternObject["Pattern"]
        :
        [];
  let sum = 0;
  for (var i=0; i<patterns.length; i++){
    sum +=parseInt(patterns[i]);
    if(i%6==0){
      hourlyPatterns.push(sum);
      sum = 0;
    }
  }
  if (type=='data'){
    return hourlyPatterns;
  } else if (type=='labels'){
    for (var i=0; i<hourlyPatterns.length; i++){
      hourlyLabels.push('');
    }
    return hourlyLabels;
  } else if (type=='average'){
    for (var i=0; i<hourlyPatterns.length; i++){
      averagePatterns.push(3);
    }
    return averagePatterns;
  }
}

function getStorageSpace(){
  const state = JSON.parse(fs.readFileSync(statePath));
  if(state.hasOwnProperty('storage')) {
    return state.storage;
  } else {
    console.error('Error reading storage field in ' + statePath);
  }
}

function getUsedSpace(){
  let usedSpace = 0;
  fs.readdirSync(storageDirPath).map((fileName)=>{
    if(fs.statSync(storageDirPath+'/'+fileName)){
      usedSpace+=fs.statSync(storageDirPath+'/'+fileName).size;
    }
  })
  return usedSpace/1024/1024;
}

function getStorageInfo(){

  const empty = getStorageSpace() - getUsedSpace();
  const used = getUsedSpace();

  return [empty,used]
}

function transform(value) {
  return Math.round((Math.exp(powerStorageSlider * value / maxStorageSlider) - 1) / (Math.exp(powerStorageSlider) - 1) * maxStorageSlider);
}

function reverse(value) {
  return (1 / powerStorageSlider) * Math.log(((Math.exp(powerStorageSlider) - 1) * value / maxStorageSlider) + 1) * maxStorageSlider;
}

function editStorage(newStorage){
  const state = JSON.parse(fs.readFileSync(statePath));
  state.storage = newStorage;
  fs.writeFileSync(statePath, JSON.stringify(state));
}

export {
  editStorage,
  reverse,
  transform,
  getStorageInfo,
  getUsedSpace,
  getStorageSpace,
  loadActivityPattern,
  readFilesInfo,
};
<|endoftext|>


<commit_before>/**
 * GCMD keywords.
 */

Ext.define('DMPlanner.ux.Keywords', {
    extend: 'Ext.panel.Panel',
    alias: 'widget.dmpkeywords',
    requires: [
        'Ext.ux.grid.FilterBar', //
        'Ext.grid.plugin.DragDrop', //
        'Ext.grid.column.Template', //
        'Ext.tree.plugin.TreeViewDragDrop', //
        'Ext.data.Model', //
        'Ext.data.Store', //
        'Ext.data.TreeStore', //
        'Ext.data.proxy.Rest', //
        'Ext.data.proxy.JsonP', //
        'Ext.layout.container.Border', //
        'Ext.tab.Panel', //
        'Ext.tree.Panel', //
        'Ext.LoadMask',//
        'Ext.data.writer.Json'//
    ],

    layout: {
        type: 'border'
    },
    title: 'Keywords',

    dmpSerialize: function(records) {
        var obj = [];

        Ext.each(records, function(record) {
            var s = Ext.data.writer.Json.prototype.getRecordData(record);
            //don't want to save these
            delete s.leaf;
            delete s.parentId;

            obj.push(s);
        });

        return obj;
    },

    initComponent: function() {
        var me = this, keywordtree, keywords,
            addTpl = '<tpl if="text && depth !== 1">

</tpl>',
            removeTpl = '<tpl if="text">

</tpl>',
            helpCol = {
                xtype: 'templatecolumn',
                width: 28,
                text: '',
                hideable: false,
                style: {cursor: 'help'},
                tpl: '<tpl if="definition">

</tpl>'
            },
            testDuplicate = function(node, data, overModel, dropPosition, dropHandlers) {
                var store = this.down('#planKeywords').getStore(),
                    draggedRecords = data.records,
                    ln = draggedRecords.length;

                for (i = 0; i < ln; i++) {
                    record = draggedRecords[i];
                    //reject duplicates
                    if(store.findExact('keywordid',record.getId()) !== -1) {
                        return false;
                    }

                    return true;
                }
            },
            addKeyword = function (view, el, idx, col){
                var store = this.down('#planKeywords').getStore(),
                    sel = view.getSelectionModel().getSelection(),
                    data = {records: sel};

                if(testDuplicate.call(this,null, data)){
                    store.add(sel);
                }
            },
            addCol = {
                xtype: 'templatecolumn',
                width: 28,
                text: '',
                hideable: false,
                tpl: addTpl,
                action: 'addkeyword',
                listeners: {
                    click: {
                        fn: addKeyword,
                        scope: this
                    }
                }
            },
            rmKeyword = function (view, el, idx, col){
                var sel = view.getSelectionModel().getSelection();
                view.getStore().remove(sel);
            };

        if (!Ext.ModelManager.getModel('KeywordNode')) {
            Ext.define('KeywordNode', {
                extend: 'Ext.data.Model',
                fields: [{
                    name: 'keywordid',
                    type: 'string'
                }, {
                    name: 'text',
                    type: 'string',
                    useNull: true
                }, {
                    name: 'definition',
                    type: 'string',
                    useNull: true
                }, {
                    name: 'fullname',
                    type: 'string',
                    useNull: true
                }],
                idProperty: 'keywordid',

                proxy: {
                    type: 'jsonp',
                    url: 'http://gcmd.herokuapp.com/keyword/tree',
                    reader: {
                        type: 'json'
                    },
                    appendId: true
                }
            });
        }

        if (!Ext.getStore('PlanKeywords')) {
            Ext.create('Ext.data.Store', {
                model: 'KeywordNode',
                storeId: 'PlanKeywords',
                //autoLoad: false,
                autoDestroy: true,
                data: me.data,
                proxy: {
                    type: 'memory',
                    reader: {
                        type: 'json',
                        root: 'data'
                    }
                },

                listeners: {
                    datachanged: function(store) {
                        var me = this,
                            recs = store.getRange(),
                            data = me.dmpSerialize(recs);

                        me.fireEvent('plugindatachanged', me, data);
                    },
                    scope: me
                }
            });
        }

        if (!Ext.getStore('KeywordNodes')) {
            Ext.create('Ext.data.TreeStore', {
                model: 'KeywordNode',
                storeId: 'KeywordNodes',
                clearOnLoad: true,
                autoLoad: false,
                defaultRootId: ''
            }).load();
        }
        if (!Ext.getStore('Keywords')) {
            Ext.create('Ext.data.Store', {
                model: 'KeywordNode',
                storeId: 'Keywords',
                autoLoad: false,
                remoteSort: true,
                remoteFilter: true,
                sorters: {
                    property: 'text',
                    direction: 'ASC'
                },

                proxy: {
                    type: 'jsonp',
                    //url : 'http://localhost:8088/keywordlist',
                    url: 'http://gcmd.herokuapp.com/keywordlist',
                    reader: {
                        type: 'json',
                        root: 'data'
                    }
                }
            }).load();
        }

        keywordtree = {
            xtype: 'treepanel',
            itemId: 'keywordTree',
            title: 'Keyword Tree',
            rootVisible: false,
            store: 'KeywordNodes',
            multiSelect: true,
            singleExpand: true,
            cls: 'dmp-keyword-tree',
            hideHeaders: true,
            viewConfig: {
                copy: true,
                plugins: {
                    ptype: 'treeviewdragdrop',
                    dragGroup: 'keywords'
                },
                loadMask: false
            },
            columns: [{
                xtype: 'treecolumn',
                text: 'Keyword',
                dataIndex: 'text',
                flex: 1
            }, helpCol, addCol],
            listeners: {
                afterLayout: function(tree) {
                    var store = tree.getStore();
                    //since root is invisible,mask on initial load
                    if (store.isLoading() && !tree.getRootNode().hasChildNodes()) {
                        store.myMask = new Ext.LoadMask({
                            target: tree,
                            msg: "Please wait..."
                        });
                        store.myMask.show();
                        store.on('load', function() {
                            store.myMask.destroy();
                        }, this, {
                            single: true
                        });
                    }
                }
            }
        };

        Ext.applyIf(me, {
            dmpPlugin: true,
            items: [{
                xtype: 'gridpanel',
                itemId: 'planKeywords',
                region: 'center',
                multiSelect: true,
                hideHeaders: true,
                viewConfig: {
                    stripeRows: false,
                    plugins: {
                        ptype: 'gridviewdragdrop',
                        dropGroup: 'keywords',
                        dragGroup: 'deletekeywords',
                        pluginId: 'ddkeywords'
                    },
                    listeners: {
                        beforedrop: {
                            fn: testDuplicate,
                            scope: this
                        }
                    }
                },
                store: 'PlanKeywords',
                columns: [{
                        xtype: 'templatecolumn',
                        width: 28,
                        text: '',
                        hideable: false,
                        tpl: removeTpl,
                        action: 'removekeyword',
                        listeners: {
                            click: {
                                fn: rmKeyword
                            }
                        }
                    },{
                    text: "Keyword",
                    flex: 1,
                    sortable: true,
                    dataIndex: 'text'
                }],
                title: 'Keywords',
                dockedItems: [{
                    xtype: 'toolbar',
                    dock: 'top',
                    items:[{
                        xtype: 'button',
                        glyph:  'xf100@FontAwesome',
                        text: 'Remove All',
                        action: 'removeallkeywords',
                        handler: function(btn){
                            btn.up('gridpanel').getStore().removeAll();
                        }
                    }]
                }]
            }, {
                xtype: 'tabpanel',
                //plain: true,
                flex: 1,
                title: 'Keywords',
                header: false,
                region: 'west',
                split: true,
                activeTab: 0,
                tabPosition: 'top',
                items: [keywordtree, {
                    xtype: 'gridpanel',
                    itemId: 'keywordSearch',
                    cls: 'dmp-keyword-grid',
                    title: 'Search',
                    store: 'Keywords',
                    hideHeaders: true,
                    columns: [{
                        xtype: 'gridcolumn',
                        dataIndex: 'text',
                        flex: 1,
                        text: 'Keyword',
                        renderer: function(value, metaData, record, rowIdx, colIdx, store, view) {
                            var fullname = record.get('fullname');

                            if (fullname) {
                                return '' + value + '';
                            }
                            return value;
                        }
                    }, {
                        xtype: 'gridcolumn',
                        hidden: true,
                        dataIndex: 'fullname',
                        flex: 2,
                        text: 'Full Path'
                    },//
                         helpCol,//
                         addCol//
                    ],
                    viewConfig: {
                        copy: true,
                        plugins: {
                            ptype: 'gridviewdragdrop',
                            dragGroup: 'keywords'
                        }
                    },
                    dockedItems: [{
                        xtype: 'filterbar',
                        searchStore: 'Keywords',
                        dock: 'top'
                    }, {
                        xtype: 'pagingtoolbar',
                        displayInfo: true,
                        store: 'Keywords',
                        dock: 'top'
                    }]
                }]
            }]
        });

        me.callParent(arguments);
    }
});
<commit_msg>Fix keywords UX, data store.<commit_after>/**
 * GCMD keywords.
 */

Ext.define('DMPlanner.ux.Keywords', {
    extend: 'Ext.panel.Panel',
    alias: 'widget.dmpkeywords',
    requires: [
        'Ext.ux.grid.FilterBar', //
        'Ext.grid.plugin.DragDrop', //
        'Ext.grid.column.Template', //
        'Ext.tree.plugin.TreeViewDragDrop', //
        'Ext.data.Model', //
        'Ext.data.Store', //
        'Ext.data.TreeStore', //
        'Ext.data.proxy.Rest', //
        'Ext.data.proxy.JsonP', //
        'Ext.layout.container.Border', //
        'Ext.tab.Panel', //
        'Ext.tree.Panel', //
        'Ext.LoadMask',//
        'Ext.data.writer.Json'//
    ],

    layout: {
        type: 'border'
    },
    title: 'Keywords',

    dmpSerialize: function(records) {
        var obj = [];

        Ext.each(records, function(record) {
            var s = Ext.data.writer.Json.prototype.getRecordData(record);
            //don't want to save these
            delete s.leaf;
            delete s.parentId;

            obj.push(s);
        });

        return obj;
    },

    initComponent: function() {
        var me = this, keywordtree, keywords, keywordStore,
            addTpl = '<tpl if="text && depth !== 1">

</tpl>',
            removeTpl = '<tpl if="text">

</tpl>',
            helpCol = {
                xtype: 'templatecolumn',
                width: 28,
                text: '',
                hideable: false,
                style: {cursor: 'help'},
                tpl: '<tpl if="definition">

</tpl>'
            },
            testDuplicate = function(node, data, overModel, dropPosition, dropHandlers) {
                var store = this.down('#planKeywords').getStore(),
                    draggedRecords = data.records,
                    ln = draggedRecords.length;

                for (i = 0; i < ln; i++) {
                    record = draggedRecords[i];
                    //reject duplicates
                    if(store.findExact('keywordid',record.getId()) !== -1) {
                        return false;
                    }

                    return true;
                }
            },
            addKeyword = function (view, el, idx, col){
                var store = this.down('#planKeywords').getStore(),
                    sel = view.getSelectionModel().getSelection(),
                    data = {records: sel};

                if(testDuplicate.call(this,null, data)){
                    store.add(sel);
                }
            },
            addCol = {
                xtype: 'templatecolumn',
                width: 28,
                text: '',
                hideable: false,
                tpl: addTpl,
                action: 'addkeyword',
                listeners: {
                    click: {
                        fn: addKeyword,
                        scope: this
                    }
                }
            },
            rmKeyword = function (view, el, idx, col){
                var sel = view.getSelectionModel().getSelection();
                view.getStore().remove(sel);
            };

        if (!Ext.ModelManager.getModel('KeywordNode')) {
            Ext.define('KeywordNode', {
                extend: 'Ext.data.Model',
                fields: [{
                    name: 'keywordid',
                    type: 'string'
                }, {
                    name: 'text',
                    type: 'string',
                    useNull: true
                }, {
                    name: 'definition',
                    type: 'string',
                    useNull: true
                }, {
                    name: 'fullname',
                    type: 'string',
                    useNull: true
                }],
                idProperty: 'keywordid',

                proxy: {
                    type: 'jsonp',
                    url: 'http://gcmd.herokuapp.com/keyword/tree',
                    reader: {
                        type: 'json'
                    },
                    appendId: true
                }
            });
        }

        //if (!Ext.getStore('PlanKeywords')) {
            keywordStore = Ext.create('Ext.data.Store', {
                model: 'KeywordNode',
                //storeId: 'PlanKeywords',
                //autoLoad: false,
                autoDestroy: true,
                data: me.data,
                proxy: {
                    type: 'memory',
                    reader: {
                        type: 'json',
                        root: 'data'
                    }
                },

                listeners: {
                    datachanged: function(store) {
                        var me = this,
                            recs = store.getRange(),
                            data = me.dmpSerialize(recs);

                        me.fireEvent('plugindatachanged', me, data);
                    },
                    scope: me
                }
            });
        //}

        if (!Ext.getStore('KeywordNodes')) {
            Ext.create('Ext.data.TreeStore', {
                model: 'KeywordNode',
                storeId: 'KeywordNodes',
                clearOnLoad: true,
                autoLoad: false,
                defaultRootId: ''
            }).load();
        }
        if (!Ext.getStore('Keywords')) {
            Ext.create('Ext.data.Store', {
                model: 'KeywordNode',
                storeId: 'Keywords',
                autoLoad: false,
                remoteSort: true,
                remoteFilter: true,
                sorters: {
                    property: 'text',
                    direction: 'ASC'
                },

                proxy: {
                    type: 'jsonp',
                    //url : 'http://localhost:8088/keywordlist',
                    url: 'http://gcmd.herokuapp.com/keywordlist',
                    reader: {
                        type: 'json',
                        root: 'data'
                    }
                }
            }).load();
        }

        keywordtree = {
            xtype: 'treepanel',
            itemId: 'keywordTree',
            title: 'Keyword Tree',
            rootVisible: false,
            store: 'KeywordNodes',
            multiSelect: true,
            singleExpand: true,
            cls: 'dmp-keyword-tree',
            hideHeaders: true,
            viewConfig: {
                copy: true,
                plugins: {
                    ptype: 'treeviewdragdrop',
                    dragGroup: 'keywords'
                },
                loadMask: false
            },
            columns: [{
                xtype: 'treecolumn',
                text: 'Keyword',
                dataIndex: 'text',
                flex: 1
            }, helpCol, addCol],
            listeners: {
                afterLayout: function(tree) {
                    var store = tree.getStore();
                    //since root is invisible,mask on initial load
                    if (store.isLoading() && !tree.getRootNode().hasChildNodes()) {
                        store.myMask = new Ext.LoadMask({
                            target: tree,
                            msg: "Please wait..."
                        });
                        store.myMask.show();
                        store.on('load', function() {
                            store.myMask.destroy();
                        }, this, {
                            single: true
                        });
                    }
                }
            }
        };

        Ext.applyIf(me, {
            dmpPlugin: true,
            items: [{
                xtype: 'gridpanel',
                itemId: 'planKeywords',
                region: 'center',
                multiSelect: true,
                hideHeaders: true,
                viewConfig: {
                    stripeRows: false,
                    plugins: {
                        ptype: 'gridviewdragdrop',
                        dropGroup: 'keywords',
                        dragGroup: 'deletekeywords',
                        pluginId: 'ddkeywords'
                    },
                    listeners: {
                        beforedrop: {
                            fn: testDuplicate,
                            scope: this
                        }
                    }
                },
                store: keywordStore,
                columns: [{
                        xtype: 'templatecolumn',
                        width: 28,
                        text: '',
                        hideable: false,
                        tpl: removeTpl,
                        action: 'removekeyword',
                        listeners: {
                            click: {
                                fn: rmKeyword
                            }
                        }
                    },{
                    text: "Keyword",
                    flex: 1,
                    sortable: true,
                    dataIndex: 'text'
                }],
                title: 'Keywords',
                dockedItems: [{
                    xtype: 'toolbar',
                    dock: 'top',
                    items:[{
                        xtype: 'button',
                        glyph:  'xf100@FontAwesome',
                        text: 'Remove All',
                        action: 'removeallkeywords',
                        handler: function(btn){
                            btn.up('gridpanel').getStore().removeAll();
                        }
                    }]
                }]
            }, {
                xtype: 'tabpanel',
                //plain: true,
                flex: 1,
                title: 'Keywords',
                header: false,
                region: 'west',
                split: true,
                activeTab: 0,
                tabPosition: 'top',
                items: [keywordtree, {
                    xtype: 'gridpanel',
                    itemId: 'keywordSearch',
                    cls: 'dmp-keyword-grid',
                    title: 'Search',
                    store: 'Keywords',
                    hideHeaders: true,
                    columns: [{
                        xtype: 'gridcolumn',
                        dataIndex: 'text',
                        flex: 1,
                        text: 'Keyword',
                        renderer: function(value, metaData, record, rowIdx, colIdx, store, view) {
                            var fullname = record.get('fullname');

                            if (fullname) {
                                return '' + value + '';
                            }
                            return value;
                        }
                    }, {
                        xtype: 'gridcolumn',
                        hidden: true,
                        dataIndex: 'fullname',
                        flex: 2,
                        text: 'Full Path'
                    },//
                         helpCol,//
                         addCol//
                    ],
                    viewConfig: {
                        copy: true,
                        plugins: {
                            ptype: 'gridviewdragdrop',
                            dragGroup: 'keywords'
                        }
                    },
                    dockedItems: [{
                        xtype: 'filterbar',
                        searchStore: 'Keywords',
                        dock: 'top'
                    }, {
                        xtype: 'pagingtoolbar',
                        displayInfo: true,
                        store: 'Keywords',
                        dock: 'top'
                    }]
                }]
            }]
        });

        me.callParent(arguments);
    }
});
<|endoftext|>


<commit_before>/**
 UUID-js : A js library to generate and parse UUIDs,TimeUUIDs and generate TimeUUID based on Data for range selections
 http://www.ietf.org/rfc/rfc4122.txt
 **/

UUIDjs = function() { };

UUIDjs.maxFromBits = function( bits )
{
  return Math.pow(2,bits);
};

UUIDjs.limitUI04 = UUIDjs.maxFromBits( 4 );
UUIDjs.limitUI06 = UUIDjs.maxFromBits( 6 );
UUIDjs.limitUI08 = UUIDjs.maxFromBits( 8 );
UUIDjs.limitUI12 = UUIDjs.maxFromBits( 12 );
UUIDjs.limitUI14 = UUIDjs.maxFromBits( 14 );
UUIDjs.limitUI16 = UUIDjs.maxFromBits( 16 );
UUIDjs.limitUI32 = UUIDjs.maxFromBits( 32 );

UUIDjs.randomUI04 = function() { return Math.round(Math.random() * UUIDjs.limitUI04); };
UUIDjs.randomUI06 = function() { return Math.round(Math.random() * UUIDjs.limitUI06); };
UUIDjs.randomUI08 = function() { return Math.round(Math.random() * UUIDjs.limitUI08); };
UUIDjs.randomUI12 = function() { return Math.round(Math.random() * UUIDjs.limitUI12); };
UUIDjs.randomUI14 = function() { return Math.round(Math.random() * UUIDjs.limitUI14); };
UUIDjs.randomUI16 = function() { return Math.round(Math.random() * UUIDjs.limitUI16); };
UUIDjs.randomUI32 = function() { return Math.round(Math.random() * UUIDjs.limitUI32); };
UUIDjs.randomUI40 = function() { return (0 | Math.random() * (1 << 30)) + (0 | Math.random() * (1 << 40 - 30)) * (1 << 30); };
UUIDjs.randomUI48 = function() { return (0 | Math.random() * (1 << 30)) + (0 | Math.random() * (1 << 48 - 30)) * (1 << 30); };

UUIDjs.paddedString = function( string, length, z )
{
  string = String(string);
  z = (!z)?"0":z;
  var i = length - string.length;
  for (; i > 0; i >>>= 1, z += z) { if (i & 1) { string = z + string; } }
  return string;
};

UUIDjs.prototype.fromParts = function( timeLow, timeMid, timeHiAndVersion, clockSeqHiAndReserved, clockSeqLow, node )
{
  this.version = (timeHiAndVersion >> 12) & 0xF;
  this.hex = UUIDjs.paddedString( timeLow.toString(16), 8 )
             + '-'
             + UUIDjs.paddedString( timeMid.toString(16), 4 )
             + '-'
             + UUIDjs.paddedString( timeHiAndVersion.toString(16), 4 )
             + '-'
             + UUIDjs.paddedString( clockSeqHiAndReserved.toString(16), 2 )
             + UUIDjs.paddedString( clockSeqLow.toString(16), 2 )
             + '-'
             + UUIDjs.paddedString( node.toString(16), 12 );
  return this;
};

UUIDjs.prototype.toString = function() { return this.hex; };
UUIDjs.prototype.toURN = function() { return 'urn:uuid:' + this.hex; };

UUIDjs.prototype.toBytes = function()
{
  var parts = this.hex.split('-');
  var ints = [];
  var intPos = 0;
  for (var i = 0; i < parts.length; i++) {
    for (var j = 0; j < parts[i].length; j+=2) {
      ints[intPos++] = parseInt(parts[i].substr(j, 2), 16);
    }
  }
  return ints;
};

UUIDjs.prototype.equals = function(uuid)
{
  if (!(uuid instanceof UUID)) { return false; }
  if (this.hex !== uuid.hex) return false;
  return true;
};

UUIDjs.new = function()
{
  return new UUIDjs().fromParts(
    UUIDjs.randomUI32(),
    UUIDjs.randomUI16(),
    0x4000 | UUIDjs.randomUI12(),
    0x80   | UUIDjs.randomUI06(),
    UUIDjs.randomUI08(),
    UUIDjs.randomUI48()
  );
};

UUIDjs.getTimeFieldValues = function(time)
{
  var ts = time - Date.UTC(1582, 9, 15);
  var hm = ((ts / 0x100000000) * 10000) & 0xFFFFFFF;
  return { low: ((ts & 0xFFFFFFF) * 10000) % 0x100000000,
            mid: hm & 0xFFFF, hi: hm >>> 16, timestamp: ts };
};

UUIDjs.newTS = function()
{
  var now = new Date().getTime();
  var sequence = UUIDjs.randomUI14();
  var node = (UUIDjs.randomUI08() | 1) * 0x10000000000 + UUIDjs.randomUI40();
  var tick = UUIDjs.randomUI04();
  var timestamp = 0;
  var timestampRatio = 1/4;

  if (now != timestamp)
  {
    if (now < timestamp) { sequence++; }
    timestamp = now;
    tick = UUIDjs.randomUI04();
  } else if (Math.random() < timestampRatio && tick < 9984) { tick += 1 + UUIDjs.randomUI04();
  } else { sequence++; }

  var tf = UUIDjs.getTimeFieldValues(timestamp);
  var tl = tf.low + tick;
  var thav = (tf.hi & 0xFFF) | 0x1000;

  sequence &= 0x3FFF;
  var cshar = (sequence >>> 8) | 0x80;
  var csl = sequence & 0xFF;

  return new UUIDjs().fromParts(tl, tf.mid, thav, cshar, csl, node);
};

UUIDjs.fromTime = function( time, last )
{
  last = (!last)?false:last;
  var tf = UUIDjs.getTimeFieldValues( time );
  var tl = tf.low;
  var thav = (tf.hi & 0xFFF) | 0x1000;  // set version '0001'
  if (last == false) return new UUIDjs().fromParts(tl,tf.mid,thav, 0, 0, 0);
  else return new UUIDjs().fromParts(tl,tf.mid,thav, 0x80 | UUIDjs.limitUI06, UUIDjs.limitUI08, UUIDjs.limitUI48 );
};

UUIDjs.firstUUIDForTime = function(time) { return UUIDjs.fromTime(time, false); };
UUIDjs.lastUUIDForTime = function(time) { return UUIDjs.fromTime(time, true); };

UUIDjs.fromURN = function(strId)
{
  var r, p = /^(?:urn:uuid:|\{)?([0-9a-f]{8})-([0-9a-f]{4})-([0-9a-f]{4})-([0-9a-f]{2})([0-9a-f]{2})-([0-9a-f]{12})(?:\})?$/i;
  if (r = p.exec(strId)) {
    return new UUIDjs().fromParts(parseInt(r[1], 16), parseInt(r[2], 16),
                            parseInt(r[3], 16), parseInt(r[4], 16),
                            parseInt(r[5], 16), parseInt(r[6], 16));
  }
  return null;
};

UUIDjs.fromBytes = function(ints)
{
  if (ints.length < 5) return null;
  var str = '';
  var pos = 0;
  var parts = [4, 2, 2, 2, 6];
  for (var i = 0; i < parts.length; i++) {
    for (var j = 0; j < parts[i]; j++) {
      var octet = ints[pos++].toString(16);
      if (octet.length == 1) {
        octet = '0' + octet;
      }
      str += octet;
    }
    if (parts[i] !== 6) {
      str += '-';
    }
  }
  return UUIDjs.fromURN( str );
};

UUIDjs.fromBinary = function(binary)
{
  var ints = [];
  for (var i = 0; i < binary.length; i++) {
    ints[i] = binary.charCodeAt(i);
    if (ints[i] > 255 || ints[i] < 0) {
      throw new Error('Unexpected byte in binary data.');
    }
  }
  return UUIDjs.fromBytes( ints );
};

module.exports = UUIDjs;
<commit_msg>Remove trailing whitespaces<commit_after>/**
 UUID-js : A js library to generate and parse UUIDs,TimeUUIDs and generate TimeUUID based on Data for range selections
 http://www.ietf.org/rfc/rfc4122.txt
 **/

UUIDjs = function() { };

UUIDjs.maxFromBits = function( bits )
{
  return Math.pow(2,bits);
};

UUIDjs.limitUI04 = UUIDjs.maxFromBits( 4 );
UUIDjs.limitUI06 = UUIDjs.maxFromBits( 6 );
UUIDjs.limitUI08 = UUIDjs.maxFromBits( 8 );
UUIDjs.limitUI12 = UUIDjs.maxFromBits( 12 );
UUIDjs.limitUI14 = UUIDjs.maxFromBits( 14 );
UUIDjs.limitUI16 = UUIDjs.maxFromBits( 16 );
UUIDjs.limitUI32 = UUIDjs.maxFromBits( 32 );

UUIDjs.randomUI04 = function() { return Math.round(Math.random() * UUIDjs.limitUI04); };
UUIDjs.randomUI06 = function() { return Math.round(Math.random() * UUIDjs.limitUI06); };
UUIDjs.randomUI08 = function() { return Math.round(Math.random() * UUIDjs.limitUI08); };
UUIDjs.randomUI12 = function() { return Math.round(Math.random() * UUIDjs.limitUI12); };
UUIDjs.randomUI14 = function() { return Math.round(Math.random() * UUIDjs.limitUI14); };
UUIDjs.randomUI16 = function() { return Math.round(Math.random() * UUIDjs.limitUI16); };
UUIDjs.randomUI32 = function() { return Math.round(Math.random() * UUIDjs.limitUI32); };
UUIDjs.randomUI40 = function() { return (0 | Math.random() * (1 << 30)) + (0 | Math.random() * (1 << 40 - 30)) * (1 << 30); };
UUIDjs.randomUI48 = function() { return (0 | Math.random() * (1 << 30)) + (0 | Math.random() * (1 << 48 - 30)) * (1 << 30); };

UUIDjs.paddedString = function( string, length, z )
{
  string = String(string);
  z = (!z)?"0":z;
  var i = length - string.length;
  for (; i > 0; i >>>= 1, z += z) { if (i & 1) { string = z + string; } }
  return string;
};

UUIDjs.prototype.fromParts = function( timeLow, timeMid, timeHiAndVersion, clockSeqHiAndReserved, clockSeqLow, node )
{
  this.version = (timeHiAndVersion >> 12) & 0xF;
  this.hex = UUIDjs.paddedString( timeLow.toString(16), 8 )
             + '-'
             + UUIDjs.paddedString( timeMid.toString(16), 4 )
             + '-'
             + UUIDjs.paddedString( timeHiAndVersion.toString(16), 4 )
             + '-'
             + UUIDjs.paddedString( clockSeqHiAndReserved.toString(16), 2 )
             + UUIDjs.paddedString( clockSeqLow.toString(16), 2 )
             + '-'
             + UUIDjs.paddedString( node.toString(16), 12 );
  return this;
};

UUIDjs.prototype.toString = function() { return this.hex; };
UUIDjs.prototype.toURN = function() { return 'urn:uuid:' + this.hex; };

UUIDjs.prototype.toBytes = function()
{
  var parts = this.hex.split('-');
  var ints = [];
  var intPos = 0;
  for (var i = 0; i < parts.length; i++) {
    for (var j = 0; j < parts[i].length; j+=2) {
      ints[intPos++] = parseInt(parts[i].substr(j, 2), 16);
    }
  }
  return ints;
};

UUIDjs.prototype.equals = function(uuid)
{
  if (!(uuid instanceof UUID)) { return false; }
  if (this.hex !== uuid.hex) return false;
  return true;
};

UUIDjs.new = function()
{
  return new UUIDjs().fromParts(
    UUIDjs.randomUI32(),
    UUIDjs.randomUI16(),
    0x4000 | UUIDjs.randomUI12(),
    0x80   | UUIDjs.randomUI06(),
    UUIDjs.randomUI08(),
    UUIDjs.randomUI48()
  );
};

UUIDjs.getTimeFieldValues = function(time)
{
  var ts = time - Date.UTC(1582, 9, 15);
  var hm = ((ts / 0x100000000) * 10000) & 0xFFFFFFF;
  return { low: ((ts & 0xFFFFFFF) * 10000) % 0x100000000,
            mid: hm & 0xFFFF, hi: hm >>> 16, timestamp: ts };
};

UUIDjs.newTS = function()
{
  var now = new Date().getTime();
  var sequence = UUIDjs.randomUI14();
  var node = (UUIDjs.randomUI08() | 1) * 0x10000000000 + UUIDjs.randomUI40();
  var tick = UUIDjs.randomUI04();
  var timestamp = 0;
  var timestampRatio = 1/4;

  if (now != timestamp)
  {
    if (now < timestamp) { sequence++; }
    timestamp = now;
    tick = UUIDjs.randomUI04();
  } else if (Math.random() < timestampRatio && tick < 9984) { tick += 1 + UUIDjs.randomUI04();
  } else { sequence++; }

  var tf = UUIDjs.getTimeFieldValues(timestamp);
  var tl = tf.low + tick;
  var thav = (tf.hi & 0xFFF) | 0x1000;

  sequence &= 0x3FFF;
  var cshar = (sequence >>> 8) | 0x80;
  var csl = sequence & 0xFF;

  return new UUIDjs().fromParts(tl, tf.mid, thav, cshar, csl, node);
};

UUIDjs.fromTime = function( time, last )
{
  last = (!last)?false:last;
  var tf = UUIDjs.getTimeFieldValues( time );
  var tl = tf.low;
  var thav = (tf.hi & 0xFFF) | 0x1000;  // set version '0001'
  if (last == false) return new UUIDjs().fromParts(tl,tf.mid,thav, 0, 0, 0);
  else return new UUIDjs().fromParts(tl,tf.mid,thav, 0x80 | UUIDjs.limitUI06, UUIDjs.limitUI08, UUIDjs.limitUI48 );
};

UUIDjs.firstUUIDForTime = function(time) { return UUIDjs.fromTime(time, false); };
UUIDjs.lastUUIDForTime = function(time) { return UUIDjs.fromTime(time, true); };

UUIDjs.fromURN = function(strId)
{
  var r, p = /^(?:urn:uuid:|\{)?([0-9a-f]{8})-([0-9a-f]{4})-([0-9a-f]{4})-([0-9a-f]{2})([0-9a-f]{2})-([0-9a-f]{12})(?:\})?$/i;
  if (r = p.exec(strId)) {
    return new UUIDjs().fromParts(parseInt(r[1], 16), parseInt(r[2], 16),
                            parseInt(r[3], 16), parseInt(r[4], 16),
                            parseInt(r[5], 16), parseInt(r[6], 16));
  }
  return null;
};

UUIDjs.fromBytes = function(ints)
{
  if (ints.length < 5) return null;
  var str = '';
  var pos = 0;
  var parts = [4, 2, 2, 2, 6];
  for (var i = 0; i < parts.length; i++) {
    for (var j = 0; j < parts[i]; j++) {
      var octet = ints[pos++].toString(16);
      if (octet.length == 1) {
        octet = '0' + octet;
      }
      str += octet;
    }
    if (parts[i] !== 6) {
      str += '-';
    }
  }
  return UUIDjs.fromURN( str );
};

UUIDjs.fromBinary = function(binary)
{
  var ints = [];
  for (var i = 0; i < binary.length; i++) {
    ints[i] = binary.charCodeAt(i);
    if (ints[i] > 255 || ints[i] < 0) {
      throw new Error('Unexpected byte in binary data.');
    }
  }
  return UUIDjs.fromBytes( ints );
};

module.exports = UUIDjs;
<|endoftext|>


<commit_before>'use strict';
console.log('view1.js loading');
angular.module('myApp.view1', ['ngRoute'])

    .config(['$routeProvider', function ($routeProvider) {
        $routeProvider.when('/view1', {
            templateUrl: 'view1/view1.html',
            controller: 'View1Ctrl'
        });
    }])

    .controller('View1Ctrl', ['$scope', '$location', 'wikiSvc', 'sharedProperties', function ($scope, $location, wikiSvc, sharedProperties) {

        $scope.searchText = '';

        var getResults = function (value) {
            if (value == '' || value === undefined) {
                $scope.results = [];
            } else {
                wikiSvc.query(value).then(function(results){
                    $scope.results = results.data.query.pages;
                    console.log("$scope: ");
                    console.log($scope.results);
                    //$scope.$apply();
                });
            }

        };

        /*
        $scope.$watch('searchText', function (newValue, oldValue) {
           if (newValue !== oldValue) sharedProperties.setSearchText(newValue);
        });*/

        $scope.$watch(
            function () {
                return sharedProperties.getSearchText();
            },
            function (newValue, oldValue) {
                if (newValue !== oldValue) getResults(newValue);
            }

        );
    }]);
<commit_msg>cleaned up old code<commit_after>'use strict';
console.log('view1.js loading');
angular.module('myApp.view1', ['ngRoute'])

    .config(['$routeProvider', function ($routeProvider) {
        $routeProvider.when('/view1', {
            templateUrl: 'view1/view1.html',
            controller: 'View1Ctrl'
        });
    }])

    .controller('View1Ctrl', ['$scope', '$location', 'wikiSvc', 'sharedProperties', function ($scope, $location, wikiSvc, sharedProperties) {

        $scope.searchText = '';

        var getResults = function (value) {
            if (value == '' || value === undefined) {
                $scope.results = [];
            } else {
                wikiSvc.query(value).then(function(results){
                    $scope.results = results.data.query.pages;
                    console.log("$scope: ");
                    console.log($scope.results);
                });
            }

        };
        $scope.$watch(
            function () {
                return sharedProperties.getSearchText();
            },
            function (newValue, oldValue) {
                if (newValue !== oldValue) getResults(newValue);
            }

        );
    }]);
<|endoftext|>


<commit_before>/* global $:false */
(function () {
  'use strict';

  angular
    .module('meetings')
    .controller('GenerateScheduleController', GenerateScheduleController);

  GenerateScheduleController.$inject = ['$scope', 'MeetingsService', 'meetingResolve', 'listFacilitiesResolve', 'listApplicationsResolve', 'listCompaniesResolve', 'Authentication', '$timeout'];

  function GenerateScheduleController($scope, MeetingsService, meeting, facilities, applications, companies, Authentication, $timeout) {
    var vm = this;

    //vm.meetings = MeetingsService.query();
    vm.facilities = facilities;
    vm.applications = applications;
    vm.companies = companies;

    // Examples of variables that are useful;
    vm.startDate = new Date('----', '--', '--', '--', '--', '--');
    vm.endDate = new Date('----', '--', '--', '--', '--', '--');
    vm.startHours = new Date('----', '--', '--', '--', '--', '--');
    vm.endHours = new Date('----', '--', '--', '--', '--', '--');
    vm.meetingTimeLength = '';
    vm.lunchStart = new Date('----', '--', '--', '--', '--', '--');
    vm.lunchEnd = new Date('----', '--', '--', '--', '--', '--');
    vm.chosenFacilities = [];

    // Chosen facilities?

    // Create meeting.
    var createMeeting = function(facility, date, endDate) {
      MeetingsService.post({
        facility: facility,
        date: date.toISOString(),
        endDate: endDate.toISOString()
      });
    };

    // Company dates.
    var startBeforeOrAtEndDate = function(start, end) {
      if(start.getFullYear() < end.getFullYear()){
        return true;
      } else if (start.getMonth() < end.getMonth() && start.getFullYear() === end.getFullYear()){
        return true;
      } else if (start.getDate() < end.getDate() && start.getMonth() === end.getMonth() && start.getFullYear() === end.getFullYear()) {
        return true;
      } else if (start.getDate() === end.getDate() && start.getMonth() === end.getMonth() && start.getFullYear() === end.getFullYear()) {
        return true;
      } else {
        return false;
      }
    };

    // Company time.
    var startBeforeOrAtEndTime = function(start, end) { //testa med denna ändring!!
      if(start.getHours() < end.getHours()){
        return true;
      } else if (start.getMinutes() <= end.getMinutes() && start.getHours() === end.getHours()) {
        return true;
      } else if (start.getMinutes() === end.getMinutes() && start.getHours() === end.getHours()) {
        return true;
      } else {
        return false;
      }
    };

    // Company time reverse.
    var startAfterOrAtEndTime = function(start, end) {
      if(start.getHours() > end.getHours()){
        return true;
      } else if (start.getMinutes() >= end.getMinutes() && start.getHours() === end.getHours()) {
        return true;
      } else if (start.getMinutes() === end.getMinutes() && start.getHours() === end.getHours()) {
        return true;
      } else {
        return false;
      }
    };

    $scope.generateSchedule = function(){
      //TODO: Implement

      /*
// Ta bort studentens valda företag som inte vill träffa studenten.
// För varje gång ett företag bokat möte med studenten, ta bort företaget
// från studentens lista. När ett möte är bokat och studenten inte har fler
// företag att träffa, ta bort studenten från applicationsList.

      // Gör om alla tider till antal minuter sen kl 00:00...
Gör om studentens tillgängliga tider till perioder. Ex: 9-12 istället för 9,10,
11,12. Och helst då i minuter (ex: 540 - 720)

Ha en funktion för att dela upp en period i två, där man anger början och slut
av "pausen"

Skriv en funktion där man om man anger: application, tid i minut och dag
så ska man få ut antal minuter kvar studenter är tillgänglig den dagen. (alltså
från tid i minut till dagens slut.)

Börja med företagen för dag ett. Iterera igenom dem, där företag som enbart
har kontaktsamtal dag ett är först i listan, annars random, eller kanske
först de företag som har längst möten? Så att de små sedan kan fylla i hålen?.

Efter varje iteration,
ta bort företag som inte har studenter kvar de vill träffa, iterera tills
listan av företag är tom.
ForEach företag:
  Bland studenterFöretagetVillTräffa sortera efter studenter med minst antal minuter
  som den är tillgänglig den dagen. Ta första studenten som är tillgänglig att
  ses på currentTime. Boka in den studenten på ett möte från currentTime till
  currentTime + företagets meetingLength. Efter det addera meetingLength på
  currentTime.

      */

    };

    $scope.createMeetings = function() {
      if(!!vm.startDate && !!vm.endDate && !!vm.startHours && !!vm.endHours && !!vm.lunchStart && !!vm.lunchEnd && vm.chosenFacilities !== 'undefined' && vm.meetingTimeLength !== '' && vm.chosenFacilities.length !== 0) {
        console.log('Alla fält är ifyllda');

        var meetingDate = new Date(vm.startDate.getFullYear(), vm.startDate.getMonth(), vm.startDate.getDate(), vm.startHours.getHours(), vm.startHours.getMinutes());
        var meetingEnd = new Date(meetingDate.getFullYear(), meetingDate.getMonth(), meetingDate.getDate(), meetingDate.getHours(), meetingDate.getMinutes() + vm.meetingTimeLength);

        while(startBeforeOrAtEndDate(meetingDate, vm.endDate)){

          while(startBeforeOrAtEndTime(meetingEnd, vm.endHours)){

            if(!(startBeforeOrAtEndTime(meetingEnd, vm.lunchStart) ||
              startAfterOrAtEndTime(meetingDate, vm.lunchEnd))) {
              meetingDate.setHours(vm.lunchEnd.getHours());
              meetingDate.setMinutes(vm.lunchEnd.getMinutes());

              meetingEnd.setHours(vm.lunchEnd.getHours());
              meetingEnd.setMinutes(vm.lunchEnd.getMinutes() + vm.meetingTimeLength);
            }

            for (var i=0; i < vm.chosenFacilities.length; i++){
              createMeeting(vm.chosenFacilities[i], meetingDate, meetingEnd);
            }

            //updating the time to the next meeting time
            meetingDate.setMinutes(meetingDate.getMinutes() + vm.meetingTimeLength);
            meetingEnd.setMinutes(meetingDate.getMinutes() + vm.meetingTimeLength);
          }

          //updating the date to the next day
          meetingDate.setDate(meetingDate.getDate() + 1);
          //reseting the time of the next day
          meetingDate.setHours(vm.startHours.getHours());
          meetingDate.setMinutes(vm.startHours.getMinutes());

          //meeting end
          meetingEnd = new Date(meetingDate.getFullYear(), meetingDate.getMonth(), meetingDate.getDate(), meetingDate.getHours(), meetingDate.getMinutes() + vm.meetingTimeLength);
        }

      } else {
        console.log('Alla fält är inte ifyllda!');
      }
    };
  }
})();
<commit_msg>implement almost all of the algoritm<commit_after>/* global $:false */
(function () {
  'use strict';

  angular
    .module('meetings')
    .controller('GenerateScheduleController', GenerateScheduleController);

  GenerateScheduleController.$inject = ['$scope', 'MeetingsService', 'meetingResolve', 'listFacilitiesResolve', 'listApplicationsResolve', 'listCompaniesResolve', 'Authentication', '$timeout'];

  function GenerateScheduleController($scope, MeetingsService, meeting, facilities, applications, companies, Authentication, $timeout) {
    var vm = this;

    // Examples of variables that are useful;
    vm.startDate = new Date('----', '--', '--', '--', '--', '--');
    vm.endDate = new Date('----', '--', '--', '--', '--', '--');
    vm.startHours = new Date('----', '--', '--', '--', '--', '--');
    vm.endHours = new Date('----', '--', '--', '--', '--', '--');
    vm.meetingTimeLength = '';
    vm.lunchStart = new Date('----', '--', '--', '--', '--', '--');
    vm.lunchEnd = new Date('----', '--', '--', '--', '--', '--');
    vm.chosenFacilities = [];

    // Chosen facilities?

    // Create meeting.
    var createMeeting = function(facility, date, endDate) {
      MeetingsService.post({
        facility: facility,
        date: date.toISOString(),
        endDate: endDate.toISOString()
      });
    };

    // Company dates.
    var startBeforeOrAtEndDate = function(start, end) {
      if(start.getFullYear() < end.getFullYear()){
        return true;
      } else if (start.getMonth() < end.getMonth() && start.getFullYear() === end.getFullYear()){
        return true;
      } else if (start.getDate() < end.getDate() && start.getMonth() === end.getMonth() && start.getFullYear() === end.getFullYear()) {
        return true;
      } else if (start.getDate() === end.getDate() && start.getMonth() === end.getMonth() && start.getFullYear() === end.getFullYear()) {
        return true;
      } else {
        return false;
      }
    };

    // Company time.
    var startBeforeOrAtEndTime = function(start, end) { //testa med denna ändring!!
      if(start.getHours() < end.getHours()){
        return true;
      } else if (start.getMinutes() <= end.getMinutes() && start.getHours() === end.getHours()) {
        return true;
      } else if (start.getMinutes() === end.getMinutes() && start.getHours() === end.getHours()) {
        return true;
      } else {
        return false;
      }
    };

    // Company time reverse.
    var startAfterOrAtEndTime = function(start, end) {
      if(start.getHours() > end.getHours()){
        return true;
      } else if (start.getMinutes() >= end.getMinutes() && start.getHours() === end.getHours()) {
        return true;
      } else if (start.getMinutes() === end.getMinutes() && start.getHours() === end.getHours()) {
        return true;
      } else {
        return false;
      }
    };

    // Fix lists.
    //vm.meetings = MeetingsService.query();
    vm.facilities = facilities;
    vm.applications = applications;
    vm.companies = companies;

    // Get active Companies
    function isActive(c){ return c.active;  }
    vm.activeCompanies = vm.companies.filter(isActive);

    // Get Companies that have student session on wednesdays, sorted by first
    // those with only wednesday, then by longest meetingLength
    function isWed(c) { return c.wednesday; }
    vm.wedCompanies = vm.activeCompanies.filter(isWed);
    function onlyWedFirstThenMeetingLength(c1, c2) {
      return (c2.wednesday + c2.thursday) - (c1.wednesday + c1.thursday) || c1.meetingLength - c2.meetingLength;
    }
    vm.wedCompanies = vm.wedCompanies.sort(onlyWedFirstThenMeetingLength);

    // Get Companies that have student session on thursday, sorted by first
    // those with only thursday
    function isThur(c) { return c.thursday; }
    vm.thurCompanies = vm.activeCompanies.filter(isThur);
    function onlyThurFirstThenMeetingLength(c1, c2) {
      return (c2.wednesday + c2.thursday) - (c1.wednesday + c1.thursday) || c1.meetingLength - c2.meetingLength;
    }
    vm.thurCompanies = vm.thurCompanies.sort(onlyThurFirstThenMeetingLength);

    // Create periodList on each Application.
    // Sort PeriodList timewise
    function sortByStart(period1, period2){ return period1.start > period2.start; }

    // Merge colliding periods in list
    function mergePeriodList(periodList){
      periodList = periodList.sort(sortByStart);
      var newList = [];
      // Check if endtime <= any other starttime
      function endTimeCollidesWithStartTime(period1, index1){
        // Get all periods that collide
        function filterStartBeforeTime(period){ return period.start <= period1.end; }
        var collidingPeriods = periodList.filter(filterStartBeforeTime);
        // Nbr colliding periods
        var nbrCollidingPeriods = collidingPeriods.length;
        if(nbrCollidingPeriods > 0){ // Merge periods in a new one
          newList.push({ start: period1.start, end: collidingPeriods[nbrCollidingPeriods-1].end });
        } else { // No collision, just push.
          newList.push(period1);
        }
      }
      periodList.forEach(endTimeCollidesWithStartTime);
      // Update periodlist with merged.
      return newList;
    }
    // Create a period (in minutes) from a time-object.
    function timesToPeriodList(times) {
      var start = times.hour * 60;
      return { start: start, end: start + 60 };
    }
    function isTimesWed(t) { return t.day === 'wed'; }
    function isTimesThur(t) { return t.day === 'thur'; }
    function splitTimesToDayPeriodLists(application){
      application.wedPeriodList = application.times.filter(isTimesWed).map(timesToPeriodList);
      application.thurPeriodList = application.times.filter(isTimesThur).map(timesToPeriodList);

      // Merge periods that collide. (ex: 540-600 & 600-660 minutes);
      application.wedPeriodList = mergePeriodList(application.wedPeriodList);
      application.thurPeriodList = mergePeriodList(application.thurPeriodList);
    }
    vm.applications.forEach(splitTimesToDayPeriodLists);

    // Calculate time left the student is available
    // from currentTime and forward.
    function timeLeftToday(application, currentTime, day){
      // Reduce function, checks against currentTime.
      function sumTimeLeft(previousValue, period){
        var diff = period.end - Math.max(period.start, currentTime);
        return previousValue + Math.max(0, diff);
      }
      if(day === 'wed'){
        return application.wedPeriodList.reduce(sumTimeLeft, 0);
      } else {
        return application.thurPeriodList.reduce(sumTimeLeft, 0);
      }
    }
    function timeLeftAvailableWednesday(application, currentTime){
      return timeLeftToday(application, currentTime, 'wed');
    }
    function timeLeftAvailableThursday(application, currentTime){
      return timeLeftToday(application, currentTime, 'thur');
    }

    // Remove students choice of company if choice not mutual.
    function removeNonMutualChoice(application){
      function companiesWhomLikeMe(company){
        // Get company by Name
        function filterOnCompanyName(c){ return c.name === company.name; }
        var comp1 = vm.companies.filter(filterOnCompanyName)[0];
        // Has company selected this application?
        function likesMe(student){ return student === application._id; }
        return comp1.chosenStudents.filter(likesMe).length > 0;
      }
      application.companies = application.companies.filter(companiesWhomLikeMe);
    }
    vm.applications.forEach(removeNonMutualChoice);

    // Check if periodList contains given period.
    function isAvailable(periodList, start, end){
      function isStartEndWithinPeriod(period){
        return period.start <= start && period.end >= end ? 1 : -1;
      }
      return periodList.filter(isStartEndWithinPeriod).length > 0;
    }

    // Iterate periodList and add pause to colliding period
    function addPause(periodList, start, end){
      function addPauseToPeriod(period){
        if(period.start <= start && period.end >= end){
          var newPeriod1 = { start: period.start, end: start};
          var newPeriod2 = { start: end, end: period.end};
          if(newPeriod1.start !== newPeriod1.end){
            period = newPeriod1;
          }
          if(newPeriod2.start !== newPeriod2.end){
            periodList.push(newPeriod2);
            periodList = periodList.sort(sortByStart);
          }
        }
      }
      periodList.forEach(addPauseToPeriod);
    }

    function bookMeeting(student, company, start, end){
      // Create meeting-object.
      // TODO: Implement

      // Remove period from Student.
      function bookPeriod(a){
        if(a._id === student._id){
          // TODO: Implement
          addPause(a.periodList, start, end);
        }
      }
      vm.applications.forEach(removeCompany);

      // Remove company from the students list.
      function removeCompany(a){
        function filterIsNotCompany(c){ return c._id !== company._id; }
        if(a._id === student._id){
          a.companies = a.companies.filter(filterIsNotCompany);
        }
      }
      vm.applications.forEach(removeCompany);

      // Remove student from the companies list.
      function notBooked(s){ return s._id === student._id; }
      company.chosenStudents = company.chosenStudents.filter(notBooked);
    }

    function generateSchedule(companies, applications, startTime, timeLeftAvailableToday){
      if(companies.length === 0){
        return; // Do nothing
      }

      // Add startTime as currentTime to all companies.
      function addStartTime(company){ company.currTime = startTime; }
      companies.forEach(addStartTime);

      // For each company, book a student from applications.
      function bookStudent(company){
        // Get latest application data from applicationList
        function mapIdToApplication(id){
          function idMatch (a) { return a._id === id; }
          var appl =  applications.filter(idMatch)[0];
          // Set timeleft available today.
          appl.timeLeft = timeLeftAvailableToday(appl, company.currTime);
        }
        company.students = company.chosenStudents.map(mapIdToApplication);

        // Sort company.students by timeLeft
        function sortByTimeLeft(a1, a2){
          return a1.timeLeft < a2.timeLeft;
        }
        company.students.sort(sortByTimeLeft);

        function bookIfAvailable(students, start, end){
          if(students.length === 0){
            return null; // Do nothing.
          }
          var isFree = isAvailable(students[0].periodList, start, end);
          if(isFree){
            bookMeeting(students[0], company, start, end);
            return students[0];
          } else {
            return bookIfAvailable(students.slice(1), start, end);
          }
        }
        var start = company.currentTime;
        var end = start + company.meetingLength;
        var bookedStudent = bookIfAvailable(company.students, start, end);

      }
      companies.forEach(bookStudent);
    }

    /*
ForEach företag:
  Bland studenterFöretagetVillTräffa sortera efter studenter med minst antal minuter
  som den är tillgänglig den dagen. Ta första studenten som är tillgänglig att
  ses på currentTime. Boka in den studenten på ett möte från currentTime till
  currentTime + företagets meetingLength. Efter det addera meetingLength på
  currentTime.
Efter varje iteration,
ta bort företag som inte har studenter kvar de vill träffa, iterera tills
listan av företag är tom.

// Ta bort studentens valda företag som inte vill träffa studenten.
// För varje gång ett företag bokat möte med studenten, ta bort företaget
// från studentens lista. När ett möte är bokat och studenten inte har fler
// företag att träffa, ta bort studenten från applicationsList.

    // Gör om alla tider till antal minuter sen kl 00:00...
Gör om studentens tillgängliga tider till perioder. Ex: 9-12 istället för 9,10,
11,12. Och helst då i minuter (ex: 540 - 720)

Ha en funktion för att dela upp en period i två, där man anger början och slut
av "pausen"

Skriv en funktion där man om man anger: application, tid i minut och dag
så ska man få ut antal minuter kvar studenter är tillgänglig den dagen. (alltså
från tid i minut till dagens slut.)

Börja med företagen för dag ett. Iterera igenom dem, där företag som enbart
har kontaktsamtal dag ett är först i listan, annars random, eller kanske
först de företag som har längst möten? Så att de små sedan kan fylla i hålen?.

    */
    function generateWednesdaySchedule(){
      // TODO: implement
      var wedApplications = vm.applications.;
      generateSchedule(vm.wedCompanies, vm.applications, 9 * 60, timeLeftAvailableWednesday); // Get time from setting?
    }
    function generateThursdaySchedule(){
      generateSchedule(vm.thurCompanies, vm.applications, 10 * 60, timeLeftAvailableThursday); // Get time from setting?
    }

    function generateBothSchedule(){
      generateWednesdaySchedule();
      generateThursdaySchedule();
    }
    $scope.generateSchedule = generateBothSchedule;

    $scope.createMeetings = function() {
      if(!!vm.startDate && !!vm.endDate && !!vm.startHours && !!vm.endHours && !!vm.lunchStart && !!vm.lunchEnd && vm.chosenFacilities !== 'undefined' && vm.meetingTimeLength !== '' && vm.chosenFacilities.length !== 0) {
        console.log('Alla fält är ifyllda');

        var meetingDate = new Date(vm.startDate.getFullYear(), vm.startDate.getMonth(), vm.startDate.getDate(), vm.startHours.getHours(), vm.startHours.getMinutes());
        var meetingEnd = new Date(meetingDate.getFullYear(), meetingDate.getMonth(), meetingDate.getDate(), meetingDate.getHours(), meetingDate.getMinutes() + vm.meetingTimeLength);

        while(startBeforeOrAtEndDate(meetingDate, vm.endDate)){

          while(startBeforeOrAtEndTime(meetingEnd, vm.endHours)){

            if(!(startBeforeOrAtEndTime(meetingEnd, vm.lunchStart) ||
              startAfterOrAtEndTime(meetingDate, vm.lunchEnd))) {
              meetingDate.setHours(vm.lunchEnd.getHours());
              meetingDate.setMinutes(vm.lunchEnd.getMinutes());

              meetingEnd.setHours(vm.lunchEnd.getHours());
              meetingEnd.setMinutes(vm.lunchEnd.getMinutes() + vm.meetingTimeLength);
            }

            for (var i=0; i < vm.chosenFacilities.length; i++){
              createMeeting(vm.chosenFacilities[i], meetingDate, meetingEnd);
            }

            //updating the time to the next meeting time
            meetingDate.setMinutes(meetingDate.getMinutes() + vm.meetingTimeLength);
            meetingEnd.setMinutes(meetingDate.getMinutes() + vm.meetingTimeLength);
          }

          //updating the date to the next day
          meetingDate.setDate(meetingDate.getDate() + 1);
          //reseting the time of the next day
          meetingDate.setHours(vm.startHours.getHours());
          meetingDate.setMinutes(vm.startHours.getMinutes());

          //meeting end
          meetingEnd = new Date(meetingDate.getFullYear(), meetingDate.getMonth(), meetingDate.getDate(), meetingDate.getHours(), meetingDate.getMinutes() + vm.meetingTimeLength);
        }

      } else {
        console.log('Alla fält är inte ifyllda!');
      }
    };
  }
})();
<|endoftext|>