<commit_before>'use strict';
angular.module("textAngularTest").controller('ButtonController', ['$http',  function($http) {
  /**
   * @return {string} A LaTeX command.
   */
  this.parseTag = function (match, tag, args) {
      switch (tag) {
        case 'h1':
          return ' \\section*{';
        case '/h1':
          return '} ';
        case 'h2':
          return ' \\subsection*{';
        case '/h2':
          return '} ';
        case 'p':
          return ' \\par\\addvspace{\\medskipamount}\\noindent ';
        case '/p':
          return ' ';
        case 'ul':
          return ' \\begin{itemize} ';
        case '/ul':
          return ' \\end{itemize} ';
        case 'ol':
          return ' \\begin{enumerate} ';
        case '/ol':
          return ' \\end{enumerate} ';
        case 'li':
          return ' \\item ';
        case '/li':
          return ' ';
        case 'b':
          return '\\textbf{';
        case '/b':
          return '}';
        case 'i':
          return '\\textit{';
        case '/i':
          return '}';
        case 'u':
          return '\\underline{';
        case '/u':
          return '}';
        case 'strike':
          return '\\sout{';
        case '/strike':
          return '}';
        case 'br/':
          return ' ';
        default:
          return ' <' + tag + '> ';
      }
  };

  /**
  * Take an HTML string and replace its tags with LaTeX commands.
  *
  * @param {string} htmlString The HTML string to parse.
  * @return {string} The corresponding LaTeX string.
  */
  this.tokenize = function (htmlString) {
    /**
     * General regular expressions in java script are a quite different, see:
     *   https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Regular_Expressions?redirectlocale=en-US&redirectslug=JavaScript%2FGuide%2FRegular_Expressions
     * string.replace is explained here:
     *   https://developer.mozilla.org/en-US/docs/JavaScript/Reference/Global_Objects/String/replace
     *
     * '([/a-zA-Z0-9]+)' is the second argument of tagsParse (the tag). A tag
     * may include '/' or word letters.
     * '([^<]*)' might be the third argument of tagsParse. This is for
     * example 'style="color: blue;"'.
     */
    var regularExpression = /<([/a-zA-Z0-9]+)(?:\s+([^<]*))?>/g;
    return htmlString.replace(regularExpression, this.parseTag);
  };

  /**
   * Add header and footer for latex document and tokenize given HTML-code.
   * @param  {string} html HTML-string generated by textAngular
   * @return {latex} Corresponding LaTeX-Code
   */
  this.html2latex = function(html){
    var texHead = '\\documentclass{juwit}\n \\begin{document}\n';
    var texBody = this.tokenize(html);
    var texTail = '\n \\end{document}\n';
    return texHead + texBody + texTail;
  };

  /**
  * Make a request to the server in order to get a pdf file.
  *
  * @param {string} htmlString String to generate pdf from HTML.
  */
  this.download = function(htmlString) {
    var latexString = this.html2latex(htmlString);
    $http.post("/compile", {"latexCode": latexString})
    .success(function(data, status, headers, config) {
      if (typeof data.redirect === 'string') {
        window.open(data.redirect, '_new', 'toolbar=yes, location=yes, status=yes, menubar=yes, scrollbars=yes');
      }
    }).error(function(data, status, headers, config) {
      //TODO: Error Handling
    })
  };
}]);
<commit_msg>parseTag new version<commit_after>'use strict';
angular.module("textAngularTest").controller('ButtonController', ['$http',  function($http) {
  /**
   * @return {string} A LaTeX command.
   */
  this.parseTag = function (match, tag, args) {
    var result = '';
    switch (tag) {
      case 'h1':
        result += ' \\section*{';
        break;
      case '/h1':
        result += '} ';
        break;
      case 'h2':
        result += ' \\subsection*{';
        break;
      case '/h2':
        result += '} ';
        break;
      case 'p':
        result += ' \\par\\addvspace{\\medskipamount}\\noindent ';
        break;
      case '/p':
        result += ' ';
        break;
      case 'ul':
        result += ' \\begin{itemize} ';
        break;
      case '/ul':
        result += ' \\end{itemize} ';
        break;
      case 'ol':
        result += ' \\begin{enumerate} ';
        break;
      case '/ol':
        result += ' \\end{enumerate} ';
        break;
      case 'li':
        result += ' \\item ';
        break;
      case '/li':
        result += ' ';
        break;
      case 'b':
        result += '\\textbf{';
        break;
      case '/b':
        result += '}';
        break;
      case 'i':
        result += '\\textit{';
        break;
      case '/i':
        result += '}';
        break;
      case 'u':
        result += '\\underline{';
        break;
      case '/u':
        result += '}';
        break;
      case 'strike':
        result += '\\sout{';
        break;
      case '/strike':
        result += '}';
        break;
      case 'br/':
        result += ' ';
        break;
      default:
        result += '<' + tag + '>';
        break;
    }
    return result;
  };

  /**
  * Take an HTML string and replace its tags with LaTeX commands.
  *
  * @param {string} htmlString The HTML string to parse.
  * @return {string} The corresponding LaTeX string.
  */
  this.tokenize = function (htmlString) {
    /**
     * General regular expressions in java script are a quite different, see:
     *   https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Regular_Expressions?redirectlocale=en-US&redirectslug=JavaScript%2FGuide%2FRegular_Expressions
     * string.replace is explained here:
     *   https://developer.mozilla.org/en-US/docs/JavaScript/Reference/Global_Objects/String/replace
     *
     * '([/a-zA-Z0-9]+)' is the second argument of tagsParse (the tag). A tag
     * may include '/' or word letters.
     * '([^<]*)' might be the third argument of tagsParse. This is for
     * example 'style="color: blue;"'.
     */
    var regularExpression = /<([/a-zA-Z0-9]+)(?:\s+([^<]*))?>/g;
    return htmlString.replace(regularExpression, this.parseTag);
  };

  /**
   * Add header and footer for latex document and tokenize given HTML-code.
   * @param  {string} html HTML-string generated by textAngular
   * @return {latex} Corresponding LaTeX-Code
   */
  this.html2latex = function(html){
    var texHead = '\\documentclass{juwit}\n \\begin{document}\n';
    var texBody = this.tokenize(html);
    var texTail = '\n \\end{document}\n';
    return texHead + texBody + texTail;
  };

  /**
  * Make a request to the server in order to get a pdf file.
  *
  * @param {string} htmlString String to generate pdf from HTML.
  */
  this.download = function(htmlString) {
    var latexString = this.html2latex(htmlString);
    $http.post("/compile", {"latexCode": latexString})
    .success(function(data, status, headers, config) {
      if (typeof data.redirect === 'string') {
        window.open(data.redirect, '_new', 'toolbar=yes, location=yes, status=yes, menubar=yes, scrollbars=yes');
      }
    }).error(function(data, status, headers, config) {
      //TODO: Error Handling
    })
  };
}]);
<|endoftext|>


<commit_before>/*
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements.  See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership.  The ASF licenses this file
 * to you under the Apache License, Version 2.0 (the
 * "License"); you may not use this file except in compliance
 * with the License.  You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing,
 * software distributed under the License is distributed on an
 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
 * KIND, either express or implied.  See the License for the
 * specific language governing permissions and limitations
 * under the License.
 */

// Default syndicator configuration. Rather than replacing this
// file, you should create your own syndicator.js file and
// load it directly by modifying the value of web.xml.
// All configurations will automatically inherit values from this
// config, so you only need to provide configuration for items
// that you require explicit special casing for.

// Please namespace your attributes using the same conventions
// as you would for javascript objects, e.g. gadgets.features
// rather than "features".

// NOTE: Please leave trailing commas to reduce errors when adding new fields.
// All known common server-side JSON parsers will handle this without issue.

// Syndicator must be an array; this allows multiple syndicators
// to share configuration.
{"gadgets.syndicator" : ["default"],

// Location of opensocial-0.7 javascript (loaded server-side).
"opensocial.0.7.location" : null, // not supported by default. over ride this in
                                  // your own syndicator file.

// This config data will be passed down to javascript. Please
// configure your object using the feature name rather than
// the javascript name.

// Only configuration for required features will be used.
// See individual feature.xml files for configuration details.
"gadgets.features" : {
  "core.io" : {
    "proxyUrl" : "http://www.gmodules.com/ig/proxy?url=%url%",
    "jsonProxyUrl" : "proxy?output=js",
  },
  "views" : {
    "default" : {
      "isOnlyVisible" : false,
      "aliases": ["DASHBOARD"],
    },
    "profile" : {
      "isOnlyVisible" : false,
    },
    "canvas" : {
      "isOnlyVisible" : true,
      "aliases" : ["FULL_PAGE"]
    },
  },
  "rpc" : {
    // This should never be on the same host in a production environment!
    // Only use this for TESTING!
    "parentRelayUrl" : "files/container/ifpc_relay.html",
    "useLegacyProtocol" : false,
  },
}}
<commit_msg>Reverted ifpc_relay to rpc_relay (regression from last patch).<commit_after>/*
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements.  See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership.  The ASF licenses this file
 * to you under the Apache License, Version 2.0 (the
 * "License"); you may not use this file except in compliance
 * with the License.  You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing,
 * software distributed under the License is distributed on an
 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
 * KIND, either express or implied.  See the License for the
 * specific language governing permissions and limitations
 * under the License.
 */

// Default syndicator configuration. Rather than replacing this
// file, you should create your own syndicator.js file and
// load it directly by modifying the value of web.xml.
// All configurations will automatically inherit values from this
// config, so you only need to provide configuration for items
// that you require explicit special casing for.

// Please namespace your attributes using the same conventions
// as you would for javascript objects, e.g. gadgets.features
// rather than "features".

// NOTE: Please leave trailing commas to reduce errors when adding new fields.
// All known common server-side JSON parsers will handle this without issue.

// Syndicator must be an array; this allows multiple syndicators
// to share configuration.
{"gadgets.syndicator" : ["default"],

// Location of opensocial-0.7 javascript (loaded server-side).
"opensocial.0.7.location" : null, // not supported by default. over ride this in
                                  // your own syndicator file.

// This config data will be passed down to javascript. Please
// configure your object using the feature name rather than
// the javascript name.

// Only configuration for required features will be used.
// See individual feature.xml files for configuration details.
"gadgets.features" : {
  "core.io" : {
    "proxyUrl" : "http://www.gmodules.com/ig/proxy?url=%url%",
    "jsonProxyUrl" : "proxy?output=js",
  },
  "views" : {
    "default" : {
      "isOnlyVisible" : false,
      "aliases": ["DASHBOARD"],
    },
    "profile" : {
      "isOnlyVisible" : false,
    },
    "canvas" : {
      "isOnlyVisible" : true,
      "aliases" : ["FULL_PAGE"]
    },
  },
  "rpc" : {
    // This should never be on the same host in a production environment!
    // Only use this for TESTING!
    "parentRelayUrl" : "files/container/rpc_relay.html",
    "useLegacyProtocol" : false,
  },
}}
<|endoftext|>


<commit_before>global.WEBPACK_ENV = "production";

