<commit_before>(function(mod) {
  if (typeof exports == "object" && typeof module == "object") // CommonJS
    return mod(require("tern/lib/infer"), require("tern/lib/tern"));
  if (typeof define == "function" && define.amd) // AMD
    return define([ "tern/lib/infer", "tern/lib/tern" ], mod);
  mod(tern, tern);
})(function(infer, tern) {
  "use strict";

  infer.registerFunction("express_render", function(_self, _args, argNodes) {
    if (argNodes && argNodes.length && argNodes.length== 2) {
      var arg = _args[1], argNode = argNodes[1], fn = getFunctionType(arg, argNode);
      if (fn) {
        // here we support the second signature.
        var params = fn.argNames, cx = infer.cx(), paths = cx.paths;
        var fnArgs = [];
        for (var j = 0; j < params.length; j++) {
          switch(j) {
          case 0: // Error
            fnArgs.push(new infer.Obj(paths["Error.prototype"]));
            break;
          case 1: // String
            fnArgs.push(new infer.Obj(paths["String.prototype"]));
            break;
          }
        }
        fn.propagate(new infer.IsCallee(infer.cx().topScope, fnArgs, null, infer.ANull))
      }
    }
  });

  infer.registerFunction("express_callback", function(_self, _args, argNodes) {
    // router.use can have 2 signatures :
    // - router.use(string, fn(req, resp, next))
    // - router.use(fn(req, resp, next))
    // tern can support only one signature with JSON Type Definition. In your case
    // we support the first signature (see Router.prototype.use)
    if (argNodes && argNodes.length) {
      for (var i = 0; i < argNodes.length; i++) {
        var arg = _args[i], argNode = argNodes[i], fn = getFunctionType(arg, argNode);
        if (fn) {
          // here we support the second signature.
          var params = fn.argNames, cx = infer.cx(), paths = cx.paths;
          var fnArgs = [];
          for (var j = 0; j < params.length; j++) {
            switch(j) {
            case 0: // Request
              fnArgs.push(new infer.Obj(paths["Request.prototype"]));
              break;
            case 1: // Response
              fnArgs.push(new infer.Obj(paths["Response.prototype"]));
              break;
            case 2: // next
              fnArgs.push(new infer.Fn(null, infer.ANull, [], [], infer.ANull));
              break;
            }
          }
          fn.propagate(new infer.IsCallee(infer.cx().topScope, fnArgs, null, infer.ANull))
        }
      }
    }
  });

  function getFunctionType(arg, argNode) {
    if (argNode.type =="FunctionExpression") return arg.getFunctionType();
    if (argNode.type =="Identifier" && arg.getFunctionType) return arg.getFunctionType();
  }

  tern.registerPlugin("express", function(server, options) {

    return {
      defs: defs
    };
  });

  var defs = {
    "!name": "express",
    "!define": {
      "!node": {
        express: {
          "!type": "fn() -> Application",
          "!url": "http://expressjs.com/4x/api.html#express",
          "!doc": "Create an express application.",
          Router: {
            "!type": "fn(options?: +RouterOptions) -> +Router"
          }
        }
      },
      Application: {
        get: {
          "!type": "fn(path: string, callback: [fn(req: +Request, req: +Response)]) -> !this",
          "!effects": ["custom express_callback"],
          "!url": "http://expressjs.com/4x/api.html#app.VERB",
          "!doc": "The app.VERB() methods provide the routing functionality in Express, where VERB is one of the HTTP verbs (such as app.get()). "
        },
        post: {
          "!type": "fn(path: string, callback: [fn(req: +Request, req: +Response)]) -> !this",
          "!effects": ["custom express_callback"],
          "!url": "http://expressjs.com/4x/api.html#app.VERB",
          "!doc": "The app.VERB() methods provide the routing functionality in Express, where VERB is one of the HTTP verbs (such as app.post()). "
        },
        put: {
          "!type": "fn(path: string, callback: [fn(req: +Request, req: +Response)]) -> !this",
          "!effects": ["custom express_callback"],
          "!url": "http://expressjs.com/4x/api.html#app.VERB",
          "!doc": "The app.VERB() methods provide the routing functionality in Express, where VERB is one of the HTTP verbs (such as app.put()). "
        },
        set: {
          "!type": "fn(name: string, value: ?) -> !this",
          "!url": "http://expressjs.com/4x/api.html#app.set",
          "!doc": "Assigns setting name to value."
        },
        enable: {
          "!type": "fn(name: string) -> !this",
          "!url": "http://expressjs.com/4x/api.html#app.enable",
          "!doc": "Set setting name to true."
        },
        enabled: {
          "!type": "fn(name: string) -> bool",
          "!url": "http://expressjs.com/4x/api.html#app.enabled",
          "!doc": "Check if setting name is enabled."
        },
        disable: {
          "!type": "fn(name: string) -> !this",
          "!url": "http://expressjs.com/4x/api.html#app.disable",
          "!doc": "Set setting name to false."
        },
        disabled: {
          "!type": "fn(name: string) -> bool",
          "!url": "http://expressjs.com/4x/api.html#app.disabled",
          "!doc": "Check if setting name is disabled."
        },
        use: {
          "!type": "fn(path?: string, callback: fn(req: +Request, req: +Response, next: fn())) -> !this",
          "!effects": ["custom express_callback"],
          "!url": "http://expressjs.com/4x/api.html#app.use",
          "!doc" : "Mount the middleware function(s) at the path. If path is not specified, it defaults to \"/\". Mounting a middleware at a path will cause the middleware function to be executed whenever the base of the requested path matches the path."
        },
        engine: {
          "!type": "fn(ext: string, callback: fn()) -> !this",
          "!url": "http://expressjs.com/4x/api.html#app.engine",
          "!doc": "Register the given template engine callback as ext. By default, Express will require() the engine based on the file extension. For example if you try to render a \"foo.jade\" file Express will invoke the following internally, and cache the require() on subsequent calls to increase performance."
        },
        param: {
          "!type": "fn(name?: string, callback: fn(req: +Request, req: +Response, next: fn())) -> !this",
          "!effects": ["custom express_callback"],
          "!url": "http://expressjs.com/4x/api.html#app.param",
          "!doc" : "Map logic to route parameters. For example, when :user is present in a route path, you may map user loading logic to automatically provide req.user to the route, or perform validations on the parameter input."
        },
        all: {
          "!type": "fn(path: string, callback: [fn(req: +Request, req: +Response)]) -> !this",
          "!effects": ["custom express_callback"],
          "!url": "http://expressjs.com/4x/api.html#app.all",
          "!doc" : "This method functions just like the app.VERB() methods, however it matches all HTTP verbs. This method is extremely useful for mapping \"global\" logic for specific path prefixes or arbitrary matches. For example if you placed the following route at the top of all other route definitions, it would require that all routes from that point on would require authentication, and automatically load a user. Keep in mind that these callbacks do not have to act as end points, loadUser can perform a task, then next() to continue matching subsequent routes."
        },
        route: {
          "!type": "fn(path: string) -> +Route",
          "!url": "http://expressjs.com/4x/api.html#app.route",
          "!doc": "Returns an instance of a single route, which can then be used to handle HTTP verbs with optional middleware. Using app.route() is a recommended approach for avoiding duplicate route names (and thus typo errors)."
        },
        locals: {
          "!type": "+Object",
          "!url": "http://expressjs.com/4x/api.html#app.locals",
          "!doc": "Application local variables are provided to all templates rendered within the application. This is useful for providing helper functions to templates, as well as app-level data."
        },
        render: {
          "!type": "fn(view: string, options?: string, callback: fn(err: +Error, html: string)) -> !this",
          "!effects": ["custom express_render"],
          "!url": "http://expressjs.com/4x/api.html#app.render",
          "!doc" : "Render a view with a callback responding with the rendered string. This is the app-level variant of res.render(), and otherwise behaves the same way."
        },
        listen: {
          "!type": "fn(port: number, hostname?: string, backlog?: number, callback?: fn())",
          "!url": "http://expressjs.com/4x/api.html#app.listen",
          "!doc": "Bind and listen for connections on the given host and port. This method is identical to node's http.Server#listen()."
        },
        path: {
          "!type": "fn() -> string",
          "!url": "http://expressjs.com/4x/api.html#app.path",
          "!doc": "Returns the canonical path of the app."
        },
        mountpath: {
          "!type": "string",
          "!url": "http://expressjs.com/4x/api.html#app.mountpath",
          "!doc": "This property refers to the path pattern(s) on which a sub app was mounted."
        },
        on: {
          "!type": "fn(name: string, callback: fn(parent: Application))",
          "!url": "http://expressjs.com/4x/api.html#app.onmount",
          "!doc" : "The mount event is fired on a sub app, when it is mounted on a parent app. The parent app is passed to the callback function."
        }
      },
      Request: {
        "!type": "fn()",
        prototype : {
          "!proto" : "http.IncomingMessage.prototype",
          param: {
            "!type": "fn(name: string, defaultValue?: ?)",
            "!url": "http://expressjs.com/4x/api.html#req.param",
            "!doc": "Return the value of param name when present."
          }
        }
      },
      Response: {
        "!type": "fn()",
        prototype : {
          "!proto" : "http.ServerResponse.prototype",
          send: {
            "!type": "fn(body?: ?)",
            "!url": "http://expressjs.com/4x/api.html#res.send",
            "!doc": "Send a response."
          }
        }
      },
      Route: {
        "!type": "fn()",
        prototype : {
          all: {
            "!type": "fn(name?: string, callback: fn(req: +Request, req: +Response, next: fn())) -> !this",
            "!effects": ["custom express_callback"],
            "!url": "http://expressjs.com/4x/api.html#app.all",
            "!doc" : "This method functions just like the app.VERB() methods, however it matches all HTTP verbs. This method is extremely useful for mapping \"global\" logic for specific path prefixes or arbitrary matches. For example if you placed the following route at the top of all other route definitions, it would require that all routes from that point on would require authentication, and automatically load a user. Keep in mind that these callbacks do not have to act as end points, loadUser can perform a task, then next() to continue matching subsequent routes."
          },
        }
      },
      Router: {
        "!type": "fn()",
        prototype : {
          use: {
            "!type": "fn(path?: string, callback: fn(req: +Request, req: +Response, next: fn())) -> !this",
            "!effects": ["custom express_callback"],
            "!url": "http://expressjs.com/4x/api.html#router.use",
            "!doc" : "Use the given middleware function, with optional mount path, defaulting to "/". Middleware is like a plumbing pipe, requests start at the first middleware you define and work their way \"down\" the middleware stack processing for each path they match."
          },
          param: {
            "!type": "fn(name?: string, callback: fn(req: +Request, req: +Response, next: fn(), id: ?)) -> !this",
            "!url": "http://expressjs.com/4x/api.html#router.param",
            "!doc" : "Map logic to route parameters. For example, when :user is present in a route path you may map user loading logic to automatically provide req.user to the route, or perform validations on the parameter input."
          }
        }
      },
      RouterOptions: {
        caseSensitive : {
          "!type": "bool"
        },
        strict : {
          "!type": "string"
        },
        mergeParams : {
          "!type": "bool"
        }
      }
    }
  }
});
<commit_msg>Upon http://expressjs.com/4x/api.html#req.query<commit_after>(function(mod) {
  if (typeof exports == "object" && typeof module == "object") // CommonJS
    return mod(require("tern/lib/infer"), require("tern/lib/tern"));
  if (typeof define == "function" && define.amd) // AMD
    return define([ "tern/lib/infer", "tern/lib/tern" ], mod);
  mod(tern, tern);
})(function(infer, tern) {
  "use strict";

  infer.registerFunction("express_render", function(_self, _args, argNodes) {
    if (argNodes && argNodes.length && argNodes.length== 2) {
      var arg = _args[1], argNode = argNodes[1], fn = getFunctionType(arg, argNode);
      if (fn) {
        // here we support the second signature.
        var params = fn.argNames, cx = infer.cx(), paths = cx.paths;
        var fnArgs = [];
        for (var j = 0; j < params.length; j++) {
          switch(j) {
          case 0: // Error
            fnArgs.push(new infer.Obj(paths["Error.prototype"]));
            break;
          case 1: // String
            fnArgs.push(new infer.Obj(paths["String.prototype"]));
            break;
          }
        }
        fn.propagate(new infer.IsCallee(infer.cx().topScope, fnArgs, null, infer.ANull))
      }
    }
  });

  infer.registerFunction("express_callback", function(_self, _args, argNodes) {
    // router.use can have 2 signatures :
    // - router.use(string, fn(req, resp, next))
    // - router.use(fn(req, resp, next))
    // tern can support only one signature with JSON Type Definition. In your case
    // we support the first signature (see Router.prototype.use)
    if (argNodes && argNodes.length) {
      for (var i = 0; i < argNodes.length; i++) {
        var arg = _args[i], argNode = argNodes[i], fn = getFunctionType(arg, argNode);
        if (fn) {
          // here we support the second signature.
          var params = fn.argNames, cx = infer.cx(), paths = cx.paths;
          var fnArgs = [];
          for (var j = 0; j < params.length; j++) {
            switch(j) {
            case 0: // Request
              fnArgs.push(new infer.Obj(paths["Request.prototype"]));
              break;
            case 1: // Response
              fnArgs.push(new infer.Obj(paths["Response.prototype"]));
              break;
            case 2: // next
              fnArgs.push(new infer.Fn(null, infer.ANull, [], [], infer.ANull));
              break;
            }
          }
          fn.propagate(new infer.IsCallee(infer.cx().topScope, fnArgs, null, infer.ANull))
        }
      }
    }
  });

  function getFunctionType(arg, argNode) {
    if (argNode.type =="FunctionExpression") return arg.getFunctionType();
    if (argNode.type =="Identifier" && arg.getFunctionType) return arg.getFunctionType();
  }

  tern.registerPlugin("express", function(server, options) {

    return {
      defs: defs
    };
  });

  var defs = {
    "!name": "express",
    "!define": {
      "!node": {
        express: {
          "!type": "fn() -> Application",
          "!url": "http://expressjs.com/4x/api.html#express",
          "!doc": "Create an express application.",
          Router: {
            "!type": "fn(options?: +RouterOptions) -> +Router"
          }
        }
      },
      Application: {
        get: {
          "!type": "fn(path: string, callback: [fn(req: +Request, req: +Response)]) -> !this",
          "!effects": ["custom express_callback"],
          "!url": "http://expressjs.com/4x/api.html#app.VERB",
          "!doc": "The app.VERB() methods provide the routing functionality in Express, where VERB is one of the HTTP verbs (such as app.get()). "
        },
        post: {
          "!type": "fn(path: string, callback: [fn(req: +Request, req: +Response)]) -> !this",
          "!effects": ["custom express_callback"],
          "!url": "http://expressjs.com/4x/api.html#app.VERB",
          "!doc": "The app.VERB() methods provide the routing functionality in Express, where VERB is one of the HTTP verbs (such as app.post()). "
        },
        put: {
          "!type": "fn(path: string, callback: [fn(req: +Request, req: +Response)]) -> !this",
          "!effects": ["custom express_callback"],
          "!url": "http://expressjs.com/4x/api.html#app.VERB",
          "!doc": "The app.VERB() methods provide the routing functionality in Express, where VERB is one of the HTTP verbs (such as app.put()). "
        },
        set: {
          "!type": "fn(name: string, value: ?) -> !this",
          "!url": "http://expressjs.com/4x/api.html#app.set",
          "!doc": "Assigns setting name to value."
        },
        enable: {
          "!type": "fn(name: string) -> !this",
          "!url": "http://expressjs.com/4x/api.html#app.enable",
          "!doc": "Set setting name to true."
        },
        enabled: {
          "!type": "fn(name: string) -> bool",
          "!url": "http://expressjs.com/4x/api.html#app.enabled",
          "!doc": "Check if setting name is enabled."
        },
        disable: {
          "!type": "fn(name: string) -> !this",
          "!url": "http://expressjs.com/4x/api.html#app.disable",
          "!doc": "Set setting name to false."
        },
        disabled: {
          "!type": "fn(name: string) -> bool",
          "!url": "http://expressjs.com/4x/api.html#app.disabled",
          "!doc": "Check if setting name is disabled."
        },
        use: {
          "!type": "fn(path?: string, callback: fn(req: +Request, req: +Response, next: fn())) -> !this",
          "!effects": ["custom express_callback"],
          "!url": "http://expressjs.com/4x/api.html#app.use",
          "!doc" : "Mount the middleware function(s) at the path. If path is not specified, it defaults to \"/\". Mounting a middleware at a path will cause the middleware function to be executed whenever the base of the requested path matches the path."
        },
        engine: {
          "!type": "fn(ext: string, callback: fn()) -> !this",
          "!url": "http://expressjs.com/4x/api.html#app.engine",
          "!doc": "Register the given template engine callback as ext. By default, Express will require() the engine based on the file extension. For example if you try to render a \"foo.jade\" file Express will invoke the following internally, and cache the require() on subsequent calls to increase performance."
        },
        param: {
          "!type": "fn(name?: string, callback: fn(req: +Request, req: +Response, next: fn())) -> !this",
          "!effects": ["custom express_callback"],
          "!url": "http://expressjs.com/4x/api.html#app.param",
          "!doc" : "Map logic to route parameters. For example, when :user is present in a route path, you may map user loading logic to automatically provide req.user to the route, or perform validations on the parameter input."
        },
        all: {
          "!type": "fn(path: string, callback: [fn(req: +Request, req: +Response)]) -> !this",
          "!effects": ["custom express_callback"],
          "!url": "http://expressjs.com/4x/api.html#app.all",
          "!doc" : "This method functions just like the app.VERB() methods, however it matches all HTTP verbs. This method is extremely useful for mapping \"global\" logic for specific path prefixes or arbitrary matches. For example if you placed the following route at the top of all other route definitions, it would require that all routes from that point on would require authentication, and automatically load a user. Keep in mind that these callbacks do not have to act as end points, loadUser can perform a task, then next() to continue matching subsequent routes."
        },
        route: {
          "!type": "fn(path: string) -> +Route",
          "!url": "http://expressjs.com/4x/api.html#app.route",
          "!doc": "Returns an instance of a single route, which can then be used to handle HTTP verbs with optional middleware. Using app.route() is a recommended approach for avoiding duplicate route names (and thus typo errors)."
        },
        locals: {
          "!type": "+Object",
          "!url": "http://expressjs.com/4x/api.html#app.locals",
          "!doc": "Application local variables are provided to all templates rendered within the application. This is useful for providing helper functions to templates, as well as app-level data."
        },
        render: {
          "!type": "fn(view: string, options?: string, callback: fn(err: +Error, html: string)) -> !this",
          "!effects": ["custom express_render"],
          "!url": "http://expressjs.com/4x/api.html#app.render",
          "!doc" : "Render a view with a callback responding with the rendered string. This is the app-level variant of res.render(), and otherwise behaves the same way."
        },
        listen: {
          "!type": "fn(port: number, hostname?: string, backlog?: number, callback?: fn())",
          "!url": "http://expressjs.com/4x/api.html#app.listen",
          "!doc": "Bind and listen for connections on the given host and port. This method is identical to node's http.Server#listen()."
        },
        path: {
          "!type": "fn() -> string",
          "!url": "http://expressjs.com/4x/api.html#app.path",
          "!doc": "Returns the canonical path of the app."
        },
        mountpath: {
          "!type": "string",
          "!url": "http://expressjs.com/4x/api.html#app.mountpath",
          "!doc": "This property refers to the path pattern(s) on which a sub app was mounted."
        },
        on: {
          "!type": "fn(name: string, callback: fn(parent: Application))",
          "!url": "http://expressjs.com/4x/api.html#app.onmount",
          "!doc" : "The mount event is fired on a sub app, when it is mounted on a parent app. The parent app is passed to the callback function."
        }
      },
      Request: {
        "!type": "fn()",
        prototype : {
          "!proto" : "http.IncomingMessage.prototype",
          params: {
            "!type": "+Object",
            "!url": "http://expressjs.com/4x/api.html#req.params",
            "!doc": "This property is an object containing properties mapped to the named route \"parameters\". For example, if you have the route /user/:name, then the \"name\" property is available to you as req.params.name. This object defaults to {}."
          },
          query: {
            "!type": "+Object",
            "!url": "http://expressjs.com/4x/api.html#req.query",
            "!doc": "This property is an object containing the parsed query-string, defaulting to {}."
          },
          param: {
            "!type": "fn(name: string, defaultValue?: ?)",
            "!url": "http://expressjs.com/4x/api.html#req.param",
            "!doc": "Return the value of param name when present."
          }
        }
      },
      Response: {
        "!type": "fn()",
        prototype : {
          "!proto" : "http.ServerResponse.prototype",
          send: {
            "!type": "fn(body?: ?)",
            "!url": "http://expressjs.com/4x/api.html#res.send",
            "!doc": "Send a response."
          }
        }
      },
      Route: {
        "!type": "fn()",
        prototype : {
          all: {
            "!type": "fn(name?: string, callback: fn(req: +Request, req: +Response, next: fn())) -> !this",
            "!effects": ["custom express_callback"],
            "!url": "http://expressjs.com/4x/api.html#app.all",
            "!doc" : "This method functions just like the app.VERB() methods, however it matches all HTTP verbs. This method is extremely useful for mapping \"global\" logic for specific path prefixes or arbitrary matches. For example if you placed the following route at the top of all other route definitions, it would require that all routes from that point on would require authentication, and automatically load a user. Keep in mind that these callbacks do not have to act as end points, loadUser can perform a task, then next() to continue matching subsequent routes."
          },
        }
      },
      Router: {
        "!type": "fn()",
        prototype : {
          use: {
            "!type": "fn(path?: string, callback: fn(req: +Request, req: +Response, next: fn())) -> !this",
            "!effects": ["custom express_callback"],
            "!url": "http://expressjs.com/4x/api.html#router.use",
            "!doc" : "Use the given middleware function, with optional mount path, defaulting to "/". Middleware is like a plumbing pipe, requests start at the first middleware you define and work their way \"down\" the middleware stack processing for each path they match."
          },
          param: {
            "!type": "fn(name?: string, callback: fn(req: +Request, req: +Response, next: fn(), id: ?)) -> !this",
            "!url": "http://expressjs.com/4x/api.html#router.param",
            "!doc" : "Map logic to route parameters. For example, when :user is present in a route path you may map user loading logic to automatically provide req.user to the route, or perform validations on the parameter input."
          }
        }
      },
      RouterOptions: {
        caseSensitive : {
          "!type": "bool"
        },
        strict : {
          "!type": "string"
        },
        mergeParams : {
          "!type": "bool"
        }
      }
    }
  }
});
<|endoftext|>


