<commit_before>const merge = require('webpack-merge');
const common = require('./webpack.common.js');

const CleanWebpackPlugin = require('clean-webpack-plugin');
const UglifyJsPlugin = require('uglifyjs-webpack-plugin');

module.exports = merge(common, {
  mode: 'production',
  devtool: "source-map",
  optimization: {
    minimizer: [
      new UglifyJsPlugin({
        sourceMap: true,
        uglifyOptions: {
          output: {
            comments: false,
          }
        },
      })
    ]
  },
  plugins: [
    new CleanWebpackPlugin('dist')
  ]
});<commit_msg>Style. Beautify code<commit_after>const merge = require('webpack-merge');
const common = require('./webpack.common.js');

const CleanWebpackPlugin = require('clean-webpack-plugin');
const UglifyJsPlugin = require('uglifyjs-webpack-plugin');

module.exports = merge(common, {
  mode: 'production',
  devtool: 'source-map',
  optimization: {
    minimizer: [
      new UglifyJsPlugin({
        sourceMap: true,
        uglifyOptions: {
          output: { comments: false }
        },
      })
    ]
  },
  plugins: [
    new CleanWebpackPlugin('dist')
  ]
});<|endoftext|>


<commit_before>import React from 'react';

const PatreonLink = ({ ...others }) => (
  <a
    className="become-patron-button"
    role="button"
    href="https://www.patreon.com/wowanalyzer"
    data-tip="Please note this Patreon is only for the core WoW Analyzer, and the specs being maintained by me (Holy Paladin and Disc Priest at the time of writing). The other specs are being developed by other people on top of the core I built, please contact them if you would prefer supporting them specifically. There is currently no distribution of donations in place, and due to the complex nature of this there are currently no plans to do this either. It sucks and I'm sorry."
    {...others}
  >

      <svg viewBox="0 0 8 8" width="12px" height="12px" fill="#fff"><path d="M2.32061871,0.367894189 C3.18961652,-0.0376047918 4.20711396,-0.109604611 5.12711165,0.16039471 C5.93360962,0.39539412 6.6591078,0.894392865 7.17010651,1.55889119 C7.67510524,2.21138955 7.96860451,3.02288751 7.99660444,3.84638544 C8.03210435,4.6978833 7.78560497,5.55788114 7.30110618,6.25987938 C6.59110797,7.31187673 5.35311108,7.98687503 4.07861429,7.999375 C3.44061589,8.000375 2.80261749,7.999875 2.1651191,7.999375 C2.17011908,6.65887837 2.1656191,5.31838174 2.16811909,3.97788511 C2.17011908,3.47138639 2.39811851,2.97288764 2.77711756,2.63638849 C3.13911665,2.30838931 3.6371154,2.13588974 4.12461417,2.17238965 C4.6291129,2.20338957 5.11311169,2.45838893 5.42761089,2.85238794 C5.75061008,3.24938694 5.89160973,3.7853856 5.80860994,4.29038433 C5.72761014,4.82138299 5.39511098,5.30638177 4.93061214,5.57838109 C4.39361349,5.90388027 3.69011526,5.91288025 3.13711665,5.61888099 C3.13761665,6.05337989 3.13661665,6.4883788 3.13761665,6.92337771 C3.63111541,7.06737734 4.15961408,7.09187728 4.66161282,6.97737757 C5.40461095,6.81487798 6.07610926,6.35987912 6.50610818,5.73538069 C6.91610715,5.14988217 7.10560668,4.41738401 7.03460685,3.70738579 C6.97460701,3.05588743 6.69410771,2.42788901 6.25160882,1.94539022 C5.84160985,1.49439136 5.29311123,1.16939217 4.69811273,1.03189252 C4.01411445,0.869392928 3.27411631,0.952892718 2.64611789,1.26789193 C1.6451204,1.7543907 0.962622121,2.82088802 0.952122147,3.93238523 C0.950122152,5.28788182 0.951622148,6.64337841 0.95112215,7.999375 C0.634622945,8.000375 0.317623743,7.999875 0.000124540763,7.999875 C0.000124540763,6.67387833 0.000624539506,5.34838167 0.000124540763,4.022885 C-0.00437544792,3.45688642 0.113124257,2.89038785 0.344123676,2.37338915 C0.7321227,1.49639135 1.4476209,0.769393179 2.32061871,0.367894189" /></svg>

    {' '}Become a patron

);

export default PatreonLink;
<commit_msg>Reworded Patreon link<commit_after>import React from 'react';

const PatreonLink = ({ ...others }) => (

      <svg viewBox="0 0 8 8" width="12px" height="12px" fill="#fff"><path d="M2.32061871,0.367894189 C3.18961652,-0.0376047918 4.20711396,-0.109604611 5.12711165,0.16039471 C5.93360962,0.39539412 6.6591078,0.894392865 7.17010651,1.55889119 C7.67510524,2.21138955 7.96860451,3.02288751 7.99660444,3.84638544 C8.03210435,4.6978833 7.78560497,5.55788114 7.30110618,6.25987938 C6.59110797,7.31187673 5.35311108,7.98687503 4.07861429,7.999375 C3.44061589,8.000375 2.80261749,7.999875 2.1651191,7.999375 C2.17011908,6.65887837 2.1656191,5.31838174 2.16811909,3.97788511 C2.17011908,3.47138639 2.39811851,2.97288764 2.77711756,2.63638849 C3.13911665,2.30838931 3.6371154,2.13588974 4.12461417,2.17238965 C4.6291129,2.20338957 5.11311169,2.45838893 5.42761089,2.85238794 C5.75061008,3.24938694 5.89160973,3.7853856 5.80860994,4.29038433 C5.72761014,4.82138299 5.39511098,5.30638177 4.93061214,5.57838109 C4.39361349,5.90388027 3.69011526,5.91288025 3.13711665,5.61888099 C3.13761665,6.05337989 3.13661665,6.4883788 3.13761665,6.92337771 C3.63111541,7.06737734 4.15961408,7.09187728 4.66161282,6.97737757 C5.40461095,6.81487798 6.07610926,6.35987912 6.50610818,5.73538069 C6.91610715,5.14988217 7.10560668,4.41738401 7.03460685,3.70738579 C6.97460701,3.05588743 6.69410771,2.42788901 6.25160882,1.94539022 C5.84160985,1.49439136 5.29311123,1.16939217 4.69811273,1.03189252 C4.01411445,0.869392928 3.27411631,0.952892718 2.64611789,1.26789193 C1.6451204,1.7543907 0.962622121,2.82088802 0.952122147,3.93238523 C0.950122152,5.28788182 0.951622148,6.64337841 0.95112215,7.999375 C0.634622945,8.000375 0.317623743,7.999875 0.000124540763,7.999875 C0.000124540763,6.67387833 0.000624539506,5.34838167 0.000124540763,4.022885 C-0.00437544792,3.45688642 0.113124257,2.89038785 0.344123676,2.37338915 C0.7321227,1.49639135 1.4476209,0.769393179 2.32061871,0.367894189" /></svg>

    {' '}Become a patron

);

export default PatreonLink;
<|endoftext|>