var webpack = require("webpack");
var generateConfig = require("./webpack.config.base");
var exec = require("child_process").execSync;
var path = require("path");
var ExtractTextPlugin = require("extract-text-webpack-plugin");
var FarmBotRenderer = require("./farmBotRenderer");
var glob = require("glob");
var OptimizeCssAssetsPlugin = require('optimize-css-assets-webpack-plugin');
var webpackUglifyJsPlugin = require('webpack-uglify-js-plugin');

c = function() {

    var conf = generateConfig();
    conf.module.rules.push({
        test: [/\.scss$/, /\.css$/],
        loader: ExtractTextPlugin.extract("css-loader!sass-loader")
    });

    // PLUGINS:
    [
        new webpack.DefinePlugin({
            "process.env.NODE_ENV": JSON.stringify("production"),
            "process.env.REVISION": JSON.stringify(
                exec('git log --pretty=format:"%h%n%ad%n%f" -1').toString()),
        }),
        new ExtractTextPlugin({
            filename: "dist/styles.css",
            disable: false,
            allChunks: true
        }),
        new OptimizeCssAssetsPlugin({
            assetNameRegExp: /\.css$/g,
            cssProcessor: require("cssnano"),
            cssProcessorOptions: { discardComments: { removeAll: true } },
            canPrint: true
        }),
        new webpackUglifyJsPlugin({
            cacheFolder: path.resolve(__dirname, 'public/cached_uglify/'),
            debug: true,
            minimize: true,
            sourceMap: true,
            output: {
                comments: false
            },
            compressor: {
                warnings: false
            }
        })
    ].forEach(function(x) { conf.plugins.push(x) })

    return conf;
}

module.exports = c();<commit_msg>screw_ie8<commit_after>global.WEBPACK_ENV = "production";

var webpack = require("webpack");
var generateConfig = require("./webpack.config.base");
var exec = require("child_process").execSync;
var path = require("path");
var ExtractTextPlugin = require("extract-text-webpack-plugin");
var FarmBotRenderer = require("./farmBotRenderer");
var glob = require("glob");
var OptimizeCssAssetsPlugin = require('optimize-css-assets-webpack-plugin');
var webpackUglifyJsPlugin = require('webpack-uglify-js-plugin');

c = function() {

    var conf = generateConfig();
    conf.module.rules.push({
        test: [/\.scss$/, /\.css$/],
        loader: ExtractTextPlugin.extract("css-loader!sass-loader")
    });

    // PLUGINS:
    [
        new webpack.DefinePlugin({
            "process.env.NODE_ENV": JSON.stringify("production"),
            "process.env.REVISION": JSON.stringify(
                exec('git log --pretty=format:"%h%n%ad%n%f" -1').toString()),
        }),
        new ExtractTextPlugin({
            filename: "dist/styles.css",
            disable: false,
            allChunks: true
        }),
        new OptimizeCssAssetsPlugin({
            assetNameRegExp: /\.css$/g,
            cssProcessor: require("cssnano"),
            cssProcessorOptions: { discardComments: { removeAll: true } },
            canPrint: true
        }),
        new webpackUglifyJsPlugin({
            cacheFolder: path.resolve(__dirname, 'public/cached_uglify/'),
            debug: true,
            minimize: true,
            sourceMap: true,
            screw_ie8: true,
            output: {
                comments: false
            },
            compressor: {
                warnings: false
            }
        })
    ].forEach(function(x) { conf.plugins.push(x) })

    return conf;
}

module.exports = c();<|endoftext|>


