<commit_before>var co = require('co');
var _ = require('underscore');

module.exports = (app) => {

  app.config(['$stateProvider', '$urlRouterProvider', ($stateProvider, $urlRouterProvider) => {

    // States
    $stateProvider.
    state('index', {
      url: '/',
      template: require('views/index'),
      resolve: {
        ws: (Webmin) => Webmin.ws(),
        summary: (Webmin) => Webmin.summary()
      },
      controller: 'IndexController'
    }).

    state('about', {
      url: '/about',
      template: require('views/about'),
      resolve: {
        summary: (Webmin) => Webmin.summary(),
        version: (summary) => summary && 'v' + summary.version || 'unknown version'
      },
      controller: 'AboutController'
    }).

    state('configure', {
      abstract: true,
      url: '/configure',
      template: require('views/init/layout'),
      controller: ($scope) => {
        $scope.conf = {
          currency: 'super_currency',
          c: 0.007376575,
          dt: 30.4375 * 24 * 3600,
          ud0: 100,
          stepMax: 3,
          sigDelay: 3600 * 24 * 365 * 5,
          sigPeriod: 0, // Instant
          sigStock: 40,
          sigWindow: 3600 * 24 * 14, // 2 weeks
          sigValidity: 3600 * 24 * 365,
          msValidity: 3600 * 24 * 365,
          sigQty: 0,
          xpercent: 0.9,
          percentRot: 0.66,
          blocksRot: 20,
          avgGenTime: 16 * 60,
          dtDiffEval: 10,
          medianTimeBlocks: 20
        };
      }
    }).

    state('configure.choose', {
      url: '/choose',
      template: require('views/init/choose'),
      controller: ($scope, Importer) => {
        Importer($scope);
      }
    }).

    state('configure.create', {
      url: '/create',
      template: '

'
    }).

    state('configure.create.uid', {
      url: '/create/uid',
      template: require('views/init/create/create_uid'),
      controller: 'IdentityController'
    }).

    state('configure.create.network', {
      url: '/create/network',
      template: require('views/init/create/create_network'),
      resolve: {
        netinterfaces: (Webmin) => resolveNetworkAutoConf(Webmin),
        firstConf: () => true
      },
      controller: 'NetworkController'
    }).

    state('configure.create.parameters', {
      url: '/create/parameters',
      template: require('views/init/create/create_parameters'),
      controller: 'ParametersController'
    }).

    state('configure.create.root', {
      url: '/create/root',
      template: require('views/init/create/create_root'),
      controller: 'RootBlockController'
    }).

    state('sync', {
      url: '/sync?host=&port=&sync=&to=',
      template: require('views/init/sync/sync'),
      controller: 'SyncController'
    }).

    state('main', {
      abstract: true,
      url: '/main',
      template: require('views/main/main'),
      resolve: {
        ws: (Webmin) => Webmin.ws(),
        summary: (Webmin) => Webmin.summary()
      },
      controller: 'MainController'
    }).

    state('main.home', {
      abstract: true,
      url: '/home',
      template: require('views/main/home/home'),
      controller: 'HomeController'
    }).

    state('main.home.overview', {
      url: '/overview',
      template: require('views/maingk/home/tabs/overview'),
      resolve: {
        summary: (Webmin) => Webmin.summary()
      },
      controller: 'OverviewController'
    }).

    state('main.home.network', {
      url: '/network',
      template: require('views/main/home/tabs/network'),
      resolve: {
        peers: (Webmin) => co(function *() {
          return Webmin.network.peers();
        })
      },
      controller: 'HomeNetworkController'
    }).

    state('main.settings', {
      abstract: true,
      url: '/settings',
      template: require('views/main/settings/settings'),
      resolve: {
        summary: (Webmin) => Webmin.summary()
      },
      controller: 'SettingsController'
    }).

    state('main.settings.data', {
      url: '/data',
      template: require('views/main/settings/tabs/data'),
      resolve: {
        peers: (Webmin) => co(function *() {
          try {
            let self = yield Webmin.network.selfPeer();
            let res = yield Webmin.network.peers();
            return _.filter(res.peers, (p) => p.pubkey != self.pubkey && p.status == 'UP');
          } catch (e) {
            console.error(e);
            return [];
          }
        })
      },
      controller: 'DataController'
    }).

    state('main.settings.logs', {
      url: '/logs',
      template: require('views/main/settings/tabs/logs'),
      controller: 'LogsSettingsController'
    }).

    state('main.settings.backup', {
      url: '/backup',
      template: require('views/main/settings/tabs/backup'),
      controller: 'BackupController'
    }).

    state('main.settings.cpu', {
      url: '/cpu',
      template: require('views/main/settings/tabs/cpu'),
      resolve: {
        summary: (Webmin) => Webmin.summary()
      },
      controller: 'CPUController'
    }).

    state('main.settings.crypto', {
      url: '/crypto',
      template: require('views/main/settings/tabs/crypto'),
      controller: 'KeyController'
    }).

    state('main.settings.network', {
      url: '/network',
      resolve: {
        netinterfaces: (Webmin) => resolveNetworkAutoConf(Webmin),
        firstConf: () => false
      },
      template: require('views/main/settings/tabs/network'),
      controller: 'NetworkController'
    }).

    state('main.settings.currency', {
      url: '/currency',
      resolve: {
        conf: (summary) => co(function *() {
          return summary.parameters;
        })
      },
      template: require('views/main/settings/tabs/currency'),
      controller: 'CurrencyController'
    }).

    state('main.graphs', {
      abstract: true,
      url: '/graphs',
      template: require('views/main/graphs/graphs'),
      controller: 'GraphsController'
    }).

    state('main.graphs.blockchain', {
      url: '/blockchain',
      template: require('views/main/graphs/blockchain'),
      controller: 'GraphsBlockchainController'
    }).

    //state('graphs.crypto', {
    //  url: '/crypto',
    //  template: require('views/graphs/crypto'),
    //  controller: 'KeyController'
    //}).
    //
    //state('graphs.network', {
    //  url: '/network',
    //  resolve: {
    //    netinterfaces: (Webmin) => resolveNetworkAutoConf(Webmin),
    //    firstConf: () => false
    //  },
    //  template: require('views/graphs/network'),
    //  controller: 'NetworkController'
    //}).
    //
    //state('graphs.currency', {
    //  url: '/currency',
    //  resolve: {
    //    conf: (bmapi) => co(function *() {
    //      return bmapi.currency.parameters();
    //    })
    //  },
    //  template: require('views/graphs/currency'),
    //  controller: 'CurrencyController'
    //}).

    state('logs', {
      url: '/logs',
      template: require('views/logs'),
      resolve: {
        ws: (Webmin) => Webmin.ws()
      },
      controller: 'LogsController'
    }).

    state('error', {
      url: '/error\?err',
      template: require('views/error'),
      controller: ($scope, $stateParams) =>
        $scope.errorMsg = $stateParams.err || 'err.unknown'
    });

    // Default route
    $urlRouterProvider.otherwise('/');
  }]);

  app.run(($rootScope, $state) => {
    $rootScope.$on('$stateChangeError', (event, toState, toParams, fromState, fromParams, error) => {
      console.error(error);
      $state.go('error', { err: error.message });
    });
  });

  function resolveNetworkAutoConf(Webmin) {
    return co(function *() {
      let netinterfaces = yield Webmin.network.interfaces();
      return netinterfaces || { local: {}, remote: {} };
    });
  }
};
<commit_msg>[fix] Typo in controllers' path<commit_after>var co = require('co');
var _ = require('underscore');

module.exports = (app) => {

  app.config(['$stateProvider', '$urlRouterProvider', ($stateProvider, $urlRouterProvider) => {

    // States
    $stateProvider.
    state('index', {
      url: '/',
      template: require('views/index'),
      resolve: {
        ws: (Webmin) => Webmin.ws(),
        summary: (Webmin) => Webmin.summary()
      },
      controller: 'IndexController'
    }).

    state('about', {
      url: '/about',
      template: require('views/about'),
      resolve: {
        summary: (Webmin) => Webmin.summary(),
        version: (summary) => summary && 'v' + summary.version || 'unknown version'
      },
      controller: 'AboutController'
    }).

    state('configure', {
      abstract: true,
      url: '/configure',
      template: require('views/init/layout'),
      controller: ($scope) => {
        $scope.conf = {
          currency: 'super_currency',
          c: 0.007376575,
          dt: 30.4375 * 24 * 3600,
          ud0: 100,
          stepMax: 3,
          sigDelay: 3600 * 24 * 365 * 5,
          sigPeriod: 0, // Instant
          sigStock: 40,
          sigWindow: 3600 * 24 * 14, // 2 weeks
          sigValidity: 3600 * 24 * 365,
          msValidity: 3600 * 24 * 365,
          sigQty: 0,
          xpercent: 0.9,
          percentRot: 0.66,
          blocksRot: 20,
          avgGenTime: 16 * 60,
          dtDiffEval: 10,
          medianTimeBlocks: 20
        };
      }
    }).

    state('configure.choose', {
      url: '/choose',
      template: require('views/init/choose'),
      controller: ($scope, Importer) => {
        Importer($scope);
      }
    }).

    state('configure.create', {
      url: '/create',
      template: '

'
    }).

    state('configure.create.uid', {
      url: '/create/uid',
      template: require('views/init/create/create_uid'),
      controller: 'IdentityController'
    }).

    state('configure.create.network', {
      url: '/create/network',
      template: require('views/init/create/create_network'),
      resolve: {
        netinterfaces: (Webmin) => resolveNetworkAutoConf(Webmin),
        firstConf: () => true
      },
      controller: 'NetworkController'
    }).

    state('configure.create.parameters', {
      url: '/create/parameters',
      template: require('views/init/create/create_parameters'),
      controller: 'ParametersController'
    }).

    state('configure.create.root', {
      url: '/create/root',
      template: require('views/init/create/create_root'),
      controller: 'RootBlockController'
    }).

    state('sync', {
      url: '/sync?host=&port=&sync=&to=',
      template: require('views/init/sync/sync'),
      controller: 'SyncController'
    }).

    state('main', {
      abstract: true,
      url: '/main',
      template: require('views/main/main'),
      resolve: {
        ws: (Webmin) => Webmin.ws(),
        summary: (Webmin) => Webmin.summary()
      },
      controller: 'MainController'
    }).

    state('main.home', {
      abstract: true,
      url: '/home',
      template: require('views/main/home/home'),
      controller: 'HomeController'
    }).

    state('main.home.overview', {
      url: '/overview',
      template: require('views/main/home/tabs/overview'),
      resolve: {
        summary: (Webmin) => Webmin.summary()
      },
      controller: 'OverviewController'
    }).

    state('main.home.network', {
      url: '/network',
      template: require('views/main/home/tabs/network'),
      resolve: {
        peers: (Webmin) => co(function *() {
          return Webmin.network.peers();
        })
      },
      controller: 'HomeNetworkController'
    }).

    state('main.settings', {
      abstract: true,
      url: '/settings',
      template: require('views/main/settings/settings'),
      resolve: {
        summary: (Webmin) => Webmin.summary()
      },
      controller: 'SettingsController'
    }).

    state('main.settings.data', {
      url: '/data',
      template: require('views/main/settings/tabs/data'),
      resolve: {
        peers: (Webmin) => co(function *() {
          try {
            let self = yield Webmin.network.selfPeer();
            let res = yield Webmin.network.peers();
            return _.filter(res.peers, (p) => p.pubkey != self.pubkey && p.status == 'UP');
          } catch (e) {
            console.error(e);
            return [];
          }
        })
      },
      controller: 'DataController'
    }).

    state('main.settings.logs', {
      url: '/logs',
      template: require('views/main/settings/tabs/logs'),
      controller: 'LogsSettingsController'
    }).

    state('main.settings.backup', {
      url: '/backup',
      template: require('views/main/settings/tabs/backup'),
      controller: 'BackupController'
    }).

    state('main.settings.cpu', {
      url: '/cpu',
      template: require('views/main/settings/tabs/cpu'),
      resolve: {
        summary: (Webmin) => Webmin.summary()
      },
      controller: 'CPUController'
    }).

    state('main.settings.crypto', {
      url: '/crypto',
      template: require('views/main/settings/tabs/crypto'),
      controller: 'KeyController'
    }).

    state('main.settings.network', {
      url: '/network',
      resolve: {
        netinterfaces: (Webmin) => resolveNetworkAutoConf(Webmin),
        firstConf: () => false
      },
      template: require('views/main/settings/tabs/network'),
      controller: 'NetworkController'
    }).

    state('main.settings.currency', {
      url: '/currency',
      resolve: {
        conf: (summary) => co(function *() {
          return summary.parameters;
        })
      },
      template: require('views/main/settings/tabs/currency'),
      controller: 'CurrencyController'
    }).

    state('main.graphs', {
      abstract: true,
      url: '/graphs',
      template: require('views/main/graphs/graphs'),
      controller: 'GraphsController'
    }).

    state('main.graphs.blockchain', {
      url: '/blockchain',
      template: require('views/main/graphs/blockchain'),
      controller: 'GraphsBlockchainController'
    }).

    //state('graphs.crypto', {
    //  url: '/crypto',
    //  template: require('views/graphs/crypto'),
    //  controller: 'KeyController'
    //}).
    //
    //state('graphs.network', {
    //  url: '/network',
    //  resolve: {
    //    netinterfaces: (Webmin) => resolveNetworkAutoConf(Webmin),
    //    firstConf: () => false
    //  },
    //  template: require('views/graphs/network'),
    //  controller: 'NetworkController'
    //}).
    //
    //state('graphs.currency', {
    //  url: '/currency',
    //  resolve: {
    //    conf: (bmapi) => co(function *() {
    //      return bmapi.currency.parameters();
    //    })
    //  },
    //  template: require('views/graphs/currency'),
    //  controller: 'CurrencyController'
    //}).

    state('logs', {
      url: '/logs',
      template: require('views/logs'),
      resolve: {
        ws: (Webmin) => Webmin.ws()
      },
      controller: 'LogsController'
    }).

    state('error', {
      url: '/error\?err',
      template: require('views/error'),
      controller: ($scope, $stateParams) =>
        $scope.errorMsg = $stateParams.err || 'err.unknown'
    });

    // Default route
    $urlRouterProvider.otherwise('/');
  }]);

  app.run(($rootScope, $state) => {
    $rootScope.$on('$stateChangeError', (event, toState, toParams, fromState, fromParams, error) => {
      console.error(error);
      $state.go('error', { err: error.message });
    });
  });

  function resolveNetworkAutoConf(Webmin) {
    return co(function *() {
      let netinterfaces = yield Webmin.network.interfaces();
      return netinterfaces || { local: {}, remote: {} };
    });
  }
};
<|endoftext|>