<commit_before>(function(jQuery, undefined) {
    jQuery.widget('Midgard.midgardStorage', {
        options: {
            localStorage: false,
            vie: null,
            changedModels: [],
            loaded: function() {},
            url: ''
        },

        _create: function() {
            var widget = this;

            if (Modernizr.localstorage) {
                this.options.localStorage = true;
            }

            this.vie = this.options.vie;

            this.vie.entities.bind('add', function(model) {
                // Add the back-end URL used by Backbone.sync
                model.url = widget.options.url;
                model.toJSON = model.toJSONLD;
            });

            jQuery('#midgardcreate-save').click(function() {
                widget._saveRemote({
                    success: function() {
                        jQuery('#midgardcreate-save').button({disabled: true});
                    },
                    error: function() {
                        console.log("Save failed");
                    }
                });
            });

            widget._bindEditables();
        },

        _bindEditables: function() {
            var widget = this;

            widget.element.bind('midgardeditablechanged', function(event, options) {
                if (_.indexOf(widget.options.changedModels, options.instance) === -1) {
                    widget.options.changedModels.push(options.instance);
                }
                widget._saveLocal(options.instance);
                jQuery('#midgardcreate-save').button({disabled: false});
            });

            widget.element.bind('midgardeditabledisable', function(event, options) {
                widget._restoreLocal(options.instance);
                jQuery('#midgardcreate-save').button({disabled: true});
            });

            widget.element.bind('midgardeditableenable', function(event, options) {
                widget._readLocal(options.instance);
                _.each(options.instance.attributes, function(attributeValue, property) {
                    if (attributeValue instanceof widget.vie.Collection) {
                        //widget._readLocalReferences(options.instance, property, attributeValue);
                    }
                });
            });

            widget.element.bind('midgardstorageloaded', function(event, options) {
                if (_.indexOf(widget.options.changedModels, options.instance) === -1) {
                    widget.options.changedModels.push(options.instance);
                }
                jQuery('#midgardcreate-save').button({disabled: false});
            });
        },

        _saveRemote: function(options) {
            var widget = this;
            var needed = widget.options.changedModels.length;
            _.forEach(widget.options.changedModels, function(model, index) {
                model.save(null, {
                    success: function() {
                        if (model.originalAttributes) {
                            // From now on we're going with the values we have on server
                            delete model.originalAttributes;
                        }
                        widget._removeLocal(model);
                        delete widget.options.changedModels[index];
                        needed--;
                        if (needed <= 0) {
                            // All models were happily saved
                            options.success();
                        }
                    },
                    error: function() {
                        options.error();
                    }
                });
            });
        },

        _saveLocal: function(model) {
            if (!this.options.localStorage) {
                return;
            }

            if (typeof model.id === 'object') {
                // Anonymous object, save as refs instead
                if (!model.primaryCollection) {
                    return;
                }
                return this._saveLocalReferences(model.primaryCollection.subject, model.primaryCollection.predicate, model);
            }
            localStorage.setItem(model.getSubject(), JSON.stringify(model.toJSONLD()));
        },

        _getReferenceId: function(model, property) {
            return model.id + ':' + property;
        },

        _saveLocalReferences: function(subject, predicate, model) {
            if (!this.options.localStorage) {
                return;
            }

            if (!subject ||
                !predicate) {
                return;
            }

            var widget = this;
            var identifier = subject + ':' + predicate;
            var json = model.toJSONLD();
            if (localStorage.getItem(identifier)) {
                var referenceList = JSON.parse(localStorage.getItem(identifier));
                var index = _.pluck(referenceList, '@').indexOf(json['@']);
                if (index !== -1) {
                    referenceList[index] = json;
                } else {
                    referenceList.push(json);
                }
                localStorage.setItem(identifier, JSON.stringify(referenceList));
                return;
            }
            localStorage.setItem(identifier, JSON.stringify([json]));
        },

        _readLocal: function(model) {
            if (!this.options.localStorage) {
                return;
            }

            var local = localStorage.getItem(model.getSubject());
            if (!local) {
                return;
            }
            model.originalAttributes = _.clone(model.attributes);
            var entity = this.vie.EntityManager.getByJSONLD(JSON.parse(local));

            this._trigger('loaded', null, {
                instance: entity
            });
        },

        _readLocalReferences: function(model, property, collection) {
            if (!this.options.localStorage) {
                return;
            }

            var identifier = this._getReferenceId(model, property);
            var local = localStorage.getItem(identifier);
            if (!local) {
                return;
            }
            collection.add(JSON.parse(local));
        },

        _restoreLocal: function(model) {
            var widget = this;
            // Remove unsaved collection members
            _.each(model.attributes, function(attributeValue, property) {
                if (attributeValue instanceof widget.vie.Collection) {
                    attributeValue.forEach(function(model) {
                        if (typeof model.id === 'object') {
                            attributeValue.remove(model);
                        }
                    });
                }
            });

            // Restore original object properties
            if (jQuery.isEmptyObject(model.changedAttributes())) {
                if (model.originalAttributes) {
                    model.set(model.originalAttributes);
                    delete model.originalAttributes;
                }
                return;
            }
            model.set(model.previousAttributes());
        },

        _removeLocal: function(model) {
            if (!this.options.localStorage) {
                return;
            }

            localStorage.removeItem(model.getSubject());
        }
    });
})(jQuery);
<commit_msg>Remove non-persistent objects when leaving edit state<commit_after>(function(jQuery, undefined) {
    jQuery.widget('Midgard.midgardStorage', {
        options: {
            localStorage: false,
            vie: null,
            changedModels: [],
            loaded: function() {},
            url: ''
        },

        _create: function() {
            var widget = this;

            if (Modernizr.localstorage) {
                this.options.localStorage = true;
            }

            this.vie = this.options.vie;

            this.vie.entities.bind('add', function(model) {
                // Add the back-end URL used by Backbone.sync
                model.url = widget.options.url;
                model.toJSON = model.toJSONLD;
            });

            jQuery('#midgardcreate-save').click(function() {
                widget._saveRemote({
                    success: function() {
                        jQuery('#midgardcreate-save').button({disabled: true});
                    },
                    error: function() {
                        console.log("Save failed");
                    }
                });
            });

            widget._bindEditables();
        },

        _bindEditables: function() {
            var widget = this;

            widget.element.bind('midgardeditablechanged', function(event, options) {
                if (_.indexOf(widget.options.changedModels, options.instance) === -1) {
                    widget.options.changedModels.push(options.instance);
                }
                widget._saveLocal(options.instance);
                jQuery('#midgardcreate-save').button({disabled: false});
            });

            widget.element.bind('midgardeditabledisable', function(event, options) {
                widget._restoreLocal(options.instance);
                jQuery('#midgardcreate-save').button({disabled: true});
            });

            widget.element.bind('midgardeditableenable', function(event, options) {
                widget._readLocal(options.instance);
                _.each(options.instance.attributes, function(attributeValue, property) {
                    if (attributeValue instanceof widget.vie.Collection) {
                        //widget._readLocalReferences(options.instance, property, attributeValue);
                    }
                });
            });

            widget.element.bind('midgardstorageloaded', function(event, options) {
                if (_.indexOf(widget.options.changedModels, options.instance) === -1) {
                    widget.options.changedModels.push(options.instance);
                }
                jQuery('#midgardcreate-save').button({disabled: false});
            });
        },

        _saveRemote: function(options) {
            var widget = this;
            var needed = widget.options.changedModels.length;
            _.forEach(widget.options.changedModels, function(model, index) {
                model.save(null, {
                    success: function() {
                        if (model.originalAttributes) {
                            // From now on we're going with the values we have on server
                            delete model.originalAttributes;
                        }
                        widget._removeLocal(model);
                        delete widget.options.changedModels[index];
                        needed--;
                        if (needed <= 0) {
                            // All models were happily saved
                            options.success();
                        }
                    },
                    error: function() {
                        options.error();
                    }
                });
            });
        },

        _saveLocal: function(model) {
            if (!this.options.localStorage) {
                return;
            }

            if (typeof model.id === 'object') {
                // Anonymous object, save as refs instead
                if (!model.primaryCollection) {
                    return;
                }
                return this._saveLocalReferences(model.primaryCollection.subject, model.primaryCollection.predicate, model);
            }
            localStorage.setItem(model.getSubject(), JSON.stringify(model.toJSONLD()));
        },

        _getReferenceId: function(model, property) {
            return model.id + ':' + property;
        },

        _saveLocalReferences: function(subject, predicate, model) {
            if (!this.options.localStorage) {
                return;
            }

            if (!subject ||
                !predicate) {
                return;
            }

            var widget = this;
            var identifier = subject + ':' + predicate;
            var json = model.toJSONLD();
            if (localStorage.getItem(identifier)) {
                var referenceList = JSON.parse(localStorage.getItem(identifier));
                var index = _.pluck(referenceList, '@').indexOf(json['@']);
                if (index !== -1) {
                    referenceList[index] = json;
                } else {
                    referenceList.push(json);
                }
                localStorage.setItem(identifier, JSON.stringify(referenceList));
                return;
            }
            localStorage.setItem(identifier, JSON.stringify([json]));
        },

        _readLocal: function(model) {
            if (!this.options.localStorage) {
                return;
            }

            var local = localStorage.getItem(model.getSubject());
            if (!local) {
                return;
            }
            model.originalAttributes = _.clone(model.attributes);
            var entity = this.vie.EntityManager.getByJSONLD(JSON.parse(local));

            this._trigger('loaded', null, {
                instance: entity
            });
        },

        _readLocalReferences: function(model, property, collection) {
            if (!this.options.localStorage) {
                return;
            }

            var identifier = this._getReferenceId(model, property);
            var local = localStorage.getItem(identifier);
            if (!local) {
                return;
            }
            collection.add(JSON.parse(local));
        },

        _restoreLocal: function(model) {
            var widget = this;
            // Remove unsaved collection members
            _.each(model.attributes, function(attributeValue, property) {
                if (attributeValue instanceof widget.vie.Collection) {
                    attributeValue.forEach(function(model) {
                        if (!model.id) {
                            attributeValue.remove(model);
                        }
                    });
                }
            });

            // Restore original object properties
            if (jQuery.isEmptyObject(model.changedAttributes())) {
                if (model.originalAttributes) {
                    model.set(model.originalAttributes);
                    delete model.originalAttributes;
                }
                return;
            }
            model.set(model.previousAttributes());
        },

        _removeLocal: function(model) {
            if (!this.options.localStorage) {
                return;
            }

            localStorage.removeItem(model.getSubject());
        }
    });
})(jQuery);
<|endoftext|>