<commit_before>angular.module('ui.bootstrap.datetimepicker', ["ui.bootstrap.dateparser", "ui.bootstrap.datepicker", "ui.bootstrap.timepicker"])
  .directive('datepickerPopup', function () {
    return {
      restrict: 'EAC',
      require: 'ngModel',
      link: function (scope, element, attr, controller) {
        //remove the default formatter from the input directive to prevent conflict
        controller.$formatters.shift();
      }
    }
  })
  .directive('datetimepicker', [
    function () {

      function versionCheck(){
        return (angular.version.major === 1 && (angular.version.minor > 4 || (angular.version.minor === 4 && angular.version.dot >= 4)));
      }

      if (!versionCheck()) {
        return {
          restrict: 'EA',
          template: "
Angular 1.4.4 or above is required for datetimepicker to work correctly
"
        };
      }
      return {
        restrict: 'EA',
        require: 'ngModel',
        scope: {
          ngModel: '=',
          ngChange: '&',
          dayFormat: "=",
          monthFormat: "=",
          yearFormat: "=",
          minTime: "=",
          maxTime: "=",
          dayHeaderFormat: "=",
          dayTitleFormat: "=",
          monthTitleFormat: "=",
          yearRange: "=",
          showButtonBar: "=",
          dateOptions: "=?",
          dateDisabled: "&",
          dateNgClick: "&",
          dateNgFocus: "&",
          hourStep: "=",
          dateOpened: "=",
          minuteStep: "=",
          showMeridian: "=",
          meredians: "=",
          mousewheel: "=",
          readonlyTime: "=",
          readonlyDate: "=",
          disabledDate: "=",
          hiddenTime: "=",
          hiddenDate: "=",
          datepickerTemplateUrl: "@",
          datepickerPopupTemplateUrl: "@",
          timepickerTemplateUrl: "@"
        },
        template: function (elem, attrs) {
          function dashCase(name) {
            return name.replace(/[A-Z]/g, function (letter, pos) {
              return (pos ? '-' : '') + letter.toLowerCase();
            });
          }

          function createAttr(innerAttr, dateTimeAttrOpt) {
            var dateTimeAttr = angular.isDefined(dateTimeAttrOpt) ? dateTimeAttrOpt : innerAttr;
            if (attrs[dateTimeAttr]) {
              return dashCase(innerAttr) + "=\"" + dateTimeAttr + "\" ";
            } else {
              return '';
            }
          }

          function createFuncAttr(innerAttr, funcArgs, dateTimeAttrOpt, defaultImpl) {
            var dateTimeAttr = angular.isDefined(dateTimeAttrOpt) ? dateTimeAttrOpt : innerAttr;
            if (attrs[dateTimeAttr]) {
              return dashCase(innerAttr) + "=\"" + dateTimeAttr + "({" + funcArgs + "})\" ";
            } else {
              return angular.isDefined(defaultImpl) ? dashCase(innerAttr) + "=\"" + defaultImpl + "\"" : "";
            }
          }

          function createEvalAttr(innerAttr, dateTimeAttrOpt) {
            var dateTimeAttr = angular.isDefined(dateTimeAttrOpt) ? dateTimeAttrOpt : innerAttr;
            if (attrs[dateTimeAttr]) {
              return dashCase(innerAttr) + "=\"" + attrs[dateTimeAttr] + "\" ";
            } else {
              return dashCase(innerAttr) + " ";
            }
          }

          function createAttrConcat(previousAttrs, attr) {
            return previousAttrs + createAttr.apply(null, attr)
          }

          var dateTmpl = "
" +
            "<input class=\"form-control\" type=\"text\" " +
            "name=\"datepicker\"" +
            "ng-change=\"date_change($event)\" " +
            "is-open=\"innerDateOpened\" " +
            "datepicker-options=\"dateOptions\" " +
            "uib-datepicker-popup=\"{{dateFormat}}\"" +
            "ng-model=\"ngModel\" " + [
              ["dayFormat"],
              ["monthFormat"],
              ["yearFormat"],
              ["dayHeaderFormat"],
              ["dayTitleFormat"],
              ["monthTitleFormat"],
              ["yearRange"],
              ["showButtonBar"],
              ["ngHide", "hiddenDate"],
              ["ngReadonly", "readonlyDate"],
              ["ngDisabled", "disabledDate"]
            ].reduce(createAttrConcat, '') +
            createFuncAttr("ngClick",
              "$event: $event, opened: opened",
              "dateNgClick",
              "open($event)") +
            createFuncAttr("ngFocus",
              "$event: $event, opened: opened",
              "dateNgFocus",
              "open($event)") +
            createEvalAttr("currentText", "currentText") +
            createEvalAttr("datepickerTemplateUrl", "datepickerTemplateUrl") +
            createEvalAttr("datepickerPopupTemplateUrl", "datepickerPopupTemplateUrl") +
            createEvalAttr("clearText", "clearText") +
            createEvalAttr("datepickerAppendToBody", "datepickerAppendToBody") +
            createEvalAttr("closeText", "closeText") +
            createEvalAttr("placeholder", "placeholder") +
            "/>\n" +
            "
\n";
          var timeTmpl = "
\n" +
            "

\n" +
            "
";
          // form is isolated so the directive is registered as one component in the parent form (not date and time)
          var tmpl = "<ng-form name=\"datetimepickerForm\" isolate-form>" + dateTmpl + timeTmpl + "</ng-form>";
          return tmpl;
        },
        controller: ['$scope', '$attrs',
          function ($scope, $attrs) {
            $scope.date_change = function () {
              // If we changed the date only, set the time (h,m) on it.
              // This is important in case the previous date was null.
              // This solves the issue when the user set a date and time, cleared the date, and chose another date,
              // and then, the time was cleared too - which is unexpected
              var time = $scope.time;
              if ($scope.ngModel && $scope.time) { // if ngModel is null, that's because the user cleared the date field
                $scope.ngModel.setHours(time.getHours(), time.getMinutes(), 0, 0);
                $scope.ngModel = new Date($scope.ngModel); // By default, ngModel watches the model by reference, not value. This is important to know when binding inputs to models that are objects (e.g. Date) (from: https://docs.angularjs.org/api/ng/directive/ngModel)
              }
            };
            $scope.time_change = function () {
              if ($scope.ngModel && $scope.time) {
                $scope.ngModel.setHours($scope.time.getHours(), $scope.time.getMinutes(), 0, 0);
                $scope.ngModel = new Date($scope.ngModel); // By default, ngModel watches the model by reference, not value. This is important to know when binding inputs to models that are objects (e.g. Date) (from: https://docs.angularjs.org/api/ng/directive/ngModel)
              }  // else the time is invalid, keep the current Date value in datepicker
            };
            $scope.open = function ($event) {
              $event.preventDefault();
              $event.stopPropagation();
              $scope.innerDateOpened = true;
            };
            $attrs.$observe('dateFormat', function(newDateFormat, oldValue) {
              $scope.dateFormat = newDateFormat;
            });
            $scope.dateOptions = angular.isDefined($scope.dateOptions) ? $scope.dateOptions : {};
            $scope.dateOptions.dateDisabled = $scope.dateDisabled;
          }
        ],
        link: function (scope, element, attrs, ctrl) {
          var updateMinTime = function() {
            if (!scope.ngModel) {
              return;
            }
            if (scope.minTime) {
              scope.minDate = new Date(scope.ngModel.getFullYear(),
                                       scope.ngModel.getMonth(),
                                       scope.ngModel.getDate(),
                                       scope.minTime.getHours(),
                                       scope.minTime.getMinutes(),
                                       0);
              if (scope.dateOptions.minDate && scope.dateOptions.minDate > scope.minDate) {
                scope.minDate = scope.dateOptions.minDate;
              }
            } else {
              scope.minDate = scope.dateOptions.minDate;
            }
          };
          var updateMaxTime = function() {
            if (!scope.ngModel) {
              return;
            }
            if (scope.maxTime) {
              scope.maxDate = new Date(scope.ngModel.getFullYear(),
                                       scope.ngModel.getMonth(),
                                       scope.ngModel.getDate(),
                                       scope.maxTime.getHours(),
                                       scope.maxTime.getMinutes(),
                                       0);
              if (scope.dateOptions.maxDate && scope.dateOptions.maxDate < scope.maxDate) {
                scope.maxDate = scope.dateOptions.maxDate;
              }
            } else {
              scope.maxDate = scope.dateOptions.maxDate;
            }
          };

          var firstTimeAssign = true;

          scope.$watch(function () {
            return scope.ngModel;
          }, function (newTime) {
            if (scope.ngModel && !(scope.ngModel instanceof Date)) {
                // convert from ISO format to Date
                scope.ngModel = new Date(scope.ngModel);
            }

            var timeElement = element[0].querySelector('[name=timepicker]');

            // if a time element is focused, updating its model will cause hours/minutes to be formatted by padding with leading zeros
            if (timeElement && !timeElement.contains(document.activeElement)) {

              if (newTime === null || newTime === '') { // if the newTime is not defined
                if (firstTimeAssign) { // if it's the first time we assign the time value
                  // create a new default time where the hours, minutes, seconds and milliseconds are set to 0.
                  newTime = new Date();
                  newTime.setHours(0, 0, 0, 0);
                } else { // clear the time
                  scope.time = null;
                  if (scope.ngChange) scope.$eval(scope.ngChange);
                  return;
                }
              }
              // Update timepicker (watch on ng-model in timepicker does not use object equality),
              // also if the ngModel was not a Date, convert it to date
              newTime = new Date(newTime);

              if (isNaN(newTime.getTime()) === false) {
                scope.time = newTime; // change the time in timepicker
                if (firstTimeAssign) {
                  firstTimeAssign = false;
                }
              }
            }
            updateMinTime();
            updateMaxTime();
            if (scope.ngChange) {
              scope.$eval(scope.ngChange);
            }
          }, true);

          scope.$watch(function () {
            return scope.datetimepickerForm && Object.keys(scope.datetimepickerForm.$error);
          }, function (errors) {
            if (angular.isUndefined(errors)) {
              return;
            }
            Object.keys(ctrl.$error).forEach(function (error) {
              ctrl.$setValidity(error, true);
            });
            errors.forEach(function (error) {
              ctrl.$setValidity(error, false);
            });
          }, true);

          scope.$watch(function () {
            return scope.datetimepickerForm && (scope.datetimepickerForm.timepicker.$touched || scope.datetimepickerForm.datepicker.$touched);
          }, function (touched) {
            if (touched) {
              ctrl.$setTouched();
            }
          });

          scope.$watch(function () {
            return scope.datetimepickerForm && scope.datetimepickerForm.$dirty;
          }, function (dirty) {
            if (dirty) {
              ctrl.$setDirty();
            }
          });

          scope.$watch('dateOpened', function (value) {
            scope.innerDateOpened = value;
          });
          scope.$watch('innerDateOpened', function (value) {
            if (angular.isDefined(scope.dateOpened)) {
              scope.dateOpened = value;
            }
          });
          scope.$watch('dateOptions.minDate', function (value) {
            updateMinTime();
          });
          scope.$watch('timeMin', function (value) {
            updateMinTime();
          });
          scope.$watch('dateOptions.maxDate', function (value) {
            updateMaxTime();
          });
          scope.$watch('timeMax', function (value) {
            updateMaxTime();
          });
        }
      }
    }
  ]).directive('isolateForm', [function () {
  return {
    restrict: 'A',
    require: '?form',
    link: function (scope, element, attrs, formController) {
      if (!formController) {
        return;
      }

      // Remove this form from parent controller
      formController.$$parentForm.$removeControl(formController)
      if (!formController.$$parentForm) {
        return;
      }
      var _handler = formController.$setValidity;
      formController.$setValidity = function (validationErrorKey, isValid, cntrl) {
          _handler.call(formController, validationErrorKey, isValid, cntrl);
          formController.$$parentForm.$setValidity(validationErrorKey, true, this);
      }
    }
  };
}]);
<commit_msg>Added support for required attribute<commit_after>angular.module('ui.bootstrap.datetimepicker', ["ui.bootstrap.dateparser", "ui.bootstrap.datepicker", "ui.bootstrap.timepicker"])
  .directive('datepickerPopup', function () {
    return {
      restrict: 'EAC',
      require: 'ngModel',
      link: function (scope, element, attr, controller) {
        //remove the default formatter from the input directive to prevent conflict
        controller.$formatters.shift();
      }
    }
  })
  .directive('datetimepicker', [
    function () {

      function versionCheck(){
        return (angular.version.major === 1 && (angular.version.minor > 4 || (angular.version.minor === 4 && angular.version.dot >= 4)));
      }

      if (!versionCheck()) {
        return {
          restrict: 'EA',
          template: "
Angular 1.4.4 or above is required for datetimepicker to work correctly
"
        };
      }
      return {
        restrict: 'EA',
        require: 'ngModel',
        scope: {
          ngModel: '=',
          ngChange: '&',
          dayFormat: "=",
          monthFormat: "=",
          yearFormat: "=",
          minTime: "=",
          maxTime: "=",
          dayHeaderFormat: "=",
          dayTitleFormat: "=",
          monthTitleFormat: "=",
          yearRange: "=",
          showButtonBar: "=",
          dateOptions: "=?",
          dateDisabled: "&",
          dateNgClick: "&",
          dateNgFocus: "&",
          hourStep: "=",
          dateOpened: "=",
          minuteStep: "=",
          showMeridian: "=",
          meredians: "=",
          mousewheel: "=",
          readonlyTime: "=",
          readonlyDate: "=",
          disabledDate: "=",
          hiddenTime: "=",
          hiddenDate: "=",
          datepickerTemplateUrl: "@",
          datepickerPopupTemplateUrl: "@",
          timepickerTemplateUrl: "@"
        },
        template: function (elem, attrs) {
          function dashCase(name) {
            return name.replace(/[A-Z]/g, function (letter, pos) {
              return (pos ? '-' : '') + letter.toLowerCase();
            });
          }

          function createAttr(innerAttr, dateTimeAttrOpt) {
            var dateTimeAttr = angular.isDefined(dateTimeAttrOpt) ? dateTimeAttrOpt : innerAttr;
            if (attrs[dateTimeAttr]) {
              return dashCase(innerAttr) + "=\"" + dateTimeAttr + "\" ";
            } else if (dateTimeAttr in attrs) { // attribute with an empty value such as "required"
              return dateTimeAttr + " ";
            } else {
              return '';
            }
          }

          function createFuncAttr(innerAttr, funcArgs, dateTimeAttrOpt, defaultImpl) {
            var dateTimeAttr = angular.isDefined(dateTimeAttrOpt) ? dateTimeAttrOpt : innerAttr;
            if (attrs[dateTimeAttr]) {
              return dashCase(innerAttr) + "=\"" + dateTimeAttr + "({" + funcArgs + "})\" ";
            } else {
              return angular.isDefined(defaultImpl) ? dashCase(innerAttr) + "=\"" + defaultImpl + "\"" : "";
            }
          }

          function createEvalAttr(innerAttr, dateTimeAttrOpt) {
            var dateTimeAttr = angular.isDefined(dateTimeAttrOpt) ? dateTimeAttrOpt : innerAttr;
            if (attrs[dateTimeAttr]) {
              return dashCase(innerAttr) + "=\"" + attrs[dateTimeAttr] + "\" ";
            } else {
              return dashCase(innerAttr) + " ";
            }
          }

          function createAttrConcat(previousAttrs, attr) {
            return previousAttrs + createAttr.apply(null, attr)
          }

          var dateTmpl = "
" +
            "<input class=\"form-control\" type=\"text\" " +
            "name=\"datepicker\"" +
            "ng-change=\"date_change($event)\" " +
            "is-open=\"innerDateOpened\" " +
            "datepicker-options=\"dateOptions\" " +
            "uib-datepicker-popup=\"{{dateFormat}}\"" +
            "ng-model=\"ngModel\" " + [
              ["dayFormat"],
              ["monthFormat"],
              ["yearFormat"],
              ["dayHeaderFormat"],
              ["dayTitleFormat"],
              ["monthTitleFormat"],
              ["yearRange"],
              ["required"],
              ["showButtonBar"],
              ["ngHide", "hiddenDate"],
              ["ngReadonly", "readonlyDate"],
              ["ngDisabled", "disabledDate"]
            ].reduce(createAttrConcat, '') +
            createFuncAttr("ngClick",
              "$event: $event, opened: opened",
              "dateNgClick",
              "open($event)") +
            createFuncAttr("ngFocus",
              "$event: $event, opened: opened",
              "dateNgFocus",
              "open($event)") +
            createEvalAttr("currentText", "currentText") +
            createEvalAttr("datepickerTemplateUrl", "datepickerTemplateUrl") +
            createEvalAttr("datepickerPopupTemplateUrl", "datepickerPopupTemplateUrl") +
            createEvalAttr("clearText", "clearText") +
            createEvalAttr("datepickerAppendToBody", "datepickerAppendToBody") +
            createEvalAttr("closeText", "closeText") +
            createEvalAttr("placeholder", "placeholder") +
            "/>\n" +
            "
\n";
          var timeTmpl = "
\n" +
            "<div uib-timepicker min=\"minDate\" max=\"maxDate\" " + [
              ["hourStep"],
              ["minuteStep"],
              ["showMeridian"],
              ["required"],
              ["meredians"],
              ["mousewheel"],
              ["ngHide", "hiddenTime"],
              ["ngDisabled", "readonlyTime"]
            ].reduce(createAttrConcat, '') +
            createEvalAttr("showSpinners", "showSpinners") +
            createEvalAttr("templateUrl", "timepickerTemplateUrl") +
            ">
\n" +
            "
";
          // form is isolated so the directive is registered as one component in the parent form (not date and time)
          var tmpl = "<ng-form name=\"datetimepickerForm\" isolate-form>" + dateTmpl + timeTmpl + "</ng-form>";
          return tmpl;
        },
        controller: ['$scope', '$attrs',
          function ($scope, $attrs) {
            $scope.date_change = function () {
              // If we changed the date only, set the time (h,m) on it.
              // This is important in case the previous date was null.
              // This solves the issue when the user set a date and time, cleared the date, and chose another date,
              // and then, the time was cleared too - which is unexpected
              var time = $scope.time;
              if ($scope.ngModel && $scope.time) { // if ngModel is null, that's because the user cleared the date field
                $scope.ngModel.setHours(time.getHours(), time.getMinutes(), 0, 0);
                $scope.ngModel = new Date($scope.ngModel); // By default, ngModel watches the model by reference, not value. This is important to know when binding inputs to models that are objects (e.g. Date) (from: https://docs.angularjs.org/api/ng/directive/ngModel)
              }
            };
            $scope.time_change = function () {
              if ($scope.ngModel && $scope.time) {
                $scope.ngModel.setHours($scope.time.getHours(), $scope.time.getMinutes(), 0, 0);
                $scope.ngModel = new Date($scope.ngModel); // By default, ngModel watches the model by reference, not value. This is important to know when binding inputs to models that are objects (e.g. Date) (from: https://docs.angularjs.org/api/ng/directive/ngModel)
              }  // else the time is invalid, keep the current Date value in datepicker
            };
            $scope.open = function ($event) {
              $event.preventDefault();
              $event.stopPropagation();
              $scope.innerDateOpened = true;
            };
            $attrs.$observe('dateFormat', function(newDateFormat, oldValue) {
              $scope.dateFormat = newDateFormat;
            });
            $scope.dateOptions = angular.isDefined($scope.dateOptions) ? $scope.dateOptions : {};
            $scope.dateOptions.dateDisabled = $scope.dateDisabled;
          }
        ],
        link: function (scope, element, attrs, ctrl) {
          var updateMinTime = function() {
            if (!scope.ngModel) {
              return;
            }
            if (scope.minTime) {
              scope.minDate = new Date(scope.ngModel.getFullYear(),
                                       scope.ngModel.getMonth(),
                                       scope.ngModel.getDate(),
                                       scope.minTime.getHours(),
                                       scope.minTime.getMinutes(),
                                       0);
              if (scope.dateOptions.minDate && scope.dateOptions.minDate > scope.minDate) {
                scope.minDate = scope.dateOptions.minDate;
              }
            } else {
              scope.minDate = scope.dateOptions.minDate;
            }
          };
          var updateMaxTime = function() {
            if (!scope.ngModel) {
              return;
            }
            if (scope.maxTime) {
              scope.maxDate = new Date(scope.ngModel.getFullYear(),
                                       scope.ngModel.getMonth(),
                                       scope.ngModel.getDate(),
                                       scope.maxTime.getHours(),
                                       scope.maxTime.getMinutes(),
                                       0);
              if (scope.dateOptions.maxDate && scope.dateOptions.maxDate < scope.maxDate) {
                scope.maxDate = scope.dateOptions.maxDate;
              }
            } else {
              scope.maxDate = scope.dateOptions.maxDate;
            }
          };

          var firstTimeAssign = true;

          scope.$watch(function () {
            return scope.ngModel;
          }, function (newTime) {
            if (scope.ngModel && !(scope.ngModel instanceof Date)) {
                // convert from ISO format to Date
                scope.ngModel = new Date(scope.ngModel);
            }

            var timeElement = element[0].querySelector('[name=timepicker]');

            // if a time element is focused, updating its model will cause hours/minutes to be formatted by padding with leading zeros
            if (timeElement && !timeElement.contains(document.activeElement)) {

              if (newTime === null || newTime === '') { // if the newTime is not defined
                if (firstTimeAssign) { // if it's the first time we assign the time value
                  // create a new default time where the hours, minutes, seconds and milliseconds are set to 0.
                  newTime = new Date();
                  newTime.setHours(0, 0, 0, 0);
                } else { // clear the time
                  scope.time = null;
                  if (scope.ngChange) scope.$eval(scope.ngChange);
                  return;
                }
              }
              // Update timepicker (watch on ng-model in timepicker does not use object equality),
              // also if the ngModel was not a Date, convert it to date
              newTime = new Date(newTime);

              if (isNaN(newTime.getTime()) === false) {
                scope.time = newTime; // change the time in timepicker
                if (firstTimeAssign) {
                  firstTimeAssign = false;
                }
              }
            }
            updateMinTime();
            updateMaxTime();
            if (scope.ngChange) {
              scope.$eval(scope.ngChange);
            }
          }, true);

          scope.$watch(function () {
            return scope.datetimepickerForm && Object.keys(scope.datetimepickerForm.$error);
          }, function (errors) {
            if (angular.isUndefined(errors)) {
              return;
            }
            Object.keys(ctrl.$error).forEach(function (error) {
              ctrl.$setValidity(error, true);
            });
            errors.forEach(function (error) {
              ctrl.$setValidity(error, false);
            });
          }, true);

          scope.$watch(function () {
            return scope.datetimepickerForm && (scope.datetimepickerForm.timepicker.$touched || scope.datetimepickerForm.datepicker.$touched);
          }, function (touched) {
            if (touched) {
              ctrl.$setTouched();
            }
          });

          scope.$watch(function () {
            return scope.datetimepickerForm && scope.datetimepickerForm.$dirty;
          }, function (dirty) {
            if (dirty) {
              ctrl.$setDirty();
            }
          });

          scope.$watch('dateOpened', function (value) {
            scope.innerDateOpened = value;
          });
          scope.$watch('innerDateOpened', function (value) {
            if (angular.isDefined(scope.dateOpened)) {
              scope.dateOpened = value;
            }
          });
          scope.$watch('dateOptions.minDate', function (value) {
            updateMinTime();
          });
          scope.$watch('timeMin', function (value) {
            updateMinTime();
          });
          scope.$watch('dateOptions.maxDate', function (value) {
            updateMaxTime();
          });
          scope.$watch('timeMax', function (value) {
            updateMaxTime();
          });
        }
      }
    }
  ]).directive('isolateForm', [function () {
  return {
    restrict: 'A',
    require: '?form',
    link: function (scope, element, attrs, formController) {
      if (!formController) {
        return;
      }

      // Remove this form from parent controller
      formController.$$parentForm.$removeControl(formController)
      if (!formController.$$parentForm) {
        return;
      }
      var _handler = formController.$setValidity;
      formController.$setValidity = function (validationErrorKey, isValid, cntrl) {
          _handler.call(formController, validationErrorKey, isValid, cntrl);
          formController.$$parentForm.$setValidity(validationErrorKey, true, this);
      }
    }
  };
}]);
<|endoftext|>