<commit_before>(function(){
  'use strict';

  var home = angular.module('getCrafty.home', []);

  home.config(function($stateProvider) {
      $stateProvider.state('main', {
        url: '/',
        templateUrl: 'home/home.html',
        controller: 'homeCtrl',
      });
  });

  home.controller('homeCtrl', function($scope, $state, $stateParams, $http, $geolocation, $localStorage, $sessionStorage) {
    var coords = {},
        responsePromise,
        config = {},
        $storage = $scope.$storage;

    $scope.input = {postal: ''};

    if ($storage.stores.length) {
      $scope.stores = $storage.stores;
    } else {
      $scope.doGeolocation();
    }

    $scope.doGeolocation = function() {
      $scope.stores = [];

      $geolocation.getCurrentPosition({
        timeout: 60000
      }).then(function(position) {
        coords = position.coords;
        $scope.getLocations(coords.latitude, coords.longitude);
      });
    };

    $scope.getLocations = function(lat, lon) {
      var responsePromise,
          config = {};

        config.url = 'http://www.getcrafty.co:3000/api/v1/storesNear?lat=' + lat + '&long=' + lon;
        $scope.stores = [];
        $storage.stores = [];
        responsePromise = $http(config);

        responsePromise.success(function(data, status, headers, config) {
          $scope.stores = data;
          $storage.stores = data;
        });

        responsePromise.error(function(data, status, headers, config) {
          alert("AJAX failed!");
        });
    };

    $scope.postalSearch = function(addressQuery) {
      var coords = {},
          postal_pattern = /^[A-Za-z]\d[A-Za-z][ -]?\d[A-Za-z]\d$/,
          city_pattern = /^([a-zA-Z\u0080-\u024F]+(?:. |-| |'))*[a-zA-Z\u0080-\u024F]*$/,
          responsePromise,
          config = {},
          doAjax = false;;

      if (addressQuery.match(postal_pattern)) {
        addressQuery = addressQuery.replace(' ', '').replace('-', '');
        doAjax = true;

        var config = {
          url: 'http://geocoder.ca/?json=1&postal=' + addressQuery
        };
      } else if (addressQuery.match(city_pattern)) {
        doAjax = true;

        var config = {
          url: 'http://geocoder.ca/?json=1&city=' + addressQuery
        };
      }

      if (doAjax) {
        var responsePromise = $http(config);

        responsePromise.success(function(data, status, headers, config) {
          if (typeof(data.error) !== undefined) {
            $scope.getLocations(data.latt, data.longt);
          } else {
            $scope.stores = [];
            $storage.stores = [];
            $scope.storesError = 'Please try your search again!';
          }
        });
      } else {
        $scope.stores = [];
        $storage.stores = [];
        $scope.storesError = 'Please try your search again!';
      }
    }
  });
})();
<commit_msg>move function call to after the function declaration<commit_after>(function(){
  'use strict';

  var home = angular.module('getCrafty.home', []);

  home.config(function($stateProvider) {
      $stateProvider.state('main', {
        url: '/',
        templateUrl: 'home/home.html',
        controller: 'homeCtrl',
      });
  });

  home.controller('homeCtrl', function($scope, $state, $stateParams, $http, $geolocation, $localStorage, $sessionStorage) {
    var coords = {},
        responsePromise,
        config = {},
        $storage = $scope.$storage;

    $scope.input = {postal: ''};

    $scope.doGeolocation = function() {
      $scope.stores = [];

      $geolocation.getCurrentPosition({
        timeout: 60000
      }).then(function(position) {
        coords = position.coords;
        $scope.getLocations(coords.latitude, coords.longitude);
      });
    };

    $scope.getLocations = function(lat, lon) {
      var responsePromise,
          config = {};

        config.url = 'http://www.getcrafty.co:3000/api/v1/storesNear?lat=' + lat + '&long=' + lon;
        $scope.stores = [];
        $storage.stores = [];
        responsePromise = $http(config);

        responsePromise.success(function(data, status, headers, config) {
          $scope.stores = data;
          $storage.stores = data;
        });

        responsePromise.error(function(data, status, headers, config) {
          alert("AJAX failed!");
        });
    };

    $scope.postalSearch = function(addressQuery) {
      var coords = {},
          postal_pattern = /^[A-Za-z]\d[A-Za-z][ -]?\d[A-Za-z]\d$/,
          city_pattern = /^([a-zA-Z\u0080-\u024F]+(?:. |-| |'))*[a-zA-Z\u0080-\u024F]*$/,
          responsePromise,
          config = {},
          doAjax = false;;

      if (addressQuery.match(postal_pattern)) {
        addressQuery = addressQuery.replace(' ', '').replace('-', '');
        doAjax = true;

        var config = {
          url: 'http://geocoder.ca/?json=1&postal=' + addressQuery
        };
      } else if (addressQuery.match(city_pattern)) {
        doAjax = true;

        var config = {
          url: 'http://geocoder.ca/?json=1&city=' + addressQuery
        };
      }

      if (doAjax) {
        var responsePromise = $http(config);

        responsePromise.success(function(data, status, headers, config) {
          if (typeof(data.error) !== undefined) {
            $scope.getLocations(data.latt, data.longt);
          } else {
            $scope.stores = [];
            $storage.stores = [];
            $scope.storesError = 'Please try your search again!';
          }
        });
      } else {
        $scope.stores = [];
        $storage.stores = [];
        $scope.storesError = 'Please try your search again!';
      }
    }

    if ($storage.stores.length) {
      $scope.stores = $storage.stores;
    } else {
      $scope.doGeolocation();
    }
  });
})();
<|endoftext|>


<commit_before>import mm723Image from '../../images/MM723_CNL_combo@2x.jpg';
const devices = {
  carelink: {
    instructions: ['Import from CareLink', '(We will not store your credentials)'],
    isFetching: false,
    key: 'carelink',
    name: 'Medtronic',
    // for the device selection list
    selectName: 'Medtronic (from CareLink)',
    source: {type: 'carelink'},
    enabled: {mac: true, win: true}
  },
  medtronic: {
    instructions: 'Connect your Bayer Contour Next Link to your computer',
    image: {
      'src': mm723Image,
      'height': 128,
      'width': 200,
      'alt': 'Bayer Contour Next Link'
    },
    key: 'medtronic',
    name: 'Medtronic - 523, 723 or 530G',
    selectName: 'Medtronic direct from Bayer Contour Next Link',
    source: {type: 'device', driverId: 'Medtronic'},
    enabled: {mac: true, win: true}
  },
  omnipod: {
    instructions: 'Plug in PDM with mini-USB and choose .ibf file from PDM',
    key: 'omnipod',
    name: 'Insulet OmniPod',
    source: {type: 'block', driverId: 'InsuletOmniPod', extension: '.ibf'},
    enabled: {mac: true, win: true}
  },
  dexcom: {
    instructions: 'Plug in receiver with micro-USB',
    key: 'dexcom',
    name: 'Dexcom',
    source: {type: 'device', driverId: 'Dexcom'},
    enabled: {mac: true, win: true}
  },
  precisionxtra: {
    instructions: 'Plug in meter with cable',
    key: 'precisionxtra',
    name: 'Abbott Precision Xtra',
    source: {type: 'device', driverId: 'AbbottPrecisionXtra'},
    enabled: {mac: false, win: true}
  },
  tandem: {
    instructions: 'Plug in pump with micro-USB',
    key: 'tandem',
    name: 'Tandem',
    source: {type: 'device', driverId: 'Tandem'},
    enabled: {mac: true, win: true}
  },
  abbottfreestylelite: {
    instructions: 'Plug in meter with cable',
    key: 'abbottfreestylelite',
    name: 'Abbott FreeStyle Lite & Freedom Lite',
    source: {type: 'device', driverId: 'AbbottFreeStyleLite'},
    enabled: {mac: false, win: true}
  },
  abbottfreestylelibre: {
    instructions: '(Unsupported) Plug in meter with micro-USB cable',
    key: 'abbottfreestylelibre',
    name: 'Abbott FreeStyle Libre (Beta)',
    showDriverLink: {linux: false, mac: false, win: false},
    source: {type: 'device', driverId: 'AbbottFreeStyleLibre'},
    enabled: {linux: true, mac: true, win: true}
  },
  bayercontournext: {
    instructions: 'Plug meter into USB port',
    key: 'bayercontournext',
    name: 'Bayer Contour Next',
    source: {type: 'device', driverId: 'BayerContourNext'},
    enabled: {mac: true, win: true}
  },
  animas: {
    instructions: 'Suspend and align back of pump with IR dongle front',
    key: 'animas',
    name: 'Animas',
    source: {type: 'device', driverId: 'Animas'},
    enabled: {mac: true, win: true}
  },
  onetouchverioiq: {
    instructions: 'Plug in meter with mini-USB',
    name: 'OneTouch VerioIQ',
    key: 'onetouchverioiq',
    source: {type: 'device', driverId: 'OneTouchVerioIQ'},
    enabled: {mac: true, win: true}
  },
  onetouchultramini: {
    instructions: 'Plug in meter with cable',
    name: 'OneTouch UltraMini',
    key: 'onetouchultramini',
    showDriverLink: {mac: true, win: true},
    source: {type: 'device', driverId: 'OneTouchUltraMini'},
    enabled: {mac: true, win: true}
  },
  onetouchultra2: {
    instructions: 'Plug in meter with cable',
    name: 'OneTouch Ultra 2',
    key: 'onetouchultra2',
    showDriverLink: {mac: true, win: true},
    source: {type: 'device', driverId: 'OneTouchUltra2'},
    enabled: {mac: true, win: true}
  }
};

export default devices;
<commit_msg>remove beta and unsupported labels from Libre<commit_after>import mm723Image from '../../images/MM723_CNL_combo@2x.jpg';
const devices = {
  carelink: {
    instructions: ['Import from CareLink', '(We will not store your credentials)'],
    isFetching: false,
    key: 'carelink',
    name: 'Medtronic',
    // for the device selection list
    selectName: 'Medtronic (from CareLink)',
    source: {type: 'carelink'},
    enabled: {mac: true, win: true}
  },
  medtronic: {
    instructions: 'Connect your Bayer Contour Next Link to your computer',
    image: {
      'src': mm723Image,
      'height': 128,
      'width': 200,
      'alt': 'Bayer Contour Next Link'
    },
    key: 'medtronic',
    name: 'Medtronic - 523, 723 or 530G',
    selectName: 'Medtronic direct from Bayer Contour Next Link',
    source: {type: 'device', driverId: 'Medtronic'},
    enabled: {mac: true, win: true}
  },
  omnipod: {
    instructions: 'Plug in PDM with mini-USB and choose .ibf file from PDM',
    key: 'omnipod',
    name: 'Insulet OmniPod',
    source: {type: 'block', driverId: 'InsuletOmniPod', extension: '.ibf'},
    enabled: {mac: true, win: true}
  },
  dexcom: {
    instructions: 'Plug in receiver with micro-USB',
    key: 'dexcom',
    name: 'Dexcom',
    source: {type: 'device', driverId: 'Dexcom'},
    enabled: {mac: true, win: true}
  },
  precisionxtra: {
    instructions: 'Plug in meter with cable',
    key: 'precisionxtra',
    name: 'Abbott Precision Xtra',
    source: {type: 'device', driverId: 'AbbottPrecisionXtra'},
    enabled: {mac: false, win: true}
  },
  tandem: {
    instructions: 'Plug in pump with micro-USB',
    key: 'tandem',
    name: 'Tandem',
    source: {type: 'device', driverId: 'Tandem'},
    enabled: {mac: true, win: true}
  },
  abbottfreestylelite: {
    instructions: 'Plug in meter with cable',
    key: 'abbottfreestylelite',
    name: 'Abbott FreeStyle Lite & Freedom Lite',
    source: {type: 'device', driverId: 'AbbottFreeStyleLite'},
    enabled: {mac: false, win: true}
  },
  abbottfreestylelibre: {
    instructions: 'Plug in meter with micro-USB cable',
    key: 'abbottfreestylelibre',
    name: 'Abbott FreeStyle Libre',
    showDriverLink: {linux: false, mac: false, win: false},
    source: {type: 'device', driverId: 'AbbottFreeStyleLibre'},
    enabled: {linux: true, mac: true, win: true}
  },
  bayercontournext: {
    instructions: 'Plug meter into USB port',
    key: 'bayercontournext',
    name: 'Bayer Contour Next',
    source: {type: 'device', driverId: 'BayerContourNext'},
    enabled: {mac: true, win: true}
  },
  animas: {
    instructions: 'Suspend and align back of pump with IR dongle front',
    key: 'animas',
    name: 'Animas',
    source: {type: 'device', driverId: 'Animas'},
    enabled: {mac: true, win: true}
  },
  onetouchverioiq: {
    instructions: 'Plug in meter with mini-USB',
    name: 'OneTouch VerioIQ',
    key: 'onetouchverioiq',
    source: {type: 'device', driverId: 'OneTouchVerioIQ'},
    enabled: {mac: true, win: true}
  },
  onetouchultramini: {
    instructions: 'Plug in meter with cable',
    name: 'OneTouch UltraMini',
    key: 'onetouchultramini',
    showDriverLink: {mac: true, win: true},
    source: {type: 'device', driverId: 'OneTouchUltraMini'},
    enabled: {mac: true, win: true}
  },
  onetouchultra2: {
    instructions: 'Plug in meter with cable',
    name: 'OneTouch Ultra 2',
    key: 'onetouchultra2',
    showDriverLink: {mac: true, win: true},
    source: {type: 'device', driverId: 'OneTouchUltra2'},
    enabled: {mac: true, win: true}
  }
};

export default devices;
<|endoftext|>


<commit_before>import Ember from "ember";
import config from '../config/environment';
import AjaxPromise from '../utils/ajax-promise';
const { getOwner } = Ember;

export default Ember.Service.extend({
  session: Ember.inject.service(),
  logger: Ember.inject.service(),
  store: Ember.inject.service(),
  messagesUtil: Ember.inject.service("messages"),

  isAndroid() {
    if (!config.cordova.enabled || !window.device) {
      return;
    }
    return (
      ["android", "Android", "amazon-fireos"].indexOf(window.device.platform) >=
      0
    );
  },

  isIOS: function() {
    if (!config.cordova.enabled || !window.device) {
      return;
    }
    return window.device.platform === "iOS";
  },

  verifyIosNotificationSetting: function(onEnabled, onDisabled) {
    PushNotificationsStatus.isPushNotificationsEnabled(function(response) {
      response === "true" ? onEnabled() : onDisabled();
    }, function() {
      onEnabled();
    });
  },

  appLoad: function() {
    if (!config.cordova.enabled) {
      return;
    }
    this.initiatePushNotifications();
  },

  initiatePushNotifications: function() {

    var _this = this;

    function onDeviceReady() {

      var push = PushNotification.init({
        android: {},
        ios: {
          alert: true,
          sound: true,
          badge: true
        }
      });

      push.on('registration', function(data) {
        sendToken(data.registrationId, platformCode());
      });

      push.on('notification', function(data) {
        if (!data.additionalData.foreground) {
          if (window.device.platform === "iOS") {
            processTappedNotification(data.additionalData.payload);
          } else {
            processTappedNotification(data.additionalData);
          }

        }
      });
    }

    function sendToken(handle, platform) {
      return new AjaxPromise("/auth/register_device", "POST", _this.get("session.authToken"), { handle: handle, platform: platform });
    }

    function platformCode() {
      var platform;
      if (_this.isAndroid()) { platform = "fcm"; } else if (window.device.platform === "iOS") { platform = "aps"; } else if (window.device.platform === "windows") { platform = "wns"; }
      return platform;
    }

    function processTappedNotification(payload) {
      var notifications = getOwner(_this).lookup("controller:notifications");
      if (payload.category === "incoming_call") {
        notifications.acceptCall(payload);
      }

      notifications.setRoute(payload);

      if (payload.category === "message") {
        var hasMessage = _this.get("store").peekRecord("message", payload.message_id);
        if (hasMessage) {
          notifications.transitionToRoute.apply(notifications, payload.route);
        } else {
          var loadingView = getOwner(_this).lookup('component:loading').append();
          var messageUrl = payload.item_id ? `/messages?item_id=${payload.item_id}` : `/messages?offer_id=${payload.offer_id}`;
          new AjaxPromise(messageUrl, "GET", _this.get("session.authToken"), {})
            .then(function(data) {
              _this.get("store").pushPayload(data);
              notifications.transitionToRoute.apply(notifications, payload.route);
            })
            .finally(() => loadingView.destroy());
        }
      } else {
        notifications.transitionToRoute.apply(notifications, payload.route);
      }
    }

    document.addEventListener('deviceready', onDeviceReady, true);

  }

});
<commit_msg>Added support for Android notification icon<commit_after>import Ember from "ember";
import config from '../config/environment';
import AjaxPromise from '../utils/ajax-promise';
const { getOwner } = Ember;

export default Ember.Service.extend({
  session: Ember.inject.service(),
  logger: Ember.inject.service(),
  store: Ember.inject.service(),
  messagesUtil: Ember.inject.service("messages"),

  isAndroid() {
    if (!config.cordova.enabled || !window.device) {
      return;
    }
    return (
      ["android", "Android", "amazon-fireos"].indexOf(window.device.platform) >=
      0
    );
  },

  isIOS: function() {
    if (!config.cordova.enabled || !window.device) {
      return;
    }
    return window.device.platform === "iOS";
  },

  verifyIosNotificationSetting: function(onEnabled, onDisabled) {
    PushNotificationsStatus.isPushNotificationsEnabled(function(response) {
      response === "true" ? onEnabled() : onDisabled();
    }, function() {
      onEnabled();
    });
  },

  appLoad: function() {
    if (!config.cordova.enabled) {
      return;
    }
    this.initiatePushNotifications();
  },

  initiatePushNotifications: function() {

    var _this = this;

    function onDeviceReady() {

      var push = PushNotification.init({
        android: {
          icon: "notification",
          iconColor: "#002352"
        },
        ios: {
          alert: true,
          sound: true,
          badge: true
        }
      });

      push.on('registration', function(data) {
        sendToken(data.registrationId, platformCode());
      });

      push.on('notification', function(data) {
        if (!data.additionalData.foreground) {
          if (window.device.platform === "iOS") {
            processTappedNotification(data.additionalData.payload);
          } else {
            processTappedNotification(data.additionalData);
          }

        }
      });

      push.on("error", e => {
        console.log(e);
      });
    }

    function sendToken(handle, platform) {
      return new AjaxPromise("/auth/register_device", "POST", _this.get("session.authToken"), { handle: handle, platform: platform });
    }

    function platformCode() {
      var platform;
      if (_this.isAndroid()) {
        platform = "fcm";
      } else if (window.device.platform === "iOS") {
        platform = "aps";
      }
      return platform;
    }

    function processTappedNotification(payload) {
      var notifications = getOwner(_this).lookup("controller:notifications");
      if (payload.category === "incoming_call") {
        notifications.acceptCall(payload);
      }

      notifications.setRoute(payload);

      if (payload.category === "message") {
        var hasMessage = _this.get("store").peekRecord("message", payload.message_id);
        if (hasMessage) {
          notifications.transitionToRoute.apply(notifications, payload.route);
        } else {
          var loadingView = getOwner(_this).lookup('component:loading').append();
          var messageUrl = payload.item_id ? `/messages?item_id=${payload.item_id}` : `/messages?offer_id=${payload.offer_id}`;
          new AjaxPromise(messageUrl, "GET", _this.get("session.authToken"), {})
            .then(function(data) {
              _this.get("store").pushPayload(data);
              notifications.transitionToRoute.apply(notifications, payload.route);
            })
            .finally(() => loadingView.destroy());
        }
      } else {
        notifications.transitionToRoute.apply(notifications, payload.route);
      }
    }

    document.addEventListener('deviceready', onDeviceReady, true);

  }

});
<|endoftext|>


<commit_before>module.exports = function(server){

  server.get('/help', function(req, res){

    res.setLocals({
      title: 'Help',
      selected: {help: 'selected'},
      tab: {help: 'selected'},
    });

    res.addPartials({yield: 'help/overview'});

    if (req.blog)
      return res.render('help/wrapper');

    res.render('help/wrapper');
  });

  function capitalize (str) {
    return str[0].toUpperCase() + str.slice(1);
  }

  function deslug (slug) {
    return capitalize(slug.split('-').join(' '));
  }

  server.get('/help/:section', function(req, res){

    res.addPartials({
      yield: 'help/sections/' + req.params.section,
      sidebar: 'help/sidebar'
    });

    res.setLocals({
      subsection: true,
      title: deslug(req.params.section),
      selected: {help: 'selected'},
      tab: {help: 'selected'}
    });

    if (req.blog)
      return res.render('help/wrapper');

    res.render('help/wrapper');
  });

  server.use('/help', function(err, req, res, next){

    console.log(req.url, err.message);

    return res.redirect('/help');
  });
};
<commit_msg>Updated documentation<commit_after>module.exports = function(server){

  var help = require('../views/help/help.json');

  server.get('/help', function(req, res){
    console.log('redirecting',req.url,' to /help/' + help.sections[0].slug);
    return res.redirect('/help/' + help.sections[0].slug);
  });

  server.get('/help/:section', function(req, res){

    var sidebar = help.sidebar.slice();
    var title = 'Help';
    var section = help[req.params.section];

    sidebar = sidebar.map(function(section){

      if (section.slug === req.params.section) {
        section.selected = 'selected';
      } else {
        section.selected = ''
      }

      return section;
    });

    console.log('HERe!');

    res.addPartials({
      sidebar: 'help/sidebar'
    });

    res.setLocals({
      section: section,
      sidebar: sidebar,
      title: section.title,
      selected: {help: 'selected'},
      tab: {help: 'selected'}
    });

    console.log('rendering', req.url);
    return res.render('help/wrapper');
  });
};
<|endoftext|>


<commit_before>$(function() {

    var dropbox = $('#dropbox'),
        message = $('.message', dropbox);

    dropbox.filedrop({
        paramname: 'file',
        maxfiles: 10,
        maxfilesize: 5,
        url: '/upload',
        uploadFinished: function(i, file, response) {
            $.data(file).addClass('done');
            var status_url = response.getResponseHeader('Location');
            check_job_status(status_url);
        },

        error: function(err, file) {
            switch (err) {
                case 'BrowserNotSupported':
                    showMessage('Your browser does not support HTML5 file uploads!');
                    break;
                case 'TooManyFiles':
                    alert('Too many files! Please select ' + this.maxfiles + ' at most!');
                    break;
                case 'FileTooLarge':
                    alert(file.name + ' is too large! The size is limited to ' + this.maxfilesize + 'MB.');
                    break;
                default:
                    break;
            }
        },

    });

    function showMessage(msg) {
        message.html(msg);
    }

    function flash_alert(message, category, clean) {
        if (typeof(clean) === "undefined")
            clean = true;
        if (clean) {
            remove_alerts();
        }
        var htmlString = '
'
        htmlString += '<button type="button" class="close" data-dismiss="alert" aria-label="Close">'
        htmlString += '×</button>' + message + '
'
        $(htmlString).prependTo("#mainContent").hide().slideDown();
    }

    function remove_alerts() {
        $(".alert").slideUp("normal", function() {
            $(this).remove();
        });
    }

    function check_job_status(status_url) {
        $.getJSON(status_url, function(data) {
            console.log(data);
            switch (data.status) {
                case "unknown":
                    flash_alert("Unknown job id", "danger");
                    $("#submit").removeAttr("disabled");
                    break;
                case "finished":
                    flash_alert(data.result, "success");
                    $("#submit").removeAttr("disabled");
                    break;
                case "failed":
                    flash_alert("Job failed: " + data.message, "danger");
                    $("#submit").removeAttr("disabled");
                    break;
                default:
                    // queued/started/deferred
                    setTimeout(function() {
                        check_job_status(status_url);
                    }, 500);
            }
        });
    }

});
<commit_msg>queuing and result calc okay, trying to bug fix js to poll result<commit_after>$(function() {

    var dropbox = $('#dropbox'),
        message = $('.message', dropbox);

    dropbox.filedrop({
        paramname: 'file',
        maxfiles: 10,
        maxfilesize: 5,
        url: '/upload',
        uploadFinished: function(i, file, response) {
            var status_url = response.getResponseHeader('Location');
            check_job_status(status_url);
        },

        error: function(err, file) {
            switch (err) {
                case 'BrowserNotSupported':
                    showMessage('Your browser does not support HTML5 file uploads!');
                    break;
                case 'TooManyFiles':
                    alert('Too many files! Please select ' + this.maxfiles + ' at most!');
                    break;
                case 'FileTooLarge':
                    alert(file.name + ' is too large! The size is limited to ' + this.maxfilesize + 'MB.');
                    break;
                default:
                    break;
            }
        },

    });

    function showMessage(msg) {
        message.html(msg);
    }

    function flash_alert(message, category, clean) {
        if (typeof(clean) === "undefined")
            clean = true;
        if (clean) {
            remove_alerts();
        }
        var htmlString = '
'
        htmlString += '<button type="button" class="close" data-dismiss="alert" aria-label="Close">'
        htmlString += '×</button>' + message + '
'
        $(htmlString).prependTo("#mainContent").hide().slideDown();
    }

    function remove_alerts() {
        $(".alert").slideUp("normal", function() {
            $(this).remove();
        });
    }

    function check_job_status(status_url) {
        $.getJSON(status_url, function(data) {
            console.log(data);
            switch (data.status) {
                case "unknown":
                    flash_alert("Unknown job id", "danger");
                    $("#submit").removeAttr("disabled");
                    break;
                case "finished":
                    flash_alert(data.result, "success");
                    $("#submit").removeAttr("disabled");
                    break;
                case "failed":
                    flash_alert("Job failed: " + data.message, "danger");
                    $("#submit").removeAttr("disabled");
                    break;
                default:
                    // queued/started/deferred
                    setTimeout(function() {
                        check_job_status(status_url);
                    }, 500);
            }
        });
    }

});
<|endoftext|>


<commit_before>var nodeca = require('nodeca-lib'),
    Store = nodeca.Settings.Store,
    $$ = nodeca.Utilities;

var Promise = require('simple-promise');

module.exports = (function (app, callback) {
  var UserGroupStore = function UserGroupStore() {
    Store.call(this);

    var STORE_KEY = '__usergroup_store__',
        UserGroup = app.model('UserGroup');

    this.__.preloader = function (env, callback) {
      // environment was preloaded before
      if (env[STORE_KEY]) {
        callback();
        return;
      }

      // env.groups was neither specified directly nor found in user
      if (!Array.isArray(env.groups) || 0 == env.groups.length) {
        callback(Error("Can't find list of groups"));
        return;
      }

      UserGroup.find({_id: {$in: env.groups}}, function (err, groups) {
        env[STORE_KEY] = groups;
        callback(err);
      });
    };

    this.__.setter = function (data, env, callback) {
      var settings = {};

      // Getter works with multiple groups.
      // Setter NEVER work with moe than one for integrity reasons.
      if (1 != env.groups.length) {
        callback(Error("Can't set on multiple groups"));
        return;
      }

      $$.each(data, function (key, val) {
        settings['settings.' + key] = val;
      });

      UserGroup.update({_id: env.groups[0]}, settings, callback);
    };

    this.__.getter = function (keys, env, callback) {
      var result = {};

      keys.forEach(function (key) {
        var chains;

        if (1 == env[STORE_KEY].length) {
          result[key] = env[STORE_KEY].settings[key];
          return;
        }

        // TODO: rework to support non-boolean vals as well

        // separate strict and non-strict values
        chains = {OR: [], AND: []};
        env[STORE_KEY].forEach(function (g) {
          var op = g.settings[key].strict ? 'AND' : 'OR';
          chains[op].push(!!g.settings[key].value);
        });

        result[key] = {strict: false, value: false};

        if (0 < chains.AND.length) {
          result[key].strict = true;
        }

        if (0 == chains.OR.length) {
          result[key].value = !($$.includes(chains.AND, false));
        } else {
          result[key].value = (
            $$.includes(chains.OR, true)
            &&
            !($$.includes(chains.AND, false))
          );
        }
      });

      callback(null, result);
    };
  };

  Store.adopts(UserGroupStore);

  callback(null, new UserGroupStore());
});

////////////////////////////////////////////////////////////////////////////////
// vim:ts=2:sw=2
////////////////////////////////////////////////////////////////////////////////
<commit_msg>Improved conditions view<commit_after>var nodeca = require('nodeca-lib'),
    Store = nodeca.Settings.Store,
    $$ = nodeca.Utilities;

var Promise = require('simple-promise');

module.exports = (function (app, callback) {
  var UserGroupStore = function UserGroupStore() {
    Store.call(this);

    var STORE_KEY = '__usergroup_store__',
        UserGroup = app.model('UserGroup');

    this.__.preloader = function (env, callback) {
      // environment was preloaded before
      if (env[STORE_KEY]) {
        callback();
        return;
      }

      // env.groups was neither specified directly nor found in user
      if (!Array.isArray(env.groups) || 0 == env.groups.length) {
        callback(Error("Can't find list of groups"));
        return;
      }

      UserGroup.find({_id: {$in: env.groups}}, function (err, groups) {
        env[STORE_KEY] = groups;
        callback(err);
      });
    };

    this.__.setter = function (data, env, callback) {
      var settings = {};

      // Getter works with multiple groups.
      // Setter NEVER work with moe than one for integrity reasons.
      if (1 != env.groups.length) {
        callback(Error("Can't set on multiple groups"));
        return;
      }

      $$.each(data, function (key, val) {
        settings['settings.' + key] = val;
      });

      UserGroup.update({_id: env.groups[0]}, settings, callback);
    };

    this.__.getter = function (keys, env, callback) {
      var result = {};

      keys.forEach(function (key) {
        var chains;

        if (1 == env[STORE_KEY].length) {
          result[key] = env[STORE_KEY].settings[key];
          return;
        }

        // TODO: rework to support non-boolean vals as well

        // separate strict and non-strict values
        chains = {OR: [], AND: []};
        env[STORE_KEY].forEach(function (g) {
          var op = g.settings[key].strict ? 'AND' : 'OR';
          chains[op].push(!!g.settings[key].value);
        });

        result[key] = {strict: false, value: false};

        if (0 < chains.AND.length) {
          result[key].strict = true;
        }

        if (0 == chains.OR.length) {
          result[key].value = !($$.includes(chains.AND, false));
        } else {
          result[key].value = (
            ($$.includes(chains.OR, true))
            &&
            !($$.includes(chains.AND, false))
          );
        }
      });

      callback(null, result);
    };
  };

  Store.adopts(UserGroupStore);

  callback(null, new UserGroupStore());
});

////////////////////////////////////////////////////////////////////////////////
// vim:ts=2:sw=2
////////////////////////////////////////////////////////////////////////////////
<|endoftext|>


<commit_before>var nodeca = require('nodeca-lib'),
    Store = nodeca.Settings.Store,
    $$ = nodeca.Utilities;

var Promise = require('simple-promise');

module.exports = (function (app, callback) {
  var UserGroupStore = function UserGroupStore() {
    Store.call(this);

    var STORE_KEY = '__usergroup_store__',
        UserGroup = app.model('UserGroup');

    this.__.preloader = function (env, callback) {
      // environment was preloaded before
      if (env[STORE_KEY]) {
        callback();
        return;
      }

      // env.grous was neither specified directly nor found in user
      if (!Array.isArray(env.groups) || 0 == env.groups.length) {
        callback(Error("Can't find list of groups"));
        return;
      }

      UserGroup.find({_id: {$in: env.groups}}, function (err, groups) {
        env[STORE_KEY] = groups;
        callback(err);
      });
    };

    this.__.setter = function (data, env, callback) {
      var settings = {};

      // Getter works with multiple groups.
      // Setter NEVER work with moe than one for integrity reasons.
      if (1 != env.groups.length) {
        callback(Error("Can't set on multiple groups"));
        return;
      }

      $$.each(data, function (key, val) {
        settings['settings.' + key] = val;
      });

      UserGroup.update({_id: env.groups[0]}, settings, callback);
    };

    this.__.getter = function (keys, env, callback) {
      var result = {};

      keys.forEach(function (key) {
        var chains;

        if (1 == env[STORE_KEY].length) {
          result[key] = env[STORE_KEY].settings[key];
          return;
        }

        // TODO: rework to support non-boolean vals as well

        // separate strict and non-strict values
        chains = {OR: [], AND: []};
        env[STORE_KEY].forEach(function (g) {
          var op = g.settings[key].strict ? 'AND' : 'OR';
          chains[op].push(g.settings[key].value);
        });

        result[key] = {strict: (0 < chains.AND.length)};

        if (0 == chains.OR.length) {
          result[key].value = (0 == $$.reject(chains.AND, function (v) { !!v; }).length);
        } else {
          result[key].value = (
            (0 < $$.select(chains.OR, function (v) { !!v; }).length)
            &&
            (0 == $$.reject(chains.AND, function (v) { !!v; }).length)
          );
        }
      });

      callback(null, result);
    };
  };

  Store.adopts(UserGroupStore);

  callback(null, new UserGroupStore());
});

////////////////////////////////////////////////////////////////////////////////
// vim:ts=2:sw=2
////////////////////////////////////////////////////////////////////////////////
<commit_msg>Fixed docs<commit_after>var nodeca = require('nodeca-lib'),
    Store = nodeca.Settings.Store,
    $$ = nodeca.Utilities;

var Promise = require('simple-promise');

module.exports = (function (app, callback) {
  var UserGroupStore = function UserGroupStore() {
    Store.call(this);

    var STORE_KEY = '__usergroup_store__',
        UserGroup = app.model('UserGroup');

    this.__.preloader = function (env, callback) {
      // environment was preloaded before
      if (env[STORE_KEY]) {
        callback();
        return;
      }

      // env.grous was neither specified directly nor found in user
      if (!Array.isArray(env.groups) || 0 == env.groups.length) {
        callback(Error("Can't find list of groups"));
        return;
      }

      UserGroup.find({_id: {$in: env.groups}}, function (err, groups) {
        env[STORE_KEY] = groups;
        callback(err);
      });
    };

    this.__.setter = function (data, env, callback) {
      var settings = {};

      // Getter works with multiple groups.
      // Setter NEVER work with moe than one for integrity reasons.
      if (1 != env.groups.length) {
        callback(Error("Can't set on multiple groups"));
        return;
      }

      $$.each(data, function (key, val) {
        settings['settings.' + key] = val;
      });

      UserGroup.update({_id: env.groups[0]}, settings, callback);
    };

    this.__.getter = function (keys, env, callback) {
      var result = {};

      keys.forEach(function (key) {
        var chains;

        if (1 == env[STORE_KEY].length) {
          result[key] = env[STORE_KEY].settings[key];
          return;
        }

        // TODO: rework to support non-boolean vals as well

        // separate strict and non-strict values
        chains = {OR: [], AND: []};
        env[STORE_KEY].forEach(function (g) {
          var op = g.settings[key].strict ? 'AND' : 'OR';
          chains[op].push(g.settings[key].value);
        });

        result[key] = {strict: false, value: false};

        if (0 < chains.AND.length) {
          result[key].strict = true;
        }

        if (0 == chains.OR.length) {
          // we have ONLY restrictive permissions
          // make sure ALL values are TRUE: removing all TRUE values
          // from an array, so if all values are true - array will be empty
          result[key].value = (0 == $$.reject(chains.AND, function (v) {
            return !!v;
          }).length);
        } else {
          result[key].value = (
            // in opposite to restrictive - select all TRUE values and make sure
            // we have at least one TRUE
            (0 < $$.select(chains.OR, function (v) { return !!v; }).length)
            &&
            // see above
            (0 == $$.reject(chains.AND, function (v) { return !!v; }).length)
          );
        }
      });

      callback(null, result);
    };
  };

  Store.adopts(UserGroupStore);

  callback(null, new UserGroupStore());
});

////////////////////////////////////////////////////////////////////////////////
// vim:ts=2:sw=2
////////////////////////////////////////////////////////////////////////////////
<|endoftext|>


<commit_before>describe("build", function() {
  var sync = require("../index");
  var fs = require("fs-extra");

  // Set up a test blog before each test
  global.test.blog();

  // Expose methods for creating fake files, paths, etc.
  beforeEach(function() {
    this.fake = global.test.fake;
  });

  beforeEach(function() {
    this.checkEntry = global.test.CheckEntry(this.blog.id);
  });

  it("hides date from title if its in the file name", function(testDone) {
    var path = "/2018/06-04 Hello.jpg";
    var content = this.fake.file();
    var checkEntry = this.checkEntry;

    sync(this.blog.id, function(err, folder, done) {
      if (err) testDone.fail(err);

      fs.outputFileSync(folder.path + path, content, "utf-8");
      folder.update(path, function(err) {
        if (err) testDone.fail(err);

        checkEntry({ path: path, title: "Hello" }, function(err) {
          if (err) testDone.fail(err);

          done(null, testDone);
        });
      });
    });
  });

  it("preserves case in name option for title", function(testDone) {
    var path = "/[tag] hello.jpg";
    var content = this.fake.file();
    var checkEntry = this.checkEntry;

    sync(this.blog.id, function(err, folder, done) {
      if (err) testDone.fail(err);

      fs.outputFileSync(folder.path + path, content, "utf-8");
      folder.update(path, { name: "[Tag] Hello.jpg" }, function(err) {
        if (err) testDone.fail(err);

        checkEntry({ path: path, title: "Hello" }, function(err) {
          if (err) testDone.fail(err);

          done(null, testDone);
        });
      });
    });
  });

  it("hides tags from title if its in the file name", function(testDone) {
    var path = "/[Tag] Hello.jpg";
    var content = this.fake.file();
    var checkEntry = this.checkEntry;

    sync(this.blog.id, function(err, folder, done) {
      if (err) testDone.fail(err);

      fs.outputFileSync(folder.path + path, content, "utf-8");
      folder.update(path, function(err) {
        if (err) testDone.fail(err);

        checkEntry({ path: path, title: "Hello" }, function(err) {
          if (err) testDone.fail(err);

          done(null, testDone);
        });
      });
    });
  });
});
<commit_msg>Updated test name<commit_after>describe("build", function() {
  var sync = require("../index");
  var fs = require("fs-extra");

  // Set up a test blog before each test
  global.test.blog();

  // Expose methods for creating fake files, paths, etc.
  beforeEach(function() {
    this.fake = global.test.fake;
  });

  beforeEach(function() {
    this.checkEntry = global.test.CheckEntry(this.blog.id);
  });

  it("hides date from title if its in the file name", function(testDone) {
    var path = "/2018/06-04 Hello.jpg";
    var content = this.fake.file();
    var checkEntry = this.checkEntry;

    sync(this.blog.id, function(err, folder, done) {
      if (err) testDone.fail(err);

      fs.outputFileSync(folder.path + path, content, "utf-8");
      folder.update(path, function(err) {
        if (err) testDone.fail(err);

        checkEntry({ path: path, title: "Hello" }, function(err) {
          if (err) testDone.fail(err);

          done(null, testDone);
        });
      });
    });
  });

  it("preserves case in title generated from file name passed as option", function(testDone) {
    var path = "/[tag] hello.jpg";
    var content = this.fake.file();
    var checkEntry = this.checkEntry;

    sync(this.blog.id, function(err, folder, done) {
      if (err) testDone.fail(err);

      fs.outputFileSync(folder.path + path, content, "utf-8");
      folder.update(path, { name: "[Tag] Hello.jpg" }, function(err) {
        if (err) testDone.fail(err);

        checkEntry({ path: path, title: "Hello" }, function(err) {
          if (err) testDone.fail(err);

          done(null, testDone);
        });
      });
    });
  });

  it("hides tags from title if its in the file name", function(testDone) {
    var path = "/[Tag] Hello.jpg";
    var content = this.fake.file();
    var checkEntry = this.checkEntry;

    sync(this.blog.id, function(err, folder, done) {
      if (err) testDone.fail(err);

      fs.outputFileSync(folder.path + path, content, "utf-8");
      folder.update(path, function(err) {
        if (err) testDone.fail(err);

        checkEntry({ path: path, title: "Hello" }, function(err) {
          if (err) testDone.fail(err);

          done(null, testDone);
        });
      });
    });
  });
});
<|endoftext|>


<commit_before>// BEGIN-SNIPPET fade-definition
import { isAnimating, finish, timeSpent, animate, stop } from "liquid-fire";
export default function fade(opts={}) {
  var firstStep;
  var outOpts = opts;

  if (isAnimating(this.oldElement, 'fade-out')) {
    // if the old view is already fading out, let it finish.
    firstStep = finish(this.oldElement, 'fade-out');
  } else {
    if (isAnimating(this.oldElement, 'fade-in')) {
      // if the old view is partially faded in, scale its fade-out
      // duration appropriately.
      outOpts = { duration: timeSpent(this.oldElement, 'fade-in') };
    }
    stop(this.oldElement);
    firstStep = animate(this.oldElement, {opacity: 0}, outOpts, 'fade-out');
  }

  return firstStep.then(() => {
    return animate(this.newElement, {opacity: [(opts.maxOpacity || 1), 0]}, opts, 'fade-in');
  });
}
// END-SNIPPET
<commit_msg>robust mult-interruption support for fade transition<commit_after>// BEGIN-SNIPPET fade-definition
import { isAnimating, finish, timeSpent, animate, stop } from "liquid-fire";
export default function fade(opts={}) {
  var firstStep;
  var outOpts = opts;
  var fadingElement = findFadingElement(this);

  if (fadingElement) {
    // We still have some older version that is in the process of
    // fading out, so out first step is waiting for it to finish.
    firstStep = finish(fadingElement, 'fade-out');
  } else {
    if (isAnimating(this.oldElement, 'fade-in')) {
      // if the previous view is partially faded in, scale its
      // fade-out duration appropriately.
      outOpts = { duration: timeSpent(this.oldElement, 'fade-in') };
    }
    stop(this.oldElement);
    firstStep = animate(this.oldElement, {opacity: 0}, outOpts, 'fade-out');
  }

  return firstStep.then(() => {
    return animate(this.newElement, {opacity: [(opts.maxOpacity || 1), 0]}, opts, 'fade-in');
  });
}
// END-SNIPPET

function findFadingElement(context) {
  for (var i = 0; i < context.older.length; i++) {
    var entry = context.older[i];
    if (isAnimating(entry.element, 'fade-out')) {
      return entry.element;
    }
  }
  if (isAnimating(context.oldElement, 'fade-out')) {
    return context.oldElement;
  }
}
<|endoftext|>


<commit_before>/*
 * Facebox (for jQuery)
 * version: 1.2 (05/05/2008)
 * @requires jQuery v1.2 or later
 *
 * Examples at http://famspam.com/facebox/
 *
 * Licensed under the MIT:
 *   http://www.opensource.org/licenses/mit-license.php
 *
 * Copyright 2007, 2008 Chris Wanstrath [ chris@ozmm.org ]
 *
 * Usage:
 *
 *  jQuery(document).ready(function() {
 *    jQuery('a[rel*=facebox]').facebox()
 *  })
 *
 *  Terms
 *    Loads the #terms div in the box
 *
 *  Terms
 *    Loads the terms.html page in the box
 *
 *  Terms
 *    Loads the terms.png image in the box
 *
 *
 *  You can also use it programmatically:
 *
 *    jQuery.facebox('some html')
 *    jQuery.facebox('some html', 'my-groovy-style')
 *
 *  The above will open a facebox with "some html" as the content.
 *
 *    jQuery.facebox(function($) {
 *      $.get('blah.html', function(data) { $.facebox(data) })
 *    })
 *
 *  The above will show a loading screen before the passed function is called,
 *  allowing for a better ajaxy experience.
 *
 *  The facebox function can also display an ajax page, an image, or the contents of a div:
 *
 *    jQuery.facebox({ ajax: 'remote.html' })
 *    jQuery.facebox({ ajax: 'remote.html' }, 'my-groovy-style')
 *    jQuery.facebox({ image: 'stairs.jpg' })
 *    jQuery.facebox({ image: 'stairs.jpg' }, 'my-groovy-style')
 *    jQuery.facebox({ div: '#box' })
 *    jQuery.facebox({ div: '#box' }, 'my-groovy-style')
 *
 *  Want to close the facebox?  Trigger the 'close.facebox' document event:
 *
 *    jQuery(document).trigger('close.facebox')
 *
 *  Facebox also has a bunch of other hooks:
 *
 *    loading.facebox
 *    beforeReveal.facebox
 *    reveal.facebox (aliased as 'afterReveal.facebox')
 *    init.facebox
 *
 *  Simply bind a function to any of these hooks:
 *
 *   $(document).bind('reveal.facebox', function() { ...stuff to do after the facebox and contents are revealed... })
 *
 */
(function($) {
  $.facebox = function(data, klass) {
    $.facebox.loading()

    if (data.ajax) fillFaceboxFromAjax(data.ajax, klass)
    else if (data.image) fillFaceboxFromImage(data.image, klass)
    else if (data.div) fillFaceboxFromHref(data.div, klass)
    else if ($.isFunction(data)) data.call($)
    else $.facebox.reveal(data, klass)
  }

  /*
   * Public, $.facebox methods
   */

  $.extend($.facebox, {
    settings: {
      opacity      : 0,
      overlay      : true,
      loadingImage : '/facebox/loading.gif',
      closeImage   : '/facebox/closelabel.gif',
      imageTypes   : [ 'png', 'jpg', 'jpeg', 'gif' ],
      faceboxHtml  : '\

 \

 \

 \

 \

 \
               \

 \

 \
               \
               \

 \

 \

 \
                   \
                     \
                   \

 \
              	 \
               \

 \

 \
               \

 \

 \

 \

 \

'
    },

    loading: function() {
      init()
      if ($('#facebox .loading').length == 1) return true
      showOverlay()

      $('#facebox .content').empty()
      $('#facebox .body').children().hide().end().
        append('

')

      $('#facebox').css({
        top:	getPageScroll()[1] + (getPageHeight() / 10),
        left:	$(window).width() / 2 - 205
      }).show()

      $(document).bind('keydown.facebox', function(e) {
        if (e.keyCode == 27) $.facebox.close()
        return true
      })
      $(document).trigger('loading.facebox')
    },

    reveal: function(data, klass) {
      $(document).trigger('beforeReveal.facebox')
      if (klass) $('#facebox .content').addClass(klass)
      $('#facebox .content').append(data)
      $('#facebox .loading').remove()
      $('#facebox .body').children().fadeIn('normal')
      $('#facebox').css('left', $(window).width() / 2 - ($('#facebox table').width() / 2))
      $(document).trigger('reveal.facebox').trigger('afterReveal.facebox')
    },

    close: function() {
      $(document).trigger('close.facebox')
      return false
    }
  })

  /*
   * Public, $.fn methods
   */

  $.fn.facebox = function(settings) {
    if ($(this).length == 0) return

    init(settings)

    function clickHandler() {
      $.facebox.loading(true)

      // support for rel="facebox.inline_popup" syntax, to add a class
      // also supports deprecated "facebox[.inline_popup]" syntax
      var klass = this.rel.match(/facebox\[?\.(\w+)\]?/)
      if (klass) klass = klass[1]

      fillFaceboxFromHref(this.href, klass)
      return false
    }

    return this.bind('click.facebox', clickHandler)
  }

  /*
   * Private methods
   */

  // called one time to setup facebox on this page
  function init(settings) {
    if ($.facebox.settings.inited) return true
    else $.facebox.settings.inited = true

    $(document).trigger('init.facebox')
    makeCompatible()

    var imageTypes = $.facebox.settings.imageTypes.join('|')
    $.facebox.settings.imageTypesRegexp = new RegExp('\.(' + imageTypes + ')$', 'i')

    if (settings) $.extend($.facebox.settings, settings)
    $('body').append($.facebox.settings.faceboxHtml)

    var preload = [ new Image(), new Image() ]
    preload[0].src = $.facebox.settings.closeImage
    preload[1].src = $.facebox.settings.loadingImage

    $('#facebox').find('.b:first, .bl').each(function() {
      preload.push(new Image())
      preload.slice(-1).src = $(this).css('background-image').replace(/url\((.+)\)/, '$1')
    })

    $('#facebox .close').click($.facebox.close)
    $('#facebox .close_image').attr('src', $.facebox.settings.closeImage)
  }

  // getPageScroll() by quirksmode.com
  function getPageScroll() {
    var xScroll, yScroll;
    if (self.pageYOffset) {
      yScroll = self.pageYOffset;
      xScroll = self.pageXOffset;
    } else if (document.documentElement && document.documentElement.scrollTop) {	 // Explorer 6 Strict
      yScroll = document.documentElement.scrollTop;
      xScroll = document.documentElement.scrollLeft;
    } else if (document.body) {// all other Explorers
      yScroll = document.body.scrollTop;
      xScroll = document.body.scrollLeft;
    }
    return new Array(xScroll,yScroll)
  }

  // Adapted from getPageSize() by quirksmode.com
  function getPageHeight() {
    var windowHeight
    if (self.innerHeight) {	// all except Explorer
      windowHeight = self.innerHeight;
    } else if (document.documentElement && document.documentElement.clientHeight) { // Explorer 6 Strict Mode
      windowHeight = document.documentElement.clientHeight;
    } else if (document.body) { // other Explorers
      windowHeight = document.body.clientHeight;
    }
    return windowHeight
  }

  // Backwards compatibility
  function makeCompatible() {
    var $s = $.facebox.settings

    $s.loadingImage = $s.loading_image || $s.loadingImage
    $s.closeImage = $s.close_image || $s.closeImage
    $s.imageTypes = $s.image_types || $s.imageTypes
    $s.faceboxHtml = $s.facebox_html || $s.faceboxHtml
  }

  // Figures out what you want to display and displays it
  // formats are:
  //     div: #id
  //   image: blah.extension
  //    ajax: anything else
  function fillFaceboxFromHref(href, klass) {
    // div
    if (href.match(/#/)) {
      var url    = window.location.href.split('#')[0]
      var target = href.replace(url,'')
      if (target == '#') return
      $.facebox.reveal($(target).html(), klass)

    // image
    } else if (href.match($.facebox.settings.imageTypesRegexp)) {
      fillFaceboxFromImage(href, klass)
    // ajax
    } else {
      fillFaceboxFromAjax(href, klass)
    }
  }

  function fillFaceboxFromImage(href, klass) {
    var image = new Image()
    image.onload = function() {
      $.facebox.reveal('

', klass)
    }
    image.src = href
  }

  function fillFaceboxFromAjax(href, klass) {
    $.get(href, function(data) { $.facebox.reveal(data, klass) })
  }

  function skipOverlay() {
    return $.facebox.settings.overlay == false || $.facebox.settings.opacity === null
  }

  function showOverlay() {
    if (skipOverlay()) return

    if ($('#facebox_overlay').length == 0)
      $("body").append('

')

    $('#facebox_overlay').hide().addClass("facebox_overlayBG")
      .css('opacity', $.facebox.settings.opacity)
      .click(function() { $(document).trigger('close.facebox') })
      .fadeIn(200)
    return false
  }

  function hideOverlay() {
    if (skipOverlay()) return

    $('#facebox_overlay').fadeOut(200, function(){
      $("#facebox_overlay").removeClass("facebox_overlayBG")
      $("#facebox_overlay").addClass("facebox_hide")
      $("#facebox_overlay").remove()
    })

    return false
  }

  /*
   * Bindings
   */

  $(document).bind('close.facebox', function() {
    $(document).unbind('keydown.facebox')
    $('#facebox').fadeOut(function() {
      $('#facebox .content').removeClass().addClass('content')
      hideOverlay()
      $('#facebox .loading').remove()
      $(document).trigger('afterClose.facebox')
    })
  })

})(jQuery);
<commit_msg>new callback in the documentation<commit_after>/*
 * Facebox (for jQuery)
 * version: 1.2 (05/05/2008)
 * @requires jQuery v1.2 or later
 *
 * Examples at http://famspam.com/facebox/
 *
 * Licensed under the MIT:
 *   http://www.opensource.org/licenses/mit-license.php
 *
 * Copyright 2007, 2008 Chris Wanstrath [ chris@ozmm.org ]
 *
 * Usage:
 *
 *  jQuery(document).ready(function() {
 *    jQuery('a[rel*=facebox]').facebox()
 *  })
 *
 *  Terms
 *    Loads the #terms div in the box
 *
 *  Terms
 *    Loads the terms.html page in the box
 *
 *  Terms
 *    Loads the terms.png image in the box
 *
 *
 *  You can also use it programmatically:
 *
 *    jQuery.facebox('some html')
 *    jQuery.facebox('some html', 'my-groovy-style')
 *
 *  The above will open a facebox with "some html" as the content.
 *
 *    jQuery.facebox(function($) {
 *      $.get('blah.html', function(data) { $.facebox(data) })
 *    })
 *
 *  The above will show a loading screen before the passed function is called,
 *  allowing for a better ajaxy experience.
 *
 *  The facebox function can also display an ajax page, an image, or the contents of a div:
 *
 *    jQuery.facebox({ ajax: 'remote.html' })
 *    jQuery.facebox({ ajax: 'remote.html' }, 'my-groovy-style')
 *    jQuery.facebox({ image: 'stairs.jpg' })
 *    jQuery.facebox({ image: 'stairs.jpg' }, 'my-groovy-style')
 *    jQuery.facebox({ div: '#box' })
 *    jQuery.facebox({ div: '#box' }, 'my-groovy-style')
 *
 *  Want to close the facebox?  Trigger the 'close.facebox' document event:
 *
 *    jQuery(document).trigger('close.facebox')
 *
 *  Facebox also has a bunch of other hooks:
 *
 *    loading.facebox
 *    beforeReveal.facebox
 *    reveal.facebox (aliased as 'afterReveal.facebox')
 *    init.facebox
 *    afterClose.facebox
 *
 *  Simply bind a function to any of these hooks:
 *
 *   $(document).bind('reveal.facebox', function() { ...stuff to do after the facebox and contents are revealed... })
 *
 */
(function($) {
  $.facebox = function(data, klass) {
    $.facebox.loading()

    if (data.ajax) fillFaceboxFromAjax(data.ajax, klass)
    else if (data.image) fillFaceboxFromImage(data.image, klass)
    else if (data.div) fillFaceboxFromHref(data.div, klass)
    else if ($.isFunction(data)) data.call($)
    else $.facebox.reveal(data, klass)
  }

  /*
   * Public, $.facebox methods
   */

  $.extend($.facebox, {
    settings: {
      opacity      : 0,
      overlay      : true,
      loadingImage : '/facebox/loading.gif',
      closeImage   : '/facebox/closelabel.gif',
      imageTypes   : [ 'png', 'jpg', 'jpeg', 'gif' ],
      faceboxHtml  : '\

 \

 \

 \

 \

 \
               \

 \

 \
               \
               \

 \

 \

 \
                   \
                     \
                   \

 \
              	 \
               \

 \

 \
               \

 \

 \

 \

 \

'
    },

    loading: function() {
      init()
      if ($('#facebox .loading').length == 1) return true
      showOverlay()

      $('#facebox .content').empty()
      $('#facebox .body').children().hide().end().
        append('

')

      $('#facebox').css({
        top:	getPageScroll()[1] + (getPageHeight() / 10),
        left:	$(window).width() / 2 - 205
      }).show()

      $(document).bind('keydown.facebox', function(e) {
        if (e.keyCode == 27) $.facebox.close()
        return true
      })
      $(document).trigger('loading.facebox')
    },

    reveal: function(data, klass) {
      $(document).trigger('beforeReveal.facebox')
      if (klass) $('#facebox .content').addClass(klass)
      $('#facebox .content').append(data)
      $('#facebox .loading').remove()
      $('#facebox .body').children().fadeIn('normal')
      $('#facebox').css('left', $(window).width() / 2 - ($('#facebox table').width() / 2))
      $(document).trigger('reveal.facebox').trigger('afterReveal.facebox')
    },

    close: function() {
      $(document).trigger('close.facebox')
      return false
    }
  })

  /*
   * Public, $.fn methods
   */

  $.fn.facebox = function(settings) {
    if ($(this).length == 0) return

    init(settings)

    function clickHandler() {
      $.facebox.loading(true)

      // support for rel="facebox.inline_popup" syntax, to add a class
      // also supports deprecated "facebox[.inline_popup]" syntax
      var klass = this.rel.match(/facebox\[?\.(\w+)\]?/)
      if (klass) klass = klass[1]

      fillFaceboxFromHref(this.href, klass)
      return false
    }

    return this.bind('click.facebox', clickHandler)
  }

  /*
   * Private methods
   */

  // called one time to setup facebox on this page
  function init(settings) {
    if ($.facebox.settings.inited) return true
    else $.facebox.settings.inited = true

    $(document).trigger('init.facebox')
    makeCompatible()

    var imageTypes = $.facebox.settings.imageTypes.join('|')
    $.facebox.settings.imageTypesRegexp = new RegExp('\.(' + imageTypes + ')$', 'i')

    if (settings) $.extend($.facebox.settings, settings)
    $('body').append($.facebox.settings.faceboxHtml)

    var preload = [ new Image(), new Image() ]
    preload[0].src = $.facebox.settings.closeImage
    preload[1].src = $.facebox.settings.loadingImage

    $('#facebox').find('.b:first, .bl').each(function() {
      preload.push(new Image())
      preload.slice(-1).src = $(this).css('background-image').replace(/url\((.+)\)/, '$1')
    })

    $('#facebox .close').click($.facebox.close)
    $('#facebox .close_image').attr('src', $.facebox.settings.closeImage)
  }

  // getPageScroll() by quirksmode.com
  function getPageScroll() {
    var xScroll, yScroll;
    if (self.pageYOffset) {
      yScroll = self.pageYOffset;
      xScroll = self.pageXOffset;
    } else if (document.documentElement && document.documentElement.scrollTop) {	 // Explorer 6 Strict
      yScroll = document.documentElement.scrollTop;
      xScroll = document.documentElement.scrollLeft;
    } else if (document.body) {// all other Explorers
      yScroll = document.body.scrollTop;
      xScroll = document.body.scrollLeft;
    }
    return new Array(xScroll,yScroll)
  }

  // Adapted from getPageSize() by quirksmode.com
  function getPageHeight() {
    var windowHeight
    if (self.innerHeight) {	// all except Explorer
      windowHeight = self.innerHeight;
    } else if (document.documentElement && document.documentElement.clientHeight) { // Explorer 6 Strict Mode
      windowHeight = document.documentElement.clientHeight;
    } else if (document.body) { // other Explorers
      windowHeight = document.body.clientHeight;
    }
    return windowHeight
  }

  // Backwards compatibility
  function makeCompatible() {
    var $s = $.facebox.settings

    $s.loadingImage = $s.loading_image || $s.loadingImage
    $s.closeImage = $s.close_image || $s.closeImage
    $s.imageTypes = $s.image_types || $s.imageTypes
    $s.faceboxHtml = $s.facebox_html || $s.faceboxHtml
  }

  // Figures out what you want to display and displays it
  // formats are:
  //     div: #id
  //   image: blah.extension
  //    ajax: anything else
  function fillFaceboxFromHref(href, klass) {
    // div
    if (href.match(/#/)) {
      var url    = window.location.href.split('#')[0]
      var target = href.replace(url,'')
      if (target == '#') return
      $.facebox.reveal($(target).html(), klass)

    // image
    } else if (href.match($.facebox.settings.imageTypesRegexp)) {
      fillFaceboxFromImage(href, klass)
    // ajax
    } else {
      fillFaceboxFromAjax(href, klass)
    }
  }

  function fillFaceboxFromImage(href, klass) {
    var image = new Image()
    image.onload = function() {
      $.facebox.reveal('

', klass)
    }
    image.src = href
  }

  function fillFaceboxFromAjax(href, klass) {
    $.get(href, function(data) { $.facebox.reveal(data, klass) })
  }

  function skipOverlay() {
    return $.facebox.settings.overlay == false || $.facebox.settings.opacity === null
  }

  function showOverlay() {
    if (skipOverlay()) return

    if ($('#facebox_overlay').length == 0)
      $("body").append('

')

    $('#facebox_overlay').hide().addClass("facebox_overlayBG")
      .css('opacity', $.facebox.settings.opacity)
      .click(function() { $(document).trigger('close.facebox') })
      .fadeIn(200)
    return false
  }

  function hideOverlay() {
    if (skipOverlay()) return

    $('#facebox_overlay').fadeOut(200, function(){
      $("#facebox_overlay").removeClass("facebox_overlayBG")
      $("#facebox_overlay").addClass("facebox_hide")
      $("#facebox_overlay").remove()
    })

    return false
  }

  /*
   * Bindings
   */

  $(document).bind('close.facebox', function() {
    $(document).unbind('keydown.facebox')
    $('#facebox').fadeOut(function() {
      $('#facebox .content').removeClass().addClass('content')
      hideOverlay()
      $('#facebox .loading').remove()
      $(document).trigger('afterClose.facebox')
    })
  })

})(jQuery);
<|endoftext|>


<commit_before>var credentials = require('../.credentials.json');
var azureTables = require('../lib/azure-table-client.js');

var tableCredentials = credentials['demo01'];

var azureTableClient = new azureTables.AzureTableClient();
azureTableClient.config(tableCredentials.key, tableCredentials.secret, tableCredentials.suffix);

var Person = azureTableClient.define({
    FirstName: String,
    LastName: String,
    UniqueIdentifier: String,
    PartitionKey: function (model) {
        return 'PERSON';
    },
    RowKey: function (model) {
        return model.UniqueIdentifier;
    },
    TableName: function () {
        return "Persons";
    }
});

// build 2500 models
var persons = [];

for(var i = 0; i < 2500; i++) {
    persons.push(Person.build({FirstName: "DefaultFirstName", LastName: "DefaultLastName", UniqueIdentifier: "PP" + i}));
}

// create the 100 models
console.log("Creating 2500 items...");
Person.insert(persons).then(function() {

    // query paged
    console.log("Loading Paged...");
    return Person.queryPaged('PERSON').progress(function(pageResult) {
            console.log("Next Page with size " + pageResult.length);
    }).then(function() {

        // query recursive
        console.log("Loading recursive...");
        return Person.query('PERSON').then(function(result) {
            console.log("Loaded recursive " + result.length);

            // delete
            console.log("Delete persons...");
            return Person.delete(persons).then(function () {
                console.log("DONE");
                process.exit(0);
            })
        });
    });

}).catch(function(e) {
    console.log("ERROR");
    console.log(e);
    process.exit(1);
});<commit_msg>Added code to play with memory consumption<commit_after>var credentials = require('../.credentials.json');
var azureTables = require('../lib/azure-table-client.js');

var tableCredentials = credentials['demo01'];

var azureTableClient = new azureTables.AzureTableClient();
azureTableClient.config(tableCredentials.key, tableCredentials.secret, tableCredentials.suffix);

var util = require('util');

var Person = azureTableClient.define({
    FirstName: String,
    LastName: String,
    UniqueIdentifier: String,
    PartitionKey: function (model) {
        return 'PERSON';
    },
    RowKey: function (model) {
        return model.UniqueIdentifier;
    },
    TableName: function () {
        return "Persons";
    }
});

function dumpMemory() {
    var workingSet = process.memoryUsage();
    console.log(workingSet.heapUsed + "," + workingSet.heapTotal);
}

function triggerGC() {
    if (global && global.gc) {
        global.gc();
    }
}

dumpMemory();

// build 2500 models
var itemCount = 25000;
var persons = [];

for(var i = 0; i < itemCount; i++) {
    persons.push(Person.build({FirstName: "DefaultFirstName", LastName: "DefaultLastName", UniqueIdentifier: "PP" + i}));
}

// create the 100 models
dumpMemory();
console.log("Creating " + itemCount + " items...");
Person.insert(persons).then(function() {

    // ensure memory can be freed
    persons = undefined;
    dumpMemory();

    triggerGC();

    // query paged
    console.log("Loading Paged...");
    return Person.queryPaged('PERSON', undefined, undefined, undefined).progress(function(pageResult) {
            triggerGC();
            dumpMemory();
            console.log("Next Page with size " + pageResult.length);
    }).then(function() {

        dumpMemory();

        // query recursive
        console.log("Loading recursive...");
        return Person.query('PERSON').then(function(result) {
            console.log("Loaded recursive " + result.length);
            dumpMemory();

            // delete
            console.log("Delete persons...");
            return Person.delete(persons).then(function () {
                dumpMemory();
                console.log("DONE");
                process.exit(0);
            })
        });
    });

}).catch(function(e) {
    console.log("ERROR");
    console.log(e);
    process.exit(1);
});<|endoftext|>