<commit_before>"use strict";

!function(){
    var app = angular.module( "stateHandler", [ "ngRoute" ] );

    // Factories required to configure this module
    app.provider('$factoriesForStateHandle',["$provide",
      function($provide){
        var obj = {
            $get:function(){}
          };

        getFactoryReferenceFn("$route");
        getFactoryReferenceFn("$timeout");
        getFactoryReferenceFn("$location");

        function getFactoryReferenceFn(factoryName){
          $provide.decorator( factoryName, factoryDecoratorFn );

          function factoryDecoratorFn( $delegate ) {
            return obj[factoryName] = $delegate;
          };
        }

        $provide.decorator( "ngViewDirective", ngViewDirectiveDecoratorFn );

        function ngViewDirectiveDecoratorFn( $delegate, $route, $injector ) {
          var ngViewRef = $delegate[$delegate.length - 1],
            compileRef = ngViewRef.compile || function () {},
            link = function () {
              var current = $route.current;

              if (current.controllerSetting) {
                current.controller = $injector.invoke(current.controllerSetting);
              }

              ngViewRef.link.apply(null, arguments);
            };
          ngViewRef.compile = function () {
            compileRef.apply(ngViewRef, arguments);
            return link;
          };

          return $delegate;
        };
        return obj;
      }
    ]);

    // Provider to handle view and path state based on routing
    app.provider('$stateHandle',["$provide", "$factoriesForStateHandleProvider",
      function($provide, $factoriesForStateHandleProvider){
        var $browser = undefined,
          identityHash = {},
          userAuthenticated = false,
          authParams = {path:undefined,route:null},
          _constructor = function(subscriber,pathExpr){
            this.subscriber = subscriber;
            this.pathExpr = pathExpr;
            this.callBacks = [];
          },
          obj = {
            subscribe:subscribeFn,
            getSubscribers:getSubscribersFn,
            setUserAuth:setUserAuthFn,
            getUserAuth:getUserAuthFn,
            setAuthParams:setAuthParamsFn,
            getAuthParams:getAuthParamsFn
          };

        function subscribeFn(subscriber,pathExpr){
          if(!(pathExpr in identityHash)){
            identityHash[pathExpr] = {};
          }else if(subscriber in identityHash[pathExpr]){
            identityHash[pathExpr][subscriber].callBacks.length = 0;
          }

          return identityHash[pathExpr][subscriber] || (identityHash[pathExpr][subscriber] = new _constructor(subscriber,pathExpr));
        };

        function getSubscribersFn(pathExpr){
          return identityHash[pathExpr];
        };

        function setUserAuthFn(bool){
          userAuthenticated = true;
          return this;
        };

        function getUserAuthFn(){
          return userAuthenticated;
        };

        function setAuthParamsFn(path, route){
          authParams.path = path;
          authParams.route = route;
          return this;
        };

        function getAuthParamsFn(){
          return authParams;
        };

        function subscriberResponseFn(callback){
          this.callBacks.push(callback);

          if(this.pathExpr == $factoriesForStateHandleProvider.$route.current.originalPath){
            callback($factoriesForStateHandleProvider.$route.current.params);
          }
        };

        _constructor.prototype = {
          response:subscriberResponseFn
        };

        return {
          $get:function(){
            return obj;
          }
        };
      }
    ]);

    app.config([ "$provide", "$routeProvider", "$httpProvider", "$locationProvider", "$stateHandleProvider", "$factoriesForStateHandleProvider",
      function($provide, $routeProvider, $httpProvider, $locationProvider, $stateHandleProvider, $factoriesForStateHandleProvider) {
        var $stateHandle = $stateHandleProvider.$get(),
          previousUrl = undefined,
          randomTemplateUrl = "###" + (Math.random()*10/10) + "###",
          whenFn = cloneRouteProviderFn.call($stateHandleProvider,'when'),
          otherwiseFn = cloneRouteProviderFn.call($stateHandleProvider,'otherwise');

        function cloneRouteProviderFn(prop){
          var that = this,
              functionRef = $routeProvider[prop];
          return function(path, route) {
            if(route!==undefined){

              if(!('templateUrl' in route || 'template' in route)){
                route.templateUrl = randomTemplateUrl;
              }

              if(!('controller' in route || 'controllerSetting' in route)){
                route.controllerSetting = function($stateHandle){
                  return $stateHandle.route.current.controller;
                };
              }

            }

            functionRef.apply( $routeProvider, arguments );
            return( that );
          };
        };

        function removeFn( path ) {
          var $routeRef = $routeProvider.$get();
          path = path.replace( /\/$/i, "" );
          delete( $routeRef.routes[ path ] );
          delete( $routeRef.routes[ path + "/" ] );
          return( this );
        };

        function removeCurrentFn(){
          var $routeRef = $routeProvider.$get();
          return( this.remove( $routeRef.current.originalPath ) );
        };

        function reloadRouteFn(){
          $factoriesForStateHandleProvider.$route.reload();
        };

        function noAuthFn(path, route){
          var that = this,
            authParamsPathRef = $stateHandle.getAuthParams().path;

          if(authParamsPathRef !== undefined){
            $stateHandleProvider.remove(authParamsPathRef);
          }

          $stateHandle.setAuthParams(path, route);

          if('authentication' in route){
            delete route['authentication'];
          }

          $stateHandleProvider.when(path, route);
          return that;
        };

        function resetRouteFn(callback){
          $factoriesForStateHandleProvider.$location.path(previousUrl);
        };

        $stateHandle.remove = $stateHandleProvider.remove = removeFn;
        $stateHandle.removeCurrent = $stateHandleProvider.removeCurrent = removeCurrentFn;
        $stateHandle.when = $stateHandleProvider.when = whenFn;
        $stateHandle.otherwise = $stateHandleProvider.otherwise = otherwiseFn;
        $stateHandle.reloadRoute = $stateHandleProvider.reloadRoute = reloadRouteFn;
        $stateHandle.noAuth = $stateHandleProvider.noAuth = noAuthFn;
        $stateHandle.resetRoute = resetRouteFn;

        $httpProvider.interceptors.push(function ($q, $location, $timeout) {
          var cache = {};
            return {
                'request': function (config) {
                  var currentRouteRef = $factoriesForStateHandleProvider.$route.current,
                    subscribers = $stateHandle.getSubscribers(currentRouteRef.originalPath);

                  if(currentRouteRef.authentication && !$stateHandle.getUserAuth()){
                    $location.path($stateHandle.getAuthParams().path);
                    return config.url===randomTemplateUrl?cache:config;
                  }

                  $timeout(function(){
                    for(var a in subscribers){
                      var subscriberCallbacks = subscribers[a].callBacks;
                      for(var i=0,len=subscriberCallbacks.length;i<len;i++){
                        subscriberCallbacks[i](currentRouteRef.params);
                      }
                    }
                  });

                  if(config.url===randomTemplateUrl){
                    return cache;
                  }

                  cache = config;
                  $stateHandle.route = angular.copy($factoriesForStateHandleProvider.$route);
                  previousUrl = $location.path();
                  return config || $q.when(config);
                }
            }
        });

        $locationProvider.html5Mode(true);
      }
    ]);
}();
<commit_msg>Checking whether second parameter is object for noAuth function<commit_after>"use strict";

