<commit_before>(function(window){

var isNode = typeof process !== 'undefined' && process.toString() === '[object process]';
var RouteRecognizer = isNode ? require('route-recognizer')['default'] : window.RouteRecognizer;
var FakeXMLHttpRequest = isNode ? require('./bower_components/FakeXMLHttpRequest/fake_xml_http_request') : window.FakeXMLHttpRequest;
var slice = [].slice;

/**
 * parseURL - decompose a URL into its parts
 * @param  {String} url a URL
 * @return {Object} parts of the URL, including the following
 *
 * 'https://www.yahoo.com:1234/mypage?test=yes#abc'
 *
 * {
 *   host: 'www.yahoo.com:1234',
 *   protocol: 'https:',
 *   search: '?test=yes',
 *   hash: '#abc',
 *   href: 'https://www.yahoo.com:1234/mypage?test=yes#abc',
 *   pathname: '/mypage',
 *   fullpath: '/mypage?test=yes'
 * }
 */
function parseURL(url) {
  // TODO: something for when document isn't present... #yolo
  var anchor = document.createElement('a');
  anchor.href = url;
  anchor.fullpath = anchor.pathname + (anchor.search || '') + (anchor.hash || '');
  return anchor;
}

/**
 * Registry
 *
 * A registry is a map of HTTP verbs to route recognizers.
 */

function Registry(host) {
  this.verbs = {
    GET: new RouteRecognizer(),
    PUT: new RouteRecognizer(),
    POST: new RouteRecognizer(),
    DELETE: new RouteRecognizer(),
    PATCH: new RouteRecognizer(),
    HEAD: new RouteRecognizer(),
    OPTIONS: new RouteRecognizer()
  };
}

/**
 * Hosts
 *
 * a map of hosts to Registries, ultimately allowing
 * a per-host-and-port, per HTTP verb lookup of RouteRecognizers
 */
function Hosts() {
  this._registries = {};
}

/**
 * Hosts#forURL - retrieve a map of HTTP verbs to RouteRecognizers
 *                for a given URL
 *
 * @param  {String} url a URL
 * @return {Registry}   a map of HTTP verbs to RouteRecognizers
 *                      corresponding to the provided URL's
 *                      hostname and port
 */
Hosts.prototype.forURL = function(url) {
  var host = parseURL(url).host;
  var registry = this._registries[host];

  if (registry === undefined) {
    registry = (this._registries[host] = new Registry(host));
  }

  return registry.verbs;
}

function Pretender(/* routeMap1, routeMap2, ...*/){
  maps = slice.call(arguments);
  // Herein we keep track of RouteRecognizer instances
  // keyed by HTTP method. Feel free to add more as needed.
  this.hosts = new Hosts();

  this.handlers = [];
  this.handledRequests = [];
  this.passthroughRequests = [];
  this.unhandledRequests = [];
  this.requestReferences = [];

  // reference the native XMLHttpRequest object so
  // it can be restored later
  this._nativeXMLHttpRequest = window.XMLHttpRequest;

  // capture xhr requests, channeling them into
  // the route map.
  window.XMLHttpRequest = interceptor(this);

  // "start" the server
  this.running = true;

  // trigger the route map DSL.
  for(var i=0; i < arguments.length; i++){
    this.map(arguments[i]);
  }
}

function interceptor(pretender) {
  function FakeRequest(){
    // super()
    FakeXMLHttpRequest.call(this);
  }
  // extend
  var proto = new FakeXMLHttpRequest();
  proto.send = function send(){
    if (!pretender.running) {
      throw new Error('You shut down a Pretender instance while there was a pending request. '+
            'That request just tried to complete. Check to see if you accidentally shut down '+
            'a pretender earlier than you intended to');
    }

    FakeXMLHttpRequest.prototype.send.apply(this, arguments);
    if (!pretender.checkPassthrough(this)) {
      pretender.handleRequest(this);
    }
    else {
      var xhr = createPassthrough(this);
      xhr.send.apply(xhr, arguments);
    }
  };

  // passthrough handling
  var evts = ['error', 'timeout', 'progress', 'abort'];
  var lifecycleProps = ['readyState', 'responseText', 'responseXML', 'status', 'statusText'];
  function createPassthrough(fakeXHR) {
    var xhr = fakeXHR._passthroughRequest = new pretender._nativeXMLHttpRequest();

    // use onload instead of onreadystatechange if the browser supports it
    if ('onload' in xhr) {
      evts.push('load');
    } else {
      evts.push('readystatechange');
    }

    // listen to all events to update lifecycle properties
    for (var i = 0; i < evts.length; i++) (function(evt) {
      xhr['on' + evt] = function(e) {
        // update lifecycle props on each event
        for (var i = 0; i < lifecycleProps.length; i++) {
          var prop = lifecycleProps[i];
          if (xhr[prop]) {
            fakeXHR[prop] = xhr[prop];
          }
        }
        // fire fake events where applicable
        fakeXHR.dispatchEvent(evt, e);
        if (fakeXHR['on' + evt]) {
          fakeXHR['on' + evt](e);
        }
      };
    })(evts[i]);
    xhr.open(fakeXHR.method, fakeXHR.url, fakeXHR.async, fakeXHR.username, fakeXHR.password);
    xhr.timeout = fakeXHR.timeout;
    xhr.withCredentials = fakeXHR.withCredentials;
    for (var h in fakeXHR.requestHeaders) {
      xhr.setRequestHeader(h, fakeXHR.requestHeaders[h]);
    }
    return xhr;
  }
  proto._passthroughCheck = function(method, arguments) {
    if (this._passthroughRequest) {
      return this._passthroughRequest[method].apply(this._passthroughRequest, arguments);
    }
    return FakeXMLHttpRequest.prototype[method].apply(this, arguments);
  }
  proto.abort = function abort(){
    return this._passthroughCheck('abort', arguments);
  }
  proto.getResponseHeader = function getResponseHeader(){
    return this._passthroughCheck('getResponseHeader', arguments);
  }
  proto.getAllResponseHeaders = function getAllResponseHeaders(){
    return this._passthroughCheck('getAllResponseHeaders', arguments);
  }

  FakeRequest.prototype = proto;
  return FakeRequest;
}

function verbify(verb){
  return function(path, handler, async){
    this.register(verb, path, handler, async);
  };
}

function scheduleProgressEvent(request, startTime, totalTime) {
  setTimeout(function() {
    if (!request.aborted && !request.status) {
      var ellapsedTime = new Date().getTime() - startTime.getTime();
      request.upload._progress(true, ellapsedTime, totalTime);
      request._progress(true, ellapsedTime, totalTime);
      scheduleProgressEvent(request, startTime, totalTime);
    }
  }, 50);
}

var PASSTHROUGH = {};

Pretender.prototype = {
  get: verbify('GET'),
  post: verbify('POST'),
  put: verbify('PUT'),
  'delete': verbify('DELETE'),
  patch: verbify('PATCH'),
  head: verbify('HEAD'),
  map: function(maps){
    maps.call(this);
  },
  register: function register(verb, url, handler, async){
    if (!handler) {
      throw new Error("The function you tried passing to Pretender to handle " + verb + " " + url + " is undefined or missing.");
    }

    handler.numberOfCalls = 0;
    handler.async = async;
    this.handlers.push(handler);

    var registry = this.hosts.forURL(url)[verb];

    registry.add([{
      path: parseURL(url).fullpath,
      handler: handler
    }]);
  },
  passthrough: PASSTHROUGH,
  checkPassthrough: function checkPassthrough(request) {
    var verb = request.method.toUpperCase();

    var path = parseURL(request.url).fullpath;

    verb = verb.toUpperCase();

    var recognized = this.hosts.forURL(request.url)[verb].recognize(path);
    var match = recognized && recognized[0];
    if (match && match.handler == PASSTHROUGH) {
      this.passthroughRequests.push(request);
      this.passthroughRequest(verb, path, request);
      return true;
    }

    return false;
  },
  handleRequest: function handleRequest(request){
    var verb = request.method.toUpperCase();
    var path = request.url;

    var handler = this._handlerFor(verb, path, request);

    if (handler) {
      handler.handler.numberOfCalls++;
      var async = handler.handler.async;
      this.handledRequests.push(request);

      try {
        var statusHeadersAndBody = handler.handler(request),
            status = statusHeadersAndBody[0],
            headers = this.prepareHeaders(statusHeadersAndBody[1]),
            body = this.prepareBody(statusHeadersAndBody[2]),
            pretender = this;

        this.handleResponse(request, async, function() {
          request.respond(status, headers, body);
          pretender.handledRequest(verb, path, request);
        });
      } catch (error) {
        this.erroredRequest(verb, path, request, error);
        this.resolve(request);
      }
    } else {
      this.unhandledRequests.push(request);
      this.unhandledRequest(verb, path, request);
    }
  },
  handleResponse: function handleResponse(request, strategy, callback) {
    var delay = typeof strategy === 'function' ? strategy() : strategy;
    delay = typeof delay === 'boolean' || typeof delay === 'number' ? delay : 0;

    if (delay === false) {
      callback();
    } else {
      var pretender = this;
      pretender.requestReferences.push({
        request: request,
        callback: callback
      });

      if (delay !== true) {
        scheduleProgressEvent(request, new Date(), delay);
        setTimeout(function() {
          pretender.resolve(request);
        }, delay);
      }
    }
  },
  resolve: function resolve(request) {
    for(var i = 0, len = this.requestReferences.length; i < len; i++) {
      var res = this.requestReferences[i];
      if (res.request === request) {
        res.callback();
        this.requestReferences.splice(i, 1);
        break;
      }
    }
  },
  requiresManualResolution: function(verb, path) {
    var handler = this._handlerFor(verb.toUpperCase(), path, {});
    if (!handler) { return false; }

    var async = handler.handler.async;
    return typeof async === 'function' ? async() === true : async === true;
  },
  prepareBody: function(body) { return body; },
  prepareHeaders: function(headers) { return headers; },
  handledRequest: function(verb, path, request) { /* no-op */},
  passthroughRequest: function(verb, path, request) { /* no-op */},
  unhandledRequest: function(verb, path, request) {
    throw new Error("Pretender intercepted "+verb+" "+path+" but no handler was defined for this type of request");
  },
  erroredRequest: function(verb, path, request, error){
    error.message = "Pretender intercepted "+verb+" "+path+" but encountered an error: " + error.message;
    throw error;
  },
  _handlerFor: function(verb, url, request){
    var registry = this.hosts.forURL(url)[verb];
    var matches = registry.recognize(parseURL(url).fullpath);

    var match = matches ? matches[0] : null;
    if (match) {
      request.params = match.params;
      request.queryParams = matches.queryParams;
    }

    return match;
  },
  shutdown: function shutdown(){
    window.XMLHttpRequest = this._nativeXMLHttpRequest;

    // "stop" the server
    this.running = false;
  }
};

Pretender.parseURL = parseURL;
Pretender.Hosts = Hosts;
Pretender.Registry = Registry;

if (isNode) {
  module.exports = Pretender;
} else {
  window.Pretender = Pretender;
}

})(window);
<commit_msg>cleanup<commit_after>(function(self){
'use strict';
var isNode = typeof process !== 'undefined' && process.toString() === '[object process]';
var RouteRecognizer = isNode ? require('route-recognizer')['default'] : window.RouteRecognizer;
var FakeXMLHttpRequest = isNode ? require('./bower_components/FakeXMLHttpRequest/fake_xml_http_request') : window.FakeXMLHttpRequest;

/**
 * parseURL - decompose a URL into its parts
 * @param  {String} url a URL
 * @return {Object} parts of the URL, including the following
 *
 * 'https://www.yahoo.com:1234/mypage?test=yes#abc'
 *
 * {
 *   host: 'www.yahoo.com:1234',
 *   protocol: 'https:',
 *   search: '?test=yes',
 *   hash: '#abc',
 *   href: 'https://www.yahoo.com:1234/mypage?test=yes#abc',
 *   pathname: '/mypage',
 *   fullpath: '/mypage?test=yes'
 * }
 */
function parseURL(url) {
  // TODO: something for when document isn't present... #yolo
  var anchor = document.createElement('a');
  anchor.href = url;
  anchor.fullpath = anchor.pathname + (anchor.search || '') + (anchor.hash || '');
  return anchor;
}

/**
 * Registry
 *
 * A registry is a map of HTTP verbs to route recognizers.
 */

function Registry(host) {
  this.verbs = {
    GET: new RouteRecognizer(),
    PUT: new RouteRecognizer(),
    POST: new RouteRecognizer(),
    DELETE: new RouteRecognizer(),
    PATCH: new RouteRecognizer(),
    HEAD: new RouteRecognizer(),
    OPTIONS: new RouteRecognizer()
  };
}

/**
 * Hosts
 *
 * a map of hosts to Registries, ultimately allowing
 * a per-host-and-port, per HTTP verb lookup of RouteRecognizers
 */
function Hosts() {
  this._registries = {};
}

/**
 * Hosts#forURL - retrieve a map of HTTP verbs to RouteRecognizers
 *                for a given URL
 *
 * @param  {String} url a URL
 * @return {Registry}   a map of HTTP verbs to RouteRecognizers
 *                      corresponding to the provided URL's
 *                      hostname and port
 */
Hosts.prototype.forURL = function(url) {
  var host = parseURL(url).host;
  var registry = this._registries[host];

  if (registry === undefined) {
    registry = (this._registries[host] = new Registry(host));
  }

  return registry.verbs;
}

function Pretender(/* routeMap1, routeMap2, ...*/){
  maps = slice.call(arguments);
  // Herein we keep track of RouteRecognizer instances
  // keyed by HTTP method. Feel free to add more as needed.
  this.hosts = new Hosts();

  this.handlers = [];
  this.handledRequests = [];
  this.passthroughRequests = [];
  this.unhandledRequests = [];
  this.requestReferences = [];

  // reference the native XMLHttpRequest object so
  // it can be restored later
  this._nativeXMLHttpRequest = window.XMLHttpRequest;

  // capture xhr requests, channeling them into
  // the route map.
  window.XMLHttpRequest = interceptor(this);

  // "start" the server
  this.running = true;

  // trigger the route map DSL.
  for(var i=0; i < arguments.length; i++){
    this.map(arguments[i]);
  }
}

function interceptor(pretender) {
  function FakeRequest(){
    // super()
    FakeXMLHttpRequest.call(this);
  }
  // extend
  var proto = new FakeXMLHttpRequest();
  proto.send = function send(){
    if (!pretender.running) {
      throw new Error('You shut down a Pretender instance while there was a pending request. '+
            'That request just tried to complete. Check to see if you accidentally shut down '+
            'a pretender earlier than you intended to');
    }

    FakeXMLHttpRequest.prototype.send.apply(this, arguments);
    if (!pretender.checkPassthrough(this)) {
      pretender.handleRequest(this);
    }
    else {
      var xhr = createPassthrough(this);
      xhr.send.apply(xhr, arguments);
    }
  };

  // passthrough handling
  var evts = ['error', 'timeout', 'progress', 'abort'];
  var lifecycleProps = ['readyState', 'responseText', 'responseXML', 'status', 'statusText'];
  function createPassthrough(fakeXHR) {
    var xhr = fakeXHR._passthroughRequest = new pretender._nativeXMLHttpRequest();

    // use onload instead of onreadystatechange if the browser supports it
    if ('onload' in xhr) {
      evts.push('load');
    } else {
      evts.push('readystatechange');
    }

    // listen to all events to update lifecycle properties
    for (var i = 0; i < evts.length; i++) (function(evt) {
      xhr['on' + evt] = function(e) {
        // update lifecycle props on each event
        for (var i = 0; i < lifecycleProps.length; i++) {
          var prop = lifecycleProps[i];
          if (xhr[prop]) {
            fakeXHR[prop] = xhr[prop];
          }
        }
        // fire fake events where applicable
        fakeXHR.dispatchEvent(evt, e);
        if (fakeXHR['on' + evt]) {
          fakeXHR['on' + evt](e);
        }
      };
    })(evts[i]);
    xhr.open(fakeXHR.method, fakeXHR.url, fakeXHR.async, fakeXHR.username, fakeXHR.password);
    xhr.timeout = fakeXHR.timeout;
    xhr.withCredentials = fakeXHR.withCredentials;
    for (var h in fakeXHR.requestHeaders) {
      xhr.setRequestHeader(h, fakeXHR.requestHeaders[h]);
    }
    return xhr;
  }

  proto._passthroughCheck = function(method, args) {
    if (this._passthroughRequest) {
      return this._passthroughRequest[method].apply(this._passthroughRequest, args);
    }
    return FakeXMLHttpRequest.prototype[method].apply(this, args);
  };

  proto.abort = function abort() {
    return this._passthroughCheck('abort', arguments);
  };

  proto.getResponseHeader = function getResponseHeader() {
    return this._passthroughCheck('getResponseHeader', arguments);
  };

  proto.getAllResponseHeaders = function getAllResponseHeaders() {
    return this._passthroughCheck('getAllResponseHeaders', arguments);
  };

  FakeRequest.prototype = proto;
  return FakeRequest;
}

function verbify(verb){
  return function(path, handler, async){
    this.register(verb, path, handler, async);
  };
}

function scheduleProgressEvent(request, startTime, totalTime) {
  setTimeout(function() {
    if (!request.aborted && !request.status) {
      var ellapsedTime = new Date().getTime() - startTime.getTime();
      request.upload._progress(true, ellapsedTime, totalTime);
      request._progress(true, ellapsedTime, totalTime);
      scheduleProgressEvent(request, startTime, totalTime);
    }
  }, 50);
}

var PASSTHROUGH = {};

Pretender.prototype = {
  get: verbify('GET'),
  post: verbify('POST'),
  put: verbify('PUT'),
  'delete': verbify('DELETE'),
  patch: verbify('PATCH'),
  head: verbify('HEAD'),
  map: function(maps){
    maps.call(this);
  },
  register: function register(verb, url, handler, async){
    if (!handler) {
      throw new Error("The function you tried passing to Pretender to handle " + verb + " " + url + " is undefined or missing.");
    }

    handler.numberOfCalls = 0;
    handler.async = async;
    this.handlers.push(handler);

    var registry = this.hosts.forURL(url)[verb];

    registry.add([{
      path: parseURL(url).fullpath,
      handler: handler
    }]);
  },
  passthrough: PASSTHROUGH,
  checkPassthrough: function checkPassthrough(request) {
    var verb = request.method.toUpperCase();

    var path = parseURL(request.url).fullpath;

    verb = verb.toUpperCase();

    var recognized = this.hosts.forURL(request.url)[verb].recognize(path);
    var match = recognized && recognized[0];
    if (match && match.handler == PASSTHROUGH) {
      this.passthroughRequests.push(request);
      this.passthroughRequest(verb, path, request);
      return true;
    }

    return false;
  },
  handleRequest: function handleRequest(request){
    var verb = request.method.toUpperCase();
    var path = request.url;

    var handler = this._handlerFor(verb, path, request);

    if (handler) {
      handler.handler.numberOfCalls++;
      var async = handler.handler.async;
      this.handledRequests.push(request);

      try {
        var statusHeadersAndBody = handler.handler(request),
            status = statusHeadersAndBody[0],
            headers = this.prepareHeaders(statusHeadersAndBody[1]),
            body = this.prepareBody(statusHeadersAndBody[2]),
            pretender = this;

        this.handleResponse(request, async, function() {
          request.respond(status, headers, body);
          pretender.handledRequest(verb, path, request);
        });
      } catch (error) {
        this.erroredRequest(verb, path, request, error);
        this.resolve(request);
      }
    } else {
      this.unhandledRequests.push(request);
      this.unhandledRequest(verb, path, request);
    }
  },
  handleResponse: function handleResponse(request, strategy, callback) {
    var delay = typeof strategy === 'function' ? strategy() : strategy;
    delay = typeof delay === 'boolean' || typeof delay === 'number' ? delay : 0;

    if (delay === false) {
      callback();
    } else {
      var pretender = this;
      pretender.requestReferences.push({
        request: request,
        callback: callback
      });

      if (delay !== true) {
        scheduleProgressEvent(request, new Date(), delay);
        setTimeout(function() {
          pretender.resolve(request);
        }, delay);
      }
    }
  },
  resolve: function resolve(request) {
    for(var i = 0, len = this.requestReferences.length; i < len; i++) {
      var res = this.requestReferences[i];
      if (res.request === request) {
        res.callback();
        this.requestReferences.splice(i, 1);
        break;
      }
    }
  },
  requiresManualResolution: function(verb, path) {
    var handler = this._handlerFor(verb.toUpperCase(), path, {});
    if (!handler) { return false; }

    var async = handler.handler.async;
    return typeof async === 'function' ? async() === true : async === true;
  },
  prepareBody: function(body) { return body; },
  prepareHeaders: function(headers) { return headers; },
  handledRequest: function(verb, path, request) { /* no-op */},
  passthroughRequest: function(verb, path, request) { /* no-op */},
  unhandledRequest: function(verb, path, request) {
    throw new Error("Pretender intercepted "+verb+" "+path+" but no handler was defined for this type of request");
  },
  erroredRequest: function(verb, path, request, error){
    error.message = "Pretender intercepted "+verb+" "+path+" but encountered an error: " + error.message;
    throw error;
  },
  _handlerFor: function(verb, url, request){
    var registry = this.hosts.forURL(url)[verb];
    var matches = registry.recognize(parseURL(url).fullpath);

    var match = matches ? matches[0] : null;
    if (match) {
      request.params = match.params;
      request.queryParams = matches.queryParams;
    }

    return match;
  },
  shutdown: function shutdown(){
    self.XMLHttpRequest = this._nativeXMLHttpRequest;

    // "stop" the server
    this.running = false;
  }
};

Pretender.parseURL = parseURL;
Pretender.Hosts = Hosts;
Pretender.Registry = Registry;

if (isNode) {
  module.exports = Pretender;
} else {
  self.Pretender = Pretender;
}

}(self));
<|endoftext|>