<commit_before>"use strict";

var sass = require('node-sass'),
    fs = require('fs'),
    url = require('url'),
    dirname = require('path').dirname,
    mkdirp = require('mkdirp'),
    join = require('path').join;

var imports = {};

/**
 * Return Connect middleware with the given `options`.
 *
 * Options:
 *
 *    `src`         Source directory used to find .scss files
 *    `dest`        Destination directory used to output .css files
 *                   when undefined defaults to `src`
 *    `root`        A base path for both source and destination directories
 *    `outputStyle` Sass output style (nested or compressed), nested by default
 *    `indentedSyntax` Use standard SCSS sytax (Sassy CSS) or the cleaner SASS syntax
 *    `force`       Always re-compile
 *    `debug`       Output debugging information
 *    `response`    True (default) to write output directly to response
 *                   instead of to a file
 *    `error`       A function to be called when something goes wrong
 *
 * Examples:
 *
 * Pass the middleware to Connect, grabbing .scss files from this directory
 * and saving .css files to _./public_.
 *
 * Following that we have a `staticProvider` layer setup to serve the .css
 * files generated by Sass.
 *
 *   var server = connect()
 *      .use(middleware({
 *        src: __dirname,
 *        dest: __dirname,
 *      }))
 *      .use(function(err, req, res, next) {
 *        res.statusCode = 500;
 *        res.end(err.message);
 *      });
 *
 * @param {Object} options
 * @return {Function}
 * @api public
 */