!function(){
    var app = angular.module( "stateHandler", [ "ngRoute" ] );

    // Factories required to configure this module
    app.provider('$factoriesForStateHandle',["$provide",
      function($provide){
        var obj = {
            $get:function(){}
          };

        getFactoryReferenceFn("$route");
        getFactoryReferenceFn("$timeout");
        getFactoryReferenceFn("$location");

        function getFactoryReferenceFn(factoryName){
          $provide.decorator( factoryName, factoryDecoratorFn );

          function factoryDecoratorFn( $delegate ) {
            return obj[factoryName] = $delegate;
          };
        }

        $provide.decorator( "ngViewDirective", ngViewDirectiveDecoratorFn );

        function ngViewDirectiveDecoratorFn( $delegate, $route, $injector ) {
          var ngViewRef = $delegate[$delegate.length - 1],
            compileRef = ngViewRef.compile || function () {},
            link = function () {
              var current = $route.current;

              if (current.controllerSetting) {
                current.controller = $injector.invoke(current.controllerSetting);
              }

              ngViewRef.link.apply(null, arguments);
            };
          ngViewRef.compile = function () {
            compileRef.apply(ngViewRef, arguments);
            return link;
          };

          return $delegate;
        };
        return obj;
      }
    ]);

    // Provider to handle view and path state based on routing
    app.provider('$stateHandle',["$provide", "$factoriesForStateHandleProvider",
      function($provide, $factoriesForStateHandleProvider){
        var $browser = undefined,
          identityHash = {},
          userAuthenticated = false,
          authParams = {path:undefined,route:null},
          _constructor = function(subscriber,pathExpr){
            this.subscriber = subscriber;
            this.pathExpr = pathExpr;
            this.callBacks = [];
          },
          obj = {
            subscribe:subscribeFn,
            getSubscribers:getSubscribersFn,
            setUserAuth:setUserAuthFn,
            getUserAuth:getUserAuthFn,
            setAuthParams:setAuthParamsFn,
            getAuthParams:getAuthParamsFn
          };

        function subscribeFn(subscriber,pathExpr){
          if(!(pathExpr in identityHash)){
            identityHash[pathExpr] = {};
          }else if(subscriber in identityHash[pathExpr]){
            identityHash[pathExpr][subscriber].callBacks.length = 0;
          }

          return identityHash[pathExpr][subscriber] || (identityHash[pathExpr][subscriber] = new _constructor(subscriber,pathExpr));
        };

        function getSubscribersFn(pathExpr){
          return identityHash[pathExpr];
        };

        function setUserAuthFn(bool){
          userAuthenticated = true;
          return this;
        };

        function getUserAuthFn(){
          return userAuthenticated;
        };

        function setAuthParamsFn(path, route){
          authParams.path = path;
          authParams.route = route;
          return this;
        };

        function getAuthParamsFn(){
          return authParams;
        };

        function subscriberResponseFn(callback){
          this.callBacks.push(callback);

          if(this.pathExpr == $factoriesForStateHandleProvider.$route.current.originalPath){
            callback($factoriesForStateHandleProvider.$route.current.params);
          }
        };

        _constructor.prototype = {
          response:subscriberResponseFn
        };

        return {
          $get:function(){
            return obj;
          }
        };
      }
    ]);

    app.config([ "$provide", "$routeProvider", "$httpProvider", "$locationProvider", "$stateHandleProvider", "$factoriesForStateHandleProvider",
      function($provide, $routeProvider, $httpProvider, $locationProvider, $stateHandleProvider, $factoriesForStateHandleProvider) {
        var $stateHandle = $stateHandleProvider.$get(),
          previousUrl = undefined,
          randomTemplateUrl = "###" + (Math.random()*10/10) + "###",
          whenFn = cloneRouteProviderFn.call($stateHandleProvider,'when'),
          otherwiseFn = cloneRouteProviderFn.call($stateHandleProvider,'otherwise');

        function cloneRouteProviderFn(prop){
          var that = this,
              functionRef = $routeProvider[prop];
          return function(path, route) {
            if(route!==undefined){

              if(!('templateUrl' in route || 'template' in route)){
                route.templateUrl = randomTemplateUrl;
              }

              if(!('controller' in route || 'controllerSetting' in route)){
                route.controllerSetting = function($stateHandle){
                  return $stateHandle.route.current.controller;
                };
              }

            }

            functionRef.apply( $routeProvider, arguments );
            return( that );
          };
        };

        function removeFn( path ) {
          var $routeRef = $routeProvider.$get();
          path = path.replace( /\/$/i, "" );
          delete( $routeRef.routes[ path ] );
          delete( $routeRef.routes[ path + "/" ] );
          return( this );
        };

        function removeCurrentFn(){
          var $routeRef = $routeProvider.$get();
          return( this.remove( $routeRef.current.originalPath ) );
        };

        function reloadRouteFn(){
          $factoriesForStateHandleProvider.$route.reload();
        };

        function noAuthFn(path, route){
          var that = this,
            authParamsPathRef = $stateHandle.getAuthParams().path;

          if(authParamsPathRef !== undefined){
            $stateHandleProvider.remove(authParamsPathRef);
          }

          $stateHandle.setAuthParams(path, route);

          if(route!==undefined && 'authentication' in route){
            delete route['authentication'];
          }

          $stateHandleProvider.when(path, route);
          return that;
        };

        function resetRouteFn(callback){
          $factoriesForStateHandleProvider.$location.path(previousUrl);
        };

        $stateHandle.remove = $stateHandleProvider.remove = removeFn;
        $stateHandle.removeCurrent = $stateHandleProvider.removeCurrent = removeCurrentFn;
        $stateHandle.when = $stateHandleProvider.when = whenFn;
        $stateHandle.otherwise = $stateHandleProvider.otherwise = otherwiseFn;
        $stateHandle.reloadRoute = $stateHandleProvider.reloadRoute = reloadRouteFn;
        $stateHandle.noAuth = $stateHandleProvider.noAuth = noAuthFn;
        $stateHandle.resetRoute = resetRouteFn;

        $httpProvider.interceptors.push(function ($q, $location, $timeout) {
          var cache = {};
            return {
                'request': function (config) {
                  var currentRouteRef = $factoriesForStateHandleProvider.$route.current,
                    subscribers = $stateHandle.getSubscribers(currentRouteRef.originalPath);

                  if(currentRouteRef.authentication && !$stateHandle.getUserAuth()){
                    $location.path($stateHandle.getAuthParams().path);
                    return config.url===randomTemplateUrl?cache:config;
                  }

                  $timeout(function(){
                    for(var a in subscribers){
                      var subscriberCallbacks = subscribers[a].callBacks;
                      for(var i=0,len=subscriberCallbacks.length;i<len;i++){
                        subscriberCallbacks[i](currentRouteRef.params);
                      }
                    }
                  });

                  if(config.url===randomTemplateUrl){
                    return cache;
                  }

                  cache = config;
                  $stateHandle.route = angular.copy($factoriesForStateHandleProvider.$route);
                  previousUrl = $location.path();
                  return config || $q.when(config);
                }
            }
        });

        $locationProvider.html5Mode(true);
      }
    ]);
}();
<|endoftext|>


<commit_before>var PORT = 3001;
var DOMAIN = 'meetua.com';

module.exports = {
  secrets: {
    db: 'mongodb://localhost:27017/meetua-staging'
  },
  port: PORT,
  domain: DOMAIN,
  hostname: 'http://' + DOMAIN + ':' + PORT
};<commit_msg>Separate logs and persistent dir for staging server<commit_after>var path = require('path');
var PORT = 3001;
var DOMAIN = 'meetua.com';

module.exports = {
  secrets: {
    db: 'mongodb://localhost:27017/meetua-staging'
  },
  port: PORT,
  domain: DOMAIN,
  hostname: 'http://' + DOMAIN + ':' + PORT,
  LOG_FILE_NAME: 'staging-service.log',
  PERSISTENT_DATA_DIR: process.env.PERSISTENT_DATA_DIR || path.join(process.cwd(), '../PERSISTENT_DATA_DIR_STAGING')
};<|endoftext|>


<commit_before>const webpack = require('webpack');
const CleanWebpackPlugin = require('clean-webpack-plugin');
// import webpack from 'webpack'
// import CleanWebpackPlugin from 'clean-webpack-plugin';