<commit_before>module.exports = {
        COMMAND_CONTROL_URL: 'localhost:3031'};
<commit_msg>fixed styling issues<commit_after>module.exports = {
    COMMAND_CONTROL_URL: 'localhost:3031'
};
<|endoftext|>


<commit_before>odoo.define('pos_order_cancel.tour', function(require) {
    "use strict";

    var core = require('web.core');
    var tour = require('web_tour.tour');

    tour.register('pos_order_cancel_tour', {
        test: true,
        url: "/web",
    }, [{
        trigger: '.o_app[data-menu-xmlid="point_of_sale.menu_point_root"], .oe_menu_toggler[data-menu-xmlid="point_of_sale.menu_point_root"]',
        content: "Ready to launch your point of sale? Click here.",
        position: 'bottom',
    }, {
        trigger: ".o_pos_kanban button.oe_kanban_action_button",
        content: "
Click to start the point of sale interface. It runs on tablets, laptops, or industrial hardware.

Once the session launched, the system continues to run without an internet connection.
",
        position: "bottom",
    }, {
        trigger: ".product-list .product",
        content: "
Click product 1
",
        position: "bottom",
        timeout: 20000,
    }, {
        trigger: ".product-list .product:not(:first)",
        content: "
Click product 2
",
        position: "bottom"
    }, {
        trigger: ".pads .numpad-backspace",
        content: "
Remove orderline
",
        position: "bottom"
    }, {
        trigger: ".reason-button[data-id='1']",
        content: "
Click predefined reason
",
        position: "bottom"
    }, {
        trigger: ".reason-button[data-id='3']",
        content: "
Click predefined reason
",
        position: "bottom"
    }, {
        trigger: ".popup-confirm-cancellation .confirm",
        content: "
Click confirm button
",
        position: "bottom"
    },{
        trigger: ".deleteorder-button",
        content: "
Click remove order button
",
        position: "bottom"
    }, {
        trigger: ".reason-button[data-id='1']",
        content: "
Click predefined reason
",
        position: "bottom"
    }, {
        trigger: ".popup-confirm-cancellation .confirm",
        content: "
Click confirm button
",
        position: "bottom"
    }
    ]);
});
<commit_msg>:shield: pos_order_cancel<commit_after>odoo.define('pos_order_cancel.tour', function(require) {
    "use strict";

    var core = require('web.core');
    var tour = require('web_tour.tour');

    tour.register('pos_order_cancel_tour', {
        test: true,
        url: "/web",
    }, [tour.STEPS.SHOW_APPS_MENU_ITEM, {
        trigger: '.o_app[data-menu-xmlid="point_of_sale.menu_point_root"]',
        content: "Ready to launch your point of sale? Click here.",
        position: 'right',
        edition: 'community'
    }, {
        trigger: '.o_app[data-menu-xmlid="point_of_sale.menu_point_root"]',
        content: "Ready to launch your point of sale? Click here.",
        position: 'bottom',
        edition: 'enterprise'
    }, {
        trigger: ".o_pos_kanban button.oe_kanban_action_button",
        content: "
Click to start the point of sale interface. It runs on tablets, laptops, or industrial hardware.

Once the session launched, the system continues to run without an internet connection.
",
        position: "bottom"
    }, {
        trigger: ".product-list .product",
        content: "
Click product 1
",
        position: "bottom",
        timeout: 20000,
    }, {
        trigger: ".product-list .product:not(:first)",
        content: "
Click product 2
",
        position: "bottom"
    }, {
        trigger: ".pads .numpad-backspace",
        content: "
Remove orderline
",
        position: "bottom"
    }, {
        trigger: ".reason-button[data-id='1']",
        content: "
Click predefined reason
",
        position: "bottom"
    }, {
        trigger: ".reason-button[data-id='3']",
        content: "
Click predefined reason
",
        position: "bottom"
    }, {
        trigger: ".popup-confirm-cancellation .confirm",
        content: "
Click confirm button
",
        position: "bottom"
    },{
        trigger: ".deleteorder-button",
        content: "
Click remove order button
",
        position: "bottom"
    }, {
        trigger: ".reason-button[data-id='1']",
        content: "
Click predefined reason
",
        position: "bottom"
    }, {
        trigger: ".popup-confirm-cancellation .confirm",
        content: "
Click confirm button
",
        position: "bottom"
    }
    ]);
});
<|endoftext|>