<commit_before>//Lets require/import the HTTP module
var http = require('http');
var bodyParser = require('body-parser');
var showMeTheMoney =100;

//Lets define a port we want to listen to
const PORT=9559;

var express = require('express');
var app = express();
app.use(bodyParser.json());
app.use(express.static('public'));

app.get('/', function (req, res) {
  res.send('Hello World!');

});

app.get('/stock/', function (req, res) {
  res.send('Your stock value:'+showMeTheMoney);

});
app.post('/stock/', function (req, res) {
  showMeTheMoney = req.body.value;
  res.send('Your new stock value:'+showMeTheMoney);

});

app.get('/coin/', function (req, res) {
  res.send({value: showMeTheMoney});

});

app.post('/coin/', function (req, res) {
  showMeTheMoney = showMeTheMoney+1;
  res.send('Your new stock value:'+showMeTheMoney);
});

var server = app.listen(3000, function () {
  var host = server.address().address;
  var port = server.address().port;

  console.log('Example app listening at http://%s:%s', host, port);
});
<commit_msg>peticiones nuevas y variables ok<commit_after>//Lets require/import the HTTP module
var http = require('http');
var bodyParser = require('body-parser');
var money = 0;
var coins = 0;
var shareCoefficient = 1;

//Lets define a port we want to listen to
const PORT=9559;

var express = require('express');
var app = express();
app.use(bodyParser.json());
app.use(express.static('public'));

app.get('/', function (req, res) {
  res.send('Hello World!');

});

app.get('/money/', function (req, res) {
  money = coins*shareCoefficient;
  res.send({value: money});

});

app.get('/stock/', function (req, res) {
  res.send({value: shareCoefficient});
});

app.post('/stock/', function (req, res) {
  shareCoefficient = req.body.value;
  res.send({value: shareCoefficient});

});

app.get('/coin/', function (req, res) {
  res.send({value: coins});

});

app.post('/coin/', function (req, res) {
  coins = coins+1;
  res.send({value: coins});
});

var server = app.listen(3000, function () {
  var host = server.address().address;
  var port = server.address().port;

  console.log('Example app listening at http://%s:%s', host, port);
});
<|endoftext|>


<commit_before>/*! customized initialization script
*/
var initPhotoSwipeFromDOM = function(gallerySelector) {

	// parse slide data (url, title, size ...) from DOM elements
	// (children of gallerySelector)
	var parseThumbnailElements = function(el) {
		var thumbElements = el.querySelectorAll('[data-index]'),
			numNodes = thumbElements.length,
			items = [],
			a,
			img,
			src,
			size,
			item;

		for(var i = 0; i < numNodes; i++) {
			a = thumbElements[i];
			img = a.childNodes[0];

			src = a.getAttribute('href').replace(/\.jpg$/,'-med.jpg');
			size = a.getAttribute('data-size-med').split('x');

			// create slide object
			item = {
				pid: a.getAttribute('id'),
				src: src,
				fsrc: a.getAttribute('href'),
				w: parseInt(size[0], 10),
				h: parseInt(size[1], 10),
				el: img
			};

			items.push(item);
		}

		return items;
	};

	// find nearest parent element
	var closestParent = function closest(el, fn) {
		return el && ( fn(el) ? el : closest(el.parentNode, fn) );
	};

	// triggers when user clicks on thumbnail
	var onThumbnailClick = function(e) {
		e = e || window.event;
		var eTarget = e.target || e.srcElement;

		// onclick is bound to gallery container, so only act when an image is clicked
		if(eTarget.tagName.toUpperCase() === 'IMG') {
			var img = eTarget;
		} else {
			//console.log('eTarget',eTarget);
			return true;
		}

		e.preventDefault ? e.preventDefault() : e.returnValue = false;

		var a = closestParent(img, function(el) {
			return (el.tagName && el.tagName.toUpperCase() === 'A');
		});

		var gallery = closestParent(img, function(el) {
			return (el.tagName && el.tagName.toUpperCase() === 'DIV');
		});

		var index = a.getAttribute('data-index');

		if(index) {
			// open PhotoSwipe if valid index found
			openPhotoSwipe( index, gallery );
		}
		return false;
	};

	// parse picture index and gallery index from URL (#&gid=gallery-name&pid=DSC_4106.JPG)
	var photoswipeParseHash = function() {
		var hash = window.location.hash.substring(1),
			params = {};

		if(hash.length < 12) {return params;}

		var vars = hash.split('&');
		for (var i = 0; i < vars.length; i++) {
			if(!vars[i]) {continue;}
			var pair = vars[i].split('=');
			if(pair.length < 2) {continue;}
			params[pair[0]] = pair[1];
		}

		return params;
	};

	var openPhotoSwipe = function(index, galleryElement, disableAnimation, fromURL) {
		//console.log('openPhotoSwipe', index, galleryElement, disableAnimation, fromURL);
		var pswpElement = document.querySelectorAll('.pswp')[0],
			pswp,
			options,
			items,
			downloadAttrSupported = ("download" in document.createElement("a")),
			shareButtons = [];

		items = parseThumbnailElements(galleryElement);

		shareButtons.push({id:'open', label:'Open Full-Size', url:'{{raw_image_url}}'});
		if(downloadAttrSupported) {
			shareButtons.push({id:'download', label:'Download Full-Size', url:'{{raw_image_url}}', download:true});
		}

		options = {
			history: true,
			galleryPIDs: true,
			galleryUID: galleryElement.getAttribute('id'),
			bgOpacity: 0.9,
			clickToCloseNonZoomable: false,
			shareButtons: shareButtons,
			getImageURLForShare: function(shareButtonData) {
				return pswp.currItem.fsrc || '';
			},
			getThumbBoundsFn: function(index) {
				var thumbnail = items[index].el,
					pageYScroll = window.pageYOffset || document.documentElement.scrollTop,
					rect = thumbnail.getBoundingClientRect(),
					ratio = items[index].w/items[index].h,
					x, y, w;

				if (ratio > 1) {
					w = rect.width * ratio;
					y = rect.top + pageYScroll;
					x = rect.left - (w - rect.width) / 2;
					// console.log('wider than thumbnail',x,y,w);
				} else {
					w = rect.width;
					y = rect.top + pageYScroll - ((rect.height / ratio) - rect.height) / 2;
					x = rect.left;
					// console.log('narrower than thumbnail',x,y,w);
				}

				return {x:x, y:y, w:w};
			}
		};

		options.index = parseInt(index, 10);

		// exit if index not found
		if( isNaN(options.index) ) {return;}

		if(disableAnimation) {options.showAnimationDuration = 0;}

		// Pass data to PhotoSwipe and initialize it
		pswp = new PhotoSwipe( pswpElement, PhotoSwipeUI_Default, items, options);
		pswp.init();

		// Close when tapping on background
		pswp.framework.bind( pswp.scrollWrap , 'pswpTap', function(e) {
			var tapped = e.target.className;
			//console.log(tapped);
			if (tapped == 'pswp__item' || tapped == 'pswp__zoom-wrap' ) {
				pswp.close();
			}
		});
	};

	// loop through all gallery elements and bind events
	var galleryElements = document.querySelectorAll( gallerySelector );
	for(var i = 0, l = galleryElements.length; i < l; i++) {
		galleryElements[i].onclick = onThumbnailClick;
	}

	// Parse URL and open gallery if it contains #&gid=gallery-name&pid=DSC_4106.JPG
	var hashData = photoswipeParseHash();
	if(hashData.gid) {
		var galleryElement = document.getElementById(hashData.gid);
		if(hashData.pid) {
			var index = document.getElementById(hashData.pid).getAttribute('data-index');
		} else {
			var index = 0; // default to first picture in the gallery
		}
		if(galleryElement && index >= 0) {
			openPhotoSwipe( index,  galleryElement, true, true );
		}
	}
};