module.exports = class Util{
  /**
   * Creating a webpack dev-server configuration with customize host and port.
   * @param {String} host -The address you want to host this project
   * @param {Number} port -The port you want to host this porject.
   * @returns {{devServer: {historyApiFallback: boolean, hot: boolean, inline: boolean, stats: string, host: *, port: *}, plugins: [*]}}
   */
  static devServer({ host = 'localhost', port = 8100 }) {
    return {
      devServer: {
        // Enable history API fallback so HTML5 History API based
        // routing works. This is a good default that will come
        // in handy in more complicated setups.
        historyApiFallback: true,
        // Unlike the cli flag, this doesn't set
        // HotModuleReplacementPlugin!
        hot: true,
        inline: true,
        // Display only errors to reduce the amount of output.
        // stats: 'errors-only',
        // Parse host and port from env to allow customization.
        //
        // If you use Vagrant or Cloud9, set
        // host: options.host || '0.0.0.0';
        //
        // 0.0.0.0 is available to all network devices
        // unlike default `localhost`.
        host, // Defaults to `localhost`
        port // Defaults to 8080
      },
      plugins: [
        // Enable multi-pass compilation for enhanced performance
        // in larger projects. Good default.
        new webpack.HotModuleReplacementPlugin({
          multiStep: false
        })
      ]
    };
  };

  /**
   * Creating a webpack UglifyJS / Dedupe / NoErrors plugin configuration.
   * - Plugins - Search for equal or similar files and deduplicate them in the output.
   * - Plugins - When there are errors while compiling this plugin skips the emitting phase (and recording phase), so there are no assets emitted that include errors.
   * - Plugins - Compress the JS bundle
   *
   * @returns {{plugins: [*]}}
   */
  static optimize() {
    return {
      plugins: [
        new webpack.optimize.UglifyJsPlugin({
          // Don't beautify output (enable for neater output)
          beautify: false,
          // Eliminate comments
          comments: false,
          compress: {
            warnings: false,
            drop_console: true
          },
          sourceMap: false,
          mangle: {
            except: ['$', 'jQuery']
          }
        }),
        new webpack.LoaderOptionsPlugin({
          minimize: true
        }),
        new webpack.NoEmitOnErrorsPlugin()
      ]
    };
  }

  static duplicateObject(obj) {
    const output = {};
    Object.keys(obj).forEach(key => {
      if (Object.prototype.toString.call(obj[key]) === '[object Object]') {
        output[key] = this.duplicateObject(obj[key]);
      } else if (Object.prototype.toString.call(obj[key]) === '[object Array]') {
        output[key] = obj[key].slice();
      } else {
        output[key] = obj[key];
      }
    });
    return output;
  }

  /**
   * Creating a webpack configuration for environment variable.
   * @param {String} key - The variable key.
   * @param {String} value - The value you would like to assign.
   * @returns {{plugins: [*]}}
   */
// exports.setFreeVariable = function (key, value) {
//   const env = {};
//   env[key] = JSON.stringify(value);
//
//   return {
//     plugins: [
//       new webpack.DefinePlugin(env)
//     ]
//   };
// };

  /**
   * Creating a webpack configuration for environment variable.
   * @param {String[]} variables - The list of the variable.
   * @returns {{plugins: [*]}}
   */
  static setEnvironmentVariable(variables) {
    // const env = variables;
    return {
      plugins: [
        new webpack.EnvironmentPlugin(variables)
      ]
    };
  };

  /**
   * Creating a webpack extract bundle configuration, extract the webpack runtime setting and some library.
   * @param {String} name -The name of the extract js file.
   * @param {Array} entries -The path of the js file.
   * @returns {{entry: {}, plugins: [*]}}
   */
  static extractJSBundle({name = '', entries = []}) {
    let names = ['manifest'];
    const entry = {};
    if (!name && name.length !== 0 && !entries && entries.length !== 0 ) {
      entry[name] = entries;
      names.unshift(name);
    }

    return {
      // Define an entry point needed for splitting.
      entry,
      plugins: [
        // Extract bundle and manifest files. Manifest is
        // needed for reliable caching.
        new webpack.optimize.CommonsChunkPlugin({
          names: names
        })
      ]
    };
  };

  /**
   * Creating a webpack cleaning plugin configuration to delete the old version of the production folder.
   * @param {String} path -The path of the production folder.
   * @returns {{plugins: [*]}}
   */
  static clean (path) {
    return {
      plugins: [
        new CleanWebpackPlugin([path], {
          // Without `root` CleanWebpackPlugin won't point to our
          // project and will fail to work.
          root: process.cwd()
        })
      ]
    };
  };

  static providePlugin( provide={} ) {
    const providePlugin = new webpack.ProvidePlugin(provide);
    return {
      plugins: [
        new providePlugin (provide)
      ]
    };
  }
};
<commit_msg>🐛 Fix: Hot fix for ProvidePlugin in Util.<commit_after>const webpack = require('webpack');
const CleanWebpackPlugin = require('clean-webpack-plugin');
// import webpack from 'webpack'
// import CleanWebpackPlugin from 'clean-webpack-plugin';

module.exports = class Util {
  /**
   * Creating a webpack dev-server configuration with customize host and port.
   * @param {String} host -The address you want to host this project
   * @param {Number} port -The port you want to host this project.
   * @param {Boolean} verbose -The controller for output detail.
   * @returns {{devServer: {historyApiFallback: boolean, hot: boolean, inline: boolean, stats: string, host: *, port: *}, plugins: [*]}}
   */
  static devServer({host = 'localhost', port = 8100, verbose = false}) {
    return {
      devServer: {
        // Enable history API fallback so HTML5 History API based
        // routing works. This is a good default that will come
        // in handy in more complicated setups.
        historyApiFallback: true,
        // Unlike the cli flag, this doesn't set
        // HotModuleReplacementPlugin!
        hot: true,
        inline: true,
        // Display only errors to reduce the amount of output.
        stats: verbose ? 'normal' : 'errors-only',
        // Parse host and port from env to allow customization.
        //
        // If you use Vagrant or Cloud9, set
        // host: options.host || '0.0.0.0';
        //
        // 0.0.0.0 is available to all network devices
        // unlike default `localhost`.
        host, // Defaults to `localhost`
        port // Defaults to 8080
      },
      plugins: [
        // Enable multi-pass compilation for enhanced performance
        // in larger projects. Good default.
        new webpack.HotModuleReplacementPlugin({
          multiStep: false
        })
      ]
    };
  };

  /**
   * Creating a webpack UglifyJS / Dedupe / NoErrors plugin configuration.
   * - Plugins - Search for equal or similar files and deduplicate them in the output.
   * - Plugins - When there are errors while compiling this plugin skips the emitting phase (and recording phase), so there are no assets emitted that include errors.
   * - Plugins - Compress the JS bundle
   *
   * @returns {{plugins: [*]}}
   */
  static optimize() {
    return {
      plugins: [
        new webpack.optimize.UglifyJsPlugin({
          // Don't beautify output (enable for neater output)
          beautify: false,
          // Eliminate comments
          comments: false,
          compress: {
            warnings: false,
            drop_console: true
          },
          sourceMap: false,
          mangle: {
            except: ['$', 'jQuery']
          }
        }),
        new webpack.LoaderOptionsPlugin({
          minimize: true
        }),
        new webpack.NoEmitOnErrorsPlugin()
      ]
    };
  }

  static duplicateObject(obj) {
    const output = {};
    Object.keys(obj).forEach(key => {
      if (Object.prototype.toString.call(obj[key]) === '[object Object]') {
        output[key] = this.duplicateObject(obj[key]);
      } else if (Object.prototype.toString.call(obj[key]) === '[object Array]') {
        output[key] = obj[key].slice();
      } else {
        output[key] = obj[key];
      }
    });
    return output;
  }

  /**
   * Creating a webpack configuration for environment variable.
   * @param {String} key - The variable key.
   * @param {String} value - The value you would like to assign.
   * @returns {{plugins: [*]}}
   */
  // TODO: Check if DefinePlugin is working or not.
  static setFreeVariable(key, value) {
    const env = {};
    env[key] = JSON.stringify(value);

    return {
      plugins: [
        new webpack.DefinePlugin(env)
      ]
    };
  }

  /**
   * Creating a webpack configuration for environment variable.
   * @param {String[]} variables - The list of the variable.
   * @returns {{plugins: [*]}}
   */
  static setEnvironmentVariable(variables) {
    // const env = variables;
    return {
      plugins: [
        new webpack.EnvironmentPlugin(variables)
      ]
    };
  }

  /**
   * Creating a webpack extract bundle configuration, extract the webpack runtime setting and some library.
   * @param {String} name -The name of the extract js file.
   * @param {Array} entries -The path of the js file.
   * @returns {{entry: {}, plugins: [*]}}
   */
  static extractJSBundle({name = '', entries = []}) {
    let names = ['manifest'];
    const entry = {};
    if (!name && name.length !== 0 && !entries && entries.length !== 0) {
      entry[name] = entries;
      names.unshift(name);
    }

    return {
      // Define an entry point needed for splitting.
      entry,
      plugins: [
        // Extract bundle and manifest files. Manifest is
        // needed for reliable caching.
        new webpack.optimize.CommonsChunkPlugin({
          names: names
        })
      ]
    };
  };

  /**
   * Creating a webpack cleaning plugin configuration to delete the old version of the production folder.
   * @param {String} path -The path of the production folder.
   * @returns {{plugins: [*]}}
   */
  static clean(path) {
    return {
      plugins: [
        new CleanWebpackPlugin([path], {
          // Without `root` CleanWebpackPlugin won't point to our
          // project and will fail to work.
          root: process.cwd()
        })
      ]
    };
  };

  static providePlugin(provide = {}) {
    const providePlugin = new webpack.ProvidePlugin(provide);
    return {
      plugins: [
        providePlugin
      ]
    };
  }
};
<|endoftext|>