<commit_before>/**
 * Created by ionagamed on 8/25/16.
 */

const translationMapping = {
    'gelatinous_octahedron': 'Желатиновый Октаэдр',
    'ghoulfiends': 'Мадемонуазели',
    'harpies': 'Гарпистки',
    'hippogriff': 'Гиппогриф',
    'insurance_salesman': 'Страховой Агент',
    '3872_orcs': '3872 орка',
    'amazon': 'Амазонка',
    'bigfoot': 'Бигфут',
    'bullrog': 'Бульрог',
    'crabs': 'Типа Вошки',
    'curse_lose_small_item': 'Невелика Потеря',
    'curse_lose_armor': 'Теряешь Надетый Броник',
    'curse_lose_footgear': 'Теряешь Надетую Обувку',
    'curse_lose_headgear': 'Теряешь Надетый Головняк',
    'wizard': 'Волшебник',
    'curse_change_class': 'Смена Класса',
    'curse_change_race': 'Смена Расы',
    'curse_change_sex': 'Смена Пола',
    'curse_chicken': 'Курица На Башне',
    'halfling': 'Халфлинг',
    'thief': 'Вор',
    'half-breed': 'Полукровка',
    'help_me_out_here': 'Помоги Себе Сам!',
    'illusion': 'Иллюзия',
    'mate': 'Гадкая Парочка',
    'out_to_lunch': 'Ушел На Обед',
    'squidzilla': 'Кальмадзилла',
    'stoned_golem': 'Обдолбанный Голем',
    'tongue_demon': 'Языческий Демон',
    'undead_horse': 'Андедный Коник',
    'horror': 'Невыразимо Жуткий Неописуемый Ужас',
    'ancient': 'Древний',
    'baby': 'Детеныш',
    'enraged': 'Психованный',
    'humongous': 'Амбал',
    'intelligent': 'Мозговитый',
    'maul_rat': 'Молотая Крысотка',
    'mr_bones': 'Г-н Кости',
    'net_troll': 'Форумный Тролль',
    'pit_bull': 'Питбуль',
    'platycore': 'Утикора',
    'cleric': 'Клирик',
    'dwarf': 'Дварф',
    'plutonium_dragon': 'Плутониевый Дракон',
    'potted_plant': 'Трава В Горшке',
    'pukachu': 'Рыгачу',
    'shrieking_geek': 'Вопящий Задрот',
    'snails_on_speed': 'Ускоренные Улитки',
    'elf': 'Эльф',
    'king_tut': 'Король Тут',
    'lame_goblin': 'Увечный Гоблин',
    'large_angry_chicken': 'Здоровенная Бешенная Цыпа',
    'lawyers': 'Адвокат',
    'leperchaun': 'Лепрокон',
    'drooling_slime': 'Сочащаяся Слизь',
    'face_sucker': 'Лицесос',
    'floating_nose': 'Сопливый Нос',
    'flying_frogs': 'Летучие Лягушки',
    'gazebo': 'Газебо',
    'curse_lose_two_cards': 'Теряешь 2 Карты',
    'curse_lose_class': 'Теряешь Класс',
    'curse_lose_race': 'Теряешь Расу',
    'curse_malign_mirror': 'Кривящее Зеркало',
    'truly_obnoxious_curse': 'В Конец Мерзкое Проклятие',
    'curse_duck_of_doom': 'Утка Обреченности',
    'curse_income_tax': 'Налоги',
    'curse_lose_big_item': 'Большая Потеря',
    'curse_lose_level': 'Теряешь 1 Уровень!',
    'warrior': 'Воин',
    'super_munchkin': 'Суперманчкин',
    'wandering_monster': 'Бродячая Тварь',
    'wannabe_vampire': 'Закос Под Вампира',
    'wight_brothers': 'Бледные Братья',
    'cheat': 'Чит!',
    'divine_intervention': 'Божественное Вмешательство',

    'male': 'мужской',
    'female': 'женский',

    'monster': 'монстр',
    'curse': 'проклятие',
    '1-handed': 'одноручное',
    '2-handed': 'двуручное',
    'armor': 'броник',
    'headgear': 'головняк',
    'footgear': 'обувка',
    'modifier': 'модификатор',

    'magic_lamp': 'Волшебная Лампа',
    'pollymorph_potion': 'Зелье Попуморфа',
    'transferral_potion': 'Зелье Стрелочника',
    'wand_of_dowsing': 'Штырь Лозоходца',
    'wishing_ring': 'Хотельное Кольцо',
    'spiky_knees': 'Острые Коленки',
    'staff_of_napalm': 'Посох Напалма',
    'stepladder': 'Боевая Стремянка',
    'swiss_army_polearm': 'Швецарская Армейская Алебарда',
    'doppleganger': 'Дупельгангер',
    'flaming_armor': 'Палёные Доспехи',
    'gentlemans_club': 'Дуб Джельтенменов',
    'hammer_of_kneecapping': 'Коленеотбойный Молоточек',
    'helm of courage': 'Шлем Бесстрашия',
    'horny_helmet': 'Шлем-Рогач',
    'bad-ass_bandanna': 'Сорвиголовная Бандана',
    'boots_of_butt-kicking': 'Башмаки Могучего Пендаля',
    'bow_with_ribbons': 'Лук с Ленточками',
    'broad_sword': 'Меч Широты Взглядов',
    'buckler_of_swashing': 'Пафосный Баклер',
    'cotion_of_ponfusion': 'Пелье Зутаницы',
    'acid_potion': 'Радиоактивно-Электрокислотное Зелье',
    'flaming_poison_potion': 'Зелье Пламенной Отравы',
    'freezing_explosive_potion': 'Заморажтвающие Взрывное Зелье',
    'magic_missile': 'Магичиская Ракета',
    'pantyhose_of_giant_strength': 'Колготки Великанской Силы',
    'pointy_hat_of_power': 'Остроконечная Шляпа Могущества',
    'rapier_of_unfairness': 'Рапира Такнечестности',
    'rat_on_a_stick': 'Крыса на палочке',
    'really_impressive_title': 'Реально Конкрктный Титул',
    '1000_gold': '1000 Голдов',
    'boil_an_anthill': 'Кипяток в Муравейнике',
    'bribe_gm_with_food': 'Прикорми Мастера',
    'convenient_addition_error': 'Выголная ошибка при сложении',
    'invoke_obscure_rules': 'Используй непонятное правило',
    'wishing_ring': 'Хотельное кольцо',
    'boots_of_running_really_fast': 'Башмаки реално быстрого бега',
    'hireling': 'Наёмничек',
    'hoard': 'Ура, Клад!',
    'kneepads_of_allure': 'Наколенники Развода',
    'flask_of_glue': 'Тюбик Клея',
    'friendship_potion': 'Зелье Дружбы',
    'instant_wall': 'Стенка-Встанька',
    'invisibility_potion': 'Зелье Невидимости',
    'loaded_die_1': 'Читерский кубик',
    'huge_rock': 'Огромная Каменюга',
    'leather_armor': 'Кожанный Прикид',
    'sandwich': 'Сэнвич запоздалого прозрения с сыром и селёдкой',
    'mace_of_sharpiness': 'Булава остроконечности',
    'mithril_armor': 'Мифрильный доспех',
    'chainsaw': 'Бензопила крававого расчленения',
    'cheese_grater_of_piece': 'Тёрка умиротвотения',
    'cloak_of_obscurity': 'Плащ замутнения',
    'dagger_of_treachery': 'Кинжал измены',
    'eleven-foot_pole': 'Одиннадцатифутовый кий',
    'nasty-tasting_sports_drink': 'Питьё противно-спортивное',
    'potion_of_halitosis': 'Зелье ротовой воин',
    'potion_of_idiotic_bravery': 'Зелье илиотской храбрости',
    'pretty_balloons': 'Клёвые шарики',
    'sleep_potion': 'Снотворное зелье',
    'shield_of_ubiquity': 'Совсесторонний щит',
    'short_wide_armor': 'Доспехи Поперёк-Себя-Шире',
    'singing_and_dancing_sword': 'Меч песни и пляски',
    'slimy_armor': 'Склизистая оболочка',
    'sneaky_bastard_sword': 'Меч коварного бастарда',
    'kill_the_hireling': 'Расчиайся с наёмником',
    'mutilate_the_bodies': 'Поглумились над телами врагов',
    'potion_of_general_studliness': 'Зелье Крутизны',
    'whine_at_the_gm': 'Разжалоби мастера',
    'yuppie_water': 'Яппиток',
    'go_up_a_level': 'Получи уровень',
    'steal_a_level': 'Укради уровень',
    'tuba_of_charm': 'Чарующая дуда',
    'sandals_of_protection': 'Сандалеты-Протекторы',
    'q-dice': 'Q-Кубик',
};