// execute above function
initPhotoSwipeFromDOM('.picture-gallery');
<commit_msg>adjust thumb bounds to account for padding<commit_after>/*! customized initialization script
*/
var initPhotoSwipeFromDOM = function(gallerySelector) {

	// parse slide data (url, title, size ...) from DOM elements
	// (children of gallerySelector)
	var parseThumbnailElements = function(el) {
		var thumbElements = el.querySelectorAll('[data-index]'),
			numNodes = thumbElements.length,
			items = [],
			a,
			img,
			src,
			size,
			item;

		for(var i = 0; i < numNodes; i++) {
			a = thumbElements[i];
			img = a.childNodes[0];

			src = a.getAttribute('href').replace(/\.jpg$/,'-med.jpg');
			size = a.getAttribute('data-size-med').split('x');

			// create slide object
			item = {
				pid: a.getAttribute('id'),
				src: src,
				fsrc: a.getAttribute('href'),
				w: parseInt(size[0], 10),
				h: parseInt(size[1], 10),
				el: img
			};

			items.push(item);
		}

		return items;
	};

	// find nearest parent element
	var closestParent = function closest(el, fn) {
		return el && ( fn(el) ? el : closest(el.parentNode, fn) );
	};

	// triggers when user clicks on thumbnail
	var onThumbnailClick = function(e) {
		e = e || window.event;
		var eTarget = e.target || e.srcElement;

		// onclick is bound to gallery container, so only act when an image is clicked
		if(eTarget.tagName.toUpperCase() === 'IMG') {
			var img = eTarget;
		} else {
			//console.log('eTarget',eTarget);
			return true;
		}

		e.preventDefault ? e.preventDefault() : e.returnValue = false;

		var a = closestParent(img, function(el) {
			return (el.tagName && el.tagName.toUpperCase() === 'A');
		});

		var gallery = closestParent(img, function(el) {
			return (el.tagName && el.tagName.toUpperCase() === 'DIV');
		});

		var index = a.getAttribute('data-index');

		if(index) {
			// open PhotoSwipe if valid index found
			openPhotoSwipe( index, gallery );
		}
		return false;
	};

	// parse picture index and gallery index from URL (#&gid=gallery-name&pid=DSC_4106.JPG)
	var photoswipeParseHash = function() {
		var hash = window.location.hash.substring(1),
			params = {};

		if(hash.length < 12) {return params;}

		var vars = hash.split('&');
		for (var i = 0; i < vars.length; i++) {
			if(!vars[i]) {continue;}
			var pair = vars[i].split('=');
			if(pair.length < 2) {continue;}
			params[pair[0]] = pair[1];
		}

		return params;
	};

	var openPhotoSwipe = function(index, galleryElement, disableAnimation, fromURL) {
		//console.log('openPhotoSwipe', index, galleryElement, disableAnimation, fromURL);
		var pswpElement = document.querySelectorAll('.pswp')[0],
			pswp,
			options,
			items,
			downloadAttrSupported = ("download" in document.createElement("a")),
			shareButtons = [];

		items = parseThumbnailElements(galleryElement);

		shareButtons.push({id:'open', label:'Open Full-Size', url:'{{raw_image_url}}'});
		if(downloadAttrSupported) {
			shareButtons.push({id:'download', label:'Download Full-Size', url:'{{raw_image_url}}', download:true});
		}

		options = {
			history: true,
			galleryPIDs: true,
			galleryUID: galleryElement.getAttribute('id'),
			bgOpacity: 0.9,
			clickToCloseNonZoomable: false,
			shareButtons: shareButtons,
			getImageURLForShare: function(shareButtonData) {
				return pswp.currItem.fsrc || '';
			},
			getThumbBoundsFn: function(index) {
				var thumbnail = items[index].el,
					pageYScroll = window.pageYOffset || document.documentElement.scrollTop,
					rect = thumbnail.getBoundingClientRect(),
					/* adjust rect values to to match my css */
					thumbTop = rect.top,
					thumbLeft = rect.left + 4,
					thumbWidth = rect.width - 8,
					thumbHeight = rect.height - 8,
					ratio = items[index].w/items[index].h,
					x, y, w;

				if (ratio > 1) {
					w = thumbWidth * ratio;
					y = thumbTop + pageYScroll;
					x = thumbLeft - (w - thumbWidth) / 2;
					// console.log('wider than thumbnail',x,y,w);
				} else {
					w = thumbWidth;
					y = thumbTop + pageYScroll - ((thumbHeight / ratio) - thumbHeight) / 2;
					x = thumbLeft;
					// console.log('narrower than thumbnail',x,y,w);
				}

				return {x:x, y:y, w:w};
			}
		};

		options.index = parseInt(index, 10);

		// exit if index not found
		if( isNaN(options.index) ) {return;}

		if(disableAnimation) {options.showAnimationDuration = 0;}

		// Pass data to PhotoSwipe and initialize it
		pswp = new PhotoSwipe( pswpElement, PhotoSwipeUI_Default, items, options);
		pswp.init();

		// Close when tapping on background
		pswp.framework.bind( pswp.scrollWrap , 'pswpTap', function(e) {
			var tapped = e.target.className;
			//console.log(tapped);
			if (tapped == 'pswp__item' || tapped == 'pswp__zoom-wrap' ) {
				pswp.close();
			}
		});
	};

	// loop through all gallery elements and bind events
	var galleryElements = document.querySelectorAll( gallerySelector );
	for(var i = 0, l = galleryElements.length; i < l; i++) {
		galleryElements[i].onclick = onThumbnailClick;
	}

	// Parse URL and open gallery if it contains #&gid=gallery-name&pid=DSC_4106.JPG
	var hashData = photoswipeParseHash();
	if(hashData.gid) {
		var galleryElement = document.getElementById(hashData.gid);
		if(hashData.pid) {
			var index = document.getElementById(hashData.pid).getAttribute('data-index');
		} else {
			var index = 0; // default to first picture in the gallery
		}
		if(galleryElement && index >= 0) {
			openPhotoSwipe( index,  galleryElement, true, true );
		}
	}
};

// execute above function
initPhotoSwipeFromDOM('.picture-gallery');
<|endoftext|>


<commit_before>gf.Camera.fx = {
    /**
     * Camera directions, used for certain effects (like shake and scanlines)
     *
     * @property DIRECTION
     * @type Object
     * @static
     */
    DIRECTION: {
        BOTH: 0,
        HORIZONTAL: 1,
        VERTICAL: 2
    }
};

gf.Camera.fx.Effect = function() {
    gf.DisplayObjectContainer.call(this);

    this.addChild(this.gfx = new PIXI.Graphics());
    this.gfx.visible = false;

    this.done = true;
};

gf.inherits(gf.Camera.fx.Effect, gf.DisplayObjectContainer, {
    start: function() {
        this.done = false;
        return this;
    },
    stop: function() {
        this.done = true;
        return this;
    },
    update: function() {
        return this;
    },
    _complete: function() {
        this.done = true;
        if(typeof this.cb === 'function')
            this.cb();
    }
});<commit_msg>if on fx callback you specify 'false' it will prevent the stop call<commit_after>gf.Camera.fx = {
    /**
     * Camera directions, used for certain effects (like shake and scanlines)
     *
     * @property DIRECTION
     * @type Object
     * @static
     */
    DIRECTION: {
        BOTH: 0,
        HORIZONTAL: 1,
        VERTICAL: 2
    }
};

gf.Camera.fx.Effect = function() {
    gf.DisplayObjectContainer.call(this);

    this.addChild(this.gfx = new PIXI.Graphics());
    this.gfx.visible = false;

    this.done = true;
};

gf.inherits(gf.Camera.fx.Effect, gf.DisplayObjectContainer, {
    start: function() {
        this.done = false;
        return this;
    },
    stop: function() {
        this.done = true;
        return this;
    },
    update: function() {
        return this;
    },
    _complete: function() {
        this.done = true;

        if(typeof this.cb === 'function') {
            var ret = this.cb();

            if(ret !=== false)
                this.stop();
        } else {
            this.stop();
        }
    }
});<|endoftext|>


<commit_before>var WebSocketServer = require('websocket').server;
var http = require('http');
var fs = require('fs');