<commit_before>var uTest = {
   testGroups:    {},

   failCount:     0,
   runCount:      0,
   ignoreCount:   0,
   startTime:     0,

   TEST_GROUP: function (group) {
      group.tests = [ ];
      this.testGroups[group.name] = group;
   },

   TEST: function (test) {
      test.group = test.group;
      this.testGroups[test.group].tests.push(test);
   },

   CHECK: function (condition) {
      var errorString;

      if (condition !== true) {
         errorString = this.buildErrorString() + "\tCHECK failed";
         this.throwTestError(errorString);
      }
   },

   CHECK_TEXT: function (condition, text) {
      var errorString;

      if (condition !== true) {
         errorString = this.buildErrorString() + "\tMessage: " + text + "\n\tCHECK failed";
         this.throwTestError(errorString);
      }
   },

   CHECK_EQUAL: function (expected, actual) {
      var errorString;

      if (expected !== actual) {
         errorString = this.buildErrorString() +   "\texpected <" + expected  + ">\n" +
                                                   "\tbut was  <" + actual    + ">";
         this.throwTestError(errorString);
      }
   },

   STRCMP_EQUAL: function (expected, actual) {
      var errorString;

      if (expected.toString() !== actual.toString()) {
         errorString = this.buildErrorString() +   "\texpected <" + expected.toString()   + ">\n" +
                                                   "\tbut was  <" + actual.toString()     + ">";
         this.throwTestError(errorString);
      }
   },

   LONGS_EQUAL: function (expected, actual) {
      var errorString;

      if (Math.floor(expected) !== Math.floor(actual)) {
         errorString = this.buildErrorString() +   "\texpected <" + Math.floor(expected)  + ">\n" +
                                                   "\tbut was  <" + Math.floor(actual)    + ">";
         this.throwTestError(errorString);
      }
   },

   BYTES_EQUAL: function (expected, actual) {
      this.LONGS_EQUAL(expected & 0xFF, actual & 0xFF);
   },

   DOUBLES_EQUAL: function (expected, actual, tolerance) {
      var errorString;

      if (Math.abs(expected - actual) > tolerance) {
         errorString = this.buildErrorString() +   "\texpected <" + expected  + ">\n"  +
                                                   "\tbut was  <" + actual    + ">"    +
                                                   " threshold was <" + tolerance + ">";
         this.throwTestError(errorString);
      }
   },

   FAIL: function (text) {
      var errorString = this.buildErrorString() + "\t" + text;
      this.throwTestError(errorString);
   },

   runAllTests: function () {
      this.run(null, null);
   },

   runTestGroup: function (groupName) {
      this.run(groupName, null);
   },

   runTest: function (test) {
      var   groupName = null,
            testName = null;

      if (typeof test === "string") {

         testName = test;

      } else if (typeof test === "object") {

         if ("group" in test) {
            groupName = test.group;
         }

         if ("name" in test) {
            testName = test.name;
         }
      }

      if (testName != null) {
         this.run(groupName, testName);
      }
   },

   run: function (groupName, testName) {
      this.resetResults();

      tests = this.findTests(groupName, testName);

      for (var i = 0; i < tests.length; i++) {
         this.runTestObj(tests[i]);
      }

      this.logResults();
   },

   TestError: function (message) {
      this.name = "TestError";
      this.message = message + "\n";
   },

   throwTestError: function (message) {
      if (this.TestError.prototype.toString() !== "Error") {
         this.TestError.prototype = new Error();
      }
      throw new this.TestError(message);
   },

   buildErrorString: function () {
      var   error = (function () { try { throw new Error(); } catch (ex) {return ex;}})(),
            errorString = "",
            callerLines,
            matches;

      if (error.stack) {
         callerLines = error.stack.split("\n")[4];
         matches = callerLines.match(/\((.*)\)/);
         if (matches !== null) {
            errorString += matches[1] + ": ";
         }
      }

      errorString += "error: Failure in TEST(";
      errorString += this.currentGroup + ", ";
      errorString += this.currentTest + ")\n";

      return errorString;
   },

   findTests: function (groupName, testName) {
      var matchingTests = [ ];

      for (var name in this.testGroups) {

         if ((groupName === null) || (name === groupName)) {

            for (var i = 0; i < this.testGroups[name].tests.length; i++) {

               if ((testName === null) || (this.testGroups[name].tests[i].name == testName)) {

                  matchingTests.push(this.testGroups[name].tests[i]);
               }
            }
         }
      }

      return matchingTests;
   },

   getTestCount: function () {
      var count = 0;

      for (var groupName in this.testGroups) {
         count += this.testGroups[groupName].tests.length;
      }

      return count;
   },

   countChecks: function (func) {
      var   count = 0,
            re,
            reStr,
            functionStr,
            matches;

      reStr =  "uTest\\.(CHECK"     +
               "|CHECK_TEXT"        +
               "|CHECK_EQUAL"       +
               "|STRCMP_EQUAL"      +
               "|LONGS_EQUAL"       +
               "|BYTES_EQUAL"       +
               "|DOUBLES_EQUAL"     +
               "|FAIL"              +
               ")";

      re = new RegExp(reStr, "g");

      functionStr = '' + func;
      matches = functionStr.match(re);

      if (matches !== null) {
         count += matches.length;
      }

      return count;
   },

   resetResults: function () {
      this.failCount    = 0;
      this.runCount     = 0;
      this.ignoreCount  = 0;
      this.startTime    = Date.now();
   },

   logResults: function () {
      var results;

      if (this.failCount > 0) {
         results =   "Errors ("     +
                     this.failCount;
         if (this.failCount === 1) {
            results += " failure, ";
         } else {
            results += " failures, ";
         }
      } else {
         results = "OK (";
      }

      results += this.getTestCount();
      if (this.getTestCount() === 1) {
         results += " test, ";
      } else {
         results += " tests, ";
      }

      results += this.runCount + " ran, ";
      results += this.ignoreCount + " ignored, ";
      results += this.getTestCount() - this.runCount + " filtered out, ";
      results += Date.now() - this.startTime + " ms)\n\n";

      console.log(results);
   },

   runTestObj: function (test) {
      var group = this.testGroups[test.group];

      this.currentGroup = test.group;
      this.currentTest  = test.name;

      this.runCount++;

      try {

         if (typeof group.setup === "function") {
            group.setup();
         }

         if (typeof test.run === "function") {
            test.run();
         }

         if (typeof group.teardown === "function") {
            group.teardown();
         }

      } catch (ex) {

         if (ex instanceof this.TestError) {

            console.log(ex.message);
            this.failCount++;

         } else {
            throw ex;
         }
      }
   }
};
<commit_msg>Declare local variable<commit_after>var uTest = {
   testGroups:    {},

   failCount:     0,
   runCount:      0,
   ignoreCount:   0,
   startTime:     0,

   TEST_GROUP: function (group) {
      group.tests = [ ];
      this.testGroups[group.name] = group;
   },

   TEST: function (test) {
      test.group = test.group;
      this.testGroups[test.group].tests.push(test);
   },

   CHECK: function (condition) {
      var errorString;

      if (condition !== true) {
         errorString = this.buildErrorString() + "\tCHECK failed";
         this.throwTestError(errorString);
      }
   },

   CHECK_TEXT: function (condition, text) {
      var errorString;

      if (condition !== true) {
         errorString = this.buildErrorString() + "\tMessage: " + text + "\n\tCHECK failed";
         this.throwTestError(errorString);
      }
   },

   CHECK_EQUAL: function (expected, actual) {
      var errorString;

      if (expected !== actual) {
         errorString = this.buildErrorString() +   "\texpected <" + expected  + ">\n" +
                                                   "\tbut was  <" + actual    + ">";
         this.throwTestError(errorString);
      }
   },

   STRCMP_EQUAL: function (expected, actual) {
      var errorString;

      if (expected.toString() !== actual.toString()) {
         errorString = this.buildErrorString() +   "\texpected <" + expected.toString()   + ">\n" +
                                                   "\tbut was  <" + actual.toString()     + ">";
         this.throwTestError(errorString);
      }
   },

   LONGS_EQUAL: function (expected, actual) {
      var errorString;

      if (Math.floor(expected) !== Math.floor(actual)) {
         errorString = this.buildErrorString() +   "\texpected <" + Math.floor(expected)  + ">\n" +
                                                   "\tbut was  <" + Math.floor(actual)    + ">";
         this.throwTestError(errorString);
      }
   },

   BYTES_EQUAL: function (expected, actual) {
      this.LONGS_EQUAL(expected & 0xFF, actual & 0xFF);
   },

   DOUBLES_EQUAL: function (expected, actual, tolerance) {
      var errorString;

      if (Math.abs(expected - actual) > tolerance) {
         errorString = this.buildErrorString() +   "\texpected <" + expected  + ">\n"  +
                                                   "\tbut was  <" + actual    + ">"    +
                                                   " threshold was <" + tolerance + ">";
         this.throwTestError(errorString);
      }
   },

   FAIL: function (text) {
      var errorString = this.buildErrorString() + "\t" + text;
      this.throwTestError(errorString);
   },

   runAllTests: function () {
      this.run(null, null);
   },

   runTestGroup: function (groupName) {
      this.run(groupName, null);
   },

   runTest: function (test) {
      var   groupName = null,
            testName = null;

      if (typeof test === "string") {

         testName = test;

      } else if (typeof test === "object") {

         if ("group" in test) {
            groupName = test.group;
         }

         if ("name" in test) {
            testName = test.name;
         }
      }

      if (testName != null) {
         this.run(groupName, testName);
      }
   },

   run: function (groupName, testName) {
      var tests;

      this.resetResults();

      tests = this.findTests(groupName, testName);

      for (var i = 0; i < tests.length; i++) {
         this.runTestObj(tests[i]);
      }

      this.logResults();
   },

   TestError: function (message) {
      this.name = "TestError";
      this.message = message + "\n";
   },

   throwTestError: function (message) {
      if (this.TestError.prototype.toString() !== "Error") {
         this.TestError.prototype = new Error();
      }
      throw new this.TestError(message);
   },

   buildErrorString: function () {
      var   error = (function () { try { throw new Error(); } catch (ex) {return ex;}})(),
            errorString = "",
            callerLines,
            matches;

      if (error.stack) {
         callerLines = error.stack.split("\n")[4];
         matches = callerLines.match(/\((.*)\)/);
         if (matches !== null) {
            errorString += matches[1] + ": ";
         }
      }

      errorString += "error: Failure in TEST(";
      errorString += this.currentGroup + ", ";
      errorString += this.currentTest + ")\n";

      return errorString;
   },

   findTests: function (groupName, testName) {
      var matchingTests = [ ];

      for (var name in this.testGroups) {

         if ((groupName === null) || (name === groupName)) {

            for (var i = 0; i < this.testGroups[name].tests.length; i++) {

               if ((testName === null) || (this.testGroups[name].tests[i].name == testName)) {

                  matchingTests.push(this.testGroups[name].tests[i]);
               }
            }
         }
      }

      return matchingTests;
   },

   getTestCount: function () {
      var count = 0;

      for (var groupName in this.testGroups) {
         count += this.testGroups[groupName].tests.length;
      }

      return count;
   },

   countChecks: function (func) {
      var   count = 0,
            re,
            reStr,
            functionStr,
            matches;

      reStr =  "uTest\\.(CHECK"     +
               "|CHECK_TEXT"        +
               "|CHECK_EQUAL"       +
               "|STRCMP_EQUAL"      +
               "|LONGS_EQUAL"       +
               "|BYTES_EQUAL"       +
               "|DOUBLES_EQUAL"     +
               "|FAIL"              +
               ")";

      re = new RegExp(reStr, "g");

      functionStr = '' + func;
      matches = functionStr.match(re);

      if (matches !== null) {
         count += matches.length;
      }

      return count;
   },

   resetResults: function () {
      this.failCount    = 0;
      this.runCount     = 0;
      this.ignoreCount  = 0;
      this.startTime    = Date.now();
   },

   logResults: function () {
      var results;

      if (this.failCount > 0) {
         results =   "Errors ("     +
                     this.failCount;
         if (this.failCount === 1) {
            results += " failure, ";
         } else {
            results += " failures, ";
         }
      } else {
         results = "OK (";
      }

      results += this.getTestCount();
      if (this.getTestCount() === 1) {
         results += " test, ";
      } else {
         results += " tests, ";
      }

      results += this.runCount + " ran, ";
      results += this.ignoreCount + " ignored, ";
      results += this.getTestCount() - this.runCount + " filtered out, ";
      results += Date.now() - this.startTime + " ms)\n\n";

      console.log(results);
   },

   runTestObj: function (test) {
      var group = this.testGroups[test.group];

      this.currentGroup = test.group;
      this.currentTest  = test.name;

      this.runCount++;

      try {

         if (typeof group.setup === "function") {
            group.setup();
         }

         if (typeof test.run === "function") {
            test.run();
         }

         if (typeof group.teardown === "function") {
            group.teardown();
         }

      } catch (ex) {

         if (ex instanceof this.TestError) {

            console.log(ex.message);
            this.failCount++;

         } else {
            throw ex;
         }
      }
   }
};
<|endoftext|>