export default function (x) {
    if (!x) return x;
    if (x.substring(x.length - 2, x.length - 1) == '_') {
        x = x.substring(0, x.length - 2);
    }
    if (translationMapping.hasOwnProperty(x)) {
        return translationMapping[x];
    } else {
        return x;
    }
}
<commit_msg>logic<commit_after>/**
 * Created by ionagamed on 8/25/16.
 */

const translationMapping = {
    'gelatinous_octahedron': 'Желатиновый Октаэдр',
    'ghoulfiends': 'Мадемонуазели',
    'harpies': 'Гарпистки',
    'hippogriff': 'Гиппогриф',
    'insurance_salesman': 'Страховой Агент',
    '3872_orcs': '3872 орка',
    'amazon': 'Амазонка',
    'bigfoot': 'Бигфут',
    'bullrog': 'Бульрог',
    'crabs': 'Типа Вошки',
    'curse_lose_small_item': 'Невелика Потеря',
    'curse_lose_armor': 'Теряешь Надетый Броник',
    'curse_lose_footgear': 'Теряешь Надетую Обувку',
    'curse_lose_headgear': 'Теряешь Надетый Головняк',
    'wizard': 'Волшебник',
    'curse_change_class': 'Смена Класса',
    'curse_change_race': 'Смена Расы',
    'curse_change_sex': 'Смена Пола',
    'curse_chicken': 'Курица На Башне',
    'halfling': 'Халфлинг',
    'thief': 'Вор',
    'half-breed': 'Полукровка',
    'help_me_out_here': 'Помоги Себе Сам!',
    'illusion': 'Иллюзия',
    'mate': 'Гадкая Парочка',
    'out_to_lunch': 'Ушел На Обед',
    'squidzilla': 'Кальмадзилла',
    'stoned_golem': 'Обдолбанный Голем',
    'tongue_demon': 'Языческий Демон',
    'undead_horse': 'Андедный Коник',
    'horror': 'Невыразимо Жуткий Неописуемый Ужас',
    'ancient': 'Древний',
    'baby': 'Детеныш',
    'enraged': 'Психованный',
    'humongous': 'Амбал',
    'intelligent': 'Мозговитый',
    'maul_rat': 'Молотая Крысотка',
    'mr_bones': 'Г-н Кости',
    'net_troll': 'Форумный Тролль',
    'pit_bull': 'Питбуль',
    'platycore': 'Утикора',
    'cleric': 'Клирик',
    'dwarf': 'Дварф',
    'plutonium_dragon': 'Плутониевый Дракон',
    'potted_plant': 'Трава В Горшке',
    'pukachu': 'Рыгачу',
    'shrieking_geek': 'Вопящий Задрот',
    'snails_on_speed': 'Ускоренные Улитки',
    'elf': 'Эльф',
    'king_tut': 'Король Тут',
    'lame_goblin': 'Увечный Гоблин',
    'large_angry_chicken': 'Здоровенная Бешенная Цыпа',
    'lawyers': 'Адвокат',
    'leperchaun': 'Лепрокон',
    'drooling_slime': 'Сочащаяся Слизь',
    'face_sucker': 'Лицесос',
    'floating_nose': 'Сопливый Нос',
    'flying_frogs': 'Летучие Лягушки',
    'gazebo': 'Газебо',
    'curse_lose_two_cards': 'Теряешь 2 Карты',
    'curse_lose_class': 'Теряешь Класс',
    'curse_lose_race': 'Теряешь Расу',
    'curse_malign_mirror': 'Кривящее Зеркало',
    'truly_obnoxious_curse': 'В Конец Мерзкое Проклятие',
    'curse_duck_of_doom': 'Утка Обреченности',
    'curse_income_tax': 'Налоги',
    'curse_lose_big_item': 'Большая Потеря',
    'curse_lose_level': 'Теряешь 1 Уровень!',
    'warrior': 'Воин',
    'super_munchkin': 'Суперманчкин',
    'wandering_monster': 'Бродячая Тварь',
    'wannabe_vampire': 'Закос Под Вампира',
    'wight_brothers': 'Бледные Братья',
    'cheat': 'Чит!',
    'divine_intervention': 'Божественное Вмешательство',

    'male': 'мужской',
    'female': 'женский',

    'monster': 'монстр',
    'curse': 'проклятие',
    '1-handed': 'одноручное',
    '2-handed': 'двуручное',
    'armor': 'броник',
    'headgear': 'головняк',
    'footgear': 'обувка',
    'modifier': 'модификатор',

    'magic_lamp': 'Волшебная Лампа',
    'pollymorph_potion': 'Зелье Попуморфа',
    'transferral_potion': 'Зелье Стрелочника',
    'wand_of_dowsing': 'Штырь Лозоходца',
    'wishing_ring': 'Хотельное Кольцо',
    'spiky_knees': 'Острые Коленки',
    'staff_of_napalm': 'Посох Напалма',
    'stepladder': 'Боевая Стремянка',
    'swiss_army_polearm': 'Швецарская Армейская Алебарда',
    'doppleganger': 'Дупельгангер',
    'flaming_armor': 'Палёные Доспехи',
    'gentlemans_club': 'Дуб Джельтенменов',
    'hammer_of_kneecapping': 'Коленеотбойный Молоточек',
    'helm of courage': 'Шлем Бесстрашия',
    'horny_helmet': 'Шлем-Рогач',
    'bad-ass_bandanna': 'Сорвиголовная Бандана',
    'boots_of_butt-kicking': 'Башмаки Могучего Пендаля',
    'bow_with_ribbons': 'Лук с Ленточками',
    'broad_sword': 'Меч Широты Взглядов',
    'buckler_of_swashing': 'Пафосный Баклер',
    'cotion_of_ponfusion': 'Пелье Зутаницы',
    'acid_potion': 'Радиоактивно-Электрокислотное Зелье',
    'flaming_poison_potion': 'Зелье Пламенной Отравы',
    'freezing_explosive_potion': 'Заморажтвающие Взрывное Зелье',
    'magic_missile': 'Магичиская Ракета',
    'pantyhose_of_giant_strength': 'Колготки Великанской Силы',
    'pointy_hat_of_power': 'Остроконечная Шляпа Могущества',
    'rapier_of_unfairness': 'Рапира Такнечестности',
    'rat_on_a_stick': 'Крыса на палочке',
    'really_impressive_title': 'Реально Конкрктный Титул',
    '1000_gold': '1000 Голдов',
    'boil_an_anthill': 'Кипяток в Муравейнике',
    'bribe_gm_with_food': 'Прикорми Мастера',
    'convenient_addition_error': 'Выголная ошибка при сложении',
    'invoke_obscure_rules': 'Используй непонятное правило',
    'wishing_ring': 'Хотельное кольцо',
    'boots_of_running_really_fast': 'Башмаки реально быстрого бега',
    'hireling': 'Наёмничек',
    'hoard': 'Ура, Клад!',
    'kneepads_of_allure': 'Наколенники Развода',
    'flask_of_glue': 'Тюбик Клея',
    'friendship_potion': 'Зелье Дружбы',
    'instant_wall': 'Стенка-Встанька',
    'invisibility_potion': 'Зелье Невидимости',
    'loaded_die_1': 'Читерский кубик',
    'huge_rock': 'Огромная Каменюга',
    'leather_armor': 'Кожанный Прикид',
    'sandwich': 'Сэнвич запоздалого прозрения с сыром и селёдкой',
    'mace_of_sharpiness': 'Булава остроконечности',
    'mithril_armor': 'Мифрильный доспех',
    'chainsaw': 'Бензопила крававого расчленения',
    'cheese_grater_of_piece': 'Тёрка умиротвотения',
    'cloak_of_obscurity': 'Плащ замутнения',
    'dagger_of_treachery': 'Кинжал измены',
    'eleven-foot_pole': 'Одиннадцатифутовый кий',
    'nasty-tasting_sports_drink': 'Питьё противно-спортивное',
    'potion_of_halitosis': 'Зелье ротовой воин',
    'potion_of_idiotic_bravery': 'Зелье илиотской храбрости',
    'pretty_balloons': 'Клёвые шарики',
    'sleep_potion': 'Снотворное зелье',
    'shield_of_ubiquity': 'Совсесторонний щит',
    'short_wide_armor': 'Доспехи Поперёк-Себя-Шире',
    'singing_and_dancing_sword': 'Меч песни и пляски',
    'slimy_armor': 'Склизистая оболочка',
    'sneaky_bastard_sword': 'Меч коварного бастарда',
    'kill_the_hireling': 'Расчиайся с наёмником',
    'mutilate_the_bodies': 'Поглумились над телами врагов',
    'potion_of_general_studliness': 'Зелье Крутизны',
    'whine_at_the_gm': 'Разжалоби мастера',
    'yuppie_water': 'Яппиток',
    'go_up_a_level': 'Получи уровень',
    'steal_a_level': 'Укради уровень',
    'tuba_of_charm': 'Чарующая дуда',
    'sandals_of_protection': 'Сандалеты-Протекторы',
    'q-dice': 'Q-Кубик',
};