module.exports.listen = function () {

    var httpServer = http.createServer();
    httpServer.listen(process.env.PORT || 3000);

    var history = [{'senderId': 'Admin', 'text': 'Welcome to the Simple Chat!', 'type': 'message'}];
    var clients = [];

    var wsServer = new WebSocketServer({
        httpServer: httpServer
    });

    wsServer.on('request', function (request) {
        var connection = request.accept(null, request.origin);

        console.log((new Date()) + ' Connection accepted.');

        clients.push(connection);
        sendHistory(connection);

        connection.on('message', function (message) {
            if (message.type === 'utf8') {
                var data = JSON.parse(message.utf8Data);
                if (data['type'] == 'authentication') {
                    processAuthentication(connection, data)
                } else if (data['type'] == 'message') {
                    processMessage(data);
                    clients.forEach(function (client) {
                        sendMessage(client, data);
                        sendDebugReport(client);
                    });
                }
            }
        });

        connection.on('close', function (connection) {
            clients.splice(clients.indexOf(connection), 1);
            console.log((new Date()) + ' Connection closed.');
        });
    });

    function processAuthentication(client, data) {
        // clients.push(client);
        // console.log("+ authentication: " + client + ' + ' + data);
        // console.log("* clients: " + clients);
    }

    function processMessage(data) {
        history.push(data);
        console.log("< message: " + JSON.stringify(data));
    }

    function sendMessage(client, data) {
        client.sendUTF(JSON.stringify(data));
    }

    function sendDebugReport(client) {
        // var debugReport = {
        //     'type': 'message',
        //     'senderId': 'Server',
        //     'text': 'users: ' + clients.length + ', messages: ' + history.length
        // };
        // client.sendUTF(JSON.stringify(debugReport));
    }

    function sendHistory(client) {
        if (history.length > 0) {
            var container = {'type': 'history', 'messages': history};
            client.sendUTF(JSON.stringify(container));
        }
    }
};<commit_msg>Added fake messages generation<commit_after>var WebSocketServer = require('websocket').server;
var http = require('http');
var fs = require('fs');

module.exports.listen = function () {

    var httpServer = http.createServer();
    httpServer.listen(process.env.PORT || 3000);

    var history = [{'senderId': 'Simple Chat', 'text': 'Welcome to the Simple Chat!', 'type': 'message'}];
    var clients = [];

    var wsServer = new WebSocketServer({
        httpServer: httpServer
    });

    wsServer.on('request', function (request) {
        var connection = request.accept(null, request.origin);

        console.log((new Date()) + ' Connection accepted.');

        clients.push(connection);
        sendHistory(connection);

        connection.on('message', function (message) {
            if (message.type === 'utf8') {
                var data = JSON.parse(message.utf8Data);
                if (data['type'] == 'authentication') {
                    processAuthentication(connection, data)
                } else if (data['type'] == 'message') {
                    processMessage(connection, data);
                    clients.forEach(function (client) {
                        sendMessage(client, data);
                        sendDebugReport(client);
                    });
                }
            }
        });

        connection.on('close', function (connection) {
            clients.splice(clients.indexOf(connection), 1);
            console.log((new Date()) + ' Connection closed.');
        });
    });

    function processAuthentication(client, data) {
        // clients.push(client);
        // console.log("+ authentication: " + client + ' + ' + data);
        // console.log("* clients: " + clients);
    }

    function processMessage(connection, data) {
        if (data['text'].startsWith('--command')) {
            var command = data['text'];
            if (command === '--command-help') {
                console.log("< command help");
                sendMessage(connection, {'senderId': 'Simple Chat', 'text': 'There is no help here...', 'type': 'message'});

            } else if (command == '--command-lorem') {
                console.log("< command lorem (create fake messages)");
                createMessages()

            } else {
                console.log("< unknown command: " + JSON.stringify(data));
            }

        } else {
            history.push(data);
            console.log("< message: " + JSON.stringify(data));
        }
    }

    function createMessages() {
        var messages = [
            'Sed ut perspiciatis, unde omnis iste natus error sit voluptatem accusantium doloremque laudantium, totam rem aperiam eaque ipsa, quae ab illo inventore veritatis et quasi architecto beatae vitae dicta sunt, explicabo.',
            'Nemo enim ipsam voluptatem, quia voluptas sit, aspernatur aut odit aut fugit, sed quia consequuntur magni dolores eos, qui ratione voluptatem sequi nesciunt, neque porro quisquam est, qui dolorem ipsum, quia dolor sit, amet, consectetur, adipisci velit, sed quia non numquam eius modi tempora incidunt, ut labore et dolore magnam aliquam quaerat voluptatem.',
            'Ut enim ad minima veniam, quis nostrum exercitationem ullam corporis suscipit laboriosam, nisi ut aliquid ex ea commodi consequatur? Quis autem vel eum iure reprehenderit, qui in ea voluptate velit esse, quam nihil molestiae consequatur, vel illum, qui dolorem eum fugiat, quo voluptas nulla pariatur? At vero eos et accusamus et iusto odio dignissimos ducimus, qui blanditiis praesentium voluptatum deleniti atque corrupti, quos dolores et quas molestias excepturi sint, obcaecati cupiditate non provident, similique sunt in culpa, qui officia deserunt mollitia animi, id est laborum et dolorum fuga.',
            'Et harum quidem rerum facilis est et expedita distinctio.',
            'Nam libero tempore, cum soluta nobis est eligendi optio, cumque nihil impedit, quo minus id, quod maxime placeat, facere possimus, omnis voluptas assumenda est, omnis dolor repellendus.',
            'Temporibus autem quibusdam et aut officiis debitis aut rerum necessitatibus saepe eveniet, ut et voluptates repudiandae sint et molestiae non recusandae.',
            'Itaque earum rerum hic tenetur a sapiente delectus, ut aut reiciendis voluptatibus maiores alias consequatur aut perferendis doloribus asperiores repellat.'
        ]

        messages.forEach(function(message) {
            var data = {'senderId': 'Simple Chat', 'text': message, 'type': 'message'}
            processMessage(null, data)
            clients.forEach(function (client) {
                sendMessage(client, data);
            });
        })
    }

    function sendMessage(client, data) {
        client.sendUTF(JSON.stringify(data));
    }

    function sendDebugReport(client) {
        // var debugReport = {
        //     'type': 'message',
        //     'senderId': 'Server',
        //     'text': 'users: ' + clients.length + ', messages: ' + history.length
        // };
        // client.sendUTF(JSON.stringify(debugReport));
    }

    function sendHistory(client) {
        if (history.length > 0) {
            var container = {'type': 'history', 'messages': history};
            client.sendUTF(JSON.stringify(container));
        }
    }
};<|endoftext|>


<commit_before>function(sender, localization) {

	var canvasElement = null;
	var character = null;
	var animCurRow = 0;
	var animCurCell = 0;

	var backgroundName = 'background';
	var maxBackgrounds = 9;

	var backgrounds = [];

	//console.log(Lyria.Resource.name(sender + '/' + 'background', 'image'));

	//background.push();

	function onSceneActive() {
		// TODO: Timeout 'cuz Chrome is too faaast
		setTimeout(function() {
		// set character to the left of the scene
		var scenePos = $('#viewport').offset();
		$('.character:visible').offset({top : scenePos.top + 200, left : scenePos.left + 10});
		/*
		 * Move character to mouse click position
		 */
		var newCharPos = scenePos.left + 10;
		var interval;
		$('#viewport').live('click', function(event) {
			if (interval) {
				window.canvasEngine.loop.removeTask(interval);
			}
			newCharPos = event.pageX;
			interval = window.canvasEngine.loop.addTask(function moveChar(loop) {

				var delta = loop.timeElapsed;

				var charCurPosX = $('.character:visible').offset().left;
				if (charCurPosX > (newCharPos+10)) {
					$('.character:visible').offset({left : charCurPosX - .5 * delta});
				} else if (charCurPosX < (newCharPos-10)) {
					$('.character:visible').offset({left : charCurPosX + .5 * delta});
				} else {
					window.canvasEngine.loop.removeTask(interval);
				}

			}, 33);

		});
		}, 100);

	    var StarAnimation = new Scene_Asset_Animation(1, 5);
	    StarAnimation.load(Lyria.Resource.name('star1.png', 'image'), function(StarAnimation) {
	    	for(var i = 0; i < 10; i++) {
	        	var obj = new Game_Star(StarAnimation);
	        	obj.position.x = 800*Math.random();
	        	obj.position.y = 100*Math.random() + 10;
	        	window.canvasEngine.sceneGraph.add(obj);
	        }
	    });

	    var FireflyAnimation = new Scene_Asset_Animation(1, 6);
	    FireflyAnimation.load(Lyria.Resource.name('firefly.png', 'image'), function(FireflyAnimation) {
	    	for(var i = 0; i < 10; i++) {
	        	var obj = new Game_Firefly(FireflyAnimation);
	        	window.canvasEngine.sceneGraph.add(obj);
	        }
	    });
	}

	function update(dt) {
		//$('.bird').css('margin-left', $('#' + sender + ' .panorama-container').css('margin-left'));

		if (canvasElement) {
			canvasElement.clearRect(0, 0, 20, 30);
			canvasElement.drawImage(bird, animCurCell * (-20), animCurRow * (-30));
		}

		animCurCell++;
		if (animCurCell > 5) {
			animCurCell = 0;
			animCurRow++;
		}

		if (animCurRow > 3) {
			animCurRow = 0;
			animCurCell = 0;
		}
	}

	for (var i = 0; i < maxBackgrounds; i++) {
		backgrounds.push({
			filename: Lyria.Resource.name([sender, backgroundName + i + '.png'].join('/'), 'image')
		});
	}

	var angle = 0;

	function update(dt) {
		angle++;
		if (angle == 360) {
			angle = 0;
		}

		$('.pinwheel').rotate(angle);
	}

	return {
		backgrounds: backgrounds,
		update: update,
		onSceneActive: onSceneActive
	}
}
<commit_msg>Updated animation for pinwheels<commit_after>function(sender, localization) {

	var canvasElement = null;
	var character = null;
	var animCurRow = 0;
	var animCurCell = 0;

	var backgroundName = 'background';
	var maxBackgrounds = 9;

	var backgrounds = [];

	//console.log(Lyria.Resource.name(sender + '/' + 'background', 'image'));

	//background.push();

	function onSceneActive() {
		// TODO: Timeout 'cuz Chrome is too faaast
		setTimeout(function() {
		// set character to the left of the scene
		var scenePos = $('#viewport').offset();
		$('.character:visible').offset({top : scenePos.top + 200, left : scenePos.left + 10});
		/*
		 * Move character to mouse click position
		 */
		var newCharPos = scenePos.left + 10;
		var interval;
		$('#viewport').live('click', function(event) {
			if (interval) {
				window.canvasEngine.loop.removeTask(interval);
			}
			newCharPos = event.pageX;
			interval = window.canvasEngine.loop.addTask(function moveChar(loop) {

				var delta = loop.timeElapsed;

				var charCurPosX = $('.character:visible').offset().left;
				if (charCurPosX > (newCharPos+10)) {
					$('.character:visible').offset({left : charCurPosX - .5 * delta});
				} else if (charCurPosX < (newCharPos-10)) {
					$('.character:visible').offset({left : charCurPosX + .5 * delta});
				} else {
					window.canvasEngine.loop.removeTask(interval);
				}

			}, 33);

		});
		}, 100);

	    var StarAnimation = new Scene_Asset_Animation(1, 5);
	    StarAnimation.load(Lyria.Resource.name('star1.png', 'image'), function(StarAnimation) {
	    	for(var i = 0; i < 10; i++) {
	        	var obj = new Game_Star(StarAnimation);
	        	obj.position.x = 800*Math.random();
	        	obj.position.y = 100*Math.random() + 10;
	        	window.canvasEngine.sceneGraph.add(obj);
	        }
	    });

	    var FireflyAnimation = new Scene_Asset_Animation(1, 6);
	    FireflyAnimation.load(Lyria.Resource.name('firefly.png', 'image'), function(FireflyAnimation) {
	    	for(var i = 0; i < 10; i++) {
	        	var obj = new Game_Firefly(FireflyAnimation);
	        	window.canvasEngine.sceneGraph.add(obj);
	        }
	    });
	}

	function update(dt) {
		//$('.bird').css('margin-left', $('#' + sender + ' .panorama-container').css('margin-left'));

		if (canvasElement) {
			canvasElement.clearRect(0, 0, 20, 30);
			canvasElement.drawImage(bird, animCurCell * (-20), animCurRow * (-30));
		}

		animCurCell++;
		if (animCurCell > 5) {
			animCurCell = 0;
			animCurRow++;
		}

		if (animCurRow > 3) {
			animCurRow = 0;
			animCurCell = 0;
		}
	}

	for (var i = 0; i < maxBackgrounds; i++) {
		backgrounds.push({
			filename: Lyria.Resource.name([sender, backgroundName + i + '.png'].join('/'), 'image')
		});
	}

	var angle = angle2 = angle3 = 0;

	function update(dt) {
		angle++;
		if (angle == 360.0) {
			angle = 0;
		}

		angle2 = angle2 + 0.5;
		if (angle2 == 360.0) {
			angle2 = 0;
		}

		angle3 = angle3 + 0.25;
		if (angle3 == 360.0) {
			angle3 = 0;
		}

		$('.pinwheel.small').rotate(angle);
		$('.pinwheel.medium').rotate(angle2);
		$('.pinwheel.big').rotate(angle3);
	}

	return {
		backgrounds: backgrounds,
		update: update,
		onSceneActive: onSceneActive
	}
}
<|endoftext|>