<commit_before>/* eslint
    no-console: 0,
    no-param-reassign: 0,
    no-use-before-define: ["error", { "variables": false }],
    no-return-assign: 0,
    react/no-string-refs: 0,
    react/sort-comp: 0
*/

import PropTypes from 'prop-types';
import React from 'react';

import { FlatList, View, StyleSheet } from 'react-native';
import sum from 'hash-sum';

import LoadEarlier from './LoadEarlier';
import Message from './Message';

export default class MessageContainer extends React.PureComponent {

  constructor(props) {
    super(props);

    this.renderRow = this.renderRow.bind(this);
    this.renderFooter = this.renderFooter.bind(this);
    this.renderLoadEarlier = this.renderLoadEarlier.bind(this);
    this.renderHeaderWrapper = this.renderHeaderWrapper.bind(this);
  }

  renderFooter() {
    if (this.props.renderFooter) {
      const footerProps = {
        ...this.props,
      };
      return this.props.renderFooter(footerProps);
    }
    return null;
  }

  renderLoadEarlier() {
    if (this.props.loadEarlier === true) {
      const loadEarlierProps = {
        ...this.props,
      };
      if (this.props.renderLoadEarlier) {
        return this.props.renderLoadEarlier(loadEarlierProps);
      }
      return <LoadEarlier {...loadEarlierProps} />;
    }
    return null;
  }

  scrollTo(options) {
    if (this.flatListRef) {
      this.refs.flatListRef.scrollToOffset(options);
    }
  }

  renderRow({ item, index }) {
    if (!item._id && item._id !== 0) {
      console.warn('GiftedChat: `_id` is missing for message', JSON.stringify(item));
    }
    if (!item.user) {
      if (!item.system) {
        console.warn('GiftedChat: `user` is missing for message', JSON.stringify(item));
      }
      item.user = {};
    }
    const { messages, ...restProps } = this.props;
    const previousMessage = messages[index + 1] || {};
    const nextMessage = messages[index - 1] || {};

    const messageProps = {
      ...restProps,
      key: item._id,
      currentMessage: item,
      previousMessage,
      nextMessage,
      position: item.user._id === this.props.user._id ? 'right' : 'left',
      hash: sum(
        `${item.body ? item.body.length : 0}${JSON.stringify(item.attributes)}${previousMessage._id}${nextMessage._id}`,
      ),
    };

    if (this.props.renderMessage) {
      return this.props.renderMessage(messageProps);
    }
    return <Message {...messageProps} />;
  }

  renderHeaderWrapper() {
    return <View style={styles.headerWrapper}>{this.renderLoadEarlier()}</View>;
  }

  render() {
    if (this.props.messages.length === 0) {
      return <View style={styles.container} />;
    }

    return (
      <View ref="container" style={styles.container}>
        <FlatList
          ref={(ref) => (this.flatListRef = ref)}
          keyExtractor={(item) => item._id}
          enableEmptySections
          automaticallyAdjustContentInsets={false}
          initialNumToRender={8}
          maxToRenderPerBatch={1}
          removeClippedSubviews
          inverted={this.props.inverted}
          {...this.props.listViewProps}
          data={this.state.messagesData}
          style={styles.listStyle}
          contentContainerStyle={styles.contentContainerStyle}
          renderItem={this.renderRow}
          renderHeader={this.renderFooter}
          renderFooter={this.renderLoadEarlier}
          {...this.props.invertibleScrollViewProps}
          ListFooterComponent={this.renderHeaderWrapper}
        />
      </View>
    );
  }

}

const styles = StyleSheet.create({
  container: {
    flex: 1,
  },
  contentContainerStyle: {
    justifyContent: 'flex-end',
  },
  headerWrapper: {
    flex: 1,
  },
  listStyle: {
    flex: 1,
  },
});

MessageContainer.defaultProps = {
  messages: [],
  user: {},
  renderFooter: null,
  renderMessage: null,
  onLoadEarlier: () => {},
  inverted: true,
  loadEarlier: false,
  listViewProps: {},
  invertibleScrollViewProps: {}, // TODO: support or not?
};

MessageContainer.propTypes = {
  messages: PropTypes.arrayOf(PropTypes.object),
  user: PropTypes.object,
  renderFooter: PropTypes.func,
  renderMessage: PropTypes.func,
  renderLoadEarlier: PropTypes.func,
  onLoadEarlier: PropTypes.func,
  listViewProps: PropTypes.object,
  inverted: PropTypes.bool,
  loadEarlier: PropTypes.bool,
  invertibleScrollViewProps: PropTypes.object, // TODO: support or not?
};
<commit_msg>fix(state): remove state at all<commit_after>/* eslint
    no-console: 0,
    no-param-reassign: 0,
    no-use-before-define: ["error", { "variables": false }],
    no-return-assign: 0,
    react/no-string-refs: 0,
    react/sort-comp: 0
*/