export default function (x) {
    if (!x) return x;
    if (x.substring(x.length - 2, x.length - 1) == '_') {
        x = x.substring(0, x.length - 2);
    }
    if (translationMapping.hasOwnProperty(x)) {
        return translationMapping[x];
    } else {
        return x;
    }
}
<|endoftext|>


<commit_before>/*globals App:true Ember before after bench*/

var view;

before(function() {
  var view;
  window.App = Ember.Namespace.create();

  App.View = Ember.View.extend({
    template: Ember.Handlebars.compile("{{view}}")
  });
});

after(function() {
  view.destroy();
});

bench("creating a new view", function() {
  Ember.run(function() {
    view = App.View.create().append();
  });
});
<commit_msg>Exclude initial proto from benchmark<commit_after>/*globals App:true Ember before after bench*/

var view;

before(function() {
  var view;
  window.App = Ember.Namespace.create();

  App.View = Ember.View.extend({
    template: Ember.Handlebars.compile("{{view}}")
  });

  App.View.create().destroy();
});

after(function() {
  view.destroy();
});

bench("creating a new view", function() {
  Ember.run(function() {
    view = App.View.create().append();
  });
});
<|endoftext|>


<commit_before><commit_msg>Updates cadence.<commit_after><|endoftext|>


<commit_before>/**
 * Static data the for the expense form
 */

export default function(groupid) {
  if (typeof groupid == "string")
    groupid = parseInt(groupid, 10);

  let categories = [];
  switch (groupid) {
    // Women Who Code
    case 2:
    case 3:
    case 4:
    case 10:
    case 12:
    case 13:
    case 14:
    case 15:
    case 47:
    case 48:
    case 51:
    case 59:
    case 195:
    case 241:
      categories = [
        'Conference',
        'Donation',
        'Fees',
        'Fireside Chat',
        'Global Development',
        'Hack Night',
        'Hackathon',
        'Leadership Development',
        'Leadership Supplies',
        'Lightning Talks',
        'Scholarship',
        'Speaker Series',
        'Sponsorship',
        'Tech Panel',
        'Transaction Fees',
        'Study Group',
        'Workshop',
        'Other WWCode Event',
        'Other'
      ];
      break;
    case 6: // laprimaire
    case 73: // nuitdebout
    case 24: // lesbarbares
      categories = [
        'Admin',
        'Autre',
        'Communication',
        'Déplacement',
        'Marketing',
        'NDD',
        'Outils',
        'PI',
        'Papeterie',
        'Représentation',
        'Serveur',
        'Transport'
      ];
       break;
    case 114: // partidodigital
      categories = [
        'Comunicación',
        'Diseño',
        'Aporte',
        'Sistemas',
        'Fondos',
        'Alimentos y Bebidas',
        'Marketing',
        'Legales',
        'Suministros & materiales',
        'Viajes',
        'Equipo',
        'Oficina',
        'Otros',
        'Servicios Digitales'
      ];
      break;
    case 245: // analizebasilicata
      categories = [
        'Comunicazioni',
        'Disign',
        'Donazione',
        'Sviluppo software',
        'Accantonamento',
        'Cibo & bevande',
        'Marketing',
        'Legale',
        'Forniture & materiali',
        'Viaggio',
        'Squadra',
        'Ufficio',
        'Altro',
        'Servizi web'
      ];
      break;
    default:
      categories = [
        'Communications',
        'Design',
        'Donation',
        'Engineering',
        'Fund',
        'Food & Beverage',
        'Marketing',
        'Legal',
        'Supplies & materials',
        'Travel',
        'Team',
        'Office',
        'Other',
        'Web services'
      ];
  }
  return categories.sort();
}
<commit_msg>added new ids to wwcode categories<commit_after>/**
 * Static data the for the expense form
 */

export default function(groupid) {
  if (typeof groupid == "string")
    groupid = parseInt(groupid, 10);

  let categories = [];
  switch (groupid) {
    // Women Who Code
    case 2:
    case 3:
    case 4:
    case 10:
    case 12:
    case 13:
    case 14:
    case 15:
    case 47:
    case 48:
    case 51:
    case 59:
    case 195:
    case 241:
    case 259:
    case 260:
    case 261:
    case 262:
    case 263:
    case 262:
    case 262:
    case 266:
    case 267:
    case 268:
    case 269:
    case 270:
    case 271:
    case 272:
    case 273:
    case 274:
    case 275:
    case 276:
    case 277:
    case 278:
    case 279:
    case 280:
    case 281:
    case 282:
    case 283:
    case 284:
    case 285:
    case 286:
    case 287:
    case 288:
    case 289:
    case 290:
    case 290:
    case 292:
    case 293:
    case 294:
    case 295:
    case 297:
    case 298:
    case 299:
    case 300:
    case 301:
      categories = [
        'Conference',
        'Donation',
        'Fees',
        'Fireside Chat',
        'Global Development',
        'Hack Night',
        'Hackathon',
        'Leadership Development',
        'Leadership Supplies',
        'Lightning Talks',
        'Scholarship',
        'Speaker Series',
        'Sponsorship',
        'Tech Panel',
        'Transaction Fees',
        'Study Group',
        'Workshop',
        'Other WWCode Event',
        'Other'
      ];
      break;
    case 6: // laprimaire
    case 73: // nuitdebout
    case 24: // lesbarbares
      categories = [
        'Admin',
        'Autre',
        'Communication',
        'Déplacement',
        'Marketing',
        'NDD',
        'Outils',
        'PI',
        'Papeterie',
        'Représentation',
        'Serveur',
        'Transport'
      ];
       break;
    case 114: // partidodigital
      categories = [
        'Comunicación',
        'Diseño',
        'Aporte',
        'Sistemas',
        'Fondos',
        'Alimentos y Bebidas',
        'Marketing',
        'Legales',
        'Suministros & materiales',
        'Viajes',
        'Equipo',
        'Oficina',
        'Otros',
        'Servicios Digitales'
      ];
      break;
    case 245: // analizebasilicata
      categories = [
        'Comunicazioni',
        'Disign',
        'Donazione',
        'Sviluppo software',
        'Accantonamento',
        'Cibo & bevande',
        'Marketing',
        'Legale',
        'Forniture & materiali',
        'Viaggio',
        'Squadra',
        'Ufficio',
        'Altro',
        'Servizi web'
      ];
      break;
    default:
      categories = [
        'Communications',
        'Design',
        'Donation',
        'Engineering',
        'Fund',
        'Food & Beverage',
        'Marketing',
        'Legal',
        'Supplies & materials',
        'Travel',
        'Team',
        'Office',
        'Other',
        'Web services'
      ];
  }
  return categories.sort();
}
<|endoftext|>