<commit_before>// @flow
import * as React from 'react'
import * as c from '@frogpond/colors'
import {Platform, StyleSheet, TextInput, View} from 'react-native'
import {Toolbar} from '@frogpond/toolbar'
import {fetch} from '@frogpond/fetch'
import {API} from '@frogpond/api'
import glamorous from 'glamorous-native'
import {iOSUIKit, material} from 'react-native-typography'
import type {NavigationScreenProp} from 'react-navigation'

const styles = StyleSheet.create({
	container: {
		backgroundColor: c.white,
		flex: 1,
	},
	default: {
		height: 44,
		borderBottomWidth: StyleSheet.hairlineWidth,
		borderColor: c.black,
		flex: 1,
		fontSize: 13,
		paddingVertical: 4,
		paddingHorizontal: 8,
	},
	data: {
		padding: 10,
	},
	error: {
		padding: 10,
		color: c.brickRed,
	},
})

export const Paragraph = glamorous(TextInput)({
	marginVertical: 3,
	paddingRight: 4,
	...Platform.select({
		ios: iOSUIKit.bodyObject,
		android: material.body1Object,
	}),
})

type Props = {
	navigation: NavigationScreenProp<*>,
}

type State = {
	results: string,
	error: string,
}

export class APITestView extends React.PureComponent<Props, State> {
	static navigationOptions = {
		title: 'API Tester',
	}

	state = {
		results: '',
		error: '',
	}

	fetchData = async (path: string) => {
		try {
			let responseData: string = await fetch(API(path), {
				cache: 'no-store',
			}).text()
			this.setState(() => ({results: responseData, error: ''}))
		} catch (err) {
			this.setState(() => ({results: '', error: JSON.stringify(err)}))
		}
	}

	render() {
		let {error, results} = this.state
		return (
			<>
				<Toolbar onPress={() => {}}>
					<TextInput
						autoCapitalize="none"
						autoCorrect={false}
						keyboardType="web-search"
						onEndEditing={e => this.fetchData(e.nativeEvent.text)}
						placeholder="path/to/resource"
						returnKeyType="done"
						style={styles.default}
					/>
				</Toolbar>
				<View style={styles.container}>
					{error ? (
						<Paragraph editable={false} multiline={true} style={styles.error}>
							{error}
						</Paragraph>
					) : null}
					{results ? (
						<Paragraph editable={false} multiline={true} style={styles.data}>
							{results}
						</Paragraph>
					) : null}
				</View>
			</>
		)
	}
}
<commit_msg>follow the example of the hint text and add the slash for the user<commit_after>// @flow
import * as React from 'react'
import * as c from '@frogpond/colors'
import {Platform, StyleSheet, TextInput, View} from 'react-native'
import {Toolbar} from '@frogpond/toolbar'
import {fetch} from '@frogpond/fetch'
import {API} from '@frogpond/api'
import glamorous from 'glamorous-native'
import {iOSUIKit, material} from 'react-native-typography'
import type {NavigationScreenProp} from 'react-navigation'

const styles = StyleSheet.create({
	container: {
		backgroundColor: c.white,
		flex: 1,
	},
	default: {
		height: 44,
		borderBottomWidth: StyleSheet.hairlineWidth,
		borderColor: c.black,
		flex: 1,
		fontSize: 13,
		paddingVertical: 4,
		paddingHorizontal: 8,
	},
	data: {
		padding: 10,
	},
	error: {
		padding: 10,
		color: c.brickRed,
	},
})

export const Paragraph = glamorous(TextInput)({
	marginVertical: 3,
	paddingRight: 4,
	...Platform.select({
		ios: iOSUIKit.bodyObject,
		android: material.body1Object,
	}),
})

type Props = {
	navigation: NavigationScreenProp<*>,
}

type State = {
	results: string,
	error: string,
}

export class APITestView extends React.PureComponent<Props, State> {
	static navigationOptions = {
		title: 'API Tester',
	}

	state = {
		results: '',
		error: '',
	}

	fetchData = async (path: string) => {
		try {
			let responseData: string = await fetch(API(`/${path}`), {
				cache: 'no-store',
			}).text()
			this.setState(() => ({results: responseData, error: ''}))
		} catch (err) {
			this.setState(() => ({results: '', error: JSON.stringify(err)}))
		}
	}

	render() {
		let {error, results} = this.state
		return (
			<>
				<Toolbar onPress={() => {}}>
					<TextInput
						autoCapitalize="none"
						autoCorrect={false}
						keyboardType="web-search"
						onEndEditing={e => this.fetchData(e.nativeEvent.text)}
						placeholder="path/to/resource"
						returnKeyType="done"
						style={styles.default}
					/>
				</Toolbar>
				<View style={styles.container}>
					{error ? (
						<Paragraph editable={false} multiline={true} style={styles.error}>
							{error}
						</Paragraph>
					) : null}
					{results ? (
						<Paragraph editable={false} multiline={true} style={styles.data}>
							{results}
						</Paragraph>
					) : null}
				</View>
			</>
		)
	}
}
<|endoftext|>


<commit_before>"use strict";

var f = require('util').format
  , MongoError = require('../error');

// Filters for classes
var classFilters = {};
var filteredClasses = {};
var level = null;
// Save the process id
var pid = process.pid;
// current logger
var currentLogger = null;

/**
 * Creates a new Logger instance
 * @class
 * @param {string} className The Class name associated with the logging instance
 * @param {object} [options=null] Optional settings.
 * @param {Function} [options.logger=null] Custom logger function;
 * @param {string} [options.loggerLevel=error] Override default global log level.
 * @return {Logger} a Logger instance.
 */
var Logger = function(className, options) {
  if(!(this instanceof Logger)) return new Logger(className, options);
  options = options || {};

  // Current reference
  var self = this;
  this.className = className;

  // Current logger
  if(options.logger) {
    currentLogger = options.logger;
  } else if(currentLogger == null) {
    currentLogger = console.log;
  }

  // Set level of logging, default is error
  if(options.loggerLevel) {
    level = options.loggerLevel || 'error';
  }

  // Add all class names
  if(filteredClasses[this.className] == null) classFilters[this.className] =  true;
}

/**
 * Log a message at the debug level
 * @method
 * @param {string} message The message to log
 * @param {object} object additional meta data to log
 * @return {null}
 */
Logger.prototype.debug = function(message, object) {
  if(this.isDebug()
    && ((Object.keys(filteredClasses).length > 0 && filteredClasses[this.className])
      || (Object.keys(filteredClasses).length == 0 && classFilters[this.className]))) {
    var dateTime = new Date().getTime();
    var msg = f("[%s-%s:%s] %s %s", 'DEBUG', this.className, pid, dateTime, message);
    var state = {
      type: 'debug', message: message, className: this.className, pid: pid, date: dateTime
    };
    if(object) state.meta = object;
    currentLogger(msg, state);
  }
}

/**
 * Log a message at the warn level
 * @method
 * @param {string} message The message to log
 * @param {object} object additional meta data to log
 * @return {null}
 */
Logger.prototype.warn = function(message, object) {
  if(this.isWarn()
    && ((Object.keys(filteredClasses).length > 0 && filteredClasses[this.className])
      || (Object.keys(filteredClasses).length == 0 && classFilters[this.className]))) {
    var dateTime = new Date().getTime();
    var msg = f("[%s-%s:%s] %s %s", 'WARN', this.className, pid, dateTime, message);
    var state = {
      type: 'info', message: message, className: this.className, pid: pid, date: dateTime
    };
    if(object) state.meta = object;
    currentLogger(msg, state);
  }
},

/**
 * Log a message at the info level
 * @method
 * @param {string} message The message to log
 * @param {object} object additional meta data to log
 * @return {null}
 */
Logger.prototype.info = function(message, object) {
  if(this.isInfo()
    && ((Object.keys(filteredClasses).length > 0 && filteredClasses[this.className])
      || (Object.keys(filteredClasses).length == 0 && classFilters[this.className]))) {
    var dateTime = new Date().getTime();
    var msg = f("[%s-%s:%s] %s %s", 'INFO', this.className, pid, dateTime, message);
    var state = {
      type: 'info', message: message, className: this.className, pid: pid, date: dateTime
    };
    if(object) state.meta = object;
    currentLogger(msg, state);
  }
},

/**
 * Log a message at the error level
 * @method
 * @param {string} message The message to log
 * @param {object} object additional meta data to log
 * @return {null}
 */
Logger.prototype.error = function(message, object) {
  if(this.isError()
    && ((Object.keys(filteredClasses).length > 0 && filteredClasses[this.className])
      || (Object.keys(filteredClasses).length == 0 && classFilters[this.className]))) {
    var dateTime = new Date().getTime();
    var msg = f("[%s-%s:%s] %s %s", 'ERROR', this.className, pid, dateTime, message);
    var state = {
      type: 'error', message: message, className: this.className, pid: pid, date: dateTime
    };
    if(object) state.meta = object;
    currentLogger(msg, state);
  }
},

/**
 * Is the logger set at info level
 * @method
 * @return {boolean}
 */
Logger.prototype.isInfo = function() {
  return level == 'info' || level == 'debug';
},