import PropTypes from 'prop-types';
import React from 'react';

import { FlatList, View, StyleSheet } from 'react-native';
import sum from 'hash-sum';

import LoadEarlier from './LoadEarlier';
import Message from './Message';

export default class MessageContainer extends React.PureComponent {

  constructor(props) {
    super(props);

    this.renderRow = this.renderRow.bind(this);
    this.renderFooter = this.renderFooter.bind(this);
    this.renderLoadEarlier = this.renderLoadEarlier.bind(this);
    this.renderHeaderWrapper = this.renderHeaderWrapper.bind(this);
  }

  renderFooter() {
    if (this.props.renderFooter) {
      const footerProps = {
        ...this.props,
      };
      return this.props.renderFooter(footerProps);
    }
    return null;
  }

  renderLoadEarlier() {
    if (this.props.loadEarlier === true) {
      const loadEarlierProps = {
        ...this.props,
      };
      if (this.props.renderLoadEarlier) {
        return this.props.renderLoadEarlier(loadEarlierProps);
      }
      return <LoadEarlier {...loadEarlierProps} />;
    }
    return null;
  }

  scrollTo(options) {
    if (this.flatListRef) {
      this.refs.flatListRef.scrollToOffset(options);
    }
  }

  renderRow({ item, index }) {
    if (!item._id && item._id !== 0) {
      console.warn('GiftedChat: `_id` is missing for message', JSON.stringify(item));
    }
    if (!item.user) {
      if (!item.system) {
        console.warn('GiftedChat: `user` is missing for message', JSON.stringify(item));
      }
      item.user = {};
    }
    const { messages, ...restProps } = this.props;
    const previousMessage = messages[index + 1] || {};
    const nextMessage = messages[index - 1] || {};

    const messageProps = {
      ...restProps,
      key: item._id,
      currentMessage: item,
      previousMessage,
      nextMessage,
      position: item.user._id === this.props.user._id ? 'right' : 'left',
      hash: sum(
        `${item.body ? item.body.length : 0}${JSON.stringify(item.attributes)}${previousMessage._id}${nextMessage._id}`,
      ),
    };

    if (this.props.renderMessage) {
      return this.props.renderMessage(messageProps);
    }
    return <Message {...messageProps} />;
  }

  renderHeaderWrapper() {
    return <View style={styles.headerWrapper}>{this.renderLoadEarlier()}</View>;
  }

  render() {
    if (this.props.messages.length === 0) {
      return <View style={styles.container} />;
    }

    return (
      <View ref="container" style={styles.container}>
        <FlatList
          ref={(ref) => (this.flatListRef = ref)}
          keyExtractor={(item) => item._id}
          enableEmptySections
          automaticallyAdjustContentInsets={false}
          initialNumToRender={8}
          maxToRenderPerBatch={1}
          removeClippedSubviews
          inverted={this.props.inverted}
          {...this.props.listViewProps}
          data={this.props.messages}
          style={styles.listStyle}
          contentContainerStyle={styles.contentContainerStyle}
          renderItem={this.renderRow}
          renderHeader={this.renderFooter}
          renderFooter={this.renderLoadEarlier}
          {...this.props.invertibleScrollViewProps}
          ListFooterComponent={this.renderHeaderWrapper}
        />
      </View>
    );
  }

}

const styles = StyleSheet.create({
  container: {
    flex: 1,
  },
  contentContainerStyle: {
    justifyContent: 'flex-end',
  },
  headerWrapper: {
    flex: 1,
  },
  listStyle: {
    flex: 1,
  },
});

MessageContainer.defaultProps = {
  messages: [],
  user: {},
  renderFooter: null,
  renderMessage: null,
  onLoadEarlier: () => {},
  inverted: true,
  loadEarlier: false,
  listViewProps: {},
  invertibleScrollViewProps: {}, // TODO: support or not?
};

MessageContainer.propTypes = {
  messages: PropTypes.arrayOf(PropTypes.object),
  user: PropTypes.object,
  renderFooter: PropTypes.func,
  renderMessage: PropTypes.func,
  renderLoadEarlier: PropTypes.func,
  onLoadEarlier: PropTypes.func,
  listViewProps: PropTypes.object,
  inverted: PropTypes.bool,
  loadEarlier: PropTypes.bool,
  invertibleScrollViewProps: PropTypes.object, // TODO: support or not?
};
<|endoftext|>


<commit_before>// Copyright 2014-2017, University of Colorado Boulder

/**
 * Model for a RadioButtonGroupMember in RadioButtonGroup. This model is designed to be used inside
 * RadioButtonGroupMember only, so there should be no need to use it outside of RadioButtonGroupMember.
 *
 * @author Aaron Davis (PhET Interactive Simulations)
 */
define( function( require ) {
  'use strict';

  // modules
  var ButtonModel = require( 'SUN/buttons/ButtonModel' );
  var inherit = require( 'PHET_CORE/inherit' );
  var RadioButtonGroupMemberIO = require( 'SUN/RadioButtonGroupMemberIO' );
  var sun = require( 'SUN/sun' );

  /**
   * @param {Property} selectorProperty - the property for the RadioButtonGroup that determines which button is selected
   * @param {Object} selectedValue - the value that selectorProperty takes when this particular SingleRadioButton is selected
   * @param {Tandem} tandem
   * @param {PhetioObject} phetioEventSource
   * @constructor
   */
  function RadioButtonGroupMemberModel( selectorProperty, selectedValue, tandem, phetioEventSource ) {

    ButtonModel.call( this, {
      tandem: tandem,
      phetioType: RadioButtonGroupMemberIO
    } );

    var self = this;

    this.selectedValue = selectedValue;
    this.selectorProperty = selectorProperty;

    // @public (read only) - fire on up if the button is enabled, public for use in the accessibility tree
    this.fire = function() {
      if ( self.enabledProperty.get() ) {
        phetioEventSource.startEvent( 'user', 'fired', {
          value: selectorProperty.phetioType && selectorProperty.phetioType.elementType && selectorProperty.phetioType.elementType.toStateObject && selectorProperty.phetioType.elementType.toStateObject( selectedValue )
        } );
        selectorProperty.set( selectedValue );
        phetioEventSource.endEvent();
      }
    };
    this.downProperty.link( function( down ) {
      if ( !down && self.overProperty.get() ) {
        self.fire();
      }
    } );
  }

  sun.register( 'RadioButtonGroupMemberModel', RadioButtonGroupMemberModel );

  return inherit( ButtonModel, RadioButtonGroupMemberModel );
} );<commit_msg>Use read-only instead of read only<commit_after>// Copyright 2014-2017, University of Colorado Boulder

/**
 * Model for a RadioButtonGroupMember in RadioButtonGroup. This model is designed to be used inside
 * RadioButtonGroupMember only, so there should be no need to use it outside of RadioButtonGroupMember.
 *
 * @author Aaron Davis (PhET Interactive Simulations)
 */
define( function( require ) {
  'use strict';

  // modules
  var ButtonModel = require( 'SUN/buttons/ButtonModel' );
  var inherit = require( 'PHET_CORE/inherit' );
  var RadioButtonGroupMemberIO = require( 'SUN/RadioButtonGroupMemberIO' );
  var sun = require( 'SUN/sun' );

  /**
   * @param {Property} selectorProperty - the property for the RadioButtonGroup that determines which button is selected
   * @param {Object} selectedValue - the value that selectorProperty takes when this particular SingleRadioButton is selected
   * @param {Tandem} tandem
   * @param {PhetioObject} phetioEventSource
   * @constructor
   */
  function RadioButtonGroupMemberModel( selectorProperty, selectedValue, tandem, phetioEventSource ) {

    ButtonModel.call( this, {
      tandem: tandem,
      phetioType: RadioButtonGroupMemberIO
    } );

    var self = this;

    this.selectedValue = selectedValue;
    this.selectorProperty = selectorProperty;

    // @public (read-only) - fire on up if the button is enabled, public for use in the accessibility tree
    this.fire = function() {
      if ( self.enabledProperty.get() ) {
        phetioEventSource.startEvent( 'user', 'fired', {
          value: selectorProperty.phetioType && selectorProperty.phetioType.elementType && selectorProperty.phetioType.elementType.toStateObject && selectorProperty.phetioType.elementType.toStateObject( selectedValue )
        } );
        selectorProperty.set( selectedValue );
        phetioEventSource.endEvent();
      }
    };
    this.downProperty.link( function( down ) {
      if ( !down && self.overProperty.get() ) {
        self.fire();
      }
    } );
  }

  sun.register( 'RadioButtonGroupMemberModel', RadioButtonGroupMemberModel );

  return inherit( ButtonModel, RadioButtonGroupMemberModel );
} );<|endoftext|>