<commit_before>var initDrawer = function initDrawer() {
  var data = {
    color: 'aliceBlue',
    shapes: {},
    currentShape: null,
    newShapes: [],
    modifiedShape: null,
    remoteShapes: []
  };

  var ShapeTypes = {line: 'line', path: 'path', rect: 'rect', circle: 'circle'};
  var LineTypes = {round: 'round'};
  var Colors = {black: 'black', red: 'red', blue: 'blue', green: 'green', purple: 'purple', yellow: 'yellow', white: 'white', aliceblue: 'aliceblue'};

  //returns 4 digit guid string
  var getGuid = function getGuid() {
    const chars = 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890';
    var codes = [0, 0, 0, 0];

    codes = codes.map(function (code) {
      return chars[Math.floor(Math.random() * chars.length)];
    });

    return codes.join('');
  };

  class Point {
    constructor(x, y) {
      this.x = x;
      this.y = y;
    }
  }

  class Shape {
    constructor(type, points, strokeColor, fillColor) {
      this.type = type;
      this.points = points;
      this.radius = 0;
      this.lineWidth = 2;
      this.lineJoin = LineTypes.round;
      this.lineCap = LineTypes.round;
      this.strokeColor = strokeColor;
      this.fillColor = fillColor;
      this.guid = getGuid();
    }
  }

  class Drawer {

    constructor(canvas, data) {
      this.canvas = canvas;
      // this.shapes = shapes;
      this.data = data;
      data = this.data;
      this.isDrawing = false;
      this.currentShapeType = ShapeTypes.path;
      this.isSelecting = false;
      this.ShapeTypes = ShapeTypes;
      this.LineTypes = LineTypes;
      this.Colors = Colors;
      this.fillColor = null;
      this.strokeColor = Colors.red;
      this.colorStroke = 'stroke';
      // keep this last so state is setup to hanlde drawing
      this.addListeners();
    }

    changeShapeType(type) {
      if (this.isSelecting) {
        this.toggleIsSelecting();
      }

      this.currentShapeType = type;
    }

    toggleStrokeFill(type) {
      this.colorStroke = type;
      this.changeColor(this.strokeColor || this.fillColor);
    }

    changeColor(color) {
      if (this.colorStroke === 'stroke') {
        this.strokeColor = color;
        this.fillColor = null;
      } else {
        this.fillColor = color;
        this.strokeColor = null;
      }
    }

    toggleIsSelecting() {
      this.isSelecting = !this.isSelecting;
      if (this.isSelecting) {
        this.canvas.style.cursor = 'pointer';
      } else {
        this.canvas.style.cursor = 'default';
      }
    }

    getSelectedShape(mousePoint) {
      var selectedShape = null;

      for (var key in this.data.shapes) {
        var shape = this.data.shapes[key];
        var test = false;

        if (shape.type === ShapeTypes.rect && shape.points.length > 1) {
          var p1 = shape.points[0];
          var p2 = shape.points[1];

          if (mousePoint.x > p1.x && mousePoint.x < p2.x || mousePoint.x < p1.x && mousePoint.x > p2.x) {
            if (mousePoint.y > p1.y && mousePoint.y < p2.y || mousePoint.y < p1.y && mousePoint.y > p2.y) {
              test = true;
            }
          }

        } else if (shape.type === ShapeTypes.circle) {
          // pythagorean theorem
          var center = shape.points[0];
          var a = mousePoint.x - center.x;
          var b = mousePoint.y - center.y;
          var hyp = Math.sqrt(Math.pow(a, 2) + Math.pow(b, 2));
          test = hyp < shape.radius;
        }

        if (test) {
          selectedShape = shape;
          selectedShape.offsetX = a;
          selectedShape.offsetY = b;
          break;
        }
      }

      this.data.modifiedShape = selectedShape;
    }

    moveSelectedShape(mousePoint) {
      var shape = this.data.modifiedShape;

      if (!shape) {
        return;
      }

      if (shape.type === ShapeTypes.rect) {
        var p1 = shape.points[0];
        var p2 = shape.points[1];
        var width = p2.x - p1.x;
        var height = p2.y - p1.y;

        p1.x = mousePoint.x;
        p1.y = mousePoint.y;
        p2.x = mousePoint.x + width;
        p2.y = mousePoint.y + height;
      } else if (shape.type === ShapeTypes.circle) {
        shape.points[0].x = mousePoint.x - shape.offsetX;
        shape.points[0].y = mousePoint.y - shape.offsetY;
      }
    }

    // mouse events & helpers ###########

    getMousePoint(e) {
      var rect = this.canvas.getBoundingClientRect();
      // get the mouse point and remove offset of canvas in window
      var x = (e.clientX - rect.left) / (rect.right - rect.left) * this.canvas.width;
      var y = (e.clientY - rect.top) / (rect.bottom - rect.top) * this.canvas.height;
      return new Point(x, y);
    }

    handleMouseUp(e) {
      this.isDrawing = false;

      if (this.isSelecting) {
        return;
      }

      var shape = this.data.currentShape;

      if (!shape) {
        return;
      }

      if (shape && (shape.mode === ShapeTypes.rect || shape.mode === ShapeTypes.line)) {
        if (shape.points.length > 1) {
          shape.points.pop();
        }
        var point = this.getMousePoint(e);
        shape.points.push(point);
      }

      shape.done = true;
      this.data.newShapes.push(shape);
      // this.data.currentShape = null;

      console.log('SHAPE COUNT: ', this.data.newShapes.length);
    }

    handleMouseDown(e) {
      this.isDrawing = true;
      var mousePoint = this.getMousePoint(e);

      // if we are selecting
      if (this.isSelecting) {
        this.getSelectedShape(mousePoint);
        return;
      }

      var points = [mousePoint];
      this.data.currentShape = new Shape(this.currentShapeType, points,
        this.strokeColor, this.fillColor);

      // this.shapes.push(this.currentShape);
    }

    handleMouseMove(e) {

      if (!this.isDrawing) { return; }
      var mousePoint = this.getMousePoint(e);
      var shape = this.data.currentShape;

      if (this.isSelecting) {
        this.moveSelectedShape(mousePoint);
        return;
      }

      if (shape.type === ShapeTypes.path) {
        // paths get every point of move
        shape.points.push(mousePoint);
      } else if (shape.type === ShapeTypes.rect) {
        // rect's only have 2 points max
        if (shape.points.length > 1) {
          shape.points.pop();
        }

        shape.points.push(mousePoint);
      } else if (shape.type === ShapeTypes.circle) {
        // circles have one center point and a radius
        var center = shape.points[0];
        var distX = mousePoint.x - center.x;
        var distY = mousePoint.y - center.y;
        shape.radius = Math.abs(distX > distY ? distX : distY);
      } else if (shape.type === ShapeTypes.line) {
        // lines have 2 points max
        if (shape.points.length > 1) {
          shape.points.pop();
        }

        shape.points.push(mousePoint);
      }
    }

    addListeners() {
      this.canvas.addEventListener('mousedown',
        this.handleMouseDown.bind(this));
      this.canvas.addEventListener('mouseup',
        this.handleMouseUp.bind(this));
      this.canvas.addEventListener('mouseout',
        function () { this.isDrawing = false; }.bind(this));
      this.canvas.addEventListener('mousemove',
        this.handleMouseMove.bind(this));
    }
  }

  var canvas = document.getElementById('draw-canvas');

  return new Drawer(canvas, data);
};

export default initDrawer;
<commit_msg>extend offset drag functionality to rectangle dragging<commit_after>var initDrawer = function initDrawer() {
  var data = {
    color: 'aliceBlue',
    shapes: {},
    currentShape: null,
    newShapes: [],
    modifiedShape: null,
    remoteShapes: []
  };

  var ShapeTypes = {line: 'line', path: 'path', rect: 'rect', circle: 'circle'};
  var LineTypes = {round: 'round'};
  var Colors = {black: 'black', red: 'red', blue: 'blue', green: 'green', purple: 'purple', yellow: 'yellow', white: 'white', aliceblue: 'aliceblue'};

  //returns 4 digit guid string
  var getGuid = function getGuid() {
    const chars = 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890';
    var codes = [0, 0, 0, 0];

    codes = codes.map(function (code) {
      return chars[Math.floor(Math.random() * chars.length)];
    });

    return codes.join('');
  };

  class Point {
    constructor(x, y) {
      this.x = x;
      this.y = y;
    }
  }

  class Shape {
    constructor(type, points, strokeColor, fillColor) {
      this.type = type;
      this.points = points;
      this.radius = 0;
      this.lineWidth = 2;
      this.lineJoin = LineTypes.round;
      this.lineCap = LineTypes.round;
      this.strokeColor = strokeColor;
      this.fillColor = fillColor;
      this.guid = getGuid();
    }
  }

  class Drawer {

    constructor(canvas, data) {
      this.canvas = canvas;
      // this.shapes = shapes;
      this.data = data;
      data = this.data;
      this.isDrawing = false;
      this.currentShapeType = ShapeTypes.path;
      this.isSelecting = false;
      this.ShapeTypes = ShapeTypes;
      this.LineTypes = LineTypes;
      this.Colors = Colors;
      this.fillColor = null;
      this.strokeColor = Colors.red;
      this.colorStroke = 'stroke';
      // keep this last so state is setup to hanlde drawing
      this.addListeners();
    }

    changeShapeType(type) {
      if (this.isSelecting) {
        this.toggleIsSelecting();
      }

      this.currentShapeType = type;
    }

    toggleStrokeFill(type) {
      this.colorStroke = type;
      this.changeColor(this.strokeColor || this.fillColor);
    }

    changeColor(color) {
      if (this.colorStroke === 'stroke') {
        this.strokeColor = color;
        this.fillColor = null;
      } else {
        this.fillColor = color;
        this.strokeColor = null;
      }
    }

    toggleIsSelecting() {
      this.isSelecting = !this.isSelecting;
      if (this.isSelecting) {
        this.canvas.style.cursor = 'pointer';
      } else {
        this.canvas.style.cursor = 'default';
      }
    }

    getSelectedShape(mousePoint) {
      var selectedShape = null;

      for (var key in this.data.shapes) {
        var shape = this.data.shapes[key];
        var test = false;

        if (shape.type === ShapeTypes.rect && shape.points.length > 1) {
          var p1 = shape.points[0];
          var p2 = shape.points[1];

          if (mousePoint.x > p1.x && mousePoint.x < p2.x || mousePoint.x < p1.x && mousePoint.x > p2.x) {
            if (mousePoint.y > p1.y && mousePoint.y < p2.y || mousePoint.y < p1.y && mousePoint.y > p2.y) {
              test = true;
            }
          }

        } else if (shape.type === ShapeTypes.circle) {
          // pythagorean theorem
          var center = shape.points[0];
          var a = mousePoint.x - center.x;
          var b = mousePoint.y - center.y;
          var hyp = Math.sqrt(Math.pow(a, 2) + Math.pow(b, 2));
          test = hyp < shape.radius;
        }

        if (test) {
          selectedShape = shape;

          if (selectedShape.type === ShapeTypes.circle) {
            selectedShape.offsetX = a;
            selectedShape.offsetY = b;
          }
          if (selectedShape.type === ShapeTypes.rect) {
            selectedShape.offsetX = mousePoint.x - p1.x;
            selectedShape.offsetY = mousePoint.y - p1.y;
          }

          break;
        }
      }

      this.data.modifiedShape = selectedShape;
    }

    moveSelectedShape(mousePoint) {
      var shape = this.data.modifiedShape;

      if (!shape) {
        return;
      }

      if (shape.type === ShapeTypes.rect) {
        var p1 = shape.points[0];
        var p2 = shape.points[1];
        var width = p2.x - p1.x;
        var height = p2.y - p1.y;

        p1.x = mousePoint.x - shape.offsetX;
        p1.y = mousePoint.y - shape.offsetY;
        p2.x = p1.x + width;
        p2.y = p1.y + height;
      } else if (shape.type === ShapeTypes.circle) {
        shape.points[0].x = mousePoint.x - shape.offsetX;
        shape.points[0].y = mousePoint.y - shape.offsetY;
      }
    }

    // mouse events & helpers ###########

    getMousePoint(e) {
      var rect = this.canvas.getBoundingClientRect();
      // get the mouse point and remove offset of canvas in window
      var x = (e.clientX - rect.left) / (rect.right - rect.left) * this.canvas.width;
      var y = (e.clientY - rect.top) / (rect.bottom - rect.top) * this.canvas.height;
      return new Point(x, y);
    }

    handleMouseUp(e) {
      this.isDrawing = false;

      if (this.isSelecting) {
        return;
      }

      var shape = this.data.currentShape;

      if (!shape) {
        return;
      }

      if (shape && (shape.mode === ShapeTypes.rect || shape.mode === ShapeTypes.line)) {
        if (shape.points.length > 1) {
          shape.points.pop();
        }
        var point = this.getMousePoint(e);
        shape.points.push(point);
      }

      shape.done = true;
      this.data.newShapes.push(shape);
      // this.data.currentShape = null;

      console.log('SHAPE COUNT: ', this.data.newShapes.length);
    }

    handleMouseDown(e) {
      this.isDrawing = true;
      var mousePoint = this.getMousePoint(e);

      // if we are selecting
      if (this.isSelecting) {
        this.getSelectedShape(mousePoint);
        return;
      }

      var points = [mousePoint];
      this.data.currentShape = new Shape(this.currentShapeType, points,
        this.strokeColor, this.fillColor);

      // this.shapes.push(this.currentShape);
    }

    handleMouseMove(e) {

      if (!this.isDrawing) { return; }
      var mousePoint = this.getMousePoint(e);
      var shape = this.data.currentShape;

      if (this.isSelecting) {
        this.moveSelectedShape(mousePoint);
        return;
      }

      if (shape.type === ShapeTypes.path) {
        // paths get every point of move
        shape.points.push(mousePoint);
      } else if (shape.type === ShapeTypes.rect) {
        // rect's only have 2 points max
        if (shape.points.length > 1) {
          shape.points.pop();
        }

        shape.points.push(mousePoint);
      } else if (shape.type === ShapeTypes.circle) {
        // circles have one center point and a radius
        var center = shape.points[0];
        var distX = mousePoint.x - center.x;
        var distY = mousePoint.y - center.y;
        shape.radius = Math.abs(distX > distY ? distX : distY);
      } else if (shape.type === ShapeTypes.line) {
        // lines have 2 points max
        if (shape.points.length > 1) {
          shape.points.pop();
        }

        shape.points.push(mousePoint);
      }
    }

    addListeners() {
      this.canvas.addEventListener('mousedown',
        this.handleMouseDown.bind(this));
      this.canvas.addEventListener('mouseup',
        this.handleMouseUp.bind(this));
      this.canvas.addEventListener('mouseout',
        function () { this.isDrawing = false; }.bind(this));
      this.canvas.addEventListener('mousemove',
        this.handleMouseMove.bind(this));
    }
  }

  var canvas = document.getElementById('draw-canvas');

  return new Drawer(canvas, data);
};