/**
 * Is the logger set at error level
 * @method
 * @return {boolean}
 */
Logger.prototype.isError = function() {
  return level == 'error' || level == 'info' || level == 'debug';
},

/**
 * Is the logger set at error level
 * @method
 * @return {boolean}
 */
Logger.prototype.isWarn = function() {
  return level == 'error' || level == 'warn' || level == 'info' || level == 'debug';
},

/**
 * Is the logger set at debug level
 * @method
 * @return {boolean}
 */
Logger.prototype.isDebug = function() {
  return level == 'debug';
}

/**
 * Resets the logger to default settings, error and no filtered classes
 * @method
 * @return {null}
 */
Logger.reset = function() {
  level = 'error';
  filteredClasses = {};
}

/**
 * Get the current logger function
 * @method
 * @return {function}
 */
Logger.currentLogger = function() {
  return currentLogger;
}

/**
 * Set the current logger function
 * @method
 * @param {function} logger Logger function.
 * @return {null}
 */
Logger.setCurrentLogger = function(logger) {
  if(typeof logger != 'function') throw new MongoError("current logger must be a function");
  currentLogger = logger;
}

/**
 * Set what classes to log.
 * @method
 * @param {string} type The type of filter (currently only class)
 * @param {string[]} values The filters to apply
 * @return {null}
 */
Logger.filter = function(type, values) {
  if(type == 'class' && Array.isArray(values)) {
    filteredClasses = {};

    values.forEach(function(x) {
      filteredClasses[x] = true;
    });
  }
}

/**
 * Set the current log level
 * @method
 * @param {string} level Set current log level (debug, info, error)
 * @return {null}
 */
Logger.setLevel = function(_level) {
  if(_level != 'info' && _level != 'error' && _level != 'debug' && _level != 'warn') {
    throw new Error(f("%s is an illegal logging level", _level));
  }

  level = _level;
}

module.exports = Logger;
<commit_msg>fixed logging warn level tag to warn<commit_after>"use strict";

var f = require('util').format
  , MongoError = require('../error');

// Filters for classes
var classFilters = {};
var filteredClasses = {};
var level = null;
// Save the process id
var pid = process.pid;
// current logger
var currentLogger = null;

/**
 * Creates a new Logger instance
 * @class
 * @param {string} className The Class name associated with the logging instance
 * @param {object} [options=null] Optional settings.
 * @param {Function} [options.logger=null] Custom logger function;
 * @param {string} [options.loggerLevel=error] Override default global log level.
 * @return {Logger} a Logger instance.
 */
var Logger = function(className, options) {
  if(!(this instanceof Logger)) return new Logger(className, options);
  options = options || {};

  // Current reference
  var self = this;
  this.className = className;

  // Current logger
  if(options.logger) {
    currentLogger = options.logger;
  } else if(currentLogger == null) {
    currentLogger = console.log;
  }

  // Set level of logging, default is error
  if(options.loggerLevel) {
    level = options.loggerLevel || 'error';
  }

  // Add all class names
  if(filteredClasses[this.className] == null) classFilters[this.className] =  true;
}

/**
 * Log a message at the debug level
 * @method
 * @param {string} message The message to log
 * @param {object} object additional meta data to log
 * @return {null}
 */
Logger.prototype.debug = function(message, object) {
  if(this.isDebug()
    && ((Object.keys(filteredClasses).length > 0 && filteredClasses[this.className])
      || (Object.keys(filteredClasses).length == 0 && classFilters[this.className]))) {
    var dateTime = new Date().getTime();
    var msg = f("[%s-%s:%s] %s %s", 'DEBUG', this.className, pid, dateTime, message);
    var state = {
      type: 'debug', message: message, className: this.className, pid: pid, date: dateTime
    };
    if(object) state.meta = object;
    currentLogger(msg, state);
  }
}

/**
 * Log a message at the warn level
 * @method
 * @param {string} message The message to log
 * @param {object} object additional meta data to log
 * @return {null}
 */
Logger.prototype.warn = function(message, object) {
  if(this.isWarn()
    && ((Object.keys(filteredClasses).length > 0 && filteredClasses[this.className])
      || (Object.keys(filteredClasses).length == 0 && classFilters[this.className]))) {
    var dateTime = new Date().getTime();
    var msg = f("[%s-%s:%s] %s %s", 'WARN', this.className, pid, dateTime, message);
    var state = {
      type: 'warn', message: message, className: this.className, pid: pid, date: dateTime
    };
    if(object) state.meta = object;
    currentLogger(msg, state);
  }
},

/**
 * Log a message at the info level
 * @method
 * @param {string} message The message to log
 * @param {object} object additional meta data to log
 * @return {null}
 */
Logger.prototype.info = function(message, object) {
  if(this.isInfo()
    && ((Object.keys(filteredClasses).length > 0 && filteredClasses[this.className])
      || (Object.keys(filteredClasses).length == 0 && classFilters[this.className]))) {
    var dateTime = new Date().getTime();
    var msg = f("[%s-%s:%s] %s %s", 'INFO', this.className, pid, dateTime, message);
    var state = {
      type: 'info', message: message, className: this.className, pid: pid, date: dateTime
    };
    if(object) state.meta = object;
    currentLogger(msg, state);
  }
},

/**
 * Log a message at the error level
 * @method
 * @param {string} message The message to log
 * @param {object} object additional meta data to log
 * @return {null}
 */
Logger.prototype.error = function(message, object) {
  if(this.isError()
    && ((Object.keys(filteredClasses).length > 0 && filteredClasses[this.className])
      || (Object.keys(filteredClasses).length == 0 && classFilters[this.className]))) {
    var dateTime = new Date().getTime();
    var msg = f("[%s-%s:%s] %s %s", 'ERROR', this.className, pid, dateTime, message);
    var state = {
      type: 'error', message: message, className: this.className, pid: pid, date: dateTime
    };
    if(object) state.meta = object;
    currentLogger(msg, state);
  }
},

/**
 * Is the logger set at info level
 * @method
 * @return {boolean}
 */
Logger.prototype.isInfo = function() {
  return level == 'info' || level == 'debug';
},

/**
 * Is the logger set at error level
 * @method
 * @return {boolean}
 */
Logger.prototype.isError = function() {
  return level == 'error' || level == 'info' || level == 'debug';
},

/**
 * Is the logger set at error level
 * @method
 * @return {boolean}
 */
Logger.prototype.isWarn = function() {
  return level == 'error' || level == 'warn' || level == 'info' || level == 'debug';
},

/**
 * Is the logger set at debug level
 * @method
 * @return {boolean}
 */
Logger.prototype.isDebug = function() {
  return level == 'debug';
}

/**
 * Resets the logger to default settings, error and no filtered classes
 * @method
 * @return {null}
 */
Logger.reset = function() {
  level = 'error';
  filteredClasses = {};
}

/**
 * Get the current logger function
 * @method
 * @return {function}
 */
Logger.currentLogger = function() {
  return currentLogger;
}

/**
 * Set the current logger function
 * @method
 * @param {function} logger Logger function.
 * @return {null}
 */
Logger.setCurrentLogger = function(logger) {
  if(typeof logger != 'function') throw new MongoError("current logger must be a function");
  currentLogger = logger;
}

/**
 * Set what classes to log.
 * @method
 * @param {string} type The type of filter (currently only class)
 * @param {string[]} values The filters to apply
 * @return {null}
 */
Logger.filter = function(type, values) {
  if(type == 'class' && Array.isArray(values)) {
    filteredClasses = {};

    values.forEach(function(x) {
      filteredClasses[x] = true;
    });
  }
}

/**
 * Set the current log level
 * @method
 * @param {string} level Set current log level (debug, info, error)
 * @return {null}
 */
Logger.setLevel = function(_level) {
  if(_level != 'info' && _level != 'error' && _level != 'debug' && _level != 'warn') {
    throw new Error(f("%s is an illegal logging level", _level));
  }

  level = _level;
}

module.exports = Logger;
<|endoftext|>


<commit_before>'use strict'
var helper = require('./test-helper')
const pg = helper.pg

// first make pool hold 2 clients
pg.defaults.poolSize = 2

const pool = new pg.Pool()

const suite = new helper.Suite()
suite.test('connecting to invalid port', (cb) => {
  const pool = new pg.Pool({ port: 13801 })
  pool.connect().catch(e => cb())
})

suite.test('errors emitted on pool', (cb) => {
  // get first client
  pool.connect(assert.success(function (client, done) {
    client.id = 1
    client.query('SELECT NOW()', function () {
      pool.connect(assert.success(function (client2, done2) {
        client2.id = 2
        var pidColName = 'procpid'
        helper.versionGTE(client2, 90200, assert.success(function (isGreater) {
          var killIdleQuery = 'SELECT pid, (SELECT pg_terminate_backend(pid)) AS killed FROM pg_stat_activity WHERE state = $1'
          var params = ['idle']
          if (!isGreater) {
            killIdleQuery = 'SELECT procpid, (SELECT pg_terminate_backend(procpid)) AS killed FROM pg_stat_activity WHERE current_query LIKE $1'
            params = ['%IDLE%']
          }

          pool.once('error', (err, brokenClient) => {
            assert.ok(err)
            assert.ok(brokenClient)
            assert.equal(client.id, brokenClient.id)
            cb()
          })

          // kill the connection from client
          client2.query(killIdleQuery, params, assert.success(function (res) {
            // check to make sure client connection actually was killed
            // return client2 to the pool
            done2()
            pool.end()
          }))
        }))
      }))
    })
  }))
})
<commit_msg>Replace poolSize by max in error test<commit_after>'use strict'
var helper = require('./test-helper')
const pg = helper.pg

// first make pool hold 2 clients
pg.defaults.max = 2

const pool = new pg.Pool()

const suite = new helper.Suite()
suite.test('connecting to invalid port', (cb) => {
  const pool = new pg.Pool({ port: 13801 })
  pool.connect().catch(e => cb())
})

suite.test('errors emitted on pool', (cb) => {
  // get first client
  pool.connect(assert.success(function (client, done) {
    client.id = 1
    client.query('SELECT NOW()', function () {
      pool.connect(assert.success(function (client2, done2) {
        client2.id = 2
        var pidColName = 'procpid'
        helper.versionGTE(client2, 90200, assert.success(function (isGreater) {
          var killIdleQuery = 'SELECT pid, (SELECT pg_terminate_backend(pid)) AS killed FROM pg_stat_activity WHERE state = $1'
          var params = ['idle']
          if (!isGreater) {
            killIdleQuery = 'SELECT procpid, (SELECT pg_terminate_backend(procpid)) AS killed FROM pg_stat_activity WHERE current_query LIKE $1'
            params = ['%IDLE%']
          }

          pool.once('error', (err, brokenClient) => {
            assert.ok(err)
            assert.ok(brokenClient)
            assert.equal(client.id, brokenClient.id)
            cb()
          })

          // kill the connection from client
          client2.query(killIdleQuery, params, assert.success(function (res) {
            // check to make sure client connection actually was killed
            // return client2 to the pool
            done2()
            pool.end()
          }))
        }))
      }))
    })
  }))
})
<|endoftext|>