module.exports = function(options) {
  options = options || {};

  // Accept single src/dest dir
  if (typeof options == 'string') {
    options = { src: options };
  }

  // This function will be called if something goes wrong
  var error = options.error || function() { };

  // Source directory (required)
  var src = options.src || function() {
    throw new Error('sass.middleware() requires "src" directory.');
  }();
  // Destination directory (source by default)
  var dest = options.dest || src;
  // Optional base path for src and dest
  var root = options.root || null;

  // Force compilation everytime
  var force = options.force || options.response;
  // Enable debug output
  var debug = options.debug;

  var indentedSyntax = options.indentedSyntax || null;
  var sassExtension = (indentedSyntax === true) ? '.sass' : '.scss';

  var sourceMap = options.sourceMap || null;
  var cssMapPath = null;

  // Default compile callback
  options.compile = options.compile || function() {
    return sass;
  };

  // Middleware
  return function sass(req, res, next) {
    if (req.method != 'GET' && req.method != 'HEAD') {
      return next();
    }

    var path = url.parse(req.url).pathname;
    if (options.prefix && 0 === path.indexOf(options.prefix)) {
      path = path.substring(options.prefix.length);
    }

    if (!/\.css$/.test(path)) {
      next();
    } else {
      var cssPath = join(dest, path),
          sassPath = join(src, path.replace(/\.css$/, sassExtension)),
          sassDir = dirname(sassPath);

      if (root) {
        cssPath = join(root, dest, path.replace(new RegExp('^' + dest), ''));
        sassPath = join(root, src, path
            .replace(new RegExp('^' + dest), '')
            .replace(/\.css$/, sassExtension));
        sassDir = dirname(sassPath);
      }

      if (sourceMap === true) {
        cssMapPath = cssPath + '.map';
      } else if (typeof sourceMap === 'string') {
        cssMapPath = join(dirname(cssPath), sourceMap);
      }

      if (debug) {
        log('source', sassPath);
        log('dest', options.response ? '<response>' : cssPath);
      }

      // When render is done, respond to the request accordingly
      var done = function(err, result) {
        var data;

        if (err) {
          var file = sassPath;
          if (err.file && err.file != 'stdin') {
            file = err.file;
          }

          var fileLineColumn = file + ':' + err.line + ':' + err.column;
          data = err.message.replace(/^ +/, '') + '\n\nin ' + fileLineColumn;
          if (debug) logError(data);

          error(err);

          return next(err);
        } else {
          data = result.css;

          if (debug) {
            log('render', options.response ? '<response>' : sassPath);

            if (sourceMap) {
              log('render', cssMapPath);
            }
          }
          imports[sassPath] = result.stats.includedFiles;

          // If response is falsey, also write to file
          if (!options.response) {
            mkdirp(dirname(cssPath), '0700', function(err) {
              if (err) {
                return error(err);
              }

              fs.writeFile(cssPath, data, 'utf8', function(err) {
                if (err) {
                  return error(err);
                }
              });
            });

            if (sourceMap) {
              mkdirp(dirname(cssMapPath), '0700', function(err) {
                if (err) {
                  return error(err);
                }

                fs.writeFile(cssMapPath, result.map, 'utf8', function(err) {
                  if (err) {
                    return error(err);
                  }
                });
              });
            }
          }
        }

        res.writeHead(200, {
          'Content-Type': 'text/css',
          'Cache-Control': 'max-age=0'
        });
        res.end(data);
      }

      // Compile to cssPath
      var compile = function() {
        if (debug) { log('read', cssPath); }

        fs.exists(sassPath, function(exists) {
          if (!exists) {
            return next();

          var style = options.compile();
          delete imports[sassPath];
          style.render({
            file: sassPath,
            includePaths: [sassDir].concat(options.includePaths || []),
            outputStyle: options.outputStyle,
            indentedSyntax: indentedSyntax,
            outFile: cssPath,
            sourceMap: sourceMap,
          }, done);
        });
      };

      // Force
      if (force){
        return compile();
      }

      // Re-compile on server restart, disregarding
      // mtimes since we need to map imports
      if (!imports[sassPath]) {
        return compile();
      }

      // Compare mtimes
      fs.stat(sassPath, function(err, sassStats){
        if (err) {
          error(err);
          return next();
        }
        fs.stat(cssPath, function(err, cssStats){
          // CSS has not been compiled, compile it!
          if (err) {
            if ('ENOENT' == err.code) {
              if (debug) { log('not found', cssPath); }
              compile();
            } else {
              next(err);
            }
          } else {
            // Source has changed, compile it
            if (sassStats.mtime > cssStats.mtime) {
              if (debug) { log('modified', cssPath); }
              compile();
            // Already compiled, check imports
            } else {
              checkImports(sassPath, cssStats.mtime, function(changed) {
                if (debug && changed && changed.length) {
                  changed.forEach(function(path) {
                    log('modified import %s', path);
                  });
                }
                changed && changed.length ? compile() : next();
              });
            }
          }
        });
      });
    }
  };
};

/**
 * Check `path`'s imports to see if they have been altered.
 *
 * @param {String} path
 * @param {Function} fn
 * @api private
 */

function checkImports(path, time, fn) {
  var nodes = imports[path];
  if (!nodes || !nodes.length) {
    return fn();
  }

  var pending = nodes.length,
      changed = [];

  // examine the imported files (nodes) for each parent sass (path)
  nodes.forEach(function(imported) {
    fs.stat(imported, function(err, stat) {
      // error or newer mtime
      if (err || stat.mtime >= time) {
        changed.push(imported);
      }
      // decrease pending, if 0 call fn with the changed imports
      --pending || fn(changed);
    });
  });
}

/**
 * Log a message.
 *
 * @api private
 */

function log(key, val) {
  console.error('  \x1B[90m%s:\x1B[0m \x1B[36m%s\x1B[0m', key, val);
}

/**
 * Log an error message.
 *
 * @api private
 */

function logError(message) {
  log('error', '\x07\x1B[31m' + message + '\x1B[91m');
}
<commit_msg>Cleaned up source-map path generation<commit_after>"use strict";

var sass = require('node-sass'),
    fs = require('fs'),
    url = require('url'),
    dirname = require('path').dirname,
    mkdirp = require('mkdirp'),
    join = require('path').join;

var imports = {};

/**
 * Return Connect middleware with the given `options`.
 *
 * Options:
 *
 *    `src`         Source directory used to find .scss files
 *    `dest`        Destination directory used to output .css files
 *                   when undefined defaults to `src`
 *    `root`        A base path for both source and destination directories
 *    `outputStyle` Sass output style (nested or compressed), nested by default
 *    `indentedSyntax` Use standard SCSS sytax (Sassy CSS) or the cleaner SASS syntax
 *    `force`       Always re-compile
 *    `debug`       Output debugging information
 *    `response`    True (default) to write output directly to response
 *                   instead of to a file
 *    `error`       A function to be called when something goes wrong
 *
 * Examples:
 *
 * Pass the middleware to Connect, grabbing .scss files from this directory
 * and saving .css files to _./public_.
 *
 * Following that we have a `staticProvider` layer setup to serve the .css
 * files generated by Sass.
 *
 *   var server = connect()
 *      .use(middleware({
 *        src: __dirname,
 *        dest: __dirname,
 *      }))
 *      .use(function(err, req, res, next) {
 *        res.statusCode = 500;
 *        res.end(err.message);
 *      });
 *
 * @param {Object} options
 * @return {Function}
 * @api public
 */

module.exports = function(options) {
  options = options || {};

  // Accept single src/dest dir
  if (typeof options == 'string') {
    options = { src: options };
  }

  // This function will be called if something goes wrong
  var error = options.error || function() { };

  // Source directory (required)
  var src = options.src || function() {
    throw new Error('sass.middleware() requires "src" directory.');
  }();
  // Destination directory (source by default)
  var dest = options.dest || src;
  // Optional base path for src and dest
  var root = options.root || null;

  // Force compilation everytime
  var force = options.force || options.response;
  // Enable debug output
  var debug = options.debug;

  var indentedSyntax = options.indentedSyntax || null;
  var sassExtension = (indentedSyntax === true) ? '.sass' : '.scss';

  var sourceMap = options.sourceMap || null;

  // Default compile callback
  options.compile = options.compile || function() {
    return sass;
  };

  // Middleware
  return function sass(req, res, next) {
    if (req.method != 'GET' && req.method != 'HEAD') {
      return next();
    }

    var path = url.parse(req.url).pathname;
    if (options.prefix && 0 === path.indexOf(options.prefix)) {
      path = path.substring(options.prefix.length);
    }

    if (!/\.css$/.test(path)) {
      next();
    } else {
      var cssPath = join(dest, path),
          sassPath = join(src, path.replace(/\.css$/, sassExtension)),
          sassDir = dirname(sassPath);

      if (root) {
        cssPath = join(root, dest, path.replace(new RegExp('^' + dest), ''));
        sassPath = join(root, src, path
            .replace(new RegExp('^' + dest), '')
            .replace(/\.css$/, sassExtension));
        sassDir = dirname(sassPath);
      }

      if (debug) {
        log('source', sassPath);
        log('dest', options.response ? '<response>' : cssPath);
      }

      // When render is done, respond to the request accordingly
      var done = function(err, result) {
        var data;

        if (err) {
          var file = sassPath;
          if (err.file && err.file != 'stdin') {
            file = err.file;
          }

          var fileLineColumn = file + ':' + err.line + ':' + err.column;
          data = err.message.replace(/^ +/, '') + '\n\nin ' + fileLineColumn;
          if (debug) logError(data);

          error(err);

          return next(err);
        } else {
          data = result.css;

          if (debug) {
            log('render', options.response ? '<response>' : sassPath);

            if (sourceMap) {
              log('render', this.options.sourceMap);
            }
          }
          imports[sassPath] = result.stats.includedFiles;

          // If response is falsey, also write to file
          if (!options.response) {
            mkdirp(dirname(cssPath), '0700', function(err) {
              if (err) {
                return error(err);
              }

              fs.writeFile(cssPath, data, 'utf8', function(err) {
                if (err) {
                  return error(err);
                }
              });
            });

            if (sourceMap) {
              var sourceMapPath = this.options.sourceMap;
              mkdirp(dirname(sourceMapPath), '0700', function(err) {
                if (err) {
                  return error(err);
                }

                fs.writeFile(sourceMapPath, result.map, 'utf8', function(err) {
                  if (err) {
                    return error(err);
                  }
                });
              });
            }
          }
        }

        res.writeHead(200, {
          'Content-Type': 'text/css',
          'Cache-Control': 'max-age=0'
        });
        res.end(data);
      }

      // Compile to cssPath
      var compile = function() {
        if (debug) { log('read', cssPath); }

        fs.exists(sassPath, function(exists) {
          if (!exists) {
            return next();
          }

          var style = options.compile();
          delete imports[sassPath];
          style.render({
            file: sassPath,
            includePaths: [sassDir].concat(options.includePaths || []),
            outputStyle: options.outputStyle,
            indentedSyntax: indentedSyntax,
            outFile: cssPath,
            sourceMap: sourceMap,
          }, done);
        });
      };

      // Force
      if (force){
        return compile();
      }

      // Re-compile on server restart, disregarding
      // mtimes since we need to map imports
      if (!imports[sassPath]) {
        return compile();
      }

      // Compare mtimes
      fs.stat(sassPath, function(err, sassStats){
        if (err) {
          error(err);
          return next();
        }
        fs.stat(cssPath, function(err, cssStats){
          // CSS has not been compiled, compile it!
          if (err) {
            if ('ENOENT' == err.code) {
              if (debug) { log('not found', cssPath); }
              compile();
            } else {
              next(err);
            }
          } else {
            // Source has changed, compile it
            if (sassStats.mtime > cssStats.mtime) {
              if (debug) { log('modified', cssPath); }
              compile();
            // Already compiled, check imports
            } else {
              checkImports(sassPath, cssStats.mtime, function(changed) {
                if (debug && changed && changed.length) {
                  changed.forEach(function(path) {
                    log('modified import %s', path);
                  });
                }
                changed && changed.length ? compile() : next();
              });
            }
          }
        });
      });
    }
  };
};

/**
 * Check `path`'s imports to see if they have been altered.
 *
 * @param {String} path
 * @param {Function} fn
 * @api private
 */

function checkImports(path, time, fn) {
  var nodes = imports[path];
  if (!nodes || !nodes.length) {
    return fn();
  }

  var pending = nodes.length,
      changed = [];

  // examine the imported files (nodes) for each parent sass (path)
  nodes.forEach(function(imported) {
    fs.stat(imported, function(err, stat) {
      // error or newer mtime
      if (err || stat.mtime >= time) {
        changed.push(imported);
      }
      // decrease pending, if 0 call fn with the changed imports
      --pending || fn(changed);
    });
  });
}

/**
 * Log a message.
 *
 * @api private
 */

function log(key, val) {
  console.error('  \x1B[90m%s:\x1B[0m \x1B[36m%s\x1B[0m', key, val);
}

/**
 * Log an error message.
 *
 * @api private
 */

function logError(message) {
  log('error', '\x07\x1B[31m' + message + '\x1B[91m');
}
<|endoftext|>


<commit_before>'use strict';

var isPromise = require('./util/isPromise');

function values(object) {
    var result = {};

    return Promise.all(
        Object.keys(object).map(function (key) {
            if (isPromise(object[key])) {
                return object[key].then(function (value) {
                    return (result[key] = value);
                });
            }

            result[key] = object[key];
        })
    )
    .then(function () { return result; });
}

/*
 * Resolve the values of an object, whether they are promises or values, fulfilled.
 */
module.exports = function (fn) {
    if (typeof fn === 'function') {
        return function (object) {
            return values(object)
            .then(fn);
        };
    }

    // fn is an object
    return values(fn);
};
<commit_msg>Remove unnecessary indentation<commit_after>'use strict';

var isPromise = require('./util/isPromise');

function values(object) {
    var result = {};

    return Promise.all(Object.keys(object).map(function (key) {
        if (isPromise(object[key])) {
            return object[key].then(function (value) {
                return (result[key] = value);
            });
        }

        return (result[key] = object[key]);
    }))
    .then(function () { return result; });
}

/*
 * Resolve the values of an object, whether they are promises or values, fulfilled.
 */
module.exports = function (fn) {
    if (typeof fn === 'function') {
        return function (object) {
            return values(object)
            .then(fn);
        };
    }

    // fn is an object
    return values(fn);
};
<|endoftext|>


<commit_before>module.exports = {

    incoming: function (message, bot, builder) {
        console.log('conversations/state')
        console.log(global.conversations);
        console.log('************');
        console.log('users');
        console.log(global.users);
        console.log('agents');
        console.log(global.agent);

        if (message.text === 'help') {
            // user initiated connect to agent
            // send something like 'hold on while I connect you'
            global.conversations[message.address.conversation.id] = Object.assign({}, global.conversations[message.address.conversation.id], { findingAgent: true });
            message.text = 'hold on while I connect you';
            return message
        };

        // find out who is talking / add new convo if not found
        if (message.user.isStaff) {
            console.log('is staff');
            var thisAgent = global.agent.filter(function (value) {
                return value === message.address.conversation.id;
            })
            if (thisAgent[0] !== message.address.conversation.id) {
                global.agent.push(message.address.conversation.id);

            };

            global.conversations[message.address.conversation.id] = Object.assign({}, global.conversations[message.address.conversation.id], { address: message.address })

        };
        if (!message.user.isStaff) {
            console.log('not staff');
            var thisUser = global.users.filter(function (value) {
                return value === message.address.conversation.id;
            });
            if (thisUser[0] !== message.address.conversation.id) {
                global.users.push(message.address.conversation.id);

            }

            global.conversations[message.address.conversation.id] = Object.assign({}, global.conversations[message.address.conversation.id], {
                transcript: global.conversations[message.address.conversation.id].transcript.push(message),
                address: message.address
            })

            // this needs to be an array of message objects and an indication of where messages should be routed
        }
        if (global.conversation[message.address.conversation.id].findingAgent) {
            console.log('getting agent');
            var myAgent = global.conversations[global.agent[0]].address;
            global.conversations[message.address.conversation.id] = Object.assign({}, global.conversations[message.address.conversation.id], { agentAddress: myAgent, findingAgent: false })

        }

        // who should they be talking to

        // make it so

        // if talking to Agent/waiting for agent, suppress default bot functionality (how if on a prompt and it's looking for a certain response? override somehow)

    }

}
<commit_msg>refactor a bit<commit_after>module.exports = {

    incoming: function (message, bot, builder) {
        console.log('conversations/state')
        console.log(global.conversations);
        console.log('************');
        console.log('users');
        console.log(global.users);
        console.log('agents');
        console.log(global.agent);

        if (message.text) { // saves a ping from adding a user/agent

            if (message.text === 'help') {
                // user initiated connect to agent
                global.conversations[message.address.conversation.id] = Object.assign({}, global.conversations[message.address.conversation.id], { 'status': 'Finding_Agent' });
                message.text = 'hold on while I connect you';
                // return message
            };

            // find out who is talking / add new convo if not found
            if (message.user.isStaff) { // move logic to an API for agents
                console.log('is staff');
                var agentId = message.address.conversation.id;
                var thisAgent = global.conversations[agentId];
                if (thisAgent === 'undefined') { // agent not in state yet, add them ****This will happen for each conversation, not agent.
                    global.agent.push(agentId);
                    global.conversations[agentId].address = message.address;
                }
            }
            // End Agent

            // Setting User state logic
            else {
                console.log('not staff');
                var userId = message.address.conversation.id;
                var thisUser = global.conversations[userId];
                // Add a user not yet in state

                if (thisUser === 'undefined') {
                    global.users.push(userId);
                    global.conversations[userId] = { transcript: [message], address: message.address, status: 'Talking_To_Bot' };
                    return
                }
                // if in state, update transcript for the user
                global.conversations[userId] = Object.assign({}, global.conversations[userId], { transcript: [...global.conversations[userId].transcript, message] });

                // Check for choices to be made
                switch (global.conversations[userId].status) {
                    case 'Finding_Agent':
                        console.log('getting agent');
                        var myAgent = global.conversations[global.agent[0]];
                        global.conversations[userId] = Object.assign({}, global.conversations[message.address.conversation.id], { agentAddress: myAgent.address, 'status': 'Talking_To_Agent' });
                        break;
                    case 'Talking_To_Agent':
                        console.log('talking to agent');
                        break;
                    case 'Talking_To_Bot':
                        console.log('talk to bot');
                        break;
                    default:
                        break;

                }

            }
        }

        // who should they be talking to
        // make it so
        // if talking to Agent/waiting for agent, suppress default bot functionality (how if on a prompt and it's looking for a certain response? override somehow)

    }
}
<|endoftext|>


<commit_before>
define([
  'jquery',
  'underscore',
  'backbone',
  'collections/topiclist',
  'collections/topic',
  'text!templates/topic.html',
  'helpers/nav',
  'views/entry'
], function ($, _, Backbone, TopicListCollection,
             TopicCollection, TopicTemplate, NavHelper,
             EntryView) {

  var TopicListView = Backbone.View.extend ({
    el: '#main',

    // index of current item
    current_item: 0,
    current_topics: false,

    initialize: function () {
      this.topicListCollection = new TopicListCollection ();
      this.topicCollection = new TopicCollection ();

      NavHelper.initialize ('');
      NavHelper.bindRefresh (this);
    },

    setTitle: function (external_url) {
      var user;
      if (user = external_url.match (/basliklar\/istatistik\/(.*?)\/son-entryleri/)) {
        NavHelper.setTitle (user[1] + '\'in son entryleri');
      } else if (user = external_url.match (/basliklar\/istatistik\/(.*?)\/favori-entryleri/)) {
        NavHelper.setTitle (user[1] + '\'in favori entryleri');
      } else if (user = external_url.match (/basliklar\/istatistik\/(.*?)\/en-begenilenleri/)) {
        NavHelper.setTitle (user[1] + '\'in en beğenilen entryleri');
      } else if (user = external_url.match (/basliklar\/istatistik\/(.*?)\/favorilenen-entryleri/)) {
        NavHelper.setTitle (user[1] + '\'in en çok favorilenen entryleri');
      } else if (user = external_url.match (/basliklar\/istatistik\/(.*?)\/son-oylananlari/)) {
        NavHelper.setTitle (user[1] + '\'in son oylanan entryleri');
      }

    },

    render: function (external_url) {

      var that = this;

      if (this.isLoading)
        return;

      this.isLoading = true;

      if (!this.current_topics) {

        this.setTitle (external_url);

        this.topicListCollection.external_url = external_url;

        this.topicListCollection.fetch ({

          success: function (entries) {

            that.isLoading = false;
            that.render ();

          }

        });

        this.current_topics = true;
        return;

      }

      this.topicCollection.reset ();

      if (!this.topicListCollection.at (this.current_item))
        return;

      this.topicCollection.external_url =
          this.topicListCollection.at (this.current_item).get ('url');

      this.topicCollection.fetch ({

        success: function (entries) {

          that.isLoading = false;

          $(that.el).append (_.template (TopicTemplate,
               {
                 entry_title: that.topicCollection.title,
                 external_url: that.topicCollection.external_url,
                 entries: [ entries
                                .at (0)
                                .toJSON ()
                          ]
               }));

        if (!that.entryview) { new EntryView (); that.entryview = true; }

          that.current_item++;

          that.checkScroll ();

        }

      });

    },

    events: {
      'scroll': 'checkScroll'
    },

    checkScroll: function () {
      if (!this.isLoading &&
          this.current_item < this.topicListCollection.length &&
          this.el.scrollTop + this.el.clientHeight + 200 >
          this.el.scrollHeight) {
        this.render ();
      }
    },

    refresh: function () {
      $(this.el).html ('');
      this.topicListCollection.reset ();
      this.topicCollection.reset ();
      this.current_topics = false;
      this.current_item = 0;
      this.render (this.topicListCollection.external_url);
    },

  });

  return TopicListView;

});
<commit_msg>add FIXME tag<commit_after>
define([
  'jquery',
  'underscore',
  'backbone',
  'collections/topiclist',
  'collections/topic',
  'text!templates/topic.html',
  'helpers/nav',
  'views/entry'
], function ($, _, Backbone, TopicListCollection,
             TopicCollection, TopicTemplate, NavHelper,
             EntryView) {

  var TopicListView = Backbone.View.extend ({
    el: '#main',

    // index of current item
    current_item: 0,
    current_topics: false,

    initialize: function () {
      this.topicListCollection = new TopicListCollection ();
      this.topicCollection = new TopicCollection ();

      NavHelper.initialize ('');
      // FIXME: refresh is binding but button is not showing, no idea why
      NavHelper.bindRefresh (this);
    },

    setTitle: function (external_url) {
      var user;
      if (user = external_url.match (/basliklar\/istatistik\/(.*?)\/son-entryleri/)) {
        NavHelper.setTitle (user[1] + '\'in son entryleri');
      } else if (user = external_url.match (/basliklar\/istatistik\/(.*?)\/favori-entryleri/)) {
        NavHelper.setTitle (user[1] + '\'in favori entryleri');
      } else if (user = external_url.match (/basliklar\/istatistik\/(.*?)\/en-begenilenleri/)) {
        NavHelper.setTitle (user[1] + '\'in en beğenilen entryleri');
      } else if (user = external_url.match (/basliklar\/istatistik\/(.*?)\/favorilenen-entryleri/)) {
        NavHelper.setTitle (user[1] + '\'in en çok favorilenen entryleri');
      } else if (user = external_url.match (/basliklar\/istatistik\/(.*?)\/son-oylananlari/)) {
        NavHelper.setTitle (user[1] + '\'in son oylanan entryleri');
      }

    },

    render: function (external_url) {

      var that = this;

      if (this.isLoading)
        return;

      this.isLoading = true;

      if (!this.current_topics) {

        this.setTitle (external_url);

        this.topicListCollection.external_url = external_url;

        this.topicListCollection.fetch ({

          success: function (entries) {

            that.isLoading = false;
            that.render ();

          }

        });

        this.current_topics = true;
        return;

      }

      this.topicCollection.reset ();

      if (!this.topicListCollection.at (this.current_item))
        return;

      this.topicCollection.external_url =
          this.topicListCollection.at (this.current_item).get ('url');

      this.topicCollection.fetch ({

        success: function (entries) {

          that.isLoading = false;

          $(that.el).append (_.template (TopicTemplate,
               {
                 entry_title: that.topicCollection.title,
                 external_url: that.topicCollection.external_url,
                 entries: [ entries
                                .at (0)
                                .toJSON ()
                          ]
               }));

        if (!that.entryview) { new EntryView (); that.entryview = true; }

          that.current_item++;

          that.checkScroll ();

        }

      });

    },

    events: {
      'scroll': 'checkScroll'
    },

    checkScroll: function () {
      if (!this.isLoading &&
          this.current_item < this.topicListCollection.length &&
          this.el.scrollTop + this.el.clientHeight + 200 >
          this.el.scrollHeight) {
        this.render ();
      }
    },

    refresh: function () {
      $(this.el).html ('');
      this.topicListCollection.reset ();
      this.topicCollection.reset ();
      this.current_topics = false;
      this.current_item = 0;
      this.render (this.topicListCollection.external_url);
    },

  });

  return TopicListView;

});
<|endoftext|>


<commit_before>var log = require('./log');

module.exports = {
  /**
   * Initialise the audit logger.
   *
   * @name withNode(felix, name)
   * @param {Object} felix The felix instance to use to persist.
   * @param {String|Function(err, name)} name Either the authors name,
   *    or a function to retrieve the name.
   * @api public
   */
  withNode: function(felix, name) {
    var nameFn = (typeof name === 'string') ?
      function(callback) { callback(null, name); } : name;
    return log.init(felix.name, felix.client, felix, nameFn);
  }
};<commit_msg>Deprecated withNode and renamed to withFelix<commit_after>var log = require('./log');

module.exports = {

  /**
   * Initialise the audit logger.
   *
   * @name withFelix(felix, name)
   * @param {Object} felix The felix instance to use to persist.
   * @param {String|Function(err, name)} name Either the authors name,
   *    or a function to retrieve the name.
   * @api public
   */
  withFelix: function(felix, name) {
    var nameFn = (typeof name === 'string') ?
      function(callback) { callback(null, name); } : name;
    return log.init(felix.name, felix.client, felix, nameFn);
  }

};

/**
 * @deprecated Use withFelix instead.
 */
module.exports.withNode = module.exports.withFelix;<|endoftext|>


<commit_before>function build(searchTerm) {
  return {
    index: 'profiles',
    type: 'gps',
    body: {
      size: 30,
      query: {
        bool: {
          should: [
            {
              match_phrase: {
                name: {
                  query: searchTerm,
                  boost: 2,
                  slop: 1
                }
              }
            },
            {
              common: {
                name: {
                  query: searchTerm,
                  cutoff_frequency: 0.0001
                }
              }
            },
            {
              common: {
                alternativeName: {
                  query: searchTerm,
                  cutoff_frequency: 0.0001
                }
              }
            },
            {
              nested: {
                path: 'doctors',
                query: {
                  bool: {
                    should: [
                      {
                        match_phrase: {
                          'doctors.name': {
                            query: searchTerm,
                            boost: 2,
                            slop: 1
                          }
                        }
                      },
                      {
                        match: {
                          'doctors.name': {
                            query: searchTerm,
                            cutoff_frequency: 0.0001
                          }
                        }
                      }
                    ]
                  }
                },
              }
            }]
        }
      },

    }
  };
}

module.exports = {
  build,
};
<commit_msg>:bug: Add missing phrase match<commit_after>function build(searchTerm) {
  return {
    index: 'profiles',
    type: 'gps',
    body: {
      size: 30,
      query: {
        bool: {
          should: [
            {
              match_phrase: {
                name: {
                  query: searchTerm,
                  boost: 2,
                  slop: 1
                }
              }
            },
            {
              match_phrase: {
                alternativeName: {
                  query: searchTerm,
                  boost: 2,
                  slop: 1
                }
              }
            },
            {
              common: {
                name: {
                  query: searchTerm,
                  cutoff_frequency: 0.0001
                }
              }
            },
            {
              common: {
                alternativeName: {
                  query: searchTerm,
                  cutoff_frequency: 0.0001
                }
              }
            },
            {
              nested: {
                path: 'doctors',
                query: {
                  bool: {
                    should: [
                      {
                        match_phrase: {
                          'doctors.name': {
                            query: searchTerm,
                            boost: 2,
                            slop: 1
                          }
                        }
                      },
                      {
                        match: {
                          'doctors.name': {
                            query: searchTerm,
                            cutoff_frequency: 0.0001
                          }
                        }
                      }
                    ]
                  }
                },
              }
            }]
        }
      },

    }
  };
}

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


<commit_before>'use strict';

/* jshint expr: true */

/**
 * Module dependencies.
 */

var should = require('should');

var consul = require('../lib');

/**
 * Tests
 */

describe('Agent', function() {
  before(function() {
    this.c = consul();
  });

  describe('checks', function() {
    it('should return local checks', function(done) {
      this.c.agent.checks(function(err, data) {
        should.not.exist(err);

        should(data).be.instanceOf(Object);

        done();
      });
    });
  });

  describe('services', function() {
    it('should return local services', function(done) {
      this.c.agent.services(function(err, data) {
        should.not.exist(err);

        should(data).be.instanceOf(Object);

        done();
      });
    });
  });

  describe('members', function() {
    it('should return members agent sees in cluster gossip pool', function(done) {
      this.c.agent.members(function(err, data) {
        should.not.exist(err);

        should(data).be.instanceOf(Object);

        done();
      });
    });
  });

  describe('self', function() {
    it('should return information about agent', function(done) {
      this.c.agent.self(function(err, data) {
        should.not.exist(err);

        should(data).be.instanceOf(Object);
        data.should.have.keys('Config', 'Member');

        done();
      });
    });
  });
});
<commit_msg>Add additional self checks<commit_after>'use strict';

/* jshint expr: true */

/**
 * Module dependencies.
 */

var should = require('should');

var consul = require('../lib');

/**
 * Tests
 */

describe('Agent', function() {
  before(function() {
    this.c = consul();
  });

  describe('checks', function() {
    it('should return local checks', function(done) {
      this.c.agent.checks(function(err, data) {
        should.not.exist(err);

        should(data).be.instanceOf(Object);

        done();
      });
    });
  });

  describe('services', function() {
    it('should return local services', function(done) {
      this.c.agent.services(function(err, data) {
        should.not.exist(err);

        should(data).be.instanceOf(Object);

        done();
      });
    });
  });

  describe('members', function() {
    it('should return members agent sees in cluster gossip pool', function(done) {
      this.c.agent.members(function(err, data) {
        should.not.exist(err);

        should(data).be.instanceOf(Object);

        done();
      });
    });
  });

  describe('self', function() {
    it('should return information about agent', function(done) {
      this.c.agent.self(function(err, data) {
        should.not.exist(err);

        should(data).be.instanceOf(Object);
        data.should.have.keys('Config', 'Member');

        data.Config.Bootstrap.should.be.true;
        data.Config.Server.should.be.true;
        data.Config.Datacenter.should.eql('dc1');
        data.Config.NodeName.should.eql('node1');

        data.Member.Name.should.eql('node1');
        data.Member.Addr.should.eql('127.0.0.1');

        done();
      });
    });
  });
});
<|endoftext|>


<commit_before>/* @flow */

// This file contains methods responsible for introspecting the current path for certain values.

import type NodePath from "./index";
import includes from "lodash/collection/includes";
import * as t from "babel-types";

/**
 * Match the current node if it matches the provided `pattern`.
 *
 * For example, given the match `React.createClass` it would match the
 * parsed nodes of `React.createClass` and `React["createClass"]`.
 */

export function matchesPattern(pattern: string, allowPartial?: boolean): boolean {
  // not a member expression
  if (!this.isMemberExpression()) return false;

  let parts = pattern.split(".");
  let search = [this.node];
  let i = 0;

  function matches(name) {
    let part = parts[i];
    return part === "*" || name === part;
  }

  while (search.length) {
    let node = search.shift();

    if (allowPartial && i === parts.length) {
      return true;
    }

    if (t.isIdentifier(node)) {
      // this part doesn't match
      if (!matches(node.name)) return false;
    } else if (t.isLiteral(node)) {
      // this part doesn't match
      if (!matches(node.value)) return false;
    } else if (t.isMemberExpression(node)) {
      if (node.computed && !t.isLiteral(node.property)) {
        // we can't deal with this
        return false;
      } else {
        search.unshift(node.property);
        search.unshift(node.object);
        continue;
      }
    } else if (t.isThisExpression(node)) {
      if (!matches("this")) return false;
    } else {
      // we can't deal with this
      return false;
    }

    // too many parts
    if (++i > parts.length) {
      return false;
    }
  }

  return i === parts.length;
}

/**
 * Check whether we have the input `key`. If the `key` references an array then we check
 * if the array has any items, otherwise we just check if it's falsy.
 */

export function has(key): boolean {
  let val = this.node[key];
  if (val && Array.isArray(val)) {
    return !!val.length;
  } else {
    return !!val;
  }
}

/**
 * Description
 */

export function isStatic() {
  return this.scope.isStatic(this.node);
}

/**
 * Alias of `has`.
 */

export let is = has;

/**
 * Opposite of `has`.
 */

export function isnt(key): boolean {
  return !this.has(key);
}

/**
 * Check whether the path node `key` strict equals `value`.
 */

export function equals(key, value): boolean {
  return this.node[key] === value;
}

/**
 * Check the type against our stored internal type of the node. This is handy when a node has
 * been removed yet we still internally know the type and need it to calculate node replacement.
 */

export function isNodeType(type: string): boolean {
  return t.isType(this.type, type);
}

/**
 * This checks whether or now we're in one of the following positions:
 *
 *   for (KEY in right);
 *   for (KEY;;);
 *
 * This is because these spots allow VariableDeclarations AND normal expressions so we need
 * to tell the path replacement that it's ok to replace this with an expression.
 */

 export function canHaveVariableDeclarationOrExpression() {
    return (this.key === "init" || this.key === "left") && this.parentPath.isFor();
 }

/**
 * Check whether the current path references a completion record
 */

export function isCompletionRecord(allowInsideFunction?) {
  let path = this;
  let first = true;

  do {
    let container = path.container;

    // we're in a function so can't be a completion record
    if (path.isFunction() && !first) {
      return !!allowInsideFunction;
    }

    first = false;

    // check to see if we're the last item in the container and if we are
    // we're a completion record!
    if (Array.isArray(container) && path.key !== container.length - 1) {
      return false;
    }
  } while ((path = path.parentPath) && !path.isProgram());

  return true;
}

/**
 * Check whether or not the current `key` allows either a single statement or block statement
 * so we can explode it if necessary.
 */

export function isStatementOrBlock() {
  if (this.parentPath.isLabeledStatement() || t.isBlockStatement(this.container)) {
    return false;
  } else {
    return includes(t.STATEMENT_OR_BLOCK_KEYS, this.key);
  }
}

/**
 * Check if the currently assigned path references the `importName` of `moduleSource`.
 */

export function referencesImport(moduleSource, importName) {
  if (!this.isReferencedIdentifier()) return false;

  let binding = this.scope.getBinding(this.node.name);
  if (!binding || binding.kind !== "module") return false;

  let path = binding.path;
  let parent = path.parentPath;
  if (!parent.isImportDeclaration()) return false;

  // check moduleSource
  if (parent.node.source.value === moduleSource) {
    if (!importName) return true;
  } else {
    return false;
  }

  if (path.isImportDefaultSpecifier() && importName === "default") {
    return true;
  }

  if (path.isImportNamespaceSpecifier() && importName === "*") {
    return true;
  }

  if (path.isImportSpecifier() && path.node.imported.name === importName) {
    return true;
  }

  return false;
}

/**
 * Get the source code associated with this node.
 */

export function getSource() {
  let node = this.node;
  if (node.end) {
    return this.hub.file.code.slice(node.start, node.end);
  } else {
    return "";
  }
}

export function willIMaybeExecuteBefore(target) {
  return this._guessExecutionStatusRelativeTo(target) !== "after";
}

/**
 * Given a `target` check the execution status of it relative to the current path.
 *
 * "Execution status" simply refers to where or not we **think** this will execuete
 * before or after the input `target` element.
 */

export function _guessExecutionStatusRelativeTo(target) {
  // check if the two paths are in different functions, we can't track execution of these
  let targetFuncParent = target.scope.getFunctionParent();
  let selfFuncParent = this.scope.getFunctionParent();

  if (targetFuncParent !== selfFuncParent) {
    let status = this._guessExecutionStatusRelativeToDifferentFunctions(targetFuncParent);
    if (status) {
      return status;
    } else {
      target = targetFuncParent.path;
    }
  }

  let targetPaths = target.getAncestry();
  if (targetPaths.indexOf(this) >= 0) return "after";

  let selfPaths   = this.getAncestry();

  // get ancestor where the branches intersect
  let commonPath;
  let targetIndex;
  let selfIndex;
  for (selfIndex = 0; selfIndex < selfPaths.length; selfIndex++) {
    let selfPath = selfPaths[selfIndex];
    targetIndex = targetPaths.indexOf(selfPath);
    if (targetIndex >= 0) {
      commonPath = selfPath;
      break;
    }
  }
  if (!commonPath) {
    return "before";
  }

  // get the relationship paths that associate these nodes to their common ancestor
  let targetRelationship = targetPaths[targetIndex - 1];
  let selfRelationship   = selfPaths[selfIndex - 1];
  if (!targetRelationship || !selfRelationship) {
    return "before";
  }

  // container list so let's see which one is after the other
  if (targetRelationship.listKey && targetRelationship.container === selfRelationship.container) {
    return targetRelationship.key > selfRelationship.key ? "before" : "after";
  }

  // otherwise we're associated by a parent node, check which key comes before the other
  let targetKeyPosition = t.VISITOR_KEYS[targetRelationship.type].indexOf(targetRelationship.key);
  let selfKeyPosition   = t.VISITOR_KEYS[selfRelationship.type].indexOf(selfRelationship.key);
  return targetKeyPosition > selfKeyPosition ? "before" : "after";
}

export function _guessExecutionStatusRelativeToDifferentFunctions(targetFuncParent) {
  let targetFuncPath = targetFuncParent.path;
  if (!targetFuncPath.isFunctionDeclaration()) return;

  // so we're in a completely different function, if this is a function declaration
  // then we can be a bit smarter and handle cases where the function is either
  // a. not called at all (part of an export)
  // b. called directly
  let binding = targetFuncPath.scope.getBinding(targetFuncPath.node.id.name);

  // no references!
  if (!binding.references) return "before";

  let referencePaths: Array = binding.referencePaths;

  // verify that all of the references are calls
  for (let path of referencePaths) {
    if (path.key !== "callee" || !path.parentPath.isCallExpression()) {
      return;
    }
  }

  let allStatus;

    // verify that all the calls have the same execution status
    for (let path of referencePaths) {
      let status = this._guessExecutionStatusRelativeTo(path);
      if (allStatus) {
        if (allStatus !== status) return;
      } else {
        allStatus = status;
      }
    }

    return allStatus;
}

/**
 * Resolve a "pointer" `NodePath` to it's absolute path.
 */

export function resolve(dangerous, resolved) {
  return this._resolve(dangerous, resolved) || this;
}

export function _resolve(dangerous?, resolved?): ?NodePath {
  // detect infinite recursion
  // todo: possibly have a max length on this just to be safe
  if (resolved && resolved.indexOf(this) >= 0) return;

  // we store all the paths we've "resolved" in this array to prevent infinite recursion
  resolved = resolved || [];
  resolved.push(this);

  if (this.isVariableDeclarator()) {
    if (this.get("id").isIdentifier()) {
      return this.get("init").resolve(dangerous, resolved);
    } else {
      // otherwise it's a request for a pattern and that's a bit more tricky
    }
  } else if (this.isReferencedIdentifier()) {
    let binding = this.scope.getBinding(this.node.name);
    if (!binding) return;

    // reassigned so we can't really resolve it
    if (!binding.constant) return;

    // todo - lookup module in dependency graph
    if (binding.kind === "module") return;

    if (binding.path !== this) {
      return binding.path.resolve(dangerous, resolved);
    }
  } else if (this.isTypeCastExpression()) {
    return this.get("expression").resolve(dangerous, resolved);
  } else if (dangerous && this.isMemberExpression()) {
    // this is dangerous, as non-direct target assignments will mutate it's state
    // making this resolution inaccurate

    let targetKey = this.toComputedKey();
    if (!t.isLiteral(targetKey)) return;

    let targetName = targetKey.value;

    let target = this.get("object").resolve(dangerous, resolved);

    if (target.isObjectExpression()) {
      let props = target.get("properties");
      for (let prop of (props: Array)) {
        if (!prop.isProperty()) continue;

        let key = prop.get("key");

        // { foo: obj }
        let match = prop.isnt("computed") && key.isIdentifier({ name: targetName });

        // { "foo": "obj" } or { ["foo"]: "obj" }
        match = match || key.isLiteral({ value: targetName });

        if (match) return prop.get("value").resolve(dangerous, resolved);
      }
    } else if (target.isArrayExpression() && !isNaN(+targetName)) {
      let elems = target.get("elements");
      let elem = elems[targetName];
      if (elem) return elem.resolve(dangerous, resolved);
    }
  }
}
<commit_msg>fix indentation and skip check for references that are inside the function we're checking execution status against<commit_after>/* @flow */

// This file contains methods responsible for introspecting the current path for certain values.

import type NodePath from "./index";
import includes from "lodash/collection/includes";
import * as t from "babel-types";

/**
 * Match the current node if it matches the provided `pattern`.
 *
 * For example, given the match `React.createClass` it would match the
 * parsed nodes of `React.createClass` and `React["createClass"]`.
 */

export function matchesPattern(pattern: string, allowPartial?: boolean): boolean {
  // not a member expression
  if (!this.isMemberExpression()) return false;

  let parts = pattern.split(".");
  let search = [this.node];
  let i = 0;

  function matches(name) {
    let part = parts[i];
    return part === "*" || name === part;
  }

  while (search.length) {
    let node = search.shift();

    if (allowPartial && i === parts.length) {
      return true;
    }

    if (t.isIdentifier(node)) {
      // this part doesn't match
      if (!matches(node.name)) return false;
    } else if (t.isLiteral(node)) {
      // this part doesn't match
      if (!matches(node.value)) return false;
    } else if (t.isMemberExpression(node)) {
      if (node.computed && !t.isLiteral(node.property)) {
        // we can't deal with this
        return false;
      } else {
        search.unshift(node.property);
        search.unshift(node.object);
        continue;
      }
    } else if (t.isThisExpression(node)) {
      if (!matches("this")) return false;
    } else {
      // we can't deal with this
      return false;
    }

    // too many parts
    if (++i > parts.length) {
      return false;
    }
  }

  return i === parts.length;
}

/**
 * Check whether we have the input `key`. If the `key` references an array then we check
 * if the array has any items, otherwise we just check if it's falsy.
 */

export function has(key): boolean {
  let val = this.node[key];
  if (val && Array.isArray(val)) {
    return !!val.length;
  } else {
    return !!val;
  }
}

/**
 * Description
 */

export function isStatic() {
  return this.scope.isStatic(this.node);
}

/**
 * Alias of `has`.
 */

export let is = has;

/**
 * Opposite of `has`.
 */

export function isnt(key): boolean {
  return !this.has(key);
}

/**
 * Check whether the path node `key` strict equals `value`.
 */

export function equals(key, value): boolean {
  return this.node[key] === value;
}

/**
 * Check the type against our stored internal type of the node. This is handy when a node has
 * been removed yet we still internally know the type and need it to calculate node replacement.
 */

export function isNodeType(type: string): boolean {
  return t.isType(this.type, type);
}

/**
 * This checks whether or now we're in one of the following positions:
 *
 *   for (KEY in right);
 *   for (KEY;;);
 *
 * This is because these spots allow VariableDeclarations AND normal expressions so we need
 * to tell the path replacement that it's ok to replace this with an expression.
 */

 export function canHaveVariableDeclarationOrExpression() {
    return (this.key === "init" || this.key === "left") && this.parentPath.isFor();
 }

/**
 * Check whether the current path references a completion record
 */

export function isCompletionRecord(allowInsideFunction?) {
  let path = this;
  let first = true;

  do {
    let container = path.container;

    // we're in a function so can't be a completion record
    if (path.isFunction() && !first) {
      return !!allowInsideFunction;
    }

    first = false;

    // check to see if we're the last item in the container and if we are
    // we're a completion record!
    if (Array.isArray(container) && path.key !== container.length - 1) {
      return false;
    }
  } while ((path = path.parentPath) && !path.isProgram());

  return true;
}

/**
 * Check whether or not the current `key` allows either a single statement or block statement
 * so we can explode it if necessary.
 */

export function isStatementOrBlock() {
  if (this.parentPath.isLabeledStatement() || t.isBlockStatement(this.container)) {
    return false;
  } else {
    return includes(t.STATEMENT_OR_BLOCK_KEYS, this.key);
  }
}

/**
 * Check if the currently assigned path references the `importName` of `moduleSource`.
 */

export function referencesImport(moduleSource, importName) {
  if (!this.isReferencedIdentifier()) return false;

  let binding = this.scope.getBinding(this.node.name);
  if (!binding || binding.kind !== "module") return false;

  let path = binding.path;
  let parent = path.parentPath;
  if (!parent.isImportDeclaration()) return false;

  // check moduleSource
  if (parent.node.source.value === moduleSource) {
    if (!importName) return true;
  } else {
    return false;
  }

  if (path.isImportDefaultSpecifier() && importName === "default") {
    return true;
  }

  if (path.isImportNamespaceSpecifier() && importName === "*") {
    return true;
  }

  if (path.isImportSpecifier() && path.node.imported.name === importName) {
    return true;
  }

  return false;
}

/**
 * Get the source code associated with this node.
 */

export function getSource() {
  let node = this.node;
  if (node.end) {
    return this.hub.file.code.slice(node.start, node.end);
  } else {
    return "";
  }
}

export function willIMaybeExecuteBefore(target) {
  return this._guessExecutionStatusRelativeTo(target) !== "after";
}

/**
 * Given a `target` check the execution status of it relative to the current path.
 *
 * "Execution status" simply refers to where or not we **think** this will execuete
 * before or after the input `target` element.
 */

export function _guessExecutionStatusRelativeTo(target) {
  // check if the two paths are in different functions, we can't track execution of these
  let targetFuncParent = target.scope.getFunctionParent();
  let selfFuncParent = this.scope.getFunctionParent();

  if (targetFuncParent !== selfFuncParent) {
    let status = this._guessExecutionStatusRelativeToDifferentFunctions(targetFuncParent);
    if (status) {
      return status;
    } else {
      target = targetFuncParent.path;
    }
  }

  let targetPaths = target.getAncestry();
  if (targetPaths.indexOf(this) >= 0) return "after";

  let selfPaths   = this.getAncestry();

  // get ancestor where the branches intersect
  let commonPath;
  let targetIndex;
  let selfIndex;
  for (selfIndex = 0; selfIndex < selfPaths.length; selfIndex++) {
    let selfPath = selfPaths[selfIndex];
    targetIndex = targetPaths.indexOf(selfPath);
    if (targetIndex >= 0) {
      commonPath = selfPath;
      break;
    }
  }
  if (!commonPath) {
    return "before";
  }

  // get the relationship paths that associate these nodes to their common ancestor
  let targetRelationship = targetPaths[targetIndex - 1];
  let selfRelationship   = selfPaths[selfIndex - 1];
  if (!targetRelationship || !selfRelationship) {
    return "before";
  }

  // container list so let's see which one is after the other
  if (targetRelationship.listKey && targetRelationship.container === selfRelationship.container) {
    return targetRelationship.key > selfRelationship.key ? "before" : "after";
  }

  // otherwise we're associated by a parent node, check which key comes before the other
  let targetKeyPosition = t.VISITOR_KEYS[targetRelationship.type].indexOf(targetRelationship.key);
  let selfKeyPosition   = t.VISITOR_KEYS[selfRelationship.type].indexOf(selfRelationship.key);
  return targetKeyPosition > selfKeyPosition ? "before" : "after";
}

export function _guessExecutionStatusRelativeToDifferentFunctions(targetFuncParent) {
  let targetFuncPath = targetFuncParent.path;
  if (!targetFuncPath.isFunctionDeclaration()) return;

  // so we're in a completely different function, if this is a function declaration
  // then we can be a bit smarter and handle cases where the function is either
  // a. not called at all (part of an export)
  // b. called directly
  let binding = targetFuncPath.scope.getBinding(targetFuncPath.node.id.name);

  // no references!
  if (!binding.references) return "before";

  let referencePaths: Array<NodePath> = binding.referencePaths;

  // verify that all of the references are calls
  for (let path of referencePaths) {
    if (path.key !== "callee" || !path.parentPath.isCallExpression()) {
      return;
    }
  }

  let allStatus;

  // verify that all the calls have the same execution status
  for (let path of referencePaths) {
    // if a reference is a child of the function we're checking against then we can
    // safelty ignore it
    let childOfFunction = !!path.find(path => path === targetFuncPath);
    if (childOfFunction) continue;

    let status = this._guessExecutionStatusRelativeTo(path);

    if (allStatus) {
      if (allStatus !== status) return;
    } else {
      allStatus = status;
    }
  }

  return allStatus;
}

/**
 * Resolve a "pointer" `NodePath` to it's absolute path.
 */

export function resolve(dangerous, resolved) {
  return this._resolve(dangerous, resolved) || this;
}

export function _resolve(dangerous?, resolved?): ?NodePath {
  // detect infinite recursion
  // todo: possibly have a max length on this just to be safe
  if (resolved && resolved.indexOf(this) >= 0) return;

  // we store all the paths we've "resolved" in this array to prevent infinite recursion
  resolved = resolved || [];
  resolved.push(this);

  if (this.isVariableDeclarator()) {
    if (this.get("id").isIdentifier()) {
      return this.get("init").resolve(dangerous, resolved);
    } else {
      // otherwise it's a request for a pattern and that's a bit more tricky
    }
  } else if (this.isReferencedIdentifier()) {
    let binding = this.scope.getBinding(this.node.name);
    if (!binding) return;

    // reassigned so we can't really resolve it
    if (!binding.constant) return;

    // todo - lookup module in dependency graph
    if (binding.kind === "module") return;

    if (binding.path !== this) {
      return binding.path.resolve(dangerous, resolved);
    }
  } else if (this.isTypeCastExpression()) {
    return this.get("expression").resolve(dangerous, resolved);
  } else if (dangerous && this.isMemberExpression()) {
    // this is dangerous, as non-direct target assignments will mutate it's state
    // making this resolution inaccurate

    let targetKey = this.toComputedKey();
    if (!t.isLiteral(targetKey)) return;

    let targetName = targetKey.value;

    let target = this.get("object").resolve(dangerous, resolved);

    if (target.isObjectExpression()) {
      let props = target.get("properties");
      for (let prop of (props: Array)) {
        if (!prop.isProperty()) continue;

        let key = prop.get("key");

        // { foo: obj }
        let match = prop.isnt("computed") && key.isIdentifier({ name: targetName });

        // { "foo": "obj" } or { ["foo"]: "obj" }
        match = match || key.isLiteral({ value: targetName });

        if (match) return prop.get("value").resolve(dangerous, resolved);
      }
    } else if (target.isArrayExpression() && !isNaN(+targetName)) {
      let elems = target.get("elements");
      let elem = elems[targetName];
      if (elem) return elem.resolve(dangerous, resolved);
    }
  }
}
<|endoftext|>


<commit_before>/*********************************************************************************
 * SugarCRM Community Edition is a customer relationship management program developed by
 * SugarCRM, Inc. Copyright (C) 2004-2013 SugarCRM Inc.

 * SuiteCRM is an extension to SugarCRM Community Edition developed by Salesagility Ltd.
 * Copyright (C) 2011 - 2014 Salesagility Ltd.
 *
 * This program is free software; you can redistribute it and/or modify it under
 * the terms of the GNU Affero General Public License version 3 as published by the
 * Free Software Foundation with the addition of the following permission added
 * to Section 15 as permitted in Section 7(a): FOR ANY PART OF THE COVERED WORK
 * IN WHICH THE COPYRIGHT IS OWNED BY SUGARCRM, SUGARCRM DISCLAIMS THE WARRANTY
 * OF NON INFRINGEMENT OF THIRD PARTY RIGHTS.
 *
 * This program is distributed in the hope that it will be useful, but WITHOUT
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
 * FOR A PARTICULAR PURPOSE.  See the GNU Affero General Public License for more
 * details.
 *
 * You should have received a copy of the GNU Affero General Public License along with
 * this program; if not, see http://www.gnu.org/licenses or write to the Free
 * Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
 * 02110-1301 USA.
 *
 * You can contact SugarCRM, Inc. headquarters at 10050 North Wolfe Road,
 * SW2-130, Cupertino, CA 95014, USA. or at email address contact@sugarcrm.com.
 *
 * The interactive user interfaces in modified source and object code versions
 * of this program must display Appropriate Legal Notices, as required under
 * Section 5 of the GNU Affero General Public License version 3.
 *
 * In accordance with Section 7(b) of the GNU Affero General Public License version 3,
 * these Appropriate Legal Notices must retain the display of the "Powered by
 * SugarCRM" logo and "Supercharged by SuiteCRM" logo. If the display of the logos is not
 * reasonably feasible for  technical reasons, the Appropriate Legal Notices must
 * display the words  "Powered by SugarCRM" and "Supercharged by SuiteCRM".
 ********************************************************************************/

//////////////////////////////////////////////////////////////////
// called on the return of a JSON-RPC async request,
// and calls the display() method on the widget registered
// in the registry at the request_id key returned by the server

//////////////////////////////////////////////////////////////////

/**
 * This is the callback function called from SugarRPCClient.prototype.call_method
 * found below.
 * @param o The response object returned by YUI2's ajax request.
 */
function method_callback (o) {
    var resp = YAHOO.lang.JSON.parse(o.responseText),
        request_id = o.tId,
        result = resp.result;

	if(result == null) {
	    return;
	}
    reqid = global_request_registry[request_id];
	if(typeof (reqid)  != 'undefined') {
	    widget = global_request_registry[request_id][0];
	    method_name = global_request_registry[request_id][1];
	    widget[method_name](result);
	}
}

//////////////////////////////////////////////////
// class: SugarVCalClient
// async retrieval/parsing of vCal freebusy info
//
//////////////////////////////////////////////////

SugarClass.inherit("SugarVCalClient","SugarClass");

function SugarVCalClient() {
	this.init();
}

SugarVCalClient.prototype.init = function() {}

SugarVCalClient.prototype.load = function(user_id, request_id) {
    this.user_id = user_id;

    // Bug 44239: Removed reliance on jsolait
    YAHOO.util.Connect.asyncRequest('GET', './vcal_server.php?type=vfb&source=outlook&noAuth=noAuth&user_id=' + user_id, {
        success: function (result) {
            if (typeof GLOBAL_REGISTRY.freebusy == 'undefined') {
                GLOBAL_REGISTRY.freebusy = new Object();
            }
            if (typeof GLOBAL_REGISTRY.freebusy_adjusted == 'undefined') {
                GLOBAL_REGISTRY.freebusy_adjusted = new Object();
            }
            // parse vCal and put it in the registry using the user_id as a key:
            GLOBAL_REGISTRY.freebusy[user_id] = SugarVCalClient.prototype.parseResults(result.responseText, false);
            // parse for current user adjusted vCal
            GLOBAL_REGISTRY.freebusy_adjusted[user_id] = SugarVCalClient.prototype.parseResults(result.responseText, true);
            // now call the display() on the widget registered at request_id:
            global_request_registry[request_id][0].display();
        },
        failure: function(result) { this.success(result); },
        argument: { result: result }
    });
}

// parse vCal freebusy info and return object
SugarVCalClient.prototype.parseResults = function(textResult, adjusted) {
    var matchXFREEBUSYID = /X\-FREEBUSY\-ID.*?\:([\w]+)\-([\w]+)\-([\w]+)\-([\w]+)\-([\w]+)/g;
    var matchFREEBUSY = /FREEBUSY.*?\:([\w]+)\/([\w]+)/g;
    var matchFREEBUSYTYPE = /X\-FREEBUSY\-TYPE.*?\:([\w]+)/g;
    //var resultFREEBUSYID = matchXFREEBUSYID.exec(textResult);
    //var resultFREEBUSY = matchFREEBUSY.exec(textResult);
    //var resultFREEBUSYTYPETEST = matchFREEBUSYTYPE.exec(textResult);

    //  datetime = new SugarDateTime();
    //var result;
    var timehash = new Object();
    var dst_id;
    var dst_start;
    var dst_end;

    if (GLOBAL_REGISTRY.current_user.fields.dst_start == null)
        dst_start = '19700101T000000Z';
    else
        dst_start = GLOBAL_REGISTRY.current_user.fields.dst_start.replace(/ /gi, 'T').replace(/:/gi, '').replace(/-/gi, '') + 'Z';

    if (GLOBAL_REGISTRY.current_user.fields.dst_end == null)
        dst_end = '19700101T000000Z';
    else
        dst_end = GLOBAL_REGISTRY.current_user.fields.dst_end.replace(/ /gi, 'T').replace(/:/gi, '').replace(/-/gi, '') + 'Z';

    gmt_offset_secs = GLOBAL_REGISTRY.current_user.fields.gmt_offset * 60;

    var index = 0;
    // New loop through all FREEBUSY & Customer Values
    while (
            ((resultFREEBUSYID = matchXFREEBUSYID.exec(textResult))) != null &&
            ((resultFREEBUSY = matchFREEBUSY.exec(textResult))) != null &&
            ((resultFREEBUSYTYPE = matchFREEBUSYTYPE.exec(textResult))) != null
        ) {
        var startdate;
        var enddate;
        if (adjusted) {// send back adjusted for current_user
            startdate = SugarDateTime.parseAdjustedDate(resultFREEBUSY[1], dst_start, dst_end, gmt_offset_secs);
            enddate = SugarDateTime.parseAdjustedDate(resultFREEBUSY[2], dst_start, dst_end, gmt_offset_secs);
        }
        else { // GMT
            startdate = SugarDateTime.parseUTCDate(resultFREEBUSY[1]);
            enddate = SugarDateTime.parseUTCDate(resultFREEBUSY[2]);
        }

        var startmins = startdate.getUTCMinutes();

        // pick the start slot based on the minutes
        if (startmins >= 0 && startmins < 15) {
            startdate.setUTCMinutes(0);
        }
        else if (startmins >= 15 && startmins < 30) {
            startdate.setUTCMinutes(15);
        }
        else if (startmins >= 30 && startmins < 45) {
            startdate.setUTCMinutes(30);
        }
        else {
            startdate.setUTCMinutes(45);
        }

        // starting at startdate, create hash of each busy 15 min
        // timeslot and store as a key
        while (startdate.valueOf() < enddate.valueOf()) {
            var hash = SugarDateTime.getUTCHash(startdate);
            id = resultFREEBUSYID[1] + '-' +
                resultFREEBUSYID[2] + '-' +
                resultFREEBUSYID[3] + '-' +
                resultFREEBUSYID[4] + '-' +
                resultFREEBUSYID[5];

            if (typeof (timehash[hash]) == 'undefined') {
                timehash[hash] = {
                    records : {}
                    //'items' : 1
                }
                timehash[hash]['records'][id] = resultFREEBUSYTYPE[1];

            } else {
                //timehash[hash]['items'] += 1;
                timehash[hash]['records'][id] = resultFREEBUSYTYPE[1];
            }

            startdate = new Date(startdate.valueOf() + (15 * 60 * 1000));
        }
        index++;
    }

    return timehash;
}

SugarVCalClient.parseResults = SugarVCalClient.prototype.parseResults;
//////////////////////////////////////////////////
// class: SugarRPCClient
// wrapper around async JSON-RPC client class
//
//////////////////////////////////////////////////
SugarRPCClient.allowed_methods = ['retrieve','query','save','set_accept_status','get_objects_from_module', 'email', 'get_user_array', 'get_full_list'];

SugarClass.inherit("SugarRPCClient","SugarClass");

function SugarRPCClient() {
	this.init();
}

/*
 * PUT NEW METHODS IN THIS ARRAY:
 */
SugarRPCClient.prototype.allowed_methods = ['retrieve','query','get_objects_from_module'];

SugarRPCClient.prototype.init = function() {
	this._showError= function (e){
		alert("ERROR CONNECTING to: ./index.php?entryPoint=json_server, ERROR:"+e);
	}
	this.serviceURL = './index.php?entryPoint=json_server';
}

/**
 * Note: This method used to depend on JSOlait which is now removed. It has been reworked to use YUI for the aynchronous call
 * and the synchronous call in sugar_3.js.
 * @param method
 * @param args
 * @param synchronous Pass in true if synchronous call is desired
 */
SugarRPCClient.prototype.call_method = function(method, args, synchronous) {
    var result,
        transaction,
        post_data = YAHOO.lang.JSON.stringify({method: method, id: 1, params: [args]});

    synchronous = synchronous || false;

    try {
        if (synchronous) {
            result = http_fetch_sync(this.serviceURL, post_data);
            result = YAHOO.lang.JSON.parse(result.responseText).result;
            return result;
        } else { // asynchronous call
            // note: Unfortunately we don't have a separate error handler and it is built into the method_callback. Maybe a future todo.
            transaction = YAHOO.util.Connect.asyncRequest('POST', this.serviceURL, {success: method_callback, failure: method_callback}, post_data);
            return transaction.tId;
        }
    } catch(e) { // error before calling server
        this._showError(e);
    }
}

var global_rpcClient =  new SugarRPCClient();<commit_msg>Fixed #208 - take Daylight saving time into consideration. Also, dont forget to change System Settings -> vCal Updates Time Period in order to see more than 2 months.<commit_after>/*********************************************************************************
 * SugarCRM Community Edition is a customer relationship management program developed by
 * SugarCRM, Inc. Copyright (C) 2004-2013 SugarCRM Inc.

 * SuiteCRM is an extension to SugarCRM Community Edition developed by Salesagility Ltd.
 * Copyright (C) 2011 - 2014 Salesagility Ltd.
 *
 * This program is free software; you can redistribute it and/or modify it under
 * the terms of the GNU Affero General Public License version 3 as published by the
 * Free Software Foundation with the addition of the following permission added
 * to Section 15 as permitted in Section 7(a): FOR ANY PART OF THE COVERED WORK
 * IN WHICH THE COPYRIGHT IS OWNED BY SUGARCRM, SUGARCRM DISCLAIMS THE WARRANTY
 * OF NON INFRINGEMENT OF THIRD PARTY RIGHTS.
 *
 * This program is distributed in the hope that it will be useful, but WITHOUT
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
 * FOR A PARTICULAR PURPOSE.  See the GNU Affero General Public License for more
 * details.
 *
 * You should have received a copy of the GNU Affero General Public License along with
 * this program; if not, see http://www.gnu.org/licenses or write to the Free
 * Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
 * 02110-1301 USA.
 *
 * You can contact SugarCRM, Inc. headquarters at 10050 North Wolfe Road,
 * SW2-130, Cupertino, CA 95014, USA. or at email address contact@sugarcrm.com.
 *
 * The interactive user interfaces in modified source and object code versions
 * of this program must display Appropriate Legal Notices, as required under
 * Section 5 of the GNU Affero General Public License version 3.
 *
 * In accordance with Section 7(b) of the GNU Affero General Public License version 3,
 * these Appropriate Legal Notices must retain the display of the "Powered by
 * SugarCRM" logo and "Supercharged by SuiteCRM" logo. If the display of the logos is not
 * reasonably feasible for  technical reasons, the Appropriate Legal Notices must
 * display the words  "Powered by SugarCRM" and "Supercharged by SuiteCRM".
 ********************************************************************************/

//////////////////////////////////////////////////////////////////
// called on the return of a JSON-RPC async request,
// and calls the display() method on the widget registered
// in the registry at the request_id key returned by the server

//////////////////////////////////////////////////////////////////

/**
 * This is the callback function called from SugarRPCClient.prototype.call_method
 * found below.
 * @param o The response object returned by YUI2's ajax request.
 */
function method_callback (o) {
    var resp = YAHOO.lang.JSON.parse(o.responseText),
        request_id = o.tId,
        result = resp.result;

	if(result == null) {
	    return;
	}
    reqid = global_request_registry[request_id];
	if(typeof (reqid)  != 'undefined') {
	    widget = global_request_registry[request_id][0];
	    method_name = global_request_registry[request_id][1];
	    widget[method_name](result);
	}
}

//////////////////////////////////////////////////
// class: SugarVCalClient
// async retrieval/parsing of vCal freebusy info
//
//////////////////////////////////////////////////

SugarClass.inherit("SugarVCalClient","SugarClass");

function SugarVCalClient() {
	this.init();
}

SugarVCalClient.prototype.init = function() {}

SugarVCalClient.prototype.load = function(user_id, request_id) {
    this.user_id = user_id;

    // Bug 44239: Removed reliance on jsolait
    YAHOO.util.Connect.asyncRequest('GET', './vcal_server.php?type=vfb&source=outlook&noAuth=noAuth&user_id=' + user_id, {
        success: function (result) {
            if (typeof GLOBAL_REGISTRY.freebusy == 'undefined') {
                GLOBAL_REGISTRY.freebusy = new Object();
            }
            if (typeof GLOBAL_REGISTRY.freebusy_adjusted == 'undefined') {
                GLOBAL_REGISTRY.freebusy_adjusted = new Object();
            }
            // parse vCal and put it in the registry using the user_id as a key:
            GLOBAL_REGISTRY.freebusy[user_id]=SugarVCalClient.prototype.parseResults(result.responseText,false , global_request_registry[request_id][0].timeslots[0].date_obj);
            // parse for current user adjusted vCal
            GLOBAL_REGISTRY.freebusy_adjusted[user_id]=SugarVCalClient.prototype.parseResults(result.responseText,true, global_request_registry[request_id][0].timeslots[0].date_obj);
            // now call the display() on the widget registered at request_id:
            global_request_registry[request_id][0].display();
        },
        failure: function(result) { this.success(result); },
        argument: { result: result }
    });
}

// parse vCal freebusy info and return object
SugarVCalClient.prototype.parseResults = function(textResult, adjusted, meetingDate) {
    var matchXFREEBUSYID = /X\-FREEBUSY\-ID.*?\:([\w]+)\-([\w]+)\-([\w]+)\-([\w]+)\-([\w]+)/g;
    var matchFREEBUSY = /FREEBUSY.*?\:([\w]+)\/([\w]+)/g;
    var matchFREEBUSYTYPE = /X\-FREEBUSY\-TYPE.*?\:([\w]+)/g;
    //var resultFREEBUSYID = matchXFREEBUSYID.exec(textResult);
    //var resultFREEBUSY = matchFREEBUSY.exec(textResult);
    //var resultFREEBUSYTYPETEST = matchFREEBUSYTYPE.exec(textResult);

    //  datetime = new SugarDateTime();
    //var result;
    var timehash = new Object();
    var dst_id;
    var dst_start;
    var dst_end;

    if (GLOBAL_REGISTRY.current_user.fields.dst_start == null)
        dst_start = '19700101T000000Z';
    else
        dst_start = GLOBAL_REGISTRY.current_user.fields.dst_start.replace(/ /gi, 'T').replace(/:/gi, '').replace(/-/gi, '') + 'Z';

    if (GLOBAL_REGISTRY.current_user.fields.dst_end == null)
        dst_end = '19700101T000000Z';
    else
        dst_end = GLOBAL_REGISTRY.current_user.fields.dst_end.replace(/ /gi, 'T').replace(/:/gi, '').replace(/-/gi, '') + 'Z';

    // Fix for issue #208 - take Daylight saving time into consideration
    var d = new Date(meetingDate);
    var offset = d.getTimezoneOffset();

    if (offset > 0 || offset < 0) {
        gmt_offset_secs= 60 * 60;
    } else {
        gmt_offset_secs = GLOBAL_REGISTRY.current_user.fields.gmt_offset*60;
    }

    var index = 0;
    // New loop through all FREEBUSY & Customer Values
    while (
            ((resultFREEBUSYID = matchXFREEBUSYID.exec(textResult))) != null &&
            ((resultFREEBUSY = matchFREEBUSY.exec(textResult))) != null &&
            ((resultFREEBUSYTYPE = matchFREEBUSYTYPE.exec(textResult))) != null
        ) {
        var startdate;
        var enddate;
        if (adjusted) {// send back adjusted for current_user
            startdate = SugarDateTime.parseAdjustedDate(resultFREEBUSY[1], dst_start, dst_end, gmt_offset_secs);
            enddate = SugarDateTime.parseAdjustedDate(resultFREEBUSY[2], dst_start, dst_end, gmt_offset_secs);
        }
        else { // GMT
            startdate = SugarDateTime.parseUTCDate(resultFREEBUSY[1]);
            enddate = SugarDateTime.parseUTCDate(resultFREEBUSY[2]);
        }

        var startmins = startdate.getUTCMinutes();

        // pick the start slot based on the minutes
        if (startmins >= 0 && startmins < 15) {
            startdate.setUTCMinutes(0);
        }
        else if (startmins >= 15 && startmins < 30) {
            startdate.setUTCMinutes(15);
        }
        else if (startmins >= 30 && startmins < 45) {
            startdate.setUTCMinutes(30);
        }
        else {
            startdate.setUTCMinutes(45);
        }

        // starting at startdate, create hash of each busy 15 min
        // timeslot and store as a key
        while (startdate.valueOf() < enddate.valueOf()) {
            var hash = SugarDateTime.getUTCHash(startdate);
            id = resultFREEBUSYID[1] + '-' +
                resultFREEBUSYID[2] + '-' +
                resultFREEBUSYID[3] + '-' +
                resultFREEBUSYID[4] + '-' +
                resultFREEBUSYID[5];

            if (typeof (timehash[hash]) == 'undefined') {
                timehash[hash] = {
                    records : {}
                    //'items' : 1
                }
                timehash[hash]['records'][id] = resultFREEBUSYTYPE[1];

            } else {
                //timehash[hash]['items'] += 1;
                timehash[hash]['records'][id] = resultFREEBUSYTYPE[1];
            }

            startdate = new Date(startdate.valueOf() + (15 * 60 * 1000));
        }
        index++;
    }

    return timehash;
}

SugarVCalClient.parseResults = SugarVCalClient.prototype.parseResults;
//////////////////////////////////////////////////
// class: SugarRPCClient
// wrapper around async JSON-RPC client class
//
//////////////////////////////////////////////////
SugarRPCClient.allowed_methods = ['retrieve','query','save','set_accept_status','get_objects_from_module', 'email', 'get_user_array', 'get_full_list'];

SugarClass.inherit("SugarRPCClient","SugarClass");

function SugarRPCClient() {
	this.init();
}

/*
 * PUT NEW METHODS IN THIS ARRAY:
 */
SugarRPCClient.prototype.allowed_methods = ['retrieve','query','get_objects_from_module'];

SugarRPCClient.prototype.init = function() {
	this._showError= function (e){
		alert("ERROR CONNECTING to: ./index.php?entryPoint=json_server, ERROR:"+e);
	}
	this.serviceURL = './index.php?entryPoint=json_server';
}

/**
 * Note: This method used to depend on JSOlait which is now removed. It has been reworked to use YUI for the aynchronous call
 * and the synchronous call in sugar_3.js.
 * @param method
 * @param args
 * @param synchronous Pass in true if synchronous call is desired
 */
SugarRPCClient.prototype.call_method = function(method, args, synchronous) {
    var result,
        transaction,
        post_data = YAHOO.lang.JSON.stringify({method: method, id: 1, params: [args]});

    synchronous = synchronous || false;

    try {
        if (synchronous) {
            result = http_fetch_sync(this.serviceURL, post_data);
            result = YAHOO.lang.JSON.parse(result.responseText).result;
            return result;
        } else { // asynchronous call
            // note: Unfortunately we don't have a separate error handler and it is built into the method_callback. Maybe a future todo.
            transaction = YAHOO.util.Connect.asyncRequest('POST', this.serviceURL, {success: method_callback, failure: method_callback}, post_data);
            return transaction.tId;
        }
    } catch(e) { // error before calling server
        this._showError(e);
    }
}

var global_rpcClient =  new SugarRPCClient();<|endoftext|>