export default initDrawer;
<|endoftext|>


<commit_before>'use strict';

const path = require('path');
const util = require('util');

const log = require('debug')('nodejs-team:drive-sequelize');
const error = require('debug')('nodejs-team:error');

var models = require('../models/index');
var Drive = require('../models/drive');
var sequelize = require('sequelize');

exports.create = function(id, name, path, type, size) {
  return new Promise((resolve, reject) => {
    models.Drive.create({
      parent_id: id,
      name: name,
      path: path,
      fileType: type,
      size: size
    }).then(function(drive) {
      if (drive)
        resolve(drive);
      else {
        reject(`Error while creating a Drive model`);
      }
    });
  });
};

exports.get_drive = function(id) {
  return new Promise((resolve, reject) => {
    models.Drive.find({
      where: {
        id: id
      }
    }).then(function(drive) {
      if (drive)
        resolve(drive);
      else {
        reject(`Error while get drive`);
      }
    });
  });
};

exports.getFilePath = function(id) {
  console.log("getFilePath" + id);
  return models.Drive.find({
    where: {
      id: id
    }
  })

}
/*
exports.list = function(sourceId) {
  return new Promise((resolve, reject) => {
    var isFile;
    console.log(`ID:${sourceId}`)

    // Find the name of the file/folder that we're moving
    models.Drive.findById(sourceId).then(function(sourceRow) {
      if (sourceRow || sourceId == 0) {
        isFile = (sourceId == 0) ? 1 : sourceRow.fileType;
        if (isFile == 1) {
          // A folder list has been requested, so find everything that has this folder as a parent
          models.Drive.findAll({
            where: {
              parent_id: sourceId
            }
          }).then(function(drives) {
            if (drives)
              resolve(drives);
            else {
              // This case covers when a folder is empty and thus intentionally returns an empty result,
              // which indicates that the folder is empty.
              resolve(drives);
            }
          });
        } else if (isFile == 2) {
          // An individual file has been requested, so send back the data that we already have
          resolve(sourceRow);
        } else {
          // Someone goofed somewhere and the database has an invalid fileType, so complain!
          var msg = `Error: Unknown fileType detected:${isFile}`;
          console.log(msg);
          reject(msg);
        }
      } else {
        var msg = `Failed to find "name" data for sourceId:${sourceId}`;
        console.log(msg);
        reject(msg);
      }
    });
  });
};
*/

exports.list = function(id) {
  console.log('id'+id);
    var x = getFilePath(id);
    return new Promise((resolve, reject) => {
    x.then(p_drive => {
      models.Drive.findAll({
        where: {
          parent_id: id
        }
      }).then(function(drive) {
      //  console.log('drrrive'+drive);
        if(drive){
            resolve(drive);
        }else {
          reject(`Error while find a parent Drive model`);
        }
        }).catch(err => {
          reject(`Error while find a parent Drive model`);
        });
      });
    });
    };

exports.get_childdrive = function(id) {
  if (id == 0) {
    return new Promise((resolve, reject) => {
      models.Drive.find({

        where: {
          parent_id: id
        }
      }).then(function(drive) {
        if (drive)
          resolve(drive);
        else {
          reject(`Error while get drive`);
        }
      }).catch(err => {
        reject(`Error while get drive`);
      });
    });
} else {
  return new Promise((resolve, reject) => {
    models.Drive.find({
      where: {
        id: id
      }
    }).then(function(drive) {
      if (drive)
        resolve(drive);
      else {
        reject(`Error while get drive`);
      }
    }).catch(err => {
      reject(`Error while get drive`);
    });
  });

}
};
exports.get_parent = function(id) {
  return new Promise((resolve, reject) => {
    models.Drive.find({
      where: {
        id: id,
        fileType: 1
      }
    }).then(function(drive) {
      if (drive)
        resolve(drive);
      else {
        reject(`Error while find a parent Drive model`);
      }
    });
  });
};

exports.multiple = function(id, isFile) {
  console.log('IsFile' + isFile);

  var p;
  if (!isFile) {
    var c = delete_file(id);
    return c;
  } else {
    var x = getFilePath(id);
    console.log('else');
    const Op = sequelize.Op;
    x.then(p_drive => {
      models.Drive.findAll({
        where: {
          path: {
            [Op.like]: p_drive.dataValues.path + '%'
          }
        }
      }).then(function(drive) {
        Object.keys(drive).forEach(function(key) {
          var val = drive[key];
          p = delete_file(val.id);
          console.log('sdddd' + p);
        }).catch(err => {
          reject(err);
        });
      });
    }).catch(err => {
      reject(err);
    });
  }

  return x;
};

var delete_file = function(id) {
  console.log("delete with id" + id);
  return new Promise((resolve, reject) => {
    models.Drive.destroy({
      where: {
        id: id
      }
    }).then(affectedRows => {
      console.log('affected' + affectedRows);
      if (affectedRows == 1)
        resolve(`Deleted Successfully`);
      else {
        reject(`Unable to find a matching Drive model`);
      }
      return affectedRows;
    });
  });
};

var getFilePath = function(id) {
  console.log("getFilePath" + id);
  return models.Drive.find({
    where: {
      id: id
    }
  })
};

exports.update_SHA = function(id, sha) {
  return new Promise((resolve, reject) => {
    models.Drive.update({
      sha_256: sha
    }, {
      where: {
        id: id
      }
    }).then(function(drive) {
      console.log(`Return value : ${drive}`);
      if (drive == 0) {
        reject(`Failed to update SHA`);
      } else {
        resolve(`Updated successfully`);
      }
    });
  });
};

exports.move = function(sourceId, destPath) {
  console.log(`sourceId:${sourceId}  destPath:${destPath}`)

  return new Promise((resolve, reject) => {

    var destRootPath = path.join(__dirname, '../public/cloud/');
    var destSearchPath;
    var destFullPath;
    var destFileName;
    var sourceFileType;
    var sourceRootPath;
    var msg;

    // First perform basic error checking on the parameters
    if (sourceId <= 0) {
      msg = `Invalid sourceId:${sourceId}`;
      console.log(msg);
      return reject(msg);
    } else if (!destPath) {
      msg = `Invalid destPath:'${destPath}'`;
      console.log(msg);
      return reject(msg);
    }

    // Find the name of the source file/folder that we're moving
    models.Drive.findById(sourceId).then(function(sourceRow) {
      if (sourceRow) {
        destFileName = sourceRow.name;
        sourceFileType = sourceRow.fileType;
        sourceRootPath = sourceRow.path;
      } else {
        msg = `Failed to find data for sourceId:${sourceId}`;
        console.log(msg);
        return reject(msg);
      }

      destSearchPath = path.join(destPath, '/');
      console.log(`destSearchPath: '${destSearchPath}'`);

      // Find new parent ID
      var destParentId;
      var destFileType;
      models.Drive.find({
        where: {
          path: destSearchPath
        }
      }).then(function(destRow) {
        if (destRow) {
          // Found the path specified, use it's ID as the new parentId
          destParentId = destRow.id;
          destFileType = destRow.fileType;
        } else if (destRootPath == destSearchPath) {
          // The path was not found, but it's the same as the root,
          // so set the root (0) as the parentId
          destParentId = 0;
          destFileType = 1;
        } else {
          // Unable to find the path
          msg = `Failed to find data for destPath:${destSearchPath}`;
          console.log(msg);
          return reject(msg);
        }

        // Sanity check -- validate that we can actually move from the source
        // to the specified destination
        if (sourceRow.id == destParentId) {
          msg = `Cannot move sourceId:${sourceId} to the same file/folder! (destSearchPath: '${destSearchPath}')`;
          console.log(msg);
          return reject(msg);
        } else if (sourceRow.parent_id == destParentId) {
          msg = `Cannot move sourceId:${sourceId} to the same parent folder! (destSearchPath: '${destSearchPath}')`;
          console.log(msg);
          return reject(msg);
        } else if (destFileType != 1) {
          msg = `Cannot move sourceId:${sourceId} to an existing file!`;
          console.log(msg);
          return reject(msg);
        } else if (destSearchPath.indexOf(sourceRootPath) >= 0) {
          msg = `Cannot move sourceId:${sourceId} to a path within itself! (destSearchPath: '${destSearchPath}')`;
          console.log(msg);
          return reject(msg);
        }

        // Build the path from the filename and destination path
        destFullPath = path.join(destSearchPath, destFileName);
        if (sourceFileType == 1) {
          // Destination is a path, so make sure there's a trailing slash
          destFullPath = path.join(destFullPath, '/');
        }

        console.log(`destFullPath: '${destFullPath}'`);

        // Update the source file/folder in the database with the new path and parentId
        models.Drive.update({
          parent_id: destParentId,
          path: destFullPath
        }, {
          where: {
            id: sourceId
          }
        }).then(function(moved) {
          if (moved != 0) {
            msg = `Moved id:${sourceId} to new parent:${destParentId}`;
            console.log(msg);

            // If we're moving a folder, then we need to update the paths for each of
            // it's children as well to reflect the new location.
            if (sourceFileType == 1) {

              // When querying for a string with backslashes, they need to be doubled up,
              // even if they already look doubled up in anything output to the console.
              // For example, if we search for C:\\SOME\\PATH then we need to actually look
              // for C:\\\\SOME\\\\PATH in order for the search to be successful.
              var pattern = /\\/g;
              var sqlSearchPath = sourceRootPath.replace(pattern, "\\\\");
              console.log(`sqlSearchPath: '${sqlSearchPath}'`);

              // Find all records that match the path we're looking for
              const Op = sequelize.Op;
              models.Drive.findAll({
                where: {
                  path: {
                    [Op.like]: sqlSearchPath + '%'
                  }
                }
              }).then(function(results) {
                // Loop through each record and update the path
                var promises = [];
                Object.keys(results).forEach(function(key) {
                  var val = results[key];
                  var updatedPath = val.path.replace(sourceRootPath, destFullPath);
                  console.log(`UPDATED PATH: '${updatedPath}'`);
                  val.updateAttributes({path: updatedPath});
                });

                resolve("Move completed successfully");

              }).catch(err => {
                console.log("Error caught: " + err);
                reject(err);
              });
            } else {
              // File has been successfully moved, so we're done!
              resolve(msg);
            }
          } else {
            msg = `Failed to move id:${sourceId} to new parent:${destParentId}`;
            console.log(msg);
            reject(msg);
          }
        });
      });
    });
  });
};
<commit_msg>Update Move to move the actual files on the server<commit_after>'use strict';

const path = require('path');
const util = require('util');

const log = require('debug')('nodejs-team:drive-sequelize');
const error = require('debug')('nodejs-team:error');
const fsx = require("fs-extra");

var models = require('../models/index');
var Drive = require('../models/drive');
var sequelize = require('sequelize');

exports.create = function (id, name, path, type, size) {
  return new Promise((resolve, reject) => {
    models.Drive.create({
      parent_id: id,
      name: name,
      path: path,
      fileType: type,
      size: size
    }).then(function (drive) {
      if (drive)
        resolve(drive);
      else {
        reject(`Error while creating a Drive model`);
      }
    });
  });
};

exports.get_drive = function (id) {
  return new Promise((resolve, reject) => {
    models.Drive.find({
      where: {
        id: id
      }
    }).then(function (drive) {
      if (drive)
        resolve(drive);
      else {
        reject(`Error while get drive`);
      }
    });
  });
};

exports.getFilePath = function (id) {
  console.log("getFilePath" + id);
  return models.Drive.find({
    where: {
      id: id
    }
  })

}
/*
exports.list = function(sourceId) {
  return new Promise((resolve, reject) => {
    var isFile;
    console.log(`ID:${sourceId}`)

    // Find the name of the file/folder that we're moving
    models.Drive.findById(sourceId).then(function(sourceRow) {
      if (sourceRow || sourceId == 0) {
        isFile = (sourceId == 0) ? 1 : sourceRow.fileType;
        if (isFile == 1) {
          // A folder list has been requested, so find everything that has this folder as a parent
          models.Drive.findAll({
            where: {
              parent_id: sourceId
            }
          }).then(function(drives) {
            if (drives)
              resolve(drives);
            else {
              // This case covers when a folder is empty and thus intentionally returns an empty result,
              // which indicates that the folder is empty.
              resolve(drives);
            }
          });
        } else if (isFile == 2) {
          // An individual file has been requested, so send back the data that we already have
          resolve(sourceRow);
        } else {
          // Someone goofed somewhere and the database has an invalid fileType, so complain!
          var msg = `Error: Unknown fileType detected:${isFile}`;
          console.log(msg);
          reject(msg);
        }
      } else {
        var msg = `Failed to find "name" data for sourceId:${sourceId}`;
        console.log(msg);
        reject(msg);
      }
    });
  });
};
*/

exports.list = function (id) {
  console.log('id' + id);
  var x = getFilePath(id);
  return new Promise((resolve, reject) => {
    x.then(p_drive => {
      models.Drive.findAll({
        where: {
          parent_id: id
        }
      }).then(function (drive) {
        //  console.log('drrrive'+drive);
        if (drive) {
          resolve(drive);
        } else {
          reject(`Error while find a parent Drive model`);
        }
      }).catch(err => {
        reject(`Error while find a parent Drive model`);
      });
    });
  });
};

exports.get_childdrive = function (id) {
  if (id == 0) {
    return new Promise((resolve, reject) => {
      models.Drive.find({

        where: {
          parent_id: id
        }
      }).then(function (drive) {
        if (drive)
          resolve(drive);
        else {
          reject(`Error while get drive`);
        }
      }).catch(err => {
        reject(`Error while get drive`);
      });
    });
  } else {
    return new Promise((resolve, reject) => {
      models.Drive.find({
        where: {
          id: id
        }
      }).then(function (drive) {
        if (drive)
          resolve(drive);
        else {
          reject(`Error while get drive`);
        }
      }).catch(err => {
        reject(`Error while get drive`);
      });
    });

  }
};
exports.get_parent = function (id) {
  return new Promise((resolve, reject) => {
    models.Drive.find({
      where: {
        id: id,
        fileType: 1
      }
    }).then(function (drive) {
      if (drive)
        resolve(drive);
      else {
        reject(`Error while find a parent Drive model`);
      }
    });
  });
};

exports.multiple = function (id, isFile) {
  console.log('IsFile' + isFile);

  var p;
  if (!isFile) {
    var c = delete_file(id);
    return c;
  } else {
    var x = getFilePath(id);
    console.log('else');
    const Op = sequelize.Op;
    x.then(p_drive => {
      models.Drive.findAll({
        where: {
          path: {
            [Op.like]: p_drive.dataValues.path + '%'
          }
        }
      }).then(function (drive) {
        Object.keys(drive).forEach(function (key) {
          var val = drive[key];
          p = delete_file(val.id);
          console.log('sdddd' + p);
        }).catch(err => {
          reject(err);
        });
      });
    }).catch(err => {
      reject(err);
    });
  }

  return x;
};

var delete_file = function (id) {
  console.log("delete with id" + id);
  return new Promise((resolve, reject) => {
    models.Drive.destroy({
      where: {
        id: id
      }
    }).then(affectedRows => {
      console.log('affected' + affectedRows);
      if (affectedRows == 1)
        resolve(`Deleted Successfully`);
      else {
        reject(`Unable to find a matching Drive model`);
      }
      return affectedRows;
    });
  });
};

var getFilePath = function (id) {
  console.log("getFilePath" + id);
  return models.Drive.find({
    where: {
      id: id
    }
  })
};

exports.update_SHA = function (id, sha) {
  return new Promise((resolve, reject) => {
    models.Drive.update({
      sha_256: sha
    }, {
        where: {
          id: id
        }
      }).then(function (drive) {
        console.log(`Return value : ${drive}`);
        if (drive == 0) {
          reject(`Failed to update SHA`);
        } else {
          resolve(`Updated successfully`);
        }
      });
  });
};

exports.move = function (sourceId, destPath) {
  console.log(`sourceId:${sourceId}  destPath:${destPath}`)

  return new Promise((resolve, reject) => {

    var destRootPath = path.join(__dirname, '../public/cloud/');
    var destSearchPath;
    var destFullPath;
    var destFileName;
    var sourceFileType;
    var sourceRootPath;
    var msg;

    // First perform basic error checking on the parameters
    if (sourceId <= 0) {
      msg = `Invalid sourceId:${sourceId}`;
      console.log(msg);
      return reject(msg);
    } else if (!destPath) {
      msg = `Invalid destPath:'${destPath}'`;
      console.log(msg);
      return reject(msg);
    }

    // Find the name of the source file/folder that we're moving
    models.Drive.findById(sourceId).then(function (sourceRow) {
      if (sourceRow) {
        destFileName = sourceRow.name;
        sourceFileType = sourceRow.fileType;
        sourceRootPath = sourceRow.path;
      } else {
        msg = `Failed to find data for sourceId:${sourceId}`;
        console.log(msg);
        return reject(msg);
      }

      destSearchPath = path.join(destPath, '/');
      console.log(`destSearchPath: '${destSearchPath}'`);

      // Find new parent ID
      var destParentId;
      var destFileType;
      models.Drive.find({
        where: {
          path: destSearchPath
        }
      }).then(function (destRow) {
        if (destRow) {
          // Found the path specified, use it's ID as the new parentId
          destParentId = destRow.id;
          destFileType = destRow.fileType;
        } else if (destRootPath == destSearchPath) {
          // The path was not found, but it's the same as the root,
          // so set the root (0) as the parentId
          destParentId = 0;
          destFileType = 1;
        } else {
          // Unable to find the path
          msg = `Failed to find data for destPath:${destSearchPath}`;
          console.log(msg);
          return reject(msg);
        }

        // Sanity check -- validate that we can actually move from the source
        // to the specified destination
        if (sourceRow.id == destParentId) {
          msg = `Cannot move sourceId:${sourceId} to the same file/folder! (destSearchPath: '${destSearchPath}')`;
          console.log(msg);
          return reject(msg);
        } else if (sourceRow.parent_id == destParentId) {
          msg = `Cannot move sourceId:${sourceId} to the same parent folder! (destSearchPath: '${destSearchPath}')`;
          console.log(msg);
          return reject(msg);
        } else if (destFileType != 1) {
          msg = `Cannot move sourceId:${sourceId} to an existing file!`;
          console.log(msg);
          return reject(msg);
        } else if (destSearchPath.indexOf(sourceRootPath) >= 0) {
          msg = `Cannot move sourceId:${sourceId} to a path within itself! (destSearchPath: '${destSearchPath}')`;
          console.log(msg);
          return reject(msg);
        }

        // Build the path from the filename and destination path
        destFullPath = path.join(destSearchPath, destFileName);
        if (sourceFileType == 1) {
          // Destination is a path, so make sure there's a trailing slash
          destFullPath = path.join(destFullPath, '/');
        }

        console.log(`destFullPath: '${destFullPath}'`);

        // Update the source file/folder in the database with the new path and parentId
        models.Drive.update({
          parent_id: destParentId,
          path: destFullPath
        }, {
            where: {
              id: sourceId
            }
          }).then(function (moved) {
            if (moved != 0) {
              msg = `Moved id:${sourceId} to new parent:${destParentId}`;
              console.log(msg);

              // If we're moving a folder, then we need to update the paths for each of
              // it's children as well to reflect the new location.
              if (sourceFileType == 1) {

                // When querying for a string with backslashes, they need to be doubled up,
                // even if they already look doubled up in anything output to the console.
                // For example, if we search for C:\\SOME\\PATH then we need to actually look
                // for C:\\\\SOME\\\\PATH in order for the search to be successful.
                var pattern = /\\/g;
                var sqlSearchPath = sourceRootPath.replace(pattern, "\\\\");
                console.log(`sqlSearchPath: '${sqlSearchPath}'`);

                // Find all records that match the path we're looking for
                const Op = sequelize.Op;
                models.Drive.findAll({
                  where: {
                    path: {
                      [Op.like]: sqlSearchPath + '%'
                    }
                  }
                }).then(function (results) {
                  // Loop through each record and update the path
                  var promises = [];
                  Object.keys(results).forEach(function (key) {
                    var val = results[key];
                    var updatedPath = val.path.replace(sourceRootPath, destFullPath);
                    console.log(`UPDATED PATH: '${updatedPath}'`);
                    val.updateAttributes({ path: updatedPath });
                  });

                  // Now move the actual folder on the server
                  fsx.move(sourceRootPath, destFullPath, function (err) {
                    if (err) {
                      console.log(err);
                      reject(err);
                    } else {
                      resolve("Move completed successfully");
                    }
                  });
                }).catch(err => {
                  console.log("Error caught: " + err);
                  reject(err);
                });
              } else {
                // Now move the actual file on the server
                fsx.move(sourceRootPath, destFullPath, function (err) {
                  if (err) {
                    console.log(err);
                    reject(err);
                  } else {
                    // File has been successfully moved, so we're done!
                    resolve(msg);
                  }
                });
              }
            } else {
              msg = `Failed to move id:${sourceId} to new parent:${destParentId}`;
              console.log(msg);
              reject(msg);
            }
          });
      });
    });
  });
};
<|endoftext|>